Ignore:
File:
1 edited

Legend:

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

    ra852181 raf7638e  
    2828
    2929/** @addtogroup arp
    30  * @{
     30 *  @{
    3131 */
    3232
    3333/** @file
    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"
     34 *  ARP module implementation.
     35 *  @see arp.h
     36 */
    4237
    4338#include <async.h>
     
    4843#include <str.h>
    4944#include <task.h>
    50 #include <adt/measured_strings.h>
    5145#include <ipc/ipc.h>
    5246#include <ipc/services.h>
     
    5549#include <ipc/il.h>
    5650#include <byteorder.h>
    57 #include <errno.h>
     51#include <err.h>
    5852
    5953#include <net/modules.h>
    6054#include <net/device.h>
    61 #include <net/packet.h>
    62 
     55#include <arp_interface.h>
    6356#include <nil_interface.h>
    6457#include <protocol_map.h>
     58#include <adt/measured_strings.h>
     59#include <net/packet.h>
    6560#include <packet_client.h>
    6661#include <packet_remote.h>
     
    6863#include <il_local.h>
    6964
    70 
    71 /** ARP module name. */
     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 */
    7273#define NAME  "arp"
    7374
    74 /** ARP global data. */
    75 arp_globals_t arp_globals;
    76 
    77 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t);
    78 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t);
    79 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t);
     75/** ARP global data.
     76 */
     77arp_globals_t   arp_globals;
    8078
    8179/** Clears the device specific data.
    82  *
    83  * @param[in] device    The device specific data.
    84  */
    85 static void arp_clear_device(arp_device_ref device)
    86 {
    87         int count;
    88         arp_proto_ref 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 
    104 static int arp_clean_cache_req(int arp_phone)
    105 {
     80 *  @param[in] device The device specific data.
     81 */
     82void 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 */
     92int 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 */
     109int 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 */
     117int 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 */
     132int 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 */
     145measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target);
     146
     147/*@}*/
     148
     149DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t)
     150
     151INT_MAP_IMPLEMENT(arp_protos, arp_proto_t)
     152
     153GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t)
     154
     155int arp_clean_cache_req(int arp_phone){
    106156        int count;
    107157        arp_device_ref device;
    108158
    109159        fibril_rwlock_write_lock(&arp_globals.lock);
    110         for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0;
    111             count--) {
     160        for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){
    112161                device = arp_cache_get_index(&arp_globals.cache, count);
    113                 if (device) {
     162                if(device){
    114163                        arp_clear_device(device);
    115                         if (device->addr_data)
     164                        if(device->addr_data){
    116165                                free(device->addr_data);
    117                         if (device->broadcast_data)
     166                        }
     167                        if(device->broadcast_data){
    118168                                free(device->broadcast_data);
     169                        }
    119170                }
    120171        }
     
    125176}
    126177
    127 static int
    128 arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol,
    129     measured_string_ref address)
    130 {
     178int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){
    131179        arp_device_ref device;
    132180        arp_proto_ref proto;
     
    134182        fibril_rwlock_write_lock(&arp_globals.lock);
    135183        device = arp_cache_find(&arp_globals.cache, device_id);
    136         if (!device) {
     184        if(! device){
    137185                fibril_rwlock_write_unlock(&arp_globals.lock);
    138186                return ENOENT;
    139187        }
    140188        proto = arp_protos_find(&device->protos, protocol);
    141         if (!proto) {
     189        if(! proto){
    142190                fibril_rwlock_write_unlock(&arp_globals.lock);
    143191                return ENOENT;
     
    148196}
    149197
    150 
    151 static int arp_clear_device_req(int arp_phone, device_id_t device_id)
    152 {
     198void 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
     217int arp_clear_device_req(int arp_phone, device_id_t device_id){
    153218        arp_device_ref device;
    154219
    155220        fibril_rwlock_write_lock(&arp_globals.lock);
    156221        device = arp_cache_find(&arp_globals.cache, device_id);
    157         if (!device) {
     222        if(! device){
    158223                fibril_rwlock_write_unlock(&arp_globals.lock);
    159224                return ENOENT;
     
    165230}
    166231
    167 /** Creates new protocol specific data.
    168  *
    169  * Allocates and returns the needed memory block as the proto parameter.
    170  *
    171  * @param[out] proto    The allocated protocol specific data.
    172  * @param[in] service   The protocol module service.
    173  * @param[in] address   The actual protocol device address.
    174  * @returns             EOK on success.
    175  * @returns             ENOMEM if there is not enough memory left.
    176  */
    177 static int
    178 arp_proto_create(arp_proto_ref *proto, services_t service,
    179     measured_string_ref address)
    180 {
    181         int rc;
    182 
    183         *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
    184         if (!*proto)
    185                 return ENOMEM;
    186        
    187         (*proto)->service = service;
    188         (*proto)->addr = address;
    189         (*proto)->addr_data = address->value;
    190        
    191         rc = arp_addr_initialize(&(*proto)->addresses);
    192         if (rc != EOK) {
    193                 free(*proto);
    194                 return rc;
    195         }
    196        
    197         return EOK;
    198 }
    199 
    200 /** Registers the device.
    201  *
    202  * Creates new device entry in the cache or updates the protocol address if the
    203  * device with the device identifier and the driver service exists.
    204  *
    205  * @param[in] device_id The device identifier.
    206  * @param[in] service   The device driver service.
    207  * @param[in] protocol  The protocol service.
    208  * @param[in] address   The actual device protocol address.
    209  * @returns             EOK on success.
    210  * @returns             EEXIST if another device with the same device identifier
    211  *                      and different driver service exists.
    212  * @returns             ENOMEM if there is not enough memory left.
    213  * @returns             Other error codes as defined for the
    214  *                      measured_strings_return() function.
    215  */
    216 static int
    217 arp_device_message(device_id_t device_id, services_t service,
    218     services_t protocol, measured_string_ref address)
    219 {
     232int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){
     233        ERROR_DECLARE;
     234
    220235        arp_device_ref device;
    221236        arp_proto_ref proto;
     237        int index;
    222238        hw_type_t hardware;
    223         int index;
    224         int rc;
    225239
    226240        fibril_rwlock_write_lock(&arp_globals.lock);
    227241        // an existing device?
    228242        device = arp_cache_find(&arp_globals.cache, device_id);
    229         if (device) {
    230                 if (device->service != service) {
     243        if(device){
     244                if(device->service != service){
    231245                        printf("Device %d already exists\n", device->device_id);
    232246                        fibril_rwlock_write_unlock(&arp_globals.lock);
     
    234248                }
    235249                proto = arp_protos_find(&device->protos, protocol);
    236                 if (proto) {
     250                if(proto){
    237251                        free(proto->addr);
    238252                        free(proto->addr_data);
    239253                        proto->addr = address;
    240254                        proto->addr_data = address->value;
    241                 } else {
    242                         rc = arp_proto_create(&proto, protocol, address);
    243                         if (rc != EOK) {
     255                }else{
     256                        if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
    244257                                fibril_rwlock_write_unlock(&arp_globals.lock);
    245                                 return rc;
    246                         }
    247                         index = arp_protos_add(&device->protos, proto->service,
    248                             proto);
    249                         if (index < 0) {
     258                                return ERROR_CODE;
     259                        }
     260                        index = arp_protos_add(&device->protos, proto->service, proto);
     261                        if(index < 0){
    250262                                fibril_rwlock_write_unlock(&arp_globals.lock);
    251263                                free(proto);
    252264                                return index;
    253265                        }
    254                         printf("New protocol added:\n\tdevice id\t= "
    255                             "%d\n\tproto\t= %d", device_id, protocol);
    256                 }
    257         } else {
     266                        printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol);
     267                }
     268        }else{
    258269                hardware = hardware_map(service);
    259                 if (!hardware)
     270                if(! hardware){
    260271                        return ENOENT;
    261                
     272                }
    262273                // create a new device
    263274                device = (arp_device_ref) malloc(sizeof(arp_device_t));
    264                 if (!device) {
     275                if(! device){
    265276                        fibril_rwlock_write_unlock(&arp_globals.lock);
    266277                        return ENOMEM;
     
    268279                device->hardware = hardware;
    269280                device->device_id = device_id;
    270                 rc = arp_protos_initialize(&device->protos);
    271                 if (rc != EOK) {
     281                if(ERROR_OCCURRED(arp_protos_initialize(&device->protos))
     282                        || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
    272283                        fibril_rwlock_write_unlock(&arp_globals.lock);
    273284                        free(device);
    274                         return rc;
    275                 }
    276                 rc = arp_proto_create(&proto, protocol, address);
    277                 if (rc != EOK) {
    278                         fibril_rwlock_write_unlock(&arp_globals.lock);
    279                         free(device);
    280                         return rc;
     285                        return ERROR_CODE;
    281286                }
    282287                index = arp_protos_add(&device->protos, proto->service, proto);
    283                 if (index < 0) {
     288                if(index < 0){
    284289                        fibril_rwlock_write_unlock(&arp_globals.lock);
    285290                        arp_protos_destroy(&device->protos);
     
    288293                }
    289294                device->service = service;
    290                
    291295                // bind the new one
    292                 device->phone = nil_bind_service(device->service,
    293                     (ipcarg_t) device->device_id, SERVICE_ARP,
    294                     arp_globals.client_connection);
    295                 if (device->phone < 0) {
     296                device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection);
     297                if(device->phone < 0){
    296298                        fibril_rwlock_write_unlock(&arp_globals.lock);
    297299                        arp_protos_destroy(&device->protos);
     
    299301                        return EREFUSED;
    300302                }
    301                
    302303                // get packet dimensions
    303                 rc = nil_packet_size_req(device->phone, device_id,
    304                     &device->packet_dimension);
    305                 if (rc != EOK) {
     304                if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){
    306305                        fibril_rwlock_write_unlock(&arp_globals.lock);
    307306                        arp_protos_destroy(&device->protos);
    308307                        free(device);
    309                         return rc;
    310                 }
    311                
     308                        return ERROR_CODE;
     309                }
    312310                // get hardware address
    313                 rc = nil_get_addr_req(device->phone, device_id, &device->addr,
    314                     &device->addr_data);
    315                 if (rc != EOK) {
     311                if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){
    316312                        fibril_rwlock_write_unlock(&arp_globals.lock);
    317313                        arp_protos_destroy(&device->protos);
    318314                        free(device);
    319                         return rc;
    320                 }
    321                
     315                        return ERROR_CODE;
     316                }
    322317                // get broadcast address
    323                 rc = nil_get_broadcast_addr_req(device->phone, device_id,
    324                     &device->broadcast_addr, &device->broadcast_data);
    325                 if (rc != EOK) {
     318                if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){
    326319                        fibril_rwlock_write_unlock(&arp_globals.lock);
    327320                        free(device->addr);
     
    329322                        arp_protos_destroy(&device->protos);
    330323                        free(device);
    331                         return rc;
    332                 }
    333                
    334                 rc = arp_cache_add(&arp_globals.cache, device->device_id,
    335                     device);
    336                 if (rc != EOK) {
     324                        return ERROR_CODE;
     325                }
     326                if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){
    337327                        fibril_rwlock_write_unlock(&arp_globals.lock);
    338328                        free(device->addr);
     
    342332                        arp_protos_destroy(&device->protos);
    343333                        free(device);
    344                         return rc;
    345                 }
    346                 printf("%s: Device registered (id: %d, type: 0x%x, service: %d,"
    347                     " proto: %d)\n", NAME, device->device_id, device->hardware,
    348                     device->service, protocol);
     334                        return ERROR_CODE;
     335                }
     336                printf("%s: Device registered (id: %d, type: 0x%x, service: %d, proto: %d)\n",
     337                    NAME, device->device_id, device->hardware, device->service, protocol);
    349338        }
    350339        fibril_rwlock_write_unlock(&arp_globals.lock);
    351        
    352         return EOK;
    353 }
    354 
    355 /** Initializes the ARP module.
    356  *
    357  *  @param[in] client_connection The client connection processing function.
    358  *                      The module skeleton propagates its own one.
    359  *  @returns            EOK on success.
    360  *  @returns            ENOMEM if there is not enough memory left.
    361  */
    362 int arp_initialize(async_client_conn_t client_connection)
    363 {
    364         int rc;
     340        return EOK;
     341}
     342
     343int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
     344        ERROR_DECLARE;
     345
     346        measured_string_ref tmp;
     347
     348        // copy the given address for exclusive use
     349        tmp = measured_string_copy(address);
     350        if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){
     351                free(tmp->value);
     352                free(tmp);
     353        }
     354        return ERROR_CODE;
     355}
     356
     357int arp_initialize(async_client_conn_t client_connection){
     358        ERROR_DECLARE;
    365359
    366360        fibril_rwlock_initialize(&arp_globals.lock);
    367361        fibril_rwlock_write_lock(&arp_globals.lock);
    368362        arp_globals.client_connection = client_connection;
    369         rc = arp_cache_initialize(&arp_globals.cache);
     363        ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
    370364        fibril_rwlock_write_unlock(&arp_globals.lock);
     365        return EOK;
     366}
     367
     368int arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     369    ipc_call_t *answer, int *answer_count)
     370{
     371        ERROR_DECLARE;
    371372       
    372         return rc;
    373 }
    374 
    375 /** Updates the device content length according to the new MTU value.
    376  *
    377  * @param[in] device_id The device identifier.
    378  * @param[in] mtu       The new mtu value.
    379  * @returns             ENOENT if device is not found.
    380  * @returns             EOK on success.
    381  */
    382 static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
    383 {
     373        measured_string_ref address;
     374        measured_string_ref translation;
     375        char * data;
     376        packet_t packet;
     377        packet_t next;
     378       
     379        *answer_count = 0;
     380        switch (IPC_GET_METHOD(*call)) {
     381                case IPC_M_PHONE_HUNGUP:
     382                        return EOK;
     383                case NET_ARP_DEVICE:
     384                        ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
     385                        if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){
     386                                free(address);
     387                                free(data);
     388                        }
     389                        return ERROR_CODE;
     390                case NET_ARP_TRANSLATE:
     391                        ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
     392                        fibril_rwlock_read_lock(&arp_globals.lock);
     393                        translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
     394                        free(address);
     395                        free(data);
     396                        if(! translation){
     397                                fibril_rwlock_read_unlock(&arp_globals.lock);
     398                                return ENOENT;
     399                        }
     400                        ERROR_CODE = measured_strings_reply(translation, 1);
     401                        fibril_rwlock_read_unlock(&arp_globals.lock);
     402                        return ERROR_CODE;
     403                case NET_ARP_CLEAR_DEVICE:
     404                        return arp_clear_device_req(0, IPC_GET_DEVICE(call));
     405                case NET_ARP_CLEAR_ADDRESS:
     406                        ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
     407                        arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
     408                        free(address);
     409                        free(data);
     410                        return EOK;
     411                case NET_ARP_CLEAN_CACHE:
     412                        return arp_clean_cache_req(0);
     413                case NET_IL_DEVICE_STATE:
     414                        // do nothing - keep the cache
     415                        return EOK;
     416                case NET_IL_RECEIVED:
     417                        if(! ERROR_OCCURRED(packet_translate_remote(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
     418                                fibril_rwlock_read_lock(&arp_globals.lock);
     419                                do{
     420                                        next = pq_detach(packet);
     421                                        ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet);
     422                                        if(ERROR_CODE != 1){
     423                                                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
     424                                        }
     425                                        packet = next;
     426                                }while(packet);
     427                                fibril_rwlock_read_unlock(&arp_globals.lock);
     428                        }
     429                        return ERROR_CODE;
     430                case NET_IL_MTU_CHANGED:
     431                        return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call));
     432        }
     433       
     434        return ENOTSUP;
     435}
     436
     437int arp_mtu_changed_message(device_id_t device_id, size_t mtu){
    384438        arp_device_ref device;
    385439
    386440        fibril_rwlock_write_lock(&arp_globals.lock);
    387441        device = arp_cache_find(&arp_globals.cache, device_id);
    388         if (!device) {
     442        if(! device){
    389443                fibril_rwlock_write_unlock(&arp_globals.lock);
    390444                return ENOENT;
    391445        }
    392446        device->packet_dimension.content = mtu;
     447        printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
    393448        fibril_rwlock_write_unlock(&arp_globals.lock);
    394         printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
    395         return EOK;
    396 }
    397 
    398 /** Processes the received ARP packet.
    399  *
    400  * Updates the source hardware address if the source entry exists or the packet
    401  * is targeted to my protocol address.
    402  * Responses to the ARP request if the packet is the ARP request and is
    403  * targeted to my address.
    404  *
    405  * @param[in] device_id The source device identifier.
    406  * @param[in,out] packet The received packet.
    407  * @returns             EOK on success and the packet is no longer needed.
    408  * @returns             One on success and the packet has been reused.
    409  * @returns             EINVAL if the packet is too small to carry an ARP
    410  *                      packet.
    411  * @returns             EINVAL if the received address lengths differs from
    412  *                      the registered values.
    413  * @returns             ENOENT if the device is not found in the cache.
    414  * @returns             ENOENT if the protocol for the device is not found in
    415  *                      the cache.
    416  * @returns             ENOMEM if there is not enough memory left.
    417  */
    418 static int arp_receive_message(device_id_t device_id, packet_t packet)
    419 {
     449        return EOK;
     450}
     451
     452int 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
     469int arp_receive_message(device_id_t device_id, packet_t packet){
     470        ERROR_DECLARE;
     471
    420472        size_t length;
    421473        arp_header_ref header;
     
    423475        arp_proto_ref proto;
    424476        measured_string_ref hw_source;
    425         uint8_t *src_hw;
    426         uint8_t *src_proto;
    427         uint8_t *des_hw;
    428         uint8_t *des_proto;
    429         int rc;
     477        uint8_t * src_hw;
     478        uint8_t * src_proto;
     479        uint8_t * des_hw;
     480        uint8_t * des_proto;
    430481
    431482        length = packet_get_data_length(packet);
    432         if (length <= sizeof(arp_header_t))
     483        if(length <= sizeof(arp_header_t)){
    433484                return EINVAL;
    434 
     485        }
    435486        device = arp_cache_find(&arp_globals.cache, device_id);
    436         if (!device)
     487        if(! device){
    437488                return ENOENT;
    438 
     489        }
    439490        header = (arp_header_ref) packet_get_data(packet);
    440         if ((ntohs(header->hardware) != device->hardware) ||
    441             (length < sizeof(arp_header_t) + header->hardware_length * 2U +
    442             header->protocol_length * 2U)) {
     491        if((ntohs(header->hardware) != device->hardware)
     492                || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){
    443493                return EINVAL;
    444494        }
    445 
    446         proto = arp_protos_find(&device->protos,
    447             protocol_unmap(device->service, ntohs(header->protocol)));
    448         if (!proto)
     495        proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol)));
     496        if(! proto){
    449497                return ENOENT;
    450 
     498        }
    451499        src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
    452500        src_proto = src_hw + header->hardware_length;
    453501        des_hw = src_proto + header->protocol_length;
    454502        des_proto = des_hw + header->hardware_length;
    455         hw_source = arp_addr_find(&proto->addresses, (char *) src_proto,
    456             CONVERT_SIZE(uint8_t, char, header->protocol_length));
     503        hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length));
    457504        // exists?
    458         if (hw_source) {
    459                 if (hw_source->length != CONVERT_SIZE(uint8_t, char,
    460                     header->hardware_length)) {
     505        if(hw_source){
     506                if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){
    461507                        return EINVAL;
    462508                }
     
    464510        }
    465511        // is my protocol address?
    466         if (proto->addr->length != CONVERT_SIZE(uint8_t, char,
    467             header->protocol_length)) {
     512        if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){
    468513                return EINVAL;
    469514        }
    470         if (!str_lcmp(proto->addr->value, (char *) des_proto,
    471             proto->addr->length)) {
     515        if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){
    472516                // not already upadted?
    473                 if (!hw_source) {
    474                         hw_source = measured_string_create_bulk((char *) src_hw,
    475                             CONVERT_SIZE(uint8_t, char,
    476                             header->hardware_length));
    477                         if (!hw_source)
     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){
    478520                                return ENOMEM;
    479 
    480                         rc = arp_addr_add(&proto->addresses, (char *) src_proto,
    481                             CONVERT_SIZE(uint8_t, char,
    482                             header->protocol_length), hw_source);
    483                         if (rc != EOK)
    484                                 return rc;
    485                 }
    486                 if (ntohs(header->operation) == ARPOP_REQUEST) {
     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){
    487525                        header->operation = htons(ARPOP_REPLY);
    488526                        memcpy(des_proto, src_proto, header->protocol_length);
    489                         memcpy(src_proto, proto->addr->value,
    490                             header->protocol_length);
    491                         memcpy(src_hw, device->addr->value,
    492                             device->packet_dimension.addr_len);
    493                         memcpy(des_hw, hw_source->value,
    494                             header->hardware_length);
    495                        
    496                         rc = packet_set_addr(packet, src_hw, des_hw,
    497                             header->hardware_length);
    498                         if (rc != EOK)
    499                                 return rc;
    500                        
    501                         nil_send_msg(device->phone, device_id, packet,
    502                             SERVICE_ARP);
     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);
    503532                        return 1;
    504533                }
    505534        }
    506 
    507         return EOK;
    508 }
    509 
    510 
    511 /** Returns the hardware address for the given protocol address.
    512  *
    513  * Sends the ARP request packet if the hardware address is not found in the
    514  * cache.
    515  *
    516  * @param[in] device_id The device identifier.
    517  * @param[in] protocol  The protocol service.
    518  * @param[in] target    The target protocol address.
    519  * @returns             The hardware address of the target.
    520  * @returns             NULL if the target parameter is NULL.
    521  * @returns             NULL if the device is not found.
    522  * @returns             NULL if the device packet is too small to send a
    523  *                      request.
    524  * @returns             NULL if the hardware address is not found in the cache.
    525  */
    526 static measured_string_ref
    527 arp_translate_message(device_id_t device_id, services_t protocol,
    528     measured_string_ref target)
    529 {
     535        return EOK;
     536}
     537
     538measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){
    530539        arp_device_ref device;
    531540        arp_proto_ref proto;
     
    535544        arp_header_ref header;
    536545
    537         if (!target)
     546        if(! target){
    538547                return NULL;
    539 
     548        }
    540549        device = arp_cache_find(&arp_globals.cache, device_id);
    541         if (!device)
     550        if(! device){
    542551                return NULL;
    543 
     552        }
    544553        proto = arp_protos_find(&device->protos, protocol);
    545         if (!proto || (proto->addr->length != target->length))
     554        if((! proto) || (proto->addr->length != target->length)){
    546555                return NULL;
    547 
     556        }
    548557        addr = arp_addr_find(&proto->addresses, target->value, target->length);
    549         if (addr)
     558        if(addr){
    550559                return addr;
    551 
     560        }
    552561        // ARP packet content size = header + (address + translation) * 2
    553         length = 8 + 2 * (CONVERT_SIZE(char, uint8_t, proto->addr->length) +
    554             CONVERT_SIZE(char, uint8_t, device->addr->length));
    555         if (length > device->packet_dimension.content)
     562        length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2;
     563        if(length > device->packet_dimension.content){
    556564                return NULL;
    557 
    558         packet = packet_get_4_remote(arp_globals.net_phone,
    559             device->packet_dimension.addr_len, device->packet_dimension.prefix,
    560             length, device->packet_dimension.suffix);
    561         if (!packet)
     565        }
     566        packet = packet_get_4_remote(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
     567        if(! packet){
    562568                return NULL;
    563 
     569        }
    564570        header = (arp_header_ref) packet_suffix(packet, length);
    565         if (!header) {
     571        if(! header){
    566572                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    567573                return NULL;
    568574        }
    569 
    570575        header->hardware = htons(device->hardware);
    571576        header->hardware_length = (uint8_t) device->addr->length;
     
    574579        header->operation = htons(ARPOP_REQUEST);
    575580        length = sizeof(arp_header_t);
    576         memcpy(((uint8_t *) header) + length, device->addr->value,
    577             device->addr->length);
     581        memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length);
    578582        length += device->addr->length;
    579         memcpy(((uint8_t *) header) + length, proto->addr->value,
    580             proto->addr->length);
     583        memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length);
    581584        length += proto->addr->length;
    582585        bzero(((uint8_t *) header) + length, device->addr->length);
    583586        length += device->addr->length;
    584587        memcpy(((uint8_t *) header) + length, target->value, target->length);
    585 
    586         if (packet_set_addr(packet, (uint8_t *) device->addr->value,
    587             (uint8_t *) device->broadcast_addr->value,
    588             CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK) {
     588        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){
    589589                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    590590                return NULL;
    591591        }
    592 
    593592        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    594593        return NULL;
    595594}
    596595
    597 
    598 /** Processes the ARP message.
    599  *
    600  * @param[in] callid    The message identifier.
    601  * @param[in] call      The message parameters.
    602  * @param[out] answer   The message answer parameters.
    603  * @param[out] answer_count The last parameter for the actual answer in the
    604  *                      answer parameter.
    605  * @returns             EOK on success.
    606  * @returns             ENOTSUP if the message is not known.
    607  *
    608  * @see arp_interface.h
    609  * @see IS_NET_ARP_MESSAGE()
    610  */
    611 int
    612 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    613     ipc_call_t *answer, int *answer_count)
    614 {
    615         measured_string_ref address;
    616         measured_string_ref translation;
    617         char *data;
    618         packet_t packet;
    619         packet_t next;
    620         int rc;
    621        
    622         *answer_count = 0;
    623         switch (IPC_GET_METHOD(*call)) {
    624         case IPC_M_PHONE_HUNGUP:
    625                 return EOK;
    626        
    627         case NET_ARP_DEVICE:
    628                 rc = measured_strings_receive(&address, &data, 1);
    629                 if (rc != EOK)
    630                         return rc;
    631                
    632                 rc = arp_device_message(IPC_GET_DEVICE(call),
    633                     IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address);
    634                 if (rc != EOK) {
    635                         free(address);
    636                         free(data);
    637                 }
    638                 return rc;
    639        
    640         case NET_ARP_TRANSLATE:
    641                 rc = measured_strings_receive(&address, &data, 1);
    642                 if (rc != EOK)
    643                         return rc;
    644                
    645                 fibril_rwlock_read_lock(&arp_globals.lock);
    646                 translation = arp_translate_message(IPC_GET_DEVICE(call),
    647                     IPC_GET_SERVICE(call), address);
    648                 free(address);
    649                 free(data);
    650                 if (!translation) {
    651                         fibril_rwlock_read_unlock(&arp_globals.lock);
    652                         return ENOENT;
    653                 }
    654                 rc = measured_strings_reply(translation, 1);
    655                 fibril_rwlock_read_unlock(&arp_globals.lock);
    656                 return rc;
    657 
    658         case NET_ARP_CLEAR_DEVICE:
    659                 return arp_clear_device_req(0, IPC_GET_DEVICE(call));
    660 
    661         case NET_ARP_CLEAR_ADDRESS:
    662                 rc = measured_strings_receive(&address, &data, 1);
    663                 if (rc != EOK)
    664                         return rc;
    665                
    666                 arp_clear_address_req(0, IPC_GET_DEVICE(call),
    667                     IPC_GET_SERVICE(call), address);
    668                 free(address);
    669                 free(data);
    670                 return EOK;
    671        
    672         case NET_ARP_CLEAN_CACHE:
    673                 return arp_clean_cache_req(0);
    674        
    675         case NET_IL_DEVICE_STATE:
    676                 // do nothing - keep the cache
    677                 return EOK;
    678        
    679         case NET_IL_RECEIVED:
    680                 rc = packet_translate_remote(arp_globals.net_phone, &packet,
    681                     IPC_GET_PACKET(call));
    682                 if (rc != EOK)
    683                         return rc;
    684                
    685                 fibril_rwlock_read_lock(&arp_globals.lock);
    686                 do {
    687                         next = pq_detach(packet);
    688                         rc = arp_receive_message(IPC_GET_DEVICE(call), packet);
    689                         if (rc != 1) {
    690                                 pq_release_remote(arp_globals.net_phone,
    691                                     packet_get_id(packet));
    692                         }
    693                         packet = next;
    694                 } while (packet);
    695                 fibril_rwlock_read_unlock(&arp_globals.lock);
    696                
    697                 return EOK;
    698        
    699         case NET_IL_MTU_CHANGED:
    700                 return arp_mtu_changed_message(IPC_GET_DEVICE(call),
    701                     IPC_GET_MTU(call));
    702         }
    703        
    704         return ENOTSUP;
    705 }
    706 
    707596/** Default thread for new connections.
    708597 *
    709  * @param[in] iid       The initial message identifier.
    710  * @param[in] icall     The initial message call structure.
    711  */
    712 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     598 *  @param[in] iid The initial message identifier.
     599 *  @param[in] icall The initial message call structure.
     600 *
     601 */
     602static void il_client_connection(ipc_callid_t iid, ipc_call_t * icall)
    713603{
    714604        /*
     
    718608        ipc_answer_0(iid, EOK);
    719609       
    720         while (true) {
     610        while(true) {
    721611                ipc_call_t answer;
    722612                int answer_count;
     
    733623                    &answer_count);
    734624               
    735                 /*
    736                  * End if told to either by the message or the processing
    737                  * result.
    738                  */
    739                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
    740                     (res == EHANGUP))
     625                /* End if said to either by the message or the processing result */
     626                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
    741627                        return;
    742628               
     
    748634/** Starts the module.
    749635 *
    750  * @returns             EOK on success.
    751  * @returns             Other error codes as defined for each specific module
    752  *                      start function.
     636 *  @param argc The count of the command line arguments. Ignored parameter.
     637 *  @param argv The command line parameters. Ignored parameter.
     638 *
     639 *  @returns EOK on success.
     640 *  @returns Other error codes as defined for each specific module start function.
     641 *
    753642 */
    754643int main(int argc, char *argv[])
    755644{
    756         int rc;
     645        ERROR_DECLARE;
    757646       
    758647        /* Start the module */
    759         rc = il_module_start_standalone(il_client_connection);
    760         return rc;
     648        if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection)))
     649                return ERROR_CODE;
     650       
     651        return EOK;
    761652}
    762653
    763654/** @}
    764655 */
    765 
Note: See TracChangeset for help on using the changeset viewer.