xref: /illumos-gate/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c (revision 7b59d02d2a384be9a08087b14defadd214b3c1dd)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Description:
30  *
31  *	Contains base code for netbios name service.
32  *
33  *
34  * 6.  DEFINED CONSTANTS AND VARIABLES
35  *
36  *   GENERAL:
37  *
38  *      SCOPE_ID                   The name of the NetBIOS scope.
39  *
40  *                                 This is expressed as a character
41  *                                 string meeting the requirements of
42  *                                 the domain name system and without
43  *                                 a leading or trailing "dot".
44  *
45  *                                 An implementation may elect to make
46  *                                 this a single global value for the
47  *                                 node or allow it to be specified
48  *                                 with each separate NetBIOS name
49  *                                 (thus permitting cross-scope
50  *                                 references.)
51  *
52  *      BROADCAST_ADDRESS          An IP address composed of the
53  *                                 nodes's network and subnetwork
54  *                                 numbers with all remaining bits set
55  *                                 to one.
56  *
57  *                                 I.e. "Specific subnet" broadcast
58  *                                 addressing according to section 2.3
59  *                                 of RFC 950.
60  *
61  *      BCAST_REQ_RETRY_TIMEOUT    250 milliseconds.
62  *                                 An adaptive timer may be used.
63  *
64  *      BCAST_REQ_RETRY_COUNT      3
65  *
66  *      UCAST_REQ_RETRY_TIMEOUT    5 seconds
67  *                                 An adaptive timer may be used.
68  *
69  *      UCAST_REQ_RETRY_COUNT      3
70  *
71  *      MAX_DATAGRAM_LENGTH        576 bytes (default)
72  *
73  *
74  *   NAME SERVICE:
75  *
76  *      REFRESH_TIMER              Negotiated with NAME for each name.
77  *
78  *      CONFLICT_TIMER             1 second
79  *                                 Implementations may chose a longer
80  *                                 value.
81  *
82  *
83  *      NAME_SERVICE_TCP_PORT      137 (decimal)
84  *
85  *      NAME_SERVICE_UDP_PORT      137 (decimal)
86  *
87  *      INFINITE_TTL               0
88  */
89 
90 #include <unistd.h>
91 #include <syslog.h>
92 #include <stdlib.h>
93 #include <synch.h>
94 #include <errno.h>
95 #include <netdb.h>
96 #include <sys/socket.h>
97 #include <sys/sockio.h>
98 #include <arpa/inet.h>
99 #include <net/if_arp.h>
100 
101 #include <smbsrv/libsmbns.h>
102 #include <smbns_netbios.h>
103 
104 #define	NAME_HEADER_SIZE 12
105 
106 typedef struct name_reply {
107 	struct name_reply *forw;
108 	struct name_reply *back;
109 	struct name_packet *packet;
110 	struct addr_entry *addr;
111 	unsigned short name_trn_id;
112 	unsigned short flags;
113 } name_reply;
114 
115 static struct name_reply reply_queue;
116 static mutex_t rq_mtx;
117 
118 static mutex_t reply_mtx;
119 static cond_t reply_cv;
120 
121 static name_queue_t delete_queue;
122 static name_queue_t refresh_queue;
123 
124 /*
125  * Flag to control whether or not NetBIOS name refresh requests
126  * are logged. Set to non-zero to enable logging.
127  */
128 
129 static unsigned short netbios_name_transcation_id = 1;
130 static int name_sock = 0;
131 
132 static int bcast_num = 0;
133 static int nbns_num = 0;
134 static struct addr_entry smb_bcast_list[SMB_PI_MAX_NETWORKS];
135 static struct addr_entry smb_nbns[SMB_PI_MAX_WINS];
136 
137 static int smb_netbios_process_response(unsigned short, struct addr_entry *,
138     struct name_packet *, uint32_t);
139 
140 static int smb_send_name_service_packet(struct addr_entry *addr,
141     struct name_packet *packet);
142 
143 static int
144 smb_end_node_challenge(struct name_reply *reply_info)
145 {
146 	int			rc;
147 	uint32_t		retry;
148 	unsigned short		tid;
149 	struct resource_record	*answer;
150 	struct name_question	question;
151 	struct addr_entry 	*addr;
152 	struct name_entry 	*destination;
153 	struct name_packet	packet;
154 	struct timespec 	st;
155 
156 	/*
157 	 * The response packet has in it the address of the presumed owner
158 	 * of the name.  Challenge that owner.  If owner either does not
159 	 * respond or indicates that he no longer owns the name, claim the
160 	 * name.  Otherwise, the name cannot be claimed.
161 	 */
162 
163 	if ((answer = reply_info->packet->answer) == 0)
164 		return (-1);
165 
166 	destination = answer->name;
167 	question.name = answer->name;
168 
169 	packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST;
170 	packet.qdcount = 1;	/* question entries */
171 	packet.question = &question;
172 	packet.ancount = 0;	/* answer recs */
173 	packet.answer = NULL;
174 	packet.nscount = 0;	/* authority recs */
175 	packet.authority = NULL;
176 	packet.arcount = 0;	/* additional recs */
177 	packet.additional = NULL;
178 
179 	addr = &destination->addr_list;
180 	for (retry = 0; retry < UCAST_REQ_RETRY_COUNT; retry++) {
181 		tid = netbios_name_transcation_id++;
182 		packet.name_trn_id = tid;
183 		if (smb_send_name_service_packet(addr, &packet) >= 0) {
184 			if ((rc = smb_netbios_process_response(tid, addr,
185 			    &packet, UCAST_REQ_RETRY_TIMEOUT)) != 0)
186 				return (rc);
187 		}
188 		st.tv_sec = 0;
189 		st.tv_nsec = (UCAST_REQ_RETRY_TIMEOUT * 1000000);
190 		(void) nanosleep(&st, 0);
191 	}
192 	/* No reply */
193 	return (0);
194 }
195 
196 
197 static struct name_reply *
198 smb_name_get_reply(unsigned short tid, uint32_t timeout)
199 {
200 	unsigned short		info;
201 	struct resource_record	*answer;
202 	struct name_reply 	*reply;
203 	uint32_t 		wait_time, to_save; /* in millisecond */
204 	struct timeval 		wt;
205 	timestruc_t 		to;
206 
207 	to_save = timeout;
208 	reply = (struct name_reply *)malloc(sizeof (struct name_reply));
209 	if (reply != 0) {
210 		reply->flags = 0;
211 		reply->name_trn_id = tid;
212 		(void) mutex_lock(&rq_mtx);
213 		QUEUE_INSERT_TAIL(&reply_queue, reply);
214 		(void) mutex_unlock(&rq_mtx);
215 
216 		for (;;) {
217 			(void) gettimeofday(&wt, 0);
218 			wait_time = wt.tv_usec / 1000;
219 
220 			(void) mutex_lock(&reply_mtx);
221 			to.tv_sec = 0;
222 			to.tv_nsec = timeout * 1000000;
223 			(void) cond_reltimedwait(&reply_cv, &reply_mtx, &to);
224 			(void) mutex_unlock(&reply_mtx);
225 
226 			if (reply->flags != 0) {
227 				info = reply->packet->info;
228 				if (PACKET_TYPE(info) == WACK_RESPONSE) {
229 					answer = reply->packet->answer;
230 					wait_time = (answer) ?
231 					    TO_MILLISECONDS(answer->ttl) :
232 					    DEFAULT_TTL;
233 					free(reply->addr);
234 					free(reply->packet);
235 					timeout = to_save + wait_time;
236 					reply->flags = 0;
237 					reply->name_trn_id = tid;
238 					(void) mutex_lock(&rq_mtx);
239 					QUEUE_INSERT_TAIL(&reply_queue, reply);
240 					(void) mutex_unlock(&rq_mtx);
241 					continue;
242 				}
243 				return (reply);
244 			}
245 			(void) gettimeofday(&wt, 0);
246 			wait_time = (wt.tv_usec / 1000) - wait_time;
247 			if (wait_time >= timeout) {
248 				(void) mutex_lock(&rq_mtx);
249 				QUEUE_CLIP(reply);
250 				(void) mutex_unlock(&rq_mtx);
251 				free(reply);
252 				break;
253 			}
254 			timeout -= wait_time;
255 		}
256 	}
257 
258 	return (0);
259 }
260 
261 static void
262 smb_reply_ready(struct name_packet *packet, struct addr_entry *addr)
263 {
264 	struct name_reply *reply;
265 	struct resource_record *answer;
266 
267 	(void) mutex_lock(&rq_mtx);
268 	for (reply = reply_queue.forw; reply != &reply_queue;
269 	    reply = reply->forw) {
270 		if (reply->name_trn_id == packet->name_trn_id) {
271 			QUEUE_CLIP(reply);
272 			(void) mutex_unlock(&rq_mtx);
273 
274 			reply->addr = addr;
275 			reply->packet = packet;
276 
277 			(void) mutex_lock(&reply_mtx);
278 			reply->flags |= 0x0001; /* reply ready */
279 			(void) cond_signal(&reply_cv);
280 			(void) mutex_unlock(&reply_mtx);
281 
282 			return;
283 		}
284 	}
285 	(void) mutex_unlock(&rq_mtx);
286 
287 	/* Presumably nobody is waiting any more... */
288 	free(addr);
289 
290 	answer = packet->answer;
291 	if (answer)
292 		smb_netbios_name_freeaddrs(answer->name);
293 	free(packet);
294 }
295 
296 static int
297 smb_netbios_process_response(unsigned short tid, struct addr_entry *addr,
298     struct name_packet *packet, uint32_t timeout)
299 {
300 	int			rc = 0;
301 	unsigned short		info;
302 	struct name_reply 	*reply;
303 	struct resource_record	*answer;
304 	struct name_entry 	*name;
305 	struct name_entry 	*entry;
306 	struct name_question 	*question;
307 	uint32_t 		ttl;
308 
309 	if ((reply = smb_name_get_reply(tid, timeout)) == 0) {
310 		return (0); /* No reply: retry */
311 	}
312 	info = reply->packet->info;
313 	answer = reply->packet->answer;
314 
315 	/* response */
316 	switch (PACKET_TYPE(info)) {
317 	case NAME_QUERY_RESPONSE:
318 		if (POSITIVE_RESPONSE(info)) {
319 			addr = &answer->name->addr_list;
320 			do {
321 				/*
322 				 * Make sure that remote name is not
323 				 * flagged local
324 				 */
325 				addr->attributes &= ~NAME_ATTR_LOCAL;
326 
327 				addr->refresh_ttl = addr->ttl =
328 				    (answer && answer->ttl) ?
329 				    (answer->ttl >> 1) :
330 				    TO_SECONDS(DEFAULT_TTL);
331 				addr = addr->forw;
332 			} while (addr != &answer->name->addr_list);
333 			smb_netbios_name_dump(answer->name);
334 			(void) smb_netbios_cache_insert_list(answer->name);
335 			rc = 1;
336 		} else {
337 			rc = -1;
338 		}
339 		break;
340 
341 	case NAME_REGISTRATION_RESPONSE:
342 		if (NEGATIVE_RESPONSE(info)) {
343 			if (RCODE(info) == RCODE_CFT_ERR) {
344 				if (answer == 0) {
345 					rc = -RCODE(info);
346 					break;
347 				}
348 
349 				name = answer->name;
350 				entry = smb_netbios_cache_lookup(name);
351 				if (entry) {
352 					/*
353 					 * a name in the state "conflict
354 					 * detected" does not "logically" exist
355 					 * on that node. No further session
356 					 * will be accepted on that name.
357 					 * No datagrams can be sent against
358 					 * that name.
359 					 * Such an entry will not be used for
360 					 * purposes of processing incoming
361 					 * request packets.
362 					 * The only valid user NetBIOS operation
363 					 * against such a name is DELETE NAME.
364 					 */
365 					entry->attributes |= NAME_ATTR_CONFLICT;
366 					syslog(LOG_DEBUG,
367 					    "NETBIOS Name conflict: %15.15s",
368 					    entry->name);
369 					smb_netbios_cache_unlock_entry(entry);
370 				}
371 			}
372 			rc = -RCODE(info);
373 			break;
374 		}
375 
376 		/*
377 		 * name can be added:
378 		 *   adjust refresh timeout value,
379 		 *   TTL, for this name
380 		 */
381 		question = packet->question;
382 		ttl = (answer && answer->ttl) ? answer->ttl >> 1
383 		    : TO_SECONDS(DEFAULT_TTL);
384 		if ((entry = smb_netbios_cache_lookup(question->name)) != 0) {
385 			addr = &entry->addr_list;
386 			do {
387 				if ((addr->refresh_ttl == 0) ||
388 				    (ttl < addr->refresh_ttl))
389 					addr->refresh_ttl = addr->ttl = ttl;
390 				addr = addr->forw;
391 			} while (addr != &entry->addr_list);
392 			smb_netbios_cache_unlock_entry(entry);
393 		}
394 
395 		rc = 1;
396 		break;
397 
398 	case NAME_RELEASE_RESPONSE:
399 		rc = 1;
400 		break;
401 
402 	case END_NODE_CHALLENGE_REGISTRATION_REQUEST:
403 		/*
404 		 * The response packet has in it the
405 		 * address of the presumed owner of the
406 		 * name.  Challenge that owner.  If
407 		 * owner either does not respond or
408 		 * indicates that he no longer owns the
409 		 * name, claim the name.  Otherwise,
410 		 * the name cannot be claimed.
411 		 */
412 		rc = smb_end_node_challenge(reply);
413 		break;
414 
415 	default:
416 		rc = 0;
417 		break;
418 	}
419 
420 	if (answer)
421 		smb_netbios_name_freeaddrs(answer->name);
422 	free(reply->addr);
423 	free(reply->packet);
424 	free(reply);
425 	return (rc);  /* retry */
426 }
427 
428 /*
429  * smb_name_buf_from_packet
430  *
431  * Description:
432  *	Convert a NetBIOS Name Server Packet Block (npb)
433  *	into the bits and bytes destined for the wire.
434  *	The "buf" is used as a heap.
435  *
436  * Inputs:
437  *	char *		buf	-> Buffer, from the wire
438  *	unsigned	n_buf	-> Length of 'buf'
439  *	name_packet	*npb	-> Packet block, decode into
440  *	unsigned	n_npb	-> Max bytes in 'npb'
441  *
442  * Returns:
443  *	>0	-> Encode successful, value is length of packet in "buf"
444  *	-1	-> Hard error, can not possibly encode
445  *	-2	-> Need more memory in buf -- it's too small
446  */
447 
448 static int
449 smb_name_buf_from_packet(unsigned char *buf,
450     int n_buf,
451     struct name_packet *npb)
452 {
453 	struct addr_entry 	*raddr;
454 	unsigned char 		*heap = buf;
455 	unsigned char 		*end_heap = heap + n_buf;
456 	unsigned char 		*dnptrs[32];
457 	unsigned char		comp_name_buf[MAX_NAME_LENGTH];
458 	unsigned int		tmp;
459 	int			i, step;
460 
461 	if (n_buf < NAME_HEADER_SIZE)
462 		return (-1);		/* no header, impossible */
463 
464 	dnptrs[0] = heap;
465 	dnptrs[1] = 0;
466 
467 	BE_OUT16(heap, npb->name_trn_id);
468 	heap += 2;
469 
470 	BE_OUT16(heap, npb->info);
471 	heap += 2;
472 
473 	BE_OUT16(heap, npb->qdcount);
474 	heap += 2;
475 
476 	BE_OUT16(heap, npb->ancount);
477 	heap += 2;
478 
479 	BE_OUT16(heap, npb->nscount);
480 	heap += 2;
481 
482 	BE_OUT16(heap, npb->arcount);
483 	heap += 2;
484 
485 	for (i = 0; i < npb->qdcount; i++) {
486 		if ((heap + 34 + 4) > end_heap)
487 			return (-2);
488 
489 		(void) smb_first_level_name_encode(npb->question[i].name,
490 		    comp_name_buf, sizeof (comp_name_buf));
491 		(void) strcpy((char *)heap, (char *)comp_name_buf);
492 		heap += strlen((char *)comp_name_buf) + 1;
493 
494 		BE_OUT16(heap, npb->question[i].question_type);
495 		heap += 2;
496 
497 		BE_OUT16(heap, npb->question[i].question_class);
498 		heap += 2;
499 	}
500 
501 	for (step = 1; step <= 3; step++) {
502 		struct resource_record *nrr;
503 		int n;
504 
505 		/* truly ugly, but saves code copying */
506 		if (step == 1) {
507 			n = npb->ancount;
508 			nrr = npb->answer;
509 		} else if (step == 2) {
510 			n = npb->nscount;
511 			nrr = npb->authority;
512 		} else { /* step == 3 */
513 			n = npb->arcount;
514 			nrr = npb->additional;
515 		}
516 
517 		for (i = 0; i < n; i++) {
518 			if ((heap + 34 + 10) > end_heap)
519 				return (-2);
520 
521 			(void) smb_first_level_name_encode(nrr->name,
522 			    comp_name_buf, sizeof (comp_name_buf));
523 			(void) strcpy((char *)heap, (char *)comp_name_buf);
524 			heap += strlen((char *)comp_name_buf) + 1;
525 
526 			BE_OUT16(heap, nrr[i].rr_type);
527 			heap += 2;
528 
529 			BE_OUT16(heap, nrr[i].rr_class);
530 			heap += 2;
531 
532 			BE_OUT32(heap, nrr[i].ttl);
533 			heap += 4;
534 
535 			BE_OUT16(heap, nrr[i].rdlength);
536 			heap += 2;
537 
538 			if ((tmp = nrr[i].rdlength) > 0) {
539 				if ((heap + tmp) > end_heap)
540 					return (-2);
541 
542 				if (nrr[i].rr_type == NAME_RR_TYPE_NB &&
543 				    nrr[i].rr_class == NAME_RR_CLASS_IN &&
544 				    tmp >= 6 && nrr[i].rdata == 0) {
545 					tmp = nrr[i].name->attributes &
546 					    (NAME_ATTR_GROUP |
547 					    NAME_ATTR_OWNER_NODE_TYPE);
548 					BE_OUT16(heap, tmp);
549 					heap += 2;
550 
551 					raddr = &nrr[i].name->addr_list;
552 					(void) memcpy(heap,
553 					    &raddr->sin.sin_addr.s_addr,
554 					    sizeof (uint32_t));
555 					heap += 4;
556 				} else {
557 					bcopy(nrr[i].rdata, heap, tmp);
558 					heap += tmp;
559 				}
560 			}
561 		}
562 	}
563 	return (heap - buf);
564 }
565 
566 /*
567  * strnchr
568  *
569  * Lookup for character 'c' in first 'n' chars of string 's'.
570  * Returns pointer to the found char, otherwise returns 0.
571  */
572 static char *
573 strnchr(const char *s, char c, int n)
574 {
575 	char *ps = (char *)s;
576 	char *es = (char *)s + n;
577 
578 	while (ps < es && *ps) {
579 		if (*ps == c)
580 			return (ps);
581 
582 		++ps;
583 	}
584 
585 	if (*ps == '\0' && c == '\0')
586 		return (ps);
587 
588 	return (0);
589 }
590 
591 static boolean_t
592 is_multihome(char *name)
593 {
594 	return (smb_nic_getnum(name) > 1);
595 }
596 
597 /*
598  * smb_netbios_getname
599  *
600  * Get the Netbios name part of the given record.
601  * Does some boundary checks.
602  *
603  * Returns the name length on success, otherwise
604  * returns 0.
605  */
606 static int
607 smb_netbios_getname(char *name, char *buf, char *buf_end)
608 {
609 	char *name_end;
610 	int name_len;
611 
612 	if (buf >= buf_end) {
613 		/* no room for a NB name */
614 		return (0);
615 	}
616 
617 	name_end = strnchr(buf, '\0', buf_end - buf + 1);
618 	if (name_end == 0) {
619 		/* not a valid NB name */
620 		return (0);
621 	}
622 
623 	name_len = name_end - buf + 1;
624 
625 	(void) strlcpy(name, buf, name_len);
626 	return (name_len);
627 }
628 
629 
630 /*
631  * smb_name_buf_to_packet
632  *
633  * Description:
634  *	Convert the bits and bytes that came from the wire
635  *	into a NetBIOS Name Server Packet Block (npb).
636  *	The "block" is used as a heap.
637  *
638  * Inputs:
639  *	char *		buf	-> Buffer, from the wire
640  *	int		n_buf	-> Length of 'buf'
641  *	name_packet	*npb	-> Packet block, decode into
642  *	int		n_npb	-> Max bytes in 'npb'
643  *
644  * Returns:
645  *	>0	-> Decode (parse) successful, value is byte length of npb
646  *	-1	-> Hard error, can not possibly decode
647  *	-2	-> Need more memory in npb -- it's too small
648  */
649 
650 static struct name_packet *
651 smb_name_buf_to_packet(char *buf, int n_buf)
652 {
653 	struct name_packet *npb;
654 	unsigned char *heap;
655 	unsigned char *scan = (unsigned char *)buf;
656 	unsigned char *scan_end = scan + n_buf;
657 	char name_buf[MAX_NAME_LENGTH];
658 	struct resource_record *nrr = 0;
659 	int	rc, i, n, nn, ns;
660 	unsigned short name_trn_id, info;
661 	unsigned short qdcount, ancount, nscount, arcount;
662 	struct addr_entry *next;
663 	int name_len;
664 
665 	if (n_buf < NAME_HEADER_SIZE) {
666 		/* truncated header */
667 		syslog(LOG_DEBUG, "SmbNBNS: packet is too short (%d)",
668 		    n_buf);
669 		return (0);
670 	}
671 
672 	name_trn_id = BE_IN16(scan); scan += 2;
673 	info = BE_IN16(scan); scan += 2;
674 	qdcount = BE_IN16(scan); scan += 2;
675 	ancount = BE_IN16(scan); scan += 2;
676 	nscount = BE_IN16(scan); scan += 2;
677 	arcount = BE_IN16(scan); scan += 2;
678 
679 	ns = sizeof (struct name_entry);
680 	n = n_buf + sizeof (struct name_packet) +
681 	    ((unsigned)qdcount * (sizeof (struct name_question) + ns)) +
682 	    ((unsigned)ancount * (sizeof (struct resource_record) + ns)) +
683 	    ((unsigned)nscount * (sizeof (struct resource_record) + ns)) +
684 	    ((unsigned)arcount * (sizeof (struct resource_record) + ns));
685 
686 	if ((npb = (struct name_packet *)malloc(n)) == 0) {
687 		return (0);
688 	}
689 	bzero(npb, n);
690 
691 	heap = npb->block_data;
692 	npb->name_trn_id = name_trn_id;
693 	npb->info = info;
694 	npb->qdcount = qdcount;
695 	npb->ancount = ancount;
696 	npb->nscount = nscount;
697 	npb->arcount = arcount;
698 
699 	/* scan is in position for question entries */
700 
701 	/*
702 	 * Measure the space needed for the tables
703 	 */
704 	if (qdcount > 0) {
705 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
706 		npb->question = (struct name_question *)heap;
707 		heap += qdcount * sizeof (struct name_question);
708 		for (i = 0; i < qdcount; i++) {
709 			/* LINTED - E_BAD_PTR_CAST_ALIGN */
710 			npb->question[i].name = (struct name_entry *)heap;
711 			heap += sizeof (struct name_entry);
712 		}
713 	}
714 
715 	/* LINTED - E_BAD_PTR_CAST_ALIGN */
716 	nrr = (struct resource_record *)heap;
717 
718 	if (ancount > 0) {
719 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
720 		npb->answer = (struct resource_record *)heap;
721 		heap += ancount * sizeof (struct resource_record);
722 	}
723 
724 	if (nscount > 0) {
725 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
726 		npb->authority = (struct resource_record *)heap;
727 		heap += nscount * sizeof (struct resource_record);
728 	}
729 
730 	if (arcount > 0) {
731 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
732 		npb->additional = (struct resource_record *)heap;
733 		heap += arcount * sizeof (struct resource_record);
734 	}
735 
736 	/*
737 	 * Populate each resource_record's .name field.
738 	 * Done as a second pass so that all resource records
739 	 * (answer, authority, additional) are consecutive via nrr[i].
740 	 */
741 	for (i = 0; i < (ancount + nscount + arcount); i++) {
742 		/* LINTED - E_BAD_PTR_CAST_ALIGN */
743 		nrr[i].name = (struct name_entry *)heap;
744 		heap += sizeof (struct name_entry);
745 	}
746 
747 
748 	for (i = 0; i < npb->qdcount; i++) {
749 		name_len = smb_netbios_getname(name_buf, (char *)scan,
750 		    (char *)scan_end);
751 		if (name_len <= 0) {
752 			free(npb);
753 			return (0);
754 		}
755 
756 		smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
757 		    npb->question[i].name);
758 		rc = smb_first_level_name_decode((unsigned char *)name_buf,
759 		    npb->question[i].name);
760 		if (rc < 0) {
761 			/* Couldn't decode the question name */
762 			free(npb);
763 			return (0);
764 		}
765 
766 		scan += name_len;
767 		if (scan + 4 > scan_end) {
768 			/* no room for Question Type(2) and Class(2) fields */
769 			free(npb);
770 			return (0);
771 		}
772 
773 		npb->question[i].question_type = BE_IN16(scan); scan += 2;
774 		npb->question[i].question_class = BE_IN16(scan); scan += 2;
775 	}
776 
777 	/*
778 	 * Cheat. Remaining sections are of the same resource_record
779 	 * format. Table space is consecutive.
780 	 */
781 
782 	for (i = 0; i < (ancount + nscount + arcount); i++) {
783 		if (scan[0] == 0xc0) {
784 			/* Namebuf is reused... */
785 			rc = 2;
786 		} else {
787 			name_len = smb_netbios_getname(name_buf, (char *)scan,
788 			    (char *)scan_end);
789 			if (name_len <= 0) {
790 				free(npb);
791 				return (0);
792 			}
793 			rc = name_len;
794 		}
795 		scan += rc;
796 
797 		if (scan + 10 > scan_end) {
798 			/*
799 			 * no room for RR_TYPE (2), RR_CLASS (2), TTL (4) and
800 			 * RDLENGTH (2) fields.
801 			 */
802 			free(npb);
803 			return (0);
804 		}
805 
806 		smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
807 		    nrr[i].name);
808 		if ((rc = smb_first_level_name_decode((unsigned char *)name_buf,
809 		    nrr[i].name)) < 0) {
810 			free(npb);
811 			return (0);
812 		}
813 
814 		nrr[i].rr_type = BE_IN16(scan); scan += 2;
815 		nrr[i].rr_class = BE_IN16(scan); scan += 2;
816 		nrr[i].ttl = BE_IN32(scan); scan += 4;
817 		nrr[i].rdlength = BE_IN16(scan); scan += 2;
818 
819 		if ((n = nrr[i].rdlength) > 0) {
820 			if ((scan + n) > scan_end) {
821 				/* no room for RDATA */
822 				free(npb);
823 				return (0);
824 			}
825 			bcopy(scan, heap, n);
826 
827 			nn = n;
828 			if (nrr[i].rr_type == 0x0020 &&
829 			    nrr[i].rr_class == 0x01 && n >= 6) {
830 				while (nn) {
831 					if (nn == 6)
832 						next = &nrr[i].name->addr_list;
833 					else {
834 						next = (struct addr_entry *)
835 						    malloc(
836 						    sizeof (struct addr_entry));
837 						if (next == 0) {
838 							/* not enough memory */
839 							free(npb);
840 							return (0);
841 						}
842 						QUEUE_INSERT_TAIL(
843 						    &nrr[i].name->addr_list,
844 						    next);
845 					}
846 					nrr[i].name->attributes =
847 					    BE_IN16(scan);
848 					next->sin.sin_family = AF_INET;
849 					next->sinlen = sizeof (next->sin);
850 					(void) memcpy(
851 					    &next->sin.sin_addr.s_addr,
852 					    scan + 2, sizeof (uint32_t));
853 					next->sin.sin_port =
854 					    htons(DGM_SRVC_UDP_PORT);
855 					nn -= 6;
856 					scan += 6;
857 				}
858 			} else {
859 				nrr[i].rdata = heap;
860 				scan += n;
861 			}
862 			heap += n;
863 		}
864 	}
865 	return (npb);
866 }
867 
868 
869 /*
870  * smb_send_name_service_packet
871  *
872  * Description:
873  *
874  *	Send out a name service packet to proper destination.
875  *
876  * Inputs:
877  *	struct netbios_name *dest	-> NETBIOS name of destination
878  *	struct name_packet *packet	-> Packet to send
879  *
880  * Returns:
881  *	success	->  >0
882  *	failure	-> <=0
883  */
884 
885 static int
886 smb_send_name_service_packet(struct addr_entry *addr,
887 				struct name_packet *packet)
888 {
889 	unsigned char buf[MAX_DATAGRAM_LENGTH];
890 	int len;
891 
892 	if ((len = smb_name_buf_from_packet(buf, sizeof (buf), packet)) < 0) {
893 		errno = EINVAL;
894 		return (-1);
895 	}
896 
897 	return (sendto(name_sock, buf, len, MSG_EOR,
898 	    (struct sockaddr *)&addr->sin, addr->sinlen));
899 }
900 
901 /*
902  * 4.2.1.1.  HEADER
903  *
904  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
905  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
906  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
907  *   |         NAME_TRN_ID           | OPCODE  |   NM_FLAGS  | RCODE |
908  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
909  *   |          QDCOUNT              |           ANCOUNT             |
910  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
911  *   |          NSCOUNT              |           ARCOUNT             |
912  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
913  *
914  *   Field     Description
915  *
916  *   NAME_TRN_ID      Transaction ID for Name Service Transaction.
917  *                    Requester places a unique value for each active
918  *                    transaction.  Responder puts NAME_TRN_ID value
919  *                    from request packet in response packet.
920  *
921  *   OPCODE           Packet type code, see table below.
922  *
923  *   NM_FLAGS         Flags for operation, see table below.
924  *
925  *   RCODE            Result codes of request.  Table of RCODE values
926  *                    for each response packet below.
927  *
928  *   QDCOUNT          Unsigned 16 bit integer specifying the number of
929  *                    entries in the question section of a Name
930  *
931  *                    Service packet.  Always zero (0) for responses.
932  *                    Must be non-zero for all NetBIOS Name requests.
933  *
934  *   ANCOUNT          Unsigned 16 bit integer specifying the number of
935  *                    resource records in the answer section of a Name
936  *                    Service packet.
937  *
938  *   NSCOUNT          Unsigned 16 bit integer specifying the number of
939  *                    resource records in the authority section of a
940  *                    Name Service packet.
941  *
942  *   ARCOUNT          Unsigned 16 bit integer specifying the number of
943  *                    resource records in the additional records
944  *                    section of a Name Service packet.
945  *
946  *   The OPCODE field is defined as:
947  *
948  *     0   1   2   3   4
949  *   +---+---+---+---+---+
950  *   | R |    OPCODE     |
951  *   +---+---+---+---+---+
952  *
953  *   Symbol     Bit(s)   Description
954  *
955  *   OPCODE        1-4   Operation specifier:
956  *                         0 = query
957  *                         5 = registration
958  *                         6 = release
959  *                         7 = WACK
960  *                         8 = refresh
961  *
962  *   R               0   RESPONSE flag:
963  *                         if bit == 0 then request packet
964  *                         if bit == 1 then response packet.
965  */
966 
967 
968 /*
969  *   The NM_FLAGS field is defined as:
970  *
971  *
972  *     0   1   2   3   4   5   6
973  *   +---+---+---+---+---+---+---+
974  *   |AA |TC |RD |RA | 0 | 0 | B |
975  *   +---+---+---+---+---+---+---+
976  *
977  *   Symbol     Bit(s)   Description
978  *
979  *   B               6   Broadcast Flag.
980  *                         = 1: packet was broadcast or multicast
981  *                         = 0: unicast
982  *
983  *   RA              3   Recursion Available Flag.
984  *
985  *                       Only valid in responses from a NetBIOS Name
986  *                       Server -- must be zero in all other
987  *                       responses.
988  *
989  *                       If one (1) then the NAME supports recursive
990  *                       query, registration, and release.
991  *
992  *                       If zero (0) then the end-node must iterate
993  *                       for query and challenge for registration.
994  *
995  *   RD              2   Recursion Desired Flag.
996  *
997  *                       May only be set on a request to a NetBIOS
998  *                       Name Server.
999  *
1000  *                       The NAME will copy its state into the
1001  *                       response packet.
1002  *
1003  *                       If one (1) the NAME will iterate on the
1004  *                       query, registration, or release.
1005  *
1006  *   TC              1   Truncation Flag.
1007  *
1008  *                       Set if this message was truncated because the
1009  *                       datagram carrying it would be greater than
1010  *                       576 bytes in length.  Use TCP to get the
1011  *                       information from the NetBIOS Name Server.
1012  *
1013  *   AA              0   Authoritative Answer flag.
1014  *
1015  *                       Must be zero (0) if R flag of OPCODE is zero
1016  *                       (0).
1017  *
1018  *                       If R flag is one (1) then if AA is one (1)
1019  *                       then the node responding is an authority for
1020  *                       the domain name.
1021  *
1022  *                       End nodes responding to queries always set
1023  *                       this bit in responses.
1024  *
1025  */
1026 
1027 /*
1028  * 4.2.1.2.  QUESTION SECTION
1029  *
1030  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1031  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1032  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1033  *   |                                                               |
1034  *   /                         QUESTION_NAME                         /
1035  *   /                                                               /
1036  *   |                                                               |
1037  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1038  *   |         QUESTION_TYPE         |        QUESTION_CLASS         |
1039  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1040  *
1041  *   Field            Description
1042  *
1043  *   QUESTION_NAME    The compressed name representation of the
1044  *                    NetBIOS name for the request.
1045  *
1046  *   QUESTION_TYPE    The type of request.  The values for this field
1047  *                    are specified for each request.
1048  *
1049  *   QUESTION_CLASS   The class of the request.  The values for this
1050  *                    field are specified for each request.
1051  *
1052  *   QUESTION_TYPE is defined as:
1053  *
1054  *   Symbol      Value   Description:
1055  *
1056  *   NB         0x0020   NetBIOS general Name Service Resource Record
1057  *   NBSTAT     0x0021   NetBIOS NODE STATUS Resource Record (See NODE
1058  *                       STATUS REQUEST)
1059  *
1060  *   QUESTION_CLASS is defined as:
1061  *
1062  *   Symbol      Value   Description:
1063  *
1064  *   IN         0x0001   Internet class
1065  */
1066 
1067 #define	QUESTION_TYPE_NETBIOS_GENERAL	0x20
1068 #define	QUESTION_TYPE_NETBIOS_STATUS	0x21
1069 
1070 #define	QUESTION_CLASS_INTERNET		0x0001
1071 
1072 /*
1073  *
1074  * 4.2.1.3.  RESOURCE RECORD
1075  *
1076  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1077  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1078  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1079  *   |                                                               |
1080  *   /                            RR_NAME                            /
1081  *   /                                                               /
1082  *   |                                                               |
1083  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1084  *   |           RR_TYPE             |          RR_CLASS             |
1085  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1086  *   |                              TTL                              |
1087  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1088  *   |           RDLENGTH            |                               |
1089  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
1090  *   /                                                               /
1091  *   /                             RDATA                             /
1092  *   |                                                               |
1093  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1094  *
1095  *   Field            Description
1096  *
1097  *   RR_NAME          The compressed name representation of the
1098  *                    NetBIOS name corresponding to this resource
1099  *                    record.
1100  *
1101  *   RR_TYPE          Resource record type code
1102  *
1103  *   RR_CLASS         Resource record class code
1104  *
1105  *   TTL              The Time To Live of a the resource record's
1106  *                    name.
1107  *
1108  *   RDLENGTH         Unsigned 16 bit integer that specifies the
1109  *                    number of bytes in the RDATA field.
1110  *
1111  *   RDATA            RR_CLASS and RR_TYPE dependent field.  Contains
1112  *                    the resource information for the NetBIOS name.
1113  *
1114  *   RESOURCE RECORD RR_TYPE field definitions:
1115  *
1116  *   Symbol      Value   Description:
1117  *
1118  *   A          0x0001   IP address Resource Record (See REDIRECT NAME
1119  *                       QUERY RESPONSE)
1120  *   NS         0x0002   Name Server Resource Record (See REDIRECT
1121  *                       NAME QUERY RESPONSE)
1122  *   NULL       0x000A   NULL Resource Record (See WAIT FOR
1123  *                       ACKNOWLEDGEMENT RESPONSE)
1124  *   NB         0x0020   NetBIOS general Name Service Resource Record
1125  *                       (See NB_FLAGS and NB_ADDRESS, below)
1126  *   NBSTAT     0x0021   NetBIOS NODE STATUS Resource Record (See NODE
1127  *                       STATUS RESPONSE)
1128  */
1129 
1130 #define	RR_TYPE_IP_ADDRESS_RESOURCE	0x0001
1131 #define	RR_TYPE_NAME_SERVER_RESOURCE	0x0002
1132 #define	RR_TYPE_NULL_RESOURCE		0x000A
1133 #define	RR_TYPE_NETBIOS_RESOURCE	0x0020
1134 #define	RR_TYPE_NETBIOS_STATUS		0x0021
1135 
1136 /*
1137  *
1138  *   RESOURCE RECORD RR_CLASS field definitions:
1139  *
1140  *   Symbol      Value   Description:
1141  *
1142  *   IN         0x0001   Internet class
1143  */
1144 #define	RR_CLASS_INTERNET_CLASS		0x0001
1145 
1146 /*
1147  *
1148  *   NB_FLAGS field of the RESOURCE RECORD RDATA field for RR_TYPE of
1149  *   "NB":
1150  *
1151  *                                             1   1   1   1   1   1
1152  *     0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
1153  *   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1154  *   | G |  ONT  |                RESERVED                           |
1155  *   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1156  *
1157  *   Symbol     Bit(s)   Description:
1158  *
1159  *   RESERVED     3-15   Reserved for future use.  Must be zero (0).
1160  *   ONT           1,2   Owner Node Type:
1161  *                          00 = B node
1162  *                          01 = P node
1163  *                          10 = M node
1164  *                          11 = Reserved for future use
1165  *                       For registration requests this is the
1166  *                       claimant's type.
1167  *                       For responses this is the actual owner's
1168  *                       type.
1169  *
1170  *   G               0   Group Name Flag.
1171  *                       If one (1) then the RR_NAME is a GROUP
1172  *                       NetBIOS name.
1173  *                       If zero (0) then the RR_NAME is a UNIQUE
1174  *                       NetBIOS name.
1175  *
1176  *   The NB_ADDRESS field of the RESOURCE RECORD RDATA field for
1177  *   RR_TYPE of "NB" is the IP address of the name's owner.
1178  *
1179  */
1180 #define	RR_FLAGS_NB_ONT_MASK		0x6000
1181 #define	RR_FLAGS_NB_ONT_B_NODE		0x0000
1182 #define	RR_FLAGS_NB_ONT_P_NODE		0x2000
1183 #define	RR_FLAGS_NB_ONT_M_NODE		0x4000
1184 #define	RR_FLAGS_NB_ONT_RESERVED	0x6000
1185 
1186 #define	RR_FLAGS_NB_GROUP_NAME		0x8000
1187 
1188 /*
1189  * smb_netbios_send_rcv
1190  *
1191  * This function sends the given NetBIOS packet to the given
1192  * address and get back the response. If send operation is not
1193  * successful, it's repeated 'retries' times.
1194  *
1195  * Returns:
1196  *		0		Unsuccessful send operation; no reply
1197  *		1		Got reply
1198  */
1199 static int
1200 smb_netbios_send_rcv(int bcast, struct addr_entry *destination,
1201 					struct name_packet *packet,
1202 					uint32_t retries, uint32_t timeout)
1203 {
1204 	uint32_t retry;
1205 	unsigned short	tid;
1206 	struct timespec st;
1207 	int	rc;
1208 
1209 	for (retry = 0; retry < retries; retry++) {
1210 		if ((destination->flags & ADDR_FLAG_VALID) == 0)
1211 			return (0);
1212 
1213 		tid = netbios_name_transcation_id++;
1214 		packet->name_trn_id = tid;
1215 		if (smb_send_name_service_packet(destination, packet) >= 0) {
1216 			rc = smb_netbios_process_response(tid, destination,
1217 			    packet, timeout);
1218 
1219 			if ((rc > 0) || (bcast == BROADCAST))
1220 				return (1);
1221 
1222 			if (rc != 0)
1223 				return (0);
1224 		}
1225 
1226 		st.tv_sec = 0;
1227 		st.tv_nsec = (timeout * 1000000);
1228 		(void) nanosleep(&st, 0);
1229 	}
1230 
1231 	return (0);
1232 }
1233 
1234 /*
1235  * 4.2.2.  NAME REGISTRATION REQUEST
1236  *
1237  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1238  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1239  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1240  *   |         NAME_TRN_ID           |0|  0x5  |0|0|1|0|0 0|B|  0x0  |
1241  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1242  *   |          0x0001               |           0x0000              |
1243  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1244  *   |          0x0000               |           0x0001              |
1245  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1246  *   |                                                               |
1247  *   /                         QUESTION_NAME                         /
1248  *   /                                                               /
1249  *   |                                                               |
1250  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1251  *   |           NB (0x0020)         |        IN (0x0001)            |
1252  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1253  *   |                                                               |
1254  *   /                            RR_NAME                            /
1255  *   /                                                               /
1256  *   |                                                               |
1257  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1258  *   |           NB (0x0020)         |         IN (0x0001)           |
1259  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1260  *   |                              TTL                              |
1261  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1262  *   |           0x0006              |          NB_FLAGS             |
1263  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1264  *   |                          NB_ADDRESS                           |
1265  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1266  *
1267  *   Since the RR_NAME is the same name as the QUESTION_NAME, the
1268  *   RR_NAME representation must use pointers to the QUESTION_NAME
1269  *   name's labels to guarantee the length of the datagram is less
1270  *   than the maximum 576 bytes.  See section above on name formats
1271  *   and also page 31 and 32 of RFC 883, Domain Names - Implementation
1272  *   and Specification, for a complete description of compressed name
1273  *   label pointers.
1274  */
1275 static int
1276 smb_send_name_registration_request(int bcast, struct name_question *question,
1277     struct resource_record *additional)
1278 {
1279 	int gotreply = 0;
1280 	uint32_t retries;
1281 	uint32_t timeout;
1282 	struct addr_entry *destination;
1283 	struct name_packet packet;
1284 	unsigned char type;
1285 	int i, addr_num, rc;
1286 
1287 	type = question->name->name[15];
1288 	if ((type != 0x00) && (type != 0x20)) {
1289 		syslog(LOG_ERR, "netbios: error trying to register"
1290 		    " non-local name");
1291 		smb_netbios_name_logf(question->name);
1292 		question->name->attributes &= ~NAME_ATTR_LOCAL;
1293 		return (-1);
1294 	}
1295 
1296 	if (bcast == BROADCAST) {
1297 		if (bcast_num == 0)
1298 			return (0);
1299 		destination = smb_bcast_list;
1300 		addr_num = bcast_num;
1301 		retries = BCAST_REQ_RETRY_COUNT;
1302 		timeout = BCAST_REQ_RETRY_TIMEOUT;
1303 		packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_BROADCAST;
1304 	} else {
1305 		if (nbns_num == 0)
1306 			return (0);
1307 		destination = smb_nbns;
1308 		addr_num = nbns_num;
1309 		retries = UCAST_REQ_RETRY_COUNT;
1310 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1311 		packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_UNICAST;
1312 	}
1313 
1314 	packet.qdcount = 1;	/* question entries */
1315 	packet.question = question;
1316 	packet.ancount = 0;	/* answer recs */
1317 	packet.answer = NULL;
1318 	packet.nscount = 0;	/* authority recs */
1319 	packet.authority = NULL;
1320 	packet.arcount = 1;	/* additional recs */
1321 	packet.additional = additional;
1322 
1323 	if (IS_UNIQUE(question->name->attributes) &&
1324 	    (is_multihome((char *)(question->name->name))))
1325 		packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST;
1326 
1327 	for (i = 0; i < addr_num; i++) {
1328 		/*
1329 		 * Only register with the Primary WINS server,
1330 		 * unless we got no reply.
1331 		 */
1332 		if ((bcast == UNICAST) && gotreply)
1333 			break;
1334 
1335 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1336 		    retries, timeout);
1337 		if (rc == 1)
1338 			gotreply = 1;
1339 	}
1340 
1341 	return (gotreply);
1342 }
1343 
1344 /*
1345  *
1346  * 4.2.4.  NAME REFRESH REQUEST
1347  *
1348  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1349  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1350  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1351  *   |         NAME_TRN_ID           |0|  0x8  |0|0|0|0|0 0|B|  0x0  |
1352  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1353  *   |          0x0001               |           0x0000              |
1354  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1355  *   |          0x0000               |           0x0001              |
1356  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1357  *   |                                                               |
1358  *   /                         QUESTION_NAME                         /
1359  *   /                                                               /
1360  *   |                                                               |
1361  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1362  *   |           NB (0x0020)         |        IN (0x0001)            |
1363  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1364  *   |                                                               |
1365  *   /                            RR_NAME                            /
1366  *   /                                                               /
1367  *   |                                                               |
1368  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1369  *   |           NB (0x0020)         |         IN (0x0001)           |
1370  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1371  *   |                              TTL                              |
1372  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1373  *   |           0x0006              |          NB_FLAGS             |
1374  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1375  *   |                          NB_ADDRESS                           |
1376  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1377  */
1378 /*ARGSUSED*/
1379 static int
1380 smb_send_name_refresh_request(int bcast, struct name_question *question,
1381     struct resource_record *additional, int force)
1382 {
1383 	int rc = 0;
1384 	int gotreply = 0;
1385 	uint32_t retries;
1386 	uint32_t timeout;
1387 	struct addr_entry *addr;
1388 	struct addr_entry *destination;
1389 	struct name_packet packet;
1390 	unsigned char type;
1391 	int i, addr_num, q_addrs = 0;
1392 
1393 	type = question->name->name[15];
1394 	if ((type != 0x00) && (type != 0x20)) {
1395 		syslog(LOG_ERR, "attempt to refresh non-local name");
1396 		smb_netbios_name_logf(question->name);
1397 		question->name->attributes &= ~NAME_ATTR_LOCAL;
1398 		return (-1);
1399 	}
1400 	switch (bcast) {
1401 	case BROADCAST :
1402 		if (bcast_num == 0)
1403 			return (-1);
1404 		destination = smb_bcast_list;
1405 		addr_num = bcast_num;
1406 		retries = BCAST_REQ_RETRY_COUNT;
1407 		timeout = BCAST_REQ_RETRY_TIMEOUT;
1408 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_BROADCAST;
1409 		break;
1410 
1411 	case UNICAST :
1412 		if (nbns_num == 0)
1413 			return (-1);
1414 		destination = smb_nbns;
1415 		addr_num = nbns_num;
1416 		retries = UCAST_REQ_RETRY_COUNT;
1417 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1418 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST;
1419 		break;
1420 
1421 	default:
1422 		destination = &question->name->addr_list;
1423 		/*
1424 		 * the value of addr_num is irrelvant here, because
1425 		 * the code is going to do special_process so it doesn't
1426 		 * need the addr_num. We set a value here just to avoid
1427 		 * compiler warning.
1428 		 */
1429 		addr_num = 0;
1430 		retries = UCAST_REQ_RETRY_COUNT;
1431 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1432 		packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST;
1433 		q_addrs = 1;
1434 		break;
1435 	}
1436 
1437 	if (IS_UNIQUE(question->name->attributes) &&
1438 	    (is_multihome((char *)(question->name->name))))
1439 		packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST;
1440 
1441 	packet.qdcount = 1;	/* question entries */
1442 	packet.question = question;
1443 	packet.ancount = 0;	/* answer recs */
1444 	packet.answer = NULL;
1445 	packet.nscount = 0;	/* authority recs */
1446 	packet.authority = NULL;
1447 	packet.arcount = 1;	/* additional recs */
1448 	packet.additional = additional;
1449 
1450 	if (q_addrs)
1451 		goto special_process;
1452 
1453 	for (i = 0; i < addr_num; i++) {
1454 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1455 		    retries, timeout);
1456 		if (rc == 1)
1457 			gotreply = 1;
1458 	}
1459 
1460 	return (gotreply);
1461 
1462 special_process:
1463 	addr = destination;
1464 	do {
1465 		rc = smb_netbios_send_rcv(bcast, addr, &packet,
1466 		    retries, timeout);
1467 		if (rc == 1)
1468 			gotreply = 1;
1469 		addr = addr->forw;
1470 	} while (addr != destination);
1471 
1472 	return (gotreply);
1473 }
1474 
1475 /*
1476  * 4.2.5.  POSITIVE NAME REGISTRATION RESPONSE
1477  *
1478  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1479  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1480  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1481  *   |         NAME_TRN_ID           |1|  0x5  |1|0|1|1|0 0|0|  0x0  |
1482  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1483  *   |          0x0000               |           0x0001              |
1484  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1485  *   |          0x0000               |           0x0000              |
1486  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1487  *   |                                                               |
1488  *   /                            RR_NAME                            /
1489  *   /                                                               /
1490  *   |                                                               |
1491  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1492  *   |           NB (0x0020)         |         IN (0x0001)           |
1493  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1494  *   |                              TTL                              |
1495  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1496  *   |           0x0006              |          NB_FLAGS             |
1497  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1498  *   |                          NB_ADDRESS                           |
1499  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1500  *
1501  *
1502  *
1503  * 4.2.6.  NEGATIVE NAME REGISTRATION RESPONSE
1504  *
1505  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1506  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1507  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1508  *   |         NAME_TRN_ID           |1|  0x5  |1|0|1|1|0 0|0| RCODE |
1509  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1510  *   |          0x0000               |           0x0001              |
1511  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1512  *   |          0x0000               |           0x0000              |
1513  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1514  *   |                                                               |
1515  *   /                            RR_NAME                            /
1516  *   /                                                               /
1517  *   |                                                               |
1518  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1519  *   |           NB (0x0020)         |         IN (0x0001)           |
1520  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1521  *   |                              TTL                              |
1522  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1523  *   |           0x0006              |          NB_FLAGS             |
1524  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1525  *   |                          NB_ADDRESS                           |
1526  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1527  *
1528  *   RCODE field values:
1529  *
1530  *   Symbol      Value   Description:
1531  *
1532  *   FMT_ERR       0x1   Format Error.  Request was invalidly
1533  *                       formatted.
1534  *   SRV_ERR       0x2   Server failure.  Problem with NAME, cannot
1535  *                       process name.
1536  *   IMP_ERR       0x4   Unsupported request error.  Allowable only
1537  *                       for challenging NAME when gets an Update type
1538  *                       registration request.
1539  *   RFS_ERR       0x5   Refused error.  For policy reasons server
1540  *                       will not register this name from this host.
1541  *   ACT_ERR       0x6   Active error.  Name is owned by another node.
1542  *   CFT_ERR       0x7   Name in conflict error.  A UNIQUE name is
1543  *                       owned by more than one node.
1544  */
1545 static int
1546 smb_send_name_registration_response(struct addr_entry *addr,
1547     struct name_packet *original_packet, unsigned short rcode)
1548 {
1549 	struct name_packet	packet;
1550 	struct resource_record	answer;
1551 
1552 	bzero(&packet, sizeof (struct name_packet));
1553 	bzero(&answer, sizeof (struct resource_record));
1554 
1555 	packet.name_trn_id = original_packet->name_trn_id;
1556 	packet.info = NAME_REGISTRATION_RESPONSE | NAME_NM_FLAGS_RA |
1557 	    (rcode & NAME_RCODE_MASK);
1558 	packet.qdcount = 0;	/* question entries */
1559 	packet.question = NULL;
1560 	packet.ancount = 1;	/* answer recs */
1561 	packet.answer = &answer;
1562 	packet.nscount = 0;	/* authority recs */
1563 	packet.authority = NULL;
1564 	packet.arcount = 0;	/* additional recs */
1565 	packet.additional = NULL;
1566 
1567 	answer.name = original_packet->question->name;
1568 	answer.rr_type = NAME_QUESTION_TYPE_NB;
1569 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1570 	answer.ttl = original_packet->additional->ttl;
1571 	answer.rdlength = original_packet->additional->rdlength;
1572 	answer.rdata = original_packet->additional->rdata;
1573 
1574 	return (smb_send_name_service_packet(addr, &packet));
1575 }
1576 
1577 /*
1578  * 4.2.9.  NAME RELEASE REQUEST & DEMAND
1579  *
1580  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1581  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1582  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1583  *   |         NAME_TRN_ID           |0|  0x6  |0|0|0|0|0 0|B|  0x0  |
1584  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1585  *   |          0x0001               |           0x0000              |
1586  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1587  *   |          0x0000               |           0x0001              |
1588  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1589  *   |                                                               |
1590  *   /                         QUESTION_NAME                         /
1591  *   /                                                               /
1592  *   |                                                               |
1593  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1594  *   |           NB (0x0020)         |        IN (0x0001)            |
1595  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1596  *   |                                                               |
1597  *   /                            RR_NAME                            /
1598  *   /                                                               /
1599  *   |                                                               |
1600  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1601  *   |           NB (0x0020)         |         IN (0x0001)           |
1602  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1603  *   |                          0x00000000                           |
1604  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1605  *   |           0x0006              |          NB_FLAGS             |
1606  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1607  *   |                          NB_ADDRESS                           |
1608  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1609  *
1610  *   Since the RR_NAME is the same name as the QUESTION_NAME, the
1611  *   RR_NAME representation must use label string pointers to the
1612  *   QUESTION_NAME labels to guarantee the length of the datagram is
1613  *   less than the maximum 576 bytes.  This is the same condition as
1614  *   with the NAME REGISTRATION REQUEST.
1615  */
1616 static int
1617 smb_send_name_release_request_and_demand(int bcast,
1618     struct name_question *question, struct resource_record *additional)
1619 {
1620 	int gotreply = 0;
1621 	int i, rc;
1622 	int addr_num;
1623 	uint32_t retries;
1624 	uint32_t timeout;
1625 	struct addr_entry *destination;
1626 	struct name_packet packet;
1627 
1628 	if (bcast == BROADCAST) {
1629 		if (bcast_num == 0)
1630 			return (-1);
1631 		destination = smb_bcast_list;
1632 		addr_num = bcast_num;
1633 		retries = 1; /* BCAST_REQ_RETRY_COUNT */
1634 		timeout = 100; /* BCAST_REQ_RETRY_TIMEOUT */
1635 		packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_BROADCAST;
1636 	} else {
1637 		if (nbns_num == 0)
1638 			return (-1);
1639 		destination = smb_nbns;
1640 		addr_num = nbns_num;
1641 		retries = 1; /* UCAST_REQ_RETRY_COUNT */
1642 		timeout = 100; /* UCAST_REQ_RETRY_TIMEOUT */
1643 		packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_UNICAST;
1644 	}
1645 
1646 	packet.qdcount = 1;	/* question entries */
1647 	packet.question = question;
1648 	packet.ancount = 0;	/* answer recs */
1649 	packet.answer = NULL;
1650 	packet.nscount = 0;	/* authority recs */
1651 	packet.authority = NULL;
1652 	packet.arcount = 1;	/* additional recs */
1653 	packet.additional = additional;
1654 
1655 	for (i = 0; i < addr_num; i++) {
1656 		rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1657 		    retries, timeout);
1658 		if (rc == 1)
1659 			gotreply = 1;
1660 	}
1661 
1662 	return (gotreply);
1663 }
1664 
1665 /*
1666  * 4.2.10.  POSITIVE NAME RELEASE RESPONSE
1667  *
1668  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1669  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1670  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1671  *   |         NAME_TRN_ID           |1|  0x6  |1|0|0|0|0 0|0|  0x0  |
1672  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1673  *   |          0x0000               |           0x0001              |
1674  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1675  *   |          0x0000               |           0x0000              |
1676  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1677  *   |                                                               |
1678  *   /                            RR_NAME                            /
1679  *   /                                                               /
1680  *   |                                                               |
1681  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1682  *   |           NB (0x0020)         |         IN (0x0001)           |
1683  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1684  *   |                              TTL                              |
1685  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1686  *   |           0x0006              |          NB_FLAGS             |
1687  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1688  *   |                          NB_ADDRESS                           |
1689  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1690  *
1691  *
1692  * 4.2.11.  NEGATIVE NAME RELEASE RESPONSE
1693  *
1694  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1695  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1696  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1697  *   |         NAME_TRN_ID           |1|  0x6  |1|0|0|0|0 0|0| RCODE |
1698  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1699  *   |          0x0000               |           0x0001              |
1700  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1701  *   |          0x0000               |           0x0000              |
1702  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1703  *   |                                                               |
1704  *   /                            RR_NAME                            /
1705  *   /                                                               /
1706  *   |                                                               |
1707  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1708  *   |           NB (0x0020)         |         IN (0x0001)           |
1709  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1710  *   |                              TTL                              |
1711  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1712  *   |           0x0006              |          NB_FLAGS             |
1713  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1714  *   |                          NB_ADDRESS                           |
1715  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1716  *
1717  *   RCODE field values:
1718  *
1719  *   Symbol      Value   Description:
1720  *
1721  *   FMT_ERR       0x1   Format Error.  Request was invalidly
1722  *                       formatted.
1723  *
1724  *   SRV_ERR       0x2   Server failure.  Problem with NAME, cannot
1725  *                       process name.
1726  *
1727  *   RFS_ERR       0x5   Refused error.  For policy reasons server
1728  *                       will not release this name from this host.
1729  *
1730  *   ACT_ERR       0x6   Active error.  Name is owned by another node.
1731  *                       Only that node may release it.  A NetBIOS
1732  *                       Name Server can optionally allow a node to
1733  *                       release a name it does not own.  This would
1734  *                       facilitate detection of inactive names for
1735  *                       nodes that went down silently.
1736  */
1737 static int
1738 /* LINTED - E_STATIC_UNUSED */
1739 smb_send_name_release_response(struct addr_entry *addr,
1740     struct name_packet *original_packet, unsigned short rcode)
1741 {
1742 	struct name_packet	packet;
1743 	struct resource_record	answer;
1744 
1745 	bzero(&packet, sizeof (struct name_packet));
1746 	bzero(&answer, sizeof (struct resource_record));
1747 
1748 	packet.name_trn_id = original_packet->name_trn_id;
1749 	packet.info = NAME_RELEASE_RESPONSE | (rcode & NAME_RCODE_MASK);
1750 	packet.qdcount = 0;	/* question entries */
1751 	packet.question = NULL;
1752 	packet.ancount = 1;	/* answer recs */
1753 	packet.answer = &answer;
1754 	packet.nscount = 0;	/* authority recs */
1755 	packet.authority = NULL;
1756 	packet.arcount = 0;	/* additional recs */
1757 	packet.additional = NULL;
1758 
1759 	answer.name = original_packet->question->name;
1760 	answer.rr_type = NAME_QUESTION_TYPE_NB;
1761 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1762 	answer.ttl = original_packet->additional->ttl;
1763 	answer.rdlength = original_packet->additional->rdlength;
1764 	answer.rdata = original_packet->additional->rdata;
1765 
1766 	return (smb_send_name_service_packet(addr, &packet));
1767 }
1768 
1769 /*
1770  *
1771  * 4.2.12.  NAME QUERY REQUEST
1772  *
1773  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1774  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1775  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1776  *   |         NAME_TRN_ID           |0|  0x0  |0|0|1|0|0 0|B|  0x0  |
1777  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1778  *   |          0x0001               |           0x0000              |
1779  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1780  *   |          0x0000               |           0x0000              |
1781  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1782  *   |                                                               |
1783  *   /                         QUESTION_NAME                         /
1784  *   /                                                               /
1785  *   |                                                               |
1786  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1787  *   |           NB (0x0020)         |        IN (0x0001)            |
1788  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1789  */
1790 static int
1791 smb_send_name_query_request(int bcast, struct name_question *question)
1792 {
1793 	int			rc = 0;
1794 	uint32_t		retry, retries;
1795 	uint32_t		timeout;
1796 	unsigned short		tid;
1797 	struct addr_entry 	*destination;
1798 	struct name_packet	packet;
1799 	int 			i, addr_num;
1800 	struct timespec 	st;
1801 
1802 	if (bcast == BROADCAST) {
1803 		if (bcast_num == 0)
1804 			return (-1);
1805 		destination = smb_bcast_list;
1806 		addr_num = bcast_num;
1807 		retries = BCAST_REQ_RETRY_COUNT;
1808 		timeout = BCAST_REQ_RETRY_TIMEOUT;
1809 		packet.info = NAME_QUERY_REQUEST | NM_FLAGS_BROADCAST;
1810 	} else {
1811 		if (nbns_num == 0)
1812 			return (-1);
1813 		destination = smb_nbns;
1814 		addr_num = nbns_num;
1815 		retries = UCAST_REQ_RETRY_COUNT;
1816 		timeout = UCAST_REQ_RETRY_TIMEOUT;
1817 		packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST;
1818 	}
1819 	packet.qdcount = 1;	/* question entries */
1820 	packet.question = question;
1821 	packet.ancount = 0;	/* answer recs */
1822 	packet.answer = NULL;
1823 	packet.nscount = 0;	/* authority recs */
1824 	packet.authority = NULL;
1825 	packet.arcount = 0;	/* additional recs */
1826 	packet.additional = NULL;
1827 
1828 	for (i = 0; i < addr_num; i++) {
1829 		for (retry = 0; retry < retries; retry++) {
1830 			if ((destination->flags & ADDR_FLAG_VALID) == 0)
1831 				break;
1832 			tid = netbios_name_transcation_id++;
1833 			packet.name_trn_id = tid;
1834 
1835 			if (smb_send_name_service_packet(&destination[i],
1836 			    &packet) >= 0) {
1837 				if ((rc = smb_netbios_process_response(tid,
1838 				    &destination[i],
1839 				    &packet, timeout)) != 0)
1840 					break;
1841 			}
1842 			st.tv_sec = 0;
1843 			st.tv_nsec = (timeout * 1000000);
1844 			(void) nanosleep(&st, 0);
1845 		}
1846 	}
1847 
1848 	return (rc);
1849 }
1850 
1851 
1852 /*
1853  *
1854  * 4.2.13.  POSITIVE NAME QUERY RESPONSE
1855  *
1856  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1857  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1858  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1859  *   |         NAME_TRN_ID           |1|  0x0  |1|T|1|?|0 0|0|  0x0  |
1860  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1861  *   |          0x0000               |           0x0001              |
1862  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1863  *   |          0x0000               |           0x0000              |
1864  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1865  *   |                                                               |
1866  *   /                            RR_NAME                            /
1867  *   /                                                               /
1868  *   |                                                               |
1869  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1870  *   |           NB (0x0020)         |         IN (0x0001)           |
1871  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1872  *   |                              TTL                              |
1873  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1874  *   |           RDLENGTH            |                               |
1875  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
1876  *   |                                                               |
1877  *   /                       ADDR_ENTRY ARRAY                        /
1878  *   /                                                               /
1879  *   |                                                               |
1880  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1881  *
1882  *   The ADDR_ENTRY ARRAY a sequence of zero or more ADDR_ENTRY
1883  *   records.  Each ADDR_ENTRY record represents an owner of a name.
1884  *   For group names there may be multiple entries.  However, the list
1885  *   may be incomplete due to packet size limitations.  Bit 22, "T",
1886  *   will be set to indicate truncated data.
1887  *
1888  *   Each ADDR_ENTRY has the following format:
1889  *
1890  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1891  *   |          NB_FLAGS             |          NB_ADDRESS           |
1892  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1893  *   |   NB_ADDRESS (continued)      |
1894  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1895  *
1896  *
1897  *
1898  * 4.2.14.  NEGATIVE NAME QUERY RESPONSE
1899  *
1900  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1901  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1902  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1903  *   |         NAME_TRN_ID           |1|  0x0  |1|0|1|?|0 0|0| RCODE |
1904  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1905  *   |          0x0000               |           0x0000              |
1906  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1907  *   |          0x0000               |           0x0000              |
1908  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1909  *   |                                                               |
1910  *   /                            RR_NAME                            /
1911  *   /                                                               /
1912  *   |                                                               |
1913  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1914  *   |           NULL (0x000A)       |         IN (0x0001)           |
1915  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1916  *   |                          0x00000000                           |
1917  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1918  *   |           0x0000              |
1919  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1920  *
1921  *   RCODE field values:
1922  *
1923  *   Symbol      Value   Description
1924  *
1925  *   FMT_ERR       0x1   Format Error.  Request was invalidly
1926  *                       formatted.
1927  *   SRV_ERR       0x2   Server failure.  Problem with NAME, cannot
1928  *                       process name.
1929  *   NAM_ERR       0x3   Name Error.  The name requested does not
1930  *                       exist.
1931  *   IMP_ERR       0x4   Unsupported request error.  Allowable only
1932  *                       for challenging NAME when gets an Update type
1933  *                       registration request.
1934  *   RFS_ERR       0x5   Refused error.  For policy reasons server
1935  *                       will not register this name from this host.
1936  */
1937 static int
1938 smb_send_name_query_response(struct addr_entry *addr,
1939     struct name_packet *original_packet, struct name_entry *entry,
1940     unsigned short rcode)
1941 {
1942 	struct addr_entry 	*raddr;
1943 	struct name_packet	packet;
1944 	struct resource_record	answer;
1945 	unsigned short		attr;
1946 	unsigned char 		data[MAX_DATAGRAM_LENGTH];
1947 	unsigned char 		*scan = data;
1948 
1949 	packet.name_trn_id = original_packet->name_trn_id;
1950 	packet.info = NAME_QUERY_RESPONSE | (rcode & NAME_RCODE_MASK);
1951 	packet.qdcount = 0;	/* question entries */
1952 	packet.question = NULL;
1953 	packet.ancount = 1;	/* answer recs */
1954 	packet.answer = &answer;
1955 	packet.nscount = 0;	/* authority recs */
1956 	packet.authority = NULL;
1957 	packet.arcount = 0;	/* additional recs */
1958 	packet.additional = NULL;
1959 
1960 	answer.name = entry;
1961 	answer.rr_class = NAME_QUESTION_CLASS_IN;
1962 	answer.ttl = entry->addr_list.ttl;
1963 	answer.rdata = data;
1964 	if (rcode) {
1965 		answer.rr_type = NAME_RR_TYPE_NULL;
1966 		answer.rdlength = 0;
1967 		bzero(data, 6);
1968 	} else {
1969 		answer.rdlength = 0;
1970 		answer.rr_type = NAME_QUESTION_TYPE_NB;
1971 		raddr = &entry->addr_list;
1972 		scan = data;
1973 		do {
1974 			attr = entry->attributes & (NAME_ATTR_GROUP |
1975 			    NAME_ATTR_OWNER_NODE_TYPE);
1976 
1977 			BE_OUT16(scan, attr); scan += 2;
1978 
1979 			*scan++ = raddr->sin.sin_addr.s_addr;
1980 			*scan++ = raddr->sin.sin_addr.s_addr >> 8;
1981 			*scan++ = raddr->sin.sin_addr.s_addr >> 16;
1982 			*scan++ = raddr->sin.sin_addr.s_addr >> 24;
1983 
1984 			answer.rdlength += 6;
1985 			raddr = raddr->forw;
1986 		} while (raddr != &entry->addr_list);
1987 	}
1988 
1989 	return (smb_send_name_service_packet(addr, &packet));
1990 }
1991 
1992 /*
1993  * 4.2.18.  NODE STATUS RESPONSE
1994  *
1995  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1996  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1997  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1998  *   |         NAME_TRN_ID           |1|  0x0  |1|0|0|0|0 0|0|  0x0  |
1999  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2000  *   |          0x0000               |           0x0001              |
2001  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2002  *   |          0x0000               |           0x0000              |
2003  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2004  *   |                                                               |
2005  *   /                            RR_NAME                            /
2006  *   |                                                               |
2007  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2008  *   |        NBSTAT (0x0021)        |         IN (0x0001)           |
2009  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2010  *   |                          0x00000000                           |
2011  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2012  *   |          RDLENGTH             |   NUM_NAMES   |               |
2013  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
2014  *   |                                                               |
2015  *   +                                                               +
2016  *   /                         NODE_NAME ARRAY                       /
2017  *   +                                                               +
2018  *   |                                                               |
2019  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2020  *   |                                                               |
2021  *   +                                                               +
2022  *   /                           STATISTICS                          /
2023  *   +                                                               +
2024  *   |                                                               |
2025  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2026  *
2027  *   The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
2028  *   of NODE_NAME records.  Each NODE_NAME entry represents an active
2029  *   name in the same NetBIOS scope as the requesting name in the
2030  *   local name table of the responder.  RR_NAME is the requesting
2031  *   name.
2032  *
2033  *   NODE_NAME Entry:
2034  *
2035  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
2036  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2037  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2038  *   |                                                               |
2039  *   +---                                                         ---+
2040  *   |                                                               |
2041  *   +---                    NETBIOS FORMAT NAME                  ---+
2042  *   |                                                               |
2043  *   +---                                                         ---+
2044  *   |                                                               |
2045  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2046  *   |         NAME_FLAGS            |
2047  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2048  *
2049  *   The NAME_FLAGS field:
2050  *
2051  *                                             1   1   1   1   1   1
2052  *     0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
2053  *   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2054  *   | G |  ONT  |DRG|CNF|ACT|PRM|          RESERVED                 |
2055  *   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2056  *
2057  *   The NAME_FLAGS field is defined as:
2058  *
2059  *   Symbol     Bit(s)   Description:
2060  *
2061  *   RESERVED     7-15   Reserved for future use.  Must be zero (0).
2062  *   PRM             6   Permanent Name Flag.  If one (1) then entry
2063  *                       is for the permanent node name.  Flag is zero
2064  *                       (0) for all other names.
2065  *   ACT             5   Active Name Flag.  All entries have this flag
2066  *                       set to one (1).
2067  *   CNF             4   Conflict Flag.  If one (1) then name on this
2068  *                       node is in conflict.
2069  *   DRG             3   Deregister Flag.  If one (1) then this name
2070  *                       is in the process of being deleted.
2071  *   ONT           1,2   Owner Node Type:
2072  *                          00 = B node
2073  *                          01 = P node
2074  *                          10 = M node
2075  *                          11 = Reserved for future use
2076  *   G               0   Group Name Flag.
2077  *                       If one (1) then the name is a GROUP NetBIOS
2078  *                       name.
2079  *                       If zero (0) then it is a UNIQUE NetBIOS name.
2080  */
2081 #define	NAME_FLAGS_PERMANENT_NAME	0x0200
2082 #define	NAME_FLAGS_ACTIVE_NAME		0x0400
2083 #define	NAME_FLAGS_CONFLICT		0x0800
2084 #define	NAME_FLAGS_DEREGISTER		0x1000
2085 #define	NAME_FLAGS_ONT_MASK		0x6000
2086 #define	NAME_FLAGS_ONT_B_NODE		0x0000
2087 #define	NAME_FLAGS_ONT_P_NODE		0x2000
2088 #define	NAME_FLAGS_ONT_M_NODE		0x4000
2089 #define	NAME_FLAGS_ONT_RESERVED		0x6000
2090 #define	NAME_FLAGS_GROUP_NAME		0x8000
2091 
2092 
2093 /*
2094  *   STATISTICS Field of the NODE STATUS RESPONSE:
2095  *
2096  *                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
2097  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2098  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2099  *   |               UNIT_ID (Unique unit ID)                        |
2100  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2101  *   |       UNIT_ID,continued       |    JUMPERS    |  TEST_RESULT  |
2102  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2103  *   |       VERSION_NUMBER          |      PERIOD_OF_STATISTICS     |
2104  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2105  *   |       NUMBER_OF_CRCs          |     NUMBER_ALIGNMENT_ERRORS   |
2106  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2107  *   |       NUMBER_OF_COLLISIONS    |        NUMBER_SEND_ABORTS     |
2108  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2109  *   |                       NUMBER_GOOD_SENDS                       |
2110  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2111  *   |                      NUMBER_GOOD_RECEIVES                     |
2112  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2113  *   |       NUMBER_RETRANSMITS      | NUMBER_NO_RESOURCE_CONDITIONS |
2114  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2115  *   |  NUMBER_FREE_COMMAND_BLOCKS   |  TOTAL_NUMBER_COMMAND_BLOCKS  |
2116  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2117  *   |MAX_TOTAL_NUMBER_COMMAND_BLOCKS|    NUMBER_PENDING_SESSIONS    |
2118  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2119  *   |  MAX_NUMBER_PENDING_SESSIONS  |  MAX_TOTAL_SESSIONS_POSSIBLE  |
2120  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2121  *   |   SESSION_DATA_PACKET_SIZE    |
2122  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2123  */
2124 #define	MAX_NETBIOS_REPLY_DATA_SIZE	500
2125 
2126 static int
2127 smb_send_node_status_response(struct addr_entry *addr,
2128     struct name_packet *original_packet)
2129 {
2130 	uint32_t		net_ipaddr;
2131 	int64_t			max_connections;
2132 	struct arpreq 		arpreq;
2133 	struct name_packet	packet;
2134 	struct resource_record	answer;
2135 	unsigned char 		*scan;
2136 	unsigned char 		*scan_end;
2137 	unsigned char		data[MAX_NETBIOS_REPLY_DATA_SIZE];
2138 	boolean_t scan_done = B_FALSE;
2139 
2140 	bzero(&packet, sizeof (struct name_packet));
2141 	bzero(&answer, sizeof (struct resource_record));
2142 
2143 	packet.name_trn_id = original_packet->name_trn_id;
2144 	packet.info = NODE_STATUS_RESPONSE;
2145 	packet.qdcount = 0;	/* question entries */
2146 	packet.question = NULL;
2147 	packet.ancount = 1;	/* answer recs */
2148 	packet.answer = &answer;
2149 	packet.nscount = 0;	/* authority recs */
2150 	packet.authority = NULL;
2151 	packet.arcount = 0;	/* additional recs */
2152 	packet.additional = NULL;
2153 
2154 	answer.name = original_packet->question->name;
2155 	answer.rr_type = NAME_RR_TYPE_NBSTAT;
2156 	answer.rr_class = NAME_QUESTION_CLASS_IN;
2157 	answer.ttl = 0;
2158 	answer.rdata = data;
2159 
2160 	scan = smb_netbios_cache_status(data, MAX_NETBIOS_REPLY_DATA_SIZE,
2161 	    original_packet->question->name->scope);
2162 
2163 	scan_end = data + MAX_NETBIOS_REPLY_DATA_SIZE;
2164 
2165 	if (smb_nic_exists(addr->sin.sin_addr.s_addr, B_TRUE))
2166 		net_ipaddr = addr->sin.sin_addr.s_addr;
2167 	else
2168 		net_ipaddr = 0;
2169 
2170 	(void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &max_connections);
2171 
2172 	while (!scan_done) {
2173 		if ((scan + 6) >= scan_end) {
2174 			packet.info |= NAME_NM_FLAGS_TC;
2175 			break;
2176 		}
2177 
2178 		if (net_ipaddr != 0) {
2179 			struct sockaddr_in *s_in;
2180 			int s;
2181 
2182 			s = socket(AF_INET, SOCK_DGRAM, 0);
2183 			/* LINTED - E_BAD_PTR_CAST_ALIGN */
2184 			s_in = (struct sockaddr_in *)&arpreq.arp_pa;
2185 			s_in->sin_family = AF_INET;
2186 			s_in->sin_addr.s_addr = net_ipaddr;
2187 			if (ioctl(s, SIOCGARP, (caddr_t)&arpreq) < 0) {
2188 				bzero(scan, 6);
2189 			} else {
2190 				bcopy(&arpreq.arp_ha.sa_data, scan, 6);
2191 			}
2192 			(void) close(s);
2193 		} else {
2194 			bzero(scan, 6);
2195 		}
2196 		scan += 6;
2197 
2198 		if ((scan + 26) >= scan_end) {
2199 			packet.info |= NAME_NM_FLAGS_TC;
2200 			break;
2201 		}
2202 		bzero(scan, 26);
2203 		scan += 26;
2204 
2205 		if ((scan + 2) >= scan_end) {
2206 			packet.info |= NAME_NM_FLAGS_TC;
2207 			break;
2208 		}
2209 		BE_OUT16(scan, 0); scan += 2;
2210 
2211 		if ((scan + 2) >= scan_end) {
2212 			packet.info |= NAME_NM_FLAGS_TC;
2213 			break;
2214 		}
2215 		BE_OUT16(scan, 0); scan += 2;
2216 
2217 		if ((scan + 2) >= scan_end) {
2218 			packet.info |= NAME_NM_FLAGS_TC;
2219 			break;
2220 		}
2221 		BE_OUT16(scan, 0); scan += 2;
2222 
2223 		if ((scan + 2) >= scan_end) {
2224 			packet.info |= NAME_NM_FLAGS_TC;
2225 			break;
2226 		}
2227 		BE_OUT16(scan, 0); scan += 2;
2228 
2229 		if ((scan + 2) >= scan_end) {
2230 			packet.info |= NAME_NM_FLAGS_TC;
2231 			break;
2232 		}
2233 		BE_OUT16(scan, 0); scan += 2;
2234 
2235 		if ((scan + 2) >= scan_end) {
2236 			packet.info |= NAME_NM_FLAGS_TC;
2237 			break;
2238 		}
2239 		BE_OUT16(scan, 0); scan += 2;
2240 
2241 		if ((scan + 2) >= scan_end) {
2242 			packet.info |= NAME_NM_FLAGS_TC;
2243 			break;
2244 		}
2245 		BE_OUT16(scan, 0); scan += 2;
2246 
2247 		if ((scan + 2) >= scan_end) {
2248 			packet.info |= NAME_NM_FLAGS_TC;
2249 			break;
2250 		}
2251 		BE_OUT16(scan, max_connections); scan += 2;
2252 
2253 		if ((scan + 2) >= scan_end) {
2254 			packet.info |= NAME_NM_FLAGS_TC;
2255 			break;
2256 		}
2257 
2258 		BE_OUT16(scan, 0); scan += 2;
2259 
2260 		scan_done = B_TRUE;
2261 	}
2262 	answer.rdlength = scan - data;
2263 	return (smb_send_name_service_packet(addr, &packet));
2264 }
2265 
2266 /*
2267  *
2268  * 5.1.  NAME SERVICE PROTOCOLS
2269  *
2270  *   A REQUEST packet is always sent to the well known UDP port -
2271  *   NAME_SERVICE_UDP_PORT.  The destination address is normally
2272  *   either the IP broadcast address or the address of the NAME - the
2273  *   address of the NAME server it set up at initialization time.  In
2274  *   rare cases, a request packet will be sent to an end node, e.g.  a
2275  *   NAME QUERY REQUEST sent to "challenge" a node.
2276  *
2277  *   A RESPONSE packet is always sent to the source UDP port and
2278  *   source IP address of the request packet.
2279  *
2280  *   A DEMAND packet must always be sent to the well known UDP port -
2281  *   NAME_SERVICE_UDP_PORT.  There is no restriction on the target IP
2282  *   address.
2283  *
2284  *   Terms used in this section:
2285  *
2286  *   tid -            Transaction ID.  This is a value composed from
2287  *                    the requestor's IP address and a unique 16 bit
2288  *                    value generated by the originator of the
2289  *                    transaction.
2290  */
2291 
2292 
2293 /*
2294  *
2295  * 5.1.1.  B-NODE ACTIVITY
2296  *
2297  * 5.1.1.1.  B-NODE ADD NAME
2298  *
2299  *   PROCEDURE add_name(name)
2300  *
2301  *   (*
2302  *    * Host initiated processing for a B node
2303  *    *)
2304  *   BEGIN
2305  *
2306  *        REPEAT
2307  *
2308  *             (* build name service packet *)
2309  *
2310  *             ONT = B_NODE; (* broadcast node *)
2311  *             G = UNIQUE;   (* unique name *)
2312  *             TTL = 0;
2313  *
2314  *             broadcast NAME REGISTRATION REQUEST packet;
2315  *
2316  *             (*
2317  *              * remote node(s) will send response packet
2318  *              * if applicable
2319  *              *)
2320  *             pause(BCAST_REQ_RETRY_TIMEOUT);
2321  *
2322  *        UNTIL response packet is received or
2323  *             retransmit count has been exceeded
2324  *
2325  *        IF no response packet was received THEN
2326  *        BEGIN (* no response *)
2327  *             (*
2328  *              * Build packet
2329  *              *)
2330  *
2331  *             ONT = B_NODE; (* broadcast node *)
2332  *             G = UNIQUE;   (* unique name *)
2333  *             TTL = 0;
2334  *
2335  *             (*
2336  *              * Let other nodes known you have the name
2337  *              *)
2338  *
2339  *             broadcast NAME UPDATE REQUEST packet;
2340  *             (* name can be added to local name table *)
2341  *             return success;
2342  *        END (* no response *)
2343  *        ELSE
2344  *        BEGIN (* got response *)
2345  *
2346  *             (*
2347  *              * Match return transaction id
2348  *              * against tid sent in request
2349  *              *)
2350  *
2351  *            IF NOT response tid = request tid THEN
2352  *            BEGIN
2353  *             ignore response packet;
2354  *            END
2355  *            ELSE
2356  *            CASE packet type OF
2357  *
2358  *            NEGATIVE NAME REGISTRATION RESPONSE:
2359  *
2360  *                 return failure; (* name cannot be added *)
2361  *
2362  *            POSITIVE NAME REGISTRATION RESPONSE:
2363  *            END-NODE CHALLENGE NAME REGISTRATION RESPONSE:
2364  *
2365  *                 (*
2366  *                  * B nodes should normally not get this
2367  *                  * response.
2368  *                  *)
2369  *
2370  *                  ignore packet;
2371  *            END (* case *);
2372  *        END (* got response *)
2373  *   END (* procedure *)
2374  *
2375  *
2376  *
2377  * 5.1.1.2.  B-NODE ADD_GROUP NAME
2378  *
2379  *   PROCEDURE add_group_name(name)
2380  *
2381  *   (*
2382  *    * Host initiated processing for a B node
2383  *    *)
2384  *
2385  *   BEGIN
2386  *        (*
2387  *         * same as for a unique name with the
2388  *         * exception that the group bit (G) must
2389  *         * be set in the request packets.
2390  *         *)
2391  *
2392  *        ...
2393  *        G = GROUP;
2394  *        ...
2395  *        ...
2396  *
2397  *        (*
2398  *         * broadcast request ...
2399  *         *)
2400  *
2401  *
2402  *   END
2403  */
2404 static int
2405 smb_name_Bnode_add_name(struct name_entry *name)
2406 {
2407 	struct name_question		question;
2408 	struct resource_record		additional;
2409 	unsigned char 			data[8];
2410 	unsigned short			attr;
2411 	struct addr_entry *addr;
2412 	int rc = 0;
2413 
2414 	addr = &name->addr_list;
2415 
2416 	do {
2417 		/* build name service packet */
2418 		question.name = name;
2419 		/*
2420 		 * question.name->attributes |= NAME_NB_FLAGS_ONT_B;
2421 		 * This is commented because NAME_NB_FLAGS_ONT_B is 0
2422 		 */
2423 		question.question_type = NAME_QUESTION_TYPE_NB;
2424 		question.question_class = NAME_QUESTION_CLASS_IN;
2425 
2426 		additional.name = name;
2427 		additional.rr_class = NAME_QUESTION_CLASS_IN;
2428 		additional.ttl = 0;
2429 		additional.rdata = data;
2430 		additional.rdlength = 6;
2431 		additional.rr_type = NAME_QUESTION_TYPE_NB;
2432 		attr = name->attributes & (NAME_ATTR_GROUP |
2433 		    NAME_ATTR_OWNER_NODE_TYPE);
2434 
2435 		BE_OUT16(&data[0], attr);
2436 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
2437 		    sizeof (uint32_t));
2438 
2439 		rc |= smb_send_name_registration_request(BROADCAST, &question,
2440 		    &additional);
2441 		addr = addr->forw;
2442 
2443 	} while (addr != &name->addr_list);
2444 
2445 	return (rc);
2446 }
2447 
2448 /*
2449  * 5.1.1.3.  B-NODE FIND_NAME
2450  *
2451  *   PROCEDURE find_name(name)
2452  *
2453  *   (*
2454  *    * Host initiated processing for a B node
2455  *    *)
2456  *
2457  *   BEGIN
2458  *
2459  *        REPEAT
2460  *             (*
2461  *              * build packet
2462  *              *)
2463  *             ONT = B;
2464  *             TTL = 0;
2465  *             G = DONT CARE;
2466  *			raddr = raddr->forw;
2467  *
2468  *             broadcast NAME QUERY REQUEST packet;
2469  *             (*
2470  *              * a node might send response packet
2471  *              *)
2472  *
2473  *             pause(BCAST_REQ_RETRY_TIMEOUT);
2474  *        UNTIL response packet received OR
2475  *             max transmit threshold exceeded
2476  *
2477  *        IF no response packet received THEN
2478  *             return failure;
2479  *        ELSE
2480  *        IF NOT response tid = request tid THEN
2481  *             ignore packet;
2482  *        ELSE
2483  *        CASE packet type OF
2484  *        POSITIVE NAME QUERY RESPONSE:
2485  *             (*
2486  *              * Start a timer to detect conflict.
2487  *              *
2488  *              * Be prepared to detect conflict if
2489  *              * any more response packets are received.
2490  *              *
2491  *              *)
2492  *
2493  *             save response as authoritative response;
2494  *             start_timer(CONFLICT_TIMER);
2495  *             return success;
2496  *
2497  *        NEGATIVE NAME QUERY RESPONSE:
2498  *        REDIRECT NAME QUERY RESPONSE:
2499  *
2500  *             (*
2501  *              * B Node should normally not get either
2502  *              * response.
2503  *              *)
2504  *
2505  *              ignore response packet;
2506  *
2507  *        END (* case *)
2508  *   END (* procedure *)
2509  */
2510 static int
2511 smb_name_Bnode_find_name(struct name_entry *name)
2512 {
2513 	struct name_question	question;
2514 
2515 	question.name = name;
2516 	question.question_type = NAME_QUESTION_TYPE_NB;
2517 	question.question_class = NAME_QUESTION_CLASS_IN;
2518 
2519 	return (smb_send_name_query_request(BROADCAST, &question));
2520 }
2521 
2522 /*
2523  * 5.1.1.4.  B NODE NAME RELEASE
2524  *
2525  *   PROCEDURE delete_name (name)
2526  *   BEGIN
2527  *
2528  *        REPEAT
2529  *
2530  *             (*
2531  *              * build packet
2532  *              *)
2533  *             ...
2534  *
2535  *             (*
2536  *              * send request
2537  *              *)
2538  *
2539  *             broadcast NAME RELEASE REQUEST packet;
2540  *
2541  *             (*
2542  *              * no response packet expected
2543  *              *)
2544  *
2545  *             pause(BCAST_REQ_RETRY_TIMEOUT);
2546  *
2547  *        UNTIL retransmit count has been exceeded
2548  *   END (* procedure *)
2549  */
2550 static int
2551 smb_name_Bnode_delete_name(struct name_entry *name)
2552 {
2553 	struct name_question	question;
2554 	struct resource_record	additional;
2555 	struct addr_entry 	*raddr;
2556 	unsigned char 		data[MAX_DATAGRAM_LENGTH];
2557 	unsigned char 		*scan = data;
2558 	uint32_t		attr;
2559 
2560 	/* build packet */
2561 	question.name = name;
2562 	question.question_type = NAME_QUESTION_TYPE_NB;
2563 	question.question_class = NAME_QUESTION_CLASS_IN;
2564 
2565 	additional.name = name;
2566 	additional.rr_class = NAME_QUESTION_CLASS_IN;
2567 	additional.ttl = 0;
2568 	additional.rdata = data;
2569 	additional.rdlength = 0;
2570 	additional.rr_type = NAME_QUESTION_TYPE_NB;
2571 	raddr = &name->addr_list;
2572 	scan = data;
2573 	do {
2574 		attr = name->attributes & (NAME_ATTR_GROUP |
2575 		    NAME_ATTR_OWNER_NODE_TYPE);
2576 
2577 		BE_OUT16(scan, attr); scan += 2;
2578 
2579 		*scan++ = raddr->sin.sin_addr.s_addr;
2580 		*scan++ = raddr->sin.sin_addr.s_addr >> 8;
2581 		*scan++ = raddr->sin.sin_addr.s_addr >> 16;
2582 		*scan++ = raddr->sin.sin_addr.s_addr >> 24;
2583 
2584 		additional.rdlength += 6;
2585 	} while (raddr != &name->addr_list);
2586 
2587 	return (smb_send_name_release_request_and_demand(BROADCAST,
2588 	    &question, &additional));
2589 }
2590 
2591 /*
2592  *
2593  * 5.1.2.  P-NODE ACTIVITY
2594  *
2595  *   All packets sent or received by P nodes are unicast UDP packets.
2596  *   A P node sends name service requests to the NAME node that is
2597  *   specified in the P-node configuration.
2598  *
2599  * 5.1.2.1.  P-NODE ADD_NAME
2600  *
2601  *   PROCEDURE add_name(name)
2602  *
2603  *   (*
2604  *    * Host initiated processing for a P node
2605  *    *)
2606  *
2607  *   BEGIN
2608  *
2609  *        REPEAT
2610  *             (*
2611  *              * build packet
2612  *              *)
2613  *
2614  *             ONT = P;
2615  *             G = UNIQUE;
2616  *             ...
2617  *
2618  *             (*
2619  *              * send request
2620  *              *)
2621  *
2622  *             unicast NAME REGISTRATION REQUEST packet;
2623  *
2624  *             (*
2625  *              * NAME will send response packet
2626  *              *)
2627  *
2628  *             IF receive a WACK RESPONSE THEN
2629  *                  pause(time from TTL field of response);
2630  *             ELSE
2631  *                  pause(UCAST_REQ_RETRY_TIMEOUT);
2632  *        UNTIL response packet is received OR
2633  *             retransmit count has been exceeded
2634  *
2635  *        IF no response packet was received THEN
2636  *        BEGIN (* no response *)
2637  *             (*
2638  *              * NAME is down.  Cannot claim name.
2639  *              *)
2640  *
2641  *             return failure; (* name cannot be claimed *)
2642  *        END (* no response *)
2643  *        ELSE
2644  *        BEGIN (* response *)
2645  *            IF NOT response tid = request tid THEN
2646  *            BEGIN
2647  *             (*  Packet may belong to another transaction  *)
2648  *             ignore response packet;
2649  *            END
2650  *            ELSE
2651  *            CASE packet type OF
2652  *
2653  *            POSITIVE NAME REGISTRATION RESPONSE:
2654  *
2655  *                 (*
2656  *                  * name can be added
2657  *                  *)
2658  *
2659  *                 adjust refresh timeout value, TTL, for this name;
2660  *                 return success;      (* name can be added *)
2661  *
2662  *            NEGATIVE NAME REGISTRATION RESPONSE:
2663  *                 return failure; (* name cannot be added *)
2664  *
2665  *            END-NODE CHALLENGE REGISTRATION REQUEST:
2666  *            BEGIN (* end node challenge *)
2667  *
2668  *                 (*
2669  *                  * The response packet has in it the
2670  *                  * address of the presumed owner of the
2671  *                  * name.  Challenge that owner.
2672  *                  * If owner either does not
2673  *                  * respond or indicates that he no longer
2674  *                  * owns the name, claim the name.
2675  *                  * Otherwise, the name cannot be claimed.
2676  *                  *
2677  *                  *)
2678  *
2679  *                 REPEAT
2680  *                  (*
2681  *                   * build packet
2682  *                   *)
2683  *                  ...
2684  *
2685  *                  unicast NAME QUERY REQUEST packet to the
2686  *                       address contained in the END NODE
2687  *                       CHALLENGE RESPONSE packet;
2688  *
2689  *                  (*
2690  *                   * remote node may send response packet
2691  *                   *)
2692  *
2693  *                  pause(UCAST_REQ_RETRY_TIMEOUT);
2694  *
2695  *                 UNTIL response packet is received or
2696  *                     retransmit count has been exceeded
2697  *                 IF no response packet is received OR
2698  *                       NEGATIVE NAME QUERY RESPONSE packet
2699  *                       received THEN
2700  *                 BEGIN (* update *)
2701  *
2702  *                  (*
2703  *                   * name can be claimed
2704  *                   *)
2705  *
2706  *                  REPEAT
2707  *
2708  *                      (*
2709  *                       * build packet
2710  *                       *)
2711  *                       ...
2712  *
2713  *                      unicast NAME UPDATE REQUEST to NAME;
2714  *
2715  *                      (*
2716  *                       * NAME node will send response packet
2717  *                       *)
2718  *
2719  *                      IF receive a WACK RESPONSE THEN
2720  *                            pause(time from TTL field of response);
2721  *                      ELSE
2722  *                            pause(UCAST_REQ_RETRY_TIMEOUT);
2723  *                  UNTIL response packet is received or
2724  *                      retransmit count has been exceeded
2725  *                  IF no response packet received THEN
2726  *                  BEGIN (* no response *)
2727  *
2728  *                       (*
2729  *                        * name could not be claimed
2730  *                        *)
2731  *
2732  *                       return failure;
2733  *                  END (* no response *)
2734  *                  ELSE
2735  *                  CASE packet type OF
2736  *                       POSITIVE NAME REGISTRATION RESPONSE:
2737  *                            (*
2738  *                             * add name
2739  *                             *)
2740  *                            return success;
2741  *                       NEGATIVE NAME REGISTRATION RESPONSE:
2742  *
2743  *                            (*
2744  *                             * you lose  ...
2745  *                             *)
2746  *                            return failure;
2747  *                       END (* case *)
2748  *                 END (* update *)
2749  *                 ELSE
2750  *
2751  *                 (*
2752  *                  * received a positive response to the "challenge"
2753  *                  * Remote node still has name
2754  *                  *)
2755  *
2756  *                  return failure;
2757  *            END (* end node challenge *)
2758  *        END (* response *)
2759  *   END (* procedure *)
2760  *
2761  *
2762  * 5.1.2.2.  P-NODE ADD GROUP NAME
2763  *
2764  *   PROCEDURE add_group_name(name)
2765  *
2766  *   (*
2767  *    * Host initiated processing for a P node
2768  *    *)
2769  *
2770  *   BEGIN
2771  *        (*
2772  *         * same as for a unique name, except that the
2773  *         * request packet must indicate that a
2774  *         * group name claim is being made.
2775  *         *)
2776  *
2777  *        ...
2778  *        G = GROUP;
2779  *        ...
2780  *
2781  *        (*
2782  *         * send packet
2783  *         *)
2784  *         ...
2785  *
2786  *
2787  *   END
2788  */
2789 static int
2790 smb_name_Pnode_add_name(struct name_entry *name)
2791 {
2792 	struct name_question		question;
2793 	struct resource_record		additional;
2794 	unsigned char 			data[8];
2795 	unsigned short			attr;
2796 	struct addr_entry *addr;
2797 	int rc = 0;
2798 
2799 	/* build packet */
2800 	addr = &name->addr_list;
2801 	do {
2802 		question.name = name;
2803 		question.question_type = NAME_QUESTION_TYPE_NB;
2804 		question.question_class = NAME_QUESTION_CLASS_IN;
2805 
2806 		additional.name = name;
2807 		additional.rr_class = NAME_QUESTION_CLASS_IN;
2808 		additional.ttl = 0;
2809 		additional.rdata = data;
2810 		additional.rdlength = 6;
2811 		additional.rr_type = NAME_QUESTION_TYPE_NB;
2812 		attr = name->attributes &
2813 		    (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE);
2814 
2815 		BE_OUT16(&data[0], attr);
2816 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
2817 		    sizeof (uint32_t));
2818 
2819 		rc |= smb_send_name_registration_request(UNICAST, &question,
2820 		    &additional);
2821 
2822 		addr = addr->forw;
2823 
2824 	} while (addr != &name->addr_list);
2825 
2826 	return (rc);
2827 }
2828 
2829 static int
2830 smb_name_Pnode_refresh_name(struct name_entry *name)
2831 {
2832 	struct name_question		question;
2833 	struct resource_record		additional;
2834 	unsigned char 			data[8];
2835 	unsigned short			attr;
2836 	struct addr_entry *addr;
2837 	int rc = 0;
2838 
2839 	/* build packet */
2840 	addr = &name->addr_list;
2841 	do {
2842 		question.name = name;
2843 		question.question_type = NAME_QUESTION_TYPE_NB;
2844 		question.question_class = NAME_QUESTION_CLASS_IN;
2845 
2846 		additional.name = name;
2847 		additional.rr_class = NAME_QUESTION_CLASS_IN;
2848 		additional.ttl = 0;
2849 		additional.rdata = data;
2850 		additional.rdlength = 6;
2851 		additional.rr_type = NAME_QUESTION_TYPE_NB;
2852 		attr = name->attributes &
2853 		    (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE);
2854 
2855 		BE_OUT16(&data[0], attr);
2856 		(void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
2857 		    sizeof (uint32_t));
2858 
2859 		rc |= smb_send_name_refresh_request(UNICAST, &question,
2860 		    &additional, 1);
2861 
2862 		addr = addr->forw;
2863 	} while (addr != &name->addr_list);
2864 
2865 	return (rc);
2866 }
2867 
2868 /*
2869  * 5.1.2.3.  P-NODE FIND NAME
2870  *
2871  *   PROCEDURE find_name(name)
2872  *
2873  *   (*
2874  *    * Host initiated processing for a P node
2875  *    *)
2876  *
2877  *   BEGIN
2878  *        REPEAT
2879  *             (*
2880  *              * build packet
2881  *              *)
2882  *
2883  *             ONT = P;
2884  *             G = DONT CARE;
2885  *
2886  *             unicast NAME QUERY REQUEST packet;
2887  *
2888  *             (*
2889  *              * a NAME node might send response packet
2890  *              *)
2891  *
2892  *             IF receive a WACK RESPONSE THEN
2893  *                  pause(time from TTL field of response);
2894  *             ELSE
2895  *                  pause(UCAST_REQ_RETRY_TIMEOUT);
2896  *        UNTIL response packet received OR
2897  *             max transmit threshold exceeded
2898  *
2899  *        IF no response packet received THEN
2900  *             return failure;
2901  *        ELSE
2902  *        IF NOT response tid = request tid THEN
2903  *             ignore packet;
2904  *        ELSE
2905  *        CASE packet type OF
2906  *        POSITIVE NAME QUERY RESPONSE:
2907  *             return success;
2908  *
2909  *        REDIRECT NAME QUERY RESPONSE:
2910  *
2911  *             (*
2912  *              * NAME node wants this end node
2913  *              * to use some other NAME node
2914  *              * to resolve the query.
2915  *              *)
2916  *
2917  *              repeat query with NAME address
2918  *                  in the response packet;
2919  *        NEGATIVE NAME QUERY RESPONSE:
2920  *             return failure;
2921  *
2922  *        END (* case *)
2923  *   END (* procedure *)
2924  */
2925 static int
2926 smb_name_Pnode_find_name(struct name_entry *name)
2927 {
2928 	struct name_question	question;
2929 
2930 	/*
2931 	 * Host initiated processing for a P node
2932 	 */
2933 	question.name = name;
2934 	question.name->attributes |= NAME_NB_FLAGS_ONT_P;
2935 	question.question_type = NAME_QUESTION_TYPE_NB;
2936 	question.question_class = NAME_QUESTION_CLASS_IN;
2937 
2938 	return (smb_send_name_query_request(UNICAST, &question));
2939 }
2940 
2941 /*
2942  * 5.1.2.4.  P-NODE DELETE_NAME
2943  *
2944  *   PROCEDURE delete_name (name)
2945  *
2946  *   (*
2947  *    * Host initiated processing for a P node
2948  *    *)
2949  *
2950  *   BEGIN
2951  *
2952  *        REPEAT
2953  *
2954  *             (*
2955  *              * build packet
2956  *              *)
2957  *             ...
2958  *
2959  *             (*
2960  *              * send request
2961  *              *)
2962  *
2963  *             unicast NAME RELEASE REQUEST packet;
2964  *             IF receive a WACK RESPONSE THEN
2965  *                  pause(time from TTL field of response);
2966  *             ELSE
2967  *                  pause(UCAST_REQ_RETRY_TIMEOUT);
2968  *        UNTIL retransmit count has been exceeded
2969  *             or response been received
2970  *
2971  *        IF response has been received THEN
2972  *        CASE packet type OF
2973  *        POSITIVE NAME RELEASE RESPONSE:
2974  *             return success;
2975  *        NEGATIVE NAME RELEASE RESPONSE:
2976  *
2977  *             (*
2978  *              * NAME does want node to delete this
2979  *              * name !!!
2980  *              *)
2981  *
2982  *             return failure;
2983  *        END (* case *)
2984  *   END (* procedure *)
2985  */
2986 static int
2987 smb_name_Pnode_delete_name(struct name_entry *name)
2988 {
2989 	struct name_question	question;
2990 	struct resource_record	additional;
2991 	struct addr_entry 	*raddr;
2992 	unsigned char 		data[MAX_DATAGRAM_LENGTH];
2993 	unsigned char 		*scan = data;
2994 	uint32_t		attr;
2995 
2996 	/* build packet */
2997 	question.name = name;
2998 	question.name->attributes |= NAME_NB_FLAGS_ONT_P;
2999 	question.question_type = NAME_QUESTION_TYPE_NB;
3000 	question.question_class = NAME_QUESTION_CLASS_IN;
3001 
3002 	additional.name = name;
3003 	additional.rr_class = NAME_QUESTION_CLASS_IN;
3004 	additional.ttl = 0;
3005 	additional.rdata = data;
3006 	additional.rdlength = 0;
3007 	additional.rr_type = NAME_QUESTION_TYPE_NB;
3008 	raddr = &name->addr_list;
3009 	do {
3010 		scan = data;
3011 		attr = name->attributes & (NAME_ATTR_GROUP |
3012 		    NAME_ATTR_OWNER_NODE_TYPE);
3013 
3014 		BE_OUT16(scan, attr); scan += 2;
3015 
3016 		*scan++ = raddr->sin.sin_addr.s_addr;
3017 		*scan++ = raddr->sin.sin_addr.s_addr >> 8;
3018 		*scan++ = raddr->sin.sin_addr.s_addr >> 16;
3019 		*scan++ = raddr->sin.sin_addr.s_addr >> 24;
3020 
3021 		additional.rdlength = 6;
3022 		raddr = raddr->forw;
3023 		(void) smb_send_name_release_request_and_demand(UNICAST,
3024 		    &question, &additional);
3025 	} while (raddr != &name->addr_list);
3026 
3027 	return (1);
3028 }
3029 
3030 /*
3031  * 5.1.3.  M-NODE ACTIVITY
3032  *
3033  *   M nodes behavior is similar to that of P nodes with the addition
3034  *   of some B node-like broadcast actions.  M node name service
3035  *   proceeds in two steps:
3036  *
3037  *   1.Use broadcast UDP based name service.  Depending on the
3038  *     operation, goto step 2.
3039  *
3040  *   2.Use directed UDP name service.
3041  *
3042  *   The following code for M nodes is exactly the same as for a P
3043  *   node, with the exception that broadcast operations are done
3044  *   before P type operation is attempted.
3045  *
3046  * 5.1.3.1.  M-NODE ADD NAME
3047  *
3048  *   PROCEDURE add_name(name)
3049  *
3050  *   (*
3051  *    * Host initiated processing for a M node
3052  *    *)
3053  *
3054  *   BEGIN
3055  *
3056  *        (*
3057  *         * check if name exists on the
3058  *         * broadcast area
3059  *         *)
3060  *        REPEAT
3061  *            (* build packet *)
3062  *
3063  *            ....
3064  *            broadcast NAME REGISTRATION REQUEST packet;
3065  *            pause(BCAST_REQ_RETRY_TIMEOUT);
3066  *
3067  *        UNTIL response packet is received or
3068  *             retransmit count has been  exceeded
3069  *
3070  *        IF valid response received THEN
3071  *        BEGIN
3072  *             (* cannot claim name *)
3073  *
3074  *             return failure;
3075  *        END
3076  *
3077  *        (*
3078  *         * No objections received within the
3079  *         * broadcast area.
3080  *         * Send request to name server.
3081  *         *)
3082  *
3083  *        REPEAT
3084  *             (*
3085  *              * build packet
3086  *              *)
3087  *
3088  *             ONT = M;
3089  *             ...
3090  *
3091  *             unicast NAME REGISTRATION REQUEST packet;
3092  *
3093  *             (*
3094  *              * remote NAME will send response packet
3095  *              *)
3096  *
3097  *             IF receive a WACK RESPONSE THEN
3098  *                  pause(time from TTL field of response);
3099  *             ELSE
3100  *                  pause(UCAST_REQ_RETRY_TIMEOUT);
3101  *
3102  *        UNTIL response packet is received or
3103  *             retransmit count has been exceeded
3104  *
3105  *        IF no response packet was received THEN
3106  *        BEGIN (* no response *)
3107  *             (*
3108  *              * NAME is down.  Cannot claim name.
3109  *              *)
3110  *             return failure; (* name cannot be claimed *)
3111  *        END (* no response *)
3112  *        ELSE
3113  *        BEGIN (* response *)
3114  *            IF NOT response tid = request tid THEN
3115  *            BEGIN
3116  *             ignore response packet;
3117  *            END
3118  *            ELSE
3119  *            CASE packet type OF
3120  *            POSITIVE NAME REGISTRATION RESPONSE:
3121  *
3122  *                 (*
3123  *                  * name can be added
3124  *                  *)
3125  *
3126  *                 adjust refresh timeout value, TTL;
3127  *                 return success;      (* name can be added *)
3128  *
3129  *            NEGATIVE NAME REGISTRATION RESPONSE:
3130  *                 return failure; (* name cannot be added *)
3131  *
3132  *            END-NODE CHALLENGE REGISTRATION REQUEST:
3133  *            BEGIN (* end node challenge *)
3134  *
3135  *                 (*
3136  *                  * The response packet has in it the
3137  *                  * address of the presumed owner of the
3138  *                  * name.  Challenge that owner.
3139  *                  * If owner either does not
3140  *                  * respond or indicates that he no longer
3141  *                  * owns the name, claim the name.
3142  *                  * Otherwise, the name cannot be claimed.
3143  *                  *
3144  *                  *)
3145  *
3146  *                 REPEAT
3147  *                  (*
3148  *                   * build packet
3149  *                   *)
3150  *                  ...
3151  *
3152  *                  (*
3153  *                   * send packet to address contained in the
3154  *                   * response packet
3155  *                   *)
3156  *
3157  *                  unicast NAME QUERY REQUEST packet;
3158  *
3159  *                  (*
3160  *                   * remote node may send response packet
3161  *                   *)
3162  *
3163  *                  pause(UCAST_REQ_RETRY_TIMEOUT);
3164  *
3165  *                 UNTIL response packet is received or
3166  *                     retransmit count has been exceeded
3167  *                 IF no response packet is received THEN
3168  *                 BEGIN (* no response *)
3169  *
3170  *                  (*
3171  *                   * name can be claimed
3172  *                   *)
3173  *                  REPEAT
3174  *
3175  *                      (*
3176  *                       * build packet
3177  *                       *)
3178  *                       ...
3179  *
3180  *                      unicast NAME UPDATE REQUEST to NAME;
3181  *
3182  *                      (*
3183  *                       * NAME node will send response packet
3184  *                       *)
3185  *
3186  *                      IF receive a WACK RESPONSE THEN
3187  *                            pause(time from TTL field of response);
3188  *                  ELSE
3189  *                       pause(UCAST_REQ_RETRY_TIMEOUT);
3190  *
3191  *                  UNTIL response packet is received or
3192  *                      retransmit count has been exceeded
3193  *                  IF no response packet received THEN
3194  *                  BEGIN (* no response *)
3195  *
3196  *                       (*
3197  *                        * name could not be claimed
3198  *                        *)
3199  *
3200  *                       return failure;
3201  *                  END (* no response *)
3202  *                  ELSE
3203  *                  CASE packet type OF
3204  *                  POSITIVE NAME REGISTRATION RESPONSE:
3205  *                       (*
3206  *                        * add name
3207  *                        *)
3208  *
3209  *                       return success;
3210  *                  NEGATIVE NAME REGISTRATION RESPONSE:
3211  *                       (*
3212  *                        * you lose  ...
3213  *                        *)
3214  *
3215  *                       return failure;
3216  *                  END (* case *)
3217  *                 END (* no response *)
3218  *                 ELSE
3219  *                 IF NOT response tid = request tid THEN
3220  *                 BEGIN
3221  *                  ignore response packet;
3222  *                 END
3223  *
3224  *                 (*
3225  *                  * received a response to the "challenge"
3226  *                  * packet
3227  *                  *)
3228  *
3229  *                 CASE packet type OF
3230  *                 POSITIVE NAME QUERY:
3231  *
3232  *                  (*
3233  *                   * remote node still has name.
3234  *                   *)
3235  *
3236  *                  return failure;
3237  *                 NEGATIVE NAME QUERY:
3238  *
3239  *                  (*
3240  *                   * remote node no longer has name
3241  *                   *)
3242  *
3243  *                  return success;
3244  *                 END (* case *)
3245  *            END (* end node challenge *)
3246  *            END (* case *)
3247  *        END (* response *)
3248  *   END (* procedure *)
3249  *
3250  *
3251  * 5.1.3.2.  M-NODE ADD GROUP NAME
3252  *
3253  *   PROCEDURE add_group_name(name)
3254  *
3255  *   (*
3256  *    * Host initiated processing for a P node
3257  *    *)
3258  *
3259  *   BEGIN
3260  *        (*
3261  *         * same as for a unique name, except that the
3262  *         * request packet must indicate that a
3263  *         * group name claim is being made.
3264  *         *)
3265  *
3266  *        ...
3267  *        G = GROUP;
3268  *        ...
3269  *
3270  *        (*
3271  *         * send packet
3272  *         *)
3273  *         ...
3274  *
3275  *
3276  *   END
3277  */
3278 static int
3279 smb_name_Mnode_add_name(struct name_entry *name)
3280 {
3281 	if (smb_name_Bnode_add_name(name) > 0) {
3282 		if (nbns_num == 0)
3283 			return (1); /* No name server configured */
3284 
3285 		return (smb_name_Pnode_add_name(name));
3286 	}
3287 	return (-1);
3288 }
3289 
3290 static int
3291 smb_name_Hnode_add_name(struct name_entry *name)
3292 {
3293 	if (nbns_num > 0) {
3294 		if (smb_name_Pnode_add_name(name) == 1)
3295 			return (1);
3296 	}
3297 
3298 	return (smb_name_Bnode_add_name(name));
3299 }
3300 
3301 /*
3302  * 5.1.3.3.  M-NODE FIND NAME
3303  *
3304  *   PROCEDURE find_name(name)
3305  *
3306  *   (*
3307  *    * Host initiated processing for a M node
3308  *    *)
3309  *
3310  *   BEGIN
3311  *        (*
3312  *         * check if any node on the broadcast
3313  *         * area has the name
3314  *         *)
3315  *
3316  *        REPEAT
3317  *             (* build packet *)
3318  *             ...
3319  *
3320  *             broadcast NAME QUERY REQUEST packet;
3321  *             pause(BCAST_REQ_RETRY_TIMEOUT);
3322  *        UNTIL response packet received OR
3323  *             max transmit threshold exceeded
3324  *
3325  *        IF valid response received THEN
3326  *        BEGIN
3327  *             save response as authoritative response;
3328  *             start_timer(CONFLICT_TIMER);
3329  *             return success;
3330  *        END
3331  *
3332  *        (*
3333  *         * no valid response on the b'cast segment.
3334  *         * Try the name server.
3335  *         *)
3336  *
3337  *        REPEAT
3338  *             (*
3339  *              * build packet
3340  *              *)
3341  *
3342  *             ONT = M;
3343  *             G = DONT CARE;
3344  *
3345  *             unicast NAME QUERY REQUEST packet to NAME;
3346  *
3347  *             (*
3348  *              * a NAME node might send response packet
3349  *              *)
3350  *
3351  *             IF receive a WACK RESPONSE THEN
3352  *                  pause(time from TTL field of response);
3353  *             ELSE
3354  *                  pause(UCAST_REQ_RETRY_TIMEOUT);
3355  *        UNTIL response packet received OR
3356  *             max transmit threshold exceeded
3357  *
3358  *        IF no response packet received THEN
3359  *             return failure;
3360  *        ELSE
3361  *        IF NOT response tid = request tid THEN
3362  *             ignore packet;
3363  *        ELSE
3364  *        CASE packet type OF
3365  *        POSITIVE NAME QUERY RESPONSE:
3366  *             return success;
3367  *
3368  *        REDIRECT NAME QUERY RESPONSE:
3369  *
3370  *             (*
3371  *              * NAME node wants this end node
3372  *              * to use some other NAME node
3373  *              * to resolve the query.
3374  *              *)
3375  *
3376  *              repeat query with NAME address
3377  *                  in the response packet;
3378  *        NEGATIVE NAME QUERY RESPONSE:
3379  *             return failure;
3380  *
3381  *        END (* case *)
3382  *   END (* procedure *)
3383  */
3384 static int
3385 smb_name_Mnode_find_name(struct name_entry *name)
3386 {
3387 	if (smb_name_Bnode_find_name(name) == 1)
3388 		return (1);
3389 
3390 	if (nbns_num == 0)
3391 		return (1); /* No name server configured */
3392 
3393 	return (smb_name_Pnode_find_name(name));
3394 }
3395 
3396 static int
3397 smb_name_Hnode_find_name(struct name_entry *name)
3398 {
3399 	if (nbns_num > 0)
3400 		if (smb_name_Pnode_find_name(name) == 1)
3401 			return (1);
3402 
3403 	return (smb_name_Bnode_find_name(name));
3404 }
3405 
3406 /*
3407  * 5.1.3.4.  M-NODE DELETE NAME
3408  *
3409  *   PROCEDURE delete_name (name)
3410  *
3411  *   (*
3412  *    * Host initiated processing for a P node
3413  *    *)
3414  *
3415  *   BEGIN
3416  *        (*
3417  *         * First, delete name on NAME
3418  *         *)
3419  *
3420  *        REPEAT
3421  *
3422  *             (*
3423  *              * build packet
3424  *	struct addr_entry *addr;
3425  *              *)
3426  *             ...
3427  *
3428  *             (*
3429  *              * send request
3430  *              *)
3431  *
3432  *             unicast NAME RELEASE REQUEST packet to NAME;
3433  *
3434  *             IF receive a WACK RESPONSE THEN
3435  *                  pause(time from TTL field of response);
3436  *             ELSE
3437  *                  pause(UCAST_REQ_RETRY_TIMEOUT);
3438  *        UNTIL retransmit count has been exceeded
3439  *             or response been received
3440  *
3441  *        IF response has been received THEN
3442  *        CASE packet type OF
3443  *        POSITIVE NAME RELEASE RESPONSE:
3444  *             (*
3445  *              * Deletion of name on b'cast segment is deferred
3446  *              * until after NAME has deleted the name
3447  *              *)
3448  *
3449  *             REPEAT
3450  *                  (* build packet *)
3451  *
3452  *                  ...
3453  *                  broadcast NAME RELEASE REQUEST;
3454  *                  pause(BCAST_REQ_RETRY_TIMEOUT);
3455  *             UNTIL rexmt threshold exceeded
3456  *
3457  *             return success;
3458  *        NEGATIVE NAME RELEASE RESPONSE:
3459  *
3460  *             (*
3461  *              * NAME does want node to delete this
3462  *              * name
3463  *              *)
3464  *             return failure;
3465  *        END (* case *)
3466  *   END (* procedure *)
3467  */
3468 static int
3469 smb_name_Mnode_delete_name(struct name_entry *name)
3470 {
3471 	(void) smb_name_Bnode_delete_name(name);
3472 
3473 	if (nbns_num == 0)
3474 		return (-1); /* No name server configured */
3475 
3476 	if (smb_name_Pnode_delete_name(name) > 0)
3477 		return (1);
3478 
3479 	return (-1);
3480 }
3481 
3482 static int
3483 smb_name_Hnode_delete_name(struct name_entry *name)
3484 {
3485 	if (nbns_num > 0)
3486 		if (smb_name_Pnode_delete_name(name) > 0)
3487 			return (1);
3488 
3489 	return (smb_name_Bnode_delete_name(name));
3490 }
3491 
3492 /*
3493  * 5.1.1.5.  B-NODE INCOMING PACKET PROCESSING
3494  *
3495  *   Following processing is done when broadcast or unicast packets
3496  *   are received at the NAME_SERVICE_UDP_PORT.
3497  *
3498  *   PROCEDURE process_incoming_packet(packet)
3499  *
3500  *   (*
3501  *    * Processing initiated by incoming packets for a B node
3502  *    *)
3503  *
3504  *   BEGIN
3505  *        (*
3506  *         * Note: response packets are always sent
3507  *         * to:
3508  *         * source IP address of request packet
3509  *         * source UDP port of request packet
3510  *         *)
3511  *
3512  *        CASE packet type OF
3513  *
3514  *        NAME REGISTRATION REQUEST (UNIQUE):
3515  *             IF name exists in local name table THEN
3516  *                  send NEGATIVE_NAME_REGISTRATION_RESPONSE ;
3517  *        NAME REGISTRATION REQUEST (GROUP):
3518  *             IF name exists in local name table THEN
3519  *             BEGIN
3520  *                  IF local entry is a unique name THEN
3521  *                      send NEGATIVE_NAME_REGISTRATION_RESPONSE ;
3522  *             END
3523  *        NAME QUERY REQUEST:
3524  *             IF name exists in local name table THEN
3525  *             BEGIN
3526  *                  build response packet;
3527  *                  send POSITIVE_NAME_QUERY_RESPONSE;
3528  *        POSITIVE NAME QUERY RESPONSE:
3529  *             IF name conflict timer is not active THEN
3530  *                 BEGIN
3531  *                      (*
3532  *                       * timer has expired already...  ignore this
3533  *                       * packet
3534  *                       *)
3535  *
3536  *                      return;
3537  *                 END
3538  *             ELSE (* timer is active *)
3539  *                 IF a response for this name has previously been
3540  *                      received THEN
3541  *                     BEGIN (* existing entry *)
3542  *
3543  *                      (*
3544  *                       * we sent out a request packet, and
3545  *                       * have already received (at least)
3546  *                       * one response
3547  *                       *
3548  *                       * Check if conflict exists.
3549  *                       * If so, send out a conflict packet.
3550  *                       *
3551  *                       * Note: detecting conflict does NOT
3552  *                       * affect any existing sessions.
3553  *                       *
3554  *                       *)
3555  *
3556  *                      (*
3557  *                       * Check for name conflict.
3558  *                       * See "Name Conflict" in Concepts and Methods
3559  *                       *)
3560  *                      check saved authoritative response against
3561  *                           information in this response packet;
3562  *                      IF conflict detected THEN
3563  *                      BEGIN
3564  *                           unicast NAME CONFLICT DEMAND packet;
3565  *                           IF entry exists in cache THEN
3566  *                           BEGIN
3567  *                                remove entry from cache;
3568  *                           END
3569  *                      END
3570  *                 END (* existing entry *)
3571  *             ELSE
3572  *                 BEGIN
3573  *                      (*
3574  *                       * Note: If this was the first response
3575  *                       * to a name query, it would have been
3576  *                       * handled in the
3577  *                       * find_name() procedure.
3578  *                       *)
3579  *
3580  *                      ignore packet;
3581  *                 END
3582  *        NAME CONFLICT DEMAND:
3583  *             IF name exists in local name table THEN
3584  *             BEGIN
3585  *                  mark name as conflict detected;
3586  *
3587  *                  (*
3588  *                   * a name in the state "conflict detected"
3589  *                   * does not "logically" exist on that node.
3590  *                   * No further session will be accepted on
3591  *                   * that name.
3592  *                   * No datagrams can be sent against that name.
3593  *                   * Such an entry will not be used for
3594  *                   * purposes of processing incoming request
3595  *                   * packets.
3596  *                   * The only valid user NetBIOS operation
3597  *                   * against such a name is DELETE NAME.
3598  *                   *)
3599  *             END
3600  *        NAME RELEASE REQUEST:
3601  *             IF caching is being done THEN
3602  *             BEGIN
3603  *                  remove entry from cache;
3604  *             END
3605  *        NAME UPDATE REQUEST:
3606  *             IF caching is being done THEN
3607  *             BEGIN
3608  *                  IF entry exists in cache already,
3609  *                       update cache;
3610  *                  ELSE IF name is "interesting" THEN
3611  *                  BEGIN
3612  *                       add entry to cache;
3613  *                  END
3614  *             END
3615  *
3616  *        NODE STATUS REQUEST:
3617  *             IF name exists in local name table THEN
3618  *             BEGIN
3619  *                  (*
3620  *                   * send only those names that are
3621  *                   * in the same scope as the scope
3622  *                   * field in the request packet
3623  *                   *)
3624  *
3625  *                  send NODE STATUS RESPONSE;
3626  *             END
3627  *   END
3628  */
3629 static void
3630 smb_name_process_Bnode_packet(struct name_packet *packet,
3631     struct addr_entry *addr)
3632 {
3633 	struct name_entry 	*name;
3634 	struct name_entry 	*entry;
3635 	struct name_question 	*question;
3636 	struct resource_record 	*additional;
3637 
3638 	question = packet->question;
3639 	additional = packet->additional;
3640 
3641 	switch (packet->info & NAME_OPCODE_OPCODE_MASK) {
3642 	case NAME_OPCODE_REFRESH:
3643 		/* Guard against malformed packets */
3644 		if ((question == 0) || (additional == 0))
3645 			break;
3646 		if (additional->name->addr_list.sin.sin_addr.s_addr == 0)
3647 			break;
3648 
3649 		name = question->name;
3650 		name->addr_list.ttl = additional->ttl;
3651 		name->attributes = additional->name->attributes;
3652 		name->addr_list.sin = additional->name->addr_list.sin;
3653 		name->addr_list.forw = name->addr_list.back = &name->addr_list;
3654 
3655 		if ((entry = smb_netbios_cache_lookup_addr(name)) != 0) {
3656 			smb_netbios_cache_update_entry(entry, question->name);
3657 			smb_netbios_cache_unlock_entry(entry);
3658 		}
3659 		else
3660 			(void) smb_netbios_cache_insert(question->name);
3661 		break;
3662 
3663 	case NAME_OPCODE_QUERY:
3664 		/*
3665 		 * This opcode covers both NAME_QUERY_REQUEST and
3666 		 * NODE_STATUS_REQUEST. They can be distinguished
3667 		 * based on the type of question entry.
3668 		 */
3669 
3670 		/* All query requests have to have question entry */
3671 		if (question == 0)
3672 			break;
3673 
3674 		if (question->question_type == NAME_QUESTION_TYPE_NB) {
3675 			name = question->name;
3676 			if ((entry = smb_netbios_cache_lookup(name)) != 0) {
3677 				(void) smb_send_name_query_response(addr,
3678 				    packet, entry, 0);
3679 				smb_netbios_cache_unlock_entry(entry);
3680 			}
3681 		}
3682 		else
3683 		if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) {
3684 			/*
3685 			 * Name of "*" may be used to force node to
3686 			 * divulge status for administrative purposes
3687 			 */
3688 			name = question->name;
3689 			entry = 0;
3690 			if (NETBIOS_NAME_IS_STAR(name->name) ||
3691 			    ((entry = smb_netbios_cache_lookup(name)) != 0)) {
3692 				if (entry)
3693 					smb_netbios_cache_unlock_entry(entry);
3694 				/*
3695 				 * send only those names that are
3696 				 * in the same scope as the scope
3697 				 * field in the request packet
3698 				 */
3699 				(void) smb_send_node_status_response(addr,
3700 				    packet);
3701 			}
3702 		}
3703 		break;
3704 
3705 	default:
3706 		break;
3707 	}
3708 }
3709 
3710 /*
3711  * 5.1.2.5.  P-NODE INCOMING PACKET PROCESSING
3712  *
3713  *   Processing initiated by reception of packets at a P node
3714  *
3715  *   PROCEDURE process_incoming_packet(packet)
3716  *
3717  *   (*
3718  *    * Processing initiated by incoming packets at a P node
3719  *    *)
3720  *
3721  *   BEGIN
3722  *        (*
3723  *         * always ignore UDP broadcast packets
3724  *         *)
3725  *
3726  *        IF packet was sent as a broadcast THEN
3727  *        BEGIN
3728  *             ignore packet;
3729  *             return;
3730  *        END
3731  *        CASE packet type of
3732  *
3733  *        NAME CONFLICT DEMAND:
3734  *             IF name exists in local name table THEN
3735  *                  mark name as in conflict;
3736  *             return;
3737  *
3738  *        NAME QUERY REQUEST:
3739  *             IF name exists in local name table THEN
3740  *             BEGIN (* name exists *)
3741  *
3742  *                  (*
3743  *                   * build packet
3744  *                   *)
3745  *                  ...
3746  *
3747  *                  (*
3748  *                   * send response to the IP address and port
3749  *                   * number from which the request was received.
3750  *                   *)
3751  *
3752  *                  send POSITIVE_NAME_QUERY_RESPONSE ;
3753  *                  return;
3754  *             END (* exists *)
3755  *             ELSE
3756  *             BEGIN (* does not exist *)
3757  *
3758  *                  (*
3759  *                   * send response to the requestor
3760  *                   *)
3761  *
3762  *                  send NEGATIVE_NAME_QUERY_RESPONSE ;
3763  *                  return;
3764  *             END (* does not exist *)
3765  *        NODE STATUS REQUEST:
3766  *             (*
3767  *              * Name of "*" may be used for force node to
3768  *              * divulge status for administrative purposes
3769  *              *)
3770  *             IF name in local name table OR name = "*" THEN
3771  *             BEGIN
3772  *                  (*
3773  *                   * Build response packet and
3774  *                   * send to requestor node
3775  *                   * Send only those names that are
3776  *                   * in the same scope as the scope
3777  *                   * in the request packet.
3778  *                   *)
3779  *
3780  *                  send NODE_STATUS_RESPONSE;
3781  *             END
3782  *
3783  *        NAME RELEASE REQUEST:
3784  *             (*
3785  *              * This will be received if the NAME wants to flush the
3786  *              * name from the local name table, or from the local
3787  *              * cache.
3788  *              *)
3789  *
3790  *             IF name exists in the local name table THEN
3791  *             BEGIN
3792  *                  delete name from local name table;
3793  *                  inform user that name has been deleted;
3794  *             END
3795  *        END (* case *)
3796  *   END (* procedure *)
3797  *
3798  *   (*
3799  *    * Incoming packet processing on a NS node
3800  *    *)
3801  *
3802  *   BEGIN
3803  *        IF packet was sent as a broadcast THEN
3804  *        BEGIN
3805  *             discard packet;
3806  *             return;
3807  *        END
3808  *        CASE packet type of
3809  *
3810  *        NAME REGISTRATION REQUEST (UNIQUE):
3811  *             IF unique name exists in data base THEN
3812  *             BEGIN (* unique name exists *)
3813  *                  (*
3814  *                   * NAME node may be a "passive"
3815  *                   * server in that it expects the
3816  *                   * end node to do the challenge
3817  *                   * server.  Such a NAME node is
3818  *                   * called a "non-secure" server.
3819  *                   * A "secure" server will do the
3820  *                   * challenging before it sends
3821  *                   * back a response packet.
3822  *                   *)
3823  *
3824  *                  IF non-secure THEN
3825  *                  BEGIN
3826  *                       (*
3827  *                        * build response packet
3828  *                        *)
3829  *                       ...
3830  *
3831  *
3832  *                       (*
3833  *                        * let end node do the challenge
3834  *                        *)
3835  *
3836  *                       send END-NODE CHALLENGE NAME REGISTRATION
3837  *                            RESPONSE;
3838  *                       return;
3839  *                  END
3840  *                  ELSE
3841  *                  (*
3842  *                   * secure server - do the name
3843  *                   * challenge operation
3844  *                   *)
3845  *
3846  *                  REPEAT
3847  *                      send NAME QUERY REQUEST;
3848  *                      pause(UCAST_REQ_RETRY_TIMEOUT);
3849  *                  UNTIL response has been received or
3850  *                       retransmit count has been exceeded
3851  *                  IF no response was received THEN
3852  *                  BEGIN
3853  *
3854  *                       (* node down *)
3855  *
3856  *                       update data base - remove entry;
3857  *                       update data base - add new entry;
3858  *                       send POSITIVE NAME REGISTRATION RESPONSE;
3859  *                       return;
3860  *                  END
3861  *                  ELSE
3862  *                  BEGIN (* challenged node replied *)
3863  *                      (*
3864  *                       * challenged node replied with
3865  *                       * a response packet
3866  *                       *)
3867  *
3868  *                      CASE packet type
3869  *
3870  *                      POSITIVE NAME QUERY RESPONSE:
3871  *
3872  *                       (*
3873  *                        * name still owned by the
3874  *                        * challenged node
3875  *                        *
3876  *                        * build packet and send response
3877  *                        *)
3878  *                        ...
3879  *
3880  *
3881  *                       (*
3882  *                        * Note: The NAME will need to
3883  *                        * keep track (based on transaction id) of
3884  *                        * the IP address and port number
3885  *                        * of the original requestor.
3886  *                        *)
3887  *
3888  *                       send NEGATIVE NAME REGISTRATION RESPONSE;
3889  *                       return;
3890  *                      NEGATIVE NAME QUERY RESPONSE:
3891  *
3892  *                       update data base - remove entry;
3893  *                       update data base - add new  entry;
3894  *
3895  *                       (*
3896  *                        * build response packet and send
3897  *                        * response
3898  *                        *)
3899  *                       send POSITIVE NAME REGISTRATION RESPONSE;
3900  *                       return;
3901  *                      END (* case *)
3902  *                  END (* challenged node replied *)
3903  *             END (* unique name exists in data base *)
3904  *             ELSE
3905  *             IF group name exists in data base THEN
3906  *             BEGIN (* group names exists *)
3907  *
3908  *                  (*
3909  *                   * Members of a group name are NOT
3910  *                   * challenged.
3911  *                   * Make the assumption that
3912  *                   * at least some of the group members
3913  *                   * are still alive.
3914  *                   * Refresh mechanism will
3915  *                   * allow the NAME to detect when all
3916  *                   * members of a group no longer use that
3917  *                   * name
3918  *                   *)
3919  *
3920  *                   send NEGATIVE NAME REGISTRATION RESPONSE;
3921  *             END (* group name exists *)
3922  *             ELSE
3923  *             BEGIN (* name does not exist *)
3924  *
3925  *                  (*
3926  *                   * Name does not exist in data base
3927  *                   *
3928  *                   * This code applies to both non-secure
3929  *                   * and secure server.
3930  *                   *)
3931  *
3932  *                  update data base - add new entry;
3933  *                  send POSITIVE NAME REGISTRATION RESPONSE;
3934  *                  return;
3935  *             END
3936  *
3937  *        NAME QUERY REQUEST:
3938  *             IF name exists in data base THEN
3939  *             BEGIN
3940  *                  (*
3941  *                   * build response packet and send to
3942  *                   * requestor
3943  *                   *)
3944  *                   ...
3945  *
3946  *                  send POSITIVE NAME QUERY RESPONSE;
3947  *                  return;
3948  *             ELSE
3949  *             BEGIN
3950  *                  (*
3951  *                   * build response packet and send to
3952  *                   * requestor
3953  *                   *)
3954  *                   ...
3955  *
3956  *                  send NEGATIVE NAME QUERY RESPONSE;
3957  *                  return;
3958  *             END
3959  *
3960  *        NAME REGISTRATION REQUEST (GROUP):
3961  *             IF name exists in data base THEN
3962  *             BEGIN
3963  *                  IF local entry is a unique name THEN
3964  *                  BEGIN (* local is unique *)
3965  *
3966  *                      IF non-secure THEN
3967  *                      BEGIN
3968  *                       send  END-NODE CHALLENGE NAME
3969  *                            REGISTRATION RESPONSE;
3970  *                       return;
3971  *                      END
3972  *
3973  *                      REPEAT
3974  *                       send NAME QUERY REQUEST;
3975  *                       pause(UCAST_REQ_RETRY_TIMEOUT);
3976  *                      UNTIL response received or
3977  *                           retransmit count exceeded
3978  *                      IF no response received or
3979  *                           NEGATIVE NAME QUERY RESPONSE
3980  *                            received THEN
3981  *                      BEGIN
3982  *                       update data base - remove entry;
3983  *                       update data base - add new entry;
3984  *                       send POSITIVE NAME REGISTRATION RESPONSE;
3985  *                       return;
3986  *                      END
3987  *                      ELSE
3988  *                      BEGIN
3989  *                       (*
3990  *                        * name still being held
3991  *                        * by challenged node
3992  *                        *)
3993  *
3994  *                        send NEGATIVE NAME REGISTRATION RESPONSE;
3995  *                      END
3996  *                  END (* local is unique *)
3997  *                  ELSE
3998  *                  BEGIN (* local is group  *)
3999  *                       (*
4000  *                        * existing entry is a group name
4001  *                        *)
4002  *
4003  *                       update data base - remove entry;
4004  *                       update data base - add new entry;
4005  *                       send POSITIVE NAME REGISTRATION RESPONSE;
4006  *                       return;
4007  *                  END (* local is group *)
4008  *             END (* names exists *)
4009  *             ELSE
4010  *             BEGIN (* does not exist *)
4011  *
4012  *                  (* name does not exist in data base *)
4013  *
4014  *                  update data base - add new entry;
4015  *                  send POSITIVE NAME REGISTRATION RESPONSE;
4016  *                  return;
4017  *             END (* does not exist *)
4018  *
4019  *        NAME RELEASE REQUEST:
4020  *
4021  *             (*
4022  *              * secure server may choose to disallow
4023  *              * a node from deleting a name
4024  *              *)
4025  *
4026  *             update data base - remove entry;
4027  *             send POSITIVE NAME RELEASE RESPONSE;
4028  *             return;
4029  *
4030  *        NAME UPDATE REQUEST:
4031  *
4032  *             (*
4033  *              * End-node completed a successful challenge,
4034  *              * no update database
4035  *              *)
4036  *
4037  *             IF secure server THEN
4038  *                  send NEGATIVE NAME REGISTRATION RESPONSE;
4039  *             ELSE
4040  *             BEGIN (* new entry *)
4041  *                  IF entry already exists THEN
4042  *                       update data base - remove entry;
4043  *                  update data base - add new entry;
4044  *                  send POSITIVE NAME REGISTRATION RESPONSE;
4045  *                  start_timer(TTL);
4046  *             END
4047  *
4048  *        NAME REFRESH REQUEST:
4049  *             check for consistency;
4050  *
4051  *             IF node not allowed to have name THEN
4052  *             BEGIN
4053  *
4054  *                  (*
4055  *                   * tell end node that it can't have name
4056  *                   *)
4057  *                  send NEGATIVE NAME REGISTRATION RESPONSE;
4058  *             END
4059  *             ELSE
4060  *             BEGIN
4061  *
4062  *                  (*
4063  *                   * send confirmation response to the
4064  *                   * end node.
4065  *                   *)
4066  *                  send POSITIVE NAME REGISTRATION;
4067  *                  start_timer(TTL);
4068  *             END
4069  *             return;
4070  *        END (* case *)
4071  *   END (* procedure *)
4072  */
4073 static void
4074 smb_name_process_Pnode_packet(struct name_packet *packet,
4075     struct addr_entry *addr)
4076 {
4077 	struct name_entry 	*name;
4078 	struct name_entry 	*entry;
4079 	struct name_question 	*question;
4080 	struct resource_record 	*additional;
4081 
4082 	question = packet->question;
4083 	additional = packet->additional;
4084 
4085 	if (packet->info & NAME_NM_FLAGS_B) {
4086 		/*
4087 		 * always ignore UDP broadcast packets
4088 		 */
4089 		return;
4090 	}
4091 
4092 	switch (packet->info & NAME_OPCODE_OPCODE_MASK) {
4093 	case NAME_OPCODE_REFRESH:
4094 		/* Guard against malformed packets */
4095 		if ((question == 0) || (additional == 0))
4096 			break;
4097 		if (additional->name->addr_list.sin.sin_addr.s_addr == 0)
4098 			break;
4099 
4100 		name = question->name;
4101 		name->addr_list.ttl = additional->ttl;
4102 		name->attributes = additional->name->attributes;
4103 		name->addr_list.sin = additional->name->addr_list.sin;
4104 		name->addr_list.forw = name->addr_list.back = &name->addr_list;
4105 
4106 		if ((entry = smb_netbios_cache_lookup(name)) != 0) {
4107 			smb_netbios_cache_update_entry(entry, name);
4108 			smb_netbios_cache_unlock_entry(entry);
4109 		}
4110 		else
4111 			(void) smb_netbios_cache_insert(name);
4112 
4113 		(void) smb_send_name_registration_response(addr, packet, 0);
4114 		break;
4115 
4116 	case NAME_OPCODE_QUERY:
4117 		/*
4118 		 * This opcode covers both NAME_QUERY_REQUEST and
4119 		 * NODE_STATUS_REQUEST. They can be distinguished
4120 		 * based on the type of question entry.
4121 		 */
4122 
4123 		/* All query requests have to have question entry */
4124 		if (question == 0)
4125 			break;
4126 
4127 		if (question->question_type == NAME_QUESTION_TYPE_NB) {
4128 			name = question->name;
4129 			if ((entry = smb_netbios_cache_lookup(name)) != 0) {
4130 				/*
4131 				 * send response to the IP address and port
4132 				 * number from which the request was received.
4133 				 */
4134 				(void) smb_send_name_query_response(addr,
4135 				    packet, entry, 0);
4136 				smb_netbios_cache_unlock_entry(entry);
4137 			} else {
4138 				/*
4139 				 * send response to the requestor
4140 				 */
4141 				(void) smb_send_name_query_response(addr,
4142 				    packet, name, RCODE_NAM_ERR);
4143 			}
4144 		}
4145 		else
4146 		if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) {
4147 			/*
4148 			 * Name of "*" may be used to force node to
4149 			 * divulge status for administrative purposes
4150 			 */
4151 			name = question->name;
4152 			entry = 0;
4153 			if (NETBIOS_NAME_IS_STAR(name->name) ||
4154 			    ((entry = smb_netbios_cache_lookup(name)) != 0)) {
4155 				/*
4156 				 * send only those names that are
4157 				 * in the same scope as the scope
4158 				 * field in the request packet
4159 				 */
4160 				if (entry)
4161 					smb_netbios_cache_unlock_entry(entry);
4162 				(void) smb_send_node_status_response(addr,
4163 				    packet);
4164 			}
4165 		}
4166 		break;
4167 
4168 	default:
4169 		break;
4170 	}
4171 }
4172 
4173 /*
4174  * 5.1.3.5.  M-NODE INCOMING PACKET PROCESSING
4175  *
4176  *   Processing initiated by reception of packets at a M node
4177  *
4178  *   PROCEDURE process_incoming_packet(packet)
4179  *
4180  *   (*
4181  *    * Processing initiated by incoming packets at a M node
4182  *    *)
4183  *
4184  *   BEGIN
4185  *        CASE packet type of
4186  *
4187  *        NAME CONFLICT DEMAND:
4188  *             IF name exists in local name table THEN
4189  *                  mark name as in conflict;
4190  *             return;
4191  *
4192  *        NAME QUERY REQUEST:
4193  *             IF name exists in local name table THEN
4194  *             BEGIN (* name exists *)
4195  *
4196  *                  (*
4197  *                   * build packet
4198  *                   *)
4199  *                  ...
4200  *
4201  *                  (*
4202  *                   * send response to the IP address and port
4203  *                   * number from which the request was received.
4204  *                   *)
4205  *
4206  *                  send POSITIVE NAME QUERY RESPONSE ;
4207  *                  return;
4208  *             END (* exists *)
4209  *             ELSE
4210  *             BEGIN (* does not exist *)
4211  *
4212  *                  (*
4213  *                   * send response to the requestor
4214  *                   *)
4215  *
4216  *                  IF request NOT broadcast THEN
4217  *                       (*
4218  *                        * Don't send negative responses to
4219  *                        * queries sent by B nodes
4220  *                        *)
4221  *                       send NEGATIVE NAME QUERY RESPONSE ;
4222  *                  return;
4223  *             END (* does not exist *)
4224  *        NODE STATUS REQUEST:
4225  *             BEGIN
4226  *             (*
4227  *              * Name of "*" may be used to force node to
4228  *              * divulge status for administrative purposes
4229  *              *)
4230  *             IF name in local name table OR name = "*" THEN
4231  *                  (*
4232  *                   * Build response packet and
4233  *                   * send to requestor node
4234  *                   * Send only those names that are
4235  *                   * in the same scope as the scope
4236  *                   * in the request packet.
4237  *                   *)
4238  *
4239  *                  send NODE STATUS RESPONSE;
4240  *             END
4241  *
4242  *        NAME RELEASE REQUEST:
4243  *             (*
4244  *              * This will be received if the NAME wants to flush the
4245  *              * name from the local name table, or from the local
4246  *              * cache.
4247  *              *)
4248  *
4249  *             IF name exists in the local name table THEN
4250  *             BEGIN
4251  *                  delete name from local name table;
4252  *                  inform user that name has been deleted;
4253  *             END
4254  *        NAME REGISTRATION REQUEST (UNIQUE):
4255  *             IF name exists in local name table THEN
4256  *                  send NEGATIVE NAME REGISTRATION RESPONSE ;
4257  *        NAME REGISTRATION REQUEST (GROUP):
4258  *             IF name exists in local name table THEN
4259  *             BEGIN
4260  *                  IF local entry is a unique name THEN
4261  *                      send NEGATIVE NAME REGISTRATION RESPONSE ;
4262  *             END
4263  *        END (* case *)
4264  *   END (* procedure *)
4265  */
4266 static void
4267 smb_name_process_Mnode_packet(struct name_packet *packet,
4268     struct addr_entry *addr)
4269 {
4270 	if (packet->info & NAME_NM_FLAGS_B)
4271 		smb_name_process_Bnode_packet(packet, addr);
4272 	else
4273 		smb_name_process_Pnode_packet(packet, addr);
4274 }
4275 
4276 static void
4277 smb_name_process_Hnode_packet(struct name_packet *packet,
4278     struct addr_entry *addr)
4279 {
4280 	if (packet->info & NAME_NM_FLAGS_B)
4281 		smb_name_process_Bnode_packet(packet, addr);
4282 	else
4283 		smb_name_process_Pnode_packet(packet, addr);
4284 }
4285 
4286 
4287 /*
4288  * smb_netbios_name_tick
4289  *
4290  * Called once a second to handle name server timeouts.
4291  */
4292 void
4293 smb_netbios_name_tick(void)
4294 {
4295 	struct name_entry *name;
4296 	struct name_entry *entry;
4297 
4298 	(void) mutex_lock(&refresh_queue.mtx);
4299 	smb_netbios_cache_refresh(&refresh_queue);
4300 
4301 	while ((name = refresh_queue.head.forw) != &refresh_queue.head) {
4302 		QUEUE_CLIP(name);
4303 		if (IS_LOCAL(name->attributes)) {
4304 			if (IS_UNIQUE(name->attributes)) {
4305 				(void) smb_name_Pnode_refresh_name(name);
4306 			}
4307 		} else {
4308 			entry = smb_name_find_name(name);
4309 			smb_name_unlock_name(entry);
4310 		}
4311 		free(name);
4312 	}
4313 	(void) mutex_unlock(&refresh_queue.mtx);
4314 
4315 	smb_netbios_cache_reset_ttl();
4316 }
4317 
4318 
4319 /*
4320  * smb_name_find_name
4321  *
4322  * Lookup name cache for the given name.
4323  * If it's not in the cache it'll send a
4324  * name query request and then lookup the
4325  * cache again. Note that if a name is
4326  * returned it's locked and called MUST
4327  * unlock it by calling smb_name_unlock_name()
4328  */
4329 struct name_entry *
4330 smb_name_find_name(struct name_entry *name)
4331 {
4332 	struct name_entry *result;
4333 
4334 	if ((result = smb_netbios_cache_lookup(name)) == 0) {
4335 		switch (smb_node_type) {
4336 		case 'B':
4337 			(void) smb_name_Bnode_find_name(name);
4338 			break;
4339 		case 'P':
4340 			(void) smb_name_Pnode_find_name(name);
4341 			break;
4342 		case 'M':
4343 			(void) smb_name_Mnode_find_name(name);
4344 			break;
4345 		case 'H':
4346 		default:
4347 			(void) smb_name_Hnode_find_name(name);
4348 			break;
4349 		}
4350 		return (smb_netbios_cache_lookup(name));
4351 	}
4352 
4353 	return (result);
4354 }
4355 
4356 void
4357 smb_name_unlock_name(struct name_entry *name)
4358 {
4359 	smb_netbios_cache_unlock_entry(name);
4360 }
4361 
4362 int
4363 smb_name_add_name(struct name_entry *name)
4364 {
4365 	int			rc = 1;
4366 
4367 	smb_netbios_name_dump(name);
4368 
4369 	switch (smb_node_type) {
4370 	case 'B':
4371 		rc = smb_name_Bnode_add_name(name);
4372 		break;
4373 	case 'P':
4374 		rc = smb_name_Pnode_add_name(name);
4375 		break;
4376 	case 'M':
4377 		rc = smb_name_Mnode_add_name(name);
4378 		break;
4379 	case 'H':
4380 	default:
4381 		rc = smb_name_Hnode_add_name(name);
4382 		break;
4383 	}
4384 
4385 	if (rc >= 0)
4386 		(void) smb_netbios_cache_insert(name);
4387 
4388 	return (rc);
4389 }
4390 
4391 int
4392 smb_name_delete_name(struct name_entry *name)
4393 {
4394 	int			rc;
4395 	unsigned char type;
4396 
4397 	type = name->name[15];
4398 	if ((type != 0x00) && (type != 0x20)) {
4399 		syslog(LOG_ERR,
4400 		    "netbios: error trying to delete non-local name");
4401 		smb_netbios_name_logf(name);
4402 		name->attributes &= ~NAME_ATTR_LOCAL;
4403 		return (-1);
4404 	}
4405 
4406 	smb_netbios_cache_delete(name);
4407 
4408 	switch (smb_node_type) {
4409 	case 'B':
4410 		rc = smb_name_Bnode_delete_name(name);
4411 		break;
4412 	case 'P':
4413 		rc = smb_name_Pnode_delete_name(name);
4414 		break;
4415 	case 'M':
4416 		rc = smb_name_Mnode_delete_name(name);
4417 		break;
4418 	case 'H':
4419 	default:
4420 		rc = smb_name_Hnode_delete_name(name);
4421 		break;
4422 	}
4423 
4424 	if (rc > 0)
4425 		return (0);
4426 
4427 	return (-1);
4428 }
4429 
4430 typedef struct {
4431 	struct addr_entry *addr;
4432 	char *buf;
4433 	int length;
4434 } worker_param_t;
4435 
4436 /*
4437  * smb_netbios_worker
4438  *
4439  * Process incoming request/response packets for Netbios
4440  * name service (on port 138).
4441  */
4442 void *
4443 smb_netbios_worker(void *arg)
4444 {
4445 	worker_param_t *p = (worker_param_t *)arg;
4446 	struct addr_entry *addr = p->addr;
4447 	struct name_packet *packet;
4448 
4449 	if ((packet = smb_name_buf_to_packet(p->buf, p->length)) != 0) {
4450 		if (packet->info & NAME_OPCODE_R) {
4451 			/* Reply packet */
4452 			smb_reply_ready(packet, addr);
4453 			free(p->buf);
4454 			free(p);
4455 			return (0);
4456 		}
4457 
4458 		/* Request packet */
4459 		switch (smb_node_type) {
4460 		case 'B':
4461 			smb_name_process_Bnode_packet(packet, addr);
4462 			break;
4463 		case 'P':
4464 			smb_name_process_Pnode_packet(packet, addr);
4465 			break;
4466 		case 'M':
4467 			smb_name_process_Mnode_packet(packet, addr);
4468 			break;
4469 		case 'H':
4470 		default:
4471 			smb_name_process_Hnode_packet(packet, addr);
4472 			break;
4473 		}
4474 
4475 		if (packet->answer)
4476 			smb_netbios_name_freeaddrs(packet->answer->name);
4477 		free(packet);
4478 	} else {
4479 		syslog(LOG_DEBUG, "SmbNBNS: error decoding received packet");
4480 	}
4481 
4482 	free(addr);
4483 	free(p->buf);
4484 	free(p);
4485 	return (0);
4486 }
4487 
4488 static void
4489 smb_netbios_wins_config(char *ip)
4490 {
4491 	uint32_t ipaddr;
4492 
4493 	ipaddr = inet_addr(ip);
4494 	if (ipaddr != INADDR_NONE) {
4495 		smb_nbns[nbns_num].flags = ADDR_FLAG_VALID;
4496 		smb_nbns[nbns_num].sinlen = sizeof (struct sockaddr_in);
4497 		smb_nbns[nbns_num].sin.sin_family = AF_INET;
4498 		smb_nbns[nbns_num].sin.sin_addr.s_addr = ipaddr;
4499 		smb_nbns[nbns_num++].sin.sin_port =
4500 		    htons(NAME_SERVICE_UDP_PORT);
4501 		smb_node_type = SMB_NODETYPE_H;
4502 	}
4503 }
4504 
4505 static void
4506 smb_netbios_name_registration(void)
4507 {
4508 	nbcache_iter_t nbc_iter;
4509 	struct name_entry *name;
4510 	int rc;
4511 
4512 	rc = smb_netbios_cache_getfirst(&nbc_iter);
4513 	while (rc == 0) {
4514 		name = nbc_iter.nbc_entry;
4515 		(void) smb_netbios_name_logf(name);
4516 		if (IS_UNIQUE(name->attributes) && IS_LOCAL(name->attributes)) {
4517 			switch (smb_node_type) {
4518 			case SMB_NODETYPE_B:
4519 				(void) smb_name_Bnode_add_name(name);
4520 				break;
4521 			case SMB_NODETYPE_P:
4522 				(void) smb_name_Pnode_add_name(name);
4523 				break;
4524 			case SMB_NODETYPE_M:
4525 				(void) smb_name_Mnode_add_name(name);
4526 				break;
4527 			case SMB_NODETYPE_H:
4528 			default:
4529 				(void) smb_name_Hnode_add_name(name);
4530 				break;
4531 			}
4532 		}
4533 		free(name);
4534 		rc = smb_netbios_cache_getnext(&nbc_iter);
4535 	}
4536 }
4537 
4538 void
4539 smb_netbios_name_config(void)
4540 {
4541 	struct name_entry name;
4542 	char wins_ip[16];
4543 	smb_niciter_t ni;
4544 	int rc;
4545 
4546 	/* Start with no broadcast addresses */
4547 	bcast_num = 0;
4548 	bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS);
4549 
4550 	/* Add all of the broadcast addresses */
4551 	rc = smb_nic_getfirst(&ni);
4552 	while (rc == 0) {
4553 		if (ni.ni_nic.nic_smbflags &
4554 		    (SMB_NICF_ALIAS | SMB_NICF_NBEXCL)) {
4555 			rc = smb_nic_getnext(&ni);
4556 			continue;
4557 		}
4558 		smb_bcast_list[bcast_num].flags = ADDR_FLAG_VALID;
4559 		smb_bcast_list[bcast_num].attributes = NAME_ATTR_LOCAL;
4560 		smb_bcast_list[bcast_num].sinlen = sizeof (struct sockaddr_in);
4561 		smb_bcast_list[bcast_num].sin.sin_family = AF_INET;
4562 		smb_bcast_list[bcast_num].sin.sin_port =
4563 		    htons(NAME_SERVICE_UDP_PORT);
4564 		smb_bcast_list[bcast_num++].sin.sin_addr.s_addr =
4565 		    ni.ni_nic.nic_bcast;
4566 		rc = smb_nic_getnext(&ni);
4567 	}
4568 
4569 	/* Start with no WINS */
4570 	smb_node_type = SMB_NODETYPE_B;
4571 	nbns_num = 0;
4572 	bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS);
4573 
4574 	/* add any configured WINS */
4575 	(void) smb_config_getstr(SMB_CI_WINS_SRV1, wins_ip, sizeof (wins_ip));
4576 	smb_netbios_wins_config(wins_ip);
4577 	(void) smb_config_getstr(SMB_CI_WINS_SRV2, wins_ip, sizeof (wins_ip));
4578 	smb_netbios_wins_config(wins_ip);
4579 
4580 	if (smb_nic_getfirst(&ni) != 0)
4581 		return;
4582 
4583 	do {
4584 		if (ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL)
4585 			continue;
4586 
4587 		smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
4588 		    0x00, 0, ni.ni_nic.nic_ip, htons(DGM_SRVC_UDP_PORT),
4589 		    NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
4590 		(void) smb_netbios_cache_insert(&name);
4591 
4592 		smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
4593 		    0x20, 0, ni.ni_nic.nic_ip, htons(DGM_SRVC_UDP_PORT),
4594 		    NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
4595 		(void) smb_netbios_cache_insert(&name);
4596 	} while (smb_nic_getnext(&ni) == 0);
4597 
4598 	smb_netbios_name_registration();
4599 }
4600 
4601 void
4602 smb_netbios_name_unconfig(void)
4603 {
4604 	struct name_entry *name;
4605 
4606 	(void) mutex_lock(&delete_queue.mtx);
4607 	smb_netbios_cache_delete_locals(&delete_queue);
4608 
4609 	while ((name = delete_queue.head.forw) != &delete_queue.head) {
4610 		QUEUE_CLIP(name);
4611 		(void) smb_name_delete_name(name);
4612 		free(name);
4613 	}
4614 	(void) mutex_unlock(&delete_queue.mtx);
4615 }
4616 
4617 void
4618 smb_netbios_name_reconfig(void)
4619 {
4620 	smb_netbios_name_unconfig();
4621 	smb_netbios_name_config();
4622 }
4623 
4624 /*
4625  * process_incoming Function: void smb_netbios_name_service_daemon(void)
4626  *
4627  * Description:
4628  *
4629  *	Put test description here.
4630  *
4631  * Inputs:
4632  *	Nothing
4633  *
4634  * Returns:
4635  *	int	-> Description
4636  */
4637 /*ARGSUSED*/
4638 void *
4639 smb_netbios_name_service_daemon(void *arg)
4640 {
4641 	struct sockaddr_in	sin;
4642 	struct addr_entry 	*addr;
4643 	int			len;
4644 	int			flag = 1;
4645 	char 			*buf;
4646 	worker_param_t 		*worker_param;
4647 
4648 	/*
4649 	 * Initialize reply_queue
4650 	 */
4651 	bzero(&reply_queue, sizeof (reply_queue));
4652 	reply_queue.forw = reply_queue.back = &reply_queue;
4653 
4654 	if (!smb_netbios_cache_init())
4655 		return (0);
4656 
4657 	bcast_num = 0;
4658 	bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS);
4659 
4660 	if ((name_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
4661 		syslog(LOG_ERR,
4662 		    "smbd: Could not create AF_INET, SOCK_DGRAM, socket");
4663 		smb_netbios_cache_fini();
4664 		smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1);
4665 		return (0);
4666 	}
4667 
4668 	(void) setsockopt(name_sock, SOL_SOCKET, SO_BROADCAST, &flag,
4669 	    sizeof (flag));
4670 
4671 	bzero(&sin, sizeof (struct sockaddr_in));
4672 	sin.sin_family = AF_INET;
4673 	sin.sin_port = htons(NAME_SERVICE_UDP_PORT);
4674 	if (bind(name_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) {
4675 		syslog(LOG_ERR,
4676 		    "smbd: Bind to name service port %d failed (%d)",
4677 		    NAME_SERVICE_UDP_PORT, errno);
4678 		smb_netbios_cache_fini();
4679 		(void) close(name_sock);
4680 		smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1);
4681 		return (0);
4682 	}
4683 
4684 	smb_netbios_chg_status(NETBIOS_NAME_SVC_RUNNING, 1);
4685 
4686 	while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) ||
4687 	    (nb_status.state & NETBIOS_BROWSER_RUNNING)) {
4688 		if ((buf = malloc(MAX_DATAGRAM_LENGTH)) == 0) {
4689 			/* Sleep for 10 sec and try again */
4690 			(void) sleep(10);
4691 			continue;
4692 		}
4693 		if ((addr = (struct addr_entry *)
4694 		    malloc(sizeof (struct addr_entry))) == 0) {
4695 			/* Sleep for 10 sec and try again */
4696 			free(buf);
4697 			(void) sleep(10);
4698 			continue;
4699 		}
4700 ignore:		bzero(addr, sizeof (struct addr_entry));
4701 		addr->sinlen = sizeof (addr->sin);
4702 		addr->forw = addr->back = addr;
4703 
4704 		if ((len = recvfrom(name_sock, buf, MAX_DATAGRAM_LENGTH,
4705 		    0, (struct sockaddr *)&addr->sin, &addr->sinlen)) < 0) {
4706 			if (errno == ENOMEM || errno == ENFILE ||
4707 			    errno == EMFILE) {
4708 				/* Sleep for 10 sec and try again */
4709 				free(buf);
4710 				free(addr);
4711 				(void) sleep(10);
4712 				continue;
4713 			}
4714 			syslog(LOG_ERR,
4715 				"smbd: NETBIOS name service - recvfrom failed");
4716 			free(buf);
4717 			free(addr);
4718 			smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1);
4719 			goto shutdown;
4720 		}
4721 
4722 		/* Ignore any incoming packets from myself... */
4723 		if (smb_nic_exists(addr->sin.sin_addr.s_addr, B_FALSE))
4724 			goto ignore;
4725 
4726 		/*
4727 		 * Launch a netbios worker to process the received packet.
4728 		 */
4729 		worker_param = (worker_param_t *)
4730 		    malloc(sizeof (worker_param_t));
4731 		if (worker_param) {
4732 			pthread_t worker;
4733 			pthread_attr_t tattr;
4734 
4735 			worker_param->addr = addr;
4736 			worker_param->buf = buf;
4737 			worker_param->length = len;
4738 
4739 			(void) pthread_attr_init(&tattr);
4740 			(void) pthread_attr_setdetachstate(&tattr,
4741 			    PTHREAD_CREATE_DETACHED);
4742 			(void) pthread_create(&worker, &tattr,
4743 			    smb_netbios_worker, worker_param);
4744 			(void) pthread_attr_destroy(&tattr);
4745 		}
4746 	}
4747 
4748 shutdown:
4749 	smb_netbios_chg_status(NETBIOS_NAME_SVC_RUNNING, 0);
4750 
4751 	(void) mutex_lock(&nb_status.mtx);
4752 	while (nb_status.state & NETBIOS_BROWSER_RUNNING)
4753 		(void) cond_wait(&nb_status.cv, &nb_status.mtx);
4754 	(void) mutex_unlock(&nb_status.mtx);
4755 
4756 	if ((nb_status.state & NETBIOS_NAME_SVC_FAILED) == 0) {
4757 		/* this might delay shutdown, do we want to do this? */
4758 		/*
4759 		 * it'll send name release requests but nobody's waiting
4760 		 * for response and it'll eventually timeout.
4761 		 */
4762 		smb_netbios_name_unconfig();
4763 	}
4764 	(void) close(name_sock);
4765 	smb_netbios_cache_fini();
4766 	syslog(LOG_DEBUG, "smbd: Netbios Name Service is down\n");
4767 	return (0);
4768 }
4769