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