⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 print-nfs.c

📁 Windump3.6.2源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lintstatic const char rcsid[] =    "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.87 2000/10/07 05:53:12 itojun Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifndef WIN32
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#else
#include <winsock2.h>
#include "bittypes.h"
#include "ip6_misc.h"
#include <Rpc/Rpc_cut.h>
#endif /* WIN32 */
struct mbuf;struct rtentry;#ifndef WIN32
#include <netinet/in.h>#include <rpc/rpc.h>#endif /* WIN32 */
#include <ctype.h>#include <pcap.h>#include <stdio.h>#include <string.h>#include "interface.h"#include "addrtoname.h"#include "nfs.h"#include "nfsfh.h"#include "ip.h"#ifdef INET6#ifndef WIN32
#include "ip6.h"#endif /* WIN32 */
#endifstatic void nfs_printfh(const u_int32_t *, const u_int);static void xid_map_enter(const struct rpc_msg *, const u_char *);static int32_t xid_map_find(const struct rpc_msg *, const u_char *,			    u_int32_t *, u_int32_t *);static void interp_reply(const struct rpc_msg *, u_int32_t, u_int32_t, int);static const u_int32_t *parse_post_op_attr(const u_int32_t *, int);static void print_sattr3(const struct nfsv3_sattr *sa3, int verbose);static int print_int64(const u_int32_t *dp, int how);static void print_nfsaddr(const u_char *, const char *, const char *);/* * Mapping of old NFS Version 2 RPC numbers to generic numbers. */u_int32_t nfsv3_procid[NFS_NPROCS] = {	NFSPROC_NULL,	NFSPROC_GETATTR,	NFSPROC_SETATTR,	NFSPROC_NOOP,	NFSPROC_LOOKUP,	NFSPROC_READLINK,	NFSPROC_READ,	NFSPROC_NOOP,	NFSPROC_WRITE,	NFSPROC_CREATE,	NFSPROC_REMOVE,	NFSPROC_RENAME,	NFSPROC_LINK,	NFSPROC_SYMLINK,	NFSPROC_MKDIR,	NFSPROC_RMDIR,	NFSPROC_READDIR,	NFSPROC_FSSTAT,	NFSPROC_NOOP,	NFSPROC_NOOP,	NFSPROC_NOOP,	NFSPROC_NOOP,	NFSPROC_NOOP,	NFSPROC_NOOP,	NFSPROC_NOOP,	NFSPROC_NOOP};/* * NFS V2 and V3 status values. * * Some of these come from the RFCs for NFS V2 and V3, with the message * strings taken from the FreeBSD C library "errlst.c". * * Others are errors that are not in the RFC but that I suspect some * NFS servers could return; the values are FreeBSD errno values, as * the first NFS server was the SunOS 2.0 one, and until 5.0 SunOS * was primarily BSD-derived. */static struct tok status2str[] = {	{ 1,     "Operation not permitted" },	/* EPERM */	{ 2,     "No such file or directory" },	/* ENOENT */	{ 5,     "Input/output error" },	/* EIO */	{ 6,     "Device not configured" },	/* ENXIO */	{ 11,    "Resource deadlock avoided" },	/* EDEADLK */	{ 12,    "Cannot allocate memory" },	/* ENOMEM */	{ 13,    "Permission denied" },		/* EACCES */	{ 17,    "File exists" },		/* EEXIST */	{ 18,    "Cross-device link" },		/* EXDEV */	{ 19,    "Operation not supported by device" }, /* ENODEV */	{ 20,    "Not a directory" },		/* ENOTDIR */	{ 21,    "Is a directory" },		/* EISDIR */	{ 22,    "Invalid argument" },		/* EINVAL */	{ 26,    "Text file busy" },		/* ETXTBSY */	{ 27,    "File too large" },		/* EFBIG */	{ 28,    "No space left on device" },	/* ENOSPC */	{ 30,    "Read-only file system" },	/* EROFS */	{ 31,    "Too many links" },		/* EMLINK */	{ 45,    "Operation not supported" },	/* EOPNOTSUPP */	{ 62,    "Too many levels of symbolic links" }, /* ELOOP */	{ 63,    "File name too long" },	/* ENAMETOOLONG */	{ 66,    "Directory not empty" },	/* ENOTEMPTY */	{ 69,    "Disc quota exceeded" },	/* EDQUOT */	{ 70,    "Stale NFS file handle" },	/* ESTALE */	{ 71,    "Too many levels of remote in path" }, /* EREMOTE */	{ 99,    "Write cache flushed to disk" }, /* NFSERR_WFLUSH (not used) */	{ 10001, "Illegal NFS file handle" },	/* NFS3ERR_BADHANDLE */	{ 10002, "Update synchronization mismatch" }, /* NFS3ERR_NOT_SYNC */	{ 10003, "READDIR/READDIRPLUS cookie is stale" }, /* NFS3ERR_BAD_COOKIE */	{ 10004, "Operation not supported" },	/* NFS3ERR_NOTSUPP */	{ 10005, "Buffer or request is too small" }, /* NFS3ERR_TOOSMALL */	{ 10006, "Unspecified error on server" }, /* NFS3ERR_SERVERFAULT */	{ 10007, "Object of that type not supported" }, /* NFS3ERR_BADTYPE */	{ 10008, "Request couldn't be completed in time" }, /* NFS3ERR_JUKEBOX */	{ 0,     NULL }};static struct tok nfsv3_writemodes[] = {	{ 0,		"unstable" },	{ 1,		"datasync" },	{ 2,		"filesync" },	{ 0,		NULL }};static struct tok type2str[] = {	{ NFNON,	"NON" },	{ NFREG,	"REG" },	{ NFDIR,	"DIR" },	{ NFBLK,	"BLK" },	{ NFCHR,	"CHR" },	{ NFLNK,	"LNK" },	{ NFFIFO,	"FIFO" },	{ 0,		NULL }};/* * Print out a 64-bit integer. This appears to be different on each system, * try to make the best of it. The integer stored as 2 consecutive XDR * encoded 32-bit integers, to which a pointer is passed. * * Assume that a system that has INT64_FORMAT defined, has a 64-bit * integer datatype and can print it. */ #define UNSIGNED 0#define SIGNED   1#define HEX      2static int print_int64(const u_int32_t *dp, int how){#ifdef INT64_FORMAT	u_int64_t res;	res = ((u_int64_t)ntohl(dp[0]) << 32) | (u_int64_t)ntohl(dp[1]);	switch (how) {	case SIGNED:		printf(INT64_FORMAT, res);		break;	case UNSIGNED:		printf(U_INT64_FORMAT, res);		break;	case HEX:		printf(HEX_INT64_FORMAT, res);		break;	default:		return (0);	}#else	switch (how) {	case SIGNED:	case UNSIGNED:	case HEX:		printf("0x%x%08x", (u_int32_t)ntohl(dp[0]),		    (u_int32_t)ntohl(dp[1]));		break;	default:		return (0);	}#endif	return 1;}static voidprint_nfsaddr(const u_char *bp, const char *s, const char *d){	struct ip *ip;#ifdef INET6	struct ip6_hdr *ip6;	char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN];#else#ifndef INET_ADDRSTRLEN#define INET_ADDRSTRLEN	16#endif	char srcaddr[INET_ADDRSTRLEN], dstaddr[INET_ADDRSTRLEN];#endif	srcaddr[0] = dstaddr[0] = '\0';	switch (IP_V((struct ip *)bp)) {	case 4:		ip = (struct ip *)bp;		strlcpy(srcaddr, ipaddr_string(&ip->ip_src), sizeof(srcaddr));		strlcpy(dstaddr, ipaddr_string(&ip->ip_dst), sizeof(dstaddr));		break;#ifdef INET6	case 6:		ip6 = (struct ip6_hdr *)bp;		strlcpy(srcaddr, ip6addr_string(&ip6->ip6_src),		    sizeof(srcaddr));		strlcpy(dstaddr, ip6addr_string(&ip6->ip6_dst),		    sizeof(dstaddr));		break;#endif	default:		strlcpy(srcaddr, "?", sizeof(srcaddr));		strlcpy(dstaddr, "?", sizeof(dstaddr));		break;	}	(void)printf("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d);}static const u_int32_t *parse_sattr3(const u_int32_t *dp, struct nfsv3_sattr *sa3){	TCHECK(dp[0]);	if ((sa3->sa_modeset = ntohl(*dp++))) {		TCHECK(dp[0]);		sa3->sa_mode = ntohl(*dp++);	}	TCHECK(dp[0]);	if ((sa3->sa_uidset = ntohl(*dp++))) {		TCHECK(dp[0]);		sa3->sa_uid = ntohl(*dp++);	}	TCHECK(dp[0]);	if ((sa3->sa_gidset = ntohl(*dp++))) {		TCHECK(dp[0]);		sa3->sa_gid = ntohl(*dp++);	}	TCHECK(dp[0]);	if ((sa3->sa_sizeset = ntohl(*dp++))) {		TCHECK(dp[0]);		sa3->sa_size = ntohl(*dp++);	}	TCHECK(dp[0]);	if ((sa3->sa_atimetype = ntohl(*dp++)) == NFSV3SATTRTIME_TOCLIENT) {		TCHECK(dp[1]);		sa3->sa_atime.nfsv3_sec = ntohl(*dp++);		sa3->sa_atime.nfsv3_nsec = ntohl(*dp++);	}	TCHECK(dp[0]);	if ((sa3->sa_mtimetype = ntohl(*dp++)) == NFSV3SATTRTIME_TOCLIENT) {		TCHECK(dp[1]);		sa3->sa_mtime.nfsv3_sec = ntohl(*dp++);		sa3->sa_mtime.nfsv3_nsec = ntohl(*dp++);	}	return dp;trunc:	return NULL;}static int nfserr;		/* true if we error rather than trunc */static voidprint_sattr3(const struct nfsv3_sattr *sa3, int verbose){	if (sa3->sa_modeset)		printf(" mode %o", sa3->sa_mode);	if (sa3->sa_uidset)		printf(" uid %u", sa3->sa_uid);	if (sa3->sa_gidset)		printf(" gid %u", sa3->sa_gid);	if (verbose > 1) {		if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT)			printf(" atime %u.%06u", sa3->sa_atime.nfsv3_sec,			       sa3->sa_atime.nfsv3_nsec);		if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT)			printf(" mtime %u.%06u", sa3->sa_mtime.nfsv3_sec,			       sa3->sa_mtime.nfsv3_nsec);	}}voidnfsreply_print(register const u_char *bp, u_int length,	       register const u_char *bp2){	register const struct rpc_msg *rp;	u_int32_t proc, vers;	char srcid[20], dstid[20];	/*fits 32bit*/	nfserr = 0;		/* assume no error */	rp = (const struct rpc_msg *)bp;	if (!nflag) {		strlcpy(srcid, "nfs", sizeof(srcid));		snprintf(dstid, sizeof(dstid), "%u",		    (u_int32_t)ntohl(rp->rm_xid));	} else {		snprintf(srcid, sizeof(srcid), "%u", NFS_PORT);		snprintf(dstid, sizeof(dstid), "%u",		    (u_int32_t)ntohl(rp->rm_xid));	}	print_nfsaddr(bp2, srcid, dstid);	(void)printf("reply %s %d",		     ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?			     "ok":"ERR",			     length);	if (xid_map_find(rp, bp2, &proc, &vers) >= 0)		interp_reply(rp, proc, vers, length);}/* * Return a pointer to the first file handle in the packet. * If the packet was truncated, return 0. */static const u_int32_t *parsereq(register const struct rpc_msg *rp, register u_int length){	register const u_int32_t *dp;	register u_int len;	/*	 * find the start of the req data (if we captured it)	 */	dp = (u_int32_t *)&rp->rm_call.cb_cred;	TCHECK(dp[1]);	len = ntohl(dp[1]);	if (len < length) {		dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp);		TCHECK(dp[1]);		len = ntohl(dp[1]);		if (len < length) {			dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp);			TCHECK2(dp[0], 0);			return (dp);		}	}trunc:	return (NULL);}/* * Print out an NFS file handle and return a pointer to following word. * If packet was truncated, return 0. */static const u_int32_t *parsefh(register const u_int32_t *dp, int v3){	int len;	if (v3) {		TCHECK(dp[0]);		len = (int)ntohl(*dp) / 4;		dp++;	} else		len = NFSX_V2FH / 4;	if (TTEST2(*dp, len * sizeof(*dp))) {		nfs_printfh(dp, len);		return (dp + len);	}trunc:	return (NULL);}/* * Print out a file name and return pointer to 32-bit word past it. * If packet was truncated, return 0. */static const u_int32_t *parsefn(register const u_int32_t *dp){	register u_int32_t len;	register const u_char *cp;	/* Bail if we don't have the string length */	TCHECK(*dp);	/* Fetch string length; convert to host order */	len = *dp++;	NTOHL(len);	TCHECK2(*dp, ((len + 3) & ~3));	cp = (u_char *)dp;	/* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */	dp += ((len + 3) & ~3) / sizeof(*dp);	/* XXX seems like we should be checking the length */	putchar('"');	(void) fn_printn(cp, len, NULL);	putchar('"');	return (dp);trunc:	return NULL;}/* * Print out file handle and file name. * Return pointer to 32-bit word past file name. * If packet was truncated (or there was some other error), return 0. */static const u_int32_t *parsefhn(register const u_int32_t *dp, int v3){	dp = parsefh(dp, v3);	if (dp == NULL)		return (NULL);	putchar(' ');	return (parsefn(dp));}voidnfsreq_print(register const u_char *bp, u_int length,    register const u_char *bp2){	register const struct rpc_msg *rp;	register const u_int32_t *dp;	nfs_type type;	int v3;	u_int32_t proc;	struct nfsv3_sattr sa3;	char srcid[20], dstid[20];	/*fits 32bit*/	nfserr = 0;		/* assume no error */	rp = (const struct rpc_msg *)bp;	if (!nflag) {		snprintf(srcid, sizeof(srcid), "%u",		    (u_int32_t)ntohl(rp->rm_xid));		strlcpy(dstid, "nfs", sizeof(dstid));	} else {		snprintf(srcid, sizeof(srcid), "%u",		    (u_int32_t)ntohl(rp->rm_xid));		snprintf(dstid, sizeof(dstid), "%u", NFS_PORT);	}	print_nfsaddr(bp2, srcid, dstid);	(void)printf("%d", length);	xid_map_enter(rp, bp2);	/* record proc number for later on */	v3 = (ntohl(rp->rm_call.cb_vers) == NFS_VER3);	proc = ntohl(rp->rm_call.cb_proc);	if (!v3 && proc < NFS_NPROCS)		proc =  nfsv3_procid[proc];	switch (proc) {	case NFSPROC_NOOP:		printf(" nop");		return;	case NFSPROC_NULL:		printf(" null");		return;	case NFSPROC_GETATTR:		printf(" getattr");		if ((dp = parsereq(rp, length)) != NULL &&		    parsefh(dp, v3) != NULL)			return;		break;	case NFSPROC_SETATTR:		printf(" setattr");		if ((dp = parsereq(rp, length)) != NULL &&		    parsefh(dp, v3) != NULL)			return;		break;	case NFSPROC_LOOKUP:		printf(" lookup");		if ((dp = parsereq(rp, length)) != NULL &&		    parsefhn(dp, v3) != NULL)			return;		break;	case NFSPROC_ACCESS:		printf(" access");		if ((dp = parsereq(rp, length)) != NULL &&		    (dp = parsefh(dp, v3)) != NULL) {			TCHECK(dp[0]);			printf(" %04x", (u_int32_t)ntohl(dp[0]));			return;		}		break;	case NFSPROC_READLINK:		printf(" readlink");		if ((dp = parsereq(rp, length)) != NULL &&		    parsefh(dp, v3) != NULL)			return;		break;	case NFSPROC_READ:		printf(" read");		if ((dp = parsereq(rp, length)) != NULL &&		    (dp = parsefh(dp, v3)) != NULL) {			if (v3) {				TCHECK(dp[2]);				printf(" %u bytes @ ",				       (u_int32_t) ntohl(dp[2]));				print_int64(dp, UNSIGNED);			} else {				TCHECK(dp[1]);				printf(" %u bytes @ %u",				    (u_int32_t)ntohl(dp[1]),				    (u_int32_t)ntohl(dp[0]));			}			return;		}		break;	case NFSPROC_WRITE:		printf(" write");		if ((dp = parsereq(rp, length)) != NULL &&		    (dp = parsefh(dp, v3)) != NULL) {			if (v3) {				TCHECK(dp[4]);				printf(" %u bytes @ ",						(u_int32_t) ntohl(dp[4]));				print_int64(dp, UNSIGNED);				if (vflag) {					dp += 3;					TCHECK(dp[0]);					printf(" <%s>",						tok2str(nfsv3_writemodes,							NULL, ntohl(*dp)));				}			} else {				TCHECK(dp[3]);				printf(" %u (%u) bytes @ %u (%u)",						(u_int32_t)ntohl(dp[3]),						(u_int32_t)ntohl(dp[2]),						(u_int32_t)ntohl(dp[1]),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -