Move rpcinfo program over from 1.1.5. Based on original work by J.T. Conklin
in 1.x.
This commit is contained in:
parent
0cc8ddab2b
commit
e99a5be395
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=1900
8
usr.bin/rpcinfo/Makefile
Normal file
8
usr.bin/rpcinfo/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# from: @(#)Makefile 5.2 (Berkeley) 5/11/90
|
||||
# $Id: Makefile,v 1.2 1993/11/10 03:46:45 smace Exp $
|
||||
|
||||
PROG= rpcinfo
|
||||
MAN8 = rpcinfo.8
|
||||
|
||||
|
||||
.include <bsd.prog.mk>
|
166
usr.bin/rpcinfo/rpcinfo.8
Normal file
166
usr.bin/rpcinfo/rpcinfo.8
Normal file
@ -0,0 +1,166 @@
|
||||
.\" from: @(#)rpcinfo.8c 2.2 88/08/03 4.0 RPCSRC; from 1.24 88/02/25 SMI
|
||||
.\" $Id: rpcinfo.8,v 1.1 1993/09/13 23:22:41 jtc Exp $
|
||||
.\"
|
||||
.Dd December 17, 1987
|
||||
.Dt RPCINFO 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rpcinfo
|
||||
.Nd report RPC information
|
||||
.Sh SYNOPSIS
|
||||
.Nm rpcinfo
|
||||
.Fl p
|
||||
.Op Ar host
|
||||
.Nm rpcinfo
|
||||
.Op Fl n Ar portnum
|
||||
.Fl u Ar host
|
||||
.Ar program
|
||||
.Op Ar version
|
||||
.Nm rpcinfo
|
||||
.Op Fl n Ar portnum
|
||||
.Fl t Ar host
|
||||
.Ar program
|
||||
.Op Ar version
|
||||
.Nm rpcinfo
|
||||
.Fl b
|
||||
.Ar program version
|
||||
.Nm rpcinfo
|
||||
.Fl d
|
||||
.Ar program version
|
||||
.Sh DESCRIPTION
|
||||
.Nm rpcinfo
|
||||
makes an
|
||||
.Tn RPC
|
||||
call to an
|
||||
.Tn RPC
|
||||
server and reports what it finds.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width indent
|
||||
.It Fl p
|
||||
Probe the portmapper on
|
||||
.Ar host ,
|
||||
and print a list of all registered
|
||||
.Tn RPC
|
||||
programs. If
|
||||
.Ar host
|
||||
is not specified, it defaults to the value returned by
|
||||
.Xr hostname 1 .
|
||||
.It Fl u
|
||||
Make an
|
||||
.Tn RPC
|
||||
call to procedure 0 of
|
||||
.Ar program
|
||||
on the specified
|
||||
.Ar host
|
||||
using
|
||||
.Tn UDP ,
|
||||
and report whether a response was received.
|
||||
.It Fl t
|
||||
Make an
|
||||
.Tn RPC
|
||||
call to procedure 0 of
|
||||
.Ar program
|
||||
on the specified
|
||||
.Ar host
|
||||
using
|
||||
.Tn TCP ,
|
||||
and report whether a response was received.
|
||||
.It Fl n
|
||||
Use
|
||||
.Ar portnum
|
||||
as the port number for the
|
||||
.Fl t
|
||||
and
|
||||
.Fl u
|
||||
options instead of the port number given by the portmapper.
|
||||
.It Fl b
|
||||
Make an
|
||||
.Tn RPC
|
||||
broadcast to procedure 0 of the specified
|
||||
.Ar program
|
||||
and
|
||||
.Ar version
|
||||
using
|
||||
.Tn UDP
|
||||
and report all hosts that respond.
|
||||
.It Fl d
|
||||
Delete registration for the
|
||||
.Tn RPC
|
||||
service of the specified
|
||||
.Ar program
|
||||
and
|
||||
.Ar version .
|
||||
This option can be exercised only by the super-user.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar program
|
||||
argument can be either a name or a number.
|
||||
.Pp
|
||||
If a
|
||||
.Ar version
|
||||
is specified,
|
||||
.Nm rpcinfo
|
||||
attempts to call that version of the specified
|
||||
.Ar program .
|
||||
Otherwise,
|
||||
.Nm rpcinfo
|
||||
attempts to find all the registered version
|
||||
numbers for the specified
|
||||
.Ar program
|
||||
by calling version 0 (which is presumed not
|
||||
to exist; if it does exist,
|
||||
.Ar rpcinfo
|
||||
attempts to obtain this information by calling
|
||||
an extremely high version
|
||||
number instead) and attempts to call each registered version.
|
||||
Note: the version number is required for
|
||||
.Fl b
|
||||
and
|
||||
.Fl d
|
||||
options.
|
||||
.Sh EXAMPLES
|
||||
To show all of the
|
||||
.Tn RPC
|
||||
services registered on the local machine use:
|
||||
.Pp
|
||||
.Dl example% rpcinfo -p
|
||||
.Pp
|
||||
To show all of the
|
||||
.Tn RPC
|
||||
services registered on the machine named
|
||||
.Ar klaxon
|
||||
use:
|
||||
.Pp
|
||||
.Dl example% rpcinfo -p klaxon
|
||||
.Pp
|
||||
To show all machines on the local net that are running the Yellow Pages
|
||||
service use:
|
||||
.Pp
|
||||
.Dl example% rpcinfo -b ypserv 'version' | uniq
|
||||
.Pp
|
||||
where 'version' is the current Yellow Pages version obtained from the
|
||||
results of the
|
||||
.Fl p
|
||||
switch above.
|
||||
.Pp
|
||||
To delete the registration for version 1 of the
|
||||
.Nm walld
|
||||
service use:
|
||||
.Pp
|
||||
.Dl example% rpcinfo -d walld 1
|
||||
.Sh SEE ALSO
|
||||
.Xr rpc 5 ,
|
||||
.Xr portmap 8
|
||||
.Rs
|
||||
.%T "RPC Programming Guide"
|
||||
.Re
|
||||
.Sh BUGS
|
||||
In releases prior to SunOS 3.0, the Network File System (NFS) did not
|
||||
register itself with the portmapper;
|
||||
.Nm rpcinfo
|
||||
cannot be used to make
|
||||
.Tn RPC
|
||||
calls to the
|
||||
.Tn NFS
|
||||
server on hosts running such releases.
|
666
usr.bin/rpcinfo/rpcinfo.c
Normal file
666
usr.bin/rpcinfo/rpcinfo.c
Normal file
@ -0,0 +1,666 @@
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)rpcinfo.c 1.22 87/08/12 SMI";*/
|
||||
/*static char sccsid[] = "from: @(#)rpcinfo.c 2.2 88/08/11 4.0 RPCSRC";*/
|
||||
static char rcsid[] = "$Id: rpcinfo.c,v 1.1 1993/09/13 23:22:42 jtc Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* rpcinfo: ping a particular rpc program
|
||||
* or dump the portmapper
|
||||
*/
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#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*/);
|
||||
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*/);
|
||||
extern u_long inet_addr(); /* in 4.2BSD, arpa/inet.h called that a in_addr */
|
||||
extern char *inet_ntoa();
|
||||
|
||||
/*
|
||||
* 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(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register int c;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
int errflg;
|
||||
int function;
|
||||
u_short portnum;
|
||||
|
||||
function = NONE;
|
||||
portnum = 0;
|
||||
errflg = 0;
|
||||
while ((c = getopt(argc, argv, "ptubdn:")) != EOF) {
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
udpping(portnum, argc, argv)
|
||||
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();
|
||||
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, xdr_void, (char *)NULL,
|
||||
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, xdr_void,
|
||||
(char *)NULL, 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) {
|
||||
/*
|
||||
* 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, xdr_void,
|
||||
(char *)NULL, xdr_void, (char *)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, xdr_void, (char *)NULL,
|
||||
xdr_void, (char *)NULL, to);
|
||||
if (pstatus(client, prognum, vers) < 0)
|
||||
failure = 1;
|
||||
}
|
||||
(void) close(sock); /* Close it up again */
|
||||
if (failure)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
tcpping(portnum, argc, argv)
|
||||
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();
|
||||
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, xdr_void, (char *)NULL,
|
||||
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);
|
||||
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, xdr_void,
|
||||
(char *)NULL, 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) {
|
||||
/*
|
||||
* 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, xdr_void, (char *)NULL,
|
||||
xdr_void, (char *)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, xdr_void, (char *)NULL,
|
||||
xdr_void, (char *)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(client, prognum, vers)
|
||||
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(argc, argv)
|
||||
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();
|
||||
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)
|
||||
bcopy(hp->h_addr, (caddr_t)&server_addr.sin_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, xdr_void, NULL,
|
||||
xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
|
||||
fprintf(stderr, "rpcinfo: can't contact portmapper: ");
|
||||
clnt_perror(client, "rpcinfo");
|
||||
exit(1);
|
||||
}
|
||||
if (head == NULL) {
|
||||
printf("No remote programs registered.\n");
|
||||
} else {
|
||||
printf(" program vers proto port\n");
|
||||
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(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
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, xdr_void,
|
||||
(char *)NULL, xdr_void, (char *)NULL, 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(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{ u_long prog_num, version_num ;
|
||||
|
||||
if (argc != 2) {
|
||||
usage() ;
|
||||
exit(1) ;
|
||||
}
|
||||
if (getuid()) { /* This command allowed only to root */
|
||||
fprintf(stderr, "Sorry. You are not root\n") ;
|
||||
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()
|
||||
{
|
||||
fprintf(stderr, "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n");
|
||||
fprintf(stderr, " rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n");
|
||||
fprintf(stderr, " rpcinfo -p [ host ]\n");
|
||||
fprintf(stderr, " rpcinfo -b prognum versnum\n");
|
||||
fprintf(stderr, " rpcinfo -d prognum versnum\n") ;
|
||||
}
|
||||
|
||||
static u_long
|
||||
getprognum(arg)
|
||||
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(arg)
|
||||
char *arg;
|
||||
{
|
||||
register u_long vers;
|
||||
|
||||
vers = (int) atoi(arg);
|
||||
return (vers);
|
||||
}
|
||||
|
||||
static void
|
||||
get_inet_address(addr, host)
|
||||
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 == -1 || addr->sin_addr.s_addr == 0) {
|
||||
if ((hp = gethostbyname(host)) == NULL) {
|
||||
fprintf(stderr, "rpcinfo: %s is unknown host\n", host);
|
||||
exit(1);
|
||||
}
|
||||
bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length);
|
||||
}
|
||||
addr->sin_family = AF_INET;
|
||||
}
|
Loading…
Reference in New Issue
Block a user