Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/icmp/icmp.c

    raadf01e rb5cbff4  
    102102 *  @returns The computed checksum.
    103103 */
    104 #define ICMP_CHECKSUM(header, length)           htons(ip_checksum((uint8_t *) (header), (length)))
     104#define ICMP_CHECKSUM( header, length )         htons( ip_checksum(( uint8_t * ) ( header ), ( length )))
    105105
    106106/** An echo request datagrams pattern.
     
    113113 *  @returns The computed ICMP reply data key.
    114114 */
    115 #define ICMP_GET_REPLY_KEY(id, sequence)        (((id) << 16) | (sequence &0xFFFF))
     115#define ICMP_GET_REPLY_KEY( id, sequence )      ((( id ) << 16 ) | ( sequence & 0xFFFF ))
    116116
    117117/** Processes the received ICMP packet.
     
    125125 *  @returns Other error codes as defined for the icmp_process_packet() function.
    126126 */
    127 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error);
     127int     icmp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error );
    128128
    129129/** Processes the received ICMP packet.
     
    140140 *  @returns Other error codes as defined for the ip_client_process_packet() function.
    141141 */
    142 int icmp_process_packet(packet_t packet, services_t error);
     142int     icmp_process_packet( packet_t packet, services_t error );
    143143
    144144/** Processes the client messages.
     
    151151 *  @see icmp_api.h
    152152 */
    153 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
     153int icmp_process_client_messages( ipc_callid_t callid, ipc_call_t call );
    154154
    155155/** Processes the generic client messages.
     
    164164 *  @see icmp_interface.h
    165165 */
    166 int icmp_process_message(ipc_call_t * call);
     166int     icmp_process_message( ipc_call_t * call );
    167167
    168168/** Releases the packet and returns the result.
     
    171171 *  @returns The result parameter.
    172172 */
    173 int icmp_release_and_return(packet_t packet, int result);
     173int     icmp_release_and_return( packet_t packet, int result );
    174174
    175175/** Requests an echo message.
    176176 *  Sends a packet with specified parameters to the target host and waits for the reply upto the given timeout.
    177  *  Blocks the caller until the reply or the timeout occurres.
     177 *  Blocks the caller until the reply or the timeout occurs.
    178178 *  @param[in] id The message identifier.
    179179 *  @param[in] sequence The message sequence parameter.
     
    192192 *  @returns EPARTY if there was an internal error.
    193193 */
    194 int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen);
     194int     icmp_echo( icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen );
    195195
    196196/** Prepares the ICMP error packet.
     
    201201 *  @returns NULL on errors.
    202202 */
    203 icmp_header_ref icmp_prepare_packet(packet_t packet);
     203icmp_header_ref icmp_prepare_packet( packet_t packet );
    204204
    205205/** Sends the ICMP message.
     
    218218 *  @returns EPERM if the error message is not allowed.
    219219 */
    220 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment);
     220int     icmp_send_packet( icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment );
    221221
    222222/** Tries to set the pending reply result as the received message type.
    223  *  If the reply data are still present, the reply timeouted and the parent fibril is awaken.
    224  *  The global lock is not released in this case to be reused by the parent fibril.
     223 *  If the reply data is not present, the reply timed out and the other fibril
     224 *  is already awake.
    225225 *  Releases the packet.
    226226 *  @param[in] packet The received reply message.
     
    230230 *  @returns EOK.
    231231 */
    232 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code);
     232int     icmp_process_echo_reply( packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code );
    233233
    234234/** Assigns a new identifier for the connection.
     
    239239 *  @returns ENOTCONN if no free identifier have been found.
    240240 */
    241 int icmp_bind_free_id(icmp_echo_ref echo_data);
     241int     icmp_bind_free_id( icmp_echo_ref echo_data );
    242242
    243243/** ICMP global data.
     
    245245icmp_globals_t  icmp_globals;
    246246
    247 INT_MAP_IMPLEMENT(icmp_replies, icmp_reply_t);
    248 
    249 INT_MAP_IMPLEMENT(icmp_echo_data, icmp_echo_t);
    250 
    251 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){
    252         icmp_echo_ref echo_data;
    253         int res;
    254 
    255         fibril_rwlock_write_lock(&icmp_globals.lock);
     247INT_MAP_IMPLEMENT( icmp_replies, icmp_reply_t );
     248
     249INT_MAP_IMPLEMENT( icmp_echo_data, icmp_echo_t );
     250
     251int icmp_echo_msg( int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen ){
     252        icmp_echo_ref   echo_data;
     253        int                             res;
     254
     255        fibril_rwlock_write_lock( & icmp_globals.lock );
    256256        // use the phone as the echo data index
    257         echo_data = icmp_echo_data_find(&icmp_globals.echo_data, icmp_phone);
    258         if(! echo_data){
     257        echo_data = icmp_echo_data_find( & icmp_globals.echo_data, icmp_phone );
     258        if( ! echo_data ){
    259259                res = ENOENT;
    260260        }else{
    261                 res = icmp_echo(echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen);
    262                 if(echo_data->sequence_number < MAX_UINT16){
     261                res = icmp_echo( echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen );
     262                if( echo_data->sequence_number < MAX_UINT16 ){
    263263                        ++ echo_data->sequence_number;
    264264                }else{
     
    266266                }
    267267        }
    268         fibril_rwlock_write_unlock(&icmp_globals.lock);
     268        fibril_rwlock_write_unlock( & icmp_globals.lock );
    269269        return res;
    270270}
    271271
    272 int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){
     272int icmp_echo( icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen ){
    273273        ERROR_DECLARE;
    274274
    275         icmp_header_ref header;
    276         packet_t packet;
    277         size_t length;
    278         uint8_t * data;
    279         icmp_reply_ref reply;
    280         int reply_key;
    281         int result;
    282         int index;
    283 
    284         if(addrlen <= 0){
     275        icmp_header_ref header;
     276        packet_t                packet;
     277        size_t                  length;
     278        uint8_t *               data;
     279        icmp_reply_ref                  reply;
     280        int                             reply_key;
     281        int                             result;
     282        int                             index;
     283
     284        if( addrlen <= 0 ){
    285285                return EINVAL;
    286286        }
    287         length = (size_t) addrlen;
     287        length = ( size_t ) addrlen;
    288288        // TODO do not ask all the time
    289         ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension));
    290         packet = packet_get_4(icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix);
    291         if(! packet){
    292                 return ENOMEM;
    293         }
     289        ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.packet_dimension ));
     290        packet = packet_get_4( icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix );
     291        if( ! packet ) return ENOMEM;
    294292
    295293        // prepare the requesting packet
    296294        // set the destination address
    297         if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (const uint8_t *) addr, length))){
    298                 return icmp_release_and_return(packet, ERROR_CODE);
     295        if( ERROR_OCCURRED( packet_set_addr( packet, NULL, ( const uint8_t * ) addr, length ))){
     296                return icmp_release_and_return( packet, ERROR_CODE );
    299297        }
    300298        // allocate space in the packet
    301         data = (uint8_t *) packet_suffix(packet, size);
    302         if(! data){
    303                 return icmp_release_and_return(packet, ENOMEM);
     299        data = ( uint8_t * ) packet_suffix( packet, size );
     300        if( ! data ){
     301                return icmp_release_and_return( packet, ENOMEM );
    304302        }
    305303        // fill the data
    306304        length = 0;
    307         while(size > length + sizeof(ICMP_ECHO_TEXT)){
    308                 memcpy(data + length, ICMP_ECHO_TEXT, sizeof(ICMP_ECHO_TEXT));
    309                 length += sizeof(ICMP_ECHO_TEXT);
    310         }
    311         memcpy(data + length, ICMP_ECHO_TEXT, size - length);
     305        while( size > length + sizeof( ICMP_ECHO_TEXT )){
     306                memcpy( data + length, ICMP_ECHO_TEXT, sizeof( ICMP_ECHO_TEXT ));
     307                length += sizeof( ICMP_ECHO_TEXT );
     308        }
     309        memcpy( data + length, ICMP_ECHO_TEXT, size - length );
    312310        // prefix the header
    313         header = PACKET_PREFIX(packet, icmp_header_t);
    314         if(! header){
    315                 return icmp_release_and_return(packet, ENOMEM);
    316         }
    317         bzero(header, sizeof(*header));
     311        header = PACKET_PREFIX( packet, icmp_header_t );
     312        if( ! header ){
     313                return icmp_release_and_return( packet, ENOMEM );
     314        }
     315        bzero( header, sizeof( * header ));
    318316        header->un.echo.identifier = id;
    319317        header->un.echo.sequence_number = sequence;
    320318
    321319        // prepare the reply structure
    322         reply = malloc(sizeof(*reply));
    323         if(! reply){
    324                 return icmp_release_and_return(packet, ENOMEM);
    325         }
    326         fibril_mutex_initialize(&reply->mutex);
    327         fibril_mutex_lock(&reply->mutex);
    328         fibril_condvar_initialize(&reply->condvar);
    329         reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number);
    330         index = icmp_replies_add(&icmp_globals.replies, reply_key, reply);
    331         if(index < 0){
    332                 free(reply);
    333                 return icmp_release_and_return(packet, index);
    334         }
    335 
    336         // unlock the globals and wait for a reply
    337         fibril_rwlock_write_unlock(&icmp_globals.lock);
     320        reply = malloc( sizeof( * reply ));
     321        if( ! reply ){
     322                return icmp_release_and_return( packet, ENOMEM );
     323        }
     324        fibril_mutex_initialize( & reply->mutex );
     325        fibril_mutex_lock( & reply->mutex );
     326        fibril_condvar_initialize( & reply->condvar );
     327        reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number );
     328        index = icmp_replies_add( & icmp_globals.replies, reply_key, reply );
     329        if( index < 0 ){
     330                free( reply );
     331                return icmp_release_and_return( packet, index );
     332        }
     333
     334        // unlock the globals so that we can wait for the reply
     335        fibril_rwlock_write_unlock( & icmp_globals.lock );
    338336
    339337        // send the request
    340         icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment);
    341 
    342         // wait for a reply
     338        icmp_send_packet( ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment );
     339
     340        // wait for the reply
    343341        // timeout in microseconds
    344         if(ERROR_OCCURRED(fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, timeout * 1000))){
     342        if( ERROR_OCCURRED( fibril_condvar_wait_timeout( & reply->condvar, & reply->mutex, timeout * 1000 ))){
    345343                result = ERROR_CODE;
    346 
    347                 // lock the globals again and clean up
    348                 fibril_rwlock_write_lock(&icmp_globals.lock);
    349344        }else{
    350345                // read the result
    351346                result = reply->result;
    352 
    353                 // release the reply structure
    354                 fibril_mutex_unlock(&reply->mutex);
    355         }
     347        }
     348
     349        // drop the reply mutex before locking the globals again
     350        fibril_mutex_unlock( & reply->mutex );
     351        fibril_rwlock_write_lock( & icmp_globals.lock );
    356352
    357353        // destroy the reply structure
    358         icmp_replies_exclude_index(&icmp_globals.replies, index);
     354        icmp_replies_exclude_index( & icmp_globals.replies, index );
    359355        return result;
    360356}
    361357
    362 int icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){
    363         icmp_header_ref header;
    364 
    365         header = icmp_prepare_packet(packet);
    366         if(! header){
    367                 return icmp_release_and_return(packet, ENOMEM);
    368         }
    369         if(mtu){
     358int icmp_destination_unreachable_msg( int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet ){
     359        icmp_header_ref header;
     360
     361        header = icmp_prepare_packet( packet );
     362        if( ! header ){
     363                return icmp_release_and_return( packet, ENOMEM );
     364        }
     365        if( mtu ){
    370366                header->un.frag.mtu = mtu;
    371367        }
    372         return icmp_send_packet(ICMP_DEST_UNREACH, code, packet, header, SERVICE_ICMP, 0, 0, 0);
    373 }
    374 
    375 int icmp_source_quench_msg(int icmp_phone, packet_t packet){
    376         icmp_header_ref header;
    377 
    378         header = icmp_prepare_packet(packet);
    379         if(! header){
    380                 return icmp_release_and_return(packet, ENOMEM);
    381         }
    382         return icmp_send_packet(ICMP_SOURCE_QUENCH, 0, packet, header, SERVICE_ICMP, 0, 0, 0);
    383 }
    384 
    385 int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t packet){
    386         icmp_header_ref header;
    387 
    388         header = icmp_prepare_packet(packet);
    389         if(! header){
    390                 return icmp_release_and_return(packet, ENOMEM);
    391         }
    392         return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header, SERVICE_ICMP, 0, 0, 0);
    393 }
    394 
    395 int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){
    396         icmp_header_ref header;
    397 
    398         header = icmp_prepare_packet(packet);
    399         if(! header){
    400                 return icmp_release_and_return(packet, ENOMEM);
     368        return icmp_send_packet( ICMP_DEST_UNREACH, code, packet, header, SERVICE_ICMP, 0, 0, 0 );
     369}
     370
     371int icmp_source_quench_msg( int icmp_phone, packet_t packet ){
     372        icmp_header_ref header;
     373
     374        header = icmp_prepare_packet( packet );
     375        if( ! header ){
     376                return icmp_release_and_return( packet, ENOMEM );
     377        }
     378        return icmp_send_packet( ICMP_SOURCE_QUENCH, 0, packet, header, SERVICE_ICMP, 0, 0, 0 );
     379}
     380
     381int icmp_time_exceeded_msg( int icmp_phone, icmp_code_t code, packet_t packet ){
     382        icmp_header_ref header;
     383
     384        header = icmp_prepare_packet( packet );
     385        if( ! header ){
     386                return icmp_release_and_return( packet, ENOMEM );
     387        }
     388        return icmp_send_packet( ICMP_TIME_EXCEEDED, code, packet, header, SERVICE_ICMP, 0, 0, 0 );
     389}
     390
     391int icmp_parameter_problem_msg( int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet ){
     392        icmp_header_ref header;
     393
     394        header = icmp_prepare_packet( packet );
     395        if( ! header ){
     396                return icmp_release_and_return( packet, ENOMEM );
    401397        }
    402398        header->un.param.pointer = pointer;
    403         return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header, SERVICE_ICMP, 0, 0, 0);
    404 }
    405 
    406 icmp_header_ref icmp_prepare_packet(packet_t packet){
    407         icmp_header_ref header;
    408         size_t header_length;
    409         size_t total_length;
    410 
    411         total_length = packet_get_data_length(packet);
    412         if(total_length <= 0){
     399        return icmp_send_packet( ICMP_PARAMETERPROB, code, packet, header, SERVICE_ICMP, 0, 0, 0 );
     400}
     401
     402icmp_header_ref icmp_prepare_packet( packet_t packet ){
     403        icmp_header_ref header;
     404        size_t                  header_length;
     405        size_t                  total_length;
     406
     407        total_length = packet_get_data_length( packet );
     408        if( total_length <= 0 ) return NULL;
     409        header_length = ip_client_header_length( packet );
     410        if( header_length <= 0 ) return NULL;
     411        // truncate if longer than 64 bits (without the IP header)
     412        if(( total_length > header_length + ICMP_KEEP_LENGTH )
     413        && ( packet_trim( packet, 0, total_length - header_length - ICMP_KEEP_LENGTH ) != EOK )){
    413414                return NULL;
    414415        }
    415         header_length = ip_client_header_length(packet);
    416         if(header_length <= 0){
    417                 return NULL;
    418         }
    419         // truncate if longer than 64 bits (without the IP header)
    420         if((total_length > header_length + ICMP_KEEP_LENGTH)
    421                 && (packet_trim(packet, 0, total_length - header_length - ICMP_KEEP_LENGTH) != EOK)){
    422                 return NULL;
    423         }
    424         header = PACKET_PREFIX(packet, icmp_header_t);
    425         if(! header){
    426                 return NULL;
    427         }
    428         bzero(header, sizeof(*header));
     416        header = PACKET_PREFIX( packet, icmp_header_t );
     417        if( ! header ) return NULL;
     418        bzero( header, sizeof( * header ));
    429419        return header;
    430420}
    431421
    432 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment){
     422int icmp_send_packet( icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment ){
    433423        ERROR_DECLARE;
    434424
    435425        // do not send an error if disabled
    436         if(error && (! icmp_globals.error_reporting)){
    437                 return icmp_release_and_return(packet, EPERM);
     426        if( error && ( ! icmp_globals.error_reporting )){
     427                return icmp_release_and_return( packet, EPERM );
    438428        }
    439429        header->type = type;
    440430        header->code = code;
    441431        header->checksum = 0;
    442         header->checksum = ICMP_CHECKSUM(header, packet_get_data_length(packet));
    443         if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos, dont_fragment, 0))){
    444                 return icmp_release_and_return(packet, ERROR_CODE);
    445         }
    446         return ip_send_msg(icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, error);
    447 }
    448 
    449 int icmp_connect_module(services_t service, suseconds_t timeout){
    450         icmp_echo_ref echo_data;
    451         icmp_param_t id;
    452         int index;
    453 
    454         echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data));
    455         if(! echo_data){
    456                 return ENOMEM;
    457         }
     432        header->checksum = ICMP_CHECKSUM( header, packet_get_data_length( packet ));
     433        if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_ICMP, ttl, tos, dont_fragment, 0 ))){
     434                return icmp_release_and_return( packet, ERROR_CODE );
     435        }
     436        return ip_send_msg( icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, error );
     437}
     438
     439int icmp_connect_module( services_t service, suseconds_t timeout ){
     440        icmp_echo_ref   echo_data;
     441        icmp_param_t    id;
     442        int                             index;
     443
     444        echo_data = ( icmp_echo_ref ) malloc( sizeof( * echo_data ));
     445        if( ! echo_data ) return ENOMEM;
    458446        // assign a new identifier
    459         fibril_rwlock_write_lock(&icmp_globals.lock);
    460         index = icmp_bind_free_id(echo_data);
    461         if(index < 0){
    462                 free(echo_data);
    463                 fibril_rwlock_write_unlock(&icmp_globals.lock);
     447        fibril_rwlock_write_lock( & icmp_globals.lock );
     448        index = icmp_bind_free_id( echo_data );
     449        if( index < 0 ){
     450                free( echo_data );
     451                fibril_rwlock_write_unlock( & icmp_globals.lock );
    464452                return index;
    465453        }else{
    466454                id = echo_data->identifier;
    467                 fibril_rwlock_write_unlock(&icmp_globals.lock);
     455                fibril_rwlock_write_unlock( & icmp_globals.lock );
    468456                // return the echo data identifier as the ICMP phone
    469457                return id;
     
    471459}
    472460
    473 int icmp_initialize(async_client_conn_t client_connection){
     461int icmp_initialize( async_client_conn_t client_connection ){
    474462        ERROR_DECLARE;
    475463
    476         measured_string_t names[] = {{str_dup("ICMP_ERROR_REPORTING"), 20}, {str_dup("ICMP_ECHO_REPLYING"), 18}};
    477         measured_string_ref configuration;
    478         size_t count = sizeof(names) / sizeof(measured_string_t);
    479         char * data;
    480 
    481         fibril_rwlock_initialize(&icmp_globals.lock);
    482         fibril_rwlock_write_lock(&icmp_globals.lock);
    483         icmp_replies_initialize(&icmp_globals.replies);
    484         icmp_echo_data_initialize(&icmp_globals.echo_data);
    485         icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection, icmp_received_msg);
    486         if(icmp_globals.ip_phone < 0){
     464        measured_string_t       names[] = {{ str_dup("ICMP_ERROR_REPORTING"), 20 }, { str_dup("ICMP_ECHO_REPLYING"), 18 }};
     465        measured_string_ref     configuration;
     466        size_t                          count = sizeof( names ) / sizeof( measured_string_t );
     467        char *                          data;
     468
     469        fibril_rwlock_initialize( & icmp_globals.lock );
     470        fibril_rwlock_write_lock( & icmp_globals.lock );
     471        icmp_replies_initialize( & icmp_globals.replies );
     472        icmp_echo_data_initialize( & icmp_globals.echo_data );
     473        icmp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection, icmp_received_msg );
     474        if( icmp_globals.ip_phone < 0 ){
    487475                return icmp_globals.ip_phone;
    488476        }
    489         ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension));
     477        ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.packet_dimension ));
    490478        icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE;
    491479        icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE;
     
    493481        icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING;
    494482        icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING;
    495         configuration = &names[0];
    496         ERROR_PROPAGATE(net_get_conf_req(icmp_globals.net_phone, &configuration, count, &data));
    497         if(configuration){
    498                 if(configuration[0].value){
    499                         icmp_globals.error_reporting = (configuration[0].value[0] == 'y');
     483        configuration = & names[ 0 ];
     484        ERROR_PROPAGATE( net_get_conf_req( icmp_globals.net_phone, & configuration, count, & data ));
     485        if( configuration ){
     486                if( configuration[ 0 ].value ){
     487                        icmp_globals.error_reporting = ( configuration[ 0 ].value[ 0 ] == 'y' );
    500488                }
    501                 if(configuration[1].value){
    502                         icmp_globals.echo_replying = (configuration[1].value[0] == 'y');
     489                if( configuration[ 1 ].value ){
     490                        icmp_globals.echo_replying = ( configuration[ 1 ].value[ 0 ] == 'y' );
    503491                }
    504                 net_free_settings(configuration, data);
    505         }
    506         fibril_rwlock_write_unlock(&icmp_globals.lock);
     492                net_free_settings( configuration, data );
     493        }
     494        fibril_rwlock_write_unlock( & icmp_globals.lock );
    507495        return EOK;
    508496}
    509497
    510 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){
     498int     icmp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ){
    511499        ERROR_DECLARE;
    512500
    513         if(ERROR_OCCURRED(icmp_process_packet(packet, error))){
    514                 return icmp_release_and_return(packet, ERROR_CODE);
     501        if( ERROR_OCCURRED( icmp_process_packet( packet, error ))){
     502                return icmp_release_and_return( packet, ERROR_CODE );
    515503        }
    516504
     
    518506}
    519507
    520 int icmp_process_packet(packet_t packet, services_t error){
     508int icmp_process_packet( packet_t packet, services_t error ){
    521509        ERROR_DECLARE;
    522510
    523         size_t length;
    524         uint8_t * src;
    525         int addrlen;
    526         int result;
    527         void * data;
    528         icmp_header_ref header;
    529         icmp_type_t type;
    530         icmp_code_t code;
    531 
    532         if(error){
    533                 switch(error){
     511        size_t                  length;
     512        uint8_t *               src;
     513        int                             addrlen;
     514        int                             result;
     515        void *                  data;
     516        icmp_header_ref header;
     517        icmp_type_t             type;
     518        icmp_code_t             code;
     519
     520        if( error ){
     521                switch( error ){
    534522                        case SERVICE_ICMP:
    535523                                // process error
    536                                 result = icmp_client_process_packet(packet, &type, &code, NULL, NULL);
    537                                 if(result < 0){
    538                                         return result;
    539                                 }
    540                                 length = (size_t) result;
     524                                result = icmp_client_process_packet( packet, & type, & code, NULL, NULL );
     525                                if( result < 0 ) return result;
     526                                length = ( size_t ) result;
    541527                                // remove the error header
    542                                 ERROR_PROPAGATE(packet_trim(packet, length, 0));
     528                                ERROR_PROPAGATE( packet_trim( packet, length, 0 ));
    543529                                break;
    544530                        default:
     
    547533        }
    548534        // get rid of the ip header
    549         length = ip_client_header_length(packet);
    550         ERROR_PROPAGATE(packet_trim(packet, length, 0));
    551 
    552         length = packet_get_data_length(packet);
    553         if(length <= 0){
    554                 return EINVAL;
    555         }
    556         if(length < ICMP_HEADER_SIZE){
    557                 return EINVAL;
    558         }
    559         data = packet_get_data(packet);
    560         if(! data){
    561                 return EINVAL;
    562         }
     535        length = ip_client_header_length( packet );
     536        ERROR_PROPAGATE( packet_trim( packet, length, 0 ));
     537
     538        length = packet_get_data_length( packet );
     539        if( length <= 0 ) return EINVAL;
     540        if( length < ICMP_HEADER_SIZE) return EINVAL;
     541        data = packet_get_data( packet );
     542        if( ! data ) return EINVAL;
    563543        // get icmp header
    564         header = (icmp_header_ref) data;
     544        header = ( icmp_header_ref ) data;
    565545        // checksum
    566         if(header->checksum){
    567                 while(ICMP_CHECKSUM(header, length) != IP_CHECKSUM_ZERO){
     546        if( header->checksum ){
     547                while( ICMP_CHECKSUM( header, length ) != IP_CHECKSUM_ZERO ){
    568548                        // set the original message type on error notification
    569549                        // type swap observed in Qemu
    570                         if(error){
    571                                 switch(header->type){
     550                        if( error ){
     551                                switch( header->type ){
    572552                                        case ICMP_ECHOREPLY:
    573553                                                header->type = ICMP_ECHO;
     
    578558                }
    579559        }
    580         switch(header->type){
     560        switch( header->type ){
    581561                case ICMP_ECHOREPLY:
    582                         if(error){
    583                                 return icmp_process_echo_reply(packet, header, type, code);
     562                        if( error ){
     563                                return icmp_process_echo_reply( packet, header, type, code );
    584564                        }else{
    585                                 return icmp_process_echo_reply(packet, header, ICMP_ECHO, 0);
     565                                return icmp_process_echo_reply( packet, header, ICMP_ECHO, 0 );
    586566                        }
    587567                case ICMP_ECHO:
    588                         if(error){
    589                                 return icmp_process_echo_reply(packet, header, type, code);
     568                        if( error ){
     569                                return icmp_process_echo_reply( packet, header, type, code );
    590570                        // do not send a reply if disabled
    591                         }else if(icmp_globals.echo_replying){
    592                                 addrlen = packet_get_addr(packet, &src, NULL);
    593                                 if((addrlen > 0)
     571                        }else if( icmp_globals.echo_replying ){
     572                                addrlen = packet_get_addr( packet, & src, NULL );
     573                                if(( addrlen > 0 )
    594574                                // set both addresses to the source one (avoids the source address deletion before setting the destination one)
    595                                         && (packet_set_addr(packet, src, src, (size_t) addrlen) == EOK)){
     575                                && ( packet_set_addr( packet, src, src, ( size_t ) addrlen ) == EOK )){
    596576                                        // send the reply
    597                                         icmp_send_packet(ICMP_ECHOREPLY, 0, packet, header, 0, 0, 0, 0);
     577                                        icmp_send_packet( ICMP_ECHOREPLY, 0, packet, header, 0, 0, 0, 0 );
    598578                                        return EOK;
    599579                                }else{
     
    615595                case ICMP_SKIP:
    616596                case ICMP_PHOTURIS:
    617                         ip_received_error_msg(icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP);
     597                        ip_received_error_msg( icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP );
    618598                        return EOK;
    619599                default:
     
    622602}
    623603
    624 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code){
    625         int reply_key;
    626         icmp_reply_ref reply;
     604int icmp_process_echo_reply( packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code ){
     605        int                             reply_key;
     606        icmp_reply_ref  reply;
    627607
    628608        // compute the reply key
    629         reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number);
    630         pq_release(icmp_globals.net_phone, packet_get_id(packet));
     609        reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number );
     610        pq_release( icmp_globals.net_phone, packet_get_id( packet ));
    631611        // lock the globals
    632         fibril_rwlock_write_lock(&icmp_globals.lock);
     612        fibril_rwlock_write_lock( & icmp_globals.lock );
    633613        // find the pending reply
    634         reply = icmp_replies_find(&icmp_globals.replies, reply_key);
    635         if(reply){
     614        reply = icmp_replies_find( & icmp_globals.replies, reply_key );
     615        if( reply ){
    636616                // set the result
    637617                reply->result = type;
    638                 // notify the main fibril
    639                 fibril_condvar_signal(&reply->condvar);
    640         }else{
    641                 // unlock only if no reply
    642                 fibril_rwlock_write_unlock(&icmp_globals.lock);
    643         }
     618                // notify the waiting fibril
     619                fibril_condvar_signal( & reply->condvar );
     620        }
     621        fibril_rwlock_write_unlock( & icmp_globals.lock );
    644622        return EOK;
    645623}
    646624
    647 int icmp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
     625int icmp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
    648626        ERROR_DECLARE;
    649627
    650         packet_t packet;
    651 
    652         *answer_count = 0;
    653         switch(IPC_GET_METHOD(*call)){
     628        packet_t                        packet;
     629
     630        * answer_count = 0;
     631        switch( IPC_GET_METHOD( * call )){
    654632                case NET_TL_RECEIVED:
    655                         if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    656                                 ERROR_CODE = icmp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_ICMP, IPC_GET_ERROR(call));
     633                        if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
     634                                ERROR_CODE = icmp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_ICMP, IPC_GET_ERROR( call ));
    657635                        }
    658636                        return ERROR_CODE;
    659637                case NET_ICMP_INIT:
    660                         return icmp_process_client_messages(callid, * call);
     638                        return icmp_process_client_messages( callid, * call );
    661639                default:
    662                         return icmp_process_message(call);
     640                        return icmp_process_message( call );
    663641        }
    664642        return ENOTSUP;
    665643}
    666644
    667 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call){
     645int icmp_process_client_messages( ipc_callid_t callid, ipc_call_t call ){
    668646        ERROR_DECLARE;
    669647
    670         bool keep_on_going = true;
     648        bool                                    keep_on_going = true;
    671649//      fibril_rwlock_t                 lock;
    672         ipc_call_t answer;
    673         int answer_count;
    674         size_t length;
    675         struct sockaddr * addr;
    676         ipc_callid_t data_callid;
    677         icmp_echo_ref echo_data;
    678         int res;
     650        ipc_call_t                              answer;
     651        int                                             answer_count;
     652        size_t                                  length;
     653        struct sockaddr *               addr;
     654        ipc_callid_t                    data_callid;
     655        icmp_echo_ref                   echo_data;
    679656
    680657        /*
     
    682659         *  - Answer the first NET_ICMP_INIT call.
    683660         */
    684         res = EOK;
    685         answer_count = 0;
    686 
    687 //      fibril_rwlock_initialize(&lock);
    688 
    689         echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data));
    690         if(! echo_data){
    691                 return ENOMEM;
    692         }
    693 
     661        ipc_answer_0( callid, EOK );
     662
     663//      fibril_rwlock_initialize( & lock );
     664
     665        echo_data = ( icmp_echo_ref ) malloc( sizeof( * echo_data ));
     666        if( ! echo_data ) return ENOMEM;
    694667        // assign a new identifier
    695         fibril_rwlock_write_lock(&icmp_globals.lock);
    696         res = icmp_bind_free_id(echo_data);
    697         fibril_rwlock_write_unlock(&icmp_globals.lock);
    698         if(res < 0){
    699                 free(echo_data);
    700                 return res;
    701         }
    702 
    703         while(keep_on_going){
    704 
    705                 // answer the call
    706                 answer_call(callid, res, &answer, answer_count);
    707 
    708                 // refresh data
    709                 refresh_answer(&answer, &answer_count);
    710 
    711                 // get the next call
    712                 callid = async_get_call(&call);
    713 
    714                 // process the call
    715                 switch(IPC_GET_METHOD(call)){
     668        fibril_rwlock_write_lock( & icmp_globals.lock );
     669        ERROR_CODE = icmp_bind_free_id( echo_data );
     670        fibril_rwlock_write_unlock( & icmp_globals.lock );
     671        if( ERROR_CODE < 0 ){
     672                free( echo_data );
     673                return ERROR_CODE;
     674        }
     675
     676        while( keep_on_going ){
     677                refresh_answer( & answer, & answer_count );
     678
     679                callid = async_get_call( & call );
     680
     681                switch( IPC_GET_METHOD( call )){
    716682                        case IPC_M_PHONE_HUNGUP:
    717683                                keep_on_going = false;
    718                                 res = EHANGUP;
     684                                ERROR_CODE = EOK;
    719685                                break;
    720686                        case NET_ICMP_ECHO:
    721 //                              fibril_rwlock_write_lock(&lock);
    722                                 if(! async_data_write_receive(&data_callid, &length)){
    723                                         res = EINVAL;
     687//                              fibril_rwlock_write_lock( & lock );
     688                                if( ! async_data_write_receive( & data_callid, & length )){
     689                                        ERROR_CODE = EINVAL;
    724690                                }else{
    725                                         addr = malloc(length);
    726                                         if(! addr){
    727                                                 res = ENOMEM;
     691                                        addr = malloc( length );
     692                                        if( ! addr ){
     693                                                ERROR_CODE = ENOMEM;
    728694                                        }else{
    729                                                 if(! ERROR_OCCURRED(async_data_write_finalize(data_callid, addr, length))){
    730                                                         fibril_rwlock_write_lock(&icmp_globals.lock);
    731                                                         res = icmp_echo(echo_data->identifier, echo_data->sequence_number, ICMP_GET_SIZE(call), ICMP_GET_TIMEOUT(call), ICMP_GET_TTL(call), ICMP_GET_TOS(call), ICMP_GET_DONT_FRAGMENT(call), addr, (socklen_t) length);
    732                                                         fibril_rwlock_write_unlock(&icmp_globals.lock);
    733                                                         free(addr);
    734                                                         if(echo_data->sequence_number < MAX_UINT16){
     695                                                if( ! ERROR_OCCURRED( async_data_write_finalize( data_callid, addr, length ))){
     696                                                        fibril_rwlock_write_lock( & icmp_globals.lock );
     697                                                        ERROR_CODE = icmp_echo( echo_data->identifier, echo_data->sequence_number, ICMP_GET_SIZE( call ), ICMP_GET_TIMEOUT( call ), ICMP_GET_TTL( call ), ICMP_GET_TOS( call ), ICMP_GET_DONT_FRAGMENT( call ), addr, ( socklen_t ) length );
     698                                                        fibril_rwlock_write_unlock( & icmp_globals.lock );
     699                                                        free( addr );
     700                                                        if( echo_data->sequence_number < MAX_UINT16 ){
    735701                                                                ++ echo_data->sequence_number;
    736702                                                        }else{
    737703                                                                echo_data->sequence_number = 0;
    738704                                                        }
    739                                                 }else{
    740                                                         res = ERROR_CODE;
    741705                                                }
    742706                                        }
    743707                                }
    744 //                              fibril_rwlock_write_unlock(&lock);
     708//                              fibril_rwlock_write_unlock( & lock );
    745709                                break;
    746710                        default:
    747                                 res = icmp_process_message(&call);
     711                                ERROR_CODE = icmp_process_message( & call );
    748712                }
     713
     714                answer_call( callid, ERROR_CODE, & answer, answer_count );
    749715        }
    750716
    751717        // release the identifier
    752         fibril_rwlock_write_lock(&icmp_globals.lock);
    753         icmp_echo_data_exclude(&icmp_globals.echo_data, echo_data->identifier);
    754         fibril_rwlock_write_unlock(&icmp_globals.lock);
    755         return res;
    756 }
    757 
    758 int icmp_process_message(ipc_call_t * call){
     718        fibril_rwlock_write_lock( & icmp_globals.lock );
     719        icmp_echo_data_exclude( & icmp_globals.echo_data, echo_data->identifier );
     720        fibril_rwlock_write_unlock( & icmp_globals.lock );
     721        return EOK;
     722}
     723
     724int icmp_process_message( ipc_call_t * call ){
    759725        ERROR_DECLARE;
    760726
    761         packet_t packet;
    762 
    763         switch(IPC_GET_METHOD(*call)){
     727        packet_t        packet;
     728
     729        switch( IPC_GET_METHOD( * call )){
    764730                case NET_ICMP_DEST_UNREACH:
    765                         if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    766                                 ERROR_CODE = icmp_destination_unreachable_msg(0, ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet);
     731                        if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
     732                                ERROR_CODE = icmp_destination_unreachable_msg( 0, ICMP_GET_CODE( call ), ICMP_GET_MTU( call ), packet );
    767733                        }
    768734                        return ERROR_CODE;
    769735                case NET_ICMP_SOURCE_QUENCH:
    770                         if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    771                                 ERROR_CODE = icmp_source_quench_msg(0, packet);
     736                        if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
     737                                ERROR_CODE = icmp_source_quench_msg( 0, packet );
    772738                        }
    773739                        return ERROR_CODE;
    774740                case NET_ICMP_TIME_EXCEEDED:
    775                         if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    776                                 ERROR_CODE = icmp_time_exceeded_msg(0, ICMP_GET_CODE(call), packet);
     741                        if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
     742                                ERROR_CODE = icmp_time_exceeded_msg( 0, ICMP_GET_CODE( call ), packet );
    777743                        }
    778744                        return ERROR_CODE;
    779745                case NET_ICMP_PARAMETERPROB:
    780                         if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    781                                 ERROR_CODE = icmp_parameter_problem_msg(0, ICMP_GET_CODE(call), ICMP_GET_POINTER(call), packet);
     746                        if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
     747                                ERROR_CODE = icmp_parameter_problem_msg( 0, ICMP_GET_CODE( call ), ICMP_GET_POINTER( call ), packet );
    782748                        }
    783749                        return ERROR_CODE;
     
    787753}
    788754
    789 int icmp_release_and_return(packet_t packet, int result){
    790         pq_release(icmp_globals.net_phone, packet_get_id(packet));
     755int     icmp_release_and_return( packet_t packet, int result ){
     756        pq_release( icmp_globals.net_phone, packet_get_id( packet ));
    791757        return result;
    792758}
    793759
    794 int icmp_bind_free_id(icmp_echo_ref echo_data){
    795         icmp_param_t index;
    796 
    797         if(! echo_data){
    798                 return EBADMEM;
    799         }
     760int icmp_bind_free_id( icmp_echo_ref echo_data ){
     761        icmp_param_t    index;
     762
     763        if( ! echo_data ) return EBADMEM;
    800764        // from the last used one
    801765        index = icmp_globals.last_used_id;
     
    803767                ++ index;
    804768                // til the range end
    805                 if(index >= ICMP_FREE_IDS_END){
     769                if( index >= ICMP_FREE_IDS_END ){
    806770                        // start from the range beginning
    807771                        index = ICMP_FREE_IDS_START - 1;
     
    809773                                ++ index;
    810774                                // til the last used one
    811                                 if(index >= icmp_globals.last_used_id){
     775                                if( index >= icmp_globals.last_used_id ){
    812776                                        // none found
    813777                                        return ENOTCONN;
    814778                                }
    815                         }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL);
     779                        }while( icmp_echo_data_find( & icmp_globals.echo_data, index ) != NULL );
    816780                        // found, break immediately
    817781                        break;
    818782                }
    819         }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL);
     783        }while( icmp_echo_data_find( & icmp_globals.echo_data, index ) != NULL );
    820784        echo_data->identifier = index;
    821785        echo_data->sequence_number = 0;
    822         return icmp_echo_data_add(&icmp_globals.echo_data, index, echo_data);
     786        return icmp_echo_data_add( & icmp_globals.echo_data, index, echo_data );
    823787}
    824788
Note: See TracChangeset for help on using the changeset viewer.