Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : broadcast name resolution module
5 :
6 : Copyright (C) Andrew Tridgell 2005
7 : Copyright (C) Jelmer Vernooij 2007
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "libcli/resolve/resolve.h"
25 : #include "system/network.h"
26 : #include "lib/socket/netif.h"
27 : #include "param/param.h"
28 :
29 : struct resolve_bcast_data {
30 : struct interface *ifaces;
31 : uint16_t nbt_port;
32 : int nbt_timeout;
33 : };
34 :
35 : /**
36 : broadcast name resolution method - async send
37 : */
38 4512 : static struct composite_context *resolve_name_bcast_send(
39 : TALLOC_CTX *mem_ctx,
40 : struct tevent_context *event_ctx,
41 : void *userdata, uint32_t flags,
42 : uint16_t port,
43 : struct nbt_name *name)
44 : {
45 0 : int num_interfaces;
46 0 : const char **address_list;
47 0 : struct composite_context *c;
48 4512 : int i, count=0;
49 4512 : struct resolve_bcast_data *data = talloc_get_type(userdata, struct resolve_bcast_data);
50 :
51 4512 : num_interfaces = iface_list_count(data->ifaces);
52 :
53 4512 : address_list = talloc_array(mem_ctx, const char *, num_interfaces+1);
54 4512 : if (address_list == NULL) return NULL;
55 :
56 13621 : for (i=0;i<num_interfaces;i++) {
57 9109 : bool ipv4 = iface_list_n_is_v4(data->ifaces, i);
58 0 : const char *bcast;
59 :
60 9109 : if (!ipv4) {
61 4512 : continue;
62 : }
63 :
64 4597 : bcast = iface_list_n_bcast(data->ifaces, i);
65 4597 : if (bcast == NULL) {
66 0 : continue;
67 : }
68 :
69 4597 : address_list[count] = talloc_strdup(address_list, bcast);
70 4597 : if (address_list[count] == NULL) {
71 0 : talloc_free(address_list);
72 0 : return NULL;
73 : }
74 4597 : count++;
75 : }
76 4512 : address_list[count] = NULL;
77 :
78 4512 : c = resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, port, name,
79 4512 : address_list, data->ifaces, data->nbt_port,
80 : data->nbt_timeout, true, false);
81 4512 : talloc_free(address_list);
82 :
83 4512 : return c;
84 : }
85 :
86 : /*
87 : broadcast name resolution method - recv side
88 : */
89 4512 : static NTSTATUS resolve_name_bcast_recv(struct composite_context *c,
90 : TALLOC_CTX *mem_ctx,
91 : struct socket_address ***addrs,
92 : char ***names)
93 : {
94 4512 : NTSTATUS status = resolve_name_nbtlist_recv(c, mem_ctx, addrs, names);
95 4512 : if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
96 : /* this makes much more sense for a bcast name resolution
97 : timeout */
98 1 : status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
99 : }
100 4512 : return status;
101 : }
102 :
103 67003 : bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout)
104 : {
105 67003 : struct resolve_bcast_data *data = talloc(ctx, struct resolve_bcast_data);
106 67003 : data->ifaces = ifaces;
107 67003 : data->nbt_port = nbt_port;
108 67003 : data->nbt_timeout = nbt_timeout;
109 67003 : return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv, data);
110 : }
111 :
112 67003 : bool resolve_context_add_bcast_method_lp(struct resolve_context *ctx, struct loadparm_context *lp_ctx)
113 : {
114 1322 : struct interface *ifaces;
115 67003 : load_interface_list(ctx, lp_ctx, &ifaces);
116 67003 : return resolve_context_add_bcast_method(ctx, ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1));
117 : }
|