s4:libcli/resolve: add resolve_name_all*() which return all addresses not only the...
[abartlet/samba.git/.git] / source4 / libcli / resolve / bcast.c
index 1733ca9d2edb0265a8e0115fc8883a5d19040963..0a71ebed99106fc11757c95178819775a3d7f843 100644 (file)
@@ -4,6 +4,7 @@
    broadcast name resolution module
 
    Copyright (C) Andrew Tridgell 2005
+   Copyright (C) Jelmer Vernooij 2007
    
    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
 #include "lib/socket/netif.h"
 #include "param/param.h"
 
+struct resolve_bcast_data {
+       struct interface *ifaces;
+       uint16_t nbt_port;
+       int nbt_timeout;
+};
+
 /**
   broadcast name resolution method - async send
  */
@@ -33,17 +40,19 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
                                                  void *userdata,
                                                  struct nbt_name *name)
 {
-       struct loadparm_context *lp_ctx = userdata;
-       int num_interfaces = iface_count(lp_ctx);
+       int num_interfaces;
        const char **address_list;
        struct composite_context *c;
        int i, count=0;
+       struct resolve_bcast_data *data = talloc_get_type(userdata, struct resolve_bcast_data);
+
+       num_interfaces = iface_count(data->ifaces);
 
        address_list = talloc_array(mem_ctx, const char *, num_interfaces+1);
        if (address_list == NULL) return NULL;
 
        for (i=0;i<num_interfaces;i++) {
-               const char *bcast = iface_n_bcast(lp_ctx, i);
+               const char *bcast = iface_n_bcast(data->ifaces, i);
                if (bcast == NULL) continue;
                address_list[count] = talloc_strdup(address_list, bcast);
                if (address_list[count] == NULL) {
@@ -54,7 +63,7 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
        }
        address_list[count] = NULL;
 
-       c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, true, false);
+       c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, data->ifaces, data->nbt_port, data->nbt_timeout, true, false);
        talloc_free(address_list);
 
        return c;       
@@ -64,9 +73,16 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
   broadcast name resolution method - recv side
  */
 NTSTATUS resolve_name_bcast_recv(struct composite_context *c, 
-                                TALLOC_CTX *mem_ctx, const char **reply_addr)
+                                TALLOC_CTX *mem_ctx,
+                                struct socket_address ***addrs)
 {
-       return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr);
+       NTSTATUS status = resolve_name_nbtlist_recv(c, mem_ctx, addrs);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
+               /* this makes much more sense for a bcast name resolution
+                  timeout */
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+       return status;
 }
 
 /*
@@ -74,14 +90,33 @@ NTSTATUS resolve_name_bcast_recv(struct composite_context *c,
  */
 NTSTATUS resolve_name_bcast(struct nbt_name *name, 
                            TALLOC_CTX *mem_ctx,
-                           const char **reply_addr)
+                           struct interface *ifaces,
+                           uint16_t nbt_port,
+                           int nbt_timeout,
+                           struct socket_address ***addrs)
+{
+       struct resolve_bcast_data *data = talloc(mem_ctx, struct resolve_bcast_data);
+       struct composite_context *c;
+       data->ifaces = talloc_reference(data, ifaces);
+       data->nbt_port = nbt_port;
+       data->nbt_timeout = nbt_timeout;
+       
+       c = resolve_name_bcast_send(mem_ctx, NULL, data, name);
+       return resolve_name_bcast_recv(c, mem_ctx, addrs);
+}
+
+bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout)
 {
-       struct composite_context *c = resolve_name_bcast_send(mem_ctx, NULL, NULL, name);
-       return resolve_name_bcast_recv(c, mem_ctx, reply_addr);
+       struct resolve_bcast_data *data = talloc(ctx, struct resolve_bcast_data);
+       data->ifaces = ifaces;
+       data->nbt_port = nbt_port;
+       data->nbt_timeout = nbt_timeout;
+       return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv, data);
 }
 
-bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct loadparm_context *lp_ctx)
+bool resolve_context_add_bcast_method_lp(struct resolve_context *ctx, struct loadparm_context *lp_ctx)
 {
-       return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv,
-                                         lp_ctx);
+       struct interface *ifaces;
+       load_interfaces(ctx, lp_interfaces(lp_ctx), &ifaces);
+       return resolve_context_add_bcast_method(ctx, ifaces, lp_nbt_port(lp_ctx), lp_parm_int(lp_ctx, NULL, "nbt", "timeout", 1));
 }