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