rpcclient/rpcclient.c: Non-void return in void function.
[ira/wip.git] / source3 / utils / nmblookup.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT client - used to lookup netbios names
5    Copyright (C) Andrew Tridgell 1994-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 */
22
23 #define NO_SYSLOG
24
25 #include "includes.h"
26
27 extern int DEBUGLEVEL;
28
29 extern struct in_addr ipzero;
30
31 static BOOL use_bcast = True;
32 static BOOL got_bcast = False;
33 static struct in_addr bcast_addr;
34 static BOOL recursion_desired = False;
35 static BOOL translate_addresses = False;
36 static int ServerFD= -1;
37 static int RootPort = False;
38 static BOOL find_status=False;
39
40 /****************************************************************************
41   open the socket communication
42   **************************************************************************/
43 static BOOL open_sockets(void)
44 {
45   ServerFD = open_socket_in( SOCK_DGRAM,
46                              (RootPort ? 137 : 0),
47                              (RootPort ?   0 : 3),
48                              interpret_addr(lp_socket_address()), True );
49
50   if (ServerFD == -1)
51     return(False);
52
53   set_socket_options( ServerFD, "SO_BROADCAST" );
54
55   DEBUG(3, ("Socket opened.\n"));
56   return True;
57 }
58
59
60 /****************************************************************************
61 usage on the program
62 ****************************************************************************/
63 static void usage(void)
64 {
65   printf("Usage: nmblookup [-M] [-B bcast address] [-d debuglevel] name\n");
66   printf("Version %s\n",VERSION);
67   printf("\t-d debuglevel         set the debuglevel\n");
68   printf("\t-B broadcast address  the address to use for broadcasts\n");
69   printf("\t-U unicast   address  the address to use for unicast\n");
70   printf("\t-M                    searches for a master browser\n");
71   printf("\t-R                    set recursion desired in packet\n");
72   printf("\t-S                    lookup node status as well\n");
73   printf("\t-T                    translate IP addresses into names\n");
74   printf("\t-r                    Use root port 137 (Win95 only replies to this)\n");
75   printf("\t-A                    Do a node status on <name> as an IP Address\n");
76   printf("\t-i NetBIOS scope      Use the given NetBIOS scope for name queries\n");
77   printf("\t-s smb.conf file      Use the given path to the smb.conf file\n");
78   printf("\t-h                    Print this help message.\n");
79   printf("\n  If you specify -M and name is \"-\", nmblookup looks up __MSBROWSE__<01>\n");
80   printf("\n");
81 }
82
83 /****************************************************************************
84 turn a node status flags field into a string
85 ****************************************************************************/
86 static char *node_status_flags(unsigned char flags)
87 {
88         static fstring ret;
89         fstrcpy(ret,"");
90         
91         fstrcat(ret, (flags & 0x80) ? "<GROUP> " : "        ");
92         if ((flags & 0x60) == 0x00) fstrcat(ret,"B ");
93         if ((flags & 0x60) == 0x20) fstrcat(ret,"P ");
94         if ((flags & 0x60) == 0x40) fstrcat(ret,"M ");
95         if ((flags & 0x60) == 0x60) fstrcat(ret,"H ");
96         if (flags & 0x10) fstrcat(ret,"<DEREGISTERING> ");
97         if (flags & 0x08) fstrcat(ret,"<CONFLICT> ");
98         if (flags & 0x04) fstrcat(ret,"<ACTIVE> ");
99         if (flags & 0x02) fstrcat(ret,"<PERMANENT> ");
100         
101         return ret;
102 }
103
104 /****************************************************************************
105 do a node status query
106 ****************************************************************************/
107 static void do_node_status(int fd, char *name, int type, struct in_addr ip)
108 {
109         struct nmb_name nname;
110         int count, i, j;
111         struct node_status *status;
112         fstring cleanname;
113
114         printf("Looking up status of %s\n",inet_ntoa(ip));
115         make_nmb_name(&nname, name, type);
116         status = name_status_query(fd,&nname,ip, &count);
117         if (status) {
118                 for (i=0;i<count;i++) {
119                         fstrcpy(cleanname, status[i].name);
120                         for (j=0;cleanname[j];j++) {
121                                 if (!isprint((int)cleanname[j])) cleanname[j] = '.';
122                         }
123                         printf("\t%-15s <%02x> - %s\n",
124                                cleanname,status[i].type,
125                                node_status_flags(status[i].flags));
126                 }
127                 free(status);
128         }
129         printf("\n");
130 }
131
132
133 /****************************************************************************
134 send out one query
135 ****************************************************************************/
136 static BOOL query_one(char *lookup, unsigned int lookup_type)
137 {
138         int j, count;
139         struct in_addr *ip_list=NULL;
140
141         if (got_bcast) {
142                 printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
143                 ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
144                                      use_bcast?True:recursion_desired,
145                                      bcast_addr,&count);
146         } else {
147                 struct in_addr *bcast;
148                 for (j=iface_count() - 1;
149                      !ip_list && j >= 0;
150                      j--) {
151                         bcast = iface_n_bcast(j);
152                         printf("querying %s on %s\n", 
153                                lookup, inet_ntoa(*bcast));
154                         ip_list = name_query(ServerFD,lookup,lookup_type,
155                                              use_bcast,
156                                              use_bcast?True:recursion_desired,
157                                              *bcast,&count);
158                 }
159         }
160
161         if (!ip_list) return False;
162
163         for (j=0;j<count;j++) {
164                 if (translate_addresses) {
165                         struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET);
166                         if (host) {
167                                 printf("%s, ", host -> h_name);
168                         }
169                 }
170                 printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
171         }
172
173         /* We can only do find_status if the ip address returned
174            was valid - ie. name_query returned true.
175         */
176         if (find_status) {
177                 do_node_status(ServerFD, lookup, lookup_type, ip_list[0]);
178         }
179
180         safe_free(ip_list);
181
182         return (ip_list != NULL);
183 }
184
185
186 /****************************************************************************
187   main program
188 ****************************************************************************/
189 int main(int argc,char *argv[])
190 {
191   int opt;
192   unsigned int lookup_type = 0x0;
193   pstring lookup;
194   extern int optind;
195   extern char *optarg;
196   BOOL find_master=False;
197   int i;
198   static pstring servicesf = CONFIGFILE;
199   BOOL lookup_by_ip = False;
200   int commandline_debuglevel = -2;
201
202   DEBUGLEVEL = 1;
203   *lookup = 0;
204
205   TimeInit();
206
207   setup_logging(argv[0],True);
208
209   charset_initialise();
210
211   while ((opt = getopt(argc, argv, "d:B:U:i:s:SMrhART")) != EOF)
212     switch (opt)
213       {
214       case 'B':
215         bcast_addr = *interpret_addr2(optarg);
216         got_bcast = True;
217         use_bcast = True;
218         break;
219       case 'U':
220         bcast_addr = *interpret_addr2(optarg);
221         got_bcast = True;
222         use_bcast = False;
223         break;
224       case 'T':
225         translate_addresses = !translate_addresses;
226         break;
227       case 'i':
228               {
229                       extern pstring global_scope;
230                       pstrcpy(global_scope,optarg);
231                       strupper(global_scope);
232               }
233               break;
234       case 'M':
235         find_master = True;
236         break;
237       case 'S':
238         find_status = True;
239         break;
240       case 'R':
241         recursion_desired = True;
242         break;
243       case 'd':
244         commandline_debuglevel = DEBUGLEVEL = atoi(optarg);
245         break;
246       case 's':
247         pstrcpy(servicesf, optarg);
248         break;
249       case 'r':
250         RootPort = True;
251         break;
252       case 'h':
253         usage();
254         exit(0);
255         break;
256       case 'A':
257         lookup_by_ip = True;
258         break;
259       default:
260         usage();
261         exit(1);
262       }
263
264   if (argc < 2) {
265     usage();
266     exit(1);
267   }
268
269   if (!lp_load(servicesf,True,False,False)) {
270     fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
271   }
272
273   /*
274    * Ensure we reset DEBUGLEVEL if someone specified it
275    * on the command line.
276    */
277
278   if(commandline_debuglevel != -2)
279     DEBUGLEVEL = commandline_debuglevel;
280
281   load_interfaces();
282   if (!open_sockets()) return(1);
283
284   for (i=optind;i<argc;i++)
285   {
286       char *p;
287       struct in_addr ip;
288
289       fstrcpy(lookup,argv[i]);
290
291       if(lookup_by_ip)
292       {
293         fstrcpy(lookup,"*");
294         ip = *interpret_addr2(argv[i]);
295         do_node_status(ServerFD, lookup, lookup_type, ip);
296         continue;
297       }
298
299       if (find_master) {
300         if (*lookup == '-') {
301           fstrcpy(lookup,"\01\02__MSBROWSE__\02");
302           lookup_type = 1;
303         } else {
304           lookup_type = 0x1d;
305         }
306       }
307
308       p = strchr(lookup,'#');
309       if (p) {
310         *p = '\0';
311         sscanf(++p,"%x",&lookup_type);
312       }
313
314       if (!query_one(lookup, lookup_type)) {
315         printf( "name_query failed to find name %s", lookup );
316         if( 0 != lookup_type )
317           printf( "#%02x", lookup_type );
318         printf( "\n" );
319       }
320   }
321   
322   return(0);
323 }