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