2 Unix SMB/CIFS implementation.
3 NBT netbios routines and daemon - version 2
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6 Copyright (C) Jeremy Allison 1994-1998
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "nmbd/nmbd.h"
28 extern int global_nmb_port
;
30 /* This is the broadcast subnets database. */
31 struct subnet_record
*subnetlist
= NULL
;
33 /* Extra subnets - keep these separate so enumeration code doesn't
34 run onto it by mistake. */
36 struct subnet_record
*unicast_subnet
= NULL
;
37 struct subnet_record
*remote_broadcast_subnet
= NULL
;
38 struct subnet_record
*wins_server_subnet
= NULL
;
40 extern uint16_t samba_nb_type
; /* Samba's NetBIOS name type. */
42 /****************************************************************************
43 Add a subnet into the list.
44 **************************************************************************/
46 static void add_subnet(struct subnet_record
*subrec
)
48 DLIST_ADD(subnetlist
, subrec
);
51 /****************************************************************************
52 stop listening on a subnet
53 we don't free the record as we don't have proper reference counting for it
54 yet and it may be in use by a response record
55 ****************************************************************************/
57 void close_subnet(struct subnet_record
*subrec
)
59 if (subrec
->nmb_sock
!= -1) {
60 close(subrec
->nmb_sock
);
61 subrec
->nmb_sock
= -1;
63 if (subrec
->nmb_bcast
!= -1) {
64 close(subrec
->nmb_bcast
);
65 subrec
->nmb_bcast
= -1;
67 if (subrec
->dgram_sock
!= -1) {
68 close(subrec
->dgram_sock
);
69 subrec
->dgram_sock
= -1;
71 if (subrec
->dgram_bcast
!= -1) {
72 close(subrec
->dgram_bcast
);
73 subrec
->dgram_bcast
= -1;
76 DLIST_REMOVE(subnetlist
, subrec
);
79 /****************************************************************************
80 Create a subnet entry.
81 ****************************************************************************/
83 static struct subnet_record
*make_subnet(const char *name
, enum subnet_type type
,
84 struct in_addr myip
, struct in_addr bcast_ip
,
85 struct in_addr mask_ip
)
87 struct subnet_record
*subrec
= NULL
;
92 bool bind_bcast
= lp_nmbd_bind_explicit_broadcast();
94 /* Check if we are creating a non broadcast subnet - if so don't create
97 if (type
== NORMAL_SUBNET
) {
98 struct sockaddr_storage ss
;
99 struct sockaddr_storage ss_bcast
;
101 in_addr_to_sockaddr_storage(&ss
, myip
);
102 in_addr_to_sockaddr_storage(&ss_bcast
, bcast_ip
);
105 * Attempt to open the sockets on port 137/138 for this interface
107 * Fail the subnet creation if this fails.
110 nmb_sock
= open_socket_in(
111 SOCK_DGRAM
, &ss
, global_nmb_port
, true);
113 DBG_ERR("Failed to open nmb socket on interface %s "
117 strerror(-nmb_sock
));
120 set_socket_options(nmb_sock
,"SO_BROADCAST");
121 set_blocking(nmb_sock
, false);
124 nmb_bcast
= open_socket_in(
125 SOCK_DGRAM
, &ss_bcast
, global_nmb_port
, true);
127 DBG_ERR("Failed to open nmb bcast socket on "
128 "interface %s for port %d: %s\n",
131 strerror(-nmb_bcast
));
134 set_socket_options(nmb_bcast
, "SO_BROADCAST");
135 set_blocking(nmb_bcast
, false);
138 dgram_sock
= open_socket_in(SOCK_DGRAM
, &ss
, DGRAM_PORT
, true);
139 if (dgram_sock
< 0) {
140 DBG_ERR("Failed to open dgram socket on "
141 "interface %s for port %d: %s\n",
144 strerror(-dgram_sock
));
147 set_socket_options(dgram_sock
, "SO_BROADCAST");
148 set_blocking(dgram_sock
, false);
151 dgram_bcast
= open_socket_in(
152 SOCK_DGRAM
, &ss_bcast
, DGRAM_PORT
, true);
153 if (dgram_bcast
< 0) {
154 DBG_ERR("Failed to open dgram bcast socket on "
155 "interface %s for port %d: %s\n",
158 strerror(-dgram_bcast
));
161 set_socket_options(dgram_bcast
, "SO_BROADCAST");
162 set_blocking(dgram_bcast
, false);
166 subrec
= SMB_MALLOC_P(struct subnet_record
);
168 DEBUG(0,("make_subnet: malloc fail !\n"));
172 ZERO_STRUCTP(subrec
);
174 if((subrec
->subnet_name
= SMB_STRDUP(name
)) == NULL
) {
175 DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
179 DEBUG(2, ("making subnet name:%s ", name
));
180 DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip
)));
181 DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip
)));
183 subrec
->namelist_changed
= False
;
184 subrec
->work_changed
= False
;
186 subrec
->bcast_ip
= bcast_ip
;
187 subrec
->mask_ip
= mask_ip
;
190 subrec
->nmb_sock
= nmb_sock
;
191 subrec
->nmb_bcast
= nmb_bcast
;
192 subrec
->dgram_sock
= dgram_sock
;
193 subrec
->dgram_bcast
= dgram_bcast
;
202 if (nmb_bcast
>= 0) {
205 if (dgram_sock
>= 0) {
208 if (dgram_bcast
>= 0) {
214 /****************************************************************************
215 Create a normal subnet
216 **************************************************************************/
218 struct subnet_record
*make_normal_subnet(const struct interface
*iface
)
221 struct subnet_record
*subrec
;
222 const struct in_addr
*pip
= &((const struct sockaddr_in
*)&iface
->ip
)->sin_addr
;
223 const struct in_addr
*pbcast
= &((const struct sockaddr_in
*)&iface
->bcast
)->sin_addr
;
224 const struct in_addr
*pnmask
= &((const struct sockaddr_in
*)&iface
->netmask
)->sin_addr
;
226 subrec
= make_subnet(inet_ntoa(*pip
), NORMAL_SUBNET
,
227 *pip
, *pbcast
, *pnmask
);
234 /****************************************************************************
235 Create subnet entries.
236 **************************************************************************/
238 bool create_subnets(void)
240 /* We only count IPv4 interfaces whilst we're waiting. */
243 struct in_addr unicast_ip
, ipzero
;
245 try_interfaces_again
:
247 /* Only count IPv4, non-loopback interfaces. */
248 if (iface_count_v4_nl() == 0) {
249 daemon_status("nmbd",
250 "No local IPv4 non-loopback interfaces "
251 "available, waiting for interface ...");
252 DEBUG(0,("NOTE: NetBIOS name resolution is not supported for "
253 "Internet Protocol Version 6 (IPv6).\n"));
256 /* We only count IPv4, non-loopback interfaces here. */
257 while (iface_count_v4_nl() == 0) {
258 void (*saved_handler
)(int);
261 * Whilst we're waiting for an interface, allow SIGTERM to
265 saved_handler
= CatchSignal(SIGTERM
, SIG_DFL
);
267 usleep(NMBD_WAIT_INTERFACES_TIME_USEC
);
271 * We got an interface, restore our normal term handler.
274 CatchSignal(SIGTERM
, saved_handler
);
278 * Here we count v4 and v6 - we know there's at least one
279 * IPv4 interface and we filter on it below.
281 num_interfaces
= iface_count();
284 * Create subnets from all the local interfaces and thread them onto
288 for (i
= 0 ; i
< num_interfaces
; i
++) {
289 const struct interface
*iface
= get_interface(i
);
292 DEBUG(2,("create_subnets: can't get interface %d.\n", i
));
296 /* Ensure we're only dealing with IPv4 here. */
297 if (iface
->ip
.ss_family
!= AF_INET
) {
298 DEBUG(2,("create_subnets: "
299 "ignoring non IPv4 interface.\n"));
304 * We don't want to add a loopback interface, in case
305 * someone has added 127.0.0.1 for smbd, nmbd needs to
306 * ignore it here. JRA.
309 if (is_loopback_addr((const struct sockaddr
*)&iface
->ip
)) {
310 DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
314 if (!make_normal_subnet(iface
))
318 /* We must have at least one subnet. */
319 if (subnetlist
== NULL
) {
320 void (*saved_handler
)(int);
322 DEBUG(0,("create_subnets: Unable to create any subnet from "
323 "given interfaces. Is your interface line in "
324 "smb.conf correct ?\n"));
326 saved_handler
= CatchSignal(SIGTERM
, SIG_DFL
);
328 usleep(NMBD_WAIT_INTERFACES_TIME_USEC
);
331 CatchSignal(SIGTERM
, saved_handler
);
332 goto try_interfaces_again
;
335 if (lp_we_are_a_wins_server()) {
336 /* Pick the first interface IPv4 address as the WINS server
338 const struct in_addr
*nip
= first_ipv4_iface();
346 /* note that we do not set the wins server IP here. We just
347 set it at zero and let the wins registration code cope
348 with getting the IPs right for each packet */
349 zero_ip_v4(&unicast_ip
);
353 * Create the unicast and remote broadcast subnets.
354 * Don't put these onto the linked list.
355 * The ip address of the unicast subnet is set to be
356 * the WINS server address, if it exists, or ipzero if not.
359 unicast_subnet
= make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET
,
360 unicast_ip
, unicast_ip
, unicast_ip
);
364 remote_broadcast_subnet
= make_subnet( "REMOTE_BROADCAST_SUBNET",
365 REMOTE_BROADCAST_SUBNET
,
366 ipzero
, ipzero
, ipzero
);
368 if((unicast_subnet
== NULL
) || (remote_broadcast_subnet
== NULL
))
372 * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
376 if (lp_we_are_a_wins_server()) {
377 if( (wins_server_subnet
= make_subnet( "WINS_SERVER_SUBNET",
379 ipzero
, ipzero
, ipzero
)) == NULL
)
386 /*******************************************************************
387 Function to tell us if we can use the unicast subnet.
388 ******************************************************************/
390 bool we_are_a_wins_client(void)
392 if (wins_srv_count() > 0) {
399 /*******************************************************************
400 Access function used by NEXT_SUBNET_INCLUDING_UNICAST
401 ******************************************************************/
403 struct subnet_record
*get_next_subnet_maybe_unicast(struct subnet_record
*subrec
)
405 if(subrec
== unicast_subnet
)
407 else if((subrec
->next
== NULL
) && we_are_a_wins_client())
408 return unicast_subnet
;
413 /*******************************************************************
414 Access function used by retransmit_or_expire_response_records() in
415 nmbd_packets.c. Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>
416 Needed when we need to enumerate all the broadcast, unicast and
418 ******************************************************************/
420 struct subnet_record
*get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record
*subrec
)
422 if(subrec
== unicast_subnet
) {
423 if(wins_server_subnet
)
424 return wins_server_subnet
;
429 if(wins_server_subnet
&& subrec
== wins_server_subnet
)
432 if((subrec
->next
== NULL
) && we_are_a_wins_client())
433 return unicast_subnet
;