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