xref: /illumos-gate/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c (revision 30165b7f6753bc3d48c52319bed7ec7b3ea36b3c)
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 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright (c) 2016 by Delphix. All rights reserved.
25  */
26 
27 /*
28  * NetBIOS name resolution node types.
29  *
30  * A B-node (broadcast node) uses broadcasts for name registration
31  * and resolution.  Routers typically do not forward broadcasts and
32  * only computers on the local subnet will respond.
33  *
34  * A P-node (peer-to-peer node) uses a NetBIOS name server (WINS)
35  * to resolve NetBIOS names, which allows it to work across routers.
36  * In order to function in a P-node environment, all computers must
37  * be configured to use the NetBIOS name server because P-nodes do
38  * not broadcast on the network.
39  *
40  * A mixed node (M-node) behaves as a B-node by default.  If it cannot
41  * resolve the name via broadcast then it tries a NetBIOS name server
42  * lookup (P-node).
43  *
44  * A hybrid node (H-node) behaves as a P-node by default.  If it cannot
45  * resolve the name using a NetBIOS name server then it resorts to
46  * broadcasts (B-node).
47  *
48  * NetBIOS Name Service Protocols
49  *
50  * A REQUEST packet is always sent to the well known UDP port 137.
51  * The destination address is normally either the IP broadcast address or
52  * the address of the NAME - the address of the NAME server it set up at
53  * initialization time.  In rare cases, a request packet will be sent to
54  * an end node, e.g.  a NAME QUERY REQUEST sent to "challenge" a node.
55  *
56  * A RESPONSE packet is always sent to the source UDP port and source IP
57  * address of the request packet.
58  *
59  * A DEMAND packet must always be sent to the well known UDP port 137.
60  * There is no restriction on the target IP address.
61  *
62  * A transaction ID is a value composed from the requestor's IP address and
63  * a unique 16 bit value generated by the originator of the transaction.
64  */
65 
66 #include <unistd.h>
67 #include <syslog.h>
68 #include <stdlib.h>
69 #include <synch.h>
70 #include <errno.h>
71 #include <netdb.h>
72 #include <sys/socket.h>
73 #include <sys/sockio.h>
74 #include <arpa/inet.h>
75 #include <net/if_arp.h>
76 
77 #include <smbsrv/libsmbns.h>
78 #include <smbns_netbios.h>
79 
80 /*
81  * RFC 1002 4.2.1.1.  HEADER
82  */
83 #define	QUESTION_TYPE_NETBIOS_GENERAL	0x20
84 #define	QUESTION_TYPE_NETBIOS_STATUS	0x21
85 
86 #define	QUESTION_CLASS_INTERNET		0x0001
87 
88 /*
89  * RFC 1002 4.2.1.3.  RESOURCE RECORD
90  */
91 #define	RR_TYPE_IP_ADDRESS_RESOURCE	0x0001
92 #define	RR_TYPE_NAME_SERVER_RESOURCE	0x0002
93 #define	RR_TYPE_NULL_RESOURCE		0x000A
94 #define	RR_TYPE_NETBIOS_RESOURCE	0x0020
95 #define	RR_TYPE_NETBIOS_STATUS		0x0021
96 
97 /*
98  *
99  * RESOURCE RECORD RR_CLASS field definitions
100  */
101 #define	RR_CLASS_INTERNET_CLASS		0x0001
102 
103 /*
104  * NB_FLAGS field of the RESOURCE RECORD RDATA field for RR_TYPE of NB.
105  */
106 #define	RR_FLAGS_NB_ONT_MASK		0x6000
107 #define	RR_FLAGS_NB_ONT_B_NODE		0x0000
108 #define	RR_FLAGS_NB_ONT_P_NODE		0x2000
109 #define	RR_FLAGS_NB_ONT_M_NODE		0x4000
110 #define	RR_FLAGS_NB_ONT_RESERVED	0x6000
111 #define	RR_FLAGS_NB_GROUP_NAME		0x8000
112 
113 #define	NAME_FLAGS_PERMANENT_NAME	0x0200
114 #define	NAME_FLAGS_ACTIVE_NAME		0x0400
115 #define	NAME_FLAGS_CONFLICT		0x0800
116 #define	NAME_FLAGS_DEREGISTER		0x1000
117 #define	NAME_FLAGS_ONT_MASK		0x6000
118 #define	NAME_FLAGS_ONT_B_NODE		0x0000
119 #define	NAME_FLAGS_ONT_P_NODE		0x2000
120 #define	NAME_FLAGS_ONT_M_NODE		0x4000
121 #define	NAME_FLAGS_ONT_RESERVED		0x6000
122 #define	NAME_FLAGS_GROUP_NAME		0x8000
123 
124 #define	MAX_NETBIOS_REPLY_DATA_SIZE	500
125 
126 #define	NAME_HEADER_SIZE		12
127 
128 typedef struct nbt_name_reply {
129 	struct nbt_name_reply	*forw;
130 	struct nbt_name_reply	*back;
131 	struct name_packet	*packet;
132 	addr_entry_t		*addr;
133 	uint16_t		name_trn_id;
134 	boolean_t		reply_ready;
135 } nbt_name_reply_t;
136 
137 static nbt_name_reply_t reply_queue;
138 static mutex_t rq_mtx;
139 static cond_t rq_cv;
140 
141 static mutex_t nbt_name_config_mtx;
142 
143 static name_queue_t delete_queue;
144 static name_queue_t refresh_queue;
145 
146 static int name_sock = 0;
147 
148 static int bcast_num = 0;
149 static int nbns_num = 0;
150 static addr_entry_t smb_bcast_list[SMB_PI_MAX_NETWORKS];
151 static addr_entry_t smb_nbns[SMB_PI_MAX_WINS];
152 
153 static int smb_netbios_process_response(uint16_t, addr_entry_t *,
154     struct name_packet *, uint32_t);
155 
156 static int smb_send_name_service_packet(addr_entry_t *addr,
157     struct name_packet *packet);
158 
159 /*
160  * Allocate a transaction id.
161  */
162 static uint16_t
163 smb_netbios_name_trn_id(void)
164 {
165 	static uint16_t trn_id;
166 	static mutex_t trn_id_mtx;
167 
168 	(void) mutex_lock(&trn_id_mtx);
169 
170 	do {
171 		++trn_id;
172 	} while (trn_id == 0 || trn_id == (uint16_t)-1);
173 
174 	(void) mutex_unlock(&trn_id_mtx);
175 	return (trn_id);
176 }
177 
178 static int
179 smb_end_node_challenge(nbt_name_reply_t *reply_info)
180 {
181 	int			rc;
182 	uint32_t		retry;
183 	uint16_t		tid;
184 	struct resource_record	*answer;
185 	struct name_question	question;
186 	addr_entry_t		*addr;
187 	struct name_entry 	*destination;
188 	struct name_packet	packet;
189 	struct timespec 	st;
190 
191 	/*
192 	 * The response packet has in it the address of the presumed owner
193 	 * of the name.  Challenge that owner.  If owner either does not
194 	 * respond or indicates that they no longer own the name, claim the
195 	 * name.  Otherwise, the name cannot be claimed.
196 	 */
197 
198 	if ((answer = reply_info->packet->answer) == 0)
199 		return (-1);
200 
201 	destination = answer->name;
202 	question.name = answer->name;
203 
204 	packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST;
205 	packet.qdcount = 1;	/* question entries */
206 	packet.question = &question;
207 	packet.ancount = 0;	/* answer recs */
208 	packet.answer = NULL;
209 	packet.nscount = 0;	/* authority recs */
210 	packet.authority = NULL;
211 	packet.arcount = 0;	/* additional recs */
212 	packet.additional = NULL;
213 
214 	addr = &destination->addr_list;
215 	for (retry = 0; retry < UCAST_REQ_RETRY_COUNT; retry++) {
216 		tid = smb_netbios_name_trn_id();
217 		packet.name_trn_id = tid;
218 		if (smb_send_name_service_packet(addr, &packet) >= 0) {
219 			if ((rc = smb_netbios_process_response(tid, addr,
220 			    &packet, UCAST_REQ_RETRY_TIMEOUT)) != 0)
221 				return (rc);
222 		}
223 		st.tv_sec = 0;
224 		st.tv_nsec = (UCAST_REQ_RETRY_TIMEOUT * 1000000);
225 		(void) nanosleep(&st, 0);
226 	}
227 	/* No reply */
228 	return (0);
229 }
230 
231 static nbt_name_reply_t *
232 smb_name_get_reply(uint16_t tid, uint32_t timeout)
233 {
234 	uint16_t		info;
235 	struct resource_record	*answer;
236 	nbt_name_reply_t 	*reply;
237 	uint32_t 		wait_time, to_save; /* in millisecond */
238 	struct timeval 		wt;
239 	timestruc_t 		to;
240 
241 	to_save = timeout;
242 	reply = malloc(sizeof (nbt_name_reply_t));
243 	if (reply != NULL) {
244 		reply->reply_ready = B_FALSE;
245 		reply->name_trn_id = tid;
246 		(void) mutex_lock(&rq_mtx);
247 		QUEUE_INSERT_TAIL(&reply_queue, reply);
248 		(void) mutex_unlock(&rq_mtx);
249 
250 		for (;;) {
251 			(void) gettimeofday(&wt, 0);
252 			wait_time = wt.tv_usec / 1000;
253 
254 			to.tv_sec = 0;
255 			to.tv_nsec = timeout * 1000000;
256 			(void) mutex_lock(&rq_mtx);
257 			(void) cond_reltimedwait(&rq_cv, &rq_mtx, &to);
258 			(void) mutex_unlock(&rq_mtx);
259 
260 			if (reply->reply_ready) {
261 				info = reply->packet->info;
262 				if (PACKET_TYPE(info) == WACK_RESPONSE) {
263 					answer = reply->packet->answer;
264 					wait_time = (answer) ?
265 					    TO_MILLISECONDS(answer->ttl) :
266 					    DEFAULT_TTL;
267 					free(reply->addr);
268 					free(reply->packet);
269 					timeout = to_save + wait_time;
270 					reply->reply_ready = B_FALSE;
271 					reply->name_trn_id = tid;
272 					(void) mutex_lock(&rq_mtx);
273 					QUEUE_INSERT_TAIL(&reply_queue, reply);
274 					(void) mutex_unlock(&rq_mtx);
275 					continue;
276 				}
277 				return (reply);
278 			}
279 			(void) gettimeofday(&wt, 0);
280 			wait_time = (wt.tv_usec / 1000) - wait_time;
281 			if (wait_time >= timeout) {
282 				(void) mutex_lock(&rq_mtx);
283 				QUEUE_CLIP(reply);
284 				(void) mutex_unlock(&rq_mtx);
285 				free(reply);
286 				break;
287 			}
288 			timeout -= wait_time;
289 		}
290 	}
291 
292 	return (0);
293 }
294 
295 static void
296 smb_reply_ready(struct name_packet *packet, addr_entry_t *addr)
297 {
298 	nbt_name_reply_t *reply;
299 	struct resource_record *answer;
300 
301 	(void) mutex_lock(&rq_mtx);
302 	for (reply = reply_queue.forw; reply != &reply_queue;
303 	    reply = reply->forw) {
304 		if (reply->name_trn_id == packet->name_trn_id) {
305 			QUEUE_CLIP(reply);
306 
307 			reply->addr = addr;
308 			reply->packet = packet;
309 			reply->reply_ready = B_TRUE;
310 			(void) cond_signal(&rq_cv);
311 			(void) mutex_unlock(&rq_mtx);
312 			return;
313 		}
314 	}
315 	(void) mutex_unlock(&rq_mtx);
316 
317 	/* Presumably nobody is waiting any more... */
318 	free(addr);
319 
320 	answer = packet->answer;
321 	if (answer)
322 		smb_netbios_name_freeaddrs(answer->name);
323 	free(packet);
324 }
325 
326 static int
327 smb_netbios_process_response(uint16_t tid, addr_entry_t *addr,
328     struct name_packet *packet, uint32_t timeout)
329 {
330 	int			rc = 0;
331 	uint16_t		info;
332 	nbt_name_reply_t 	*reply;
333 	struct resource_record	*answer;
334 	struct name_entry 	*name;
335 	struct name_entry 	*entry;
336 	struct name_question 	*question;
337 	uint32_t 		ttl;
338 
339 	if ((reply = smb_name_get_reply(tid, timeout)) == 0) {
340 		return (0); /* No reply: retry */
341 	}
342 	info = reply->packet->info;
343 	answer = reply->packet->answer;
344 
345 	/* response */
346 	switch (PACKET_TYPE(info)) {
347 	case NAME_QUERY_RESPONSE:
348 		if (POSITIVE_RESPONSE(info)) {
349 			addr = &answer->name->addr_list;
350 			do {
351 				/*
352 				 * Make sure that remote name is not
353 				 * flagged local
354 				 */
355 				addr->attributes &= ~NAME_ATTR_LOCAL;
356 
357 				if (answer->ttl)
358 					addr->ttl = answer->ttl;
359 				else
360 					addr->ttl = DEFAULT_TTL;
361 				addr->refresh_ttl = TO_SECONDS(addr->ttl);
362 				addr->ttl = addr->refresh_ttl;
363 
364 				addr = addr->forw;
365 			} while (addr != &answer->name->addr_list);
366 			smb_netbios_name_logf(answer->name);
367 			(void) smb_netbios_cache_insert_list(answer->name);
368 			rc = 1;
369 		} else {
370 			rc = -1;
371 		}
372 		break;
373 
374 	case NAME_REGISTRATION_RESPONSE:
375 		if (NEGATIVE_RESPONSE(info)) {
376 			if (RCODE(info) == RCODE_CFT_ERR) {
377 				if (answer == 0) {
378 					rc = -RCODE(info);
379 					break;
380 				}
381 
382 				name = answer->name;
383 				entry = smb_netbios_cache_lookup(name);
384 				if (entry) {
385 					/*
386 					 * a name in the state "conflict
387 					 * detected" does not "logically" exist
388 					 * on that node. No further session
389 					 * will be accepted on that name.
390 					 * No datagrams can be sent against
391 					 * that name.
392 					 * Such an entry will not be used for
393 					 * purposes of processing incoming
394 					 * request packets.
395 					 * The only valid user NetBIOS operation
396 					 * against such a name is DELETE NAME.
397 					 */
398 					entry->attributes |= NAME_ATTR_CONFLICT;
399 					syslog(LOG_DEBUG,
400 					    "nbns: name conflict: %15.15s",
401 					    entry->name);
402 					smb_netbios_cache_unlock_entry(entry);
403 				}
404 			}
405 			rc = -RCODE(info);
406 			break;
407 		}
408 
409 		/*
410 		 * name can be added:
411 		 *   adjust refresh timeout value,
412 		 *   TTL, for this name
413 		 */
414 		question = packet->question;
415 		ttl = (answer && answer->ttl) ? answer->ttl : DEFAULT_TTL;
416 		ttl = TO_SECONDS(ttl);
417 		if ((entry = smb_netbios_cache_lookup(question->name)) != 0) {
418 			addr = &entry->addr_list;
419 			do {
420 				if ((addr->refresh_ttl == 0) ||
421 				    (ttl < addr->refresh_ttl))
422 					addr->refresh_ttl = addr->ttl = ttl;
423 				addr = addr->forw;
424 			} while (addr != &entry->addr_list);
425 			smb_netbios_cache_unlock_entry(entry);
426 		}
427 
428 		rc = 1;
429 		break;
430 
431 	case NAME_RELEASE_RESPONSE:
432 		rc = 1;
433 		break;
434 
435 	case END_NODE_CHALLENGE_REGISTRATION_REQUEST:
436 		/*
437 		 * The response packet has in it the
438 		 * address of the presumed owner of the
439 		 * name.  Challenge that owner.  If
440 		 * owner either does not respond or
441 		 * indicates that they no longer own the
442 		 * name, claim the name.  Otherwise,
443 		 * the name cannot be claimed.
444 		 */
445 		rc = smb_end_node_challenge(reply);
446 		break;
447 
448 	default:
449 		rc = 0;
450 		break;
451 	}
452 
453 	if (answer)
454 		smb_netbios_name_freeaddrs(answer->name);
455 	free(reply->addr);
456 	free(reply->packet);
457 	free(reply);
458 	return (rc);  /* retry */
459 }
460 
461 /*
462  * smb_name_buf_from_packet
463  *
464  * Description:
465  *	Convert a NetBIOS Name Server Packet Block (npb)
466  *	into the bits and bytes destined for the wire.
467  *	The "buf" is used as a heap.
468  *
469  * Inputs:
470  *	char *		buf	-> Buffer, from the wire
471  *	unsigned	n_buf	-> Length of 'buf'
472  *	name_packet	*npb	-> Packet block, decode into
473  *	unsigned	n_npb	-> Max bytes in 'npb'
474  *
475  * Returns:
476  *	>0	-> Encode successful, value is length of packet in "buf"
477  *	-1	-> Hard error, can not possibly encode
478  *	-2	-> Need more memory in buf -- it's too small
479  */
480 static int
481 smb_name_buf_from_packet(unsigned char *buf, int n_buf,
482     struct name_packet *npb)
483 {
484 	addr_entry_t		*raddr;
485 	unsigned char 		*heap = buf;
486 	unsigned char 		*end_heap = heap + n_buf;
487 	unsigned char		comp_name_buf[MAX_NAME_LENGTH];
488 	unsigned int		tmp;
489 	int			i, step;
490 
491 	if (n_buf < NAME_HEADER_SIZE)
492 		return (-1);		/* no header, impossible */
493 
494 	BE_OUT16(heap, npb->name_trn_id);
495 	heap += 2;
496 
497 	BE_OUT16(heap, npb->info);
498 	heap += 2;
499 
500 	BE_OUT16(heap, npb->qdcount);
501 	heap += 2;
502 
503 	BE_OUT16(heap, npb->ancount);
504 	heap += 2;
505 
506 	BE_OUT16(heap, npb->nscount);
507 	heap += 2;
508 
509 	BE_OUT16(heap, npb->arcount);
510 	heap += 2;
511 
512 	for (i = 0; i < npb->qdcount; i++) {
513 		if ((heap + 34 + 4) > end_heap)
514 			return (-2);
515 
516 		(void) smb_first_level_name_encode(npb->question[i].name,
517 		    comp_name_buf, sizeof (comp_name_buf));
518 		(void) strcpy((char *)heap, (char *)comp_name_buf);
519 		heap += strlen((char *)comp_name_buf) + 1;
520 
521 		BE_OUT16(heap, npb->question[i].question_type);
522 		heap += 2;
523 
524 		BE_OUT16(heap, npb->question[i].question_class);
525 		heap += 2;
526 	}
527 
528 	for (step = 1; step <= 3; step++) {
529 		struct resource_record *nrr;
530 		int n;
531 
532 		/* truly ugly, but saves code copying */
533 		if (step == 1) {
534 			n = npb->ancount;
535 			nrr = npb->answer;
536 		} else if (step == 2) {
537 			n = npb->nscount;
538 			nrr = npb->authority;
539 		} else { /* step == 3 */
540 			n = npb->arcount;
541 			nrr = npb->additional;
542 		}
543 
544 		for (i = 0; i < n; i++) {
545 			if ((heap + 34 + 10) > end_heap)
546 				return (-2);
547 
548 			(void) smb_first_level_name_encode(nrr->name,
549 			    comp_name_buf, sizeof (comp_name_buf));
550 			(void) strcpy((char *)heap, (char *)comp_name_buf);
551 			heap += strlen((char *)comp_name_buf) + 1;
552 
553 			BE_OUT16(heap, nrr[i].rr_type);
554 			heap += 2;
555 
556 			BE_OUT16(heap, nrr[i].rr_class);
557 			heap += 2;
558 
559 			BE_OUT32(heap, nrr[i].ttl);
560 			heap += 4;
561 
562 			BE_OUT16(heap, nrr[i].rdlength);
563 			heap += 2;
564 
565 			if ((tmp = nrr[i].rdlength) > 0) {
566 				if ((heap + tmp) > end_heap)
567 					return (-2);
568 
569 				if (nrr[i].rr_type == NAME_RR_TYPE_NB &&
570 				    nrr[i].rr_class == NAME_RR_CLASS_IN &&
571 				    tmp >= 6 && nrr[i].rdata == 0) {
572 					tmp = nrr[i].name->attributes &
573 					    (NAME_ATTR_GROUP |
574 					    NAME_ATTR_OWNER_NODE_TYPE);
575 					BE_OUT16(heap, tmp);
576 					heap += 2;
577 
578 					raddr = &nrr[i].name->addr_list;
579 					(void) memcpy(heap,
580 					    &raddr->sin.sin_addr.s_addr,
581 					    sizeof (uint32_t));
582 					heap += 4;
583 				} else {
584 					bcopy(nrr[i].rdata, heap, tmp);
585 					heap += tmp;
586 				}
587 			}
588 		}
589 	}
590 	return (heap - buf);
591 }
592 
593 /*
594  * strnchr
595  *
596  * Lookup for character 'c' in first 'n' chars of string 's'.
597  * Returns pointer to the found char, otherwise returns 0.
598  */
599 static char *
600 strnchr(const char *s, char c, int n)
601 {
602 	char *ps = (char *)s;
603 	char *es = (char *)s + n;
604 
605 	while (ps < es && *ps) {
606 		if (*ps == c)
607 			return (ps);
608 
609 		++ps;
610 	}
611 
612 	if (*ps == '\0' && c == '\0')
613 		return (ps);
614 
615 	return (0);
616 }
617 
618 static boolean_t
619 is_multihome(char *name)
620 {
621 	return (smb_nic_getnum(name) > 1);
622 }
623 
624 /*
625  * smb_netbios_getname
626  *
627  * Get the Netbios name part of the given record.
628  * Does some boundary checks.
629  *
630  * Returns the name length on success, otherwise
631  * returns 0.
632  */
633 static int
634 smb_netbios_getname(char *name, char *buf, char *buf_end)
635 {
636 	char *name_end;
637 	int name_len;
638 
639 	if (buf >= buf_end) {
640 		/* no room for a NB name */
641 		return (0);
642 	}
643 
644 	name_end = strnchr(buf, '\0', buf_end - buf + 1);
645 	if (name_end == 0) {
646 		/* not a valid NB name */
647 		return (0);
648 	}
649 
650 	name_len = name_end - buf + 1;
651 
652 	(void) strlcpy(name, buf, name_len);
653 	return (name_len);
654 }
655 
656 /*
657  * smb_name_buf_to_packet
658  *
659  * Convert the bits and bytes that came from the wire into a NetBIOS
660  * Name Server Packet Block (npb).  The "block" is used as a heap.
661  *
662  * Returns a pointer to a name packet on success.  Otherwise, returns
663  * a NULL pointer.
664  */
665 static struct name_packet *
666 smb_name_buf_to_packet(char *buf, int n_buf)
667 {
668 	struct name_packet *npb;
669 	unsigned char *heap;
670 	unsigned char *scan = (unsigned char *)buf;
671 	unsigned char *scan_end = scan + n_buf;
672 	char name_buf[MAX_NAME_LENGTH];
673 	struct resource_record *nrr = 0;
674 	int	rc, i, n, nn, ns;
675 	uint16_t name_trn_id, info;
676 	uint16_t qdcount, ancount, nscount, arcount;
677 	addr_entry_t *next;
678 	int name_len;
679 
680 	if (n_buf < NAME_HEADER_SIZE) {
681 		/* truncated header */
682 		syslog(LOG_DEBUG, "nbns: short packet (%d bytes)", n_buf);
683 		return (NULL);
684 	}
685 
686 	name_trn_id = BE_IN16(scan); scan += 2;
687 	info = BE_IN16(scan); scan += 2;
688 	qdcount = BE_IN16(scan); scan += 2;
689 	ancount = BE_IN16(scan); scan += 2;
690 	nscount = BE_IN16(scan); scan += 2;
691 	arcount = BE_IN16(scan); scan += 2;
692 
693 	ns = sizeof (struct name_entry);
694 	n = n_buf + sizeof (struct name_packet) +
695 	    ((unsigned)qdcount * (sizeof (struct name_question) + ns)) +
696 	    ((unsigned)ancount * (sizeof (struct resource_record) + ns)) +
697 	    ((unsigned)nscount * (sizeof (struct resource_record) + ns)) +
698 	    ((unsigned)arcount * (sizeof (struct resource_record) + ns));
699 
700 	if ((npb = malloc(n)) == NULL)
701 		return (NULL);
702 
703 	bzero(npb, n);
704 	heap = npb->block_data;
705 	npb->name_trn_id = name_trn_id;
706 	npb->info = info;
707 	npb->qdcount = qdcount;
708 	npb->ancount = ancount;
709 	npb->nscount = nscount;
710 	npb->arcount = arcount;
711 
712 	/* scan is in position for question entries */
713 
714 	/*
715 	 * Measure the space needed for the tables
716 	 */
717 	if (qdcount > 0) {
718 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
719 		npb->question = (struct name_question *)heap;
720 		heap += qdcount * sizeof (struct name_question);
721 		for (i = 0; i < qdcount; i++) {
722 			/* LINTED - E_BAD_PTR_CAST_ALIGN */
723 			npb->question[i].name = (struct name_entry *)heap;
724 			heap += sizeof (struct name_entry);
725 		}
726 	}
727 
728 	/* LINTED - E_BAD_PTR_CAST_ALIGN */
729 	nrr = (struct resource_record *)heap;
730 
731 	if (ancount > 0) {
732 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
733 		npb->answer = (struct resource_record *)heap;
734 		heap += ancount * sizeof (struct resource_record);
735 	}
736 
737 	if (nscount > 0) {
738 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
739 		npb->authority = (struct resource_record *)heap;
740 		heap += nscount * sizeof (struct resource_record);
741 	}
742 
743 	if (arcount > 0) {
744 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
745 		npb->additional = (struct resource_record *)heap;
746 		heap += arcount * sizeof (struct resource_record);
747 	}
748 
749 	/*
750 	 * Populate each resource_record's .name field.
751 	 * Done as a second pass so that all resource records
752 	 * (answer, authority, additional) are consecutive via nrr[i].
753 	 */
754 	for (i = 0; i < (ancount + nscount + arcount); i++) {
755 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
756 		nrr[i].name = (struct name_entry *)heap;
757 		heap += sizeof (struct name_entry);
758 	}
759 
760 
761 	for (i = 0; i < npb->qdcount; i++) {
762 		name_len = smb_netbios_getname(name_buf, (char *)scan,
763 		    (char *)scan_end);
764 		if (name_len <= 0) {
765 			free(npb);
766 			return (NULL);
767 		}
768 
769 		smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
770 		    npb->question[i].name);
771 		rc = smb_first_level_name_decode((unsigned char *)name_buf,
772 		    npb->question[i].name);
773 		if (rc < 0) {
774 			/* Couldn't decode the question name */
775 			free(npb);
776 			return (NULL);
777 		}
778 
779 		scan += name_len;
780 		if (scan + 4 > scan_end) {
781 			/* no room for Question Type(2) and Class(2) fields */
782 			free(npb);
783 			return (NULL);
784 		}
785 
786 		npb->question[i].question_type = BE_IN16(scan); scan += 2;
787 		npb->question[i].question_class = BE_IN16(scan); scan += 2;
788 	}
789 
790 	/*
791 	 * Cheat. Remaining sections are of the same resource_record
792 	 * format. Table space is consecutive.
793 	 */
794 
795 	for (i = 0; i < (ancount + nscount + arcount); i++) {
796 		if (scan[0] == 0xc0) {
797 			/* Namebuf is reused... */
798 			rc = 2;
799 		} else {
800 			name_len = smb_netbios_getname(name_buf, (char *)scan,
801 			    (char *)scan_end);
802 			if (name_len <= 0) {
803 				free(npb);
804 				return (NULL);
805 			}
806 			rc = name_len;
807 		}
808 		scan += rc;
809 
810 		if (scan + 10 > scan_end) {
811 			/*
812 			 * no room for RR_TYPE (2), RR_CLASS (2), TTL (4) and
813 			 * RDLENGTH (2) fields.
814 			 */
815 			free(npb);
816 			return (NULL);
817 		}
818 
819 		smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
820 		    nrr[i].name);
821 		if ((rc = smb_first_level_name_decode((unsigned char *)name_buf,
822 		    nrr[i].name)) < 0) {
823 			free(npb);
824 			return (NULL);
825 		}
826 
827 		nrr[i].rr_type = BE_IN16(scan); scan += 2;
828 		nrr[i].rr_class = BE_IN16(scan); scan += 2;
829 		nrr[i].ttl = BE_IN32(scan); scan += 4;
830 		nrr[i].rdlength = BE_IN16(scan); scan += 2;
831 
832 		if ((n = nrr[i].rdlength) > 0) {
833 			if ((scan + n) > scan_end) {
834 				/* no room for RDATA */
835 				free(npb);
836 				return (NULL);
837 			}
838 			bcopy(scan, heap, n);
839 
840 			nn = n;
841 			if (nrr[i].rr_type == 0x0020 &&
842 			    nrr[i].rr_class == 0x01 && n >= 6) {
843 				while (nn) {
844 					if (nn == 6)
845 						next = &nrr[i].name->addr_list;
846 					else {
847 						next = malloc(
848 						    sizeof (addr_entry_t));
849 						if (next == 0) {
850 							/* not enough memory */
851 							free(npb);
852 							return (NULL);
853 						}
854 						QUEUE_INSERT_TAIL(
855 						    &nrr[i].name->addr_list,
856 						    next);
857 					}
858 					nrr[i].name->attributes =
859 					    BE_IN16(scan);
860 					next->sin.sin_family = AF_INET;
861 					next->sinlen = sizeof (next->sin);
862 					(void) memcpy(
863 					    &next->sin.sin_addr.s_addr,
864 					    scan + 2, sizeof (uint32_t));
865 					next->sin.sin_port =
866 					    htons(IPPORT_NETBIOS_DGM);
867 					nn -= 6;
868 					scan += 6;
869 				}
870 			} else {
871 				nrr[i].rdata = heap;
872 				scan += n;
873 			}
874 			heap += n;
875 		}
876 	}
877 	return (npb);
878 }
879 
880 /*
881  * smb_send_name_service_packet
882  *
883  * Description:
884  *
885  *	Send out a name service packet to proper destination.
886  *
887  * Inputs:
888  *	struct netbios_name *dest	-> NETBIOS name of destination
889  *	struct name_packet *packet	-> Packet to send
890  *
891  * Returns:
892  *	success	->  >0
893  *	failure	-> <=0
894  */
895 static int
896 smb_send_name_service_packet(addr_entry_t *addr, struct name_packet *packet)
897 {
898 	unsigned char buf[MAX_DATAGRAM_LENGTH];
899 	int len;
900 
901 	if ((len = smb_name_buf_from_packet(buf, sizeof (buf), packet)) < 0) {
902 		errno = EINVAL;
903 		return (-1);
904 	}
905 
906 	return (sendto(name_sock, buf, len, MSG_EOR,
907 	    (struct sockaddr *)&addr->sin, addr->sinlen));
908 }
909 
910 /*
911  * smb_netbios_send_rcv
912  *
913  * This function sends the given NetBIOS packet to the given
914  * address and get back the response. If send operation is not
915  * successful, it's repeated 'retries' times.
916  *
917  * Returns:
918  *		0		Unsuccessful send operation; no reply
919  *		1		Got reply
920  */
921 static int
922 smb_netbios_send_rcv(int bcast, addr_entry_t *destination,
923     struct name_packet *packet, uint32_t retries, uint32_t timeout)
924 {
925 	uint32_t retry;
926 	uint16_t	tid;
927 	struct timespec st;
928 	int	rc;
929 
930 	for (retry = 0; retry < retries; retry++) {
931 		if ((destination->flags & ADDR_FLAG_VALID) == 0)
932 			return (0);
933 
934 		tid = smb_netbios_name_trn_id();
935 		packet->name_trn_id = tid;
936 		if (smb_send_name_service_packet(destination, packet) >= 0) {
937 			rc = smb_netbios_process_response(tid, destination,
938 			    packet, timeout);
939 
940 			if ((rc > 0) || (bcast == BROADCAST))
941 				return (1);
942 
943 			if (rc != 0)
944 				return (0);
945 		}
946 
947 		st.tv_sec = 0;
948 		st.tv_nsec = (timeout * 1000000);
949 		(void) nanosleep(&st, 0);
950 	}
951 
952 	return (0);
953 }
954 
955 /*
956  * RFC 1002 4.2.2.  NAME REGISTRATION REQUEST
957  */
958 static int
959 smb_send_name_registration_request(int bcast, struct name_question *question,
960     struct resource_record *additional)
961 {
962 	int gotreply = 0;
963 	uint32_t retries;
964 	uint32_t timeout;
965 	addr_entry_t *destination;
966 	struct name_packet packet;
967 	unsigned char type;
968 	int i, addr_num, rc;
969 
970 	type = question->name->name[15];
971 	if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
972 		syslog(LOG_DEBUG, "nbns: name registration bad type (0x%02x)",
973 		    type);
974 		smb_netbios_name_logf(question->name);
975 		question->name->attributes &= ~NAME_ATTR_LOCAL;
976 		return (-1);
977 	}
978 
979 	if (bcast == BROADCAST) {
980 		if (bcast_num == 0)
981 			return (0);
982 		destination = smb_bcast_list;
983 		addr_num = bcast_num;
984 		retries = BCAST_REQ_RETRY_COUNT;
985 		timeout = BCAST_REQ_RETRY_TIMEOUT;
986 		packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_BROADCAST;
987 	} else {
988 		if (nbns_num == 0)
989 			return (0);
990 		destination = smb_nbns;
991 		addr_num = nbns_num;
992 		retries = UCAST_REQ_RETRY_COUNT;
993 		timeout = UCAST_REQ_RETRY_TIMEOUT;
994 		packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_UNICAST;
995 	}
996 
997 	packet.qdcount = 1;	/* question entries */
998 	packet.question = question;
999 	packet.ancount = 0;	/* answer recs */
1000 	packet.answer = NULL;
1001 	packet.nscount = 0;	/* authority recs */
1002 	packet.authority = NULL;
1003 	packet.arcount = 1;	/* additional recs */
1004 	packet.additional = additional;
1005 
1006 	if (IS_UNIQUE(question->name->attributes) &&
1007 	    (is_multihome((char *)(question->name->name))))
1008 		packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST;
1009 
1010 	for (i = 0; i < addr_num; i++) {
1011 		/*
1012 		 * Only register with the Primary WINS server,
1013 		 * unless we got no reply.
1014 		 */
1015 		if ((bcast == UNICAST) && gotreply)
1016 			break;
1017 
1018 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1019 		    retries, timeout);
1020 		if (rc == 1)
1021 			gotreply = 1;
1022 	}
1023 
1024 	return (gotreply);
1025 }
1026 
1027 /*
1028  * RFC 1002 4.2.4.  NAME REFRESH REQUEST
1029  */
1030 /*ARGSUSED*/
1031 static int
1032 smb_send_name_refresh_request(int bcast, struct name_question *question,
1033     struct resource_record *additional, int force)
1034 {
1035 	int rc = 0;
1036 	int gotreply = 0;
1037 	uint32_t retries;
1038 	uint32_t timeout;
1039 	addr_entry_t *addr;
1040 	addr_entry_t *destination;
1041 	struct name_packet packet;
1042 	unsigned char type;
1043 	int i, addr_num, q_addrs = 0;
1044 
1045 	type = question->name->name[15];
1046 	if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
1047 		syslog(LOG_DEBUG, "nbns: name refresh bad type (0x%02x)", type);
1048 		smb_netbios_name_logf(question->name);
1049 		question->name->attributes &= ~NAME_ATTR_LOCAL;
1050 		return (-1);
1051 	}
1052 	switch (bcast) {
1053 	case BROADCAST :
1054 		if (bcast_num == 0)
1055 			return (-1);
1056 		destination = smb_bcast_list;
1057 		addr_num = bcast_num;
1058 		retries = BCAST_REQ_RETRY_COUNT;
1059 		timeout = BCAST_REQ_RETRY_TIMEOUT;
1060 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_BROADCAST;
1061 		break;
1062 
1063 	case UNICAST :
1064 		if (nbns_num == 0)
1065 			return (-1);
1066 		destination = smb_nbns;
1067 		addr_num = nbns_num;
1068 		retries = UCAST_REQ_RETRY_COUNT;
1069 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1070 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST;
1071 		break;
1072 
1073 	default:
1074 		destination = &question->name->addr_list;
1075 		/*
1076 		 * the value of addr_num is irrelvant here, because
1077 		 * the code is going to do special_process so it doesn't
1078 		 * need the addr_num. We set a value here just to avoid
1079 		 * compiler warning.
1080 		 */
1081 		addr_num = 0;
1082 		retries = UCAST_REQ_RETRY_COUNT;
1083 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1084 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST;
1085 		q_addrs = 1;
1086 		break;
1087 	}
1088 
1089 	if (IS_UNIQUE(question->name->attributes) &&
1090 	    (is_multihome((char *)(question->name->name))))
1091 		packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST;
1092 
1093 	packet.qdcount = 1;	/* question entries */
1094 	packet.question = question;
1095 	packet.ancount = 0;	/* answer recs */
1096 	packet.answer = NULL;
1097 	packet.nscount = 0;	/* authority recs */
1098 	packet.authority = NULL;
1099 	packet.arcount = 1;	/* additional recs */
1100 	packet.additional = additional;
1101 
1102 	if (q_addrs)
1103 		goto special_process;
1104 
1105 	for (i = 0; i < addr_num; i++) {
1106 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1107 		    retries, timeout);
1108 		if (rc == 1)
1109 			gotreply = 1;
1110 	}
1111 
1112 	return (gotreply);
1113 
1114 special_process:
1115 	addr = destination;
1116 	do {
1117 		rc = smb_netbios_send_rcv(bcast, addr, &packet,
1118 		    retries, timeout);
1119 		if (rc == 1)
1120 			gotreply = 1;
1121 		addr = addr->forw;
1122 	} while (addr != destination);
1123 
1124 	return (gotreply);
1125 }
1126 
1127 /*
1128  * RFC 1002 4.2.5.  POSITIVE NAME REGISTRATION RESPONSE
1129  * RFC 1002 4.2.6.  NEGATIVE NAME REGISTRATION RESPONSE
1130  */
1131 static int
1132 smb_send_name_registration_response(addr_entry_t *addr,
1133     struct name_packet *original_packet, uint16_t rcode)
1134 {
1135 	struct name_packet	packet;
1136 	struct resource_record	answer;
1137 
1138 	bzero(&packet, sizeof (struct name_packet));
1139 	bzero(&answer, sizeof (struct resource_record));
1140 
1141 	packet.name_trn_id = original_packet->name_trn_id;
1142 	packet.info = NAME_REGISTRATION_RESPONSE | NAME_NM_FLAGS_RA |
1143 	    (rcode & NAME_RCODE_MASK);
1144 	packet.qdcount = 0;	/* question entries */
1145 	packet.question = NULL;
1146 	packet.ancount = 1;	/* answer recs */
1147 	packet.answer = &answer;
1148 	packet.nscount = 0;	/* authority recs */
1149 	packet.authority = NULL;
1150 	packet.arcount = 0;	/* additional recs */
1151 	packet.additional = NULL;
1152 
1153 	answer.name = original_packet->question->name;
1154 	answer.rr_type = NAME_QUESTION_TYPE_NB;
1155 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1156 	answer.ttl = original_packet->additional->ttl;
1157 	answer.rdlength = original_packet->additional->rdlength;
1158 	answer.rdata = original_packet->additional->rdata;
1159 
1160 	return (smb_send_name_service_packet(addr, &packet));
1161 }
1162 
1163 /*
1164  * RFC 1002 4.2.9.  NAME RELEASE REQUEST & DEMAND
1165  */
1166 static int
1167 smb_send_name_release_request_and_demand(int bcast,
1168     struct name_question *question, struct resource_record *additional)
1169 {
1170 	int gotreply = 0;
1171 	int i, rc;
1172 	int addr_num;
1173 	uint32_t retries;
1174 	uint32_t timeout;
1175 	addr_entry_t *destination;
1176 	struct name_packet packet;
1177 
1178 	if (bcast == BROADCAST) {
1179 		if (bcast_num == 0)
1180 			return (-1);
1181 		destination = smb_bcast_list;
1182 		addr_num = bcast_num;
1183 		retries = 1; /* BCAST_REQ_RETRY_COUNT */
1184 		timeout = 100; /* BCAST_REQ_RETRY_TIMEOUT */
1185 		packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_BROADCAST;
1186 	} else {
1187 		if (nbns_num == 0)
1188 			return (-1);
1189 		destination = smb_nbns;
1190 		addr_num = nbns_num;
1191 		retries = 1; /* UCAST_REQ_RETRY_COUNT */
1192 		timeout = 100; /* UCAST_REQ_RETRY_TIMEOUT */
1193 		packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_UNICAST;
1194 	}
1195 
1196 	packet.qdcount = 1;	/* question entries */
1197 	packet.question = question;
1198 	packet.ancount = 0;	/* answer recs */
1199 	packet.answer = NULL;
1200 	packet.nscount = 0;	/* authority recs */
1201 	packet.authority = NULL;
1202 	packet.arcount = 1;	/* additional recs */
1203 	packet.additional = additional;
1204 
1205 	for (i = 0; i < addr_num; i++) {
1206 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1207 		    retries, timeout);
1208 		if (rc == 1)
1209 			gotreply = 1;
1210 	}
1211 
1212 	return (gotreply);
1213 }
1214 
1215 /*
1216  * RFC 1002 4.2.10.  POSITIVE NAME RELEASE RESPONSE
1217  * RFC 1002 4.2.11.  NEGATIVE NAME RELEASE RESPONSE
1218  */
1219 static int
1220 /* LINTED - E_STATIC_UNUSED */
1221 smb_send_name_release_response(addr_entry_t *addr,
1222     struct name_packet *original_packet, uint16_t rcode)
1223 {
1224 	struct name_packet	packet;
1225 	struct resource_record	answer;
1226 
1227 	bzero(&packet, sizeof (struct name_packet));
1228 	bzero(&answer, sizeof (struct resource_record));
1229 
1230 	packet.name_trn_id = original_packet->name_trn_id;
1231 	packet.info = NAME_RELEASE_RESPONSE | (rcode & NAME_RCODE_MASK);
1232 	packet.qdcount = 0;	/* question entries */
1233 	packet.question = NULL;
1234 	packet.ancount = 1;	/* answer recs */
1235 	packet.answer = &answer;
1236 	packet.nscount = 0;	/* authority recs */
1237 	packet.authority = NULL;
1238 	packet.arcount = 0;	/* additional recs */
1239 	packet.additional = NULL;
1240 
1241 	answer.name = original_packet->question->name;
1242 	answer.rr_type = NAME_QUESTION_TYPE_NB;
1243 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1244 	answer.ttl = original_packet->additional->ttl;
1245 	answer.rdlength = original_packet->additional->rdlength;
1246 	answer.rdata = original_packet->additional->rdata;
1247 
1248 	return (smb_send_name_service_packet(addr, &packet));
1249 }
1250 
1251 /*
1252  * RFC 1002 4.2.12.  NAME QUERY REQUEST
1253  */
1254 static int
1255 smb_send_name_query_request(int bcast, struct name_question *question)
1256 {
1257 	int			rc = 0;
1258 	uint32_t		retry, retries;
1259 	uint32_t		timeout;
1260 	uint16_t		tid;
1261 	addr_entry_t		*destination;
1262 	struct name_packet	packet;
1263 	int 			i, addr_num;
1264 	struct timespec 	st;
1265 
1266 	if (bcast == BROADCAST) {
1267 		if (bcast_num == 0)
1268 			return (-1);
1269 		destination = smb_bcast_list;
1270 		addr_num = bcast_num;
1271 		retries = BCAST_REQ_RETRY_COUNT;
1272 		timeout = BCAST_REQ_RETRY_TIMEOUT;
1273 		packet.info = NAME_QUERY_REQUEST | NM_FLAGS_BROADCAST;
1274 	} else {
1275 		if (nbns_num == 0)
1276 			return (-1);
1277 		destination = smb_nbns;
1278 		addr_num = nbns_num;
1279 		retries = UCAST_REQ_RETRY_COUNT;
1280 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1281 		packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST;
1282 	}
1283 	packet.qdcount = 1;	/* question entries */
1284 	packet.question = question;
1285 	packet.ancount = 0;	/* answer recs */
1286 	packet.answer = NULL;
1287 	packet.nscount = 0;	/* authority recs */
1288 	packet.authority = NULL;
1289 	packet.arcount = 0;	/* additional recs */
1290 	packet.additional = NULL;
1291 
1292 	for (i = 0; i < addr_num; i++) {
1293 		for (retry = 0; retry < retries; retry++) {
1294 			if ((destination[i].flags & ADDR_FLAG_VALID) == 0)
1295 				break;
1296 			tid = smb_netbios_name_trn_id();
1297 			packet.name_trn_id = tid;
1298 
1299 			if (smb_send_name_service_packet(&destination[i],
1300 			    &packet) >= 0) {
1301 				if ((rc = smb_netbios_process_response(tid,
1302 				    &destination[i],
1303 				    &packet, timeout)) != 0)
1304 					break;
1305 			}
1306 			st.tv_sec = 0;
1307 			st.tv_nsec = (timeout * 1000000);
1308 			(void) nanosleep(&st, 0);
1309 		}
1310 	}
1311 
1312 	return (rc);
1313 }
1314 
1315 /*
1316  * RFC 1002 4.2.13.  POSITIVE NAME QUERY RESPONSE
1317  * RFC 1002 4.2.14.  NEGATIVE NAME QUERY RESPONSE
1318  */
1319 static int
1320 smb_send_name_query_response(addr_entry_t *addr,
1321     struct name_packet *original_packet, struct name_entry *entry,
1322     uint16_t rcode)
1323 {
1324 	addr_entry_t		*raddr;
1325 	struct name_packet	packet;
1326 	struct resource_record	answer;
1327 	uint16_t		attr;
1328 	unsigned char 		data[MAX_DATAGRAM_LENGTH];
1329 	unsigned char 		*scan = data;
1330 	uint32_t		ret_addr;
1331 
1332 	packet.name_trn_id = original_packet->name_trn_id;
1333 	packet.info = NAME_QUERY_RESPONSE | (rcode & NAME_RCODE_MASK);
1334 	packet.qdcount = 0;	/* question entries */
1335 	packet.question = NULL;
1336 	packet.ancount = 1;	/* answer recs */
1337 	packet.answer = &answer;
1338 	packet.nscount = 0;	/* authority recs */
1339 	packet.authority = NULL;
1340 	packet.arcount = 0;	/* additional recs */
1341 	packet.additional = NULL;
1342 
1343 	answer.name = entry;
1344 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1345 	answer.ttl = entry->addr_list.ttl;
1346 	answer.rdata = data;
1347 	if (rcode) {
1348 		answer.rr_type = NAME_RR_TYPE_NULL;
1349 		answer.rdlength = 0;
1350 		bzero(data, 6);
1351 	} else {
1352 		answer.rdlength = 0;
1353 		answer.rr_type = NAME_QUESTION_TYPE_NB;
1354 		raddr = &entry->addr_list;
1355 		scan = data;
1356 		do {
1357 			attr = entry->attributes & (NAME_ATTR_GROUP |
1358 			    NAME_ATTR_OWNER_NODE_TYPE);
1359 
1360 			BE_OUT16(scan, attr); scan += 2;
1361 			ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1362 			*scan++ = ret_addr;
1363 			*scan++ = ret_addr >> 8;
1364 			*scan++ = ret_addr >> 16;
1365 			*scan++ = ret_addr >> 24;
1366 
1367 			answer.rdlength += 6;
1368 			raddr = raddr->forw;
1369 		} while (raddr != &entry->addr_list);
1370 	}
1371 
1372 	return (smb_send_name_service_packet(addr, &packet));
1373 }
1374 
1375 /*
1376  * RFC 1002 4.2.18.  NODE STATUS RESPONSE
1377  */
1378 static int
1379 smb_send_node_status_response(addr_entry_t *addr,
1380     struct name_packet *original_packet)
1381 {
1382 	uint32_t		net_ipaddr;
1383 	int64_t			max_connections;
1384 	struct arpreq 		arpreq;
1385 	struct name_packet	packet;
1386 	struct resource_record	answer;
1387 	unsigned char 		*scan;
1388 	unsigned char 		*scan_end;
1389 	unsigned char		data[MAX_NETBIOS_REPLY_DATA_SIZE];
1390 	boolean_t scan_done = B_FALSE;
1391 	smb_inaddr_t ipaddr;
1392 
1393 	bzero(&packet, sizeof (struct name_packet));
1394 	bzero(&answer, sizeof (struct resource_record));
1395 
1396 	packet.name_trn_id = original_packet->name_trn_id;
1397 	packet.info = NODE_STATUS_RESPONSE;
1398 	packet.qdcount = 0;	/* question entries */
1399 	packet.question = NULL;
1400 	packet.ancount = 1;	/* answer recs */
1401 	packet.answer = &answer;
1402 	packet.nscount = 0;	/* authority recs */
1403 	packet.authority = NULL;
1404 	packet.arcount = 0;	/* additional recs */
1405 	packet.additional = NULL;
1406 
1407 	answer.name = original_packet->question->name;
1408 	answer.rr_type = NAME_RR_TYPE_NBSTAT;
1409 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1410 	answer.ttl = 0;
1411 	answer.rdata = data;
1412 
1413 	scan = smb_netbios_cache_status(data, MAX_NETBIOS_REPLY_DATA_SIZE,
1414 	    original_packet->question->name->scope);
1415 
1416 	scan_end = data + MAX_NETBIOS_REPLY_DATA_SIZE;
1417 
1418 	ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr;
1419 	ipaddr.a_family = AF_INET;
1420 	if (smb_nic_is_same_subnet(&ipaddr))
1421 		net_ipaddr = addr->sin.sin_addr.s_addr;
1422 	else
1423 		net_ipaddr = 0;
1424 
1425 	(void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &max_connections);
1426 
1427 	while (!scan_done) {
1428 		if ((scan + 6) >= scan_end) {
1429 			packet.info |= NAME_NM_FLAGS_TC;
1430 			break;
1431 		}
1432 
1433 		if (net_ipaddr != 0) {
1434 			struct sockaddr_in *s_in;
1435 			int s;
1436 
1437 			s = socket(AF_INET, SOCK_DGRAM, 0);
1438 			/* LINTED - E_BAD_PTR_CAST_ALIGN */
1439 			s_in = (struct sockaddr_in *)&arpreq.arp_pa;
1440 			s_in->sin_family = AF_INET;
1441 			s_in->sin_addr.s_addr = net_ipaddr;
1442 			if (ioctl(s, SIOCGARP, (caddr_t)&arpreq) < 0) {
1443 				bzero(scan, 6);
1444 			} else {
1445 				bcopy(&arpreq.arp_ha.sa_data, scan, 6);
1446 			}
1447 			(void) close(s);
1448 		} else {
1449 			bzero(scan, 6);
1450 		}
1451 		scan += 6;
1452 
1453 		if ((scan + 26) >= scan_end) {
1454 			packet.info |= NAME_NM_FLAGS_TC;
1455 			break;
1456 		}
1457 		bzero(scan, 26);
1458 		scan += 26;
1459 
1460 		if ((scan + 2) >= scan_end) {
1461 			packet.info |= NAME_NM_FLAGS_TC;
1462 			break;
1463 		}
1464 		BE_OUT16(scan, 0); scan += 2;
1465 
1466 		if ((scan + 2) >= scan_end) {
1467 			packet.info |= NAME_NM_FLAGS_TC;
1468 			break;
1469 		}
1470 		BE_OUT16(scan, 0); scan += 2;
1471 
1472 		if ((scan + 2) >= scan_end) {
1473 			packet.info |= NAME_NM_FLAGS_TC;
1474 			break;
1475 		}
1476 		BE_OUT16(scan, 0); scan += 2;
1477 
1478 		if ((scan + 2) >= scan_end) {
1479 			packet.info |= NAME_NM_FLAGS_TC;
1480 			break;
1481 		}
1482 		BE_OUT16(scan, 0); scan += 2;
1483 
1484 		if ((scan + 2) >= scan_end) {
1485 			packet.info |= NAME_NM_FLAGS_TC;
1486 			break;
1487 		}
1488 		BE_OUT16(scan, 0); scan += 2;
1489 
1490 		if ((scan + 2) >= scan_end) {
1491 			packet.info |= NAME_NM_FLAGS_TC;
1492 			break;
1493 		}
1494 		BE_OUT16(scan, 0); scan += 2;
1495 
1496 		if ((scan + 2) >= scan_end) {
1497 			packet.info |= NAME_NM_FLAGS_TC;
1498 			break;
1499 		}
1500 		BE_OUT16(scan, 0); scan += 2;
1501 
1502 		if ((scan + 2) >= scan_end) {
1503 			packet.info |= NAME_NM_FLAGS_TC;
1504 			break;
1505 		}
1506 		BE_OUT16(scan, max_connections); scan += 2;
1507 
1508 		if ((scan + 2) >= scan_end) {
1509 			packet.info |= NAME_NM_FLAGS_TC;
1510 			break;
1511 		}
1512 
1513 		BE_OUT16(scan, 0); scan += 2;
1514 
1515 		scan_done = B_TRUE;
1516 	}
1517 	answer.rdlength = scan - data;
1518 	return (smb_send_name_service_packet(addr, &packet));
1519 }
1520 
1521 static int
1522 smb_name_Bnode_add_name(struct name_entry *name)
1523 {
1524 	struct name_question		question;
1525 	struct resource_record		additional;
1526 	unsigned char 			data[8];
1527 	uint16_t			attr;
1528 	addr_entry_t			*addr;
1529 	int rc = 0;
1530 
1531 	addr = &name->addr_list;
1532 
1533 	do {
1534 		/* build name service packet */
1535 		question.name = name;
1536 		/*
1537 		 * question.name->attributes |= NAME_NB_FLAGS_ONT_B;
1538 		 * This is commented because NAME_NB_FLAGS_ONT_B is 0
1539 		 */
1540 		question.question_type = NAME_QUESTION_TYPE_NB;
1541 		question.question_class = NAME_QUESTION_CLASS_IN;
1542 
1543 		additional.name = name;
1544 		additional.rr_class = NAME_QUESTION_CLASS_IN;
1545 		additional.ttl = 0;
1546 		additional.rdata = data;
1547 		additional.rdlength = 6;
1548 		additional.rr_type = NAME_QUESTION_TYPE_NB;
1549 		attr = name->attributes & (NAME_ATTR_GROUP |
1550 		    NAME_ATTR_OWNER_NODE_TYPE);
1551 
1552 		BE_OUT16(&data[0], attr);
1553 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1554 		    sizeof (uint32_t));
1555 
1556 		rc |= smb_send_name_registration_request(BROADCAST, &question,
1557 		    &additional);
1558 		addr = addr->forw;
1559 
1560 	} while (addr != &name->addr_list);
1561 
1562 	return (rc);
1563 }
1564 
1565 static int
1566 smb_name_Bnode_find_name(struct name_entry *name)
1567 {
1568 	struct name_question	question;
1569 
1570 	question.name = name;
1571 	question.question_type = NAME_QUESTION_TYPE_NB;
1572 	question.question_class = NAME_QUESTION_CLASS_IN;
1573 
1574 	return (smb_send_name_query_request(BROADCAST, &question));
1575 }
1576 
1577 static int
1578 smb_name_Bnode_delete_name(struct name_entry *name)
1579 {
1580 	struct name_question	question;
1581 	struct resource_record	additional;
1582 	addr_entry_t		*raddr;
1583 	unsigned char		data[MAX_DATAGRAM_LENGTH];
1584 	unsigned char		*scan = data;
1585 	uint32_t		attr;
1586 	uint32_t		ret_addr;
1587 
1588 	/* build packet */
1589 	question.name = name;
1590 	question.question_type = NAME_QUESTION_TYPE_NB;
1591 	question.question_class = NAME_QUESTION_CLASS_IN;
1592 
1593 	additional.name = name;
1594 	additional.rr_class = NAME_QUESTION_CLASS_IN;
1595 	additional.ttl = 0;
1596 	additional.rdata = data;
1597 	additional.rdlength = 0;
1598 	additional.rr_type = NAME_QUESTION_TYPE_NB;
1599 	raddr = &name->addr_list;
1600 	scan = data;
1601 	do {
1602 		attr = name->attributes & (NAME_ATTR_GROUP |
1603 		    NAME_ATTR_OWNER_NODE_TYPE);
1604 
1605 		BE_OUT16(scan, attr); scan += 2;
1606 		ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1607 		*scan++ = ret_addr;
1608 		*scan++ = ret_addr >> 8;
1609 		*scan++ = ret_addr >> 16;
1610 		*scan++ = ret_addr >> 24;
1611 
1612 		additional.rdlength += 6;
1613 	} while (raddr != &name->addr_list);
1614 
1615 	return (smb_send_name_release_request_and_demand(BROADCAST,
1616 	    &question, &additional));
1617 }
1618 
1619 static int
1620 smb_name_Pnode_add_name(struct name_entry *name)
1621 {
1622 	struct name_question		question;
1623 	struct resource_record		additional;
1624 	unsigned char 			data[8];
1625 	uint16_t			attr;
1626 	addr_entry_t			*addr;
1627 	int rc = 0;
1628 
1629 	/* build packet */
1630 	addr = &name->addr_list;
1631 	do {
1632 		question.name = name;
1633 		question.question_type = NAME_QUESTION_TYPE_NB;
1634 		question.question_class = NAME_QUESTION_CLASS_IN;
1635 
1636 		additional.name = name;
1637 		additional.rr_class = NAME_QUESTION_CLASS_IN;
1638 		additional.ttl = 0;
1639 		additional.rdata = data;
1640 		additional.rdlength = 6;
1641 		additional.rr_type = NAME_QUESTION_TYPE_NB;
1642 		attr = name->attributes &
1643 		    (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE);
1644 
1645 		BE_OUT16(&data[0], attr);
1646 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1647 		    sizeof (uint32_t));
1648 
1649 		rc |= smb_send_name_registration_request(UNICAST, &question,
1650 		    &additional);
1651 
1652 		addr = addr->forw;
1653 
1654 	} while (addr != &name->addr_list);
1655 
1656 	return (rc);
1657 }
1658 
1659 static int
1660 smb_name_Pnode_refresh_name(struct name_entry *name)
1661 {
1662 	struct name_question		question;
1663 	struct resource_record		additional;
1664 	unsigned char 			data[8];
1665 	uint16_t			attr;
1666 	addr_entry_t			*addr;
1667 	int rc = 0;
1668 
1669 	/* build packet */
1670 	addr = &name->addr_list;
1671 	do {
1672 		question.name = name;
1673 		question.question_type = NAME_QUESTION_TYPE_NB;
1674 		question.question_class = NAME_QUESTION_CLASS_IN;
1675 
1676 		additional.name = name;
1677 		additional.rr_class = NAME_QUESTION_CLASS_IN;
1678 		additional.ttl = 0;
1679 		additional.rdata = data;
1680 		additional.rdlength = 6;
1681 		additional.rr_type = NAME_QUESTION_TYPE_NB;
1682 		attr = name->attributes &
1683 		    (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE);
1684 
1685 		BE_OUT16(&data[0], attr);
1686 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1687 		    sizeof (uint32_t));
1688 
1689 		rc |= smb_send_name_refresh_request(UNICAST, &question,
1690 		    &additional, 1);
1691 
1692 		addr = addr->forw;
1693 	} while (addr != &name->addr_list);
1694 
1695 	return (rc);
1696 }
1697 
1698 static int
1699 smb_name_Pnode_find_name(struct name_entry *name)
1700 {
1701 	struct name_question	question;
1702 
1703 	/*
1704 	 * Host initiated processing for a P node
1705 	 */
1706 	question.name = name;
1707 	question.name->attributes |= NAME_NB_FLAGS_ONT_P;
1708 	question.question_type = NAME_QUESTION_TYPE_NB;
1709 	question.question_class = NAME_QUESTION_CLASS_IN;
1710 
1711 	return (smb_send_name_query_request(UNICAST, &question));
1712 }
1713 
1714 static int
1715 smb_name_Pnode_delete_name(struct name_entry *name)
1716 {
1717 	struct name_question	question;
1718 	struct resource_record	additional;
1719 	addr_entry_t		*raddr;
1720 	unsigned char		data[MAX_DATAGRAM_LENGTH];
1721 	unsigned char		*scan = data;
1722 	uint32_t		attr;
1723 	uint32_t		ret_addr;
1724 
1725 	/* build packet */
1726 	question.name = name;
1727 	question.name->attributes |= NAME_NB_FLAGS_ONT_P;
1728 	question.question_type = NAME_QUESTION_TYPE_NB;
1729 	question.question_class = NAME_QUESTION_CLASS_IN;
1730 
1731 	additional.name = name;
1732 	additional.rr_class = NAME_QUESTION_CLASS_IN;
1733 	additional.ttl = 0;
1734 	additional.rdata = data;
1735 	additional.rdlength = 0;
1736 	additional.rr_type = NAME_QUESTION_TYPE_NB;
1737 	raddr = &name->addr_list;
1738 	do {
1739 		scan = data;
1740 		attr = name->attributes & (NAME_ATTR_GROUP |
1741 		    NAME_ATTR_OWNER_NODE_TYPE);
1742 
1743 		BE_OUT16(scan, attr); scan += 2;
1744 		ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1745 		*scan++ = ret_addr;
1746 		*scan++ = ret_addr >> 8;
1747 		*scan++ = ret_addr >> 16;
1748 		*scan++ = ret_addr >> 24;
1749 
1750 		additional.rdlength = 6;
1751 		raddr = raddr->forw;
1752 		(void) smb_send_name_release_request_and_demand(UNICAST,
1753 		    &question, &additional);
1754 	} while (raddr != &name->addr_list);
1755 
1756 	return (1);
1757 }
1758 
1759 static int
1760 smb_name_Mnode_add_name(struct name_entry *name)
1761 {
1762 	if (smb_name_Bnode_add_name(name) > 0) {
1763 		if (nbns_num == 0)
1764 			return (1); /* No name server configured */
1765 
1766 		return (smb_name_Pnode_add_name(name));
1767 	}
1768 	return (-1);
1769 }
1770 
1771 static int
1772 smb_name_Hnode_add_name(struct name_entry *name)
1773 {
1774 	if (nbns_num > 0) {
1775 		if (smb_name_Pnode_add_name(name) == 1)
1776 			return (1);
1777 	}
1778 
1779 	return (smb_name_Bnode_add_name(name));
1780 }
1781 
1782 static int
1783 smb_name_Mnode_find_name(struct name_entry *name)
1784 {
1785 	if (smb_name_Bnode_find_name(name) == 1)
1786 		return (1);
1787 
1788 	if (nbns_num == 0)
1789 		return (1); /* No name server configured */
1790 
1791 	return (smb_name_Pnode_find_name(name));
1792 }
1793 
1794 static int
1795 smb_name_Hnode_find_name(struct name_entry *name)
1796 {
1797 	if (nbns_num > 0)
1798 		if (smb_name_Pnode_find_name(name) == 1)
1799 			return (1);
1800 
1801 	return (smb_name_Bnode_find_name(name));
1802 }
1803 
1804 static int
1805 smb_name_Mnode_delete_name(struct name_entry *name)
1806 {
1807 	(void) smb_name_Bnode_delete_name(name);
1808 
1809 	if (nbns_num == 0)
1810 		return (-1); /* No name server configured */
1811 
1812 	if (smb_name_Pnode_delete_name(name) > 0)
1813 		return (1);
1814 
1815 	return (-1);
1816 }
1817 
1818 static int
1819 smb_name_Hnode_delete_name(struct name_entry *name)
1820 {
1821 	if (nbns_num > 0)
1822 		if (smb_name_Pnode_delete_name(name) > 0)
1823 			return (1);
1824 
1825 	return (smb_name_Bnode_delete_name(name));
1826 }
1827 
1828 static void
1829 smb_name_process_Bnode_packet(struct name_packet *packet, addr_entry_t *addr)
1830 {
1831 	struct name_entry 	*name;
1832 	struct name_entry 	*entry;
1833 	struct name_question 	*question;
1834 	struct resource_record 	*additional;
1835 
1836 	question = packet->question;
1837 	additional = packet->additional;
1838 
1839 	switch (packet->info & NAME_OPCODE_OPCODE_MASK) {
1840 	case NAME_OPCODE_REFRESH:
1841 		/* Guard against malformed packets */
1842 		if ((question == 0) || (additional == 0))
1843 			break;
1844 		if (additional->name->addr_list.sin.sin_addr.s_addr == 0)
1845 			break;
1846 
1847 		name = question->name;
1848 		name->addr_list.ttl = additional->ttl;
1849 		name->attributes = additional->name->attributes;
1850 		name->addr_list.sin = additional->name->addr_list.sin;
1851 		name->addr_list.forw = name->addr_list.back = &name->addr_list;
1852 
1853 		if ((entry = smb_netbios_cache_lookup_addr(name)) != 0) {
1854 			smb_netbios_cache_update_entry(entry, question->name);
1855 			smb_netbios_cache_unlock_entry(entry);
1856 		}
1857 		else
1858 			(void) smb_netbios_cache_insert(question->name);
1859 		break;
1860 
1861 	case NAME_OPCODE_QUERY:
1862 		/*
1863 		 * This opcode covers both NAME_QUERY_REQUEST and
1864 		 * NODE_STATUS_REQUEST. They can be distinguished
1865 		 * based on the type of question entry.
1866 		 */
1867 
1868 		/* All query requests have to have question entry */
1869 		if (question == 0)
1870 			break;
1871 
1872 		if (question->question_type == NAME_QUESTION_TYPE_NB) {
1873 			name = question->name;
1874 			if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1875 				(void) smb_send_name_query_response(addr,
1876 				    packet, entry, 0);
1877 				smb_netbios_cache_unlock_entry(entry);
1878 			}
1879 		}
1880 		else
1881 		if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) {
1882 			/*
1883 			 * Name of "*" may be used to force node to
1884 			 * divulge status for administrative purposes
1885 			 */
1886 			name = question->name;
1887 			entry = 0;
1888 			if (NETBIOS_NAME_IS_STAR(name->name) ||
1889 			    ((entry = smb_netbios_cache_lookup(name)) != 0)) {
1890 				if (entry)
1891 					smb_netbios_cache_unlock_entry(entry);
1892 				/*
1893 				 * send only those names that are
1894 				 * in the same scope as the scope
1895 				 * field in the request packet
1896 				 */
1897 				(void) smb_send_node_status_response(addr,
1898 				    packet);
1899 			}
1900 		}
1901 		break;
1902 
1903 	default:
1904 		break;
1905 	}
1906 }
1907 
1908 static void
1909 smb_name_process_Pnode_packet(struct name_packet *packet, addr_entry_t *addr)
1910 {
1911 	struct name_entry 	*name;
1912 	struct name_entry 	*entry;
1913 	struct name_question 	*question;
1914 	struct resource_record 	*additional;
1915 
1916 	question = packet->question;
1917 	additional = packet->additional;
1918 
1919 	if (packet->info & NAME_NM_FLAGS_B) {
1920 		/*
1921 		 * always ignore UDP broadcast packets
1922 		 */
1923 		return;
1924 	}
1925 
1926 	switch (packet->info & NAME_OPCODE_OPCODE_MASK) {
1927 	case NAME_OPCODE_REFRESH:
1928 		/* Guard against malformed packets */
1929 		if ((question == 0) || (additional == 0))
1930 			break;
1931 		if (additional->name->addr_list.sin.sin_addr.s_addr == 0)
1932 			break;
1933 
1934 		name = question->name;
1935 		name->addr_list.ttl = additional->ttl;
1936 		name->attributes = additional->name->attributes;
1937 		name->addr_list.sin = additional->name->addr_list.sin;
1938 		name->addr_list.forw = name->addr_list.back = &name->addr_list;
1939 
1940 		if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1941 			smb_netbios_cache_update_entry(entry, name);
1942 			smb_netbios_cache_unlock_entry(entry);
1943 		}
1944 		else
1945 			(void) smb_netbios_cache_insert(name);
1946 
1947 		(void) smb_send_name_registration_response(addr, packet, 0);
1948 		break;
1949 
1950 	case NAME_OPCODE_QUERY:
1951 		/*
1952 		 * This opcode covers both NAME_QUERY_REQUEST and
1953 		 * NODE_STATUS_REQUEST. They can be distinguished
1954 		 * based on the type of question entry.
1955 		 */
1956 
1957 		/* All query requests have to have question entry */
1958 		if (question == 0)
1959 			break;
1960 
1961 		if (question->question_type == NAME_QUESTION_TYPE_NB) {
1962 			name = question->name;
1963 			if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1964 				/*
1965 				 * send response to the IP address and port
1966 				 * number from which the request was received.
1967 				 */
1968 				(void) smb_send_name_query_response(addr,
1969 				    packet, entry, 0);
1970 				smb_netbios_cache_unlock_entry(entry);
1971 			} else {
1972 				/*
1973 				 * send response to the requestor
1974 				 */
1975 				(void) smb_send_name_query_response(addr,
1976 				    packet, name, RCODE_NAM_ERR);
1977 			}
1978 		}
1979 		else
1980 		if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) {
1981 			/*
1982 			 * Name of "*" may be used to force node to
1983 			 * divulge status for administrative purposes
1984 			 */
1985 			name = question->name;
1986 			entry = 0;
1987 			if (NETBIOS_NAME_IS_STAR(name->name) ||
1988 			    ((entry = smb_netbios_cache_lookup(name)) != 0)) {
1989 				/*
1990 				 * send only those names that are
1991 				 * in the same scope as the scope
1992 				 * field in the request packet
1993 				 */
1994 				if (entry)
1995 					smb_netbios_cache_unlock_entry(entry);
1996 				(void) smb_send_node_status_response(addr,
1997 				    packet);
1998 			}
1999 		}
2000 		break;
2001 
2002 	default:
2003 		break;
2004 	}
2005 }
2006 
2007 static void
2008 smb_name_process_Mnode_packet(struct name_packet *packet, addr_entry_t *addr)
2009 {
2010 	if (packet->info & NAME_NM_FLAGS_B)
2011 		smb_name_process_Bnode_packet(packet, addr);
2012 	else
2013 		smb_name_process_Pnode_packet(packet, addr);
2014 }
2015 
2016 static void
2017 smb_name_process_Hnode_packet(struct name_packet *packet, addr_entry_t *addr)
2018 {
2019 	if (packet->info & NAME_NM_FLAGS_B)
2020 		smb_name_process_Bnode_packet(packet, addr);
2021 	else
2022 		smb_name_process_Pnode_packet(packet, addr);
2023 }
2024 
2025 
2026 /*
2027  * smb_netbios_name_tick
2028  *
2029  * Called once a second to handle name server timeouts.
2030  */
2031 void
2032 smb_netbios_name_tick(void)
2033 {
2034 	struct name_entry *name;
2035 	struct name_entry *entry;
2036 
2037 	(void) mutex_lock(&refresh_queue.mtx);
2038 	smb_netbios_cache_refresh(&refresh_queue);
2039 
2040 	while ((name = refresh_queue.head.forw) != &refresh_queue.head) {
2041 		QUEUE_CLIP(name);
2042 		if (IS_LOCAL(name->attributes)) {
2043 			if (IS_UNIQUE(name->attributes)) {
2044 				(void) smb_name_Pnode_refresh_name(name);
2045 			}
2046 		} else {
2047 			entry = smb_name_find_name(name);
2048 			smb_name_unlock_name(entry);
2049 		}
2050 		free(name);
2051 	}
2052 	(void) mutex_unlock(&refresh_queue.mtx);
2053 
2054 	smb_netbios_cache_reset_ttl();
2055 }
2056 
2057 /*
2058  * smb_name_find_name
2059  *
2060  * Lookup name cache for the given name.
2061  * If it's not in the cache it'll send a
2062  * name query request and then lookup the
2063  * cache again. Note that if a name is
2064  * returned it's locked and called MUST
2065  * unlock it by calling smb_name_unlock_name()
2066  */
2067 struct name_entry *
2068 smb_name_find_name(struct name_entry *name)
2069 {
2070 	struct name_entry *result;
2071 
2072 	if ((result = smb_netbios_cache_lookup(name)) == 0) {
2073 		switch (smb_node_type) {
2074 		case 'B':
2075 			(void) smb_name_Bnode_find_name(name);
2076 			break;
2077 		case 'P':
2078 			(void) smb_name_Pnode_find_name(name);
2079 			break;
2080 		case 'M':
2081 			(void) smb_name_Mnode_find_name(name);
2082 			break;
2083 		case 'H':
2084 		default:
2085 			(void) smb_name_Hnode_find_name(name);
2086 			break;
2087 		}
2088 		return (smb_netbios_cache_lookup(name));
2089 	}
2090 
2091 	return (result);
2092 }
2093 
2094 void
2095 smb_name_unlock_name(struct name_entry *name)
2096 {
2097 	smb_netbios_cache_unlock_entry(name);
2098 }
2099 
2100 int
2101 smb_name_add_name(struct name_entry *name)
2102 {
2103 	int			rc = 1;
2104 
2105 	smb_netbios_name_logf(name);
2106 
2107 	switch (smb_node_type) {
2108 	case 'B':
2109 		rc = smb_name_Bnode_add_name(name);
2110 		break;
2111 	case 'P':
2112 		rc = smb_name_Pnode_add_name(name);
2113 		break;
2114 	case 'M':
2115 		rc = smb_name_Mnode_add_name(name);
2116 		break;
2117 	case 'H':
2118 	default:
2119 		rc = smb_name_Hnode_add_name(name);
2120 		break;
2121 	}
2122 
2123 	if (rc >= 0)
2124 		(void) smb_netbios_cache_insert(name);
2125 
2126 	return (rc);
2127 }
2128 
2129 int
2130 smb_name_delete_name(struct name_entry *name)
2131 {
2132 	int			rc;
2133 	unsigned char type;
2134 
2135 	type = name->name[15];
2136 	if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
2137 		syslog(LOG_DEBUG, "nbns: name delete bad type (0x%02x)", type);
2138 		smb_netbios_name_logf(name);
2139 		name->attributes &= ~NAME_ATTR_LOCAL;
2140 		return (-1);
2141 	}
2142 
2143 	smb_netbios_cache_delete(name);
2144 
2145 	switch (smb_node_type) {
2146 	case 'B':
2147 		rc = smb_name_Bnode_delete_name(name);
2148 		break;
2149 	case 'P':
2150 		rc = smb_name_Pnode_delete_name(name);
2151 		break;
2152 	case 'M':
2153 		rc = smb_name_Mnode_delete_name(name);
2154 		break;
2155 	case 'H':
2156 	default:
2157 		rc = smb_name_Hnode_delete_name(name);
2158 		break;
2159 	}
2160 
2161 	if (rc > 0)
2162 		return (0);
2163 
2164 	return (-1);
2165 }
2166 
2167 typedef struct {
2168 	addr_entry_t *addr;
2169 	char *buf;
2170 	int length;
2171 } worker_param_t;
2172 
2173 /*
2174  * smb_netbios_worker
2175  *
2176  * Process incoming request/response packets for Netbios
2177  * name service (on port 138).
2178  */
2179 void *
2180 smb_netbios_worker(void *arg)
2181 {
2182 	worker_param_t *p = (worker_param_t *)arg;
2183 	addr_entry_t *addr = p->addr;
2184 	struct name_packet *packet;
2185 
2186 	if ((packet = smb_name_buf_to_packet(p->buf, p->length)) != NULL) {
2187 		if (packet->info & NAME_OPCODE_R) {
2188 			/* Reply packet */
2189 			smb_reply_ready(packet, addr);
2190 			free(p->buf);
2191 			free(p);
2192 			return (NULL);
2193 		}
2194 
2195 		/* Request packet */
2196 		switch (smb_node_type) {
2197 		case 'B':
2198 			smb_name_process_Bnode_packet(packet, addr);
2199 			break;
2200 		case 'P':
2201 			smb_name_process_Pnode_packet(packet, addr);
2202 			break;
2203 		case 'M':
2204 			smb_name_process_Mnode_packet(packet, addr);
2205 			break;
2206 		case 'H':
2207 		default:
2208 			smb_name_process_Hnode_packet(packet, addr);
2209 			break;
2210 		}
2211 
2212 		if (packet->answer)
2213 			smb_netbios_name_freeaddrs(packet->answer->name);
2214 		free(packet);
2215 	} else {
2216 		syslog(LOG_ERR, "nbns: packet decode failed");
2217 	}
2218 
2219 	free(addr);
2220 	free(p->buf);
2221 	free(p);
2222 	return (NULL);
2223 }
2224 
2225 /*
2226  * Configure the node type.  If a WINS server has been specified,
2227  * act like an H-node.  Otherwise, behave like a B-node.
2228  */
2229 static void
2230 smb_netbios_node_config(void)
2231 {
2232 	static smb_cfg_id_t	wins[SMB_PI_MAX_WINS] = {
2233 		SMB_CI_WINS_SRV1,
2234 		SMB_CI_WINS_SRV2
2235 	};
2236 	char		ipstr[16];
2237 	uint32_t	ipaddr;
2238 	int		i;
2239 
2240 	smb_node_type = SMB_NODETYPE_B;
2241 	nbns_num = 0;
2242 	bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS);
2243 
2244 	for (i = 0; i < SMB_PI_MAX_WINS; ++i) {
2245 		ipstr[0] = '\0';
2246 		(void) smb_config_getstr(wins[i], ipstr, sizeof (ipstr));
2247 
2248 		if ((ipaddr = inet_addr(ipstr)) == INADDR_NONE)
2249 			continue;
2250 
2251 		smb_node_type = SMB_NODETYPE_H;
2252 		smb_nbns[nbns_num].flags = ADDR_FLAG_VALID;
2253 		smb_nbns[nbns_num].sinlen = sizeof (struct sockaddr_in);
2254 		smb_nbns[nbns_num].sin.sin_family = AF_INET;
2255 		smb_nbns[nbns_num].sin.sin_addr.s_addr = ipaddr;
2256 		smb_nbns[nbns_num].sin.sin_port = htons(IPPORT_NETBIOS_NS);
2257 		nbns_num++;
2258 	}
2259 }
2260 
2261 static void
2262 smb_netbios_name_registration(void)
2263 {
2264 	nbcache_iter_t nbc_iter;
2265 	struct name_entry *name;
2266 	int rc;
2267 
2268 	rc = smb_netbios_cache_getfirst(&nbc_iter);
2269 	while (rc == 0) {
2270 		name = nbc_iter.nbc_entry;
2271 		(void) smb_netbios_name_logf(name);
2272 		if (IS_UNIQUE(name->attributes) && IS_LOCAL(name->attributes)) {
2273 			switch (smb_node_type) {
2274 			case SMB_NODETYPE_B:
2275 				(void) smb_name_Bnode_add_name(name);
2276 				break;
2277 			case SMB_NODETYPE_P:
2278 				(void) smb_name_Pnode_add_name(name);
2279 				break;
2280 			case SMB_NODETYPE_M:
2281 				(void) smb_name_Mnode_add_name(name);
2282 				break;
2283 			case SMB_NODETYPE_H:
2284 			default:
2285 				(void) smb_name_Hnode_add_name(name);
2286 				break;
2287 			}
2288 		}
2289 		free(name);
2290 		rc = smb_netbios_cache_getnext(&nbc_iter);
2291 	}
2292 }
2293 
2294 /*
2295  * Note that the node configuration must be setup before calling
2296  * smb_init_name_struct().
2297  */
2298 void
2299 smb_netbios_name_config(void)
2300 {
2301 	addr_entry_t		*bcast_entry;
2302 	struct name_entry	name;
2303 	smb_niciter_t		ni;
2304 	int			rc;
2305 
2306 	(void) mutex_lock(&nbt_name_config_mtx);
2307 	smb_netbios_node_config();
2308 
2309 	bcast_num = 0;
2310 	bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS);
2311 
2312 	rc = smb_nic_getfirst(&ni);
2313 	while (rc == SMB_NIC_SUCCESS) {
2314 		if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) ||
2315 		    (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS)) {
2316 			rc = smb_nic_getnext(&ni);
2317 			continue;
2318 		}
2319 
2320 		bcast_entry = &smb_bcast_list[bcast_num];
2321 		bcast_entry->flags = ADDR_FLAG_VALID;
2322 		bcast_entry->attributes = NAME_ATTR_LOCAL;
2323 		bcast_entry->sinlen = sizeof (struct sockaddr_in);
2324 		bcast_entry->sin.sin_family = AF_INET;
2325 		bcast_entry->sin.sin_port = htons(IPPORT_NETBIOS_NS);
2326 		bcast_entry->sin.sin_addr.s_addr = ni.ni_nic.nic_bcast;
2327 		bcast_num++;
2328 
2329 		smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
2330 		    NBT_WKSTA, 0, ni.ni_nic.nic_ip.a_ipv4,
2331 		    htons(IPPORT_NETBIOS_DGM),
2332 		    NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
2333 		(void) smb_netbios_cache_insert(&name);
2334 
2335 		smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
2336 		    NBT_SERVER, 0, ni.ni_nic.nic_ip.a_ipv4,
2337 		    htons(IPPORT_NETBIOS_DGM),
2338 		    NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
2339 		(void) smb_netbios_cache_insert(&name);
2340 
2341 		rc = smb_nic_getnext(&ni);
2342 	}
2343 
2344 	smb_netbios_name_registration();
2345 	(void) mutex_unlock(&nbt_name_config_mtx);
2346 }
2347 
2348 void
2349 smb_netbios_name_unconfig(void)
2350 {
2351 	struct name_entry *name;
2352 
2353 	(void) mutex_lock(&nbt_name_config_mtx);
2354 	(void) mutex_lock(&delete_queue.mtx);
2355 	smb_netbios_cache_delete_locals(&delete_queue);
2356 
2357 	while ((name = delete_queue.head.forw) != &delete_queue.head) {
2358 		QUEUE_CLIP(name);
2359 		(void) smb_name_delete_name(name);
2360 		free(name);
2361 	}
2362 	(void) mutex_unlock(&delete_queue.mtx);
2363 	(void) mutex_unlock(&nbt_name_config_mtx);
2364 }
2365 
2366 void
2367 smb_netbios_name_reconfig(void)
2368 {
2369 	smb_netbios_name_unconfig();
2370 	smb_netbios_name_config();
2371 }
2372 
2373 /*
2374  * NetBIOS Name Service (port 137)
2375  */
2376 /*ARGSUSED*/
2377 void *
2378 smb_netbios_name_service(void *arg)
2379 {
2380 	struct sockaddr_in	sin;
2381 	addr_entry_t		*addr;
2382 	int			len;
2383 	int			flag = 1;
2384 	char			*buf;
2385 	worker_param_t 		*worker_param;
2386 	smb_inaddr_t		ipaddr;
2387 
2388 	/*
2389 	 * Initialize reply_queue
2390 	 */
2391 	bzero(&reply_queue, sizeof (reply_queue));
2392 	reply_queue.forw = reply_queue.back = &reply_queue;
2393 
2394 	if ((name_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2395 		syslog(LOG_ERR, "nbns: socket failed: %m");
2396 		smb_netbios_event(NETBIOS_EVENT_ERROR);
2397 		return (NULL);
2398 	}
2399 
2400 	flag = 1;
2401 	(void) setsockopt(name_sock, SOL_SOCKET, SO_REUSEADDR, &flag,
2402 	    sizeof (flag));
2403 	flag = 1;
2404 	(void) setsockopt(name_sock, SOL_SOCKET, SO_BROADCAST, &flag,
2405 	    sizeof (flag));
2406 
2407 	bzero(&sin, sizeof (struct sockaddr_in));
2408 	sin.sin_family = AF_INET;
2409 	sin.sin_port = htons(IPPORT_NETBIOS_NS);
2410 	if (bind(name_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) {
2411 		syslog(LOG_ERR, "nbns: bind(%d) failed: %m",
2412 		    IPPORT_NETBIOS_NS);
2413 		(void) close(name_sock);
2414 		smb_netbios_event(NETBIOS_EVENT_ERROR);
2415 		return (NULL);
2416 	}
2417 
2418 	smb_netbios_event(NETBIOS_EVENT_NS_START);
2419 
2420 	while (smb_netbios_running()) {
2421 		buf = malloc(MAX_DATAGRAM_LENGTH);
2422 		addr = malloc(sizeof (addr_entry_t));
2423 		if ((buf == NULL) || (addr == NULL)) {
2424 			/* Sleep for 10 seconds and try again */
2425 			free(addr);
2426 			free(buf);
2427 			smb_netbios_sleep(10);
2428 			continue;
2429 		}
2430 ignore:		bzero(addr, sizeof (addr_entry_t));
2431 		addr->sinlen = sizeof (addr->sin);
2432 		addr->forw = addr->back = addr;
2433 
2434 		if ((len = recvfrom(name_sock, buf, MAX_DATAGRAM_LENGTH,
2435 		    0, (struct sockaddr *)&addr->sin, &addr->sinlen)) < 0) {
2436 			if (errno == ENOMEM || errno == ENFILE ||
2437 			    errno == EMFILE) {
2438 				/* Sleep for 10 seconds and try again */
2439 				free(buf);
2440 				free(addr);
2441 				smb_netbios_sleep(10);
2442 				continue;
2443 			}
2444 			syslog(LOG_ERR, "nbns: recvfrom failed: %m");
2445 			free(buf);
2446 			free(addr);
2447 			smb_netbios_event(NETBIOS_EVENT_ERROR);
2448 			goto shutdown;
2449 		}
2450 
2451 		/* Ignore any incoming packets from myself... */
2452 
2453 		ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr;
2454 		ipaddr.a_family = AF_INET;
2455 		if (smb_nic_is_local(&ipaddr))
2456 			goto ignore;
2457 
2458 		/*
2459 		 * Launch a netbios worker to process the received packet.
2460 		 */
2461 		worker_param = malloc(sizeof (worker_param_t));
2462 		if (worker_param) {
2463 			pthread_t worker;
2464 			pthread_attr_t tattr;
2465 
2466 			worker_param->addr = addr;
2467 			worker_param->buf = buf;
2468 			worker_param->length = len;
2469 
2470 			(void) pthread_attr_init(&tattr);
2471 			(void) pthread_attr_setdetachstate(&tattr,
2472 			    PTHREAD_CREATE_DETACHED);
2473 			(void) pthread_create(&worker, &tattr,
2474 			    smb_netbios_worker, worker_param);
2475 			(void) pthread_attr_destroy(&tattr);
2476 		}
2477 	}
2478 
2479 shutdown:
2480 	smb_netbios_event(NETBIOS_EVENT_NS_STOP);
2481 	smb_netbios_wait(NETBIOS_EVENT_BROWSER_STOP);
2482 
2483 	if (!smb_netbios_error())
2484 		smb_netbios_name_unconfig();
2485 
2486 	(void) close(name_sock);
2487 	return (NULL);
2488 }
2489