aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-gmhdr.c
diff options
context:
space:
mode:
authorwmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7>2010-06-20 21:18:48 +0000
committerwmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7>2010-06-20 21:18:48 +0000
commit343ade52c608ddce0349a4951d5c8350a1a7256f (patch)
tree90b575feea058316032a28059d78623364cd714a /epan/dissectors/packet-gmhdr.c
parentf2be40bd1fda03b154bc6d2ac68c3e96099e417b (diff)
More rework of the code:
- Refactor to use a separate function for common code; - Prefs callback not required; - Use val_to_str(...); - Fix issues relating to incorrect bytes highlighted in the hex view; git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@33271 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-gmhdr.c')
-rw-r--r--epan/dissectors/packet-gmhdr.c224
1 files changed, 86 insertions, 138 deletions
diff --git a/epan/dissectors/packet-gmhdr.c b/epan/dissectors/packet-gmhdr.c
index 36512218ef..b7ceaff28f 100644
--- a/epan/dissectors/packet-gmhdr.c
+++ b/epan/dissectors/packet-gmhdr.c
@@ -39,6 +39,12 @@
#define GMHDR_FTYPE_TIMESTAMP_NTP 4
#define GMHDR_FTYPE_TIMESTAMP_EXT 5
+static const value_string gmhdr_ftype_timestamp[] = {
+ { GMHDR_FTYPE_TIMESTAMP_LOCAL, "Local" },
+ { GMHDR_FTYPE_TIMESTAMP_NTP, "NTP" },
+ { GMHDR_FTYPE_TIMESTAMP_EXT, "External" }
+};
+
#define GMHDR_SRCPORT_PLFM_MASK 0x00f80000
#define GMHDR_SRCPORT_GID_MASK 0x00078000
#define GMHDR_SRCPORT_BID_MASK 0x00007c00
@@ -54,8 +60,6 @@ static const value_string gmhdr_plfm_str[] = {
{ 0, NULL }
};
-void proto_reg_handoff_gmhdr(void);
-
static gboolean gmhdr_summary_in_tree = TRUE;
static int proto_gmhdr = -1;
@@ -74,83 +78,83 @@ static int hf_gmhdr_trailer = -1;
static gint ett_gmhdr = -1;
static gint ett_srcport = -1;
+
+
+static void
+dissect_gmtlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *gmhdr_tree, guint offset, guint16 length)
+{
+ proto_tree *ti;
+ proto_tree *srcport_tree;
+ guint16 fl;
+
+ while (length > 1) {
+ guint16 tl = tvb_get_ntohs(tvb, offset);
+ offset += 2; /* type + len */
+ length -= 2;
+
+ fl = tl & 0xff;
+ switch (tl >> 8) {
+ case GMHDR_FTYPE_SRCPORT: {
+ guint16 pid;
+ guint32 tv = tvb_get_ntohl(tvb, offset) >> 8; /* Only 24-bit field */
+ ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_srcport, tvb, offset, fl, FALSE);
+ srcport_tree = proto_item_add_subtree(ti, ett_srcport);
+ proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_plfm, tvb, offset, fl, FALSE);
+ proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_gid, tvb, offset, fl, FALSE);
+ proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_bid, tvb, offset, fl, FALSE);
+ ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_pid, tvb, offset, fl, FALSE);
+ /* If not GV-2404, we need different formula here */
+ pid = ((tv & GMHDR_SRCPORT_PID_MASK) >> GMHDR_SRCPORT_PID_SHFT) - 24;
+ if (pid >= 1 && pid <= 4) {
+ proto_item_append_text(ti, " (g%d)", pid);
+ }
+ break;
+ }
+ case GMHDR_FTYPE_PKTSIZE:
+ proto_tree_add_item(gmhdr_tree, hf_gmhdr_pktsize, tvb, offset, fl, FALSE);
+ break;
+ case GMHDR_FTYPE_TIMESTAMP_LOCAL:
+ case GMHDR_FTYPE_TIMESTAMP_NTP:
+ case GMHDR_FTYPE_TIMESTAMP_EXT:
+ ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_timestamp, tvb, offset, fl, FALSE);
+ proto_item_append_text(ti, "; Source: %s", val_to_str(tl>>8, gmhdr_ftype_timestamp, "Unknown"));
+ break;
+ default:
+ ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_generic, tvb, offset, fl, FALSE);
+ proto_item_append_text(ti, " [Id: %u, Length: %u]", tl >> 8, fl);
+ break;
+ }
+ /* Adjust for the field length */
+ offset += fl;
+ length -= fl;
+ }
+}
+
+
+
static void
dissect_gmhdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *ti;
gint16 length;
- guint16 fl;
volatile guint16 encap_proto;
volatile gboolean is_802_2;
- proto_tree *volatile gmhdr_tree;
- proto_tree *srcport_tree;
- unsigned offset = 0;
+ proto_tree *volatile gmhdr_tree = NULL;
+ guint offset = 0;
- length = tvb_get_guint8(tvb, offset); /* This is length of Gigamon header */
-
- gmhdr_tree = NULL;
+ length = tvb_get_guint8(tvb, offset); /* Length of the Gigamon header */
if (tree) {
- ti = proto_tree_add_item(tree, proto_gmhdr, tvb, offset, length + 2, FALSE);
+ ti = proto_tree_add_item(tree, proto_gmhdr, tvb, offset, length, FALSE);
if (gmhdr_summary_in_tree) {
- proto_item_append_text(ti, ", Length: %u", length);
+ proto_item_append_text(ti, ", Length: %u", length);
}
gmhdr_tree = proto_item_add_subtree(ti, ett_gmhdr);
+ dissect_gmtlv(tvb, pinfo, gmhdr_tree, offset+1, length-1);
- /* Adjust one byte for length */
- offset += 1;
- length -= 1;
- while (length > 1) {
- guint16 tl = tvb_get_ntohs(tvb, offset);
- offset += 2; /* type + len */
- length -= 2;
- fl = tl & 0xff;
- switch (tl >> 8) {
- case GMHDR_FTYPE_SRCPORT: {
- guint16 pid;
- guint32 tv = tvb_get_ntohl(tvb, offset) >> 8; /* Only 24-bit field */
- ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_srcport, tvb, offset, fl, FALSE);
- srcport_tree = proto_item_add_subtree(ti, ett_srcport);
- ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_plfm, tvb, offset, fl, FALSE);
- ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_gid, tvb, offset, fl, FALSE);
- ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_bid, tvb, offset, fl, FALSE);
- ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_pid, tvb, offset, fl, FALSE);
- /* If not GV-2404, we need different formula here */
- pid = ((tv & GMHDR_SRCPORT_PID_MASK) >> GMHDR_SRCPORT_PID_SHFT) - 24;
- if (pid >= 1 && pid <= 4) {
- proto_item_append_text(ti, " (g%d)", pid);
- }
- break;
- }
- case GMHDR_FTYPE_PKTSIZE:
- proto_tree_add_item(gmhdr_tree, hf_gmhdr_pktsize, tvb, offset, fl, FALSE);
- break;
- case GMHDR_FTYPE_TIMESTAMP_LOCAL:
- case GMHDR_FTYPE_TIMESTAMP_NTP:
- case GMHDR_FTYPE_TIMESTAMP_EXT: {
- char *tssrc = "Unknown";
- ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_timestamp, tvb, offset, fl, FALSE);
-
- switch (tl >> 8) {
- case GMHDR_FTYPE_TIMESTAMP_LOCAL: tssrc = "Local"; break;
- case GMHDR_FTYPE_TIMESTAMP_NTP: tssrc = "NTP"; break;
- case GMHDR_FTYPE_TIMESTAMP_EXT: tssrc = "External"; break;
- }
- proto_item_append_text(ti, ", Source: %s", tssrc);
- break;
- }
- default:
- ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_generic, tvb, offset, fl, FALSE);
- proto_item_append_text(ti, " [Id: %u, Length: %u]", tl >> 8, fl);
- break;
- }
- /* Adjust for the field length */
- offset += fl;
- length -= fl;
- }
- }
+ } /* if (tree) */
offset += length;
encap_proto = tvb_get_ntohs(tvb, offset);
@@ -187,37 +191,35 @@ dissect_gmtrailer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
proto_tree *ti;
gint16 length;
- guint16 fl;
- proto_tree *volatile gmhdr_tree;
- proto_tree *srcport_tree;
- unsigned offset = 0;
+ proto_tree *gmhdr_tree = NULL;
+ guint offset;
guint16 cksum, comp_cksum;
/* See if this packet has a Gigamon trailer, if yes, then decode it */
- if (tvb_get_ntohs(tvb, tvb->length - 4) != ETHERTYPE_GIGAMON) {
+ if (tvb_get_ntohs(tvb, -4) != ETHERTYPE_GIGAMON) {
return 0;
}
- offset = tvb->length - 2; /* 2 byte checksum */
- cksum = tvb_get_ntohs(tvb, offset);
- offset -= 3; /* 1 byte length + 2 byte ET */
- length = tvb_get_guint8(tvb, offset); /* This is length of Gigamon header */
+ offset = tvb_reported_length(tvb) - 2; /* 2 byte checksum */
+ cksum = tvb_get_ntohs(tvb, offset);
+ offset -= 3; /* 1 byte length + 2 byte ET */
+ length = tvb_get_guint8(tvb, offset); /* length of Gigamon header */
+ offset -= length;
- /* Verify the checksum, if not valid, it means that the trailer is not valid */
+ /* Verify the checksum; if not valid, it means that the trailer is not valid */
{
vec_t vec;
vec.len = length + 3;
- vec.ptr = tvb_get_ptr(tvb, offset - length, vec.len);
+ vec.ptr = tvb_get_ptr(tvb, offset, vec.len);
comp_cksum = in_cksum(&vec, 1);
if (pntohs(&comp_cksum) != cksum) {
return 0;
}
}
- gmhdr_tree = NULL;
if (tree) {
- ti = proto_tree_add_item(tree, proto_gmhdr, tvb, offset - length, length + 5, FALSE);
+ ti = proto_tree_add_item(tree, proto_gmhdr, tvb, offset, length + 5, FALSE);
if (gmhdr_summary_in_tree) {
proto_item_append_text(ti, ", Length: %u, Checksum: 0x%x", length, cksum);
@@ -225,59 +227,9 @@ dissect_gmtrailer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
gmhdr_tree = proto_item_add_subtree(ti, ett_gmhdr);
- /* Adjust for length */
- offset -= length;
- while (length > 1) {
- guint16 tl = tvb_get_ntohs(tvb, offset);
- offset += 2; /* type + len */
- length -= 2;
- fl = tl & 0xff;
- switch (tl >> 8) {
- case GMHDR_FTYPE_SRCPORT: {
- guint16 pid;
- guint32 tv = tvb_get_ntohl(tvb, offset) >> 8; /* Only 24-bit field */
- ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_srcport, tvb, offset, fl, FALSE);
- srcport_tree = proto_item_add_subtree(ti, ett_srcport);
- ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_plfm, tvb, offset, fl, FALSE);
- ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_gid, tvb, offset, fl, FALSE);
- ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_bid, tvb, offset, fl, FALSE);
- ti = proto_tree_add_item(srcport_tree, hf_gmhdr_srcport_pid, tvb, offset, fl, FALSE);
- /* If not GV-2404, we need different formula here */
- pid = ((tv & GMHDR_SRCPORT_PID_MASK) >> GMHDR_SRCPORT_PID_SHFT) - 24;
- if (pid >= 1 && pid <= 4) {
- proto_item_append_text(ti, " (g%d)", pid);
- }
- break;
- }
- case GMHDR_FTYPE_PKTSIZE:
- proto_tree_add_item(gmhdr_tree, hf_gmhdr_pktsize, tvb, offset, fl, FALSE);
- break;
- case GMHDR_FTYPE_TIMESTAMP_LOCAL:
- case GMHDR_FTYPE_TIMESTAMP_NTP:
- case GMHDR_FTYPE_TIMESTAMP_EXT: {
- char *tssrc = "Unknown";
- ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_timestamp, tvb, offset, fl, FALSE);
-
- switch (tl >> 8) {
- case GMHDR_FTYPE_TIMESTAMP_LOCAL: tssrc = "Local"; break;
- case GMHDR_FTYPE_TIMESTAMP_NTP: tssrc = "NTP"; break;
- case GMHDR_FTYPE_TIMESTAMP_EXT: tssrc = "External"; break;
- }
- proto_item_append_text(ti, ", Source: %s", tssrc);
- break;
- }
- default:
- ti = proto_tree_add_item(gmhdr_tree, hf_gmhdr_generic, tvb, offset, fl, FALSE);
- proto_item_append_text(ti, " [Id: %u, Length: %u]", tl >> 8, fl);
- break;
- }
- /* Adjust for the field length */
- offset += fl;
- length -= fl;
- }
+ dissect_gmtlv(tvb, pinfo, gmhdr_tree, offset, length);
}
-
- return offset;
+ return tvb_reported_length(tvb);
}
void
@@ -328,7 +280,7 @@ proto_register_gmhdr(void)
proto_register_field_array(proto_gmhdr, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
- gmhdr_module = prefs_register_protocol(proto_gmhdr, proto_reg_handoff_gmhdr);
+ gmhdr_module = prefs_register_protocol(proto_gmhdr, NULL);
prefs_register_bool_preference(gmhdr_module, "summary_in_tree",
"Show Gigamon header summary in protocol tree",
"Whether the Gigamon header summary line should be shown in the protocol tree",
@@ -338,14 +290,10 @@ proto_register_gmhdr(void)
void
proto_reg_handoff_gmhdr(void)
{
- static gboolean prefs_initialized = FALSE;
- static dissector_handle_t gmhdr_handle;
-
- if (!prefs_initialized) {
- gmhdr_handle = create_dissector_handle(dissect_gmhdr, proto_gmhdr);
- dissector_add("ethertype", ETHERTYPE_GIGAMON, gmhdr_handle);
- heur_dissector_add("eth.trailer", dissect_gmtrailer, proto_gmhdr);
- prefs_initialized = TRUE;
- }
+ dissector_handle_t gmhdr_handle;
+
+ gmhdr_handle = create_dissector_handle(dissect_gmhdr, proto_gmhdr);
+ dissector_add("ethertype", ETHERTYPE_GIGAMON, gmhdr_handle);
+ heur_dissector_add("eth.trailer", dissect_gmtrailer, proto_gmhdr);
}