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