8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / smbsrv / libsmbns / common / smbns_netbios_name.c
blob063a505504e51628a65798758e276cc63ae3d08e
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
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.
28 * NetBIOS name resolution node types.
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.
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.
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).
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).
48 * NetBIOS Name Service Protocols
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.
56 * A RESPONSE packet is always sent to the source UDP port and source IP
57 * address of the request packet.
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.
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.
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>
77 #include <smbsrv/libsmbns.h>
78 #include <smbns_netbios.h>
81 * RFC 1002 4.2.1.1. HEADER
83 #define QUESTION_TYPE_NETBIOS_GENERAL 0x20
84 #define QUESTION_TYPE_NETBIOS_STATUS 0x21
86 #define QUESTION_CLASS_INTERNET 0x0001
89 * RFC 1002 4.2.1.3. RESOURCE RECORD
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
99 * RESOURCE RECORD RR_CLASS field definitions
101 #define RR_CLASS_INTERNET_CLASS 0x0001
104 * NB_FLAGS field of the RESOURCE RECORD RDATA field for RR_TYPE of NB.
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
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
124 #define MAX_NETBIOS_REPLY_DATA_SIZE 500
126 #define NAME_HEADER_SIZE 12
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;
137 static nbt_name_reply_t reply_queue;
138 static mutex_t rq_mtx;
139 static cond_t rq_cv;
141 static mutex_t nbt_name_config_mtx;
143 static name_queue_t delete_queue;
144 static name_queue_t refresh_queue;
146 static int name_sock = 0;
148 static int bcast_num = 0;
149 static int nbns_num = 0;
150 static addr_entry_t smb_bcast_list[SMB_PI_MAX_NETWORKS];
151 static addr_entry_t smb_nbns[SMB_PI_MAX_WINS];
153 static int smb_netbios_process_response(uint16_t, addr_entry_t *,
154 struct name_packet *, uint32_t);
156 static int smb_send_name_service_packet(addr_entry_t *addr,
157 struct name_packet *packet);
160 * Allocate a transaction id.
162 static uint16_t
163 smb_netbios_name_trn_id(void)
165 static uint16_t trn_id;
166 static mutex_t trn_id_mtx;
168 (void) mutex_lock(&trn_id_mtx);
170 do {
171 ++trn_id;
172 } while (trn_id == 0 || trn_id == (uint16_t)-1);
174 (void) mutex_unlock(&trn_id_mtx);
175 return (trn_id);
178 static int
179 smb_end_node_challenge(nbt_name_reply_t *reply_info)
181 int rc;
182 uint32_t retry;
183 uint16_t tid;
184 struct resource_record *answer;
185 struct name_question question;
186 addr_entry_t *addr;
187 struct name_entry *destination;
188 struct name_packet packet;
189 struct timespec st;
192 * The response packet has in it the address of the presumed owner
193 * of the name. Challenge that owner. If owner either does not
194 * respond or indicates that they no longer own the name, claim the
195 * name. Otherwise, the name cannot be claimed.
198 if ((answer = reply_info->packet->answer) == 0)
199 return (-1);
201 destination = answer->name;
202 question.name = answer->name;
204 packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST;
205 packet.qdcount = 1; /* question entries */
206 packet.question = &question;
207 packet.ancount = 0; /* answer recs */
208 packet.answer = NULL;
209 packet.nscount = 0; /* authority recs */
210 packet.authority = NULL;
211 packet.arcount = 0; /* additional recs */
212 packet.additional = NULL;
214 addr = &destination->addr_list;
215 for (retry = 0; retry < UCAST_REQ_RETRY_COUNT; retry++) {
216 tid = smb_netbios_name_trn_id();
217 packet.name_trn_id = tid;
218 if (smb_send_name_service_packet(addr, &packet) >= 0) {
219 if ((rc = smb_netbios_process_response(tid, addr,
220 &packet, UCAST_REQ_RETRY_TIMEOUT)) != 0)
221 return (rc);
223 st.tv_sec = 0;
224 st.tv_nsec = (UCAST_REQ_RETRY_TIMEOUT * 1000000);
225 (void) nanosleep(&st, 0);
227 /* No reply */
228 return (0);
231 static nbt_name_reply_t *
232 smb_name_get_reply(uint16_t tid, uint32_t timeout)
234 uint16_t info;
235 struct resource_record *answer;
236 nbt_name_reply_t *reply;
237 uint32_t wait_time, to_save; /* in millisecond */
238 struct timeval wt;
239 timestruc_t to;
241 to_save = timeout;
242 reply = malloc(sizeof (nbt_name_reply_t));
243 if (reply != NULL) {
244 reply->reply_ready = B_FALSE;
245 reply->name_trn_id = tid;
246 (void) mutex_lock(&rq_mtx);
247 QUEUE_INSERT_TAIL(&reply_queue, reply);
248 (void) mutex_unlock(&rq_mtx);
250 for (;;) {
251 (void) gettimeofday(&wt, 0);
252 wait_time = wt.tv_usec / 1000;
254 to.tv_sec = 0;
255 to.tv_nsec = timeout * 1000000;
256 (void) mutex_lock(&rq_mtx);
257 (void) cond_reltimedwait(&rq_cv, &rq_mtx, &to);
258 (void) mutex_unlock(&rq_mtx);
260 if (reply->reply_ready) {
261 info = reply->packet->info;
262 if (PACKET_TYPE(info) == WACK_RESPONSE) {
263 answer = reply->packet->answer;
264 wait_time = (answer) ?
265 TO_MILLISECONDS(answer->ttl) :
266 DEFAULT_TTL;
267 free(reply->addr);
268 free(reply->packet);
269 timeout = to_save + wait_time;
270 reply->reply_ready = B_FALSE;
271 reply->name_trn_id = tid;
272 (void) mutex_lock(&rq_mtx);
273 QUEUE_INSERT_TAIL(&reply_queue, reply);
274 (void) mutex_unlock(&rq_mtx);
275 continue;
277 return (reply);
279 (void) gettimeofday(&wt, 0);
280 wait_time = (wt.tv_usec / 1000) - wait_time;
281 if (wait_time >= timeout) {
282 (void) mutex_lock(&rq_mtx);
283 QUEUE_CLIP(reply);
284 (void) mutex_unlock(&rq_mtx);
285 free(reply);
286 break;
288 timeout -= wait_time;
292 return (0);
295 static void
296 smb_reply_ready(struct name_packet *packet, addr_entry_t *addr)
298 nbt_name_reply_t *reply;
299 struct resource_record *answer;
301 (void) mutex_lock(&rq_mtx);
302 for (reply = reply_queue.forw; reply != &reply_queue;
303 reply = reply->forw) {
304 if (reply->name_trn_id == packet->name_trn_id) {
305 QUEUE_CLIP(reply);
307 reply->addr = addr;
308 reply->packet = packet;
309 reply->reply_ready = B_TRUE;
310 (void) cond_signal(&rq_cv);
311 (void) mutex_unlock(&rq_mtx);
312 return;
315 (void) mutex_unlock(&rq_mtx);
317 /* Presumably nobody is waiting any more... */
318 free(addr);
320 answer = packet->answer;
321 if (answer)
322 smb_netbios_name_freeaddrs(answer->name);
323 free(packet);
326 static int
327 smb_netbios_process_response(uint16_t tid, addr_entry_t *addr,
328 struct name_packet *packet, uint32_t timeout)
330 int rc = 0;
331 uint16_t info;
332 nbt_name_reply_t *reply;
333 struct resource_record *answer;
334 struct name_entry *name;
335 struct name_entry *entry;
336 struct name_question *question;
337 uint32_t ttl;
339 if ((reply = smb_name_get_reply(tid, timeout)) == 0) {
340 return (0); /* No reply: retry */
342 info = reply->packet->info;
343 answer = reply->packet->answer;
345 /* response */
346 switch (PACKET_TYPE(info)) {
347 case NAME_QUERY_RESPONSE:
348 if (POSITIVE_RESPONSE(info)) {
349 addr = &answer->name->addr_list;
350 do {
352 * Make sure that remote name is not
353 * flagged local
355 addr->attributes &= ~NAME_ATTR_LOCAL;
357 if (answer->ttl)
358 addr->ttl = answer->ttl;
359 else
360 addr->ttl = DEFAULT_TTL;
361 addr->refresh_ttl = TO_SECONDS(addr->ttl);
362 addr->ttl = addr->refresh_ttl;
364 addr = addr->forw;
365 } while (addr != &answer->name->addr_list);
366 smb_netbios_name_logf(answer->name);
367 (void) smb_netbios_cache_insert_list(answer->name);
368 rc = 1;
369 } else {
370 rc = -1;
372 break;
374 case NAME_REGISTRATION_RESPONSE:
375 if (NEGATIVE_RESPONSE(info)) {
376 if (RCODE(info) == RCODE_CFT_ERR) {
377 if (answer == 0) {
378 rc = -RCODE(info);
379 break;
382 name = answer->name;
383 entry = smb_netbios_cache_lookup(name);
384 if (entry) {
386 * a name in the state "conflict
387 * detected" does not "logically" exist
388 * on that node. No further session
389 * will be accepted on that name.
390 * No datagrams can be sent against
391 * that name.
392 * Such an entry will not be used for
393 * purposes of processing incoming
394 * request packets.
395 * The only valid user NetBIOS operation
396 * against such a name is DELETE NAME.
398 entry->attributes |= NAME_ATTR_CONFLICT;
399 syslog(LOG_DEBUG,
400 "nbns: name conflict: %15.15s",
401 entry->name);
402 smb_netbios_cache_unlock_entry(entry);
405 rc = -RCODE(info);
406 break;
410 * name can be added:
411 * adjust refresh timeout value,
412 * TTL, for this name
414 question = packet->question;
415 ttl = (answer && answer->ttl) ? answer->ttl : DEFAULT_TTL;
416 ttl = TO_SECONDS(ttl);
417 if ((entry = smb_netbios_cache_lookup(question->name)) != 0) {
418 addr = &entry->addr_list;
419 do {
420 if ((addr->refresh_ttl == 0) ||
421 (ttl < addr->refresh_ttl))
422 addr->refresh_ttl = addr->ttl = ttl;
423 addr = addr->forw;
424 } while (addr != &entry->addr_list);
425 smb_netbios_cache_unlock_entry(entry);
428 rc = 1;
429 break;
431 case NAME_RELEASE_RESPONSE:
432 rc = 1;
433 break;
435 case END_NODE_CHALLENGE_REGISTRATION_REQUEST:
437 * The response packet has in it the
438 * address of the presumed owner of the
439 * name. Challenge that owner. If
440 * owner either does not respond or
441 * indicates that they no longer own the
442 * name, claim the name. Otherwise,
443 * the name cannot be claimed.
445 rc = smb_end_node_challenge(reply);
446 break;
448 default:
449 rc = 0;
450 break;
453 if (answer)
454 smb_netbios_name_freeaddrs(answer->name);
455 free(reply->addr);
456 free(reply->packet);
457 free(reply);
458 return (rc); /* retry */
462 * smb_name_buf_from_packet
464 * Description:
465 * Convert a NetBIOS Name Server Packet Block (npb)
466 * into the bits and bytes destined for the wire.
467 * The "buf" is used as a heap.
469 * Inputs:
470 * char * buf -> Buffer, from the wire
471 * unsigned n_buf -> Length of 'buf'
472 * name_packet *npb -> Packet block, decode into
473 * unsigned n_npb -> Max bytes in 'npb'
475 * Returns:
476 * >0 -> Encode successful, value is length of packet in "buf"
477 * -1 -> Hard error, can not possibly encode
478 * -2 -> Need more memory in buf -- it's too small
480 static int
481 smb_name_buf_from_packet(unsigned char *buf, int n_buf,
482 struct name_packet *npb)
484 addr_entry_t *raddr;
485 unsigned char *heap = buf;
486 unsigned char *end_heap = heap + n_buf;
487 unsigned char *dnptrs[32];
488 unsigned char comp_name_buf[MAX_NAME_LENGTH];
489 unsigned int tmp;
490 int i, step;
492 if (n_buf < NAME_HEADER_SIZE)
493 return (-1); /* no header, impossible */
495 dnptrs[0] = heap;
496 dnptrs[1] = 0;
498 BE_OUT16(heap, npb->name_trn_id);
499 heap += 2;
501 BE_OUT16(heap, npb->info);
502 heap += 2;
504 BE_OUT16(heap, npb->qdcount);
505 heap += 2;
507 BE_OUT16(heap, npb->ancount);
508 heap += 2;
510 BE_OUT16(heap, npb->nscount);
511 heap += 2;
513 BE_OUT16(heap, npb->arcount);
514 heap += 2;
516 for (i = 0; i < npb->qdcount; i++) {
517 if ((heap + 34 + 4) > end_heap)
518 return (-2);
520 (void) smb_first_level_name_encode(npb->question[i].name,
521 comp_name_buf, sizeof (comp_name_buf));
522 (void) strcpy((char *)heap, (char *)comp_name_buf);
523 heap += strlen((char *)comp_name_buf) + 1;
525 BE_OUT16(heap, npb->question[i].question_type);
526 heap += 2;
528 BE_OUT16(heap, npb->question[i].question_class);
529 heap += 2;
532 for (step = 1; step <= 3; step++) {
533 struct resource_record *nrr;
534 int n;
536 /* truly ugly, but saves code copying */
537 if (step == 1) {
538 n = npb->ancount;
539 nrr = npb->answer;
540 } else if (step == 2) {
541 n = npb->nscount;
542 nrr = npb->authority;
543 } else { /* step == 3 */
544 n = npb->arcount;
545 nrr = npb->additional;
548 for (i = 0; i < n; i++) {
549 if ((heap + 34 + 10) > end_heap)
550 return (-2);
552 (void) smb_first_level_name_encode(nrr->name,
553 comp_name_buf, sizeof (comp_name_buf));
554 (void) strcpy((char *)heap, (char *)comp_name_buf);
555 heap += strlen((char *)comp_name_buf) + 1;
557 BE_OUT16(heap, nrr[i].rr_type);
558 heap += 2;
560 BE_OUT16(heap, nrr[i].rr_class);
561 heap += 2;
563 BE_OUT32(heap, nrr[i].ttl);
564 heap += 4;
566 BE_OUT16(heap, nrr[i].rdlength);
567 heap += 2;
569 if ((tmp = nrr[i].rdlength) > 0) {
570 if ((heap + tmp) > end_heap)
571 return (-2);
573 if (nrr[i].rr_type == NAME_RR_TYPE_NB &&
574 nrr[i].rr_class == NAME_RR_CLASS_IN &&
575 tmp >= 6 && nrr[i].rdata == 0) {
576 tmp = nrr[i].name->attributes &
577 (NAME_ATTR_GROUP |
578 NAME_ATTR_OWNER_NODE_TYPE);
579 BE_OUT16(heap, tmp);
580 heap += 2;
582 raddr = &nrr[i].name->addr_list;
583 (void) memcpy(heap,
584 &raddr->sin.sin_addr.s_addr,
585 sizeof (uint32_t));
586 heap += 4;
587 } else {
588 bcopy(nrr[i].rdata, heap, tmp);
589 heap += tmp;
594 return (heap - buf);
598 * strnchr
600 * Lookup for character 'c' in first 'n' chars of string 's'.
601 * Returns pointer to the found char, otherwise returns 0.
603 static char *
604 strnchr(const char *s, char c, int n)
606 char *ps = (char *)s;
607 char *es = (char *)s + n;
609 while (ps < es && *ps) {
610 if (*ps == c)
611 return (ps);
613 ++ps;
616 if (*ps == '\0' && c == '\0')
617 return (ps);
619 return (0);
622 static boolean_t
623 is_multihome(char *name)
625 return (smb_nic_getnum(name) > 1);
629 * smb_netbios_getname
631 * Get the Netbios name part of the given record.
632 * Does some boundary checks.
634 * Returns the name length on success, otherwise
635 * returns 0.
637 static int
638 smb_netbios_getname(char *name, char *buf, char *buf_end)
640 char *name_end;
641 int name_len;
643 if (buf >= buf_end) {
644 /* no room for a NB name */
645 return (0);
648 name_end = strnchr(buf, '\0', buf_end - buf + 1);
649 if (name_end == 0) {
650 /* not a valid NB name */
651 return (0);
654 name_len = name_end - buf + 1;
656 (void) strlcpy(name, buf, name_len);
657 return (name_len);
661 * smb_name_buf_to_packet
663 * Convert the bits and bytes that came from the wire into a NetBIOS
664 * Name Server Packet Block (npb). The "block" is used as a heap.
666 * Returns a pointer to a name packet on success. Otherwise, returns
667 * a NULL pointer.
669 static struct name_packet *
670 smb_name_buf_to_packet(char *buf, int n_buf)
672 struct name_packet *npb;
673 unsigned char *heap;
674 unsigned char *scan = (unsigned char *)buf;
675 unsigned char *scan_end = scan + n_buf;
676 char name_buf[MAX_NAME_LENGTH];
677 struct resource_record *nrr = 0;
678 int rc, i, n, nn, ns;
679 uint16_t name_trn_id, info;
680 uint16_t qdcount, ancount, nscount, arcount;
681 addr_entry_t *next;
682 int name_len;
684 if (n_buf < NAME_HEADER_SIZE) {
685 /* truncated header */
686 syslog(LOG_DEBUG, "nbns: short packet (%d bytes)", n_buf);
687 return (NULL);
690 name_trn_id = BE_IN16(scan); scan += 2;
691 info = BE_IN16(scan); scan += 2;
692 qdcount = BE_IN16(scan); scan += 2;
693 ancount = BE_IN16(scan); scan += 2;
694 nscount = BE_IN16(scan); scan += 2;
695 arcount = BE_IN16(scan); scan += 2;
697 ns = sizeof (struct name_entry);
698 n = n_buf + sizeof (struct name_packet) +
699 ((unsigned)qdcount * (sizeof (struct name_question) + ns)) +
700 ((unsigned)ancount * (sizeof (struct resource_record) + ns)) +
701 ((unsigned)nscount * (sizeof (struct resource_record) + ns)) +
702 ((unsigned)arcount * (sizeof (struct resource_record) + ns));
704 if ((npb = malloc(n)) == NULL)
705 return (NULL);
707 bzero(npb, n);
708 heap = npb->block_data;
709 npb->name_trn_id = name_trn_id;
710 npb->info = info;
711 npb->qdcount = qdcount;
712 npb->ancount = ancount;
713 npb->nscount = nscount;
714 npb->arcount = arcount;
716 /* scan is in position for question entries */
719 * Measure the space needed for the tables
721 if (qdcount > 0) {
722 /* LINTED - E_BAD_PTR_CAST_ALIGN */
723 npb->question = (struct name_question *)heap;
724 heap += qdcount * sizeof (struct name_question);
725 for (i = 0; i < qdcount; i++) {
726 /* LINTED - E_BAD_PTR_CAST_ALIGN */
727 npb->question[i].name = (struct name_entry *)heap;
728 heap += sizeof (struct name_entry);
732 /* LINTED - E_BAD_PTR_CAST_ALIGN */
733 nrr = (struct resource_record *)heap;
735 if (ancount > 0) {
736 /* LINTED - E_BAD_PTR_CAST_ALIGN */
737 npb->answer = (struct resource_record *)heap;
738 heap += ancount * sizeof (struct resource_record);
741 if (nscount > 0) {
742 /* LINTED - E_BAD_PTR_CAST_ALIGN */
743 npb->authority = (struct resource_record *)heap;
744 heap += nscount * sizeof (struct resource_record);
747 if (arcount > 0) {
748 /* LINTED - E_BAD_PTR_CAST_ALIGN */
749 npb->additional = (struct resource_record *)heap;
750 heap += arcount * sizeof (struct resource_record);
754 * Populate each resource_record's .name field.
755 * Done as a second pass so that all resource records
756 * (answer, authority, additional) are consecutive via nrr[i].
758 for (i = 0; i < (ancount + nscount + arcount); i++) {
759 /* LINTED - E_BAD_PTR_CAST_ALIGN */
760 nrr[i].name = (struct name_entry *)heap;
761 heap += sizeof (struct name_entry);
765 for (i = 0; i < npb->qdcount; i++) {
766 name_len = smb_netbios_getname(name_buf, (char *)scan,
767 (char *)scan_end);
768 if (name_len <= 0) {
769 free(npb);
770 return (NULL);
773 smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
774 npb->question[i].name);
775 rc = smb_first_level_name_decode((unsigned char *)name_buf,
776 npb->question[i].name);
777 if (rc < 0) {
778 /* Couldn't decode the question name */
779 free(npb);
780 return (NULL);
783 scan += name_len;
784 if (scan + 4 > scan_end) {
785 /* no room for Question Type(2) and Class(2) fields */
786 free(npb);
787 return (NULL);
790 npb->question[i].question_type = BE_IN16(scan); scan += 2;
791 npb->question[i].question_class = BE_IN16(scan); scan += 2;
795 * Cheat. Remaining sections are of the same resource_record
796 * format. Table space is consecutive.
799 for (i = 0; i < (ancount + nscount + arcount); i++) {
800 if (scan[0] == 0xc0) {
801 /* Namebuf is reused... */
802 rc = 2;
803 } else {
804 name_len = smb_netbios_getname(name_buf, (char *)scan,
805 (char *)scan_end);
806 if (name_len <= 0) {
807 free(npb);
808 return (NULL);
810 rc = name_len;
812 scan += rc;
814 if (scan + 10 > scan_end) {
816 * no room for RR_TYPE (2), RR_CLASS (2), TTL (4) and
817 * RDLENGTH (2) fields.
819 free(npb);
820 return (NULL);
823 smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
824 nrr[i].name);
825 if ((rc = smb_first_level_name_decode((unsigned char *)name_buf,
826 nrr[i].name)) < 0) {
827 free(npb);
828 return (NULL);
831 nrr[i].rr_type = BE_IN16(scan); scan += 2;
832 nrr[i].rr_class = BE_IN16(scan); scan += 2;
833 nrr[i].ttl = BE_IN32(scan); scan += 4;
834 nrr[i].rdlength = BE_IN16(scan); scan += 2;
836 if ((n = nrr[i].rdlength) > 0) {
837 if ((scan + n) > scan_end) {
838 /* no room for RDATA */
839 free(npb);
840 return (NULL);
842 bcopy(scan, heap, n);
844 nn = n;
845 if (nrr[i].rr_type == 0x0020 &&
846 nrr[i].rr_class == 0x01 && n >= 6) {
847 while (nn) {
848 if (nn == 6)
849 next = &nrr[i].name->addr_list;
850 else {
851 next = malloc(
852 sizeof (addr_entry_t));
853 if (next == 0) {
854 /* not enough memory */
855 free(npb);
856 return (NULL);
858 QUEUE_INSERT_TAIL(
859 &nrr[i].name->addr_list,
860 next);
862 nrr[i].name->attributes =
863 BE_IN16(scan);
864 next->sin.sin_family = AF_INET;
865 next->sinlen = sizeof (next->sin);
866 (void) memcpy(
867 &next->sin.sin_addr.s_addr,
868 scan + 2, sizeof (uint32_t));
869 next->sin.sin_port =
870 htons(IPPORT_NETBIOS_DGM);
871 nn -= 6;
872 scan += 6;
874 } else {
875 nrr[i].rdata = heap;
876 scan += n;
878 heap += n;
881 return (npb);
885 * smb_send_name_service_packet
887 * Description:
889 * Send out a name service packet to proper destination.
891 * Inputs:
892 * struct netbios_name *dest -> NETBIOS name of destination
893 * struct name_packet *packet -> Packet to send
895 * Returns:
896 * success -> >0
897 * failure -> <=0
899 static int
900 smb_send_name_service_packet(addr_entry_t *addr, struct name_packet *packet)
902 unsigned char buf[MAX_DATAGRAM_LENGTH];
903 int len;
905 if ((len = smb_name_buf_from_packet(buf, sizeof (buf), packet)) < 0) {
906 errno = EINVAL;
907 return (-1);
910 return (sendto(name_sock, buf, len, MSG_EOR,
911 (struct sockaddr *)&addr->sin, addr->sinlen));
915 * smb_netbios_send_rcv
917 * This function sends the given NetBIOS packet to the given
918 * address and get back the response. If send operation is not
919 * successful, it's repeated 'retries' times.
921 * Returns:
922 * 0 Unsuccessful send operation; no reply
923 * 1 Got reply
925 static int
926 smb_netbios_send_rcv(int bcast, addr_entry_t *destination,
927 struct name_packet *packet, uint32_t retries, uint32_t timeout)
929 uint32_t retry;
930 uint16_t tid;
931 struct timespec st;
932 int rc;
934 for (retry = 0; retry < retries; retry++) {
935 if ((destination->flags & ADDR_FLAG_VALID) == 0)
936 return (0);
938 tid = smb_netbios_name_trn_id();
939 packet->name_trn_id = tid;
940 if (smb_send_name_service_packet(destination, packet) >= 0) {
941 rc = smb_netbios_process_response(tid, destination,
942 packet, timeout);
944 if ((rc > 0) || (bcast == BROADCAST))
945 return (1);
947 if (rc != 0)
948 return (0);
951 st.tv_sec = 0;
952 st.tv_nsec = (timeout * 1000000);
953 (void) nanosleep(&st, 0);
956 return (0);
960 * RFC 1002 4.2.2. NAME REGISTRATION REQUEST
962 static int
963 smb_send_name_registration_request(int bcast, struct name_question *question,
964 struct resource_record *additional)
966 int gotreply = 0;
967 uint32_t retries;
968 uint32_t timeout;
969 addr_entry_t *destination;
970 struct name_packet packet;
971 unsigned char type;
972 int i, addr_num, rc;
974 type = question->name->name[15];
975 if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
976 syslog(LOG_DEBUG, "nbns: name registration bad type (0x%02x)",
977 type);
978 smb_netbios_name_logf(question->name);
979 question->name->attributes &= ~NAME_ATTR_LOCAL;
980 return (-1);
983 if (bcast == BROADCAST) {
984 if (bcast_num == 0)
985 return (0);
986 destination = smb_bcast_list;
987 addr_num = bcast_num;
988 retries = BCAST_REQ_RETRY_COUNT;
989 timeout = BCAST_REQ_RETRY_TIMEOUT;
990 packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_BROADCAST;
991 } else {
992 if (nbns_num == 0)
993 return (0);
994 destination = smb_nbns;
995 addr_num = nbns_num;
996 retries = UCAST_REQ_RETRY_COUNT;
997 timeout = UCAST_REQ_RETRY_TIMEOUT;
998 packet.info = NAME_REGISTRATION_REQUEST | NM_FLAGS_UNICAST;
1001 packet.qdcount = 1; /* question entries */
1002 packet.question = question;
1003 packet.ancount = 0; /* answer recs */
1004 packet.answer = NULL;
1005 packet.nscount = 0; /* authority recs */
1006 packet.authority = NULL;
1007 packet.arcount = 1; /* additional recs */
1008 packet.additional = additional;
1010 if (IS_UNIQUE(question->name->attributes) &&
1011 (is_multihome((char *)(question->name->name))))
1012 packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST;
1014 for (i = 0; i < addr_num; i++) {
1016 * Only register with the Primary WINS server,
1017 * unless we got no reply.
1019 if ((bcast == UNICAST) && gotreply)
1020 break;
1022 rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1023 retries, timeout);
1024 if (rc == 1)
1025 gotreply = 1;
1028 return (gotreply);
1032 * RFC 1002 4.2.4. NAME REFRESH REQUEST
1034 /*ARGSUSED*/
1035 static int
1036 smb_send_name_refresh_request(int bcast, struct name_question *question,
1037 struct resource_record *additional, int force)
1039 int rc = 0;
1040 int gotreply = 0;
1041 uint32_t retries;
1042 uint32_t timeout;
1043 addr_entry_t *addr;
1044 addr_entry_t *destination;
1045 struct name_packet packet;
1046 unsigned char type;
1047 int i, addr_num, q_addrs = 0;
1049 type = question->name->name[15];
1050 if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
1051 syslog(LOG_DEBUG, "nbns: name refresh bad type (0x%02x)", type);
1052 smb_netbios_name_logf(question->name);
1053 question->name->attributes &= ~NAME_ATTR_LOCAL;
1054 return (-1);
1056 switch (bcast) {
1057 case BROADCAST :
1058 if (bcast_num == 0)
1059 return (-1);
1060 destination = smb_bcast_list;
1061 addr_num = bcast_num;
1062 retries = BCAST_REQ_RETRY_COUNT;
1063 timeout = BCAST_REQ_RETRY_TIMEOUT;
1064 packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_BROADCAST;
1065 break;
1067 case UNICAST :
1068 if (nbns_num == 0)
1069 return (-1);
1070 destination = smb_nbns;
1071 addr_num = nbns_num;
1072 retries = UCAST_REQ_RETRY_COUNT;
1073 timeout = UCAST_REQ_RETRY_TIMEOUT;
1074 packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST;
1075 break;
1077 default:
1078 destination = &question->name->addr_list;
1080 * the value of addr_num is irrelvant here, because
1081 * the code is going to do special_process so it doesn't
1082 * need the addr_num. We set a value here just to avoid
1083 * compiler warning.
1085 addr_num = 0;
1086 retries = UCAST_REQ_RETRY_COUNT;
1087 timeout = UCAST_REQ_RETRY_TIMEOUT;
1088 packet.info = NAME_REFRESH_REQUEST | NM_FLAGS_UNICAST;
1089 q_addrs = 1;
1090 break;
1093 if (IS_UNIQUE(question->name->attributes) &&
1094 (is_multihome((char *)(question->name->name))))
1095 packet.info |= NAME_MULTIHOME_REGISTRATION_REQUEST;
1097 packet.qdcount = 1; /* question entries */
1098 packet.question = question;
1099 packet.ancount = 0; /* answer recs */
1100 packet.answer = NULL;
1101 packet.nscount = 0; /* authority recs */
1102 packet.authority = NULL;
1103 packet.arcount = 1; /* additional recs */
1104 packet.additional = additional;
1106 if (q_addrs)
1107 goto special_process;
1109 for (i = 0; i < addr_num; i++) {
1110 rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1111 retries, timeout);
1112 if (rc == 1)
1113 gotreply = 1;
1116 return (gotreply);
1118 special_process:
1119 addr = destination;
1120 do {
1121 rc = smb_netbios_send_rcv(bcast, addr, &packet,
1122 retries, timeout);
1123 if (rc == 1)
1124 gotreply = 1;
1125 addr = addr->forw;
1126 } while (addr != destination);
1128 return (gotreply);
1132 * RFC 1002 4.2.5. POSITIVE NAME REGISTRATION RESPONSE
1133 * RFC 1002 4.2.6. NEGATIVE NAME REGISTRATION RESPONSE
1135 static int
1136 smb_send_name_registration_response(addr_entry_t *addr,
1137 struct name_packet *original_packet, uint16_t rcode)
1139 struct name_packet packet;
1140 struct resource_record answer;
1142 bzero(&packet, sizeof (struct name_packet));
1143 bzero(&answer, sizeof (struct resource_record));
1145 packet.name_trn_id = original_packet->name_trn_id;
1146 packet.info = NAME_REGISTRATION_RESPONSE | NAME_NM_FLAGS_RA |
1147 (rcode & NAME_RCODE_MASK);
1148 packet.qdcount = 0; /* question entries */
1149 packet.question = NULL;
1150 packet.ancount = 1; /* answer recs */
1151 packet.answer = &answer;
1152 packet.nscount = 0; /* authority recs */
1153 packet.authority = NULL;
1154 packet.arcount = 0; /* additional recs */
1155 packet.additional = NULL;
1157 answer.name = original_packet->question->name;
1158 answer.rr_type = NAME_QUESTION_TYPE_NB;
1159 answer.rr_class = NAME_QUESTION_CLASS_IN;
1160 answer.ttl = original_packet->additional->ttl;
1161 answer.rdlength = original_packet->additional->rdlength;
1162 answer.rdata = original_packet->additional->rdata;
1164 return (smb_send_name_service_packet(addr, &packet));
1168 * RFC 1002 4.2.9. NAME RELEASE REQUEST & DEMAND
1170 static int
1171 smb_send_name_release_request_and_demand(int bcast,
1172 struct name_question *question, struct resource_record *additional)
1174 int gotreply = 0;
1175 int i, rc;
1176 int addr_num;
1177 uint32_t retries;
1178 uint32_t timeout;
1179 addr_entry_t *destination;
1180 struct name_packet packet;
1182 if (bcast == BROADCAST) {
1183 if (bcast_num == 0)
1184 return (-1);
1185 destination = smb_bcast_list;
1186 addr_num = bcast_num;
1187 retries = 1; /* BCAST_REQ_RETRY_COUNT */
1188 timeout = 100; /* BCAST_REQ_RETRY_TIMEOUT */
1189 packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_BROADCAST;
1190 } else {
1191 if (nbns_num == 0)
1192 return (-1);
1193 destination = smb_nbns;
1194 addr_num = nbns_num;
1195 retries = 1; /* UCAST_REQ_RETRY_COUNT */
1196 timeout = 100; /* UCAST_REQ_RETRY_TIMEOUT */
1197 packet.info = NAME_RELEASE_REQUEST | NM_FLAGS_UNICAST;
1200 packet.qdcount = 1; /* question entries */
1201 packet.question = question;
1202 packet.ancount = 0; /* answer recs */
1203 packet.answer = NULL;
1204 packet.nscount = 0; /* authority recs */
1205 packet.authority = NULL;
1206 packet.arcount = 1; /* additional recs */
1207 packet.additional = additional;
1209 for (i = 0; i < addr_num; i++) {
1210 rc = smb_netbios_send_rcv(bcast, &destination[i], &packet,
1211 retries, timeout);
1212 if (rc == 1)
1213 gotreply = 1;
1216 return (gotreply);
1220 * RFC 1002 4.2.10. POSITIVE NAME RELEASE RESPONSE
1221 * RFC 1002 4.2.11. NEGATIVE NAME RELEASE RESPONSE
1223 static int
1224 /* LINTED - E_STATIC_UNUSED */
1225 smb_send_name_release_response(addr_entry_t *addr,
1226 struct name_packet *original_packet, uint16_t rcode)
1228 struct name_packet packet;
1229 struct resource_record answer;
1231 bzero(&packet, sizeof (struct name_packet));
1232 bzero(&answer, sizeof (struct resource_record));
1234 packet.name_trn_id = original_packet->name_trn_id;
1235 packet.info = NAME_RELEASE_RESPONSE | (rcode & NAME_RCODE_MASK);
1236 packet.qdcount = 0; /* question entries */
1237 packet.question = NULL;
1238 packet.ancount = 1; /* answer recs */
1239 packet.answer = &answer;
1240 packet.nscount = 0; /* authority recs */
1241 packet.authority = NULL;
1242 packet.arcount = 0; /* additional recs */
1243 packet.additional = NULL;
1245 answer.name = original_packet->question->name;
1246 answer.rr_type = NAME_QUESTION_TYPE_NB;
1247 answer.rr_class = NAME_QUESTION_CLASS_IN;
1248 answer.ttl = original_packet->additional->ttl;
1249 answer.rdlength = original_packet->additional->rdlength;
1250 answer.rdata = original_packet->additional->rdata;
1252 return (smb_send_name_service_packet(addr, &packet));
1256 * RFC 1002 4.2.12. NAME QUERY REQUEST
1258 static int
1259 smb_send_name_query_request(int bcast, struct name_question *question)
1261 int rc = 0;
1262 uint32_t retry, retries;
1263 uint32_t timeout;
1264 uint16_t tid;
1265 addr_entry_t *destination;
1266 struct name_packet packet;
1267 int i, addr_num;
1268 struct timespec st;
1270 if (bcast == BROADCAST) {
1271 if (bcast_num == 0)
1272 return (-1);
1273 destination = smb_bcast_list;
1274 addr_num = bcast_num;
1275 retries = BCAST_REQ_RETRY_COUNT;
1276 timeout = BCAST_REQ_RETRY_TIMEOUT;
1277 packet.info = NAME_QUERY_REQUEST | NM_FLAGS_BROADCAST;
1278 } else {
1279 if (nbns_num == 0)
1280 return (-1);
1281 destination = smb_nbns;
1282 addr_num = nbns_num;
1283 retries = UCAST_REQ_RETRY_COUNT;
1284 timeout = UCAST_REQ_RETRY_TIMEOUT;
1285 packet.info = NAME_QUERY_REQUEST | NM_FLAGS_UNICAST;
1287 packet.qdcount = 1; /* question entries */
1288 packet.question = question;
1289 packet.ancount = 0; /* answer recs */
1290 packet.answer = NULL;
1291 packet.nscount = 0; /* authority recs */
1292 packet.authority = NULL;
1293 packet.arcount = 0; /* additional recs */
1294 packet.additional = NULL;
1296 for (i = 0; i < addr_num; i++) {
1297 for (retry = 0; retry < retries; retry++) {
1298 if ((destination[i].flags & ADDR_FLAG_VALID) == 0)
1299 break;
1300 tid = smb_netbios_name_trn_id();
1301 packet.name_trn_id = tid;
1303 if (smb_send_name_service_packet(&destination[i],
1304 &packet) >= 0) {
1305 if ((rc = smb_netbios_process_response(tid,
1306 &destination[i],
1307 &packet, timeout)) != 0)
1308 break;
1310 st.tv_sec = 0;
1311 st.tv_nsec = (timeout * 1000000);
1312 (void) nanosleep(&st, 0);
1316 return (rc);
1320 * RFC 1002 4.2.13. POSITIVE NAME QUERY RESPONSE
1321 * RFC 1002 4.2.14. NEGATIVE NAME QUERY RESPONSE
1323 static int
1324 smb_send_name_query_response(addr_entry_t *addr,
1325 struct name_packet *original_packet, struct name_entry *entry,
1326 uint16_t rcode)
1328 addr_entry_t *raddr;
1329 struct name_packet packet;
1330 struct resource_record answer;
1331 uint16_t attr;
1332 unsigned char data[MAX_DATAGRAM_LENGTH];
1333 unsigned char *scan = data;
1334 uint32_t ret_addr;
1336 packet.name_trn_id = original_packet->name_trn_id;
1337 packet.info = NAME_QUERY_RESPONSE | (rcode & NAME_RCODE_MASK);
1338 packet.qdcount = 0; /* question entries */
1339 packet.question = NULL;
1340 packet.ancount = 1; /* answer recs */
1341 packet.answer = &answer;
1342 packet.nscount = 0; /* authority recs */
1343 packet.authority = NULL;
1344 packet.arcount = 0; /* additional recs */
1345 packet.additional = NULL;
1347 answer.name = entry;
1348 answer.rr_class = NAME_QUESTION_CLASS_IN;
1349 answer.ttl = entry->addr_list.ttl;
1350 answer.rdata = data;
1351 if (rcode) {
1352 answer.rr_type = NAME_RR_TYPE_NULL;
1353 answer.rdlength = 0;
1354 bzero(data, 6);
1355 } else {
1356 answer.rdlength = 0;
1357 answer.rr_type = NAME_QUESTION_TYPE_NB;
1358 raddr = &entry->addr_list;
1359 scan = data;
1360 do {
1361 attr = entry->attributes & (NAME_ATTR_GROUP |
1362 NAME_ATTR_OWNER_NODE_TYPE);
1364 BE_OUT16(scan, attr); scan += 2;
1365 ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1366 *scan++ = ret_addr;
1367 *scan++ = ret_addr >> 8;
1368 *scan++ = ret_addr >> 16;
1369 *scan++ = ret_addr >> 24;
1371 answer.rdlength += 6;
1372 raddr = raddr->forw;
1373 } while (raddr != &entry->addr_list);
1376 return (smb_send_name_service_packet(addr, &packet));
1380 * RFC 1002 4.2.18. NODE STATUS RESPONSE
1382 static int
1383 smb_send_node_status_response(addr_entry_t *addr,
1384 struct name_packet *original_packet)
1386 uint32_t net_ipaddr;
1387 int64_t max_connections;
1388 struct arpreq arpreq;
1389 struct name_packet packet;
1390 struct resource_record answer;
1391 unsigned char *scan;
1392 unsigned char *scan_end;
1393 unsigned char data[MAX_NETBIOS_REPLY_DATA_SIZE];
1394 boolean_t scan_done = B_FALSE;
1395 smb_inaddr_t ipaddr;
1397 bzero(&packet, sizeof (struct name_packet));
1398 bzero(&answer, sizeof (struct resource_record));
1400 packet.name_trn_id = original_packet->name_trn_id;
1401 packet.info = NODE_STATUS_RESPONSE;
1402 packet.qdcount = 0; /* question entries */
1403 packet.question = NULL;
1404 packet.ancount = 1; /* answer recs */
1405 packet.answer = &answer;
1406 packet.nscount = 0; /* authority recs */
1407 packet.authority = NULL;
1408 packet.arcount = 0; /* additional recs */
1409 packet.additional = NULL;
1411 answer.name = original_packet->question->name;
1412 answer.rr_type = NAME_RR_TYPE_NBSTAT;
1413 answer.rr_class = NAME_QUESTION_CLASS_IN;
1414 answer.ttl = 0;
1415 answer.rdata = data;
1417 scan = smb_netbios_cache_status(data, MAX_NETBIOS_REPLY_DATA_SIZE,
1418 original_packet->question->name->scope);
1420 scan_end = data + MAX_NETBIOS_REPLY_DATA_SIZE;
1422 ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr;
1423 ipaddr.a_family = AF_INET;
1424 if (smb_nic_is_same_subnet(&ipaddr))
1425 net_ipaddr = addr->sin.sin_addr.s_addr;
1426 else
1427 net_ipaddr = 0;
1429 (void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &max_connections);
1431 while (!scan_done) {
1432 if ((scan + 6) >= scan_end) {
1433 packet.info |= NAME_NM_FLAGS_TC;
1434 break;
1437 if (net_ipaddr != 0) {
1438 struct sockaddr_in *s_in;
1439 int s;
1441 s = socket(AF_INET, SOCK_DGRAM, 0);
1442 /* LINTED - E_BAD_PTR_CAST_ALIGN */
1443 s_in = (struct sockaddr_in *)&arpreq.arp_pa;
1444 s_in->sin_family = AF_INET;
1445 s_in->sin_addr.s_addr = net_ipaddr;
1446 if (ioctl(s, SIOCGARP, (caddr_t)&arpreq) < 0) {
1447 bzero(scan, 6);
1448 } else {
1449 bcopy(&arpreq.arp_ha.sa_data, scan, 6);
1451 (void) close(s);
1452 } else {
1453 bzero(scan, 6);
1455 scan += 6;
1457 if ((scan + 26) >= scan_end) {
1458 packet.info |= NAME_NM_FLAGS_TC;
1459 break;
1461 bzero(scan, 26);
1462 scan += 26;
1464 if ((scan + 2) >= scan_end) {
1465 packet.info |= NAME_NM_FLAGS_TC;
1466 break;
1468 BE_OUT16(scan, 0); scan += 2;
1470 if ((scan + 2) >= scan_end) {
1471 packet.info |= NAME_NM_FLAGS_TC;
1472 break;
1474 BE_OUT16(scan, 0); scan += 2;
1476 if ((scan + 2) >= scan_end) {
1477 packet.info |= NAME_NM_FLAGS_TC;
1478 break;
1480 BE_OUT16(scan, 0); scan += 2;
1482 if ((scan + 2) >= scan_end) {
1483 packet.info |= NAME_NM_FLAGS_TC;
1484 break;
1486 BE_OUT16(scan, 0); scan += 2;
1488 if ((scan + 2) >= scan_end) {
1489 packet.info |= NAME_NM_FLAGS_TC;
1490 break;
1492 BE_OUT16(scan, 0); scan += 2;
1494 if ((scan + 2) >= scan_end) {
1495 packet.info |= NAME_NM_FLAGS_TC;
1496 break;
1498 BE_OUT16(scan, 0); scan += 2;
1500 if ((scan + 2) >= scan_end) {
1501 packet.info |= NAME_NM_FLAGS_TC;
1502 break;
1504 BE_OUT16(scan, 0); scan += 2;
1506 if ((scan + 2) >= scan_end) {
1507 packet.info |= NAME_NM_FLAGS_TC;
1508 break;
1510 BE_OUT16(scan, max_connections); scan += 2;
1512 if ((scan + 2) >= scan_end) {
1513 packet.info |= NAME_NM_FLAGS_TC;
1514 break;
1517 BE_OUT16(scan, 0); scan += 2;
1519 scan_done = B_TRUE;
1521 answer.rdlength = scan - data;
1522 return (smb_send_name_service_packet(addr, &packet));
1525 static int
1526 smb_name_Bnode_add_name(struct name_entry *name)
1528 struct name_question question;
1529 struct resource_record additional;
1530 unsigned char data[8];
1531 uint16_t attr;
1532 addr_entry_t *addr;
1533 int rc = 0;
1535 addr = &name->addr_list;
1537 do {
1538 /* build name service packet */
1539 question.name = name;
1541 * question.name->attributes |= NAME_NB_FLAGS_ONT_B;
1542 * This is commented because NAME_NB_FLAGS_ONT_B is 0
1544 question.question_type = NAME_QUESTION_TYPE_NB;
1545 question.question_class = NAME_QUESTION_CLASS_IN;
1547 additional.name = name;
1548 additional.rr_class = NAME_QUESTION_CLASS_IN;
1549 additional.ttl = 0;
1550 additional.rdata = data;
1551 additional.rdlength = 6;
1552 additional.rr_type = NAME_QUESTION_TYPE_NB;
1553 attr = name->attributes & (NAME_ATTR_GROUP |
1554 NAME_ATTR_OWNER_NODE_TYPE);
1556 BE_OUT16(&data[0], attr);
1557 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1558 sizeof (uint32_t));
1560 rc |= smb_send_name_registration_request(BROADCAST, &question,
1561 &additional);
1562 addr = addr->forw;
1564 } while (addr != &name->addr_list);
1566 return (rc);
1569 static int
1570 smb_name_Bnode_find_name(struct name_entry *name)
1572 struct name_question question;
1574 question.name = name;
1575 question.question_type = NAME_QUESTION_TYPE_NB;
1576 question.question_class = NAME_QUESTION_CLASS_IN;
1578 return (smb_send_name_query_request(BROADCAST, &question));
1581 static int
1582 smb_name_Bnode_delete_name(struct name_entry *name)
1584 struct name_question question;
1585 struct resource_record additional;
1586 addr_entry_t *raddr;
1587 unsigned char data[MAX_DATAGRAM_LENGTH];
1588 unsigned char *scan = data;
1589 uint32_t attr;
1590 uint32_t ret_addr;
1592 /* build packet */
1593 question.name = name;
1594 question.question_type = NAME_QUESTION_TYPE_NB;
1595 question.question_class = NAME_QUESTION_CLASS_IN;
1597 additional.name = name;
1598 additional.rr_class = NAME_QUESTION_CLASS_IN;
1599 additional.ttl = 0;
1600 additional.rdata = data;
1601 additional.rdlength = 0;
1602 additional.rr_type = NAME_QUESTION_TYPE_NB;
1603 raddr = &name->addr_list;
1604 scan = data;
1605 do {
1606 attr = name->attributes & (NAME_ATTR_GROUP |
1607 NAME_ATTR_OWNER_NODE_TYPE);
1609 BE_OUT16(scan, attr); scan += 2;
1610 ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1611 *scan++ = ret_addr;
1612 *scan++ = ret_addr >> 8;
1613 *scan++ = ret_addr >> 16;
1614 *scan++ = ret_addr >> 24;
1616 additional.rdlength += 6;
1617 } while (raddr != &name->addr_list);
1619 return (smb_send_name_release_request_and_demand(BROADCAST,
1620 &question, &additional));
1623 static int
1624 smb_name_Pnode_add_name(struct name_entry *name)
1626 struct name_question question;
1627 struct resource_record additional;
1628 unsigned char data[8];
1629 uint16_t attr;
1630 addr_entry_t *addr;
1631 int rc = 0;
1633 /* build packet */
1634 addr = &name->addr_list;
1635 do {
1636 question.name = name;
1637 question.question_type = NAME_QUESTION_TYPE_NB;
1638 question.question_class = NAME_QUESTION_CLASS_IN;
1640 additional.name = name;
1641 additional.rr_class = NAME_QUESTION_CLASS_IN;
1642 additional.ttl = 0;
1643 additional.rdata = data;
1644 additional.rdlength = 6;
1645 additional.rr_type = NAME_QUESTION_TYPE_NB;
1646 attr = name->attributes &
1647 (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE);
1649 BE_OUT16(&data[0], attr);
1650 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1651 sizeof (uint32_t));
1653 rc |= smb_send_name_registration_request(UNICAST, &question,
1654 &additional);
1656 addr = addr->forw;
1658 } while (addr != &name->addr_list);
1660 return (rc);
1663 static int
1664 smb_name_Pnode_refresh_name(struct name_entry *name)
1666 struct name_question question;
1667 struct resource_record additional;
1668 unsigned char data[8];
1669 uint16_t attr;
1670 addr_entry_t *addr;
1671 int rc = 0;
1673 /* build packet */
1674 addr = &name->addr_list;
1675 do {
1676 question.name = name;
1677 question.question_type = NAME_QUESTION_TYPE_NB;
1678 question.question_class = NAME_QUESTION_CLASS_IN;
1680 additional.name = name;
1681 additional.rr_class = NAME_QUESTION_CLASS_IN;
1682 additional.ttl = 0;
1683 additional.rdata = data;
1684 additional.rdlength = 6;
1685 additional.rr_type = NAME_QUESTION_TYPE_NB;
1686 attr = name->attributes &
1687 (NAME_ATTR_GROUP | NAME_ATTR_OWNER_NODE_TYPE);
1689 BE_OUT16(&data[0], attr);
1690 (void) memcpy(&data[2], &addr->sin.sin_addr.s_addr,
1691 sizeof (uint32_t));
1693 rc |= smb_send_name_refresh_request(UNICAST, &question,
1694 &additional, 1);
1696 addr = addr->forw;
1697 } while (addr != &name->addr_list);
1699 return (rc);
1702 static int
1703 smb_name_Pnode_find_name(struct name_entry *name)
1705 struct name_question question;
1708 * Host initiated processing for a P node
1710 question.name = name;
1711 question.name->attributes |= NAME_NB_FLAGS_ONT_P;
1712 question.question_type = NAME_QUESTION_TYPE_NB;
1713 question.question_class = NAME_QUESTION_CLASS_IN;
1715 return (smb_send_name_query_request(UNICAST, &question));
1718 static int
1719 smb_name_Pnode_delete_name(struct name_entry *name)
1721 struct name_question question;
1722 struct resource_record additional;
1723 addr_entry_t *raddr;
1724 unsigned char data[MAX_DATAGRAM_LENGTH];
1725 unsigned char *scan = data;
1726 uint32_t attr;
1727 uint32_t ret_addr;
1729 /* build packet */
1730 question.name = name;
1731 question.name->attributes |= NAME_NB_FLAGS_ONT_P;
1732 question.question_type = NAME_QUESTION_TYPE_NB;
1733 question.question_class = NAME_QUESTION_CLASS_IN;
1735 additional.name = name;
1736 additional.rr_class = NAME_QUESTION_CLASS_IN;
1737 additional.ttl = 0;
1738 additional.rdata = data;
1739 additional.rdlength = 0;
1740 additional.rr_type = NAME_QUESTION_TYPE_NB;
1741 raddr = &name->addr_list;
1742 do {
1743 scan = data;
1744 attr = name->attributes & (NAME_ATTR_GROUP |
1745 NAME_ATTR_OWNER_NODE_TYPE);
1747 BE_OUT16(scan, attr); scan += 2;
1748 ret_addr = LE_32(raddr->sin.sin_addr.s_addr);
1749 *scan++ = ret_addr;
1750 *scan++ = ret_addr >> 8;
1751 *scan++ = ret_addr >> 16;
1752 *scan++ = ret_addr >> 24;
1754 additional.rdlength = 6;
1755 raddr = raddr->forw;
1756 (void) smb_send_name_release_request_and_demand(UNICAST,
1757 &question, &additional);
1758 } while (raddr != &name->addr_list);
1760 return (1);
1763 static int
1764 smb_name_Mnode_add_name(struct name_entry *name)
1766 if (smb_name_Bnode_add_name(name) > 0) {
1767 if (nbns_num == 0)
1768 return (1); /* No name server configured */
1770 return (smb_name_Pnode_add_name(name));
1772 return (-1);
1775 static int
1776 smb_name_Hnode_add_name(struct name_entry *name)
1778 if (nbns_num > 0) {
1779 if (smb_name_Pnode_add_name(name) == 1)
1780 return (1);
1783 return (smb_name_Bnode_add_name(name));
1786 static int
1787 smb_name_Mnode_find_name(struct name_entry *name)
1789 if (smb_name_Bnode_find_name(name) == 1)
1790 return (1);
1792 if (nbns_num == 0)
1793 return (1); /* No name server configured */
1795 return (smb_name_Pnode_find_name(name));
1798 static int
1799 smb_name_Hnode_find_name(struct name_entry *name)
1801 if (nbns_num > 0)
1802 if (smb_name_Pnode_find_name(name) == 1)
1803 return (1);
1805 return (smb_name_Bnode_find_name(name));
1808 static int
1809 smb_name_Mnode_delete_name(struct name_entry *name)
1811 (void) smb_name_Bnode_delete_name(name);
1813 if (nbns_num == 0)
1814 return (-1); /* No name server configured */
1816 if (smb_name_Pnode_delete_name(name) > 0)
1817 return (1);
1819 return (-1);
1822 static int
1823 smb_name_Hnode_delete_name(struct name_entry *name)
1825 if (nbns_num > 0)
1826 if (smb_name_Pnode_delete_name(name) > 0)
1827 return (1);
1829 return (smb_name_Bnode_delete_name(name));
1832 static void
1833 smb_name_process_Bnode_packet(struct name_packet *packet, addr_entry_t *addr)
1835 struct name_entry *name;
1836 struct name_entry *entry;
1837 struct name_question *question;
1838 struct resource_record *additional;
1840 question = packet->question;
1841 additional = packet->additional;
1843 switch (packet->info & NAME_OPCODE_OPCODE_MASK) {
1844 case NAME_OPCODE_REFRESH:
1845 /* Guard against malformed packets */
1846 if ((question == 0) || (additional == 0))
1847 break;
1848 if (additional->name->addr_list.sin.sin_addr.s_addr == 0)
1849 break;
1851 name = question->name;
1852 name->addr_list.ttl = additional->ttl;
1853 name->attributes = additional->name->attributes;
1854 name->addr_list.sin = additional->name->addr_list.sin;
1855 name->addr_list.forw = name->addr_list.back = &name->addr_list;
1857 if ((entry = smb_netbios_cache_lookup_addr(name)) != 0) {
1858 smb_netbios_cache_update_entry(entry, question->name);
1859 smb_netbios_cache_unlock_entry(entry);
1861 else
1862 (void) smb_netbios_cache_insert(question->name);
1863 break;
1865 case NAME_OPCODE_QUERY:
1867 * This opcode covers both NAME_QUERY_REQUEST and
1868 * NODE_STATUS_REQUEST. They can be distinguished
1869 * based on the type of question entry.
1872 /* All query requests have to have question entry */
1873 if (question == 0)
1874 break;
1876 if (question->question_type == NAME_QUESTION_TYPE_NB) {
1877 name = question->name;
1878 if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1879 (void) smb_send_name_query_response(addr,
1880 packet, entry, 0);
1881 smb_netbios_cache_unlock_entry(entry);
1884 else
1885 if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) {
1887 * Name of "*" may be used to force node to
1888 * divulge status for administrative purposes
1890 name = question->name;
1891 entry = 0;
1892 if (NETBIOS_NAME_IS_STAR(name->name) ||
1893 ((entry = smb_netbios_cache_lookup(name)) != 0)) {
1894 if (entry)
1895 smb_netbios_cache_unlock_entry(entry);
1897 * send only those names that are
1898 * in the same scope as the scope
1899 * field in the request packet
1901 (void) smb_send_node_status_response(addr,
1902 packet);
1905 break;
1907 default:
1908 break;
1912 static void
1913 smb_name_process_Pnode_packet(struct name_packet *packet, addr_entry_t *addr)
1915 struct name_entry *name;
1916 struct name_entry *entry;
1917 struct name_question *question;
1918 struct resource_record *additional;
1920 question = packet->question;
1921 additional = packet->additional;
1923 if (packet->info & NAME_NM_FLAGS_B) {
1925 * always ignore UDP broadcast packets
1927 return;
1930 switch (packet->info & NAME_OPCODE_OPCODE_MASK) {
1931 case NAME_OPCODE_REFRESH:
1932 /* Guard against malformed packets */
1933 if ((question == 0) || (additional == 0))
1934 break;
1935 if (additional->name->addr_list.sin.sin_addr.s_addr == 0)
1936 break;
1938 name = question->name;
1939 name->addr_list.ttl = additional->ttl;
1940 name->attributes = additional->name->attributes;
1941 name->addr_list.sin = additional->name->addr_list.sin;
1942 name->addr_list.forw = name->addr_list.back = &name->addr_list;
1944 if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1945 smb_netbios_cache_update_entry(entry, name);
1946 smb_netbios_cache_unlock_entry(entry);
1948 else
1949 (void) smb_netbios_cache_insert(name);
1951 (void) smb_send_name_registration_response(addr, packet, 0);
1952 break;
1954 case NAME_OPCODE_QUERY:
1956 * This opcode covers both NAME_QUERY_REQUEST and
1957 * NODE_STATUS_REQUEST. They can be distinguished
1958 * based on the type of question entry.
1961 /* All query requests have to have question entry */
1962 if (question == 0)
1963 break;
1965 if (question->question_type == NAME_QUESTION_TYPE_NB) {
1966 name = question->name;
1967 if ((entry = smb_netbios_cache_lookup(name)) != 0) {
1969 * send response to the IP address and port
1970 * number from which the request was received.
1972 (void) smb_send_name_query_response(addr,
1973 packet, entry, 0);
1974 smb_netbios_cache_unlock_entry(entry);
1975 } else {
1977 * send response to the requestor
1979 (void) smb_send_name_query_response(addr,
1980 packet, name, RCODE_NAM_ERR);
1983 else
1984 if (question->question_type == NAME_QUESTION_TYPE_NBSTAT) {
1986 * Name of "*" may be used to force node to
1987 * divulge status for administrative purposes
1989 name = question->name;
1990 entry = 0;
1991 if (NETBIOS_NAME_IS_STAR(name->name) ||
1992 ((entry = smb_netbios_cache_lookup(name)) != 0)) {
1994 * send only those names that are
1995 * in the same scope as the scope
1996 * field in the request packet
1998 if (entry)
1999 smb_netbios_cache_unlock_entry(entry);
2000 (void) smb_send_node_status_response(addr,
2001 packet);
2004 break;
2006 default:
2007 break;
2011 static void
2012 smb_name_process_Mnode_packet(struct name_packet *packet, addr_entry_t *addr)
2014 if (packet->info & NAME_NM_FLAGS_B)
2015 smb_name_process_Bnode_packet(packet, addr);
2016 else
2017 smb_name_process_Pnode_packet(packet, addr);
2020 static void
2021 smb_name_process_Hnode_packet(struct name_packet *packet, addr_entry_t *addr)
2023 if (packet->info & NAME_NM_FLAGS_B)
2024 smb_name_process_Bnode_packet(packet, addr);
2025 else
2026 smb_name_process_Pnode_packet(packet, addr);
2031 * smb_netbios_name_tick
2033 * Called once a second to handle name server timeouts.
2035 void
2036 smb_netbios_name_tick(void)
2038 struct name_entry *name;
2039 struct name_entry *entry;
2041 (void) mutex_lock(&refresh_queue.mtx);
2042 smb_netbios_cache_refresh(&refresh_queue);
2044 while ((name = refresh_queue.head.forw) != &refresh_queue.head) {
2045 QUEUE_CLIP(name);
2046 if (IS_LOCAL(name->attributes)) {
2047 if (IS_UNIQUE(name->attributes)) {
2048 (void) smb_name_Pnode_refresh_name(name);
2050 } else {
2051 entry = smb_name_find_name(name);
2052 smb_name_unlock_name(entry);
2054 free(name);
2056 (void) mutex_unlock(&refresh_queue.mtx);
2058 smb_netbios_cache_reset_ttl();
2062 * smb_name_find_name
2064 * Lookup name cache for the given name.
2065 * If it's not in the cache it'll send a
2066 * name query request and then lookup the
2067 * cache again. Note that if a name is
2068 * returned it's locked and called MUST
2069 * unlock it by calling smb_name_unlock_name()
2071 struct name_entry *
2072 smb_name_find_name(struct name_entry *name)
2074 struct name_entry *result;
2076 if ((result = smb_netbios_cache_lookup(name)) == 0) {
2077 switch (smb_node_type) {
2078 case 'B':
2079 (void) smb_name_Bnode_find_name(name);
2080 break;
2081 case 'P':
2082 (void) smb_name_Pnode_find_name(name);
2083 break;
2084 case 'M':
2085 (void) smb_name_Mnode_find_name(name);
2086 break;
2087 case 'H':
2088 default:
2089 (void) smb_name_Hnode_find_name(name);
2090 break;
2092 return (smb_netbios_cache_lookup(name));
2095 return (result);
2098 void
2099 smb_name_unlock_name(struct name_entry *name)
2101 smb_netbios_cache_unlock_entry(name);
2105 smb_name_add_name(struct name_entry *name)
2107 int rc = 1;
2109 smb_netbios_name_logf(name);
2111 switch (smb_node_type) {
2112 case 'B':
2113 rc = smb_name_Bnode_add_name(name);
2114 break;
2115 case 'P':
2116 rc = smb_name_Pnode_add_name(name);
2117 break;
2118 case 'M':
2119 rc = smb_name_Mnode_add_name(name);
2120 break;
2121 case 'H':
2122 default:
2123 rc = smb_name_Hnode_add_name(name);
2124 break;
2127 if (rc >= 0)
2128 (void) smb_netbios_cache_insert(name);
2130 return (rc);
2134 smb_name_delete_name(struct name_entry *name)
2136 int rc;
2137 unsigned char type;
2139 type = name->name[15];
2140 if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
2141 syslog(LOG_DEBUG, "nbns: name delete bad type (0x%02x)", type);
2142 smb_netbios_name_logf(name);
2143 name->attributes &= ~NAME_ATTR_LOCAL;
2144 return (-1);
2147 smb_netbios_cache_delete(name);
2149 switch (smb_node_type) {
2150 case 'B':
2151 rc = smb_name_Bnode_delete_name(name);
2152 break;
2153 case 'P':
2154 rc = smb_name_Pnode_delete_name(name);
2155 break;
2156 case 'M':
2157 rc = smb_name_Mnode_delete_name(name);
2158 break;
2159 case 'H':
2160 default:
2161 rc = smb_name_Hnode_delete_name(name);
2162 break;
2165 if (rc > 0)
2166 return (0);
2168 return (-1);
2171 typedef struct {
2172 addr_entry_t *addr;
2173 char *buf;
2174 int length;
2175 } worker_param_t;
2178 * smb_netbios_worker
2180 * Process incoming request/response packets for Netbios
2181 * name service (on port 138).
2183 void *
2184 smb_netbios_worker(void *arg)
2186 worker_param_t *p = (worker_param_t *)arg;
2187 addr_entry_t *addr = p->addr;
2188 struct name_packet *packet;
2190 if ((packet = smb_name_buf_to_packet(p->buf, p->length)) != NULL) {
2191 if (packet->info & NAME_OPCODE_R) {
2192 /* Reply packet */
2193 smb_reply_ready(packet, addr);
2194 free(p->buf);
2195 free(p);
2196 return (NULL);
2199 /* Request packet */
2200 switch (smb_node_type) {
2201 case 'B':
2202 smb_name_process_Bnode_packet(packet, addr);
2203 break;
2204 case 'P':
2205 smb_name_process_Pnode_packet(packet, addr);
2206 break;
2207 case 'M':
2208 smb_name_process_Mnode_packet(packet, addr);
2209 break;
2210 case 'H':
2211 default:
2212 smb_name_process_Hnode_packet(packet, addr);
2213 break;
2216 if (packet->answer)
2217 smb_netbios_name_freeaddrs(packet->answer->name);
2218 free(packet);
2219 } else {
2220 syslog(LOG_ERR, "nbns: packet decode failed");
2223 free(addr);
2224 free(p->buf);
2225 free(p);
2226 return (NULL);
2230 * Configure the node type. If a WINS server has been specified,
2231 * act like an H-node. Otherwise, behave like a B-node.
2233 static void
2234 smb_netbios_node_config(void)
2236 static smb_cfg_id_t wins[SMB_PI_MAX_WINS] = {
2237 SMB_CI_WINS_SRV1,
2238 SMB_CI_WINS_SRV2
2240 char ipstr[16];
2241 uint32_t ipaddr;
2242 int i;
2244 smb_node_type = SMB_NODETYPE_B;
2245 nbns_num = 0;
2246 bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS);
2248 for (i = 0; i < SMB_PI_MAX_WINS; ++i) {
2249 ipstr[0] = '\0';
2250 (void) smb_config_getstr(wins[i], ipstr, sizeof (ipstr));
2252 if ((ipaddr = inet_addr(ipstr)) == INADDR_NONE)
2253 continue;
2255 smb_node_type = SMB_NODETYPE_H;
2256 smb_nbns[nbns_num].flags = ADDR_FLAG_VALID;
2257 smb_nbns[nbns_num].sinlen = sizeof (struct sockaddr_in);
2258 smb_nbns[nbns_num].sin.sin_family = AF_INET;
2259 smb_nbns[nbns_num].sin.sin_addr.s_addr = ipaddr;
2260 smb_nbns[nbns_num].sin.sin_port = htons(IPPORT_NETBIOS_NS);
2261 nbns_num++;
2265 static void
2266 smb_netbios_name_registration(void)
2268 nbcache_iter_t nbc_iter;
2269 struct name_entry *name;
2270 int rc;
2272 rc = smb_netbios_cache_getfirst(&nbc_iter);
2273 while (rc == 0) {
2274 name = nbc_iter.nbc_entry;
2275 (void) smb_netbios_name_logf(name);
2276 if (IS_UNIQUE(name->attributes) && IS_LOCAL(name->attributes)) {
2277 switch (smb_node_type) {
2278 case SMB_NODETYPE_B:
2279 (void) smb_name_Bnode_add_name(name);
2280 break;
2281 case SMB_NODETYPE_P:
2282 (void) smb_name_Pnode_add_name(name);
2283 break;
2284 case SMB_NODETYPE_M:
2285 (void) smb_name_Mnode_add_name(name);
2286 break;
2287 case SMB_NODETYPE_H:
2288 default:
2289 (void) smb_name_Hnode_add_name(name);
2290 break;
2293 free(name);
2294 rc = smb_netbios_cache_getnext(&nbc_iter);
2299 * Note that the node configuration must be setup before calling
2300 * smb_init_name_struct().
2302 void
2303 smb_netbios_name_config(void)
2305 addr_entry_t *bcast_entry;
2306 struct name_entry name;
2307 smb_niciter_t ni;
2308 int rc;
2310 (void) mutex_lock(&nbt_name_config_mtx);
2311 smb_netbios_node_config();
2313 bcast_num = 0;
2314 bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS);
2316 rc = smb_nic_getfirst(&ni);
2317 while (rc == SMB_NIC_SUCCESS) {
2318 if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) ||
2319 (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS)) {
2320 rc = smb_nic_getnext(&ni);
2321 continue;
2324 bcast_entry = &smb_bcast_list[bcast_num];
2325 bcast_entry->flags = ADDR_FLAG_VALID;
2326 bcast_entry->attributes = NAME_ATTR_LOCAL;
2327 bcast_entry->sinlen = sizeof (struct sockaddr_in);
2328 bcast_entry->sin.sin_family = AF_INET;
2329 bcast_entry->sin.sin_port = htons(IPPORT_NETBIOS_NS);
2330 bcast_entry->sin.sin_addr.s_addr = ni.ni_nic.nic_bcast;
2331 bcast_num++;
2333 smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
2334 NBT_WKSTA, 0, ni.ni_nic.nic_ip.a_ipv4,
2335 htons(IPPORT_NETBIOS_DGM),
2336 NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
2337 (void) smb_netbios_cache_insert(&name);
2339 smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
2340 NBT_SERVER, 0, ni.ni_nic.nic_ip.a_ipv4,
2341 htons(IPPORT_NETBIOS_DGM),
2342 NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
2343 (void) smb_netbios_cache_insert(&name);
2345 rc = smb_nic_getnext(&ni);
2348 smb_netbios_name_registration();
2349 (void) mutex_unlock(&nbt_name_config_mtx);
2352 void
2353 smb_netbios_name_unconfig(void)
2355 struct name_entry *name;
2357 (void) mutex_lock(&nbt_name_config_mtx);
2358 (void) mutex_lock(&delete_queue.mtx);
2359 smb_netbios_cache_delete_locals(&delete_queue);
2361 while ((name = delete_queue.head.forw) != &delete_queue.head) {
2362 QUEUE_CLIP(name);
2363 (void) smb_name_delete_name(name);
2364 free(name);
2366 (void) mutex_unlock(&delete_queue.mtx);
2367 (void) mutex_unlock(&nbt_name_config_mtx);
2370 void
2371 smb_netbios_name_reconfig(void)
2373 smb_netbios_name_unconfig();
2374 smb_netbios_name_config();
2378 * NetBIOS Name Service (port 137)
2380 /*ARGSUSED*/
2381 void *
2382 smb_netbios_name_service(void *arg)
2384 struct sockaddr_in sin;
2385 addr_entry_t *addr;
2386 int len;
2387 int flag = 1;
2388 char *buf;
2389 worker_param_t *worker_param;
2390 smb_inaddr_t ipaddr;
2393 * Initialize reply_queue
2395 bzero(&reply_queue, sizeof (reply_queue));
2396 reply_queue.forw = reply_queue.back = &reply_queue;
2398 if ((name_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2399 syslog(LOG_ERR, "nbns: socket failed: %m");
2400 smb_netbios_event(NETBIOS_EVENT_ERROR);
2401 return (NULL);
2404 flag = 1;
2405 (void) setsockopt(name_sock, SOL_SOCKET, SO_REUSEADDR, &flag,
2406 sizeof (flag));
2407 flag = 1;
2408 (void) setsockopt(name_sock, SOL_SOCKET, SO_BROADCAST, &flag,
2409 sizeof (flag));
2411 bzero(&sin, sizeof (struct sockaddr_in));
2412 sin.sin_family = AF_INET;
2413 sin.sin_port = htons(IPPORT_NETBIOS_NS);
2414 if (bind(name_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) {
2415 syslog(LOG_ERR, "nbns: bind(%d) failed: %m",
2416 IPPORT_NETBIOS_NS);
2417 (void) close(name_sock);
2418 smb_netbios_event(NETBIOS_EVENT_ERROR);
2419 return (NULL);
2422 smb_netbios_event(NETBIOS_EVENT_NS_START);
2424 while (smb_netbios_running()) {
2425 buf = malloc(MAX_DATAGRAM_LENGTH);
2426 addr = malloc(sizeof (addr_entry_t));
2427 if ((buf == NULL) || (addr == NULL)) {
2428 /* Sleep for 10 seconds and try again */
2429 free(addr);
2430 free(buf);
2431 smb_netbios_sleep(10);
2432 continue;
2434 ignore: bzero(addr, sizeof (addr_entry_t));
2435 addr->sinlen = sizeof (addr->sin);
2436 addr->forw = addr->back = addr;
2438 if ((len = recvfrom(name_sock, buf, MAX_DATAGRAM_LENGTH,
2439 0, (struct sockaddr *)&addr->sin, &addr->sinlen)) < 0) {
2440 if (errno == ENOMEM || errno == ENFILE ||
2441 errno == EMFILE) {
2442 /* Sleep for 10 seconds and try again */
2443 free(buf);
2444 free(addr);
2445 smb_netbios_sleep(10);
2446 continue;
2448 syslog(LOG_ERR, "nbns: recvfrom failed: %m");
2449 free(buf);
2450 free(addr);
2451 smb_netbios_event(NETBIOS_EVENT_ERROR);
2452 goto shutdown;
2455 /* Ignore any incoming packets from myself... */
2457 ipaddr.a_ipv4 = addr->sin.sin_addr.s_addr;
2458 ipaddr.a_family = AF_INET;
2459 if (smb_nic_is_local(&ipaddr))
2460 goto ignore;
2463 * Launch a netbios worker to process the received packet.
2465 worker_param = malloc(sizeof (worker_param_t));
2466 if (worker_param) {
2467 pthread_t worker;
2468 pthread_attr_t tattr;
2470 worker_param->addr = addr;
2471 worker_param->buf = buf;
2472 worker_param->length = len;
2474 (void) pthread_attr_init(&tattr);
2475 (void) pthread_attr_setdetachstate(&tattr,
2476 PTHREAD_CREATE_DETACHED);
2477 (void) pthread_create(&worker, &tattr,
2478 smb_netbios_worker, worker_param);
2479 (void) pthread_attr_destroy(&tattr);
2483 shutdown:
2484 smb_netbios_event(NETBIOS_EVENT_NS_STOP);
2485 smb_netbios_wait(NETBIOS_EVENT_BROWSER_STOP);
2487 if (!smb_netbios_error())
2488 smb_netbios_name_unconfig();
2490 (void) close(name_sock);
2491 return (NULL);