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