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