forked from osmocom/wireshark
If we know that an Ethernet packet includes the FCS, remove the FCS from
the payload we hand to the next dissector. Check whether the length field in an 802.3 header doesn't go past the (presumed) end of the payload. svn path=/trunk/; revision=25731
This commit is contained in:
parent
e86825b8f8
commit
a985d71ec1
|
@ -187,8 +187,9 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
|
|||
int etype_id, int trailer_id, int fcs_len)
|
||||
{
|
||||
const char *description;
|
||||
tvbuff_t *next_tvb;
|
||||
tvbuff_t *volatile next_tvb;
|
||||
guint length_before;
|
||||
gint captured_length, reported_length;
|
||||
volatile gboolean dissector_found = FALSE;
|
||||
const char *saved_proto;
|
||||
|
||||
|
@ -198,14 +199,34 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
|
|||
offset_after_etype - 2, 2, etype);
|
||||
}
|
||||
|
||||
/* Tvbuff for the payload after the Ethernet type. */
|
||||
next_tvb = tvb_new_subset(tvb, offset_after_etype, -1, -1);
|
||||
/* Get the captured length and reported length of the data
|
||||
after the Ethernet type. */
|
||||
captured_length = tvb_length_remaining(tvb, offset_after_etype);
|
||||
reported_length = tvb_reported_length_remaining(tvb,
|
||||
offset_after_etype);
|
||||
|
||||
/* Remember how much data there is after the Ethernet type,
|
||||
including any trailer and FCS. */
|
||||
length_before = reported_length;
|
||||
|
||||
/* Construct a tvbuff for the payload after the Ethernet type.
|
||||
If the FCS length is positive, remove the FCS.
|
||||
(If it's zero, there's no FCS; if it's negative,
|
||||
we don't know whether there's an FCS, so we'll
|
||||
guess based on the length of the trailer.) */
|
||||
if (fcs_len > 0) {
|
||||
if (captured_length >= 0 && reported_length >= 0) {
|
||||
if (reported_length >= fcs_len)
|
||||
reported_length -= fcs_len;
|
||||
if (captured_length > reported_length)
|
||||
captured_length = reported_length;
|
||||
}
|
||||
}
|
||||
next_tvb = tvb_new_subset(tvb, offset_after_etype, captured_length,
|
||||
reported_length);
|
||||
|
||||
pinfo->ethertype = etype;
|
||||
|
||||
/* Remember how much data there is in it. */
|
||||
length_before = tvb_reported_length(next_tvb);
|
||||
|
||||
/* Look for sub-dissector, and call it if found.
|
||||
Catch exceptions, so that if the reported length of "next_tvb"
|
||||
was reduced by some dissector before an exception was thrown,
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/expert.h>
|
||||
#include "packet-ieee8023.h"
|
||||
#include "packet-eth.h"
|
||||
#include "packet-frame.h"
|
||||
|
@ -36,21 +37,39 @@ static dissector_handle_t ipx_handle;
|
|||
static dissector_handle_t llc_handle;
|
||||
|
||||
void
|
||||
dissect_802_3(int length, gboolean is_802_2, tvbuff_t *tvb,
|
||||
dissect_802_3(volatile int length, gboolean is_802_2, tvbuff_t *tvb,
|
||||
int offset_after_length, packet_info *pinfo, proto_tree *tree,
|
||||
proto_tree *fh_tree, int length_id, int trailer_id,
|
||||
int fcs_len)
|
||||
{
|
||||
proto_item *length_it;
|
||||
tvbuff_t *volatile next_tvb = NULL;
|
||||
tvbuff_t *volatile trailer_tvb = NULL;
|
||||
const char *saved_proto;
|
||||
gint captured_length;
|
||||
gint captured_length, reported_length;
|
||||
|
||||
if (fh_tree)
|
||||
proto_tree_add_uint(fh_tree, length_id, tvb, offset_after_length - 2, 2,
|
||||
length);
|
||||
length_it = proto_tree_add_uint(fh_tree, length_id, tvb,
|
||||
offset_after_length - 2, 2, length);
|
||||
|
||||
/* Give the next dissector only 'length' number of bytes */
|
||||
/* Get the length of the payload.
|
||||
If the FCS length is positive, remove the FCS.
|
||||
(If it's zero, there's no FCS; if it's negative, we don't know whether
|
||||
there's an FCS, so we'll guess based on the length of the trailer.) */
|
||||
reported_length = tvb_reported_length_remaining(tvb, offset_after_length);
|
||||
if (fcs_len > 0) {
|
||||
if (reported_length >= fcs_len)
|
||||
reported_length -= fcs_len;
|
||||
}
|
||||
|
||||
/* Make sure the length in the 802.3 header doesn't go past the end of
|
||||
the payload. */
|
||||
if (length > reported_length) {
|
||||
length = reported_length;
|
||||
expert_add_info_format(pinfo, length_it, PI_MALFORMED, PI_ERROR,
|
||||
"Length field value goes past the end of the payload");
|
||||
}
|
||||
|
||||
/* Give the next dissector only 'length' number of bytes. */
|
||||
captured_length = tvb_length_remaining(tvb, offset_after_length);
|
||||
if (captured_length > length)
|
||||
captured_length = length;
|
||||
|
|
Loading…
Reference in New Issue