summaryrefslogtreecommitdiff
path: root/source4/libcli/resolve/bcast.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-21 11:18:56 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:09:03 -0500
commit2383787f199c51cdc202a3cef5822a9fe6b8774c (patch)
tree52419b4e736f5ae1727561a3c9831e899edb35c5 /source4/libcli/resolve/bcast.c
parentf1aaef3015864f9323711127a4964a8eceff6a52 (diff)
downloadsamba-2383787f199c51cdc202a3cef5822a9fe6b8774c.tar.gz
samba-2383787f199c51cdc202a3cef5822a9fe6b8774c.tar.bz2
samba-2383787f199c51cdc202a3cef5822a9fe6b8774c.zip
r4891: - added a generic resolve_name() async interface in libcli/resolve/,
which will eventually try all resolution methods setup in smb.conf - only resolution backend at the moment is bcast, which does a parallel broadcast to all configured network interfaces, and takes the first reply that comes in (this nicely demonstrates how to do parallel requests using the async APIs) - converted all the existing code to use the new resolve_name() api - removed all the old nmb code (yay!) (This used to be commit 239c310f255e43dd2d1c2433f666c9faaacbdce3)
Diffstat (limited to 'source4/libcli/resolve/bcast.c')
-rw-r--r--source4/libcli/resolve/bcast.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c
new file mode 100644
index 0000000000..b2d37fbfbb
--- /dev/null
+++ b/source4/libcli/resolve/bcast.c
@@ -0,0 +1,163 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ broadcast name resolution module
+
+ Copyright (C) Andrew Tridgell 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "system/network.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/nbt/libnbt.h"
+#include "libcli/composite/composite.h"
+
+struct bcast_state {
+ struct nbt_name name;
+ struct nbt_name_socket *nbtsock;
+ int num_queries;
+ struct nbt_name_request **queries;
+ struct nbt_name_query *io_queries;
+ const char *reply_addr;
+};
+
+/*
+ handle events during broadcast name resolution
+*/
+static void bcast_handler(struct nbt_name_request *req)
+{
+ struct smbcli_composite *c = talloc_get_type(req->async.private,
+ struct smbcli_composite);
+ struct bcast_state *state = talloc_get_type(c->private, struct bcast_state);
+ int i;
+
+ for (i=0;i<state->num_queries;i++) {
+ if (req == state->queries[i]) break;
+ }
+ if (i == state->num_queries) {
+ /* not for us?! */
+ c->status = NT_STATUS_INTERNAL_ERROR;
+ c->state = SMBCLI_REQUEST_ERROR;
+ goto done;
+ }
+
+ c->status = nbt_name_query_recv(req, state, &state->io_queries[i]);
+ if (!NT_STATUS_IS_OK(c->status)) {
+ c->state = SMBCLI_REQUEST_ERROR;
+ } else {
+ c->state = SMBCLI_REQUEST_DONE;
+ state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addr);
+ }
+
+done:
+ talloc_free(state->nbtsock);
+ if (c->async.fn) {
+ c->async.fn(c);
+ }
+}
+
+/*
+ broadcast name resolution method - async send
+ */
+struct smbcli_composite *resolve_name_bcast_send(struct nbt_name *name,
+ struct event_context *event_ctx)
+{
+ struct smbcli_composite *c;
+ struct bcast_state *state;
+ int i;
+ NTSTATUS status;
+
+ c = talloc_zero(NULL, struct smbcli_composite);
+ if (c == NULL) goto failed;
+
+ state = talloc(c, struct bcast_state);
+ if (state == NULL) goto failed;
+
+ status = nbt_name_dup(state, name, &state->name);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+
+ state->nbtsock = nbt_name_socket_init(state, event_ctx);
+ if (state->nbtsock == NULL) goto failed;
+
+ state->num_queries = iface_count();
+
+ state->io_queries = talloc_array(state, struct nbt_name_query, state->num_queries);
+ if (!state->io_queries) goto failed;
+
+ state->queries = talloc_array(state, struct nbt_name_request *, state->num_queries);
+ if (!state->queries) goto failed;
+
+ for (i=0;i<state->num_queries;i++) {
+ struct ipv4_addr *ip = iface_n_bcast(i);
+ const char *addr = sys_inet_ntoa(*ip);
+ if (!addr) goto failed;
+
+ state->io_queries[i].in.name = state->name;
+ state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, addr);
+ if (!state->io_queries[i].in.dest_addr) goto failed;
+ state->io_queries[i].in.broadcast = True;
+ state->io_queries[i].in.wins_lookup = False;
+ state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "bcastTimeout", 5);
+
+ state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]);
+ if (!state->queries[i]) goto failed;
+
+ state->queries[i]->async.fn = bcast_handler;
+ state->queries[i]->async.private = c;
+ }
+
+ c->state = SMBCLI_REQUEST_SEND;
+ c->private = state;
+ c->event_ctx = state->nbtsock->event_ctx;
+
+ return c;
+
+failed:
+ talloc_free(c);
+ return NULL;
+}
+
+/*
+ broadcast name resolution method - recv side
+ */
+NTSTATUS resolve_name_bcast_recv(struct smbcli_composite *c,
+ TALLOC_CTX *mem_ctx, const char **reply_addr)
+{
+ NTSTATUS status;
+
+ status = smb_composite_wait(c);
+
+ if (NT_STATUS_IS_OK(status)) {
+ struct bcast_state *state = talloc_get_type(c->private, struct bcast_state);
+ *reply_addr = talloc_steal(mem_ctx, state->reply_addr);
+ }
+
+ talloc_free(c);
+ return status;
+}
+
+/*
+ broadcast name resolution method - sync call
+ */
+NTSTATUS resolve_name_bcast(struct nbt_name *name,
+ TALLOC_CTX *mem_ctx,
+ const char **reply_addr)
+{
+ struct smbcli_composite *c = resolve_name_bcast_send(name, NULL);
+ return resolve_name_bcast_recv(c, mem_ctx, reply_addr);
+}
+