summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-avsp.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-avsp.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-avsp.c')
-rw-r--r--epan/dissectors/packet-avsp.c555
1 files changed, 555 insertions, 0 deletions
diff --git a/epan/dissectors/packet-avsp.c b/epan/dissectors/packet-avsp.c
new file mode 100644
index 00000000..c68347f1
--- /dev/null
+++ b/epan/dissectors/packet-avsp.c
@@ -0,0 +1,555 @@
+/* packet-avsp.c
+ * Arista Vendor Specific ethertype Protocol (AVSP)
+ *
+ * Copyright (c) 2018-2022 by Arista Networks
+ * Author: Nikhil AP <nikhilap@arista.com>
+ * Author: PMcL <peterm@arista.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+ /* Arista Vendor-Specific EtherType Protocol Identifier
+ *
+ * Arista applied for, and received the assignment of, a vendor-specific EtherType Protocol Identifier in May of 2016. Details below:
+ *
+ * Ethertype number is: D28B
+ * Issue date is: May 12, 2016
+ *
+ * Arista Subtype 0x0001 is a Timestamp L2 Header
+ * Arista Subtype 0xCAFE is a TGen L2 header
+ *
+ * The timestamp L2 header consists of the following fields:
+ *
+ * Arista Vendor Specific Protocol EtherType (0xD28B)
+ * Two-byte protocol subtype of 0x0001
+ * Two-byte protocol version: 0x0010 for 64-bit timestamp and 0x0020 for 48-bit timestamp
+ * UTC timestamp value in IEEE 1588 time of day format (either 64-bit or 48-bit) with the lower 32-bits representing nanoseconds and upper bits representing seconds.
+ *
+ * The TGen L2 header consists of the following fields:
+ *
+ * Arista Vendor Specific Protocol EtherType (0xD28B)
+ * Two-byte protocol subtype of 0xCAFE
+ * Two-byte protocol version: 0x0001
+ */
+
+#include "config.h"
+#include <epan/packet.h>
+#include <epan/exceptions.h>
+#include <epan/etypes.h>
+#include <epan/expert.h>
+
+#include <wsutil/str_util.h>
+
+#include "packet-eth.h"
+
+#define ARISTA_SUBTYPE_TIMESTAMP 0x0001
+
+#define ARISTA_TIMESTAMP_64_TAI 0x0010
+#define ARISTA_TIMESTAMP_64_UTC 0x0110
+#define ARISTA_TIMESTAMP_48_TAI 0x0020
+#define ARISTA_TIMESTAMP_48_UTC 0x0120
+
+#define ARISTA_SUBTYPE_TGEN 0xCAFE
+#define ARISTA_TGEN_VER_1 0x0001
+
+void proto_reg_handoff_avsp(void);
+void proto_register_avsp(void);
+
+static dissector_handle_t avsp_handle;
+static int proto_avsp = -1;
+
+/* sub trees */
+static gint ett_avsp = -1;
+static gint ett_avsp_ts_48 = -1;
+static gint ett_avsp_ts_64 = -1;
+static gint ett_avsp_tgen_hdr = -1;
+static gint ett_avsp_tgen_hdr_ctrl = -1;
+static gint ett_avsp_tgen_payload = -1;
+
+/* AVSP Timestamp subtype header fields */
+static int hf_avsp_subtype = -1;
+static int hf_avsp_ts_version = -1;
+static int hf_avsp_ts_64_tai = -1;
+static int hf_avsp_ts_64_utc = -1;
+static int hf_avsp_ts_64_sec = -1;
+static int hf_avsp_ts_64_ns = -1;
+static int hf_avsp_ts_48_tai = -1;
+static int hf_avsp_ts_48_utc = -1;
+static int hf_avsp_ts_48_sec = -1;
+static int hf_avsp_ts_48_ns = -1;
+
+static int hf_avsp_etype = -1;
+static int hf_avsp_trailer = -1;
+
+/*
+ TGen subtype format
+ 0.............7...............15..............23..............31
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Ethertype = 0xD28B | Protocol Subtype = 0xCAFE |
+ +---------------+---------------+---------------+---------------+
+ | Protocol Version = 0x0001 | TGen Control Word |
+ +---------------+---------------+---------------+---------------+
+ | TGen Sequence Number | TGen Payload Length |
+ +---------------+---------------+---------------+---------------+
+ | TGen Data Payload |
+ +---------------+---------------+---------------+---------------+
+ | ... |
+ +---------------+---------------+---------------+---------------+
+ | TGen Data Payload |
+ +---------------+---------------+---------------+---------------+
+*/
+
+/* AVSP TGen subtype header fields */
+static int hf_avsp_tgen_version = -1;
+static int hf_avsp_tgen_hdr = -1;
+static int hf_avsp_tgen_hdr_ctrl = -1;
+static int hf_avsp_tgen_hdr_ctrl_fcs_inverted = -1;
+static int hf_avsp_tgen_hdr_ctrl_reserved = -1;
+static int hf_avsp_tgen_hdr_seq_num = -1;
+static int hf_avsp_tgen_hdr_payload_len = -1;
+static int hf_avsp_tgen_payload = -1;
+static int hf_avsp_tgen_payload_data = -1;
+static int hf_avsp_tgen_trailer = -1;
+
+static int* const avsp_tgen_ctrl[] = {
+ &hf_avsp_tgen_hdr_ctrl_fcs_inverted,
+ &hf_avsp_tgen_hdr_ctrl_reserved,
+ NULL
+};
+
+static dissector_handle_t ethertype_handle;
+
+static const value_string arista_subtypes[] = {
+ {ARISTA_SUBTYPE_TIMESTAMP, "timestamp"},
+ {ARISTA_SUBTYPE_TGEN, "TGen"},
+ {0, NULL}
+};
+
+static const value_string ts_versions[] = {
+ {ARISTA_TIMESTAMP_64_TAI, "Version 1"},
+ {ARISTA_TIMESTAMP_64_UTC, "Version 11"},
+ {ARISTA_TIMESTAMP_48_TAI, "Version 2"},
+ {ARISTA_TIMESTAMP_48_UTC, "Version 12"},
+ {0, NULL}
+};
+
+static const value_string tgen_versions[] = {
+ {ARISTA_TGEN_VER_1, "1"},
+ {0, NULL}
+};
+
+static expert_field ei_avsp_unknown_subtype = EI_INIT;
+static expert_field ei_avsp_ts_unknown_version = EI_INIT;
+static expert_field ei_avsp_tgen_unknown_version = EI_INIT;
+
+static int
+dissect_avsp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
+{
+ volatile guint8 offset = 0;
+ guint32 version, subtype, tgen_payload_len = 0;
+ guint64 tgen_ctrl;
+ guint32 tgen_seq_num;
+ const char* str;
+
+ tvbuff_t* volatile tgen_payload_tvb = NULL;
+ tvbuff_t* volatile trailer_tvb = NULL;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVSP");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ proto_item* avsp_ti, * ti;
+ proto_tree* avsp_tree, * avsp_48_tree = NULL, * avsp_64_tree = NULL,
+ * avsp_tgen_hdr = NULL, * avsp_tgen_payload = NULL;
+
+ /* Adding Items and Values to the Protocol Tree */
+ avsp_ti = proto_tree_add_item(tree, proto_avsp, tvb, 0, -1,
+ ENC_NA);
+ avsp_tree = proto_item_add_subtree(avsp_ti, ett_avsp);
+
+ /* add the subtype to avsp */
+ proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_subtype, tvb,
+ offset, 2, ENC_BIG_ENDIAN, &subtype);
+ str = try_val_to_str(subtype, arista_subtypes);
+ if (str) {
+ proto_item_append_text(avsp_ti, ", Subtype: %s", str);
+ }
+ offset += 2;
+
+ /* Based on the subtype, add the version and further custom protocol fields */
+ switch (subtype) {
+ case ARISTA_SUBTYPE_TIMESTAMP:
+ proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_ts_version, tvb, offset,
+ 2, ENC_BIG_ENDIAN, &version);
+ str = try_val_to_str(version, ts_versions);
+ if (str) {
+ proto_item_append_text(avsp_ti, ", Version: %s", str);
+ }
+ offset += 2;
+
+ switch (version) {
+ case ARISTA_TIMESTAMP_64_TAI:
+ ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_64_tai, tvb, 0, -1,
+ ENC_NA);
+ avsp_64_tree = proto_item_add_subtree(ti, ett_avsp);
+ col_add_str(pinfo->cinfo, COL_INFO, "64bit TAI timestamp");
+ proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_sec, tvb, offset,
+ 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_ns, tvb, offset,
+ 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ break;
+ case ARISTA_TIMESTAMP_64_UTC:
+ ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_64_utc, tvb, 0, -1,
+ ENC_NA);
+ avsp_64_tree = proto_item_add_subtree(ti, ett_avsp);
+ col_add_str(pinfo->cinfo, COL_INFO, "64bit UTC timestamp");
+ proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_sec, tvb, offset,
+ 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(avsp_64_tree, hf_avsp_ts_64_ns, tvb, offset,
+ 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ break;
+ case ARISTA_TIMESTAMP_48_TAI:
+ ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_48_tai, tvb, 0, -1,
+ ENC_NA);
+ avsp_48_tree = proto_item_add_subtree(ti, ett_avsp);
+ col_add_str(pinfo->cinfo, COL_INFO, "48bit TAI timestamp");
+ proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_sec, tvb, offset,
+ 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_ns, tvb, offset,
+ 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ break;
+ case ARISTA_TIMESTAMP_48_UTC:
+ ti = proto_tree_add_item(avsp_tree, hf_avsp_ts_48_utc, tvb, 0, -1,
+ ENC_NA);
+ avsp_48_tree = proto_item_add_subtree(ti, ett_avsp);
+ col_add_str(pinfo->cinfo, COL_INFO, "48bit UTC timestamp");
+ proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_sec, tvb, offset,
+ 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(avsp_48_tree, hf_avsp_ts_48_ns, tvb, offset,
+ 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ break;
+ default:
+ expert_add_info_format(pinfo, avsp_ti, &ei_avsp_ts_unknown_version,
+ "Unknown timestamp version: 0x%0x", version);
+ return tvb_captured_length(tvb);
+ }
+
+ guint16 encap_proto;
+ encap_proto = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_uint(avsp_tree, hf_avsp_etype, tvb, offset, 2, encap_proto);
+ offset += 2;
+
+ ethertype_data_t ethertype_data;
+ ethertype_data.etype = encap_proto;
+ ethertype_data.payload_offset = offset;
+ ethertype_data.fh_tree = avsp_tree;
+ ethertype_data.trailer_id = hf_avsp_trailer;
+ ethertype_data.fcs_len = 0;
+
+ call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, &ethertype_data);
+ break;
+
+ case ARISTA_SUBTYPE_TGEN:
+ proto_tree_add_item_ret_uint(avsp_tree, hf_avsp_tgen_version, tvb,
+ offset, 2, ENC_BIG_ENDIAN, &version);
+ str = try_val_to_str(version, tgen_versions);
+ if (str) {
+ proto_item_append_text(avsp_ti, ", Version: %s", str);
+ }
+ offset += 2;
+
+ switch (version) {
+ case ARISTA_TGEN_VER_1:
+ col_add_str(pinfo->cinfo, COL_INFO, "Arista TGen Frame");
+
+ /* Get TGen Header Control Word. */
+ ti = proto_tree_add_item(avsp_tree, hf_avsp_tgen_hdr, tvb, offset, 6,
+ ENC_NA);
+ avsp_tgen_hdr = proto_item_add_subtree(ti, ett_avsp_tgen_hdr);
+ proto_tree_add_bitmask_ret_uint64(avsp_tgen_hdr, tvb, offset,
+ hf_avsp_tgen_hdr_ctrl, ett_avsp_tgen_hdr_ctrl, avsp_tgen_ctrl,
+ ENC_BIG_ENDIAN, &tgen_ctrl);
+ proto_item_append_text(ti, ", Control Word: 0x%04" PRIx64, tgen_ctrl);
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Ctrl=0x%04" PRIx64, tgen_ctrl);
+ offset += 2;
+
+ /* Get TGen Header Sequence Number*/
+ proto_tree_add_item_ret_uint(avsp_tgen_hdr, hf_avsp_tgen_hdr_seq_num, tvb,
+ offset, 2, ENC_BIG_ENDIAN, &tgen_seq_num);
+ proto_item_append_text(ti, ", Sequence Number: %u", tgen_seq_num);
+ col_append_str_uint(pinfo->cinfo, COL_INFO, "Seq", tgen_seq_num, ", ");
+ offset += 2;
+
+ /* Get TGen Header Payload Length */
+ proto_tree_add_item_ret_uint(avsp_tgen_hdr,
+ hf_avsp_tgen_hdr_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN,
+ &tgen_payload_len);
+ proto_item_append_text(ti, ", Payload Length: %u", tgen_payload_len);
+ col_append_str_uint(pinfo->cinfo, COL_INFO, "Len", tgen_payload_len, ", ");
+ offset += 2;
+
+ /* Try to construct a tvbuff containing only
+ the data specified by the tgen_payload_len field. */
+
+ TRY {
+ tgen_payload_tvb = tvb_new_subset_length(tvb, offset, tgen_payload_len);
+ trailer_tvb = tvb_new_subset_remaining(tvb, offset + tgen_payload_len);
+ }
+ CATCH_BOUNDS_ERRORS {
+ /* Either:
+
+ the packet doesn't have "tgen_payload_len" bytes worth of
+ captured data left in it so the "tvb_new_subset_length()"
+ creating "payload_tvb" threw an exception
+
+ or
+
+ the packet has exactly "tgen_payload_len" bytes worth of
+ captured data left in it, so the "tvb_new_subset_remaining()"
+ creating "trailer_tvb" threw an exception.
+
+ In either case, this means that all the data in the frame
+ is within the length value, so we give all the data to the
+ payload and have no trailer. */
+ tgen_payload_tvb = tvb_new_subset_remaining(tvb, offset);
+ trailer_tvb = NULL;
+ }
+ ENDTRY;
+
+ /* Get the TGen payload captured length. */
+ guint16 tgen_payload_captured_len = tvb_captured_length(tgen_payload_tvb);
+
+ /* Add the TGen payload to the tree, with a heading that displays
+ the TGgen payload captured length. */
+ ti = proto_tree_add_bytes_format(avsp_tree, hf_avsp_tgen_payload_data,
+ tgen_payload_tvb, 0, -1, NULL, "TGen Payload (%u byte%s)",
+ tgen_payload_captured_len,
+ plurality(tgen_payload_captured_len, "", "s"));
+ avsp_tgen_payload = proto_item_add_subtree(ti, ett_avsp_tgen_payload);
+ proto_tree_add_item(avsp_tgen_payload, hf_avsp_tgen_payload_data, tgen_payload_tvb,
+ 0, -1, ENC_NA);
+
+ /* Now we know the TGen payload captured length (which may be less than
+ that specified in the TGen header because the captured frame may have
+ been truncated) we can set the length of the entire AVSP protocol. */
+ proto_item_set_len(avsp_ti, offset + tgen_payload_captured_len);
+
+ /* If there is a trailer, then add it to the tree. */
+ add_ethernet_trailer(pinfo, tree, avsp_tree, hf_avsp_tgen_trailer, tvb, trailer_tvb, -1);
+ break;
+
+ default:
+ expert_add_info_format(pinfo, avsp_ti, &ei_avsp_tgen_unknown_version,
+ "Unknown version: 0x%0x", version);
+ return tvb_captured_length(tvb);
+ }
+ break;
+
+ default:
+ expert_add_info_format(pinfo, avsp_ti, &ei_avsp_unknown_subtype,
+ "Unknown subtype: 0x%0x", subtype);
+ return tvb_captured_length(tvb);
+ }
+ return tvb_captured_length(tvb);
+}
+
+void proto_reg_handoff_avsp(void)
+{
+ dissector_add_uint("ethertype", ETHERTYPE_AVSP, avsp_handle);
+ ethertype_handle = find_dissector_add_dependency("ethertype", proto_avsp);
+}
+
+void proto_register_avsp(void)
+{
+ /* Field Registration */
+ static hf_register_info hf[] = {
+ /* For avsp */
+ {&hf_avsp_subtype,
+ {"Subtype", "avsp.subtype",
+ FT_UINT16, BASE_HEX,
+ VALS(arista_subtypes), 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_version,
+ {"Version", "avsp.ts.ver",
+ FT_UINT16, BASE_HEX,
+ VALS(ts_versions), 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_64_tai,
+ {"Timestamp (TAI)", "avsp.ts.64.tai",
+ FT_NONE, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_64_utc,
+ {"Timestamp (UTC)", "avsp.ts.64.utc",
+ FT_NONE, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_64_sec,
+ {"Seconds", "avsp.ts.64.sec",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_64_ns,
+ {"Nanoseconds", "avsp.ts.64.ns",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_48_tai,
+ {"Timestamp (TAI)", "avsp.ts.48.tai",
+ FT_NONE, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_48_utc,
+ {"Timestamp (UTC)", "avsp.ts.48.utc",
+ FT_NONE, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_48_sec,
+ {"Seconds", "avsp.ts.48.sec",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_ts_48_ns,
+ {"Nanoseconds", "avsp.ts.48.ns",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_etype,
+ {"Type", "avsp.etype",
+ FT_UINT16, BASE_HEX,
+ VALS(etype_vals), 0x0,
+ "Ethertype", HFILL}
+ },
+ {&hf_avsp_trailer,
+ {"Trailer", "avsp.trailer",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ "AVSP Trailer", HFILL}
+ },
+ {&hf_avsp_tgen_version,
+ {"Version", "avsp.tgen.ver",
+ FT_UINT16, BASE_DEC,
+ VALS(tgen_versions), 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_tgen_hdr,
+ {"TGen Header", "avsp.tgen.hdr",
+ FT_NONE, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_tgen_hdr_ctrl,
+ {"Control Word", "avsp.tgen.hdr.ctrl",
+ FT_UINT16, BASE_HEX,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_tgen_hdr_ctrl_fcs_inverted,
+ {"FCS Inverted", "avsp.tgen.hdr.ctrl.fcs_inverted",
+ FT_BOOLEAN, 16,
+ NULL, 0x0001,
+ NULL, HFILL}
+ },
+ {&hf_avsp_tgen_hdr_ctrl_reserved,
+ {"Reserved", "avsp.tgen.hdr.ctrl.reserved",
+ FT_UINT16, BASE_HEX,
+ NULL, 0xFFFE,
+ NULL, HFILL}
+ },
+ {&hf_avsp_tgen_hdr_seq_num,
+ {"Sequence Number", "avsp.tgen.hdr.seq_num",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ {&hf_avsp_tgen_hdr_payload_len,
+ {"Payload Length", "avsp.tgen.hdr.payload_len",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_avsp_tgen_payload,
+ {"TGen Payload", "avsp.tgen.payload",
+ FT_NONE, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_avsp_tgen_payload_data,
+ {"Data", "avsp.tgen.payload.data",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_avsp_tgen_trailer,
+ {"Trailer", "avsp.tgen.trailer",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ "Ethernet Trailer or Checksum", HFILL }
+ },
+ };
+
+ /* Setup protocol subtree array */
+ static gint* ett[] = {
+ &ett_avsp, /* main avsp tree */
+ &ett_avsp_ts_48, /* subtree above for 48 bit timestamp */
+ &ett_avsp_ts_64, /* subtree above for 64 bit timestamp */
+ &ett_avsp_tgen_hdr, /* subtree for TGen header */
+ &ett_avsp_tgen_hdr_ctrl, /* subtree for TGen header control bits */
+ &ett_avsp_tgen_payload, /* subtree for TGen payload */
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_avsp_unknown_subtype, { "avsp.unknown_subtype", PI_SEQUENCE, PI_WARN, "Unknown AVSP subtype", EXPFILL}},
+ { &ei_avsp_ts_unknown_version, { "avsp.ts.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown timestamp version", EXPFILL }},
+ { &ei_avsp_tgen_unknown_version, { "avsp.tgen.unknown_version", PI_SEQUENCE, PI_WARN, "Unknown TGen version", EXPFILL }},
+ };
+
+ /* Register the AVSP protocol. */
+ proto_avsp = proto_register_protocol("Arista Vendor Specific Protocol", "AVSP", "avsp");
+
+ /* Register header fields and subtrees. */
+ proto_register_field_array(proto_avsp, hf, array_length(hf));
+
+ /* Register subtree types. */
+ proto_register_subtree_array(ett, array_length(ett));
+
+ /* Register the expert module. */
+ expert_register_field_array(expert_register_protocol(proto_avsp), ei, array_length(ei));
+
+ /* Register the dissector handle. */
+ avsp_handle = register_dissector("avsp", dissect_avsp, proto_avsp);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */