Changeset 89c57b6 in mainline for uspace/srv/net/il/arp/arp.c
- Timestamp:
- 2011-04-13T14:45:41Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 88634420
- Parents:
- cefb126 (diff), 17279ead (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/arp/arp.c
rcefb126 r89c57b6 28 28 29 29 /** @addtogroup arp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * ARP module implementation. 35 * @see arp.h 36 36 */ 37 37 … … 40 40 #include <mem.h> 41 41 #include <fibril_synch.h> 42 #include <assert.h> 42 43 #include <stdio.h> 43 44 #include <str.h> 44 45 #include <task.h> 45 #include < ipc/ipc.h>46 #include <adt/measured_strings.h> 46 47 #include <ipc/services.h> 47 48 #include <net_err.h> 49 #include <net_messages.h> 50 #include <net_modules.h> 51 #include <net_byteorder.h> 52 #include <net_device.h> 53 #include <arp_interface.h> 54 #include <nil_interface.h> 48 #include <ipc/net.h> 49 #include <ipc/arp.h> 50 #include <ipc/il.h> 51 #include <ipc/nil.h> 52 #include <byteorder.h> 53 #include <errno.h> 54 #include <net/modules.h> 55 #include <net/device.h> 56 #include <net/packet.h> 57 #include <nil_remote.h> 55 58 #include <protocol_map.h> 56 #include <adt/measured_strings.h> 57 #include <packet/packet.h> 58 #include <packet/packet_client.h> 59 #include <packet_client.h> 59 60 #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 61 #include <il_remote.h> 62 #include <il_skel.h> 65 63 #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 */ 64 65 /** ARP module name. */ 73 66 #define NAME "arp" 74 67 75 /** ARP global data. 76 */ 77 arp_globals_t arp_globals; 78 79 /** Clears the device specific data. 80 * @param[in] device The device specific data. 81 */ 82 void arp_clear_device(arp_device_ref device); 83 84 /** Creates new protocol specific data. 85 * Allocates and returns the needed memory block as the proto parameter. 86 * @param[out] proto The allocated protocol specific data. 87 * @param[in] service The protocol module service. 88 * @param[in] address The actual protocol device address. 89 * @returns EOK on success. 90 * @returns ENOMEM if there is not enough memory left. 91 */ 92 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address); 93 94 /** @name Message processing functions 95 */ 68 /** Number of microseconds to wait for an ARP reply. */ 69 #define ARP_TRANS_WAIT 1000000 70 71 /** @name ARP operation codes definitions */ 96 72 /*@{*/ 97 73 98 /** Registers the device. 99 * Creates new device entry in the cache or updates the protocol address if the device with the device identifier and the driver service exists. 100 * @param[in] device_id The device identifier. 101 * @param[in] service The device driver service. 102 * @param[in] protocol The protocol service. 103 * @param[in] address The actual device protocol address. 104 * @returns EOK on success. 105 * @returns EEXIST if another device with the same device identifier and different driver service exists. 106 * @returns ENOMEM if there is not enough memory left. 107 * @returns Other error codes as defined for the measured_strings_return() function. 108 */ 109 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address); 110 111 /** Updates the device content length according to the new MTU value. 112 * @param[in] device_id The device identifier. 113 * @param[in] mtu The new mtu value. 114 * @returns ENOENT if device is not found. 115 * @returns EOK on success. 116 */ 117 int arp_mtu_changed_message(device_id_t device_id, size_t mtu); 118 119 /** Processes the received ARP packet. 120 * Updates the source hardware address if the source entry exists or the packet is targeted to my protocol address. 121 * Responses to the ARP request if the packet is the ARP request and is targeted to my address. 122 * @param[in] device_id The source device identifier. 123 * @param[in,out] packet The received packet. 124 * @returns EOK on success and the packet is no longer needed. 125 * @returns 1 on success and the packet has been reused. 126 * @returns EINVAL if the packet is too small to carry an ARP packet. 127 * @returns EINVAL if the received address lengths differs from the registered values. 128 * @returns ENOENT if the device is not found in the cache. 129 * @returns ENOENT if the protocol for the device is not found in the cache. 130 * @returns ENOMEM if there is not enough memory left. 131 */ 132 int arp_receive_message(device_id_t device_id, packet_t packet); 133 134 /** Returns the hardware address for the given protocol address. 135 * Sends the ARP request packet if the hardware address is not found in the cache. 136 * @param[in] device_id The device identifier. 137 * @param[in] protocol The protocol service. 138 * @param[in] target The target protocol address. 139 * @returns The hardware address of the target. 140 * @returns NULL if the target parameter is NULL. 141 * @returns NULL if the device is not found. 142 * @returns NULL if the device packet is too small to send a request. 143 * @returns NULL if the hardware address is not found in the cache. 144 */ 145 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target); 74 /** REQUEST operation code. */ 75 #define ARPOP_REQUEST 1 76 77 /** REPLY operation code. */ 78 #define ARPOP_REPLY 2 146 79 147 80 /*@}*/ 148 81 149 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t) 150 151 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t) 152 153 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t) 154 155 int arp_clean_cache_req(int arp_phone){ 82 /** Type definition of an ARP protocol header. 83 * @see arp_header 84 */ 85 typedef struct arp_header arp_header_t; 86 87 /** ARP protocol header. */ 88 struct 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 109 /** ARP global data. */ 110 arp_globals_t arp_globals; 111 112 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t); 113 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t); 114 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, arp_trans_t); 115 116 static 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 126 static void arp_clear_addr(arp_addr_t *addresses) 127 { 156 128 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){ 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 */ 142 static void arp_clear_device(arp_device_t *device) 143 { 144 int count; 145 146 for (count = arp_protos_count(&device->protos) - 1; count >= 0; 147 count--) { 148 arp_proto_t *proto = arp_protos_get_index(&device->protos, 149 count); 150 151 if (proto) { 152 if (proto->addr) 153 free(proto->addr); 154 155 if (proto->addr_data) 156 free(proto->addr_data); 157 158 arp_clear_addr(&proto->addresses); 159 arp_addr_destroy(&proto->addresses, free); 160 } 161 } 162 163 arp_protos_clear(&device->protos, free); 164 } 165 166 static int arp_clean_cache_req(int arp_phone) 167 { 168 int count; 169 170 fibril_mutex_lock(&arp_globals.lock); 171 for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; 172 count--) { 173 arp_device_t *device = arp_cache_get_index(&arp_globals.cache, 174 count); 175 176 if (device) { 163 177 arp_clear_device(device); 164 if (device->addr_data){178 if (device->addr_data) 165 179 free(device->addr_data); 180 181 if (device->broadcast_data) 182 free(device->broadcast_data); 183 } 184 } 185 186 arp_cache_clear(&arp_globals.cache, free); 187 fibril_mutex_unlock(&arp_globals.lock); 188 189 return EOK; 190 } 191 192 static 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); 198 if (!device) { 199 fibril_mutex_unlock(&arp_globals.lock); 200 return ENOENT; 201 } 202 203 arp_proto_t *proto = arp_protos_find(&device->protos, protocol); 204 if (!proto) { 205 fibril_mutex_unlock(&arp_globals.lock); 206 return ENOENT; 207 } 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); 217 return EOK; 218 } 219 220 static int arp_clear_device_req(int arp_phone, device_id_t device_id) 221 { 222 fibril_mutex_lock(&arp_globals.lock); 223 224 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 225 if (!device) { 226 fibril_mutex_unlock(&arp_globals.lock); 227 return ENOENT; 228 } 229 230 arp_clear_device(device); 231 232 fibril_mutex_unlock(&arp_globals.lock); 233 return EOK; 234 } 235 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 */ 248 static 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)); 252 if (!*proto) 253 return ENOMEM; 254 255 (*proto)->service = service; 256 (*proto)->addr = address; 257 (*proto)->addr_data = address->value; 258 259 int rc = arp_addr_initialize(&(*proto)->addresses); 260 if (rc != EOK) { 261 free(*proto); 262 return rc; 263 } 264 265 return EOK; 266 } 267 268 /** Process the received ARP packet. 269 * 270 * Update the source hardware address if the source entry exists or the packet 271 * is targeted to my protocol address. 272 * 273 * Respond to the ARP request if the packet is the ARP request and is 274 * targeted to my address. 275 * 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 */ 291 static 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); 296 if (length <= sizeof(arp_header_t)) 297 return EINVAL; 298 299 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 300 if (!device) 301 return ENOENT; 302 303 arp_header_t *header = (arp_header_t *) packet_get_data(packet); 304 if ((ntohs(header->hardware) != device->hardware) || 305 (length < sizeof(arp_header_t) + header->hardware_length * 2U + 306 header->protocol_length * 2U)) { 307 return EINVAL; 308 } 309 310 arp_proto_t *proto = arp_protos_find(&device->protos, 311 protocol_unmap(device->service, ntohs(header->protocol))); 312 if (!proto) 313 return ENOENT; 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) 326 return EINVAL; 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) 333 return EINVAL; 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) 340 return ENOMEM; 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; 166 349 } 167 if(device->broadcast_data){ 168 free(device->broadcast_data); 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 362 if (ntohs(header->operation) == ARPOP_REQUEST) { 363 header->operation = htons(ARPOP_REPLY); 364 memcpy(des_proto, src_proto, header->protocol_length); 365 memcpy(src_proto, proto->addr->value, 366 header->protocol_length); 367 memcpy(src_hw, device->addr->value, 368 device->packet_dimension.addr_len); 369 memcpy(des_hw, trans->hw_addr->value, 370 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 377 nil_send_msg(device->phone, device_id, packet, 378 SERVICE_ARP); 379 return 1; 380 } 381 } 382 383 return EOK; 384 } 385 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 */ 395 static 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 */ 420 static 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); 169 448 } 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 178 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){ 179 arp_device_ref device; 180 arp_proto_ref proto; 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 198 void arp_clear_device(arp_device_ref device){ 199 int count; 200 arp_proto_ref proto; 201 202 for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){ 203 proto = arp_protos_get_index(&device->protos, count); 204 if(proto){ 205 if(proto->addr){ 206 free(proto->addr); 207 } 208 if(proto->addr_data){ 209 free(proto->addr_data); 210 } 211 arp_addr_destroy(&proto->addresses); 212 } 213 } 214 arp_protos_clear(&device->protos); 215 } 216 217 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 218 arp_device_ref device; 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 232 int arp_connect_module(services_t service){ 233 if(service != SERVICE_ARP){ 234 return EINVAL; 235 } 236 return EOK; 237 } 238 239 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){ 240 ERROR_DECLARE; 241 242 arp_device_ref device; 243 arp_proto_ref proto; 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 */ 484 static int arp_device_message(device_id_t device_id, services_t service, 485 services_t protocol, measured_string_t *address) 486 { 244 487 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); 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); 254 499 return EEXIST; 255 500 } 256 proto = arp_protos_find(&device->protos, protocol); 257 if(proto){ 501 502 arp_proto_t *proto = arp_protos_find(&device->protos, protocol); 503 if (proto) { 258 504 free(proto->addr); 259 505 free(proto->addr_data); 260 506 proto->addr = address; 261 507 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; 508 } else { 509 rc = arp_proto_create(&proto, protocol, address); 510 if (rc != EOK) { 511 fibril_mutex_unlock(&arp_globals.lock); 512 return rc; 266 513 } 267 index = arp_protos_add(&device->protos, proto->service, proto); 268 if(index < 0){ 269 fibril_rwlock_write_unlock(&arp_globals.lock); 514 515 index = arp_protos_add(&device->protos, proto->service, 516 proto); 517 if (index < 0) { 518 fibril_mutex_unlock(&arp_globals.lock); 270 519 free(proto); 271 520 return index; 272 521 } 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){ 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) 278 529 return ENOENT; 279 }280 / / create a new device281 device = (arp_device_ ref) malloc(sizeof(arp_device_t));282 if (! device){283 fibril_ rwlock_write_unlock(&arp_globals.lock);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); 284 535 return ENOMEM; 285 536 } 537 286 538 device->hardware = hardware; 287 539 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);540 rc = arp_protos_initialize(&device->protos); 541 if (rc != EOK) { 542 fibril_mutex_unlock(&arp_globals.lock); 291 543 free(device); 292 return ERROR_CODE; 293 } 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 294 555 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 );556 if (index < 0) { 557 fibril_mutex_unlock(&arp_globals.lock); 558 arp_protos_destroy(&device->protos, free); 298 559 free(device); 299 560 return index; 300 561 } 562 301 563 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); 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); 307 572 free(device); 308 573 return EREFUSED; 309 574 } 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); 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); 314 582 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); 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); 321 592 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); 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); 327 601 free(device->addr); 328 602 free(device->addr_data); 329 arp_protos_destroy(&device->protos );603 arp_protos_destroy(&device->protos, free); 330 604 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); 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); 335 612 free(device->addr); 336 613 free(device->addr_data); 337 614 free(device->broadcast_addr); 338 615 free(device->broadcast_data); 339 arp_protos_destroy(&device->protos );616 arp_protos_destroy(&device->protos, free); 340 617 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); 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); 347 626 return EOK; 348 627 } 349 628 350 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 351 ERROR_DECLARE; 352 353 measured_string_ref tmp; 354 355 // copy the given address for exclusive use 356 tmp = measured_string_copy(address); 357 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){ 358 free(tmp->value); 359 free(tmp); 360 } 361 return ERROR_CODE; 362 } 363 364 int arp_initialize(async_client_conn_t client_connection){ 365 ERROR_DECLARE; 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 375 int arp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 376 ipc_call_t *answer, int *answer_count) 377 { 378 ERROR_DECLARE; 379 380 measured_string_ref address; 381 measured_string_ref translation; 382 char * data; 383 packet_t packet; 384 packet_t next; 385 386 *answer_count = 0; 387 switch (IPC_GET_METHOD(*call)) { 388 case IPC_M_PHONE_HUNGUP: 389 return EOK; 390 case NET_ARP_DEVICE: 391 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 392 if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){ 393 free(address); 394 free(data); 395 } 396 return ERROR_CODE; 397 case NET_ARP_TRANSLATE: 398 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 399 fibril_rwlock_read_lock(&arp_globals.lock); 400 translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 401 free(address); 402 free(data); 403 if(! translation){ 404 fibril_rwlock_read_unlock(&arp_globals.lock); 405 return ENOENT; 406 } 407 ERROR_CODE = measured_strings_reply(translation, 1); 408 fibril_rwlock_read_unlock(&arp_globals.lock); 409 return ERROR_CODE; 410 case NET_ARP_CLEAR_DEVICE: 411 return arp_clear_device_req(0, IPC_GET_DEVICE(call)); 412 case NET_ARP_CLEAR_ADDRESS: 413 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 414 arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 415 free(address); 416 free(data); 417 return EOK; 418 case NET_ARP_CLEAN_CACHE: 419 return arp_clean_cache_req(0); 420 case NET_IL_DEVICE_STATE: 421 // do nothing - keep the cache 422 return EOK; 423 case NET_IL_RECEIVED: 424 if(! ERROR_OCCURRED(packet_translate_remote(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 425 fibril_rwlock_read_lock(&arp_globals.lock); 426 do{ 427 next = pq_detach(packet); 428 ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet); 429 if(ERROR_CODE != 1){ 430 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 431 } 432 packet = next; 433 }while(packet); 434 fibril_rwlock_read_unlock(&arp_globals.lock); 435 } 436 return ERROR_CODE; 437 case NET_IL_MTU_CHANGED: 438 return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call)); 439 } 440 441 return ENOTSUP; 442 } 443 444 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){ 445 arp_device_ref device; 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 459 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){ 460 ERROR_DECLARE; 461 462 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 463 if(!(*proto)){ 629 int 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 641 static 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); 646 if (length > device->packet_dimension.content) 647 return ELIMIT; 648 649 packet_t *packet = packet_get_4_remote(arp_globals.net_phone, 650 device->packet_dimension.addr_len, device->packet_dimension.prefix, 651 length, device->packet_dimension.suffix); 652 if (!packet) 464 653 return ENOMEM; 465 } 466 (** proto).service = service; 467 (** proto).addr = address; 468 (** proto).addr_data = address->value; 469 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){ 470 free(*proto); 471 return ERROR_CODE; 472 } 473 return EOK; 474 } 475 476 int arp_receive_message(device_id_t device_id, packet_t packet){ 477 ERROR_DECLARE; 478 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 545 task_id_t arp_task_get_id(void){ 546 return task_get_id(); 547 } 548 549 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){ 550 arp_device_ref device; 551 arp_proto_ref proto; 552 measured_string_ref addr; 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){ 654 655 arp_header_t *header = (arp_header_t *) packet_suffix(packet, length); 656 if (!header) { 583 657 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 584 return NULL; 585 } 658 return ENOMEM; 659 } 660 586 661 header->hardware = htons(device->hardware); 587 662 header->hardware_length = (uint8_t) device->addr->length; … … 589 664 header->protocol_length = (uint8_t) proto->addr->length; 590 665 header->operation = htons(ARPOP_REQUEST); 666 591 667 length = sizeof(arp_header_t); 592 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length); 668 669 memcpy(((uint8_t *) header) + length, device->addr->value, 670 device->addr->length); 593 671 length += device->addr->length; 594 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length); 672 memcpy(((uint8_t *) header) + length, proto->addr->value, 673 proto->addr->length); 595 674 length += proto->addr->length; 596 675 bzero(((uint8_t *) header) + length, device->addr->length); 597 676 length += device->addr->length; 598 677 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){ 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) { 600 682 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 601 return NULL; 602 } 683 return rc; 684 } 685 603 686 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 604 return NULL; 605 } 606 607 int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){ 608 measured_string_ref tmp; 609 610 fibril_rwlock_read_lock(&arp_globals.lock); 611 tmp = arp_translate_message(device_id, protocol, address); 612 if(tmp){ 613 *translation = measured_string_copy(tmp); 614 fibril_rwlock_read_unlock(&arp_globals.lock); 615 if(*translation){ 616 *data = (** translation).value; 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 */ 705 static 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 713 restart: 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; 617 731 return EOK; 618 }else{ 619 return ENOMEM; 620 } 621 }else{ 622 fibril_rwlock_read_unlock(&arp_globals.lock); 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); 623 810 return ENOENT; 624 811 } 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 */ 633 static void il_client_connection(ipc_callid_t iid, ipc_call_t * icall) 634 { 812 635 813 /* 636 * Accept the connection 637 * - Answer the first IPC_M_CONNECT_ME_TO call. 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. 638 818 */ 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 */ 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. 833 * 834 * @see arp_interface.h 835 * @see IS_NET_ARP_MESSAGE() 836 * 837 */ 838 int 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)) { 848 case IPC_M_PHONE_HUNGUP: 849 return EOK; 850 851 case NET_ARP_DEVICE: 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) { 859 free(address); 860 free(data); 861 } 862 863 return rc; 864 865 case NET_ARP_TRANSLATE: 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); 873 free(address); 874 free(data); 875 876 if (rc != EOK) { 877 fibril_mutex_unlock(&arp_globals.lock); 878 return rc; 879 } 880 881 if (!translation) { 882 fibril_mutex_unlock(&arp_globals.lock); 883 return ENOENT; 884 } 885 886 rc = measured_strings_reply(translation, 1); 887 fibril_mutex_unlock(&arp_globals.lock); 888 return rc; 889 890 case NET_ARP_CLEAR_DEVICE: 891 return arp_clear_device_req(0, IPC_GET_DEVICE(*call)); 892 893 case NET_ARP_CLEAR_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); 900 free(address); 901 free(data); 902 return EOK; 903 904 case NET_ARP_CLEAN_CACHE: 905 return arp_clean_cache_req(0); 906 } 907 908 return ENOTSUP; 909 } 910 674 911 int main(int argc, char *argv[]) 675 912 { 676 ERROR_DECLARE;677 678 913 /* Start the module */ 679 if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection))) 680 return ERROR_CODE; 681 682 return EOK; 914 return il_module_start(SERVICE_ARP); 683 915 } 684 916
Note:
See TracChangeset
for help on using the changeset viewer.