Ignore:
File:
1 edited

Legend:

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

    ra64c64d r91478aa  
    7373arp_globals_t   arp_globals;
    7474
    75 /** Clears the device specific data.
    76  *  @param[in] device The device specific data.
    77  */
    78 void arp_clear_device(arp_device_ref device);
    79 
    8075/** Creates new protocol specific data.
    8176 *  Allocates and returns the needed memory block as the proto parameter.
     
    8681 *  @returns ENOMEM if there is not enough memory left.
    8782 */
    88 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 );
     84
     85/** Clears the device specific data.
     86 *  @param[in] device The device specific data.
     87 */
     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);
    106 
    107 /** Updates the device content length according to the new MTU value.
     105int     arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address );
     106
     107/** Returns the hardware address for the given protocol address.
     108 *  Sends the ARP request packet if the hardware address is not found in the cache.
    108109 *  @param[in] device_id The device identifier.
    109  *  @param[in] mtu The new mtu value.
    110  *  @returns ENOENT if device is not found.
    111  *  @returns EOK on success.
    112  */
    113 int arp_mtu_changed_message(device_id_t device_id, size_t mtu);
     110 *  @param[in] protocol The protocol service.
     111 *  @param[in] target The target protocol address.
     112 *  @returns The hardware address of the target.
     113 *  @returns NULL if the target parameter is NULL.
     114 *  @returns NULL if the device is not found.
     115 *  @returns NULL if the device packet is too small to send a request.
     116 *  @returns NULL if the hardware address is not found in the cache.
     117 */
     118measured_string_ref     arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target );
    114119
    115120/** Processes the received ARP packet.
     
    126131 *  @returns ENOMEM if there is not enough memory left.
    127132 */
    128 int arp_receive_message(device_id_t device_id, packet_t packet);
    129 
    130 /** Returns the hardware address for the given protocol address.
    131  *  Sends the ARP request packet if the hardware address is not found in the cache.
     133int     arp_receive_message( device_id_t device_id, packet_t packet );
     134
     135/** Updates the device content length according to the new MTU value.
    132136 *  @param[in] device_id The device identifier.
    133  *  @param[in] protocol The protocol service.
    134  *  @param[in] target The target protocol address.
    135  *  @returns The hardware address of the target.
    136  *  @returns NULL if the target parameter is NULL.
    137  *  @returns NULL if the device is not found.
    138  *  @returns NULL if the device packet is too small to send a request.
    139  *  @returns NULL if the hardware address is not found in the cache.
    140  */
    141 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target);
     137 *  @param[in] mtu The new mtu value.
     138 *  @returns ENOENT if device is not found.
     139 *  @returns EOK on success.
     140 */
     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 int arp_clean_cache_req(int arp_phone){
    152         int count;
    153         arp_device_ref device;
    154 
    155         fibril_rwlock_write_lock(&arp_globals.lock);
    156         for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){
    157                 device = arp_cache_get_index(&arp_globals.cache, count);
    158                 if(device){
    159                         arp_clear_device(device);
    160                         if(device->addr_data){
    161                                 free(device->addr_data);
    162                         }
    163                         if(device->broadcast_data){
    164                                 free(device->broadcast_data);
    165                         }
    166                 }
    167         }
    168         arp_cache_clear(&arp_globals.cache);
    169         fibril_rwlock_write_unlock(&arp_globals.lock);
    170         printf("Cache cleaned\n");
    171         return EOK;
    172 }
    173 
    174 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){
    175         arp_device_ref device;
    176         arp_proto_ref proto;
    177 
    178         fibril_rwlock_write_lock(&arp_globals.lock);
    179         device = arp_cache_find(&arp_globals.cache, device_id);
    180         if(! device){
    181                 fibril_rwlock_write_unlock(&arp_globals.lock);
     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 ){
     152        return task_get_id();
     153}
     154
     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 );
    182162                return ENOENT;
    183163        }
    184         proto = arp_protos_find(&device->protos, protocol);
    185         if(! proto){
    186                 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 );
    187178                return ENOENT;
    188179        }
    189         arp_addr_exclude(&proto->addresses, address->value, address->length);
    190         fibril_rwlock_write_unlock(&arp_globals.lock);
    191         return EOK;
    192 }
    193 
    194 void arp_clear_device(arp_device_ref device){
    195         int count;
    196         arp_proto_ref proto;
    197 
    198         for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){
    199                 proto = arp_protos_get_index(&device->protos, count);
    200                 if(proto){
    201                         if(proto->addr){
    202                                 free(proto->addr);
    203                         }
    204                         if(proto->addr_data){
    205                                 free(proto->addr_data);
    206                         }
    207                         arp_addr_destroy(&proto->addresses);
    208                 }
    209         }
    210         arp_protos_clear(&device->protos);
    211 }
    212 
    213 int arp_clear_device_req(int arp_phone, device_id_t device_id){
    214         arp_device_ref device;
    215 
    216         fibril_rwlock_write_lock(&arp_globals.lock);
    217         device = arp_cache_find(&arp_globals.cache, device_id);
    218         if(! device){
    219                 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 );
    220183                return ENOENT;
    221184        }
    222         arp_clear_device(device);
    223         printf("Device %d cleared\n", device_id);
    224         fibril_rwlock_write_unlock(&arp_globals.lock);
    225         return EOK;
    226 }
    227 
    228 int arp_connect_module(services_t service){
    229         if(service != SERVICE_ARP){
    230                 return EINVAL;
    231         }
    232         return EOK;
    233 }
    234 
    235 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, 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 ) 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
     209int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address ){
    236210        ERROR_DECLARE;
    237211
    238         arp_device_ref device;
    239         arp_proto_ref proto;
    240         int index;
    241         hw_type_t hardware;
    242 
    243         fibril_rwlock_write_lock(&arp_globals.lock);
     212        measured_string_ref tmp;
     213
     214        // 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        }
     220        return ERROR_CODE;
     221}
     222
     223int 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;
     233                        return EOK;
     234                }else{
     235                        return ENOMEM;
     236                }
     237        }else{
     238                fibril_rwlock_read_unlock( & arp_globals.lock );
     239                return ENOENT;
     240        }
     241}
     242
     243int arp_initialize( async_client_conn_t client_connection ){
     244        ERROR_DECLARE;
     245
     246        fibril_rwlock_initialize( & arp_globals.lock );
     247        fibril_rwlock_write_lock( & arp_globals.lock );
     248        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
     254int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){
     255        ERROR_DECLARE;
     256
     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 );
     264                return ERROR_CODE;
     265        }
     266        return EOK;
     267}
     268
     269int arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address ){
     270        ERROR_DECLARE;
     271
     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 );
    244278        // an existing device?
    245         device = arp_cache_find(&arp_globals.cache, device_id);
    246         if(device){
    247                 if(device->service != service){
    248                         printf("Device %d already exists\n", device->device_id);
    249                         fibril_rwlock_write_unlock(&arp_globals.lock);
     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 );
    250284                        return EEXIST;
    251285                }
    252                 proto = arp_protos_find(&device->protos, protocol);
    253                 if(proto){
    254                         free(proto->addr);
    255                         free(proto->addr_data);
     286                proto = arp_protos_find( & device->protos, protocol );
     287                if( proto ){
     288                        free( proto->addr );
     289                        free( proto->addr_data );
    256290                        proto->addr = address;
    257291                        proto->addr_data = address->value;
    258292                }else{
    259                         if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
    260                                 fibril_rwlock_write_unlock(&arp_globals.lock);
     293                        if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
     294                                fibril_rwlock_write_unlock( & arp_globals.lock );
    261295                                return ERROR_CODE;
    262296                        }
    263                         index = arp_protos_add(&device->protos, proto->service, proto);
    264                         if(index < 0){
    265                                 fibril_rwlock_write_unlock(&arp_globals.lock);
    266                                 free(proto);
     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 );
    267301                                return index;
    268302                        }
    269                         printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol);
     303                        printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol );
    270304                }
    271305        }else{
    272                 hardware = hardware_map(service);
    273                 if(! hardware){
    274                         return ENOENT;
    275                 }
     306                hardware = hardware_map( service );
     307                if( ! hardware ) return ENOENT;
    276308                // create a new device
    277                 device = (arp_device_ref) malloc(sizeof(arp_device_t));
    278                 if(! device){
    279                         fibril_rwlock_write_unlock(&arp_globals.lock);
     309                device = ( arp_device_ref ) malloc( sizeof( arp_device_t ));
     310                if( ! device ){
     311                        fibril_rwlock_write_unlock( & arp_globals.lock );
    280312                        return ENOMEM;
    281313                }
    282314                device->hardware = hardware;
    283315                device->device_id = device_id;
    284                 if(ERROR_OCCURRED(arp_protos_initialize(&device->protos))
    285                         || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
    286                         fibril_rwlock_write_unlock(&arp_globals.lock);
    287                         free(device);
    288                         return ERROR_CODE;
    289                 }
    290                 index = arp_protos_add(&device->protos, proto->service, proto);
    291                 if(index < 0){
    292                         fibril_rwlock_write_unlock(&arp_globals.lock);
    293                         arp_protos_destroy(&device->protos);
    294                         free(device);
     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 );
    295327                        return index;
    296328                }
    297329                device->service = service;
    298330                // bind the new one
    299                 device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection);
    300                 if(device->phone < 0){
    301                         fibril_rwlock_write_unlock(&arp_globals.lock);
    302                         arp_protos_destroy(&device->protos);
    303                         free(device);
     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 );
    304336                        return EREFUSED;
    305337                }
    306338                // get packet dimensions
    307                 if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){
    308                         fibril_rwlock_write_unlock(&arp_globals.lock);
    309                         arp_protos_destroy(&device->protos);
    310                         free(device);
     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 );
    311343                        return ERROR_CODE;
    312344                }
    313345                // get hardware address
    314                 if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){
    315                         fibril_rwlock_write_unlock(&arp_globals.lock);
    316                         arp_protos_destroy(&device->protos);
    317                         free(device);
     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 );
    318350                        return ERROR_CODE;
    319351                }
    320352                // get broadcast address
    321                 if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){
    322                         fibril_rwlock_write_unlock(&arp_globals.lock);
    323                         free(device->addr);
    324                         free(device->addr_data);
    325                         arp_protos_destroy(&device->protos);
    326                         free(device);
    327                         return ERROR_CODE;
    328                 }
    329                 if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){
    330                         fibril_rwlock_write_unlock(&arp_globals.lock);
    331                         free(device->addr);
    332                         free(device->addr_data);
    333                         free(device->broadcast_addr);
    334                         free(device->broadcast_data);
    335                         arp_protos_destroy(&device->protos);
    336                         free(device);
    337                         return ERROR_CODE;
    338                 }
    339                 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);
    340         }
    341         fibril_rwlock_write_unlock(&arp_globals.lock);
    342         return EOK;
    343 }
    344 
    345 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref 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
     377measured_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 ));
     400                return NULL;
     401        }
     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 );
     409        length += device->addr->length;
     410        memcpy((( uint8_t * ) header ) + length, proto->addr->value, proto->addr->length );
     411        length += proto->addr->length;
     412        bzero((( uint8_t * ) header ) + length, device->addr->length );
     413        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 ));
     417                return NULL;
     418        }
     419        nil_send_msg( device->phone, device_id, packet, SERVICE_ARP );
     420        return NULL;
     421}
     422
     423int arp_receive_message( device_id_t device_id, packet_t packet ){
    346424        ERROR_DECLARE;
    347425
    348         measured_string_ref tmp;
    349 
    350         // copy the given address for exclusive use
    351         tmp = measured_string_copy(address);
    352         if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){
    353                 free(tmp->value);
    354                 free(tmp);
    355         }
    356         return ERROR_CODE;
    357 }
    358 
    359 int arp_initialize(async_client_conn_t client_connection){
     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 )){
     443                return EINVAL;
     444        }
     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 );
     448        src_proto = src_hw + header->hardware_length;
     449        des_hw = src_proto + header->protocol_length;
     450        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 ));
     452        // exists?
     453        if( hw_source ){
     454                if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){
     455                        return EINVAL;
     456                }
     457                memcpy( hw_source->value, src_hw, hw_source->length );
     458        }
     459        // is my protocol address?
     460        if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->protocol_length )){
     461                return EINVAL;
     462        }
     463        if( ! str_lcmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){
     464                // 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 );
     478                        return 1;
     479                }
     480        }
     481        return EOK;
     482}
     483
     484void 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
     499int arp_connect_module( services_t service ){
     500        if( service != SERVICE_ARP ) return EINVAL;
     501        return EOK;
     502}
     503
     504int 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 );
     511                return ENOENT;
     512        }
     513        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
     519int arp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
    360520        ERROR_DECLARE;
    361521
    362         fibril_rwlock_initialize(&arp_globals.lock);
    363         fibril_rwlock_write_lock(&arp_globals.lock);
    364         arp_globals.client_connection = client_connection;
    365         ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
    366         fibril_rwlock_write_unlock(&arp_globals.lock);
    367         return EOK;
    368 }
    369 
    370 int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
    371         ERROR_DECLARE;
    372 
    373         measured_string_ref address;
    374         measured_string_ref translation;
    375         char * data;
    376         packet_t packet;
    377         packet_t next;
    378 
    379 //      printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_ARP_FIRST);
    380         *answer_count = 0;
    381         switch(IPC_GET_METHOD(*call)){
     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 )){
    382531                case IPC_M_PHONE_HUNGUP:
    383532                        return EOK;
    384533                case NET_ARP_DEVICE:
    385                         ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    386                         if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){
    387                                 free(address);
    388                                 free(data);
     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 );
    389538                        }
    390539                        return ERROR_CODE;
    391540                case NET_ARP_TRANSLATE:
    392                         ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    393                         fibril_rwlock_read_lock(&arp_globals.lock);
    394                         translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
    395                         free(address);
    396                         free(data);
    397                         if(! translation){
    398                                 fibril_rwlock_read_unlock(&arp_globals.lock);
     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 );
    399548                                return ENOENT;
    400549                        }
    401                         ERROR_CODE = measured_strings_reply(translation, 1);
    402                         fibril_rwlock_read_unlock(&arp_globals.lock);
     550                        ERROR_CODE = measured_strings_reply( translation, 1 );
     551                        fibril_rwlock_read_unlock( & arp_globals.lock );
    403552                        return ERROR_CODE;
    404553                case NET_ARP_CLEAR_DEVICE:
    405                         return arp_clear_device_req(0, IPC_GET_DEVICE(call));
     554                        return arp_clear_device_req( 0, IPC_GET_DEVICE( call ));
    406555                case NET_ARP_CLEAR_ADDRESS:
    407                         ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    408                         arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
    409                         free(address);
    410                         free(data);
     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 );
    411560                        return EOK;
    412561                case NET_ARP_CLEAN_CACHE:
    413                         return arp_clean_cache_req(0);
     562                        return arp_clean_cache_req( 0 );
    414563                case NET_IL_DEVICE_STATE:
    415564                        // do nothing - keep the cache
    416565                        return EOK;
    417566                case NET_IL_RECEIVED:
    418                         if(! ERROR_OCCURRED(packet_translate(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    419                                 fibril_rwlock_read_lock(&arp_globals.lock);
     567                        if( ! ERROR_OCCURRED( packet_translate( arp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
     568                                fibril_rwlock_read_lock( & arp_globals.lock );
    420569                                do{
    421                                         next = pq_detach(packet);
    422                                         ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet);
    423                                         if(ERROR_CODE != 1){
    424                                                 pq_release(arp_globals.net_phone, packet_get_id(packet));
    425                                         }
     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 ));
    426573                                        packet = next;
    427                                 }while(packet);
    428                                 fibril_rwlock_read_unlock(&arp_globals.lock);
     574                                }while( packet );
     575                                fibril_rwlock_read_unlock( & arp_globals.lock );
    429576                        }
    430577                        return ERROR_CODE;
    431578                case NET_IL_MTU_CHANGED:
    432                         return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call));
     579                        return arp_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call ));
    433580        }
    434581        return ENOTSUP;
    435582}
    436583
    437 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){
    438         arp_device_ref device;
    439 
    440         fibril_rwlock_write_lock(&arp_globals.lock);
    441         device = arp_cache_find(&arp_globals.cache, device_id);
    442         if(! device){
    443                 fibril_rwlock_write_unlock(&arp_globals.lock);
    444                 return ENOENT;
    445         }
    446         device->packet_dimension.content = mtu;
    447         printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
    448         fibril_rwlock_write_unlock(&arp_globals.lock);
    449         return EOK;
    450 }
    451 
    452 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){
    453         ERROR_DECLARE;
    454 
    455         *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
    456         if(!(*proto)){
    457                 return ENOMEM;
    458         }
    459         (** proto).service = service;
    460         (** proto).addr = address;
    461         (** proto).addr_data = address->value;
    462         if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){
    463                 free(*proto);
    464                 return ERROR_CODE;
    465         }
    466         return EOK;
    467 }
    468 
    469 int arp_receive_message(device_id_t device_id, packet_t packet){
    470         ERROR_DECLARE;
    471 
    472         size_t length;
    473         arp_header_ref header;
    474         arp_device_ref device;
    475         arp_proto_ref proto;
    476         measured_string_ref hw_source;
    477         uint8_t * src_hw;
    478         uint8_t * src_proto;
    479         uint8_t * des_hw;
    480         uint8_t * des_proto;
    481 
    482         length = packet_get_data_length(packet);
    483         if(length <= sizeof(arp_header_t)){
    484                 return EINVAL;
    485         }
    486         device = arp_cache_find(&arp_globals.cache, device_id);
    487         if(! device){
    488                 return ENOENT;
    489         }
    490         header = (arp_header_ref) packet_get_data(packet);
    491         if((ntohs(header->hardware) != device->hardware)
    492                 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){
    493                 return EINVAL;
    494         }
    495         proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol)));
    496         if(! proto){
    497                 return ENOENT;
    498         }
    499         src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
    500         src_proto = src_hw + header->hardware_length;
    501         des_hw = src_proto + header->protocol_length;
    502         des_proto = des_hw + header->hardware_length;
    503         hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length));
    504         // exists?
    505         if(hw_source){
    506                 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){
    507                         return EINVAL;
    508                 }
    509                 memcpy(hw_source->value, src_hw, hw_source->length);
    510         }
    511         // is my protocol address?
    512         if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){
    513                 return EINVAL;
    514         }
    515         if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){
    516                 // not already upadted?
    517                 if(! hw_source){
    518                         hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length));
    519                         if(! hw_source){
    520                                 return ENOMEM;
    521                         }
    522                         ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source));
    523                 }
    524                 if(ntohs(header->operation) == ARPOP_REQUEST){
    525                         header->operation = htons(ARPOP_REPLY);
    526                         memcpy(des_proto, src_proto, header->protocol_length);
    527                         memcpy(src_proto, proto->addr->value, header->protocol_length);
    528                         memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len);
    529                         memcpy(des_hw, hw_source->value, header->hardware_length);
    530                         ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length));
    531                         nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    532                         return 1;
    533                 }
    534         }
    535         return EOK;
    536 }
    537 
    538 task_id_t arp_task_get_id(void){
    539         return task_get_id();
    540 }
    541 
    542 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){
    543         arp_device_ref device;
    544         arp_proto_ref proto;
    545         measured_string_ref addr;
    546         size_t length;
    547         packet_t packet;
    548         arp_header_ref header;
    549 
    550         if(! target){
    551                 return NULL;
    552         }
    553         device = arp_cache_find(&arp_globals.cache, device_id);
    554         if(! device){
    555                 return NULL;
    556         }
    557         proto = arp_protos_find(&device->protos, protocol);
    558         if((! proto) || (proto->addr->length != target->length)){
    559                 return NULL;
    560         }
    561         addr = arp_addr_find(&proto->addresses, target->value, target->length);
    562         if(addr){
    563                 return addr;
    564         }
    565         // ARP packet content size = header + (address + translation) * 2
    566         length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2;
    567         if(length > device->packet_dimension.content){
    568                 return NULL;
    569         }
    570         packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
    571         if(! packet){
    572                 return NULL;
    573         }
    574         header = (arp_header_ref) packet_suffix(packet, length);
    575         if(! header){
    576                 pq_release(arp_globals.net_phone, packet_get_id(packet));
    577                 return NULL;
    578         }
    579         header->hardware = htons(device->hardware);
    580         header->hardware_length = (uint8_t) device->addr->length;
    581         header->protocol = htons(protocol_map(device->service, protocol));
    582         header->protocol_length = (uint8_t) proto->addr->length;
    583         header->operation = htons(ARPOP_REQUEST);
    584         length = sizeof(arp_header_t);
    585         memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length);
    586         length += device->addr->length;
    587         memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length);
    588         length += proto->addr->length;
    589         bzero(((uint8_t *) header) + length, device->addr->length);
    590         length += device->addr->length;
    591         memcpy(((uint8_t *) header) + length, target->value, target->length);
    592         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){
    593                 pq_release(arp_globals.net_phone, packet_get_id(packet));
    594                 return NULL;
    595         }
    596         nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    597         return NULL;
    598 }
    599 
    600 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){
    601         measured_string_ref tmp;
    602 
    603         fibril_rwlock_read_lock(&arp_globals.lock);
    604         tmp = arp_translate_message(device_id, protocol, address);
    605         if(tmp){
    606                 *translation = measured_string_copy(tmp);
    607                 fibril_rwlock_read_unlock(&arp_globals.lock);
    608                 if(*translation){
    609                         *data = (** translation).value;
    610                         return EOK;
    611                 }else{
    612                         return ENOMEM;
    613                 }
    614         }else{
    615                 fibril_rwlock_read_unlock(&arp_globals.lock);
    616                 return ENOENT;
    617         }
    618 }
    619 
    620584/** @}
    621585 */
Note: See TracChangeset for help on using the changeset viewer.