aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-eth.c
diff options
context:
space:
mode:
authorSake Blok <sake@euronet.nl>2013-06-01 09:05:56 +0000
committerSake Blok <sake@euronet.nl>2013-06-01 09:05:56 +0000
commitb2a6a6c15cd059bbf5ce83faaf611974f16158be (patch)
tree1c22f4f4cd449c0bbb37449a8ea180a588dffa0b /epan/dissectors/packet-eth.c
parent9c4488cedf94517f65d8b0714ad4b1a140b96244 (diff)
Add ethernet protocol preference to manually set the trailer length.
(some TAPs can slice packets and then add a custom trailer) svn path=/trunk/; revision=49675
Diffstat (limited to 'epan/dissectors/packet-eth.c')
-rw-r--r--epan/dissectors/packet-eth.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/epan/dissectors/packet-eth.c b/epan/dissectors/packet-eth.c
index 77c79703b3..b605bc03bd 100644
--- a/epan/dissectors/packet-eth.c
+++ b/epan/dissectors/packet-eth.c
@@ -45,6 +45,7 @@ void proto_reg_handoff_eth(void);
/* Assume all packets have an FCS */
static gboolean eth_assume_padding = TRUE;
+static guint eth_trailer_length = 0;
static gboolean eth_assume_fcs = FALSE;
static gboolean eth_check_fcs = TRUE;
/* Interpret packets as FW1 monitor file packets if they look as if they are */
@@ -207,7 +208,7 @@ capture_eth(const guchar *pd, int offset, int len, packet_counts *ld)
static gboolean check_is_802_2(tvbuff_t *tvb, int fcs_len);
-static void
+static proto_tree *
dissect_eth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
int fcs_len)
{
@@ -252,7 +253,7 @@ dissect_eth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
* Ethernet packet.
*/
if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, parent_tree, NULL))
- return;
+ return fh_tree;
if (ehdr->type <= IEEE_802_3_MAX_LEN) {
/* Oh, yuck. Cisco ISL frames require special interpretation of the
@@ -266,7 +267,7 @@ dissect_eth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
tvb_get_guint8(tvb, 3) == 0x00 &&
tvb_get_guint8(tvb, 4) == 0x00) {
dissect_isl(tvb, pinfo, parent_tree, fcs_len);
- return;
+ return fh_tree;
}
}
@@ -319,7 +320,7 @@ dissect_eth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
"Invalid length/type: 0x%04x (%d)", ehdr->type, ehdr->type);
next_tvb = tvb_new_subset_remaining(tvb, 14);
call_dissector(data_handle, next_tvb, pinfo, parent_tree);
- return;
+ return fh_tree;
}
if (ehdr->type <= IEEE_802_3_MAX_LEN && ehdr->type != ETHERTYPE_UNK) {
@@ -367,7 +368,7 @@ dissect_eth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
if ((dst_addr[0] == 'i') || (dst_addr[0] == 'I') ||
(dst_addr[0] == 'o') || (dst_addr[0] == 'O')) {
call_dissector(fw1_handle, tvb, pinfo, parent_tree);
- return;
+ return fh_tree;
}
}
@@ -407,6 +408,7 @@ dissect_eth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
ethertype(ehdr->type, tvb, ETH_HEADER_SIZE, pinfo, parent_tree, fh_tree, hf_eth_type,
hf_eth_trailer, fcs_len);
}
+ return fh_tree;
}
/* -------------- */
@@ -663,9 +665,33 @@ add_ethernet_trailer(packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
static void
dissect_eth_maybefcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- dissect_eth_common(tvb, pinfo, tree,
- eth_assume_fcs ? 4 :
- pinfo->pseudo_header->eth.fcs_len);
+ proto_tree *fh_tree;
+
+ /* Some devices slice the packet and add their own trailer before
+ putting the frame on the network. Make sure these packets get
+ a proper trailer (even though the sliced frame might not
+ properly dissect. */
+ if ( (eth_trailer_length > 0) && (eth_trailer_length < tvb_length(tvb)) ) {
+ tvbuff_t *next_tvb;
+ guint total_trailer_length;
+
+ total_trailer_length = eth_trailer_length + (eth_assume_fcs ? 4 : 0);
+
+ /* Dissect the tvb up to, but not including the trailer */
+ next_tvb = tvb_new_subset(tvb, 0,
+ tvb_length(tvb) - total_trailer_length,
+ tvb_reported_length(tvb) - total_trailer_length);
+ fh_tree = dissect_eth_common(next_tvb, pinfo, tree, 0);
+
+ /* Now handle the ethernet trailer and optional FCS */
+ if ( fh_tree != NULL ) {
+ next_tvb = tvb_new_subset_remaining(tvb, tvb_length(tvb) - total_trailer_length);
+ add_ethernet_trailer(pinfo, tree, fh_tree, hf_eth_trailer, tvb, next_tvb,
+ eth_assume_fcs ? 4 : pinfo->pseudo_header->eth.fcs_len);
+ }
+ } else {
+ dissect_eth_common(tvb, pinfo, tree, eth_assume_fcs ? 4 : pinfo->pseudo_header->eth.fcs_len);
+ }
}
/* Called by other dissectors This one's for encapsulated Ethernet
@@ -781,6 +807,13 @@ proto_register_eth(void)
"before the frame was padded.",
&eth_assume_padding);
+ prefs_register_uint_preference(eth_module, "trailer_length",
+ "Fixed ethernet trailer length",
+ "Some TAPs add a fixed length ethernet trailer at the end "
+ "of the frame, but before the (optional) FCS. Make sure it "
+ "gets interpreted correctly.",
+ 10, &eth_trailer_length);
+
prefs_register_bool_preference(eth_module, "assume_fcs",
"Assume packets have FCS",
"Some Ethernet adapters and drivers include the FCS at the end of a packet, others do not. "