X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/ee68aa36460d7efeca48747f33b7f2adc0900bfb..0023eaa78f123676bfa9c5fba72ea4b8a59aaa70:/print-nfs.c diff --git a/print-nfs.c b/print-nfs.c index a6755513..b67ec370 100644 --- a/print-nfs.c +++ b/print-nfs.c @@ -21,9 +21,7 @@ /* \summary: Network File System (NFS) printer */ -#ifdef HAVE_CONFIG_H #include -#endif #include "netdissect-stdinc.h" @@ -198,7 +196,7 @@ static const struct tok sunrpc_str[] = { }; static void -print_nfsaddr(netdissect_options *ndo, +nfsaddr_print(netdissect_options *ndo, const u_char *bp, const char *s, const char *d) { const struct ip *ip; @@ -209,14 +207,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, GET_IPADDR_STRING(ip->ip_src), sizeof(srcaddr)); + strlcpy(dstaddr, GET_IPADDR_STRING(ip->ip_dst), sizeof(dstaddr)); break; case 6: ip6 = (const struct ip6_hdr *)bp; - strlcpy(srcaddr, ip6addr_string(ndo, ip6->ip6_src), + strlcpy(srcaddr, GET_IP6ADDR_STRING(ip6->ip6_src), sizeof(srcaddr)); - strlcpy(dstaddr, ip6addr_string(ndo, ip6->ip6_dst), + strlcpy(dstaddr, GET_IP6ADDR_STRING(ip6->ip6_dst), sizeof(dstaddr)); break; default: @@ -260,58 +258,46 @@ static const uint32_t * parse_sattr3(netdissect_options *ndo, const uint32_t *dp, struct nfsv3_sattr *sa3) { - ND_TCHECK_4(dp); sa3->sa_modeset = GET_BE_U_4(dp); dp++; if (sa3->sa_modeset) { - ND_TCHECK_4(dp); sa3->sa_mode = GET_BE_U_4(dp); dp++; } - ND_TCHECK_4(dp); sa3->sa_uidset = GET_BE_U_4(dp); dp++; if (sa3->sa_uidset) { - ND_TCHECK_4(dp); sa3->sa_uid = GET_BE_U_4(dp); dp++; } - ND_TCHECK_4(dp); sa3->sa_gidset = GET_BE_U_4(dp); dp++; if (sa3->sa_gidset) { - ND_TCHECK_4(dp); sa3->sa_gid = GET_BE_U_4(dp); dp++; } - ND_TCHECK_4(dp); sa3->sa_sizeset = GET_BE_U_4(dp); dp++; if (sa3->sa_sizeset) { - ND_TCHECK_4(dp); sa3->sa_size = GET_BE_U_4(dp); dp++; } - ND_TCHECK_4(dp); sa3->sa_atimetype = GET_BE_U_4(dp); dp++; if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) { - ND_TCHECK_4(dp + 1); sa3->sa_atime.nfsv3_sec = GET_BE_U_4(dp); dp++; sa3->sa_atime.nfsv3_nsec = GET_BE_U_4(dp); dp++; } - ND_TCHECK_4(dp); sa3->sa_mtimetype = GET_BE_U_4(dp); dp++; if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) { - ND_TCHECK_4(dp + 1); sa3->sa_mtime.nfsv3_sec = GET_BE_U_4(dp); dp++; sa3->sa_mtime.nfsv3_nsec = GET_BE_U_4(dp); @@ -319,8 +305,6 @@ parse_sattr3(netdissect_options *ndo, } return dp; -trunc: - return NULL; } static void @@ -354,23 +338,18 @@ nfsreply_print(netdissect_options *ndo, ndo->ndo_protocol = "nfs"; rp = (const struct sunrpc_msg *)bp; - ND_TCHECK_4(rp->rm_xid); if (!ndo->ndo_nflag) { strlcpy(srcid, "nfs", sizeof(srcid)); - nd_snprintf(dstid, sizeof(dstid), "%u", + snprintf(dstid, sizeof(dstid), "%u", GET_BE_U_4(rp->rm_xid)); } else { - nd_snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); - nd_snprintf(dstid, sizeof(dstid), "%u", + snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); + snprintf(dstid, sizeof(dstid), "%u", GET_BE_U_4(rp->rm_xid)); } - print_nfsaddr(ndo, bp2, srcid, dstid); + nfsaddr_print(ndo, bp2, srcid, dstid); nfsreply_noaddr_print(ndo, bp, length, bp2); - return; - -trunc: - nd_print_trunc(ndo); } void @@ -452,8 +431,12 @@ parsereq(netdissect_options *ndo, dp = (const uint32_t *)&rp->rm_call.cb_cred; if (length < 2 * sizeof(*dp)) goto trunc; - ND_TCHECK_4(dp + 1); len = GET_BE_U_4(dp + 1); + if (len > length) { + ND_PRINT(" [credentials length %u > %u]", len, length); + nd_print_invalid(ndo); + return NULL; + } rounded_len = roundup2(len, 4); ND_TCHECK_LEN(dp + 2, rounded_len); if (2 * sizeof(*dp) + rounded_len <= length) { @@ -472,8 +455,12 @@ parsereq(netdissect_options *ndo, */ if (length < 2 * sizeof(*dp)) goto trunc; - ND_TCHECK_4(dp + 1); len = GET_BE_U_4(dp + 1); + if (len > length) { + ND_PRINT(" [verifier length %u > %u]", len, length); + nd_print_invalid(ndo); + return NULL; + } rounded_len = roundup2(len, 4); ND_TCHECK_LEN(dp + 2, rounded_len); if (2 * sizeof(*dp) + rounded_len < length) { @@ -502,7 +489,6 @@ parsefh(netdissect_options *ndo, u_int len; if (v3) { - ND_TCHECK_4(dp); len = GET_BE_U_4(dp) / 4; dp++; } else @@ -511,9 +497,8 @@ parsefh(netdissect_options *ndo, if (ND_TTEST_LEN(dp, len * sizeof(*dp))) { nfs_printfh(ndo, dp, len); return (dp + len); - } -trunc: - return (NULL); + } else + return NULL; } /* @@ -524,12 +509,9 @@ static const uint32_t * parsefn(netdissect_options *ndo, const uint32_t *dp) { - uint32_t len; + uint32_t len, rounded_len; const u_char *cp; - /* Bail if we don't have the string length */ - ND_TCHECK_4(dp); - /* Fetch big-endian string length */ len = GET_BE_U_4(dp); dp++; @@ -540,11 +522,12 @@ parsefn(netdissect_options *ndo, return NULL; } - ND_TCHECK_LEN(dp, ((len + 3) & ~3)); + rounded_len = roundup2(len, 4); + ND_TCHECK_LEN(dp, rounded_len); cp = (const u_char *)dp; /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ - dp += ((len + 3) & ~3) / sizeof(*dp); + dp += rounded_len / sizeof(*dp); ND_PRINT("\""); if (nd_printn(ndo, cp, len, ndo->ndo_snapend)) { ND_PRINT("\""); @@ -634,7 +617,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, dp = parsefh(ndo, dp, v3); if (dp == NULL) goto trunc; - ND_TCHECK_4(dp); access_flags = GET_BE_U_4(dp); if (access_flags & ~NFSV3ACCESS_FULL) { /* NFSV3ACCESS definitions aren't up to date */ @@ -676,12 +658,10 @@ nfsreq_noaddr_print(netdissect_options *ndo, if (dp == NULL) goto trunc; if (v3) { - ND_TCHECK_4(dp + 2); ND_PRINT(" %u bytes @ %" PRIu64, GET_BE_U_4(dp + 2), GET_BE_U_8(dp)); } else { - ND_TCHECK_4(dp + 1); ND_PRINT(" %u bytes @ %u", GET_BE_U_4(dp + 1), GET_BE_U_4(dp)); @@ -696,7 +676,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, if (dp == NULL) goto trunc; if (v3) { - ND_TCHECK_4(dp + 4); ND_PRINT(" %u (%u) bytes @ %" PRIu64, GET_BE_U_4(dp + 4), GET_BE_U_4(dp + 2), @@ -707,7 +686,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, NULL, GET_BE_U_4(dp + 3))); } } else { - ND_TCHECK_4(dp + 3); ND_PRINT(" %u (%u) bytes @ %u (%u)", GET_BE_U_4(dp + 3), GET_BE_U_4(dp + 2), @@ -739,7 +717,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, dp = parsefhn(ndo, dp, v3); if (dp == NULL) goto trunc; - ND_TCHECK_4(dp); type = (nfs_type) GET_BE_U_4(dp); dp++; dp = parse_sattr3(ndo, dp, &sa3); @@ -747,7 +724,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, goto trunc; 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", GET_BE_U_4(dp), GET_BE_U_4(dp + 1)); @@ -789,7 +765,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, if (dp == NULL) goto trunc; if (v3) { - ND_TCHECK_4(dp + 4); /* * We shouldn't really try to interpret the * offset cookie here. @@ -809,7 +784,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, GET_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. @@ -827,7 +801,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, dp = parsefh(ndo, dp, v3); if (dp == NULL) goto trunc; - ND_TCHECK_4(dp + 4); /* * We don't try to interpret the offset * cookie here. @@ -836,7 +809,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, GET_BE_U_4(dp + 4), GET_BE_U_8(dp)); if (ndo->ndo_vflag) { - ND_TCHECK_4(dp + 5); /* * This displays the 8 bytes * of the verifier in order, @@ -857,7 +829,6 @@ nfsreq_noaddr_print(netdissect_options *ndo, dp = parsefh(ndo, dp, v3); if (dp == NULL) goto trunc; - ND_TCHECK_4(dp + 2); ND_PRINT(" %u bytes @ %" PRIu64, GET_BE_U_4(dp + 2), GET_BE_U_8(dp)); @@ -933,17 +904,19 @@ nfs_printfh(netdissect_options *ndo, if (spacep) *spacep = '\0'; - ND_PRINT(" fh %s/", temp); + ND_PRINT(" fh "); + fn_print_str(ndo, (const u_char *)temp); + ND_PRINT("/"); } else { ND_PRINT(" fh %u,%u/", fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor); } - if(fsid.Fsid_dev.Minor == 257) + if(fsid.Fsid_dev.Minor == UINT_MAX && fsid.Fsid_dev.Major == UINT_MAX) /* Print the undecoded handle */ - ND_PRINT("%s", fsid.Opaque_Handle); + fn_print_str(ndo, (const u_char *)fsid.Opaque_Handle); else - ND_PRINT("%ld", (long) ino); + ND_PRINT("%u", ino); } /* @@ -955,8 +928,8 @@ nfs_printfh(netdissect_options *ndo, struct xid_map_entry { uint32_t xid; /* transaction ID (net order) */ int ipver; /* IP version (4 or 6) */ - struct in6_addr client; /* client IP address (net order) */ - struct in6_addr server; /* server IP address (net order) */ + nd_ipv6 client; /* client IP address (net order) */ + nd_ipv6 server; /* server IP address (net order) */ uint32_t proc; /* call proc number (host order) */ uint32_t vers; /* program version (host order) */ }; @@ -1007,8 +980,7 @@ xid_map_enter(netdissect_options *ndo, sizeof(ip->ip_src)); UNALIGNED_MEMCPY(&xmep->server, ip->ip_dst, sizeof(ip->ip_dst)); - } - else if (ip6) { + } else if (ip6) { xmep->ipver = 6; UNALIGNED_MEMCPY(&xmep->client, ip6->ip6_src, sizeof(ip6->ip6_src)); @@ -1112,7 +1084,6 @@ parserep(netdissect_options *ndo, * which is an "enum" and so occupies one 32-bit word. */ dp = ((const uint32_t *)&rp->rm_reply) + 1; - ND_TCHECK_4(dp + 1); len = GET_BE_U_4(dp + 1); if (len >= length) return (NULL); @@ -1124,7 +1095,6 @@ parserep(netdissect_options *ndo, /* * now we can check the ar_stat field */ - ND_TCHECK_4(dp); astat = (enum sunrpc_accept_stat) GET_BE_U_4(dp); if (astat != SUNRPC_SUCCESS) { ND_PRINT(" %s", tok2str(sunrpc_str, "ar_stat %u", astat)); @@ -1144,8 +1114,6 @@ parsestatus(netdissect_options *ndo, { u_int errnum; - ND_TCHECK_4(dp); - errnum = GET_BE_U_4(dp); if (er) *er = errnum; @@ -1156,8 +1124,6 @@ parsestatus(netdissect_options *ndo, *nfserrp = 1; } return (dp + 1); -trunc: - return NULL; } static const uint32_t * @@ -1182,11 +1148,9 @@ parsefattr(netdissect_options *ndo, GET_BE_S_4(fap->fa_uid), GET_BE_S_4(fap->fa_gid)); if (v3) { - ND_TCHECK_8(fap->fa3_size); ND_PRINT(" sz %" PRIu64, GET_BE_U_8(fap->fa3_size)); } else { - ND_TCHECK_4(fap->fa2_size); ND_PRINT(" sz %u", GET_BE_U_4(fap->fa2_size)); } } @@ -1357,15 +1321,12 @@ parserddires(netdissect_options *ndo, if (ndo->ndo_qflag) return (1); - ND_TCHECK_4(dp + 2); ND_PRINT(" offset 0x%x size %u ", GET_BE_U_4(dp), GET_BE_U_4(dp + 1)); if (GET_BE_U_4(dp + 2) != 0) ND_PRINT(" eof"); return (1); -trunc: - return (0); } static const uint32_t * @@ -1387,7 +1348,6 @@ static const uint32_t * parse_pre_op_attr(netdissect_options *ndo, const uint32_t *dp, int verbose) { - ND_TCHECK_4(dp); if (!GET_BE_U_4(dp)) return (dp + 1); dp++; @@ -1409,7 +1369,6 @@ static const uint32_t * parse_post_op_attr(netdissect_options *ndo, const uint32_t *dp, int verbose) { - ND_TCHECK_4(dp); if (!GET_BE_U_4(dp)) return (dp + 1); dp++; @@ -1417,8 +1376,6 @@ parse_post_op_attr(netdissect_options *ndo, return parsefattr(ndo, dp, verbose, 1); } else return (dp + (NFSX_V3FATTR / sizeof (uint32_t))); -trunc: - return (NULL); } static const uint32_t * @@ -1448,7 +1405,6 @@ parsecreateopres(netdissect_options *ndo, if (er) dp = parse_wcc_data(ndo, dp, verbose); else { - ND_TCHECK_4(dp); if (!GET_BE_U_4(dp)) return (dp + 1); dp++; @@ -1466,8 +1422,6 @@ parsecreateopres(netdissect_options *ndo, } } return (dp); -trunc: - return (NULL); } static const uint32_t * @@ -1499,7 +1453,6 @@ parsev3rddirres(netdissect_options *ndo, if (er) return dp; if (ndo->ndo_vflag) { - ND_TCHECK_4(dp + 1); /* * This displays the 8 bytes of the verifier in order, * from the low-order byte to the high-order byte. @@ -1509,8 +1462,6 @@ parsev3rddirres(netdissect_options *ndo, dp += 2; } return dp; -trunc: - return (NULL); } static int @@ -1617,7 +1568,7 @@ interp_reply(netdissect_options *ndo, if (dp == NULL) goto trunc; if (v3) { - if (parsewccres(ndo, dp, ndo->ndo_vflag, &nfserr) == 0) + if (parsewccres(ndo, dp, ndo->ndo_vflag, &nfserr) == NULL) goto trunc; } else { if (parseattrstat(ndo, dp, !ndo->ndo_qflag, 0, &nfserr) == 0) @@ -1673,7 +1624,6 @@ interp_reply(netdissect_options *ndo, if (dp == NULL) goto trunc; if (!er) { - ND_TCHECK_4(dp); ND_PRINT(" c %04x", GET_BE_U_4(dp)); } break; @@ -1699,7 +1649,6 @@ interp_reply(netdissect_options *ndo, goto trunc; if (!er) { if (ndo->ndo_vflag) { - ND_TCHECK_4(dp + 1); ND_PRINT(" %u bytes", GET_BE_U_4(dp)); if (GET_BE_U_4(dp + 1)) ND_PRINT(" EOF"); @@ -1724,16 +1673,13 @@ interp_reply(netdissect_options *ndo, goto trunc; if (!er) { if (ndo->ndo_vflag) { - ND_TCHECK_4(dp); ND_PRINT(" %u bytes", GET_BE_U_4(dp)); if (ndo->ndo_vflag > 1) { - ND_TCHECK_4(dp + 1); ND_PRINT(" <%s>", tok2str(nfsv3_writemodes, NULL, GET_BE_U_4(dp + 1))); /* write-verf-cookie */ - ND_TCHECK_8(dp + 2); ND_PRINT(" verf %" PRIx64, GET_BE_U_8(dp + 2)); } @@ -1898,7 +1844,6 @@ interp_reply(netdissect_options *ndo, goto trunc; if (ndo->ndo_vflag > 1) { /* write-verf-cookie */ - ND_TCHECK_8(dp); ND_PRINT(" verf %" PRIx64, GET_BE_U_8(dp)); } break;