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