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