xref: /illumos-gate/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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