From: Guy Harris Date: Wed, 12 Nov 2014 09:09:27 +0000 (-0800) Subject: Report a too-long unreachable destination list. X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/c33ee7ff380c77ec2c0dbd8fceeb16cc41c618d0 Report a too-long unreachable destination list. Running out of packet length before running out of unreachable destinations is an error; report it as such. Don't worry about leftover data past the end of the list of unreachable destinations. --- diff --git a/print-aodv.c b/print-aodv.c index 9b3523a5..ef27eee6 100644 --- a/print-aodv.c +++ b/print-aodv.c @@ -277,14 +277,15 @@ aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length) ap->rerr_dc, length)); dp = (struct rerr_unreach *)(dat + sizeof(*ap)); i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp); - ++dp, --dc, i -= sizeof(*dp)) { + for (dc = ap->rerr_dc; dc != 0; dc--) { ND_TCHECK(*dp); + if (i < sizeof(*dp)) + goto trunc; ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da), (unsigned long)EXTRACT_32BITS(&dp->u_ds))); + dp++; + i -= sizeof(*dp); } - if ((i % sizeof(*dp)) != 0) - goto trunc; return; trunc: @@ -386,14 +387,15 @@ aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length) ap->rerr_dc, length)); dp6 = (struct rerr_unreach6 *)(void *)(ap + 1); i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6); - ++dp6, --dc, i -= sizeof(*dp6)) { + for (dc = ap->rerr_dc; dc != 0; dc--) { ND_TCHECK(*dp6); + if (i < sizeof(*dp6)) + goto trunc; ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); + dp6++; + i -= sizeof(*dp6); } - if ((i % sizeof(*dp6)) != 0) - goto trunc; return; trunc: @@ -498,14 +500,15 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int leng ap->rerr_dc, length)); dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1); i = length - sizeof(*ap); - for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6); - ++dp6, --dc, i -= sizeof(*dp6)) { + for (dc = ap->rerr_dc; dc != 0; dc--) { ND_TCHECK(*dp6); + if (i < sizeof(*dp6)) + goto trunc; ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da), (unsigned long)EXTRACT_32BITS(&dp6->u_ds))); + dp6++; + i -= sizeof(*dp6); } - if ((i % sizeof(*dp6)) != 0) - goto trunc; return; trunc: