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