Back to index

glibc  2.9
Defines | Functions
rpcinfo.c File Reference
#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>

Go to the source code of this file.

Defines

#define MAXHOSTLEN   256
#define MIN_VERS   ((u_long) 0)
#define MAX_VERS   ((u_long) 4294967295UL)
#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 */

Functions

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 (void)
static u_long getprognum (char *arg)
static u_long getvers (char *arg)
static void get_inet_address (struct sockaddr_in *addr, char *host)
int main (int argc, char **argv)

Define Documentation

#define BRDCST   4 /* ping broadcast UDP service */

Definition at line 85 of file rpcinfo.c.

#define DELETES   5 /* delete registration for the service */

Definition at line 86 of file rpcinfo.c.

#define MAX_VERS   ((u_long) 4294967295UL)

Definition at line 64 of file rpcinfo.c.

#define MAXHOSTLEN   256

Definition at line 61 of file rpcinfo.c.

#define MIN_VERS   ((u_long) 0)

Definition at line 63 of file rpcinfo.c.

#define NONE   0 /* no function */

Definition at line 81 of file rpcinfo.c.

#define PMAPDUMP   1 /* dump portmapper registrations */

Definition at line 82 of file rpcinfo.c.

#define TCPPING   2 /* ping TCP service */

Definition at line 83 of file rpcinfo.c.

#define UDPPING   3 /* ping UDP service */

Definition at line 84 of file rpcinfo.c.


Function Documentation

static void brdcst ( int  argc,
char **  argv 
) [static]

Definition at line 618 of file rpcinfo.c.

{
  enum clnt_stat rpc_stat;
  u_long prognum, vers;

  if (argc != 2)
    {
      usage ();
      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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void deletereg ( int  argc,
char **  argv 
) [static]

Definition at line 645 of file rpcinfo.c.

{
  u_long prog_num, version_num;

  if (argc != 2)
    {
      usage ();
      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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_inet_address ( struct sockaddr_in addr,
char *  host 
) [static]

Definition at line 719 of file rpcinfo.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static u_long getprognum ( char *  arg) [static]

Definition at line 684 of file rpcinfo.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static u_long getvers ( char *  arg) [static]

Definition at line 709 of file rpcinfo.c.

{
  register u_long vers;

  vers = (int) atoi (arg);
  return vers;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 89 of file rpcinfo.c.

{
  register int c;
  int errflg;
  int function;
  u_short portnum;

  setlocale (LC_ALL, "");
  textdomain (_libc_intl_domainname);

  function = NONE;
  portnum = 0;
  errflg = 0;
  while ((c = getopt (argc, argv, "ptubdn:")) != -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 '?':
         errflg = 1;
       }
    }

  if (errflg || function == NONE)
    {
      usage ();
      return 1;
    }

  switch (function)
    {

    case PMAPDUMP:
      if (portnum != 0)
       {
         usage ();
         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 ();
         return 1;
       }
      brdcst (argc - optind, argv + optind);
      break;

    case DELETES:
      deletereg (argc - optind, argv + optind);
      break;
    }

  return 0;
}

Here is the call graph for this function:

static void pmapdump ( int  argc,
char **  argv 
) [static]

Definition at line 521 of file rpcinfo.c.

{
  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 ();
      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");
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pstatus ( CLIENT client,
u_long  prognum,
u_long  vers 
) [static]

Definition at line 499 of file rpcinfo.c.

{
  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;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool_t reply_proc ( void *  res,
struct sockaddr_in who 
) [static]

Definition at line 604 of file rpcinfo.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void tcpping ( u_short  portflag,
int  argc,
char **  argv 
) [static]

Definition at line 350 of file rpcinfo.c.

{
  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 ();
      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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void udpping ( u_short  portflag,
int  argc,
char **  argv 
) [static]

Definition at line 195 of file rpcinfo.c.

{
  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 ();
      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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void usage ( void  ) [static]

Definition at line 672 of file rpcinfo.c.

{
  fputs (_("Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"),
        stderr);
  fputs (_("       rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"),
        stderr);
  fputs (_("       rpcinfo -p [ host ]\n"), stderr);
  fputs (_("       rpcinfo -b prognum versnum\n"), stderr);
  fputs (_("       rpcinfo -d prognum versnum\n"), stderr);
}

Here is the call graph for this function:

Here is the caller graph for this function: