Changes in uspace/srv/net/il/arp/arp.c [af7638e:46d4d9f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/arp/arp.c
raf7638e r46d4d9f 28 28 29 29 /** @addtogroup arp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * ARP module implementation. 35 * @see arp.h 36 */ 34 * ARP module implementation. 35 * @see arp.h 36 */ 37 38 #include "arp.h" 39 #include "arp_header.h" 40 #include "arp_oc.h" 41 #include "arp_module.h" 37 42 38 43 #include <async.h> … … 43 48 #include <str.h> 44 49 #include <task.h> 50 #include <adt/measured_strings.h> 45 51 #include <ipc/ipc.h> 46 52 #include <ipc/services.h> … … 49 55 #include <ipc/il.h> 50 56 #include <byteorder.h> 51 #include <err .h>57 #include <errno.h> 52 58 53 59 #include <net/modules.h> 54 60 #include <net/device.h> 55 #include <arp_interface.h> 61 #include <net/packet.h> 62 56 63 #include <nil_interface.h> 57 64 #include <protocol_map.h> 58 #include <adt/measured_strings.h>59 #include <net/packet.h>60 65 #include <packet_client.h> 61 66 #include <packet_remote.h> … … 63 68 #include <il_local.h> 64 69 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 */ 70 71 /** ARP module name. */ 73 72 #define NAME "arp" 74 73 75 /** ARP global data. 76 */ 77 arp_globals_t arp_globals; 74 /** ARP global data. */ 75 arp_globals_t arp_globals; 76 77 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t); 78 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t); 79 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t); 78 80 79 81 /** 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 */ 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 */ 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); 146 147 /*@}*/ 148 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 * 83 * @param[in] device The device specific data. 84 */ 85 static void arp_clear_device(arp_device_t *device) 86 { 156 87 int count; 157 arp_device_ref device; 88 arp_proto_t *proto; 89 90 for (count = arp_protos_count(&device->protos) - 1; count >= 0; 91 count--) { 92 proto = arp_protos_get_index(&device->protos, count); 93 if (proto) { 94 if (proto->addr) 95 free(proto->addr); 96 if (proto->addr_data) 97 free(proto->addr_data); 98 arp_addr_destroy(&proto->addresses); 99 } 100 } 101 arp_protos_clear(&device->protos); 102 } 103 104 static int arp_clean_cache_req(int arp_phone) 105 { 106 int count; 107 arp_device_t *device; 158 108 159 109 fibril_rwlock_write_lock(&arp_globals.lock); 160 for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){ 110 for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; 111 count--) { 161 112 device = arp_cache_get_index(&arp_globals.cache, count); 162 if (device){113 if (device) { 163 114 arp_clear_device(device); 164 if (device->addr_data){115 if (device->addr_data) 165 116 free(device->addr_data); 166 } 167 if(device->broadcast_data){ 117 if (device->broadcast_data) 168 118 free(device->broadcast_data); 169 }170 119 } 171 120 } … … 176 125 } 177 126 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; 127 static int arp_clear_address_req(int arp_phone, device_id_t device_id, 128 services_t protocol, measured_string_t *address) 129 { 130 arp_device_t *device; 131 arp_proto_t *proto; 181 132 182 133 fibril_rwlock_write_lock(&arp_globals.lock); 183 134 device = arp_cache_find(&arp_globals.cache, device_id); 184 if (! device){135 if (!device) { 185 136 fibril_rwlock_write_unlock(&arp_globals.lock); 186 137 return ENOENT; 187 138 } 188 139 proto = arp_protos_find(&device->protos, protocol); 189 if (! proto){140 if (!proto) { 190 141 fibril_rwlock_write_unlock(&arp_globals.lock); 191 142 return ENOENT; … … 196 147 } 197 148 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; 149 150 static int arp_clear_device_req(int arp_phone, device_id_t device_id) 151 { 152 arp_device_t *device; 219 153 220 154 fibril_rwlock_write_lock(&arp_globals.lock); 221 155 device = arp_cache_find(&arp_globals.cache, device_id); 222 if (! device){156 if (!device) { 223 157 fibril_rwlock_write_unlock(&arp_globals.lock); 224 158 return ENOENT; … … 230 164 } 231 165 232 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){ 233 ERROR_DECLARE; 234 235 arp_device_ref device; 236 arp_proto_ref proto; 166 /** Creates new protocol specific data. 167 * 168 * Allocates and returns the needed memory block as the proto parameter. 169 * 170 * @param[out] proto The allocated protocol specific data. 171 * @param[in] service The protocol module service. 172 * @param[in] address The actual protocol device address. 173 * @return EOK on success. 174 * @return ENOMEM if there is not enough memory left. 175 */ 176 static int arp_proto_create(arp_proto_t **proto, services_t service, 177 measured_string_t *address) 178 { 179 int rc; 180 181 *proto = (arp_proto_t *) malloc(sizeof(arp_proto_t)); 182 if (!*proto) 183 return ENOMEM; 184 185 (*proto)->service = service; 186 (*proto)->addr = address; 187 (*proto)->addr_data = address->value; 188 189 rc = arp_addr_initialize(&(*proto)->addresses); 190 if (rc != EOK) { 191 free(*proto); 192 return rc; 193 } 194 195 return EOK; 196 } 197 198 /** Registers the device. 199 * 200 * Creates new device entry in the cache or updates the protocol address if the 201 * device with the device identifier and the driver service exists. 202 * 203 * @param[in] device_id The device identifier. 204 * @param[in] service The device driver service. 205 * @param[in] protocol The protocol service. 206 * @param[in] address The actual device protocol address. 207 * @return EOK on success. 208 * @return EEXIST if another device with the same device identifier 209 * and different driver service exists. 210 * @return ENOMEM if there is not enough memory left. 211 * @return Other error codes as defined for the 212 * measured_strings_return() function. 213 */ 214 static int arp_device_message(device_id_t device_id, services_t service, 215 services_t protocol, measured_string_t *address) 216 { 217 arp_device_t *device; 218 arp_proto_t *proto; 219 hw_type_t hardware; 237 220 int index; 238 hw_type_t hardware;221 int rc; 239 222 240 223 fibril_rwlock_write_lock(&arp_globals.lock); 241 // an existing device? 224 225 /* An existing device? */ 242 226 device = arp_cache_find(&arp_globals.cache, device_id); 243 if(device){ 244 if(device->service != service){ 227 228 if (device) { 229 if (device->service != service) { 245 230 printf("Device %d already exists\n", device->device_id); 246 231 fibril_rwlock_write_unlock(&arp_globals.lock); … … 248 233 } 249 234 proto = arp_protos_find(&device->protos, protocol); 250 if (proto){235 if (proto) { 251 236 free(proto->addr); 252 237 free(proto->addr_data); 253 238 proto->addr = address; 254 239 proto->addr_data = address->value; 255 }else{ 256 if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 240 } else { 241 rc = arp_proto_create(&proto, protocol, address); 242 if (rc != EOK) { 257 243 fibril_rwlock_write_unlock(&arp_globals.lock); 258 return ERROR_CODE;244 return rc; 259 245 } 260 index = arp_protos_add(&device->protos, proto->service, proto); 261 if(index < 0){ 246 index = arp_protos_add(&device->protos, proto->service, 247 proto); 248 if (index < 0) { 262 249 fibril_rwlock_write_unlock(&arp_globals.lock); 263 250 free(proto); 264 251 return index; 265 252 } 266 printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol); 267 } 268 }else{ 253 printf("New protocol added:\n\tdevice id\t= " 254 "%d\n\tproto\t= %d", device_id, protocol); 255 } 256 } else { 269 257 hardware = hardware_map(service); 270 if (! hardware){258 if (!hardware) 271 259 return ENOENT; 272 }273 / / create a new device274 device = (arp_device_ ref) malloc(sizeof(arp_device_t));275 if (! device){260 261 /* Create a new device */ 262 device = (arp_device_t *) malloc(sizeof(arp_device_t)); 263 if (!device) { 276 264 fibril_rwlock_write_unlock(&arp_globals.lock); 277 265 return ENOMEM; … … 279 267 device->hardware = hardware; 280 268 device->device_id = device_id; 281 if(ERROR_OCCURRED(arp_protos_initialize(&device->protos))282 || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){269 rc = arp_protos_initialize(&device->protos); 270 if (rc != EOK) { 283 271 fibril_rwlock_write_unlock(&arp_globals.lock); 284 272 free(device); 285 return ERROR_CODE; 273 return rc; 274 } 275 rc = arp_proto_create(&proto, protocol, address); 276 if (rc != EOK) { 277 fibril_rwlock_write_unlock(&arp_globals.lock); 278 free(device); 279 return rc; 286 280 } 287 281 index = arp_protos_add(&device->protos, proto->service, proto); 288 if (index < 0){282 if (index < 0) { 289 283 fibril_rwlock_write_unlock(&arp_globals.lock); 290 284 arp_protos_destroy(&device->protos); … … 293 287 } 294 288 device->service = service; 295 // bind the new one 296 device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection); 297 if(device->phone < 0){ 289 290 /* Bind the new one */ 291 device->phone = nil_bind_service(device->service, 292 (ipcarg_t) device->device_id, SERVICE_ARP, 293 arp_globals.client_connection); 294 if (device->phone < 0) { 298 295 fibril_rwlock_write_unlock(&arp_globals.lock); 299 296 arp_protos_destroy(&device->protos); … … 301 298 return EREFUSED; 302 299 } 303 // get packet dimensions 304 if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){ 300 301 /* Get packet dimensions */ 302 rc = nil_packet_size_req(device->phone, device_id, 303 &device->packet_dimension); 304 if (rc != EOK) { 305 305 fibril_rwlock_write_unlock(&arp_globals.lock); 306 306 arp_protos_destroy(&device->protos); 307 307 free(device); 308 return ERROR_CODE; 309 } 310 // get hardware address 311 if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){ 308 return rc; 309 } 310 311 /* Get hardware address */ 312 rc = nil_get_addr_req(device->phone, device_id, &device->addr, 313 &device->addr_data); 314 if (rc != EOK) { 312 315 fibril_rwlock_write_unlock(&arp_globals.lock); 313 316 arp_protos_destroy(&device->protos); 314 317 free(device); 315 return ERROR_CODE; 316 } 317 // get broadcast address 318 if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){ 318 return rc; 319 } 320 321 /* Get broadcast address */ 322 rc = nil_get_broadcast_addr_req(device->phone, device_id, 323 &device->broadcast_addr, &device->broadcast_data); 324 if (rc != EOK) { 319 325 fibril_rwlock_write_unlock(&arp_globals.lock); 320 326 free(device->addr); … … 322 328 arp_protos_destroy(&device->protos); 323 329 free(device); 324 return ERROR_CODE; 325 } 326 if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){ 330 return rc; 331 } 332 333 rc = arp_cache_add(&arp_globals.cache, device->device_id, 334 device); 335 if (rc != EOK) { 327 336 fibril_rwlock_write_unlock(&arp_globals.lock); 328 337 free(device->addr); … … 332 341 arp_protos_destroy(&device->protos); 333 342 free(device); 334 return ERROR_CODE; 335 } 336 printf("%s: Device registered (id: %d, type: 0x%x, service: %d, proto: %d)\n", 337 NAME, device->device_id, device->hardware, device->service, protocol); 343 return rc; 344 } 345 printf("%s: Device registered (id: %d, type: 0x%x, service: %d," 346 " proto: %d)\n", NAME, device->device_id, device->hardware, 347 device->service, protocol); 338 348 } 339 349 fibril_rwlock_write_unlock(&arp_globals.lock); 350 340 351 return EOK; 341 352 } 342 353 343 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 344 ERROR_DECLARE; 345 346 measured_string_ref tmp; 347 348 // copy the given address for exclusive use 349 tmp = measured_string_copy(address); 350 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){ 351 free(tmp->value); 352 free(tmp); 353 } 354 return ERROR_CODE; 355 } 356 357 int arp_initialize(async_client_conn_t client_connection){ 358 ERROR_DECLARE; 354 /** Initializes the ARP module. 355 * 356 * @param[in] client_connection The client connection processing function. 357 * The module skeleton propagates its own one. 358 * @return EOK on success. 359 * @return ENOMEM if there is not enough memory left. 360 */ 361 int arp_initialize(async_client_conn_t client_connection) 362 { 363 int rc; 359 364 360 365 fibril_rwlock_initialize(&arp_globals.lock); 361 366 fibril_rwlock_write_lock(&arp_globals.lock); 362 367 arp_globals.client_connection = client_connection; 363 ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));368 rc = arp_cache_initialize(&arp_globals.cache); 364 369 fibril_rwlock_write_unlock(&arp_globals.lock); 365 return EOK; 366 } 367 368 int arp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 369 ipc_call_t *answer, int *answer_count) 370 { 371 ERROR_DECLARE; 372 373 measured_string_ref address; 374 measured_string_ref translation; 375 char * data; 376 packet_t packet; 377 packet_t next; 378 379 *answer_count = 0; 380 switch (IPC_GET_METHOD(*call)) { 381 case IPC_M_PHONE_HUNGUP: 382 return EOK; 383 case NET_ARP_DEVICE: 384 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 385 if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){ 386 free(address); 387 free(data); 388 } 389 return ERROR_CODE; 390 case NET_ARP_TRANSLATE: 391 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 392 fibril_rwlock_read_lock(&arp_globals.lock); 393 translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 394 free(address); 395 free(data); 396 if(! translation){ 397 fibril_rwlock_read_unlock(&arp_globals.lock); 398 return ENOENT; 399 } 400 ERROR_CODE = measured_strings_reply(translation, 1); 401 fibril_rwlock_read_unlock(&arp_globals.lock); 402 return ERROR_CODE; 403 case NET_ARP_CLEAR_DEVICE: 404 return arp_clear_device_req(0, IPC_GET_DEVICE(call)); 405 case NET_ARP_CLEAR_ADDRESS: 406 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 407 arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 408 free(address); 409 free(data); 410 return EOK; 411 case NET_ARP_CLEAN_CACHE: 412 return arp_clean_cache_req(0); 413 case NET_IL_DEVICE_STATE: 414 // do nothing - keep the cache 415 return EOK; 416 case NET_IL_RECEIVED: 417 if(! ERROR_OCCURRED(packet_translate_remote(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 418 fibril_rwlock_read_lock(&arp_globals.lock); 419 do{ 420 next = pq_detach(packet); 421 ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet); 422 if(ERROR_CODE != 1){ 423 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 424 } 425 packet = next; 426 }while(packet); 427 fibril_rwlock_read_unlock(&arp_globals.lock); 428 } 429 return ERROR_CODE; 430 case NET_IL_MTU_CHANGED: 431 return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call)); 432 } 433 434 return ENOTSUP; 435 } 436 437 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){ 438 arp_device_ref device; 370 371 return rc; 372 } 373 374 /** Updates the device content length according to the new MTU value. 375 * 376 * @param[in] device_id The device identifier. 377 * @param[in] mtu The new mtu value. 378 * @return ENOENT if device is not found. 379 * @return EOK on success. 380 */ 381 static int arp_mtu_changed_message(device_id_t device_id, size_t mtu) 382 { 383 arp_device_t *device; 439 384 440 385 fibril_rwlock_write_lock(&arp_globals.lock); 441 386 device = arp_cache_find(&arp_globals.cache, device_id); 442 if (! device){387 if (!device) { 443 388 fibril_rwlock_write_unlock(&arp_globals.lock); 444 389 return ENOENT; 445 390 } 446 391 device->packet_dimension.content = mtu; 392 fibril_rwlock_write_unlock(&arp_globals.lock); 447 393 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu); 448 fibril_rwlock_write_unlock(&arp_globals.lock);449 394 return EOK; 450 395 } 451 396 452 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){ 453 ERROR_DECLARE; 454 455 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 456 if(!(*proto)){ 457 return ENOMEM; 458 } 459 (** proto).service = service; 460 (** proto).addr = address; 461 (** proto).addr_data = address->value; 462 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){ 463 free(*proto); 464 return ERROR_CODE; 465 } 466 return EOK; 467 } 468 469 int arp_receive_message(device_id_t device_id, packet_t packet){ 470 ERROR_DECLARE; 471 397 /** Processes the received ARP packet. 398 * 399 * Updates the source hardware address if the source entry exists or the packet 400 * is targeted to my protocol address. 401 * Responses to the ARP request if the packet is the ARP request and is 402 * targeted to my address. 403 * 404 * @param[in] device_id The source device identifier. 405 * @param[in,out] packet The received packet. 406 * @return EOK on success and the packet is no longer needed. 407 * @return One on success and the packet has been reused. 408 * @return EINVAL if the packet is too small to carry an ARP 409 * packet. 410 * @return EINVAL if the received address lengths differs from 411 * the registered values. 412 * @return ENOENT if the device is not found in the cache. 413 * @return ENOENT if the protocol for the device is not found in 414 * the cache. 415 * @return ENOMEM if there is not enough memory left. 416 */ 417 static int arp_receive_message(device_id_t device_id, packet_t *packet) 418 { 472 419 size_t length; 473 arp_header_ref header; 474 arp_device_ref device; 475 arp_proto_ref proto; 476 measured_string_ref hw_source; 477 uint8_t * src_hw; 478 uint8_t * src_proto; 479 uint8_t * des_hw; 480 uint8_t * des_proto; 420 arp_header_t *header; 421 arp_device_t *device; 422 arp_proto_t *proto; 423 measured_string_t *hw_source; 424 uint8_t *src_hw; 425 uint8_t *src_proto; 426 uint8_t *des_hw; 427 uint8_t *des_proto; 428 int rc; 481 429 482 430 length = packet_get_data_length(packet); 483 if (length <= sizeof(arp_header_t)){431 if (length <= sizeof(arp_header_t)) 484 432 return EINVAL; 485 } 433 486 434 device = arp_cache_find(&arp_globals.cache, device_id); 487 if (! device){435 if (!device) 488 436 return ENOENT; 489 } 490 header = (arp_header_ref) packet_get_data(packet); 491 if((ntohs(header->hardware) != device->hardware) 492 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){ 437 438 header = (arp_header_t *) packet_get_data(packet); 439 if ((ntohs(header->hardware) != device->hardware) || 440 (length < sizeof(arp_header_t) + header->hardware_length * 2U + 441 header->protocol_length * 2U)) { 493 442 return EINVAL; 494 443 } 495 proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol))); 496 if(! proto){ 444 445 proto = arp_protos_find(&device->protos, 446 protocol_unmap(device->service, ntohs(header->protocol))); 447 if (!proto) 497 448 return ENOENT; 498 } 449 499 450 src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 500 451 src_proto = src_hw + header->hardware_length; 501 452 des_hw = src_proto + header->protocol_length; 502 453 des_proto = des_hw + header->hardware_length; 503 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length)); 504 // exists? 505 if(hw_source){ 506 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){ 454 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, 455 CONVERT_SIZE(uint8_t, char, header->protocol_length)); 456 /* Exists? */ 457 if (hw_source) { 458 if (hw_source->length != CONVERT_SIZE(uint8_t, char, 459 header->hardware_length)) { 507 460 return EINVAL; 508 461 } 509 462 memcpy(hw_source->value, src_hw, hw_source->length); 510 463 } 511 // is my protocol address? 512 if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){ 464 /* Is my protocol address? */ 465 if (proto->addr->length != CONVERT_SIZE(uint8_t, char, 466 header->protocol_length)) { 513 467 return EINVAL; 514 468 } 515 if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){ 516 // not already upadted? 517 if(! hw_source){ 518 hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length)); 519 if(! hw_source){ 469 if (!str_lcmp(proto->addr->value, (char *) des_proto, 470 proto->addr->length)) { 471 /* Not already updated? */ 472 if (!hw_source) { 473 hw_source = measured_string_create_bulk((char *) src_hw, 474 CONVERT_SIZE(uint8_t, char, 475 header->hardware_length)); 476 if (!hw_source) 520 477 return ENOMEM; 521 } 522 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source)); 523 } 524 if(ntohs(header->operation) == ARPOP_REQUEST){ 478 479 rc = arp_addr_add(&proto->addresses, (char *) src_proto, 480 CONVERT_SIZE(uint8_t, char, 481 header->protocol_length), hw_source); 482 if (rc != EOK) 483 return rc; 484 } 485 if (ntohs(header->operation) == ARPOP_REQUEST) { 525 486 header->operation = htons(ARPOP_REPLY); 526 487 memcpy(des_proto, src_proto, header->protocol_length); 527 memcpy(src_proto, proto->addr->value, header->protocol_length); 528 memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len); 529 memcpy(des_hw, hw_source->value, header->hardware_length); 530 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length)); 531 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 488 memcpy(src_proto, proto->addr->value, 489 header->protocol_length); 490 memcpy(src_hw, device->addr->value, 491 device->packet_dimension.addr_len); 492 memcpy(des_hw, hw_source->value, 493 header->hardware_length); 494 495 rc = packet_set_addr(packet, src_hw, des_hw, 496 header->hardware_length); 497 if (rc != EOK) 498 return rc; 499 500 nil_send_msg(device->phone, device_id, packet, 501 SERVICE_ARP); 532 502 return 1; 533 503 } 534 504 } 505 535 506 return EOK; 536 507 } 537 508 538 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){ 539 arp_device_ref device; 540 arp_proto_ref proto; 541 measured_string_ref addr; 509 510 /** Returns the hardware address for the given protocol address. 511 * 512 * Sends the ARP request packet if the hardware address is not found in the 513 * cache. 514 * 515 * @param[in] device_id The device identifier. 516 * @param[in] protocol The protocol service. 517 * @param[in] target The target protocol address. 518 * @return The hardware address of the target. 519 * @return NULL if the target parameter is NULL. 520 * @return NULL if the device is not found. 521 * @return NULL if the device packet is too small to send a 522 * request. 523 * @return NULL if the hardware address is not found in the cache. 524 */ 525 static measured_string_t * 526 arp_translate_message(device_id_t device_id, services_t protocol, 527 measured_string_t *target) 528 { 529 arp_device_t *device; 530 arp_proto_t *proto; 531 measured_string_t *addr; 542 532 size_t length; 543 packet_t packet;544 arp_header_ refheader;545 546 if (! target){533 packet_t *packet; 534 arp_header_t *header; 535 536 if (!target) 547 537 return NULL; 548 } 538 549 539 device = arp_cache_find(&arp_globals.cache, device_id); 550 if (! device){540 if (!device) 551 541 return NULL; 552 } 542 553 543 proto = arp_protos_find(&device->protos, protocol); 554 if ((! proto) || (proto->addr->length != target->length)){544 if (!proto || (proto->addr->length != target->length)) 555 545 return NULL; 556 } 546 557 547 addr = arp_addr_find(&proto->addresses, target->value, target->length); 558 if (addr){548 if (addr) 559 549 return addr; 560 } 561 // ARP packet content size = header + (address + translation) * 2 562 length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2; 563 if(length > device->packet_dimension.content){ 550 551 /* ARP packet content size = header + (address + translation) * 2 */ 552 length = 8 + 2 * (CONVERT_SIZE(char, uint8_t, proto->addr->length) + 553 CONVERT_SIZE(char, uint8_t, device->addr->length)); 554 if (length > device->packet_dimension.content) 564 555 return NULL; 565 } 566 packet = packet_get_4_remote(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix); 567 if(! packet){ 556 557 packet = packet_get_4_remote(arp_globals.net_phone, 558 device->packet_dimension.addr_len, device->packet_dimension.prefix, 559 length, device->packet_dimension.suffix); 560 if (!packet) 568 561 return NULL; 569 } 570 header = (arp_header_ ref) packet_suffix(packet, length);571 if (! header){562 563 header = (arp_header_t *) packet_suffix(packet, length); 564 if (!header) { 572 565 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 573 566 return NULL; 574 567 } 568 575 569 header->hardware = htons(device->hardware); 576 570 header->hardware_length = (uint8_t) device->addr->length; … … 579 573 header->operation = htons(ARPOP_REQUEST); 580 574 length = sizeof(arp_header_t); 581 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length); 575 memcpy(((uint8_t *) header) + length, device->addr->value, 576 device->addr->length); 582 577 length += device->addr->length; 583 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length); 578 memcpy(((uint8_t *) header) + length, proto->addr->value, 579 proto->addr->length); 584 580 length += proto->addr->length; 585 581 bzero(((uint8_t *) header) + length, device->addr->length); 586 582 length += device->addr->length; 587 583 memcpy(((uint8_t *) header) + length, target->value, target->length); 588 if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){ 584 585 if (packet_set_addr(packet, (uint8_t *) device->addr->value, 586 (uint8_t *) device->broadcast_addr->value, 587 CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK) { 589 588 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 590 589 return NULL; 591 590 } 591 592 592 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 593 593 return NULL; 594 594 } 595 595 596 597 /** Processes the ARP message. 598 * 599 * @param[in] callid The message identifier. 600 * @param[in] call The message parameters. 601 * @param[out] answer The message answer parameters. 602 * @param[out] answer_count The last parameter for the actual answer in the 603 * answer parameter. 604 * @return EOK on success. 605 * @return ENOTSUP if the message is not known. 606 * 607 * @see arp_interface.h 608 * @see IS_NET_ARP_MESSAGE() 609 */ 610 int 611 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 612 ipc_call_t *answer, int *answer_count) 613 { 614 measured_string_t *address; 615 measured_string_t *translation; 616 char *data; 617 packet_t *packet; 618 packet_t *next; 619 int rc; 620 621 *answer_count = 0; 622 switch (IPC_GET_METHOD(*call)) { 623 case IPC_M_PHONE_HUNGUP: 624 return EOK; 625 626 case NET_ARP_DEVICE: 627 rc = measured_strings_receive(&address, &data, 1); 628 if (rc != EOK) 629 return rc; 630 631 rc = arp_device_message(IPC_GET_DEVICE(call), 632 IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address); 633 if (rc != EOK) { 634 free(address); 635 free(data); 636 } 637 return rc; 638 639 case NET_ARP_TRANSLATE: 640 rc = measured_strings_receive(&address, &data, 1); 641 if (rc != EOK) 642 return rc; 643 644 fibril_rwlock_read_lock(&arp_globals.lock); 645 translation = arp_translate_message(IPC_GET_DEVICE(call), 646 IPC_GET_SERVICE(call), address); 647 free(address); 648 free(data); 649 if (!translation) { 650 fibril_rwlock_read_unlock(&arp_globals.lock); 651 return ENOENT; 652 } 653 rc = measured_strings_reply(translation, 1); 654 fibril_rwlock_read_unlock(&arp_globals.lock); 655 return rc; 656 657 case NET_ARP_CLEAR_DEVICE: 658 return arp_clear_device_req(0, IPC_GET_DEVICE(call)); 659 660 case NET_ARP_CLEAR_ADDRESS: 661 rc = measured_strings_receive(&address, &data, 1); 662 if (rc != EOK) 663 return rc; 664 665 arp_clear_address_req(0, IPC_GET_DEVICE(call), 666 IPC_GET_SERVICE(call), address); 667 free(address); 668 free(data); 669 return EOK; 670 671 case NET_ARP_CLEAN_CACHE: 672 return arp_clean_cache_req(0); 673 674 case NET_IL_DEVICE_STATE: 675 /* Do nothing - keep the cache */ 676 return EOK; 677 678 case NET_IL_RECEIVED: 679 rc = packet_translate_remote(arp_globals.net_phone, &packet, 680 IPC_GET_PACKET(call)); 681 if (rc != EOK) 682 return rc; 683 684 fibril_rwlock_read_lock(&arp_globals.lock); 685 do { 686 next = pq_detach(packet); 687 rc = arp_receive_message(IPC_GET_DEVICE(call), packet); 688 if (rc != 1) { 689 pq_release_remote(arp_globals.net_phone, 690 packet_get_id(packet)); 691 } 692 packet = next; 693 } while (packet); 694 fibril_rwlock_read_unlock(&arp_globals.lock); 695 696 return EOK; 697 698 case NET_IL_MTU_CHANGED: 699 return arp_mtu_changed_message(IPC_GET_DEVICE(call), 700 IPC_GET_MTU(call)); 701 } 702 703 return ENOTSUP; 704 } 705 596 706 /** Default thread for new connections. 597 707 * 598 * @param[in] iid The initial message identifier. 599 * @param[in] icall The initial message call structure. 600 * 601 */ 602 static void il_client_connection(ipc_callid_t iid, ipc_call_t * icall) 708 * @param[in] iid The initial message identifier. 709 * @param[in] icall The initial message call structure. 710 */ 711 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall) 603 712 { 604 713 /* … … 608 717 ipc_answer_0(iid, EOK); 609 718 610 while (true) {719 while (true) { 611 720 ipc_call_t answer; 612 721 int answer_count; … … 623 732 &answer_count); 624 733 625 /* End if said to either by the message or the processing result */ 626 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)) 734 /* 735 * End if told to either by the message or the processing 736 * result. 737 */ 738 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 739 (res == EHANGUP)) 627 740 return; 628 741 … … 634 747 /** Starts the module. 635 748 * 636 * @param argc The count of the command line arguments. Ignored parameter. 637 * @param argv The command line parameters. Ignored parameter. 638 * 639 * @returns EOK on success. 640 * @returns Other error codes as defined for each specific module start function. 641 * 749 * @return EOK on success. 750 * @return Other error codes as defined for each specific module 751 * start function. 642 752 */ 643 753 int main(int argc, char *argv[]) 644 754 { 645 ERROR_DECLARE;755 int rc; 646 756 647 757 /* Start the module */ 648 if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection))) 649 return ERROR_CODE; 650 651 return EOK; 758 rc = il_module_start_standalone(il_client_connection); 759 return rc; 652 760 } 653 761 654 762 /** @} 655 763 */ 764
Note:
See TracChangeset
for help on using the changeset viewer.