xref: /illumos-gate/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c (revision 5f82aa32fbc5dc2c59bca6ff315f44a4c4c9ea86)
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 		*dnptrs[32];
488 	unsigned char		comp_name_buf[MAX_NAME_LENGTH];
489 	unsigned int		tmp;
490 	int			i, step;
491 
492 	if (n_buf < NAME_HEADER_SIZE)
493 		return (-1);		/* no header, impossible */
494 
495 	dnptrs[0] = heap;
496 	dnptrs[1] = 0;
497 
498 	BE_OUT16(heap, npb->name_trn_id);
499 	heap += 2;
500 
501 	BE_OUT16(heap, npb->info);
502 	heap += 2;
503 
504 	BE_OUT16(heap, npb->qdcount);
505 	heap += 2;
506 
507 	BE_OUT16(heap, npb->ancount);
508 	heap += 2;
509 
510 	BE_OUT16(heap, npb->nscount);
511 	heap += 2;
512 
513 	BE_OUT16(heap, npb->arcount);
514 	heap += 2;
515 
516 	for (i = 0; i < npb->qdcount; i++) {
517 		if ((heap + 34 + 4) > end_heap)
518 			return (-2);
519 
520 		(void) smb_first_level_name_encode(npb->question[i].name,
521 		    comp_name_buf, sizeof (comp_name_buf));
522 		(void) strcpy((char *)heap, (char *)comp_name_buf);
523 		heap += strlen((char *)comp_name_buf) + 1;
524 
525 		BE_OUT16(heap, npb->question[i].question_type);
526 		heap += 2;
527 
528 		BE_OUT16(heap, npb->question[i].question_class);
529 		heap += 2;
530 	}
531 
532 	for (step = 1; step <= 3; step++) {
533 		struct resource_record *nrr;
534 		int n;
535 
536 		/* truly ugly, but saves code copying */
537 		if (step == 1) {
538 			n = npb->ancount;
539 			nrr = npb->answer;
540 		} else if (step == 2) {
541 			n = npb->nscount;
542 			nrr = npb->authority;
543 		} else { /* step == 3 */
544 			n = npb->arcount;
545 			nrr = npb->additional;
546 		}
547 
548 		for (i = 0; i < n; i++) {
549 			if ((heap + 34 + 10) > end_heap)
550 				return (-2);
551 
552 			(void) smb_first_level_name_encode(nrr->name,
553 			    comp_name_buf, sizeof (comp_name_buf));
554 			(void) strcpy((char *)heap, (char *)comp_name_buf);
555 			heap += strlen((char *)comp_name_buf) + 1;
556 
557 			BE_OUT16(heap, nrr[i].rr_type);
558 			heap += 2;
559 
560 			BE_OUT16(heap, nrr[i].rr_class);
561 			heap += 2;
562 
563 			BE_OUT32(heap, nrr[i].ttl);
564 			heap += 4;
565 
566 			BE_OUT16(heap, nrr[i].rdlength);
567 			heap += 2;
568 
569 			if ((tmp = nrr[i].rdlength) > 0) {
570 				if ((heap + tmp) > end_heap)
571 					return (-2);
572 
573 				if (nrr[i].rr_type == NAME_RR_TYPE_NB &&
574 				    nrr[i].rr_class == NAME_RR_CLASS_IN &&
575 				    tmp >= 6 && nrr[i].rdata == 0) {
576 					tmp = nrr[i].name->attributes &
577 					    (NAME_ATTR_GROUP |
578 					    NAME_ATTR_OWNER_NODE_TYPE);
579 					BE_OUT16(heap, tmp);
580 					heap += 2;
581 
582 					raddr = &nrr[i].name->addr_list;
583 					(void) memcpy(heap,
584 					    &raddr->sin.sin_addr.s_addr,
585 					    sizeof (uint32_t));
586 					heap += 4;
587 				} else {
588 					bcopy(nrr[i].rdata, heap, tmp);
589 					heap += tmp;
590 				}
591 			}
592 		}
593 	}
594 	return (heap - buf);
595 }
596 
597 /*
598  * strnchr
599  *
600  * Lookup for character 'c' in first 'n' chars of string 's'.
601  * Returns pointer to the found char, otherwise returns 0.
602  */
603 static char *
604 strnchr(const char *s, char c, int n)
605 {
606 	char *ps = (char *)s;
607 	char *es = (char *)s + n;
608 
609 	while (ps < es && *ps) {
610 		if (*ps == c)
611 			return (ps);
612 
613 		++ps;
614 	}
615 
616 	if (*ps == '\0' && c == '\0')
617 		return (ps);
618 
619 	return (0);
620 }
621 
622 static boolean_t
623 is_multihome(char *name)
624 {
625 	return (smb_nic_getnum(name) > 1);
626 }
627 
628 /*
629  * smb_netbios_getname
630  *
631  * Get the Netbios name part of the given record.
632  * Does some boundary checks.
633  *
634  * Returns the name length on success, otherwise
635  * returns 0.
636  */
637 static int
638 smb_netbios_getname(char *name, char *buf, char *buf_end)
639 {
640 	char *name_end;
641 	int name_len;
642 
643 	if (buf >= buf_end) {
644 		/* no room for a NB name */
645 		return (0);
646 	}
647 
648 	name_end = strnchr(buf, '\0', buf_end - buf + 1);
649 	if (name_end == 0) {
650 		/* not a valid NB name */
651 		return (0);
652 	}
653 
654 	name_len = name_end - buf + 1;
655 
656 	(void) strlcpy(name, buf, name_len);
657 	return (name_len);
658 }
659 
660 /*
661  * smb_name_buf_to_packet
662  *
663  * Convert the bits and bytes that came from the wire into a NetBIOS
664  * Name Server Packet Block (npb).  The "block" is used as a heap.
665  *
666  * Returns a pointer to a name packet on success.  Otherwise, returns
667  * a NULL pointer.
668  */
669 static struct name_packet *
670 smb_name_buf_to_packet(char *buf, int n_buf)
671 {
672 	struct name_packet *npb;
673 	unsigned char *heap;
674 	unsigned char *scan = (unsigned char *)buf;
675 	unsigned char *scan_end = scan + n_buf;
676 	char name_buf[MAX_NAME_LENGTH];
677 	struct resource_record *nrr = 0;
678 	int	rc, i, n, nn, ns;
679 	uint16_t name_trn_id, info;
680 	uint16_t qdcount, ancount, nscount, arcount;
681 	addr_entry_t *next;
682 	int name_len;
683 
684 	if (n_buf < NAME_HEADER_SIZE) {
685 		/* truncated header */
686 		syslog(LOG_DEBUG, "nbns: short packet (%d bytes)", n_buf);
687 		return (NULL);
688 	}
689 
690 	name_trn_id = BE_IN16(scan); scan += 2;
691 	info = BE_IN16(scan); scan += 2;
692 	qdcount = BE_IN16(scan); scan += 2;
693 	ancount = BE_IN16(scan); scan += 2;
694 	nscount = BE_IN16(scan); scan += 2;
695 	arcount = BE_IN16(scan); scan += 2;
696 
697 	ns = sizeof (struct name_entry);
698 	n = n_buf + sizeof (struct name_packet) +
699 	    ((unsigned)qdcount * (sizeof (struct name_question) + ns)) +
700 	    ((unsigned)ancount * (sizeof (struct resource_record) + ns)) +
701 	    ((unsigned)nscount * (sizeof (struct resource_record) + ns)) +
702 	    ((unsigned)arcount * (sizeof (struct resource_record) + ns));
703 
704 	if ((npb = malloc(n)) == NULL)
705 		return (NULL);
706 
707 	bzero(npb, n);
708 	heap = npb->block_data;
709 	npb->name_trn_id = name_trn_id;
710 	npb->info = info;
711 	npb->qdcount = qdcount;
712 	npb->ancount = ancount;
713 	npb->nscount = nscount;
714 	npb->arcount = arcount;
715 
716 	/* scan is in position for question entries */
717 
718 	/*
719 	 * Measure the space needed for the tables
720 	 */
721 	if (qdcount > 0) {
722 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
723 		npb->question = (struct name_question *)heap;
724 		heap += qdcount * sizeof (struct name_question);
725 		for (i = 0; i < qdcount; i++) {
726 			/* LINTED - E_BAD_PTR_CAST_ALIGN */
727 			npb->question[i].name = (struct name_entry *)heap;
728 			heap += sizeof (struct name_entry);
729 		}
730 	}
731 
732 	/* LINTED - E_BAD_PTR_CAST_ALIGN */
733 	nrr = (struct resource_record *)heap;
734 
735 	if (ancount > 0) {
736 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
737 		npb->answer = (struct resource_record *)heap;
738 		heap += ancount * sizeof (struct resource_record);
739 	}
740 
741 	if (nscount > 0) {
742 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
743 		npb->authority = (struct resource_record *)heap;
744 		heap += nscount * sizeof (struct resource_record);
745 	}
746 
747 	if (arcount > 0) {
748 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
749 		npb->additional = (struct resource_record *)heap;
750 		heap += arcount * sizeof (struct resource_record);
751 	}
752 
753 	/*
754 	 * Populate each resource_record's .name field.
755 	 * Done as a second pass so that all resource records
756 	 * (answer, authority, additional) are consecutive via nrr[i].
757 	 */
758 	for (i = 0; i < (ancount + nscount + arcount); i++) {
759 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
760 		nrr[i].name = (struct name_entry *)heap;
761 		heap += sizeof (struct name_entry);
762 	}
763 
764 
765 	for (i = 0; i < npb->qdcount; i++) {
766 		name_len = smb_netbios_getname(name_buf, (char *)scan,
767 		    (char *)scan_end);
768 		if (name_len <= 0) {
769 			free(npb);
770 			return (NULL);
771 		}
772 
773 		smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
774 		    npb->question[i].name);
775 		rc = smb_first_level_name_decode((unsigned char *)name_buf,
776 		    npb->question[i].name);
777 		if (rc < 0) {
778 			/* Couldn't decode the question name */
779 			free(npb);
780 			return (NULL);
781 		}
782 
783 		scan += name_len;
784 		if (scan + 4 > scan_end) {
785 			/* no room for Question Type(2) and Class(2) fields */
786 			free(npb);
787 			return (NULL);
788 		}
789 
790 		npb->question[i].question_type = BE_IN16(scan); scan += 2;
791 		npb->question[i].question_class = BE_IN16(scan); scan += 2;
792 	}
793 
794 	/*
795 	 * Cheat. Remaining sections are of the same resource_record
796 	 * format. Table space is consecutive.
797 	 */
798 
799 	for (i = 0; i < (ancount + nscount + arcount); i++) {
800 		if (scan[0] == 0xc0) {
801 			/* Namebuf is reused... */
802 			rc = 2;
803 		} else {
804 			name_len = smb_netbios_getname(name_buf, (char *)scan,
805 			    (char *)scan_end);
806 			if (name_len <= 0) {
807 				free(npb);
808 				return (NULL);
809 			}
810 			rc = name_len;
811 		}
812 		scan += rc;
813 
814 		if (scan + 10 > scan_end) {
815 			/*
816 			 * no room for RR_TYPE (2), RR_CLASS (2), TTL (4) and
817 			 * RDLENGTH (2) fields.
818 			 */
819 			free(npb);
820 			return (NULL);
821 		}
822 
823 		smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
824 		    nrr[i].name);
825 		if ((rc = smb_first_level_name_decode((unsigned char *)name_buf,
826 		    nrr[i].name)) < 0) {
827 			free(npb);
828 			return (NULL);
829 		}
830 
831 		nrr[i].rr_type = BE_IN16(scan); scan += 2;
832 		nrr[i].rr_class = BE_IN16(scan); scan += 2;
833 		nrr[i].ttl = BE_IN32(scan); scan += 4;
834 		nrr[i].rdlength = BE_IN16(scan); scan += 2;
835 
836 		if ((n = nrr[i].rdlength) > 0) {
837 			if ((scan + n) > scan_end) {
838 				/* no room for RDATA */
839 				free(npb);
840 				return (NULL);
841 			}
842 			bcopy(scan, heap, n);
843 
844 			nn = n;
845 			if (nrr[i].rr_type == 0x0020 &&
846 			    nrr[i].rr_class == 0x01 && n >= 6) {
847 				while (nn) {
848 					if (nn == 6)
849 						next = &nrr[i].name->addr_list;
850 					else {
851 						next = malloc(
852 						    sizeof (addr_entry_t));
853 						if (next == 0) {
854 							/* not enough memory */
855 							free(npb);
856 							return (NULL);
857 						}
858 						QUEUE_INSERT_TAIL(
859 						    &nrr[i].name->addr_list,
860 						    next);
861 					}
862 					nrr[i].name->attributes =
863 					    BE_IN16(scan);
864 					next->sin.sin_family = AF_INET;
865 					next->sinlen = sizeof (next->sin);
866 					(void) memcpy(
867 					    &next->sin.sin_addr.s_addr,
868 					    scan + 2, sizeof (uint32_t));
869 					next->sin.sin_port =
870 					    htons(IPPORT_NETBIOS_DGM);
871 					nn -= 6;
872 					scan += 6;
873 				}
874 			} else {
875 				nrr[i].rdata = heap;
876 				scan += n;
877 			}
878 			heap += n;
879 		}
880 	}
881 	return (npb);
882 }
883 
884 /*
885  * smb_send_name_service_packet
886  *
887  * Description:
888  *
889  *	Send out a name service packet to proper destination.
890  *
891  * Inputs:
892  *	struct netbios_name *dest	-> NETBIOS name of destination
893  *	struct name_packet *packet	-> Packet to send
894  *
895  * Returns:
896  *	success	->  >0
897  *	failure	-> <=0
898  */
899 static int
900 smb_send_name_service_packet(addr_entry_t *addr, struct name_packet *packet)
901 {
902 	unsigned char buf[MAX_DATAGRAM_LENGTH];
903 	int len;
904 
905 	if ((len = smb_name_buf_from_packet(buf, sizeof (buf), packet)) < 0) {
906 		errno = EINVAL;
907 		return (-1);
908 	}
909 
910 	return (sendto(name_sock, buf, len, MSG_EOR,
911 	    (struct sockaddr *)&addr->sin, addr->sinlen));
912 }
913 
914 /*
915  * smb_netbios_send_rcv
916  *
917  * This function sends the given NetBIOS packet to the given
918  * address and get back the response. If send operation is not
919  * successful, it's repeated 'retries' times.
920  *
921  * Returns:
922  *		0		Unsuccessful send operation; no reply
923  *		1		Got reply
924  */
925 static int
926 smb_netbios_send_rcv(int bcast, addr_entry_t *destination,
927     struct name_packet *packet, uint32_t retries, uint32_t timeout)
928 {
929 	uint32_t retry;
930 	uint16_t	tid;
931 	struct timespec st;
932 	int	rc;
933 
934 	for (retry = 0; retry < retries; retry++) {
935 		if ((destination->flags & ADDR_FLAG_VALID) == 0)
936 			return (0);
937 
938 		tid = smb_netbios_name_trn_id();
939 		packet->name_trn_id = tid;
940 		if (smb_send_name_service_packet(destination, packet) >= 0) {
941 			rc = smb_netbios_process_response(tid, destination,
942 			    packet, timeout);
943 
944 			if ((rc > 0) || (bcast == BROADCAST))
945 				return (1);
946 
947 			if (rc != 0)
948 				return (0);
949 		}
950 
951 		st.tv_sec = 0;
952 		st.tv_nsec = (timeout * 1000000);
953 		(void) nanosleep(&st, 0);
954 	}
955 
956 	return (0);
957 }
958 
959 /*
960  * RFC 1002 4.2.2.  NAME REGISTRATION REQUEST
961  */
962 static int
963 smb_send_name_registration_request(int bcast, struct name_question *question,
964     struct resource_record *additional)
965 {
966 	int gotreply = 0;
967 	uint32_t retries;
968 	uint32_t timeout;
969 	addr_entry_t *destination;
970 	struct name_packet packet;
971 	unsigned char type;
972 	int i, addr_num, rc;
973 
974 	type = question->name->name[15];
975 	if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
976 		syslog(LOG_DEBUG, "nbns: name registration bad type (0x%02x)",
977 		    type);
978 		smb_netbios_name_logf(question->name);
979 		question->name->attributes &= ~NAME_ATTR_LOCAL;
980 		return (-1);
981 	}
982 
983 	if (bcast == BROADCAST) {
984 		if (bcast_num == 0)
985 			return (0);
986 		destination = smb_bcast_list;
987 		addr_num = bcast_num;
988 		retries = BCAST_REQ_RETRY_COUNT;
989 		timeout = BCAST_REQ_RETRY_TIMEOUT;
990 		packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_BROADCAST;
991 	} else {
992 		if (nbns_num == 0)
993 			return (0);
994 		destination = smb_nbns;
995 		addr_num = nbns_num;
996 		retries = UCAST_REQ_RETRY_COUNT;
997 		timeout = UCAST_REQ_RETRY_TIMEOUT;
998 		packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_UNICAST;
999 	}
1000 
1001 	packet.qdcount = 1;	/* question entries */
1002 	packet.question = question;
1003 	packet.ancount = 0;	/* answer recs */
1004 	packet.answer = NULL;
1005 	packet.nscount = 0;	/* authority recs */
1006 	packet.authority = NULL;
1007 	packet.arcount = 1;	/* additional recs */
1008 	packet.additional = additional;
1009 
1010 	if (IS_UNIQUE(question->name->attributes) &&
1011 	    (is_multihome((char *)(question->name->name))))
1012 		packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST;
1013 
1014 	for (i = 0; i < addr_num; i++) {
1015 		/*
1016 		 * Only register with the Primary WINS server,
1017 		 * unless we got no reply.
1018 		 */
1019 		if ((bcast == UNICAST) && gotreply)
1020 			break;
1021 
1022 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1023 		    retries, timeout);
1024 		if (rc == 1)
1025 			gotreply = 1;
1026 	}
1027 
1028 	return (gotreply);
1029 }
1030 
1031 /*
1032  * RFC 1002 4.2.4.  NAME REFRESH REQUEST
1033  */
1034 /*ARGSUSED*/
1035 static int
1036 smb_send_name_refresh_request(int bcast, struct name_question *question,
1037     struct resource_record *additional, int force)
1038 {
1039 	int rc = 0;
1040 	int gotreply = 0;
1041 	uint32_t retries;
1042 	uint32_t timeout;
1043 	addr_entry_t *addr;
1044 	addr_entry_t *destination;
1045 	struct name_packet packet;
1046 	unsigned char type;
1047 	int i, addr_num, q_addrs = 0;
1048 
1049 	type = question->name->name[15];
1050 	if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
1051 		syslog(LOG_DEBUG, "nbns: name refresh bad type (0x%02x)", type);
1052 		smb_netbios_name_logf(question->name);
1053 		question->name->attributes &= ~NAME_ATTR_LOCAL;
1054 		return (-1);
1055 	}
1056 	switch (bcast) {
1057 	case BROADCAST :
1058 		if (bcast_num == 0)
1059 			return (-1);
1060 		destination = smb_bcast_list;
1061 		addr_num = bcast_num;
1062 		retries = BCAST_REQ_RETRY_COUNT;
1063 		timeout = BCAST_REQ_RETRY_TIMEOUT;
1064 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_BROADCAST;
1065 		break;
1066 
1067 	case UNICAST :
1068 		if (nbns_num == 0)
1069 			return (-1);
1070 		destination = smb_nbns;
1071 		addr_num = nbns_num;
1072 		retries = UCAST_REQ_RETRY_COUNT;
1073 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1074 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST;
1075 		break;
1076 
1077 	default:
1078 		destination = &question->name->addr_list;
1079 		/*
1080 		 * the value of addr_num is irrelvant here, because
1081 		 * the code is going to do special_process so it doesn't
1082 		 * need the addr_num. We set a value here just to avoid
1083 		 * compiler warning.
1084 		 */
1085 		addr_num = 0;
1086 		retries = UCAST_REQ_RETRY_COUNT;
1087 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1088 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST;
1089 		q_addrs = 1;
1090 		break;
1091 	}
1092 
1093 	if (IS_UNIQUE(question->name->attributes) &&
1094 	    (is_multihome((char *)(question->name->name))))
1095 		packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST;
1096 
1097 	packet.qdcount = 1;	/* question entries */
1098 	packet.question = question;
1099 	packet.ancount = 0;	/* answer recs */
1100 	packet.answer = NULL;
1101 	packet.nscount = 0;	/* authority recs */
1102 	packet.authority = NULL;
1103 	packet.arcount = 1;	/* additional recs */
1104 	packet.additional = additional;
1105 
1106 	if (q_addrs)
1107 		goto special_process;
1108 
1109 	for (i = 0; i < addr_num; i++) {
1110 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1111 		    retries, timeout);
1112 		if (rc == 1)
1113 			gotreply = 1;
1114 	}
1115 
1116 	return (gotreply);
1117 
1118 special_process:
1119 	addr = destination;
1120 	do {
1121 		rc = smb_netbios_send_rcv(bcast, addr, &packet,
1122 		    retries, timeout);
1123 		if (rc == 1)
1124 			gotreply = 1;
1125 		addr = addr->forw;
1126 	} while (addr != destination);
1127 
1128 	return (gotreply);
1129 }
1130 
1131 /*
1132  * RFC 1002 4.2.5.  POSITIVE NAME REGISTRATION RESPONSE
1133  * RFC 1002 4.2.6.  NEGATIVE NAME REGISTRATION RESPONSE
1134  */
1135 static int
1136 smb_send_name_registration_response(addr_entry_t *addr,
1137     struct name_packet *original_packet, uint16_t rcode)
1138 {
1139 	struct name_packet	packet;
1140 	struct resource_record	answer;
1141 
1142 	bzero(&packet, sizeof (struct name_packet));
1143 	bzero(&answer, sizeof (struct resource_record));
1144 
1145 	packet.name_trn_id = original_packet->name_trn_id;
1146 	packet.info = NAME_REGISTRATION_RESPONSE | NAME_NM_FLAGS_RA |
1147 	    (rcode & NAME_RCODE_MASK);
1148 	packet.qdcount = 0;	/* question entries */
1149 	packet.question = NULL;
1150 	packet.ancount = 1;	/* answer recs */
1151 	packet.answer = &answer;
1152 	packet.nscount = 0;	/* authority recs */
1153 	packet.authority = NULL;
1154 	packet.arcount = 0;	/* additional recs */
1155 	packet.additional = NULL;
1156 
1157 	answer.name = original_packet->question->name;
1158 	answer.rr_type = NAME_QUESTION_TYPE_NB;
1159 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1160 	answer.ttl = original_packet->additional->ttl;
1161 	answer.rdlength = original_packet->additional->rdlength;
1162 	answer.rdata = original_packet->additional->rdata;
1163 
1164 	return (smb_send_name_service_packet(addr, &packet));
1165 }
1166 
1167 /*
1168  * RFC 1002 4.2.9.  NAME RELEASE REQUEST & DEMAND
1169  */
1170 static int
1171 smb_send_name_release_request_and_demand(int bcast,
1172     struct name_question *question, struct resource_record *additional)
1173 {
1174 	int gotreply = 0;
1175 	int i, rc;
1176 	int addr_num;
1177 	uint32_t retries;
1178 	uint32_t timeout;
1179 	addr_entry_t *destination;
1180 	struct name_packet packet;
1181 
1182 	if (bcast == BROADCAST) {
1183 		if (bcast_num == 0)
1184 			return (-1);
1185 		destination = smb_bcast_list;
1186 		addr_num = bcast_num;
1187 		retries = 1; /* BCAST_REQ_RETRY_COUNT */
1188 		timeout = 100; /* BCAST_REQ_RETRY_TIMEOUT */
1189 		packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_BROADCAST;
1190 	} else {
1191 		if (nbns_num == 0)
1192 			return (-1);
1193 		destination = smb_nbns;
1194 		addr_num = nbns_num;
1195 		retries = 1; /* UCAST_REQ_RETRY_COUNT */
1196 		timeout = 100; /* UCAST_REQ_RETRY_TIMEOUT */
1197 		packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_UNICAST;
1198 	}
1199 
1200 	packet.qdcount = 1;	/* question entries */
1201 	packet.question = question;
1202 	packet.ancount = 0;	/* answer recs */
1203 	packet.answer = NULL;
1204 	packet.nscount = 0;	/* authority recs */
1205 	packet.authority = NULL;
1206 	packet.arcount = 1;	/* additional recs */
1207 	packet.additional = additional;
1208 
1209 	for (i = 0; i < addr_num; i++) {
1210 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1211 		    retries, timeout);
1212 		if (rc == 1)
1213 			gotreply = 1;
1214 	}
1215 
1216 	return (gotreply);
1217 }
1218 
1219 /*
1220  * RFC 1002 4.2.10.  POSITIVE NAME RELEASE RESPONSE
1221  * RFC 1002 4.2.11.  NEGATIVE NAME RELEASE RESPONSE
1222  */
1223 static int
1224 /* LINTED - E_STATIC_UNUSED */
1225 smb_send_name_release_response(addr_entry_t *addr,
1226     struct name_packet *original_packet, uint16_t rcode)
1227 {
1228 	struct name_packet	packet;
1229 	struct resource_record	answer;
1230 
1231 	bzero(&packet, sizeof (struct name_packet));
1232 	bzero(&answer, sizeof (struct resource_record));
1233 
1234 	packet.name_trn_id = original_packet->name_trn_id;
1235 	packet.info = NAME_RELEASE_RESPONSE | (rcode & NAME_RCODE_MASK);
1236 	packet.qdcount = 0;	/* question entries */
1237 	packet.question = NULL;
1238 	packet.ancount = 1;	/* answer recs */
1239 	packet.answer = &answer;
1240 	packet.nscount = 0;	/* authority recs */
1241 	packet.authority = NULL;
1242 	packet.arcount = 0;	/* additional recs */
1243 	packet.additional = NULL;
1244 
1245 	answer.name = original_packet->question->name;
1246 	answer.rr_type = NAME_QUESTION_TYPE_NB;
1247 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1248 	answer.ttl = original_packet->additional->ttl;
1249 	answer.rdlength = original_packet->additional->rdlength;
1250 	answer.rdata = original_packet->additional->rdata;
1251 
1252 	return (smb_send_name_service_packet(addr, &packet));
1253 }
1254 
1255 /*
1256  * RFC 1002 4.2.12.  NAME QUERY REQUEST
1257  */
1258 static int
1259 smb_send_name_query_request(int bcast, struct name_question *question)
1260 {
1261 	int			rc = 0;
1262 	uint32_t		retry, retries;
1263 	uint32_t		timeout;
1264 	uint16_t		tid;
1265 	addr_entry_t		*destination;
1266 	struct name_packet	packet;
1267 	int 			i, addr_num;
1268 	struct timespec 	st;
1269 
1270 	if (bcast == BROADCAST) {
1271 		if (bcast_num == 0)
1272 			return (-1);
1273 		destination = smb_bcast_list;
1274 		addr_num = bcast_num;
1275 		retries = BCAST_REQ_RETRY_COUNT;
1276 		timeout = BCAST_REQ_RETRY_TIMEOUT;
1277 		packet.info = NAME_QUERY_REQUEST | NM_FLAGS_BROADCAST;
1278 	} else {
1279 		if (nbns_num == 0)
1280 			return (-1);
1281 		destination = smb_nbns;
1282 		addr_num = nbns_num;
1283 		retries = UCAST_REQ_RETRY_COUNT;
1284 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1285 		packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST;
1286 	}
1287 	packet.qdcount = 1;	/* question entries */
1288 	packet.question = question;
1289 	packet.ancount = 0;	/* answer recs */
1290 	packet.answer = NULL;
1291 	packet.nscount = 0;	/* authority recs */
1292 	packet.authority = NULL;
1293 	packet.arcount = 0;	/* additional recs */
1294 	packet.additional = NULL;
1295 
1296 	for (i = 0; i < addr_num; i++) {
1297 		for (retry = 0; retry < retries; retry++) {
1298 			if ((destination[i].flags & ADDR_FLAG_VALID) == 0)
1299 				break;
1300 			tid = smb_netbios_name_trn_id();
1301 			packet.name_trn_id = tid;
1302 
1303 			if (smb_send_name_service_packet(&destination[i],
1304 			    &packet) >= 0) {
1305 				if ((rc = smb_netbios_process_response(tid,
1306 				    &destination[i],
1307 				    &packet, timeout)) != 0)
1308 					break;
1309 			}
1310 			st.tv_sec = 0;
1311 			st.tv_nsec = (timeout * 1000000);
1312 			(void) nanosleep(&st, 0);
1313 		}
1314 	}
1315 
1316 	return (rc);
1317 }
1318 
1319 /*
1320  * RFC 1002 4.2.13.  POSITIVE NAME QUERY RESPONSE
1321  * RFC 1002 4.2.14.  NEGATIVE NAME QUERY RESPONSE
1322  */
1323 static int
1324 smb_send_name_query_response(addr_entry_t *addr,
1325     struct name_packet *original_packet, struct name_entry *entry,
1326     uint16_t rcode)
1327 {
1328 	addr_entry_t		*raddr;
1329 	struct name_packet	packet;
1330 	struct resource_record	answer;
1331 	uint16_t		attr;
1332 	unsigned char 		data[MAX_DATAGRAM_LENGTH];
1333 	unsigned char 		*scan = data;
1334 	uint32_t		ret_addr;
1335 
1336 	packet.name_trn_id = original_packet->name_trn_id;
1337 	packet.info = NAME_QUERY_RESPONSE | (rcode & NAME_RCODE_MASK);
1338 	packet.qdcount = 0;	/* question entries */
1339 	packet.question = NULL;
1340 	packet.ancount = 1;	/* answer recs */
1341 	packet.answer = &answer;
1342 	packet.nscount = 0;	/* authority recs */
1343 	packet.authority = NULL;
1344 	packet.arcount = 0;	/* additional recs */
1345 	packet.additional = NULL;
1346 
1347 	answer.name = entry;
1348 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1349 	answer.ttl = entry->addr_list.ttl;
1350 	answer.rdata = data;
1351 	if (rcode) {
1352 		answer.rr_type = NAME_RR_TYPE_NULL;
1353 		answer.rdlength = 0;
1354 		bzero(data, 6);
1355 	} else {
1356 		answer.rdlength = 0;
1357 		answer.rr_type = NAME_QUESTION_TYPE_NB;
1358 		raddr = &entry->addr_list;
1359 		scan = data;
1360 		do {
1361 			attr = entry->attributes & (NAME_ATTR_GROUP |
1362 			    NAME_ATTR_OWNER_NODE_TYPE);
1363 
1364 			BE_OUT16(scan, attr); scan += 2;
1365 			ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1366 			*scan++ = ret_addr;
1367 			*scan++ = ret_addr >> 8;
1368 			*scan++ = ret_addr >> 16;
1369 			*scan++ = ret_addr >> 24;
1370 
1371 			answer.rdlength += 6;
1372 			raddr = raddr->forw;
1373 		} while (raddr != &entry->addr_list);
1374 	}
1375 
1376 	return (smb_send_name_service_packet(addr, &packet));
1377 }
1378 
1379 /*
1380  * RFC 1002 4.2.18.  NODE STATUS RESPONSE
1381  */
1382 static int
1383 smb_send_node_status_response(addr_entry_t *addr,
1384     struct name_packet *original_packet)
1385 {
1386 	uint32_t		net_ipaddr;
1387 	int64_t			max_connections;
1388 	struct arpreq 		arpreq;
1389 	struct name_packet	packet;
1390 	struct resource_record	answer;
1391 	unsigned char 		*scan;
1392 	unsigned char 		*scan_end;
1393 	unsigned char		data[MAX_NETBIOS_REPLY_DATA_SIZE];
1394 	boolean_t scan_done = B_FALSE;
1395 	smb_inaddr_t ipaddr;
1396 
1397 	bzero(&packet, sizeof (struct name_packet));
1398 	bzero(&answer, sizeof (struct resource_record));
1399 
1400 	packet.name_trn_id = original_packet->name_trn_id;
1401 	packet.info = NODE_STATUS_RESPONSE;
1402 	packet.qdcount = 0;	/* question entries */
1403 	packet.question = NULL;
1404 	packet.ancount = 1;	/* answer recs */
1405 	packet.answer = &answer;
1406 	packet.nscount = 0;	/* authority recs */
1407 	packet.authority = NULL;
1408 	packet.arcount = 0;	/* additional recs */
1409 	packet.additional = NULL;
1410 
1411 	answer.name = original_packet->question->name;
1412 	answer.rr_type = NAME_RR_TYPE_NBSTAT;
1413 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1414 	answer.ttl = 0;
1415 	answer.rdata = data;
1416 
1417 	scan = smb_netbios_cache_status(data, MAX_NETBIOS_REPLY_DATA_SIZE,
1418 	    original_packet->question->name->scope);
1419 
1420 	scan_end = data + MAX_NETBIOS_REPLY_DATA_SIZE;
1421 
1422 	ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr;
1423 	ipaddr.a_family = AF_INET;
1424 	if (smb_nic_is_same_subnet(&ipaddr))
1425 		net_ipaddr = addr->sin.sin_addr.s_addr;
1426 	else
1427 		net_ipaddr = 0;
1428 
1429 	(void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &max_connections);
1430 
1431 	while (!scan_done) {
1432 		if ((scan + 6) >= scan_end) {
1433 			packet.info |= NAME_NM_FLAGS_TC;
1434 			break;
1435 		}
1436 
1437 		if (net_ipaddr != 0) {
1438 			struct sockaddr_in *s_in;
1439 			int s;
1440 
1441 			s = socket(AF_INET, SOCK_DGRAM, 0);
1442 			/* LINTED - E_BAD_PTR_CAST_ALIGN */
1443 			s_in = (struct sockaddr_in *)&arpreq.arp_pa;
1444 			s_in->sin_family = AF_INET;
1445 			s_in->sin_addr.s_addr = net_ipaddr;
1446 			if (ioctl(s, SIOCGARP, (caddr_t)&arpreq) < 0) {
1447 				bzero(scan, 6);
1448 			} else {
1449 				bcopy(&arpreq.arp_ha.sa_data, scan, 6);
1450 			}
1451 			(void) close(s);
1452 		} else {
1453 			bzero(scan, 6);
1454 		}
1455 		scan += 6;
1456 
1457 		if ((scan + 26) >= scan_end) {
1458 			packet.info |= NAME_NM_FLAGS_TC;
1459 			break;
1460 		}
1461 		bzero(scan, 26);
1462 		scan += 26;
1463 
1464 		if ((scan + 2) >= scan_end) {
1465 			packet.info |= NAME_NM_FLAGS_TC;
1466 			break;
1467 		}
1468 		BE_OUT16(scan, 0); scan += 2;
1469 
1470 		if ((scan + 2) >= scan_end) {
1471 			packet.info |= NAME_NM_FLAGS_TC;
1472 			break;
1473 		}
1474 		BE_OUT16(scan, 0); scan += 2;
1475 
1476 		if ((scan + 2) >= scan_end) {
1477 			packet.info |= NAME_NM_FLAGS_TC;
1478 			break;
1479 		}
1480 		BE_OUT16(scan, 0); scan += 2;
1481 
1482 		if ((scan + 2) >= scan_end) {
1483 			packet.info |= NAME_NM_FLAGS_TC;
1484 			break;
1485 		}
1486 		BE_OUT16(scan, 0); scan += 2;
1487 
1488 		if ((scan + 2) >= scan_end) {
1489 			packet.info |= NAME_NM_FLAGS_TC;
1490 			break;
1491 		}
1492 		BE_OUT16(scan, 0); scan += 2;
1493 
1494 		if ((scan + 2) >= scan_end) {
1495 			packet.info |= NAME_NM_FLAGS_TC;
1496 			break;
1497 		}
1498 		BE_OUT16(scan, 0); scan += 2;
1499 
1500 		if ((scan + 2) >= scan_end) {
1501 			packet.info |= NAME_NM_FLAGS_TC;
1502 			break;
1503 		}
1504 		BE_OUT16(scan, 0); scan += 2;
1505 
1506 		if ((scan + 2) >= scan_end) {
1507 			packet.info |= NAME_NM_FLAGS_TC;
1508 			break;
1509 		}
1510 		BE_OUT16(scan, max_connections); scan += 2;
1511 
1512 		if ((scan + 2) >= scan_end) {
1513 			packet.info |= NAME_NM_FLAGS_TC;
1514 			break;
1515 		}
1516 
1517 		BE_OUT16(scan, 0); scan += 2;
1518 
1519 		scan_done = B_TRUE;
1520 	}
1521 	answer.rdlength = scan - data;
1522 	return (smb_send_name_service_packet(addr, &packet));
1523 }
1524 
1525 static int
1526 smb_name_Bnode_add_name(struct name_entry *name)
1527 {
1528 	struct name_question		question;
1529 	struct resource_record		additional;
1530 	unsigned char 			data[8];
1531 	uint16_t			attr;
1532 	addr_entry_t			*addr;
1533 	int rc = 0;
1534 
1535 	addr = &name->addr_list;
1536 
1537 	do {
1538 		/* build name service packet */
1539 		question.name = name;
1540 		/*
1541 		 * question.name->attributes |= NAME_NB_FLAGS_ONT_B;
1542 		 * This is commented because NAME_NB_FLAGS_ONT_B is 0
1543 		 */
1544 		question.question_type = NAME_QUESTION_TYPE_NB;
1545 		question.question_class = NAME_QUESTION_CLASS_IN;
1546 
1547 		additional.name = name;
1548 		additional.rr_class = NAME_QUESTION_CLASS_IN;
1549 		additional.ttl = 0;
1550 		additional.rdata = data;
1551 		additional.rdlength = 6;
1552 		additional.rr_type = NAME_QUESTION_TYPE_NB;
1553 		attr = name->attributes & (NAME_ATTR_GROUP |
1554 		    NAME_ATTR_OWNER_NODE_TYPE);
1555 
1556 		BE_OUT16(&data[0], attr);
1557 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1558 		    sizeof (uint32_t));
1559 
1560 		rc |= smb_send_name_registration_request(BROADCAST, &question,
1561 		    &additional);
1562 		addr = addr->forw;
1563 
1564 	} while (addr != &name->addr_list);
1565 
1566 	return (rc);
1567 }
1568 
1569 static int
1570 smb_name_Bnode_find_name(struct name_entry *name)
1571 {
1572 	struct name_question	question;
1573 
1574 	question.name = name;
1575 	question.question_type = NAME_QUESTION_TYPE_NB;
1576 	question.question_class = NAME_QUESTION_CLASS_IN;
1577 
1578 	return (smb_send_name_query_request(BROADCAST, &question));
1579 }
1580 
1581 static int
1582 smb_name_Bnode_delete_name(struct name_entry *name)
1583 {
1584 	struct name_question	question;
1585 	struct resource_record	additional;
1586 	addr_entry_t		*raddr;
1587 	unsigned char		data[MAX_DATAGRAM_LENGTH];
1588 	unsigned char		*scan = data;
1589 	uint32_t		attr;
1590 	uint32_t		ret_addr;
1591 
1592 	/* build packet */
1593 	question.name = name;
1594 	question.question_type = NAME_QUESTION_TYPE_NB;
1595 	question.question_class = NAME_QUESTION_CLASS_IN;
1596 
1597 	additional.name = name;
1598 	additional.rr_class = NAME_QUESTION_CLASS_IN;
1599 	additional.ttl = 0;
1600 	additional.rdata = data;
1601 	additional.rdlength = 0;
1602 	additional.rr_type = NAME_QUESTION_TYPE_NB;
1603 	raddr = &name->addr_list;
1604 	scan = data;
1605 	do {
1606 		attr = name->attributes & (NAME_ATTR_GROUP |
1607 		    NAME_ATTR_OWNER_NODE_TYPE);
1608 
1609 		BE_OUT16(scan, attr); scan += 2;
1610 		ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1611 		*scan++ = ret_addr;
1612 		*scan++ = ret_addr >> 8;
1613 		*scan++ = ret_addr >> 16;
1614 		*scan++ = ret_addr >> 24;
1615 
1616 		additional.rdlength += 6;
1617 	} while (raddr != &name->addr_list);
1618 
1619 	return (smb_send_name_release_request_and_demand(BROADCAST,
1620 	    &question, &additional));
1621 }
1622 
1623 static int
1624 smb_name_Pnode_add_name(struct name_entry *name)
1625 {
1626 	struct name_question		question;
1627 	struct resource_record		additional;
1628 	unsigned char 			data[8];
1629 	uint16_t			attr;
1630 	addr_entry_t			*addr;
1631 	int rc = 0;
1632 
1633 	/* build packet */
1634 	addr = &name->addr_list;
1635 	do {
1636 		question.name = name;
1637 		question.question_type = NAME_QUESTION_TYPE_NB;
1638 		question.question_class = NAME_QUESTION_CLASS_IN;
1639 
1640 		additional.name = name;
1641 		additional.rr_class = NAME_QUESTION_CLASS_IN;
1642 		additional.ttl = 0;
1643 		additional.rdata = data;
1644 		additional.rdlength = 6;
1645 		additional.rr_type = NAME_QUESTION_TYPE_NB;
1646 		attr = name->attributes &
1647 		    (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE);
1648 
1649 		BE_OUT16(&data[0], attr);
1650 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1651 		    sizeof (uint32_t));
1652 
1653 		rc |= smb_send_name_registration_request(UNICAST, &question,
1654 		    &additional);
1655 
1656 		addr = addr->forw;
1657 
1658 	} while (addr != &name->addr_list);
1659 
1660 	return (rc);
1661 }
1662 
1663 static int
1664 smb_name_Pnode_refresh_name(struct name_entry *name)
1665 {
1666 	struct name_question		question;
1667 	struct resource_record		additional;
1668 	unsigned char 			data[8];
1669 	uint16_t			attr;
1670 	addr_entry_t			*addr;
1671 	int rc = 0;
1672 
1673 	/* build packet */
1674 	addr = &name->addr_list;
1675 	do {
1676 		question.name = name;
1677 		question.question_type = NAME_QUESTION_TYPE_NB;
1678 		question.question_class = NAME_QUESTION_CLASS_IN;
1679 
1680 		additional.name = name;
1681 		additional.rr_class = NAME_QUESTION_CLASS_IN;
1682 		additional.ttl = 0;
1683 		additional.rdata = data;
1684 		additional.rdlength = 6;
1685 		additional.rr_type = NAME_QUESTION_TYPE_NB;
1686 		attr = name->attributes &
1687 		    (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE);
1688 
1689 		BE_OUT16(&data[0], attr);
1690 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1691 		    sizeof (uint32_t));
1692 
1693 		rc |= smb_send_name_refresh_request(UNICAST, &question,
1694 		    &additional, 1);
1695 
1696 		addr = addr->forw;
1697 	} while (addr != &name->addr_list);
1698 
1699 	return (rc);
1700 }
1701 
1702 static int
1703 smb_name_Pnode_find_name(struct name_entry *name)
1704 {
1705 	struct name_question	question;
1706 
1707 	/*
1708 	 * Host initiated processing for a P node
1709 	 */
1710 	question.name = name;
1711 	question.name->attributes |= NAME_NB_FLAGS_ONT_P;
1712 	question.question_type = NAME_QUESTION_TYPE_NB;
1713 	question.question_class = NAME_QUESTION_CLASS_IN;
1714 
1715 	return (smb_send_name_query_request(UNICAST, &question));
1716 }
1717 
1718 static int
1719 smb_name_Pnode_delete_name(struct name_entry *name)
1720 {
1721 	struct name_question	question;
1722 	struct resource_record	additional;
1723 	addr_entry_t		*raddr;
1724 	unsigned char		data[MAX_DATAGRAM_LENGTH];
1725 	unsigned char		*scan = data;
1726 	uint32_t		attr;
1727 	uint32_t		ret_addr;
1728 
1729 	/* build packet */
1730 	question.name = name;
1731 	question.name->attributes |= NAME_NB_FLAGS_ONT_P;
1732 	question.question_type = NAME_QUESTION_TYPE_NB;
1733 	question.question_class = NAME_QUESTION_CLASS_IN;
1734 
1735 	additional.name = name;
1736 	additional.rr_class = NAME_QUESTION_CLASS_IN;
1737 	additional.ttl = 0;
1738 	additional.rdata = data;
1739 	additional.rdlength = 0;
1740 	additional.rr_type = NAME_QUESTION_TYPE_NB;
1741 	raddr = &name->addr_list;
1742 	do {
1743 		scan = data;
1744 		attr = name->attributes & (NAME_ATTR_GROUP |
1745 		    NAME_ATTR_OWNER_NODE_TYPE);
1746 
1747 		BE_OUT16(scan, attr); scan += 2;
1748 		ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1749 		*scan++ = ret_addr;
1750 		*scan++ = ret_addr >> 8;
1751 		*scan++ = ret_addr >> 16;
1752 		*scan++ = ret_addr >> 24;
1753 
1754 		additional.rdlength = 6;
1755 		raddr = raddr->forw;
1756 		(void) smb_send_name_release_request_and_demand(UNICAST,
1757 		    &question, &additional);
1758 	} while (raddr != &name->addr_list);
1759 
1760 	return (1);
1761 }
1762 
1763 static int
1764 smb_name_Mnode_add_name(struct name_entry *name)
1765 {
1766 	if (smb_name_Bnode_add_name(name) > 0) {
1767 		if (nbns_num == 0)
1768 			return (1); /* No name server configured */
1769 
1770 		return (smb_name_Pnode_add_name(name));
1771 	}
1772 	return (-1);
1773 }
1774 
1775 static int
1776 smb_name_Hnode_add_name(struct name_entry *name)
1777 {
1778 	if (nbns_num > 0) {
1779 		if (smb_name_Pnode_add_name(name) == 1)
1780 			return (1);
1781 	}
1782 
1783 	return (smb_name_Bnode_add_name(name));
1784 }
1785 
1786 static int
1787 smb_name_Mnode_find_name(struct name_entry *name)
1788 {
1789 	if (smb_name_Bnode_find_name(name) == 1)
1790 		return (1);
1791 
1792 	if (nbns_num == 0)
1793 		return (1); /* No name server configured */
1794 
1795 	return (smb_name_Pnode_find_name(name));
1796 }
1797 
1798 static int
1799 smb_name_Hnode_find_name(struct name_entry *name)
1800 {
1801 	if (nbns_num > 0)
1802 		if (smb_name_Pnode_find_name(name) == 1)
1803 			return (1);
1804 
1805 	return (smb_name_Bnode_find_name(name));
1806 }
1807 
1808 static int
1809 smb_name_Mnode_delete_name(struct name_entry *name)
1810 {
1811 	(void) smb_name_Bnode_delete_name(name);
1812 
1813 	if (nbns_num == 0)
1814 		return (-1); /* No name server configured */
1815 
1816 	if (smb_name_Pnode_delete_name(name) > 0)
1817 		return (1);
1818 
1819 	return (-1);
1820 }
1821 
1822 static int
1823 smb_name_Hnode_delete_name(struct name_entry *name)
1824 {
1825 	if (nbns_num > 0)
1826 		if (smb_name_Pnode_delete_name(name) > 0)
1827 			return (1);
1828 
1829 	return (smb_name_Bnode_delete_name(name));
1830 }
1831 
1832 static void
1833 smb_name_process_Bnode_packet(struct name_packet *packet, addr_entry_t *addr)
1834 {
1835 	struct name_entry 	*name;
1836 	struct name_entry 	*entry;
1837 	struct name_question 	*question;
1838 	struct resource_record 	*additional;
1839 
1840 	question = packet->question;
1841 	additional = packet->additional;
1842 
1843 	switch (packet->info & NAME_OPCODE_OPCODE_MASK) {
1844 	case NAME_OPCODE_REFRESH:
1845 		/* Guard against malformed packets */
1846 		if ((question == 0) || (additional == 0))
1847 			break;
1848 		if (additional->name->addr_list.sin.sin_addr.s_addr == 0)
1849 			break;
1850 
1851 		name = question->name;
1852 		name->addr_list.ttl = additional->ttl;
1853 		name->attributes = additional->name->attributes;
1854 		name->addr_list.sin = additional->name->addr_list.sin;
1855 		name->addr_list.forw = name->addr_list.back = &name->addr_list;
1856 
1857 		if ((entry = smb_netbios_cache_lookup_addr(name)) != 0) {
1858 			smb_netbios_cache_update_entry(entry, question->name);
1859 			smb_netbios_cache_unlock_entry(entry);
1860 		}
1861 		else
1862 			(void) smb_netbios_cache_insert(question->name);
1863 		break;
1864 
1865 	case NAME_OPCODE_QUERY:
1866 		/*
1867 		 * This opcode covers both NAME_QUERY_REQUEST and
1868 		 * NODE_STATUS_REQUEST. They can be distinguished
1869 		 * based on the type of question entry.
1870 		 */
1871 
1872 		/* All query requests have to have question entry */
1873 		if (question == 0)
1874 			break;
1875 
1876 		if (question->question_type == NAME_QUESTION_TYPE_NB) {
1877 			name = question->name;
1878 			if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1879 				(void) smb_send_name_query_response(addr,
1880 				    packet, entry, 0);
1881 				smb_netbios_cache_unlock_entry(entry);
1882 			}
1883 		}
1884 		else
1885 		if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) {
1886 			/*
1887 			 * Name of "*" may be used to force node to
1888 			 * divulge status for administrative purposes
1889 			 */
1890 			name = question->name;
1891 			entry = 0;
1892 			if (NETBIOS_NAME_IS_STAR(name->name) ||
1893 			    ((entry = smb_netbios_cache_lookup(name)) != 0)) {
1894 				if (entry)
1895 					smb_netbios_cache_unlock_entry(entry);
1896 				/*
1897 				 * send only those names that are
1898 				 * in the same scope as the scope
1899 				 * field in the request packet
1900 				 */
1901 				(void) smb_send_node_status_response(addr,
1902 				    packet);
1903 			}
1904 		}
1905 		break;
1906 
1907 	default:
1908 		break;
1909 	}
1910 }
1911 
1912 static void
1913 smb_name_process_Pnode_packet(struct name_packet *packet, addr_entry_t *addr)
1914 {
1915 	struct name_entry 	*name;
1916 	struct name_entry 	*entry;
1917 	struct name_question 	*question;
1918 	struct resource_record 	*additional;
1919 
1920 	question = packet->question;
1921 	additional = packet->additional;
1922 
1923 	if (packet->info & NAME_NM_FLAGS_B) {
1924 		/*
1925 		 * always ignore UDP broadcast packets
1926 		 */
1927 		return;
1928 	}
1929 
1930 	switch (packet->info & NAME_OPCODE_OPCODE_MASK) {
1931 	case NAME_OPCODE_REFRESH:
1932 		/* Guard against malformed packets */
1933 		if ((question == 0) || (additional == 0))
1934 			break;
1935 		if (additional->name->addr_list.sin.sin_addr.s_addr == 0)
1936 			break;
1937 
1938 		name = question->name;
1939 		name->addr_list.ttl = additional->ttl;
1940 		name->attributes = additional->name->attributes;
1941 		name->addr_list.sin = additional->name->addr_list.sin;
1942 		name->addr_list.forw = name->addr_list.back = &name->addr_list;
1943 
1944 		if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1945 			smb_netbios_cache_update_entry(entry, name);
1946 			smb_netbios_cache_unlock_entry(entry);
1947 		}
1948 		else
1949 			(void) smb_netbios_cache_insert(name);
1950 
1951 		(void) smb_send_name_registration_response(addr, packet, 0);
1952 		break;
1953 
1954 	case NAME_OPCODE_QUERY:
1955 		/*
1956 		 * This opcode covers both NAME_QUERY_REQUEST and
1957 		 * NODE_STATUS_REQUEST. They can be distinguished
1958 		 * based on the type of question entry.
1959 		 */
1960 
1961 		/* All query requests have to have question entry */
1962 		if (question == 0)
1963 			break;
1964 
1965 		if (question->question_type == NAME_QUESTION_TYPE_NB) {
1966 			name = question->name;
1967 			if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1968 				/*
1969 				 * send response to the IP address and port
1970 				 * number from which the request was received.
1971 				 */
1972 				(void) smb_send_name_query_response(addr,
1973 				    packet, entry, 0);
1974 				smb_netbios_cache_unlock_entry(entry);
1975 			} else {
1976 				/*
1977 				 * send response to the requestor
1978 				 */
1979 				(void) smb_send_name_query_response(addr,
1980 				    packet, name, RCODE_NAM_ERR);
1981 			}
1982 		}
1983 		else
1984 		if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) {
1985 			/*
1986 			 * Name of "*" may be used to force node to
1987 			 * divulge status for administrative purposes
1988 			 */
1989 			name = question->name;
1990 			entry = 0;
1991 			if (NETBIOS_NAME_IS_STAR(name->name) ||
1992 			    ((entry = smb_netbios_cache_lookup(name)) != 0)) {
1993 				/*
1994 				 * send only those names that are
1995 				 * in the same scope as the scope
1996 				 * field in the request packet
1997 				 */
1998 				if (entry)
1999 					smb_netbios_cache_unlock_entry(entry);
2000 				(void) smb_send_node_status_response(addr,
2001 				    packet);
2002 			}
2003 		}
2004 		break;
2005 
2006 	default:
2007 		break;
2008 	}
2009 }
2010 
2011 static void
2012 smb_name_process_Mnode_packet(struct name_packet *packet, addr_entry_t *addr)
2013 {
2014 	if (packet->info & NAME_NM_FLAGS_B)
2015 		smb_name_process_Bnode_packet(packet, addr);
2016 	else
2017 		smb_name_process_Pnode_packet(packet, addr);
2018 }
2019 
2020 static void
2021 smb_name_process_Hnode_packet(struct name_packet *packet, addr_entry_t *addr)
2022 {
2023 	if (packet->info & NAME_NM_FLAGS_B)
2024 		smb_name_process_Bnode_packet(packet, addr);
2025 	else
2026 		smb_name_process_Pnode_packet(packet, addr);
2027 }
2028 
2029 
2030 /*
2031  * smb_netbios_name_tick
2032  *
2033  * Called once a second to handle name server timeouts.
2034  */
2035 void
2036 smb_netbios_name_tick(void)
2037 {
2038 	struct name_entry *name;
2039 	struct name_entry *entry;
2040 
2041 	(void) mutex_lock(&refresh_queue.mtx);
2042 	smb_netbios_cache_refresh(&refresh_queue);
2043 
2044 	while ((name = refresh_queue.head.forw) != &refresh_queue.head) {
2045 		QUEUE_CLIP(name);
2046 		if (IS_LOCAL(name->attributes)) {
2047 			if (IS_UNIQUE(name->attributes)) {
2048 				(void) smb_name_Pnode_refresh_name(name);
2049 			}
2050 		} else {
2051 			entry = smb_name_find_name(name);
2052 			smb_name_unlock_name(entry);
2053 		}
2054 		free(name);
2055 	}
2056 	(void) mutex_unlock(&refresh_queue.mtx);
2057 
2058 	smb_netbios_cache_reset_ttl();
2059 }
2060 
2061 /*
2062  * smb_name_find_name
2063  *
2064  * Lookup name cache for the given name.
2065  * If it's not in the cache it'll send a
2066  * name query request and then lookup the
2067  * cache again. Note that if a name is
2068  * returned it's locked and called MUST
2069  * unlock it by calling smb_name_unlock_name()
2070  */
2071 struct name_entry *
2072 smb_name_find_name(struct name_entry *name)
2073 {
2074 	struct name_entry *result;
2075 
2076 	if ((result = smb_netbios_cache_lookup(name)) == 0) {
2077 		switch (smb_node_type) {
2078 		case 'B':
2079 			(void) smb_name_Bnode_find_name(name);
2080 			break;
2081 		case 'P':
2082 			(void) smb_name_Pnode_find_name(name);
2083 			break;
2084 		case 'M':
2085 			(void) smb_name_Mnode_find_name(name);
2086 			break;
2087 		case 'H':
2088 		default:
2089 			(void) smb_name_Hnode_find_name(name);
2090 			break;
2091 		}
2092 		return (smb_netbios_cache_lookup(name));
2093 	}
2094 
2095 	return (result);
2096 }
2097 
2098 void
2099 smb_name_unlock_name(struct name_entry *name)
2100 {
2101 	smb_netbios_cache_unlock_entry(name);
2102 }
2103 
2104 int
2105 smb_name_add_name(struct name_entry *name)
2106 {
2107 	int			rc = 1;
2108 
2109 	smb_netbios_name_logf(name);
2110 
2111 	switch (smb_node_type) {
2112 	case 'B':
2113 		rc = smb_name_Bnode_add_name(name);
2114 		break;
2115 	case 'P':
2116 		rc = smb_name_Pnode_add_name(name);
2117 		break;
2118 	case 'M':
2119 		rc = smb_name_Mnode_add_name(name);
2120 		break;
2121 	case 'H':
2122 	default:
2123 		rc = smb_name_Hnode_add_name(name);
2124 		break;
2125 	}
2126 
2127 	if (rc >= 0)
2128 		(void) smb_netbios_cache_insert(name);
2129 
2130 	return (rc);
2131 }
2132 
2133 int
2134 smb_name_delete_name(struct name_entry *name)
2135 {
2136 	int			rc;
2137 	unsigned char type;
2138 
2139 	type = name->name[15];
2140 	if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
2141 		syslog(LOG_DEBUG, "nbns: name delete bad type (0x%02x)", type);
2142 		smb_netbios_name_logf(name);
2143 		name->attributes &= ~NAME_ATTR_LOCAL;
2144 		return (-1);
2145 	}
2146 
2147 	smb_netbios_cache_delete(name);
2148 
2149 	switch (smb_node_type) {
2150 	case 'B':
2151 		rc = smb_name_Bnode_delete_name(name);
2152 		break;
2153 	case 'P':
2154 		rc = smb_name_Pnode_delete_name(name);
2155 		break;
2156 	case 'M':
2157 		rc = smb_name_Mnode_delete_name(name);
2158 		break;
2159 	case 'H':
2160 	default:
2161 		rc = smb_name_Hnode_delete_name(name);
2162 		break;
2163 	}
2164 
2165 	if (rc > 0)
2166 		return (0);
2167 
2168 	return (-1);
2169 }
2170 
2171 typedef struct {
2172 	addr_entry_t *addr;
2173 	char *buf;
2174 	int length;
2175 } worker_param_t;
2176 
2177 /*
2178  * smb_netbios_worker
2179  *
2180  * Process incoming request/response packets for Netbios
2181  * name service (on port 138).
2182  */
2183 void *
2184 smb_netbios_worker(void *arg)
2185 {
2186 	worker_param_t *p = (worker_param_t *)arg;
2187 	addr_entry_t *addr = p->addr;
2188 	struct name_packet *packet;
2189 
2190 	if ((packet = smb_name_buf_to_packet(p->buf, p->length)) != NULL) {
2191 		if (packet->info & NAME_OPCODE_R) {
2192 			/* Reply packet */
2193 			smb_reply_ready(packet, addr);
2194 			free(p->buf);
2195 			free(p);
2196 			return (NULL);
2197 		}
2198 
2199 		/* Request packet */
2200 		switch (smb_node_type) {
2201 		case 'B':
2202 			smb_name_process_Bnode_packet(packet, addr);
2203 			break;
2204 		case 'P':
2205 			smb_name_process_Pnode_packet(packet, addr);
2206 			break;
2207 		case 'M':
2208 			smb_name_process_Mnode_packet(packet, addr);
2209 			break;
2210 		case 'H':
2211 		default:
2212 			smb_name_process_Hnode_packet(packet, addr);
2213 			break;
2214 		}
2215 
2216 		if (packet->answer)
2217 			smb_netbios_name_freeaddrs(packet->answer->name);
2218 		free(packet);
2219 	} else {
2220 		syslog(LOG_ERR, "nbns: packet decode failed");
2221 	}
2222 
2223 	free(addr);
2224 	free(p->buf);
2225 	free(p);
2226 	return (NULL);
2227 }
2228 
2229 /*
2230  * Configure the node type.  If a WINS server has been specified,
2231  * act like an H-node.  Otherwise, behave like a B-node.
2232  */
2233 static void
2234 smb_netbios_node_config(void)
2235 {
2236 	static smb_cfg_id_t	wins[SMB_PI_MAX_WINS] = {
2237 		SMB_CI_WINS_SRV1,
2238 		SMB_CI_WINS_SRV2
2239 	};
2240 	char		ipstr[16];
2241 	uint32_t	ipaddr;
2242 	int		i;
2243 
2244 	smb_node_type = SMB_NODETYPE_B;
2245 	nbns_num = 0;
2246 	bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS);
2247 
2248 	for (i = 0; i < SMB_PI_MAX_WINS; ++i) {
2249 		ipstr[0] = '\0';
2250 		(void) smb_config_getstr(wins[i], ipstr, sizeof (ipstr));
2251 
2252 		if ((ipaddr = inet_addr(ipstr)) == INADDR_NONE)
2253 			continue;
2254 
2255 		smb_node_type = SMB_NODETYPE_H;
2256 		smb_nbns[nbns_num].flags = ADDR_FLAG_VALID;
2257 		smb_nbns[nbns_num].sinlen = sizeof (struct sockaddr_in);
2258 		smb_nbns[nbns_num].sin.sin_family = AF_INET;
2259 		smb_nbns[nbns_num].sin.sin_addr.s_addr = ipaddr;
2260 		smb_nbns[nbns_num].sin.sin_port = htons(IPPORT_NETBIOS_NS);
2261 		nbns_num++;
2262 	}
2263 }
2264 
2265 static void
2266 smb_netbios_name_registration(void)
2267 {
2268 	nbcache_iter_t nbc_iter;
2269 	struct name_entry *name;
2270 	int rc;
2271 
2272 	rc = smb_netbios_cache_getfirst(&nbc_iter);
2273 	while (rc == 0) {
2274 		name = nbc_iter.nbc_entry;
2275 		(void) smb_netbios_name_logf(name);
2276 		if (IS_UNIQUE(name->attributes) && IS_LOCAL(name->attributes)) {
2277 			switch (smb_node_type) {
2278 			case SMB_NODETYPE_B:
2279 				(void) smb_name_Bnode_add_name(name);
2280 				break;
2281 			case SMB_NODETYPE_P:
2282 				(void) smb_name_Pnode_add_name(name);
2283 				break;
2284 			case SMB_NODETYPE_M:
2285 				(void) smb_name_Mnode_add_name(name);
2286 				break;
2287 			case SMB_NODETYPE_H:
2288 			default:
2289 				(void) smb_name_Hnode_add_name(name);
2290 				break;
2291 			}
2292 		}
2293 		free(name);
2294 		rc = smb_netbios_cache_getnext(&nbc_iter);
2295 	}
2296 }
2297 
2298 /*
2299  * Note that the node configuration must be setup before calling
2300  * smb_init_name_struct().
2301  */
2302 void
2303 smb_netbios_name_config(void)
2304 {
2305 	addr_entry_t		*bcast_entry;
2306 	struct name_entry	name;
2307 	smb_niciter_t		ni;
2308 	int			rc;
2309 
2310 	(void) mutex_lock(&nbt_name_config_mtx);
2311 	smb_netbios_node_config();
2312 
2313 	bcast_num = 0;
2314 	bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS);
2315 
2316 	rc = smb_nic_getfirst(&ni);
2317 	while (rc == SMB_NIC_SUCCESS) {
2318 		if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) ||
2319 		    (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS)) {
2320 			rc = smb_nic_getnext(&ni);
2321 			continue;
2322 		}
2323 
2324 		bcast_entry = &smb_bcast_list[bcast_num];
2325 		bcast_entry->flags = ADDR_FLAG_VALID;
2326 		bcast_entry->attributes = NAME_ATTR_LOCAL;
2327 		bcast_entry->sinlen = sizeof (struct sockaddr_in);
2328 		bcast_entry->sin.sin_family = AF_INET;
2329 		bcast_entry->sin.sin_port = htons(IPPORT_NETBIOS_NS);
2330 		bcast_entry->sin.sin_addr.s_addr = ni.ni_nic.nic_bcast;
2331 		bcast_num++;
2332 
2333 		smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
2334 		    NBT_WKSTA, 0, ni.ni_nic.nic_ip.a_ipv4,
2335 		    htons(IPPORT_NETBIOS_DGM),
2336 		    NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
2337 		(void) smb_netbios_cache_insert(&name);
2338 
2339 		smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
2340 		    NBT_SERVER, 0, ni.ni_nic.nic_ip.a_ipv4,
2341 		    htons(IPPORT_NETBIOS_DGM),
2342 		    NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
2343 		(void) smb_netbios_cache_insert(&name);
2344 
2345 		rc = smb_nic_getnext(&ni);
2346 	}
2347 
2348 	smb_netbios_name_registration();
2349 	(void) mutex_unlock(&nbt_name_config_mtx);
2350 }
2351 
2352 void
2353 smb_netbios_name_unconfig(void)
2354 {
2355 	struct name_entry *name;
2356 
2357 	(void) mutex_lock(&nbt_name_config_mtx);
2358 	(void) mutex_lock(&delete_queue.mtx);
2359 	smb_netbios_cache_delete_locals(&delete_queue);
2360 
2361 	while ((name = delete_queue.head.forw) != &delete_queue.head) {
2362 		QUEUE_CLIP(name);
2363 		(void) smb_name_delete_name(name);
2364 		free(name);
2365 	}
2366 	(void) mutex_unlock(&delete_queue.mtx);
2367 	(void) mutex_unlock(&nbt_name_config_mtx);
2368 }
2369 
2370 void
2371 smb_netbios_name_reconfig(void)
2372 {
2373 	smb_netbios_name_unconfig();
2374 	smb_netbios_name_config();
2375 }
2376 
2377 /*
2378  * NetBIOS Name Service (port 137)
2379  */
2380 /*ARGSUSED*/
2381 void *
2382 smb_netbios_name_service(void *arg)
2383 {
2384 	struct sockaddr_in	sin;
2385 	addr_entry_t		*addr;
2386 	int			len;
2387 	int			flag = 1;
2388 	char			*buf;
2389 	worker_param_t 		*worker_param;
2390 	smb_inaddr_t		ipaddr;
2391 
2392 	/*
2393 	 * Initialize reply_queue
2394 	 */
2395 	bzero(&reply_queue, sizeof (reply_queue));
2396 	reply_queue.forw = reply_queue.back = &reply_queue;
2397 
2398 	if ((name_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2399 		syslog(LOG_ERR, "nbns: socket failed: %m");
2400 		smb_netbios_event(NETBIOS_EVENT_ERROR);
2401 		return (NULL);
2402 	}
2403 
2404 	flag = 1;
2405 	(void) setsockopt(name_sock, SOL_SOCKET, SO_REUSEADDR, &flag,
2406 	    sizeof (flag));
2407 	flag = 1;
2408 	(void) setsockopt(name_sock, SOL_SOCKET, SO_BROADCAST, &flag,
2409 	    sizeof (flag));
2410 
2411 	bzero(&sin, sizeof (struct sockaddr_in));
2412 	sin.sin_family = AF_INET;
2413 	sin.sin_port = htons(IPPORT_NETBIOS_NS);
2414 	if (bind(name_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) {
2415 		syslog(LOG_ERR, "nbns: bind(%d) failed: %m",
2416 		    IPPORT_NETBIOS_NS);
2417 		(void) close(name_sock);
2418 		smb_netbios_event(NETBIOS_EVENT_ERROR);
2419 		return (NULL);
2420 	}
2421 
2422 	smb_netbios_event(NETBIOS_EVENT_NS_START);
2423 
2424 	while (smb_netbios_running()) {
2425 		buf = malloc(MAX_DATAGRAM_LENGTH);
2426 		addr = malloc(sizeof (addr_entry_t));
2427 		if ((buf == NULL) || (addr == NULL)) {
2428 			/* Sleep for 10 seconds and try again */
2429 			free(addr);
2430 			free(buf);
2431 			smb_netbios_sleep(10);
2432 			continue;
2433 		}
2434 ignore:		bzero(addr, sizeof (addr_entry_t));
2435 		addr->sinlen = sizeof (addr->sin);
2436 		addr->forw = addr->back = addr;
2437 
2438 		if ((len = recvfrom(name_sock, buf, MAX_DATAGRAM_LENGTH,
2439 		    0, (struct sockaddr *)&addr->sin, &addr->sinlen)) < 0) {
2440 			if (errno == ENOMEM || errno == ENFILE ||
2441 			    errno == EMFILE) {
2442 				/* Sleep for 10 seconds and try again */
2443 				free(buf);
2444 				free(addr);
2445 				smb_netbios_sleep(10);
2446 				continue;
2447 			}
2448 			syslog(LOG_ERR, "nbns: recvfrom failed: %m");
2449 			free(buf);
2450 			free(addr);
2451 			smb_netbios_event(NETBIOS_EVENT_ERROR);
2452 			goto shutdown;
2453 		}
2454 
2455 		/* Ignore any incoming packets from myself... */
2456 
2457 		ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr;
2458 		ipaddr.a_family = AF_INET;
2459 		if (smb_nic_is_local(&ipaddr))
2460 			goto ignore;
2461 
2462 		/*
2463 		 * Launch a netbios worker to process the received packet.
2464 		 */
2465 		worker_param = malloc(sizeof (worker_param_t));
2466 		if (worker_param) {
2467 			pthread_t worker;
2468 			pthread_attr_t tattr;
2469 
2470 			worker_param->addr = addr;
2471 			worker_param->buf = buf;
2472 			worker_param->length = len;
2473 
2474 			(void) pthread_attr_init(&tattr);
2475 			(void) pthread_attr_setdetachstate(&tattr,
2476 			    PTHREAD_CREATE_DETACHED);
2477 			(void) pthread_create(&worker, &tattr,
2478 			    smb_netbios_worker, worker_param);
2479 			(void) pthread_attr_destroy(&tattr);
2480 		}
2481 	}
2482 
2483 shutdown:
2484 	smb_netbios_event(NETBIOS_EVENT_NS_STOP);
2485 	smb_netbios_wait(NETBIOS_EVENT_BROWSER_STOP);
2486 
2487 	if (!smb_netbios_error())
2488 		smb_netbios_name_unconfig();
2489 
2490 	(void) close(name_sock);
2491 	return (NULL);
2492 }
2493