18360efbdSAlfred Perlstein /* $NetBSD: rpcinfo.c,v 1.15 2000/10/04 20:09:05 mjl Exp $ */ 2e99a5be3SGarrett Wollman 3e99a5be3SGarrett Wollman /* 4e99a5be3SGarrett Wollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5e99a5be3SGarrett Wollman * unrestricted use provided that this legend is included on all tape 6e99a5be3SGarrett Wollman * media and as a part of the software program in whole or part. Users 7e99a5be3SGarrett Wollman * may copy or modify Sun RPC without charge, but are not authorized 8e99a5be3SGarrett Wollman * to license or distribute it to anyone else except as part of a product or 9e99a5be3SGarrett Wollman * program developed by the user. 10e99a5be3SGarrett Wollman * 11e99a5be3SGarrett Wollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12e99a5be3SGarrett Wollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13e99a5be3SGarrett Wollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14e99a5be3SGarrett Wollman * 15e99a5be3SGarrett Wollman * Sun RPC is provided with no support and without any obligation on the 16e99a5be3SGarrett Wollman * part of Sun Microsystems, Inc. to assist in its use, correction, 17e99a5be3SGarrett Wollman * modification or enhancement. 18e99a5be3SGarrett Wollman * 19e99a5be3SGarrett Wollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20e99a5be3SGarrett Wollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21e99a5be3SGarrett Wollman * OR ANY PART THEREOF. 22e99a5be3SGarrett Wollman * 23e99a5be3SGarrett Wollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24e99a5be3SGarrett Wollman * or profits or other special, indirect and consequential damages, even if 25e99a5be3SGarrett Wollman * Sun has been advised of the possibility of such damages. 26e99a5be3SGarrett Wollman * 27e99a5be3SGarrett Wollman * Sun Microsystems, Inc. 28e99a5be3SGarrett Wollman * 2550 Garcia Avenue 29e99a5be3SGarrett Wollman * Mountain View, California 94043 30e99a5be3SGarrett Wollman */ 31e99a5be3SGarrett Wollman 328360efbdSAlfred Perlstein /* 338360efbdSAlfred Perlstein * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 348360efbdSAlfred Perlstein */ 358360efbdSAlfred Perlstein 368360efbdSAlfred Perlstein /* #ident "@(#)rpcinfo.c 1.18 93/07/05 SMI" */ 378360efbdSAlfred Perlstein 388360efbdSAlfred Perlstein #if 0 398360efbdSAlfred Perlstein #ifndef lint 408360efbdSAlfred Perlstein static char sccsid[] = "@(#)rpcinfo.c 1.16 89/04/05 Copyr 1986 Sun Micro"; 418360efbdSAlfred Perlstein #endif 428360efbdSAlfred Perlstein #endif 438360efbdSAlfred Perlstein 44003bc1d4SPhilippe Charnier #include <sys/cdefs.h> 45003bc1d4SPhilippe Charnier __FBSDID("$FreeBSD$"); 46003bc1d4SPhilippe Charnier 478360efbdSAlfred Perlstein /* 488360efbdSAlfred Perlstein * rpcinfo: ping a particular rpc program 496bccea7cSRebecca Cran * or dump the registered programs on the remote machine. 508360efbdSAlfred Perlstein */ 518360efbdSAlfred Perlstein 528360efbdSAlfred Perlstein /* 53487ac9acSUlrich Spörlein * We are for now defining PORTMAP here. It doesn't even compile 548360efbdSAlfred Perlstein * unless it is defined. 558360efbdSAlfred Perlstein */ 568360efbdSAlfred Perlstein #ifndef PORTMAP 578360efbdSAlfred Perlstein #define PORTMAP 588360efbdSAlfred Perlstein #endif 598360efbdSAlfred Perlstein 608360efbdSAlfred Perlstein /* 618360efbdSAlfred Perlstein * If PORTMAP is defined, rpcinfo will talk to both portmapper and 628360efbdSAlfred Perlstein * rpcbind programs; else it talks only to rpcbind. In the latter case 638360efbdSAlfred Perlstein * all the portmapper specific options such as -u, -t, -p become void. 648360efbdSAlfred Perlstein */ 658360efbdSAlfred Perlstein #include <sys/types.h> 668360efbdSAlfred Perlstein #include <sys/param.h> 678360efbdSAlfred Perlstein #include <sys/socket.h> 688360efbdSAlfred Perlstein #include <sys/un.h> 69e99a5be3SGarrett Wollman #include <rpc/rpc.h> 70e99a5be3SGarrett Wollman #include <stdio.h> 718360efbdSAlfred Perlstein #include <rpc/rpcb_prot.h> 728360efbdSAlfred Perlstein #include <rpc/rpcent.h> 738360efbdSAlfred Perlstein #include <rpc/nettype.h> 748360efbdSAlfred Perlstein #include <rpc/rpc_com.h> 758360efbdSAlfred Perlstein #include <stdlib.h> 768360efbdSAlfred Perlstein #include <string.h> 778360efbdSAlfred Perlstein #include <unistd.h> 788360efbdSAlfred Perlstein #include <err.h> 798360efbdSAlfred Perlstein #include <ctype.h> 808360efbdSAlfred Perlstein 818360efbdSAlfred Perlstein #ifdef PORTMAP /* Support for version 2 portmapper */ 828360efbdSAlfred Perlstein #include <netinet/in.h> 83e99a5be3SGarrett Wollman #include <netdb.h> 848360efbdSAlfred Perlstein #include <arpa/inet.h> 85e99a5be3SGarrett Wollman #include <rpc/pmap_prot.h> 86e99a5be3SGarrett Wollman #include <rpc/pmap_clnt.h> 878360efbdSAlfred Perlstein #endif 88e99a5be3SGarrett Wollman 89e99a5be3SGarrett Wollman #define MAXHOSTLEN 256 90e99a5be3SGarrett Wollman #define MIN_VERS ((u_long) 0) 91e99a5be3SGarrett Wollman #define MAX_VERS ((u_long) 4294967295UL) 928360efbdSAlfred Perlstein #define UNKNOWN "unknown" 93e99a5be3SGarrett Wollman 94e99a5be3SGarrett Wollman /* 95e99a5be3SGarrett Wollman * Functions to be performed. 96e99a5be3SGarrett Wollman */ 97e99a5be3SGarrett Wollman #define NONE 0 /* no function */ 98e99a5be3SGarrett Wollman #define PMAPDUMP 1 /* dump portmapper registrations */ 99e99a5be3SGarrett Wollman #define TCPPING 2 /* ping TCP service */ 100e99a5be3SGarrett Wollman #define UDPPING 3 /* ping UDP service */ 1018360efbdSAlfred Perlstein #define BROADCAST 4 /* ping broadcast service */ 102e99a5be3SGarrett Wollman #define DELETES 5 /* delete registration for the service */ 1038360efbdSAlfred Perlstein #define ADDRPING 6 /* pings at the given address */ 1048360efbdSAlfred Perlstein #define PROGPING 7 /* pings a program on a given host */ 1058360efbdSAlfred Perlstein #define RPCBDUMP 8 /* dump rpcbind registrations */ 1068360efbdSAlfred Perlstein #define RPCBDUMP_SHORT 9 /* dump rpcbind registrations - short version */ 1078360efbdSAlfred Perlstein #define RPCBADDRLIST 10 /* dump addr list about one prog */ 1088360efbdSAlfred Perlstein #define RPCBGETSTAT 11 /* Get statistics */ 1098360efbdSAlfred Perlstein 1108360efbdSAlfred Perlstein struct netidlist { 1118360efbdSAlfred Perlstein char *netid; 1128360efbdSAlfred Perlstein struct netidlist *next; 1138360efbdSAlfred Perlstein }; 1148360efbdSAlfred Perlstein 1158360efbdSAlfred Perlstein struct verslist { 1168360efbdSAlfred Perlstein int vers; 1178360efbdSAlfred Perlstein struct verslist *next; 1188360efbdSAlfred Perlstein }; 1198360efbdSAlfred Perlstein 1208360efbdSAlfred Perlstein struct rpcbdump_short { 1218360efbdSAlfred Perlstein u_long prog; 1228360efbdSAlfred Perlstein struct verslist *vlist; 1238360efbdSAlfred Perlstein struct netidlist *nlist; 1248360efbdSAlfred Perlstein struct rpcbdump_short *next; 1258360efbdSAlfred Perlstein char *owner; 1268360efbdSAlfred Perlstein }; 1278360efbdSAlfred Perlstein 1288360efbdSAlfred Perlstein 1298360efbdSAlfred Perlstein 1308360efbdSAlfred Perlstein #ifdef PORTMAP 13161382374SXin LI static void ip_ping(u_short, const char *, int, char **); 1328360efbdSAlfred Perlstein static CLIENT *clnt_com_create(struct sockaddr_in *, u_long, u_long, int *, 13361382374SXin LI const char *); 1348360efbdSAlfred Perlstein static void pmapdump(int, char **); 1358360efbdSAlfred Perlstein static void get_inet_address(struct sockaddr_in *, char *); 1368360efbdSAlfred Perlstein #endif 1378360efbdSAlfred Perlstein 1388360efbdSAlfred Perlstein static bool_t reply_proc(void *, struct netbuf *, struct netconfig *); 1398360efbdSAlfred Perlstein static void brdcst(int, char **); 1408360efbdSAlfred Perlstein static void addrping(char *, char *, int, char **); 1418360efbdSAlfred Perlstein static void progping(char *, int, char **); 1428360efbdSAlfred Perlstein static CLIENT *clnt_addr_create(char *, struct netconfig *, u_long, u_long); 1438360efbdSAlfred Perlstein static CLIENT *clnt_rpcbind_create(char *, int, struct netbuf **); 1448360efbdSAlfred Perlstein static CLIENT *getclnthandle(char *, struct netconfig *, u_long, 1458360efbdSAlfred Perlstein struct netbuf **); 1468360efbdSAlfred Perlstein static CLIENT *local_rpcb(u_long, u_long); 1478360efbdSAlfred Perlstein static int pstatus(CLIENT *, u_long, u_long); 1488360efbdSAlfred Perlstein static void rpcbdump(int, char *, int, char **); 1498360efbdSAlfred Perlstein static void rpcbgetstat(int, char **); 1508360efbdSAlfred Perlstein static void rpcbaddrlist(char *, int, char **); 1518360efbdSAlfred Perlstein static void deletereg(char *, int, char **); 1528360efbdSAlfred Perlstein static void print_rmtcallstat(int, rpcb_stat *); 1538360efbdSAlfred Perlstein static void print_getaddrstat(int, rpcb_stat *); 1548360efbdSAlfred Perlstein static void usage(void); 1558360efbdSAlfred Perlstein static u_long getprognum(char *); 1568360efbdSAlfred Perlstein static u_long getvers(char *); 1578360efbdSAlfred Perlstein static char *spaces(int); 1588360efbdSAlfred Perlstein static bool_t add_version(struct rpcbdump_short *, u_long); 1598360efbdSAlfred Perlstein static bool_t add_netid(struct rpcbdump_short *, char *); 1608360efbdSAlfred Perlstein 161e99a5be3SGarrett Wollman int 1628360efbdSAlfred Perlstein main(int argc, char **argv) 163e99a5be3SGarrett Wollman { 164e99a5be3SGarrett Wollman register int c; 165e99a5be3SGarrett Wollman int errflg; 166e99a5be3SGarrett Wollman int function; 1678360efbdSAlfred Perlstein char *netid = NULL; 1688360efbdSAlfred Perlstein char *address = NULL; 1698360efbdSAlfred Perlstein #ifdef PORTMAP 1708360efbdSAlfred Perlstein char *strptr; 1718360efbdSAlfred Perlstein u_short portnum = 0; 1728360efbdSAlfred Perlstein #endif 173e99a5be3SGarrett Wollman 174e99a5be3SGarrett Wollman function = NONE; 175e99a5be3SGarrett Wollman errflg = 0; 1768360efbdSAlfred Perlstein #ifdef PORTMAP 1778360efbdSAlfred Perlstein while ((c = getopt(argc, argv, "a:bdlmn:pstT:u")) != -1) { 1788360efbdSAlfred Perlstein #else 1798360efbdSAlfred Perlstein while ((c = getopt(argc, argv, "a:bdlmn:sT:")) != -1) { 1808360efbdSAlfred Perlstein #endif 181e99a5be3SGarrett Wollman switch (c) { 1828360efbdSAlfred Perlstein #ifdef PORTMAP 183e99a5be3SGarrett Wollman case 'p': 184e99a5be3SGarrett Wollman if (function != NONE) 185e99a5be3SGarrett Wollman errflg = 1; 186e99a5be3SGarrett Wollman else 187e99a5be3SGarrett Wollman function = PMAPDUMP; 188e99a5be3SGarrett Wollman break; 189e99a5be3SGarrett Wollman 190e99a5be3SGarrett Wollman case 't': 191e99a5be3SGarrett Wollman if (function != NONE) 192e99a5be3SGarrett Wollman errflg = 1; 193e99a5be3SGarrett Wollman else 194e99a5be3SGarrett Wollman function = TCPPING; 195e99a5be3SGarrett Wollman break; 196e99a5be3SGarrett Wollman 197e99a5be3SGarrett Wollman case 'u': 198e99a5be3SGarrett Wollman if (function != NONE) 199e99a5be3SGarrett Wollman errflg = 1; 200e99a5be3SGarrett Wollman else 201e99a5be3SGarrett Wollman function = UDPPING; 202e99a5be3SGarrett Wollman break; 203e99a5be3SGarrett Wollman 2048360efbdSAlfred Perlstein case 'n': 2058360efbdSAlfred Perlstein portnum = (u_short) strtol(optarg, &strptr, 10); 206003bc1d4SPhilippe Charnier if (strptr == optarg || *strptr != '\0') 207003bc1d4SPhilippe Charnier errx(1, "%s is illegal port number", optarg); 2088360efbdSAlfred Perlstein break; 2098360efbdSAlfred Perlstein #endif 2108360efbdSAlfred Perlstein case 'a': 2118360efbdSAlfred Perlstein address = optarg; 2128360efbdSAlfred Perlstein if (function != NONE) 2138360efbdSAlfred Perlstein errflg = 1; 2148360efbdSAlfred Perlstein else 2158360efbdSAlfred Perlstein function = ADDRPING; 2168360efbdSAlfred Perlstein break; 217e99a5be3SGarrett Wollman case 'b': 218e99a5be3SGarrett Wollman if (function != NONE) 219e99a5be3SGarrett Wollman errflg = 1; 220e99a5be3SGarrett Wollman else 2218360efbdSAlfred Perlstein function = BROADCAST; 222e99a5be3SGarrett Wollman break; 223e99a5be3SGarrett Wollman 224e99a5be3SGarrett Wollman case 'd': 225e99a5be3SGarrett Wollman if (function != NONE) 226e99a5be3SGarrett Wollman errflg = 1; 227e99a5be3SGarrett Wollman else 228e99a5be3SGarrett Wollman function = DELETES; 229e99a5be3SGarrett Wollman break; 230e99a5be3SGarrett Wollman 2318360efbdSAlfred Perlstein case 'l': 2328360efbdSAlfred Perlstein if (function != NONE) 2338360efbdSAlfred Perlstein errflg = 1; 2348360efbdSAlfred Perlstein else 2358360efbdSAlfred Perlstein function = RPCBADDRLIST; 2368360efbdSAlfred Perlstein break; 2378360efbdSAlfred Perlstein 2388360efbdSAlfred Perlstein case 'm': 2398360efbdSAlfred Perlstein if (function != NONE) 2408360efbdSAlfred Perlstein errflg = 1; 2418360efbdSAlfred Perlstein else 2428360efbdSAlfred Perlstein function = RPCBGETSTAT; 2438360efbdSAlfred Perlstein break; 2448360efbdSAlfred Perlstein 2458360efbdSAlfred Perlstein case 's': 2468360efbdSAlfred Perlstein if (function != NONE) 2478360efbdSAlfred Perlstein errflg = 1; 2488360efbdSAlfred Perlstein else 2498360efbdSAlfred Perlstein function = RPCBDUMP_SHORT; 2508360efbdSAlfred Perlstein break; 2518360efbdSAlfred Perlstein 2528360efbdSAlfred Perlstein case 'T': 2538360efbdSAlfred Perlstein netid = optarg; 2548360efbdSAlfred Perlstein break; 255e99a5be3SGarrett Wollman case '?': 256e99a5be3SGarrett Wollman errflg = 1; 2578360efbdSAlfred Perlstein break; 258e99a5be3SGarrett Wollman } 259e99a5be3SGarrett Wollman } 260e99a5be3SGarrett Wollman 261003bc1d4SPhilippe Charnier if (errflg || ((function == ADDRPING) && !netid)) 262e99a5be3SGarrett Wollman usage(); 263e99a5be3SGarrett Wollman 2648360efbdSAlfred Perlstein if (function == NONE) { 2658360efbdSAlfred Perlstein if (argc - optind > 1) 2668360efbdSAlfred Perlstein function = PROGPING; 2678360efbdSAlfred Perlstein else 2688360efbdSAlfred Perlstein function = RPCBDUMP; 2698360efbdSAlfred Perlstein } 270e99a5be3SGarrett Wollman 2718360efbdSAlfred Perlstein switch (function) { 2728360efbdSAlfred Perlstein #ifdef PORTMAP 273e99a5be3SGarrett Wollman case PMAPDUMP: 274003bc1d4SPhilippe Charnier if (portnum != 0) 275e99a5be3SGarrett Wollman usage(); 276e99a5be3SGarrett Wollman pmapdump(argc - optind, argv + optind); 277e99a5be3SGarrett Wollman break; 278e99a5be3SGarrett Wollman 279e99a5be3SGarrett Wollman case UDPPING: 2808360efbdSAlfred Perlstein ip_ping(portnum, "udp", argc - optind, argv + optind); 281e99a5be3SGarrett Wollman break; 282e99a5be3SGarrett Wollman 283e99a5be3SGarrett Wollman case TCPPING: 2848360efbdSAlfred Perlstein ip_ping(portnum, "tcp", argc - optind, argv + optind); 285e99a5be3SGarrett Wollman break; 2868360efbdSAlfred Perlstein #endif 2878360efbdSAlfred Perlstein case BROADCAST: 288e99a5be3SGarrett Wollman brdcst(argc - optind, argv + optind); 289e99a5be3SGarrett Wollman break; 290e99a5be3SGarrett Wollman case DELETES: 2918360efbdSAlfred Perlstein deletereg(netid, argc - optind, argv + optind); 2928360efbdSAlfred Perlstein break; 2938360efbdSAlfred Perlstein case ADDRPING: 2948360efbdSAlfred Perlstein addrping(address, netid, argc - optind, argv + optind); 2958360efbdSAlfred Perlstein break; 2968360efbdSAlfred Perlstein case PROGPING: 2978360efbdSAlfred Perlstein progping(netid, argc - optind, argv + optind); 2988360efbdSAlfred Perlstein break; 2998360efbdSAlfred Perlstein case RPCBDUMP: 3008360efbdSAlfred Perlstein case RPCBDUMP_SHORT: 3018360efbdSAlfred Perlstein rpcbdump(function, netid, argc - optind, argv + optind); 3028360efbdSAlfred Perlstein break; 3038360efbdSAlfred Perlstein case RPCBGETSTAT: 3048360efbdSAlfred Perlstein rpcbgetstat(argc - optind, argv + optind); 3058360efbdSAlfred Perlstein break; 3068360efbdSAlfred Perlstein case RPCBADDRLIST: 3078360efbdSAlfred Perlstein rpcbaddrlist(netid, argc - optind, argv + optind); 308e99a5be3SGarrett Wollman break; 309e99a5be3SGarrett Wollman } 310e99a5be3SGarrett Wollman return (0); 311e99a5be3SGarrett Wollman } 312e99a5be3SGarrett Wollman 3138360efbdSAlfred Perlstein static CLIENT * 3148360efbdSAlfred Perlstein local_rpcb(u_long prog, u_long vers) 315e99a5be3SGarrett Wollman { 3168858373fSAlfred Perlstein void *localhandle; 3178858373fSAlfred Perlstein struct netconfig *nconf; 3188858373fSAlfred Perlstein CLIENT *clnt; 3198360efbdSAlfred Perlstein 3208858373fSAlfred Perlstein localhandle = setnetconfig(); 3218858373fSAlfred Perlstein while ((nconf = getnetconfig(localhandle)) != NULL) { 3228858373fSAlfred Perlstein if (nconf->nc_protofmly != NULL && 3238858373fSAlfred Perlstein strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 3248858373fSAlfred Perlstein break; 3258858373fSAlfred Perlstein } 3268858373fSAlfred Perlstein if (nconf == NULL) { 3278858373fSAlfred Perlstein warnx("getnetconfig: %s", nc_sperror()); 3288858373fSAlfred Perlstein return (NULL); 3298858373fSAlfred Perlstein } 3308360efbdSAlfred Perlstein 3318858373fSAlfred Perlstein clnt = clnt_tp_create(NULL, prog, vers, nconf); 3328858373fSAlfred Perlstein endnetconfig(localhandle); 3338858373fSAlfred Perlstein return clnt; 3348360efbdSAlfred Perlstein } 3358360efbdSAlfred Perlstein 3368360efbdSAlfred Perlstein #ifdef PORTMAP 3378360efbdSAlfred Perlstein static CLIENT * 3388360efbdSAlfred Perlstein clnt_com_create(struct sockaddr_in *addr, u_long prog, u_long vers, 33961382374SXin LI int *fdp, const char *trans) 3408360efbdSAlfred Perlstein { 3418360efbdSAlfred Perlstein CLIENT *clnt; 3428360efbdSAlfred Perlstein 3438360efbdSAlfred Perlstein if (strcmp(trans, "tcp") == 0) { 3448360efbdSAlfred Perlstein clnt = clnttcp_create(addr, prog, vers, fdp, 0, 0); 3458360efbdSAlfred Perlstein } else { 3468360efbdSAlfred Perlstein struct timeval to; 3478360efbdSAlfred Perlstein 3488360efbdSAlfred Perlstein to.tv_sec = 5; 3498360efbdSAlfred Perlstein to.tv_usec = 0; 3508360efbdSAlfred Perlstein clnt = clntudp_create(addr, prog, vers, to, fdp); 3518360efbdSAlfred Perlstein } 3528360efbdSAlfred Perlstein if (clnt == (CLIENT *)NULL) { 3538360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 3548360efbdSAlfred Perlstein if (vers == MIN_VERS) 3558360efbdSAlfred Perlstein printf("program %lu is not available\n", prog); 3568360efbdSAlfred Perlstein else 3578360efbdSAlfred Perlstein printf("program %lu version %lu is not available\n", 3588360efbdSAlfred Perlstein prog, vers); 3598360efbdSAlfred Perlstein exit(1); 3608360efbdSAlfred Perlstein } 3618360efbdSAlfred Perlstein return (clnt); 3628360efbdSAlfred Perlstein } 3638360efbdSAlfred Perlstein 3648360efbdSAlfred Perlstein /* 3658360efbdSAlfred Perlstein * If portnum is 0, then go and get the address from portmapper, which happens 3668360efbdSAlfred Perlstein * transparently through clnt*_create(); If version number is not given, it 3678360efbdSAlfred Perlstein * tries to find out the version number by making a call to version 0 and if 3688360efbdSAlfred Perlstein * that fails, it obtains the high order and the low order version number. If 3698360efbdSAlfred Perlstein * version 0 calls succeeds, it tries for MAXVERS call and repeats the same. 3708360efbdSAlfred Perlstein */ 3718360efbdSAlfred Perlstein static void 37261382374SXin LI ip_ping(u_short portnum, const char *trans, int argc, char **argv) 3738360efbdSAlfred Perlstein { 3748360efbdSAlfred Perlstein CLIENT *client; 3758360efbdSAlfred Perlstein int fd = RPC_ANYFD; 376e99a5be3SGarrett Wollman struct timeval to; 377e99a5be3SGarrett Wollman struct sockaddr_in addr; 378e99a5be3SGarrett Wollman enum clnt_stat rpc_stat; 379e99a5be3SGarrett Wollman u_long prognum, vers, minvers, maxvers; 380e99a5be3SGarrett Wollman struct rpc_err rpcerr; 3818360efbdSAlfred Perlstein int failure = 0; 382e99a5be3SGarrett Wollman 383003bc1d4SPhilippe Charnier if (argc < 2 || argc > 3) 384e99a5be3SGarrett Wollman usage(); 3858360efbdSAlfred Perlstein to.tv_sec = 10; 3868360efbdSAlfred Perlstein to.tv_usec = 0; 387e99a5be3SGarrett Wollman prognum = getprognum(argv[1]); 388e99a5be3SGarrett Wollman get_inet_address(&addr, argv[0]); 3898360efbdSAlfred Perlstein if (argc == 2) { /* Version number not known */ 390e99a5be3SGarrett Wollman /* 391e99a5be3SGarrett Wollman * A call to version 0 should fail with a program/version 392e99a5be3SGarrett Wollman * mismatch, and give us the range of versions supported. 393e99a5be3SGarrett Wollman */ 3948360efbdSAlfred Perlstein vers = MIN_VERS; 3958360efbdSAlfred Perlstein } else { 3968360efbdSAlfred Perlstein vers = getvers(argv[2]); 397e99a5be3SGarrett Wollman } 3988360efbdSAlfred Perlstein addr.sin_port = htons(portnum); 3998360efbdSAlfred Perlstein client = clnt_com_create(&addr, prognum, vers, &fd, trans); 4008360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 4018360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, (char *)NULL, 4028360efbdSAlfred Perlstein to); 4038360efbdSAlfred Perlstein if (argc != 2) { 4048360efbdSAlfred Perlstein /* Version number was known */ 4058360efbdSAlfred Perlstein if (pstatus(client, prognum, vers) < 0) 4068360efbdSAlfred Perlstein exit(1); 4078360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 4088360efbdSAlfred Perlstein return; 4098360efbdSAlfred Perlstein } 4108360efbdSAlfred Perlstein /* Version number not known */ 4118360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL); 412e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 413e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 414e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 415e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 416e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 417e99a5be3SGarrett Wollman /* 418e99a5be3SGarrett Wollman * Oh dear, it DOES support version 0. 419e99a5be3SGarrett Wollman * Let's try version MAX_VERS. 420e99a5be3SGarrett Wollman */ 4218360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 422e99a5be3SGarrett Wollman addr.sin_port = htons(portnum); 4238360efbdSAlfred Perlstein client = clnt_com_create(&addr, prognum, MAX_VERS, &fd, trans); 4248360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 4258360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 4268360efbdSAlfred Perlstein (char *)NULL, to); 427e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 428e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 429e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 430e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 431e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 432e99a5be3SGarrett Wollman /* 433e99a5be3SGarrett Wollman * It also supports version MAX_VERS. 434e99a5be3SGarrett Wollman * Looks like we have a wise guy. 435e99a5be3SGarrett Wollman * OK, we give them information on all 436e99a5be3SGarrett Wollman * 4 billion versions they support... 437e99a5be3SGarrett Wollman */ 438e99a5be3SGarrett Wollman minvers = 0; 439e99a5be3SGarrett Wollman maxvers = MAX_VERS; 440e99a5be3SGarrett Wollman } else { 441e99a5be3SGarrett Wollman (void) pstatus(client, prognum, MAX_VERS); 442e99a5be3SGarrett Wollman exit(1); 443e99a5be3SGarrett Wollman } 444e99a5be3SGarrett Wollman } else { 445e99a5be3SGarrett Wollman (void) pstatus(client, prognum, (u_long)0); 446e99a5be3SGarrett Wollman exit(1); 447e99a5be3SGarrett Wollman } 4488360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 449e99a5be3SGarrett Wollman for (vers = minvers; vers <= maxvers; vers++) { 450e99a5be3SGarrett Wollman addr.sin_port = htons(portnum); 4518360efbdSAlfred Perlstein client = clnt_com_create(&addr, prognum, vers, &fd, trans); 4528360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 4538360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 4548360efbdSAlfred Perlstein (char *)NULL, to); 455e99a5be3SGarrett Wollman if (pstatus(client, prognum, vers) < 0) 456e99a5be3SGarrett Wollman failure = 1; 4578360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 458e99a5be3SGarrett Wollman } 459e99a5be3SGarrett Wollman if (failure) 460e99a5be3SGarrett Wollman exit(1); 4618360efbdSAlfred Perlstein (void) close(fd); 4628360efbdSAlfred Perlstein return; 463e99a5be3SGarrett Wollman } 464e99a5be3SGarrett Wollman 4658360efbdSAlfred Perlstein /* 4668360efbdSAlfred Perlstein * Dump all the portmapper registerations 4678360efbdSAlfred Perlstein */ 468e99a5be3SGarrett Wollman static void 4698360efbdSAlfred Perlstein pmapdump(int argc, char **argv) 470e99a5be3SGarrett Wollman { 4718360efbdSAlfred Perlstein struct sockaddr_in server_addr; 4728360efbdSAlfred Perlstein struct pmaplist *head = NULL; 4738360efbdSAlfred Perlstein int socket = RPC_ANYSOCK; 4748360efbdSAlfred Perlstein struct timeval minutetimeout; 4758360efbdSAlfred Perlstein register CLIENT *client; 4768360efbdSAlfred Perlstein struct rpcent *rpc; 4778360efbdSAlfred Perlstein enum clnt_stat clnt_st; 4788360efbdSAlfred Perlstein struct rpc_err err; 479b918e603SKevin Lo char *host = NULL; 480e99a5be3SGarrett Wollman 481003bc1d4SPhilippe Charnier if (argc > 1) 482e99a5be3SGarrett Wollman usage(); 4838360efbdSAlfred Perlstein if (argc == 1) { 4848360efbdSAlfred Perlstein host = argv[0]; 4858360efbdSAlfred Perlstein get_inet_address(&server_addr, host); 4868360efbdSAlfred Perlstein server_addr.sin_port = htons(PMAPPORT); 4878360efbdSAlfred Perlstein client = clnttcp_create(&server_addr, PMAPPROG, PMAPVERS, 4888360efbdSAlfred Perlstein &socket, 50, 500); 4898360efbdSAlfred Perlstein } else 4908360efbdSAlfred Perlstein client = local_rpcb(PMAPPROG, PMAPVERS); 4918360efbdSAlfred Perlstein 4928360efbdSAlfred Perlstein if (client == NULL) { 4938360efbdSAlfred Perlstein if (rpc_createerr.cf_stat == RPC_TLIERROR) { 4948360efbdSAlfred Perlstein /* 4958360efbdSAlfred Perlstein * "Misc. TLI error" is not too helpful. Most likely 4968360efbdSAlfred Perlstein * the connection to the remote server timed out, so 4978360efbdSAlfred Perlstein * this error is at least less perplexing. 4988360efbdSAlfred Perlstein */ 4998360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_PMAPFAILURE; 5008360efbdSAlfred Perlstein rpc_createerr.cf_error.re_status = RPC_FAILED; 5018360efbdSAlfred Perlstein } 5028360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact portmapper"); 5038360efbdSAlfred Perlstein exit(1); 5048360efbdSAlfred Perlstein } 5058360efbdSAlfred Perlstein 5068360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 5078360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 5088360efbdSAlfred Perlstein 5098360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, PMAPPROC_DUMP, (xdrproc_t) xdr_void, 5108360efbdSAlfred Perlstein NULL, (xdrproc_t) xdr_pmaplist_ptr, (char *)&head, 5118360efbdSAlfred Perlstein minutetimeout); 5128360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) { 5138360efbdSAlfred Perlstein if ((clnt_st == RPC_PROGVERSMISMATCH) || 5148360efbdSAlfred Perlstein (clnt_st == RPC_PROGUNAVAIL)) { 5158360efbdSAlfred Perlstein CLNT_GETERR(client, &err); 516b918e603SKevin Lo if (err.re_vers.low > PMAPVERS) { 517b918e603SKevin Lo if (host) 518b918e603SKevin Lo warnx("%s does not support portmapper." 519b918e603SKevin Lo "Try rpcinfo %s instead", host, 520b918e603SKevin Lo host); 521b918e603SKevin Lo else 522b918e603SKevin Lo warnx("local host does not support " 523b918e603SKevin Lo "portmapper. Try 'rpcinfo' " 524b918e603SKevin Lo "instead"); 525b918e603SKevin Lo } 5268360efbdSAlfred Perlstein exit(1); 5278360efbdSAlfred Perlstein } 5288360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact portmapper"); 5298360efbdSAlfred Perlstein exit(1); 5308360efbdSAlfred Perlstein } 5318360efbdSAlfred Perlstein if (head == NULL) { 5328360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 5338360efbdSAlfred Perlstein } else { 5348360efbdSAlfred Perlstein printf(" program vers proto port service\n"); 5358360efbdSAlfred Perlstein for (; head != NULL; head = head->pml_next) { 5368360efbdSAlfred Perlstein printf("%10ld%5ld", 5378360efbdSAlfred Perlstein head->pml_map.pm_prog, 5388360efbdSAlfred Perlstein head->pml_map.pm_vers); 5398360efbdSAlfred Perlstein if (head->pml_map.pm_prot == IPPROTO_UDP) 5408360efbdSAlfred Perlstein printf("%6s", "udp"); 5418360efbdSAlfred Perlstein else if (head->pml_map.pm_prot == IPPROTO_TCP) 5428360efbdSAlfred Perlstein printf("%6s", "tcp"); 5438360efbdSAlfred Perlstein else if (head->pml_map.pm_prot == IPPROTO_ST) 544fb4c8061SMartin Blapp printf("%6s", "local"); 5458360efbdSAlfred Perlstein else 5468360efbdSAlfred Perlstein printf("%6ld", head->pml_map.pm_prot); 5478360efbdSAlfred Perlstein printf("%7ld", head->pml_map.pm_port); 5488360efbdSAlfred Perlstein rpc = getrpcbynumber(head->pml_map.pm_prog); 5498360efbdSAlfred Perlstein if (rpc) 5508360efbdSAlfred Perlstein printf(" %s\n", rpc->r_name); 5518360efbdSAlfred Perlstein else 5528360efbdSAlfred Perlstein printf("\n"); 5538360efbdSAlfred Perlstein } 5548360efbdSAlfred Perlstein } 5558360efbdSAlfred Perlstein } 5568360efbdSAlfred Perlstein 5578360efbdSAlfred Perlstein static void 5588360efbdSAlfred Perlstein get_inet_address(struct sockaddr_in *addr, char *host) 5598360efbdSAlfred Perlstein { 5608360efbdSAlfred Perlstein struct netconfig *nconf; 5618360efbdSAlfred Perlstein struct addrinfo hints, *res; 5628360efbdSAlfred Perlstein int error; 5638360efbdSAlfred Perlstein 5648360efbdSAlfred Perlstein (void) memset((char *)addr, 0, sizeof (*addr)); 5658360efbdSAlfred Perlstein addr->sin_addr.s_addr = inet_addr(host); 566482d8831SKevin Lo if (addr->sin_addr.s_addr == INADDR_NONE || 567482d8831SKevin Lo addr->sin_addr.s_addr == INADDR_ANY) { 5688360efbdSAlfred Perlstein if ((nconf = __rpc_getconfip("udp")) == NULL && 569003bc1d4SPhilippe Charnier (nconf = __rpc_getconfip("tcp")) == NULL) 570003bc1d4SPhilippe Charnier errx(1, "couldn't find a suitable transport"); 571003bc1d4SPhilippe Charnier else { 5728360efbdSAlfred Perlstein memset(&hints, 0, sizeof hints); 5738360efbdSAlfred Perlstein hints.ai_family = AF_INET; 5748360efbdSAlfred Perlstein if ((error = getaddrinfo(host, "rpcbind", &hints, &res)) 575003bc1d4SPhilippe Charnier != 0) 576003bc1d4SPhilippe Charnier errx(1, "%s: %s", host, gai_strerror(error)); 577003bc1d4SPhilippe Charnier else { 5788360efbdSAlfred Perlstein memcpy(addr, res->ai_addr, res->ai_addrlen); 5798360efbdSAlfred Perlstein freeaddrinfo(res); 5808360efbdSAlfred Perlstein } 5818360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 5828360efbdSAlfred Perlstein } 5838360efbdSAlfred Perlstein } else { 5848360efbdSAlfred Perlstein addr->sin_family = AF_INET; 5858360efbdSAlfred Perlstein } 5868360efbdSAlfred Perlstein } 5878360efbdSAlfred Perlstein #endif /* PORTMAP */ 5888360efbdSAlfred Perlstein 5898360efbdSAlfred Perlstein /* 5908360efbdSAlfred Perlstein * reply_proc collects replies from the broadcast. 5918360efbdSAlfred Perlstein * to get a unique list of responses the output of rpcinfo should 5928360efbdSAlfred Perlstein * be piped through sort(1) and then uniq(1). 5938360efbdSAlfred Perlstein */ 5948360efbdSAlfred Perlstein 5958360efbdSAlfred Perlstein /*ARGSUSED*/ 5968360efbdSAlfred Perlstein static bool_t 5978360efbdSAlfred Perlstein reply_proc(void *res, struct netbuf *who, struct netconfig *nconf) 5988360efbdSAlfred Perlstein /* void *res; Nothing comes back */ 5998360efbdSAlfred Perlstein /* struct netbuf *who; Who sent us the reply */ 6008360efbdSAlfred Perlstein /* struct netconfig *nconf; On which transport the reply came */ 6018360efbdSAlfred Perlstein { 6028360efbdSAlfred Perlstein char *uaddr; 6038360efbdSAlfred Perlstein char hostbuf[NI_MAXHOST]; 60461382374SXin LI const char *hostname; 6058360efbdSAlfred Perlstein struct sockaddr *sa = (struct sockaddr *)who->buf; 6068360efbdSAlfred Perlstein 6078360efbdSAlfred Perlstein if (getnameinfo(sa, sa->sa_len, hostbuf, NI_MAXHOST, NULL, 0, 0)) { 6088360efbdSAlfred Perlstein hostname = UNKNOWN; 6098360efbdSAlfred Perlstein } else { 6108360efbdSAlfred Perlstein hostname = hostbuf; 6118360efbdSAlfred Perlstein } 61216a9eab9SDon Lewis uaddr = taddr2uaddr(nconf, who); 61316a9eab9SDon Lewis if (uaddr == NULL) { 61416a9eab9SDon Lewis printf("%s\t%s\n", UNKNOWN, hostname); 61516a9eab9SDon Lewis } else { 6168360efbdSAlfred Perlstein printf("%s\t%s\n", uaddr, hostname); 6178360efbdSAlfred Perlstein free((char *)uaddr); 61816a9eab9SDon Lewis } 6198360efbdSAlfred Perlstein return (FALSE); 6208360efbdSAlfred Perlstein } 6218360efbdSAlfred Perlstein 6228360efbdSAlfred Perlstein static void 6238360efbdSAlfred Perlstein brdcst(int argc, char **argv) 6248360efbdSAlfred Perlstein { 6258360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 6268360efbdSAlfred Perlstein u_long prognum, vers; 6278360efbdSAlfred Perlstein 628003bc1d4SPhilippe Charnier if (argc != 2) 6298360efbdSAlfred Perlstein usage(); 6308360efbdSAlfred Perlstein prognum = getprognum(argv[0]); 6318360efbdSAlfred Perlstein vers = getvers(argv[1]); 6328360efbdSAlfred Perlstein rpc_stat = rpc_broadcast(prognum, vers, NULLPROC, 6338360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, (xdrproc_t) xdr_void, 6348360efbdSAlfred Perlstein (char *)NULL, (resultproc_t) reply_proc, NULL); 635003bc1d4SPhilippe Charnier if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) 636003bc1d4SPhilippe Charnier errx(1, "broadcast failed: %s", clnt_sperrno(rpc_stat)); 6378360efbdSAlfred Perlstein exit(0); 6388360efbdSAlfred Perlstein } 6398360efbdSAlfred Perlstein 6408360efbdSAlfred Perlstein static bool_t 6418360efbdSAlfred Perlstein add_version(struct rpcbdump_short *rs, u_long vers) 6428360efbdSAlfred Perlstein { 6438360efbdSAlfred Perlstein struct verslist *vl; 6448360efbdSAlfred Perlstein 6458360efbdSAlfred Perlstein for (vl = rs->vlist; vl; vl = vl->next) 6468360efbdSAlfred Perlstein if (vl->vers == vers) 6478360efbdSAlfred Perlstein break; 6488360efbdSAlfred Perlstein if (vl) 6498360efbdSAlfred Perlstein return (TRUE); 6508360efbdSAlfred Perlstein vl = (struct verslist *)malloc(sizeof (struct verslist)); 6518360efbdSAlfred Perlstein if (vl == NULL) 6528360efbdSAlfred Perlstein return (FALSE); 6538360efbdSAlfred Perlstein vl->vers = vers; 6548360efbdSAlfred Perlstein vl->next = rs->vlist; 6558360efbdSAlfred Perlstein rs->vlist = vl; 6568360efbdSAlfred Perlstein return (TRUE); 6578360efbdSAlfred Perlstein } 6588360efbdSAlfred Perlstein 6598360efbdSAlfred Perlstein static bool_t 6608360efbdSAlfred Perlstein add_netid(struct rpcbdump_short *rs, char *netid) 6618360efbdSAlfred Perlstein { 6628360efbdSAlfred Perlstein struct netidlist *nl; 6638360efbdSAlfred Perlstein 6648360efbdSAlfred Perlstein for (nl = rs->nlist; nl; nl = nl->next) 6658360efbdSAlfred Perlstein if (strcmp(nl->netid, netid) == 0) 6668360efbdSAlfred Perlstein break; 6678360efbdSAlfred Perlstein if (nl) 6688360efbdSAlfred Perlstein return (TRUE); 6698360efbdSAlfred Perlstein nl = (struct netidlist *)malloc(sizeof (struct netidlist)); 6708360efbdSAlfred Perlstein if (nl == NULL) 6718360efbdSAlfred Perlstein return (FALSE); 6728360efbdSAlfred Perlstein nl->netid = netid; 6738360efbdSAlfred Perlstein nl->next = rs->nlist; 6748360efbdSAlfred Perlstein rs->nlist = nl; 6758360efbdSAlfred Perlstein return (TRUE); 6768360efbdSAlfred Perlstein } 6778360efbdSAlfred Perlstein 6788360efbdSAlfred Perlstein static void 6798360efbdSAlfred Perlstein rpcbdump(int dumptype, char *netid, int argc, char **argv) 6808360efbdSAlfred Perlstein { 6818360efbdSAlfred Perlstein rpcblist_ptr head = NULL; 6828360efbdSAlfred Perlstein struct timeval minutetimeout; 6838360efbdSAlfred Perlstein register CLIENT *client; 6848360efbdSAlfred Perlstein struct rpcent *rpc; 6858360efbdSAlfred Perlstein char *host; 6868360efbdSAlfred Perlstein struct netidlist *nl; 6878360efbdSAlfred Perlstein struct verslist *vl; 6888360efbdSAlfred Perlstein struct rpcbdump_short *rs, *rs_tail; 6898360efbdSAlfred Perlstein char buf[256]; 6908360efbdSAlfred Perlstein enum clnt_stat clnt_st; 6918360efbdSAlfred Perlstein struct rpc_err err; 6928360efbdSAlfred Perlstein struct rpcbdump_short *rs_head = NULL; 6938360efbdSAlfred Perlstein 694003bc1d4SPhilippe Charnier if (argc > 1) 6958360efbdSAlfred Perlstein usage(); 6968360efbdSAlfred Perlstein if (argc == 1) { 6978360efbdSAlfred Perlstein host = argv[0]; 6988360efbdSAlfred Perlstein if (netid == NULL) { 6998360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS, NULL); 7008360efbdSAlfred Perlstein } else { 7018360efbdSAlfred Perlstein struct netconfig *nconf; 7028360efbdSAlfred Perlstein 7038360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 7048360efbdSAlfred Perlstein if (nconf == NULL) { 7058360efbdSAlfred Perlstein nc_perror("rpcinfo: invalid transport"); 7068360efbdSAlfred Perlstein exit(1); 7078360efbdSAlfred Perlstein } 7088360efbdSAlfred Perlstein client = getclnthandle(host, nconf, RPCBVERS, NULL); 7098360efbdSAlfred Perlstein if (nconf) 7108360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 7118360efbdSAlfred Perlstein } 7128360efbdSAlfred Perlstein } else 7138360efbdSAlfred Perlstein client = local_rpcb(PMAPPROG, RPCBVERS); 7148360efbdSAlfred Perlstein 7158360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 7168360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 7178360efbdSAlfred Perlstein exit(1); 7188360efbdSAlfred Perlstein } 7198360efbdSAlfred Perlstein 7208360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 7218360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 7228360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, (xdrproc_t) xdr_void, 7238360efbdSAlfred Perlstein NULL, (xdrproc_t) xdr_rpcblist_ptr, (char *) &head, 7248360efbdSAlfred Perlstein minutetimeout); 7258360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) { 7268360efbdSAlfred Perlstein if ((clnt_st == RPC_PROGVERSMISMATCH) || 7278360efbdSAlfred Perlstein (clnt_st == RPC_PROGUNAVAIL)) { 7288360efbdSAlfred Perlstein int vers; 7298360efbdSAlfred Perlstein 7308360efbdSAlfred Perlstein CLNT_GETERR(client, &err); 7318360efbdSAlfred Perlstein if (err.re_vers.low == RPCBVERS4) { 7328360efbdSAlfred Perlstein vers = RPCBVERS4; 7338360efbdSAlfred Perlstein clnt_control(client, CLSET_VERS, (char *)&vers); 7348360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, 7358360efbdSAlfred Perlstein (xdrproc_t) xdr_void, NULL, 7368360efbdSAlfred Perlstein (xdrproc_t) xdr_rpcblist_ptr, (char *) &head, 7378360efbdSAlfred Perlstein minutetimeout); 7388360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) 7398360efbdSAlfred Perlstein goto failed; 7408360efbdSAlfred Perlstein } else { 7418360efbdSAlfred Perlstein if (err.re_vers.high == PMAPVERS) { 7428360efbdSAlfred Perlstein int high, low; 7438360efbdSAlfred Perlstein struct pmaplist *pmaphead = NULL; 7448360efbdSAlfred Perlstein rpcblist_ptr list, prev; 7458360efbdSAlfred Perlstein 7468360efbdSAlfred Perlstein vers = PMAPVERS; 7478360efbdSAlfred Perlstein clnt_control(client, CLSET_VERS, (char *)&vers); 7488360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, PMAPPROC_DUMP, 7498360efbdSAlfred Perlstein (xdrproc_t) xdr_void, NULL, 7508360efbdSAlfred Perlstein (xdrproc_t) xdr_pmaplist_ptr, 7518360efbdSAlfred Perlstein (char *)&pmaphead, minutetimeout); 7528360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) 7538360efbdSAlfred Perlstein goto failed; 7548360efbdSAlfred Perlstein /* 7558360efbdSAlfred Perlstein * convert to rpcblist_ptr format 7568360efbdSAlfred Perlstein */ 7578360efbdSAlfred Perlstein for (head = NULL; pmaphead != NULL; 7588360efbdSAlfred Perlstein pmaphead = pmaphead->pml_next) { 7598360efbdSAlfred Perlstein list = (rpcblist *)malloc(sizeof (rpcblist)); 7608360efbdSAlfred Perlstein if (list == NULL) 7618360efbdSAlfred Perlstein goto error; 7628360efbdSAlfred Perlstein if (head == NULL) 7638360efbdSAlfred Perlstein head = list; 7648360efbdSAlfred Perlstein else 7658360efbdSAlfred Perlstein prev->rpcb_next = (rpcblist_ptr) list; 7668360efbdSAlfred Perlstein 7678360efbdSAlfred Perlstein list->rpcb_next = NULL; 7688360efbdSAlfred Perlstein list->rpcb_map.r_prog = pmaphead->pml_map.pm_prog; 7698360efbdSAlfred Perlstein list->rpcb_map.r_vers = pmaphead->pml_map.pm_vers; 7708360efbdSAlfred Perlstein if (pmaphead->pml_map.pm_prot == IPPROTO_UDP) 7718360efbdSAlfred Perlstein list->rpcb_map.r_netid = "udp"; 7728360efbdSAlfred Perlstein else if (pmaphead->pml_map.pm_prot == IPPROTO_TCP) 7738360efbdSAlfred Perlstein list->rpcb_map.r_netid = "tcp"; 7748360efbdSAlfred Perlstein else { 7758360efbdSAlfred Perlstein #define MAXLONG_AS_STRING "2147483648" 7768360efbdSAlfred Perlstein list->rpcb_map.r_netid = 7778360efbdSAlfred Perlstein malloc(strlen(MAXLONG_AS_STRING) + 1); 7788360efbdSAlfred Perlstein if (list->rpcb_map.r_netid == NULL) 7798360efbdSAlfred Perlstein goto error; 7808360efbdSAlfred Perlstein sprintf(list->rpcb_map.r_netid, "%6ld", 7818360efbdSAlfred Perlstein pmaphead->pml_map.pm_prot); 7828360efbdSAlfred Perlstein } 7838360efbdSAlfred Perlstein list->rpcb_map.r_owner = UNKNOWN; 7848360efbdSAlfred Perlstein low = pmaphead->pml_map.pm_port & 0xff; 7858360efbdSAlfred Perlstein high = (pmaphead->pml_map.pm_port >> 8) & 0xff; 7868360efbdSAlfred Perlstein list->rpcb_map.r_addr = strdup("0.0.0.0.XXX.XXX"); 7878360efbdSAlfred Perlstein sprintf(&list->rpcb_map.r_addr[8], "%d.%d", 7888360efbdSAlfred Perlstein high, low); 7898360efbdSAlfred Perlstein prev = list; 7908360efbdSAlfred Perlstein } 7918360efbdSAlfred Perlstein } 7928360efbdSAlfred Perlstein } 7938360efbdSAlfred Perlstein } else { /* any other error */ 7948360efbdSAlfred Perlstein failed: 7958360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 7968360efbdSAlfred Perlstein exit(1); 7978360efbdSAlfred Perlstein } 7988360efbdSAlfred Perlstein } 7998360efbdSAlfred Perlstein if (head == NULL) { 8008360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 8018360efbdSAlfred Perlstein } else if (dumptype == RPCBDUMP) { 8028360efbdSAlfred Perlstein printf( 8038360efbdSAlfred Perlstein " program version netid address service owner\n"); 8048360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_next) { 8058360efbdSAlfred Perlstein printf("%10u%5u ", 8068360efbdSAlfred Perlstein head->rpcb_map.r_prog, head->rpcb_map.r_vers); 8078360efbdSAlfred Perlstein printf("%-9s ", head->rpcb_map.r_netid); 8088360efbdSAlfred Perlstein printf("%-22s", head->rpcb_map.r_addr); 8098360efbdSAlfred Perlstein rpc = getrpcbynumber(head->rpcb_map.r_prog); 8108360efbdSAlfred Perlstein if (rpc) 8118360efbdSAlfred Perlstein printf(" %-10s", rpc->r_name); 8128360efbdSAlfred Perlstein else 8138360efbdSAlfred Perlstein printf(" %-10s", "-"); 8148360efbdSAlfred Perlstein printf(" %s\n", head->rpcb_map.r_owner); 8158360efbdSAlfred Perlstein } 8168360efbdSAlfred Perlstein } else if (dumptype == RPCBDUMP_SHORT) { 8178360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_next) { 8188360efbdSAlfred Perlstein for (rs = rs_head; rs; rs = rs->next) 8198360efbdSAlfred Perlstein if (head->rpcb_map.r_prog == rs->prog) 8208360efbdSAlfred Perlstein break; 8218360efbdSAlfred Perlstein if (rs == NULL) { 8228360efbdSAlfred Perlstein rs = (struct rpcbdump_short *) 8238360efbdSAlfred Perlstein malloc(sizeof (struct rpcbdump_short)); 8248360efbdSAlfred Perlstein if (rs == NULL) 8258360efbdSAlfred Perlstein goto error; 8268360efbdSAlfred Perlstein rs->next = NULL; 8278360efbdSAlfred Perlstein if (rs_head == NULL) { 8288360efbdSAlfred Perlstein rs_head = rs; 8298360efbdSAlfred Perlstein rs_tail = rs; 8308360efbdSAlfred Perlstein } else { 8318360efbdSAlfred Perlstein rs_tail->next = rs; 8328360efbdSAlfred Perlstein rs_tail = rs; 8338360efbdSAlfred Perlstein } 8348360efbdSAlfred Perlstein rs->prog = head->rpcb_map.r_prog; 8358360efbdSAlfred Perlstein rs->owner = head->rpcb_map.r_owner; 8368360efbdSAlfred Perlstein rs->nlist = NULL; 8378360efbdSAlfred Perlstein rs->vlist = NULL; 8388360efbdSAlfred Perlstein } 8398360efbdSAlfred Perlstein if (add_version(rs, head->rpcb_map.r_vers) == FALSE) 8408360efbdSAlfred Perlstein goto error; 8418360efbdSAlfred Perlstein if (add_netid(rs, head->rpcb_map.r_netid) == FALSE) 8428360efbdSAlfred Perlstein goto error; 8438360efbdSAlfred Perlstein } 8448360efbdSAlfred Perlstein printf( 8458360efbdSAlfred Perlstein " program version(s) netid(s) service owner\n"); 8468360efbdSAlfred Perlstein for (rs = rs_head; rs; rs = rs->next) { 8478360efbdSAlfred Perlstein char *p = buf; 8488360efbdSAlfred Perlstein 8498360efbdSAlfred Perlstein printf("%10ld ", rs->prog); 8508360efbdSAlfred Perlstein for (vl = rs->vlist; vl; vl = vl->next) { 8518360efbdSAlfred Perlstein sprintf(p, "%d", vl->vers); 8528360efbdSAlfred Perlstein p = p + strlen(p); 8538360efbdSAlfred Perlstein if (vl->next) 8548360efbdSAlfred Perlstein sprintf(p++, ","); 8558360efbdSAlfred Perlstein } 8568360efbdSAlfred Perlstein printf("%-10s", buf); 85783e6e840SBruce Evans buf[0] = '\0'; 8588360efbdSAlfred Perlstein for (nl = rs->nlist; nl; nl = nl->next) { 859*9039018cSAlan Somers strlcat(buf, nl->netid, sizeof(buf)); 8608360efbdSAlfred Perlstein if (nl->next) 861*9039018cSAlan Somers strlcat(buf, ",", sizeof(buf)); 8628360efbdSAlfred Perlstein } 8638360efbdSAlfred Perlstein printf("%-32s", buf); 8648360efbdSAlfred Perlstein rpc = getrpcbynumber(rs->prog); 8658360efbdSAlfred Perlstein if (rpc) 8668360efbdSAlfred Perlstein printf(" %-11s", rpc->r_name); 8678360efbdSAlfred Perlstein else 8688360efbdSAlfred Perlstein printf(" %-11s", "-"); 8698360efbdSAlfred Perlstein printf(" %s\n", rs->owner); 8708360efbdSAlfred Perlstein } 8718360efbdSAlfred Perlstein } 8728360efbdSAlfred Perlstein clnt_destroy(client); 8738360efbdSAlfred Perlstein return; 874003bc1d4SPhilippe Charnier error: warnx("no memory"); 8758360efbdSAlfred Perlstein return; 8768360efbdSAlfred Perlstein } 8778360efbdSAlfred Perlstein 8788360efbdSAlfred Perlstein static char nullstring[] = "\000"; 8798360efbdSAlfred Perlstein 8808360efbdSAlfred Perlstein static void 8818360efbdSAlfred Perlstein rpcbaddrlist(char *netid, int argc, char **argv) 8828360efbdSAlfred Perlstein { 8838360efbdSAlfred Perlstein rpcb_entry_list_ptr head = NULL; 8848360efbdSAlfred Perlstein struct timeval minutetimeout; 8858360efbdSAlfred Perlstein register CLIENT *client; 8868360efbdSAlfred Perlstein struct rpcent *rpc; 8878360efbdSAlfred Perlstein char *host; 8888360efbdSAlfred Perlstein RPCB parms; 8898360efbdSAlfred Perlstein struct netbuf *targaddr; 8908360efbdSAlfred Perlstein 891003bc1d4SPhilippe Charnier if (argc != 3) 8928360efbdSAlfred Perlstein usage(); 8938360efbdSAlfred Perlstein host = argv[0]; 8948360efbdSAlfred Perlstein if (netid == NULL) { 8958360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS4, &targaddr); 8968360efbdSAlfred Perlstein } else { 8978360efbdSAlfred Perlstein struct netconfig *nconf; 8988360efbdSAlfred Perlstein 8998360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 9008360efbdSAlfred Perlstein if (nconf == NULL) { 9018360efbdSAlfred Perlstein nc_perror("rpcinfo: invalid transport"); 9028360efbdSAlfred Perlstein exit(1); 9038360efbdSAlfred Perlstein } 9048360efbdSAlfred Perlstein client = getclnthandle(host, nconf, RPCBVERS4, &targaddr); 9058360efbdSAlfred Perlstein if (nconf) 9068360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 9078360efbdSAlfred Perlstein } 9088360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 9098360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 9108360efbdSAlfred Perlstein exit(1); 9118360efbdSAlfred Perlstein } 9128360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 9138360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 9148360efbdSAlfred Perlstein 9158360efbdSAlfred Perlstein parms.r_prog = getprognum(argv[1]); 9168360efbdSAlfred Perlstein parms.r_vers = getvers(argv[2]); 9178360efbdSAlfred Perlstein parms.r_netid = client->cl_netid; 9188360efbdSAlfred Perlstein if (targaddr == NULL) { 9198360efbdSAlfred Perlstein parms.r_addr = nullstring; /* for XDRing */ 9208360efbdSAlfred Perlstein } else { 9218360efbdSAlfred Perlstein /* 9228360efbdSAlfred Perlstein * We also send the remote system the address we 9238360efbdSAlfred Perlstein * used to contact it in case it can help it 9248360efbdSAlfred Perlstein * connect back with us 9258360efbdSAlfred Perlstein */ 9268360efbdSAlfred Perlstein struct netconfig *nconf; 9278360efbdSAlfred Perlstein 9288360efbdSAlfred Perlstein nconf = getnetconfigent(client->cl_netid); 9298360efbdSAlfred Perlstein if (nconf != NULL) { 9308360efbdSAlfred Perlstein parms.r_addr = taddr2uaddr(nconf, targaddr); 9318360efbdSAlfred Perlstein if (parms.r_addr == NULL) 9328360efbdSAlfred Perlstein parms.r_addr = nullstring; 9338360efbdSAlfred Perlstein freenetconfigent(nconf); 9348360efbdSAlfred Perlstein } else { 9358360efbdSAlfred Perlstein parms.r_addr = nullstring; /* for XDRing */ 9368360efbdSAlfred Perlstein } 9378360efbdSAlfred Perlstein free(targaddr->buf); 9388360efbdSAlfred Perlstein free(targaddr); 9398360efbdSAlfred Perlstein } 9408360efbdSAlfred Perlstein parms.r_owner = nullstring; 9418360efbdSAlfred Perlstein 9428360efbdSAlfred Perlstein if (CLNT_CALL(client, RPCBPROC_GETADDRLIST, (xdrproc_t) xdr_rpcb, 9438360efbdSAlfred Perlstein (char *) &parms, (xdrproc_t) xdr_rpcb_entry_list_ptr, 9448360efbdSAlfred Perlstein (char *) &head, minutetimeout) != RPC_SUCCESS) { 9458360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 9468360efbdSAlfred Perlstein exit(1); 9478360efbdSAlfred Perlstein } 9488360efbdSAlfred Perlstein if (head == NULL) { 9498360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 9508360efbdSAlfred Perlstein } else { 9518360efbdSAlfred Perlstein printf( 9528360efbdSAlfred Perlstein " program vers tp_family/name/class address\t\t service\n"); 9538360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_entry_next) { 9548360efbdSAlfred Perlstein rpcb_entry *re; 9558360efbdSAlfred Perlstein char buf[128]; 9568360efbdSAlfred Perlstein 9578360efbdSAlfred Perlstein re = &head->rpcb_entry_map; 9588360efbdSAlfred Perlstein printf("%10u%3u ", 9598360efbdSAlfred Perlstein parms.r_prog, parms.r_vers); 9608360efbdSAlfred Perlstein sprintf(buf, "%s/%s/%s ", 9618360efbdSAlfred Perlstein re->r_nc_protofmly, re->r_nc_proto, 9628360efbdSAlfred Perlstein re->r_nc_semantics == NC_TPI_CLTS ? "clts" : 9638360efbdSAlfred Perlstein re->r_nc_semantics == NC_TPI_COTS ? "cots" : 9648360efbdSAlfred Perlstein "cots_ord"); 9658360efbdSAlfred Perlstein printf("%-24s", buf); 9668360efbdSAlfred Perlstein printf("%-24s", re->r_maddr); 9678360efbdSAlfred Perlstein rpc = getrpcbynumber(parms.r_prog); 9688360efbdSAlfred Perlstein if (rpc) 9698360efbdSAlfred Perlstein printf(" %-13s", rpc->r_name); 9708360efbdSAlfred Perlstein else 9718360efbdSAlfred Perlstein printf(" %-13s", "-"); 9728360efbdSAlfred Perlstein printf("\n"); 9738360efbdSAlfred Perlstein } 9748360efbdSAlfred Perlstein } 9758360efbdSAlfred Perlstein clnt_destroy(client); 9768360efbdSAlfred Perlstein return; 9778360efbdSAlfred Perlstein } 9788360efbdSAlfred Perlstein 9798360efbdSAlfred Perlstein /* 9808360efbdSAlfred Perlstein * monitor rpcbind 9818360efbdSAlfred Perlstein */ 9828360efbdSAlfred Perlstein static void 9838360efbdSAlfred Perlstein rpcbgetstat(int argc, char **argv) 9848360efbdSAlfred Perlstein { 9858360efbdSAlfred Perlstein rpcb_stat_byvers inf; 9868360efbdSAlfred Perlstein struct timeval minutetimeout; 9878360efbdSAlfred Perlstein register CLIENT *client; 9888360efbdSAlfred Perlstein char *host; 9898360efbdSAlfred Perlstein int i, j; 9908360efbdSAlfred Perlstein rpcbs_addrlist *pa; 9918360efbdSAlfred Perlstein rpcbs_rmtcalllist *pr; 9928360efbdSAlfred Perlstein int cnt, flen; 9938360efbdSAlfred Perlstein #define MAXFIELD 64 9948360efbdSAlfred Perlstein char fieldbuf[MAXFIELD]; 9958360efbdSAlfred Perlstein #define MAXLINE 256 9968360efbdSAlfred Perlstein char linebuf[MAXLINE]; 9978360efbdSAlfred Perlstein char *cp, *lp; 99861382374SXin LI const char *pmaphdr[] = { 9998360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETPORT", 10008360efbdSAlfred Perlstein "DUMP", "CALLIT" 10018360efbdSAlfred Perlstein }; 100261382374SXin LI const char *rpcb3hdr[] = { 10038360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME", 10048360efbdSAlfred Perlstein "U2T", "T2U" 10058360efbdSAlfred Perlstein }; 100661382374SXin LI const char *rpcb4hdr[] = { 10078360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME", 10088360efbdSAlfred Perlstein "U2T", "T2U", "VERADDR", "INDRECT", "GETLIST", "GETSTAT" 10098360efbdSAlfred Perlstein }; 10108360efbdSAlfred Perlstein 10118360efbdSAlfred Perlstein #define TABSTOP 8 10128360efbdSAlfred Perlstein 10138360efbdSAlfred Perlstein if (argc >= 1) { 10148360efbdSAlfred Perlstein host = argv[0]; 10158360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS4, NULL); 10168360efbdSAlfred Perlstein } else 10178360efbdSAlfred Perlstein client = local_rpcb(PMAPPROG, RPCBVERS4); 10188360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 10198360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 10208360efbdSAlfred Perlstein exit(1); 10218360efbdSAlfred Perlstein } 10228360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 10238360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 10248360efbdSAlfred Perlstein memset((char *)&inf, 0, sizeof (rpcb_stat_byvers)); 10258360efbdSAlfred Perlstein if (CLNT_CALL(client, RPCBPROC_GETSTAT, (xdrproc_t) xdr_void, NULL, 10268360efbdSAlfred Perlstein (xdrproc_t) xdr_rpcb_stat_byvers, (char *)&inf, minutetimeout) 10278360efbdSAlfred Perlstein != RPC_SUCCESS) { 10288360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 10298360efbdSAlfred Perlstein exit(1); 10308360efbdSAlfred Perlstein } 10318360efbdSAlfred Perlstein printf("PORTMAP (version 2) statistics\n"); 10328360efbdSAlfred Perlstein lp = linebuf; 10338360efbdSAlfred Perlstein for (i = 0; i <= rpcb_highproc_2; i++) { 10348360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 10358360efbdSAlfred Perlstein switch (i) { 10368360efbdSAlfred Perlstein case PMAPPROC_SET: 10378360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", inf[RPCBVERS_2_STAT].setinfo); 10388360efbdSAlfred Perlstein break; 10398360efbdSAlfred Perlstein case PMAPPROC_UNSET: 10408360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 10418360efbdSAlfred Perlstein inf[RPCBVERS_2_STAT].unsetinfo); 10428360efbdSAlfred Perlstein break; 10438360efbdSAlfred Perlstein case PMAPPROC_GETPORT: 10448360efbdSAlfred Perlstein cnt = 0; 10458360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_2_STAT].addrinfo; pa; 10468360efbdSAlfred Perlstein pa = pa->next) 10478360efbdSAlfred Perlstein cnt += pa->success; 10488360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 10498360efbdSAlfred Perlstein break; 10508360efbdSAlfred Perlstein case PMAPPROC_CALLIT: 10518360efbdSAlfred Perlstein cnt = 0; 10528360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_2_STAT].rmtinfo; pr; 10538360efbdSAlfred Perlstein pr = pr->next) 10548360efbdSAlfred Perlstein cnt += pr->success; 10558360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 10568360efbdSAlfred Perlstein break; 10578360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 10588360efbdSAlfred Perlstein } 10598360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 10608360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_2_STAT].info[i]); 10618360efbdSAlfred Perlstein flen = strlen(fieldbuf); 10628360efbdSAlfred Perlstein printf("%s%s", pmaphdr[i], 10638360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 10648360efbdSAlfred Perlstein - strlen(pmaphdr[i]))); 10658360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 10668360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 10678360efbdSAlfred Perlstein - flen))); 10688360efbdSAlfred Perlstein lp += (flen + cnt); 10698360efbdSAlfred Perlstein } 10708360efbdSAlfred Perlstein printf("\n%s\n\n", linebuf); 10718360efbdSAlfred Perlstein 10728360efbdSAlfred Perlstein if (inf[RPCBVERS_2_STAT].info[PMAPPROC_CALLIT]) { 10738360efbdSAlfred Perlstein printf("PMAP_RMTCALL call statistics\n"); 10748360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]); 10758360efbdSAlfred Perlstein printf("\n"); 10768360efbdSAlfred Perlstein } 10778360efbdSAlfred Perlstein 10788360efbdSAlfred Perlstein if (inf[RPCBVERS_2_STAT].info[PMAPPROC_GETPORT]) { 10798360efbdSAlfred Perlstein printf("PMAP_GETPORT call statistics\n"); 10808360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]); 10818360efbdSAlfred Perlstein printf("\n"); 10828360efbdSAlfred Perlstein } 10838360efbdSAlfred Perlstein 10848360efbdSAlfred Perlstein printf("RPCBIND (version 3) statistics\n"); 10858360efbdSAlfred Perlstein lp = linebuf; 10868360efbdSAlfred Perlstein for (i = 0; i <= rpcb_highproc_3; i++) { 10878360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 10888360efbdSAlfred Perlstein switch (i) { 10898360efbdSAlfred Perlstein case RPCBPROC_SET: 10908360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", inf[RPCBVERS_3_STAT].setinfo); 10918360efbdSAlfred Perlstein break; 10928360efbdSAlfred Perlstein case RPCBPROC_UNSET: 10938360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 10948360efbdSAlfred Perlstein inf[RPCBVERS_3_STAT].unsetinfo); 10958360efbdSAlfred Perlstein break; 10968360efbdSAlfred Perlstein case RPCBPROC_GETADDR: 10978360efbdSAlfred Perlstein cnt = 0; 10988360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_3_STAT].addrinfo; pa; 10998360efbdSAlfred Perlstein pa = pa->next) 11008360efbdSAlfred Perlstein cnt += pa->success; 11018360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11028360efbdSAlfred Perlstein break; 11038360efbdSAlfred Perlstein case RPCBPROC_CALLIT: 11048360efbdSAlfred Perlstein cnt = 0; 11058360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_3_STAT].rmtinfo; pr; 11068360efbdSAlfred Perlstein pr = pr->next) 11078360efbdSAlfred Perlstein cnt += pr->success; 11088360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11098360efbdSAlfred Perlstein break; 11108360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 11118360efbdSAlfred Perlstein } 11128360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 11138360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_3_STAT].info[i]); 11148360efbdSAlfred Perlstein flen = strlen(fieldbuf); 11158360efbdSAlfred Perlstein printf("%s%s", rpcb3hdr[i], 11168360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 11178360efbdSAlfred Perlstein - strlen(rpcb3hdr[i]))); 11188360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 11198360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 11208360efbdSAlfred Perlstein - flen))); 11218360efbdSAlfred Perlstein lp += (flen + cnt); 11228360efbdSAlfred Perlstein } 11238360efbdSAlfred Perlstein printf("\n%s\n\n", linebuf); 11248360efbdSAlfred Perlstein 11258360efbdSAlfred Perlstein if (inf[RPCBVERS_3_STAT].info[RPCBPROC_CALLIT]) { 11268360efbdSAlfred Perlstein printf("RPCB_RMTCALL (version 3) call statistics\n"); 11278360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]); 11288360efbdSAlfred Perlstein printf("\n"); 11298360efbdSAlfred Perlstein } 11308360efbdSAlfred Perlstein 11318360efbdSAlfred Perlstein if (inf[RPCBVERS_3_STAT].info[RPCBPROC_GETADDR]) { 11328360efbdSAlfred Perlstein printf("RPCB_GETADDR (version 3) call statistics\n"); 11338360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]); 11348360efbdSAlfred Perlstein printf("\n"); 11358360efbdSAlfred Perlstein } 11368360efbdSAlfred Perlstein 11378360efbdSAlfred Perlstein printf("RPCBIND (version 4) statistics\n"); 11388360efbdSAlfred Perlstein 11398360efbdSAlfred Perlstein for (j = 0; j <= 9; j += 9) { /* Just two iterations for printing */ 11408360efbdSAlfred Perlstein lp = linebuf; 11418360efbdSAlfred Perlstein for (i = j; i <= MAX(8, rpcb_highproc_4 - 9 + j); i++) { 11428360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 11438360efbdSAlfred Perlstein switch (i) { 11448360efbdSAlfred Perlstein case RPCBPROC_SET: 11458360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 11468360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].setinfo); 11478360efbdSAlfred Perlstein break; 11488360efbdSAlfred Perlstein case RPCBPROC_UNSET: 11498360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 11508360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].unsetinfo); 11518360efbdSAlfred Perlstein break; 11528360efbdSAlfred Perlstein case RPCBPROC_GETADDR: 11538360efbdSAlfred Perlstein cnt = 0; 11548360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_4_STAT].addrinfo; pa; 11558360efbdSAlfred Perlstein pa = pa->next) 11568360efbdSAlfred Perlstein cnt += pa->success; 11578360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11588360efbdSAlfred Perlstein break; 11598360efbdSAlfred Perlstein case RPCBPROC_CALLIT: 11608360efbdSAlfred Perlstein cnt = 0; 11618360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_4_STAT].rmtinfo; pr; 11628360efbdSAlfred Perlstein pr = pr->next) 11638360efbdSAlfred Perlstein cnt += pr->success; 11648360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11658360efbdSAlfred Perlstein break; 11668360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 11678360efbdSAlfred Perlstein } 11688360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 11698360efbdSAlfred Perlstein /* 11708360efbdSAlfred Perlstein * XXX: We also add RPCBPROC_GETADDRLIST queries to 11718360efbdSAlfred Perlstein * RPCB_GETADDR because rpcbind includes the 11728360efbdSAlfred Perlstein * RPCB_GETADDRLIST successes in RPCB_GETADDR. 11738360efbdSAlfred Perlstein */ 11748360efbdSAlfred Perlstein if (i != RPCBPROC_GETADDR) 11758360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_4_STAT].info[i]); 11768360efbdSAlfred Perlstein else 11778360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_4_STAT].info[i] + 11788360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDRLIST]); 11798360efbdSAlfred Perlstein flen = strlen(fieldbuf); 11808360efbdSAlfred Perlstein printf("%s%s", rpcb4hdr[i], 11818360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 11828360efbdSAlfred Perlstein - strlen(rpcb4hdr[i]))); 11838360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 11848360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 11858360efbdSAlfred Perlstein - flen))); 11868360efbdSAlfred Perlstein lp += (flen + cnt); 11878360efbdSAlfred Perlstein } 11888360efbdSAlfred Perlstein printf("\n%s\n", linebuf); 11898360efbdSAlfred Perlstein } 11908360efbdSAlfred Perlstein 11918360efbdSAlfred Perlstein if (inf[RPCBVERS_4_STAT].info[RPCBPROC_CALLIT] || 11928360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].info[RPCBPROC_INDIRECT]) { 11938360efbdSAlfred Perlstein printf("\n"); 11948360efbdSAlfred Perlstein printf("RPCB_RMTCALL (version 4) call statistics\n"); 11958360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]); 11968360efbdSAlfred Perlstein } 11978360efbdSAlfred Perlstein 11988360efbdSAlfred Perlstein if (inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDR]) { 11998360efbdSAlfred Perlstein printf("\n"); 12008360efbdSAlfred Perlstein printf("RPCB_GETADDR (version 4) call statistics\n"); 12018360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]); 12028360efbdSAlfred Perlstein } 12038360efbdSAlfred Perlstein clnt_destroy(client); 12048360efbdSAlfred Perlstein } 12058360efbdSAlfred Perlstein 12068360efbdSAlfred Perlstein /* 12078360efbdSAlfred Perlstein * Delete registeration for this (prog, vers, netid) 12088360efbdSAlfred Perlstein */ 12098360efbdSAlfred Perlstein static void 12108360efbdSAlfred Perlstein deletereg(char *netid, int argc, char **argv) 12118360efbdSAlfred Perlstein { 12128360efbdSAlfred Perlstein struct netconfig *nconf = NULL; 12138360efbdSAlfred Perlstein 1214003bc1d4SPhilippe Charnier if (argc != 2) 12158360efbdSAlfred Perlstein usage(); 12168360efbdSAlfred Perlstein if (netid) { 12178360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 1218003bc1d4SPhilippe Charnier if (nconf == NULL) 1219003bc1d4SPhilippe Charnier errx(1, "netid %s not supported", netid); 12208360efbdSAlfred Perlstein } 1221003bc1d4SPhilippe Charnier if ((rpcb_unset(getprognum(argv[0]), getvers(argv[1]), nconf)) == 0) 1222003bc1d4SPhilippe Charnier errx(1, 1223003bc1d4SPhilippe Charnier "could not delete registration for prog %s version %s", 12248360efbdSAlfred Perlstein argv[0], argv[1]); 12258360efbdSAlfred Perlstein } 12268360efbdSAlfred Perlstein 12278360efbdSAlfred Perlstein /* 12288360efbdSAlfred Perlstein * Create and return a handle for the given nconf. 12298360efbdSAlfred Perlstein * Exit if cannot create handle. 12308360efbdSAlfred Perlstein */ 12318360efbdSAlfred Perlstein static CLIENT * 12328360efbdSAlfred Perlstein clnt_addr_create(char *address, struct netconfig *nconf, 12338360efbdSAlfred Perlstein u_long prog, u_long vers) 12348360efbdSAlfred Perlstein { 12358360efbdSAlfred Perlstein CLIENT *client; 12368360efbdSAlfred Perlstein static struct netbuf *nbuf; 12378360efbdSAlfred Perlstein static int fd = RPC_ANYFD; 12388360efbdSAlfred Perlstein 12398360efbdSAlfred Perlstein if (fd == RPC_ANYFD) { 12408360efbdSAlfred Perlstein if ((fd = __rpc_nconf2fd(nconf)) == -1) { 12418360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_TLIERROR; 12428360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 12438360efbdSAlfred Perlstein exit(1); 12448360efbdSAlfred Perlstein } 12458360efbdSAlfred Perlstein /* Convert the uaddr to taddr */ 12468360efbdSAlfred Perlstein nbuf = uaddr2taddr(nconf, address); 1247003bc1d4SPhilippe Charnier if (nbuf == NULL) 1248003bc1d4SPhilippe Charnier errx(1, "no address for client handle"); 12498360efbdSAlfred Perlstein } 12508360efbdSAlfred Perlstein client = clnt_tli_create(fd, nconf, nbuf, prog, vers, 0, 0); 12518360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 12528360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 12538360efbdSAlfred Perlstein exit(1); 12548360efbdSAlfred Perlstein } 12558360efbdSAlfred Perlstein return (client); 12568360efbdSAlfred Perlstein } 12578360efbdSAlfred Perlstein 12588360efbdSAlfred Perlstein /* 12598360efbdSAlfred Perlstein * If the version number is given, ping that (prog, vers); else try to find 12608360efbdSAlfred Perlstein * the version numbers supported for that prog and ping all the versions. 12618360efbdSAlfred Perlstein * Remote rpcbind is not contacted for this service. The requests are 12628360efbdSAlfred Perlstein * sent directly to the services themselves. 12638360efbdSAlfred Perlstein */ 12648360efbdSAlfred Perlstein static void 12658360efbdSAlfred Perlstein addrping(char *address, char *netid, int argc, char **argv) 12668360efbdSAlfred Perlstein { 12678360efbdSAlfred Perlstein CLIENT *client; 12688360efbdSAlfred Perlstein struct timeval to; 12698360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 12708360efbdSAlfred Perlstein u_long prognum, versnum, minvers, maxvers; 12718360efbdSAlfred Perlstein struct rpc_err rpcerr; 12728360efbdSAlfred Perlstein int failure = 0; 12738360efbdSAlfred Perlstein struct netconfig *nconf; 12748360efbdSAlfred Perlstein int fd; 12758360efbdSAlfred Perlstein 1276003bc1d4SPhilippe Charnier if (argc < 1 || argc > 2 || (netid == NULL)) 12778360efbdSAlfred Perlstein usage(); 12788360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 1279003bc1d4SPhilippe Charnier if (nconf == (struct netconfig *)NULL) 1280003bc1d4SPhilippe Charnier errx(1, "could not find %s", netid); 12818360efbdSAlfred Perlstein to.tv_sec = 10; 12828360efbdSAlfred Perlstein to.tv_usec = 0; 12838360efbdSAlfred Perlstein prognum = getprognum(argv[0]); 12848360efbdSAlfred Perlstein if (argc == 1) { /* Version number not known */ 1285e99a5be3SGarrett Wollman /* 1286e99a5be3SGarrett Wollman * A call to version 0 should fail with a program/version 1287e99a5be3SGarrett Wollman * mismatch, and give us the range of versions supported. 1288e99a5be3SGarrett Wollman */ 12898360efbdSAlfred Perlstein versnum = MIN_VERS; 12908360efbdSAlfred Perlstein } else { 12918360efbdSAlfred Perlstein versnum = getvers(argv[1]); 1292e99a5be3SGarrett Wollman } 12938360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, versnum); 12948360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 12958360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 12968360efbdSAlfred Perlstein (char *)NULL, to); 12978360efbdSAlfred Perlstein if (argc == 2) { 12988360efbdSAlfred Perlstein /* Version number was known */ 12998360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 13008360efbdSAlfred Perlstein failure = 1; 13018360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 13028360efbdSAlfred Perlstein if (failure) 13038360efbdSAlfred Perlstein exit(1); 13048360efbdSAlfred Perlstein return; 13058360efbdSAlfred Perlstein } 13068360efbdSAlfred Perlstein /* Version number not known */ 13078360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL); 13088360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLGET_FD, (char *)&fd); 1309e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 1310e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1311e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 1312e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 1313e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 1314e99a5be3SGarrett Wollman /* 1315e99a5be3SGarrett Wollman * Oh dear, it DOES support version 0. 1316e99a5be3SGarrett Wollman * Let's try version MAX_VERS. 1317e99a5be3SGarrett Wollman */ 13188360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 13198360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, MAX_VERS); 13208360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 13218360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 13228360efbdSAlfred Perlstein (char *)NULL, to); 1323e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 1324e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1325e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 1326e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 1327e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 1328e99a5be3SGarrett Wollman /* 1329e99a5be3SGarrett Wollman * It also supports version MAX_VERS. 1330e99a5be3SGarrett Wollman * Looks like we have a wise guy. 1331e99a5be3SGarrett Wollman * OK, we give them information on all 1332e99a5be3SGarrett Wollman * 4 billion versions they support... 1333e99a5be3SGarrett Wollman */ 1334e99a5be3SGarrett Wollman minvers = 0; 1335e99a5be3SGarrett Wollman maxvers = MAX_VERS; 1336e99a5be3SGarrett Wollman } else { 1337e99a5be3SGarrett Wollman (void) pstatus(client, prognum, MAX_VERS); 1338e99a5be3SGarrett Wollman exit(1); 1339e99a5be3SGarrett Wollman } 1340e99a5be3SGarrett Wollman } else { 13418360efbdSAlfred Perlstein (void) pstatus(client, prognum, (u_long)0); 1342e99a5be3SGarrett Wollman exit(1); 1343e99a5be3SGarrett Wollman } 13448360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 13458360efbdSAlfred Perlstein for (versnum = minvers; versnum <= maxvers; versnum++) { 13468360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, versnum); 13478360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 13488360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 13498360efbdSAlfred Perlstein (char *)NULL, to); 13508360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 1351e99a5be3SGarrett Wollman failure = 1; 13528360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 1353e99a5be3SGarrett Wollman } 13548360efbdSAlfred Perlstein (void) close(fd); 1355e99a5be3SGarrett Wollman if (failure) 1356e99a5be3SGarrett Wollman exit(1); 13578360efbdSAlfred Perlstein return; 13588360efbdSAlfred Perlstein } 13598360efbdSAlfred Perlstein 13608360efbdSAlfred Perlstein /* 13618360efbdSAlfred Perlstein * If the version number is given, ping that (prog, vers); else try to find 13628360efbdSAlfred Perlstein * the version numbers supported for that prog and ping all the versions. 13638360efbdSAlfred Perlstein * Remote rpcbind is *contacted* for this service. The requests are 13648360efbdSAlfred Perlstein * then sent directly to the services themselves. 13658360efbdSAlfred Perlstein */ 13668360efbdSAlfred Perlstein static void 13678360efbdSAlfred Perlstein progping(char *netid, int argc, char **argv) 13688360efbdSAlfred Perlstein { 13698360efbdSAlfred Perlstein CLIENT *client; 13708360efbdSAlfred Perlstein struct timeval to; 13718360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 13728360efbdSAlfred Perlstein u_long prognum, versnum, minvers, maxvers; 13738360efbdSAlfred Perlstein struct rpc_err rpcerr; 13748360efbdSAlfred Perlstein int failure = 0; 13758360efbdSAlfred Perlstein struct netconfig *nconf; 13768360efbdSAlfred Perlstein 1377003bc1d4SPhilippe Charnier if (argc < 2 || argc > 3 || (netid == NULL)) 13788360efbdSAlfred Perlstein usage(); 13798360efbdSAlfred Perlstein prognum = getprognum(argv[1]); 13808360efbdSAlfred Perlstein if (argc == 2) { /* Version number not known */ 13818360efbdSAlfred Perlstein /* 13828360efbdSAlfred Perlstein * A call to version 0 should fail with a program/version 13838360efbdSAlfred Perlstein * mismatch, and give us the range of versions supported. 13848360efbdSAlfred Perlstein */ 13858360efbdSAlfred Perlstein versnum = MIN_VERS; 13868360efbdSAlfred Perlstein } else { 13878360efbdSAlfred Perlstein versnum = getvers(argv[2]); 13888360efbdSAlfred Perlstein } 13898360efbdSAlfred Perlstein if (netid) { 13908360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 1391003bc1d4SPhilippe Charnier if (nconf == (struct netconfig *)NULL) 1392003bc1d4SPhilippe Charnier errx(1, "could not find %s", netid); 13938360efbdSAlfred Perlstein client = clnt_tp_create(argv[0], prognum, versnum, nconf); 13948360efbdSAlfred Perlstein } else { 13958360efbdSAlfred Perlstein client = clnt_create(argv[0], prognum, versnum, "NETPATH"); 13968360efbdSAlfred Perlstein } 13978360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 13988360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 13998360efbdSAlfred Perlstein exit(1); 14008360efbdSAlfred Perlstein } 14018360efbdSAlfred Perlstein to.tv_sec = 10; 14028360efbdSAlfred Perlstein to.tv_usec = 0; 14038360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 14048360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 14058360efbdSAlfred Perlstein (char *)NULL, to); 14068360efbdSAlfred Perlstein if (argc == 3) { 14078360efbdSAlfred Perlstein /* Version number was known */ 14088360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 14098360efbdSAlfred Perlstein failure = 1; 14108360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 14118360efbdSAlfred Perlstein if (failure) 14128360efbdSAlfred Perlstein exit(1); 14138360efbdSAlfred Perlstein return; 14148360efbdSAlfred Perlstein } 14158360efbdSAlfred Perlstein /* Version number not known */ 14168360efbdSAlfred Perlstein if (rpc_stat == RPC_PROGVERSMISMATCH) { 14178360efbdSAlfred Perlstein clnt_geterr(client, &rpcerr); 14188360efbdSAlfred Perlstein minvers = rpcerr.re_vers.low; 14198360efbdSAlfred Perlstein maxvers = rpcerr.re_vers.high; 14208360efbdSAlfred Perlstein } else if (rpc_stat == RPC_SUCCESS) { 14218360efbdSAlfred Perlstein /* 14228360efbdSAlfred Perlstein * Oh dear, it DOES support version 0. 14238360efbdSAlfred Perlstein * Let's try version MAX_VERS. 14248360efbdSAlfred Perlstein */ 14258360efbdSAlfred Perlstein versnum = MAX_VERS; 14268360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum); 14278360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, 14288360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, 14298360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, to); 14308360efbdSAlfred Perlstein if (rpc_stat == RPC_PROGVERSMISMATCH) { 14318360efbdSAlfred Perlstein clnt_geterr(client, &rpcerr); 14328360efbdSAlfred Perlstein minvers = rpcerr.re_vers.low; 14338360efbdSAlfred Perlstein maxvers = rpcerr.re_vers.high; 14348360efbdSAlfred Perlstein } else if (rpc_stat == RPC_SUCCESS) { 14358360efbdSAlfred Perlstein /* 14368360efbdSAlfred Perlstein * It also supports version MAX_VERS. 14378360efbdSAlfred Perlstein * Looks like we have a wise guy. 14388360efbdSAlfred Perlstein * OK, we give them information on all 14398360efbdSAlfred Perlstein * 4 billion versions they support... 14408360efbdSAlfred Perlstein */ 14418360efbdSAlfred Perlstein minvers = 0; 14428360efbdSAlfred Perlstein maxvers = MAX_VERS; 14438360efbdSAlfred Perlstein } else { 14448360efbdSAlfred Perlstein (void) pstatus(client, prognum, MAX_VERS); 14458360efbdSAlfred Perlstein exit(1); 14468360efbdSAlfred Perlstein } 14478360efbdSAlfred Perlstein } else { 14488360efbdSAlfred Perlstein (void) pstatus(client, prognum, (u_long)0); 14498360efbdSAlfred Perlstein exit(1); 14508360efbdSAlfred Perlstein } 14518360efbdSAlfred Perlstein for (versnum = minvers; versnum <= maxvers; versnum++) { 14528360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum); 14538360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 14548360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 14558360efbdSAlfred Perlstein (char *)NULL, to); 14568360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 14578360efbdSAlfred Perlstein failure = 1; 14588360efbdSAlfred Perlstein } 14598360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 14608360efbdSAlfred Perlstein if (failure) 14618360efbdSAlfred Perlstein exit(1); 14628360efbdSAlfred Perlstein return; 14638360efbdSAlfred Perlstein } 14648360efbdSAlfred Perlstein 14658360efbdSAlfred Perlstein static void 146661382374SXin LI usage(void) 14678360efbdSAlfred Perlstein { 1468d3974088SDag-Erling Smørgrav fprintf(stderr, "usage: rpcinfo [-m | -s] [host]\n"); 14698360efbdSAlfred Perlstein #ifdef PORTMAP 14708360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -p [host]\n"); 14718360efbdSAlfred Perlstein #endif 14728360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -T netid host prognum [versnum]\n"); 14738360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -l host prognum versnum\n"); 14748360efbdSAlfred Perlstein #ifdef PORTMAP 14758360efbdSAlfred Perlstein fprintf(stderr, 14768360efbdSAlfred Perlstein " rpcinfo [-n portnum] -u | -t host prognum [versnum]\n"); 14778360efbdSAlfred Perlstein #endif 14788360efbdSAlfred Perlstein fprintf(stderr, 14798360efbdSAlfred Perlstein " rpcinfo -a serv_address -T netid prognum [version]\n"); 14808360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -b prognum versnum\n"); 14818360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -d [-T netid] prognum versnum\n"); 1482003bc1d4SPhilippe Charnier exit(1); 14838360efbdSAlfred Perlstein } 14848360efbdSAlfred Perlstein 14858360efbdSAlfred Perlstein static u_long 14868360efbdSAlfred Perlstein getprognum (char *arg) 14878360efbdSAlfred Perlstein { 14888360efbdSAlfred Perlstein char *strptr; 14898360efbdSAlfred Perlstein register struct rpcent *rpc; 14908360efbdSAlfred Perlstein register u_long prognum; 14918360efbdSAlfred Perlstein char *tptr = arg; 14928360efbdSAlfred Perlstein 14938360efbdSAlfred Perlstein while (*tptr && isdigit(*tptr++)); 14948360efbdSAlfred Perlstein if (*tptr || isalpha(*(tptr - 1))) { 14958360efbdSAlfred Perlstein rpc = getrpcbyname(arg); 1496003bc1d4SPhilippe Charnier if (rpc == NULL) 1497003bc1d4SPhilippe Charnier errx(1, "%s is unknown service", arg); 14988360efbdSAlfred Perlstein prognum = rpc->r_number; 14998360efbdSAlfred Perlstein } else { 15008360efbdSAlfred Perlstein prognum = strtol(arg, &strptr, 10); 1501003bc1d4SPhilippe Charnier if (strptr == arg || *strptr != '\0') 1502003bc1d4SPhilippe Charnier errx(1, "%s is illegal program number", arg); 15038360efbdSAlfred Perlstein } 15048360efbdSAlfred Perlstein return (prognum); 15058360efbdSAlfred Perlstein } 15068360efbdSAlfred Perlstein 15078360efbdSAlfred Perlstein static u_long 15088360efbdSAlfred Perlstein getvers(char *arg) 15098360efbdSAlfred Perlstein { 15108360efbdSAlfred Perlstein char *strptr; 15118360efbdSAlfred Perlstein register u_long vers; 15128360efbdSAlfred Perlstein 15138360efbdSAlfred Perlstein vers = (int) strtol(arg, &strptr, 10); 1514003bc1d4SPhilippe Charnier if (strptr == arg || *strptr != '\0') 1515003bc1d4SPhilippe Charnier errx(1, "%s is illegal version number", arg); 15168360efbdSAlfred Perlstein return (vers); 1517e99a5be3SGarrett Wollman } 1518e99a5be3SGarrett Wollman 1519e99a5be3SGarrett Wollman /* 1520e99a5be3SGarrett Wollman * This routine should take a pointer to an "rpc_err" structure, rather than 1521e99a5be3SGarrett Wollman * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to 1522e99a5be3SGarrett Wollman * a CLIENT structure rather than a pointer to an "rpc_err" structure. 1523e99a5be3SGarrett Wollman * As such, we have to keep the CLIENT structure around in order to print 1524e99a5be3SGarrett Wollman * a good error message. 1525e99a5be3SGarrett Wollman */ 1526e99a5be3SGarrett Wollman static int 15278360efbdSAlfred Perlstein pstatus(register CLIENT *client, u_long prog, u_long vers) 1528e99a5be3SGarrett Wollman { 1529e99a5be3SGarrett Wollman struct rpc_err rpcerr; 1530e99a5be3SGarrett Wollman 1531e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1532e99a5be3SGarrett Wollman if (rpcerr.re_status != RPC_SUCCESS) { 1533e99a5be3SGarrett Wollman clnt_perror(client, "rpcinfo"); 1534e99a5be3SGarrett Wollman printf("program %lu version %lu is not available\n", 15358360efbdSAlfred Perlstein prog, vers); 1536e99a5be3SGarrett Wollman return (-1); 1537e99a5be3SGarrett Wollman } else { 1538e99a5be3SGarrett Wollman printf("program %lu version %lu ready and waiting\n", 15398360efbdSAlfred Perlstein prog, vers); 1540e99a5be3SGarrett Wollman return (0); 1541e99a5be3SGarrett Wollman } 1542e99a5be3SGarrett Wollman } 1543e99a5be3SGarrett Wollman 15448360efbdSAlfred Perlstein static CLIENT * 15458360efbdSAlfred Perlstein clnt_rpcbind_create(char *host, int rpcbversnum, struct netbuf **targaddr) 1546e99a5be3SGarrett Wollman { 154761382374SXin LI static const char *tlist[3] = { 15488360efbdSAlfred Perlstein "circuit_n", "circuit_v", "datagram_v" 15498360efbdSAlfred Perlstein }; 15508360efbdSAlfred Perlstein int i; 15518360efbdSAlfred Perlstein struct netconfig *nconf; 15528360efbdSAlfred Perlstein CLIENT *clnt = NULL; 15538360efbdSAlfred Perlstein void *handle; 15548360efbdSAlfred Perlstein 15558360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_SUCCESS; 15568360efbdSAlfred Perlstein for (i = 0; i < 3; i++) { 15578360efbdSAlfred Perlstein if ((handle = __rpc_setconf(tlist[i])) == NULL) 15588360efbdSAlfred Perlstein continue; 15598360efbdSAlfred Perlstein while (clnt == (CLIENT *)NULL) { 15608360efbdSAlfred Perlstein if ((nconf = __rpc_getconf(handle)) == NULL) { 15618360efbdSAlfred Perlstein if (rpc_createerr.cf_stat == RPC_SUCCESS) 15628360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 15638360efbdSAlfred Perlstein break; 15648360efbdSAlfred Perlstein } 15658360efbdSAlfred Perlstein clnt = getclnthandle(host, nconf, rpcbversnum, 15668360efbdSAlfred Perlstein targaddr); 15678360efbdSAlfred Perlstein } 15688360efbdSAlfred Perlstein if (clnt) 15698360efbdSAlfred Perlstein break; 15708360efbdSAlfred Perlstein __rpc_endconf(handle); 15718360efbdSAlfred Perlstein } 15728360efbdSAlfred Perlstein return (clnt); 15738360efbdSAlfred Perlstein } 15748360efbdSAlfred Perlstein 15758360efbdSAlfred Perlstein static CLIENT* 15768360efbdSAlfred Perlstein getclnthandle(char *host, struct netconfig *nconf, 15778360efbdSAlfred Perlstein u_long rpcbversnum, struct netbuf **targaddr) 15788360efbdSAlfred Perlstein { 15798360efbdSAlfred Perlstein struct netbuf addr; 15808360efbdSAlfred Perlstein struct addrinfo hints, *res; 15818360efbdSAlfred Perlstein CLIENT *client = NULL; 15828360efbdSAlfred Perlstein 15838360efbdSAlfred Perlstein /* Get the address of the rpcbind */ 15848360efbdSAlfred Perlstein memset(&hints, 0, sizeof hints); 15858360efbdSAlfred Perlstein if (getaddrinfo(host, "rpcbind", &hints, &res) != 0) { 15868360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; 15878360efbdSAlfred Perlstein return (NULL); 15888360efbdSAlfred Perlstein } 15898360efbdSAlfred Perlstein addr.len = addr.maxlen = res->ai_addrlen; 15908360efbdSAlfred Perlstein addr.buf = res->ai_addr; 15918360efbdSAlfred Perlstein client = clnt_tli_create(RPC_ANYFD, nconf, &addr, RPCBPROG, 15928360efbdSAlfred Perlstein rpcbversnum, 0, 0); 15938360efbdSAlfred Perlstein if (client) { 15948360efbdSAlfred Perlstein if (targaddr != NULL) { 15958360efbdSAlfred Perlstein *targaddr = 15968360efbdSAlfred Perlstein (struct netbuf *)malloc(sizeof (struct netbuf)); 15978360efbdSAlfred Perlstein if (*targaddr != NULL) { 15988360efbdSAlfred Perlstein (*targaddr)->maxlen = addr.maxlen; 15998360efbdSAlfred Perlstein (*targaddr)->len = addr.len; 16008360efbdSAlfred Perlstein (*targaddr)->buf = (char *)malloc(addr.len); 16018360efbdSAlfred Perlstein if ((*targaddr)->buf != NULL) { 16028360efbdSAlfred Perlstein memcpy((*targaddr)->buf, addr.buf, 16038360efbdSAlfred Perlstein addr.len); 16048360efbdSAlfred Perlstein } 16058360efbdSAlfred Perlstein } 16068360efbdSAlfred Perlstein } 16078360efbdSAlfred Perlstein } else { 16088360efbdSAlfred Perlstein if (rpc_createerr.cf_stat == RPC_TLIERROR) { 16098360efbdSAlfred Perlstein /* 16108360efbdSAlfred Perlstein * Assume that the other system is dead; this is a 16118360efbdSAlfred Perlstein * better error to display to the user. 16128360efbdSAlfred Perlstein */ 16138360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_RPCBFAILURE; 16148360efbdSAlfred Perlstein rpc_createerr.cf_error.re_status = RPC_FAILED; 16158360efbdSAlfred Perlstein } 16168360efbdSAlfred Perlstein } 16178360efbdSAlfred Perlstein freeaddrinfo(res); 16188360efbdSAlfred Perlstein return (client); 16198360efbdSAlfred Perlstein } 16208360efbdSAlfred Perlstein 16218360efbdSAlfred Perlstein static void 16228360efbdSAlfred Perlstein print_rmtcallstat(int rtype, rpcb_stat *infp) 16238360efbdSAlfred Perlstein { 16248360efbdSAlfred Perlstein register rpcbs_rmtcalllist_ptr pr; 1625e99a5be3SGarrett Wollman struct rpcent *rpc; 1626e99a5be3SGarrett Wollman 16278360efbdSAlfred Perlstein if (rtype == RPCBVERS_4_STAT) 16288360efbdSAlfred Perlstein printf( 16298360efbdSAlfred Perlstein "prog\t\tvers\tproc\tnetid\tindirect success failure\n"); 1630e99a5be3SGarrett Wollman else 16318360efbdSAlfred Perlstein printf("prog\t\tvers\tproc\tnetid\tsuccess\tfailure\n"); 16328360efbdSAlfred Perlstein for (pr = infp->rmtinfo; pr; pr = pr->next) { 16338360efbdSAlfred Perlstein rpc = getrpcbynumber(pr->prog); 1634e99a5be3SGarrett Wollman if (rpc) 16358360efbdSAlfred Perlstein printf("%-16s", rpc->r_name); 1636e99a5be3SGarrett Wollman else 16378360efbdSAlfred Perlstein printf("%-16d", pr->prog); 16388360efbdSAlfred Perlstein printf("%d\t%d\t%s\t", 16398360efbdSAlfred Perlstein pr->vers, pr->proc, pr->netid); 16408360efbdSAlfred Perlstein if (rtype == RPCBVERS_4_STAT) 16418360efbdSAlfred Perlstein printf("%d\t ", pr->indirect); 16428360efbdSAlfred Perlstein printf("%d\t%d\n", pr->success, pr->failure); 1643e99a5be3SGarrett Wollman } 1644e99a5be3SGarrett Wollman } 1645e99a5be3SGarrett Wollman 1646e99a5be3SGarrett Wollman static void 16478360efbdSAlfred Perlstein print_getaddrstat(int rtype, rpcb_stat *infp) 1648e99a5be3SGarrett Wollman { 16498360efbdSAlfred Perlstein rpcbs_addrlist_ptr al; 1650e99a5be3SGarrett Wollman register struct rpcent *rpc; 1651e99a5be3SGarrett Wollman 16528360efbdSAlfred Perlstein printf("prog\t\tvers\tnetid\t success\tfailure\n"); 16538360efbdSAlfred Perlstein for (al = infp->addrinfo; al; al = al->next) { 16548360efbdSAlfred Perlstein rpc = getrpcbynumber(al->prog); 16558360efbdSAlfred Perlstein if (rpc) 16568360efbdSAlfred Perlstein printf("%-16s", rpc->r_name); 16578360efbdSAlfred Perlstein else 16588360efbdSAlfred Perlstein printf("%-16d", al->prog); 16598360efbdSAlfred Perlstein printf("%d\t%s\t %-12d\t%d\n", 16608360efbdSAlfred Perlstein al->vers, al->netid, 16618360efbdSAlfred Perlstein al->success, al->failure); 16628360efbdSAlfred Perlstein } 1663e99a5be3SGarrett Wollman } 1664e99a5be3SGarrett Wollman 16658360efbdSAlfred Perlstein static char * 16668360efbdSAlfred Perlstein spaces(int howmany) 1667e99a5be3SGarrett Wollman { 16688360efbdSAlfred Perlstein static char space_array[] = /* 64 spaces */ 16698360efbdSAlfred Perlstein " "; 1670e99a5be3SGarrett Wollman 16718360efbdSAlfred Perlstein if (howmany <= 0 || howmany > sizeof (space_array)) { 16728360efbdSAlfred Perlstein return (""); 1673e99a5be3SGarrett Wollman } 16748360efbdSAlfred Perlstein return (&space_array[sizeof (space_array) - howmany - 1]); 1675e99a5be3SGarrett Wollman } 1676