snoop_mount.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1991, 1999-2000 by Sun Microsystems, Inc.
* All rights reserved.
*/
#ident "%Z%%M% %I% %E% SMI" /* SunOS */
#include <sys/types.h>
#include <sys/errno.h>
#include <setjmp.h>
#include <sys/tiuser.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
#include <rpc/rpc_msg.h>
#include <nfs/nfs.h>
#include <rpcsvc/mount.h>
#include <string.h>
#include "snoop.h"
#include "snoop_nfs.h"
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
extern char *dlc_header;
extern jmp_buf xdr_err;
static void mountcall(int, int);
static void mountreply(int, int);
static void sum_mountstat(char *);
static void sum_mountstat3(char *);
static char *sum_mountfh(void);
static char *sum_mountfh3(void);
static char *sum_exports(void);
static char *sum_mounts(void);
static int detail_mountstat(void);
static void detail_mountstat3(void);
static void detail_mountfh(void);
static void detail_mountfh3(void);
static void detail_exports(void);
static void detail_mounts(void);
static char *statusmsg3(ulong_t);
static char *procnames_short[] = {
"Null", /* 0 */
"Mount", /* 1 */
"Get mount list", /* 2 */
"Unmount", /* 3 */
"Unmountall", /* 4 */
"Get export list", /* 5 */
"Get export list", /* 6 */
"PATHCONF", /* 7 */
};
static char *procnames_long[] = {
"Null procedure", /* 0 */
"Add mount entry", /* 1 */
"Return mount entries", /* 2 */
"Remove mount entry", /* 3 */
"Remove all mount entries", /* 4 */
"Return export list", /* 5 */
"Return export list", /* 6 */
"Get POSIX Pathconf info", /* 7 */
};
#define MAXPROC 7
void
interpret_mount(flags, type, xid, vers, proc, data, len)
int flags, type, xid, vers, proc;
char *data;
int len;
{
char *line;
char buff[MNTPATHLEN + 1];
if (proc < 0 || proc > MAXPROC)
return;
if (flags & F_SUM) {
if (setjmp(xdr_err)) {
return;
}
line = get_sum_line();
if (type == CALL) {
(void) sprintf(line, "MOUNT%d C %s",
vers, procnames_short[proc]);
line += strlen(line);
switch (proc) {
case MOUNTPROC_MNT:
case MOUNTPROC_UMNT:
(void) sprintf(line, " %s",
getxdr_string(buff, MNTPATHLEN));
break;
case MOUNTPROC_DUMP:
case MOUNTPROC_UMNTALL:
case MOUNTPROC_EXPORT:
case MOUNTPROC_EXPORTALL:
#ifdef MOUNTPROC_PATHCONF
case MOUNTPROC_PATHCONF:
if (vers != 3)
(void) sprintf(line, " %s",
getxdr_string(buff,
MNTPATHLEN));
#endif
break;
default:
break;
}
check_retransmit(line, xid);
} else {
(void) sprintf(line, "MOUNT%d R %s ",
vers, procnames_short[proc]);
line += strlen(line);
switch (proc) {
case MOUNTPROC_MNT:
if (vers == 3)
sum_mountstat3(line);
else
sum_mountstat(line);
break;
case MOUNTPROC_DUMP:
(void) sprintf(line, sum_mounts());
break;
case MOUNTPROC_UMNT:
case MOUNTPROC_UMNTALL:
(void) sprintf(line, "reply");
break;
case MOUNTPROC_EXPORTALL:
/*
* EXPORTALL is the same as EXPORT in v1
* and v2, and it doesn't exist in v3.
*/
if (vers == 3)
break;
/*FALLTHROUGH*/
case MOUNTPROC_EXPORT:
(void) sprintf(line, sum_exports());
break;
#ifdef MOUNTPROC_PATHCONF
case MOUNTPROC_PATHCONF:
if (vers != 2)
break;
#ifdef notyet
(void) sprintf(line, sum_ppathcnf());
#endif
break;
#endif
default:
break;
}
}
}
if (flags & F_DTAIL) {
show_header("MOUNT:", "NFS MOUNT", len);
show_space();
if (setjmp(xdr_err)) {
return;
}
(void) sprintf(get_line(0, 0),
"Proc = %d (%s)",
proc, procnames_long[proc]);
if (type == CALL)
mountcall(proc, vers);
else
mountreply(proc, vers);
show_trailer();
}
}
/*
* Interpret call packets in detail
*/
static void
mountcall(proc, vers)
int proc, vers;
{
switch (proc) {
case MOUNTPROC_MNT:
case MOUNTPROC_UMNT:
(void) showxdr_string(MNTPATHLEN, "Directory = %s");
break;
case MOUNTPROC_DUMP:
break;
case MOUNTPROC_UMNTALL:
break;
case MOUNTPROC_EXPORTALL:
if (vers == 3)
break;
break;
case MOUNTPROC_EXPORT:
break;
#ifdef MOUNTPROC_PATHCONF
case MOUNTPROC_PATHCONF:
if (vers != 2)
break;
(void) showxdr_string(MNTPATHLEN, "File = %s");
#endif
break;
default:
break;
}
}
/*
* Interpret reply packets in detail
*/
static void
mountreply(proc, vers)
int proc, vers;
{
switch (proc) {
case MOUNTPROC_MNT:
if (vers == 3) {
detail_mountstat3();
} else {
if (detail_mountstat() == 0) {
detail_mountfh();
}
}
break;
case MOUNTPROC_DUMP:
detail_mounts();
break;
case MOUNTPROC_UMNT:
case MOUNTPROC_UMNTALL:
(void) detail_mountstat();
break;
case MOUNTPROC_EXPORTALL:
if (vers == 3)
break;
/*FALLTHROUGH*/
case MOUNTPROC_EXPORT:
detail_exports();
break;
#ifdef MOUNTPROC_PATHCONF
case MOUNTPROC_PATHCONF:
#ifdef notyet
(void) detail_ppathcnf();
#endif
break;
#endif
default:
break;
}
}
static void
sum_mountstat(line)
char *line;
{
ulong_t status;
char *str;
status = getxdr_u_long();
if (status == 0)
str = "OK";
else if ((str = strerror(status)) == (char *)NULL)
str = "";
(void) strcpy(line, str);
if (status == 0) {
(void) strcat(line, sum_mountfh());
}
}
static int
detail_mountstat()
{
ulong_t status;
char *str;
status = getxdr_u_long();
if (status == 0)
str = "OK";
else if ((str = strerror(status)) == (char *)NULL)
str = "";
(void) sprintf(get_line(0, 0), "Status = %d (%s)", status, str);
return ((int)status);
}
char *
sum_mountfh()
{
int fh;
static char buff[8];
fh = sum_filehandle(NFS_FHSIZE);
(void) sprintf(buff, " FH=%04X", fh & 0xFFFF);
return (buff);
}
static void
detail_mountfh()
{
int pos;
int fh;
pos = getxdr_pos();
fh = sum_filehandle(NFS_FHSIZE);
setxdr_pos(pos);
(void) sprintf(get_line(0, 0), "File handle = [%04X]", fh & 0xFFFF);
(void) showxdr_hex(NFS_FHSIZE, " %s");
}
static char *
print_auth()
{
int i, auth, flavors;
char *p;
static char buff[64];
buff[0] = '\0';
flavors = getxdr_long();
for (i = 0; i < flavors; i++) {
if (i > 0)
(void) strlcat(buff, ",", sizeof (buff));
switch (auth = getxdr_u_long()) {
case AUTH_NONE:
(void) strlcat(buff, "none", sizeof (buff));
break;
case AUTH_UNIX:
(void) strlcat(buff, "unix", sizeof (buff));
break;
case AUTH_SHORT:
(void) strlcat(buff, "short", sizeof (buff));
break;
case AUTH_DES:
(void) strlcat(buff, "des", sizeof (buff));
break;
default:
p = buff + strlen(buff);
if (p < &buff[sizeof (buff)])
(void) snprintf(p, sizeof (buff) - strlen(buff),
"%d", auth);
break;
}
}
return (buff);
}
static void
sum_mountstat3(line)
char *line;
{
ulong_t status;
status = getxdr_u_long();
(void) strcpy(line, statusmsg3(status));
if (status == 0) {
(void) strcat(line, sum_mountfh3());
(void) strcat(line, " Auth=");
(void) strcat(line, print_auth());
}
}
static void
detail_mountstat3()
{
ulong_t status;
status = getxdr_u_long();
(void) sprintf(get_line(0, 0), "Status = %d (%s)", status,
statusmsg3(status));
if (status == 0) {
detail_mountfh3();
(void) sprintf(get_line(0, 0), "Authentication flavor = %s",
print_auth());
}
}
char *
sum_mountfh3()
{
int len;
int fh;
static char buff[8];
len = getxdr_long();
fh = sum_filehandle(len);
(void) sprintf(buff, " FH=%04X", fh & 0xFFFF);
return (buff);
}
static void
detail_mountfh3()
{
int pos;
int i, l, len;
int fh;
len = getxdr_long();
pos = getxdr_pos();
fh = sum_filehandle(len);
setxdr_pos(pos);
(void) sprintf(get_line(0, 0), "File handle = [%04X]", fh & 0xFFFF);
i = 0;
while (i < len) {
l = MIN(len - i, 32);
(void) showxdr_hex(l, " %s");
i += l;
}
}
static char *
sum_exports()
{
static char buff[MNTPATHLEN + 1];
int entries = 0;
if (setjmp(xdr_err)) {
(void) sprintf(buff, "%d+ entries", entries);
return (buff);
}
while (getxdr_long()) {
(void) getxdr_string(buff, MNTPATHLEN);
while (getxdr_long()) {
(void) getxdr_string(buff, MNTNAMLEN);
}
entries++;
}
(void) sprintf(buff, "%d entries", entries);
return (buff);
}
static void
detail_exports()
{
int entries = 0;
char *dirpath, *grpname;
char buff[MNTPATHLEN + 1];
if (setjmp(xdr_err)) {
(void) sprintf(get_line(0, 0),
" %d+ entries. (Frame is incomplete)",
entries);
return;
}
while (getxdr_long()) {
dirpath = (char *)getxdr_string(buff, MNTPATHLEN);
(void) sprintf(get_line(0, 0), "Directory = %s", dirpath);
entries++;
while (getxdr_long()) {
grpname = (char *)getxdr_string(buff, MNTNAMLEN);
(void) sprintf(get_line(0, 0), " Group = %s", grpname);
}
}
}
static char *
sum_mounts()
{
int entries = 0;
static char buff[MNTPATHLEN + 1];
if (setjmp(xdr_err)) {
(void) sprintf(buff, "%d+ entries", entries);
return (buff);
}
while (getxdr_long()) {
(void) getxdr_string(buff, MNTNAMLEN);
(void) getxdr_string(buff, MNTPATHLEN);
entries++;
}
(void) sprintf(buff, "%d entries", entries);
return (buff);
}
static void
detail_mounts()
{
int entries = 0;
char *hostname, *directory;
char buff1[MNTNAMLEN + 1], buff2[MNTPATHLEN + 1];
if (setjmp(xdr_err)) {
(void) sprintf(get_line(0, 0),
" %d+ entries. (Frame is incomplete)",
entries);
return;
}
(void) sprintf(get_line(0, 0), "Mount list");
while (getxdr_long()) {
hostname = (char *)getxdr_string(buff1, MNTNAMLEN);
directory = (char *)getxdr_string(buff2, MNTPATHLEN);
(void) sprintf(get_line(0, 0), " %s:%s", hostname, directory);
entries++;
}
}
char *
statusmsg3(status)
ulong_t status;
{
switch (status) {
case MNT_OK:
return ("OK");
case MNT3ERR_PERM:
return ("Not owner");
case MNT3ERR_NOENT:
return ("No such file or directory");
case MNT3ERR_IO:
return ("I/O error");
case MNT3ERR_ACCES:
return ("Permission denied");
case MNT3ERR_NOTDIR:
return ("Not a directory");
case MNT3ERR_INVAL:
return ("Invalid argument");
case MNT3ERR_NAMETOOLONG:
return ("File name too long");
case MNT3ERR_NOTSUPP:
return ("Operation not supported");
case MNT3ERR_SERVERFAULT:
return ("Server error");
default:
return ("(unknown error)");
}
}