diff options
author | Guy Harris <guy@alum.mit.edu> | 2019-04-22 23:48:45 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2019-04-22 23:49:02 -0700 |
commit | b7b72b7c6335fb22b712688b144a538be4ae96e9 (patch) | |
tree | e8ccc9d70c44e0059bbf6be7126a7e488abcc8cb /netdissect.c | |
parent | 36f7997806c3857f3200fc2adc335f23e0e95223 (diff) | |
download | tcpdump-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 'netdissect.c')
-rw-r--r-- | netdissect.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/netdissect.c b/netdissect.c index 60c0a750..15594de8 100644 --- a/netdissect.c +++ b/netdissect.c @@ -151,40 +151,65 @@ int nd_push_buffer(netdissect_options *ndo, u_char *new_buffer, const u_char *new_packetp, const u_char *new_snapend) { - struct netdissect_saved_info *ndsi; + struct netdissect_saved_packet_info *ndspi; - ndsi = (struct netdissect_saved_info *)malloc(sizeof(struct netdissect_saved_info)); - if (ndsi == NULL) + ndspi = (struct netdissect_saved_packet_info *)malloc(sizeof(struct netdissect_saved_packet_info)); + if (ndspi == NULL) return (0); /* fail */ - ndsi->ndsi_buffer = new_buffer; - ndsi->ndsi_packetp = ndo->ndo_packetp; - ndsi->ndsi_snapend = ndo->ndo_snapend; - ndsi->ndsi_prev = ndo->ndo_buffer_stack; + ndspi->ndspi_buffer = new_buffer; + ndspi->ndspi_packetp = ndo->ndo_packetp; + ndspi->ndspi_snapend = ndo->ndo_snapend; + ndspi->ndspi_prev = ndo->ndo_packet_info_stack; ndo->ndo_packetp = new_packetp; ndo->ndo_snapend = new_snapend; - ndo->ndo_buffer_stack = ndsi; + ndo->ndo_packet_info_stack = ndspi; + + return (1); /* success */ +} + +/* + * Set a new snapshot end to the minimum of the existing snapshot end + * and the new snapshot end. + */ +int +nd_push_snapend(netdissect_options *ndo, const u_char *new_snapend) +{ + struct netdissect_saved_packet_info *ndspi; + + ndspi = (struct netdissect_saved_packet_info *)malloc(sizeof(struct netdissect_saved_packet_info)); + if (ndspi == NULL) + return (0); /* fail */ + ndspi->ndspi_buffer = NULL; /* no new buffer */ + ndspi->ndspi_packetp = ndo->ndo_packetp; + ndspi->ndspi_snapend = ndo->ndo_snapend; + ndspi->ndspi_prev = ndo->ndo_packet_info_stack; + + /* No new packet pointer, either */ + if (new_snapend < ndo->ndo_snapend) + ndo->ndo_snapend = new_snapend; + ndo->ndo_packet_info_stack = ndspi; return (1); /* success */ } void -nd_pop_buffer(netdissect_options *ndo) +nd_pop_packet_info(netdissect_options *ndo) { - struct netdissect_saved_info *ndsi; + struct netdissect_saved_packet_info *ndspi; - ndsi = ndo->ndo_buffer_stack; - ndo->ndo_packetp = ndsi->ndsi_packetp; - ndo->ndo_snapend = ndsi->ndsi_snapend; - ndo->ndo_buffer_stack = ndsi->ndsi_prev; + ndspi = ndo->ndo_packet_info_stack; + ndo->ndo_packetp = ndspi->ndspi_packetp; + ndo->ndo_snapend = ndspi->ndspi_snapend; + ndo->ndo_packet_info_stack = ndspi->ndspi_prev; - free(ndsi->ndsi_buffer); - free(ndsi); + free(ndspi->ndspi_buffer); + free(ndspi); } void -nd_pop_all_buffers(netdissect_options *ndo) +nd_pop_all_packet_info(netdissect_options *ndo) { - while (ndo->ndo_buffer_stack != NULL) - nd_pop_buffer(ndo); + while (ndo->ndo_packet_info_stack != NULL) + nd_pop_packet_info(ndo); } |