1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 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 2138 bzero(&packet, sizeof (struct name_packet)); 2139 bzero(&answer, sizeof (struct resource_record)); 2140 2141 packet.name_trn_id = original_packet->name_trn_id; 2142 packet.info = NODE_STATUS_RESPONSE; 2143 packet.qdcount = 0; /* question entries */ 2144 packet.question = NULL; 2145 packet.ancount = 1; /* answer recs */ 2146 packet.answer = &answer; 2147 packet.nscount = 0; /* authority recs */ 2148 packet.authority = NULL; 2149 packet.arcount = 0; /* additional recs */ 2150 packet.additional = NULL; 2151 2152 answer.name = original_packet->question->name; 2153 answer.rr_type = NAME_RR_TYPE_NBSTAT; 2154 answer.rr_class = NAME_QUESTION_CLASS_IN; 2155 answer.ttl = 0; 2156 answer.rdata = data; 2157 2158 scan = smb_netbios_cache_status(data, MAX_NETBIOS_REPLY_DATA_SIZE, 2159 original_packet->question->name->scope); 2160 2161 scan_end = data + MAX_NETBIOS_REPLY_DATA_SIZE; 2162 2163 if (smb_nic_exists(addr->sin.sin_addr.s_addr, B_TRUE)) 2164 net_ipaddr = addr->sin.sin_addr.s_addr; 2165 else 2166 net_ipaddr = 0; 2167 2168 (void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &max_connections); 2169 2170 while (!scan_done) { 2171 if ((scan + 6) >= scan_end) { 2172 packet.info |= NAME_NM_FLAGS_TC; 2173 break; 2174 } 2175 2176 if (net_ipaddr != 0) { 2177 struct sockaddr_in *s_in; 2178 int s; 2179 2180 s = socket(AF_INET, SOCK_DGRAM, 0); 2181 /* LINTED - E_BAD_PTR_CAST_ALIGN */ 2182 s_in = (struct sockaddr_in *)&arpreq.arp_pa; 2183 s_in->sin_family = AF_INET; 2184 s_in->sin_addr.s_addr = net_ipaddr; 2185 if (ioctl(s, SIOCGARP, (caddr_t)&arpreq) < 0) { 2186 bzero(scan, 6); 2187 } else { 2188 bcopy(&arpreq.arp_ha.sa_data, scan, 6); 2189 } 2190 (void) close(s); 2191 } else { 2192 bzero(scan, 6); 2193 } 2194 scan += 6; 2195 2196 if ((scan + 26) >= scan_end) { 2197 packet.info |= NAME_NM_FLAGS_TC; 2198 break; 2199 } 2200 bzero(scan, 26); 2201 scan += 26; 2202 2203 if ((scan + 2) >= scan_end) { 2204 packet.info |= NAME_NM_FLAGS_TC; 2205 break; 2206 } 2207 BE_OUT16(scan, 0); scan += 2; 2208 2209 if ((scan + 2) >= scan_end) { 2210 packet.info |= NAME_NM_FLAGS_TC; 2211 break; 2212 } 2213 BE_OUT16(scan, 0); scan += 2; 2214 2215 if ((scan + 2) >= scan_end) { 2216 packet.info |= NAME_NM_FLAGS_TC; 2217 break; 2218 } 2219 BE_OUT16(scan, 0); scan += 2; 2220 2221 if ((scan + 2) >= scan_end) { 2222 packet.info |= NAME_NM_FLAGS_TC; 2223 break; 2224 } 2225 BE_OUT16(scan, 0); scan += 2; 2226 2227 if ((scan + 2) >= scan_end) { 2228 packet.info |= NAME_NM_FLAGS_TC; 2229 break; 2230 } 2231 BE_OUT16(scan, 0); scan += 2; 2232 2233 if ((scan + 2) >= scan_end) { 2234 packet.info |= NAME_NM_FLAGS_TC; 2235 break; 2236 } 2237 BE_OUT16(scan, 0); scan += 2; 2238 2239 if ((scan + 2) >= scan_end) { 2240 packet.info |= NAME_NM_FLAGS_TC; 2241 break; 2242 } 2243 BE_OUT16(scan, 0); scan += 2; 2244 2245 if ((scan + 2) >= scan_end) { 2246 packet.info |= NAME_NM_FLAGS_TC; 2247 break; 2248 } 2249 BE_OUT16(scan, max_connections); scan += 2; 2250 2251 if ((scan + 2) >= scan_end) { 2252 packet.info |= NAME_NM_FLAGS_TC; 2253 break; 2254 } 2255 2256 BE_OUT16(scan, 0); scan += 2; 2257 2258 scan_done = B_TRUE; 2259 } 2260 answer.rdlength = scan - data; 2261 return (smb_send_name_service_packet(addr, &packet)); 2262 } 2263 2264 /* 2265 * 2266 * 5.1. NAME SERVICE PROTOCOLS 2267 * 2268 * A REQUEST packet is always sent to the well known UDP port - 2269 * NAME_SERVICE_UDP_PORT. The destination address is normally 2270 * either the IP broadcast address or the address of the NAME - the 2271 * address of the NAME server it set up at initialization time. In 2272 * rare cases, a request packet will be sent to an end node, e.g. a 2273 * NAME QUERY REQUEST sent to "challenge" a node. 2274 * 2275 * A RESPONSE packet is always sent to the source UDP port and 2276 * source IP address of the request packet. 2277 * 2278 * A DEMAND packet must always be sent to the well known UDP port - 2279 * NAME_SERVICE_UDP_PORT. There is no restriction on the target IP 2280 * address. 2281 * 2282 * Terms used in this section: 2283 * 2284 * tid - Transaction ID. This is a value composed from 2285 * the requestor's IP address and a unique 16 bit 2286 * value generated by the originator of the 2287 * transaction. 2288 */ 2289 2290 2291 /* 2292 * 2293 * 5.1.1. B-NODE ACTIVITY 2294 * 2295 * 5.1.1.1. B-NODE ADD NAME 2296 * 2297 * PROCEDURE add_name(name) 2298 * 2299 * (* 2300 * * Host initiated processing for a B node 2301 * *) 2302 * BEGIN 2303 * 2304 * REPEAT 2305 * 2306 * (* build name service packet *) 2307 * 2308 * ONT = B_NODE; (* broadcast node *) 2309 * G = UNIQUE; (* unique name *) 2310 * TTL = 0; 2311 * 2312 * broadcast NAME REGISTRATION REQUEST packet; 2313 * 2314 * (* 2315 * * remote node(s) will send response packet 2316 * * if applicable 2317 * *) 2318 * pause(BCAST_REQ_RETRY_TIMEOUT); 2319 * 2320 * UNTIL response packet is received or 2321 * retransmit count has been exceeded 2322 * 2323 * IF no response packet was received THEN 2324 * BEGIN (* no response *) 2325 * (* 2326 * * Build packet 2327 * *) 2328 * 2329 * ONT = B_NODE; (* broadcast node *) 2330 * G = UNIQUE; (* unique name *) 2331 * TTL = 0; 2332 * 2333 * (* 2334 * * Let other nodes known you have the name 2335 * *) 2336 * 2337 * broadcast NAME UPDATE REQUEST packet; 2338 * (* name can be added to local name table *) 2339 * return success; 2340 * END (* no response *) 2341 * ELSE 2342 * BEGIN (* got response *) 2343 * 2344 * (* 2345 * * Match return transaction id 2346 * * against tid sent in request 2347 * *) 2348 * 2349 * IF NOT response tid = request tid THEN 2350 * BEGIN 2351 * ignore response packet; 2352 * END 2353 * ELSE 2354 * CASE packet type OF 2355 * 2356 * NEGATIVE NAME REGISTRATION RESPONSE: 2357 * 2358 * return failure; (* name cannot be added *) 2359 * 2360 * POSITIVE NAME REGISTRATION RESPONSE: 2361 * END-NODE CHALLENGE NAME REGISTRATION RESPONSE: 2362 * 2363 * (* 2364 * * B nodes should normally not get this 2365 * * response. 2366 * *) 2367 * 2368 * ignore packet; 2369 * END (* case *); 2370 * END (* got response *) 2371 * END (* procedure *) 2372 * 2373 * 2374 * 2375 * 5.1.1.2. B-NODE ADD_GROUP NAME 2376 * 2377 * PROCEDURE add_group_name(name) 2378 * 2379 * (* 2380 * * Host initiated processing for a B node 2381 * *) 2382 * 2383 * BEGIN 2384 * (* 2385 * * same as for a unique name with the 2386 * * exception that the group bit (G) must 2387 * * be set in the request packets. 2388 * *) 2389 * 2390 * ... 2391 * G = GROUP; 2392 * ... 2393 * ... 2394 * 2395 * (* 2396 * * broadcast request ... 2397 * *) 2398 * 2399 * 2400 * END 2401 */ 2402 static int 2403 smb_name_Bnode_add_name(struct name_entry *name) 2404 { 2405 struct name_question question; 2406 struct resource_record additional; 2407 unsigned char data[8]; 2408 unsigned short attr; 2409 struct addr_entry *addr; 2410 int rc = 0; 2411 2412 addr = &name->addr_list; 2413 2414 do { 2415 /* build name service packet */ 2416 question.name = name; 2417 /* 2418 * question.name->attributes |= NAME_NB_FLAGS_ONT_B; 2419 * This is commented because NAME_NB_FLAGS_ONT_B is 0 2420 */ 2421 question.question_type = NAME_QUESTION_TYPE_NB; 2422 question.question_class = NAME_QUESTION_CLASS_IN; 2423 2424 additional.name = name; 2425 additional.rr_class = NAME_QUESTION_CLASS_IN; 2426 additional.ttl = 0; 2427 additional.rdata = data; 2428 additional.rdlength = 6; 2429 additional.rr_type = NAME_QUESTION_TYPE_NB; 2430 attr = name->attributes & (NAME_ATTR_GROUP | 2431 NAME_ATTR_OWNER_NODE_TYPE); 2432 2433 BE_OUT16(&data[0], attr); 2434 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr, 2435 sizeof (uint32_t)); 2436 2437 rc |= smb_send_name_registration_request(BROADCAST, &question, 2438 &additional); 2439 addr = addr->forw; 2440 2441 } while (addr != &name->addr_list); 2442 2443 return (rc); 2444 } 2445 2446 /* 2447 * 5.1.1.3. B-NODE FIND_NAME 2448 * 2449 * PROCEDURE find_name(name) 2450 * 2451 * (* 2452 * * Host initiated processing for a B node 2453 * *) 2454 * 2455 * BEGIN 2456 * 2457 * REPEAT 2458 * (* 2459 * * build packet 2460 * *) 2461 * ONT = B; 2462 * TTL = 0; 2463 * G = DONT CARE; 2464 * raddr = raddr->forw; 2465 * 2466 * broadcast NAME QUERY REQUEST packet; 2467 * (* 2468 * * a node might send response packet 2469 * *) 2470 * 2471 * pause(BCAST_REQ_RETRY_TIMEOUT); 2472 * UNTIL response packet received OR 2473 * max transmit threshold exceeded 2474 * 2475 * IF no response packet received THEN 2476 * return failure; 2477 * ELSE 2478 * IF NOT response tid = request tid THEN 2479 * ignore packet; 2480 * ELSE 2481 * CASE packet type OF 2482 * POSITIVE NAME QUERY RESPONSE: 2483 * (* 2484 * * Start a timer to detect conflict. 2485 * * 2486 * * Be prepared to detect conflict if 2487 * * any more response packets are received. 2488 * * 2489 * *) 2490 * 2491 * save response as authoritative response; 2492 * start_timer(CONFLICT_TIMER); 2493 * return success; 2494 * 2495 * NEGATIVE NAME QUERY RESPONSE: 2496 * REDIRECT NAME QUERY RESPONSE: 2497 * 2498 * (* 2499 * * B Node should normally not get either 2500 * * response. 2501 * *) 2502 * 2503 * ignore response packet; 2504 * 2505 * END (* case *) 2506 * END (* procedure *) 2507 */ 2508 static int 2509 smb_name_Bnode_find_name(struct name_entry *name) 2510 { 2511 struct name_question question; 2512 2513 question.name = name; 2514 question.question_type = NAME_QUESTION_TYPE_NB; 2515 question.question_class = NAME_QUESTION_CLASS_IN; 2516 2517 return (smb_send_name_query_request(BROADCAST, &question)); 2518 } 2519 2520 /* 2521 * 5.1.1.4. B NODE NAME RELEASE 2522 * 2523 * PROCEDURE delete_name (name) 2524 * BEGIN 2525 * 2526 * REPEAT 2527 * 2528 * (* 2529 * * build packet 2530 * *) 2531 * ... 2532 * 2533 * (* 2534 * * send request 2535 * *) 2536 * 2537 * broadcast NAME RELEASE REQUEST packet; 2538 * 2539 * (* 2540 * * no response packet expected 2541 * *) 2542 * 2543 * pause(BCAST_REQ_RETRY_TIMEOUT); 2544 * 2545 * UNTIL retransmit count has been exceeded 2546 * END (* procedure *) 2547 */ 2548 static int 2549 smb_name_Bnode_delete_name(struct name_entry *name) 2550 { 2551 struct name_question question; 2552 struct resource_record additional; 2553 struct addr_entry *raddr; 2554 unsigned char data[MAX_DATAGRAM_LENGTH]; 2555 unsigned char *scan = data; 2556 uint32_t attr; 2557 2558 /* build packet */ 2559 question.name = name; 2560 question.question_type = NAME_QUESTION_TYPE_NB; 2561 question.question_class = NAME_QUESTION_CLASS_IN; 2562 2563 additional.name = name; 2564 additional.rr_class = NAME_QUESTION_CLASS_IN; 2565 additional.ttl = 0; 2566 additional.rdata = data; 2567 additional.rdlength = 0; 2568 additional.rr_type = NAME_QUESTION_TYPE_NB; 2569 raddr = &name->addr_list; 2570 scan = data; 2571 do { 2572 attr = name->attributes & (NAME_ATTR_GROUP | 2573 NAME_ATTR_OWNER_NODE_TYPE); 2574 2575 BE_OUT16(scan, attr); scan += 2; 2576 2577 *scan++ = raddr->sin.sin_addr.s_addr; 2578 *scan++ = raddr->sin.sin_addr.s_addr >> 8; 2579 *scan++ = raddr->sin.sin_addr.s_addr >> 16; 2580 *scan++ = raddr->sin.sin_addr.s_addr >> 24; 2581 2582 additional.rdlength += 6; 2583 } while (raddr != &name->addr_list); 2584 2585 return (smb_send_name_release_request_and_demand(BROADCAST, 2586 &question, &additional)); 2587 } 2588 2589 /* 2590 * 2591 * 5.1.2. P-NODE ACTIVITY 2592 * 2593 * All packets sent or received by P nodes are unicast UDP packets. 2594 * A P node sends name service requests to the NAME node that is 2595 * specified in the P-node configuration. 2596 * 2597 * 5.1.2.1. P-NODE ADD_NAME 2598 * 2599 * PROCEDURE add_name(name) 2600 * 2601 * (* 2602 * * Host initiated processing for a P node 2603 * *) 2604 * 2605 * BEGIN 2606 * 2607 * REPEAT 2608 * (* 2609 * * build packet 2610 * *) 2611 * 2612 * ONT = P; 2613 * G = UNIQUE; 2614 * ... 2615 * 2616 * (* 2617 * * send request 2618 * *) 2619 * 2620 * unicast NAME REGISTRATION REQUEST packet; 2621 * 2622 * (* 2623 * * NAME will send response packet 2624 * *) 2625 * 2626 * IF receive a WACK RESPONSE THEN 2627 * pause(time from TTL field of response); 2628 * ELSE 2629 * pause(UCAST_REQ_RETRY_TIMEOUT); 2630 * UNTIL response packet is received OR 2631 * retransmit count has been exceeded 2632 * 2633 * IF no response packet was received THEN 2634 * BEGIN (* no response *) 2635 * (* 2636 * * NAME is down. Cannot claim name. 2637 * *) 2638 * 2639 * return failure; (* name cannot be claimed *) 2640 * END (* no response *) 2641 * ELSE 2642 * BEGIN (* response *) 2643 * IF NOT response tid = request tid THEN 2644 * BEGIN 2645 * (* Packet may belong to another transaction *) 2646 * ignore response packet; 2647 * END 2648 * ELSE 2649 * CASE packet type OF 2650 * 2651 * POSITIVE NAME REGISTRATION RESPONSE: 2652 * 2653 * (* 2654 * * name can be added 2655 * *) 2656 * 2657 * adjust refresh timeout value, TTL, for this name; 2658 * return success; (* name can be added *) 2659 * 2660 * NEGATIVE NAME REGISTRATION RESPONSE: 2661 * return failure; (* name cannot be added *) 2662 * 2663 * END-NODE CHALLENGE REGISTRATION REQUEST: 2664 * BEGIN (* end node challenge *) 2665 * 2666 * (* 2667 * * The response packet has in it the 2668 * * address of the presumed owner of the 2669 * * name. Challenge that owner. 2670 * * If owner either does not 2671 * * respond or indicates that he no longer 2672 * * owns the name, claim the name. 2673 * * Otherwise, the name cannot be claimed. 2674 * * 2675 * *) 2676 * 2677 * REPEAT 2678 * (* 2679 * * build packet 2680 * *) 2681 * ... 2682 * 2683 * unicast NAME QUERY REQUEST packet to the 2684 * address contained in the END NODE 2685 * CHALLENGE RESPONSE packet; 2686 * 2687 * (* 2688 * * remote node may send response packet 2689 * *) 2690 * 2691 * pause(UCAST_REQ_RETRY_TIMEOUT); 2692 * 2693 * UNTIL response packet is received or 2694 * retransmit count has been exceeded 2695 * IF no response packet is received OR 2696 * NEGATIVE NAME QUERY RESPONSE packet 2697 * received THEN 2698 * BEGIN (* update *) 2699 * 2700 * (* 2701 * * name can be claimed 2702 * *) 2703 * 2704 * REPEAT 2705 * 2706 * (* 2707 * * build packet 2708 * *) 2709 * ... 2710 * 2711 * unicast NAME UPDATE REQUEST to NAME; 2712 * 2713 * (* 2714 * * NAME node will send response packet 2715 * *) 2716 * 2717 * IF receive a WACK RESPONSE THEN 2718 * pause(time from TTL field of response); 2719 * ELSE 2720 * pause(UCAST_REQ_RETRY_TIMEOUT); 2721 * UNTIL response packet is received or 2722 * retransmit count has been exceeded 2723 * IF no response packet received THEN 2724 * BEGIN (* no response *) 2725 * 2726 * (* 2727 * * name could not be claimed 2728 * *) 2729 * 2730 * return failure; 2731 * END (* no response *) 2732 * ELSE 2733 * CASE packet type OF 2734 * POSITIVE NAME REGISTRATION RESPONSE: 2735 * (* 2736 * * add name 2737 * *) 2738 * return success; 2739 * NEGATIVE NAME REGISTRATION RESPONSE: 2740 * 2741 * (* 2742 * * you lose ... 2743 * *) 2744 * return failure; 2745 * END (* case *) 2746 * END (* update *) 2747 * ELSE 2748 * 2749 * (* 2750 * * received a positive response to the "challenge" 2751 * * Remote node still has name 2752 * *) 2753 * 2754 * return failure; 2755 * END (* end node challenge *) 2756 * END (* response *) 2757 * END (* procedure *) 2758 * 2759 * 2760 * 5.1.2.2. P-NODE ADD GROUP NAME 2761 * 2762 * PROCEDURE add_group_name(name) 2763 * 2764 * (* 2765 * * Host initiated processing for a P node 2766 * *) 2767 * 2768 * BEGIN 2769 * (* 2770 * * same as for a unique name, except that the 2771 * * request packet must indicate that a 2772 * * group name claim is being made. 2773 * *) 2774 * 2775 * ... 2776 * G = GROUP; 2777 * ... 2778 * 2779 * (* 2780 * * send packet 2781 * *) 2782 * ... 2783 * 2784 * 2785 * END 2786 */ 2787 static int 2788 smb_name_Pnode_add_name(struct name_entry *name) 2789 { 2790 struct name_question question; 2791 struct resource_record additional; 2792 unsigned char data[8]; 2793 unsigned short attr; 2794 struct addr_entry *addr; 2795 int rc = 0; 2796 2797 /* build packet */ 2798 addr = &name->addr_list; 2799 do { 2800 question.name = name; 2801 question.question_type = NAME_QUESTION_TYPE_NB; 2802 question.question_class = NAME_QUESTION_CLASS_IN; 2803 2804 additional.name = name; 2805 additional.rr_class = NAME_QUESTION_CLASS_IN; 2806 additional.ttl = 0; 2807 additional.rdata = data; 2808 additional.rdlength = 6; 2809 additional.rr_type = NAME_QUESTION_TYPE_NB; 2810 attr = name->attributes & 2811 (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE); 2812 2813 BE_OUT16(&data[0], attr); 2814 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr, 2815 sizeof (uint32_t)); 2816 2817 rc |= smb_send_name_registration_request(UNICAST, &question, 2818 &additional); 2819 2820 addr = addr->forw; 2821 2822 } while (addr != &name->addr_list); 2823 2824 return (rc); 2825 } 2826 2827 static int 2828 smb_name_Pnode_refresh_name(struct name_entry *name) 2829 { 2830 struct name_question question; 2831 struct resource_record additional; 2832 unsigned char data[8]; 2833 unsigned short attr; 2834 struct addr_entry *addr; 2835 int rc = 0; 2836 2837 /* build packet */ 2838 addr = &name->addr_list; 2839 do { 2840 question.name = name; 2841 question.question_type = NAME_QUESTION_TYPE_NB; 2842 question.question_class = NAME_QUESTION_CLASS_IN; 2843 2844 additional.name = name; 2845 additional.rr_class = NAME_QUESTION_CLASS_IN; 2846 additional.ttl = 0; 2847 additional.rdata = data; 2848 additional.rdlength = 6; 2849 additional.rr_type = NAME_QUESTION_TYPE_NB; 2850 attr = name->attributes & 2851 (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE); 2852 2853 BE_OUT16(&data[0], attr); 2854 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr, 2855 sizeof (uint32_t)); 2856 2857 rc |= smb_send_name_refresh_request(UNICAST, &question, 2858 &additional, 1); 2859 2860 addr = addr->forw; 2861 } while (addr != &name->addr_list); 2862 2863 return (rc); 2864 } 2865 2866 /* 2867 * 5.1.2.3. P-NODE FIND NAME 2868 * 2869 * PROCEDURE find_name(name) 2870 * 2871 * (* 2872 * * Host initiated processing for a P node 2873 * *) 2874 * 2875 * BEGIN 2876 * REPEAT 2877 * (* 2878 * * build packet 2879 * *) 2880 * 2881 * ONT = P; 2882 * G = DONT CARE; 2883 * 2884 * unicast NAME QUERY REQUEST packet; 2885 * 2886 * (* 2887 * * a NAME node might send response packet 2888 * *) 2889 * 2890 * IF receive a WACK RESPONSE THEN 2891 * pause(time from TTL field of response); 2892 * ELSE 2893 * pause(UCAST_REQ_RETRY_TIMEOUT); 2894 * UNTIL response packet received OR 2895 * max transmit threshold exceeded 2896 * 2897 * IF no response packet received THEN 2898 * return failure; 2899 * ELSE 2900 * IF NOT response tid = request tid THEN 2901 * ignore packet; 2902 * ELSE 2903 * CASE packet type OF 2904 * POSITIVE NAME QUERY RESPONSE: 2905 * return success; 2906 * 2907 * REDIRECT NAME QUERY RESPONSE: 2908 * 2909 * (* 2910 * * NAME node wants this end node 2911 * * to use some other NAME node 2912 * * to resolve the query. 2913 * *) 2914 * 2915 * repeat query with NAME address 2916 * in the response packet; 2917 * NEGATIVE NAME QUERY RESPONSE: 2918 * return failure; 2919 * 2920 * END (* case *) 2921 * END (* procedure *) 2922 */ 2923 static int 2924 smb_name_Pnode_find_name(struct name_entry *name) 2925 { 2926 struct name_question question; 2927 2928 /* 2929 * Host initiated processing for a P node 2930 */ 2931 question.name = name; 2932 question.name->attributes |= NAME_NB_FLAGS_ONT_P; 2933 question.question_type = NAME_QUESTION_TYPE_NB; 2934 question.question_class = NAME_QUESTION_CLASS_IN; 2935 2936 return (smb_send_name_query_request(UNICAST, &question)); 2937 } 2938 2939 /* 2940 * 5.1.2.4. P-NODE DELETE_NAME 2941 * 2942 * PROCEDURE delete_name (name) 2943 * 2944 * (* 2945 * * Host initiated processing for a P node 2946 * *) 2947 * 2948 * BEGIN 2949 * 2950 * REPEAT 2951 * 2952 * (* 2953 * * build packet 2954 * *) 2955 * ... 2956 * 2957 * (* 2958 * * send request 2959 * *) 2960 * 2961 * unicast NAME RELEASE REQUEST packet; 2962 * IF receive a WACK RESPONSE THEN 2963 * pause(time from TTL field of response); 2964 * ELSE 2965 * pause(UCAST_REQ_RETRY_TIMEOUT); 2966 * UNTIL retransmit count has been exceeded 2967 * or response been received 2968 * 2969 * IF response has been received THEN 2970 * CASE packet type OF 2971 * POSITIVE NAME RELEASE RESPONSE: 2972 * return success; 2973 * NEGATIVE NAME RELEASE RESPONSE: 2974 * 2975 * (* 2976 * * NAME does want node to delete this 2977 * * name !!! 2978 * *) 2979 * 2980 * return failure; 2981 * END (* case *) 2982 * END (* procedure *) 2983 */ 2984 static int 2985 smb_name_Pnode_delete_name(struct name_entry *name) 2986 { 2987 struct name_question question; 2988 struct resource_record additional; 2989 struct addr_entry *raddr; 2990 unsigned char data[MAX_DATAGRAM_LENGTH]; 2991 unsigned char *scan = data; 2992 uint32_t attr; 2993 2994 /* build packet */ 2995 question.name = name; 2996 question.name->attributes |= NAME_NB_FLAGS_ONT_P; 2997 question.question_type = NAME_QUESTION_TYPE_NB; 2998 question.question_class = NAME_QUESTION_CLASS_IN; 2999 3000 additional.name = name; 3001 additional.rr_class = NAME_QUESTION_CLASS_IN; 3002 additional.ttl = 0; 3003 additional.rdata = data; 3004 additional.rdlength = 0; 3005 additional.rr_type = NAME_QUESTION_TYPE_NB; 3006 raddr = &name->addr_list; 3007 do { 3008 scan = data; 3009 attr = name->attributes & (NAME_ATTR_GROUP | 3010 NAME_ATTR_OWNER_NODE_TYPE); 3011 3012 BE_OUT16(scan, attr); scan += 2; 3013 3014 *scan++ = raddr->sin.sin_addr.s_addr; 3015 *scan++ = raddr->sin.sin_addr.s_addr >> 8; 3016 *scan++ = raddr->sin.sin_addr.s_addr >> 16; 3017 *scan++ = raddr->sin.sin_addr.s_addr >> 24; 3018 3019 additional.rdlength = 6; 3020 raddr = raddr->forw; 3021 (void) smb_send_name_release_request_and_demand(UNICAST, 3022 &question, &additional); 3023 } while (raddr != &name->addr_list); 3024 3025 return (1); 3026 } 3027 3028 /* 3029 * 5.1.3. M-NODE ACTIVITY 3030 * 3031 * M nodes behavior is similar to that of P nodes with the addition 3032 * of some B node-like broadcast actions. M node name service 3033 * proceeds in two steps: 3034 * 3035 * 1.Use broadcast UDP based name service. Depending on the 3036 * operation, goto step 2. 3037 * 3038 * 2.Use directed UDP name service. 3039 * 3040 * The following code for M nodes is exactly the same as for a P 3041 * node, with the exception that broadcast operations are done 3042 * before P type operation is attempted. 3043 * 3044 * 5.1.3.1. M-NODE ADD NAME 3045 * 3046 * PROCEDURE add_name(name) 3047 * 3048 * (* 3049 * * Host initiated processing for a M node 3050 * *) 3051 * 3052 * BEGIN 3053 * 3054 * (* 3055 * * check if name exists on the 3056 * * broadcast area 3057 * *) 3058 * REPEAT 3059 * (* build packet *) 3060 * 3061 * .... 3062 * broadcast NAME REGISTRATION REQUEST packet; 3063 * pause(BCAST_REQ_RETRY_TIMEOUT); 3064 * 3065 * UNTIL response packet is received or 3066 * retransmit count has been exceeded 3067 * 3068 * IF valid response received THEN 3069 * BEGIN 3070 * (* cannot claim name *) 3071 * 3072 * return failure; 3073 * END 3074 * 3075 * (* 3076 * * No objections received within the 3077 * * broadcast area. 3078 * * Send request to name server. 3079 * *) 3080 * 3081 * REPEAT 3082 * (* 3083 * * build packet 3084 * *) 3085 * 3086 * ONT = M; 3087 * ... 3088 * 3089 * unicast NAME REGISTRATION REQUEST packet; 3090 * 3091 * (* 3092 * * remote NAME will send response packet 3093 * *) 3094 * 3095 * IF receive a WACK RESPONSE THEN 3096 * pause(time from TTL field of response); 3097 * ELSE 3098 * pause(UCAST_REQ_RETRY_TIMEOUT); 3099 * 3100 * UNTIL response packet is received or 3101 * retransmit count has been exceeded 3102 * 3103 * IF no response packet was received THEN 3104 * BEGIN (* no response *) 3105 * (* 3106 * * NAME is down. Cannot claim name. 3107 * *) 3108 * return failure; (* name cannot be claimed *) 3109 * END (* no response *) 3110 * ELSE 3111 * BEGIN (* response *) 3112 * IF NOT response tid = request tid THEN 3113 * BEGIN 3114 * ignore response packet; 3115 * END 3116 * ELSE 3117 * CASE packet type OF 3118 * POSITIVE NAME REGISTRATION RESPONSE: 3119 * 3120 * (* 3121 * * name can be added 3122 * *) 3123 * 3124 * adjust refresh timeout value, TTL; 3125 * return success; (* name can be added *) 3126 * 3127 * NEGATIVE NAME REGISTRATION RESPONSE: 3128 * return failure; (* name cannot be added *) 3129 * 3130 * END-NODE CHALLENGE REGISTRATION REQUEST: 3131 * BEGIN (* end node challenge *) 3132 * 3133 * (* 3134 * * The response packet has in it the 3135 * * address of the presumed owner of the 3136 * * name. Challenge that owner. 3137 * * If owner either does not 3138 * * respond or indicates that he no longer 3139 * * owns the name, claim the name. 3140 * * Otherwise, the name cannot be claimed. 3141 * * 3142 * *) 3143 * 3144 * REPEAT 3145 * (* 3146 * * build packet 3147 * *) 3148 * ... 3149 * 3150 * (* 3151 * * send packet to address contained in the 3152 * * response packet 3153 * *) 3154 * 3155 * unicast NAME QUERY REQUEST packet; 3156 * 3157 * (* 3158 * * remote node may send response packet 3159 * *) 3160 * 3161 * pause(UCAST_REQ_RETRY_TIMEOUT); 3162 * 3163 * UNTIL response packet is received or 3164 * retransmit count has been exceeded 3165 * IF no response packet is received THEN 3166 * BEGIN (* no response *) 3167 * 3168 * (* 3169 * * name can be claimed 3170 * *) 3171 * REPEAT 3172 * 3173 * (* 3174 * * build packet 3175 * *) 3176 * ... 3177 * 3178 * unicast NAME UPDATE REQUEST to NAME; 3179 * 3180 * (* 3181 * * NAME node will send response packet 3182 * *) 3183 * 3184 * IF receive a WACK RESPONSE THEN 3185 * pause(time from TTL field of response); 3186 * ELSE 3187 * pause(UCAST_REQ_RETRY_TIMEOUT); 3188 * 3189 * UNTIL response packet is received or 3190 * retransmit count has been exceeded 3191 * IF no response packet received THEN 3192 * BEGIN (* no response *) 3193 * 3194 * (* 3195 * * name could not be claimed 3196 * *) 3197 * 3198 * return failure; 3199 * END (* no response *) 3200 * ELSE 3201 * CASE packet type OF 3202 * POSITIVE NAME REGISTRATION RESPONSE: 3203 * (* 3204 * * add name 3205 * *) 3206 * 3207 * return success; 3208 * NEGATIVE NAME REGISTRATION RESPONSE: 3209 * (* 3210 * * you lose ... 3211 * *) 3212 * 3213 * return failure; 3214 * END (* case *) 3215 * END (* no response *) 3216 * ELSE 3217 * IF NOT response tid = request tid THEN 3218 * BEGIN 3219 * ignore response packet; 3220 * END 3221 * 3222 * (* 3223 * * received a response to the "challenge" 3224 * * packet 3225 * *) 3226 * 3227 * CASE packet type OF 3228 * POSITIVE NAME QUERY: 3229 * 3230 * (* 3231 * * remote node still has name. 3232 * *) 3233 * 3234 * return failure; 3235 * NEGATIVE NAME QUERY: 3236 * 3237 * (* 3238 * * remote node no longer has name 3239 * *) 3240 * 3241 * return success; 3242 * END (* case *) 3243 * END (* end node challenge *) 3244 * END (* case *) 3245 * END (* response *) 3246 * END (* procedure *) 3247 * 3248 * 3249 * 5.1.3.2. M-NODE ADD GROUP NAME 3250 * 3251 * PROCEDURE add_group_name(name) 3252 * 3253 * (* 3254 * * Host initiated processing for a P node 3255 * *) 3256 * 3257 * BEGIN 3258 * (* 3259 * * same as for a unique name, except that the 3260 * * request packet must indicate that a 3261 * * group name claim is being made. 3262 * *) 3263 * 3264 * ... 3265 * G = GROUP; 3266 * ... 3267 * 3268 * (* 3269 * * send packet 3270 * *) 3271 * ... 3272 * 3273 * 3274 * END 3275 */ 3276 static int 3277 smb_name_Mnode_add_name(struct name_entry *name) 3278 { 3279 if (smb_name_Bnode_add_name(name) > 0) { 3280 if (nbns_num == 0) 3281 return (1); /* No name server configured */ 3282 3283 return (smb_name_Pnode_add_name(name)); 3284 } 3285 return (-1); 3286 } 3287 3288 static int 3289 smb_name_Hnode_add_name(struct name_entry *name) 3290 { 3291 if (nbns_num > 0) { 3292 if (smb_name_Pnode_add_name(name) == 1) 3293 return (1); 3294 } 3295 3296 return (smb_name_Bnode_add_name(name)); 3297 } 3298 3299 /* 3300 * 5.1.3.3. M-NODE FIND NAME 3301 * 3302 * PROCEDURE find_name(name) 3303 * 3304 * (* 3305 * * Host initiated processing for a M node 3306 * *) 3307 * 3308 * BEGIN 3309 * (* 3310 * * check if any node on the broadcast 3311 * * area has the name 3312 * *) 3313 * 3314 * REPEAT 3315 * (* build packet *) 3316 * ... 3317 * 3318 * broadcast NAME QUERY REQUEST packet; 3319 * pause(BCAST_REQ_RETRY_TIMEOUT); 3320 * UNTIL response packet received OR 3321 * max transmit threshold exceeded 3322 * 3323 * IF valid response received THEN 3324 * BEGIN 3325 * save response as authoritative response; 3326 * start_timer(CONFLICT_TIMER); 3327 * return success; 3328 * END 3329 * 3330 * (* 3331 * * no valid response on the b'cast segment. 3332 * * Try the name server. 3333 * *) 3334 * 3335 * REPEAT 3336 * (* 3337 * * build packet 3338 * *) 3339 * 3340 * ONT = M; 3341 * G = DONT CARE; 3342 * 3343 * unicast NAME QUERY REQUEST packet to NAME; 3344 * 3345 * (* 3346 * * a NAME node might send response packet 3347 * *) 3348 * 3349 * IF receive a WACK RESPONSE THEN 3350 * pause(time from TTL field of response); 3351 * ELSE 3352 * pause(UCAST_REQ_RETRY_TIMEOUT); 3353 * UNTIL response packet received OR 3354 * max transmit threshold exceeded 3355 * 3356 * IF no response packet received THEN 3357 * return failure; 3358 * ELSE 3359 * IF NOT response tid = request tid THEN 3360 * ignore packet; 3361 * ELSE 3362 * CASE packet type OF 3363 * POSITIVE NAME QUERY RESPONSE: 3364 * return success; 3365 * 3366 * REDIRECT NAME QUERY RESPONSE: 3367 * 3368 * (* 3369 * * NAME node wants this end node 3370 * * to use some other NAME node 3371 * * to resolve the query. 3372 * *) 3373 * 3374 * repeat query with NAME address 3375 * in the response packet; 3376 * NEGATIVE NAME QUERY RESPONSE: 3377 * return failure; 3378 * 3379 * END (* case *) 3380 * END (* procedure *) 3381 */ 3382 static int 3383 smb_name_Mnode_find_name(struct name_entry *name) 3384 { 3385 if (smb_name_Bnode_find_name(name) == 1) 3386 return (1); 3387 3388 if (nbns_num == 0) 3389 return (1); /* No name server configured */ 3390 3391 return (smb_name_Pnode_find_name(name)); 3392 } 3393 3394 static int 3395 smb_name_Hnode_find_name(struct name_entry *name) 3396 { 3397 if (nbns_num > 0) 3398 if (smb_name_Pnode_find_name(name) == 1) 3399 return (1); 3400 3401 return (smb_name_Bnode_find_name(name)); 3402 } 3403 3404 /* 3405 * 5.1.3.4. M-NODE DELETE NAME 3406 * 3407 * PROCEDURE delete_name (name) 3408 * 3409 * (* 3410 * * Host initiated processing for a P node 3411 * *) 3412 * 3413 * BEGIN 3414 * (* 3415 * * First, delete name on NAME 3416 * *) 3417 * 3418 * REPEAT 3419 * 3420 * (* 3421 * * build packet 3422 * struct addr_entry *addr; 3423 * *) 3424 * ... 3425 * 3426 * (* 3427 * * send request 3428 * *) 3429 * 3430 * unicast NAME RELEASE REQUEST packet to NAME; 3431 * 3432 * IF receive a WACK RESPONSE THEN 3433 * pause(time from TTL field of response); 3434 * ELSE 3435 * pause(UCAST_REQ_RETRY_TIMEOUT); 3436 * UNTIL retransmit count has been exceeded 3437 * or response been received 3438 * 3439 * IF response has been received THEN 3440 * CASE packet type OF 3441 * POSITIVE NAME RELEASE RESPONSE: 3442 * (* 3443 * * Deletion of name on b'cast segment is deferred 3444 * * until after NAME has deleted the name 3445 * *) 3446 * 3447 * REPEAT 3448 * (* build packet *) 3449 * 3450 * ... 3451 * broadcast NAME RELEASE REQUEST; 3452 * pause(BCAST_REQ_RETRY_TIMEOUT); 3453 * UNTIL rexmt threshold exceeded 3454 * 3455 * return success; 3456 * NEGATIVE NAME RELEASE RESPONSE: 3457 * 3458 * (* 3459 * * NAME does want node to delete this 3460 * * name 3461 * *) 3462 * return failure; 3463 * END (* case *) 3464 * END (* procedure *) 3465 */ 3466 static int 3467 smb_name_Mnode_delete_name(struct name_entry *name) 3468 { 3469 (void) smb_name_Bnode_delete_name(name); 3470 3471 if (nbns_num == 0) 3472 return (-1); /* No name server configured */ 3473 3474 if (smb_name_Pnode_delete_name(name) > 0) 3475 return (1); 3476 3477 return (-1); 3478 } 3479 3480 static int 3481 smb_name_Hnode_delete_name(struct name_entry *name) 3482 { 3483 if (nbns_num > 0) 3484 if (smb_name_Pnode_delete_name(name) > 0) 3485 return (1); 3486 3487 return (smb_name_Bnode_delete_name(name)); 3488 } 3489 3490 /* 3491 * 5.1.1.5. B-NODE INCOMING PACKET PROCESSING 3492 * 3493 * Following processing is done when broadcast or unicast packets 3494 * are received at the NAME_SERVICE_UDP_PORT. 3495 * 3496 * PROCEDURE process_incoming_packet(packet) 3497 * 3498 * (* 3499 * * Processing initiated by incoming packets for a B node 3500 * *) 3501 * 3502 * BEGIN 3503 * (* 3504 * * Note: response packets are always sent 3505 * * to: 3506 * * source IP address of request packet 3507 * * source UDP port of request packet 3508 * *) 3509 * 3510 * CASE packet type OF 3511 * 3512 * NAME REGISTRATION REQUEST (UNIQUE): 3513 * IF name exists in local name table THEN 3514 * send NEGATIVE_NAME_REGISTRATION_RESPONSE ; 3515 * NAME REGISTRATION REQUEST (GROUP): 3516 * IF name exists in local name table THEN 3517 * BEGIN 3518 * IF local entry is a unique name THEN 3519 * send NEGATIVE_NAME_REGISTRATION_RESPONSE ; 3520 * END 3521 * NAME QUERY REQUEST: 3522 * IF name exists in local name table THEN 3523 * BEGIN 3524 * build response packet; 3525 * send POSITIVE_NAME_QUERY_RESPONSE; 3526 * POSITIVE NAME QUERY RESPONSE: 3527 * IF name conflict timer is not active THEN 3528 * BEGIN 3529 * (* 3530 * * timer has expired already... ignore this 3531 * * packet 3532 * *) 3533 * 3534 * return; 3535 * END 3536 * ELSE (* timer is active *) 3537 * IF a response for this name has previously been 3538 * received THEN 3539 * BEGIN (* existing entry *) 3540 * 3541 * (* 3542 * * we sent out a request packet, and 3543 * * have already received (at least) 3544 * * one response 3545 * * 3546 * * Check if conflict exists. 3547 * * If so, send out a conflict packet. 3548 * * 3549 * * Note: detecting conflict does NOT 3550 * * affect any existing sessions. 3551 * * 3552 * *) 3553 * 3554 * (* 3555 * * Check for name conflict. 3556 * * See "Name Conflict" in Concepts and Methods 3557 * *) 3558 * check saved authoritative response against 3559 * information in this response packet; 3560 * IF conflict detected THEN 3561 * BEGIN 3562 * unicast NAME CONFLICT DEMAND packet; 3563 * IF entry exists in cache THEN 3564 * BEGIN 3565 * remove entry from cache; 3566 * END 3567 * END 3568 * END (* existing entry *) 3569 * ELSE 3570 * BEGIN 3571 * (* 3572 * * Note: If this was the first response 3573 * * to a name query, it would have been 3574 * * handled in the 3575 * * find_name() procedure. 3576 * *) 3577 * 3578 * ignore packet; 3579 * END 3580 * NAME CONFLICT DEMAND: 3581 * IF name exists in local name table THEN 3582 * BEGIN 3583 * mark name as conflict detected; 3584 * 3585 * (* 3586 * * a name in the state "conflict detected" 3587 * * does not "logically" exist on that node. 3588 * * No further session will be accepted on 3589 * * that name. 3590 * * No datagrams can be sent against that name. 3591 * * Such an entry will not be used for 3592 * * purposes of processing incoming request 3593 * * packets. 3594 * * The only valid user NetBIOS operation 3595 * * against such a name is DELETE NAME. 3596 * *) 3597 * END 3598 * NAME RELEASE REQUEST: 3599 * IF caching is being done THEN 3600 * BEGIN 3601 * remove entry from cache; 3602 * END 3603 * NAME UPDATE REQUEST: 3604 * IF caching is being done THEN 3605 * BEGIN 3606 * IF entry exists in cache already, 3607 * update cache; 3608 * ELSE IF name is "interesting" THEN 3609 * BEGIN 3610 * add entry to cache; 3611 * END 3612 * END 3613 * 3614 * NODE STATUS REQUEST: 3615 * IF name exists in local name table THEN 3616 * BEGIN 3617 * (* 3618 * * send only those names that are 3619 * * in the same scope as the scope 3620 * * field in the request packet 3621 * *) 3622 * 3623 * send NODE STATUS RESPONSE; 3624 * END 3625 * END 3626 */ 3627 static void 3628 smb_name_process_Bnode_packet(struct name_packet *packet, 3629 struct addr_entry *addr) 3630 { 3631 struct name_entry *name; 3632 struct name_entry *entry; 3633 struct name_question *question; 3634 struct resource_record *additional; 3635 3636 question = packet->question; 3637 additional = packet->additional; 3638 3639 switch (packet->info & NAME_OPCODE_OPCODE_MASK) { 3640 case NAME_OPCODE_REFRESH: 3641 /* Guard against malformed packets */ 3642 if ((question == 0) || (additional == 0)) 3643 break; 3644 if (additional->name->addr_list.sin.sin_addr.s_addr == 0) 3645 break; 3646 3647 name = question->name; 3648 name->addr_list.ttl = additional->ttl; 3649 name->attributes = additional->name->attributes; 3650 name->addr_list.sin = additional->name->addr_list.sin; 3651 name->addr_list.forw = name->addr_list.back = &name->addr_list; 3652 3653 if ((entry = smb_netbios_cache_lookup_addr(name)) != 0) { 3654 smb_netbios_cache_update_entry(entry, question->name); 3655 smb_netbios_cache_unlock_entry(entry); 3656 } 3657 else 3658 (void) smb_netbios_cache_insert(question->name); 3659 break; 3660 3661 case NAME_OPCODE_QUERY: 3662 /* 3663 * This opcode covers both NAME_QUERY_REQUEST and 3664 * NODE_STATUS_REQUEST. They can be distinguished 3665 * based on the type of question entry. 3666 */ 3667 3668 /* All query requests have to have question entry */ 3669 if (question == 0) 3670 break; 3671 3672 if (question->question_type == NAME_QUESTION_TYPE_NB) { 3673 name = question->name; 3674 if ((entry = smb_netbios_cache_lookup(name)) != 0) { 3675 (void) smb_send_name_query_response(addr, 3676 packet, entry, 0); 3677 smb_netbios_cache_unlock_entry(entry); 3678 } 3679 } 3680 else 3681 if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) { 3682 /* 3683 * Name of "*" may be used to force node to 3684 * divulge status for administrative purposes 3685 */ 3686 name = question->name; 3687 entry = 0; 3688 if (NETBIOS_NAME_IS_STAR(name->name) || 3689 ((entry = smb_netbios_cache_lookup(name)) != 0)) { 3690 if (entry) 3691 smb_netbios_cache_unlock_entry(entry); 3692 /* 3693 * send only those names that are 3694 * in the same scope as the scope 3695 * field in the request packet 3696 */ 3697 (void) smb_send_node_status_response(addr, 3698 packet); 3699 } 3700 } 3701 break; 3702 3703 default: 3704 break; 3705 } 3706 } 3707 3708 /* 3709 * 5.1.2.5. P-NODE INCOMING PACKET PROCESSING 3710 * 3711 * Processing initiated by reception of packets at a P node 3712 * 3713 * PROCEDURE process_incoming_packet(packet) 3714 * 3715 * (* 3716 * * Processing initiated by incoming packets at a P node 3717 * *) 3718 * 3719 * BEGIN 3720 * (* 3721 * * always ignore UDP broadcast packets 3722 * *) 3723 * 3724 * IF packet was sent as a broadcast THEN 3725 * BEGIN 3726 * ignore packet; 3727 * return; 3728 * END 3729 * CASE packet type of 3730 * 3731 * NAME CONFLICT DEMAND: 3732 * IF name exists in local name table THEN 3733 * mark name as in conflict; 3734 * return; 3735 * 3736 * NAME QUERY REQUEST: 3737 * IF name exists in local name table THEN 3738 * BEGIN (* name exists *) 3739 * 3740 * (* 3741 * * build packet 3742 * *) 3743 * ... 3744 * 3745 * (* 3746 * * send response to the IP address and port 3747 * * number from which the request was received. 3748 * *) 3749 * 3750 * send POSITIVE_NAME_QUERY_RESPONSE ; 3751 * return; 3752 * END (* exists *) 3753 * ELSE 3754 * BEGIN (* does not exist *) 3755 * 3756 * (* 3757 * * send response to the requestor 3758 * *) 3759 * 3760 * send NEGATIVE_NAME_QUERY_RESPONSE ; 3761 * return; 3762 * END (* does not exist *) 3763 * NODE STATUS REQUEST: 3764 * (* 3765 * * Name of "*" may be used for force node to 3766 * * divulge status for administrative purposes 3767 * *) 3768 * IF name in local name table OR name = "*" THEN 3769 * BEGIN 3770 * (* 3771 * * Build response packet and 3772 * * send to requestor node 3773 * * Send only those names that are 3774 * * in the same scope as the scope 3775 * * in the request packet. 3776 * *) 3777 * 3778 * send NODE_STATUS_RESPONSE; 3779 * END 3780 * 3781 * NAME RELEASE REQUEST: 3782 * (* 3783 * * This will be received if the NAME wants to flush the 3784 * * name from the local name table, or from the local 3785 * * cache. 3786 * *) 3787 * 3788 * IF name exists in the local name table THEN 3789 * BEGIN 3790 * delete name from local name table; 3791 * inform user that name has been deleted; 3792 * END 3793 * END (* case *) 3794 * END (* procedure *) 3795 * 3796 * (* 3797 * * Incoming packet processing on a NS node 3798 * *) 3799 * 3800 * BEGIN 3801 * IF packet was sent as a broadcast THEN 3802 * BEGIN 3803 * discard packet; 3804 * return; 3805 * END 3806 * CASE packet type of 3807 * 3808 * NAME REGISTRATION REQUEST (UNIQUE): 3809 * IF unique name exists in data base THEN 3810 * BEGIN (* unique name exists *) 3811 * (* 3812 * * NAME node may be a "passive" 3813 * * server in that it expects the 3814 * * end node to do the challenge 3815 * * server. Such a NAME node is 3816 * * called a "non-secure" server. 3817 * * A "secure" server will do the 3818 * * challenging before it sends 3819 * * back a response packet. 3820 * *) 3821 * 3822 * IF non-secure THEN 3823 * BEGIN 3824 * (* 3825 * * build response packet 3826 * *) 3827 * ... 3828 * 3829 * 3830 * (* 3831 * * let end node do the challenge 3832 * *) 3833 * 3834 * send END-NODE CHALLENGE NAME REGISTRATION 3835 * RESPONSE; 3836 * return; 3837 * END 3838 * ELSE 3839 * (* 3840 * * secure server - do the name 3841 * * challenge operation 3842 * *) 3843 * 3844 * REPEAT 3845 * send NAME QUERY REQUEST; 3846 * pause(UCAST_REQ_RETRY_TIMEOUT); 3847 * UNTIL response has been received or 3848 * retransmit count has been exceeded 3849 * IF no response was received THEN 3850 * BEGIN 3851 * 3852 * (* node down *) 3853 * 3854 * update data base - remove entry; 3855 * update data base - add new entry; 3856 * send POSITIVE NAME REGISTRATION RESPONSE; 3857 * return; 3858 * END 3859 * ELSE 3860 * BEGIN (* challenged node replied *) 3861 * (* 3862 * * challenged node replied with 3863 * * a response packet 3864 * *) 3865 * 3866 * CASE packet type 3867 * 3868 * POSITIVE NAME QUERY RESPONSE: 3869 * 3870 * (* 3871 * * name still owned by the 3872 * * challenged node 3873 * * 3874 * * build packet and send response 3875 * *) 3876 * ... 3877 * 3878 * 3879 * (* 3880 * * Note: The NAME will need to 3881 * * keep track (based on transaction id) of 3882 * * the IP address and port number 3883 * * of the original requestor. 3884 * *) 3885 * 3886 * send NEGATIVE NAME REGISTRATION RESPONSE; 3887 * return; 3888 * NEGATIVE NAME QUERY RESPONSE: 3889 * 3890 * update data base - remove entry; 3891 * update data base - add new entry; 3892 * 3893 * (* 3894 * * build response packet and send 3895 * * response 3896 * *) 3897 * send POSITIVE NAME REGISTRATION RESPONSE; 3898 * return; 3899 * END (* case *) 3900 * END (* challenged node replied *) 3901 * END (* unique name exists in data base *) 3902 * ELSE 3903 * IF group name exists in data base THEN 3904 * BEGIN (* group names exists *) 3905 * 3906 * (* 3907 * * Members of a group name are NOT 3908 * * challenged. 3909 * * Make the assumption that 3910 * * at least some of the group members 3911 * * are still alive. 3912 * * Refresh mechanism will 3913 * * allow the NAME to detect when all 3914 * * members of a group no longer use that 3915 * * name 3916 * *) 3917 * 3918 * send NEGATIVE NAME REGISTRATION RESPONSE; 3919 * END (* group name exists *) 3920 * ELSE 3921 * BEGIN (* name does not exist *) 3922 * 3923 * (* 3924 * * Name does not exist in data base 3925 * * 3926 * * This code applies to both non-secure 3927 * * and secure server. 3928 * *) 3929 * 3930 * update data base - add new entry; 3931 * send POSITIVE NAME REGISTRATION RESPONSE; 3932 * return; 3933 * END 3934 * 3935 * NAME QUERY REQUEST: 3936 * IF name exists in data base THEN 3937 * BEGIN 3938 * (* 3939 * * build response packet and send to 3940 * * requestor 3941 * *) 3942 * ... 3943 * 3944 * send POSITIVE NAME QUERY RESPONSE; 3945 * return; 3946 * ELSE 3947 * BEGIN 3948 * (* 3949 * * build response packet and send to 3950 * * requestor 3951 * *) 3952 * ... 3953 * 3954 * send NEGATIVE NAME QUERY RESPONSE; 3955 * return; 3956 * END 3957 * 3958 * NAME REGISTRATION REQUEST (GROUP): 3959 * IF name exists in data base THEN 3960 * BEGIN 3961 * IF local entry is a unique name THEN 3962 * BEGIN (* local is unique *) 3963 * 3964 * IF non-secure THEN 3965 * BEGIN 3966 * send END-NODE CHALLENGE NAME 3967 * REGISTRATION RESPONSE; 3968 * return; 3969 * END 3970 * 3971 * REPEAT 3972 * send NAME QUERY REQUEST; 3973 * pause(UCAST_REQ_RETRY_TIMEOUT); 3974 * UNTIL response received or 3975 * retransmit count exceeded 3976 * IF no response received or 3977 * NEGATIVE NAME QUERY RESPONSE 3978 * received THEN 3979 * BEGIN 3980 * update data base - remove entry; 3981 * update data base - add new entry; 3982 * send POSITIVE NAME REGISTRATION RESPONSE; 3983 * return; 3984 * END 3985 * ELSE 3986 * BEGIN 3987 * (* 3988 * * name still being held 3989 * * by challenged node 3990 * *) 3991 * 3992 * send NEGATIVE NAME REGISTRATION RESPONSE; 3993 * END 3994 * END (* local is unique *) 3995 * ELSE 3996 * BEGIN (* local is group *) 3997 * (* 3998 * * existing entry is a group name 3999 * *) 4000 * 4001 * update data base - remove entry; 4002 * update data base - add new entry; 4003 * send POSITIVE NAME REGISTRATION RESPONSE; 4004 * return; 4005 * END (* local is group *) 4006 * END (* names exists *) 4007 * ELSE 4008 * BEGIN (* does not exist *) 4009 * 4010 * (* name does not exist in data base *) 4011 * 4012 * update data base - add new entry; 4013 * send POSITIVE NAME REGISTRATION RESPONSE; 4014 * return; 4015 * END (* does not exist *) 4016 * 4017 * NAME RELEASE REQUEST: 4018 * 4019 * (* 4020 * * secure server may choose to disallow 4021 * * a node from deleting a name 4022 * *) 4023 * 4024 * update data base - remove entry; 4025 * send POSITIVE NAME RELEASE RESPONSE; 4026 * return; 4027 * 4028 * NAME UPDATE REQUEST: 4029 * 4030 * (* 4031 * * End-node completed a successful challenge, 4032 * * no update database 4033 * *) 4034 * 4035 * IF secure server THEN 4036 * send NEGATIVE NAME REGISTRATION RESPONSE; 4037 * ELSE 4038 * BEGIN (* new entry *) 4039 * IF entry already exists THEN 4040 * update data base - remove entry; 4041 * update data base - add new entry; 4042 * send POSITIVE NAME REGISTRATION RESPONSE; 4043 * start_timer(TTL); 4044 * END 4045 * 4046 * NAME REFRESH REQUEST: 4047 * check for consistency; 4048 * 4049 * IF node not allowed to have name THEN 4050 * BEGIN 4051 * 4052 * (* 4053 * * tell end node that it can't have name 4054 * *) 4055 * send NEGATIVE NAME REGISTRATION RESPONSE; 4056 * END 4057 * ELSE 4058 * BEGIN 4059 * 4060 * (* 4061 * * send confirmation response to the 4062 * * end node. 4063 * *) 4064 * send POSITIVE NAME REGISTRATION; 4065 * start_timer(TTL); 4066 * END 4067 * return; 4068 * END (* case *) 4069 * END (* procedure *) 4070 */ 4071 static void 4072 smb_name_process_Pnode_packet(struct name_packet *packet, 4073 struct addr_entry *addr) 4074 { 4075 struct name_entry *name; 4076 struct name_entry *entry; 4077 struct name_question *question; 4078 struct resource_record *additional; 4079 4080 question = packet->question; 4081 additional = packet->additional; 4082 4083 if (packet->info & NAME_NM_FLAGS_B) { 4084 /* 4085 * always ignore UDP broadcast packets 4086 */ 4087 return; 4088 } 4089 4090 switch (packet->info & NAME_OPCODE_OPCODE_MASK) { 4091 case NAME_OPCODE_REFRESH: 4092 /* Guard against malformed packets */ 4093 if ((question == 0) || (additional == 0)) 4094 break; 4095 if (additional->name->addr_list.sin.sin_addr.s_addr == 0) 4096 break; 4097 4098 name = question->name; 4099 name->addr_list.ttl = additional->ttl; 4100 name->attributes = additional->name->attributes; 4101 name->addr_list.sin = additional->name->addr_list.sin; 4102 name->addr_list.forw = name->addr_list.back = &name->addr_list; 4103 4104 if ((entry = smb_netbios_cache_lookup(name)) != 0) { 4105 smb_netbios_cache_update_entry(entry, name); 4106 smb_netbios_cache_unlock_entry(entry); 4107 } 4108 else 4109 (void) smb_netbios_cache_insert(name); 4110 4111 (void) smb_send_name_registration_response(addr, packet, 0); 4112 break; 4113 4114 case NAME_OPCODE_QUERY: 4115 /* 4116 * This opcode covers both NAME_QUERY_REQUEST and 4117 * NODE_STATUS_REQUEST. They can be distinguished 4118 * based on the type of question entry. 4119 */ 4120 4121 /* All query requests have to have question entry */ 4122 if (question == 0) 4123 break; 4124 4125 if (question->question_type == NAME_QUESTION_TYPE_NB) { 4126 name = question->name; 4127 if ((entry = smb_netbios_cache_lookup(name)) != 0) { 4128 /* 4129 * send response to the IP address and port 4130 * number from which the request was received. 4131 */ 4132 (void) smb_send_name_query_response(addr, 4133 packet, entry, 0); 4134 smb_netbios_cache_unlock_entry(entry); 4135 } else { 4136 /* 4137 * send response to the requestor 4138 */ 4139 (void) smb_send_name_query_response(addr, 4140 packet, name, RCODE_NAM_ERR); 4141 } 4142 } 4143 else 4144 if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) { 4145 /* 4146 * Name of "*" may be used to force node to 4147 * divulge status for administrative purposes 4148 */ 4149 name = question->name; 4150 entry = 0; 4151 if (NETBIOS_NAME_IS_STAR(name->name) || 4152 ((entry = smb_netbios_cache_lookup(name)) != 0)) { 4153 /* 4154 * send only those names that are 4155 * in the same scope as the scope 4156 * field in the request packet 4157 */ 4158 if (entry) 4159 smb_netbios_cache_unlock_entry(entry); 4160 (void) smb_send_node_status_response(addr, 4161 packet); 4162 } 4163 } 4164 break; 4165 4166 default: 4167 break; 4168 } 4169 } 4170 4171 /* 4172 * 5.1.3.5. M-NODE INCOMING PACKET PROCESSING 4173 * 4174 * Processing initiated by reception of packets at a M node 4175 * 4176 * PROCEDURE process_incoming_packet(packet) 4177 * 4178 * (* 4179 * * Processing initiated by incoming packets at a M node 4180 * *) 4181 * 4182 * BEGIN 4183 * CASE packet type of 4184 * 4185 * NAME CONFLICT DEMAND: 4186 * IF name exists in local name table THEN 4187 * mark name as in conflict; 4188 * return; 4189 * 4190 * NAME QUERY REQUEST: 4191 * IF name exists in local name table THEN 4192 * BEGIN (* name exists *) 4193 * 4194 * (* 4195 * * build packet 4196 * *) 4197 * ... 4198 * 4199 * (* 4200 * * send response to the IP address and port 4201 * * number from which the request was received. 4202 * *) 4203 * 4204 * send POSITIVE NAME QUERY RESPONSE ; 4205 * return; 4206 * END (* exists *) 4207 * ELSE 4208 * BEGIN (* does not exist *) 4209 * 4210 * (* 4211 * * send response to the requestor 4212 * *) 4213 * 4214 * IF request NOT broadcast THEN 4215 * (* 4216 * * Don't send negative responses to 4217 * * queries sent by B nodes 4218 * *) 4219 * send NEGATIVE NAME QUERY RESPONSE ; 4220 * return; 4221 * END (* does not exist *) 4222 * NODE STATUS REQUEST: 4223 * BEGIN 4224 * (* 4225 * * Name of "*" may be used to force node to 4226 * * divulge status for administrative purposes 4227 * *) 4228 * IF name in local name table OR name = "*" THEN 4229 * (* 4230 * * Build response packet and 4231 * * send to requestor node 4232 * * Send only those names that are 4233 * * in the same scope as the scope 4234 * * in the request packet. 4235 * *) 4236 * 4237 * send NODE STATUS RESPONSE; 4238 * END 4239 * 4240 * NAME RELEASE REQUEST: 4241 * (* 4242 * * This will be received if the NAME wants to flush the 4243 * * name from the local name table, or from the local 4244 * * cache. 4245 * *) 4246 * 4247 * IF name exists in the local name table THEN 4248 * BEGIN 4249 * delete name from local name table; 4250 * inform user that name has been deleted; 4251 * END 4252 * NAME REGISTRATION REQUEST (UNIQUE): 4253 * IF name exists in local name table THEN 4254 * send NEGATIVE NAME REGISTRATION RESPONSE ; 4255 * NAME REGISTRATION REQUEST (GROUP): 4256 * IF name exists in local name table THEN 4257 * BEGIN 4258 * IF local entry is a unique name THEN 4259 * send NEGATIVE NAME REGISTRATION RESPONSE ; 4260 * END 4261 * END (* case *) 4262 * END (* procedure *) 4263 */ 4264 static void 4265 smb_name_process_Mnode_packet(struct name_packet *packet, 4266 struct addr_entry *addr) 4267 { 4268 if (packet->info & NAME_NM_FLAGS_B) 4269 smb_name_process_Bnode_packet(packet, addr); 4270 else 4271 smb_name_process_Pnode_packet(packet, addr); 4272 } 4273 4274 static void 4275 smb_name_process_Hnode_packet(struct name_packet *packet, 4276 struct addr_entry *addr) 4277 { 4278 if (packet->info & NAME_NM_FLAGS_B) 4279 smb_name_process_Bnode_packet(packet, addr); 4280 else 4281 smb_name_process_Pnode_packet(packet, addr); 4282 } 4283 4284 4285 /* 4286 * smb_netbios_name_tick 4287 * 4288 * Called once a second to handle name server timeouts. 4289 */ 4290 void 4291 smb_netbios_name_tick(void) 4292 { 4293 struct name_entry *name; 4294 struct name_entry *entry; 4295 4296 (void) mutex_lock(&refresh_queue.mtx); 4297 smb_netbios_cache_refresh(&refresh_queue); 4298 4299 while ((name = refresh_queue.head.forw) != &refresh_queue.head) { 4300 QUEUE_CLIP(name); 4301 if (IS_LOCAL(name->attributes)) { 4302 if (IS_UNIQUE(name->attributes)) { 4303 (void) smb_name_Pnode_refresh_name(name); 4304 } 4305 } else { 4306 entry = smb_name_find_name(name); 4307 smb_name_unlock_name(entry); 4308 } 4309 free(name); 4310 } 4311 (void) mutex_unlock(&refresh_queue.mtx); 4312 4313 smb_netbios_cache_reset_ttl(); 4314 } 4315 4316 4317 /* 4318 * smb_name_find_name 4319 * 4320 * Lookup name cache for the given name. 4321 * If it's not in the cache it'll send a 4322 * name query request and then lookup the 4323 * cache again. Note that if a name is 4324 * returned it's locked and called MUST 4325 * unlock it by calling smb_name_unlock_name() 4326 */ 4327 struct name_entry * 4328 smb_name_find_name(struct name_entry *name) 4329 { 4330 struct name_entry *result; 4331 4332 if ((result = smb_netbios_cache_lookup(name)) == 0) { 4333 switch (smb_node_type) { 4334 case 'B': 4335 (void) smb_name_Bnode_find_name(name); 4336 break; 4337 case 'P': 4338 (void) smb_name_Pnode_find_name(name); 4339 break; 4340 case 'M': 4341 (void) smb_name_Mnode_find_name(name); 4342 break; 4343 case 'H': 4344 default: 4345 (void) smb_name_Hnode_find_name(name); 4346 break; 4347 } 4348 return (smb_netbios_cache_lookup(name)); 4349 } 4350 4351 return (result); 4352 } 4353 4354 void 4355 smb_name_unlock_name(struct name_entry *name) 4356 { 4357 smb_netbios_cache_unlock_entry(name); 4358 } 4359 4360 int 4361 smb_name_add_name(struct name_entry *name) 4362 { 4363 int rc = 1; 4364 4365 smb_netbios_name_dump(name); 4366 4367 switch (smb_node_type) { 4368 case 'B': 4369 rc = smb_name_Bnode_add_name(name); 4370 break; 4371 case 'P': 4372 rc = smb_name_Pnode_add_name(name); 4373 break; 4374 case 'M': 4375 rc = smb_name_Mnode_add_name(name); 4376 break; 4377 case 'H': 4378 default: 4379 rc = smb_name_Hnode_add_name(name); 4380 break; 4381 } 4382 4383 if (rc >= 0) 4384 (void) smb_netbios_cache_insert(name); 4385 4386 return (rc); 4387 } 4388 4389 int 4390 smb_name_delete_name(struct name_entry *name) 4391 { 4392 int rc; 4393 unsigned char type; 4394 4395 type = name->name[15]; 4396 if ((type != 0x00) && (type != 0x20)) { 4397 syslog(LOG_ERR, 4398 "netbios: error trying to delete non-local name"); 4399 smb_netbios_name_logf(name); 4400 name->attributes &= ~NAME_ATTR_LOCAL; 4401 return (-1); 4402 } 4403 4404 smb_netbios_cache_delete(name); 4405 4406 switch (smb_node_type) { 4407 case 'B': 4408 rc = smb_name_Bnode_delete_name(name); 4409 break; 4410 case 'P': 4411 rc = smb_name_Pnode_delete_name(name); 4412 break; 4413 case 'M': 4414 rc = smb_name_Mnode_delete_name(name); 4415 break; 4416 case 'H': 4417 default: 4418 rc = smb_name_Hnode_delete_name(name); 4419 break; 4420 } 4421 4422 if (rc > 0) 4423 return (0); 4424 4425 return (-1); 4426 } 4427 4428 typedef struct { 4429 struct addr_entry *addr; 4430 char *buf; 4431 int length; 4432 } worker_param_t; 4433 4434 /* 4435 * smb_netbios_worker 4436 * 4437 * Process incoming request/response packets for Netbios 4438 * name service (on port 138). 4439 */ 4440 void * 4441 smb_netbios_worker(void *arg) 4442 { 4443 worker_param_t *p = (worker_param_t *)arg; 4444 struct addr_entry *addr = p->addr; 4445 struct name_packet *packet; 4446 4447 if ((packet = smb_name_buf_to_packet(p->buf, p->length)) != 0) { 4448 if (packet->info & NAME_OPCODE_R) { 4449 /* Reply packet */ 4450 smb_reply_ready(packet, addr); 4451 free(p->buf); 4452 free(p); 4453 return (0); 4454 } 4455 4456 /* Request packet */ 4457 switch (smb_node_type) { 4458 case 'B': 4459 smb_name_process_Bnode_packet(packet, addr); 4460 break; 4461 case 'P': 4462 smb_name_process_Pnode_packet(packet, addr); 4463 break; 4464 case 'M': 4465 smb_name_process_Mnode_packet(packet, addr); 4466 break; 4467 case 'H': 4468 default: 4469 smb_name_process_Hnode_packet(packet, addr); 4470 break; 4471 } 4472 4473 if (packet->answer) 4474 smb_netbios_name_freeaddrs(packet->answer->name); 4475 free(packet); 4476 } else { 4477 syslog(LOG_DEBUG, "SmbNBNS: error decoding received packet"); 4478 } 4479 4480 free(addr); 4481 free(p->buf); 4482 free(p); 4483 return (0); 4484 } 4485 4486 static void 4487 smb_netbios_wins_config(char *ip) 4488 { 4489 uint32_t ipaddr; 4490 4491 ipaddr = inet_addr(ip); 4492 if (ipaddr != INADDR_NONE) { 4493 smb_nbns[nbns_num].flags = ADDR_FLAG_VALID; 4494 smb_nbns[nbns_num].sinlen = sizeof (struct sockaddr_in); 4495 smb_nbns[nbns_num].sin.sin_family = AF_INET; 4496 smb_nbns[nbns_num].sin.sin_addr.s_addr = ipaddr; 4497 smb_nbns[nbns_num++].sin.sin_port = 4498 htons(NAME_SERVICE_UDP_PORT); 4499 smb_node_type = SMB_NODETYPE_H; 4500 } 4501 } 4502 4503 static void 4504 smb_netbios_name_registration(void) 4505 { 4506 nbcache_iter_t nbc_iter; 4507 struct name_entry *name; 4508 int rc; 4509 4510 rc = smb_netbios_cache_getfirst(&nbc_iter); 4511 while (rc == 0) { 4512 name = nbc_iter.nbc_entry; 4513 (void) smb_netbios_name_logf(name); 4514 if (IS_UNIQUE(name->attributes) && IS_LOCAL(name->attributes)) { 4515 switch (smb_node_type) { 4516 case SMB_NODETYPE_B: 4517 (void) smb_name_Bnode_add_name(name); 4518 break; 4519 case SMB_NODETYPE_P: 4520 (void) smb_name_Pnode_add_name(name); 4521 break; 4522 case SMB_NODETYPE_M: 4523 (void) smb_name_Mnode_add_name(name); 4524 break; 4525 case SMB_NODETYPE_H: 4526 default: 4527 (void) smb_name_Hnode_add_name(name); 4528 break; 4529 } 4530 } 4531 free(name); 4532 rc = smb_netbios_cache_getnext(&nbc_iter); 4533 } 4534 } 4535 4536 void 4537 smb_netbios_name_config(void) 4538 { 4539 struct name_entry name; 4540 char wins_ip[16]; 4541 smb_niciter_t ni; 4542 int rc; 4543 4544 /* Start with no broadcast addresses */ 4545 bcast_num = 0; 4546 bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS); 4547 4548 /* Add all of the broadcast addresses */ 4549 rc = smb_nic_getfirst(&ni); 4550 while (rc == 0) { 4551 if (ni.ni_nic.nic_smbflags & 4552 (SMB_NICF_ALIAS | SMB_NICF_NBEXCL)) { 4553 rc = smb_nic_getnext(&ni); 4554 continue; 4555 } 4556 smb_bcast_list[bcast_num].flags = ADDR_FLAG_VALID; 4557 smb_bcast_list[bcast_num].attributes = NAME_ATTR_LOCAL; 4558 smb_bcast_list[bcast_num].sinlen = sizeof (struct sockaddr_in); 4559 smb_bcast_list[bcast_num].sin.sin_family = AF_INET; 4560 smb_bcast_list[bcast_num].sin.sin_port = 4561 htons(NAME_SERVICE_UDP_PORT); 4562 smb_bcast_list[bcast_num++].sin.sin_addr.s_addr = 4563 ni.ni_nic.nic_bcast; 4564 rc = smb_nic_getnext(&ni); 4565 } 4566 4567 /* Start with no WINS */ 4568 smb_node_type = SMB_NODETYPE_B; 4569 nbns_num = 0; 4570 bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS); 4571 4572 /* add any configured WINS */ 4573 (void) smb_config_getstr(SMB_CI_WINS_SRV1, wins_ip, sizeof (wins_ip)); 4574 smb_netbios_wins_config(wins_ip); 4575 (void) smb_config_getstr(SMB_CI_WINS_SRV2, wins_ip, sizeof (wins_ip)); 4576 smb_netbios_wins_config(wins_ip); 4577 4578 if (smb_nic_getfirst(&ni) != 0) 4579 return; 4580 4581 do { 4582 if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) || 4583 (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS)) 4584 continue; 4585 4586 smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host, 4587 0x00, 0, ni.ni_nic.nic_ip, htons(DGM_SRVC_UDP_PORT), 4588 NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name); 4589 (void) smb_netbios_cache_insert(&name); 4590 4591 smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host, 4592 0x20, 0, ni.ni_nic.nic_ip, htons(DGM_SRVC_UDP_PORT), 4593 NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name); 4594 (void) smb_netbios_cache_insert(&name); 4595 } while (smb_nic_getnext(&ni) == 0); 4596 4597 smb_netbios_name_registration(); 4598 } 4599 4600 void 4601 smb_netbios_name_unconfig(void) 4602 { 4603 struct name_entry *name; 4604 4605 (void) mutex_lock(&delete_queue.mtx); 4606 smb_netbios_cache_delete_locals(&delete_queue); 4607 4608 while ((name = delete_queue.head.forw) != &delete_queue.head) { 4609 QUEUE_CLIP(name); 4610 (void) smb_name_delete_name(name); 4611 free(name); 4612 } 4613 (void) mutex_unlock(&delete_queue.mtx); 4614 } 4615 4616 void 4617 smb_netbios_name_reconfig(void) 4618 { 4619 smb_netbios_name_unconfig(); 4620 smb_netbios_name_config(); 4621 } 4622 4623 /* 4624 * process_incoming Function: void smb_netbios_name_service_daemon(void) 4625 * 4626 * Description: 4627 * 4628 * Put test description here. 4629 * 4630 * Inputs: 4631 * Nothing 4632 * 4633 * Returns: 4634 * int -> Description 4635 */ 4636 /*ARGSUSED*/ 4637 void * 4638 smb_netbios_name_service_daemon(void *arg) 4639 { 4640 struct sockaddr_in sin; 4641 struct addr_entry *addr; 4642 int len; 4643 int flag = 1; 4644 char *buf; 4645 worker_param_t *worker_param; 4646 4647 /* 4648 * Initialize reply_queue 4649 */ 4650 bzero(&reply_queue, sizeof (reply_queue)); 4651 reply_queue.forw = reply_queue.back = &reply_queue; 4652 4653 if (!smb_netbios_cache_init()) 4654 return (0); 4655 4656 bcast_num = 0; 4657 bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS); 4658 4659 if ((name_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 4660 syslog(LOG_ERR, 4661 "smbd: Could not create AF_INET, SOCK_DGRAM, socket"); 4662 smb_netbios_cache_fini(); 4663 smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1); 4664 return (0); 4665 } 4666 4667 (void) setsockopt(name_sock, SOL_SOCKET, SO_BROADCAST, &flag, 4668 sizeof (flag)); 4669 4670 bzero(&sin, sizeof (struct sockaddr_in)); 4671 sin.sin_family = AF_INET; 4672 sin.sin_port = htons(NAME_SERVICE_UDP_PORT); 4673 if (bind(name_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) { 4674 syslog(LOG_ERR, 4675 "smbd: Bind to name service port %d failed (%d)", 4676 NAME_SERVICE_UDP_PORT, errno); 4677 smb_netbios_cache_fini(); 4678 (void) close(name_sock); 4679 smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1); 4680 return (0); 4681 } 4682 4683 smb_netbios_chg_status(NETBIOS_NAME_SVC_RUNNING, 1); 4684 4685 while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) || 4686 (nb_status.state & NETBIOS_BROWSER_RUNNING)) { 4687 if ((buf = malloc(MAX_DATAGRAM_LENGTH)) == 0) { 4688 /* Sleep for 10 sec and try again */ 4689 (void) sleep(10); 4690 continue; 4691 } 4692 if ((addr = (struct addr_entry *) 4693 malloc(sizeof (struct addr_entry))) == 0) { 4694 /* Sleep for 10 sec and try again */ 4695 free(buf); 4696 (void) sleep(10); 4697 continue; 4698 } 4699 ignore: bzero(addr, sizeof (struct addr_entry)); 4700 addr->sinlen = sizeof (addr->sin); 4701 addr->forw = addr->back = addr; 4702 4703 if ((len = recvfrom(name_sock, buf, MAX_DATAGRAM_LENGTH, 4704 0, (struct sockaddr *)&addr->sin, &addr->sinlen)) < 0) { 4705 if (errno == ENOMEM || errno == ENFILE || 4706 errno == EMFILE) { 4707 /* Sleep for 10 sec and try again */ 4708 free(buf); 4709 free(addr); 4710 (void) sleep(10); 4711 continue; 4712 } 4713 syslog(LOG_ERR, 4714 "smbd: NETBIOS name service - recvfrom failed"); 4715 free(buf); 4716 free(addr); 4717 smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1); 4718 goto shutdown; 4719 } 4720 4721 /* Ignore any incoming packets from myself... */ 4722 if (smb_nic_exists(addr->sin.sin_addr.s_addr, B_FALSE)) 4723 goto ignore; 4724 4725 /* 4726 * Launch a netbios worker to process the received packet. 4727 */ 4728 worker_param = (worker_param_t *) 4729 malloc(sizeof (worker_param_t)); 4730 if (worker_param) { 4731 pthread_t worker; 4732 pthread_attr_t tattr; 4733 4734 worker_param->addr = addr; 4735 worker_param->buf = buf; 4736 worker_param->length = len; 4737 4738 (void) pthread_attr_init(&tattr); 4739 (void) pthread_attr_setdetachstate(&tattr, 4740 PTHREAD_CREATE_DETACHED); 4741 (void) pthread_create(&worker, &tattr, 4742 smb_netbios_worker, worker_param); 4743 (void) pthread_attr_destroy(&tattr); 4744 } 4745 } 4746 4747 shutdown: 4748 smb_netbios_chg_status(NETBIOS_NAME_SVC_RUNNING, 0); 4749 4750 (void) mutex_lock(&nb_status.mtx); 4751 while (nb_status.state & NETBIOS_BROWSER_RUNNING) 4752 (void) cond_wait(&nb_status.cv, &nb_status.mtx); 4753 (void) mutex_unlock(&nb_status.mtx); 4754 4755 if ((nb_status.state & NETBIOS_NAME_SVC_FAILED) == 0) { 4756 /* this might delay shutdown, do we want to do this? */ 4757 /* 4758 * it'll send name release requests but nobody's waiting 4759 * for response and it'll eventually timeout. 4760 */ 4761 smb_netbios_name_unconfig(); 4762 } 4763 (void) close(name_sock); 4764 smb_netbios_cache_fini(); 4765 syslog(LOG_DEBUG, "smbd: Netbios Name Service is down\n"); 4766 return (0); 4767 } 4768