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

📄 print-nfs.c

📁 Windump3.6.2源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
						(u_int32_t)ntohl(dp[0]));			}			return;		}		break;	case NFSPROC_CREATE:		printf(" create");		if ((dp = parsereq(rp, length)) != NULL &&		    parsefhn(dp, v3) != NULL)			return;		break;	case NFSPROC_MKDIR:		printf(" mkdir");		if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp, v3) != 0)			return;		break;	case NFSPROC_SYMLINK:		printf(" symlink");		if ((dp = parsereq(rp, length)) != 0 &&		    (dp = parsefhn(dp, v3)) != 0) {			fputs(" ->", stdout);			if (v3 && (dp = parse_sattr3(dp, &sa3)) == 0)				break;			if (parsefn(dp) == 0)				break;			if (v3 && vflag)				print_sattr3(&sa3, vflag);			return;		}		break;	case NFSPROC_MKNOD:		printf(" mknod");		if ((dp = parsereq(rp, length)) != 0 &&		    (dp = parsefhn(dp, v3)) != 0) {			TCHECK(*dp);			type = (nfs_type)ntohl(*dp++);			if ((dp = parse_sattr3(dp, &sa3)) == 0)				break;			printf(" %s", tok2str(type2str, "unk-ft %d", type));			if (vflag && (type == NFCHR || type == NFBLK)) {				TCHECK(dp[1]);				printf(" %u/%u",				       (u_int32_t)ntohl(dp[0]),				       (u_int32_t)ntohl(dp[1]));				dp += 2;			}			if (vflag)				print_sattr3(&sa3, vflag);			return;		}		break;	case NFSPROC_REMOVE:		printf(" remove");		if ((dp = parsereq(rp, length)) != NULL &&		    parsefhn(dp, v3) != NULL)			return;		break;	case NFSPROC_RMDIR:		printf(" rmdir");		if ((dp = parsereq(rp, length)) != NULL &&		    parsefhn(dp, v3) != NULL)			return;		break;	case NFSPROC_RENAME:		printf(" rename");		if ((dp = parsereq(rp, length)) != NULL &&		    (dp = parsefhn(dp, v3)) != NULL) {			fputs(" ->", stdout);			if (parsefhn(dp, v3) != NULL)				return;		}		break;	case NFSPROC_LINK:		printf(" link");		if ((dp = parsereq(rp, length)) != NULL &&		    (dp = parsefh(dp, v3)) != NULL) {			fputs(" ->", stdout);			if (parsefhn(dp, v3) != NULL)				return;		}		break;	case NFSPROC_READDIR:		printf(" readdir");		if ((dp = parsereq(rp, length)) != NULL &&		    (dp = parsefh(dp, v3)) != NULL) {			if (v3) {				TCHECK(dp[4]);				/*				 * We shouldn't really try to interpret the				 * offset cookie here.				 */				printf(" %u bytes @ ",				    (u_int32_t) ntohl(dp[4]));				print_int64(dp, SIGNED);				if (vflag)					printf(" verf %08x%08x", dp[2],					       dp[3]);			} else {				TCHECK(dp[1]);				/*				 * Print the offset as signed, since -1 is				 * common, but offsets > 2^31 aren't.				 */				printf(" %u bytes @ %d",				    (u_int32_t)ntohl(dp[1]),				    (u_int32_t)ntohl(dp[0]));			}			return;		}		break;	case NFSPROC_READDIRPLUS:		printf(" readdirplus");		if ((dp = parsereq(rp, length)) != NULL &&		    (dp = parsefh(dp, v3)) != NULL) {			TCHECK(dp[4]);			/*			 * We don't try to interpret the offset			 * cookie here.			 */			printf(" %u bytes @ ", (u_int32_t) ntohl(dp[4]));			print_int64(dp, SIGNED);			if (vflag)				printf(" max %u verf %08x%08x",				       (u_int32_t) ntohl(dp[5]), dp[2], dp[3]);			return;		}		break;	case NFSPROC_FSSTAT:		printf(" fsstat");		if ((dp = parsereq(rp, length)) != NULL &&		    parsefh(dp, v3) != NULL)			return;		break;	case NFSPROC_FSINFO:		printf(" fsinfo");		break;	case NFSPROC_PATHCONF:		printf(" pathconf");		break;	case NFSPROC_COMMIT:		printf(" commit");		if ((dp = parsereq(rp, length)) != NULL &&		    (dp = parsefh(dp, v3)) != NULL) {			printf(" %u bytes @ ", (u_int32_t) ntohl(dp[2]));			print_int64(dp, UNSIGNED);			return;		}		break;	default:		printf(" proc-%u", (u_int32_t)ntohl(rp->rm_call.cb_proc));		return;	}trunc:	if (!nfserr)		fputs(" [|nfs]", stdout);}/* * Print out an NFS file handle. * We assume packet was not truncated before the end of the * file handle pointed to by dp. * * Note: new version (using portable file-handle parser) doesn't produce * generation number.  It probably could be made to do that, with some * additional hacking on the parser code. */static voidnfs_printfh(register const u_int32_t *dp, const u_int len){	my_fsid fsid;	ino_t ino;	char *sfsname = NULL;	Parse_fh((caddr_t*)dp, len, &fsid, &ino, NULL, &sfsname, 0);	if (sfsname) {		/* file system ID is ASCII, not numeric, for this server OS */		static char temp[NFSX_V3FHMAX+1];		/* Make sure string is null-terminated */		strncpy(temp, sfsname, NFSX_V3FHMAX);		temp[sizeof(temp) - 1] = '\0';		/* Remove trailing spaces */		sfsname = strchr(temp, ' ');		if (sfsname)			*sfsname = 0;		(void)printf(" fh %s/", temp);	} else {		(void)printf(" fh %d,%d/",			     fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor);	}	if(fsid.Fsid_dev.Minor == 257 && uflag)		/* Print the undecoded handle */ 		(void)printf("%s", fsid.Opaque_Handle);	else		(void)printf("%ld", (long) ino);}/* * Maintain a small cache of recent client.XID.server/proc pairs, to allow * us to match up replies with requests and thus to know how to parse * the reply. */struct xid_map_entry {	u_int32_t	xid;		/* transaction ID (net order) */	int ipver;			/* IP version (4 or 6) */#ifdef INET6	struct in6_addr	client;		/* client IP address (net order) */	struct in6_addr	server;		/* server IP address (net order) */#else	struct in_addr	client;		/* client IP address (net order) */	struct in_addr	server;		/* server IP address (net order) */#endif	u_int32_t	proc;		/* call proc number (host order) */	u_int32_t	vers;		/* program version (host order) */};/* * Map entries are kept in an array that we manage as a ring; * new entries are always added at the tail of the ring.  Initially, * all the entries are zero and hence don't match anything. */#define	XIDMAPSIZE	64struct xid_map_entry xid_map[XIDMAPSIZE];int	xid_map_next = 0;int	xid_map_hint = 0;static voidxid_map_enter(const struct rpc_msg *rp, const u_char *bp){	struct ip *ip = NULL;#ifdef INET6	struct ip6_hdr *ip6 = NULL;#endif	struct xid_map_entry *xmep;	switch (IP_V((struct ip *)bp)) {	case 4:		ip = (struct ip *)bp;		break;#ifdef INET6	case 6:		ip6 = (struct ip6_hdr *)bp;		break;#endif	default:		return;	}	xmep = &xid_map[xid_map_next];	if (++xid_map_next >= XIDMAPSIZE)		xid_map_next = 0;	xmep->xid = rp->rm_xid;	if (ip) {		xmep->ipver = 4;		memcpy(&xmep->client, &ip->ip_src, sizeof(ip->ip_src));		memcpy(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst));	}#ifdef INET6	else if (ip6) {		xmep->ipver = 6;		memcpy(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src));		memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst));	}#endif	xmep->proc = ntohl(rp->rm_call.cb_proc);	xmep->vers = ntohl(rp->rm_call.cb_vers);}/* * Returns 0 and puts NFSPROC_xxx in proc return and * version in vers return, or returns -1 on failure */static intxid_map_find(const struct rpc_msg *rp, const u_char *bp, u_int32_t *proc,	     u_int32_t *vers){	int i;	struct xid_map_entry *xmep;	u_int32_t xid = rp->rm_xid;	struct ip *ip = (struct ip *)bp;#ifdef INET6	struct ip6_hdr *ip6 = (struct ip6_hdr *)bp;#endif	int cmp;	/* Start searching from where we last left off */	i = xid_map_hint; 	do {		xmep = &xid_map[i];		cmp = 1;		if (xmep->ipver != IP_V(ip) || xmep->xid != xid)			goto nextitem;		switch (xmep->ipver) {		case 4:			if (memcmp(&ip->ip_src, &xmep->server,				   sizeof(ip->ip_src)) != 0 ||			    memcmp(&ip->ip_dst, &xmep->client,				   sizeof(ip->ip_dst)) != 0) {				cmp = 0;			}			break;#ifdef INET6		case 6:			if (memcmp(&ip6->ip6_src, &xmep->server,				   sizeof(ip6->ip6_src)) != 0 ||			    memcmp(&ip6->ip6_dst, &xmep->client,				   sizeof(ip6->ip6_dst)) != 0) {				cmp = 0;			}			break;#endif		default:			cmp = 0;			break;		}		if (cmp) {			/* match */			xid_map_hint = i;			*proc = xmep->proc;			*vers = xmep->vers;			return 0;		}	nextitem:		if (++i >= XIDMAPSIZE)			i = 0;	} while (i != xid_map_hint);	/* search failed */	return (-1);}/* * Routines for parsing reply packets *//* * Return a pointer to the beginning of the actual results. * If the packet was truncated, return 0. */static const u_int32_t *parserep(register const struct rpc_msg *rp, register u_int length){	register const u_int32_t *dp;	u_int len;	enum accept_stat astat;	/*	 * Portability note:	 * Here we find the address of the ar_verf credentials.	 * Originally, this calculation was	 *	dp = (u_int32_t *)&rp->rm_reply.rp_acpt.ar_verf	 * On the wire, the rp_acpt field starts immediately after	 * the (32 bit) rp_stat field.  However, rp_acpt (which is a	 * "struct accepted_reply") contains a "struct opaque_auth",	 * whose internal representation contains a pointer, so on a	 * 64-bit machine the compiler inserts 32 bits of padding	 * before rp->rm_reply.rp_acpt.ar_verf.  So, we cannot use	 * the internal representation to parse the on-the-wire	 * representation.  Instead, we skip past the rp_stat field,	 * which is an "enum" and so occupies one 32-bit word.	 */	dp = ((const u_int32_t *)&rp->rm_reply) + 1;	TCHECK(dp[1]);	len = ntohl(dp[1]);	if (len >= length)		return (NULL);	/*	 * skip past the ar_verf credentials.	 */	dp += (len + (2*sizeof(u_int32_t) + 3)) / sizeof(u_int32_t);	TCHECK2(dp[0], 0);	/*	 * now we can check the ar_stat field	 */	astat = ntohl(*(enum accept_stat *)dp);	switch (astat) {	case SUCCESS:		break;	case PROG_UNAVAIL:		printf(" PROG_UNAVAIL");		nfserr = 1;		/* suppress trunc string */		return (NULL);	case PROG_MISMATCH:		printf(" PROG_MISMATCH");		nfserr = 1;		/* suppress trunc string */		return (NULL);	case PROC_UNAVAIL:		printf(" PROC_UNAVAIL");		nfserr = 1;		/* suppress trunc string */		return (NULL);	case GARBAGE_ARGS:		printf(" GARBAGE_ARGS");		nfserr = 1;		/* suppress trunc string */		return (NULL);	case SYSTEM_ERR:		printf(" SYSTEM_ERR");		nfserr = 1;		/* suppress trunc string */		return (NULL);	default:		printf(" ar_stat %d", astat);		nfserr = 1;		/* suppress trunc string */		return (NULL);	}	/* successful return */	TCHECK2(*dp, sizeof(astat));	return ((u_int32_t *) (sizeof(astat) + ((char *)dp)));trunc:	return (0);}static const u_int32_t *parsestatus(const u_int32_t *dp, int *er){	int errnum;	TCHECK(dp[0]);	errnum = ntohl(dp[0]);	if (er)		*er = errnum;	if (errnum != 0) {		if (!qflag)			printf(" ERROR: %s",			    tok2str(status2str, "unk %d", errnum));		nfserr = 1;		return (NULL);	}	return (dp + 1);trunc:	return NULL;}static const u_int32_t *parsefattr(const u_int32_t *dp, int verbose, int v3){	const struct nfs_fattr *fap;	fap = (const struct nfs_fattr *)dp;	TCHECK(fap->fa_gid);	if (verbose) {		printf(" %s %o ids %d/%d",		    tok2str(type2str, "unk-ft %d ",		    (u_int32_t)ntohl(fap->fa_type)),		    (u_int32_t)ntohl(fap->fa_mode),		    (u_int32_t)ntohl(fap->fa_uid),		    (u_int32_t) ntohl(fap->fa_gid));		if (v3) {			TCHECK(fap->fa3_size);			printf(" sz ");			print_int64((u_int32_t *)&fap->fa3_size, UNSIGNED);			putchar(' ');		} else {			TCHECK(fap->fa2_size);			printf(" sz %d ", (u_int32_t) ntohl(fap->fa2_size));		}	}	/* print lots more stuff */	if (verbose > 1) {		if (v3) {			TCHECK(fap->fa3_ctime);			printf("nlink %d rdev %d/%d ",			       (u_int32_t)ntohl(fap->fa_nlink),			       (u_int32_t) ntohl(fap->fa3_rdev.specdata1),			       (u_int32_t) ntohl(fap->fa3_rdev.specdata2));			printf("fsid ");			print_int64((u_int32_t *)&fap->fa2_fsid, HEX);			printf(" nodeid ");			print_int64((u_int32_t *)&fap->fa2_fileid, HEX);			printf(" a/m/ctime %u.%06u ",			       (u_int32_t) ntohl(fap->fa3_atime.nfsv3_sec),			       (u_int32_t) ntohl(fap->fa3_atime.nfsv3_nsec));			printf("%u.%06u ",			       (u_int32_t) ntohl(fap->fa3_mtime.nfsv3_sec),			       (u_int32_t) ntohl(fap->fa3_mtime.nfsv3_nsec));			printf("%u.%06u ",			       (u_int32_t) ntohl(fap->fa3_ctime.nfsv3_sec),			       (u_int32_t) ntohl(fap->fa3_ctime.nfsv3_nsec));		} else {			TCHECK(fap->fa2_ctime);			printf("nlink %d rdev %x fsid %x nodeid %x a/m/ctime ",			       (u_int32_t) ntohl(fap->fa_nlink),			       (u_int32_t) ntohl(fap->fa2_rdev),			       (u_int32_t) ntohl(fap->fa2_fsid),			       (u_int32_t) ntohl(fap->fa2_fileid));			printf("%u.%06u ",			       (u_int32_t) ntohl(fap->fa2_atime.nfsv2_sec),			       (u_int32_t) ntohl(fap->fa2_atime.nfsv2_usec));			printf("%u.%06u ",			       (u_int32_t) ntohl(fap->fa2_mtime.nfsv2_sec),			       (u_int32_t) ntohl(fap->fa2_mtime.nfsv2_usec));			printf("%u.%06u ",			       (u_int32_t) ntohl(fap->fa2_ctime.nfsv2_sec),			       (u_int32_t) ntohl(fap->fa2_ctime.nfsv2_usec));		}	}	return ((const u_int32_t *)((unsigned char *)dp +		(v3 ? NFSX_V3FATTR : NFSX_V2FATTR)));trunc:	return (NULL);}static intparseattrstat(const u_int32_t *dp, int verbose, int v3){	int er;	dp = parsestatus(dp, &er);	if (dp == NULL || er)		return (0);	return (parsefattr(dp, verbose, v3) != NULL);}static intparsediropres(const u_int32_t *dp){	int er;	if (!(dp = parsestatus(dp, &er)) || er)		return (0);	dp = parsefh(dp, 0);	if (dp == NULL)		return (0);	return (parsefattr(dp, vflag, 0) != NULL);}static intparselinkres(const u_int32_t *dp, int v3){	int er;	dp = parsestatus(dp, &er);	if (dp == NULL || er)		return(0);	if (v3 && !(dp = parse_post_op_attr(dp, vflag)))		return (0);	putchar(' ');	return (parsefn(dp) != NULL);}static intparsestatfs(const u_int32_t *dp, int v3){	const struct nfs_statfs *sfsp;	int er;	dp = parsestatus(dp, &er);

⌨️ 快捷键说明

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