Ignore:
File:
1 edited

Legend:

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

    re9caf47 r5fe7692  
    3636 */
    3737
    38 #include "arp.h"
    39 #include "arp_header.h"
    40 #include "arp_oc.h"
    41 #include "arp_module.h"
    42 
    4338#include <async.h>
    4439#include <malloc.h>
    4540#include <mem.h>
    4641#include <fibril_synch.h>
     42#include <assert.h>
    4743#include <stdio.h>
    4844#include <str.h>
    4945#include <task.h>
    5046#include <adt/measured_strings.h>
    51 #include <ipc/ipc.h>
    5247#include <ipc/services.h>
    5348#include <ipc/net.h>
    5449#include <ipc/arp.h>
    5550#include <ipc/il.h>
     51#include <ipc/nil.h>
    5652#include <byteorder.h>
    57 #include <err.h>
    58 
     53#include <errno.h>
    5954#include <net/modules.h>
    6055#include <net/device.h>
    6156#include <net/packet.h>
    62 
    63 #include <nil_interface.h>
     57#include <nil_remote.h>
    6458#include <protocol_map.h>
    6559#include <packet_client.h>
    6660#include <packet_remote.h>
    67 #include <il_interface.h>
    68 #include <il_local.h>
    69 
     61#include <il_remote.h>
     62#include <il_skel.h>
     63#include "arp.h"
    7064
    7165/** ARP module name. */
    7266#define NAME  "arp"
    7367
     68/** Number of microseconds to wait for an ARP reply. */
     69#define ARP_TRANS_WAIT  1000000
     70
     71/** @name ARP operation codes definitions */
     72/*@{*/
     73
     74/** REQUEST operation code. */
     75#define ARPOP_REQUEST  1
     76
     77/** REPLY operation code. */
     78#define ARPOP_REPLY  2
     79
     80/*@}*/
     81
     82/** Type definition of an ARP protocol header.
     83 * @see arp_header
     84 */
     85typedef struct arp_header arp_header_t;
     86
     87/** ARP protocol header. */
     88struct arp_header {
     89        /**
     90         * Hardware type identifier.
     91         * @see hardware.h
     92         */
     93        uint16_t hardware;
     94       
     95        /** Protocol identifier. */
     96        uint16_t protocol;
     97        /** Hardware address length in bytes. */
     98        uint8_t hardware_length;
     99        /** Protocol address length in bytes. */
     100        uint8_t protocol_length;
     101       
     102        /**
     103         * ARP packet type.
     104         * @see arp_oc.h
     105         */
     106        uint16_t operation;
     107} __attribute__ ((packed));
     108
    74109/** ARP global data. */
    75110arp_globals_t arp_globals;
     
    77112DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t);
    78113INT_MAP_IMPLEMENT(arp_protos, arp_proto_t);
    79 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t);
    80 
    81 /** 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)
     114GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, arp_trans_t);
     115
     116static void arp_clear_trans(arp_trans_t *trans)
     117{
     118        if (trans->hw_addr) {
     119                free(trans->hw_addr);
     120                trans->hw_addr = NULL;
     121        }
     122       
     123        fibril_condvar_broadcast(&trans->cv);
     124}
     125
     126static void arp_clear_addr(arp_addr_t *addresses)
    86127{
    87128        int count;
    88         arp_proto_ref proto;
    89 
     129       
     130        for (count = arp_addr_count(addresses) - 1; count >= 0; count--) {
     131                arp_trans_t *trans = arp_addr_items_get_index(&addresses->values,
     132                    count);
     133                if (trans)
     134                        arp_clear_trans(trans);
     135        }
     136}
     137
     138/** Clear the device specific data.
     139 *
     140 * @param[in] device Device specific data.
     141 */
     142static void arp_clear_device(arp_device_t *device)
     143{
     144        int count;
     145       
    90146        for (count = arp_protos_count(&device->protos) - 1; count >= 0;
    91147            count--) {
    92                 proto = arp_protos_get_index(&device->protos, count);
     148                arp_proto_t *proto = arp_protos_get_index(&device->protos,
     149                    count);
     150               
    93151                if (proto) {
    94152                        if (proto->addr)
    95153                                free(proto->addr);
     154                       
    96155                        if (proto->addr_data)
    97156                                free(proto->addr_data);
    98                         arp_addr_destroy(&proto->addresses);
    99                 }
    100         }
    101         arp_protos_clear(&device->protos);
     157                       
     158                        arp_clear_addr(&proto->addresses);
     159                        arp_addr_destroy(&proto->addresses, free);
     160                }
     161        }
     162       
     163        arp_protos_clear(&device->protos, free);
    102164}
    103165
     
    105167{
    106168        int count;
    107         arp_device_ref device;
    108 
    109         fibril_rwlock_write_lock(&arp_globals.lock);
     169       
     170        fibril_mutex_lock(&arp_globals.lock);
    110171        for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0;
    111172            count--) {
    112                 device = arp_cache_get_index(&arp_globals.cache, count);
     173                arp_device_t *device = arp_cache_get_index(&arp_globals.cache,
     174                    count);
     175               
    113176                if (device) {
    114177                        arp_clear_device(device);
    115178                        if (device->addr_data)
    116179                                free(device->addr_data);
     180                       
    117181                        if (device->broadcast_data)
    118182                                free(device->broadcast_data);
    119183                }
    120184        }
    121         arp_cache_clear(&arp_globals.cache);
    122         fibril_rwlock_write_unlock(&arp_globals.lock);
    123         printf("Cache cleaned\n");
     185       
     186        arp_cache_clear(&arp_globals.cache, free);
     187        fibril_mutex_unlock(&arp_globals.lock);
     188       
    124189        return EOK;
    125190}
    126191
    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 {
    131         arp_device_ref device;
    132         arp_proto_ref proto;
    133 
    134         fibril_rwlock_write_lock(&arp_globals.lock);
    135         device = arp_cache_find(&arp_globals.cache, device_id);
     192static int arp_clear_address_req(int arp_phone, device_id_t device_id,
     193    services_t protocol, measured_string_t *address)
     194{
     195        fibril_mutex_lock(&arp_globals.lock);
     196       
     197        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    136198        if (!device) {
    137                 fibril_rwlock_write_unlock(&arp_globals.lock);
     199                fibril_mutex_unlock(&arp_globals.lock);
    138200                return ENOENT;
    139201        }
    140         proto = arp_protos_find(&device->protos, protocol);
     202       
     203        arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
    141204        if (!proto) {
    142                 fibril_rwlock_write_unlock(&arp_globals.lock);
     205                fibril_mutex_unlock(&arp_globals.lock);
    143206                return ENOENT;
    144207        }
    145         arp_addr_exclude(&proto->addresses, address->value, address->length);
    146         fibril_rwlock_write_unlock(&arp_globals.lock);
     208       
     209        arp_trans_t *trans = arp_addr_find(&proto->addresses, address->value,
     210            address->length);
     211        if (trans)
     212                arp_clear_trans(trans);
     213       
     214        arp_addr_exclude(&proto->addresses, address->value, address->length, free);
     215       
     216        fibril_mutex_unlock(&arp_globals.lock);
    147217        return EOK;
    148218}
    149219
    150 
    151220static int arp_clear_device_req(int arp_phone, device_id_t device_id)
    152221{
    153         arp_device_ref device;
    154 
    155         fibril_rwlock_write_lock(&arp_globals.lock);
    156         device = arp_cache_find(&arp_globals.cache, device_id);
     222        fibril_mutex_lock(&arp_globals.lock);
     223       
     224        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    157225        if (!device) {
    158                 fibril_rwlock_write_unlock(&arp_globals.lock);
     226                fibril_mutex_unlock(&arp_globals.lock);
    159227                return ENOENT;
    160228        }
     229       
    161230        arp_clear_device(device);
    162         printf("Device %d cleared\n", device_id);
    163         fibril_rwlock_write_unlock(&arp_globals.lock);
     231       
     232        fibril_mutex_unlock(&arp_globals.lock);
    164233        return EOK;
    165234}
    166235
    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         ERROR_DECLARE;
    182 
    183         *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
     236/** Create new protocol specific data.
     237 *
     238 * Allocate and return the needed memory block as the proto parameter.
     239 *
     240 * @param[out] proto   Allocated protocol specific data.
     241 * @param[in]  service Protocol module service.
     242 * @param[in]  address Actual protocol device address.
     243 *
     244 * @return EOK on success.
     245 * @return ENOMEM if there is not enough memory left.
     246 *
     247 */
     248static int arp_proto_create(arp_proto_t **proto, services_t service,
     249    measured_string_t *address)
     250{
     251        *proto = (arp_proto_t *) malloc(sizeof(arp_proto_t));
    184252        if (!*proto)
    185253                return ENOMEM;
     254       
    186255        (*proto)->service = service;
    187256        (*proto)->addr = address;
    188257        (*proto)->addr_data = address->value;
    189         if (ERROR_OCCURRED(arp_addr_initialize(&(*proto)->addresses))) {
     258       
     259        int rc = arp_addr_initialize(&(*proto)->addresses);
     260        if (rc != EOK) {
    190261                free(*proto);
    191                 return ERROR_CODE;
    192         }
     262                return rc;
     263        }
     264       
    193265        return EOK;
    194266}
    195267
    196 /** Registers the device.
    197  *
    198  * Creates new device entry in the cache or updates the protocol address if the
    199  * device with the device identifier and the driver service exists.
    200  *
    201  * @param[in] device_id The device identifier.
    202  * @param[in] service   The device driver service.
    203  * @param[in] protocol  The protocol service.
    204  * @param[in] address   The actual device protocol address.
    205  * @returns             EOK on success.
    206  * @returns             EEXIST if another device with the same device identifier
    207  *                      and different driver service exists.
    208  * @returns             ENOMEM if there is not enough memory left.
    209  * @returns             Other error codes as defined for the
    210  *                      measured_strings_return() function.
    211  */
    212 static int
    213 arp_device_message(device_id_t device_id, services_t service,
    214     services_t protocol, measured_string_ref address)
    215 {
    216         ERROR_DECLARE;
    217 
    218         arp_device_ref device;
    219         arp_proto_ref proto;
    220         int index;
    221         hw_type_t hardware;
    222 
    223         fibril_rwlock_write_lock(&arp_globals.lock);
    224         // an existing device?
    225         device = arp_cache_find(&arp_globals.cache, device_id);
    226         if (device) {
    227                 if (device->service != service) {
    228                         printf("Device %d already exists\n", device->device_id);
    229                         fibril_rwlock_write_unlock(&arp_globals.lock);
    230                         return EEXIST;
    231                 }
    232                 proto = arp_protos_find(&device->protos, protocol);
    233                 if (proto) {
    234                         free(proto->addr);
    235                         free(proto->addr_data);
    236                         proto->addr = address;
    237                         proto->addr_data = address->value;
    238                 } else {
    239                         if (ERROR_OCCURRED(arp_proto_create(&proto, protocol,
    240                             address))) {
    241                                 fibril_rwlock_write_unlock(&arp_globals.lock);
    242                                 return ERROR_CODE;
    243                         }
    244                         index = arp_protos_add(&device->protos, proto->service,
    245                             proto);
    246                         if (index < 0) {
    247                                 fibril_rwlock_write_unlock(&arp_globals.lock);
    248                                 free(proto);
    249                                 return index;
    250                         }
    251                         printf("New protocol added:\n\tdevice id\t= "
    252                             "%d\n\tproto\t= %d", device_id, protocol);
    253                 }
    254         } else {
    255                 hardware = hardware_map(service);
    256                 if (!hardware)
    257                         return ENOENT;
    258                
    259                 // create a new device
    260                 device = (arp_device_ref) malloc(sizeof(arp_device_t));
    261                 if (!device) {
    262                         fibril_rwlock_write_unlock(&arp_globals.lock);
    263                         return ENOMEM;
    264                 }
    265                 device->hardware = hardware;
    266                 device->device_id = device_id;
    267                 if (ERROR_OCCURRED(arp_protos_initialize(&device->protos)) ||
    268                     ERROR_OCCURRED(arp_proto_create(&proto, protocol,
    269                     address))) {
    270                         fibril_rwlock_write_unlock(&arp_globals.lock);
    271                         free(device);
    272                         return ERROR_CODE;
    273                 }
    274                 index = arp_protos_add(&device->protos, proto->service, proto);
    275                 if (index < 0) {
    276                         fibril_rwlock_write_unlock(&arp_globals.lock);
    277                         arp_protos_destroy(&device->protos);
    278                         free(device);
    279                         return index;
    280                 }
    281                 device->service = service;
    282                
    283                 // bind the new one
    284                 device->phone = nil_bind_service(device->service,
    285                     (ipcarg_t) device->device_id, SERVICE_ARP,
    286                     arp_globals.client_connection);
    287                 if (device->phone < 0) {
    288                         fibril_rwlock_write_unlock(&arp_globals.lock);
    289                         arp_protos_destroy(&device->protos);
    290                         free(device);
    291                         return EREFUSED;
    292                 }
    293                
    294                 // get packet dimensions
    295                 if (ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id,
    296                     &device->packet_dimension))) {
    297                         fibril_rwlock_write_unlock(&arp_globals.lock);
    298                         arp_protos_destroy(&device->protos);
    299                         free(device);
    300                         return ERROR_CODE;
    301                 }
    302                
    303                 // get hardware address
    304                 if (ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id,
    305                     &device->addr, &device->addr_data))) {
    306                         fibril_rwlock_write_unlock(&arp_globals.lock);
    307                         arp_protos_destroy(&device->protos);
    308                         free(device);
    309                         return ERROR_CODE;
    310                 }
    311                
    312                 // get broadcast address
    313                 if (ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone,
    314                     device_id, &device->broadcast_addr,
    315                     &device->broadcast_data))) {
    316                         fibril_rwlock_write_unlock(&arp_globals.lock);
    317                         free(device->addr);
    318                         free(device->addr_data);
    319                         arp_protos_destroy(&device->protos);
    320                         free(device);
    321                         return ERROR_CODE;
    322                 }
    323                
    324                 if (ERROR_OCCURRED(arp_cache_add(&arp_globals.cache,
    325                     device->device_id, device))) {
    326                         fibril_rwlock_write_unlock(&arp_globals.lock);
    327                         free(device->addr);
    328                         free(device->addr_data);
    329                         free(device->broadcast_addr);
    330                         free(device->broadcast_data);
    331                         arp_protos_destroy(&device->protos);
    332                         free(device);
    333                         return ERROR_CODE;
    334                 }
    335                 printf("%s: Device registered (id: %d, type: 0x%x, service: %d,"
    336                     " proto: %d)\n", NAME, device->device_id, device->hardware,
    337                     device->service, protocol);
    338         }
    339         fibril_rwlock_write_unlock(&arp_globals.lock);
    340        
    341         return EOK;
    342 }
    343 
    344 /** Initializes the ARP module.
    345  *
    346  *  @param[in] client_connection The client connection processing function.
    347  *                      The module skeleton propagates its own one.
    348  *  @returns            EOK on success.
    349  *  @returns            ENOMEM if there is not enough memory left.
    350  */
    351 int arp_initialize(async_client_conn_t client_connection)
    352 {
    353         ERROR_DECLARE;
    354 
    355         fibril_rwlock_initialize(&arp_globals.lock);
    356         fibril_rwlock_write_lock(&arp_globals.lock);
    357         arp_globals.client_connection = client_connection;
    358         ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
    359         fibril_rwlock_write_unlock(&arp_globals.lock);
    360         return EOK;
    361 }
    362 
    363 /** Updates the device content length according to the new MTU value.
    364  *
    365  * @param[in] device_id The device identifier.
    366  * @param[in] mtu       The new mtu value.
    367  * @returns             ENOENT if device is not found.
    368  * @returns             EOK on success.
    369  */
    370 static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
    371 {
    372         arp_device_ref device;
    373 
    374         fibril_rwlock_write_lock(&arp_globals.lock);
    375         device = arp_cache_find(&arp_globals.cache, device_id);
    376         if (!device) {
    377                 fibril_rwlock_write_unlock(&arp_globals.lock);
    378                 return ENOENT;
    379         }
    380         device->packet_dimension.content = mtu;
    381         fibril_rwlock_write_unlock(&arp_globals.lock);
    382         printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
    383         return EOK;
    384 }
    385 
    386 /** Processes the received ARP packet.
    387  *
    388  * Updates the source hardware address if the source entry exists or the packet
     268/** Process the received ARP packet.
     269 *
     270 * Update the source hardware address if the source entry exists or the packet
    389271 * is targeted to my protocol address.
    390  * Responses to the ARP request if the packet is the ARP request and is
     272 *
     273 * Respond to the ARP request if the packet is the ARP request and is
    391274 * targeted to my address.
    392275 *
    393  * @param[in] device_id The source device identifier.
    394  * @param[in,out] packet The received packet.
    395  * @returns             EOK on success and the packet is no longer needed.
    396  * @returns             One on success and the packet has been reused.
    397  * @returns             EINVAL if the packet is too small to carry an ARP
    398  *                      packet.
    399  * @returns             EINVAL if the received address lengths differs from
    400  *                      the registered values.
    401  * @returns             ENOENT if the device is not found in the cache.
    402  * @returns             ENOENT if the protocol for the device is not found in
    403  *                      the cache.
    404  * @returns             ENOMEM if there is not enough memory left.
    405  */
    406 static int arp_receive_message(device_id_t device_id, packet_t packet)
    407 {
    408         ERROR_DECLARE;
    409 
    410         size_t length;
    411         arp_header_ref header;
    412         arp_device_ref device;
    413         arp_proto_ref proto;
    414         measured_string_ref hw_source;
    415         uint8_t *src_hw;
    416         uint8_t *src_proto;
    417         uint8_t *des_hw;
    418         uint8_t *des_proto;
    419 
    420         length = packet_get_data_length(packet);
     276 * @param[in]     device_id Source device identifier.
     277 * @param[in,out] packet    Received packet.
     278 *
     279 * @return EOK on success and the packet is no longer needed.
     280 * @return One on success and the packet has been reused.
     281 * @return EINVAL if the packet is too small to carry an ARP
     282 *         packet.
     283 * @return EINVAL if the received address lengths differs from
     284 *         the registered values.
     285 * @return ENOENT if the device is not found in the cache.
     286 * @return ENOENT if the protocol for the device is not found in
     287 *         the cache.
     288 * @return ENOMEM if there is not enough memory left.
     289 *
     290 */
     291static int arp_receive_message(device_id_t device_id, packet_t *packet)
     292{
     293        int rc;
     294       
     295        size_t length = packet_get_data_length(packet);
    421296        if (length <= sizeof(arp_header_t))
    422297                return EINVAL;
    423 
    424         device = arp_cache_find(&arp_globals.cache, device_id);
     298       
     299        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    425300        if (!device)
    426301                return ENOENT;
    427 
    428         header = (arp_header_ref) packet_get_data(packet);
     302       
     303        arp_header_t *header = (arp_header_t *) packet_get_data(packet);
    429304        if ((ntohs(header->hardware) != device->hardware) ||
    430305            (length < sizeof(arp_header_t) + header->hardware_length * 2U +
     
    432307                return EINVAL;
    433308        }
    434 
    435         proto = arp_protos_find(&device->protos,
     309       
     310        arp_proto_t *proto = arp_protos_find(&device->protos,
    436311            protocol_unmap(device->service, ntohs(header->protocol)));
    437312        if (!proto)
    438313                return ENOENT;
    439 
    440         src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
    441         src_proto = src_hw + header->hardware_length;
    442         des_hw = src_proto + header->protocol_length;
    443         des_proto = des_hw + header->hardware_length;
    444         hw_source = arp_addr_find(&proto->addresses, (char *) src_proto,
    445             CONVERT_SIZE(uint8_t, char, header->protocol_length));
    446         // exists?
    447         if (hw_source) {
    448                 if (hw_source->length != CONVERT_SIZE(uint8_t, char,
    449                     header->hardware_length)) {
     314       
     315        uint8_t *src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
     316        uint8_t *src_proto = src_hw + header->hardware_length;
     317        uint8_t *des_hw = src_proto + header->protocol_length;
     318        uint8_t *des_proto = des_hw + header->hardware_length;
     319       
     320        arp_trans_t *trans = arp_addr_find(&proto->addresses, src_proto,
     321            header->protocol_length);
     322       
     323        if ((trans) && (trans->hw_addr)) {
     324                /* Translation exists */
     325                if (trans->hw_addr->length != header->hardware_length)
    450326                        return EINVAL;
    451                 }
    452                 memcpy(hw_source->value, src_hw, hw_source->length);
    453         }
    454         // is my protocol address?
    455         if (proto->addr->length != CONVERT_SIZE(uint8_t, char,
    456             header->protocol_length)) {
     327               
     328                memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
     329        }
     330       
     331        /* Is my protocol address? */
     332        if (proto->addr->length != header->protocol_length)
    457333                return EINVAL;
    458         }
    459         if (!str_lcmp(proto->addr->value, (char *) des_proto,
    460             proto->addr->length)) {
    461                 // not already upadted?
    462                 if (!hw_source) {
    463                         hw_source = measured_string_create_bulk((char *) src_hw,
    464                             CONVERT_SIZE(uint8_t, char,
    465                             header->hardware_length));
    466                         if (!hw_source)
     334       
     335        if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
     336                if (!trans) {
     337                        /* Update the translation */
     338                        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
     339                        if (!trans)
    467340                                return ENOMEM;
    468 
    469                         ERROR_PROPAGATE(arp_addr_add(&proto->addresses,
    470                             (char *) src_proto, CONVERT_SIZE(uint8_t, char,
    471                             header->protocol_length), hw_source));
    472                 }
     341                       
     342                        trans->hw_addr = NULL;
     343                        fibril_condvar_initialize(&trans->cv);
     344                        rc = arp_addr_add(&proto->addresses, src_proto,
     345                            header->protocol_length, trans);
     346                        if (rc != EOK) {
     347                                free(trans);
     348                                return rc;
     349                        }
     350                }
     351               
     352                if (!trans->hw_addr) {
     353                        trans->hw_addr = measured_string_create_bulk(src_hw,
     354                            header->hardware_length);
     355                        if (!trans->hw_addr)
     356                                return ENOMEM;
     357                       
     358                        /* Notify the fibrils that wait for the translation. */
     359                        fibril_condvar_broadcast(&trans->cv);
     360                }
     361               
    473362                if (ntohs(header->operation) == ARPOP_REQUEST) {
    474363                        header->operation = htons(ARPOP_REPLY);
     
    478367                        memcpy(src_hw, device->addr->value,
    479368                            device->packet_dimension.addr_len);
    480                         memcpy(des_hw, hw_source->value,
     369                        memcpy(des_hw, trans->hw_addr->value,
    481370                            header->hardware_length);
    482                         ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw,
    483                             header->hardware_length));
     371                       
     372                        rc = packet_set_addr(packet, src_hw, des_hw,
     373                            header->hardware_length);
     374                        if (rc != EOK)
     375                                return rc;
     376                       
    484377                        nil_send_msg(device->phone, device_id, packet,
    485378                            SERVICE_ARP);
     
    487380                }
    488381        }
    489 
     382       
    490383        return EOK;
    491384}
    492385
    493 
    494 /** Returns the hardware address for the given protocol address.
    495  *
    496  * Sends the ARP request packet if the hardware address is not found in the
    497  * cache.
    498  *
    499  * @param[in] device_id The device identifier.
    500  * @param[in] protocol  The protocol service.
    501  * @param[in] target    The target protocol address.
    502  * @returns             The hardware address of the target.
    503  * @returns             NULL if the target parameter is NULL.
    504  * @returns             NULL if the device is not found.
    505  * @returns             NULL if the device packet is too small to send a
    506  *                      request.
    507  * @returns             NULL if the hardware address is not found in the cache.
    508  */
    509 static measured_string_ref
    510 arp_translate_message(device_id_t device_id, services_t protocol,
    511     measured_string_ref target)
    512 {
    513         arp_device_ref device;
    514         arp_proto_ref proto;
    515         measured_string_ref addr;
    516         size_t length;
    517         packet_t packet;
    518         arp_header_ref header;
    519 
    520         if (!target)
    521                 return NULL;
    522 
    523         device = arp_cache_find(&arp_globals.cache, device_id);
    524         if (!device)
    525                 return NULL;
    526 
    527         proto = arp_protos_find(&device->protos, protocol);
    528         if (!proto || (proto->addr->length != target->length))
    529                 return NULL;
    530 
    531         addr = arp_addr_find(&proto->addresses, target->value, target->length);
    532         if (addr)
    533                 return addr;
    534 
    535         // ARP packet content size = header + (address + translation) * 2
    536         length = 8 + 2 * (CONVERT_SIZE(char, uint8_t, proto->addr->length) +
    537             CONVERT_SIZE(char, uint8_t, device->addr->length));
     386/** Update the device content length according to the new MTU value.
     387 *
     388 * @param[in] device_id Device identifier.
     389 * @param[in] mtu       New MTU value.
     390 *
     391 * @return ENOENT if device is not found.
     392 * @return EOK on success.
     393 *
     394 */
     395static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
     396{
     397        fibril_mutex_lock(&arp_globals.lock);
     398       
     399        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     400        if (!device) {
     401                fibril_mutex_unlock(&arp_globals.lock);
     402                return ENOENT;
     403        }
     404       
     405        device->packet_dimension.content = mtu;
     406       
     407        fibril_mutex_unlock(&arp_globals.lock);
     408       
     409        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
     410       
     411        return EOK;
     412}
     413
     414/** Process IPC messages from the registered device driver modules
     415 *
     416 * @param[in]     iid   Message identifier.
     417 * @param[in,out] icall Message parameters.
     418 *
     419 */
     420static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     421{
     422        packet_t *packet;
     423        int rc;
     424       
     425        while (true) {
     426                switch (IPC_GET_IMETHOD(*icall)) {
     427                case NET_IL_DEVICE_STATE:
     428                        /* Do nothing - keep the cache */
     429                        async_answer_0(iid, (sysarg_t) EOK);
     430                        break;
     431               
     432                case NET_IL_RECEIVED:
     433                        rc = packet_translate_remote(arp_globals.net_phone, &packet,
     434                            IPC_GET_PACKET(*icall));
     435                        if (rc == EOK) {
     436                                fibril_mutex_lock(&arp_globals.lock);
     437                                do {
     438                                        packet_t *next = pq_detach(packet);
     439                                        rc = arp_receive_message(IPC_GET_DEVICE(*icall), packet);
     440                                        if (rc != 1) {
     441                                                pq_release_remote(arp_globals.net_phone,
     442                                                    packet_get_id(packet));
     443                                        }
     444                                       
     445                                        packet = next;
     446                                } while (packet);
     447                                fibril_mutex_unlock(&arp_globals.lock);
     448                        }
     449                        async_answer_0(iid, (sysarg_t) rc);
     450                        break;
     451               
     452                case NET_IL_MTU_CHANGED:
     453                        rc = arp_mtu_changed_message(IPC_GET_DEVICE(*icall),
     454                            IPC_GET_MTU(*icall));
     455                        async_answer_0(iid, (sysarg_t) rc);
     456                        break;
     457               
     458                default:
     459                        async_answer_0(iid, (sysarg_t) ENOTSUP);
     460                }
     461               
     462                iid = async_get_call(icall);
     463        }
     464}
     465
     466/** Register the device.
     467 *
     468 * Create new device entry in the cache or update the protocol address if the
     469 * device with the device identifier and the driver service exists.
     470 *
     471 * @param[in] device_id Device identifier.
     472 * @param[in] service   Device driver service.
     473 * @param[in] protocol  Protocol service.
     474 * @param[in] address   Actual device protocol address.
     475 *
     476 * @return EOK on success.
     477 * @return EEXIST if another device with the same device identifier
     478 *         and different driver service exists.
     479 * @return ENOMEM if there is not enough memory left.
     480 * @return Other error codes as defined for the
     481 *         measured_strings_return() function.
     482 *
     483 */
     484static int arp_device_message(device_id_t device_id, services_t service,
     485    services_t protocol, measured_string_t *address)
     486{
     487        int index;
     488        int rc;
     489       
     490        fibril_mutex_lock(&arp_globals.lock);
     491       
     492        /* An existing device? */
     493        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     494        if (device) {
     495                if (device->service != service) {
     496                        printf("%s: Device %d already exists\n", NAME,
     497                            device->device_id);
     498                        fibril_mutex_unlock(&arp_globals.lock);
     499                        return EEXIST;
     500                }
     501               
     502                arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
     503                if (proto) {
     504                        free(proto->addr);
     505                        free(proto->addr_data);
     506                        proto->addr = address;
     507                        proto->addr_data = address->value;
     508                } else {
     509                        rc = arp_proto_create(&proto, protocol, address);
     510                        if (rc != EOK) {
     511                                fibril_mutex_unlock(&arp_globals.lock);
     512                                return rc;
     513                        }
     514                       
     515                        index = arp_protos_add(&device->protos, proto->service,
     516                            proto);
     517                        if (index < 0) {
     518                                fibril_mutex_unlock(&arp_globals.lock);
     519                                free(proto);
     520                                return index;
     521                        }
     522                       
     523                        printf("%s: New protocol added (id: %d, proto: %d)\n", NAME,
     524                            device_id, protocol);
     525                }
     526        } else {
     527                hw_type_t hardware = hardware_map(service);
     528                if (!hardware)
     529                        return ENOENT;
     530               
     531                /* Create new device */
     532                device = (arp_device_t *) malloc(sizeof(arp_device_t));
     533                if (!device) {
     534                        fibril_mutex_unlock(&arp_globals.lock);
     535                        return ENOMEM;
     536                }
     537               
     538                device->hardware = hardware;
     539                device->device_id = device_id;
     540                rc = arp_protos_initialize(&device->protos);
     541                if (rc != EOK) {
     542                        fibril_mutex_unlock(&arp_globals.lock);
     543                        free(device);
     544                        return rc;
     545                }
     546               
     547                arp_proto_t *proto;
     548                rc = arp_proto_create(&proto, protocol, address);
     549                if (rc != EOK) {
     550                        fibril_mutex_unlock(&arp_globals.lock);
     551                        free(device);
     552                        return rc;
     553                }
     554               
     555                index = arp_protos_add(&device->protos, proto->service, proto);
     556                if (index < 0) {
     557                        fibril_mutex_unlock(&arp_globals.lock);
     558                        arp_protos_destroy(&device->protos, free);
     559                        free(device);
     560                        return index;
     561                }
     562               
     563                device->service = service;
     564               
     565                /* Bind */
     566                device->phone = nil_bind_service(device->service,
     567                    (sysarg_t) device->device_id, SERVICE_ARP,
     568                    arp_receiver);
     569                if (device->phone < 0) {
     570                        fibril_mutex_unlock(&arp_globals.lock);
     571                        arp_protos_destroy(&device->protos, free);
     572                        free(device);
     573                        return EREFUSED;
     574                }
     575               
     576                /* Get packet dimensions */
     577                rc = nil_packet_size_req(device->phone, device_id,
     578                    &device->packet_dimension);
     579                if (rc != EOK) {
     580                        fibril_mutex_unlock(&arp_globals.lock);
     581                        arp_protos_destroy(&device->protos, free);
     582                        free(device);
     583                        return rc;
     584                }
     585               
     586                /* Get hardware address */
     587                rc = nil_get_addr_req(device->phone, device_id, &device->addr,
     588                    &device->addr_data);
     589                if (rc != EOK) {
     590                        fibril_mutex_unlock(&arp_globals.lock);
     591                        arp_protos_destroy(&device->protos, free);
     592                        free(device);
     593                        return rc;
     594                }
     595               
     596                /* Get broadcast address */
     597                rc = nil_get_broadcast_addr_req(device->phone, device_id,
     598                    &device->broadcast_addr, &device->broadcast_data);
     599                if (rc != EOK) {
     600                        fibril_mutex_unlock(&arp_globals.lock);
     601                        free(device->addr);
     602                        free(device->addr_data);
     603                        arp_protos_destroy(&device->protos, free);
     604                        free(device);
     605                        return rc;
     606                }
     607               
     608                rc = arp_cache_add(&arp_globals.cache, device->device_id,
     609                    device);
     610                if (rc != EOK) {
     611                        fibril_mutex_unlock(&arp_globals.lock);
     612                        free(device->addr);
     613                        free(device->addr_data);
     614                        free(device->broadcast_addr);
     615                        free(device->broadcast_data);
     616                        arp_protos_destroy(&device->protos, free);
     617                        free(device);
     618                        return rc;
     619                }
     620                printf("%s: Device registered (id: %d, type: 0x%x, service: %d,"
     621                    " proto: %d)\n", NAME, device->device_id, device->hardware,
     622                    device->service, protocol);
     623        }
     624       
     625        fibril_mutex_unlock(&arp_globals.lock);
     626        return EOK;
     627}
     628
     629int il_initialize(int net_phone)
     630{
     631        fibril_mutex_initialize(&arp_globals.lock);
     632       
     633        fibril_mutex_lock(&arp_globals.lock);
     634        arp_globals.net_phone = net_phone;
     635        int rc = arp_cache_initialize(&arp_globals.cache);
     636        fibril_mutex_unlock(&arp_globals.lock);
     637       
     638        return rc;
     639}
     640
     641static int arp_send_request(device_id_t device_id, services_t protocol,
     642    measured_string_t *target, arp_device_t *device, arp_proto_t *proto)
     643{
     644        /* ARP packet content size = header + (address + translation) * 2 */
     645        size_t length = 8 + 2 * (proto->addr->length + device->addr->length);
    538646        if (length > device->packet_dimension.content)
    539                 return NULL;
    540 
    541         packet = packet_get_4_remote(arp_globals.net_phone,
     647                return ELIMIT;
     648       
     649        packet_t *packet = packet_get_4_remote(arp_globals.net_phone,
    542650            device->packet_dimension.addr_len, device->packet_dimension.prefix,
    543651            length, device->packet_dimension.suffix);
    544652        if (!packet)
    545                 return NULL;
    546 
    547         header = (arp_header_ref) packet_suffix(packet, length);
     653                return ENOMEM;
     654       
     655        arp_header_t *header = (arp_header_t *) packet_suffix(packet, length);
    548656        if (!header) {
    549657                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    550                 return NULL;
    551         }
    552 
     658                return ENOMEM;
     659        }
     660       
    553661        header->hardware = htons(device->hardware);
    554662        header->hardware_length = (uint8_t) device->addr->length;
     
    556664        header->protocol_length = (uint8_t) proto->addr->length;
    557665        header->operation = htons(ARPOP_REQUEST);
     666       
    558667        length = sizeof(arp_header_t);
     668       
    559669        memcpy(((uint8_t *) header) + length, device->addr->value,
    560670            device->addr->length);
     
    566676        length += device->addr->length;
    567677        memcpy(((uint8_t *) header) + length, target->value, target->length);
    568 
    569         if (packet_set_addr(packet, (uint8_t *) device->addr->value,
    570             (uint8_t *) device->broadcast_addr->value,
    571             CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK) {
     678       
     679        int rc = packet_set_addr(packet, (uint8_t *) device->addr->value,
     680            (uint8_t *) device->broadcast_addr->value, device->addr->length);
     681        if (rc != EOK) {
    572682                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    573                 return NULL;
    574         }
    575 
     683                return rc;
     684        }
     685       
    576686        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    577         return NULL;
    578 }
    579 
    580 
    581 /** Processes the ARP message.
    582  *
    583  * @param[in] callid    The message identifier.
    584  * @param[in] call      The message parameters.
    585  * @param[out] answer   The message answer parameters.
    586  * @param[out] answer_count The last parameter for the actual answer in the
    587  *                      answer parameter.
    588  * @returns             EOK on success.
    589  * @returns             ENOTSUP if the message is not known.
     687        return EOK;
     688}
     689
     690/** Return the hardware address for the given protocol address.
     691 *
     692 * Send the ARP request packet if the hardware address is not found in the
     693 * cache.
     694 *
     695 * @param[in]  device_id   Device identifier.
     696 * @param[in]  protocol    Protocol service.
     697 * @param[in]  target      Target protocol address.
     698 * @param[out] translation Where the hardware address of the target is stored.
     699 *
     700 * @return EOK on success.
     701 * @return EAGAIN if the caller should try again.
     702 * @return Other error codes in case of error.
     703 *
     704 */
     705static int arp_translate_message(device_id_t device_id, services_t protocol,
     706    measured_string_t *target, measured_string_t **translation)
     707{
     708        bool retry = false;
     709        int rc;
     710
     711        assert(fibril_mutex_is_locked(&arp_globals.lock));
     712       
     713restart:
     714        if ((!target) || (!translation))
     715                return EBADMEM;
     716       
     717        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     718        if (!device)
     719                return ENOENT;
     720       
     721        arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
     722        if ((!proto) || (proto->addr->length != target->length))
     723                return ENOENT;
     724       
     725        arp_trans_t *trans = arp_addr_find(&proto->addresses, target->value,
     726            target->length);
     727        if (trans) {
     728                if (trans->hw_addr) {
     729                        /* The translation is in place. */
     730                        *translation = trans->hw_addr;
     731                        return EOK;
     732                }
     733               
     734                if (retry) {
     735                        /*
     736                         * We may get here as a result of being signalled for
     737                         * some reason while waiting for the translation (e.g.
     738                         * translation becoming available, record being removed
     739                         * from the table) and then losing the race for
     740                         * the arp_globals.lock with someone else who modified
     741                         * the table.
     742                         *
     743                         * Remove the incomplete record so that it is possible
     744                         * to make new ARP requests.
     745                         */
     746                        arp_clear_trans(trans);
     747                        arp_addr_exclude(&proto->addresses, target->value,
     748                            target->length, free);
     749                        return EAGAIN;
     750                }
     751               
     752                /*
     753                 * We are a random passer-by who merely joins an already waiting
     754                 * fibril in waiting for the translation.
     755                 */
     756                rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
     757                    ARP_TRANS_WAIT);
     758                if (rc == ETIMEOUT)
     759                        return ENOENT;
     760               
     761                /*
     762                 * Need to recheck because we did not hold the lock while
     763                 * sleeping on the condition variable.
     764                 */
     765                retry = true;
     766                goto restart;
     767        }
     768       
     769        if (retry)
     770                return EAGAIN;
     771
     772        /*
     773         * We are under the protection of arp_globals.lock, so we can afford to
     774         * first send the ARP request and then insert an incomplete ARP record.
     775         * The incomplete record is used to tell any other potential waiter
     776         * that this fibril has already sent the request and that it is waiting
     777         * for the answer. Lastly, any fibril which sees the incomplete request
     778         * can perform a timed wait on its condition variable to wait for the
     779         * ARP reply to arrive.
     780         */
     781
     782        rc = arp_send_request(device_id, protocol, target, device, proto);
     783        if (rc != EOK)
     784                return rc;
     785       
     786        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
     787        if (!trans)
     788                return ENOMEM;
     789       
     790        trans->hw_addr = NULL;
     791        fibril_condvar_initialize(&trans->cv);
     792       
     793        rc = arp_addr_add(&proto->addresses, target->value, target->length,
     794            trans);
     795        if (rc != EOK) {
     796                free(trans);
     797                return rc;
     798        }
     799       
     800        rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
     801            ARP_TRANS_WAIT);
     802        if (rc == ETIMEOUT) {
     803                /*
     804                 * Remove the incomplete record so that it is possible to make
     805                 * new ARP requests.
     806                 */
     807                arp_clear_trans(trans);
     808                arp_addr_exclude(&proto->addresses, target->value,
     809                    target->length, free);
     810                return ENOENT;
     811        }
     812       
     813        /*
     814         * We need to recheck that the translation has indeed become available,
     815         * because we dropped the arp_globals.lock while sleeping on the
     816         * condition variable and someone else might have e.g. removed the
     817         * translation before we managed to lock arp_globals.lock again.
     818         */
     819
     820        retry = true;
     821        goto restart;
     822}
     823
     824/** Process the ARP message.
     825 *
     826 * @param[in]  callid Message identifier.
     827 * @param[in]  call   Message parameters.
     828 * @param[out] answer Answer.
     829 * @param[out] count  Number of arguments of the answer.
     830 *
     831 * @return EOK on success.
     832 * @return ENOTSUP if the message is not known.
    590833 *
    591834 * @see arp_interface.h
    592835 * @see IS_NET_ARP_MESSAGE()
    593  */
    594 int
    595 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    596     ipc_call_t *answer, int *answer_count)
    597 {
    598         ERROR_DECLARE;
    599        
    600         measured_string_ref address;
    601         measured_string_ref translation;
    602         char *data;
    603         packet_t packet;
    604         packet_t next;
    605        
    606         *answer_count = 0;
    607         switch (IPC_GET_METHOD(*call)) {
     836 *
     837 */
     838int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     839    size_t *count)
     840{
     841        measured_string_t *address;
     842        measured_string_t *translation;
     843        uint8_t *data;
     844        int rc;
     845       
     846        *count = 0;
     847        switch (IPC_GET_IMETHOD(*call)) {
    608848        case IPC_M_PHONE_HUNGUP:
    609849                return EOK;
    610850       
    611851        case NET_ARP_DEVICE:
    612                 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    613                 if (ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call),
    614                     IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))) {
     852                rc = measured_strings_receive(&address, &data, 1);
     853                if (rc != EOK)
     854                        return rc;
     855               
     856                rc = arp_device_message(IPC_GET_DEVICE(*call),
     857                    IPC_GET_SERVICE(*call), ARP_GET_NETIF(*call), address);
     858                if (rc != EOK) {
    615859                        free(address);
    616860                        free(data);
    617861                }
    618                 return ERROR_CODE;
     862               
     863                return rc;
    619864       
    620865        case NET_ARP_TRANSLATE:
    621                 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    622                 fibril_rwlock_read_lock(&arp_globals.lock);
    623                 translation = arp_translate_message(IPC_GET_DEVICE(call),
    624                     IPC_GET_SERVICE(call), address);
     866                rc = measured_strings_receive(&address, &data, 1);
     867                if (rc != EOK)
     868                        return rc;
     869               
     870                fibril_mutex_lock(&arp_globals.lock);
     871                rc = arp_translate_message(IPC_GET_DEVICE(*call),
     872                    IPC_GET_SERVICE(*call), address, &translation);
    625873                free(address);
    626874                free(data);
     875               
     876                if (rc != EOK) {
     877                        fibril_mutex_unlock(&arp_globals.lock);
     878                        return rc;
     879                }
     880               
    627881                if (!translation) {
    628                         fibril_rwlock_read_unlock(&arp_globals.lock);
     882                        fibril_mutex_unlock(&arp_globals.lock);
    629883                        return ENOENT;
    630884                }
    631                 ERROR_CODE = measured_strings_reply(translation, 1);
    632                 fibril_rwlock_read_unlock(&arp_globals.lock);
    633                 return ERROR_CODE;
    634 
     885               
     886                rc = measured_strings_reply(translation, 1);
     887                fibril_mutex_unlock(&arp_globals.lock);
     888                return rc;
     889       
    635890        case NET_ARP_CLEAR_DEVICE:
    636                 return arp_clear_device_req(0, IPC_GET_DEVICE(call));
    637 
     891                return arp_clear_device_req(0, IPC_GET_DEVICE(*call));
     892       
    638893        case NET_ARP_CLEAR_ADDRESS:
    639                 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    640                 arp_clear_address_req(0, IPC_GET_DEVICE(call),
    641                     IPC_GET_SERVICE(call), address);
     894                rc = measured_strings_receive(&address, &data, 1);
     895                if (rc != EOK)
     896                        return rc;
     897               
     898                arp_clear_address_req(0, IPC_GET_DEVICE(*call),
     899                    IPC_GET_SERVICE(*call), address);
    642900                free(address);
    643901                free(data);
     
    646904        case NET_ARP_CLEAN_CACHE:
    647905                return arp_clean_cache_req(0);
    648        
    649         case NET_IL_DEVICE_STATE:
    650                 // do nothing - keep the cache
    651                 return EOK;
    652        
    653         case NET_IL_RECEIVED:
    654                 if (ERROR_NONE(packet_translate_remote(arp_globals.net_phone,
    655                     &packet, IPC_GET_PACKET(call)))) {
    656                         fibril_rwlock_read_lock(&arp_globals.lock);
    657                         do {
    658                                 next = pq_detach(packet);
    659                                 ERROR_CODE =
    660                                     arp_receive_message(IPC_GET_DEVICE(call),
    661                                     packet);
    662                                 if (ERROR_CODE != 1) {
    663                                         pq_release_remote(arp_globals.net_phone,
    664                                             packet_get_id(packet));
    665                                 }
    666                                 packet = next;
    667                         } while (packet);
    668                         fibril_rwlock_read_unlock(&arp_globals.lock);
    669                 }
    670                 return ERROR_CODE;
    671        
    672         case NET_IL_MTU_CHANGED:
    673                 return arp_mtu_changed_message(IPC_GET_DEVICE(call),
    674                     IPC_GET_MTU(call));
    675906        }
    676907       
     
    678909}
    679910
    680 /** Default thread for new connections.
    681  *
    682  * @param[in] iid       The initial message identifier.
    683  * @param[in] icall     The initial message call structure.
    684  */
    685 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    686 {
    687         /*
    688          * Accept the connection
    689          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    690          */
    691         ipc_answer_0(iid, EOK);
    692        
    693         while (true) {
    694                 ipc_call_t answer;
    695                 int answer_count;
    696                
    697                 /* Clear the answer structure */
    698                 refresh_answer(&answer, &answer_count);
    699                
    700                 /* Fetch the next message */
    701                 ipc_call_t call;
    702                 ipc_callid_t callid = async_get_call(&call);
    703                
    704                 /* Process the message */
    705                 int res = il_module_message_standalone(callid, &call, &answer,
    706                     &answer_count);
    707                
    708                 /*
    709                  * End if told to either by the message or the processing
    710                  * result.
    711                  */
    712                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
    713                     (res == EHANGUP))
    714                         return;
    715                
    716                 /* Answer the message */
    717                 answer_call(callid, res, &answer, answer_count);
    718         }
    719 }
    720 
    721 /** Starts the module.
    722  *
    723  * @returns             EOK on success.
    724  * @returns             Other error codes as defined for each specific module
    725  *                      start function.
    726  */
    727911int main(int argc, char *argv[])
    728912{
    729         ERROR_DECLARE;
    730        
    731913        /* Start the module */
    732         ERROR_PROPAGATE(il_module_start_standalone(il_client_connection));
    733         return EOK;
     914        return il_module_start(SERVICE_ARP);
    734915}
    735916
    736917/** @}
    737918 */
    738 
Note: See TracChangeset for help on using the changeset viewer.