1 /* $NetBSD: rpcinfo.c,v 1.28 2009/04/13 07:04:54 lukem Exp $ */
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or
9 * program developed by the user.
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement.
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF.
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages.
27 * Sun Microsystems, Inc.
29 * Mountain View, California 94043
33 * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
36 /* #ident "@(#)rpcinfo.c 1.18 93/07/05 SMI" */
40 static char sccsid
[] = "@(#)rpcinfo.c 1.16 89/04/05 Copyr 1986 Sun Micro";
45 * rpcinfo: ping a particular rpc program
46 * or dump the registered programs on the remote machine.
50 * We are for now defining PORTMAP here. It doesnt even compile
51 * unless it is defined.
58 * If PORTMAP is defined, rpcinfo will talk to both portmapper and
59 * rpcbind programs; else it talks only to rpcbind. In the latter case
60 * all the portmapper specific options such as -u, -t, -p become void.
62 #include <sys/types.h>
63 #include <sys/socket.h>
64 #include <sys/param.h>
68 #include <rpc/rpcb_prot.h>
69 #include <rpc/rpcent.h>
70 #include <rpc/nettype.h>
77 #ifdef PORTMAP /* Support for version 2 portmapper */
78 #include <netinet/in.h>
80 #include <arpa/inet.h>
81 #include <rpc/pmap_prot.h>
82 #include <rpc/pmap_clnt.h>
85 #define MIN_VERS ((u_long)0)
86 #define MAX_VERS ((u_long)4294967295UL)
87 #define UNKNOWN "unknown"
90 * Functions to be performed.
92 #define NONE 0 /* no function */
93 #define PMAPDUMP 1 /* dump portmapper registrations */
94 #define TCPPING 2 /* ping TCP service */
95 #define UDPPING 3 /* ping UDP service */
96 #define BROADCAST 4 /* ping broadcast service */
97 #define DELETES 5 /* delete registration for the service */
98 #define ADDRPING 6 /* pings at the given address */
99 #define PROGPING 7 /* pings a program on a given host */
100 #define RPCBDUMP 8 /* dump rpcbind registrations */
101 #define RPCBDUMP_SHORT 9 /* dump rpcbind registrations - short version */
102 #define RPCBADDRLIST 10 /* dump addr list about one prog */
103 #define RPCBGETSTAT 11 /* Get statistics */
107 struct netidlist
*next
;
112 struct verslist
*next
;
115 struct rpcbdump_short
{
117 struct verslist
*vlist
;
118 struct netidlist
*nlist
;
119 struct rpcbdump_short
*next
;
126 static void ip_ping(u_short
, const char *, int, char **);
127 static CLIENT
*clnt_com_create(struct sockaddr_in
*, u_long
, u_long
, int *,
129 static void pmapdump(int, char **);
130 static void get_inet_address(struct sockaddr_in
*, const char *);
133 static bool_t
reply_proc(void *, struct netbuf
*, struct netconfig
*);
134 static void brdcst(int, char **);
135 static void addrping(char *, char *, int, char **);
136 static void progping(char *, int, char **);
137 static CLIENT
*clnt_addr_create(char *, struct netconfig
*, u_long
, u_long
);
138 static CLIENT
*clnt_rpcbind_create(char *, int, struct netbuf
**);
139 static CLIENT
*getclnthandle(char *, struct netconfig
*, u_long
,
141 static CLIENT
*local_rpcb(u_long
, u_long
);
142 static int pstatus(CLIENT
*, u_long
, u_long
);
143 static void rpcbdump(int, char *, int, char **);
144 static void rpcbgetstat(int, char **);
145 static void rpcbaddrlist(char *, int, char **);
146 static void deletereg(char *, int, char **);
147 static void print_rmtcallstat(int, rpcb_stat
*);
148 static void print_getaddrstat(int, rpcb_stat
*);
149 static void usage(void);
150 static u_long
getprognum(char *);
151 static u_long
getvers(char *);
152 static char *spaces(int);
153 static bool_t
add_version(struct rpcbdump_short
*, u_long
);
154 static bool_t
add_netid(struct rpcbdump_short
*, char *);
156 int main(int argc
, char **argv
);
159 main(int argc
, char **argv
)
165 char *address
= NULL
;
174 while ((c
= getopt(argc
, argv
, "a:bdlmn:pstT:u")) != -1) {
176 while ((c
= getopt(argc
, argv
, "a:bdlmn:sT:")) != -1) {
181 if (function
!= NONE
)
188 if (function
!= NONE
)
195 if (function
!= NONE
)
202 portnum
= (u_short
) strtol(optarg
, &strptr
, 10);
203 if (strptr
== optarg
|| *strptr
!= '\0')
204 errx(1, "Illegal port number `%s'", optarg
);
209 if (function
!= NONE
)
215 if (function
!= NONE
)
218 function
= BROADCAST
;
222 if (function
!= NONE
)
229 if (function
!= NONE
)
232 function
= RPCBADDRLIST
;
236 if (function
!= NONE
)
239 function
= RPCBGETSTAT
;
243 if (function
!= NONE
)
246 function
= RPCBDUMP_SHORT
;
258 if (errflg
|| ((function
== ADDRPING
) && !netid
)) {
263 if (function
== NONE
) {
264 if (argc
- optind
> 1)
277 pmapdump(argc
- optind
, argv
+ optind
);
281 ip_ping(portnum
, "udp", argc
- optind
, argv
+ optind
);
285 ip_ping(portnum
, "tcp", argc
- optind
, argv
+ optind
);
289 brdcst(argc
- optind
, argv
+ optind
);
292 deletereg(netid
, argc
- optind
, argv
+ optind
);
295 addrping(address
, netid
, argc
- optind
, argv
+ optind
);
298 progping(netid
, argc
- optind
, argv
+ optind
);
302 rpcbdump(function
, netid
, argc
- optind
, argv
+ optind
);
305 rpcbgetstat(argc
- optind
, argv
+ optind
);
308 rpcbaddrlist(netid
, argc
- optind
, argv
+ optind
);
315 local_rpcb(u_long prog
, u_long vers
)
318 struct sockaddr_un sun
;
321 memset(&sun
, 0, sizeof sun
);
322 sock
= socket(AF_LOCAL
, SOCK_STREAM
, 0);
326 sun
.sun_family
= AF_LOCAL
;
327 strcpy(sun
.sun_path
, _PATH_RPCBINDSOCK
);
328 nbuf
.len
= sun
.sun_len
= SUN_LEN(&sun
);
329 nbuf
.maxlen
= sizeof (struct sockaddr_un
);
332 return clnt_vc_create(sock
, &nbuf
, prog
, vers
, 0, 0);
337 clnt_com_create(struct sockaddr_in
*addr
, u_long prog
, u_long vers
,
338 int *fdp
, const char *trans
)
342 if (strcmp(trans
, "tcp") == 0) {
343 clnt
= clnttcp_create(addr
, prog
, vers
, fdp
, 0, 0);
349 clnt
= clntudp_create(addr
, prog
, vers
, to
, fdp
);
352 clnt_pcreateerror(getprogname());
353 if (vers
== MIN_VERS
)
354 printf("program %lu is not available\n", prog
);
356 printf("program %lu version %lu is not available\n",
364 * If portnum is 0, then go and get the address from portmapper, which happens
365 * transparently through clnt*_create(); If version number is not given, it
366 * tries to find out the version number by making a call to version 0 and if
367 * that fails, it obtains the high order and the low order version number. If
368 * version 0 calls succeeds, it tries for MAXVERS call and repeats the same.
371 ip_ping(u_short portnum
, const char *trans
, int argc
, char **argv
)
376 struct sockaddr_in addr
;
377 enum clnt_stat rpc_stat
;
378 u_long prognum
, vers
, minvers
, maxvers
;
379 struct rpc_err rpcerr
;
382 if (argc
< 2 || argc
> 3) {
388 prognum
= getprognum(argv
[1]);
389 get_inet_address(&addr
, argv
[0]);
390 if (argc
== 2) { /* Version number not known */
392 * A call to version 0 should fail with a program/version
393 * mismatch, and give us the range of versions supported.
397 vers
= getvers(argv
[2]);
399 addr
.sin_port
= htons(portnum
);
400 client
= clnt_com_create(&addr
, prognum
, vers
, &fd
, trans
);
401 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
) xdr_void
,
402 NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
404 /* Version number was known */
405 if (pstatus(client
, prognum
, vers
) < 0)
407 (void) CLNT_DESTROY(client
);
410 /* Version number not known */
411 (void) CLNT_CONTROL(client
, CLSET_FD_NCLOSE
, NULL
);
412 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
413 clnt_geterr(client
, &rpcerr
);
414 minvers
= rpcerr
.re_vers
.low
;
415 maxvers
= rpcerr
.re_vers
.high
;
416 } else if (rpc_stat
== RPC_SUCCESS
) {
418 * Oh dear, it DOES support version 0.
419 * Let's try version MAX_VERS.
421 (void) CLNT_DESTROY(client
);
422 addr
.sin_port
= htons(portnum
);
423 client
= clnt_com_create(&addr
, prognum
, MAX_VERS
, &fd
, trans
);
424 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
) xdr_void
,
425 NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
426 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
427 clnt_geterr(client
, &rpcerr
);
428 minvers
= rpcerr
.re_vers
.low
;
429 maxvers
= rpcerr
.re_vers
.high
;
430 } else if (rpc_stat
== RPC_SUCCESS
) {
432 * It also supports version MAX_VERS.
433 * Looks like we have a wise guy.
434 * OK, we give them information on all
435 * 4 billion versions they support...
440 (void) pstatus(client
, prognum
, MAX_VERS
);
444 (void) pstatus(client
, prognum
, (u_long
)0);
447 (void) CLNT_DESTROY(client
);
448 for (vers
= minvers
; vers
<= maxvers
; vers
++) {
449 addr
.sin_port
= htons(portnum
);
450 client
= clnt_com_create(&addr
, prognum
, vers
, &fd
, trans
);
451 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
) xdr_void
,
452 NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
453 if (pstatus(client
, prognum
, vers
) < 0)
455 (void) CLNT_DESTROY(client
);
464 * Dump all the portmapper registerations
467 pmapdump(int argc
, char **argv
)
469 struct sockaddr_in server_addr
;
470 struct pmaplist
*head
= NULL
;
471 int sock
= RPC_ANYSOCK
;
472 struct timeval minutetimeout
;
473 register CLIENT
*client
;
475 enum clnt_stat clnt_st
;
476 struct rpc_err error
;
485 get_inet_address(&server_addr
, host
);
486 server_addr
.sin_port
= htons(PMAPPORT
);
487 client
= clnttcp_create(&server_addr
, PMAPPROG
, PMAPVERS
,
490 client
= local_rpcb(PMAPPROG
, PMAPVERS
);
492 if (client
== NULL
) {
493 if (rpc_createerr
.cf_stat
== RPC_TLIERROR
) {
495 * "Misc. TLI error" is not too helpful. Most likely
496 * the connection to the remote server timed out, so
497 * this error is at least less perplexing.
499 rpc_createerr
.cf_stat
= RPC_PMAPFAILURE
;
500 rpc_createerr
.cf_error
.re_status
= RPC_FAILED
;
502 clnt_pcreateerror("rpcinfo: can't contact portmapper");
506 minutetimeout
.tv_sec
= 60;
507 minutetimeout
.tv_usec
= 0;
509 clnt_st
= CLNT_CALL(client
, PMAPPROC_DUMP
, (xdrproc_t
) xdr_void
,
510 NULL
, (xdrproc_t
) xdr_pmaplist_ptr
, (char *)&head
,
512 if (clnt_st
!= RPC_SUCCESS
) {
513 if ((clnt_st
== RPC_PROGVERSMISMATCH
) ||
514 (clnt_st
== RPC_PROGUNAVAIL
)) {
515 CLNT_GETERR(client
, &error
);
516 if (error
.re_vers
.low
> PMAPVERS
) {
519 "%s does not support portmapper. Try 'rpcinfo %s' instead\n",
523 "local host does not support portmapper. Try 'rpcinfo' instead\n");
527 clnt_perror(client
, "rpcinfo: can't contact portmapper");
531 printf("No remote programs registered.\n");
533 printf(" program vers proto port service\n");
534 for (; head
!= NULL
; head
= head
->pml_next
) {
536 head
->pml_map
.pm_prog
,
537 head
->pml_map
.pm_vers
);
538 if (head
->pml_map
.pm_prot
== IPPROTO_UDP
)
539 printf("%6s", "udp");
540 else if (head
->pml_map
.pm_prot
== IPPROTO_TCP
)
541 printf("%6s", "tcp");
543 printf("%6ld", head
->pml_map
.pm_prot
);
544 printf("%7ld", head
->pml_map
.pm_port
);
545 rpc
= getrpcbynumber(head
->pml_map
.pm_prog
);
547 printf(" %s\n", rpc
->r_name
);
555 get_inet_address(struct sockaddr_in
*addr
, const char *host
)
557 struct netconfig
*nconf
;
558 struct addrinfo hints
, *res
;
561 (void) memset((char *)addr
, 0, sizeof (*addr
));
562 addr
->sin_addr
.s_addr
= inet_addr(host
);
563 if (addr
->sin_addr
.s_addr
== -1 || addr
->sin_addr
.s_addr
== 0) {
564 if ((nconf
= __rpc_getconfip("udp")) == NULL
&&
565 (nconf
= __rpc_getconfip("tcp")) == NULL
) {
566 errx(1, "Couldn't find a suitable transport");
568 memset(&hints
, 0, sizeof hints
);
569 hints
.ai_family
= AF_INET
;
570 if ((error
= getaddrinfo(host
, "rpcbind", &hints
, &res
))
572 errx(1, "%s: %s", host
, gai_strerror(error
));
574 memcpy(addr
, res
->ai_addr
, res
->ai_addrlen
);
577 (void) freenetconfigent(nconf
);
580 addr
->sin_family
= AF_INET
;
586 * reply_proc collects replies from the broadcast.
587 * to get a unique list of responses the output of rpcinfo should
588 * be piped through sort(1) and then uniq(1).
593 reply_proc(res
, who
, nconf
)
594 void *res
; /* Nothing comes back */
595 struct netbuf
*who
; /* Who sent us the reply */
596 struct netconfig
*nconf
; /* On which transport the reply came */
599 char hostbuf
[NI_MAXHOST
];
601 struct sockaddr
*sa
= (struct sockaddr
*)who
->buf
;
603 if (getnameinfo(sa
, sa
->sa_len
, hostbuf
, NI_MAXHOST
, NULL
, 0, 0)) {
608 if (!(uaddr
= taddr2uaddr(nconf
, who
))) {
611 printf("%s\t%s\n", uaddr
, hostname
);
612 if (strcmp(uaddr
, UNKNOWN
))
622 enum clnt_stat rpc_stat
;
623 u_long prognum
, vers
;
629 prognum
= getprognum(argv
[0]);
630 vers
= getvers(argv
[1]);
631 rpc_stat
= rpc_broadcast(prognum
, vers
, NULLPROC
,
632 (xdrproc_t
) xdr_void
, NULL
, (xdrproc_t
) xdr_void
,
633 NULL
, (resultproc_t
) reply_proc
, NULL
);
634 if ((rpc_stat
!= RPC_SUCCESS
) && (rpc_stat
!= RPC_TIMEDOUT
))
635 errx(1, "broadcast failed: %s", clnt_sperrno(rpc_stat
));
640 add_version(rs
, vers
)
641 struct rpcbdump_short
*rs
;
646 for (vl
= rs
->vlist
; vl
; vl
= vl
->next
)
647 if (vl
->vers
== vers
)
651 vl
= malloc(sizeof (struct verslist
));
655 vl
->next
= rs
->vlist
;
662 struct rpcbdump_short
*rs
;
665 struct netidlist
*nl
;
667 for (nl
= rs
->nlist
; nl
; nl
= nl
->next
)
668 if (strcmp(nl
->netid
, netid
) == 0)
672 nl
= malloc(sizeof (struct netidlist
));
676 nl
->next
= rs
->nlist
;
682 rpcbdump(dumptype
, netid
, argc
, argv
)
688 rpcblist_ptr head
= NULL
, p
;
689 struct timeval minutetimeout
;
690 register CLIENT
*client
= NULL
;
693 struct netidlist
*nl
;
695 struct rpcbdump_short
*rs
, *rs_tail
= NULL
;
697 enum clnt_stat clnt_st
;
698 struct rpc_err error
;
699 struct rpcbdump_short
*rs_head
= NULL
;
708 client
= clnt_rpcbind_create(host
, RPCBVERS
, NULL
);
710 struct netconfig
*nconf
;
712 nconf
= getnetconfigent(netid
);
714 nc_perror("rpcinfo: invalid transport");
717 client
= getclnthandle(host
, nconf
, RPCBVERS
, NULL
);
719 (void) freenetconfigent(nconf
);
722 client
= local_rpcb(PMAPPROG
, RPCBVERS
);
724 if (client
== NULL
) {
725 clnt_pcreateerror("rpcinfo: can't contact rpcbind");
728 minutetimeout
.tv_sec
= 60;
729 minutetimeout
.tv_usec
= 0;
730 clnt_st
= CLNT_CALL(client
, RPCBPROC_DUMP
, (xdrproc_t
) xdr_void
,
731 NULL
, (xdrproc_t
) xdr_rpcblist_ptr
, (char *) &head
,
733 if (clnt_st
!= RPC_SUCCESS
) {
734 if ((clnt_st
== RPC_PROGVERSMISMATCH
) ||
735 (clnt_st
== RPC_PROGUNAVAIL
)) {
738 CLNT_GETERR(client
, &error
);
739 if (error
.re_vers
.low
== RPCBVERS4
) {
741 clnt_control(client
, CLSET_VERS
, (char *)&vers
);
742 clnt_st
= CLNT_CALL(client
, RPCBPROC_DUMP
,
743 (xdrproc_t
) xdr_void
, NULL
,
744 (xdrproc_t
) xdr_rpcblist_ptr
, (char *) &head
,
746 if (clnt_st
!= RPC_SUCCESS
)
749 if (error
.re_vers
.high
== PMAPVERS
) {
751 struct pmaplist
*pmaphead
= NULL
;
752 rpcblist_ptr list
, prev
= NULL
;
755 clnt_control(client
, CLSET_VERS
, (char *)&vers
);
756 clnt_st
= CLNT_CALL(client
, PMAPPROC_DUMP
,
757 (xdrproc_t
) xdr_void
, NULL
,
758 (xdrproc_t
) xdr_pmaplist_ptr
,
759 (char *)&pmaphead
, minutetimeout
);
760 if (clnt_st
!= RPC_SUCCESS
)
763 * convert to rpcblist_ptr format
765 for (head
= NULL
; pmaphead
!= NULL
;
766 pmaphead
= pmaphead
->pml_next
) {
767 list
= malloc(sizeof (rpcblist
));
773 prev
->rpcb_next
= (rpcblist_ptr
) list
;
775 list
->rpcb_next
= NULL
;
776 list
->rpcb_map
.r_prog
= pmaphead
->pml_map
.pm_prog
;
777 list
->rpcb_map
.r_vers
= pmaphead
->pml_map
.pm_vers
;
778 if (pmaphead
->pml_map
.pm_prot
== IPPROTO_UDP
)
779 list
->rpcb_map
.r_netid
= strdup("udp");
780 else if (pmaphead
->pml_map
.pm_prot
== IPPROTO_TCP
)
781 list
->rpcb_map
.r_netid
= strdup("tcp");
783 #define MAXLONG_AS_STRING "2147483648"
784 list
->rpcb_map
.r_netid
=
785 malloc(strlen(MAXLONG_AS_STRING
) + 1);
786 if (list
->rpcb_map
.r_netid
== NULL
)
788 sprintf(list
->rpcb_map
.r_netid
, "%6ld",
789 pmaphead
->pml_map
.pm_prot
);
791 list
->rpcb_map
.r_owner
= UNKNOWN
;
792 low
= pmaphead
->pml_map
.pm_port
& 0xff;
793 high
= (pmaphead
->pml_map
.pm_port
>> 8) & 0xff;
794 list
->rpcb_map
.r_addr
= strdup("0.0.0.0.XXX.XXX");
795 sprintf(&list
->rpcb_map
.r_addr
[8], "%d.%d",
801 } else { /* any other error */
803 clnt_perror(client
, "rpcinfo: can't contact rpcbind: ");
808 printf("No remote programs registered.\n");
809 } else if (dumptype
== RPCBDUMP
) {
811 " program version netid address service owner\n");
812 for (p
= head
; p
!= NULL
; p
= p
->rpcb_next
) {
814 p
->rpcb_map
.r_prog
, p
->rpcb_map
.r_vers
);
815 printf("%-9s ", p
->rpcb_map
.r_netid
);
816 printf("%-22s", p
->rpcb_map
.r_addr
);
817 rpc
= getrpcbynumber(p
->rpcb_map
.r_prog
);
819 printf(" %-10s", rpc
->r_name
);
821 printf(" %-10s", "-");
822 printf(" %s\n", p
->rpcb_map
.r_owner
);
824 } else if (dumptype
== RPCBDUMP_SHORT
) {
825 for (p
= head
; p
!= NULL
; p
= p
->rpcb_next
) {
826 for (rs
= rs_head
; rs
; rs
= rs
->next
)
827 if (p
->rpcb_map
.r_prog
== rs
->prog
)
830 rs
= malloc(sizeof (struct rpcbdump_short
));
834 if (rs_head
== NULL
) {
841 rs
->prog
= p
->rpcb_map
.r_prog
;
842 rs
->owner
= p
->rpcb_map
.r_owner
;
846 if (add_version(rs
, p
->rpcb_map
.r_vers
) == FALSE
)
848 if (add_netid(rs
, p
->rpcb_map
.r_netid
) == FALSE
)
852 " program version(s) netid(s) service owner\n");
853 for (rs
= rs_head
; rs
; rs
= rs
->next
) {
856 printf("%10ld ", rs
->prog
);
857 for (vl
= rs
->vlist
; vl
; vl
= vl
->next
) {
858 sprintf(bp
, "%d", vl
->vers
);
859 bp
= bp
+ strlen(bp
);
863 printf("%-10s", buf
);
865 for (nl
= rs
->nlist
; nl
; nl
= nl
->next
) {
866 strcat(buf
, nl
->netid
);
870 printf("%-32s", buf
);
871 rpc
= getrpcbynumber(rs
->prog
);
873 printf(" %-11s", rpc
->r_name
);
875 printf(" %-11s", "-");
876 printf(" %s\n", rs
->owner
);
880 clnt_destroy(client
);
881 while (head
!= NULL
) {
882 rpcblist_ptr list
= head
->rpcb_next
;
883 if (head
->rpcb_map
.r_addr
)
884 free(head
->rpcb_map
.r_addr
);
885 if (head
->rpcb_map
.r_netid
)
886 free(head
->rpcb_map
.r_netid
);
892 rs_head
= rs_head
->next
;
896 error
: err(1, "Cannot allocate memory");
899 static char nullstring
[] = "\000";
902 rpcbaddrlist(netid
, argc
, argv
)
907 rpcb_entry_list_ptr head
= NULL
;
908 struct timeval minutetimeout
;
909 register CLIENT
*client
;
913 struct netbuf
*targaddr
;
921 client
= clnt_rpcbind_create(host
, RPCBVERS4
, &targaddr
);
923 struct netconfig
*nconf
;
925 nconf
= getnetconfigent(netid
);
927 nc_perror("rpcinfo: invalid transport");
930 client
= getclnthandle(host
, nconf
, RPCBVERS4
, &targaddr
);
932 (void) freenetconfigent(nconf
);
934 if (client
== NULL
) {
935 clnt_pcreateerror("rpcinfo: can't contact rpcbind");
938 minutetimeout
.tv_sec
= 60;
939 minutetimeout
.tv_usec
= 0;
941 parms
.r_prog
= getprognum(argv
[1]);
942 parms
.r_vers
= getvers(argv
[2]);
943 parms
.r_netid
= client
->cl_netid
;
944 if (targaddr
== NULL
) {
945 parms
.r_addr
= nullstring
; /* for XDRing */
948 * We also send the remote system the address we
949 * used to contact it in case it can help it
950 * connect back with us
952 struct netconfig
*nconf
;
954 nconf
= getnetconfigent(client
->cl_netid
);
956 parms
.r_addr
= taddr2uaddr(nconf
, targaddr
);
957 if (parms
.r_addr
== NULL
)
958 parms
.r_addr
= nullstring
;
959 freenetconfigent(nconf
);
961 parms
.r_addr
= nullstring
; /* for XDRing */
966 parms
.r_owner
= nullstring
;
968 if (CLNT_CALL(client
, RPCBPROC_GETADDRLIST
, (xdrproc_t
) xdr_rpcb
,
969 (char *) &parms
, (xdrproc_t
) xdr_rpcb_entry_list_ptr
,
970 (char *) &head
, minutetimeout
) != RPC_SUCCESS
) {
971 clnt_perror(client
, "rpcinfo: can't contact rpcbind: ");
975 printf("No remote programs registered.\n");
978 " program vers tp_family/name/class address\t\t service\n");
979 for (; head
!= NULL
; head
= head
->rpcb_entry_next
) {
983 re
= &head
->rpcb_entry_map
;
985 parms
.r_prog
, parms
.r_vers
);
986 sprintf(buf
, "%s/%s/%s ",
987 re
->r_nc_protofmly
, re
->r_nc_proto
,
988 re
->r_nc_semantics
== NC_TPI_CLTS
? "clts" :
989 re
->r_nc_semantics
== NC_TPI_COTS
? "cots" :
991 printf("%-24s", buf
);
992 printf("%-24s", re
->r_maddr
);
993 rpc
= getrpcbynumber(parms
.r_prog
);
995 printf(" %-13s", rpc
->r_name
);
997 printf(" %-13s", "-");
1001 clnt_destroy(client
);
1009 rpcbgetstat(argc
, argv
)
1013 rpcb_stat_byvers inf
;
1014 struct timeval minutetimeout
;
1015 register CLIENT
*client
;
1019 rpcbs_rmtcalllist
*pr
;
1022 char fieldbuf
[MAXFIELD
];
1024 char linebuf
[MAXLINE
];
1027 "NULL", "SET", "UNSET", "GETPORT",
1030 char *rpcb3hdr
[] = {
1031 "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME",
1034 char *rpcb4hdr
[] = {
1035 "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME",
1036 "U2T", "T2U", "VERADDR", "INDRECT", "GETLIST", "GETSTAT"
1043 client
= clnt_rpcbind_create(host
, RPCBVERS4
, NULL
);
1045 client
= local_rpcb(PMAPPROG
, RPCBVERS4
);
1046 if (client
== NULL
) {
1047 clnt_pcreateerror("rpcinfo: can't contact rpcbind");
1050 minutetimeout
.tv_sec
= 60;
1051 minutetimeout
.tv_usec
= 0;
1052 memset((char *)&inf
, 0, sizeof (rpcb_stat_byvers
));
1053 if (CLNT_CALL(client
, RPCBPROC_GETSTAT
, (xdrproc_t
) xdr_void
, NULL
,
1054 (xdrproc_t
) xdr_rpcb_stat_byvers
, (char *)&inf
, minutetimeout
)
1056 clnt_perror(client
, "rpcinfo: can't contact rpcbind: ");
1059 printf("PORTMAP (version 2) statistics\n");
1061 for (i
= 0; i
<= rpcb_highproc_2
; i
++) {
1065 sprintf(fieldbuf
, "%d/", inf
[RPCBVERS_2_STAT
].setinfo
);
1067 case PMAPPROC_UNSET
:
1068 sprintf(fieldbuf
, "%d/",
1069 inf
[RPCBVERS_2_STAT
].unsetinfo
);
1071 case PMAPPROC_GETPORT
:
1073 for (pa
= inf
[RPCBVERS_2_STAT
].addrinfo
; pa
;
1076 sprintf(fieldbuf
, "%d/", cnt
);
1078 case PMAPPROC_CALLIT
:
1080 for (pr
= inf
[RPCBVERS_2_STAT
].rmtinfo
; pr
;
1083 sprintf(fieldbuf
, "%d/", cnt
);
1085 default: break; /* For the remaining ones */
1087 cp
= &fieldbuf
[0] + strlen(fieldbuf
);
1088 sprintf(cp
, "%d", inf
[RPCBVERS_2_STAT
].info
[i
]);
1089 flen
= strlen(fieldbuf
);
1090 printf("%s%s", pmaphdr
[i
],
1091 spaces((TABSTOP
* (1 + flen
/ TABSTOP
))
1092 - strlen(pmaphdr
[i
])));
1093 sprintf(lp
, "%s%s", fieldbuf
,
1094 spaces(cnt
= ((TABSTOP
* (1 + flen
/ TABSTOP
))
1098 printf("\n%s\n\n", linebuf
);
1100 if (inf
[RPCBVERS_2_STAT
].info
[PMAPPROC_CALLIT
]) {
1101 printf("PMAP_RMTCALL call statistics\n");
1102 print_rmtcallstat(RPCBVERS_2_STAT
, &inf
[RPCBVERS_2_STAT
]);
1106 if (inf
[RPCBVERS_2_STAT
].info
[PMAPPROC_GETPORT
]) {
1107 printf("PMAP_GETPORT call statistics\n");
1108 print_getaddrstat(RPCBVERS_2_STAT
, &inf
[RPCBVERS_2_STAT
]);
1112 printf("RPCBIND (version 3) statistics\n");
1114 for (i
= 0; i
<= rpcb_highproc_3
; i
++) {
1118 sprintf(fieldbuf
, "%d/", inf
[RPCBVERS_3_STAT
].setinfo
);
1120 case RPCBPROC_UNSET
:
1121 sprintf(fieldbuf
, "%d/",
1122 inf
[RPCBVERS_3_STAT
].unsetinfo
);
1124 case RPCBPROC_GETADDR
:
1126 for (pa
= inf
[RPCBVERS_3_STAT
].addrinfo
; pa
;
1129 sprintf(fieldbuf
, "%d/", cnt
);
1131 case RPCBPROC_CALLIT
:
1133 for (pr
= inf
[RPCBVERS_3_STAT
].rmtinfo
; pr
;
1136 sprintf(fieldbuf
, "%d/", cnt
);
1138 default: break; /* For the remaining ones */
1140 cp
= &fieldbuf
[0] + strlen(fieldbuf
);
1141 sprintf(cp
, "%d", inf
[RPCBVERS_3_STAT
].info
[i
]);
1142 flen
= strlen(fieldbuf
);
1143 printf("%s%s", rpcb3hdr
[i
],
1144 spaces((TABSTOP
* (1 + flen
/ TABSTOP
))
1145 - strlen(rpcb3hdr
[i
])));
1146 sprintf(lp
, "%s%s", fieldbuf
,
1147 spaces(cnt
= ((TABSTOP
* (1 + flen
/ TABSTOP
))
1151 printf("\n%s\n\n", linebuf
);
1153 if (inf
[RPCBVERS_3_STAT
].info
[RPCBPROC_CALLIT
]) {
1154 printf("RPCB_RMTCALL (version 3) call statistics\n");
1155 print_rmtcallstat(RPCBVERS_3_STAT
, &inf
[RPCBVERS_3_STAT
]);
1159 if (inf
[RPCBVERS_3_STAT
].info
[RPCBPROC_GETADDR
]) {
1160 printf("RPCB_GETADDR (version 3) call statistics\n");
1161 print_getaddrstat(RPCBVERS_3_STAT
, &inf
[RPCBVERS_3_STAT
]);
1165 printf("RPCBIND (version 4) statistics\n");
1167 for (j
= 0; j
<= 9; j
+= 9) { /* Just two iterations for printing */
1169 for (i
= j
; i
<= MAX(8, rpcb_highproc_4
- 9 + j
); i
++) {
1173 sprintf(fieldbuf
, "%d/",
1174 inf
[RPCBVERS_4_STAT
].setinfo
);
1176 case RPCBPROC_UNSET
:
1177 sprintf(fieldbuf
, "%d/",
1178 inf
[RPCBVERS_4_STAT
].unsetinfo
);
1180 case RPCBPROC_GETADDR
:
1182 for (pa
= inf
[RPCBVERS_4_STAT
].addrinfo
; pa
;
1185 sprintf(fieldbuf
, "%d/", cnt
);
1187 case RPCBPROC_CALLIT
:
1189 for (pr
= inf
[RPCBVERS_4_STAT
].rmtinfo
; pr
;
1192 sprintf(fieldbuf
, "%d/", cnt
);
1194 default: break; /* For the remaining ones */
1196 cp
= &fieldbuf
[0] + strlen(fieldbuf
);
1198 * XXX: We also add RPCBPROC_GETADDRLIST queries to
1199 * RPCB_GETADDR because rpcbind includes the
1200 * RPCB_GETADDRLIST successes in RPCB_GETADDR.
1202 if (i
!= RPCBPROC_GETADDR
)
1203 sprintf(cp
, "%d", inf
[RPCBVERS_4_STAT
].info
[i
]);
1205 sprintf(cp
, "%d", inf
[RPCBVERS_4_STAT
].info
[i
] +
1206 inf
[RPCBVERS_4_STAT
].info
[RPCBPROC_GETADDRLIST
]);
1207 flen
= strlen(fieldbuf
);
1208 printf("%s%s", rpcb4hdr
[i
],
1209 spaces((TABSTOP
* (1 + flen
/ TABSTOP
))
1210 - strlen(rpcb4hdr
[i
])));
1211 sprintf(lp
, "%s%s", fieldbuf
,
1212 spaces(cnt
= ((TABSTOP
* (1 + flen
/ TABSTOP
))
1216 printf("\n%s\n", linebuf
);
1219 if (inf
[RPCBVERS_4_STAT
].info
[RPCBPROC_CALLIT
] ||
1220 inf
[RPCBVERS_4_STAT
].info
[RPCBPROC_INDIRECT
]) {
1222 printf("RPCB_RMTCALL (version 4) call statistics\n");
1223 print_rmtcallstat(RPCBVERS_4_STAT
, &inf
[RPCBVERS_4_STAT
]);
1226 if (inf
[RPCBVERS_4_STAT
].info
[RPCBPROC_GETADDR
]) {
1228 printf("RPCB_GETADDR (version 4) call statistics\n");
1229 print_getaddrstat(RPCBVERS_4_STAT
, &inf
[RPCBVERS_4_STAT
]);
1231 clnt_destroy(client
);
1235 * Delete registeration for this (prog, vers, netid)
1238 deletereg(netid
, argc
, argv
)
1243 struct netconfig
*nconf
= NULL
;
1250 nconf
= getnetconfigent(netid
);
1251 if (nconf
== NULL
) {
1252 fprintf(stderr
, "rpcinfo: netid %s not supported\n",
1257 if ((rpcb_unset(getprognum(argv
[0]), getvers(argv
[1]), nconf
)) == 0) {
1259 "rpcinfo: Could not delete registration for prog %s version %s\n",
1266 * Create and return a handle for the given nconf.
1267 * Exit if cannot create handle.
1270 clnt_addr_create(address
, nconf
, prog
, vers
)
1272 struct netconfig
*nconf
;
1277 static struct netbuf
*nbuf
;
1278 static int fd
= RPC_ANYFD
;
1280 if (fd
== RPC_ANYFD
) {
1281 if ((fd
= __rpc_nconf2fd(nconf
)) == -1) {
1282 rpc_createerr
.cf_stat
= RPC_TLIERROR
;
1283 clnt_pcreateerror("rpcinfo");
1286 /* Convert the uaddr to taddr */
1287 nbuf
= uaddr2taddr(nconf
, address
);
1289 errx(1, "No address for client handle");
1293 client
= clnt_tli_create(fd
, nconf
, nbuf
, prog
, vers
, 0, 0);
1294 if (client
== NULL
) {
1295 clnt_pcreateerror(getprogname());
1302 * If the version number is given, ping that (prog, vers); else try to find
1303 * the version numbers supported for that prog and ping all the versions.
1304 * Remote rpcbind is not contacted for this service. The requests are
1305 * sent directly to the services themselves.
1308 addrping(address
, netid
, argc
, argv
)
1316 enum clnt_stat rpc_stat
;
1317 u_long prognum
, versnum
, minvers
, maxvers
;
1318 struct rpc_err rpcerr
;
1320 struct netconfig
*nconf
;
1323 if (argc
< 1 || argc
> 2 || (netid
== NULL
)) {
1327 nconf
= getnetconfigent(netid
);
1329 errx(1, "Could not find %s", netid
);
1332 prognum
= getprognum(argv
[0]);
1333 if (argc
== 1) { /* Version number not known */
1335 * A call to version 0 should fail with a program/version
1336 * mismatch, and give us the range of versions supported.
1340 versnum
= getvers(argv
[1]);
1342 client
= clnt_addr_create(address
, nconf
, prognum
, versnum
);
1343 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
) xdr_void
,
1344 NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
1346 /* Version number was known */
1347 if (pstatus(client
, prognum
, versnum
) < 0)
1349 (void) CLNT_DESTROY(client
);
1354 /* Version number not known */
1355 (void) CLNT_CONTROL(client
, CLSET_FD_NCLOSE
, NULL
);
1356 (void) CLNT_CONTROL(client
, CLGET_FD
, (char *)&fd
);
1357 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
1358 clnt_geterr(client
, &rpcerr
);
1359 minvers
= rpcerr
.re_vers
.low
;
1360 maxvers
= rpcerr
.re_vers
.high
;
1361 } else if (rpc_stat
== RPC_SUCCESS
) {
1363 * Oh dear, it DOES support version 0.
1364 * Let's try version MAX_VERS.
1366 (void) CLNT_DESTROY(client
);
1367 client
= clnt_addr_create(address
, nconf
, prognum
, MAX_VERS
);
1368 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
) xdr_void
,
1369 NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
1370 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
1371 clnt_geterr(client
, &rpcerr
);
1372 minvers
= rpcerr
.re_vers
.low
;
1373 maxvers
= rpcerr
.re_vers
.high
;
1374 } else if (rpc_stat
== RPC_SUCCESS
) {
1376 * It also supports version MAX_VERS.
1377 * Looks like we have a wise guy.
1378 * OK, we give them information on all
1379 * 4 billion versions they support...
1384 (void) pstatus(client
, prognum
, MAX_VERS
);
1388 (void) pstatus(client
, prognum
, (u_long
)0);
1391 (void) CLNT_DESTROY(client
);
1392 for (versnum
= minvers
; versnum
<= maxvers
; versnum
++) {
1393 client
= clnt_addr_create(address
, nconf
, prognum
, versnum
);
1394 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
) xdr_void
,
1395 NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
1396 if (pstatus(client
, prognum
, versnum
) < 0)
1398 (void) CLNT_DESTROY(client
);
1407 * If the version number is given, ping that (prog, vers); else try to find
1408 * the version numbers supported for that prog and ping all the versions.
1409 * Remote rpcbind is *contacted* for this service. The requests are
1410 * then sent directly to the services themselves.
1413 progping(netid
, argc
, argv
)
1420 enum clnt_stat rpc_stat
;
1421 u_long prognum
, versnum
, minvers
, maxvers
;
1422 struct rpc_err rpcerr
;
1424 struct netconfig
*nconf
;
1426 if (argc
< 2 || argc
> 3 || (netid
== NULL
)) {
1430 prognum
= getprognum(argv
[1]);
1431 if (argc
== 2) { /* Version number not known */
1433 * A call to version 0 should fail with a program/version
1434 * mismatch, and give us the range of versions supported.
1438 versnum
= getvers(argv
[2]);
1441 nconf
= getnetconfigent(netid
);
1443 errx(1, "Could not find `%s'", netid
);
1444 client
= clnt_tp_create(argv
[0], prognum
, versnum
, nconf
);
1446 client
= clnt_create(argv
[0], prognum
, versnum
, "NETPATH");
1448 if (client
== NULL
) {
1449 clnt_pcreateerror(getprogname());
1454 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
) xdr_void
,
1455 NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
1457 /* Version number was known */
1458 if (pstatus(client
, prognum
, versnum
) < 0)
1460 (void) CLNT_DESTROY(client
);
1465 /* Version number not known */
1466 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
1467 clnt_geterr(client
, &rpcerr
);
1468 minvers
= rpcerr
.re_vers
.low
;
1469 maxvers
= rpcerr
.re_vers
.high
;
1470 } else if (rpc_stat
== RPC_SUCCESS
) {
1472 * Oh dear, it DOES support version 0.
1473 * Let's try version MAX_VERS.
1476 (void) CLNT_CONTROL(client
, CLSET_VERS
, (char *)&versnum
);
1477 rpc_stat
= CLNT_CALL(client
, NULLPROC
,
1478 (xdrproc_t
) xdr_void
, NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
1479 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
1480 clnt_geterr(client
, &rpcerr
);
1481 minvers
= rpcerr
.re_vers
.low
;
1482 maxvers
= rpcerr
.re_vers
.high
;
1483 } else if (rpc_stat
== RPC_SUCCESS
) {
1485 * It also supports version MAX_VERS.
1486 * Looks like we have a wise guy.
1487 * OK, we give them information on all
1488 * 4 billion versions they support...
1493 (void) pstatus(client
, prognum
, MAX_VERS
);
1497 (void) pstatus(client
, prognum
, (u_long
)0);
1500 for (versnum
= minvers
; versnum
<= maxvers
; versnum
++) {
1501 (void) CLNT_CONTROL(client
, CLSET_VERS
, (char *)&versnum
);
1502 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
) xdr_void
,
1503 NULL
, (xdrproc_t
) xdr_void
, NULL
, to
);
1504 if (pstatus(client
, prognum
, versnum
) < 0)
1507 (void) CLNT_DESTROY(client
);
1516 fprintf(stderr
, "usage: rpcinfo [-m | -s] [host]\n");
1518 fprintf(stderr
, " rpcinfo -p [host]\n");
1520 fprintf(stderr
, " rpcinfo -T netid host prognum [versnum]\n");
1521 fprintf(stderr
, " rpcinfo -l host prognum versnum\n");
1524 " rpcinfo [-n portnum] -u | -t host prognum [versnum]\n");
1527 " rpcinfo -a serv_address -T netid prognum [version]\n");
1528 fprintf(stderr
, " rpcinfo -b prognum versnum\n");
1529 fprintf(stderr
, " rpcinfo -d [-T netid] prognum versnum\n");
1537 register struct rpcent
*rpc
;
1538 register u_long prognum
;
1541 while (*tptr
&& isdigit((unsigned char)*tptr
++));
1542 if (*tptr
|| isalpha((unsigned char)*(tptr
- 1))) {
1543 rpc
= getrpcbyname(arg
);
1545 errx(1, "Unknown service `%s'", arg
);
1546 prognum
= rpc
->r_number
;
1548 prognum
= strtol(arg
, &strptr
, 10);
1549 if (strptr
== arg
|| *strptr
!= '\0')
1550 errx(1, "Illegal program number `%s'", arg
);
1560 register u_long vers
;
1562 vers
= (int) strtol(arg
, &strptr
, 10);
1563 if (strptr
== arg
|| *strptr
!= '\0')
1564 errx(1, "Illegal version number `%s'", arg
);
1569 * This routine should take a pointer to an "rpc_err" structure, rather than
1570 * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
1571 * a CLIENT structure rather than a pointer to an "rpc_err" structure.
1572 * As such, we have to keep the CLIENT structure around in order to print
1573 * a good error message.
1576 pstatus(client
, prog
, vers
)
1577 register CLIENT
*client
;
1581 struct rpc_err rpcerr
;
1583 clnt_geterr(client
, &rpcerr
);
1584 if (rpcerr
.re_status
!= RPC_SUCCESS
) {
1585 clnt_perror(client
, getprogname());
1586 printf("program %lu version %lu is not available\n",
1590 printf("program %lu version %lu ready and waiting\n",
1597 clnt_rpcbind_create(host
, rpcbversnum
, targaddr
)
1600 struct netbuf
**targaddr
;
1602 static char *tlist
[3] = {
1603 "circuit_n", "circuit_v", "datagram_v"
1606 struct netconfig
*nconf
;
1607 CLIENT
*clnt
= NULL
;
1610 rpc_createerr
.cf_stat
= RPC_SUCCESS
;
1611 for (i
= 0; i
< 3; i
++) {
1612 if ((handle
= __rpc_setconf(tlist
[i
])) == NULL
)
1614 while (clnt
== NULL
) {
1615 if ((nconf
= __rpc_getconf(handle
)) == NULL
) {
1616 if (rpc_createerr
.cf_stat
== RPC_SUCCESS
)
1617 rpc_createerr
.cf_stat
= RPC_UNKNOWNPROTO
;
1620 clnt
= getclnthandle(host
, nconf
, rpcbversnum
,
1625 __rpc_endconf(handle
);
1631 getclnthandle(host
, nconf
, rpcbversnum
, targaddr
)
1633 struct netconfig
*nconf
;
1635 struct netbuf
**targaddr
;
1638 struct addrinfo hints
, *res
;
1639 CLIENT
*client
= NULL
;
1641 /* Get the address of the rpcbind */
1642 memset(&hints
, 0, sizeof hints
);
1643 if (getaddrinfo(host
, "rpcbind", &hints
, &res
) != 0) {
1644 rpc_createerr
.cf_stat
= RPC_N2AXLATEFAILURE
;
1647 addr
.len
= addr
.maxlen
= res
->ai_addrlen
;
1648 addr
.buf
= res
->ai_addr
;
1649 client
= clnt_tli_create(RPC_ANYFD
, nconf
, &addr
, RPCBPROG
,
1652 if (targaddr
!= NULL
) {
1653 *targaddr
= malloc(sizeof (struct netbuf
));
1654 if (*targaddr
!= NULL
) {
1655 (*targaddr
)->maxlen
= addr
.maxlen
;
1656 (*targaddr
)->len
= addr
.len
;
1657 (*targaddr
)->buf
= malloc(addr
.len
);
1658 if ((*targaddr
)->buf
!= NULL
) {
1659 memcpy((*targaddr
)->buf
, addr
.buf
,
1665 if (rpc_createerr
.cf_stat
== RPC_TLIERROR
) {
1667 * Assume that the other system is dead; this is a
1668 * better error to display to the user.
1670 rpc_createerr
.cf_stat
= RPC_RPCBFAILURE
;
1671 rpc_createerr
.cf_error
.re_status
= RPC_FAILED
;
1679 print_rmtcallstat(rtype
, infp
)
1683 register rpcbs_rmtcalllist_ptr pr
;
1686 if (rtype
== RPCBVERS_4_STAT
)
1688 "prog\t\tvers\tproc\tnetid\tindirect success failure\n");
1690 printf("prog\t\tvers\tproc\tnetid\tsuccess\tfailure\n");
1691 for (pr
= infp
->rmtinfo
; pr
; pr
= pr
->next
) {
1692 rpc
= getrpcbynumber(pr
->prog
);
1694 printf("%-16s", rpc
->r_name
);
1696 printf("%-16d", pr
->prog
);
1697 printf("%d\t%d\t%s\t",
1698 pr
->vers
, pr
->proc
, pr
->netid
);
1699 if (rtype
== RPCBVERS_4_STAT
)
1700 printf("%d\t ", pr
->indirect
);
1701 printf("%d\t%d\n", pr
->success
, pr
->failure
);
1706 print_getaddrstat(rtype
, infp
)
1710 rpcbs_addrlist_ptr al
;
1711 register struct rpcent
*rpc
;
1713 printf("prog\t\tvers\tnetid\t success\tfailure\n");
1714 for (al
= infp
->addrinfo
; al
; al
= al
->next
) {
1715 rpc
= getrpcbynumber(al
->prog
);
1717 printf("%-16s", rpc
->r_name
);
1719 printf("%-16d", al
->prog
);
1720 printf("%d\t%s\t %-12d\t%d\n",
1721 al
->vers
, al
->netid
,
1722 al
->success
, al
->failure
);
1730 static char space_array
[] = /* 64 spaces */
1733 if (howmany
<= 0 || howmany
> sizeof (space_array
)) {
1736 return (&space_array
[sizeof (space_array
) - howmany
- 1]);