18360efbdSAlfred Perlstein /* $NetBSD: rpcinfo.c,v 1.15 2000/10/04 20:09:05 mjl Exp $ */ 28360efbdSAlfred Perlstein /* $FreeBSD$ */ 3e99a5be3SGarrett Wollman 4e99a5be3SGarrett Wollman /* 5e99a5be3SGarrett Wollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 6e99a5be3SGarrett Wollman * unrestricted use provided that this legend is included on all tape 7e99a5be3SGarrett Wollman * media and as a part of the software program in whole or part. Users 8e99a5be3SGarrett Wollman * may copy or modify Sun RPC without charge, but are not authorized 9e99a5be3SGarrett Wollman * to license or distribute it to anyone else except as part of a product or 10e99a5be3SGarrett Wollman * program developed by the user. 11e99a5be3SGarrett Wollman * 12e99a5be3SGarrett Wollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 13e99a5be3SGarrett Wollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 14e99a5be3SGarrett Wollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 15e99a5be3SGarrett Wollman * 16e99a5be3SGarrett Wollman * Sun RPC is provided with no support and without any obligation on the 17e99a5be3SGarrett Wollman * part of Sun Microsystems, Inc. to assist in its use, correction, 18e99a5be3SGarrett Wollman * modification or enhancement. 19e99a5be3SGarrett Wollman * 20e99a5be3SGarrett Wollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 21e99a5be3SGarrett Wollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 22e99a5be3SGarrett Wollman * OR ANY PART THEREOF. 23e99a5be3SGarrett Wollman * 24e99a5be3SGarrett Wollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 25e99a5be3SGarrett Wollman * or profits or other special, indirect and consequential damages, even if 26e99a5be3SGarrett Wollman * Sun has been advised of the possibility of such damages. 27e99a5be3SGarrett Wollman * 28e99a5be3SGarrett Wollman * Sun Microsystems, Inc. 29e99a5be3SGarrett Wollman * 2550 Garcia Avenue 30e99a5be3SGarrett Wollman * Mountain View, California 94043 31e99a5be3SGarrett Wollman */ 32e99a5be3SGarrett Wollman 338360efbdSAlfred Perlstein /* 348360efbdSAlfred Perlstein * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 358360efbdSAlfred Perlstein */ 368360efbdSAlfred Perlstein 378360efbdSAlfred Perlstein /* #ident "@(#)rpcinfo.c 1.18 93/07/05 SMI" */ 388360efbdSAlfred Perlstein 398360efbdSAlfred Perlstein #if 0 408360efbdSAlfred Perlstein #ifndef lint 418360efbdSAlfred Perlstein static char sccsid[] = "@(#)rpcinfo.c 1.16 89/04/05 Copyr 1986 Sun Micro"; 428360efbdSAlfred Perlstein #endif 438360efbdSAlfred Perlstein #endif 448360efbdSAlfred Perlstein 458360efbdSAlfred Perlstein /* 468360efbdSAlfred Perlstein * rpcinfo: ping a particular rpc program 478360efbdSAlfred Perlstein * or dump the the registered programs on the remote machine. 488360efbdSAlfred Perlstein */ 498360efbdSAlfred Perlstein 508360efbdSAlfred Perlstein /* 518360efbdSAlfred Perlstein * We are for now defining PORTMAP here. It doesnt even compile 528360efbdSAlfred Perlstein * unless it is defined. 538360efbdSAlfred Perlstein */ 548360efbdSAlfred Perlstein #ifndef PORTMAP 558360efbdSAlfred Perlstein #define PORTMAP 568360efbdSAlfred Perlstein #endif 578360efbdSAlfred Perlstein 588360efbdSAlfred Perlstein /* 598360efbdSAlfred Perlstein * If PORTMAP is defined, rpcinfo will talk to both portmapper and 608360efbdSAlfred Perlstein * rpcbind programs; else it talks only to rpcbind. In the latter case 618360efbdSAlfred Perlstein * all the portmapper specific options such as -u, -t, -p become void. 628360efbdSAlfred Perlstein */ 638360efbdSAlfred Perlstein #include <sys/types.h> 648360efbdSAlfred Perlstein #include <sys/param.h> 658360efbdSAlfred Perlstein #include <sys/socket.h> 668360efbdSAlfred Perlstein #include <sys/un.h> 67e99a5be3SGarrett Wollman #include <rpc/rpc.h> 68e99a5be3SGarrett Wollman #include <stdio.h> 698360efbdSAlfred Perlstein #include <rpc/rpcb_prot.h> 708360efbdSAlfred Perlstein #include <rpc/rpcent.h> 718360efbdSAlfred Perlstein #include <rpc/nettype.h> 728360efbdSAlfred Perlstein #include <rpc/rpc_com.h> 738360efbdSAlfred Perlstein #include <stdlib.h> 748360efbdSAlfred Perlstein #include <string.h> 758360efbdSAlfred Perlstein #include <unistd.h> 768360efbdSAlfred Perlstein #include <err.h> 778360efbdSAlfred Perlstein #include <ctype.h> 788360efbdSAlfred Perlstein 798360efbdSAlfred Perlstein #ifdef PORTMAP /* Support for version 2 portmapper */ 808360efbdSAlfred Perlstein #include <netinet/in.h> 81e99a5be3SGarrett Wollman #include <netdb.h> 828360efbdSAlfred Perlstein #include <arpa/inet.h> 83e99a5be3SGarrett Wollman #include <rpc/pmap_prot.h> 84e99a5be3SGarrett Wollman #include <rpc/pmap_clnt.h> 858360efbdSAlfred Perlstein #endif 86e99a5be3SGarrett Wollman 87e99a5be3SGarrett Wollman #define MAXHOSTLEN 256 88e99a5be3SGarrett Wollman #define MIN_VERS ((u_long) 0) 89e99a5be3SGarrett Wollman #define MAX_VERS ((u_long) 4294967295UL) 908360efbdSAlfred Perlstein #define UNKNOWN "unknown" 91e99a5be3SGarrett Wollman 92e99a5be3SGarrett Wollman /* 93e99a5be3SGarrett Wollman * Functions to be performed. 94e99a5be3SGarrett Wollman */ 95e99a5be3SGarrett Wollman #define NONE 0 /* no function */ 96e99a5be3SGarrett Wollman #define PMAPDUMP 1 /* dump portmapper registrations */ 97e99a5be3SGarrett Wollman #define TCPPING 2 /* ping TCP service */ 98e99a5be3SGarrett Wollman #define UDPPING 3 /* ping UDP service */ 998360efbdSAlfred Perlstein #define BROADCAST 4 /* ping broadcast service */ 100e99a5be3SGarrett Wollman #define DELETES 5 /* delete registration for the service */ 1018360efbdSAlfred Perlstein #define ADDRPING 6 /* pings at the given address */ 1028360efbdSAlfred Perlstein #define PROGPING 7 /* pings a program on a given host */ 1038360efbdSAlfred Perlstein #define RPCBDUMP 8 /* dump rpcbind registrations */ 1048360efbdSAlfred Perlstein #define RPCBDUMP_SHORT 9 /* dump rpcbind registrations - short version */ 1058360efbdSAlfred Perlstein #define RPCBADDRLIST 10 /* dump addr list about one prog */ 1068360efbdSAlfred Perlstein #define RPCBGETSTAT 11 /* Get statistics */ 1078360efbdSAlfred Perlstein 1088360efbdSAlfred Perlstein struct netidlist { 1098360efbdSAlfred Perlstein char *netid; 1108360efbdSAlfred Perlstein struct netidlist *next; 1118360efbdSAlfred Perlstein }; 1128360efbdSAlfred Perlstein 1138360efbdSAlfred Perlstein struct verslist { 1148360efbdSAlfred Perlstein int vers; 1158360efbdSAlfred Perlstein struct verslist *next; 1168360efbdSAlfred Perlstein }; 1178360efbdSAlfred Perlstein 1188360efbdSAlfred Perlstein struct rpcbdump_short { 1198360efbdSAlfred Perlstein u_long prog; 1208360efbdSAlfred Perlstein struct verslist *vlist; 1218360efbdSAlfred Perlstein struct netidlist *nlist; 1228360efbdSAlfred Perlstein struct rpcbdump_short *next; 1238360efbdSAlfred Perlstein char *owner; 1248360efbdSAlfred Perlstein }; 1258360efbdSAlfred Perlstein 1268360efbdSAlfred Perlstein 1278360efbdSAlfred Perlstein 1288360efbdSAlfred Perlstein #ifdef PORTMAP 1298360efbdSAlfred Perlstein static void ip_ping(u_short, char *, int, char **); 1308360efbdSAlfred Perlstein static CLIENT *clnt_com_create(struct sockaddr_in *, u_long, u_long, int *, 1318360efbdSAlfred Perlstein char *); 1328360efbdSAlfred Perlstein static void pmapdump(int, char **); 1338360efbdSAlfred Perlstein static void get_inet_address(struct sockaddr_in *, char *); 1348360efbdSAlfred Perlstein #endif 1358360efbdSAlfred Perlstein 1368360efbdSAlfred Perlstein static bool_t reply_proc(void *, struct netbuf *, struct netconfig *); 1378360efbdSAlfred Perlstein static void brdcst(int, char **); 1388360efbdSAlfred Perlstein static void addrping(char *, char *, int, char **); 1398360efbdSAlfred Perlstein static void progping(char *, int, char **); 1408360efbdSAlfred Perlstein static CLIENT *clnt_addr_create(char *, struct netconfig *, u_long, u_long); 1418360efbdSAlfred Perlstein static CLIENT *clnt_rpcbind_create(char *, int, struct netbuf **); 1428360efbdSAlfred Perlstein static CLIENT *getclnthandle(char *, struct netconfig *, u_long, 1438360efbdSAlfred Perlstein struct netbuf **); 1448360efbdSAlfred Perlstein static CLIENT *local_rpcb(u_long, u_long); 1458360efbdSAlfred Perlstein static int pstatus(CLIENT *, u_long, u_long); 1468360efbdSAlfred Perlstein static void rpcbdump(int, char *, int, char **); 1478360efbdSAlfred Perlstein static void rpcbgetstat(int, char **); 1488360efbdSAlfred Perlstein static void rpcbaddrlist(char *, int, char **); 1498360efbdSAlfred Perlstein static void deletereg(char *, int, char **); 1508360efbdSAlfred Perlstein static void print_rmtcallstat(int, rpcb_stat *); 1518360efbdSAlfred Perlstein static void print_getaddrstat(int, rpcb_stat *); 1528360efbdSAlfred Perlstein static void usage(void); 1538360efbdSAlfred Perlstein static u_long getprognum(char *); 1548360efbdSAlfred Perlstein static u_long getvers(char *); 1558360efbdSAlfred Perlstein static char *spaces(int); 1568360efbdSAlfred Perlstein static bool_t add_version(struct rpcbdump_short *, u_long); 1578360efbdSAlfred Perlstein static bool_t add_netid(struct rpcbdump_short *, char *); 1588360efbdSAlfred Perlstein 1598360efbdSAlfred Perlstein int main(int argc, char **argv); 160e99a5be3SGarrett Wollman 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); 2068360efbdSAlfred Perlstein if (strptr == optarg || *strptr != '\0') { 2078360efbdSAlfred Perlstein fprintf(stderr, 2088360efbdSAlfred Perlstein "rpcinfo: %s is illegal port number\n", 2098360efbdSAlfred Perlstein optarg); 2108360efbdSAlfred Perlstein exit(1); 2118360efbdSAlfred Perlstein } 2128360efbdSAlfred Perlstein break; 2138360efbdSAlfred Perlstein #endif 2148360efbdSAlfred Perlstein case 'a': 2158360efbdSAlfred Perlstein address = optarg; 2168360efbdSAlfred Perlstein if (function != NONE) 2178360efbdSAlfred Perlstein errflg = 1; 2188360efbdSAlfred Perlstein else 2198360efbdSAlfred Perlstein function = ADDRPING; 2208360efbdSAlfred Perlstein break; 221e99a5be3SGarrett Wollman case 'b': 222e99a5be3SGarrett Wollman if (function != NONE) 223e99a5be3SGarrett Wollman errflg = 1; 224e99a5be3SGarrett Wollman else 2258360efbdSAlfred Perlstein function = BROADCAST; 226e99a5be3SGarrett Wollman break; 227e99a5be3SGarrett Wollman 228e99a5be3SGarrett Wollman case 'd': 229e99a5be3SGarrett Wollman if (function != NONE) 230e99a5be3SGarrett Wollman errflg = 1; 231e99a5be3SGarrett Wollman else 232e99a5be3SGarrett Wollman function = DELETES; 233e99a5be3SGarrett Wollman break; 234e99a5be3SGarrett Wollman 2358360efbdSAlfred Perlstein case 'l': 2368360efbdSAlfred Perlstein if (function != NONE) 2378360efbdSAlfred Perlstein errflg = 1; 2388360efbdSAlfred Perlstein else 2398360efbdSAlfred Perlstein function = RPCBADDRLIST; 2408360efbdSAlfred Perlstein break; 2418360efbdSAlfred Perlstein 2428360efbdSAlfred Perlstein case 'm': 2438360efbdSAlfred Perlstein if (function != NONE) 2448360efbdSAlfred Perlstein errflg = 1; 2458360efbdSAlfred Perlstein else 2468360efbdSAlfred Perlstein function = RPCBGETSTAT; 2478360efbdSAlfred Perlstein break; 2488360efbdSAlfred Perlstein 2498360efbdSAlfred Perlstein case 's': 2508360efbdSAlfred Perlstein if (function != NONE) 2518360efbdSAlfred Perlstein errflg = 1; 2528360efbdSAlfred Perlstein else 2538360efbdSAlfred Perlstein function = RPCBDUMP_SHORT; 2548360efbdSAlfred Perlstein break; 2558360efbdSAlfred Perlstein 2568360efbdSAlfred Perlstein case 'T': 2578360efbdSAlfred Perlstein netid = optarg; 2588360efbdSAlfred Perlstein break; 259e99a5be3SGarrett Wollman case '?': 260e99a5be3SGarrett Wollman errflg = 1; 2618360efbdSAlfred Perlstein break; 262e99a5be3SGarrett Wollman } 263e99a5be3SGarrett Wollman } 264e99a5be3SGarrett Wollman 2658360efbdSAlfred Perlstein if (errflg || ((function == ADDRPING) && !netid)) { 266e99a5be3SGarrett Wollman usage(); 267e99a5be3SGarrett Wollman return (1); 268e99a5be3SGarrett Wollman } 269e99a5be3SGarrett Wollman 2708360efbdSAlfred Perlstein if (function == NONE) { 2718360efbdSAlfred Perlstein if (argc - optind > 1) 2728360efbdSAlfred Perlstein function = PROGPING; 2738360efbdSAlfred Perlstein else 2748360efbdSAlfred Perlstein function = RPCBDUMP; 2758360efbdSAlfred Perlstein } 276e99a5be3SGarrett Wollman 2778360efbdSAlfred Perlstein switch (function) { 2788360efbdSAlfred Perlstein #ifdef PORTMAP 279e99a5be3SGarrett Wollman case PMAPDUMP: 280e99a5be3SGarrett Wollman if (portnum != 0) { 281e99a5be3SGarrett Wollman usage(); 282e99a5be3SGarrett Wollman return (1); 283e99a5be3SGarrett Wollman } 284e99a5be3SGarrett Wollman pmapdump(argc - optind, argv + optind); 285e99a5be3SGarrett Wollman break; 286e99a5be3SGarrett Wollman 287e99a5be3SGarrett Wollman case UDPPING: 2888360efbdSAlfred Perlstein ip_ping(portnum, "udp", argc - optind, argv + optind); 289e99a5be3SGarrett Wollman break; 290e99a5be3SGarrett Wollman 291e99a5be3SGarrett Wollman case TCPPING: 2928360efbdSAlfred Perlstein ip_ping(portnum, "tcp", argc - optind, argv + optind); 293e99a5be3SGarrett Wollman break; 2948360efbdSAlfred Perlstein #endif 2958360efbdSAlfred Perlstein case BROADCAST: 296e99a5be3SGarrett Wollman brdcst(argc - optind, argv + optind); 297e99a5be3SGarrett Wollman break; 298e99a5be3SGarrett Wollman case DELETES: 2998360efbdSAlfred Perlstein deletereg(netid, argc - optind, argv + optind); 3008360efbdSAlfred Perlstein break; 3018360efbdSAlfred Perlstein case ADDRPING: 3028360efbdSAlfred Perlstein addrping(address, netid, argc - optind, argv + optind); 3038360efbdSAlfred Perlstein break; 3048360efbdSAlfred Perlstein case PROGPING: 3058360efbdSAlfred Perlstein progping(netid, argc - optind, argv + optind); 3068360efbdSAlfred Perlstein break; 3078360efbdSAlfred Perlstein case RPCBDUMP: 3088360efbdSAlfred Perlstein case RPCBDUMP_SHORT: 3098360efbdSAlfred Perlstein rpcbdump(function, netid, argc - optind, argv + optind); 3108360efbdSAlfred Perlstein break; 3118360efbdSAlfred Perlstein case RPCBGETSTAT: 3128360efbdSAlfred Perlstein rpcbgetstat(argc - optind, argv + optind); 3138360efbdSAlfred Perlstein break; 3148360efbdSAlfred Perlstein case RPCBADDRLIST: 3158360efbdSAlfred Perlstein rpcbaddrlist(netid, argc - optind, argv + optind); 316e99a5be3SGarrett Wollman break; 317e99a5be3SGarrett Wollman } 318e99a5be3SGarrett Wollman return (0); 319e99a5be3SGarrett Wollman } 320e99a5be3SGarrett Wollman 3218360efbdSAlfred Perlstein static CLIENT * 3228360efbdSAlfred Perlstein local_rpcb(u_long prog, u_long vers) 323e99a5be3SGarrett Wollman { 3248360efbdSAlfred Perlstein struct netbuf nbuf; 3258360efbdSAlfred Perlstein struct sockaddr_un sun; 3268360efbdSAlfred Perlstein int sock; 3278360efbdSAlfred Perlstein 3288360efbdSAlfred Perlstein memset(&sun, 0, sizeof sun); 3298360efbdSAlfred Perlstein sock = socket(AF_LOCAL, SOCK_STREAM, 0); 3308360efbdSAlfred Perlstein if (sock < 0) 3318360efbdSAlfred Perlstein return NULL; 3328360efbdSAlfred Perlstein 3338360efbdSAlfred Perlstein sun.sun_family = AF_LOCAL; 3348360efbdSAlfred Perlstein strcpy(sun.sun_path, _PATH_RPCBINDSOCK); 3358360efbdSAlfred Perlstein nbuf.len = sun.sun_len = SUN_LEN(&sun); 3368360efbdSAlfred Perlstein nbuf.maxlen = sizeof (struct sockaddr_un); 3378360efbdSAlfred Perlstein nbuf.buf = &sun; 3388360efbdSAlfred Perlstein 3398360efbdSAlfred Perlstein return clnt_vc_create(sock, &nbuf, prog, vers, 0, 0); 3408360efbdSAlfred Perlstein } 3418360efbdSAlfred Perlstein 3428360efbdSAlfred Perlstein #ifdef PORTMAP 3438360efbdSAlfred Perlstein static CLIENT * 3448360efbdSAlfred Perlstein clnt_com_create(struct sockaddr_in *addr, u_long prog, u_long vers, 3458360efbdSAlfred Perlstein int *fdp, char *trans) 3468360efbdSAlfred Perlstein { 3478360efbdSAlfred Perlstein CLIENT *clnt; 3488360efbdSAlfred Perlstein 3498360efbdSAlfred Perlstein if (strcmp(trans, "tcp") == 0) { 3508360efbdSAlfred Perlstein clnt = clnttcp_create(addr, prog, vers, fdp, 0, 0); 3518360efbdSAlfred Perlstein } else { 3528360efbdSAlfred Perlstein struct timeval to; 3538360efbdSAlfred Perlstein 3548360efbdSAlfred Perlstein to.tv_sec = 5; 3558360efbdSAlfred Perlstein to.tv_usec = 0; 3568360efbdSAlfred Perlstein clnt = clntudp_create(addr, prog, vers, to, fdp); 3578360efbdSAlfred Perlstein } 3588360efbdSAlfred Perlstein if (clnt == (CLIENT *)NULL) { 3598360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 3608360efbdSAlfred Perlstein if (vers == MIN_VERS) 3618360efbdSAlfred Perlstein printf("program %lu is not available\n", prog); 3628360efbdSAlfred Perlstein else 3638360efbdSAlfred Perlstein printf("program %lu version %lu is not available\n", 3648360efbdSAlfred Perlstein prog, vers); 3658360efbdSAlfred Perlstein exit(1); 3668360efbdSAlfred Perlstein } 3678360efbdSAlfred Perlstein return (clnt); 3688360efbdSAlfred Perlstein } 3698360efbdSAlfred Perlstein 3708360efbdSAlfred Perlstein /* 3718360efbdSAlfred Perlstein * If portnum is 0, then go and get the address from portmapper, which happens 3728360efbdSAlfred Perlstein * transparently through clnt*_create(); If version number is not given, it 3738360efbdSAlfred Perlstein * tries to find out the version number by making a call to version 0 and if 3748360efbdSAlfred Perlstein * that fails, it obtains the high order and the low order version number. If 3758360efbdSAlfred Perlstein * version 0 calls succeeds, it tries for MAXVERS call and repeats the same. 3768360efbdSAlfred Perlstein */ 3778360efbdSAlfred Perlstein static void 3788360efbdSAlfred Perlstein ip_ping(u_short portnum, char *trans, int argc, char **argv) 3798360efbdSAlfred Perlstein { 3808360efbdSAlfred Perlstein CLIENT *client; 3818360efbdSAlfred Perlstein int fd = RPC_ANYFD; 382e99a5be3SGarrett Wollman struct timeval to; 383e99a5be3SGarrett Wollman struct sockaddr_in addr; 384e99a5be3SGarrett Wollman enum clnt_stat rpc_stat; 385e99a5be3SGarrett Wollman u_long prognum, vers, minvers, maxvers; 386e99a5be3SGarrett Wollman struct rpc_err rpcerr; 3878360efbdSAlfred Perlstein int failure = 0; 388e99a5be3SGarrett Wollman 389e99a5be3SGarrett Wollman if (argc < 2 || argc > 3) { 390e99a5be3SGarrett Wollman usage(); 391e99a5be3SGarrett Wollman exit(1); 392e99a5be3SGarrett Wollman } 3938360efbdSAlfred Perlstein to.tv_sec = 10; 3948360efbdSAlfred Perlstein to.tv_usec = 0; 395e99a5be3SGarrett Wollman prognum = getprognum(argv[1]); 396e99a5be3SGarrett Wollman get_inet_address(&addr, argv[0]); 3978360efbdSAlfred Perlstein if (argc == 2) { /* Version number not known */ 398e99a5be3SGarrett Wollman /* 399e99a5be3SGarrett Wollman * A call to version 0 should fail with a program/version 400e99a5be3SGarrett Wollman * mismatch, and give us the range of versions supported. 401e99a5be3SGarrett Wollman */ 4028360efbdSAlfred Perlstein vers = MIN_VERS; 4038360efbdSAlfred Perlstein } else { 4048360efbdSAlfred Perlstein vers = getvers(argv[2]); 405e99a5be3SGarrett Wollman } 4068360efbdSAlfred Perlstein addr.sin_port = htons(portnum); 4078360efbdSAlfred Perlstein client = clnt_com_create(&addr, prognum, vers, &fd, trans); 4088360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 4098360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, (char *)NULL, 4108360efbdSAlfred Perlstein to); 4118360efbdSAlfred Perlstein if (argc != 2) { 4128360efbdSAlfred Perlstein /* Version number was known */ 4138360efbdSAlfred Perlstein if (pstatus(client, prognum, vers) < 0) 4148360efbdSAlfred Perlstein exit(1); 4158360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 4168360efbdSAlfred Perlstein return; 4178360efbdSAlfred Perlstein } 4188360efbdSAlfred Perlstein /* Version number not known */ 4198360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL); 420e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 421e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 422e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 423e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 424e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 425e99a5be3SGarrett Wollman /* 426e99a5be3SGarrett Wollman * Oh dear, it DOES support version 0. 427e99a5be3SGarrett Wollman * Let's try version MAX_VERS. 428e99a5be3SGarrett Wollman */ 4298360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 430e99a5be3SGarrett Wollman addr.sin_port = htons(portnum); 4318360efbdSAlfred Perlstein client = clnt_com_create(&addr, prognum, MAX_VERS, &fd, trans); 4328360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 4338360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 4348360efbdSAlfred Perlstein (char *)NULL, to); 435e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 436e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 437e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 438e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 439e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 440e99a5be3SGarrett Wollman /* 441e99a5be3SGarrett Wollman * It also supports version MAX_VERS. 442e99a5be3SGarrett Wollman * Looks like we have a wise guy. 443e99a5be3SGarrett Wollman * OK, we give them information on all 444e99a5be3SGarrett Wollman * 4 billion versions they support... 445e99a5be3SGarrett Wollman */ 446e99a5be3SGarrett Wollman minvers = 0; 447e99a5be3SGarrett Wollman maxvers = MAX_VERS; 448e99a5be3SGarrett Wollman } else { 449e99a5be3SGarrett Wollman (void) pstatus(client, prognum, MAX_VERS); 450e99a5be3SGarrett Wollman exit(1); 451e99a5be3SGarrett Wollman } 452e99a5be3SGarrett Wollman } else { 453e99a5be3SGarrett Wollman (void) pstatus(client, prognum, (u_long)0); 454e99a5be3SGarrett Wollman exit(1); 455e99a5be3SGarrett Wollman } 4568360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 457e99a5be3SGarrett Wollman for (vers = minvers; vers <= maxvers; vers++) { 458e99a5be3SGarrett Wollman addr.sin_port = htons(portnum); 4598360efbdSAlfred Perlstein client = clnt_com_create(&addr, prognum, vers, &fd, trans); 4608360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 4618360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 4628360efbdSAlfred Perlstein (char *)NULL, to); 463e99a5be3SGarrett Wollman if (pstatus(client, prognum, vers) < 0) 464e99a5be3SGarrett Wollman failure = 1; 4658360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 466e99a5be3SGarrett Wollman } 467e99a5be3SGarrett Wollman if (failure) 468e99a5be3SGarrett Wollman exit(1); 4698360efbdSAlfred Perlstein (void) close(fd); 4708360efbdSAlfred Perlstein return; 471e99a5be3SGarrett Wollman } 472e99a5be3SGarrett Wollman 4738360efbdSAlfred Perlstein /* 4748360efbdSAlfred Perlstein * Dump all the portmapper registerations 4758360efbdSAlfred Perlstein */ 476e99a5be3SGarrett Wollman static void 4778360efbdSAlfred Perlstein pmapdump(int argc, char **argv) 478e99a5be3SGarrett Wollman { 4798360efbdSAlfred Perlstein struct sockaddr_in server_addr; 4808360efbdSAlfred Perlstein struct pmaplist *head = NULL; 4818360efbdSAlfred Perlstein int socket = RPC_ANYSOCK; 4828360efbdSAlfred Perlstein struct timeval minutetimeout; 4838360efbdSAlfred Perlstein register CLIENT *client; 4848360efbdSAlfred Perlstein struct rpcent *rpc; 4858360efbdSAlfred Perlstein enum clnt_stat clnt_st; 4868360efbdSAlfred Perlstein struct rpc_err err; 4878360efbdSAlfred Perlstein char *host; 488e99a5be3SGarrett Wollman 4898360efbdSAlfred Perlstein if (argc > 1) { 490e99a5be3SGarrett Wollman usage(); 491e99a5be3SGarrett Wollman exit(1); 492e99a5be3SGarrett Wollman } 4938360efbdSAlfred Perlstein if (argc == 1) { 4948360efbdSAlfred Perlstein host = argv[0]; 4958360efbdSAlfred Perlstein get_inet_address(&server_addr, host); 4968360efbdSAlfred Perlstein server_addr.sin_port = htons(PMAPPORT); 4978360efbdSAlfred Perlstein client = clnttcp_create(&server_addr, PMAPPROG, PMAPVERS, 4988360efbdSAlfred Perlstein &socket, 50, 500); 4998360efbdSAlfred Perlstein } else 5008360efbdSAlfred Perlstein client = local_rpcb(PMAPPROG, PMAPVERS); 5018360efbdSAlfred Perlstein 5028360efbdSAlfred Perlstein if (client == NULL) { 5038360efbdSAlfred Perlstein if (rpc_createerr.cf_stat == RPC_TLIERROR) { 5048360efbdSAlfred Perlstein /* 5058360efbdSAlfred Perlstein * "Misc. TLI error" is not too helpful. Most likely 5068360efbdSAlfred Perlstein * the connection to the remote server timed out, so 5078360efbdSAlfred Perlstein * this error is at least less perplexing. 5088360efbdSAlfred Perlstein */ 5098360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_PMAPFAILURE; 5108360efbdSAlfred Perlstein rpc_createerr.cf_error.re_status = RPC_FAILED; 5118360efbdSAlfred Perlstein } 5128360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact portmapper"); 5138360efbdSAlfred Perlstein exit(1); 5148360efbdSAlfred Perlstein } 5158360efbdSAlfred Perlstein 5168360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 5178360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 5188360efbdSAlfred Perlstein 5198360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, PMAPPROC_DUMP, (xdrproc_t) xdr_void, 5208360efbdSAlfred Perlstein NULL, (xdrproc_t) xdr_pmaplist_ptr, (char *)&head, 5218360efbdSAlfred Perlstein minutetimeout); 5228360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) { 5238360efbdSAlfred Perlstein if ((clnt_st == RPC_PROGVERSMISMATCH) || 5248360efbdSAlfred Perlstein (clnt_st == RPC_PROGUNAVAIL)) { 5258360efbdSAlfred Perlstein CLNT_GETERR(client, &err); 5268360efbdSAlfred Perlstein if (err.re_vers.low > PMAPVERS) 5278360efbdSAlfred Perlstein fprintf(stderr, 5288360efbdSAlfred Perlstein "%s does not support portmapper. Try rpcinfo %s instead\n", 5298360efbdSAlfred Perlstein host, host); 5308360efbdSAlfred Perlstein exit(1); 5318360efbdSAlfred Perlstein } 5328360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact portmapper"); 5338360efbdSAlfred Perlstein exit(1); 5348360efbdSAlfred Perlstein } 5358360efbdSAlfred Perlstein if (head == NULL) { 5368360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 5378360efbdSAlfred Perlstein } else { 5388360efbdSAlfred Perlstein printf(" program vers proto port service\n"); 5398360efbdSAlfred Perlstein for (; head != NULL; head = head->pml_next) { 5408360efbdSAlfred Perlstein printf("%10ld%5ld", 5418360efbdSAlfred Perlstein head->pml_map.pm_prog, 5428360efbdSAlfred Perlstein head->pml_map.pm_vers); 5438360efbdSAlfred Perlstein if (head->pml_map.pm_prot == IPPROTO_UDP) 5448360efbdSAlfred Perlstein printf("%6s", "udp"); 5458360efbdSAlfred Perlstein else if (head->pml_map.pm_prot == IPPROTO_TCP) 5468360efbdSAlfred Perlstein printf("%6s", "tcp"); 5478360efbdSAlfred Perlstein else if (head->pml_map.pm_prot == IPPROTO_ST) 5488360efbdSAlfred Perlstein printf("%6s", "unix"); 5498360efbdSAlfred Perlstein else 5508360efbdSAlfred Perlstein printf("%6ld", head->pml_map.pm_prot); 5518360efbdSAlfred Perlstein printf("%7ld", head->pml_map.pm_port); 5528360efbdSAlfred Perlstein rpc = getrpcbynumber(head->pml_map.pm_prog); 5538360efbdSAlfred Perlstein if (rpc) 5548360efbdSAlfred Perlstein printf(" %s\n", rpc->r_name); 5558360efbdSAlfred Perlstein else 5568360efbdSAlfred Perlstein printf("\n"); 5578360efbdSAlfred Perlstein } 5588360efbdSAlfred Perlstein } 5598360efbdSAlfred Perlstein } 5608360efbdSAlfred Perlstein 5618360efbdSAlfred Perlstein static void 5628360efbdSAlfred Perlstein get_inet_address(struct sockaddr_in *addr, char *host) 5638360efbdSAlfred Perlstein { 5648360efbdSAlfred Perlstein struct netconfig *nconf; 5658360efbdSAlfred Perlstein struct addrinfo hints, *res; 5668360efbdSAlfred Perlstein int error; 5678360efbdSAlfred Perlstein 5688360efbdSAlfred Perlstein (void) memset((char *)addr, 0, sizeof (*addr)); 5698360efbdSAlfred Perlstein addr->sin_addr.s_addr = inet_addr(host); 5708360efbdSAlfred Perlstein if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) { 5718360efbdSAlfred Perlstein if ((nconf = __rpc_getconfip("udp")) == NULL && 5728360efbdSAlfred Perlstein (nconf = __rpc_getconfip("tcp")) == NULL) { 5738360efbdSAlfred Perlstein fprintf(stderr, 5748360efbdSAlfred Perlstein "rpcinfo: couldn't find a suitable transport\n"); 5758360efbdSAlfred Perlstein exit(1); 5768360efbdSAlfred Perlstein } else { 5778360efbdSAlfred Perlstein memset(&hints, 0, sizeof hints); 5788360efbdSAlfred Perlstein hints.ai_family = AF_INET; 5798360efbdSAlfred Perlstein if ((error = getaddrinfo(host, "rpcbind", &hints, &res)) 5808360efbdSAlfred Perlstein != 0) { 5818360efbdSAlfred Perlstein fprintf(stderr, "rpcinfo: %s: %s\n", 5828360efbdSAlfred Perlstein host, gai_strerror(error)); 5838360efbdSAlfred Perlstein exit(1); 5848360efbdSAlfred Perlstein } else { 5858360efbdSAlfred Perlstein memcpy(addr, res->ai_addr, res->ai_addrlen); 5868360efbdSAlfred Perlstein freeaddrinfo(res); 5878360efbdSAlfred Perlstein } 5888360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 5898360efbdSAlfred Perlstein } 5908360efbdSAlfred Perlstein } else { 5918360efbdSAlfred Perlstein addr->sin_family = AF_INET; 5928360efbdSAlfred Perlstein } 5938360efbdSAlfred Perlstein } 5948360efbdSAlfred Perlstein #endif /* PORTMAP */ 5958360efbdSAlfred Perlstein 5968360efbdSAlfred Perlstein /* 5978360efbdSAlfred Perlstein * reply_proc collects replies from the broadcast. 5988360efbdSAlfred Perlstein * to get a unique list of responses the output of rpcinfo should 5998360efbdSAlfred Perlstein * be piped through sort(1) and then uniq(1). 6008360efbdSAlfred Perlstein */ 6018360efbdSAlfred Perlstein 6028360efbdSAlfred Perlstein /*ARGSUSED*/ 6038360efbdSAlfred Perlstein static bool_t 6048360efbdSAlfred Perlstein reply_proc(void *res, struct netbuf *who, struct netconfig *nconf) 6058360efbdSAlfred Perlstein /* void *res; Nothing comes back */ 6068360efbdSAlfred Perlstein /* struct netbuf *who; Who sent us the reply */ 6078360efbdSAlfred Perlstein /* struct netconfig *nconf; On which transport the reply came */ 6088360efbdSAlfred Perlstein { 6098360efbdSAlfred Perlstein char *uaddr; 6108360efbdSAlfred Perlstein char hostbuf[NI_MAXHOST]; 6118360efbdSAlfred Perlstein char *hostname; 6128360efbdSAlfred Perlstein struct sockaddr *sa = (struct sockaddr *)who->buf; 6138360efbdSAlfred Perlstein 6148360efbdSAlfred Perlstein if (getnameinfo(sa, sa->sa_len, hostbuf, NI_MAXHOST, NULL, 0, 0)) { 6158360efbdSAlfred Perlstein hostname = UNKNOWN; 6168360efbdSAlfred Perlstein } else { 6178360efbdSAlfred Perlstein hostname = hostbuf; 6188360efbdSAlfred Perlstein } 6198360efbdSAlfred Perlstein if (!(uaddr = taddr2uaddr(nconf, who))) { 6208360efbdSAlfred Perlstein uaddr = UNKNOWN; 6218360efbdSAlfred Perlstein } 6228360efbdSAlfred Perlstein printf("%s\t%s\n", uaddr, hostname); 6238360efbdSAlfred Perlstein if (strcmp(uaddr, UNKNOWN)) 6248360efbdSAlfred Perlstein free((char *)uaddr); 6258360efbdSAlfred Perlstein return (FALSE); 6268360efbdSAlfred Perlstein } 6278360efbdSAlfred Perlstein 6288360efbdSAlfred Perlstein static void 6298360efbdSAlfred Perlstein brdcst(int argc, char **argv) 6308360efbdSAlfred Perlstein { 6318360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 6328360efbdSAlfred Perlstein u_long prognum, vers; 6338360efbdSAlfred Perlstein 6348360efbdSAlfred Perlstein if (argc != 2) { 6358360efbdSAlfred Perlstein usage(); 6368360efbdSAlfred Perlstein exit(1); 6378360efbdSAlfred Perlstein } 6388360efbdSAlfred Perlstein prognum = getprognum(argv[0]); 6398360efbdSAlfred Perlstein vers = getvers(argv[1]); 6408360efbdSAlfred Perlstein rpc_stat = rpc_broadcast(prognum, vers, NULLPROC, 6418360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, (xdrproc_t) xdr_void, 6428360efbdSAlfred Perlstein (char *)NULL, (resultproc_t) reply_proc, NULL); 6438360efbdSAlfred Perlstein if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) { 6448360efbdSAlfred Perlstein fprintf(stderr, "rpcinfo: broadcast failed: %s\n", 6458360efbdSAlfred Perlstein clnt_sperrno(rpc_stat)); 6468360efbdSAlfred Perlstein exit(1); 6478360efbdSAlfred Perlstein } 6488360efbdSAlfred Perlstein exit(0); 6498360efbdSAlfred Perlstein } 6508360efbdSAlfred Perlstein 6518360efbdSAlfred Perlstein static bool_t 6528360efbdSAlfred Perlstein add_version(struct rpcbdump_short *rs, u_long vers) 6538360efbdSAlfred Perlstein { 6548360efbdSAlfred Perlstein struct verslist *vl; 6558360efbdSAlfred Perlstein 6568360efbdSAlfred Perlstein for (vl = rs->vlist; vl; vl = vl->next) 6578360efbdSAlfred Perlstein if (vl->vers == vers) 6588360efbdSAlfred Perlstein break; 6598360efbdSAlfred Perlstein if (vl) 6608360efbdSAlfred Perlstein return (TRUE); 6618360efbdSAlfred Perlstein vl = (struct verslist *)malloc(sizeof (struct verslist)); 6628360efbdSAlfred Perlstein if (vl == NULL) 6638360efbdSAlfred Perlstein return (FALSE); 6648360efbdSAlfred Perlstein vl->vers = vers; 6658360efbdSAlfred Perlstein vl->next = rs->vlist; 6668360efbdSAlfred Perlstein rs->vlist = vl; 6678360efbdSAlfred Perlstein return (TRUE); 6688360efbdSAlfred Perlstein } 6698360efbdSAlfred Perlstein 6708360efbdSAlfred Perlstein static bool_t 6718360efbdSAlfred Perlstein add_netid(struct rpcbdump_short *rs, char *netid) 6728360efbdSAlfred Perlstein { 6738360efbdSAlfred Perlstein struct netidlist *nl; 6748360efbdSAlfred Perlstein 6758360efbdSAlfred Perlstein for (nl = rs->nlist; nl; nl = nl->next) 6768360efbdSAlfred Perlstein if (strcmp(nl->netid, netid) == 0) 6778360efbdSAlfred Perlstein break; 6788360efbdSAlfred Perlstein if (nl) 6798360efbdSAlfred Perlstein return (TRUE); 6808360efbdSAlfred Perlstein nl = (struct netidlist *)malloc(sizeof (struct netidlist)); 6818360efbdSAlfred Perlstein if (nl == NULL) 6828360efbdSAlfred Perlstein return (FALSE); 6838360efbdSAlfred Perlstein nl->netid = netid; 6848360efbdSAlfred Perlstein nl->next = rs->nlist; 6858360efbdSAlfred Perlstein rs->nlist = nl; 6868360efbdSAlfred Perlstein return (TRUE); 6878360efbdSAlfred Perlstein } 6888360efbdSAlfred Perlstein 6898360efbdSAlfred Perlstein static void 6908360efbdSAlfred Perlstein rpcbdump(int dumptype, char *netid, int argc, char **argv) 6918360efbdSAlfred Perlstein { 6928360efbdSAlfred Perlstein rpcblist_ptr head = NULL; 6938360efbdSAlfred Perlstein struct timeval minutetimeout; 6948360efbdSAlfred Perlstein register CLIENT *client; 6958360efbdSAlfred Perlstein struct rpcent *rpc; 6968360efbdSAlfred Perlstein char *host; 6978360efbdSAlfred Perlstein struct netidlist *nl; 6988360efbdSAlfred Perlstein struct verslist *vl; 6998360efbdSAlfred Perlstein struct rpcbdump_short *rs, *rs_tail; 7008360efbdSAlfred Perlstein char buf[256]; 7018360efbdSAlfred Perlstein enum clnt_stat clnt_st; 7028360efbdSAlfred Perlstein struct rpc_err err; 7038360efbdSAlfred Perlstein struct rpcbdump_short *rs_head = NULL; 7048360efbdSAlfred Perlstein 7058360efbdSAlfred Perlstein if (argc > 1) { 7068360efbdSAlfred Perlstein usage(); 7078360efbdSAlfred Perlstein exit(1); 7088360efbdSAlfred Perlstein } 7098360efbdSAlfred Perlstein if (argc == 1) { 7108360efbdSAlfred Perlstein host = argv[0]; 7118360efbdSAlfred Perlstein if (netid == NULL) { 7128360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS, NULL); 7138360efbdSAlfred Perlstein } else { 7148360efbdSAlfred Perlstein struct netconfig *nconf; 7158360efbdSAlfred Perlstein 7168360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 7178360efbdSAlfred Perlstein if (nconf == NULL) { 7188360efbdSAlfred Perlstein nc_perror("rpcinfo: invalid transport"); 7198360efbdSAlfred Perlstein exit(1); 7208360efbdSAlfred Perlstein } 7218360efbdSAlfred Perlstein client = getclnthandle(host, nconf, RPCBVERS, NULL); 7228360efbdSAlfred Perlstein if (nconf) 7238360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 7248360efbdSAlfred Perlstein } 7258360efbdSAlfred Perlstein } else 7268360efbdSAlfred Perlstein client = local_rpcb(PMAPPROG, RPCBVERS); 7278360efbdSAlfred Perlstein 7288360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 7298360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 7308360efbdSAlfred Perlstein exit(1); 7318360efbdSAlfred Perlstein } 7328360efbdSAlfred Perlstein 7338360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 7348360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 7358360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, (xdrproc_t) xdr_void, 7368360efbdSAlfred Perlstein NULL, (xdrproc_t) xdr_rpcblist_ptr, (char *) &head, 7378360efbdSAlfred Perlstein minutetimeout); 7388360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) { 7398360efbdSAlfred Perlstein if ((clnt_st == RPC_PROGVERSMISMATCH) || 7408360efbdSAlfred Perlstein (clnt_st == RPC_PROGUNAVAIL)) { 7418360efbdSAlfred Perlstein int vers; 7428360efbdSAlfred Perlstein 7438360efbdSAlfred Perlstein CLNT_GETERR(client, &err); 7448360efbdSAlfred Perlstein if (err.re_vers.low == RPCBVERS4) { 7458360efbdSAlfred Perlstein vers = RPCBVERS4; 7468360efbdSAlfred Perlstein clnt_control(client, CLSET_VERS, (char *)&vers); 7478360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, RPCBPROC_DUMP, 7488360efbdSAlfred Perlstein (xdrproc_t) xdr_void, NULL, 7498360efbdSAlfred Perlstein (xdrproc_t) xdr_rpcblist_ptr, (char *) &head, 7508360efbdSAlfred Perlstein minutetimeout); 7518360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) 7528360efbdSAlfred Perlstein goto failed; 7538360efbdSAlfred Perlstein } else { 7548360efbdSAlfred Perlstein if (err.re_vers.high == PMAPVERS) { 7558360efbdSAlfred Perlstein int high, low; 7568360efbdSAlfred Perlstein struct pmaplist *pmaphead = NULL; 7578360efbdSAlfred Perlstein rpcblist_ptr list, prev; 7588360efbdSAlfred Perlstein 7598360efbdSAlfred Perlstein vers = PMAPVERS; 7608360efbdSAlfred Perlstein clnt_control(client, CLSET_VERS, (char *)&vers); 7618360efbdSAlfred Perlstein clnt_st = CLNT_CALL(client, PMAPPROC_DUMP, 7628360efbdSAlfred Perlstein (xdrproc_t) xdr_void, NULL, 7638360efbdSAlfred Perlstein (xdrproc_t) xdr_pmaplist_ptr, 7648360efbdSAlfred Perlstein (char *)&pmaphead, minutetimeout); 7658360efbdSAlfred Perlstein if (clnt_st != RPC_SUCCESS) 7668360efbdSAlfred Perlstein goto failed; 7678360efbdSAlfred Perlstein /* 7688360efbdSAlfred Perlstein * convert to rpcblist_ptr format 7698360efbdSAlfred Perlstein */ 7708360efbdSAlfred Perlstein for (head = NULL; pmaphead != NULL; 7718360efbdSAlfred Perlstein pmaphead = pmaphead->pml_next) { 7728360efbdSAlfred Perlstein list = (rpcblist *)malloc(sizeof (rpcblist)); 7738360efbdSAlfred Perlstein if (list == NULL) 7748360efbdSAlfred Perlstein goto error; 7758360efbdSAlfred Perlstein if (head == NULL) 7768360efbdSAlfred Perlstein head = list; 7778360efbdSAlfred Perlstein else 7788360efbdSAlfred Perlstein prev->rpcb_next = (rpcblist_ptr) list; 7798360efbdSAlfred Perlstein 7808360efbdSAlfred Perlstein list->rpcb_next = NULL; 7818360efbdSAlfred Perlstein list->rpcb_map.r_prog = pmaphead->pml_map.pm_prog; 7828360efbdSAlfred Perlstein list->rpcb_map.r_vers = pmaphead->pml_map.pm_vers; 7838360efbdSAlfred Perlstein if (pmaphead->pml_map.pm_prot == IPPROTO_UDP) 7848360efbdSAlfred Perlstein list->rpcb_map.r_netid = "udp"; 7858360efbdSAlfred Perlstein else if (pmaphead->pml_map.pm_prot == IPPROTO_TCP) 7868360efbdSAlfred Perlstein list->rpcb_map.r_netid = "tcp"; 7878360efbdSAlfred Perlstein else { 7888360efbdSAlfred Perlstein #define MAXLONG_AS_STRING "2147483648" 7898360efbdSAlfred Perlstein list->rpcb_map.r_netid = 7908360efbdSAlfred Perlstein malloc(strlen(MAXLONG_AS_STRING) + 1); 7918360efbdSAlfred Perlstein if (list->rpcb_map.r_netid == NULL) 7928360efbdSAlfred Perlstein goto error; 7938360efbdSAlfred Perlstein sprintf(list->rpcb_map.r_netid, "%6ld", 7948360efbdSAlfred Perlstein pmaphead->pml_map.pm_prot); 7958360efbdSAlfred Perlstein } 7968360efbdSAlfred Perlstein list->rpcb_map.r_owner = UNKNOWN; 7978360efbdSAlfred Perlstein low = pmaphead->pml_map.pm_port & 0xff; 7988360efbdSAlfred Perlstein high = (pmaphead->pml_map.pm_port >> 8) & 0xff; 7998360efbdSAlfred Perlstein list->rpcb_map.r_addr = strdup("0.0.0.0.XXX.XXX"); 8008360efbdSAlfred Perlstein sprintf(&list->rpcb_map.r_addr[8], "%d.%d", 8018360efbdSAlfred Perlstein high, low); 8028360efbdSAlfred Perlstein prev = list; 8038360efbdSAlfred Perlstein } 8048360efbdSAlfred Perlstein } 8058360efbdSAlfred Perlstein } 8068360efbdSAlfred Perlstein } else { /* any other error */ 8078360efbdSAlfred Perlstein failed: 8088360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 8098360efbdSAlfred Perlstein exit(1); 8108360efbdSAlfred Perlstein } 8118360efbdSAlfred Perlstein } 8128360efbdSAlfred Perlstein if (head == NULL) { 8138360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 8148360efbdSAlfred Perlstein } else if (dumptype == RPCBDUMP) { 8158360efbdSAlfred Perlstein printf( 8168360efbdSAlfred Perlstein " program version netid address service owner\n"); 8178360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_next) { 8188360efbdSAlfred Perlstein printf("%10u%5u ", 8198360efbdSAlfred Perlstein head->rpcb_map.r_prog, head->rpcb_map.r_vers); 8208360efbdSAlfred Perlstein printf("%-9s ", head->rpcb_map.r_netid); 8218360efbdSAlfred Perlstein printf("%-22s", head->rpcb_map.r_addr); 8228360efbdSAlfred Perlstein rpc = getrpcbynumber(head->rpcb_map.r_prog); 8238360efbdSAlfred Perlstein if (rpc) 8248360efbdSAlfred Perlstein printf(" %-10s", rpc->r_name); 8258360efbdSAlfred Perlstein else 8268360efbdSAlfred Perlstein printf(" %-10s", "-"); 8278360efbdSAlfred Perlstein printf(" %s\n", head->rpcb_map.r_owner); 8288360efbdSAlfred Perlstein } 8298360efbdSAlfred Perlstein } else if (dumptype == RPCBDUMP_SHORT) { 8308360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_next) { 8318360efbdSAlfred Perlstein for (rs = rs_head; rs; rs = rs->next) 8328360efbdSAlfred Perlstein if (head->rpcb_map.r_prog == rs->prog) 8338360efbdSAlfred Perlstein break; 8348360efbdSAlfred Perlstein if (rs == NULL) { 8358360efbdSAlfred Perlstein rs = (struct rpcbdump_short *) 8368360efbdSAlfred Perlstein malloc(sizeof (struct rpcbdump_short)); 8378360efbdSAlfred Perlstein if (rs == NULL) 8388360efbdSAlfred Perlstein goto error; 8398360efbdSAlfred Perlstein rs->next = NULL; 8408360efbdSAlfred Perlstein if (rs_head == NULL) { 8418360efbdSAlfred Perlstein rs_head = rs; 8428360efbdSAlfred Perlstein rs_tail = rs; 8438360efbdSAlfred Perlstein } else { 8448360efbdSAlfred Perlstein rs_tail->next = rs; 8458360efbdSAlfred Perlstein rs_tail = rs; 8468360efbdSAlfred Perlstein } 8478360efbdSAlfred Perlstein rs->prog = head->rpcb_map.r_prog; 8488360efbdSAlfred Perlstein rs->owner = head->rpcb_map.r_owner; 8498360efbdSAlfred Perlstein rs->nlist = NULL; 8508360efbdSAlfred Perlstein rs->vlist = NULL; 8518360efbdSAlfred Perlstein } 8528360efbdSAlfred Perlstein if (add_version(rs, head->rpcb_map.r_vers) == FALSE) 8538360efbdSAlfred Perlstein goto error; 8548360efbdSAlfred Perlstein if (add_netid(rs, head->rpcb_map.r_netid) == FALSE) 8558360efbdSAlfred Perlstein goto error; 8568360efbdSAlfred Perlstein } 8578360efbdSAlfred Perlstein printf( 8588360efbdSAlfred Perlstein " program version(s) netid(s) service owner\n"); 8598360efbdSAlfred Perlstein for (rs = rs_head; rs; rs = rs->next) { 8608360efbdSAlfred Perlstein char *p = buf; 8618360efbdSAlfred Perlstein 8628360efbdSAlfred Perlstein printf("%10ld ", rs->prog); 8638360efbdSAlfred Perlstein for (vl = rs->vlist; vl; vl = vl->next) { 8648360efbdSAlfred Perlstein sprintf(p, "%d", vl->vers); 8658360efbdSAlfred Perlstein p = p + strlen(p); 8668360efbdSAlfred Perlstein if (vl->next) 8678360efbdSAlfred Perlstein sprintf(p++, ","); 8688360efbdSAlfred Perlstein } 8698360efbdSAlfred Perlstein printf("%-10s", buf); 8708360efbdSAlfred Perlstein buf[0] = NULL; 8718360efbdSAlfred Perlstein for (nl = rs->nlist; nl; nl = nl->next) { 8728360efbdSAlfred Perlstein strcat(buf, nl->netid); 8738360efbdSAlfred Perlstein if (nl->next) 8748360efbdSAlfred Perlstein strcat(buf, ","); 8758360efbdSAlfred Perlstein } 8768360efbdSAlfred Perlstein printf("%-32s", buf); 8778360efbdSAlfred Perlstein rpc = getrpcbynumber(rs->prog); 8788360efbdSAlfred Perlstein if (rpc) 8798360efbdSAlfred Perlstein printf(" %-11s", rpc->r_name); 8808360efbdSAlfred Perlstein else 8818360efbdSAlfred Perlstein printf(" %-11s", "-"); 8828360efbdSAlfred Perlstein printf(" %s\n", rs->owner); 8838360efbdSAlfred Perlstein } 8848360efbdSAlfred Perlstein } 8858360efbdSAlfred Perlstein clnt_destroy(client); 8868360efbdSAlfred Perlstein return; 8878360efbdSAlfred Perlstein error: fprintf(stderr, "rpcinfo: no memory\n"); 8888360efbdSAlfred Perlstein return; 8898360efbdSAlfred Perlstein } 8908360efbdSAlfred Perlstein 8918360efbdSAlfred Perlstein static char nullstring[] = "\000"; 8928360efbdSAlfred Perlstein 8938360efbdSAlfred Perlstein static void 8948360efbdSAlfred Perlstein rpcbaddrlist(char *netid, int argc, char **argv) 8958360efbdSAlfred Perlstein { 8968360efbdSAlfred Perlstein rpcb_entry_list_ptr head = NULL; 8978360efbdSAlfred Perlstein struct timeval minutetimeout; 8988360efbdSAlfred Perlstein register CLIENT *client; 8998360efbdSAlfred Perlstein struct rpcent *rpc; 9008360efbdSAlfred Perlstein char *host; 9018360efbdSAlfred Perlstein RPCB parms; 9028360efbdSAlfred Perlstein struct netbuf *targaddr; 9038360efbdSAlfred Perlstein 9048360efbdSAlfred Perlstein if (argc != 3) { 9058360efbdSAlfred Perlstein usage(); 9068360efbdSAlfred Perlstein exit(1); 9078360efbdSAlfred Perlstein } 9088360efbdSAlfred Perlstein host = argv[0]; 9098360efbdSAlfred Perlstein if (netid == NULL) { 9108360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS4, &targaddr); 9118360efbdSAlfred Perlstein } else { 9128360efbdSAlfred Perlstein struct netconfig *nconf; 9138360efbdSAlfred Perlstein 9148360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 9158360efbdSAlfred Perlstein if (nconf == NULL) { 9168360efbdSAlfred Perlstein nc_perror("rpcinfo: invalid transport"); 9178360efbdSAlfred Perlstein exit(1); 9188360efbdSAlfred Perlstein } 9198360efbdSAlfred Perlstein client = getclnthandle(host, nconf, RPCBVERS4, &targaddr); 9208360efbdSAlfred Perlstein if (nconf) 9218360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 9228360efbdSAlfred Perlstein } 9238360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 9248360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 9258360efbdSAlfred Perlstein exit(1); 9268360efbdSAlfred Perlstein } 9278360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 9288360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 9298360efbdSAlfred Perlstein 9308360efbdSAlfred Perlstein parms.r_prog = getprognum(argv[1]); 9318360efbdSAlfred Perlstein parms.r_vers = getvers(argv[2]); 9328360efbdSAlfred Perlstein parms.r_netid = client->cl_netid; 9338360efbdSAlfred Perlstein if (targaddr == NULL) { 9348360efbdSAlfred Perlstein parms.r_addr = nullstring; /* for XDRing */ 9358360efbdSAlfred Perlstein } else { 9368360efbdSAlfred Perlstein /* 9378360efbdSAlfred Perlstein * We also send the remote system the address we 9388360efbdSAlfred Perlstein * used to contact it in case it can help it 9398360efbdSAlfred Perlstein * connect back with us 9408360efbdSAlfred Perlstein */ 9418360efbdSAlfred Perlstein struct netconfig *nconf; 9428360efbdSAlfred Perlstein 9438360efbdSAlfred Perlstein nconf = getnetconfigent(client->cl_netid); 9448360efbdSAlfred Perlstein if (nconf != NULL) { 9458360efbdSAlfred Perlstein parms.r_addr = taddr2uaddr(nconf, targaddr); 9468360efbdSAlfred Perlstein if (parms.r_addr == NULL) 9478360efbdSAlfred Perlstein parms.r_addr = nullstring; 9488360efbdSAlfred Perlstein freenetconfigent(nconf); 9498360efbdSAlfred Perlstein } else { 9508360efbdSAlfred Perlstein parms.r_addr = nullstring; /* for XDRing */ 9518360efbdSAlfred Perlstein } 9528360efbdSAlfred Perlstein free(targaddr->buf); 9538360efbdSAlfred Perlstein free(targaddr); 9548360efbdSAlfred Perlstein } 9558360efbdSAlfred Perlstein parms.r_owner = nullstring; 9568360efbdSAlfred Perlstein 9578360efbdSAlfred Perlstein if (CLNT_CALL(client, RPCBPROC_GETADDRLIST, (xdrproc_t) xdr_rpcb, 9588360efbdSAlfred Perlstein (char *) &parms, (xdrproc_t) xdr_rpcb_entry_list_ptr, 9598360efbdSAlfred Perlstein (char *) &head, minutetimeout) != RPC_SUCCESS) { 9608360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 9618360efbdSAlfred Perlstein exit(1); 9628360efbdSAlfred Perlstein } 9638360efbdSAlfred Perlstein if (head == NULL) { 9648360efbdSAlfred Perlstein printf("No remote programs registered.\n"); 9658360efbdSAlfred Perlstein } else { 9668360efbdSAlfred Perlstein printf( 9678360efbdSAlfred Perlstein " program vers tp_family/name/class address\t\t service\n"); 9688360efbdSAlfred Perlstein for (; head != NULL; head = head->rpcb_entry_next) { 9698360efbdSAlfred Perlstein rpcb_entry *re; 9708360efbdSAlfred Perlstein char buf[128]; 9718360efbdSAlfred Perlstein 9728360efbdSAlfred Perlstein re = &head->rpcb_entry_map; 9738360efbdSAlfred Perlstein printf("%10u%3u ", 9748360efbdSAlfred Perlstein parms.r_prog, parms.r_vers); 9758360efbdSAlfred Perlstein sprintf(buf, "%s/%s/%s ", 9768360efbdSAlfred Perlstein re->r_nc_protofmly, re->r_nc_proto, 9778360efbdSAlfred Perlstein re->r_nc_semantics == NC_TPI_CLTS ? "clts" : 9788360efbdSAlfred Perlstein re->r_nc_semantics == NC_TPI_COTS ? "cots" : 9798360efbdSAlfred Perlstein "cots_ord"); 9808360efbdSAlfred Perlstein printf("%-24s", buf); 9818360efbdSAlfred Perlstein printf("%-24s", re->r_maddr); 9828360efbdSAlfred Perlstein rpc = getrpcbynumber(parms.r_prog); 9838360efbdSAlfred Perlstein if (rpc) 9848360efbdSAlfred Perlstein printf(" %-13s", rpc->r_name); 9858360efbdSAlfred Perlstein else 9868360efbdSAlfred Perlstein printf(" %-13s", "-"); 9878360efbdSAlfred Perlstein printf("\n"); 9888360efbdSAlfred Perlstein } 9898360efbdSAlfred Perlstein } 9908360efbdSAlfred Perlstein clnt_destroy(client); 9918360efbdSAlfred Perlstein return; 9928360efbdSAlfred Perlstein } 9938360efbdSAlfred Perlstein 9948360efbdSAlfred Perlstein /* 9958360efbdSAlfred Perlstein * monitor rpcbind 9968360efbdSAlfred Perlstein */ 9978360efbdSAlfred Perlstein static void 9988360efbdSAlfred Perlstein rpcbgetstat(int argc, char **argv) 9998360efbdSAlfred Perlstein { 10008360efbdSAlfred Perlstein rpcb_stat_byvers inf; 10018360efbdSAlfred Perlstein struct timeval minutetimeout; 10028360efbdSAlfred Perlstein register CLIENT *client; 10038360efbdSAlfred Perlstein char *host; 10048360efbdSAlfred Perlstein int i, j; 10058360efbdSAlfred Perlstein rpcbs_addrlist *pa; 10068360efbdSAlfred Perlstein rpcbs_rmtcalllist *pr; 10078360efbdSAlfred Perlstein int cnt, flen; 10088360efbdSAlfred Perlstein #define MAXFIELD 64 10098360efbdSAlfred Perlstein char fieldbuf[MAXFIELD]; 10108360efbdSAlfred Perlstein #define MAXLINE 256 10118360efbdSAlfred Perlstein char linebuf[MAXLINE]; 10128360efbdSAlfred Perlstein char *cp, *lp; 10138360efbdSAlfred Perlstein char *pmaphdr[] = { 10148360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETPORT", 10158360efbdSAlfred Perlstein "DUMP", "CALLIT" 10168360efbdSAlfred Perlstein }; 10178360efbdSAlfred Perlstein char *rpcb3hdr[] = { 10188360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME", 10198360efbdSAlfred Perlstein "U2T", "T2U" 10208360efbdSAlfred Perlstein }; 10218360efbdSAlfred Perlstein char *rpcb4hdr[] = { 10228360efbdSAlfred Perlstein "NULL", "SET", "UNSET", "GETADDR", "DUMP", "CALLIT", "TIME", 10238360efbdSAlfred Perlstein "U2T", "T2U", "VERADDR", "INDRECT", "GETLIST", "GETSTAT" 10248360efbdSAlfred Perlstein }; 10258360efbdSAlfred Perlstein 10268360efbdSAlfred Perlstein #define TABSTOP 8 10278360efbdSAlfred Perlstein 10288360efbdSAlfred Perlstein if (argc >= 1) { 10298360efbdSAlfred Perlstein host = argv[0]; 10308360efbdSAlfred Perlstein client = clnt_rpcbind_create(host, RPCBVERS4, NULL); 10318360efbdSAlfred Perlstein } else 10328360efbdSAlfred Perlstein client = local_rpcb(PMAPPROG, RPCBVERS4); 10338360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 10348360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo: can't contact rpcbind"); 10358360efbdSAlfred Perlstein exit(1); 10368360efbdSAlfred Perlstein } 10378360efbdSAlfred Perlstein minutetimeout.tv_sec = 60; 10388360efbdSAlfred Perlstein minutetimeout.tv_usec = 0; 10398360efbdSAlfred Perlstein memset((char *)&inf, 0, sizeof (rpcb_stat_byvers)); 10408360efbdSAlfred Perlstein if (CLNT_CALL(client, RPCBPROC_GETSTAT, (xdrproc_t) xdr_void, NULL, 10418360efbdSAlfred Perlstein (xdrproc_t) xdr_rpcb_stat_byvers, (char *)&inf, minutetimeout) 10428360efbdSAlfred Perlstein != RPC_SUCCESS) { 10438360efbdSAlfred Perlstein clnt_perror(client, "rpcinfo: can't contact rpcbind: "); 10448360efbdSAlfred Perlstein exit(1); 10458360efbdSAlfred Perlstein } 10468360efbdSAlfred Perlstein printf("PORTMAP (version 2) statistics\n"); 10478360efbdSAlfred Perlstein lp = linebuf; 10488360efbdSAlfred Perlstein for (i = 0; i <= rpcb_highproc_2; i++) { 10498360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 10508360efbdSAlfred Perlstein switch (i) { 10518360efbdSAlfred Perlstein case PMAPPROC_SET: 10528360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", inf[RPCBVERS_2_STAT].setinfo); 10538360efbdSAlfred Perlstein break; 10548360efbdSAlfred Perlstein case PMAPPROC_UNSET: 10558360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 10568360efbdSAlfred Perlstein inf[RPCBVERS_2_STAT].unsetinfo); 10578360efbdSAlfred Perlstein break; 10588360efbdSAlfred Perlstein case PMAPPROC_GETPORT: 10598360efbdSAlfred Perlstein cnt = 0; 10608360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_2_STAT].addrinfo; pa; 10618360efbdSAlfred Perlstein pa = pa->next) 10628360efbdSAlfred Perlstein cnt += pa->success; 10638360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 10648360efbdSAlfred Perlstein break; 10658360efbdSAlfred Perlstein case PMAPPROC_CALLIT: 10668360efbdSAlfred Perlstein cnt = 0; 10678360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_2_STAT].rmtinfo; pr; 10688360efbdSAlfred Perlstein pr = pr->next) 10698360efbdSAlfred Perlstein cnt += pr->success; 10708360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 10718360efbdSAlfred Perlstein break; 10728360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 10738360efbdSAlfred Perlstein } 10748360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 10758360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_2_STAT].info[i]); 10768360efbdSAlfred Perlstein flen = strlen(fieldbuf); 10778360efbdSAlfred Perlstein printf("%s%s", pmaphdr[i], 10788360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 10798360efbdSAlfred Perlstein - strlen(pmaphdr[i]))); 10808360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 10818360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 10828360efbdSAlfred Perlstein - flen))); 10838360efbdSAlfred Perlstein lp += (flen + cnt); 10848360efbdSAlfred Perlstein } 10858360efbdSAlfred Perlstein printf("\n%s\n\n", linebuf); 10868360efbdSAlfred Perlstein 10878360efbdSAlfred Perlstein if (inf[RPCBVERS_2_STAT].info[PMAPPROC_CALLIT]) { 10888360efbdSAlfred Perlstein printf("PMAP_RMTCALL call statistics\n"); 10898360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]); 10908360efbdSAlfred Perlstein printf("\n"); 10918360efbdSAlfred Perlstein } 10928360efbdSAlfred Perlstein 10938360efbdSAlfred Perlstein if (inf[RPCBVERS_2_STAT].info[PMAPPROC_GETPORT]) { 10948360efbdSAlfred Perlstein printf("PMAP_GETPORT call statistics\n"); 10958360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_2_STAT, &inf[RPCBVERS_2_STAT]); 10968360efbdSAlfred Perlstein printf("\n"); 10978360efbdSAlfred Perlstein } 10988360efbdSAlfred Perlstein 10998360efbdSAlfred Perlstein printf("RPCBIND (version 3) statistics\n"); 11008360efbdSAlfred Perlstein lp = linebuf; 11018360efbdSAlfred Perlstein for (i = 0; i <= rpcb_highproc_3; i++) { 11028360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 11038360efbdSAlfred Perlstein switch (i) { 11048360efbdSAlfred Perlstein case RPCBPROC_SET: 11058360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", inf[RPCBVERS_3_STAT].setinfo); 11068360efbdSAlfred Perlstein break; 11078360efbdSAlfred Perlstein case RPCBPROC_UNSET: 11088360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 11098360efbdSAlfred Perlstein inf[RPCBVERS_3_STAT].unsetinfo); 11108360efbdSAlfred Perlstein break; 11118360efbdSAlfred Perlstein case RPCBPROC_GETADDR: 11128360efbdSAlfred Perlstein cnt = 0; 11138360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_3_STAT].addrinfo; pa; 11148360efbdSAlfred Perlstein pa = pa->next) 11158360efbdSAlfred Perlstein cnt += pa->success; 11168360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11178360efbdSAlfred Perlstein break; 11188360efbdSAlfred Perlstein case RPCBPROC_CALLIT: 11198360efbdSAlfred Perlstein cnt = 0; 11208360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_3_STAT].rmtinfo; pr; 11218360efbdSAlfred Perlstein pr = pr->next) 11228360efbdSAlfred Perlstein cnt += pr->success; 11238360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11248360efbdSAlfred Perlstein break; 11258360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 11268360efbdSAlfred Perlstein } 11278360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 11288360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_3_STAT].info[i]); 11298360efbdSAlfred Perlstein flen = strlen(fieldbuf); 11308360efbdSAlfred Perlstein printf("%s%s", rpcb3hdr[i], 11318360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 11328360efbdSAlfred Perlstein - strlen(rpcb3hdr[i]))); 11338360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 11348360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 11358360efbdSAlfred Perlstein - flen))); 11368360efbdSAlfred Perlstein lp += (flen + cnt); 11378360efbdSAlfred Perlstein } 11388360efbdSAlfred Perlstein printf("\n%s\n\n", linebuf); 11398360efbdSAlfred Perlstein 11408360efbdSAlfred Perlstein if (inf[RPCBVERS_3_STAT].info[RPCBPROC_CALLIT]) { 11418360efbdSAlfred Perlstein printf("RPCB_RMTCALL (version 3) call statistics\n"); 11428360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]); 11438360efbdSAlfred Perlstein printf("\n"); 11448360efbdSAlfred Perlstein } 11458360efbdSAlfred Perlstein 11468360efbdSAlfred Perlstein if (inf[RPCBVERS_3_STAT].info[RPCBPROC_GETADDR]) { 11478360efbdSAlfred Perlstein printf("RPCB_GETADDR (version 3) call statistics\n"); 11488360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_3_STAT, &inf[RPCBVERS_3_STAT]); 11498360efbdSAlfred Perlstein printf("\n"); 11508360efbdSAlfred Perlstein } 11518360efbdSAlfred Perlstein 11528360efbdSAlfred Perlstein printf("RPCBIND (version 4) statistics\n"); 11538360efbdSAlfred Perlstein 11548360efbdSAlfred Perlstein for (j = 0; j <= 9; j += 9) { /* Just two iterations for printing */ 11558360efbdSAlfred Perlstein lp = linebuf; 11568360efbdSAlfred Perlstein for (i = j; i <= MAX(8, rpcb_highproc_4 - 9 + j); i++) { 11578360efbdSAlfred Perlstein fieldbuf[0] = '\0'; 11588360efbdSAlfred Perlstein switch (i) { 11598360efbdSAlfred Perlstein case RPCBPROC_SET: 11608360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 11618360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].setinfo); 11628360efbdSAlfred Perlstein break; 11638360efbdSAlfred Perlstein case RPCBPROC_UNSET: 11648360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", 11658360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].unsetinfo); 11668360efbdSAlfred Perlstein break; 11678360efbdSAlfred Perlstein case RPCBPROC_GETADDR: 11688360efbdSAlfred Perlstein cnt = 0; 11698360efbdSAlfred Perlstein for (pa = inf[RPCBVERS_4_STAT].addrinfo; pa; 11708360efbdSAlfred Perlstein pa = pa->next) 11718360efbdSAlfred Perlstein cnt += pa->success; 11728360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11738360efbdSAlfred Perlstein break; 11748360efbdSAlfred Perlstein case RPCBPROC_CALLIT: 11758360efbdSAlfred Perlstein cnt = 0; 11768360efbdSAlfred Perlstein for (pr = inf[RPCBVERS_4_STAT].rmtinfo; pr; 11778360efbdSAlfred Perlstein pr = pr->next) 11788360efbdSAlfred Perlstein cnt += pr->success; 11798360efbdSAlfred Perlstein sprintf(fieldbuf, "%d/", cnt); 11808360efbdSAlfred Perlstein break; 11818360efbdSAlfred Perlstein default: break; /* For the remaining ones */ 11828360efbdSAlfred Perlstein } 11838360efbdSAlfred Perlstein cp = &fieldbuf[0] + strlen(fieldbuf); 11848360efbdSAlfred Perlstein /* 11858360efbdSAlfred Perlstein * XXX: We also add RPCBPROC_GETADDRLIST queries to 11868360efbdSAlfred Perlstein * RPCB_GETADDR because rpcbind includes the 11878360efbdSAlfred Perlstein * RPCB_GETADDRLIST successes in RPCB_GETADDR. 11888360efbdSAlfred Perlstein */ 11898360efbdSAlfred Perlstein if (i != RPCBPROC_GETADDR) 11908360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_4_STAT].info[i]); 11918360efbdSAlfred Perlstein else 11928360efbdSAlfred Perlstein sprintf(cp, "%d", inf[RPCBVERS_4_STAT].info[i] + 11938360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDRLIST]); 11948360efbdSAlfred Perlstein flen = strlen(fieldbuf); 11958360efbdSAlfred Perlstein printf("%s%s", rpcb4hdr[i], 11968360efbdSAlfred Perlstein spaces((TABSTOP * (1 + flen / TABSTOP)) 11978360efbdSAlfred Perlstein - strlen(rpcb4hdr[i]))); 11988360efbdSAlfred Perlstein sprintf(lp, "%s%s", fieldbuf, 11998360efbdSAlfred Perlstein spaces(cnt = ((TABSTOP * (1 + flen / TABSTOP)) 12008360efbdSAlfred Perlstein - flen))); 12018360efbdSAlfred Perlstein lp += (flen + cnt); 12028360efbdSAlfred Perlstein } 12038360efbdSAlfred Perlstein printf("\n%s\n", linebuf); 12048360efbdSAlfred Perlstein } 12058360efbdSAlfred Perlstein 12068360efbdSAlfred Perlstein if (inf[RPCBVERS_4_STAT].info[RPCBPROC_CALLIT] || 12078360efbdSAlfred Perlstein inf[RPCBVERS_4_STAT].info[RPCBPROC_INDIRECT]) { 12088360efbdSAlfred Perlstein printf("\n"); 12098360efbdSAlfred Perlstein printf("RPCB_RMTCALL (version 4) call statistics\n"); 12108360efbdSAlfred Perlstein print_rmtcallstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]); 12118360efbdSAlfred Perlstein } 12128360efbdSAlfred Perlstein 12138360efbdSAlfred Perlstein if (inf[RPCBVERS_4_STAT].info[RPCBPROC_GETADDR]) { 12148360efbdSAlfred Perlstein printf("\n"); 12158360efbdSAlfred Perlstein printf("RPCB_GETADDR (version 4) call statistics\n"); 12168360efbdSAlfred Perlstein print_getaddrstat(RPCBVERS_4_STAT, &inf[RPCBVERS_4_STAT]); 12178360efbdSAlfred Perlstein } 12188360efbdSAlfred Perlstein clnt_destroy(client); 12198360efbdSAlfred Perlstein } 12208360efbdSAlfred Perlstein 12218360efbdSAlfred Perlstein /* 12228360efbdSAlfred Perlstein * Delete registeration for this (prog, vers, netid) 12238360efbdSAlfred Perlstein */ 12248360efbdSAlfred Perlstein static void 12258360efbdSAlfred Perlstein deletereg(char *netid, int argc, char **argv) 12268360efbdSAlfred Perlstein { 12278360efbdSAlfred Perlstein struct netconfig *nconf = NULL; 12288360efbdSAlfred Perlstein 12298360efbdSAlfred Perlstein if (argc != 2) { 12308360efbdSAlfred Perlstein usage(); 12318360efbdSAlfred Perlstein exit(1); 12328360efbdSAlfred Perlstein } 12338360efbdSAlfred Perlstein if (netid) { 12348360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 12358360efbdSAlfred Perlstein if (nconf == NULL) { 12368360efbdSAlfred Perlstein fprintf(stderr, "rpcinfo: netid %s not supported\n", 12378360efbdSAlfred Perlstein netid); 12388360efbdSAlfred Perlstein exit(1); 12398360efbdSAlfred Perlstein } 12408360efbdSAlfred Perlstein } 12418360efbdSAlfred Perlstein if ((rpcb_unset(getprognum(argv[0]), getvers(argv[1]), nconf)) == 0) { 12428360efbdSAlfred Perlstein fprintf(stderr, 12438360efbdSAlfred Perlstein "rpcinfo: Could not delete registration for prog %s version %s\n", 12448360efbdSAlfred Perlstein argv[0], argv[1]); 12458360efbdSAlfred Perlstein exit(1); 12468360efbdSAlfred Perlstein } 12478360efbdSAlfred Perlstein } 12488360efbdSAlfred Perlstein 12498360efbdSAlfred Perlstein /* 12508360efbdSAlfred Perlstein * Create and return a handle for the given nconf. 12518360efbdSAlfred Perlstein * Exit if cannot create handle. 12528360efbdSAlfred Perlstein */ 12538360efbdSAlfred Perlstein static CLIENT * 12548360efbdSAlfred Perlstein clnt_addr_create(char *address, struct netconfig *nconf, 12558360efbdSAlfred Perlstein u_long prog, u_long vers) 12568360efbdSAlfred Perlstein { 12578360efbdSAlfred Perlstein CLIENT *client; 12588360efbdSAlfred Perlstein static struct netbuf *nbuf; 12598360efbdSAlfred Perlstein static int fd = RPC_ANYFD; 12608360efbdSAlfred Perlstein 12618360efbdSAlfred Perlstein if (fd == RPC_ANYFD) { 12628360efbdSAlfred Perlstein if ((fd = __rpc_nconf2fd(nconf)) == -1) { 12638360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_TLIERROR; 12648360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 12658360efbdSAlfred Perlstein exit(1); 12668360efbdSAlfred Perlstein } 12678360efbdSAlfred Perlstein /* Convert the uaddr to taddr */ 12688360efbdSAlfred Perlstein nbuf = uaddr2taddr(nconf, address); 12698360efbdSAlfred Perlstein if (nbuf == NULL) { 12708360efbdSAlfred Perlstein errx(1, "rpcinfo: no address for client handle"); 12718360efbdSAlfred Perlstein exit(1); 12728360efbdSAlfred Perlstein } 12738360efbdSAlfred Perlstein } 12748360efbdSAlfred Perlstein client = clnt_tli_create(fd, nconf, nbuf, prog, vers, 0, 0); 12758360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 12768360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 12778360efbdSAlfred Perlstein exit(1); 12788360efbdSAlfred Perlstein } 12798360efbdSAlfred Perlstein return (client); 12808360efbdSAlfred Perlstein } 12818360efbdSAlfred Perlstein 12828360efbdSAlfred Perlstein /* 12838360efbdSAlfred Perlstein * If the version number is given, ping that (prog, vers); else try to find 12848360efbdSAlfred Perlstein * the version numbers supported for that prog and ping all the versions. 12858360efbdSAlfred Perlstein * Remote rpcbind is not contacted for this service. The requests are 12868360efbdSAlfred Perlstein * sent directly to the services themselves. 12878360efbdSAlfred Perlstein */ 12888360efbdSAlfred Perlstein static void 12898360efbdSAlfred Perlstein addrping(char *address, char *netid, int argc, char **argv) 12908360efbdSAlfred Perlstein { 12918360efbdSAlfred Perlstein CLIENT *client; 12928360efbdSAlfred Perlstein struct timeval to; 12938360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 12948360efbdSAlfred Perlstein u_long prognum, versnum, minvers, maxvers; 12958360efbdSAlfred Perlstein struct rpc_err rpcerr; 12968360efbdSAlfred Perlstein int failure = 0; 12978360efbdSAlfred Perlstein struct netconfig *nconf; 12988360efbdSAlfred Perlstein int fd; 12998360efbdSAlfred Perlstein 13008360efbdSAlfred Perlstein if (argc < 1 || argc > 2 || (netid == NULL)) { 13018360efbdSAlfred Perlstein usage(); 13028360efbdSAlfred Perlstein exit(1); 13038360efbdSAlfred Perlstein } 13048360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 13058360efbdSAlfred Perlstein if (nconf == (struct netconfig *)NULL) { 13068360efbdSAlfred Perlstein fprintf(stderr, "rpcinfo: Could not find %s\n", netid); 13078360efbdSAlfred Perlstein exit(1); 13088360efbdSAlfred Perlstein } 13098360efbdSAlfred Perlstein to.tv_sec = 10; 13108360efbdSAlfred Perlstein to.tv_usec = 0; 13118360efbdSAlfred Perlstein prognum = getprognum(argv[0]); 13128360efbdSAlfred Perlstein if (argc == 1) { /* Version number not known */ 1313e99a5be3SGarrett Wollman /* 1314e99a5be3SGarrett Wollman * A call to version 0 should fail with a program/version 1315e99a5be3SGarrett Wollman * mismatch, and give us the range of versions supported. 1316e99a5be3SGarrett Wollman */ 13178360efbdSAlfred Perlstein versnum = MIN_VERS; 13188360efbdSAlfred Perlstein } else { 13198360efbdSAlfred Perlstein versnum = getvers(argv[1]); 1320e99a5be3SGarrett Wollman } 13218360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, versnum); 13228360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 13238360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 13248360efbdSAlfred Perlstein (char *)NULL, to); 13258360efbdSAlfred Perlstein if (argc == 2) { 13268360efbdSAlfred Perlstein /* Version number was known */ 13278360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 13288360efbdSAlfred Perlstein failure = 1; 13298360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 13308360efbdSAlfred Perlstein if (failure) 13318360efbdSAlfred Perlstein exit(1); 13328360efbdSAlfred Perlstein return; 13338360efbdSAlfred Perlstein } 13348360efbdSAlfred Perlstein /* Version number not known */ 13358360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_FD_NCLOSE, (char *)NULL); 13368360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLGET_FD, (char *)&fd); 1337e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 1338e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1339e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 1340e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 1341e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 1342e99a5be3SGarrett Wollman /* 1343e99a5be3SGarrett Wollman * Oh dear, it DOES support version 0. 1344e99a5be3SGarrett Wollman * Let's try version MAX_VERS. 1345e99a5be3SGarrett Wollman */ 13468360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 13478360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, MAX_VERS); 13488360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 13498360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 13508360efbdSAlfred Perlstein (char *)NULL, to); 1351e99a5be3SGarrett Wollman if (rpc_stat == RPC_PROGVERSMISMATCH) { 1352e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1353e99a5be3SGarrett Wollman minvers = rpcerr.re_vers.low; 1354e99a5be3SGarrett Wollman maxvers = rpcerr.re_vers.high; 1355e99a5be3SGarrett Wollman } else if (rpc_stat == RPC_SUCCESS) { 1356e99a5be3SGarrett Wollman /* 1357e99a5be3SGarrett Wollman * It also supports version MAX_VERS. 1358e99a5be3SGarrett Wollman * Looks like we have a wise guy. 1359e99a5be3SGarrett Wollman * OK, we give them information on all 1360e99a5be3SGarrett Wollman * 4 billion versions they support... 1361e99a5be3SGarrett Wollman */ 1362e99a5be3SGarrett Wollman minvers = 0; 1363e99a5be3SGarrett Wollman maxvers = MAX_VERS; 1364e99a5be3SGarrett Wollman } else { 1365e99a5be3SGarrett Wollman (void) pstatus(client, prognum, MAX_VERS); 1366e99a5be3SGarrett Wollman exit(1); 1367e99a5be3SGarrett Wollman } 1368e99a5be3SGarrett Wollman } else { 13698360efbdSAlfred Perlstein (void) pstatus(client, prognum, (u_long)0); 1370e99a5be3SGarrett Wollman exit(1); 1371e99a5be3SGarrett Wollman } 13728360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 13738360efbdSAlfred Perlstein for (versnum = minvers; versnum <= maxvers; versnum++) { 13748360efbdSAlfred Perlstein client = clnt_addr_create(address, nconf, prognum, versnum); 13758360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 13768360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 13778360efbdSAlfred Perlstein (char *)NULL, to); 13788360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 1379e99a5be3SGarrett Wollman failure = 1; 13808360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 1381e99a5be3SGarrett Wollman } 13828360efbdSAlfred Perlstein (void) close(fd); 1383e99a5be3SGarrett Wollman if (failure) 1384e99a5be3SGarrett Wollman exit(1); 13858360efbdSAlfred Perlstein return; 13868360efbdSAlfred Perlstein } 13878360efbdSAlfred Perlstein 13888360efbdSAlfred Perlstein /* 13898360efbdSAlfred Perlstein * If the version number is given, ping that (prog, vers); else try to find 13908360efbdSAlfred Perlstein * the version numbers supported for that prog and ping all the versions. 13918360efbdSAlfred Perlstein * Remote rpcbind is *contacted* for this service. The requests are 13928360efbdSAlfred Perlstein * then sent directly to the services themselves. 13938360efbdSAlfred Perlstein */ 13948360efbdSAlfred Perlstein static void 13958360efbdSAlfred Perlstein progping(char *netid, int argc, char **argv) 13968360efbdSAlfred Perlstein { 13978360efbdSAlfred Perlstein CLIENT *client; 13988360efbdSAlfred Perlstein struct timeval to; 13998360efbdSAlfred Perlstein enum clnt_stat rpc_stat; 14008360efbdSAlfred Perlstein u_long prognum, versnum, minvers, maxvers; 14018360efbdSAlfred Perlstein struct rpc_err rpcerr; 14028360efbdSAlfred Perlstein int failure = 0; 14038360efbdSAlfred Perlstein struct netconfig *nconf; 14048360efbdSAlfred Perlstein 14058360efbdSAlfred Perlstein if (argc < 2 || argc > 3 || (netid == NULL)) { 14068360efbdSAlfred Perlstein usage(); 14078360efbdSAlfred Perlstein exit(1); 14088360efbdSAlfred Perlstein } 14098360efbdSAlfred Perlstein prognum = getprognum(argv[1]); 14108360efbdSAlfred Perlstein if (argc == 2) { /* Version number not known */ 14118360efbdSAlfred Perlstein /* 14128360efbdSAlfred Perlstein * A call to version 0 should fail with a program/version 14138360efbdSAlfred Perlstein * mismatch, and give us the range of versions supported. 14148360efbdSAlfred Perlstein */ 14158360efbdSAlfred Perlstein versnum = MIN_VERS; 14168360efbdSAlfred Perlstein } else { 14178360efbdSAlfred Perlstein versnum = getvers(argv[2]); 14188360efbdSAlfred Perlstein } 14198360efbdSAlfred Perlstein if (netid) { 14208360efbdSAlfred Perlstein nconf = getnetconfigent(netid); 14218360efbdSAlfred Perlstein if (nconf == (struct netconfig *)NULL) { 14228360efbdSAlfred Perlstein fprintf(stderr, "rpcinfo: Could not find %s\n", netid); 14238360efbdSAlfred Perlstein exit(1); 14248360efbdSAlfred Perlstein } 14258360efbdSAlfred Perlstein client = clnt_tp_create(argv[0], prognum, versnum, nconf); 14268360efbdSAlfred Perlstein } else { 14278360efbdSAlfred Perlstein client = clnt_create(argv[0], prognum, versnum, "NETPATH"); 14288360efbdSAlfred Perlstein } 14298360efbdSAlfred Perlstein if (client == (CLIENT *)NULL) { 14308360efbdSAlfred Perlstein clnt_pcreateerror("rpcinfo"); 14318360efbdSAlfred Perlstein exit(1); 14328360efbdSAlfred Perlstein } 14338360efbdSAlfred Perlstein to.tv_sec = 10; 14348360efbdSAlfred Perlstein to.tv_usec = 0; 14358360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 14368360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 14378360efbdSAlfred Perlstein (char *)NULL, to); 14388360efbdSAlfred Perlstein if (argc == 3) { 14398360efbdSAlfred Perlstein /* Version number was known */ 14408360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 14418360efbdSAlfred Perlstein failure = 1; 14428360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 14438360efbdSAlfred Perlstein if (failure) 14448360efbdSAlfred Perlstein exit(1); 14458360efbdSAlfred Perlstein return; 14468360efbdSAlfred Perlstein } 14478360efbdSAlfred Perlstein /* Version number not known */ 14488360efbdSAlfred Perlstein if (rpc_stat == RPC_PROGVERSMISMATCH) { 14498360efbdSAlfred Perlstein clnt_geterr(client, &rpcerr); 14508360efbdSAlfred Perlstein minvers = rpcerr.re_vers.low; 14518360efbdSAlfred Perlstein maxvers = rpcerr.re_vers.high; 14528360efbdSAlfred Perlstein } else if (rpc_stat == RPC_SUCCESS) { 14538360efbdSAlfred Perlstein /* 14548360efbdSAlfred Perlstein * Oh dear, it DOES support version 0. 14558360efbdSAlfred Perlstein * Let's try version MAX_VERS. 14568360efbdSAlfred Perlstein */ 14578360efbdSAlfred Perlstein versnum = MAX_VERS; 14588360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum); 14598360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, 14608360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, 14618360efbdSAlfred Perlstein (xdrproc_t) xdr_void, (char *)NULL, to); 14628360efbdSAlfred Perlstein if (rpc_stat == RPC_PROGVERSMISMATCH) { 14638360efbdSAlfred Perlstein clnt_geterr(client, &rpcerr); 14648360efbdSAlfred Perlstein minvers = rpcerr.re_vers.low; 14658360efbdSAlfred Perlstein maxvers = rpcerr.re_vers.high; 14668360efbdSAlfred Perlstein } else if (rpc_stat == RPC_SUCCESS) { 14678360efbdSAlfred Perlstein /* 14688360efbdSAlfred Perlstein * It also supports version MAX_VERS. 14698360efbdSAlfred Perlstein * Looks like we have a wise guy. 14708360efbdSAlfred Perlstein * OK, we give them information on all 14718360efbdSAlfred Perlstein * 4 billion versions they support... 14728360efbdSAlfred Perlstein */ 14738360efbdSAlfred Perlstein minvers = 0; 14748360efbdSAlfred Perlstein maxvers = MAX_VERS; 14758360efbdSAlfred Perlstein } else { 14768360efbdSAlfred Perlstein (void) pstatus(client, prognum, MAX_VERS); 14778360efbdSAlfred Perlstein exit(1); 14788360efbdSAlfred Perlstein } 14798360efbdSAlfred Perlstein } else { 14808360efbdSAlfred Perlstein (void) pstatus(client, prognum, (u_long)0); 14818360efbdSAlfred Perlstein exit(1); 14828360efbdSAlfred Perlstein } 14838360efbdSAlfred Perlstein for (versnum = minvers; versnum <= maxvers; versnum++) { 14848360efbdSAlfred Perlstein (void) CLNT_CONTROL(client, CLSET_VERS, (char *)&versnum); 14858360efbdSAlfred Perlstein rpc_stat = CLNT_CALL(client, NULLPROC, (xdrproc_t) xdr_void, 14868360efbdSAlfred Perlstein (char *)NULL, (xdrproc_t) xdr_void, 14878360efbdSAlfred Perlstein (char *)NULL, to); 14888360efbdSAlfred Perlstein if (pstatus(client, prognum, versnum) < 0) 14898360efbdSAlfred Perlstein failure = 1; 14908360efbdSAlfred Perlstein } 14918360efbdSAlfred Perlstein (void) CLNT_DESTROY(client); 14928360efbdSAlfred Perlstein if (failure) 14938360efbdSAlfred Perlstein exit(1); 14948360efbdSAlfred Perlstein return; 14958360efbdSAlfred Perlstein } 14968360efbdSAlfred Perlstein 14978360efbdSAlfred Perlstein static void 14988360efbdSAlfred Perlstein usage() 14998360efbdSAlfred Perlstein { 15008360efbdSAlfred Perlstein fprintf(stderr, "Usage: rpcinfo [-m | -s] [host]\n"); 15018360efbdSAlfred Perlstein #ifdef PORTMAP 15028360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -p [host]\n"); 15038360efbdSAlfred Perlstein #endif 15048360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -T netid host prognum [versnum]\n"); 15058360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -l host prognum versnum\n"); 15068360efbdSAlfred Perlstein #ifdef PORTMAP 15078360efbdSAlfred Perlstein fprintf(stderr, 15088360efbdSAlfred Perlstein " rpcinfo [-n portnum] -u | -t host prognum [versnum]\n"); 15098360efbdSAlfred Perlstein #endif 15108360efbdSAlfred Perlstein fprintf(stderr, 15118360efbdSAlfred Perlstein " rpcinfo -a serv_address -T netid prognum [version]\n"); 15128360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -b prognum versnum\n"); 15138360efbdSAlfred Perlstein fprintf(stderr, " rpcinfo -d [-T netid] prognum versnum\n"); 15148360efbdSAlfred Perlstein } 15158360efbdSAlfred Perlstein 15168360efbdSAlfred Perlstein static u_long 15178360efbdSAlfred Perlstein getprognum (char *arg) 15188360efbdSAlfred Perlstein { 15198360efbdSAlfred Perlstein char *strptr; 15208360efbdSAlfred Perlstein register struct rpcent *rpc; 15218360efbdSAlfred Perlstein register u_long prognum; 15228360efbdSAlfred Perlstein char *tptr = arg; 15238360efbdSAlfred Perlstein 15248360efbdSAlfred Perlstein while (*tptr && isdigit(*tptr++)); 15258360efbdSAlfred Perlstein if (*tptr || isalpha(*(tptr - 1))) { 15268360efbdSAlfred Perlstein rpc = getrpcbyname(arg); 15278360efbdSAlfred Perlstein if (rpc == NULL) { 15288360efbdSAlfred Perlstein fprintf(stderr, "rpcinfo: %s is unknown service\n", 15298360efbdSAlfred Perlstein arg); 15308360efbdSAlfred Perlstein exit(1); 15318360efbdSAlfred Perlstein } 15328360efbdSAlfred Perlstein prognum = rpc->r_number; 15338360efbdSAlfred Perlstein } else { 15348360efbdSAlfred Perlstein prognum = strtol(arg, &strptr, 10); 15358360efbdSAlfred Perlstein if (strptr == arg || *strptr != '\0') { 15368360efbdSAlfred Perlstein fprintf(stderr, 15378360efbdSAlfred Perlstein "rpcinfo: %s is illegal program number\n", arg); 15388360efbdSAlfred Perlstein exit(1); 15398360efbdSAlfred Perlstein } 15408360efbdSAlfred Perlstein } 15418360efbdSAlfred Perlstein return (prognum); 15428360efbdSAlfred Perlstein } 15438360efbdSAlfred Perlstein 15448360efbdSAlfred Perlstein static u_long 15458360efbdSAlfred Perlstein getvers(char *arg) 15468360efbdSAlfred Perlstein { 15478360efbdSAlfred Perlstein char *strptr; 15488360efbdSAlfred Perlstein register u_long vers; 15498360efbdSAlfred Perlstein 15508360efbdSAlfred Perlstein vers = (int) strtol(arg, &strptr, 10); 15518360efbdSAlfred Perlstein if (strptr == arg || *strptr != '\0') { 15528360efbdSAlfred Perlstein fprintf(stderr, "rpcinfo: %s is illegal version number\n", 15538360efbdSAlfred Perlstein arg); 15548360efbdSAlfred Perlstein exit(1); 15558360efbdSAlfred Perlstein } 15568360efbdSAlfred Perlstein return (vers); 1557e99a5be3SGarrett Wollman } 1558e99a5be3SGarrett Wollman 1559e99a5be3SGarrett Wollman /* 1560e99a5be3SGarrett Wollman * This routine should take a pointer to an "rpc_err" structure, rather than 1561e99a5be3SGarrett Wollman * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to 1562e99a5be3SGarrett Wollman * a CLIENT structure rather than a pointer to an "rpc_err" structure. 1563e99a5be3SGarrett Wollman * As such, we have to keep the CLIENT structure around in order to print 1564e99a5be3SGarrett Wollman * a good error message. 1565e99a5be3SGarrett Wollman */ 1566e99a5be3SGarrett Wollman static int 15678360efbdSAlfred Perlstein pstatus(register CLIENT *client, u_long prog, u_long vers) 1568e99a5be3SGarrett Wollman { 1569e99a5be3SGarrett Wollman struct rpc_err rpcerr; 1570e99a5be3SGarrett Wollman 1571e99a5be3SGarrett Wollman clnt_geterr(client, &rpcerr); 1572e99a5be3SGarrett Wollman if (rpcerr.re_status != RPC_SUCCESS) { 1573e99a5be3SGarrett Wollman clnt_perror(client, "rpcinfo"); 1574e99a5be3SGarrett Wollman printf("program %lu version %lu is not available\n", 15758360efbdSAlfred Perlstein prog, vers); 1576e99a5be3SGarrett Wollman return (-1); 1577e99a5be3SGarrett Wollman } else { 1578e99a5be3SGarrett Wollman printf("program %lu version %lu ready and waiting\n", 15798360efbdSAlfred Perlstein prog, vers); 1580e99a5be3SGarrett Wollman return (0); 1581e99a5be3SGarrett Wollman } 1582e99a5be3SGarrett Wollman } 1583e99a5be3SGarrett Wollman 15848360efbdSAlfred Perlstein static CLIENT * 15858360efbdSAlfred Perlstein clnt_rpcbind_create(char *host, int rpcbversnum, struct netbuf **targaddr) 1586e99a5be3SGarrett Wollman { 15878360efbdSAlfred Perlstein static char *tlist[3] = { 15888360efbdSAlfred Perlstein "circuit_n", "circuit_v", "datagram_v" 15898360efbdSAlfred Perlstein }; 15908360efbdSAlfred Perlstein int i; 15918360efbdSAlfred Perlstein struct netconfig *nconf; 15928360efbdSAlfred Perlstein CLIENT *clnt = NULL; 15938360efbdSAlfred Perlstein void *handle; 15948360efbdSAlfred Perlstein 15958360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_SUCCESS; 15968360efbdSAlfred Perlstein for (i = 0; i < 3; i++) { 15978360efbdSAlfred Perlstein if ((handle = __rpc_setconf(tlist[i])) == NULL) 15988360efbdSAlfred Perlstein continue; 15998360efbdSAlfred Perlstein while (clnt == (CLIENT *)NULL) { 16008360efbdSAlfred Perlstein if ((nconf = __rpc_getconf(handle)) == NULL) { 16018360efbdSAlfred Perlstein if (rpc_createerr.cf_stat == RPC_SUCCESS) 16028360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 16038360efbdSAlfred Perlstein break; 16048360efbdSAlfred Perlstein } 16058360efbdSAlfred Perlstein clnt = getclnthandle(host, nconf, rpcbversnum, 16068360efbdSAlfred Perlstein targaddr); 16078360efbdSAlfred Perlstein } 16088360efbdSAlfred Perlstein if (clnt) 16098360efbdSAlfred Perlstein break; 16108360efbdSAlfred Perlstein __rpc_endconf(handle); 16118360efbdSAlfred Perlstein } 16128360efbdSAlfred Perlstein return (clnt); 16138360efbdSAlfred Perlstein } 16148360efbdSAlfred Perlstein 16158360efbdSAlfred Perlstein static CLIENT* 16168360efbdSAlfred Perlstein getclnthandle(char *host, struct netconfig *nconf, 16178360efbdSAlfred Perlstein u_long rpcbversnum, struct netbuf **targaddr) 16188360efbdSAlfred Perlstein { 16198360efbdSAlfred Perlstein struct netbuf addr; 16208360efbdSAlfred Perlstein struct addrinfo hints, *res; 16218360efbdSAlfred Perlstein CLIENT *client = NULL; 16228360efbdSAlfred Perlstein 16238360efbdSAlfred Perlstein /* Get the address of the rpcbind */ 16248360efbdSAlfred Perlstein memset(&hints, 0, sizeof hints); 16258360efbdSAlfred Perlstein if (getaddrinfo(host, "rpcbind", &hints, &res) != 0) { 16268360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; 16278360efbdSAlfred Perlstein return (NULL); 16288360efbdSAlfred Perlstein } 16298360efbdSAlfred Perlstein addr.len = addr.maxlen = res->ai_addrlen; 16308360efbdSAlfred Perlstein addr.buf = res->ai_addr; 16318360efbdSAlfred Perlstein client = clnt_tli_create(RPC_ANYFD, nconf, &addr, RPCBPROG, 16328360efbdSAlfred Perlstein rpcbversnum, 0, 0); 16338360efbdSAlfred Perlstein if (client) { 16348360efbdSAlfred Perlstein if (targaddr != NULL) { 16358360efbdSAlfred Perlstein *targaddr = 16368360efbdSAlfred Perlstein (struct netbuf *)malloc(sizeof (struct netbuf)); 16378360efbdSAlfred Perlstein if (*targaddr != NULL) { 16388360efbdSAlfred Perlstein (*targaddr)->maxlen = addr.maxlen; 16398360efbdSAlfred Perlstein (*targaddr)->len = addr.len; 16408360efbdSAlfred Perlstein (*targaddr)->buf = (char *)malloc(addr.len); 16418360efbdSAlfred Perlstein if ((*targaddr)->buf != NULL) { 16428360efbdSAlfred Perlstein memcpy((*targaddr)->buf, addr.buf, 16438360efbdSAlfred Perlstein addr.len); 16448360efbdSAlfred Perlstein } 16458360efbdSAlfred Perlstein } 16468360efbdSAlfred Perlstein } 16478360efbdSAlfred Perlstein } else { 16488360efbdSAlfred Perlstein if (rpc_createerr.cf_stat == RPC_TLIERROR) { 16498360efbdSAlfred Perlstein /* 16508360efbdSAlfred Perlstein * Assume that the other system is dead; this is a 16518360efbdSAlfred Perlstein * better error to display to the user. 16528360efbdSAlfred Perlstein */ 16538360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_RPCBFAILURE; 16548360efbdSAlfred Perlstein rpc_createerr.cf_error.re_status = RPC_FAILED; 16558360efbdSAlfred Perlstein } 16568360efbdSAlfred Perlstein } 16578360efbdSAlfred Perlstein freeaddrinfo(res); 16588360efbdSAlfred Perlstein return (client); 16598360efbdSAlfred Perlstein } 16608360efbdSAlfred Perlstein 16618360efbdSAlfred Perlstein static void 16628360efbdSAlfred Perlstein print_rmtcallstat(int rtype, rpcb_stat *infp) 16638360efbdSAlfred Perlstein { 16648360efbdSAlfred Perlstein register rpcbs_rmtcalllist_ptr pr; 1665e99a5be3SGarrett Wollman struct rpcent *rpc; 1666e99a5be3SGarrett Wollman 16678360efbdSAlfred Perlstein if (rtype == RPCBVERS_4_STAT) 16688360efbdSAlfred Perlstein printf( 16698360efbdSAlfred Perlstein "prog\t\tvers\tproc\tnetid\tindirect success failure\n"); 1670e99a5be3SGarrett Wollman else 16718360efbdSAlfred Perlstein printf("prog\t\tvers\tproc\tnetid\tsuccess\tfailure\n"); 16728360efbdSAlfred Perlstein for (pr = infp->rmtinfo; pr; pr = pr->next) { 16738360efbdSAlfred Perlstein rpc = getrpcbynumber(pr->prog); 1674e99a5be3SGarrett Wollman if (rpc) 16758360efbdSAlfred Perlstein printf("%-16s", rpc->r_name); 1676e99a5be3SGarrett Wollman else 16778360efbdSAlfred Perlstein printf("%-16d", pr->prog); 16788360efbdSAlfred Perlstein printf("%d\t%d\t%s\t", 16798360efbdSAlfred Perlstein pr->vers, pr->proc, pr->netid); 16808360efbdSAlfred Perlstein if (rtype == RPCBVERS_4_STAT) 16818360efbdSAlfred Perlstein printf("%d\t ", pr->indirect); 16828360efbdSAlfred Perlstein printf("%d\t%d\n", pr->success, pr->failure); 1683e99a5be3SGarrett Wollman } 1684e99a5be3SGarrett Wollman } 1685e99a5be3SGarrett Wollman 1686e99a5be3SGarrett Wollman static void 16878360efbdSAlfred Perlstein print_getaddrstat(int rtype, rpcb_stat *infp) 1688e99a5be3SGarrett Wollman { 16898360efbdSAlfred Perlstein rpcbs_addrlist_ptr al; 1690e99a5be3SGarrett Wollman register struct rpcent *rpc; 1691e99a5be3SGarrett Wollman 16928360efbdSAlfred Perlstein printf("prog\t\tvers\tnetid\t success\tfailure\n"); 16938360efbdSAlfred Perlstein for (al = infp->addrinfo; al; al = al->next) { 16948360efbdSAlfred Perlstein rpc = getrpcbynumber(al->prog); 16958360efbdSAlfred Perlstein if (rpc) 16968360efbdSAlfred Perlstein printf("%-16s", rpc->r_name); 16978360efbdSAlfred Perlstein else 16988360efbdSAlfred Perlstein printf("%-16d", al->prog); 16998360efbdSAlfred Perlstein printf("%d\t%s\t %-12d\t%d\n", 17008360efbdSAlfred Perlstein al->vers, al->netid, 17018360efbdSAlfred Perlstein al->success, al->failure); 17028360efbdSAlfred Perlstein } 1703e99a5be3SGarrett Wollman } 1704e99a5be3SGarrett Wollman 17058360efbdSAlfred Perlstein static char * 17068360efbdSAlfred Perlstein spaces(int howmany) 1707e99a5be3SGarrett Wollman { 17088360efbdSAlfred Perlstein static char space_array[] = /* 64 spaces */ 17098360efbdSAlfred Perlstein " "; 1710e99a5be3SGarrett Wollman 17118360efbdSAlfred Perlstein if (howmany <= 0 || howmany > sizeof (space_array)) { 17128360efbdSAlfred Perlstein return (""); 1713e99a5be3SGarrett Wollman } 17148360efbdSAlfred Perlstein return (&space_array[sizeof (space_array) - howmany - 1]); 1715e99a5be3SGarrett Wollman } 1716