Changeset 71b00dcc in mainline for uspace/srv/net/il/arp/arp.c


Ignore:
Timestamp:
2010-03-07T22:51:38Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
60ab6c3
Parents:
b5cbff4 (diff), 31c80a5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~lukasmejdrech/helenos/network.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/il/arp/arp.c

    rb5cbff4 r71b00dcc  
    8181 *  @returns ENOMEM if there is not enough memory left.
    8282 */
    83 int     arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address );
     83int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address);
    8484
    8585/** Clears the device specific data.
    8686 *  @param[in] device The device specific data.
    8787 */
    88 void    arp_clear_device( arp_device_ref device );
     88void arp_clear_device(arp_device_ref device);
    8989
    9090/** @name Message processing functions
     
    103103 *  @returns Other error codes as defined for the measured_strings_return() function.
    104104 */
    105 int     arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address );
     105int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address);
    106106
    107107/** Returns the hardware address for the given protocol address.
     
    116116 *  @returns NULL if the hardware address is not found in the cache.
    117117 */
    118 measured_string_ref     arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target );
     118measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target);
    119119
    120120/** Processes the received ARP packet.
     
    131131 *  @returns ENOMEM if there is not enough memory left.
    132132 */
    133 int     arp_receive_message( device_id_t device_id, packet_t packet );
     133int arp_receive_message(device_id_t device_id, packet_t packet);
    134134
    135135/** Updates the device content length according to the new MTU value.
     
    139139 *  @returns EOK on success.
    140140 */
    141 int     arp_mtu_changed_message( device_id_t device_id, size_t mtu );
     141int arp_mtu_changed_message(device_id_t device_id, size_t mtu);
    142142
    143143/*@}*/
    144144
    145 DEVICE_MAP_IMPLEMENT( arp_cache, arp_device_t )
    146 
    147 INT_MAP_IMPLEMENT( arp_protos, arp_proto_t )
    148 
    149 GENERIC_CHAR_MAP_IMPLEMENT( arp_addr, measured_string_t )
    150 
    151 task_id_t arp_task_get_id( void ){
     145DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t)
     146
     147INT_MAP_IMPLEMENT(arp_protos, arp_proto_t)
     148
     149GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t)
     150
     151task_id_t arp_task_get_id(void){
    152152        return task_get_id();
    153153}
    154154
    155 int arp_clear_device_req( int arp_phone, device_id_t device_id ){
    156         arp_device_ref  device;
    157 
    158         fibril_rwlock_write_lock( & arp_globals.lock );
    159         device = arp_cache_find( & arp_globals.cache, device_id );
    160         if( ! device ){
    161                 fibril_rwlock_write_unlock( & arp_globals.lock );
     155int arp_clear_device_req(int arp_phone, device_id_t device_id){
     156        arp_device_ref device;
     157
     158        fibril_rwlock_write_lock(&arp_globals.lock);
     159        device = arp_cache_find(&arp_globals.cache, device_id);
     160        if(! device){
     161                fibril_rwlock_write_unlock(&arp_globals.lock);
    162162                return ENOENT;
    163163        }
    164         arp_clear_device( device );
    165         printf( "Device %d cleared\n", device_id );
    166         fibril_rwlock_write_unlock( & arp_globals.lock );
    167         return EOK;
    168 }
    169 
    170 int arp_clear_address_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address ){
    171         arp_device_ref  device;
    172         arp_proto_ref   proto;
    173 
    174         fibril_rwlock_write_lock( & arp_globals.lock );
    175         device = arp_cache_find( & arp_globals.cache, device_id );
    176         if( ! device ){
    177                 fibril_rwlock_write_unlock( & arp_globals.lock );
     164        arp_clear_device(device);
     165        printf("Device %d cleared\n", device_id);
     166        fibril_rwlock_write_unlock(&arp_globals.lock);
     167        return EOK;
     168}
     169
     170int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){
     171        arp_device_ref device;
     172        arp_proto_ref proto;
     173
     174        fibril_rwlock_write_lock(&arp_globals.lock);
     175        device = arp_cache_find(&arp_globals.cache, device_id);
     176        if(! device){
     177                fibril_rwlock_write_unlock(&arp_globals.lock);
    178178                return ENOENT;
    179179        }
    180         proto = arp_protos_find( & device->protos, protocol );
    181         if( ! proto ){
    182                 fibril_rwlock_write_unlock( & arp_globals.lock );
     180        proto = arp_protos_find(&device->protos, protocol);
     181        if(! proto){
     182                fibril_rwlock_write_unlock(&arp_globals.lock);
    183183                return ENOENT;
    184184        }
    185         arp_addr_exclude( & proto->addresses, address->value, address->length );
    186         fibril_rwlock_write_unlock( & arp_globals.lock );
    187         return EOK;
    188 }
    189 
    190 int arp_clean_cache_req( int arp_phone ){
    191         int                             count;
    192         arp_device_ref  device;
    193 
    194         fibril_rwlock_write_lock( & arp_globals.lock );
    195         for( count = arp_cache_count( & arp_globals.cache ) - 1; count >= 0; -- count ){
    196                 device = arp_cache_get_index( & arp_globals.cache, count );
    197                 if( device ){
    198                         arp_clear_device( device );
    199                         if( device->addr_data ) free( device->addr_data );
    200                         if( device->broadcast_data ) free( device->broadcast_data );
    201                 }
    202         }
    203         arp_cache_clear( & arp_globals.cache );
    204         fibril_rwlock_write_unlock( & arp_globals.lock );
    205         printf( "Cache cleaned\n" );
    206         return EOK;
    207 }
    208 
    209 int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address ){
     185        arp_addr_exclude(&proto->addresses, address->value, address->length);
     186        fibril_rwlock_write_unlock(&arp_globals.lock);
     187        return EOK;
     188}
     189
     190int arp_clean_cache_req(int arp_phone){
     191        int count;
     192        arp_device_ref device;
     193
     194        fibril_rwlock_write_lock(&arp_globals.lock);
     195        for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){
     196                device = arp_cache_get_index(&arp_globals.cache, count);
     197                if(device){
     198                        arp_clear_device(device);
     199                        if(device->addr_data){
     200                                free(device->addr_data);
     201                        }
     202                        if(device->broadcast_data){
     203                                free(device->broadcast_data);
     204                        }
     205                }
     206        }
     207        arp_cache_clear(&arp_globals.cache);
     208        fibril_rwlock_write_unlock(&arp_globals.lock);
     209        printf("Cache cleaned\n");
     210        return EOK;
     211}
     212
     213int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
    210214        ERROR_DECLARE;
    211215
     
    213217
    214218        // copy the given address for exclusive use
    215         tmp = measured_string_copy( address );
    216         if( ERROR_OCCURRED( arp_device_message( device_id, netif, protocol, tmp ))){
    217                 free( tmp->value );
    218                 free( tmp );
     219        tmp = measured_string_copy(address);
     220        if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){
     221                free(tmp->value);
     222                free(tmp);
    219223        }
    220224        return ERROR_CODE;
    221225}
    222226
    223 int arp_translate_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data ){
    224         measured_string_ref     tmp;
    225 
    226         fibril_rwlock_read_lock( & arp_globals.lock );
    227         tmp = arp_translate_message( device_id, protocol, address );
    228         if( tmp ){
    229                 * translation = measured_string_copy( tmp );
    230                 fibril_rwlock_read_unlock( & arp_globals.lock );
    231                 if( * translation ){
    232                         * data = ( ** translation ).value;
     227int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){
     228        measured_string_ref tmp;
     229
     230        fibril_rwlock_read_lock(&arp_globals.lock);
     231        tmp = arp_translate_message(device_id, protocol, address);
     232        if(tmp){
     233                *translation = measured_string_copy(tmp);
     234                fibril_rwlock_read_unlock(&arp_globals.lock);
     235                if(*translation){
     236                        *data = (** translation).value;
    233237                        return EOK;
    234238                }else{
     
    236240                }
    237241        }else{
    238                 fibril_rwlock_read_unlock( & arp_globals.lock );
     242                fibril_rwlock_read_unlock(&arp_globals.lock);
    239243                return ENOENT;
    240244        }
    241245}
    242246
    243 int arp_initialize( async_client_conn_t client_connection ){
     247int arp_initialize(async_client_conn_t client_connection){
    244248        ERROR_DECLARE;
    245249
    246         fibril_rwlock_initialize( & arp_globals.lock );
    247         fibril_rwlock_write_lock( & arp_globals.lock );
     250        fibril_rwlock_initialize(&arp_globals.lock);
     251        fibril_rwlock_write_lock(&arp_globals.lock);
    248252        arp_globals.client_connection = client_connection;
    249         ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache ));
    250         fibril_rwlock_write_unlock( & arp_globals.lock );
    251         return EOK;
    252 }
    253 
    254 int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){
     253        ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
     254        fibril_rwlock_write_unlock(&arp_globals.lock);
     255        return EOK;
     256}
     257
     258int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){
    255259        ERROR_DECLARE;
    256260
    257         * proto = ( arp_proto_ref ) malloc( sizeof( arp_proto_t ));
    258         if( !( * proto )) return ENOMEM;
    259         ( ** proto ).service = service;
    260         ( ** proto ).addr = address;
    261         ( ** proto ).addr_data = address->value;
    262         if( ERROR_OCCURRED( arp_addr_initialize( &( ** proto).addresses ))){
    263                 free( * proto );
     261        *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
     262        if(!(*proto)){
     263                return ENOMEM;
     264        }
     265        (** proto).service = service;
     266        (** proto).addr = address;
     267        (** proto).addr_data = address->value;
     268        if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){
     269                free(*proto);
    264270                return ERROR_CODE;
    265271        }
     
    267273}
    268274
    269 int arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address ){
     275int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){
    270276        ERROR_DECLARE;
    271277
    272         arp_device_ref  device;
    273         arp_proto_ref   proto;
    274         int                             index;
    275         hw_type_t               hardware;
    276 
    277         fibril_rwlock_write_lock( & arp_globals.lock );
     278        arp_device_ref device;
     279        arp_proto_ref proto;
     280        int index;
     281        hw_type_t hardware;
     282
     283        fibril_rwlock_write_lock(&arp_globals.lock);
    278284        // an existing device?
    279         device = arp_cache_find( & arp_globals.cache, device_id );
    280         if( device ){
    281                 if( device->service != service ){
    282                         printf( "Device %d already exists\n", device->device_id );
    283                         fibril_rwlock_write_unlock( & arp_globals.lock );
     285        device = arp_cache_find(&arp_globals.cache, device_id);
     286        if(device){
     287                if(device->service != service){
     288                        printf("Device %d already exists\n", device->device_id);
     289                        fibril_rwlock_write_unlock(&arp_globals.lock);
    284290                        return EEXIST;
    285291                }
    286                 proto = arp_protos_find( & device->protos, protocol );
    287                 if( proto ){
    288                         free( proto->addr );
    289                         free( proto->addr_data );
     292                proto = arp_protos_find(&device->protos, protocol);
     293                if(proto){
     294                        free(proto->addr);
     295                        free(proto->addr_data);
    290296                        proto->addr = address;
    291297                        proto->addr_data = address->value;
    292298                }else{
    293                         if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
    294                                 fibril_rwlock_write_unlock( & arp_globals.lock );
     299                        if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
     300                                fibril_rwlock_write_unlock(&arp_globals.lock);
    295301                                return ERROR_CODE;
    296302                        }
    297                         index = arp_protos_add( & device->protos, proto->service, proto );
    298                         if( index < 0 ){
    299                                 fibril_rwlock_write_unlock( & arp_globals.lock );
    300                                 free( proto );
     303                        index = arp_protos_add(&device->protos, proto->service, proto);
     304                        if(index < 0){
     305                                fibril_rwlock_write_unlock(&arp_globals.lock);
     306                                free(proto);
    301307                                return index;
    302308                        }
    303                         printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol );
     309                        printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol);
    304310                }
    305311        }else{
    306                 hardware = hardware_map( service );
    307                 if( ! hardware ) return ENOENT;
     312                hardware = hardware_map(service);
     313                if(! hardware){
     314                        return ENOENT;
     315                }
    308316                // create a new device
    309                 device = ( arp_device_ref ) malloc( sizeof( arp_device_t ));
    310                 if( ! device ){
    311                         fibril_rwlock_write_unlock( & arp_globals.lock );
     317                device = (arp_device_ref) malloc(sizeof(arp_device_t));
     318                if(! device){
     319                        fibril_rwlock_write_unlock(&arp_globals.lock);
    312320                        return ENOMEM;
    313321                }
    314322                device->hardware = hardware;
    315323                device->device_id = device_id;
    316                 if( ERROR_OCCURRED( arp_protos_initialize( & device->protos ))
    317                 || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
    318                         fibril_rwlock_write_unlock( & arp_globals.lock );
    319                         free( device );
    320                         return ERROR_CODE;
    321                 }
    322                 index = arp_protos_add( & device->protos, proto->service, proto );
    323                 if( index < 0 ){
    324                         fibril_rwlock_write_unlock( & arp_globals.lock );
    325                         arp_protos_destroy( & device->protos );
    326                         free( device );
     324                if(ERROR_OCCURRED(arp_protos_initialize(&device->protos))
     325                        || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
     326                        fibril_rwlock_write_unlock(&arp_globals.lock);
     327                        free(device);
     328                        return ERROR_CODE;
     329                }
     330                index = arp_protos_add(&device->protos, proto->service, proto);
     331                if(index < 0){
     332                        fibril_rwlock_write_unlock(&arp_globals.lock);
     333                        arp_protos_destroy(&device->protos);
     334                        free(device);
    327335                        return index;
    328336                }
    329337                device->service = service;
    330338                // bind the new one
    331                 device->phone = nil_bind_service( device->service, ( ipcarg_t ) device->device_id, SERVICE_ARP, arp_globals.client_connection );
    332                 if( device->phone < 0 ){
    333                         fibril_rwlock_write_unlock( & arp_globals.lock );
    334                         arp_protos_destroy( & device->protos );
    335                         free( device );
     339                device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection);
     340                if(device->phone < 0){
     341                        fibril_rwlock_write_unlock(&arp_globals.lock);
     342                        arp_protos_destroy(&device->protos);
     343                        free(device);
    336344                        return EREFUSED;
    337345                }
    338346                // get packet dimensions
    339                 if( ERROR_OCCURRED( nil_packet_size_req( device->phone, device_id, & device->packet_dimension ))){
    340                         fibril_rwlock_write_unlock( & arp_globals.lock );
    341                         arp_protos_destroy( & device->protos );
    342                         free( device );
     347                if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){
     348                        fibril_rwlock_write_unlock(&arp_globals.lock);
     349                        arp_protos_destroy(&device->protos);
     350                        free(device);
    343351                        return ERROR_CODE;
    344352                }
    345353                // get hardware address
    346                 if( ERROR_OCCURRED( nil_get_addr_req( device->phone, device_id, & device->addr, & device->addr_data ))){
    347                         fibril_rwlock_write_unlock( & arp_globals.lock );
    348                         arp_protos_destroy( & device->protos );
    349                         free( device );
     354                if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){
     355                        fibril_rwlock_write_unlock(&arp_globals.lock);
     356                        arp_protos_destroy(&device->protos);
     357                        free(device);
    350358                        return ERROR_CODE;
    351359                }
    352360                // get broadcast address
    353                 if( ERROR_OCCURRED( nil_get_broadcast_addr_req( device->phone, device_id, & device->broadcast_addr, & device->broadcast_data ))){
    354                         fibril_rwlock_write_unlock( & arp_globals.lock );
    355                         free( device->addr );
    356                         free( device->addr_data );
    357                         arp_protos_destroy( & device->protos );
    358                         free( device );
    359                         return ERROR_CODE;
    360                 }
    361                 if( ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){
    362                         fibril_rwlock_write_unlock( & arp_globals.lock );
    363                         free( device->addr );
    364                         free( device->addr_data );
    365                         free( device->broadcast_addr );
    366                         free( device->broadcast_data );
    367                         arp_protos_destroy( & device->protos );
    368                         free( device );
    369                         return ERROR_CODE;
    370                 }
    371                 printf( "New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol );
    372         }
    373         fibril_rwlock_write_unlock( & arp_globals.lock );
    374         return EOK;
    375 }
    376 
    377 measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){
    378         arp_device_ref          device;
    379         arp_proto_ref           proto;
    380         measured_string_ref     addr;
    381         size_t                          length;
    382         packet_t                        packet;
    383         arp_header_ref          header;
    384 
    385         if( ! target ) return NULL;
    386         device = arp_cache_find( & arp_globals.cache, device_id );
    387         if( ! device ) return NULL;
    388         proto = arp_protos_find( & device->protos, protocol );
    389         if(( ! proto ) || ( proto->addr->length != target->length )) return NULL;
    390         addr = arp_addr_find( & proto->addresses, target->value, target->length );
    391         if( addr ) return addr;
    392         // ARP packet content size = header + ( address + translation ) * 2
    393         length = 8 + ( CONVERT_SIZE( char, uint8_t, proto->addr->length ) + CONVERT_SIZE( char, uint8_t, device->addr->length )) * 2;
    394         if( length > device->packet_dimension.content ) return NULL;
    395         packet = packet_get_4( arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix );
    396         if( ! packet ) return NULL;
    397         header = ( arp_header_ref ) packet_suffix( packet, length );
    398         if( ! header ){
    399                 pq_release( arp_globals.net_phone, packet_get_id( packet ));
     361                if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){
     362                        fibril_rwlock_write_unlock(&arp_globals.lock);
     363                        free(device->addr);
     364                        free(device->addr_data);
     365                        arp_protos_destroy(&device->protos);
     366                        free(device);
     367                        return ERROR_CODE;
     368                }
     369                if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){
     370                        fibril_rwlock_write_unlock(&arp_globals.lock);
     371                        free(device->addr);
     372                        free(device->addr_data);
     373                        free(device->broadcast_addr);
     374                        free(device->broadcast_data);
     375                        arp_protos_destroy(&device->protos);
     376                        free(device);
     377                        return ERROR_CODE;
     378                }
     379                printf("New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol);
     380        }
     381        fibril_rwlock_write_unlock(&arp_globals.lock);
     382        return EOK;
     383}
     384
     385measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){
     386        arp_device_ref device;
     387        arp_proto_ref proto;
     388        measured_string_ref addr;
     389        size_t length;
     390        packet_t packet;
     391        arp_header_ref header;
     392
     393        if(! target){
    400394                return NULL;
    401395        }
    402         header->hardware = htons( device->hardware );
    403         header->hardware_length = ( uint8_t ) device->addr->length;
    404         header->protocol = htons( protocol_map( device->service, protocol ));
    405         header->protocol_length = ( uint8_t ) proto->addr->length;
    406         header->operation = htons( ARPOP_REQUEST );
    407         length = sizeof( arp_header_t );
    408         memcpy((( uint8_t * ) header ) + length, device->addr->value, device->addr->length );
     396        device = arp_cache_find(&arp_globals.cache, device_id);
     397        if(! device){
     398                return NULL;
     399        }
     400        proto = arp_protos_find(&device->protos, protocol);
     401        if((! proto) || (proto->addr->length != target->length)){
     402                return NULL;
     403        }
     404        addr = arp_addr_find(&proto->addresses, target->value, target->length);
     405        if(addr){
     406                return addr;
     407        }
     408        // ARP packet content size = header + (address + translation) * 2
     409        length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2;
     410        if(length > device->packet_dimension.content){
     411                return NULL;
     412        }
     413        packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
     414        if(! packet){
     415                return NULL;
     416        }
     417        header = (arp_header_ref) packet_suffix(packet, length);
     418        if(! header){
     419                pq_release(arp_globals.net_phone, packet_get_id(packet));
     420                return NULL;
     421        }
     422        header->hardware = htons(device->hardware);
     423        header->hardware_length = (uint8_t) device->addr->length;
     424        header->protocol = htons(protocol_map(device->service, protocol));
     425        header->protocol_length = (uint8_t) proto->addr->length;
     426        header->operation = htons(ARPOP_REQUEST);
     427        length = sizeof(arp_header_t);
     428        memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length);
    409429        length += device->addr->length;
    410         memcpy((( uint8_t * ) header ) + length, proto->addr->value, proto->addr->length );
     430        memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length);
    411431        length += proto->addr->length;
    412         bzero((( uint8_t * ) header ) + length, device->addr->length );
     432        bzero(((uint8_t *) header) + length, device->addr->length);
    413433        length += device->addr->length;
    414         memcpy((( uint8_t * ) header ) + length, target->value, target->length );
    415         if( packet_set_addr( packet, ( uint8_t * ) device->addr->value, ( uint8_t * ) device->broadcast_addr->value, CONVERT_SIZE( char, uint8_t, device->addr->length )) != EOK ){
    416                 pq_release( arp_globals.net_phone, packet_get_id( packet ));
     434        memcpy(((uint8_t *) header) + length, target->value, target->length);
     435        if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){
     436                pq_release(arp_globals.net_phone, packet_get_id(packet));
    417437                return NULL;
    418438        }
    419         nil_send_msg( device->phone, device_id, packet, SERVICE_ARP );
     439        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    420440        return NULL;
    421441}
    422442
    423 int arp_receive_message( device_id_t device_id, packet_t packet ){
     443int arp_receive_message(device_id_t device_id, packet_t packet){
    424444        ERROR_DECLARE;
    425445
    426         size_t                          length;
    427         arp_header_ref          header;
    428         arp_device_ref          device;
    429         arp_proto_ref           proto;
    430         measured_string_ref     hw_source;
    431         uint8_t *                       src_hw;
    432         uint8_t *                       src_proto;
    433         uint8_t *                       des_hw;
    434         uint8_t *                       des_proto;
    435 
    436         length = packet_get_data_length( packet );
    437         if( length <= sizeof( arp_header_t )) return EINVAL;
    438         device = arp_cache_find( & arp_globals.cache, device_id );
    439         if( ! device ) return ENOENT;
    440         header = ( arp_header_ref ) packet_get_data( packet );
    441         if(( ntohs( header->hardware ) != device->hardware )
    442         || ( length < sizeof( arp_header_t ) + header->hardware_length * 2u + header->protocol_length * 2u )){
     446        size_t length;
     447        arp_header_ref header;
     448        arp_device_ref device;
     449        arp_proto_ref proto;
     450        measured_string_ref hw_source;
     451        uint8_t * src_hw;
     452        uint8_t * src_proto;
     453        uint8_t * des_hw;
     454        uint8_t * des_proto;
     455
     456        length = packet_get_data_length(packet);
     457        if(length <= sizeof(arp_header_t)){
    443458                return EINVAL;
    444459        }
    445         proto = arp_protos_find( & device->protos, protocol_unmap( device->service, ntohs( header->protocol )));
    446         if( ! proto ) return ENOENT;
    447         src_hw = (( uint8_t * ) header ) + sizeof( arp_header_t );
     460        device = arp_cache_find(&arp_globals.cache, device_id);
     461        if(! device){
     462                return ENOENT;
     463        }
     464        header = (arp_header_ref) packet_get_data(packet);
     465        if((ntohs(header->hardware) != device->hardware)
     466                || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){
     467                return EINVAL;
     468        }
     469        proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol)));
     470        if(! proto){
     471                return ENOENT;
     472        }
     473        src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
    448474        src_proto = src_hw + header->hardware_length;
    449475        des_hw = src_proto + header->protocol_length;
    450476        des_proto = des_hw + header->hardware_length;
    451         hw_source = arp_addr_find( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ));
     477        hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length));
    452478        // exists?
    453         if( hw_source ){
    454                 if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){
     479        if(hw_source){
     480                if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){
    455481                        return EINVAL;
    456482                }
    457                 memcpy( hw_source->value, src_hw, hw_source->length );
     483                memcpy(hw_source->value, src_hw, hw_source->length);
    458484        }
    459485        // is my protocol address?
    460         if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->protocol_length )){
     486        if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){
    461487                return EINVAL;
    462488        }
    463         if( ! str_lcmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){
     489        if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){
    464490                // not already upadted?
    465                 if( ! hw_source ){
    466                         hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length ));
    467                         if( ! hw_source ) return ENOMEM;
    468                         ERROR_PROPAGATE( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source ));
    469                 }
    470                 if( ntohs( header->operation ) == ARPOP_REQUEST ){
    471                         header->operation = htons( ARPOP_REPLY );
    472                         memcpy( des_proto, src_proto, header->protocol_length );
    473                         memcpy( src_proto, proto->addr->value, header->protocol_length );
    474                         memcpy( src_hw, device->addr->value, device->packet_dimension.addr_len );
    475                         memcpy( des_hw, hw_source->value, header->hardware_length );
    476                         ERROR_PROPAGATE( packet_set_addr( packet, src_hw, des_hw, header->hardware_length ));
    477                         nil_send_msg( device->phone, device_id, packet, SERVICE_ARP );
     491                if(! hw_source){
     492                        hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length));
     493                        if(! hw_source){
     494                                return ENOMEM;
     495                        }
     496                        ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source));
     497                }
     498                if(ntohs(header->operation) == ARPOP_REQUEST){
     499                        header->operation = htons(ARPOP_REPLY);
     500                        memcpy(des_proto, src_proto, header->protocol_length);
     501                        memcpy(src_proto, proto->addr->value, header->protocol_length);
     502                        memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len);
     503                        memcpy(des_hw, hw_source->value, header->hardware_length);
     504                        ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length));
     505                        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    478506                        return 1;
    479507                }
     
    482510}
    483511
    484 void arp_clear_device( arp_device_ref device ){
    485         int                             count;
    486         arp_proto_ref   proto;
    487 
    488         for( count = arp_protos_count( & device->protos ) - 1; count >= 0; -- count ){
    489                 proto = arp_protos_get_index( & device->protos, count );
    490                 if( proto ){
    491                         if( proto->addr ) free( proto->addr );
    492                         if( proto->addr_data ) free( proto->addr_data );
    493                         arp_addr_destroy( & proto->addresses );
    494                 }
    495         }
    496         arp_protos_clear( & device->protos );
    497 }
    498 
    499 int arp_connect_module( services_t service ){
    500         if( service != SERVICE_ARP ) return EINVAL;
    501         return EOK;
    502 }
    503 
    504 int arp_mtu_changed_message( device_id_t device_id, size_t mtu ){
    505         arp_device_ref  device;
    506 
    507         fibril_rwlock_write_lock( & arp_globals.lock );
    508         device = arp_cache_find( & arp_globals.cache, device_id );
    509         if( ! device ){
    510                 fibril_rwlock_write_unlock( & arp_globals.lock );
     512void arp_clear_device(arp_device_ref device){
     513        int count;
     514        arp_proto_ref proto;
     515
     516        for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){
     517                proto = arp_protos_get_index(&device->protos, count);
     518                if(proto){
     519                        if(proto->addr){
     520                                free(proto->addr);
     521                        }
     522                        if(proto->addr_data){
     523                                free(proto->addr_data);
     524                        }
     525                        arp_addr_destroy(&proto->addresses);
     526                }
     527        }
     528        arp_protos_clear(&device->protos);
     529}
     530
     531int arp_connect_module(services_t service){
     532        if(service != SERVICE_ARP){
     533                return EINVAL;
     534        }
     535        return EOK;
     536}
     537
     538int arp_mtu_changed_message(device_id_t device_id, size_t mtu){
     539        arp_device_ref device;
     540
     541        fibril_rwlock_write_lock(&arp_globals.lock);
     542        device = arp_cache_find(&arp_globals.cache, device_id);
     543        if(! device){
     544                fibril_rwlock_write_unlock(&arp_globals.lock);
    511545                return ENOENT;
    512546        }
    513547        device->packet_dimension.content = mtu;
    514         printf( "arp - device %d changed mtu to %d\n\n", device_id, mtu );
    515         fibril_rwlock_write_unlock( & arp_globals.lock );
    516         return EOK;
    517 }
    518 
    519 int arp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
     548        printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
     549        fibril_rwlock_write_unlock(&arp_globals.lock);
     550        return EOK;
     551}
     552
     553int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
    520554        ERROR_DECLARE;
    521555
    522         measured_string_ref     address;
    523         measured_string_ref     translation;
    524         char *                          data;
    525         packet_t                        packet;
    526         packet_t                        next;
    527 
    528 //      printf( "message %d - %d\n", IPC_GET_METHOD( * call ), NET_ARP_FIRST );
    529         * answer_count = 0;
    530         switch( IPC_GET_METHOD( * call )){
     556        measured_string_ref address;
     557        measured_string_ref translation;
     558        char * data;
     559        packet_t packet;
     560        packet_t next;
     561
     562//      printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_ARP_FIRST);
     563        *answer_count = 0;
     564        switch(IPC_GET_METHOD(*call)){
    531565                case IPC_M_PHONE_HUNGUP:
    532566                        return EOK;
    533567                case NET_ARP_DEVICE:
    534                         ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1 ));
    535                         if( ERROR_OCCURRED( arp_device_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), ARP_GET_NETIF( call ), address ))){
    536                                 free( address );
    537                                 free( data );
     568                        ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
     569                        if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){
     570                                free(address);
     571                                free(data);
    538572                        }
    539573                        return ERROR_CODE;
    540574                case NET_ARP_TRANSLATE:
    541                         ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1 ));
    542                         fibril_rwlock_read_lock( & arp_globals.lock );
    543                         translation = arp_translate_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address );
    544                         free( address );
    545                         free( data );
    546                         if( ! translation ){
    547                                 fibril_rwlock_read_unlock( & arp_globals.lock );
     575                        ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
     576                        fibril_rwlock_read_lock(&arp_globals.lock);
     577                        translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
     578                        free(address);
     579                        free(data);
     580                        if(! translation){
     581                                fibril_rwlock_read_unlock(&arp_globals.lock);
    548582                                return ENOENT;
    549583                        }
    550                         ERROR_CODE = measured_strings_reply( translation, 1 );
    551                         fibril_rwlock_read_unlock( & arp_globals.lock );
     584                        ERROR_CODE = measured_strings_reply(translation, 1);
     585                        fibril_rwlock_read_unlock(&arp_globals.lock);
    552586                        return ERROR_CODE;
    553587                case NET_ARP_CLEAR_DEVICE:
    554                         return arp_clear_device_req( 0, IPC_GET_DEVICE( call ));
     588                        return arp_clear_device_req(0, IPC_GET_DEVICE(call));
    555589                case NET_ARP_CLEAR_ADDRESS:
    556                         ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1 ));
    557                         arp_clear_address_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address );
    558                         free( address );
    559                         free( data );
     590                        ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
     591                        arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
     592                        free(address);
     593                        free(data);
    560594                        return EOK;
    561595                case NET_ARP_CLEAN_CACHE:
    562                         return arp_clean_cache_req( 0 );
     596                        return arp_clean_cache_req(0);
    563597                case NET_IL_DEVICE_STATE:
    564598                        // do nothing - keep the cache
    565599                        return EOK;
    566600                case NET_IL_RECEIVED:
    567                         if( ! ERROR_OCCURRED( packet_translate( arp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
    568                                 fibril_rwlock_read_lock( & arp_globals.lock );
     601                        if(! ERROR_OCCURRED(packet_translate(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
     602                                fibril_rwlock_read_lock(&arp_globals.lock);
    569603                                do{
    570                                         next = pq_detach( packet );
    571                                         ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( call ), packet );
    572                                         if( ERROR_CODE != 1 ) pq_release( arp_globals.net_phone, packet_get_id( packet ));
     604                                        next = pq_detach(packet);
     605                                        ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet);
     606                                        if(ERROR_CODE != 1){
     607                                                pq_release(arp_globals.net_phone, packet_get_id(packet));
     608                                        }
    573609                                        packet = next;
    574                                 }while( packet );
    575                                 fibril_rwlock_read_unlock( & arp_globals.lock );
     610                                }while(packet);
     611                                fibril_rwlock_read_unlock(&arp_globals.lock);
    576612                        }
    577613                        return ERROR_CODE;
    578614                case NET_IL_MTU_CHANGED:
    579                         return arp_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call ));
     615                        return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call));
    580616        }
    581617        return ENOTSUP;
Note: See TracChangeset for help on using the changeset viewer.