xref: /illumos-gate/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c (revision fc724630b14603e4c1147df68b7bf45f7de7431f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Description:
28  *
29  *	Contains base code for netbios datagram service.
30  *
31  * Relavent sections from RFC1002:
32  *
33  *  5.3.  NetBIOS DATAGRAM SERVICE PROTOCOLS
34  *
35  *   The following are GLOBAL variables and should be NetBIOS user
36  *   configurable:
37  *
38  *   - SCOPE_ID: the non-leaf section of the domain name preceded by a
39  *     '.'  which represents the domain of the NetBIOS scope for the
40  *     NetBIOS name.  The following protocol description only supports
41  *     single scope operation.
42  *
43  *   - MAX_DATAGRAM_LENGTH: the maximum length of an IP datagram.  The
44  *     minimal maximum length defined in for IP is 576 bytes.  This
45  *     value is used when determining whether to fragment a NetBIOS
46  *     datagram.  Implementations are expected to be capable of
47  *     receiving unfragmented NetBIOS datagrams up to their maximum
48  *     size.
49  *
50  *   - BROADCAST_ADDRESS: the IP address B-nodes use to send datagrams
51  *     with group name destinations and broadcast datagrams.  The
52  *     default is the IP broadcast address for a single IP network.
53  *
54  *
55  *   The following are Defined Constants for the NetBIOS Datagram
56  *   Service:
57  *
58  *   - DGM_SRVC_UDP_PORT: the globally well-known UDP port allocated
59  *     where the NetBIOS Datagram Service receives UDP packets.  See
60  *     section 6, "Defined Constants", for its value.
61  */
62 
63 /*
64  *
65  *  6.  DEFINED CONSTANTS AND VARIABLES
66  *
67  *   GENERAL:
68  *
69  *      SCOPE_ID                   The name of the NetBIOS scope.
70  *
71  *                                 This is expressed as a character
72  *                                 string meeting the requirements of
73  *                                 the domain name system and without
74  *                                 a leading or trailing "dot".
75  *
76  *                                 An implementation may elect to make
77  *                                 this a single global value for the
78  *                                 node or allow it to be specified
79  *                                 with each separate NetBIOS name
80  *                                 (thus permitting cross-scope
81  *                                 references.)
82  *
83  *      BROADCAST_ADDRESS          An IP address composed of the
84  *                                 node network and subnetwork
85  *                                 numbers with all remaining bits set
86  *                                 to one.
87  *
88  *                                 I.e. "Specific subnet" broadcast
89  *                                 addressing according to section 2.3
90  *                                 of RFC 950.
91  *
92  *      BCAST_REQ_RETRY_TIMEOUT    250 milliseconds.
93  *                                 An adaptive timer may be used.
94  *
95  *      BCAST_REQ_RETRY_COUNT      3
96  *
97  *      UCAST_REQ_RETRY_TIMEOUT    5 seconds
98  *                                 An adaptive timer may be used.
99  *
100  *      UCAST_REQ_RETRY_COUNT      3
101  *
102  *      MAX_DATAGRAM_LENGTH        576 bytes (default)
103  *
104  *   DATAGRAM SERVICE:
105  *
106  *      DGM_SRVC_UDP_PORT          138 (decimal)
107  *
108  *      FRAGMENT_TO                2 seconds (default)
109  */
110 
111 #include <stdlib.h>
112 #include <unistd.h>
113 #include <string.h>
114 #include <strings.h>
115 #include <syslog.h>
116 #include <synch.h>
117 #include <sys/socket.h>
118 #include <arpa/inet.h>
119 
120 #include <smbns_netbios.h>
121 
122 #include <smbsrv/libsmbns.h>
123 
124 static int datagram_sock = -1;
125 static short datagram_id = 1;
126 static struct datagram_queue smb_datagram_queue;
127 static mutex_t smb_dgq_mtx;
128 
129 /*
130  * Function:  smb_netbios_datagram_tick(void)
131  *
132  * Description:
133  *
134  *	Called once a second to handle time to live timeouts in
135  *	datagram assembly queue.
136  *
137  * Inputs:
138  *
139  * Returns:
140  *	void	-> Nothing at all...
141  */
142 
143 void
144 smb_netbios_datagram_tick(void)
145 {
146 	struct datagram *entry;
147 	struct datagram *next;
148 
149 	(void) mutex_lock(&smb_dgq_mtx);
150 
151 	for (entry = smb_datagram_queue.forw;
152 	    entry != (struct datagram *)((uintptr_t)&smb_datagram_queue);
153 	    entry = next) {
154 		next = entry->forw;
155 		if (--entry->discard_timer == 0) {
156 			/* Toss it */
157 			QUEUE_CLIP(entry);
158 			free(entry);
159 		}
160 	}
161 	(void) mutex_unlock(&smb_dgq_mtx);
162 }
163 
164 void
165 smb_netbios_datagram_fini()
166 {
167 	struct datagram *entry;
168 
169 	(void) mutex_lock(&smb_dgq_mtx);
170 	while ((entry = smb_datagram_queue.forw) !=
171 	    (struct datagram *)((uintptr_t)&smb_datagram_queue)) {
172 		QUEUE_CLIP(entry);
173 		free(entry);
174 	}
175 	(void) mutex_unlock(&smb_dgq_mtx);
176 }
177 
178 /*
179  * Function: int smb_netbios_send_Bnode_datagram(unsigned char *data,
180  *		struct name_entry *source, struct name_entry *destination,
181  *		uint32_t broadcast)
182  *
183  * Description from rfc1002:
184  *
185  *  5.3.1.  B NODE TRANSMISSION OF NetBIOS DATAGRAMS
186  *
187  *   PROCEDURE send_datagram(data, source, destination, broadcast)
188  *
189  *   (*
190  *    * user initiated processing on B node
191  *    *)
192  *
193  *   BEGIN
194  *        group = FALSE;
195  *
196  *        do name discovery on destination name, returns name type and
197  *             IP address;
198  *
199  *        IF name type is group name THEN
200  *        BEGIN
201  *             group = TRUE;
202  *        END
203  *
204  *        (*
205  *         * build datagram service UDP packet;
206  *         *)
207  *        convert source and destination NetBIOS names into
208  *             half-ASCII, biased encoded name;
209  *        SOURCE_NAME = cat(source, SCOPE_ID);
210  *        SOURCE_IP = this nodes IP address;
211  *        SOURCE_PORT =  DGM_SRVC_UDP_PORT;
212  *
213  *        IF NetBIOS broadcast THEN
214  *        BEGIN
215  *             DESTINATION_NAME = cat("*", SCOPE_ID)
216  *        END
217  *        ELSE
218  *        BEGIN
219  *             DESTINATION_NAME = cat(destination, SCOPE_ID)
220  *        END
221  *
222  *        MSG_TYPE = select_one_from_set
223  *             {BROADCAST, DIRECT_UNIQUE, DIRECT_GROUP}
224  *        DGM_ID = next transaction id for Datagrams;
225  *        DGM_LENGTH = length of data + length of second level encoded
226  *             source and destination names;
227  *
228  *        IF (length of the NetBIOS Datagram, including UDP and
229  *            IP headers, > MAX_DATAGRAM_LENGTH) THEN
230  *        BEGIN
231  *             (*
232  *              * fragment NetBIOS datagram into 2 UDP packets
233  *              *)
234  *             Put names into 1st UDP packet and any data that fits
235  *                  after names;
236  *             Set MORE and FIRST bits in 1st UDP packets FLAGS;
237  *             OFFSET in 1st UDP = 0;
238  *
239  *             Replicate NetBIOS Datagram header from 1st UDP packet
240  *                  into 2nd UDP packet;
241  *             Put rest of data in 2nd UDP packet;
242  *             Clear MORE and FIRST bits in 2nd UDP packets FLAGS;
243  *             OFFSET in 2nd UDP = DGM_LENGTH - number of name and
244  *                  data bytes in 1st UDP;
245  *        END
246  *        BEGIN
247  *             (*
248  *              * Only need one UDP packet
249  *              *)
250  *             USER_DATA = data;
251  *             Clear MORE bit and set FIRST bit in FLAGS;
252  *             OFFSET = 0;
253  *        END
254  *
255  *        IF (group == TRUE) OR (NetBIOS broadcast) THEN
256  *        BEGIN
257  *             send UDP packet(s) to BROADCAST_ADDRESS;
258  *        END
259  *        ELSE
260  *        BEGIN
261  *             send UDP packet(s) to IP address returned by name
262  *                discovery;
263  *        END
264  *   END (* procedure *)
265  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
266  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
267  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
268  *   |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
269  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
270  *   |                           SOURCE_IP                           |
271  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
272  *   |          SOURCE_PORT          |          DGM_LENGTH           |
273  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
274  *   |         PACKET_OFFSET         |
275  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
276  *
277  *   MSG_TYPE values (in hexidecimal):
278  *
279  *           10 -  DIRECT_UNIQUE DATAGRAM
280  *           11 -  DIRECT_GROUP DATAGRAM
281  *           12 -  BROADCAST DATAGRAM
282  *           13 -  DATAGRAM ERROR
283  *           14 -  DATAGRAM QUERY REQUEST
284  *           15 -  DATAGRAM POSITIVE QUERY RESPONSE
285  *           16 -  DATAGRAM NEGATIVE QUERY RESPONSE
286  *
287  *   Bit definitions of the FLAGS field:
288  *
289  *     0   1   2   3   4   5   6   7
290  *   +---+---+---+---+---+---+---+---+
291  *   | 0 | 0 | 0 | 0 |  SNT  | F | M |
292  *   +---+---+---+---+---+---+---+---+
293  *
294  *   Symbol     Bit(s)   Description
295  *
296  *   M               7   MORE flag, If set then more NetBIOS datagram
297  *                       fragments follow.
298  *
299  *   F               6   FIRST packet flag,  If set then this is first
300  *                       (and possibly only) fragment of NetBIOS
301  *                       datagram
302  *
303  *   SNT           4,5   Source End-Node type:
304  *                          00 = B node
305  *                          01 = P node
306  *                          10 = M node
307  *                          11 = NBDD
308  *   RESERVED      0-3   Reserved, must be zero (0)
309  *      (But MS sets bit 3 in this field)
310  *
311  */
312 
313 int
314 smb_netbios_datagram_send(struct name_entry *src, struct name_entry *dest,
315     unsigned char *data, int length)
316 {
317 	smb_inaddr_t ipaddr;
318 	size_t count, srclen, destlen, sinlen;
319 	struct addr_entry *addr;
320 	struct sockaddr_in sin;
321 	char *buffer;
322 	char ha_source[NETBIOS_DOMAIN_NAME_MAX];
323 	char ha_dest[NETBIOS_DOMAIN_NAME_MAX];
324 
325 	(void) smb_first_level_name_encode(src, (unsigned char *)ha_source,
326 	    sizeof (ha_source));
327 	srclen = strlen(ha_source) + 1;
328 
329 	(void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest,
330 	    sizeof (ha_dest));
331 	destlen = strlen(ha_dest) + 1;
332 
333 	/* give some extra room */
334 	buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4);
335 	if (buffer == 0) {
336 		syslog(LOG_ERR, "netbios: datagram send (resource shortage)");
337 		return (-1);
338 	}
339 
340 	buffer[0] = DATAGRAM_TYPE_DIRECT_UNIQUE;
341 	switch (smb_node_type) {
342 	case 'B':
343 		buffer[1] = DATAGRAM_FLAGS_B_NODE | DATAGRAM_FLAGS_FIRST;
344 		break;
345 	case 'P':
346 		buffer[1] = DATAGRAM_FLAGS_P_NODE | DATAGRAM_FLAGS_FIRST;
347 		break;
348 	case 'M':
349 		buffer[1] = DATAGRAM_FLAGS_M_NODE | DATAGRAM_FLAGS_FIRST;
350 		break;
351 	case 'H':
352 	default:
353 		buffer[1] = DATAGRAM_FLAGS_H_NODE | DATAGRAM_FLAGS_FIRST;
354 		break;
355 	}
356 
357 	datagram_id++;
358 	BE_OUT16(&buffer[2], datagram_id);
359 	(void) memcpy(&buffer[4], &src->addr_list.sin.sin_addr.s_addr,
360 	    sizeof (uint32_t));
361 	(void) memcpy(&buffer[8], &src->addr_list.sin.sin_port,
362 	    sizeof (uint16_t));
363 	BE_OUT16(&buffer[10], length + srclen + destlen);
364 	BE_OUT16(&buffer[12], 0);
365 
366 	bcopy(ha_source, &buffer[14], srclen);
367 	bcopy(ha_dest, &buffer[14 + srclen], destlen);
368 	bcopy(data, &buffer[14 + srclen + destlen], length);
369 	count = &buffer[14 + srclen + destlen + length] - buffer;
370 
371 	bzero(&sin, sizeof (sin));
372 	sin.sin_family = AF_INET;
373 	sinlen = sizeof (sin);
374 	addr = &dest->addr_list;
375 	do {
376 		ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr;
377 		ipaddr.a_family = AF_INET;
378 		/* Don't send anything to myself... */
379 		if (smb_nic_is_local(&ipaddr))
380 			goto next;
381 
382 		sin.sin_addr.s_addr = ipaddr.a_ipv4;
383 		sin.sin_port = addr->sin.sin_port;
384 		(void) sendto(datagram_sock, buffer, count, 0,
385 		    (struct sockaddr *)&sin, sinlen);
386 
387 next:		addr = addr->forw;
388 	} while (addr != &dest->addr_list);
389 	free(buffer);
390 	return (0);
391 }
392 
393 
394 int
395 smb_netbios_datagram_send_to_net(struct name_entry *src,
396     struct name_entry *dest, char *data, int length)
397 {
398 	smb_inaddr_t ipaddr;
399 	size_t count, srclen, destlen, sinlen;
400 	struct addr_entry *addr;
401 	struct sockaddr_in sin;
402 	char *buffer;
403 	char ha_source[NETBIOS_DOMAIN_NAME_MAX];
404 	char ha_dest[NETBIOS_DOMAIN_NAME_MAX];
405 
406 	(void) smb_first_level_name_encode(src, (unsigned char *)ha_source,
407 	    sizeof (ha_source));
408 	srclen = strlen(ha_source) + 1;
409 
410 	(void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest,
411 	    sizeof (ha_dest));
412 	destlen = strlen(ha_dest) + 1;
413 
414 	/* give some extra room */
415 	buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4);
416 	if (buffer == 0) {
417 		syslog(LOG_ERR, "netbios: datagram send (resource shortage)");
418 		return (-1);
419 	}
420 
421 	buffer[0] = DATAGRAM_TYPE_DIRECT_UNIQUE;
422 	switch (smb_node_type) {
423 	case 'B':
424 		buffer[1] = DATAGRAM_FLAGS_B_NODE | DATAGRAM_FLAGS_FIRST;
425 		break;
426 	case 'P':
427 		buffer[1] = DATAGRAM_FLAGS_P_NODE | DATAGRAM_FLAGS_FIRST;
428 		break;
429 	case 'M':
430 		buffer[1] = DATAGRAM_FLAGS_M_NODE | DATAGRAM_FLAGS_FIRST;
431 		break;
432 	case 'H':
433 	default:
434 		buffer[1] = DATAGRAM_FLAGS_H_NODE | DATAGRAM_FLAGS_FIRST;
435 		break;
436 	}
437 
438 	datagram_id++;
439 	BE_OUT16(&buffer[2], datagram_id);
440 	(void) memcpy(&buffer[4], &src->addr_list.sin.sin_addr.s_addr,
441 	    sizeof (uint32_t));
442 	(void) memcpy(&buffer[8], &src->addr_list.sin.sin_port,
443 	    sizeof (uint16_t));
444 	BE_OUT16(&buffer[10], length + srclen + destlen);
445 	BE_OUT16(&buffer[12], 0);
446 
447 	bcopy(ha_source, &buffer[14], srclen);
448 	bcopy(ha_dest, &buffer[14 + srclen], destlen);
449 	bcopy(data, &buffer[14 + srclen + destlen], length);
450 	count = &buffer[14 + srclen + destlen + length] - buffer;
451 
452 	bzero(&sin, sizeof (sin));
453 	sin.sin_family = AF_INET;
454 	sinlen = sizeof (sin);
455 	addr = &dest->addr_list;
456 	do {
457 		ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr;
458 		ipaddr.a_family = AF_INET;
459 		if (smb_nic_is_local(&ipaddr))
460 			goto next;
461 
462 		sin.sin_addr.s_addr = ipaddr.a_ipv4;
463 		sin.sin_port = addr->sin.sin_port;
464 		(void) sendto(datagram_sock, buffer, count, 0,
465 		    (struct sockaddr *)&sin, sinlen);
466 
467 next:		addr = addr->forw;
468 	} while (addr != &dest->addr_list);
469 	free(buffer);
470 	return (0);
471 }
472 
473 
474 int
475 smb_datagram_decode(struct datagram *datagram, int bytes)
476 {
477 	unsigned char *ha_src;
478 	unsigned char *ha_dest;
479 	unsigned char *data;
480 
481 	if (bytes < DATAGRAM_HEADER_LENGTH) {
482 		syslog(LOG_ERR, "NbtDatagramDecode[%d]: too small packet",
483 		    bytes);
484 		return (-1);
485 	}
486 
487 	ha_src = &datagram->rawbuf[DATAGRAM_HEADER_LENGTH];
488 	ha_dest = ha_src + strlen((char *)ha_src) + 1;
489 	data = ha_dest + strlen((char *)ha_dest) + 1;
490 
491 	bzero(&datagram->src, sizeof (struct name_entry));
492 	bzero(&datagram->dest, sizeof (struct name_entry));
493 
494 	datagram->rawbytes = bytes;
495 	datagram->packet_type = datagram->rawbuf[0];
496 	datagram->flags = datagram->rawbuf[1];
497 	datagram->datagram_id = BE_IN16(&datagram->rawbuf[2]);
498 
499 	datagram->src.addr_list.sinlen = sizeof (struct sockaddr_in);
500 	(void) memcpy(&datagram->src.addr_list.sin.sin_addr.s_addr,
501 	    &datagram->rawbuf[4], sizeof (uint32_t));
502 	(void) memcpy(&datagram->src.addr_list.sin.sin_port,
503 	    &datagram->rawbuf[8], sizeof (uint16_t));
504 	datagram->src.addr_list.forw = datagram->src.addr_list.back =
505 	    &datagram->src.addr_list;
506 
507 	datagram->data = data;
508 	datagram->data_length = BE_IN16(&datagram->rawbuf[10]);
509 	datagram->offset = BE_IN16(&datagram->rawbuf[12]);
510 
511 	if (smb_first_level_name_decode(ha_src, &datagram->src) < 0) {
512 		syslog(LOG_DEBUG, "NbtDatagram[%s]: invalid calling name",
513 		    inet_ntoa(datagram->src.addr_list.sin.sin_addr));
514 		syslog(LOG_DEBUG, "Calling name: <%02X>%32.32s",
515 		    ha_src[0], &ha_src[1]);
516 	}
517 
518 	datagram->dest.addr_list.forw = datagram->dest.addr_list.back =
519 	    &datagram->dest.addr_list;
520 
521 	if (smb_first_level_name_decode(ha_dest, &datagram->dest) < 0) {
522 		syslog(LOG_DEBUG, "NbtDatagram[%s]: invalid called name",
523 		    inet_ntoa(datagram->src.addr_list.sin.sin_addr));
524 		syslog(LOG_DEBUG, "Called name: <%02X>%32.32s", ha_dest[0],
525 		    &ha_dest[1]);
526 	}
527 
528 	return (0);
529 }
530 
531 
532 /*
533  * Function: int smb_netbios_process_BPM_datagram(unsigned char *packet,
534  *		struct addr_entry *addr)
535  *
536  * Description from rfc1002:
537  *
538  *  5.3.3.  RECEPTION OF NetBIOS DATAGRAMS BY ALL NODES
539  *
540  *   The following algorithm discards out of order NetBIOS Datagram
541  *   fragments.  An implementation which reassembles out of order
542  *   NetBIOS Datagram fragments conforms to this specification.  The
543  *   fragment discard timer is initialized to the value FRAGMENT_TIMEOUT.
544  *   This value should be user configurable.  The default value is
545  *   given in Section 6, "Defined Constants and Variables".
546  *
547  *   PROCEDURE datagram_packet(packet)
548  *
549  *   (*
550  *    * processing initiated by datagram packet reception
551  *    * on B, P and M nodes
552  *    *)
553  *   BEGIN
554  *        (*
555  *         * if this node is a P node, ignore
556  *         * broadcast packets.
557  *         *)
558  *
559  *        IF this is a P node AND incoming packet is
560  *             a broadcast packet THEN
561  *        BEGIN
562  *             discard packet;
563  *        END
564  *
565  *        CASE packet type OF
566  *
567  *           DATAGRAM SERVICE:
568  *           BEGIN
569  *             IF FIRST bit in FLAGS is set THEN
570  *             BEGIN
571  *                  IF MORE bit in FLAGS is set THEN
572  *                  BEGIN
573  *                       Save 1st UDP packet of the Datagram;
574  *                       Set this Datagrams fragment discard
575  *                         timer to FRAGMENT_TIMEOUT;
576  *                       return;
577  *                  END
578  *                  ELSE
579  *                       Datagram is composed of a single
580  *                         UDP packet;
581  *             END
582  *             ELSE
583  *             BEGIN
584  *                  (* Have the second fragment of a Datagram *)
585  *
586  *                  Search for 1st fragment by source IP address
587  *                     and DGM_ID;
588  *                  IF found 1st fragment THEN
589  *                       Process both UDP packets;
590  *                  ELSE
591  *                  BEGIN
592  *                       discard 2nd fragment UDP packet;
593  *                       return;
594  *                  END
595  *             END
596  *
597  *             IF DESTINATION_NAME is '*' THEN
598  *             BEGIN
599  *                  (* NetBIOS broadcast *)
600  *
601  *                  deliver USER_DATA from UDP packet(s) to all
602  *                       outstanding receive broadcast
603  *                       datagram requests;
604  *                  return;
605  *             END
606  *             ELSE
607  *             BEGIN (* non-broadcast *)
608  *                  (* Datagram for Unique or Group Name *)
609  *
610  *                  IF DESTINATION_NAME is not present in the
611  *                     local name table THEN
612  *                  BEGIN
613  *                       (* destination not present *)
614  *                       build DATAGRAM ERROR packet, clear
615  *                            FIRST and MORE bit, put in
616  *                            this nodes IP and PORT, set
617  *                            ERROR_CODE;
618  *                       send DATAGRAM ERROR packet to
619  *                            source IP address and port
620  *                            of UDP;
621  *                       discard UDP packet(s);
622  *                       return;
623  *                  END
624  *                  ELSE
625  *                  BEGIN (* good *)
626  *                       (*
627  *                        * Replicate received NetBIOS datagram for
628  *                        * each recipient
629  *                        *)
630  *                       FOR EACH pending NetBIOS users receive
631  *                            datagram operation
632  *                       BEGIN
633  *                            IF source name of operation
634  *                               matches destination name
635  *                               of packet THEN
636  *                            BEGIN
637  *                               deliver USER_DATA from UDP
638  *                                 packet(s);
639  *                            END
640  *                       END (* for each *)
641  *                       return;
642  *                  END (* good *)
643  *             END (* non-broadcast *)
644  *            END (* datagram service *)
645  *
646  *           DATAGRAM ERROR:
647  *           BEGIN
648  *                (*
649  *                 * name service returned incorrect information
650  *                 *)
651  *
652  *                inform local name service that incorrect
653  *                  information was provided;
654  *
655  *                IF this is a P or M node THEN
656  *                BEGIN
657  *                     (*
658  *                      * tell NetBIOS Name Server that it may
659  *                      * have given incorrect information
660  *                      *)
661  *
662  *                     send NAME RELEASE REQUEST with name
663  *                       and incorrect IP address to NetBIOS
664  *                       Name Server;
665  *                END
666  *           END (* datagram error *)
667  *
668  *        END (* case *)
669  *   END
670  */
671 
672 static struct datagram *
673 smb_netbios_datagram_getq(struct datagram *datagram)
674 {
675 	struct datagram *prev = 0;
676 
677 	(void) mutex_lock(&smb_dgq_mtx);
678 	for (prev = smb_datagram_queue.forw;
679 	    prev != (struct datagram *)((uintptr_t)&smb_datagram_queue);
680 	    prev = prev->forw) {
681 		if (prev->src.addr_list.sin.sin_addr.s_addr ==
682 		    datagram->src.addr_list.sin.sin_addr.s_addr) {
683 			/* Something waiting */
684 			QUEUE_CLIP(prev);
685 			(void) mutex_unlock(&smb_dgq_mtx);
686 			bcopy(datagram->data, &prev->data[prev->data_length],
687 			    datagram->data_length);
688 			prev->data_length += datagram->data_length;
689 			free(datagram);
690 			return (prev);
691 		}
692 	}
693 	(void) mutex_unlock(&smb_dgq_mtx);
694 
695 	return (0);
696 }
697 
698 static void
699 smb_netbios_BPM_datagram(struct datagram *datagram)
700 {
701 	struct name_entry *entry = 0;
702 	struct datagram *qpacket = 0;
703 	pthread_t browser_dispatch;
704 
705 	switch (datagram->packet_type) {
706 	case DATAGRAM_TYPE_BROADCAST :
707 		if (smb_node_type == 'P') {
708 			/*
709 			 * if this node is a P node, ignore
710 			 * broadcast packets.
711 			 */
712 			break;
713 		}
714 		/* FALLTHROUGH */
715 
716 	case DATAGRAM_TYPE_DIRECT_UNIQUE :
717 	case DATAGRAM_TYPE_DIRECT_GROUP :
718 		if ((datagram->flags & DATAGRAM_FLAGS_FIRST) != 0) {
719 			if (datagram->flags & DATAGRAM_FLAGS_MORE) {
720 				/* Save 1st UDP packet of the Datagram */
721 				datagram->discard_timer = FRAGMENT_TIMEOUT;
722 				(void) mutex_lock(&smb_dgq_mtx);
723 				QUEUE_INSERT_TAIL(&smb_datagram_queue, datagram)
724 				(void) mutex_unlock(&smb_dgq_mtx);
725 				return;
726 			}
727 			/* process datagram */
728 		} else {
729 			qpacket = smb_netbios_datagram_getq(datagram);
730 			if (qpacket) {
731 				datagram = qpacket;
732 				goto process_datagram;
733 			}
734 			break;
735 		}
736 
737 process_datagram:
738 		entry = 0;
739 		if ((strcmp((char *)datagram->dest.name, "*") == 0) ||
740 		    ((entry =
741 		    smb_netbios_cache_lookup(&datagram->dest)) != 0)) {
742 			if (entry) {
743 				int is_local = IS_LOCAL(entry->attributes);
744 				smb_netbios_cache_unlock_entry(entry);
745 
746 				if (is_local) {
747 					(void) pthread_create(&browser_dispatch,
748 					    0, smb_browser_dispatch,
749 					    (void *)datagram);
750 					(void) pthread_detach(browser_dispatch);
751 					return;
752 				}
753 			}
754 
755 			datagram->rawbuf[0] = DATAGRAM_TYPE_ERROR_DATAGRAM;
756 			datagram->rawbuf[1] &= DATAGRAM_FLAGS_SRC_TYPE;
757 
758 			(void) memcpy(&datagram->rawbuf[4],
759 			    &datagram->src.addr_list.sin.sin_addr.s_addr,
760 			    sizeof (uint32_t));
761 			BE_OUT16(&datagram->rawbuf[8], DGM_SRVC_UDP_PORT);
762 
763 			(void) sendto(datagram_sock, datagram->rawbuf,
764 			    datagram->rawbytes, 0,
765 			    (struct sockaddr *)&datagram->src.addr_list.sin,
766 			    datagram->src.addr_list.sinlen);
767 		}
768 		break;
769 
770 	case DATAGRAM_TYPE_ERROR_DATAGRAM :
771 		break;
772 	}
773 	free(datagram);
774 }
775 
776 
777 /*
778  * smb_netbios_process_NBDD_datagram
779  *
780  * Description from rfc1002:
781  *
782  *
783  *  5.3.4.  PROTOCOLS FOR THE NBDD
784  *
785  *   The key to NetBIOS Datagram forwarding service is the packet
786  *   delivered to the destination end node must have the same NetBIOS
787  *   header as if the source end node sent the packet directly to the
788  *   destination end node.  Consequently, the NBDD does not reassemble
789  *   NetBIOS Datagrams.  It forwards the UDP packet as is.
790  *
791  *   PROCEDURE  datagram_packet(packet)
792  *
793  *   (*
794  *    * processing initiated by a incoming datagram service
795  *    * packet on a NBDD node.
796  *    *)
797  *
798  *   BEGIN
799  *        CASE packet type OF
800  *
801  *           DATAGRAM SERVICE:
802  *           BEGIN
803  *                IF packet was sent as a directed
804  *                   NetBIOS datagram THEN
805  *                BEGIN
806  *                  (*
807  *                   * provide group forwarding service
808  *                   *
809  *                   * Forward datagram to each member of the
810  *                   * group.  Can forward via:
811  *                   *   1) get list of group members and send
812  *                   *   the DATAGRAM SERVICE packet unicast
813  *                   *   to each
814  *                   *   2) use Group Multicast, if available
815  *                   *   3) combination of 1) and 2)
816  *                   *)
817  *
818  *                  ...
819  *
820  *                END
821  *
822  *                ELSE
823  *                BEGIN
824  *                  (*
825  *                   * provide broadcast forwarding service
826  *                   *
827  *                   * Forward datagram to every node in the
828  *                   * NetBIOS scope.  Can forward via:
829  *                   *   1) get list of group members and send
830  *                   *   the DATAGRAM SERVICE packet unicast
831  *                   *   to each
832  *                   *   2) use Group Multicast, if available
833  *                   *   3) combination of 1) and 2)
834  *                   *)
835  *
836  *                  ...
837  *
838  *                END
839  *           END (* datagram service *)
840  *
841  *           DATAGRAM ERROR:
842  *           BEGIN
843  *             (*
844  *              * Should never receive these because Datagrams
845  *              * forwarded have source end node IP address and
846  *              * port in NetBIOS header.
847  *              *)
848  *
849  *             send DELETE NAME REQUEST with incorrect name and
850  *                  IP address to NetBIOS Name Server;
851  *
852  *           END (* datagram error *)
853  *
854  *           DATAGRAM QUERY REQUEST:
855  *           BEGIN
856  *             IF can send packet to DESTINATION_NAME THEN
857  *             BEGIN
858  *                  (*
859  *                   * NBDD is able to relay Datagrams for
860  *                   * this name
861  *                   *)
862  *
863  *                  send POSITIVE DATAGRAM QUERY RESPONSE to
864  *                    REQUEST source IP address and UDP port
865  *                    with requests DGM_ID;
866  *             END
867  *             ELSE
868  *             BEGIN
869  *                  (*
870  *                   * NBDD is NOT able to relay Datagrams for
871  *                   * this name
872  *                   *)
873  *
874  *                  send NEGATIVE DATAGRAM QUERY RESPONSE to
875  *                    REQUEST source IP address and UDP port
876  *
877  *                    with requests DGM_ID;
878  *             END
879  *           END (* datagram query request *)
880  *
881  *        END (* case *)
882  *   END (* procedure *)
883  */
884 
885 
886 /*
887  * Function: int smb_netbios_datagram_service_daemon(void)
888  *
889  * Description:
890  *
891  * 4.4.  DATAGRAM SERVICE PACKETS
892  *
893  * 4.4.1.  NetBIOS DATAGRAM HEADER
894  *
895  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
896  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
897  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
898  *   |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
899  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
900  *   |                           SOURCE_IP                           |
901  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
902  *   |          SOURCE_PORT          |          DGM_LENGTH           |
903  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
904  *   |         PACKET_OFFSET         |
905  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
906  *
907  *   MSG_TYPE values (in hexidecimal):
908  *
909  *           10 -  DIRECT_UNIQUE DATAGRAM
910  *           11 -  DIRECT_GROUP DATAGRAM
911  *           12 -  BROADCAST DATAGRAM
912  *           13 -  DATAGRAM ERROR
913  *           14 -  DATAGRAM QUERY REQUEST
914  *           15 -  DATAGRAM POSITIVE QUERY RESPONSE
915  *           16 -  DATAGRAM NEGATIVE QUERY RESPONSE
916  *
917  *   Bit definitions of the FLAGS field:
918  *
919  *     0   1   2   3   4   5   6   7
920  *   +---+---+---+---+---+---+---+---+
921  *   | 0 | 0 | 0 | 0 |  SNT  | F | M |
922  *   +---+---+---+---+---+---+---+---+
923  *
924  *   Symbol     Bit(s)   Description
925  *
926  *   M               7   MORE flag, If set then more NetBIOS datagram
927  *                       fragments follow.
928  *
929  *   F               6   FIRST packet flag,  If set then this is first
930  *                       (and possibly only) fragment of NetBIOS
931  *                       datagram
932  *
933  *   SNT           4,5   Source End-Node type:
934  *                          00 = B node
935  *                          01 = P node
936  *                          10 = M node
937  *                          11 = NBDD
938  *   RESERVED      0-3   Reserved, must be zero (0)
939  *
940  * Inputs:
941  *	Nothing
942  *
943  * Returns:
944  *	int	-> Description
945  */
946 
947 /*ARGSUSED*/
948 void *
949 smb_netbios_datagram_service_daemon(void *arg)
950 {
951 	struct sockaddr_in 	sin;
952 	struct datagram 	*datagram;
953 	int			bytes, flag = 1;
954 	smb_inaddr_t 		ipaddr;
955 
956 	(void) mutex_lock(&smb_dgq_mtx);
957 	bzero(&smb_datagram_queue, sizeof (smb_datagram_queue));
958 	smb_datagram_queue.forw = smb_datagram_queue.back =
959 	    (struct datagram *)((uintptr_t)&smb_datagram_queue);
960 	(void) mutex_unlock(&smb_dgq_mtx);
961 
962 	if ((datagram_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
963 		syslog(LOG_ERR,
964 		    "smbd: Could not create AF_INET, SOCK_DGRAM, socket");
965 		smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
966 		return (0);
967 	}
968 
969 	bzero(&sin, sizeof (sin));
970 	sin.sin_family = AF_INET;
971 	sin.sin_port = htons(DGM_SRVC_UDP_PORT);
972 	if (bind(datagram_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) {
973 		syslog(LOG_ERR, "smbd: Bind to name service port %d failed",
974 		    DGM_SRVC_UDP_PORT);
975 		(void) close(datagram_sock);
976 		smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
977 		return (0);
978 	}
979 	(void) setsockopt(datagram_sock, SOL_SOCKET, SO_BROADCAST, &flag,
980 	    sizeof (flag));
981 
982 	smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 1);
983 
984 	while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) ||
985 	    (nb_status.state & NETBIOS_BROWSER_RUNNING)) {
986 		if ((datagram = (struct datagram *)
987 		    malloc(sizeof (struct datagram))) == 0) {
988 			/* Sleep for 10 sec and try again */
989 			(void) sleep(10);
990 			continue;
991 		}
992 
993 ignore:		bzero(&datagram->inaddr, sizeof (struct addr_entry));
994 		datagram->inaddr.sinlen = sizeof (datagram->inaddr.sin);
995 		datagram->inaddr.forw = datagram->inaddr.back =
996 		    &datagram->inaddr;
997 
998 		if ((bytes = recvfrom(datagram_sock, datagram->rawbuf,
999 		    MAX_DATAGRAM_LENGTH, 0,
1000 		    (struct sockaddr *)&datagram->inaddr.sin,
1001 		    &datagram->inaddr.sinlen)) < 0) {
1002 			syslog(LOG_ERR,
1003 			    "smbd: NETBIOS datagram - recvfrom failed");
1004 			smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
1005 			break;
1006 		}
1007 
1008 		/* Ignore any incoming packets from myself... */
1009 		ipaddr.a_ipv4 = datagram->inaddr.sin.sin_addr.s_addr;
1010 		ipaddr.a_family = AF_INET;
1011 		if (smb_nic_is_local(&ipaddr)) {
1012 			goto ignore;
1013 		}
1014 
1015 		if (smb_datagram_decode(datagram, bytes) < 0)
1016 			goto ignore;
1017 
1018 	/*
1019 	 * This code was doing the wrong thing with responses from a
1020 	 * Windows2000 PDC because both DATAGRAM_FLAGS_H_NODE and
1021 	 * DATAGRAM_FLAGS_NBDD are defined to be the same value (see
1022 	 * netbios.h). Since the Windows2000 PDC wants to be an H-Node,
1023 	 * we need to handle all messages via smb_netbios_BPM_datagram.
1024 	 *
1025 	 *	if ((datagram->flags & DATAGRAM_FLAGS_SRC_TYPE) ==
1026 	 *	    DATAGRAM_FLAGS_NBDD)
1027 	 *		smb_netbios_NBDD_datagram(datagram);
1028 	 *	else
1029 	 *		smb_netbios_BPM_datagram(datagram);
1030 	 */
1031 
1032 		smb_netbios_BPM_datagram(datagram);
1033 	}
1034 
1035 	smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 0);
1036 
1037 	(void) mutex_lock(&nb_status.mtx);
1038 	while (nb_status.state & NETBIOS_BROWSER_RUNNING)
1039 		(void) cond_wait(&nb_status.cv, &nb_status.mtx);
1040 	(void) mutex_unlock(&nb_status.mtx);
1041 
1042 	(void) close(datagram_sock);
1043 	smb_netbios_datagram_fini();
1044 	syslog(LOG_DEBUG, "smbd: Netbios Datagram Service is down\n");
1045 	return (0);
1046 }
1047 
1048 static char
1049 /* LINTED - E_STATIC_UNUSED */
1050 nb_fmt_flags(unsigned char flags)
1051 {
1052 	switch (flags & DATAGRAM_FLAGS_SRC_TYPE) {
1053 	case DATAGRAM_FLAGS_B_NODE:	return ('B');
1054 	case DATAGRAM_FLAGS_P_NODE:	return ('P');
1055 	case DATAGRAM_FLAGS_M_NODE:	return ('M');
1056 	case DATAGRAM_FLAGS_H_NODE:	return ('H');
1057 	default:	return ('?');
1058 	}
1059 }
1060