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 * - IPPORT_NETBIOS_DGM: 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 * IPPORT_NETBIOS_DGM 138 (decimal) 107 * 108 * FRAGMENT_TO 2 seconds (default) 109 */ 110 111 #include <errno.h> 112 #include <stdlib.h> 113 #include <unistd.h> 114 #include <string.h> 115 #include <strings.h> 116 #include <syslog.h> 117 #include <synch.h> 118 #include <sys/socket.h> 119 #include <arpa/inet.h> 120 121 #include <smbns_netbios.h> 122 123 #include <smbsrv/libsmbns.h> 124 125 static int datagram_sock = -1; 126 static short datagram_id = 1; 127 static struct datagram_queue smb_datagram_queue; 128 static mutex_t smb_dgq_mtx; 129 130 static void smb_netbios_datagram_error(unsigned char *buf); 131 132 /* 133 * Function: smb_netbios_datagram_tick(void) 134 * 135 * Description: 136 * 137 * Called once a second to handle time to live timeouts in 138 * datagram assembly queue. 139 * 140 * Inputs: 141 * 142 * Returns: 143 * void -> Nothing at all... 144 */ 145 146 void 147 smb_netbios_datagram_tick(void) 148 { 149 struct datagram *entry; 150 struct datagram *next; 151 152 (void) mutex_lock(&smb_dgq_mtx); 153 154 for (entry = smb_datagram_queue.forw; 155 entry != (struct datagram *)((uintptr_t)&smb_datagram_queue); 156 entry = next) { 157 next = entry->forw; 158 if (--entry->discard_timer == 0) { 159 /* Toss it */ 160 QUEUE_CLIP(entry); 161 free(entry); 162 } 163 } 164 (void) mutex_unlock(&smb_dgq_mtx); 165 } 166 167 void 168 smb_netbios_datagram_fini() 169 { 170 struct datagram *entry; 171 172 (void) mutex_lock(&smb_dgq_mtx); 173 while ((entry = smb_datagram_queue.forw) != 174 (struct datagram *)((uintptr_t)&smb_datagram_queue)) { 175 QUEUE_CLIP(entry); 176 free(entry); 177 } 178 (void) mutex_unlock(&smb_dgq_mtx); 179 } 180 181 /* 182 * Function: int smb_netbios_send_Bnode_datagram(unsigned char *data, 183 * struct name_entry *source, struct name_entry *destination, 184 * uint32_t broadcast) 185 * 186 * Description from rfc1002: 187 * 188 * 5.3.1. B NODE TRANSMISSION OF NetBIOS DATAGRAMS 189 * 190 * PROCEDURE send_datagram(data, source, destination, broadcast) 191 * 192 * (* 193 * * user initiated processing on B node 194 * *) 195 * 196 * BEGIN 197 * group = FALSE; 198 * 199 * do name discovery on destination name, returns name type and 200 * IP address; 201 * 202 * IF name type is group name THEN 203 * BEGIN 204 * group = TRUE; 205 * END 206 * 207 * (* 208 * * build datagram service UDP packet; 209 * *) 210 * convert source and destination NetBIOS names into 211 * half-ASCII, biased encoded name; 212 * SOURCE_NAME = cat(source, SCOPE_ID); 213 * SOURCE_IP = this nodes IP address; 214 * SOURCE_PORT = IPPORT_NETBIOS_DGM; 215 * 216 * IF NetBIOS broadcast THEN 217 * BEGIN 218 * DESTINATION_NAME = cat("*", SCOPE_ID) 219 * END 220 * ELSE 221 * BEGIN 222 * DESTINATION_NAME = cat(destination, SCOPE_ID) 223 * END 224 * 225 * MSG_TYPE = select_one_from_set 226 * {BROADCAST, DIRECT_UNIQUE, DIRECT_GROUP} 227 * DGM_ID = next transaction id for Datagrams; 228 * DGM_LENGTH = length of data + length of second level encoded 229 * source and destination names; 230 * 231 * IF (length of the NetBIOS Datagram, including UDP and 232 * IP headers, > MAX_DATAGRAM_LENGTH) THEN 233 * BEGIN 234 * (* 235 * * fragment NetBIOS datagram into 2 UDP packets 236 * *) 237 * Put names into 1st UDP packet and any data that fits 238 * after names; 239 * Set MORE and FIRST bits in 1st UDP packets FLAGS; 240 * OFFSET in 1st UDP = 0; 241 * 242 * Replicate NetBIOS Datagram header from 1st UDP packet 243 * into 2nd UDP packet; 244 * Put rest of data in 2nd UDP packet; 245 * Clear MORE and FIRST bits in 2nd UDP packets FLAGS; 246 * OFFSET in 2nd UDP = DGM_LENGTH - number of name and 247 * data bytes in 1st UDP; 248 * END 249 * BEGIN 250 * (* 251 * * Only need one UDP packet 252 * *) 253 * USER_DATA = data; 254 * Clear MORE bit and set FIRST bit in FLAGS; 255 * OFFSET = 0; 256 * END 257 * 258 * IF (group == TRUE) OR (NetBIOS broadcast) THEN 259 * BEGIN 260 * send UDP packet(s) to BROADCAST_ADDRESS; 261 * END 262 * ELSE 263 * BEGIN 264 * send UDP packet(s) to IP address returned by name 265 * discovery; 266 * END 267 * END (* procedure *) 268 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 269 * 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 270 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 271 * | MSG_TYPE | FLAGS | DGM_ID | 272 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 273 * | SOURCE_IP | 274 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 275 * | SOURCE_PORT | DGM_LENGTH | 276 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 277 * | PACKET_OFFSET | 278 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 279 * 280 * MSG_TYPE values (in hexidecimal): 281 * 282 * 10 - DIRECT_UNIQUE DATAGRAM 283 * 11 - DIRECT_GROUP DATAGRAM 284 * 12 - BROADCAST DATAGRAM 285 * 13 - DATAGRAM ERROR 286 * 14 - DATAGRAM QUERY REQUEST 287 * 15 - DATAGRAM POSITIVE QUERY RESPONSE 288 * 16 - DATAGRAM NEGATIVE QUERY RESPONSE 289 * 290 * Bit definitions of the FLAGS field: 291 * 292 * 0 1 2 3 4 5 6 7 293 * +---+---+---+---+---+---+---+---+ 294 * | 0 | 0 | 0 | 0 | SNT | F | M | 295 * +---+---+---+---+---+---+---+---+ 296 * 297 * Symbol Bit(s) Description 298 * 299 * M 7 MORE flag, If set then more NetBIOS datagram 300 * fragments follow. 301 * 302 * F 6 FIRST packet flag, If set then this is first 303 * (and possibly only) fragment of NetBIOS 304 * datagram 305 * 306 * SNT 4,5 Source End-Node type: 307 * 00 = B node 308 * 01 = P node 309 * 10 = M node 310 * 11 = NBDD 311 * RESERVED 0-3 Reserved, must be zero (0) 312 * (But MS sets bit 3 in this field) 313 * 314 */ 315 316 int 317 smb_netbios_datagram_send(struct name_entry *src, struct name_entry *dest, 318 unsigned char *data, int length) 319 { 320 smb_inaddr_t ipaddr; 321 size_t count, srclen, destlen, sinlen; 322 addr_entry_t *addr; 323 struct sockaddr_in sin; 324 char *buffer; 325 char ha_source[NETBIOS_DOMAIN_NAME_MAX]; 326 char ha_dest[NETBIOS_DOMAIN_NAME_MAX]; 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 if ((buffer = malloc(MAX_DATAGRAM_LENGTH * 4)) == NULL) { 338 syslog(LOG_ERR, "nbt datagram: send: %m"); 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 addr_entry_t *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 if ((buffer = malloc(MAX_DATAGRAM_LENGTH * 4)) == NULL) { 418 syslog(LOG_ERR, "nbt datagram: send_to_net: %m"); 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.a_ipv4 = addr->sin.sin_addr.s_addr; 459 ipaddr.a_family = AF_INET; 460 if (smb_nic_is_local(&ipaddr)) 461 goto next; 462 463 sin.sin_addr.s_addr = ipaddr.a_ipv4; 464 sin.sin_port = addr->sin.sin_port; 465 (void) sendto(datagram_sock, buffer, count, 0, 466 (struct sockaddr *)&sin, sinlen); 467 468 next: addr = addr->forw; 469 } while (addr != &dest->addr_list); 470 free(buffer); 471 return (0); 472 } 473 474 475 int 476 smb_datagram_decode(struct datagram *datagram, int bytes) 477 { 478 unsigned char *ha_src; 479 unsigned char *ha_dest; 480 unsigned char *data; 481 482 if (bytes == DATAGRAM_ERR_HEADER_LENGTH) { 483 if (datagram->rawbuf[0] == DATAGRAM_TYPE_ERROR_DATAGRAM) 484 smb_netbios_datagram_error(datagram->rawbuf); 485 return (-1); 486 487 } 488 489 if (bytes >= DATAGRAM_HEADER_LENGTH) { 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 smb_tracef("NbtDatagram[%s]: invalid calling name", 516 inet_ntoa(datagram->src.addr_list.sin.sin_addr)); 517 smb_tracef("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 smb_tracef("NbtDatagram[%s]: invalid called name", 526 inet_ntoa(datagram->src.addr_list.sin.sin_addr)); 527 smb_tracef("Called name: <%02X>%32.32s", ha_dest[0], 528 &ha_dest[1]); 529 } 530 531 return (0); 532 } 533 534 /* ignore other malformed datagram packets */ 535 return (-1); 536 } 537 538 /* 539 * 4.4.3. Datagram Error Packet 540 */ 541 static void 542 smb_netbios_datagram_error(unsigned char *buf) 543 { 544 int error; 545 int datagram_id; 546 547 if (buf[0] != DATAGRAM_TYPE_ERROR_DATAGRAM) 548 return; 549 550 datagram_id = BE_IN16(&buf[2]); 551 error = buf[DATAGRAM_ERR_HEADER_LENGTH - 1]; 552 switch (error) { 553 case DATAGRAM_INVALID_SOURCE_NAME_FORMAT: 554 smb_tracef("NbtDatagramError[%d]: invalid source name format", 555 datagram_id); 556 break; 557 558 case DATAGRAM_INVALID_DESTINATION_NAME_FORMAT: 559 smb_tracef("NbtDatagramError[%d]: invalid destination name " 560 "format", datagram_id); 561 break; 562 563 case DATAGRAM_DESTINATION_NAME_NOT_PRESENT: 564 default: 565 break; 566 } 567 } 568 569 570 /* 571 * Function: int smb_netbios_process_BPM_datagram(unsigned char *packet, 572 * addr_entry_t *addr) 573 * 574 * Description from rfc1002: 575 * 576 * 5.3.3. RECEPTION OF NetBIOS DATAGRAMS BY ALL NODES 577 * 578 * The following algorithm discards out of order NetBIOS Datagram 579 * fragments. An implementation which reassembles out of order 580 * NetBIOS Datagram fragments conforms to this specification. The 581 * fragment discard timer is initialized to the value FRAGMENT_TIMEOUT. 582 * This value should be user configurable. The default value is 583 * given in Section 6, "Defined Constants and Variables". 584 * 585 * PROCEDURE datagram_packet(packet) 586 * 587 * (* 588 * * processing initiated by datagram packet reception 589 * * on B, P and M nodes 590 * *) 591 * BEGIN 592 * (* 593 * * if this node is a P node, ignore 594 * * broadcast packets. 595 * *) 596 * 597 * IF this is a P node AND incoming packet is 598 * a broadcast packet THEN 599 * BEGIN 600 * discard packet; 601 * END 602 * 603 * CASE packet type OF 604 * 605 * DATAGRAM SERVICE: 606 * BEGIN 607 * IF FIRST bit in FLAGS is set THEN 608 * BEGIN 609 * IF MORE bit in FLAGS is set THEN 610 * BEGIN 611 * Save 1st UDP packet of the Datagram; 612 * Set this Datagrams fragment discard 613 * timer to FRAGMENT_TIMEOUT; 614 * return; 615 * END 616 * ELSE 617 * Datagram is composed of a single 618 * UDP packet; 619 * END 620 * ELSE 621 * BEGIN 622 * (* Have the second fragment of a Datagram *) 623 * 624 * Search for 1st fragment by source IP address 625 * and DGM_ID; 626 * IF found 1st fragment THEN 627 * Process both UDP packets; 628 * ELSE 629 * BEGIN 630 * discard 2nd fragment UDP packet; 631 * return; 632 * END 633 * END 634 * 635 * IF DESTINATION_NAME is '*' THEN 636 * BEGIN 637 * (* NetBIOS broadcast *) 638 * 639 * deliver USER_DATA from UDP packet(s) to all 640 * outstanding receive broadcast 641 * datagram requests; 642 * return; 643 * END 644 * ELSE 645 * BEGIN (* non-broadcast *) 646 * (* Datagram for Unique or Group Name *) 647 * 648 * IF DESTINATION_NAME is not present in the 649 * local name table THEN 650 * BEGIN 651 * (* destination not present *) 652 * build DATAGRAM ERROR packet, clear 653 * FIRST and MORE bit, put in 654 * this nodes IP and PORT, set 655 * ERROR_CODE; 656 * send DATAGRAM ERROR packet to 657 * source IP address and port 658 * of UDP; 659 * discard UDP packet(s); 660 * return; 661 * END 662 * ELSE 663 * BEGIN (* good *) 664 * (* 665 * * Replicate received NetBIOS datagram for 666 * * each recipient 667 * *) 668 * FOR EACH pending NetBIOS users receive 669 * datagram operation 670 * BEGIN 671 * IF source name of operation 672 * matches destination name 673 * of packet THEN 674 * BEGIN 675 * deliver USER_DATA from UDP 676 * packet(s); 677 * END 678 * END (* for each *) 679 * return; 680 * END (* good *) 681 * END (* non-broadcast *) 682 * END (* datagram service *) 683 * 684 * DATAGRAM ERROR: 685 * BEGIN 686 * (* 687 * * name service returned incorrect information 688 * *) 689 * 690 * inform local name service that incorrect 691 * information was provided; 692 * 693 * IF this is a P or M node THEN 694 * BEGIN 695 * (* 696 * * tell NetBIOS Name Server that it may 697 * * have given incorrect information 698 * *) 699 * 700 * send NAME RELEASE REQUEST with name 701 * and incorrect IP address to NetBIOS 702 * Name Server; 703 * END 704 * END (* datagram error *) 705 * 706 * END (* case *) 707 * END 708 */ 709 710 static struct datagram * 711 smb_netbios_datagram_getq(struct datagram *datagram) 712 { 713 struct datagram *prev = 0; 714 715 (void) mutex_lock(&smb_dgq_mtx); 716 for (prev = smb_datagram_queue.forw; 717 prev != (struct datagram *)((uintptr_t)&smb_datagram_queue); 718 prev = prev->forw) { 719 if (prev->src.addr_list.sin.sin_addr.s_addr == 720 datagram->src.addr_list.sin.sin_addr.s_addr) { 721 /* Something waiting */ 722 QUEUE_CLIP(prev); 723 (void) mutex_unlock(&smb_dgq_mtx); 724 bcopy(datagram->data, &prev->data[prev->data_length], 725 datagram->data_length); 726 prev->data_length += datagram->data_length; 727 free(datagram); 728 return (prev); 729 } 730 } 731 (void) mutex_unlock(&smb_dgq_mtx); 732 733 return (0); 734 } 735 736 static void 737 smb_netbios_BPM_datagram(struct datagram *datagram) 738 { 739 struct name_entry *entry = 0; 740 struct datagram *qpacket = 0; 741 pthread_t browser_dispatch; 742 743 switch (datagram->packet_type) { 744 case DATAGRAM_TYPE_BROADCAST : 745 if (smb_node_type == 'P') { 746 /* 747 * if this node is a P node, ignore 748 * broadcast packets. 749 */ 750 break; 751 } 752 /* FALLTHROUGH */ 753 754 case DATAGRAM_TYPE_DIRECT_UNIQUE : 755 case DATAGRAM_TYPE_DIRECT_GROUP : 756 if ((datagram->flags & DATAGRAM_FLAGS_FIRST) != 0) { 757 if (datagram->flags & DATAGRAM_FLAGS_MORE) { 758 /* Save 1st UDP packet of the Datagram */ 759 datagram->discard_timer = FRAGMENT_TIMEOUT; 760 (void) mutex_lock(&smb_dgq_mtx); 761 QUEUE_INSERT_TAIL(&smb_datagram_queue, datagram) 762 (void) mutex_unlock(&smb_dgq_mtx); 763 return; 764 } 765 /* process datagram */ 766 } else { 767 qpacket = smb_netbios_datagram_getq(datagram); 768 if (qpacket) { 769 datagram = qpacket; 770 goto process_datagram; 771 } 772 break; 773 } 774 775 process_datagram: 776 entry = 0; 777 if ((strcmp((char *)datagram->dest.name, "*") == 0) || 778 ((entry = 779 smb_netbios_cache_lookup(&datagram->dest)) != 0)) { 780 if (entry) { 781 int is_local = IS_LOCAL(entry->attributes); 782 smb_netbios_cache_unlock_entry(entry); 783 784 if (is_local) { 785 (void) pthread_create(&browser_dispatch, 786 0, smb_browser_dispatch, 787 (void *)datagram); 788 (void) pthread_detach(browser_dispatch); 789 return; 790 } 791 } 792 793 datagram->rawbuf[0] = DATAGRAM_TYPE_ERROR_DATAGRAM; 794 datagram->rawbuf[1] &= DATAGRAM_FLAGS_SRC_TYPE; 795 796 (void) memcpy(&datagram->rawbuf[4], 797 &datagram->src.addr_list.sin.sin_addr.s_addr, 798 sizeof (uint32_t)); 799 BE_OUT16(&datagram->rawbuf[8], IPPORT_NETBIOS_DGM); 800 801 (void) sendto(datagram_sock, datagram->rawbuf, 802 datagram->rawbytes, 0, 803 (struct sockaddr *)&datagram->src.addr_list.sin, 804 datagram->src.addr_list.sinlen); 805 } 806 break; 807 808 case DATAGRAM_TYPE_ERROR_DATAGRAM : 809 break; 810 } 811 free(datagram); 812 } 813 814 /* 815 * NetBIOS Datagram Service (port 138) 816 */ 817 /*ARGSUSED*/ 818 void * 819 smb_netbios_datagram_service(void *arg) 820 { 821 struct sockaddr_in sin; 822 struct datagram *datagram; 823 int bytes, flag = 1; 824 smb_inaddr_t ipaddr; 825 826 (void) mutex_lock(&smb_dgq_mtx); 827 bzero(&smb_datagram_queue, sizeof (smb_datagram_queue)); 828 smb_datagram_queue.forw = smb_datagram_queue.back = 829 (struct datagram *)((uintptr_t)&smb_datagram_queue); 830 (void) mutex_unlock(&smb_dgq_mtx); 831 832 if ((datagram_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 833 syslog(LOG_ERR, "nbt datagram: socket failed: %m"); 834 smb_netbios_event(NETBIOS_EVENT_ERROR); 835 return (NULL); 836 } 837 838 flag = 1; 839 (void) setsockopt(datagram_sock, SOL_SOCKET, SO_REUSEADDR, &flag, 840 sizeof (flag)); 841 842 bzero(&sin, sizeof (sin)); 843 sin.sin_family = AF_INET; 844 sin.sin_port = htons(IPPORT_NETBIOS_DGM); 845 if (bind(datagram_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) { 846 syslog(LOG_ERR, "nbt datagram: bind(%d) failed: %m", 847 IPPORT_NETBIOS_DGM); 848 (void) close(datagram_sock); 849 smb_netbios_event(NETBIOS_EVENT_ERROR); 850 return (NULL); 851 } 852 853 flag = 1; 854 (void) setsockopt(datagram_sock, SOL_SOCKET, SO_BROADCAST, &flag, 855 sizeof (flag)); 856 857 smb_netbios_event(NETBIOS_EVENT_DGM_START); 858 859 while (smb_netbios_running()) { 860 if ((datagram = malloc(sizeof (struct datagram))) == NULL) { 861 /* Sleep for 10 seconds and try again */ 862 smb_netbios_sleep(10); 863 continue; 864 } 865 866 ignore: bzero(&datagram->inaddr, sizeof (addr_entry_t)); 867 datagram->inaddr.sinlen = sizeof (datagram->inaddr.sin); 868 datagram->inaddr.forw = datagram->inaddr.back = 869 &datagram->inaddr; 870 871 if ((bytes = recvfrom(datagram_sock, datagram->rawbuf, 872 MAX_DATAGRAM_LENGTH, 0, 873 (struct sockaddr *)&datagram->inaddr.sin, 874 &datagram->inaddr.sinlen)) < 0) { 875 syslog(LOG_ERR, "nbt datagram: recvfrom failed: %m"); 876 smb_netbios_event(NETBIOS_EVENT_ERROR); 877 break; 878 } 879 880 /* Ignore any incoming packets from myself... */ 881 ipaddr.a_ipv4 = datagram->inaddr.sin.sin_addr.s_addr; 882 ipaddr.a_family = AF_INET; 883 if (smb_nic_is_local(&ipaddr)) { 884 goto ignore; 885 } 886 887 if (smb_datagram_decode(datagram, bytes) < 0) 888 goto ignore; 889 890 /* 891 * This code was doing the wrong thing with responses from a 892 * Windows2000 PDC because both DATAGRAM_FLAGS_H_NODE and 893 * DATAGRAM_FLAGS_NBDD are defined to be the same value (see 894 * netbios.h). Since the Windows2000 PDC wants to be an H-Node, 895 * we need to handle all messages via smb_netbios_BPM_datagram. 896 * 897 * if ((datagram->flags & DATAGRAM_FLAGS_SRC_TYPE) == 898 * DATAGRAM_FLAGS_NBDD) 899 * smb_netbios_NBDD_datagram(datagram); 900 * else 901 * smb_netbios_BPM_datagram(datagram); 902 */ 903 904 smb_netbios_BPM_datagram(datagram); 905 } 906 907 smb_netbios_event(NETBIOS_EVENT_DGM_STOP); 908 (void) smb_netbios_wait(NETBIOS_EVENT_BROWSER_STOP); 909 910 (void) close(datagram_sock); 911 smb_netbios_datagram_fini(); 912 return (NULL); 913 } 914 915 static char 916 /* LINTED - E_STATIC_UNUSED */ 917 nb_fmt_flags(unsigned char flags) 918 { 919 switch (flags & DATAGRAM_FLAGS_SRC_TYPE) { 920 case DATAGRAM_FLAGS_B_NODE: return ('B'); 921 case DATAGRAM_FLAGS_P_NODE: return ('P'); 922 case DATAGRAM_FLAGS_M_NODE: return ('M'); 923 case DATAGRAM_FLAGS_H_NODE: return ('H'); 924 default: return ('?'); 925 } 926 } 927