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>
This commit is contained in:
parent
35cf66d8bd
commit
3d02987272
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue