X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/513f782ae18791f0c925b9235da749b38159b607..a8abce5c5e2dce2ba6dbccd5d3829da104b80f9c:/print-nfs.c diff --git a/print-nfs.c b/print-nfs.c index 494d4747..92c87fc4 100644 --- a/print-nfs.c +++ b/print-nfs.c @@ -22,7 +22,7 @@ /* \summary: Network File System (NFS) printer */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #include "netdissect-stdinc.h" @@ -42,7 +42,6 @@ #include "rpc_auth.h" #include "rpc_msg.h" -static const char tstr[] = " [|nfs]"; static void nfs_printfh(netdissect_options *, const uint32_t *, const u_int); static int xid_map_enter(netdissect_options *, const struct sunrpc_msg *, const u_char *); @@ -210,14 +209,14 @@ print_nfsaddr(netdissect_options *ndo, switch (IP_V((const struct ip *)bp)) { case 4: ip = (const struct ip *)bp; - strlcpy(srcaddr, ipaddr_string(ndo, &ip->ip_src), sizeof(srcaddr)); - strlcpy(dstaddr, ipaddr_string(ndo, &ip->ip_dst), sizeof(dstaddr)); + strlcpy(srcaddr, ipaddr_string(ndo, ip->ip_src), sizeof(srcaddr)); + strlcpy(dstaddr, ipaddr_string(ndo, ip->ip_dst), sizeof(dstaddr)); break; case 6: ip6 = (const struct ip6_hdr *)bp; - strlcpy(srcaddr, ip6addr_string(ndo, &ip6->ip6_src), + strlcpy(srcaddr, ip6addr_string(ndo, ip6->ip6_src), sizeof(srcaddr)); - strlcpy(dstaddr, ip6addr_string(ndo, &ip6->ip6_dst), + strlcpy(dstaddr, ip6addr_string(ndo, ip6->ip6_dst), sizeof(dstaddr)); break; default: @@ -229,6 +228,34 @@ print_nfsaddr(netdissect_options *ndo, ND_PRINT("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d); } +/* + * NFS Version 3 sattr3 structure for the new node creation case. + * This does not have a fixed layout on the network, so this + * structure does not correspond to the layout of the data on + * the network; it's used to store the data when the sattr3 + * is parsed for use when it's later printed. + */ +struct nfsv3_sattr { + uint32_t sa_modeset; + uint32_t sa_mode; + uint32_t sa_uidset; + uint32_t sa_uid; + uint32_t sa_gidset; + uint32_t sa_gid; + uint32_t sa_sizeset; + uint32_t sa_size; + uint32_t sa_atimetype; + struct { + uint32_t nfsv3_sec; + uint32_t nfsv3_nsec; + } sa_atime; + uint32_t sa_mtimetype; + struct { + uint32_t nfsv3_sec; + uint32_t nfsv3_nsec; + } sa_mtime; +}; + static const uint32_t * parse_sattr3(netdissect_options *ndo, const uint32_t *dp, struct nfsv3_sattr *sa3) @@ -326,17 +353,18 @@ nfsreply_print(netdissect_options *ndo, const struct sunrpc_msg *rp; char srcid[20], dstid[20]; /*fits 32bit*/ + ndo->ndo_protocol = "nfs"; nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; - ND_TCHECK(rp->rm_xid); + ND_TCHECK_4(rp->rm_xid); if (!ndo->ndo_nflag) { strlcpy(srcid, "nfs", sizeof(srcid)); - snprintf(dstid, sizeof(dstid), "%u", + nd_snprintf(dstid, sizeof(dstid), "%u", EXTRACT_BE_U_4(rp->rm_xid)); } else { - snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); - snprintf(dstid, sizeof(dstid), "%u", + nd_snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); + nd_snprintf(dstid, sizeof(dstid), "%u", EXTRACT_BE_U_4(rp->rm_xid)); } print_nfsaddr(ndo, bp2, srcid, dstid); @@ -346,7 +374,7 @@ nfsreply_print(netdissect_options *ndo, trunc: if (!nfserr) - ND_PRINT("%s", tstr); + nd_print_trunc(ndo); } void @@ -361,10 +389,11 @@ nfsreply_noaddr_print(netdissect_options *ndo, uint32_t rhigh; enum sunrpc_auth_stat rwhy; + ndo->ndo_protocol = "nfs"; nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; - ND_TCHECK(rp->rm_reply.rp_stat); + ND_TCHECK_4(rp->rm_reply.rp_stat); reply_stat = EXTRACT_BE_U_4(&rp->rm_reply.rp_stat); switch (reply_stat) { @@ -376,19 +405,19 @@ nfsreply_noaddr_print(netdissect_options *ndo, case SUNRPC_MSG_DENIED: ND_PRINT("reply ERR %u: ", length); - ND_TCHECK(rp->rm_reply.rp_reject.rj_stat); + ND_TCHECK_4(rp->rm_reply.rp_reject.rj_stat); rstat = EXTRACT_BE_U_4(&rp->rm_reply.rp_reject.rj_stat); switch (rstat) { case SUNRPC_RPC_MISMATCH: - ND_TCHECK(rp->rm_reply.rp_reject.rj_vers.high); + ND_TCHECK_4(rp->rm_reply.rp_reject.rj_vers.high); rlow = EXTRACT_BE_U_4(&rp->rm_reply.rp_reject.rj_vers.low); rhigh = EXTRACT_BE_U_4(&rp->rm_reply.rp_reject.rj_vers.high); ND_PRINT("RPC Version mismatch (%u-%u)", rlow, rhigh); break; case SUNRPC_AUTH_ERROR: - ND_TCHECK(rp->rm_reply.rp_reject.rj_why); + ND_TCHECK_4(rp->rm_reply.rp_reject.rj_why); rwhy = EXTRACT_BE_U_4(&rp->rm_reply.rp_reject.rj_why); ND_PRINT("Auth %s", tok2str(sunrpc_auth_str, "Invalid failure code %u", rwhy)); break; @@ -407,7 +436,7 @@ nfsreply_noaddr_print(netdissect_options *ndo, trunc: if (!nfserr) - ND_PRINT("%s", tstr); + nd_print_trunc(ndo); } /* @@ -419,21 +448,48 @@ parsereq(netdissect_options *ndo, const struct sunrpc_msg *rp, u_int length) { const uint32_t *dp; - u_int len; + u_int len, rounded_len; /* - * find the start of the req data (if we captured it) + * Find the start of the req data (if we captured it). + * First, get the length of the credentials, and make sure + * we have all of the opaque part of the credentials. */ dp = (const uint32_t *)&rp->rm_call.cb_cred; + if (length < 2 * sizeof(*dp)) + goto trunc; ND_TCHECK_4(dp + 1); len = EXTRACT_BE_U_4(dp + 1); - if (len < length) { + rounded_len = roundup2(len, 4); + ND_TCHECK_LEN(dp + 2, rounded_len); + if (2 * sizeof(*dp) + rounded_len <= length) { + /* + * We have all of the credentials. Skip past them; they + * consist of 4 bytes of flavor, 4 bytes of length, + * and len-rounded-up-to-a-multiple-of-4 bytes of + * data. + */ dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); + length -= 2 * sizeof(*dp) + rounded_len; + + /* + * Now get the length of the verifier, and make sure + * we have all of the opaque part of the verifier. + */ + if (length < 2 * sizeof(*dp)) + goto trunc; ND_TCHECK_4(dp + 1); len = EXTRACT_BE_U_4(dp + 1); - if (len < length) { + rounded_len = roundup2(len, 4); + ND_TCHECK_LEN(dp + 2, rounded_len); + if (2 * sizeof(*dp) + rounded_len < length) { + /* + * We have all of the verifier. Skip past it; + * it consists of 4 bytes of flavor, 4 bytes of + * length, and len-rounded-up-to-a-multiple-of-4 + * bytes of data. + */ dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); - ND_TCHECK_LEN(dp, 0); return (dp); } } @@ -490,7 +546,7 @@ parsefn(netdissect_options *ndo, /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ dp += ((len + 3) & ~3) / sizeof(*dp); ND_PRINT("\""); - if (fn_printn(ndo, cp, len, ndo->ndo_snapend)) { + if (nd_printn(ndo, cp, len, ndo->ndo_snapend)) { ND_PRINT("\""); goto trunc; } @@ -530,6 +586,7 @@ nfsreq_noaddr_print(netdissect_options *ndo, uint32_t access_flags; struct nfsv3_sattr sa3; + ndo->ndo_protocol = "nfs"; ND_PRINT("%u", length); nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; @@ -786,7 +843,7 @@ nfsreq_noaddr_print(netdissect_options *ndo, trunc: if (!nfserr) - ND_PRINT("%s", tstr); + nd_print_trunc(ndo); } /* @@ -899,7 +956,7 @@ xid_map_enter(netdissect_options *ndo, const struct ip6_hdr *ip6 = NULL; struct xid_map_entry *xmep; - if (!ND_TTEST(rp->rm_call.cb_proc)) + if (!ND_TTEST_4(rp->rm_call.cb_proc)) return (0); switch (IP_V((const struct ip *)bp)) { case 4: @@ -920,13 +977,17 @@ xid_map_enter(netdissect_options *ndo, UNALIGNED_MEMCPY(&xmep->xid, &rp->rm_xid, sizeof(xmep->xid)); if (ip) { xmep->ipver = 4; - UNALIGNED_MEMCPY(&xmep->client, &ip->ip_src, sizeof(ip->ip_src)); - UNALIGNED_MEMCPY(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst)); + UNALIGNED_MEMCPY(&xmep->client, ip->ip_src, + sizeof(ip->ip_src)); + UNALIGNED_MEMCPY(&xmep->server, ip->ip_dst, + sizeof(ip->ip_dst)); } else if (ip6) { xmep->ipver = 6; - UNALIGNED_MEMCPY(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src)); - UNALIGNED_MEMCPY(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); + UNALIGNED_MEMCPY(&xmep->client, ip6->ip6_src, + sizeof(ip6->ip6_src)); + UNALIGNED_MEMCPY(&xmep->server, ip6->ip6_dst, + sizeof(ip6->ip6_dst)); } xmep->proc = EXTRACT_BE_U_4(&rp->rm_call.cb_proc); xmep->vers = EXTRACT_BE_U_4(&rp->rm_call.cb_vers); @@ -958,18 +1019,18 @@ xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, uint32_t *proc, goto nextitem; switch (xmep->ipver) { case 4: - if (UNALIGNED_MEMCMP(&ip->ip_src, &xmep->server, - sizeof(ip->ip_src)) != 0 || - UNALIGNED_MEMCMP(&ip->ip_dst, &xmep->client, - sizeof(ip->ip_dst)) != 0) { + if (UNALIGNED_MEMCMP(ip->ip_src, &xmep->server, + sizeof(ip->ip_src)) != 0 || + UNALIGNED_MEMCMP(ip->ip_dst, &xmep->client, + sizeof(ip->ip_dst)) != 0) { cmp = 0; } break; case 6: - if (UNALIGNED_MEMCMP(&ip6->ip6_src, &xmep->server, - sizeof(ip6->ip6_src)) != 0 || - UNALIGNED_MEMCMP(&ip6->ip6_dst, &xmep->client, - sizeof(ip6->ip6_dst)) != 0) { + if (UNALIGNED_MEMCMP(ip6->ip6_src, &xmep->server, + sizeof(ip6->ip6_src)) != 0 || + UNALIGNED_MEMCMP(ip6->ip6_dst, &xmep->client, + sizeof(ip6->ip6_dst)) != 0) { cmp = 0; } break; @@ -1080,7 +1141,7 @@ parsefattr(netdissect_options *ndo, const struct nfs_fattr *fap; fap = (const struct nfs_fattr *)dp; - ND_TCHECK(fap->fa_gid); + ND_TCHECK_4(fap->fa_gid); if (verbose) { /* * XXX - UIDs and GIDs are unsigned in NFS and in @@ -1090,56 +1151,56 @@ parsefattr(netdissect_options *ndo, */ ND_PRINT(" %s %o ids %d/%d", tok2str(type2str, "unk-ft %u ", - EXTRACT_BE_U_4(&fap->fa_type)), - EXTRACT_BE_U_4(&fap->fa_mode), - EXTRACT_BE_S_4(&fap->fa_uid), - EXTRACT_BE_S_4(&fap->fa_gid)); + EXTRACT_BE_U_4(fap->fa_type)), + EXTRACT_BE_U_4(fap->fa_mode), + EXTRACT_BE_S_4(fap->fa_uid), + EXTRACT_BE_S_4(fap->fa_gid)); if (v3) { - ND_TCHECK(fap->fa3_size); + ND_TCHECK_8(fap->fa3_size); ND_PRINT(" sz %" PRIu64, - EXTRACT_BE_U_8((const uint32_t *)&fap->fa3_size)); + EXTRACT_BE_U_8(fap->fa3_size)); } else { - ND_TCHECK(fap->fa2_size); - ND_PRINT(" sz %u", EXTRACT_BE_U_4(&fap->fa2_size)); + ND_TCHECK_4(fap->fa2_size); + ND_PRINT(" sz %u", EXTRACT_BE_U_4(fap->fa2_size)); } } /* print lots more stuff */ if (verbose > 1) { if (v3) { - ND_TCHECK(fap->fa3_ctime); + ND_TCHECK_8(&fap->fa3_ctime); ND_PRINT(" nlink %u rdev %u/%u", - EXTRACT_BE_U_4(&fap->fa_nlink), - EXTRACT_BE_U_4(&fap->fa3_rdev.specdata1), - EXTRACT_BE_U_4(&fap->fa3_rdev.specdata2)); + EXTRACT_BE_U_4(fap->fa_nlink), + EXTRACT_BE_U_4(fap->fa3_rdev.specdata1), + EXTRACT_BE_U_4(fap->fa3_rdev.specdata2)); ND_PRINT(" fsid %" PRIx64, - EXTRACT_BE_U_8((const uint32_t *)&fap->fa3_fsid)); + EXTRACT_BE_U_8(fap->fa3_fsid)); ND_PRINT(" fileid %" PRIx64, - EXTRACT_BE_U_8((const uint32_t *)&fap->fa3_fileid)); + EXTRACT_BE_U_8(fap->fa3_fileid)); ND_PRINT(" a/m/ctime %u.%06u", - EXTRACT_BE_U_4(&fap->fa3_atime.nfsv3_sec), - EXTRACT_BE_U_4(&fap->fa3_atime.nfsv3_nsec)); + EXTRACT_BE_U_4(fap->fa3_atime.nfsv3_sec), + EXTRACT_BE_U_4(fap->fa3_atime.nfsv3_nsec)); ND_PRINT(" %u.%06u", - EXTRACT_BE_U_4(&fap->fa3_mtime.nfsv3_sec), - EXTRACT_BE_U_4(&fap->fa3_mtime.nfsv3_nsec)); + EXTRACT_BE_U_4(fap->fa3_mtime.nfsv3_sec), + EXTRACT_BE_U_4(fap->fa3_mtime.nfsv3_nsec)); ND_PRINT(" %u.%06u", - EXTRACT_BE_U_4(&fap->fa3_ctime.nfsv3_sec), - EXTRACT_BE_U_4(&fap->fa3_ctime.nfsv3_nsec)); + EXTRACT_BE_U_4(fap->fa3_ctime.nfsv3_sec), + EXTRACT_BE_U_4(fap->fa3_ctime.nfsv3_nsec)); } else { - ND_TCHECK(fap->fa2_ctime); + ND_TCHECK_8(&fap->fa2_ctime); ND_PRINT(" nlink %u rdev 0x%x fsid 0x%x nodeid 0x%x a/m/ctime", - EXTRACT_BE_U_4(&fap->fa_nlink), - EXTRACT_BE_U_4(&fap->fa2_rdev), - EXTRACT_BE_U_4(&fap->fa2_fsid), - EXTRACT_BE_U_4(&fap->fa2_fileid)); + EXTRACT_BE_U_4(fap->fa_nlink), + EXTRACT_BE_U_4(fap->fa2_rdev), + EXTRACT_BE_U_4(fap->fa2_fsid), + EXTRACT_BE_U_4(fap->fa2_fileid)); ND_PRINT(" %u.%06u", - EXTRACT_BE_U_4(&fap->fa2_atime.nfsv2_sec), - EXTRACT_BE_U_4(&fap->fa2_atime.nfsv2_usec)); + EXTRACT_BE_U_4(fap->fa2_atime.nfsv2_sec), + EXTRACT_BE_U_4(fap->fa2_atime.nfsv2_usec)); ND_PRINT(" %u.%06u", - EXTRACT_BE_U_4(&fap->fa2_mtime.nfsv2_sec), - EXTRACT_BE_U_4(&fap->fa2_mtime.nfsv2_usec)); + EXTRACT_BE_U_4(fap->fa2_mtime.nfsv2_sec), + EXTRACT_BE_U_4(fap->fa2_mtime.nfsv2_usec)); ND_PRINT(" %u.%06u", - EXTRACT_BE_U_4(&fap->fa2_ctime.nfsv2_sec), - EXTRACT_BE_U_4(&fap->fa2_ctime.nfsv2_usec)); + EXTRACT_BE_U_4(fap->fa2_ctime.nfsv2_sec), + EXTRACT_BE_U_4(fap->fa2_ctime.nfsv2_usec)); } } return ((const uint32_t *)((const unsigned char *)dp + @@ -1227,23 +1288,23 @@ parsestatfs(netdissect_options *ndo, if (v3) { ND_PRINT(" tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64, - EXTRACT_BE_U_8((const uint32_t *)&sfsp->sf_tbytes), - EXTRACT_BE_U_8((const uint32_t *)&sfsp->sf_fbytes), - EXTRACT_BE_U_8((const uint32_t *)&sfsp->sf_abytes)); + EXTRACT_BE_U_8(sfsp->sf_tbytes), + EXTRACT_BE_U_8(sfsp->sf_fbytes), + EXTRACT_BE_U_8(sfsp->sf_abytes)); if (ndo->ndo_vflag) { ND_PRINT(" tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u", - EXTRACT_BE_U_8((const uint32_t *)&sfsp->sf_tfiles), - EXTRACT_BE_U_8((const uint32_t *)&sfsp->sf_ffiles), - EXTRACT_BE_U_8((const uint32_t *)&sfsp->sf_afiles), - EXTRACT_BE_U_4(&sfsp->sf_invarsec)); + EXTRACT_BE_U_8(sfsp->sf_tfiles), + EXTRACT_BE_U_8(sfsp->sf_ffiles), + EXTRACT_BE_U_8(sfsp->sf_afiles), + EXTRACT_BE_U_4(sfsp->sf_invarsec)); } } else { ND_PRINT(" tsize %u bsize %u blocks %u bfree %u bavail %u", - EXTRACT_BE_U_4(&sfsp->sf_tsize), - EXTRACT_BE_U_4(&sfsp->sf_bsize), - EXTRACT_BE_U_4(&sfsp->sf_blocks), - EXTRACT_BE_U_4(&sfsp->sf_bfree), - EXTRACT_BE_U_4(&sfsp->sf_bavail)); + EXTRACT_BE_U_4(sfsp->sf_tsize), + EXTRACT_BE_U_4(sfsp->sf_bsize), + EXTRACT_BE_U_4(sfsp->sf_blocks), + EXTRACT_BE_U_4(sfsp->sf_bfree), + EXTRACT_BE_U_4(sfsp->sf_bavail)); } return (1); @@ -1433,19 +1494,19 @@ parsefsinfo(netdissect_options *ndo, sfp = (const struct nfsv3_fsinfo *)dp; ND_TCHECK_SIZE(sfp); ND_PRINT(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u", - EXTRACT_BE_U_4(&sfp->fs_rtmax), - EXTRACT_BE_U_4(&sfp->fs_rtpref), - EXTRACT_BE_U_4(&sfp->fs_wtmax), - EXTRACT_BE_U_4(&sfp->fs_wtpref), - EXTRACT_BE_U_4(&sfp->fs_dtpref)); + EXTRACT_BE_U_4(sfp->fs_rtmax), + EXTRACT_BE_U_4(sfp->fs_rtpref), + EXTRACT_BE_U_4(sfp->fs_wtmax), + EXTRACT_BE_U_4(sfp->fs_wtpref), + EXTRACT_BE_U_4(sfp->fs_dtpref)); if (ndo->ndo_vflag) { ND_PRINT(" rtmult %u wtmult %u maxfsz %" PRIu64, - EXTRACT_BE_U_4(&sfp->fs_rtmult), - EXTRACT_BE_U_4(&sfp->fs_wtmult), - EXTRACT_BE_U_8((const uint32_t *)&sfp->fs_maxfilesize)); + EXTRACT_BE_U_4(sfp->fs_rtmult), + EXTRACT_BE_U_4(sfp->fs_wtmult), + EXTRACT_BE_U_8(sfp->fs_maxfilesize)); ND_PRINT(" delta %u.%06u ", - EXTRACT_BE_U_4(&sfp->fs_timedelta.nfsv3_sec), - EXTRACT_BE_U_4(&sfp->fs_timedelta.nfsv3_nsec)); + EXTRACT_BE_U_4(sfp->fs_timedelta.nfsv3_sec), + EXTRACT_BE_U_4(sfp->fs_timedelta.nfsv3_nsec)); } return (1); trunc: @@ -1472,12 +1533,12 @@ parsepathconf(netdissect_options *ndo, ND_TCHECK_SIZE(spp); ND_PRINT(" linkmax %u namemax %u %s %s %s %s", - EXTRACT_BE_U_4(&spp->pc_linkmax), - EXTRACT_BE_U_4(&spp->pc_namemax), - EXTRACT_BE_U_4(&spp->pc_notrunc) ? "notrunc" : "", - EXTRACT_BE_U_4(&spp->pc_chownrestricted) ? "chownres" : "", - EXTRACT_BE_U_4(&spp->pc_caseinsensitive) ? "igncase" : "", - EXTRACT_BE_U_4(&spp->pc_casepreserving) ? "keepcase" : ""); + EXTRACT_BE_U_4(spp->pc_linkmax), + EXTRACT_BE_U_4(spp->pc_namemax), + EXTRACT_BE_U_4(spp->pc_notrunc) ? "notrunc" : "", + EXTRACT_BE_U_4(spp->pc_chownrestricted) ? "chownres" : "", + EXTRACT_BE_U_4(spp->pc_caseinsensitive) ? "igncase" : "", + EXTRACT_BE_U_4(spp->pc_casepreserving) ? "keepcase" : ""); return (1); trunc: return (0); @@ -1751,5 +1812,5 @@ interp_reply(netdissect_options *ndo, } trunc: if (!nfserr) - ND_PRINT("%s", tstr); + nd_print_trunc(ndo); }