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