8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / smbsrv / libsmbns / common / smbns_netbios.h
blob9ab53e1ac030e4c4469b3f10f1a7d7e7b550cb1f
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #ifndef _SMB_NETBIOS_H_
27 #define _SMB_NETBIOS_H_
29 #include <stdio.h>
30 #include <synch.h>
31 #include <pthread.h>
32 #include <strings.h>
33 #include <netinet/in.h>
35 #include <smbsrv/libsmbns.h>
37 #include <smbsrv/smbinfo.h>
38 #include <smbsrv/netbios.h>
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);
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;
52 typedef enum {
53 NETBIOS_EVENT_START = 0,
54 NETBIOS_EVENT_STOP,
55 NETBIOS_EVENT_RESET,
56 NETBIOS_EVENT_NS_START,
57 NETBIOS_EVENT_NS_STOP,
58 NETBIOS_EVENT_DGM_START,
59 NETBIOS_EVENT_DGM_STOP,
60 NETBIOS_EVENT_BROWSER_START,
61 NETBIOS_EVENT_BROWSER_STOP,
62 NETBIOS_EVENT_TIMER_START,
63 NETBIOS_EVENT_TIMER_STOP,
64 NETBIOS_EVENT_ERROR,
65 NETBIOS_EVENT_DUMP
66 } netbios_event_t;
68 typedef enum {
69 NETBIOS_STATE_INIT = 0,
70 NETBIOS_STATE_RUNNING,
71 NETBIOS_STATE_CLOSING,
72 NETBIOS_STATE_ERROR
73 } netbios_state_t;
75 typedef struct {
76 pthread_t s_tid;
77 boolean_t s_up;
78 } netbios_svc_t;
80 typedef struct {
81 mutex_t nbs_mtx;
82 cond_t nbs_cv;
83 netbios_svc_t nbs_ns;
84 netbios_svc_t nbs_dgm;
85 netbios_svc_t nbs_browser;
86 netbios_svc_t nbs_timer;
87 netbios_state_t nbs_state;
88 uint32_t nbs_errors;
89 char *nbs_last_event;
90 } netbios_service_t;
92 char smb_node_type;
94 #define SMB_NODETYPE_B 'B'
95 #define SMB_NODETYPE_P 'P'
96 #define SMB_NODETYPE_M 'M'
97 #define SMB_NODETYPE_H 'H'
100 * NAME service definitions
102 #define ADDR_FLAG_INVALID 0x0000
103 #define ADDR_FLAG_VALID 0x0001
105 typedef struct addr_entry {
106 struct addr_entry *forw;
107 struct addr_entry *back;
108 uint32_t attributes;
109 uint32_t conflict_timer;
110 uint32_t refresh_ttl;
111 uint32_t ttl;
112 struct sockaddr_in sin;
113 int sinlen;
114 uint32_t flags;
115 } addr_entry_t;
118 * The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
119 * of NODE_NAME records. Each NODE_NAME entry represents an active
120 * name in the same NetBIOS scope as the requesting name in the
121 * local name table of the responder. RR_NAME is the requesting
122 * name.
124 * NODE_NAME Entry:
126 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
127 * 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
128 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
129 * | |
130 * +--- ---+
131 * | |
132 * +--- NETBIOS FORMAT NAME ---+
133 * | |
134 * +--- ---+
135 * | |
136 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
137 * | NAME_FLAGS |
138 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
140 * The NAME_FLAGS field:
142 * 1 1 1 1 1 1
143 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
144 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
145 * | G | ONT |DRG|CNF|ACT|PRM| RESERVED |
146 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
148 * The NAME_FLAGS field is defined as:
150 * Symbol Bit(s) Description:
152 * RESERVED 7-15 Reserved for future use. Must be zero (0).
153 * PRM 6 Permanent Name Flag. If one (1) then entry
154 * is for the permanent node name. Flag is zero
155 * (0) for all other names.
156 * ACT 5 Active Name Flag. All entries have this flag
157 * set to one (1).
158 * CNF 4 Conflict Flag. If one (1) then name on this
159 * node is in conflict.
160 * DRG 3 Deregister Flag. If one (1) then this name
161 * is in the process of being deleted.
162 * ONT 1,2 Owner Node Type:
163 * 00 = B node
164 * 01 = P node
165 * 10 = M node
166 * 11 = Reserved for future use
167 * G 0 Group Name Flag.
168 * name.
169 * If zero (0) then it is a UNIQUE NetBIOS name.
172 typedef struct name_entry {
173 struct name_entry *forw;
174 struct name_entry *back;
175 unsigned char name[NETBIOS_NAME_SZ];
176 unsigned char scope[NETBIOS_DOMAIN_NAME_MAX];
177 unsigned short attributes;
178 struct addr_entry addr_list;
179 mutex_t mtx;
180 } name_entry_t;
182 struct name_question {
183 struct name_entry *name;
184 unsigned question_type;
185 unsigned question_class;
188 struct resource_record {
190 * These two flags and address are contained within RDATA
191 * when rr_type==0x0020 (NB - NetBIOS general Name Service)
192 * and rr_class==0x01 (IN - Internet Class).
195 struct name_entry *name;
196 unsigned short rr_type;
197 unsigned short rr_class;
198 uint32_t ttl;
199 unsigned short rdlength;
200 unsigned char *rdata;
203 struct name_packet {
204 unsigned short name_trn_id;
205 unsigned short info;
207 unsigned qdcount; /* question entries */
208 unsigned ancount; /* answer recs */
209 unsigned nscount; /* authority recs */
210 unsigned arcount; /* additional recs */
212 struct name_question *question;
213 struct resource_record *answer;
214 struct resource_record *authority;
215 struct resource_record *additional;
217 unsigned char block_data[4]; /* begining of space */
220 #define NAME_OPCODE_R 0x8000 /* RESPONSE flag: 1 bit */
221 #define NAME_OPCODE_OPCODE_MASK 0x7800 /* OPCODE Field: 4 bits */
222 #define NAME_OPCODE_QUERY 0x0000
223 #define NAME_OPCODE_REGISTRATION 0x2800
224 #define NAME_OPCODE_RELEASE 0x3000
225 #define NAME_OPCODE_WACK 0x3800
226 #define NAME_OPCODE_REFRESH 0x4000
227 #define NAME_OPCODE_MULTIHOME 0x7800
228 #define NAME_NM_FLAGS_AA 0x0400 /* Authoritative Answer:1 bit */
229 #define NAME_NM_FLAGS_TC 0x0200 /* Truncation: 1 bit */
230 #define NAME_NM_FLAGS_RD 0x0100 /* Recursion desired: 1 bit */
231 #define NAME_NM_FLAGS_RA 0x0080 /* Recursion available: 1 bit */
232 #define NAME_NM_FLAGS_x2 0x0040 /* reserved, mbz: 1 bit */
233 #define NAME_NM_FLAGS_x1 0x0020 /* reserved, mbz: 1 bit */
234 #define NAME_NM_FLAGS_B 0x0010 /* Broadcast: 1 bit */
235 #define NAME_RCODE_MASK 0x000f /* RCODE Field: 4 bits */
236 #define RCODE_FMT_ERR 0x0001
237 #define RCODE_SRV_ERR 0x0002
238 #define RCODE_NAM_ERR 0x0003
239 #define RCODE_IMP_ERR 0x0004
240 #define RCODE_RFS_ERR 0x0005
241 #define RCODE_ACT_ERR 0x0006
242 #define RCODE_CFT_ERR 0x0007
244 #define NM_FLAGS_UNICAST 0
245 #define NM_FLAGS_BROADCAST NAME_NM_FLAGS_B
247 #define PACKET_TYPE(x) ((x) & (NAME_OPCODE_R | NAME_OPCODE_OPCODE_MASK | \
248 NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD))
250 #define RCODE(x) ((x) & NAME_RCODE_MASK)
251 #define POSITIVE_RESPONSE(x) (RCODE(x) == 0)
252 #define NEGATIVE_RESPONSE(x) (RCODE(x) != 0)
254 #define END_NODE_CHALLENGE_REGISTRATION_REQUEST \
255 (NAME_OPCODE_REGISTRATION | NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD)
256 #define END_NODE_CHALLENGE_NAME_REGISTRATION_RESPONSE \
257 (NAME_OPCODE_R | END_NODE_CHALLENGE_REGISTRATION_REQUEST)
259 #define NAME_QUERY_REQUEST \
260 (NAME_OPCODE_QUERY | NAME_NM_FLAGS_RD)
261 #define NAME_QUERY_RESPONSE \
262 (NAME_OPCODE_R | NAME_QUERY_REQUEST | \
263 NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD)
265 #define NODE_STATUS_REQUEST \
266 (NAME_OPCODE_QUERY)
267 #define NODE_STATUS_RESPONSE \
268 (NAME_OPCODE_R | NODE_STATUS_REQUEST | NAME_NM_FLAGS_AA)
270 #define REDIRECT_NAME_QUERY_RESPONSE \
271 (NAME_OPCODE_R | NAME_QUERY_REQUEST | NAME_NM_FLAGS_RD)
273 #define NAME_REFRESH_REQUEST \
274 (NAME_OPCODE_REFRESH)
275 #define NAME_REGISTRATION_REQUEST \
276 (NAME_OPCODE_REGISTRATION | NAME_NM_FLAGS_RD)
277 #define NAME_MULTIHOME_REGISTRATION_REQUEST \
278 (NAME_OPCODE_MULTIHOME | NAME_NM_FLAGS_RD)
279 #define NAME_REGISTRATION_RESPONSE \
280 (NAME_OPCODE_R | NAME_REGISTRATION_REQUEST | NAME_NM_FLAGS_AA)
282 #define NAME_RELEASE_REQUEST \
283 (NAME_OPCODE_RELEASE)
284 #define NAME_RELEASE_RESPONSE \
285 (NAME_OPCODE_R | NAME_RELEASE_REQUEST | NAME_NM_FLAGS_AA)
287 #define WACK_RESPONSE \
288 (NAME_OPCODE_R | NAME_OPCODE_WACK | NAME_NM_FLAGS_AA)
290 #define NAME_QUESTION_TYPE_NB 0x0020
291 #define NAME_QUESTION_TYPE_NBSTAT 0x0021
292 #define NAME_QUESTION_CLASS_IN 0x0001
295 #define NAME_RR_TYPE_A 0x0001 /* IP Address */
296 #define NAME_RR_TYPE_NS 0x0002 /* Name Server */
297 #define NAME_RR_TYPE_NULL 0x000A /* NULL */
298 #define NAME_RR_TYPE_NB 0x0020 /* NetBIOS Name Service */
299 #define NAME_RR_TYPE_NBSTAT 0x0021 /* NetBIOS Node Status */
301 #define NAME_RR_CLASS_IN 0x0001 /* NetBIOS Node Status */
303 #define NAME_NB_FLAGS_ONT_MASK (3<<13)
304 #define NAME_NB_FLAGS_ONT_B (0<<13) /* B-node (broadcast) */
305 #define NAME_NB_FLAGS_ONT_P (1<<13) /* P-node (point-to-point) */
306 #define NAME_NB_FLAGS_ONT_M (2<<13) /* M-node (multicast) */
307 #define NAME_NB_FLAGS_ONT_resv (3<<13)
308 #define NAME_NB_FLAGS_G (1<<15) /* Group Name */
310 #define UNICAST 0
311 #define BROADCAST 1
312 #define POINTCAST 2
314 #define NAME_ATTR_UNIQUE 0x0000
315 #define NAME_ATTR_GROUP 0x8000
316 #define NAME_ATTR_OWNER_NODE_TYPE 0x6000
317 #define NAME_ATTR_OWNER_TYPE_BNODE 0x0000
318 #define NAME_ATTR_OWNER_TYPE_PNODE 0x2000
319 #define NAME_ATTR_OWNER_TYPE_MNODE 0x4000
320 #define NAME_ATTR_OWNER_TYPE_HNODE 0x6000
321 #define NAME_ATTR_DEREGISTER 0x1000
322 #define NAME_ATTR_CONFLICT 0x0800
323 #define NAME_ATTR_ACTIVE_NAME 0x0400
324 #define NAME_ATTR_PERMANENT 0x0200
325 #define NAME_ATTR_RESERVED 0x01FF
326 #define NAME_ATTR_LOCAL 0x0001
328 #define NODE_TYPE(x) ((x) & NAME_ATTR_OWNER_NODE_TYPE))
329 #define IS_BNODE(x) (NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_BNODE)
330 #define IS_PNODE(x) (NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_PNODE)
331 #define IS_MNODE(x) (NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_MNODE)
332 #define IS_HNODE(x) (NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_HNODE)
334 #define IS_UNIQUE(x) (((x) & NAME_ATTR_GROUP) == 0)
335 #define IS_GROUP(x) (((x) & NAME_ATTR_GROUP) != 0)
336 #define IS_PERMANENT(x) (((x) & NAME_ATTR_PERMANENT) != 0)
337 #define IS_CONFLICTING(x) (((x) & NAME_ATTR_CONFLICT) != 0)
338 #define IS_ACTIVE(x) (((x) & NAME_ATTR_ACTIVE) != 0)
339 #define IS_DEGREGISTERED(x) (((x) & NAME_ATTR_ACTIVE) != 0)
341 #define IS_LOCAL(x) (((x) & NAME_ATTR_LOCAL) != 0)
342 #define IS_PUBLIC(x) (((x) & NAME_ATTR_LOCAL) == 0)
343 #define PUBLIC_BITS(x) ((x) & ~NAME_ATTR_RESERVED)
345 #define SAME_SCOPE(scope, e) (strcmp((scope), ((e)->scope)) == 0)
348 * STATISTICS Field of the NODE STATUS RESPONSE:
350 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
351 * 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
352 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
353 * | UNIT_ID (Unique unit ID) |
354 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
355 * | UNIT_ID,continued | JUMPERS | TEST_RESULT |
356 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
357 * | VERSION_NUMBER | PERIOD_OF_STATISTICS |
358 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
359 * | NUMBER_OF_CRCs | NUMBER_ALIGNMENT_ERRORS |
360 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
361 * | NUMBER_OF_COLLISIONS | NUMBER_SEND_ABORTS |
362 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363 * | NUMBER_GOOD_SENDS |
364 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365 * | NUMBER_GOOD_RECEIVES |
366 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367 * | NUMBER_RETRANSMITS | NUMBER_NO_RESOURCE_CONDITIONS |
368 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369 * | NUMBER_FREE_COMMAND_BLOCKS | TOTAL_NUMBER_COMMAND_BLOCKS |
370 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
371 * |MAX_TOTAL_NUMBER_COMMAND_BLOCKS| NUMBER_PENDING_SESSIONS |
372 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
373 * | MAX_NUMBER_PENDING_SESSIONS | MAX_TOTAL_SESSIONS_POSSIBLE |
374 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
375 * | SESSION_DATA_PACKET_SIZE |
376 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
379 typedef struct {
380 unsigned char unit_id[6];
381 unsigned char jumpers;
382 unsigned char test_result;
383 unsigned short version_number;
384 unsigned short statistical_period;
385 unsigned short crc_errors;
386 unsigned short alignment_errors;
387 unsigned short collisions;
388 unsigned short send_aborts;
389 unsigned int good_sends;
390 unsigned int good_receives;
391 unsigned short retransmits;
392 unsigned short no_resource_conditions;
393 unsigned short free_command_blocks;
394 unsigned short total_command_blocks;
395 unsigned short max_total_command_blocks;
396 unsigned short pending_sessions;
397 unsigned short max_pending_sessions;
398 unsigned short total_possible_sessions;
399 unsigned short session_data_packet_size;
400 } node_status_response;
403 * 4.4.1. NetBIOS DATAGRAM HEADER
405 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
406 * 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
407 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
408 * | MSG_TYPE | FLAGS | DGM_ID |
409 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
410 * | SOURCE_IP |
411 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
412 * | SOURCE_PORT | DGM_LENGTH |
413 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
414 * | PACKET_OFFSET |
415 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
417 typedef struct {
418 unsigned char msg_type;
419 unsigned char flags;
420 unsigned short dgm_id;
421 uint32_t source_ip;
422 unsigned short source_port;
423 unsigned short dgm_length;
424 unsigned short packet_offset;
425 } datagram_header;
428 * MSG_TYPE values (in hexidecimal):
430 * 10 - DIRECT_UNIQUE DATAGRAM
431 * 11 - DIRECT_GROUP DATAGRAM
432 * 12 - BROADCAST DATAGRAM
433 * 13 - DATAGRAM ERROR
434 * 14 - DATAGRAM QUERY REQUEST
435 * 15 - DATAGRAM POSITIVE QUERY RESPONSE
436 * 16 - DATAGRAM NEGATIVE QUERY RESPONSE
438 #define DATAGRAM_TYPE_DIRECT_UNIQUE 0x10
439 #define DATAGRAM_TYPE_DIRECT_GROUP 0x11
440 #define DATAGRAM_TYPE_BROADCAST 0x12
441 #define DATAGRAM_TYPE_ERROR_DATAGRAM 0x13
442 #define DATAGRAM_TYPE_QUERY_REQUEST 0x14
443 #define DATAGRAM_TYPE_POSITIVE_RESPONSE 0x15
444 #define DATAGRAM_TYPE_NEGATIVE_RESPONSE 0x16
448 * Bit definitions of the FLAGS field:
450 * 0 1 2 3 4 5 6 7
451 * +---+---+---+---+---+---+---+---+
452 * | 0 | 0 | 0 | 0 | SNT | F | M |
453 * +---+---+---+---+---+---+---+---+
455 * Symbol Bit(s) Description
457 * M 7 MORE flag, If set then more NetBIOS datagram
458 * fragments follow.
460 * F 6 FIRST packet flag, If set then this is first
461 * (and possibly only) fragment of NetBIOS
462 * datagram
464 * SNT 4,5 Source End-Node type:
465 * 00 = B node
466 * 01 = P node
467 * 10 = M node
468 * 11 = H node
469 * RESERVED 0-3 Reserved, must be zero (0)
471 #define DATAGRAM_FLAGS_MORE 0x01
472 #define DATAGRAM_FLAGS_FIRST 0x02
473 #define DATAGRAM_FLAGS_SRC_TYPE 0x0c
474 #define DATAGRAM_FLAGS_B_NODE 0x00
475 #define DATAGRAM_FLAGS_P_NODE 0x04
476 #define DATAGRAM_FLAGS_M_NODE 0x08
477 #define DATAGRAM_FLAGS_H_NODE 0x0C
478 #define DATAGRAM_FLAGS_NBDD 0x0c
479 #define DATAGRAM_FLAGS_RESERVED 0xf0
482 * 4.4.2. DIRECT_UNIQUE, DIRECT_GROUP, & BROADCAST DATAGRAM
484 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
485 * 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
486 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
487 * | MSG_TYPE | FLAGS | DGM_ID |
488 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
489 * | SOURCE_IP |
490 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
491 * | SOURCE_PORT | DGM_LENGTH |
492 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
493 * | PACKET_OFFSET | |
494 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
495 * | |
496 * / SOURCE_NAME /
497 * / /
498 * | |
499 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
500 * | |
501 * / DESTINATION_NAME /
502 * / /
503 * | |
504 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
505 * | |
506 * / USER_DATA /
507 * / /
508 * | |
509 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
511 typedef struct {
512 datagram_header header;
513 unsigned char *source_name;
514 unsigned char *destination_name;
515 unsigned char *user_data;
516 } datagram_packet;
520 * 4.4.3. DATAGRAM ERROR PACKET
522 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
523 * 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
524 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
525 * | MSG_TYPE | FLAGS | DGM_ID |
526 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
527 * | SOURCE_IP |
528 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
529 * | SOURCE_PORT | ERROR_CODE |
530 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
532 * ERROR_CODE values (in hexidecimal):
534 * 82 - DESTINATION NAME NOT PRESENT
535 * 83 - INVALID SOURCE NAME FORMAT
536 * 84 - INVALID DESTINATION NAME FORMAT
539 typedef struct {
540 unsigned char msg_type;
541 unsigned char flags;
542 unsigned short dgm_id;
543 uint32_t source_ip;
544 unsigned short source_port;
545 unsigned char error;
546 } datagram_error_packet;
549 * 4.4.4. DATAGRAM QUERY REQUEST
551 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
552 * 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
553 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
554 * | MSG_TYPE | FLAGS | DGM_ID |
555 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
556 * | SOURCE_IP |
557 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
558 * | SOURCE_PORT | |
559 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
560 * | |
561 * / DESTINATION_NAME /
562 * / /
563 * | |
564 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
566 * 4.4.5. DATAGRAM POSITIVE AND NEGATIVE QUERY RESPONSE
568 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
569 * 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
570 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
571 * | MSG_TYPE | FLAGS | DGM_ID |
572 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
573 * | SOURCE_IP |
574 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
575 * | SOURCE_PORT | |
576 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
577 * | |
578 * / DESTINATION_NAME /
579 * / /
580 * | |
581 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
584 typedef struct datagram_query_packet {
585 unsigned char msg_type;
586 unsigned char flags;
587 unsigned short dgm_id;
588 uint32_t source_ip;
589 unsigned short source_port;
590 unsigned char destination_name[MAX_NAME_LENGTH];
591 } datagram_query_packet;
594 typedef struct datagram {
595 struct datagram *forw;
596 struct datagram *back;
597 struct addr_entry inaddr;
598 int discard_timer;
599 unsigned char packet_type;
600 unsigned char flags;
601 unsigned short datagram_id;
602 struct name_entry src;
603 struct name_entry dest;
604 unsigned short offset;
605 unsigned short data_length;
606 unsigned char *data;
607 unsigned int rawbytes;
608 unsigned char rawbuf[MAX_DATAGRAM_LENGTH];
609 } datagram;
611 typedef struct datagram_queue {
612 struct datagram *forw;
613 struct datagram *back;
614 } datagram_queue;
616 typedef struct name_queue {
617 struct name_entry head;
618 mutex_t mtx;
619 } name_queue_t;
621 typedef struct nbcache_iter {
622 HT_ITERATOR nbc_hti;
623 struct name_entry *nbc_entry;
624 } nbcache_iter_t;
626 #define NETBIOS_EMPTY_NAME (unsigned char *)""
628 #define NETBIOS_NAME_IS_STAR(name) \
629 (bcmp(name, "*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NETBIOS_NAME_SZ) == 0)
633 * NetBIOS service state machine interface
635 void smb_netbios_event(netbios_event_t);
636 void smb_netbios_wait(netbios_event_t);
637 void smb_netbios_sleep(time_t);
638 boolean_t smb_netbios_running(void);
639 boolean_t smb_netbios_error(void);
642 * Name Cache Functions
644 int smb_netbios_cache_init(void);
645 void smb_netbios_cache_fini(void);
646 void smb_netbios_cache_dump(FILE *fp);
647 int smb_netbios_cache_count(void);
648 void smb_netbios_cache_clean(void);
649 void smb_netbios_cache_reset_ttl(void);
650 void smb_netbios_cache_delete_locals(name_queue_t *);
651 void smb_netbios_cache_refresh(name_queue_t *);
653 int smb_netbios_cache_insert(struct name_entry *name);
654 int smb_netbios_cache_insert_list(struct name_entry *name);
655 void smb_netbios_cache_delete(struct name_entry *name);
656 int smb_netbios_cache_delete_addr(struct name_entry *name);
657 struct name_entry *smb_netbios_cache_lookup(struct name_entry *name);
658 struct name_entry *smb_netbios_cache_lookup_addr(struct name_entry *name);
659 void smb_netbios_cache_update_entry(struct name_entry *, struct name_entry *);
660 void smb_netbios_cache_unlock_entry(struct name_entry *);
661 unsigned char *smb_netbios_cache_status(unsigned char *, int, unsigned char *);
662 int smb_netbios_cache_getfirst(nbcache_iter_t *);
663 int smb_netbios_cache_getnext(nbcache_iter_t *);
665 void smb_netbios_name_dump(FILE *fp, struct name_entry *entry);
666 void smb_netbios_name_logf(struct name_entry *entry);
667 void smb_netbios_name_freeaddrs(struct name_entry *entry);
668 struct name_entry *smb_netbios_name_dup(struct name_entry *, int);
670 /* Name service functions */
671 void *smb_netbios_name_service(void *);
672 void smb_init_name_struct(unsigned char *, char, unsigned char *, uint32_t,
673 unsigned short, uint32_t, uint32_t, struct name_entry *);
675 struct name_entry *smb_name_find_name(struct name_entry *name);
676 int smb_name_add_name(struct name_entry *name);
677 int smb_name_delete_name(struct name_entry *name);
678 void smb_name_unlock_name(struct name_entry *name);
680 void smb_netbios_name_config(void);
681 void smb_netbios_name_unconfig(void);
682 void smb_netbios_name_tick(void);
684 int smb_first_level_name_encode(struct name_entry *, unsigned char *, int);
685 int smb_first_level_name_decode(unsigned char *, struct name_entry *);
686 void smb_encode_netbios_name(unsigned char *, char, unsigned char *,
687 struct name_entry *);
689 /* Datagram service functions */
690 void *smb_netbios_datagram_service(void *);
691 int smb_netbios_datagram_send(struct name_entry *,
692 struct name_entry *, unsigned char *, int);
693 void smb_netbios_datagram_tick(void);
695 /* browser functions */
696 void *smb_browser_dispatch(void *arg);
697 void *smb_browser_service(void *);
698 int smb_browser_load_transact_header(unsigned char *, int, int, int, char *);
700 /* Netlogon function */
701 void smb_netlogon_receive(struct datagram *, char *, unsigned char *, int);
702 void smb_netlogon_request(struct name_entry *, char *);
704 #endif /* _SMB_NETBIOS_H_ */