1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Description: 30 * 31 * Contains base code for netbios name service. 32 * 33 * 34 * 6. DEFINED CONSTANTS AND VARIABLES 35 * 36 * GENERAL: 37 * 38 * SCOPE_ID The name of the NetBIOS scope. 39 * 40 * This is expressed as a character 41 * string meeting the requirements of 42 * the domain name system and without 43 * a leading or trailing "dot". 44 * 45 * An implementation may elect to make 46 * this a single global value for the 47 * node or allow it to be specified 48 * with each separate NetBIOS name 49 * (thus permitting cross-scope 50 * references.) 51 * 52 * BROADCAST_ADDRESS An IP address composed of the 53 * nodes's network and subnetwork 54 * numbers with all remaining bits set 55 * to one. 56 * 57 * I.e. "Specific subnet" broadcast 58 * addressing according to section 2.3 59 * of RFC 950. 60 * 61 * BCAST_REQ_RETRY_TIMEOUT 250 milliseconds. 62 * An adaptive timer may be used. 63 * 64 * BCAST_REQ_RETRY_COUNT 3 65 * 66 * UCAST_REQ_RETRY_TIMEOUT 5 seconds 67 * An adaptive timer may be used. 68 * 69 * UCAST_REQ_RETRY_COUNT 3 70 * 71 * MAX_DATAGRAM_LENGTH 576 bytes (default) 72 * 73 * 74 * NAME SERVICE: 75 * 76 * REFRESH_TIMER Negotiated with NAME for each name. 77 * 78 * CONFLICT_TIMER 1 second 79 * Implementations may chose a longer 80 * value. 81 * 82 * 83 * NAME_SERVICE_TCP_PORT 137 (decimal) 84 * 85 * NAME_SERVICE_UDP_PORT 137 (decimal) 86 * 87 * INFINITE_TTL 0 88 */ 89 90 #include <unistd.h> 91 #include <syslog.h> 92 #include <stdlib.h> 93 #include <synch.h> 94 #include <errno.h> 95 #include <netdb.h> 96 #include <sys/socket.h> 97 #include <sys/sockio.h> 98 #include <arpa/inet.h> 99 #include <net/if_arp.h> 100 101 #include <smbsrv/libsmbns.h> 102 #include <smbns_netbios.h> 103 104 #define NAME_HEADER_SIZE 12 105 106 typedef struct name_reply { 107 struct name_reply *forw; 108 struct name_reply *back; 109 struct name_packet *packet; 110 struct addr_entry *addr; 111 unsigned short name_trn_id; 112 unsigned short flags; 113 } name_reply; 114 115 static struct name_reply reply_queue; 116 static mutex_t rq_mtx; 117 118 static mutex_t reply_mtx; 119 static cond_t reply_cv; 120 121 static name_queue_t delete_queue; 122 static name_queue_t refresh_queue; 123 124 /* 125 * Flag to control whether or not NetBIOS name refresh requests 126 * are logged. Set to non-zero to enable logging. 127 */ 128 129 static unsigned short netbios_name_transcation_id = 1; 130 static int name_sock = 0; 131 132 static int bcast_num = 0; 133 static int nbns_num = 0; 134 static struct addr_entry smb_bcast_list[SMB_PI_MAX_NETWORKS]; 135 static struct addr_entry smb_nbns[SMB_PI_MAX_WINS]; 136 137 static int smb_netbios_process_response(unsigned short, struct addr_entry *, 138 struct name_packet *, uint32_t); 139 140 static int smb_send_name_service_packet(struct addr_entry *addr, 141 struct name_packet *packet); 142 143 static int 144 smb_end_node_challenge(struct name_reply *reply_info) 145 { 146 int rc; 147 uint32_t retry; 148 unsigned short tid; 149 struct resource_record *answer; 150 struct name_question question; 151 struct addr_entry *addr; 152 struct name_entry *destination; 153 struct name_packet packet; 154 struct timespec st; 155 156 /* 157 * The response packet has in it the address of the presumed owner 158 * of the name. Challenge that owner. If owner either does not 159 * respond or indicates that he no longer owns the name, claim the 160 * name. Otherwise, the name cannot be claimed. 161 */ 162 163 if ((answer = reply_info->packet->answer) == 0) 164 return (-1); 165 166 destination = answer->name; 167 question.name = answer->name; 168 169 packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST; 170 packet.qdcount = 1; /* question entries */ 171 packet.question = &question; 172 packet.ancount = 0; /* answer recs */ 173 packet.answer = NULL; 174 packet.nscount = 0; /* authority recs */ 175 packet.authority = NULL; 176 packet.arcount = 0; /* additional recs */ 177 packet.additional = NULL; 178 179 addr = &destination->addr_list; 180 for (retry = 0; retry < UCAST_REQ_RETRY_COUNT; retry++) { 181 tid = netbios_name_transcation_id++; 182 packet.name_trn_id = tid; 183 if (smb_send_name_service_packet(addr, &packet) >= 0) { 184 if ((rc = smb_netbios_process_response(tid, addr, 185 &packet, UCAST_REQ_RETRY_TIMEOUT)) != 0) 186 return (rc); 187 } 188 st.tv_sec = 0; 189 st.tv_nsec = (UCAST_REQ_RETRY_TIMEOUT * 1000000); 190 (void) nanosleep(&st, 0); 191 } 192 /* No reply */ 193 return (0); 194 } 195 196 197 static struct name_reply * 198 smb_name_get_reply(unsigned short tid, uint32_t timeout) 199 { 200 unsigned short info; 201 struct resource_record *answer; 202 struct name_reply *reply; 203 uint32_t wait_time, to_save; /* in millisecond */ 204 struct timeval wt; 205 timestruc_t to; 206 207 to_save = timeout; 208 reply = (struct name_reply *)malloc(sizeof (struct name_reply)); 209 if (reply != 0) { 210 reply->flags = 0; 211 reply->name_trn_id = tid; 212 (void) mutex_lock(&rq_mtx); 213 QUEUE_INSERT_TAIL(&reply_queue, reply); 214 (void) mutex_unlock(&rq_mtx); 215 216 for (;;) { 217 (void) gettimeofday(&wt, 0); 218 wait_time = wt.tv_usec / 1000; 219 220 (void) mutex_lock(&reply_mtx); 221 to.tv_sec = 0; 222 to.tv_nsec = timeout * 1000000; 223 (void) cond_reltimedwait(&reply_cv, &reply_mtx, &to); 224 (void) mutex_unlock(&reply_mtx); 225 226 if (reply->flags != 0) { 227 info = reply->packet->info; 228 if (PACKET_TYPE(info) == WACK_RESPONSE) { 229 answer = reply->packet->answer; 230 wait_time = (answer) ? 231 TO_MILLISECONDS(answer->ttl) : 232 DEFAULT_TTL; 233 free(reply->addr); 234 free(reply->packet); 235 timeout = to_save + wait_time; 236 reply->flags = 0; 237 reply->name_trn_id = tid; 238 (void) mutex_lock(&rq_mtx); 239 QUEUE_INSERT_TAIL(&reply_queue, reply); 240 (void) mutex_unlock(&rq_mtx); 241 continue; 242 } 243 return (reply); 244 } 245 (void) gettimeofday(&wt, 0); 246 wait_time = (wt.tv_usec / 1000) - wait_time; 247 if (wait_time >= timeout) { 248 (void) mutex_lock(&rq_mtx); 249 QUEUE_CLIP(reply); 250 (void) mutex_unlock(&rq_mtx); 251 free(reply); 252 break; 253 } 254 timeout -= wait_time; 255 } 256 } 257 258 return (0); 259 } 260 261 static void 262 smb_reply_ready(struct name_packet *packet, struct addr_entry *addr) 263 { 264 struct name_reply *reply; 265 struct resource_record *answer; 266 267 (void) mutex_lock(&rq_mtx); 268 for (reply = reply_queue.forw; reply != &reply_queue; 269 reply = reply->forw) { 270 if (reply->name_trn_id == packet->name_trn_id) { 271 QUEUE_CLIP(reply); 272 (void) mutex_unlock(&rq_mtx); 273 274 reply->addr = addr; 275 reply->packet = packet; 276 277 (void) mutex_lock(&reply_mtx); 278 reply->flags |= 0x0001; /* reply ready */ 279 (void) cond_signal(&reply_cv); 280 (void) mutex_unlock(&reply_mtx); 281 282 return; 283 } 284 } 285 (void) mutex_unlock(&rq_mtx); 286 287 /* Presumably nobody is waiting any more... */ 288 free(addr); 289 290 answer = packet->answer; 291 if (answer) 292 smb_netbios_name_freeaddrs(answer->name); 293 free(packet); 294 } 295 296 static int 297 smb_netbios_process_response(unsigned short tid, struct addr_entry *addr, 298 struct name_packet *packet, uint32_t timeout) 299 { 300 int rc = 0; 301 unsigned short info; 302 struct name_reply *reply; 303 struct resource_record *answer; 304 struct name_entry *name; 305 struct name_entry *entry; 306 struct name_question *question; 307 uint32_t ttl; 308 309 if ((reply = smb_name_get_reply(tid, timeout)) == 0) { 310 return (0); /* No reply: retry */ 311 } 312 info = reply->packet->info; 313 answer = reply->packet->answer; 314 315 /* response */ 316 switch (PACKET_TYPE(info)) { 317 case NAME_QUERY_RESPONSE: 318 if (POSITIVE_RESPONSE(info)) { 319 addr = &answer->name->addr_list; 320 do { 321 /* 322 * Make sure that remote name is not 323 * flagged local 324 */ 325 addr->attributes &= ~NAME_ATTR_LOCAL; 326 327 addr->refresh_ttl = addr->ttl = 328 (answer && answer->ttl) ? 329 (answer->ttl >> 1) : 330 TO_SECONDS(DEFAULT_TTL); 331 addr = addr->forw; 332 } while (addr != &answer->name->addr_list); 333 smb_netbios_name_dump(answer->name); 334 (void) smb_netbios_cache_insert_list(answer->name); 335 rc = 1; 336 } else { 337 rc = -1; 338 } 339 break; 340 341 case NAME_REGISTRATION_RESPONSE: 342 if (NEGATIVE_RESPONSE(info)) { 343 if (RCODE(info) == RCODE_CFT_ERR) { 344 if (answer == 0) { 345 rc = -RCODE(info); 346 break; 347 } 348 349 name = answer->name; 350 entry = smb_netbios_cache_lookup(name); 351 if (entry) { 352 /* 353 * a name in the state "conflict 354 * detected" does not "logically" exist 355 * on that node. No further session 356 * will be accepted on that name. 357 * No datagrams can be sent against 358 * that name. 359 * Such an entry will not be used for 360 * purposes of processing incoming 361 * request packets. 362 * The only valid user NetBIOS operation 363 * against such a name is DELETE NAME. 364 */ 365 entry->attributes |= NAME_ATTR_CONFLICT; 366 syslog(LOG_DEBUG, 367 "NETBIOS Name conflict: %15.15s", 368 entry->name); 369 smb_netbios_cache_unlock_entry(entry); 370 } 371 } 372 rc = -RCODE(info); 373 break; 374 } 375 376 /* 377 * name can be added: 378 * adjust refresh timeout value, 379 * TTL, for this name 380 */ 381 question = packet->question; 382 ttl = (answer && answer->ttl) ? answer->ttl >> 1 383 : TO_SECONDS(DEFAULT_TTL); 384 if ((entry = smb_netbios_cache_lookup(question->name)) != 0) { 385 addr = &entry->addr_list; 386 do { 387 if ((addr->refresh_ttl == 0) || 388 (ttl < addr->refresh_ttl)) 389 addr->refresh_ttl = addr->ttl = ttl; 390 addr = addr->forw; 391 } while (addr != &entry->addr_list); 392 smb_netbios_cache_unlock_entry(entry); 393 } 394 395 rc = 1; 396 break; 397 398 case NAME_RELEASE_RESPONSE: 399 rc = 1; 400 break; 401 402 case END_NODE_CHALLENGE_REGISTRATION_REQUEST: 403 /* 404 * The response packet has in it the 405 * address of the presumed owner of the 406 * name. Challenge that owner. If 407 * owner either does not respond or 408 * indicates that he no longer owns the 409 * name, claim the name. Otherwise, 410 * the name cannot be claimed. 411 */ 412 rc = smb_end_node_challenge(reply); 413 break; 414 415 default: 416 rc = 0; 417 break; 418 } 419 420 if (answer) 421 smb_netbios_name_freeaddrs(answer->name); 422 free(reply->addr); 423 free(reply->packet); 424 free(reply); 425 return (rc); /* retry */ 426 } 427 428 /* 429 * smb_name_buf_from_packet 430 * 431 * Description: 432 * Convert a NetBIOS Name Server Packet Block (npb) 433 * into the bits and bytes destined for the wire. 434 * The "buf" is used as a heap. 435 * 436 * Inputs: 437 * char * buf -> Buffer, from the wire 438 * unsigned n_buf -> Length of 'buf' 439 * name_packet *npb -> Packet block, decode into 440 * unsigned n_npb -> Max bytes in 'npb' 441 * 442 * Returns: 443 * >0 -> Encode successful, value is length of packet in "buf" 444 * -1 -> Hard error, can not possibly encode 445 * -2 -> Need more memory in buf -- it's too small 446 */ 447 448 static int 449 smb_name_buf_from_packet(unsigned char *buf, 450 int n_buf, 451 struct name_packet *npb) 452 { 453 struct addr_entry *raddr; 454 unsigned char *heap = buf; 455 unsigned char *end_heap = heap + n_buf; 456 unsigned char *dnptrs[32]; 457 unsigned char comp_name_buf[MAX_NAME_LENGTH]; 458 unsigned int tmp; 459 int i, step; 460 461 if (n_buf < NAME_HEADER_SIZE) 462 return (-1); /* no header, impossible */ 463 464 dnptrs[0] = heap; 465 dnptrs[1] = 0; 466 467 BE_OUT16(heap, npb->name_trn_id); 468 heap += 2; 469 470 BE_OUT16(heap, npb->info); 471 heap += 2; 472 473 BE_OUT16(heap, npb->qdcount); 474 heap += 2; 475 476 BE_OUT16(heap, npb->ancount); 477 heap += 2; 478 479 BE_OUT16(heap, npb->nscount); 480 heap += 2; 481 482 BE_OUT16(heap, npb->arcount); 483 heap += 2; 484 485 for (i = 0; i < npb->qdcount; i++) { 486 if ((heap + 34 + 4) > end_heap) 487 return (-2); 488 489 (void) smb_first_level_name_encode(npb->question[i].name, 490 comp_name_buf, sizeof (comp_name_buf)); 491 (void) strcpy((char *)heap, (char *)comp_name_buf); 492 heap += strlen((char *)comp_name_buf) + 1; 493 494 BE_OUT16(heap, npb->question[i].question_type); 495 heap += 2; 496 497 BE_OUT16(heap, npb->question[i].question_class); 498 heap += 2; 499 } 500 501 for (step = 1; step <= 3; step++) { 502 struct resource_record *nrr; 503 int n; 504 505 /* truly ugly, but saves code copying */ 506 if (step == 1) { 507 n = npb->ancount; 508 nrr = npb->answer; 509 } else if (step == 2) { 510 n = npb->nscount; 511 nrr = npb->authority; 512 } else { /* step == 3 */ 513 n = npb->arcount; 514 nrr = npb->additional; 515 } 516 517 for (i = 0; i < n; i++) { 518 if ((heap + 34 + 10) > end_heap) 519 return (-2); 520 521 (void) smb_first_level_name_encode(nrr->name, 522 comp_name_buf, sizeof (comp_name_buf)); 523 (void) strcpy((char *)heap, (char *)comp_name_buf); 524 heap += strlen((char *)comp_name_buf) + 1; 525 526 BE_OUT16(heap, nrr[i].rr_type); 527 heap += 2; 528 529 BE_OUT16(heap, nrr[i].rr_class); 530 heap += 2; 531 532 BE_OUT32(heap, nrr[i].ttl); 533 heap += 4; 534 535 BE_OUT16(heap, nrr[i].rdlength); 536 heap += 2; 537 538 if ((tmp = nrr[i].rdlength) > 0) { 539 if ((heap + tmp) > end_heap) 540 return (-2); 541 542 if (nrr[i].rr_type == NAME_RR_TYPE_NB && 543 nrr[i].rr_class == NAME_RR_CLASS_IN && 544 tmp >= 6 && nrr[i].rdata == 0) { 545 tmp = nrr[i].name->attributes & 546 (NAME_ATTR_GROUP | 547 NAME_ATTR_OWNER_NODE_TYPE); 548 BE_OUT16(heap, tmp); 549 heap += 2; 550 551 raddr = &nrr[i].name->addr_list; 552 (void) memcpy(heap, 553 &raddr->sin.sin_addr.s_addr, 554 sizeof (uint32_t)); 555 heap += 4; 556 } else { 557 bcopy(nrr[i].rdata, heap, tmp); 558 heap += tmp; 559 } 560 } 561 } 562 } 563 return (heap - buf); 564 } 565 566 /* 567 * strnchr 568 * 569 * Lookup for character 'c' in first 'n' chars of string 's'. 570 * Returns pointer to the found char, otherwise returns 0. 571 */ 572 static char * 573 strnchr(const char *s, char c, int n) 574 { 575 char *ps = (char *)s; 576 char *es = (char *)s + n; 577 578 while (ps < es && *ps) { 579 if (*ps == c) 580 return (ps); 581 582 ++ps; 583 } 584 585 if (*ps == '\0' && c == '\0') 586 return (ps); 587 588 return (0); 589 } 590 591 /*ARGSUSED*/ 592 static int 593 is_multihome(char *name) 594 { 595 return ((smb_nic_get_num() > 1) ? 1 : 0); 596 } 597 598 /* 599 * smb_netbios_getname 600 * 601 * Get the Netbios name part of the given record. 602 * Does some boundary checks. 603 * 604 * Returns the name length on success, otherwise 605 * returns 0. 606 */ 607 static int 608 smb_netbios_getname(char *name, char *buf, char *buf_end) 609 { 610 char *name_end; 611 int name_len; 612 613 if (buf >= buf_end) { 614 /* no room for a NB name */ 615 return (0); 616 } 617 618 name_end = strnchr(buf, '\0', buf_end - buf + 1); 619 if (name_end == 0) { 620 /* not a valid NB name */ 621 return (0); 622 } 623 624 name_len = name_end - buf + 1; 625 626 (void) strlcpy(name, buf, name_len); 627 return (name_len); 628 } 629 630 631 /* 632 * smb_name_buf_to_packet 633 * 634 * Description: 635 * Convert the bits and bytes that came from the wire 636 * into a NetBIOS Name Server Packet Block (npb). 637 * The "block" is used as a heap. 638 * 639 * Inputs: 640 * char * buf -> Buffer, from the wire 641 * int n_buf -> Length of 'buf' 642 * name_packet *npb -> Packet block, decode into 643 * int n_npb -> Max bytes in 'npb' 644 * 645 * Returns: 646 * >0 -> Decode (parse) successful, value is byte length of npb 647 * -1 -> Hard error, can not possibly decode 648 * -2 -> Need more memory in npb -- it's too small 649 */ 650 651 static struct name_packet * 652 smb_name_buf_to_packet(char *buf, int n_buf) 653 { 654 struct name_packet *npb; 655 unsigned char *heap; 656 unsigned char *scan = (unsigned char *)buf; 657 unsigned char *scan_end = scan + n_buf; 658 char name_buf[MAX_NAME_LENGTH]; 659 struct resource_record *nrr = 0; 660 int rc, i, n, nn, ns; 661 unsigned short name_trn_id, info; 662 unsigned short qdcount, ancount, nscount, arcount; 663 struct addr_entry *next; 664 int name_len; 665 666 if (n_buf < NAME_HEADER_SIZE) { 667 /* truncated header */ 668 syslog(LOG_DEBUG, "SmbNBNS: packet is too short (%d)", 669 n_buf); 670 return (0); 671 } 672 673 name_trn_id = BE_IN16(scan); scan += 2; 674 info = BE_IN16(scan); scan += 2; 675 qdcount = BE_IN16(scan); scan += 2; 676 ancount = BE_IN16(scan); scan += 2; 677 nscount = BE_IN16(scan); scan += 2; 678 arcount = BE_IN16(scan); scan += 2; 679 680 ns = sizeof (struct name_entry); 681 n = n_buf + sizeof (struct name_packet) + 682 ((unsigned)qdcount * (sizeof (struct name_question) + ns)) + 683 ((unsigned)ancount * (sizeof (struct resource_record) + ns)) + 684 ((unsigned)nscount * (sizeof (struct resource_record) + ns)) + 685 ((unsigned)arcount * (sizeof (struct resource_record) + ns)); 686 687 if ((npb = (struct name_packet *)malloc(n)) == 0) { 688 return (0); 689 } 690 bzero(npb, n); 691 692 heap = npb->block_data; 693 npb->name_trn_id = name_trn_id; 694 npb->info = info; 695 npb->qdcount = qdcount; 696 npb->ancount = ancount; 697 npb->nscount = nscount; 698 npb->arcount = arcount; 699 700 /* scan is in position for question entries */ 701 702 /* 703 * Measure the space needed for the tables 704 */ 705 if (qdcount > 0) { 706 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 707 npb->question = (struct name_question *)heap; 708 heap += qdcount * sizeof (struct name_question); 709 for (i = 0; i < qdcount; i++) { 710 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 711 npb->question[i].name = (struct name_entry *)heap; 712 heap += sizeof (struct name_entry); 713 } 714 } 715 716 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 717 nrr = (struct resource_record *)heap; 718 719 if (ancount > 0) { 720 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 721 npb->answer = (struct resource_record *)heap; 722 heap += ancount * sizeof (struct resource_record); 723 } 724 725 if (nscount > 0) { 726 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 727 npb->authority = (struct resource_record *)heap; 728 heap += nscount * sizeof (struct resource_record); 729 } 730 731 if (arcount > 0) { 732 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 733 npb->additional = (struct resource_record *)heap; 734 heap += arcount * sizeof (struct resource_record); 735 } 736 737 /* 738 * Populate each resource_record's .name field. 739 * Done as a second pass so that all resource records 740 * (answer, authority, additional) are consecutive via nrr[i]. 741 */ 742 for (i = 0; i < (ancount + nscount + arcount); i++) { 743 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 744 nrr[i].name = (struct name_entry *)heap; 745 heap += sizeof (struct name_entry); 746 } 747 748 749 for (i = 0; i < npb->qdcount; i++) { 750 name_len = smb_netbios_getname(name_buf, (char *)scan, 751 (char *)scan_end); 752 if (name_len <= 0) { 753 free(npb); 754 return (0); 755 } 756 757 smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0, 758 npb->question[i].name); 759 rc = smb_first_level_name_decode((unsigned char *)name_buf, 760 npb->question[i].name); 761 if (rc < 0) { 762 /* Couldn't decode the question name */ 763 free(npb); 764 return (0); 765 } 766 767 scan += name_len; 768 if (scan + 4 > scan_end) { 769 /* no room for Question Type(2) and Class(2) fields */ 770 free(npb); 771 return (0); 772 } 773 774 npb->question[i].question_type = BE_IN16(scan); scan += 2; 775 npb->question[i].question_class = BE_IN16(scan); scan += 2; 776 } 777 778 /* 779 * Cheat. Remaining sections are of the same resource_record 780 * format. Table space is consecutive. 781 */ 782 783 for (i = 0; i < (ancount + nscount + arcount); i++) { 784 if (scan[0] == 0xc0) { 785 /* Namebuf is reused... */ 786 rc = 2; 787 } else { 788 name_len = smb_netbios_getname(name_buf, (char *)scan, 789 (char *)scan_end); 790 if (name_len <= 0) { 791 free(npb); 792 return (0); 793 } 794 rc = name_len; 795 } 796 scan += rc; 797 798 if (scan + 10 > scan_end) { 799 /* 800 * no room for RR_TYPE (2), RR_CLASS (2), TTL (4) and 801 * RDLENGTH (2) fields. 802 */ 803 free(npb); 804 return (0); 805 } 806 807 smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0, 808 nrr[i].name); 809 if ((rc = smb_first_level_name_decode((unsigned char *)name_buf, 810 nrr[i].name)) < 0) { 811 free(npb); 812 return (0); 813 } 814 815 nrr[i].rr_type = BE_IN16(scan); scan += 2; 816 nrr[i].rr_class = BE_IN16(scan); scan += 2; 817 nrr[i].ttl = BE_IN32(scan); scan += 4; 818 nrr[i].rdlength = BE_IN16(scan); scan += 2; 819 820 if ((n = nrr[i].rdlength) > 0) { 821 if ((scan + n) > scan_end) { 822 /* no room for RDATA */ 823 free(npb); 824 return (0); 825 } 826 bcopy(scan, heap, n); 827 828 nn = n; 829 if (nrr[i].rr_type == 0x0020 && 830 nrr[i].rr_class == 0x01 && n >= 6) { 831 while (nn) { 832 if (nn == 6) 833 next = &nrr[i].name->addr_list; 834 else { 835 next = (struct addr_entry *) 836 malloc( 837 sizeof (struct addr_entry)); 838 if (next == 0) { 839 /* not enough memory */ 840 free(npb); 841 return (0); 842 } 843 QUEUE_INSERT_TAIL( 844 &nrr[i].name->addr_list, 845 next); 846 } 847 nrr[i].name->attributes = 848 BE_IN16(scan); 849 next->sin.sin_family = AF_INET; 850 next->sinlen = sizeof (next->sin); 851 (void) memcpy( 852 &next->sin.sin_addr.s_addr, 853 scan + 2, sizeof (uint32_t)); 854 next->sin.sin_port = 855 htons(DGM_SRVC_UDP_PORT); 856 nn -= 6; 857 scan += 6; 858 } 859 } else { 860 nrr[i].rdata = heap; 861 scan += n; 862 } 863 heap += n; 864 } 865 } 866 return (npb); 867 } 868 869 870 /* 871 * smb_send_name_service_packet 872 * 873 * Description: 874 * 875 * Send out a name service packet to proper destination. 876 * 877 * Inputs: 878 * struct netbios_name *dest -> NETBIOS name of destination 879 * struct name_packet *packet -> Packet to send 880 * 881 * Returns: 882 * success -> >0 883 * failure -> <=0 884 */ 885 886 static int 887 smb_send_name_service_packet(struct addr_entry *addr, 888 struct name_packet *packet) 889 { 890 unsigned char buf[MAX_DATAGRAM_LENGTH]; 891 int len; 892 893 if ((len = smb_name_buf_from_packet(buf, sizeof (buf), packet)) < 0) { 894 errno = EINVAL; 895 return (-1); 896 } 897 898 return (sendto(name_sock, buf, len, MSG_EOR, 899 (struct sockaddr *)&addr->sin, addr->sinlen)); 900 } 901 902 /* 903 * 4.2.1.1. HEADER 904 * 905 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 906 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 907 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 908 * | NAME_TRN_ID | OPCODE | NM_FLAGS | RCODE | 909 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 910 * | QDCOUNT | ANCOUNT | 911 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 912 * | NSCOUNT | ARCOUNT | 913 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 914 * 915 * Field Description 916 * 917 * NAME_TRN_ID Transaction ID for Name Service Transaction. 918 * Requester places a unique value for each active 919 * transaction. Responder puts NAME_TRN_ID value 920 * from request packet in response packet. 921 * 922 * OPCODE Packet type code, see table below. 923 * 924 * NM_FLAGS Flags for operation, see table below. 925 * 926 * RCODE Result codes of request. Table of RCODE values 927 * for each response packet below. 928 * 929 * QDCOUNT Unsigned 16 bit integer specifying the number of 930 * entries in the question section of a Name 931 * 932 * Service packet. Always zero (0) for responses. 933 * Must be non-zero for all NetBIOS Name requests. 934 * 935 * ANCOUNT Unsigned 16 bit integer specifying the number of 936 * resource records in the answer section of a Name 937 * Service packet. 938 * 939 * NSCOUNT Unsigned 16 bit integer specifying the number of 940 * resource records in the authority section of a 941 * Name Service packet. 942 * 943 * ARCOUNT Unsigned 16 bit integer specifying the number of 944 * resource records in the additional records 945 * section of a Name Service packet. 946 * 947 * The OPCODE field is defined as: 948 * 949 * 0 1 2 3 4 950 * +---+---+---+---+---+ 951 * | R | OPCODE | 952 * +---+---+---+---+---+ 953 * 954 * Symbol Bit(s) Description 955 * 956 * OPCODE 1-4 Operation specifier: 957 * 0 = query 958 * 5 = registration 959 * 6 = release 960 * 7 = WACK 961 * 8 = refresh 962 * 963 * R 0 RESPONSE flag: 964 * if bit == 0 then request packet 965 * if bit == 1 then response packet. 966 */ 967 968 969 /* 970 * The NM_FLAGS field is defined as: 971 * 972 * 973 * 0 1 2 3 4 5 6 974 * +---+---+---+---+---+---+---+ 975 * |AA |TC |RD |RA | 0 | 0 | B | 976 * +---+---+---+---+---+---+---+ 977 * 978 * Symbol Bit(s) Description 979 * 980 * B 6 Broadcast Flag. 981 * = 1: packet was broadcast or multicast 982 * = 0: unicast 983 * 984 * RA 3 Recursion Available Flag. 985 * 986 * Only valid in responses from a NetBIOS Name 987 * Server -- must be zero in all other 988 * responses. 989 * 990 * If one (1) then the NAME supports recursive 991 * query, registration, and release. 992 * 993 * If zero (0) then the end-node must iterate 994 * for query and challenge for registration. 995 * 996 * RD 2 Recursion Desired Flag. 997 * 998 * May only be set on a request to a NetBIOS 999 * Name Server. 1000 * 1001 * The NAME will copy its state into the 1002 * response packet. 1003 * 1004 * If one (1) the NAME will iterate on the 1005 * query, registration, or release. 1006 * 1007 * TC 1 Truncation Flag. 1008 * 1009 * Set if this message was truncated because the 1010 * datagram carrying it would be greater than 1011 * 576 bytes in length. Use TCP to get the 1012 * information from the NetBIOS Name Server. 1013 * 1014 * AA 0 Authoritative Answer flag. 1015 * 1016 * Must be zero (0) if R flag of OPCODE is zero 1017 * (0). 1018 * 1019 * If R flag is one (1) then if AA is one (1) 1020 * then the node responding is an authority for 1021 * the domain name. 1022 * 1023 * End nodes responding to queries always set 1024 * this bit in responses. 1025 * 1026 */ 1027 1028 /* 1029 * 4.2.1.2. QUESTION SECTION 1030 * 1031 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1032 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1033 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1034 * | | 1035 * / QUESTION_NAME / 1036 * / / 1037 * | | 1038 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1039 * | QUESTION_TYPE | QUESTION_CLASS | 1040 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1041 * 1042 * Field Description 1043 * 1044 * QUESTION_NAME The compressed name representation of the 1045 * NetBIOS name for the request. 1046 * 1047 * QUESTION_TYPE The type of request. The values for this field 1048 * are specified for each request. 1049 * 1050 * QUESTION_CLASS The class of the request. The values for this 1051 * field are specified for each request. 1052 * 1053 * QUESTION_TYPE is defined as: 1054 * 1055 * Symbol Value Description: 1056 * 1057 * NB 0x0020 NetBIOS general Name Service Resource Record 1058 * NBSTAT 0x0021 NetBIOS NODE STATUS Resource Record (See NODE 1059 * STATUS REQUEST) 1060 * 1061 * QUESTION_CLASS is defined as: 1062 * 1063 * Symbol Value Description: 1064 * 1065 * IN 0x0001 Internet class 1066 */ 1067 1068 #define QUESTION_TYPE_NETBIOS_GENERAL 0x20 1069 #define QUESTION_TYPE_NETBIOS_STATUS 0x21 1070 1071 #define QUESTION_CLASS_INTERNET 0x0001 1072 1073 /* 1074 * 1075 * 4.2.1.3. RESOURCE RECORD 1076 * 1077 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1078 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1079 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1080 * | | 1081 * / RR_NAME / 1082 * / / 1083 * | | 1084 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1085 * | RR_TYPE | RR_CLASS | 1086 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1087 * | TTL | 1088 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1089 * | RDLENGTH | | 1090 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 1091 * / / 1092 * / RDATA / 1093 * | | 1094 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1095 * 1096 * Field Description 1097 * 1098 * RR_NAME The compressed name representation of the 1099 * NetBIOS name corresponding to this resource 1100 * record. 1101 * 1102 * RR_TYPE Resource record type code 1103 * 1104 * RR_CLASS Resource record class code 1105 * 1106 * TTL The Time To Live of a the resource record's 1107 * name. 1108 * 1109 * RDLENGTH Unsigned 16 bit integer that specifies the 1110 * number of bytes in the RDATA field. 1111 * 1112 * RDATA RR_CLASS and RR_TYPE dependent field. Contains 1113 * the resource information for the NetBIOS name. 1114 * 1115 * RESOURCE RECORD RR_TYPE field definitions: 1116 * 1117 * Symbol Value Description: 1118 * 1119 * A 0x0001 IP address Resource Record (See REDIRECT NAME 1120 * QUERY RESPONSE) 1121 * NS 0x0002 Name Server Resource Record (See REDIRECT 1122 * NAME QUERY RESPONSE) 1123 * NULL 0x000A NULL Resource Record (See WAIT FOR 1124 * ACKNOWLEDGEMENT RESPONSE) 1125 * NB 0x0020 NetBIOS general Name Service Resource Record 1126 * (See NB_FLAGS and NB_ADDRESS, below) 1127 * NBSTAT 0x0021 NetBIOS NODE STATUS Resource Record (See NODE 1128 * STATUS RESPONSE) 1129 */ 1130 1131 #define RR_TYPE_IP_ADDRESS_RESOURCE 0x0001 1132 #define RR_TYPE_NAME_SERVER_RESOURCE 0x0002 1133 #define RR_TYPE_NULL_RESOURCE 0x000A 1134 #define RR_TYPE_NETBIOS_RESOURCE 0x0020 1135 #define RR_TYPE_NETBIOS_STATUS 0x0021 1136 1137 /* 1138 * 1139 * RESOURCE RECORD RR_CLASS field definitions: 1140 * 1141 * Symbol Value Description: 1142 * 1143 * IN 0x0001 Internet class 1144 */ 1145 #define RR_CLASS_INTERNET_CLASS 0x0001 1146 1147 /* 1148 * 1149 * NB_FLAGS field of the RESOURCE RECORD RDATA field for RR_TYPE of 1150 * "NB": 1151 * 1152 * 1 1 1 1 1 1 1153 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 1154 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 1155 * | G | ONT | RESERVED | 1156 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 1157 * 1158 * Symbol Bit(s) Description: 1159 * 1160 * RESERVED 3-15 Reserved for future use. Must be zero (0). 1161 * ONT 1,2 Owner Node Type: 1162 * 00 = B node 1163 * 01 = P node 1164 * 10 = M node 1165 * 11 = Reserved for future use 1166 * For registration requests this is the 1167 * claimant's type. 1168 * For responses this is the actual owner's 1169 * type. 1170 * 1171 * G 0 Group Name Flag. 1172 * If one (1) then the RR_NAME is a GROUP 1173 * NetBIOS name. 1174 * If zero (0) then the RR_NAME is a UNIQUE 1175 * NetBIOS name. 1176 * 1177 * The NB_ADDRESS field of the RESOURCE RECORD RDATA field for 1178 * RR_TYPE of "NB" is the IP address of the name's owner. 1179 * 1180 */ 1181 #define RR_FLAGS_NB_ONT_MASK 0x6000 1182 #define RR_FLAGS_NB_ONT_B_NODE 0x0000 1183 #define RR_FLAGS_NB_ONT_P_NODE 0x2000 1184 #define RR_FLAGS_NB_ONT_M_NODE 0x4000 1185 #define RR_FLAGS_NB_ONT_RESERVED 0x6000 1186 1187 #define RR_FLAGS_NB_GROUP_NAME 0x8000 1188 1189 /* 1190 * smb_netbios_send_rcv 1191 * 1192 * This function sends the given NetBIOS packet to the given 1193 * address and get back the response. If send operation is not 1194 * successful, it's repeated 'retries' times. 1195 * 1196 * Returns: 1197 * 0 Unsuccessful send operation; no reply 1198 * 1 Got reply 1199 */ 1200 static int 1201 smb_netbios_send_rcv(int bcast, struct addr_entry *destination, 1202 struct name_packet *packet, 1203 uint32_t retries, uint32_t timeout) 1204 { 1205 uint32_t retry; 1206 unsigned short tid; 1207 struct timespec st; 1208 int rc; 1209 1210 for (retry = 0; retry < retries; retry++) { 1211 if ((destination->flags & ADDR_FLAG_VALID) == 0) 1212 return (0); 1213 1214 tid = netbios_name_transcation_id++; 1215 packet->name_trn_id = tid; 1216 if (smb_send_name_service_packet(destination, packet) >= 0) { 1217 rc = smb_netbios_process_response(tid, destination, 1218 packet, timeout); 1219 1220 if ((rc > 0) || (bcast == BROADCAST)) 1221 return (1); 1222 1223 if (rc != 0) 1224 return (0); 1225 } 1226 1227 st.tv_sec = 0; 1228 st.tv_nsec = (timeout * 1000000); 1229 (void) nanosleep(&st, 0); 1230 } 1231 1232 return (0); 1233 } 1234 1235 /* 1236 * 4.2.2. NAME REGISTRATION REQUEST 1237 * 1238 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1239 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1240 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1241 * | NAME_TRN_ID |0| 0x5 |0|0|1|0|0 0|B| 0x0 | 1242 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1243 * | 0x0001 | 0x0000 | 1244 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1245 * | 0x0000 | 0x0001 | 1246 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1247 * | | 1248 * / QUESTION_NAME / 1249 * / / 1250 * | | 1251 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1252 * | NB (0x0020) | IN (0x0001) | 1253 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1254 * | | 1255 * / RR_NAME / 1256 * / / 1257 * | | 1258 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1259 * | NB (0x0020) | IN (0x0001) | 1260 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1261 * | TTL | 1262 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1263 * | 0x0006 | NB_FLAGS | 1264 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1265 * | NB_ADDRESS | 1266 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1267 * 1268 * Since the RR_NAME is the same name as the QUESTION_NAME, the 1269 * RR_NAME representation must use pointers to the QUESTION_NAME 1270 * name's labels to guarantee the length of the datagram is less 1271 * than the maximum 576 bytes. See section above on name formats 1272 * and also page 31 and 32 of RFC 883, Domain Names - Implementation 1273 * and Specification, for a complete description of compressed name 1274 * label pointers. 1275 */ 1276 static int 1277 smb_send_name_registration_request(int bcast, struct name_question *question, 1278 struct resource_record *additional) 1279 { 1280 int gotreply = 0; 1281 uint32_t retries; 1282 uint32_t timeout; 1283 struct addr_entry *destination; 1284 struct name_packet packet; 1285 unsigned char type; 1286 int i, addr_num, rc; 1287 1288 type = question->name->name[15]; 1289 if ((type != 0x00) && (type != 0x20)) { 1290 syslog(LOG_ERR, "netbios: error trying to register" 1291 " non-local name"); 1292 smb_netbios_name_logf(question->name); 1293 question->name->attributes &= ~NAME_ATTR_LOCAL; 1294 return (-1); 1295 } 1296 1297 if (bcast == BROADCAST) { 1298 if (bcast_num == 0) 1299 return (0); 1300 destination = smb_bcast_list; 1301 addr_num = bcast_num; 1302 retries = BCAST_REQ_RETRY_COUNT; 1303 timeout = BCAST_REQ_RETRY_TIMEOUT; 1304 packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_BROADCAST; 1305 } else { 1306 if (nbns_num == 0) 1307 return (0); 1308 destination = smb_nbns; 1309 addr_num = nbns_num; 1310 retries = UCAST_REQ_RETRY_COUNT; 1311 timeout = UCAST_REQ_RETRY_TIMEOUT; 1312 packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_UNICAST; 1313 } 1314 1315 packet.qdcount = 1; /* question entries */ 1316 packet.question = question; 1317 packet.ancount = 0; /* answer recs */ 1318 packet.answer = NULL; 1319 packet.nscount = 0; /* authority recs */ 1320 packet.authority = NULL; 1321 packet.arcount = 1; /* additional recs */ 1322 packet.additional = additional; 1323 1324 if (IS_UNIQUE(question->name->attributes) && 1325 (is_multihome((char *)(question->name->name)))) 1326 packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST; 1327 1328 for (i = 0; i < addr_num; i++) { 1329 /* 1330 * Only register with the Primary WINS server, 1331 * unless we got no reply. 1332 */ 1333 if ((bcast == UNICAST) && gotreply) 1334 break; 1335 1336 rc = smb_netbios_send_rcv(bcast, &destination[i], &packet, 1337 retries, timeout); 1338 if (rc == 1) 1339 gotreply = 1; 1340 } 1341 1342 return (gotreply); 1343 } 1344 1345 /* 1346 * 1347 * 4.2.4. NAME REFRESH REQUEST 1348 * 1349 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1350 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1351 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1352 * | NAME_TRN_ID |0| 0x8 |0|0|0|0|0 0|B| 0x0 | 1353 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1354 * | 0x0001 | 0x0000 | 1355 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1356 * | 0x0000 | 0x0001 | 1357 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1358 * | | 1359 * / QUESTION_NAME / 1360 * / / 1361 * | | 1362 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1363 * | NB (0x0020) | IN (0x0001) | 1364 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1365 * | | 1366 * / RR_NAME / 1367 * / / 1368 * | | 1369 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1370 * | NB (0x0020) | IN (0x0001) | 1371 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1372 * | TTL | 1373 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1374 * | 0x0006 | NB_FLAGS | 1375 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1376 * | NB_ADDRESS | 1377 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1378 */ 1379 /*ARGSUSED*/ 1380 static int 1381 smb_send_name_refresh_request(int bcast, struct name_question *question, 1382 struct resource_record *additional, int force) 1383 { 1384 int rc = 0; 1385 int gotreply = 0; 1386 uint32_t retries; 1387 uint32_t timeout; 1388 struct addr_entry *addr; 1389 struct addr_entry *destination; 1390 struct name_packet packet; 1391 unsigned char type; 1392 int i, addr_num, q_addrs = 0; 1393 1394 type = question->name->name[15]; 1395 if ((type != 0x00) && (type != 0x20)) { 1396 syslog(LOG_ERR, "attempt to refresh non-local name"); 1397 smb_netbios_name_logf(question->name); 1398 question->name->attributes &= ~NAME_ATTR_LOCAL; 1399 return (-1); 1400 } 1401 switch (bcast) { 1402 case BROADCAST : 1403 if (bcast_num == 0) 1404 return (-1); 1405 destination = smb_bcast_list; 1406 addr_num = bcast_num; 1407 retries = BCAST_REQ_RETRY_COUNT; 1408 timeout = BCAST_REQ_RETRY_TIMEOUT; 1409 packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_BROADCAST; 1410 break; 1411 1412 case UNICAST : 1413 if (nbns_num == 0) 1414 return (-1); 1415 destination = smb_nbns; 1416 addr_num = nbns_num; 1417 retries = UCAST_REQ_RETRY_COUNT; 1418 timeout = UCAST_REQ_RETRY_TIMEOUT; 1419 packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST; 1420 break; 1421 1422 default: 1423 destination = &question->name->addr_list; 1424 /* 1425 * the value of addr_num is irrelvant here, because 1426 * the code is going to do special_process so it doesn't 1427 * need the addr_num. We set a value here just to avoid 1428 * compiler warning. 1429 */ 1430 addr_num = 0; 1431 retries = UCAST_REQ_RETRY_COUNT; 1432 timeout = UCAST_REQ_RETRY_TIMEOUT; 1433 packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST; 1434 q_addrs = 1; 1435 break; 1436 } 1437 1438 if (IS_UNIQUE(question->name->attributes) && 1439 (is_multihome((char *)(question->name->name)))) 1440 packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST; 1441 1442 packet.qdcount = 1; /* question entries */ 1443 packet.question = question; 1444 packet.ancount = 0; /* answer recs */ 1445 packet.answer = NULL; 1446 packet.nscount = 0; /* authority recs */ 1447 packet.authority = NULL; 1448 packet.arcount = 1; /* additional recs */ 1449 packet.additional = additional; 1450 1451 if (q_addrs) 1452 goto special_process; 1453 1454 for (i = 0; i < addr_num; i++) { 1455 rc = smb_netbios_send_rcv(bcast, &destination[i], &packet, 1456 retries, timeout); 1457 if (rc == 1) 1458 gotreply = 1; 1459 } 1460 1461 return (gotreply); 1462 1463 special_process: 1464 addr = destination; 1465 do { 1466 rc = smb_netbios_send_rcv(bcast, addr, &packet, 1467 retries, timeout); 1468 if (rc == 1) 1469 gotreply = 1; 1470 addr = addr->forw; 1471 } while (addr != destination); 1472 1473 return (gotreply); 1474 } 1475 1476 /* 1477 * 4.2.5. POSITIVE NAME REGISTRATION RESPONSE 1478 * 1479 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1480 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1481 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1482 * | NAME_TRN_ID |1| 0x5 |1|0|1|1|0 0|0| 0x0 | 1483 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1484 * | 0x0000 | 0x0001 | 1485 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1486 * | 0x0000 | 0x0000 | 1487 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1488 * | | 1489 * / RR_NAME / 1490 * / / 1491 * | | 1492 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1493 * | NB (0x0020) | IN (0x0001) | 1494 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1495 * | TTL | 1496 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1497 * | 0x0006 | NB_FLAGS | 1498 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1499 * | NB_ADDRESS | 1500 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1501 * 1502 * 1503 * 1504 * 4.2.6. NEGATIVE NAME REGISTRATION RESPONSE 1505 * 1506 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1507 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1508 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1509 * | NAME_TRN_ID |1| 0x5 |1|0|1|1|0 0|0| RCODE | 1510 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1511 * | 0x0000 | 0x0001 | 1512 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1513 * | 0x0000 | 0x0000 | 1514 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1515 * | | 1516 * / RR_NAME / 1517 * / / 1518 * | | 1519 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1520 * | NB (0x0020) | IN (0x0001) | 1521 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1522 * | TTL | 1523 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1524 * | 0x0006 | NB_FLAGS | 1525 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1526 * | NB_ADDRESS | 1527 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1528 * 1529 * RCODE field values: 1530 * 1531 * Symbol Value Description: 1532 * 1533 * FMT_ERR 0x1 Format Error. Request was invalidly 1534 * formatted. 1535 * SRV_ERR 0x2 Server failure. Problem with NAME, cannot 1536 * process name. 1537 * IMP_ERR 0x4 Unsupported request error. Allowable only 1538 * for challenging NAME when gets an Update type 1539 * registration request. 1540 * RFS_ERR 0x5 Refused error. For policy reasons server 1541 * will not register this name from this host. 1542 * ACT_ERR 0x6 Active error. Name is owned by another node. 1543 * CFT_ERR 0x7 Name in conflict error. A UNIQUE name is 1544 * owned by more than one node. 1545 */ 1546 static int 1547 smb_send_name_registration_response(struct addr_entry *addr, 1548 struct name_packet *original_packet, unsigned short rcode) 1549 { 1550 struct name_packet packet; 1551 struct resource_record answer; 1552 1553 bzero(&packet, sizeof (struct name_packet)); 1554 bzero(&answer, sizeof (struct resource_record)); 1555 1556 packet.name_trn_id = original_packet->name_trn_id; 1557 packet.info = NAME_REGISTRATION_RESPONSE | NAME_NM_FLAGS_RA | 1558 (rcode & NAME_RCODE_MASK); 1559 packet.qdcount = 0; /* question entries */ 1560 packet.question = NULL; 1561 packet.ancount = 1; /* answer recs */ 1562 packet.answer = &answer; 1563 packet.nscount = 0; /* authority recs */ 1564 packet.authority = NULL; 1565 packet.arcount = 0; /* additional recs */ 1566 packet.additional = NULL; 1567 1568 answer.name = original_packet->question->name; 1569 answer.rr_type = NAME_QUESTION_TYPE_NB; 1570 answer.rr_class = NAME_QUESTION_CLASS_IN; 1571 answer.ttl = original_packet->additional->ttl; 1572 answer.rdlength = original_packet->additional->rdlength; 1573 answer.rdata = original_packet->additional->rdata; 1574 1575 return (smb_send_name_service_packet(addr, &packet)); 1576 } 1577 1578 /* 1579 * 4.2.9. NAME RELEASE REQUEST & DEMAND 1580 * 1581 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1582 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1583 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1584 * | NAME_TRN_ID |0| 0x6 |0|0|0|0|0 0|B| 0x0 | 1585 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1586 * | 0x0001 | 0x0000 | 1587 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1588 * | 0x0000 | 0x0001 | 1589 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1590 * | | 1591 * / QUESTION_NAME / 1592 * / / 1593 * | | 1594 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1595 * | NB (0x0020) | IN (0x0001) | 1596 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1597 * | | 1598 * / RR_NAME / 1599 * / / 1600 * | | 1601 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1602 * | NB (0x0020) | IN (0x0001) | 1603 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1604 * | 0x00000000 | 1605 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1606 * | 0x0006 | NB_FLAGS | 1607 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1608 * | NB_ADDRESS | 1609 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1610 * 1611 * Since the RR_NAME is the same name as the QUESTION_NAME, the 1612 * RR_NAME representation must use label string pointers to the 1613 * QUESTION_NAME labels to guarantee the length of the datagram is 1614 * less than the maximum 576 bytes. This is the same condition as 1615 * with the NAME REGISTRATION REQUEST. 1616 */ 1617 static int 1618 smb_send_name_release_request_and_demand(int bcast, 1619 struct name_question *question, struct resource_record *additional) 1620 { 1621 int gotreply = 0; 1622 int i, rc; 1623 int addr_num; 1624 uint32_t retries; 1625 uint32_t timeout; 1626 struct addr_entry *destination; 1627 struct name_packet packet; 1628 1629 if (bcast == BROADCAST) { 1630 if (bcast_num == 0) 1631 return (-1); 1632 destination = smb_bcast_list; 1633 addr_num = bcast_num; 1634 retries = 1; /* BCAST_REQ_RETRY_COUNT */ 1635 timeout = 100; /* BCAST_REQ_RETRY_TIMEOUT */ 1636 packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_BROADCAST; 1637 } else { 1638 if (nbns_num == 0) 1639 return (-1); 1640 destination = smb_nbns; 1641 addr_num = nbns_num; 1642 retries = 1; /* UCAST_REQ_RETRY_COUNT */ 1643 timeout = 100; /* UCAST_REQ_RETRY_TIMEOUT */ 1644 packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_UNICAST; 1645 } 1646 1647 packet.qdcount = 1; /* question entries */ 1648 packet.question = question; 1649 packet.ancount = 0; /* answer recs */ 1650 packet.answer = NULL; 1651 packet.nscount = 0; /* authority recs */ 1652 packet.authority = NULL; 1653 packet.arcount = 1; /* additional recs */ 1654 packet.additional = additional; 1655 1656 for (i = 0; i < addr_num; i++) { 1657 rc = smb_netbios_send_rcv(bcast, &destination[i], &packet, 1658 retries, timeout); 1659 if (rc == 1) 1660 gotreply = 1; 1661 } 1662 1663 return (gotreply); 1664 } 1665 1666 /* 1667 * 4.2.10. POSITIVE NAME RELEASE RESPONSE 1668 * 1669 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1670 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1671 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1672 * | NAME_TRN_ID |1| 0x6 |1|0|0|0|0 0|0| 0x0 | 1673 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1674 * | 0x0000 | 0x0001 | 1675 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1676 * | 0x0000 | 0x0000 | 1677 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1678 * | | 1679 * / RR_NAME / 1680 * / / 1681 * | | 1682 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1683 * | NB (0x0020) | IN (0x0001) | 1684 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1685 * | TTL | 1686 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1687 * | 0x0006 | NB_FLAGS | 1688 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1689 * | NB_ADDRESS | 1690 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1691 * 1692 * 1693 * 4.2.11. NEGATIVE NAME RELEASE RESPONSE 1694 * 1695 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1696 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1697 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1698 * | NAME_TRN_ID |1| 0x6 |1|0|0|0|0 0|0| RCODE | 1699 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1700 * | 0x0000 | 0x0001 | 1701 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1702 * | 0x0000 | 0x0000 | 1703 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1704 * | | 1705 * / RR_NAME / 1706 * / / 1707 * | | 1708 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1709 * | NB (0x0020) | IN (0x0001) | 1710 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1711 * | TTL | 1712 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1713 * | 0x0006 | NB_FLAGS | 1714 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1715 * | NB_ADDRESS | 1716 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1717 * 1718 * RCODE field values: 1719 * 1720 * Symbol Value Description: 1721 * 1722 * FMT_ERR 0x1 Format Error. Request was invalidly 1723 * formatted. 1724 * 1725 * SRV_ERR 0x2 Server failure. Problem with NAME, cannot 1726 * process name. 1727 * 1728 * RFS_ERR 0x5 Refused error. For policy reasons server 1729 * will not release this name from this host. 1730 * 1731 * ACT_ERR 0x6 Active error. Name is owned by another node. 1732 * Only that node may release it. A NetBIOS 1733 * Name Server can optionally allow a node to 1734 * release a name it does not own. This would 1735 * facilitate detection of inactive names for 1736 * nodes that went down silently. 1737 */ 1738 static int 1739 /* LINTED - E_STATIC_UNUSED */ 1740 smb_send_name_release_response(struct addr_entry *addr, 1741 struct name_packet *original_packet, unsigned short rcode) 1742 { 1743 struct name_packet packet; 1744 struct resource_record answer; 1745 1746 bzero(&packet, sizeof (struct name_packet)); 1747 bzero(&answer, sizeof (struct resource_record)); 1748 1749 packet.name_trn_id = original_packet->name_trn_id; 1750 packet.info = NAME_RELEASE_RESPONSE | (rcode & NAME_RCODE_MASK); 1751 packet.qdcount = 0; /* question entries */ 1752 packet.question = NULL; 1753 packet.ancount = 1; /* answer recs */ 1754 packet.answer = &answer; 1755 packet.nscount = 0; /* authority recs */ 1756 packet.authority = NULL; 1757 packet.arcount = 0; /* additional recs */ 1758 packet.additional = NULL; 1759 1760 answer.name = original_packet->question->name; 1761 answer.rr_type = NAME_QUESTION_TYPE_NB; 1762 answer.rr_class = NAME_QUESTION_CLASS_IN; 1763 answer.ttl = original_packet->additional->ttl; 1764 answer.rdlength = original_packet->additional->rdlength; 1765 answer.rdata = original_packet->additional->rdata; 1766 1767 return (smb_send_name_service_packet(addr, &packet)); 1768 } 1769 1770 /* 1771 * 1772 * 4.2.12. NAME QUERY REQUEST 1773 * 1774 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1775 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1776 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1777 * | NAME_TRN_ID |0| 0x0 |0|0|1|0|0 0|B| 0x0 | 1778 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1779 * | 0x0001 | 0x0000 | 1780 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1781 * | 0x0000 | 0x0000 | 1782 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1783 * | | 1784 * / QUESTION_NAME / 1785 * / / 1786 * | | 1787 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1788 * | NB (0x0020) | IN (0x0001) | 1789 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1790 */ 1791 static int 1792 smb_send_name_query_request(int bcast, struct name_question *question) 1793 { 1794 int rc = 0; 1795 uint32_t retry, retries; 1796 uint32_t timeout; 1797 unsigned short tid; 1798 struct addr_entry *destination; 1799 struct name_packet packet; 1800 int i, addr_num; 1801 struct timespec st; 1802 1803 if (bcast == BROADCAST) { 1804 if (bcast_num == 0) 1805 return (-1); 1806 destination = smb_bcast_list; 1807 addr_num = bcast_num; 1808 retries = BCAST_REQ_RETRY_COUNT; 1809 timeout = BCAST_REQ_RETRY_TIMEOUT; 1810 packet.info = NAME_QUERY_REQUEST | NM_FLAGS_BROADCAST; 1811 } else { 1812 if (nbns_num == 0) 1813 return (-1); 1814 destination = smb_nbns; 1815 addr_num = nbns_num; 1816 retries = UCAST_REQ_RETRY_COUNT; 1817 timeout = UCAST_REQ_RETRY_TIMEOUT; 1818 packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST; 1819 } 1820 packet.qdcount = 1; /* question entries */ 1821 packet.question = question; 1822 packet.ancount = 0; /* answer recs */ 1823 packet.answer = NULL; 1824 packet.nscount = 0; /* authority recs */ 1825 packet.authority = NULL; 1826 packet.arcount = 0; /* additional recs */ 1827 packet.additional = NULL; 1828 1829 for (i = 0; i < addr_num; i++) { 1830 for (retry = 0; retry < retries; retry++) { 1831 if ((destination->flags & ADDR_FLAG_VALID) == 0) 1832 break; 1833 tid = netbios_name_transcation_id++; 1834 packet.name_trn_id = tid; 1835 1836 if (smb_send_name_service_packet(&destination[i], 1837 &packet) >= 0) { 1838 if ((rc = smb_netbios_process_response(tid, 1839 &destination[i], 1840 &packet, timeout)) != 0) 1841 break; 1842 } 1843 st.tv_sec = 0; 1844 st.tv_nsec = (timeout * 1000000); 1845 (void) nanosleep(&st, 0); 1846 } 1847 } 1848 1849 return (rc); 1850 } 1851 1852 1853 /* 1854 * 1855 * 4.2.13. POSITIVE NAME QUERY RESPONSE 1856 * 1857 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1858 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1859 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1860 * | NAME_TRN_ID |1| 0x0 |1|T|1|?|0 0|0| 0x0 | 1861 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1862 * | 0x0000 | 0x0001 | 1863 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1864 * | 0x0000 | 0x0000 | 1865 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1866 * | | 1867 * / RR_NAME / 1868 * / / 1869 * | | 1870 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1871 * | NB (0x0020) | IN (0x0001) | 1872 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1873 * | TTL | 1874 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1875 * | RDLENGTH | | 1876 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 1877 * | | 1878 * / ADDR_ENTRY ARRAY / 1879 * / / 1880 * | | 1881 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1882 * 1883 * The ADDR_ENTRY ARRAY a sequence of zero or more ADDR_ENTRY 1884 * records. Each ADDR_ENTRY record represents an owner of a name. 1885 * For group names there may be multiple entries. However, the list 1886 * may be incomplete due to packet size limitations. Bit 22, "T", 1887 * will be set to indicate truncated data. 1888 * 1889 * Each ADDR_ENTRY has the following format: 1890 * 1891 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1892 * | NB_FLAGS | NB_ADDRESS | 1893 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1894 * | NB_ADDRESS (continued) | 1895 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1896 * 1897 * 1898 * 1899 * 4.2.14. NEGATIVE NAME QUERY RESPONSE 1900 * 1901 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1902 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1903 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1904 * | NAME_TRN_ID |1| 0x0 |1|0|1|?|0 0|0| RCODE | 1905 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1906 * | 0x0000 | 0x0000 | 1907 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1908 * | 0x0000 | 0x0000 | 1909 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1910 * | | 1911 * / RR_NAME / 1912 * / / 1913 * | | 1914 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1915 * | NULL (0x000A) | IN (0x0001) | 1916 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1917 * | 0x00000000 | 1918 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1919 * | 0x0000 | 1920 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1921 * 1922 * RCODE field values: 1923 * 1924 * Symbol Value Description 1925 * 1926 * FMT_ERR 0x1 Format Error. Request was invalidly 1927 * formatted. 1928 * SRV_ERR 0x2 Server failure. Problem with NAME, cannot 1929 * process name. 1930 * NAM_ERR 0x3 Name Error. The name requested does not 1931 * exist. 1932 * IMP_ERR 0x4 Unsupported request error. Allowable only 1933 * for challenging NAME when gets an Update type 1934 * registration request. 1935 * RFS_ERR 0x5 Refused error. For policy reasons server 1936 * will not register this name from this host. 1937 */ 1938 static int 1939 smb_send_name_query_response(struct addr_entry *addr, 1940 struct name_packet *original_packet, struct name_entry *entry, 1941 unsigned short rcode) 1942 { 1943 struct addr_entry *raddr; 1944 struct name_packet packet; 1945 struct resource_record answer; 1946 unsigned short attr; 1947 unsigned char data[MAX_DATAGRAM_LENGTH]; 1948 unsigned char *scan = data; 1949 1950 packet.name_trn_id = original_packet->name_trn_id; 1951 packet.info = NAME_QUERY_RESPONSE | (rcode & NAME_RCODE_MASK); 1952 packet.qdcount = 0; /* question entries */ 1953 packet.question = NULL; 1954 packet.ancount = 1; /* answer recs */ 1955 packet.answer = &answer; 1956 packet.nscount = 0; /* authority recs */ 1957 packet.authority = NULL; 1958 packet.arcount = 0; /* additional recs */ 1959 packet.additional = NULL; 1960 1961 answer.name = entry; 1962 answer.rr_class = NAME_QUESTION_CLASS_IN; 1963 answer.ttl = entry->addr_list.ttl; 1964 answer.rdata = data; 1965 if (rcode) { 1966 answer.rr_type = NAME_RR_TYPE_NULL; 1967 answer.rdlength = 0; 1968 bzero(data, 6); 1969 } else { 1970 answer.rdlength = 0; 1971 answer.rr_type = NAME_QUESTION_TYPE_NB; 1972 raddr = &entry->addr_list; 1973 scan = data; 1974 do { 1975 attr = entry->attributes & (NAME_ATTR_GROUP | 1976 NAME_ATTR_OWNER_NODE_TYPE); 1977 1978 BE_OUT16(scan, attr); scan += 2; 1979 (void) memcpy(scan, &raddr->sin.sin_addr.s_addr, 1980 sizeof (uint32_t)); 1981 scan += 4; 1982 1983 answer.rdlength += 6; 1984 raddr = raddr->forw; 1985 } while (raddr != &entry->addr_list); 1986 } 1987 1988 return (smb_send_name_service_packet(addr, &packet)); 1989 } 1990 1991 /* 1992 * 4.2.18. NODE STATUS RESPONSE 1993 * 1994 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 1995 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1996 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1997 * | NAME_TRN_ID |1| 0x0 |1|0|0|0|0 0|0| 0x0 | 1998 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1999 * | 0x0000 | 0x0001 | 2000 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2001 * | 0x0000 | 0x0000 | 2002 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2003 * | | 2004 * / RR_NAME / 2005 * | | 2006 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2007 * | NBSTAT (0x0021) | IN (0x0001) | 2008 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2009 * | 0x00000000 | 2010 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2011 * | RDLENGTH | NUM_NAMES | | 2012 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 2013 * | | 2014 * + + 2015 * / NODE_NAME ARRAY / 2016 * + + 2017 * | | 2018 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2019 * | | 2020 * + + 2021 * / STATISTICS / 2022 * + + 2023 * | | 2024 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2025 * 2026 * The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries 2027 * of NODE_NAME records. Each NODE_NAME entry represents an active 2028 * name in the same NetBIOS scope as the requesting name in the 2029 * local name table of the responder. RR_NAME is the requesting 2030 * name. 2031 * 2032 * NODE_NAME Entry: 2033 * 2034 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 2035 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2036 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2037 * | | 2038 * +--- ---+ 2039 * | | 2040 * +--- NETBIOS FORMAT NAME ---+ 2041 * | | 2042 * +--- ---+ 2043 * | | 2044 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2045 * | NAME_FLAGS | 2046 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2047 * 2048 * The NAME_FLAGS field: 2049 * 2050 * 1 1 1 1 1 1 2051 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 2052 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 2053 * | G | ONT |DRG|CNF|ACT|PRM| RESERVED | 2054 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 2055 * 2056 * The NAME_FLAGS field is defined as: 2057 * 2058 * Symbol Bit(s) Description: 2059 * 2060 * RESERVED 7-15 Reserved for future use. Must be zero (0). 2061 * PRM 6 Permanent Name Flag. If one (1) then entry 2062 * is for the permanent node name. Flag is zero 2063 * (0) for all other names. 2064 * ACT 5 Active Name Flag. All entries have this flag 2065 * set to one (1). 2066 * CNF 4 Conflict Flag. If one (1) then name on this 2067 * node is in conflict. 2068 * DRG 3 Deregister Flag. If one (1) then this name 2069 * is in the process of being deleted. 2070 * ONT 1,2 Owner Node Type: 2071 * 00 = B node 2072 * 01 = P node 2073 * 10 = M node 2074 * 11 = Reserved for future use 2075 * G 0 Group Name Flag. 2076 * If one (1) then the name is a GROUP NetBIOS 2077 * name. 2078 * If zero (0) then it is a UNIQUE NetBIOS name. 2079 */ 2080 #define NAME_FLAGS_PERMANENT_NAME 0x0200 2081 #define NAME_FLAGS_ACTIVE_NAME 0x0400 2082 #define NAME_FLAGS_CONFLICT 0x0800 2083 #define NAME_FLAGS_DEREGISTER 0x1000 2084 #define NAME_FLAGS_ONT_MASK 0x6000 2085 #define NAME_FLAGS_ONT_B_NODE 0x0000 2086 #define NAME_FLAGS_ONT_P_NODE 0x2000 2087 #define NAME_FLAGS_ONT_M_NODE 0x4000 2088 #define NAME_FLAGS_ONT_RESERVED 0x6000 2089 #define NAME_FLAGS_GROUP_NAME 0x8000 2090 2091 2092 /* 2093 * STATISTICS Field of the NODE STATUS RESPONSE: 2094 * 2095 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 2096 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2097 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2098 * | UNIT_ID (Unique unit ID) | 2099 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2100 * | UNIT_ID,continued | JUMPERS | TEST_RESULT | 2101 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2102 * | VERSION_NUMBER | PERIOD_OF_STATISTICS | 2103 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2104 * | NUMBER_OF_CRCs | NUMBER_ALIGNMENT_ERRORS | 2105 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2106 * | NUMBER_OF_COLLISIONS | NUMBER_SEND_ABORTS | 2107 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2108 * | NUMBER_GOOD_SENDS | 2109 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2110 * | NUMBER_GOOD_RECEIVES | 2111 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2112 * | NUMBER_RETRANSMITS | NUMBER_NO_RESOURCE_CONDITIONS | 2113 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2114 * | NUMBER_FREE_COMMAND_BLOCKS | TOTAL_NUMBER_COMMAND_BLOCKS | 2115 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2116 * |MAX_TOTAL_NUMBER_COMMAND_BLOCKS| NUMBER_PENDING_SESSIONS | 2117 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2118 * | MAX_NUMBER_PENDING_SESSIONS | MAX_TOTAL_SESSIONS_POSSIBLE | 2119 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2120 * | SESSION_DATA_PACKET_SIZE | 2121 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2122 */ 2123 #define MAX_NETBIOS_REPLY_DATA_SIZE 500 2124 2125 static int 2126 smb_send_node_status_response(struct addr_entry *addr, 2127 struct name_packet *original_packet) 2128 { 2129 uint32_t net_ipaddr; 2130 int64_t max_connections; 2131 struct arpreq arpreq; 2132 struct name_packet packet; 2133 struct resource_record answer; 2134 unsigned char *scan; 2135 unsigned char *scan_end; 2136 unsigned char data[MAX_NETBIOS_REPLY_DATA_SIZE]; 2137 net_cfg_t cfg; 2138 boolean_t scan_done = B_FALSE; 2139 2140 bzero(&packet, sizeof (struct name_packet)); 2141 bzero(&answer, sizeof (struct resource_record)); 2142 2143 packet.name_trn_id = original_packet->name_trn_id; 2144 packet.info = NODE_STATUS_RESPONSE; 2145 packet.qdcount = 0; /* question entries */ 2146 packet.question = NULL; 2147 packet.ancount = 1; /* answer recs */ 2148 packet.answer = &answer; 2149 packet.nscount = 0; /* authority recs */ 2150 packet.authority = NULL; 2151 packet.arcount = 0; /* additional recs */ 2152 packet.additional = NULL; 2153 2154 answer.name = original_packet->question->name; 2155 answer.rr_type = NAME_RR_TYPE_NBSTAT; 2156 answer.rr_class = NAME_QUESTION_CLASS_IN; 2157 answer.ttl = 0; 2158 answer.rdata = data; 2159 2160 scan = smb_netbios_cache_status(data, MAX_NETBIOS_REPLY_DATA_SIZE, 2161 original_packet->question->name->scope); 2162 2163 scan_end = data + MAX_NETBIOS_REPLY_DATA_SIZE; 2164 2165 if (smb_nic_get_bysubnet(addr->sin.sin_addr.s_addr, &cfg) == NULL) 2166 net_ipaddr = 0; 2167 else 2168 net_ipaddr = cfg.ip; 2169 2170 (void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &max_connections); 2171 2172 while (!scan_done) { 2173 if ((scan + 6) >= scan_end) { 2174 packet.info |= NAME_NM_FLAGS_TC; 2175 break; 2176 } 2177 2178 if (net_ipaddr != 0) { 2179 struct sockaddr_in *s_in; 2180 int s; 2181 2182 s = socket(AF_INET, SOCK_DGRAM, 0); 2183 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 2184 s_in = (struct sockaddr_in *)&arpreq.arp_pa; 2185 s_in->sin_family = AF_INET; 2186 s_in->sin_addr.s_addr = net_ipaddr; 2187 if (ioctl(s, SIOCGARP, (caddr_t)&arpreq) < 0) { 2188 bzero(scan, 6); 2189 } else { 2190 bcopy(&arpreq.arp_ha.sa_data, scan, 6); 2191 } 2192 (void) close(s); 2193 } else { 2194 bzero(scan, 6); 2195 } 2196 scan += 6; 2197 2198 if ((scan + 26) >= scan_end) { 2199 packet.info |= NAME_NM_FLAGS_TC; 2200 break; 2201 } 2202 bzero(scan, 26); 2203 scan += 26; 2204 2205 if ((scan + 2) >= scan_end) { 2206 packet.info |= NAME_NM_FLAGS_TC; 2207 break; 2208 } 2209 BE_OUT16(scan, 0); scan += 2; 2210 2211 if ((scan + 2) >= scan_end) { 2212 packet.info |= NAME_NM_FLAGS_TC; 2213 break; 2214 } 2215 BE_OUT16(scan, 0); scan += 2; 2216 2217 if ((scan + 2) >= scan_end) { 2218 packet.info |= NAME_NM_FLAGS_TC; 2219 break; 2220 } 2221 BE_OUT16(scan, 0); scan += 2; 2222 2223 if ((scan + 2) >= scan_end) { 2224 packet.info |= NAME_NM_FLAGS_TC; 2225 break; 2226 } 2227 BE_OUT16(scan, 0); scan += 2; 2228 2229 if ((scan + 2) >= scan_end) { 2230 packet.info |= NAME_NM_FLAGS_TC; 2231 break; 2232 } 2233 BE_OUT16(scan, 0); scan += 2; 2234 2235 if ((scan + 2) >= scan_end) { 2236 packet.info |= NAME_NM_FLAGS_TC; 2237 break; 2238 } 2239 BE_OUT16(scan, 0); scan += 2; 2240 2241 if ((scan + 2) >= scan_end) { 2242 packet.info |= NAME_NM_FLAGS_TC; 2243 break; 2244 } 2245 BE_OUT16(scan, 0); scan += 2; 2246 2247 if ((scan + 2) >= scan_end) { 2248 packet.info |= NAME_NM_FLAGS_TC; 2249 break; 2250 } 2251 BE_OUT16(scan, max_connections); scan += 2; 2252 2253 if ((scan + 2) >= scan_end) { 2254 packet.info |= NAME_NM_FLAGS_TC; 2255 break; 2256 } 2257 2258 BE_OUT16(scan, 0); scan += 2; 2259 2260 scan_done = B_TRUE; 2261 } 2262 answer.rdlength = scan - data; 2263 return (smb_send_name_service_packet(addr, &packet)); 2264 } 2265 2266 /* 2267 * 2268 * 5.1. NAME SERVICE PROTOCOLS 2269 * 2270 * A REQUEST packet is always sent to the well known UDP port - 2271 * NAME_SERVICE_UDP_PORT. The destination address is normally 2272 * either the IP broadcast address or the address of the NAME - the 2273 * address of the NAME server it set up at initialization time. In 2274 * rare cases, a request packet will be sent to an end node, e.g. a 2275 * NAME QUERY REQUEST sent to "challenge" a node. 2276 * 2277 * A RESPONSE packet is always sent to the source UDP port and 2278 * source IP address of the request packet. 2279 * 2280 * A DEMAND packet must always be sent to the well known UDP port - 2281 * NAME_SERVICE_UDP_PORT. There is no restriction on the target IP 2282 * address. 2283 * 2284 * Terms used in this section: 2285 * 2286 * tid - Transaction ID. This is a value composed from 2287 * the requestor's IP address and a unique 16 bit 2288 * value generated by the originator of the 2289 * transaction. 2290 */ 2291 2292 2293 /* 2294 * 2295 * 5.1.1. B-NODE ACTIVITY 2296 * 2297 * 5.1.1.1. B-NODE ADD NAME 2298 * 2299 * PROCEDURE add_name(name) 2300 * 2301 * (* 2302 * * Host initiated processing for a B node 2303 * *) 2304 * BEGIN 2305 * 2306 * REPEAT 2307 * 2308 * (* build name service packet *) 2309 * 2310 * ONT = B_NODE; (* broadcast node *) 2311 * G = UNIQUE; (* unique name *) 2312 * TTL = 0; 2313 * 2314 * broadcast NAME REGISTRATION REQUEST packet; 2315 * 2316 * (* 2317 * * remote node(s) will send response packet 2318 * * if applicable 2319 * *) 2320 * pause(BCAST_REQ_RETRY_TIMEOUT); 2321 * 2322 * UNTIL response packet is received or 2323 * retransmit count has been exceeded 2324 * 2325 * IF no response packet was received THEN 2326 * BEGIN (* no response *) 2327 * (* 2328 * * Build packet 2329 * *) 2330 * 2331 * ONT = B_NODE; (* broadcast node *) 2332 * G = UNIQUE; (* unique name *) 2333 * TTL = 0; 2334 * 2335 * (* 2336 * * Let other nodes known you have the name 2337 * *) 2338 * 2339 * broadcast NAME UPDATE REQUEST packet; 2340 * (* name can be added to local name table *) 2341 * return success; 2342 * END (* no response *) 2343 * ELSE 2344 * BEGIN (* got response *) 2345 * 2346 * (* 2347 * * Match return transaction id 2348 * * against tid sent in request 2349 * *) 2350 * 2351 * IF NOT response tid = request tid THEN 2352 * BEGIN 2353 * ignore response packet; 2354 * END 2355 * ELSE 2356 * CASE packet type OF 2357 * 2358 * NEGATIVE NAME REGISTRATION RESPONSE: 2359 * 2360 * return failure; (* name cannot be added *) 2361 * 2362 * POSITIVE NAME REGISTRATION RESPONSE: 2363 * END-NODE CHALLENGE NAME REGISTRATION RESPONSE: 2364 * 2365 * (* 2366 * * B nodes should normally not get this 2367 * * response. 2368 * *) 2369 * 2370 * ignore packet; 2371 * END (* case *); 2372 * END (* got response *) 2373 * END (* procedure *) 2374 * 2375 * 2376 * 2377 * 5.1.1.2. B-NODE ADD_GROUP NAME 2378 * 2379 * PROCEDURE add_group_name(name) 2380 * 2381 * (* 2382 * * Host initiated processing for a B node 2383 * *) 2384 * 2385 * BEGIN 2386 * (* 2387 * * same as for a unique name with the 2388 * * exception that the group bit (G) must 2389 * * be set in the request packets. 2390 * *) 2391 * 2392 * ... 2393 * G = GROUP; 2394 * ... 2395 * ... 2396 * 2397 * (* 2398 * * broadcast request ... 2399 * *) 2400 * 2401 * 2402 * END 2403 */ 2404 static int 2405 smb_name_Bnode_add_name(struct name_entry *name) 2406 { 2407 struct name_question question; 2408 struct resource_record additional; 2409 unsigned char data[8]; 2410 unsigned short attr; 2411 struct addr_entry *addr; 2412 int rc = 0; 2413 2414 addr = &name->addr_list; 2415 2416 do { 2417 /* build name service packet */ 2418 question.name = name; 2419 /* 2420 * question.name->attributes |= NAME_NB_FLAGS_ONT_B; 2421 * This is commented because NAME_NB_FLAGS_ONT_B is 0 2422 */ 2423 question.question_type = NAME_QUESTION_TYPE_NB; 2424 question.question_class = NAME_QUESTION_CLASS_IN; 2425 2426 additional.name = name; 2427 additional.rr_class = NAME_QUESTION_CLASS_IN; 2428 additional.ttl = 0; 2429 additional.rdata = data; 2430 additional.rdlength = 6; 2431 additional.rr_type = NAME_QUESTION_TYPE_NB; 2432 attr = name->attributes & (NAME_ATTR_GROUP | 2433 NAME_ATTR_OWNER_NODE_TYPE); 2434 2435 BE_OUT16(&data[0], attr); 2436 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr, 2437 sizeof (uint32_t)); 2438 2439 rc |= smb_send_name_registration_request(BROADCAST, &question, 2440 &additional); 2441 addr = addr->forw; 2442 2443 } while (addr != &name->addr_list); 2444 2445 return (rc); 2446 } 2447 2448 /* 2449 * 5.1.1.3. B-NODE FIND_NAME 2450 * 2451 * PROCEDURE find_name(name) 2452 * 2453 * (* 2454 * * Host initiated processing for a B node 2455 * *) 2456 * 2457 * BEGIN 2458 * 2459 * REPEAT 2460 * (* 2461 * * build packet 2462 * *) 2463 * ONT = B; 2464 * TTL = 0; 2465 * G = DONT CARE; 2466 * raddr = raddr->forw; 2467 * 2468 * broadcast NAME QUERY REQUEST packet; 2469 * (* 2470 * * a node might send response packet 2471 * *) 2472 * 2473 * pause(BCAST_REQ_RETRY_TIMEOUT); 2474 * UNTIL response packet received OR 2475 * max transmit threshold exceeded 2476 * 2477 * IF no response packet received THEN 2478 * return failure; 2479 * ELSE 2480 * IF NOT response tid = request tid THEN 2481 * ignore packet; 2482 * ELSE 2483 * CASE packet type OF 2484 * POSITIVE NAME QUERY RESPONSE: 2485 * (* 2486 * * Start a timer to detect conflict. 2487 * * 2488 * * Be prepared to detect conflict if 2489 * * any more response packets are received. 2490 * * 2491 * *) 2492 * 2493 * save response as authoritative response; 2494 * start_timer(CONFLICT_TIMER); 2495 * return success; 2496 * 2497 * NEGATIVE NAME QUERY RESPONSE: 2498 * REDIRECT NAME QUERY RESPONSE: 2499 * 2500 * (* 2501 * * B Node should normally not get either 2502 * * response. 2503 * *) 2504 * 2505 * ignore response packet; 2506 * 2507 * END (* case *) 2508 * END (* procedure *) 2509 */ 2510 static int 2511 smb_name_Bnode_find_name(struct name_entry *name) 2512 { 2513 struct name_question question; 2514 2515 question.name = name; 2516 question.question_type = NAME_QUESTION_TYPE_NB; 2517 question.question_class = NAME_QUESTION_CLASS_IN; 2518 2519 return (smb_send_name_query_request(BROADCAST, &question)); 2520 } 2521 2522 /* 2523 * 5.1.1.4. B NODE NAME RELEASE 2524 * 2525 * PROCEDURE delete_name (name) 2526 * BEGIN 2527 * 2528 * REPEAT 2529 * 2530 * (* 2531 * * build packet 2532 * *) 2533 * ... 2534 * 2535 * (* 2536 * * send request 2537 * *) 2538 * 2539 * broadcast NAME RELEASE REQUEST packet; 2540 * 2541 * (* 2542 * * no response packet expected 2543 * *) 2544 * 2545 * pause(BCAST_REQ_RETRY_TIMEOUT); 2546 * 2547 * UNTIL retransmit count has been exceeded 2548 * END (* procedure *) 2549 */ 2550 static int 2551 smb_name_Bnode_delete_name(struct name_entry *name) 2552 { 2553 struct name_question question; 2554 struct resource_record additional; 2555 struct addr_entry *raddr; 2556 unsigned char data[MAX_DATAGRAM_LENGTH]; 2557 unsigned char *scan = data; 2558 uint32_t attr; 2559 2560 /* build packet */ 2561 question.name = name; 2562 question.question_type = NAME_QUESTION_TYPE_NB; 2563 question.question_class = NAME_QUESTION_CLASS_IN; 2564 2565 additional.name = name; 2566 additional.rr_class = NAME_QUESTION_CLASS_IN; 2567 additional.ttl = 0; 2568 additional.rdata = data; 2569 additional.rdlength = 0; 2570 additional.rr_type = NAME_QUESTION_TYPE_NB; 2571 raddr = &name->addr_list; 2572 scan = data; 2573 do { 2574 attr = name->attributes & (NAME_ATTR_GROUP | 2575 NAME_ATTR_OWNER_NODE_TYPE); 2576 2577 BE_OUT16(scan, attr); scan += 2; 2578 (void) memcpy(scan, &raddr->sin.sin_addr.s_addr, 2579 sizeof (uint32_t)); 2580 scan += 4; 2581 2582 additional.rdlength += 6; 2583 } while (raddr != &name->addr_list); 2584 2585 return (smb_send_name_release_request_and_demand(BROADCAST, 2586 &question, &additional)); 2587 } 2588 2589 /* 2590 * 2591 * 5.1.2. P-NODE ACTIVITY 2592 * 2593 * All packets sent or received by P nodes are unicast UDP packets. 2594 * A P node sends name service requests to the NAME node that is 2595 * specified in the P-node configuration. 2596 * 2597 * 5.1.2.1. P-NODE ADD_NAME 2598 * 2599 * PROCEDURE add_name(name) 2600 * 2601 * (* 2602 * * Host initiated processing for a P node 2603 * *) 2604 * 2605 * BEGIN 2606 * 2607 * REPEAT 2608 * (* 2609 * * build packet 2610 * *) 2611 * 2612 * ONT = P; 2613 * G = UNIQUE; 2614 * ... 2615 * 2616 * (* 2617 * * send request 2618 * *) 2619 * 2620 * unicast NAME REGISTRATION REQUEST packet; 2621 * 2622 * (* 2623 * * NAME will send response packet 2624 * *) 2625 * 2626 * IF receive a WACK RESPONSE THEN 2627 * pause(time from TTL field of response); 2628 * ELSE 2629 * pause(UCAST_REQ_RETRY_TIMEOUT); 2630 * UNTIL response packet is received OR 2631 * retransmit count has been exceeded 2632 * 2633 * IF no response packet was received THEN 2634 * BEGIN (* no response *) 2635 * (* 2636 * * NAME is down. Cannot claim name. 2637 * *) 2638 * 2639 * return failure; (* name cannot be claimed *) 2640 * END (* no response *) 2641 * ELSE 2642 * BEGIN (* response *) 2643 * IF NOT response tid = request tid THEN 2644 * BEGIN 2645 * (* Packet may belong to another transaction *) 2646 * ignore response packet; 2647 * END 2648 * ELSE 2649 * CASE packet type OF 2650 * 2651 * POSITIVE NAME REGISTRATION RESPONSE: 2652 * 2653 * (* 2654 * * name can be added 2655 * *) 2656 * 2657 * adjust refresh timeout value, TTL, for this name; 2658 * return success; (* name can be added *) 2659 * 2660 * NEGATIVE NAME REGISTRATION RESPONSE: 2661 * return failure; (* name cannot be added *) 2662 * 2663 * END-NODE CHALLENGE REGISTRATION REQUEST: 2664 * BEGIN (* end node challenge *) 2665 * 2666 * (* 2667 * * The response packet has in it the 2668 * * address of the presumed owner of the 2669 * * name. Challenge that owner. 2670 * * If owner either does not 2671 * * respond or indicates that he no longer 2672 * * owns the name, claim the name. 2673 * * Otherwise, the name cannot be claimed. 2674 * * 2675 * *) 2676 * 2677 * REPEAT 2678 * (* 2679 * * build packet 2680 * *) 2681 * ... 2682 * 2683 * unicast NAME QUERY REQUEST packet to the 2684 * address contained in the END NODE 2685 * CHALLENGE RESPONSE packet; 2686 * 2687 * (* 2688 * * remote node may send response packet 2689 * *) 2690 * 2691 * pause(UCAST_REQ_RETRY_TIMEOUT); 2692 * 2693 * UNTIL response packet is received or 2694 * retransmit count has been exceeded 2695 * IF no response packet is received OR 2696 * NEGATIVE NAME QUERY RESPONSE packet 2697 * received THEN 2698 * BEGIN (* update *) 2699 * 2700 * (* 2701 * * name can be claimed 2702 * *) 2703 * 2704 * REPEAT 2705 * 2706 * (* 2707 * * build packet 2708 * *) 2709 * ... 2710 * 2711 * unicast NAME UPDATE REQUEST to NAME; 2712 * 2713 * (* 2714 * * NAME node will send response packet 2715 * *) 2716 * 2717 * IF receive a WACK RESPONSE THEN 2718 * pause(time from TTL field of response); 2719 * ELSE 2720 * pause(UCAST_REQ_RETRY_TIMEOUT); 2721 * UNTIL response packet is received or 2722 * retransmit count has been exceeded 2723 * IF no response packet received THEN 2724 * BEGIN (* no response *) 2725 * 2726 * (* 2727 * * name could not be claimed 2728 * *) 2729 * 2730 * return failure; 2731 * END (* no response *) 2732 * ELSE 2733 * CASE packet type OF 2734 * POSITIVE NAME REGISTRATION RESPONSE: 2735 * (* 2736 * * add name 2737 * *) 2738 * return success; 2739 * NEGATIVE NAME REGISTRATION RESPONSE: 2740 * 2741 * (* 2742 * * you lose ... 2743 * *) 2744 * return failure; 2745 * END (* case *) 2746 * END (* update *) 2747 * ELSE 2748 * 2749 * (* 2750 * * received a positive response to the "challenge" 2751 * * Remote node still has name 2752 * *) 2753 * 2754 * return failure; 2755 * END (* end node challenge *) 2756 * END (* response *) 2757 * END (* procedure *) 2758 * 2759 * 2760 * 5.1.2.2. P-NODE ADD GROUP NAME 2761 * 2762 * PROCEDURE add_group_name(name) 2763 * 2764 * (* 2765 * * Host initiated processing for a P node 2766 * *) 2767 * 2768 * BEGIN 2769 * (* 2770 * * same as for a unique name, except that the 2771 * * request packet must indicate that a 2772 * * group name claim is being made. 2773 * *) 2774 * 2775 * ... 2776 * G = GROUP; 2777 * ... 2778 * 2779 * (* 2780 * * send packet 2781 * *) 2782 * ... 2783 * 2784 * 2785 * END 2786 */ 2787 static int 2788 smb_name_Pnode_add_name(struct name_entry *name) 2789 { 2790 struct name_question question; 2791 struct resource_record additional; 2792 unsigned char data[8]; 2793 unsigned short attr; 2794 struct addr_entry *addr; 2795 int rc = 0; 2796 2797 /* build packet */ 2798 addr = &name->addr_list; 2799 do { 2800 question.name = name; 2801 question.question_type = NAME_QUESTION_TYPE_NB; 2802 question.question_class = NAME_QUESTION_CLASS_IN; 2803 2804 additional.name = name; 2805 additional.rr_class = NAME_QUESTION_CLASS_IN; 2806 additional.ttl = 0; 2807 additional.rdata = data; 2808 additional.rdlength = 6; 2809 additional.rr_type = NAME_QUESTION_TYPE_NB; 2810 attr = name->attributes & 2811 (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE); 2812 2813 BE_OUT16(&data[0], attr); 2814 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr, 2815 sizeof (uint32_t)); 2816 2817 rc |= smb_send_name_registration_request(UNICAST, &question, 2818 &additional); 2819 2820 addr = addr->forw; 2821 2822 } while (addr != &name->addr_list); 2823 2824 return (rc); 2825 } 2826 2827 static int 2828 smb_name_Pnode_refresh_name(struct name_entry *name) 2829 { 2830 struct name_question question; 2831 struct resource_record additional; 2832 unsigned char data[8]; 2833 unsigned short attr; 2834 struct addr_entry *addr; 2835 int rc = 0; 2836 2837 /* build packet */ 2838 addr = &name->addr_list; 2839 do { 2840 question.name = name; 2841 question.question_type = NAME_QUESTION_TYPE_NB; 2842 question.question_class = NAME_QUESTION_CLASS_IN; 2843 2844 additional.name = name; 2845 additional.rr_class = NAME_QUESTION_CLASS_IN; 2846 additional.ttl = 0; 2847 additional.rdata = data; 2848 additional.rdlength = 6; 2849 additional.rr_type = NAME_QUESTION_TYPE_NB; 2850 attr = name->attributes & 2851 (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE); 2852 2853 BE_OUT16(&data[0], attr); 2854 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr, 2855 sizeof (uint32_t)); 2856 2857 rc |= smb_send_name_refresh_request(UNICAST, &question, 2858 &additional, 1); 2859 2860 addr = addr->forw; 2861 } while (addr != &name->addr_list); 2862 2863 return (rc); 2864 } 2865 2866 /* 2867 * 5.1.2.3. P-NODE FIND NAME 2868 * 2869 * PROCEDURE find_name(name) 2870 * 2871 * (* 2872 * * Host initiated processing for a P node 2873 * *) 2874 * 2875 * BEGIN 2876 * REPEAT 2877 * (* 2878 * * build packet 2879 * *) 2880 * 2881 * ONT = P; 2882 * G = DONT CARE; 2883 * 2884 * unicast NAME QUERY REQUEST packet; 2885 * 2886 * (* 2887 * * a NAME node might send response packet 2888 * *) 2889 * 2890 * IF receive a WACK RESPONSE THEN 2891 * pause(time from TTL field of response); 2892 * ELSE 2893 * pause(UCAST_REQ_RETRY_TIMEOUT); 2894 * UNTIL response packet received OR 2895 * max transmit threshold exceeded 2896 * 2897 * IF no response packet received THEN 2898 * return failure; 2899 * ELSE 2900 * IF NOT response tid = request tid THEN 2901 * ignore packet; 2902 * ELSE 2903 * CASE packet type OF 2904 * POSITIVE NAME QUERY RESPONSE: 2905 * return success; 2906 * 2907 * REDIRECT NAME QUERY RESPONSE: 2908 * 2909 * (* 2910 * * NAME node wants this end node 2911 * * to use some other NAME node 2912 * * to resolve the query. 2913 * *) 2914 * 2915 * repeat query with NAME address 2916 * in the response packet; 2917 * NEGATIVE NAME QUERY RESPONSE: 2918 * return failure; 2919 * 2920 * END (* case *) 2921 * END (* procedure *) 2922 */ 2923 static int 2924 smb_name_Pnode_find_name(struct name_entry *name) 2925 { 2926 struct name_question question; 2927 2928 /* 2929 * Host initiated processing for a P node 2930 */ 2931 question.name = name; 2932 question.name->attributes |= NAME_NB_FLAGS_ONT_P; 2933 question.question_type = NAME_QUESTION_TYPE_NB; 2934 question.question_class = NAME_QUESTION_CLASS_IN; 2935 2936 return (smb_send_name_query_request(UNICAST, &question)); 2937 } 2938 2939 /* 2940 * 5.1.2.4. P-NODE DELETE_NAME 2941 * 2942 * PROCEDURE delete_name (name) 2943 * 2944 * (* 2945 * * Host initiated processing for a P node 2946 * *) 2947 * 2948 * BEGIN 2949 * 2950 * REPEAT 2951 * 2952 * (* 2953 * * build packet 2954 * *) 2955 * ... 2956 * 2957 * (* 2958 * * send request 2959 * *) 2960 * 2961 * unicast NAME RELEASE REQUEST packet; 2962 * IF receive a WACK RESPONSE THEN 2963 * pause(time from TTL field of response); 2964 * ELSE 2965 * pause(UCAST_REQ_RETRY_TIMEOUT); 2966 * UNTIL retransmit count has been exceeded 2967 * or response been received 2968 * 2969 * IF response has been received THEN 2970 * CASE packet type OF 2971 * POSITIVE NAME RELEASE RESPONSE: 2972 * return success; 2973 * NEGATIVE NAME RELEASE RESPONSE: 2974 * 2975 * (* 2976 * * NAME does want node to delete this 2977 * * name !!! 2978 * *) 2979 * 2980 * return failure; 2981 * END (* case *) 2982 * END (* procedure *) 2983 */ 2984 static int 2985 smb_name_Pnode_delete_name(struct name_entry *name) 2986 { 2987 struct name_question question; 2988 struct resource_record additional; 2989 struct addr_entry *raddr; 2990 unsigned char data[MAX_DATAGRAM_LENGTH]; 2991 unsigned char *scan = data; 2992 uint32_t attr; 2993 2994 /* build packet */ 2995 question.name = name; 2996 question.name->attributes |= NAME_NB_FLAGS_ONT_P; 2997 question.question_type = NAME_QUESTION_TYPE_NB; 2998 question.question_class = NAME_QUESTION_CLASS_IN; 2999 3000 additional.name = name; 3001 additional.rr_class = NAME_QUESTION_CLASS_IN; 3002 additional.ttl = 0; 3003 additional.rdata = data; 3004 additional.rdlength = 0; 3005 additional.rr_type = NAME_QUESTION_TYPE_NB; 3006 raddr = &name->addr_list; 3007 do { 3008 scan = data; 3009 attr = name->attributes & (NAME_ATTR_GROUP | 3010 NAME_ATTR_OWNER_NODE_TYPE); 3011 3012 BE_OUT16(scan, attr); scan += 2; 3013 BE_OUT32(scan, raddr->sin.sin_addr.s_addr); scan += 4; 3014 (void) memcpy(scan, &raddr->sin.sin_addr.s_addr, 3015 sizeof (uint32_t)); 3016 scan += 4; 3017 3018 additional.rdlength = 6; 3019 raddr = raddr->forw; 3020 (void) smb_send_name_release_request_and_demand(UNICAST, 3021 &question, &additional); 3022 } while (raddr != &name->addr_list); 3023 3024 return (1); 3025 } 3026 3027 /* 3028 * 5.1.3. M-NODE ACTIVITY 3029 * 3030 * M nodes behavior is similar to that of P nodes with the addition 3031 * of some B node-like broadcast actions. M node name service 3032 * proceeds in two steps: 3033 * 3034 * 1.Use broadcast UDP based name service. Depending on the 3035 * operation, goto step 2. 3036 * 3037 * 2.Use directed UDP name service. 3038 * 3039 * The following code for M nodes is exactly the same as for a P 3040 * node, with the exception that broadcast operations are done 3041 * before P type operation is attempted. 3042 * 3043 * 5.1.3.1. M-NODE ADD NAME 3044 * 3045 * PROCEDURE add_name(name) 3046 * 3047 * (* 3048 * * Host initiated processing for a M node 3049 * *) 3050 * 3051 * BEGIN 3052 * 3053 * (* 3054 * * check if name exists on the 3055 * * broadcast area 3056 * *) 3057 * REPEAT 3058 * (* build packet *) 3059 * 3060 * .... 3061 * broadcast NAME REGISTRATION REQUEST packet; 3062 * pause(BCAST_REQ_RETRY_TIMEOUT); 3063 * 3064 * UNTIL response packet is received or 3065 * retransmit count has been exceeded 3066 * 3067 * IF valid response received THEN 3068 * BEGIN 3069 * (* cannot claim name *) 3070 * 3071 * return failure; 3072 * END 3073 * 3074 * (* 3075 * * No objections received within the 3076 * * broadcast area. 3077 * * Send request to name server. 3078 * *) 3079 * 3080 * REPEAT 3081 * (* 3082 * * build packet 3083 * *) 3084 * 3085 * ONT = M; 3086 * ... 3087 * 3088 * unicast NAME REGISTRATION REQUEST packet; 3089 * 3090 * (* 3091 * * remote NAME will send response packet 3092 * *) 3093 * 3094 * IF receive a WACK RESPONSE THEN 3095 * pause(time from TTL field of response); 3096 * ELSE 3097 * pause(UCAST_REQ_RETRY_TIMEOUT); 3098 * 3099 * UNTIL response packet is received or 3100 * retransmit count has been exceeded 3101 * 3102 * IF no response packet was received THEN 3103 * BEGIN (* no response *) 3104 * (* 3105 * * NAME is down. Cannot claim name. 3106 * *) 3107 * return failure; (* name cannot be claimed *) 3108 * END (* no response *) 3109 * ELSE 3110 * BEGIN (* response *) 3111 * IF NOT response tid = request tid THEN 3112 * BEGIN 3113 * ignore response packet; 3114 * END 3115 * ELSE 3116 * CASE packet type OF 3117 * POSITIVE NAME REGISTRATION RESPONSE: 3118 * 3119 * (* 3120 * * name can be added 3121 * *) 3122 * 3123 * adjust refresh timeout value, TTL; 3124 * return success; (* name can be added *) 3125 * 3126 * NEGATIVE NAME REGISTRATION RESPONSE: 3127 * return failure; (* name cannot be added *) 3128 * 3129 * END-NODE CHALLENGE REGISTRATION REQUEST: 3130 * BEGIN (* end node challenge *) 3131 * 3132 * (* 3133 * * The response packet has in it the 3134 * * address of the presumed owner of the 3135 * * name. Challenge that owner. 3136 * * If owner either does not 3137 * * respond or indicates that he no longer 3138 * * owns the name, claim the name. 3139 * * Otherwise, the name cannot be claimed. 3140 * * 3141 * *) 3142 * 3143 * REPEAT 3144 * (* 3145 * * build packet 3146 * *) 3147 * ... 3148 * 3149 * (* 3150 * * send packet to address contained in the 3151 * * response packet 3152 * *) 3153 * 3154 * unicast NAME QUERY REQUEST packet; 3155 * 3156 * (* 3157 * * remote node may send response packet 3158 * *) 3159 * 3160 * pause(UCAST_REQ_RETRY_TIMEOUT); 3161 * 3162 * UNTIL response packet is received or 3163 * retransmit count has been exceeded 3164 * IF no response packet is received THEN 3165 * BEGIN (* no response *) 3166 * 3167 * (* 3168 * * name can be claimed 3169 * *) 3170 * REPEAT 3171 * 3172 * (* 3173 * * build packet 3174 * *) 3175 * ... 3176 * 3177 * unicast NAME UPDATE REQUEST to NAME; 3178 * 3179 * (* 3180 * * NAME node will send response packet 3181 * *) 3182 * 3183 * IF receive a WACK RESPONSE THEN 3184 * pause(time from TTL field of response); 3185 * ELSE 3186 * pause(UCAST_REQ_RETRY_TIMEOUT); 3187 * 3188 * UNTIL response packet is received or 3189 * retransmit count has been exceeded 3190 * IF no response packet received THEN 3191 * BEGIN (* no response *) 3192 * 3193 * (* 3194 * * name could not be claimed 3195 * *) 3196 * 3197 * return failure; 3198 * END (* no response *) 3199 * ELSE 3200 * CASE packet type OF 3201 * POSITIVE NAME REGISTRATION RESPONSE: 3202 * (* 3203 * * add name 3204 * *) 3205 * 3206 * return success; 3207 * NEGATIVE NAME REGISTRATION RESPONSE: 3208 * (* 3209 * * you lose ... 3210 * *) 3211 * 3212 * return failure; 3213 * END (* case *) 3214 * END (* no response *) 3215 * ELSE 3216 * IF NOT response tid = request tid THEN 3217 * BEGIN 3218 * ignore response packet; 3219 * END 3220 * 3221 * (* 3222 * * received a response to the "challenge" 3223 * * packet 3224 * *) 3225 * 3226 * CASE packet type OF 3227 * POSITIVE NAME QUERY: 3228 * 3229 * (* 3230 * * remote node still has name. 3231 * *) 3232 * 3233 * return failure; 3234 * NEGATIVE NAME QUERY: 3235 * 3236 * (* 3237 * * remote node no longer has name 3238 * *) 3239 * 3240 * return success; 3241 * END (* case *) 3242 * END (* end node challenge *) 3243 * END (* case *) 3244 * END (* response *) 3245 * END (* procedure *) 3246 * 3247 * 3248 * 5.1.3.2. M-NODE ADD GROUP NAME 3249 * 3250 * PROCEDURE add_group_name(name) 3251 * 3252 * (* 3253 * * Host initiated processing for a P node 3254 * *) 3255 * 3256 * BEGIN 3257 * (* 3258 * * same as for a unique name, except that the 3259 * * request packet must indicate that a 3260 * * group name claim is being made. 3261 * *) 3262 * 3263 * ... 3264 * G = GROUP; 3265 * ... 3266 * 3267 * (* 3268 * * send packet 3269 * *) 3270 * ... 3271 * 3272 * 3273 * END 3274 */ 3275 static int 3276 smb_name_Mnode_add_name(struct name_entry *name) 3277 { 3278 if (smb_name_Bnode_add_name(name) > 0) { 3279 if (nbns_num == 0) 3280 return (1); /* No name server configured */ 3281 3282 return (smb_name_Pnode_add_name(name)); 3283 } 3284 return (-1); 3285 } 3286 3287 static int 3288 smb_name_Hnode_add_name(struct name_entry *name) 3289 { 3290 if (nbns_num > 0) { 3291 if (smb_name_Pnode_add_name(name) == 1) 3292 return (1); 3293 } 3294 3295 return (smb_name_Bnode_add_name(name)); 3296 } 3297 3298 /* 3299 * 5.1.3.3. M-NODE FIND NAME 3300 * 3301 * PROCEDURE find_name(name) 3302 * 3303 * (* 3304 * * Host initiated processing for a M node 3305 * *) 3306 * 3307 * BEGIN 3308 * (* 3309 * * check if any node on the broadcast 3310 * * area has the name 3311 * *) 3312 * 3313 * REPEAT 3314 * (* build packet *) 3315 * ... 3316 * 3317 * broadcast NAME QUERY REQUEST packet; 3318 * pause(BCAST_REQ_RETRY_TIMEOUT); 3319 * UNTIL response packet received OR 3320 * max transmit threshold exceeded 3321 * 3322 * IF valid response received THEN 3323 * BEGIN 3324 * save response as authoritative response; 3325 * start_timer(CONFLICT_TIMER); 3326 * return success; 3327 * END 3328 * 3329 * (* 3330 * * no valid response on the b'cast segment. 3331 * * Try the name server. 3332 * *) 3333 * 3334 * REPEAT 3335 * (* 3336 * * build packet 3337 * *) 3338 * 3339 * ONT = M; 3340 * G = DONT CARE; 3341 * 3342 * unicast NAME QUERY REQUEST packet to NAME; 3343 * 3344 * (* 3345 * * a NAME node might send response packet 3346 * *) 3347 * 3348 * IF receive a WACK RESPONSE THEN 3349 * pause(time from TTL field of response); 3350 * ELSE 3351 * pause(UCAST_REQ_RETRY_TIMEOUT); 3352 * UNTIL response packet received OR 3353 * max transmit threshold exceeded 3354 * 3355 * IF no response packet received THEN 3356 * return failure; 3357 * ELSE 3358 * IF NOT response tid = request tid THEN 3359 * ignore packet; 3360 * ELSE 3361 * CASE packet type OF 3362 * POSITIVE NAME QUERY RESPONSE: 3363 * return success; 3364 * 3365 * REDIRECT NAME QUERY RESPONSE: 3366 * 3367 * (* 3368 * * NAME node wants this end node 3369 * * to use some other NAME node 3370 * * to resolve the query. 3371 * *) 3372 * 3373 * repeat query with NAME address 3374 * in the response packet; 3375 * NEGATIVE NAME QUERY RESPONSE: 3376 * return failure; 3377 * 3378 * END (* case *) 3379 * END (* procedure *) 3380 */ 3381 static int 3382 smb_name_Mnode_find_name(struct name_entry *name) 3383 { 3384 if (smb_name_Bnode_find_name(name) == 1) 3385 return (1); 3386 3387 if (nbns_num == 0) 3388 return (1); /* No name server configured */ 3389 3390 return (smb_name_Pnode_find_name(name)); 3391 } 3392 3393 static int 3394 smb_name_Hnode_find_name(struct name_entry *name) 3395 { 3396 if (nbns_num > 0) 3397 if (smb_name_Pnode_find_name(name) == 1) 3398 return (1); 3399 3400 return (smb_name_Bnode_find_name(name)); 3401 } 3402 3403 /* 3404 * 5.1.3.4. M-NODE DELETE NAME 3405 * 3406 * PROCEDURE delete_name (name) 3407 * 3408 * (* 3409 * * Host initiated processing for a P node 3410 * *) 3411 * 3412 * BEGIN 3413 * (* 3414 * * First, delete name on NAME 3415 * *) 3416 * 3417 * REPEAT 3418 * 3419 * (* 3420 * * build packet 3421 * struct addr_entry *addr; 3422 * *) 3423 * ... 3424 * 3425 * (* 3426 * * send request 3427 * *) 3428 * 3429 * unicast NAME RELEASE REQUEST packet to NAME; 3430 * 3431 * IF receive a WACK RESPONSE THEN 3432 * pause(time from TTL field of response); 3433 * ELSE 3434 * pause(UCAST_REQ_RETRY_TIMEOUT); 3435 * UNTIL retransmit count has been exceeded 3436 * or response been received 3437 * 3438 * IF response has been received THEN 3439 * CASE packet type OF 3440 * POSITIVE NAME RELEASE RESPONSE: 3441 * (* 3442 * * Deletion of name on b'cast segment is deferred 3443 * * until after NAME has deleted the name 3444 * *) 3445 * 3446 * REPEAT 3447 * (* build packet *) 3448 * 3449 * ... 3450 * broadcast NAME RELEASE REQUEST; 3451 * pause(BCAST_REQ_RETRY_TIMEOUT); 3452 * UNTIL rexmt threshold exceeded 3453 * 3454 * return success; 3455 * NEGATIVE NAME RELEASE RESPONSE: 3456 * 3457 * (* 3458 * * NAME does want node to delete this 3459 * * name 3460 * *) 3461 * return failure; 3462 * END (* case *) 3463 * END (* procedure *) 3464 */ 3465 static int 3466 smb_name_Mnode_delete_name(struct name_entry *name) 3467 { 3468 (void) smb_name_Bnode_delete_name(name); 3469 3470 if (nbns_num == 0) 3471 return (-1); /* No name server configured */ 3472 3473 if (smb_name_Pnode_delete_name(name) > 0) 3474 return (1); 3475 3476 return (-1); 3477 } 3478 3479 static int 3480 smb_name_Hnode_delete_name(struct name_entry *name) 3481 { 3482 if (nbns_num > 0) 3483 if (smb_name_Pnode_delete_name(name) > 0) 3484 return (1); 3485 3486 return (smb_name_Bnode_delete_name(name)); 3487 } 3488 3489 /* 3490 * 5.1.1.5. B-NODE INCOMING PACKET PROCESSING 3491 * 3492 * Following processing is done when broadcast or unicast packets 3493 * are received at the NAME_SERVICE_UDP_PORT. 3494 * 3495 * PROCEDURE process_incoming_packet(packet) 3496 * 3497 * (* 3498 * * Processing initiated by incoming packets for a B node 3499 * *) 3500 * 3501 * BEGIN 3502 * (* 3503 * * Note: response packets are always sent 3504 * * to: 3505 * * source IP address of request packet 3506 * * source UDP port of request packet 3507 * *) 3508 * 3509 * CASE packet type OF 3510 * 3511 * NAME REGISTRATION REQUEST (UNIQUE): 3512 * IF name exists in local name table THEN 3513 * send NEGATIVE_NAME_REGISTRATION_RESPONSE ; 3514 * NAME REGISTRATION REQUEST (GROUP): 3515 * IF name exists in local name table THEN 3516 * BEGIN 3517 * IF local entry is a unique name THEN 3518 * send NEGATIVE_NAME_REGISTRATION_RESPONSE ; 3519 * END 3520 * NAME QUERY REQUEST: 3521 * IF name exists in local name table THEN 3522 * BEGIN 3523 * build response packet; 3524 * send POSITIVE_NAME_QUERY_RESPONSE; 3525 * POSITIVE NAME QUERY RESPONSE: 3526 * IF name conflict timer is not active THEN 3527 * BEGIN 3528 * (* 3529 * * timer has expired already... ignore this 3530 * * packet 3531 * *) 3532 * 3533 * return; 3534 * END 3535 * ELSE (* timer is active *) 3536 * IF a response for this name has previously been 3537 * received THEN 3538 * BEGIN (* existing entry *) 3539 * 3540 * (* 3541 * * we sent out a request packet, and 3542 * * have already received (at least) 3543 * * one response 3544 * * 3545 * * Check if conflict exists. 3546 * * If so, send out a conflict packet. 3547 * * 3548 * * Note: detecting conflict does NOT 3549 * * affect any existing sessions. 3550 * * 3551 * *) 3552 * 3553 * (* 3554 * * Check for name conflict. 3555 * * See "Name Conflict" in Concepts and Methods 3556 * *) 3557 * check saved authoritative response against 3558 * information in this response packet; 3559 * IF conflict detected THEN 3560 * BEGIN 3561 * unicast NAME CONFLICT DEMAND packet; 3562 * IF entry exists in cache THEN 3563 * BEGIN 3564 * remove entry from cache; 3565 * END 3566 * END 3567 * END (* existing entry *) 3568 * ELSE 3569 * BEGIN 3570 * (* 3571 * * Note: If this was the first response 3572 * * to a name query, it would have been 3573 * * handled in the 3574 * * find_name() procedure. 3575 * *) 3576 * 3577 * ignore packet; 3578 * END 3579 * NAME CONFLICT DEMAND: 3580 * IF name exists in local name table THEN 3581 * BEGIN 3582 * mark name as conflict detected; 3583 * 3584 * (* 3585 * * a name in the state "conflict detected" 3586 * * does not "logically" exist on that node. 3587 * * No further session will be accepted on 3588 * * that name. 3589 * * No datagrams can be sent against that name. 3590 * * Such an entry will not be used for 3591 * * purposes of processing incoming request 3592 * * packets. 3593 * * The only valid user NetBIOS operation 3594 * * against such a name is DELETE NAME. 3595 * *) 3596 * END 3597 * NAME RELEASE REQUEST: 3598 * IF caching is being done THEN 3599 * BEGIN 3600 * remove entry from cache; 3601 * END 3602 * NAME UPDATE REQUEST: 3603 * IF caching is being done THEN 3604 * BEGIN 3605 * IF entry exists in cache already, 3606 * update cache; 3607 * ELSE IF name is "interesting" THEN 3608 * BEGIN 3609 * add entry to cache; 3610 * END 3611 * END 3612 * 3613 * NODE STATUS REQUEST: 3614 * IF name exists in local name table THEN 3615 * BEGIN 3616 * (* 3617 * * send only those names that are 3618 * * in the same scope as the scope 3619 * * field in the request packet 3620 * *) 3621 * 3622 * send NODE STATUS RESPONSE; 3623 * END 3624 * END 3625 */ 3626 static void 3627 smb_name_process_Bnode_packet(struct name_packet *packet, 3628 struct addr_entry *addr) 3629 { 3630 struct name_entry *name; 3631 struct name_entry *entry; 3632 struct name_question *question; 3633 struct resource_record *additional; 3634 3635 question = packet->question; 3636 additional = packet->additional; 3637 3638 switch (packet->info & NAME_OPCODE_OPCODE_MASK) { 3639 case NAME_OPCODE_REFRESH: 3640 /* Guard against malformed packets */ 3641 if ((question == 0) || (additional == 0)) 3642 break; 3643 if (additional->name->addr_list.sin.sin_addr.s_addr == 0) 3644 break; 3645 3646 name = question->name; 3647 name->addr_list.ttl = additional->ttl; 3648 name->attributes = additional->name->attributes; 3649 name->addr_list.sin = additional->name->addr_list.sin; 3650 name->addr_list.forw = name->addr_list.back = &name->addr_list; 3651 3652 if ((entry = smb_netbios_cache_lookup_addr(name)) != 0) { 3653 smb_netbios_cache_update_entry(entry, question->name); 3654 smb_netbios_cache_unlock_entry(entry); 3655 } 3656 else 3657 (void) smb_netbios_cache_insert(question->name); 3658 break; 3659 3660 case NAME_OPCODE_QUERY: 3661 /* 3662 * This opcode covers both NAME_QUERY_REQUEST and 3663 * NODE_STATUS_REQUEST. They can be distinguished 3664 * based on the type of question entry. 3665 */ 3666 3667 /* All query requests have to have question entry */ 3668 if (question == 0) 3669 break; 3670 3671 if (question->question_type == NAME_QUESTION_TYPE_NB) { 3672 name = question->name; 3673 if ((entry = smb_netbios_cache_lookup(name)) != 0) { 3674 (void) smb_send_name_query_response(addr, 3675 packet, entry, 0); 3676 smb_netbios_cache_unlock_entry(entry); 3677 } 3678 } 3679 else 3680 if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) { 3681 /* 3682 * Name of "*" may be used to force node to 3683 * divulge status for administrative purposes 3684 */ 3685 name = question->name; 3686 entry = 0; 3687 if (NETBIOS_NAME_IS_STAR(name->name) || 3688 ((entry = smb_netbios_cache_lookup(name)) != 0)) { 3689 if (entry) 3690 smb_netbios_cache_unlock_entry(entry); 3691 /* 3692 * send only those names that are 3693 * in the same scope as the scope 3694 * field in the request packet 3695 */ 3696 (void) smb_send_node_status_response(addr, 3697 packet); 3698 } 3699 } 3700 break; 3701 3702 default: 3703 break; 3704 } 3705 } 3706 3707 /* 3708 * 5.1.2.5. P-NODE INCOMING PACKET PROCESSING 3709 * 3710 * Processing initiated by reception of packets at a P node 3711 * 3712 * PROCEDURE process_incoming_packet(packet) 3713 * 3714 * (* 3715 * * Processing initiated by incoming packets at a P node 3716 * *) 3717 * 3718 * BEGIN 3719 * (* 3720 * * always ignore UDP broadcast packets 3721 * *) 3722 * 3723 * IF packet was sent as a broadcast THEN 3724 * BEGIN 3725 * ignore packet; 3726 * return; 3727 * END 3728 * CASE packet type of 3729 * 3730 * NAME CONFLICT DEMAND: 3731 * IF name exists in local name table THEN 3732 * mark name as in conflict; 3733 * return; 3734 * 3735 * NAME QUERY REQUEST: 3736 * IF name exists in local name table THEN 3737 * BEGIN (* name exists *) 3738 * 3739 * (* 3740 * * build packet 3741 * *) 3742 * ... 3743 * 3744 * (* 3745 * * send response to the IP address and port 3746 * * number from which the request was received. 3747 * *) 3748 * 3749 * send POSITIVE_NAME_QUERY_RESPONSE ; 3750 * return; 3751 * END (* exists *) 3752 * ELSE 3753 * BEGIN (* does not exist *) 3754 * 3755 * (* 3756 * * send response to the requestor 3757 * *) 3758 * 3759 * send NEGATIVE_NAME_QUERY_RESPONSE ; 3760 * return; 3761 * END (* does not exist *) 3762 * NODE STATUS REQUEST: 3763 * (* 3764 * * Name of "*" may be used for force node to 3765 * * divulge status for administrative purposes 3766 * *) 3767 * IF name in local name table OR name = "*" THEN 3768 * BEGIN 3769 * (* 3770 * * Build response packet and 3771 * * send to requestor node 3772 * * Send only those names that are 3773 * * in the same scope as the scope 3774 * * in the request packet. 3775 * *) 3776 * 3777 * send NODE_STATUS_RESPONSE; 3778 * END 3779 * 3780 * NAME RELEASE REQUEST: 3781 * (* 3782 * * This will be received if the NAME wants to flush the 3783 * * name from the local name table, or from the local 3784 * * cache. 3785 * *) 3786 * 3787 * IF name exists in the local name table THEN 3788 * BEGIN 3789 * delete name from local name table; 3790 * inform user that name has been deleted; 3791 * END 3792 * END (* case *) 3793 * END (* procedure *) 3794 * 3795 * (* 3796 * * Incoming packet processing on a NS node 3797 * *) 3798 * 3799 * BEGIN 3800 * IF packet was sent as a broadcast THEN 3801 * BEGIN 3802 * discard packet; 3803 * return; 3804 * END 3805 * CASE packet type of 3806 * 3807 * NAME REGISTRATION REQUEST (UNIQUE): 3808 * IF unique name exists in data base THEN 3809 * BEGIN (* unique name exists *) 3810 * (* 3811 * * NAME node may be a "passive" 3812 * * server in that it expects the 3813 * * end node to do the challenge 3814 * * server. Such a NAME node is 3815 * * called a "non-secure" server. 3816 * * A "secure" server will do the 3817 * * challenging before it sends 3818 * * back a response packet. 3819 * *) 3820 * 3821 * IF non-secure THEN 3822 * BEGIN 3823 * (* 3824 * * build response packet 3825 * *) 3826 * ... 3827 * 3828 * 3829 * (* 3830 * * let end node do the challenge 3831 * *) 3832 * 3833 * send END-NODE CHALLENGE NAME REGISTRATION 3834 * RESPONSE; 3835 * return; 3836 * END 3837 * ELSE 3838 * (* 3839 * * secure server - do the name 3840 * * challenge operation 3841 * *) 3842 * 3843 * REPEAT 3844 * send NAME QUERY REQUEST; 3845 * pause(UCAST_REQ_RETRY_TIMEOUT); 3846 * UNTIL response has been received or 3847 * retransmit count has been exceeded 3848 * IF no response was received THEN 3849 * BEGIN 3850 * 3851 * (* node down *) 3852 * 3853 * update data base - remove entry; 3854 * update data base - add new entry; 3855 * send POSITIVE NAME REGISTRATION RESPONSE; 3856 * return; 3857 * END 3858 * ELSE 3859 * BEGIN (* challenged node replied *) 3860 * (* 3861 * * challenged node replied with 3862 * * a response packet 3863 * *) 3864 * 3865 * CASE packet type 3866 * 3867 * POSITIVE NAME QUERY RESPONSE: 3868 * 3869 * (* 3870 * * name still owned by the 3871 * * challenged node 3872 * * 3873 * * build packet and send response 3874 * *) 3875 * ... 3876 * 3877 * 3878 * (* 3879 * * Note: The NAME will need to 3880 * * keep track (based on transaction id) of 3881 * * the IP address and port number 3882 * * of the original requestor. 3883 * *) 3884 * 3885 * send NEGATIVE NAME REGISTRATION RESPONSE; 3886 * return; 3887 * NEGATIVE NAME QUERY RESPONSE: 3888 * 3889 * update data base - remove entry; 3890 * update data base - add new entry; 3891 * 3892 * (* 3893 * * build response packet and send 3894 * * response 3895 * *) 3896 * send POSITIVE NAME REGISTRATION RESPONSE; 3897 * return; 3898 * END (* case *) 3899 * END (* challenged node replied *) 3900 * END (* unique name exists in data base *) 3901 * ELSE 3902 * IF group name exists in data base THEN 3903 * BEGIN (* group names exists *) 3904 * 3905 * (* 3906 * * Members of a group name are NOT 3907 * * challenged. 3908 * * Make the assumption that 3909 * * at least some of the group members 3910 * * are still alive. 3911 * * Refresh mechanism will 3912 * * allow the NAME to detect when all 3913 * * members of a group no longer use that 3914 * * name 3915 * *) 3916 * 3917 * send NEGATIVE NAME REGISTRATION RESPONSE; 3918 * END (* group name exists *) 3919 * ELSE 3920 * BEGIN (* name does not exist *) 3921 * 3922 * (* 3923 * * Name does not exist in data base 3924 * * 3925 * * This code applies to both non-secure 3926 * * and secure server. 3927 * *) 3928 * 3929 * update data base - add new entry; 3930 * send POSITIVE NAME REGISTRATION RESPONSE; 3931 * return; 3932 * END 3933 * 3934 * NAME QUERY REQUEST: 3935 * IF name exists in data base THEN 3936 * BEGIN 3937 * (* 3938 * * build response packet and send to 3939 * * requestor 3940 * *) 3941 * ... 3942 * 3943 * send POSITIVE NAME QUERY RESPONSE; 3944 * return; 3945 * ELSE 3946 * BEGIN 3947 * (* 3948 * * build response packet and send to 3949 * * requestor 3950 * *) 3951 * ... 3952 * 3953 * send NEGATIVE NAME QUERY RESPONSE; 3954 * return; 3955 * END 3956 * 3957 * NAME REGISTRATION REQUEST (GROUP): 3958 * IF name exists in data base THEN 3959 * BEGIN 3960 * IF local entry is a unique name THEN 3961 * BEGIN (* local is unique *) 3962 * 3963 * IF non-secure THEN 3964 * BEGIN 3965 * send END-NODE CHALLENGE NAME 3966 * REGISTRATION RESPONSE; 3967 * return; 3968 * END 3969 * 3970 * REPEAT 3971 * send NAME QUERY REQUEST; 3972 * pause(UCAST_REQ_RETRY_TIMEOUT); 3973 * UNTIL response received or 3974 * retransmit count exceeded 3975 * IF no response received or 3976 * NEGATIVE NAME QUERY RESPONSE 3977 * received THEN 3978 * BEGIN 3979 * update data base - remove entry; 3980 * update data base - add new entry; 3981 * send POSITIVE NAME REGISTRATION RESPONSE; 3982 * return; 3983 * END 3984 * ELSE 3985 * BEGIN 3986 * (* 3987 * * name still being held 3988 * * by challenged node 3989 * *) 3990 * 3991 * send NEGATIVE NAME REGISTRATION RESPONSE; 3992 * END 3993 * END (* local is unique *) 3994 * ELSE 3995 * BEGIN (* local is group *) 3996 * (* 3997 * * existing entry is a group name 3998 * *) 3999 * 4000 * update data base - remove entry; 4001 * update data base - add new entry; 4002 * send POSITIVE NAME REGISTRATION RESPONSE; 4003 * return; 4004 * END (* local is group *) 4005 * END (* names exists *) 4006 * ELSE 4007 * BEGIN (* does not exist *) 4008 * 4009 * (* name does not exist in data base *) 4010 * 4011 * update data base - add new entry; 4012 * send POSITIVE NAME REGISTRATION RESPONSE; 4013 * return; 4014 * END (* does not exist *) 4015 * 4016 * NAME RELEASE REQUEST: 4017 * 4018 * (* 4019 * * secure server may choose to disallow 4020 * * a node from deleting a name 4021 * *) 4022 * 4023 * update data base - remove entry; 4024 * send POSITIVE NAME RELEASE RESPONSE; 4025 * return; 4026 * 4027 * NAME UPDATE REQUEST: 4028 * 4029 * (* 4030 * * End-node completed a successful challenge, 4031 * * no update database 4032 * *) 4033 * 4034 * IF secure server THEN 4035 * send NEGATIVE NAME REGISTRATION RESPONSE; 4036 * ELSE 4037 * BEGIN (* new entry *) 4038 * IF entry already exists THEN 4039 * update data base - remove entry; 4040 * update data base - add new entry; 4041 * send POSITIVE NAME REGISTRATION RESPONSE; 4042 * start_timer(TTL); 4043 * END 4044 * 4045 * NAME REFRESH REQUEST: 4046 * check for consistency; 4047 * 4048 * IF node not allowed to have name THEN 4049 * BEGIN 4050 * 4051 * (* 4052 * * tell end node that it can't have name 4053 * *) 4054 * send NEGATIVE NAME REGISTRATION RESPONSE; 4055 * END 4056 * ELSE 4057 * BEGIN 4058 * 4059 * (* 4060 * * send confirmation response to the 4061 * * end node. 4062 * *) 4063 * send POSITIVE NAME REGISTRATION; 4064 * start_timer(TTL); 4065 * END 4066 * return; 4067 * END (* case *) 4068 * END (* procedure *) 4069 */ 4070 static void 4071 smb_name_process_Pnode_packet(struct name_packet *packet, 4072 struct addr_entry *addr) 4073 { 4074 struct name_entry *name; 4075 struct name_entry *entry; 4076 struct name_question *question; 4077 struct resource_record *additional; 4078 4079 question = packet->question; 4080 additional = packet->additional; 4081 4082 if (packet->info & NAME_NM_FLAGS_B) { 4083 /* 4084 * always ignore UDP broadcast packets 4085 */ 4086 return; 4087 } 4088 4089 switch (packet->info & NAME_OPCODE_OPCODE_MASK) { 4090 case NAME_OPCODE_REFRESH: 4091 /* Guard against malformed packets */ 4092 if ((question == 0) || (additional == 0)) 4093 break; 4094 if (additional->name->addr_list.sin.sin_addr.s_addr == 0) 4095 break; 4096 4097 name = question->name; 4098 name->addr_list.ttl = additional->ttl; 4099 name->attributes = additional->name->attributes; 4100 name->addr_list.sin = additional->name->addr_list.sin; 4101 name->addr_list.forw = name->addr_list.back = &name->addr_list; 4102 4103 if ((entry = smb_netbios_cache_lookup(name)) != 0) { 4104 smb_netbios_cache_update_entry(entry, name); 4105 smb_netbios_cache_unlock_entry(entry); 4106 } 4107 else 4108 (void) smb_netbios_cache_insert(name); 4109 4110 (void) smb_send_name_registration_response(addr, packet, 0); 4111 break; 4112 4113 case NAME_OPCODE_QUERY: 4114 /* 4115 * This opcode covers both NAME_QUERY_REQUEST and 4116 * NODE_STATUS_REQUEST. They can be distinguished 4117 * based on the type of question entry. 4118 */ 4119 4120 /* All query requests have to have question entry */ 4121 if (question == 0) 4122 break; 4123 4124 if (question->question_type == NAME_QUESTION_TYPE_NB) { 4125 name = question->name; 4126 if ((entry = smb_netbios_cache_lookup(name)) != 0) { 4127 /* 4128 * send response to the IP address and port 4129 * number from which the request was received. 4130 */ 4131 (void) smb_send_name_query_response(addr, 4132 packet, entry, 0); 4133 smb_netbios_cache_unlock_entry(entry); 4134 } else { 4135 /* 4136 * send response to the requestor 4137 */ 4138 (void) smb_send_name_query_response(addr, 4139 packet, name, RCODE_NAM_ERR); 4140 } 4141 } 4142 else 4143 if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) { 4144 /* 4145 * Name of "*" may be used to force node to 4146 * divulge status for administrative purposes 4147 */ 4148 name = question->name; 4149 entry = 0; 4150 if (NETBIOS_NAME_IS_STAR(name->name) || 4151 ((entry = smb_netbios_cache_lookup(name)) != 0)) { 4152 /* 4153 * send only those names that are 4154 * in the same scope as the scope 4155 * field in the request packet 4156 */ 4157 if (entry) 4158 smb_netbios_cache_unlock_entry(entry); 4159 (void) smb_send_node_status_response(addr, 4160 packet); 4161 } 4162 } 4163 break; 4164 4165 default: 4166 break; 4167 } 4168 } 4169 4170 /* 4171 * 5.1.3.5. M-NODE INCOMING PACKET PROCESSING 4172 * 4173 * Processing initiated by reception of packets at a M node 4174 * 4175 * PROCEDURE process_incoming_packet(packet) 4176 * 4177 * (* 4178 * * Processing initiated by incoming packets at a M node 4179 * *) 4180 * 4181 * BEGIN 4182 * CASE packet type of 4183 * 4184 * NAME CONFLICT DEMAND: 4185 * IF name exists in local name table THEN 4186 * mark name as in conflict; 4187 * return; 4188 * 4189 * NAME QUERY REQUEST: 4190 * IF name exists in local name table THEN 4191 * BEGIN (* name exists *) 4192 * 4193 * (* 4194 * * build packet 4195 * *) 4196 * ... 4197 * 4198 * (* 4199 * * send response to the IP address and port 4200 * * number from which the request was received. 4201 * *) 4202 * 4203 * send POSITIVE NAME QUERY RESPONSE ; 4204 * return; 4205 * END (* exists *) 4206 * ELSE 4207 * BEGIN (* does not exist *) 4208 * 4209 * (* 4210 * * send response to the requestor 4211 * *) 4212 * 4213 * IF request NOT broadcast THEN 4214 * (* 4215 * * Don't send negative responses to 4216 * * queries sent by B nodes 4217 * *) 4218 * send NEGATIVE NAME QUERY RESPONSE ; 4219 * return; 4220 * END (* does not exist *) 4221 * NODE STATUS REQUEST: 4222 * BEGIN 4223 * (* 4224 * * Name of "*" may be used to force node to 4225 * * divulge status for administrative purposes 4226 * *) 4227 * IF name in local name table OR name = "*" THEN 4228 * (* 4229 * * Build response packet and 4230 * * send to requestor node 4231 * * Send only those names that are 4232 * * in the same scope as the scope 4233 * * in the request packet. 4234 * *) 4235 * 4236 * send NODE STATUS RESPONSE; 4237 * END 4238 * 4239 * NAME RELEASE REQUEST: 4240 * (* 4241 * * This will be received if the NAME wants to flush the 4242 * * name from the local name table, or from the local 4243 * * cache. 4244 * *) 4245 * 4246 * IF name exists in the local name table THEN 4247 * BEGIN 4248 * delete name from local name table; 4249 * inform user that name has been deleted; 4250 * END 4251 * NAME REGISTRATION REQUEST (UNIQUE): 4252 * IF name exists in local name table THEN 4253 * send NEGATIVE NAME REGISTRATION RESPONSE ; 4254 * NAME REGISTRATION REQUEST (GROUP): 4255 * IF name exists in local name table THEN 4256 * BEGIN 4257 * IF local entry is a unique name THEN 4258 * send NEGATIVE NAME REGISTRATION RESPONSE ; 4259 * END 4260 * END (* case *) 4261 * END (* procedure *) 4262 */ 4263 static void 4264 smb_name_process_Mnode_packet(struct name_packet *packet, 4265 struct addr_entry *addr) 4266 { 4267 if (packet->info & NAME_NM_FLAGS_B) 4268 smb_name_process_Bnode_packet(packet, addr); 4269 else 4270 smb_name_process_Pnode_packet(packet, addr); 4271 } 4272 4273 static void 4274 smb_name_process_Hnode_packet(struct name_packet *packet, 4275 struct addr_entry *addr) 4276 { 4277 if (packet->info & NAME_NM_FLAGS_B) 4278 smb_name_process_Bnode_packet(packet, addr); 4279 else 4280 smb_name_process_Pnode_packet(packet, addr); 4281 } 4282 4283 4284 /* 4285 * smb_netbios_name_tick 4286 * 4287 * Called once a second to handle name server timeouts. 4288 */ 4289 void 4290 smb_netbios_name_tick(void) 4291 { 4292 struct name_entry *name; 4293 struct name_entry *entry; 4294 4295 (void) mutex_lock(&refresh_queue.mtx); 4296 smb_netbios_cache_refresh(&refresh_queue); 4297 4298 while ((name = refresh_queue.head.forw) != &refresh_queue.head) { 4299 QUEUE_CLIP(name); 4300 if (IS_LOCAL(name->attributes)) { 4301 if (IS_UNIQUE(name->attributes)) { 4302 (void) smb_name_Pnode_refresh_name(name); 4303 } 4304 } else { 4305 entry = smb_name_find_name(name); 4306 smb_name_unlock_name(entry); 4307 } 4308 free(name); 4309 } 4310 (void) mutex_unlock(&refresh_queue.mtx); 4311 4312 smb_netbios_cache_reset_ttl(); 4313 } 4314 4315 4316 /* 4317 * smb_name_find_name 4318 * 4319 * Lookup name cache for the given name. 4320 * If it's not in the cache it'll send a 4321 * name query request and then lookup the 4322 * cache again. Note that if a name is 4323 * returned it's locked and called MUST 4324 * unlock it by calling smb_name_unlock_name() 4325 */ 4326 struct name_entry * 4327 smb_name_find_name(struct name_entry *name) 4328 { 4329 struct name_entry *result; 4330 4331 if ((result = smb_netbios_cache_lookup(name)) == 0) { 4332 switch (smb_node_type) { 4333 case 'B': 4334 (void) smb_name_Bnode_find_name(name); 4335 break; 4336 case 'P': 4337 (void) smb_name_Pnode_find_name(name); 4338 break; 4339 case 'M': 4340 (void) smb_name_Mnode_find_name(name); 4341 break; 4342 case 'H': 4343 default: 4344 (void) smb_name_Hnode_find_name(name); 4345 break; 4346 } 4347 return (smb_netbios_cache_lookup(name)); 4348 } 4349 4350 return (result); 4351 } 4352 4353 void 4354 smb_name_unlock_name(struct name_entry *name) 4355 { 4356 smb_netbios_cache_unlock_entry(name); 4357 } 4358 4359 int 4360 smb_name_add_name(struct name_entry *name) 4361 { 4362 int rc = 1; 4363 4364 smb_netbios_name_dump(name); 4365 4366 switch (smb_node_type) { 4367 case 'B': 4368 rc = smb_name_Bnode_add_name(name); 4369 break; 4370 case 'P': 4371 rc = smb_name_Pnode_add_name(name); 4372 break; 4373 case 'M': 4374 rc = smb_name_Mnode_add_name(name); 4375 break; 4376 case 'H': 4377 default: 4378 rc = smb_name_Hnode_add_name(name); 4379 break; 4380 } 4381 4382 if (rc >= 0) 4383 (void) smb_netbios_cache_insert(name); 4384 4385 return (rc); 4386 } 4387 4388 int 4389 smb_name_delete_name(struct name_entry *name) 4390 { 4391 int rc; 4392 unsigned char type; 4393 4394 type = name->name[15]; 4395 if ((type != 0x00) && (type != 0x20)) { 4396 syslog(LOG_ERR, 4397 "netbios: error trying to delete non-local name"); 4398 smb_netbios_name_logf(name); 4399 name->attributes &= ~NAME_ATTR_LOCAL; 4400 return (-1); 4401 } 4402 4403 smb_netbios_cache_delete(name); 4404 4405 switch (smb_node_type) { 4406 case 'B': 4407 rc = smb_name_Bnode_delete_name(name); 4408 break; 4409 case 'P': 4410 rc = smb_name_Pnode_delete_name(name); 4411 break; 4412 case 'M': 4413 rc = smb_name_Mnode_delete_name(name); 4414 break; 4415 case 'H': 4416 default: 4417 rc = smb_name_Hnode_delete_name(name); 4418 break; 4419 } 4420 4421 if (rc > 0) 4422 return (0); 4423 4424 return (-1); 4425 } 4426 4427 typedef struct { 4428 struct addr_entry *addr; 4429 char *buf; 4430 int length; 4431 } worker_param_t; 4432 4433 /* 4434 * smb_netbios_worker 4435 * 4436 * Process incoming request/response packets for Netbios 4437 * name service (on port 138). 4438 */ 4439 void * 4440 smb_netbios_worker(void *arg) 4441 { 4442 worker_param_t *p = (worker_param_t *)arg; 4443 struct addr_entry *addr = p->addr; 4444 struct name_packet *packet; 4445 4446 if ((packet = smb_name_buf_to_packet(p->buf, p->length)) != 0) { 4447 if (packet->info & NAME_OPCODE_R) { 4448 /* Reply packet */ 4449 smb_reply_ready(packet, addr); 4450 free(p->buf); 4451 free(p); 4452 return (0); 4453 } 4454 4455 /* Request packet */ 4456 switch (smb_node_type) { 4457 case 'B': 4458 smb_name_process_Bnode_packet(packet, addr); 4459 break; 4460 case 'P': 4461 smb_name_process_Pnode_packet(packet, addr); 4462 break; 4463 case 'M': 4464 smb_name_process_Mnode_packet(packet, addr); 4465 break; 4466 case 'H': 4467 default: 4468 smb_name_process_Hnode_packet(packet, addr); 4469 break; 4470 } 4471 4472 if (packet->answer) 4473 smb_netbios_name_freeaddrs(packet->answer->name); 4474 free(packet); 4475 } 4476 else 4477 { 4478 syslog(LOG_DEBUG, "SmbNBNS: error decoding received packet"); 4479 } 4480 4481 free(addr); 4482 free(p->buf); 4483 free(p); 4484 return (0); 4485 } 4486 4487 static void 4488 smb_netbios_wins_config(char *ip) 4489 { 4490 uint32_t ipaddr; 4491 4492 ipaddr = inet_addr(ip); 4493 if (ipaddr != INADDR_NONE) { 4494 smb_nbns[nbns_num].flags = ADDR_FLAG_VALID; 4495 smb_nbns[nbns_num].sinlen = sizeof (struct sockaddr_in); 4496 smb_nbns[nbns_num].sin.sin_family = AF_INET; 4497 smb_nbns[nbns_num].sin.sin_addr.s_addr = ipaddr; 4498 smb_nbns[nbns_num++].sin.sin_port = 4499 htons(NAME_SERVICE_UDP_PORT); 4500 smb_node_type = 'H'; 4501 } 4502 } 4503 4504 void 4505 smb_netbios_name_config(void) 4506 { 4507 uint32_t ipaddr; 4508 struct name_entry name; 4509 char myname[MAXHOSTNAMELEN]; 4510 int i; 4511 int smb_nc_cnt; 4512 net_cfg_t cfg; 4513 char wins_ip[16]; 4514 4515 if (smb_getnetbiosname(myname, MAXHOSTNAMELEN) != 0) 4516 return; 4517 4518 /* Start with no broadcast addresses */ 4519 bcast_num = 0; 4520 bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS); 4521 4522 smb_nc_cnt = smb_nic_get_num(); 4523 /* Add all of my broadcast addresses */ 4524 for (i = 0; i < smb_nc_cnt; i++) { 4525 if (smb_nic_get_byind(i, &cfg) == NULL) { 4526 break; 4527 } 4528 smb_bcast_list[bcast_num].flags = ADDR_FLAG_VALID; 4529 smb_bcast_list[bcast_num].attributes = NAME_ATTR_LOCAL; 4530 smb_bcast_list[bcast_num].sinlen = sizeof (struct sockaddr_in); 4531 smb_bcast_list[bcast_num].sin.sin_family = AF_INET; 4532 smb_bcast_list[bcast_num].sin.sin_port = 4533 htons(NAME_SERVICE_UDP_PORT); 4534 smb_bcast_list[bcast_num++].sin.sin_addr.s_addr = 4535 cfg.broadcast; 4536 } 4537 4538 /* Start with no WINS */ 4539 smb_node_type = 'B'; 4540 nbns_num = 0; 4541 bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS); 4542 4543 /* add any configured WINS */ 4544 (void) smb_config_getstr(SMB_CI_WINS_SRV1, wins_ip, sizeof (wins_ip)); 4545 smb_netbios_wins_config(wins_ip); 4546 (void) smb_config_getstr(SMB_CI_WINS_SRV2, wins_ip, sizeof (wins_ip)); 4547 smb_netbios_wins_config(wins_ip); 4548 4549 for (i = 0; i < smb_nc_cnt; i++) { 4550 if (smb_nic_get_byind(i, &cfg) == NULL) { 4551 break; 4552 } 4553 if (cfg.exclude) 4554 continue; 4555 4556 ipaddr = cfg.ip; 4557 smb_init_name_struct((unsigned char *)myname, 0x00, 0, ipaddr, 4558 htons(DGM_SRVC_UDP_PORT), NAME_ATTR_UNIQUE, 4559 NAME_ATTR_LOCAL, &name); 4560 (void) smb_name_add_name(&name); 4561 4562 smb_init_name_struct((unsigned char *)myname, 0x20, 0, 4563 ipaddr, htons(DGM_SRVC_UDP_PORT), 4564 NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name); 4565 (void) smb_name_add_name(&name); 4566 } 4567 } 4568 4569 void 4570 smb_netbios_name_unconfig(void) 4571 { 4572 struct name_entry *name; 4573 4574 (void) mutex_lock(&delete_queue.mtx); 4575 smb_netbios_cache_delete_locals(&delete_queue); 4576 4577 while ((name = delete_queue.head.forw) != &delete_queue.head) { 4578 QUEUE_CLIP(name); 4579 (void) smb_name_delete_name(name); 4580 free(name); 4581 } 4582 (void) mutex_unlock(&delete_queue.mtx); 4583 } 4584 4585 void 4586 smb_netbios_name_reconfig(void) 4587 { 4588 smb_netbios_name_unconfig(); 4589 smb_netbios_name_config(); 4590 } 4591 4592 /* 4593 * process_incoming Function: void smb_netbios_name_service_daemon(void) 4594 * 4595 * Description: 4596 * 4597 * Put test description here. 4598 * 4599 * Inputs: 4600 * Nothing 4601 * 4602 * Returns: 4603 * int -> Description 4604 */ 4605 /*ARGSUSED*/ 4606 void * 4607 smb_netbios_name_service_daemon(void *arg) 4608 { 4609 struct sockaddr_in sin; 4610 struct addr_entry *addr; 4611 int len; 4612 int flag = 1; 4613 char *buf; 4614 worker_param_t *worker_param; 4615 net_cfg_t cfg; 4616 4617 /* 4618 * Initialize reply_queue 4619 */ 4620 bzero(&reply_queue, sizeof (reply_queue)); 4621 reply_queue.forw = reply_queue.back = &reply_queue; 4622 4623 if (!smb_netbios_cache_init()) 4624 return (0); 4625 4626 bcast_num = 0; 4627 bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS); 4628 4629 if ((name_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 4630 syslog(LOG_ERR, 4631 "smbd: Could not create AF_INET, SOCK_DGRAM, socket"); 4632 smb_netbios_cache_fini(); 4633 smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1); 4634 return (0); 4635 } 4636 4637 (void) setsockopt(name_sock, SOL_SOCKET, SO_BROADCAST, &flag, 4638 sizeof (flag)); 4639 4640 bzero(&sin, sizeof (struct sockaddr_in)); 4641 sin.sin_family = AF_INET; 4642 sin.sin_port = htons(NAME_SERVICE_UDP_PORT); 4643 if (bind(name_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) { 4644 syslog(LOG_ERR, 4645 "smbd: Bind to name service port %d failed (%d)", 4646 NAME_SERVICE_UDP_PORT, errno); 4647 smb_netbios_cache_fini(); 4648 (void) close(name_sock); 4649 smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1); 4650 return (0); 4651 } 4652 4653 smb_netbios_chg_status(NETBIOS_NAME_SVC_RUNNING, 1); 4654 4655 while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) || 4656 (nb_status.state & NETBIOS_BROWSER_RUNNING)) { 4657 if ((buf = malloc(MAX_DATAGRAM_LENGTH)) == 0) { 4658 /* Sleep for 10 sec and try again */ 4659 (void) sleep(10); 4660 continue; 4661 } 4662 if ((addr = (struct addr_entry *) 4663 malloc(sizeof (struct addr_entry))) == 0) { 4664 /* Sleep for 10 sec and try again */ 4665 free(buf); 4666 (void) sleep(10); 4667 continue; 4668 } 4669 ignore: bzero(addr, sizeof (struct addr_entry)); 4670 addr->sinlen = sizeof (addr->sin); 4671 addr->forw = addr->back = addr; 4672 4673 if ((len = recvfrom(name_sock, buf, MAX_DATAGRAM_LENGTH, 4674 0, (struct sockaddr *)&addr->sin, &addr->sinlen)) < 0) { 4675 if (errno == ENOMEM || errno == ENFILE || 4676 errno == EMFILE) { 4677 /* Sleep for 10 sec and try again */ 4678 free(buf); 4679 free(addr); 4680 (void) sleep(10); 4681 continue; 4682 } 4683 syslog(LOG_ERR, 4684 "smbd: NETBIOS name service - recvfrom failed"); 4685 free(buf); 4686 free(addr); 4687 smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1); 4688 goto shutdown; 4689 } 4690 4691 /* Ignore any incoming packets from myself... */ 4692 if (smb_nic_get_byip(addr->sin.sin_addr.s_addr, 4693 &cfg) != NULL) { 4694 goto ignore; 4695 } 4696 4697 /* 4698 * Launch a netbios worker to process the received packet. 4699 */ 4700 worker_param = (worker_param_t *) 4701 malloc(sizeof (worker_param_t)); 4702 if (worker_param) { 4703 pthread_t worker; 4704 pthread_attr_t tattr; 4705 4706 worker_param->addr = addr; 4707 worker_param->buf = buf; 4708 worker_param->length = len; 4709 4710 (void) pthread_attr_init(&tattr); 4711 (void) pthread_attr_setdetachstate(&tattr, 4712 PTHREAD_CREATE_DETACHED); 4713 (void) pthread_create(&worker, &tattr, 4714 smb_netbios_worker, worker_param); 4715 (void) pthread_attr_destroy(&tattr); 4716 } 4717 } 4718 4719 shutdown: 4720 smb_netbios_chg_status(NETBIOS_NAME_SVC_RUNNING, 0); 4721 4722 (void) mutex_lock(&nb_status.mtx); 4723 while (nb_status.state & NETBIOS_BROWSER_RUNNING) 4724 (void) cond_wait(&nb_status.cv, &nb_status.mtx); 4725 (void) mutex_unlock(&nb_status.mtx); 4726 4727 if ((nb_status.state & NETBIOS_NAME_SVC_FAILED) == 0) { 4728 /* this might delay shutdown, do we want to do this? */ 4729 /* 4730 * it'll send name release requests but nobody's waiting 4731 * for response and it'll eventually timeout. 4732 */ 4733 smb_netbios_name_unconfig(); 4734 } 4735 (void) close(name_sock); 4736 smb_netbios_cache_fini(); 4737 syslog(LOG_DEBUG, "smbd: Netbios Name Service is down\n"); 4738 return (0); 4739 } 4740