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 /* 538360efbdSAlfred Perlstein * We are for now defining PORTMAP here. It doesnt 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 131*61382374SXin 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 *, 133*61382374SXin 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, 339*61382374SXin 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 372*61382374SXin 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; 4798360efbdSAlfred Perlstein char *host; 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); 5168360efbdSAlfred Perlstein if (err.re_vers.low > PMAPVERS) 517003bc1d4SPhilippe Charnier warnx( 518003bc1d4SPhilippe Charnier "%s does not support portmapper. Try rpcinfo %s instead", 5198360efbdSAlfred Perlstein host, host); 5208360efbdSAlfred Perlstein exit(1); 5218360efbdSAlfred Perlstein } 5228360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact portmapper"); 5238360efbdSAlfred Perlstein exit(1); 5248360efbdSAlfred Perlstein } 5258360efbdSAlfred Perlstein if (head == NULL) { 5268360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 5278360efbdSAlfred Perlstein } else { 5288360efbdSAlfred Perlstein printf(" program vers proto port service\n"); 5298360efbdSAlfred Perlstein for (; head != NULL; head = head->pml_next) { 5308360efbdSAlfred Perlstein printf("%10ld%5ld", 5318360efbdSAlfred Perlstein head->pml_map.pm_prog, 5328360efbdSAlfred Perlstein head->pml_map.pm_vers); 5338360efbdSAlfred Perlstein if (head->pml_map.pm_prot == IPPROTO_UDP) 5348360efbdSAlfred Perlstein printf("%6s", "udp"); 5358360efbdSAlfred Perlstein else if (head->pml_map.pm_prot == IPPROTO_TCP) 5368360efbdSAlfred Perlstein printf("%6s", "tcp"); 5378360efbdSAlfred Perlstein else if (head->pml_map.pm_prot == IPPROTO_ST) 538fb4c8061SMartin Blapp printf("%6s", "local"); 5398360efbdSAlfred Perlstein else 5408360efbdSAlfred Perlstein printf("%6ld", head->pml_map.pm_prot); 5418360efbdSAlfred Perlstein printf("%7ld", head->pml_map.pm_port); 5428360efbdSAlfred Perlstein rpc = getrpcbynumber(head->pml_map.pm_prog); 5438360efbdSAlfred Perlstein if (rpc) 5448360efbdSAlfred Perlstein printf(" %s\n", rpc->r_name); 5458360efbdSAlfred Perlstein else 5468360efbdSAlfred Perlstein printf("\n"); 5478360efbdSAlfred Perlstein } 5488360efbdSAlfred Perlstein } 5498360efbdSAlfred Perlstein } 5508360efbdSAlfred Perlstein 5518360efbdSAlfred Perlstein static void 5528360efbdSAlfred Perlstein get_inet_address(struct sockaddr_in *addr, char *host) 5538360efbdSAlfred Perlstein { 5548360efbdSAlfred Perlstein struct netconfig *nconf; 5558360efbdSAlfred Perlstein struct addrinfo hints, *res; 5568360efbdSAlfred Perlstein int error; 5578360efbdSAlfred Perlstein 5588360efbdSAlfred Perlstein (void) memset((char *)addr, 0, sizeof (*addr)); 5598360efbdSAlfred Perlstein addr->sin_addr.s_addr = inet_addr(host); 5608360efbdSAlfred Perlstein if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) { 5618360efbdSAlfred Perlstein if ((nconf = __rpc_getconfip("udp")) == NULL && 562003bc1d4SPhilippe Charnier (nconf = __rpc_getconfip("tcp")) == NULL) 563003bc1d4SPhilippe Charnier errx(1, "couldn't find a suitable transport"); 564003bc1d4SPhilippe Charnier else { 5658360efbdSAlfred Perlstein memset(&hints, 0, sizeof hints); 5668360efbdSAlfred Perlstein hints.ai_family = AF_INET; 5678360efbdSAlfred Perlstein if ((error = getaddrinfo(host, "rpcbind", &hints, &res)) 568003bc1d4SPhilippe Charnier != 0) 569003bc1d4SPhilippe Charnier errx(1, "%s: %s", host, gai_strerror(error)); 570003bc1d4SPhilippe Charnier else { 5718360efbdSAlfred Perlstein memcpy(addr, res->ai_addr, res->ai_addrlen); 5728360efbdSAlfred Perlstein freeaddrinfo(res); 5738360efbdSAlfred Perlstein } 5748360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 5758360efbdSAlfred Perlstein } 5768360efbdSAlfred Perlstein } else { 5778360efbdSAlfred Perlstein addr->sin_family = AF_INET; 5788360efbdSAlfred Perlstein } 5798360efbdSAlfred Perlstein } 5808360efbdSAlfred Perlstein #endif /* PORTMAP */ 5818360efbdSAlfred Perlstein 5828360efbdSAlfred Perlstein /* 5838360efbdSAlfred Perlstein * reply_proc collects replies from the broadcast. 5848360efbdSAlfred Perlstein * to get a unique list of responses the output of rpcinfo should 5858360efbdSAlfred Perlstein * be piped through sort(1) and then uniq(1). 5868360efbdSAlfred Perlstein */ 5878360efbdSAlfred Perlstein 5888360efbdSAlfred Perlstein /*ARGSUSED*/ 5898360efbdSAlfred Perlstein static bool_t 5908360efbdSAlfred Perlstein reply_proc(void *res, struct netbuf *who, struct netconfig *nconf) 5918360efbdSAlfred Perlstein /* void *res; Nothing comes back */ 5928360efbdSAlfred Perlstein /* struct netbuf *who; Who sent us the reply */ 5938360efbdSAlfred Perlstein /* struct netconfig *nconf; On which transport the reply came */ 5948360efbdSAlfred Perlstein { 5958360efbdSAlfred Perlstein char *uaddr; 5968360efbdSAlfred Perlstein char hostbuf[NI_MAXHOST]; 597*61382374SXin LI const char *hostname; 5988360efbdSAlfred Perlstein struct sockaddr *sa = (struct sockaddr *)who->buf; 5998360efbdSAlfred Perlstein 6008360efbdSAlfred Perlstein if (getnameinfo(sa, sa->sa_len, hostbuf, NI_MAXHOST, NULL, 0, 0)) { 6018360efbdSAlfred Perlstein hostname = UNKNOWN; 6028360efbdSAlfred Perlstein } else { 6038360efbdSAlfred Perlstein hostname = hostbuf; 6048360efbdSAlfred Perlstein } 6058360efbdSAlfred Perlstein if (!(uaddr = taddr2uaddr(nconf, who))) { 6068360efbdSAlfred Perlstein uaddr = UNKNOWN; 6078360efbdSAlfred Perlstein } 6088360efbdSAlfred Perlstein printf("%s\t%s\n", uaddr, hostname); 6098360efbdSAlfred Perlstein if (strcmp(uaddr, UNKNOWN)) 6108360efbdSAlfred Perlstein free((char *)uaddr); 6118360efbdSAlfred Perlstein return (FALSE); 6128360efbdSAlfred Perlstein } 6138360efbdSAlfred Perlstein 6148360efbdSAlfred Perlstein static void 6158360efbdSAlfred Perlstein brdcst(int argc, char **argv) 6168360efbdSAlfred Perlstein { 6178360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 6188360efbdSAlfred Perlstein u_long prognum, vers; 6198360efbdSAlfred Perlstein 620003bc1d4SPhilippe Charnier if (argc != 2) 6218360efbdSAlfred Perlstein usage(); 6228360efbdSAlfred Perlstein prognum = getprognum(argv[0]); 6238360efbdSAlfred Perlstein vers = getvers(argv[1]); 6248360efbdSAlfred Perlstein rpc_stat = rpc_broadcast(prognum, vers, NULLPROC, 6258360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, (xdrproc_t) xdr_void, 6268360efbdSAlfred Perlstein (char *)NULL, (resultproc_t) reply_proc, NULL); 627003bc1d4SPhilippe Charnier if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) 628003bc1d4SPhilippe Charnier errx(1, "broadcast failed: %s", clnt_sperrno(rpc_stat)); 6298360efbdSAlfred Perlstein exit(0); 6308360efbdSAlfred Perlstein } 6318360efbdSAlfred Perlstein 6328360efbdSAlfred Perlstein static bool_t 6338360efbdSAlfred Perlstein add_version(struct rpcbdump_short *rs, u_long vers) 6348360efbdSAlfred Perlstein { 6358360efbdSAlfred Perlstein struct verslist *vl; 6368360efbdSAlfred Perlstein 6378360efbdSAlfred Perlstein for (vl = rs->vlist; vl; vl = vl->next) 6388360efbdSAlfred Perlstein if (vl->vers == vers) 6398360efbdSAlfred Perlstein break; 6408360efbdSAlfred Perlstein if (vl) 6418360efbdSAlfred Perlstein return (TRUE); 6428360efbdSAlfred Perlstein vl = (struct verslist *)malloc(sizeof (struct verslist)); 6438360efbdSAlfred Perlstein if (vl == NULL) 6448360efbdSAlfred Perlstein return (FALSE); 6458360efbdSAlfred Perlstein vl->vers = vers; 6468360efbdSAlfred Perlstein vl->next = rs->vlist; 6478360efbdSAlfred Perlstein rs->vlist = vl; 6488360efbdSAlfred Perlstein return (TRUE); 6498360efbdSAlfred Perlstein } 6508360efbdSAlfred Perlstein 6518360efbdSAlfred Perlstein static bool_t 6528360efbdSAlfred Perlstein add_netid(struct rpcbdump_short *rs, char *netid) 6538360efbdSAlfred Perlstein { 6548360efbdSAlfred Perlstein struct netidlist *nl; 6558360efbdSAlfred Perlstein 6568360efbdSAlfred Perlstein for (nl = rs->nlist; nl; nl = nl->next) 6578360efbdSAlfred Perlstein if (strcmp(nl->netid, netid) == 0) 6588360efbdSAlfred Perlstein break; 6598360efbdSAlfred Perlstein if (nl) 6608360efbdSAlfred Perlstein return (TRUE); 6618360efbdSAlfred Perlstein nl = (struct netidlist *)malloc(sizeof (struct netidlist)); 6628360efbdSAlfred Perlstein if (nl == NULL) 6638360efbdSAlfred Perlstein return (FALSE); 6648360efbdSAlfred Perlstein nl->netid = netid; 6658360efbdSAlfred Perlstein nl->next = rs->nlist; 6668360efbdSAlfred Perlstein rs->nlist = nl; 6678360efbdSAlfred Perlstein return (TRUE); 6688360efbdSAlfred Perlstein } 6698360efbdSAlfred Perlstein 6708360efbdSAlfred Perlstein static void 6718360efbdSAlfred Perlstein rpcbdump(int dumptype, char *netid, int argc, char **argv) 6728360efbdSAlfred Perlstein { 6738360efbdSAlfred Perlstein rpcblist_ptr head = NULL; 6748360efbdSAlfred Perlstein struct timeval minutetimeout; 6758360efbdSAlfred Perlstein register CLIENT *client; 6768360efbdSAlfred Perlstein struct rpcent *rpc; 6778360efbdSAlfred Perlstein char *host; 6788360efbdSAlfred Perlstein struct netidlist *nl; 6798360efbdSAlfred Perlstein struct verslist *vl; 6808360efbdSAlfred Perlstein struct rpcbdump_short *rs, *rs_tail; 6818360efbdSAlfred Perlstein char buf[256]; 6828360efbdSAlfred Perlstein enum clnt_stat clnt_st; 6838360efbdSAlfred Perlstein struct rpc_err err; 6848360efbdSAlfred Perlstein struct rpcbdump_short *rs_head = NULL; 6858360efbdSAlfred Perlstein 686003bc1d4SPhilippe Charnier if (argc > 1) 6878360efbdSAlfred Perlstein usage(); 6888360efbdSAlfred Perlstein if (argc == 1) { 6898360efbdSAlfred Perlstein host = argv[0]; 6908360efbdSAlfred Perlstein if (netid == NULL) { 6918360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS, NULL); 6928360efbdSAlfred Perlstein } else { 6938360efbdSAlfred Perlstein struct netconfig *nconf; 6948360efbdSAlfred Perlstein 6958360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 6968360efbdSAlfred Perlstein if (nconf == NULL) { 6978360efbdSAlfred Perlstein nc_perror("rpcinfo: invalid transport"); 6988360efbdSAlfred Perlstein exit(1); 6998360efbdSAlfred Perlstein } 7008360efbdSAlfred Perlstein client = getclnthandle(host, nconf, RPCBVERS, NULL); 7018360efbdSAlfred Perlstein if (nconf) 7028360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 7038360efbdSAlfred Perlstein } 7048360efbdSAlfred Perlstein } else 7058360efbdSAlfred Perlstein client = local_rpcb(PMAPPROG, RPCBVERS); 7068360efbdSAlfred Perlstein 7078360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 7088360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 7098360efbdSAlfred Perlstein exit(1); 7108360efbdSAlfred Perlstein } 7118360efbdSAlfred Perlstein 7128360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 7138360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 7148360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, (xdrproc_t) xdr_void, 7158360efbdSAlfred Perlstein NULL, (xdrproc_t) xdr_rpcblist_ptr, (char *) &head, 7168360efbdSAlfred Perlstein minutetimeout); 7178360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) { 7188360efbdSAlfred Perlstein if ((clnt_st == RPC_PROGVERSMISMATCH) || 7198360efbdSAlfred Perlstein (clnt_st == RPC_PROGUNAVAIL)) { 7208360efbdSAlfred Perlstein int vers; 7218360efbdSAlfred Perlstein 7228360efbdSAlfred Perlstein CLNT_GETERR(client, &err); 7238360efbdSAlfred Perlstein if (err.re_vers.low == RPCBVERS4) { 7248360efbdSAlfred Perlstein vers = RPCBVERS4; 7258360efbdSAlfred Perlstein clnt_control(client, CLSET_VERS, (char *)&vers); 7268360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, 7278360efbdSAlfred Perlstein (xdrproc_t) xdr_void, NULL, 7288360efbdSAlfred Perlstein (xdrproc_t) xdr_rpcblist_ptr, (char *) &head, 7298360efbdSAlfred Perlstein minutetimeout); 7308360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) 7318360efbdSAlfred Perlstein goto failed; 7328360efbdSAlfred Perlstein } else { 7338360efbdSAlfred Perlstein if (err.re_vers.high == PMAPVERS) { 7348360efbdSAlfred Perlstein int high, low; 7358360efbdSAlfred Perlstein struct pmaplist *pmaphead = NULL; 7368360efbdSAlfred Perlstein rpcblist_ptr list, prev; 7378360efbdSAlfred Perlstein 7388360efbdSAlfred Perlstein vers = PMAPVERS; 7398360efbdSAlfred Perlstein clnt_control(client, CLSET_VERS, (char *)&vers); 7408360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, PMAPPROC_DUMP, 7418360efbdSAlfred Perlstein (xdrproc_t) xdr_void, NULL, 7428360efbdSAlfred Perlstein (xdrproc_t) xdr_pmaplist_ptr, 7438360efbdSAlfred Perlstein (char *)&pmaphead, minutetimeout); 7448360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) 7458360efbdSAlfred Perlstein goto failed; 7468360efbdSAlfred Perlstein /* 7478360efbdSAlfred Perlstein * convert to rpcblist_ptr format 7488360efbdSAlfred Perlstein */ 7498360efbdSAlfred Perlstein for (head = NULL; pmaphead != NULL; 7508360efbdSAlfred Perlstein pmaphead = pmaphead->pml_next) { 7518360efbdSAlfred Perlstein list = (rpcblist *)malloc(sizeof (rpcblist)); 7528360efbdSAlfred Perlstein if (list == NULL) 7538360efbdSAlfred Perlstein goto error; 7548360efbdSAlfred Perlstein if (head == NULL) 7558360efbdSAlfred Perlstein head = list; 7568360efbdSAlfred Perlstein else 7578360efbdSAlfred Perlstein prev->rpcb_next = (rpcblist_ptr) list; 7588360efbdSAlfred Perlstein 7598360efbdSAlfred Perlstein list->rpcb_next = NULL; 7608360efbdSAlfred Perlstein list->rpcb_map.r_prog = pmaphead->pml_map.pm_prog; 7618360efbdSAlfred Perlstein list->rpcb_map.r_vers = pmaphead->pml_map.pm_vers; 7628360efbdSAlfred Perlstein if (pmaphead->pml_map.pm_prot == IPPROTO_UDP) 7638360efbdSAlfred Perlstein list->rpcb_map.r_netid = "udp"; 7648360efbdSAlfred Perlstein else if (pmaphead->pml_map.pm_prot == IPPROTO_TCP) 7658360efbdSAlfred Perlstein list->rpcb_map.r_netid = "tcp"; 7668360efbdSAlfred Perlstein else { 7678360efbdSAlfred Perlstein #define MAXLONG_AS_STRING "2147483648" 7688360efbdSAlfred Perlstein list->rpcb_map.r_netid = 7698360efbdSAlfred Perlstein malloc(strlen(MAXLONG_AS_STRING) + 1); 7708360efbdSAlfred Perlstein if (list->rpcb_map.r_netid == NULL) 7718360efbdSAlfred Perlstein goto error; 7728360efbdSAlfred Perlstein sprintf(list->rpcb_map.r_netid, "%6ld", 7738360efbdSAlfred Perlstein pmaphead->pml_map.pm_prot); 7748360efbdSAlfred Perlstein } 7758360efbdSAlfred Perlstein list->rpcb_map.r_owner = UNKNOWN; 7768360efbdSAlfred Perlstein low = pmaphead->pml_map.pm_port & 0xff; 7778360efbdSAlfred Perlstein high = (pmaphead->pml_map.pm_port >> 8) & 0xff; 7788360efbdSAlfred Perlstein list->rpcb_map.r_addr = strdup("0.0.0.0.XXX.XXX"); 7798360efbdSAlfred Perlstein sprintf(&list->rpcb_map.r_addr[8], "%d.%d", 7808360efbdSAlfred Perlstein high, low); 7818360efbdSAlfred Perlstein prev = list; 7828360efbdSAlfred Perlstein } 7838360efbdSAlfred Perlstein } 7848360efbdSAlfred Perlstein } 7858360efbdSAlfred Perlstein } else { /* any other error */ 7868360efbdSAlfred Perlstein failed: 7878360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 7888360efbdSAlfred Perlstein exit(1); 7898360efbdSAlfred Perlstein } 7908360efbdSAlfred Perlstein } 7918360efbdSAlfred Perlstein if (head == NULL) { 7928360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 7938360efbdSAlfred Perlstein } else if (dumptype == RPCBDUMP) { 7948360efbdSAlfred Perlstein printf( 7958360efbdSAlfred Perlstein " program version netid address service owner\n"); 7968360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_next) { 7978360efbdSAlfred Perlstein printf("%10u%5u ", 7988360efbdSAlfred Perlstein head->rpcb_map.r_prog, head->rpcb_map.r_vers); 7998360efbdSAlfred Perlstein printf("%-9s ", head->rpcb_map.r_netid); 8008360efbdSAlfred Perlstein printf("%-22s", head->rpcb_map.r_addr); 8018360efbdSAlfred Perlstein rpc = getrpcbynumber(head->rpcb_map.r_prog); 8028360efbdSAlfred Perlstein if (rpc) 8038360efbdSAlfred Perlstein printf(" %-10s", rpc->r_name); 8048360efbdSAlfred Perlstein else 8058360efbdSAlfred Perlstein printf(" %-10s", "-"); 8068360efbdSAlfred Perlstein printf(" %s\n", head->rpcb_map.r_owner); 8078360efbdSAlfred Perlstein } 8088360efbdSAlfred Perlstein } else if (dumptype == RPCBDUMP_SHORT) { 8098360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_next) { 8108360efbdSAlfred Perlstein for (rs = rs_head; rs; rs = rs->next) 8118360efbdSAlfred Perlstein if (head->rpcb_map.r_prog == rs->prog) 8128360efbdSAlfred Perlstein break; 8138360efbdSAlfred Perlstein if (rs == NULL) { 8148360efbdSAlfred Perlstein rs = (struct rpcbdump_short *) 8158360efbdSAlfred Perlstein malloc(sizeof (struct rpcbdump_short)); 8168360efbdSAlfred Perlstein if (rs == NULL) 8178360efbdSAlfred Perlstein goto error; 8188360efbdSAlfred Perlstein rs->next = NULL; 8198360efbdSAlfred Perlstein if (rs_head == NULL) { 8208360efbdSAlfred Perlstein rs_head = rs; 8218360efbdSAlfred Perlstein rs_tail = rs; 8228360efbdSAlfred Perlstein } else { 8238360efbdSAlfred Perlstein rs_tail->next = rs; 8248360efbdSAlfred Perlstein rs_tail = rs; 8258360efbdSAlfred Perlstein } 8268360efbdSAlfred Perlstein rs->prog = head->rpcb_map.r_prog; 8278360efbdSAlfred Perlstein rs->owner = head->rpcb_map.r_owner; 8288360efbdSAlfred Perlstein rs->nlist = NULL; 8298360efbdSAlfred Perlstein rs->vlist = NULL; 8308360efbdSAlfred Perlstein } 8318360efbdSAlfred Perlstein if (add_version(rs, head->rpcb_map.r_vers) == FALSE) 8328360efbdSAlfred Perlstein goto error; 8338360efbdSAlfred Perlstein if (add_netid(rs, head->rpcb_map.r_netid) == FALSE) 8348360efbdSAlfred Perlstein goto error; 8358360efbdSAlfred Perlstein } 8368360efbdSAlfred Perlstein printf( 8378360efbdSAlfred Perlstein " program version(s) netid(s) service owner\n"); 8388360efbdSAlfred Perlstein for (rs = rs_head; rs; rs = rs->next) { 8398360efbdSAlfred Perlstein char *p = buf; 8408360efbdSAlfred Perlstein 8418360efbdSAlfred Perlstein printf("%10ld ", rs->prog); 8428360efbdSAlfred Perlstein for (vl = rs->vlist; vl; vl = vl->next) { 8438360efbdSAlfred Perlstein sprintf(p, "%d", vl->vers); 8448360efbdSAlfred Perlstein p = p + strlen(p); 8458360efbdSAlfred Perlstein if (vl->next) 8468360efbdSAlfred Perlstein sprintf(p++, ","); 8478360efbdSAlfred Perlstein } 8488360efbdSAlfred Perlstein printf("%-10s", buf); 84983e6e840SBruce Evans buf[0] = '\0'; 8508360efbdSAlfred Perlstein for (nl = rs->nlist; nl; nl = nl->next) { 8518360efbdSAlfred Perlstein strcat(buf, nl->netid); 8528360efbdSAlfred Perlstein if (nl->next) 8538360efbdSAlfred Perlstein strcat(buf, ","); 8548360efbdSAlfred Perlstein } 8558360efbdSAlfred Perlstein printf("%-32s", buf); 8568360efbdSAlfred Perlstein rpc = getrpcbynumber(rs->prog); 8578360efbdSAlfred Perlstein if (rpc) 8588360efbdSAlfred Perlstein printf(" %-11s", rpc->r_name); 8598360efbdSAlfred Perlstein else 8608360efbdSAlfred Perlstein printf(" %-11s", "-"); 8618360efbdSAlfred Perlstein printf(" %s\n", rs->owner); 8628360efbdSAlfred Perlstein } 8638360efbdSAlfred Perlstein } 8648360efbdSAlfred Perlstein clnt_destroy(client); 8658360efbdSAlfred Perlstein return; 866003bc1d4SPhilippe Charnier error: warnx("no memory"); 8678360efbdSAlfred Perlstein return; 8688360efbdSAlfred Perlstein } 8698360efbdSAlfred Perlstein 8708360efbdSAlfred Perlstein static char nullstring[] = "\000"; 8718360efbdSAlfred Perlstein 8728360efbdSAlfred Perlstein static void 8738360efbdSAlfred Perlstein rpcbaddrlist(char *netid, int argc, char **argv) 8748360efbdSAlfred Perlstein { 8758360efbdSAlfred Perlstein rpcb_entry_list_ptr head = NULL; 8768360efbdSAlfred Perlstein struct timeval minutetimeout; 8778360efbdSAlfred Perlstein register CLIENT *client; 8788360efbdSAlfred Perlstein struct rpcent *rpc; 8798360efbdSAlfred Perlstein char *host; 8808360efbdSAlfred Perlstein RPCB parms; 8818360efbdSAlfred Perlstein struct netbuf *targaddr; 8828360efbdSAlfred Perlstein 883003bc1d4SPhilippe Charnier if (argc != 3) 8848360efbdSAlfred Perlstein usage(); 8858360efbdSAlfred Perlstein host = argv[0]; 8868360efbdSAlfred Perlstein if (netid == NULL) { 8878360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS4, &targaddr); 8888360efbdSAlfred Perlstein } else { 8898360efbdSAlfred Perlstein struct netconfig *nconf; 8908360efbdSAlfred Perlstein 8918360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 8928360efbdSAlfred Perlstein if (nconf == NULL) { 8938360efbdSAlfred Perlstein nc_perror("rpcinfo: invalid transport"); 8948360efbdSAlfred Perlstein exit(1); 8958360efbdSAlfred Perlstein } 8968360efbdSAlfred Perlstein client = getclnthandle(host, nconf, RPCBVERS4, &targaddr); 8978360efbdSAlfred Perlstein if (nconf) 8988360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 8998360efbdSAlfred Perlstein } 9008360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 9018360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 9028360efbdSAlfred Perlstein exit(1); 9038360efbdSAlfred Perlstein } 9048360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 9058360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 9068360efbdSAlfred Perlstein 9078360efbdSAlfred Perlstein parms.r_prog = getprognum(argv[1]); 9088360efbdSAlfred Perlstein parms.r_vers = getvers(argv[2]); 9098360efbdSAlfred Perlstein parms.r_netid = client->cl_netid; 9108360efbdSAlfred Perlstein if (targaddr == NULL) { 9118360efbdSAlfred Perlstein parms.r_addr = nullstring; /* for XDRing */ 9128360efbdSAlfred Perlstein } else { 9138360efbdSAlfred Perlstein /* 9148360efbdSAlfred Perlstein * We also send the remote system the address we 9158360efbdSAlfred Perlstein * used to contact it in case it can help it 9168360efbdSAlfred Perlstein * connect back with us 9178360efbdSAlfred Perlstein */ 9188360efbdSAlfred Perlstein struct netconfig *nconf; 9198360efbdSAlfred Perlstein 9208360efbdSAlfred Perlstein nconf = getnetconfigent(client->cl_netid); 9218360efbdSAlfred Perlstein if (nconf != NULL) { 9228360efbdSAlfred Perlstein parms.r_addr = taddr2uaddr(nconf, targaddr); 9238360efbdSAlfred Perlstein if (parms.r_addr == NULL) 9248360efbdSAlfred Perlstein parms.r_addr = nullstring; 9258360efbdSAlfred Perlstein freenetconfigent(nconf); 9268360efbdSAlfred Perlstein } else { 9278360efbdSAlfred Perlstein parms.r_addr = nullstring; /* for XDRing */ 9288360efbdSAlfred Perlstein } 9298360efbdSAlfred Perlstein free(targaddr->buf); 9308360efbdSAlfred Perlstein free(targaddr); 9318360efbdSAlfred Perlstein } 9328360efbdSAlfred Perlstein parms.r_owner = nullstring; 9338360efbdSAlfred Perlstein 9348360efbdSAlfred Perlstein if (CLNT_CALL(client, RPCBPROC_GETADDRLIST, (xdrproc_t) xdr_rpcb, 9358360efbdSAlfred Perlstein (char *) &parms, (xdrproc_t) xdr_rpcb_entry_list_ptr, 9368360efbdSAlfred Perlstein (char *) &head, minutetimeout) != RPC_SUCCESS) { 9378360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 9388360efbdSAlfred Perlstein exit(1); 9398360efbdSAlfred Perlstein } 9408360efbdSAlfred Perlstein if (head == NULL) { 9418360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 9428360efbdSAlfred Perlstein } else { 9438360efbdSAlfred Perlstein printf( 9448360efbdSAlfred Perlstein " program vers tp_family/name/class address\t\t service\n"); 9458360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_entry_next) { 9468360efbdSAlfred Perlstein rpcb_entry *re; 9478360efbdSAlfred Perlstein char buf[128]; 9488360efbdSAlfred Perlstein 9498360efbdSAlfred Perlstein re = &head->rpcb_entry_map; 9508360efbdSAlfred Perlstein printf("%10u%3u ", 9518360efbdSAlfred Perlstein parms.r_prog, parms.r_vers); 9528360efbdSAlfred Perlstein sprintf(buf, "%s/%s/%s ", 9538360efbdSAlfred Perlstein re->r_nc_protofmly, re->r_nc_proto, 9548360efbdSAlfred Perlstein re->r_nc_semantics == NC_TPI_CLTS ? "clts" : 9558360efbdSAlfred Perlstein re->r_nc_semantics == NC_TPI_COTS ? "cots" : 9568360efbdSAlfred Perlstein "cots_ord"); 9578360efbdSAlfred Perlstein printf("%-24s", buf); 9588360efbdSAlfred Perlstein printf("%-24s", re->r_maddr); 9598360efbdSAlfred Perlstein rpc = getrpcbynumber(parms.r_prog); 9608360efbdSAlfred Perlstein if (rpc) 9618360efbdSAlfred Perlstein printf(" %-13s", rpc->r_name); 9628360efbdSAlfred Perlstein else 9638360efbdSAlfred Perlstein printf(" %-13s", "-"); 9648360efbdSAlfred Perlstein printf("\n"); 9658360efbdSAlfred Perlstein } 9668360efbdSAlfred Perlstein } 9678360efbdSAlfred Perlstein clnt_destroy(client); 9688360efbdSAlfred Perlstein return; 9698360efbdSAlfred Perlstein } 9708360efbdSAlfred Perlstein 9718360efbdSAlfred Perlstein /* 9728360efbdSAlfred Perlstein * monitor rpcbind 9738360efbdSAlfred Perlstein */ 9748360efbdSAlfred Perlstein static void 9758360efbdSAlfred Perlstein rpcbgetstat(int argc, char **argv) 9768360efbdSAlfred Perlstein { 9778360efbdSAlfred Perlstein rpcb_stat_byvers inf; 9788360efbdSAlfred Perlstein struct timeval minutetimeout; 9798360efbdSAlfred Perlstein register CLIENT *client; 9808360efbdSAlfred Perlstein char *host; 9818360efbdSAlfred Perlstein int i, j; 9828360efbdSAlfred Perlstein rpcbs_addrlist *pa; 9838360efbdSAlfred Perlstein rpcbs_rmtcalllist *pr; 9848360efbdSAlfred Perlstein int cnt, flen; 9858360efbdSAlfred Perlstein #define MAXFIELD 64 9868360efbdSAlfred Perlstein char fieldbuf[MAXFIELD]; 9878360efbdSAlfred Perlstein #define MAXLINE 256 9888360efbdSAlfred Perlstein char linebuf[MAXLINE]; 9898360efbdSAlfred Perlstein char *cp, *lp; 990*61382374SXin LI const char *pmaphdr[] = { 9918360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETPORT", 9928360efbdSAlfred Perlstein "DUMP", "CALLIT" 9938360efbdSAlfred Perlstein }; 994*61382374SXin LI const char *rpcb3hdr[] = { 9958360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME", 9968360efbdSAlfred Perlstein "U2T", "T2U" 9978360efbdSAlfred Perlstein }; 998*61382374SXin LI const char *rpcb4hdr[] = { 9998360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME", 10008360efbdSAlfred Perlstein "U2T", "T2U", "VERADDR", "INDRECT", "GETLIST", "GETSTAT" 10018360efbdSAlfred Perlstein }; 10028360efbdSAlfred Perlstein 10038360efbdSAlfred Perlstein #define TABSTOP 8 10048360efbdSAlfred Perlstein 10058360efbdSAlfred Perlstein if (argc >= 1) { 10068360efbdSAlfred Perlstein host = argv[0]; 10078360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS4, NULL); 10088360efbdSAlfred Perlstein } else 10098360efbdSAlfred Perlstein client = local_rpcb(PMAPPROG, RPCBVERS4); 10108360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 10118360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 10128360efbdSAlfred Perlstein exit(1); 10138360efbdSAlfred Perlstein } 10148360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 10158360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 10168360efbdSAlfred Perlstein memset((char *)&inf, 0, sizeof (rpcb_stat_byvers)); 10178360efbdSAlfred Perlstein if (CLNT_CALL(client, RPCBPROC_GETSTAT, (xdrproc_t) xdr_void, NULL, 10188360efbdSAlfred Perlstein (xdrproc_t) xdr_rpcb_stat_byvers, (char *)&inf, minutetimeout) 10198360efbdSAlfred Perlstein != RPC_SUCCESS) { 10208360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 10218360efbdSAlfred Perlstein exit(1); 10228360efbdSAlfred Perlstein } 10238360efbdSAlfred Perlstein printf("PORTMAP (version 2) statistics\n"); 10248360efbdSAlfred Perlstein lp = linebuf; 10258360efbdSAlfred Perlstein for (i = 0; i <= rpcb_highproc_2; i++) { 10268360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 10278360efbdSAlfred Perlstein switch (i) { 10288360efbdSAlfred Perlstein case PMAPPROC_SET: 10298360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", inf[RPCBVERS_2_STAT].setinfo); 10308360efbdSAlfred Perlstein break; 10318360efbdSAlfred Perlstein case PMAPPROC_UNSET: 10328360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 10338360efbdSAlfred Perlstein inf[RPCBVERS_2_STAT].unsetinfo); 10348360efbdSAlfred Perlstein break; 10358360efbdSAlfred Perlstein case PMAPPROC_GETPORT: 10368360efbdSAlfred Perlstein cnt = 0; 10378360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_2_STAT].addrinfo; pa; 10388360efbdSAlfred Perlstein pa = pa->next) 10398360efbdSAlfred Perlstein cnt += pa->success; 10408360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 10418360efbdSAlfred Perlstein break; 10428360efbdSAlfred Perlstein case PMAPPROC_CALLIT: 10438360efbdSAlfred Perlstein cnt = 0; 10448360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_2_STAT].rmtinfo; pr; 10458360efbdSAlfred Perlstein pr = pr->next) 10468360efbdSAlfred Perlstein cnt += pr->success; 10478360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 10488360efbdSAlfred Perlstein break; 10498360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 10508360efbdSAlfred Perlstein } 10518360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 10528360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_2_STAT].info[i]); 10538360efbdSAlfred Perlstein flen = strlen(fieldbuf); 10548360efbdSAlfred Perlstein printf("%s%s", pmaphdr[i], 10558360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 10568360efbdSAlfred Perlstein - strlen(pmaphdr[i]))); 10578360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 10588360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 10598360efbdSAlfred Perlstein - flen))); 10608360efbdSAlfred Perlstein lp += (flen + cnt); 10618360efbdSAlfred Perlstein } 10628360efbdSAlfred Perlstein printf("\n%s\n\n", linebuf); 10638360efbdSAlfred Perlstein 10648360efbdSAlfred Perlstein if (inf[RPCBVERS_2_STAT].info[PMAPPROC_CALLIT]) { 10658360efbdSAlfred Perlstein printf("PMAP_RMTCALL call statistics\n"); 10668360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]); 10678360efbdSAlfred Perlstein printf("\n"); 10688360efbdSAlfred Perlstein } 10698360efbdSAlfred Perlstein 10708360efbdSAlfred Perlstein if (inf[RPCBVERS_2_STAT].info[PMAPPROC_GETPORT]) { 10718360efbdSAlfred Perlstein printf("PMAP_GETPORT call statistics\n"); 10728360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]); 10738360efbdSAlfred Perlstein printf("\n"); 10748360efbdSAlfred Perlstein } 10758360efbdSAlfred Perlstein 10768360efbdSAlfred Perlstein printf("RPCBIND (version 3) statistics\n"); 10778360efbdSAlfred Perlstein lp = linebuf; 10788360efbdSAlfred Perlstein for (i = 0; i <= rpcb_highproc_3; i++) { 10798360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 10808360efbdSAlfred Perlstein switch (i) { 10818360efbdSAlfred Perlstein case RPCBPROC_SET: 10828360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", inf[RPCBVERS_3_STAT].setinfo); 10838360efbdSAlfred Perlstein break; 10848360efbdSAlfred Perlstein case RPCBPROC_UNSET: 10858360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 10868360efbdSAlfred Perlstein inf[RPCBVERS_3_STAT].unsetinfo); 10878360efbdSAlfred Perlstein break; 10888360efbdSAlfred Perlstein case RPCBPROC_GETADDR: 10898360efbdSAlfred Perlstein cnt = 0; 10908360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_3_STAT].addrinfo; pa; 10918360efbdSAlfred Perlstein pa = pa->next) 10928360efbdSAlfred Perlstein cnt += pa->success; 10938360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 10948360efbdSAlfred Perlstein break; 10958360efbdSAlfred Perlstein case RPCBPROC_CALLIT: 10968360efbdSAlfred Perlstein cnt = 0; 10978360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_3_STAT].rmtinfo; pr; 10988360efbdSAlfred Perlstein pr = pr->next) 10998360efbdSAlfred Perlstein cnt += pr->success; 11008360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11018360efbdSAlfred Perlstein break; 11028360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 11038360efbdSAlfred Perlstein } 11048360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 11058360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_3_STAT].info[i]); 11068360efbdSAlfred Perlstein flen = strlen(fieldbuf); 11078360efbdSAlfred Perlstein printf("%s%s", rpcb3hdr[i], 11088360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 11098360efbdSAlfred Perlstein - strlen(rpcb3hdr[i]))); 11108360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 11118360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 11128360efbdSAlfred Perlstein - flen))); 11138360efbdSAlfred Perlstein lp += (flen + cnt); 11148360efbdSAlfred Perlstein } 11158360efbdSAlfred Perlstein printf("\n%s\n\n", linebuf); 11168360efbdSAlfred Perlstein 11178360efbdSAlfred Perlstein if (inf[RPCBVERS_3_STAT].info[RPCBPROC_CALLIT]) { 11188360efbdSAlfred Perlstein printf("RPCB_RMTCALL (version 3) call statistics\n"); 11198360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]); 11208360efbdSAlfred Perlstein printf("\n"); 11218360efbdSAlfred Perlstein } 11228360efbdSAlfred Perlstein 11238360efbdSAlfred Perlstein if (inf[RPCBVERS_3_STAT].info[RPCBPROC_GETADDR]) { 11248360efbdSAlfred Perlstein printf("RPCB_GETADDR (version 3) call statistics\n"); 11258360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]); 11268360efbdSAlfred Perlstein printf("\n"); 11278360efbdSAlfred Perlstein } 11288360efbdSAlfred Perlstein 11298360efbdSAlfred Perlstein printf("RPCBIND (version 4) statistics\n"); 11308360efbdSAlfred Perlstein 11318360efbdSAlfred Perlstein for (j = 0; j <= 9; j += 9) { /* Just two iterations for printing */ 11328360efbdSAlfred Perlstein lp = linebuf; 11338360efbdSAlfred Perlstein for (i = j; i <= MAX(8, rpcb_highproc_4 - 9 + j); i++) { 11348360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 11358360efbdSAlfred Perlstein switch (i) { 11368360efbdSAlfred Perlstein case RPCBPROC_SET: 11378360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 11388360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].setinfo); 11398360efbdSAlfred Perlstein break; 11408360efbdSAlfred Perlstein case RPCBPROC_UNSET: 11418360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 11428360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].unsetinfo); 11438360efbdSAlfred Perlstein break; 11448360efbdSAlfred Perlstein case RPCBPROC_GETADDR: 11458360efbdSAlfred Perlstein cnt = 0; 11468360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_4_STAT].addrinfo; pa; 11478360efbdSAlfred Perlstein pa = pa->next) 11488360efbdSAlfred Perlstein cnt += pa->success; 11498360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11508360efbdSAlfred Perlstein break; 11518360efbdSAlfred Perlstein case RPCBPROC_CALLIT: 11528360efbdSAlfred Perlstein cnt = 0; 11538360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_4_STAT].rmtinfo; pr; 11548360efbdSAlfred Perlstein pr = pr->next) 11558360efbdSAlfred Perlstein cnt += pr->success; 11568360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11578360efbdSAlfred Perlstein break; 11588360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 11598360efbdSAlfred Perlstein } 11608360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 11618360efbdSAlfred Perlstein /* 11628360efbdSAlfred Perlstein * XXX: We also add RPCBPROC_GETADDRLIST queries to 11638360efbdSAlfred Perlstein * RPCB_GETADDR because rpcbind includes the 11648360efbdSAlfred Perlstein * RPCB_GETADDRLIST successes in RPCB_GETADDR. 11658360efbdSAlfred Perlstein */ 11668360efbdSAlfred Perlstein if (i != RPCBPROC_GETADDR) 11678360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_4_STAT].info[i]); 11688360efbdSAlfred Perlstein else 11698360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_4_STAT].info[i] + 11708360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDRLIST]); 11718360efbdSAlfred Perlstein flen = strlen(fieldbuf); 11728360efbdSAlfred Perlstein printf("%s%s", rpcb4hdr[i], 11738360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 11748360efbdSAlfred Perlstein - strlen(rpcb4hdr[i]))); 11758360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 11768360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 11778360efbdSAlfred Perlstein - flen))); 11788360efbdSAlfred Perlstein lp += (flen + cnt); 11798360efbdSAlfred Perlstein } 11808360efbdSAlfred Perlstein printf("\n%s\n", linebuf); 11818360efbdSAlfred Perlstein } 11828360efbdSAlfred Perlstein 11838360efbdSAlfred Perlstein if (inf[RPCBVERS_4_STAT].info[RPCBPROC_CALLIT] || 11848360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].info[RPCBPROC_INDIRECT]) { 11858360efbdSAlfred Perlstein printf("\n"); 11868360efbdSAlfred Perlstein printf("RPCB_RMTCALL (version 4) call statistics\n"); 11878360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]); 11888360efbdSAlfred Perlstein } 11898360efbdSAlfred Perlstein 11908360efbdSAlfred Perlstein if (inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDR]) { 11918360efbdSAlfred Perlstein printf("\n"); 11928360efbdSAlfred Perlstein printf("RPCB_GETADDR (version 4) call statistics\n"); 11938360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]); 11948360efbdSAlfred Perlstein } 11958360efbdSAlfred Perlstein clnt_destroy(client); 11968360efbdSAlfred Perlstein } 11978360efbdSAlfred Perlstein 11988360efbdSAlfred Perlstein /* 11998360efbdSAlfred Perlstein * Delete registeration for this (prog, vers, netid) 12008360efbdSAlfred Perlstein */ 12018360efbdSAlfred Perlstein static void 12028360efbdSAlfred Perlstein deletereg(char *netid, int argc, char **argv) 12038360efbdSAlfred Perlstein { 12048360efbdSAlfred Perlstein struct netconfig *nconf = NULL; 12058360efbdSAlfred Perlstein 1206003bc1d4SPhilippe Charnier if (argc != 2) 12078360efbdSAlfred Perlstein usage(); 12088360efbdSAlfred Perlstein if (netid) { 12098360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 1210003bc1d4SPhilippe Charnier if (nconf == NULL) 1211003bc1d4SPhilippe Charnier errx(1, "netid %s not supported", netid); 12128360efbdSAlfred Perlstein } 1213003bc1d4SPhilippe Charnier if ((rpcb_unset(getprognum(argv[0]), getvers(argv[1]), nconf)) == 0) 1214003bc1d4SPhilippe Charnier errx(1, 1215003bc1d4SPhilippe Charnier "could not delete registration for prog %s version %s", 12168360efbdSAlfred Perlstein argv[0], argv[1]); 12178360efbdSAlfred Perlstein } 12188360efbdSAlfred Perlstein 12198360efbdSAlfred Perlstein /* 12208360efbdSAlfred Perlstein * Create and return a handle for the given nconf. 12218360efbdSAlfred Perlstein * Exit if cannot create handle. 12228360efbdSAlfred Perlstein */ 12238360efbdSAlfred Perlstein static CLIENT * 12248360efbdSAlfred Perlstein clnt_addr_create(char *address, struct netconfig *nconf, 12258360efbdSAlfred Perlstein u_long prog, u_long vers) 12268360efbdSAlfred Perlstein { 12278360efbdSAlfred Perlstein CLIENT *client; 12288360efbdSAlfred Perlstein static struct netbuf *nbuf; 12298360efbdSAlfred Perlstein static int fd = RPC_ANYFD; 12308360efbdSAlfred Perlstein 12318360efbdSAlfred Perlstein if (fd == RPC_ANYFD) { 12328360efbdSAlfred Perlstein if ((fd = __rpc_nconf2fd(nconf)) == -1) { 12338360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_TLIERROR; 12348360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 12358360efbdSAlfred Perlstein exit(1); 12368360efbdSAlfred Perlstein } 12378360efbdSAlfred Perlstein /* Convert the uaddr to taddr */ 12388360efbdSAlfred Perlstein nbuf = uaddr2taddr(nconf, address); 1239003bc1d4SPhilippe Charnier if (nbuf == NULL) 1240003bc1d4SPhilippe Charnier errx(1, "no address for client handle"); 12418360efbdSAlfred Perlstein } 12428360efbdSAlfred Perlstein client = clnt_tli_create(fd, nconf, nbuf, prog, vers, 0, 0); 12438360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 12448360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 12458360efbdSAlfred Perlstein exit(1); 12468360efbdSAlfred Perlstein } 12478360efbdSAlfred Perlstein return (client); 12488360efbdSAlfred Perlstein } 12498360efbdSAlfred Perlstein 12508360efbdSAlfred Perlstein /* 12518360efbdSAlfred Perlstein * If the version number is given, ping that (prog, vers); else try to find 12528360efbdSAlfred Perlstein * the version numbers supported for that prog and ping all the versions. 12538360efbdSAlfred Perlstein * Remote rpcbind is not contacted for this service. The requests are 12548360efbdSAlfred Perlstein * sent directly to the services themselves. 12558360efbdSAlfred Perlstein */ 12568360efbdSAlfred Perlstein static void 12578360efbdSAlfred Perlstein addrping(char *address, char *netid, int argc, char **argv) 12588360efbdSAlfred Perlstein { 12598360efbdSAlfred Perlstein CLIENT *client; 12608360efbdSAlfred Perlstein struct timeval to; 12618360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 12628360efbdSAlfred Perlstein u_long prognum, versnum, minvers, maxvers; 12638360efbdSAlfred Perlstein struct rpc_err rpcerr; 12648360efbdSAlfred Perlstein int failure = 0; 12658360efbdSAlfred Perlstein struct netconfig *nconf; 12668360efbdSAlfred Perlstein int fd; 12678360efbdSAlfred Perlstein 1268003bc1d4SPhilippe Charnier if (argc < 1 || argc > 2 || (netid == NULL)) 12698360efbdSAlfred Perlstein usage(); 12708360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 1271003bc1d4SPhilippe Charnier if (nconf == (struct netconfig *)NULL) 1272003bc1d4SPhilippe Charnier errx(1, "could not find %s", netid); 12738360efbdSAlfred Perlstein to.tv_sec = 10; 12748360efbdSAlfred Perlstein to.tv_usec = 0; 12758360efbdSAlfred Perlstein prognum = getprognum(argv[0]); 12768360efbdSAlfred Perlstein if (argc == 1) { /* Version number not known */ 1277e99a5be3SGarrett Wollman /* 1278e99a5be3SGarrett Wollman * A call to version 0 should fail with a program/version 1279e99a5be3SGarrett Wollman * mismatch, and give us the range of versions supported. 1280e99a5be3SGarrett Wollman */ 12818360efbdSAlfred Perlstein versnum = MIN_VERS; 12828360efbdSAlfred Perlstein } else { 12838360efbdSAlfred Perlstein versnum = getvers(argv[1]); 1284e99a5be3SGarrett Wollman } 12858360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, versnum); 12868360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 12878360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 12888360efbdSAlfred Perlstein (char *)NULL, to); 12898360efbdSAlfred Perlstein if (argc == 2) { 12908360efbdSAlfred Perlstein /* Version number was known */ 12918360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 12928360efbdSAlfred Perlstein failure = 1; 12938360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 12948360efbdSAlfred Perlstein if (failure) 12958360efbdSAlfred Perlstein exit(1); 12968360efbdSAlfred Perlstein return; 12978360efbdSAlfred Perlstein } 12988360efbdSAlfred Perlstein /* Version number not known */ 12998360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL); 13008360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLGET_FD, (char *)&fd); 1301e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 1302e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1303e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 1304e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 1305e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 1306e99a5be3SGarrett Wollman /* 1307e99a5be3SGarrett Wollman * Oh dear, it DOES support version 0. 1308e99a5be3SGarrett Wollman * Let's try version MAX_VERS. 1309e99a5be3SGarrett Wollman */ 13108360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 13118360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, MAX_VERS); 13128360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 13138360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 13148360efbdSAlfred Perlstein (char *)NULL, to); 1315e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 1316e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1317e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 1318e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 1319e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 1320e99a5be3SGarrett Wollman /* 1321e99a5be3SGarrett Wollman * It also supports version MAX_VERS. 1322e99a5be3SGarrett Wollman * Looks like we have a wise guy. 1323e99a5be3SGarrett Wollman * OK, we give them information on all 1324e99a5be3SGarrett Wollman * 4 billion versions they support... 1325e99a5be3SGarrett Wollman */ 1326e99a5be3SGarrett Wollman minvers = 0; 1327e99a5be3SGarrett Wollman maxvers = MAX_VERS; 1328e99a5be3SGarrett Wollman } else { 1329e99a5be3SGarrett Wollman (void) pstatus(client, prognum, MAX_VERS); 1330e99a5be3SGarrett Wollman exit(1); 1331e99a5be3SGarrett Wollman } 1332e99a5be3SGarrett Wollman } else { 13338360efbdSAlfred Perlstein (void) pstatus(client, prognum, (u_long)0); 1334e99a5be3SGarrett Wollman exit(1); 1335e99a5be3SGarrett Wollman } 13368360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 13378360efbdSAlfred Perlstein for (versnum = minvers; versnum <= maxvers; versnum++) { 13388360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, versnum); 13398360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 13408360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 13418360efbdSAlfred Perlstein (char *)NULL, to); 13428360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 1343e99a5be3SGarrett Wollman failure = 1; 13448360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 1345e99a5be3SGarrett Wollman } 13468360efbdSAlfred Perlstein (void) close(fd); 1347e99a5be3SGarrett Wollman if (failure) 1348e99a5be3SGarrett Wollman exit(1); 13498360efbdSAlfred Perlstein return; 13508360efbdSAlfred Perlstein } 13518360efbdSAlfred Perlstein 13528360efbdSAlfred Perlstein /* 13538360efbdSAlfred Perlstein * If the version number is given, ping that (prog, vers); else try to find 13548360efbdSAlfred Perlstein * the version numbers supported for that prog and ping all the versions. 13558360efbdSAlfred Perlstein * Remote rpcbind is *contacted* for this service. The requests are 13568360efbdSAlfred Perlstein * then sent directly to the services themselves. 13578360efbdSAlfred Perlstein */ 13588360efbdSAlfred Perlstein static void 13598360efbdSAlfred Perlstein progping(char *netid, int argc, char **argv) 13608360efbdSAlfred Perlstein { 13618360efbdSAlfred Perlstein CLIENT *client; 13628360efbdSAlfred Perlstein struct timeval to; 13638360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 13648360efbdSAlfred Perlstein u_long prognum, versnum, minvers, maxvers; 13658360efbdSAlfred Perlstein struct rpc_err rpcerr; 13668360efbdSAlfred Perlstein int failure = 0; 13678360efbdSAlfred Perlstein struct netconfig *nconf; 13688360efbdSAlfred Perlstein 1369003bc1d4SPhilippe Charnier if (argc < 2 || argc > 3 || (netid == NULL)) 13708360efbdSAlfred Perlstein usage(); 13718360efbdSAlfred Perlstein prognum = getprognum(argv[1]); 13728360efbdSAlfred Perlstein if (argc == 2) { /* Version number not known */ 13738360efbdSAlfred Perlstein /* 13748360efbdSAlfred Perlstein * A call to version 0 should fail with a program/version 13758360efbdSAlfred Perlstein * mismatch, and give us the range of versions supported. 13768360efbdSAlfred Perlstein */ 13778360efbdSAlfred Perlstein versnum = MIN_VERS; 13788360efbdSAlfred Perlstein } else { 13798360efbdSAlfred Perlstein versnum = getvers(argv[2]); 13808360efbdSAlfred Perlstein } 13818360efbdSAlfred Perlstein if (netid) { 13828360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 1383003bc1d4SPhilippe Charnier if (nconf == (struct netconfig *)NULL) 1384003bc1d4SPhilippe Charnier errx(1, "could not find %s", netid); 13858360efbdSAlfred Perlstein client = clnt_tp_create(argv[0], prognum, versnum, nconf); 13868360efbdSAlfred Perlstein } else { 13878360efbdSAlfred Perlstein client = clnt_create(argv[0], prognum, versnum, "NETPATH"); 13888360efbdSAlfred Perlstein } 13898360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 13908360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 13918360efbdSAlfred Perlstein exit(1); 13928360efbdSAlfred Perlstein } 13938360efbdSAlfred Perlstein to.tv_sec = 10; 13948360efbdSAlfred Perlstein to.tv_usec = 0; 13958360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 13968360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 13978360efbdSAlfred Perlstein (char *)NULL, to); 13988360efbdSAlfred Perlstein if (argc == 3) { 13998360efbdSAlfred Perlstein /* Version number was known */ 14008360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 14018360efbdSAlfred Perlstein failure = 1; 14028360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 14038360efbdSAlfred Perlstein if (failure) 14048360efbdSAlfred Perlstein exit(1); 14058360efbdSAlfred Perlstein return; 14068360efbdSAlfred Perlstein } 14078360efbdSAlfred Perlstein /* Version number not known */ 14088360efbdSAlfred Perlstein if (rpc_stat == RPC_PROGVERSMISMATCH) { 14098360efbdSAlfred Perlstein clnt_geterr(client, &rpcerr); 14108360efbdSAlfred Perlstein minvers = rpcerr.re_vers.low; 14118360efbdSAlfred Perlstein maxvers = rpcerr.re_vers.high; 14128360efbdSAlfred Perlstein } else if (rpc_stat == RPC_SUCCESS) { 14138360efbdSAlfred Perlstein /* 14148360efbdSAlfred Perlstein * Oh dear, it DOES support version 0. 14158360efbdSAlfred Perlstein * Let's try version MAX_VERS. 14168360efbdSAlfred Perlstein */ 14178360efbdSAlfred Perlstein versnum = MAX_VERS; 14188360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum); 14198360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, 14208360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, 14218360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, to); 14228360efbdSAlfred Perlstein if (rpc_stat == RPC_PROGVERSMISMATCH) { 14238360efbdSAlfred Perlstein clnt_geterr(client, &rpcerr); 14248360efbdSAlfred Perlstein minvers = rpcerr.re_vers.low; 14258360efbdSAlfred Perlstein maxvers = rpcerr.re_vers.high; 14268360efbdSAlfred Perlstein } else if (rpc_stat == RPC_SUCCESS) { 14278360efbdSAlfred Perlstein /* 14288360efbdSAlfred Perlstein * It also supports version MAX_VERS. 14298360efbdSAlfred Perlstein * Looks like we have a wise guy. 14308360efbdSAlfred Perlstein * OK, we give them information on all 14318360efbdSAlfred Perlstein * 4 billion versions they support... 14328360efbdSAlfred Perlstein */ 14338360efbdSAlfred Perlstein minvers = 0; 14348360efbdSAlfred Perlstein maxvers = MAX_VERS; 14358360efbdSAlfred Perlstein } else { 14368360efbdSAlfred Perlstein (void) pstatus(client, prognum, MAX_VERS); 14378360efbdSAlfred Perlstein exit(1); 14388360efbdSAlfred Perlstein } 14398360efbdSAlfred Perlstein } else { 14408360efbdSAlfred Perlstein (void) pstatus(client, prognum, (u_long)0); 14418360efbdSAlfred Perlstein exit(1); 14428360efbdSAlfred Perlstein } 14438360efbdSAlfred Perlstein for (versnum = minvers; versnum <= maxvers; versnum++) { 14448360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum); 14458360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 14468360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 14478360efbdSAlfred Perlstein (char *)NULL, to); 14488360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 14498360efbdSAlfred Perlstein failure = 1; 14508360efbdSAlfred Perlstein } 14518360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 14528360efbdSAlfred Perlstein if (failure) 14538360efbdSAlfred Perlstein exit(1); 14548360efbdSAlfred Perlstein return; 14558360efbdSAlfred Perlstein } 14568360efbdSAlfred Perlstein 14578360efbdSAlfred Perlstein static void 1458*61382374SXin LI usage(void) 14598360efbdSAlfred Perlstein { 1460d3974088SDag-Erling Smørgrav fprintf(stderr, "usage: rpcinfo [-m | -s] [host]\n"); 14618360efbdSAlfred Perlstein #ifdef PORTMAP 14628360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -p [host]\n"); 14638360efbdSAlfred Perlstein #endif 14648360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -T netid host prognum [versnum]\n"); 14658360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -l host prognum versnum\n"); 14668360efbdSAlfred Perlstein #ifdef PORTMAP 14678360efbdSAlfred Perlstein fprintf(stderr, 14688360efbdSAlfred Perlstein " rpcinfo [-n portnum] -u | -t host prognum [versnum]\n"); 14698360efbdSAlfred Perlstein #endif 14708360efbdSAlfred Perlstein fprintf(stderr, 14718360efbdSAlfred Perlstein " rpcinfo -a serv_address -T netid prognum [version]\n"); 14728360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -b prognum versnum\n"); 14738360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -d [-T netid] prognum versnum\n"); 1474003bc1d4SPhilippe Charnier exit(1); 14758360efbdSAlfred Perlstein } 14768360efbdSAlfred Perlstein 14778360efbdSAlfred Perlstein static u_long 14788360efbdSAlfred Perlstein getprognum (char *arg) 14798360efbdSAlfred Perlstein { 14808360efbdSAlfred Perlstein char *strptr; 14818360efbdSAlfred Perlstein register struct rpcent *rpc; 14828360efbdSAlfred Perlstein register u_long prognum; 14838360efbdSAlfred Perlstein char *tptr = arg; 14848360efbdSAlfred Perlstein 14858360efbdSAlfred Perlstein while (*tptr && isdigit(*tptr++)); 14868360efbdSAlfred Perlstein if (*tptr || isalpha(*(tptr - 1))) { 14878360efbdSAlfred Perlstein rpc = getrpcbyname(arg); 1488003bc1d4SPhilippe Charnier if (rpc == NULL) 1489003bc1d4SPhilippe Charnier errx(1, "%s is unknown service", arg); 14908360efbdSAlfred Perlstein prognum = rpc->r_number; 14918360efbdSAlfred Perlstein } else { 14928360efbdSAlfred Perlstein prognum = strtol(arg, &strptr, 10); 1493003bc1d4SPhilippe Charnier if (strptr == arg || *strptr != '\0') 1494003bc1d4SPhilippe Charnier errx(1, "%s is illegal program number", arg); 14958360efbdSAlfred Perlstein } 14968360efbdSAlfred Perlstein return (prognum); 14978360efbdSAlfred Perlstein } 14988360efbdSAlfred Perlstein 14998360efbdSAlfred Perlstein static u_long 15008360efbdSAlfred Perlstein getvers(char *arg) 15018360efbdSAlfred Perlstein { 15028360efbdSAlfred Perlstein char *strptr; 15038360efbdSAlfred Perlstein register u_long vers; 15048360efbdSAlfred Perlstein 15058360efbdSAlfred Perlstein vers = (int) strtol(arg, &strptr, 10); 1506003bc1d4SPhilippe Charnier if (strptr == arg || *strptr != '\0') 1507003bc1d4SPhilippe Charnier errx(1, "%s is illegal version number", arg); 15088360efbdSAlfred Perlstein return (vers); 1509e99a5be3SGarrett Wollman } 1510e99a5be3SGarrett Wollman 1511e99a5be3SGarrett Wollman /* 1512e99a5be3SGarrett Wollman * This routine should take a pointer to an "rpc_err" structure, rather than 1513e99a5be3SGarrett Wollman * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to 1514e99a5be3SGarrett Wollman * a CLIENT structure rather than a pointer to an "rpc_err" structure. 1515e99a5be3SGarrett Wollman * As such, we have to keep the CLIENT structure around in order to print 1516e99a5be3SGarrett Wollman * a good error message. 1517e99a5be3SGarrett Wollman */ 1518e99a5be3SGarrett Wollman static int 15198360efbdSAlfred Perlstein pstatus(register CLIENT *client, u_long prog, u_long vers) 1520e99a5be3SGarrett Wollman { 1521e99a5be3SGarrett Wollman struct rpc_err rpcerr; 1522e99a5be3SGarrett Wollman 1523e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1524e99a5be3SGarrett Wollman if (rpcerr.re_status != RPC_SUCCESS) { 1525e99a5be3SGarrett Wollman clnt_perror(client, "rpcinfo"); 1526e99a5be3SGarrett Wollman printf("program %lu version %lu is not available\n", 15278360efbdSAlfred Perlstein prog, vers); 1528e99a5be3SGarrett Wollman return (-1); 1529e99a5be3SGarrett Wollman } else { 1530e99a5be3SGarrett Wollman printf("program %lu version %lu ready and waiting\n", 15318360efbdSAlfred Perlstein prog, vers); 1532e99a5be3SGarrett Wollman return (0); 1533e99a5be3SGarrett Wollman } 1534e99a5be3SGarrett Wollman } 1535e99a5be3SGarrett Wollman 15368360efbdSAlfred Perlstein static CLIENT * 15378360efbdSAlfred Perlstein clnt_rpcbind_create(char *host, int rpcbversnum, struct netbuf **targaddr) 1538e99a5be3SGarrett Wollman { 1539*61382374SXin LI static const char *tlist[3] = { 15408360efbdSAlfred Perlstein "circuit_n", "circuit_v", "datagram_v" 15418360efbdSAlfred Perlstein }; 15428360efbdSAlfred Perlstein int i; 15438360efbdSAlfred Perlstein struct netconfig *nconf; 15448360efbdSAlfred Perlstein CLIENT *clnt = NULL; 15458360efbdSAlfred Perlstein void *handle; 15468360efbdSAlfred Perlstein 15478360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_SUCCESS; 15488360efbdSAlfred Perlstein for (i = 0; i < 3; i++) { 15498360efbdSAlfred Perlstein if ((handle = __rpc_setconf(tlist[i])) == NULL) 15508360efbdSAlfred Perlstein continue; 15518360efbdSAlfred Perlstein while (clnt == (CLIENT *)NULL) { 15528360efbdSAlfred Perlstein if ((nconf = __rpc_getconf(handle)) == NULL) { 15538360efbdSAlfred Perlstein if (rpc_createerr.cf_stat == RPC_SUCCESS) 15548360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 15558360efbdSAlfred Perlstein break; 15568360efbdSAlfred Perlstein } 15578360efbdSAlfred Perlstein clnt = getclnthandle(host, nconf, rpcbversnum, 15588360efbdSAlfred Perlstein targaddr); 15598360efbdSAlfred Perlstein } 15608360efbdSAlfred Perlstein if (clnt) 15618360efbdSAlfred Perlstein break; 15628360efbdSAlfred Perlstein __rpc_endconf(handle); 15638360efbdSAlfred Perlstein } 15648360efbdSAlfred Perlstein return (clnt); 15658360efbdSAlfred Perlstein } 15668360efbdSAlfred Perlstein 15678360efbdSAlfred Perlstein static CLIENT* 15688360efbdSAlfred Perlstein getclnthandle(char *host, struct netconfig *nconf, 15698360efbdSAlfred Perlstein u_long rpcbversnum, struct netbuf **targaddr) 15708360efbdSAlfred Perlstein { 15718360efbdSAlfred Perlstein struct netbuf addr; 15728360efbdSAlfred Perlstein struct addrinfo hints, *res; 15738360efbdSAlfred Perlstein CLIENT *client = NULL; 15748360efbdSAlfred Perlstein 15758360efbdSAlfred Perlstein /* Get the address of the rpcbind */ 15768360efbdSAlfred Perlstein memset(&hints, 0, sizeof hints); 15778360efbdSAlfred Perlstein if (getaddrinfo(host, "rpcbind", &hints, &res) != 0) { 15788360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; 15798360efbdSAlfred Perlstein return (NULL); 15808360efbdSAlfred Perlstein } 15818360efbdSAlfred Perlstein addr.len = addr.maxlen = res->ai_addrlen; 15828360efbdSAlfred Perlstein addr.buf = res->ai_addr; 15838360efbdSAlfred Perlstein client = clnt_tli_create(RPC_ANYFD, nconf, &addr, RPCBPROG, 15848360efbdSAlfred Perlstein rpcbversnum, 0, 0); 15858360efbdSAlfred Perlstein if (client) { 15868360efbdSAlfred Perlstein if (targaddr != NULL) { 15878360efbdSAlfred Perlstein *targaddr = 15888360efbdSAlfred Perlstein (struct netbuf *)malloc(sizeof (struct netbuf)); 15898360efbdSAlfred Perlstein if (*targaddr != NULL) { 15908360efbdSAlfred Perlstein (*targaddr)->maxlen = addr.maxlen; 15918360efbdSAlfred Perlstein (*targaddr)->len = addr.len; 15928360efbdSAlfred Perlstein (*targaddr)->buf = (char *)malloc(addr.len); 15938360efbdSAlfred Perlstein if ((*targaddr)->buf != NULL) { 15948360efbdSAlfred Perlstein memcpy((*targaddr)->buf, addr.buf, 15958360efbdSAlfred Perlstein addr.len); 15968360efbdSAlfred Perlstein } 15978360efbdSAlfred Perlstein } 15988360efbdSAlfred Perlstein } 15998360efbdSAlfred Perlstein } else { 16008360efbdSAlfred Perlstein if (rpc_createerr.cf_stat == RPC_TLIERROR) { 16018360efbdSAlfred Perlstein /* 16028360efbdSAlfred Perlstein * Assume that the other system is dead; this is a 16038360efbdSAlfred Perlstein * better error to display to the user. 16048360efbdSAlfred Perlstein */ 16058360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_RPCBFAILURE; 16068360efbdSAlfred Perlstein rpc_createerr.cf_error.re_status = RPC_FAILED; 16078360efbdSAlfred Perlstein } 16088360efbdSAlfred Perlstein } 16098360efbdSAlfred Perlstein freeaddrinfo(res); 16108360efbdSAlfred Perlstein return (client); 16118360efbdSAlfred Perlstein } 16128360efbdSAlfred Perlstein 16138360efbdSAlfred Perlstein static void 16148360efbdSAlfred Perlstein print_rmtcallstat(int rtype, rpcb_stat *infp) 16158360efbdSAlfred Perlstein { 16168360efbdSAlfred Perlstein register rpcbs_rmtcalllist_ptr pr; 1617e99a5be3SGarrett Wollman struct rpcent *rpc; 1618e99a5be3SGarrett Wollman 16198360efbdSAlfred Perlstein if (rtype == RPCBVERS_4_STAT) 16208360efbdSAlfred Perlstein printf( 16218360efbdSAlfred Perlstein "prog\t\tvers\tproc\tnetid\tindirect success failure\n"); 1622e99a5be3SGarrett Wollman else 16238360efbdSAlfred Perlstein printf("prog\t\tvers\tproc\tnetid\tsuccess\tfailure\n"); 16248360efbdSAlfred Perlstein for (pr = infp->rmtinfo; pr; pr = pr->next) { 16258360efbdSAlfred Perlstein rpc = getrpcbynumber(pr->prog); 1626e99a5be3SGarrett Wollman if (rpc) 16278360efbdSAlfred Perlstein printf("%-16s", rpc->r_name); 1628e99a5be3SGarrett Wollman else 16298360efbdSAlfred Perlstein printf("%-16d", pr->prog); 16308360efbdSAlfred Perlstein printf("%d\t%d\t%s\t", 16318360efbdSAlfred Perlstein pr->vers, pr->proc, pr->netid); 16328360efbdSAlfred Perlstein if (rtype == RPCBVERS_4_STAT) 16338360efbdSAlfred Perlstein printf("%d\t ", pr->indirect); 16348360efbdSAlfred Perlstein printf("%d\t%d\n", pr->success, pr->failure); 1635e99a5be3SGarrett Wollman } 1636e99a5be3SGarrett Wollman } 1637e99a5be3SGarrett Wollman 1638e99a5be3SGarrett Wollman static void 16398360efbdSAlfred Perlstein print_getaddrstat(int rtype, rpcb_stat *infp) 1640e99a5be3SGarrett Wollman { 16418360efbdSAlfred Perlstein rpcbs_addrlist_ptr al; 1642e99a5be3SGarrett Wollman register struct rpcent *rpc; 1643e99a5be3SGarrett Wollman 16448360efbdSAlfred Perlstein printf("prog\t\tvers\tnetid\t success\tfailure\n"); 16458360efbdSAlfred Perlstein for (al = infp->addrinfo; al; al = al->next) { 16468360efbdSAlfred Perlstein rpc = getrpcbynumber(al->prog); 16478360efbdSAlfred Perlstein if (rpc) 16488360efbdSAlfred Perlstein printf("%-16s", rpc->r_name); 16498360efbdSAlfred Perlstein else 16508360efbdSAlfred Perlstein printf("%-16d", al->prog); 16518360efbdSAlfred Perlstein printf("%d\t%s\t %-12d\t%d\n", 16528360efbdSAlfred Perlstein al->vers, al->netid, 16538360efbdSAlfred Perlstein al->success, al->failure); 16548360efbdSAlfred Perlstein } 1655e99a5be3SGarrett Wollman } 1656e99a5be3SGarrett Wollman 16578360efbdSAlfred Perlstein static char * 16588360efbdSAlfred Perlstein spaces(int howmany) 1659e99a5be3SGarrett Wollman { 16608360efbdSAlfred Perlstein static char space_array[] = /* 64 spaces */ 16618360efbdSAlfred Perlstein " "; 1662e99a5be3SGarrett Wollman 16638360efbdSAlfred Perlstein if (howmany <= 0 || howmany > sizeof (space_array)) { 16648360efbdSAlfred Perlstein return (""); 1665e99a5be3SGarrett Wollman } 16668360efbdSAlfred Perlstein return (&space_array[sizeof (space_array) - howmany - 1]); 1667e99a5be3SGarrett Wollman } 1668