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 datagram service. 30 * 31 * Relavent sections from RFC1002: 32 * 33 * 5.3. NetBIOS DATAGRAM SERVICE PROTOCOLS 34 * 35 * The following are GLOBAL variables and should be NetBIOS user 36 * configurable: 37 * 38 * - SCOPE_ID: the non-leaf section of the domain name preceded by a 39 * '.' which represents the domain of the NetBIOS scope for the 40 * NetBIOS name. The following protocol description only supports 41 * single scope operation. 42 * 43 * - MAX_DATAGRAM_LENGTH: the maximum length of an IP datagram. The 44 * minimal maximum length defined in for IP is 576 bytes. This 45 * value is used when determining whether to fragment a NetBIOS 46 * datagram. Implementations are expected to be capable of 47 * receiving unfragmented NetBIOS datagrams up to their maximum 48 * size. 49 * 50 * - BROADCAST_ADDRESS: the IP address B-nodes use to send datagrams 51 * with group name destinations and broadcast datagrams. The 52 * default is the IP broadcast address for a single IP network. 53 * 54 * 55 * The following are Defined Constants for the NetBIOS Datagram 56 * Service: 57 * 58 * - DGM_SRVC_UDP_PORT: the globally well-known UDP port allocated 59 * where the NetBIOS Datagram Service receives UDP packets. See 60 * section 6, "Defined Constants", for its value. 61 */ 62 63 /* 64 * 65 * 6. DEFINED CONSTANTS AND VARIABLES 66 * 67 * GENERAL: 68 * 69 * SCOPE_ID The name of the NetBIOS scope. 70 * 71 * This is expressed as a character 72 * string meeting the requirements of 73 * the domain name system and without 74 * a leading or trailing "dot". 75 * 76 * An implementation may elect to make 77 * this a single global value for the 78 * node or allow it to be specified 79 * with each separate NetBIOS name 80 * (thus permitting cross-scope 81 * references.) 82 * 83 * BROADCAST_ADDRESS An IP address composed of the 84 * node network and subnetwork 85 * numbers with all remaining bits set 86 * to one. 87 * 88 * I.e. "Specific subnet" broadcast 89 * addressing according to section 2.3 90 * of RFC 950. 91 * 92 * BCAST_REQ_RETRY_TIMEOUT 250 milliseconds. 93 * An adaptive timer may be used. 94 * 95 * BCAST_REQ_RETRY_COUNT 3 96 * 97 * UCAST_REQ_RETRY_TIMEOUT 5 seconds 98 * An adaptive timer may be used. 99 * 100 * UCAST_REQ_RETRY_COUNT 3 101 * 102 * MAX_DATAGRAM_LENGTH 576 bytes (default) 103 * 104 * DATAGRAM SERVICE: 105 * 106 * DGM_SRVC_UDP_PORT 138 (decimal) 107 * 108 * FRAGMENT_TO 2 seconds (default) 109 */ 110 111 #include <stdlib.h> 112 #include <unistd.h> 113 #include <string.h> 114 #include <strings.h> 115 #include <syslog.h> 116 #include <synch.h> 117 #include <sys/socket.h> 118 #include <arpa/inet.h> 119 120 #include <smbns_netbios.h> 121 122 #include <smbsrv/libsmbns.h> 123 124 static int datagram_sock = -1; 125 static short datagram_id = 1; 126 static struct datagram_queue smb_datagram_queue; 127 static mutex_t smb_dgq_mtx; 128 129 /* 130 * Function: smb_netbios_datagram_tick(void) 131 * 132 * Description: 133 * 134 * Called once a second to handle time to live timeouts in 135 * datagram assembly queue. 136 * 137 * Inputs: 138 * 139 * Returns: 140 * void -> Nothing at all... 141 */ 142 143 void 144 smb_netbios_datagram_tick(void) 145 { 146 struct datagram *entry; 147 struct datagram *next; 148 149 (void) mutex_lock(&smb_dgq_mtx); 150 151 for (entry = smb_datagram_queue.forw; 152 entry != (struct datagram *)((uintptr_t)&smb_datagram_queue); 153 entry = next) { 154 next = entry->forw; 155 if (--entry->discard_timer == 0) { 156 /* Toss it */ 157 QUEUE_CLIP(entry); 158 free(entry); 159 } 160 } 161 (void) mutex_unlock(&smb_dgq_mtx); 162 } 163 164 void 165 smb_netbios_datagram_fini() 166 { 167 struct datagram *entry; 168 169 (void) mutex_lock(&smb_dgq_mtx); 170 while ((entry = smb_datagram_queue.forw) != 171 (struct datagram *)((uintptr_t)&smb_datagram_queue)) { 172 QUEUE_CLIP(entry); 173 free(entry); 174 } 175 (void) mutex_unlock(&smb_dgq_mtx); 176 } 177 178 /* 179 * Function: int smb_netbios_send_Bnode_datagram(unsigned char *data, 180 * struct name_entry *source, struct name_entry *destination, 181 * uint32_t broadcast) 182 * 183 * Description from rfc1002: 184 * 185 * 5.3.1. B NODE TRANSMISSION OF NetBIOS DATAGRAMS 186 * 187 * PROCEDURE send_datagram(data, source, destination, broadcast) 188 * 189 * (* 190 * * user initiated processing on B node 191 * *) 192 * 193 * BEGIN 194 * group = FALSE; 195 * 196 * do name discovery on destination name, returns name type and 197 * IP address; 198 * 199 * IF name type is group name THEN 200 * BEGIN 201 * group = TRUE; 202 * END 203 * 204 * (* 205 * * build datagram service UDP packet; 206 * *) 207 * convert source and destination NetBIOS names into 208 * half-ASCII, biased encoded name; 209 * SOURCE_NAME = cat(source, SCOPE_ID); 210 * SOURCE_IP = this nodes IP address; 211 * SOURCE_PORT = DGM_SRVC_UDP_PORT; 212 * 213 * IF NetBIOS broadcast THEN 214 * BEGIN 215 * DESTINATION_NAME = cat("*", SCOPE_ID) 216 * END 217 * ELSE 218 * BEGIN 219 * DESTINATION_NAME = cat(destination, SCOPE_ID) 220 * END 221 * 222 * MSG_TYPE = select_one_from_set 223 * {BROADCAST, DIRECT_UNIQUE, DIRECT_GROUP} 224 * DGM_ID = next transaction id for Datagrams; 225 * DGM_LENGTH = length of data + length of second level encoded 226 * source and destination names; 227 * 228 * IF (length of the NetBIOS Datagram, including UDP and 229 * IP headers, > MAX_DATAGRAM_LENGTH) THEN 230 * BEGIN 231 * (* 232 * * fragment NetBIOS datagram into 2 UDP packets 233 * *) 234 * Put names into 1st UDP packet and any data that fits 235 * after names; 236 * Set MORE and FIRST bits in 1st UDP packets FLAGS; 237 * OFFSET in 1st UDP = 0; 238 * 239 * Replicate NetBIOS Datagram header from 1st UDP packet 240 * into 2nd UDP packet; 241 * Put rest of data in 2nd UDP packet; 242 * Clear MORE and FIRST bits in 2nd UDP packets FLAGS; 243 * OFFSET in 2nd UDP = DGM_LENGTH - number of name and 244 * data bytes in 1st UDP; 245 * END 246 * BEGIN 247 * (* 248 * * Only need one UDP packet 249 * *) 250 * USER_DATA = data; 251 * Clear MORE bit and set FIRST bit in FLAGS; 252 * OFFSET = 0; 253 * END 254 * 255 * IF (group == TRUE) OR (NetBIOS broadcast) THEN 256 * BEGIN 257 * send UDP packet(s) to BROADCAST_ADDRESS; 258 * END 259 * ELSE 260 * BEGIN 261 * send UDP packet(s) to IP address returned by name 262 * discovery; 263 * END 264 * END (* procedure *) 265 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 266 * 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 267 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 268 * | MSG_TYPE | FLAGS | DGM_ID | 269 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 270 * | SOURCE_IP | 271 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 272 * | SOURCE_PORT | DGM_LENGTH | 273 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 274 * | PACKET_OFFSET | 275 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 276 * 277 * MSG_TYPE values (in hexidecimal): 278 * 279 * 10 - DIRECT_UNIQUE DATAGRAM 280 * 11 - DIRECT_GROUP DATAGRAM 281 * 12 - BROADCAST DATAGRAM 282 * 13 - DATAGRAM ERROR 283 * 14 - DATAGRAM QUERY REQUEST 284 * 15 - DATAGRAM POSITIVE QUERY RESPONSE 285 * 16 - DATAGRAM NEGATIVE QUERY RESPONSE 286 * 287 * Bit definitions of the FLAGS field: 288 * 289 * 0 1 2 3 4 5 6 7 290 * +---+---+---+---+---+---+---+---+ 291 * | 0 | 0 | 0 | 0 | SNT | F | M | 292 * +---+---+---+---+---+---+---+---+ 293 * 294 * Symbol Bit(s) Description 295 * 296 * M 7 MORE flag, If set then more NetBIOS datagram 297 * fragments follow. 298 * 299 * F 6 FIRST packet flag, If set then this is first 300 * (and possibly only) fragment of NetBIOS 301 * datagram 302 * 303 * SNT 4,5 Source End-Node type: 304 * 00 = B node 305 * 01 = P node 306 * 10 = M node 307 * 11 = NBDD 308 * RESERVED 0-3 Reserved, must be zero (0) 309 * (But MS sets bit 3 in this field) 310 * 311 */ 312 313 int 314 smb_netbios_datagram_send(struct name_entry *src, struct name_entry *dest, 315 unsigned char *data, int length) 316 { 317 smb_inaddr_t ipaddr; 318 size_t count, srclen, destlen, sinlen; 319 struct addr_entry *addr; 320 struct sockaddr_in sin; 321 char *buffer; 322 char ha_source[NETBIOS_DOMAIN_NAME_MAX]; 323 char ha_dest[NETBIOS_DOMAIN_NAME_MAX]; 324 325 (void) smb_first_level_name_encode(src, (unsigned char *)ha_source, 326 sizeof (ha_source)); 327 srclen = strlen(ha_source) + 1; 328 329 (void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest, 330 sizeof (ha_dest)); 331 destlen = strlen(ha_dest) + 1; 332 333 /* give some extra room */ 334 buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4); 335 if (buffer == 0) { 336 syslog(LOG_ERR, "netbios: datagram send (resource shortage)"); 337 return (-1); 338 } 339 340 buffer[0] = DATAGRAM_TYPE_DIRECT_UNIQUE; 341 switch (smb_node_type) { 342 case 'B': 343 buffer[1] = DATAGRAM_FLAGS_B_NODE | DATAGRAM_FLAGS_FIRST; 344 break; 345 case 'P': 346 buffer[1] = DATAGRAM_FLAGS_P_NODE | DATAGRAM_FLAGS_FIRST; 347 break; 348 case 'M': 349 buffer[1] = DATAGRAM_FLAGS_M_NODE | DATAGRAM_FLAGS_FIRST; 350 break; 351 case 'H': 352 default: 353 buffer[1] = DATAGRAM_FLAGS_H_NODE | DATAGRAM_FLAGS_FIRST; 354 break; 355 } 356 357 datagram_id++; 358 BE_OUT16(&buffer[2], datagram_id); 359 (void) memcpy(&buffer[4], &src->addr_list.sin.sin_addr.s_addr, 360 sizeof (uint32_t)); 361 (void) memcpy(&buffer[8], &src->addr_list.sin.sin_port, 362 sizeof (uint16_t)); 363 BE_OUT16(&buffer[10], length + srclen + destlen); 364 BE_OUT16(&buffer[12], 0); 365 366 bcopy(ha_source, &buffer[14], srclen); 367 bcopy(ha_dest, &buffer[14 + srclen], destlen); 368 bcopy(data, &buffer[14 + srclen + destlen], length); 369 count = &buffer[14 + srclen + destlen + length] - buffer; 370 371 bzero(&sin, sizeof (sin)); 372 sin.sin_family = AF_INET; 373 sinlen = sizeof (sin); 374 addr = &dest->addr_list; 375 do { 376 ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr; 377 ipaddr.a_family = AF_INET; 378 /* Don't send anything to myself... */ 379 if (smb_nic_is_local(&ipaddr)) 380 goto next; 381 382 sin.sin_addr.s_addr = ipaddr.a_ipv4; 383 sin.sin_port = addr->sin.sin_port; 384 (void) sendto(datagram_sock, buffer, count, 0, 385 (struct sockaddr *)&sin, sinlen); 386 387 next: addr = addr->forw; 388 } while (addr != &dest->addr_list); 389 free(buffer); 390 return (0); 391 } 392 393 394 int 395 smb_netbios_datagram_send_to_net(struct name_entry *src, 396 struct name_entry *dest, char *data, int length) 397 { 398 smb_inaddr_t ipaddr; 399 size_t count, srclen, destlen, sinlen; 400 struct addr_entry *addr; 401 struct sockaddr_in sin; 402 char *buffer; 403 char ha_source[NETBIOS_DOMAIN_NAME_MAX]; 404 char ha_dest[NETBIOS_DOMAIN_NAME_MAX]; 405 406 (void) smb_first_level_name_encode(src, (unsigned char *)ha_source, 407 sizeof (ha_source)); 408 srclen = strlen(ha_source) + 1; 409 410 (void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest, 411 sizeof (ha_dest)); 412 destlen = strlen(ha_dest) + 1; 413 414 /* give some extra room */ 415 buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4); 416 if (buffer == 0) { 417 syslog(LOG_ERR, "netbios: datagram send (resource shortage)"); 418 return (-1); 419 } 420 421 buffer[0] = DATAGRAM_TYPE_DIRECT_UNIQUE; 422 switch (smb_node_type) { 423 case 'B': 424 buffer[1] = DATAGRAM_FLAGS_B_NODE | DATAGRAM_FLAGS_FIRST; 425 break; 426 case 'P': 427 buffer[1] = DATAGRAM_FLAGS_P_NODE | DATAGRAM_FLAGS_FIRST; 428 break; 429 case 'M': 430 buffer[1] = DATAGRAM_FLAGS_M_NODE | DATAGRAM_FLAGS_FIRST; 431 break; 432 case 'H': 433 default: 434 buffer[1] = DATAGRAM_FLAGS_H_NODE | DATAGRAM_FLAGS_FIRST; 435 break; 436 } 437 438 datagram_id++; 439 BE_OUT16(&buffer[2], datagram_id); 440 (void) memcpy(&buffer[4], &src->addr_list.sin.sin_addr.s_addr, 441 sizeof (uint32_t)); 442 (void) memcpy(&buffer[8], &src->addr_list.sin.sin_port, 443 sizeof (uint16_t)); 444 BE_OUT16(&buffer[10], length + srclen + destlen); 445 BE_OUT16(&buffer[12], 0); 446 447 bcopy(ha_source, &buffer[14], srclen); 448 bcopy(ha_dest, &buffer[14 + srclen], destlen); 449 bcopy(data, &buffer[14 + srclen + destlen], length); 450 count = &buffer[14 + srclen + destlen + length] - buffer; 451 452 bzero(&sin, sizeof (sin)); 453 sin.sin_family = AF_INET; 454 sinlen = sizeof (sin); 455 addr = &dest->addr_list; 456 do { 457 ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr; 458 ipaddr.a_family = AF_INET; 459 if (smb_nic_is_local(&ipaddr)) 460 goto next; 461 462 sin.sin_addr.s_addr = ipaddr.a_ipv4; 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 smb_inaddr_t ipaddr; 955 956 (void) mutex_lock(&smb_dgq_mtx); 957 bzero(&smb_datagram_queue, sizeof (smb_datagram_queue)); 958 smb_datagram_queue.forw = smb_datagram_queue.back = 959 (struct datagram *)((uintptr_t)&smb_datagram_queue); 960 (void) mutex_unlock(&smb_dgq_mtx); 961 962 if ((datagram_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 963 syslog(LOG_ERR, 964 "smbd: Could not create AF_INET, SOCK_DGRAM, socket"); 965 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 966 return (0); 967 } 968 969 bzero(&sin, sizeof (sin)); 970 sin.sin_family = AF_INET; 971 sin.sin_port = htons(DGM_SRVC_UDP_PORT); 972 if (bind(datagram_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) { 973 syslog(LOG_ERR, "smbd: Bind to name service port %d failed", 974 DGM_SRVC_UDP_PORT); 975 (void) close(datagram_sock); 976 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 977 return (0); 978 } 979 (void) setsockopt(datagram_sock, SOL_SOCKET, SO_BROADCAST, &flag, 980 sizeof (flag)); 981 982 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 1); 983 984 while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) || 985 (nb_status.state & NETBIOS_BROWSER_RUNNING)) { 986 if ((datagram = (struct datagram *) 987 malloc(sizeof (struct datagram))) == 0) { 988 /* Sleep for 10 sec and try again */ 989 (void) sleep(10); 990 continue; 991 } 992 993 ignore: bzero(&datagram->inaddr, sizeof (struct addr_entry)); 994 datagram->inaddr.sinlen = sizeof (datagram->inaddr.sin); 995 datagram->inaddr.forw = datagram->inaddr.back = 996 &datagram->inaddr; 997 998 if ((bytes = recvfrom(datagram_sock, datagram->rawbuf, 999 MAX_DATAGRAM_LENGTH, 0, 1000 (struct sockaddr *)&datagram->inaddr.sin, 1001 &datagram->inaddr.sinlen)) < 0) { 1002 syslog(LOG_ERR, 1003 "smbd: NETBIOS datagram - recvfrom failed"); 1004 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1); 1005 break; 1006 } 1007 1008 /* Ignore any incoming packets from myself... */ 1009 ipaddr.a_ipv4 = datagram->inaddr.sin.sin_addr.s_addr; 1010 ipaddr.a_family = AF_INET; 1011 if (smb_nic_is_local(&ipaddr)) { 1012 goto ignore; 1013 } 1014 1015 if (smb_datagram_decode(datagram, bytes) < 0) 1016 goto ignore; 1017 1018 /* 1019 * This code was doing the wrong thing with responses from a 1020 * Windows2000 PDC because both DATAGRAM_FLAGS_H_NODE and 1021 * DATAGRAM_FLAGS_NBDD are defined to be the same value (see 1022 * netbios.h). Since the Windows2000 PDC wants to be an H-Node, 1023 * we need to handle all messages via smb_netbios_BPM_datagram. 1024 * 1025 * if ((datagram->flags & DATAGRAM_FLAGS_SRC_TYPE) == 1026 * DATAGRAM_FLAGS_NBDD) 1027 * smb_netbios_NBDD_datagram(datagram); 1028 * else 1029 * smb_netbios_BPM_datagram(datagram); 1030 */ 1031 1032 smb_netbios_BPM_datagram(datagram); 1033 } 1034 1035 smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 0); 1036 1037 (void) mutex_lock(&nb_status.mtx); 1038 while (nb_status.state & NETBIOS_BROWSER_RUNNING) 1039 (void) cond_wait(&nb_status.cv, &nb_status.mtx); 1040 (void) mutex_unlock(&nb_status.mtx); 1041 1042 (void) close(datagram_sock); 1043 smb_netbios_datagram_fini(); 1044 syslog(LOG_DEBUG, "smbd: Netbios Datagram Service is down\n"); 1045 return (0); 1046 } 1047 1048 static char 1049 /* LINTED - E_STATIC_UNUSED */ 1050 nb_fmt_flags(unsigned char flags) 1051 { 1052 switch (flags & DATAGRAM_FLAGS_SRC_TYPE) { 1053 case DATAGRAM_FLAGS_B_NODE: return ('B'); 1054 case DATAGRAM_FLAGS_P_NODE: return ('P'); 1055 case DATAGRAM_FLAGS_M_NODE: return ('M'); 1056 case DATAGRAM_FLAGS_H_NODE: return ('H'); 1057 default: return ('?'); 1058 } 1059 } 1060