aboutsummaryrefslogtreecommitdiffstats
path: root/tools/dissectors/epan
diff options
context:
space:
mode:
Diffstat (limited to 'tools/dissectors/epan')
-rw-r--r--tools/dissectors/epan/octoclock/CMakeLists.txt25
-rw-r--r--tools/dissectors/epan/octoclock/packet-octoclock.c203
-rw-r--r--tools/dissectors/epan/octoclock/plugin.rc.in35
-rw-r--r--tools/dissectors/epan/rfnoc/CMakeLists.txt27
-rw-r--r--tools/dissectors/epan/rfnoc/packet-rfnoc.cpp705
-rw-r--r--tools/dissectors/epan/rfnoc/plugin.rc.in35
-rw-r--r--tools/dissectors/epan/zpu/CMakeLists.txt25
-rw-r--r--tools/dissectors/epan/zpu/packet-zpu.c245
-rw-r--r--tools/dissectors/epan/zpu/plugin.rc.in35
-rw-r--r--tools/dissectors/epan/zpu/zpu_addr_names.h39
10 files changed, 1374 insertions, 0 deletions
diff --git a/tools/dissectors/epan/octoclock/CMakeLists.txt b/tools/dissectors/epan/octoclock/CMakeLists.txt
new file mode 100644
index 000000000..dcc8077c9
--- /dev/null
+++ b/tools/dissectors/epan/octoclock/CMakeLists.txt
@@ -0,0 +1,25 @@
+set_module_info(octoclock 4 0 0 0)
+
+set(DISSECTOR_SRC
+ ${CMAKE_CURRENT_SOURCE_DIR}/packet-octoclock.c
+)
+
+set(PLUGIN_FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/plugin.c
+ ${DISSECTOR_SRC}
+)
+
+register_plugin_files(${CMAKE_CURRENT_BINARY_DIR}/plugin.c
+ plugin
+ ${DISSECTOR_SRC}
+)
+
+add_plugin_library(octoclock epan)
+
+set_target_properties(octoclock PROPERTIES PREFIX "")
+set_target_properties(octoclock PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}")
+target_link_libraries(octoclock wireshark epan)
+
+install_plugin(octoclock epan)
+
+
diff --git a/tools/dissectors/epan/octoclock/packet-octoclock.c b/tools/dissectors/epan/octoclock/packet-octoclock.c
new file mode 100644
index 000000000..e8e5e6858
--- /dev/null
+++ b/tools/dissectors/epan/octoclock/packet-octoclock.c
@@ -0,0 +1,203 @@
+/*
+ * Dissector for Ettus Octoclock packets
+ *
+ * Copyright 2016 Ettus Research
+ * Copyright 2019 Ettus Research, a National Instruments brand
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#include "../../../../host/lib/usrp_clock/octoclock/common.h"
+
+#define LOG_HEADER "[Octoclock] "
+#define size_mem(t,m) sizeof(((t*)0)->m)
+#define packet_elem_size(m) (size_mem(octoclock_packet_t,m))
+#define packet_offset(m) (offsetof(octoclock_packet_t, m))
+const unsigned int OCTOCLOCK_PORT = OCTOCLOCK_UDP_CTRL_PORT;
+
+static int proto_octo = -1;
+static int hf_octo_proto_version = -1;
+static int hf_octo_proto_sequence = -1;
+static int hf_octo_proto_code = -1;
+static int hf_octo_proto_poolsize = -1;
+static int hf_octo_proto_data = -1;
+static int hf_octo_proto_payload = -1;
+static int hf_octo_proto_len = -1;
+static gint ett_octo = -1;
+static const value_string packetcodes[] = {
+ {1, "OCTOCLOCK_QUERY_CMD"},
+ {2, "OCTOCLOCK_QUERY_ACK"},
+ {3, "SEND_EEPROM_CMD"},
+ {4, "SEND_EEPROM_ACK"},
+ {5, "BURN_EEPROM_CMD"},
+ {6, "BURN_EEPROM_SUCCESS_ACK"},
+ {7, "BURN_EEPROM_FAILURE_ACK"},
+ {8, "CLEAR_EEPROM_CMD"},
+ {9, "CLEAR_EEPROM_ACK"},
+ {10, "SEND_STATE_CMD"},
+ {11, "SEND_STATE_ACK"},
+ {12, "RESET_CMD"},
+ {13, "RESET_ACK"},
+ {14, "HOST_SEND_TO_GPSDO_CMD"},
+ {15, "HOST_SEND_TO_GPSDO_ACK"},
+ {16, "SEND_POOLSIZE_CMD"},
+ {17, "SEND_POOLSIZE_ACK"},
+ {18, "SEND_CACHE_STATE_CMD"},
+ {19, "SEND_CACHE_STATE_ACK"},
+ {20, "SEND_GPSDO_CACHE_CMD"},
+ {21, "SEND_GPSDO_CACHE_ACK"},
+ {22, "PREPARE_FW_BURN_CMD"},
+ {23, "FW_BURN_READY_ACK"},
+ {24, "FILE_TRANSFER_CMD"},
+ {25, "FILE_TRANSFER_ACK"},
+ {26, "READ_FW_CMD"},
+ {27, "READ_FW_ACK"},
+ {28, "FINALIZE_BURNING_CMD"},
+ {29, "FINALIZE_BURNING_ACK"},
+ { 0, NULL }
+};
+/* Forward-declare the dissector functions */
+void proto_register_octo(void);
+void proto_reg_handoff_octo(void);
+static int dissect_octo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
+
+static int dissect_octo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "OCTO");
+ col_clear(pinfo->cinfo, COL_INFO);
+ proto_item *ti = proto_tree_add_item(tree, proto_octo, tvb, 0, -1, ENC_NA);
+ proto_tree *octo_tree = proto_item_add_subtree(ti, ett_octo);
+ proto_tree_add_item(octo_tree,
+ hf_octo_proto_version,
+ tvb,
+ packet_offset(proto_ver),
+ packet_elem_size(proto_ver),
+ ENC_LITTLE_ENDIAN);
+ guint32 rev = tvb_get_letohl(tvb, packet_offset(proto_ver));
+ if(rev==3)
+ {
+ proto_tree_add_item(octo_tree,
+ hf_octo_proto_sequence,
+ tvb,
+ packet_offset(sequence),
+ packet_elem_size(sequence),
+ ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(octo_tree,
+ hf_octo_proto_code,
+ tvb,
+ packet_offset(code),
+ packet_elem_size(code),
+ ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(octo_tree,
+ hf_octo_proto_poolsize,
+ tvb,
+ packet_offset(poolsize),
+ packet_elem_size(poolsize),
+ ENC_LITTLE_ENDIAN);
+
+ //packet_code_t code = (packet_code_t)(tvb_get_guint8(tvb, packet_offset(code)));
+
+ guint16 len = tvb_get_letohs(tvb, packet_offset(len));
+ if(len && len <= packet_elem_size(data))
+ {
+ proto_tree_add_item(octo_tree,
+ hf_octo_proto_payload,
+ tvb,
+ packet_offset(data),
+ len,
+ ENC_LITTLE_ENDIAN);
+ }
+ proto_tree_add_item(octo_tree,
+ hf_octo_proto_data,
+ tvb,
+ packet_offset(data),
+ packet_elem_size(data),
+ ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(octo_tree,
+ hf_octo_proto_len,
+ tvb,
+ packet_offset(len),
+ packet_elem_size(len),
+ ENC_LITTLE_ENDIAN);
+ return len;
+ }
+ return 0;
+}
+
+
+void proto_register_octo(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_octo_proto_version,
+ { "version", "octo.rev",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ "Protocol Revision", HFILL }
+ },
+ { &hf_octo_proto_sequence,
+ { "sequence number", "octo.seq",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_octo_proto_code,
+ { "code", "octo.code",
+ FT_UINT8, BASE_DEC,
+ VALS(packetcodes), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_octo_proto_poolsize,
+ { "poolsize", "octo.poolsize",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_octo_proto_payload,
+ { "payload", "octo.payload",
+ FT_STRING, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_octo_proto_data,
+ { "data", "octo.data",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_octo_proto_len,
+ { "length", "octo.len",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ }
+ };
+ //protocol subtree array
+ static gint *ett[] = {
+ &ett_octo
+ };
+ proto_octo = proto_register_protocol(
+ "Octoclock",
+ "Octoclock",
+ "octo"
+ );
+
+ proto_register_field_array(proto_octo, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ register_dissector("octo", dissect_octo, proto_octo);
+}
+
+void proto_reg_handoff_octo(void)
+{
+ static dissector_handle_t octo_handle;
+ octo_handle = create_dissector_handle(dissect_octo, proto_octo);
+ dissector_add_uint_with_preference("udp.port", OCTOCLOCK_PORT, octo_handle);
+ dissector_add_uint_with_preference("udp.port", OCTOCLOCK_UDP_GPSDO_PORT, octo_handle);
+}
diff --git a/tools/dissectors/epan/octoclock/plugin.rc.in b/tools/dissectors/epan/octoclock/plugin.rc.in
new file mode 100644
index 000000000..eca74e1a7
--- /dev/null
+++ b/tools/dissectors/epan/octoclock/plugin.rc.in
@@ -0,0 +1,35 @@
+#include "winver.h"
+#pragma code_page(65001)
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @RC_MODULE_VERSION@
+ PRODUCTVERSION @RC_VERSION@
+ FILEFLAGSMASK 0x0L
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Ettus Research (National Instruments)\0"
+ VALUE "FileDescription", "@MODULE_NAME@ dissector\0"
+ VALUE "FileVersion", "@MODULE_VERSION@\0"
+ VALUE "InternalName", "@MODULE_NAME@ @MODULE_VERSION@\0"
+ VALUE "LegalCopyright", "Copyright © 2019 Ettus Research (National Instruments)\0"
+ VALUE "OriginalFilename", "@MODULE_NAME@.dll\0"
+ VALUE "ProductName", "Wireshark\0"
+ VALUE "ProductVersion", "@PROJECT_VERSION@\0"
+ VALUE "Comments", "Build with @MSVC_VARIANT@\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/tools/dissectors/epan/rfnoc/CMakeLists.txt b/tools/dissectors/epan/rfnoc/CMakeLists.txt
new file mode 100644
index 000000000..3c021a464
--- /dev/null
+++ b/tools/dissectors/epan/rfnoc/CMakeLists.txt
@@ -0,0 +1,27 @@
+set_module_info(rfnoc 4 0 0 0)
+
+set(DISSECTOR_SRC
+ ${CMAKE_CURRENT_SOURCE_DIR}/packet-rfnoc.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../host/lib/exception.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../host/lib/rfnoc/chdr_types.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../host/lib/rfnoc/chdr_packet.cpp
+)
+
+set(PLUGIN_FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/plugin.c
+ ${DISSECTOR_SRC}
+)
+
+register_plugin_files(${CMAKE_CURRENT_BINARY_DIR}/plugin.c
+ plugin
+ ${DISSECTOR_SRC}
+)
+
+add_plugin_library(rfnoc epan)
+
+set_target_properties(rfnoc PROPERTIES PREFIX "")
+set_target_properties(rfnoc PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}")
+target_link_libraries(rfnoc wireshark epan)
+
+install_plugin(rfnoc epan)
+
diff --git a/tools/dissectors/epan/rfnoc/packet-rfnoc.cpp b/tools/dissectors/epan/rfnoc/packet-rfnoc.cpp
new file mode 100644
index 000000000..23672793e
--- /dev/null
+++ b/tools/dissectors/epan/rfnoc/packet-rfnoc.cpp
@@ -0,0 +1,705 @@
+/*
+ * Dissector for UHD RFNoC (CHDR) packets
+ *
+ * Copyright 2019 Ettus Research, a National Instruments brand
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <cstdio>
+#include <iostream>
+
+#include "../../../../host/lib/usrp/x300/x300_fw_common.h"
+#include <uhdlib/rfnoc/chdr_packet.hpp>
+
+constexpr unsigned int RFNOC_PORT = X300_VITA_UDP_PORT;
+static const uhd::rfnoc::chdr::chdr_packet_factory pkt_factory(uhd::rfnoc::CHDR_W_64, uhd::ENDIANNESS_BIG);
+
+static int proto_rfnoc = -1;
+static int hf_rfnoc_hdr = -1;
+static int hf_rfnoc_hdr_vc = -1;
+static int hf_rfnoc_hdr_eob = -1;
+static int hf_rfnoc_hdr_eov = -1;
+static int hf_rfnoc_hdr_pkttype = -1;
+static int hf_rfnoc_hdr_num_mdata = -1;
+static int hf_rfnoc_hdr_seqnum = -1;
+static int hf_rfnoc_hdr_len = -1;
+static int hf_rfnoc_hdr_dst_epid = -1;
+static int hf_rfnoc_timestamp = -1;
+static int hf_rfnoc_src_epid = -1;
+static int hf_rfnoc_ctrl = -1;
+static int hf_rfnoc_ctrl_dst_port = -1;
+static int hf_rfnoc_ctrl_src_port = -1;
+static int hf_rfnoc_ctrl_num_data = -1;
+static int hf_rfnoc_ctrl_seqnum = -1;
+static int hf_rfnoc_ctrl_is_ack = -1;
+static int hf_rfnoc_ctrl_address = -1;
+static int hf_rfnoc_ctrl_data0 = -1;
+static int hf_rfnoc_ctrl_data = -1; // TODO: Figure out what to do here
+static int hf_rfnoc_ctrl_byte_enable = -1;
+static int hf_rfnoc_ctrl_opcode = -1;
+static int hf_rfnoc_ctrl_status = -1;
+static int hf_rfnoc_strs = -1;
+static int hf_rfnoc_strs_status = -1;
+static int hf_rfnoc_strs_capacity_bytes = -1;
+static int hf_rfnoc_strs_capacity_pkts = -1;
+static int hf_rfnoc_strs_xfer_bytes = -1;
+static int hf_rfnoc_strs_xfer_pkts = -1;
+static int hf_rfnoc_strs_buff_info = -1;
+static int hf_rfnoc_strs_ext_status = -1;
+static int hf_rfnoc_strc = -1;
+static int hf_rfnoc_strc_opcode = -1;
+static int hf_rfnoc_strc_data = -1;
+static int hf_rfnoc_strc_num_pkts = -1;
+static int hf_rfnoc_strc_num_bytes = -1;
+static int hf_rfnoc_mgmt = -1;
+static int hf_rfnoc_mgmt_protover = -1;
+static int hf_rfnoc_mgmt_chdr_w = -1;
+static int hf_rfnoc_mgmt_num_hops = -1;
+static int hf_rfnoc_mgmt_hop = -1;
+static int hf_rfnoc_mgmt_op = -1;
+static int hf_rfnoc_mgmt_op_code = -1;
+static int hf_rfnoc_mgmt_op_dest = -1;
+static int hf_rfnoc_mgmt_op_device_id = -1;
+static int hf_rfnoc_mgmt_op_node_type = -1;
+static int hf_rfnoc_mgmt_op_node_inst = -1;
+static int hf_rfnoc_mgmt_op_cfg_address = -1;
+static int hf_rfnoc_mgmt_op_cfg_data = -1;
+
+static const value_string RFNOC_PACKET_TYPES[] = {
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_MGMT, "Management" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_STRS, "Stream Status" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_STRC, "Stream Command" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_CTRL, "Control" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_DATA_NO_TS, "Data" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_DATA_WITH_TS, "Data with Timestamp" },
+};
+
+static const value_string RFNOC_PACKET_TYPES_SHORT[] = {
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_MGMT, "mgmt" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_STRS, "strs" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_STRC, "strc" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_CTRL, "ctrl" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_DATA_NO_TS, "data" },
+ { uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_DATA_WITH_TS, "data" },
+};
+
+static const value_string RFNOC_CTRL_STATUS[] = {
+ { uhd::rfnoc::chdr::ctrl_status_t::CMD_OKAY, "OK" },
+ { uhd::rfnoc::chdr::ctrl_status_t::CMD_CMDERR, "CMDERR" },
+ { uhd::rfnoc::chdr::ctrl_status_t::CMD_TSERR, "TSERR" },
+ { uhd::rfnoc::chdr::ctrl_status_t::CMD_WARNING, "WARNING" },
+};
+
+static const value_string RFNOC_CTRL_OPCODES[] = {
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_SLEEP, "sleep" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_WRITE, "write" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_READ, "read" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_READ_WRITE, "r/w" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_BLOCK_WRITE, "block write" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_BLOCK_READ, "block read" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_POLL, "poll" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_USER1, "user1" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_USER2, "user2" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_USER3, "user3" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_USER4, "user4" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_USER5, "user5" },
+ { uhd::rfnoc::chdr::ctrl_opcode_t::OP_USER6, "user6" },
+};
+
+static const value_string RFNOC_STRS_STATUS[] = {
+ { uhd::rfnoc::chdr::strs_status_t::STRS_OKAY, "OK" },
+ { uhd::rfnoc::chdr::strs_status_t::STRS_CMDERR, "CMDERR" },
+ { uhd::rfnoc::chdr::strs_status_t::STRS_SEQERR, "SEQERR" },
+ { uhd::rfnoc::chdr::strs_status_t::STRS_DATAERR, "DATAERR" },
+ { uhd::rfnoc::chdr::strs_status_t::STRS_RTERR, "RTERR" },
+};
+
+static const value_string RFNOC_STRC_OPCODES[] = {
+ { uhd::rfnoc::chdr::strc_op_code_t::STRC_INIT, "init" },
+ { uhd::rfnoc::chdr::strc_op_code_t::STRC_PING, "ping" },
+ { uhd::rfnoc::chdr::strc_op_code_t::STRC_RESYNC, "resync" },
+};
+
+static const value_string RFNOC_MGMT_OPCODES[] = {
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_NOP, "nop" },
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_ADVERTISE, "advertise" },
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_SEL_DEST, "select_dest" },
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_RETURN, "return_to_sender" },
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_INFO_REQ, "node_info_req" },
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_INFO_RESP, "node_info_resp" },
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_CFG_WR_REQ, "cfg_wr_req" },
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_CFG_RD_REQ, "cfg_rd_req" },
+ { uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_CFG_RD_RESP, "cfg_rd_resp" },
+};
+
+/* the heuristic dissector is called on every packet with payload.
+ * The warning printed for this should only be printed once.
+ */
+static int heur_warning_printed = 0;
+
+/* Subtree handles: set by register_subtree_array */
+static gint ett_rfnoc = -1;
+static gint ett_rfnoc_hdr = -1;
+static gint ett_rfnoc_ctrl = -1;
+static gint ett_rfnoc_strs = -1;
+static gint ett_rfnoc_strc = -1;
+static gint ett_rfnoc_mgmt = -1;
+static gint ett_rfnoc_mgmt_hop = -1;
+static gint ett_rfnoc_mgmt_hop_op = -1;
+
+/* Forward-declare the dissector functions */
+static int dissect_rfnoc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
+
+/* The dissector itself */
+static int dissect_rfnoc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ // Here are all the variables
+ proto_item *item;
+ proto_tree *rfnoc_tree;
+ proto_item *header_item;
+ proto_tree *header_tree;
+ proto_item *ctrl_item;
+ proto_tree *ctrl_tree;
+ proto_item *strs_item;
+ proto_tree *strs_tree;
+ proto_item *strc_item;
+ proto_tree *strc_tree;
+ proto_item *mgmt_item;
+ proto_tree *mgmt_tree;
+ proto_item *hop_item;
+ proto_tree *hop_tree;
+ proto_item *mgmt_op_item;
+ proto_tree *mgmt_op_tree;
+ gint len;
+
+ guint64 hdr;
+ gint flag_offset;
+ guint8 *bytes;
+ guint8 hdr_bits = 0;
+ uint64_t timestamp;
+ int chdr_len = 0;
+ gboolean is_network;
+ gint endianness;
+ size_t offset = 0;
+ /* FIXME: Assuming CHDR_W_64 */
+ size_t chdr_w_bytes = 8;
+
+ if (pinfo->match_uint == RFNOC_PORT) {
+ is_network = TRUE;
+ flag_offset = 0;
+ endianness = ENC_BIG_ENDIAN;
+ }
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RFNoC");
+ /* Clear out stuff in info column */
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ len = tvb_reported_length(tvb);
+
+ if (tree){
+ guint64 hdr = tvb_get_ntoh64(tvb, 0);
+ uhd::rfnoc::chdr::chdr_header chdr_hdr(hdr);
+ chdr_len = chdr_hdr.get_length();
+ len = (len < chdr_len) ? len : chdr_len;
+
+ /* Start with a top-level item to add everything else to */
+ item = proto_tree_add_item(tree, proto_rfnoc, tvb, offset, len, ENC_NA);
+
+ if (len >= 4) {
+ rfnoc_tree = proto_item_add_subtree(item, ett_rfnoc);
+ proto_item_append_text(item, ", Packet type: %s, Dst EPID: %d",
+ val_to_str(chdr_hdr.get_pkt_type(), RFNOC_PACKET_TYPES, "Unknown (0x%x)"), chdr_hdr.get_dst_epid()
+ );
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s dst_epid=%d",
+ val_to_str(chdr_hdr.get_pkt_type(), RFNOC_PACKET_TYPES_SHORT, "Unknown (0x%x)"), chdr_hdr.get_dst_epid()
+ );
+
+ /* Header info. First, a top-level header tree item: */
+ header_item = proto_tree_add_item(rfnoc_tree, hf_rfnoc_hdr, tvb, offset, 8, endianness);
+ header_tree = proto_item_add_subtree(header_item, ett_rfnoc_hdr);
+ /* Let us query hdr.type */
+ proto_tree_add_string(
+ header_tree, hf_rfnoc_hdr_pkttype, tvb, offset+1, 1,
+ val_to_str(chdr_hdr.get_pkt_type(), RFNOC_PACKET_TYPES_SHORT, "invalid")
+ );
+
+ /* Add Dst EPID */
+ proto_item_append_text(header_item, ", Dst EPID: %02x", chdr_hdr.get_dst_epid());
+ proto_tree_add_uint(header_tree, hf_rfnoc_hdr_dst_epid, tvb, offset+6, 2, chdr_hdr.get_dst_epid());
+ /* Add length */
+ proto_tree_add_uint(header_tree, hf_rfnoc_hdr_len, tvb, offset+4, 2, chdr_hdr.get_length());
+ /* Add sequence number */
+ proto_tree_add_uint(header_tree, hf_rfnoc_hdr_seqnum, tvb, offset+2, 2, chdr_hdr.get_seq_num());
+
+ if (chdr_hdr.get_num_mdata()) {
+ /* Can't decode packets with metadata */
+ return len;
+ }
+
+ /* TODO: Update offsets if there is a timestamp. Also update lengths */
+ /* Add subtree based on packet type */
+ uhd::rfnoc::chdr::packet_type_t pkttype = chdr_hdr.get_pkt_type();
+ offset += 8;
+ if (pkttype == uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_CTRL) {
+ ctrl_item = proto_tree_add_item(rfnoc_tree, hf_rfnoc_ctrl, tvb, 8, chdr_len-8, endianness);
+ ctrl_tree = proto_item_add_subtree(ctrl_item, ett_rfnoc_ctrl);
+ auto pkt = pkt_factory.make_ctrl();
+ pkt->refresh(tvb_get_ptr(tvb, 0, chdr_len));
+ auto payload = pkt->get_payload();
+
+ /* Add source EPID */
+ proto_tree_add_uint(ctrl_tree, hf_rfnoc_src_epid, tvb, offset+2, 2, payload.src_epid);
+ /* Add source port */
+ proto_tree_add_uint(ctrl_tree, hf_rfnoc_ctrl_src_port, tvb, offset+5, 2, payload.src_port);
+ /* Add dest port */
+ proto_tree_add_uint(ctrl_tree, hf_rfnoc_ctrl_dst_port, tvb, offset+6, 2, payload.dst_port);
+ /* Add num data */
+ proto_tree_add_uint(ctrl_tree, hf_rfnoc_ctrl_num_data, tvb, offset+5, 1, payload.data_vtr.size());
+ /* Add is_ack */
+ proto_tree_add_boolean(ctrl_tree, hf_rfnoc_ctrl_is_ack, tvb, offset+4, 1, payload.is_ack);
+ /* Add sequence number */
+ proto_tree_add_uint(ctrl_tree, hf_rfnoc_ctrl_seqnum, tvb, offset+4, 1, payload.seq_num);
+ if (payload.timestamp) {
+ proto_tree_add_uint64(ctrl_tree, hf_rfnoc_timestamp, tvb, offset+8, 8, *payload.timestamp);
+ offset += 8;
+ }
+ /* Add data0 */
+ proto_tree_add_uint(ctrl_tree, hf_rfnoc_ctrl_data0, tvb, offset+8, 4, payload.data_vtr[0]);
+ /* Add op code */
+ proto_tree_add_string(
+ ctrl_tree, hf_rfnoc_ctrl_opcode, tvb, offset+12, 1,
+ val_to_str(payload.op_code, RFNOC_CTRL_OPCODES, "reserved")
+ );
+ /* Add address */
+ proto_tree_add_uint(ctrl_tree, hf_rfnoc_ctrl_address, tvb, offset+13, 3, payload.address);
+ }
+
+ if (pkttype == uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_STRS) {
+ strs_item = proto_tree_add_item(rfnoc_tree, hf_rfnoc_strs, tvb, offset, chdr_len-8, endianness);
+ strs_tree = proto_item_add_subtree(strs_item, ett_rfnoc_strs);
+ auto pkt = pkt_factory.make_strs();
+ pkt->refresh(tvb_get_ptr(tvb, 0, chdr_len));
+ auto payload = pkt->get_payload();
+
+ proto_tree_add_string(
+ strs_tree, hf_rfnoc_strs_status, tvb, offset+5, 1,
+ val_to_str(payload.status, RFNOC_STRS_STATUS, "invalid")
+ );
+
+ /* Add source EPID */
+ proto_tree_add_uint(strs_tree, hf_rfnoc_src_epid, tvb, offset+6, 2, payload.src_epid);
+ /* Add capacities */
+ proto_tree_add_uint64(strs_tree, hf_rfnoc_strs_capacity_bytes, tvb, offset, 5, payload.capacity_bytes);
+ proto_tree_add_uint(strs_tree, hf_rfnoc_strs_capacity_pkts, tvb, offset+13, 3, payload.capacity_pkts);
+ /* Add xfer amounts */
+ proto_tree_add_uint64(strs_tree, hf_rfnoc_strs_xfer_bytes, tvb, offset+16, 8, payload.xfer_count_bytes);
+ proto_tree_add_uint64(strs_tree, hf_rfnoc_strs_xfer_pkts, tvb, offset+8, 5, payload.xfer_count_pkts);
+ }
+
+ if (pkttype == uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_STRC) {
+ strc_item = proto_tree_add_item(rfnoc_tree, hf_rfnoc_strc, tvb, 8, chdr_len-8, endianness);
+ strc_tree = proto_item_add_subtree(strc_item, ett_rfnoc_strc);
+ auto pkt = pkt_factory.make_strc();
+ pkt->refresh(tvb_get_ptr(tvb, 0, chdr_len));
+ auto payload = pkt->get_payload();
+
+ proto_tree_add_string(
+ strc_tree, hf_rfnoc_strc_opcode, tvb, offset+5, 1,
+ val_to_str(payload.op_code, RFNOC_STRC_OPCODES, "invalid")
+ );
+
+ /* Add source EPID */
+ proto_tree_add_uint(strc_tree, hf_rfnoc_src_epid, tvb, offset+6, 2, payload.src_epid);
+ /* Add transfer amounts */
+ proto_tree_add_uint64(strc_tree, hf_rfnoc_strc_num_bytes, tvb, offset+8, 8, payload.num_bytes);
+ proto_tree_add_uint64(strc_tree, hf_rfnoc_strc_num_pkts, tvb, offset, 5, payload.num_pkts);
+ }
+
+ if (pkttype == uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_MGMT) {
+ mgmt_item = proto_tree_add_item(rfnoc_tree, hf_rfnoc_mgmt, tvb, offset, len-8, endianness);
+ mgmt_tree = proto_item_add_subtree(mgmt_item, ett_rfnoc_mgmt);
+ auto pkt = pkt_factory.make_mgmt();
+ pkt->refresh(tvb_get_ptr(tvb, 0, chdr_len));
+ auto payload = pkt->get_payload();
+ /* Add source EPID */
+ proto_tree_add_uint(mgmt_tree, hf_rfnoc_src_epid, tvb, offset+6, 2, payload.get_src_epid());
+ size_t num_hops = payload.get_num_hops();
+ offset += 8;
+
+ /* FIXME: Assuming CHDR_W_64 here */
+ for (size_t hop_id = 0; hop_id < num_hops; hop_id++) {
+ auto hop = payload.get_hop(hop_id);
+ size_t num_ops = hop.get_num_ops();
+ hop_item = proto_tree_add_item(mgmt_tree, hf_rfnoc_mgmt_hop, tvb, offset, num_ops*chdr_w_bytes, endianness);
+ hop_tree = proto_item_add_subtree(hop_item, ett_rfnoc_mgmt_hop);
+ for (size_t op_id = 0; op_id < num_ops; op_id++) {
+ auto op = hop.get_op(op_id);
+ auto opcode = op.get_op_code();
+ mgmt_op_item = proto_tree_add_item(hop_tree, hf_rfnoc_mgmt_op, tvb, offset, chdr_w_bytes, endianness);
+ mgmt_op_tree = proto_item_add_subtree(mgmt_op_item, ett_rfnoc_mgmt_hop_op);
+
+ /* Add op code */
+ proto_tree_add_string(
+ mgmt_op_tree, hf_rfnoc_mgmt_op_code, tvb, offset+6, 1,
+ val_to_str(opcode, RFNOC_MGMT_OPCODES, "invalid")
+ );
+
+ /* Add op payload */
+ if (opcode == uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_SEL_DEST) {
+ auto opdata = uhd::rfnoc::chdr::mgmt_op_t::sel_dest_payload(
+ op.get_op_payload());
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_dest, tvb, offset+4, 2, opdata.dest);
+ } else if (opcode == uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_INFO_RESP) {
+ auto opdata = uhd::rfnoc::chdr::mgmt_op_t::node_info_payload(
+ op.get_op_payload());
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_device_id, tvb, offset, 6, opdata.device_id);
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_node_type, tvb, offset, 6, opdata.node_type);
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_node_inst, tvb, offset, 6, opdata.node_inst);
+ } else if (opcode == uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_CFG_WR_REQ) {
+ auto opdata = uhd::rfnoc::chdr::mgmt_op_t::cfg_payload(
+ op.get_op_payload());
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_cfg_address, tvb, offset, 6, opdata.addr);
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_cfg_data, tvb, offset, 6, opdata.data);
+ } else if (opcode == uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_CFG_RD_REQ) {
+ auto opdata = uhd::rfnoc::chdr::mgmt_op_t::cfg_payload(
+ op.get_op_payload());
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_cfg_address, tvb, offset, 6, opdata.addr);
+ } else if (opcode == uhd::rfnoc::chdr::mgmt_op_t::op_code_t::MGMT_OP_CFG_RD_RESP) {
+ auto opdata = uhd::rfnoc::chdr::mgmt_op_t::cfg_payload(
+ op.get_op_payload());
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_cfg_address, tvb, offset, 6, opdata.addr);
+ proto_tree_add_uint(mgmt_op_tree, hf_rfnoc_mgmt_op_cfg_data, tvb, offset, 6, opdata.data);
+ }
+ offset += chdr_w_bytes;
+ }
+ }
+ }
+ if (pkttype == uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_DATA_NO_TS) {
+ }
+ if (pkttype == uhd::rfnoc::chdr::packet_type_t::PKT_TYPE_DATA_WITH_TS) {
+ auto pkt = pkt_factory.make_generic();
+ pkt->refresh(tvb_get_ptr(tvb, 0, chdr_len));
+ proto_tree_add_uint64(rfnoc_tree, hf_rfnoc_timestamp, tvb, offset+8, 8, *(pkt->get_timestamp()));
+ }
+ }
+ }
+ return len;
+}
+
+extern "C"
+void proto_register_rfnoc(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_rfnoc_hdr,
+ { "Header", "rfnoc.hdr",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_hdr_pkttype,
+ { "Packet Type", "rfnoc.hdr.pkttype",
+ FT_STRINGZ, BASE_NONE,
+ NULL, 0x00,
+ "Packet Type", HFILL }
+ },
+ { &hf_rfnoc_hdr_vc,
+ { "Virtual Channel", "rfnoc.hdr.vc",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_hdr_eob,
+ { "End Of Burst", "rfnoc.hdr.eob",
+ FT_BOOLEAN, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_hdr_eov,
+ { "End Of Vector", "rfnoc.hdr.eov",
+ FT_BOOLEAN, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_hdr_num_mdata,
+ { "Num Mdata", "rfnoc.hdr.nummdata",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_hdr_seqnum,
+ { "Sequence Number", "rfnoc.hdr.seqnum",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_hdr_len,
+ { "RFNoC Length", "rfnoc.hdr.len",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_hdr_dst_epid,
+ { "Dst EPID", "rfnoc.hdr.dst_epid",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_timestamp,
+ { "Timestamp", "rfnoc.timestamp",
+ FT_UINT64, BASE_HEX,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl,
+ { "CTRL Payload", "rfnoc.ctrl",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_dst_port,
+ { "Dst Port", "rfnoc.ctrl.dst_port",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_src_port,
+ { "Src Port", "rfnoc.ctrl.src_port",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_num_data,
+ { "Num Data", "rfnoc.ctrl.num_data",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_data0,
+ { "Data0", "rfnoc.ctrl.data0",
+ FT_UINT32, BASE_HEX,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_seqnum,
+ { "Seq Num", "rfnoc.ctrl.seqnum",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_is_ack,
+ { "Is ACK", "rfnoc.ctrl.is_ack",
+ FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_src_epid,
+ { "Src EPID", "rfnoc.src_epid",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_address,
+ { "Address", "rfnoc.ctrl.address",
+ FT_UINT16, BASE_HEX,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_opcode,
+ { "Op Code", "rfnoc.ctrl.opcode",
+ FT_STRINGZ, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_ctrl_status,
+ { "Status", "rfnoc.ctrl.status",
+ FT_STRINGZ, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strs,
+ { "Stream Status", "rfnoc.strs",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strs_status,
+ { "Status", "rfnoc.strs.status",
+ FT_STRINGZ, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strs_capacity_bytes,
+ { "Capacity Bytes", "rfnoc.strs.capacity_bytes",
+ FT_UINT64, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strs_capacity_pkts,
+ { "Capacity Packets", "rfnoc.strs.capacity_pkts",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strs_xfer_bytes,
+ { "Xfer Count Bytes", "rfnoc.strs.xfer_bytes",
+ FT_UINT64, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strs_xfer_pkts,
+ { "Xfer Count Packets", "rfnoc.strs.xfer_pkts",
+ FT_UINT64, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strc,
+ { "Stream Command", "rfnoc.strc",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strc_opcode,
+ { "Opcode", "rfnoc.strc.opcode",
+ FT_STRINGZ, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strc_num_bytes,
+ { "Num Bytes", "rfnoc.strc.num_bytes",
+ FT_UINT64, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_strc_num_pkts,
+ { "Num Packets", "rfnoc.strc.num_pkts",
+ FT_UINT64, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt,
+ { "Mgmt Xact", "rfnoc.mgmt",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_protover,
+ { "Protocol Version", "rfnoc.mgmt.protover",
+ FT_UINT16, BASE_HEX,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_chdr_w,
+ { "CHDR Width", "rfnoc.mgmt.chdr_w",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_num_hops,
+ { "Num Hops", "rfnoc.mgmt.num_hops",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_hop,
+ { "Hop", "rfnoc.mgmt.hop",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_op,
+ { "Operation", "rfnoc.mgmt.op",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_op_code,
+ { "Opcode", "rfnoc.mgmt.op.op_code",
+ FT_STRINGZ, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_op_dest,
+ { "Destination", "rfnoc.mgmt.op.dest",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_op_device_id,
+ { "Device ID", "rfnoc.mgmt.op.device_id",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_op_node_type,
+ { "Node Type", "rfnoc.mgmt.op.node_type",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_op_node_inst,
+ { "Node Instance", "rfnoc.mgmt.op.node_inst",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_op_cfg_address,
+ { "Address", "rfnoc.mgmt.op.cfg_address",
+ FT_UINT16, BASE_HEX,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_rfnoc_mgmt_op_cfg_data,
+ { "Data", "rfnoc.mgmt.op.cfg_data",
+ FT_UINT32, BASE_HEX,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+
+ };
+
+ static gint *ett[] = {
+ &ett_rfnoc,
+ &ett_rfnoc_hdr,
+ &ett_rfnoc_ctrl,
+ &ett_rfnoc_strs,
+ &ett_rfnoc_strc,
+ &ett_rfnoc_mgmt,
+ &ett_rfnoc_mgmt_hop,
+ &ett_rfnoc_mgmt_hop_op,
+ };
+
+ module_t *rfnoc_module;
+
+ proto_rfnoc = proto_register_protocol("UHD RFNoC", "RFNoC", "rfnoc");
+ proto_register_field_array(proto_rfnoc, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ rfnoc_module = prefs_register_protocol(proto_rfnoc, NULL);
+}
+
+/* Handler registration */
+extern "C"
+void proto_reg_handoff_rfnoc(void)
+{
+ static gboolean initialized = FALSE;
+ static dissector_handle_t rfnoc_handle;
+ static uint16_t current_port = RFNOC_PORT;
+
+ rfnoc_handle = create_dissector_handle(dissect_rfnoc, proto_rfnoc);
+ dissector_add_uint_with_preference("udp.port", current_port, rfnoc_handle);
+}
diff --git a/tools/dissectors/epan/rfnoc/plugin.rc.in b/tools/dissectors/epan/rfnoc/plugin.rc.in
new file mode 100644
index 000000000..eca74e1a7
--- /dev/null
+++ b/tools/dissectors/epan/rfnoc/plugin.rc.in
@@ -0,0 +1,35 @@
+#include "winver.h"
+#pragma code_page(65001)
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @RC_MODULE_VERSION@
+ PRODUCTVERSION @RC_VERSION@
+ FILEFLAGSMASK 0x0L
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Ettus Research (National Instruments)\0"
+ VALUE "FileDescription", "@MODULE_NAME@ dissector\0"
+ VALUE "FileVersion", "@MODULE_VERSION@\0"
+ VALUE "InternalName", "@MODULE_NAME@ @MODULE_VERSION@\0"
+ VALUE "LegalCopyright", "Copyright © 2019 Ettus Research (National Instruments)\0"
+ VALUE "OriginalFilename", "@MODULE_NAME@.dll\0"
+ VALUE "ProductName", "Wireshark\0"
+ VALUE "ProductVersion", "@PROJECT_VERSION@\0"
+ VALUE "Comments", "Build with @MSVC_VARIANT@\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/tools/dissectors/epan/zpu/CMakeLists.txt b/tools/dissectors/epan/zpu/CMakeLists.txt
new file mode 100644
index 000000000..043ee8a7a
--- /dev/null
+++ b/tools/dissectors/epan/zpu/CMakeLists.txt
@@ -0,0 +1,25 @@
+set_module_info(zpu 4 0 0 0)
+
+set(DISSECTOR_SRC
+ ${CMAKE_CURRENT_SOURCE_DIR}/packet-zpu.c
+)
+
+set(PLUGIN_FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/plugin.c
+ ${DISSECTOR_SRC}
+)
+
+register_plugin_files(${CMAKE_CURRENT_BINARY_DIR}/plugin.c
+ plugin
+ ${DISSECTOR_SRC}
+)
+
+add_plugin_library(zpu epan)
+
+set_target_properties(zpu PROPERTIES PREFIX "")
+set_target_properties(zpu PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}")
+target_link_libraries(zpu wireshark epan)
+
+install_plugin(zpu epan)
+
+
diff --git a/tools/dissectors/epan/zpu/packet-zpu.c b/tools/dissectors/epan/zpu/packet-zpu.c
new file mode 100644
index 000000000..3eff36997
--- /dev/null
+++ b/tools/dissectors/epan/zpu/packet-zpu.c
@@ -0,0 +1,245 @@
+/*
+ * Dissector for ZPU packets (communication with X300 firmware)
+ *
+ * Copyright 2013-2014 Ettus Research LLC
+ * Copyright 2019 Ettus Research, a National Instruments brand
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* Format of ZPU packets is defined in x300_fw_commons.h,
+ * x300_fw_comms_t.
+ *
+ * Reminder:
+ *
+ * uint32_t flags; (ack, error, peek, poke)
+ * uint32_t sequence;
+ * uint32_t addr;
+ * uint32_t data;
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <endian.h>
+
+#include "../../../../host/lib/usrp/x300/x300_fw_common.h"
+#include "zpu_addr_names.h"
+
+#define LOG_HEADER "[ZPU] "
+
+#ifndef min
+#define min(a,b) ((a<b)?a:b)
+#endif // min
+
+const unsigned int FW_PORT = X300_FW_COMMS_UDP_PORT;
+
+static int proto_zpu = -1;
+static int hf_zpu_flags = -1;
+static int hf_zpu_flags_ack = -1;
+static int hf_zpu_flags_error = -1;
+static int hf_zpu_flags_poke = -1;
+static int hf_zpu_flags_peek = -1;
+static int hf_zpu_seq = -1;
+static int hf_zpu_addr = -1;
+static int hf_zpu_data = -1;
+static int hf_zpu_shmem_addr = -1;
+static int hf_zpu_shmem_addr_name = -1;
+
+/* Subtree handles: set by register_subtree_array */
+static gint ett_zpu = -1;
+static gint ett_zpu_flags = -1;
+//static gint ett_zpu_shmem = -1;
+
+/* Forward-declare the dissector functions */
+void proto_register_zpu(void);
+void proto_reg_handoff_zpu(void);
+static int dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
+
+/* The dissector itself */
+static int dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ proto_item *item;
+ proto_tree *zpu_tree;
+ proto_item *flags_item;
+ proto_tree *flags_tree;
+ gint len;
+
+ gboolean is_network;
+ gint endianness;
+
+ if (pinfo->match_uint == FW_PORT) {
+ is_network = TRUE;
+ endianness = ENC_BIG_ENDIAN;
+ }
+ else {
+ is_network = FALSE;
+ endianness = ENC_LITTLE_ENDIAN;
+ }
+
+ len = tvb_reported_length(tvb);
+
+ col_append_str(pinfo->cinfo, COL_PROTOCOL, "/ZPU");
+ /*col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "ZPU", tvb_format_text_wsp(tvb, 0, len));*/
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "ZPU");
+
+ if (tree)
+ {
+ item = proto_tree_add_item(tree, proto_zpu, tvb, 0, min(16, len), ENC_NA);
+
+ // Dissect 'flags'
+ if (len >= 4)
+ {
+ zpu_tree = proto_item_add_subtree(item, ett_zpu);
+
+ flags_item = proto_tree_add_item(zpu_tree, hf_zpu_flags, tvb, 0, 4, endianness);
+ flags_tree = proto_item_add_subtree(flags_item, ett_zpu_flags);
+
+ proto_tree_add_item(flags_tree, hf_zpu_flags_ack, tvb, 0, 4, ENC_NA);
+ proto_tree_add_item(flags_tree, hf_zpu_flags_error, tvb, 0, 4, ENC_NA);
+ proto_tree_add_item(flags_tree, hf_zpu_flags_poke, tvb, 0, 4, ENC_NA);
+ proto_tree_add_item(flags_tree, hf_zpu_flags_peek, tvb, 0, 4, ENC_NA);
+
+ // Dissect 'sequence number'
+ if (len >= 8)
+ {
+ proto_tree_add_item(zpu_tree, hf_zpu_seq, tvb, 4, 4, ENC_NA);
+
+ // Dissect 'address'
+ if (len >= 12)
+ {
+ proto_tree_add_item(zpu_tree, hf_zpu_addr, tvb, 8, 4, ENC_NA);
+#if VERSION_MAJOR == 1
+ guint8 *bytes = tvb_get_string(tvb, 8, 4);
+#elif VERSION_MAJOR == 2
+ guint8 *bytes = tvb_get_string(wmem_packet_scope(), tvb, 8, 4);
+#elif VERSION_MAJOR == 3
+ guint8 *bytes = tvb_get_string_enc(wmem_packet_scope(), tvb, 8, 4, ENC_ASCII);
+#else
+#error Wireshark version not found or not compatible
+#endif
+ unsigned int addr = 0;
+ memcpy(&addr, bytes, 4);
+ /* TODO proper endianness handling */
+ addr = (addr >> 24) | ((addr & 0x00FF0000) >> 8) | ((addr & 0x0000FF00) << 8) | ((addr & 0x000000FF) << 24);
+ /* TODO check the actual size of shmem instead of this constant */
+ if (addr >= X300_FW_SHMEM_BASE && addr <= X300_FW_SHMEM_BASE + 0x2000)
+ {
+ proto_item *shmem_addr_item = NULL;
+
+ // Convert the address to a register number (32-bit registers == 4-byte registers)
+ addr -= X300_FW_SHMEM_BASE;
+ addr /= 4;
+
+ shmem_addr_item = proto_tree_add_uint(zpu_tree, hf_zpu_shmem_addr, tvb, 8, 4, addr);
+ proto_item_append_text(shmem_addr_item, ", Register name: %s",
+ val_to_str(addr, X300_SHMEM_NAMES, "Unknown (0x%04x)")
+ );
+
+ }
+
+ // Dissect 'data'
+ if (len >= 16)
+ {
+ proto_tree_add_item(zpu_tree, hf_zpu_data, tvb, 12, 4, ENC_NA);
+ }
+ }
+ }
+ }
+ }
+ return len;
+}
+
+void proto_register_zpu(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_zpu_flags,
+ { "Flags", "zpu.flags",
+ FT_UINT32, BASE_HEX,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_zpu_flags_ack,
+ { "ACK", "zpu.flags.ack",
+ FT_BOOLEAN, 32,
+ TFS(&tfs_set_notset), 0x1,
+ NULL, HFILL }
+ },
+ { &hf_zpu_flags_error,
+ { "Error", "zpu.flags.error",
+ FT_BOOLEAN, 32,
+ TFS(&tfs_set_notset), 0x2,
+ NULL, HFILL }
+ },
+ { &hf_zpu_flags_poke,
+ { "Poke", "zpu.flags.poke",
+ FT_BOOLEAN, 32,
+ TFS(&tfs_set_notset), 0x4,
+ NULL, HFILL }
+ },
+ { &hf_zpu_flags_peek,
+ { "Peek", "zpu.flags.peek",
+ FT_BOOLEAN, 32,
+ TFS(&tfs_set_notset), 0x8,
+ NULL, HFILL }
+ },
+ { &hf_zpu_seq,
+ { "Sequence ID", "zpu.seq",
+ FT_UINT32, BASE_HEX,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_zpu_addr,
+ { "Address", "zpu.addr",
+ FT_UINT32, BASE_HEX,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_zpu_shmem_addr,
+ { "SHMEM section", "zpu.shmem",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_zpu_data,
+ { "Data", "zpu.data",
+ FT_UINT32, BASE_HEX,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ };
+
+ static gint *ett[] = {
+ &ett_zpu,
+ &ett_zpu_flags,
+ //&ett_zpu_shmem
+ };
+
+ proto_zpu = proto_register_protocol("ZPU FW", "ZPU", "zpu");
+ proto_register_field_array(proto_zpu, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ register_dissector("zpu", dissect_zpu, proto_zpu);
+}
+
+/* Handler registration */
+void proto_reg_handoff_zpu(void)
+{
+ /* register dissector for UDP packets */
+ static dissector_handle_t zpu_handle;
+ zpu_handle = create_dissector_handle(dissect_zpu, proto_zpu);
+ dissector_add_uint("udp.port", FW_PORT, zpu_handle);
+}
diff --git a/tools/dissectors/epan/zpu/plugin.rc.in b/tools/dissectors/epan/zpu/plugin.rc.in
new file mode 100644
index 000000000..eca74e1a7
--- /dev/null
+++ b/tools/dissectors/epan/zpu/plugin.rc.in
@@ -0,0 +1,35 @@
+#include "winver.h"
+#pragma code_page(65001)
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @RC_MODULE_VERSION@
+ PRODUCTVERSION @RC_VERSION@
+ FILEFLAGSMASK 0x0L
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Ettus Research (National Instruments)\0"
+ VALUE "FileDescription", "@MODULE_NAME@ dissector\0"
+ VALUE "FileVersion", "@MODULE_VERSION@\0"
+ VALUE "InternalName", "@MODULE_NAME@ @MODULE_VERSION@\0"
+ VALUE "LegalCopyright", "Copyright © 2019 Ettus Research (National Instruments)\0"
+ VALUE "OriginalFilename", "@MODULE_NAME@.dll\0"
+ VALUE "ProductName", "Wireshark\0"
+ VALUE "ProductVersion", "@PROJECT_VERSION@\0"
+ VALUE "Comments", "Build with @MSVC_VARIANT@\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/tools/dissectors/epan/zpu/zpu_addr_names.h b/tools/dissectors/epan/zpu/zpu_addr_names.h
new file mode 100644
index 000000000..64a1307bc
--- /dev/null
+++ b/tools/dissectors/epan/zpu/zpu_addr_names.h
@@ -0,0 +1,39 @@
+/*
+ * Dissector for ZPU packets (communication with X300 firmware)
+ *
+ * Copyright 2013-2014 Ettus Research LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* TODO: autogenerate this file */
+
+/* Names of SHMEM registers: */
+static const value_string X300_SHMEM_NAMES[] = {
+ { 0, "X300_FW_SHMEM_COMPAT_NUM" },
+ { 1, "X300_FW_SHMEM_GPSDO_STATUS" },
+ { 2, "X300_FW_SHMEM_UART_RX_INDEX" },
+ { 3, "X300_FW_SHMEM_UART_TX_INDEX" },
+ { 5, "X300_FW_SHMEM_CLAIM_STATUS" },
+ { 6, "X300_FW_SHMEM_CLAIM_TIME" },
+ { 7, "X300_FW_SHMEM_CLAIM_SRC" },
+ { 8, "X300_FW_SHMEM_UART_RX_ADDR" },
+ { 9, "X300_FW_SHMEM_UART_TX_ADDR" },
+ { 10, "X300_FW_SHMEM_UART_WORDS32" },
+ { 11, "X300_FW_SHMEM_ROUTE_MAP_ADDR" },
+ { 12, "X300_FW_SHMEM_ROUTE_MAP_LEN" },
+ { 0, NULL }
+};
+