2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2005
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/>.
23 #include "../lib/util/dlinklist.h"
24 #include "nbt_server/nbt_server.h"
25 #include "smbd/service_task.h"
26 #include "lib/socket/socket.h"
27 #include "nbt_server/wins/winsserver.h"
28 #include "nbt_server/dgram/proto.h"
29 #include "system/network.h"
30 #include "lib/socket/netif.h"
31 #include "param/param.h"
35 receive an incoming request and dispatch it to the right place
37 static void nbtd_request_handler(struct nbt_name_socket
*nbtsock
,
38 struct nbt_name_packet
*packet
,
39 struct socket_address
*src
)
41 struct nbtd_interface
*iface
= talloc_get_type(nbtsock
->incoming
.private_data
,
42 struct nbtd_interface
);
43 struct nbtd_server
*nbtsrv
= iface
->nbtsrv
;
45 nbtsrv
->stats
.total_received
++;
47 /* see if its from one of our own interfaces - if so, then ignore it */
48 if (nbtd_self_packet_and_bcast(nbtsock
, packet
, src
)) {
49 DEBUG(10,("Ignoring bcast self packet from %s:%d\n", src
->addr
, src
->port
));
53 switch (packet
->operation
& NBT_OPCODE
) {
54 case NBT_OPCODE_QUERY
:
55 nbtsrv
->stats
.query_count
++;
56 nbtd_request_query(nbtsock
, packet
, src
);
59 case NBT_OPCODE_REGISTER
:
60 case NBT_OPCODE_REFRESH
:
61 case NBT_OPCODE_REFRESH2
:
62 nbtsrv
->stats
.register_count
++;
63 nbtd_request_defense(nbtsock
, packet
, src
);
66 case NBT_OPCODE_RELEASE
:
67 case NBT_OPCODE_MULTI_HOME_REG
:
68 nbtsrv
->stats
.release_count
++;
69 nbtd_winsserver_request(nbtsock
, packet
, src
);
73 nbtd_bad_packet(packet
, src
, "Unexpected opcode");
78 static void nbtd_unexpected_handler(struct nbt_name_socket
*nbtsock
,
79 struct nbt_name_packet
*packet
,
80 struct socket_address
*src
)
82 struct nbtd_interface
*iface
= talloc_get_type(nbtsock
->incoming
.private_data
,
83 struct nbtd_interface
);
84 struct nbtd_server
*nbtsrv
= iface
->nbtsrv
;
85 struct nbtd_interface
*i
;
86 struct nbt_name_request
*req
= NULL
;
88 nbtsrv
->stats
.total_received
++;
90 DEBUG(10,("unexpected from src[%s] on interface[%p] %s/%s\n",
91 src
->addr
, iface
, iface
->ip_address
, iface
->netmask
));
93 /* try the broadcast interface */
94 if (nbtsrv
->bcast_interface
) {
95 i
= nbtsrv
->bcast_interface
;
96 req
= idr_find(i
->nbtsock
->idr
, packet
->name_trn_id
);
99 /* try the wins server client interface */
100 if (!req
&& nbtsrv
->wins_interface
&& nbtsrv
->wins_interface
->nbtsock
) {
101 i
= nbtsrv
->wins_interface
;
102 req
= idr_find(i
->nbtsock
->idr
, packet
->name_trn_id
);
105 /* try all other interfaces... */
107 for (i
= nbtsrv
->interfaces
; i
; i
= i
->next
) {
111 req
= idr_find(i
->nbtsock
->idr
, packet
->name_trn_id
);
117 DEBUG(10,("unexpected from src[%s] unable to redirected\n", src
->addr
));
121 DEBUG(10,("unexpected from src[%s] redirected to interface[%p] %s/%s\n",
122 src
->addr
, i
, i
->ip_address
, i
->netmask
));
125 * redirect the incoming response to the socket
126 * we sent the matching request
128 nbt_name_socket_handle_response_packet(req
, packet
, src
);
132 find a registered name on an interface
134 struct nbtd_iface_name
*nbtd_find_iname(struct nbtd_interface
*iface
,
135 struct nbt_name
*name
,
138 struct nbtd_iface_name
*iname
;
139 for (iname
=iface
->names
;iname
;iname
=iname
->next
) {
140 if (iname
->name
.type
== name
->type
&&
141 strcmp(name
->name
, iname
->name
.name
) == 0 &&
142 ((iname
->nb_flags
& nb_flags
) == nb_flags
)) {
150 start listening on the given address
152 static NTSTATUS
nbtd_add_socket(struct nbtd_server
*nbtsrv
,
153 struct loadparm_context
*lp_ctx
,
154 const char *bind_address
,
159 struct nbtd_interface
*iface
;
161 struct socket_address
*bcast_address
;
162 struct socket_address
*unicast_address
;
164 DEBUG(6,("nbtd_add_socket(%s, %s, %s, %s)\n", bind_address
, address
, bcast
, netmask
));
167 we actually create two sockets. One listens on the broadcast address
168 for the interface, and the other listens on our specific address. This
169 allows us to run with "bind interfaces only" while still receiving
170 broadcast addresses, and also simplifies matching incoming requests
174 iface
= talloc(nbtsrv
, struct nbtd_interface
);
175 NT_STATUS_HAVE_NO_MEMORY(iface
);
177 iface
->nbtsrv
= nbtsrv
;
178 iface
->bcast_address
= talloc_steal(iface
, bcast
);
179 iface
->ip_address
= talloc_steal(iface
, address
);
180 iface
->netmask
= talloc_steal(iface
, netmask
);
182 iface
->wack_queue
= NULL
;
184 if (strcmp(netmask
, "0.0.0.0") != 0) {
185 struct nbt_name_socket
*bcast_nbtsock
;
187 /* listen for broadcasts on port 137 */
188 bcast_nbtsock
= nbt_name_socket_init(iface
, nbtsrv
->task
->event_ctx
, lp_iconv_convenience(nbtsrv
->task
->lp_ctx
));
189 if (!bcast_nbtsock
) {
191 return NT_STATUS_NO_MEMORY
;
194 bcast_address
= socket_address_from_strings(bcast_nbtsock
, bcast_nbtsock
->sock
->backend_name
,
195 bcast
, lp_nbt_port(lp_ctx
));
196 if (!bcast_address
) {
198 return NT_STATUS_NO_MEMORY
;
201 status
= socket_listen(bcast_nbtsock
->sock
, bcast_address
, 0, 0);
202 if (!NT_STATUS_IS_OK(status
)) {
203 DEBUG(0,("Failed to bind to %s:%d - %s\n",
204 bcast
, lp_nbt_port(lp_ctx
), nt_errstr(status
)));
208 talloc_free(bcast_address
);
210 nbt_set_incoming_handler(bcast_nbtsock
, nbtd_request_handler
, iface
);
213 /* listen for unicasts on port 137 */
214 iface
->nbtsock
= nbt_name_socket_init(iface
, nbtsrv
->task
->event_ctx
,
215 lp_iconv_convenience(nbtsrv
->task
->lp_ctx
));
216 if (!iface
->nbtsock
) {
218 return NT_STATUS_NO_MEMORY
;
221 unicast_address
= socket_address_from_strings(iface
->nbtsock
,
222 iface
->nbtsock
->sock
->backend_name
,
223 bind_address
, lp_nbt_port(lp_ctx
));
225 status
= socket_listen(iface
->nbtsock
->sock
, unicast_address
, 0, 0);
226 if (!NT_STATUS_IS_OK(status
)) {
227 DEBUG(0,("Failed to bind to %s:%d - %s\n",
228 bind_address
, lp_nbt_port(lp_ctx
), nt_errstr(status
)));
232 talloc_free(unicast_address
);
234 nbt_set_incoming_handler(iface
->nbtsock
, nbtd_request_handler
, iface
);
235 nbt_set_unexpected_handler(iface
->nbtsock
, nbtd_unexpected_handler
, iface
);
237 /* also setup the datagram listeners */
238 status
= nbtd_dgram_setup(iface
, bind_address
);
239 if (!NT_STATUS_IS_OK(status
)) {
240 DEBUG(0,("Failed to setup dgram listen on %s - %s\n",
241 bind_address
, nt_errstr(status
)));
246 if (strcmp(netmask
, "0.0.0.0") == 0) {
247 DLIST_ADD(nbtsrv
->bcast_interface
, iface
);
249 DLIST_ADD(nbtsrv
->interfaces
, iface
);
256 setup a socket for talking to our WINS servers
258 static NTSTATUS
nbtd_add_wins_socket(struct nbtd_server
*nbtsrv
)
260 struct nbtd_interface
*iface
;
262 iface
= talloc_zero(nbtsrv
, struct nbtd_interface
);
263 NT_STATUS_HAVE_NO_MEMORY(iface
);
265 iface
->nbtsrv
= nbtsrv
;
267 DLIST_ADD(nbtsrv
->wins_interface
, iface
);
274 setup our listening sockets on the configured network interfaces
276 NTSTATUS
nbtd_startup_interfaces(struct nbtd_server
*nbtsrv
, struct loadparm_context
*lp_ctx
,
277 struct interface
*ifaces
)
279 int num_interfaces
= iface_count(ifaces
);
281 TALLOC_CTX
*tmp_ctx
= talloc_new(nbtsrv
);
284 /* if we are allowing incoming packets from any address, then
285 we also need to bind to the wildcard address */
286 if (!lp_bind_interfaces_only(lp_ctx
)) {
287 const char *primary_address
;
289 /* the primary address is the address we will return
290 for non-WINS queries not made on a specific
292 if (num_interfaces
> 0) {
293 primary_address
= iface_n_ip(ifaces
, 0);
295 primary_address
= inet_ntoa(interpret_addr2(
296 lp_netbios_name(lp_ctx
)));
298 primary_address
= talloc_strdup(tmp_ctx
, primary_address
);
299 NT_STATUS_HAVE_NO_MEMORY(primary_address
);
301 status
= nbtd_add_socket(nbtsrv
,
305 talloc_strdup(tmp_ctx
, "255.255.255.255"),
306 talloc_strdup(tmp_ctx
, "0.0.0.0"));
307 NT_STATUS_NOT_OK_RETURN(status
);
310 for (i
=0; i
<num_interfaces
; i
++) {
311 const char *bcast
= iface_n_bcast(ifaces
, i
);
312 const char *address
, *netmask
;
314 /* we can't assume every interface is broadcast capable */
315 if (bcast
== NULL
) continue;
317 address
= talloc_strdup(tmp_ctx
, iface_n_ip(ifaces
, i
));
318 bcast
= talloc_strdup(tmp_ctx
, bcast
);
319 netmask
= talloc_strdup(tmp_ctx
, iface_n_netmask(ifaces
, i
));
321 status
= nbtd_add_socket(nbtsrv
, lp_ctx
,
322 address
, address
, bcast
, netmask
);
323 NT_STATUS_NOT_OK_RETURN(status
);
326 if (lp_wins_server_list(lp_ctx
)) {
327 status
= nbtd_add_wins_socket(nbtsrv
);
328 NT_STATUS_NOT_OK_RETURN(status
);
331 talloc_free(tmp_ctx
);
338 form a list of addresses that we should use in name query replies
339 we always place the IP in the given interface first
341 const char **nbtd_address_list(struct nbtd_interface
*iface
, TALLOC_CTX
*mem_ctx
)
343 struct nbtd_server
*nbtsrv
= iface
->nbtsrv
;
344 const char **ret
= NULL
;
345 struct nbtd_interface
*iface2
;
346 bool is_loopback
= false;
348 if (iface
->ip_address
) {
349 is_loopback
= iface_same_net(iface
->ip_address
, "127.0.0.1", "255.0.0.0");
350 ret
= str_list_add(ret
, iface
->ip_address
);
353 for (iface2
=nbtsrv
->interfaces
;iface2
;iface2
=iface2
->next
) {
354 if (iface2
== iface
) continue;
356 if (!iface2
->ip_address
) continue;
359 if (iface_same_net(iface2
->ip_address
, "127.0.0.1", "255.0.0.0")) {
364 ret
= str_list_add(ret
, iface2
->ip_address
);
367 talloc_steal(mem_ctx
, ret
);
374 find the interface to use for sending a outgoing request
376 struct nbtd_interface
*nbtd_find_request_iface(struct nbtd_server
*nbtd_server
,
377 const char *address
, bool allow_bcast_iface
)
379 struct nbtd_interface
*cur
;
381 /* try to find a exact match */
382 for (cur
=nbtd_server
->interfaces
;cur
;cur
=cur
->next
) {
383 if (iface_same_net(address
, cur
->ip_address
, cur
->netmask
)) {
384 DEBUG(10,("find interface for dst[%s] ip: %s/%s (iface[%p])\n",
385 address
, cur
->ip_address
, cur
->netmask
, cur
));
390 /* no exact match, if we have the broadcast interface, use that */
391 if (allow_bcast_iface
&& nbtd_server
->bcast_interface
) {
392 cur
= nbtd_server
->bcast_interface
;
393 DEBUG(10,("find interface for dst[%s] ip: %s/%s (bcast iface[%p])\n",
394 address
, cur
->ip_address
, cur
->netmask
, cur
));
398 /* fallback to first interface */
399 cur
= nbtd_server
->interfaces
;
400 DEBUG(10,("find interface for dst[%s] ip: %s/%s (default iface[%p])\n",
401 address
, cur
->ip_address
, cur
->netmask
, cur
));
406 * find the interface to use for sending a outgoing reply
408 struct nbtd_interface
*nbtd_find_reply_iface(struct nbtd_interface
*iface
,
409 const char *address
, bool allow_bcast_iface
)
411 struct nbtd_server
*nbtd_server
= iface
->nbtsrv
;
413 /* first try to use the given interfacel when it's not the broadcast one */
414 if (iface
!= nbtd_server
->bcast_interface
) {
418 return nbtd_find_request_iface(nbtd_server
, address
, allow_bcast_iface
);