1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * Copyright 2000 Sun Microsystems, Inc. All rights reserved. 23*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 27*7c478bd9Sstevel@tonic-gate /* 28*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 29*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 30*7c478bd9Sstevel@tonic-gate * All Rights Reserved 31*7c478bd9Sstevel@tonic-gate * 32*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 33*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 34*7c478bd9Sstevel@tonic-gate * contributors. 35*7c478bd9Sstevel@tonic-gate */ 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate /* 40*7c478bd9Sstevel@tonic-gate * rpcinfo: ping a particular rpc program 41*7c478bd9Sstevel@tonic-gate * or dump the the registered programs on the remote machine. 42*7c478bd9Sstevel@tonic-gate */ 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * We are for now defining PORTMAP here. It doesnt even compile 46*7c478bd9Sstevel@tonic-gate * unless it is defined. 47*7c478bd9Sstevel@tonic-gate */ 48*7c478bd9Sstevel@tonic-gate #ifndef PORTMAP 49*7c478bd9Sstevel@tonic-gate #define PORTMAP 50*7c478bd9Sstevel@tonic-gate #endif 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate /* 53*7c478bd9Sstevel@tonic-gate * If PORTMAP is defined, rpcinfo will talk to both portmapper and 54*7c478bd9Sstevel@tonic-gate * rpcbind programs; else it talks only to rpcbind. In the latter case 55*7c478bd9Sstevel@tonic-gate * all the portmapper specific options such as -u, -t, -p become void. 56*7c478bd9Sstevel@tonic-gate */ 57*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 58*7c478bd9Sstevel@tonic-gate #include <stdio.h> 59*7c478bd9Sstevel@tonic-gate #include <rpc/rpcb_prot.h> 60*7c478bd9Sstevel@tonic-gate #include <rpc/nettype.h> 61*7c478bd9Sstevel@tonic-gate #include <netdir.h> 62*7c478bd9Sstevel@tonic-gate #include <rpc/rpcent.h> 63*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 64*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 65*7c478bd9Sstevel@tonic-gate #include <string.h> 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP /* Support for version 2 portmapper */ 68*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 69*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 70*7c478bd9Sstevel@tonic-gate #include <netdb.h> 71*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 72*7c478bd9Sstevel@tonic-gate #include <rpc/pmap_prot.h> 73*7c478bd9Sstevel@tonic-gate #include <rpc/pmap_clnt.h> 74*7c478bd9Sstevel@tonic-gate #endif 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate #define MAXHOSTLEN 256 77*7c478bd9Sstevel@tonic-gate #define MIN_VERS ((ulong_t)0) 78*7c478bd9Sstevel@tonic-gate #define MAX_VERS ((ulong_t)4294967295L) 79*7c478bd9Sstevel@tonic-gate #define UNKNOWN "unknown" 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate extern int t_errno; 84*7c478bd9Sstevel@tonic-gate extern long strtol(); 85*7c478bd9Sstevel@tonic-gate static char *spaces(); 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 88*7c478bd9Sstevel@tonic-gate static void ip_ping(/*ushort_t portflag, char *trans, 89*7c478bd9Sstevel@tonic-gate int argc, char **argv*/); 90*7c478bd9Sstevel@tonic-gate static CLIENT *clnt_com_create(/* struct sockaddr_in *addr, long prog, 91*7c478bd9Sstevel@tonic-gate long vers, int *fd, char *trans*/); 92*7c478bd9Sstevel@tonic-gate static void pmapdump(/*int argc, char **argv*/); 93*7c478bd9Sstevel@tonic-gate static void get_inet_address(/*struct sockaddr_in *addr, char *host*/); 94*7c478bd9Sstevel@tonic-gate #endif 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate static bool_t reply_proc(/*void *res, struct netbuf *who*, 97*7c478bd9Sstevel@tonic-gate struct netconfig *nconf*/); 98*7c478bd9Sstevel@tonic-gate static void brdcst(/*int argc, char **argv*/); 99*7c478bd9Sstevel@tonic-gate static void addrping(/*char *address, char *netid, 100*7c478bd9Sstevel@tonic-gate int argc, char **argv*/); 101*7c478bd9Sstevel@tonic-gate static void progping(/* char *netid, int argc, char **argv*/); 102*7c478bd9Sstevel@tonic-gate static CLIENT *clnt_addr_create(/* char *addr, struct netconfig *nconf, 103*7c478bd9Sstevel@tonic-gate long prog, long vers*/); 104*7c478bd9Sstevel@tonic-gate static CLIENT *clnt_rpcbind_create(/* char *host, int vers */); 105*7c478bd9Sstevel@tonic-gate static CLIENT *getclnthandle(/* host, nconf, rpcbversnum */); 106*7c478bd9Sstevel@tonic-gate static int pstatus(/*CLIENT *client, ulong_t prognum, ulong_t vers*/); 107*7c478bd9Sstevel@tonic-gate static void rpcbdump(/*char *netid, int argc, char **argv*/); 108*7c478bd9Sstevel@tonic-gate static void rpcbgetstat(/* int argc, char **argv*/); 109*7c478bd9Sstevel@tonic-gate static void rpcbaddrlist(/*char *netid, int argc, char **argv*/); 110*7c478bd9Sstevel@tonic-gate static void deletereg(/*char *netid, int argc, char **argv */); 111*7c478bd9Sstevel@tonic-gate static void print_rmtcallstat(/* rtype, infp */); 112*7c478bd9Sstevel@tonic-gate static void print_getaddrstat(/* rtype, infp */); 113*7c478bd9Sstevel@tonic-gate static void usage(/*void*/); 114*7c478bd9Sstevel@tonic-gate static ulong_t getprognum(/*char *arg*/); 115*7c478bd9Sstevel@tonic-gate static ulong_t getvers(/*char *arg*/); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* 118*7c478bd9Sstevel@tonic-gate * Functions to be performed. 119*7c478bd9Sstevel@tonic-gate */ 120*7c478bd9Sstevel@tonic-gate #define NONE 0 /* no function */ 121*7c478bd9Sstevel@tonic-gate #define PMAPDUMP 1 /* dump portmapper registrations */ 122*7c478bd9Sstevel@tonic-gate #define TCPPING 2 /* ping TCP service */ 123*7c478bd9Sstevel@tonic-gate #define UDPPING 3 /* ping UDP service */ 124*7c478bd9Sstevel@tonic-gate #define BROADCAST 4 /* ping broadcast service */ 125*7c478bd9Sstevel@tonic-gate #define DELETES 5 /* delete registration for the service */ 126*7c478bd9Sstevel@tonic-gate #define ADDRPING 6 /* pings at the given address */ 127*7c478bd9Sstevel@tonic-gate #define PROGPING 7 /* pings a program on a given host */ 128*7c478bd9Sstevel@tonic-gate #define RPCBDUMP 8 /* dump rpcbind registrations */ 129*7c478bd9Sstevel@tonic-gate #define RPCBDUMP_SHORT 9 /* dump rpcbind registrations - short version */ 130*7c478bd9Sstevel@tonic-gate #define RPCBADDRLIST 10 /* dump addr list about one prog */ 131*7c478bd9Sstevel@tonic-gate #define RPCBGETSTAT 11 /* Get statistics */ 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate struct netidlist { 134*7c478bd9Sstevel@tonic-gate char *netid; 135*7c478bd9Sstevel@tonic-gate struct netidlist *next; 136*7c478bd9Sstevel@tonic-gate }; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate struct verslist { 139*7c478bd9Sstevel@tonic-gate int vers; 140*7c478bd9Sstevel@tonic-gate struct verslist *next; 141*7c478bd9Sstevel@tonic-gate }; 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate struct rpcbdump_short { 144*7c478bd9Sstevel@tonic-gate ulong_t prog; 145*7c478bd9Sstevel@tonic-gate struct verslist *vlist; 146*7c478bd9Sstevel@tonic-gate struct netidlist *nlist; 147*7c478bd9Sstevel@tonic-gate struct rpcbdump_short *next; 148*7c478bd9Sstevel@tonic-gate char *owner; 149*7c478bd9Sstevel@tonic-gate }; 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate char *loopback_netid = NULL; 153*7c478bd9Sstevel@tonic-gate struct netconfig *loopback_nconf; 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate int 156*7c478bd9Sstevel@tonic-gate main(argc, argv) 157*7c478bd9Sstevel@tonic-gate int argc; 158*7c478bd9Sstevel@tonic-gate char **argv; 159*7c478bd9Sstevel@tonic-gate { 160*7c478bd9Sstevel@tonic-gate register int c; 161*7c478bd9Sstevel@tonic-gate extern char *optarg; 162*7c478bd9Sstevel@tonic-gate extern int optind; 163*7c478bd9Sstevel@tonic-gate int errflg; 164*7c478bd9Sstevel@tonic-gate int function; 165*7c478bd9Sstevel@tonic-gate char *netid = NULL; 166*7c478bd9Sstevel@tonic-gate char *address = NULL; 167*7c478bd9Sstevel@tonic-gate void *handle; 168*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 169*7c478bd9Sstevel@tonic-gate char *strptr; 170*7c478bd9Sstevel@tonic-gate ushort_t portnum = 0; 171*7c478bd9Sstevel@tonic-gate #endif 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate function = NONE; 174*7c478bd9Sstevel@tonic-gate errflg = 0; 175*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 176*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "a:bdlmn:pstT:u")) != EOF) { 177*7c478bd9Sstevel@tonic-gate #else 178*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "a:bdlmn:sT:")) != EOF) { 179*7c478bd9Sstevel@tonic-gate #endif 180*7c478bd9Sstevel@tonic-gate switch (c) { 181*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 182*7c478bd9Sstevel@tonic-gate case 'p': 183*7c478bd9Sstevel@tonic-gate if (function != NONE) 184*7c478bd9Sstevel@tonic-gate errflg = 1; 185*7c478bd9Sstevel@tonic-gate else 186*7c478bd9Sstevel@tonic-gate function = PMAPDUMP; 187*7c478bd9Sstevel@tonic-gate break; 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate case 't': 190*7c478bd9Sstevel@tonic-gate if (function != NONE) 191*7c478bd9Sstevel@tonic-gate errflg = 1; 192*7c478bd9Sstevel@tonic-gate else 193*7c478bd9Sstevel@tonic-gate function = TCPPING; 194*7c478bd9Sstevel@tonic-gate break; 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate case 'u': 197*7c478bd9Sstevel@tonic-gate if (function != NONE) 198*7c478bd9Sstevel@tonic-gate errflg = 1; 199*7c478bd9Sstevel@tonic-gate else 200*7c478bd9Sstevel@tonic-gate function = UDPPING; 201*7c478bd9Sstevel@tonic-gate break; 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate case 'n': 204*7c478bd9Sstevel@tonic-gate portnum = (ushort_t)strtol(optarg, &strptr, 10); 205*7c478bd9Sstevel@tonic-gate if (strptr == optarg || *strptr != '\0') { 206*7c478bd9Sstevel@tonic-gate fprintf(stderr, 207*7c478bd9Sstevel@tonic-gate "rpcinfo: %s is illegal port number\n", 208*7c478bd9Sstevel@tonic-gate optarg); 209*7c478bd9Sstevel@tonic-gate exit(1); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate break; 212*7c478bd9Sstevel@tonic-gate #endif 213*7c478bd9Sstevel@tonic-gate case 'a': 214*7c478bd9Sstevel@tonic-gate address = optarg; 215*7c478bd9Sstevel@tonic-gate if (function != NONE) 216*7c478bd9Sstevel@tonic-gate errflg = 1; 217*7c478bd9Sstevel@tonic-gate else 218*7c478bd9Sstevel@tonic-gate function = ADDRPING; 219*7c478bd9Sstevel@tonic-gate break; 220*7c478bd9Sstevel@tonic-gate case 'b': 221*7c478bd9Sstevel@tonic-gate if (function != NONE) 222*7c478bd9Sstevel@tonic-gate errflg = 1; 223*7c478bd9Sstevel@tonic-gate else 224*7c478bd9Sstevel@tonic-gate function = BROADCAST; 225*7c478bd9Sstevel@tonic-gate break; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate case 'd': 228*7c478bd9Sstevel@tonic-gate if (function != NONE) 229*7c478bd9Sstevel@tonic-gate errflg = 1; 230*7c478bd9Sstevel@tonic-gate else 231*7c478bd9Sstevel@tonic-gate function = DELETES; 232*7c478bd9Sstevel@tonic-gate break; 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate case 'l': 235*7c478bd9Sstevel@tonic-gate if (function != NONE) 236*7c478bd9Sstevel@tonic-gate errflg = 1; 237*7c478bd9Sstevel@tonic-gate else 238*7c478bd9Sstevel@tonic-gate function = RPCBADDRLIST; 239*7c478bd9Sstevel@tonic-gate break; 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate case 'm': 242*7c478bd9Sstevel@tonic-gate if (function != NONE) 243*7c478bd9Sstevel@tonic-gate errflg = 1; 244*7c478bd9Sstevel@tonic-gate else 245*7c478bd9Sstevel@tonic-gate function = RPCBGETSTAT; 246*7c478bd9Sstevel@tonic-gate break; 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate case 's': 249*7c478bd9Sstevel@tonic-gate if (function != NONE) 250*7c478bd9Sstevel@tonic-gate errflg = 1; 251*7c478bd9Sstevel@tonic-gate else 252*7c478bd9Sstevel@tonic-gate function = RPCBDUMP_SHORT; 253*7c478bd9Sstevel@tonic-gate break; 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate case 'T': 256*7c478bd9Sstevel@tonic-gate netid = optarg; 257*7c478bd9Sstevel@tonic-gate break; 258*7c478bd9Sstevel@tonic-gate case '?': 259*7c478bd9Sstevel@tonic-gate errflg = 1; 260*7c478bd9Sstevel@tonic-gate break; 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate if (errflg || ((function == ADDRPING) && !netid)) { 265*7c478bd9Sstevel@tonic-gate usage(); 266*7c478bd9Sstevel@tonic-gate return (1); 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate if (netid == NULL) { /* user has not selected transport to use */ 269*7c478bd9Sstevel@tonic-gate /* 270*7c478bd9Sstevel@tonic-gate * See if a COTS loopback transport is available, in case we 271*7c478bd9Sstevel@tonic-gate * will be talking to the local system. 272*7c478bd9Sstevel@tonic-gate */ 273*7c478bd9Sstevel@tonic-gate handle = setnetconfig(); 274*7c478bd9Sstevel@tonic-gate while ((loopback_nconf = getnetconfig(handle)) != NULL) { 275*7c478bd9Sstevel@tonic-gate if (strcmp(loopback_nconf->nc_protofmly, 276*7c478bd9Sstevel@tonic-gate NC_LOOPBACK) == 0 && 277*7c478bd9Sstevel@tonic-gate (loopback_nconf->nc_semantics == NC_TPI_COTS || 278*7c478bd9Sstevel@tonic-gate loopback_nconf->nc_semantics == NC_TPI_COTS_ORD)) { 279*7c478bd9Sstevel@tonic-gate loopback_netid = loopback_nconf->nc_netid; 280*7c478bd9Sstevel@tonic-gate break; 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate if (loopback_netid == NULL) { 284*7c478bd9Sstevel@tonic-gate endnetconfig(handle); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate if (function == NONE) { 288*7c478bd9Sstevel@tonic-gate if (argc - optind > 1) 289*7c478bd9Sstevel@tonic-gate function = PROGPING; 290*7c478bd9Sstevel@tonic-gate else 291*7c478bd9Sstevel@tonic-gate function = RPCBDUMP; 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate switch (function) { 295*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 296*7c478bd9Sstevel@tonic-gate case PMAPDUMP: 297*7c478bd9Sstevel@tonic-gate if (portnum != 0) { 298*7c478bd9Sstevel@tonic-gate usage(); 299*7c478bd9Sstevel@tonic-gate return (1); 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate pmapdump(argc - optind, argv + optind); 302*7c478bd9Sstevel@tonic-gate break; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate case UDPPING: 305*7c478bd9Sstevel@tonic-gate ip_ping(portnum, "udp", argc - optind, argv + optind); 306*7c478bd9Sstevel@tonic-gate break; 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate case TCPPING: 309*7c478bd9Sstevel@tonic-gate ip_ping(portnum, "tcp", argc - optind, argv + optind); 310*7c478bd9Sstevel@tonic-gate break; 311*7c478bd9Sstevel@tonic-gate #endif 312*7c478bd9Sstevel@tonic-gate case BROADCAST: 313*7c478bd9Sstevel@tonic-gate brdcst(argc - optind, argv + optind); 314*7c478bd9Sstevel@tonic-gate break; 315*7c478bd9Sstevel@tonic-gate case DELETES: 316*7c478bd9Sstevel@tonic-gate deletereg(netid, argc - optind, argv + optind); 317*7c478bd9Sstevel@tonic-gate break; 318*7c478bd9Sstevel@tonic-gate case ADDRPING: 319*7c478bd9Sstevel@tonic-gate addrping(address, netid, argc - optind, argv + optind); 320*7c478bd9Sstevel@tonic-gate break; 321*7c478bd9Sstevel@tonic-gate case PROGPING: 322*7c478bd9Sstevel@tonic-gate progping(netid, argc - optind, argv + optind); 323*7c478bd9Sstevel@tonic-gate break; 324*7c478bd9Sstevel@tonic-gate case RPCBDUMP: 325*7c478bd9Sstevel@tonic-gate case RPCBDUMP_SHORT: 326*7c478bd9Sstevel@tonic-gate rpcbdump(function, netid, argc - optind, argv + optind); 327*7c478bd9Sstevel@tonic-gate break; 328*7c478bd9Sstevel@tonic-gate case RPCBGETSTAT: 329*7c478bd9Sstevel@tonic-gate rpcbgetstat(argc - optind, argv + optind); 330*7c478bd9Sstevel@tonic-gate break; 331*7c478bd9Sstevel@tonic-gate case RPCBADDRLIST: 332*7c478bd9Sstevel@tonic-gate rpcbaddrlist(netid, argc - optind, argv + optind); 333*7c478bd9Sstevel@tonic-gate break; 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate return (0); 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 339*7c478bd9Sstevel@tonic-gate static CLIENT * 340*7c478bd9Sstevel@tonic-gate clnt_com_create(addr, prog, vers, fdp, trans) 341*7c478bd9Sstevel@tonic-gate struct sockaddr_in *addr; 342*7c478bd9Sstevel@tonic-gate ulong_t prog; 343*7c478bd9Sstevel@tonic-gate ulong_t vers; 344*7c478bd9Sstevel@tonic-gate int *fdp; 345*7c478bd9Sstevel@tonic-gate char *trans; 346*7c478bd9Sstevel@tonic-gate { 347*7c478bd9Sstevel@tonic-gate CLIENT *clnt; 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate if (strcmp(trans, "tcp") == 0) { 350*7c478bd9Sstevel@tonic-gate clnt = clnttcp_create(addr, prog, vers, fdp, 0, 0); 351*7c478bd9Sstevel@tonic-gate } else { 352*7c478bd9Sstevel@tonic-gate struct timeval to; 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate to.tv_sec = 5; 355*7c478bd9Sstevel@tonic-gate to.tv_usec = 0; 356*7c478bd9Sstevel@tonic-gate clnt = clntudp_create(addr, prog, vers, to, fdp); 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate if (clnt == (CLIENT *)NULL) { 359*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("rpcinfo"); 360*7c478bd9Sstevel@tonic-gate if (vers == MIN_VERS) 361*7c478bd9Sstevel@tonic-gate printf("program %lu is not available\n", prog); 362*7c478bd9Sstevel@tonic-gate else 363*7c478bd9Sstevel@tonic-gate printf("program %lu version %lu is not available\n", 364*7c478bd9Sstevel@tonic-gate prog, vers); 365*7c478bd9Sstevel@tonic-gate exit(1); 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate return (clnt); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate /* 371*7c478bd9Sstevel@tonic-gate * If portnum is 0, then go and get the address from portmapper, which happens 372*7c478bd9Sstevel@tonic-gate * transparently through clnt*_create(); If version number is not given, it 373*7c478bd9Sstevel@tonic-gate * tries to find out the version number by making a call to version 0 and if 374*7c478bd9Sstevel@tonic-gate * that fails, it obtains the high order and the low order version number. If 375*7c478bd9Sstevel@tonic-gate * version 0 calls succeeds, it tries for MAXVERS call and repeats the same. 376*7c478bd9Sstevel@tonic-gate */ 377*7c478bd9Sstevel@tonic-gate static void 378*7c478bd9Sstevel@tonic-gate ip_ping(portnum, trans, argc, argv) 379*7c478bd9Sstevel@tonic-gate ushort_t portnum; 380*7c478bd9Sstevel@tonic-gate char *trans; 381*7c478bd9Sstevel@tonic-gate int argc; 382*7c478bd9Sstevel@tonic-gate char **argv; 383*7c478bd9Sstevel@tonic-gate { 384*7c478bd9Sstevel@tonic-gate CLIENT *client; 385*7c478bd9Sstevel@tonic-gate int fd = RPC_ANYFD; 386*7c478bd9Sstevel@tonic-gate struct timeval to; 387*7c478bd9Sstevel@tonic-gate struct sockaddr_in addr; 388*7c478bd9Sstevel@tonic-gate enum clnt_stat rpc_stat; 389*7c478bd9Sstevel@tonic-gate ulong_t prognum, vers, minvers, maxvers; 390*7c478bd9Sstevel@tonic-gate struct rpc_err rpcerr; 391*7c478bd9Sstevel@tonic-gate int failure = 0; 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate if (argc < 2 || argc > 3) { 394*7c478bd9Sstevel@tonic-gate usage(); 395*7c478bd9Sstevel@tonic-gate exit(1); 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate to.tv_sec = 10; 398*7c478bd9Sstevel@tonic-gate to.tv_usec = 0; 399*7c478bd9Sstevel@tonic-gate prognum = getprognum(argv[1]); 400*7c478bd9Sstevel@tonic-gate get_inet_address(&addr, argv[0]); 401*7c478bd9Sstevel@tonic-gate if (argc == 2) { /* Version number not known */ 402*7c478bd9Sstevel@tonic-gate /* 403*7c478bd9Sstevel@tonic-gate * A call to version 0 should fail with a program/version 404*7c478bd9Sstevel@tonic-gate * mismatch, and give us the range of versions supported. 405*7c478bd9Sstevel@tonic-gate */ 406*7c478bd9Sstevel@tonic-gate vers = MIN_VERS; 407*7c478bd9Sstevel@tonic-gate } else { 408*7c478bd9Sstevel@tonic-gate vers = getvers(argv[2]); 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate addr.sin_port = htons(portnum); 411*7c478bd9Sstevel@tonic-gate client = clnt_com_create(&addr, prognum, vers, &fd, trans); 412*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void, 413*7c478bd9Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, (char *)NULL, 414*7c478bd9Sstevel@tonic-gate to); 415*7c478bd9Sstevel@tonic-gate if (argc != 2) { 416*7c478bd9Sstevel@tonic-gate /* Version number was known */ 417*7c478bd9Sstevel@tonic-gate if (pstatus(client, prognum, vers) < 0) 418*7c478bd9Sstevel@tonic-gate exit(1); 419*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 420*7c478bd9Sstevel@tonic-gate return; 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate /* Version number not known */ 423*7c478bd9Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL); 424*7c478bd9Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) { 425*7c478bd9Sstevel@tonic-gate clnt_geterr(client, &rpcerr); 426*7c478bd9Sstevel@tonic-gate minvers = rpcerr.re_vers.low; 427*7c478bd9Sstevel@tonic-gate maxvers = rpcerr.re_vers.high; 428*7c478bd9Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) { 429*7c478bd9Sstevel@tonic-gate /* 430*7c478bd9Sstevel@tonic-gate * Oh dear, it DOES support version 0. 431*7c478bd9Sstevel@tonic-gate * Let's try version MAX_VERS. 432*7c478bd9Sstevel@tonic-gate */ 433*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 434*7c478bd9Sstevel@tonic-gate addr.sin_port = htons(portnum); 435*7c478bd9Sstevel@tonic-gate client = clnt_com_create(&addr, prognum, MAX_VERS, &fd, trans); 436*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void, 437*7c478bd9Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, 438*7c478bd9Sstevel@tonic-gate (char *)NULL, to); 439*7c478bd9Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) { 440*7c478bd9Sstevel@tonic-gate clnt_geterr(client, &rpcerr); 441*7c478bd9Sstevel@tonic-gate minvers = rpcerr.re_vers.low; 442*7c478bd9Sstevel@tonic-gate maxvers = rpcerr.re_vers.high; 443*7c478bd9Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) { 444*7c478bd9Sstevel@tonic-gate /* 445*7c478bd9Sstevel@tonic-gate * It also supports version MAX_VERS. 446*7c478bd9Sstevel@tonic-gate * Looks like we have a wise guy. 447*7c478bd9Sstevel@tonic-gate * OK, we give them information on all 448*7c478bd9Sstevel@tonic-gate * 4 billion versions they support... 449*7c478bd9Sstevel@tonic-gate */ 450*7c478bd9Sstevel@tonic-gate minvers = 0; 451*7c478bd9Sstevel@tonic-gate maxvers = MAX_VERS; 452*7c478bd9Sstevel@tonic-gate } else { 453*7c478bd9Sstevel@tonic-gate (void) pstatus(client, prognum, MAX_VERS); 454*7c478bd9Sstevel@tonic-gate exit(1); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate } else { 457*7c478bd9Sstevel@tonic-gate (void) pstatus(client, prognum, (ulong_t)0); 458*7c478bd9Sstevel@tonic-gate exit(1); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 461*7c478bd9Sstevel@tonic-gate for (vers = minvers; vers <= maxvers; vers++) { 462*7c478bd9Sstevel@tonic-gate addr.sin_port = htons(portnum); 463*7c478bd9Sstevel@tonic-gate client = clnt_com_create(&addr, prognum, vers, &fd, trans); 464*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void, 465*7c478bd9Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, 466*7c478bd9Sstevel@tonic-gate (char *)NULL, to); 467*7c478bd9Sstevel@tonic-gate if (pstatus(client, prognum, vers) < 0) 468*7c478bd9Sstevel@tonic-gate failure = 1; 469*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate if (failure) 472*7c478bd9Sstevel@tonic-gate exit(1); 473*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate /* 477*7c478bd9Sstevel@tonic-gate * Dump all the portmapper registerations 478*7c478bd9Sstevel@tonic-gate */ 479*7c478bd9Sstevel@tonic-gate static void 480*7c478bd9Sstevel@tonic-gate pmapdump(argc, argv) 481*7c478bd9Sstevel@tonic-gate int argc; 482*7c478bd9Sstevel@tonic-gate char **argv; 483*7c478bd9Sstevel@tonic-gate { 484*7c478bd9Sstevel@tonic-gate struct sockaddr_in server_addr; 485*7c478bd9Sstevel@tonic-gate pmaplist_ptr head = NULL; 486*7c478bd9Sstevel@tonic-gate int socket = RPC_ANYSOCK; 487*7c478bd9Sstevel@tonic-gate struct timeval minutetimeout; 488*7c478bd9Sstevel@tonic-gate register CLIENT *client; 489*7c478bd9Sstevel@tonic-gate struct rpcent *rpc; 490*7c478bd9Sstevel@tonic-gate enum clnt_stat clnt_st; 491*7c478bd9Sstevel@tonic-gate struct rpc_err err; 492*7c478bd9Sstevel@tonic-gate struct utsname utsname; 493*7c478bd9Sstevel@tonic-gate char *host; 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate if (argc > 1) { 496*7c478bd9Sstevel@tonic-gate usage(); 497*7c478bd9Sstevel@tonic-gate exit(1); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate if (argc == 1) { 500*7c478bd9Sstevel@tonic-gate host = argv[0]; 501*7c478bd9Sstevel@tonic-gate get_inet_address(&server_addr, host); 502*7c478bd9Sstevel@tonic-gate } else { 503*7c478bd9Sstevel@tonic-gate uname(&utsname); 504*7c478bd9Sstevel@tonic-gate host = utsname.nodename; 505*7c478bd9Sstevel@tonic-gate get_inet_address(&server_addr, host); 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate minutetimeout.tv_sec = 60; 508*7c478bd9Sstevel@tonic-gate minutetimeout.tv_usec = 0; 509*7c478bd9Sstevel@tonic-gate server_addr.sin_port = htons(PMAPPORT); 510*7c478bd9Sstevel@tonic-gate if ((client = clnttcp_create(&server_addr, PMAPPROG, 511*7c478bd9Sstevel@tonic-gate PMAPVERS, &socket, 50, 500)) == NULL) { 512*7c478bd9Sstevel@tonic-gate if (rpc_createerr.cf_stat == RPC_TLIERROR) { 513*7c478bd9Sstevel@tonic-gate /* 514*7c478bd9Sstevel@tonic-gate * "Misc. TLI error" is not too helpful. Most likely 515*7c478bd9Sstevel@tonic-gate * the connection to the remote server timed out, so 516*7c478bd9Sstevel@tonic-gate * this error is at least less perplexing. 517*7c478bd9Sstevel@tonic-gate */ 518*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_PMAPFAILURE; 519*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_error.re_status = RPC_FAILED; 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("rpcinfo: can't contact portmapper"); 522*7c478bd9Sstevel@tonic-gate exit(1); 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate clnt_st = CLNT_CALL(client, PMAPPROC_DUMP, (xdrproc_t)xdr_void, 525*7c478bd9Sstevel@tonic-gate NULL, (xdrproc_t)xdr_pmaplist_ptr, (char *)&head, 526*7c478bd9Sstevel@tonic-gate minutetimeout); 527*7c478bd9Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS) { 528*7c478bd9Sstevel@tonic-gate if ((clnt_st == RPC_PROGVERSMISMATCH) || 529*7c478bd9Sstevel@tonic-gate (clnt_st == RPC_PROGUNAVAIL)) { 530*7c478bd9Sstevel@tonic-gate CLNT_GETERR(client, &err); 531*7c478bd9Sstevel@tonic-gate if (err.re_vers.low > PMAPVERS) 532*7c478bd9Sstevel@tonic-gate fprintf(stderr, 533*7c478bd9Sstevel@tonic-gate "%s does not support portmapper. Try rpcinfo %s instead\n", 534*7c478bd9Sstevel@tonic-gate host, host); 535*7c478bd9Sstevel@tonic-gate exit(1); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate clnt_perror(client, "rpcinfo: can't contact portmapper"); 538*7c478bd9Sstevel@tonic-gate exit(1); 539*7c478bd9Sstevel@tonic-gate } 540*7c478bd9Sstevel@tonic-gate if (head == NULL) { 541*7c478bd9Sstevel@tonic-gate printf("No remote programs registered.\n"); 542*7c478bd9Sstevel@tonic-gate } else { 543*7c478bd9Sstevel@tonic-gate printf(" program vers proto port service\n"); 544*7c478bd9Sstevel@tonic-gate for (; head != NULL; head = head->pml_next) { 545*7c478bd9Sstevel@tonic-gate printf("%10ld%5ld", 546*7c478bd9Sstevel@tonic-gate head->pml_map.pm_prog, 547*7c478bd9Sstevel@tonic-gate head->pml_map.pm_vers); 548*7c478bd9Sstevel@tonic-gate if (head->pml_map.pm_prot == IPPROTO_UDP) 549*7c478bd9Sstevel@tonic-gate printf("%6s", "udp"); 550*7c478bd9Sstevel@tonic-gate else if (head->pml_map.pm_prot == IPPROTO_TCP) 551*7c478bd9Sstevel@tonic-gate printf("%6s", "tcp"); 552*7c478bd9Sstevel@tonic-gate else 553*7c478bd9Sstevel@tonic-gate printf("%6ld", head->pml_map.pm_prot); 554*7c478bd9Sstevel@tonic-gate printf("%7ld", head->pml_map.pm_port); 555*7c478bd9Sstevel@tonic-gate rpc = getrpcbynumber(head->pml_map.pm_prog); 556*7c478bd9Sstevel@tonic-gate if (rpc) 557*7c478bd9Sstevel@tonic-gate printf(" %s\n", rpc->r_name); 558*7c478bd9Sstevel@tonic-gate else 559*7c478bd9Sstevel@tonic-gate printf("\n"); 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate static void 565*7c478bd9Sstevel@tonic-gate get_inet_address(addr, host) 566*7c478bd9Sstevel@tonic-gate struct sockaddr_in *addr; 567*7c478bd9Sstevel@tonic-gate char *host; 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 570*7c478bd9Sstevel@tonic-gate struct nd_hostserv service; 571*7c478bd9Sstevel@tonic-gate struct nd_addrlist *naddrs; 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate (void) memset((char *)addr, 0, sizeof (*addr)); 574*7c478bd9Sstevel@tonic-gate addr->sin_addr.s_addr = inet_addr(host); 575*7c478bd9Sstevel@tonic-gate if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) { 576*7c478bd9Sstevel@tonic-gate if ((nconf = __rpc_getconfip("udp")) == NULL && 577*7c478bd9Sstevel@tonic-gate (nconf = __rpc_getconfip("tcp")) == NULL) { 578*7c478bd9Sstevel@tonic-gate fprintf(stderr, 579*7c478bd9Sstevel@tonic-gate "rpcinfo: couldn't find a suitable transport\n"); 580*7c478bd9Sstevel@tonic-gate exit(1); 581*7c478bd9Sstevel@tonic-gate } else { 582*7c478bd9Sstevel@tonic-gate service.h_host = host; 583*7c478bd9Sstevel@tonic-gate service.h_serv = "rpcbind"; 584*7c478bd9Sstevel@tonic-gate if (netdir_getbyname(nconf, &service, &naddrs)) { 585*7c478bd9Sstevel@tonic-gate fprintf(stderr, "rpcinfo: %s: %s\n", 586*7c478bd9Sstevel@tonic-gate host, netdir_sperror()); 587*7c478bd9Sstevel@tonic-gate exit(1); 588*7c478bd9Sstevel@tonic-gate } else { 589*7c478bd9Sstevel@tonic-gate (void) memcpy((caddr_t)addr, 590*7c478bd9Sstevel@tonic-gate naddrs->n_addrs->buf, naddrs->n_addrs->len); 591*7c478bd9Sstevel@tonic-gate (void) netdir_free((char *)naddrs, ND_ADDRLIST); 592*7c478bd9Sstevel@tonic-gate } 593*7c478bd9Sstevel@tonic-gate (void) freenetconfigent(nconf); 594*7c478bd9Sstevel@tonic-gate } 595*7c478bd9Sstevel@tonic-gate } else { 596*7c478bd9Sstevel@tonic-gate addr->sin_family = AF_INET; 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate #endif /* PORTMAP */ 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate /* 602*7c478bd9Sstevel@tonic-gate * reply_proc collects replies from the broadcast. 603*7c478bd9Sstevel@tonic-gate * to get a unique list of responses the output of rpcinfo should 604*7c478bd9Sstevel@tonic-gate * be piped through sort(1) and then uniq(1). 605*7c478bd9Sstevel@tonic-gate */ 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 608*7c478bd9Sstevel@tonic-gate static bool_t 609*7c478bd9Sstevel@tonic-gate reply_proc(res, who, nconf) 610*7c478bd9Sstevel@tonic-gate void *res; /* Nothing comes back */ 611*7c478bd9Sstevel@tonic-gate struct netbuf *who; /* Who sent us the reply */ 612*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; /* On which transport the reply came */ 613*7c478bd9Sstevel@tonic-gate { 614*7c478bd9Sstevel@tonic-gate struct nd_hostservlist *serv; 615*7c478bd9Sstevel@tonic-gate char *uaddr; 616*7c478bd9Sstevel@tonic-gate char *hostname; 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate if (netdir_getbyaddr(nconf, &serv, who)) { 619*7c478bd9Sstevel@tonic-gate hostname = UNKNOWN; 620*7c478bd9Sstevel@tonic-gate } else { 621*7c478bd9Sstevel@tonic-gate hostname = serv->h_hostservs->h_host; 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate if (!(uaddr = taddr2uaddr(nconf, who))) { 624*7c478bd9Sstevel@tonic-gate uaddr = UNKNOWN; 625*7c478bd9Sstevel@tonic-gate } 626*7c478bd9Sstevel@tonic-gate printf("%s\t%s\n", uaddr, hostname); 627*7c478bd9Sstevel@tonic-gate if (strcmp(hostname, UNKNOWN)) 628*7c478bd9Sstevel@tonic-gate netdir_free((char *)serv, ND_HOSTSERVLIST); 629*7c478bd9Sstevel@tonic-gate if (strcmp(uaddr, UNKNOWN)) 630*7c478bd9Sstevel@tonic-gate free((char *)uaddr); 631*7c478bd9Sstevel@tonic-gate return (FALSE); 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate static void 635*7c478bd9Sstevel@tonic-gate brdcst(argc, argv) 636*7c478bd9Sstevel@tonic-gate int argc; 637*7c478bd9Sstevel@tonic-gate char **argv; 638*7c478bd9Sstevel@tonic-gate { 639*7c478bd9Sstevel@tonic-gate enum clnt_stat rpc_stat; 640*7c478bd9Sstevel@tonic-gate ulong_t prognum, vers; 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate if (argc != 2) { 643*7c478bd9Sstevel@tonic-gate usage(); 644*7c478bd9Sstevel@tonic-gate exit(1); 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate prognum = getprognum(argv[0]); 647*7c478bd9Sstevel@tonic-gate vers = getvers(argv[1]); 648*7c478bd9Sstevel@tonic-gate rpc_stat = rpc_broadcast(prognum, vers, NULLPROC, 649*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_void, (char *)NULL, (xdrproc_t)xdr_void, 650*7c478bd9Sstevel@tonic-gate (char *)NULL, (resultproc_t)reply_proc, NULL); 651*7c478bd9Sstevel@tonic-gate if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) { 652*7c478bd9Sstevel@tonic-gate fprintf(stderr, "rpcinfo: broadcast failed: %s\n", 653*7c478bd9Sstevel@tonic-gate clnt_sperrno(rpc_stat)); 654*7c478bd9Sstevel@tonic-gate exit(1); 655*7c478bd9Sstevel@tonic-gate } 656*7c478bd9Sstevel@tonic-gate exit(0); 657*7c478bd9Sstevel@tonic-gate } 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate static bool_t 660*7c478bd9Sstevel@tonic-gate add_version(rs, vers) 661*7c478bd9Sstevel@tonic-gate struct rpcbdump_short *rs; 662*7c478bd9Sstevel@tonic-gate ulong_t vers; 663*7c478bd9Sstevel@tonic-gate { 664*7c478bd9Sstevel@tonic-gate struct verslist *vl; 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate for (vl = rs->vlist; vl; vl = vl->next) 667*7c478bd9Sstevel@tonic-gate if (vl->vers == vers) 668*7c478bd9Sstevel@tonic-gate break; 669*7c478bd9Sstevel@tonic-gate if (vl) 670*7c478bd9Sstevel@tonic-gate return (TRUE); 671*7c478bd9Sstevel@tonic-gate vl = (struct verslist *)malloc(sizeof (struct verslist)); 672*7c478bd9Sstevel@tonic-gate if (vl == NULL) 673*7c478bd9Sstevel@tonic-gate return (FALSE); 674*7c478bd9Sstevel@tonic-gate vl->vers = vers; 675*7c478bd9Sstevel@tonic-gate vl->next = rs->vlist; 676*7c478bd9Sstevel@tonic-gate rs->vlist = vl; 677*7c478bd9Sstevel@tonic-gate return (TRUE); 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate static bool_t 681*7c478bd9Sstevel@tonic-gate add_netid(rs, netid) 682*7c478bd9Sstevel@tonic-gate struct rpcbdump_short *rs; 683*7c478bd9Sstevel@tonic-gate char *netid; 684*7c478bd9Sstevel@tonic-gate { 685*7c478bd9Sstevel@tonic-gate struct netidlist *nl; 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate for (nl = rs->nlist; nl; nl = nl->next) 688*7c478bd9Sstevel@tonic-gate if (strcmp(nl->netid, netid) == 0) 689*7c478bd9Sstevel@tonic-gate break; 690*7c478bd9Sstevel@tonic-gate if (nl) 691*7c478bd9Sstevel@tonic-gate return (TRUE); 692*7c478bd9Sstevel@tonic-gate nl = (struct netidlist *)malloc(sizeof (struct netidlist)); 693*7c478bd9Sstevel@tonic-gate if (nl == NULL) 694*7c478bd9Sstevel@tonic-gate return (FALSE); 695*7c478bd9Sstevel@tonic-gate nl->netid = netid; 696*7c478bd9Sstevel@tonic-gate nl->next = rs->nlist; 697*7c478bd9Sstevel@tonic-gate rs->nlist = nl; 698*7c478bd9Sstevel@tonic-gate return (TRUE); 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate static void 702*7c478bd9Sstevel@tonic-gate rpcbdump(dumptype, netid, argc, argv) 703*7c478bd9Sstevel@tonic-gate int dumptype; 704*7c478bd9Sstevel@tonic-gate char *netid; 705*7c478bd9Sstevel@tonic-gate int argc; 706*7c478bd9Sstevel@tonic-gate char **argv; 707*7c478bd9Sstevel@tonic-gate { 708*7c478bd9Sstevel@tonic-gate rpcblist_ptr head = NULL; 709*7c478bd9Sstevel@tonic-gate struct timeval minutetimeout; 710*7c478bd9Sstevel@tonic-gate register CLIENT *client; 711*7c478bd9Sstevel@tonic-gate struct rpcent *rpc; 712*7c478bd9Sstevel@tonic-gate char *host; 713*7c478bd9Sstevel@tonic-gate struct netidlist *nl; 714*7c478bd9Sstevel@tonic-gate struct verslist *vl; 715*7c478bd9Sstevel@tonic-gate struct rpcbdump_short *rs, *rs_tail; 716*7c478bd9Sstevel@tonic-gate char buf[256]; 717*7c478bd9Sstevel@tonic-gate enum clnt_stat clnt_st; 718*7c478bd9Sstevel@tonic-gate struct rpc_err err; 719*7c478bd9Sstevel@tonic-gate struct utsname utsname; 720*7c478bd9Sstevel@tonic-gate struct rpcbdump_short *rs_head = NULL; 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate if (argc > 1) { 723*7c478bd9Sstevel@tonic-gate usage(); 724*7c478bd9Sstevel@tonic-gate exit(1); 725*7c478bd9Sstevel@tonic-gate } 726*7c478bd9Sstevel@tonic-gate if (argc == 1) { 727*7c478bd9Sstevel@tonic-gate host = argv[0]; 728*7c478bd9Sstevel@tonic-gate } else { 729*7c478bd9Sstevel@tonic-gate uname(&utsname); 730*7c478bd9Sstevel@tonic-gate host = utsname.nodename; 731*7c478bd9Sstevel@tonic-gate } 732*7c478bd9Sstevel@tonic-gate if (netid == NULL) { 733*7c478bd9Sstevel@tonic-gate if (loopback_netid == NULL) { 734*7c478bd9Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS, NULL); 735*7c478bd9Sstevel@tonic-gate } else { 736*7c478bd9Sstevel@tonic-gate client = getclnthandle(host, loopback_nconf, RPCBVERS, NULL); 737*7c478bd9Sstevel@tonic-gate if (client == NULL && rpc_createerr.cf_stat == 738*7c478bd9Sstevel@tonic-gate RPC_N2AXLATEFAILURE) { 739*7c478bd9Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS, NULL); 740*7c478bd9Sstevel@tonic-gate } 741*7c478bd9Sstevel@tonic-gate } 742*7c478bd9Sstevel@tonic-gate } else { 743*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate nconf = getnetconfigent(netid); 746*7c478bd9Sstevel@tonic-gate if (nconf == NULL) { 747*7c478bd9Sstevel@tonic-gate nc_perror("rpcinfo: invalid transport"); 748*7c478bd9Sstevel@tonic-gate exit(1); 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate client = getclnthandle(host, nconf, RPCBVERS, NULL); 751*7c478bd9Sstevel@tonic-gate if (nconf) 752*7c478bd9Sstevel@tonic-gate (void) freenetconfigent(nconf); 753*7c478bd9Sstevel@tonic-gate } 754*7c478bd9Sstevel@tonic-gate if (client == (CLIENT *)NULL) { 755*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 756*7c478bd9Sstevel@tonic-gate exit(1); 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate minutetimeout.tv_sec = 60; 759*7c478bd9Sstevel@tonic-gate minutetimeout.tv_usec = 0; 760*7c478bd9Sstevel@tonic-gate clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, (xdrproc_t)xdr_void, 761*7c478bd9Sstevel@tonic-gate NULL, (xdrproc_t)xdr_rpcblist_ptr, (char *)&head, 762*7c478bd9Sstevel@tonic-gate minutetimeout); 763*7c478bd9Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS) { 764*7c478bd9Sstevel@tonic-gate if ((clnt_st == RPC_PROGVERSMISMATCH) || 765*7c478bd9Sstevel@tonic-gate (clnt_st == RPC_PROGUNAVAIL)) { 766*7c478bd9Sstevel@tonic-gate int vers; 767*7c478bd9Sstevel@tonic-gate 768*7c478bd9Sstevel@tonic-gate CLNT_GETERR(client, &err); 769*7c478bd9Sstevel@tonic-gate if (err.re_vers.low == RPCBVERS4) { 770*7c478bd9Sstevel@tonic-gate vers = RPCBVERS4; 771*7c478bd9Sstevel@tonic-gate clnt_control(client, CLSET_VERS, (char *)&vers); 772*7c478bd9Sstevel@tonic-gate clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, 773*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_void, NULL, 774*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_rpcblist_ptr, (char *)&head, 775*7c478bd9Sstevel@tonic-gate minutetimeout); 776*7c478bd9Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS) 777*7c478bd9Sstevel@tonic-gate goto failed; 778*7c478bd9Sstevel@tonic-gate } else { 779*7c478bd9Sstevel@tonic-gate if (err.re_vers.high == PMAPVERS) { 780*7c478bd9Sstevel@tonic-gate int high, low; 781*7c478bd9Sstevel@tonic-gate pmaplist_ptr pmaphead = NULL; 782*7c478bd9Sstevel@tonic-gate rpcblist_ptr list, prev; 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate vers = PMAPVERS; 785*7c478bd9Sstevel@tonic-gate clnt_control(client, CLSET_VERS, (char *)&vers); 786*7c478bd9Sstevel@tonic-gate clnt_st = CLNT_CALL(client, PMAPPROC_DUMP, 787*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_void, NULL, 788*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_pmaplist_ptr, 789*7c478bd9Sstevel@tonic-gate (char *)&pmaphead, minutetimeout); 790*7c478bd9Sstevel@tonic-gate if (clnt_st != RPC_SUCCESS) 791*7c478bd9Sstevel@tonic-gate goto failed; 792*7c478bd9Sstevel@tonic-gate /* 793*7c478bd9Sstevel@tonic-gate * convert to rpcblist_ptr format 794*7c478bd9Sstevel@tonic-gate */ 795*7c478bd9Sstevel@tonic-gate for (head = NULL; pmaphead != NULL; 796*7c478bd9Sstevel@tonic-gate pmaphead = pmaphead->pml_next) { 797*7c478bd9Sstevel@tonic-gate list = (rpcblist *)malloc(sizeof (rpcblist)); 798*7c478bd9Sstevel@tonic-gate if (list == NULL) 799*7c478bd9Sstevel@tonic-gate goto error; 800*7c478bd9Sstevel@tonic-gate if (head == NULL) 801*7c478bd9Sstevel@tonic-gate head = list; 802*7c478bd9Sstevel@tonic-gate else 803*7c478bd9Sstevel@tonic-gate prev->rpcb_next = (rpcblist_ptr) list; 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate list->rpcb_next = NULL; 806*7c478bd9Sstevel@tonic-gate list->rpcb_map.r_prog = pmaphead->pml_map.pm_prog; 807*7c478bd9Sstevel@tonic-gate list->rpcb_map.r_vers = pmaphead->pml_map.pm_vers; 808*7c478bd9Sstevel@tonic-gate if (pmaphead->pml_map.pm_prot == IPPROTO_UDP) 809*7c478bd9Sstevel@tonic-gate list->rpcb_map.r_netid = "udp"; 810*7c478bd9Sstevel@tonic-gate else if (pmaphead->pml_map.pm_prot == IPPROTO_TCP) 811*7c478bd9Sstevel@tonic-gate list->rpcb_map.r_netid = "tcp"; 812*7c478bd9Sstevel@tonic-gate else { 813*7c478bd9Sstevel@tonic-gate #define MAXLONG_AS_STRING "2147483648" 814*7c478bd9Sstevel@tonic-gate list->rpcb_map.r_netid = 815*7c478bd9Sstevel@tonic-gate malloc(strlen(MAXLONG_AS_STRING) + 1); 816*7c478bd9Sstevel@tonic-gate if (list->rpcb_map.r_netid == NULL) 817*7c478bd9Sstevel@tonic-gate goto error; 818*7c478bd9Sstevel@tonic-gate sprintf(list->rpcb_map.r_netid, "%6ld", 819*7c478bd9Sstevel@tonic-gate pmaphead->pml_map.pm_prot); 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate list->rpcb_map.r_owner = UNKNOWN; 822*7c478bd9Sstevel@tonic-gate low = pmaphead->pml_map.pm_port & 0xff; 823*7c478bd9Sstevel@tonic-gate high = (pmaphead->pml_map.pm_port >> 8) & 0xff; 824*7c478bd9Sstevel@tonic-gate list->rpcb_map.r_addr = strdup("0.0.0.0.XXX.XXX"); 825*7c478bd9Sstevel@tonic-gate sprintf(&list->rpcb_map.r_addr[8], "%d.%d", 826*7c478bd9Sstevel@tonic-gate high, low); 827*7c478bd9Sstevel@tonic-gate prev = list; 828*7c478bd9Sstevel@tonic-gate } 829*7c478bd9Sstevel@tonic-gate } 830*7c478bd9Sstevel@tonic-gate } 831*7c478bd9Sstevel@tonic-gate } else { /* any other error */ 832*7c478bd9Sstevel@tonic-gate failed: 833*7c478bd9Sstevel@tonic-gate clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 834*7c478bd9Sstevel@tonic-gate exit(1); 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate if (head == NULL) { 838*7c478bd9Sstevel@tonic-gate printf("No remote programs registered.\n"); 839*7c478bd9Sstevel@tonic-gate } else if (dumptype == RPCBDUMP) { 840*7c478bd9Sstevel@tonic-gate printf( 841*7c478bd9Sstevel@tonic-gate " program version netid address service owner\n"); 842*7c478bd9Sstevel@tonic-gate for (; head != NULL; head = head->rpcb_next) { 843*7c478bd9Sstevel@tonic-gate printf("%10ld%5ld ", 844*7c478bd9Sstevel@tonic-gate head->rpcb_map.r_prog, head->rpcb_map.r_vers); 845*7c478bd9Sstevel@tonic-gate printf("%-9s ", head->rpcb_map.r_netid); 846*7c478bd9Sstevel@tonic-gate printf("%-19s", head->rpcb_map.r_addr); 847*7c478bd9Sstevel@tonic-gate rpc = getrpcbynumber(head->rpcb_map.r_prog); 848*7c478bd9Sstevel@tonic-gate if (rpc) 849*7c478bd9Sstevel@tonic-gate printf(" %-10s", rpc->r_name); 850*7c478bd9Sstevel@tonic-gate else 851*7c478bd9Sstevel@tonic-gate printf(" %-10s", "-"); 852*7c478bd9Sstevel@tonic-gate printf(" %s\n", head->rpcb_map.r_owner); 853*7c478bd9Sstevel@tonic-gate } 854*7c478bd9Sstevel@tonic-gate } else if (dumptype == RPCBDUMP_SHORT) { 855*7c478bd9Sstevel@tonic-gate for (; head != NULL; head = head->rpcb_next) { 856*7c478bd9Sstevel@tonic-gate for (rs = rs_head; rs; rs = rs->next) 857*7c478bd9Sstevel@tonic-gate if (head->rpcb_map.r_prog == rs->prog) 858*7c478bd9Sstevel@tonic-gate break; 859*7c478bd9Sstevel@tonic-gate if (rs == NULL) { 860*7c478bd9Sstevel@tonic-gate rs = (struct rpcbdump_short *) 861*7c478bd9Sstevel@tonic-gate malloc(sizeof (struct rpcbdump_short)); 862*7c478bd9Sstevel@tonic-gate if (rs == NULL) 863*7c478bd9Sstevel@tonic-gate goto error; 864*7c478bd9Sstevel@tonic-gate rs->next = NULL; 865*7c478bd9Sstevel@tonic-gate if (rs_head == NULL) { 866*7c478bd9Sstevel@tonic-gate rs_head = rs; 867*7c478bd9Sstevel@tonic-gate rs_tail = rs; 868*7c478bd9Sstevel@tonic-gate } else { 869*7c478bd9Sstevel@tonic-gate rs_tail->next = rs; 870*7c478bd9Sstevel@tonic-gate rs_tail = rs; 871*7c478bd9Sstevel@tonic-gate } 872*7c478bd9Sstevel@tonic-gate rs->prog = head->rpcb_map.r_prog; 873*7c478bd9Sstevel@tonic-gate rs->owner = head->rpcb_map.r_owner; 874*7c478bd9Sstevel@tonic-gate rs->nlist = NULL; 875*7c478bd9Sstevel@tonic-gate rs->vlist = NULL; 876*7c478bd9Sstevel@tonic-gate } 877*7c478bd9Sstevel@tonic-gate if (add_version(rs, head->rpcb_map.r_vers) == FALSE) 878*7c478bd9Sstevel@tonic-gate goto error; 879*7c478bd9Sstevel@tonic-gate if (add_netid(rs, head->rpcb_map.r_netid) == FALSE) 880*7c478bd9Sstevel@tonic-gate goto error; 881*7c478bd9Sstevel@tonic-gate } 882*7c478bd9Sstevel@tonic-gate printf( 883*7c478bd9Sstevel@tonic-gate " program version(s) netid(s) service owner\n"); 884*7c478bd9Sstevel@tonic-gate for (rs = rs_head; rs; rs = rs->next) { 885*7c478bd9Sstevel@tonic-gate char *p = buf; 886*7c478bd9Sstevel@tonic-gate 887*7c478bd9Sstevel@tonic-gate printf("%10ld ", rs->prog); 888*7c478bd9Sstevel@tonic-gate for (vl = rs->vlist; vl; vl = vl->next) { 889*7c478bd9Sstevel@tonic-gate sprintf(p, "%d", vl->vers); 890*7c478bd9Sstevel@tonic-gate p = p + strlen(p); 891*7c478bd9Sstevel@tonic-gate if (vl->next) 892*7c478bd9Sstevel@tonic-gate sprintf(p++, ","); 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate printf("%-10s", buf); 895*7c478bd9Sstevel@tonic-gate buf[0] = NULL; 896*7c478bd9Sstevel@tonic-gate for (nl = rs->nlist; nl; nl = nl->next) { 897*7c478bd9Sstevel@tonic-gate strcat(buf, nl->netid); 898*7c478bd9Sstevel@tonic-gate if (nl->next) 899*7c478bd9Sstevel@tonic-gate strcat(buf, ","); 900*7c478bd9Sstevel@tonic-gate } 901*7c478bd9Sstevel@tonic-gate printf("%-32s", buf); 902*7c478bd9Sstevel@tonic-gate rpc = getrpcbynumber(rs->prog); 903*7c478bd9Sstevel@tonic-gate if (rpc) 904*7c478bd9Sstevel@tonic-gate printf(" %-11s", rpc->r_name); 905*7c478bd9Sstevel@tonic-gate else 906*7c478bd9Sstevel@tonic-gate printf(" %-11s", "-"); 907*7c478bd9Sstevel@tonic-gate printf(" %s\n", rs->owner); 908*7c478bd9Sstevel@tonic-gate } 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate clnt_destroy(client); 911*7c478bd9Sstevel@tonic-gate return; 912*7c478bd9Sstevel@tonic-gate 913*7c478bd9Sstevel@tonic-gate error: fprintf(stderr, "rpcinfo: no memory\n"); 914*7c478bd9Sstevel@tonic-gate } 915*7c478bd9Sstevel@tonic-gate 916*7c478bd9Sstevel@tonic-gate static char nullstring[] = "\000"; 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate static void 919*7c478bd9Sstevel@tonic-gate rpcbaddrlist(netid, argc, argv) 920*7c478bd9Sstevel@tonic-gate char *netid; 921*7c478bd9Sstevel@tonic-gate int argc; 922*7c478bd9Sstevel@tonic-gate char **argv; 923*7c478bd9Sstevel@tonic-gate { 924*7c478bd9Sstevel@tonic-gate rpcb_entry_list_ptr head = NULL; 925*7c478bd9Sstevel@tonic-gate struct timeval minutetimeout; 926*7c478bd9Sstevel@tonic-gate register CLIENT *client; 927*7c478bd9Sstevel@tonic-gate struct rpcent *rpc; 928*7c478bd9Sstevel@tonic-gate char *host; 929*7c478bd9Sstevel@tonic-gate RPCB parms; 930*7c478bd9Sstevel@tonic-gate struct netbuf *targaddr; 931*7c478bd9Sstevel@tonic-gate 932*7c478bd9Sstevel@tonic-gate if (argc != 3) { 933*7c478bd9Sstevel@tonic-gate usage(); 934*7c478bd9Sstevel@tonic-gate exit(1); 935*7c478bd9Sstevel@tonic-gate } 936*7c478bd9Sstevel@tonic-gate host = argv[0]; 937*7c478bd9Sstevel@tonic-gate if (netid == NULL) { 938*7c478bd9Sstevel@tonic-gate if (loopback_netid == NULL) { 939*7c478bd9Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS4, &targaddr); 940*7c478bd9Sstevel@tonic-gate } else { 941*7c478bd9Sstevel@tonic-gate client = getclnthandle(host, loopback_nconf, RPCBVERS4, 942*7c478bd9Sstevel@tonic-gate &targaddr); 943*7c478bd9Sstevel@tonic-gate if (client == NULL && rpc_createerr.cf_stat == 944*7c478bd9Sstevel@tonic-gate RPC_N2AXLATEFAILURE) { 945*7c478bd9Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS4, &targaddr); 946*7c478bd9Sstevel@tonic-gate } 947*7c478bd9Sstevel@tonic-gate } 948*7c478bd9Sstevel@tonic-gate } else { 949*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 950*7c478bd9Sstevel@tonic-gate 951*7c478bd9Sstevel@tonic-gate nconf = getnetconfigent(netid); 952*7c478bd9Sstevel@tonic-gate if (nconf == NULL) { 953*7c478bd9Sstevel@tonic-gate nc_perror("rpcinfo: invalid transport"); 954*7c478bd9Sstevel@tonic-gate exit(1); 955*7c478bd9Sstevel@tonic-gate } 956*7c478bd9Sstevel@tonic-gate client = getclnthandle(host, nconf, RPCBVERS4, &targaddr); 957*7c478bd9Sstevel@tonic-gate if (nconf) 958*7c478bd9Sstevel@tonic-gate (void) freenetconfigent(nconf); 959*7c478bd9Sstevel@tonic-gate } 960*7c478bd9Sstevel@tonic-gate if (client == (CLIENT *)NULL) { 961*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 962*7c478bd9Sstevel@tonic-gate exit(1); 963*7c478bd9Sstevel@tonic-gate } 964*7c478bd9Sstevel@tonic-gate minutetimeout.tv_sec = 60; 965*7c478bd9Sstevel@tonic-gate minutetimeout.tv_usec = 0; 966*7c478bd9Sstevel@tonic-gate 967*7c478bd9Sstevel@tonic-gate parms.r_prog = getprognum(argv[1]); 968*7c478bd9Sstevel@tonic-gate parms.r_vers = getvers(argv[2]); 969*7c478bd9Sstevel@tonic-gate parms.r_netid = client->cl_netid; 970*7c478bd9Sstevel@tonic-gate if (targaddr == NULL) { 971*7c478bd9Sstevel@tonic-gate parms.r_addr = nullstring; /* for XDRing */ 972*7c478bd9Sstevel@tonic-gate } else { 973*7c478bd9Sstevel@tonic-gate /* 974*7c478bd9Sstevel@tonic-gate * We also send the remote system the address we 975*7c478bd9Sstevel@tonic-gate * used to contact it in case it can help it 976*7c478bd9Sstevel@tonic-gate * connect back with us 977*7c478bd9Sstevel@tonic-gate */ 978*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate nconf = getnetconfigent(client->cl_netid); 981*7c478bd9Sstevel@tonic-gate if (nconf != NULL) { 982*7c478bd9Sstevel@tonic-gate parms.r_addr = taddr2uaddr(nconf, targaddr); 983*7c478bd9Sstevel@tonic-gate if (parms.r_addr == NULL) 984*7c478bd9Sstevel@tonic-gate parms.r_addr = nullstring; 985*7c478bd9Sstevel@tonic-gate freenetconfigent(nconf); 986*7c478bd9Sstevel@tonic-gate } else { 987*7c478bd9Sstevel@tonic-gate parms.r_addr = nullstring; /* for XDRing */ 988*7c478bd9Sstevel@tonic-gate } 989*7c478bd9Sstevel@tonic-gate free(targaddr->buf); 990*7c478bd9Sstevel@tonic-gate free(targaddr); 991*7c478bd9Sstevel@tonic-gate } 992*7c478bd9Sstevel@tonic-gate parms.r_owner = nullstring; 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate if (CLNT_CALL(client, RPCBPROC_GETADDRLIST, (xdrproc_t)xdr_rpcb, 995*7c478bd9Sstevel@tonic-gate (char *)&parms, (xdrproc_t)xdr_rpcb_entry_list_ptr, 996*7c478bd9Sstevel@tonic-gate (char *)&head, minutetimeout) != RPC_SUCCESS) { 997*7c478bd9Sstevel@tonic-gate clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 998*7c478bd9Sstevel@tonic-gate exit(1); 999*7c478bd9Sstevel@tonic-gate } 1000*7c478bd9Sstevel@tonic-gate if (head == NULL) { 1001*7c478bd9Sstevel@tonic-gate printf("No remote programs registered.\n"); 1002*7c478bd9Sstevel@tonic-gate } else { 1003*7c478bd9Sstevel@tonic-gate printf( 1004*7c478bd9Sstevel@tonic-gate " program vers tp_family/name/class address\t\t service\n"); 1005*7c478bd9Sstevel@tonic-gate for (; head != NULL; head = head->rpcb_entry_next) { 1006*7c478bd9Sstevel@tonic-gate rpcb_entry *re; 1007*7c478bd9Sstevel@tonic-gate char buf[128]; 1008*7c478bd9Sstevel@tonic-gate 1009*7c478bd9Sstevel@tonic-gate re = &head->rpcb_entry_map; 1010*7c478bd9Sstevel@tonic-gate printf("%10ld%3ld ", 1011*7c478bd9Sstevel@tonic-gate parms.r_prog, parms.r_vers); 1012*7c478bd9Sstevel@tonic-gate sprintf(buf, "%s/%s/%s ", 1013*7c478bd9Sstevel@tonic-gate re->r_nc_protofmly, re->r_nc_proto, 1014*7c478bd9Sstevel@tonic-gate re->r_nc_semantics == NC_TPI_CLTS ? "clts" : 1015*7c478bd9Sstevel@tonic-gate re->r_nc_semantics == NC_TPI_COTS ? "cots" : 1016*7c478bd9Sstevel@tonic-gate "cots_ord"); 1017*7c478bd9Sstevel@tonic-gate printf("%-24s", buf); 1018*7c478bd9Sstevel@tonic-gate printf("%-24s", re->r_maddr); 1019*7c478bd9Sstevel@tonic-gate rpc = getrpcbynumber(parms.r_prog); 1020*7c478bd9Sstevel@tonic-gate if (rpc) 1021*7c478bd9Sstevel@tonic-gate printf(" %-13s", rpc->r_name); 1022*7c478bd9Sstevel@tonic-gate else 1023*7c478bd9Sstevel@tonic-gate printf(" %-13s", "-"); 1024*7c478bd9Sstevel@tonic-gate printf("\n"); 1025*7c478bd9Sstevel@tonic-gate } 1026*7c478bd9Sstevel@tonic-gate } 1027*7c478bd9Sstevel@tonic-gate clnt_destroy(client); 1028*7c478bd9Sstevel@tonic-gate } 1029*7c478bd9Sstevel@tonic-gate 1030*7c478bd9Sstevel@tonic-gate /* 1031*7c478bd9Sstevel@tonic-gate * monitor rpcbind 1032*7c478bd9Sstevel@tonic-gate */ 1033*7c478bd9Sstevel@tonic-gate static void 1034*7c478bd9Sstevel@tonic-gate rpcbgetstat(argc, argv) 1035*7c478bd9Sstevel@tonic-gate int argc; 1036*7c478bd9Sstevel@tonic-gate char **argv; 1037*7c478bd9Sstevel@tonic-gate { 1038*7c478bd9Sstevel@tonic-gate rpcb_stat_byvers inf; 1039*7c478bd9Sstevel@tonic-gate struct timeval minutetimeout; 1040*7c478bd9Sstevel@tonic-gate register CLIENT *client; 1041*7c478bd9Sstevel@tonic-gate char *host; 1042*7c478bd9Sstevel@tonic-gate int i, j; 1043*7c478bd9Sstevel@tonic-gate rpcbs_addrlist *pa; 1044*7c478bd9Sstevel@tonic-gate rpcbs_rmtcalllist *pr; 1045*7c478bd9Sstevel@tonic-gate int cnt, flen; 1046*7c478bd9Sstevel@tonic-gate struct utsname utsname; 1047*7c478bd9Sstevel@tonic-gate #define MAXFIELD 64 1048*7c478bd9Sstevel@tonic-gate char fieldbuf[MAXFIELD]; 1049*7c478bd9Sstevel@tonic-gate #define MAXLINE 256 1050*7c478bd9Sstevel@tonic-gate char linebuf[MAXLINE]; 1051*7c478bd9Sstevel@tonic-gate char *cp, *bp, *lp; 1052*7c478bd9Sstevel@tonic-gate char *pmaphdr[] = { 1053*7c478bd9Sstevel@tonic-gate "NULL", "SET", "UNSET", "GETPORT", 1054*7c478bd9Sstevel@tonic-gate "DUMP", "CALLIT" 1055*7c478bd9Sstevel@tonic-gate }; 1056*7c478bd9Sstevel@tonic-gate char *rpcb3hdr[] = { 1057*7c478bd9Sstevel@tonic-gate "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME", 1058*7c478bd9Sstevel@tonic-gate "U2T", "T2U" 1059*7c478bd9Sstevel@tonic-gate }; 1060*7c478bd9Sstevel@tonic-gate char *rpcb4hdr[] = { 1061*7c478bd9Sstevel@tonic-gate "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME", 1062*7c478bd9Sstevel@tonic-gate "U2T", "T2U", "VERADDR", "INDRECT", "GETLIST", "GETSTAT" 1063*7c478bd9Sstevel@tonic-gate }; 1064*7c478bd9Sstevel@tonic-gate 1065*7c478bd9Sstevel@tonic-gate #define TABSTOP 8 1066*7c478bd9Sstevel@tonic-gate 1067*7c478bd9Sstevel@tonic-gate if (argc >= 1) { 1068*7c478bd9Sstevel@tonic-gate host = argv[0]; 1069*7c478bd9Sstevel@tonic-gate } else { 1070*7c478bd9Sstevel@tonic-gate uname(&utsname); 1071*7c478bd9Sstevel@tonic-gate host = utsname.nodename; 1072*7c478bd9Sstevel@tonic-gate } 1073*7c478bd9Sstevel@tonic-gate if (loopback_netid != NULL) { 1074*7c478bd9Sstevel@tonic-gate client = getclnthandle(host, loopback_nconf, RPCBVERS4, NULL); 1075*7c478bd9Sstevel@tonic-gate if (client == NULL && rpc_createerr.cf_stat == 1076*7c478bd9Sstevel@tonic-gate RPC_N2AXLATEFAILURE) { 1077*7c478bd9Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS4, NULL); 1078*7c478bd9Sstevel@tonic-gate } 1079*7c478bd9Sstevel@tonic-gate } else { 1080*7c478bd9Sstevel@tonic-gate client = clnt_rpcbind_create(host, RPCBVERS4, NULL); 1081*7c478bd9Sstevel@tonic-gate } 1082*7c478bd9Sstevel@tonic-gate if (client == (CLIENT *)NULL) { 1083*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 1084*7c478bd9Sstevel@tonic-gate exit(1); 1085*7c478bd9Sstevel@tonic-gate } 1086*7c478bd9Sstevel@tonic-gate minutetimeout.tv_sec = 60; 1087*7c478bd9Sstevel@tonic-gate minutetimeout.tv_usec = 0; 1088*7c478bd9Sstevel@tonic-gate memset((char *)&inf, 0, sizeof (rpcb_stat_byvers)); 1089*7c478bd9Sstevel@tonic-gate if (CLNT_CALL(client, RPCBPROC_GETSTAT, (xdrproc_t)xdr_void, NULL, 1090*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_rpcb_stat_byvers, (char *)&inf, minutetimeout) 1091*7c478bd9Sstevel@tonic-gate != RPC_SUCCESS) { 1092*7c478bd9Sstevel@tonic-gate clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 1093*7c478bd9Sstevel@tonic-gate exit(1); 1094*7c478bd9Sstevel@tonic-gate } 1095*7c478bd9Sstevel@tonic-gate printf("PORTMAP (version 2) statistics\n"); 1096*7c478bd9Sstevel@tonic-gate lp = linebuf; 1097*7c478bd9Sstevel@tonic-gate for (i = 0; i <= rpcb_highproc_2; i++) { 1098*7c478bd9Sstevel@tonic-gate fieldbuf[0] = '\0'; 1099*7c478bd9Sstevel@tonic-gate switch (i) { 1100*7c478bd9Sstevel@tonic-gate case PMAPPROC_SET: 1101*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", inf[RPCBVERS_2_STAT].setinfo); 1102*7c478bd9Sstevel@tonic-gate break; 1103*7c478bd9Sstevel@tonic-gate case PMAPPROC_UNSET: 1104*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", 1105*7c478bd9Sstevel@tonic-gate inf[RPCBVERS_2_STAT].unsetinfo); 1106*7c478bd9Sstevel@tonic-gate break; 1107*7c478bd9Sstevel@tonic-gate case PMAPPROC_GETPORT: 1108*7c478bd9Sstevel@tonic-gate cnt = 0; 1109*7c478bd9Sstevel@tonic-gate for (pa = inf[RPCBVERS_2_STAT].addrinfo; pa; 1110*7c478bd9Sstevel@tonic-gate pa = pa->next) 1111*7c478bd9Sstevel@tonic-gate cnt += pa->success; 1112*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", cnt); 1113*7c478bd9Sstevel@tonic-gate break; 1114*7c478bd9Sstevel@tonic-gate case PMAPPROC_CALLIT: 1115*7c478bd9Sstevel@tonic-gate cnt = 0; 1116*7c478bd9Sstevel@tonic-gate for (pr = inf[RPCBVERS_2_STAT].rmtinfo; pr; 1117*7c478bd9Sstevel@tonic-gate pr = pr->next) 1118*7c478bd9Sstevel@tonic-gate cnt += pr->success; 1119*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", cnt); 1120*7c478bd9Sstevel@tonic-gate break; 1121*7c478bd9Sstevel@tonic-gate default: break; /* For the remaining ones */ 1122*7c478bd9Sstevel@tonic-gate } 1123*7c478bd9Sstevel@tonic-gate cp = &fieldbuf[0] + strlen(fieldbuf); 1124*7c478bd9Sstevel@tonic-gate sprintf(cp, "%d", inf[RPCBVERS_2_STAT].info[i]); 1125*7c478bd9Sstevel@tonic-gate flen = strlen(fieldbuf); 1126*7c478bd9Sstevel@tonic-gate printf("%s%s", pmaphdr[i], 1127*7c478bd9Sstevel@tonic-gate spaces((TABSTOP * (1 + flen / TABSTOP)) 1128*7c478bd9Sstevel@tonic-gate - strlen(pmaphdr[i]))); 1129*7c478bd9Sstevel@tonic-gate sprintf(lp, "%s%s", fieldbuf, 1130*7c478bd9Sstevel@tonic-gate spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 1131*7c478bd9Sstevel@tonic-gate - flen))); 1132*7c478bd9Sstevel@tonic-gate lp += (flen + cnt); 1133*7c478bd9Sstevel@tonic-gate } 1134*7c478bd9Sstevel@tonic-gate printf("\n%s\n\n", linebuf); 1135*7c478bd9Sstevel@tonic-gate 1136*7c478bd9Sstevel@tonic-gate if (inf[RPCBVERS_2_STAT].info[PMAPPROC_CALLIT]) { 1137*7c478bd9Sstevel@tonic-gate printf("PMAP_RMTCALL call statistics\n"); 1138*7c478bd9Sstevel@tonic-gate print_rmtcallstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]); 1139*7c478bd9Sstevel@tonic-gate printf("\n"); 1140*7c478bd9Sstevel@tonic-gate } 1141*7c478bd9Sstevel@tonic-gate 1142*7c478bd9Sstevel@tonic-gate if (inf[RPCBVERS_2_STAT].info[PMAPPROC_GETPORT]) { 1143*7c478bd9Sstevel@tonic-gate printf("PMAP_GETPORT call statistics\n"); 1144*7c478bd9Sstevel@tonic-gate print_getaddrstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]); 1145*7c478bd9Sstevel@tonic-gate printf("\n"); 1146*7c478bd9Sstevel@tonic-gate } 1147*7c478bd9Sstevel@tonic-gate 1148*7c478bd9Sstevel@tonic-gate printf("RPCBIND (version 3) statistics\n"); 1149*7c478bd9Sstevel@tonic-gate lp = linebuf; 1150*7c478bd9Sstevel@tonic-gate for (i = 0; i <= rpcb_highproc_3; i++) { 1151*7c478bd9Sstevel@tonic-gate fieldbuf[0] = '\0'; 1152*7c478bd9Sstevel@tonic-gate switch (i) { 1153*7c478bd9Sstevel@tonic-gate case RPCBPROC_SET: 1154*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", inf[RPCBVERS_3_STAT].setinfo); 1155*7c478bd9Sstevel@tonic-gate break; 1156*7c478bd9Sstevel@tonic-gate case RPCBPROC_UNSET: 1157*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", 1158*7c478bd9Sstevel@tonic-gate inf[RPCBVERS_3_STAT].unsetinfo); 1159*7c478bd9Sstevel@tonic-gate break; 1160*7c478bd9Sstevel@tonic-gate case RPCBPROC_GETADDR: 1161*7c478bd9Sstevel@tonic-gate cnt = 0; 1162*7c478bd9Sstevel@tonic-gate for (pa = inf[RPCBVERS_3_STAT].addrinfo; pa; 1163*7c478bd9Sstevel@tonic-gate pa = pa->next) 1164*7c478bd9Sstevel@tonic-gate cnt += pa->success; 1165*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", cnt); 1166*7c478bd9Sstevel@tonic-gate break; 1167*7c478bd9Sstevel@tonic-gate case RPCBPROC_CALLIT: 1168*7c478bd9Sstevel@tonic-gate cnt = 0; 1169*7c478bd9Sstevel@tonic-gate for (pr = inf[RPCBVERS_3_STAT].rmtinfo; pr; 1170*7c478bd9Sstevel@tonic-gate pr = pr->next) 1171*7c478bd9Sstevel@tonic-gate cnt += pr->success; 1172*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", cnt); 1173*7c478bd9Sstevel@tonic-gate break; 1174*7c478bd9Sstevel@tonic-gate default: break; /* For the remaining ones */ 1175*7c478bd9Sstevel@tonic-gate } 1176*7c478bd9Sstevel@tonic-gate cp = &fieldbuf[0] + strlen(fieldbuf); 1177*7c478bd9Sstevel@tonic-gate sprintf(cp, "%d", inf[RPCBVERS_3_STAT].info[i]); 1178*7c478bd9Sstevel@tonic-gate flen = strlen(fieldbuf); 1179*7c478bd9Sstevel@tonic-gate printf("%s%s", rpcb3hdr[i], 1180*7c478bd9Sstevel@tonic-gate spaces((TABSTOP * (1 + flen / TABSTOP)) 1181*7c478bd9Sstevel@tonic-gate - strlen(rpcb3hdr[i]))); 1182*7c478bd9Sstevel@tonic-gate sprintf(lp, "%s%s", fieldbuf, 1183*7c478bd9Sstevel@tonic-gate spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 1184*7c478bd9Sstevel@tonic-gate - flen))); 1185*7c478bd9Sstevel@tonic-gate lp += (flen + cnt); 1186*7c478bd9Sstevel@tonic-gate } 1187*7c478bd9Sstevel@tonic-gate printf("\n%s\n\n", linebuf); 1188*7c478bd9Sstevel@tonic-gate 1189*7c478bd9Sstevel@tonic-gate if (inf[RPCBVERS_3_STAT].info[RPCBPROC_CALLIT]) { 1190*7c478bd9Sstevel@tonic-gate printf("RPCB_RMTCALL (version 3) call statistics\n"); 1191*7c478bd9Sstevel@tonic-gate print_rmtcallstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]); 1192*7c478bd9Sstevel@tonic-gate printf("\n"); 1193*7c478bd9Sstevel@tonic-gate } 1194*7c478bd9Sstevel@tonic-gate 1195*7c478bd9Sstevel@tonic-gate if (inf[RPCBVERS_3_STAT].info[RPCBPROC_GETADDR]) { 1196*7c478bd9Sstevel@tonic-gate printf("RPCB_GETADDR (version 3) call statistics\n"); 1197*7c478bd9Sstevel@tonic-gate print_getaddrstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]); 1198*7c478bd9Sstevel@tonic-gate printf("\n"); 1199*7c478bd9Sstevel@tonic-gate } 1200*7c478bd9Sstevel@tonic-gate 1201*7c478bd9Sstevel@tonic-gate printf("RPCBIND (version 4) statistics\n"); 1202*7c478bd9Sstevel@tonic-gate 1203*7c478bd9Sstevel@tonic-gate for (j = 0; j <= 9; j += 9) { /* Just two iterations for printing */ 1204*7c478bd9Sstevel@tonic-gate lp = linebuf; 1205*7c478bd9Sstevel@tonic-gate for (i = j; i <= MAX(8, rpcb_highproc_4 - 9 + j); i++) { 1206*7c478bd9Sstevel@tonic-gate fieldbuf[0] = '\0'; 1207*7c478bd9Sstevel@tonic-gate switch (i) { 1208*7c478bd9Sstevel@tonic-gate case RPCBPROC_SET: 1209*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", 1210*7c478bd9Sstevel@tonic-gate inf[RPCBVERS_4_STAT].setinfo); 1211*7c478bd9Sstevel@tonic-gate break; 1212*7c478bd9Sstevel@tonic-gate case RPCBPROC_UNSET: 1213*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", 1214*7c478bd9Sstevel@tonic-gate inf[RPCBVERS_4_STAT].unsetinfo); 1215*7c478bd9Sstevel@tonic-gate break; 1216*7c478bd9Sstevel@tonic-gate case RPCBPROC_GETADDR: 1217*7c478bd9Sstevel@tonic-gate cnt = 0; 1218*7c478bd9Sstevel@tonic-gate for (pa = inf[RPCBVERS_4_STAT].addrinfo; pa; 1219*7c478bd9Sstevel@tonic-gate pa = pa->next) 1220*7c478bd9Sstevel@tonic-gate cnt += pa->success; 1221*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", cnt); 1222*7c478bd9Sstevel@tonic-gate break; 1223*7c478bd9Sstevel@tonic-gate case RPCBPROC_CALLIT: 1224*7c478bd9Sstevel@tonic-gate cnt = 0; 1225*7c478bd9Sstevel@tonic-gate for (pr = inf[RPCBVERS_4_STAT].rmtinfo; pr; 1226*7c478bd9Sstevel@tonic-gate pr = pr->next) 1227*7c478bd9Sstevel@tonic-gate cnt += pr->success; 1228*7c478bd9Sstevel@tonic-gate sprintf(fieldbuf, "%d/", cnt); 1229*7c478bd9Sstevel@tonic-gate break; 1230*7c478bd9Sstevel@tonic-gate default: break; /* For the remaining ones */ 1231*7c478bd9Sstevel@tonic-gate } 1232*7c478bd9Sstevel@tonic-gate cp = &fieldbuf[0] + strlen(fieldbuf); 1233*7c478bd9Sstevel@tonic-gate /* 1234*7c478bd9Sstevel@tonic-gate * XXX: We also add RPCBPROC_GETADDRLIST queries to 1235*7c478bd9Sstevel@tonic-gate * RPCB_GETADDR because rpcbind includes the 1236*7c478bd9Sstevel@tonic-gate * RPCB_GETADDRLIST successes in RPCB_GETADDR. 1237*7c478bd9Sstevel@tonic-gate */ 1238*7c478bd9Sstevel@tonic-gate if (i != RPCBPROC_GETADDR) 1239*7c478bd9Sstevel@tonic-gate sprintf(cp, "%d", inf[RPCBVERS_4_STAT].info[i]); 1240*7c478bd9Sstevel@tonic-gate else 1241*7c478bd9Sstevel@tonic-gate sprintf(cp, "%d", inf[RPCBVERS_4_STAT].info[i] + 1242*7c478bd9Sstevel@tonic-gate inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDRLIST]); 1243*7c478bd9Sstevel@tonic-gate flen = strlen(fieldbuf); 1244*7c478bd9Sstevel@tonic-gate printf("%s%s", rpcb4hdr[i], 1245*7c478bd9Sstevel@tonic-gate spaces((TABSTOP * (1 + flen / TABSTOP)) 1246*7c478bd9Sstevel@tonic-gate - strlen(rpcb4hdr[i]))); 1247*7c478bd9Sstevel@tonic-gate sprintf(lp, "%s%s", fieldbuf, 1248*7c478bd9Sstevel@tonic-gate spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 1249*7c478bd9Sstevel@tonic-gate - flen))); 1250*7c478bd9Sstevel@tonic-gate lp += (flen + cnt); 1251*7c478bd9Sstevel@tonic-gate } 1252*7c478bd9Sstevel@tonic-gate printf("\n%s\n", linebuf); 1253*7c478bd9Sstevel@tonic-gate } 1254*7c478bd9Sstevel@tonic-gate 1255*7c478bd9Sstevel@tonic-gate if (inf[RPCBVERS_4_STAT].info[RPCBPROC_CALLIT] || 1256*7c478bd9Sstevel@tonic-gate inf[RPCBVERS_4_STAT].info[RPCBPROC_INDIRECT]) { 1257*7c478bd9Sstevel@tonic-gate printf("\n"); 1258*7c478bd9Sstevel@tonic-gate printf("RPCB_RMTCALL (version 4) call statistics\n"); 1259*7c478bd9Sstevel@tonic-gate print_rmtcallstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]); 1260*7c478bd9Sstevel@tonic-gate } 1261*7c478bd9Sstevel@tonic-gate 1262*7c478bd9Sstevel@tonic-gate if (inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDR]) { 1263*7c478bd9Sstevel@tonic-gate printf("\n"); 1264*7c478bd9Sstevel@tonic-gate printf("RPCB_GETADDR (version 4) call statistics\n"); 1265*7c478bd9Sstevel@tonic-gate print_getaddrstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]); 1266*7c478bd9Sstevel@tonic-gate } 1267*7c478bd9Sstevel@tonic-gate clnt_destroy(client); 1268*7c478bd9Sstevel@tonic-gate } 1269*7c478bd9Sstevel@tonic-gate 1270*7c478bd9Sstevel@tonic-gate /* 1271*7c478bd9Sstevel@tonic-gate * Delete registeration for this (prog, vers, netid) 1272*7c478bd9Sstevel@tonic-gate */ 1273*7c478bd9Sstevel@tonic-gate static void 1274*7c478bd9Sstevel@tonic-gate deletereg(netid, argc, argv) 1275*7c478bd9Sstevel@tonic-gate char *netid; 1276*7c478bd9Sstevel@tonic-gate int argc; 1277*7c478bd9Sstevel@tonic-gate char **argv; 1278*7c478bd9Sstevel@tonic-gate { 1279*7c478bd9Sstevel@tonic-gate struct netconfig *nconf = NULL; 1280*7c478bd9Sstevel@tonic-gate 1281*7c478bd9Sstevel@tonic-gate if (argc != 2) { 1282*7c478bd9Sstevel@tonic-gate usage(); 1283*7c478bd9Sstevel@tonic-gate exit(1); 1284*7c478bd9Sstevel@tonic-gate } 1285*7c478bd9Sstevel@tonic-gate if (netid) { 1286*7c478bd9Sstevel@tonic-gate nconf = getnetconfigent(netid); 1287*7c478bd9Sstevel@tonic-gate if (nconf == NULL) { 1288*7c478bd9Sstevel@tonic-gate fprintf(stderr, "rpcinfo: netid %s not supported\n", 1289*7c478bd9Sstevel@tonic-gate netid); 1290*7c478bd9Sstevel@tonic-gate exit(1); 1291*7c478bd9Sstevel@tonic-gate } 1292*7c478bd9Sstevel@tonic-gate } 1293*7c478bd9Sstevel@tonic-gate if ((rpcb_unset(getprognum(argv[0]), getvers(argv[1]), nconf)) == 0) { 1294*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1295*7c478bd9Sstevel@tonic-gate "rpcinfo: Could not delete registration for prog %s version %s\n", 1296*7c478bd9Sstevel@tonic-gate argv[0], argv[1]); 1297*7c478bd9Sstevel@tonic-gate exit(1); 1298*7c478bd9Sstevel@tonic-gate } 1299*7c478bd9Sstevel@tonic-gate } 1300*7c478bd9Sstevel@tonic-gate 1301*7c478bd9Sstevel@tonic-gate /* 1302*7c478bd9Sstevel@tonic-gate * Create and return a handle for the given nconf. 1303*7c478bd9Sstevel@tonic-gate * Exit if cannot create handle. 1304*7c478bd9Sstevel@tonic-gate */ 1305*7c478bd9Sstevel@tonic-gate static CLIENT * 1306*7c478bd9Sstevel@tonic-gate clnt_addr_create(address, nconf, prog, vers) 1307*7c478bd9Sstevel@tonic-gate char *address; 1308*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 1309*7c478bd9Sstevel@tonic-gate ulong_t prog; 1310*7c478bd9Sstevel@tonic-gate ulong_t vers; 1311*7c478bd9Sstevel@tonic-gate { 1312*7c478bd9Sstevel@tonic-gate CLIENT *client; 1313*7c478bd9Sstevel@tonic-gate static struct netbuf *nbuf; 1314*7c478bd9Sstevel@tonic-gate static int fd = RPC_ANYFD; 1315*7c478bd9Sstevel@tonic-gate struct t_info tinfo; 1316*7c478bd9Sstevel@tonic-gate 1317*7c478bd9Sstevel@tonic-gate if (fd == RPC_ANYFD) { 1318*7c478bd9Sstevel@tonic-gate if ((fd = t_open(nconf->nc_device, O_RDWR, &tinfo)) == -1) { 1319*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_TLIERROR; 1320*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_error.re_terrno = t_errno; 1321*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("rpcinfo"); 1322*7c478bd9Sstevel@tonic-gate exit(1); 1323*7c478bd9Sstevel@tonic-gate } 1324*7c478bd9Sstevel@tonic-gate /* Convert the uaddr to taddr */ 1325*7c478bd9Sstevel@tonic-gate nbuf = uaddr2taddr(nconf, address); 1326*7c478bd9Sstevel@tonic-gate if (nbuf == NULL) { 1327*7c478bd9Sstevel@tonic-gate netdir_perror("rpcinfo"); 1328*7c478bd9Sstevel@tonic-gate exit(1); 1329*7c478bd9Sstevel@tonic-gate } 1330*7c478bd9Sstevel@tonic-gate } 1331*7c478bd9Sstevel@tonic-gate client = clnt_tli_create(fd, nconf, nbuf, prog, vers, 0, 0); 1332*7c478bd9Sstevel@tonic-gate if (client == (CLIENT *)NULL) { 1333*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("rpcinfo"); 1334*7c478bd9Sstevel@tonic-gate exit(1); 1335*7c478bd9Sstevel@tonic-gate } 1336*7c478bd9Sstevel@tonic-gate return (client); 1337*7c478bd9Sstevel@tonic-gate } 1338*7c478bd9Sstevel@tonic-gate 1339*7c478bd9Sstevel@tonic-gate /* 1340*7c478bd9Sstevel@tonic-gate * If the version number is given, ping that (prog, vers); else try to find 1341*7c478bd9Sstevel@tonic-gate * the version numbers supported for that prog and ping all the versions. 1342*7c478bd9Sstevel@tonic-gate * Remote rpcbind is not contacted for this service. The requests are 1343*7c478bd9Sstevel@tonic-gate * sent directly to the services themselves. 1344*7c478bd9Sstevel@tonic-gate */ 1345*7c478bd9Sstevel@tonic-gate static void 1346*7c478bd9Sstevel@tonic-gate addrping(address, netid, argc, argv) 1347*7c478bd9Sstevel@tonic-gate char *address; 1348*7c478bd9Sstevel@tonic-gate char *netid; 1349*7c478bd9Sstevel@tonic-gate int argc; 1350*7c478bd9Sstevel@tonic-gate char **argv; 1351*7c478bd9Sstevel@tonic-gate { 1352*7c478bd9Sstevel@tonic-gate CLIENT *client; 1353*7c478bd9Sstevel@tonic-gate struct timeval to; 1354*7c478bd9Sstevel@tonic-gate enum clnt_stat rpc_stat; 1355*7c478bd9Sstevel@tonic-gate ulong_t prognum, versnum, minvers, maxvers; 1356*7c478bd9Sstevel@tonic-gate struct rpc_err rpcerr; 1357*7c478bd9Sstevel@tonic-gate int failure = 0; 1358*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 1359*7c478bd9Sstevel@tonic-gate int fd; 1360*7c478bd9Sstevel@tonic-gate 1361*7c478bd9Sstevel@tonic-gate if (argc < 1 || argc > 2 || (netid == NULL)) { 1362*7c478bd9Sstevel@tonic-gate usage(); 1363*7c478bd9Sstevel@tonic-gate exit(1); 1364*7c478bd9Sstevel@tonic-gate } 1365*7c478bd9Sstevel@tonic-gate nconf = getnetconfigent(netid); 1366*7c478bd9Sstevel@tonic-gate if (nconf == (struct netconfig *)NULL) { 1367*7c478bd9Sstevel@tonic-gate fprintf(stderr, "rpcinfo: Could not find %s\n", netid); 1368*7c478bd9Sstevel@tonic-gate exit(1); 1369*7c478bd9Sstevel@tonic-gate } 1370*7c478bd9Sstevel@tonic-gate to.tv_sec = 10; 1371*7c478bd9Sstevel@tonic-gate to.tv_usec = 0; 1372*7c478bd9Sstevel@tonic-gate prognum = getprognum(argv[0]); 1373*7c478bd9Sstevel@tonic-gate if (argc == 1) { /* Version number not known */ 1374*7c478bd9Sstevel@tonic-gate /* 1375*7c478bd9Sstevel@tonic-gate * A call to version 0 should fail with a program/version 1376*7c478bd9Sstevel@tonic-gate * mismatch, and give us the range of versions supported. 1377*7c478bd9Sstevel@tonic-gate */ 1378*7c478bd9Sstevel@tonic-gate versnum = MIN_VERS; 1379*7c478bd9Sstevel@tonic-gate } else { 1380*7c478bd9Sstevel@tonic-gate versnum = getvers(argv[1]); 1381*7c478bd9Sstevel@tonic-gate } 1382*7c478bd9Sstevel@tonic-gate client = clnt_addr_create(address, nconf, prognum, versnum); 1383*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void, 1384*7c478bd9Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, 1385*7c478bd9Sstevel@tonic-gate (char *)NULL, to); 1386*7c478bd9Sstevel@tonic-gate if (argc == 2) { 1387*7c478bd9Sstevel@tonic-gate /* Version number was known */ 1388*7c478bd9Sstevel@tonic-gate if (pstatus(client, prognum, versnum) < 0) 1389*7c478bd9Sstevel@tonic-gate failure = 1; 1390*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 1391*7c478bd9Sstevel@tonic-gate if (failure) 1392*7c478bd9Sstevel@tonic-gate exit(1); 1393*7c478bd9Sstevel@tonic-gate return; 1394*7c478bd9Sstevel@tonic-gate } 1395*7c478bd9Sstevel@tonic-gate /* Version number not known */ 1396*7c478bd9Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL); 1397*7c478bd9Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLGET_FD, (char *)&fd); 1398*7c478bd9Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) { 1399*7c478bd9Sstevel@tonic-gate clnt_geterr(client, &rpcerr); 1400*7c478bd9Sstevel@tonic-gate minvers = rpcerr.re_vers.low; 1401*7c478bd9Sstevel@tonic-gate maxvers = rpcerr.re_vers.high; 1402*7c478bd9Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) { 1403*7c478bd9Sstevel@tonic-gate /* 1404*7c478bd9Sstevel@tonic-gate * Oh dear, it DOES support version 0. 1405*7c478bd9Sstevel@tonic-gate * Let's try version MAX_VERS. 1406*7c478bd9Sstevel@tonic-gate */ 1407*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 1408*7c478bd9Sstevel@tonic-gate client = clnt_addr_create(address, nconf, prognum, MAX_VERS); 1409*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void, 1410*7c478bd9Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, 1411*7c478bd9Sstevel@tonic-gate (char *)NULL, to); 1412*7c478bd9Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) { 1413*7c478bd9Sstevel@tonic-gate clnt_geterr(client, &rpcerr); 1414*7c478bd9Sstevel@tonic-gate minvers = rpcerr.re_vers.low; 1415*7c478bd9Sstevel@tonic-gate maxvers = rpcerr.re_vers.high; 1416*7c478bd9Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) { 1417*7c478bd9Sstevel@tonic-gate /* 1418*7c478bd9Sstevel@tonic-gate * It also supports version MAX_VERS. 1419*7c478bd9Sstevel@tonic-gate * Looks like we have a wise guy. 1420*7c478bd9Sstevel@tonic-gate * OK, we give them information on all 1421*7c478bd9Sstevel@tonic-gate * 4 billion versions they support... 1422*7c478bd9Sstevel@tonic-gate */ 1423*7c478bd9Sstevel@tonic-gate minvers = 0; 1424*7c478bd9Sstevel@tonic-gate maxvers = MAX_VERS; 1425*7c478bd9Sstevel@tonic-gate } else { 1426*7c478bd9Sstevel@tonic-gate (void) pstatus(client, prognum, MAX_VERS); 1427*7c478bd9Sstevel@tonic-gate exit(1); 1428*7c478bd9Sstevel@tonic-gate } 1429*7c478bd9Sstevel@tonic-gate } else { 1430*7c478bd9Sstevel@tonic-gate (void) pstatus(client, prognum, (ulong_t)0); 1431*7c478bd9Sstevel@tonic-gate exit(1); 1432*7c478bd9Sstevel@tonic-gate } 1433*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 1434*7c478bd9Sstevel@tonic-gate for (versnum = minvers; versnum <= maxvers; versnum++) { 1435*7c478bd9Sstevel@tonic-gate client = clnt_addr_create(address, nconf, prognum, versnum); 1436*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void, 1437*7c478bd9Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, 1438*7c478bd9Sstevel@tonic-gate (char *)NULL, to); 1439*7c478bd9Sstevel@tonic-gate if (pstatus(client, prognum, versnum) < 0) 1440*7c478bd9Sstevel@tonic-gate failure = 1; 1441*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 1442*7c478bd9Sstevel@tonic-gate } 1443*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 1444*7c478bd9Sstevel@tonic-gate if (failure) 1445*7c478bd9Sstevel@tonic-gate exit(1); 1446*7c478bd9Sstevel@tonic-gate } 1447*7c478bd9Sstevel@tonic-gate 1448*7c478bd9Sstevel@tonic-gate /* 1449*7c478bd9Sstevel@tonic-gate * If the version number is given, ping that (prog, vers); else try to find 1450*7c478bd9Sstevel@tonic-gate * the version numbers supported for that prog and ping all the versions. 1451*7c478bd9Sstevel@tonic-gate * Remote rpcbind is *contacted* for this service. The requests are 1452*7c478bd9Sstevel@tonic-gate * then sent directly to the services themselves. 1453*7c478bd9Sstevel@tonic-gate */ 1454*7c478bd9Sstevel@tonic-gate static void 1455*7c478bd9Sstevel@tonic-gate progping(netid, argc, argv) 1456*7c478bd9Sstevel@tonic-gate char *netid; 1457*7c478bd9Sstevel@tonic-gate int argc; 1458*7c478bd9Sstevel@tonic-gate char **argv; 1459*7c478bd9Sstevel@tonic-gate { 1460*7c478bd9Sstevel@tonic-gate CLIENT *client; 1461*7c478bd9Sstevel@tonic-gate struct timeval to; 1462*7c478bd9Sstevel@tonic-gate enum clnt_stat rpc_stat; 1463*7c478bd9Sstevel@tonic-gate ulong_t prognum, versnum, minvers, maxvers; 1464*7c478bd9Sstevel@tonic-gate struct rpc_err rpcerr; 1465*7c478bd9Sstevel@tonic-gate int failure = 0; 1466*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 1467*7c478bd9Sstevel@tonic-gate int fd; 1468*7c478bd9Sstevel@tonic-gate 1469*7c478bd9Sstevel@tonic-gate if (argc < 2 || argc > 3 || (netid == NULL)) { 1470*7c478bd9Sstevel@tonic-gate usage(); 1471*7c478bd9Sstevel@tonic-gate exit(1); 1472*7c478bd9Sstevel@tonic-gate } 1473*7c478bd9Sstevel@tonic-gate prognum = getprognum(argv[1]); 1474*7c478bd9Sstevel@tonic-gate if (argc == 2) { /* Version number not known */ 1475*7c478bd9Sstevel@tonic-gate /* 1476*7c478bd9Sstevel@tonic-gate * A call to version 0 should fail with a program/version 1477*7c478bd9Sstevel@tonic-gate * mismatch, and give us the range of versions supported. 1478*7c478bd9Sstevel@tonic-gate */ 1479*7c478bd9Sstevel@tonic-gate versnum = MIN_VERS; 1480*7c478bd9Sstevel@tonic-gate } else { 1481*7c478bd9Sstevel@tonic-gate versnum = getvers(argv[2]); 1482*7c478bd9Sstevel@tonic-gate } 1483*7c478bd9Sstevel@tonic-gate if (netid) { 1484*7c478bd9Sstevel@tonic-gate nconf = getnetconfigent(netid); 1485*7c478bd9Sstevel@tonic-gate if (nconf == (struct netconfig *)NULL) { 1486*7c478bd9Sstevel@tonic-gate fprintf(stderr, "rpcinfo: Could not find %s\n", netid); 1487*7c478bd9Sstevel@tonic-gate exit(1); 1488*7c478bd9Sstevel@tonic-gate } 1489*7c478bd9Sstevel@tonic-gate client = clnt_tp_create(argv[0], prognum, versnum, nconf); 1490*7c478bd9Sstevel@tonic-gate } else { 1491*7c478bd9Sstevel@tonic-gate client = clnt_create(argv[0], prognum, versnum, "NETPATH"); 1492*7c478bd9Sstevel@tonic-gate } 1493*7c478bd9Sstevel@tonic-gate if (client == (CLIENT *)NULL) { 1494*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("rpcinfo"); 1495*7c478bd9Sstevel@tonic-gate exit(1); 1496*7c478bd9Sstevel@tonic-gate } 1497*7c478bd9Sstevel@tonic-gate to.tv_sec = 10; 1498*7c478bd9Sstevel@tonic-gate to.tv_usec = 0; 1499*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void, 1500*7c478bd9Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, 1501*7c478bd9Sstevel@tonic-gate (char *)NULL, to); 1502*7c478bd9Sstevel@tonic-gate if (argc == 3) { 1503*7c478bd9Sstevel@tonic-gate /* Version number was known */ 1504*7c478bd9Sstevel@tonic-gate if (pstatus(client, prognum, versnum) < 0) 1505*7c478bd9Sstevel@tonic-gate failure = 1; 1506*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 1507*7c478bd9Sstevel@tonic-gate if (failure) 1508*7c478bd9Sstevel@tonic-gate exit(1); 1509*7c478bd9Sstevel@tonic-gate return; 1510*7c478bd9Sstevel@tonic-gate } 1511*7c478bd9Sstevel@tonic-gate /* Version number not known */ 1512*7c478bd9Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) { 1513*7c478bd9Sstevel@tonic-gate clnt_geterr(client, &rpcerr); 1514*7c478bd9Sstevel@tonic-gate minvers = rpcerr.re_vers.low; 1515*7c478bd9Sstevel@tonic-gate maxvers = rpcerr.re_vers.high; 1516*7c478bd9Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) { 1517*7c478bd9Sstevel@tonic-gate /* 1518*7c478bd9Sstevel@tonic-gate * Oh dear, it DOES support version 0. 1519*7c478bd9Sstevel@tonic-gate * Let's try version MAX_VERS. 1520*7c478bd9Sstevel@tonic-gate */ 1521*7c478bd9Sstevel@tonic-gate versnum = MAX_VERS; 1522*7c478bd9Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum); 1523*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, 1524*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_void, (char *)NULL, 1525*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_void, (char *)NULL, to); 1526*7c478bd9Sstevel@tonic-gate if (rpc_stat == RPC_PROGVERSMISMATCH) { 1527*7c478bd9Sstevel@tonic-gate clnt_geterr(client, &rpcerr); 1528*7c478bd9Sstevel@tonic-gate minvers = rpcerr.re_vers.low; 1529*7c478bd9Sstevel@tonic-gate maxvers = rpcerr.re_vers.high; 1530*7c478bd9Sstevel@tonic-gate } else if (rpc_stat == RPC_SUCCESS) { 1531*7c478bd9Sstevel@tonic-gate /* 1532*7c478bd9Sstevel@tonic-gate * It also supports version MAX_VERS. 1533*7c478bd9Sstevel@tonic-gate * Looks like we have a wise guy. 1534*7c478bd9Sstevel@tonic-gate * OK, we give them information on all 1535*7c478bd9Sstevel@tonic-gate * 4 billion versions they support... 1536*7c478bd9Sstevel@tonic-gate */ 1537*7c478bd9Sstevel@tonic-gate minvers = 0; 1538*7c478bd9Sstevel@tonic-gate maxvers = MAX_VERS; 1539*7c478bd9Sstevel@tonic-gate } else { 1540*7c478bd9Sstevel@tonic-gate (void) pstatus(client, prognum, MAX_VERS); 1541*7c478bd9Sstevel@tonic-gate exit(1); 1542*7c478bd9Sstevel@tonic-gate } 1543*7c478bd9Sstevel@tonic-gate } else { 1544*7c478bd9Sstevel@tonic-gate (void) pstatus(client, prognum, (ulong_t)0); 1545*7c478bd9Sstevel@tonic-gate exit(1); 1546*7c478bd9Sstevel@tonic-gate } 1547*7c478bd9Sstevel@tonic-gate for (versnum = minvers; versnum <= maxvers; versnum++) { 1548*7c478bd9Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum); 1549*7c478bd9Sstevel@tonic-gate rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t)xdr_void, 1550*7c478bd9Sstevel@tonic-gate (char *)NULL, (xdrproc_t)xdr_void, 1551*7c478bd9Sstevel@tonic-gate (char *)NULL, to); 1552*7c478bd9Sstevel@tonic-gate if (pstatus(client, prognum, versnum) < 0) 1553*7c478bd9Sstevel@tonic-gate failure = 1; 1554*7c478bd9Sstevel@tonic-gate } 1555*7c478bd9Sstevel@tonic-gate (void) CLNT_DESTROY(client); 1556*7c478bd9Sstevel@tonic-gate if (failure) 1557*7c478bd9Sstevel@tonic-gate exit(1); 1558*7c478bd9Sstevel@tonic-gate } 1559*7c478bd9Sstevel@tonic-gate 1560*7c478bd9Sstevel@tonic-gate static void 1561*7c478bd9Sstevel@tonic-gate usage() 1562*7c478bd9Sstevel@tonic-gate { 1563*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Usage: rpcinfo [-m | -s] [host]\n"); 1564*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 1565*7c478bd9Sstevel@tonic-gate fprintf(stderr, " rpcinfo -p [host]\n"); 1566*7c478bd9Sstevel@tonic-gate #endif 1567*7c478bd9Sstevel@tonic-gate fprintf(stderr, " rpcinfo -T netid host prognum [versnum]\n"); 1568*7c478bd9Sstevel@tonic-gate fprintf(stderr, " rpcinfo -l host prognum versnum\n"); 1569*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 1570*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1571*7c478bd9Sstevel@tonic-gate " rpcinfo [-n portnum] -u | -t host prognum [versnum]\n"); 1572*7c478bd9Sstevel@tonic-gate #endif 1573*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1574*7c478bd9Sstevel@tonic-gate " rpcinfo -a serv_address -T netid prognum [version]\n"); 1575*7c478bd9Sstevel@tonic-gate fprintf(stderr, " rpcinfo -b prognum versnum\n"); 1576*7c478bd9Sstevel@tonic-gate fprintf(stderr, " rpcinfo -d [-T netid] prognum versnum\n"); 1577*7c478bd9Sstevel@tonic-gate } 1578*7c478bd9Sstevel@tonic-gate 1579*7c478bd9Sstevel@tonic-gate static ulong_t 1580*7c478bd9Sstevel@tonic-gate getprognum (arg) 1581*7c478bd9Sstevel@tonic-gate char *arg; 1582*7c478bd9Sstevel@tonic-gate { 1583*7c478bd9Sstevel@tonic-gate char *strptr; 1584*7c478bd9Sstevel@tonic-gate register struct rpcent *rpc; 1585*7c478bd9Sstevel@tonic-gate register ulong_t prognum; 1586*7c478bd9Sstevel@tonic-gate char *tptr = arg; 1587*7c478bd9Sstevel@tonic-gate 1588*7c478bd9Sstevel@tonic-gate while (*tptr && isdigit(*tptr++)); 1589*7c478bd9Sstevel@tonic-gate if (*tptr || isalpha(*(tptr - 1))) { 1590*7c478bd9Sstevel@tonic-gate rpc = getrpcbyname(arg); 1591*7c478bd9Sstevel@tonic-gate if (rpc == NULL) { 1592*7c478bd9Sstevel@tonic-gate fprintf(stderr, "rpcinfo: %s is unknown service\n", 1593*7c478bd9Sstevel@tonic-gate arg); 1594*7c478bd9Sstevel@tonic-gate exit(1); 1595*7c478bd9Sstevel@tonic-gate } 1596*7c478bd9Sstevel@tonic-gate prognum = rpc->r_number; 1597*7c478bd9Sstevel@tonic-gate } else { 1598*7c478bd9Sstevel@tonic-gate prognum = strtol(arg, &strptr, 10); 1599*7c478bd9Sstevel@tonic-gate if (strptr == arg || *strptr != '\0') { 1600*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1601*7c478bd9Sstevel@tonic-gate "rpcinfo: %s is illegal program number\n", arg); 1602*7c478bd9Sstevel@tonic-gate exit(1); 1603*7c478bd9Sstevel@tonic-gate } 1604*7c478bd9Sstevel@tonic-gate } 1605*7c478bd9Sstevel@tonic-gate return (prognum); 1606*7c478bd9Sstevel@tonic-gate } 1607*7c478bd9Sstevel@tonic-gate 1608*7c478bd9Sstevel@tonic-gate static ulong_t 1609*7c478bd9Sstevel@tonic-gate getvers(arg) 1610*7c478bd9Sstevel@tonic-gate char *arg; 1611*7c478bd9Sstevel@tonic-gate { 1612*7c478bd9Sstevel@tonic-gate char *strptr; 1613*7c478bd9Sstevel@tonic-gate register ulong_t vers; 1614*7c478bd9Sstevel@tonic-gate 1615*7c478bd9Sstevel@tonic-gate vers = (int)strtol(arg, &strptr, 10); 1616*7c478bd9Sstevel@tonic-gate if (strptr == arg || *strptr != '\0') { 1617*7c478bd9Sstevel@tonic-gate fprintf(stderr, "rpcinfo: %s is illegal version number\n", 1618*7c478bd9Sstevel@tonic-gate arg); 1619*7c478bd9Sstevel@tonic-gate exit(1); 1620*7c478bd9Sstevel@tonic-gate } 1621*7c478bd9Sstevel@tonic-gate return (vers); 1622*7c478bd9Sstevel@tonic-gate } 1623*7c478bd9Sstevel@tonic-gate 1624*7c478bd9Sstevel@tonic-gate /* 1625*7c478bd9Sstevel@tonic-gate * This routine should take a pointer to an "rpc_err" structure, rather than 1626*7c478bd9Sstevel@tonic-gate * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to 1627*7c478bd9Sstevel@tonic-gate * a CLIENT structure rather than a pointer to an "rpc_err" structure. 1628*7c478bd9Sstevel@tonic-gate * As such, we have to keep the CLIENT structure around in order to print 1629*7c478bd9Sstevel@tonic-gate * a good error message. 1630*7c478bd9Sstevel@tonic-gate */ 1631*7c478bd9Sstevel@tonic-gate static int 1632*7c478bd9Sstevel@tonic-gate pstatus(client, prog, vers) 1633*7c478bd9Sstevel@tonic-gate register CLIENT *client; 1634*7c478bd9Sstevel@tonic-gate ulong_t prog; 1635*7c478bd9Sstevel@tonic-gate ulong_t vers; 1636*7c478bd9Sstevel@tonic-gate { 1637*7c478bd9Sstevel@tonic-gate struct rpc_err rpcerr; 1638*7c478bd9Sstevel@tonic-gate 1639*7c478bd9Sstevel@tonic-gate clnt_geterr(client, &rpcerr); 1640*7c478bd9Sstevel@tonic-gate if (rpcerr.re_status != RPC_SUCCESS) { 1641*7c478bd9Sstevel@tonic-gate clnt_perror(client, "rpcinfo"); 1642*7c478bd9Sstevel@tonic-gate printf("program %lu version %lu is not available\n", 1643*7c478bd9Sstevel@tonic-gate prog, vers); 1644*7c478bd9Sstevel@tonic-gate return (-1); 1645*7c478bd9Sstevel@tonic-gate } else { 1646*7c478bd9Sstevel@tonic-gate printf("program %lu version %lu ready and waiting\n", 1647*7c478bd9Sstevel@tonic-gate prog, vers); 1648*7c478bd9Sstevel@tonic-gate return (0); 1649*7c478bd9Sstevel@tonic-gate } 1650*7c478bd9Sstevel@tonic-gate } 1651*7c478bd9Sstevel@tonic-gate 1652*7c478bd9Sstevel@tonic-gate static CLIENT * 1653*7c478bd9Sstevel@tonic-gate clnt_rpcbind_create(host, rpcbversnum, targaddr) 1654*7c478bd9Sstevel@tonic-gate char *host; 1655*7c478bd9Sstevel@tonic-gate ulong_t rpcbversnum; 1656*7c478bd9Sstevel@tonic-gate struct netbuf **targaddr; 1657*7c478bd9Sstevel@tonic-gate { 1658*7c478bd9Sstevel@tonic-gate static char *tlist[3] = { 1659*7c478bd9Sstevel@tonic-gate "circuit_n", "circuit_v", "datagram_v" 1660*7c478bd9Sstevel@tonic-gate }; 1661*7c478bd9Sstevel@tonic-gate int i; 1662*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 1663*7c478bd9Sstevel@tonic-gate CLIENT *clnt = NULL; 1664*7c478bd9Sstevel@tonic-gate void *handle; 1665*7c478bd9Sstevel@tonic-gate 1666*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_SUCCESS; 1667*7c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 1668*7c478bd9Sstevel@tonic-gate if ((handle = __rpc_setconf(tlist[i])) == NULL) 1669*7c478bd9Sstevel@tonic-gate continue; 1670*7c478bd9Sstevel@tonic-gate while (clnt == (CLIENT *)NULL) { 1671*7c478bd9Sstevel@tonic-gate if ((nconf = __rpc_getconf(handle)) == NULL) { 1672*7c478bd9Sstevel@tonic-gate if (rpc_createerr.cf_stat == RPC_SUCCESS) 1673*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 1674*7c478bd9Sstevel@tonic-gate break; 1675*7c478bd9Sstevel@tonic-gate } 1676*7c478bd9Sstevel@tonic-gate clnt = getclnthandle(host, nconf, rpcbversnum, 1677*7c478bd9Sstevel@tonic-gate targaddr); 1678*7c478bd9Sstevel@tonic-gate } 1679*7c478bd9Sstevel@tonic-gate if (clnt) 1680*7c478bd9Sstevel@tonic-gate break; 1681*7c478bd9Sstevel@tonic-gate __rpc_endconf(handle); 1682*7c478bd9Sstevel@tonic-gate } 1683*7c478bd9Sstevel@tonic-gate return (clnt); 1684*7c478bd9Sstevel@tonic-gate } 1685*7c478bd9Sstevel@tonic-gate 1686*7c478bd9Sstevel@tonic-gate static CLIENT* 1687*7c478bd9Sstevel@tonic-gate getclnthandle(host, nconf, rpcbversnum, targaddr) 1688*7c478bd9Sstevel@tonic-gate char *host; 1689*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 1690*7c478bd9Sstevel@tonic-gate ulong_t rpcbversnum; 1691*7c478bd9Sstevel@tonic-gate struct netbuf **targaddr; 1692*7c478bd9Sstevel@tonic-gate { 1693*7c478bd9Sstevel@tonic-gate struct netbuf *addr; 1694*7c478bd9Sstevel@tonic-gate struct nd_addrlist *nas; 1695*7c478bd9Sstevel@tonic-gate struct nd_hostserv rpcbind_hs; 1696*7c478bd9Sstevel@tonic-gate CLIENT *client = NULL; 1697*7c478bd9Sstevel@tonic-gate 1698*7c478bd9Sstevel@tonic-gate /* Get the address of the rpcbind */ 1699*7c478bd9Sstevel@tonic-gate rpcbind_hs.h_host = host; 1700*7c478bd9Sstevel@tonic-gate rpcbind_hs.h_serv = "rpcbind"; 1701*7c478bd9Sstevel@tonic-gate if (netdir_getbyname(nconf, &rpcbind_hs, &nas)) { 1702*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; 1703*7c478bd9Sstevel@tonic-gate return (NULL); 1704*7c478bd9Sstevel@tonic-gate } 1705*7c478bd9Sstevel@tonic-gate addr = nas->n_addrs; 1706*7c478bd9Sstevel@tonic-gate client = clnt_tli_create(RPC_ANYFD, nconf, addr, RPCBPROG, 1707*7c478bd9Sstevel@tonic-gate rpcbversnum, 0, 0); 1708*7c478bd9Sstevel@tonic-gate if (client) { 1709*7c478bd9Sstevel@tonic-gate if (targaddr != NULL) { 1710*7c478bd9Sstevel@tonic-gate *targaddr = 1711*7c478bd9Sstevel@tonic-gate (struct netbuf *)malloc(sizeof (struct netbuf)); 1712*7c478bd9Sstevel@tonic-gate if (*targaddr != NULL) { 1713*7c478bd9Sstevel@tonic-gate (*targaddr)->maxlen = addr->maxlen; 1714*7c478bd9Sstevel@tonic-gate (*targaddr)->len = addr->len; 1715*7c478bd9Sstevel@tonic-gate (*targaddr)->buf = (char *)malloc(addr->len); 1716*7c478bd9Sstevel@tonic-gate if ((*targaddr)->buf != NULL) { 1717*7c478bd9Sstevel@tonic-gate memcpy((*targaddr)->buf, addr->buf, 1718*7c478bd9Sstevel@tonic-gate addr->len); 1719*7c478bd9Sstevel@tonic-gate } 1720*7c478bd9Sstevel@tonic-gate } 1721*7c478bd9Sstevel@tonic-gate } 1722*7c478bd9Sstevel@tonic-gate } else { 1723*7c478bd9Sstevel@tonic-gate if (rpc_createerr.cf_stat == RPC_TLIERROR) { 1724*7c478bd9Sstevel@tonic-gate /* 1725*7c478bd9Sstevel@tonic-gate * Assume that the other system is dead; this is a 1726*7c478bd9Sstevel@tonic-gate * better error to display to the user. 1727*7c478bd9Sstevel@tonic-gate */ 1728*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_stat = RPC_RPCBFAILURE; 1729*7c478bd9Sstevel@tonic-gate rpc_createerr.cf_error.re_status = RPC_FAILED; 1730*7c478bd9Sstevel@tonic-gate } 1731*7c478bd9Sstevel@tonic-gate } 1732*7c478bd9Sstevel@tonic-gate netdir_free((char *)nas, ND_ADDRLIST); 1733*7c478bd9Sstevel@tonic-gate return (client); 1734*7c478bd9Sstevel@tonic-gate } 1735*7c478bd9Sstevel@tonic-gate 1736*7c478bd9Sstevel@tonic-gate static void 1737*7c478bd9Sstevel@tonic-gate print_rmtcallstat(rtype, infp) 1738*7c478bd9Sstevel@tonic-gate int rtype; 1739*7c478bd9Sstevel@tonic-gate rpcb_stat *infp; 1740*7c478bd9Sstevel@tonic-gate { 1741*7c478bd9Sstevel@tonic-gate register rpcbs_rmtcalllist_ptr pr; 1742*7c478bd9Sstevel@tonic-gate struct rpcent *rpc; 1743*7c478bd9Sstevel@tonic-gate 1744*7c478bd9Sstevel@tonic-gate if (rtype == RPCBVERS_4_STAT) 1745*7c478bd9Sstevel@tonic-gate printf( 1746*7c478bd9Sstevel@tonic-gate "prog\t\tvers\tproc\tnetid\tindirect success failure\n"); 1747*7c478bd9Sstevel@tonic-gate else 1748*7c478bd9Sstevel@tonic-gate printf("prog\t\tvers\tproc\tnetid\tsuccess\tfailure\n"); 1749*7c478bd9Sstevel@tonic-gate for (pr = infp->rmtinfo; pr; pr = pr->next) { 1750*7c478bd9Sstevel@tonic-gate rpc = getrpcbynumber(pr->prog); 1751*7c478bd9Sstevel@tonic-gate if (rpc) 1752*7c478bd9Sstevel@tonic-gate printf("%-16s", rpc->r_name); 1753*7c478bd9Sstevel@tonic-gate else 1754*7c478bd9Sstevel@tonic-gate printf("%-16d", pr->prog); 1755*7c478bd9Sstevel@tonic-gate printf("%d\t%d\t%-7s ", 1756*7c478bd9Sstevel@tonic-gate pr->vers, pr->proc, pr->netid); 1757*7c478bd9Sstevel@tonic-gate if (rtype == RPCBVERS_4_STAT) 1758*7c478bd9Sstevel@tonic-gate printf("%d\t ", pr->indirect); 1759*7c478bd9Sstevel@tonic-gate printf("%d\t%d\n", pr->success, pr->failure); 1760*7c478bd9Sstevel@tonic-gate } 1761*7c478bd9Sstevel@tonic-gate } 1762*7c478bd9Sstevel@tonic-gate 1763*7c478bd9Sstevel@tonic-gate static void 1764*7c478bd9Sstevel@tonic-gate print_getaddrstat(rtype, infp) 1765*7c478bd9Sstevel@tonic-gate int rtype; 1766*7c478bd9Sstevel@tonic-gate rpcb_stat *infp; 1767*7c478bd9Sstevel@tonic-gate { 1768*7c478bd9Sstevel@tonic-gate rpcbs_addrlist_ptr al; 1769*7c478bd9Sstevel@tonic-gate register struct rpcent *rpc; 1770*7c478bd9Sstevel@tonic-gate 1771*7c478bd9Sstevel@tonic-gate printf("prog\t\tvers\tnetid\t success\tfailure\n"); 1772*7c478bd9Sstevel@tonic-gate for (al = infp->addrinfo; al; al = al->next) { 1773*7c478bd9Sstevel@tonic-gate rpc = getrpcbynumber(al->prog); 1774*7c478bd9Sstevel@tonic-gate if (rpc) 1775*7c478bd9Sstevel@tonic-gate printf("%-16s", rpc->r_name); 1776*7c478bd9Sstevel@tonic-gate else 1777*7c478bd9Sstevel@tonic-gate printf("%-16d", al->prog); 1778*7c478bd9Sstevel@tonic-gate printf("%d\t%-9s %-12d\t%d\n", 1779*7c478bd9Sstevel@tonic-gate al->vers, al->netid, 1780*7c478bd9Sstevel@tonic-gate al->success, al->failure); 1781*7c478bd9Sstevel@tonic-gate } 1782*7c478bd9Sstevel@tonic-gate } 1783*7c478bd9Sstevel@tonic-gate 1784*7c478bd9Sstevel@tonic-gate static char * 1785*7c478bd9Sstevel@tonic-gate spaces(howmany) 1786*7c478bd9Sstevel@tonic-gate int howmany; 1787*7c478bd9Sstevel@tonic-gate { 1788*7c478bd9Sstevel@tonic-gate static char space_array[] = /* 64 spaces */ 1789*7c478bd9Sstevel@tonic-gate " "; 1790*7c478bd9Sstevel@tonic-gate 1791*7c478bd9Sstevel@tonic-gate if (howmany <= 0 || howmany > sizeof (space_array)) { 1792*7c478bd9Sstevel@tonic-gate return (""); 1793*7c478bd9Sstevel@tonic-gate } 1794*7c478bd9Sstevel@tonic-gate return (&space_array[sizeof (space_array) - howmany - 1]); 1795*7c478bd9Sstevel@tonic-gate } 1796