Example #1
0
static const uint32_t *
parsecreateopres(netdissect_options *ndo,
                 const uint32_t *dp, int verbose)
{
	u_int er;

	if (!(dp = parsestatus(ndo, dp, &er)))
		return (0);
	if (er)
		dp = parse_wcc_data(ndo, dp, verbose);
	else {
		ND_TCHECK_4(dp);
		if (!EXTRACT_BE_U_4(dp))
			return (dp + 1);
		dp++;
		if (!(dp = parsefh(ndo, dp, 1)))
			return (0);
		if (verbose) {
			if (!(dp = parse_post_op_attr(ndo, dp, verbose)))
				return (0);
			if (ndo->ndo_vflag > 1) {
				ND_PRINT(" dir attr:");
				dp = parse_wcc_data(ndo, dp, verbose);
			}
		}
	}
	return (dp);
trunc:
	return (NULL);
}
Example #2
0
static const u_int32_t *
parsecreateopres(const u_int32_t *dp, int verbose)
{
	int er;

	if (!(dp = parsestatus(dp, &er)))
		return (0);
	if (er)
		dp = parse_wcc_data(dp, verbose);
	else {
		TCHECK(dp[0]);
		if (!EXTRACT_32BITS(&dp[0]))
			return (dp + 1);
		dp++;
		if (!(dp = parsefh(dp, 1)))
			return (0);
		if (verbose) {
			if (!(dp = parse_post_op_attr(dp, verbose)))
				return (0);
			if (vflag > 1) {
				printf(" dir attr:");
				dp = parse_wcc_data(dp, verbose);
			}
		}
	}
	return (dp);
trunc:
	return (NULL);
}
Example #3
0
/*
 * 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));
}
Example #4
0
/*
 * 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 uint32_t *
parsefhn(netdissect_options *ndo,
         const uint32_t *dp, int v3)
{
	dp = parsefh(ndo, dp, v3);
	if (dp == NULL)
		return (NULL);
	ND_PRINT(" ");
	return (parsefn(ndo, dp));
}
Example #5
0
static int
parsediropres(const u_int32_t *dp)
{
	int er;

	if (!(dp = parsestatus(dp, &er)))
		return (0);
	if (er)
		return (1);

	dp = parsefh(dp, 0);
	if (dp == NULL)
		return (0);

	return (parsefattr(dp, vflag, 0) != NULL);
}
Example #6
0
static int
parsediropres(netdissect_options *ndo,
              const uint32_t *dp)
{
	u_int er;

	if (!(dp = parsestatus(ndo, dp, &er)))
		return (0);
	if (er)
		return (1);

	dp = parsefh(ndo, dp, 0);
	if (dp == NULL)
		return (0);

	return (parsefattr(ndo, dp, ndo->ndo_vflag, 0) != NULL);
}
Example #7
0
void
nfsreq_noaddr_print(netdissect_options *ndo,
                    const u_char *bp, u_int length,
                    const u_char *bp2)
{
	const struct sunrpc_msg *rp;
	const uint32_t *dp;
	nfs_type type;
	int v3;
	uint32_t proc;
	uint32_t access_flags;
	struct nfsv3_sattr sa3;

	ND_PRINT("%u", length);
	nfserr = 0;		/* assume no error */
	rp = (const struct sunrpc_msg *)bp;

	if (!xid_map_enter(ndo, rp, bp2))	/* record proc number for later on */
		goto trunc;

	v3 = (EXTRACT_BE_U_4(&rp->rm_call.cb_vers) == NFS_VER3);
	proc = EXTRACT_BE_U_4(&rp->rm_call.cb_proc);

	if (!v3 && proc < NFS_NPROCS)
		proc =  nfsv3_procid[proc];

	ND_PRINT(" %s", tok2str(nfsproc_str, "proc-%u", proc));
	switch (proc) {

	case NFSPROC_GETATTR:
	case NFSPROC_SETATTR:
	case NFSPROC_READLINK:
	case NFSPROC_FSSTAT:
	case NFSPROC_FSINFO:
	case NFSPROC_PATHCONF:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    parsefh(ndo, dp, v3) != NULL)
			return;
		break;

	case NFSPROC_LOOKUP:
	case NFSPROC_CREATE:
	case NFSPROC_MKDIR:
	case NFSPROC_REMOVE:
	case NFSPROC_RMDIR:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    parsefhn(ndo, dp, v3) != NULL)
			return;
		break;

	case NFSPROC_ACCESS:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefh(ndo, dp, v3)) != NULL) {
			ND_TCHECK_4(dp);
			access_flags = EXTRACT_BE_U_4(dp);
			if (access_flags & ~NFSV3ACCESS_FULL) {
				/* NFSV3ACCESS definitions aren't up to date */
				ND_PRINT(" %04x", access_flags);
			} else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) {
				ND_PRINT(" NFS_ACCESS_FULL");
			} else {
				char separator = ' ';
				if (access_flags & NFSV3ACCESS_READ) {
					ND_PRINT(" NFS_ACCESS_READ");
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_LOOKUP) {
					ND_PRINT("%cNFS_ACCESS_LOOKUP", separator);
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_MODIFY) {
					ND_PRINT("%cNFS_ACCESS_MODIFY", separator);
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_EXTEND) {
					ND_PRINT("%cNFS_ACCESS_EXTEND", separator);
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_DELETE) {
					ND_PRINT("%cNFS_ACCESS_DELETE", separator);
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_EXECUTE)
					ND_PRINT("%cNFS_ACCESS_EXECUTE", separator);
			}
			return;
		}
		break;

	case NFSPROC_READ:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefh(ndo, dp, v3)) != NULL) {
			if (v3) {
				ND_TCHECK_4(dp + 2);
				ND_PRINT(" %u bytes @ %" PRIu64,
				       EXTRACT_BE_U_4(dp + 2),
				       EXTRACT_BE_U_8(dp));
			} else {
				ND_TCHECK_4(dp + 1);
				ND_PRINT(" %u bytes @ %u",
				    EXTRACT_BE_U_4(dp + 1),
				    EXTRACT_BE_U_4(dp));
			}
			return;
		}
		break;

	case NFSPROC_WRITE:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefh(ndo, dp, v3)) != NULL) {
			if (v3) {
				ND_TCHECK_4(dp + 4);
				ND_PRINT(" %u (%u) bytes @ %" PRIu64,
						EXTRACT_BE_U_4(dp + 4),
						EXTRACT_BE_U_4(dp + 2),
						EXTRACT_BE_U_8(dp));
				if (ndo->ndo_vflag) {
					ND_PRINT(" <%s>",
						tok2str(nfsv3_writemodes,
							NULL, EXTRACT_BE_U_4(dp + 3)));
				}
			} else {
				ND_TCHECK_4(dp + 3);
				ND_PRINT(" %u (%u) bytes @ %u (%u)",
						EXTRACT_BE_U_4(dp + 3),
						EXTRACT_BE_U_4(dp + 2),
						EXTRACT_BE_U_4(dp + 1),
						EXTRACT_BE_U_4(dp));
			}
			return;
		}
		break;

	case NFSPROC_SYMLINK:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefhn(ndo, dp, v3)) != NULL) {
			ND_PRINT(" ->");
			if (v3 && (dp = parse_sattr3(ndo, dp, &sa3)) == NULL)
				break;
			if (parsefn(ndo, dp) == NULL)
				break;
			if (v3 && ndo->ndo_vflag)
				print_sattr3(ndo, &sa3, ndo->ndo_vflag);
			return;
		}
		break;

	case NFSPROC_MKNOD:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefhn(ndo, dp, v3)) != NULL) {
			ND_TCHECK_4(dp);
			type = (nfs_type) EXTRACT_BE_U_4(dp);
			dp++;
			if ((dp = parse_sattr3(ndo, dp, &sa3)) == NULL)
				break;
			ND_PRINT(" %s", tok2str(type2str, "unk-ft %u", type));
			if (ndo->ndo_vflag && (type == NFCHR || type == NFBLK)) {
				ND_TCHECK_4(dp + 1);
				ND_PRINT(" %u/%u",
				       EXTRACT_BE_U_4(dp),
				       EXTRACT_BE_U_4(dp + 1));
				dp += 2;
			}
			if (ndo->ndo_vflag)
				print_sattr3(ndo, &sa3, ndo->ndo_vflag);
			return;
		}
		break;

	case NFSPROC_RENAME:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefhn(ndo, dp, v3)) != NULL) {
			ND_PRINT(" ->");
			if (parsefhn(ndo, dp, v3) != NULL)
				return;
		}
		break;

	case NFSPROC_LINK:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefh(ndo, dp, v3)) != NULL) {
			ND_PRINT(" ->");
			if (parsefhn(ndo, dp, v3) != NULL)
				return;
		}
		break;

	case NFSPROC_READDIR:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefh(ndo, dp, v3)) != NULL) {
			if (v3) {
				ND_TCHECK_4(dp + 4);
				/*
				 * We shouldn't really try to interpret the
				 * offset cookie here.
				 */
				ND_PRINT(" %u bytes @ %" PRId64,
				    EXTRACT_BE_U_4(dp + 4),
				    EXTRACT_BE_U_8(dp));
				if (ndo->ndo_vflag) {
					/*
					 * This displays the 8 bytes
					 * of the verifier in order,
					 * from the low-order byte
					 * to the high-order byte.
					 */
					ND_PRINT(" verf %08x%08x",
						  EXTRACT_BE_U_4(dp + 2),
						  EXTRACT_BE_U_4(dp + 3));
				}
			} else {
				ND_TCHECK_4(dp + 1);
				/*
				 * Print the offset as signed, since -1 is
				 * common, but offsets > 2^31 aren't.
				 */
				ND_PRINT(" %u bytes @ %u",
				    EXTRACT_BE_U_4(dp + 1),
				    EXTRACT_BE_U_4(dp));
			}
			return;
		}
		break;

	case NFSPROC_READDIRPLUS:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefh(ndo, dp, v3)) != NULL) {
			ND_TCHECK_4(dp + 4);
			/*
			 * We don't try to interpret the offset
			 * cookie here.
			 */
			ND_PRINT(" %u bytes @ %" PRId64,
				EXTRACT_BE_U_4(dp + 4),
				EXTRACT_BE_U_8(dp));
			if (ndo->ndo_vflag) {
				ND_TCHECK_4(dp + 5);
				/*
				 * This displays the 8 bytes
				 * of the verifier in order,
				 * from the low-order byte
				 * to the high-order byte.
				 */
				ND_PRINT(" max %u verf %08x%08x",
				          EXTRACT_BE_U_4(dp + 5),
					  EXTRACT_BE_U_4(dp + 2),
					  EXTRACT_BE_U_4(dp + 3));
			}
			return;
		}
		break;

	case NFSPROC_COMMIT:
		if ((dp = parsereq(ndo, rp, length)) != NULL &&
		    (dp = parsefh(ndo, dp, v3)) != NULL) {
			ND_TCHECK_4(dp + 2);
			ND_PRINT(" %u bytes @ %" PRIu64,
				EXTRACT_BE_U_4(dp + 2),
				EXTRACT_BE_U_8(dp));
			return;
		}
		break;

	default:
		return;
	}

trunc:
	if (!nfserr)
		ND_PRINT("%s", tstr);
}
Example #8
0
static void
interp_reply(netdissect_options *ndo,
             const struct sunrpc_msg *rp, uint32_t proc, uint32_t vers, int length)
{
	const uint32_t *dp;
	int v3;
	u_int er;

	v3 = (vers == NFS_VER3);

	if (!v3 && proc < NFS_NPROCS)
		proc = nfsv3_procid[proc];

	ND_PRINT(" %s", tok2str(nfsproc_str, "proc-%u", proc));
	switch (proc) {

	case NFSPROC_GETATTR:
		dp = parserep(ndo, rp, length);
		if (dp != NULL && parseattrstat(ndo, dp, !ndo->ndo_qflag, v3) != 0)
			return;
		break;

	case NFSPROC_SETATTR:
		if (!(dp = parserep(ndo, rp, length)))
			return;
		if (v3) {
			if (parsewccres(ndo, dp, ndo->ndo_vflag))
				return;
		} else {
			if (parseattrstat(ndo, dp, !ndo->ndo_qflag, 0) != 0)
				return;
		}
		break;

	case NFSPROC_LOOKUP:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(ndo, dp, &er)))
				break;
			if (er) {
				if (ndo->ndo_vflag > 1) {
					ND_PRINT(" post dattr:");
					dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag);
				}
			} else {
				if (!(dp = parsefh(ndo, dp, v3)))
					break;
				if ((dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)) &&
				    ndo->ndo_vflag > 1) {
					ND_PRINT(" post dattr:");
					dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag);
				}
			}
			if (dp)
				return;
		} else {
			if (parsediropres(ndo, dp) != 0)
				return;
		}
		break;

	case NFSPROC_ACCESS:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (!(dp = parsestatus(ndo, dp, &er)))
			break;
		if (ndo->ndo_vflag)
			ND_PRINT(" attr:");
		if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)))
			break;
		if (!er) {
			ND_TCHECK_4(dp);
			ND_PRINT(" c %04x", EXTRACT_BE_U_4(dp));
		}
		return;

	case NFSPROC_READLINK:
		dp = parserep(ndo, rp, length);
		if (dp != NULL && parselinkres(ndo, dp, v3) != 0)
			return;
		break;

	case NFSPROC_READ:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(ndo, dp, &er)))
				break;
			if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)))
				break;
			if (er)
				return;
			if (ndo->ndo_vflag) {
				ND_TCHECK_4(dp + 1);
				ND_PRINT(" %u bytes", EXTRACT_BE_U_4(dp));
				if (EXTRACT_BE_U_4(dp + 1))
					ND_PRINT(" EOF");
			}
			return;
		} else {
			if (parseattrstat(ndo, dp, ndo->ndo_vflag, 0) != 0)
				return;
		}
		break;

	case NFSPROC_WRITE:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(ndo, dp, &er)))
				break;
			if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag)))
				break;
			if (er)
				return;
			if (ndo->ndo_vflag) {
				ND_TCHECK_4(dp);
				ND_PRINT(" %u bytes", EXTRACT_BE_U_4(dp));
				if (ndo->ndo_vflag > 1) {
					ND_TCHECK_4(dp + 1);
					ND_PRINT(" <%s>",
						tok2str(nfsv3_writemodes,
							NULL, EXTRACT_BE_U_4(dp + 1)));
				}
				return;
			}
		} else {
			if (parseattrstat(ndo, dp, ndo->ndo_vflag, v3) != 0)
				return;
		}
		break;

	case NFSPROC_CREATE:
	case NFSPROC_MKDIR:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL)
				return;
		} else {
			if (parsediropres(ndo, dp) != 0)
				return;
		}
		break;

	case NFSPROC_SYMLINK:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL)
				return;
		} else {
			if (parsestatus(ndo, dp, &er) != NULL)
				return;
		}
		break;

	case NFSPROC_MKNOD:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (parsecreateopres(ndo, dp, ndo->ndo_vflag) != NULL)
			return;
		break;

	case NFSPROC_REMOVE:
	case NFSPROC_RMDIR:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (parsewccres(ndo, dp, ndo->ndo_vflag))
				return;
		} else {
			if (parsestatus(ndo, dp, &er) != NULL)
				return;
		}
		break;

	case NFSPROC_RENAME:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(ndo, dp, &er)))
				break;
			if (ndo->ndo_vflag) {
				ND_PRINT(" from:");
				if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag)))
					break;
				ND_PRINT(" to:");
				if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag)))
					break;
			}
			return;
		} else {
			if (parsestatus(ndo, dp, &er) != NULL)
				return;
		}
		break;

	case NFSPROC_LINK:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(ndo, dp, &er)))
				break;
			if (ndo->ndo_vflag) {
				ND_PRINT(" file POST:");
				if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)))
					break;
				ND_PRINT(" dir:");
				if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag)))
					break;
				return;
			}
		} else {
			if (parsestatus(ndo, dp, &er) != NULL)
				return;
		}
		break;

	case NFSPROC_READDIR:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (v3) {
			if (parsev3rddirres(ndo, dp, ndo->ndo_vflag))
				return;
		} else {
			if (parserddires(ndo, dp) != 0)
				return;
		}
		break;

	case NFSPROC_READDIRPLUS:
		if (!(dp = parserep(ndo, rp, length)))
			break;
		if (parsev3rddirres(ndo, dp, ndo->ndo_vflag))
			return;
		break;

	case NFSPROC_FSSTAT:
		dp = parserep(ndo, rp, length);
		if (dp != NULL && parsestatfs(ndo, dp, v3) != 0)
			return;
		break;

	case NFSPROC_FSINFO:
		dp = parserep(ndo, rp, length);
		if (dp != NULL && parsefsinfo(ndo, dp) != 0)
			return;
		break;

	case NFSPROC_PATHCONF:
		dp = parserep(ndo, rp, length);
		if (dp != NULL && parsepathconf(ndo, dp) != 0)
			return;
		break;

	case NFSPROC_COMMIT:
		dp = parserep(ndo, rp, length);
		if (dp != NULL && parsewccres(ndo, dp, ndo->ndo_vflag) != 0)
			return;
		break;

	default:
		return;
	}
trunc:
	if (!nfserr)
		ND_PRINT("%s", tstr);
}
Example #9
0
void
nfsreq_print_noaddr(register const u_char *bp, u_int length,
    register const u_char *bp2)
{
	register const struct sunrpc_msg *rp;
	register const u_int32_t *dp;
	nfs_type type;
	int v3;
	u_int32_t proc;
	u_int32_t access_flags;
	struct nfsv3_sattr sa3;

	nfserr = 0;		/* assume no error */
	rp = (const struct sunrpc_msg *)bp;

	if (!xid_map_enter(rp, bp2))	/* record proc number for later on */
		goto trunc;

	v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3);
	proc = EXTRACT_32BITS(&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]);
			access_flags = EXTRACT_32BITS(&dp[0]);
			if (access_flags & ~NFSV3ACCESS_FULL) {
				/* NFSV3ACCESS definitions aren't up to date */
				printf(" %04x", access_flags);
			} else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) {
				printf(" NFS_ACCESS_FULL");
			} else {
				char separator = ' ';
				if (access_flags & NFSV3ACCESS_READ) {
					printf(" NFS_ACCESS_READ");
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_LOOKUP) {
					printf("%cNFS_ACCESS_LOOKUP", separator);
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_MODIFY) {
					printf("%cNFS_ACCESS_MODIFY", separator);
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_EXTEND) {
					printf("%cNFS_ACCESS_EXTEND", separator);
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_DELETE) {
					printf("%cNFS_ACCESS_DELETE", separator);
					separator = '|';
				}
				if (access_flags & NFSV3ACCESS_EXECUTE)
					printf("%cNFS_ACCESS_EXECUTE", separator);
			}
			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 @ %" PRIu64,
				       EXTRACT_32BITS(&dp[2]),
				       EXTRACT_64BITS(&dp[0]));
			} else {
				TCHECK(dp[1]);
				printf(" %u bytes @ %u",
				    EXTRACT_32BITS(&dp[1]),
				    EXTRACT_32BITS(&dp[0]));
			}
			return;
		}
		break;

	case NFSPROC_WRITE:
		printf(" write");
		if ((dp = parsereq(rp, length)) != NULL &&
		    (dp = parsefh(dp, v3)) != NULL) {
			if (v3) {
				TCHECK(dp[2]);
				printf(" %u (%u) bytes @ %" PRIu64,
						EXTRACT_32BITS(&dp[4]),
						EXTRACT_32BITS(&dp[2]),
						EXTRACT_64BITS(&dp[0]));
				if (vflag) {
					dp += 3;
					TCHECK(dp[0]);
					printf(" <%s>",
						tok2str(nfsv3_writemodes,
							NULL, EXTRACT_32BITS(dp)));
				}
			} else {
				TCHECK(dp[3]);
				printf(" %u (%u) bytes @ %u (%u)",
						EXTRACT_32BITS(&dp[3]),
						EXTRACT_32BITS(&dp[2]),
						EXTRACT_32BITS(&dp[1]),
						EXTRACT_32BITS(&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)EXTRACT_32BITS(dp);
			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",
				       EXTRACT_32BITS(&dp[0]),
				       EXTRACT_32BITS(&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 @ %" PRId64,
				    EXTRACT_32BITS(&dp[4]),
				    EXTRACT_64BITS(&dp[0]));
				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",
				    EXTRACT_32BITS(&dp[1]),
				    EXTRACT_32BITS(&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 @ %" PRId64,
				EXTRACT_32BITS(&dp[4]),
				EXTRACT_64BITS(&dp[0]));
			if (vflag) {
				TCHECK(dp[5]);
				printf(" max %u verf %08x%08x",
				       EXTRACT_32BITS(&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");
		if ((dp = parsereq(rp, length)) != NULL &&
		    parsefh(dp, v3) != NULL)
			return;
		break;

	case NFSPROC_PATHCONF:
		printf(" pathconf");
		if ((dp = parsereq(rp, length)) != NULL &&
		    parsefh(dp, v3) != NULL)
			return;
		break;

	case NFSPROC_COMMIT:
		printf(" commit");
		if ((dp = parsereq(rp, length)) != NULL &&
		    (dp = parsefh(dp, v3)) != NULL) {
			TCHECK(dp[2]);
			printf(" %u bytes @ %" PRIu64,
				EXTRACT_32BITS(&dp[2]),
				EXTRACT_64BITS(&dp[0]));
			return;
		}
		break;

	default:
		printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc));
		return;
	}

trunc:
	if (!nfserr)
		printf("%s", tstr);
}
Example #10
0
static void
interp_reply(const struct sunrpc_msg *rp, u_int32_t proc, u_int32_t vers, int length)
{
	register const u_int32_t *dp;
	register int v3;
	int er;

	v3 = (vers == NFS_VER3);

	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");
		dp = parserep(rp, length);
		if (dp != NULL && parseattrstat(dp, !qflag, v3) != 0)
			return;
		break;

	case NFSPROC_SETATTR:
		printf(" setattr");
		if (!(dp = parserep(rp, length)))
			return;
		if (v3) {
			if (parsewccres(dp, vflag))
				return;
		} else {
			if (parseattrstat(dp, !qflag, 0) != 0)
				return;
		}
		break;

	case NFSPROC_LOOKUP:
		printf(" lookup");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(dp, &er)))
				break;
			if (er) {
				if (vflag > 1) {
					printf(" post dattr:");
					dp = parse_post_op_attr(dp, vflag);
				}
			} else {
				if (!(dp = parsefh(dp, v3)))
					break;
				if ((dp = parse_post_op_attr(dp, vflag)) &&
				    vflag > 1) {
					printf(" post dattr:");
					dp = parse_post_op_attr(dp, vflag);
				}
			}
			if (dp)
				return;
		} else {
			if (parsediropres(dp) != 0)
				return;
		}
		break;

	case NFSPROC_ACCESS:
		printf(" access");
		if (!(dp = parserep(rp, length)))
			break;
		if (!(dp = parsestatus(dp, &er)))
			break;
		if (vflag)
			printf(" attr:");
		if (!(dp = parse_post_op_attr(dp, vflag)))
			break;
		if (!er)
			printf(" c %04x", EXTRACT_32BITS(&dp[0]));
		return;

	case NFSPROC_READLINK:
		printf(" readlink");
		dp = parserep(rp, length);
		if (dp != NULL && parselinkres(dp, v3) != 0)
			return;
		break;

	case NFSPROC_READ:
		printf(" read");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(dp, &er)))
				break;
			if (!(dp = parse_post_op_attr(dp, vflag)))
				break;
			if (er)
				return;
			if (vflag) {
				TCHECK(dp[1]);
				printf(" %u bytes", EXTRACT_32BITS(&dp[0]));
				if (EXTRACT_32BITS(&dp[1]))
					printf(" EOF");
			}
			return;
		} else {
			if (parseattrstat(dp, vflag, 0) != 0)
				return;
		}
		break;

	case NFSPROC_WRITE:
		printf(" write");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(dp, &er)))
				break;
			if (!(dp = parse_wcc_data(dp, vflag)))
				break;
			if (er)
				return;
			if (vflag) {
				TCHECK(dp[0]);
				printf(" %u bytes", EXTRACT_32BITS(&dp[0]));
				if (vflag > 1) {
					TCHECK(dp[1]);
					printf(" <%s>",
						tok2str(nfsv3_writemodes,
							NULL, EXTRACT_32BITS(&dp[1])));
				}
				return;
			}
		} else {
			if (parseattrstat(dp, vflag, v3) != 0)
				return;
		}
		break;

	case NFSPROC_CREATE:
		printf(" create");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (parsecreateopres(dp, vflag) != 0)
				return;
		} else {
			if (parsediropres(dp) != 0)
				return;
		}
		break;

	case NFSPROC_MKDIR:
		printf(" mkdir");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (parsecreateopres(dp, vflag) != 0)
				return;
		} else {
			if (parsediropres(dp) != 0)
				return;
		}
		break;

	case NFSPROC_SYMLINK:
		printf(" symlink");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (parsecreateopres(dp, vflag) != 0)
				return;
		} else {
			if (parsestatus(dp, &er) != 0)
				return;
		}
		break;

	case NFSPROC_MKNOD:
		printf(" mknod");
		if (!(dp = parserep(rp, length)))
			break;
		if (parsecreateopres(dp, vflag) != 0)
			return;
		break;

	case NFSPROC_REMOVE:
		printf(" remove");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (parsewccres(dp, vflag))
				return;
		} else {
			if (parsestatus(dp, &er) != 0)
				return;
		}
		break;

	case NFSPROC_RMDIR:
		printf(" rmdir");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (parsewccres(dp, vflag))
				return;
		} else {
			if (parsestatus(dp, &er) != 0)
				return;
		}
		break;

	case NFSPROC_RENAME:
		printf(" rename");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(dp, &er)))
				break;
			if (vflag) {
				printf(" from:");
				if (!(dp = parse_wcc_data(dp, vflag)))
					break;
				printf(" to:");
				if (!(dp = parse_wcc_data(dp, vflag)))
					break;
			}
			return;
		} else {
			if (parsestatus(dp, &er) != 0)
				return;
		}
		break;

	case NFSPROC_LINK:
		printf(" link");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (!(dp = parsestatus(dp, &er)))
				break;
			if (vflag) {
				printf(" file POST:");
				if (!(dp = parse_post_op_attr(dp, vflag)))
					break;
				printf(" dir:");
				if (!(dp = parse_wcc_data(dp, vflag)))
					break;
				return;
			}
		} else {
			if (parsestatus(dp, &er) != 0)
				return;
		}
		break;

	case NFSPROC_READDIR:
		printf(" readdir");
		if (!(dp = parserep(rp, length)))
			break;
		if (v3) {
			if (parsev3rddirres(dp, vflag))
				return;
		} else {
			if (parserddires(dp) != 0)
				return;
		}
		break;

	case NFSPROC_READDIRPLUS:
		printf(" readdirplus");
		if (!(dp = parserep(rp, length)))
			break;
		if (parsev3rddirres(dp, vflag))
			return;
		break;

	case NFSPROC_FSSTAT:
		printf(" fsstat");
		dp = parserep(rp, length);
		if (dp != NULL && parsestatfs(dp, v3) != 0)
			return;
		break;

	case NFSPROC_FSINFO:
		printf(" fsinfo");
		dp = parserep(rp, length);
		if (dp != NULL && parsefsinfo(dp) != 0)
			return;
		break;

	case NFSPROC_PATHCONF:
		printf(" pathconf");
		dp = parserep(rp, length);
		if (dp != NULL && parsepathconf(dp) != 0)
			return;
		break;

	case NFSPROC_COMMIT:
		printf(" commit");
		dp = parserep(rp, length);
		if (dp != NULL && parsewccres(dp, vflag) != 0)
			return;
		break;

	default:
		printf(" proc-%u", proc);
		return;
	}
trunc:
	if (!nfserr)
		printf("%s", tstr);
}
void
nfsreq_print(register const u_char *bp, u_int length,
    register const u_char *bp2)
{
	register const struct sunrpc_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 sunrpc_msg *)bp;
	if (!nflag) {
		snprintf(srcid, sizeof(srcid), "%u",
		    EXTRACT_32BITS(&rp->rm_xid));
		strlcpy(dstid, "nfs", sizeof(dstid));
	} else {
		snprintf(srcid, sizeof(srcid), "%u",
		    EXTRACT_32BITS(&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 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3);
	proc = EXTRACT_32BITS(&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", EXTRACT_32BITS(&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 @ %" PRIu64,
				       EXTRACT_32BITS(&dp[2]),
				       EXTRACT_64BITS(&dp[0]));
			} else {
				TCHECK(dp[1]);
				printf(" %u bytes @ %u",
				    EXTRACT_32BITS(&dp[1]),
				    EXTRACT_32BITS(&dp[0]));
			}
			return;
		}
		break;

	case NFSPROC_WRITE:
		printf(" write");
		if ((dp = parsereq(rp, length)) != NULL &&
		    (dp = parsefh(dp, v3)) != NULL) {
			if (v3) {
				TCHECK(dp[2]);
				printf(" %u (%u) bytes @ %" PRIu64,
						EXTRACT_32BITS(&dp[4]),
						EXTRACT_32BITS(&dp[2]),
						EXTRACT_64BITS(&dp[0]));
				if (vflag) {
					dp += 3;
					TCHECK(dp[0]);
					printf(" <%s>",
						tok2str(nfsv3_writemodes,
							NULL, EXTRACT_32BITS(dp)));
				}
			} else {
				TCHECK(dp[3]);
				printf(" %u (%u) bytes @ %u (%u)",
						EXTRACT_32BITS(&dp[3]),
						EXTRACT_32BITS(&dp[2]),
						EXTRACT_32BITS(&dp[1]),
						EXTRACT_32BITS(&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)EXTRACT_32BITS(dp);
			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",
				       EXTRACT_32BITS(&dp[0]),
				       EXTRACT_32BITS(&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 @ %" PRId64,
				    EXTRACT_32BITS(&dp[4]),
				    EXTRACT_64BITS(&dp[0]));
				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",
				    EXTRACT_32BITS(&dp[1]),
				    EXTRACT_32BITS(&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 @ %" PRId64,
				EXTRACT_32BITS(&dp[4]),
				EXTRACT_64BITS(&dp[0]));
			if (vflag) {
				TCHECK(dp[5]);
				printf(" max %u verf %08x%08x",
				       EXTRACT_32BITS(&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");
		if ((dp = parsereq(rp, length)) != NULL &&
		    parsefh(dp, v3) != NULL)
			return;
		break;

	case NFSPROC_PATHCONF:
		printf(" pathconf");
		if ((dp = parsereq(rp, length)) != NULL &&
		    parsefh(dp, v3) != NULL)
			return;
		break;

	case NFSPROC_COMMIT:
		printf(" commit");
		if ((dp = parsereq(rp, length)) != NULL &&
		    (dp = parsefh(dp, v3)) != NULL) {
			TCHECK(dp[2]);
			printf(" %u bytes @ %" PRIu64,
				EXTRACT_32BITS(&dp[2]),
				EXTRACT_64BITS(&dp[0]));
			return;
		}
		break;

	default:
		printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc));
		return;
	}

trunc:
	if (!nfserr)
		fputs(" [|nfs]", stdout);
}