aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Cohen <j.cohen@f5.com>2020-03-01 20:34:04 -0600
committerAnders Broman <a.broman58@gmail.com>2020-03-17 12:09:51 +0000
commitac82fd63534e6044a07896a519726ced78270882 (patch)
treeb71123d252b842d3fe34255e6f0f0c13856d23a1
parentae2e83f2d8895a3e7496dc6db520146573beb022 (diff)
f5ethtrailer: Add support for version 4 of low noise trailer
Change-Id: Ibdcfdd675f5c1e86b15f36f9a6c28b73e13c1616 Reviewed-on: https://code.wireshark.org/review/36480 Reviewed-by: Jason Cohen <kryojenik2@gmail.com> Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/dissectors/packet-f5ethtrailer.c267
1 files changed, 203 insertions, 64 deletions
diff --git a/epan/dissectors/packet-f5ethtrailer.c b/epan/dissectors/packet-f5ethtrailer.c
index 9257fdac15..95fd956da9 100644
--- a/epan/dissectors/packet-f5ethtrailer.c
+++ b/epan/dissectors/packet-f5ethtrailer.c
@@ -226,6 +226,7 @@ static gint hf_type = -1;
static gint hf_length = -1;
static gint hf_version = -1;
static gint hf_data = -1;
+static gint hf_data_str = -1;
static gint hf_dpt_unknown = -1;
static gint hf_trailer_hdr = -1;
/* Low */
@@ -237,8 +238,14 @@ static gint hf_ingress = -1;
static gint hf_slot0 = -1;
static gint hf_slot1 = -1;
static gint hf_tmm = -1;
+static gint hf_obj_name_type = -1;
+static gint hf_obj_data_len = -1;
static gint hf_vipnamelen = -1;
static gint hf_vip = -1;
+static gint hf_portnamelen = -1;
+static gint hf_phys_port = -1;
+static gint hf_trunknamelen = -1;
+static gint hf_trunk = -1;
/* Med */
static gint hf_med_id = -1;
static gint hf_flow_id = -1;
@@ -293,6 +300,7 @@ static gint hf_dpt_len = -1;
static expert_field ei_f5eth_flowlost = EI_INIT;
static expert_field ei_f5eth_flowreuse = EI_INIT;
static expert_field ei_f5eth_badlen = EI_INIT;
+static expert_field ei_f5eth_undecoded = EI_INIT;
/* These are the ids of the subtrees that we may be creating */
static gint ett_f5ethtrailer = -1;
@@ -303,6 +311,7 @@ static gint ett_f5ethtrailer_med = -1;
static gint ett_f5ethtrailer_high = -1;
static gint ett_f5ethtrailer_rstcause = -1;
static gint ett_f5ethtrailer_trailer_hdr = -1;
+static gint ett_f5ethtrailer_obj_names = -1;
/* For fileinformation */
static gint hf_fi_command = -1;
@@ -2069,7 +2078,8 @@ dissect_low_trailer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint o
proto_item_set_hidden(pi);
o += 1;
}
- proto_tree_add_item(tree, hf_vip, tvb, o, vipnamelen, ENC_ASCII | ENC_NA);
+ pi = proto_tree_add_item(tree, hf_vip, tvb, o, vipnamelen, ENC_ASCII | ENC_NA);
+ proto_item_prepend_text(pi, "VIP ");
return trailer_length;
} /* dissect_low_trailer() */
@@ -2374,6 +2384,14 @@ dissect_dpt_trailer_noise_med(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
return len;
} /* dissect_dpt_trailer_noise_med() */
+static const value_string f5_obj_data_types[] = {
+ {0, "Virtual Server"},
+ {1, "Port"},
+ {2, "Trunk"},
+ {255, "Unknown"},
+ {0, NULL}
+};
+
/*---------------------------------------------------------------------------*/
/**
* @brief Render the data for DPT low noise trailer TVB
@@ -2387,17 +2405,15 @@ dissect_dpt_trailer_noise_med(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
static int
dissect_dpt_trailer_noise_low(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
+ gint len;
+ gint ver;
proto_item *pi;
- proto_item *pi_ingress;
+ proto_item *ti;
+ gint offset;
guint flags;
guint ingress;
- gint o;
- int vipnamelen;
- int badvipnamelen = 0;
- guint slot_display = 0;
+ guint slot_display = 0;
guint tmm;
- gint len;
- gint ver;
f5eth_tap_data_t *tdata = (f5eth_tap_data_t *)data;
DISSECTOR_ASSERT(tdata != NULL);
@@ -2405,63 +2421,30 @@ dissect_dpt_trailer_noise_low(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
ver = tvb_get_ntohs(tvb, F5_DPT_V1_TLV_VERSION_OFF);
/* Unknown version, cannot do anything */
- if (ver < 2 || ver > 3) {
+ if (ver < 2 || ver > 4) {
return 0;
}
+ /* Add the Low Noise trailer and attach a subtree */
pi = proto_tree_add_item(tree, hf_low_id, tvb, 0, len, ENC_NA);
tree = proto_item_add_subtree(pi, ett_f5ethtrailer_low);
render_f5dptv1_tlvhdr(tvb, tree, 0);
- o = F5_DPT_V1_TLV_HDR_LEN;
+ offset = F5_DPT_V1_TLV_HDR_LEN;
tdata->noise_low = 1;
/* Direction */
- flags = tvb_get_guint8(tvb, o);
+ flags = tvb_get_guint8(tvb, offset);
if (ver == 2) {
ingress = flags;
} else {
ingress = flags & F5_LOW_FLAGS_INGRESS_MASK;
}
- tdata->ingress = ingress == 0 ? 0 : 1;
- /* Slot */
- slot_display = tvb_get_guint8(tvb, o + 1) + 1;
- /* TMM */
- tmm = tvb_get_guint8(tvb, o + 2);
- if (tmm < F5ETH_TAP_TMM_MAX && slot_display < F5ETH_TAP_SLOT_MAX) {
- tdata->tmm = tmm;
- tdata->slot = slot_display;
- }
- /* VIP Name */
- vipnamelen = tvb_get_guint8(tvb, o + 3);
- /* Check for an invalid vip name length and do not try to reference any of the data if it is
- * bad
- */
- if (tvb_reported_length_remaining(tvb, o + 4) < vipnamelen) {
- badvipnamelen = 1;
- /* Set this to zero to prevent processing of things that utilze it */
- vipnamelen = 0;
- }
- if (vipnamelen > 0 && have_tap_listener(tap_f5ethtrailer)) {
- tdata->virtual_name =
- tvb_get_string_enc(wmem_packet_scope(), tvb, o + 4, vipnamelen, ENC_ASCII);
- }
-
- /* Is the column visible? */
- if (pref_info_type != none) {
- f5eth_set_info_col(pinfo, ingress, slot_display, tmm);
- }
-
- /* We do not need to do anything more if we don't have a tree. */
- if (tree == NULL) {
- return len;
- }
-
/* Use special formatting here so that users do not have to filter on "IN"
* and "OUT", but rather can continue to use typical boolean values. "IN"
* and "OUT" are provided as convenience. */
- pi_ingress = proto_tree_add_boolean_format_value(tree, hf_ingress, tvb, o, 1, ingress,
+ pi = proto_tree_add_boolean_format_value(tree, hf_ingress, tvb, offset, 1, ingress,
"%s (%s)", ingress ? tfs_true_false.true_string : tfs_true_false.false_string,
ingress ? f5tfs_ing.true_string : f5tfs_ing.false_string);
if (ver > 2) {
@@ -2469,27 +2452,150 @@ dissect_dpt_trailer_noise_low(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
* for backward compatability for users that are accustomed to using
* "f5ethtrailer.ingress" but mark it as generated to indicate that that
* field no longer really exists. */
- PROTO_ITEM_SET_GENERATED(pi_ingress);
+ PROTO_ITEM_SET_GENERATED(pi);
proto_tree_add_bitmask(
- tree, tvb, o, hf_flags, ett_f5ethtrailer_low_flags, hf_flags__fields, ENC_BIG_ENDIAN);
+ tree, tvb, offset, hf_flags, ett_f5ethtrailer_low_flags, hf_flags__fields,
+ ENC_BIG_ENDIAN);
}
- o++;
+ tdata->ingress = ingress == 0 ? 0 : 1;
+ offset += 1;
- proto_tree_add_uint(tree, hf_slot1, tvb, o, 1, slot_display);
- o += 1;
+ /* Slot */
+ slot_display = tvb_get_guint8(tvb, offset) + 1;
+ proto_tree_add_uint(tree, hf_slot1, tvb, offset, 1, slot_display);
+ offset += 1;
- proto_tree_add_item(tree, hf_tmm, tvb, o, 1, ENC_BIG_ENDIAN);
- o += 1;
- pi = proto_tree_add_item(tree, hf_vipnamelen, tvb, o, 1, ENC_BIG_ENDIAN);
- if (badvipnamelen) {
- expert_add_info(pinfo, pi, &ei_f5eth_badlen);
- /* Cannot go any further */
- return len;
+ /* TMM */
+ tmm = tvb_get_guint8(tvb, offset);
+ if (tmm < F5ETH_TAP_TMM_MAX && slot_display < F5ETH_TAP_SLOT_MAX) {
+ tdata->tmm = tmm;
+ tdata->slot = slot_display;
}
- o += 1;
- proto_tree_add_item(tree, hf_vip, tvb, o, vipnamelen, ENC_ASCII | ENC_NA);
+ proto_tree_add_item(tree, hf_tmm, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
- return len;
+ /* Is the column visible? */
+ if (pref_info_type != none) {
+ f5eth_set_info_col(pinfo, ingress, slot_display, tmm);
+ }
+
+ if (ver < 4) { /* Low noise versions 2 and 3 */
+ /* VIP Name */
+ gint viplen = tvb_get_guint8(tvb, offset);
+ /* Make sure VIP Name Length does not extend past the TVB */
+ if (tvb_reported_length_remaining(tvb, offset) < viplen) {
+ pi = proto_tree_add_item(tree, hf_vip, tvb, offset, 0, ENC_ASCII|ENC_NA);
+ expert_add_info(pinfo, pi, &ei_f5eth_badlen);
+ /* Cannot go any further */
+ return len;
+ }
+ gchar *text = tvb_format_text(tvb, offset +1, viplen);
+ ti = proto_tree_add_subtree_format(
+ tree, tvb, offset, viplen + 1, ett_f5ethtrailer_obj_names, NULL,
+ "Virtual Server: %s", text);
+ proto_tree_add_item(ti, hf_vipnamelen, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(ti, hf_vip, tvb, offset, viplen, ENC_ASCII|ENC_NA);
+ if (viplen > 0 && have_tap_listener(tap_f5ethtrailer)) {
+ tdata->virtual_name = text;
+ }
+ offset += viplen;
+ } else { /* Low noise version 4 */
+ /* This area now is a data block containing a number of BIG-IP config object names
+ * i.e. Virtual server that handled the packt
+ * Port that handled the packet
+ * Trunk that handled the packet
+ *
+ * 1-Byte Length of block (excluding this byte)
+ * len-Bytes data block
+ * <len><data block...>
+ *
+ * Then the "data block" is a variable number of object names
+ * Each name value is:
+ * 1-Byte Type
+ * 1-Byte Length (excluding type and length bytes)
+ * len-Bytes String
+ * <type><len><string><type><len><string>
+ */
+
+ gint data_len = tvb_get_gint8(tvb, offset);
+ pi = proto_tree_add_item(tree, hf_data, tvb, offset, 1, ENC_NA);
+ proto_item_set_text(pi, "Associated config object names");
+ ti = proto_item_add_subtree(pi, ett_f5ethtrailer_obj_names);
+ proto_tree_add_item(ti, hf_obj_data_len, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ if (tvb_reported_length_remaining(tvb, offset) < data_len) {
+ expert_add_info(pinfo, pi, &ei_f5eth_badlen);
+ /* Cannot go any further */
+ return len;
+ }
+ proto_item_set_len(pi, data_len + 1);
+
+ /* Begin parsing the data field and adding items for the strings contained */
+ tvbuff_t *data_tvb = tvb_new_subset_length(tvb, offset, data_len);
+ gint data_off = 0;
+
+ while (data_off < data_len) {
+ gint field_name_len_idx;
+ gint field_name_idx;
+ gchar *text_format;
+ guint8 t = tvb_get_guint8(data_tvb, data_off);
+ guint8 l = tvb_get_guint8(data_tvb, data_off + 1);
+
+ switch (t) {
+ case 0: /* Virtual Server */
+ field_name_len_idx = hf_vipnamelen;
+ field_name_idx = hf_vip;
+ text_format = "Virtual Server: %s";
+ break;
+ case 1: /* Port */
+ field_name_len_idx = hf_portnamelen;
+ field_name_idx = hf_phys_port;
+ text_format = "Port: %s";
+ break;
+ case 2: /* Trunk */
+ field_name_len_idx = hf_trunknamelen;
+ field_name_idx = hf_trunk;
+ text_format = "Trunk: %s";
+ break;
+ default:
+ /* unknown type */
+ t = 255; /* Unknown */
+ field_name_len_idx = hf_obj_data_len;
+ field_name_idx = hf_data_str;
+ text_format = "Unknown type";
+ break;
+ }
+
+ if (tvb_reported_length_remaining(data_tvb, data_off + 2) < l) {
+ ti = proto_tree_add_subtree_format(
+ tree, data_tvb, data_off, 2, ett_f5ethtrailer_obj_names, NULL,
+ text_format, "");
+ proto_tree_add_item(ti, hf_obj_name_type, data_tvb, data_off, 1, ENC_BIG_ENDIAN);
+ pi = proto_tree_add_item(
+ ti, field_name_len_idx, data_tvb, data_off + 1, 1, ENC_BIG_ENDIAN);
+ expert_add_info(pinfo, pi, &ei_f5eth_badlen);
+ /* Cannot go any further */
+ return len;
+ }
+ gchar *text = tvb_format_text(data_tvb, data_off + 2, l);
+ ti = proto_tree_add_subtree_format(
+ tree, data_tvb, data_off, l + 2, ett_f5ethtrailer_obj_names, NULL,
+ text_format, text);
+ pi = proto_tree_add_item(ti, hf_obj_name_type, data_tvb, data_off, 1, ENC_BIG_ENDIAN);
+ if (t == 255) {
+ expert_add_info(pinfo, pi, &ei_f5eth_undecoded);
+ }
+ proto_tree_add_item(ti, field_name_len_idx, data_tvb, data_off + 1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(ti, field_name_idx, data_tvb, data_off + 2, l, ENC_ASCII|ENC_NA);
+ if (t == 0 && l > 0 && have_tap_listener(tap_f5ethtrailer)) {
+ tdata->virtual_name = text;
+ }
+ data_off += l + 2;
+ }
+ offset += data_off;
+ }
+ return offset;
} /* dissect_dpt_trailer_noise_low() */
/*---------------------------------------------------------------------------*/
@@ -3555,6 +3661,10 @@ proto_register_f5ethtrailer(void)
{ "Data", "f5ethtrailer.data", FT_BYTES, SEP_SPACE, NULL,
0x0, NULL, HFILL }
},
+ { &hf_data_str,
+ { "Data", "f5ethtrailer.data", FT_STRING, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }
+ },
/* Low parameters */
{ &hf_low_id,
@@ -3588,14 +3698,38 @@ proto_register_f5ethtrailer(void)
{ "TMM (0-based)", "f5ethtrailer.tmm", FT_UINT8, BASE_DEC, NULL,
0x0, "TMM captured on", HFILL }
},
+ { &hf_obj_name_type,
+ { "Type", "f5ethtrailer.objnametype", FT_UINT8, BASE_DEC,
+ VALS(f5_obj_data_types), 0x0, NULL, HFILL }
+ },
+ { &hf_obj_data_len,
+ { "Object Name Data Length", "f5ethtrailer.objnamelen", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }
+ },
{ &hf_vipnamelen,
- { "VIP name length", "f5ethtrailer.vipnamelen", FT_UINT8, BASE_DEC, NULL,
+ { "Length", "f5ethtrailer.vipnamelen", FT_UINT8, BASE_DEC, NULL,
0x0, NULL, HFILL }
},
{ &hf_vip,
- { "VIP", "f5ethtrailer.vip", FT_STRING, BASE_NONE, NULL,
+ { "Name", "f5ethtrailer.vip", FT_STRING, BASE_NONE, NULL,
0x0, "VIP flow associated with", HFILL }
},
+ { &hf_portnamelen,
+ { "Length", "f5ethtrailer.portnamelen", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }
+ },
+ { &hf_phys_port,
+ { "Name", "f5ethtrailer.phys_port", FT_STRING, BASE_NONE, NULL,
+ 0x0, "Physical port", HFILL }
+ },
+ { &hf_trunknamelen,
+ { "Length", "f5ethtrailer.trunknamelen", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }
+ },
+ { &hf_trunk,
+ { "Name", "f5ethtrailer.trunk", FT_STRING, BASE_NONE, NULL,
+ 0x0, "Trunk name", HFILL }
+ },
/* Medium parameters */
{ &hf_med_id,
@@ -3812,6 +3946,7 @@ proto_register_f5ethtrailer(void)
&ett_f5ethtrailer_high,
&ett_f5ethtrailer_rstcause,
&ett_f5ethtrailer_trailer_hdr,
+ &ett_f5ethtrailer_obj_names,
&ett_f5tls,
&ett_f5tls_std,
&ett_f5tls_ext,
@@ -3825,7 +3960,9 @@ proto_register_f5ethtrailer(void)
{ &ei_f5eth_flowreuse, { "f5ethtrailer.flowreuse", PI_SEQUENCE, PI_WARN,
"Flow reuse or SYN retransmit", EXPFILL } },
{ &ei_f5eth_badlen, { "f5ethtrailer.badlen", PI_MALFORMED, PI_ERROR,
- "Bad length", EXPFILL } }
+ "Length extends past remaining available bytes", EXPFILL } },
+ { &ei_f5eth_undecoded, { "f5ethtrailer.undecoded", PI_UNDECODED, PI_NOTE,
+ "This version of Wireshark does not understand how to decode this value", EXPFILL } },
};
proto_f5ethtrailer = proto_register_protocol(
@@ -3967,6 +4104,8 @@ proto_reg_handoff_f5ethtrailer(void)
create_dissector_handle(dissect_dpt_trailer_noise_low, -1));
dissector_add_uint("f5ethtrailer.noise_type_ver", F5TYPE_LOW << 16 | 3,
create_dissector_handle(dissect_dpt_trailer_noise_low, -1));
+ dissector_add_uint("f5ethtrailer.noise_type_ver", F5TYPE_LOW << 16 | 4,
+ create_dissector_handle(dissect_dpt_trailer_noise_low, -1));
dissector_add_uint("f5ethtrailer.noise_type_ver", F5TYPE_MED << 16 | 4,
create_dissector_handle(dissect_dpt_trailer_noise_med, -1));
dissector_add_uint("f5ethtrailer.noise_type_ver", F5TYPE_HIGH << 16 | 1,