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

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

Fix packet_get_copy() and socket_destroy_core() to use the remote packet
interfaces.

Fix packet_client.h to declare the remote packet interfaces and create
packet_local.h for the use by the packet server (or later possibly also by the
bundle build).

  • 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_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.