aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-roofnet.c
diff options
context:
space:
mode:
authorSimon Barber <simon.barber@meraki.net>2017-02-10 18:42:29 -0800
committerAnders Broman <a.broman58@gmail.com>2017-02-18 07:14:54 +0000
commit3d02987272d43c01cd506786c5068fdbe02e211e (patch)
tree5d2dfa2f3269470b431b40272e43ca914e8e3ed0 /epan/dissectors/packet-roofnet.c
parent35cf66d8bd2d225ab4dad39f5af5253ab6c8caa9 (diff)
roofnet: decode framed ethernet frames.
Change-Id: I4881bf8e16c75d34ff3421230b763803c1d2f43b Reviewed-on: https://code.wireshark.org/review/20055 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-roofnet.c')
-rw-r--r--epan/dissectors/packet-roofnet.c72
1 files changed, 52 insertions, 20 deletions
diff --git a/epan/dissectors/packet-roofnet.c b/epan/dissectors/packet-roofnet.c
index 23563f999b..7d19bd0587 100644
--- a/epan/dissectors/packet-roofnet.c
+++ b/epan/dissectors/packet-roofnet.c
@@ -43,13 +43,10 @@ static const value_string roofnet_pt_vals[] = {
};
/* roofnet flag bit masks */
-#define ROOFNET_FLAG_ERROR 0x01
-#define ROOFNET_FLAG_UPDATE 0x02
-static const value_string roofnet_flags_vals[] = {
- { ROOFNET_FLAG_ERROR, "Error" },
- { ROOFNET_FLAG_UPDATE, "Update" },
- { 0, NULL }
-};
+#define ROOFNET_FLAG_ERROR (1<<0)
+#define ROOFNET_FLAG_UPDATE (1<<1)
+#define ROOFNET_FLAG_LAYER2 (1<<9)
+#define ROOFNET_FLAG_MASK (ROOFNET_FLAG_ERROR | ROOFNET_FLAG_UPDATE | ROOFNET_FLAG_LAYER2)
/* header length */
#define ROOFNET_HEADER_LENGTH 160
@@ -76,6 +73,7 @@ void proto_register_roofnet(void);
void proto_reg_handoff_roofnet(void);
static dissector_handle_t ip_handle;
+static dissector_handle_t eth_withoutfcs_handle;
static int proto_roofnet = -1;
/* hf fields for the header of roofnet */
@@ -86,6 +84,9 @@ static int hf_roofnet_next = -1;
static int hf_roofnet_ttl = -1;
static int hf_roofnet_cksum = -1;
static int hf_roofnet_flags = -1;
+static int hf_roofnet_flags_error = -1;
+static int hf_roofnet_flags_update = -1;
+static int hf_roofnet_flags_layer2 = -1;
static int hf_roofnet_data_length = -1;
static int hf_roofnet_query_dst = -1;
static int hf_roofnet_seq = -1;
@@ -97,8 +98,16 @@ static int hf_roofnet_link_seq = -1;
static int hf_roofnet_link_age = -1;
static int hf_roofnet_link_dst = -1;
+static const int *flag_list[] = {
+ &hf_roofnet_flags_error,
+ &hf_roofnet_flags_update,
+ &hf_roofnet_flags_layer2,
+ NULL
+};
+
static gint ett_roofnet = -1;
+static gint ett_roofnet_flags = -1;
static gint ett_roofnet_link = -1;
static expert_field ei_roofnet_too_many_links = EI_INIT;
@@ -107,7 +116,7 @@ static expert_field ei_roofnet_too_much_data = EI_INIT;
/*
* dissect the header of roofnet
*/
-static void dissect_roofnet_header(proto_tree *tree, tvbuff_t *tvb, guint *offset)
+static guint16 dissect_roofnet_header(proto_tree *tree, tvbuff_t *tvb, guint *offset)
{
ptvcursor_t *cursor = ptvcursor_new(tree, tvb, *offset);
@@ -119,13 +128,18 @@ static void dissect_roofnet_header(proto_tree *tree, tvbuff_t *tvb, guint *offse
proto_tree_add_checksum(ptvcursor_tree(cursor), ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor),
hf_roofnet_cksum, -1, NULL, NULL, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
ptvcursor_advance(cursor, 2);
- ptvcursor_add(cursor, hf_roofnet_flags, 2, ENC_BIG_ENDIAN);
+ guint16 flags = tvb_get_ntohs(ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor));
+ proto_tree_add_bitmask(ptvcursor_tree(cursor), ptvcursor_tvbuff(cursor), ptvcursor_current_offset(cursor),
+ hf_roofnet_flags, ett_roofnet_flags, flag_list, ENC_BIG_ENDIAN);
+ ptvcursor_advance(cursor, 2);
ptvcursor_add(cursor, hf_roofnet_data_length, 2, ENC_BIG_ENDIAN);
ptvcursor_add(cursor, hf_roofnet_query_dst, 4, ENC_BIG_ENDIAN);
ptvcursor_add(cursor, hf_roofnet_seq, 4, ENC_BIG_ENDIAN);
*offset = ptvcursor_current_offset(cursor);
ptvcursor_free(cursor);
+
+ return flags;
}
/*
@@ -169,7 +183,7 @@ static void dissect_roofnet_link(proto_tree *tree, tvbuff_t *tvb, guint *offset,
/*
* dissect the data in roofnet
*/
-static void dissect_roofnet_data(proto_tree *tree, tvbuff_t *tvb, packet_info * pinfo, gint offset)
+static void dissect_roofnet_data(proto_tree *tree, tvbuff_t *tvb, packet_info * pinfo, gint offset, guint16 flags)
{
guint16 roofnet_datalen= 0;
guint16 remaining_datalen= 0;
@@ -187,8 +201,13 @@ static void dissect_roofnet_data(proto_tree *tree, tvbuff_t *tvb, packet_info *
if (roofnet_datalen == 0)
return;
- /* dissect ip payload */
- call_dissector(ip_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
+ /* dissect payload */
+ if (flags & ROOFNET_FLAG_LAYER2) {
+ /* ethernet frame is padded with 2 bytes at the start */
+ call_dissector(eth_withoutfcs_handle, tvb_new_subset_remaining(tvb, offset+2), pinfo, tree);
+ } else {
+ call_dissector(ip_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
+ }
}
@@ -215,7 +234,7 @@ static int dissect_roofnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
it = proto_tree_add_item(tree, proto_roofnet, tvb, offset, -1, ENC_NA);
roofnet_tree = proto_item_add_subtree(it, ett_roofnet);
- dissect_roofnet_header(roofnet_tree, tvb, &offset);
+ guint16 flags = dissect_roofnet_header(roofnet_tree, tvb, &offset);
roofnet_nlinks= tvb_get_guint8(tvb, ROOFNET_OFFSET_NLINKS);
/* Check that we do not have a malformed roofnet packet */
@@ -231,7 +250,7 @@ static int dissect_roofnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
dissect_roofnet_link(roofnet_tree, tvb, &offset, nlink++);
}
- dissect_roofnet_data(tree, tvb, pinfo, offset+4);
+ dissect_roofnet_data(tree, tvb, pinfo, offset+4, flags);
return tvb_captured_length(tvb);
}
@@ -271,7 +290,22 @@ void proto_register_roofnet(void)
{ &hf_roofnet_flags,
{ "Flags", "roofnet.flags",
- FT_UINT16, BASE_DEC, VALS(roofnet_flags_vals), 0x0, "Roofnet Flags", HFILL }
+ FT_UINT16, BASE_HEX, NULL, 0x0, "Roofnet flags", HFILL }
+ },
+
+ { &hf_roofnet_flags_error,
+ { "Roofnet Error", "roofnet.flags.error",
+ FT_BOOLEAN, 16, NULL, ROOFNET_FLAG_ERROR, NULL, HFILL }
+ },
+
+ { &hf_roofnet_flags_update,
+ { "Roofnet Update", "roofnet.flags.update",
+ FT_BOOLEAN, 16, NULL, ROOFNET_FLAG_UPDATE, NULL, HFILL }
+ },
+
+ { &hf_roofnet_flags_layer2,
+ { "Roofnet Layer 2", "roofnet.flags.layer2",
+ FT_BOOLEAN, 16, NULL, ROOFNET_FLAG_LAYER2, NULL, HFILL }
},
{ &hf_roofnet_data_length,
@@ -330,6 +364,7 @@ void proto_register_roofnet(void)
/* setup protocol subtree array */
static gint *ett[] = {
&ett_roofnet,
+ &ett_roofnet_flags,
&ett_roofnet_link
};
@@ -340,11 +375,7 @@ void proto_register_roofnet(void)
expert_module_t* expert_roofnet;
- proto_roofnet = proto_register_protocol(
- "Roofnet Protocol", /* Name */
- "Roofnet", /* Short Name */
- "roofnet" /* Abbrev */
- );
+ proto_roofnet = proto_register_protocol("Roofnet Protocol", "Roofnet","roofnet");
proto_register_field_array(proto_roofnet, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
@@ -360,6 +391,7 @@ void proto_reg_handoff_roofnet(void)
/* Until now there is no other option than having an IPv4 payload (maybe
* extended one day to IPv6 or other?) */
ip_handle = find_dissector_add_dependency("ip", proto_roofnet);
+ eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_roofnet);
roofnet_handle = create_dissector_handle(dissect_roofnet, proto_roofnet);
/* I did not put the type numbers in the ethertypes.h as they only are
* experimental and not official */