diff options
author | Simon Barber <simon.barber@meraki.net> | 2017-02-10 18:42:29 -0800 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2017-02-18 07:14:54 +0000 |
commit | 3d02987272d43c01cd506786c5068fdbe02e211e (patch) | |
tree | 5d2dfa2f3269470b431b40272e43ca914e8e3ed0 /epan/dissectors/packet-roofnet.c | |
parent | 35cf66d8bd2d225ab4dad39f5af5253ab6c8caa9 (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.c | 72 |
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 */ |