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 "includes.h"
-#include "dynconfig.h"
-#include "libcli/nbt/libnbt.h"
#include "lib/cmdline/popt_common.h"
-#include "system/iconv.h"
#include "lib/socket/socket.h"
+#include "system/network.h"
+#include "system/locale.h"
+#include "lib/socket/netif.h"
+#include "librpc/gen_ndr/nbt.h"
+#include "libcli/nbt/libnbt.h"
/* command line options */
static struct {
char *ret = talloc_strdup(mem_ctx, name);
int i;
for (i=0;ret[i];i++) {
- if (!isprint(ret[i])) ret[i] = '.';
+ if (!isprint((unsigned char)ret[i])) ret[i] = '.';
}
return ret;
}
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 void do_node_status(struct nbt_name_socket *nbtsock,
+static BOOL do_node_status(struct nbt_name_socket *nbtsock,
const char *addr)
{
struct nbt_name_status io;
io.out.status.statistics.unit_id[3],
io.out.status.statistics.unit_id[4],
io.out.status.statistics.unit_id[5]);
+ return True;
}
+
+ return False;
}
/* do a single node query */
}
-static void process_one(const char *name)
+static BOOL process_one(const char *name)
{
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
enum nbt_name_type node_type = NBT_NAME_CLIENT;
char *node_name, *p;
+ struct socket_address *all_zero_addr;
struct nbt_name_socket *nbtsock;
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
+ BOOL ret = True;
if (!options.case_sensitive) {
name = strupper_talloc(tmp_ctx, name);
if (options.find_master) {
node_type = NBT_NAME_MASTER;
- if (*name == '-') {
+ if (*name == '-' || *name == '_') {
name = "\01\02__MSBROWSE__\02";
node_type = NBT_NAME_MS;
}
}
nbtsock = nbt_name_socket_init(tmp_ctx, NULL);
-
+
if (options.root_port) {
- status = socket_listen(nbtsock->sock, "0.0.0.0", NBT_NAME_SERVICE_PORT, 0, 0);
+ all_zero_addr = socket_address_from_strings(tmp_ctx, nbtsock->sock->backend_name,
+ "0.0.0.0", NBT_NAME_SERVICE_PORT);
+
+ if (!all_zero_addr) {
+ talloc_free(tmp_ctx);
+ 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));
- return;
+ talloc_free(tmp_ctx);
+ return False;
}
}
if (options.lookup_by_ip) {
- do_node_status(nbtsock, name);
+ ret = do_node_status(nbtsock, name);
talloc_free(tmp_ctx);
- return;
+ return ret;
}
if (options.broadcast_address) {
int i, num_interfaces = iface_count();
for (i=0;i<num_interfaces;i++) {
const char *bcast = iface_n_bcast(i);
+ if (bcast == NULL) continue;
status = do_node_query(nbtsock, bcast, 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;
}
talloc_free(tmp_ctx);
- }
+ return ret;
+}
/*
main program
*/
-int main(int argc,char *argv[])
+int main(int argc, const char *argv[])
{
+ BOOL ret = True;
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 }
};
- setup_logging(argv[0], True);
-
- 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);
exit(1);
}
- lp_load(dyn_CONFIGFILE,True,False,False);
- load_interfaces();
-
while (poptPeekArg(pc)) {
const char *name = poptGetArg(pc);
- process_one(name);
+ ret &= process_one(name);
}
poptFreeContext(pc);
+ if (!ret) {
+ return 1;
+ }
+
return 0;
}