rpcinfo.c revision 1.5 1 1.5 tls /* $NetBSD: rpcinfo.c,v 1.5 1997/01/09 20:21:11 tls Exp $ */
2 1.5 tls
3 1.1 glass #ifndef lint
4 1.3 mycroft /*static char sccsid[] = "from: @(#)rpcinfo.c 1.22 87/08/12 SMI";*/
5 1.3 mycroft /*static char sccsid[] = "from: @(#)rpcinfo.c 2.2 88/08/11 4.0 RPCSRC";*/
6 1.5 tls static char rcsid[] = "$NetBSD: rpcinfo.c,v 1.5 1997/01/09 20:21:11 tls Exp $";
7 1.1 glass #endif
8 1.1 glass
9 1.1 glass /*
10 1.1 glass * Copyright (C) 1986, Sun Microsystems, Inc.
11 1.1 glass */
12 1.1 glass
13 1.1 glass /*
14 1.1 glass * rpcinfo: ping a particular rpc program
15 1.1 glass * or dump the portmapper
16 1.1 glass */
17 1.1 glass
18 1.1 glass /*
19 1.1 glass * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
20 1.1 glass * unrestricted use provided that this legend is included on all tape
21 1.1 glass * media and as a part of the software program in whole or part. Users
22 1.1 glass * may copy or modify Sun RPC without charge, but are not authorized
23 1.1 glass * to license or distribute it to anyone else except as part of a product or
24 1.1 glass * program developed by the user.
25 1.1 glass *
26 1.1 glass * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
27 1.1 glass * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
28 1.1 glass * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
29 1.1 glass *
30 1.1 glass * Sun RPC is provided with no support and without any obligation on the
31 1.1 glass * part of Sun Microsystems, Inc. to assist in its use, correction,
32 1.1 glass * modification or enhancement.
33 1.1 glass *
34 1.1 glass * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
35 1.1 glass * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
36 1.1 glass * OR ANY PART THEREOF.
37 1.1 glass *
38 1.1 glass * In no event will Sun Microsystems, Inc. be liable for any lost revenue
39 1.1 glass * or profits or other special, indirect and consequential damages, even if
40 1.1 glass * Sun has been advised of the possibility of such damages.
41 1.1 glass *
42 1.1 glass * Sun Microsystems, Inc.
43 1.1 glass * 2550 Garcia Avenue
44 1.1 glass * Mountain View, California 94043
45 1.1 glass */
46 1.1 glass
47 1.1 glass #include <rpc/rpc.h>
48 1.1 glass #include <stdio.h>
49 1.1 glass #include <sys/socket.h>
50 1.1 glass #include <netdb.h>
51 1.1 glass #include <rpc/pmap_prot.h>
52 1.1 glass #include <rpc/pmap_clnt.h>
53 1.1 glass #include <signal.h>
54 1.1 glass #include <ctype.h>
55 1.4 mycroft #include <arpa/inet.h>
56 1.1 glass
57 1.1 glass #define MAXHOSTLEN 256
58 1.1 glass
59 1.1 glass #define MIN_VERS ((u_long) 0)
60 1.2 mycroft #define MAX_VERS ((u_long) 4294967295UL)
61 1.1 glass
62 1.1 glass static void udpping(/*u_short portflag, int argc, char **argv*/);
63 1.1 glass static void tcpping(/*u_short portflag, int argc, char **argv*/);
64 1.1 glass static int pstatus(/*CLIENT *client, u_long prognum, u_long vers*/);
65 1.1 glass static void pmapdump(/*int argc, char **argv*/);
66 1.1 glass static bool_t reply_proc(/*void *res, struct sockaddr_in *who*/);
67 1.1 glass static void brdcst(/*int argc, char **argv*/);
68 1.1 glass static void deletereg(/* int argc, char **argv */) ;
69 1.1 glass static void usage(/*void*/);
70 1.1 glass static u_long getprognum(/*char *arg*/);
71 1.1 glass static u_long getvers(/*char *arg*/);
72 1.1 glass static void get_inet_address(/*struct sockaddr_in *addr, char *host*/);
73 1.1 glass
74 1.1 glass /*
75 1.1 glass * Functions to be performed.
76 1.1 glass */
77 1.1 glass #define NONE 0 /* no function */
78 1.1 glass #define PMAPDUMP 1 /* dump portmapper registrations */
79 1.1 glass #define TCPPING 2 /* ping TCP service */
80 1.1 glass #define UDPPING 3 /* ping UDP service */
81 1.1 glass #define BRDCST 4 /* ping broadcast UDP service */
82 1.1 glass #define DELETES 5 /* delete registration for the service */
83 1.1 glass
84 1.1 glass int
85 1.1 glass main(argc, argv)
86 1.1 glass int argc;
87 1.1 glass char **argv;
88 1.1 glass {
89 1.1 glass register int c;
90 1.1 glass extern char *optarg;
91 1.1 glass extern int optind;
92 1.1 glass int errflg;
93 1.1 glass int function;
94 1.1 glass u_short portnum;
95 1.1 glass
96 1.1 glass function = NONE;
97 1.1 glass portnum = 0;
98 1.1 glass errflg = 0;
99 1.1 glass while ((c = getopt(argc, argv, "ptubdn:")) != EOF) {
100 1.1 glass switch (c) {
101 1.1 glass
102 1.1 glass case 'p':
103 1.1 glass if (function != NONE)
104 1.1 glass errflg = 1;
105 1.1 glass else
106 1.1 glass function = PMAPDUMP;
107 1.1 glass break;
108 1.1 glass
109 1.1 glass case 't':
110 1.1 glass if (function != NONE)
111 1.1 glass errflg = 1;
112 1.1 glass else
113 1.1 glass function = TCPPING;
114 1.1 glass break;
115 1.1 glass
116 1.1 glass case 'u':
117 1.1 glass if (function != NONE)
118 1.1 glass errflg = 1;
119 1.1 glass else
120 1.1 glass function = UDPPING;
121 1.1 glass break;
122 1.1 glass
123 1.1 glass case 'b':
124 1.1 glass if (function != NONE)
125 1.1 glass errflg = 1;
126 1.1 glass else
127 1.1 glass function = BRDCST;
128 1.1 glass break;
129 1.1 glass
130 1.1 glass case 'n':
131 1.1 glass portnum = (u_short) atoi(optarg); /* hope we don't get bogus # */
132 1.1 glass break;
133 1.1 glass
134 1.1 glass case 'd':
135 1.1 glass if (function != NONE)
136 1.1 glass errflg = 1;
137 1.1 glass else
138 1.1 glass function = DELETES;
139 1.1 glass break;
140 1.1 glass
141 1.1 glass case '?':
142 1.1 glass errflg = 1;
143 1.1 glass }
144 1.1 glass }
145 1.1 glass
146 1.1 glass if (errflg || function == NONE) {
147 1.1 glass usage();
148 1.1 glass return (1);
149 1.1 glass }
150 1.1 glass
151 1.1 glass switch (function) {
152 1.1 glass
153 1.1 glass case PMAPDUMP:
154 1.1 glass if (portnum != 0) {
155 1.1 glass usage();
156 1.1 glass return (1);
157 1.1 glass }
158 1.1 glass pmapdump(argc - optind, argv + optind);
159 1.1 glass break;
160 1.1 glass
161 1.1 glass case UDPPING:
162 1.1 glass udpping(portnum, argc - optind, argv + optind);
163 1.1 glass break;
164 1.1 glass
165 1.1 glass case TCPPING:
166 1.1 glass tcpping(portnum, argc - optind, argv + optind);
167 1.1 glass break;
168 1.1 glass
169 1.1 glass case BRDCST:
170 1.1 glass if (portnum != 0) {
171 1.1 glass usage();
172 1.1 glass return (1);
173 1.1 glass }
174 1.1 glass brdcst(argc - optind, argv + optind);
175 1.1 glass break;
176 1.1 glass
177 1.1 glass case DELETES:
178 1.1 glass deletereg(argc - optind, argv + optind);
179 1.1 glass break;
180 1.1 glass }
181 1.1 glass
182 1.1 glass return (0);
183 1.1 glass }
184 1.1 glass
185 1.1 glass static void
186 1.1 glass udpping(portnum, argc, argv)
187 1.1 glass u_short portnum;
188 1.1 glass int argc;
189 1.1 glass char **argv;
190 1.1 glass {
191 1.1 glass struct timeval to;
192 1.1 glass struct sockaddr_in addr;
193 1.1 glass enum clnt_stat rpc_stat;
194 1.1 glass CLIENT *client;
195 1.1 glass u_long prognum, vers, minvers, maxvers;
196 1.1 glass int sock = RPC_ANYSOCK;
197 1.1 glass struct rpc_err rpcerr;
198 1.1 glass int failure;
199 1.1 glass
200 1.1 glass if (argc < 2 || argc > 3) {
201 1.1 glass usage();
202 1.1 glass exit(1);
203 1.1 glass }
204 1.1 glass prognum = getprognum(argv[1]);
205 1.1 glass get_inet_address(&addr, argv[0]);
206 1.1 glass /* Open the socket here so it will survive calls to clnt_destroy */
207 1.1 glass sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP);
208 1.1 glass if (sock < 0) {
209 1.1 glass perror("rpcinfo: socket");
210 1.1 glass exit(1);
211 1.1 glass }
212 1.1 glass failure = 0;
213 1.1 glass if (argc == 2) {
214 1.1 glass /*
215 1.1 glass * A call to version 0 should fail with a program/version
216 1.1 glass * mismatch, and give us the range of versions supported.
217 1.1 glass */
218 1.1 glass addr.sin_port = htons(portnum);
219 1.1 glass to.tv_sec = 5;
220 1.1 glass to.tv_usec = 0;
221 1.1 glass if ((client = clntudp_create(&addr, prognum, (u_long)0,
222 1.1 glass to, &sock)) == NULL) {
223 1.1 glass clnt_pcreateerror("rpcinfo");
224 1.1 glass printf("program %lu is not available\n",
225 1.1 glass prognum);
226 1.1 glass exit(1);
227 1.1 glass }
228 1.1 glass to.tv_sec = 10;
229 1.1 glass to.tv_usec = 0;
230 1.1 glass rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
231 1.1 glass xdr_void, (char *)NULL, to);
232 1.1 glass if (rpc_stat == RPC_PROGVERSMISMATCH) {
233 1.1 glass clnt_geterr(client, &rpcerr);
234 1.1 glass minvers = rpcerr.re_vers.low;
235 1.1 glass maxvers = rpcerr.re_vers.high;
236 1.1 glass } else if (rpc_stat == RPC_SUCCESS) {
237 1.1 glass /*
238 1.1 glass * Oh dear, it DOES support version 0.
239 1.1 glass * Let's try version MAX_VERS.
240 1.1 glass */
241 1.1 glass addr.sin_port = htons(portnum);
242 1.1 glass to.tv_sec = 5;
243 1.1 glass to.tv_usec = 0;
244 1.1 glass if ((client = clntudp_create(&addr, prognum, MAX_VERS,
245 1.1 glass to, &sock)) == NULL) {
246 1.1 glass clnt_pcreateerror("rpcinfo");
247 1.1 glass printf("program %lu version %lu is not available\n",
248 1.1 glass prognum, MAX_VERS);
249 1.1 glass exit(1);
250 1.1 glass }
251 1.1 glass to.tv_sec = 10;
252 1.1 glass to.tv_usec = 0;
253 1.1 glass rpc_stat = clnt_call(client, NULLPROC, xdr_void,
254 1.1 glass (char *)NULL, xdr_void, (char *)NULL, to);
255 1.1 glass if (rpc_stat == RPC_PROGVERSMISMATCH) {
256 1.1 glass clnt_geterr(client, &rpcerr);
257 1.1 glass minvers = rpcerr.re_vers.low;
258 1.1 glass maxvers = rpcerr.re_vers.high;
259 1.1 glass } else if (rpc_stat == RPC_SUCCESS) {
260 1.1 glass /*
261 1.1 glass * It also supports version MAX_VERS.
262 1.1 glass * Looks like we have a wise guy.
263 1.1 glass * OK, we give them information on all
264 1.1 glass * 4 billion versions they support...
265 1.1 glass */
266 1.1 glass minvers = 0;
267 1.1 glass maxvers = MAX_VERS;
268 1.1 glass } else {
269 1.1 glass (void) pstatus(client, prognum, MAX_VERS);
270 1.1 glass exit(1);
271 1.1 glass }
272 1.1 glass } else {
273 1.1 glass (void) pstatus(client, prognum, (u_long)0);
274 1.1 glass exit(1);
275 1.1 glass }
276 1.1 glass clnt_destroy(client);
277 1.1 glass for (vers = minvers; vers <= maxvers; vers++) {
278 1.1 glass addr.sin_port = htons(portnum);
279 1.1 glass to.tv_sec = 5;
280 1.1 glass to.tv_usec = 0;
281 1.1 glass if ((client = clntudp_create(&addr, prognum, vers,
282 1.1 glass to, &sock)) == NULL) {
283 1.1 glass clnt_pcreateerror("rpcinfo");
284 1.1 glass printf("program %lu version %lu is not available\n",
285 1.1 glass prognum, vers);
286 1.1 glass exit(1);
287 1.1 glass }
288 1.1 glass to.tv_sec = 10;
289 1.1 glass to.tv_usec = 0;
290 1.1 glass rpc_stat = clnt_call(client, NULLPROC, xdr_void,
291 1.1 glass (char *)NULL, xdr_void, (char *)NULL, to);
292 1.1 glass if (pstatus(client, prognum, vers) < 0)
293 1.1 glass failure = 1;
294 1.1 glass clnt_destroy(client);
295 1.1 glass }
296 1.1 glass }
297 1.1 glass else {
298 1.1 glass vers = getvers(argv[2]);
299 1.1 glass addr.sin_port = htons(portnum);
300 1.1 glass to.tv_sec = 5;
301 1.1 glass to.tv_usec = 0;
302 1.1 glass if ((client = clntudp_create(&addr, prognum, vers,
303 1.1 glass to, &sock)) == NULL) {
304 1.1 glass clnt_pcreateerror("rpcinfo");
305 1.1 glass printf("program %lu version %lu is not available\n",
306 1.1 glass prognum, vers);
307 1.1 glass exit(1);
308 1.1 glass }
309 1.1 glass to.tv_sec = 10;
310 1.1 glass to.tv_usec = 0;
311 1.1 glass rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
312 1.1 glass xdr_void, (char *)NULL, to);
313 1.1 glass if (pstatus(client, prognum, vers) < 0)
314 1.1 glass failure = 1;
315 1.1 glass }
316 1.1 glass (void) close(sock); /* Close it up again */
317 1.1 glass if (failure)
318 1.1 glass exit(1);
319 1.1 glass }
320 1.1 glass
321 1.1 glass static void
322 1.1 glass tcpping(portnum, argc, argv)
323 1.1 glass u_short portnum;
324 1.1 glass int argc;
325 1.1 glass char **argv;
326 1.1 glass {
327 1.1 glass struct timeval to;
328 1.1 glass struct sockaddr_in addr;
329 1.1 glass enum clnt_stat rpc_stat;
330 1.1 glass CLIENT *client;
331 1.1 glass u_long prognum, vers, minvers, maxvers;
332 1.1 glass int sock = RPC_ANYSOCK;
333 1.1 glass struct rpc_err rpcerr;
334 1.1 glass int failure;
335 1.1 glass
336 1.1 glass if (argc < 2 || argc > 3) {
337 1.1 glass usage();
338 1.1 glass exit(1);
339 1.1 glass }
340 1.1 glass prognum = getprognum(argv[1]);
341 1.1 glass get_inet_address(&addr, argv[0]);
342 1.1 glass failure = 0;
343 1.1 glass if (argc == 2) {
344 1.1 glass /*
345 1.1 glass * A call to version 0 should fail with a program/version
346 1.1 glass * mismatch, and give us the range of versions supported.
347 1.1 glass */
348 1.1 glass addr.sin_port = htons(portnum);
349 1.1 glass if ((client = clnttcp_create(&addr, prognum, MIN_VERS,
350 1.1 glass &sock, 0, 0)) == NULL) {
351 1.1 glass clnt_pcreateerror("rpcinfo");
352 1.1 glass printf("program %lu is not available\n",
353 1.1 glass prognum);
354 1.1 glass exit(1);
355 1.1 glass }
356 1.1 glass to.tv_sec = 10;
357 1.1 glass to.tv_usec = 0;
358 1.1 glass rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
359 1.1 glass xdr_void, (char *)NULL, to);
360 1.1 glass if (rpc_stat == RPC_PROGVERSMISMATCH) {
361 1.1 glass clnt_geterr(client, &rpcerr);
362 1.1 glass minvers = rpcerr.re_vers.low;
363 1.1 glass maxvers = rpcerr.re_vers.high;
364 1.1 glass } else if (rpc_stat == RPC_SUCCESS) {
365 1.1 glass /*
366 1.1 glass * Oh dear, it DOES support version 0.
367 1.1 glass * Let's try version MAX_VERS.
368 1.1 glass */
369 1.1 glass addr.sin_port = htons(portnum);
370 1.1 glass if ((client = clnttcp_create(&addr, prognum, MAX_VERS,
371 1.1 glass &sock, 0, 0)) == NULL) {
372 1.1 glass clnt_pcreateerror("rpcinfo");
373 1.1 glass printf("program %lu version %lu is not available\n",
374 1.1 glass prognum, MAX_VERS);
375 1.1 glass exit(1);
376 1.1 glass }
377 1.1 glass to.tv_sec = 10;
378 1.1 glass to.tv_usec = 0;
379 1.1 glass rpc_stat = clnt_call(client, NULLPROC, xdr_void,
380 1.1 glass (char *)NULL, xdr_void, (char *)NULL, to);
381 1.1 glass if (rpc_stat == RPC_PROGVERSMISMATCH) {
382 1.1 glass clnt_geterr(client, &rpcerr);
383 1.1 glass minvers = rpcerr.re_vers.low;
384 1.1 glass maxvers = rpcerr.re_vers.high;
385 1.1 glass } else if (rpc_stat == RPC_SUCCESS) {
386 1.1 glass /*
387 1.1 glass * It also supports version MAX_VERS.
388 1.1 glass * Looks like we have a wise guy.
389 1.1 glass * OK, we give them information on all
390 1.1 glass * 4 billion versions they support...
391 1.1 glass */
392 1.1 glass minvers = 0;
393 1.1 glass maxvers = MAX_VERS;
394 1.1 glass } else {
395 1.1 glass (void) pstatus(client, prognum, MAX_VERS);
396 1.1 glass exit(1);
397 1.1 glass }
398 1.1 glass } else {
399 1.1 glass (void) pstatus(client, prognum, MIN_VERS);
400 1.1 glass exit(1);
401 1.1 glass }
402 1.1 glass clnt_destroy(client);
403 1.1 glass (void) close(sock);
404 1.1 glass sock = RPC_ANYSOCK; /* Re-initialize it for later */
405 1.1 glass for (vers = minvers; vers <= maxvers; vers++) {
406 1.1 glass addr.sin_port = htons(portnum);
407 1.1 glass if ((client = clnttcp_create(&addr, prognum, vers,
408 1.1 glass &sock, 0, 0)) == NULL) {
409 1.1 glass clnt_pcreateerror("rpcinfo");
410 1.1 glass printf("program %lu version %lu is not available\n",
411 1.1 glass prognum, vers);
412 1.1 glass exit(1);
413 1.1 glass }
414 1.1 glass to.tv_usec = 0;
415 1.1 glass to.tv_sec = 10;
416 1.1 glass rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
417 1.1 glass xdr_void, (char *)NULL, to);
418 1.1 glass if (pstatus(client, prognum, vers) < 0)
419 1.1 glass failure = 1;
420 1.1 glass clnt_destroy(client);
421 1.1 glass (void) close(sock);
422 1.1 glass sock = RPC_ANYSOCK;
423 1.1 glass }
424 1.1 glass }
425 1.1 glass else {
426 1.1 glass vers = getvers(argv[2]);
427 1.1 glass addr.sin_port = htons(portnum);
428 1.1 glass if ((client = clnttcp_create(&addr, prognum, vers, &sock,
429 1.1 glass 0, 0)) == NULL) {
430 1.1 glass clnt_pcreateerror("rpcinfo");
431 1.1 glass printf("program %lu version %lu is not available\n",
432 1.1 glass prognum, vers);
433 1.1 glass exit(1);
434 1.1 glass }
435 1.1 glass to.tv_usec = 0;
436 1.1 glass to.tv_sec = 10;
437 1.1 glass rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
438 1.1 glass xdr_void, (char *)NULL, to);
439 1.1 glass if (pstatus(client, prognum, vers) < 0)
440 1.1 glass failure = 1;
441 1.1 glass }
442 1.1 glass if (failure)
443 1.1 glass exit(1);
444 1.1 glass }
445 1.1 glass
446 1.1 glass /*
447 1.1 glass * This routine should take a pointer to an "rpc_err" structure, rather than
448 1.1 glass * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
449 1.1 glass * a CLIENT structure rather than a pointer to an "rpc_err" structure.
450 1.1 glass * As such, we have to keep the CLIENT structure around in order to print
451 1.1 glass * a good error message.
452 1.1 glass */
453 1.1 glass static int
454 1.1 glass pstatus(client, prognum, vers)
455 1.1 glass register CLIENT *client;
456 1.1 glass u_long prognum;
457 1.1 glass u_long vers;
458 1.1 glass {
459 1.1 glass struct rpc_err rpcerr;
460 1.1 glass
461 1.1 glass clnt_geterr(client, &rpcerr);
462 1.1 glass if (rpcerr.re_status != RPC_SUCCESS) {
463 1.1 glass clnt_perror(client, "rpcinfo");
464 1.1 glass printf("program %lu version %lu is not available\n",
465 1.1 glass prognum, vers);
466 1.1 glass return (-1);
467 1.1 glass } else {
468 1.1 glass printf("program %lu version %lu ready and waiting\n",
469 1.1 glass prognum, vers);
470 1.1 glass return (0);
471 1.1 glass }
472 1.1 glass }
473 1.1 glass
474 1.1 glass static void
475 1.1 glass pmapdump(argc, argv)
476 1.1 glass int argc;
477 1.1 glass char **argv;
478 1.1 glass {
479 1.1 glass struct sockaddr_in server_addr;
480 1.1 glass register struct hostent *hp;
481 1.1 glass struct pmaplist *head = NULL;
482 1.1 glass int socket = RPC_ANYSOCK;
483 1.1 glass struct timeval minutetimeout;
484 1.1 glass register CLIENT *client;
485 1.1 glass struct rpcent *rpc;
486 1.1 glass
487 1.1 glass if (argc > 1) {
488 1.1 glass usage();
489 1.1 glass exit(1);
490 1.1 glass }
491 1.1 glass if (argc == 1)
492 1.1 glass get_inet_address(&server_addr, argv[0]);
493 1.1 glass else {
494 1.1 glass bzero((char *)&server_addr, sizeof server_addr);
495 1.1 glass server_addr.sin_family = AF_INET;
496 1.1 glass if ((hp = gethostbyname("localhost")) != NULL)
497 1.1 glass bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
498 1.1 glass hp->h_length);
499 1.1 glass else
500 1.4 mycroft (void) inet_aton("0.0.0.0", &server_addr.sin_addr);
501 1.1 glass }
502 1.1 glass minutetimeout.tv_sec = 60;
503 1.1 glass minutetimeout.tv_usec = 0;
504 1.1 glass server_addr.sin_port = htons(PMAPPORT);
505 1.1 glass if ((client = clnttcp_create(&server_addr, PMAPPROG,
506 1.1 glass PMAPVERS, &socket, 50, 500)) == NULL) {
507 1.1 glass clnt_pcreateerror("rpcinfo: can't contact portmapper");
508 1.1 glass exit(1);
509 1.1 glass }
510 1.1 glass if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
511 1.1 glass xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
512 1.1 glass fprintf(stderr, "rpcinfo: can't contact portmapper: ");
513 1.1 glass clnt_perror(client, "rpcinfo");
514 1.1 glass exit(1);
515 1.1 glass }
516 1.1 glass if (head == NULL) {
517 1.1 glass printf("No remote programs registered.\n");
518 1.1 glass } else {
519 1.1 glass printf(" program vers proto port\n");
520 1.1 glass for (; head != NULL; head = head->pml_next) {
521 1.1 glass printf("%10ld%5ld",
522 1.1 glass head->pml_map.pm_prog,
523 1.1 glass head->pml_map.pm_vers);
524 1.1 glass if (head->pml_map.pm_prot == IPPROTO_UDP)
525 1.1 glass printf("%6s", "udp");
526 1.1 glass else if (head->pml_map.pm_prot == IPPROTO_TCP)
527 1.1 glass printf("%6s", "tcp");
528 1.1 glass else
529 1.1 glass printf("%6ld", head->pml_map.pm_prot);
530 1.1 glass printf("%7ld", head->pml_map.pm_port);
531 1.1 glass rpc = getrpcbynumber(head->pml_map.pm_prog);
532 1.1 glass if (rpc)
533 1.1 glass printf(" %s\n", rpc->r_name);
534 1.1 glass else
535 1.1 glass printf("\n");
536 1.1 glass }
537 1.1 glass }
538 1.1 glass }
539 1.1 glass
540 1.1 glass /*
541 1.1 glass * reply_proc collects replies from the broadcast.
542 1.1 glass * to get a unique list of responses the output of rpcinfo should
543 1.1 glass * be piped through sort(1) and then uniq(1).
544 1.1 glass */
545 1.1 glass
546 1.1 glass /*ARGSUSED*/
547 1.1 glass static bool_t
548 1.1 glass reply_proc(res, who)
549 1.1 glass void *res; /* Nothing comes back */
550 1.1 glass struct sockaddr_in *who; /* Who sent us the reply */
551 1.1 glass {
552 1.1 glass register struct hostent *hp;
553 1.1 glass
554 1.1 glass hp = gethostbyaddr((char *) &who->sin_addr, sizeof who->sin_addr,
555 1.1 glass AF_INET);
556 1.1 glass printf("%s %s\n", inet_ntoa(who->sin_addr),
557 1.1 glass (hp == NULL) ? "(unknown)" : hp->h_name);
558 1.1 glass return(FALSE);
559 1.1 glass }
560 1.1 glass
561 1.1 glass static void
562 1.1 glass brdcst(argc, argv)
563 1.1 glass int argc;
564 1.1 glass char **argv;
565 1.1 glass {
566 1.1 glass enum clnt_stat rpc_stat;
567 1.1 glass u_long prognum, vers;
568 1.1 glass
569 1.1 glass if (argc != 2) {
570 1.1 glass usage();
571 1.1 glass exit(1);
572 1.1 glass }
573 1.1 glass prognum = getprognum(argv[0]);
574 1.1 glass vers = getvers(argv[1]);
575 1.1 glass rpc_stat = clnt_broadcast(prognum, vers, NULLPROC, xdr_void,
576 1.1 glass (char *)NULL, xdr_void, (char *)NULL, reply_proc);
577 1.1 glass if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) {
578 1.1 glass fprintf(stderr, "rpcinfo: broadcast failed: %s\n",
579 1.1 glass clnt_sperrno(rpc_stat));
580 1.1 glass exit(1);
581 1.1 glass }
582 1.1 glass exit(0);
583 1.1 glass }
584 1.1 glass
585 1.1 glass static void
586 1.1 glass deletereg(argc, argv)
587 1.1 glass int argc;
588 1.1 glass char **argv;
589 1.1 glass { u_long prog_num, version_num ;
590 1.1 glass
591 1.1 glass if (argc != 2) {
592 1.1 glass usage() ;
593 1.1 glass exit(1) ;
594 1.1 glass }
595 1.1 glass if (getuid()) { /* This command allowed only to root */
596 1.1 glass fprintf(stderr, "Sorry. You are not root\n") ;
597 1.1 glass exit(1) ;
598 1.1 glass }
599 1.1 glass prog_num = getprognum(argv[0]);
600 1.1 glass version_num = getvers(argv[1]);
601 1.1 glass if ((pmap_unset(prog_num, version_num)) == 0) {
602 1.1 glass fprintf(stderr, "rpcinfo: Could not delete registration for prog %s version %s\n",
603 1.1 glass argv[0], argv[1]) ;
604 1.1 glass exit(1) ;
605 1.1 glass }
606 1.1 glass }
607 1.1 glass
608 1.1 glass static void
609 1.1 glass usage()
610 1.1 glass {
611 1.1 glass fprintf(stderr, "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n");
612 1.1 glass fprintf(stderr, " rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n");
613 1.1 glass fprintf(stderr, " rpcinfo -p [ host ]\n");
614 1.1 glass fprintf(stderr, " rpcinfo -b prognum versnum\n");
615 1.1 glass fprintf(stderr, " rpcinfo -d prognum versnum\n") ;
616 1.1 glass }
617 1.1 glass
618 1.1 glass static u_long
619 1.1 glass getprognum(arg)
620 1.1 glass char *arg;
621 1.1 glass {
622 1.1 glass register struct rpcent *rpc;
623 1.1 glass register u_long prognum;
624 1.1 glass
625 1.1 glass if (isalpha(*arg)) {
626 1.1 glass rpc = getrpcbyname(arg);
627 1.1 glass if (rpc == NULL) {
628 1.1 glass fprintf(stderr, "rpcinfo: %s is unknown service\n",
629 1.1 glass arg);
630 1.1 glass exit(1);
631 1.1 glass }
632 1.1 glass prognum = rpc->r_number;
633 1.1 glass } else {
634 1.1 glass prognum = (u_long) atoi(arg);
635 1.1 glass }
636 1.1 glass
637 1.1 glass return (prognum);
638 1.1 glass }
639 1.1 glass
640 1.1 glass static u_long
641 1.1 glass getvers(arg)
642 1.1 glass char *arg;
643 1.1 glass {
644 1.1 glass register u_long vers;
645 1.1 glass
646 1.1 glass vers = (int) atoi(arg);
647 1.1 glass return (vers);
648 1.1 glass }
649 1.1 glass
650 1.1 glass static void
651 1.1 glass get_inet_address(addr, host)
652 1.1 glass struct sockaddr_in *addr;
653 1.1 glass char *host;
654 1.1 glass {
655 1.1 glass register struct hostent *hp;
656 1.1 glass
657 1.1 glass bzero((char *)addr, sizeof *addr);
658 1.4 mycroft if (inet_aton(host, &addr->sin_addr) == 0) {
659 1.1 glass if ((hp = gethostbyname(host)) == NULL) {
660 1.1 glass fprintf(stderr, "rpcinfo: %s is unknown host\n", host);
661 1.1 glass exit(1);
662 1.1 glass }
663 1.1 glass bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length);
664 1.1 glass }
665 1.1 glass addr->sin_family = AF_INET;
666 1.1 glass }
667