xref: /onnv-gate/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h (revision 10717:fe0545fc3cdd)
15331Samw /*
25331Samw  * CDDL HEADER START
35331Samw  *
45331Samw  * The contents of this file are subject to the terms of the
55331Samw  * Common Development and Distribution License (the "License").
65331Samw  * You may not use this file except in compliance with the License.
75331Samw  *
85331Samw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw  * or http://www.opensolaris.org/os/licensing.
105331Samw  * See the License for the specific language governing permissions
115331Samw  * and limitations under the License.
125331Samw  *
135331Samw  * When distributing Covered Code, include this CDDL HEADER in each
145331Samw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw  * If applicable, add the following below this CDDL HEADER, with the
165331Samw  * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw  * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw  *
195331Samw  * CDDL HEADER END
205331Samw  */
215331Samw /*
229832Samw@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
235331Samw  * Use is subject to license terms.
245331Samw  */
255331Samw 
265331Samw #ifndef _SMB_NETBIOS_H_
275331Samw #define	_SMB_NETBIOS_H_
285331Samw 
295331Samw #include <stdio.h>
305331Samw #include <synch.h>
315331Samw #include <pthread.h>
325331Samw #include <strings.h>
335331Samw #include <netinet/in.h>
345331Samw 
355331Samw #include <smbsrv/libsmbns.h>
365331Samw 
375331Samw #include <smbsrv/smbinfo.h>
385331Samw #include <smbsrv/netbios.h>
395331Samw 
405331Samw #define	QUEUE_INSERT_TAIL(q, e) \
415331Samw 	((e)->back) = (void *)((q)->back);	\
426030Sjb150015 	((e)->forw) = (void *)(q);		\
435331Samw 	((q)->back->forw) = (void *)(e);	\
445331Samw 	((q)->back) = (void *)(e);
455331Samw 
465331Samw #define	QUEUE_CLIP(e) \
475331Samw 	(e)->forw->back = (e)->back;	\
485331Samw 	(e)->back->forw = (e)->forw;	\
496030Sjb150015 	(e)->forw = 0;			\
505331Samw 	(e)->back = 0;
515331Samw 
52*10717Samw@Sun.COM typedef enum {
53*10717Samw@Sun.COM 	NETBIOS_EVENT_START = 0,
54*10717Samw@Sun.COM 	NETBIOS_EVENT_STOP,
55*10717Samw@Sun.COM 	NETBIOS_EVENT_RESET,
56*10717Samw@Sun.COM 	NETBIOS_EVENT_NS_START,
57*10717Samw@Sun.COM 	NETBIOS_EVENT_NS_STOP,
58*10717Samw@Sun.COM 	NETBIOS_EVENT_DGM_START,
59*10717Samw@Sun.COM 	NETBIOS_EVENT_DGM_STOP,
60*10717Samw@Sun.COM 	NETBIOS_EVENT_BROWSER_START,
61*10717Samw@Sun.COM 	NETBIOS_EVENT_BROWSER_STOP,
62*10717Samw@Sun.COM 	NETBIOS_EVENT_TIMER_START,
63*10717Samw@Sun.COM 	NETBIOS_EVENT_TIMER_STOP,
64*10717Samw@Sun.COM 	NETBIOS_EVENT_ERROR,
65*10717Samw@Sun.COM 	NETBIOS_EVENT_DUMP
66*10717Samw@Sun.COM } netbios_event_t;
675331Samw 
68*10717Samw@Sun.COM typedef enum {
69*10717Samw@Sun.COM 	NETBIOS_STATE_INIT = 0,
70*10717Samw@Sun.COM 	NETBIOS_STATE_RUNNING,
71*10717Samw@Sun.COM 	NETBIOS_STATE_CLOSING,
72*10717Samw@Sun.COM 	NETBIOS_STATE_ERROR
73*10717Samw@Sun.COM } netbios_state_t;
74*10717Samw@Sun.COM 
75*10717Samw@Sun.COM typedef struct {
76*10717Samw@Sun.COM 	pthread_t	s_tid;
77*10717Samw@Sun.COM 	boolean_t	s_up;
78*10717Samw@Sun.COM } netbios_svc_t;
795331Samw 
80*10717Samw@Sun.COM typedef struct {
81*10717Samw@Sun.COM 	mutex_t		nbs_mtx;
82*10717Samw@Sun.COM 	cond_t		nbs_cv;
83*10717Samw@Sun.COM 	netbios_svc_t	nbs_ns;
84*10717Samw@Sun.COM 	netbios_svc_t	nbs_dgm;
85*10717Samw@Sun.COM 	netbios_svc_t	nbs_browser;
86*10717Samw@Sun.COM 	netbios_svc_t	nbs_timer;
87*10717Samw@Sun.COM 	netbios_state_t	nbs_state;
88*10717Samw@Sun.COM 	uint32_t	nbs_errors;
89*10717Samw@Sun.COM 	char		*nbs_last_event;
90*10717Samw@Sun.COM } netbios_service_t;
915331Samw 
925331Samw char smb_node_type;
935331Samw 
946030Sjb150015 #define	SMB_NODETYPE_B	'B'
956030Sjb150015 #define	SMB_NODETYPE_P	'P'
966030Sjb150015 #define	SMB_NODETYPE_M	'M'
976030Sjb150015 #define	SMB_NODETYPE_H	'H'
986030Sjb150015 
995331Samw /*
1005331Samw  * NAME service definitions
1015331Samw  */
1025331Samw #define	ADDR_FLAG_INVALID		0x0000
1035331Samw #define	ADDR_FLAG_VALID		0x0001
1045331Samw 
1055331Samw typedef struct addr_entry {
1065331Samw 	struct addr_entry 	*forw;
1075331Samw 	struct addr_entry 	*back;
1085331Samw 	uint32_t		attributes;
1095331Samw 	uint32_t		conflict_timer;
1105331Samw 	uint32_t		refresh_ttl;
1115331Samw 	uint32_t		ttl;
1125331Samw 	struct sockaddr_in	sin;
1135331Samw 	int			sinlen;
1145331Samw 	uint32_t 		flags;
1155331Samw } addr_entry_t;
1165331Samw 
1175331Samw /*
1185331Samw  *   The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
1195331Samw  *   of NODE_NAME records.  Each NODE_NAME entry represents an active
1205331Samw  *   name in the same NetBIOS scope as the requesting name in the
1215331Samw  *   local name table of the responder.  RR_NAME is the requesting
1225331Samw  *   name.
1235331Samw  *
1245331Samw  *   NODE_NAME Entry:
1255331Samw  *
1265331Samw  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1275331Samw  *    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
1285331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1295331Samw  *   |                                                               |
1305331Samw  *   +---                                                         ---+
1315331Samw  *   |                                                               |
1325331Samw  *   +---                    NETBIOS FORMAT NAME                  ---+
1335331Samw  *   |                                                               |
1345331Samw  *   +---                                                         ---+
1355331Samw  *   |                                                               |
1365331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1375331Samw  *   |         NAME_FLAGS            |
1385331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1395331Samw  *
1405331Samw  *   The NAME_FLAGS field:
1415331Samw  *
1425331Samw  *                                             1   1   1   1   1   1
1435331Samw  *     0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
1445331Samw  *   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1455331Samw  *   | G |  ONT  |DRG|CNF|ACT|PRM|          RESERVED                 |
1465331Samw  *   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1475331Samw  *
1485331Samw  *   The NAME_FLAGS field is defined as:
1495331Samw  *
1505331Samw  *   Symbol     Bit(s)   Description:
1515331Samw  *
1525331Samw  *   RESERVED     7-15   Reserved for future use.  Must be zero (0).
1535331Samw  *   PRM             6   Permanent Name Flag.  If one (1) then entry
1545331Samw  *                       is for the permanent node name.  Flag is zero
1555331Samw  *                       (0) for all other names.
1565331Samw  *   ACT             5   Active Name Flag.  All entries have this flag
1575331Samw  *                       set to one (1).
1585331Samw  *   CNF             4   Conflict Flag.  If one (1) then name on this
1595331Samw  *                       node is in conflict.
1605331Samw  *   DRG             3   Deregister Flag.  If one (1) then this name
1615331Samw  *                       is in the process of being deleted.
1625331Samw  *   ONT           1,2   Owner Node Type:
1635331Samw  *                          00 = B node
1645331Samw  *                          01 = P node
1655331Samw  *                          10 = M node
1665331Samw  *                          11 = Reserved for future use
1675331Samw  *   G               0   Group Name Flag.
1685331Samw  *                       name.
1695331Samw  *                       If zero (0) then it is a UNIQUE NetBIOS name.
1705331Samw  */
1715331Samw 
1725331Samw typedef struct name_entry {
1735331Samw 	struct name_entry 	*forw;
1745331Samw 	struct name_entry 	*back;
1755331Samw 	unsigned char		name[NETBIOS_NAME_SZ];
1765331Samw 	unsigned char		scope[NETBIOS_DOMAIN_NAME_MAX];
1775331Samw 	unsigned short		attributes;
1785331Samw 	struct addr_entry	addr_list;
1795331Samw 	mutex_t			mtx;
1806030Sjb150015 } name_entry_t;
1815331Samw 
1825331Samw struct name_question {
1835331Samw 	struct name_entry 	*name;
1845331Samw 	unsigned		question_type;
1855331Samw 	unsigned		question_class;
1865331Samw };
1875331Samw 
1885331Samw struct resource_record {
1895331Samw 	/*
1905331Samw 	 * These two flags and address are contained within RDATA
1915331Samw 	 * when rr_type==0x0020 (NB - NetBIOS general Name Service)
1925331Samw 	 * and rr_class==0x01 (IN - Internet Class).
1935331Samw 	 */
1945331Samw 
1955331Samw 	struct name_entry *name;
1965331Samw 	unsigned short rr_type;
1975331Samw 	unsigned short rr_class;
1985331Samw 	uint32_t ttl;
1995331Samw 	unsigned short rdlength;
2005331Samw 	unsigned char *rdata;
2015331Samw };
2025331Samw 
2035331Samw struct name_packet {
2045331Samw 	unsigned short		name_trn_id;
2055331Samw 	unsigned short		info;
2065331Samw 
2075331Samw 	unsigned		qdcount;	/* question entries */
2085331Samw 	unsigned		ancount;	/* answer recs */
2095331Samw 	unsigned		nscount;	/* authority recs */
2105331Samw 	unsigned		arcount;	/* additional recs */
2115331Samw 
2125331Samw 	struct name_question 	*question;
2135331Samw 	struct resource_record 	*answer;
2145331Samw 	struct resource_record 	*authority;
2155331Samw 	struct resource_record 	*additional;
2165331Samw 
2175331Samw 	unsigned char			block_data[4];	/* begining of space */
2185331Samw };
2195331Samw 
2205331Samw #define	NAME_OPCODE_R		0x8000	/* RESPONSE flag: 1 bit */
2215331Samw #define	NAME_OPCODE_OPCODE_MASK	0x7800	/* OPCODE Field: 4 bits */
2225331Samw #define	NAME_OPCODE_QUERY	0x0000
2235331Samw #define	NAME_OPCODE_REGISTRATION	0x2800
2245331Samw #define	NAME_OPCODE_RELEASE	0x3000
2255331Samw #define	NAME_OPCODE_WACK	0x3800
2265331Samw #define	NAME_OPCODE_REFRESH	0x4000
2275331Samw #define	NAME_OPCODE_MULTIHOME	0x7800
2285331Samw #define	NAME_NM_FLAGS_AA	0x0400	/* Authoritative Answer:1 bit */
2295331Samw #define	NAME_NM_FLAGS_TC	0x0200	/* Truncation:		1 bit */
2305331Samw #define	NAME_NM_FLAGS_RD	0x0100	/* Recursion desired:	1 bit */
2315331Samw #define	NAME_NM_FLAGS_RA	0x0080	/* Recursion available:	1 bit */
2325331Samw #define	NAME_NM_FLAGS_x2	0x0040	/* reserved, mbz:	1 bit */
2335331Samw #define	NAME_NM_FLAGS_x1	0x0020	/* reserved, mbz:	1 bit */
2345331Samw #define	NAME_NM_FLAGS_B		0x0010	/* Broadcast:		1 bit */
2355331Samw #define	NAME_RCODE_MASK		0x000f	/* RCODE Field:		4 bits */
2365331Samw #define	RCODE_FMT_ERR		0x0001
2375331Samw #define	RCODE_SRV_ERR		0x0002
2385331Samw #define	RCODE_NAM_ERR		0x0003
2395331Samw #define	RCODE_IMP_ERR		0x0004
2405331Samw #define	RCODE_RFS_ERR		0x0005
2415331Samw #define	RCODE_ACT_ERR		0x0006
2425331Samw #define	RCODE_CFT_ERR		0x0007
2435331Samw 
2445331Samw #define	NM_FLAGS_UNICAST		0
2455331Samw #define	NM_FLAGS_BROADCAST		NAME_NM_FLAGS_B
2465331Samw 
2475331Samw #define	PACKET_TYPE(x)	((x) & (NAME_OPCODE_R | NAME_OPCODE_OPCODE_MASK | \
2485331Samw 			NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD))
2495331Samw 
2505331Samw #define	RCODE(x)		((x) & NAME_RCODE_MASK)
2515331Samw #define	POSITIVE_RESPONSE(x)	(RCODE(x) == 0)
2525331Samw #define	NEGATIVE_RESPONSE(x)	(RCODE(x) != 0)
2535331Samw 
2545331Samw #define	END_NODE_CHALLENGE_REGISTRATION_REQUEST				\
2555331Samw 	    (NAME_OPCODE_REGISTRATION | NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD)
2565331Samw #define	END_NODE_CHALLENGE_NAME_REGISTRATION_RESPONSE			\
2575331Samw 	    (NAME_OPCODE_R | END_NODE_CHALLENGE_REGISTRATION_REQUEST)
2585331Samw 
2595331Samw #define	NAME_QUERY_REQUEST						\
2605331Samw 	    (NAME_OPCODE_QUERY | NAME_NM_FLAGS_RD)
2615331Samw #define	NAME_QUERY_RESPONSE						\
2625331Samw 	    (NAME_OPCODE_R | NAME_QUERY_REQUEST |			\
2635331Samw 	    NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD)
2645331Samw 
2655331Samw #define	NODE_STATUS_REQUEST						\
2665331Samw 	    (NAME_OPCODE_QUERY)
2675331Samw #define	NODE_STATUS_RESPONSE						\
2685331Samw 	    (NAME_OPCODE_R | NODE_STATUS_REQUEST | NAME_NM_FLAGS_AA)
2695331Samw 
2705331Samw #define	REDIRECT_NAME_QUERY_RESPONSE					\
2715331Samw 	    (NAME_OPCODE_R | NAME_QUERY_REQUEST | NAME_NM_FLAGS_RD)
2725331Samw 
2735331Samw #define	NAME_REFRESH_REQUEST						\
2745331Samw 	    (NAME_OPCODE_REFRESH)
2755331Samw #define	NAME_REGISTRATION_REQUEST					\
2765331Samw 	    (NAME_OPCODE_REGISTRATION | NAME_NM_FLAGS_RD)
2775331Samw #define	NAME_MULTIHOME_REGISTRATION_REQUEST				\
2785331Samw 	    (NAME_OPCODE_MULTIHOME | NAME_NM_FLAGS_RD)
2795331Samw #define	NAME_REGISTRATION_RESPONSE					\
2805331Samw 	    (NAME_OPCODE_R | NAME_REGISTRATION_REQUEST | NAME_NM_FLAGS_AA)
2815331Samw 
2825331Samw #define	NAME_RELEASE_REQUEST						\
2835331Samw 	    (NAME_OPCODE_RELEASE)
2845331Samw #define	NAME_RELEASE_RESPONSE						\
2855331Samw 	    (NAME_OPCODE_R | NAME_RELEASE_REQUEST | NAME_NM_FLAGS_AA)
2865331Samw 
2875331Samw #define	WACK_RESPONSE						\
2885331Samw 	    (NAME_OPCODE_R | NAME_OPCODE_WACK | NAME_NM_FLAGS_AA)
2895331Samw 
2905331Samw #define	NAME_QUESTION_TYPE_NB		0x0020
2915331Samw #define	NAME_QUESTION_TYPE_NBSTAT	0x0021
2925331Samw #define	NAME_QUESTION_CLASS_IN		0x0001
2935331Samw 
2945331Samw 
2955331Samw #define	NAME_RR_TYPE_A			0x0001	/* IP Address */
2965331Samw #define	NAME_RR_TYPE_NS			0x0002	/* Name Server */
2975331Samw #define	NAME_RR_TYPE_NULL		0x000A	/* NULL */
2985331Samw #define	NAME_RR_TYPE_NB			0x0020	/* NetBIOS Name Service */
2995331Samw #define	NAME_RR_TYPE_NBSTAT		0x0021	/* NetBIOS Node Status */
3005331Samw 
3015331Samw #define	NAME_RR_CLASS_IN		0x0001	/* NetBIOS Node Status */
3025331Samw 
3035331Samw #define	NAME_NB_FLAGS_ONT_MASK		(3<<13)
3045331Samw #define	NAME_NB_FLAGS_ONT_B		(0<<13) /* B-node (broadcast) */
3055331Samw #define	NAME_NB_FLAGS_ONT_P		(1<<13)	/* P-node (point-to-point) */
3065331Samw #define	NAME_NB_FLAGS_ONT_M		(2<<13)	/* M-node (multicast) */
3075331Samw #define	NAME_NB_FLAGS_ONT_resv		(3<<13)
3085331Samw #define	NAME_NB_FLAGS_G			(1<<15)	/* Group Name */
3095331Samw 
3105331Samw #define	UNICAST				0
3115331Samw #define	BROADCAST			1
3125331Samw #define	POINTCAST			2
3135331Samw 
3145331Samw #define	NAME_ATTR_UNIQUE		0x0000
3155331Samw #define	NAME_ATTR_GROUP			0x8000
3165331Samw #define	NAME_ATTR_OWNER_NODE_TYPE	0x6000
3175331Samw #define	  NAME_ATTR_OWNER_TYPE_BNODE	  0x0000
3185331Samw #define	  NAME_ATTR_OWNER_TYPE_PNODE	  0x2000
3195331Samw #define	  NAME_ATTR_OWNER_TYPE_MNODE	  0x4000
3205331Samw #define	  NAME_ATTR_OWNER_TYPE_HNODE	  0x6000
3215331Samw #define	NAME_ATTR_DEREGISTER		0x1000
3225331Samw #define	NAME_ATTR_CONFLICT		0x0800
3235331Samw #define	NAME_ATTR_ACTIVE_NAME		0x0400
3245331Samw #define	NAME_ATTR_PERMANENT		0x0200
3255331Samw #define	NAME_ATTR_RESERVED		0x01FF
3265331Samw #define	NAME_ATTR_LOCAL			0x0001
3275331Samw 
3285331Samw #define	NODE_TYPE(x)		((x) & NAME_ATTR_OWNER_NODE_TYPE))
3295331Samw #define	IS_BNODE(x)		(NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_BNODE)
3305331Samw #define	IS_PNODE(x)		(NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_PNODE)
3315331Samw #define	IS_MNODE(x)		(NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_MNODE)
3325331Samw #define	IS_HNODE(x)		(NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_HNODE)
3335331Samw 
3345331Samw #define	IS_UNIQUE(x)		(((x) & NAME_ATTR_GROUP) == 0)
3355331Samw #define	IS_GROUP(x)		(((x) & NAME_ATTR_GROUP) != 0)
3365331Samw #define	IS_PERMANENT(x)		(((x) & NAME_ATTR_PERMANENT) != 0)
3375331Samw #define	IS_CONFLICTING(x)	(((x) & NAME_ATTR_CONFLICT) != 0)
3385331Samw #define	IS_ACTIVE(x)		(((x) & NAME_ATTR_ACTIVE) != 0)
3395331Samw #define	IS_DEGREGISTERED(x)	(((x) & NAME_ATTR_ACTIVE) != 0)
3405331Samw 
3415331Samw #define	IS_LOCAL(x)		(((x) & NAME_ATTR_LOCAL) != 0)
3425331Samw #define	IS_PUBLIC(x)		(((x) & NAME_ATTR_LOCAL) == 0)
3435331Samw #define	PUBLIC_BITS(x)		((x) & ~NAME_ATTR_RESERVED)
3445331Samw 
3455331Samw #define	SAME_SCOPE(scope, e)	(strcmp((scope), ((e)->scope)) == 0)
3465331Samw 
3475331Samw /*
3485331Samw  *   STATISTICS Field of the NODE STATUS RESPONSE:
3495331Samw  *
3505331Samw  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
3515331Samw  *    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
3525331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3535331Samw  *   |               UNIT_ID (Unique unit ID)                        |
3545331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3555331Samw  *   |       UNIT_ID,continued       |    JUMPERS    |  TEST_RESULT  |
3565331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3575331Samw  *   |       VERSION_NUMBER          |      PERIOD_OF_STATISTICS     |
3585331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3595331Samw  *   |       NUMBER_OF_CRCs          |     NUMBER_ALIGNMENT_ERRORS   |
3605331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3615331Samw  *   |       NUMBER_OF_COLLISIONS    |        NUMBER_SEND_ABORTS     |
3625331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3635331Samw  *   |                       NUMBER_GOOD_SENDS                       |
3645331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3655331Samw  *   |                      NUMBER_GOOD_RECEIVES                     |
3665331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3675331Samw  *   |       NUMBER_RETRANSMITS      | NUMBER_NO_RESOURCE_CONDITIONS |
3685331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3695331Samw  *   |  NUMBER_FREE_COMMAND_BLOCKS   |  TOTAL_NUMBER_COMMAND_BLOCKS  |
3705331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3715331Samw  *   |MAX_TOTAL_NUMBER_COMMAND_BLOCKS|    NUMBER_PENDING_SESSIONS    |
3725331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3735331Samw  *   |  MAX_NUMBER_PENDING_SESSIONS  |  MAX_TOTAL_SESSIONS_POSSIBLE  |
3745331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3755331Samw  *   |   SESSION_DATA_PACKET_SIZE    |
3765331Samw  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3775331Samw  */
3785331Samw 
3795331Samw typedef struct {
3805331Samw 	unsigned char	unit_id[6];
3815331Samw 	unsigned char	jumpers;
3825331Samw 	unsigned char	test_result;
3835331Samw 	unsigned short	version_number;
3845331Samw 	unsigned short	statistical_period;
3855331Samw 	unsigned short	crc_errors;
3865331Samw 	unsigned short	alignment_errors;
3875331Samw 	unsigned short	collisions;
3885331Samw 	unsigned short	send_aborts;
3895331Samw 	unsigned int	good_sends;
3905331Samw 	unsigned int	good_receives;
3915331Samw 	unsigned short	retransmits;
3925331Samw 	unsigned short	no_resource_conditions;
3935331Samw 	unsigned short	free_command_blocks;
3945331Samw 	unsigned short	total_command_blocks;
3955331Samw 	unsigned short	max_total_command_blocks;
3965331Samw 	unsigned short	pending_sessions;
3975331Samw 	unsigned short	max_pending_sessions;
3985331Samw 	unsigned short	total_possible_sessions;
3995331Samw 	unsigned short	session_data_packet_size;
4005331Samw } node_status_response;
4015331Samw 
4025331Samw /*
4035331Samw  * 4.4.1.  NetBIOS DATAGRAM HEADER
4045331Samw  *
4055331Samw  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
4065331Samw  *     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
4075331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4085331Samw  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
4095331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4105331Samw  *    |                           SOURCE_IP                           |
4115331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4125331Samw  *    |          SOURCE_PORT          |          DGM_LENGTH           |
4135331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4145331Samw  *    |         PACKET_OFFSET         |
4155331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4165331Samw  */
4175331Samw typedef struct {
4185331Samw 	unsigned char	msg_type;
4195331Samw 	unsigned char	flags;
4205331Samw 	unsigned short	dgm_id;
4215331Samw 	uint32_t	source_ip;
4225331Samw 	unsigned short	source_port;
4235331Samw 	unsigned short	dgm_length;
4245331Samw 	unsigned short	packet_offset;
4255331Samw } datagram_header;
4265331Samw 
4275331Samw /*
4285331Samw  *    MSG_TYPE values (in hexidecimal):
4295331Samw  *
4305331Samw  *            10 -  DIRECT_UNIQUE DATAGRAM
4315331Samw  *            11 -  DIRECT_GROUP DATAGRAM
4325331Samw  *            12 -  BROADCAST DATAGRAM
4335331Samw  *            13 -  DATAGRAM ERROR
4345331Samw  *            14 -  DATAGRAM QUERY REQUEST
4355331Samw  *            15 -  DATAGRAM POSITIVE QUERY RESPONSE
4365331Samw  *            16 -  DATAGRAM NEGATIVE QUERY RESPONSE
4375331Samw  */
4385331Samw #define	DATAGRAM_TYPE_DIRECT_UNIQUE	0x10
4395331Samw #define	DATAGRAM_TYPE_DIRECT_GROUP	0x11
4405331Samw #define	DATAGRAM_TYPE_BROADCAST		0x12
4415331Samw #define	DATAGRAM_TYPE_ERROR_DATAGRAM	0x13
4425331Samw #define	DATAGRAM_TYPE_QUERY_REQUEST	0x14
4435331Samw #define	DATAGRAM_TYPE_POSITIVE_RESPONSE	0x15
4445331Samw #define	DATAGRAM_TYPE_NEGATIVE_RESPONSE	0x16
4455331Samw 
4465331Samw 
4475331Samw /*
4485331Samw  *    Bit definitions of the FLAGS field:
4495331Samw  *
4505331Samw  *      0   1   2   3   4   5   6   7
4515331Samw  *    +---+---+---+---+---+---+---+---+
4525331Samw  *    | 0 | 0 | 0 | 0 |  SNT  | F | M |
4535331Samw  *    +---+---+---+---+---+---+---+---+
4545331Samw  *
4555331Samw  *    Symbol     Bit(s)   Description
4565331Samw  *
4575331Samw  *    M               7   MORE flag, If set then more NetBIOS datagram
4585331Samw  *                        fragments follow.
4595331Samw  *
4605331Samw  *    F               6   FIRST packet flag,  If set then this is first
4615331Samw  *                        (and possibly only) fragment of NetBIOS
4625331Samw  *                        datagram
4635331Samw  *
4645331Samw  *    SNT           4,5   Source End-Node type:
4655331Samw  *                           00 = B node
4665331Samw  *                           01 = P node
4675331Samw  *                           10 = M node
4685331Samw  *                           11 = H node
4695331Samw  *    RESERVED      0-3   Reserved, must be zero (0)
4705331Samw  */
4715331Samw #define	DATAGRAM_FLAGS_MORE	0x01
4725331Samw #define	DATAGRAM_FLAGS_FIRST	0x02
4735331Samw #define	DATAGRAM_FLAGS_SRC_TYPE	0x0c
4745331Samw #define	DATAGRAM_FLAGS_B_NODE	  0x00
4755331Samw #define	DATAGRAM_FLAGS_P_NODE	  0x04
4765331Samw #define	DATAGRAM_FLAGS_M_NODE	  0x08
4775331Samw #define	DATAGRAM_FLAGS_H_NODE	  0x0C
4785331Samw #define	DATAGRAM_FLAGS_NBDD	  0x0c
4795331Samw #define	DATAGRAM_FLAGS_RESERVED	0xf0
4805331Samw 
4815331Samw /*
4825331Samw  * 4.4.2.  DIRECT_UNIQUE, DIRECT_GROUP, & BROADCAST DATAGRAM
4835331Samw  *
4845331Samw  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
4855331Samw  *     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
4865331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4875331Samw  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
4885331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4895331Samw  *    |                           SOURCE_IP                           |
4905331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4915331Samw  *    |          SOURCE_PORT          |          DGM_LENGTH           |
4925331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4935331Samw  *    |         PACKET_OFFSET         |                               |
4945331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
4955331Samw  *    |                                                               |
4965331Samw  *    /                          SOURCE_NAME                          /
4975331Samw  *    /                                                               /
4985331Samw  *    |                                                               |
4995331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5005331Samw  *    |                                                               |
5015331Samw  *    /                       DESTINATION_NAME                        /
5025331Samw  *    /                                                               /
5035331Samw  *    |                                                               |
5045331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5055331Samw  *    |                                                               |
5065331Samw  *    /                           USER_DATA                           /
5075331Samw  *    /                                                               /
5085331Samw  *    |                                                               |
5095331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5105331Samw  */
5115331Samw typedef struct {
5125331Samw 	datagram_header	header;
5135331Samw 	unsigned char	*source_name;
5145331Samw 	unsigned char	*destination_name;
5155331Samw 	unsigned char	*user_data;
5165331Samw } datagram_packet;
5175331Samw 
5185331Samw 
5195331Samw /*
5205331Samw  *    4.4.3.  DATAGRAM ERROR PACKET
5215331Samw  *
5225331Samw  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
5235331Samw  *     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
5245331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5255331Samw  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
5265331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5275331Samw  *    |                           SOURCE_IP                           |
5285331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5295331Samw  *    |          SOURCE_PORT          |  ERROR_CODE   |
5305331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5315331Samw  *
5325331Samw  *    ERROR_CODE values (in hexidecimal):
5335331Samw  *
5345331Samw  *            82 -  DESTINATION NAME NOT PRESENT
5355331Samw  *            83 -  INVALID SOURCE NAME FORMAT
5365331Samw  *            84 -  INVALID DESTINATION NAME FORMAT
5375331Samw  */
5385331Samw 
5395331Samw typedef struct {
5405331Samw 	unsigned char	msg_type;
5415331Samw 	unsigned char	flags;
5425331Samw 	unsigned short	dgm_id;
5435331Samw 	uint32_t	source_ip;
5445331Samw 	unsigned short	source_port;
5455331Samw 	unsigned char	error;
5465331Samw } datagram_error_packet;
5475331Samw 
5485331Samw /*
5495331Samw  * 4.4.4.  DATAGRAM QUERY REQUEST
5505331Samw  *
5515331Samw  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
5525331Samw  *     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
5535331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5545331Samw  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
5555331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5565331Samw  *    |                           SOURCE_IP                           |
5575331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5585331Samw  *    |          SOURCE_PORT          |                               |
5595331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
5605331Samw  *    |                                                               |
5615331Samw  *    /                       DESTINATION_NAME                        /
5625331Samw  *    /                                                               /
5635331Samw  *    |                                                               |
5645331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5655331Samw  *
5665331Samw  * 4.4.5.  DATAGRAM POSITIVE AND NEGATIVE QUERY RESPONSE
5675331Samw  *
5685331Samw  *                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
5695331Samw  *     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
5705331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5715331Samw  *    |   MSG_TYPE    |     FLAGS     |           DGM_ID              |
5725331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5735331Samw  *    |                           SOURCE_IP                           |
5745331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5755331Samw  *    |          SOURCE_PORT          |                               |
5765331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
5775331Samw  *    |                                                               |
5785331Samw  *    /                       DESTINATION_NAME                        /
5795331Samw  *    /                                                               /
5805331Samw  *    |                                                               |
5815331Samw  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5825331Samw  */
5835331Samw 
5845331Samw typedef struct datagram_query_packet {
5855331Samw 	unsigned char	msg_type;
5865331Samw 	unsigned char	flags;
5875331Samw 	unsigned short	dgm_id;
5885331Samw 	uint32_t	source_ip;
5895331Samw 	unsigned short	source_port;
5905331Samw 	unsigned char	destination_name[MAX_NAME_LENGTH];
5915331Samw } datagram_query_packet;
5925331Samw 
5935331Samw 
5945331Samw typedef struct datagram {
5955331Samw 	struct datagram 	*forw;
5965331Samw 	struct datagram 	*back;
5975331Samw 	struct addr_entry	inaddr;
5985331Samw 	int			discard_timer;
5995331Samw 	unsigned char		packet_type;
6005331Samw 	unsigned char		flags;
6015331Samw 	unsigned short		datagram_id;
6025331Samw 	struct name_entry	src;
6035331Samw 	struct name_entry	dest;
6045331Samw 	unsigned short		offset;
6055331Samw 	unsigned short		data_length;
6065331Samw 	unsigned char 		*data;
6075331Samw 	unsigned int		rawbytes;
6085331Samw 	unsigned char		rawbuf[MAX_DATAGRAM_LENGTH];
6095331Samw } datagram;
6105331Samw 
6115331Samw typedef struct datagram_queue {
6125331Samw 	struct datagram 	*forw;
6135331Samw 	struct datagram 	*back;
6145331Samw } datagram_queue;
6155331Samw 
6165331Samw typedef struct name_queue {
6175331Samw 	struct name_entry head;
6185331Samw 	mutex_t mtx;
6195331Samw } name_queue_t;
6205331Samw 
6216030Sjb150015 typedef struct nbcache_iter {
6226030Sjb150015 	HT_ITERATOR		nbc_hti;
6236030Sjb150015 	struct name_entry	*nbc_entry;
6246030Sjb150015 } nbcache_iter_t;
6256030Sjb150015 
6265331Samw #define	NETBIOS_EMPTY_NAME (unsigned char *)""
6275331Samw 
6285331Samw #define	NETBIOS_NAME_IS_STAR(name) \
6295331Samw 	(bcmp(name, "*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NETBIOS_NAME_SZ) == 0)
6305331Samw 
631*10717Samw@Sun.COM 
632*10717Samw@Sun.COM /*
633*10717Samw@Sun.COM  * NetBIOS service state machine interface
634*10717Samw@Sun.COM  */
635*10717Samw@Sun.COM void smb_netbios_event(netbios_event_t);
636*10717Samw@Sun.COM void smb_netbios_wait(netbios_event_t);
637*10717Samw@Sun.COM void smb_netbios_sleep(time_t);
638*10717Samw@Sun.COM boolean_t smb_netbios_running(void);
639*10717Samw@Sun.COM boolean_t smb_netbios_error(void);
6405331Samw 
6415331Samw /*
6425331Samw  * Name Cache Functions
6435331Samw  */
6445331Samw int  smb_netbios_cache_init(void);
6455331Samw void smb_netbios_cache_fini(void);
646*10717Samw@Sun.COM void smb_netbios_cache_dump(FILE *fp);
6475331Samw int smb_netbios_cache_count(void);
6485331Samw void smb_netbios_cache_clean(void);
6495331Samw void smb_netbios_cache_reset_ttl(void);
6506030Sjb150015 void smb_netbios_cache_delete_locals(name_queue_t *);
6516030Sjb150015 void smb_netbios_cache_refresh(name_queue_t *);
6525331Samw 
6535331Samw int smb_netbios_cache_insert(struct name_entry *name);
6545331Samw int smb_netbios_cache_insert_list(struct name_entry *name);
6555331Samw void smb_netbios_cache_delete(struct name_entry *name);
6565331Samw int smb_netbios_cache_delete_addr(struct name_entry *name);
6575331Samw struct name_entry *smb_netbios_cache_lookup(struct name_entry *name);
6585331Samw struct name_entry *smb_netbios_cache_lookup_addr(struct name_entry *name);
6596030Sjb150015 void smb_netbios_cache_update_entry(struct name_entry *, struct name_entry *);
6606030Sjb150015 void smb_netbios_cache_unlock_entry(struct name_entry *);
6616030Sjb150015 unsigned char *smb_netbios_cache_status(unsigned char *, int, unsigned char *);
6626030Sjb150015 int smb_netbios_cache_getfirst(nbcache_iter_t *);
6636030Sjb150015 int smb_netbios_cache_getnext(nbcache_iter_t *);
6645331Samw 
665*10717Samw@Sun.COM void smb_netbios_name_dump(FILE *fp, struct name_entry *entry);
6665331Samw void smb_netbios_name_logf(struct name_entry *entry);
6675331Samw void smb_netbios_name_freeaddrs(struct name_entry *entry);
6686030Sjb150015 struct name_entry *smb_netbios_name_dup(struct name_entry *, int);
6695331Samw 
6705331Samw /* Name service functions */
671*10717Samw@Sun.COM void *smb_netbios_name_service(void *);
6726030Sjb150015 void smb_init_name_struct(unsigned char *, char, unsigned char *, uint32_t,
6736030Sjb150015     unsigned short, uint32_t, uint32_t, struct name_entry *);
6745331Samw 
6755331Samw struct name_entry *smb_name_find_name(struct name_entry *name);
6765331Samw int smb_name_add_name(struct name_entry *name);
6775331Samw int smb_name_delete_name(struct name_entry *name);
6785331Samw void smb_name_unlock_name(struct name_entry *name);
6795331Samw 
6805331Samw void smb_netbios_name_config(void);
6815331Samw void smb_netbios_name_unconfig(void);
6825331Samw void smb_netbios_name_tick(void);
6835331Samw 
6846030Sjb150015 int smb_first_level_name_encode(struct name_entry *, unsigned char *, int);
6856030Sjb150015 int smb_first_level_name_decode(unsigned char *, struct name_entry *);
6866030Sjb150015 void smb_encode_netbios_name(unsigned char *, char, unsigned char *,
6876030Sjb150015     struct name_entry *);
6885331Samw 
6895331Samw /* Datagram service functions */
690*10717Samw@Sun.COM void *smb_netbios_datagram_service(void *);
6915331Samw int smb_netbios_datagram_send(struct name_entry *,
6926030Sjb150015     struct name_entry *, unsigned char *, int);
6935331Samw void smb_netbios_datagram_tick(void);
6945331Samw 
6955331Samw /* browser functions */
6965331Samw void *smb_browser_dispatch(void *arg);
697*10717Samw@Sun.COM void *smb_browser_service(void *);
6986030Sjb150015 int smb_browser_load_transact_header(unsigned char *, int, int, int, char *);
6995331Samw 
7005331Samw /* Netlogon function */
7016030Sjb150015 void smb_netlogon_receive(struct datagram *, char *, unsigned char *, int);
7029832Samw@Sun.COM void smb_netlogon_request(struct name_entry *, char *);
7035331Samw 
7045331Samw #endif /* _SMB_NETBIOS_H_ */
705