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