summaryrefslogtreecommitdiff
path: root/print-ip6.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-04-22 23:48:45 -0700
committerGuy Harris <guy@alum.mit.edu>2019-04-22 23:49:02 -0700
commitb7b72b7c6335fb22b712688b144a538be4ae96e9 (patch)
treee8ccc9d70c44e0059bbf6be7126a7e488abcc8cb /print-ip6.c
parent36f7997806c3857f3200fc2adc335f23e0e95223 (diff)
downloadtcpdump-b7b72b7c6335fb22b712688b144a538be4ae96e9.tar.gz
Treat the length field in an Ethernet header as such.
If we have an Ethernet packet where the last 2 octets of the header are a length rather than an Ethernet type, and it's less than the remaining length of the packet, shorten the length and captured length, update the snapshot end. Turn the buffer stack into a "packet information" stack, so that, if we *do* update the snapshot end, we push the old end onto the stack, and pop it off as soon as we're done dissecting the Ethernet packet, in case there's more data in the packet after the Ethernet packet. Use the stack when we use the IPv4 and IPv6 length fields as well.
Diffstat (limited to 'print-ip6.c')
-rw-r--r--print-ip6.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/print-ip6.c b/print-ip6.c
index 37a17cc8..a9a18faf 100644
--- a/print-ip6.c
+++ b/print-ip6.c
@@ -231,7 +231,6 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
const struct ip6_hdr *ip6;
int advance;
u_int len;
- const u_char *ipend;
const u_char *cp;
u_int payload_len;
uint8_t nh;
@@ -289,9 +288,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
/*
* Cut off the snapshot length to the end of the IP payload.
*/
- ipend = bp + len;
- if (ipend < ndo->ndo_snapend)
- ndo->ndo_snapend = ipend;
+ nd_push_snapend(ndo, bp + len);
cp = (const u_char *)ip6;
advance = sizeof(struct ip6_hdr);
@@ -313,22 +310,28 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
case IPPROTO_HOPOPTS:
advance = hbhopt_print(ndo, cp);
- if (advance < 0)
+ if (advance < 0) {
+ nd_pop_packet_info(ndo);
return;
+ }
nh = GET_U_1(cp);
break;
case IPPROTO_DSTOPTS:
advance = dstopt_print(ndo, cp);
- if (advance < 0)
+ if (advance < 0) {
+ nd_pop_packet_info(ndo);
return;
+ }
nh = GET_U_1(cp);
break;
case IPPROTO_FRAGMENT:
advance = frag6_print(ndo, cp, (const u_char *)ip6);
- if (advance < 0 || ndo->ndo_snapend <= cp + advance)
+ if (advance < 0 || ndo->ndo_snapend <= cp + advance) {
+ nd_pop_packet_info(ndo);
return;
+ }
nh = GET_U_1(cp);
fragmented = 1;
break;
@@ -344,16 +347,21 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
* mobility header.
*/
advance = mobility_print(ndo, cp, (const u_char *)ip6);
- if (advance < 0)
+ if (advance < 0) {
+ nd_pop_packet_info(ndo);
return;
+ }
nh = GET_U_1(cp);
+ nd_pop_packet_info(ndo);
return;
case IPPROTO_ROUTING:
ND_TCHECK_1(cp);
advance = rt6_print(ndo, cp, (const u_char *)ip6);
- if (advance < 0)
+ if (advance < 0) {
+ nd_pop_packet_info(ndo);
return;
+ }
nh = GET_U_1(cp);
break;
@@ -364,6 +372,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
*/
ip_print_demux(ndo, cp, len, 6, fragmented,
GET_U_1(ip6->ip6_hlim), nh, bp);
+ nd_pop_packet_info(ndo);
return;
}
@@ -371,6 +380,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
ndo->ndo_protocol = "ip6";
}
+ nd_pop_packet_info(ndo);
return;
trunc:
nd_print_trunc(ndo);