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