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:
Guy Harris 2008-07-13 18:56:54 +00:00
parent e86825b8f8
commit a985d71ec1
2 changed files with 52 additions and 12 deletions

View File

@ -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,

View File

@ -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;