xref: /illumos-gate/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c (revision 7b59d02d2a384be9a08087b14defadd214b3c1dd)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Description:
30  *
31  *	Contains base code for netbios datagram service.
32  *
33  * Relavent sections from RFC1002:
34  *
35  *  5.3.  NetBIOS DATAGRAM SERVICE PROTOCOLS
36  *
37  *   The following are GLOBAL variables and should be NetBIOS user
38  *   configurable:
39  *
40  *   - SCOPE_ID: the non-leaf section of the domain name preceded by a
41  *     '.'  which represents the domain of the NetBIOS scope for the
42  *     NetBIOS name.  The following protocol description only supports
43  *     single scope operation.
44  *
45  *   - MAX_DATAGRAM_LENGTH: the maximum length of an IP datagram.  The
46  *     minimal maximum length defined in for IP is 576 bytes.  This
47  *     value is used when determining whether to fragment a NetBIOS
48  *     datagram.  Implementations are expected to be capable of
49  *     receiving unfragmented NetBIOS datagrams up to their maximum
50  *     size.
51  *
52  *   - BROADCAST_ADDRESS: the IP address B-nodes use to send datagrams
53  *     with group name destinations and broadcast datagrams.  The
54  *     default is the IP broadcast address for a single IP network.
55  *
56  *
57  *   The following are Defined Constants for the NetBIOS Datagram
58  *   Service:
59  *
60  *   - DGM_SRVC_UDP_PORT: the globally well-known UDP port allocated
61  *     where the NetBIOS Datagram Service receives UDP packets.  See
62  *     section 6, "Defined Constants", for its value.
63  */
64 
65 /*
66  *
67  *  6.  DEFINED CONSTANTS AND VARIABLES
68  *
69  *   GENERAL:
70  *
71  *      SCOPE_ID                   The name of the NetBIOS scope.
72  *
73  *                                 This is expressed as a character
74  *                                 string meeting the requirements of
75  *                                 the domain name system and without
76  *                                 a leading or trailing "dot".
77  *
78  *                                 An implementation may elect to make
79  *                                 this a single global value for the
80  *                                 node or allow it to be specified
81  *                                 with each separate NetBIOS name
82  *                                 (thus permitting cross-scope
83  *                                 references.)
84  *
85  *      BROADCAST_ADDRESS          An IP address composed of the
86  *                                 node network and subnetwork
87  *                                 numbers with all remaining bits set
88  *                                 to one.
89  *
90  *                                 I.e. "Specific subnet" broadcast
91  *                                 addressing according to section 2.3
92  *                                 of RFC 950.
93  *
94  *      BCAST_REQ_RETRY_TIMEOUT    250 milliseconds.
95  *                                 An adaptive timer may be used.
96  *
97  *      BCAST_REQ_RETRY_COUNT      3
98  *
99  *      UCAST_REQ_RETRY_TIMEOUT    5 seconds
100  *                                 An adaptive timer may be used.
101  *
102  *      UCAST_REQ_RETRY_COUNT      3
103  *
104  *      MAX_DATAGRAM_LENGTH        576 bytes (default)
105  *
106  *   DATAGRAM SERVICE:
107  *
108  *      DGM_SRVC_UDP_PORT          138 (decimal)
109  *
110  *      FRAGMENT_TO                2 seconds (default)
111  */
112 
113 #include <stdlib.h>
114 #include <unistd.h>
115 #include <string.h>
116 #include <strings.h>
117 #include <syslog.h>
118 #include <synch.h>
119 #include <sys/socket.h>
120 #include <arpa/inet.h>
121 
122 #include <smbns_netbios.h>
123 
124 #include <smbsrv/libsmbns.h>
125 
126 static int datagram_sock = -1;
127 static short datagram_id = 1;
128 static struct datagram_queue smb_datagram_queue;
129 static mutex_t smb_dgq_mtx;
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 	uint32_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 = addr->sin.sin_addr.s_addr;
379 		/* Don't send anything to myself... */
380 		if (smb_nic_exists(ipaddr, B_FALSE))
381 			goto next;
382 
383 		sin.sin_addr.s_addr = ipaddr;
384 		sin.sin_port = addr->sin.sin_port;
385 		(void) sendto(datagram_sock, buffer, count, 0,
386 		    (struct sockaddr *)&sin, sinlen);
387 
388 next:		addr = addr->forw;
389 	} while (addr != &dest->addr_list);
390 	free(buffer);
391 	return (0);
392 }
393 
394 
395 int
396 smb_netbios_datagram_send_to_net(struct name_entry *src,
397     struct name_entry *dest, char *data, int length)
398 {
399 	uint32_t ipaddr;
400 	size_t count, srclen, destlen, sinlen;
401 	struct addr_entry *addr;
402 	struct sockaddr_in sin;
403 	char *buffer;
404 	char ha_source[NETBIOS_DOMAIN_NAME_MAX];
405 	char ha_dest[NETBIOS_DOMAIN_NAME_MAX];
406 
407 	(void) smb_first_level_name_encode(src, (unsigned char *)ha_source,
408 	    sizeof (ha_source));
409 	srclen = strlen(ha_source) + 1;
410 
411 	(void) smb_first_level_name_encode(dest, (unsigned char *)ha_dest,
412 	    sizeof (ha_dest));
413 	destlen = strlen(ha_dest) + 1;
414 
415 	/* give some extra room */
416 	buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4);
417 	if (buffer == 0) {
418 		syslog(LOG_ERR, "netbios: datagram send (resource shortage)");
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 = addr->sin.sin_addr.s_addr;
459 		if (smb_nic_exists(ipaddr, B_FALSE))
460 			goto next;
461 
462 		sin.sin_addr.s_addr = ipaddr;
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 
955 	(void) mutex_lock(&smb_dgq_mtx);
956 	bzero(&smb_datagram_queue, sizeof (smb_datagram_queue));
957 	smb_datagram_queue.forw = smb_datagram_queue.back =
958 	    (struct datagram *)((uintptr_t)&smb_datagram_queue);
959 	(void) mutex_unlock(&smb_dgq_mtx);
960 
961 	if ((datagram_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
962 		syslog(LOG_ERR,
963 		    "smbd: Could not create AF_INET, SOCK_DGRAM, socket");
964 		smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
965 		return (0);
966 	}
967 
968 	bzero(&sin, sizeof (sin));
969 	sin.sin_family = AF_INET;
970 	sin.sin_port = htons(DGM_SRVC_UDP_PORT);
971 	if (bind(datagram_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) {
972 		syslog(LOG_ERR, "smbd: Bind to name service port %d failed",
973 		    DGM_SRVC_UDP_PORT);
974 		(void) close(datagram_sock);
975 		smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
976 		return (0);
977 	}
978 	(void) setsockopt(datagram_sock, SOL_SOCKET, SO_BROADCAST, &flag,
979 	    sizeof (flag));
980 
981 	smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 1);
982 
983 	while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) ||
984 	    (nb_status.state & NETBIOS_BROWSER_RUNNING)) {
985 		if ((datagram = (struct datagram *)
986 		    malloc(sizeof (struct datagram))) == 0) {
987 			/* Sleep for 10 sec and try again */
988 			(void) sleep(10);
989 			continue;
990 		}
991 
992 ignore:		bzero(&datagram->inaddr, sizeof (struct addr_entry));
993 		datagram->inaddr.sinlen = sizeof (datagram->inaddr.sin);
994 		datagram->inaddr.forw = datagram->inaddr.back =
995 		    &datagram->inaddr;
996 
997 		if ((bytes = recvfrom(datagram_sock, datagram->rawbuf,
998 		    MAX_DATAGRAM_LENGTH, 0,
999 		    (struct sockaddr *)&datagram->inaddr.sin,
1000 		    &datagram->inaddr.sinlen)) < 0) {
1001 			syslog(LOG_ERR,
1002 			    "smbd: NETBIOS datagram - recvfrom failed");
1003 			smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
1004 			break;
1005 		}
1006 
1007 		/* Ignore any incoming packets from myself... */
1008 		if (smb_nic_exists(datagram->inaddr.sin.sin_addr.s_addr,
1009 		    B_FALSE)) {
1010 			goto ignore;
1011 		}
1012 
1013 		if (smb_datagram_decode(datagram, bytes) < 0)
1014 			goto ignore;
1015 
1016 	/*
1017 	 * This code was doing the wrong thing with responses from a
1018 	 * Windows2000 PDC because both DATAGRAM_FLAGS_H_NODE and
1019 	 * DATAGRAM_FLAGS_NBDD are defined to be the same value (see
1020 	 * netbios.h). Since the Windows2000 PDC wants to be an H-Node,
1021 	 * we need to handle all messages via smb_netbios_BPM_datagram.
1022 	 *
1023 	 *	if ((datagram->flags & DATAGRAM_FLAGS_SRC_TYPE) ==
1024 	 *	    DATAGRAM_FLAGS_NBDD)
1025 	 *		smb_netbios_NBDD_datagram(datagram);
1026 	 *	else
1027 	 *		smb_netbios_BPM_datagram(datagram);
1028 	 */
1029 
1030 		smb_netbios_BPM_datagram(datagram);
1031 	}
1032 
1033 	smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 0);
1034 
1035 	(void) mutex_lock(&nb_status.mtx);
1036 	while (nb_status.state & NETBIOS_BROWSER_RUNNING)
1037 		(void) cond_wait(&nb_status.cv, &nb_status.mtx);
1038 	(void) mutex_unlock(&nb_status.mtx);
1039 
1040 	(void) close(datagram_sock);
1041 	smb_netbios_datagram_fini();
1042 	syslog(LOG_DEBUG, "smbd: Netbios Datagram Service is down\n");
1043 	return (0);
1044 }
1045 
1046 static char
1047 /* LINTED - E_STATIC_UNUSED */
1048 nb_fmt_flags(unsigned char flags)
1049 {
1050 	switch (flags & DATAGRAM_FLAGS_SRC_TYPE) {
1051 	case DATAGRAM_FLAGS_B_NODE:	return ('B');
1052 	case DATAGRAM_FLAGS_P_NODE:	return ('P');
1053 	case DATAGRAM_FLAGS_M_NODE:	return ('M');
1054 	case DATAGRAM_FLAGS_H_NODE:	return ('H');
1055 	default:	return ('?');
1056 	}
1057 }
1058