summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ixiatrailer.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-ixiatrailer.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-ixiatrailer.c')
-rw-r--r--epan/dissectors/packet-ixiatrailer.c264
1 files changed, 264 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ixiatrailer.c b/epan/dissectors/packet-ixiatrailer.c
new file mode 100644
index 00000000..1cdff60b
--- /dev/null
+++ b/epan/dissectors/packet-ixiatrailer.c
@@ -0,0 +1,264 @@
+/* packet-ixiatrailer.c
+ * Routines for Ixia trailer parsing
+ *
+ * Dissector for Ixia Network Visibility Solutions trailer
+ * Copyright Ixia 2012
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <wsutil/pint.h>
+#include <epan/prefs.h>
+#include <epan/in_cksum.h>
+#include <epan/expert.h>
+
+void proto_register_ixiatrailer(void);
+void proto_reg_handoff_ixiatrailer(void);
+
+/* Trailer "magic number". */
+#define IXIA_PATTERN 0xAF12
+
+/* Trailer TLV types.
+
+ TODO: which of these typestamp types are currently supported?
+ Should lose the rest!! */
+#define IXIATRAILER_FTYPE_ORIGINAL_PACKET_SIZE 1
+#define IXIATRAILER_FTYPE_TIMESTAMP_LOCAL 3
+#define IXIATRAILER_FTYPE_TIMESTAMP_NTP 4
+#define IXIATRAILER_FTYPE_TIMESTAMP_GPS 5
+#define IXIATRAILER_FTYPE_TIMESTAMP_1588 6 /* PTP */
+#define IXIATRAILER_FTYPE_TIMESTAMP_HOLDOVER 7
+
+static const value_string ixiatrailer_ftype_timestamp[] = {
+ { IXIATRAILER_FTYPE_TIMESTAMP_LOCAL, "Local" },
+ { IXIATRAILER_FTYPE_TIMESTAMP_NTP, "NTP" },
+ { IXIATRAILER_FTYPE_TIMESTAMP_GPS, "GPS" },
+ { IXIATRAILER_FTYPE_TIMESTAMP_1588, "PTP" },
+ { IXIATRAILER_FTYPE_TIMESTAMP_HOLDOVER, "Holdover" },
+ { 0, NULL }
+};
+
+/* Preference settings */
+static gboolean ixiatrailer_summary_in_tree = TRUE;
+
+static int proto_ixiatrailer = -1;
+static gint ett_ixiatrailer = -1;
+
+static int hf_ixiatrailer_packetlen = -1;
+static int hf_ixiatrailer_timestamp = -1;
+static int hf_ixiatrailer_generic = -1;
+
+static expert_field ei_ixiatrailer_field_length_invalid = EI_INIT;
+
+/* The trailer begins with a sequence of TLVs, each of which has a
+ 1-byte type, a 1-byte value length (not TLV length, so the TLV
+ length is the value length + 2), and a variable-length value.
+
+ Following the sequence of TLVs is:
+
+ a 1-byte field giving the length of the sequence of TLVs;
+ a 2-byte big-endian signature field with the value 0xAF12;
+ a 2-byte big-endian checksum field, covering the sequence
+ of TLVs, the sequence length, and the signature.
+*/
+static int
+dissect_ixiatrailer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
+{
+ proto_tree *ti;
+ guint tvblen, trailer_length, field_length;
+ gboolean matched_without_fcs, matched_with_fcs;
+ proto_tree *ixiatrailer_tree = NULL;
+ guint offset = 0;
+ guint16 cksum, comp_cksum;
+ vec_t vec;
+ guint8 field_type;
+
+ /* A trailer must, at minimum, include:
+
+ a "original packet size" TLV, with 1 byte of type, 1 byte of
+ value length, and 2 bytes of original packet ize;
+
+ 1 byte of trailer length;
+
+ 2 bytes of signature;
+
+ 2 bytes of trailer checksum;
+
+ for a total of 9 bytes. */
+ tvblen = tvb_reported_length(tvb);
+ if (tvblen != tvb_captured_length(tvb)) {
+ /* The heuristic check includes a checksum check, so we need the
+ *entire* trailer to have been captured; if it wasn't, we don't
+ try to check it. */
+ return 0;
+ }
+ if (tvblen < 9) {
+ /* This is too short, so it cannot be a valid Ixia trailer. */
+ return 0;
+ }
+
+ /* Depending upon the ethernet preference "Assume packets have FCS", we
+ may be given those 4 bytes too.
+
+ Try checking two locations for our pattern. */
+
+ if (tvblen == 23) {
+ tvblen = 19;
+ }
+
+ /* 3rd & 4th bytes from the end must match our pattern.
+ First, try under the assumption that the tvbuff doesn't include
+ the FCS. */
+ matched_without_fcs = (tvb_get_ntohs(tvb, tvblen-4) == IXIA_PATTERN);
+
+ /* If that didn't match, is the tvbuff big enough to include an Ixia
+ trailer *and* an FCS? If so, try under that assumption. */
+ if (!matched_without_fcs && tvblen >= 13)
+ matched_with_fcs = (tvb_get_ntohs(tvb, tvblen-(4+4)) == IXIA_PATTERN);
+ else
+ matched_with_fcs = FALSE;
+ if (!matched_without_fcs) {
+ if (!matched_with_fcs) {
+ /* Neither matched, so no Ixia trailer. */
+ return 0;
+ }
+
+ /* Matched under the assumption that we have an FCS, so let's
+ act as if that's the case. Remove the FCS length from the
+ tvbuff. */
+ tvblen -= 4;
+ }
+
+ /* Read Trailer-length field */
+ trailer_length = tvb_get_guint8(tvb, tvblen-5);
+ /* Should match overall length of trailer */
+ if ((tvblen-5) != trailer_length) {
+ return 0;
+ }
+
+ /* Last 2 bytes are the checksum */
+ cksum = tvb_get_ntohs(tvb, tvblen-2);
+
+ /* Verify the checksum; if not valid, it means that the trailer is not valid */
+ SET_CKSUM_VEC_TVB(vec, tvb, offset, trailer_length + 3);
+ comp_cksum = in_cksum(&vec, 1);
+ if (pntoh16(&comp_cksum) != cksum) {
+ return 0;
+ }
+
+ /* OK: We have our trailer - create protocol root */
+ ti = proto_tree_add_item(tree, proto_ixiatrailer, tvb, offset, trailer_length + 5, ENC_NA);
+
+ /* Append summary to item, if configured to */
+ if (ixiatrailer_summary_in_tree) {
+ proto_item_append_text(ti, ", Length: %u, Checksum: 0x%x", trailer_length, cksum);
+ }
+
+ /* Create subtree */
+ ixiatrailer_tree = proto_item_add_subtree(ti, ett_ixiatrailer);
+
+ while (offset < trailer_length - 2)
+ {
+ field_type = tvb_get_guint8(tvb, offset++);
+ field_length = tvb_get_guint8(tvb, offset++);
+ switch (field_type) {
+ case IXIATRAILER_FTYPE_ORIGINAL_PACKET_SIZE:
+ if (field_length != 2){
+ expert_add_info_format(pinfo, ti, &ei_ixiatrailer_field_length_invalid, "Field length %u invalid", field_length);
+ break;
+ }
+ ti = proto_tree_add_item(ixiatrailer_tree, hf_ixiatrailer_packetlen, tvb, offset, field_length, ENC_BIG_ENDIAN);
+ proto_item_append_text(ti, " bytes");
+ break;
+ case IXIATRAILER_FTYPE_TIMESTAMP_LOCAL:
+ case IXIATRAILER_FTYPE_TIMESTAMP_NTP:
+ case IXIATRAILER_FTYPE_TIMESTAMP_GPS:
+ case IXIATRAILER_FTYPE_TIMESTAMP_1588:
+ case IXIATRAILER_FTYPE_TIMESTAMP_HOLDOVER:
+ if (field_length != 8) {
+ expert_add_info_format(pinfo, ti, &ei_ixiatrailer_field_length_invalid, "Field length %u invalid", field_length);
+ break;
+ }
+ /* Timestamp */
+ ti = proto_tree_add_item(ixiatrailer_tree, hf_ixiatrailer_timestamp, tvb, offset, field_length, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
+ proto_item_append_text(ti, "; Source: %s", val_to_str_const(field_type, ixiatrailer_ftype_timestamp, "Unknown"));
+ break;
+ default:
+ /* Not a recognized time format - just show as bytes */
+ ti = proto_tree_add_item(ixiatrailer_tree, hf_ixiatrailer_generic, tvb, offset, field_length, ENC_NA);
+ proto_item_append_text(ti, " [Id: %u, Length: %u bytes]", field_type, field_length);
+ break;
+ };
+ offset += field_length;
+ }
+ /* We are claiming all of the bytes */
+ return tvblen;
+}
+
+void
+proto_register_ixiatrailer(void)
+{
+
+ static hf_register_info hf[] = {
+ { &hf_ixiatrailer_packetlen, {
+ "Original packet length", "ixiatrailer.packetlen", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_ixiatrailer_timestamp, {
+ "Time Stamp", "ixiatrailer.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_ixiatrailer_generic, {
+ "Generic Field", "ixiatrailer.generic", FT_BYTES, BASE_NONE,
+ NULL, 0x0, NULL, HFILL }},
+ };
+
+ static gint *ixiatrailer_ett[] = {
+ &ett_ixiatrailer
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_ixiatrailer_field_length_invalid, { "ixiatrailer.field_length_invalid", PI_MALFORMED, PI_ERROR, "Field length invalid", EXPFILL }},
+ };
+
+ module_t *ixiatrailer_module;
+ expert_module_t* expert_ixiatrailer;
+
+ proto_ixiatrailer = proto_register_protocol("Ixia Trailer", "IXIATRAILER", "ixiatrailer");
+ proto_register_field_array(proto_ixiatrailer, hf, array_length(hf));
+ proto_register_subtree_array(ixiatrailer_ett, array_length(ixiatrailer_ett));
+ expert_ixiatrailer = expert_register_protocol(proto_ixiatrailer);
+ expert_register_field_array(expert_ixiatrailer, ei, array_length(ei));
+
+ ixiatrailer_module = prefs_register_protocol(proto_ixiatrailer, NULL);
+ prefs_register_bool_preference(ixiatrailer_module, "summary_in_tree",
+ "Show trailer summary in protocol tree",
+ "Whether the trailer summary line should be shown in the protocol tree",
+ &ixiatrailer_summary_in_tree);
+}
+
+
+void
+proto_reg_handoff_ixiatrailer(void)
+{
+ /* Check for Ixia format in the ethernet trailer */
+ heur_dissector_add("eth.trailer", dissect_ixiatrailer, "Ixia Trailer", "ixiatrailer_eth", proto_ixiatrailer, HEURISTIC_ENABLE);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */