10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*11563SVallish.Vaidyeshwara@Sun.COM * Common Development and Distribution License (the "License").
6*11563SVallish.Vaidyeshwara@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate *
21*11563SVallish.Vaidyeshwara@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
220Sstevel@tonic-gate * Use is subject to license terms.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
250Sstevel@tonic-gate /* All Rights Reserved */
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988
280Sstevel@tonic-gate * The Regents of the University of California
290Sstevel@tonic-gate * All Rights Reserved
300Sstevel@tonic-gate *
310Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from
320Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its
330Sstevel@tonic-gate * contributors.
340Sstevel@tonic-gate */
350Sstevel@tonic-gate
360Sstevel@tonic-gate /*
370Sstevel@tonic-gate * rpcinfo: ping a particular rpc program
380Sstevel@tonic-gate * or dump the the registered programs on the remote machine.
390Sstevel@tonic-gate */
400Sstevel@tonic-gate
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate * We are for now defining PORTMAP here. It doesnt even compile
430Sstevel@tonic-gate * unless it is defined.
440Sstevel@tonic-gate */
450Sstevel@tonic-gate #ifndef PORTMAP
460Sstevel@tonic-gate #define PORTMAP
470Sstevel@tonic-gate #endif
480Sstevel@tonic-gate
490Sstevel@tonic-gate /*
500Sstevel@tonic-gate * If PORTMAP is defined, rpcinfo will talk to both portmapper and
510Sstevel@tonic-gate * rpcbind programs; else it talks only to rpcbind. In the latter case
520Sstevel@tonic-gate * all the portmapper specific options such as -u, -t, -p become void.
530Sstevel@tonic-gate */
540Sstevel@tonic-gate #include <rpc/rpc.h>
550Sstevel@tonic-gate #include <stdio.h>
560Sstevel@tonic-gate #include <rpc/rpcb_prot.h>
570Sstevel@tonic-gate #include <rpc/nettype.h>
580Sstevel@tonic-gate #include <netdir.h>
590Sstevel@tonic-gate #include <rpc/rpcent.h>
600Sstevel@tonic-gate #include <sys/utsname.h>
610Sstevel@tonic-gate #include <stdlib.h>
620Sstevel@tonic-gate #include <string.h>
63*11563SVallish.Vaidyeshwara@Sun.COM #include <ctype.h>
640Sstevel@tonic-gate
650Sstevel@tonic-gate #ifdef PORTMAP /* Support for version 2 portmapper */
660Sstevel@tonic-gate #include <netinet/in.h>
670Sstevel@tonic-gate #include <sys/socket.h>
680Sstevel@tonic-gate #include <netdb.h>
690Sstevel@tonic-gate #include <arpa/inet.h>
700Sstevel@tonic-gate #include <rpc/pmap_prot.h>
710Sstevel@tonic-gate #include <rpc/pmap_clnt.h>
720Sstevel@tonic-gate #endif
730Sstevel@tonic-gate
740Sstevel@tonic-gate #define MAXHOSTLEN 256
750Sstevel@tonic-gate #define MIN_VERS ((ulong_t)0)
76481Sssdevi #define MAX_VERS (4294967295UL)
770Sstevel@tonic-gate #define UNKNOWN "unknown"
780Sstevel@tonic-gate
790Sstevel@tonic-gate #define MAX(a, b) (((a) > (b)) ? (a) : (b))
800Sstevel@tonic-gate
810Sstevel@tonic-gate extern int t_errno;
820Sstevel@tonic-gate extern long strtol();
830Sstevel@tonic-gate static char *spaces();
840Sstevel@tonic-gate
850Sstevel@tonic-gate #ifdef PORTMAP
860Sstevel@tonic-gate static void ip_ping(/*ushort_t portflag, char *trans,
870Sstevel@tonic-gate int argc, char **argv*/);
880Sstevel@tonic-gate static CLIENT *clnt_com_create(/* struct sockaddr_in *addr, long prog,
890Sstevel@tonic-gate long vers, int *fd, char *trans*/);
900Sstevel@tonic-gate static void pmapdump(/*int argc, char **argv*/);
910Sstevel@tonic-gate static void get_inet_address(/*struct sockaddr_in *addr, char *host*/);
920Sstevel@tonic-gate #endif
930Sstevel@tonic-gate
940Sstevel@tonic-gate static bool_t reply_proc(/*void *res, struct netbuf *who*,
950Sstevel@tonic-gate struct netconfig *nconf*/);
960Sstevel@tonic-gate static void brdcst(/*int argc, char **argv*/);
970Sstevel@tonic-gate static void addrping(/*char *address, char *netid,
980Sstevel@tonic-gate int argc, char **argv*/);
990Sstevel@tonic-gate static void progping(/* char *netid, int argc, char **argv*/);
1000Sstevel@tonic-gate static CLIENT *clnt_addr_create(/* char *addr, struct netconfig *nconf,
1010Sstevel@tonic-gate long prog, long vers*/);
1020Sstevel@tonic-gate static CLIENT *clnt_rpcbind_create(/* char *host, int vers */);
1030Sstevel@tonic-gate static CLIENT *getclnthandle(/* host, nconf, rpcbversnum */);
1040Sstevel@tonic-gate static int pstatus(/*CLIENT *client, ulong_t prognum, ulong_t vers*/);
1050Sstevel@tonic-gate static void rpcbdump(/*char *netid, int argc, char **argv*/);
1060Sstevel@tonic-gate static void rpcbgetstat(/* int argc, char **argv*/);
1070Sstevel@tonic-gate static void rpcbaddrlist(/*char *netid, int argc, char **argv*/);
1080Sstevel@tonic-gate static void deletereg(/*char *netid, int argc, char **argv */);
1090Sstevel@tonic-gate static void print_rmtcallstat(/* rtype, infp */);
1100Sstevel@tonic-gate static void print_getaddrstat(/* rtype, infp */);
1110Sstevel@tonic-gate static void usage(/*void*/);
1120Sstevel@tonic-gate static ulong_t getprognum(/*char *arg*/);
1130Sstevel@tonic-gate static ulong_t getvers(/*char *arg*/);
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate /*
1160Sstevel@tonic-gate * Functions to be performed.
1170Sstevel@tonic-gate */
1180Sstevel@tonic-gate #define NONE 0 /* no function */
1190Sstevel@tonic-gate #define PMAPDUMP 1 /* dump portmapper registrations */
1200Sstevel@tonic-gate #define TCPPING 2 /* ping TCP service */
1210Sstevel@tonic-gate #define UDPPING 3 /* ping UDP service */
1220Sstevel@tonic-gate #define BROADCAST 4 /* ping broadcast service */
1230Sstevel@tonic-gate #define DELETES 5 /* delete registration for the service */
1240Sstevel@tonic-gate #define ADDRPING 6 /* pings at the given address */
1250Sstevel@tonic-gate #define PROGPING 7 /* pings a program on a given host */
1260Sstevel@tonic-gate #define RPCBDUMP 8 /* dump rpcbind registrations */
1270Sstevel@tonic-gate #define RPCBDUMP_SHORT 9 /* dump rpcbind registrations - short version */
1280Sstevel@tonic-gate #define RPCBADDRLIST 10 /* dump addr list about one prog */
1290Sstevel@tonic-gate #define RPCBGETSTAT 11 /* Get statistics */
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate struct netidlist {
1320Sstevel@tonic-gate char *netid;
1330Sstevel@tonic-gate struct netidlist *next;
1340Sstevel@tonic-gate };
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate struct verslist {
1370Sstevel@tonic-gate int vers;
1380Sstevel@tonic-gate struct verslist *next;
1390Sstevel@tonic-gate };
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate struct rpcbdump_short {
1420Sstevel@tonic-gate ulong_t prog;
1430Sstevel@tonic-gate struct verslist *vlist;
1440Sstevel@tonic-gate struct netidlist *nlist;
1450Sstevel@tonic-gate struct rpcbdump_short *next;
1460Sstevel@tonic-gate char *owner;
1470Sstevel@tonic-gate };
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate char *loopback_netid = NULL;
1510Sstevel@tonic-gate struct netconfig *loopback_nconf;
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate int
main(argc,argv)1540Sstevel@tonic-gate main(argc, argv)
1550Sstevel@tonic-gate int argc;
1560Sstevel@tonic-gate char **argv;
1570Sstevel@tonic-gate {
1580Sstevel@tonic-gate register int c;
1590Sstevel@tonic-gate extern char *optarg;
1600Sstevel@tonic-gate extern int optind;
1610Sstevel@tonic-gate int errflg;
1620Sstevel@tonic-gate int function;
1630Sstevel@tonic-gate char *netid = NULL;
1640Sstevel@tonic-gate char *address = NULL;
1650Sstevel@tonic-gate void *handle;
1660Sstevel@tonic-gate #ifdef PORTMAP
1670Sstevel@tonic-gate char *strptr;
1680Sstevel@tonic-gate ushort_t portnum = 0;
1690Sstevel@tonic-gate #endif
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate function = NONE;
1720Sstevel@tonic-gate errflg = 0;
1730Sstevel@tonic-gate #ifdef PORTMAP
1740Sstevel@tonic-gate while ((c = getopt(argc, argv, "a:bdlmn:pstT:u")) != EOF) {
1750Sstevel@tonic-gate #else
1760Sstevel@tonic-gate while ((c = getopt(argc, argv, "a:bdlmn:sT:")) != EOF) {
1770Sstevel@tonic-gate #endif
1780Sstevel@tonic-gate switch (c) {
1790Sstevel@tonic-gate #ifdef PORTMAP
1800Sstevel@tonic-gate case 'p':
1810Sstevel@tonic-gate if (function != NONE)
1820Sstevel@tonic-gate errflg = 1;
1830Sstevel@tonic-gate else
1840Sstevel@tonic-gate function = PMAPDUMP;
1850Sstevel@tonic-gate break;
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate case 't':
1880Sstevel@tonic-gate if (function != NONE)
1890Sstevel@tonic-gate errflg = 1;
1900Sstevel@tonic-gate else
1910Sstevel@tonic-gate function = TCPPING;
1920Sstevel@tonic-gate break;
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate case 'u':
1950Sstevel@tonic-gate if (function != NONE)
1960Sstevel@tonic-gate errflg = 1;
1970Sstevel@tonic-gate else
1980Sstevel@tonic-gate function = UDPPING;
1990Sstevel@tonic-gate break;
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate case 'n':
2020Sstevel@tonic-gate portnum = (ushort_t)strtol(optarg, &strptr, 10);
2030Sstevel@tonic-gate if (strptr == optarg || *strptr != '\0') {
204*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
2050Sstevel@tonic-gate "rpcinfo: %s is illegal port number\n",
2060Sstevel@tonic-gate optarg);
2070Sstevel@tonic-gate exit(1);
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate break;
2100Sstevel@tonic-gate #endif
2110Sstevel@tonic-gate case 'a':
2120Sstevel@tonic-gate address = optarg;
2130Sstevel@tonic-gate if (function != NONE)
2140Sstevel@tonic-gate errflg = 1;
2150Sstevel@tonic-gate else
2160Sstevel@tonic-gate function = ADDRPING;
2170Sstevel@tonic-gate break;
2180Sstevel@tonic-gate case 'b':
2190Sstevel@tonic-gate if (function != NONE)
2200Sstevel@tonic-gate errflg = 1;
2210Sstevel@tonic-gate else
2220Sstevel@tonic-gate function = BROADCAST;
2230Sstevel@tonic-gate break;
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate case 'd':
2260Sstevel@tonic-gate if (function != NONE)
2270Sstevel@tonic-gate errflg = 1;
2280Sstevel@tonic-gate else
2290Sstevel@tonic-gate function = DELETES;
2300Sstevel@tonic-gate break;
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate case 'l':
2330Sstevel@tonic-gate if (function != NONE)
2340Sstevel@tonic-gate errflg = 1;
2350Sstevel@tonic-gate else
2360Sstevel@tonic-gate function = RPCBADDRLIST;
2370Sstevel@tonic-gate break;
2380Sstevel@tonic-gate
2390Sstevel@tonic-gate case 'm':
2400Sstevel@tonic-gate if (function != NONE)
2410Sstevel@tonic-gate errflg = 1;
2420Sstevel@tonic-gate else
2430Sstevel@tonic-gate function = RPCBGETSTAT;
2440Sstevel@tonic-gate break;
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate case 's':
2470Sstevel@tonic-gate if (function != NONE)
2480Sstevel@tonic-gate errflg = 1;
2490Sstevel@tonic-gate else
2500Sstevel@tonic-gate function = RPCBDUMP_SHORT;
2510Sstevel@tonic-gate break;
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate case 'T':
2540Sstevel@tonic-gate netid = optarg;
2550Sstevel@tonic-gate break;
2560Sstevel@tonic-gate case '?':
2570Sstevel@tonic-gate errflg = 1;
2580Sstevel@tonic-gate break;
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate if (errflg || ((function == ADDRPING) && !netid)) {
2630Sstevel@tonic-gate usage();
2640Sstevel@tonic-gate return (1);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate if (netid == NULL) { /* user has not selected transport to use */
2670Sstevel@tonic-gate /*
2680Sstevel@tonic-gate * See if a COTS loopback transport is available, in case we
2690Sstevel@tonic-gate * will be talking to the local system.
2700Sstevel@tonic-gate */
2710Sstevel@tonic-gate handle = setnetconfig();
2720Sstevel@tonic-gate while ((loopback_nconf = getnetconfig(handle)) != NULL) {
2730Sstevel@tonic-gate if (strcmp(loopback_nconf->nc_protofmly,
2740Sstevel@tonic-gate NC_LOOPBACK) == 0 &&
2750Sstevel@tonic-gate (loopback_nconf->nc_semantics == NC_TPI_COTS ||
2760Sstevel@tonic-gate loopback_nconf->nc_semantics == NC_TPI_COTS_ORD)) {
2770Sstevel@tonic-gate loopback_netid = loopback_nconf->nc_netid;
2780Sstevel@tonic-gate break;
2790Sstevel@tonic-gate }
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate if (loopback_netid == NULL) {
282*11563SVallish.Vaidyeshwara@Sun.COM (void) endnetconfig(handle);
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate }
2850Sstevel@tonic-gate if (function == NONE) {
2860Sstevel@tonic-gate if (argc - optind > 1)
2870Sstevel@tonic-gate function = PROGPING;
2880Sstevel@tonic-gate else
2890Sstevel@tonic-gate function = RPCBDUMP;
2900Sstevel@tonic-gate }
2910Sstevel@tonic-gate
2920Sstevel@tonic-gate switch (function) {
2930Sstevel@tonic-gate #ifdef PORTMAP
2940Sstevel@tonic-gate case PMAPDUMP:
2950Sstevel@tonic-gate if (portnum != 0) {
2960Sstevel@tonic-gate usage();
2970Sstevel@tonic-gate return (1);
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate pmapdump(argc - optind, argv + optind);
3000Sstevel@tonic-gate break;
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate case UDPPING:
3030Sstevel@tonic-gate ip_ping(portnum, "udp", argc - optind, argv + optind);
3040Sstevel@tonic-gate break;
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate case TCPPING:
3070Sstevel@tonic-gate ip_ping(portnum, "tcp", argc - optind, argv + optind);
3080Sstevel@tonic-gate break;
3090Sstevel@tonic-gate #endif
3100Sstevel@tonic-gate case BROADCAST:
3110Sstevel@tonic-gate brdcst(argc - optind, argv + optind);
3120Sstevel@tonic-gate break;
3130Sstevel@tonic-gate case DELETES:
3140Sstevel@tonic-gate deletereg(netid, argc - optind, argv + optind);
3150Sstevel@tonic-gate break;
3160Sstevel@tonic-gate case ADDRPING:
3170Sstevel@tonic-gate addrping(address, netid, argc - optind, argv + optind);
3180Sstevel@tonic-gate break;
3190Sstevel@tonic-gate case PROGPING:
3200Sstevel@tonic-gate progping(netid, argc - optind, argv + optind);
3210Sstevel@tonic-gate break;
3220Sstevel@tonic-gate case RPCBDUMP:
3230Sstevel@tonic-gate case RPCBDUMP_SHORT:
3240Sstevel@tonic-gate rpcbdump(function, netid, argc - optind, argv + optind);
3250Sstevel@tonic-gate break;
3260Sstevel@tonic-gate case RPCBGETSTAT:
3270Sstevel@tonic-gate rpcbgetstat(argc - optind, argv + optind);
3280Sstevel@tonic-gate break;
3290Sstevel@tonic-gate case RPCBADDRLIST:
3300Sstevel@tonic-gate rpcbaddrlist(netid, argc - optind, argv + optind);
3310Sstevel@tonic-gate break;
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate return (0);
3340Sstevel@tonic-gate }
3350Sstevel@tonic-gate
3360Sstevel@tonic-gate #ifdef PORTMAP
3370Sstevel@tonic-gate static CLIENT *
clnt_com_create(addr,prog,vers,fdp,trans)3380Sstevel@tonic-gate clnt_com_create(addr, prog, vers, fdp, trans)
3390Sstevel@tonic-gate struct sockaddr_in *addr;
3400Sstevel@tonic-gate ulong_t prog;
3410Sstevel@tonic-gate ulong_t vers;
3420Sstevel@tonic-gate int *fdp;
3430Sstevel@tonic-gate char *trans;
3440Sstevel@tonic-gate {
3450Sstevel@tonic-gate CLIENT *clnt;
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate if (strcmp(trans, "tcp") == 0) {
3480Sstevel@tonic-gate clnt = clnttcp_create(addr, prog, vers, fdp, 0, 0);
3490Sstevel@tonic-gate } else {
3500Sstevel@tonic-gate struct timeval to;
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate to.tv_sec = 5;
3530Sstevel@tonic-gate to.tv_usec = 0;
3540Sstevel@tonic-gate clnt = clntudp_create(addr, prog, vers, to, fdp);
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate if (clnt == (CLIENT *)NULL) {
3570Sstevel@tonic-gate clnt_pcreateerror("rpcinfo");
3580Sstevel@tonic-gate if (vers == MIN_VERS)
359*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("program %lu is not available\n", prog);
3600Sstevel@tonic-gate else
361*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(
362*11563SVallish.Vaidyeshwara@Sun.COM "program %lu version %lu is not available\n",
3630Sstevel@tonic-gate prog, vers);
3640Sstevel@tonic-gate exit(1);
3650Sstevel@tonic-gate }
3660Sstevel@tonic-gate return (clnt);
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate /*
3700Sstevel@tonic-gate * If portnum is 0, then go and get the address from portmapper, which happens
3710Sstevel@tonic-gate * transparently through clnt*_create(); If version number is not given, it
3720Sstevel@tonic-gate * tries to find out the version number by making a call to version 0 and if
3730Sstevel@tonic-gate * that fails, it obtains the high order and the low order version number. If
3740Sstevel@tonic-gate * version 0 calls succeeds, it tries for MAXVERS call and repeats the same.
3750Sstevel@tonic-gate */
3760Sstevel@tonic-gate static void
ip_ping(portnum,trans,argc,argv)3770Sstevel@tonic-gate ip_ping(portnum, trans, argc, argv)
3780Sstevel@tonic-gate ushort_t portnum;
3790Sstevel@tonic-gate char *trans;
3800Sstevel@tonic-gate int argc;
3810Sstevel@tonic-gate char **argv;
3820Sstevel@tonic-gate {
3830Sstevel@tonic-gate CLIENT *client;
3840Sstevel@tonic-gate int fd = RPC_ANYFD;
3850Sstevel@tonic-gate struct timeval to;
3860Sstevel@tonic-gate struct sockaddr_in addr;
3870Sstevel@tonic-gate enum clnt_stat rpc_stat;
3880Sstevel@tonic-gate ulong_t prognum, vers, minvers, maxvers;
3890Sstevel@tonic-gate struct rpc_err rpcerr;
3900Sstevel@tonic-gate int failure = 0;
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate if (argc < 2 || argc > 3) {
3930Sstevel@tonic-gate usage();
3940Sstevel@tonic-gate exit(1);
3950Sstevel@tonic-gate }
3960Sstevel@tonic-gate to.tv_sec = 10;
3970Sstevel@tonic-gate to.tv_usec = 0;
3980Sstevel@tonic-gate prognum = getprognum(argv[1]);
3990Sstevel@tonic-gate get_inet_address(&addr, argv[0]);
4000Sstevel@tonic-gate if (argc == 2) { /* Version number not known */
4010Sstevel@tonic-gate /*
4020Sstevel@tonic-gate * A call to version 0 should fail with a program/version
4030Sstevel@tonic-gate * mismatch, and give us the range of versions supported.
4040Sstevel@tonic-gate */
4050Sstevel@tonic-gate vers = MIN_VERS;
4060Sstevel@tonic-gate } else {
4070Sstevel@tonic-gate vers = getvers(argv[2]);
4080Sstevel@tonic-gate }
4090Sstevel@tonic-gate addr.sin_port = htons(portnum);
4100Sstevel@tonic-gate client = clnt_com_create(&addr, prognum, vers, &fd, trans);
4110Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void,
4120Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, (char *)NULL,
4130Sstevel@tonic-gate to);
4140Sstevel@tonic-gate if (argc != 2) {
4150Sstevel@tonic-gate /* Version number was known */
4160Sstevel@tonic-gate if (pstatus(client, prognum, vers) < 0)
4170Sstevel@tonic-gate exit(1);
4180Sstevel@tonic-gate (void) CLNT_DESTROY(client);
4190Sstevel@tonic-gate return;
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate /* Version number not known */
4220Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL);
4230Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) {
4240Sstevel@tonic-gate clnt_geterr(client, &rpcerr);
4250Sstevel@tonic-gate minvers = rpcerr.re_vers.low;
4260Sstevel@tonic-gate maxvers = rpcerr.re_vers.high;
4270Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) {
4280Sstevel@tonic-gate /*
4290Sstevel@tonic-gate * Oh dear, it DOES support version 0.
4300Sstevel@tonic-gate * Let's try version MAX_VERS.
4310Sstevel@tonic-gate */
4320Sstevel@tonic-gate (void) CLNT_DESTROY(client);
4330Sstevel@tonic-gate addr.sin_port = htons(portnum);
4340Sstevel@tonic-gate client = clnt_com_create(&addr, prognum, MAX_VERS, &fd, trans);
4350Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void,
4360Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void,
4370Sstevel@tonic-gate (char *)NULL, to);
4380Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) {
4390Sstevel@tonic-gate clnt_geterr(client, &rpcerr);
4400Sstevel@tonic-gate minvers = rpcerr.re_vers.low;
4410Sstevel@tonic-gate maxvers = rpcerr.re_vers.high;
4420Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) {
4430Sstevel@tonic-gate /*
4440Sstevel@tonic-gate * It also supports version MAX_VERS.
4450Sstevel@tonic-gate * Looks like we have a wise guy.
4460Sstevel@tonic-gate * OK, we give them information on all
4470Sstevel@tonic-gate * 4 billion versions they support...
4480Sstevel@tonic-gate */
4490Sstevel@tonic-gate minvers = 0;
4500Sstevel@tonic-gate maxvers = MAX_VERS;
4510Sstevel@tonic-gate } else {
4520Sstevel@tonic-gate (void) pstatus(client, prognum, MAX_VERS);
4530Sstevel@tonic-gate exit(1);
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate } else {
4560Sstevel@tonic-gate (void) pstatus(client, prognum, (ulong_t)0);
4570Sstevel@tonic-gate exit(1);
4580Sstevel@tonic-gate }
4590Sstevel@tonic-gate (void) CLNT_DESTROY(client);
4600Sstevel@tonic-gate for (vers = minvers; vers <= maxvers; vers++) {
4610Sstevel@tonic-gate addr.sin_port = htons(portnum);
4620Sstevel@tonic-gate client = clnt_com_create(&addr, prognum, vers, &fd, trans);
4630Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void,
4640Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void,
4650Sstevel@tonic-gate (char *)NULL, to);
4660Sstevel@tonic-gate if (pstatus(client, prognum, vers) < 0)
4670Sstevel@tonic-gate failure = 1;
4680Sstevel@tonic-gate (void) CLNT_DESTROY(client);
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate if (failure)
4710Sstevel@tonic-gate exit(1);
4720Sstevel@tonic-gate (void) t_close(fd);
4730Sstevel@tonic-gate }
4740Sstevel@tonic-gate
4750Sstevel@tonic-gate /*
4760Sstevel@tonic-gate * Dump all the portmapper registerations
4770Sstevel@tonic-gate */
4780Sstevel@tonic-gate static void
pmapdump(argc,argv)4790Sstevel@tonic-gate pmapdump(argc, argv)
4800Sstevel@tonic-gate int argc;
4810Sstevel@tonic-gate char **argv;
4820Sstevel@tonic-gate {
4830Sstevel@tonic-gate struct sockaddr_in server_addr;
4840Sstevel@tonic-gate pmaplist_ptr head = NULL;
4850Sstevel@tonic-gate int socket = RPC_ANYSOCK;
4860Sstevel@tonic-gate struct timeval minutetimeout;
4870Sstevel@tonic-gate register CLIENT *client;
4880Sstevel@tonic-gate struct rpcent *rpc;
4890Sstevel@tonic-gate enum clnt_stat clnt_st;
4900Sstevel@tonic-gate struct rpc_err err;
4910Sstevel@tonic-gate struct utsname utsname;
4920Sstevel@tonic-gate char *host;
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate if (argc > 1) {
4950Sstevel@tonic-gate usage();
4960Sstevel@tonic-gate exit(1);
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate if (argc == 1) {
4990Sstevel@tonic-gate host = argv[0];
5000Sstevel@tonic-gate get_inet_address(&server_addr, host);
5010Sstevel@tonic-gate } else {
502*11563SVallish.Vaidyeshwara@Sun.COM (void) uname(&utsname);
5030Sstevel@tonic-gate host = utsname.nodename;
5040Sstevel@tonic-gate get_inet_address(&server_addr, host);
5050Sstevel@tonic-gate }
5060Sstevel@tonic-gate minutetimeout.tv_sec = 60;
5070Sstevel@tonic-gate minutetimeout.tv_usec = 0;
5080Sstevel@tonic-gate server_addr.sin_port = htons(PMAPPORT);
5090Sstevel@tonic-gate if ((client = clnttcp_create(&server_addr, PMAPPROG,
5100Sstevel@tonic-gate PMAPVERS, &socket, 50, 500)) == NULL) {
5110Sstevel@tonic-gate if (rpc_createerr.cf_stat == RPC_TLIERROR) {
5120Sstevel@tonic-gate /*
5130Sstevel@tonic-gate * "Misc. TLI error" is not too helpful. Most likely
5140Sstevel@tonic-gate * the connection to the remote server timed out, so
5150Sstevel@tonic-gate * this error is at least less perplexing.
5160Sstevel@tonic-gate */
5170Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_PMAPFAILURE;
5180Sstevel@tonic-gate rpc_createerr.cf_error.re_status = RPC_FAILED;
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate clnt_pcreateerror("rpcinfo: can't contact portmapper");
5210Sstevel@tonic-gate exit(1);
5220Sstevel@tonic-gate }
5230Sstevel@tonic-gate clnt_st = CLNT_CALL(client, PMAPPROC_DUMP, (xdrproc_t)xdr_void,
5240Sstevel@tonic-gate NULL, (xdrproc_t)xdr_pmaplist_ptr, (char *)&head,
5250Sstevel@tonic-gate minutetimeout);
5260Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS) {
5270Sstevel@tonic-gate if ((clnt_st == RPC_PROGVERSMISMATCH) ||
5280Sstevel@tonic-gate (clnt_st == RPC_PROGUNAVAIL)) {
5290Sstevel@tonic-gate CLNT_GETERR(client, &err);
5300Sstevel@tonic-gate if (err.re_vers.low > PMAPVERS)
531*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
5320Sstevel@tonic-gate "%s does not support portmapper. Try rpcinfo %s instead\n",
5330Sstevel@tonic-gate host, host);
5340Sstevel@tonic-gate exit(1);
5350Sstevel@tonic-gate }
5360Sstevel@tonic-gate clnt_perror(client, "rpcinfo: can't contact portmapper");
5370Sstevel@tonic-gate exit(1);
5380Sstevel@tonic-gate }
5390Sstevel@tonic-gate if (head == NULL) {
540*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("No remote programs registered.\n");
5410Sstevel@tonic-gate } else {
542*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" program vers proto port service\n");
5430Sstevel@tonic-gate for (; head != NULL; head = head->pml_next) {
544*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%10ld%5ld",
5450Sstevel@tonic-gate head->pml_map.pm_prog,
5460Sstevel@tonic-gate head->pml_map.pm_vers);
5470Sstevel@tonic-gate if (head->pml_map.pm_prot == IPPROTO_UDP)
548*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%6s", "udp");
5490Sstevel@tonic-gate else if (head->pml_map.pm_prot == IPPROTO_TCP)
550*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%6s", "tcp");
5510Sstevel@tonic-gate else
552*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%6ld", head->pml_map.pm_prot);
553*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%7ld", head->pml_map.pm_port);
5540Sstevel@tonic-gate rpc = getrpcbynumber(head->pml_map.pm_prog);
5550Sstevel@tonic-gate if (rpc)
556*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %s\n", rpc->r_name);
5570Sstevel@tonic-gate else
558*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n");
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate }
5610Sstevel@tonic-gate }
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate static void
get_inet_address(addr,host)5640Sstevel@tonic-gate get_inet_address(addr, host)
5650Sstevel@tonic-gate struct sockaddr_in *addr;
5660Sstevel@tonic-gate char *host;
5670Sstevel@tonic-gate {
5680Sstevel@tonic-gate struct netconfig *nconf;
5690Sstevel@tonic-gate struct nd_hostserv service;
5700Sstevel@tonic-gate struct nd_addrlist *naddrs;
5710Sstevel@tonic-gate
5720Sstevel@tonic-gate (void) memset((char *)addr, 0, sizeof (*addr));
5730Sstevel@tonic-gate addr->sin_addr.s_addr = inet_addr(host);
574*11563SVallish.Vaidyeshwara@Sun.COM if (addr->sin_addr.s_addr == (uint32_t)-1 ||
575*11563SVallish.Vaidyeshwara@Sun.COM addr->sin_addr.s_addr == 0) {
5760Sstevel@tonic-gate if ((nconf = __rpc_getconfip("udp")) == NULL &&
5770Sstevel@tonic-gate (nconf = __rpc_getconfip("tcp")) == NULL) {
578*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
5790Sstevel@tonic-gate "rpcinfo: couldn't find a suitable transport\n");
5800Sstevel@tonic-gate exit(1);
5810Sstevel@tonic-gate } else {
5820Sstevel@tonic-gate service.h_host = host;
5830Sstevel@tonic-gate service.h_serv = "rpcbind";
5840Sstevel@tonic-gate if (netdir_getbyname(nconf, &service, &naddrs)) {
585*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr, "rpcinfo: %s: %s\n",
5860Sstevel@tonic-gate host, netdir_sperror());
5870Sstevel@tonic-gate exit(1);
5880Sstevel@tonic-gate } else {
5890Sstevel@tonic-gate (void) memcpy((caddr_t)addr,
5900Sstevel@tonic-gate naddrs->n_addrs->buf, naddrs->n_addrs->len);
5910Sstevel@tonic-gate (void) netdir_free((char *)naddrs, ND_ADDRLIST);
5920Sstevel@tonic-gate }
5930Sstevel@tonic-gate (void) freenetconfigent(nconf);
5940Sstevel@tonic-gate }
5950Sstevel@tonic-gate } else {
5960Sstevel@tonic-gate addr->sin_family = AF_INET;
5970Sstevel@tonic-gate }
5980Sstevel@tonic-gate }
5990Sstevel@tonic-gate #endif /* PORTMAP */
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate /*
6020Sstevel@tonic-gate * reply_proc collects replies from the broadcast.
6030Sstevel@tonic-gate * to get a unique list of responses the output of rpcinfo should
6040Sstevel@tonic-gate * be piped through sort(1) and then uniq(1).
6050Sstevel@tonic-gate */
6060Sstevel@tonic-gate
6070Sstevel@tonic-gate /*ARGSUSED*/
6080Sstevel@tonic-gate static bool_t
reply_proc(res,who,nconf)6090Sstevel@tonic-gate reply_proc(res, who, nconf)
6100Sstevel@tonic-gate void *res; /* Nothing comes back */
6110Sstevel@tonic-gate struct netbuf *who; /* Who sent us the reply */
6120Sstevel@tonic-gate struct netconfig *nconf; /* On which transport the reply came */
6130Sstevel@tonic-gate {
6140Sstevel@tonic-gate struct nd_hostservlist *serv;
6150Sstevel@tonic-gate char *uaddr;
6160Sstevel@tonic-gate char *hostname;
6170Sstevel@tonic-gate
6180Sstevel@tonic-gate if (netdir_getbyaddr(nconf, &serv, who)) {
6190Sstevel@tonic-gate hostname = UNKNOWN;
6200Sstevel@tonic-gate } else {
6210Sstevel@tonic-gate hostname = serv->h_hostservs->h_host;
6220Sstevel@tonic-gate }
6230Sstevel@tonic-gate if (!(uaddr = taddr2uaddr(nconf, who))) {
6240Sstevel@tonic-gate uaddr = UNKNOWN;
6250Sstevel@tonic-gate }
626*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%s\t%s\n", uaddr, hostname);
6270Sstevel@tonic-gate if (strcmp(hostname, UNKNOWN))
6280Sstevel@tonic-gate netdir_free((char *)serv, ND_HOSTSERVLIST);
6290Sstevel@tonic-gate if (strcmp(uaddr, UNKNOWN))
6300Sstevel@tonic-gate free((char *)uaddr);
6310Sstevel@tonic-gate return (FALSE);
6320Sstevel@tonic-gate }
6330Sstevel@tonic-gate
6340Sstevel@tonic-gate static void
brdcst(argc,argv)6350Sstevel@tonic-gate brdcst(argc, argv)
6360Sstevel@tonic-gate int argc;
6370Sstevel@tonic-gate char **argv;
6380Sstevel@tonic-gate {
6390Sstevel@tonic-gate enum clnt_stat rpc_stat;
6400Sstevel@tonic-gate ulong_t prognum, vers;
6410Sstevel@tonic-gate
6420Sstevel@tonic-gate if (argc != 2) {
6430Sstevel@tonic-gate usage();
6440Sstevel@tonic-gate exit(1);
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate prognum = getprognum(argv[0]);
6470Sstevel@tonic-gate vers = getvers(argv[1]);
6480Sstevel@tonic-gate rpc_stat = rpc_broadcast(prognum, vers, NULLPROC,
6490Sstevel@tonic-gate (xdrproc_t)xdr_void, (char *)NULL, (xdrproc_t)xdr_void,
6500Sstevel@tonic-gate (char *)NULL, (resultproc_t)reply_proc, NULL);
6510Sstevel@tonic-gate if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) {
652*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr, "rpcinfo: broadcast failed: %s\n",
6530Sstevel@tonic-gate clnt_sperrno(rpc_stat));
6540Sstevel@tonic-gate exit(1);
6550Sstevel@tonic-gate }
6560Sstevel@tonic-gate exit(0);
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate
6590Sstevel@tonic-gate static bool_t
add_version(rs,vers)6600Sstevel@tonic-gate add_version(rs, vers)
6610Sstevel@tonic-gate struct rpcbdump_short *rs;
6620Sstevel@tonic-gate ulong_t vers;
6630Sstevel@tonic-gate {
6640Sstevel@tonic-gate struct verslist *vl;
6650Sstevel@tonic-gate
6660Sstevel@tonic-gate for (vl = rs->vlist; vl; vl = vl->next)
6670Sstevel@tonic-gate if (vl->vers == vers)
6680Sstevel@tonic-gate break;
6690Sstevel@tonic-gate if (vl)
6700Sstevel@tonic-gate return (TRUE);
6710Sstevel@tonic-gate vl = (struct verslist *)malloc(sizeof (struct verslist));
6720Sstevel@tonic-gate if (vl == NULL)
6730Sstevel@tonic-gate return (FALSE);
6740Sstevel@tonic-gate vl->vers = vers;
6750Sstevel@tonic-gate vl->next = rs->vlist;
6760Sstevel@tonic-gate rs->vlist = vl;
6770Sstevel@tonic-gate return (TRUE);
6780Sstevel@tonic-gate }
6790Sstevel@tonic-gate
6800Sstevel@tonic-gate static bool_t
add_netid(rs,netid)6810Sstevel@tonic-gate add_netid(rs, netid)
6820Sstevel@tonic-gate struct rpcbdump_short *rs;
6830Sstevel@tonic-gate char *netid;
6840Sstevel@tonic-gate {
6850Sstevel@tonic-gate struct netidlist *nl;
6860Sstevel@tonic-gate
6870Sstevel@tonic-gate for (nl = rs->nlist; nl; nl = nl->next)
6880Sstevel@tonic-gate if (strcmp(nl->netid, netid) == 0)
6890Sstevel@tonic-gate break;
6900Sstevel@tonic-gate if (nl)
6910Sstevel@tonic-gate return (TRUE);
6920Sstevel@tonic-gate nl = (struct netidlist *)malloc(sizeof (struct netidlist));
6930Sstevel@tonic-gate if (nl == NULL)
6940Sstevel@tonic-gate return (FALSE);
6950Sstevel@tonic-gate nl->netid = netid;
6960Sstevel@tonic-gate nl->next = rs->nlist;
6970Sstevel@tonic-gate rs->nlist = nl;
6980Sstevel@tonic-gate return (TRUE);
6990Sstevel@tonic-gate }
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate static void
rpcbdump(dumptype,netid,argc,argv)7020Sstevel@tonic-gate rpcbdump(dumptype, netid, argc, argv)
7030Sstevel@tonic-gate int dumptype;
7040Sstevel@tonic-gate char *netid;
7050Sstevel@tonic-gate int argc;
7060Sstevel@tonic-gate char **argv;
7070Sstevel@tonic-gate {
7080Sstevel@tonic-gate rpcblist_ptr head = NULL;
7090Sstevel@tonic-gate struct timeval minutetimeout;
7100Sstevel@tonic-gate register CLIENT *client;
7110Sstevel@tonic-gate struct rpcent *rpc;
7120Sstevel@tonic-gate char *host;
7130Sstevel@tonic-gate struct netidlist *nl;
7140Sstevel@tonic-gate struct verslist *vl;
7150Sstevel@tonic-gate struct rpcbdump_short *rs, *rs_tail;
7160Sstevel@tonic-gate enum clnt_stat clnt_st;
7170Sstevel@tonic-gate struct rpc_err err;
7180Sstevel@tonic-gate struct utsname utsname;
7190Sstevel@tonic-gate struct rpcbdump_short *rs_head = NULL;
7200Sstevel@tonic-gate
7210Sstevel@tonic-gate if (argc > 1) {
7220Sstevel@tonic-gate usage();
7230Sstevel@tonic-gate exit(1);
7240Sstevel@tonic-gate }
7250Sstevel@tonic-gate if (argc == 1) {
7260Sstevel@tonic-gate host = argv[0];
7270Sstevel@tonic-gate } else {
728*11563SVallish.Vaidyeshwara@Sun.COM (void) uname(&utsname);
7290Sstevel@tonic-gate host = utsname.nodename;
7300Sstevel@tonic-gate }
7310Sstevel@tonic-gate if (netid == NULL) {
7320Sstevel@tonic-gate if (loopback_netid == NULL) {
7330Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS, NULL);
7340Sstevel@tonic-gate } else {
7350Sstevel@tonic-gate client = getclnthandle(host, loopback_nconf, RPCBVERS, NULL);
7360Sstevel@tonic-gate if (client == NULL && rpc_createerr.cf_stat ==
7370Sstevel@tonic-gate RPC_N2AXLATEFAILURE) {
7380Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS, NULL);
7390Sstevel@tonic-gate }
7400Sstevel@tonic-gate }
7410Sstevel@tonic-gate } else {
7420Sstevel@tonic-gate struct netconfig *nconf;
7430Sstevel@tonic-gate
7440Sstevel@tonic-gate nconf = getnetconfigent(netid);
7450Sstevel@tonic-gate if (nconf == NULL) {
7460Sstevel@tonic-gate nc_perror("rpcinfo: invalid transport");
7470Sstevel@tonic-gate exit(1);
7480Sstevel@tonic-gate }
7490Sstevel@tonic-gate client = getclnthandle(host, nconf, RPCBVERS, NULL);
7500Sstevel@tonic-gate if (nconf)
7510Sstevel@tonic-gate (void) freenetconfigent(nconf);
7520Sstevel@tonic-gate }
7530Sstevel@tonic-gate if (client == (CLIENT *)NULL) {
7540Sstevel@tonic-gate clnt_pcreateerror("rpcinfo: can't contact rpcbind");
7550Sstevel@tonic-gate exit(1);
7560Sstevel@tonic-gate }
7570Sstevel@tonic-gate minutetimeout.tv_sec = 60;
7580Sstevel@tonic-gate minutetimeout.tv_usec = 0;
7590Sstevel@tonic-gate clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, (xdrproc_t)xdr_void,
7600Sstevel@tonic-gate NULL, (xdrproc_t)xdr_rpcblist_ptr, (char *)&head,
7610Sstevel@tonic-gate minutetimeout);
7620Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS) {
7630Sstevel@tonic-gate if ((clnt_st == RPC_PROGVERSMISMATCH) ||
7640Sstevel@tonic-gate (clnt_st == RPC_PROGUNAVAIL)) {
7650Sstevel@tonic-gate int vers;
7660Sstevel@tonic-gate
7670Sstevel@tonic-gate CLNT_GETERR(client, &err);
7680Sstevel@tonic-gate if (err.re_vers.low == RPCBVERS4) {
7690Sstevel@tonic-gate vers = RPCBVERS4;
7700Sstevel@tonic-gate clnt_control(client, CLSET_VERS, (char *)&vers);
7710Sstevel@tonic-gate clnt_st = CLNT_CALL(client, RPCBPROC_DUMP,
7720Sstevel@tonic-gate (xdrproc_t)xdr_void, NULL,
7730Sstevel@tonic-gate (xdrproc_t)xdr_rpcblist_ptr, (char *)&head,
7740Sstevel@tonic-gate minutetimeout);
7750Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS)
7760Sstevel@tonic-gate goto failed;
7770Sstevel@tonic-gate } else {
7780Sstevel@tonic-gate if (err.re_vers.high == PMAPVERS) {
7790Sstevel@tonic-gate int high, low;
7800Sstevel@tonic-gate pmaplist_ptr pmaphead = NULL;
781*11563SVallish.Vaidyeshwara@Sun.COM rpcblist_ptr list, prev = NULL;
7820Sstevel@tonic-gate
7830Sstevel@tonic-gate vers = PMAPVERS;
7840Sstevel@tonic-gate clnt_control(client, CLSET_VERS, (char *)&vers);
7850Sstevel@tonic-gate clnt_st = CLNT_CALL(client, PMAPPROC_DUMP,
7860Sstevel@tonic-gate (xdrproc_t)xdr_void, NULL,
7870Sstevel@tonic-gate (xdrproc_t)xdr_pmaplist_ptr,
7880Sstevel@tonic-gate (char *)&pmaphead, minutetimeout);
7890Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS)
7900Sstevel@tonic-gate goto failed;
7910Sstevel@tonic-gate /*
7920Sstevel@tonic-gate * convert to rpcblist_ptr format
7930Sstevel@tonic-gate */
7940Sstevel@tonic-gate for (head = NULL; pmaphead != NULL;
7950Sstevel@tonic-gate pmaphead = pmaphead->pml_next) {
7960Sstevel@tonic-gate list = (rpcblist *)malloc(sizeof (rpcblist));
7970Sstevel@tonic-gate if (list == NULL)
7980Sstevel@tonic-gate goto error;
7990Sstevel@tonic-gate if (head == NULL)
8000Sstevel@tonic-gate head = list;
8010Sstevel@tonic-gate else
8020Sstevel@tonic-gate prev->rpcb_next = (rpcblist_ptr) list;
8030Sstevel@tonic-gate
8040Sstevel@tonic-gate list->rpcb_next = NULL;
8050Sstevel@tonic-gate list->rpcb_map.r_prog = pmaphead->pml_map.pm_prog;
8060Sstevel@tonic-gate list->rpcb_map.r_vers = pmaphead->pml_map.pm_vers;
8070Sstevel@tonic-gate if (pmaphead->pml_map.pm_prot == IPPROTO_UDP)
8080Sstevel@tonic-gate list->rpcb_map.r_netid = "udp";
8090Sstevel@tonic-gate else if (pmaphead->pml_map.pm_prot == IPPROTO_TCP)
8100Sstevel@tonic-gate list->rpcb_map.r_netid = "tcp";
8110Sstevel@tonic-gate else {
8120Sstevel@tonic-gate #define MAXLONG_AS_STRING "2147483648"
8130Sstevel@tonic-gate list->rpcb_map.r_netid =
8140Sstevel@tonic-gate malloc(strlen(MAXLONG_AS_STRING) + 1);
8150Sstevel@tonic-gate if (list->rpcb_map.r_netid == NULL)
8160Sstevel@tonic-gate goto error;
817*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(list->rpcb_map.r_netid, "%6ld",
8180Sstevel@tonic-gate pmaphead->pml_map.pm_prot);
8190Sstevel@tonic-gate }
8200Sstevel@tonic-gate list->rpcb_map.r_owner = UNKNOWN;
8210Sstevel@tonic-gate low = pmaphead->pml_map.pm_port & 0xff;
8220Sstevel@tonic-gate high = (pmaphead->pml_map.pm_port >> 8) & 0xff;
8230Sstevel@tonic-gate list->rpcb_map.r_addr = strdup("0.0.0.0.XXX.XXX");
824*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(&list->rpcb_map.r_addr[8], "%d.%d",
8250Sstevel@tonic-gate high, low);
8260Sstevel@tonic-gate prev = list;
8270Sstevel@tonic-gate }
8280Sstevel@tonic-gate }
8290Sstevel@tonic-gate }
8300Sstevel@tonic-gate } else { /* any other error */
8310Sstevel@tonic-gate failed:
8320Sstevel@tonic-gate clnt_perror(client, "rpcinfo: can't contact rpcbind: ");
8330Sstevel@tonic-gate exit(1);
8340Sstevel@tonic-gate }
8350Sstevel@tonic-gate }
8360Sstevel@tonic-gate if (head == NULL) {
837*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("No remote programs registered.\n");
8380Sstevel@tonic-gate } else if (dumptype == RPCBDUMP) {
839*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(
8400Sstevel@tonic-gate " program version netid address service owner\n");
8410Sstevel@tonic-gate for (; head != NULL; head = head->rpcb_next) {
842*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%10ld%5ld ",
8430Sstevel@tonic-gate head->rpcb_map.r_prog, head->rpcb_map.r_vers);
844*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-9s ", head->rpcb_map.r_netid);
845*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-19s", head->rpcb_map.r_addr);
8460Sstevel@tonic-gate rpc = getrpcbynumber(head->rpcb_map.r_prog);
8470Sstevel@tonic-gate if (rpc)
848*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %-10s", rpc->r_name);
8490Sstevel@tonic-gate else
850*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %-10s", "-");
851*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %s\n", head->rpcb_map.r_owner);
8520Sstevel@tonic-gate }
8530Sstevel@tonic-gate } else if (dumptype == RPCBDUMP_SHORT) {
8540Sstevel@tonic-gate for (; head != NULL; head = head->rpcb_next) {
8550Sstevel@tonic-gate for (rs = rs_head; rs; rs = rs->next)
8560Sstevel@tonic-gate if (head->rpcb_map.r_prog == rs->prog)
8570Sstevel@tonic-gate break;
8580Sstevel@tonic-gate if (rs == NULL) {
8590Sstevel@tonic-gate rs = (struct rpcbdump_short *)
8600Sstevel@tonic-gate malloc(sizeof (struct rpcbdump_short));
8610Sstevel@tonic-gate if (rs == NULL)
8620Sstevel@tonic-gate goto error;
8630Sstevel@tonic-gate rs->next = NULL;
8640Sstevel@tonic-gate if (rs_head == NULL) {
8650Sstevel@tonic-gate rs_head = rs;
8660Sstevel@tonic-gate rs_tail = rs;
8670Sstevel@tonic-gate } else {
8680Sstevel@tonic-gate rs_tail->next = rs;
8690Sstevel@tonic-gate rs_tail = rs;
8700Sstevel@tonic-gate }
8710Sstevel@tonic-gate rs->prog = head->rpcb_map.r_prog;
8720Sstevel@tonic-gate rs->owner = head->rpcb_map.r_owner;
8730Sstevel@tonic-gate rs->nlist = NULL;
8740Sstevel@tonic-gate rs->vlist = NULL;
8750Sstevel@tonic-gate }
8760Sstevel@tonic-gate if (add_version(rs, head->rpcb_map.r_vers) == FALSE)
8770Sstevel@tonic-gate goto error;
8780Sstevel@tonic-gate if (add_netid(rs, head->rpcb_map.r_netid) == FALSE)
8790Sstevel@tonic-gate goto error;
8800Sstevel@tonic-gate }
881*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(
8820Sstevel@tonic-gate " program version(s) netid(s) service owner\n");
8830Sstevel@tonic-gate for (rs = rs_head; rs; rs = rs->next) {
884*11563SVallish.Vaidyeshwara@Sun.COM int bytes_trans = 0;
885*11563SVallish.Vaidyeshwara@Sun.COM int len;
8860Sstevel@tonic-gate
887*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%10ld ", rs->prog);
8880Sstevel@tonic-gate for (vl = rs->vlist; vl; vl = vl->next) {
889*11563SVallish.Vaidyeshwara@Sun.COM bytes_trans += (len = printf("%d", vl->vers))
890*11563SVallish.Vaidyeshwara@Sun.COM < 0 ? 0 : len;
8910Sstevel@tonic-gate if (vl->next)
892*11563SVallish.Vaidyeshwara@Sun.COM bytes_trans += (len = printf(",")) < 0
893*11563SVallish.Vaidyeshwara@Sun.COM ? 0 : len;
8940Sstevel@tonic-gate }
895*11563SVallish.Vaidyeshwara@Sun.COM /*
896*11563SVallish.Vaidyeshwara@Sun.COM * If number of bytes transferred is less than 10,
897*11563SVallish.Vaidyeshwara@Sun.COM * align 10 bytes for version(s) column. If bytes
898*11563SVallish.Vaidyeshwara@Sun.COM * transferred is more than 10, add a trailing white
899*11563SVallish.Vaidyeshwara@Sun.COM * space.
900*11563SVallish.Vaidyeshwara@Sun.COM */
901*11563SVallish.Vaidyeshwara@Sun.COM if (bytes_trans < 10)
902*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%*s", (bytes_trans - 10), " ");
903*11563SVallish.Vaidyeshwara@Sun.COM else
904*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" ");
905*11563SVallish.Vaidyeshwara@Sun.COM
906*11563SVallish.Vaidyeshwara@Sun.COM bytes_trans = 0;
9070Sstevel@tonic-gate for (nl = rs->nlist; nl; nl = nl->next) {
908*11563SVallish.Vaidyeshwara@Sun.COM bytes_trans += (len = printf("%s", nl->netid))
909*11563SVallish.Vaidyeshwara@Sun.COM < 0 ? 0 : len;
9100Sstevel@tonic-gate if (nl->next)
911*11563SVallish.Vaidyeshwara@Sun.COM bytes_trans += (len = printf(",")) < 0
912*11563SVallish.Vaidyeshwara@Sun.COM ? 0 : len;
9130Sstevel@tonic-gate }
914*11563SVallish.Vaidyeshwara@Sun.COM /*
915*11563SVallish.Vaidyeshwara@Sun.COM * Align netid(s) column output for 32 bytes.
916*11563SVallish.Vaidyeshwara@Sun.COM */
917*11563SVallish.Vaidyeshwara@Sun.COM if (bytes_trans < 32)
918*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%*s", (bytes_trans - 32), " ");
919*11563SVallish.Vaidyeshwara@Sun.COM
9200Sstevel@tonic-gate rpc = getrpcbynumber(rs->prog);
9210Sstevel@tonic-gate if (rpc)
922*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %-11s", rpc->r_name);
9230Sstevel@tonic-gate else
924*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %-11s", "-");
925*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %s\n", rs->owner);
9260Sstevel@tonic-gate }
9270Sstevel@tonic-gate }
9280Sstevel@tonic-gate clnt_destroy(client);
9290Sstevel@tonic-gate return;
9300Sstevel@tonic-gate
931*11563SVallish.Vaidyeshwara@Sun.COM error: (void) fprintf(stderr, "rpcinfo: no memory\n");
9320Sstevel@tonic-gate }
9330Sstevel@tonic-gate
9340Sstevel@tonic-gate static char nullstring[] = "\000";
9350Sstevel@tonic-gate
9360Sstevel@tonic-gate static void
rpcbaddrlist(netid,argc,argv)9370Sstevel@tonic-gate rpcbaddrlist(netid, argc, argv)
9380Sstevel@tonic-gate char *netid;
9390Sstevel@tonic-gate int argc;
9400Sstevel@tonic-gate char **argv;
9410Sstevel@tonic-gate {
9420Sstevel@tonic-gate rpcb_entry_list_ptr head = NULL;
9430Sstevel@tonic-gate struct timeval minutetimeout;
9440Sstevel@tonic-gate register CLIENT *client;
9450Sstevel@tonic-gate struct rpcent *rpc;
9460Sstevel@tonic-gate char *host;
9470Sstevel@tonic-gate RPCB parms;
9480Sstevel@tonic-gate struct netbuf *targaddr;
9490Sstevel@tonic-gate
9500Sstevel@tonic-gate if (argc != 3) {
9510Sstevel@tonic-gate usage();
9520Sstevel@tonic-gate exit(1);
9530Sstevel@tonic-gate }
9540Sstevel@tonic-gate host = argv[0];
9550Sstevel@tonic-gate if (netid == NULL) {
9560Sstevel@tonic-gate if (loopback_netid == NULL) {
9570Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS4, &targaddr);
9580Sstevel@tonic-gate } else {
9590Sstevel@tonic-gate client = getclnthandle(host, loopback_nconf, RPCBVERS4,
9600Sstevel@tonic-gate &targaddr);
9610Sstevel@tonic-gate if (client == NULL && rpc_createerr.cf_stat ==
9620Sstevel@tonic-gate RPC_N2AXLATEFAILURE) {
9630Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS4, &targaddr);
9640Sstevel@tonic-gate }
9650Sstevel@tonic-gate }
9660Sstevel@tonic-gate } else {
9670Sstevel@tonic-gate struct netconfig *nconf;
9680Sstevel@tonic-gate
9690Sstevel@tonic-gate nconf = getnetconfigent(netid);
9700Sstevel@tonic-gate if (nconf == NULL) {
9710Sstevel@tonic-gate nc_perror("rpcinfo: invalid transport");
9720Sstevel@tonic-gate exit(1);
9730Sstevel@tonic-gate }
9740Sstevel@tonic-gate client = getclnthandle(host, nconf, RPCBVERS4, &targaddr);
9750Sstevel@tonic-gate if (nconf)
9760Sstevel@tonic-gate (void) freenetconfigent(nconf);
9770Sstevel@tonic-gate }
9780Sstevel@tonic-gate if (client == (CLIENT *)NULL) {
9790Sstevel@tonic-gate clnt_pcreateerror("rpcinfo: can't contact rpcbind");
9800Sstevel@tonic-gate exit(1);
9810Sstevel@tonic-gate }
9820Sstevel@tonic-gate minutetimeout.tv_sec = 60;
9830Sstevel@tonic-gate minutetimeout.tv_usec = 0;
9840Sstevel@tonic-gate
9850Sstevel@tonic-gate parms.r_prog = getprognum(argv[1]);
9860Sstevel@tonic-gate parms.r_vers = getvers(argv[2]);
9870Sstevel@tonic-gate parms.r_netid = client->cl_netid;
9880Sstevel@tonic-gate if (targaddr == NULL) {
9890Sstevel@tonic-gate parms.r_addr = nullstring; /* for XDRing */
9900Sstevel@tonic-gate } else {
9910Sstevel@tonic-gate /*
9920Sstevel@tonic-gate * We also send the remote system the address we
9930Sstevel@tonic-gate * used to contact it in case it can help it
9940Sstevel@tonic-gate * connect back with us
9950Sstevel@tonic-gate */
9960Sstevel@tonic-gate struct netconfig *nconf;
9970Sstevel@tonic-gate
9980Sstevel@tonic-gate nconf = getnetconfigent(client->cl_netid);
9990Sstevel@tonic-gate if (nconf != NULL) {
10000Sstevel@tonic-gate parms.r_addr = taddr2uaddr(nconf, targaddr);
10010Sstevel@tonic-gate if (parms.r_addr == NULL)
10020Sstevel@tonic-gate parms.r_addr = nullstring;
10030Sstevel@tonic-gate freenetconfigent(nconf);
10040Sstevel@tonic-gate } else {
10050Sstevel@tonic-gate parms.r_addr = nullstring; /* for XDRing */
10060Sstevel@tonic-gate }
10070Sstevel@tonic-gate free(targaddr->buf);
10080Sstevel@tonic-gate free(targaddr);
10090Sstevel@tonic-gate }
10100Sstevel@tonic-gate parms.r_owner = nullstring;
10110Sstevel@tonic-gate
10120Sstevel@tonic-gate if (CLNT_CALL(client, RPCBPROC_GETADDRLIST, (xdrproc_t)xdr_rpcb,
10130Sstevel@tonic-gate (char *)&parms, (xdrproc_t)xdr_rpcb_entry_list_ptr,
10140Sstevel@tonic-gate (char *)&head, minutetimeout) != RPC_SUCCESS) {
10150Sstevel@tonic-gate clnt_perror(client, "rpcinfo: can't contact rpcbind: ");
10160Sstevel@tonic-gate exit(1);
10170Sstevel@tonic-gate }
10180Sstevel@tonic-gate if (head == NULL) {
1019*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("No remote programs registered.\n");
10200Sstevel@tonic-gate } else {
1021*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(
10220Sstevel@tonic-gate " program vers tp_family/name/class address\t\t service\n");
10230Sstevel@tonic-gate for (; head != NULL; head = head->rpcb_entry_next) {
10240Sstevel@tonic-gate rpcb_entry *re;
10250Sstevel@tonic-gate char buf[128];
10260Sstevel@tonic-gate
10270Sstevel@tonic-gate re = &head->rpcb_entry_map;
1028*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%10ld%3ld ",
10290Sstevel@tonic-gate parms.r_prog, parms.r_vers);
1030*11563SVallish.Vaidyeshwara@Sun.COM (void) snprintf(buf, sizeof (buf), "%s/%s/%s ",
10310Sstevel@tonic-gate re->r_nc_protofmly, re->r_nc_proto,
10320Sstevel@tonic-gate re->r_nc_semantics == NC_TPI_CLTS ? "clts" :
10330Sstevel@tonic-gate re->r_nc_semantics == NC_TPI_COTS ? "cots" :
10340Sstevel@tonic-gate "cots_ord");
1035*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-24s", buf);
1036*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-24s", re->r_maddr);
10370Sstevel@tonic-gate rpc = getrpcbynumber(parms.r_prog);
10380Sstevel@tonic-gate if (rpc)
1039*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %-13s", rpc->r_name);
10400Sstevel@tonic-gate else
1041*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(" %-13s", "-");
1042*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n");
10430Sstevel@tonic-gate }
10440Sstevel@tonic-gate }
10450Sstevel@tonic-gate clnt_destroy(client);
10460Sstevel@tonic-gate }
10470Sstevel@tonic-gate
10480Sstevel@tonic-gate /*
10490Sstevel@tonic-gate * monitor rpcbind
10500Sstevel@tonic-gate */
10510Sstevel@tonic-gate static void
rpcbgetstat(argc,argv)10520Sstevel@tonic-gate rpcbgetstat(argc, argv)
10530Sstevel@tonic-gate int argc;
10540Sstevel@tonic-gate char **argv;
10550Sstevel@tonic-gate {
10560Sstevel@tonic-gate rpcb_stat_byvers inf;
10570Sstevel@tonic-gate struct timeval minutetimeout;
10580Sstevel@tonic-gate register CLIENT *client;
10590Sstevel@tonic-gate char *host;
10600Sstevel@tonic-gate int i, j;
10610Sstevel@tonic-gate rpcbs_addrlist *pa;
10620Sstevel@tonic-gate rpcbs_rmtcalllist *pr;
10630Sstevel@tonic-gate int cnt, flen;
10640Sstevel@tonic-gate struct utsname utsname;
10650Sstevel@tonic-gate #define MAXFIELD 64
10660Sstevel@tonic-gate char fieldbuf[MAXFIELD];
10670Sstevel@tonic-gate #define MAXLINE 256
10680Sstevel@tonic-gate char linebuf[MAXLINE];
1069*11563SVallish.Vaidyeshwara@Sun.COM char *cp, *lp;
10700Sstevel@tonic-gate char *pmaphdr[] = {
10710Sstevel@tonic-gate "NULL", "SET", "UNSET", "GETPORT",
10720Sstevel@tonic-gate "DUMP", "CALLIT"
10730Sstevel@tonic-gate };
10740Sstevel@tonic-gate char *rpcb3hdr[] = {
10750Sstevel@tonic-gate "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME",
10760Sstevel@tonic-gate "U2T", "T2U"
10770Sstevel@tonic-gate };
10780Sstevel@tonic-gate char *rpcb4hdr[] = {
10790Sstevel@tonic-gate "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME",
10800Sstevel@tonic-gate "U2T", "T2U", "VERADDR", "INDRECT", "GETLIST", "GETSTAT"
10810Sstevel@tonic-gate };
10820Sstevel@tonic-gate
10830Sstevel@tonic-gate #define TABSTOP 8
10840Sstevel@tonic-gate
10850Sstevel@tonic-gate if (argc >= 1) {
10860Sstevel@tonic-gate host = argv[0];
10870Sstevel@tonic-gate } else {
1088*11563SVallish.Vaidyeshwara@Sun.COM (void) uname(&utsname);
10890Sstevel@tonic-gate host = utsname.nodename;
10900Sstevel@tonic-gate }
10910Sstevel@tonic-gate if (loopback_netid != NULL) {
10920Sstevel@tonic-gate client = getclnthandle(host, loopback_nconf, RPCBVERS4, NULL);
10930Sstevel@tonic-gate if (client == NULL && rpc_createerr.cf_stat ==
10940Sstevel@tonic-gate RPC_N2AXLATEFAILURE) {
10950Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS4, NULL);
10960Sstevel@tonic-gate }
10970Sstevel@tonic-gate } else {
10980Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS4, NULL);
10990Sstevel@tonic-gate }
11000Sstevel@tonic-gate if (client == (CLIENT *)NULL) {
11010Sstevel@tonic-gate clnt_pcreateerror("rpcinfo: can't contact rpcbind");
11020Sstevel@tonic-gate exit(1);
11030Sstevel@tonic-gate }
11040Sstevel@tonic-gate minutetimeout.tv_sec = 60;
11050Sstevel@tonic-gate minutetimeout.tv_usec = 0;
1106*11563SVallish.Vaidyeshwara@Sun.COM (void) memset((char *)&inf, 0, sizeof (rpcb_stat_byvers));
11070Sstevel@tonic-gate if (CLNT_CALL(client, RPCBPROC_GETSTAT, (xdrproc_t)xdr_void, NULL,
11080Sstevel@tonic-gate (xdrproc_t)xdr_rpcb_stat_byvers, (char *)&inf, minutetimeout)
11090Sstevel@tonic-gate != RPC_SUCCESS) {
11100Sstevel@tonic-gate clnt_perror(client, "rpcinfo: can't contact rpcbind: ");
11110Sstevel@tonic-gate exit(1);
11120Sstevel@tonic-gate }
1113*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("PORTMAP (version 2) statistics\n");
11140Sstevel@tonic-gate lp = linebuf;
11150Sstevel@tonic-gate for (i = 0; i <= rpcb_highproc_2; i++) {
11160Sstevel@tonic-gate fieldbuf[0] = '\0';
11170Sstevel@tonic-gate switch (i) {
11180Sstevel@tonic-gate case PMAPPROC_SET:
1119*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/",
1120*11563SVallish.Vaidyeshwara@Sun.COM inf[RPCBVERS_2_STAT].setinfo);
11210Sstevel@tonic-gate break;
11220Sstevel@tonic-gate case PMAPPROC_UNSET:
1123*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/",
11240Sstevel@tonic-gate inf[RPCBVERS_2_STAT].unsetinfo);
11250Sstevel@tonic-gate break;
11260Sstevel@tonic-gate case PMAPPROC_GETPORT:
11270Sstevel@tonic-gate cnt = 0;
11280Sstevel@tonic-gate for (pa = inf[RPCBVERS_2_STAT].addrinfo; pa;
11290Sstevel@tonic-gate pa = pa->next)
11300Sstevel@tonic-gate cnt += pa->success;
1131*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/", cnt);
11320Sstevel@tonic-gate break;
11330Sstevel@tonic-gate case PMAPPROC_CALLIT:
11340Sstevel@tonic-gate cnt = 0;
11350Sstevel@tonic-gate for (pr = inf[RPCBVERS_2_STAT].rmtinfo; pr;
11360Sstevel@tonic-gate pr = pr->next)
11370Sstevel@tonic-gate cnt += pr->success;
1138*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/", cnt);
11390Sstevel@tonic-gate break;
11400Sstevel@tonic-gate default: break; /* For the remaining ones */
11410Sstevel@tonic-gate }
11420Sstevel@tonic-gate cp = &fieldbuf[0] + strlen(fieldbuf);
1143*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(cp, "%d", inf[RPCBVERS_2_STAT].info[i]);
11440Sstevel@tonic-gate flen = strlen(fieldbuf);
1145*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%s%s", pmaphdr[i],
1146*11563SVallish.Vaidyeshwara@Sun.COM spaces((int)((TABSTOP * (1 + flen / TABSTOP))
1147*11563SVallish.Vaidyeshwara@Sun.COM - strlen(pmaphdr[i]))));
1148*11563SVallish.Vaidyeshwara@Sun.COM (void) snprintf(lp, (MAXLINE - (lp - linebuf)), "%s%s",
1149*11563SVallish.Vaidyeshwara@Sun.COM fieldbuf, spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP))
11500Sstevel@tonic-gate - flen)));
11510Sstevel@tonic-gate lp += (flen + cnt);
11520Sstevel@tonic-gate }
1153*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n%s\n\n", linebuf);
11540Sstevel@tonic-gate
11550Sstevel@tonic-gate if (inf[RPCBVERS_2_STAT].info[PMAPPROC_CALLIT]) {
1156*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("PMAP_RMTCALL call statistics\n");
11570Sstevel@tonic-gate print_rmtcallstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]);
1158*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n");
11590Sstevel@tonic-gate }
11600Sstevel@tonic-gate
11610Sstevel@tonic-gate if (inf[RPCBVERS_2_STAT].info[PMAPPROC_GETPORT]) {
1162*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("PMAP_GETPORT call statistics\n");
11630Sstevel@tonic-gate print_getaddrstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]);
1164*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n");
11650Sstevel@tonic-gate }
11660Sstevel@tonic-gate
1167*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("RPCBIND (version 3) statistics\n");
11680Sstevel@tonic-gate lp = linebuf;
11690Sstevel@tonic-gate for (i = 0; i <= rpcb_highproc_3; i++) {
11700Sstevel@tonic-gate fieldbuf[0] = '\0';
11710Sstevel@tonic-gate switch (i) {
11720Sstevel@tonic-gate case RPCBPROC_SET:
1173*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/",
1174*11563SVallish.Vaidyeshwara@Sun.COM inf[RPCBVERS_3_STAT].setinfo);
11750Sstevel@tonic-gate break;
11760Sstevel@tonic-gate case RPCBPROC_UNSET:
1177*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/",
11780Sstevel@tonic-gate inf[RPCBVERS_3_STAT].unsetinfo);
11790Sstevel@tonic-gate break;
11800Sstevel@tonic-gate case RPCBPROC_GETADDR:
11810Sstevel@tonic-gate cnt = 0;
11820Sstevel@tonic-gate for (pa = inf[RPCBVERS_3_STAT].addrinfo; pa;
11830Sstevel@tonic-gate pa = pa->next)
11840Sstevel@tonic-gate cnt += pa->success;
1185*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/", cnt);
11860Sstevel@tonic-gate break;
11870Sstevel@tonic-gate case RPCBPROC_CALLIT:
11880Sstevel@tonic-gate cnt = 0;
11890Sstevel@tonic-gate for (pr = inf[RPCBVERS_3_STAT].rmtinfo; pr;
11900Sstevel@tonic-gate pr = pr->next)
11910Sstevel@tonic-gate cnt += pr->success;
1192*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/", cnt);
11930Sstevel@tonic-gate break;
11940Sstevel@tonic-gate default: break; /* For the remaining ones */
11950Sstevel@tonic-gate }
11960Sstevel@tonic-gate cp = &fieldbuf[0] + strlen(fieldbuf);
1197*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(cp, "%d", inf[RPCBVERS_3_STAT].info[i]);
11980Sstevel@tonic-gate flen = strlen(fieldbuf);
1199*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%s%s", rpcb3hdr[i],
1200*11563SVallish.Vaidyeshwara@Sun.COM spaces((int)((TABSTOP * (1 + flen / TABSTOP))
1201*11563SVallish.Vaidyeshwara@Sun.COM - strlen(rpcb3hdr[i]))));
1202*11563SVallish.Vaidyeshwara@Sun.COM (void) snprintf(lp, (MAXLINE - (lp - linebuf)), "%s%s",
1203*11563SVallish.Vaidyeshwara@Sun.COM fieldbuf, spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP))
12040Sstevel@tonic-gate - flen)));
12050Sstevel@tonic-gate lp += (flen + cnt);
12060Sstevel@tonic-gate }
1207*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n%s\n\n", linebuf);
12080Sstevel@tonic-gate
12090Sstevel@tonic-gate if (inf[RPCBVERS_3_STAT].info[RPCBPROC_CALLIT]) {
1210*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("RPCB_RMTCALL (version 3) call statistics\n");
12110Sstevel@tonic-gate print_rmtcallstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]);
1212*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n");
12130Sstevel@tonic-gate }
12140Sstevel@tonic-gate
12150Sstevel@tonic-gate if (inf[RPCBVERS_3_STAT].info[RPCBPROC_GETADDR]) {
1216*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("RPCB_GETADDR (version 3) call statistics\n");
12170Sstevel@tonic-gate print_getaddrstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]);
1218*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n");
12190Sstevel@tonic-gate }
12200Sstevel@tonic-gate
1221*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("RPCBIND (version 4) statistics\n");
12220Sstevel@tonic-gate
12230Sstevel@tonic-gate for (j = 0; j <= 9; j += 9) { /* Just two iterations for printing */
12240Sstevel@tonic-gate lp = linebuf;
12250Sstevel@tonic-gate for (i = j; i <= MAX(8, rpcb_highproc_4 - 9 + j); i++) {
12260Sstevel@tonic-gate fieldbuf[0] = '\0';
12270Sstevel@tonic-gate switch (i) {
12280Sstevel@tonic-gate case RPCBPROC_SET:
1229*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/",
12300Sstevel@tonic-gate inf[RPCBVERS_4_STAT].setinfo);
12310Sstevel@tonic-gate break;
12320Sstevel@tonic-gate case RPCBPROC_UNSET:
1233*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/",
12340Sstevel@tonic-gate inf[RPCBVERS_4_STAT].unsetinfo);
12350Sstevel@tonic-gate break;
12360Sstevel@tonic-gate case RPCBPROC_GETADDR:
12370Sstevel@tonic-gate cnt = 0;
12380Sstevel@tonic-gate for (pa = inf[RPCBVERS_4_STAT].addrinfo; pa;
12390Sstevel@tonic-gate pa = pa->next)
12400Sstevel@tonic-gate cnt += pa->success;
1241*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/", cnt);
12420Sstevel@tonic-gate break;
12430Sstevel@tonic-gate case RPCBPROC_CALLIT:
12440Sstevel@tonic-gate cnt = 0;
12450Sstevel@tonic-gate for (pr = inf[RPCBVERS_4_STAT].rmtinfo; pr;
12460Sstevel@tonic-gate pr = pr->next)
12470Sstevel@tonic-gate cnt += pr->success;
1248*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(fieldbuf, "%d/", cnt);
12490Sstevel@tonic-gate break;
12500Sstevel@tonic-gate default: break; /* For the remaining ones */
12510Sstevel@tonic-gate }
12520Sstevel@tonic-gate cp = &fieldbuf[0] + strlen(fieldbuf);
12530Sstevel@tonic-gate /*
12540Sstevel@tonic-gate * XXX: We also add RPCBPROC_GETADDRLIST queries to
12550Sstevel@tonic-gate * RPCB_GETADDR because rpcbind includes the
12560Sstevel@tonic-gate * RPCB_GETADDRLIST successes in RPCB_GETADDR.
12570Sstevel@tonic-gate */
12580Sstevel@tonic-gate if (i != RPCBPROC_GETADDR)
1259*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(cp, "%d",
1260*11563SVallish.Vaidyeshwara@Sun.COM inf[RPCBVERS_4_STAT].info[i]);
12610Sstevel@tonic-gate else
1262*11563SVallish.Vaidyeshwara@Sun.COM (void) sprintf(cp, "%d",
1263*11563SVallish.Vaidyeshwara@Sun.COM inf[RPCBVERS_4_STAT].info[i] +
12640Sstevel@tonic-gate inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDRLIST]);
12650Sstevel@tonic-gate flen = strlen(fieldbuf);
1266*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%s%s", rpcb4hdr[i],
1267*11563SVallish.Vaidyeshwara@Sun.COM spaces((int)((TABSTOP * (1 + flen / TABSTOP))
1268*11563SVallish.Vaidyeshwara@Sun.COM - strlen(rpcb4hdr[i]))));
1269*11563SVallish.Vaidyeshwara@Sun.COM (void) snprintf(lp, MAXLINE - (lp - linebuf), "%s%s",
1270*11563SVallish.Vaidyeshwara@Sun.COM fieldbuf, spaces(cnt =
1271*11563SVallish.Vaidyeshwara@Sun.COM ((TABSTOP * (1 + flen / TABSTOP)) - flen)));
12720Sstevel@tonic-gate lp += (flen + cnt);
12730Sstevel@tonic-gate }
1274*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n%s\n", linebuf);
12750Sstevel@tonic-gate }
12760Sstevel@tonic-gate
12770Sstevel@tonic-gate if (inf[RPCBVERS_4_STAT].info[RPCBPROC_CALLIT] ||
12780Sstevel@tonic-gate inf[RPCBVERS_4_STAT].info[RPCBPROC_INDIRECT]) {
1279*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n");
1280*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("RPCB_RMTCALL (version 4) call statistics\n");
12810Sstevel@tonic-gate print_rmtcallstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]);
12820Sstevel@tonic-gate }
12830Sstevel@tonic-gate
12840Sstevel@tonic-gate if (inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDR]) {
1285*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("\n");
1286*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("RPCB_GETADDR (version 4) call statistics\n");
12870Sstevel@tonic-gate print_getaddrstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]);
12880Sstevel@tonic-gate }
12890Sstevel@tonic-gate clnt_destroy(client);
12900Sstevel@tonic-gate }
12910Sstevel@tonic-gate
12920Sstevel@tonic-gate /*
12930Sstevel@tonic-gate * Delete registeration for this (prog, vers, netid)
12940Sstevel@tonic-gate */
12950Sstevel@tonic-gate static void
deletereg(netid,argc,argv)12960Sstevel@tonic-gate deletereg(netid, argc, argv)
12970Sstevel@tonic-gate char *netid;
12980Sstevel@tonic-gate int argc;
12990Sstevel@tonic-gate char **argv;
13000Sstevel@tonic-gate {
13010Sstevel@tonic-gate struct netconfig *nconf = NULL;
13020Sstevel@tonic-gate
13030Sstevel@tonic-gate if (argc != 2) {
13040Sstevel@tonic-gate usage();
13050Sstevel@tonic-gate exit(1);
13060Sstevel@tonic-gate }
13070Sstevel@tonic-gate if (netid) {
13080Sstevel@tonic-gate nconf = getnetconfigent(netid);
13090Sstevel@tonic-gate if (nconf == NULL) {
1310*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
1311*11563SVallish.Vaidyeshwara@Sun.COM "rpcinfo: netid %s not supported\n", netid);
13120Sstevel@tonic-gate exit(1);
13130Sstevel@tonic-gate }
13140Sstevel@tonic-gate }
13150Sstevel@tonic-gate if ((rpcb_unset(getprognum(argv[0]), getvers(argv[1]), nconf)) == 0) {
1316*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
13170Sstevel@tonic-gate "rpcinfo: Could not delete registration for prog %s version %s\n",
13180Sstevel@tonic-gate argv[0], argv[1]);
13190Sstevel@tonic-gate exit(1);
13200Sstevel@tonic-gate }
13210Sstevel@tonic-gate }
13220Sstevel@tonic-gate
13230Sstevel@tonic-gate /*
13240Sstevel@tonic-gate * Create and return a handle for the given nconf.
13250Sstevel@tonic-gate * Exit if cannot create handle.
13260Sstevel@tonic-gate */
13270Sstevel@tonic-gate static CLIENT *
clnt_addr_create(address,nconf,prog,vers)13280Sstevel@tonic-gate clnt_addr_create(address, nconf, prog, vers)
13290Sstevel@tonic-gate char *address;
13300Sstevel@tonic-gate struct netconfig *nconf;
13310Sstevel@tonic-gate ulong_t prog;
13320Sstevel@tonic-gate ulong_t vers;
13330Sstevel@tonic-gate {
13340Sstevel@tonic-gate CLIENT *client;
13350Sstevel@tonic-gate static struct netbuf *nbuf;
13360Sstevel@tonic-gate static int fd = RPC_ANYFD;
13370Sstevel@tonic-gate struct t_info tinfo;
13380Sstevel@tonic-gate
13390Sstevel@tonic-gate if (fd == RPC_ANYFD) {
13400Sstevel@tonic-gate if ((fd = t_open(nconf->nc_device, O_RDWR, &tinfo)) == -1) {
13410Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_TLIERROR;
13420Sstevel@tonic-gate rpc_createerr.cf_error.re_terrno = t_errno;
13430Sstevel@tonic-gate clnt_pcreateerror("rpcinfo");
13440Sstevel@tonic-gate exit(1);
13450Sstevel@tonic-gate }
13460Sstevel@tonic-gate /* Convert the uaddr to taddr */
13470Sstevel@tonic-gate nbuf = uaddr2taddr(nconf, address);
13480Sstevel@tonic-gate if (nbuf == NULL) {
13490Sstevel@tonic-gate netdir_perror("rpcinfo");
13500Sstevel@tonic-gate exit(1);
13510Sstevel@tonic-gate }
13520Sstevel@tonic-gate }
13530Sstevel@tonic-gate client = clnt_tli_create(fd, nconf, nbuf, prog, vers, 0, 0);
13540Sstevel@tonic-gate if (client == (CLIENT *)NULL) {
13550Sstevel@tonic-gate clnt_pcreateerror("rpcinfo");
13560Sstevel@tonic-gate exit(1);
13570Sstevel@tonic-gate }
13580Sstevel@tonic-gate return (client);
13590Sstevel@tonic-gate }
13600Sstevel@tonic-gate
13610Sstevel@tonic-gate /*
13620Sstevel@tonic-gate * If the version number is given, ping that (prog, vers); else try to find
13630Sstevel@tonic-gate * the version numbers supported for that prog and ping all the versions.
13640Sstevel@tonic-gate * Remote rpcbind is not contacted for this service. The requests are
13650Sstevel@tonic-gate * sent directly to the services themselves.
13660Sstevel@tonic-gate */
13670Sstevel@tonic-gate static void
addrping(address,netid,argc,argv)13680Sstevel@tonic-gate addrping(address, netid, argc, argv)
13690Sstevel@tonic-gate char *address;
13700Sstevel@tonic-gate char *netid;
13710Sstevel@tonic-gate int argc;
13720Sstevel@tonic-gate char **argv;
13730Sstevel@tonic-gate {
13740Sstevel@tonic-gate CLIENT *client;
13750Sstevel@tonic-gate struct timeval to;
13760Sstevel@tonic-gate enum clnt_stat rpc_stat;
13770Sstevel@tonic-gate ulong_t prognum, versnum, minvers, maxvers;
13780Sstevel@tonic-gate struct rpc_err rpcerr;
13790Sstevel@tonic-gate int failure = 0;
13800Sstevel@tonic-gate struct netconfig *nconf;
13810Sstevel@tonic-gate int fd;
13820Sstevel@tonic-gate
13830Sstevel@tonic-gate if (argc < 1 || argc > 2 || (netid == NULL)) {
13840Sstevel@tonic-gate usage();
13850Sstevel@tonic-gate exit(1);
13860Sstevel@tonic-gate }
13870Sstevel@tonic-gate nconf = getnetconfigent(netid);
13880Sstevel@tonic-gate if (nconf == (struct netconfig *)NULL) {
1389*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr, "rpcinfo: Could not find %s\n", netid);
13900Sstevel@tonic-gate exit(1);
13910Sstevel@tonic-gate }
13920Sstevel@tonic-gate to.tv_sec = 10;
13930Sstevel@tonic-gate to.tv_usec = 0;
13940Sstevel@tonic-gate prognum = getprognum(argv[0]);
13950Sstevel@tonic-gate if (argc == 1) { /* Version number not known */
13960Sstevel@tonic-gate /*
13970Sstevel@tonic-gate * A call to version 0 should fail with a program/version
13980Sstevel@tonic-gate * mismatch, and give us the range of versions supported.
13990Sstevel@tonic-gate */
14000Sstevel@tonic-gate versnum = MIN_VERS;
14010Sstevel@tonic-gate } else {
14020Sstevel@tonic-gate versnum = getvers(argv[1]);
14030Sstevel@tonic-gate }
14040Sstevel@tonic-gate client = clnt_addr_create(address, nconf, prognum, versnum);
14050Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void,
14060Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void,
14070Sstevel@tonic-gate (char *)NULL, to);
14080Sstevel@tonic-gate if (argc == 2) {
14090Sstevel@tonic-gate /* Version number was known */
14100Sstevel@tonic-gate if (pstatus(client, prognum, versnum) < 0)
14110Sstevel@tonic-gate failure = 1;
14120Sstevel@tonic-gate (void) CLNT_DESTROY(client);
14130Sstevel@tonic-gate if (failure)
14140Sstevel@tonic-gate exit(1);
14150Sstevel@tonic-gate return;
14160Sstevel@tonic-gate }
14170Sstevel@tonic-gate /* Version number not known */
14180Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL);
14190Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLGET_FD, (char *)&fd);
14200Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) {
14210Sstevel@tonic-gate clnt_geterr(client, &rpcerr);
14220Sstevel@tonic-gate minvers = rpcerr.re_vers.low;
14230Sstevel@tonic-gate maxvers = rpcerr.re_vers.high;
14240Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) {
14250Sstevel@tonic-gate /*
14260Sstevel@tonic-gate * Oh dear, it DOES support version 0.
14270Sstevel@tonic-gate * Let's try version MAX_VERS.
14280Sstevel@tonic-gate */
14290Sstevel@tonic-gate (void) CLNT_DESTROY(client);
14300Sstevel@tonic-gate client = clnt_addr_create(address, nconf, prognum, MAX_VERS);
14310Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void,
14320Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void,
14330Sstevel@tonic-gate (char *)NULL, to);
14340Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) {
14350Sstevel@tonic-gate clnt_geterr(client, &rpcerr);
14360Sstevel@tonic-gate minvers = rpcerr.re_vers.low;
14370Sstevel@tonic-gate maxvers = rpcerr.re_vers.high;
14380Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) {
14390Sstevel@tonic-gate /*
14400Sstevel@tonic-gate * It also supports version MAX_VERS.
14410Sstevel@tonic-gate * Looks like we have a wise guy.
14420Sstevel@tonic-gate * OK, we give them information on all
14430Sstevel@tonic-gate * 4 billion versions they support...
14440Sstevel@tonic-gate */
14450Sstevel@tonic-gate minvers = 0;
14460Sstevel@tonic-gate maxvers = MAX_VERS;
14470Sstevel@tonic-gate } else {
14480Sstevel@tonic-gate (void) pstatus(client, prognum, MAX_VERS);
14490Sstevel@tonic-gate exit(1);
14500Sstevel@tonic-gate }
14510Sstevel@tonic-gate } else {
14520Sstevel@tonic-gate (void) pstatus(client, prognum, (ulong_t)0);
14530Sstevel@tonic-gate exit(1);
14540Sstevel@tonic-gate }
14550Sstevel@tonic-gate (void) CLNT_DESTROY(client);
14560Sstevel@tonic-gate for (versnum = minvers; versnum <= maxvers; versnum++) {
14570Sstevel@tonic-gate client = clnt_addr_create(address, nconf, prognum, versnum);
14580Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void,
14590Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void,
14600Sstevel@tonic-gate (char *)NULL, to);
14610Sstevel@tonic-gate if (pstatus(client, prognum, versnum) < 0)
14620Sstevel@tonic-gate failure = 1;
14630Sstevel@tonic-gate (void) CLNT_DESTROY(client);
14640Sstevel@tonic-gate }
14650Sstevel@tonic-gate (void) t_close(fd);
14660Sstevel@tonic-gate if (failure)
14670Sstevel@tonic-gate exit(1);
14680Sstevel@tonic-gate }
14690Sstevel@tonic-gate
14700Sstevel@tonic-gate /*
14710Sstevel@tonic-gate * If the version number is given, ping that (prog, vers); else try to find
14720Sstevel@tonic-gate * the version numbers supported for that prog and ping all the versions.
14730Sstevel@tonic-gate * Remote rpcbind is *contacted* for this service. The requests are
14740Sstevel@tonic-gate * then sent directly to the services themselves.
14750Sstevel@tonic-gate */
14760Sstevel@tonic-gate static void
progping(netid,argc,argv)14770Sstevel@tonic-gate progping(netid, argc, argv)
14780Sstevel@tonic-gate char *netid;
14790Sstevel@tonic-gate int argc;
14800Sstevel@tonic-gate char **argv;
14810Sstevel@tonic-gate {
14820Sstevel@tonic-gate CLIENT *client;
14830Sstevel@tonic-gate struct timeval to;
14840Sstevel@tonic-gate enum clnt_stat rpc_stat;
14850Sstevel@tonic-gate ulong_t prognum, versnum, minvers, maxvers;
14860Sstevel@tonic-gate struct rpc_err rpcerr;
14870Sstevel@tonic-gate int failure = 0;
14880Sstevel@tonic-gate struct netconfig *nconf;
14890Sstevel@tonic-gate
14900Sstevel@tonic-gate if (argc < 2 || argc > 3 || (netid == NULL)) {
14910Sstevel@tonic-gate usage();
14920Sstevel@tonic-gate exit(1);
14930Sstevel@tonic-gate }
14940Sstevel@tonic-gate prognum = getprognum(argv[1]);
14950Sstevel@tonic-gate if (argc == 2) { /* Version number not known */
14960Sstevel@tonic-gate /*
14970Sstevel@tonic-gate * A call to version 0 should fail with a program/version
14980Sstevel@tonic-gate * mismatch, and give us the range of versions supported.
14990Sstevel@tonic-gate */
15000Sstevel@tonic-gate versnum = MIN_VERS;
15010Sstevel@tonic-gate } else {
15020Sstevel@tonic-gate versnum = getvers(argv[2]);
15030Sstevel@tonic-gate }
15040Sstevel@tonic-gate if (netid) {
15050Sstevel@tonic-gate nconf = getnetconfigent(netid);
15060Sstevel@tonic-gate if (nconf == (struct netconfig *)NULL) {
1507*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
1508*11563SVallish.Vaidyeshwara@Sun.COM "rpcinfo: Could not find %s\n", netid);
15090Sstevel@tonic-gate exit(1);
15100Sstevel@tonic-gate }
15110Sstevel@tonic-gate client = clnt_tp_create(argv[0], prognum, versnum, nconf);
15120Sstevel@tonic-gate } else {
15130Sstevel@tonic-gate client = clnt_create(argv[0], prognum, versnum, "NETPATH");
15140Sstevel@tonic-gate }
15150Sstevel@tonic-gate if (client == (CLIENT *)NULL) {
15160Sstevel@tonic-gate clnt_pcreateerror("rpcinfo");
15170Sstevel@tonic-gate exit(1);
15180Sstevel@tonic-gate }
15190Sstevel@tonic-gate to.tv_sec = 10;
15200Sstevel@tonic-gate to.tv_usec = 0;
15210Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void,
15220Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void,
15230Sstevel@tonic-gate (char *)NULL, to);
15240Sstevel@tonic-gate if (argc == 3) {
15250Sstevel@tonic-gate /* Version number was known */
15260Sstevel@tonic-gate if (pstatus(client, prognum, versnum) < 0)
15270Sstevel@tonic-gate failure = 1;
15280Sstevel@tonic-gate (void) CLNT_DESTROY(client);
15290Sstevel@tonic-gate if (failure)
15300Sstevel@tonic-gate exit(1);
15310Sstevel@tonic-gate return;
15320Sstevel@tonic-gate }
15330Sstevel@tonic-gate /* Version number not known */
15340Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) {
15350Sstevel@tonic-gate clnt_geterr(client, &rpcerr);
15360Sstevel@tonic-gate minvers = rpcerr.re_vers.low;
15370Sstevel@tonic-gate maxvers = rpcerr.re_vers.high;
15380Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) {
15390Sstevel@tonic-gate /*
15400Sstevel@tonic-gate * Oh dear, it DOES support version 0.
15410Sstevel@tonic-gate * Let's try version MAX_VERS.
15420Sstevel@tonic-gate */
15430Sstevel@tonic-gate versnum = MAX_VERS;
15440Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum);
15450Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC,
15460Sstevel@tonic-gate (xdrproc_t)xdr_void, (char *)NULL,
15470Sstevel@tonic-gate (xdrproc_t)xdr_void, (char *)NULL, to);
15480Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) {
15490Sstevel@tonic-gate clnt_geterr(client, &rpcerr);
15500Sstevel@tonic-gate minvers = rpcerr.re_vers.low;
15510Sstevel@tonic-gate maxvers = rpcerr.re_vers.high;
15520Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) {
15530Sstevel@tonic-gate /*
15540Sstevel@tonic-gate * It also supports version MAX_VERS.
15550Sstevel@tonic-gate * Looks like we have a wise guy.
15560Sstevel@tonic-gate * OK, we give them information on all
15570Sstevel@tonic-gate * 4 billion versions they support...
15580Sstevel@tonic-gate */
15590Sstevel@tonic-gate minvers = 0;
15600Sstevel@tonic-gate maxvers = MAX_VERS;
15610Sstevel@tonic-gate } else {
15620Sstevel@tonic-gate (void) pstatus(client, prognum, MAX_VERS);
15630Sstevel@tonic-gate exit(1);
15640Sstevel@tonic-gate }
15650Sstevel@tonic-gate } else {
15660Sstevel@tonic-gate (void) pstatus(client, prognum, (ulong_t)0);
15670Sstevel@tonic-gate exit(1);
15680Sstevel@tonic-gate }
15690Sstevel@tonic-gate for (versnum = minvers; versnum <= maxvers; versnum++) {
15700Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum);
15710Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void,
15720Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void,
15730Sstevel@tonic-gate (char *)NULL, to);
15740Sstevel@tonic-gate if (pstatus(client, prognum, versnum) < 0)
15750Sstevel@tonic-gate failure = 1;
15760Sstevel@tonic-gate }
15770Sstevel@tonic-gate (void) CLNT_DESTROY(client);
15780Sstevel@tonic-gate if (failure)
15790Sstevel@tonic-gate exit(1);
15800Sstevel@tonic-gate }
15810Sstevel@tonic-gate
15820Sstevel@tonic-gate static void
usage()15830Sstevel@tonic-gate usage()
15840Sstevel@tonic-gate {
1585*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr, "Usage: rpcinfo [-m | -s] [host]\n");
15860Sstevel@tonic-gate #ifdef PORTMAP
1587*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr, " rpcinfo -p [host]\n");
15880Sstevel@tonic-gate #endif
1589*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
1590*11563SVallish.Vaidyeshwara@Sun.COM " rpcinfo -T netid host prognum [versnum]\n");
1591*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr, " rpcinfo -l host prognum versnum\n");
15920Sstevel@tonic-gate #ifdef PORTMAP
1593*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
15940Sstevel@tonic-gate " rpcinfo [-n portnum] -u | -t host prognum [versnum]\n");
15950Sstevel@tonic-gate #endif
1596*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
15970Sstevel@tonic-gate " rpcinfo -a serv_address -T netid prognum [version]\n");
1598*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr, " rpcinfo -b prognum versnum\n");
1599*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
1600*11563SVallish.Vaidyeshwara@Sun.COM " rpcinfo -d [-T netid] prognum versnum\n");
16010Sstevel@tonic-gate }
16020Sstevel@tonic-gate
16030Sstevel@tonic-gate static ulong_t
getprognum(arg)16040Sstevel@tonic-gate getprognum (arg)
16050Sstevel@tonic-gate char *arg;
16060Sstevel@tonic-gate {
16070Sstevel@tonic-gate char *strptr;
16080Sstevel@tonic-gate register struct rpcent *rpc;
16090Sstevel@tonic-gate register ulong_t prognum;
16100Sstevel@tonic-gate char *tptr = arg;
16110Sstevel@tonic-gate
16120Sstevel@tonic-gate while (*tptr && isdigit(*tptr++));
16130Sstevel@tonic-gate if (*tptr || isalpha(*(tptr - 1))) {
16140Sstevel@tonic-gate rpc = getrpcbyname(arg);
16150Sstevel@tonic-gate if (rpc == NULL) {
1616*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
1617*11563SVallish.Vaidyeshwara@Sun.COM "rpcinfo: %s is unknown service\n", arg);
16180Sstevel@tonic-gate exit(1);
16190Sstevel@tonic-gate }
16200Sstevel@tonic-gate prognum = rpc->r_number;
16210Sstevel@tonic-gate } else {
16220Sstevel@tonic-gate prognum = strtol(arg, &strptr, 10);
16230Sstevel@tonic-gate if (strptr == arg || *strptr != '\0') {
1624*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
16250Sstevel@tonic-gate "rpcinfo: %s is illegal program number\n", arg);
16260Sstevel@tonic-gate exit(1);
16270Sstevel@tonic-gate }
16280Sstevel@tonic-gate }
16290Sstevel@tonic-gate return (prognum);
16300Sstevel@tonic-gate }
16310Sstevel@tonic-gate
16320Sstevel@tonic-gate static ulong_t
getvers(arg)16330Sstevel@tonic-gate getvers(arg)
16340Sstevel@tonic-gate char *arg;
16350Sstevel@tonic-gate {
16360Sstevel@tonic-gate char *strptr;
16370Sstevel@tonic-gate register ulong_t vers;
16380Sstevel@tonic-gate
16390Sstevel@tonic-gate vers = (int)strtol(arg, &strptr, 10);
16400Sstevel@tonic-gate if (strptr == arg || *strptr != '\0') {
1641*11563SVallish.Vaidyeshwara@Sun.COM (void) fprintf(stderr,
1642*11563SVallish.Vaidyeshwara@Sun.COM "rpcinfo: %s is illegal version number\n", arg);
16430Sstevel@tonic-gate exit(1);
16440Sstevel@tonic-gate }
16450Sstevel@tonic-gate return (vers);
16460Sstevel@tonic-gate }
16470Sstevel@tonic-gate
16480Sstevel@tonic-gate /*
16490Sstevel@tonic-gate * This routine should take a pointer to an "rpc_err" structure, rather than
16500Sstevel@tonic-gate * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
16510Sstevel@tonic-gate * a CLIENT structure rather than a pointer to an "rpc_err" structure.
16520Sstevel@tonic-gate * As such, we have to keep the CLIENT structure around in order to print
16530Sstevel@tonic-gate * a good error message.
16540Sstevel@tonic-gate */
16550Sstevel@tonic-gate static int
pstatus(client,prog,vers)16560Sstevel@tonic-gate pstatus(client, prog, vers)
16570Sstevel@tonic-gate register CLIENT *client;
16580Sstevel@tonic-gate ulong_t prog;
16590Sstevel@tonic-gate ulong_t vers;
16600Sstevel@tonic-gate {
16610Sstevel@tonic-gate struct rpc_err rpcerr;
16620Sstevel@tonic-gate
16630Sstevel@tonic-gate clnt_geterr(client, &rpcerr);
16640Sstevel@tonic-gate if (rpcerr.re_status != RPC_SUCCESS) {
16650Sstevel@tonic-gate clnt_perror(client, "rpcinfo");
1666*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("program %lu version %lu is not available\n",
16670Sstevel@tonic-gate prog, vers);
16680Sstevel@tonic-gate return (-1);
16690Sstevel@tonic-gate } else {
1670*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("program %lu version %lu ready and waiting\n",
16710Sstevel@tonic-gate prog, vers);
16720Sstevel@tonic-gate return (0);
16730Sstevel@tonic-gate }
16740Sstevel@tonic-gate }
16750Sstevel@tonic-gate
16760Sstevel@tonic-gate static CLIENT *
clnt_rpcbind_create(host,rpcbversnum,targaddr)16770Sstevel@tonic-gate clnt_rpcbind_create(host, rpcbversnum, targaddr)
16780Sstevel@tonic-gate char *host;
16790Sstevel@tonic-gate ulong_t rpcbversnum;
16800Sstevel@tonic-gate struct netbuf **targaddr;
16810Sstevel@tonic-gate {
16820Sstevel@tonic-gate static char *tlist[3] = {
16830Sstevel@tonic-gate "circuit_n", "circuit_v", "datagram_v"
16840Sstevel@tonic-gate };
16850Sstevel@tonic-gate int i;
16860Sstevel@tonic-gate struct netconfig *nconf;
16870Sstevel@tonic-gate CLIENT *clnt = NULL;
16880Sstevel@tonic-gate void *handle;
16890Sstevel@tonic-gate
16900Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_SUCCESS;
16910Sstevel@tonic-gate for (i = 0; i < 3; i++) {
16920Sstevel@tonic-gate if ((handle = __rpc_setconf(tlist[i])) == NULL)
16930Sstevel@tonic-gate continue;
16940Sstevel@tonic-gate while (clnt == (CLIENT *)NULL) {
16950Sstevel@tonic-gate if ((nconf = __rpc_getconf(handle)) == NULL) {
16960Sstevel@tonic-gate if (rpc_createerr.cf_stat == RPC_SUCCESS)
16970Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
16980Sstevel@tonic-gate break;
16990Sstevel@tonic-gate }
17000Sstevel@tonic-gate clnt = getclnthandle(host, nconf, rpcbversnum,
17010Sstevel@tonic-gate targaddr);
17020Sstevel@tonic-gate }
17030Sstevel@tonic-gate if (clnt)
17040Sstevel@tonic-gate break;
17050Sstevel@tonic-gate __rpc_endconf(handle);
17060Sstevel@tonic-gate }
17070Sstevel@tonic-gate return (clnt);
17080Sstevel@tonic-gate }
17090Sstevel@tonic-gate
17100Sstevel@tonic-gate static CLIENT*
getclnthandle(host,nconf,rpcbversnum,targaddr)17110Sstevel@tonic-gate getclnthandle(host, nconf, rpcbversnum, targaddr)
17120Sstevel@tonic-gate char *host;
17130Sstevel@tonic-gate struct netconfig *nconf;
17140Sstevel@tonic-gate ulong_t rpcbversnum;
17150Sstevel@tonic-gate struct netbuf **targaddr;
17160Sstevel@tonic-gate {
17170Sstevel@tonic-gate struct netbuf *addr;
17180Sstevel@tonic-gate struct nd_addrlist *nas;
17190Sstevel@tonic-gate struct nd_hostserv rpcbind_hs;
17200Sstevel@tonic-gate CLIENT *client = NULL;
17210Sstevel@tonic-gate
17220Sstevel@tonic-gate /* Get the address of the rpcbind */
17230Sstevel@tonic-gate rpcbind_hs.h_host = host;
17240Sstevel@tonic-gate rpcbind_hs.h_serv = "rpcbind";
17250Sstevel@tonic-gate if (netdir_getbyname(nconf, &rpcbind_hs, &nas)) {
17260Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE;
17270Sstevel@tonic-gate return (NULL);
17280Sstevel@tonic-gate }
17290Sstevel@tonic-gate addr = nas->n_addrs;
17300Sstevel@tonic-gate client = clnt_tli_create(RPC_ANYFD, nconf, addr, RPCBPROG,
17310Sstevel@tonic-gate rpcbversnum, 0, 0);
17320Sstevel@tonic-gate if (client) {
17330Sstevel@tonic-gate if (targaddr != NULL) {
17340Sstevel@tonic-gate *targaddr =
17350Sstevel@tonic-gate (struct netbuf *)malloc(sizeof (struct netbuf));
17360Sstevel@tonic-gate if (*targaddr != NULL) {
17370Sstevel@tonic-gate (*targaddr)->maxlen = addr->maxlen;
17380Sstevel@tonic-gate (*targaddr)->len = addr->len;
17390Sstevel@tonic-gate (*targaddr)->buf = (char *)malloc(addr->len);
17400Sstevel@tonic-gate if ((*targaddr)->buf != NULL) {
1741*11563SVallish.Vaidyeshwara@Sun.COM (void) memcpy((*targaddr)->buf,
1742*11563SVallish.Vaidyeshwara@Sun.COM addr->buf, addr->len);
17430Sstevel@tonic-gate }
17440Sstevel@tonic-gate }
17450Sstevel@tonic-gate }
17460Sstevel@tonic-gate } else {
17470Sstevel@tonic-gate if (rpc_createerr.cf_stat == RPC_TLIERROR) {
17480Sstevel@tonic-gate /*
17490Sstevel@tonic-gate * Assume that the other system is dead; this is a
17500Sstevel@tonic-gate * better error to display to the user.
17510Sstevel@tonic-gate */
17520Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_RPCBFAILURE;
17530Sstevel@tonic-gate rpc_createerr.cf_error.re_status = RPC_FAILED;
17540Sstevel@tonic-gate }
17550Sstevel@tonic-gate }
17560Sstevel@tonic-gate netdir_free((char *)nas, ND_ADDRLIST);
17570Sstevel@tonic-gate return (client);
17580Sstevel@tonic-gate }
17590Sstevel@tonic-gate
17600Sstevel@tonic-gate static void
print_rmtcallstat(rtype,infp)17610Sstevel@tonic-gate print_rmtcallstat(rtype, infp)
17620Sstevel@tonic-gate int rtype;
17630Sstevel@tonic-gate rpcb_stat *infp;
17640Sstevel@tonic-gate {
17650Sstevel@tonic-gate register rpcbs_rmtcalllist_ptr pr;
17660Sstevel@tonic-gate struct rpcent *rpc;
17670Sstevel@tonic-gate
17680Sstevel@tonic-gate if (rtype == RPCBVERS_4_STAT)
1769*11563SVallish.Vaidyeshwara@Sun.COM (void) printf(
17700Sstevel@tonic-gate "prog\t\tvers\tproc\tnetid\tindirect success failure\n");
17710Sstevel@tonic-gate else
1772*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("prog\t\tvers\tproc\tnetid\tsuccess\tfailure\n");
17730Sstevel@tonic-gate for (pr = infp->rmtinfo; pr; pr = pr->next) {
17740Sstevel@tonic-gate rpc = getrpcbynumber(pr->prog);
17750Sstevel@tonic-gate if (rpc)
1776*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-16s", rpc->r_name);
17770Sstevel@tonic-gate else
1778*11563SVallish.Vaidyeshwara@Sun.COM #if defined(_LP64) || defined(_I32LPx)
1779*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-16u", pr->prog);
1780*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%u\t%u\t%-7s ",
1781*11563SVallish.Vaidyeshwara@Sun.COM #else
1782*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-16lu", pr->prog);
1783*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%lu\t%lu\t%-7s ",
1784*11563SVallish.Vaidyeshwara@Sun.COM #endif
17850Sstevel@tonic-gate pr->vers, pr->proc, pr->netid);
17860Sstevel@tonic-gate if (rtype == RPCBVERS_4_STAT)
1787*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%d\t ", pr->indirect);
1788*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%d\t%d\n", pr->success, pr->failure);
17890Sstevel@tonic-gate }
17900Sstevel@tonic-gate }
17910Sstevel@tonic-gate
17920Sstevel@tonic-gate static void
1793*11563SVallish.Vaidyeshwara@Sun.COM /* LINTED E_FUNC_ARG_UNUSED for 1st arg rtype */
print_getaddrstat(rtype,infp)17940Sstevel@tonic-gate print_getaddrstat(rtype, infp)
17950Sstevel@tonic-gate int rtype;
17960Sstevel@tonic-gate rpcb_stat *infp;
17970Sstevel@tonic-gate {
17980Sstevel@tonic-gate rpcbs_addrlist_ptr al;
17990Sstevel@tonic-gate register struct rpcent *rpc;
18000Sstevel@tonic-gate
1801*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("prog\t\tvers\tnetid\t success\tfailure\n");
18020Sstevel@tonic-gate for (al = infp->addrinfo; al; al = al->next) {
18030Sstevel@tonic-gate rpc = getrpcbynumber(al->prog);
18040Sstevel@tonic-gate if (rpc)
1805*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-16s", rpc->r_name);
18060Sstevel@tonic-gate else
1807*11563SVallish.Vaidyeshwara@Sun.COM #if defined(_LP64) || defined(_I32LPx)
1808*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-16u", al->prog);
1809*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%u\t%-9s %-12d\t%d\n",
1810*11563SVallish.Vaidyeshwara@Sun.COM #else
1811*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%-16lu", al->prog);
1812*11563SVallish.Vaidyeshwara@Sun.COM (void) printf("%lu\t%-9s %-12d\t%d\n",
1813*11563SVallish.Vaidyeshwara@Sun.COM #endif
18140Sstevel@tonic-gate al->vers, al->netid,
18150Sstevel@tonic-gate al->success, al->failure);
18160Sstevel@tonic-gate }
18170Sstevel@tonic-gate }
18180Sstevel@tonic-gate
18190Sstevel@tonic-gate static char *
spaces(howmany)18200Sstevel@tonic-gate spaces(howmany)
18210Sstevel@tonic-gate int howmany;
18220Sstevel@tonic-gate {
18230Sstevel@tonic-gate static char space_array[] = /* 64 spaces */
18240Sstevel@tonic-gate " ";
18250Sstevel@tonic-gate
18260Sstevel@tonic-gate if (howmany <= 0 || howmany > sizeof (space_array)) {
18270Sstevel@tonic-gate return ("");
18280Sstevel@tonic-gate }
18290Sstevel@tonic-gate return (&space_array[sizeof (space_array) - howmany - 1]);
18300Sstevel@tonic-gate }
1831