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