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 2007 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 net_cfg_t cfg; 327 328 (void) smb_first_level_name_encode(src, (unsigned char *)ha_source, 329 sizeof (ha_source)); 330 srclen = strlen(ha_source) + 1; 331 332 (void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest, 333 sizeof (ha_dest)); 334 destlen = strlen(ha_dest) + 1; 335 336 /* give some extra room */ 337 buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4); 338 if (buffer == 0) { 339 syslog(LOG_ERR, "netbios: datagram send (resource shortage)"); 340 return (-1); 341 } 342 343 buffer[0] = DATAGRAM_TYPE_DIRECT_UNIQUE; 344 switch (smb_node_type) { 345 case 'B': 346 buffer[1] = DATAGRAM_FLAGS_B_NODE | DATAGRAM_FLAGS_FIRST; 347 break; 348 case 'P': 349 buffer[1] = DATAGRAM_FLAGS_P_NODE | DATAGRAM_FLAGS_FIRST; 350 break; 351 case 'M': 352 buffer[1] = DATAGRAM_FLAGS_M_NODE | DATAGRAM_FLAGS_FIRST; 353 break; 354 case 'H': 355 default: 356 buffer[1] = DATAGRAM_FLAGS_H_NODE | DATAGRAM_FLAGS_FIRST; 357 break; 358 } 359 360 datagram_id++; 361 BE_OUT16(&buffer[2], datagram_id); 362 (void) memcpy(&buffer[4], &src->addr_list.sin.sin_addr.s_addr, 363 sizeof (uint32_t)); 364 (void) memcpy(&buffer[8], &src->addr_list.sin.sin_port, 365 sizeof (uint16_t)); 366 BE_OUT16(&buffer[10], length + srclen + destlen); 367 BE_OUT16(&buffer[12], 0); 368 369 bcopy(ha_source, &buffer[14], srclen); 370 bcopy(ha_dest, &buffer[14 + srclen], destlen); 371 bcopy(data, &buffer[14 + srclen + destlen], length); 372 count = &buffer[14 + srclen + destlen + length] - buffer; 373 374 bzero(&sin, sizeof (sin)); 375 sin.sin_family = AF_INET; 376 sinlen = sizeof (sin); 377 addr = &dest->addr_list; 378 do { 379 ipaddr = addr->sin.sin_addr.s_addr; 380 /* Don't send anything to myself... */ 381 if (smb_nic_get_byip(ipaddr, &cfg) != NULL) { 382 goto next; 383 } 384 385 sin.sin_addr.s_addr = ipaddr; 386 sin.sin_port = addr->sin.sin_port; 387 (void) sendto(datagram_sock, buffer, count, 0, 388 (struct sockaddr *)&sin, sinlen); 389 390 next: addr = addr->forw; 391 } while (addr != &dest->addr_list); 392 free(buffer); 393 return (0); 394 } 395 396 397 int 398 smb_netbios_datagram_send_to_net(struct name_entry *src, 399 struct name_entry *dest, char *data, int length) 400 { 401 uint32_t ipaddr; 402 size_t count, srclen, destlen, sinlen; 403 struct addr_entry *addr; 404 struct sockaddr_in sin; 405 char *buffer; 406 char ha_source[NETBIOS_DOMAIN_NAME_MAX]; 407 char ha_dest[NETBIOS_DOMAIN_NAME_MAX]; 408 net_cfg_t cfg; 409 410 (void) smb_first_level_name_encode(src, (unsigned char *)ha_source, 411 sizeof (ha_source)); 412 srclen = strlen(ha_source) + 1; 413 414 (void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest, 415 sizeof (ha_dest)); 416 destlen = strlen(ha_dest) + 1; 417 418 /* give some extra room */ 419 buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4); 420 if (buffer == 0) { 421 syslog(LOG_ERR, "netbios: datagram send (resource shortage)"); 422 return (-1); 423 } 424 425 buffer[0] = DATAGRAM_TYPE_DIRECT_UNIQUE; 426 switch (smb_node_type) { 427 case 'B': 428 buffer[1] = DATAGRAM_FLAGS_B_NODE | DATAGRAM_FLAGS_FIRST; 429 break; 430 case 'P': 431 buffer[1] = DATAGRAM_FLAGS_P_NODE | DATAGRAM_FLAGS_FIRST; 432 break; 433 case 'M': 434 buffer[1] = DATAGRAM_FLAGS_M_NODE | DATAGRAM_FLAGS_FIRST; 435 break; 436 case 'H': 437 default: 438 buffer[1] = DATAGRAM_FLAGS_H_NODE | DATAGRAM_FLAGS_FIRST; 439 break; 440 } 441 442 datagram_id++; 443 BE_OUT16(&buffer[2], datagram_id); 444 (void) memcpy(&buffer[4], &src->addr_list.sin.sin_addr.s_addr, 445 sizeof (uint32_t)); 446 (void) memcpy(&buffer[8], &src->addr_list.sin.sin_port, 447 sizeof (uint16_t)); 448 BE_OUT16(&buffer[10], length + srclen + destlen); 449 BE_OUT16(&buffer[12], 0); 450 451 bcopy(ha_source, &buffer[14], srclen); 452 bcopy(ha_dest, &buffer[14 + srclen], destlen); 453 bcopy(data, &buffer[14 + srclen + destlen], length); 454 count = &buffer[14 + srclen + destlen + length] - buffer; 455 456 bzero(&sin, sizeof (sin)); 457 sin.sin_family = AF_INET; 458 sinlen = sizeof (sin); 459 addr = &dest->addr_list; 460 do { 461 ipaddr = addr->sin.sin_addr.s_addr; 462 if (smb_nic_get_byip(ipaddr, &cfg) != NULL) { 463 goto next; 464 } 465 sin.sin_addr.s_addr = ipaddr; 466 sin.sin_port = addr->sin.sin_port; 467 (void) sendto(datagram_sock, buffer, count, 0, 468 (struct sockaddr *)&sin, sinlen); 469 470 next: addr = addr->forw; 471 } while (addr != &dest->addr_list); 472 free(buffer); 473 return (0); 474 } 475 476 477 int 478 smb_datagram_decode(struct datagram *datagram, int bytes) 479 { 480 unsigned char *ha_src; 481 unsigned char *ha_dest; 482 unsigned char *data; 483 484 if (bytes < DATAGRAM_HEADER_LENGTH) { 485 syslog(LOG_ERR, "NbtDatagramDecode[%d]: too small packet", 486 bytes); 487 return (-1); 488 } 489 490 ha_src = &datagram->rawbuf[DATAGRAM_HEADER_LENGTH]; 491 ha_dest = ha_src + strlen((char *)ha_src) + 1; 492 data = ha_dest + strlen((char *)ha_dest) + 1; 493 494 bzero(&datagram->src, sizeof (struct name_entry)); 495 bzero(&datagram->dest, sizeof (struct name_entry)); 496 497 datagram->rawbytes = bytes; 498 datagram->packet_type = datagram->rawbuf[0]; 499 datagram->flags = datagram->rawbuf[1]; 500 datagram->datagram_id = BE_IN16(&datagram->rawbuf[2]); 501 502 datagram->src.addr_list.sinlen = sizeof (struct sockaddr_in); 503 (void) memcpy(&datagram->src.addr_list.sin.sin_addr.s_addr, 504 &datagram->rawbuf[4], sizeof (uint32_t)); 505 (void) memcpy(&datagram->src.addr_list.sin.sin_port, 506 &datagram->rawbuf[8], sizeof (uint16_t)); 507 datagram->src.addr_list.forw = datagram->src.addr_list.back = 508 &datagram->src.addr_list; 509 510 datagram->data = data; 511 datagram->data_length = BE_IN16(&datagram->rawbuf[10]); 512 datagram->offset = BE_IN16(&datagram->rawbuf[12]); 513 514 if (smb_first_level_name_decode(ha_src, &datagram->src) < 0) { 515 syslog(LOG_DEBUG, "NbtDatagram[%s]: invalid calling name", 516 inet_ntoa(datagram->src.addr_list.sin.sin_addr)); 517 syslog(LOG_DEBUG, "Calling name: <%02X>%32.32s", 518 ha_src[0], &ha_src[1]); 519 } 520 521 datagram->dest.addr_list.forw = datagram->dest.addr_list.back = 522 &datagram->dest.addr_list; 523 524 if (smb_first_level_name_decode(ha_dest, &datagram->dest) < 0) { 525 syslog(LOG_DEBUG, "NbtDatagram[%s]: invalid called name", 526 inet_ntoa(datagram->src.addr_list.sin.sin_addr)); 527 syslog(LOG_DEBUG, "Called name: <%02X>%32.32s", ha_dest[0], 528 &ha_dest[1]); 529 } 530 531 return (0); 532 } 533 534 535 /* 536 * Function: int smb_netbios_process_BPM_datagram(unsigned char *packet, 537 * struct addr_entry *addr) 538 * 539 * Description from rfc1002: 540 * 541 * 5.3.3. RECEPTION OF NetBIOS DATAGRAMS BY ALL NODES 542 * 543 * The following algorithm discards out of order NetBIOS Datagram 544 * fragments. An implementation which reassembles out of order 545 * NetBIOS Datagram fragments conforms to this specification. The 546 * fragment discard timer is initialized to the value FRAGMENT_TIMEOUT. 547 * This value should be user configurable. The default value is 548 * given in Section 6, "Defined Constants and Variables". 549 * 550 * PROCEDURE datagram_packet(packet) 551 * 552 * (* 553 * * processing initiated by datagram packet reception 554 * * on B, P and M nodes 555 * *) 556 * BEGIN 557 * (* 558 * * if this node is a P node, ignore 559 * * broadcast packets. 560 * *) 561 * 562 * IF this is a P node AND incoming packet is 563 * a broadcast packet THEN 564 * BEGIN 565 * discard packet; 566 * END 567 * 568 * CASE packet type OF 569 * 570 * DATAGRAM SERVICE: 571 * BEGIN 572 * IF FIRST bit in FLAGS is set THEN 573 * BEGIN 574 * IF MORE bit in FLAGS is set THEN 575 * BEGIN 576 * Save 1st UDP packet of the Datagram; 577 * Set this Datagrams fragment discard 578 * timer to FRAGMENT_TIMEOUT; 579 * return; 580 * END 581 * ELSE 582 * Datagram is composed of a single 583 * UDP packet; 584 * END 585 * ELSE 586 * BEGIN 587 * (* Have the second fragment of a Datagram *) 588 * 589 * Search for 1st fragment by source IP address 590 * and DGM_ID; 591 * IF found 1st fragment THEN 592 * Process both UDP packets; 593 * ELSE 594 * BEGIN 595 * discard 2nd fragment UDP packet; 596 * return; 597 * END 598 * END 599 * 600 * IF DESTINATION_NAME is '*' THEN 601 * BEGIN 602 * (* NetBIOS broadcast *) 603 * 604 * deliver USER_DATA from UDP packet(s) to all 605 * outstanding receive broadcast 606 * datagram requests; 607 * return; 608 * END 609 * ELSE 610 * BEGIN (* non-broadcast *) 611 * (* Datagram for Unique or Group Name *) 612 * 613 * IF DESTINATION_NAME is not present in the 614 * local name table THEN 615 * BEGIN 616 * (* destination not present *) 617 * build DATAGRAM ERROR packet, clear 618 * FIRST and MORE bit, put in 619 * this nodes IP and PORT, set 620 * ERROR_CODE; 621 * send DATAGRAM ERROR packet to 622 * source IP address and port 623 * of UDP; 624 * discard UDP packet(s); 625 * return; 626 * END 627 * ELSE 628 * BEGIN (* good *) 629 * (* 630 * * Replicate received NetBIOS datagram for 631 * * each recipient 632 * *) 633 * FOR EACH pending NetBIOS users receive 634 * datagram operation 635 * BEGIN 636 * IF source name of operation 637 * matches destination name 638 * of packet THEN 639 * BEGIN 640 * deliver USER_DATA from UDP 641 * packet(s); 642 * END 643 * END (* for each *) 644 * return; 645 * END (* good *) 646 * END (* non-broadcast *) 647 * END (* datagram service *) 648 * 649 * DATAGRAM ERROR: 650 * BEGIN 651 * (* 652 * * name service returned incorrect information 653 * *) 654 * 655 * inform local name service that incorrect 656 * information was provided; 657 * 658 * IF this is a P or M node THEN 659 * BEGIN 660 * (* 661 * * tell NetBIOS Name Server that it may 662 * * have given incorrect information 663 * *) 664 * 665 * send NAME RELEASE REQUEST with name 666 * and incorrect IP address to NetBIOS 667 * Name Server; 668 * END 669 * END (* datagram error *) 670 * 671 * END (* case *) 672 * END 673 */ 674 675 static struct datagram * 676 smb_netbios_datagram_getq(struct datagram *datagram) 677 { 678 struct datagram *prev = 0; 679 680 (void) mutex_lock(&smb_dgq_mtx); 681 for (prev = smb_datagram_queue.forw; 682 prev != (struct datagram *)((uintptr_t)&smb_datagram_queue); 683 prev = prev->forw) { 684 if (prev->src.addr_list.sin.sin_addr.s_addr == 685 datagram->src.addr_list.sin.sin_addr.s_addr) { 686 /* Something waiting */ 687 QUEUE_CLIP(prev); 688 (void) mutex_unlock(&smb_dgq_mtx); 689 bcopy(datagram->data, &prev->data[prev->data_length], 690 datagram->data_length); 691 prev->data_length += datagram->data_length; 692 free(datagram); 693 return (prev); 694 } 695 } 696 (void) mutex_unlock(&smb_dgq_mtx); 697 698 return (0); 699 } 700 701 static void 702 smb_netbios_BPM_datagram(struct datagram *datagram) 703 { 704 struct name_entry *entry = 0; 705 struct datagram *qpacket = 0; 706 pthread_t browser_dispatch; 707 708 switch (datagram->packet_type) { 709 case DATAGRAM_TYPE_BROADCAST : 710 if (smb_node_type == 'P') { 711 /* 712 * if this node is a P node, ignore 713 * broadcast packets. 714 */ 715 break; 716 } 717 /* FALLTHROUGH */ 718 719 case DATAGRAM_TYPE_DIRECT_UNIQUE : 720 case DATAGRAM_TYPE_DIRECT_GROUP : 721 if ((datagram->flags & DATAGRAM_FLAGS_FIRST) != 0) { 722 if (datagram->flags & DATAGRAM_FLAGS_MORE) { 723 /* Save 1st UDP packet of the Datagram */ 724 datagram->discard_timer = FRAGMENT_TIMEOUT; 725 (void) mutex_lock(&smb_dgq_mtx); 726 QUEUE_INSERT_TAIL(&smb_datagram_queue, datagram) 727 (void) mutex_unlock(&smb_dgq_mtx); 728 return; 729 } 730 /* process datagram */ 731 } else { 732 qpacket = smb_netbios_datagram_getq(datagram); 733 if (qpacket) { 734 datagram = qpacket; 735 goto process_datagram; 736 } 737 break; 738 } 739 740 process_datagram: 741 entry = 0; 742 if ((strcmp((char *)datagram->dest.name, "*") == 0) || 743 ((entry = 744 smb_netbios_cache_lookup(&datagram->dest)) != 0)) { 745 if (entry) { 746 int is_local = IS_LOCAL(entry->attributes); 747 smb_netbios_cache_unlock_entry(entry); 748 749 if (is_local) { 750 (void) pthread_create(&browser_dispatch, 751 0, smb_browser_dispatch, 752 (void *)datagram); 753 (void) pthread_detach(browser_dispatch); 754 return; 755 } 756 } 757 758 datagram->rawbuf[0] = DATAGRAM_TYPE_ERROR_DATAGRAM; 759 datagram->rawbuf[1] &= DATAGRAM_FLAGS_SRC_TYPE; 760 761 (void) memcpy(&datagram->rawbuf[4], 762 &datagram->src.addr_list.sin.sin_addr.s_addr, 763 sizeof (uint32_t)); 764 BE_OUT16(&datagram->rawbuf[8], DGM_SRVC_UDP_PORT); 765 766 (void) sendto(datagram_sock, datagram->rawbuf, 767 datagram->rawbytes, 0, 768 (struct sockaddr *)&datagram->src.addr_list.sin, 769 datagram->src.addr_list.sinlen); 770 } 771 break; 772 773 case DATAGRAM_TYPE_ERROR_DATAGRAM : 774 break; 775 } 776 free(datagram); 777 } 778 779 780 /* 781 * smb_netbios_process_NBDD_datagram 782 * 783 * Description from rfc1002: 784 * 785 * 786 * 5.3.4. PROTOCOLS FOR THE NBDD 787 * 788 * The key to NetBIOS Datagram forwarding service is the packet 789 * delivered to the destination end node must have the same NetBIOS 790 * header as if the source end node sent the packet directly to the 791 * destination end node. Consequently, the NBDD does not reassemble 792 * NetBIOS Datagrams. It forwards the UDP packet as is. 793 * 794 * PROCEDURE datagram_packet(packet) 795 * 796 * (* 797 * * processing initiated by a incoming datagram service 798 * * packet on a NBDD node. 799 * *) 800 * 801 * BEGIN 802 * CASE packet type OF 803 * 804 * DATAGRAM SERVICE: 805 * BEGIN 806 * IF packet was sent as a directed 807 * NetBIOS datagram THEN 808 * BEGIN 809 * (* 810 * * provide group forwarding service 811 * * 812 * * Forward datagram to each member of the 813 * * group. Can forward via: 814 * * 1) get list of group members and send 815 * * the DATAGRAM SERVICE packet unicast 816 * * to each 817 * * 2) use Group Multicast, if available 818 * * 3) combination of 1) and 2) 819 * *) 820 * 821 * ... 822 * 823 * END 824 * 825 * ELSE 826 * BEGIN 827 * (* 828 * * provide broadcast forwarding service 829 * * 830 * * Forward datagram to every node in the 831 * * NetBIOS scope. Can forward via: 832 * * 1) get list of group members and send 833 * * the DATAGRAM SERVICE packet unicast 834 * * to each 835 * * 2) use Group Multicast, if available 836 * * 3) combination of 1) and 2) 837 * *) 838 * 839 * ... 840 * 841 * END 842 * END (* datagram service *) 843 * 844 * DATAGRAM ERROR: 845 * BEGIN 846 * (* 847 * * Should never receive these because Datagrams 848 * * forwarded have source end node IP address and 849 * * port in NetBIOS header. 850 * *) 851 * 852 * send DELETE NAME REQUEST with incorrect name and 853 * IP address to NetBIOS Name Server; 854 * 855 * END (* datagram error *) 856 * 857 * DATAGRAM QUERY REQUEST: 858 * BEGIN 859 * IF can send packet to DESTINATION_NAME THEN 860 * BEGIN 861 * (* 862 * * NBDD is able to relay Datagrams for 863 * * this name 864 * *) 865 * 866 * send POSITIVE DATAGRAM QUERY RESPONSE to 867 * REQUEST source IP address and UDP port 868 * with requests DGM_ID; 869 * END 870 * ELSE 871 * BEGIN 872 * (* 873 * * NBDD is NOT able to relay Datagrams for 874 * * this name 875 * *) 876 * 877 * send NEGATIVE DATAGRAM QUERY RESPONSE to 878 * REQUEST source IP address and UDP port 879 * 880 * with requests DGM_ID; 881 * END 882 * END (* datagram query request *) 883 * 884 * END (* case *) 885 * END (* procedure *) 886 */ 887 888 889 /* 890 * Function: int smb_netbios_datagram_service_daemon(void) 891 * 892 * Description: 893 * 894 * 4.4. DATAGRAM SERVICE PACKETS 895 * 896 * 4.4.1. NetBIOS DATAGRAM HEADER 897 * 898 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 899 * 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 900 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 901 * | MSG_TYPE | FLAGS | DGM_ID | 902 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 903 * | SOURCE_IP | 904 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 905 * | SOURCE_PORT | DGM_LENGTH | 906 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 907 * | PACKET_OFFSET | 908 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 909 * 910 * MSG_TYPE values (in hexidecimal): 911 * 912 * 10 - DIRECT_UNIQUE DATAGRAM 913 * 11 - DIRECT_GROUP DATAGRAM 914 * 12 - BROADCAST DATAGRAM 915 * 13 - DATAGRAM ERROR 916 * 14 - DATAGRAM QUERY REQUEST 917 * 15 - DATAGRAM POSITIVE QUERY RESPONSE 918 * 16 - DATAGRAM NEGATIVE QUERY RESPONSE 919 * 920 * Bit definitions of the FLAGS field: 921 * 922 * 0 1 2 3 4 5 6 7 923 * +---+---+---+---+---+---+---+---+ 924 * | 0 | 0 | 0 | 0 | SNT | F | M | 925 * +---+---+---+---+---+---+---+---+ 926 * 927 * Symbol Bit(s) Description 928 * 929 * M 7 MORE flag, If set then more NetBIOS datagram 930 * fragments follow. 931 * 932 * F 6 FIRST packet flag, If set then this is first 933 * (and possibly only) fragment of NetBIOS 934 * datagram 935 * 936 * SNT 4,5 Source End-Node type: 937 * 00 = B node 938 * 01 = P node 939 * 10 = M node 940 * 11 = NBDD 941 * RESERVED 0-3 Reserved, must be zero (0) 942 * 943 * Inputs: 944 * Nothing 945 * 946 * Returns: 947 * int -> Description 948 */ 949 950 /*ARGSUSED*/ 951 void * 952 smb_netbios_datagram_service_daemon(void *arg) 953 { 954 struct sockaddr_in sin; 955 struct datagram *datagram; 956 int bytes, flag = 1; 957 net_cfg_t cfg; 958 959 (void) mutex_lock(&smb_dgq_mtx); 960 bzero(&smb_datagram_queue, sizeof (smb_datagram_queue)); 961 smb_datagram_queue.forw = smb_datagram_queue.back = 962 (struct datagram *)((uintptr_t)&smb_datagram_queue); 963 (void) mutex_unlock(&smb_dgq_mtx); 964 965 if ((datagram_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 966 syslog(LOG_ERR, 967 "smbd: Could not create AF_INET, SOCK_DGRAM, socket"); 968 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 969 return (0); 970 } 971 972 bzero(&sin, sizeof (sin)); 973 sin.sin_family = AF_INET; 974 sin.sin_port = htons(DGM_SRVC_UDP_PORT); 975 if (bind(datagram_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) { 976 syslog(LOG_ERR, "smbd: Bind to name service port %d failed", 977 DGM_SRVC_UDP_PORT); 978 (void) close(datagram_sock); 979 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 980 return (0); 981 } 982 (void) setsockopt(datagram_sock, SOL_SOCKET, SO_BROADCAST, &flag, 983 sizeof (flag)); 984 985 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 1); 986 987 while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) || 988 (nb_status.state & NETBIOS_BROWSER_RUNNING)) { 989 if ((datagram = (struct datagram *) 990 malloc(sizeof (struct datagram))) == 0) { 991 /* Sleep for 10 sec and try again */ 992 (void) sleep(10); 993 continue; 994 } 995 996 ignore: bzero(&datagram->inaddr, sizeof (struct addr_entry)); 997 datagram->inaddr.sinlen = sizeof (datagram->inaddr.sin); 998 datagram->inaddr.forw = datagram->inaddr.back = 999 &datagram->inaddr; 1000 1001 if ((bytes = recvfrom(datagram_sock, datagram->rawbuf, 1002 MAX_DATAGRAM_LENGTH, 0, 1003 (struct sockaddr *)&datagram->inaddr.sin, 1004 &datagram->inaddr.sinlen)) < 0) { 1005 syslog(LOG_ERR, 1006 "smbd: NETBIOS datagram - recvfrom failed"); 1007 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 1008 break; 1009 } 1010 1011 /* Ignore any incoming packets from myself... */ 1012 if (smb_nic_get_byip( 1013 datagram->inaddr.sin.sin_addr.s_addr, 1014 &cfg) != NULL) { 1015 goto ignore; 1016 } 1017 if (smb_datagram_decode(datagram, bytes) < 0) 1018 goto ignore; 1019 1020 /* 1021 * This code was doing the wrong thing with responses from a 1022 * Windows2000 PDC because both DATAGRAM_FLAGS_H_NODE and 1023 * DATAGRAM_FLAGS_NBDD are defined to be the same value (see 1024 * netbios.h). Since the Windows2000 PDC wants to be an H-Node, 1025 * we need to handle all messages via smb_netbios_BPM_datagram. 1026 * 1027 * if ((datagram->flags & DATAGRAM_FLAGS_SRC_TYPE) == 1028 * DATAGRAM_FLAGS_NBDD) 1029 * smb_netbios_NBDD_datagram(datagram); 1030 * else 1031 * smb_netbios_BPM_datagram(datagram); 1032 */ 1033 1034 smb_netbios_BPM_datagram(datagram); 1035 } 1036 1037 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 0); 1038 1039 (void) mutex_lock(&nb_status.mtx); 1040 while (nb_status.state & NETBIOS_BROWSER_RUNNING) 1041 (void) cond_wait(&nb_status.cv, &nb_status.mtx); 1042 (void) mutex_unlock(&nb_status.mtx); 1043 1044 (void) close(datagram_sock); 1045 smb_netbios_datagram_fini(); 1046 syslog(LOG_DEBUG, "smbd: Netbios Datagram Service is down\n"); 1047 return (0); 1048 } 1049 1050 static char 1051 /* LINTED - E_STATIC_UNUSED */ 1052 nb_fmt_flags(unsigned char flags) 1053 { 1054 switch (flags & DATAGRAM_FLAGS_SRC_TYPE) { 1055 case DATAGRAM_FLAGS_B_NODE: return ('B'); 1056 case DATAGRAM_FLAGS_P_NODE: return ('P'); 1057 case DATAGRAM_FLAGS_M_NODE: return ('M'); 1058 case DATAGRAM_FLAGS_H_NODE: return ('H'); 1059 default: return ('?'); 1060 } 1061 } 1062