aboutsummaryrefslogtreecommitdiffstats
path: root/tools/zpu-dissector/packet-zpu.c
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2014-10-09 20:17:17 +0200
committerMartin Braun <martin.braun@ettus.com>2014-10-10 11:28:49 +0200
commitb048d918b64eeee387b22cf3ff78da7354c1c6a2 (patch)
treecf8f062082188cdb7da23957f00de112860d009c /tools/zpu-dissector/packet-zpu.c
parentd655137c93c7622f86c0794efcf0044b009b1fb4 (diff)
downloaduhd-b048d918b64eeee387b22cf3ff78da7354c1c6a2.tar.gz
uhd-b048d918b64eeee387b22cf3ff78da7354c1c6a2.tar.bz2
uhd-b048d918b64eeee387b22cf3ff78da7354c1c6a2.zip
tools: Added Balints ZPU dissector
Diffstat (limited to 'tools/zpu-dissector/packet-zpu.c')
-rw-r--r--tools/zpu-dissector/packet-zpu.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/tools/zpu-dissector/packet-zpu.c b/tools/zpu-dissector/packet-zpu.c
new file mode 100644
index 000000000..4bff97912
--- /dev/null
+++ b/tools/zpu-dissector/packet-zpu.c
@@ -0,0 +1,209 @@
+/*
+ * packet-chdr.c
+ * Dissector for UHD CHDR packets
+ *
+ * Copyright 2010-2013 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/>.
+ *
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#define LOG_HEADER "[ZPU] "
+
+#ifndef min
+#define min(a,b) ((a<b)?a:b)
+#endif // min
+
+const unsigned int FW_PORT = 49152;
+
+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;
+
+/* 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 void dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
+/* The dissector itself */
+static void dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ 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));
+
+ if (tree)
+ {
+ item = proto_tree_add_item(tree, proto_zpu, tvb, 0, min(16, len), ENC_NA);
+
+ 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);
+
+ if (len >= 8)
+ {
+ proto_tree_add_item(zpu_tree, hf_zpu_seq, tvb, 4, 4, ENC_NA);
+
+ if (len >= 12)
+ {
+ proto_tree_add_item(zpu_tree, hf_zpu_addr, tvb, 8, 4, ENC_NA);
+
+ guint8 *bytes = tvb_get_string(tvb, 8, 4);
+ unsigned int addr = 0;
+ memcpy(&addr, bytes, 4);
+ const unsigned int shmmem_base = 0x6000;
+ addr = (addr >> 24) | ((addr & 0x00FF0000) >> 8) | ((addr & 0x0000FF00) << 8) | ((addr & 0x000000FF) << 24);
+ if (addr >= shmmem_base)
+ {
+ addr -= 0x6000;
+ addr /= 4;
+
+ proto_tree_add_uint(zpu_tree, hf_zpu_shmem_addr, tvb, 8, 4, addr);
+ }
+
+ if (len >= 16)
+ {
+ proto_tree_add_item(zpu_tree, hf_zpu_data, tvb, 12, 4, ENC_NA);
+ }
+ }
+ }
+ }
+ }
+}
+
+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, BASE_NONE,
+ NULL, 0x1,
+ NULL, HFILL }
+ },
+ { &hf_zpu_flags_error,
+ { "Error", "zpu.flags.error",
+ FT_BOOLEAN, BASE_NONE,
+ NULL, 0x2,
+ NULL, HFILL }
+ },
+ { &hf_zpu_flags_poke,
+ { "Poke", "zpu.flags.poke",
+ FT_BOOLEAN, BASE_NONE,
+ NULL, 0x4,
+ NULL, HFILL }
+ },
+ { &hf_zpu_flags_peek,
+ { "Peek", "zpu.flags.peek",
+ FT_BOOLEAN, BASE_NONE,
+ NULL, 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);
+}