4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
30 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
31 /* All Rights Reserved */
33 * University Copyright- Copyright (c) 1982, 1986, 1988
34 * The Regents of the University of California
37 * University Acknowledgment- Portions of this document are derived from
38 * software developed by the University of California, Berkeley, and its
43 * rpcinfo: ping a particular rpc program
44 * or dump the the registered programs on the remote machine.
48 * We are for now defining PORTMAP here. It doesn't even compile
49 * unless it is defined.
56 * If PORTMAP is defined, rpcinfo will talk to both portmapper and
57 * rpcbind programs; else it talks only to rpcbind. In the latter case
58 * all the portmapper specific options such as -u, -t, -p become void.
62 #include <rpc/rpcb_prot.h>
63 #include <rpc/nettype.h>
65 #include <rpc/rpcent.h>
70 #ifdef PORTMAP /* Support for version 2 portmapper */
71 #include <netinet/in.h>
72 #include <sys/socket.h>
74 #include <arpa/inet.h>
75 #include <rpc/pmap_prot.h>
76 #include <rpc/pmap_clnt.h>
79 #define MAXHOSTLEN 256
80 #define MIN_VERS ((ulong_t)0)
81 #define MAX_VERS (4294967295UL)
82 #define UNKNOWN "unknown"
84 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
88 static char *spaces();
91 static void ip_ping(/*ushort_t portflag, char *trans,
92 int argc, char **argv*/);
93 static CLIENT
*clnt_com_create(/* struct sockaddr_in *addr, long prog,
94 long vers, int *fd, char *trans*/);
95 static void pmapdump(/*int argc, char **argv*/);
96 static void get_inet_address(/*struct sockaddr_in *addr, char *host*/);
99 static bool_t
reply_proc(/*void *res, struct netbuf *who*,
100 struct netconfig *nconf*/);
101 static void brdcst(/*int argc, char **argv*/);
102 static void addrping(/*char *address, char *netid,
103 int argc, char **argv*/);
104 static void progping(/* char *netid, int argc, char **argv*/);
105 static CLIENT
*clnt_addr_create(/* char *addr, struct netconfig *nconf,
106 long prog, long vers*/);
107 static CLIENT
*clnt_rpcbind_create(/* char *host, int vers */);
108 static CLIENT
*getclnthandle(/* host, nconf, rpcbversnum */);
109 static int pstatus(/*CLIENT *client, ulong_t prognum, ulong_t vers*/);
110 static void rpcbdump(/*char *netid, int argc, char **argv*/);
111 static void rpcbgetstat(/* int argc, char **argv*/);
112 static void rpcbaddrlist(/*char *netid, int argc, char **argv*/);
113 static void deletereg(/*char *netid, int argc, char **argv */);
114 static void print_rmtcallstat(/* rtype, infp */);
115 static void print_getaddrstat(/* rtype, infp */);
116 static void usage(/*void*/);
117 static ulong_t
getprognum(/*char *arg*/);
118 static ulong_t
getvers(/*char *arg*/);
121 * Functions to be performed.
123 #define NONE 0 /* no function */
124 #define PMAPDUMP 1 /* dump portmapper registrations */
125 #define TCPPING 2 /* ping TCP service */
126 #define UDPPING 3 /* ping UDP service */
127 #define BROADCAST 4 /* ping broadcast service */
128 #define DELETES 5 /* delete registration for the service */
129 #define ADDRPING 6 /* pings at the given address */
130 #define PROGPING 7 /* pings a program on a given host */
131 #define RPCBDUMP 8 /* dump rpcbind registrations */
132 #define RPCBDUMP_SHORT 9 /* dump rpcbind registrations - short version */
133 #define RPCBADDRLIST 10 /* dump addr list about one prog */
134 #define RPCBGETSTAT 11 /* Get statistics */
138 struct netidlist
*next
;
143 struct verslist
*next
;
146 struct rpcbdump_short
{
148 struct verslist
*vlist
;
149 struct netidlist
*nlist
;
150 struct rpcbdump_short
*next
;
155 char *loopback_netid
= NULL
;
156 struct netconfig
*loopback_nconf
;
169 char *address
= NULL
;
173 ushort_t portnum
= 0;
179 while ((c
= getopt(argc
, argv
, "a:bdlmn:pstT:u")) != EOF
) {
181 while ((c
= getopt(argc
, argv
, "a:bdlmn:sT:")) != EOF
) {
186 if (function
!= NONE
)
193 if (function
!= NONE
)
200 if (function
!= NONE
)
207 portnum
= (ushort_t
)strtol(optarg
, &strptr
, 10);
208 if (strptr
== optarg
|| *strptr
!= '\0') {
209 (void) fprintf(stderr
,
210 "rpcinfo: %s is illegal port number\n",
218 if (function
!= NONE
)
224 if (function
!= NONE
)
227 function
= BROADCAST
;
231 if (function
!= NONE
)
238 if (function
!= NONE
)
241 function
= RPCBADDRLIST
;
245 if (function
!= NONE
)
248 function
= RPCBGETSTAT
;
252 if (function
!= NONE
)
255 function
= RPCBDUMP_SHORT
;
267 if (errflg
|| ((function
== ADDRPING
) && !netid
)) {
271 if (netid
== NULL
) { /* user has not selected transport to use */
273 * See if a COTS loopback transport is available, in case we
274 * will be talking to the local system.
276 handle
= setnetconfig();
277 while ((loopback_nconf
= getnetconfig(handle
)) != NULL
) {
278 if (strcmp(loopback_nconf
->nc_protofmly
,
280 (loopback_nconf
->nc_semantics
== NC_TPI_COTS
||
281 loopback_nconf
->nc_semantics
== NC_TPI_COTS_ORD
)) {
282 loopback_netid
= loopback_nconf
->nc_netid
;
286 if (loopback_netid
== NULL
) {
287 (void) endnetconfig(handle
);
290 if (function
== NONE
) {
291 if (argc
- optind
> 1)
304 pmapdump(argc
- optind
, argv
+ optind
);
308 ip_ping(portnum
, "udp", argc
- optind
, argv
+ optind
);
312 ip_ping(portnum
, "tcp", argc
- optind
, argv
+ optind
);
316 brdcst(argc
- optind
, argv
+ optind
);
319 deletereg(netid
, argc
- optind
, argv
+ optind
);
322 addrping(address
, netid
, argc
- optind
, argv
+ optind
);
325 progping(netid
, argc
- optind
, argv
+ optind
);
329 rpcbdump(function
, netid
, argc
- optind
, argv
+ optind
);
332 rpcbgetstat(argc
- optind
, argv
+ optind
);
335 rpcbaddrlist(netid
, argc
- optind
, argv
+ optind
);
343 clnt_com_create(addr
, prog
, vers
, fdp
, trans
)
344 struct sockaddr_in
*addr
;
352 if (strcmp(trans
, "tcp") == 0) {
353 clnt
= clnttcp_create(addr
, prog
, vers
, fdp
, 0, 0);
359 clnt
= clntudp_create(addr
, prog
, vers
, to
, fdp
);
361 if (clnt
== (CLIENT
*)NULL
) {
362 clnt_pcreateerror("rpcinfo");
363 if (vers
== MIN_VERS
)
364 (void) printf("program %lu is not available\n", prog
);
367 "program %lu version %lu is not available\n",
375 * If portnum is 0, then go and get the address from portmapper, which happens
376 * transparently through clnt*_create(); If version number is not given, it
377 * tries to find out the version number by making a call to version 0 and if
378 * that fails, it obtains the high order and the low order version number. If
379 * version 0 calls succeeds, it tries for MAXVERS call and repeats the same.
382 ip_ping(portnum
, trans
, argc
, argv
)
391 struct sockaddr_in addr
;
392 enum clnt_stat rpc_stat
;
393 ulong_t prognum
, vers
, minvers
, maxvers
;
394 struct rpc_err rpcerr
;
397 if (argc
< 2 || argc
> 3) {
403 prognum
= getprognum(argv
[1]);
404 get_inet_address(&addr
, argv
[0]);
405 if (argc
== 2) { /* Version number not known */
407 * A call to version 0 should fail with a program/version
408 * mismatch, and give us the range of versions supported.
412 vers
= getvers(argv
[2]);
414 addr
.sin_port
= htons(portnum
);
415 client
= clnt_com_create(&addr
, prognum
, vers
, &fd
, trans
);
416 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
)xdr_void
,
417 (char *)NULL
, (xdrproc_t
)xdr_void
, (char *)NULL
,
420 /* Version number was known */
421 if (pstatus(client
, prognum
, vers
) < 0)
423 (void) CLNT_DESTROY(client
);
426 /* Version number not known */
427 (void) CLNT_CONTROL(client
, CLSET_FD_NCLOSE
, (char *)NULL
);
428 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
429 clnt_geterr(client
, &rpcerr
);
430 minvers
= rpcerr
.re_vers
.low
;
431 maxvers
= rpcerr
.re_vers
.high
;
432 } else if (rpc_stat
== RPC_SUCCESS
) {
434 * Oh dear, it DOES support version 0.
435 * Let's try version MAX_VERS.
437 (void) CLNT_DESTROY(client
);
438 addr
.sin_port
= htons(portnum
);
439 client
= clnt_com_create(&addr
, prognum
, MAX_VERS
, &fd
, trans
);
440 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
)xdr_void
,
441 (char *)NULL
, (xdrproc_t
)xdr_void
,
443 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
444 clnt_geterr(client
, &rpcerr
);
445 minvers
= rpcerr
.re_vers
.low
;
446 maxvers
= rpcerr
.re_vers
.high
;
447 } else if (rpc_stat
== RPC_SUCCESS
) {
449 * It also supports version MAX_VERS.
450 * Looks like we have a wise guy.
451 * OK, we give them information on all
452 * 4 billion versions they support...
457 (void) pstatus(client
, prognum
, MAX_VERS
);
461 (void) pstatus(client
, prognum
, (ulong_t
)0);
464 (void) CLNT_DESTROY(client
);
465 for (vers
= minvers
; vers
<= maxvers
; vers
++) {
466 addr
.sin_port
= htons(portnum
);
467 client
= clnt_com_create(&addr
, prognum
, vers
, &fd
, trans
);
468 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
)xdr_void
,
469 (char *)NULL
, (xdrproc_t
)xdr_void
,
471 if (pstatus(client
, prognum
, vers
) < 0)
473 (void) CLNT_DESTROY(client
);
481 * Dump all the portmapper registerations
488 struct sockaddr_in server_addr
;
489 pmaplist_ptr head
= NULL
;
490 int socket
= RPC_ANYSOCK
;
491 struct timeval minutetimeout
;
492 register CLIENT
*client
;
494 enum clnt_stat clnt_st
;
505 host
= HOST_SELF_CONNECT
;
507 get_inet_address(&server_addr
, host
);
509 minutetimeout
.tv_sec
= 60;
510 minutetimeout
.tv_usec
= 0;
511 server_addr
.sin_port
= htons(PMAPPORT
);
512 if ((client
= clnttcp_create(&server_addr
, PMAPPROG
,
513 PMAPVERS
, &socket
, 50, 500)) == NULL
) {
514 if (rpc_createerr
.cf_stat
== RPC_TLIERROR
) {
516 * "Misc. TLI error" is not too helpful. Most likely
517 * the connection to the remote server timed out, so
518 * this error is at least less perplexing.
520 rpc_createerr
.cf_stat
= RPC_PMAPFAILURE
;
521 rpc_createerr
.cf_error
.re_status
= RPC_FAILED
;
523 clnt_pcreateerror("rpcinfo: can't contact portmapper");
526 clnt_st
= CLNT_CALL(client
, PMAPPROC_DUMP
, (xdrproc_t
)xdr_void
,
527 NULL
, (xdrproc_t
)xdr_pmaplist_ptr
, (char *)&head
,
529 if (clnt_st
!= RPC_SUCCESS
) {
530 if ((clnt_st
== RPC_PROGVERSMISMATCH
) ||
531 (clnt_st
== RPC_PROGUNAVAIL
)) {
532 CLNT_GETERR(client
, &err
);
533 if (err
.re_vers
.low
> PMAPVERS
)
534 (void) fprintf(stderr
,
535 "%s does not support portmapper. Try rpcinfo %s instead\n",
539 clnt_perror(client
, "rpcinfo: can't contact portmapper");
543 (void) printf("No remote programs registered.\n");
545 (void) printf(" program vers proto port service\n");
546 for (; head
!= NULL
; head
= head
->pml_next
) {
547 (void) printf("%10ld%5ld",
548 head
->pml_map
.pm_prog
,
549 head
->pml_map
.pm_vers
);
550 if (head
->pml_map
.pm_prot
== IPPROTO_UDP
)
551 (void) printf("%6s", "udp");
552 else if (head
->pml_map
.pm_prot
== IPPROTO_TCP
)
553 (void) printf("%6s", "tcp");
555 (void) printf("%6ld", head
->pml_map
.pm_prot
);
556 (void) printf("%7ld", head
->pml_map
.pm_port
);
557 rpc
= getrpcbynumber(head
->pml_map
.pm_prog
);
559 (void) printf(" %s\n", rpc
->r_name
);
567 get_inet_address(addr
, host
)
568 struct sockaddr_in
*addr
;
571 struct netconfig
*nconf
;
572 struct nd_hostserv service
;
573 struct nd_addrlist
*naddrs
;
575 (void) memset((char *)addr
, 0, sizeof (*addr
));
576 addr
->sin_addr
.s_addr
= inet_addr(host
);
577 if (addr
->sin_addr
.s_addr
== (uint32_t)-1 ||
578 addr
->sin_addr
.s_addr
== 0) {
579 if ((nconf
= __rpc_getconfip("udp")) == NULL
&&
580 (nconf
= __rpc_getconfip("tcp")) == NULL
) {
581 (void) fprintf(stderr
,
582 "rpcinfo: couldn't find a suitable transport\n");
585 service
.h_host
= host
;
586 service
.h_serv
= "rpcbind";
587 if (netdir_getbyname(nconf
, &service
, &naddrs
)) {
588 (void) fprintf(stderr
, "rpcinfo: %s: %s\n",
589 host
, netdir_sperror());
592 (void) memcpy((caddr_t
)addr
,
593 naddrs
->n_addrs
->buf
, naddrs
->n_addrs
->len
);
594 (void) netdir_free((char *)naddrs
, ND_ADDRLIST
);
596 (void) freenetconfigent(nconf
);
599 addr
->sin_family
= AF_INET
;
605 * reply_proc collects replies from the broadcast.
606 * to get a unique list of responses the output of rpcinfo should
607 * be piped through sort(1) and then uniq(1).
612 reply_proc(res
, who
, nconf
)
613 void *res
; /* Nothing comes back */
614 struct netbuf
*who
; /* Who sent us the reply */
615 struct netconfig
*nconf
; /* On which transport the reply came */
617 struct nd_hostservlist
*serv
;
621 if (netdir_getbyaddr(nconf
, &serv
, who
)) {
624 hostname
= serv
->h_hostservs
->h_host
;
626 if (!(uaddr
= taddr2uaddr(nconf
, who
))) {
629 (void) printf("%s\t%s\n", uaddr
, hostname
);
630 if (strcmp(hostname
, UNKNOWN
))
631 netdir_free((char *)serv
, ND_HOSTSERVLIST
);
632 if (strcmp(uaddr
, UNKNOWN
))
642 enum clnt_stat rpc_stat
;
643 ulong_t prognum
, vers
;
649 prognum
= getprognum(argv
[0]);
650 vers
= getvers(argv
[1]);
651 rpc_stat
= rpc_broadcast(prognum
, vers
, NULLPROC
,
652 (xdrproc_t
)xdr_void
, (char *)NULL
, (xdrproc_t
)xdr_void
,
653 (char *)NULL
, (resultproc_t
)reply_proc
, NULL
);
654 if ((rpc_stat
!= RPC_SUCCESS
) && (rpc_stat
!= RPC_TIMEDOUT
)) {
655 (void) fprintf(stderr
, "rpcinfo: broadcast failed: %s\n",
656 clnt_sperrno(rpc_stat
));
663 add_version(rs
, vers
)
664 struct rpcbdump_short
*rs
;
669 for (vl
= rs
->vlist
; vl
; vl
= vl
->next
)
670 if (vl
->vers
== vers
)
674 vl
= (struct verslist
*)malloc(sizeof (struct verslist
));
678 vl
->next
= rs
->vlist
;
685 struct rpcbdump_short
*rs
;
688 struct netidlist
*nl
;
690 for (nl
= rs
->nlist
; nl
; nl
= nl
->next
)
691 if (strcmp(nl
->netid
, netid
) == 0)
695 nl
= (struct netidlist
*)malloc(sizeof (struct netidlist
));
699 nl
->next
= rs
->nlist
;
705 rpcbdump(dumptype
, netid
, argc
, argv
)
711 rpcblist_ptr head
= NULL
;
712 struct timeval minutetimeout
;
713 register CLIENT
*client
;
716 struct netidlist
*nl
;
718 struct rpcbdump_short
*rs
, *rs_tail
;
719 enum clnt_stat clnt_st
;
721 struct rpcbdump_short
*rs_head
= NULL
;
730 host
= HOST_SELF_CONNECT
;
733 if (loopback_netid
== NULL
) {
734 client
= clnt_rpcbind_create(host
, RPCBVERS
, NULL
);
736 client
= getclnthandle(host
, loopback_nconf
, RPCBVERS
, NULL
);
737 if (client
== NULL
&& rpc_createerr
.cf_stat
==
738 RPC_N2AXLATEFAILURE
) {
739 client
= clnt_rpcbind_create(host
, RPCBVERS
, NULL
);
743 struct netconfig
*nconf
;
745 nconf
= getnetconfigent(netid
);
747 nc_perror("rpcinfo: invalid transport");
750 client
= getclnthandle(host
, nconf
, RPCBVERS
, NULL
);
752 (void) freenetconfigent(nconf
);
754 if (client
== (CLIENT
*)NULL
) {
755 clnt_pcreateerror("rpcinfo: can't contact rpcbind");
758 minutetimeout
.tv_sec
= 60;
759 minutetimeout
.tv_usec
= 0;
760 clnt_st
= CLNT_CALL(client
, RPCBPROC_DUMP
, (xdrproc_t
)xdr_void
,
761 NULL
, (xdrproc_t
)xdr_rpcblist_ptr
, (char *)&head
,
763 if (clnt_st
!= RPC_SUCCESS
) {
764 if ((clnt_st
== RPC_PROGVERSMISMATCH
) ||
765 (clnt_st
== RPC_PROGUNAVAIL
)) {
768 CLNT_GETERR(client
, &err
);
769 if (err
.re_vers
.low
== RPCBVERS4
) {
771 clnt_control(client
, CLSET_VERS
, (char *)&vers
);
772 clnt_st
= CLNT_CALL(client
, RPCBPROC_DUMP
,
773 (xdrproc_t
)xdr_void
, NULL
,
774 (xdrproc_t
)xdr_rpcblist_ptr
, (char *)&head
,
776 if (clnt_st
!= RPC_SUCCESS
)
779 if (err
.re_vers
.high
== PMAPVERS
) {
781 pmaplist_ptr pmaphead
= NULL
;
782 rpcblist_ptr list
, prev
= NULL
;
785 clnt_control(client
, CLSET_VERS
, (char *)&vers
);
786 clnt_st
= CLNT_CALL(client
, PMAPPROC_DUMP
,
787 (xdrproc_t
)xdr_void
, NULL
,
788 (xdrproc_t
)xdr_pmaplist_ptr
,
789 (char *)&pmaphead
, minutetimeout
);
790 if (clnt_st
!= RPC_SUCCESS
)
793 * convert to rpcblist_ptr format
795 for (head
= NULL
; pmaphead
!= NULL
;
796 pmaphead
= pmaphead
->pml_next
) {
797 list
= (rpcblist
*)malloc(sizeof (rpcblist
));
803 prev
->rpcb_next
= (rpcblist_ptr
) list
;
805 list
->rpcb_next
= NULL
;
806 list
->rpcb_map
.r_prog
= pmaphead
->pml_map
.pm_prog
;
807 list
->rpcb_map
.r_vers
= pmaphead
->pml_map
.pm_vers
;
808 if (pmaphead
->pml_map
.pm_prot
== IPPROTO_UDP
)
809 list
->rpcb_map
.r_netid
= "udp";
810 else if (pmaphead
->pml_map
.pm_prot
== IPPROTO_TCP
)
811 list
->rpcb_map
.r_netid
= "tcp";
813 #define MAXLONG_AS_STRING "2147483648"
814 list
->rpcb_map
.r_netid
=
815 malloc(strlen(MAXLONG_AS_STRING
) + 1);
816 if (list
->rpcb_map
.r_netid
== NULL
)
818 (void) sprintf(list
->rpcb_map
.r_netid
, "%6ld",
819 pmaphead
->pml_map
.pm_prot
);
821 list
->rpcb_map
.r_owner
= UNKNOWN
;
822 low
= pmaphead
->pml_map
.pm_port
& 0xff;
823 high
= (pmaphead
->pml_map
.pm_port
>> 8) & 0xff;
824 list
->rpcb_map
.r_addr
= strdup("0.0.0.0.XXX.XXX");
825 (void) sprintf(&list
->rpcb_map
.r_addr
[8], "%d.%d",
831 } else { /* any other error */
833 clnt_perror(client
, "rpcinfo: can't contact rpcbind: ");
838 (void) printf("No remote programs registered.\n");
839 } else if (dumptype
== RPCBDUMP
) {
841 " program version netid address service owner\n");
842 for (; head
!= NULL
; head
= head
->rpcb_next
) {
843 (void) printf("%10ld%5ld ",
844 head
->rpcb_map
.r_prog
, head
->rpcb_map
.r_vers
);
845 (void) printf("%-9s ", head
->rpcb_map
.r_netid
);
846 (void) printf("%-19s", head
->rpcb_map
.r_addr
);
847 rpc
= getrpcbynumber(head
->rpcb_map
.r_prog
);
849 (void) printf(" %-10s", rpc
->r_name
);
851 (void) printf(" %-10s", "-");
852 (void) printf(" %s\n", head
->rpcb_map
.r_owner
);
854 } else if (dumptype
== RPCBDUMP_SHORT
) {
855 for (; head
!= NULL
; head
= head
->rpcb_next
) {
856 for (rs
= rs_head
; rs
; rs
= rs
->next
)
857 if (head
->rpcb_map
.r_prog
== rs
->prog
)
860 rs
= (struct rpcbdump_short
*)
861 malloc(sizeof (struct rpcbdump_short
));
865 if (rs_head
== NULL
) {
872 rs
->prog
= head
->rpcb_map
.r_prog
;
873 rs
->owner
= head
->rpcb_map
.r_owner
;
877 if (add_version(rs
, head
->rpcb_map
.r_vers
) == FALSE
)
879 if (add_netid(rs
, head
->rpcb_map
.r_netid
) == FALSE
)
883 " program version(s) netid(s) service owner\n");
884 for (rs
= rs_head
; rs
; rs
= rs
->next
) {
888 (void) printf("%10ld ", rs
->prog
);
889 for (vl
= rs
->vlist
; vl
; vl
= vl
->next
) {
890 bytes_trans
+= (len
= printf("%d", vl
->vers
))
893 bytes_trans
+= (len
= printf(",")) < 0
897 * If number of bytes transferred is less than 10,
898 * align 10 bytes for version(s) column. If bytes
899 * transferred is more than 10, add a trailing white
902 if (bytes_trans
< 10)
903 (void) printf("%*s", (bytes_trans
- 10), " ");
908 for (nl
= rs
->nlist
; nl
; nl
= nl
->next
) {
909 bytes_trans
+= (len
= printf("%s", nl
->netid
))
912 bytes_trans
+= (len
= printf(",")) < 0
916 * Align netid(s) column output for 32 bytes.
918 if (bytes_trans
< 32)
919 (void) printf("%*s", (bytes_trans
- 32), " ");
921 rpc
= getrpcbynumber(rs
->prog
);
923 (void) printf(" %-11s", rpc
->r_name
);
925 (void) printf(" %-11s", "-");
926 (void) printf(" %s\n", rs
->owner
);
929 clnt_destroy(client
);
932 error
: (void) fprintf(stderr
, "rpcinfo: no memory\n");
935 static char nullstring
[] = "\000";
938 rpcbaddrlist(netid
, argc
, argv
)
943 rpcb_entry_list_ptr head
= NULL
;
944 struct timeval minutetimeout
;
945 register CLIENT
*client
;
949 struct netbuf
*targaddr
;
957 if (loopback_netid
== NULL
) {
958 client
= clnt_rpcbind_create(host
, RPCBVERS4
, &targaddr
);
960 client
= getclnthandle(host
, loopback_nconf
, RPCBVERS4
,
962 if (client
== NULL
&& rpc_createerr
.cf_stat
==
963 RPC_N2AXLATEFAILURE
) {
964 client
= clnt_rpcbind_create(host
, RPCBVERS4
, &targaddr
);
968 struct netconfig
*nconf
;
970 nconf
= getnetconfigent(netid
);
972 nc_perror("rpcinfo: invalid transport");
975 client
= getclnthandle(host
, nconf
, RPCBVERS4
, &targaddr
);
977 (void) freenetconfigent(nconf
);
979 if (client
== (CLIENT
*)NULL
) {
980 clnt_pcreateerror("rpcinfo: can't contact rpcbind");
983 minutetimeout
.tv_sec
= 60;
984 minutetimeout
.tv_usec
= 0;
986 parms
.r_prog
= getprognum(argv
[1]);
987 parms
.r_vers
= getvers(argv
[2]);
988 parms
.r_netid
= client
->cl_netid
;
989 if (targaddr
== NULL
) {
990 parms
.r_addr
= nullstring
; /* for XDRing */
993 * We also send the remote system the address we
994 * used to contact it in case it can help it
995 * connect back with us
997 struct netconfig
*nconf
;
999 nconf
= getnetconfigent(client
->cl_netid
);
1000 if (nconf
!= NULL
) {
1001 parms
.r_addr
= taddr2uaddr(nconf
, targaddr
);
1002 if (parms
.r_addr
== NULL
)
1003 parms
.r_addr
= nullstring
;
1004 freenetconfigent(nconf
);
1006 parms
.r_addr
= nullstring
; /* for XDRing */
1008 free(targaddr
->buf
);
1011 parms
.r_owner
= nullstring
;
1013 if (CLNT_CALL(client
, RPCBPROC_GETADDRLIST
, (xdrproc_t
)xdr_rpcb
,
1014 (char *)&parms
, (xdrproc_t
)xdr_rpcb_entry_list_ptr
,
1015 (char *)&head
, minutetimeout
) != RPC_SUCCESS
) {
1016 clnt_perror(client
, "rpcinfo: can't contact rpcbind: ");
1020 (void) printf("No remote programs registered.\n");
1023 " program vers tp_family/name/class address\t\t service\n");
1024 for (; head
!= NULL
; head
= head
->rpcb_entry_next
) {
1028 re
= &head
->rpcb_entry_map
;
1029 (void) printf("%10ld%3ld ",
1030 parms
.r_prog
, parms
.r_vers
);
1031 (void) snprintf(buf
, sizeof (buf
), "%s/%s/%s ",
1032 re
->r_nc_protofmly
, re
->r_nc_proto
,
1033 re
->r_nc_semantics
== NC_TPI_CLTS
? "clts" :
1034 re
->r_nc_semantics
== NC_TPI_COTS
? "cots" :
1036 (void) printf("%-24s", buf
);
1037 (void) printf("%-24s", re
->r_maddr
);
1038 rpc
= getrpcbynumber(parms
.r_prog
);
1040 (void) printf(" %-13s", rpc
->r_name
);
1042 (void) printf(" %-13s", "-");
1043 (void) printf("\n");
1046 clnt_destroy(client
);
1053 rpcbgetstat(argc
, argv
)
1057 rpcb_stat_byvers inf
;
1058 struct timeval minutetimeout
;
1059 register CLIENT
*client
;
1063 rpcbs_rmtcalllist
*pr
;
1066 char fieldbuf
[MAXFIELD
];
1068 char linebuf
[MAXLINE
];
1071 "NULL", "SET", "UNSET", "GETPORT",
1074 char *rpcb3hdr
[] = {
1075 "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME",
1078 char *rpcb4hdr
[] = {
1079 "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME",
1080 "U2T", "T2U", "VERADDR", "INDRECT", "GETLIST", "GETSTAT"
1088 host
= HOST_SELF_CONNECT
;
1090 if (loopback_netid
!= NULL
) {
1091 client
= getclnthandle(host
, loopback_nconf
, RPCBVERS4
, NULL
);
1092 if (client
== NULL
&& rpc_createerr
.cf_stat
==
1093 RPC_N2AXLATEFAILURE
) {
1094 client
= clnt_rpcbind_create(host
, RPCBVERS4
, NULL
);
1097 client
= clnt_rpcbind_create(host
, RPCBVERS4
, NULL
);
1099 if (client
== (CLIENT
*)NULL
) {
1100 clnt_pcreateerror("rpcinfo: can't contact rpcbind");
1103 minutetimeout
.tv_sec
= 60;
1104 minutetimeout
.tv_usec
= 0;
1105 (void) memset((char *)&inf
, 0, sizeof (rpcb_stat_byvers
));
1106 if (CLNT_CALL(client
, RPCBPROC_GETSTAT
, (xdrproc_t
)xdr_void
, NULL
,
1107 (xdrproc_t
)xdr_rpcb_stat_byvers
, (char *)&inf
, minutetimeout
)
1109 clnt_perror(client
, "rpcinfo: can't contact rpcbind: ");
1112 (void) printf("PORTMAP (version 2) statistics\n");
1114 for (i
= 0; i
<= rpcb_highproc_2
; i
++) {
1118 (void) sprintf(fieldbuf
, "%d/",
1119 inf
[RPCBVERS_2_STAT
].setinfo
);
1121 case PMAPPROC_UNSET
:
1122 (void) sprintf(fieldbuf
, "%d/",
1123 inf
[RPCBVERS_2_STAT
].unsetinfo
);
1125 case PMAPPROC_GETPORT
:
1127 for (pa
= inf
[RPCBVERS_2_STAT
].addrinfo
; pa
;
1130 (void) sprintf(fieldbuf
, "%d/", cnt
);
1132 case PMAPPROC_CALLIT
:
1134 for (pr
= inf
[RPCBVERS_2_STAT
].rmtinfo
; pr
;
1137 (void) sprintf(fieldbuf
, "%d/", cnt
);
1139 default: break; /* For the remaining ones */
1141 cp
= &fieldbuf
[0] + strlen(fieldbuf
);
1142 (void) sprintf(cp
, "%d", inf
[RPCBVERS_2_STAT
].info
[i
]);
1143 flen
= strlen(fieldbuf
);
1144 (void) printf("%s%s", pmaphdr
[i
],
1145 spaces((int)((TABSTOP
* (1 + flen
/ TABSTOP
))
1146 - strlen(pmaphdr
[i
]))));
1147 (void) snprintf(lp
, (MAXLINE
- (lp
- linebuf
)), "%s%s",
1148 fieldbuf
, spaces(cnt
= ((TABSTOP
* (1 + flen
/ TABSTOP
))
1152 (void) printf("\n%s\n\n", linebuf
);
1154 if (inf
[RPCBVERS_2_STAT
].info
[PMAPPROC_CALLIT
]) {
1155 (void) printf("PMAP_RMTCALL call statistics\n");
1156 print_rmtcallstat(RPCBVERS_2_STAT
, &inf
[RPCBVERS_2_STAT
]);
1157 (void) printf("\n");
1160 if (inf
[RPCBVERS_2_STAT
].info
[PMAPPROC_GETPORT
]) {
1161 (void) printf("PMAP_GETPORT call statistics\n");
1162 print_getaddrstat(RPCBVERS_2_STAT
, &inf
[RPCBVERS_2_STAT
]);
1163 (void) printf("\n");
1166 (void) printf("RPCBIND (version 3) statistics\n");
1168 for (i
= 0; i
<= rpcb_highproc_3
; i
++) {
1172 (void) sprintf(fieldbuf
, "%d/",
1173 inf
[RPCBVERS_3_STAT
].setinfo
);
1175 case RPCBPROC_UNSET
:
1176 (void) sprintf(fieldbuf
, "%d/",
1177 inf
[RPCBVERS_3_STAT
].unsetinfo
);
1179 case RPCBPROC_GETADDR
:
1181 for (pa
= inf
[RPCBVERS_3_STAT
].addrinfo
; pa
;
1184 (void) sprintf(fieldbuf
, "%d/", cnt
);
1186 case RPCBPROC_CALLIT
:
1188 for (pr
= inf
[RPCBVERS_3_STAT
].rmtinfo
; pr
;
1191 (void) sprintf(fieldbuf
, "%d/", cnt
);
1193 default: break; /* For the remaining ones */
1195 cp
= &fieldbuf
[0] + strlen(fieldbuf
);
1196 (void) sprintf(cp
, "%d", inf
[RPCBVERS_3_STAT
].info
[i
]);
1197 flen
= strlen(fieldbuf
);
1198 (void) printf("%s%s", rpcb3hdr
[i
],
1199 spaces((int)((TABSTOP
* (1 + flen
/ TABSTOP
))
1200 - strlen(rpcb3hdr
[i
]))));
1201 (void) snprintf(lp
, (MAXLINE
- (lp
- linebuf
)), "%s%s",
1202 fieldbuf
, spaces(cnt
= ((TABSTOP
* (1 + flen
/ TABSTOP
))
1206 (void) printf("\n%s\n\n", linebuf
);
1208 if (inf
[RPCBVERS_3_STAT
].info
[RPCBPROC_CALLIT
]) {
1209 (void) printf("RPCB_RMTCALL (version 3) call statistics\n");
1210 print_rmtcallstat(RPCBVERS_3_STAT
, &inf
[RPCBVERS_3_STAT
]);
1211 (void) printf("\n");
1214 if (inf
[RPCBVERS_3_STAT
].info
[RPCBPROC_GETADDR
]) {
1215 (void) printf("RPCB_GETADDR (version 3) call statistics\n");
1216 print_getaddrstat(RPCBVERS_3_STAT
, &inf
[RPCBVERS_3_STAT
]);
1217 (void) printf("\n");
1220 (void) printf("RPCBIND (version 4) statistics\n");
1222 for (j
= 0; j
<= 9; j
+= 9) { /* Just two iterations for printing */
1224 for (i
= j
; i
<= MAX(8, rpcb_highproc_4
- 9 + j
); i
++) {
1228 (void) sprintf(fieldbuf
, "%d/",
1229 inf
[RPCBVERS_4_STAT
].setinfo
);
1231 case RPCBPROC_UNSET
:
1232 (void) sprintf(fieldbuf
, "%d/",
1233 inf
[RPCBVERS_4_STAT
].unsetinfo
);
1235 case RPCBPROC_GETADDR
:
1237 for (pa
= inf
[RPCBVERS_4_STAT
].addrinfo
; pa
;
1240 (void) sprintf(fieldbuf
, "%d/", cnt
);
1242 case RPCBPROC_CALLIT
:
1244 for (pr
= inf
[RPCBVERS_4_STAT
].rmtinfo
; pr
;
1247 (void) sprintf(fieldbuf
, "%d/", cnt
);
1249 default: break; /* For the remaining ones */
1251 cp
= &fieldbuf
[0] + strlen(fieldbuf
);
1253 * XXX: We also add RPCBPROC_GETADDRLIST queries to
1254 * RPCB_GETADDR because rpcbind includes the
1255 * RPCB_GETADDRLIST successes in RPCB_GETADDR.
1257 if (i
!= RPCBPROC_GETADDR
)
1258 (void) sprintf(cp
, "%d",
1259 inf
[RPCBVERS_4_STAT
].info
[i
]);
1261 (void) sprintf(cp
, "%d",
1262 inf
[RPCBVERS_4_STAT
].info
[i
] +
1263 inf
[RPCBVERS_4_STAT
].info
[RPCBPROC_GETADDRLIST
]);
1264 flen
= strlen(fieldbuf
);
1265 (void) printf("%s%s", rpcb4hdr
[i
],
1266 spaces((int)((TABSTOP
* (1 + flen
/ TABSTOP
))
1267 - strlen(rpcb4hdr
[i
]))));
1268 (void) snprintf(lp
, MAXLINE
- (lp
- linebuf
), "%s%s",
1269 fieldbuf
, spaces(cnt
=
1270 ((TABSTOP
* (1 + flen
/ TABSTOP
)) - flen
)));
1273 (void) printf("\n%s\n", linebuf
);
1276 if (inf
[RPCBVERS_4_STAT
].info
[RPCBPROC_CALLIT
] ||
1277 inf
[RPCBVERS_4_STAT
].info
[RPCBPROC_INDIRECT
]) {
1278 (void) printf("\n");
1279 (void) printf("RPCB_RMTCALL (version 4) call statistics\n");
1280 print_rmtcallstat(RPCBVERS_4_STAT
, &inf
[RPCBVERS_4_STAT
]);
1283 if (inf
[RPCBVERS_4_STAT
].info
[RPCBPROC_GETADDR
]) {
1284 (void) printf("\n");
1285 (void) printf("RPCB_GETADDR (version 4) call statistics\n");
1286 print_getaddrstat(RPCBVERS_4_STAT
, &inf
[RPCBVERS_4_STAT
]);
1288 clnt_destroy(client
);
1292 * Delete registeration for this (prog, vers, netid)
1295 deletereg(netid
, argc
, argv
)
1300 struct netconfig
*nconf
= NULL
;
1307 nconf
= getnetconfigent(netid
);
1308 if (nconf
== NULL
) {
1309 (void) fprintf(stderr
,
1310 "rpcinfo: netid %s not supported\n", netid
);
1314 if ((rpcb_unset(getprognum(argv
[0]), getvers(argv
[1]), nconf
)) == 0) {
1315 (void) fprintf(stderr
,
1316 "rpcinfo: Could not delete registration for prog %s version %s\n",
1323 * Create and return a handle for the given nconf.
1324 * Exit if cannot create handle.
1327 clnt_addr_create(address
, nconf
, prog
, vers
)
1329 struct netconfig
*nconf
;
1334 static struct netbuf
*nbuf
;
1335 static int fd
= RPC_ANYFD
;
1336 struct t_info tinfo
;
1338 if (fd
== RPC_ANYFD
) {
1339 if ((fd
= t_open(nconf
->nc_device
, O_RDWR
, &tinfo
)) == -1) {
1340 rpc_createerr
.cf_stat
= RPC_TLIERROR
;
1341 rpc_createerr
.cf_error
.re_terrno
= t_errno
;
1342 clnt_pcreateerror("rpcinfo");
1345 /* Convert the uaddr to taddr */
1346 nbuf
= uaddr2taddr(nconf
, address
);
1348 netdir_perror("rpcinfo");
1352 client
= clnt_tli_create(fd
, nconf
, nbuf
, prog
, vers
, 0, 0);
1353 if (client
== (CLIENT
*)NULL
) {
1354 clnt_pcreateerror("rpcinfo");
1361 * If the version number is given, ping that (prog, vers); else try to find
1362 * the version numbers supported for that prog and ping all the versions.
1363 * Remote rpcbind is not contacted for this service. The requests are
1364 * sent directly to the services themselves.
1367 addrping(address
, netid
, argc
, argv
)
1375 enum clnt_stat rpc_stat
;
1376 ulong_t prognum
, versnum
, minvers
, maxvers
;
1377 struct rpc_err rpcerr
;
1379 struct netconfig
*nconf
;
1382 if (argc
< 1 || argc
> 2 || (netid
== NULL
)) {
1386 nconf
= getnetconfigent(netid
);
1387 if (nconf
== (struct netconfig
*)NULL
) {
1388 (void) fprintf(stderr
, "rpcinfo: Could not find %s\n", netid
);
1393 prognum
= getprognum(argv
[0]);
1394 if (argc
== 1) { /* Version number not known */
1396 * A call to version 0 should fail with a program/version
1397 * mismatch, and give us the range of versions supported.
1401 versnum
= getvers(argv
[1]);
1403 client
= clnt_addr_create(address
, nconf
, prognum
, versnum
);
1404 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
)xdr_void
,
1405 (char *)NULL
, (xdrproc_t
)xdr_void
,
1408 /* Version number was known */
1409 if (pstatus(client
, prognum
, versnum
) < 0)
1411 (void) CLNT_DESTROY(client
);
1416 /* Version number not known */
1417 (void) CLNT_CONTROL(client
, CLSET_FD_NCLOSE
, (char *)NULL
);
1418 (void) CLNT_CONTROL(client
, CLGET_FD
, (char *)&fd
);
1419 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
1420 clnt_geterr(client
, &rpcerr
);
1421 minvers
= rpcerr
.re_vers
.low
;
1422 maxvers
= rpcerr
.re_vers
.high
;
1423 } else if (rpc_stat
== RPC_SUCCESS
) {
1425 * Oh dear, it DOES support version 0.
1426 * Let's try version MAX_VERS.
1428 (void) CLNT_DESTROY(client
);
1429 client
= clnt_addr_create(address
, nconf
, prognum
, MAX_VERS
);
1430 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
)xdr_void
,
1431 (char *)NULL
, (xdrproc_t
)xdr_void
,
1433 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
1434 clnt_geterr(client
, &rpcerr
);
1435 minvers
= rpcerr
.re_vers
.low
;
1436 maxvers
= rpcerr
.re_vers
.high
;
1437 } else if (rpc_stat
== RPC_SUCCESS
) {
1439 * It also supports version MAX_VERS.
1440 * Looks like we have a wise guy.
1441 * OK, we give them information on all
1442 * 4 billion versions they support...
1447 (void) pstatus(client
, prognum
, MAX_VERS
);
1451 (void) pstatus(client
, prognum
, (ulong_t
)0);
1454 (void) CLNT_DESTROY(client
);
1455 for (versnum
= minvers
; versnum
<= maxvers
; versnum
++) {
1456 client
= clnt_addr_create(address
, nconf
, prognum
, versnum
);
1457 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
)xdr_void
,
1458 (char *)NULL
, (xdrproc_t
)xdr_void
,
1460 if (pstatus(client
, prognum
, versnum
) < 0)
1462 (void) CLNT_DESTROY(client
);
1470 * If the version number is given, ping that (prog, vers); else try to find
1471 * the version numbers supported for that prog and ping all the versions.
1472 * Remote rpcbind is *contacted* for this service. The requests are
1473 * then sent directly to the services themselves.
1476 progping(netid
, argc
, argv
)
1483 enum clnt_stat rpc_stat
;
1484 ulong_t prognum
, versnum
, minvers
, maxvers
;
1485 struct rpc_err rpcerr
;
1487 struct netconfig
*nconf
;
1489 if (argc
< 2 || argc
> 3 || (netid
== NULL
)) {
1493 prognum
= getprognum(argv
[1]);
1494 if (argc
== 2) { /* Version number not known */
1496 * A call to version 0 should fail with a program/version
1497 * mismatch, and give us the range of versions supported.
1501 versnum
= getvers(argv
[2]);
1504 nconf
= getnetconfigent(netid
);
1505 if (nconf
== (struct netconfig
*)NULL
) {
1506 (void) fprintf(stderr
,
1507 "rpcinfo: Could not find %s\n", netid
);
1510 client
= clnt_tp_create(argv
[0], prognum
, versnum
, nconf
);
1512 client
= clnt_create(argv
[0], prognum
, versnum
, "NETPATH");
1514 if (client
== (CLIENT
*)NULL
) {
1515 clnt_pcreateerror("rpcinfo");
1520 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
)xdr_void
,
1521 (char *)NULL
, (xdrproc_t
)xdr_void
,
1524 /* Version number was known */
1525 if (pstatus(client
, prognum
, versnum
) < 0)
1527 (void) CLNT_DESTROY(client
);
1532 /* Version number not known */
1533 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
1534 clnt_geterr(client
, &rpcerr
);
1535 minvers
= rpcerr
.re_vers
.low
;
1536 maxvers
= rpcerr
.re_vers
.high
;
1537 } else if (rpc_stat
== RPC_SUCCESS
) {
1539 * Oh dear, it DOES support version 0.
1540 * Let's try version MAX_VERS.
1543 (void) CLNT_CONTROL(client
, CLSET_VERS
, (char *)&versnum
);
1544 rpc_stat
= CLNT_CALL(client
, NULLPROC
,
1545 (xdrproc_t
)xdr_void
, (char *)NULL
,
1546 (xdrproc_t
)xdr_void
, (char *)NULL
, to
);
1547 if (rpc_stat
== RPC_PROGVERSMISMATCH
) {
1548 clnt_geterr(client
, &rpcerr
);
1549 minvers
= rpcerr
.re_vers
.low
;
1550 maxvers
= rpcerr
.re_vers
.high
;
1551 } else if (rpc_stat
== RPC_SUCCESS
) {
1553 * It also supports version MAX_VERS.
1554 * Looks like we have a wise guy.
1555 * OK, we give them information on all
1556 * 4 billion versions they support...
1561 (void) pstatus(client
, prognum
, MAX_VERS
);
1565 (void) pstatus(client
, prognum
, (ulong_t
)0);
1568 for (versnum
= minvers
; versnum
<= maxvers
; versnum
++) {
1569 (void) CLNT_CONTROL(client
, CLSET_VERS
, (char *)&versnum
);
1570 rpc_stat
= CLNT_CALL(client
, NULLPROC
, (xdrproc_t
)xdr_void
,
1571 (char *)NULL
, (xdrproc_t
)xdr_void
,
1573 if (pstatus(client
, prognum
, versnum
) < 0)
1576 (void) CLNT_DESTROY(client
);
1584 (void) fprintf(stderr
, "Usage: rpcinfo [-T netid] [-m | -s] [host]\n");
1586 (void) fprintf(stderr
, " rpcinfo -p [host]\n");
1588 (void) fprintf(stderr
,
1589 " rpcinfo -T netid host prognum [versnum]\n");
1590 (void) fprintf(stderr
,
1591 " rpcinfo -l [-T netid] host prognum versnum\n");
1593 (void) fprintf(stderr
,
1594 " rpcinfo [-n portnum] -u | -t host prognum [versnum]\n");
1596 (void) fprintf(stderr
,
1597 " rpcinfo -a serv_address -T netid prognum [versnum]\n");
1598 (void) fprintf(stderr
,
1599 " rpcinfo -b [-T netid] prognum versnum\n");
1600 (void) fprintf(stderr
,
1601 " rpcinfo -d [-T netid] prognum versnum\n");
1609 register struct rpcent
*rpc
;
1610 register ulong_t prognum
;
1613 while (*tptr
&& isdigit(*tptr
++));
1614 if (*tptr
|| isalpha(*(tptr
- 1))) {
1615 rpc
= getrpcbyname(arg
);
1617 (void) fprintf(stderr
,
1618 "rpcinfo: %s is unknown service\n", arg
);
1621 prognum
= rpc
->r_number
;
1623 prognum
= strtol(arg
, &strptr
, 10);
1624 if (strptr
== arg
|| *strptr
!= '\0') {
1625 (void) fprintf(stderr
,
1626 "rpcinfo: %s is illegal program number\n", arg
);
1638 register ulong_t vers
;
1640 vers
= (int)strtol(arg
, &strptr
, 10);
1641 if (strptr
== arg
|| *strptr
!= '\0') {
1642 (void) fprintf(stderr
,
1643 "rpcinfo: %s is illegal version number\n", arg
);
1650 * This routine should take a pointer to an "rpc_err" structure, rather than
1651 * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
1652 * a CLIENT structure rather than a pointer to an "rpc_err" structure.
1653 * As such, we have to keep the CLIENT structure around in order to print
1654 * a good error message.
1657 pstatus(client
, prog
, vers
)
1658 register CLIENT
*client
;
1662 struct rpc_err rpcerr
;
1664 clnt_geterr(client
, &rpcerr
);
1665 if (rpcerr
.re_status
!= RPC_SUCCESS
) {
1666 clnt_perror(client
, "rpcinfo");
1667 (void) printf("program %lu version %lu is not available\n",
1671 (void) printf("program %lu version %lu ready and waiting\n",
1678 clnt_rpcbind_create(host
, rpcbversnum
, targaddr
)
1680 ulong_t rpcbversnum
;
1681 struct netbuf
**targaddr
;
1683 static char *tlist
[3] = {
1684 "circuit_n", "circuit_v", "datagram_v"
1687 struct netconfig
*nconf
;
1688 CLIENT
*clnt
= NULL
;
1691 rpc_createerr
.cf_stat
= RPC_SUCCESS
;
1692 for (i
= 0; i
< 3; i
++) {
1693 if ((handle
= __rpc_setconf(tlist
[i
])) == NULL
)
1695 while (clnt
== (CLIENT
*)NULL
) {
1696 if ((nconf
= __rpc_getconf(handle
)) == NULL
) {
1697 if (rpc_createerr
.cf_stat
== RPC_SUCCESS
)
1698 rpc_createerr
.cf_stat
= RPC_UNKNOWNPROTO
;
1701 clnt
= getclnthandle(host
, nconf
, rpcbversnum
,
1706 __rpc_endconf(handle
);
1712 getclnthandle(host
, nconf
, rpcbversnum
, targaddr
)
1714 struct netconfig
*nconf
;
1715 ulong_t rpcbversnum
;
1716 struct netbuf
**targaddr
;
1718 struct netbuf
*addr
;
1719 struct nd_addrlist
*nas
;
1720 struct nd_hostserv rpcbind_hs
;
1721 CLIENT
*client
= NULL
;
1723 /* Get the address of the rpcbind */
1724 rpcbind_hs
.h_host
= host
;
1725 rpcbind_hs
.h_serv
= "rpcbind";
1726 if (netdir_getbyname(nconf
, &rpcbind_hs
, &nas
)) {
1727 rpc_createerr
.cf_stat
= RPC_N2AXLATEFAILURE
;
1730 addr
= nas
->n_addrs
;
1731 client
= clnt_tli_create(RPC_ANYFD
, nconf
, addr
, RPCBPROG
,
1734 if (targaddr
!= NULL
) {
1736 (struct netbuf
*)malloc(sizeof (struct netbuf
));
1737 if (*targaddr
!= NULL
) {
1738 (*targaddr
)->maxlen
= addr
->maxlen
;
1739 (*targaddr
)->len
= addr
->len
;
1740 (*targaddr
)->buf
= (char *)malloc(addr
->len
);
1741 if ((*targaddr
)->buf
!= NULL
) {
1742 (void) memcpy((*targaddr
)->buf
,
1743 addr
->buf
, addr
->len
);
1748 if (rpc_createerr
.cf_stat
== RPC_TLIERROR
) {
1750 * Assume that the other system is dead; this is a
1751 * better error to display to the user.
1753 rpc_createerr
.cf_stat
= RPC_RPCBFAILURE
;
1754 rpc_createerr
.cf_error
.re_status
= RPC_FAILED
;
1757 netdir_free((char *)nas
, ND_ADDRLIST
);
1762 print_rmtcallstat(rtype
, infp
)
1766 register rpcbs_rmtcalllist_ptr pr
;
1769 if (rtype
== RPCBVERS_4_STAT
)
1771 "prog\t\tvers\tproc\tnetid\tindirect success failure\n");
1773 (void) printf("prog\t\tvers\tproc\tnetid\tsuccess\tfailure\n");
1774 for (pr
= infp
->rmtinfo
; pr
; pr
= pr
->next
) {
1775 rpc
= getrpcbynumber(pr
->prog
);
1777 (void) printf("%-16s", rpc
->r_name
);
1779 #if defined(_LP64) || defined(_I32LPx)
1780 (void) printf("%-16u", pr
->prog
);
1781 (void) printf("%u\t%u\t%-7s ",
1783 (void) printf("%-16lu", pr
->prog
);
1784 (void) printf("%lu\t%lu\t%-7s ",
1786 pr
->vers
, pr
->proc
, pr
->netid
);
1787 if (rtype
== RPCBVERS_4_STAT
)
1788 (void) printf("%d\t ", pr
->indirect
);
1789 (void) printf("%d\t%d\n", pr
->success
, pr
->failure
);
1794 /* LINTED E_FUNC_ARG_UNUSED for 1st arg rtype */
1795 print_getaddrstat(rtype
, infp
)
1799 rpcbs_addrlist_ptr al
;
1800 register struct rpcent
*rpc
;
1802 (void) printf("prog\t\tvers\tnetid\t success\tfailure\n");
1803 for (al
= infp
->addrinfo
; al
; al
= al
->next
) {
1804 rpc
= getrpcbynumber(al
->prog
);
1806 (void) printf("%-16s", rpc
->r_name
);
1808 #if defined(_LP64) || defined(_I32LPx)
1809 (void) printf("%-16u", al
->prog
);
1810 (void) printf("%u\t%-9s %-12d\t%d\n",
1812 (void) printf("%-16lu", al
->prog
);
1813 (void) printf("%lu\t%-9s %-12d\t%d\n",
1815 al
->vers
, al
->netid
,
1816 al
->success
, al
->failure
);
1824 static char space_array
[] = /* 64 spaces */
1827 if (howmany
<= 0 || howmany
> sizeof (space_array
)) {
1830 return (&space_array
[sizeof (space_array
) - howmany
- 1]);