source: mainline/uspace/srv/net/il/arp/arp.c@ d52fbaf

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d52fbaf was c7a8442, checked in by Jakub Jermar <jakub@…>, 15 years ago

Move net_modules.[ch] to the standard library. Note that this functionality is
not directly related to networking so the next step regarding these two files
would be to somehow merge its functionality with what we already have in lib c.

  • Property mode set to 100644
File size: 21.6 KB
Line 
1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup arp
30 * @{
31 */
32
33/** @file
34 * ARP module implementation.
35 * @see arp.h
36 */
37
38#include <async.h>
39#include <malloc.h>
40#include <mem.h>
41#include <fibril_synch.h>
42#include <stdio.h>
43#include <str.h>
44#include <task.h>
45#include <ipc/ipc.h>
46#include <ipc/services.h>
47#include <byteorder.h>
48#include <err.h>
49
50#include <net_messages.h>
51#include <net/modules.h>
52#include <net_device.h>
53#include <arp_interface.h>
54#include <nil_interface.h>
55#include <protocol_map.h>
56#include <adt/measured_strings.h>
57#include <packet/packet.h>
58#include <packet/packet_client.h>
59#include <packet_remote.h>
60#include <il_messages.h>
61#include <il_interface.h>
62#include <il_local.h>
63#include <arp_messages.h>
64
65#include "arp.h"
66#include "arp_header.h"
67#include "arp_oc.h"
68#include "arp_module.h"
69
70
71/** ARP module name.
72 */
73#define NAME "arp"
74
75/** ARP global data.
76 */
77arp_globals_t arp_globals;
78
79/** Clears the device specific data.
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){
156 int count;
157 arp_device_ref device;
158
159 fibril_rwlock_write_lock(&arp_globals.lock);
160 for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){
161 device = arp_cache_get_index(&arp_globals.cache, count);
162 if(device){
163 arp_clear_device(device);
164 if(device->addr_data){
165 free(device->addr_data);
166 }
167 if(device->broadcast_data){
168 free(device->broadcast_data);
169 }
170 }
171 }
172 arp_cache_clear(&arp_globals.cache);
173 fibril_rwlock_write_unlock(&arp_globals.lock);
174 printf("Cache cleaned\n");
175 return EOK;
176}
177
178int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){
179 arp_device_ref device;
180 arp_proto_ref proto;
181
182 fibril_rwlock_write_lock(&arp_globals.lock);
183 device = arp_cache_find(&arp_globals.cache, device_id);
184 if(! device){
185 fibril_rwlock_write_unlock(&arp_globals.lock);
186 return ENOENT;
187 }
188 proto = arp_protos_find(&device->protos, protocol);
189 if(! proto){
190 fibril_rwlock_write_unlock(&arp_globals.lock);
191 return ENOENT;
192 }
193 arp_addr_exclude(&proto->addresses, address->value, address->length);
194 fibril_rwlock_write_unlock(&arp_globals.lock);
195 return EOK;
196}
197
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){
218 arp_device_ref device;
219
220 fibril_rwlock_write_lock(&arp_globals.lock);
221 device = arp_cache_find(&arp_globals.cache, device_id);
222 if(! device){
223 fibril_rwlock_write_unlock(&arp_globals.lock);
224 return ENOENT;
225 }
226 arp_clear_device(device);
227 printf("Device %d cleared\n", device_id);
228 fibril_rwlock_write_unlock(&arp_globals.lock);
229 return EOK;
230}
231
232int arp_connect_module(services_t service){
233 if(service != SERVICE_ARP){
234 return EINVAL;
235 }
236 return EOK;
237}
238
239int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){
240 ERROR_DECLARE;
241
242 arp_device_ref device;
243 arp_proto_ref proto;
244 int index;
245 hw_type_t hardware;
246
247 fibril_rwlock_write_lock(&arp_globals.lock);
248 // an existing device?
249 device = arp_cache_find(&arp_globals.cache, device_id);
250 if(device){
251 if(device->service != service){
252 printf("Device %d already exists\n", device->device_id);
253 fibril_rwlock_write_unlock(&arp_globals.lock);
254 return EEXIST;
255 }
256 proto = arp_protos_find(&device->protos, protocol);
257 if(proto){
258 free(proto->addr);
259 free(proto->addr_data);
260 proto->addr = address;
261 proto->addr_data = address->value;
262 }else{
263 if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
264 fibril_rwlock_write_unlock(&arp_globals.lock);
265 return ERROR_CODE;
266 }
267 index = arp_protos_add(&device->protos, proto->service, proto);
268 if(index < 0){
269 fibril_rwlock_write_unlock(&arp_globals.lock);
270 free(proto);
271 return index;
272 }
273 printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol);
274 }
275 }else{
276 hardware = hardware_map(service);
277 if(! hardware){
278 return ENOENT;
279 }
280 // create a new device
281 device = (arp_device_ref) malloc(sizeof(arp_device_t));
282 if(! device){
283 fibril_rwlock_write_unlock(&arp_globals.lock);
284 return ENOMEM;
285 }
286 device->hardware = hardware;
287 device->device_id = device_id;
288 if(ERROR_OCCURRED(arp_protos_initialize(&device->protos))
289 || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){
290 fibril_rwlock_write_unlock(&arp_globals.lock);
291 free(device);
292 return ERROR_CODE;
293 }
294 index = arp_protos_add(&device->protos, proto->service, proto);
295 if(index < 0){
296 fibril_rwlock_write_unlock(&arp_globals.lock);
297 arp_protos_destroy(&device->protos);
298 free(device);
299 return index;
300 }
301 device->service = service;
302 // bind the new one
303 device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection);
304 if(device->phone < 0){
305 fibril_rwlock_write_unlock(&arp_globals.lock);
306 arp_protos_destroy(&device->protos);
307 free(device);
308 return EREFUSED;
309 }
310 // get packet dimensions
311 if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){
312 fibril_rwlock_write_unlock(&arp_globals.lock);
313 arp_protos_destroy(&device->protos);
314 free(device);
315 return ERROR_CODE;
316 }
317 // get hardware address
318 if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){
319 fibril_rwlock_write_unlock(&arp_globals.lock);
320 arp_protos_destroy(&device->protos);
321 free(device);
322 return ERROR_CODE;
323 }
324 // get broadcast address
325 if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){
326 fibril_rwlock_write_unlock(&arp_globals.lock);
327 free(device->addr);
328 free(device->addr_data);
329 arp_protos_destroy(&device->protos);
330 free(device);
331 return ERROR_CODE;
332 }
333 if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){
334 fibril_rwlock_write_unlock(&arp_globals.lock);
335 free(device->addr);
336 free(device->addr_data);
337 free(device->broadcast_addr);
338 free(device->broadcast_data);
339 arp_protos_destroy(&device->protos);
340 free(device);
341 return ERROR_CODE;
342 }
343 printf("%s: Device registered (id: %d, type: 0x%x, service: %d, proto: %d)\n",
344 NAME, device->device_id, device->hardware, device->service, protocol);
345 }
346 fibril_rwlock_write_unlock(&arp_globals.lock);
347 return EOK;
348}
349
350int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
351 ERROR_DECLARE;
352
353 measured_string_ref tmp;
354
355 // copy the given address for exclusive use
356 tmp = measured_string_copy(address);
357 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){
358 free(tmp->value);
359 free(tmp);
360 }
361 return ERROR_CODE;
362}
363
364int arp_initialize(async_client_conn_t client_connection){
365 ERROR_DECLARE;
366
367 fibril_rwlock_initialize(&arp_globals.lock);
368 fibril_rwlock_write_lock(&arp_globals.lock);
369 arp_globals.client_connection = client_connection;
370 ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
371 fibril_rwlock_write_unlock(&arp_globals.lock);
372 return EOK;
373}
374
375int arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
376 ipc_call_t *answer, int *answer_count)
377{
378 ERROR_DECLARE;
379
380 measured_string_ref address;
381 measured_string_ref translation;
382 char * data;
383 packet_t packet;
384 packet_t next;
385
386 *answer_count = 0;
387 switch (IPC_GET_METHOD(*call)) {
388 case IPC_M_PHONE_HUNGUP:
389 return EOK;
390 case NET_ARP_DEVICE:
391 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
392 if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){
393 free(address);
394 free(data);
395 }
396 return ERROR_CODE;
397 case NET_ARP_TRANSLATE:
398 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
399 fibril_rwlock_read_lock(&arp_globals.lock);
400 translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
401 free(address);
402 free(data);
403 if(! translation){
404 fibril_rwlock_read_unlock(&arp_globals.lock);
405 return ENOENT;
406 }
407 ERROR_CODE = measured_strings_reply(translation, 1);
408 fibril_rwlock_read_unlock(&arp_globals.lock);
409 return ERROR_CODE;
410 case NET_ARP_CLEAR_DEVICE:
411 return arp_clear_device_req(0, IPC_GET_DEVICE(call));
412 case NET_ARP_CLEAR_ADDRESS:
413 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
414 arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address);
415 free(address);
416 free(data);
417 return EOK;
418 case NET_ARP_CLEAN_CACHE:
419 return arp_clean_cache_req(0);
420 case NET_IL_DEVICE_STATE:
421 // do nothing - keep the cache
422 return EOK;
423 case NET_IL_RECEIVED:
424 if(! ERROR_OCCURRED(packet_translate_remote(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
425 fibril_rwlock_read_lock(&arp_globals.lock);
426 do{
427 next = pq_detach(packet);
428 ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet);
429 if(ERROR_CODE != 1){
430 pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
431 }
432 packet = next;
433 }while(packet);
434 fibril_rwlock_read_unlock(&arp_globals.lock);
435 }
436 return ERROR_CODE;
437 case NET_IL_MTU_CHANGED:
438 return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call));
439 }
440
441 return ENOTSUP;
442}
443
444int arp_mtu_changed_message(device_id_t device_id, size_t mtu){
445 arp_device_ref device;
446
447 fibril_rwlock_write_lock(&arp_globals.lock);
448 device = arp_cache_find(&arp_globals.cache, device_id);
449 if(! device){
450 fibril_rwlock_write_unlock(&arp_globals.lock);
451 return ENOENT;
452 }
453 device->packet_dimension.content = mtu;
454 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu);
455 fibril_rwlock_write_unlock(&arp_globals.lock);
456 return EOK;
457}
458
459int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){
460 ERROR_DECLARE;
461
462 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
463 if(!(*proto)){
464 return ENOMEM;
465 }
466 (** proto).service = service;
467 (** proto).addr = address;
468 (** proto).addr_data = address->value;
469 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){
470 free(*proto);
471 return ERROR_CODE;
472 }
473 return EOK;
474}
475
476int arp_receive_message(device_id_t device_id, packet_t packet){
477 ERROR_DECLARE;
478
479 size_t length;
480 arp_header_ref header;
481 arp_device_ref device;
482 arp_proto_ref proto;
483 measured_string_ref hw_source;
484 uint8_t * src_hw;
485 uint8_t * src_proto;
486 uint8_t * des_hw;
487 uint8_t * des_proto;
488
489 length = packet_get_data_length(packet);
490 if(length <= sizeof(arp_header_t)){
491 return EINVAL;
492 }
493 device = arp_cache_find(&arp_globals.cache, device_id);
494 if(! device){
495 return ENOENT;
496 }
497 header = (arp_header_ref) packet_get_data(packet);
498 if((ntohs(header->hardware) != device->hardware)
499 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){
500 return EINVAL;
501 }
502 proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol)));
503 if(! proto){
504 return ENOENT;
505 }
506 src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
507 src_proto = src_hw + header->hardware_length;
508 des_hw = src_proto + header->protocol_length;
509 des_proto = des_hw + header->hardware_length;
510 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length));
511 // exists?
512 if(hw_source){
513 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){
514 return EINVAL;
515 }
516 memcpy(hw_source->value, src_hw, hw_source->length);
517 }
518 // is my protocol address?
519 if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){
520 return EINVAL;
521 }
522 if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){
523 // not already upadted?
524 if(! hw_source){
525 hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length));
526 if(! hw_source){
527 return ENOMEM;
528 }
529 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source));
530 }
531 if(ntohs(header->operation) == ARPOP_REQUEST){
532 header->operation = htons(ARPOP_REPLY);
533 memcpy(des_proto, src_proto, header->protocol_length);
534 memcpy(src_proto, proto->addr->value, header->protocol_length);
535 memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len);
536 memcpy(des_hw, hw_source->value, header->hardware_length);
537 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length));
538 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
539 return 1;
540 }
541 }
542 return EOK;
543}
544
545task_id_t arp_task_get_id(void){
546 return task_get_id();
547}
548
549measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){
550 arp_device_ref device;
551 arp_proto_ref proto;
552 measured_string_ref addr;
553 size_t length;
554 packet_t packet;
555 arp_header_ref header;
556
557 if(! target){
558 return NULL;
559 }
560 device = arp_cache_find(&arp_globals.cache, device_id);
561 if(! device){
562 return NULL;
563 }
564 proto = arp_protos_find(&device->protos, protocol);
565 if((! proto) || (proto->addr->length != target->length)){
566 return NULL;
567 }
568 addr = arp_addr_find(&proto->addresses, target->value, target->length);
569 if(addr){
570 return addr;
571 }
572 // ARP packet content size = header + (address + translation) * 2
573 length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2;
574 if(length > device->packet_dimension.content){
575 return NULL;
576 }
577 packet = packet_get_4_remote(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
578 if(! packet){
579 return NULL;
580 }
581 header = (arp_header_ref) packet_suffix(packet, length);
582 if(! header){
583 pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
584 return NULL;
585 }
586 header->hardware = htons(device->hardware);
587 header->hardware_length = (uint8_t) device->addr->length;
588 header->protocol = htons(protocol_map(device->service, protocol));
589 header->protocol_length = (uint8_t) proto->addr->length;
590 header->operation = htons(ARPOP_REQUEST);
591 length = sizeof(arp_header_t);
592 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length);
593 length += device->addr->length;
594 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length);
595 length += proto->addr->length;
596 bzero(((uint8_t *) header) + length, device->addr->length);
597 length += device->addr->length;
598 memcpy(((uint8_t *) header) + length, target->value, target->length);
599 if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){
600 pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
601 return NULL;
602 }
603 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
604 return NULL;
605}
606
607int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){
608 measured_string_ref tmp;
609
610 fibril_rwlock_read_lock(&arp_globals.lock);
611 tmp = arp_translate_message(device_id, protocol, address);
612 if(tmp){
613 *translation = measured_string_copy(tmp);
614 fibril_rwlock_read_unlock(&arp_globals.lock);
615 if(*translation){
616 *data = (** translation).value;
617 return EOK;
618 }else{
619 return ENOMEM;
620 }
621 }else{
622 fibril_rwlock_read_unlock(&arp_globals.lock);
623 return ENOENT;
624 }
625}
626
627/** Default thread for new connections.
628 *
629 * @param[in] iid The initial message identifier.
630 * @param[in] icall The initial message call structure.
631 *
632 */
633static void il_client_connection(ipc_callid_t iid, ipc_call_t * icall)
634{
635 /*
636 * Accept the connection
637 * - Answer the first IPC_M_CONNECT_ME_TO call.
638 */
639 ipc_answer_0(iid, EOK);
640
641 while(true) {
642 ipc_call_t answer;
643 int answer_count;
644
645 /* Clear the answer structure */
646 refresh_answer(&answer, &answer_count);
647
648 /* Fetch the next message */
649 ipc_call_t call;
650 ipc_callid_t callid = async_get_call(&call);
651
652 /* Process the message */
653 int res = il_module_message_standalone(callid, &call, &answer,
654 &answer_count);
655
656 /* End if said to either by the message or the processing result */
657 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
658 return;
659
660 /* Answer the message */
661 answer_call(callid, res, &answer, answer_count);
662 }
663}
664
665/** Starts the module.
666 *
667 * @param argc The count of the command line arguments. Ignored parameter.
668 * @param argv The command line parameters. Ignored parameter.
669 *
670 * @returns EOK on success.
671 * @returns Other error codes as defined for each specific module start function.
672 *
673 */
674int main(int argc, char *argv[])
675{
676 ERROR_DECLARE;
677
678 /* Start the module */
679 if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection)))
680 return ERROR_CODE;
681
682 return EOK;
683}
684
685/** @}
686 */
Note: See TracBrowser for help on using the repository browser.