aboutsummaryrefslogtreecommitdiffstats
path: root/tools/dissectors/epan/zpu/packet-zpu.c
diff options
context:
space:
mode:
authorAlex Williams <alex.williams@ni.com>2019-07-30 19:45:58 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:35 -0800
commit9f29b9a556634e41d13fa298f9634b67fdd0a749 (patch)
tree694a38eb03629aec1ea118f6b3cdf63c6cfd7d0d /tools/dissectors/epan/zpu/packet-zpu.c
parent1c79742231c5cc3609e35bda34c8d9b9e7440f50 (diff)
downloaduhd-9f29b9a556634e41d13fa298f9634b67fdd0a749.tar.gz
uhd-9f29b9a556634e41d13fa298f9634b67fdd0a749.tar.bz2
uhd-9f29b9a556634e41d13fa298f9634b67fdd0a749.zip
tools: Update dissectors for Wireshark major version 3, new CHDR
Dissectors may now be incompatible with earlier versions. Fixes ZPU dissector.
Diffstat (limited to 'tools/dissectors/epan/zpu/packet-zpu.c')
-rw-r--r--tools/dissectors/epan/zpu/packet-zpu.c245
1 files changed, 245 insertions, 0 deletions
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);
+}