diff options
Diffstat (limited to 'sunrpc/rpcinfo.c')
-rw-r--r-- | sunrpc/rpcinfo.c | 739 |
1 files changed, 0 insertions, 739 deletions
diff --git a/sunrpc/rpcinfo.c b/sunrpc/rpcinfo.c deleted file mode 100644 index 2b55eb4..0000000 --- a/sunrpc/rpcinfo.c +++ /dev/null @@ -1,739 +0,0 @@ -/* - * Copyright (c) 2010, Oracle America, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * * Neither the name of the "Oracle America, Inc." nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * rpcinfo: ping a particular rpc program - * or dump the portmapper - */ - -#include <getopt.h> -#include <string.h> -#include <unistd.h> -#include <rpc/rpc.h> -#include <stdio.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <rpc/pmap_prot.h> -#include <rpc/pmap_clnt.h> -#include <signal.h> -#include <ctype.h> -#include <locale.h> -#include <libintl.h> - -#include "../version.h" -#define PACKAGE _libc_intl_domainname - -#define MAXHOSTLEN 256 - -#define MIN_VERS ((u_long) 0) -#define MAX_VERS ((u_long) 4294967295UL) - -static void udpping (u_short portflag, int argc, char **argv); -static void tcpping (u_short portflag, int argc, char **argv); -static int pstatus (CLIENT *client, u_long prognum, u_long vers); -static void pmapdump (int argc, char **argv); -static bool_t reply_proc (void *res, struct sockaddr_in *who); -static void brdcst (int argc, char **argv) __attribute__ ((noreturn)); -static void deletereg (int argc, char **argv); -static void usage (FILE *stream); -static void print_version (void); -static u_long getprognum (char *arg); -static u_long getvers (char *arg); -static void get_inet_address (struct sockaddr_in *addr, char *host); - -/* - * Functions to be performed. - */ -#define NONE 0 /* no function */ -#define PMAPDUMP 1 /* dump portmapper registrations */ -#define TCPPING 2 /* ping TCP service */ -#define UDPPING 3 /* ping UDP service */ -#define BRDCST 4 /* ping broadcast UDP service */ -#define DELETES 5 /* delete registration for the service */ - -int -main (int argc, char **argv) -{ - register int c; - int errflg; - int function; - u_short portnum; - static const struct option long_options[] = { - { "help", no_argument, NULL, 'H' }, - { "version", no_argument, NULL, 'V' }, - { NULL, 0, NULL, 0 } - }; - - setlocale (LC_ALL, ""); - textdomain (_libc_intl_domainname); - - function = NONE; - portnum = 0; - errflg = 0; - while ((c = getopt_long (argc, argv, "ptubdn:", long_options, NULL)) != -1) - { - switch (c) - { - - case 'p': - if (function != NONE) - errflg = 1; - else - function = PMAPDUMP; - break; - - case 't': - if (function != NONE) - errflg = 1; - else - function = TCPPING; - break; - - case 'u': - if (function != NONE) - errflg = 1; - else - function = UDPPING; - break; - - case 'b': - if (function != NONE) - errflg = 1; - else - function = BRDCST; - break; - - case 'n': - portnum = (u_short) atoi (optarg); /* hope we don't get bogus # */ - break; - - case 'd': - if (function != NONE) - errflg = 1; - else - function = DELETES; - break; - - case 'H': - usage (stdout); - return 0; - - case 'V': - print_version (); - return 0; - - case '?': - errflg = 1; - } - } - - if (errflg || function == NONE) - { - usage (stderr); - return 1; - } - - switch (function) - { - - case PMAPDUMP: - if (portnum != 0) - { - usage (stderr); - return 1; - } - pmapdump (argc - optind, argv + optind); - break; - - case UDPPING: - udpping (portnum, argc - optind, argv + optind); - break; - - case TCPPING: - tcpping (portnum, argc - optind, argv + optind); - break; - - case BRDCST: - if (portnum != 0) - { - usage (stderr); - return 1; - } - brdcst (argc - optind, argv + optind); - break; - - case DELETES: - deletereg (argc - optind, argv + optind); - break; - } - - return 0; -} - -static void -udpping (u_short portnum, int argc, char **argv) -{ - struct timeval to; - struct sockaddr_in addr; - enum clnt_stat rpc_stat; - CLIENT *client; - u_long prognum, vers, minvers, maxvers; - int sock = RPC_ANYSOCK; - struct rpc_err rpcerr; - int failure; - - if (argc < 2 || argc > 3) - { - usage (stderr); - exit (1); - } - prognum = getprognum (argv[1]); - get_inet_address (&addr, argv[0]); - /* Open the socket here so it will survive calls to clnt_destroy */ - sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock < 0) - { - perror ("rpcinfo: socket"); - exit (1); - } - failure = 0; - if (argc == 2) - { - /* - * A call to version 0 should fail with a program/version - * mismatch, and give us the range of versions supported. - */ - addr.sin_port = htons (portnum); - to.tv_sec = 5; - to.tv_usec = 0; - if ((client = clntudp_create (&addr, prognum, (u_long) 0, - to, &sock)) == NULL) - { - clnt_pcreateerror ("rpcinfo"); - printf (_("program %lu is not available\n"), prognum); - exit (1); - } - to.tv_sec = 10; - to.tv_usec = 0; - rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, - (char *) NULL, (xdrproc_t) xdr_void, - (char *) NULL, to); - if (rpc_stat == RPC_PROGVERSMISMATCH) - { - clnt_geterr (client, &rpcerr); - minvers = rpcerr.re_vers.low; - maxvers = rpcerr.re_vers.high; - } - else if (rpc_stat == RPC_SUCCESS) - { - /* - * Oh dear, it DOES support version 0. - * Let's try version MAX_VERS. - */ - addr.sin_port = htons (portnum); - to.tv_sec = 5; - to.tv_usec = 0; - if ((client = clntudp_create (&addr, prognum, MAX_VERS, - to, &sock)) == NULL) - { - clnt_pcreateerror ("rpcinfo"); - printf (_("program %lu version %lu is not available\n"), - prognum, MAX_VERS); - exit (1); - } - to.tv_sec = 10; - to.tv_usec = 0; - rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, - NULL, (xdrproc_t) xdr_void, NULL, to); - if (rpc_stat == RPC_PROGVERSMISMATCH) - { - clnt_geterr (client, &rpcerr); - minvers = rpcerr.re_vers.low; - maxvers = rpcerr.re_vers.high; - } - else if (rpc_stat == RPC_SUCCESS) - { - /* - * It also supports version MAX_VERS. - * Looks like we have a wise guy. - * OK, we give them information on all - * 4 billion versions they support... - */ - minvers = 0; - maxvers = MAX_VERS; - } - else - { - (void) pstatus (client, prognum, MAX_VERS); - exit (1); - } - } - else - { - (void) pstatus (client, prognum, (u_long) 0); - exit (1); - } - clnt_destroy (client); - for (vers = minvers; vers <= maxvers; vers++) - { - addr.sin_port = htons (portnum); - to.tv_sec = 5; - to.tv_usec = 0; - if ((client = clntudp_create (&addr, prognum, vers, - to, &sock)) == NULL) - { - clnt_pcreateerror ("rpcinfo"); - printf (_("program %lu version %lu is not available\n"), - prognum, vers); - exit (1); - } - to.tv_sec = 10; - to.tv_usec = 0; - rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, - NULL, (xdrproc_t) xdr_void, NULL, to); - if (pstatus (client, prognum, vers) < 0) - failure = 1; - clnt_destroy (client); - } - } - else - { - vers = getvers (argv[2]); - addr.sin_port = htons (portnum); - to.tv_sec = 5; - to.tv_usec = 0; - if ((client = clntudp_create (&addr, prognum, vers, - to, &sock)) == NULL) - { - clnt_pcreateerror ("rpcinfo"); - printf (_("program %lu version %lu is not available\n"), - prognum, vers); - exit (1); - } - to.tv_sec = 10; - to.tv_usec = 0; - rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_void, NULL, to); - if (pstatus (client, prognum, vers) < 0) - failure = 1; - } - (void) close (sock); /* Close it up again */ - if (failure) - exit (1); -} - -static void -tcpping (u_short portnum, int argc, char **argv) -{ - struct timeval to; - struct sockaddr_in addr; - enum clnt_stat rpc_stat; - CLIENT *client; - u_long prognum, vers, minvers, maxvers; - int sock = RPC_ANYSOCK; - struct rpc_err rpcerr; - int failure; - - if (argc < 2 || argc > 3) - { - usage (stderr); - exit (1); - } - prognum = getprognum (argv[1]); - get_inet_address (&addr, argv[0]); - failure = 0; - if (argc == 2) - { - /* - * A call to version 0 should fail with a program/version - * mismatch, and give us the range of versions supported. - */ - addr.sin_port = htons (portnum); - if ((client = clnttcp_create (&addr, prognum, MIN_VERS, - &sock, 0, 0)) == NULL) - { - clnt_pcreateerror ("rpcinfo"); - printf (_("program %lu is not available\n"), prognum); - exit (1); - } - to.tv_sec = 10; - to.tv_usec = 0; - rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_void, NULL, to); - if (rpc_stat == RPC_PROGVERSMISMATCH) - { - clnt_geterr (client, &rpcerr); - minvers = rpcerr.re_vers.low; - maxvers = rpcerr.re_vers.high; - } - else if (rpc_stat == RPC_SUCCESS) - { - /* - * Oh dear, it DOES support version 0. - * Let's try version MAX_VERS. - */ - addr.sin_port = htons (portnum); - if ((client = clnttcp_create (&addr, prognum, MAX_VERS, - &sock, 0, 0)) == NULL) - { - clnt_pcreateerror ("rpcinfo"); - printf (_("program %lu version %lu is not available\n"), - prognum, MAX_VERS); - exit (1); - } - to.tv_sec = 10; - to.tv_usec = 0; - rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, - NULL, (xdrproc_t) xdr_void, NULL, to); - if (rpc_stat == RPC_PROGVERSMISMATCH) - { - clnt_geterr (client, &rpcerr); - minvers = rpcerr.re_vers.low; - maxvers = rpcerr.re_vers.high; - } - else if (rpc_stat == RPC_SUCCESS) - { - /* - * It also supports version MAX_VERS. - * Looks like we have a wise guy. - * OK, we give them information on all - * 4 billion versions they support... - */ - minvers = 0; - maxvers = MAX_VERS; - } - else - { - (void) pstatus (client, prognum, MAX_VERS); - exit (1); - } - } - else - { - (void) pstatus (client, prognum, MIN_VERS); - exit (1); - } - clnt_destroy (client); - (void) close (sock); - sock = RPC_ANYSOCK; /* Re-initialize it for later */ - for (vers = minvers; vers <= maxvers; vers++) - { - addr.sin_port = htons (portnum); - if ((client = clnttcp_create (&addr, prognum, vers, - &sock, 0, 0)) == NULL) - { - clnt_pcreateerror ("rpcinfo"); - printf (_("program %lu version %lu is not available\n"), - prognum, vers); - exit (1); - } - to.tv_usec = 0; - to.tv_sec = 10; - rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_void, NULL, to); - if (pstatus (client, prognum, vers) < 0) - failure = 1; - clnt_destroy (client); - (void) close (sock); - sock = RPC_ANYSOCK; - } - } - else - { - vers = getvers (argv[2]); - addr.sin_port = htons (portnum); - if ((client = clnttcp_create (&addr, prognum, vers, &sock, - 0, 0)) == NULL) - { - clnt_pcreateerror ("rpcinfo"); - printf (_("program %lu version %lu is not available\n"), - prognum, vers); - exit (1); - } - to.tv_usec = 0; - to.tv_sec = 10; - rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_void, NULL, to); - if (pstatus (client, prognum, vers) < 0) - failure = 1; - } - if (failure) - exit (1); -} - -/* - * This routine should take a pointer to an "rpc_err" structure, rather than - * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to - * a CLIENT structure rather than a pointer to an "rpc_err" structure. - * As such, we have to keep the CLIENT structure around in order to print - * a good error message. - */ -static int -pstatus (register CLIENT *client, u_long prognum, u_long vers) -{ - struct rpc_err rpcerr; - - clnt_geterr (client, &rpcerr); - if (rpcerr.re_status != RPC_SUCCESS) - { - clnt_perror (client, "rpcinfo"); - printf (_("program %lu version %lu is not available\n"), prognum, vers); - return -1; - } - else - { - printf (_("program %lu version %lu ready and waiting\n"), prognum, vers); - return 0; - } -} - -static void -pmapdump (int argc, char **argv) -{ - struct sockaddr_in server_addr; - register struct hostent *hp; - struct pmaplist *head = NULL; - int socket = RPC_ANYSOCK; - struct timeval minutetimeout; - register CLIENT *client; - struct rpcent *rpc; - - if (argc > 1) - { - usage (stderr); - exit (1); - } - if (argc == 1) - get_inet_address (&server_addr, argv[0]); - else - { - bzero ((char *) &server_addr, sizeof server_addr); - server_addr.sin_family = AF_INET; - if ((hp = gethostbyname ("localhost")) != NULL) - memcpy ((caddr_t) & server_addr.sin_addr, hp->h_addr, - hp->h_length); - else - server_addr.sin_addr.s_addr = inet_addr ("0.0.0.0"); - } - minutetimeout.tv_sec = 60; - minutetimeout.tv_usec = 0; - server_addr.sin_port = htons (PMAPPORT); - if ((client = clnttcp_create (&server_addr, PMAPPROG, - PMAPVERS, &socket, 50, 500)) == NULL) - { - clnt_pcreateerror (_("rpcinfo: can't contact portmapper")); - exit (1); - } - if (clnt_call (client, PMAPPROC_DUMP, (xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_pmaplist, (caddr_t) &head, - minutetimeout) != RPC_SUCCESS) - { - fputs (_("rpcinfo: can't contact portmapper"), stderr); - fputs (": ", stderr); - clnt_perror (client, "rpcinfo"); - exit (1); - } - if (head == NULL) - { - fputs (_("No remote programs registered.\n"), stdout); - } - else - { - fputs (_(" program vers proto port\n"), stdout); - for (; head != NULL; head = head->pml_next) - { - printf ("%10ld%5ld", - head->pml_map.pm_prog, - head->pml_map.pm_vers); - if (head->pml_map.pm_prot == IPPROTO_UDP) - printf ("%6s", "udp"); - else if (head->pml_map.pm_prot == IPPROTO_TCP) - printf ("%6s", "tcp"); - else - printf ("%6ld", head->pml_map.pm_prot); - printf ("%7ld", head->pml_map.pm_port); - rpc = getrpcbynumber (head->pml_map.pm_prog); - if (rpc) - printf (" %s\n", rpc->r_name); - else - printf ("\n"); - } - } -} - -/* - * reply_proc collects replies from the broadcast. - * to get a unique list of responses the output of rpcinfo should - * be piped through sort(1) and then uniq(1). - */ - -/*ARGSUSED */ -static bool_t -reply_proc (res, who) - void *res; /* Nothing comes back */ - struct sockaddr_in *who; /* Who sent us the reply */ -{ - register struct hostent *hp; - - hp = gethostbyaddr ((char *) &who->sin_addr, sizeof who->sin_addr, - AF_INET); - printf ("%s %s\n", inet_ntoa (who->sin_addr), - (hp == NULL) ? _("(unknown)") : hp->h_name); - return FALSE; -} - -static void -brdcst (int argc, char **argv) -{ - enum clnt_stat rpc_stat; - u_long prognum, vers; - - if (argc != 2) - { - usage (stderr); - exit (1); - } - prognum = getprognum (argv[0]); - vers = getvers (argv[1]); - rpc_stat = clnt_broadcast (prognum, vers, NULLPROC, (xdrproc_t) xdr_void, - NULL, (xdrproc_t) xdr_void, NULL, - (resultproc_t) reply_proc); - if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) - { - fprintf (stderr, _("rpcinfo: broadcast failed: %s\n"), - clnt_sperrno (rpc_stat)); - exit (1); - } - exit (0); -} - -static void -deletereg (int argc, char **argv) -{ - u_long prog_num, version_num; - - if (argc != 2) - { - usage (stderr); - exit (1); - } - if (getuid ()) - { /* This command allowed only to root */ - fputs (_("Sorry. You are not root\n"), stderr); - exit (1); - } - prog_num = getprognum (argv[0]); - version_num = getvers (argv[1]); - if ((pmap_unset (prog_num, version_num)) == 0) - { - fprintf (stderr, _("rpcinfo: Could not delete registration for prog %s version %s\n"), - argv[0], argv[1]); - exit (1); - } -} - -static void -usage (FILE *stream) -{ - fputs (_("Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"), - stream); - fputs (_(" rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"), - stream); - fputs (_(" rpcinfo -p [ host ]\n"), stream); - fputs (_(" rpcinfo -b prognum versnum\n"), stream); - fputs (_(" rpcinfo -d prognum versnum\n"), stream); - fputc ('\n', stream); - fprintf (stream, _("\ -For bug reporting instructions, please see:\n\ -%s.\n"), REPORT_BUGS_TO); -} - -static void -print_version (void) -{ - printf ("rpcinfo %s%s\n", PKGVERSION, VERSION); -} - -static u_long -getprognum (char *arg) -{ - register struct rpcent *rpc; - register u_long prognum; - - if (isalpha (*arg)) - { - rpc = getrpcbyname (arg); - if (rpc == NULL) - { - fprintf (stderr, _("rpcinfo: %s is unknown service\n"), arg); - exit (1); - } - prognum = rpc->r_number; - } - else - { - prognum = (u_long) atoi (arg); - } - - return prognum; -} - -static u_long -getvers (char *arg) -{ - register u_long vers; - - vers = (int) atoi (arg); - return vers; -} - -static void -get_inet_address (struct sockaddr_in *addr, char *host) -{ - register struct hostent *hp; - - bzero ((char *) addr, sizeof *addr); - addr->sin_addr.s_addr = (u_long) inet_addr (host); - if (addr->sin_addr.s_addr == INADDR_NONE - || addr->sin_addr.s_addr == INADDR_ANY) - { - if ((hp = gethostbyname (host)) == NULL) - { - fprintf (stderr, _("rpcinfo: %s is unknown host\n"), - host); - exit (1); - } - memmove ((char *) &addr->sin_addr, hp->h_addr, hp->h_length); - } - addr->sin_family = AF_INET; -} |