xref: /illumos-gate/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _SMB_NETBIOS_H_
27 #define	_SMB_NETBIOS_H_
28 
29 #include <stdio.h>
30 #include <synch.h>
31 #include <pthread.h>
32 #include <strings.h>
33 #include <netinet/in.h>
34 
35 #include <smbsrv/libsmbns.h>
36 
37 #include <smbsrv/smbinfo.h>
38 #include <smbsrv/netbios.h>
39 
40 #define	QUEUE_INSERT_TAIL(q, e) \
41 	((e)->back) = (void *)((q)->back);	\
42 	((e)->forw) = (void *)(q);		\
43 	((q)->back->forw) = (void *)(e);	\
44 	((q)->back) = (void *)(e);
45 
46 #define	QUEUE_CLIP(e) \
47 	(e)->forw->back = (e)->back;	\
48 	(e)->back->forw = (e)->forw;	\
49 	(e)->forw = 0;			\
50 	(e)->back = 0;
51 
52 #define	NETBIOS_NAME_SVC_LAUNCHED	0x00001
53 #define	NETBIOS_NAME_SVC_RUNNING	0x00002
54 #define	NETBIOS_NAME_SVC_FAILED		0x00004
55 
56 #define	NETBIOS_DATAGRAM_SVC_LAUNCHED	0x00010
57 #define	NETBIOS_DATAGRAM_SVC_RUNNING	0x00020
58 #define	NETBIOS_DATAGRAM_SVC_FAILED	0x00040
59 
60 #define	NETBIOS_TIMER_LAUNCHED		0x00100
61 #define	NETBIOS_TIMER_RUNNING		0x00200
62 #define	NETBIOS_TIMER_FAILED		0x00400
63 
64 #define	NETBIOS_BROWSER_LAUNCHED	0x01000
65 #define	NETBIOS_BROWSER_RUNNING		0x02000
66 #define	NETBIOS_BROWSER_FAILED		0x04000
67 
68 #define	NETBIOS_SHUTTING_DOWN		0x10000
69 #define	NETBIOS_SHUT_DOWN		0x20000
70 
71 char smb_node_type;
72 
73 #define	SMB_NODETYPE_B	'B'
74 #define	SMB_NODETYPE_P	'P'
75 #define	SMB_NODETYPE_M	'M'
76 #define	SMB_NODETYPE_H	'H'
77 
78 typedef struct {
79 	mutex_t mtx;
80 	cond_t cv;
81 	uint32_t state;
82 } netbios_status_t;
83 extern netbios_status_t nb_status;
84 
85 /*
86  * NAME service definitions
87  */
88 #define	ADDR_FLAG_INVALID		0x0000
89 #define	ADDR_FLAG_VALID		0x0001
90 
91 typedef struct addr_entry {
92 	struct addr_entry 	*forw;
93 	struct addr_entry 	*back;
94 	uint32_t		attributes;
95 	uint32_t		conflict_timer;
96 	uint32_t		refresh_ttl;
97 	uint32_t		ttl;
98 	struct sockaddr_in	sin;
99 	int			sinlen;
100 	uint32_t 		flags;
101 } addr_entry_t;
102 
103 /*
104  *   The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
105  *   of NODE_NAME records.  Each NODE_NAME entry represents an active
106  *   name in the same NetBIOS scope as the requesting name in the
107  *   local name table of the responder.  RR_NAME is the requesting
108  *   name.
109  *
110  *   NODE_NAME Entry:
111  *
112  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
113  *    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
114  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115  *   |                                                               |
116  *   +---                                                         ---+
117  *   |                                                               |
118  *   +---                    NETBIOS FORMAT NAME                  ---+
119  *   |                                                               |
120  *   +---                                                         ---+
121  *   |                                                               |
122  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123  *   |         NAME_FLAGS            |
124  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125  *
126  *   The NAME_FLAGS field:
127  *
128  *                                             1   1   1   1   1   1
129  *     0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
130  *   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
131  *   | G |  ONT  |DRG|CNF|ACT|PRM|          RESERVED                 |
132  *   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
133  *
134  *   The NAME_FLAGS field is defined as:
135  *
136  *   Symbol     Bit(s)   Description:
137  *
138  *   RESERVED     7-15   Reserved for future use.  Must be zero (0).
139  *   PRM             6   Permanent Name Flag.  If one (1) then entry
140  *                       is for the permanent node name.  Flag is zero
141  *                       (0) for all other names.
142  *   ACT             5   Active Name Flag.  All entries have this flag
143  *                       set to one (1).
144  *   CNF             4   Conflict Flag.  If one (1) then name on this
145  *                       node is in conflict.
146  *   DRG             3   Deregister Flag.  If one (1) then this name
147  *                       is in the process of being deleted.
148  *   ONT           1,2   Owner Node Type:
149  *                          00 = B node
150  *                          01 = P node
151  *                          10 = M node
152  *                          11 = Reserved for future use
153  *   G               0   Group Name Flag.
154  *                       name.
155  *                       If zero (0) then it is a UNIQUE NetBIOS name.
156  */
157 
158 typedef struct name_entry {
159 	struct name_entry 	*forw;
160 	struct name_entry 	*back;
161 	unsigned char		name[NETBIOS_NAME_SZ];
162 	unsigned char		scope[NETBIOS_DOMAIN_NAME_MAX];
163 	unsigned short		attributes;
164 	struct addr_entry	addr_list;
165 	mutex_t			mtx;
166 } name_entry_t;
167 
168 struct name_question {
169 	struct name_entry 	*name;
170 	unsigned		question_type;
171 	unsigned		question_class;
172 };
173 
174 struct resource_record {
175 	/*
176 	 * These two flags and address are contained within RDATA
177 	 * when rr_type==0x0020 (NB - NetBIOS general Name Service)
178 	 * and rr_class==0x01 (IN - Internet Class).
179 	 */
180 
181 	struct name_entry *name;
182 	unsigned short rr_type;
183 	unsigned short rr_class;
184 	uint32_t ttl;
185 	unsigned short rdlength;
186 	unsigned char *rdata;
187 };
188 
189 struct name_packet {
190 	unsigned short		name_trn_id;
191 	unsigned short		info;
192 
193 	unsigned		qdcount;	/* question entries */
194 	unsigned		ancount;	/* answer recs */
195 	unsigned		nscount;	/* authority recs */
196 	unsigned		arcount;	/* additional recs */
197 
198 	struct name_question 	*question;
199 	struct resource_record 	*answer;
200 	struct resource_record 	*authority;
201 	struct resource_record 	*additional;
202 
203 	unsigned char			block_data[4];	/* begining of space */
204 };
205 
206 #define	NAME_OPCODE_R		0x8000	/* RESPONSE flag: 1 bit */
207 #define	NAME_OPCODE_OPCODE_MASK	0x7800	/* OPCODE Field: 4 bits */
208 #define	NAME_OPCODE_QUERY	0x0000
209 #define	NAME_OPCODE_REGISTRATION	0x2800
210 #define	NAME_OPCODE_RELEASE	0x3000
211 #define	NAME_OPCODE_WACK	0x3800
212 #define	NAME_OPCODE_REFRESH	0x4000
213 #define	NAME_OPCODE_MULTIHOME	0x7800
214 #define	NAME_NM_FLAGS_AA	0x0400	/* Authoritative Answer:1 bit */
215 #define	NAME_NM_FLAGS_TC	0x0200	/* Truncation:		1 bit */
216 #define	NAME_NM_FLAGS_RD	0x0100	/* Recursion desired:	1 bit */
217 #define	NAME_NM_FLAGS_RA	0x0080	/* Recursion available:	1 bit */
218 #define	NAME_NM_FLAGS_x2	0x0040	/* reserved, mbz:	1 bit */
219 #define	NAME_NM_FLAGS_x1	0x0020	/* reserved, mbz:	1 bit */
220 #define	NAME_NM_FLAGS_B		0x0010	/* Broadcast:		1 bit */
221 #define	NAME_RCODE_MASK		0x000f	/* RCODE Field:		4 bits */
222 #define	RCODE_FMT_ERR		0x0001
223 #define	RCODE_SRV_ERR		0x0002
224 #define	RCODE_NAM_ERR		0x0003
225 #define	RCODE_IMP_ERR		0x0004
226 #define	RCODE_RFS_ERR		0x0005
227 #define	RCODE_ACT_ERR		0x0006
228 #define	RCODE_CFT_ERR		0x0007
229 
230 #define	NM_FLAGS_UNICAST		0
231 #define	NM_FLAGS_BROADCAST		NAME_NM_FLAGS_B
232 
233 #define	PACKET_TYPE(x)	((x) & (NAME_OPCODE_R | NAME_OPCODE_OPCODE_MASK | \
234 			NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD))
235 
236 #define	RCODE(x)		((x) & NAME_RCODE_MASK)
237 #define	POSITIVE_RESPONSE(x)	(RCODE(x) == 0)
238 #define	NEGATIVE_RESPONSE(x)	(RCODE(x) != 0)
239 
240 #define	END_NODE_CHALLENGE_REGISTRATION_REQUEST				\
241 	    (NAME_OPCODE_REGISTRATION | NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD)
242 #define	END_NODE_CHALLENGE_NAME_REGISTRATION_RESPONSE			\
243 	    (NAME_OPCODE_R | END_NODE_CHALLENGE_REGISTRATION_REQUEST)
244 
245 #define	NAME_QUERY_REQUEST						\
246 	    (NAME_OPCODE_QUERY | NAME_NM_FLAGS_RD)
247 #define	NAME_QUERY_RESPONSE						\
248 	    (NAME_OPCODE_R | NAME_QUERY_REQUEST |			\
249 	    NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD)
250 
251 #define	NODE_STATUS_REQUEST						\
252 	    (NAME_OPCODE_QUERY)
253 #define	NODE_STATUS_RESPONSE						\
254 	    (NAME_OPCODE_R | NODE_STATUS_REQUEST | NAME_NM_FLAGS_AA)
255 
256 #define	REDIRECT_NAME_QUERY_RESPONSE					\
257 	    (NAME_OPCODE_R | NAME_QUERY_REQUEST | NAME_NM_FLAGS_RD)
258 
259 #define	NAME_REFRESH_REQUEST						\
260 	    (NAME_OPCODE_REFRESH)
261 #define	NAME_REGISTRATION_REQUEST					\
262 	    (NAME_OPCODE_REGISTRATION | NAME_NM_FLAGS_RD)
263 #define	NAME_MULTIHOME_REGISTRATION_REQUEST				\
264 	    (NAME_OPCODE_MULTIHOME | NAME_NM_FLAGS_RD)
265 #define	NAME_REGISTRATION_RESPONSE					\
266 	    (NAME_OPCODE_R | NAME_REGISTRATION_REQUEST | NAME_NM_FLAGS_AA)
267 
268 #define	NAME_RELEASE_REQUEST						\
269 	    (NAME_OPCODE_RELEASE)
270 #define	NAME_RELEASE_RESPONSE						\
271 	    (NAME_OPCODE_R | NAME_RELEASE_REQUEST | NAME_NM_FLAGS_AA)
272 
273 #define	WACK_RESPONSE						\
274 	    (NAME_OPCODE_R | NAME_OPCODE_WACK | NAME_NM_FLAGS_AA)
275 
276 #define	NAME_QUESTION_TYPE_NB		0x0020
277 #define	NAME_QUESTION_TYPE_NBSTAT	0x0021
278 #define	NAME_QUESTION_CLASS_IN		0x0001
279 
280 
281 #define	NAME_RR_TYPE_A			0x0001	/* IP Address */
282 #define	NAME_RR_TYPE_NS			0x0002	/* Name Server */
283 #define	NAME_RR_TYPE_NULL		0x000A	/* NULL */
284 #define	NAME_RR_TYPE_NB			0x0020	/* NetBIOS Name Service */
285 #define	NAME_RR_TYPE_NBSTAT		0x0021	/* NetBIOS Node Status */
286 
287 #define	NAME_RR_CLASS_IN		0x0001	/* NetBIOS Node Status */
288 
289 #define	NAME_NB_FLAGS_ONT_MASK		(3<<13)
290 #define	NAME_NB_FLAGS_ONT_B		(0<<13) /* B-node (broadcast) */
291 #define	NAME_NB_FLAGS_ONT_P		(1<<13)	/* P-node (point-to-point) */
292 #define	NAME_NB_FLAGS_ONT_M		(2<<13)	/* M-node (multicast) */
293 #define	NAME_NB_FLAGS_ONT_resv		(3<<13)
294 #define	NAME_NB_FLAGS_G			(1<<15)	/* Group Name */
295 
296 #define	UNICAST				0
297 #define	BROADCAST			1
298 #define	POINTCAST			2
299 
300 #define	NAME_ATTR_UNIQUE		0x0000
301 #define	NAME_ATTR_GROUP			0x8000
302 #define	NAME_ATTR_OWNER_NODE_TYPE	0x6000
303 #define	  NAME_ATTR_OWNER_TYPE_BNODE	  0x0000
304 #define	  NAME_ATTR_OWNER_TYPE_PNODE	  0x2000
305 #define	  NAME_ATTR_OWNER_TYPE_MNODE	  0x4000
306 #define	  NAME_ATTR_OWNER_TYPE_HNODE	  0x6000
307 #define	NAME_ATTR_DEREGISTER		0x1000
308 #define	NAME_ATTR_CONFLICT		0x0800
309 #define	NAME_ATTR_ACTIVE_NAME		0x0400
310 #define	NAME_ATTR_PERMANENT		0x0200
311 #define	NAME_ATTR_RESERVED		0x01FF
312 #define	NAME_ATTR_LOCAL			0x0001
313 
314 #define	NODE_TYPE(x)		((x) & NAME_ATTR_OWNER_NODE_TYPE))
315 #define	IS_BNODE(x)		(NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_BNODE)
316 #define	IS_PNODE(x)		(NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_PNODE)
317 #define	IS_MNODE(x)		(NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_MNODE)
318 #define	IS_HNODE(x)		(NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_HNODE)
319 
320 #define	IS_UNIQUE(x)		(((x) & NAME_ATTR_GROUP) == 0)
321 #define	IS_GROUP(x)		(((x) & NAME_ATTR_GROUP) != 0)
322 #define	IS_PERMANENT(x)		(((x) & NAME_ATTR_PERMANENT) != 0)
323 #define	IS_CONFLICTING(x)	(((x) & NAME_ATTR_CONFLICT) != 0)
324 #define	IS_ACTIVE(x)		(((x) & NAME_ATTR_ACTIVE) != 0)
325 #define	IS_DEGREGISTERED(x)	(((x) & NAME_ATTR_ACTIVE) != 0)
326 
327 #define	IS_LOCAL(x)		(((x) & NAME_ATTR_LOCAL) != 0)
328 #define	IS_PUBLIC(x)		(((x) & NAME_ATTR_LOCAL) == 0)
329 #define	PUBLIC_BITS(x)		((x) & ~NAME_ATTR_RESERVED)
330 
331 #define	SAME_SCOPE(scope, e)	(strcmp((scope), ((e)->scope)) == 0)
332 
333 /*
334  *   STATISTICS Field of the NODE STATUS RESPONSE:
335  *
336  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
337  *    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
338  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
339  *   |               UNIT_ID (Unique unit ID)                        |
340  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
341  *   |       UNIT_ID,continued       |    JUMPERS    |  TEST_RESULT  |
342  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
343  *   |       VERSION_NUMBER          |      PERIOD_OF_STATISTICS     |
344  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
345  *   |       NUMBER_OF_CRCs          |     NUMBER_ALIGNMENT_ERRORS   |
346  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
347  *   |       NUMBER_OF_COLLISIONS    |        NUMBER_SEND_ABORTS     |
348  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
349  *   |                       NUMBER_GOOD_SENDS                       |
350  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
351  *   |                      NUMBER_GOOD_RECEIVES                     |
352  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
353  *   |       NUMBER_RETRANSMITS      | NUMBER_NO_RESOURCE_CONDITIONS |
354  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
355  *   |  NUMBER_FREE_COMMAND_BLOCKS   |  TOTAL_NUMBER_COMMAND_BLOCKS  |
356  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
357  *   |MAX_TOTAL_NUMBER_COMMAND_BLOCKS|    NUMBER_PENDING_SESSIONS    |
358  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
359  *   |  MAX_NUMBER_PENDING_SESSIONS  |  MAX_TOTAL_SESSIONS_POSSIBLE  |
360  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
361  *   |   SESSION_DATA_PACKET_SIZE    |
362  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363  */
364 
365 typedef struct {
366 	unsigned char	unit_id[6];
367 	unsigned char	jumpers;
368 	unsigned char	test_result;
369 	unsigned short	version_number;
370 	unsigned short	statistical_period;
371 	unsigned short	crc_errors;
372 	unsigned short	alignment_errors;
373 	unsigned short	collisions;
374 	unsigned short	send_aborts;
375 	unsigned int	good_sends;
376 	unsigned int	good_receives;
377 	unsigned short	retransmits;
378 	unsigned short	no_resource_conditions;
379 	unsigned short	free_command_blocks;
380 	unsigned short	total_command_blocks;
381 	unsigned short	max_total_command_blocks;
382 	unsigned short	pending_sessions;
383 	unsigned short	max_pending_sessions;
384 	unsigned short	total_possible_sessions;
385 	unsigned short	session_data_packet_size;
386 } node_status_response;
387 
388 /*
389  * 4.4.1.  NetBIOS DATAGRAM HEADER
390  *
391  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
392  *     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
393  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
394  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
395  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
396  *    |                           SOURCE_IP                           |
397  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
398  *    |          SOURCE_PORT          |          DGM_LENGTH           |
399  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
400  *    |         PACKET_OFFSET         |
401  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
402  */
403 typedef struct {
404 	unsigned char	msg_type;
405 	unsigned char	flags;
406 	unsigned short	dgm_id;
407 	uint32_t	source_ip;
408 	unsigned short	source_port;
409 	unsigned short	dgm_length;
410 	unsigned short	packet_offset;
411 } datagram_header;
412 
413 /*
414  *    MSG_TYPE values (in hexidecimal):
415  *
416  *            10 -  DIRECT_UNIQUE DATAGRAM
417  *            11 -  DIRECT_GROUP DATAGRAM
418  *            12 -  BROADCAST DATAGRAM
419  *            13 -  DATAGRAM ERROR
420  *            14 -  DATAGRAM QUERY REQUEST
421  *            15 -  DATAGRAM POSITIVE QUERY RESPONSE
422  *            16 -  DATAGRAM NEGATIVE QUERY RESPONSE
423  */
424 #define	DATAGRAM_TYPE_DIRECT_UNIQUE	0x10
425 #define	DATAGRAM_TYPE_DIRECT_GROUP	0x11
426 #define	DATAGRAM_TYPE_BROADCAST		0x12
427 #define	DATAGRAM_TYPE_ERROR_DATAGRAM	0x13
428 #define	DATAGRAM_TYPE_QUERY_REQUEST	0x14
429 #define	DATAGRAM_TYPE_POSITIVE_RESPONSE	0x15
430 #define	DATAGRAM_TYPE_NEGATIVE_RESPONSE	0x16
431 
432 
433 /*
434  *    Bit definitions of the FLAGS field:
435  *
436  *      0   1   2   3   4   5   6   7
437  *    +---+---+---+---+---+---+---+---+
438  *    | 0 | 0 | 0 | 0 |  SNT  | F | M |
439  *    +---+---+---+---+---+---+---+---+
440  *
441  *    Symbol     Bit(s)   Description
442  *
443  *    M               7   MORE flag, If set then more NetBIOS datagram
444  *                        fragments follow.
445  *
446  *    F               6   FIRST packet flag,  If set then this is first
447  *                        (and possibly only) fragment of NetBIOS
448  *                        datagram
449  *
450  *    SNT           4,5   Source End-Node type:
451  *                           00 = B node
452  *                           01 = P node
453  *                           10 = M node
454  *                           11 = H node
455  *    RESERVED      0-3   Reserved, must be zero (0)
456  */
457 #define	DATAGRAM_FLAGS_MORE	0x01
458 #define	DATAGRAM_FLAGS_FIRST	0x02
459 #define	DATAGRAM_FLAGS_SRC_TYPE	0x0c
460 #define	DATAGRAM_FLAGS_B_NODE	  0x00
461 #define	DATAGRAM_FLAGS_P_NODE	  0x04
462 #define	DATAGRAM_FLAGS_M_NODE	  0x08
463 #define	DATAGRAM_FLAGS_H_NODE	  0x0C
464 #define	DATAGRAM_FLAGS_NBDD	  0x0c
465 #define	DATAGRAM_FLAGS_RESERVED	0xf0
466 
467 /*
468  * 4.4.2.  DIRECT_UNIQUE, DIRECT_GROUP, & BROADCAST DATAGRAM
469  *
470  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
471  *     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
472  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
473  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
474  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
475  *    |                           SOURCE_IP                           |
476  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
477  *    |          SOURCE_PORT          |          DGM_LENGTH           |
478  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
479  *    |         PACKET_OFFSET         |                               |
480  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
481  *    |                                                               |
482  *    /                          SOURCE_NAME                          /
483  *    /                                                               /
484  *    |                                                               |
485  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
486  *    |                                                               |
487  *    /                       DESTINATION_NAME                        /
488  *    /                                                               /
489  *    |                                                               |
490  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
491  *    |                                                               |
492  *    /                           USER_DATA                           /
493  *    /                                                               /
494  *    |                                                               |
495  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
496  */
497 typedef struct {
498 	datagram_header	header;
499 	unsigned char	*source_name;
500 	unsigned char	*destination_name;
501 	unsigned char	*user_data;
502 } datagram_packet;
503 
504 
505 /*
506  *    4.4.3.  DATAGRAM ERROR PACKET
507  *
508  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
509  *     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
510  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
511  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
512  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
513  *    |                           SOURCE_IP                           |
514  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
515  *    |          SOURCE_PORT          |  ERROR_CODE   |
516  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
517  *
518  *    ERROR_CODE values (in hexidecimal):
519  *
520  *            82 -  DESTINATION NAME NOT PRESENT
521  *            83 -  INVALID SOURCE NAME FORMAT
522  *            84 -  INVALID DESTINATION NAME FORMAT
523  */
524 
525 typedef struct {
526 	unsigned char	msg_type;
527 	unsigned char	flags;
528 	unsigned short	dgm_id;
529 	uint32_t	source_ip;
530 	unsigned short	source_port;
531 	unsigned char	error;
532 } datagram_error_packet;
533 
534 /*
535  * 4.4.4.  DATAGRAM QUERY REQUEST
536  *
537  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
538  *     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
539  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
540  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
541  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
542  *    |                           SOURCE_IP                           |
543  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
544  *    |          SOURCE_PORT          |                               |
545  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
546  *    |                                                               |
547  *    /                       DESTINATION_NAME                        /
548  *    /                                                               /
549  *    |                                                               |
550  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
551  *
552  * 4.4.5.  DATAGRAM POSITIVE AND NEGATIVE QUERY RESPONSE
553  *
554  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
555  *     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
556  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
557  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
558  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
559  *    |                           SOURCE_IP                           |
560  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
561  *    |          SOURCE_PORT          |                               |
562  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
563  *    |                                                               |
564  *    /                       DESTINATION_NAME                        /
565  *    /                                                               /
566  *    |                                                               |
567  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
568  */
569 
570 typedef struct datagram_query_packet {
571 	unsigned char	msg_type;
572 	unsigned char	flags;
573 	unsigned short	dgm_id;
574 	uint32_t	source_ip;
575 	unsigned short	source_port;
576 	unsigned char	destination_name[MAX_NAME_LENGTH];
577 } datagram_query_packet;
578 
579 
580 typedef struct datagram {
581 	struct datagram 	*forw;
582 	struct datagram 	*back;
583 	struct addr_entry	inaddr;
584 	int			discard_timer;
585 	unsigned char		packet_type;
586 	unsigned char		flags;
587 	unsigned short		datagram_id;
588 	struct name_entry	src;
589 	struct name_entry	dest;
590 	unsigned short		offset;
591 	unsigned short		data_length;
592 	unsigned char 		*data;
593 	unsigned int		rawbytes;
594 	unsigned char		rawbuf[MAX_DATAGRAM_LENGTH];
595 } datagram;
596 
597 typedef struct datagram_queue {
598 	struct datagram 	*forw;
599 	struct datagram 	*back;
600 } datagram_queue;
601 
602 typedef struct name_queue {
603 	struct name_entry head;
604 	mutex_t mtx;
605 } name_queue_t;
606 
607 typedef struct nbcache_iter {
608 	HT_ITERATOR		nbc_hti;
609 	struct name_entry	*nbc_entry;
610 } nbcache_iter_t;
611 
612 #define	NETBIOS_EMPTY_NAME (unsigned char *)""
613 
614 #define	NETBIOS_NAME_IS_STAR(name) \
615 	(bcmp(name, "*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NETBIOS_NAME_SZ) == 0)
616 
617 void smb_netbios_chg_status(uint32_t status, int set);
618 
619 /*
620  * Name Cache Functions
621  */
622 int  smb_netbios_cache_init(void);
623 void smb_netbios_cache_fini(void);
624 void smb_netbios_cache_dump(void);
625 int smb_netbios_cache_count(void);
626 void smb_netbios_cache_clean(void);
627 void smb_netbios_cache_reset_ttl(void);
628 void smb_netbios_cache_delete_locals(name_queue_t *);
629 void smb_netbios_cache_refresh(name_queue_t *);
630 
631 int smb_netbios_cache_insert(struct name_entry *name);
632 int smb_netbios_cache_insert_list(struct name_entry *name);
633 void smb_netbios_cache_delete(struct name_entry *name);
634 int smb_netbios_cache_delete_addr(struct name_entry *name);
635 struct name_entry *smb_netbios_cache_lookup(struct name_entry *name);
636 struct name_entry *smb_netbios_cache_lookup_addr(struct name_entry *name);
637 void smb_netbios_cache_update_entry(struct name_entry *, struct name_entry *);
638 void smb_netbios_cache_unlock_entry(struct name_entry *);
639 unsigned char *smb_netbios_cache_status(unsigned char *, int, unsigned char *);
640 int smb_netbios_cache_getfirst(nbcache_iter_t *);
641 int smb_netbios_cache_getnext(nbcache_iter_t *);
642 
643 void smb_netbios_name_dump(struct name_entry *entry);
644 void smb_netbios_name_logf(struct name_entry *entry);
645 void smb_netbios_name_freeaddrs(struct name_entry *entry);
646 struct name_entry *smb_netbios_name_dup(struct name_entry *, int);
647 
648 /* Name service functions */
649 void *smb_netbios_name_service_daemon(void *);
650 void smb_init_name_struct(unsigned char *, char, unsigned char *, uint32_t,
651     unsigned short, uint32_t, uint32_t, struct name_entry *);
652 
653 struct name_entry *smb_name_find_name(struct name_entry *name);
654 int smb_name_add_name(struct name_entry *name);
655 int smb_name_delete_name(struct name_entry *name);
656 void smb_name_unlock_name(struct name_entry *name);
657 
658 void smb_netbios_name_config(void);
659 void smb_netbios_name_unconfig(void);
660 void smb_netbios_name_tick(void);
661 
662 int smb_first_level_name_encode(struct name_entry *, unsigned char *, int);
663 int smb_first_level_name_decode(unsigned char *, struct name_entry *);
664 void smb_encode_netbios_name(unsigned char *, char, unsigned char *,
665     struct name_entry *);
666 
667 /* Datagram service functions */
668 void *smb_netbios_datagram_service_daemon(void *);
669 int smb_netbios_datagram_send(struct name_entry *,
670     struct name_entry *, unsigned char *, int);
671 void smb_netbios_datagram_tick(void);
672 
673 /* browser functions */
674 void *smb_browser_dispatch(void *arg);
675 void *smb_browser_daemon(void *);
676 int smb_browser_load_transact_header(unsigned char *, int, int, int, char *);
677 
678 /* Netlogon function */
679 void smb_netlogon_receive(struct datagram *, char *, unsigned char *, int);
680 void smb_netlogon_request(struct name_entry *, char *);
681 
682 #endif /* _SMB_NETBIOS_H_ */
683