1 /* 2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10 #include "ancillary_data.h" 11 #include "device_interfaces.h" 12 #include "domains.h" 13 #include "interfaces.h" 14 #include "link.h" 15 #include "stack_private.h" 16 #include "utility.h" 17 18 #include <net_datalink_protocol.h> 19 #include <net_device.h> 20 #include <net_protocol.h> 21 #include <net_stack.h> 22 23 #include <lock.h> 24 #include <util/AutoLock.h> 25 #include <util/Vector.h> 26 27 #include <KernelExport.h> 28 29 #include <net/if_types.h> 30 #include <new> 31 #include <stdarg.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 36 //#define TRACE_STACK 37 #ifdef TRACE_STACK 38 # define TRACE(x) dprintf x 39 #else 40 # define TRACE(x) ; 41 #endif 42 43 #define MAX_CHAIN_MODULES 5 44 45 struct chain; 46 typedef DoublyLinkedList<chain> ChainList; 47 48 struct chain_key { 49 int family; 50 int type; 51 int protocol; 52 }; 53 54 struct family { 55 family(int type); 56 57 void Acquire(); 58 void Release(); 59 60 static int Compare(void* _family, const void* _key); 61 static uint32 Hash(void* _family, const void* _key, uint32 range); 62 static struct family* Lookup(int type); 63 static struct family* Add(int type); 64 65 struct family* next; 66 int type; 67 int32 ref_count; 68 ChainList chains; 69 }; 70 71 struct ChainHash; 72 73 struct chain : DoublyLinkedListLinkImpl<chain> { 74 chain(int family, int type, int protocol); 75 ~chain(); 76 77 status_t Acquire(); 78 void Release(); 79 void Uninitialize(); 80 81 static struct chain* Lookup(BOpenHashTable<ChainHash>* chains, 82 int family, int type, int protocol); 83 static struct chain* Add(BOpenHashTable<ChainHash>* chains, 84 int family, int type, int protocol, va_list modules); 85 static struct chain* Add(BOpenHashTable<ChainHash>* chains, 86 int family, int type, int protocol, ...); 87 static void DeleteChains(BOpenHashTable<ChainHash>* chains); 88 89 chain* next; 90 struct family* parent; 91 92 int family; 93 int type; 94 int protocol; 95 96 int32 ref_count; 97 uint32 flags; 98 const char* modules[MAX_CHAIN_MODULES + 1]; 99 module_info* infos[MAX_CHAIN_MODULES + 1]; 100 }; 101 102 struct ChainHash { 103 typedef chain_key KeyType; 104 typedef chain ValueType; 105 106 // TODO: check if this makes a good hash... 107 #define HASH(o) ((uint32)(((o)->family) ^ ((o)->type) ^ ((o)->protocol))) 108 109 size_t HashKey(KeyType key) const 110 { 111 return HASH(&key); 112 } 113 114 size_t Hash(ValueType* value) const 115 { 116 return HASH(value); 117 } 118 119 #undef HASH 120 121 bool Compare(KeyType key, ValueType* chain) const 122 { 123 if (chain->family == key.family 124 && chain->type == key.type 125 && chain->protocol == key.protocol) 126 return true; 127 128 return false; 129 } 130 131 ValueType*& GetLink(ValueType* value) const 132 { 133 return value->next; 134 } 135 }; 136 137 struct FamilyHash { 138 typedef int KeyType; 139 typedef family ValueType; 140 141 size_t HashKey(KeyType key) const 142 { 143 return key; 144 } 145 146 size_t Hash(ValueType* value) const 147 { 148 return value->type; 149 } 150 151 bool Compare(KeyType key, ValueType* family) const 152 { 153 return family->type == key; 154 } 155 156 ValueType*& GetLink(ValueType* value) const 157 { 158 return value->next; 159 } 160 }; 161 162 typedef BOpenHashTable<ChainHash> ChainTable; 163 typedef BOpenHashTable<FamilyHash> FamilyTable; 164 165 #define CHAIN_MISSING_MODULE 0x02 166 #define CHAIN_INITIALIZED 0x01 167 168 static mutex sChainLock; 169 static mutex sInitializeChainLock; 170 static ChainTable* sProtocolChains; 171 static ChainTable* sDatalinkProtocolChains; 172 static ChainTable* sReceivingProtocolChains; 173 static FamilyTable* sFamilies; 174 static bool sInitialized; 175 176 177 family::family(int _type) 178 : 179 type(_type), 180 ref_count(0) 181 { 182 } 183 184 185 void 186 family::Acquire() 187 { 188 atomic_add(&ref_count, 1); 189 } 190 191 192 void 193 family::Release() 194 { 195 if (atomic_add(&ref_count, -1) > 1) 196 return; 197 198 TRACE(("family %d unused, uninit chains\n", type)); 199 MutexLocker _(sChainLock); 200 201 ChainList::Iterator iterator = chains.GetIterator(); 202 while (struct chain* chain = iterator.Next()) { 203 chain->Uninitialize(); 204 } 205 } 206 207 208 /*static*/ struct family* 209 family::Lookup(int type) 210 { 211 return sFamilies->Lookup(type); 212 } 213 214 215 /*static*/ struct family* 216 family::Add(int type) 217 { 218 struct family* family = new (std::nothrow) ::family(type); 219 if (family == NULL) 220 return NULL; 221 222 if (sFamilies->Insert(family) != B_OK) { 223 delete family; 224 return NULL; 225 } 226 227 return family; 228 } 229 230 231 // #pragma mark - 232 233 234 chain::chain(int _family, int _type, int _protocol) 235 : 236 family(_family), 237 type(_type), 238 protocol(_protocol), 239 ref_count(0), 240 flags(0) 241 { 242 parent = ::family::Lookup(family); 243 if (parent == NULL) 244 parent = ::family::Add(family); 245 246 //parent->chains.Add(this); 247 248 for (int32 i = 0; i < MAX_CHAIN_MODULES; i++) { 249 modules[i] = NULL; 250 infos[i] = NULL; 251 } 252 } 253 254 255 chain::~chain() 256 { 257 for (int32 i = 0; i < MAX_CHAIN_MODULES; i++) { 258 free((char*)modules[i]); 259 } 260 261 //parent->chains.Remove(this); 262 } 263 264 265 status_t 266 chain::Acquire() 267 { 268 if (atomic_add(&ref_count, 1) > 0) { 269 if ((flags & CHAIN_MISSING_MODULE) != 0) { 270 atomic_add(&ref_count, -1); 271 return EAFNOSUPPORT; 272 } 273 274 while ((flags & CHAIN_INITIALIZED) == 0) { 275 mutex_lock(&sInitializeChainLock); 276 mutex_unlock(&sInitializeChainLock); 277 } 278 return B_OK; 279 } 280 281 parent->Acquire(); 282 283 if ((flags & CHAIN_INITIALIZED) != 0) 284 return B_OK; 285 286 TRACE(("initializing chain %d.%d.%d\n", family, type, protocol)); 287 MutexLocker locker(&sInitializeChainLock); 288 289 for (int32 i = 0; modules[i] != NULL; i++) { 290 if (get_module(modules[i], &infos[i]) < B_OK) { 291 flags |= CHAIN_MISSING_MODULE; 292 293 // put already opened modules 294 while (i-- > 0) { 295 put_module(modules[i]); 296 } 297 return EAFNOSUPPORT; 298 } 299 } 300 301 flags |= CHAIN_INITIALIZED; 302 return B_OK; 303 } 304 305 306 void 307 chain::Release() 308 { 309 if (atomic_add(&ref_count, -1) > 1) 310 return; 311 312 TRACE(("chain %d.%d.%d unused\n", family, type, protocol)); 313 parent->Release(); 314 } 315 316 317 void 318 chain::Uninitialize() 319 { 320 if ((flags & CHAIN_INITIALIZED) == 0) 321 return; 322 323 TRACE(("uninit chain %d.%d.%d\n", family, type, protocol)); 324 MutexLocker _(sInitializeChainLock); 325 326 for (int32 i = 0; modules[i] != NULL; i++) { 327 put_module(modules[i]); 328 } 329 330 flags &= ~CHAIN_INITIALIZED; 331 } 332 333 334 /*static*/ struct chain* 335 chain::Lookup(ChainTable* chains, int family, int type, int protocol) 336 { 337 struct chain_key key = { family, type, protocol }; 338 return chains->Lookup(key); 339 } 340 341 342 /*static*/ struct chain* 343 chain::Add(ChainTable* chains, int family, int type, int protocol, 344 va_list modules) 345 { 346 struct chain* chain = new (std::nothrow) ::chain(family, type, protocol); 347 if (chain == NULL) 348 return NULL; 349 350 if (chain->parent == NULL || chains->Insert(chain) != B_OK) { 351 delete chain; 352 return NULL; 353 } 354 355 TRACE(("Add chain %d.%d.%d:\n", family, type, protocol)); 356 const char* module; 357 int32 count = 0; 358 359 while (true) { 360 module = va_arg(modules, const char*); 361 if (module == NULL) 362 break; 363 364 TRACE((" [%" B_PRId32 "] %s\n", count, module)); 365 chain->modules[count] = strdup(module); 366 if (chain->modules[count] == NULL 367 || ++count >= MAX_CHAIN_MODULES) { 368 chains->Remove(chain); 369 delete chain; 370 return NULL; 371 } 372 } 373 374 if (chains == sProtocolChains && count == 0) { 375 chains->Remove(chain); 376 delete chain; 377 return NULL; 378 } 379 380 return chain; 381 } 382 383 384 /*static*/ struct chain* 385 chain::Add(ChainTable* chains, int family, int type, int protocol, ...) 386 { 387 va_list modules; 388 va_start(modules, protocol); 389 390 struct chain* chain = Add(chains, family, type, 0, modules); 391 392 va_end(modules); 393 return chain; 394 } 395 396 397 /*static*/ void 398 chain::DeleteChains(ChainTable* chains) 399 { 400 struct chain* current; 401 current = chains->Clear(true); 402 while (current) { 403 struct chain* next = current->next; 404 405 current->Uninitialize(); 406 delete current; 407 current = next; 408 } 409 } 410 411 412 // #pragma mark - 413 414 415 static void 416 uninit_domain_protocols(net_socket* socket) 417 { 418 net_protocol* protocol = socket->first_protocol; 419 while (protocol != NULL) { 420 net_protocol* next = protocol->next; 421 protocol->module->uninit_protocol(protocol); 422 423 protocol = next; 424 } 425 426 socket->first_protocol = NULL; 427 socket->first_info = NULL; 428 } 429 430 431 status_t 432 get_domain_protocols(net_socket* socket) 433 { 434 struct chain* chain; 435 436 { 437 MutexLocker _(sChainLock); 438 439 chain = chain::Lookup(sProtocolChains, socket->family, socket->type, 440 socket->type == SOCK_RAW ? 0 : socket->protocol); 441 // in SOCK_RAW mode, we ignore the protocol information 442 if (chain == NULL) { 443 // TODO: if we want to be POSIX compatible, we should also support 444 // the error codes EPROTONOSUPPORT and EPROTOTYPE. 445 return EAFNOSUPPORT; 446 } 447 } 448 449 // create net_protocol objects for the protocols in the chain 450 451 status_t status = chain->Acquire(); 452 if (status != B_OK) 453 return status; 454 455 net_protocol* last = NULL; 456 457 for (int32 i = 0; chain->infos[i] != NULL; i++) { 458 net_protocol* protocol = 459 ((net_protocol_module_info*)chain->infos[i])->init_protocol(socket); 460 if (protocol == NULL) { 461 // free protocols we already initialized 462 uninit_domain_protocols(socket); 463 chain->Release(); 464 return B_NO_MEMORY; 465 } 466 467 protocol->module = (net_protocol_module_info*)chain->infos[i]; 468 protocol->socket = socket; 469 protocol->next = NULL; 470 471 if (last == NULL) { 472 socket->first_protocol = protocol; 473 socket->first_info = protocol->module; 474 } else 475 last->next = protocol; 476 477 last = protocol; 478 } 479 480 return B_OK; 481 } 482 483 484 status_t 485 put_domain_protocols(net_socket* socket) 486 { 487 struct chain* chain; 488 489 { 490 MutexLocker _(sChainLock); 491 492 chain = chain::Lookup(sProtocolChains, socket->family, socket->type, 493 socket->protocol); 494 if (chain == NULL) 495 return B_ERROR; 496 } 497 498 uninit_domain_protocols(socket); 499 chain->Release(); 500 return B_OK; 501 } 502 503 504 static void 505 uninit_domain_datalink_protocols(domain_datalink* datalink) 506 { 507 TRACE(("%s(datalink %p)\n", __FUNCTION__, datalink)); 508 509 if (datalink == NULL) 510 return; 511 512 net_datalink_protocol* protocol = datalink->first_protocol; 513 while (protocol != NULL) { 514 net_datalink_protocol* next = protocol->next; 515 protocol->module->uninit_protocol(protocol); 516 517 protocol = next; 518 } 519 520 datalink->first_protocol = NULL; 521 datalink->first_info = NULL; 522 } 523 524 525 status_t 526 get_domain_datalink_protocols(Interface* interface, net_domain* domain) 527 { 528 TRACE(("%s(interface %p, domain %d)\n", __FUNCTION__, interface, 529 domain->family)); 530 531 struct chain* chain; 532 533 { 534 MutexLocker _(sChainLock); 535 536 chain = chain::Lookup(sDatalinkProtocolChains, domain->family, 537 interface->DeviceInterface()->device->type, 0); 538 if (chain == NULL) 539 return EAFNOSUPPORT; 540 } 541 542 domain_datalink* datalink = interface->DomainDatalink(domain->family); 543 if (datalink == NULL) 544 return B_BAD_VALUE; 545 if (datalink->first_protocol != NULL) 546 return B_NAME_IN_USE; 547 548 // create net_protocol objects for the protocols in the chain 549 550 status_t status = chain->Acquire(); 551 if (status != B_OK) 552 return status; 553 554 net_datalink_protocol* last = NULL; 555 556 for (int32 i = 0; chain->infos[i] != NULL; i++) { 557 net_datalink_protocol* protocol; 558 status_t status = ((net_datalink_protocol_module_info*) 559 chain->infos[i])->init_protocol(interface, domain, &protocol); 560 if (status != B_OK) { 561 // free protocols we already initialized 562 uninit_domain_datalink_protocols(datalink); 563 chain->Release(); 564 return status; 565 } 566 567 protocol->module = (net_datalink_protocol_module_info*)chain->infos[i]; 568 protocol->interface = interface; 569 protocol->domain = domain; 570 protocol->next = NULL; 571 572 if (last == NULL) { 573 datalink->first_protocol = protocol; 574 datalink->first_info = protocol->module; 575 } else 576 last->next = protocol; 577 578 last = protocol; 579 } 580 581 return B_OK; 582 } 583 584 585 status_t 586 put_domain_datalink_protocols(Interface* interface, net_domain* domain) 587 { 588 TRACE(("%s(interface %p, domain %d)\n", __FUNCTION__, interface, 589 domain->family)); 590 591 struct chain* chain; 592 593 { 594 MutexLocker _(sChainLock); 595 596 chain = chain::Lookup(sDatalinkProtocolChains, domain->family, 597 interface->DeviceInterface()->device->type, 0); 598 if (chain == NULL) 599 return B_ERROR; 600 } 601 602 uninit_domain_datalink_protocols(interface->DomainDatalink(domain->family)); 603 chain->Release(); 604 return B_OK; 605 } 606 607 608 status_t 609 get_domain_receiving_protocol(net_domain* _domain, uint32 type, 610 net_protocol_module_info** _module) 611 { 612 struct net_domain_private* domain = (net_domain_private*)_domain; 613 struct chain* chain; 614 615 TRACE(("get_domain_receiving_protocol(family %d, type %" B_PRIu32 ")\n", 616 domain->family, type)); 617 618 { 619 MutexLocker _(sChainLock); 620 621 chain = chain::Lookup(sReceivingProtocolChains, domain->family, 622 type, 0); 623 if (chain == NULL) 624 return EAFNOSUPPORT; 625 } 626 627 status_t status = chain->Acquire(); 628 if (status != B_OK) 629 return status; 630 631 *_module = (net_protocol_module_info*)chain->infos[0]; 632 return B_OK; 633 } 634 635 636 status_t 637 put_domain_receiving_protocol(net_domain* _domain, uint32 type) 638 { 639 struct net_domain_private* domain = (net_domain_private*)_domain; 640 struct chain* chain; 641 642 { 643 MutexLocker _(sChainLock); 644 645 chain = chain::Lookup(sReceivingProtocolChains, domain->family, 646 type, 0); 647 if (chain == NULL) 648 return B_ERROR; 649 } 650 651 chain->Release(); 652 return B_OK; 653 } 654 655 656 status_t 657 register_domain_protocols(int family, int type, int protocol, ...) 658 { 659 if (type == SOCK_RAW) { 660 // in SOCK_RAW mode, we ignore the protocol information 661 protocol = 0; 662 } 663 664 MutexLocker locker(&sChainLock); 665 666 struct chain* chain = chain::Lookup(sProtocolChains, family, type, protocol); 667 if (chain != NULL) 668 return B_OK; 669 670 va_list modules; 671 va_start(modules, protocol); 672 673 chain = chain::Add(sProtocolChains, family, type, protocol, modules); 674 675 va_end(modules); 676 677 if (chain == NULL) 678 return B_NO_MEMORY; 679 680 return B_OK; 681 } 682 683 684 status_t 685 register_domain_datalink_protocols(int family, int type, ...) 686 { 687 TRACE(("register_domain_datalink_protocol(%d.%d)\n", family, type)); 688 MutexLocker locker(&sChainLock); 689 690 struct chain* chain 691 = chain::Lookup(sDatalinkProtocolChains, family, type, 0); 692 if (chain != NULL) 693 return B_OK; 694 695 va_list modules; 696 va_start(modules, type); 697 698 chain = chain::Add(sDatalinkProtocolChains, family, type, 0, modules); 699 700 va_end(modules); 701 702 if (chain == NULL) 703 return B_NO_MEMORY; 704 705 // Add datalink interface protocol as the last protocol in the chain; it's 706 // name stays unset, so that it won't be part of the release/acquire process. 707 708 uint32 count = 0; 709 while (chain->modules[count] != NULL) { 710 count++; 711 } 712 713 chain->infos[count] = (module_info*)&gDatalinkInterfaceProtocolModule; 714 return B_OK; 715 } 716 717 718 static status_t 719 register_domain_receiving_protocol(int family, int type, const char* moduleName) 720 { 721 TRACE(("register_domain_receiving_protocol(%d.%d, %s)\n", family, type, 722 moduleName)); 723 724 MutexLocker _(sChainLock); 725 726 struct chain* chain 727 = chain::Lookup(sReceivingProtocolChains, family, type, 0); 728 if (chain != NULL) 729 return B_OK; 730 731 chain = chain::Add(sReceivingProtocolChains, family, type, 0, moduleName, 732 NULL); 733 if (chain == NULL) 734 return B_NO_MEMORY; 735 736 return B_OK; 737 } 738 739 740 static void 741 scan_modules(const char* path) 742 { 743 void* cookie = open_module_list(path); 744 if (cookie == NULL) 745 return; 746 747 Vector<module_info*> modules; 748 while (true) { 749 char name[B_FILE_NAME_LENGTH]; 750 size_t length = sizeof(name); 751 if (read_next_module_name(cookie, name, &length) != B_OK) 752 break; 753 754 TRACE(("scan %s\n", name)); 755 756 // we don't need the module right now, but we give it a chance 757 // to register itself 758 module_info* module; 759 if (get_module(name, &module) == B_OK) 760 modules.Add(module); 761 } 762 763 close_module_list(cookie); 764 765 // We don't need the modules right now, so put them all. 766 // (This is done at the end to avoid repeated loading/unloading of dependencies.) 767 for (int32 i = 0; i < modules.Count(); i++) 768 put_module(modules[i]->name); 769 } 770 771 772 status_t 773 init_stack() 774 { 775 status_t status = init_domains(); 776 if (status != B_OK) 777 return status; 778 779 status = init_interfaces(); 780 if (status != B_OK) 781 goto err1; 782 783 status = init_device_interfaces(); 784 if (status != B_OK) 785 goto err2; 786 787 status = init_timers(); 788 if (status != B_OK) 789 goto err3; 790 791 status = init_notifications(); 792 if (status < B_OK) { 793 // If this fails, it just means there won't be any notifications, 794 // it's not a fatal error. 795 dprintf("networking stack notifications could not be initialized: %s\n", 796 strerror(status)); 797 } 798 799 module_info* dummy; 800 status = get_module(NET_SOCKET_MODULE_NAME, &dummy); 801 if (status != B_OK) 802 goto err4; 803 804 mutex_init(&sChainLock, "net chains"); 805 mutex_init(&sInitializeChainLock, "net intialize chains"); 806 807 sFamilies = new(std::nothrow) FamilyTable(); 808 if (sFamilies == NULL || sFamilies->Init(10) != B_OK) { 809 status = B_NO_MEMORY; 810 goto err5; 811 } 812 813 sProtocolChains = new(std::nothrow) ChainTable(); 814 if (sProtocolChains == NULL || sProtocolChains->Init(10) != B_OK) { 815 status = B_NO_MEMORY; 816 goto err6; 817 } 818 819 sDatalinkProtocolChains = new(std::nothrow) ChainTable(); 820 if (sDatalinkProtocolChains == NULL 821 || sDatalinkProtocolChains->Init(10) != B_OK) { 822 status = B_NO_MEMORY; 823 goto err7; 824 } 825 826 sReceivingProtocolChains = new(std::nothrow) ChainTable(); 827 if (sReceivingProtocolChains == NULL 828 || sReceivingProtocolChains->Init(10) != B_OK) { 829 status = B_NO_MEMORY; 830 goto err8; 831 } 832 833 sInitialized = true; 834 835 link_init(); 836 scan_modules("network/protocols"); 837 scan_modules("network/datalink_protocols"); 838 839 // TODO: for now! 840 register_domain_datalink_protocols(AF_INET, IFT_LOOP, 841 "network/datalink_protocols/loopback_frame/v1", NULL); 842 register_domain_datalink_protocols(AF_INET, IFT_TUNNEL, 843 "network/datalink_protocols/loopback_frame/v1", NULL); 844 #if 0 // PPP is not (currently) included in the build 845 register_domain_datalink_protocols(AF_INET, IFT_PPP, 846 "network/datalink_protocols/ppp_frame/v1", NULL); 847 #endif 848 register_domain_datalink_protocols(AF_INET6, IFT_LOOP, 849 "network/datalink_protocols/loopback_frame/v1", NULL); 850 register_domain_datalink_protocols(AF_INET, IFT_ETHER, 851 "network/datalink_protocols/arp/v1", 852 "network/datalink_protocols/ethernet_frame/v1", 853 NULL); 854 register_domain_datalink_protocols(AF_INET6, IFT_ETHER, 855 "network/datalink_protocols/ipv6_datagram/v1", 856 "network/datalink_protocols/ethernet_frame/v1", 857 NULL); 858 859 return B_OK; 860 861 err8: 862 delete sDatalinkProtocolChains; 863 err7: 864 delete sProtocolChains; 865 err6: 866 delete sFamilies; 867 err5: 868 mutex_destroy(&sInitializeChainLock); 869 mutex_destroy(&sChainLock); 870 err4: 871 uninit_timers(); 872 err3: 873 uninit_device_interfaces(); 874 err2: 875 uninit_interfaces(); 876 err1: 877 uninit_domains(); 878 return status; 879 } 880 881 882 status_t 883 uninit_stack() 884 { 885 TRACE(("Unloading network stack\n")); 886 887 put_module(NET_SOCKET_MODULE_NAME); 888 uninit_notifications(); 889 890 // remove chains and families 891 892 chain::DeleteChains(sProtocolChains); 893 chain::DeleteChains(sDatalinkProtocolChains); 894 chain::DeleteChains(sReceivingProtocolChains); 895 896 mutex_destroy(&sChainLock); 897 mutex_destroy(&sInitializeChainLock); 898 899 uninit_timers(); 900 uninit_device_interfaces(); 901 uninit_interfaces(); 902 uninit_domains(); 903 904 struct family* current; 905 current = sFamilies->Clear(true); 906 while (current) { 907 struct family* next = current->next; 908 909 delete current; 910 current = next; 911 } 912 913 delete sProtocolChains; 914 delete sDatalinkProtocolChains; 915 delete sReceivingProtocolChains; 916 delete sFamilies; 917 918 return B_OK; 919 } 920 921 922 static status_t 923 stack_std_ops(int32 op, ...) 924 { 925 switch (op) { 926 case B_MODULE_INIT: 927 return sInitialized ? B_OK : B_BUSY; 928 case B_MODULE_UNINIT: 929 return B_OK; 930 931 default: 932 return B_ERROR; 933 } 934 } 935 936 937 net_stack_module_info gNetStackModule = { 938 { 939 NET_STACK_MODULE_NAME, 940 0, 941 stack_std_ops 942 }, 943 944 register_domain, 945 unregister_domain, 946 get_domain, 947 948 register_domain_protocols, 949 register_domain_datalink_protocols, 950 register_domain_receiving_protocol, 951 952 get_domain_receiving_protocol, 953 put_domain_receiving_protocol, 954 955 register_device_deframer, 956 unregister_device_deframer, 957 register_domain_device_handler, 958 register_device_handler, 959 unregister_device_handler, 960 register_device_monitor, 961 unregister_device_monitor, 962 device_link_changed, 963 device_removed, 964 device_enqueue_buffer, 965 966 notify_socket, 967 968 checksum, 969 970 init_fifo, 971 uninit_fifo, 972 fifo_enqueue_buffer, 973 fifo_dequeue_buffer, 974 clear_fifo, 975 fifo_socket_enqueue_buffer, 976 977 init_timer, 978 set_timer, 979 cancel_timer, 980 wait_for_timer, 981 is_timer_active, 982 is_timer_running, 983 984 is_syscall, 985 is_restarted_syscall, 986 store_syscall_restart_timeout, 987 restore_syscall_restart_timeout, 988 989 create_ancillary_data_container, 990 delete_ancillary_data_container, 991 add_ancillary_data, 992 remove_ancillary_data, 993 move_ancillary_data, 994 next_ancillary_data 995 }; 996 997 module_info* modules[] = { 998 (module_info*)&gNetStackModule, 999 (module_info*)&gNetBufferModule, 1000 (module_info*)&gNetSocketModule, 1001 (module_info*)&gNetDatalinkModule, 1002 (module_info*)&gLinkModule, 1003 (module_info*)&gNetStackInterfaceModule, 1004 NULL 1005 }; 1006