diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-01-21 13:13:24 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:09:04 -0500 |
commit | 6f0aef31cdfa9b486d1f2e0f097e071830f5600d (patch) | |
tree | 01891cccf49ab3bde362968bf10af93796c20107 /source4/libcli/resolve/nbtlist.c | |
parent | 757a063a134ab466f437e60b1eed5215b992d80c (diff) | |
download | samba-6f0aef31cdfa9b486d1f2e0f097e071830f5600d.tar.gz samba-6f0aef31cdfa9b486d1f2e0f097e071830f5600d.tar.bz2 samba-6f0aef31cdfa9b486d1f2e0f097e071830f5600d.zip |
r4898: - removed the unused wins_srv_*() code
- expanded the generic async name resolver to try multiple methods
- added wins resolutions to the list of methods tried
- fixed up the random trn id generation to use the good random generator
(This used to be commit 266fd2751c01808e5a18d4094032af50554ceb7a)
Diffstat (limited to 'source4/libcli/resolve/nbtlist.c')
-rw-r--r-- | source4/libcli/resolve/nbtlist.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c new file mode 100644 index 0000000000..036e983fd2 --- /dev/null +++ b/source4/libcli/resolve/nbtlist.c @@ -0,0 +1,170 @@ +/* + Unix SMB/CIFS implementation. + + nbt list of addresses 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. +*/ + +/* + TODO: we should lower the timeout, and add retries for each name +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/composite/composite.h" + +struct nbtlist_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 nbtlist name resolution +*/ +static void nbtlist_handler(struct nbt_name_request *req) +{ + struct smbcli_composite *c = talloc_get_type(req->async.private, + struct smbcli_composite); + struct nbtlist_state *state = talloc_get_type(c->private, struct nbtlist_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); + } +} + +/* + nbtlist name resolution method - async send + */ +struct smbcli_composite *resolve_name_nbtlist_send(struct nbt_name *name, + struct event_context *event_ctx, + const char **address_list, + BOOL broadcast, + BOOL wins_lookup) +{ + struct smbcli_composite *c; + struct nbtlist_state *state; + int i; + NTSTATUS status; + + c = talloc_zero(NULL, struct smbcli_composite); + if (c == NULL) goto failed; + + state = talloc(c, struct nbtlist_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; + + /* count the address_list size */ + for (i=0;address_list[i];i++) /* noop */ ; + + state->num_queries = i; + 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++) { + state->io_queries[i].in.name = state->name; + state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, address_list[i]); + if (!state->io_queries[i].in.dest_addr) goto failed; + state->io_queries[i].in.broadcast = broadcast; + state->io_queries[i].in.wins_lookup = wins_lookup; + state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "timeout", 3); + + state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]); + if (!state->queries[i]) goto failed; + + state->queries[i]->async.fn = nbtlist_handler; + state->queries[i]->async.private = c; + } + + c->state = SMBCLI_REQUEST_SEND; + c->private = state; + c->event_ctx = talloc_reference(c, state->nbtsock->event_ctx); + + return c; + +failed: + talloc_free(c); + return NULL; +} + +/* + nbt list of addresses name resolution method - recv side + */ +NTSTATUS resolve_name_nbtlist_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 nbtlist_state *state = talloc_get_type(c->private, struct nbtlist_state); + *reply_addr = talloc_steal(mem_ctx, state->reply_addr); + } + + talloc_free(c); + return status; +} + +/* + nbt list of addresses name resolution method - sync call + */ +NTSTATUS resolve_name_nbtlist(struct nbt_name *name, + TALLOC_CTX *mem_ctx, + const char **address_list, + BOOL broadcast, BOOL wins_lookup, + const char **reply_addr) +{ + struct smbcli_composite *c = resolve_name_nbtlist_send(name, NULL, address_list, + broadcast, wins_lookup); + return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); +} + |