aboutsummaryrefslogtreecommitdiff
path: root/sunrpc/rpcinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'sunrpc/rpcinfo.c')
-rw-r--r--sunrpc/rpcinfo.c739
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;
-}