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