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