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