Changeset b5e68c8 in mainline for uspace/srv/net/nil/eth/eth.c
- Timestamp:
- 2011-05-12T16:49:44Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f36787d7
- Parents:
- e80329d6 (diff), 750636a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/nil/eth/eth.c
re80329d6 rb5e68c8 42 42 #include <byteorder.h> 43 43 #include <str.h> 44 #include <err.h> 45 46 #include <ipc/ipc.h> 44 #include <errno.h> 45 #include <ipc/nil.h> 47 46 #include <ipc/net.h> 48 47 #include <ipc/services.h> 49 50 48 #include <net/modules.h> 51 49 #include <net_checksum.h> … … 54 52 #include <protocol_map.h> 55 53 #include <net/device.h> 56 #include <netif_ interface.h>54 #include <netif_remote.h> 57 55 #include <net_interface.h> 58 #include <nil_interface.h> 59 #include <il_interface.h> 56 #include <il_remote.h> 60 57 #include <adt/measured_strings.h> 61 58 #include <packet_client.h> 62 59 #include <packet_remote.h> 63 #include <nil_ local.h>60 #include <nil_skel.h> 64 61 65 62 #include "eth.h" 66 #include "eth_header.h"67 63 68 64 /** The module name. */ … … 72 68 #define ETH_PREFIX \ 73 69 (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \ 74 sizeof(eth_header_snap_t))70 sizeof(eth_header_snap_t)) 75 71 76 72 /** Reserved packet suffix length. */ 77 #define ETH_SUFFIX \ 78 sizeof(eth_fcs_t) 73 #define ETH_SUFFIX (sizeof(eth_fcs_t)) 79 74 80 75 /** Maximum packet content length. */ 81 #define ETH_MAX_CONTENT 1500u76 #define ETH_MAX_CONTENT 1500u 82 77 83 78 /** Minimum packet content length. */ 84 #define ETH_MIN_CONTENT 46u79 #define ETH_MIN_CONTENT 46u 85 80 86 81 /** Maximum tagged packet content length. */ 87 82 #define ETH_MAX_TAGGED_CONTENT(flags) \ 88 83 (ETH_MAX_CONTENT - \ 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))84 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 85 sizeof(eth_header_lsap_t) : 0) - \ 86 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 92 87 93 88 /** Minimum tagged packet content length. */ 94 89 #define ETH_MIN_TAGGED_CONTENT(flags) \ 95 90 (ETH_MIN_CONTENT - \ 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))91 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 92 sizeof(eth_header_lsap_t) : 0) - \ 93 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 99 94 100 95 /** Dummy flag shift value. */ 101 #define ETH_DUMMY_SHIFT 96 #define ETH_DUMMY_SHIFT 0 102 97 103 98 /** Mode flag shift value. */ 104 #define ETH_MODE_SHIFT 99 #define ETH_MODE_SHIFT 1 105 100 106 101 /** Dummy device flag. 107 102 * Preamble and FCS are mandatory part of the packets. 108 103 */ 109 #define ETH_DUMMY 104 #define ETH_DUMMY (1 << ETH_DUMMY_SHIFT) 110 105 111 106 /** Returns the dummy flag. 112 107 * @see ETH_DUMMY 113 108 */ 114 #define IS_DUMMY(flags) 109 #define IS_DUMMY(flags) ((flags) & ETH_DUMMY) 115 110 116 111 /** Device mode flags. … … 119 114 * @see ETH_8023_2_SNAP 120 115 */ 121 #define ETH_MODE_MASK 116 #define ETH_MODE_MASK (3 << ETH_MODE_SHIFT) 122 117 123 118 /** DIX Ethernet mode flag. */ 124 #define ETH_DIX 125 126 /** Return swhether the DIX Ethernet mode flag is set.127 * 128 * @param[in] flags The ethernet flags.119 #define ETH_DIX (1 << ETH_MODE_SHIFT) 120 121 /** Return whether the DIX Ethernet mode flag is set. 122 * 123 * @param[in] flags Ethernet flags. 129 124 * @see ETH_DIX 130 */ 131 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 125 * 126 */ 127 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 132 128 133 129 /** 802.3 + 802.2 + LSAP mode flag. */ 134 #define ETH_8023_2_LSAP 135 136 /** Return swhether the 802.3 + 802.2 + LSAP mode flag is set.137 * 138 * @param[in] flags The ethernet flags.130 #define ETH_8023_2_LSAP (2 << ETH_MODE_SHIFT) 131 132 /** Return whether the 802.3 + 802.2 + LSAP mode flag is set. 133 * 134 * @param[in] flags Ethernet flags. 139 135 * @see ETH_8023_2_LSAP 140 */ 141 #define IS_8023_2_LSAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP) 136 * 137 */ 138 #define IS_8023_2_LSAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP) 142 139 143 140 /** 802.3 + 802.2 + LSAP + SNAP mode flag. */ 144 #define ETH_8023_2_SNAP 145 146 /** Return swhether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.147 * 148 * @param[in] flags The ethernet flags.141 #define ETH_8023_2_SNAP (3 << ETH_MODE_SHIFT) 142 143 /** Return whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. 144 * 145 * @param[in] flags Ethernet flags. 149 146 * @see ETH_8023_2_SNAP 150 */ 151 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 147 * 148 */ 149 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 152 150 153 151 /** Type definition of the ethernet address type. … … 155 153 */ 156 154 typedef enum eth_addr_type eth_addr_type_t; 157 158 /** Type definition of the ethernet address type pointer.159 * @see eth_addr_type160 */161 typedef eth_addr_type_t *eth_addr_type_ref;162 155 163 156 /** Ethernet address type. */ … … 178 171 { 179 172 int index; 180 eth_proto_ refproto;173 eth_proto_t *proto; 181 174 182 175 fibril_rwlock_read_lock(ð_globals.protos_lock); … … 196 189 int nil_initialize(int net_phone) 197 190 { 198 ERROR_DECLARE;191 int rc; 199 192 200 193 fibril_rwlock_initialize(ð_globals.devices_lock); … … 204 197 fibril_rwlock_write_lock(ð_globals.protos_lock); 205 198 eth_globals.net_phone = net_phone; 199 206 200 eth_globals.broadcast_addr = 207 measured_string_create_bulk("\xFF\xFF\xFF\xFF\xFF\xFF", 208 CONVERT_SIZE(uint8_t, char, ETH_ADDR)); 201 measured_string_create_bulk((uint8_t *) "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ADDR); 209 202 if (!eth_globals.broadcast_addr) { 210 ERROR_CODE= ENOMEM;203 rc = ENOMEM; 211 204 goto out; 212 205 } 213 if (ERROR_OCCURRED(eth_devices_initialize(ð_globals.devices))) { 206 207 rc = eth_devices_initialize(ð_globals.devices); 208 if (rc != EOK) { 214 209 free(eth_globals.broadcast_addr); 215 210 goto out; 216 211 } 217 if (ERROR_OCCURRED(eth_protos_initialize(ð_globals.protos))) { 212 213 rc = eth_protos_initialize(ð_globals.protos); 214 if (rc != EOK) { 218 215 free(eth_globals.broadcast_addr); 219 eth_devices_destroy(ð_globals.devices );216 eth_devices_destroy(ð_globals.devices, free); 220 217 } 221 218 out: … … 223 220 fibril_rwlock_write_unlock(ð_globals.devices_lock); 224 221 225 return ERROR_CODE;222 return rc; 226 223 } 227 224 … … 234 231 static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall) 235 232 { 236 ERROR_DECLARE; 237 238 packet_t packet; 233 packet_t *packet; 234 int rc; 239 235 240 236 while (true) { 241 switch (IPC_GET_ METHOD(*icall)) {237 switch (IPC_GET_IMETHOD(*icall)) { 242 238 case NET_NIL_DEVICE_STATE: 243 nil_device_state_msg_local(0, IPC_GET_DEVICE( icall),244 IPC_GET_STATE( icall));245 ipc_answer_0(iid, EOK);239 nil_device_state_msg_local(0, IPC_GET_DEVICE(*icall), 240 IPC_GET_STATE(*icall)); 241 async_answer_0(iid, EOK); 246 242 break; 247 243 case NET_NIL_RECEIVED: 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);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); 255 251 break; 256 252 default: 257 ipc_answer_0(iid, (ipcarg_t) ENOTSUP);253 async_answer_0(iid, (sysarg_t) ENOTSUP); 258 254 } 259 255 … … 269 265 * @param[in] service The device driver service. 270 266 * @param[in] mtu The device maximum transmission unit. 271 * @return sEOK on success.272 * @return sEEXIST if the device with the different service exists.273 * @return sENOMEM if there is not enough memory left.274 * @return sOther error codes as defined for the267 * @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 the 275 271 * net_get_device_conf_req() function. 276 * @return sOther error codes as defined for the272 * @return Other error codes as defined for the 277 273 * netif_bind_service() function. 278 * @return sOther error codes as defined for the274 * @return Other error codes as defined for the 279 275 * netif_get_addr_req() function. 280 276 */ 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; 277 static int eth_device_message(device_id_t device_id, services_t service, 278 size_t mtu) 279 { 280 eth_device_t *device; 287 281 int index; 288 282 measured_string_t names[2] = { 289 283 { 290 ( char*) "ETH_MODE",284 (uint8_t *) "ETH_MODE", 291 285 8 292 286 }, 293 287 { 294 ( char*) "ETH_DUMMY",288 (uint8_t *) "ETH_DUMMY", 295 289 9 296 290 } 297 291 }; 298 measured_string_ refconfiguration;292 measured_string_t *configuration; 299 293 size_t count = sizeof(names) / sizeof(measured_string_t); 300 char *data; 301 eth_proto_ref proto; 294 uint8_t *data; 295 eth_proto_t *proto; 296 int rc; 302 297 303 298 fibril_rwlock_write_lock(ð_globals.devices_lock); 304 / / an existing device?299 /* An existing device? */ 305 300 device = eth_devices_find(ð_globals.devices, device_id); 306 301 if (device) { … … 311 306 } 312 307 313 / / update mtu308 /* Update mtu */ 314 309 if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))) 315 310 device->mtu = mtu; … … 317 312 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags); 318 313 319 printf("Device %d already exists:\tMTU\t= % d\n",314 printf("Device %d already exists:\tMTU\t= %zu\n", 320 315 device->device_id, device->mtu); 321 316 fibril_rwlock_write_unlock(ð_globals.devices_lock); 322 317 323 / / notify all upper layer modules318 /* Notify all upper layer modules */ 324 319 fibril_rwlock_read_lock(ð_globals.protos_lock); 325 320 for (index = 0; index < eth_protos_count(ð_globals.protos); … … 333 328 } 334 329 } 330 335 331 fibril_rwlock_read_unlock(ð_globals.protos_lock); 336 332 return EOK; 337 333 } 338 334 339 / / create a new device340 device = (eth_device_ ref) malloc(sizeof(eth_device_t));335 /* Create a new device */ 336 device = (eth_device_t *) malloc(sizeof(eth_device_t)); 341 337 if (!device) 342 338 return ENOMEM; … … 351 347 352 348 configuration = &names[0]; 353 if (ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone, 354 device->device_id, &configuration, count, &data))) { 349 rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id, 350 &configuration, count, &data); 351 if (rc != EOK) { 355 352 fibril_rwlock_write_unlock(ð_globals.devices_lock); 356 353 free(device); 357 return ERROR_CODE; 358 } 354 return rc; 355 } 356 359 357 if (configuration) { 360 if (!str_lcmp( configuration[0].value, "DIX",358 if (!str_lcmp((char *) configuration[0].value, "DIX", 361 359 configuration[0].length)) { 362 360 device->flags |= ETH_DIX; 363 } else if(!str_lcmp( configuration[0].value, "8023_2_LSAP",361 } else if(!str_lcmp((char *) configuration[0].value, "8023_2_LSAP", 364 362 configuration[0].length)) { 365 363 device->flags |= ETH_8023_2_LSAP; … … 377 375 } 378 376 379 / / bind the device driver377 /* Bind the device driver */ 380 378 device->phone = netif_bind_service(device->service, device->device_id, 381 379 SERVICE_ETHERNET, eth_receiver); … … 386 384 } 387 385 388 // get hardware address 389 if (ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, 390 &device->addr, &device->addr_data))) { 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) { 391 390 fibril_rwlock_write_unlock(ð_globals.devices_lock); 392 391 free(device); 393 return ERROR_CODE;394 } 395 396 / / add to the cache392 return rc; 393 } 394 395 /* Add to the cache */ 397 396 index = eth_devices_add(ð_globals.devices, device->device_id, 398 397 device); … … 405 404 } 406 405 407 printf("%s: Device registered (id: %d, service: %d: mtu: % d, "408 "mac: % x:%x:%x:%x:%x:%x, flags: 0x%x)\n",406 printf("%s: Device registered (id: %d, service: %d: mtu: %zu, " 407 "mac: %02x:%02x:%02x:%02x:%02x:%02x, flags: 0x%x)\n", 409 408 NAME, device->device_id, device->service, device->mtu, 410 409 device->addr_data[0], device->addr_data[1], … … 420 419 * @param[in] flags The device flags. 421 420 * @param[in] packet The packet. 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; 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; 434 431 size_t length; 435 432 eth_type_t type; 436 433 size_t prefix; 437 434 size_t suffix; 438 eth_fcs_ref fcs; 439 uint8_t * data; 435 eth_fcs_t *fcs; 436 uint8_t *data; 437 int rc; 440 438 441 439 length = packet_get_data_length(packet); … … 448 446 449 447 data = packet_get_data(packet); 450 header = (eth_header_snap_ ref) data;448 header = (eth_header_snap_t *) data; 451 449 type = ntohs(header->header.ethertype); 452 450 453 451 if (type >= ETH_MIN_PROTO) { 454 / / DIX Ethernet452 /* DIX Ethernet */ 455 453 prefix = sizeof(eth_header_t); 456 454 suffix = 0; 457 fcs = (eth_fcs_ ref) data + length - sizeof(eth_fcs_t);455 fcs = (eth_fcs_t *) data + length - sizeof(eth_fcs_t); 458 456 length -= sizeof(eth_fcs_t); 459 457 } else if(type <= ETH_MAX_CONTENT) { 460 / / translate "LSAP" values458 /* Translate "LSAP" values */ 461 459 if ((header->lsap.dsap == ETH_LSAP_GLSAP) && 462 460 (header->lsap.ssap == ETH_LSAP_GLSAP)) { 463 // raw packet 464 // discard 461 /* Raw packet -- discard */ 465 462 return NULL; 466 463 } else if((header->lsap.dsap == ETH_LSAP_SNAP) && 467 464 (header->lsap.ssap == ETH_LSAP_SNAP)) { 468 // IEEE 802.3 + 802.2 + LSAP + SNAP 469 // organization code not supported 465 /* 466 * IEEE 802.3 + 802.2 + LSAP + SNAP 467 * organization code not supported 468 */ 470 469 type = ntohs(header->snap.ethertype); 471 470 prefix = sizeof(eth_header_t) + … … 473 472 sizeof(eth_header_snap_t); 474 473 } else { 475 / / IEEE 802.3 + 802.2 LSAP474 /* IEEE 802.3 + 802.2 LSAP */ 476 475 type = lsap_map(header->lsap.dsap); 477 476 prefix = sizeof(eth_header_t) + 478 477 sizeof(eth_header_lsap_t); 479 478 } 479 480 480 suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0U; 481 fcs = (eth_fcs_ ref) data + prefix + type + suffix;481 fcs = (eth_fcs_t *) 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 occurr485 /* Invalid length/type, should not occur */ 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 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))) {495 rc = packet_set_addr(packet, header->header.source_address, 496 header->header.destination_address, ETH_ADDR); 497 if (rc != EOK) 498 498 return NULL; 499 } 499 500 rc = packet_trim(packet, prefix, suffix); 501 if (rc != EOK) 502 return NULL; 500 503 501 504 return eth_protos_find(ð_globals.protos, type); 502 505 } 503 506 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; 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; 511 513 int flags; 512 514 … … 517 519 return ENOENT; 518 520 } 521 519 522 flags = device->flags; 520 523 fibril_rwlock_read_unlock(ð_globals.devices_lock); … … 528 531 proto->service); 529 532 } else { 530 / / drop invalid/unknown533 /* Drop invalid/unknown */ 531 534 pq_release_remote(eth_globals.net_phone, 532 535 packet_get_id(packet)); … … 534 537 packet = next; 535 538 } while(packet); 539 536 540 fibril_rwlock_read_unlock(ð_globals.protos_lock); 537 538 541 return EOK; 539 542 } … … 546 549 * @param[out] content The maximum content size. 547 550 * @param[out] suffix The minimum reserved suffix size. 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, 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, 554 556 size_t *prefix, size_t *content, size_t *suffix) 555 557 { 556 eth_device_ refdevice;558 eth_device_t *device; 557 559 558 560 if (!addr_len || !prefix || !content || !suffix) … … 565 567 return ENOENT; 566 568 } 569 567 570 *content = device->mtu; 568 571 fibril_rwlock_read_unlock(ð_globals.devices_lock); … … 571 574 *prefix = ETH_PREFIX; 572 575 *suffix = ETH_MIN_CONTENT + ETH_SUFFIX; 576 573 577 return EOK; 574 578 } … … 579 583 * @param[in] type Type of the desired address. 580 584 * @param[out] address The device hardware address. 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; 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; 590 593 591 594 if (!address) … … 614 617 * @param[in] service The module service. 615 618 * @param[in] phone The service phone. 616 * @return sEOK on success.617 * @return sENOENT if the service is not known.618 * @return sENOMEM if there is not enough memory left.619 * @return EOK on success. 620 * @return ENOENT if the service is not known. 621 * @return ENOMEM if there is not enough memory left. 619 622 */ 620 623 static int eth_register_message(services_t service, int phone) 621 624 { 622 eth_proto_ refproto;625 eth_proto_t *proto; 623 626 int protocol; 624 627 int index; … … 635 638 return EOK; 636 639 } else { 637 proto = (eth_proto_ ref) malloc(sizeof(eth_proto_t));640 proto = (eth_proto_t *) malloc(sizeof(eth_proto_t)); 638 641 if (!proto) { 639 642 fibril_rwlock_write_unlock(ð_globals.protos_lock); 640 643 return ENOMEM; 641 644 } 645 642 646 proto->service = service; 643 647 proto->protocol = protocol; 644 648 proto->phone = phone; 649 645 650 index = eth_protos_add(ð_globals.protos, protocol, proto); 646 651 if (index < 0) { … … 665 670 * @param[in] ethertype The ethernet protocol type. 666 671 * @param[in] mtu The device maximum transmission unit. 667 * @return sEOK on success.668 * @return sEINVAL if the packet addresses length is not long672 * @return EOK on success. 673 * @return EINVAL if the packet addresses length is not long 669 674 * enough. 670 * @return sEINVAL if the packet is bigger than the device MTU.671 * @return sENOMEM if there is not enough memory in the packet.675 * @return EINVAL if the packet is bigger than the device MTU. 676 * @return ENOMEM if there is not enough memory in the packet. 672 677 */ 673 678 static int 674 eth_prepare_packet(int flags, packet_t packet, uint8_t *src_addr, int ethertype,679 eth_prepare_packet(int flags, packet_t *packet, uint8_t *src_addr, int ethertype, 675 680 size_t mtu) 676 681 { 677 eth_header_snap_ refheader;678 eth_header_lsap_ refheader_lsap;679 eth_header_ refheader_dix;680 eth_fcs_ reffcs;682 eth_header_snap_t *header; 683 eth_header_lsap_t *header_lsap; 684 eth_header_t *header_dix; 685 eth_fcs_t *fcs; 681 686 uint8_t *src; 682 687 uint8_t *dest; … … 684 689 int i; 685 690 void *padding; 686 eth_preamble_ refpreamble;691 eth_preamble_t *preamble; 687 692 688 693 i = packet_get_addr(packet, &src, &dest); … … 701 706 if (!padding) 702 707 return ENOMEM; 708 703 709 bzero(padding, ETH_MIN_TAGGED_CONTENT(flags) - length); 704 710 } … … 774 780 * @param[in] packet The packet queue. 775 781 * @param[in] sender The sending module service. 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; 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; 788 792 int ethertype; 793 int rc; 789 794 790 795 ethertype = htons(protocol_map(SERVICE_ETHERNET, sender)); … … 801 806 } 802 807 803 / / process packet queue808 /* Process packet queue */ 804 809 next = packet; 805 810 do { 806 if (ERROR_OCCURRED(eth_prepare_packet(device->flags, next, 807 (uint8_t *) device->addr->value, ethertype, device->mtu))) { 808 // release invalid packet 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 */ 809 815 tmp = pq_detach(next); 810 816 if (next == packet) … … 818 824 } while(next); 819 825 820 / / send packet queue826 /* Send packet queue */ 821 827 if (packet) { 822 828 netif_send_msg(device->phone, device_id, packet, 823 829 SERVICE_ETHERNET); 824 830 } 831 825 832 fibril_rwlock_read_unlock(ð_globals.devices_lock); 826 827 833 return EOK; 828 834 } 829 835 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; 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; 838 841 size_t addrlen; 839 842 size_t prefix; 840 843 size_t suffix; 841 844 size_t content; 845 int rc; 842 846 843 847 *answer_count = 0; 844 switch (IPC_GET_ METHOD(*call)) {848 switch (IPC_GET_IMETHOD(*call)) { 845 849 case IPC_M_PHONE_HUNGUP: 846 850 return EOK; 847 851 848 852 case NET_NIL_DEVICE: 849 return eth_device_message(IPC_GET_DEVICE( call),850 IPC_GET_SERVICE( call), IPC_GET_MTU(call));853 return eth_device_message(IPC_GET_DEVICE(*call), 854 IPC_GET_SERVICE(*call), IPC_GET_MTU(*call)); 851 855 case NET_NIL_SEND: 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)); 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)); 856 862 case NET_NIL_PACKET_SPACE: 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); 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); 863 871 *answer_count = 4; 864 872 return EOK; 865 873 case NET_NIL_ADDR: 866 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 867 ETH_LOCAL_ADDR, &address)); 874 rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_LOCAL_ADDR, 875 &address); 876 if (rc != EOK) 877 return rc; 868 878 return measured_strings_reply(address, 1); 869 879 case NET_NIL_BROADCAST_ADDR: 870 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 871 ETH_BROADCAST_ADDR, &address)); 880 rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_BROADCAST_ADDR, 881 &address); 882 if (rc != EOK) 883 return EOK; 872 884 return measured_strings_reply(address, 1); 873 885 case IPC_M_CONNECT_TO_ME: 874 return eth_register_message(NIL_GET_PROTO( call),875 IPC_GET_PHONE( call));886 return eth_register_message(NIL_GET_PROTO(*call), 887 IPC_GET_PHONE(*call)); 876 888 } 877 889 … … 879 891 } 880 892 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 connection891 * - 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 processing912 * 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 923 893 int main(int argc, char *argv[]) 924 894 { 925 ERROR_DECLARE;926 927 895 /* Start the module */ 928 ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection)); 929 return EOK; 896 return nil_module_start(SERVICE_ETHERNET); 930 897 } 931 898
Note:
See TracChangeset
for help on using the changeset viewer.