aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/dissectors/CMakeLists.txt191
-rw-r--r--tools/dissectors/cmake/Modules/WSComponent.cmake104
-rw-r--r--tools/dissectors/epan/octoclock/CMakeLists.txt25
-rw-r--r--tools/dissectors/epan/octoclock/packet-octoclock.c (renamed from tools/dissectors/packet-octoclock.c)27
-rw-r--r--tools/dissectors/epan/octoclock/plugin.rc.in (renamed from tools/dissectors/plugin.rc.in)11
-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.c (renamed from tools/dissectors/packet-zpu.c)51
-rw-r--r--tools/dissectors/epan/zpu/plugin.rc.in35
-rw-r--r--tools/dissectors/epan/zpu/zpu_addr_names.h (renamed from tools/dissectors/zpu_addr_names.h)3
-rwxr-xr-xtools/dissectors/make-dissector-reg.py305
-rwxr-xr-xtools/dissectors/make-plugin-reg.py184
-rw-r--r--tools/dissectors/moduleinfo.h.in10
-rw-r--r--tools/dissectors/packet-chdr.c528
16 files changed, 1293 insertions, 973 deletions
diff --git a/tools/dissectors/CMakeLists.txt b/tools/dissectors/CMakeLists.txt
index 9f63a356a..6d835aa48 100644
--- a/tools/dissectors/CMakeLists.txt
+++ b/tools/dissectors/CMakeLists.txt
@@ -1,106 +1,133 @@
# Copyright 2010-2013 Ettus Research LLC
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
+# Copyright 2019 Ettus Research, a National Instruments brand
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+cmake_minimum_required(VERSION 3.1)
+cmake_policy(SET CMP0048 NEW)
+project(EttusDissectors VERSION 4.0.0 DESCRIPTION "Dissector Plugins" LANGUAGES C CXX)
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
+set(UHD_HOST_ROOT ${CMAKE_SOURCE_DIR}/../../host)
########################################################################
-# Project setup
+# useful macros
########################################################################
-cmake_minimum_required(VERSION 2.8)
-project(ettus-dissector C)
-enable_testing()
+include(WSComponent)
-#select the release build type by default to get optimization flags
-if(NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE "Release")
- message(STATUS "Build type not specified: defaulting to release.")
-endif(NOT CMAKE_BUILD_TYPE)
-set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
+set(PLUGIN_C_GENERATOR ${CMAKE_SOURCE_DIR}/make-plugin-reg.py)
+macro(register_plugin_files _outputfile _registertype)
-list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
+ add_custom_command(
+ OUTPUT ${_outputfile}
+ DEPENDS ${ARGN} ${PLUGIN_C_GENERATOR}
+ COMMAND ${PYTHON_EXECUTABLE}
+ ${PLUGIN_C_GENERATOR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${_registertype}
+ ${ARGN}
+ COMMENT "Generating ${_outputfile}"
+ )
+
+endmacro(register_plugin_files)
+
+# Plugin name and version info (major minor micro extra)
+macro(SET_MODULE_INFO _plugin _ver_major _ver_minor _ver_micro _ver_extra)
+ if(WIN32)
+ # Create the Windows .rc file for the plugin.
+ set(MODULE_NAME ${_plugin})
+ set(MODULE_VERSION_MAJOR ${_ver_major})
+ set(MODULE_VERSION_MINOR ${_ver_minor})
+ set(MODULE_VERSION_MICRO ${_ver_micro})
+ set(MODULE_VERSION_EXTRA ${_ver_extra})
+ set(MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}.${MODULE_VERSION_MICRO}.${MODULE_VERSION_EXTRA}")
+ set(RC_MODULE_VERSION "${MODULE_VERSION_MAJOR},${MODULE_VERSION_MINOR},${MODULE_VERSION_MICRO},${MODULE_VERSION_EXTRA}")
+
+ set(MSVC_VARIANT "${CMAKE_GENERATOR}")
+
+ # Create the plugin.rc file from the template
+ set(_plugin_rc_in ${CMAKE_CURRENT_SOURCE_DIR}/plugin.rc.in)
+ configure_file(${_plugin_rc_in} plugin.rc @ONLY)
+ set(PLUGIN_RC_FILE ${CMAKE_CURRENT_BINARY_DIR}/plugin.rc)
+ endif()
+
+ set(PLUGIN_VERSION "${_ver_major}.${_ver_minor}.${_ver_micro}")
+ add_definitions(-DPLUGIN_VERSION=\"${PLUGIN_VERSION}\")
+ add_definitions(-DVERSION_MAJOR=${Wireshark_VERSION_MAJOR})
+ add_definitions(-DVERSION_MINOR=${Wireshark_VERSION_MINOR})
+endmacro()
+
+macro(ADD_PLUGIN_LIBRARY _plugin _subfolder)
+ add_library(${_plugin} MODULE
+ ${PLUGIN_FILES}
+ ${PLUGIN_RC_FILE}
+ )
+
+ set_target_properties(${_plugin} PROPERTIES
+ PREFIX ""
+ LINK_FLAGS "${WS_LINK_FLAGS}"
+ FOLDER "Plugins"
+ )
+
+ set_target_properties(${_plugin} PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${_subfolder}
+ INSTALL_RPATH ""
+ )
+endmacro()
+
+macro(INSTALL_PLUGIN _plugin _subfolder)
+ install(TARGETS ${_plugin}
+ LIBRARY DESTINATION ${_subfolder} NAMELINK_SKIP
+ )
+ #LIBRARY DESTINATION ${Wireshark_PLUGIN_INSTALL_DIR}/${_subfolder} NAMELINK_SKIP
+ #RUNTIME DESTINATION ${Wireshark_PLUGIN_INSTALL_DIR}
+ #ARCHIVE DESTINATION ${Wireshark_PLUGIN_INSTALL_DIR}
+endmacro()
-########################################################################
-# Compiler specific setup
-########################################################################
-#if(CMAKE_COMPILER_IS_GNUC AND NOT WIN32)
-# #http://gcc.gnu.org/wiki/Visibility
-# add_definitions(-fvisibility=visible)
-#endif()
+find_package(Wireshark CONFIG REQUIRED)
find_package(GLIB2)
-if(NOT GLIB2_FOUND)
- message(FATAL_ERROR "Glib not found")
-endif()
-find_package(Wireshark)
-if(NOT WIRESHARK_FOUND)
- message(FATAL_ERROR "Wireshark dev package not found")
+if(NOT Wireshark_PLUGINS_ENABLED)
+ message(FATAL_ERROR "Wireshark was compiled without support for plugins")
endif()
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX ${Wireshark_PLUGIN_INSTALL_DIR}
+ CACHE
+ PATH
+ "Default installation path for plugins"
+ FORCE
+ )
+endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+
+set(UHD_INCLUDE_DIR "${UHD_HOST_ROOT}/include")
+set(UHDLIB_INCLUDE_DIR "${UHD_HOST_ROOT}/lib/include")
-########################################################################
-# Setup the include and linker paths
-########################################################################
include_directories(
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
+ ${UHD_INCLUDE_DIR}
+ ${UHDLIB_INCLUDE_DIR}
${GLIB2_INCLUDE_DIRS}
- ${WIRESHARK_INCLUDE_DIRS}
+ ${Wireshark_INCLUDE_DIR}
)
-set(CMAKE_INSTALL_LIBDIR ~/.wireshark)
-
-# Set component parameters
-set(ETTUS_DISSECTOR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR} CACHE INTERNAL "" FORCE)
-set(ETTUS_DISSECTOR_NAME "chdr" CACHE STRING "Select a dissector to build")
+WS_REGISTER_COMPONENT("RFNoC" ENABLE_RFNOC ON "" OFF ON)
+WS_REGISTER_COMPONENT("Octoclock" ENABLE_OCTOCLOCK ON "" OFF OFF)
+WS_REGISTER_COMPONENT("ZPU" ENABLE_ZPU ON "" OFF OFF)
-function(generate_ettus_dissector DISSECTOR_NAME)
-
- set(ETTUS_PLUGIN_SRC ${CMAKE_SOURCE_DIR}/packet-${DISSECTOR_NAME}.c)
-
- configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/moduleinfo.h.in
- ${CMAKE_BINARY_DIR}/moduleinfo.h
- )
+if(ENABLE_RFNOC)
+ add_subdirectory(epan/rfnoc)
+endif(ENABLE_RFNOC)
- set(PLUGIN_C_GENERATOR ${CMAKE_SOURCE_DIR}/make-dissector-reg.py)
- set(PLUGIN_C plugin.c)
-
- add_custom_command(
- OUTPUT ${PLUGIN_C}
- DEPENDS ${ETTUS_PLUGIN_SRC}
- COMMAND ${PLUGIN_C_GENERATOR} ${CMAKE_SOURCE_DIR} plugin ${ETTUS_PLUGIN_SRC}
- COMMENT "Generating ${PLUGIN_C}"
- )
-
- set(ETTUS_TARGET_NAME "${DISSECTOR_NAME}-plugin")
- add_library(${ETTUS_TARGET_NAME} MODULE
- ${PLUGIN_C}
- moduleinfo.h
- ${ETTUS_PLUGIN_SRC}
- )
- set_target_properties(${ETTUS_TARGET_NAME} PROPERTIES PREFIX "")
- set_target_properties(${ETTUS_TARGET_NAME} PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}")
- target_link_libraries(${ETTUS_TARGET_NAME} wireshark)
+if(ENABLE_OCTOCLOCK)
+ add_subdirectory(epan/octoclock)
+endif(ENABLE_OCTOCLOCK)
- install(TARGETS ${ETTUS_TARGET_NAME}
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/plugins NAMELINK_SKIP
- )
+if(ENABLE_ZPU)
+ add_subdirectory(epan/zpu)
+endif(ENABLE_ZPU)
-endfunction(generate_ettus_dissector)
+WS_PRINT_COMPONENT_SUMMARY()
-generate_ettus_dissector("${ETTUS_DISSECTOR_NAME}")
diff --git a/tools/dissectors/cmake/Modules/WSComponent.cmake b/tools/dissectors/cmake/Modules/WSComponent.cmake
new file mode 100644
index 000000000..3e7f14900
--- /dev/null
+++ b/tools/dissectors/cmake/Modules/WSComponent.cmake
@@ -0,0 +1,104 @@
+#
+# Copyright 2019 Ettus Research, a National Instruments brand
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+set(_ws_enabled_components "" CACHE INTERNAL "" FORCE)
+set(_ws_disabled_components "" CACHE INTERNAL "" FORCE)
+
+########################################################################
+# Register a component into the system
+# - name the component string name ("FOO")
+# - var the global enable variable (ENABLE_FOO)
+# - enb the default enable setting (ON)
+# - deps a list of dependencies (DEPENDENCY_FOUND)
+# - dis the default disable setting (OFF)
+# - req fail if dependencies not met (unless specifically disabled)
+#
+# In parentheses are examples. If you specify those, we register a component
+# "FOO" which is enabled by calling CMake with -DENABLE_FOO=ON. It defaults to
+# ON, unless DEPENDENCY_FOUND is false, in which case it becomes false.
+########################################################################
+macro(WS_REGISTER_COMPONENT name var enb deps dis req)
+ message(STATUS "")
+ message(STATUS "Configuring ${name} support...")
+ foreach(dep ${deps})
+ message(STATUS " Dependency ${dep} = ${${dep}}")
+ endforeach(dep)
+
+ # If user specified option, store here. Note: If the user doesn't specify
+ # this option on the cmake command line, both user_enabled and
+ # user_disabled will be false!
+ if("${${var}}" STREQUAL "OFF")
+ set(user_disabled TRUE)
+ else()
+ set(user_disabled FALSE)
+ endif("${${var}}" STREQUAL "OFF")
+ if("${${var}}" STREQUAL "ON")
+ set(user_enabled TRUE)
+ else()
+ set(user_enabled FALSE)
+ endif("${${var}}" STREQUAL "ON")
+
+ # Override default if user set
+ if(user_enabled OR user_disabled)
+ set(option "${${var}}")
+ else(user_enabled OR user_disabled)
+ set(option ${req})
+ endif()
+
+ # setup the dependent option for this component
+ include(CMakeDependentOption)
+ CMAKE_DEPENDENT_OPTION(${var} "enable ${name} support" ${option} "${deps}" ${dis})
+
+ # There are two failure cases:
+ # 1) The user requested this component explicitly (-DENABLE_FOO=ON) but the
+ # requirements are not met.
+ # 2) The user did not explicitly turn off this component (-DENABLE_FOO=OFF)
+ # but it is flagged as required by ${req}
+ if(NOT ${var} AND user_enabled) # Case 1)
+ message(FATAL_ERROR "Dependencies for required component ${name} not met.")
+ endif(NOT ${var} AND user_enabled)
+ if(NOT ${var} AND ${req} AND NOT user_disabled) # Case 2)
+ message(FATAL_ERROR "Dependencies for required component ${name} not met.")
+ endif(NOT ${var} AND ${req} AND NOT user_disabled)
+
+ #append the component into one of the lists
+ if(${var})
+ message(STATUS " Enabling ${name} support.")
+ list(APPEND _ws_enabled_components ${name})
+ else(${var})
+ message(STATUS " Disabling ${name} support.")
+ list(APPEND _ws_disabled_components ${name})
+ endif(${var})
+ message(STATUS " Override with -D${var}=ON/OFF")
+
+ #make components lists into global variables
+ set(_ws_enabled_components ${_ws_enabled_components} CACHE INTERNAL "" FORCE)
+ set(_ws_disabled_components ${_ws_disabled_components} CACHE INTERNAL "" FORCE)
+endmacro(WS_REGISTER_COMPONENT)
+
+########################################################################
+# Print the registered component summary
+########################################################################
+function(WS_PRINT_COMPONENT_SUMMARY)
+ message(STATUS "")
+ message(STATUS "######################################################")
+ message(STATUS "# Ettus dissectors enabled ")
+ message(STATUS "######################################################")
+ foreach(comp ${_ws_enabled_components})
+ message(STATUS " * ${comp}")
+ endforeach(comp)
+
+ message(STATUS "")
+ message(STATUS "######################################################")
+ message(STATUS "# Ettus dissectors disabled ")
+ message(STATUS "######################################################")
+ foreach(comp ${_ws_disabled_components})
+ message(STATUS " * ${comp}")
+ endforeach(comp)
+
+ message(STATUS "")
+endfunction(WS_PRINT_COMPONENT_SUMMARY)
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/packet-octoclock.c b/tools/dissectors/epan/octoclock/packet-octoclock.c
index 453c325d7..e8e5e6858 100644
--- a/tools/dissectors/packet-octoclock.c
+++ b/tools/dissectors/epan/octoclock/packet-octoclock.c
@@ -2,20 +2,9 @@
* Dissector for Ettus Octoclock packets
*
* Copyright 2016 Ettus Research
+ * Copyright 2019 Ettus Research, a National Instruments brand
*
- * 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/>.
- *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
@@ -26,7 +15,7 @@
#include <stdio.h>
#include <stddef.h>
-#include "../../host/lib/usrp_clock/octoclock/common.h"
+#include "../../../../host/lib/usrp_clock/octoclock/common.h"
#define LOG_HEADER "[Octoclock] "
#define size_mem(t,m) sizeof(((t*)0)->m)
@@ -78,9 +67,9 @@ static const value_string packetcodes[] = {
/* Forward-declare the dissector functions */
void proto_register_octo(void);
void proto_reg_handoff_octo(void);
-static void dissect_octo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static int dissect_octo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
-static void dissect_octo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+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);
@@ -138,7 +127,9 @@ static void dissect_octo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
packet_offset(len),
packet_elem_size(len),
ENC_LITTLE_ENDIAN);
+ return len;
}
+ return 0;
}
@@ -207,6 +198,6 @@ void proto_reg_handoff_octo(void)
{
static dissector_handle_t octo_handle;
octo_handle = create_dissector_handle(dissect_octo, proto_octo);
- dissector_add_uint("udp.port", OCTOCLOCK_PORT, octo_handle);
- dissector_add_uint("udp.port", OCTOCLOCK_UDP_GPSDO_PORT, octo_handle);
+ 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/plugin.rc.in b/tools/dissectors/epan/octoclock/plugin.rc.in
index 29fcfdc33..eca74e1a7 100644
--- a/tools/dissectors/plugin.rc.in
+++ b/tools/dissectors/epan/octoclock/plugin.rc.in
@@ -1,4 +1,5 @@
#include "winver.h"
+#pragma code_page(65001)
VS_VERSION_INFO VERSIONINFO
FILEVERSION @RC_MODULE_VERSION@
@@ -17,13 +18,13 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Ettus Research (National Instruments)\0"
- VALUE "FileDescription", "@PACKAGE@ dissector\0"
+ VALUE "FileDescription", "@MODULE_NAME@ dissector\0"
VALUE "FileVersion", "@MODULE_VERSION@\0"
- VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0"
- VALUE "LegalCopyright", "Copyright © 2013 Ettus Research (National Instruments)\0"
- VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\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", "@VERSION@\0"
+ VALUE "ProductVersion", "@PROJECT_VERSION@\0"
VALUE "Comments", "Build with @MSVC_VARIANT@\0"
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/packet-zpu.c b/tools/dissectors/epan/zpu/packet-zpu.c
index 39507165e..3eff36997 100644
--- a/tools/dissectors/packet-zpu.c
+++ b/tools/dissectors/epan/zpu/packet-zpu.c
@@ -2,20 +2,9 @@
* Dissector for ZPU packets (communication with X300 firmware)
*
* Copyright 2013-2014 Ettus Research LLC
+ * Copyright 2019 Ettus Research, a National Instruments brand
*
- * 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/>.
- *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
/* Format of ZPU packets is defined in x300_fw_commons.h,
@@ -29,15 +18,26 @@
* 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 "../../../../host/lib/usrp/x300/x300_fw_common.h"
#include "zpu_addr_names.h"
#define LOG_HEADER "[ZPU] "
@@ -68,10 +68,10 @@ static gint ett_zpu_flags = -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);
+static int dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
/* The dissector itself */
-static void dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_item *item;
proto_tree *zpu_tree;
@@ -127,6 +127,8 @@ static void dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
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
@@ -159,6 +161,7 @@ static void dissect_zpu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
}
+ return len;
}
void proto_register_zpu(void)
@@ -172,26 +175,26 @@ void proto_register_zpu(void)
},
{ &hf_zpu_flags_ack,
{ "ACK", "zpu.flags.ack",
- FT_BOOLEAN, BASE_NONE,
- NULL, 0x1,
+ FT_BOOLEAN, 32,
+ TFS(&tfs_set_notset), 0x1,
NULL, HFILL }
},
{ &hf_zpu_flags_error,
{ "Error", "zpu.flags.error",
- FT_BOOLEAN, BASE_NONE,
- NULL, 0x2,
+ FT_BOOLEAN, 32,
+ TFS(&tfs_set_notset), 0x2,
NULL, HFILL }
},
{ &hf_zpu_flags_poke,
{ "Poke", "zpu.flags.poke",
- FT_BOOLEAN, BASE_NONE,
- NULL, 0x4,
+ FT_BOOLEAN, 32,
+ TFS(&tfs_set_notset), 0x4,
NULL, HFILL }
},
{ &hf_zpu_flags_peek,
{ "Peek", "zpu.flags.peek",
- FT_BOOLEAN, BASE_NONE,
- NULL, 0x8,
+ FT_BOOLEAN, 32,
+ TFS(&tfs_set_notset), 0x8,
NULL, HFILL }
},
{ &hf_zpu_seq,
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/zpu_addr_names.h b/tools/dissectors/epan/zpu/zpu_addr_names.h
index ebbf423ed..64a1307bc 100644
--- a/tools/dissectors/zpu_addr_names.h
+++ b/tools/dissectors/epan/zpu/zpu_addr_names.h
@@ -33,6 +33,7 @@ static const value_string X300_SHMEM_NAMES[] = {
{ 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" }
+ { 12, "X300_FW_SHMEM_ROUTE_MAP_LEN" },
+ { 0, NULL }
};
diff --git a/tools/dissectors/make-dissector-reg.py b/tools/dissectors/make-dissector-reg.py
deleted file mode 100755
index 37170a84f..000000000
--- a/tools/dissectors/make-dissector-reg.py
+++ /dev/null
@@ -1,305 +0,0 @@
-#!/usr/bin/env python
-#
-# Looks for registration routines in the protocol dissectors,
-# and assembles C code to call all the routines.
-#
-# This is a Python version of the make-reg-dotc shell script.
-# Running the shell script on Win32 is very very slow because of
-# all the process-launching that goes on --- multiple greps and
-# seds for each input file. I wrote this python version so that
-# less processes would have to be started.
-#
-# $Id: make-dissector-reg.py 30447 2009-10-09 20:47:18Z krj $
-
-import os
-import sys
-import re
-import pickle
-from stat import *
-
-VERSION_KEY = '_VERSION'
-CUR_VERSION = '$Id: make-dissector-reg.py 30447 2009-10-09 20:47:18Z krj $'
-
-#
-# The first argument is the directory in which the source files live.
-#
-srcdir = sys.argv[1]
-
-#
-# The second argument is either "plugin" or "dissectors"; if it's
-# "plugin", we build a plugin.c for a plugin, and if it's
-# "dissectors", we build a register.c for libwireshark.
-#
-registertype = sys.argv[2]
-if registertype == "plugin" or registertype == "plugin_wtap":
- tmp_filename = "plugin.c-tmp"
- final_filename = "plugin.c"
- cache_filename = None
- preamble = """\
-/*
- * Do not modify this file.
- *
- * It is created automatically by Makefile or Makefile.nmake.
- */
-"""
-elif registertype == "dissectors":
- tmp_filename = "register.c-tmp"
- final_filename = "register.c"
- cache_filename = "register-cache.pkl"
- preamble = """\
-/*
- * Do not modify this file.
- *
- * It is created automatically by the "register.c" target in
- * epan/dissectors/Makefile or Makefile.nmake using information in
- * epan/dissectors/register-cache.pkl.
- *
- * You can force this file to be regenerated completely by deleting
- * it along with epan/dissectors/register-cache.pkl.
- */
-"""
-else:
- print("Unknown output type '%s'" % registertype)
- sys.exit(1)
-
-
-#
-# All subsequent arguments are the files to scan.
-#
-files = sys.argv[3:]
-
-# Create the proper list of filenames
-filenames = []
-for file in files:
- if os.path.isfile(file):
- filenames.append(file)
- else:
- filenames.append(os.path.join(srcdir, file))
-
-if len(filenames) < 1:
- print("No files found")
- sys.exit(1)
-
-
-# Look through all files, applying the regex to each line.
-# If the pattern matches, save the "symbol" section to the
-# appropriate array.
-regs = {
- 'proto_reg': [],
- 'handoff_reg': [],
- 'wtap_register': [],
- }
-
-# For those that don't know Python, r"" indicates a raw string,
-# devoid of Python escapes.
-proto_regex0 = r"^(?P<symbol>proto_register_[_A-Za-z0-9]+)\s*\([^;]+$"
-proto_regex1 = r"void\s+(?P<symbol>proto_register_[_A-Za-z0-9]+)\s*\([^;]+$"
-
-handoff_regex0 = r"^(?P<symbol>proto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$"
-handoff_regex1 = r"void\s+(?P<symbol>proto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$"
-
-wtap_reg_regex0 = r"^(?P<symbol>wtap_register_[_A-Za-z0-9]+)\s*\([^;]+$"
-wtap_reg_regex1 = r"void\s+(?P<symbol>wtap_register_[_A-Za-z0-9]+)\s*\([^;]+$"
-
-# This table drives the pattern-matching and symbol-harvesting
-patterns = [
- ( 'proto_reg', re.compile(proto_regex0) ),
- ( 'proto_reg', re.compile(proto_regex1) ),
- ( 'handoff_reg', re.compile(handoff_regex0) ),
- ( 'handoff_reg', re.compile(handoff_regex1) ),
- ( 'wtap_register', re.compile(wtap_reg_regex0) ),
- ( 'wtap_register', re.compile(wtap_reg_regex1) ),
- ]
-
-# Open our registration symbol cache
-cache = None
-if cache_filename:
- try:
- cache_file = open(cache_filename, 'rb')
- cache = pickle.load(cache_file)
- cache_file.close()
- if (VERSION_KEY not in cache) or cache[VERSION_KEY] != CUR_VERSION:
- cache = {VERSION_KEY: CUR_VERSION}
- except:
- cache = {VERSION_KEY: CUR_VERSION}
-
-# Grep
-for filename in filenames:
- file = open(filename)
- cur_mtime = os.fstat(file.fileno())[ST_MTIME]
- if cache and (filename in cache):
- cdict = cache[filename]
- if cur_mtime == cdict['mtime']:
-# print("Pulling %s from cache" % (filename))
- regs['proto_reg'].extend(cdict['proto_reg'])
- regs['handoff_reg'].extend(cdict['handoff_reg'])
- regs['wtap_register'].extend(cdict['wtap_register'])
- file.close()
- continue
- # We don't have a cache entry
- if cache is not None:
- cache[filename] = {
- 'mtime': cur_mtime,
- 'proto_reg': [],
- 'handoff_reg': [],
- 'wtap_register': [],
- }
-# print("Searching %s" % (filename))
- for line in file.readlines():
- for action in patterns:
- regex = action[1]
- match = regex.search(line)
- if match:
- symbol = match.group("symbol")
- sym_type = action[0]
- regs[sym_type].append(symbol)
- if cache is not None:
-# print("Caching %s for %s: %s" % (sym_type, filename, symbol))
- cache[filename][sym_type].append(symbol)
- file.close()
-
-if cache is not None and cache_filename is not None:
- cache_file = open(cache_filename, 'wb')
- pickle.dump(cache, cache_file)
- cache_file.close()
-
-# Make sure we actually processed something
-if len(regs['proto_reg']) < 1:
- print("No protocol registrations found")
- sys.exit(1)
-
-# Sort the lists to make them pretty
-regs['proto_reg'].sort()
-regs['handoff_reg'].sort()
-regs['wtap_register'].sort()
-
-reg_code = open(tmp_filename, "w")
-
-reg_code.write(preamble)
-
-# Make the routine to register all protocols
-if registertype == "plugin" or registertype == "plugin_wtap":
- reg_code.write("""
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <gmodule.h>
-
-#include "moduleinfo.h"
-
-#ifndef ENABLE_STATIC
-G_MODULE_EXPORT const gchar version[] = VERSION;
-
-/* Start the functions we need for the plugin stuff */
-
-G_MODULE_EXPORT void
-plugin_register (void)
-{
-""");
-else:
- reg_code.write("""
-#include "register.h"
-void
-register_all_protocols(register_cb cb, gpointer client_data)
-{
-""");
-
-for symbol in regs['proto_reg']:
- if registertype == "plugin" or registertype == "plugin_wtap":
- line = " {extern void %s (void); %s ();}\n" % (symbol, symbol)
- else:
- line = " {extern void %s (void); if(cb) (*cb)(RA_REGISTER, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol)
- reg_code.write(line)
-
-reg_code.write("}\n")
-
-
-# Make the routine to register all protocol handoffs
-if registertype == "plugin" or registertype == "plugin_wtap":
- reg_code.write("""
-G_MODULE_EXPORT void
-plugin_reg_handoff(void)
-{
-""");
-else:
- reg_code.write("""
-void
-register_all_protocol_handoffs(register_cb cb, gpointer client_data)
-{
-""");
-
-for symbol in regs['handoff_reg']:
- if registertype == "plugin" or registertype == "plugin_wtap":
- line = " {extern void %s (void); %s ();}\n" % (symbol, symbol)
- else:
- line = " {extern void %s (void); if(cb) (*cb)(RA_HANDOFF, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol)
- reg_code.write(line)
-
-reg_code.write("}\n")
-
-if registertype == "plugin":
- reg_code.write("#endif\n");
-elif registertype == "plugin_wtap":
- reg_code.write("""
-G_MODULE_EXPORT void
-register_wtap_module(void)
-{
-""");
-
- for symbol in regs['wtap_register']:
- line = " {extern void %s (void); %s ();}\n" % (symbol, symbol)
- reg_code.write(line)
-
- reg_code.write("}\n");
- reg_code.write("#endif\n");
-else:
- reg_code.write("""
-static gulong proto_reg_count(void)
-{
-""");
-
- line = " return %d;\n" % len(regs['proto_reg'])
- reg_code.write(line)
-
- reg_code.write("""
-}
-""");
- reg_code.write("""
-static gulong handoff_reg_count(void)
-{
-""");
-
- line = " return %d;\n" % len(regs['handoff_reg'])
- reg_code.write(line)
-
- reg_code.write("""
-}
-""");
- reg_code.write("""
-gulong register_count(void)
-{
-""");
-
- line = " return proto_reg_count() + handoff_reg_count();"
- reg_code.write(line)
-
- reg_code.write("""
-}\n
-""");
-
-
-# Close the file
-reg_code.close()
-
-# Remove the old final_file if it exists.
-try:
- os.stat(final_filename)
- os.remove(final_filename)
-except OSError:
- pass
-
-# Move from tmp file to final file
-os.rename(tmp_filename, final_filename)
-
-
diff --git a/tools/dissectors/make-plugin-reg.py b/tools/dissectors/make-plugin-reg.py
new file mode 100755
index 000000000..6c394da97
--- /dev/null
+++ b/tools/dissectors/make-plugin-reg.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+#
+# Looks for registration routines in the plugins
+# and assembles C code to call all the routines.
+#
+
+import os
+import sys
+import re
+
+#
+# The first argument is the directory in which the source files live.
+#
+srcdir = sys.argv[1]
+#
+# The second argument is either "plugin", "plugin_wtap" or "plugin_codec".
+#
+registertype = sys.argv[2]
+#
+# All subsequent arguments are the files to scan.
+#
+files = sys.argv[3:]
+
+final_filename = "plugin.c"
+preamble = """\
+/*
+ * Do not modify this file. Changes will be overwritten.
+ *
+ * Generated automatically from %s.
+ */
+""" % (sys.argv[0])
+
+# Create the proper list of filenames
+filenames = []
+for file in files:
+ if os.path.isfile(file):
+ filenames.append(file)
+ else:
+ filenames.append(os.path.join(srcdir, file))
+
+if len(filenames) < 1:
+ print("No files found")
+ sys.exit(1)
+
+
+# Look through all files, applying the regex to each line.
+# If the pattern matches, save the "symbol" section to the
+# appropriate set.
+regs = {
+ 'proto_reg': set(),
+ 'handoff_reg': set(),
+ 'wtap_register': set(),
+ 'codec_register': set(),
+ }
+
+# For those that don't know Python, r"" indicates a raw string,
+# devoid of Python escapes.
+proto_regex = r"\bproto_register_(?P<symbol>[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$"
+
+handoff_regex = r"\bproto_reg_handoff_(?P<symbol>[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$"
+
+wtap_reg_regex = r"\bwtap_register_(?P<symbol>[_A-Za-z0-9]+)\s*\([^;]+$"
+
+codec_reg_regex = r"\bcodec_register_(?P<symbol>[_A-Za-z0-9]+)\s*\([^;]+$"
+
+# This table drives the pattern-matching and symbol-harvesting
+patterns = [
+ ( 'proto_reg', re.compile(proto_regex, re.MULTILINE) ),
+ ( 'handoff_reg', re.compile(handoff_regex, re.MULTILINE) ),
+ ( 'wtap_register', re.compile(wtap_reg_regex, re.MULTILINE) ),
+ ( 'codec_register', re.compile(codec_reg_regex, re.MULTILINE) ),
+ ]
+
+# Grep
+for filename in filenames:
+ file = open(filename)
+ # Read the whole file into memory
+ contents = file.read()
+ for action in patterns:
+ regex = action[1]
+ for match in regex.finditer(contents):
+ symbol = match.group("symbol")
+ sym_type = action[0]
+ regs[sym_type].add(symbol)
+ # We're done with the file contents
+ del contents
+ file.close()
+
+# Make sure we actually processed something
+if (len(regs['proto_reg']) < 1 and len(regs['wtap_register']) < 1 and len(regs['codec_register']) < 1):
+ print("No plugin registrations found")
+ sys.exit(1)
+
+# Convert the sets into sorted lists to make the output pretty
+regs['proto_reg'] = sorted(regs['proto_reg'])
+regs['handoff_reg'] = sorted(regs['handoff_reg'])
+regs['wtap_register'] = sorted(regs['wtap_register'])
+regs['codec_register'] = sorted(regs['codec_register'])
+
+reg_code = ""
+
+reg_code += preamble
+
+reg_code += """
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gmodule.h>
+
+/* plugins are DLLs */
+#define WS_BUILD_DLL
+#include "ws_symbol_export.h"
+
+"""
+
+if registertype == "plugin":
+ reg_code += "#include \"epan/proto.h\"\n\n"
+if registertype == "plugin_wtap":
+ reg_code += "#include \"wiretap/wtap.h\"\n\n"
+if registertype == "plugin_codec":
+ reg_code += "#include \"codecs/codecs.h\"\n\n"
+
+for symbol in regs['proto_reg']:
+ reg_code += "void proto_register_%s(void);\n" % (symbol)
+for symbol in regs['handoff_reg']:
+ reg_code += "void proto_reg_handoff_%s(void);\n" % (symbol)
+for symbol in regs['wtap_register']:
+ reg_code += "void wtap_register_%s(void);\n" % (symbol)
+for symbol in regs['codec_register']:
+ reg_code += "void codec_register_%s(void);\n" % (symbol)
+
+reg_code += """
+WS_DLL_PUBLIC_DEF const gchar plugin_version[] = PLUGIN_VERSION;
+WS_DLL_PUBLIC_DEF const int plugin_want_major = VERSION_MAJOR;
+WS_DLL_PUBLIC_DEF const int plugin_want_minor = VERSION_MINOR;
+
+WS_DLL_PUBLIC void plugin_register(void);
+
+void plugin_register(void)
+{
+"""
+
+if registertype == "plugin":
+ for symbol in regs['proto_reg']:
+ reg_code +=" static proto_plugin plug_%s;\n\n" % (symbol)
+ reg_code +=" plug_%s.register_protoinfo = proto_register_%s;\n" % (symbol, symbol)
+ if symbol in regs['handoff_reg']:
+ reg_code +=" plug_%s.register_handoff = proto_reg_handoff_%s;\n" % (symbol, symbol)
+ else:
+ reg_code +=" plug_%s.register_handoff = NULL;\n" % (symbol)
+ reg_code += " proto_register_plugin(&plug_%s);\n" % (symbol)
+if registertype == "plugin_wtap":
+ for symbol in regs['wtap_register']:
+ reg_code += " static wtap_plugin plug_%s;\n\n" % (symbol)
+ reg_code += " plug_%s.register_wtap_module = wtap_register_%s;\n" % (symbol, symbol)
+ reg_code += " wtap_register_plugin(&plug_%s);\n" % (symbol)
+if registertype == "plugin_codec":
+ for symbol in regs['codec_register']:
+ reg_code += " static codecs_plugin plug_%s;\n\n" % (symbol)
+ reg_code += " plug_%s.register_codec_module = codec_register_%s;\n" % (symbol, symbol)
+ reg_code += " codecs_register_plugin(&plug_%s);\n" % (symbol)
+
+reg_code += "}\n"
+
+try:
+ print(('Updating ' + final_filename))
+ fh = open(final_filename, 'w')
+ fh.write(reg_code)
+ fh.close()
+except OSError:
+ sys.exit('Unable to write ' + final_filename + '.\n')
+
+#
+# Editor modelines - http://www.wireshark.org/tools/modelines.html
+#
+# Local variables:
+# c-basic-offset: 4
+# indent-tabs-mode: nil
+# End:
+#
+# vi: set shiftwidth=4 expandtab:
+# :indentSize=4:noTabs=true:
+#
diff --git a/tools/dissectors/moduleinfo.h.in b/tools/dissectors/moduleinfo.h.in
deleted file mode 100644
index 7910c56a3..000000000
--- a/tools/dissectors/moduleinfo.h.in
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifdef PACKAGE
-#undef PACKAGE
-#endif
-#define PACKAGE "@ETTUS_DISSECTOR_NAME@"
-
-#ifdef VERSION
-#undef VERSION
-#endif
-#define VERSION "0.0.0.2"
-
diff --git a/tools/dissectors/packet-chdr.c b/tools/dissectors/packet-chdr.c
deleted file mode 100644
index e5dcd6e5e..000000000
--- a/tools/dissectors/packet-chdr.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Dissector for UHD CVITA (CHDR) packets
- *
- * Copyright 2010-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/>.
- *
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <epan/packet.h>
-#include <ctype.h>
-#include <stdio.h>
-
-#include "../../host/lib/usrp/x300/x300_fw_common.h"
-
-#define LOG_HEADER "[UHD CHDR] "
-
-#ifndef min
-#define min(a,b) ((a<b)?a:b)
-#endif // min
-
-const unsigned int CHDR_PORT = X300_VITA_UDP_PORT;
-
-static int proto_chdr = -1;
-static int hf_chdr_hdr = -1;
-static int hf_chdr_type = -1;
-static int hf_chdr_has_time = -1;
-static int hf_chdr_eob = -1;
-static int hf_chdr_error = -1;
-static int hf_chdr_fc_ack = -1;
-static int hf_chdr_fc_pktcount = -1;
-static int hf_chdr_fc_bytecount = -1;
-static int hf_chdr_sequence = -1;
-static int hf_chdr_packet_size = -1;
-static int hf_chdr_stream_id = -1;
-static int hf_chdr_src_dev = -1;
-static int hf_chdr_src_ep = -1;
-static int hf_chdr_src_blockport = -1;
-static int hf_chdr_dst_dev = -1;
-static int hf_chdr_dst_ep = -1;
-static int hf_chdr_dst_blockport = -1;
-static int hf_chdr_timestamp = -1;
-static int hf_chdr_payload = -1;
-static int hf_chdr_ext_response = -1;
-static int hf_chdr_ext_fc = -1;
-static int hf_chdr_ext_status_code = -1;
-static int hf_chdr_ext_seq_num = -1;
-static int hf_chdr_cmd = -1;
-static int hf_chdr_cmd_address = -1;
-static int hf_chdr_cmd_value = -1;
-
-static const value_string CHDR_PACKET_TYPES[] = {
- { 0, "Data" },
- { 1, "Data (End-of-Burst)" },
- { 4, "Flow Control" },
- { 5, "Flow Control (ACK)" },
- { 8, "Command" },
- { 12, "Response" },
- { 13, "Error Response" },
-};
-
-static const value_string CHDR_PACKET_TYPES_SHORT[] = {
- { 0, "data" },
- { 1, "data" },
- { 4, "fc" },
- { 5, "fc" },
- { 8, "cmd" },
- { 12, "resp" },
- { 13, "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_chdr = -1;
-static gint ett_chdr_header = -1;
-static gint ett_chdr_id = -1;
-static gint ett_chdr_response = -1;
-static gint ett_chdr_fc = -1;
-static gint ett_chdr_cmd = -1;
-
-/* Forward-declare the dissector functions */
-void proto_register_chdr(void);
-void proto_reg_handoff_chdr(void);
-static void dissect_chdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-
-/* heuristic dissector call. Will always return. */
-static gboolean heur_dissect_chdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* whatislove)
-{
- if(heur_warning_printed < 1){
- printf(LOG_HEADER"heuristic dissector always returns true!\n");
- heur_warning_printed++;
- }
- dissect_chdr(tvb, pinfo, tree);
- return (TRUE);
-}
-
-static void byte_swap(guint8 *bytes, gint len)
-{
- guint8 tmp[4];
-
- if(len != sizeof(tmp)){
- printf(LOG_HEADER"FATAL! number of bytes don't match 32 bit!\n");
- return;
- }
-
- memcpy(tmp, bytes, sizeof(tmp));
- bytes[0] = tmp[3];
- bytes[1] = tmp[2];
- bytes[2] = tmp[1];
- bytes[3] = tmp[0];
-}
-
-static unsigned long long get_timestamp(guint8 *bytes, gint len)
-{
- unsigned long long ts;
- unsigned long long trans;
- int it;
-
- if(len != sizeof(unsigned long long)){
- printf(LOG_HEADER"FATAL! timestamps always consist of 64 bits!\n");
- }
-
- byte_swap(bytes + 0, 4);
- byte_swap(bytes + 4, 4);
-
- ts = 0;
- for(it = 0; it < 8; it++){
- ts = ts << 8;
- trans = (guint64) bytes[it];
- ts = ts | trans;
- }
-
- return (ts);
-}
-
-/* The dissector itself */
-static void dissect_chdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- // Here are all the variables
- proto_item *item;
- proto_item *stream_item;
- proto_tree *chdr_tree;
- proto_item *header_item;
- proto_tree *header_tree;
- proto_tree *stream_tree;
- proto_item *response_item;
- proto_tree *response_tree;
- proto_item *cmd_item;
- proto_tree *cmd_tree;
- proto_item *fc_item;
- proto_tree *fc_tree;
- gint len;
-
- gint flag_offset;
- guint8 *bytes;
- guint8 hdr_bits = 0;
- gboolean flag_has_time = 0;
- gboolean flag_is_data = 0;
- gboolean flag_is_fc = 0;
- gboolean flag_is_cmd = 0;
- gboolean flag_is_resp = 0;
- gboolean flag_is_eob = 0;
- gboolean flag_is_error = 0;
- gboolean flag_is_fcack = 0;
- uint64_t timestamp;
- gboolean is_network;
- gint endianness;
- gint id_pos_usb[4] = {3, 2, 1, 0};
- gint id_pos_net[4] = {0, 1, 2, 3};
- gint id_pos[4] = {0, 1, 2, 3};
-
- if(pinfo->match_uint == CHDR_PORT){
- is_network = TRUE;
- flag_offset = 0;
- endianness = ENC_BIG_ENDIAN;
- memcpy(id_pos, id_pos_net, 4 * sizeof(gint));
- }
- else{ // Parsing a USB capture
- is_network = FALSE;
- flag_offset = 3;
- endianness = ENC_LITTLE_ENDIAN;
- memcpy(id_pos, id_pos_usb, 4 * sizeof(gint));
- }
-
- len = tvb_reported_length(tvb);
-
- col_append_str(pinfo->cinfo, COL_PROTOCOL, "/CHDR");
- /* This throws a warning: */
- /*col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "CHDR", tvb_format_text_wsp(tvb, 0, len));*/
- col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "CHDR");
-
- if (tree){
- int header_size = -1; // Total size of the CHDR header. Either 8 or 16.
-
- guint16 hdr_info;
- if (len >= 4){
- guint8 pkt_type = 0;
- hdr_info = tvb_get_ntohs(tvb, flag_offset);
- header_size = 8; // We now know the header is at least 8 bytes long.
- hdr_bits = (hdr_info & 0xF000) >> 12;
- pkt_type = hdr_bits >> 2;
- flag_is_data = (pkt_type == 0);
- flag_is_fc = (pkt_type == 1);
- flag_is_cmd = (pkt_type == 2);
- flag_is_resp = (pkt_type == 3);
- flag_is_eob = flag_is_data && (hdr_bits & 0x1);
- flag_is_error = flag_is_resp && (hdr_bits & 0x1);
- flag_is_fcack = flag_is_fc && (hdr_bits & 0x1);
- flag_has_time = hdr_bits & 0x2;
- if (flag_has_time) {
- header_size += 8; // 64-bit timestamp.
- }
- /* header_size is now final. */
- }
-
- /* Start with a top-level item to add everything else to */
- item = proto_tree_add_item(tree, proto_chdr, tvb, 0, min(len, header_size), ENC_NA);
-
- if (len >= 4) {
- chdr_tree = proto_item_add_subtree(item, ett_chdr);
-
- /* Header info. First, a top-level header tree item: */
- header_item = proto_tree_add_item(chdr_tree, hf_chdr_hdr, tvb, flag_offset, 1, endianness);
- header_tree = proto_item_add_subtree(header_item, ett_chdr_header);
- proto_item_append_text(header_item, ", Packet type: %s %04x",
- val_to_str(hdr_bits & 0xD, CHDR_PACKET_TYPES, "Unknown (0x%x)"), hdr_bits
- );
- /* Let us query hdr.type */
- proto_tree_add_string(
- header_tree, hf_chdr_type, tvb, flag_offset, 1,
- val_to_str(hdr_bits & 0xD, CHDR_PACKET_TYPES_SHORT, "invalid")
- );
- /* And other flags */
- proto_tree_add_boolean(header_tree, hf_chdr_has_time, tvb, flag_offset, 1, flag_has_time);
- if (flag_is_data) {
- proto_tree_add_boolean(header_tree, hf_chdr_eob, tvb, flag_offset, 1, flag_is_eob);
- }
- if (flag_is_resp) {
- proto_tree_add_boolean(header_tree, hf_chdr_error, tvb, flag_offset, 1, flag_is_error);
- /*proto_tree_add_boolean(header_tree, hf_chdr_error, tvb, flag_offset, 1, true);*/
- }
- if (flag_is_fc) {
- proto_tree_add_boolean(header_tree, hf_chdr_fc_ack, tvb, flag_offset, 1, flag_is_fcack);
- }
-
- /* These lines add sequence, packet_size and stream ID */
- proto_tree_add_item(chdr_tree, hf_chdr_sequence, tvb, (is_network ? 0:2), 2, endianness);
- proto_tree_add_item(chdr_tree, hf_chdr_packet_size, tvb, (is_network ? 2:0), 2, endianness);
-
- if (len >= 8){
- /* stream id can be broken down to 4 sections. these are collapsed in a subtree */
- stream_item = proto_tree_add_item(chdr_tree, hf_chdr_stream_id, tvb, 4, 4, endianness);
- stream_tree = proto_item_add_subtree(stream_item, ett_chdr_id);
- proto_tree_add_item(stream_tree, hf_chdr_src_dev, tvb, 4+id_pos[0], 1, ENC_NA);
- proto_tree_add_item(stream_tree, hf_chdr_src_ep, tvb, 4+id_pos[1], 1, ENC_NA);
- proto_tree_add_item(stream_tree, hf_chdr_dst_dev, tvb, 4+id_pos[2], 1, ENC_NA);
- proto_tree_add_item(stream_tree, hf_chdr_dst_ep, tvb, 4+id_pos[3], 1, ENC_NA);
-
- /* Block ports (only add them if address points to a device) */
- guint32 sid = tvb_get_ntohl(tvb, 4);
- guint8* sid_bytes = (guint8*) &sid;
- if (sid_bytes[3] != 0) {
- proto_tree_add_item(stream_tree, hf_chdr_src_blockport, tvb, 4+2, 1, ENC_NA);
- }
- if (sid_bytes[1] != 0) {
- proto_tree_add_item(stream_tree, hf_chdr_dst_blockport, tvb, 4+0, 1, ENC_NA);
- }
-
- /* Append SID in sid_t hex format */
- proto_item_append_text(stream_item, " (%02X:%02X>%02X:%02X)",
- sid_bytes[3],
- sid_bytes[2],
- sid_bytes[1],
- sid_bytes[0]
- );
- /*proto_item_append_text(stream_item, "%08X", sid);*/
-
-
- /* if has_time flag is present interpret timestamp */
- if ((flag_has_time) && (len >= 16)){
- if (is_network)
- item = proto_tree_add_item(chdr_tree, hf_chdr_timestamp, tvb, 8, 8, endianness);
- else{
- bytes = (guint8*) tvb_get_string_enc(wmem_packet_scope(), tvb, 8, sizeof(unsigned long long), ENC_ASCII);
- timestamp = get_timestamp(bytes, sizeof(unsigned long long));
- proto_tree_add_uint64(chdr_tree, hf_chdr_timestamp, tvb, 8, 8, timestamp);
- }
- }
-
- int remaining_bytes = (len - header_size);
- int show_raw_payload = (remaining_bytes > 0);
-
- if (flag_is_cmd && remaining_bytes == 8) {
- cmd_item = proto_tree_add_item(chdr_tree, hf_chdr_cmd, tvb, header_size, 8, endianness);
- cmd_tree = proto_item_add_subtree(cmd_item, ett_chdr_cmd);
- proto_tree_add_item(cmd_tree, hf_chdr_cmd_address, tvb, header_size, 4, endianness);
- proto_tree_add_item(cmd_tree, hf_chdr_cmd_value, tvb, header_size + 4, 4, endianness);
- } else if (flag_is_resp) {
- response_item = proto_tree_add_item(chdr_tree, hf_chdr_ext_response, tvb, header_size, 8, endianness);
- response_tree = proto_item_add_subtree(response_item, ett_chdr_response);
-
- proto_tree_add_item(response_tree, hf_chdr_ext_status_code, tvb, header_size, 4, endianness);
- /* This will show the 12-bits of sequence ID in the last 2 bytes */
- proto_tree_add_item(response_tree, hf_chdr_ext_seq_num, tvb, (header_size + 4 + (is_network ? 2 : 0)), 2, endianness);
- } else if (flag_is_fc) {
- fc_item = proto_tree_add_item(chdr_tree, hf_chdr_ext_fc, tvb, header_size, 8, endianness);
- fc_tree = proto_item_add_subtree(fc_item, ett_chdr_fc);
- proto_tree_add_item(fc_tree, hf_chdr_fc_pktcount, tvb, header_size, 4, endianness);
- proto_tree_add_item(fc_tree, hf_chdr_fc_bytecount, tvb, header_size + 4, 4, endianness);
- } else if (show_raw_payload) {
- proto_tree_add_item(chdr_tree, hf_chdr_payload, tvb, header_size, -1, ENC_NA);
- }
- }
- }
- }
-}
-
-void proto_register_chdr(void)
-{
- static hf_register_info hf[] = {
- { &hf_chdr_hdr,
- { "Header bits", "chdr.hdr",
- FT_UINT8, BASE_HEX,
- NULL, 0xF0,
- NULL, HFILL }
- },
- { &hf_chdr_type,
- { "Packet Type", "chdr.hdr.type",
- FT_STRINGZ, BASE_NONE,
- NULL, 0x00,
- "Packet Type", HFILL }
- },
- { &hf_chdr_has_time,
- { "Has time", "chdr.hdr.has_time",
- FT_BOOLEAN, BASE_NONE,
- NULL, 0x20,
- NULL, HFILL }
- },
- { &hf_chdr_eob,
- { "End Of Burst", "chdr.hdr.eob",
- FT_BOOLEAN, BASE_NONE,
- NULL, 0x10,
- NULL, HFILL }
- },
- { &hf_chdr_error,
- { "Error Flag", "chdr.hdr.error",
- FT_BOOLEAN, BASE_NONE,
- NULL, 0x10,
- NULL, HFILL }
- },
- { &hf_chdr_fc_ack,
- { "FC ACK Flag", "chdr.hdr.fc_ack",
- FT_BOOLEAN, BASE_NONE,
- NULL, 0x10,
- NULL, HFILL }
- },
- { &hf_chdr_ext_fc,
- { "Flow Control", "chdr.fc",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_fc_bytecount,
- { "FC Byte Count", "chdr.hdr.fc.byte_count",
- FT_UINT32, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_fc_pktcount,
- { "FC Packet Count", "chdr.hdr.fc.pkt_count",
- FT_UINT32, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_sequence,
- { "Sequence ID", "chdr.seq",
- FT_UINT16, BASE_DEC,
- NULL, 0x0FFF,
- NULL, HFILL }
- },
- { &hf_chdr_packet_size,
- { "Packet size", "chdr.size",
- FT_UINT16, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_stream_id,
- { "Stream ID", "chdr.sid",
- FT_IPv4, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_src_dev,
- { "Source device", "chdr.src_dev",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_src_ep,
- { "Source endpoint", "chdr.src_ep",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_src_blockport,
- { "Source block port", "chdr.src_bp",
- FT_UINT8, BASE_DEC,
- NULL, 0xF,
- NULL, HFILL }
- },
- { &hf_chdr_dst_dev,
- { "Destination device", "chdr.dst_dev",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_dst_ep,
- { "Destination endpoint", "chdr.dst_ep",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_dst_blockport,
- { "Destination block port", "chdr.dst_bp",
- FT_UINT8, BASE_DEC,
- NULL, 0xF,
- NULL, HFILL }
- },
- { &hf_chdr_timestamp,
- { "Time", "chdr.time",
- FT_UINT64, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_payload,
- { "Payload", "chdr.payload",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL
- }
- },
- { &hf_chdr_ext_response,
- { "Response", "chdr.res",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_ext_status_code,
- { "Status code", "chdr.res.status",
- FT_UINT32, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_ext_seq_num,
- { "Response to sequence ID", "chdr.res.seq",
- FT_UINT16, BASE_DEC,
- NULL, 0x0FFF,
- NULL, HFILL }
- },
- { &hf_chdr_cmd,
- { "Command", "chdr.cmd",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_cmd_address,
- { "Register Address", "chdr.cmd.addr",
- FT_UINT32, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_chdr_cmd_value,
- { "Command Value", "chdr.cmd.val",
- FT_UINT32, BASE_HEX,
- NULL, 0x0,
- NULL, HFILL }
- },
- };
-
- static gint *ett[] = {
- &ett_chdr,
- &ett_chdr_header,
- &ett_chdr_id,
- &ett_chdr_response,
- &ett_chdr_fc,
- &ett_chdr_cmd
- };
-
- proto_chdr = proto_register_protocol("UHD CHDR", "CHDR", "chdr");
- proto_register_field_array(proto_chdr, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
- register_dissector("chdr", dissect_chdr, proto_chdr);
-}
-
-/* Handler registration */
-void proto_reg_handoff_chdr(void)
-{
- /* register heuristic dissector for use with USB */
-#if VERSION_MAJOR == 1
- heur_dissector_add("usb.bulk", heur_dissect_chdr, proto_chdr);
-#elif VERSION_MAJOR == 2
- heur_dissector_add("usb.bulk", heur_dissect_chdr, "USB dissector", "usb_bulk", proto_chdr, HEURISTIC_ENABLE);
-#else
-#error Wireshark version not found or not compatible
-#endif
- /* register dissector for UDP packets */
- static dissector_handle_t chdr_handle;
- chdr_handle = create_dissector_handle(dissect_chdr, proto_chdr);
- dissector_add_uint("udp.port", CHDR_PORT, chdr_handle);
-}