diff options
Diffstat (limited to 'source3/utils/nmblookup.c')
-rw-r--r-- | source3/utils/nmblookup.c | 299 |
1 files changed, 200 insertions, 99 deletions
diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c index aa43173332..9549d16d04 100644 --- a/source3/utils/nmblookup.c +++ b/source3/utils/nmblookup.c @@ -1,8 +1,7 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. NBT client - used to lookup netbios names - Copyright (C) Andrew Tridgell 1994-1995 + Copyright (C) Andrew Tridgell 1994-1998 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 @@ -20,44 +19,35 @@ */ -#ifdef SYSLOG -#undef SYSLOG -#endif +#define NO_SYSLOG #include "includes.h" -#include "nameserv.h" -extern int DEBUGLEVEL; - -extern pstring scope; - -extern struct in_addr bcast_ip; -extern pstring myhostname; +extern BOOL AllowDebugChange; +static BOOL use_bcast = True; static BOOL got_bcast = False; - -int ServerFD= -1; +static struct in_addr bcast_addr; +static BOOL recursion_desired = False; +static BOOL translate_addresses = False; +static int ServerFD= -1; +static int RootPort = False; +static BOOL find_status=False; /**************************************************************************** open the socket communication **************************************************************************/ static BOOL open_sockets(void) { - struct hostent *hp; - - /* get host info */ - if ((hp = Get_Hostbyname(myhostname)) == 0) - { - DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname)); - return False; - } - - ServerFD = open_socket_in(SOCK_DGRAM, 0,3); + ServerFD = open_socket_in( SOCK_DGRAM, + (RootPort ? 137 : 0), + (RootPort ? 0 : 3), + interpret_addr(lp_socket_address()), True ); if (ServerFD == -1) return(False); - set_socket_options(ServerFD,"SO_BROADCAST"); + set_socket_options( ServerFD, "SO_BROADCAST" ); DEBUG(3, ("Socket opened.\n")); return True; @@ -65,43 +55,128 @@ static BOOL open_sockets(void) /**************************************************************************** - initialise connect, service and file structs +usage on the program ****************************************************************************/ -static BOOL init_structs(void ) +static void usage(void) { - struct in_addr myip; - - if (!get_myname(myhostname,&myip)) - return(False); - - /* Read the broadcast address from the interface */ - { - struct in_addr ip0,ip2; - - ip0 = myip; - - if (!got_bcast) { - get_broadcast(&ip0,&bcast_ip,&ip2); + d_printf("Usage: nmblookup [-M] [-B bcast address] [-d debuglevel] name\n"); + d_printf("Version %s\n",VERSION); + d_printf("\t-d debuglevel set the debuglevel\n"); + d_printf("\t-B broadcast address the address to use for broadcasts\n"); + d_printf("\t-U unicast address the address to use for unicast\n"); + d_printf("\t-M searches for a master browser\n"); + d_printf("\t-R set recursion desired in packet\n"); + d_printf("\t-S lookup node status as well\n"); + d_printf("\t-T translate IP addresses into names\n"); + d_printf("\t-r Use root port 137 (Win95 only replies to this)\n"); + d_printf("\t-A Do a node status on <name> as an IP Address\n"); + d_printf("\t-i NetBIOS scope Use the given NetBIOS scope for name queries\n"); + d_printf("\t-s smb.conf file Use the given path to the smb.conf file\n"); + d_printf("\t-h Print this help message.\n"); + d_printf("\n If you specify -M and name is \"-\", nmblookup looks up __MSBROWSE__<01>\n"); + d_printf("\n"); +} - DEBUG(2,("Using broadcast %s\n",inet_ntoa(bcast_ip))); - } - } +/**************************************************************************** +turn a node status flags field into a string +****************************************************************************/ +static char *node_status_flags(unsigned char flags) +{ + static fstring ret; + fstrcpy(ret,""); + + fstrcat(ret, (flags & 0x80) ? "<GROUP> " : " "); + if ((flags & 0x60) == 0x00) fstrcat(ret,"B "); + if ((flags & 0x60) == 0x20) fstrcat(ret,"P "); + if ((flags & 0x60) == 0x40) fstrcat(ret,"M "); + if ((flags & 0x60) == 0x60) fstrcat(ret,"H "); + if (flags & 0x10) fstrcat(ret,"<DEREGISTERING> "); + if (flags & 0x08) fstrcat(ret,"<CONFLICT> "); + if (flags & 0x04) fstrcat(ret,"<ACTIVE> "); + if (flags & 0x02) fstrcat(ret,"<PERMANENT> "); + + return ret; +} - return True; +/**************************************************************************** +do a node status query +****************************************************************************/ +static void do_node_status(int fd, char *name, int type, struct in_addr ip) +{ + struct nmb_name nname; + int count, i, j; + struct node_status *status; + fstring cleanname; + + d_printf("Looking up status of %s\n",inet_ntoa(ip)); + make_nmb_name(&nname, name, type); + status = node_status_query(fd,&nname,ip, &count); + if (status) { + for (i=0;i<count;i++) { + fstrcpy(cleanname, status[i].name); + for (j=0;cleanname[j];j++) { + if (!isprint((int)cleanname[j])) cleanname[j] = '.'; + } + d_printf("\t%-15s <%02x> - %s\n", + cleanname,status[i].type, + node_status_flags(status[i].flags)); + } + SAFE_FREE(status); + } + d_printf("\n"); } + /**************************************************************************** -usage on the program +send out one query ****************************************************************************/ -static void usage(void) +static BOOL query_one(char *lookup, unsigned int lookup_type) { - printf("Usage: nmblookup [-M] [-B bcast address] [-d debuglevel] name\n"); - printf("Version %s\n",VERSION); - printf("\t-d debuglevel set the debuglevel\n"); - printf("\t-B broadcast address the address to use for broadcasts\n"); - printf("\t-M searches for a master browser\n"); - printf("\t-S lookup node status as well\n"); - printf("\n"); + int j, count; + struct in_addr *ip_list=NULL; + + if (got_bcast) { + d_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); + } else { + struct in_addr *bcast; + for (j=iface_count() - 1; + !ip_list && j >= 0; + j--) { + bcast = iface_n_bcast(j); + d_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); + } + } + + 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) { + d_printf("%s, ", host -> h_name); + } + } + d_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); } @@ -111,50 +186,71 @@ static void usage(void) int main(int argc,char *argv[]) { int opt; - unsigned int lookup_type = 0x20; + unsigned int lookup_type = 0x0; pstring lookup; extern int optind; extern char *optarg; BOOL find_master=False; - BOOL find_status=False; int i; - + BOOL lookup_by_ip = False; + int commandline_debuglevel = -2; + DEBUGLEVEL = 1; - *lookup = 0; + /* Prevent smb.conf setting from overridding */ + AllowDebugChange = False; - TimeInit(); + *lookup = 0; setup_logging(argv[0],True); - charset_initialise(); - - while ((opt = getopt(argc, argv, "p:d:B:i:SMh")) != EOF) + while ((opt = getopt(argc, argv, "d:B:U:i:s:SMrhART")) != EOF) switch (opt) { case 'B': - { - unsigned long a = interpret_addr(optarg); - putip((char *)&bcast_ip,(char *)&a); - got_bcast = True; - } + bcast_addr = *interpret_addr2(optarg); + got_bcast = True; + use_bcast = True; break; - case 'i': - strcpy(scope,optarg); - strupper(scope); + 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); + commandline_debuglevel = DEBUGLEVEL = atoi(optarg); + break; + case 's': + pstrcpy(dyn_CONFIGFILE, optarg); break; + case 'r': + RootPort = True; + break; case 'h': usage(); exit(0); break; + case 'A': + lookup_by_ip = True; + break; default: usage(); exit(1); @@ -165,53 +261,58 @@ int main(int argc,char *argv[]) exit(1); } - init_structs(); - if (!open_sockets()) return(1); + if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); + } - DEBUG(1,("Sending queries to %s\n",inet_ntoa(bcast_ip))); + /* + * Ensure we reset DEBUGLEVEL if someone specified it + * on the command line. + */ + if(commandline_debuglevel != -2) + DEBUGLEVEL = commandline_debuglevel; + + load_interfaces(); + if (!open_sockets()) return(1); for (i=optind;i<argc;i++) - { - BOOL bcast = True; - int retries = 2; + { char *p; struct in_addr ip; - strcpy(lookup,argv[i]); + 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 == '-') { - strcpy(lookup,"\01\02__MSBROWSE__\02"); + fstrcpy(lookup,"\01\02__MSBROWSE__\02"); lookup_type = 1; } else { lookup_type = 0x1d; } } - p = strchr(lookup,'#'); - + p = strchr_m(lookup,'#'); if (p) { - *p = 0; - sscanf(p+1,"%x",&lookup_type); - bcast = False; - retries = 1; + *p = '\0'; + sscanf(++p,"%x",&lookup_type); } - if (name_query(ServerFD,lookup,lookup_type,bcast,True, - bcast_ip,&ip,NULL)) - { - printf("%s %s\n",inet_ntoa(ip),lookup); - if (find_status) - { - printf("Looking up status of %s\n",inet_ntoa(ip)); - name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL,NULL); - printf("\n"); - } - } else { - printf("couldn't find name %s\n",lookup); + if (!query_one(lookup, lookup_type)) { + d_printf( "name_query failed to find name %s", lookup ); + if( 0 != lookup_type ) + d_printf( "#%02x", lookup_type ); + d_printf( "\n" ); } - } - + } + return(0); } |