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.
ap->rerr_dc, length));
dp = (struct rerr_unreach *)(dat + sizeof(*ap));
i = length - sizeof(*ap);
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--) {
+ if (i < sizeof(*dp))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds)));
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;
ap->rerr_dc, length));
dp6 = (struct rerr_unreach6 *)(void *)(ap + 1);
i = length - sizeof(*ap);
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--) {
+ if (i < sizeof(*dp6))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
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;
ap->rerr_dc, length));
dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1);
i = length - sizeof(*ap);
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--) {
+ if (i < sizeof(*dp6))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
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;