Files
Arquivotheca.SunOS-4.1.4/usr.etc/etherfind/rpcprint.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

696 lines
16 KiB
C

/*
* This module prints out Sun RPC packets in a verbose form
*
* @(#)rpcprint.c 1.1 94/10/31
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include <sys/types.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <netdb.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
#include <rpc/rpc_msg.h>
#include <rpc/pmap_clnt.h>
#include <rpc/svc.h>
#include <rpcsvc/yp_prot.h>
#include "nfs_prot.h"
extern char *sprintf();
/* define some well-known program numbers */
#define FIRST_RPC_PROG ((u_long)100000)
#define PM_PROG ((u_long)100000)
#define RSTATD_PROG ((u_long)100001)
#define RUSERSD_PROG ((u_long)100002)
#define NFS_PROG ((u_long)100003)
#define YPSERV_PROG ((u_long)100004)
#define MOUNTD_PROG ((u_long)100005)
#define YPBIND_PROG ((u_long)100007)
#define WALLD_PROG ((u_long)100008)
#define YPPASSWD_PROG ((u_long)100009)
#define ETHERSTATD_PROG ((u_long)100010)
#define RQUOTAD_PROG ((u_long)100011)
#define SPRAYD_PROG ((u_long)100012)
#define MAP_3270_PROG ((u_long)100013)
#define RJE_MAPPER_PROG ((u_long)100014)
#define SELECTION_SVC ((u_long)100015)
#define DATABASE_SVC ((u_long)100016)
#define REXD_PROG ((u_long)100017)
#define ALIS_PROG ((u_long)100018)
#define SCHED_PROG ((u_long)100019)
#define LLOCKMGR ((u_long)100020)
#define NLOCKMGR ((u_long)100021)
#define X25_INR ((u_long)100022)
#define STATMON ((u_long)100023)
#define STATUS ((u_long)100024)
#define BOOTPARAMPROG ((u_long)100026)
#define LAST_RPC_PROG ((u_long)100026)
/*
* The number of RPC program names cached in the following table:
*/
#define MAX_RPC_PROG ((u_long)128)
char *prog_names[] = { /* table of RPC program names */
"portmapper", /* 100000 */
"rstatd", /* 100001 */
"rusersd", /* 100002 */
"nfs", /* 100003 */
"ypserv", /* 100004 */
"mountd", /* 100005 */
NULL,
"ypbind", /* 100007 */
" walld ", /* 100008 */
" yppasswdd ", /* 100009 */
" etherstatd ", /* 100010 */
" rquotad ", /* 100011 */
" sprayd ", /* 100012 */
" 3270_mapper ", /* 100013 */
" rje_mapper ", /* 100014 */
" selection_svc ", /* 100015 */
" database_svc ", /* 100016 */
" rexd ", /* 100017 */
" alis ", /* 100018 */
" sched ", /* 100019 */
" llockmgr ", /* 100020 */
" nlockmgr ", /* 100021 */
" x25.inr ", /* 100022 */
" statmon ", /* 100023 */
" status ", /* 100024 */
NULL,
" bootparams " /* 100026 */
};
char *nfs_procs[] = { /* NFS procedure names */
" Null ", /* 0 */
" Getattr ", /* 1 */
" Setattr ", /* 2 */
" Root ", /* 3 */
" Lookup ", /* 4 */
" Read link ", /* 5 */
" Read ", /* 6 */
" Write cache ", /* 7 */
" Write ", /* 8 */
" Create ", /* 9 */
" Remove ", /* 10 */
" Rename ", /* 11 */
" Link ", /* 12 */
" Symlink ", /* 13 */
" Make dir ", /* 14 */
" Remove dir ", /* 15 */
" Read dir ", /* 16 */
" Stat FS ", /* 17 */
" Nproc " /* 18 */
};
char *mount_procs[] = { /* mount procedure names */
" MNTPROC_NULL ", /* 0 */
" MNTPROC_MNT ", /* 1 */
" MNTPROC_DUMP ", /* 2 */
" MNTPROC_UMNT ", /* 3 */
" MNTPROC_UMNTALL ", /* 4 */
" MNTPROC_EXPORT ", /* 5 */
};
char *pm_procs[] = { /* Portmapper procedure names */
" PMAPPROC_NULL ", /* 0 */
" PMAPPROC_SET ", /* 1 */
" PMAPPROC_UNSET ", /* 2 */
" PMAPPROC_GETPORT ", /* 3 */
" PMAPPROC_DUMP ", /* 4 */
" PMAPPROC_CALLIT " /* 5 */
};
char *rs_procs[] = { /* Remote status daemon names */
" RSTATPROC_NULL ", /* 0 */
" RSTATPROC_STATS ", /* 1 */
" RSTATPROC_HAVEDISK " /* 2 */
};
char *yp_procs[] = { /* NIS procedure names */
" NULL ", /* 0 */
" Domain ", /* 1 */
" Domain_NONACK ", /* 2 */
" Match ", /* 3 */
" First ", /* 4 */
" Next ", /* 5 */
" XFR ", /* 6 */
" Clear ", /* 7 */
" All ", /* 8 */
" Master ", /* 9 */
" Order ", /* 10 */
" Map List " /* 11 */
};
char *bootparam_procs[] = { /* Boot Param procedures */
" BOOTPARAMPROC_NULL ", /* 0 */
" BOOTPARAMPROC_WHOAMI ", /* 1 */
" BOOTPARAMPROC_GETFILE " /* 2 */
};
char *accept_stats[] = { /* RPC reply statuses */
" Success ", /* 0 */
" PROG_UNAVAIL ", /* 1 */
" PROG_MISMATCH ", /* 2 */
" PROC_UNAVAIL ", /* 3 */
" GARBAGE_ARGS ", /* 4 */
" SYSTEM_ERR " /* 5 */
};
char *auth_stats[] = { /* RPC authorization statuses */
" auth OK (invalid with rejection) ", /* AUTH_OK=0 */
" bad credentials ", /* AUTH_BADCRED=1 */
" rejected credentials: begin new session ", /* AUTH_REJECTEDCRED=2 */
" bad verifier ", /* AUTH_BADVERF=3 */
" expired verifier ", /* AUTH_REJECTEDVERF=4 */
" security rejection ", /* AUTH_TOOWEAK=5 */
" bad response verifier (local only!) ", /* AUTH_INVALIDRESP=6 */
" unknown rejection " /* AUTH_FAILED=7 */
};
#define XID_CACHE_SIZE 32
struct cache_struct {
int xid_number;
struct timeval xid_time;
} xid_cache[XID_CACHE_SIZE];
struct cache_struct *xid_cache_ptr = &xid_cache[0];
extern int tflag; /* turn on RPC transaction timing */
struct timeval start_time, *tvp;/* globals from ?? */
/*
* Return true if this is a valid RPC packet
*/
valid_rpc(rpc, length)
struct rpc_msg *rpc;
{
XDR xdrm;
int rm_xid;
int rm_direction;
if (length < sizeof(struct rpc_msg))
return (FALSE);
xdrmem_create(&xdrm, rpc, length, XDR_DECODE);
if (!(xdr_int(&xdrm, &rm_xid))) {
return (FALSE);
}
if (!(xdr_int(&xdrm, &rm_direction))) {
return(FALSE);
}
if ((rm_direction != 0) && (rm_direction != 1)) {
return(FALSE);
}
return (TRUE);
}
cached_xid(id)
int id;
{
struct cache_struct *p = xid_cache_ptr;
while (p != &xid_cache[0]) {
if (p->xid_number == id) {
if (tflag) {
tvp->tv_sec =
tvp->tv_sec - p->xid_time.tv_sec
+ start_time.tv_sec;
tvp->tv_usec =
tvp->tv_usec - p->xid_time.tv_usec
+ start_time.tv_usec;
}
return (TRUE);
}
p--;
}
p = &xid_cache[XID_CACHE_SIZE - 1];
while (p != xid_cache_ptr) {
if (p->xid_number == id) {
if (tflag) {
tvp->tv_sec =
tvp->tv_sec - p->xid_time.tv_sec
+ start_time.tv_sec;
tvp->tv_usec =
tvp->tv_usec - p->xid_time.tv_usec
+ start_time.tv_usec;
}
return (TRUE);
}
p--;
}
return (FALSE);
}
valid_nfs(rpc, length)
struct rpc_msg *rpc;
{
XDR xdrm;
int rm_xid;
int rm_direction;
if (length < sizeof(struct rpc_msg))
return (FALSE);
xdrmem_create(&xdrm, rpc, length, XDR_DECODE);
if (!(xdr_int(&xdrm, &rm_xid))) {
display (0, "valid_rpc: can't decode transaction ident\n");
return (FALSE);
}
if (!(xdr_int(&xdrm, &rm_direction))) {
display (0, "valid_rpc: can't decode direction\n");
return(FALSE);
}
if ((rm_direction != 0) && (rm_direction != 1)) {
return(FALSE);
}
if (rpc->rm_call.cb_prog == NFS_PROG) {
xid_cache_ptr->xid_number = rm_xid;
if (tflag) {
xid_cache_ptr->xid_time.tv_sec = tvp->tv_sec;
xid_cache_ptr->xid_time.tv_usec = tvp->tv_usec;
}
if (xid_cache_ptr == &xid_cache[XID_CACHE_SIZE - 1])
xid_cache_ptr = &xid_cache[0];
else
xid_cache_ptr++;
return (TRUE);
}
return (cached_xid (rm_xid));
}
/*
* Returns the string name of the given RPC program number
*/
char *rpc_progname(prog)
u_long prog;
{
static char buf[128];
int index;
struct rpcent *rp, *getrpcbynumber();
index = prog - FIRST_RPC_PROG;
if (index < MAX_RPC_PROG && prog_names[index])
return(prog_names[index]);
rp = NULL;
if (index < MAX_RPC_PROG)
rp = getrpcbynumber(prog);
if (rp) {
prog_names[index] = malloc(strlen(rp->r_name)+1);
if (prog_names[index]) {
strcpy(prog_names[index], rp->r_name);
return(prog_names[index]);
}
}
sprintf(buf, "prog %d", prog);
if (index < MAX_RPC_PROG) {
prog_names[index] = malloc(strlen(buf)+1);
if (prog_names[index])
strcpy(prog_names[index], buf);
}
return(buf);
}
/*
* Returns the string name of the given RPC procedure number
*/
char *rpc_procname(prog, proc)
u_long prog, proc;
{
static char buf[128];
switch (prog)
{
case NFS_PROG:
if (proc <= 18) return(nfs_procs[proc]);
break;
case MOUNTD_PROG:
if (proc <= 5) return(mount_procs[proc]);
break;
case PM_PROG:
if (proc <= 5) return(pm_procs[proc]);
break;
case RSTATD_PROG:
if (proc <= 2) return(rs_procs[proc]);
break;
case YPSERV_PROG:
if (proc <= 12) return(yp_procs[proc]);
break;
case BOOTPARAMPROG:
if (proc <= 2) return(bootparam_procs[proc]);
break;
}
sprintf(buf, "proc %d", proc);
return(buf);
}
static char auth_buf[MAX_AUTH_BYTES];
static char verf_buf[MAX_AUTH_BYTES];
/*
* Print an accepted RPC reply
*/
rpc_printreply(index, msg, xdrp)
int index;
register struct rpc_msg *msg;
XDR *xdrp;
{
enum accept_stat ar_stat;
msg->acpted_rply.ar_verf.oa_base = auth_buf;
if (!(xdr_opaque_auth(xdrp, &msg->acpted_rply.ar_verf))) {
display(index, "Can't decode accepted reply\n");
return;
}
if (!(xdr_enum(xdrp, &msg->acpted_rply.ar_stat))) {
display(index, "Can't decode accepted reply\n");
return;
}
ar_stat = msg->acpted_rply.ar_stat;
display(index," [%x] ", msg->rm_xid);
switch (msg->acpted_rply.ar_verf.oa_flavor)
{
case AUTH_NULL:
display(index,"AUTH_NULL");
break;
case AUTH_UNIX:
display(index,"AUTH_UNIX");
break;
case AUTH_SHORT:
display(index,"AUTH_SHORT");
break;
case AUTH_DES:
display(index,"AUTH_DES");
break;
default:
display(index,"auth %d ", msg->acpted_rply.ar_verf.oa_flavor);
}
if ((u_long ) ar_stat <= (u_long) SYSTEM_ERR)
display(index,accept_stats[(int)ar_stat]);
switch (ar_stat)
{
case SUCCESS:
case PROG_MISMATCH:
case PROG_UNAVAIL:
case PROC_UNAVAIL:
case GARBAGE_ARGS:
case SYSTEM_ERR:
/*
* To be completed
*/
break;
default:
display(index," bad status %d", ar_stat);
}
}
rpcprint( index, p, size )
int index;
char *p;
int size;
{
XDR xdrm;
struct rpc_msg msg;
xdrmem_create(&xdrm, p, size, XDR_DECODE);
if (!(xdr_long(&xdrm, &msg.rm_xid)) ||
!(xdr_long(&xdrm, &msg.rm_direction))) {
/*** Probably just not a real RPC after all ***/
return;
}
switch (msg.rm_direction)
{
case CALL:
if (!(xdr_long(&xdrm, &msg.rm_call.cb_rpcvers)))
return;
if (msg.rm_call.cb_rpcvers != RPC_MSG_VERSION) {
display(index, " bad version %d ", msg.rm_call.cb_rpcvers);
break;
}
msg.rm_call.cb_cred.oa_base = auth_buf;
msg.rm_call.cb_verf.oa_base = verf_buf;
if (!(xdr_long(&xdrm, &msg.rm_call.cb_prog)) ||
!(xdr_long(&xdrm, &msg.rm_call.cb_vers)) ||
!(xdr_long(&xdrm, &msg.rm_call.cb_proc)) ||
!(xdr_opaque_auth(&xdrm, &msg.rm_call.cb_cred)) ||
!(xdr_opaque_auth(&xdrm, &msg.rm_call.cb_verf))) {
display(index, "Can't decode RPC call\n");
break;
}
display(index,"\n RPC Call %s %s V%d [%x]",
rpc_progname(msg.rm_call.cb_prog),
rpc_procname(msg.rm_call.cb_prog, msg.rm_call.cb_proc),
msg.rm_call.cb_vers, msg.rm_xid );
if (msg.rm_call.cb_prog == NFS_PROG)
nfs_print(display, &xdrm, msg.rm_call.cb_proc);
if (msg.rm_call.cb_prog == YPSERV_PROG && msg.rm_call.cb_vers==YPVERS)
yp_print(display, &xdrm, msg.rm_call.cb_proc);
break;
case REPLY:
if (!(xdr_long(&xdrm, &msg.rm_reply.rp_stat))) {
display(index, "can't decode reply\n");
return;
}
display(index,"\n RPC Reply ");
switch (msg.rm_reply.rp_stat)
{
case MSG_ACCEPTED:
rpc_printreply(index, &msg, &xdrm);
break;
case MSG_DENIED:
if (!(xdr_rejected_reply(&xdrm, &msg.rjcted_rply))) {
display(index, "can't decode rejected reply\n");
}
display(index,"denied (low %d hi %d) [%x]",
msg.rjcted_rply.rj_vers.low,
msg.rjcted_rply.rj_vers.high,
msg.rm_xid );
if ((u_long)msg.rjcted_rply.rj_why <= (u_long) AUTH_FAILED)
display(index,auth_stats[msg.rjcted_rply.rj_why]);
break;
default:
display(index,"\tillegal reply status, %d",
msg.rm_reply.rp_stat);
}
break;
default:
/*
* Probably just not an RPC, so quietly ignore it
*/
return;
}
}
char *fh_print(fh)
struct nfs_fh *fh;
{
static char buf[256];
(void) sprintf(buf, "%d.%x", _getlong(fh->data),
_getlong(&(fh->data[12])));
return(buf);
}
nfs_print(index, xdrp, proc)
int index;
XDR *xdrp;
int proc;
{
struct nfs_fh fh;
unsigned value;
char *name;
static char buf[256];
struct sattr sa;
struct fattr fa;
switch (proc)
{
case NFSPROC_NULL:
break;
case NFSPROC_GETATTR:
(void) xdr_nfs_fh(xdrp, &fh);
display(index, " %s", fh_print(&fh));
break;
case NFSPROC_SETATTR:
(void) xdr_nfs_fh(xdrp, &fh);
display(index, " %s", fh_print(&fh));
(void) xdr_sattr(xdrp, &sa);
break;
case NFSPROC_ROOT:
break;
case NFSPROC_LOOKUP:
case NFSPROC_REMOVE:
case NFSPROC_RMDIR:
(void) xdr_nfs_fh(xdrp, &fh);
name = buf;
(void) xdr_filename(xdrp, &name);
display(index, " %s %s", fh_print(&fh), name);
break;
case NFSPROC_READLINK:
(void) xdr_nfs_fh(xdrp, &fh);
display(index, " %s", fh_print(&fh));
break;
case NFSPROC_READ:
(void) xdr_nfs_fh(xdrp, &fh);
display(index, " %s", fh_print(&fh));
(void) xdr_long(xdrp, &value);
display(index, " off=%d,", value);
(void) xdr_long(xdrp, &value);
display(index, " count=%d,", value);
(void) xdr_long(xdrp, &value);
display(index, " total=%d", value);
break;
case NFSPROC_WRITECACHE:
break;
case NFSPROC_WRITE:
(void) xdr_nfs_fh(xdrp, &fh);
display(index, " %s", fh_print(&fh));
(void) xdr_long(xdrp, &value);
display(index, " begin=%d,", value);
(void) xdr_long(xdrp, &value);
display(index, " off=%d,", value);
(void) xdr_long(xdrp, &value);
display(index, " total=%d", value);
(void) xdr_long(xdrp, &value);
display(index, " count=%d", value);
break;
case NFSPROC_CREATE:
case NFSPROC_MKDIR:
(void) xdr_nfs_fh(xdrp, &fh);
name = buf;
(void) xdr_filename(xdrp, &name);
display(index, " %s %s", fh_print(&fh), name);
break;
case NFSPROC_RENAME:
(void) xdr_nfs_fh(xdrp, &fh);
name = buf;
(void) xdr_filename(xdrp, &name);
display(index, " %s %s", fh_print(&fh), name);
(void) xdr_nfs_fh(xdrp, &fh);
name = buf;
(void) xdr_filename(xdrp, &name);
display(index, " to %s %s", fh_print(&fh), name);
break;
case NFSPROC_LINK:
(void) xdr_nfs_fh(xdrp, &fh);
display(index, " %s", fh_print(&fh));
(void) xdr_nfs_fh(xdrp, &fh);
name = buf;
(void) xdr_filename(xdrp, &name);
display(index, " to %s %s", fh_print(&fh), name);
break;
case NFSPROC_SYMLINK:
(void) xdr_nfs_fh(xdrp, &fh);
name = buf;
(void) xdr_filename(xdrp, &name);
display(index, " from %s %s", fh_print(&fh), name);
name = buf;
(void) xdr_filename(xdrp, &name);
display(index, " to %s", name);
(void) xdr_sattr(xdrp, &sa);
break;
case NFSPROC_READDIR:
(void) xdr_nfs_fh(xdrp, &fh);
display(index, " %s", fh_print(&fh));
(void) xdr_long(xdrp, &value);
display(index, " cookie=%d", value);
(void) xdr_long(xdrp, &value);
display(index, " count=%d", value);
break;
case NFSPROC_STATFS:
(void) xdr_nfs_fh(xdrp, &fh);
display(index, " %s", fh_print(&fh));
break;
}
}
yp_print(index, xdrp, proc)
int index;
XDR *xdrp;
int proc;
{
unsigned value;
char *name;
static char dom[256], map[256], key[256];
struct ypreq_key ypk;
struct ypreq_nokey ypnk;
switch (proc)
{
case YPPROC_NULL:
break;
case YPPROC_DOMAIN:
case YPPROC_DOMAIN_NONACK:
case YPPROC_MAPLIST:
(void) xdr_ypdomain_wrap_string(xdrp, dom);
display(index, " %s", dom);
break;
case YPPROC_MATCH:
case YPPROC_NEXT:
ypk.domain = dom;
ypk.map = map;
ypk.keydat.dptr = key;
(void) xdr_ypreq_key(xdrp, &ypk);
key[ypk.keydat.dsize] = '\0';
display(index, " domain %s map %s key len %d %s",
dom, map, ypk.keydat.dsize, key);
break;
case YPPROC_FIRST:
case YPPROC_ALL:
case YPPROC_MASTER:
case YPPROC_ORDER:
ypnk.domain = dom;
ypnk.map = map;
(void) xdr_ypreq_nokey(xdrp, &ypnk);
key[ypk.keydat.dsize] = '\0';
display(index, " domain %s map %s", dom, map);
break;
}
}