1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Description: 30 * 31 * Contains base code for netbios datagram service. 32 * 33 * Relavent sections from RFC1002: 34 * 35 * 5.3. NetBIOS DATAGRAM SERVICE PROTOCOLS 36 * 37 * The following are GLOBAL variables and should be NetBIOS user 38 * configurable: 39 * 40 * - SCOPE_ID: the non-leaf section of the domain name preceded by a 41 * '.' which represents the domain of the NetBIOS scope for the 42 * NetBIOS name. The following protocol description only supports 43 * single scope operation. 44 * 45 * - MAX_DATAGRAM_LENGTH: the maximum length of an IP datagram. The 46 * minimal maximum length defined in for IP is 576 bytes. This 47 * value is used when determining whether to fragment a NetBIOS 48 * datagram. Implementations are expected to be capable of 49 * receiving unfragmented NetBIOS datagrams up to their maximum 50 * size. 51 * 52 * - BROADCAST_ADDRESS: the IP address B-nodes use to send datagrams 53 * with group name destinations and broadcast datagrams. The 54 * default is the IP broadcast address for a single IP network. 55 * 56 * 57 * The following are Defined Constants for the NetBIOS Datagram 58 * Service: 59 * 60 * - DGM_SRVC_UDP_PORT: the globally well-known UDP port allocated 61 * where the NetBIOS Datagram Service receives UDP packets. See 62 * section 6, "Defined Constants", for its value. 63 */ 64 65 /* 66 * 67 * 6. DEFINED CONSTANTS AND VARIABLES 68 * 69 * GENERAL: 70 * 71 * SCOPE_ID The name of the NetBIOS scope. 72 * 73 * This is expressed as a character 74 * string meeting the requirements of 75 * the domain name system and without 76 * a leading or trailing "dot". 77 * 78 * An implementation may elect to make 79 * this a single global value for the 80 * node or allow it to be specified 81 * with each separate NetBIOS name 82 * (thus permitting cross-scope 83 * references.) 84 * 85 * BROADCAST_ADDRESS An IP address composed of the 86 * node network and subnetwork 87 * numbers with all remaining bits set 88 * to one. 89 * 90 * I.e. "Specific subnet" broadcast 91 * addressing according to section 2.3 92 * of RFC 950. 93 * 94 * BCAST_REQ_RETRY_TIMEOUT 250 milliseconds. 95 * An adaptive timer may be used. 96 * 97 * BCAST_REQ_RETRY_COUNT 3 98 * 99 * UCAST_REQ_RETRY_TIMEOUT 5 seconds 100 * An adaptive timer may be used. 101 * 102 * UCAST_REQ_RETRY_COUNT 3 103 * 104 * MAX_DATAGRAM_LENGTH 576 bytes (default) 105 * 106 * DATAGRAM SERVICE: 107 * 108 * DGM_SRVC_UDP_PORT 138 (decimal) 109 * 110 * FRAGMENT_TO 2 seconds (default) 111 */ 112 113 #include <stdlib.h> 114 #include <unistd.h> 115 #include <string.h> 116 #include <strings.h> 117 #include <syslog.h> 118 #include <synch.h> 119 #include <sys/socket.h> 120 #include <arpa/inet.h> 121 122 #include <smbns_netbios.h> 123 124 #include <smbsrv/libsmbns.h> 125 126 static int datagram_sock = -1; 127 static short datagram_id = 1; 128 static struct datagram_queue smb_datagram_queue; 129 static mutex_t smb_dgq_mtx; 130 131 /* 132 * Function: smb_netbios_datagram_tick(void) 133 * 134 * Description: 135 * 136 * Called once a second to handle time to live timeouts in 137 * datagram assembly queue. 138 * 139 * Inputs: 140 * 141 * Returns: 142 * void -> Nothing at all... 143 */ 144 145 void 146 smb_netbios_datagram_tick(void) 147 { 148 struct datagram *entry; 149 struct datagram *next; 150 151 (void) mutex_lock(&smb_dgq_mtx); 152 153 for (entry = smb_datagram_queue.forw; 154 entry != (struct datagram *)((uintptr_t)&smb_datagram_queue); 155 entry = next) { 156 next = entry->forw; 157 if (--entry->discard_timer == 0) { 158 /* Toss it */ 159 QUEUE_CLIP(entry); 160 free(entry); 161 } 162 } 163 (void) mutex_unlock(&smb_dgq_mtx); 164 } 165 166 void 167 smb_netbios_datagram_fini() 168 { 169 struct datagram *entry; 170 171 (void) mutex_lock(&smb_dgq_mtx); 172 while ((entry = smb_datagram_queue.forw) != 173 (struct datagram *)((uintptr_t)&smb_datagram_queue)) { 174 QUEUE_CLIP(entry); 175 free(entry); 176 } 177 (void) mutex_unlock(&smb_dgq_mtx); 178 } 179 180 /* 181 * Function: int smb_netbios_send_Bnode_datagram(unsigned char *data, 182 * struct name_entry *source, struct name_entry *destination, 183 * uint32_t broadcast) 184 * 185 * Description from rfc1002: 186 * 187 * 5.3.1. B NODE TRANSMISSION OF NetBIOS DATAGRAMS 188 * 189 * PROCEDURE send_datagram(data, source, destination, broadcast) 190 * 191 * (* 192 * * user initiated processing on B node 193 * *) 194 * 195 * BEGIN 196 * group = FALSE; 197 * 198 * do name discovery on destination name, returns name type and 199 * IP address; 200 * 201 * IF name type is group name THEN 202 * BEGIN 203 * group = TRUE; 204 * END 205 * 206 * (* 207 * * build datagram service UDP packet; 208 * *) 209 * convert source and destination NetBIOS names into 210 * half-ASCII, biased encoded name; 211 * SOURCE_NAME = cat(source, SCOPE_ID); 212 * SOURCE_IP = this nodes IP address; 213 * SOURCE_PORT = DGM_SRVC_UDP_PORT; 214 * 215 * IF NetBIOS broadcast THEN 216 * BEGIN 217 * DESTINATION_NAME = cat("*", SCOPE_ID) 218 * END 219 * ELSE 220 * BEGIN 221 * DESTINATION_NAME = cat(destination, SCOPE_ID) 222 * END 223 * 224 * MSG_TYPE = select_one_from_set 225 * {BROADCAST, DIRECT_UNIQUE, DIRECT_GROUP} 226 * DGM_ID = next transaction id for Datagrams; 227 * DGM_LENGTH = length of data + length of second level encoded 228 * source and destination names; 229 * 230 * IF (length of the NetBIOS Datagram, including UDP and 231 * IP headers, > MAX_DATAGRAM_LENGTH) THEN 232 * BEGIN 233 * (* 234 * * fragment NetBIOS datagram into 2 UDP packets 235 * *) 236 * Put names into 1st UDP packet and any data that fits 237 * after names; 238 * Set MORE and FIRST bits in 1st UDP packets FLAGS; 239 * OFFSET in 1st UDP = 0; 240 * 241 * Replicate NetBIOS Datagram header from 1st UDP packet 242 * into 2nd UDP packet; 243 * Put rest of data in 2nd UDP packet; 244 * Clear MORE and FIRST bits in 2nd UDP packets FLAGS; 245 * OFFSET in 2nd UDP = DGM_LENGTH - number of name and 246 * data bytes in 1st UDP; 247 * END 248 * BEGIN 249 * (* 250 * * Only need one UDP packet 251 * *) 252 * USER_DATA = data; 253 * Clear MORE bit and set FIRST bit in FLAGS; 254 * OFFSET = 0; 255 * END 256 * 257 * IF (group == TRUE) OR (NetBIOS broadcast) THEN 258 * BEGIN 259 * send UDP packet(s) to BROADCAST_ADDRESS; 260 * END 261 * ELSE 262 * BEGIN 263 * send UDP packet(s) to IP address returned by name 264 * discovery; 265 * END 266 * END (* procedure *) 267 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 268 * 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 269 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 270 * | MSG_TYPE | FLAGS | DGM_ID | 271 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 272 * | SOURCE_IP | 273 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 274 * | SOURCE_PORT | DGM_LENGTH | 275 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 276 * | PACKET_OFFSET | 277 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 278 * 279 * MSG_TYPE values (in hexidecimal): 280 * 281 * 10 - DIRECT_UNIQUE DATAGRAM 282 * 11 - DIRECT_GROUP DATAGRAM 283 * 12 - BROADCAST DATAGRAM 284 * 13 - DATAGRAM ERROR 285 * 14 - DATAGRAM QUERY REQUEST 286 * 15 - DATAGRAM POSITIVE QUERY RESPONSE 287 * 16 - DATAGRAM NEGATIVE QUERY RESPONSE 288 * 289 * Bit definitions of the FLAGS field: 290 * 291 * 0 1 2 3 4 5 6 7 292 * +---+---+---+---+---+---+---+---+ 293 * | 0 | 0 | 0 | 0 | SNT | F | M | 294 * +---+---+---+---+---+---+---+---+ 295 * 296 * Symbol Bit(s) Description 297 * 298 * M 7 MORE flag, If set then more NetBIOS datagram 299 * fragments follow. 300 * 301 * F 6 FIRST packet flag, If set then this is first 302 * (and possibly only) fragment of NetBIOS 303 * datagram 304 * 305 * SNT 4,5 Source End-Node type: 306 * 00 = B node 307 * 01 = P node 308 * 10 = M node 309 * 11 = NBDD 310 * RESERVED 0-3 Reserved, must be zero (0) 311 * (But MS sets bit 3 in this field) 312 * 313 */ 314 315 int 316 smb_netbios_datagram_send(struct name_entry *src, struct name_entry *dest, 317 unsigned char *data, int length) 318 { 319 uint32_t ipaddr; 320 size_t count, srclen, destlen, sinlen; 321 struct addr_entry *addr; 322 struct sockaddr_in sin; 323 char *buffer; 324 char ha_source[NETBIOS_DOMAIN_NAME_MAX]; 325 char ha_dest[NETBIOS_DOMAIN_NAME_MAX]; 326 327 (void) smb_first_level_name_encode(src, (unsigned char *)ha_source, 328 sizeof (ha_source)); 329 srclen = strlen(ha_source) + 1; 330 331 (void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest, 332 sizeof (ha_dest)); 333 destlen = strlen(ha_dest) + 1; 334 335 /* give some extra room */ 336 buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4); 337 if (buffer == 0) { 338 syslog(LOG_ERR, "netbios: datagram send (resource shortage)"); 339 return (-1); 340 } 341 342 buffer[0] = DATAGRAM_TYPE_DIRECT_UNIQUE; 343 switch (smb_node_type) { 344 case 'B': 345 buffer[1] = DATAGRAM_FLAGS_B_NODE | DATAGRAM_FLAGS_FIRST; 346 break; 347 case 'P': 348 buffer[1] = DATAGRAM_FLAGS_P_NODE | DATAGRAM_FLAGS_FIRST; 349 break; 350 case 'M': 351 buffer[1] = DATAGRAM_FLAGS_M_NODE | DATAGRAM_FLAGS_FIRST; 352 break; 353 case 'H': 354 default: 355 buffer[1] = DATAGRAM_FLAGS_H_NODE | DATAGRAM_FLAGS_FIRST; 356 break; 357 } 358 359 datagram_id++; 360 BE_OUT16(&buffer[2], datagram_id); 361 (void) memcpy(&buffer[4], &src->addr_list.sin.sin_addr.s_addr, 362 sizeof (uint32_t)); 363 (void) memcpy(&buffer[8], &src->addr_list.sin.sin_port, 364 sizeof (uint16_t)); 365 BE_OUT16(&buffer[10], length + srclen + destlen); 366 BE_OUT16(&buffer[12], 0); 367 368 bcopy(ha_source, &buffer[14], srclen); 369 bcopy(ha_dest, &buffer[14 + srclen], destlen); 370 bcopy(data, &buffer[14 + srclen + destlen], length); 371 count = &buffer[14 + srclen + destlen + length] - buffer; 372 373 bzero(&sin, sizeof (sin)); 374 sin.sin_family = AF_INET; 375 sinlen = sizeof (sin); 376 addr = &dest->addr_list; 377 do { 378 ipaddr = addr->sin.sin_addr.s_addr; 379 /* Don't send anything to myself... */ 380 if (smb_nic_exists(ipaddr, B_FALSE)) 381 goto next; 382 383 sin.sin_addr.s_addr = ipaddr; 384 sin.sin_port = addr->sin.sin_port; 385 (void) sendto(datagram_sock, buffer, count, 0, 386 (struct sockaddr *)&sin, sinlen); 387 388 next: addr = addr->forw; 389 } while (addr != &dest->addr_list); 390 free(buffer); 391 return (0); 392 } 393 394 395 int 396 smb_netbios_datagram_send_to_net(struct name_entry *src, 397 struct name_entry *dest, char *data, int length) 398 { 399 uint32_t ipaddr; 400 size_t count, srclen, destlen, sinlen; 401 struct addr_entry *addr; 402 struct sockaddr_in sin; 403 char *buffer; 404 char ha_source[NETBIOS_DOMAIN_NAME_MAX]; 405 char ha_dest[NETBIOS_DOMAIN_NAME_MAX]; 406 407 (void) smb_first_level_name_encode(src, (unsigned char *)ha_source, 408 sizeof (ha_source)); 409 srclen = strlen(ha_source) + 1; 410 411 (void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest, 412 sizeof (ha_dest)); 413 destlen = strlen(ha_dest) + 1; 414 415 /* give some extra room */ 416 buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4); 417 if (buffer == 0) { 418 syslog(LOG_ERR, "netbios: datagram send (resource shortage)"); 419 return (-1); 420 } 421 422 buffer[0] = DATAGRAM_TYPE_DIRECT_UNIQUE; 423 switch (smb_node_type) { 424 case 'B': 425 buffer[1] = DATAGRAM_FLAGS_B_NODE | DATAGRAM_FLAGS_FIRST; 426 break; 427 case 'P': 428 buffer[1] = DATAGRAM_FLAGS_P_NODE | DATAGRAM_FLAGS_FIRST; 429 break; 430 case 'M': 431 buffer[1] = DATAGRAM_FLAGS_M_NODE | DATAGRAM_FLAGS_FIRST; 432 break; 433 case 'H': 434 default: 435 buffer[1] = DATAGRAM_FLAGS_H_NODE | DATAGRAM_FLAGS_FIRST; 436 break; 437 } 438 439 datagram_id++; 440 BE_OUT16(&buffer[2], datagram_id); 441 (void) memcpy(&buffer[4], &src->addr_list.sin.sin_addr.s_addr, 442 sizeof (uint32_t)); 443 (void) memcpy(&buffer[8], &src->addr_list.sin.sin_port, 444 sizeof (uint16_t)); 445 BE_OUT16(&buffer[10], length + srclen + destlen); 446 BE_OUT16(&buffer[12], 0); 447 448 bcopy(ha_source, &buffer[14], srclen); 449 bcopy(ha_dest, &buffer[14 + srclen], destlen); 450 bcopy(data, &buffer[14 + srclen + destlen], length); 451 count = &buffer[14 + srclen + destlen + length] - buffer; 452 453 bzero(&sin, sizeof (sin)); 454 sin.sin_family = AF_INET; 455 sinlen = sizeof (sin); 456 addr = &dest->addr_list; 457 do { 458 ipaddr = addr->sin.sin_addr.s_addr; 459 if (smb_nic_exists(ipaddr, B_FALSE)) 460 goto next; 461 462 sin.sin_addr.s_addr = ipaddr; 463 sin.sin_port = addr->sin.sin_port; 464 (void) sendto(datagram_sock, buffer, count, 0, 465 (struct sockaddr *)&sin, sinlen); 466 467 next: addr = addr->forw; 468 } while (addr != &dest->addr_list); 469 free(buffer); 470 return (0); 471 } 472 473 474 int 475 smb_datagram_decode(struct datagram *datagram, int bytes) 476 { 477 unsigned char *ha_src; 478 unsigned char *ha_dest; 479 unsigned char *data; 480 481 if (bytes < DATAGRAM_HEADER_LENGTH) { 482 syslog(LOG_ERR, "NbtDatagramDecode[%d]: too small packet", 483 bytes); 484 return (-1); 485 } 486 487 ha_src = &datagram->rawbuf[DATAGRAM_HEADER_LENGTH]; 488 ha_dest = ha_src + strlen((char *)ha_src) + 1; 489 data = ha_dest + strlen((char *)ha_dest) + 1; 490 491 bzero(&datagram->src, sizeof (struct name_entry)); 492 bzero(&datagram->dest, sizeof (struct name_entry)); 493 494 datagram->rawbytes = bytes; 495 datagram->packet_type = datagram->rawbuf[0]; 496 datagram->flags = datagram->rawbuf[1]; 497 datagram->datagram_id = BE_IN16(&datagram->rawbuf[2]); 498 499 datagram->src.addr_list.sinlen = sizeof (struct sockaddr_in); 500 (void) memcpy(&datagram->src.addr_list.sin.sin_addr.s_addr, 501 &datagram->rawbuf[4], sizeof (uint32_t)); 502 (void) memcpy(&datagram->src.addr_list.sin.sin_port, 503 &datagram->rawbuf[8], sizeof (uint16_t)); 504 datagram->src.addr_list.forw = datagram->src.addr_list.back = 505 &datagram->src.addr_list; 506 507 datagram->data = data; 508 datagram->data_length = BE_IN16(&datagram->rawbuf[10]); 509 datagram->offset = BE_IN16(&datagram->rawbuf[12]); 510 511 if (smb_first_level_name_decode(ha_src, &datagram->src) < 0) { 512 syslog(LOG_DEBUG, "NbtDatagram[%s]: invalid calling name", 513 inet_ntoa(datagram->src.addr_list.sin.sin_addr)); 514 syslog(LOG_DEBUG, "Calling name: <%02X>%32.32s", 515 ha_src[0], &ha_src[1]); 516 } 517 518 datagram->dest.addr_list.forw = datagram->dest.addr_list.back = 519 &datagram->dest.addr_list; 520 521 if (smb_first_level_name_decode(ha_dest, &datagram->dest) < 0) { 522 syslog(LOG_DEBUG, "NbtDatagram[%s]: invalid called name", 523 inet_ntoa(datagram->src.addr_list.sin.sin_addr)); 524 syslog(LOG_DEBUG, "Called name: <%02X>%32.32s", ha_dest[0], 525 &ha_dest[1]); 526 } 527 528 return (0); 529 } 530 531 532 /* 533 * Function: int smb_netbios_process_BPM_datagram(unsigned char *packet, 534 * struct addr_entry *addr) 535 * 536 * Description from rfc1002: 537 * 538 * 5.3.3. RECEPTION OF NetBIOS DATAGRAMS BY ALL NODES 539 * 540 * The following algorithm discards out of order NetBIOS Datagram 541 * fragments. An implementation which reassembles out of order 542 * NetBIOS Datagram fragments conforms to this specification. The 543 * fragment discard timer is initialized to the value FRAGMENT_TIMEOUT. 544 * This value should be user configurable. The default value is 545 * given in Section 6, "Defined Constants and Variables". 546 * 547 * PROCEDURE datagram_packet(packet) 548 * 549 * (* 550 * * processing initiated by datagram packet reception 551 * * on B, P and M nodes 552 * *) 553 * BEGIN 554 * (* 555 * * if this node is a P node, ignore 556 * * broadcast packets. 557 * *) 558 * 559 * IF this is a P node AND incoming packet is 560 * a broadcast packet THEN 561 * BEGIN 562 * discard packet; 563 * END 564 * 565 * CASE packet type OF 566 * 567 * DATAGRAM SERVICE: 568 * BEGIN 569 * IF FIRST bit in FLAGS is set THEN 570 * BEGIN 571 * IF MORE bit in FLAGS is set THEN 572 * BEGIN 573 * Save 1st UDP packet of the Datagram; 574 * Set this Datagrams fragment discard 575 * timer to FRAGMENT_TIMEOUT; 576 * return; 577 * END 578 * ELSE 579 * Datagram is composed of a single 580 * UDP packet; 581 * END 582 * ELSE 583 * BEGIN 584 * (* Have the second fragment of a Datagram *) 585 * 586 * Search for 1st fragment by source IP address 587 * and DGM_ID; 588 * IF found 1st fragment THEN 589 * Process both UDP packets; 590 * ELSE 591 * BEGIN 592 * discard 2nd fragment UDP packet; 593 * return; 594 * END 595 * END 596 * 597 * IF DESTINATION_NAME is '*' THEN 598 * BEGIN 599 * (* NetBIOS broadcast *) 600 * 601 * deliver USER_DATA from UDP packet(s) to all 602 * outstanding receive broadcast 603 * datagram requests; 604 * return; 605 * END 606 * ELSE 607 * BEGIN (* non-broadcast *) 608 * (* Datagram for Unique or Group Name *) 609 * 610 * IF DESTINATION_NAME is not present in the 611 * local name table THEN 612 * BEGIN 613 * (* destination not present *) 614 * build DATAGRAM ERROR packet, clear 615 * FIRST and MORE bit, put in 616 * this nodes IP and PORT, set 617 * ERROR_CODE; 618 * send DATAGRAM ERROR packet to 619 * source IP address and port 620 * of UDP; 621 * discard UDP packet(s); 622 * return; 623 * END 624 * ELSE 625 * BEGIN (* good *) 626 * (* 627 * * Replicate received NetBIOS datagram for 628 * * each recipient 629 * *) 630 * FOR EACH pending NetBIOS users receive 631 * datagram operation 632 * BEGIN 633 * IF source name of operation 634 * matches destination name 635 * of packet THEN 636 * BEGIN 637 * deliver USER_DATA from UDP 638 * packet(s); 639 * END 640 * END (* for each *) 641 * return; 642 * END (* good *) 643 * END (* non-broadcast *) 644 * END (* datagram service *) 645 * 646 * DATAGRAM ERROR: 647 * BEGIN 648 * (* 649 * * name service returned incorrect information 650 * *) 651 * 652 * inform local name service that incorrect 653 * information was provided; 654 * 655 * IF this is a P or M node THEN 656 * BEGIN 657 * (* 658 * * tell NetBIOS Name Server that it may 659 * * have given incorrect information 660 * *) 661 * 662 * send NAME RELEASE REQUEST with name 663 * and incorrect IP address to NetBIOS 664 * Name Server; 665 * END 666 * END (* datagram error *) 667 * 668 * END (* case *) 669 * END 670 */ 671 672 static struct datagram * 673 smb_netbios_datagram_getq(struct datagram *datagram) 674 { 675 struct datagram *prev = 0; 676 677 (void) mutex_lock(&smb_dgq_mtx); 678 for (prev = smb_datagram_queue.forw; 679 prev != (struct datagram *)((uintptr_t)&smb_datagram_queue); 680 prev = prev->forw) { 681 if (prev->src.addr_list.sin.sin_addr.s_addr == 682 datagram->src.addr_list.sin.sin_addr.s_addr) { 683 /* Something waiting */ 684 QUEUE_CLIP(prev); 685 (void) mutex_unlock(&smb_dgq_mtx); 686 bcopy(datagram->data, &prev->data[prev->data_length], 687 datagram->data_length); 688 prev->data_length += datagram->data_length; 689 free(datagram); 690 return (prev); 691 } 692 } 693 (void) mutex_unlock(&smb_dgq_mtx); 694 695 return (0); 696 } 697 698 static void 699 smb_netbios_BPM_datagram(struct datagram *datagram) 700 { 701 struct name_entry *entry = 0; 702 struct datagram *qpacket = 0; 703 pthread_t browser_dispatch; 704 705 switch (datagram->packet_type) { 706 case DATAGRAM_TYPE_BROADCAST : 707 if (smb_node_type == 'P') { 708 /* 709 * if this node is a P node, ignore 710 * broadcast packets. 711 */ 712 break; 713 } 714 /* FALLTHROUGH */ 715 716 case DATAGRAM_TYPE_DIRECT_UNIQUE : 717 case DATAGRAM_TYPE_DIRECT_GROUP : 718 if ((datagram->flags & DATAGRAM_FLAGS_FIRST) != 0) { 719 if (datagram->flags & DATAGRAM_FLAGS_MORE) { 720 /* Save 1st UDP packet of the Datagram */ 721 datagram->discard_timer = FRAGMENT_TIMEOUT; 722 (void) mutex_lock(&smb_dgq_mtx); 723 QUEUE_INSERT_TAIL(&smb_datagram_queue, datagram) 724 (void) mutex_unlock(&smb_dgq_mtx); 725 return; 726 } 727 /* process datagram */ 728 } else { 729 qpacket = smb_netbios_datagram_getq(datagram); 730 if (qpacket) { 731 datagram = qpacket; 732 goto process_datagram; 733 } 734 break; 735 } 736 737 process_datagram: 738 entry = 0; 739 if ((strcmp((char *)datagram->dest.name, "*") == 0) || 740 ((entry = 741 smb_netbios_cache_lookup(&datagram->dest)) != 0)) { 742 if (entry) { 743 int is_local = IS_LOCAL(entry->attributes); 744 smb_netbios_cache_unlock_entry(entry); 745 746 if (is_local) { 747 (void) pthread_create(&browser_dispatch, 748 0, smb_browser_dispatch, 749 (void *)datagram); 750 (void) pthread_detach(browser_dispatch); 751 return; 752 } 753 } 754 755 datagram->rawbuf[0] = DATAGRAM_TYPE_ERROR_DATAGRAM; 756 datagram->rawbuf[1] &= DATAGRAM_FLAGS_SRC_TYPE; 757 758 (void) memcpy(&datagram->rawbuf[4], 759 &datagram->src.addr_list.sin.sin_addr.s_addr, 760 sizeof (uint32_t)); 761 BE_OUT16(&datagram->rawbuf[8], DGM_SRVC_UDP_PORT); 762 763 (void) sendto(datagram_sock, datagram->rawbuf, 764 datagram->rawbytes, 0, 765 (struct sockaddr *)&datagram->src.addr_list.sin, 766 datagram->src.addr_list.sinlen); 767 } 768 break; 769 770 case DATAGRAM_TYPE_ERROR_DATAGRAM : 771 break; 772 } 773 free(datagram); 774 } 775 776 777 /* 778 * smb_netbios_process_NBDD_datagram 779 * 780 * Description from rfc1002: 781 * 782 * 783 * 5.3.4. PROTOCOLS FOR THE NBDD 784 * 785 * The key to NetBIOS Datagram forwarding service is the packet 786 * delivered to the destination end node must have the same NetBIOS 787 * header as if the source end node sent the packet directly to the 788 * destination end node. Consequently, the NBDD does not reassemble 789 * NetBIOS Datagrams. It forwards the UDP packet as is. 790 * 791 * PROCEDURE datagram_packet(packet) 792 * 793 * (* 794 * * processing initiated by a incoming datagram service 795 * * packet on a NBDD node. 796 * *) 797 * 798 * BEGIN 799 * CASE packet type OF 800 * 801 * DATAGRAM SERVICE: 802 * BEGIN 803 * IF packet was sent as a directed 804 * NetBIOS datagram THEN 805 * BEGIN 806 * (* 807 * * provide group forwarding service 808 * * 809 * * Forward datagram to each member of the 810 * * group. Can forward via: 811 * * 1) get list of group members and send 812 * * the DATAGRAM SERVICE packet unicast 813 * * to each 814 * * 2) use Group Multicast, if available 815 * * 3) combination of 1) and 2) 816 * *) 817 * 818 * ... 819 * 820 * END 821 * 822 * ELSE 823 * BEGIN 824 * (* 825 * * provide broadcast forwarding service 826 * * 827 * * Forward datagram to every node in the 828 * * NetBIOS scope. Can forward via: 829 * * 1) get list of group members and send 830 * * the DATAGRAM SERVICE packet unicast 831 * * to each 832 * * 2) use Group Multicast, if available 833 * * 3) combination of 1) and 2) 834 * *) 835 * 836 * ... 837 * 838 * END 839 * END (* datagram service *) 840 * 841 * DATAGRAM ERROR: 842 * BEGIN 843 * (* 844 * * Should never receive these because Datagrams 845 * * forwarded have source end node IP address and 846 * * port in NetBIOS header. 847 * *) 848 * 849 * send DELETE NAME REQUEST with incorrect name and 850 * IP address to NetBIOS Name Server; 851 * 852 * END (* datagram error *) 853 * 854 * DATAGRAM QUERY REQUEST: 855 * BEGIN 856 * IF can send packet to DESTINATION_NAME THEN 857 * BEGIN 858 * (* 859 * * NBDD is able to relay Datagrams for 860 * * this name 861 * *) 862 * 863 * send POSITIVE DATAGRAM QUERY RESPONSE to 864 * REQUEST source IP address and UDP port 865 * with requests DGM_ID; 866 * END 867 * ELSE 868 * BEGIN 869 * (* 870 * * NBDD is NOT able to relay Datagrams for 871 * * this name 872 * *) 873 * 874 * send NEGATIVE DATAGRAM QUERY RESPONSE to 875 * REQUEST source IP address and UDP port 876 * 877 * with requests DGM_ID; 878 * END 879 * END (* datagram query request *) 880 * 881 * END (* case *) 882 * END (* procedure *) 883 */ 884 885 886 /* 887 * Function: int smb_netbios_datagram_service_daemon(void) 888 * 889 * Description: 890 * 891 * 4.4. DATAGRAM SERVICE PACKETS 892 * 893 * 4.4.1. NetBIOS DATAGRAM HEADER 894 * 895 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 896 * 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 897 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 898 * | MSG_TYPE | FLAGS | DGM_ID | 899 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 900 * | SOURCE_IP | 901 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 902 * | SOURCE_PORT | DGM_LENGTH | 903 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 904 * | PACKET_OFFSET | 905 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 906 * 907 * MSG_TYPE values (in hexidecimal): 908 * 909 * 10 - DIRECT_UNIQUE DATAGRAM 910 * 11 - DIRECT_GROUP DATAGRAM 911 * 12 - BROADCAST DATAGRAM 912 * 13 - DATAGRAM ERROR 913 * 14 - DATAGRAM QUERY REQUEST 914 * 15 - DATAGRAM POSITIVE QUERY RESPONSE 915 * 16 - DATAGRAM NEGATIVE QUERY RESPONSE 916 * 917 * Bit definitions of the FLAGS field: 918 * 919 * 0 1 2 3 4 5 6 7 920 * +---+---+---+---+---+---+---+---+ 921 * | 0 | 0 | 0 | 0 | SNT | F | M | 922 * +---+---+---+---+---+---+---+---+ 923 * 924 * Symbol Bit(s) Description 925 * 926 * M 7 MORE flag, If set then more NetBIOS datagram 927 * fragments follow. 928 * 929 * F 6 FIRST packet flag, If set then this is first 930 * (and possibly only) fragment of NetBIOS 931 * datagram 932 * 933 * SNT 4,5 Source End-Node type: 934 * 00 = B node 935 * 01 = P node 936 * 10 = M node 937 * 11 = NBDD 938 * RESERVED 0-3 Reserved, must be zero (0) 939 * 940 * Inputs: 941 * Nothing 942 * 943 * Returns: 944 * int -> Description 945 */ 946 947 /*ARGSUSED*/ 948 void * 949 smb_netbios_datagram_service_daemon(void *arg) 950 { 951 struct sockaddr_in sin; 952 struct datagram *datagram; 953 int bytes, flag = 1; 954 955 (void) mutex_lock(&smb_dgq_mtx); 956 bzero(&smb_datagram_queue, sizeof (smb_datagram_queue)); 957 smb_datagram_queue.forw = smb_datagram_queue.back = 958 (struct datagram *)((uintptr_t)&smb_datagram_queue); 959 (void) mutex_unlock(&smb_dgq_mtx); 960 961 if ((datagram_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 962 syslog(LOG_ERR, 963 "smbd: Could not create AF_INET, SOCK_DGRAM, socket"); 964 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 965 return (0); 966 } 967 968 bzero(&sin, sizeof (sin)); 969 sin.sin_family = AF_INET; 970 sin.sin_port = htons(DGM_SRVC_UDP_PORT); 971 if (bind(datagram_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) { 972 syslog(LOG_ERR, "smbd: Bind to name service port %d failed", 973 DGM_SRVC_UDP_PORT); 974 (void) close(datagram_sock); 975 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 976 return (0); 977 } 978 (void) setsockopt(datagram_sock, SOL_SOCKET, SO_BROADCAST, &flag, 979 sizeof (flag)); 980 981 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 1); 982 983 while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) || 984 (nb_status.state & NETBIOS_BROWSER_RUNNING)) { 985 if ((datagram = (struct datagram *) 986 malloc(sizeof (struct datagram))) == 0) { 987 /* Sleep for 10 sec and try again */ 988 (void) sleep(10); 989 continue; 990 } 991 992 ignore: bzero(&datagram->inaddr, sizeof (struct addr_entry)); 993 datagram->inaddr.sinlen = sizeof (datagram->inaddr.sin); 994 datagram->inaddr.forw = datagram->inaddr.back = 995 &datagram->inaddr; 996 997 if ((bytes = recvfrom(datagram_sock, datagram->rawbuf, 998 MAX_DATAGRAM_LENGTH, 0, 999 (struct sockaddr *)&datagram->inaddr.sin, 1000 &datagram->inaddr.sinlen)) < 0) { 1001 syslog(LOG_ERR, 1002 "smbd: NETBIOS datagram - recvfrom failed"); 1003 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 1004 break; 1005 } 1006 1007 /* Ignore any incoming packets from myself... */ 1008 if (smb_nic_exists(datagram->inaddr.sin.sin_addr.s_addr, 1009 B_FALSE)) { 1010 goto ignore; 1011 } 1012 1013 if (smb_datagram_decode(datagram, bytes) < 0) 1014 goto ignore; 1015 1016 /* 1017 * This code was doing the wrong thing with responses from a 1018 * Windows2000 PDC because both DATAGRAM_FLAGS_H_NODE and 1019 * DATAGRAM_FLAGS_NBDD are defined to be the same value (see 1020 * netbios.h). Since the Windows2000 PDC wants to be an H-Node, 1021 * we need to handle all messages via smb_netbios_BPM_datagram. 1022 * 1023 * if ((datagram->flags & DATAGRAM_FLAGS_SRC_TYPE) == 1024 * DATAGRAM_FLAGS_NBDD) 1025 * smb_netbios_NBDD_datagram(datagram); 1026 * else 1027 * smb_netbios_BPM_datagram(datagram); 1028 */ 1029 1030 smb_netbios_BPM_datagram(datagram); 1031 } 1032 1033 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 0); 1034 1035 (void) mutex_lock(&nb_status.mtx); 1036 while (nb_status.state & NETBIOS_BROWSER_RUNNING) 1037 (void) cond_wait(&nb_status.cv, &nb_status.mtx); 1038 (void) mutex_unlock(&nb_status.mtx); 1039 1040 (void) close(datagram_sock); 1041 smb_netbios_datagram_fini(); 1042 syslog(LOG_DEBUG, "smbd: Netbios Datagram Service is down\n"); 1043 return (0); 1044 } 1045 1046 static char 1047 /* LINTED - E_STATIC_UNUSED */ 1048 nb_fmt_flags(unsigned char flags) 1049 { 1050 switch (flags & DATAGRAM_FLAGS_SRC_TYPE) { 1051 case DATAGRAM_FLAGS_B_NODE: return ('B'); 1052 case DATAGRAM_FLAGS_P_NODE: return ('P'); 1053 case DATAGRAM_FLAGS_M_NODE: return ('M'); 1054 case DATAGRAM_FLAGS_H_NODE: return ('H'); 1055 default: return ('?'); 1056 } 1057 } 1058