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