Changes in uspace/srv/net/nil/eth/eth.c [28a3e74:0a3fbc7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/nil/eth/eth.c
r28a3e74 r0a3fbc7 42 42 #include <byteorder.h> 43 43 #include <str.h> 44 #include <errno.h> 45 #include <ipc/nil.h> 44 #include <err.h> 45 46 #include <ipc/ipc.h> 46 47 #include <ipc/net.h> 47 48 #include <ipc/services.h> 49 48 50 #include <net/modules.h> 49 51 #include <net_checksum.h> … … 52 54 #include <protocol_map.h> 53 55 #include <net/device.h> 54 #include <netif_ remote.h>56 #include <netif_interface.h> 55 57 #include <net_interface.h> 56 #include <il_remote.h> 58 #include <nil_interface.h> 59 #include <il_interface.h> 57 60 #include <adt/measured_strings.h> 58 61 #include <packet_client.h> 59 62 #include <packet_remote.h> 60 #include <nil_ skel.h>63 #include <nil_local.h> 61 64 62 65 #include "eth.h" 66 #include "eth_header.h" 63 67 64 68 /** The module name. */ … … 68 72 #define ETH_PREFIX \ 69 73 (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \ 70 74 sizeof(eth_header_snap_t)) 71 75 72 76 /** Reserved packet suffix length. */ 73 #define ETH_SUFFIX (sizeof(eth_fcs_t)) 77 #define ETH_SUFFIX \ 78 sizeof(eth_fcs_t) 74 79 75 80 /** Maximum packet content length. */ 76 #define ETH_MAX_CONTENT 81 #define ETH_MAX_CONTENT 1500u 77 82 78 83 /** Minimum packet content length. */ 79 #define ETH_MIN_CONTENT 84 #define ETH_MIN_CONTENT 46u 80 85 81 86 /** Maximum tagged packet content length. */ 82 87 #define ETH_MAX_TAGGED_CONTENT(flags) \ 83 88 (ETH_MAX_CONTENT - \ 84 85 86 89 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 90 sizeof(eth_header_lsap_t) : 0) - \ 91 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 87 92 88 93 /** Minimum tagged packet content length. */ 89 94 #define ETH_MIN_TAGGED_CONTENT(flags) \ 90 95 (ETH_MIN_CONTENT - \ 91 92 93 96 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 97 sizeof(eth_header_lsap_t) : 0) - \ 98 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 94 99 95 100 /** Dummy flag shift value. */ 96 #define ETH_DUMMY_SHIFT 101 #define ETH_DUMMY_SHIFT 0 97 102 98 103 /** Mode flag shift value. */ 99 #define ETH_MODE_SHIFT 104 #define ETH_MODE_SHIFT 1 100 105 101 106 /** Dummy device flag. 102 107 * Preamble and FCS are mandatory part of the packets. 103 108 */ 104 #define ETH_DUMMY 109 #define ETH_DUMMY (1 << ETH_DUMMY_SHIFT) 105 110 106 111 /** Returns the dummy flag. 107 112 * @see ETH_DUMMY 108 113 */ 109 #define IS_DUMMY(flags) 114 #define IS_DUMMY(flags) ((flags) & ETH_DUMMY) 110 115 111 116 /** Device mode flags. … … 114 119 * @see ETH_8023_2_SNAP 115 120 */ 116 #define ETH_MODE_MASK 121 #define ETH_MODE_MASK (3 << ETH_MODE_SHIFT) 117 122 118 123 /** DIX Ethernet mode flag. */ 119 #define ETH_DIX 120 121 /** Return whether the DIX Ethernet mode flag is set.122 * 123 * @param[in] flags Ethernet flags.124 #define ETH_DIX (1 << ETH_MODE_SHIFT) 125 126 /** Returns whether the DIX Ethernet mode flag is set. 127 * 128 * @param[in] flags The ethernet flags. 124 129 * @see ETH_DIX 125 * 126 */ 127 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 130 */ 131 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 128 132 129 133 /** 802.3 + 802.2 + LSAP mode flag. */ 130 #define ETH_8023_2_LSAP 131 132 /** Return whether the 802.3 + 802.2 + LSAP mode flag is set.133 * 134 * @param[in] flags Ethernet flags.134 #define ETH_8023_2_LSAP (2 << ETH_MODE_SHIFT) 135 136 /** Returns whether the 802.3 + 802.2 + LSAP mode flag is set. 137 * 138 * @param[in] flags The ethernet flags. 135 139 * @see ETH_8023_2_LSAP 136 * 137 */ 138 #define IS_8023_2_LSAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP) 140 */ 141 #define IS_8023_2_LSAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP) 139 142 140 143 /** 802.3 + 802.2 + LSAP + SNAP mode flag. */ 141 #define ETH_8023_2_SNAP 142 143 /** Return whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.144 * 145 * @param[in] flags Ethernet flags.144 #define ETH_8023_2_SNAP (3 << ETH_MODE_SHIFT) 145 146 /** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. 147 * 148 * @param[in] flags The ethernet flags. 146 149 * @see ETH_8023_2_SNAP 147 * 148 */ 149 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 150 */ 151 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 150 152 151 153 /** Type definition of the ethernet address type. … … 153 155 */ 154 156 typedef enum eth_addr_type eth_addr_type_t; 157 158 /** Type definition of the ethernet address type pointer. 159 * @see eth_addr_type 160 */ 161 typedef eth_addr_type_t *eth_addr_type_ref; 155 162 156 163 /** Ethernet address type. */ … … 171 178 { 172 179 int index; 173 eth_proto_ t *proto;180 eth_proto_ref proto; 174 181 175 182 fibril_rwlock_read_lock(ð_globals.protos_lock); … … 189 196 int nil_initialize(int net_phone) 190 197 { 191 int rc;198 ERROR_DECLARE; 192 199 193 200 fibril_rwlock_initialize(ð_globals.devices_lock); … … 197 204 fibril_rwlock_write_lock(ð_globals.protos_lock); 198 205 eth_globals.net_phone = net_phone; 199 200 206 eth_globals.broadcast_addr = 201 measured_string_create_bulk((uint8_t *) "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ADDR); 207 measured_string_create_bulk("\xFF\xFF\xFF\xFF\xFF\xFF", 208 CONVERT_SIZE(uint8_t, char, ETH_ADDR)); 202 209 if (!eth_globals.broadcast_addr) { 203 rc= ENOMEM;210 ERROR_CODE = ENOMEM; 204 211 goto out; 205 212 } 206 207 rc = eth_devices_initialize(ð_globals.devices); 208 if (rc != EOK) { 213 if (ERROR_OCCURRED(eth_devices_initialize(ð_globals.devices))) { 209 214 free(eth_globals.broadcast_addr); 210 215 goto out; 211 216 } 212 213 rc = eth_protos_initialize(ð_globals.protos); 214 if (rc != EOK) { 217 if (ERROR_OCCURRED(eth_protos_initialize(ð_globals.protos))) { 215 218 free(eth_globals.broadcast_addr); 216 eth_devices_destroy(ð_globals.devices , free);219 eth_devices_destroy(ð_globals.devices); 217 220 } 218 221 out: … … 220 223 fibril_rwlock_write_unlock(ð_globals.devices_lock); 221 224 222 return rc;225 return ERROR_CODE; 223 226 } 224 227 … … 231 234 static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall) 232 235 { 233 packet_t *packet; 234 int rc; 236 ERROR_DECLARE; 237 238 packet_t packet; 235 239 236 240 while (true) { 237 switch (IPC_GET_ IMETHOD(*icall)) {241 switch (IPC_GET_METHOD(*icall)) { 238 242 case NET_NIL_DEVICE_STATE: 239 nil_device_state_msg_local(0, IPC_GET_DEVICE( *icall),240 IPC_GET_STATE( *icall));241 async_answer_0(iid, EOK);243 nil_device_state_msg_local(0, IPC_GET_DEVICE(icall), 244 IPC_GET_STATE(icall)); 245 ipc_answer_0(iid, EOK); 242 246 break; 243 247 case NET_NIL_RECEIVED: 244 rc = packet_translate_remote(eth_globals.net_phone,245 &packet, IPC_GET_PACKET(*icall));246 if (rc == EOK)247 rc= nil_received_msg_local(0,248 IPC_GET_DEVICE( *icall), packet, 0);249 250 async_answer_0(iid, (sysarg_t) rc);248 if (ERROR_NONE(packet_translate_remote( 249 eth_globals.net_phone, &packet, 250 IPC_GET_PACKET(icall)))) { 251 ERROR_CODE = nil_received_msg_local(0, 252 IPC_GET_DEVICE(icall), packet, 0); 253 } 254 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE); 251 255 break; 252 256 default: 253 async_answer_0(iid, (sysarg_t) ENOTSUP);257 ipc_answer_0(iid, (ipcarg_t) ENOTSUP); 254 258 } 255 259 … … 265 269 * @param[in] service The device driver service. 266 270 * @param[in] mtu The device maximum transmission unit. 267 * @return EOK on success.268 * @return EEXIST if the device with the different service exists.269 * @return ENOMEM if there is not enough memory left.270 * @return Other error codes as defined for the271 * @returns EOK on success. 272 * @returns EEXIST if the device with the different service exists. 273 * @returns ENOMEM if there is not enough memory left. 274 * @returns Other error codes as defined for the 271 275 * net_get_device_conf_req() function. 272 * @return Other error codes as defined for the276 * @returns Other error codes as defined for the 273 277 * netif_bind_service() function. 274 * @return Other error codes as defined for the278 * @returns Other error codes as defined for the 275 279 * netif_get_addr_req() function. 276 280 */ 277 static int eth_device_message(device_id_t device_id, services_t service, 278 size_t mtu) 279 { 280 eth_device_t *device; 281 static int 282 eth_device_message(device_id_t device_id, services_t service, size_t mtu) 283 { 284 ERROR_DECLARE; 285 286 eth_device_ref device; 281 287 int index; 282 288 measured_string_t names[2] = { 283 289 { 284 ( uint8_t*) "ETH_MODE",290 (char *) "ETH_MODE", 285 291 8 286 292 }, 287 293 { 288 ( uint8_t*) "ETH_DUMMY",294 (char *) "ETH_DUMMY", 289 295 9 290 296 } 291 297 }; 292 measured_string_ t *configuration;298 measured_string_ref configuration; 293 299 size_t count = sizeof(names) / sizeof(measured_string_t); 294 uint8_t *data; 295 eth_proto_t *proto; 296 int rc; 300 char *data; 301 eth_proto_ref proto; 297 302 298 303 fibril_rwlock_write_lock(ð_globals.devices_lock); 299 / * An existing device? */304 // an existing device? 300 305 device = eth_devices_find(ð_globals.devices, device_id); 301 306 if (device) { … … 306 311 } 307 312 308 / * Update mtu */313 // update mtu 309 314 if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))) 310 315 device->mtu = mtu; … … 312 317 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags); 313 318 314 printf("Device %d already exists:\tMTU\t= % zu\n",319 printf("Device %d already exists:\tMTU\t= %d\n", 315 320 device->device_id, device->mtu); 316 321 fibril_rwlock_write_unlock(ð_globals.devices_lock); 317 322 318 / * Notify all upper layer modules */323 // notify all upper layer modules 319 324 fibril_rwlock_read_lock(ð_globals.protos_lock); 320 325 for (index = 0; index < eth_protos_count(ð_globals.protos); … … 328 333 } 329 334 } 330 331 335 fibril_rwlock_read_unlock(ð_globals.protos_lock); 332 336 return EOK; 333 337 } 334 338 335 / * Create a new device */336 device = (eth_device_ t *) malloc(sizeof(eth_device_t));339 // create a new device 340 device = (eth_device_ref) malloc(sizeof(eth_device_t)); 337 341 if (!device) 338 342 return ENOMEM; … … 347 351 348 352 configuration = &names[0]; 349 rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id, 350 &configuration, count, &data); 351 if (rc != EOK) { 353 if (ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone, 354 device->device_id, &configuration, count, &data))) { 352 355 fibril_rwlock_write_unlock(ð_globals.devices_lock); 353 356 free(device); 354 return rc; 355 } 356 357 return ERROR_CODE; 358 } 357 359 if (configuration) { 358 if (!str_lcmp( (char *)configuration[0].value, "DIX",360 if (!str_lcmp(configuration[0].value, "DIX", 359 361 configuration[0].length)) { 360 362 device->flags |= ETH_DIX; 361 } else if(!str_lcmp( (char *)configuration[0].value, "8023_2_LSAP",363 } else if(!str_lcmp(configuration[0].value, "8023_2_LSAP", 362 364 configuration[0].length)) { 363 365 device->flags |= ETH_8023_2_LSAP; … … 375 377 } 376 378 377 / * Bind the device driver */379 // bind the device driver 378 380 device->phone = netif_bind_service(device->service, device->device_id, 379 381 SERVICE_ETHERNET, eth_receiver); … … 384 386 } 385 387 386 /* Get hardware address */ 387 rc = netif_get_addr_req(device->phone, device->device_id, &device->addr, 388 &device->addr_data); 389 if (rc != EOK) { 388 // get hardware address 389 if (ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, 390 &device->addr, &device->addr_data))) { 390 391 fibril_rwlock_write_unlock(ð_globals.devices_lock); 391 392 free(device); 392 return rc;393 } 394 395 / * Add to the cache */393 return ERROR_CODE; 394 } 395 396 // add to the cache 396 397 index = eth_devices_add(ð_globals.devices, device->device_id, 397 398 device); … … 404 405 } 405 406 406 printf("%s: Device registered (id: %d, service: %d: mtu: % zu, "407 "mac: % 02x:%02x:%02x:%02x:%02x:%02x, flags: 0x%x)\n",407 printf("%s: Device registered (id: %d, service: %d: mtu: %d, " 408 "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n", 408 409 NAME, device->device_id, device->service, device->mtu, 409 410 device->addr_data[0], device->addr_data[1], … … 419 420 * @param[in] flags The device flags. 420 421 * @param[in] packet The packet. 421 * @return The target registered module. 422 * @return NULL if the packet is not long enough. 423 * @return NULL if the packet is too long. 424 * @return NULL if the raw ethernet protocol is used. 425 * @return NULL if the dummy device FCS checksum is invalid. 426 * @return NULL if the packet address length is not big enough. 427 */ 428 static eth_proto_t *eth_process_packet(int flags, packet_t *packet) 429 { 430 eth_header_snap_t *header; 422 * @returns The target registered module. 423 * @returns NULL if the packet is not long enough. 424 * @returns NULL if the packet is too long. 425 * @returns NULL if the raw ethernet protocol is used. 426 * @returns NULL if the dummy device FCS checksum is invalid. 427 * @returns NULL if the packet address length is not big enough. 428 */ 429 static eth_proto_ref eth_process_packet(int flags, packet_t packet) 430 { 431 ERROR_DECLARE; 432 433 eth_header_snap_ref header; 431 434 size_t length; 432 435 eth_type_t type; 433 436 size_t prefix; 434 437 size_t suffix; 435 eth_fcs_t *fcs; 436 uint8_t *data; 437 int rc; 438 eth_fcs_ref fcs; 439 uint8_t * data; 438 440 439 441 length = packet_get_data_length(packet); … … 446 448 447 449 data = packet_get_data(packet); 448 header = (eth_header_snap_ t *) data;450 header = (eth_header_snap_ref) data; 449 451 type = ntohs(header->header.ethertype); 450 452 451 453 if (type >= ETH_MIN_PROTO) { 452 / * DIX Ethernet */454 // DIX Ethernet 453 455 prefix = sizeof(eth_header_t); 454 456 suffix = 0; 455 fcs = (eth_fcs_ t *) data + length - sizeof(eth_fcs_t);457 fcs = (eth_fcs_ref) data + length - sizeof(eth_fcs_t); 456 458 length -= sizeof(eth_fcs_t); 457 459 } else if(type <= ETH_MAX_CONTENT) { 458 / * Translate "LSAP" values */460 // translate "LSAP" values 459 461 if ((header->lsap.dsap == ETH_LSAP_GLSAP) && 460 462 (header->lsap.ssap == ETH_LSAP_GLSAP)) { 461 /* Raw packet -- discard */ 463 // raw packet 464 // discard 462 465 return NULL; 463 466 } else if((header->lsap.dsap == ETH_LSAP_SNAP) && 464 467 (header->lsap.ssap == ETH_LSAP_SNAP)) { 465 /* 466 * IEEE 802.3 + 802.2 + LSAP + SNAP 467 * organization code not supported 468 */ 468 // IEEE 802.3 + 802.2 + LSAP + SNAP 469 // organization code not supported 469 470 type = ntohs(header->snap.ethertype); 470 471 prefix = sizeof(eth_header_t) + … … 472 473 sizeof(eth_header_snap_t); 473 474 } else { 474 / * IEEE 802.3 + 802.2 LSAP */475 // IEEE 802.3 + 802.2 LSAP 475 476 type = lsap_map(header->lsap.dsap); 476 477 prefix = sizeof(eth_header_t) + 477 478 sizeof(eth_header_lsap_t); 478 479 } 479 480 480 suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0U; 481 fcs = (eth_fcs_ t *) data + prefix + type + suffix;481 fcs = (eth_fcs_ref) data + prefix + type + suffix; 482 482 suffix += length - prefix - type; 483 483 length = prefix + type + suffix; 484 484 } else { 485 / * Invalid length/type, should not occur */485 // invalid length/type, should not occurr 486 486 return NULL; 487 487 } 488 488 489 489 if (IS_DUMMY(flags)) { 490 if ( ~compute_crc32(~0U, data, length * 8) != ntohl(*fcs))490 if ((~compute_crc32(~0U, data, length * 8)) != ntohl(*fcs)) 491 491 return NULL; 492 492 suffix += sizeof(eth_fcs_t); 493 493 } 494 494 495 rc = packet_set_addr(packet, header->header.source_address,496 header->header. destination_address, ETH_ADDR);497 if (rc != EOK)495 if (ERROR_OCCURRED(packet_set_addr(packet, 496 header->header.source_address, header->header.destination_address, 497 ETH_ADDR)) || ERROR_OCCURRED(packet_trim(packet, prefix, suffix))) { 498 498 return NULL; 499 500 rc = packet_trim(packet, prefix, suffix); 501 if (rc != EOK) 502 return NULL; 499 } 503 500 504 501 return eth_protos_find(ð_globals.protos, type); 505 502 } 506 503 507 int nil_received_msg_local(int nil_phone, device_id_t device_id, 508 packet_t *packet, services_t target) 509 { 510 eth_proto_t *proto; 511 packet_t *next; 512 eth_device_t *device; 504 int 505 nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, 506 services_t target) 507 { 508 eth_proto_ref proto; 509 packet_t next; 510 eth_device_ref device; 513 511 int flags; 514 512 … … 519 517 return ENOENT; 520 518 } 521 522 519 flags = device->flags; 523 520 fibril_rwlock_read_unlock(ð_globals.devices_lock); … … 531 528 proto->service); 532 529 } else { 533 / * Drop invalid/unknown */530 // drop invalid/unknown 534 531 pq_release_remote(eth_globals.net_phone, 535 532 packet_get_id(packet)); … … 537 534 packet = next; 538 535 } while(packet); 539 540 536 fibril_rwlock_read_unlock(ð_globals.protos_lock); 537 541 538 return EOK; 542 539 } … … 549 546 * @param[out] content The maximum content size. 550 547 * @param[out] suffix The minimum reserved suffix size. 551 * @return EOK on success. 552 * @return EBADMEM if either one of the parameters is NULL. 553 * @return ENOENT if there is no such device. 554 */ 555 static int eth_packet_space_message(device_id_t device_id, size_t *addr_len, 548 * @returns EOK on success. 549 * @returns EBADMEM if either one of the parameters is NULL. 550 * @returns ENOENT if there is no such device. 551 */ 552 static int 553 eth_packet_space_message(device_id_t device_id, size_t *addr_len, 556 554 size_t *prefix, size_t *content, size_t *suffix) 557 555 { 558 eth_device_ t *device;556 eth_device_ref device; 559 557 560 558 if (!addr_len || !prefix || !content || !suffix) … … 567 565 return ENOENT; 568 566 } 569 570 567 *content = device->mtu; 571 568 fibril_rwlock_read_unlock(ð_globals.devices_lock); … … 574 571 *prefix = ETH_PREFIX; 575 572 *suffix = ETH_MIN_CONTENT + ETH_SUFFIX; 576 577 573 return EOK; 578 574 } … … 583 579 * @param[in] type Type of the desired address. 584 580 * @param[out] address The device hardware address. 585 * @return EOK on success. 586 * @return EBADMEM if the address parameter is NULL. 587 * @return ENOENT if there no such device. 588 */ 589 static int eth_addr_message(device_id_t device_id, eth_addr_type_t type, 590 measured_string_t **address) 591 { 592 eth_device_t *device; 581 * @returns EOK on success. 582 * @returns EBADMEM if the address parameter is NULL. 583 * @returns ENOENT if there no such device. 584 */ 585 static int 586 eth_addr_message(device_id_t device_id, eth_addr_type_t type, 587 measured_string_ref *address) 588 { 589 eth_device_ref device; 593 590 594 591 if (!address) … … 617 614 * @param[in] service The module service. 618 615 * @param[in] phone The service phone. 619 * @return EOK on success.620 * @return ENOENT if the service is not known.621 * @return ENOMEM if there is not enough memory left.616 * @returns EOK on success. 617 * @returns ENOENT if the service is not known. 618 * @returns ENOMEM if there is not enough memory left. 622 619 */ 623 620 static int eth_register_message(services_t service, int phone) 624 621 { 625 eth_proto_ t *proto;622 eth_proto_ref proto; 626 623 int protocol; 627 624 int index; … … 638 635 return EOK; 639 636 } else { 640 proto = (eth_proto_ t *) malloc(sizeof(eth_proto_t));637 proto = (eth_proto_ref) malloc(sizeof(eth_proto_t)); 641 638 if (!proto) { 642 639 fibril_rwlock_write_unlock(ð_globals.protos_lock); 643 640 return ENOMEM; 644 641 } 645 646 642 proto->service = service; 647 643 proto->protocol = protocol; 648 644 proto->phone = phone; 649 650 645 index = eth_protos_add(ð_globals.protos, protocol, proto); 651 646 if (index < 0) { … … 670 665 * @param[in] ethertype The ethernet protocol type. 671 666 * @param[in] mtu The device maximum transmission unit. 672 * @return EOK on success.673 * @return EINVAL if the packet addresses length is not long667 * @returns EOK on success. 668 * @returns EINVAL if the packet addresses length is not long 674 669 * enough. 675 * @return EINVAL if the packet is bigger than the device MTU.676 * @return ENOMEM if there is not enough memory in the packet.670 * @returns EINVAL if the packet is bigger than the device MTU. 671 * @returns ENOMEM if there is not enough memory in the packet. 677 672 */ 678 673 static int 679 eth_prepare_packet(int flags, packet_t *packet, uint8_t *src_addr, int ethertype,674 eth_prepare_packet(int flags, packet_t packet, uint8_t *src_addr, int ethertype, 680 675 size_t mtu) 681 676 { 682 eth_header_snap_ t *header;683 eth_header_lsap_ t *header_lsap;684 eth_header_ t *header_dix;685 eth_fcs_ t *fcs;677 eth_header_snap_ref header; 678 eth_header_lsap_ref header_lsap; 679 eth_header_ref header_dix; 680 eth_fcs_ref fcs; 686 681 uint8_t *src; 687 682 uint8_t *dest; … … 689 684 int i; 690 685 void *padding; 691 eth_preamble_ t *preamble;686 eth_preamble_ref preamble; 692 687 693 688 i = packet_get_addr(packet, &src, &dest); … … 706 701 if (!padding) 707 702 return ENOMEM; 708 709 703 bzero(padding, ETH_MIN_TAGGED_CONTENT(flags) - length); 710 704 } … … 780 774 * @param[in] packet The packet queue. 781 775 * @param[in] sender The sending module service. 782 * @return EOK on success. 783 * @return ENOENT if there no such device. 784 * @return EINVAL if the service parameter is not known. 785 */ 786 static int eth_send_message(device_id_t device_id, packet_t *packet, 787 services_t sender) 788 { 789 eth_device_t *device; 790 packet_t *next; 791 packet_t *tmp; 776 * @returns EOK on success. 777 * @returns ENOENT if there no such device. 778 * @returns EINVAL if the service parameter is not known. 779 */ 780 static int 781 eth_send_message(device_id_t device_id, packet_t packet, services_t sender) 782 { 783 ERROR_DECLARE; 784 785 eth_device_ref device; 786 packet_t next; 787 packet_t tmp; 792 788 int ethertype; 793 int rc;794 789 795 790 ethertype = htons(protocol_map(SERVICE_ETHERNET, sender)); … … 806 801 } 807 802 808 / * Process packet queue */803 // process packet queue 809 804 next = packet; 810 805 do { 811 rc = eth_prepare_packet(device->flags, next, 812 (uint8_t *) device->addr->value, ethertype, device->mtu); 813 if (rc != EOK) { 814 /* Release invalid packet */ 806 if (ERROR_OCCURRED(eth_prepare_packet(device->flags, next, 807 (uint8_t *) device->addr->value, ethertype, device->mtu))) { 808 // release invalid packet 815 809 tmp = pq_detach(next); 816 810 if (next == packet) … … 824 818 } while(next); 825 819 826 / * Send packet queue */820 // send packet queue 827 821 if (packet) { 828 822 netif_send_msg(device->phone, device_id, packet, 829 823 SERVICE_ETHERNET); 830 824 } 831 832 825 fibril_rwlock_read_unlock(ð_globals.devices_lock); 826 833 827 return EOK; 834 828 } 835 829 836 int nil_module_message(ipc_callid_t callid, ipc_call_t *call, 837 ipc_call_t *answer, size_t *answer_count) 838 { 839 measured_string_t *address; 840 packet_t *packet; 830 int 831 nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call, 832 ipc_call_t *answer, int *answer_count) 833 { 834 ERROR_DECLARE; 835 836 measured_string_ref address; 837 packet_t packet; 841 838 size_t addrlen; 842 839 size_t prefix; 843 840 size_t suffix; 844 841 size_t content; 845 int rc;846 842 847 843 *answer_count = 0; 848 switch (IPC_GET_ IMETHOD(*call)) {844 switch (IPC_GET_METHOD(*call)) { 849 845 case IPC_M_PHONE_HUNGUP: 850 846 return EOK; 851 847 852 848 case NET_NIL_DEVICE: 853 return eth_device_message(IPC_GET_DEVICE( *call),854 IPC_GET_SERVICE( *call), IPC_GET_MTU(*call));849 return eth_device_message(IPC_GET_DEVICE(call), 850 IPC_GET_SERVICE(call), IPC_GET_MTU(call)); 855 851 case NET_NIL_SEND: 856 rc = packet_translate_remote(eth_globals.net_phone, &packet, 857 IPC_GET_PACKET(*call)); 858 if (rc != EOK) 859 return rc; 860 return eth_send_message(IPC_GET_DEVICE(*call), packet, 861 IPC_GET_SERVICE(*call)); 852 ERROR_PROPAGATE(packet_translate_remote(eth_globals.net_phone, 853 &packet, IPC_GET_PACKET(call))); 854 return eth_send_message(IPC_GET_DEVICE(call), packet, 855 IPC_GET_SERVICE(call)); 862 856 case NET_NIL_PACKET_SPACE: 863 rc = eth_packet_space_message(IPC_GET_DEVICE(*call), &addrlen, 864 &prefix, &content, &suffix); 865 if (rc != EOK) 866 return rc; 867 IPC_SET_ADDR(*answer, addrlen); 868 IPC_SET_PREFIX(*answer, prefix); 869 IPC_SET_CONTENT(*answer, content); 870 IPC_SET_SUFFIX(*answer, suffix); 857 ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call), 858 &addrlen, &prefix, &content, &suffix)); 859 IPC_SET_ADDR(answer, addrlen); 860 IPC_SET_PREFIX(answer, prefix); 861 IPC_SET_CONTENT(answer, content); 862 IPC_SET_SUFFIX(answer, suffix); 871 863 *answer_count = 4; 872 864 return EOK; 873 865 case NET_NIL_ADDR: 874 rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_LOCAL_ADDR, 875 &address); 876 if (rc != EOK) 877 return rc; 866 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 867 ETH_LOCAL_ADDR, &address)); 878 868 return measured_strings_reply(address, 1); 879 869 case NET_NIL_BROADCAST_ADDR: 880 rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_BROADCAST_ADDR, 881 &address); 882 if (rc != EOK) 883 return EOK; 870 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 871 ETH_BROADCAST_ADDR, &address)); 884 872 return measured_strings_reply(address, 1); 885 873 case IPC_M_CONNECT_TO_ME: 886 return eth_register_message(NIL_GET_PROTO( *call),887 IPC_GET_PHONE( *call));874 return eth_register_message(NIL_GET_PROTO(call), 875 IPC_GET_PHONE(call)); 888 876 } 889 877 … … 891 879 } 892 880 881 /** Default thread for new connections. 882 * 883 * @param[in] iid The initial message identifier. 884 * @param[in] icall The initial message call structure. 885 * 886 */ 887 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall) 888 { 889 /* 890 * Accept the connection 891 * - Answer the first IPC_M_CONNECT_ME_TO call. 892 */ 893 ipc_answer_0(iid, EOK); 894 895 while (true) { 896 ipc_call_t answer; 897 int answer_count; 898 899 /* Clear the answer structure */ 900 refresh_answer(&answer, &answer_count); 901 902 /* Fetch the next message */ 903 ipc_call_t call; 904 ipc_callid_t callid = async_get_call(&call); 905 906 /* Process the message */ 907 int res = nil_module_message_standalone(NAME, callid, &call, 908 &answer, &answer_count); 909 910 /* 911 * End if told to either by the message or the processing 912 * result. 913 */ 914 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 915 (res == EHANGUP)) 916 return; 917 918 /* Answer the message */ 919 answer_call(callid, res, &answer, answer_count); 920 } 921 } 922 893 923 int main(int argc, char *argv[]) 894 924 { 925 ERROR_DECLARE; 926 895 927 /* Start the module */ 896 return nil_module_start(SERVICE_ETHERNET); 928 ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection)); 929 return EOK; 897 930 } 898 931
Note:
See TracChangeset
for help on using the changeset viewer.