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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "lib/socket/socket.h"
#include "system/network.h"
#include "system/locale.h"
-#include "netif/netif.h"
+#include "lib/socket/netif.h"
#include "librpc/gen_ndr/nbt.h"
#include "libcli/nbt/libnbt.h"
+#include "param/param.h"
/* command line options */
static struct {
const char *broadcast_address;
const char *unicast_address;
- BOOL find_master;
- BOOL wins_lookup;
- BOOL node_status;
- BOOL root_port;
- BOOL lookup_by_ip;
- BOOL case_sensitive;
+ bool find_master;
+ bool wins_lookup;
+ bool node_status;
+ bool root_port;
+ bool lookup_by_ip;
+ bool case_sensitive;
} options;
/*
ret = talloc_asprintf(mem_ctx, "%s %s", group, type);
if (flags & NBT_NM_DEREGISTER) {
- ret = talloc_asprintf_append(ret, " <DEREGISTERING>");
+ ret = talloc_asprintf_append_buffer(ret, " <DEREGISTERING>");
}
if (flags & NBT_NM_CONFLICT) {
- ret = talloc_asprintf_append(ret, " <CONFLICT>");
+ ret = talloc_asprintf_append_buffer(ret, " <CONFLICT>");
}
if (flags & NBT_NM_ACTIVE) {
- ret = talloc_asprintf_append(ret, " <ACTIVE>");
+ ret = talloc_asprintf_append_buffer(ret, " <ACTIVE>");
}
if (flags & NBT_NM_PERMANENT) {
- ret = talloc_asprintf_append(ret, " <PERMANENT>");
+ ret = talloc_asprintf_append_buffer(ret, " <PERMANENT>");
}
return ret;
}
/* do a single node status */
-static BOOL do_node_status(struct nbt_name_socket *nbtsock,
- const char *addr)
+static bool do_node_status(struct nbt_name_socket *nbtsock,
+ const char *addr, uint16_t port)
{
struct nbt_name_status io;
NTSTATUS status;
io.in.name.type = NBT_NAME_CLIENT;
io.in.name.scope = NULL;
io.in.dest_addr = addr;
+ io.in.dest_port = port;
io.in.timeout = 1;
io.in.retries = 2;
io.out.status.statistics.unit_id[3],
io.out.status.statistics.unit_id[4],
io.out.status.statistics.unit_id[5]);
- return True;
+ return true;
}
- return False;
+ return false;
}
/* do a single node query */
static NTSTATUS do_node_query(struct nbt_name_socket *nbtsock,
const char *addr,
+ uint16_t port,
const char *node_name,
enum nbt_name_type node_type,
- BOOL broadcast)
+ bool broadcast)
{
struct nbt_name_query io;
NTSTATUS status;
io.in.name.type = node_type;
io.in.name.scope = NULL;
io.in.dest_addr = addr;
+ io.in.dest_port = port;
io.in.broadcast = broadcast;
io.in.wins_lookup = options.wins_lookup;
io.in.timeout = 1;
io.out.name.type);
}
if (options.node_status && io.out.num_addrs > 0) {
- do_node_status(nbtsock, io.out.reply_addrs[0]);
+ do_node_status(nbtsock, io.out.reply_addrs[0], port);
}
return status;
}
-static BOOL process_one(const char *name)
+static bool process_one(struct loadparm_context *lp_ctx,
+ struct interface *ifaces, const char *name, int nbt_port)
{
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
enum nbt_name_type node_type = NBT_NAME_CLIENT;
struct socket_address *all_zero_addr;
struct nbt_name_socket *nbtsock;
NTSTATUS status = NT_STATUS_OK;
- BOOL ret = True;
+ bool ret = true;
if (!options.case_sensitive) {
name = strupper_talloc(tmp_ctx, name);
if (!all_zero_addr) {
talloc_free(tmp_ctx);
- return False;
+ return false;
}
status = socket_listen(nbtsock->sock, all_zero_addr, 0, 0);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to bind to local port 137 - %s\n", nt_errstr(status));
talloc_free(tmp_ctx);
- return False;
+ return false;
}
}
if (options.lookup_by_ip) {
- ret = do_node_status(nbtsock, name);
+ ret = do_node_status(nbtsock, name, nbt_port);
talloc_free(tmp_ctx);
return ret;
}
if (options.broadcast_address) {
- status = do_node_query(nbtsock, options.broadcast_address, node_name, node_type, True);
+ status = do_node_query(nbtsock, options.broadcast_address, nbt_port,
+ node_name, node_type, true);
} else if (options.unicast_address) {
- status = do_node_query(nbtsock, options.unicast_address, node_name, node_type, False);
+ status = do_node_query(nbtsock, options.unicast_address,
+ nbt_port, node_name, node_type, false);
} else {
- int i, num_interfaces = iface_count();
+ int i, num_interfaces;
+
+ num_interfaces = iface_count(ifaces);
for (i=0;i<num_interfaces;i++) {
- const char *bcast = iface_n_bcast(i);
+ const char *bcast = iface_n_bcast(ifaces, i);
if (bcast == NULL) continue;
- status = do_node_query(nbtsock, bcast, node_name, node_type, True);
+ status = do_node_query(nbtsock, bcast, nbt_port,
+ node_name, node_type, true);
if (NT_STATUS_IS_OK(status)) break;
}
}
if (!NT_STATUS_IS_OK(status)) {
printf("Lookup failed - %s\n", nt_errstr(status));
- ret = False;
+ ret = false;
}
talloc_free(tmp_ctx);
/*
main program
*/
-int main(int argc,char *argv[])
+int main(int argc, const char *argv[])
{
- BOOL ret = True;
+ bool ret = true;
+ struct interface *ifaces;
poptContext pc;
+ int opt;
+ enum {
+ OPT_BROADCAST_ADDRESS = 1000,
+ OPT_UNICAST_ADDRESS,
+ OPT_FIND_MASTER,
+ OPT_WINS_LOOKUP,
+ OPT_NODE_STATUS,
+ OPT_ROOT_PORT,
+ OPT_LOOKUP_BY_IP,
+ OPT_CASE_SENSITIVE
+ };
struct poptOption long_options[] = {
POPT_AUTOHELP
- { "broadcast", 'B', POPT_ARG_STRING, &options.broadcast_address,
- 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
+ { "broadcast", 'B', POPT_ARG_STRING, NULL, OPT_BROADCAST_ADDRESS,
+ "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
- { "unicast", 'U', POPT_ARG_STRING, &options.unicast_address,
- 'U', "Specify address to use for unicast" },
+ { "unicast", 'U', POPT_ARG_STRING, NULL, OPT_UNICAST_ADDRESS,
+ "Specify address to use for unicast", NULL },
- { "master-browser", 'M', POPT_ARG_VAL, &options.find_master,
- True, "Search for a master browser" },
+ { "master-browser", 'M', POPT_ARG_NONE, NULL, OPT_FIND_MASTER,
+ "Search for a master browser", NULL },
- { "wins", 'W', POPT_ARG_VAL, &options.wins_lookup, True, "Do a WINS lookup" },
+ { "wins", 'W', POPT_ARG_NONE, NULL, OPT_WINS_LOOKUP,
+ "Do a WINS lookup", NULL },
- { "status", 'S', POPT_ARG_VAL, &options.node_status,
- True, "Lookup node status as well" },
+ { "status", 'S', POPT_ARG_NONE, NULL, OPT_NODE_STATUS,
+ "Lookup node status as well", NULL },
- { "root-port", 'r', POPT_ARG_VAL, &options.root_port,
- True, "Use root port 137 (Win95 only replies to this)" },
+ { "root-port", 'r', POPT_ARG_NONE, NULL, OPT_ROOT_PORT,
+ "Use root port 137 (Win95 only replies to this)", NULL },
- { "lookup-by-ip", 'A', POPT_ARG_VAL, &options.lookup_by_ip,
- True, "Do a node status on <name> as an IP Address" },
+ { "lookup-by-ip", 'A', POPT_ARG_NONE, NULL, OPT_LOOKUP_BY_IP,
+ "Do a node status on <name> as an IP Address", NULL },
- { "case-sensitive", 0, POPT_ARG_VAL, &options.case_sensitive,
- True, "Don't uppercase the name before sending" },
+ { "case-sensitive", 0, POPT_ARG_NONE, NULL, OPT_CASE_SENSITIVE,
+ "Don't uppercase the name before sending", NULL },
POPT_COMMON_SAMBA
{ 0, 0, 0, 0 }
};
- pc = poptGetContext("nmblookup", argc, (const char **)argv, long_options,
+ pc = poptGetContext("nmblookup", argc, argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
-
+
poptSetOtherOptionHelp(pc, "<NODE> ...");
- while ((poptGetNextOpt(pc) != -1)) /* noop */ ;
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ switch(opt) {
+ case OPT_BROADCAST_ADDRESS:
+ options.broadcast_address = poptGetOptArg(pc);
+ break;
+ case OPT_UNICAST_ADDRESS:
+ options.unicast_address = poptGetOptArg(pc);
+ break;
+ case OPT_FIND_MASTER:
+ options.find_master = true;
+ break;
+ case OPT_WINS_LOOKUP:
+ options.wins_lookup = true;
+ break;
+ case OPT_NODE_STATUS:
+ options.node_status = true;
+ break;
+ case OPT_ROOT_PORT:
+ options.root_port = true;
+ break;
+ case OPT_LOOKUP_BY_IP:
+ options.lookup_by_ip = true;
+ break;
+ case OPT_CASE_SENSITIVE:
+ options.case_sensitive = true;
+ break;
+ }
+ }
/* swallow argv[0] */
poptGetArg(pc);
poptPrintUsage(pc, stderr, 0);
exit(1);
}
+
+ load_interfaces(lp_interfaces(cmdline_lp_ctx), &ifaces);
while (poptPeekArg(pc)) {
const char *name = poptGetArg(pc);
- ret &= process_one(name);
+ ret &= process_one(cmdline_lp_ctx, ifaces, name, lp_nbt_port(cmdline_lp_ctx));
}
poptFreeContext(pc);