Changeset 0b749a3 in mainline for uspace/srv/net/il/arp/arp.c


Ignore:
Timestamp:
2010-11-22T15:39:53Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0eddb76, aae339e9
Parents:
9a1d8ab (diff), 8cd1aa5e (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 development/ changes

File:
1 edited

Legend:

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

    r9a1d8ab r0b749a3  
    2828
    2929/** @addtogroup arp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  ARP module implementation.
    35  *  @see arp.h
    36  */
     34 * ARP module implementation.
     35 * @see arp.h
     36 */
     37
     38#include "arp.h"
     39#include "arp_header.h"
     40#include "arp_oc.h"
     41#include "arp_module.h"
    3742
    3843#include <async.h>
     
    4348#include <str.h>
    4449#include <task.h>
     50#include <adt/measured_strings.h>
    4551#include <ipc/ipc.h>
    4652#include <ipc/services.h>
    47 
    48 #include <net_err.h>
    49 #include <net_messages.h>
    50 #include <net_modules.h>
    51 #include <net_byteorder.h>
    52 #include <net_device.h>
    53 #include <arp_interface.h>
     53#include <ipc/net.h>
     54#include <ipc/arp.h>
     55#include <ipc/il.h>
     56#include <byteorder.h>
     57#include <errno.h>
     58
     59#include <net/modules.h>
     60#include <net/device.h>
     61#include <net/packet.h>
     62
    5463#include <nil_interface.h>
    5564#include <protocol_map.h>
    56 #include <adt/measured_strings.h>
    57 #include <packet/packet.h>
    58 #include <packet/packet_client.h>
     65#include <packet_client.h>
    5966#include <packet_remote.h>
    60 #include <il_messages.h>
    6167#include <il_interface.h>
    6268#include <il_local.h>
    63 #include <arp_messages.h>
    64 
    65 #include "arp.h"
    66 #include "arp_header.h"
    67 #include "arp_oc.h"
    68 #include "arp_module.h"
    69 
    70 
    71 /** ARP module name.
    72  */
     69
     70
     71/** ARP module name. */
    7372#define NAME  "arp"
    7473
    75 /** ARP global data.
    76  */
    77 arp_globals_t   arp_globals;
     74/** ARP global data. */
     75arp_globals_t arp_globals;
     76
     77DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t);
     78INT_MAP_IMPLEMENT(arp_protos, arp_proto_t);
     79GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t);
    7880
    7981/** Clears the device specific data.
    80  *  @param[in] device The device specific data.
    81  */
    82 void arp_clear_device(arp_device_ref device);
    83 
    84 /** Creates new protocol specific data.
    85  *  Allocates and returns the needed memory block as the proto parameter.
    86  *  @param[out] proto The allocated protocol specific data.
    87  *  @param[in] service The protocol module service.
    88  *  @param[in] address The actual protocol device address.
    89  *  @returns EOK on success.
    90  *  @returns ENOMEM if there is not enough memory left.
    91  */
    92 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address);
    93 
    94 /** @name Message processing functions
    95  */
    96 /*@{*/
    97 
    98 /** Registers the device.
    99  *  Creates new device entry in the cache or updates the protocol address if the device with the device identifier and the driver service exists.
    100  *  @param[in] device_id The device identifier.
    101  *  @param[in] service The device driver service.
    102  *  @param[in] protocol The protocol service.
    103  *  @param[in] address The actual device protocol address.
    104  *  @returns EOK on success.
    105  *  @returns EEXIST if another device with the same device identifier and different driver service exists.
    106  *  @returns ENOMEM if there is not enough memory left.
    107  *  @returns Other error codes as defined for the measured_strings_return() function.
    108  */
    109 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address);
    110 
    111 /** Updates the device content length according to the new MTU value.
    112  *  @param[in] device_id The device identifier.
    113  *  @param[in] mtu The new mtu value.
    114  *  @returns ENOENT if device is not found.
    115  *  @returns EOK on success.
    116  */
    117 int arp_mtu_changed_message(device_id_t device_id, size_t mtu);
    118 
    119 /** Processes the received ARP packet.
    120  *  Updates the source hardware address if the source entry exists or the packet is targeted to my protocol address.
    121  *  Responses to the ARP request if the packet is the ARP request and is targeted to my address.
    122  *  @param[in] device_id The source device identifier.
    123  *  @param[in,out] packet The received packet.
    124  *  @returns EOK on success and the packet is no longer needed.
    125  *  @returns 1 on success and the packet has been reused.
    126  *  @returns EINVAL if the packet is too small to carry an ARP packet.
    127  *  @returns EINVAL if the received address lengths differs from the registered values.
    128  *  @returns ENOENT if the device is not found in the cache.
    129  *  @returns ENOENT if the protocol for the device is not found in the cache.
    130  *  @returns ENOMEM if there is not enough memory left.
    131  */
    132 int arp_receive_message(device_id_t device_id, packet_t packet);
    133 
    134 /** Returns the hardware address for the given protocol address.
    135  *  Sends the ARP request packet if the hardware address is not found in the cache.
    136  *  @param[in] device_id The device identifier.
    137  *  @param[in] protocol The protocol service.
    138  *  @param[in] target The target protocol address.
    139  *  @returns The hardware address of the target.
    140  *  @returns NULL if the target parameter is NULL.
    141  *  @returns NULL if the device is not found.
    142  *  @returns NULL if the device packet is too small to send a&nbsp;request.
    143  *  @returns NULL if the hardware address is not found in the cache.
    144  */
    145 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target);
    146 
    147 /*@}*/
    148 
    149 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t)
    150 
    151 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t)
    152 
    153 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t)
    154 
    155 int arp_clean_cache_req(int arp_phone){
     82 *
     83 * @param[in] device    The device specific data.
     84 */
     85static void arp_clear_device(arp_device_t *device)
     86{
    15687        int count;
    157         arp_device_ref device;
     88        arp_proto_t *proto;
     89
     90        for (count = arp_protos_count(&device->protos) - 1; count >= 0;
     91            count--) {
     92                proto = arp_protos_get_index(&device->protos, count);
     93                if (proto) {
     94                        if (proto->addr)
     95                                free(proto->addr);
     96                        if (proto->addr_data)
     97                                free(proto->addr_data);
     98                        arp_addr_destroy(&proto->addresses);
     99                }
     100        }
     101        arp_protos_clear(&device->protos);
     102}
     103
     104static int arp_clean_cache_req(int arp_phone)
     105{
     106        int count;
     107        arp_device_t *device;
    158108
    159109        fibril_rwlock_write_lock(&arp_globals.lock);
    160         for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){
     110        for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0;
     111            count--) {
    161112                device = arp_cache_get_index(&arp_globals.cache, count);
    162                 if(device){
     113                if (device) {
    163114                        arp_clear_device(device);
    164                         if(device->addr_data){
     115                        if (device->addr_data)
    165116                                free(device->addr_data);
    166                         }
    167                         if(device->broadcast_data){
     117                        if (device->broadcast_data)
    168118                                free(device->broadcast_data);
    169                         }
    170119                }
    171120        }
     
    176125}
    177126
    178 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){
    179         arp_device_ref device;
    180         arp_proto_ref proto;
     127static int arp_clear_address_req(int arp_phone, device_id_t device_id,
     128    services_t protocol, measured_string_t *address)
     129{
     130        arp_device_t *device;
     131        arp_proto_t *proto;
    181132
    182133        fibril_rwlock_write_lock(&arp_globals.lock);
    183134        device = arp_cache_find(&arp_globals.cache, device_id);
    184         if(! device){
     135        if (!device) {
    185136                fibril_rwlock_write_unlock(&arp_globals.lock);
    186137                return ENOENT;
    187138        }
    188139        proto = arp_protos_find(&device->protos, protocol);
    189         if(! proto){
     140        if (!proto) {
    190141                fibril_rwlock_write_unlock(&arp_globals.lock);
    191142                return ENOENT;
     
    196147}
    197148
    198 void arp_clear_device(arp_device_ref device){
    199         int count;
    200         arp_proto_ref proto;
    201 
    202         for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){
    203                 proto = arp_protos_get_index(&device->protos, count);
    204                 if(proto){
    205                         if(proto->addr){
    206                                 free(proto->addr);
    207                         }
    208                         if(proto->addr_data){
    209                                 free(proto->addr_data);
    210                         }
    211                         arp_addr_destroy(&proto->addresses);
    212                 }
    213         }
    214         arp_protos_clear(&device->protos);
    215 }
    216 
    217 int arp_clear_device_req(int arp_phone, device_id_t device_id){
    218         arp_device_ref device;
     149
     150static int arp_clear_device_req(int arp_phone, device_id_t device_id)
     151{
     152        arp_device_t *device;
    219153
    220154        fibril_rwlock_write_lock(&arp_globals.lock);
    221155        device = arp_cache_find(&arp_globals.cache, device_id);
    222         if(! device){
     156        if (!device) {
    223157                fibril_rwlock_write_unlock(&arp_globals.lock);
    224158                return ENOENT;
     
    230164}
    231165
    232 int arp_connect_module(services_t service){
    233         if(service != SERVICE_ARP){
    234                 return EINVAL;
    235         }
     166/** Creates new protocol specific data.
     167 *
     168 * Allocates and returns the needed memory block as the proto parameter.
     169 *
     170 * @param[out] proto    The allocated protocol specific data.
     171 * @param[in] service   The protocol module service.
     172 * @param[in] address   The actual protocol device address.
     173 * @return              EOK on success.
     174 * @return              ENOMEM if there is not enough memory left.
     175 */
     176static int arp_proto_create(arp_proto_t **proto, services_t service,
     177    measured_string_t *address)
     178{
     179        int rc;
     180
     181        *proto = (arp_proto_t *) malloc(sizeof(arp_proto_t));
     182        if (!*proto)
     183                return ENOMEM;
     184       
     185        (*proto)->service = service;
     186        (*proto)->addr = address;
     187        (*proto)->addr_data = address->value;
     188       
     189        rc = arp_addr_initialize(&(*proto)->addresses);
     190        if (rc != EOK) {
     191                free(*proto);
     192                return rc;
     193        }
     194       
    236195        return EOK;
    237196}
    238197
    239 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){
    240         ERROR_DECLARE;
    241 
    242         arp_device_ref device;
    243         arp_proto_ref proto;
     198/** Registers the device.
     199 *
     200 * Creates new device entry in the cache or updates the protocol address if the
     201 * device with the device identifier and the driver service exists.
     202 *
     203 * @param[in] device_id The device identifier.
     204 * @param[in] service   The device driver service.
     205 * @param[in] protocol  The protocol service.
     206 * @param[in] address   The actual device protocol address.
     207 * @return              EOK on success.
     208 * @return              EEXIST if another device with the same device identifier
     209 *                      and different driver service exists.
     210 * @return              ENOMEM if there is not enough memory left.
     211 * @return              Other error codes as defined for the
     212 *                      measured_strings_return() function.
     213 */
     214static int arp_device_message(device_id_t device_id, services_t service,
     215    services_t protocol, measured_string_t *address)
     216{
     217        arp_device_t *device;
     218        arp_proto_t *proto;
     219        hw_type_t hardware;
    244220        int index;
    245         hw_type_t hardware;
     221        int rc;
    246222
    247223        fibril_rwlock_write_lock(&arp_globals.lock);
    248         // an existing device?
     224
     225        /* An existing device? */
    249226        device = arp_cache_find(&arp_globals.cache, device_id);
    250         if(device){
    251                 if(device->service != service){
     227
     228        if (device) {
     229                if (device->service != service) {
    252230                        printf("Device %d already exists\n", device->device_id);
    253231                        fibril_rwlock_write_unlock(&arp_globals.lock);
     
    255233                }
    256234                proto = arp_protos_find(&device->protos, protocol);
    257                 if(proto){
     235                if (proto) {
    258236                        free(proto->addr);
    259237                        free(proto->addr_data);
    260238                        proto->addr = address;
    261239                        proto->addr_data = address->value;
    262                 }else{
    263                         if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
     240                } else {
     241                        rc = arp_proto_create(&proto, protocol, address);
     242                        if (rc != EOK) {
    264243                                fibril_rwlock_write_unlock(&arp_globals.lock);
    265                                 return ERROR_CODE;
     244                                return rc;
    266245                        }
    267                         index = arp_protos_add(&device->protos, proto->service, proto);
    268                         if(index < 0){
     246                        index = arp_protos_add(&device->protos, proto->service,
     247                            proto);
     248                        if (index < 0) {
    269249                                fibril_rwlock_write_unlock(&arp_globals.lock);
    270250                                free(proto);
    271251                                return index;
    272252                        }
    273                         printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol);
    274                 }
    275         }else{
     253                        printf("New protocol added:\n\tdevice id\t= "
     254                            "%d\n\tproto\t= %d", device_id, protocol);
     255                }
     256        } else {
    276257                hardware = hardware_map(service);
    277                 if(! hardware){
     258                if (!hardware)
    278259                        return ENOENT;
    279                 }
    280                 // create a new device
    281                 device = (arp_device_ref) malloc(sizeof(arp_device_t));
    282                 if(! device){
     260               
     261                /* Create a new device */
     262                device = (arp_device_t *) malloc(sizeof(arp_device_t));
     263                if (!device) {
    283264                        fibril_rwlock_write_unlock(&arp_globals.lock);
    284265                        return ENOMEM;
     
    286267                device->hardware = hardware;
    287268                device->device_id = device_id;
    288                 if(ERROR_OCCURRED(arp_protos_initialize(&device->protos))
    289                         || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
     269                rc = arp_protos_initialize(&device->protos);
     270                if (rc != EOK) {
    290271                        fibril_rwlock_write_unlock(&arp_globals.lock);
    291272                        free(device);
    292                         return ERROR_CODE;
     273                        return rc;
     274                }
     275                rc = arp_proto_create(&proto, protocol, address);
     276                if (rc != EOK) {
     277                        fibril_rwlock_write_unlock(&arp_globals.lock);
     278                        free(device);
     279                        return rc;
    293280                }
    294281                index = arp_protos_add(&device->protos, proto->service, proto);
    295                 if(index < 0){
     282                if (index < 0) {
    296283                        fibril_rwlock_write_unlock(&arp_globals.lock);
    297284                        arp_protos_destroy(&device->protos);
     
    300287                }
    301288                device->service = service;
    302                 // bind the new one
    303                 device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection);
    304                 if(device->phone < 0){
     289               
     290                /* Bind the new one */
     291                device->phone = nil_bind_service(device->service,
     292                    (ipcarg_t) device->device_id, SERVICE_ARP,
     293                    arp_globals.client_connection);
     294                if (device->phone < 0) {
    305295                        fibril_rwlock_write_unlock(&arp_globals.lock);
    306296                        arp_protos_destroy(&device->protos);
     
    308298                        return EREFUSED;
    309299                }
    310                 // get packet dimensions
    311                 if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){
     300               
     301                /* Get packet dimensions */
     302                rc = nil_packet_size_req(device->phone, device_id,
     303                    &device->packet_dimension);
     304                if (rc != EOK) {
    312305                        fibril_rwlock_write_unlock(&arp_globals.lock);
    313306                        arp_protos_destroy(&device->protos);
    314307                        free(device);
    315                         return ERROR_CODE;
    316                 }
    317                 // get hardware address
    318                 if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){
     308                        return rc;
     309                }
     310               
     311                /* Get hardware address */
     312                rc = nil_get_addr_req(device->phone, device_id, &device->addr,
     313                    &device->addr_data);
     314                if (rc != EOK) {
    319315                        fibril_rwlock_write_unlock(&arp_globals.lock);
    320316                        arp_protos_destroy(&device->protos);
    321317                        free(device);
    322                         return ERROR_CODE;
    323                 }
    324                 // get broadcast address
    325                 if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){
     318                        return rc;
     319                }
     320               
     321                /* Get broadcast address */
     322                rc = nil_get_broadcast_addr_req(device->phone, device_id,
     323                    &device->broadcast_addr, &device->broadcast_data);
     324                if (rc != EOK) {
    326325                        fibril_rwlock_write_unlock(&arp_globals.lock);
    327326                        free(device->addr);
     
    329328                        arp_protos_destroy(&device->protos);
    330329                        free(device);
    331                         return ERROR_CODE;
    332                 }
    333                 if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){
     330                        return rc;
     331                }
     332               
     333                rc = arp_cache_add(&arp_globals.cache, device->device_id,
     334                    device);
     335                if (rc != EOK) {
    334336                        fibril_rwlock_write_unlock(&arp_globals.lock);
    335337                        free(device->addr);
     
    339341                        arp_protos_destroy(&device->protos);
    340342                        free(device);
    341                         return ERROR_CODE;
    342                 }
    343                 printf("%s: Device registered (id: %d, type: 0x%x, service: %d, proto: %d)\n",
    344                     NAME, device->device_id, device->hardware, device->service, protocol);
     343                        return rc;
     344                }
     345                printf("%s: Device registered (id: %d, type: 0x%x, service: %d,"
     346                    " proto: %d)\n", NAME, device->device_id, device->hardware,
     347                    device->service, protocol);
    345348        }
    346349        fibril_rwlock_write_unlock(&arp_globals.lock);
     350       
    347351        return EOK;
    348352}
    349353
    350 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
    351         ERROR_DECLARE;
    352 
    353         measured_string_ref tmp;
    354 
    355         // copy the given address for exclusive use
    356         tmp = measured_string_copy(address);
    357         if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){
    358                 free(tmp->value);
    359                 free(tmp);
    360         }
    361         return ERROR_CODE;
    362 }
    363 
    364 int arp_initialize(async_client_conn_t client_connection){
    365         ERROR_DECLARE;
     354/** Initializes the ARP module.
     355 *
     356 *  @param[in] client_connection The client connection processing function.
     357 *                      The module skeleton propagates its own one.
     358 *  @return             EOK on success.
     359 *  @return             ENOMEM if there is not enough memory left.
     360 */
     361int arp_initialize(async_client_conn_t client_connection)
     362{
     363        int rc;
    366364
    367365        fibril_rwlock_initialize(&arp_globals.lock);
    368366        fibril_rwlock_write_lock(&arp_globals.lock);
    369367        arp_globals.client_connection = client_connection;
    370         ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
     368        rc = arp_cache_initialize(&arp_globals.cache);
    371369        fibril_rwlock_write_unlock(&arp_globals.lock);
    372         return EOK;
    373 }
    374 
    375 int arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    376     ipc_call_t *answer, int *answer_count)
    377 {
    378         ERROR_DECLARE;
    379        
    380         measured_string_ref address;
    381         measured_string_ref translation;
    382         char * data;
    383         packet_t packet;
    384         packet_t next;
    385        
    386         *answer_count = 0;
    387         switch (IPC_GET_METHOD(*call)) {
    388                 case IPC_M_PHONE_HUNGUP:
    389                         return EOK;
    390                 case NET_ARP_DEVICE:
    391                         ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    392                         if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){
    393                                 free(address);
    394                                 free(data);
    395                         }
    396                         return ERROR_CODE;
    397                 case NET_ARP_TRANSLATE:
    398                         ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    399                         fibril_rwlock_read_lock(&arp_globals.lock);
    400                         translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
    401                         free(address);
    402                         free(data);
    403                         if(! translation){
    404                                 fibril_rwlock_read_unlock(&arp_globals.lock);
    405                                 return ENOENT;
    406                         }
    407                         ERROR_CODE = measured_strings_reply(translation, 1);
    408                         fibril_rwlock_read_unlock(&arp_globals.lock);
    409                         return ERROR_CODE;
    410                 case NET_ARP_CLEAR_DEVICE:
    411                         return arp_clear_device_req(0, IPC_GET_DEVICE(call));
    412                 case NET_ARP_CLEAR_ADDRESS:
    413                         ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    414                         arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
    415                         free(address);
    416                         free(data);
    417                         return EOK;
    418                 case NET_ARP_CLEAN_CACHE:
    419                         return arp_clean_cache_req(0);
    420                 case NET_IL_DEVICE_STATE:
    421                         // do nothing - keep the cache
    422                         return EOK;
    423                 case NET_IL_RECEIVED:
    424                         if(! ERROR_OCCURRED(packet_translate_remote(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    425                                 fibril_rwlock_read_lock(&arp_globals.lock);
    426                                 do{
    427                                         next = pq_detach(packet);
    428                                         ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet);
    429                                         if(ERROR_CODE != 1){
    430                                                 pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    431                                         }
    432                                         packet = next;
    433                                 }while(packet);
    434                                 fibril_rwlock_read_unlock(&arp_globals.lock);
    435                         }
    436                         return ERROR_CODE;
    437                 case NET_IL_MTU_CHANGED:
    438                         return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call));
    439         }
    440        
    441         return ENOTSUP;
    442 }
    443 
    444 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){
    445         arp_device_ref device;
     370       
     371        return rc;
     372}
     373
     374/** Updates the device content length according to the new MTU value.
     375 *
     376 * @param[in] device_id The device identifier.
     377 * @param[in] mtu       The new mtu value.
     378 * @return              ENOENT if device is not found.
     379 * @return              EOK on success.
     380 */
     381static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
     382{
     383        arp_device_t *device;
    446384
    447385        fibril_rwlock_write_lock(&arp_globals.lock);
    448386        device = arp_cache_find(&arp_globals.cache, device_id);
    449         if(! device){
     387        if (!device) {
    450388                fibril_rwlock_write_unlock(&arp_globals.lock);
    451389                return ENOENT;
    452390        }
    453391        device->packet_dimension.content = mtu;
     392        fibril_rwlock_write_unlock(&arp_globals.lock);
    454393        printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
    455         fibril_rwlock_write_unlock(&arp_globals.lock);
    456394        return EOK;
    457395}
    458396
    459 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){
    460         ERROR_DECLARE;
    461 
    462         *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
    463         if(!(*proto)){
    464                 return ENOMEM;
    465         }
    466         (** proto).service = service;
    467         (** proto).addr = address;
    468         (** proto).addr_data = address->value;
    469         if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){
    470                 free(*proto);
    471                 return ERROR_CODE;
    472         }
    473         return EOK;
    474 }
    475 
    476 int arp_receive_message(device_id_t device_id, packet_t packet){
    477         ERROR_DECLARE;
    478 
     397/** Processes the received ARP packet.
     398 *
     399 * Updates the source hardware address if the source entry exists or the packet
     400 * is targeted to my protocol address.
     401 * Responses to the ARP request if the packet is the ARP request and is
     402 * targeted to my address.
     403 *
     404 * @param[in] device_id The source device identifier.
     405 * @param[in,out] packet The received packet.
     406 * @return              EOK on success and the packet is no longer needed.
     407 * @return              One on success and the packet has been reused.
     408 * @return              EINVAL if the packet is too small to carry an ARP
     409 *                      packet.
     410 * @return              EINVAL if the received address lengths differs from
     411 *                      the registered values.
     412 * @return              ENOENT if the device is not found in the cache.
     413 * @return              ENOENT if the protocol for the device is not found in
     414 *                      the cache.
     415 * @return              ENOMEM if there is not enough memory left.
     416 */
     417static int arp_receive_message(device_id_t device_id, packet_t *packet)
     418{
    479419        size_t length;
    480         arp_header_ref header;
    481         arp_device_ref device;
    482         arp_proto_ref proto;
    483         measured_string_ref hw_source;
    484         uint8_t * src_hw;
    485         uint8_t * src_proto;
    486         uint8_t * des_hw;
    487         uint8_t * des_proto;
     420        arp_header_t *header;
     421        arp_device_t *device;
     422        arp_proto_t *proto;
     423        measured_string_t *hw_source;
     424        uint8_t *src_hw;
     425        uint8_t *src_proto;
     426        uint8_t *des_hw;
     427        uint8_t *des_proto;
     428        int rc;
    488429
    489430        length = packet_get_data_length(packet);
    490         if(length <= sizeof(arp_header_t)){
     431        if (length <= sizeof(arp_header_t))
    491432                return EINVAL;
    492         }
     433
    493434        device = arp_cache_find(&arp_globals.cache, device_id);
    494         if(! device){
     435        if (!device)
    495436                return ENOENT;
    496         }
    497         header = (arp_header_ref) packet_get_data(packet);
    498         if((ntohs(header->hardware) != device->hardware)
    499                 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){
     437
     438        header = (arp_header_t *) packet_get_data(packet);
     439        if ((ntohs(header->hardware) != device->hardware) ||
     440            (length < sizeof(arp_header_t) + header->hardware_length * 2U +
     441            header->protocol_length * 2U)) {
    500442                return EINVAL;
    501443        }
    502         proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol)));
    503         if(! proto){
     444
     445        proto = arp_protos_find(&device->protos,
     446            protocol_unmap(device->service, ntohs(header->protocol)));
     447        if (!proto)
    504448                return ENOENT;
    505         }
     449
    506450        src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
    507451        src_proto = src_hw + header->hardware_length;
    508452        des_hw = src_proto + header->protocol_length;
    509453        des_proto = des_hw + header->hardware_length;
    510         hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length));
    511         // exists?
    512         if(hw_source){
    513                 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){
     454        hw_source = arp_addr_find(&proto->addresses, (char *) src_proto,
     455            CONVERT_SIZE(uint8_t, char, header->protocol_length));
     456        /* Exists? */
     457        if (hw_source) {
     458                if (hw_source->length != CONVERT_SIZE(uint8_t, char,
     459                    header->hardware_length)) {
    514460                        return EINVAL;
    515461                }
    516462                memcpy(hw_source->value, src_hw, hw_source->length);
    517463        }
    518         // is my protocol address?
    519         if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){
     464        /* Is my protocol address? */
     465        if (proto->addr->length != CONVERT_SIZE(uint8_t, char,
     466            header->protocol_length)) {
    520467                return EINVAL;
    521468        }
    522         if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){
    523                 // not already upadted?
    524                 if(! hw_source){
    525                         hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length));
    526                         if(! hw_source){
     469        if (!str_lcmp(proto->addr->value, (char *) des_proto,
     470            proto->addr->length)) {
     471                /* Not already updated? */
     472                if (!hw_source) {
     473                        hw_source = measured_string_create_bulk((char *) src_hw,
     474                            CONVERT_SIZE(uint8_t, char,
     475                            header->hardware_length));
     476                        if (!hw_source)
    527477                                return ENOMEM;
    528                         }
    529                         ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source));
    530                 }
    531                 if(ntohs(header->operation) == ARPOP_REQUEST){
     478
     479                        rc = arp_addr_add(&proto->addresses, (char *) src_proto,
     480                            CONVERT_SIZE(uint8_t, char,
     481                            header->protocol_length), hw_source);
     482                        if (rc != EOK)
     483                                return rc;
     484                }
     485                if (ntohs(header->operation) == ARPOP_REQUEST) {
    532486                        header->operation = htons(ARPOP_REPLY);
    533487                        memcpy(des_proto, src_proto, header->protocol_length);
    534                         memcpy(src_proto, proto->addr->value, header->protocol_length);
    535                         memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len);
    536                         memcpy(des_hw, hw_source->value, header->hardware_length);
    537                         ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length));
    538                         nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
     488                        memcpy(src_proto, proto->addr->value,
     489                            header->protocol_length);
     490                        memcpy(src_hw, device->addr->value,
     491                            device->packet_dimension.addr_len);
     492                        memcpy(des_hw, hw_source->value,
     493                            header->hardware_length);
     494                       
     495                        rc = packet_set_addr(packet, src_hw, des_hw,
     496                            header->hardware_length);
     497                        if (rc != EOK)
     498                                return rc;
     499                       
     500                        nil_send_msg(device->phone, device_id, packet,
     501                            SERVICE_ARP);
    539502                        return 1;
    540503                }
    541504        }
     505
    542506        return EOK;
    543507}
    544508
    545 task_id_t arp_task_get_id(void){
    546         return task_get_id();
    547 }
    548 
    549 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){
    550         arp_device_ref device;
    551         arp_proto_ref proto;
    552         measured_string_ref addr;
     509
     510/** Returns the hardware address for the given protocol address.
     511 *
     512 * Sends the ARP request packet if the hardware address is not found in the
     513 * cache.
     514 *
     515 * @param[in] device_id The device identifier.
     516 * @param[in] protocol  The protocol service.
     517 * @param[in] target    The target protocol address.
     518 * @return              The hardware address of the target.
     519 * @return              NULL if the target parameter is NULL.
     520 * @return              NULL if the device is not found.
     521 * @return              NULL if the device packet is too small to send a
     522 *                      request.
     523 * @return              NULL if the hardware address is not found in the cache.
     524 */
     525static measured_string_t *
     526arp_translate_message(device_id_t device_id, services_t protocol,
     527    measured_string_t *target)
     528{
     529        arp_device_t *device;
     530        arp_proto_t *proto;
     531        measured_string_t *addr;
    553532        size_t length;
    554         packet_t packet;
    555         arp_header_ref header;
    556 
    557         if(! target){
     533        packet_t *packet;
     534        arp_header_t *header;
     535
     536        if (!target)
    558537                return NULL;
    559         }
     538
    560539        device = arp_cache_find(&arp_globals.cache, device_id);
    561         if(! device){
     540        if (!device)
    562541                return NULL;
    563         }
     542
    564543        proto = arp_protos_find(&device->protos, protocol);
    565         if((! proto) || (proto->addr->length != target->length)){
     544        if (!proto || (proto->addr->length != target->length))
    566545                return NULL;
    567         }
     546
    568547        addr = arp_addr_find(&proto->addresses, target->value, target->length);
    569         if(addr){
     548        if (addr)
    570549                return addr;
    571         }
    572         // ARP packet content size = header + (address + translation) * 2
    573         length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2;
    574         if(length > device->packet_dimension.content){
     550
     551        /* ARP packet content size = header + (address + translation) * 2 */
     552        length = 8 + 2 * (CONVERT_SIZE(char, uint8_t, proto->addr->length) +
     553            CONVERT_SIZE(char, uint8_t, device->addr->length));
     554        if (length > device->packet_dimension.content)
    575555                return NULL;
    576         }
    577         packet = packet_get_4_remote(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
    578         if(! packet){
     556
     557        packet = packet_get_4_remote(arp_globals.net_phone,
     558            device->packet_dimension.addr_len, device->packet_dimension.prefix,
     559            length, device->packet_dimension.suffix);
     560        if (!packet)
    579561                return NULL;
    580         }
    581         header = (arp_header_ref) packet_suffix(packet, length);
    582         if(! header){
     562
     563        header = (arp_header_t *) packet_suffix(packet, length);
     564        if (!header) {
    583565                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    584566                return NULL;
    585567        }
     568
    586569        header->hardware = htons(device->hardware);
    587570        header->hardware_length = (uint8_t) device->addr->length;
     
    590573        header->operation = htons(ARPOP_REQUEST);
    591574        length = sizeof(arp_header_t);
    592         memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length);
     575        memcpy(((uint8_t *) header) + length, device->addr->value,
     576            device->addr->length);
    593577        length += device->addr->length;
    594         memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length);
     578        memcpy(((uint8_t *) header) + length, proto->addr->value,
     579            proto->addr->length);
    595580        length += proto->addr->length;
    596581        bzero(((uint8_t *) header) + length, device->addr->length);
    597582        length += device->addr->length;
    598583        memcpy(((uint8_t *) header) + length, target->value, target->length);
    599         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){
     584
     585        if (packet_set_addr(packet, (uint8_t *) device->addr->value,
     586            (uint8_t *) device->broadcast_addr->value,
     587            CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK) {
    600588                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    601589                return NULL;
    602590        }
     591
    603592        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    604593        return NULL;
    605594}
    606595
    607 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){
    608         measured_string_ref tmp;
    609 
    610         fibril_rwlock_read_lock(&arp_globals.lock);
    611         tmp = arp_translate_message(device_id, protocol, address);
    612         if(tmp){
    613                 *translation = measured_string_copy(tmp);
     596
     597/** Processes the ARP message.
     598 *
     599 * @param[in] callid    The message identifier.
     600 * @param[in] call      The message parameters.
     601 * @param[out] answer   The message answer parameters.
     602 * @param[out] answer_count The last parameter for the actual answer in the
     603 *                      answer parameter.
     604 * @return              EOK on success.
     605 * @return              ENOTSUP if the message is not known.
     606 *
     607 * @see arp_interface.h
     608 * @see IS_NET_ARP_MESSAGE()
     609 */
     610int
     611arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     612    ipc_call_t *answer, int *answer_count)
     613{
     614        measured_string_t *address;
     615        measured_string_t *translation;
     616        char *data;
     617        packet_t *packet;
     618        packet_t *next;
     619        int rc;
     620       
     621        *answer_count = 0;
     622        switch (IPC_GET_METHOD(*call)) {
     623        case IPC_M_PHONE_HUNGUP:
     624                return EOK;
     625       
     626        case NET_ARP_DEVICE:
     627                rc = measured_strings_receive(&address, &data, 1);
     628                if (rc != EOK)
     629                        return rc;
     630               
     631                rc = arp_device_message(IPC_GET_DEVICE(call),
     632                    IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address);
     633                if (rc != EOK) {
     634                        free(address);
     635                        free(data);
     636                }
     637                return rc;
     638       
     639        case NET_ARP_TRANSLATE:
     640                rc = measured_strings_receive(&address, &data, 1);
     641                if (rc != EOK)
     642                        return rc;
     643               
     644                fibril_rwlock_read_lock(&arp_globals.lock);
     645                translation = arp_translate_message(IPC_GET_DEVICE(call),
     646                    IPC_GET_SERVICE(call), address);
     647                free(address);
     648                free(data);
     649                if (!translation) {
     650                        fibril_rwlock_read_unlock(&arp_globals.lock);
     651                        return ENOENT;
     652                }
     653                rc = measured_strings_reply(translation, 1);
    614654                fibril_rwlock_read_unlock(&arp_globals.lock);
    615                 if(*translation){
    616                         *data = (** translation).value;
    617                         return EOK;
    618                 }else{
    619                         return ENOMEM;
    620                 }
    621         }else{
     655                return rc;
     656
     657        case NET_ARP_CLEAR_DEVICE:
     658                return arp_clear_device_req(0, IPC_GET_DEVICE(call));
     659
     660        case NET_ARP_CLEAR_ADDRESS:
     661                rc = measured_strings_receive(&address, &data, 1);
     662                if (rc != EOK)
     663                        return rc;
     664               
     665                arp_clear_address_req(0, IPC_GET_DEVICE(call),
     666                    IPC_GET_SERVICE(call), address);
     667                free(address);
     668                free(data);
     669                return EOK;
     670       
     671        case NET_ARP_CLEAN_CACHE:
     672                return arp_clean_cache_req(0);
     673       
     674        case NET_IL_DEVICE_STATE:
     675                /* Do nothing - keep the cache */
     676                return EOK;
     677       
     678        case NET_IL_RECEIVED:
     679                rc = packet_translate_remote(arp_globals.net_phone, &packet,
     680                    IPC_GET_PACKET(call));
     681                if (rc != EOK)
     682                        return rc;
     683               
     684                fibril_rwlock_read_lock(&arp_globals.lock);
     685                do {
     686                        next = pq_detach(packet);
     687                        rc = arp_receive_message(IPC_GET_DEVICE(call), packet);
     688                        if (rc != 1) {
     689                                pq_release_remote(arp_globals.net_phone,
     690                                    packet_get_id(packet));
     691                        }
     692                        packet = next;
     693                } while (packet);
    622694                fibril_rwlock_read_unlock(&arp_globals.lock);
    623                 return ENOENT;
    624         }
     695               
     696                return EOK;
     697       
     698        case NET_IL_MTU_CHANGED:
     699                return arp_mtu_changed_message(IPC_GET_DEVICE(call),
     700                    IPC_GET_MTU(call));
     701        }
     702       
     703        return ENOTSUP;
    625704}
    626705
    627706/** Default thread for new connections.
    628707 *
    629  *  @param[in] iid The initial message identifier.
    630  *  @param[in] icall The initial message call structure.
    631  *
    632  */
    633 static void il_client_connection(ipc_callid_t iid, ipc_call_t * icall)
     708 * @param[in] iid       The initial message identifier.
     709 * @param[in] icall     The initial message call structure.
     710 */
     711static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    634712{
    635713        /*
     
    639717        ipc_answer_0(iid, EOK);
    640718       
    641         while(true) {
     719        while (true) {
    642720                ipc_call_t answer;
    643721                int answer_count;
     
    654732                    &answer_count);
    655733               
    656                 /* End if said to either by the message or the processing result */
    657                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
     734                /*
     735                 * End if told to either by the message or the processing
     736                 * result.
     737                 */
     738                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     739                    (res == EHANGUP))
    658740                        return;
    659741               
     
    665747/** Starts the module.
    666748 *
    667  *  @param argc The count of the command line arguments. Ignored parameter.
    668  *  @param argv The command line parameters. Ignored parameter.
    669  *
    670  *  @returns EOK on success.
    671  *  @returns Other error codes as defined for each specific module start function.
    672  *
     749 * @return              EOK on success.
     750 * @return              Other error codes as defined for each specific module
     751 *                      start function.
    673752 */
    674753int main(int argc, char *argv[])
    675754{
    676         ERROR_DECLARE;
     755        int rc;
    677756       
    678757        /* Start the module */
    679         if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection)))
    680                 return ERROR_CODE;
    681        
    682         return EOK;
     758        rc = il_module_start_standalone(il_client_connection);
     759        return rc;
    683760}
    684761
    685762/** @}
    686763 */
     764
Note: See TracChangeset for help on using the changeset viewer.