/* do a single node query */ static NTSTATUS do_node_query(struct nbt_name_socket *nbtsock, const char *addr, const char *node_name, enum nbt_name_type node_type, BOOL broadcast) { struct nbt_name_query io; NTSTATUS status; int i; io.in.name.name = node_name; io.in.name.type = node_type; io.in.name.scope = NULL; io.in.dest_addr = addr; io.in.broadcast = broadcast; io.in.wins_lookup = options.wins_lookup; io.in.timeout = 1; io.in.retries = 2; status = nbt_name_query(nbtsock, nbtsock, &io); NT_STATUS_NOT_OK_RETURN(status); for (i=0;i<io.out.num_addrs;i++) { printf("%s %s<%02x>\n", io.out.reply_addrs[i], io.out.name.name, io.out.name.type); } if (options.node_status && io.out.num_addrs > 0) { do_node_status(nbtsock, io.out.reply_addrs[0]); } return status; }
static bool query_one(const char *lookup, unsigned int lookup_type) { int j, count; uint8_t flags; struct sockaddr_storage *ip_list=NULL; NTSTATUS status = NT_STATUS_NOT_FOUND; if (got_bcast) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &bcast_addr); d_printf("querying %s on %s\n", lookup, addr); status = name_query(lookup,lookup_type,use_bcast, use_bcast?true:recursion_desired, &bcast_addr, talloc_tos(), &ip_list, &count, &flags); } else { status = name_resolve_bcast( lookup, lookup_type, talloc_tos(), &ip_list, &count); } if (!NT_STATUS_IS_OK(status)) { return false; } if (give_flags) { d_printf("Flags: %s\n", query_flags(flags)); } for (j=0;j<count;j++) { char addr[INET6_ADDRSTRLEN]; if (translate_addresses) { char h_name[MAX_DNS_NAME_LENGTH]; h_name[0] = '\0'; if (sys_getnameinfo((const struct sockaddr *)&ip_list[j], sizeof(struct sockaddr_storage), h_name, sizeof(h_name), NULL, 0, NI_NAMEREQD)) { continue; } d_printf("%s, ", h_name); } print_sockaddr(addr, sizeof(addr), &ip_list[j]); d_printf("%s %s<%02x>\n", addr,lookup, lookup_type); /* We can only do find_status if the ip address returned was valid - ie. name_query returned true. */ if (find_status) { if (!do_node_status(lookup, lookup_type, &ip_list[j])) { status = NT_STATUS_UNSUCCESSFUL; } } } TALLOC_FREE(ip_list); return NT_STATUS_IS_OK(status); }
/**************************************************************************** send out one query ****************************************************************************/ static BOOL query_one(char *lookup, unsigned int lookup_type) { int j, count, flags; struct in_addr *ip_list=NULL; if (got_bcast) { printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr)); ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast, use_bcast?True:recursion_desired, bcast_addr,&count, &flags); } else { struct in_addr *bcast; for (j=iface_count() - 1; !ip_list && j >= 0; j--) { bcast = iface_n_bcast(j); printf("querying %s on %s\n", lookup, inet_ntoa(*bcast)); ip_list = name_query(ServerFD,lookup,lookup_type, use_bcast, use_bcast?True:recursion_desired, *bcast,&count, &flags); } } if (give_flags) printf("Flags: %s\n", query_flags(flags)); if (!ip_list) return False; for (j=0;j<count;j++) { if (translate_addresses) { struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET); if (host) { printf("%s, ", host -> h_name); } } printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type); } /* We can only do find_status if the ip address returned was valid - ie. name_query returned true. */ if (find_status) { do_node_status(ServerFD, lookup, lookup_type, ip_list[0]); } safe_free(ip_list); return (ip_list != NULL); }
/**************************************************************************** main program ****************************************************************************/ int main(int argc, const char *argv[]) { int opt; unsigned int lookup_type = 0x0; fstring lookup; static bool find_master=False; static bool lookup_by_ip = False; poptContext pc = NULL; TALLOC_CTX *frame = talloc_stackframe(); int rc = 0; struct poptOption long_options[] = { POPT_AUTOHELP { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" }, { "flags", 'f', POPT_ARG_NONE, NULL, 'f', "List the NMB flags returned" }, { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" }, { "master-browser", 'M', POPT_ARG_NONE, NULL, 'M', "Search for a master browser" }, { "recursion", 'R', POPT_ARG_NONE, NULL, 'R', "Set recursion desired in package" }, { "status", 'S', POPT_ARG_NONE, NULL, 'S', "Lookup node status as well" }, { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" }, { "root-port", 'r', POPT_ARG_NONE, NULL, 'r', "Use root port 137 (Win95 only replies to this)" }, { "lookup-by-ip", 'A', POPT_ARG_NONE, NULL, 'A', "Do a node status on <name> as an IP Address" }, POPT_COMMON_SAMBA POPT_COMMON_CONNECTION { 0, 0, 0, 0 } }; *lookup = 0; load_case_tables(); setup_logging(argv[0], DEBUG_STDOUT); pc = poptGetContext("nmblookup", argc, argv, long_options, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, "<NODE> ..."); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 'f': give_flags = true; break; case 'M': find_master = true; break; case 'R': recursion_desired = true; break; case 'S': find_status = true; break; case 'r': RootPort = true; break; case 'A': lookup_by_ip = true; break; case 'B': if (interpret_string_addr(&bcast_addr, poptGetOptArg(pc), NI_NUMERICHOST)) { got_bcast = True; use_bcast = True; } break; case 'U': if (interpret_string_addr(&bcast_addr, poptGetOptArg(pc), 0)) { got_bcast = True; use_bcast = False; } break; case 'T': translate_addresses = !translate_addresses; break; } } poptGetArg(pc); /* Remove argv[0] */ if(!poptPeekArg(pc)) { poptPrintUsage(pc, stderr, 0); rc = 1; goto out; } if (!lp_load_global(get_dyn_CONFIGFILE())) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", get_dyn_CONFIGFILE()); } load_interfaces(); if (!open_sockets()) { rc = 1; goto out; } while(poptPeekArg(pc)) { char *p; struct in_addr ip; fstrcpy(lookup,poptGetArg(pc)); if(lookup_by_ip) { struct sockaddr_storage ss; ip = interpret_addr2(lookup); in_addr_to_sockaddr_storage(&ss, ip); fstrcpy(lookup,"*"); if (!do_node_status(lookup, lookup_type, &ss)) { rc = 1; } continue; } if (find_master) { if (*lookup == '-') { fstrcpy(lookup,"\01\02__MSBROWSE__\02"); lookup_type = 1; } else { lookup_type = 0x1d; } } p = strchr_m(lookup,'#'); if (p) { *p = '\0'; sscanf(++p,"%x",&lookup_type); } if (!query_one(lookup, lookup_type)) { rc = 1; d_printf( "name_query failed to find name %s", lookup ); if( 0 != lookup_type ) { d_printf( "#%02x", lookup_type ); } d_printf( "\n" ); } } out: poptFreeContext(pc); TALLOC_FREE(frame); return rc; }
static bool process_one(struct loadparm_context *lp_ctx, struct tevent_context *ev, 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; char *node_name, *p; struct socket_address *all_zero_addr; struct nbt_name_socket *nbtsock; 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 == '-' || *name == '_') { name = "\01\02__MSBROWSE__\02"; node_type = NBT_NAME_MS; } } p = strchr(name, '#'); if (p) { node_name = talloc_strndup(tmp_ctx, name, PTR_DIFF(p,name)); node_type = (enum nbt_name_type)strtol(p+1, NULL, 16); } else { node_name = talloc_strdup(tmp_ctx, name); } nbtsock = nbt_name_socket_init(tmp_ctx, ev, lp_iconv_convenience(lp_ctx)); if (options.root_port) { 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)); talloc_free(tmp_ctx); return false; } } if (options.lookup_by_ip) { 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, nbt_port, node_name, node_type, true); } else if (options.unicast_address) { status = do_node_query(nbtsock, options.unicast_address, nbt_port, node_name, node_type, false); } else { int i, num_interfaces; num_interfaces = iface_count(ifaces); for (i=0;i<num_interfaces;i++) { const char *bcast = iface_n_bcast(ifaces, i); if (bcast == NULL) continue; 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; } talloc_free(tmp_ctx); return ret; }
static bool query_one(const char *lookup, unsigned int lookup_type) { int j, count, flags = 0; struct sockaddr_storage *ip_list=NULL; if (got_bcast) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &bcast_addr); d_printf("querying %s on %s\n", lookup, addr); ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast, use_bcast?true:recursion_desired, &bcast_addr, &count, &flags, NULL); } else { const struct in_addr *bcast; for (j=iface_count() - 1; !ip_list && j >= 0; j--) { char addr[INET6_ADDRSTRLEN]; struct sockaddr_storage bcast_ss; bcast = iface_n_bcast_v4(j); if (!bcast) { continue; } in_addr_to_sockaddr_storage(&bcast_ss, *bcast); print_sockaddr(addr, sizeof(addr), &bcast_ss); d_printf("querying %s on %s\n", lookup, addr); ip_list = name_query(ServerFD,lookup,lookup_type, use_bcast, use_bcast?True:recursion_desired, &bcast_ss,&count, &flags, NULL); } } if (!ip_list) { return false; } if (give_flags) { d_printf("Flags: %s\n", query_flags(flags)); } for (j=0;j<count;j++) { char addr[INET6_ADDRSTRLEN]; if (translate_addresses) { char h_name[MAX_DNS_NAME_LENGTH]; h_name[0] = '\0'; if (sys_getnameinfo((const struct sockaddr *)&ip_list[j], sizeof(struct sockaddr_storage), h_name, sizeof(h_name), NULL, 0, NI_NAMEREQD)) { continue; } d_printf("%s, ", h_name); } print_sockaddr(addr, sizeof(addr), &ip_list[j]); d_printf("%s %s<%02x>\n", addr,lookup, lookup_type); /* We can only do find_status if the ip address returned was valid - ie. name_query returned true. */ if (find_status) { do_node_status(ServerFD, lookup, lookup_type, &ip_list[j]); } } free(ip_list); return (ip_list != NULL); }
/**************************************************************************** main program ****************************************************************************/ int main(int argc,char *argv[]) { int opt; unsigned int lookup_type = 0x0; pstring lookup; extern int optind; extern char *optarg; BOOL find_master=False; int i; static pstring servicesf = CONFIGFILE; BOOL lookup_by_ip = False; DEBUGLEVEL = 1; /* Prevent smb.conf setting from overridding */ AllowDebugChange = False; *lookup = 0; TimeInit(); setup_logging(argv[0],True); charset_initialise(); while ((opt = getopt(argc, argv, "d:fB:U:i:s:SMrhART")) != EOF) switch (opt) { case 'B': bcast_addr = *interpret_addr2(optarg); got_bcast = True; use_bcast = True; break; case 'f': give_flags = True; break; case 'U': bcast_addr = *interpret_addr2(optarg); got_bcast = True; use_bcast = False; break; case 'T': translate_addresses = !translate_addresses; break; case 'i': { extern pstring global_scope; pstrcpy(global_scope,optarg); strupper(global_scope); } break; case 'M': find_master = True; break; case 'S': find_status = True; break; case 'R': recursion_desired = True; break; case 'd': DEBUGLEVEL = atoi(optarg); break; case 's': pstrcpy(servicesf, optarg); break; case 'r': RootPort = True; break; case 'h': usage(); exit(0); break; case 'A': lookup_by_ip = True; break; default: usage(); exit(1); } if (argc < 2) { usage(); exit(1); } if (!lp_load(servicesf,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); } load_interfaces(); if (!open_sockets()) return(1); for (i=optind;i<argc;i++) { char *p; struct in_addr ip; fstrcpy(lookup,argv[i]); if(lookup_by_ip) { fstrcpy(lookup,"*"); ip = *interpret_addr2(argv[i]); do_node_status(ServerFD, lookup, lookup_type, ip); continue; } if (find_master) { if (*lookup == '-') { fstrcpy(lookup,"\01\02__MSBROWSE__\02"); lookup_type = 1; } else { lookup_type = 0x1d; } } p = strchr(lookup,'#'); if (p) { *p = '\0'; sscanf(++p,"%x",&lookup_type); } if (!query_one(lookup, lookup_type)) { printf( "name_query failed to find name %s", lookup ); if( 0 != lookup_type ) printf( "#%02x", lookup_type ); printf( "\n" ); } } return(0); }