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