Ignore:
File:
1 edited

Legend:

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

    ra64c64d raadf01e  
    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.
     
    8782 */
    8883int 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
     
    105105int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address);
    106106
    107 /** Updates the device content length according to the new MTU value.
     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.
     
    128133int arp_receive_message(device_id_t device_id, packet_t packet);
    129134
    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.
     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/*@}*/
     
    148148
    149149GENERIC_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);
     162                return ENOENT;
     163        }
     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);
     178                return ENOENT;
     179        }
     180        proto = arp_protos_find(&device->protos, protocol);
     181        if(! proto){
     182                fibril_rwlock_write_unlock(&arp_globals.lock);
     183                return ENOENT;
     184        }
     185        arp_addr_exclude(&proto->addresses, address->value, address->length);
     186        fibril_rwlock_write_unlock(&arp_globals.lock);
     187        return EOK;
     188}
    150189
    151190int arp_clean_cache_req(int arp_phone){
     
    172211}
    173212
    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 
     213int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
     214        ERROR_DECLARE;
     215
     216        measured_string_ref tmp;
     217
     218        // copy the given address for exclusive use
     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);
     223        }
     224        return ERROR_CODE;
     225}
     226
     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;
     237                        return EOK;
     238                }else{
     239                        return ENOMEM;
     240                }
     241        }else{
     242                fibril_rwlock_read_unlock(&arp_globals.lock);
     243                return ENOENT;
     244        }
     245}
     246
     247int arp_initialize(async_client_conn_t client_connection){
     248        ERROR_DECLARE;
     249
     250        fibril_rwlock_initialize(&arp_globals.lock);
    178251        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);
    182                 return ENOENT;
    183         }
    184         proto = arp_protos_find(&device->protos, protocol);
    185         if(! proto){
    186                 fibril_rwlock_write_unlock(&arp_globals.lock);
    187                 return ENOENT;
    188         }
    189         arp_addr_exclude(&proto->addresses, address->value, address->length);
     252        arp_globals.client_connection = client_connection;
     253        ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
    190254        fibril_rwlock_write_unlock(&arp_globals.lock);
    191255        return EOK;
    192256}
    193257
    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);
    220                 return ENOENT;
    221         }
    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;
     258int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){
     259        ERROR_DECLARE;
     260
     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);
     270                return ERROR_CODE;
    231271        }
    232272        return EOK;
     
    343383}
    344384
    345 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
     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){
     394                return NULL;
     395        }
     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);
     429        length += device->addr->length;
     430        memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length);
     431        length += proto->addr->length;
     432        bzero(((uint8_t *) header) + length, device->addr->length);
     433        length += device->addr->length;
     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));
     437                return NULL;
     438        }
     439        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
     440        return NULL;
     441}
     442
     443int arp_receive_message(device_id_t device_id, packet_t packet){
    346444        ERROR_DECLARE;
    347445
    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){
    360         ERROR_DECLARE;
    361 
    362         fibril_rwlock_initialize(&arp_globals.lock);
     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)){
     458                return EINVAL;
     459        }
     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);
     474        src_proto = src_hw + header->hardware_length;
     475        des_hw = src_proto + header->protocol_length;
     476        des_proto = des_hw + header->hardware_length;
     477        hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length));
     478        // exists?
     479        if(hw_source){
     480                if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){
     481                        return EINVAL;
     482                }
     483                memcpy(hw_source->value, src_hw, hw_source->length);
     484        }
     485        // is my protocol address?
     486        if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){
     487                return EINVAL;
     488        }
     489        if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){
     490                // not already upadted?
     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);
     506                        return 1;
     507                }
     508        }
     509        return EOK;
     510}
     511
     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
    363541        fibril_rwlock_write_lock(&arp_globals.lock);
    364         arp_globals.client_connection = client_connection;
    365         ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
     542        device = arp_cache_find(&arp_globals.cache, device_id);
     543        if(! device){
     544                fibril_rwlock_write_unlock(&arp_globals.lock);
     545                return ENOENT;
     546        }
     547        device->packet_dimension.content = mtu;
     548        printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
    366549        fibril_rwlock_write_unlock(&arp_globals.lock);
    367550        return EOK;
     
    435618}
    436619
    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 
    620620/** @}
    621621 */
Note: See TracChangeset for help on using the changeset viewer.