summaryrefslogtreecommitdiffstats
path: root/plugins/epan/profinet
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /plugins/epan/profinet
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/epan/profinet')
-rw-r--r--plugins/epan/profinet/AUTHORS4
-rw-r--r--plugins/epan/profinet/CMakeLists.txt80
-rw-r--r--plugins/epan/profinet/ChangeLog33
-rw-r--r--plugins/epan/profinet/packet-dcerpc-pn-io.c17887
-rw-r--r--plugins/epan/profinet/packet-dcom-cba-acco.c5158
-rw-r--r--plugins/epan/profinet/packet-dcom-cba-acco.h59
-rw-r--r--plugins/epan/profinet/packet-dcom-cba.c1730
-rw-r--r--plugins/epan/profinet/packet-pn-dcp.c2096
-rw-r--r--plugins/epan/profinet/packet-pn-mrp.c675
-rw-r--r--plugins/epan/profinet/packet-pn-mrrt.c247
-rw-r--r--plugins/epan/profinet/packet-pn-ptcp.c1093
-rw-r--r--plugins/epan/profinet/packet-pn-rsi.c1087
-rw-r--r--plugins/epan/profinet/packet-pn-rt.c1204
-rw-r--r--plugins/epan/profinet/packet-pn-rtc-one.c1356
-rw-r--r--plugins/epan/profinet/packet-pn.c1518
-rw-r--r--plugins/epan/profinet/packet-pn.h204
16 files changed, 34431 insertions, 0 deletions
diff --git a/plugins/epan/profinet/AUTHORS b/plugins/epan/profinet/AUTHORS
new file mode 100644
index 0000000..4979d26
--- /dev/null
+++ b/plugins/epan/profinet/AUTHORS
@@ -0,0 +1,4 @@
+Author :
+Ulf Lamping <ulf.lamping@web.de>
+Tobias Scholz <scholzt234@googlemail.com>
+Birol Capa <birol.capa@gmail.com> \ No newline at end of file
diff --git a/plugins/epan/profinet/CMakeLists.txt b/plugins/epan/profinet/CMakeLists.txt
new file mode 100644
index 0000000..7e6ca56
--- /dev/null
+++ b/plugins/epan/profinet/CMakeLists.txt
@@ -0,0 +1,80 @@
+# CMakeLists.txt
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+include(WiresharkPlugin)
+
+# Plugin name and version info (major minor micro extra)
+set_module_info(profinet 0 2 4 0)
+
+set(DISSECTOR_SRC
+ packet-dcerpc-pn-io.c
+ packet-dcom-cba.c
+ packet-dcom-cba-acco.c
+ packet-pn-dcp.c
+ packet-pn-mrp.c
+ packet-pn-mrrt.c
+ packet-pn-ptcp.c
+ packet-pn-rt.c
+ packet-pn-rtc-one.c
+ packet-pn-rsi.c
+)
+
+set(DISSECTOR_SUPPORT_SRC
+ packet-pn.c
+)
+
+set(PLUGIN_FILES
+ plugin.c
+ ${DISSECTOR_SRC}
+ ${DISSECTOR_SUPPORT_SRC}
+)
+
+set_source_files_properties(
+ ${PLUGIN_FILES}
+ PROPERTIES
+ COMPILE_FLAGS "${WERROR_COMMON_FLAGS}"
+)
+
+register_plugin_files(plugin.c
+ plugin
+ ${DISSECTOR_SRC}
+ ${DISSECTOR_SUPPORT_SRC}
+)
+
+add_wireshark_plugin_library(profinet epan)
+
+target_link_libraries(profinet epan)
+
+install_plugin(profinet epan)
+
+file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h")
+CHECKAPI(
+ NAME
+ profinet
+ SWITCHES
+ --group dissectors-prohibited
+ --group dissectors-restricted
+ SOURCES
+ ${DISSECTOR_SRC}
+ ${DISSECTOR_SUPPORT_SRC}
+ ${DISSECTOR_HEADERS}
+)
+
+#
+# Editor modelines - https://www.wireshark.org/tools/modelines.html
+#
+# Local variables:
+# c-basic-offset: 8
+# tab-width: 8
+# indent-tabs-mode: t
+# End:
+#
+# vi: set shiftwidth=8 tabstop=8 noexpandtab:
+# :indentSize=8:tabSize=8:noTabs=false:
+#
diff --git a/plugins/epan/profinet/ChangeLog b/plugins/epan/profinet/ChangeLog
new file mode 100644
index 0000000..5298f56
--- /dev/null
+++ b/plugins/epan/profinet/ChangeLog
@@ -0,0 +1,33 @@
+Overview of changes in Art-Net Ethereal plugin:
+
+Version 0.0.0:
+
+* initial implementation
+
+Version 0.0.1:
+
+* some experiments
+
+Version 0.1.0:
+
+* first official plugin
+
+Version 0.1.1:
+
+* fixed some bugs in the PN-IO dissection found with fuzz-test.sh
+
+Version 0.1.2:
+
+* PN-DCP: dissection of "DHCP/DHCP client identifier" suboption was added
+
+Version 0.2.0:
+
+* PN-PTCP: add whole new Precision Time Control Protocol dissector
+
+Version 0.2.1:
+
+* PN-MRP and PN-MRRT: add new Media Redundancy Protocol and Media Redundacy for RealTime Protocol dissector
+
+Version 0.2.2:
+
+* PN-IO: RT class 3 packets and some more blocks
diff --git a/plugins/epan/profinet/packet-dcerpc-pn-io.c b/plugins/epan/profinet/packet-dcerpc-pn-io.c
new file mode 100644
index 0000000..34e08ae
--- /dev/null
+++ b/plugins/epan/profinet/packet-dcerpc-pn-io.c
@@ -0,0 +1,17887 @@
+/* packet-dcerpc-pn-io.c
+ * Routines for PROFINET IO dissection.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * The PN-IO protocol is a field bus protocol related to decentralized
+ * periphery and is developed by the PROFIBUS Nutzerorganisation e.V. (PNO),
+ * see: www.profibus.com
+ *
+ *
+ * PN-IO is based on the common DCE-RPC and the "lightweight" PN-RT
+ * (ethernet type 0x8892) protocols.
+ *
+ * The context manager (CM) part is handling context information
+ * (like establishing, ...) and is using DCE-RPC as its underlying
+ * protocol.
+ *
+ * The actual cyclic data transfer and acyclic notification uses the
+ * "lightweight" PN-RT protocol.
+ *
+ * There are some other related PROFINET protocols (e.g. PN-DCP, which is
+ * handling addressing topics).
+ *
+ * Please note: the PROFINET CBA protocol is independent of the PN-IO protocol!
+ */
+
+/*
+ * Cyclic PNIO RTC1 Data Dissection:
+ *
+ * To dissect cyclic PNIO RTC1 frames, this plug-in has to collect important module
+ * information out of "Ident OK", "Connect Request" and "Write Response"
+ * frames first. This information will be used within "packet-pn-rtc-one.c" to
+ * dissect PNIO and PROFIsafe RTC1 frames.
+ *
+ * The data of Stationname-, -type and -id will be gained out of
+ * packet-pn-dcp.c. The header packet-pn.h will save those data.
+ *
+ * Overview for cyclic PNIO RTC1 data dissection functions:
+ * -> dissect_IOCRBlockReq_block (Save amount of IODataObjects, IOCS)
+ * -> dissect_DataDescription (Save important values for cyclic data)
+ * -> dissect_ExpectedSubmoduleBlockReq_block (Get GSD information)
+ * -> dissect_ModuleDiffBlock_block (Module has different ID)
+ * -> dissect_ProfiSafeParameterRequest (Save PROFIsafe parameters)
+ * -> dissect_RecordDataWrite (Call ProfiSafeParameterRequest)
+ * -> pnio_rtc1_cleanup (Reset routine of saved RTC1 information)
+ */
+
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/to_str.h>
+#include <epan/wmem_scopes.h>
+#include <epan/dissectors/packet-dcerpc.h>
+#include <epan/expert.h>
+#include <epan/conversation_filter.h>
+#include <epan/proto_data.h>
+
+#include <wsutil/file_util.h>
+#include <epan/prefs.h>
+
+#include "packet-pn.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void proto_register_pn_io(void);
+void proto_reg_handoff_pn_io(void);
+
+
+#define MAX_NAMELENGTH 200 /* max. length of the given paths */
+#define F_MESSAGE_TRAILER_4BYTE 4 /* PROFIsafe: Defines the Amount of Bytes for CRC and Status-/Controlbyte */
+#define PN_INPUT_CR 1 /* PROFINET Input Connect Request value */
+#define PN_INPUT_DATADESCRITPION 1 /* PROFINET Input Data Description value */
+
+#define PA_PROFILE_API 0x9700u
+#define PA_PROFILE_DAP_MASK 0xFFFF0000u
+#define PA_PROFILE_DAP_IDENT 0x00FD0000u
+
+#define PA_PROFILE_BLOCK_DAP 0u
+#define PA_PROFILE_BLOCK_PB 1u
+#define PA_PROFILE_BLOCK_FB 2u
+#define PA_PROFILE_BLOCK_TB 3u
+
+#define PA_PROFILE_TB_PARENT_PRESSURE 1u
+#define PA_PROFILE_TB_PARENT_TEMPERATURE 2u
+#define PA_PROFILE_TB_PARENT_FLOW 3u
+#define PA_PROFILE_TB_PARENT_LEVEL 1u
+#define PA_PROFILE_TB_PARENT_ACTUATOR 1u
+#define PA_PROFILE_TB_PARENT_DISCRETE_IO 1u
+#define PA_PROFILE_TB_PARENT_LIQUID_ANALYZER 1u
+#define PA_PROFILE_TB_PARENT_GAS_ANALYZER 1u
+#define PA_PROFILE_TB_PARENT_ENUMERATED_IO 1u
+#define PA_PROFILE_TB_PARENT_BINARY_IO 1u
+
+
+
+static int proto_pn_io = -1;
+static int proto_pn_io_device = -1;
+static int proto_pn_io_controller = -1;
+static int proto_pn_io_supervisor = -1;
+static int proto_pn_io_parameterserver = -1;
+static int proto_pn_io_implicitar = -1;
+int proto_pn_io_apdu_status = -1;
+int proto_pn_io_time_aware_status = -1;
+
+static int hf_pn_io_opnum = -1;
+static int hf_pn_io_reserved16 = -1;
+
+static int hf_pn_io_array = -1;
+static int hf_pn_io_args_max = -1;
+static int hf_pn_io_args_len = -1;
+static int hf_pn_io_array_max_count = -1;
+static int hf_pn_io_array_offset = -1;
+static int hf_pn_io_array_act_count = -1;
+
+static int hf_pn_io_ar_type = -1;
+static int hf_pn_io_artype_req = -1;
+static int hf_pn_io_cminitiator_macadd = -1;
+static int hf_pn_io_cminitiator_objectuuid = -1;
+static int hf_pn_io_parameter_server_objectuuid = -1;
+static int hf_pn_io_ar_data = -1;
+static int hf_pn_io_ar_properties = -1;
+static int hf_pn_io_ar_properties_state = -1;
+static int hf_pn_io_ar_properties_supervisor_takeover_allowed = -1;
+static int hf_pn_io_ar_properties_parameterization_server = -1;
+/* removed within 2.3
+static int hf_pn_io_ar_properties_data_rate = -1;
+*/
+static int hf_pn_io_ar_properties_reserved_1 = -1;
+static int hf_pn_io_ar_properties_device_access = -1;
+static int hf_pn_io_ar_properties_companion_ar = -1;
+static int hf_pn_io_ar_properties_achnowledge_companion_ar = -1;
+static int hf_pn_io_ar_properties_reserved = -1;
+static int hf_pn_io_ar_properties_time_aware_system = -1;
+static int hf_pn_io_ar_properties_combined_object_container_with_legacy_startupmode = -1;
+static int hf_pn_io_ar_properties_combined_object_container_with_advanced_startupmode = -1;
+static int hf_pn_io_ar_properties_pull_module_alarm_allowed = -1;
+
+static int hf_pn_RedundancyInfo = -1;
+static int hf_pn_RedundancyInfo_reserved = -1;
+static int hf_pn_io_number_of_ARDATAInfo = -1;
+
+static int hf_pn_io_cminitiator_activitytimeoutfactor = -1;
+static int hf_pn_io_cminitiator_udprtport = -1;
+static int hf_pn_io_station_name_length = -1;
+static int hf_pn_io_cminitiator_station_name = -1;
+/* static int hf_pn_io_responder_station_name = -1; */
+static int hf_pn_io_arproperties_StartupMode = -1;
+
+static int hf_pn_io_parameter_server_station_name = -1;
+
+static int hf_pn_io_cmresponder_macadd = -1;
+static int hf_pn_io_cmresponder_udprtport = -1;
+
+static int hf_pn_io_number_of_iocrs = -1;
+static int hf_pn_io_iocr_tree = -1;
+static int hf_pn_io_iocr_type = -1;
+static int hf_pn_io_iocr_reference = -1;
+static int hf_pn_io_iocr_SubframeOffset = -1;
+static int hf_pn_io_iocr_SubframeData =-1;
+/* static int hf_pn_io_iocr_txports_port = -1; */
+/* static int hf_pn_io_iocr_txports_redundantport = -1; */
+static int hf_pn_io_sr_properties_Reserved_1 = -1;
+static int hf_pn_io_sr_properties_Mode = -1;
+static int hf_pn_io_sr_properties_Reserved_2 = -1;
+static int hf_pn_io_sr_properties_Reserved_3 = -1;
+static int hf_pn_io_RedundancyDataHoldFactor = -1;
+static int hf_pn_io_sr_properties = -1;
+static int hf_pn_io_sr_properties_InputValidOnBackupAR_with_SRProperties_Mode_0 = -1;
+static int hf_pn_io_sr_properties_InputValidOnBackupAR_with_SRProperties_Mode_1 = -1;
+
+static int hf_pn_io_arvendor_strucidentifier_if0_low = -1;
+static int hf_pn_io_arvendor_strucidentifier_if0_high = -1;
+static int hf_pn_io_arvendor_strucidentifier_if0_is8000= -1;
+static int hf_pn_io_arvendor_strucidentifier_not0 = -1;
+
+static int hf_pn_io_lt = -1;
+static int hf_pn_io_iocr_properties = -1;
+static int hf_pn_io_iocr_properties_rtclass = -1;
+static int hf_pn_io_iocr_properties_reserved_1 = -1;
+static int hf_pn_io_iocr_properties_media_redundancy = -1;
+static int hf_pn_io_iocr_properties_reserved_2 = -1;
+static int hf_pn_io_iocr_properties_reserved_3 = -1;
+static int hf_pn_io_iocr_properties_fast_forwarding_mac_adr = -1;
+static int hf_pn_io_iocr_properties_distributed_subframe_watchdog = -1;
+static int hf_pn_io_iocr_properties_full_subframe_structure = -1;
+
+
+static int hf_pn_io_data_length = -1;
+static int hf_pn_io_ir_frame_data = -1;
+static int hf_pn_io_frame_id = -1;
+static int hf_pn_io_send_clock_factor = -1;
+static int hf_pn_io_reduction_ratio = -1;
+static int hf_pn_io_phase = -1;
+static int hf_pn_io_sequence = -1;
+static int hf_pn_io_frame_send_offset = -1;
+static int hf_pn_io_frame_data_properties = -1;
+static int hf_pn_io_frame_data_properties_forwarding_Mode = -1;
+static int hf_pn_io_frame_data_properties_FastForwardingMulticastMACAdd = -1;
+static int hf_pn_io_frame_data_properties_FragmentMode = -1;
+static int hf_pn_io_frame_data_properties_reserved_1 = -1;
+static int hf_pn_io_frame_data_properties_reserved_2 = -1;
+static int hf_pn_io_watchdog_factor = -1;
+static int hf_pn_io_data_hold_factor = -1;
+static int hf_pn_io_iocr_tag_header = -1;
+static int hf_pn_io_iocr_multicast_mac_add = -1;
+static int hf_pn_io_number_of_apis = -1;
+static int hf_pn_io_number_of_io_data_objects = -1;
+static int hf_pn_io_io_data_object_frame_offset = -1;
+static int hf_pn_io_number_of_iocs = -1;
+static int hf_pn_io_iocs_frame_offset = -1;
+
+static int hf_pn_io_SFIOCRProperties = -1;
+static int hf_pn_io_DistributedWatchDogFactor = -1;
+static int hf_pn_io_RestartFactorForDistributedWD = -1;
+static int hf_pn_io_SFIOCRProperties_DFPmode = -1;
+static int hf_pn_io_SFIOCRProperties_reserved_1 = -1;
+static int hf_pn_io_SFIOCRProperties_reserved_2 = -1;
+static int hf_pn_io_SFIOCRProperties_DFPType =-1;
+static int hf_pn_io_SFIOCRProperties_DFPRedundantPathLayout = -1;
+static int hf_pn_io_SFIOCRProperties_SFCRC16 = -1;
+
+static int hf_pn_io_subframe_data = -1;
+static int hf_pn_io_subframe_data_reserved1 = -1;
+static int hf_pn_io_subframe_data_reserved2 = -1;
+
+static int hf_pn_io_subframe_data_position = -1;
+static int hf_pn_io_subframe_reserved1 = -1;
+static int hf_pn_io_subframe_data_length = -1;
+static int hf_pn_io_subframe_reserved2 = -1;
+
+static int hf_pn_io_alarmcr_type = -1;
+static int hf_pn_io_alarmcr_properties = -1;
+static int hf_pn_io_alarmcr_properties_priority = -1;
+static int hf_pn_io_alarmcr_properties_transport = -1;
+static int hf_pn_io_alarmcr_properties_reserved = -1;
+
+static int hf_pn_io_rta_timeoutfactor = -1;
+static int hf_pn_io_rta_retries = -1;
+static int hf_pn_io_localalarmref = -1;
+static int hf_pn_io_remotealarmref = -1;
+static int hf_pn_io_maxalarmdatalength = -1;
+static int hf_pn_io_alarmcr_tagheaderhigh = -1;
+static int hf_pn_io_alarmcr_tagheaderlow = -1;
+
+static int hf_pn_io_IRData_uuid = -1;
+static int hf_pn_io_ar_uuid = -1;
+static int hf_pn_io_target_ar_uuid = -1;
+static int hf_pn_io_ar_discriminator = -1;
+static int hf_pn_io_ar_configid = -1;
+static int hf_pn_io_ar_arnumber = -1;
+static int hf_pn_io_ar_arresource = -1;
+static int hf_pn_io_ar_arreserved = -1;
+static int hf_pn_io_ar_selector = -1;
+static int hf_pn_io_api_tree = -1;
+static int hf_pn_io_module_tree = -1;
+static int hf_pn_io_submodule_tree = -1;
+static int hf_pn_io_io_data_object = -1;
+/* General module information */
+static int hf_pn_io_io_cs = -1;
+
+static int hf_pn_io_substitutionmode = -1;
+
+static int hf_pn_io_api = -1;
+static int hf_pn_io_slot_nr = -1;
+static int hf_pn_io_subslot_nr = -1;
+static int hf_pn_io_index = -1;
+static int hf_pn_io_seq_number = -1;
+static int hf_pn_io_record_data_length = -1;
+static int hf_pn_io_add_val1 = -1;
+static int hf_pn_io_add_val2 = -1;
+
+static int hf_pn_io_block = -1;
+static int hf_pn_io_block_header = -1;
+static int hf_pn_io_block_type = -1;
+static int hf_pn_io_block_length = -1;
+static int hf_pn_io_block_version_high = -1;
+static int hf_pn_io_block_version_low = -1;
+
+static int hf_pn_io_sessionkey = -1;
+static int hf_pn_io_control_alarm_sequence_number = -1;
+static int hf_pn_io_control_command = -1;
+static int hf_pn_io_control_command_prmend = -1;
+static int hf_pn_io_control_command_applready = -1;
+static int hf_pn_io_control_command_release = -1;
+static int hf_pn_io_control_command_done = -1;
+static int hf_pn_io_control_command_ready_for_companion = -1;
+static int hf_pn_io_control_command_ready_for_rt_class3 = -1;
+static int hf_pn_io_control_command_prmbegin = -1;
+static int hf_pn_io_control_command_reserved_7_15 = -1;
+static int hf_pn_io_control_block_properties = -1;
+static int hf_pn_io_control_block_properties_applready = -1;
+static int hf_pn_io_control_block_properties_applready_bit0 = -1;
+static int hf_pn_io_control_block_properties_applready_bit1 = -1;
+static int hf_pn_io_control_block_properties_applready_otherbits = -1;
+
+/* static int hf_pn_io_AlarmSequenceNumber = -1; */
+static int hf_pn_io_control_command_reserved = -1;
+static int hf_pn_io_SubmoduleListEntries = -1;
+
+static int hf_pn_io_alarm_type = -1;
+static int hf_pn_io_alarm_specifier = -1;
+static int hf_pn_io_alarm_specifier_sequence = -1;
+static int hf_pn_io_alarm_specifier_channel = -1;
+static int hf_pn_io_alarm_specifier_manufacturer = -1;
+static int hf_pn_io_alarm_specifier_submodule = -1;
+static int hf_pn_io_alarm_specifier_ardiagnosis = -1;
+
+static int hf_pn_io_alarm_dst_endpoint = -1;
+static int hf_pn_io_alarm_src_endpoint = -1;
+static int hf_pn_io_pdu_type = -1;
+static int hf_pn_io_pdu_type_type = -1;
+static int hf_pn_io_pdu_type_version = -1;
+static int hf_pn_io_add_flags = -1;
+static int hf_pn_io_window_size = -1;
+static int hf_pn_io_tack = -1;
+static int hf_pn_io_send_seq_num = -1;
+static int hf_pn_io_ack_seq_num = -1;
+static int hf_pn_io_var_part_len = -1;
+
+static int hf_pn_io_number_of_modules = -1;
+static int hf_pn_io_module_ident_number = -1;
+static int hf_pn_io_module_properties = -1;
+static int hf_pn_io_module_state = -1;
+static int hf_pn_io_number_of_submodules = -1;
+static int hf_pn_io_submodule_ident_number = -1;
+static int hf_pn_io_submodule_properties = -1;
+static int hf_pn_io_submodule_properties_type = -1;
+static int hf_pn_io_submodule_properties_shared_input = -1;
+static int hf_pn_io_submodule_properties_reduce_input_submodule_data_length = -1;
+static int hf_pn_io_submodule_properties_reduce_output_submodule_data_length = -1;
+static int hf_pn_io_submodule_properties_discard_ioxs = -1;
+static int hf_pn_io_submodule_properties_reserved = -1;
+
+static int hf_pn_io_submodule_state = -1;
+static int hf_pn_io_submodule_state_format_indicator = -1;
+static int hf_pn_io_submodule_state_add_info = -1;
+static int hf_pn_io_submodule_state_advice = -1;
+static int hf_pn_io_submodule_state_maintenance_required = -1;
+static int hf_pn_io_submodule_state_maintenance_demanded = -1;
+static int hf_pn_io_submodule_state_fault = -1;
+static int hf_pn_io_submodule_state_ar_info = -1;
+static int hf_pn_io_submodule_state_ident_info = -1;
+static int hf_pn_io_submodule_state_detail = -1;
+
+static int hf_pn_io_data_description_tree = -1;
+static int hf_pn_io_data_description = -1;
+static int hf_pn_io_submodule_data_length = -1;
+static int hf_pn_io_length_iocs = -1;
+static int hf_pn_io_length_iops = -1;
+
+static int hf_pn_io_iocs = -1;
+static int hf_pn_io_iops = -1;
+static int hf_pn_io_ioxs_extension = -1;
+static int hf_pn_io_ioxs_res14 = -1;
+static int hf_pn_io_ioxs_instance = -1;
+static int hf_pn_io_ioxs_datastate = -1;
+
+static int hf_pn_io_address_resolution_properties = -1;
+static int hf_pn_io_mci_timeout_factor = -1;
+static int hf_pn_io_provider_station_name = -1;
+
+static int hf_pn_io_user_structure_identifier = -1;
+static int hf_pn_io_user_structure_identifier_manf = -1;
+
+static int hf_pn_io_channel_number = -1;
+static int hf_pn_io_channel_properties = -1;
+static int hf_pn_io_channel_properties_type = -1;
+static int hf_pn_io_channel_properties_accumulative = -1;
+static int hf_pn_io_channel_properties_maintenance = -1;
+
+
+static int hf_pn_io_NumberOfSubframeBlocks = -1;
+static int hf_pn_io_channel_properties_specifier = -1;
+static int hf_pn_io_channel_properties_direction = -1;
+
+static int hf_pn_io_channel_error_type = -1;
+static int hf_pn_io_ext_channel_error_type0 = -1;
+static int hf_pn_io_ext_channel_error_type0x8000 = -1;
+static int hf_pn_io_ext_channel_error_type0x8001 = -1;
+static int hf_pn_io_ext_channel_error_type0x8002 = -1;
+static int hf_pn_io_ext_channel_error_type0x8003 = -1;
+static int hf_pn_io_ext_channel_error_type0x8004 = -1;
+static int hf_pn_io_ext_channel_error_type0x8005 = -1;
+static int hf_pn_io_ext_channel_error_type0x8007 = -1;
+static int hf_pn_io_ext_channel_error_type0x8008 = -1;
+static int hf_pn_io_ext_channel_error_type0x800A = -1;
+static int hf_pn_io_ext_channel_error_type0x800B = -1;
+static int hf_pn_io_ext_channel_error_type0x800C = -1;
+static int hf_pn_io_ext_channel_error_type0x8010 = -1;
+
+static int hf_pn_io_ext_channel_error_type = -1;
+
+static int hf_pn_io_ext_channel_add_value = -1;
+static int hf_pn_io_qualified_channel_qualifier = -1;
+
+static int hf_pn_io_ptcp_subdomain_id = -1;
+static int hf_pn_io_ir_data_id = -1;
+static int hf_pn_io_max_bridge_delay = -1;
+static int hf_pn_io_number_of_ports = -1;
+static int hf_pn_io_max_port_tx_delay = -1;
+static int hf_pn_io_max_port_rx_delay = -1;
+
+static int hf_pn_io_max_line_rx_delay = -1;
+static int hf_pn_io_yellowtime = -1;
+static int hf_pn_io_reserved_interval_begin = -1;
+static int hf_pn_io_reserved_interval_end = -1;
+static int hf_pn_io_pllwindow = -1;
+static int hf_pn_io_sync_send_factor = -1;
+static int hf_pn_io_sync_properties = -1;
+static int hf_pn_io_sync_frame_address = -1;
+static int hf_pn_io_ptcp_timeout_factor = -1;
+static int hf_pn_io_ptcp_takeover_timeout_factor = -1;
+static int hf_pn_io_ptcp_master_startup_time = -1;
+static int hf_pn_io_ptcp_master_priority_1 = -1;
+static int hf_pn_io_ptcp_master_priority_2 = -1;
+static int hf_pn_io_ptcp_length_subdomain_name = -1;
+static int hf_pn_io_ptcp_subdomain_name = -1;
+
+static int hf_pn_io_MultipleInterfaceMode_NameOfDevice = -1;
+static int hf_pn_io_MultipleInterfaceMode_reserved_1 = -1;
+static int hf_pn_io_MultipleInterfaceMode_reserved_2 = -1;
+/* added Portstatistics */
+static int hf_pn_io_pdportstatistic_counter_status = -1;
+static int hf_pn_io_pdportstatistic_counter_status_ifInOctets = -1;
+static int hf_pn_io_pdportstatistic_counter_status_ifOutOctets = -1;
+static int hf_pn_io_pdportstatistic_counter_status_ifInDiscards = -1;
+static int hf_pn_io_pdportstatistic_counter_status_ifOutDiscards = -1;
+static int hf_pn_io_pdportstatistic_counter_status_ifInErrors = -1;
+static int hf_pn_io_pdportstatistic_counter_status_ifOutErrors = -1;
+static int hf_pn_io_pdportstatistic_counter_status_reserved = -1;
+static int hf_pn_io_pdportstatistic_ifInOctets = -1;
+static int hf_pn_io_pdportstatistic_ifOutOctets = -1;
+static int hf_pn_io_pdportstatistic_ifInDiscards = -1;
+static int hf_pn_io_pdportstatistic_ifOutDiscards = -1;
+static int hf_pn_io_pdportstatistic_ifInErrors = -1;
+static int hf_pn_io_pdportstatistic_ifOutErrors = -1;
+/* end of port statistics */
+
+static int hf_pn_io_domain_boundary = -1;
+static int hf_pn_io_domain_boundary_ingress = -1;
+static int hf_pn_io_domain_boundary_egress = -1;
+static int hf_pn_io_multicast_boundary = -1;
+static int hf_pn_io_adjust_properties = -1;
+static int hf_pn_io_PreambleLength = -1;
+static int hf_pn_io_mau_type = -1;
+static int hf_pn_io_mau_type_mode = -1;
+static int hf_pn_io_port_state = -1;
+static int hf_pn_io_link_state_port = -1;
+static int hf_pn_io_link_state_link = -1;
+static int hf_pn_io_line_delay = -1;
+static int hf_pn_io_line_delay_value = -1;
+static int hf_pn_io_cable_delay_value = -1;
+static int hf_pn_io_line_delay_format_indicator = -1;
+static int hf_pn_io_number_of_peers = -1;
+static int hf_pn_io_length_peer_port_id = -1;
+static int hf_pn_io_peer_port_id = -1;
+static int hf_pn_io_length_peer_chassis_id = -1;
+static int hf_pn_io_peer_chassis_id = -1;
+static int hf_pn_io_neighbor = -1;
+static int hf_pn_io_length_peer_port_name = -1;
+static int hf_pn_io_peer_port_name = -1;
+static int hf_pn_io_length_peer_station_name = -1;
+static int hf_pn_io_peer_station_name = -1;
+static int hf_pn_io_length_own_port_id = -1;
+static int hf_pn_io_own_port_id = -1;
+static int hf_pn_io_peer_macadd = -1;
+static int hf_pn_io_media_type = -1;
+static int hf_pn_io_macadd = -1;
+static int hf_pn_io_length_own_chassis_id = -1;
+static int hf_pn_io_own_chassis_id = -1;
+static int hf_pn_io_rtclass3_port_status = -1;
+
+static int hf_pn_io_ethertype = -1;
+static int hf_pn_io_rx_port = -1;
+static int hf_pn_io_frame_details = -1;
+static int hf_pn_io_frame_details_sync_frame = -1;
+static int hf_pn_io_frame_details_meaning_frame_send_offset = -1;
+static int hf_pn_io_frame_details_reserved = -1;
+static int hf_pn_io_nr_of_tx_port_groups = -1;
+static int hf_pn_io_TxPortGroupProperties = -1;
+static int hf_pn_io_TxPortGroupProperties_bit0 = -1;
+static int hf_pn_io_TxPortGroupProperties_bit1 = -1;
+static int hf_pn_io_TxPortGroupProperties_bit2 = -1;
+static int hf_pn_io_TxPortGroupProperties_bit3 = -1;
+static int hf_pn_io_TxPortGroupProperties_bit4 = -1;
+static int hf_pn_io_TxPortGroupProperties_bit5 = -1;
+static int hf_pn_io_TxPortGroupProperties_bit6 = -1;
+static int hf_pn_io_TxPortGroupProperties_bit7 = -1;
+
+static int hf_pn_io_start_of_red_frame_id = -1;
+static int hf_pn_io_end_of_red_frame_id = -1;
+static int hf_pn_io_ir_begin_end_port = -1;
+static int hf_pn_io_number_of_assignments = -1;
+static int hf_pn_io_number_of_phases = -1;
+static int hf_pn_io_red_orange_period_begin_tx = -1;
+static int hf_pn_io_orange_period_begin_tx = -1;
+static int hf_pn_io_green_period_begin_tx = -1;
+static int hf_pn_io_red_orange_period_begin_rx = -1;
+static int hf_pn_io_orange_period_begin_rx = -1;
+static int hf_pn_io_green_period_begin_rx = -1;
+/* static int hf_pn_io_tx_phase_assignment = -1; */
+static int hf_pn_ir_tx_phase_assignment = -1;
+static int hf_pn_ir_rx_phase_assignment = -1;
+static int hf_pn_io_tx_phase_assignment_begin_value = -1;
+static int hf_pn_io_tx_phase_assignment_orange_begin = -1;
+static int hf_pn_io_tx_phase_assignment_end_reserved = -1;
+static int hf_pn_io_tx_phase_assignment_reserved = -1;
+/* static int hf_pn_io_rx_phase_assignment = -1; */
+
+static int hf_pn_io_slot = -1;
+static int hf_pn_io_subslot = -1;
+static int hf_pn_io_number_of_slots = -1;
+static int hf_pn_io_number_of_subslots = -1;
+
+/* static int hf_pn_io_maintenance_required_drop_budget = -1; */
+/* static int hf_pn_io_maintenance_demanded_drop_budget = -1; */
+/* static int hf_pn_io_error_drop_budget = -1; */
+
+static int hf_pn_io_tsn_number_of_queues = -1;
+static int hf_pn_io_tsn_max_supported_record_size = -1;
+static int hf_pn_io_tsn_transfer_time_tx = -1;
+static int hf_pn_io_tsn_transfer_time_rx = -1;
+static int hf_pn_io_tsn_port_capabilities_time_aware = -1;
+static int hf_pn_io_tsn_port_capabilities_preemption = -1;
+static int hf_pn_io_tsn_port_capabilities_queue_masking = -1;
+static int hf_pn_io_tsn_port_capabilities_reserved = -1;
+static int hf_pn_io_tsn_forwarding_group = -1;
+static int hf_pn_io_tsn_forwarding_group_ingress = -1;
+static int hf_pn_io_tsn_forwarding_group_egress = -1;
+static int hf_pn_io_tsn_stream_class = -1;
+static int hf_pn_io_tsn_dependent_forwarding_delay = -1;
+static int hf_pn_io_tsn_independent_forwarding_delay = -1;
+static int hf_pn_io_tsn_forwarding_delay_block_number_of_entries = -1;
+static int hf_pn_io_tsn_expected_neighbor_block_number_of_entries = -1;
+static int hf_pn_io_tsn_port_id_block_number_of_entries = -1;
+
+static int hf_pn_io_tsn_nme_parameter_uuid = -1;
+static int hf_pn_io_tsn_domain_vid_config = -1;
+static int hf_pn_io_tsn_domain_vid_config_stream_high_vid = -1;
+static int hf_pn_io_tsn_domain_vid_config_stream_high_red_vid = -1;
+static int hf_pn_io_tsn_domain_vid_config_stream_low_vid = -1;
+static int hf_pn_io_tsn_domain_vid_config_stream_low_red_vid = -1;
+static int hf_pn_io_tsn_domain_vid_config_non_stream_vid = -1;
+static int hf_pn_io_tsn_domain_vid_config_non_stream_vid_B = -1;
+static int hf_pn_io_tsn_domain_vid_config_non_stream_vid_C = -1;
+static int hf_pn_io_tsn_domain_vid_config_non_stream_vid_D = -1;
+static int hf_pn_io_tsn_domain_vid_config_reserved = -1;
+static int hf_pn_io_number_of_tsn_time_data_block_entries = -1;
+static int hf_pn_io_number_of_tsn_domain_queue_rate_limiter_entries = -1;
+static int hf_pn_io_number_of_tsn_domain_port_ingress_rate_limiter_entries = -1;
+static int hf_pn_io_number_of_tsn_domain_port_config_entries = -1;
+
+static int hf_pn_io_tsn_domain_port_config = -1;
+static int hf_pn_io_tsn_domain_port_config_preemption_enabled = -1;
+static int hf_pn_io_tsn_domain_port_config_boundary_port_config = -1;
+static int hf_pn_io_tsn_domain_port_config_reserved = -1;
+
+static int hf_pn_io_tsn_domain_port_ingress_rate_limiter = -1;
+static int hf_pn_io_tsn_domain_port_ingress_rate_limiter_cir = -1;
+static int hf_pn_io_tsn_domain_port_ingress_rate_limiter_cbs = -1;
+static int hf_pn_io_tsn_domain_port_ingress_rate_limiter_envelope = -1;
+static int hf_pn_io_tsn_domain_port_ingress_rate_limiter_rank = -1;
+
+static int hf_pn_io_tsn_domain_queue_rate_limiter = -1;
+static int hf_pn_io_tsn_domain_queue_rate_limiter_cir = -1;
+static int hf_pn_io_tsn_domain_queue_rate_limiter_cbs = -1;
+static int hf_pn_io_tsn_domain_queue_rate_limiter_envelope = -1;
+static int hf_pn_io_tsn_domain_queue_rate_limiter_rank = -1;
+static int hf_pn_io_tsn_domain_queue_rate_limiter_queue_id = -1;
+static int hf_pn_io_tsn_domain_queue_rate_limiter_reserved = -1;
+
+static int hf_pn_io_number_of_tsn_domain_queue_config_entries = -1;
+static int hf_pn_io_tsn_domain_queue_config = -1;
+static int hf_pn_io_tsn_domain_queue_config_queue_id = -1;
+static int hf_pn_io_tsn_domain_queue_config_tci_pcp = -1;
+static int hf_pn_io_tsn_domain_queue_config_shaper = -1;
+static int hf_pn_io_tsn_domain_queue_config_preemption_mode = -1;
+static int hf_pn_io_tsn_domain_queue_config_unmask_time_offset = -1;
+static int hf_pn_io_tsn_domain_queue_config_mask_time_offset = -1;
+
+static int hf_pn_io_network_deadline = -1;
+static int hf_pn_io_time_domain_number = -1;
+static int hf_pn_io_time_pll_window = -1;
+static int hf_pn_io_message_interval_factor = -1;
+static int hf_pn_io_message_timeout_factor = -1;
+static int hf_pn_io_time_sync_properties = -1;
+static int hf_pn_io_time_sync_properties_role = -1;
+static int hf_pn_io_time_sync_properties_reserved = -1;
+static int hf_pn_io_time_domain_uuid = -1;
+static int hf_pn_io_time_domain_name_length = -1;
+static int hf_pn_io_time_domain_name = -1;
+static int hf_pn_io_tsn_nme_name_uuid = -1;
+static int hf_pn_io_tsn_nme_name_length = -1;
+static int hf_pn_io_tsn_nme_name = -1;
+static int hf_pn_io_tsn_domain_uuid = -1;
+static int hf_pn_io_tsn_domain_name_length = -1;
+static int hf_pn_io_tsn_domain_name = -1;
+
+static int hf_pn_io_tsn_fdb_command = -1;
+static int hf_pn_io_tsn_dst_add = -1;
+
+static int hf_pn_io_number_of_tsn_domain_sync_tree_entries = -1;
+static int hf_pn_io_tsn_domain_sync_port_role = -1;
+static int hf_pn_io_tsn_domain_port_id = -1;
+
+static int hf_pn_io_maintenance_required_power_budget = -1;
+static int hf_pn_io_maintenance_demanded_power_budget = -1;
+static int hf_pn_io_error_power_budget = -1;
+
+static int hf_pn_io_fiber_optic_type = -1;
+static int hf_pn_io_fiber_optic_cable_type = -1;
+
+static int hf_pn_io_controller_appl_cycle_factor = -1;
+static int hf_pn_io_time_data_cycle = -1;
+static int hf_pn_io_time_io_input = -1;
+static int hf_pn_io_time_io_output = -1;
+static int hf_pn_io_time_io_input_valid = -1;
+static int hf_pn_io_time_io_output_valid = -1;
+
+static int hf_pn_io_maintenance_status = -1;
+static int hf_pn_io_maintenance_status_required = -1;
+static int hf_pn_io_maintenance_status_demanded = -1;
+
+static int hf_pn_io_vendor_id_high = -1;
+static int hf_pn_io_vendor_id_low = -1;
+static int hf_pn_io_vendor_block_type = -1;
+static int hf_pn_io_order_id = -1;
+static int hf_pn_io_im_serial_number = -1;
+static int hf_pn_io_im_hardware_revision = -1;
+static int hf_pn_io_im_revision_prefix = -1;
+static int hf_pn_io_im_sw_revision_functional_enhancement = -1;
+static int hf_pn_io_im_revision_bugfix = -1;
+static int hf_pn_io_im_sw_revision_internal_change = -1;
+static int hf_pn_io_im_revision_counter = -1;
+static int hf_pn_io_im_profile_id = -1;
+static int hf_pn_io_im_profile_specific_type = -1;
+static int hf_pn_io_im_version_major = -1;
+static int hf_pn_io_im_version_minor = -1;
+static int hf_pn_io_im_supported = -1;
+static int hf_pn_io_im_numberofentries = -1;
+static int hf_pn_io_im_annotation = -1;
+static int hf_pn_io_im_order_id = -1;
+
+static int hf_pn_io_number_of_ars = -1;
+
+static int hf_pn_io_cycle_counter = -1;
+static int hf_pn_io_data_status = -1;
+static int hf_pn_io_data_status_res67 = -1;
+static int hf_pn_io_data_status_ok = -1;
+static int hf_pn_io_data_status_operate = -1;
+static int hf_pn_io_data_status_res3 = -1;
+static int hf_pn_io_data_status_valid = -1;
+static int hf_pn_io_data_status_res1 = -1;
+static int hf_pn_io_data_status_primary = -1;
+static int hf_pn_io_transfer_status = -1;
+
+static int hf_pn_io_actual_local_time_stamp = -1;
+static int hf_pn_io_number_of_log_entries = -1;
+static int hf_pn_io_local_time_stamp = -1;
+static int hf_pn_io_entry_detail = -1;
+
+static int hf_pn_io_ip_address = -1;
+static int hf_pn_io_subnetmask = -1;
+static int hf_pn_io_standard_gateway = -1;
+
+static int hf_pn_io_mrp_domain_uuid = -1;
+static int hf_pn_io_mrp_role = -1;
+static int hf_pn_io_mrp_length_domain_name = -1;
+static int hf_pn_io_mrp_domain_name = -1;
+static int hf_pn_io_mrp_instances = -1;
+static int hf_pn_io_mrp_instance = -1;
+
+static int hf_pn_io_mrp_prio = -1;
+static int hf_pn_io_mrp_topchgt = -1;
+static int hf_pn_io_mrp_topnrmax = -1;
+static int hf_pn_io_mrp_tstshortt = -1;
+static int hf_pn_io_mrp_tstdefaultt = -1;
+static int hf_pn_io_mrp_tstnrmax = -1;
+static int hf_pn_io_mrp_check = -1;
+static int hf_pn_io_mrp_check_mrm = -1;
+static int hf_pn_io_mrp_check_mrpdomain = -1;
+static int hf_pn_io_mrp_check_reserved_1 = -1;
+static int hf_pn_io_mrp_check_reserved_2 = -1;
+
+static int hf_pn_io_mrp_rtmode = -1;
+static int hf_pn_io_mrp_rtmode_rtclass12 = -1;
+static int hf_pn_io_mrp_rtmode_rtclass3 = -1;
+static int hf_pn_io_mrp_rtmode_reserved1 = -1;
+static int hf_pn_io_mrp_rtmode_reserved2 = -1;
+
+static int hf_pn_io_mrp_lnkdownt = -1;
+static int hf_pn_io_mrp_lnkupt = -1;
+static int hf_pn_io_mrp_lnknrmax = -1;
+static int hf_pn_io_mrp_version = -1;
+
+static int hf_pn_io_substitute_active_flag = -1;
+static int hf_pn_io_length_data = -1;
+
+static int hf_pn_io_mrp_ring_state = -1;
+static int hf_pn_io_mrp_rt_state = -1;
+
+static int hf_pn_io_im_tag_function = -1;
+static int hf_pn_io_im_tag_location = -1;
+static int hf_pn_io_im_date = -1;
+static int hf_pn_io_im_descriptor = -1;
+
+static int hf_pn_io_fs_hello_mode = -1;
+static int hf_pn_io_fs_hello_interval = -1;
+static int hf_pn_io_fs_hello_retry = -1;
+static int hf_pn_io_fs_hello_delay = -1;
+
+static int hf_pn_io_fs_parameter_mode = -1;
+static int hf_pn_io_fs_parameter_uuid = -1;
+
+
+static int hf_pn_io_check_sync_mode = -1;
+static int hf_pn_io_check_sync_mode_reserved = -1;
+static int hf_pn_io_check_sync_mode_sync_master = -1;
+static int hf_pn_io_check_sync_mode_cable_delay = -1;
+
+/* PROFIsafe fParameters */
+static int hf_pn_io_ps_f_prm_flag1 = -1;
+static int hf_pn_io_ps_f_prm_flag1_chck_seq = -1;
+static int hf_pn_io_ps_f_prm_flag1_chck_ipar = -1;
+static int hf_pn_io_ps_f_prm_flag1_sil = -1;
+static int hf_pn_io_ps_f_prm_flag1_crc_len = -1;
+static int hf_pn_io_ps_f_prm_flag1_crc_seed = -1;
+static int hf_pn_io_ps_f_prm_flag1_reserved = -1;
+static int hf_pn_io_ps_f_prm_flag2 = -1;
+static int hf_pn_io_ps_f_wd_time = -1;
+static int hf_pn_io_ps_f_ipar_crc = -1;
+static int hf_pn_io_ps_f_par_crc = -1;
+static int hf_pn_io_ps_f_src_adr = -1;
+static int hf_pn_io_ps_f_dest_adr = -1;
+static int hf_pn_io_ps_f_prm_flag2_reserved = -1;
+static int hf_pn_io_ps_f_prm_flag2_f_block_id = -1;
+static int hf_pn_io_ps_f_prm_flag2_f_par_version = -1;
+
+static int hf_pn_io_profidrive_request_reference = -1;
+static int hf_pn_io_profidrive_request_id = -1;
+static int hf_pn_io_profidrive_do_id = -1;
+static int hf_pn_io_profidrive_no_of_parameters = -1;
+static int hf_pn_io_profidrive_response_id = -1;
+static int hf_pn_io_profidrive_param_attribute = -1;
+static int hf_pn_io_profidrive_param_no_of_elems = -1;
+static int hf_pn_io_profidrive_param_number = -1;
+static int hf_pn_io_profidrive_param_subindex = -1;
+static int hf_pn_io_profidrive_param_format = -1;
+static int hf_pn_io_profidrive_param_no_of_values = -1;
+static int hf_pn_io_profidrive_param_value_byte = -1;
+static int hf_pn_io_profidrive_param_value_word = -1;
+static int hf_pn_io_profidrive_param_value_dword = -1;
+static int hf_pn_io_profidrive_param_value_float = -1;
+static int hf_pn_io_profidrive_param_value_string = -1;
+static int hf_pn_io_profidrive_param_value_error = -1;
+static int hf_pn_io_profidrive_param_value_error_sub = -1;
+
+
+/* Sequence of Events - Reporting System Alarm/Event Information */
+static int hf_pn_io_rs_alarm_info_reserved_0_7 = -1;
+static int hf_pn_io_rs_alarm_info_reserved_8_15 = -1;
+static int hf_pn_io_rs_alarm_info = -1;
+static int hf_pn_io_rs_event_info = -1;
+static int hf_pn_io_rs_event_block = -1;
+static int hf_pn_io_rs_adjust_block = -1;
+static int hf_pn_io_rs_event_data_extension = -1;
+static int hf_pn_io_number_of_rs_event_info = -1;
+static int hf_pn_io_rs_block_type = -1;
+static int hf_pn_io_rs_block_length = -1;
+static int hf_pn_io_rs_specifier = -1;
+static int hf_pn_io_rs_specifier_sequence = -1;
+static int hf_pn_io_rs_specifier_reserved = -1;
+static int hf_pn_io_rs_specifier_specifier = -1;
+static int hf_pn_io_rs_time_stamp = -1;
+static int hf_pn_io_rs_time_stamp_status = -1;
+static int hf_pn_io_rs_time_stamp_value = -1;
+static int hf_pn_io_rs_minus_error = -1;
+static int hf_pn_io_rs_plus_error = -1;
+static int hf_pn_io_rs_extension_block_type = -1;
+static int hf_pn_io_rs_extension_block_length = -1;
+static int hf_pn_io_rs_reason_code = -1;
+static int hf_pn_io_rs_reason_code_reason = -1;
+static int hf_pn_io_rs_reason_code_detail = -1;
+static int hf_pn_io_rs_domain_identification = -1;
+static int hf_pn_io_rs_master_identification = -1;
+static int hf_pn_io_soe_digital_input_current_value = -1;
+static int hf_pn_io_soe_digital_input_current_value_value = -1;
+static int hf_pn_io_soe_digital_input_current_value_reserved = -1;
+static int hf_pn_io_am_device_identification = -1;
+static int hf_pn_io_am_device_identification_device_sub_id = -1;
+static int hf_pn_io_am_device_identification_device_id = -1;
+static int hf_pn_io_am_device_identification_vendor_id = -1;
+static int hf_pn_io_am_device_identification_organization = -1;
+static int hf_pn_io_rs_adjust_info = -1;
+static int hf_pn_io_soe_max_scan_delay = -1;
+static int hf_pn_io_soe_adjust_specifier = -1;
+static int hf_pn_io_soe_adjust_specifier_reserved = -1;
+static int hf_pn_io_soe_adjust_specifier_incident = -1;
+static int hf_pn_io_rs_properties = -1;
+static int hf_pn_io_rs_properties_alarm_transport = -1;
+static int hf_pn_io_rs_properties_reserved1 = -1;
+static int hf_pn_io_rs_properties_reserved2 = -1;
+
+static int hf_pn_io_asset_management_info = -1;
+static int hf_pn_io_number_of_asset_management_info = -1;
+static int hf_pn_io_im_uniqueidentifier = -1;
+static int hf_pn_io_am_location_structure = -1;
+static int hf_pn_io_am_location_level_0 = -1;
+static int hf_pn_io_am_location_level_1 = -1;
+static int hf_pn_io_am_location_level_2 = -1;
+static int hf_pn_io_am_location_level_3 = -1;
+static int hf_pn_io_am_location_level_4 = -1;
+static int hf_pn_io_am_location_level_5 = -1;
+static int hf_pn_io_am_location_level_6 = -1;
+static int hf_pn_io_am_location_level_7 = -1;
+static int hf_pn_io_am_location_level_8 = -1;
+static int hf_pn_io_am_location_level_9 = -1;
+static int hf_pn_io_am_location_level_10 = -1;
+static int hf_pn_io_am_location_level_11 = -1;
+static int hf_pn_io_am_location = -1;
+static int hf_pn_io_am_location_reserved1 = -1;
+static int hf_pn_io_am_location_reserved2 = -1;
+static int hf_pn_io_am_location_reserved3 = -1;
+static int hf_pn_io_am_location_reserved4 = -1;
+static int hf_pn_io_am_location_beginslotnum = -1;
+static int hf_pn_io_am_location_beginsubslotnum = -1;
+static int hf_pn_io_am_location_endslotnum = -1;
+static int hf_pn_io_am_location_endsubslotnum = -1;
+static int hf_pn_io_am_software_revision = -1;
+static int hf_pn_io_am_hardware_revision = -1;
+static int hf_pn_io_am_type_identification = -1;
+static int hf_pn_io_am_reserved = -1;
+
+static int hf_pn_io_dcp_boundary_value = -1;
+static int hf_pn_io_dcp_boundary_value_bit0 = -1;
+static int hf_pn_io_dcp_boundary_value_bit1 = -1;
+static int hf_pn_io_dcp_boundary_value_otherbits = -1;
+
+static int hf_pn_io_peer_to_peer_boundary_value = -1;
+static int hf_pn_io_peer_to_peer_boundary_value_bit0 = -1;
+static int hf_pn_io_peer_to_peer_boundary_value_bit1 = -1;
+static int hf_pn_io_peer_to_peer_boundary_value_bit2 = -1;
+static int hf_pn_io_peer_to_peer_boundary_value_otherbits = -1;
+
+static int hf_pn_io_mau_type_extension = -1;
+
+static int hf_pn_io_pe_operational_mode = -1;
+
+static int hf_pn_io_snmp_community_name_length = -1;
+static int hf_pn_io_snmp_community_name = -1;
+static int hf_pn_io_snmp_read_community_name = -1;
+static int hf_pn_io_snmp_write_community_name = -1;
+
+static int hf_pn_io_snmp_control = -1;
+
+/* static int hf_pn_io_packedframe_SFCRC = -1; */
+static gint ett_pn_io = -1;
+static gint ett_pn_io_block = -1;
+static gint ett_pn_io_block_header = -1;
+static gint ett_pn_io_rtc = -1;
+static gint ett_pn_io_rta = -1;
+static gint ett_pn_io_pdu_type = -1;
+static gint ett_pn_io_add_flags = -1;
+static gint ett_pn_io_control_command = -1;
+static gint ett_pn_io_ioxs = -1;
+static gint ett_pn_io_api = -1;
+static gint ett_pn_io_data_description = -1;
+static gint ett_pn_io_module = -1;
+static gint ett_pn_io_submodule = -1;
+static gint ett_pn_io_io_data_object = -1;
+static gint ett_pn_io_io_cs = -1;
+static gint ett_pn_io_ar_properties = -1;
+static gint ett_pn_io_iocr_properties = -1;
+static gint ett_pn_io_submodule_properties = -1;
+static gint ett_pn_io_alarmcr_properties = -1;
+static gint ett_pn_io_submodule_state = -1;
+static gint ett_pn_io_channel_properties = -1;
+static gint ett_pn_io_slot = -1;
+static gint ett_pn_io_subslot = -1;
+static gint ett_pn_io_maintenance_status = -1;
+static gint ett_pn_io_data_status = -1;
+static gint ett_pn_io_iocr = -1;
+static gint ett_pn_io_mrp_rtmode = -1;
+static gint ett_pn_io_control_block_properties = -1;
+static gint ett_pn_io_check_sync_mode = -1;
+static gint ett_pn_io_ir_frame_data = -1;
+static gint ett_pn_FrameDataProperties = -1;
+static gint ett_pn_io_ar_info = -1;
+static gint ett_pn_io_ar_data = -1;
+static gint ett_pn_io_ir_begin_end_port = -1;
+static gint ett_pn_io_ir_tx_phase = -1;
+static gint ett_pn_io_ir_rx_phase = -1;
+static gint ett_pn_io_subframe_data =-1;
+static gint ett_pn_io_SFIOCRProperties = -1;
+static gint ett_pn_io_frame_defails = -1;
+static gint ett_pn_io_profisafe_f_parameter = -1;
+static gint ett_pn_io_profisafe_f_parameter_prm_flag1 = -1;
+static gint ett_pn_io_profisafe_f_parameter_prm_flag2 = -1;
+static gint ett_pn_io_profidrive_parameter_request = -1;
+static gint ett_pn_io_profidrive_parameter_response = -1;
+static gint ett_pn_io_profidrive_parameter_address = -1;
+static gint ett_pn_io_profidrive_parameter_value = -1;
+static gint ett_pn_io_rs_alarm_info = -1;
+static gint ett_pn_io_rs_event_info = -1;
+static gint ett_pn_io_rs_event_block = -1;
+static gint ett_pn_io_rs_adjust_block = -1;
+static gint ett_pn_io_rs_event_data_extension = -1;
+static gint ett_pn_io_rs_specifier = -1;
+static gint ett_pn_io_rs_time_stamp = -1;
+static gint ett_pn_io_am_device_identification = -1;
+static gint ett_pn_io_rs_reason_code = -1;
+static gint ett_pn_io_soe_digital_input_current_value = -1;
+static gint ett_pn_io_rs_adjust_info = -1;
+static gint ett_pn_io_soe_adjust_specifier = -1;
+static gint ett_pn_io_sr_properties = -1;
+static gint ett_pn_io_line_delay = -1;
+static gint ett_pn_io_counter_status = -1;
+static gint ett_pn_io_neighbor = -1;
+
+static gint ett_pn_io_GroupProperties = -1;
+
+static gint ett_pn_io_asset_management_info = -1;
+static gint ett_pn_io_asset_management_block = -1;
+static gint ett_pn_io_am_location = -1;
+
+static gint ett_pn_io_dcp_boundary = -1;
+static gint ett_pn_io_peer_to_peer_boundary = -1;
+
+static gint ett_pn_io_mau_type_extension = -1;
+
+static gint ett_pn_io_pe_operational_mode = -1;
+
+static gint ett_pn_io_tsn_domain_port_config = -1;
+static gint ett_pn_io_tsn_domain_port_ingress_rate_limiter = -1;
+static gint ett_pn_io_tsn_domain_queue_rate_limiter = -1;
+static gint ett_pn_io_tsn_domain_vid_config = -1;
+static gint ett_pn_io_tsn_domain_queue_config = -1;
+static gint ett_pn_io_time_sync_properties = -1;
+static gint ett_pn_io_tsn_domain_port_id = -1;
+
+static gint ett_pn_io_snmp_command_name = -1;
+
+
+#define PD_SUB_FRAME_BLOCK_FIOCR_PROPERTIES_LENGTH 4
+#define PD_SUB_FRAME_BLOCK_FRAME_ID_LENGTH 2
+#define PD_SUB_FRAME_BLOCK_SUB_FRAME_DATA_LENGTH 4
+
+static expert_field ei_pn_io_block_version = EI_INIT;
+static expert_field ei_pn_io_block_length = EI_INIT;
+static expert_field ei_pn_io_unsupported = EI_INIT;
+static expert_field ei_pn_io_localalarmref = EI_INIT;
+static expert_field ei_pn_io_mrp_instances = EI_INIT;
+static expert_field ei_pn_io_ar_info_not_found = EI_INIT;
+static expert_field ei_pn_io_iocr_type = EI_INIT;
+static expert_field ei_pn_io_frame_id = EI_INIT;
+static expert_field ei_pn_io_nr_of_tx_port_groups = EI_INIT;
+static expert_field ei_pn_io_max_recursion_depth_reached = EI_INIT;
+
+static e_guid_t uuid_pn_io_device = { 0xDEA00001, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
+static guint16 ver_pn_io_device = 1;
+
+static e_guid_t uuid_pn_io_controller = { 0xDEA00002, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
+static guint16 ver_pn_io_controller = 1;
+
+static e_guid_t uuid_pn_io_supervisor = { 0xDEA00003, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
+static guint16 ver_pn_io_supervisor = 1;
+
+static e_guid_t uuid_pn_io_parameterserver = { 0xDEA00004, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
+static guint16 ver_pn_io_parameterserver = 1;
+
+/* According to specification:
+ * Value(UUID): 00000000-0000-0000-0000-000000000000
+ * Meaning: Reserved
+ * Use: The value NIL indicates the usage of the implicit AR.
+ */
+static e_guid_t uuid_pn_io_implicitar = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
+static guint16 ver_pn_io_implicitar = 1;
+
+/* PNIO Preference Variables */
+gboolean pnio_ps_selection = TRUE;
+static const char *pnio_ps_networkpath = "";
+
+wmem_list_t *aruuid_frame_setup_list = NULL;
+static wmem_map_t *pnio_time_aware_frame_map = NULL;
+
+
+/* Allow heuristic dissection */
+static heur_dissector_list_t heur_pn_subdissector_list;
+
+static const value_string pn_io_block_type[] = {
+ { 0x0000, "Reserved" },
+ { 0x0001, "Alarm Notification High"},
+ { 0x8001, "Alarm Ack High"},
+ { 0x0002, "Alarm Notification Low"},
+ { 0x8002, "Alarm Ack Low"},
+ { 0x0008, "IODWriteReqHeader"},
+ { 0x8008, "IODWriteResHeader"},
+ { 0x0009, "IODReadReqHeader"},
+ { 0x8009, "IODReadResHeader"},
+ { 0x0010, "DiagnosisData"},
+ { 0x0011, "Reserved"},
+ { 0x0012, "ExpectedIdentificationData"},
+ { 0x0013, "RealIdentificationData"},
+ { 0x0014, "SubstituteValue"},
+ { 0x0015, "RecordInputDataObjectElement"},
+ { 0x0016, "RecordOutputDataObjectElement"},
+ { 0x0017, "reserved"},
+ { 0x0018, "ARData"},
+ { 0x0019, "LogData"},
+ { 0x001A, "APIData"},
+ { 0x001b, "SRLData"},
+ { 0x0020, "I&M0"},
+ { 0x0021, "I&M1"},
+ { 0x0022, "I&M2"},
+ { 0x0023, "I&M3"},
+ { 0x0024, "I&M4"},
+ { 0x0025, "I&M5"},
+ { 0x0026, "I&M6"},
+ { 0x0027, "I&M7"},
+ { 0x0028, "I&M8"},
+ { 0x0029, "I&M9"},
+ { 0x002A, "I&M10"},
+ { 0x002B, "I&M11"},
+ { 0x002C, "I&M12"},
+ { 0x002D, "I&M13"},
+ { 0x002E, "I&M14"},
+ { 0x002F, "I&M15"},
+ { 0x0030, "I&M0FilterDataSubmodul"},
+ { 0x0031, "I&M0FilterDataModul"},
+ { 0x0032, "I&M0FilterDataDevice"},
+ { 0x0033, "Reserved" },
+ { 0x0034, "I&M5Data"},
+ { 0x0035, "AssetManagementData"},
+ { 0x0036, "AM_FullInformation"},
+ { 0x0037, "AM_HardwareOnlyInformation"},
+ { 0x0038, "AM_FirmwareOnlyInformation" },
+ { 0x8001, "Alarm Ack High"},
+ { 0x8002, "Alarm Ack Low"},
+ { 0x0101, "ARBlockReq"},
+ { 0x8101, "ARBlockRes"},
+ { 0x0102, "IOCRBlockReq"},
+ { 0x8102, "IOCRBlockRes"},
+ { 0x0103, "AlarmCRBlockReq"},
+ { 0x8103, "AlarmCRBlockRes"},
+ { 0x0104, "ExpectedSubmoduleBlockReq"},
+ { 0x8104, "ModuleDiffBlock"},
+ { 0x0105, "PrmServerBlockReq"},
+ { 0x8105, "PrmServerBlockRes"},
+ { 0x0106, "MCRBlockReq"},
+ { 0x8106, "ARServerBlockRes"},
+ { 0x0107, "SubFrameBlock"},
+ { 0x8107, "ARRPCBlockRes"},
+ { 0x0108, "ARVendorBlockReq"},
+ { 0x8108, "ARVendorBlockRes"},
+ { 0x0109, "IRInfoBlock"},
+ { 0x010A, "SRInfoBlock"},
+ { 0x010B, "ARFSUBlock"},
+ { 0x010C, "RSInfoBlock"},
+ { 0x0110, "IODControlReq Prm End.req"},
+ { 0x8110, "IODControlRes Prm End.rsp"},
+ { 0x0111, "IODControlReq Plug Prm End.req"},
+ { 0x8111, "IODControlRes Plug Prm End.rsp"},
+ { 0x0112, "IOXBlockReq Application Ready.req"},
+ { 0x8112, "IOXBlockRes Application Ready.rsp"},
+ { 0x0113, "IOXBlockReq Plug Application Ready.req"},
+ { 0x8113, "IOXBlockRes Plug Application Ready.rsp"},
+ { 0x0114, "IODReleaseReq"},
+ { 0x8114, "IODReleaseRes"},
+ { 0x0115, "ARRPCServerBlockReq"},
+ { 0x8115, "ARRPCServerBlockRes"},
+ { 0x0116, "IOXControlReq Ready for Companion.req"},
+ { 0x8116, "IOXControlRes Ready for Companion.rsp"},
+ { 0x0117, "IOXControlReq Ready for RT_CLASS_3.req"},
+ { 0x8117, "IOXControlRes Ready for RT_CLASS_3.rsp"},
+ { 0x0118, "PrmBeginReq"},
+ { 0x8118, "PrmBeginRes"},
+ { 0x0119, "SubmoduleListBlock"},
+
+ { 0x0200, "PDPortDataCheck"},
+ { 0x0201, "PDevData"},
+ { 0x0202, "PDPortDataAdjust"},
+ { 0x0203, "PDSyncData"},
+ { 0x0204, "IsochronousModeData"},
+ { 0x0205, "PDIRData"},
+ { 0x0206, "PDIRGlobalData"},
+ { 0x0207, "PDIRFrameData"},
+ { 0x0208, "PDIRBeginEndData"},
+ { 0x0209, "AdjustDomainBoundary"},
+ { 0x020A, "CheckPeers"},
+ { 0x020B, "CheckLineDelay"},
+ { 0x020C, "Checking MAUType"},
+ { 0x020E, "Adjusting MAUType"},
+ { 0x020F, "PDPortDataReal"},
+ { 0x0210, "AdjustMulticastBoundary"},
+ { 0x0211, "PDInterfaceMrpDataAdjust"},
+ { 0x0212, "PDInterfaceMrpDataReal"},
+ { 0x0213, "PDInterfaceMrpDataCheck"},
+ { 0x0214, "PDPortMrpDataAdjust"},
+ { 0x0215, "PDPortMrpDataReal"},
+ { 0x0216, "Media redundancy manager parameters"},
+ { 0x0217, "Media redundancy client parameters"},
+ { 0x0218, "Media redundancy RT mode for manager"},
+ { 0x0219, "Media redundancy ring state data"},
+ { 0x021A, "Media redundancy RT ring state data"},
+ { 0x021B, "Adjust LinkState"},
+ { 0x021C, "Checking LinkState"},
+ { 0x021D, "Media redundancy RT mode for clients"},
+ { 0x021E, "CheckSyncDifference"},
+ { 0x021F, "CheckMAUTypeDifference"},
+ { 0x0220, "PDPortFODataReal"},
+ { 0x0221, "Reading real fiber optic manufacturerspecific data"},
+ { 0x0222, "PDPortFODataAdjust"},
+ { 0x0223, "PDPortFODataCheck"},
+ { 0x0224, "Adjust PeerToPeerBoundary"},
+ { 0x0225, "Adjust DCPBoundary"},
+ { 0x0226, "Adjust PreambleLength"},
+ { 0x0227, "CheckMAUType-Extension"},
+ { 0x0228, "Reading real fiber optic diagnosis data"},
+ { 0x0229, "AdjustMAUType-Extension"},
+ { 0x022A, "PDIRSubframeData"},
+ { 0x022B, "SubframeBlock"},
+ { 0x022C, "PDPortDataRealExtended"},
+ { 0x022D, "PDTimeData"},
+ { 0x022E, "PDPortSFPDataCheck"},
+ { 0x0230, "PDNCDataCheck"},
+ { 0x0231, "MrpInstanceDataAdjust"},
+ { 0x0232, "MrpInstanceDataReal"},
+ { 0x0233, "MrpInstanceDataCheck"},
+ { 0x0234, "PDPortMrpIcDataAdjust"},
+ { 0x0235, "PDPortMrpIcDataCheck"},
+ { 0x0236, "PDPortMrpIcDataReal"},
+ { 0x0240, "PDInterfaceDataReal"},
+ { 0x0241, "PDRsiInstances"},
+ { 0x0250, "PDInterfaceAdjust"},
+ { 0x0251, "PDPortStatistic"},
+ { 0x0260, "OwnPort"},
+ { 0x0261, "Neighbors"},
+ { 0x0270, "TSNNetworkControlDataReal"},
+ { 0x0271, "TSNNetworkControlDataAdjust"},
+ { 0x0272, "TSNDomainPortConfigBlock"},
+ { 0x0273, "TSNDomainQueueConfigBlock"},
+ { 0x0274, "TSNTimeDataBlock"},
+ { 0x0275, "TSNStreamPathData"},
+ { 0x0276, "TSNSyncTreeData"},
+ { 0x0277, "TSNUploadNetworkAttributes"},
+ { 0x0278, "ForwardingDelayBlock"},
+ { 0x0279, "TSNExpectedNetworkAttributes"},
+ { 0x027A, "TSNStreamPathDataReal"},
+ { 0x027B, "TSNDomainPortIngressRateLimiterBlock"},
+ { 0x027C, "TSNDomainQueueRateLimiterBlock"},
+ { 0x027D, "TSNPortIDBlock"},
+ { 0x027E, "TSNExpectedNeighborBlock" },
+ { 0x0300, "CIMSNMPAdjust"},
+ { 0x0400, "MultipleBlockHeader"},
+ { 0x0401, "COContainerContent"},
+ { 0x0500, "RecordDataReadQuery"},
+ { 0x0501, "TSNAddStreamReq"},
+ { 0x0502, "TSNAddStreamRsp"},
+ { 0x0503, "TSNRemoveStreamReq"},
+ { 0x0504, "TSNRemoveStreamRsp"},
+ { 0x0505, "TSNRenewStreamReq"},
+ { 0x0506, "TSNRenewStreamRsp"},
+ { 0x0600, "FSHelloBlock"},
+ { 0x0601, "FSParameterBlock"},
+ { 0x0602, "FastStartUpBlock"},
+ { 0x0608, "PDInterfaceFSUDataAdjust"},
+ { 0x0609, "ARFSUDataAdjust"},
+ { 0x0700, "AutoConfiguration"},
+ { 0x0701, "AutoConfiguration Communication"},
+ { 0x0702, "AutoConfiguration Configuration"},
+ { 0x0703, "AutoConfiguration Isochronous"},
+ { 0x0810, "PE_EntityFilterData"},
+ { 0x0811, "PE_EntityStatusData"},
+ { 0x0900, "RS_AdjustObserver" },
+ { 0x0901, "RS_GetEvent" },
+ { 0x0902, "RS_AckEvent" },
+ { 0x0A00, "Upload BLOB Query" },
+ { 0x0A01, "Upload BLOB" },
+ { 0xB050, "Ext-PLL Control / RTC+RTA SyncID 0 (EDD)" },
+ { 0xB051, "Ext-PLL Control / RTA SyncID 1 (GSY)" },
+
+ { 0xB060, "EDD Trace Unit (EDD)" },
+ { 0xB061, "EDD Trace Unit (EDD)" },
+
+ { 0xB070, "OHA Info (OHA)" },
+
+ { 0x0F00, "MaintenanceItem"},
+ { 0x0F01, "Upload selected Records within Upload&RetrievalItem"},
+ { 0x0F02, "iParameterItem"},
+ { 0x0F03, "Retrieve selected Records within Upload&RetrievalItem"},
+ { 0x0F04, "Retrieve all Records within Upload&RetrievalItem"},
+ { 0x0F05, "Signal a PE_OperationalMode change within PE_EnergySavingStatus" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_alarm_type[] = {
+ { 0x0000, "Reserved" },
+ { 0x0001, "Diagnosis" },
+ { 0x0002, "Process" },
+ { 0x0003, "Pull" },
+ { 0x0004, "Plug" },
+ { 0x0005, "Status" },
+ { 0x0006, "Update" },
+ { 0x0007, "Redundancy" },
+ { 0x0008, "Controlled by supervisor" },
+ { 0x0009, "Released" },
+ { 0x000A, "Plug wrong submodule" },
+ { 0x000B, "Return of submodule" },
+ { 0x000C, "Diagnosis disappears" },
+ { 0x000D, "Multicast communication mismatch notification" },
+ { 0x000E, "Port data change notification" },
+ { 0x000F, "Sync data changed notification" },
+ { 0x0010, "Isochronous mode problem notification" },
+ { 0x0011, "Network component problem notification" },
+ { 0x0012, "Time data changed notification" },
+ { 0x0013, "Dynamic Frame Packing problem notification" },
+ /*0x0014 - 0x001D reserved */
+ { 0x001E, "Upload and retrieval notification" },
+ { 0x001F, "Pull module" },
+ /*0x0020 - 0x007F manufacturer specific */
+ /*0x0080 - 0x00FF reserved for profiles */
+ /*0x0100 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_pdu_type[] = {
+ { 0x01, "Data-RTA-PDU" },
+ { 0x02, "NACK-RTA-PDU" },
+ { 0x03, "ACK-RTA-PDU" },
+ { 0x04, "ERR-RTA-PDU" },
+ { 0, NULL }
+};
+
+static const value_string hf_pn_io_frame_data_properties_forwardingMode[] = {
+ { 0x00, "absolute mode" },
+ { 0x01, "relative mode"},
+ { 0, NULL }
+};
+static const value_string hf_pn_io_frame_data_properties_FFMulticastMACAdd[] = {
+ { 0x00, "Use interface MAC destination unicast address" },
+ { 0x01, "Use RT_CLASS_3 destination multicast address"},
+ { 0x02, "Use FastForwardingMulticastMACAdd"},
+ { 0x03, "reserved"},
+ { 0, NULL }};
+
+static const value_string hf_pn_io_frame_data_properties_FragMode[] = {
+ { 0x00, "No fragmentation" },
+ { 0x01, "Fragmentation enabled maximum size for static fragmentation 128 bytes"},
+ { 0x02, "Fragmentation enabled maximum size for static fragmentation 256 bytes"},
+ { 0x03, "reserved"},
+ { 0, NULL }};
+
+static const value_string pn_io_SFIOCRProperties_DFPType_vals[] = {
+ { 0x00, "DFP_INBOUND" },
+ { 0x01, "DFP_OUTBOUND" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_DFPRedundantPathLayout_decode[] = {
+ { 0x00, "The Frame for the redundant path contains the ordering shown by SubframeData" },
+ { 0x01, "The Frame for the redundant path contains the inverse ordering shown by SubframeData" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_SFCRC16_Decode[] = {
+ { 0x00, "SFCRC16 and SFCycleCounter shall be created or set to zero by the sender and not checked by the receiver" },
+ { 0x01, "SFCRC16 and SFCycleCounter shall be created by the sender and checked by the receiver." },
+ { 0, NULL }
+};
+
+static const value_string pn_io_txgroup_state[] = {
+ { 0x00, "Transmission off" },
+ { 0x01, "Transmission on " },
+ { 0, NULL }
+};
+
+static const value_string pn_io_ioxs[] = {
+ { 0x00 /* 0*/, "detected by subslot" },
+ { 0x01 /* 1*/, "detected by slot" },
+ { 0x02 /* 2*/, "detected by IO device" },
+ { 0x03 /* 3*/, "detected by IO controller" },
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_ar_type[] = {
+ { 0x0000, "reserved" },
+ { 0x0001, "IO Controller AR"},
+ { 0x0002, "reserved" },
+ { 0x0003, "IOCARCIR" },
+ { 0x0004, "reserved" },
+ { 0x0005, "reserved" },
+ { 0x0006, "IO Supervisor AR / DeviceAccess AR" },
+ /*0x0007 - 0x000F reserved */
+ { 0x0010, "IO Controller AR (RT_CLASS_3)" },
+ /*0x0011 - 0x001F reserved */
+ { 0x0020, "IO Controller AR (sysred/CiR)" },
+ /*0x0007 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_iocr_type[] = {
+ { 0x0000, "reserved" },
+ { 0x0001, "Input CR" },
+ { 0x0002, "Output CR" },
+ { 0x0003, "Multicast Provider CR" },
+ { 0x0004, "Multicast Consumer CR" },
+ /*0x0005 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_data_description[] = {
+ { 0x0000, "reserved" },
+ { 0x0001, "Input" },
+ { 0x0002, "Output" },
+ { 0x0003, "reserved" },
+ /*0x0004 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_module_state[] = {
+ { 0x0000, "no module" },
+ { 0x0001, "wrong module" },
+ { 0x0002, "proper module" },
+ { 0x0003, "substitute" },
+ /*0x0004 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_arproperties_state[] = {
+ { 0x00000000, "Reserved" },
+ { 0x00000001, "Active" },
+ { 0x00000002, "reserved" },
+ { 0x00000003, "reserved" },
+ { 0x00000004, "reserved" },
+ { 0x00000005, "reserved" },
+ { 0x00000006, "reserved" },
+ { 0x00000007, "reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_arproperties_supervisor_takeover_allowed[] = {
+ { 0x00000000, "not allowed" },
+ { 0x00000001, "allowed" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_arproperties_parameterization_server[] = {
+ { 0x00000000, "External PrmServer" },
+ { 0x00000001, "CM Initiator" },
+ { 0, NULL }
+};
+/* BIT 8 */
+static const value_string pn_io_arproperties_DeviceAccess[] = {
+ { 0x00000000, "Only the submodules from the ExpectedSubmoduleBlock are accessible" },
+ { 0x00000001, "Submodule access is controlled by IO device application" },
+ { 0, NULL }
+};
+
+/* Bit 9 - 10 */
+static const value_string pn_io_arproperties_companion_ar[] = {
+ { 0x00000000, "Single AR" },
+ { 0x00000001, "First AR of a companion pair and a companion AR shall follow" },
+ { 0x00000002, "Companion AR" },
+ { 0x00000003, "Reserved" },
+ { 0, NULL }
+};
+/* REMOVED with 2.3
+static const value_string pn_io_arproperties_data_rate[] = {
+ { 0x00000000, "at least 100 MB/s or more" },
+ { 0x00000001, "100 MB/s" },
+ { 0x00000002, "1 GB/s" },
+ { 0x00000003, "10 GB/s" },
+ { 0, NULL }
+};
+*/
+
+/* BIT 11 */
+static const value_string pn_io_arproperties_acknowldege_companion_ar[] = {
+ { 0x00000000, "No companion AR or no acknowledge for the companion AR required" },
+ { 0x00000001, "Companion AR with acknowledge" },
+ { 0, NULL }
+};
+
+/* Bit 28 */
+static const value_string pn_io_arproperties_time_aware_system[] = {
+ { 0x00000000, "NonTimeAware" },
+ { 0x00000001, "TimeAware" },
+ { 0, NULL }
+};
+
+/* bit 29 for legacy startup mode*/
+static const value_string pn_io_arproperties_combined_object_container_with_legacy_startupmode[] = {
+ { 0x00000000, "CombinedObjectContainer not used" },
+ { 0x00000001, "Reserved" },
+ { 0, NULL }
+};
+
+/* bit 29 for advanced statup mode*/
+static const value_string pn_io_arproperties_combined_object_container_with_advanced_startupmode[] = {
+ { 0x00000000, "CombinedObjectContainer not used" },
+ { 0x00000001, "Usage of CombinedObjectContainer required" },
+ { 0, NULL }
+};
+
+/* bit 30 */
+static const value_string pn_io_arpropertiesStartupMode[] = {
+ { 0x00000000, "Legacy" },
+ { 0x00000001, "Advanced" },
+ { 0, NULL }
+};
+
+/* bit 31 */
+static const value_string pn_io_arproperties_pull_module_alarm_allowed[] = {
+ { 0x00000000, "AlarmType(=Pull) shall signal pulling of submodule and module" },
+ { 0x00000001, "AlarmType(=Pull) shall signal pulling of submodule" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_RedundancyInfo[] = {
+ { 0x00000000, "Reserved" },
+ { 0x00000001, "The delivering node is the left or below one" },
+ { 0x00000002, "The delivering node is the right or above one" },
+ { 0x00000003, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_iocr_properties_rtclass[] = {
+ { 0x00000000, "reserved" },
+ { 0x00000001, "RT_CLASS_1" },
+ { 0x00000002, "RT_CLASS_2" },
+ { 0x00000003, "RT_CLASS_3" },
+ { 0x00000004, "RT_CLASS_UDP" },
+ /*0x00000005 - 0x00000007 reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_MultipleInterfaceMode_NameOfDevice[] = {
+ { 0x00000000, "PortID of LLDP contains name of port (Default)" },
+ { 0x00000001, "PortID of LLDP contains name of port and NameOfStation" },
+ { 0, NULL }
+};
+
+static const true_false_string tfs_pn_io_sr_properties_BackupAR_with_SRProperties_Mode_0 =
+ { "The device shall deliver valid input data", "The IO controller shall not evaluate the input data." };
+
+static const true_false_string tfs_pn_io_sr_properties_BackupAR_with_SRProperties_Mode_1 =
+ { "The device shall deliver valid input data", "The IO device shall mark the data as invalid using APDU_Status.DataStatus.DataValid == Invalid." };
+
+static const true_false_string tfs_pn_io_sr_properties_Mode =
+ { "Default The IO device shall use APDU_Status.DataStatus.DataValid == Invalid if input data is request as not valid.",
+ "The IO controller do not support APDU_Status.DataStatus.DataValid == Invalid if input data is request as not valid." };
+
+static const true_false_string tfs_pn_io_sr_properties_Reserved1 =
+ { "Legacy mode", "Shall be set to zero for this standard." };
+
+static const value_string pn_io_iocr_properties_media_redundancy[] = {
+ { 0x00000000, "No media redundant frame transfer" },
+ { 0x00000001, "Media redundant frame transfer" },
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_submodule_properties_type[] = {
+ { 0x0000, "no input and no output data" },
+ { 0x0001, "input data" },
+ { 0x0002, "output data" },
+ { 0x0003, "input and output data" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_properties_shared_input[] = {
+ { 0x0000, "IO controller" },
+ { 0x0001, "IO controller shared" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_properties_reduce_input_submodule_data_length[] = {
+ { 0x0000, "Expected" },
+ { 0x0001, "Zero" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_properties_reduce_output_submodule_data_length[] = {
+ { 0x0000, "Expected" },
+ { 0x0001, "Zero" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_properties_discard_ioxs[] = {
+ { 0x0000, "Expected" },
+ { 0x0001, "Zero" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_alarmcr_properties_priority[] = {
+ { 0x0000, "user priority (default)" },
+ { 0x0001, "use only low priority" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_alarmcr_properties_transport[] = {
+ { 0x0000, "RTA_CLASS_1" },
+ { 0x0001, "RTA_CLASS_UDP" },
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_submodule_state_format_indicator[] = {
+ { 0x0000, "Coding uses Detail" },
+ { 0x0001, "Coding uses .IdentInfo, ..." },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_state_add_info[] = {
+ { 0x0000, "None" },
+ { 0x0001, "Takeover not allowed" },
+ /*0x0002 - 0x0007 reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_state_advice[] = {
+ { 0x0000, "No Advice available" },
+ { 0x0001, "Advice available" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_state_maintenance_required[] = {
+ { 0x0000, "No MaintenanceRequired available" },
+ { 0x0001, "MaintenanceRequired available" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_state_maintenance_demanded[] = {
+ { 0x0000, "No MaintenanceDemanded available" },
+ { 0x0001, "MaintenanceDemanded available" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_state_fault[] = {
+ { 0x0000, "No Fault available" },
+ { 0x0001, "Fault available" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_state_ar_info[] = {
+ { 0x0000, "Own" },
+ { 0x0001, "ApplicationReadyPending (ARP)" },
+ { 0x0002, "Superordinated Locked (SO)" },
+ { 0x0003, "Locked By IO Controller (IOC)" },
+ { 0x0004, "Locked By IO Supervisor (IOS)" },
+ /*0x0005 - 0x000F reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_state_ident_info[] = {
+ { 0x0000, "OK" },
+ { 0x0001, "Substitute (SU)" },
+ { 0x0002, "Wrong (WR)" },
+ { 0x0003, "NoSubmodule (NO)" },
+ /*0x0004 - 0x000F reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_submodule_state_detail[] = {
+ { 0x0000, "no submodule" },
+ { 0x0001, "wrong submodule" },
+ { 0x0002, "locked by IO controller" },
+ { 0x0003, "reserved" },
+ { 0x0004, "application ready pending" },
+ { 0x0005, "reserved" },
+ { 0x0006, "reserved" },
+ { 0x0007, "Substitute" },
+ /*0x0008 - 0x7FFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_substitutionmode[] = {
+ { 0x0000, "ZERO" },
+ { 0x0001, "Last value" },
+ { 0x0002, "Replacement value" },
+ /*0x0003 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_index[] = {
+ /*0x0008 - 0x7FFF user specific */
+
+ /* PROFISafe */
+ { 0x0100, "PROFISafe" },
+
+ /* subslot specific */
+ { 0x8000, "ExpectedIdentificationData for one subslot" },
+ { 0x8001, "RealIdentificationData for one subslot" },
+ /*0x8002 - 0x8009 reserved */
+ { 0x800A, "Diagnosis in channel coding for one subslot" },
+ { 0x800B, "Diagnosis in all codings for one subslot" },
+ { 0x800C, "Diagnosis, Maintenance, Qualified and Status for one subslot" },
+ /*0x800D - 0x800F reserved */
+ { 0x8010, "Maintenance required in channel coding for one subslot" },
+ { 0x8011, "Maintenance demanded in channel coding for one subslot" },
+ { 0x8012, "Maintenance required in all codings for one subslot" },
+ { 0x8013, "Maintenance demanded in all codings for one subslot" },
+ /*0x8014 - 0x801D reserved */
+ { 0x801E, "SubstituteValues for one subslot" },
+ /*0x801F reserved */
+ { 0x8020, "PDIRSubframeData for one subslot" },
+ /*0x8021 - 0x8026 reserved */
+ { 0x8027, "PDPortDataRealExtended for one subslot" },
+ { 0x8028, "RecordInputDataObjectElement for one subslot" },
+ { 0x8029, "RecordOutputDataObjectElement for one subslot" },
+ { 0x802A, "PDPortDataReal for one subslot" },
+ { 0x802B, "PDPortDataCheck for one subslot" },
+ { 0x802C, "PDIRData for one subslot" },
+ { 0x802D, "PDSyncData for one subslot with SyncID value 0" },
+ /*0x802E reserved */
+ { 0x802F, "PDPortDataAdjust for one subslot" },
+ { 0x8030, "IsochronousModeData for one subslot" },
+ { 0x8031, "PDTimeData for one subslot" },
+ /*0x8032 - 0x804F reserved */
+ { 0x8050, "PDInterfaceMrpDataReal for one subslot" },
+ { 0x8051, "PDInterfaceMrpDataCheck for one subslot" },
+ { 0x8052, "PDInterfaceMrpDataAdjust for one subslot" },
+ { 0x8053, "PDPortMrpDataAdjust for one subslot" },
+ { 0x8054, "PDPortMrpDataReal for one subslot" },
+ { 0x8055, "PDPortMrpIcDataAdjust for one subslot" },
+ { 0x8056, "PDPortMrpIcDataCheck for one subslot" },
+ { 0x8057, "PDPortMrpIcDataReal for one subslot" },
+ /*0x8058 - 0x805F reserved */
+ { 0x8060, "PDPortFODataReal for one subslot" },
+ { 0x8061, "PDPortFODataCheck for one subslot" },
+ { 0x8062, "PDPortFODataAdjust for one subslot" },
+ { 0x8063, "PDPortSFPDataCheck for one subslot" },
+ /*0x8064 - 0x806F reserved */
+ { 0x8070, "PDNCDataCheck for one subslot" },
+ { 0x8071, "PDInterfaceAdjust for one subslot" },
+ { 0x8072, "PDPortStatistic for one subslot" },
+ /*0x8071 - 0x807F reserved */
+ { 0x8080, "PDInterfaceDataReal" },
+ /*0x8081 - 0x808F reserved */
+ { 0x8090, "PDInterfaceFSUDataAdjust" },
+ /*0x8091 - 0x809F reserved */
+ { 0x80A0, "Profiles covering energy saving - Record_0" },
+ /*0x80A1 - 0x80AE reserved */
+ { 0x80AF, "PE_EntityStatusData for one subslot" },
+ { 0x80B0, "CombinedObjectContainer" },
+ /*0x80B1 - 0x80CE reserved */
+ { 0x80CF, "RS_AdjustObserver" },
+ { 0x80D0, "Profiles covering condition monitoring - Record_0" },
+ /*0x80D1 - 0x80DF reserved */
+ { 0x80F0, "TSNNetworkControlDataReal" },
+ { 0x80F1, "TSNStreamPathData" },
+ { 0x80F2, "TSNSyncTreeData" },
+ { 0x80F3, "TSNUploadNetworkAttributes" },
+ { 0x80F4, "TSNExpectedNetworkAttributes" },
+ { 0x80F5, "TSNNetworkControlDataAdjust" },
+ { 0x80F6, "TSNStreamPathDataReal for stream class High" },
+ { 0x80F7, "TSNStreamPathDataReal for stream class High Redundant" },
+ { 0x80F8, "TSNStreamPathDataReal for stream class Low" },
+ { 0x80F9, "TSNStreamPathDataReal for stream class Low Redundant" },
+ /*0x80FA - 0x80FF reserved for CIM data */
+ /*0x8100 - 0x81FF reserved */
+ { 0x8200, "CIMSNMPAdjust" },
+ /*0x8201 - 0xAFEF reserved */
+ { 0xAFF0, "I&M0" },
+ { 0xAFF1, "I&M1" },
+ { 0xAFF2, "I&M2" },
+ { 0xAFF3, "I&M3" },
+ { 0xAFF4, "I&M4" },
+ { 0xAFF5, "I&M5" },
+ { 0xAFF6, "I&M6" },
+ { 0xAFF7, "I&M7" },
+ { 0xAFF8, "I&M8" },
+ { 0xAFF9, "I&M9" },
+ { 0xAFFA, "I&M10" },
+ { 0xAFFB, "I&M11" },
+ { 0xAFFC, "I&M12" },
+ { 0xAFFD, "I&M13" },
+ { 0xAFFE, "I&M14" },
+ { 0xAFFF, "I&M15" },
+ /*0xB000 - 0xB02D reserved for profiles */
+ { 0xB000, "Sync-Log / RTA SyncID 0 (GSY)" },
+ { 0xB001, "Sync-Log / RTA SyncID 1 (GSY)" },
+ { 0xB002, "reserved for profiles" },
+ { 0xB003, "reserved for profiles" },
+ { 0xB004, "reserved for profiles" },
+ { 0xB005, "reserved for profiles" },
+ { 0xB006, "reserved for profiles" },
+ { 0xB007, "reserved for profiles" },
+ { 0xB008, "reserved for profiles" },
+ { 0xB009, "reserved for profiles" },
+ { 0xB00A, "reserved for profiles" },
+ { 0xB00B, "reserved for profiles" },
+ { 0xB00C, "reserved for profiles" },
+ { 0xB00D, "reserved for profiles" },
+ { 0xB00E, "reserved for profiles" },
+ { 0xB00F, "reserved for profiles" },
+ { 0xB010, "reserved for profiles" },
+ { 0xB011, "reserved for profiles" },
+ { 0xB012, "reserved for profiles" },
+ { 0xB013, "reserved for profiles" },
+ { 0xB014, "reserved for profiles" },
+ { 0xB015, "reserved for profiles" },
+ { 0xB016, "reserved for profiles" },
+ { 0xB017, "reserved for profiles" },
+ { 0xB018, "reserved for profiles" },
+ { 0xB019, "reserved for profiles" },
+ { 0xB01A, "reserved for profiles" },
+ { 0xB01B, "reserved for profiles" },
+ { 0xB01C, "reserved for profiles" },
+ { 0xB01D, "reserved for profiles" },
+ { 0xB01E, "reserved for profiles" },
+ { 0xB01F, "reserved for profiles" },
+ { 0xB020, "reserved for profiles" },
+ { 0xB021, "reserved for profiles" },
+ { 0xB022, "reserved for profiles" },
+ { 0xB023, "reserved for profiles" },
+ { 0xB024, "reserved for profiles" },
+ { 0xB025, "reserved for profiles" },
+ { 0xB026, "reserved for profiles" },
+ { 0xB027, "reserved for profiles" },
+ { 0xB028, "reserved for profiles" },
+ { 0xB029, "reserved for profiles" },
+ { 0xB02A, "reserved for profiles" },
+ { 0xB02B, "reserved for profiles" },
+ { 0xB02C, "reserved for profiles" },
+ { 0xB02D, "reserved for profiles" },
+ /* PROFIDrive */
+ { 0xB02E, "PROFIDrive Parameter Access - Local"},
+ { 0xB02F, "PROFIDrive Parameter Access - Global"},
+
+ /*0xB030 - 0xBFFF reserved for profiles */
+ { 0xB050, "Ext-PLL Control / RTC+RTA SyncID 0 (EDD)" },
+ { 0xB051, "Ext-PLL Control / RTA SyncID 1 (GSY)" },
+
+ { 0xB060, "EDD Trace Unit (EDD" },
+ { 0xB061, "EDD Trace Unit (EDD" },
+
+ { 0xB070, "OHA Info (OHA)" },
+
+
+ /* slot specific */
+ { 0xC000, "ExpectedIdentificationData for one slot" },
+ { 0xC001, "RealIdentificationData for one slot" },
+ /*0xC002 - 0xC009 reserved */
+ { 0xC00A, "Diagnosis in channel coding for one slot" },
+ { 0xC00B, "Diagnosis in all codings for one slot" },
+ { 0xC00C, "Diagnosis, Maintenance, Qualified and Status for one slot" },
+ /*0xC00D - 0xC00F reserved */
+ { 0xC010, "Maintenance required in channel coding for one slot" },
+ { 0xC011, "Maintenance demanded in channel coding for one slot" },
+ { 0xC012, "Maintenance required in all codings for one slot" },
+ { 0xC013, "Maintenance demanded in all codings for one slot" },
+ /*0xC014 - 0xCFFF reserved */
+ /*0xD000 - 0xDFFF reserved for profiles */
+
+ /* AR specific */
+ { 0xE000, "ExpectedIdentificationData for one AR" },
+ { 0xE001, "RealIdentificationData for one AR" },
+ { 0xE002, "ModuleDiffBlock for one AR" },
+ /*0xE003 - 0xE009 reserved */
+ { 0xE00A, "Diagnosis in channel coding for one AR" },
+ { 0xE00B, "Diagnosis in all codings for one AR" },
+ { 0xE00C, "Diagnosis, Maintenance, Qualified and Status for one AR" },
+ /*0xE00D - 0xE00F reserved */
+ { 0xE010, "Maintenance required in channel coding for one AR" },
+ { 0xE011, "Maintenance demanded in channel coding for one AR" },
+ { 0xE012, "Maintenance required in all codings for one AR" },
+ { 0xE013, "Maintenance demanded in all codings for one AR" },
+ /*0xE014 - 0xE02F reserved */
+ { 0xE030, "PE_EntityFilterData for one AR" },
+ { 0xE031, "PE_EntityStatusData for one AR" },
+ /*0xE032 - 0xE03F reserved */
+ { 0xE040, "MultipleWrite" },
+ { 0xE041, "ApplicationReadyBlock" },
+ /*0xE042 - 0xE04F reserved */
+ { 0xE050, "ARFSUDataAdjust data for one AR" },
+ /*0xE051 - 0xE05F reserved */
+ { 0xE060, "RS_GetEvent (using RecordDataRead service)" },
+ { 0xE061, "RS_AckEvent (using RecordDataWrite service)" },
+ /*0xEC00 - 0xEFFF reserved */
+
+ /* API specific */
+ { 0xF000, "RealIdentificationData for one API" },
+ /*0xF001 - 0xF009 reserved */
+ { 0xF00A, "Diagnosis in channel coding for one API" },
+ { 0xF00B, "Diagnosis in all codings for one API" },
+ { 0xF00C, "Diagnosis, Maintenance, Qualified and Status for one API" },
+ /*0xF00D - 0xF00F reserved */
+ { 0xF010, "Maintenance required in channel coding for one API" },
+ { 0xF011, "Maintenance demanded in channel coding for one API" },
+ { 0xF012, "Maintenance required in all codings for one API" },
+ { 0xF013, "Maintenance demanded in all codings for one API" },
+ /*0xF014 - 0xF01F reserved */
+ { 0xF020, "ARData for one API" },
+ /*0xF021 - 0xF3FF reserved */
+ /*0xF400 - 0xF7FF reserved */
+
+ /* device specific */
+ /*0xF800 - 0xF80B reserved */
+ { 0xF80C, "Diagnosis, Maintenance, Qualified and Status for one device" },
+ /*0xF80D - 0xF81F reserved */
+ { 0xF820, "ARData" },
+ { 0xF821, "APIData" },
+ /*0xF822 - 0xF82F reserved */
+ { 0xF830, "LogData" },
+ { 0xF831, "PDevData" },
+ /*0xF832 - 0xF83F reserved */
+ { 0xF840, "I&M0FilterData" },
+ { 0xF841, "PDRealData" },
+ { 0xF842, "PDExpectedData" },
+ /*0xF843 - 0xF84F reserved */
+ { 0xF850, "AutoConfiguration" },
+ { 0xF860, "GSD upload using UploadBLOBQuery and UploadBLOB" },
+ { 0xF870, "PE_EntityFilterData" },
+ { 0xF871, "PE_EntityStatusData" },
+ { 0xF880, "AssetManagementData - contains all or first chunk of complete assets" },
+ { 0xF881, "AssetManagementData - second chunk" },
+ { 0xF882, "AssetManagementData - third chunk" },
+ { 0xF883, "AssetManagementData - fourth chunk" },
+ { 0xF884, "AssetManagementData - fifth chunk" },
+ { 0xF885, "AssetManagementData - sixth chunk" },
+ { 0xF886, "AssetManagementData - seventh chunk" },
+ { 0xF887, "AssetManagementData - eighth chunk" },
+ { 0xF888, "AssetManagementData - ninth chunk" },
+ { 0xF889, "AssetManagementData - tenth chunk" },
+ { 0xF8F0, "Stream Add using TSNAddStreamReq and TSNAddStreamRsp" },
+ { 0xF8F1, "PDRsiInstances" },
+ { 0xF8F2, "Stream Remove using TSNRemoveStreamReq and TSNRemoveStreamRsp" },
+ { 0xF8F3, "Stream Renew using TSNRenewStreamReq and TSNRenewStreamRsp" },
+ { 0xFBFF, "Trigger index for RPC connection monitoring" },
+ /*0xFC00 - 0xFFFF reserved for profiles */
+ { 0, NULL }
+};
+
+static const value_string pn_io_user_structure_identifier[] = {
+ /*0x0000 - 0x7FFF manufacturer specific */
+ { 0x8000, "ChannelDiagnosis" },
+ { 0x8001, "Multiple" },
+ { 0x8002, "ExtChannelDiagnosis" },
+ { 0x8003, "QualifiedChannelDiagnosis" },
+ /*0x8004 - 0x80FF reserved */
+ { 0x8100, "Maintenance" },
+ /*0x8101 - 0x8FFF reserved except 8200, 8201, 8300, 8301, 8302, 8303, 8310, 8320 */
+ { 0x8200, "Upload&Retrieval" },
+ { 0x8201, "iParameter" },
+ { 0x8300, "Reporting system RS_LowWatermark" },
+ { 0x8301, "Reporting system RS_Timeout" },
+ { 0x8302, "Reporting system RS_Overflow" },
+ { 0x8303, "Reporting system RS_Event" },
+ { 0x8310, "PE_EnergySavingStatus" },
+ { 0x8320, "Channel related Process Alarm reasons" },
+ /*0x9000 - 0x9FFF reserved for profiles */
+ /*0xA000 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_channel_error_type[] = {
+ { 0x0000, "reserved" },
+ { 0x0001, "short circuit" },
+ { 0x0002, "Undervoltage" },
+ { 0x0003, "Overvoltage" },
+ { 0x0004, "Overload" },
+ { 0x0005, "Overtemperature" },
+ { 0x0006, "Wire break" },
+ { 0x0007, "Upper limit value exceeded" },
+ { 0x0008, "Lower limit value exceeded" },
+ { 0x0009, "Error" },
+ { 0x000A, "Simulation active" },
+ /*0x000B - 0x000E reserved */
+ { 0x000F, "Parameter missing" },
+ { 0x0010, "Parameterization fault" },
+ { 0x0011, "Power supply fault" },
+ { 0x0012, "Fuse blown / open" },
+ { 0x0013, "Manufacturer specific" },
+ { 0x0014, "Ground fault" },
+ { 0x0015, "Reference point lost" },
+ { 0x0016, "Process event lost / sampling error" },
+ { 0x0017, "Threshold warning" },
+ { 0x0018, "Output disabled" },
+ { 0x0019, "FunctionalSafety event" },
+ { 0x001A, "External fault" },
+ /*0x001B - 0x001F manufacturer specific */
+ { 0x001F, "Temporary fault" },
+ /*0x0020 - 0x00FF reserved for common profiles */
+ { 0x0040, "Mismatch of safety destination address" },
+ { 0x0041, "Safety destination address not valid" },
+ { 0x0042, "Safety source address not valid" },
+ { 0x0043, "Safety watchdog time value is 0ms" },
+ { 0x0044, "Parameter F_SIL exceeds SIL of specific application" },
+ { 0x0045, "Parameter F_CRC_Length does not match generated values" },
+ { 0x0046, "Version of F-Parameter set incorrect" },
+ { 0x0047, "Data inconsistent in received F-Parameter block (CRC1 error)" },
+ { 0x0048, "Device specific or unspecific diagnosis information, see manual" },
+ { 0x0049, "Save iParameter watchdog time exceeded" },
+ { 0x004A, "Restore iParameter watchdog time exceeded" },
+ { 0x004B, "Inconsistent iParameters (iParCRC error)" },
+ { 0x004C, "F_Block_ID not supported" },
+ { 0x004D, "Transmission error: data inconsistent (CRC2 error)" },
+ { 0x004E, "Transmission error: timeout" },
+ { 0x004F, "Acknowledge needed to enable the channel(s)" },
+ /*0x0100 - 0x7FFF manufacturer specific */
+ { 0x8000, "Data transmission impossible" },
+ { 0x8001, "Remote mismatch" },
+ { 0x8002, "Media redundancy mismatch - Ring" },
+ { 0x8003, "Sync mismatch" },
+ { 0x8004, "IsochronousMode mismatch" },
+ { 0x8005, "Multicast CR mismatch" },
+ { 0x8006, "reserved" },
+ { 0x8007, "Fiber optic mismatch" },
+ { 0x8008, "Network component function mismatch" },
+ { 0x8009, "Time mismatch" },
+ /* added values for IEC version 2.3: */
+ { 0x800A, "Dynamic frame packing function mismatch" },
+ { 0x800B, "Media redundancy with planned duplication mismatch"},
+ { 0x800C, "System redundancy mismatch"},
+ { 0x800D, "Multiple interface mismatch"},
+ { 0x8010, "Power failure over Single Pair Ethernet"},
+ /* ends */
+ /*0x800D - 0x8FFF reserved */
+ /*0x9000 - 0x9FFF reserved for profile */
+ /*0x9000 - 0x902F NE107 common (PA Profile 4.02) */
+ { 0x9000, "Sensor element exciter faulty" },
+ { 0x9001, "Error in evaluation electronics" },
+ { 0x9002, "Error in internal energy supply" },
+ { 0x9003, "Error in sensor element" },
+ { 0x9004, "Error in actuator element" },
+ { 0x9005, "Faulty installation e.g. dead space" },
+ { 0x9006, "Parameter setting error" },
+ { 0x9008, "Overloading" },
+ { 0x9009, "Wrong polarity of aux power" },
+ { 0x900A, "Maximum line length exceeded" },
+ { 0x900B, "Corrosion/abrasion by medium" },
+ { 0x900C, "Fouling on sensor element" },
+ { 0x900D, "Auxil medium missing or insufficient" },
+ { 0x900E, "Wear reserve used up (operation)" },
+ { 0x900F, "Wear reserve used up (wear)" },
+ { 0x9010, "Error in peripherals" },
+ { 0x9011, "Electromag interference too high" },
+ { 0x9012, "Temperature of medium too high" },
+ { 0x9013, "Ambient temperature too high" },
+ { 0x9014, "Vibration/Impact load too high" },
+ { 0x9015, "Auxiliary power range off-spec" },
+ { 0x9016, "Auxiliary medium missing" },
+ { 0x9017, "Excessive temperature shock" },
+ { 0x9018, "Deviation from measurement" },
+ { 0x9019, "Humidity in electronics area" },
+ { 0x901A, "Medium in electronics area" },
+ { 0x901B, "Mechanical damage" },
+ { 0x901C, "Communication error" },
+ { 0x901D, "Foreign material in electro area" },
+ /*0x9030 - 0x906F NE107 contact thermometer (PA Profile 4.02) */
+ { 0x9030, "Immersion depth too limited" },
+ { 0x9031, "Unequate medium around sensor" },
+ { 0x9032, "Temp distrib not representative" },
+ { 0x9033, "Inadequate thermal contact" },
+ { 0x9034, "Sensor close to heat source/sink" },
+ { 0x9035, "External temperature influence" },
+ { 0x9036, "Insufficient thermocoupling" },
+ { 0x9037, "Thermocoupling too high" },
+ { 0x9038, "Friction heat by flowing gases" },
+ { 0x9039, "Thermalcapac of sensor too high" },
+ { 0x903A, "Deposits" },
+ { 0x903B, "Systemrelated resonant vibration" },
+ { 0x903C, "Resonantvibrat excited by flow" },
+ { 0x903D, "Leakage" },
+ { 0x903E, "Abrasion" },
+ { 0x903F, "Corrosion" },
+ { 0x9040, "Flow approach speed too high" },
+ { 0x9041, "Insulation to ground too low" },
+ { 0x9042, "Insulation betw. lines too low" },
+ { 0x9043, "Parasitic thermal elements" },
+ { 0x9044, "Parasitic galvanic elements" },
+ { 0x9045, "Short circuit" },
+ { 0x9046, "Shorted coil and break" },
+ { 0x9047, "Line/contact resistance too high" },
+ { 0x9048, "Compression spring failure" },
+ { 0x9049, "Drift of sensor charact curve" },
+ { 0x904A, "Insuff contact of meas insert" },
+ { 0x904B, "Meas insert mechanical seized" },
+ { 0x904C, "Measuring insert in thermowell" },
+ { 0x904D, "Measuring insert too short" },
+ { 0x904E, "Resistance wire abrasion" },
+ { 0x904F, "Mechanic stress character curve" },
+ { 0x9050, "Thermal stress character curve" },
+ { 0x9051, "Intrinsic heating too severe" },
+ { 0x9052, "EMI on measuring circuit" },
+ { 0x9053, "Faulty linearisation" },
+ { 0x9054, "Incorrect sensor position" },
+ { 0x9055, "Faulty comparative point temp" },
+ { 0x9056, "Faulty compar of line resistance" },
+ { 0x9057, "Unsymmet supply line resistance" },
+ { 0x9058, "Wrong material of compens line" },
+ { 0x9059, "Damage to supply lines" },
+ { 0x905A, "Capacitive feedback" },
+ { 0x905B, "Potential transfer" },
+ { 0x905C, "Potential differences exceeded" },
+ { 0x905D, "Impermiss mix of wire systems" },
+ { 0x905E, "Reverse polarity of lines" },
+ { 0x905F, "Reverse polarity of lines" },
+ /*0x9070 - 0x90A7 NE107 pressure (PA Profile 4.02) */
+ { 0x9070, "Pressure peaks outside range" },
+ { 0x9071, "Deposits on the seal diaphragm" },
+ { 0x9072, "Characteristic curve change" },
+ { 0x9073, "Inc. measuring err. (turn down)" },
+ { 0x9074, "Wear on the seal diaphragm" },
+ { 0x9075, "Process seal at flush diaphragm" },
+ { 0x9076, "Offset error due to inst. pos." },
+ { 0x9077, "Seal diaphragm deformation" },
+ { 0x9078, "Hydrogen penetration" },
+ { 0x9079, "Mean value deviation" },
+ { 0x907A, "Pressure sensor system leakage" },
+ { 0x907B, "Hydrostatic offset" },
+ { 0x907C, "Gas seepage from pressure sensor" },
+ { 0x907D, "Add. measuring err. due to temp." },
+ { 0x907E, "Delta T in capillary tubing" },
+ { 0x907F, "Increase in compensation times" },
+ { 0x9080, "Oleic acid leak" },
+ { 0x9081, "Pulse lines blocked" },
+ { 0x9082, "Gas inclusion in liquid medium" },
+ { 0x9083, "Delta T in pulse lines" },
+ { 0x9084, "Liquid inclusion in gas" },
+ { 0x9088, "Sedimentation on sensor" },
+ { 0x9089, "Change of density" },
+ { 0x908A, "Wrong height / wrong adjustment" },
+ { 0x908B, "Clogged membrane" },
+ { 0x908C, "Error with pulse line" },
+ { 0x908D, "Internal tank pressure influence" },
+ { 0x908E, "Influence of temperature" },
+ { 0x908F, "Hydrogen diffusion" },
+ { 0x9090, "Absence of bubble gas" },
+ { 0x9091, "Air-bubble feed line blocked" },
+ { 0x9092, "Wear and tear of diaphragm" },
+ { 0x9093, "Gas seepage" },
+ { 0x9094, "Pressure rise at rel. of bubbles" },
+ { 0x9095, "Pressure sensor overload" },
+ { 0x9096, "Flow rate of bubble gas too high" },
+ /*0x90F8 - 0x910F NE107 coriolis (PA Profile 4.02) */
+ { 0x90F8, "Gas bubbles in the liquid" },
+ { 0x90F9, "Fouling, clogging" },
+ { 0x90FA, "Erosion, corrosion" },
+ { 0x90FB, "Faulty mounting" },
+ { 0x90FC, "Asymmetry of measuring tubes" },
+ { 0x90FD, "External vibrations" },
+ { 0x90FE, "Pulsating flow" },
+ { 0x90FF, "Incomplete filling" },
+ /*0x9110 - 0x9127 NE107 EMF (PA Profile 4.02) */
+ { 0x9110, "Gas bubbles in the liquid" },
+ { 0x9111, "Corrosion of electrodes" },
+ { 0x9112, "Electrical conductivity too low" },
+ { 0x9113, "Liner damage" },
+ { 0x9114, "Electrode fouling" },
+ { 0x9115, "External magnetic fields" },
+ { 0x9116, "Electrode short circuit" },
+ { 0x9117, "Incomplete filling" },
+ /*0x9128 - 0x913F NE107 thermal mass (PA Profile 4.02) */
+ /* empty */
+ /*0x9140 - 0x915F NE107 ultrasonic (PA Profile 4.02) */
+ { 0x9140, "Particle inclusions Check process" },
+ { 0x9141, "Gas bubbles in the liquid" },
+ { 0x9142, "Body fouling" },
+ { 0x9143, "External ultrasonic waves" },
+ { 0x9144, "Sensor fouling" },
+ { 0x9145, "Erosion" },
+ { 0x9146, "Faulty mounting (clamp on)" },
+ { 0x9147, "Pulsating flow" },
+ { 0x9148, "Sound conductivity" },
+ { 0x9149, "Signal lost due to overrange" },
+ { 0x914A, "Flow profile disturbance" },
+ { 0x914B, "Incomplete filling" },
+ /*0x9160 - 0x9177 NE107 variable area (PA Profile 4.02) */
+ { 0x9160, "Blocked float" },
+ { 0x9161, "Fouling" },
+ { 0x9162, "Erosion, corrosion" },
+ { 0x9163, "Gas bubbles in the liquid" },
+ { 0x9164, "Pulsating flow" },
+ { 0x9165, "External magnetic fields" },
+ /*0x9178 - 0x9197 NE107 vortex (PA Profile 4.02) */
+ { 0x9178, "Gas bubbles in the liquid" },
+ { 0x9179, "External vibrations" },
+ { 0x917A, "Pulsating flow" },
+ { 0x917B, "Two phase flow" },
+ { 0x917C, "Cavitation in device" },
+ { 0x917D, "Out of linear range" },
+ { 0x917E, "Sensor fouling" },
+ { 0x917F, "Solid particles" },
+ { 0x9180, "Flow profile disturbance" },
+ { 0x9181, "Incomplete filling" },
+ { 0x9182, "Bluff body fouling" },
+ /*0x9198 - 0x91B7 NE107 buoyancy (PA Profile 4.02) */
+ { 0x9198, "Gas density change above liquid" },
+ { 0x9199, "Vibration/strokes from outside" },
+ { 0x919A, "Displacer partly inside compartm" },
+ { 0x919B, "Displacer too heavy/too light" },
+ { 0x919C, "Density change or displac config" },
+ { 0x919D, "Sticking of torque or spring" },
+ { 0x919E, "Displacer swinging freedomly" },
+ { 0x919F, "Displac mounting faulty" },
+ { 0x91A0, "Displacer blocked or bended" },
+ { 0x91A1, "Displacer too light, corrosion" },
+ { 0x91A2, "Displacer leakage" },
+ { 0x91A3, "Force sensor broken" },
+ /*0x91B8 - 0x91FF NE107 radar (PA Profile 4.02) */
+ { 0x91B8, "Change of running time, encrust?" },
+ { 0x91B9, "False echoes, encrustation?" },
+ { 0x91BA, "Wrong/no indication, foam" },
+ { 0x91BB, "Poor reflection" },
+ { 0x91BC, "Problems with tank wall" },
+ { 0x91BD, "Surge tube or vent blocked" },
+ { 0x91BE, "Nozzle too long/high" },
+ { 0x91BF, "No metallic reflecting surface" },
+ { 0x91C0, "Blocking distance underrun" },
+ { 0x91C1, "Mechanical overloading of probe" },
+ { 0x91C2, "Probe lost or torn off" },
+ { 0x91C3, "Overload by external power" },
+ { 0x91C4, "Product or moisture in coupler" },
+ { 0x91C5, "Change of microwave speed" },
+ { 0x91C6, "Corr,abras, coating detachment" },
+ { 0x91C7, "Probe in filling flow" },
+ { 0x91D8, "No clear interface Emulsion?" },
+ { 0x91D9, "Wrong indication param setting" },
+ { 0x91DA, "Diff dielecon too small" },
+ { 0x91DB, "More than one interface" },
+ { 0x91DC, "First phase thickness too small" },
+ { 0x91E0, "Attenuation due to deposits" },
+ { 0x91E1, "False echoes due to deposits" },
+ { 0x91E2, "Corrosion surge tube (inside)" },
+ { 0x91E3, "Impurity in wave coupler area" },
+ { 0x91E4, "Antenna immersed in product" },
+ { 0x91E5, "Wrong signal due to foam" },
+ { 0x91E6, "Strong signal attenuation" },
+ { 0x91E7, "Shift of radar signal speed" },
+ { 0x91E8, "Reflection" },
+ { 0x91E9, "False interpretation of the echo" },
+ { 0x91EA, "Bad polarization of the signal" },
+ { 0x91EB, "Surge tube or vent blocked" },
+ { 0x91EC, "Nozzle too long for antenna" },
+ { 0x91ED, "Wall clearance, not vertical" },
+ { 0x91EE, "Corrosion on antenna" },
+ { 0x91EF, "Attenuation due to fog or dust" },
+ { 0x91F0, "Antenna signal blocked" },
+ { 0x91F1, "Blocking distance under-run" },
+ { 0x91F2, "Echo too strong (overmodulation)" },
+ /*0x9208 - 0x9257 NE107 electro (PA Profile 4.02) */
+ { 0x9208, "Faulty torque monitoring" },
+ { 0x9209, "Worn gear/spindle" },
+ { 0x920A, "Drive torque off-spec" },
+ { 0x920B, "Device temperature too high" },
+ { 0x920C, "Faulty limit position monitoring" },
+ { 0x920D, "Motor overload" },
+ { 0x920E, "Oil quality off-spec" },
+ { 0x920F, "Oil loss" },
+ { 0x9210, "Blocked drive" },
+ { 0x9211, "Off-spec seat/plug leakage" },
+ { 0x9212, "Off-spec spindle/shaft seal leak" },
+ { 0x9213, "Alteration and wear on spindle" },
+ { 0x9214, "Altered friction" },
+ { 0x9215, "Wear in the valve" },
+ { 0x9216, "Blocked valve" },
+ { 0x9217, "Change in valve move performance" },
+ { 0x9218, "Changed breakaway moment" },
+ { 0x9219, "Spindle deformation" },
+ { 0x921A, "Plug torn off" },
+ { 0x921B, "Off-spec valve temperature" },
+ { 0x921C, "Off-spec characteristic line" },
+ { 0x921E, "Incorrect position sensing" },
+ { 0x921F, "Input signal off-spec" },
+ { 0x9220, "Vibration off-spec" },
+ { 0x9221, "Temp in positioner too high/low" },
+ { 0x9222, "Moisture in positioner" },
+ { 0x9223, "Additional IO module defect" },
+ { 0x9224, "Signal without end position" },
+ { 0x9225, "No signal in end position" },
+ { 0x9226, "Control loop oscillation" },
+ { 0x9227, "Hysteresis" },
+ { 0x9228, "Changed friction" },
+ { 0x9229, "Backlash between drive and valve" },
+ { 0x922A, "Persistent deviation of control" },
+ { 0x922B, "Inadmissible dynamic stress" },
+ { 0x922C, "Faulty mounting" },
+ { 0x922D, "Faulty mount positioner to motor" },
+ { 0x922E, "Leak in piping" },
+ { 0x922F, "Insufficient drive power" },
+ { 0x9231, "Operator error during operation" },
+ { 0x9232, "Inadmissible static stress" },
+ { 0x9233, "Recording of pers. control dev." },
+ { 0x9234, "Parameter plausibility check" },
+ { 0x9235, "Status report on operating mode" },
+ { 0x9236, "Histogram for valve positions" },
+ { 0x9237, "Zero point and endpoint shift" },
+ { 0x9238, "Running time monitoring" },
+ { 0x9239, "Evaluation of internal signals" },
+ { 0x923A, "Operating hours counter" },
+ { 0x923B, "Pressure-displacement diagram" },
+ { 0x923C, "Total valve travel" },
+ { 0x923D, "Step response diagnostics" },
+ { 0x923E, "Internal temperature monitoring" },
+ { 0x923F, "Counter for direction changes" },
+ { 0x9240, "Operating archive" },
+ { 0x9241, "Report archive" },
+ { 0x9242, "Status reports on access control" },
+ { 0x9243, "Cavitation / flashing" },
+ { 0x9244, "Partial stroke test" },
+ { 0x9245, "P dif measurement across valve" },
+ { 0x9246, "Noise level measurement" },
+ /*0x9258 - 0x92A7 NE107 electro pneumatic (PA Profile 4.02) */
+ { 0x9258, "Minor drive leakage" },
+ { 0x9259, "High friction" },
+ { 0x925A, "Feed air pressure off-spec" },
+ { 0x925B, "Vent blockage" },
+ { 0x925C, "Diaphragm damage" },
+ { 0x925D, "Broken spring" },
+ { 0x925E, "Moist air in spring chamber" },
+ { 0x925F, "Blocked drive" },
+ { 0x9260, "Drive leakage too big" },
+ { 0x9261, "Off-spec seat/plug leakage" },
+ { 0x9262, "Off-spec spindle/shaft seal leak" },
+ { 0x9263, "Alteration and wear on spindle" },
+ { 0x9264, "Altered friction" },
+ { 0x9265, "Wear in the valve" },
+ { 0x9266, "Blocked valve" },
+ { 0x9267, "Change in valve move performance" },
+ { 0x9268, "Changed breakaway moment" },
+ { 0x9269, "Spindle deformation" },
+ { 0x926A, "Plug torn off" },
+ { 0x926B, "Off-spec valve temperature" },
+ { 0x926C, "Off-spec characteristic line" },
+ { 0x926D, "Fault in the pneumatic unit" },
+ { 0x926E, "Incorrect position sensing" },
+ { 0x926F, "Input signal off-spec" },
+ { 0x9270, "Vibration off-spec" },
+ { 0x9271, "Temp in positioner too high/low" },
+ { 0x9272, "Moisture in positioner" },
+ { 0x9273, "Additional IO module defect" },
+ { 0x9274, "Signal without end position" },
+ { 0x9275, "No signal in end position" },
+ { 0x9276, "Control loop oscillation" },
+ { 0x9277, "Hysteresis" },
+ { 0x9278, "Changed friction" },
+ { 0x9279, "Backlash between drive and valve" },
+ { 0x927A, "Persistent deviation of control" },
+ { 0x927B, "Inadmissible dynamic stress" },
+ { 0x927C, "Faulty mounting" },
+ { 0x927D, "Faulty mount positioner to drive" },
+ { 0x927E, "Leak in piping" },
+ { 0x927F, "Insufficient drive power" },
+ { 0x9280, "Quality of feed air off-spec" },
+ { 0x9281, "Operator error during operation" },
+ { 0x9282, "Inadmissible static stress" },
+ { 0x9283, "Recording of pers. control dev." },
+ { 0x9284, "Parameter plausibility check" },
+ { 0x9285, "Status report on operating mode" },
+ { 0x9286, "Histogram for valve positions" },
+ { 0x9287, "Zero point and endpoint shift" },
+ { 0x9288, "Running time monitoring" },
+ { 0x9289, "Evaluation of internal signals" },
+ { 0x928A, "Operating hours counter" },
+ { 0x928B, "Pressure-displacement diagram" },
+ { 0x928C, "Total valve travel" },
+ { 0x928D, "Step response diagnostics" },
+ { 0x928E, "Internal temperature monitoring" },
+ { 0x928F, "Counter for direction changes" },
+ { 0x9290, "Operating archive" },
+ { 0x9291, "Report archive" },
+ { 0x9292, "Status reports on access control" },
+ { 0x9293, "Cavitation / flashing" },
+ { 0x9294, "Partial stroke test" },
+ { 0x9295, "P dif measurement across valve" },
+ { 0x9296, "Noise level measurement" },
+ /*0x92A8 - 0x92BF NE107 sol valve (PA Profile 4.02) */
+ { 0x92A8, "Failure to reach safe position" },
+ { 0x92A9, "Failure to reach operat position" },
+ { 0x92AA, "High temperature in coil" },
+ { 0x92AB, "Moisture, humidity" },
+ { 0x92AC, "Signal outside of endposition" },
+ { 0x92AD, "No signal at endposition" },
+ /*0x92C0 - 0x92DF Physical block (PA Profile 4.02) */
+ { 0x92CD, "Maintenance" },
+ { 0x92D0, "Maintenance alarm" },
+ { 0x92D1, "Maintenance demanded" },
+ { 0x92D2, "Function check" },
+ { 0x92D3, "Out of spec." },
+ { 0x92D4, "Update event" },
+ /*0xA000 - 0xFFFF reserved */
+ { 0, NULL }
+};
+ /* ExtChannelErrorType for ChannelErrorType 0 - 0x7FFF */
+
+static const value_string pn_io_ext_channel_error_type0[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "Accumulative Info"},
+ /* 0x8001 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+
+ /* ExtChannelErrorType for ChannelErrorType "Data transmission impossible" */
+static const value_string pn_io_ext_channel_error_type0x8000[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "Link State mismatch - Link down"},
+ { 0x8001, "MAUType mismatch"},
+ { 0x8002, "Line Delay mismatch"},
+ /* 0x8003 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Remote mismatch" */
+static const value_string pn_io_ext_channel_error_type0x8001[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "Peer name of station mismatch"},
+ { 0x8001, "Peer name of port mismatch"},
+ { 0x8002, "Peer RT_CLASS_3 mismatch a"},
+ { 0x8003, "Peer MAUType mismatch"},
+ { 0x8004, "Peer MRP domain mismatch"},
+ { 0x8005, "No peer detected"},
+ { 0x8006, "Reserved"},
+ { 0x8007, "Peer Line Delay mismatch"},
+ { 0x8008, "Peer PTCP mismatch b"},
+ { 0x8009, "Peer Preamble Length mismatch"},
+ { 0x800A, "Peer Fragmentation mismatch"},
+ { 0x800B, "Peer MRP Interconnection domain mismatch"},
+ /* 0x800C - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Media redundancy mismatch" 0x8002 */
+static const value_string pn_io_ext_channel_error_type0x8002[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "Manager role fail MRP-instance 1"},
+ { 0x8001, "MRP-instance 1 ring open"},
+ { 0x8002, "Reserved"},
+ { 0x8003, "Multiple manager MRP-instance 1"},
+ { 0x8010, "Manager role fail MRP-instance 2"},
+ { 0x8011, "MRP-instance 2 ring open"},
+ { 0x8012, "Reserved"},
+ { 0x8013, "Multiple manager MRP-instance 2"},
+ { 0x8020, "Manager role fail MRP-instance 3"},
+ { 0x8021, "MRP-instance 3 ring open"},
+ { 0x8023, "Multiple manager MRP-instance 3"},
+ { 0x8030, "Manager role fail MRP-instance 4"},
+ { 0x8031, "MRP-instance 4 ring open"},
+ { 0x8033, "Multiple manager MRP-instance 4"},
+ { 0x8040, "Manager role fail MRP-instance 5"},
+ { 0x8041, "MRP-instance 5 ring open"},
+ { 0x8043, "Multiple manager MRP-instance 5"},
+ { 0x8050, "Manager role fail MRP-instance 6"},
+ { 0x8051, "MRP-instance 6 ring open"},
+ { 0x8053, "Multiple manager MRP-instance 6"},
+ { 0x8060, "Manager role fail MRP-instance 7"},
+ { 0x8061, "MRP-instance 7 ring open"},
+ { 0x8063, "Multiple manager MRP-instance 7"},
+ { 0x8070, "Manager role fail MRP-instance 8"},
+ { 0x8071, "MRP-instance 8 ring open"},
+ { 0x8073, "Multiple manager MRP-instance 8"},
+ { 0x8080, "Manager role fail MRP-instance 9"},
+ { 0x8081, "MRP-instance 9 ring open"},
+ { 0x8083, "Multiple manager MRP-instance 9"},
+ { 0x8090, "Manager role fail MRP-instance 10"},
+ { 0x8091, "MRP-instance 10 ring open"},
+ { 0x8093, "Multiple manager MRP-instance 10"},
+ { 0x80A0, "Manager role fail MRP-instance 11"},
+ { 0x80A1, "MRP-instance 11 ring open"},
+ { 0x80A3, "Multiple manager MRP-instance 11"},
+ { 0x80B0, "Manager role fail MRP-instance 12"},
+ { 0x80B1, "MRP-instance 12 ring open"},
+ { 0x80B3, "Multiple manager MRP-instance 12"},
+ { 0x80C0, "Manager role fail MRP-instance 13"},
+ { 0x80C1, "MRP-instance 13 ring open"},
+ { 0x80C3, "Multiple manager MRP-instance 13"},
+ { 0x80D0, "Manager role fail MRP-instance 14"},
+ { 0x80D1, "MRP-instance 14 ring open"},
+ { 0x80D3, "Multiple manager MRP-instance 14"},
+ { 0x80E0, "Manager role fail MRP-instance 15"},
+ { 0x80E1, "MRP-instance 15 ring open"},
+ { 0x80E3, "Multiple manager MRP-instance 15"},
+ { 0x80F0, "Manager role fail MRP-instance 16"},
+ { 0x80F1, "MRP-instance 16 ring open"},
+ { 0x80F3, "Multiple manager MRP-instance 16"},
+ /* 0x8004 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Sync mismatch" and for ChannelErrorType "Time mismatch" 0x8003 and 0x8009*/
+static const value_string pn_io_ext_channel_error_type0x8003[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "No sync message received"},
+ { 0x8001, "- 0x8002 Reserved"},
+ { 0x8003, "Jitter out of boundary"},
+ /* 0x8004 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /*ExtChannelErrorType for ChannelErrorType "Isochronous mode mismatch" 0x8004 */
+static const value_string pn_io_ext_channel_error_type0x8004[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "Output Time Failure - Output update missing or out of order"},
+ { 0x8001, "Input Time Failure"},
+ { 0x8002, "Master Life Sign Failure - Error in MLS update detected"},
+ /* 0x8003 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Multicast CR mismatch" 0x8005 */
+static const value_string pn_io_ext_channel_error_type0x8005[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "Multicast Consumer CR timed out"},
+ { 0x8001, "Address resolution failed"},
+ /* 0x8002 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Fiber optic mismatch" 0x8007*/
+static const value_string pn_io_ext_channel_error_type0x8007[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "Power Budget"},
+ { 0x8001, "SFP - Temperature threshold violation (High)"},
+ { 0x8002, "SFP - TX Bias threshold violation (High)"},
+ { 0x8003, "SFP - TX Bias threshold violation (Low)"},
+ { 0x8004, "SFP - TX Power threshold violation (High)"},
+ { 0x8005, "SFP - TX Power threshold violation (Low)"},
+ { 0x8006, "SFP - RX Power threshold violation (High)"},
+ { 0x8007, "SFP - RX Power threshold violation (Low)"},
+ { 0x8008, "SFP - TX Fault State indication"},
+ { 0x8009, "SFP - RX Loss State indication"},
+ /* 0x800A - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Network component function mismatch" 0x8008 */
+static const value_string pn_io_ext_channel_error_type0x8008[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "Frame dropped - no resource"},
+ /* 0x8001 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Dynamic Frame Packing function mismatch" 0x800A */
+static const value_string pn_io_ext_channel_error_type0x800A[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ /* 0x8000 - 0x80FF Reserved */
+ { 0x8100, "Frame late error for FrameID (0x0100)"},
+ /* 0x8101 + 0x8FFE See Equation (56) */
+ { 0x8FFF, "Frame late error for FrameID (0x0FFF)"},
+ /* 0x8001 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Media redundancy with planned duplication mismatch" 0x800B */
+static const value_string pn_io_ext_channel_error_type0x800B[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ /* 0x8000 - 0x86FF Reserved */
+ { 0x8700, "MRPD duplication void for FrameID (0x0700)"},
+ /* 0x8701 + 0x8FFE See Equation (57) */
+ { 0x8FFF, "MRPD duplication void for FrameID (0x0FFF)"},
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "System redundancy mismatch" 0x800C */
+static const value_string pn_io_ext_channel_error_type0x800C[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "System redundancy event"},
+ /* 0x8001 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+ /* ExtChannelErrorType for ChannelErrorType "Power failure over Single Pair Ethernet" 0x8010 */
+static const value_string pn_io_ext_channel_error_type0x8010[] = {
+ /* 0x0000 Reserved */
+ /* 0x0001 - 0x7FFF Manufacturer specific */
+ { 0x8000, "SPE power supply - Short circuit"},
+ { 0x8001, "SPE power supply - Open circuit"},
+ { 0x8002, "SPE power supply - Voltage level"},
+ { 0x8003, "SPE power supply - Current level"},
+ /* 0x8004 - 0x8FFF Reserved */
+ /* 0x9000 - 0x9FFF Reserved for profiles */
+ /* 0xA000 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+/* QualifiedChannelQualifier */
+static const value_string pn_io_qualified_channel_qualifier[] = {
+ {0x00000001, "Reserved"},
+ {0x00000002, "Reserved"},
+ {0x00000004, "Reserved"},
+ {0x00000008, "Qualifier_3 (Advice)"},
+ {0x00000010, "Qualifier_4 (Advice, PA: UpdateEvent)"},
+ {0x00000020, "Qualifier_5 (Advice, PA: OutOfSpecification)"},
+ {0x00000040, "Qualifier_6 (Advice)"},
+ {0x00000080, "Qualifier_7 (MaintenanceRequired)"},
+ {0x00000100, "Qualifier_8 (MaintenanceRequired)"},
+ {0x00000200, "Qualifier_9 (MaintenanceRequired)"},
+ {0x00000400, "Qualifier_10 (MaintenanceRequired)"},
+ {0x00000800, "Qualifier_11 (MaintenanceRequired)"},
+ {0x00001000, "Qualifier_12 (MaintenanceRequired, PA: MaintenanceRequired)"},
+ {0x00002000, "Qualifier_13 (MaintenanceRequired)"},
+ {0x00004000, "Qualifier_14 (MaintenanceRequired)"},
+ {0x00008000, "Qualifier_15 (MaintenanceRequired)"},
+ {0x00010000, "Qualifier_16 (MaintenanceRequired)"},
+ {0x00020000, "Qualifier_17 (MaintenanceDemanded)"},
+ {0x00040000, "Qualifier_18 (MaintenanceDemanded)"},
+ {0x00080000, "Qualifier_19 (MaintenanceDemanded)"},
+ {0x00100000, "Qualifier_20 (MaintenanceDemanded)"},
+ {0x00200000, "Qualifier_21 (MaintenanceDemanded)"},
+ {0x00400000, "Qualifier_22 (MaintenanceDemanded, PA: MaintenanceDemanded)"},
+ {0x00800000, "Qualifier_23 (MaintenanceDemanded)"},
+ {0x01000000, "Qualifier_24 (MaintenanceDemanded, PA: FunctionCheck)"},
+ {0x02000000, "Qualifier_25 (MaintenanceDemanded)"},
+ {0x04000000, "Qualifier_26 (MaintenanceDemanded)"},
+ {0x08000000, "Qualifier_27 (Fault)"},
+ {0x10000000, "Qualifier_28 (Fault)"},
+ {0x20000000, "Qualifier_29 (Fault)"},
+ {0x40000000, "Qualifier_30 (Fault, PA: Fault)"},
+ {0x80000000, "Qualifier_31 (Fault)"},
+ {0, NULL}};
+
+static const value_string pn_io_channel_properties_type[] = {
+ { 0x0000, "submodule or unspecified" },
+ { 0x0001, "1 Bit" },
+ { 0x0002, "2 Bit" },
+ { 0x0003, "4 Bit" },
+ { 0x0004, "8 Bit" },
+ { 0x0005, "16 Bit" },
+ { 0x0006, "32 Bit" },
+ { 0x0007, "64 Bit" },
+ /*0x0008 - 0x00FF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_channel_properties_accumulative_vals[] = {
+ { 0x0000, "Channel" },
+ { 0x0001, "ChannelGroup" },
+ { 0, NULL }
+};
+
+/* We are reading this as a two bit value, but the spec specifies each bit
+ * separately. Beware endianness when reading spec
+ */
+static const value_string pn_io_channel_properties_maintenance[] = {
+ { 0x0000, "Failure" },
+ { 0x0001, "Maintenance required" },
+ { 0x0002, "Maintenance demanded" },
+ { 0x0003, "see QualifiedChannelQualifier" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_channel_properties_specifier[] = {
+ { 0x0000, "All subsequent disappears" },
+ { 0x0001, "Appears" },
+ { 0x0002, "Disappears" },
+ { 0x0003, "Disappears but others remain" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_channel_properties_direction[] = {
+ { 0x0000, "Manufacturer-specific" },
+ { 0x0001, "Input" },
+ { 0x0002, "Output" },
+ { 0x0003, "Input/Output" },
+ /*0x0004 - 0x0007 reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_alarmcr_type[] = {
+ { 0x0000, "reserved" },
+ { 0x0001, "Alarm CR" },
+ /*0x0002 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_mau_type[] = {
+ /*0x0000 - 0x0004 reserved */
+ { 0x0005, "10BASET" },
+ /*0x0006 - 0x0009 reserved */
+ { 0x000A, "10BASETXHD" },
+ { 0x000B, "10BASETXFD" },
+ { 0x000C, "10BASEFLHD" },
+ { 0x000D, "10BASEFLFD" },
+ { 0x000F, "100BASETXHD" },
+ { 0x0010, "100BASETXFD" },
+ { 0x0011, "100BASEFXHD" },
+ { 0x0012, "100BASEFXFD" },
+ /*0x0013 - 0x0014 reserved */
+ { 0x0015, "1000BASEXHD" },
+ { 0x0016, "1000BASEXFD" },
+ { 0x0017, "1000BASELXHD" },
+ { 0x0018, "1000BASELXFD" },
+ { 0x0019, "1000BASESXHD" },
+ { 0x001A, "1000BASESXFD" },
+ /*0x001B - 0x001C reserved */
+ { 0x001D, "1000BASETHD" },
+ { 0x001E, "1000BASETFD" },
+ { 0x001F, "10GigBASEFX" },
+ /*0x0020 - 0x002D reserved */
+ { 0x002E, "100BASELX10" },
+ /*0x002F - 0x0035 reserved */
+ { 0x0036, "100BASEPXFD" },
+ /*0x0037 - 0x008C reserved */
+ { 0x008D, "10BASET1L" },
+ /*0x008E - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_preamble_length[] = {
+ { 0x0000, "Seven octets Preamble shall be used" },
+ { 0x0001, "One octet Preamble shall be used" },
+ /*0x0002 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_mau_type_mode[] = {
+ { 0x0000, "OFF" },
+ { 0x0001, "ON" },
+ /*0x0002 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_dcp_boundary_value_bit0[] = {
+ { 0x00, "Do not block the multicast MAC address 01-0E-CF-00-00-00" },
+ { 0x01, "Block an outgoing DCP_Identify frame (egress filter) with the multicast MAC address 01-0E-CF-00-00-00" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_dcp_boundary_value_bit1[] = {
+ { 0x00, "Do not block the multicast MAC address 01-0E-CF-00-00-01" },
+ { 0x01, "Block an outgoing DCP_Hello frame (egress filter) with the multicast MAC address 01-0E-CF-00-00-01" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_peer_to_peer_boundary_value_bit0[] = {
+ { 0x00, "The LLDP agent shall send LLDP frames for this port." },
+ { 0x01, "The LLDP agent shall not send LLDP frames (egress filter)." },
+ { 0, NULL }
+};
+
+static const value_string pn_io_peer_to_peer_boundary_value_bit1[] = {
+ { 0x00, "The PTCP ASE shall send PTCP_DELAY request frames for this port." },
+ { 0x01, "The PTCP ASE shall not send PTCP_DELAY request frames (egress filter)." },
+ { 0, NULL }
+};
+
+static const value_string pn_io_peer_to_peer_boundary_value_bit2[] = {
+ { 0x00, "The Time ASE shall send PATH_DELAY request frames for this port." },
+ { 0x01, "The Time ASE shall not send PATH_DELAY request frames (egress filter)." },
+ { 0, NULL }
+};
+
+static const range_string pn_io_mau_type_extension[] = {
+ { 0x0000, 0x0000, "No SubMAUType" },
+ { 0x0001, 0x00FF, "Reserved" },
+ { 0x0100, 0x0100, "POF" },
+ { 0x0101, 0x01FF, "Reserved for SubMAUType" },
+ { 0x0200, 0x0200, "APL" },
+ { 0x0201, 0xFFEF, "Reserved for SubMAUType" },
+ { 0xFFF0, 0xFFFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_pe_operational_mode[] = {
+ { 0x00, 0x00, "PE_PowerOff" },
+ { 0x01, 0x1F, "PE_EnergySavingMode" },
+ { 0x20, 0xEF, "Reserved" },
+ { 0xF0, 0xF0, "PE_Operate" },
+ { 0xF1, 0xFD, "Reserved" },
+ { 0xFE, 0xFE, "PE_SleepModeWOL" },
+ { 0xFF, 0xFF, "PE_ReadyToOperate" },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_port_state[] = {
+ { 0x0000, "reserved" },
+ { 0x0001, "up" },
+ { 0x0002, "down" },
+ { 0x0003, "testing" },
+ { 0x0004, "unknown" },
+ /*0x0005 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_link_state_port[] = {
+ { 0x00, "unknown" },
+ { 0x01, "disabled/discarding" },
+ { 0x02, "blocking" },
+ { 0x03, "listening" },
+ { 0x04, "learning" },
+ { 0x05, "forwarding" },
+ { 0x06, "broken" },
+ /*0x07 - 0xFF reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_link_state_link[] = {
+ { 0x00, "reserved" },
+ { 0x01, "up" },
+ { 0x02, "down" },
+ { 0x03, "testing" },
+ { 0x04, "unknown" },
+ { 0x05, "dormant" },
+ { 0x06, "notpresent" },
+ { 0x07, "lowerlayerdown" },
+ /*0x08 - 0xFF reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_media_type[] = {
+ { 0x0000, "Unknown" },
+ { 0x0001, "Copper cable" },
+ { 0x0002, "Fiber optic cable" },
+ { 0x0003, "Radio communication" },
+ /*0x0004 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_fiber_optic_type[] = {
+ { 0x0000, "No fiber type adjusted" },
+ { 0x0001, "9 um single mode fiber" },
+ { 0x0002, "50 um multi mode fiber" },
+ { 0x0003, "62,5 um multi mode fiber" },
+ { 0x0004, "SI-POF, NA=0.5" },
+ { 0x0005, "SI-PCF, NA=0.36" },
+ { 0x0006, "LowNA-POF, NA=0.3" },
+ { 0x0007, "GI-POF" },
+ /*0x0008 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_fiber_optic_cable_type[] = {
+ { 0x0000, "No cable specified" },
+ { 0x0001, "Inside/outside cable, fixed installation" },
+ { 0x0002, "Inside/outside cable, flexible installation" },
+ { 0x0003, "Outdoor cable, fixed installation" },
+ /*0x0004 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_im_revision_prefix_vals[] = {
+ { 'V', "V - Officially released version" },
+ { 'R', "R - Revision" },
+ { 'P', "P - Prototype" },
+ { 'U', "U - Under Test (Field Test)" },
+ { 'T', "T - Test Device" },
+ /*all others reserved */
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_mrp_role_vals[] = {
+ { 0x0000, "Media Redundancy disabled" },
+ { 0x0001, "Media Redundancy Client" },
+ { 0x0002, "Media Redundancy Manager" },
+ /*all others reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_mrp_instance_no[] = {
+ { 0x0000, "MRP_Instance 1" },
+ { 0x0001, "MRP_Instance 2" },
+ { 0x0002, "MRP_Instance 3" },
+ { 0x0003, "MRP_Instance 4" },
+ { 0x0004, "MRP_Instance 5" },
+ { 0x0005, "MRP_Instance 6" },
+ { 0x0006, "MRP_Instance 7" },
+ { 0x0007, "MRP_Instance 8" },
+ { 0x0008, "MRP_Instance 9" },
+ { 0x0009, "MRP_Instance 10" },
+ { 0x000A, "MRP_Instance 11" },
+ { 0x000B, "MRP_Instance 12" },
+ { 0x000C, "MRP_Instance 13" },
+ { 0x000D, "MRP_Instance 14" },
+ { 0x000E, "MRP_Instance 15" },
+ { 0x000F, "MRP_Instance 16" },
+ /*all others reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_mrp_mrm_on[] = {
+ { 0x0000, "Disable MediaRedundancyManager diagnosis" },
+ { 0x0001, "Enable MediaRedundancyManager diagnosis"},
+ { 0, NULL }
+};
+static const value_string pn_io_mrp_checkUUID[] = {
+ { 0x0000, "Disable the check of the MRP_DomainUUID" },
+ { 0x0001, "Enable the check of the MRP_DomainUUID"},
+ { 0, NULL }
+};
+
+static const value_string pn_io_mrp_prio_vals[] = {
+ { 0x0000, "Highest priority redundancy manager" },
+ /* 0x1000 - 0x7000 High priorities */
+ { 0x8000, "Default priority for redundancy manager" },
+ /* 0x9000 - 0xE000 Low priorities */
+ { 0xF000, "Lowest priority redundancy manager" },
+ /*all others reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_mrp_rtmode_rtclass12_vals[] = {
+ { 0x0000, "RT_CLASS_1 and RT_CLASS_2 redundancy mode deactivated" },
+ { 0x0001, "RT_CLASS_1 and RT_CLASS_2 redundancy mode activated" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_mrp_rtmode_rtclass3_vals[] = {
+ { 0x0000, "RT_CLASS_3 redundancy mode deactivated" },
+ { 0x0001, "RT_CLASS_3 redundancy mode activated" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_mrp_ring_state_vals[] = {
+ { 0x0000, "Ring open" },
+ { 0x0001, "Ring closed" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_mrp_rt_state_vals[] = {
+ { 0x0000, "RT media redundancy lost" },
+ { 0x0001, "RT media redundancy available" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_control_properties_vals[] = {
+ { 0x0000, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_control_properties_prmbegin_vals[] = {
+ { 0x0000, "No PrmBegin" },
+ { 0x0001, "The IO controller starts the transmission of the stored start-up parameter" },
+ { 0, NULL }
+};
+static const value_string pn_io_control_properties_application_ready_bit0_vals[] = {
+ { 0x0000, "Wait for explicit ControlCommand.ReadyForCompanion" },
+ { 0x0001, "Implicit ControlCommand.ReadyForCompanion" },
+ { 0, NULL }
+};
+static const value_string pn_io_control_properties_application_ready_bit1_vals[] = {
+ { 0x0000, "Wait for explicit ControlCommand.ReadyForRT_CLASS_3" },
+ { 0x0001, "Implicit ControlCommand.ReadyForRT_CLASS_3" },
+ { 0, NULL }
+};
+static const value_string pn_io_fs_hello_mode_vals[] = {
+ { 0x0000, "OFF" },
+ { 0x0001, "Send req on LinkUp" },
+ { 0x0002, "Send req on LinkUp after HelloDelay" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_fs_parameter_mode_vals[] = {
+ { 0x0000, "OFF" },
+ { 0x0001, "ON" },
+ { 0x0002, "Reserved" },
+ { 0x0003, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_frame_details_sync_master_vals[] = {
+ { 0x0000, "No Sync Frame" },
+ { 0x0001, "Primary sync frame" },
+ { 0x0002, "Secondary sync frame" },
+ { 0x0003, "Reserved" },
+ { 0, NULL }
+};
+static const value_string pn_io_frame_details_meaning_frame_send_offset_vals[] = {
+ { 0x0000, "Field FrameSendOffset specifies the point of time for receiving or transmitting a frame " },
+ { 0x0001, "Field FrameSendOffset specifies the beginning of the RT_CLASS_3 interval within a phase" },
+ { 0x0002, "Field FrameSendOffset specifies the ending of the RT_CLASS_3 interval within a phase" },
+ { 0x0003, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_f_check_seqnr[] = {
+ { 0x00, "consecutive number not included in crc" },
+ { 0x01, "consecutive number included in crc" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_f_check_ipar[] = {
+ { 0x00, "no check" },
+ { 0x01, "check" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_f_sil[] = {
+ { 0x00, "SIL1" },
+ { 0x01, "SIL2" },
+ { 0x02, "SIL3" },
+ { 0x03, "NoSIL" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_f_crc_len[] = {
+ { 0x00, "3 octet CRC" },
+ { 0x01, "2 octet CRC" },
+ { 0x02, "4 octet CRC" },
+ { 0x03, "reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_f_crc_seed[] = {
+ { 0x00, "CRC-FP as seed value and counter" },
+ { 0x01, "'1' as seed value and CRC-FP+/MNR" },
+ { 0, NULL }
+};
+
+/* F_Block_ID dissection due to ver2.6 specifikation of PI */
+static const value_string pn_io_f_block_id[] = {
+ { 0x00, "No F_WD_Time_2, no F_iPar_CRC" },
+ { 0x01, "No F_WD_Time_2, F_iPar_CRC" },
+ { 0x02, "F_WD_Time_2, no F_iPar_CRC" },
+ { 0x03, "F_WD_Time_2, F_iPar_CRC" },
+ /* 0x04..0x07 reserved */
+ /* { 0x00, "Parameter set for F-Host/F-Device relationship" }, */
+ /* { 0x01, "Additional F_Address parameter block" }, */
+ /* 0x02..0x07 reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_f_par_version[] = {
+ { 0x00, "Valid for V1-mode" },
+ { 0x01, "Valid for V2-mode" },
+ /* 0x02..0x03 reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_profidrive_request_id_vals[] = {
+ { 0x00, "Reserved" },
+ { 0x01, "Read request" },
+ { 0x02, "Change request" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_profidrive_response_id_vals[] = {
+ { 0x00, "Reserved" },
+ { 0x01, "Positive read response" },
+ { 0x02, "Positive change response" },
+ { 0x81, "Negative read response" },
+ { 0x82, "Negative change response" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_profidrive_attribute_vals[] = {
+ { 0x00, "Reserved" },
+ { 0x10, "Value" },
+ { 0x20, "Description" },
+ { 0x30, "Text" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_profidrive_format_vals[] = {
+ {0x0, "Zero"},
+ {0x01, "Boolean" },
+ {0x02, "Integer8" },
+ {0x03, "Integer16" },
+ {0x04, "Integer32" },
+ {0x05, "Unsigned8" },
+ {0x06, "Unsigned16" },
+ {0x07, "Unsigned32" },
+ {0x08, "Float32" },
+ {0x09, "VisibleString" },
+ {0x0A, "OctetString" },
+ {0x0B, "Binary Date"},
+ {0x0C, "TimeOfDay" },
+ {0x0D, "TimeDifference" },
+ {0x0E, "BitString"},
+ {0x0F, "Float64"},
+ {0x10, "UniversalTime"},
+ {0x11, "FieldbusTime"},
+ {0x15, "Time Value"},
+ {0x16, "Bitstring8"},
+ {0x17, "Bitstring16"},
+ {0x18, "Bitstring32"},
+ {0x19, "VisibleString1"},
+ {0x1A, "VisibleString2"},
+ {0x1B, "VisibleString4"},
+ {0x1C, "VisibleString8"},
+ {0x1D, "VisibleString16"},
+ {0x1E, "OctetString1"},
+ {0x1F, "OctetString2"},
+ {0x20, "OctetString4"},
+ {0x21, "OctetString8"},
+ {0x22, "OctetString16"},
+ {0x23, "BCD"},
+ {0x24, "UNICODE char"},
+ {0x25, "CompactBoolean-Array"},
+ {0x26, "CompactBCDArray"},
+ {0x27, "UNICODEString"},
+ {0x28, "BinaryTime0"},
+ {0x29, "BinaryTime1"},
+ {0x2A, "BinaryTime2"},
+ {0x2B, "BinaryTime3"},
+ {0x2C, "BinaryTime4"},
+ {0x2D, "BinaryTime5"},
+ {0x2E, "BinaryTime6"},
+ {0x2F, "BinaryTime7"},
+ {0x30, "BinaryTime8"},
+ {0x31, "BinaryTime9"},
+ {0x32, "Date"},
+ {0x33, "BinaryDate2000"},
+ {0x34, "TimeOfDay without date indication"},
+ {0x35, "TimeDifference with date indication"},
+ {0x36, "TimeDifference without date indication"},
+ {0x37, "Integer64"},
+ {0x38, "Unsigned64"},
+ {0x39, "BitString64"},
+ {0x3A, "NetworkTime"},
+ {0x3B, "NetworkTime-Difference"},
+
+ {0x40, "Zero" },
+ {0x41, "Byte" },
+ {0x42, "Word" },
+ {0x43, "Dword" },
+ {0x44, "Error Type" },
+ {0x65, "Float32+Unsigned8"},
+ {0x66, "Unsigned8+Unsigned8"},
+ {0x67, "OctetString2+Unsigned8"},
+ {0x68, "Unsigned16_S"},
+ {0x69, "Integer16_S"},
+ {0x6A, "Unsigned8_S"},
+ {0x6B, "OctetString_S"},
+ {0x6E, "F message trailer with 4 octets"},
+ {0x6F, "F message trailer with 5 octets"},
+ {0x70, "F message trailer with 6 octets"},
+ {0x71, "N2 Normalized value (16 bit)"},
+ {0x72, "N4 Normalized value (32 bit)"},
+ {0x73, "V2 Bit sequence" },
+ {0x74, "L2 Nibble"},
+ {0x75, "R2 Reciprocal time constant"},
+ {0x76, "T2 Time constant (16 bit)"},
+ {0x77, "T4 Time constant (32 bit)"},
+ {0x78, "D2 Time constant"},
+ {0x79, "E2 Fixed point value (16 bit)"},
+ {0x7A, "C4 Fixed point value (32 bit)"},
+ {0x7B, "X2 Normalized value, variable (16bit)"},
+ {0x7C, "X4 Normalized value, variables (32bit)"},
+ { 0, NULL }
+};
+
+static const value_string pn_io_profidrive_parameter_resp_errors[] =
+{
+ {0x0, "Disallowed parameter number" },
+ {0x1, "The parameter value cannot be changed" },
+ {0x2, "Exceed the upper or lower limit" },
+ {0x3, "Sub-index error" },
+ {0x4, "Non-array" },
+ {0x5, "Incorrect data type" },
+ {0x6, "Setting is not allowed (can only be reset)" },
+ {0x7, "The description element cannot be modified" },
+ {0x8, "Reserved" },
+ {0x9, "Descriptive data does not exist" },
+ {0xA, "Reserved" },
+ {0xB, "No operation priority" },
+ {0xC, "Reserved" },
+ {0xD, "Reserved" },
+ {0xE, "Reserved" },
+ {0xF, "The text array does not save right" },
+ {0x11, "The request cannot be executed because of the working status" },
+ {0x12, "Reserved" },
+ {0x13, "Reserved" },
+ {0x14, "Value is not allowed" },
+ {0x15, "Response timeout" },
+ {0x16, "Illegal parameter address" },
+ {0x17, "Illegal parameter format" },
+ {0x18, "The number of values is inconsistent" },
+ {0x19, "Axis/DO does not exist" },
+ {0x20, "The parameter text element cannot be changed" },
+ {0x21, "No support service" },
+ {0x22, "Too many parameter requests" },
+ {0x23, "Only support single parameter access" },
+ { 0, NULL }
+};
+static const range_string pn_io_rs_block_type[] = {
+ /* Following ranges are used for events */
+ { 0x0000, 0x0000, "reserved" },
+ { 0x0001, 0x3FFF, "Manufacturer specific" },
+ { 0x4000, 0x4000, "Stop observer - Observer Status Observer" },
+ { 0x4001, 0x4001, "Buffer observer - RS_BufferObserver" },
+ { 0x4002, 0x4002, "Time status observer - RS_TimeStatus" },
+ { 0x4003, 0x4003, "System redundancy layer observer - RS_SRLObserver" },
+ { 0x4004, 0x4004, "Source identification observer - RS_SourceIdentification" },
+ { 0x4005, 0x400F, "reserved" },
+ { 0x4010, 0x4010, "Digital input observer - SoE_DigitalInputObserver" },
+ { 0x4011, 0x6FFF, "Reserved for normative usage" },
+ { 0x7000, 0x7FFF, "Reserved for profile usage" },
+ /* Following ranges are used for adjust */
+ { 0x8000, 0x8000, "reserved" },
+ { 0x8001, 0xBFFF, "Manufacturer specific" },
+ { 0xC000, 0xC00F, "Reserved for normative usage" },
+ { 0xC010, 0xC010, "Digital input observer - SoE_DigitalInputObserver" },
+ { 0xC011, 0xEFFF, "Reserved for normative usage"},
+ { 0xF000, 0xFFFF, "Reserved for profile usage"},
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_rs_specifier_specifier[] = {
+ { 0x0, "Current value" },
+ { 0x1, "Appears" },
+ { 0x2, "Disappears" },
+ { 0x3, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_rs_time_stamp_status[] = {
+ { 0x0, "TimeStamp related to global synchronized time" },
+ { 0x1, "TimeStamp related to local time" },
+ { 0x2, "TimeStamp related to local (arbitrary timescale) time" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_rs_reason_code_reason[] = {
+ { 0x00000000, "Reserved" },
+ { 0x00000001, "Observed data status unclear" },
+ { 0x00000002, "Buffer overrun" },
+ /* 0x0003 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_rs_reason_code_detail[] = {
+ { 0x00000000, "No Detail" },
+ /* 0x0001 - 0xFFFF Reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_soe_digital_input_current_value_value[] = {
+ { 0x0, "Digital input is zero" },
+ { 0x1, "Digital input is one" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_soe_adjust_specifier_incident[] = {
+ { 0x00, "Reserved" },
+ { 0x01, "Rising edge" },
+ { 0x02, "Falling edge" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_rs_properties_alarm_transport[] = {
+ { 0x00000000, "Default Reporting system events need to be read by record " },
+ { 0x00000001, "Reporting system events shall be forwarded to the IOC using the alarm transport" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_am_location_structure_vals[] = {
+ { 0x00, "Reserved" },
+ { 0x01, "Twelve level tree format" },
+ { 0x02, "Slot - and SubslotNumber format" },
+ { 0, NULL }
+};
+
+static const range_string pn_io_am_location_level_vals[] = {
+ { 0x0000, 0x03FE, "Address information to identify a reported node" },
+ { 0x03FF, 0x03FF, "Level not used" },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_am_location_reserved_vals[] = {
+ { 0x00, "Reserved" },
+ { 0, NULL }
+};
+
+static const range_string pn_io_RedundancyDataHoldFactor[] = {
+ { 0x0000, 0x0002, "Reserved" },
+ { 0x0003, 0x00C7, "Optional - An expiration of the time leads to an AR termination." },
+ { 0x00C8, 0xFFFF, "Mandatory - An expiration of the time leads to an AR termination." },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_ar_arnumber[] = {
+ { 0x0000, "reserved" },
+ { 0x0001, "1st AR of an ARset" },
+ { 0x0002, "2nd AR of an ARset" },
+ { 0x0003, "3rd AR of an ARset" },
+ { 0x0004, "4th AR of an ARset" },
+ /*0x0005 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_ar_arresource[] = {
+ { 0x0000, "reserved" },
+ { 0x0002, "Communication endpoint shall allocate two ARs for the ARset" },
+ /*0x0001 and 0x0003 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const range_string pn_io_line_delay_value[] = {
+ { 0x00000000, 0x00000000, "Line delay and cable delay unknown" },
+ { 0x00000001, 0x7FFFFFFF, "Line delay in nanoseconds" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_cable_delay_value[] = {
+ { 0x00000000, 0x00000000, "Reserved" },
+ { 0x00000001, 0x7FFFFFFF, "Cable delay in nanoseconds" },
+ { 0, 0, NULL }
+};
+
+static const true_false_string pn_io_pdportstatistic_counter_status_contents = {
+ "The contents of the field are invalid. They shall be set to zero.",
+ "The contents of the field are valid"
+};
+
+static const value_string pn_io_pdportstatistic_counter_status_reserved[] = {
+ { 0x00, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_tsn_domain_vid_config_vals[] = {
+ { 0x00, "Reserved" },
+ { 0x64, "NonStreamVID-Default" },
+ { 0x65, "StreamHighVID-Default" },
+ { 0x66, "StreamHighRedVID-Default" },
+ { 0x67, "StreamLowVID-Default" },
+ { 0x68, "StreamLowRedVID-Default" },
+ { 0x69, "NonStreamVIDB-Default" },
+ { 0x6A, "NonStreamVIDC-Default" },
+ { 0x6B, "NonStreamVIDD-Default" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_tsn_domain_port_config_preemption_enabled_vals[] = {
+ { 0x00, "Preemption support is disabled for this port" },
+ { 0x01, "Preemption support is enabled for this port" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_tsn_domain_port_config_boundary_port_config_vals[] = {
+ { 0x00, "No boundary port" },
+ { 0x01, "Boundary port with Remapping1" },
+ { 0x02, "Boundary port with Remapping2" },
+ { 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_port_ingress_rate_limiter_cir[] = {
+ { 0x0000, 0x0000, "No Boundary Port" },
+ { 0x0001, 0xFFFF, "Committed information rate in 0,1 Mbit/s"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_port_ingress_rate_limiter_cbs[] = {
+ { 0x0000, 0x0000, "No Boundary Port" },
+ { 0x0001, 0xFFFF, "Committed burst size in octets"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_port_ingress_rate_limiter_envelope[] = {
+ { 0x0000, 0x0000, "No Boundary Port" },
+ { 0x0001, 0x0001, "Best effort envelope"},
+ { 0x0002, 0x0002, "RT_CLASS_X, RTA_CLASS_X envelope"},
+ { 0x0003, 0xFFFF, "Reserved"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_port_ingress_rate_limiter_rank[] = {
+ { 0x0000, 0x0000, "No Boundary Port" },
+ { 0x0001, 0x0001, "CF1"},
+ { 0x0002, 0x0002, "CF2"},
+ { 0x0003, 0x0003, "CF3"},
+ { 0x0004, 0x0004, "CF4"},
+ { 0x0005, 0x0005, "CF5"},
+ { 0x0006, 0xFFFF, "Reserved"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_queue_rate_limiter_cir[] = {
+ { 0x0000, 0x0000, "Used in case of no rate limiter" },
+ { 0x0001, 0xFFFF, "Committed information rate in 0,1 Mbit/s"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_queue_rate_limiter_cbs[] = {
+ { 0x0000, 0x0000, "Used in case of no rate limiter" },
+ { 0x0001, 0xFFFF, "Committed burst size in octets"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_queue_rate_limiter_envelope[] = {
+ { 0x00, 0x00, "Used in case of no rate limiter" },
+ { 0x01, 0x01, "Best effort envelope"},
+ { 0x02, 0xFF, "Reserved"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_queue_rate_limiter_rank[] = {
+ { 0x00, 0x00, "Used in case of no boundary port" },
+ { 0x01, 0x01, "CF1"},
+ { 0x02, 0x02, "CF2"},
+ { 0x03, 0x03, "CF3"},
+ { 0x04, 0x04, "CF4"},
+ { 0x05, 0x05, "CF5"},
+ { 0x06, 0xFF, "Reserved"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_queue_rate_limiter_queue_id[] = {
+ { 0x00, 0x07, "Identifier of the queue" },
+ { 0x08, 0xFF, "Reserved"},
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_queue_rate_limiter_reserved[] = {
+ { 0x00, 0xFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_network_domain[] = {
+ { 0x00000000, 0x00000000, "No Deadline" },
+ { 0x00000001, 0xFFFFFFFF, "The Deadline in Microseconds"},
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_time_domain_number_vals[] = {
+ { 0x0000, "Global Time" },
+ { 0x0001, "Global Time Redundant" },
+ { 0x0020, "Working Clock" },
+ { 0x0021, "Working Clock Redundant" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_time_pll_window_vals[] = {
+ { 0x00000000, "Disabled" },
+ { 0x000003E8, "Default" },
+ { 0x00002710, "Default" },
+ { 0x000186A0, "Default" },
+ { 0x000F4240, "Default" },
+ { 0x00989680, "Default" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_message_interval_factor_vals[] = {
+ { 0x0000, "Reserved" },
+ { 0x03E8, "Default" },
+ { 0x0FA0, "Default" },
+ { 0, NULL }
+};
+
+static const range_string pn_io_message_timeout_factor[] = {
+ { 0x0000, 0x0000, "Disabled" },
+ { 0x0001, 0x0002, "Optional" },
+ { 0x0003, 0x0005, "Mandatory" },
+ { 0x0006, 0x0006, "Default, mandatory" },
+ { 0x0007, 0x000F, "Mandatory" },
+ { 0x0010, 0x01FF, "Optional" },
+ { 0x0200, 0xFFFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_time_sync_properties_vals[] = {
+ { 0x00, "Reserved" },
+ { 0x01, "External Sync" },
+ { 0x02, "Internal Sync" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_queue_config_shaper[] = {
+ { 0x00, 0x00, "Reserved" },
+ { 0x01, 0x01, "Strict Priority" },
+ { 0x02, 0xFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_domain_sync_port_role_vals[] = {
+ { 0x00,0x00, "The port is not part of the sync tree for this sync domain" },
+ { 0x01,0x01, "Sync egress port for this sync domain" },
+ { 0x02,0x02, "Sync ingress port for this sync domain" },
+ { 0x02,0XFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_tsn_fdb_command[] = {
+ { 0x01, "AddStreamEntry" },
+ { 0x02, "RemoveStreamEntry" },
+ { 0x03, "RemoveAllStreamEntries" },
+ /* all others reserved */
+ { 0, NULL }
+};
+
+static const range_string pn_io_tsn_transfer_time_tx_vals[] = {
+ { 0x00000000, 0x00000000, "Reserved" },
+ { 0x00000001, 0x05F5E100, "Egress transfer time for the local interface of an endstation" },
+ { 0x05F5E101, 0xFFFFFFFF, "Reserved" },
+ { 0, 0, NULL }
+
+};
+
+static const range_string pn_io_tsn_transfer_time_rx_vals[] = {
+
+ { 0x00000000, 0x00000000, "Reserved" },
+ { 0x00000001, 0x05F5E100, "Ingress transfer time for the local interface of an endstation" },
+ { 0x05F5E101, 0xFFFFFFFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_max_supported_record_size_vals[] = {
+ { 0x00000000,0x00000FE3, "Reserved" },
+ { 0x00000FE4,0x0000FFFF, "Describes the maximum supported size of RecordDataWrite." },
+ {0x00010000,0xFFFFFFFF,"Reserved"},
+ { 0, 0, NULL }
+};
+static const range_string pn_io_tsn_forwarding_group_vals[] = {
+ { 0x00,0x00, "Reserved" },
+ { 0x01,0xFF, "Identifier of logical port grouping. Identifies ports with equal forwarding delay values." },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_tsn_stream_class_vals[] = {
+
+ /*other reserved */
+ { 0x01, "High" },
+ { 0x02, "High Redundant" },
+ { 0x03, "Low" },
+ { 0x04, "Low Redundant" },
+ { 0, NULL }
+};
+
+static const range_string pn_io_tsn_independent_forwarding_delay_vals[] = {
+
+ { 0x00000000, 0x00000000, "Reserved" },
+ { 0x00000001, 0x000F4240, "Independent bridge delay value used for calculation" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_io_tsn_dependent_forwarding_delay_vals[] = {
+
+ { 0x00000000, 0x00000000, "Reserved" },
+ { 0x00000001, 0x000C3500, "Octet size dependent bridge delay value used for calculation" },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_io_tsn_number_of_queues_vals[] = {
+
+ { 0x06, "The bridge supports six transmit queues at the port" },
+ { 0x08, "The bridge supports eight transmit queues at the port" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_tsn_port_capabilities_time_aware_vals[] = {
+ { 0x00, "This port is not usable within a Time Aware System"},
+ { 0x01, "This port is usable within a Time Aware System" },
+ { 0, NULL }
+};
+static const value_string pn_io_tsn_port_capabilities_preemption_vals[] = {
+ { 0x00, "Preemption is not supported at this port" },
+ { 0x01, "Preemption is supported at this port"},
+ { 0, NULL }
+};
+
+static const value_string pn_io_tsn_port_capabilities_queue_masking_vals[] = {
+ { 0x00, "Queue Masking is not supported at this port"},
+ { 0x01, "Queue Masking is supported at this port" },
+ { 0, NULL }
+};
+
+/* Format of submodule ident number as per PA Profile 4.02 specification:
+ [VariantOfSubmodule, Block_object, Parent_Class, Class] */
+static const value_string pn_io_pa_profile_block_object_vals[] = {
+ { 0, "DAP" },
+ { 1, "PB" },
+ { 2, "FB" },
+ { 3, "TB" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_dap_submodule_vals[] = {
+ { 1, "DAP" },
+ { 2, "Device Management" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_physical_block_parent_class_vals[] = {
+ { 1, "Transmitter" },
+ { 2, "Actuator" },
+ { 3, "Discrete I/O" },
+ { 4, "Controller" },
+ { 5, "Analyzer" },
+ { 6, "Lab Device" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_function_block_class_vals[] = {
+ { 1, "Input" },
+ { 2, "Output" },
+ { 3, "Further Input" },
+ { 4, "Further Output" },
+ { 128, "Manuf. specific Input" },
+ { 129, "Manuf. specific Output" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_function_block_parent_class_vals[] = {
+ {0, "Analog Temperature" },
+ {1, "Analog Temperature Difference"},
+ {2, "Analog Average Temperature"},
+ {3, "Analog Electronics Temperature"},
+ {4, "Analog Transmitter Temperature"},
+ {5, "Analog Sensor Temperature"},
+ {6, "Analog Frame Temperature"},
+ {7, "Analog Auxiliary Temperature"},
+ {8, "Analog Energy Supply Temperature"},
+ {9, "Analog Energy Return Temperature"},
+ {20, "Analog Pressure"},
+ {21, "Analog Absolute Pressure"},
+ {22, "Analog Gauge Pressure"},
+ {23, "Analog Differential Pressure"},
+ {30, "Analog Level"},
+ {31, "Analog Distance"},
+ {32, "Analog Interface Level"},
+ {33, "Analog Interface Distance"},
+ {40, "Analog Volume"},
+ {41, "Analog Ullage"},
+ {42, "Analog Interface Volume"},
+ {43, "Analog Standard Volume"},
+ {44, "Analog Fraction Substance 1 Volume"},
+ {45, "Analog Fraction Substance 2 Volume"},
+ {46, "Analog Fraction Substance 1 Std Volume"},
+ {47, "Analog Fraction Substance 2 Std Volume"},
+ {50, "Analog Mass"},
+ {51, "Analog Net Mass"},
+ {52, "Analog Fraction Substance 1 Mass"},
+ {53, "Analog Fraction Substance 2 Mass"},
+ {60, "Analog Volume Flow"},
+ {61, "Analog Standard Volume Flow"},
+ {62, "Analog Fraction Substance 1 Volume Flow"},
+ {63, "Analog Fraction Substance 2 Volume Flow"},
+ {70, "Analog Mass Flow"},
+ {71, "Analog Fraction Substance 1 Mass Flow"},
+ {72, "Analog Fraction Substance 2 Mass Flow"},
+ {80, "Analog Density"},
+ {81, "Analog Standard Density"},
+ {82, "Analog Analog Api Gravity"},
+ {83, "Analog Standard Api Gravity"},
+ {84, "Analog Specific Gravity"},
+ {85, "Analog Standard Specific Gravity"},
+ {90, "Analog Flow Velocity"},
+ {91, "Analog Sound Velocity"},
+ {92, "Analog Rate Of Change"},
+ {100, "Analog Kinematic Viscosity"},
+ {101, "Analog Dynamic Viscosity"},
+ {110, "Analog Energy"},
+ {111, "Analog Power"},
+ {120, "Analog Vortex Frequency"},
+ {130, "Analog Concentration"},
+ {131, "Analog Energy Efficiency Rating"},
+ {132, "Analog Coefficient Of Performance"},
+ {133, "Analog Fraction Substance 1%"},
+ {134, "Analog Fraction Substance 2%"},
+ {140, "Analog pH"},
+ {141, "Analog Conductivity"},
+ {142, "Analog Resistivity"},
+ {143, "Analog Gas Concentration"},
+ {149, "Flexible AI"},
+ {150, "Totalizer"},
+ {160, "Actuator"},
+ {170, "Discrete"},
+ {180, "Enumerated"},
+ {190, "Binary(8 Bit)"},
+ {191, "Binary(16 Bit)"},
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_parent_class_vals[] = {
+ { 1, "Pressure" },
+ { 2, "Temperature" },
+ { 3, "Flow" },
+ { 4, "Level" },
+ { 5, "Actuator" },
+ { 6, "Discrete I/O" },
+ { 7, "Liquid analyzer" },
+ { 8, "Gas analyzer" },
+ { 10, "Enumerated I/O" },
+ { 11, "Binary I/O" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_pressure_class_vals[] = {
+ { 1, "Pressure" },
+ { 2, "Pressure + level" },
+ { 3, "Pressure + flow" },
+ { 4, "Pressure + level + flow" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_temperature_class_vals[] = {
+ { 1, "Thermocouple (TC)" },
+ { 2, "Resistance thermometer (RTD)" },
+ { 3, "Pyrometer" },
+ { 16, "TC + DC U (DC Voltage)" },
+ { 17, "RTD + R (R-Resistance)" },
+ { 18, "TC+RTD+r+DC U" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_flow_class_vals[] = {
+ { 1, "Electromagnetic" },
+ { 2, "Vortex" },
+ { 3, "Coriolis" },
+ { 4, "Thermal mass" },
+ { 5, "Ultrasonic" },
+ { 6, "Variable area" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_level_class_vals[] = {
+ { 1, "Hydrostatic" },
+ { 2, "Ultrasonic" },
+ { 3, "Radiometric" },
+ { 4, "Capacitance" },
+ { 5, "Displacer" },
+ { 6, "Float" },
+ { 7, "Radar" },
+ { 8, "Buoyancy" },
+ { 9, "Air bubble system" },
+ { 10, "Gravimetric" },
+ { 11, "Optical" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_actuator_class_vals[] = {
+ { 1, "Electric" },
+ { 2, "Electro-pneumatic" },
+ { 3, "Electro-hydraulic" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_discrete_io_class_vals[] = {
+ { 1, "Input" },
+ { 2, "Output" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_liquid_analyzer_class_vals[] = {
+ { 1, "pH" },
+ { 2, "Conductivity" },
+ { 3, "Oxygen" },
+ { 4, "Chlorine" },
+ { 5, "Resistivity" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_gas_analyzer_class_vals[] = {
+ { 1, "Standard" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_enumerated_io_class_vals[] = {
+ { 1, "Input" },
+ { 2, "Output" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_pa_profile_transducer_block_binary_io_class_vals[] = {
+ { 2, "8 Bit output" },
+ { 3, "8 Bit input" },
+ { 4, "16 Bit output" },
+ { 5, "16 Bit input" },
+ { 0, NULL }
+};
+
+static const value_string* pn_io_pa_profile_transducer_block_class_vals[] = {
+ NULL,
+ pn_io_pa_profile_transducer_block_pressure_class_vals,
+ pn_io_pa_profile_transducer_block_temperature_class_vals,
+ pn_io_pa_profile_transducer_block_flow_class_vals,
+ pn_io_pa_profile_transducer_block_level_class_vals,
+ pn_io_pa_profile_transducer_block_actuator_class_vals,
+ pn_io_pa_profile_transducer_block_discrete_io_class_vals,
+ pn_io_pa_profile_transducer_block_liquid_analyzer_class_vals,
+ pn_io_pa_profile_transducer_block_gas_analyzer_class_vals,
+ NULL,
+ pn_io_pa_profile_transducer_block_enumerated_io_class_vals,
+ pn_io_pa_profile_transducer_block_binary_io_class_vals
+};
+
+static const value_string pn_io_snmp_control[] = {
+ { 0x00, "Disable SNMP" },
+ { 0x01, "Enable SNMP read only" },
+ { 0x02, "Enable SNMP read/write" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
+static int
+dissect_profidrive_value(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, guint8 *drep, guint8 format_val)
+{
+ guint32 value32;
+ guint16 value16;
+ guint8 value8;
+
+ switch(format_val)
+ {
+ case 1:
+ case 2:
+ case 5:
+ case 0x0A:
+ case 0x41:
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_profidrive_param_value_byte, &value8);
+ break;
+ case 3:
+ case 6:
+ case 0x42:
+ case 0x73:
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_profidrive_param_value_word, &value16);
+ break;
+ case 4:
+ case 7:
+ case 0x43:
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_profidrive_param_value_dword, &value32);
+ break;
+ case 8:
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_profidrive_param_value_float, &value32);
+ break;
+ case 9:
+ {
+ gint sLen;
+ sLen = (gint)tvb_strnlen( tvb, offset, -1);
+ proto_tree_add_item(tree, hf_pn_io_profidrive_param_value_string, tvb, offset, sLen, ENC_ASCII);
+ offset = (offset + sLen);
+ break;
+ }
+ default:
+ offset = offset + 1;
+ expert_add_info_format(pinfo, tree, &ei_pn_io_unsupported, "Not supported or invalid format %u!", format_val);
+ break;
+ }
+ return(offset);
+}
+
+static GList *pnio_ars;
+
+typedef struct pnio_ar_s {
+ /* generic */
+ e_guid_t aruuid;
+ guint16 inputframeid;
+ guint16 outputframeid;
+
+ /* controller only */
+ /*const char controllername[33];*/
+ guint8 controllermac[6];
+ guint16 controlleralarmref;
+
+ /* device only */
+ guint8 devicemac[6];
+ guint16 devicealarmref;
+ guint16 arType;
+} pnio_ar_t;
+
+
+
+static void
+pnio_ar_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pnio_ar_t *ar)
+{
+ p_add_proto_data(wmem_file_scope(), pinfo, proto_pn_io, 0, ar );
+ p_add_proto_data(pinfo->pool, pinfo, proto_pn_io, 0, GUINT_TO_POINTER(10));
+
+ if (tree) {
+ proto_item *item;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ address controllermac_addr, devicemac_addr;
+
+ set_address(&controllermac_addr, AT_ETHER, 6, ar->controllermac);
+ set_address(&devicemac_addr, AT_ETHER, 6, ar->devicemac);
+
+ sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_pn_io_ar_info, &sub_item,
+ "ARUUID:%s ContrMAC:%s ContrAlRef:0x%x DevMAC:%s DevAlRef:0x%x InCR:0x%x OutCR=0x%x",
+ guid_to_str(pinfo->pool, (const e_guid_t*) &ar->aruuid),
+ address_to_str(pinfo->pool, &controllermac_addr), ar->controlleralarmref,
+ address_to_str(pinfo->pool, &devicemac_addr), ar->devicealarmref,
+ ar->inputframeid, ar->outputframeid);
+ proto_item_set_generated(sub_item);
+
+ item = proto_tree_add_guid(sub_tree, hf_pn_io_ar_uuid, tvb, 0, 0, (e_guid_t *) &ar->aruuid);
+ proto_item_set_generated(item);
+
+ item = proto_tree_add_ether(sub_tree, hf_pn_io_cminitiator_macadd, tvb, 0, 0, ar->controllermac);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_pn_io_localalarmref, tvb, 0, 0, ar->controlleralarmref);
+ proto_item_set_generated(item);
+
+ item = proto_tree_add_ether(sub_tree, hf_pn_io_cmresponder_macadd, tvb, 0, 0, ar->devicemac);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_pn_io_localalarmref, tvb, 0, 0, ar->devicealarmref);
+ proto_item_set_generated(item);
+
+ item = proto_tree_add_uint(sub_tree, hf_pn_io_frame_id, tvb, 0, 0, ar->inputframeid);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_pn_io_frame_id, tvb, 0, 0, ar->outputframeid);
+ proto_item_set_generated(item);
+ }
+}
+
+
+
+
+static int dissect_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar);
+
+static int dissect_a_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep);
+
+static int dissect_PNIO_IOxS(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, int hfindex);
+
+
+
+
+
+static pnio_ar_t *
+pnio_ar_find_by_aruuid(packet_info *pinfo _U_, e_guid_t *aruuid)
+{
+ GList *ars;
+ pnio_ar_t *ar;
+
+
+ /* find pdev */
+ for(ars = pnio_ars; ars != NULL; ars = g_list_next(ars)) {
+ ar = (pnio_ar_t *)ars->data;
+
+ if (memcmp(&ar->aruuid, aruuid, sizeof(e_guid_t)) == 0) {
+ return ar;
+ }
+ }
+
+ return NULL;
+}
+
+
+static pnio_ar_t *
+pnio_ar_new(e_guid_t *aruuid)
+{
+ pnio_ar_t *ar;
+
+
+ ar = wmem_new0(wmem_file_scope(), pnio_ar_t);
+
+ memcpy(&ar->aruuid, aruuid, sizeof(e_guid_t));
+
+ ar->controlleralarmref = 0xffff;
+ ar->devicealarmref = 0xffff;
+
+ pnio_ars = g_list_append(pnio_ars, ar);
+
+ return ar;
+}
+
+/* dissect the alarm specifier */
+static int
+dissect_Alarm_specifier(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16AlarmSpecifierSequence;
+ guint16 u16AlarmSpecifierChannel;
+ guint16 u16AlarmSpecifierManufacturer;
+ guint16 u16AlarmSpecifierSubmodule;
+ guint16 u16AlarmSpecifierAR;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* alarm specifier */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_alarm_specifier, tvb, offset, 2, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pdu_type);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_sequence, &u16AlarmSpecifierSequence);
+ u16AlarmSpecifierSequence &= 0x07FF;
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_channel, &u16AlarmSpecifierChannel);
+ u16AlarmSpecifierChannel = (u16AlarmSpecifierChannel &0x0800) >> 11;
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_manufacturer, &u16AlarmSpecifierManufacturer);
+ u16AlarmSpecifierManufacturer = (u16AlarmSpecifierManufacturer &0x1000) >> 12;
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_submodule, &u16AlarmSpecifierSubmodule);
+ u16AlarmSpecifierSubmodule = (u16AlarmSpecifierSubmodule & 0x2000) >> 13;
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_ardiagnosis, &u16AlarmSpecifierAR);
+ u16AlarmSpecifierAR = (u16AlarmSpecifierAR & 0x8000) >> 15;
+
+
+ proto_item_append_text(sub_item, ", Sequence: %u, Channel: %u, Manuf: %u, Submodule: %u AR: %u",
+ u16AlarmSpecifierSequence, u16AlarmSpecifierChannel,
+ u16AlarmSpecifierManufacturer, u16AlarmSpecifierSubmodule, u16AlarmSpecifierAR);
+
+ return offset;
+}
+
+
+/* dissect the alarm header */
+static int
+dissect_Alarm_header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep)
+{
+ guint16 u16AlarmType;
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_alarm_type, &u16AlarmType);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ proto_item_append_text(item, ", %s, API:%u, Slot:0x%x/0x%x",
+ val_to_str(u16AlarmType, pn_io_alarm_type, "(0x%x)"),
+ u32Api, u16SlotNr, u16SubslotNr);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Slot: 0x%x/0x%x",
+ val_to_str(u16AlarmType, pn_io_alarm_type, "(0x%x)"),
+ u16SlotNr, u16SubslotNr);
+
+ return offset;
+}
+
+
+static int
+dissect_ChannelProperties(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16ChannelProperties;
+
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_channel_properties, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_channel_properties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_channel_properties_direction, &u16ChannelProperties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_channel_properties_specifier, &u16ChannelProperties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_channel_properties_maintenance, &u16ChannelProperties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_channel_properties_accumulative, &u16ChannelProperties);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_channel_properties_type, &u16ChannelProperties);
+
+ return offset;
+}
+
+/* dissect the RS_BlockHeader */
+static int
+dissect_RS_BlockHeader(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint8 *drep,
+ guint16 *u16RSBodyLength, guint16 *u16RSBlockType)
+{
+ guint16 u16RSBlockLength;
+ guint8 u8BlockVersionHigh;
+ guint8 u8BlockVersionLow;
+
+ /* u16RSBlockType is needed for further dissection */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rs_block_type, u16RSBlockType);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rs_block_length, &u16RSBlockLength);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_block_version_high, &u8BlockVersionHigh);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_block_version_low, &u8BlockVersionLow);
+
+ proto_item_append_text(item, ": Type=%s, Length=%u(+4), Version=%u.%u",
+ rval_to_str(*u16RSBlockType, pn_io_rs_block_type, "Unknown (0x%04x)"),
+ u16RSBlockLength, u8BlockVersionHigh, u8BlockVersionLow);
+
+ /* Block length is without type and length fields, but with version field */
+ /* as it's already dissected, remove it */
+ *u16RSBodyLength = u16RSBlockLength - 2;
+
+ /* Padding 2 + 2 + 1 + 1 = 6 */
+ /* Therefore we need 2 byte padding to make the block u32 aligned */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* remove padding */
+ *u16RSBodyLength -= 2;
+ return offset;
+}
+
+static int
+dissect_RS_AddressInfo(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep, guint16 *u16RSBodyLength)
+{
+ e_guid_t IM_UniqueIdentifier;
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16ChannelNumber;
+
+ /* IM_UniqueIdentifier */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_uuid, &IM_UniqueIdentifier);
+ *u16RSBodyLength -= 16;
+
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ *u16RSBodyLength -= 4;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ *u16RSBodyLength -= 2;
+
+ /* SubSlotNumber*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ *u16RSBodyLength -= 2;
+
+ /* Channel Number*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_channel_number, &u16ChannelNumber);
+ *u16RSBodyLength -= 2;
+
+ return offset;
+}
+
+/* dissect the RS_EventDataCommon */
+static int
+dissect_RS_EventDataCommon(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep, guint16 *u16RSBodyLength)
+{
+ guint16 u16RSSpecifierSequenceNumber;
+ guint16 u16RSSpecifierReserved;
+ guint16 u16RSSpecifierSpecifier;
+ guint16 u16RSMinorError;
+ guint16 u16RSPlusError;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ proto_item *sub_item_time_stamp;
+ proto_tree *sub_tree_time_stamp;
+ nstime_t timestamp;
+ guint16 u16RSTimeStampStatus;
+
+ /* RS_AddressInfo */
+ offset = dissect_RS_AddressInfo(tvb, offset, pinfo, tree, drep, u16RSBodyLength);
+
+ /* RS_Specifier */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_rs_specifier, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_rs_specifier);
+
+ /* RS_Specifier.SequenceNumber */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_rs_specifier_sequence, &u16RSSpecifierSequenceNumber);
+
+ /* RS_Specifier.Reserved */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_rs_specifier_reserved, &u16RSSpecifierReserved);
+
+ /* RS_Specifier.Specifier */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_rs_specifier_specifier, &u16RSSpecifierSpecifier);
+ *u16RSBodyLength -= 2;
+
+ /* RS_TimeStamp */
+ sub_item_time_stamp = proto_tree_add_item(tree, hf_pn_io_rs_time_stamp, tvb, offset, 12, ENC_NA);
+ sub_tree_time_stamp = proto_item_add_subtree(sub_item_time_stamp, ett_pn_io_rs_time_stamp);
+
+ /* RS_TimeStamp.Status */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree_time_stamp, drep,
+ hf_pn_io_rs_time_stamp_status, &u16RSTimeStampStatus);
+
+ /* RS_TimeStamp.TimeStamp */
+
+ /* Start after from 2 bytes Status */
+ timestamp.secs = (time_t)tvb_get_ntoh48(tvb, offset + 2);
+
+ /* Start after from 4 bytes timestamp.secs */
+ timestamp.nsecs = (int)tvb_get_ntohl(tvb, offset + 8);
+
+ /* Start after from 2 bytes Status and get all 10 bytes */
+ proto_tree_add_time(sub_tree_time_stamp, hf_pn_io_rs_time_stamp_value, tvb, offset + 2, 10, &timestamp);
+ *u16RSBodyLength -= 12;
+ offset += 12;
+
+ /* RS_MinusError */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rs_minus_error, &u16RSMinorError);
+ *u16RSBodyLength -= 2;
+
+ /* RS_PlusError */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rs_plus_error, &u16RSPlusError);
+ *u16RSBodyLength -= 2;
+
+ return offset;
+}
+
+/* dissect the RS_IdentificationInfo */
+static int
+dissect_RS_IdentificationInfo(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ dcerpc_info di; /* fake dcerpc_info struct */
+ dcerpc_call_value dcv; /* fake dcerpc_call_value struct */
+ guint64 u64AMDeviceIdentificationDeviceSubID;
+ guint64 u64AMDeviceIdentificationDeviceID;
+ guint64 u64AMDeviceIdentificationVendorID;
+ guint64 u64AM_DeviceIdentificationOrganization;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ di.call_data = &dcv;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_am_device_identification, tvb, offset, 8, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_am_device_identification);
+
+ /* AM_DeviceIdentification */
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_am_device_identification_device_sub_id, &u64AMDeviceIdentificationDeviceSubID);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_am_device_identification_device_id, &u64AMDeviceIdentificationDeviceID);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_am_device_identification_vendor_id, &u64AMDeviceIdentificationVendorID);
+ offset = dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_am_device_identification_organization, &u64AM_DeviceIdentificationOrganization);
+
+ /* IM_Tag_Function [32] */
+ proto_tree_add_item(tree, hf_pn_io_im_tag_function, tvb, offset, 32, ENC_ASCII);
+ offset += 32;
+
+ /* IM_Tag_Location [22] */
+ proto_tree_add_item(tree, hf_pn_io_im_tag_location, tvb, offset, 22, ENC_ASCII);
+ offset += 22;
+
+ return offset;
+}
+
+/* dissect the RS_EventDataExtension_Data */
+static int
+dissect_RS_EventDataExtension_Data(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep,
+ guint8 *u8RSExtensionBlockLength, guint16 *u16RSBlockType)
+{
+ guint32 u32RSReasonCodeReason;
+ guint32 u32RSReasonCodeDetail;
+ guint8 u8LengthRSDomainIdentification = 16;
+ guint8 u8LengthRSMasterIdentification = 8;
+ guint16 u16SoE_DigitalInputCurrentValueValue;
+ guint16 u16SoE_DigitalInputCurrentValueReserved;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ nstime_t timestamp;
+ guint16 u16RSTimeStampStatus;
+ proto_item *sub_item_time_stamp;
+ proto_tree *sub_tree_time_stamp;
+
+ switch (*u16RSBlockType) {
+ case(0x4000): /* RS_StopObserver */
+
+ /* RS_BlockType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rs_block_type, u16RSBlockType);
+
+ /* RS_ReasonCode */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_rs_reason_code, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_rs_reason_code);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_rs_reason_code_reason, &u32RSReasonCodeReason);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_rs_reason_code_detail, &u32RSReasonCodeDetail);
+ *u8RSExtensionBlockLength -= 6;
+ break;
+ case(0x4001): /* RS_BufferObserver */
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, *u8RSExtensionBlockLength, "UserData");
+ *u8RSExtensionBlockLength = 0;
+ break;
+ case(0x4002): /* RS_TimeStatus */
+
+ /* Padding 1 + 1 + 16 + 8 = 26 or 1 + 1 + 16 + 8 + 12 = 38 */
+ /* Therefore we need 2 byte padding to make the block u32 aligned */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+ *u8RSExtensionBlockLength -= 2;
+
+ /* RS_DomainIdentification */
+ proto_tree_add_item(tree, hf_pn_io_rs_domain_identification, tvb, offset, u8LengthRSDomainIdentification, ENC_NA);
+ offset += u8LengthRSDomainIdentification;
+ *u8RSExtensionBlockLength -= 16;
+
+ /* RS_MasterIdentification */
+ proto_tree_add_item(tree, hf_pn_io_rs_master_identification, tvb, offset, u8LengthRSMasterIdentification, ENC_NA);
+ offset += u8LengthRSMasterIdentification;
+ *u8RSExtensionBlockLength -= 8;
+
+ if (*u8RSExtensionBlockLength > 2)
+ {
+ /* RS_TimeStamp */
+ sub_item_time_stamp = proto_tree_add_item(tree, hf_pn_io_rs_time_stamp, tvb, offset, 12, ENC_NA);
+ sub_tree_time_stamp = proto_item_add_subtree(sub_item_time_stamp, ett_pn_io_rs_time_stamp);
+
+ /* RS_TimeStamp.Status */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree_time_stamp, drep,
+ hf_pn_io_rs_time_stamp_status, &u16RSTimeStampStatus);
+
+ /* RS_TimeStamp.TimeStamp */
+ timestamp.secs = (time_t)tvb_get_ntoh48(tvb, offset + 2); // Start after from 2 bytes Status
+ timestamp.nsecs = (int)tvb_get_ntohl(tvb, offset + 8); // Start after from 4 bytes timestamp.secs
+ // Start after from 2 bytes Status and get all 10 bytes
+ proto_tree_add_time(sub_tree_time_stamp, hf_pn_io_rs_time_stamp_value, tvb, offset + 2, 10, &timestamp);
+ offset += 12;
+ }
+ break;
+ case(0x4003): /* RS_SRLObserver */
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, *u8RSExtensionBlockLength, "UserData");
+ *u8RSExtensionBlockLength = 0;
+ break;
+ case(0x4004): /* RS_SourceIdentification */
+ offset = dissect_RS_IdentificationInfo(tvb, offset, pinfo, tree, drep);
+ *u8RSExtensionBlockLength = 0;
+ break;
+ case(0x4010): /* SoE_DigitalInputObserver */
+ /* SoE_DigitalInputCurrentValue */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_soe_digital_input_current_value, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_soe_digital_input_current_value);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_soe_digital_input_current_value_value, &u16SoE_DigitalInputCurrentValueValue);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_soe_digital_input_current_value_reserved, &u16SoE_DigitalInputCurrentValueReserved);
+ *u8RSExtensionBlockLength -= 2;
+ break;
+ default:
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, *u8RSExtensionBlockLength, "UserData");
+ *u8RSExtensionBlockLength = 0;
+ break;
+ }
+ return offset;
+}
+
+/* dissect the RS_EventDataExtension */
+static int
+dissect_RS_EventDataExtension(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint8 *drep, guint16 *u16RSBlockLength, guint16 *u16RSBlockType)
+{
+ guint8 u8RSExtensionBlockType;
+ guint8 u8RSExtensionBlockLength;
+
+ /* RS_ExtensionBlockType */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rs_extension_block_type, &u8RSExtensionBlockType);
+ *u16RSBlockLength -= 1;
+
+ /* RS_ExtensionBlockLength */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rs_extension_block_length, &u8RSExtensionBlockLength);
+ *u16RSBlockLength -= 1;
+
+ /* Data*[Padding] * a*/
+ while (u8RSExtensionBlockLength) {
+ *u16RSBlockLength -= u8RSExtensionBlockLength;
+ offset = dissect_RS_EventDataExtension_Data(tvb, offset, pinfo, tree, drep,
+ &u8RSExtensionBlockLength, u16RSBlockType);
+ }
+
+ return offset;
+}
+
+/* dissect the RS_EventData */
+static int
+dissect_RS_EventData(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep,
+ guint16 *u16RSBodyLength, guint16 *u16RSBlockType)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* RS_EventDataCommon */
+ offset = dissect_RS_EventDataCommon(tvb, offset, pinfo, tree, drep, u16RSBodyLength);
+
+ /* optional: RS_EventDataExtension */
+ while (*u16RSBodyLength > 0) {
+ sub_item = proto_tree_add_item(tree, hf_pn_io_rs_event_data_extension, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_rs_event_data_extension);
+ offset = dissect_RS_EventDataExtension(tvb, offset, pinfo, sub_tree, drep,
+ u16RSBodyLength, u16RSBlockType);
+ }
+
+ return offset;
+}
+
+/* dissect the RS_EventBlock */
+static int
+dissect_RS_EventBlock(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ guint16 u16RSBodyLength;
+ guint16 u16RSBlockType;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_rs_event_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_rs_event_block);
+
+ /* RS_BlockHeader */
+ offset = dissect_RS_BlockHeader(tvb, offset, pinfo, sub_tree, sub_item, drep,
+ &u16RSBodyLength, &u16RSBlockType);
+
+ /* RS_EventData */
+ offset = dissect_RS_EventData(tvb, offset, pinfo, sub_tree, drep,
+ &u16RSBodyLength, &u16RSBlockType);
+ return offset;
+}
+
+/* dissect the RS_AlarmInfo */
+static int
+dissect_RS_AlarmInfo(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16RSAlarmInfo;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_rs_alarm_info, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_rs_alarm_info);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_rs_alarm_info_reserved_0_7, &u16RSAlarmInfo);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_rs_alarm_info_reserved_8_15, &u16RSAlarmInfo);
+
+ return offset;
+}
+
+/* dissect the RS_EventInfo */
+static int
+dissect_RS_EventInfo(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16NumberofEntries;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_rs_event_info, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_rs_event_info);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_number_of_rs_event_info, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+ offset = dissect_RS_EventBlock(tvb, offset, pinfo, sub_tree, drep);
+ }
+ return offset;
+}
+
+static int
+dissect_Diagnosis(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, proto_item *item, guint8 *drep, guint16 u16UserStructureIdentifier)
+{
+ guint16 u16ChannelNumber;
+ guint16 u16ChannelErrorType;
+ guint16 u16ExtChannelErrorType;
+ guint32 u32ExtChannelAddValue;
+ guint32 u32QualifiedChannelQualifier;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_channel_number, &u16ChannelNumber);
+
+ offset = dissect_ChannelProperties(tvb, offset, pinfo, tree, item, drep);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_channel_error_type, &u16ChannelErrorType);
+
+ if (u16UserStructureIdentifier == 0x8000) /* ChannelDiagnosisData */
+ {
+ return offset;
+ }
+
+ if (u16ChannelErrorType < 0x7fff)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x8000)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8000, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x8001)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8001, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x8002)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8002, &u16ExtChannelErrorType);
+ }
+ else if ((u16ChannelErrorType == 0x8003)||(u16ChannelErrorType == 0x8009))
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8003, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x8004)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8004, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x8005)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8005, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x8007)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8007, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x8008)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8008, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x800A)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x800A, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x800B)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x800B, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x800C)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x800C, &u16ExtChannelErrorType);
+ }
+ else if (u16ChannelErrorType == 0x8010)
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type0x8010, &u16ExtChannelErrorType);
+ }
+ else
+ {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_error_type, &u16ExtChannelErrorType);
+ }
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ext_channel_add_value, &u32ExtChannelAddValue);
+
+ if (u16UserStructureIdentifier == 0x8002) /* ExtChannelDiagnosisData */
+ {
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_qualified_channel_qualifier, &u32QualifiedChannelQualifier);
+
+ /* QualifiedChannelDiagnosisData */
+ return offset;
+}
+
+static int
+dissect_AlarmUserStructure(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+ guint16 *body_length, guint16 u16UserStructureIdentifier)
+{
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+
+ switch (u16UserStructureIdentifier) {
+ case(0x8000): /* ChannelDiagnosisData */
+ offset = dissect_Diagnosis(tvb, offset, pinfo, tree, item, drep,
+ u16UserStructureIdentifier);
+ *body_length -= 6;
+ break;
+ case(0x8002): /* ExtChannelDiagnosisData */
+ offset = dissect_Diagnosis(tvb, offset, pinfo, tree, item, drep,
+ u16UserStructureIdentifier);
+ *body_length -= 12;
+ break;
+ case (0x8003): /* QualifiedChannelDiagnosisData */
+ offset = dissect_Diagnosis(tvb, offset, pinfo, tree, item, drep,
+ u16UserStructureIdentifier);
+ *body_length -= 16;
+ break;
+ case(0x8100): /* MaintenanceItem */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ *body_length -= 12;
+ break;
+ case(0x8300): /* RS_AlarmInfo (Reporting System Alarm Information) */
+ case(0x8301): /* RS_AlarmInfo */
+ case(0x8302): /* RS_AlarmInfo */
+ offset = dissect_RS_AlarmInfo(tvb, offset, pinfo, tree, drep);
+ *body_length = 0;
+ break;
+ case(0x8303): /* RS_EventInfo (Reporting System Event Information) */
+ offset = dissect_RS_EventInfo(tvb, offset, pinfo, tree, drep);
+ *body_length = 0;
+ break;
+ case(0x8310): /* PE_EnergySavingStatus */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ *body_length = 0;
+ break;
+ /* XXX - dissect remaining user structures of [AlarmItem] */
+ case(0x8001): /* DiagnosisData */
+ default:
+ if (u16UserStructureIdentifier >= 0x8000) {
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, *body_length);
+ } else {
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, *body_length, "UserData");
+ }
+
+ *body_length = 0;
+ }
+
+ return offset;
+}
+
+
+
+/* dissect the alarm notification block */
+static int
+dissect_AlarmNotification_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 body_length)
+{
+ guint32 u32ModuleIdentNumber;
+ guint32 u32SubmoduleIdentNumber;
+ guint16 u16UserStructureIdentifier;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_Alarm_header(tvb, offset, pinfo, tree, item, drep);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
+
+ offset = dissect_Alarm_specifier(tvb, offset, pinfo, tree, drep);
+
+ proto_item_append_text(item, ", Ident:0x%x, SubIdent:0x%x",
+ u32ModuleIdentNumber, u32SubmoduleIdentNumber);
+
+ body_length -= 20;
+
+ /* the rest of the block contains optional: [MaintenanceItem] and/or [AlarmItem] */
+ while (body_length) {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_user_structure_identifier, &u16UserStructureIdentifier);
+ proto_item_append_text(item, ", USI:0x%x", u16UserStructureIdentifier);
+ body_length -= 2;
+
+ offset = dissect_AlarmUserStructure(tvb, offset, pinfo, tree, item, drep, &body_length, u16UserStructureIdentifier);
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_IandM0_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint8 u8VendorIDHigh;
+ guint8 u8VendorIDLow;
+ guint16 u16IMHardwareRevision;
+ guint8 u8SWRevisionPrefix;
+ guint8 u8IMSWRevisionFunctionalEnhancement;
+ guint8 u8IMSWRevisionBugFix;
+ guint8 u8IMSWRevisionInternalChange;
+ guint16 u16IMRevisionCounter;
+ guint16 u16IMProfileID;
+ guint16 u16IMProfileSpecificType;
+ guint8 u8IMVersionMajor;
+ guint8 u8IMVersionMinor;
+ guint16 u16IMSupported;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* x8 VendorIDHigh */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_vendor_id_high, &u8VendorIDHigh);
+ /* x8 VendorIDLow */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_vendor_id_low, &u8VendorIDLow);
+ /* c8[20] OrderID */
+ proto_tree_add_item (tree, hf_pn_io_order_id, tvb, offset, 20, ENC_ASCII);
+ offset += 20;
+
+ /* c8[16] IM_Serial_Number */
+ proto_tree_add_item (tree, hf_pn_io_im_serial_number, tvb, offset, 16, ENC_ASCII);
+ offset += 16;
+
+ /* x16 IM_Hardware_Revision */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_hardware_revision, &u16IMHardwareRevision);
+ /* c8 SWRevisionPrefix */
+ offset = dissect_dcerpc_char(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_revision_prefix, &u8SWRevisionPrefix);
+ /* x8 IM_SWRevision_Functional_Enhancement */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_sw_revision_functional_enhancement, &u8IMSWRevisionFunctionalEnhancement);
+ /* x8 IM_SWRevision_Bug_Fix */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_revision_bugfix, &u8IMSWRevisionBugFix);
+ /* x8 IM_SWRevision_Internal_Change */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_sw_revision_internal_change, &u8IMSWRevisionInternalChange);
+ /* x16 IM_Revision_Counter */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_revision_counter, &u16IMRevisionCounter);
+ /* x16 IM_Profile_ID */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_profile_id, &u16IMProfileID);
+ /* x16 IM_Profile_Specific_Type */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_profile_specific_type, &u16IMProfileSpecificType);
+ /* x8 IM_Version_Major (values) */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_version_major, &u8IMVersionMajor);
+ /* x8 IM_Version_Minor (values) */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_version_minor, &u8IMVersionMinor);
+ /* x16 IM_Supported (bitfield) */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_supported, &u16IMSupported);
+
+ return offset;
+}
+
+
+static int
+dissect_IandM1_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ char *pTagFunction;
+ char *pTagLocation;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* IM_Tag_Function [32] */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_io_im_tag_function, tvb, offset, 32, ENC_ASCII, pinfo->pool, &pTagFunction);
+ offset += 32;
+
+ /* IM_Tag_Location [22] */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_io_im_tag_location, tvb, offset, 22, ENC_ASCII, pinfo->pool, &pTagLocation);
+ offset += 22;
+
+ proto_item_append_text(item, ": TagFunction:\"%s\", TagLocation:\"%s\"", pTagFunction, pTagLocation);
+
+ return offset;
+}
+
+
+static int
+dissect_IandM2_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ char *pDate;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* IM_Date [16] */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_io_im_date, tvb, offset, 16, ENC_ASCII, pinfo->pool, &pDate);
+ offset += 16;
+
+ proto_item_append_text(item, ": Date:\"%s\"", pDate);
+
+ return offset;
+}
+
+
+static int
+dissect_IandM3_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ char *pDescriptor;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* IM_Descriptor [54] */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_io_im_descriptor, tvb, offset, 54, ENC_ASCII, pinfo->pool, &pDescriptor);
+ offset += 54;
+
+ proto_item_append_text(item, ": Descriptor:\"%s\"", pDescriptor);
+
+ return offset;
+}
+
+
+static int
+dissect_IandM4_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ dissect_pn_user_data(tvb, offset, pinfo, tree, 54, "IM Signature");
+
+ return offset;
+}
+
+static int
+dissect_IandM5_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberofEntries;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_im_numberofentries, &u16NumberofEntries);
+
+ while(u16NumberofEntries > 0) {
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+ u16NumberofEntries--;
+ }
+ return offset;
+}
+
+static int
+dissect_IandM0FilterData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberOfAPIs;
+ guint32 u32Api;
+ guint16 u16NumberOfModules;
+ guint16 u16SlotNr;
+ guint32 u32ModuleIdentNumber;
+ guint16 u16NumberOfSubmodules;
+ guint16 u16SubslotNr;
+ guint32 u32SubmoduleIdentNumber;
+ proto_item *subslot_item;
+ proto_tree *subslot_tree;
+ proto_item *module_item;
+ proto_tree *module_tree;
+ guint32 u32ModuleStart;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* NumberOfAPIs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+
+ while (u16NumberOfAPIs--) {
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ /* NumberOfModules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_modules, &u16NumberOfModules);
+
+ while (u16NumberOfModules--) {
+ module_item = proto_tree_add_item(tree, hf_pn_io_subslot, tvb, offset, 6, ENC_NA);
+ module_tree = proto_item_add_subtree(module_item, ett_pn_io_module);
+
+ u32ModuleStart = offset;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* ModuleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
+ /* NumberOfSubmodules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_number_of_submodules, &u16NumberOfSubmodules);
+
+ proto_item_append_text(module_item, ": Slot:%u, Ident:0x%x Submodules:%u",
+ u16SlotNr, u32ModuleIdentNumber, u16NumberOfSubmodules);
+
+ while (u16NumberOfSubmodules--) {
+ subslot_item = proto_tree_add_item(module_tree, hf_pn_io_subslot, tvb, offset, 6, ENC_NA);
+ subslot_tree = proto_item_add_subtree(subslot_item, ett_pn_io_subslot);
+
+ /* SubslotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, subslot_tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* SubmoduleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, subslot_tree, drep,
+ hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
+
+ proto_item_append_text(subslot_item, ": Number:0x%x, Ident:0x%x",
+ u16SubslotNr, u32SubmoduleIdentNumber);
+ }
+
+ proto_item_set_len(module_item, offset-u32ModuleStart);
+ }
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_IandM5Data_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep)
+{
+ guint8 u8VendorIDHigh;
+ guint8 u8VendorIDLow;
+ guint16 u16IMHardwareRevision;
+ guint8 u8SWRevisionPrefix;
+ guint8 u8IMSWRevisionFunctionalEnhancement;
+ guint8 u8IMSWRevisionBugFix;
+ guint8 u8IMSWRevisionInternalChange;
+
+ /* c8[64] IM Annotation */
+ proto_tree_add_item(tree, hf_pn_io_im_annotation, tvb, offset, 64, ENC_ASCII);
+ offset += 64;
+
+ /* c8[64] IM Order ID */
+ proto_tree_add_item(tree, hf_pn_io_im_order_id, tvb, offset, 64, ENC_ASCII);
+ offset += 64;
+
+ /* x8 VendorIDHigh */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_vendor_id_high, &u8VendorIDHigh);
+ /* x8 VendorIDLow */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_vendor_id_low, &u8VendorIDLow);
+
+ /* c8[16] IM Serial Number */
+ proto_tree_add_item(tree, hf_pn_io_im_serial_number, tvb, offset, 16, ENC_ASCII);
+ offset += 16;
+
+ /* x16 IM_Hardware_Revision */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_hardware_revision, &u16IMHardwareRevision);
+ /* c8 SWRevisionPrefix */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_revision_prefix, &u8SWRevisionPrefix);
+ /* x8 IM_SWRevision_Functional_Enhancement */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_sw_revision_functional_enhancement, &u8IMSWRevisionFunctionalEnhancement);
+ /* x8 IM_SWRevision_Bug_Fix */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_revision_bugfix, &u8IMSWRevisionBugFix);
+
+ /* x8 IM_SWRevision_Internal_Change */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_sw_revision_internal_change, &u8IMSWRevisionInternalChange);
+
+ return offset;
+}
+
+static int
+dissect_AM_Location(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint8 am_location_structtype;
+ int bit_offset;
+ guint8 am_location_reserved1;
+ guint16 am_location_begin_slot_number;
+ guint16 am_location_begin_subslot_number;
+ guint16 am_location_end_slot_number;
+ guint16 am_location_end_subslot_number;
+ guint16 am_location_reserved2;
+ guint16 am_location_reserved3;
+ guint16 am_location_reserved4;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_am_location, tvb, offset, 16, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_am_location);
+
+ am_location_structtype = tvb_get_guint8(tvb, offset+15);
+ bit_offset = offset << 3;
+
+ switch (am_location_structtype)
+ {
+ case (0x01):
+
+ /* level 11 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_11, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 10 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_10, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 9 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_9, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 8 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_8, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 7 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_7, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 6 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_6, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 5 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_5, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 4 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_4, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 3 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_3, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 2 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_2, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 1 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_1, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 0 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_level_0, tvb, bit_offset, 10, ENC_BIG_ENDIAN);
+ bit_offset += 10;
+
+ /* level 0 */
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_am_location_structure, tvb, bit_offset, 8, ENC_BIG_ENDIAN);
+
+ offset += 16;
+
+ break;
+ case (0x02):
+ /* Reserved 4 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_reserved4, &am_location_reserved4);
+
+ /* Reserved 3 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_reserved3, &am_location_reserved3);
+
+ /* Reserved 2 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_reserved2, &am_location_reserved2);
+
+ /* EndSubSlotNumber*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_endsubslotnum, &am_location_end_subslot_number);
+
+ /* EndSlotNumber*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_endslotnum, &am_location_end_slot_number);
+
+ /* BeginSubslotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_beginsubslotnum, &am_location_begin_subslot_number);
+
+ /* BeginSlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_beginslotnum, &am_location_begin_slot_number);
+
+ /* Reserved1 */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_reserved1, &am_location_reserved1);
+
+ /* Structure */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_am_location_structure, &am_location_structtype);
+
+ break;
+ default: /* will not execute because of the line preceding the switch */
+ offset += 16;
+ break;
+ }
+
+ return offset;
+}
+
+static int
+dissect_IM_software_revision(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint8 u8SWRevisionPrefix;
+ guint8 u8IMSWRevisionFunctionalEnhancement;
+ guint8 u8IMSWRevisionBugFix;
+ guint8 u8IMSWRevisionInternalChange;
+
+ /* SWRevisionPrefix */
+ offset = dissect_dcerpc_char(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_revision_prefix, &u8SWRevisionPrefix);
+
+ /* IM_SWRevision_Functional_Enhancement */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_sw_revision_functional_enhancement, &u8IMSWRevisionFunctionalEnhancement);
+
+ /* IM_SWRevision_Bug_Fix */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_revision_bugfix, &u8IMSWRevisionBugFix);
+
+ /* IM_SWRevision_Internal_Change */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_sw_revision_internal_change, &u8IMSWRevisionInternalChange);
+
+ return offset;
+}
+
+static int
+dissect_AM_device_identification(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ dcerpc_info di; /* fake dcerpc_info struct */
+ dcerpc_call_value dcv; /* fake dcerpc_call_value struct */
+ guint64 u64AMDeviceIdentificationDeviceSubID;
+ guint64 u64AMDeviceIdentificationDeviceID;
+ guint64 u64AMDeviceIdentificationVendorID;
+ guint64 u64AM_DeviceIdentificationOrganization;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ di.call_data = &dcv;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_am_device_identification, tvb, offset, 8, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_am_device_identification);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_am_device_identification_device_sub_id, &u64AMDeviceIdentificationDeviceSubID);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_am_device_identification_device_id, &u64AMDeviceIdentificationDeviceID);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_am_device_identification_vendor_id, &u64AMDeviceIdentificationVendorID);
+ offset = dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_am_device_identification_organization, &u64AM_DeviceIdentificationOrganization);
+
+ return offset;
+}
+
+static int
+dissect_AM_FullInformation_block(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ e_guid_t IM_UniqueIdentifier;
+ guint16 u16AM_TypeIdentification;
+ guint16 u16IMHardwareRevision;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* align padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* IM_UniqueIdentifier */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_uniqueidentifier, &IM_UniqueIdentifier);
+
+ /* AM_Location */
+ offset = dissect_AM_Location(tvb, offset, pinfo, tree, drep);
+
+ /* IM_Annotation */
+ proto_tree_add_item(tree, hf_pn_io_im_annotation, tvb, offset, 64, ENC_ASCII);
+ offset += 64;
+
+ /* IM_OrderID */
+ proto_tree_add_item(tree, hf_pn_io_im_order_id, tvb, offset, 64, ENC_ASCII);
+ offset += 64;
+
+ /* AM_SoftwareRevision */
+ proto_tree_add_item(tree, hf_pn_io_am_software_revision, tvb, offset, 64, ENC_ASCII);
+ offset += 64;
+
+ /* AM_HardwareRevision */
+ proto_tree_add_item(tree, hf_pn_io_am_hardware_revision, tvb, offset, 64, ENC_ASCII);
+ offset += 64;
+
+ /* IM_Serial_Number */
+ proto_tree_add_item(tree, hf_pn_io_im_serial_number, tvb, offset, 16, ENC_ASCII);
+ offset += 16;
+
+ /* IM_Software_Revision */
+ offset = dissect_IM_software_revision(tvb, offset, pinfo, tree, drep);
+
+ /* AM_DeviceIdentification */
+ offset = dissect_AM_device_identification(tvb, offset, pinfo, tree, drep);
+
+ /* AM_TypeIdentification */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_am_type_identification, &u16AM_TypeIdentification);
+
+ /* IM_Hardware_Revision */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_hardware_revision, &u16IMHardwareRevision);
+
+ return offset;
+}
+
+static int
+dissect_AM_HardwareOnlyInformation_block(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ e_guid_t IM_UniqueIdentifier;
+ guint16 u16AM_TypeIdentification;
+ guint16 u16IMHardwareRevision;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* align padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* IM_UniqueIdentifier */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_uniqueidentifier, &IM_UniqueIdentifier);
+
+ /* AM_Location */
+ offset = dissect_AM_Location(tvb, offset, pinfo, tree, drep);
+
+ /* IM_Annotation */
+ proto_tree_add_item(tree, hf_pn_io_im_annotation, tvb, offset, 64, ENC_ASCII | ENC_NA);
+ offset += 64;
+
+ /* IM_OrderID */
+ proto_tree_add_item(tree, hf_pn_io_im_order_id, tvb, offset, 64, ENC_ASCII | ENC_NA);
+ offset += 64;
+
+ /* AM_HardwareRevision */
+ proto_tree_add_item(tree, hf_pn_io_am_hardware_revision, tvb, offset, 64, ENC_ASCII | ENC_NA);
+ offset += 64;
+
+ /* IM_Serial_Number */
+ proto_tree_add_item(tree, hf_pn_io_im_serial_number, tvb, offset, 16, ENC_ASCII | ENC_NA);
+ offset += 16;
+
+ /* AM_DeviceIdentification */
+ offset = dissect_AM_device_identification(tvb, offset, pinfo, tree, drep);
+
+ /* AM_TypeIdentification */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_am_type_identification, &u16AM_TypeIdentification);
+
+ /* IM_Hardware_Revision */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_hardware_revision, &u16IMHardwareRevision);
+
+ return offset;
+}
+
+static int
+dissect_AM_FirmwareOnlyInformation_block(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ e_guid_t IM_UniqueIdentifier;
+ guint16 u16AM_TypeIdentification;
+ guint16 u16AM_Reserved;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* IM_UniqueIdentifier */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_im_uniqueidentifier, &IM_UniqueIdentifier);
+
+ /* AM_Location */
+ offset = dissect_AM_Location(tvb, offset, pinfo, tree, drep);
+
+ /* IM_Annotation */
+ proto_tree_add_item(tree, hf_pn_io_im_annotation, tvb, offset, 64, ENC_ASCII | ENC_NA);
+ offset += 64;
+
+ /* IM_OrderID */
+ proto_tree_add_item(tree, hf_pn_io_im_order_id, tvb, offset, 64, ENC_ASCII | ENC_NA);
+ offset += 64;
+
+ /* AM_SoftwareRevision */
+ proto_tree_add_item(tree, hf_pn_io_am_software_revision, tvb, offset, 64, ENC_ASCII | ENC_NA);
+ offset += 64;
+
+ /* IM_Serial_Number */
+ proto_tree_add_item(tree, hf_pn_io_im_serial_number, tvb, offset, 16, ENC_ASCII | ENC_NA);
+ offset += 16;
+
+ /* IM_Software_Revision */
+ offset = dissect_IM_software_revision(tvb, offset, pinfo, tree, drep);
+
+ /* AM_DeviceIdentification */
+ offset = dissect_AM_device_identification(tvb, offset, pinfo, tree, drep);
+
+ /* AM_TypeIdentification */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_am_type_identification, &u16AM_TypeIdentification);
+
+ /* AM_Reserved */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_am_reserved, &u16AM_Reserved);
+
+ return offset;
+}
+
+/* dissect the AssetManagementInfo */
+static int
+dissect_AssetManagementInfo(tvbuff_t *tvb, int offset,
+packet_info *pinfo _U_, proto_tree *tree, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16NumberofEntries;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_asset_management_info, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_asset_management_info);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_number_of_asset_management_info, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+ offset = dissect_a_block(tvb, offset, pinfo, sub_tree, drep);
+ }
+ return offset;
+}
+
+/* dissect the AssetManagementData block */
+static int
+dissect_AssetManagementData_block(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ offset = dissect_AssetManagementInfo(tvb, offset, pinfo, tree, drep);
+ return offset;
+}
+
+/* dissect the IdentificationData block */
+static int
+dissect_IdentificationData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberOfAPIs = 1;
+ guint32 u32Api;
+ guint16 u16NumberOfSlots;
+ guint16 u16SlotNr;
+ guint32 u32ModuleIdentNumber;
+ guint16 u16NumberOfSubslots;
+ guint32 u32SubmoduleIdentNumber;
+ guint16 u16SubslotNr;
+ proto_item *slot_item;
+ proto_tree *slot_tree;
+ guint32 u32SlotStart;
+ proto_item *subslot_item;
+ proto_tree *subslot_tree;
+
+
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ if (u8BlockVersionLow == 1) {
+ /* NumberOfAPIs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+ }
+
+ proto_item_append_text(item, ": APIs:%u", u16NumberOfAPIs);
+
+ while (u16NumberOfAPIs--) {
+ if (u8BlockVersionLow == 1) {
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ }
+
+ /* NumberOfSlots */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_slots, &u16NumberOfSlots);
+
+ proto_item_append_text(item, ", Slots:%u", u16NumberOfSlots);
+
+ while (u16NumberOfSlots--) {
+ slot_item = proto_tree_add_item(tree, hf_pn_io_slot, tvb, offset, 0, ENC_NA);
+ slot_tree = proto_item_add_subtree(slot_item, ett_pn_io_slot);
+ u32SlotStart = offset;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, slot_tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* ModuleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, slot_tree, drep,
+ hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
+ /* NumberOfSubslots */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, slot_tree, drep,
+ hf_pn_io_number_of_subslots, &u16NumberOfSubslots);
+
+ proto_item_append_text(slot_item, ": SlotNr:%u Ident:0x%x Subslots:%u",
+ u16SlotNr, u32ModuleIdentNumber, u16NumberOfSubslots);
+
+ while (u16NumberOfSubslots--) {
+ subslot_item = proto_tree_add_item(slot_tree, hf_pn_io_subslot, tvb, offset, 6, ENC_NA);
+ subslot_tree = proto_item_add_subtree(subslot_item, ett_pn_io_subslot);
+
+ /* SubslotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, subslot_tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* SubmoduleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, subslot_tree, drep,
+ hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
+
+ proto_item_append_text(subslot_item, ": Number:0x%x, Ident:0x%x",
+ u16SubslotNr, u32SubmoduleIdentNumber);
+ }
+
+ proto_item_set_len(slot_item, offset-u32SlotStart);
+ }
+ }
+
+ return offset;
+}
+
+
+/* dissect the substitute value block */
+static int
+dissect_SubstituteValue_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint16 u16SubstitutionMode;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* SubstitutionMode */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_substitutionmode, &u16SubstitutionMode);
+
+
+ /* SubstituteDataItem */
+ /* IOCS */
+ offset = dissect_PNIO_IOxS(tvb, offset, pinfo, tree, drep, hf_pn_io_iocs);
+ u16BodyLength -= 3;
+ /* SubstituteDataObjectElement */
+ dissect_pn_user_data_bytes(tvb, offset, pinfo, tree, u16BodyLength, SUBST_DATA);
+
+ return offset;
+}
+
+
+/* dissect the RecordInputDataObjectElement block */
+static int
+dissect_RecordInputDataObjectElement_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint8 u8LengthIOCS;
+ guint8 u8LengthIOPS;
+ guint16 u16LengthData;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* LengthIOCS */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_iocs, &u8LengthIOCS);
+ /* IOCS */
+ offset = dissect_PNIO_IOxS(tvb, offset, pinfo, tree, drep, hf_pn_io_iocs);
+ /* LengthIOPS */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_iops, &u8LengthIOPS);
+ /* IOPS */
+ offset = dissect_PNIO_IOxS(tvb, offset, pinfo, tree, drep, hf_pn_io_iops);
+ /* LengthData */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_data, &u16LengthData);
+ /* Data */
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, u16LengthData, "Data");
+
+ return offset;
+}
+
+
+/* dissect the RecordOutputDataObjectElement block */
+static int
+dissect_RecordOutputDataObjectElement_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16SubstituteActiveFlag;
+ guint8 u8LengthIOCS;
+ guint8 u8LengthIOPS;
+ guint16 u16LengthData;
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* SubstituteActiveFlag */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_substitute_active_flag, &u16SubstituteActiveFlag);
+
+ /* LengthIOCS */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_iocs, &u8LengthIOCS);
+ /* LengthIOPS */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_iops, &u8LengthIOPS);
+ /* LengthData */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_data, &u16LengthData);
+ /* DataItem (IOCS, Data, IOPS) */
+ offset = dissect_PNIO_IOxS(tvb, offset, pinfo, tree, drep, hf_pn_io_iocs);
+
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, u16LengthData, "Data");
+
+ offset = dissect_PNIO_IOxS(tvb, offset, pinfo, tree, drep, hf_pn_io_iops);
+
+ /* SubstituteValue */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+
+ return offset;
+}
+
+
+/* dissect the alarm acknowledge block */
+static int
+dissect_Alarm_ack_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ col_append_str(pinfo->cinfo, COL_INFO, ", Alarm Ack");
+
+ offset = dissect_Alarm_header(tvb, offset, pinfo, tree, item, drep);
+
+ offset = dissect_Alarm_specifier(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect the maintenance block */
+static int
+dissect_Maintenance_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32MaintenanceStatus;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_maintenance_status, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_maintenance_status);
+
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_maintenance_status_demanded, &u32MaintenanceStatus);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_maintenance_status_required, &u32MaintenanceStatus);
+
+ if (u32MaintenanceStatus & 0x0002) {
+ proto_item_append_text(item, ", Demanded");
+ proto_item_append_text(sub_item, ", Demanded");
+ }
+
+ if (u32MaintenanceStatus & 0x0001) {
+ proto_item_append_text(item, ", Required");
+ proto_item_append_text(sub_item, ", Required");
+ }
+
+ return offset;
+}
+
+/* dissect the pe_alarm block */
+static int
+dissect_PE_Alarm_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint8 u8PEOperationalMode;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_pe_operational_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pe_operational_mode);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pe_operational_mode, &u8PEOperationalMode);
+
+ return offset;
+
+}
+
+/* dissect the read/write header */
+static int
+dissect_ReadWrite_header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, e_guid_t *aruuid)
+{
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16SeqNr;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_seq_number, &u16SeqNr);
+
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_uuid, aruuid);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* padding doesn't match offset required for align4 */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_index, u16Index);
+
+ proto_item_append_text(item, ": Seq:%u, Api:0x%x, Slot:0x%x/0x%x",
+ u16SeqNr, u32Api, u16SlotNr, u16SubslotNr);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Api:0x%x, Slot:0x%x/0x%x, Index:%s",
+ u32Api, u16SlotNr, u16SubslotNr,
+ val_to_str(*u16Index, pn_io_index, "(0x%x)"));
+
+ return offset;
+}
+
+
+/* dissect the write request block */
+static int
+dissect_IODWriteReqHeader_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t ** ar)
+{
+ e_guid_t aruuid;
+ e_guid_t null_uuid;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, item, drep, u16Index, &aruuid);
+
+ /* The value NIL indicates the usage of the implicit AR*/
+ *ar = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_record_data_length, u32RecDataLen);
+
+ memset(&null_uuid, 0, sizeof(e_guid_t));
+ if (memcmp(&aruuid, &null_uuid, sizeof (e_guid_t)) == 0) {
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_target_ar_uuid, &aruuid);
+ }
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 24);
+
+ proto_item_append_text(item, ", Len:%u", *u32RecDataLen);
+
+ if (*u32RecDataLen != 0)
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %u bytes",
+ *u32RecDataLen);
+
+ return offset;
+}
+
+
+/* dissect the read request block */
+static int
+dissect_IODReadReqHeader_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
+{
+ e_guid_t aruuid;
+ e_guid_t null_uuid;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, item, drep, u16Index, &aruuid);
+
+ /* The value NIL indicates the usage of the implicit AR*/
+ *ar = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_record_data_length, u32RecDataLen);
+
+ memset(&null_uuid, 0, sizeof(e_guid_t));
+ if (memcmp(&aruuid, &null_uuid, sizeof (e_guid_t)) == 0) {
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_target_ar_uuid, &aruuid);
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 8);
+ } else {
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 24);
+ }
+
+ proto_item_append_text(item, ", Len:%u", *u32RecDataLen);
+
+ if (*u32RecDataLen != 0)
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %u bytes",
+ *u32RecDataLen);
+
+ return offset;
+}
+
+
+/* dissect the write response block */
+static int
+dissect_IODWriteResHeader_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
+{
+ e_guid_t aruuid;
+ guint16 u16AddVal1;
+ guint16 u16AddVal2;
+ guint32 u32Status;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, item, drep, u16Index, &aruuid);
+
+ /* The value NIL indicates the usage of the implicit AR*/
+ *ar = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_record_data_length, u32RecDataLen);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_add_val1, &u16AddVal1);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_add_val2, &u16AddVal2);
+
+ u32Status = ((drep[0] & DREP_LITTLE_ENDIAN)
+ ? tvb_get_letohl (tvb, offset)
+ : tvb_get_ntohl (tvb, offset));
+
+ offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 16);
+
+ proto_item_append_text(item, ", Len:%u, Index:0x%x, Status:0x%x, Val1:%u, Val2:%u",
+ *u32RecDataLen, *u16Index, u32Status, u16AddVal1, u16AddVal2);
+
+ if (*u32RecDataLen != 0)
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %u bytes",
+ *u32RecDataLen);
+
+ return offset;
+}
+
+
+/* dissect the read response block */
+static int
+dissect_IODReadResHeader_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
+{
+ e_guid_t aruuid;
+ guint16 u16AddVal1;
+ guint16 u16AddVal2;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, item, drep, u16Index, &aruuid);
+
+ /* The value NIL indicates the usage of the implicit AR*/
+ *ar = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_record_data_length, u32RecDataLen);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_add_val1, &u16AddVal1);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_add_val2, &u16AddVal2);
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 20);
+
+ proto_item_append_text(item, ", Len:%u, AddVal1:%u, AddVal2:%u",
+ *u32RecDataLen, u16AddVal1, u16AddVal2);
+
+ if (*u32RecDataLen != 0)
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %u bytes",
+ *u32RecDataLen);
+
+ return offset;
+}
+
+
+/* dissect the control/connect and control/connect block */
+static int
+dissect_ControlPlugOrConnect_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ pnio_ar_t **ar, guint16 blocktype)
+{
+ e_guid_t ar_uuid;
+ guint16 u16SessionKey;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16Command;
+ guint16 u16Properties;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reserved16, NULL);
+
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_uuid, &ar_uuid);
+
+ /* The value NIL indicates the usage of the implicit AR*/
+ *ar = pnio_ar_find_by_aruuid(pinfo, &ar_uuid);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sessionkey, &u16SessionKey);
+
+ if (((blocktype & 0x7FFF) == 0x0111) || ((blocktype & 0x7FFF) == 0x0113)) {
+ /* control/plug */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_control_alarm_sequence_number, NULL);
+ } else {
+ /* control/connect */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reserved16, NULL);
+ }
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_control_command, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_control_command);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_prmend, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_applready, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_release, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_done, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_ready_for_companion, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_ready_for_rt_class3, &u16Command);
+ /* Prm.Begin */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_prmbegin, &u16Command);
+
+ if (u16Command & 0x0002) {
+ /* ApplicationReady: special decode */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_control_block_properties_applready, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_control_block_properties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_control_block_properties_applready_bit0, &u16Properties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_control_block_properties_applready_bit1, &u16Properties);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_control_block_properties_applready_otherbits, &u16Properties);
+ } else {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_control_block_properties, &u16Properties);
+ }
+
+ proto_item_append_text(item, ": Session:%u, Command:", u16SessionKey);
+
+ if (u16Command & 0x0001) {
+ proto_item_append_text(sub_item, ", ParameterEnd");
+ proto_item_append_text(item, " ParameterEnd");
+ col_append_str(pinfo->cinfo, COL_INFO, ", Command: ParameterEnd");
+ }
+ if (u16Command & 0x0002) {
+ proto_item_append_text(sub_item, ", ApplicationReady");
+ proto_item_append_text(item, " ApplicationReady");
+ col_append_str(pinfo->cinfo, COL_INFO, ", Command: ApplicationReady");
+ }
+ if (u16Command & 0x0004) {
+ proto_item_append_text(sub_item, ", Release");
+ proto_item_append_text(item, " Release");
+ col_append_str(pinfo->cinfo, COL_INFO, ", Command: Release");
+ }
+ if (u16Command & 0x0008) {
+ proto_item_append_text(sub_item, ", Done");
+ proto_item_append_text(item, ", Done");
+ col_append_str(pinfo->cinfo, COL_INFO, ", Command: Done");
+
+ /* When Release Command Done, keep the release frame of corresponding ar & ar uuid */
+ if (!PINFO_FD_VISITED(pinfo) && blocktype == 0x8114) {
+
+ wmem_list_frame_t* aruuid_frame;
+ ARUUIDFrame* current_aruuid_frame = NULL;
+
+ if (aruuid_frame_setup_list != NULL) {
+ for (aruuid_frame = wmem_list_head(aruuid_frame_setup_list); aruuid_frame != NULL; aruuid_frame = wmem_list_frame_next(aruuid_frame)) {
+ current_aruuid_frame = (ARUUIDFrame*)wmem_list_frame_data(aruuid_frame);
+ if (current_aruuid_frame->aruuid.data1 == ar_uuid.data1) {
+ current_aruuid_frame->releaseframe = pinfo->num;
+ }
+ }
+ }
+ }
+ }
+
+ proto_item_append_text(item, ", Properties:0x%x", u16Properties);
+
+ return offset;
+}
+
+/* dissect the ControlBlockPrmBegin block */
+static int
+dissect_ControlBlockPrmBegin(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint32 u32RecDataLen,
+ pnio_ar_t **ar)
+{
+ e_guid_t ar_uuid;
+ guint16 u16SessionKey;
+ guint16 u16Command;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ if (u32RecDataLen != 28-2) /* must be 28 see specification (version already dissected) */
+ {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_length, "Block length of %u is invalid!", u32RecDataLen);
+ return offset;
+ }
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* ARUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep, hf_pn_io_ar_uuid, &ar_uuid);
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ pn_init_append_aruuid_frame_setup_list(ar_uuid, pinfo->num);
+ }
+
+ /* The value NIL indicates the usage of the implicit AR*/
+ *ar = pnio_ar_find_by_aruuid(pinfo, &ar_uuid);
+
+ /* SessionKey */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_sessionkey, &u16SessionKey);
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* ControlCommand */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_control_command, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_control_command);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_prmend, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_applready, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_release, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_done, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_ready_for_companion, &u16Command);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_ready_for_rt_class3, &u16Command);
+ /* Prm.Begin */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_prmbegin, &u16Command);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_reserved_7_15, &u16Command);
+
+ /* ControlBlockProperties.reserved */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_control_command_reserved, NULL);
+ return offset;
+}
+
+/* dissect the SubmoduleListBlock block */
+static int
+dissect_SubmoduleListBlock(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint32 u32RecDataLen _U_,
+ pnio_ar_t **ar _U_)
+{
+ guint16 u16Entries;
+ guint32 u32API;
+ guint16 u16SlotNumber;
+ guint16 u16SubSlotNumber;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_SubmoduleListEntries, &u16Entries);
+
+ while (u16Entries --)
+ {
+ /*API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_api, &u32API);
+ /*SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_slot_nr, &u16SlotNumber);
+ /* SubSlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_subslot_nr, &u16SubSlotNumber);
+ }
+ return offset;
+}
+
+
+/* dissect the PDevData block */
+static int
+dissect_PDevData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+/* dissect the AdjustPreambleLength block */
+static int
+dissect_AdjustPreambleLength_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16AdjustProperties;
+ guint16 u16PreambleLength;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* PreambleLength */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_PreambleLength, &u16PreambleLength);
+
+
+ /* AdjustProperties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+
+ return offset;
+}
+
+/* dissect the dissect_CheckMAUTypeExtension_block block */
+static int
+dissect_CheckMAUTypeExtension_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16MauTypeExtension;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* MauTypeExtension */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_mau_type_extension, &u16MauTypeExtension);
+
+ return offset;
+}
+
+/* dissect the PDPortDataAdjust block */
+static int
+dissect_PDPortData_Adjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ tvbuff_t *new_tvb;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ proto_item_append_text(item, ": Slot:0x%x/0x%x", u16SlotNr, u16SubslotNr);
+
+ u16BodyLength -= 6;
+
+ new_tvb = tvb_new_subset_length(tvb, offset, u16BodyLength);
+ dissect_blocks(new_tvb, 0, pinfo, tree, drep);
+ offset += u16BodyLength;
+
+ /* XXX - do we have to free the new_tvb somehow? */
+
+ return offset;
+}
+
+
+/* dissect the PDPortDataCheck blocks */
+static int
+dissect_PDPortData_Check_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ tvbuff_t *new_tvb;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ proto_item_append_text(item, ": Slot:0x%x/0x%x", u16SlotNr, u16SubslotNr);
+
+ u16BodyLength -= 6;
+
+ new_tvb = tvb_new_subset_length(tvb, offset, u16BodyLength);
+ dissect_blocks(new_tvb, 0, pinfo, tree, drep);
+ offset += u16BodyLength;
+
+ /* XXX - do we have to free the new_tvb somehow? */
+
+ return offset;
+}
+
+/* dissect the Line Delay */
+static int
+dissect_Line_Delay(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep,
+ guint32 *u32LineDelayValue)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32FormatIndicator;
+ guint8 isFormatIndicatorEnabled;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_line_delay, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_line_delay);
+
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_line_delay_format_indicator, &u32FormatIndicator);
+
+ isFormatIndicatorEnabled = (guint8)((u32FormatIndicator >> 31) & 0x01);
+ if (isFormatIndicatorEnabled)
+ {
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_cable_delay_value, u32LineDelayValue);
+ }
+ else
+ {
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_line_delay_value, u32LineDelayValue);
+ }
+
+ return offset;
+}
+
+/* dissect the PDPortDataReal blocks */
+static int
+dissect_PDPortDataReal_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint8 u8LengthOwnPortID;
+ char *pOwnPortID;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint8 u8NumberOfPeers;
+ guint8 u8I;
+ guint8 u8LengthPeerPortID;
+ guint8 u8LengthPeerChassisID;
+ guint8 mac[6];
+ char *pPeerChassisId;
+ char *pPeerPortId;
+ guint16 u16MAUType;
+ guint32 u32DomainBoundary;
+ guint32 u32MulticastBoundary;
+ guint8 u8LinkStatePort;
+ guint8 u8LinkStateLink;
+ guint32 u32MediaType;
+ guint32 u32LineDelayValue;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ /* LengthOwnPortID */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_own_port_id, &u8LengthOwnPortID);
+ /* OwnPortID */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_io_own_port_id, tvb, offset, u8LengthOwnPortID, ENC_ASCII, pinfo->pool, &pOwnPortID);
+ offset += u8LengthOwnPortID;
+
+ /* NumberOfPeers */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_peers, &u8NumberOfPeers);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ u8I = u8NumberOfPeers;
+ while (u8I--) {
+ sub_item = proto_tree_add_item(tree, hf_pn_io_neighbor, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_neighbor);
+
+ /* LengthPeerPortID */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_length_peer_port_id, &u8LengthPeerPortID);
+ /* PeerPortID */
+ proto_tree_add_item_ret_display_string (sub_tree, hf_pn_io_peer_port_id, tvb, offset, u8LengthPeerPortID,
+ ENC_ASCII, pinfo->pool, &pPeerPortId);
+
+ offset += u8LengthPeerPortID;
+
+ /* LengthPeerChassisID */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_length_peer_chassis_id, &u8LengthPeerChassisID);
+ /* PeerChassisID */
+ proto_tree_add_item_ret_display_string (sub_tree, hf_pn_io_peer_chassis_id, tvb, offset, u8LengthPeerChassisID,
+ ENC_ASCII, pinfo->pool, &pPeerChassisId);
+
+ offset += u8LengthPeerChassisID;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, sub_tree);
+
+ /* LineDelay */
+ offset = dissect_Line_Delay(tvb, offset, pinfo, sub_tree, drep, &u32LineDelayValue);
+
+ /* PeerMACAddress */
+ offset = dissect_pn_mac(tvb, offset, pinfo, sub_tree,
+ hf_pn_io_peer_macadd, mac);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, sub_tree);
+
+ proto_item_append_text(sub_item, ": %s (%s)", pPeerChassisId, pPeerPortId);
+ }
+
+ /* MAUType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mau_type, &u16MAUType);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* DomainBoundary */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_domain_boundary, &u32DomainBoundary);
+ /* MulticastBoundary */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_multicast_boundary, &u32MulticastBoundary);
+ /* LinkState.Port */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_link_state_port, &u8LinkStatePort);
+ /* LinkState.Link */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_link_state_link, &u8LinkStateLink);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MediaType */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_media_type, &u32MediaType);
+
+ proto_item_append_text(item, ": Slot:0x%x/0x%x, OwnPortID:%s, Peers:%u LinkState.Port:%s LinkState.Link:%s MediaType:%s",
+ u16SlotNr, u16SubslotNr, pOwnPortID, u8NumberOfPeers,
+ val_to_str(u8LinkStatePort, pn_io_link_state_port, "0x%x"),
+ val_to_str(u8LinkStateLink, pn_io_link_state_link, "0x%x"),
+ val_to_str(u32MediaType, pn_io_media_type, "0x%x"));
+
+ return offset;
+}
+
+
+/* dissect the PDPortDataRealExtended blocks */
+static int
+dissect_PDPortDataRealExtended_block(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
+ proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BodyLength)
+{
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+ int endoffset = offset + u16BodyLength;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ proto_item_append_text(item, ": Slot:0x%x/0x%x", u16SlotNr, u16SubslotNr);
+
+ while (endoffset > offset) {
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ u16Index++;
+ }
+
+ return offset;
+}
+
+static int
+dissect_PDInterfaceMrpDataAdjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BodyLength)
+{
+ e_guid_t uuid;
+ guint16 u16Role;
+ guint8 u8LengthDomainName;
+ guint8 u8NumberOfMrpInstances;
+ int endoffset = offset + u16BodyLength;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow > 1) { /* added low version == 1 */
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ if (u8BlockVersionLow == 0) /*dissect LowVersion == 0 */
+ {
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MRP_DomainUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_domain_uuid, &uuid);
+ /* MRP_Role */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_role, &u16Role);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MRP_LengthDomainName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_length_domain_name, &u8LengthDomainName);
+ /* MRP_DomainName */
+ /* XXX - IEC 61158-6-10 Edition 4.0 says, in section 5.2.17.2.4 "Coding
+ of the field MRP_DomainName", that "This field shall be coded as
+ data type OctetString with 1 to 240 octets according to Table 702
+ and 4.3.1.4.15.2."
+
+ It then says, in subsection 4.3.1.4.15.2 "Encoding" of section
+ 4.3.1.4.15 "Coding of the field NameOfStationValue", that "This
+ field shall be coded as data type OctetString with 1 to 240
+ octets. The definition of IETF RFC 5890 and the following syntax
+ applies: ..."
+
+ RFC 5890 means Punycode; should we translate the domain name to
+ UTF-8 and show both the untranslated and translated domain name?
+
+ They don't mention anything about the RFC 1035 encoding of
+ domain names as mentioned in section 3.1 "Name space definitions",
+ with the labels being counted strings; does that mean that this
+ is just an ASCII string to be interpreted as a Punycode Unicode
+ domain name? */
+ proto_tree_add_item (tree, hf_pn_io_mrp_domain_name, tvb, offset, u8LengthDomainName, ENC_ASCII);
+ offset += u8LengthDomainName;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+ while (endoffset > offset)
+ {
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+ }
+ }
+ else if (u8BlockVersionLow == 1) /*dissect LowVersion == 1 */
+ {
+ /* Padding one byte */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ /* Number of Mrp Instances */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_instances, &u8NumberOfMrpInstances);
+ if (u8NumberOfMrpInstances > 0xf) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_mrp_instances, "Number of MrpInstances greater 0x0f is (0x%x)", u8NumberOfMrpInstances);
+ return offset;
+ }
+ while(u8NumberOfMrpInstances > 0)
+ {
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+ u8NumberOfMrpInstances--;
+ }
+ }
+ return offset;
+}
+
+
+static int
+dissect_PDInterfaceMrpDataReal_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BodyLength)
+{
+ e_guid_t uuid;
+ guint16 u16Role;
+ guint16 u16Version;
+ guint8 u8LengthDomainName;
+ guint8 u8NumberOfMrpInstances;
+ int endoffset = offset + u16BodyLength;
+
+ /* added blockversion 1 */
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow > 2) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ if (u8BlockVersionLow < 2) /* dissect low versions 0 and 1 */
+ {
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MRP_DomainUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_domain_uuid, &uuid);
+ /* MRP_Role */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_role, &u16Role);
+
+ if (u8BlockVersionLow == 1) {
+ /* MRP_Version */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_version, &u16Version);
+ }
+ /* MRP_LengthDomainName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_length_domain_name, &u8LengthDomainName);
+ /* MRP_DomainName */
+ /* XXX - see comment earlier about MRP_DomainName */
+ proto_tree_add_item (tree, hf_pn_io_mrp_domain_name, tvb, offset, u8LengthDomainName, ENC_ASCII);
+ offset += u8LengthDomainName;
+
+ if (u8BlockVersionLow == 0) {
+ /* MRP_Version */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_version, &u16Version);
+ }
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ while(endoffset > offset)
+ {
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+ }
+ }
+ else if (u8BlockVersionLow == 2)
+ {
+ /* Padding one byte */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ /* Number of Mrp Instances */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_instances, &u8NumberOfMrpInstances);
+ if (u8NumberOfMrpInstances > 0xf) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_mrp_instances, "Number of MrpInstances greater 0x0f is (0x%x)", u8NumberOfMrpInstances);
+ return offset;
+ }
+ while(u8NumberOfMrpInstances > 0)
+ {
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+ u8NumberOfMrpInstances--;
+ }
+ }
+ return offset;
+}
+
+
+static int
+dissect_PDInterfaceMrpDataCheck_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ e_guid_t uuid;
+ guint32 u32Check;
+ guint8 u8NumberOfMrpInstances;
+
+ /* BlockVersionLow == 1 added */
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow > 1) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ if (u8BlockVersionLow == 0)
+ {
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MRP_DomainUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_domain_uuid, &uuid);
+
+ /* MRP_Check */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check, &u32Check);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check_mrm, &u32Check);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check_mrpdomain, &u32Check);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check_reserved_1, &u32Check);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check_reserved_2, &u32Check);
+ offset +=4; /* MRP_Check (32 bit) done */
+ }
+ else if (u8BlockVersionLow == 1)
+ {
+ /* Padding one byte */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ /* Number of Mrp Instances */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_instances, &u8NumberOfMrpInstances);
+ if (u8NumberOfMrpInstances > 0xf) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_mrp_instances, "Number of MrpInstances greater 0x0f is (0x%x)", u8NumberOfMrpInstances);
+ return offset;
+ }
+ while(u8NumberOfMrpInstances > 0)
+ {
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+ u8NumberOfMrpInstances--;
+ }
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_PDPortMrpData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ e_guid_t uuid;
+ guint8 u8MrpInstance;
+
+ /* added BlockVersionLow == 1 */
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow > 1) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ if (u8BlockVersionLow == 0) {
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+ }
+ else /*if (u8BlockVersionLow == 1) */
+ {
+ /* Padding one byte */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ /* Mrp Instance */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_instance, &u8MrpInstance);
+ }
+ /* MRP_DomainUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_domain_uuid, &uuid);
+ return offset;
+}
+
+
+static int
+dissect_MrpManagerParams_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16Prio;
+ guint16 u16TOPchgT;
+ guint16 u16TOPNRmax;
+ guint16 u16TSTshortT;
+ guint16 u16TSTdefaultT;
+ guint16 u16TSTNRmax;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* MRP_Prio */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_prio, &u16Prio);
+ /* MRP_TOPchgT */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_topchgt, &u16TOPchgT);
+ /* MRP_TOPNRmax */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_topnrmax, &u16TOPNRmax);
+ /* MRP_TSTshortT */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_tstshortt, &u16TSTshortT);
+ /* MRP_TSTdefaultT */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_tstdefaultt, &u16TSTdefaultT);
+ /* MSP_TSTNRmax */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_tstnrmax, &u16TSTNRmax);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+
+static int
+dissect_MrpRTMode(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32RTMode;
+
+
+ /* MRP_RTMode */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_mrp_rtmode, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_mrp_rtmode);
+
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_mrp_rtmode_reserved2, &u32RTMode);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_mrp_rtmode_reserved1, &u32RTMode);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_mrp_rtmode_rtclass3, &u32RTMode);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_mrp_rtmode_rtclass12, &u32RTMode);
+
+ return offset;
+}
+
+
+static int
+dissect_MrpRTModeManagerData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16TSTNRmax;
+ guint16 u16TSTdefaultT;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* MSP_TSTNRmax */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_tstnrmax, &u16TSTNRmax);
+ /* MRP_TSTdefaultT */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_tstdefaultt, &u16TSTdefaultT);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MRP_RTMode */
+ offset = dissect_MrpRTMode(tvb, offset, pinfo, tree, item, drep);
+
+ return offset;
+}
+
+
+static int
+dissect_MrpRingStateData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16RingState;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* MRP_RingState */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_ring_state, &u16RingState);
+
+ return offset;
+}
+
+
+static int
+dissect_MrpRTStateData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16RTState;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* MRP_RTState */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_rt_state, &u16RTState);
+
+ return offset;
+}
+
+
+static int
+dissect_MrpClientParams_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16MRP_LNKdownT;
+ guint16 u16MRP_LNKupT;
+ guint16 u16MRP_LNKNRmax;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* MRP_LNKdownT */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_lnkdownt, &u16MRP_LNKdownT);
+ /* MRP_LNKupT */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_lnkupt, &u16MRP_LNKupT);
+ /* MRP_LNKNRmax u16 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_lnknrmax, &u16MRP_LNKNRmax);
+
+ return offset;
+}
+
+
+static int
+dissect_MrpRTModeClientData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* MRP_RTMode */
+ offset = dissect_MrpRTMode(tvb, offset, pinfo, tree, item, drep);
+
+ return offset;
+}
+
+
+static int
+dissect_CheckSyncDifference_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16CheckSyncMode;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_check_sync_mode, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_check_sync_mode);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_check_sync_mode_reserved, &u16CheckSyncMode);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_check_sync_mode_sync_master, &u16CheckSyncMode);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_check_sync_mode_cable_delay, &u16CheckSyncMode);
+
+
+ proto_item_append_text(sub_item, "CheckSyncMode: SyncMaster:%d, CableDelay:%d",
+ (u16CheckSyncMode >> 1) & 1, u16CheckSyncMode & 1);
+
+ proto_item_append_text(item, " : SyncMaster:%d, CableDelay:%d",
+ (u16CheckSyncMode >> 1) & 1, u16CheckSyncMode & 1);
+
+ return offset;
+}
+
+
+static int
+dissect_CheckMAUTypeDifference_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16MAUTypeMode;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mau_type_mode, &u16MAUTypeMode);
+
+ proto_item_append_text(item, ": MAUTypeMode:%s",
+ val_to_str(u16MAUTypeMode, pn_io_mau_type_mode, "0x%x"));
+
+ return offset;
+}
+
+
+/* dissect the AdjustDomainBoundary blocks */
+static int
+dissect_AdjustDomainBoundary_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32DomainBoundary;
+ guint32 u32DomainBoundaryIngress;
+ guint32 u32DomainBoundaryEgress;
+ guint16 u16AdjustProperties;
+
+
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ switch (u8BlockVersionLow) {
+ case(0):
+ /* DomainBoundary */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_domain_boundary, &u32DomainBoundary);
+ /* AdjustProperties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ proto_item_append_text(item, ": Boundary:0x%x, Properties:0x%x",
+ u32DomainBoundary, u16AdjustProperties);
+
+ break;
+ case(1):
+ /* DomainBoundaryIngress */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_domain_boundary_ingress, &u32DomainBoundaryIngress);
+ /* DomainBoundaryEgress */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_domain_boundary_egress, &u32DomainBoundaryEgress);
+ /* AdjustProperties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ proto_item_append_text(item, ": BoundaryIngress:0x%x, BoundaryEgress:0x%x, Properties:0x%x",
+ u32DomainBoundaryIngress, u32DomainBoundaryEgress, u16AdjustProperties);
+
+ break;
+ default:
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ return offset;
+}
+
+
+/* dissect the AdjustMulticastBoundary blocks */
+static int
+dissect_AdjustMulticastBoundary_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32MulticastBoundary;
+ guint16 u16AdjustProperties;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* Boundary */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_multicast_boundary, &u32MulticastBoundary);
+ /* AdjustProperties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+
+ proto_item_append_text(item, ": Boundary:0x%x, Properties:0x%x",
+ u32MulticastBoundary, u16AdjustProperties);
+
+ return offset;
+}
+
+
+/* dissect the AdjustMAUType block */
+static int
+dissect_AdjustMAUType_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16MAUType;
+ guint16 u16AdjustProperties;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MAUType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mau_type, &u16MAUType);
+ /* AdjustProperties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+
+ proto_item_append_text(item, ": MAUType:%s, Properties:0x%x",
+ val_to_str(u16MAUType, pn_io_mau_type, "0x%x"),
+ u16AdjustProperties);
+
+ return offset;
+}
+
+
+/* dissect the CheckMAUType block */
+static int
+dissect_CheckMAUType_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16MAUType;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* MAUType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mau_type, &u16MAUType);
+
+ proto_item_append_text(item, ": MAUType:%s",
+ val_to_str(u16MAUType, pn_io_mau_type, "0x%x"));
+
+ return offset;
+}
+
+
+/* dissect the CheckLineDelay block */
+static int
+dissect_CheckLineDelay_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32LineDelay;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* LineDelay */
+ offset = dissect_Line_Delay(tvb, offset, pinfo, tree, drep, &u32LineDelay);
+
+ proto_item_append_text(item, ": LineDelay:%uns", u32LineDelay);
+
+ return offset;
+}
+
+
+/* dissect the CheckPeers block */
+static int
+dissect_CheckPeers_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint8 u8NumberOfPeers;
+ guint8 u8I;
+ guint8 u8LengthPeerPortID;
+ guint8 u8LengthPeerChassisID;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* NumberOfPeers */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_peers, &u8NumberOfPeers);
+
+ u8I = u8NumberOfPeers;
+ while (u8I--) {
+ /* LengthPeerPortID */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_peer_port_id, &u8LengthPeerPortID);
+ /* PeerPortID */
+ proto_tree_add_item (tree, hf_pn_io_peer_port_id, tvb, offset, u8LengthPeerPortID, ENC_ASCII);
+ offset += u8LengthPeerPortID;
+
+ /* LengthPeerChassisID */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_peer_chassis_id, &u8LengthPeerChassisID);
+ /* PeerChassisID */
+ proto_tree_add_item (tree, hf_pn_io_peer_chassis_id, tvb, offset, u8LengthPeerChassisID, ENC_ASCII);
+ offset += u8LengthPeerChassisID;
+ }
+
+ proto_item_append_text(item, ": NumberOfPeers:%u", u8NumberOfPeers);
+
+ return offset;
+}
+
+
+/* dissect the AdjustPortState block */
+static int
+dissect_AdjustPortState_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16PortState;
+ guint16 u16AdjustProperties;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* PortState */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_port_state, &u16PortState);
+ /* AdjustProperties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+
+ proto_item_append_text(item, ": PortState:%s, Properties:0x%x",
+ val_to_str(u16PortState, pn_io_port_state, "0x%x"),
+ u16AdjustProperties);
+
+ return offset;
+}
+
+
+/* dissect the CheckPortState block */
+static int
+dissect_CheckPortState_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16PortState;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* PortState */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_port_state, &u16PortState);
+
+ proto_item_append_text(item, ": %s",
+ val_to_str(u16PortState, pn_io_port_state, "0x%x"));
+ return offset;
+}
+
+
+/* dissect the PDPortFODataReal block */
+static int
+dissect_PDPortFODataReal_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint32 u32FiberOpticType;
+ guint32 u32FiberOpticCableType;
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* FiberOpticType */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fiber_optic_type, &u32FiberOpticType);
+
+ /* FiberOpticCableType */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fiber_optic_cable_type, &u32FiberOpticCableType);
+
+ /* optional: FiberOpticManufacturerSpecific */
+ if (u16BodyLength != 10) {
+ dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ }
+
+ return offset;
+}
+
+
+/* dissect the FiberOpticManufacturerSpecific block */
+static int
+dissect_FiberOpticManufacturerSpecific_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint8 u8VendorIDHigh;
+ guint8 u8VendorIDLow;
+ guint16 u16VendorBlockType;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* x8 VendorIDHigh */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_vendor_id_high, &u8VendorIDHigh);
+ /* x8 VendorIDLow */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_vendor_id_low, &u8VendorIDLow);
+
+ /* VendorBlockType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_vendor_block_type, &u16VendorBlockType);
+ /* Data */
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, u16BodyLength-4, "Data");
+
+ return offset;
+}
+
+
+/* dissect the FiberOpticDiagnosisInfo block */
+static int
+dissect_FiberOpticDiagnosisInfo_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32FiberOpticPowerBudget;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* decode the u32FiberOpticPowerBudget better */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_maintenance_required_power_budget, &u32FiberOpticPowerBudget);
+
+ return offset;
+}
+
+/* dissect the AdjustMAUTypeExtension block */
+static int
+dissect_AdjustMAUTypeExtension_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16MauTypeExtension;
+ guint16 u16AdjustProperties;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MauTypeExtension */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_mau_type_extension, &u16MauTypeExtension);
+
+ /* Properties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+
+ return offset;
+}
+
+/* dissect the PDPortFODataAdjust block */
+static int
+dissect_PDPortFODataAdjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32FiberOpticType;
+ guint32 u32FiberOpticCableType;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* FiberOpticType */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fiber_optic_type, &u32FiberOpticType);
+
+ /* FiberOpticCableType */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fiber_optic_cable_type, &u32FiberOpticCableType);
+
+/*
+ proto_item_append_text(item, ": %s",
+ val_to_str(u16PortState, pn_io_port_state, "0x%x"));*/
+
+ return offset;
+}
+
+
+/* dissect the PDPortFODataCheck block */
+static int
+dissect_PDPortFODataCheck_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32FiberOpticPowerBudget;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MaintenanceRequiredPowerBudget */
+ /* XXX - decode the u32FiberOpticPowerBudget better */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_maintenance_required_power_budget, &u32FiberOpticPowerBudget);
+
+ /* MaintenanceDemandedPowerBudget */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_maintenance_demanded_power_budget, &u32FiberOpticPowerBudget);
+
+ /* ErrorPowerBudget */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_error_power_budget, &u32FiberOpticPowerBudget);
+
+/*
+ proto_item_append_text(item, ": %s",
+ val_to_str(u16PortState, pn_io_port_state, "0x%x"));*/
+
+ return offset;
+}
+
+/* dissect the AdjustPeerToPeerBoundary block */
+static int
+dissect_AdjustPeerToPeerBoundary_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32PeerToPeerBoundary;
+ guint16 u16AdjustProperties;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_peer_to_peer_boundary_value, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_peer_to_peer_boundary);
+
+ /* PeerToPeerBoundary.Bit0 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_peer_to_peer_boundary_value_bit0, &u32PeerToPeerBoundary);
+
+ /* PeerToPeerBoundary.Bit1 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_peer_to_peer_boundary_value_bit1, &u32PeerToPeerBoundary);
+
+ /* PeerToPeerBoundary.Bit2 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_peer_to_peer_boundary_value_bit2, &u32PeerToPeerBoundary);
+
+ /* PeerToPeerBoundary.OtherBits */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_peer_to_peer_boundary_value_otherbits, &u32PeerToPeerBoundary);
+
+ /* Properties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+
+ return offset;
+}
+
+
+/* dissect the AdjustDCPBoundary block */
+static int
+dissect_AdjustDCPBoundary_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32DcpBoundary;
+ guint16 u16AdjustProperties;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_dcp_boundary_value, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_dcp_boundary);
+
+ /* DcpBoundary.Bit0 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_dcp_boundary_value_bit0, &u32DcpBoundary);
+
+ /* DcpBoundary.Bit1 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_dcp_boundary_value_bit1, &u32DcpBoundary);
+
+ /* DcpBoundary.OtherBits */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_dcp_boundary_value_otherbits, &u32DcpBoundary);
+
+ /* Properties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_adjust_properties, &u16AdjustProperties);
+
+ return offset;
+}
+
+static int
+dissect_MrpInstanceDataAdjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BodyLength)
+{
+ guint8 u8MrpInstance;
+ e_guid_t uuid;
+ guint16 u16Role;
+ guint8 u8LengthDomainName;
+ int endoffset = offset + u16BodyLength;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ /* Padding one byte */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ /* Mrp Instance */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_instance, &u8MrpInstance);
+ /* MRP_DomainUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_domain_uuid, &uuid);
+ /* MRP_Role */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_role, &u16Role);
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+ /* MRP_LengthDomainName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_length_domain_name, &u8LengthDomainName);
+ /* MRP_DomainName */
+ /* XXX - see comment earlier about MRP_DomainName */
+ proto_tree_add_item (tree, hf_pn_io_mrp_domain_name, tvb, offset, u8LengthDomainName, ENC_ASCII);
+ offset += u8LengthDomainName;
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+ while(endoffset > offset)
+ {
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+ }
+
+ return offset;
+}
+
+static int
+dissect_MrpInstanceDataReal_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BodyLength)
+{
+ guint8 u8MrpInstance;
+ e_guid_t uuid;
+ guint16 u16Role;
+ guint16 u16Version;
+ guint8 u8LengthDomainName;
+ int endoffset = offset + u16BodyLength;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ /* Padding one byte */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ /* Mrp Instance */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_instance, &u8MrpInstance);
+ /* MRP_DomainUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_domain_uuid, &uuid);
+ /* MRP_Role */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_role, &u16Role);
+ /* MRP_Version */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_version, &u16Version);
+ /* MRP_LengthDomainName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_length_domain_name, &u8LengthDomainName);
+ /* MRP_DomainName */
+ /* XXX - see comment earlier about MRP_DomainName */
+ proto_tree_add_item (tree, hf_pn_io_mrp_domain_name, tvb, offset, u8LengthDomainName, ENC_ASCII);
+ offset += u8LengthDomainName;
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ while(endoffset > offset)
+ {
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+ }
+ return offset;
+}
+
+static int
+dissect_MrpInstanceDataCheck_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BodyLength _U_)
+{
+ guint8 u8MrpInstance;
+ guint32 u32Check;
+ e_guid_t uuid;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ /* Padding one byte */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ /* Mrp Instance */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_instance, &u8MrpInstance);
+ /* MRP_DomainUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_domain_uuid, &uuid);
+
+ /* MRP_Check */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check, &u32Check);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check_mrm, &u32Check);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check_mrpdomain, &u32Check);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check_reserved_1, &u32Check);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mrp_check_reserved_2, &u32Check);
+ offset +=4; /* MRP_Check (32 bit) done */
+
+ return offset;
+}
+
+/* PDInterfaceAdjust */
+static int
+dissect_PDInterfaceAdjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32SMultipleInterfaceMode;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+}
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+/* MultipleInterfaceMode */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_MultipleInterfaceMode_NameOfDevice, &u32SMultipleInterfaceMode);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_MultipleInterfaceMode_reserved_1, &u32SMultipleInterfaceMode);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_MultipleInterfaceMode_reserved_2, &u32SMultipleInterfaceMode);
+ return offset;
+}
+
+/* TSNNetworkControlDataReal */
+static int
+dissect_TSNNetworkControlDataReal_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item* sub_item;
+ proto_tree* sub_tree;
+
+ e_guid_t nme_parameter_uuid;
+ guint32 u32NetworkDeadline;
+ guint16 u16SendClockFactor;
+ guint16 u16NumberofEntries;
+ guint16 u16TSNNMENameLength;
+ guint16 u16TSNDomainNameLength;
+ e_guid_t tsn_nme_name_uuid;
+ e_guid_t tsn_domain_uuid;
+
+ int bit_offset;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* NMEParameterUUID*/
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_io_tsn_nme_parameter_uuid, &nme_parameter_uuid);
+
+ /* TSNDomainVIDConfig*/
+ sub_item = proto_tree_add_item(tree, hf_pn_io_tsn_domain_vid_config, tvb, offset, 16, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_tsn_domain_vid_config);
+ bit_offset = offset << 3;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_reserved, tvb, bit_offset, 32, ENC_BIG_ENDIAN);
+ bit_offset += 32;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_non_stream_vid_D, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_non_stream_vid_C, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_non_stream_vid_B, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_non_stream_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_stream_low_red_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_stream_low_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_stream_high_red_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_stream_high_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+
+ offset += 16;
+
+ /* TSNDomainPortConfigBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep);
+
+ /* Network Deadline */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_network_deadline, &u32NetworkDeadline);
+
+ /* SendClockFactor 16 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_send_clock_factor, &u16SendClockFactor);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_number_of_tsn_time_data_block_entries, &u16NumberofEntries);
+
+ /* TSNTimeDataBlock */
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+
+ offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep);
+ }
+
+ /* TSNNMENameUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_io_tsn_nme_name_uuid, &tsn_nme_name_uuid);
+
+ /* TSNNMENameLength */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_tsn_nme_name_length, &u16TSNNMENameLength);
+
+ /* TSNNMEName */
+ proto_tree_add_item(tree, hf_pn_io_tsn_nme_name, tvb, offset, u16TSNNMENameLength, ENC_ASCII | ENC_NA);
+ offset += u16TSNNMENameLength;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* TSNDomainUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_io_tsn_domain_uuid, &tsn_domain_uuid);
+
+ /* TSNDomainNameLength */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_tsn_domain_name_length, &u16TSNDomainNameLength);
+
+ /* TSNDomainName */
+ proto_tree_add_item(tree, hf_pn_io_tsn_domain_name, tvb, offset, u16TSNDomainNameLength, ENC_ASCII | ENC_NA);
+ offset += u16TSNDomainNameLength;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ return offset;
+
+}
+
+/* TSNNetworkControlDataAdjust */
+static int
+dissect_TSNNetworkControlDataAdjust_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item* sub_item;
+ proto_tree* sub_tree;
+
+ e_guid_t nme_parameter_uuid;
+ guint32 u32NetworkDeadline;
+ guint16 u16SendClockFactor;
+ guint16 u16NumberofEntries;
+ guint16 u16TSNNMENameLength;
+ e_guid_t tsn_nme_name_uuid;
+
+ int bit_offset;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* NMEParameterUUID*/
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_io_tsn_nme_parameter_uuid, &nme_parameter_uuid);
+
+ /* TSNDomainVIDConfig*/
+ sub_item = proto_tree_add_item(tree, hf_pn_io_tsn_domain_vid_config, tvb, offset, 16, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_tsn_domain_vid_config);
+
+ bit_offset = offset << 3;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_reserved, tvb, bit_offset, 32, ENC_BIG_ENDIAN);
+ bit_offset += 32;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_non_stream_vid_D, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_non_stream_vid_C, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_non_stream_vid_B, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_non_stream_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_stream_low_red_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_stream_low_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_stream_high_red_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+ bit_offset += 12;
+
+ proto_tree_add_bits_item(sub_tree, hf_pn_io_tsn_domain_vid_config_stream_high_vid, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
+
+ offset += 16;
+
+ /* TSNDomainPortConfigBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep);
+
+ /* Network Deadline */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_network_deadline, &u32NetworkDeadline);
+
+ /* SendClockFactor 16 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_send_clock_factor, &u16SendClockFactor);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_number_of_tsn_time_data_block_entries, &u16NumberofEntries);
+
+ /* TSNTimeDataBlock */
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+
+ offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep);
+ }
+
+ /* TSNNMENameUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_io_tsn_nme_name_uuid, &tsn_nme_name_uuid);
+
+ /* TSNNMENameLength */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_tsn_nme_name_length, &u16TSNNMENameLength);
+
+ /* TSNNMEName */
+ proto_tree_add_item(tree, hf_pn_io_tsn_nme_name, tvb, offset, u16TSNNMENameLength, ENC_ASCII | ENC_NA);
+ offset += u16TSNNMENameLength;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+/* TSNStreamPathData */
+static int
+dissect_TSNStreamPathDataReal_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, gboolean real)
+{
+ guint8 u8FDBCommand;
+ guint16 u16NumberofEntries;
+ guint8 dstAdd[6];
+ guint16 u16StreamClass;
+ guint16 u16SlotNumber;
+ guint16 u16SubSlotNumber;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+
+ if (!real) {
+ /* FDBCommand */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_fdb_command, &u8FDBCommand);
+ }
+ else {
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ }
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_tsn_domain_sync_tree_entries, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+ /* DestinationAddress */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_io_tsn_dst_add, dstAdd);
+
+ /* StreamClass */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_tsn_stream_class, &u16StreamClass);
+
+ /* IngressPort */
+ /* TSNDomainPortID */
+ /*SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_slot_nr, &u16SlotNumber);
+ /* SubSlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_subslot_nr, &u16SubSlotNumber);
+
+ /* EgressPort */
+ /* TSNDomainPortID */
+ /*SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_slot_nr, &u16SlotNumber);
+ /* SubSlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_subslot_nr, &u16SubSlotNumber);
+ }
+ return offset;
+}
+
+/* TSNSyncTreeData */
+static int
+dissect_TSNSyncTreeData_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberofEntries;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16TimeDomainNumber;
+ guint8 u8SyncPortRole;
+ proto_item* sub_item;
+ proto_tree* sub_tree;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_tsn_domain_sync_tree_entries, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+ /* TSNDomainPortID */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_tsn_domain_port_id, tvb, offset, 4, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_tsn_domain_port_id);
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_slot_nr, &u16SlotNr);
+ /*--*/
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* TimeDomainNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_time_domain_number, &u16TimeDomainNumber);
+ /* SyncPortRole */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep, hf_pn_io_tsn_domain_sync_port_role, &u8SyncPortRole);
+
+ /* Padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ }
+ return offset;
+}
+
+/* TSNDomainPortConfigBlock */
+static int
+dissect_TSNDomainPortConfig_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberofEntries;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ proto_item* sub_item_port_config;
+ proto_tree* sub_tree_port_config;
+ guint8 u8TSNDomainPortConfig;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_tsn_domain_port_config_entries, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ /* TSNDomainPortConfig */
+ sub_item_port_config = proto_tree_add_item(tree, hf_pn_io_tsn_domain_port_config, tvb, offset, 1, ENC_NA);
+ sub_tree_port_config = proto_item_add_subtree(sub_item_port_config, ett_pn_io_tsn_domain_port_config);
+
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree_port_config, drep,
+ hf_pn_io_tsn_domain_port_config_reserved, &u8TSNDomainPortConfig);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree_port_config, drep,
+ hf_pn_io_tsn_domain_port_config_boundary_port_config, &u8TSNDomainPortConfig);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree_port_config, drep,
+ hf_pn_io_tsn_domain_port_config_preemption_enabled, &u8TSNDomainPortConfig);
+
+ /* Padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 3);
+
+ /* TSNDomainPortIngressRateLimiter */
+ offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep);
+
+ /* TSNDomainQueueConfigBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep);
+
+ /* TSNDomainQueueRateLimiterBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep);
+ }
+ return offset;
+}
+
+/* TSNDomainQueueConfigBlock */
+static int
+dissect_TSNDomainQueueConfig_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberofEntries;
+ proto_item* sub_item;
+ proto_tree* sub_tree;
+ guint64 u64TSNDomainQueueConfig;
+ dcerpc_info di; /* fake dcerpc_info struct */
+ dcerpc_call_value dcv; /* fake dcerpc_call_value struct */
+ di.call_data = &dcv;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_tsn_domain_queue_config_entries, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_tsn_domain_queue_config, tvb, offset, 8, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_tsn_domain_queue_config);
+
+ /* TSNDomainQueueConfig */
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_config_mask_time_offset, &u64TSNDomainQueueConfig);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_config_unmask_time_offset, &u64TSNDomainQueueConfig);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_config_preemption_mode, &u64TSNDomainQueueConfig);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_config_shaper, &u64TSNDomainQueueConfig);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_config_tci_pcp, &u64TSNDomainQueueConfig);
+ offset = dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_config_queue_id, &u64TSNDomainQueueConfig);
+ }
+ return offset;
+}
+
+/* TSNTimeDataBlock */
+static int
+dissect_TSNTimeData_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16TimeDomainNumber;
+ guint32 u32TimePLLWindow;
+ guint32 u32MessageIntervalFactor;
+ guint16 u16MessageTimeoutFactor;
+ guint16 u16TimeSyncProperties;
+ guint8 u8TimeDomainNameLength;
+ e_guid_t time_domain_uuid;
+ proto_item* sub_item;
+ proto_tree* sub_tree;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* TimeDomainNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_time_domain_number, &u16TimeDomainNumber);
+
+ /* TimePLLWindow */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_time_pll_window, &u32TimePLLWindow);
+
+ /* MessageIntervalFactor */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_message_interval_factor, &u32MessageIntervalFactor);
+
+ /* MessageTimeoutFactor */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_message_timeout_factor, &u16MessageTimeoutFactor);
+
+ /* TimeSyncProperties */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_time_sync_properties, tvb, offset, 2, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_time_sync_properties);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_time_sync_properties_reserved, &u16TimeSyncProperties);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_time_sync_properties_role, &u16TimeSyncProperties);
+
+ /* TimeDomainUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_io_time_domain_uuid, &time_domain_uuid);
+
+ /* TimeDomainNameLength */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep, hf_pn_io_time_domain_name_length, &u8TimeDomainNameLength);
+
+ /* TimeDomainName */
+ proto_tree_add_item(tree, hf_pn_io_time_domain_name, tvb, offset, u8TimeDomainNameLength, ENC_ASCII | ENC_NA);
+ offset += u8TimeDomainNameLength;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+/* TSNUploadNetworkAttributesBlock */
+static int
+dissect_TSNUploadNetworkAttributes_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32TransferTimeTX;
+ guint32 u32TransferTimeRX;
+ guint32 u32MaxSupportedRecordSize;
+
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ /* Align to the next 32 bit twice */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* TSNPortIDBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+
+ /*MaxSupportedRecordSize*/
+ offset= dissect_dcerpc_uint32(tvb,offset,pinfo,tree,drep,hf_pn_io_tsn_max_supported_record_size,&u32MaxSupportedRecordSize);
+
+ /* TransferTimeTX */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_transfer_time_tx, &u32TransferTimeTX);
+
+ /* TransferTimeRX */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_transfer_time_rx, &u32TransferTimeRX);
+
+ /* TSNForwardingDelayBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+/* TSNExpectedNeighborBlock */
+static int
+dissect_TSNExpectedNeighbor_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint8 u8NumberOfPeers;
+ guint8 u8I;
+ guint8 u8LengthPeerPortName;
+ guint8 u8LengthPeerStationName;
+ guint16 u16NumberOfEntries;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint32 u32LineDelayValue;
+
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_tsn_expected_neighbor_block_number_of_entries, &u16NumberOfEntries);
+
+ while (u16NumberOfEntries > 0)
+ {
+ u16NumberOfEntries--;
+
+ /*TSNDomainPortID*/
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_slot_nr, &u16SlotNr);
+ /*--*/
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ /* Padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 3);
+
+ /* NumberOfPeers */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_peers, &u8NumberOfPeers);
+
+ u8I = u8NumberOfPeers;
+ while (u8I--) {
+ /* LengthPeerPortName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_peer_port_name, &u8LengthPeerPortName);
+
+ /* PeerPortName */
+ proto_tree_add_item(tree, hf_pn_io_peer_port_name, tvb, offset, u8LengthPeerPortName, ENC_ASCII | ENC_NA);
+ offset += u8LengthPeerPortName;
+
+ /* LengthPeerStationName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_peer_station_name, &u8LengthPeerStationName);
+
+ /* PeerStationName */
+ proto_tree_add_item(tree, hf_pn_io_peer_station_name, tvb, offset, u8LengthPeerStationName, ENC_ASCII | ENC_NA);
+ offset += u8LengthPeerStationName;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* LineDelay */
+ offset = dissect_Line_Delay(tvb, offset, pinfo, tree, drep, &u32LineDelayValue);
+ }
+ }
+ return offset;
+}
+
+/* TSNExpectedNetworkAttributesBlock */
+static int
+dissect_TSNExpectedNetworkAttributes_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Align to the next 32 bit twice */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* TSNPortIDBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+
+ /* TSNForwardingDelayBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+
+ /* TSNExpectedNeighborBlock */
+ offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+/* TSNDomainPortIngressRateLimiterBlock */
+static int
+dissect_TSNDomainPortIngressRateLimiter_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberofEntries;
+ proto_item* sub_item_port_ingress;
+ proto_tree* sub_tree_port_ingress;
+ guint64 u64TSNDomainPortIngressRateLimiter;
+ dcerpc_info di; /* fake dcerpc_info struct */
+ dcerpc_call_value dcv; /* fake dcerpc_call_value struct */
+ di.call_data = &dcv;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_tsn_domain_port_ingress_rate_limiter_entries, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+
+ /* TSNDomainPortIngressRateLimiter */
+ sub_item_port_ingress = proto_tree_add_item(tree, hf_pn_io_tsn_domain_port_ingress_rate_limiter, tvb, offset, 8, ENC_NA);
+ sub_tree_port_ingress = proto_item_add_subtree(sub_item_port_ingress, ett_pn_io_tsn_domain_port_ingress_rate_limiter);
+
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree_port_ingress, &di, drep,
+ hf_pn_io_tsn_domain_port_ingress_rate_limiter_cir, &u64TSNDomainPortIngressRateLimiter);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree_port_ingress, &di, drep,
+ hf_pn_io_tsn_domain_port_ingress_rate_limiter_cbs, &u64TSNDomainPortIngressRateLimiter);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree_port_ingress, &di, drep,
+ hf_pn_io_tsn_domain_port_ingress_rate_limiter_envelope, &u64TSNDomainPortIngressRateLimiter);
+ offset = dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree_port_ingress, &di, drep,
+ hf_pn_io_tsn_domain_port_ingress_rate_limiter_rank, &u64TSNDomainPortIngressRateLimiter);
+ }
+ return offset;
+}
+
+/* TSNDomainQueueRateLimiterBlock */
+static int
+dissect_TSNDomainQueueRateLimiter_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberofEntries;
+ proto_item* sub_item;
+ proto_tree* sub_tree;
+ guint64 u64TSNDomainQueueRateLimiter;
+ dcerpc_info di; /* fake dcerpc_info struct */
+ dcerpc_call_value dcv; /* fake dcerpc_call_value struct */
+ di.call_data = &dcv;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_tsn_domain_queue_rate_limiter_entries, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+
+ /* TSNDomainQueueRateLimiter */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_tsn_domain_queue_rate_limiter, tvb, offset, 8, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_tsn_domain_queue_rate_limiter);
+
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_rate_limiter_cir, &u64TSNDomainQueueRateLimiter);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_rate_limiter_cbs, &u64TSNDomainQueueRateLimiter);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_rate_limiter_envelope, &u64TSNDomainQueueRateLimiter);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_rate_limiter_rank, &u64TSNDomainQueueRateLimiter);
+ dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_rate_limiter_queue_id, &u64TSNDomainQueueRateLimiter);
+ offset = dissect_dcerpc_uint64(tvb, offset, pinfo, sub_tree, &di, drep,
+ hf_pn_io_tsn_domain_queue_rate_limiter_reserved, &u64TSNDomainQueueRateLimiter);
+ }
+ return offset;
+}
+
+/* TSNPortIDBlock */
+static int
+dissect_TSNPortID_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint8 u8NumberOfQueues;
+ guint8 u8ForwardingGroup;
+ guint8 u8TSNPortCapabilities;
+ guint16 u16NumberOfEntries;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16MAUType;
+ guint16 u16MAUTypeExtension;
+
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_tsn_port_id_block_number_of_entries, &u16NumberOfEntries);
+
+ while (u16NumberOfEntries > 0)
+ {
+ u16NumberOfEntries--;
+
+ /*TSNDomainPortID*/
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_slot_nr, &u16SlotNr);
+ /*--*/
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ /*MAUType*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mau_type, &u16MAUType);
+
+ /*MAUTypeExtension*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mau_type_extension, &u16MAUTypeExtension);
+
+ /* NumberOfQueues */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_number_of_queues, &u8NumberOfQueues);
+
+ /* TSNPortCapabilities */
+ /* bit 0 */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_port_capabilities_time_aware, &u8TSNPortCapabilities);
+
+ /* bit 1 */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_port_capabilities_preemption, &u8TSNPortCapabilities);
+
+ /* bit 2 */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_port_capabilities_queue_masking, &u8TSNPortCapabilities);
+
+ /* bit 3-7 */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_port_capabilities_reserved, &u8TSNPortCapabilities);
+
+ /* ForwardingGroup */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_forwarding_group, &u8ForwardingGroup);
+
+ /* Align to the next 32 bit */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+
+ }
+ return offset;
+}
+
+/* TSNForwardingDelayBlock */
+static int
+dissect_TSNForwardingDelay_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint8 u8ForwardingGroupIngress;
+ guint8 u8ForwardingGroupEgress;
+ guint16 u16NumberOfEntries;
+ guint16 u16StreamClass;
+ guint32 u32DependentForwardingDelay;
+ guint32 u32IndependentForwardingDelay;
+
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_tsn_forwarding_delay_block_number_of_entries, &u16NumberOfEntries);
+
+ while (u16NumberOfEntries > 0)
+ {
+ u16NumberOfEntries--;
+
+ /*ForwardingGroupIngress*/
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_forwarding_group_ingress, &u8ForwardingGroupIngress);
+
+ /*ForwardingGroupEgress*/
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_forwarding_group_egress, &u8ForwardingGroupEgress);
+
+ /* StreamClass */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_stream_class, &u16StreamClass);
+
+ /* DependentForwardingDelay */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_dependent_forwarding_delay, &u32DependentForwardingDelay);
+
+ /* IndependentForwardingDelay */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_tsn_independent_forwarding_delay, &u32IndependentForwardingDelay);
+ }
+ return offset;
+}
+
+/* PDPortStatistic for one subslot */
+static int
+dissect_PDPortStatistic_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32StatValue;
+ guint16 u16CounterStatus;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ switch (u8BlockVersionLow) {
+ case(0):
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+ break;
+ case(1):
+ sub_item = proto_tree_add_item(tree, hf_pn_io_pdportstatistic_counter_status, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_counter_status);
+ /* bit 0 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdportstatistic_counter_status_ifInOctets, &u16CounterStatus);
+ /* bit 1 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdportstatistic_counter_status_ifOutOctets, &u16CounterStatus);
+ /* bit 2 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdportstatistic_counter_status_ifInDiscards, &u16CounterStatus);
+ /* bit 3 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdportstatistic_counter_status_ifOutDiscards, &u16CounterStatus);
+ /* bit 4 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdportstatistic_counter_status_ifInErrors, &u16CounterStatus);
+ /* bit 5 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdportstatistic_counter_status_ifOutErrors, &u16CounterStatus);
+ /* bit 6-15 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdportstatistic_counter_status_reserved, &u16CounterStatus);
+ break;
+ default: /* will not execute because of the line preceding the switch */
+ break;
+ }
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_pdportstatistic_ifInOctets, &u32StatValue);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_pdportstatistic_ifOutOctets, &u32StatValue);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_pdportstatistic_ifInDiscards, &u32StatValue);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_pdportstatistic_ifOutDiscards, &u32StatValue);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_pdportstatistic_ifInErrors, &u32StatValue);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_pdportstatistic_ifOutErrors, &u32StatValue);
+
+ return offset;
+}
+
+/* OwnPort */
+static int
+dissect_OwnPort_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint8 u8LengthOwnPortID;
+ char *pOwnPortID;
+ guint16 u16MAUType;
+ guint16 u16MAUTypeExtension;
+ guint32 u32MulticastBoundary;
+ guint8 u8LinkStatePort;
+ guint8 u8LinkStateLink;
+ guint32 u32MediaType;
+ guint32 u32LineDelayValue;
+ guint16 u16PortStatus;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* LengthOwnPortID */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_own_port_id, &u8LengthOwnPortID);
+ /* OwnPortName */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_io_own_port_id, tvb, offset, u8LengthOwnPortID, ENC_ASCII, pinfo->pool, &pOwnPortID);
+ offset += u8LengthOwnPortID;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* LineDelay */
+ offset = dissect_Line_Delay(tvb, offset, pinfo, tree, drep, &u32LineDelayValue);
+
+ /* MediaType */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_media_type, &u32MediaType);
+
+ /* MulticastBoundary */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_multicast_boundary, &u32MulticastBoundary);
+
+ /* MAUType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mau_type, &u16MAUType);
+
+ /* MAUTypeExtension */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mau_type_extension, &u16MAUTypeExtension);
+
+ /* LinkState.Port */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_link_state_port, &u8LinkStatePort);
+ /* LinkState.Link */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_link_state_link, &u8LinkStateLink);
+
+ /* RTClass3_PortStatus */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rtclass3_port_status, &u16PortStatus);
+
+ proto_item_append_text(item, ": OwnPortID:%s, LinkState.Port:%s LinkState.Link:%s MediaType:%s MAUType:%s",
+ pOwnPortID,
+ val_to_str(u8LinkStatePort, pn_io_link_state_port, "0x%x"),
+ val_to_str(u8LinkStateLink, pn_io_link_state_link, "0x%x"),
+ val_to_str(u32MediaType, pn_io_media_type, "0x%x"),
+ val_to_str(u16MAUType, pn_io_mau_type, "0x%x"));
+
+ return offset;
+}
+
+
+/* Neighbors */
+static int
+dissect_Neighbors_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint8 u8NumberOfPeers;
+ guint8 u8I;
+ guint8 mac[6];
+ char *pPeerStationName;
+ char *pPeerPortName;
+ guint8 u8LengthPeerPortName;
+ guint8 u8LengthPeerStationName;
+ guint16 u16MAUType;
+ guint16 u16MAUTypeExtension;
+ guint32 u32LineDelayValue;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* NumberOfPeers */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_peers, &u8NumberOfPeers);
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ u8I = u8NumberOfPeers;
+ while (u8I--) {
+ sub_item = proto_tree_add_item(tree, hf_pn_io_neighbor, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_neighbor);
+
+ /* LineDelay */
+ offset = dissect_Line_Delay(tvb, offset, pinfo, sub_tree, drep, &u32LineDelayValue);
+
+ /* MAUType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_mau_type, &u16MAUType);
+
+ /* MAUTypeExtension */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_mau_type_extension, &u16MAUTypeExtension);
+
+ /* PeerMACAddress */
+ offset = dissect_pn_mac(tvb, offset, pinfo, sub_tree,
+ hf_pn_io_peer_macadd, mac);
+
+ /* LengthPeerPortName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_length_peer_port_name, &u8LengthPeerPortName);
+ /* PeerPortName */
+ proto_tree_add_item_ret_display_string (sub_tree, hf_pn_io_peer_port_name, tvb, offset, u8LengthPeerPortName,
+ ENC_ASCII, pinfo->pool, &pPeerPortName);
+ offset += u8LengthPeerPortName;
+
+ /* LengthPeerStationName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_length_peer_station_name, &u8LengthPeerStationName);
+ /* PeerStationName */
+ proto_tree_add_item_ret_display_string (sub_tree, hf_pn_io_peer_station_name, tvb, offset, u8LengthPeerStationName,
+ ENC_ASCII, pinfo->pool, &pPeerStationName);
+ offset += u8LengthPeerStationName;
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, sub_tree);
+
+ proto_item_append_text(sub_item, ": %s (%s)", pPeerStationName, pPeerPortName);
+ }
+
+ return offset;
+}
+
+
+/* dissect the PDInterfaceDataReal block */
+static int
+dissect_PDInterfaceDataReal_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint8 u8LengthOwnChassisID;
+ guint8 mac[6];
+ guint32 ip;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* LengthOwnChassisID */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_length_own_chassis_id, &u8LengthOwnChassisID);
+ /* OwnChassisID */
+ proto_tree_add_item (tree, hf_pn_io_own_chassis_id, tvb, offset, u8LengthOwnChassisID, ENC_ASCII);
+ offset += u8LengthOwnChassisID;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* MACAddressValue */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_io_macadd, mac);
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* IPAddress */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_io_ip_address, &ip);
+ /*proto_item_append_text(block_item, ", IP: %s", ip_to_str((guint8*)&ip));*/
+
+ /* Subnetmask */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_io_subnetmask, &ip);
+ /*proto_item_append_text(block_item, ", Subnet: %s", ip_to_str((guint8*)&ip));*/
+
+ /* StandardGateway */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_io_standard_gateway, &ip);
+ /*proto_item_append_text(block_item, ", Router: %s", ip_to_str((guint8*)&ip));*/
+
+
+ return offset;
+}
+
+
+/* dissect the PDSyncData block */
+static int
+dissect_PDSyncData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ e_guid_t uuid;
+ guint32 u32ReservedIntervalBegin;
+ guint32 u32ReservedIntervalEnd;
+ guint32 u32PLLWindow;
+ guint32 u32SyncSendFactor;
+ guint16 u16SendClockFactor;
+ guint16 u16SyncProperties;
+ guint16 u16SyncFrameAddress;
+ guint16 u16PTCPTimeoutFactor;
+ guint16 u16PTCPTakeoverTimeoutFactor;
+ guint16 u16PTCPMasterStartupTime;
+ guint8 u8MasterPriority1;
+ guint8 u8MasterPriority2;
+ guint8 u8LengthSubdomainName;
+
+
+ if (u8BlockVersionHigh != 1) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ switch (u8BlockVersionLow) {
+ case(0):
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* PTCPSubdomainID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_subdomain_id, &uuid);
+ /* IRDataID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ir_data_id, &uuid);
+ /* ReservedIntervalBegin */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reserved_interval_begin, &u32ReservedIntervalBegin);
+ /* ReservedIntervalEnd */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reserved_interval_end, &u32ReservedIntervalEnd);
+ /* PLLWindow enum */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_pllwindow, &u32PLLWindow);
+ /* SyncSendFactor 32 enum */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sync_send_factor, &u32SyncSendFactor);
+ /* SendClockFactor 16 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_send_clock_factor, &u16SendClockFactor);
+ /* SyncProperties 16 bitfield */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sync_properties, &u16SyncProperties);
+ /* SyncFrameAddress 16 bitfield */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sync_frame_address, &u16SyncFrameAddress);
+ /* PTCPTimeoutFactor 16 enum */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_timeout_factor, &u16PTCPTimeoutFactor);
+
+ proto_item_append_text(item, ": Slot:0x%x/0x%x, Interval:%u-%u, PLLWin:%u, Send:%u, Clock:%u",
+ u16SlotNr, u16SubslotNr, u32ReservedIntervalBegin, u32ReservedIntervalEnd,
+ u32PLLWindow, u32SyncSendFactor, u16SendClockFactor);
+ break;
+ case(2):
+ /* PTCPSubdomainID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_subdomain_id, &uuid);
+ /* ReservedIntervalBegin */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reserved_interval_begin, &u32ReservedIntervalBegin);
+ /* ReservedIntervalEnd */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reserved_interval_end, &u32ReservedIntervalEnd);
+ /* PLLWindow enum */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_pllwindow, &u32PLLWindow);
+ /* SyncSendFactor 32 enum */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sync_send_factor, &u32SyncSendFactor);
+ /* SendClockFactor 16 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_send_clock_factor, &u16SendClockFactor);
+ /* PTCPTimeoutFactor 16 enum */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_timeout_factor, &u16PTCPTimeoutFactor);
+ /* PTCPTakeoverTimeoutFactor 16 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_takeover_timeout_factor, &u16PTCPTakeoverTimeoutFactor);
+ /* PTCPMasterStartupTime 16 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_master_startup_time, &u16PTCPMasterStartupTime);
+ /* SyncProperties 16 bitfield */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sync_properties, &u16SyncProperties);
+ /* PTCP_MasterPriority1 */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_master_priority_1, &u8MasterPriority1);
+ /* PTCP_MasterPriority2 */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_master_priority_2, &u8MasterPriority2);
+ /* PTCPLengthSubdomainName */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ptcp_length_subdomain_name, &u8LengthSubdomainName);
+ /* PTCPSubdomainName */
+ /* XXX - another Punycode string */
+ proto_tree_add_item (tree, hf_pn_io_ptcp_subdomain_name, tvb, offset, u8LengthSubdomainName, ENC_ASCII);
+ offset += u8LengthSubdomainName;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ proto_item_append_text(item, ": Interval:%u-%u, PLLWin:%u, Send:%u, Clock:%u",
+ u32ReservedIntervalBegin, u32ReservedIntervalEnd,
+ u32PLLWindow, u32SyncSendFactor, u16SendClockFactor);
+ break;
+ default:
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ }
+
+ return offset;
+}
+
+
+/* dissect the PDIRData block */
+static int
+dissect_PDIRData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+
+ /* versions decoded are High: 1 and LOW 0..2 */
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow > 2 ) ) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ proto_item_append_text(item, ": Slot:0x%x/0x%x",
+ u16SlotNr, u16SubslotNr);
+
+ /* PDIRGlobalData */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ if (u8BlockVersionLow == 0) {
+ /* PDIRFrameData */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ } else if (u8BlockVersionLow == 1) {
+ /* [PDIRFrameData] */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ /* PDIRBeginEndData */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ }else if (u8BlockVersionLow == 2) {
+ /* [PDIRFrameData] */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ /* PDIRBeginEndData */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ }
+ return offset;
+}
+
+
+/* dissect the PDIRGlobalData block */
+static int
+dissect_PDIRGlobalData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ e_guid_t uuid;
+ guint32 u32MaxBridgeDelay;
+ guint32 u32NumberOfPorts;
+ guint32 u32MaxPortTxDelay;
+ guint32 u32MaxPortRxDelay;
+ guint32 u32MaxLineRxDelay;
+ guint32 u32YellowTime;
+ guint32 u32Tmp;
+
+ /* added blockversion 2 */
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow > 2)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* IRDataID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ir_data_id, &uuid);
+
+ if (u8BlockVersionLow <= 2) {
+ /* MaxBridgeDelay */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_max_bridge_delay, &u32MaxBridgeDelay);
+ /* NumberOfPorts */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_ports, &u32NumberOfPorts);
+ u32Tmp = u32NumberOfPorts;
+
+ while (u32Tmp--) {
+ /* MaxPortTxDelay */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_max_port_tx_delay, &u32MaxPortTxDelay);
+ /* MaxPortRxDelay */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_max_port_rx_delay, &u32MaxPortRxDelay);
+ if (u8BlockVersionLow >= 2) {
+ /* MaxLineRxDelay */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_max_line_rx_delay, &u32MaxLineRxDelay);
+ /* YellowTime */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_yellowtime, &u32YellowTime);
+ }
+ }
+ proto_item_append_text(item, ": MaxBridgeDelay:%u, NumberOfPorts:%u",
+ u32MaxBridgeDelay, u32NumberOfPorts);
+
+ }
+ return offset;
+}
+
+
+/* dissect the PDIRFrameData block */
+static int
+dissect_PDIRFrameData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint32 u32FrameSendOffset;
+ guint32 u32FrameDataProperties;
+ guint16 u16DataLength;
+ guint16 u16ReductionRatio;
+ guint16 u16Phase;
+ guint16 u16FrameID;
+ guint16 u16Ethertype;
+ guint8 u8RXPort;
+ guint8 u8FrameDetails;
+ guint8 u8NumberOfTxPortGroups;
+ guint8 u8TxPortGroupArray;
+ guint16 u16TxPortGroupArraySize;
+ guint16 u16EndOffset;
+ guint16 n = 0;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* added low version 1 */
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow > 1) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ u16EndOffset = offset + u16BodyLength -2;
+ if (u8BlockVersionLow > 0) {
+ /* for low version 1 FrameDataProperties is added */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_frame_data_properties, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_FrameDataProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_frame_data_properties_forwarding_Mode, &u32FrameDataProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_frame_data_properties_FastForwardingMulticastMACAdd, &u32FrameDataProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_frame_data_properties_FragmentMode, &u32FrameDataProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_frame_data_properties_reserved_1, &u32FrameDataProperties);
+ offset =
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_frame_data_properties_reserved_2, &u32FrameDataProperties);
+ }
+ /* dissect all IR frame data */
+ while (offset < u16EndOffset)
+ {
+ proto_item *ir_frame_data_sub_item;
+ proto_tree *ir_frame_data_tree;
+
+ n++;
+
+ /* new subtree for each IR frame */
+ ir_frame_data_sub_item = proto_tree_add_item(tree, hf_pn_io_ir_frame_data, tvb, offset, 17, ENC_NA);
+ ir_frame_data_tree = proto_item_add_subtree(ir_frame_data_sub_item, ett_pn_io_ir_frame_data);
+
+ /* FrameSendOffset */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_frame_data_tree, drep,
+ hf_pn_io_frame_send_offset, &u32FrameSendOffset);
+ /* DataLength */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_frame_data_tree, drep,
+ hf_pn_io_data_length, &u16DataLength);
+ /* ReductionRatio */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_frame_data_tree, drep,
+ hf_pn_io_reduction_ratio, &u16ReductionRatio);
+ /* Phase */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_frame_data_tree, drep,
+ hf_pn_io_phase, &u16Phase);
+ /* FrameID */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_frame_data_tree, drep,
+ hf_pn_io_frame_id, &u16FrameID);
+
+ /* Ethertype */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_frame_data_tree, drep,
+ hf_pn_io_ethertype, &u16Ethertype);
+ /* RxPort */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, ir_frame_data_tree, drep,
+ hf_pn_io_rx_port, &u8RXPort);
+ /* FrameDetails */
+ sub_item = proto_tree_add_item(ir_frame_data_tree, hf_pn_io_frame_details, tvb, offset, 1, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_frame_defails);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_frame_details_sync_frame, &u8FrameDetails);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_frame_details_meaning_frame_send_offset, &u8FrameDetails);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_frame_details_reserved, &u8FrameDetails);
+ /* TxPortGroup */
+ u8NumberOfTxPortGroups = tvb_get_guint8(tvb, offset);
+ sub_item = proto_tree_add_uint(ir_frame_data_tree, hf_pn_io_nr_of_tx_port_groups,
+ tvb, offset, 1, u8NumberOfTxPortGroups);
+ offset++;
+ if ((u8NumberOfTxPortGroups > 21) || ((u8NumberOfTxPortGroups & 0x1) !=1)) {
+ expert_add_info(pinfo, sub_item, &ei_pn_io_nr_of_tx_port_groups);
+ }
+
+ /* TxPortArray */
+ u16TxPortGroupArraySize = (u8NumberOfTxPortGroups + 7 / 8);
+ sub_item = proto_tree_add_item(ir_frame_data_tree, hf_pn_io_TxPortGroupProperties,
+ tvb, offset, u16TxPortGroupArraySize, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_GroupProperties);
+ while (u16TxPortGroupArraySize > 0)
+ {
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_TxPortGroupProperties_bit0, &u8TxPortGroupArray);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_TxPortGroupProperties_bit1, &u8TxPortGroupArray);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_TxPortGroupProperties_bit2, &u8TxPortGroupArray);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_TxPortGroupProperties_bit3, &u8TxPortGroupArray);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_TxPortGroupProperties_bit4, &u8TxPortGroupArray);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_TxPortGroupProperties_bit5, &u8TxPortGroupArray);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_TxPortGroupProperties_bit6, &u8TxPortGroupArray);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_TxPortGroupProperties_bit7, &u8TxPortGroupArray);
+
+ offset+=1;
+ u16TxPortGroupArraySize --;
+ }
+
+ /* align to next dataset */
+ offset = dissect_pn_align4(tvb, offset, pinfo, ir_frame_data_tree);
+
+ proto_item_append_text(ir_frame_data_tree, ": Offset:%u, Len:%u, Ratio:%u, Phase:%u, FrameID:0x%04x",
+ u32FrameSendOffset, u16DataLength, u16ReductionRatio, u16Phase, u16FrameID);
+
+ }
+
+ proto_item_append_text(item, ": Frames:%u", n);
+
+ return offset;
+}
+
+
+static int
+dissect_PDIRBeginEndData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint16 u16StartOfRedFrameID;
+ guint16 u16EndOfRedFrameID;
+ guint32 u32NumberOfPorts;
+ guint32 u32NumberOfAssignments;
+ guint32 u32NumberOfPhases;
+ guint32 u32RedOrangePeriodBegin;
+ guint32 u32OrangePeriodBegin;
+ guint32 u32GreenPeriodBegin;
+ guint16 u16TXPhaseAssignment;
+ guint16 u16RXPhaseAssignment;
+ guint32 u32SubStart;
+ guint32 u32Tmp;
+ guint32 u32Tmp2;
+ guint32 u32TxRedOrangePeriodBegin[0x11] = {0};
+ guint32 u32TxOrangePeriodBegin [0x11] = {0};
+ guint32 u32TxGreenPeriodBegin [0x11] = {0};
+ guint32 u32RxRedOrangePeriodBegin[0x11] = {0};
+ guint32 u32RxOrangePeriodBegin [0x11] = {0};
+ guint32 u32RxGreenPeriodBegin [0x11] = {0};
+ guint32 u32PortIndex;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_start_of_red_frame_id, &u16StartOfRedFrameID);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_end_of_red_frame_id, &u16EndOfRedFrameID);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_ports, &u32NumberOfPorts);
+ u32Tmp2 = u32NumberOfPorts;
+ while (u32Tmp2--) {
+ proto_item *ir_begin_end_port_sub_item;
+ proto_tree *ir_begin_end_port_tree;
+
+ /* new subtree for each Port */
+ ir_begin_end_port_sub_item = proto_tree_add_item(tree, hf_pn_io_ir_begin_end_port, tvb, offset, 0, ENC_NA);
+ ir_begin_end_port_tree = proto_item_add_subtree(ir_begin_end_port_sub_item, ett_pn_io_ir_begin_end_port);
+ u32SubStart = offset;
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_begin_end_port_tree, drep,
+ hf_pn_io_number_of_assignments, &u32NumberOfAssignments);
+ u32Tmp = u32NumberOfAssignments;
+ u32PortIndex = 0;
+ if (u32Tmp <= 0x10)
+ {
+ while (u32Tmp--) {
+ /* TXBeginEndAssignment */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_begin_end_port_tree, drep,
+ hf_pn_io_red_orange_period_begin_tx, &u32RedOrangePeriodBegin);
+ u32TxRedOrangePeriodBegin[u32PortIndex] = u32RedOrangePeriodBegin;
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_begin_end_port_tree, drep,
+ hf_pn_io_orange_period_begin_tx, &u32OrangePeriodBegin);
+ u32TxOrangePeriodBegin[u32PortIndex]= u32OrangePeriodBegin;
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_begin_end_port_tree, drep,
+ hf_pn_io_green_period_begin_tx, &u32GreenPeriodBegin);
+ u32TxGreenPeriodBegin[u32PortIndex] = u32GreenPeriodBegin;
+
+ /* RXBeginEndAssignment */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_begin_end_port_tree, drep,
+ hf_pn_io_red_orange_period_begin_rx, &u32RedOrangePeriodBegin);
+ u32RxRedOrangePeriodBegin[u32PortIndex] = u32RedOrangePeriodBegin;
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_begin_end_port_tree, drep,
+ hf_pn_io_orange_period_begin_rx, &u32OrangePeriodBegin);
+ u32RxOrangePeriodBegin[u32PortIndex]= u32OrangePeriodBegin;
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_begin_end_port_tree, drep,
+ hf_pn_io_green_period_begin_rx, &u32GreenPeriodBegin);
+ u32RxGreenPeriodBegin[u32PortIndex] = u32GreenPeriodBegin;
+
+ u32PortIndex++;
+ }
+ }
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_begin_end_port_tree, drep,
+ hf_pn_io_number_of_phases, &u32NumberOfPhases);
+ u32Tmp = u32NumberOfPhases;
+ if (u32Tmp <= 0x10)
+ {
+ while (u32Tmp--) {
+ proto_item *ir_begin_tx_phase_sub_item;
+ proto_tree *ir_begin_tx_phase_tree;
+
+ /* new subtree for TXPhaseAssignment */
+ ir_begin_tx_phase_sub_item = proto_tree_add_item(ir_begin_end_port_tree,
+ hf_pn_ir_tx_phase_assignment, tvb, offset, 0, ENC_NA);
+ ir_begin_tx_phase_tree = proto_item_add_subtree(ir_begin_tx_phase_sub_item, ett_pn_io_ir_tx_phase);
+ /* bit 0..3 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_tx_phase_tree, drep,
+ hf_pn_io_tx_phase_assignment_begin_value, &u16TXPhaseAssignment);
+ /* bit 4..7 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_tx_phase_tree, drep,
+ hf_pn_io_tx_phase_assignment_orange_begin, &u16TXPhaseAssignment);
+ /* bit 8..11 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_tx_phase_tree, drep,
+ hf_pn_io_tx_phase_assignment_end_reserved, &u16TXPhaseAssignment);
+ /* bit 12..15 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_tx_phase_tree, drep,
+ hf_pn_io_tx_phase_assignment_reserved, &u16TXPhaseAssignment);
+
+ proto_item_append_text(ir_begin_tx_phase_sub_item,
+ ": 0x%x, RedOrangePeriodBegin: %d, OrangePeriodBegin: %d, GreenPeriodBegin: %d",
+ u16TXPhaseAssignment,
+ u32TxRedOrangePeriodBegin[u16TXPhaseAssignment & 0x0F],
+ u32TxOrangePeriodBegin[(u16TXPhaseAssignment & 0x0F0) >> 4],
+ u32TxGreenPeriodBegin[(u16TXPhaseAssignment & 0x0F00)>> 8]);
+
+ /* new subtree for RXPhaseAssignment */
+ ir_begin_tx_phase_sub_item = proto_tree_add_item(ir_begin_end_port_tree,
+ hf_pn_ir_rx_phase_assignment, tvb, offset, 0, ENC_NA);
+ ir_begin_tx_phase_tree = proto_item_add_subtree(ir_begin_tx_phase_sub_item, ett_pn_io_ir_rx_phase);
+ /* bit 0..3 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_tx_phase_tree, drep,
+ hf_pn_io_tx_phase_assignment_begin_value, &u16RXPhaseAssignment);
+ /* bit 4..7 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_tx_phase_tree, drep,
+ hf_pn_io_tx_phase_assignment_orange_begin, &u16RXPhaseAssignment);
+ /* bit 8..11 */
+ dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_tx_phase_tree, drep,
+ hf_pn_io_tx_phase_assignment_end_reserved, &u16RXPhaseAssignment);
+ /* bit 12..15 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_tx_phase_tree, drep,
+ hf_pn_io_tx_phase_assignment_reserved, &u16RXPhaseAssignment);
+
+ proto_item_append_text(ir_begin_tx_phase_sub_item,
+ ": 0x%x, RedOrangePeriodBegin: %d, OrangePeriodBegin: %d, GreenPeriodBegin: %d",
+ u16RXPhaseAssignment,
+ u32RxRedOrangePeriodBegin[u16RXPhaseAssignment & 0x0F],
+ u32RxOrangePeriodBegin[(u16RXPhaseAssignment & 0x0F0) >> 4],
+ u32RxGreenPeriodBegin[(u16RXPhaseAssignment & 0x0F00)>> 8]);
+ }
+ }
+ proto_item_append_text(ir_begin_end_port_sub_item, ": Assignments:%u, Phases:%u",
+ u32NumberOfAssignments, u32NumberOfPhases);
+
+ proto_item_set_len(ir_begin_end_port_sub_item, offset - u32SubStart);
+ }
+
+ proto_item_append_text(item, ": StartOfRedFrameID: 0x%x, EndOfRedFrameID: 0x%x, Ports: %u",
+ u16StartOfRedFrameID, u16EndOfRedFrameID, u32NumberOfPorts);
+
+ return offset+u16BodyLength;
+}
+
+
+/* dissect the DiagnosisData block */
+static int
+dissect_DiagnosisData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 body_length)
+{
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16ChannelNumber;
+ guint16 u16UserStructureIdentifier;
+ proto_item *sub_item;
+
+
+ if (u8BlockVersionHigh != 1 || (u8BlockVersionLow != 0 && u8BlockVersionLow != 1)) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ if (u8BlockVersionLow == 1) {
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ body_length-=4;
+ }
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* ChannelNumber got new ranges: 0..0x7FFF the source is a channel as specified by the manufacturer */
+ /* fetch u16ChannelNumber */
+ u16ChannelNumber = ((drep[0] & DREP_LITTLE_ENDIAN)
+ ? tvb_get_letohs(tvb, offset)
+ : tvb_get_ntohs(tvb, offset));
+ if (tree) {
+ sub_item = proto_tree_add_item(tree,hf_pn_io_channel_number, tvb, offset, 2, DREP_ENC_INTEGER(drep));
+ if (u16ChannelNumber < 0x8000){ /* 0..0x7FFF the source is a channel as specified by the manufacturer */
+ proto_item_append_text(sub_item, " channel number of the diagnosis source");
+ }
+ else
+ if (u16ChannelNumber == 0x8000) /* 0x8000 the whole submodule is the source, */
+ proto_item_append_text(sub_item, " (whole) Submodule");
+ else
+ proto_item_append_text(sub_item, " reserved");
+ }
+ offset = offset +2; /* Advance behind ChannelNumber */
+ /* ChannelProperties */
+ offset = dissect_ChannelProperties(tvb, offset, pinfo, tree, item, drep);
+ body_length-=8;
+ /* UserStructureIdentifier */
+ u16UserStructureIdentifier = ((drep[0] & DREP_LITTLE_ENDIAN)
+ ? tvb_get_letohs(tvb, offset)
+ : tvb_get_ntohs(tvb, offset));
+ if (u16UserStructureIdentifier > 0x7FFF){
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_user_structure_identifier, &u16UserStructureIdentifier);
+ }
+ else
+ { /* range 0x0 to 0x7fff is manufacturer specific */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_user_structure_identifier_manf, &u16UserStructureIdentifier);
+ }
+ proto_item_append_text(item, ", USI:0x%x", u16UserStructureIdentifier);
+ body_length-=2;
+
+ /* the rest of the block contains optional: [MaintenanceItem] and/or [AlarmItem] */
+ while (body_length) {
+ offset = dissect_AlarmUserStructure(tvb, offset, pinfo, tree, item, drep,
+ &body_length, u16UserStructureIdentifier);
+ }
+ return offset;
+}
+
+
+static int
+dissect_ARProperties(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint8 *drep _U_)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32ARProperties;
+ guint8 startupMode;
+ guint8 isTimeAware;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_ar_properties, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_ar_properties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_pull_module_alarm_allowed, &u32ARProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_arproperties_StartupMode, &u32ARProperties);
+ startupMode = (guint8)((u32ARProperties >> 30) & 0x01);
+ /* Advanced startup mode */
+ if (startupMode)
+ {
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_combined_object_container_with_advanced_startupmode, &u32ARProperties);
+ }
+ /* Legacy startup mode */
+ else
+ {
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_combined_object_container_with_legacy_startupmode, &u32ARProperties);
+ }
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_time_aware_system, &u32ARProperties);
+
+ isTimeAware = (guint8)((u32ARProperties >> 28) & 0x01);
+
+ wmem_map_insert(pnio_time_aware_frame_map, GUINT_TO_POINTER(pinfo->num), GUINT_TO_POINTER(isTimeAware));
+
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_reserved, &u32ARProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_achnowledge_companion_ar, &u32ARProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_companion_ar, &u32ARProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_device_access, &u32ARProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_reserved_1, &u32ARProperties);
+/* removed within 2.3
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_data_rate, &u32ARProperties);
+*/
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_parameterization_server, &u32ARProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_supervisor_takeover_allowed, &u32ARProperties);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_ar_properties_state, &u32ARProperties);
+
+ return offset;
+}
+
+/* dissect the IOCRProperties */
+static int
+dissect_IOCRProperties(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32IOCRProperties;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_iocr_properties, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_iocr_properties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocr_properties_full_subframe_structure, &u32IOCRProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocr_properties_distributed_subframe_watchdog, &u32IOCRProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocr_properties_fast_forwarding_mac_adr, &u32IOCRProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocr_properties_reserved_3, &u32IOCRProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocr_properties_reserved_2, &u32IOCRProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocr_properties_media_redundancy, &u32IOCRProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocr_properties_reserved_1, &u32IOCRProperties);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocr_properties_rtclass, &u32IOCRProperties);
+
+ return offset;
+}
+
+
+/* dissect the ARData block */
+static int
+dissect_ARData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BlockLength)
+{
+ guint16 u16NumberOfARs;
+ guint16 u16NumberofEntries;
+ e_guid_t aruuid;
+ e_guid_t uuid;
+ guint16 u16ARType;
+ guint16 u16NameLength;
+ guint16 u16NumberOfIOCRs;
+ guint16 u16IOCRType;
+ guint16 u16FrameID;
+ guint16 u16CycleCounter;
+ guint8 u8DataStatus;
+ guint8 u8TransferStatus;
+ proto_item *ds_item;
+ proto_tree *ds_tree;
+ guint16 u16UDPRTPort;
+ guint16 u16AlarmCRType;
+ guint16 u16LocalAlarmReference;
+ guint16 u16RemoteAlarmReference;
+ guint16 u16NumberOfAPIs;
+ guint32 u32Api;
+ proto_item *iocr_item;
+ proto_tree *iocr_tree;
+ proto_item *ar_item;
+ proto_tree *ar_tree;
+ guint32 u32IOCRStart;
+ gint32 i32EndOffset;
+ guint32 u32ARDataStart;
+
+ /* added BlockversionLow == 1 */
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow > 1) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ i32EndOffset = offset + u16BlockLength;
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_ars, &u16NumberOfARs);
+ /* BlockversionLow: 0 */
+ if (u8BlockVersionLow == 0) {
+ while (u16NumberOfARs--) {
+ ar_item = proto_tree_add_item(tree, hf_pn_io_ar_data, tvb, offset, 0, ENC_NA);
+ ar_tree = proto_item_add_subtree(ar_item, ett_pn_io_ar_data);
+ u32ARDataStart = offset;
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_ar_uuid, &aruuid);
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ pn_init_append_aruuid_frame_setup_list(aruuid, pinfo->num);
+ }
+
+ proto_item_append_text(ar_item, "ARUUID:%s", guid_to_str(pinfo->pool, (const e_guid_t*) &aruuid));
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_ar_type, &u16ARType);
+ offset = dissect_ARProperties(tvb, offset, pinfo, ar_tree, item, drep);
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_cminitiator_objectuuid, &uuid);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_station_name_length, &u16NameLength);
+ proto_tree_add_item (ar_tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, ENC_ASCII);
+ offset += u16NameLength;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_number_of_iocrs, &u16NumberOfIOCRs);
+
+ while (u16NumberOfIOCRs--) {
+ iocr_item = proto_tree_add_item(ar_tree, hf_pn_io_iocr_tree, tvb, offset, 0, ENC_NA);
+ iocr_tree = proto_item_add_subtree(iocr_item, ett_pn_io_iocr);
+ u32IOCRStart = offset;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, iocr_tree, drep,
+ hf_pn_io_iocr_type, &u16IOCRType);
+ offset = dissect_IOCRProperties(tvb, offset, pinfo, iocr_tree, drep);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, iocr_tree, drep,
+ hf_pn_io_frame_id, &u16FrameID);
+
+ proto_item_append_text(iocr_item, ": FrameID:0x%x", u16FrameID);
+
+ /* add cycle counter */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, iocr_tree, drep,
+ hf_pn_io_cycle_counter, &u16CycleCounter);
+
+ u8DataStatus = tvb_get_guint8(tvb, offset);
+ u8TransferStatus = tvb_get_guint8(tvb, offset+1);
+
+ /* add data status subtree */
+ ds_item = proto_tree_add_uint_format(iocr_tree, hf_pn_io_data_status,
+ tvb, offset, 1, u8DataStatus,
+ "DataStatus: 0x%02x (Frame: %s and %s, Provider: %s and %s)",
+ u8DataStatus,
+ (u8DataStatus & 0x04) ? "Valid" : "Invalid",
+ (u8DataStatus & 0x01) ? "Primary" : "Backup",
+ (u8DataStatus & 0x20) ? "Ok" : "Problem",
+ (u8DataStatus & 0x10) ? "Run" : "Stop");
+ ds_tree = proto_item_add_subtree(ds_item, ett_pn_io_data_status);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_res67, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_ok, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_operate, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_res3, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_valid, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_res1, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_primary, tvb, offset, 1, u8DataStatus);
+
+ offset++;
+
+ /* add transfer status */
+ if (u8TransferStatus) {
+ proto_tree_add_uint_format(iocr_tree, hf_pn_io_transfer_status, tvb,
+ offset, 1, u8TransferStatus,
+ "TransferStatus: 0x%02x (ignore this frame)", u8TransferStatus);
+ } else {
+ proto_tree_add_uint_format(iocr_tree, hf_pn_io_transfer_status, tvb,
+ offset, 1, u8TransferStatus,
+ "TransferStatus: 0x%02x (OK)", u8TransferStatus);
+ }
+
+ offset++;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, iocr_tree, drep,
+ hf_pn_io_cminitiator_udprtport, &u16UDPRTPort);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, iocr_tree, drep,
+ hf_pn_io_cmresponder_udprtport, &u16UDPRTPort);
+
+ proto_item_set_len(iocr_item, offset - u32IOCRStart);
+ }
+
+ /* AlarmCRType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_alarmcr_type, &u16AlarmCRType);
+ /* LocalAlarmReference */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_localalarmref, &u16LocalAlarmReference);
+ /* RemoteAlarmReference */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_remotealarmref, &u16RemoteAlarmReference);
+ /* ParameterServerObjectUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_parameter_server_objectuuid, &uuid);
+ /* StationNameLength */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_station_name_length, &u16NameLength);
+ /* ParameterServerStationName */
+ proto_tree_add_item (ar_tree, hf_pn_io_parameter_server_station_name, tvb, offset, u16NameLength, ENC_ASCII);
+ offset += u16NameLength;
+ /* NumberOfAPIs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+ /* API */
+ while (u16NumberOfAPIs--) {
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ar_tree, drep,
+ hf_pn_io_api, &u32Api);
+ }
+ proto_item_set_len(ar_item, offset - u32ARDataStart);
+ }
+ }
+ else
+ { /* BlockversionLow == 1 */
+ while (u16NumberOfARs--) {
+ ar_item = proto_tree_add_item(tree, hf_pn_io_ar_data, tvb, offset, 0, ENC_NA);
+ ar_tree = proto_item_add_subtree(ar_item, ett_pn_io_ar_data);
+ u32ARDataStart = offset;
+ /*ARUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_ar_uuid, &aruuid);
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ pn_init_append_aruuid_frame_setup_list(aruuid, pinfo->num);
+ }
+
+ proto_item_append_text(ar_item, "ARUUID:%s", guid_to_str(pinfo->pool, (const e_guid_t*) &aruuid));
+ /* CMInitiatorObjectUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_cminitiator_objectuuid, &uuid);
+ /* ParameterServerObjectUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_parameter_server_objectuuid, &uuid);
+ /* ARProperties*/
+ offset = dissect_ARProperties(tvb, offset, pinfo, ar_tree, item, drep);
+ /* ARType*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_ar_type, &u16ARType);
+ /* AlarmCRType */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_alarmcr_type, &u16AlarmCRType);
+ /* LocalAlarmReference */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_localalarmref, &u16LocalAlarmReference);
+ /* RemoteAlarmReference */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_remotealarmref, &u16RemoteAlarmReference);
+ /* InitiatorUDPRTPort*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_cminitiator_udprtport, &u16UDPRTPort);
+ /* ResponderUDPRTPort*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_cmresponder_udprtport, &u16UDPRTPort);
+ /* CMInitiatorStationName*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_station_name_length, &u16NameLength);
+ proto_tree_add_item (ar_tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, ENC_ASCII);
+ offset += u16NameLength;
+ /** align padding! **/
+ offset = dissect_pn_align4(tvb, offset, pinfo, ar_tree);
+
+ /* StationNameLength */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_station_name_length, &u16NameLength);
+ if (u16NameLength != 0) {
+ /* ParameterServerStationName */
+ proto_tree_add_item (ar_tree, hf_pn_io_parameter_server_station_name, tvb, offset, u16NameLength, ENC_ASCII);
+ offset += u16NameLength;
+ }
+ else
+ { /* display no name present */
+ proto_tree_add_string (ar_tree, hf_pn_io_parameter_server_station_name, tvb, offset, u16NameLength, " <no ParameterServerStationName present>");
+ }
+ /** align padding! **/
+ offset = dissect_pn_align4(tvb, offset, pinfo, ar_tree);
+
+ /* NumberOfIOCRs*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_number_of_iocrs, &u16NumberOfIOCRs);
+ /* align to next 32 bit */
+ offset = dissect_pn_padding(tvb, offset, pinfo, ar_tree, 2);
+
+ while (u16NumberOfIOCRs--) {
+ iocr_item = proto_tree_add_item(ar_tree, hf_pn_io_iocr_tree, tvb, offset, 0, ENC_NA);
+ iocr_tree = proto_item_add_subtree(iocr_item, ett_pn_io_iocr);
+ u32IOCRStart = offset;
+
+ /* IOCRProperties*/
+ offset = dissect_IOCRProperties(tvb, offset, pinfo, iocr_tree, drep);
+ /* IOCRType*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, iocr_tree, drep, hf_pn_io_iocr_type, &u16IOCRType);
+ /* FrameID*/
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, iocr_tree, drep, hf_pn_io_frame_id, &u16FrameID);
+ proto_item_append_text(iocr_item, ": FrameID:0x%x", u16FrameID);
+
+ /* add cycle counter */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, iocr_tree, drep,
+ hf_pn_io_cycle_counter, &u16CycleCounter);
+
+ u8DataStatus = tvb_get_guint8(tvb, offset);
+ u8TransferStatus = tvb_get_guint8(tvb, offset+1);
+
+ /* add data status subtree */
+ ds_item = proto_tree_add_uint_format(iocr_tree, hf_pn_io_data_status,
+ tvb, offset, 1, u8DataStatus,
+ "DataStatus: 0x%02x (Frame: %s and %s, Provider: %s and %s)",
+ u8DataStatus,
+ (u8DataStatus & 0x04) ? "Valid" : "Invalid",
+ (u8DataStatus & 0x01) ? "Primary" : "Backup",
+ (u8DataStatus & 0x20) ? "Ok" : "Problem",
+ (u8DataStatus & 0x10) ? "Run" : "Stop");
+ ds_tree = proto_item_add_subtree(ds_item, ett_pn_io_data_status);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_res67, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_ok, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_operate, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_res3, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_valid, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_res1, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(ds_tree, hf_pn_io_data_status_primary, tvb, offset, 1, u8DataStatus);
+
+ offset++;
+
+ /* add transfer status */
+ if (u8TransferStatus) {
+ proto_tree_add_uint_format(iocr_tree, hf_pn_io_transfer_status, tvb,
+ offset, 1, u8TransferStatus,
+ "TransferStatus: 0x%02x (ignore this frame)", u8TransferStatus);
+ } else {
+ proto_tree_add_uint_format(iocr_tree, hf_pn_io_transfer_status, tvb,
+ offset, 1, u8TransferStatus,
+ "TransferStatus: 0x%02x (OK)", u8TransferStatus);
+ }
+ offset++;
+ proto_item_set_len(iocr_item, offset - u32IOCRStart);
+ }
+ /* NumberOfAPIs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+ /* align to next 32 bit */
+ offset = dissect_pn_padding(tvb, offset, pinfo, ar_tree, 2);
+ /* API */
+ while (u16NumberOfAPIs--) {
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_api, &u32Api);
+ }
+ /* get the number of subblocks an dissect them */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_number_of_ARDATAInfo, &u16NumberofEntries);
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, ar_tree, 2);
+
+ while ((offset < i32EndOffset) && (u16NumberofEntries > 0)) {
+ offset = dissect_a_block(tvb, offset, pinfo, ar_tree, drep);
+ u16NumberofEntries--;
+ }
+ proto_item_set_len(ar_item, offset - u32ARDataStart);
+ }
+ }
+ return offset;
+}
+
+
+/* dissect the APIData block */
+static int
+dissect_APIData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberOfAPIs;
+ guint32 u32Api;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* NumberOfAPIs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+
+ while (u16NumberOfAPIs--) {
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ }
+
+ return offset;
+}
+
+/* dissect the SLRData block */
+static int
+dissect_SRLData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 RedundancyInfo;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ /* bit 0 ..1 EndPoint1 and EndPoint2*/
+ dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_RedundancyInfo, &RedundancyInfo);
+ /* bit 2 .. 15 reserved */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_RedundancyInfo_reserved, &RedundancyInfo);
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+ return offset;
+}
+
+/* dissect the LogData block */
+static int
+dissect_LogData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint64 u64ActualLocaltimeStamp;
+ guint16 u16NumberOfLogEntries;
+ guint64 u64LocaltimeStamp;
+ e_guid_t aruuid;
+ guint32 u32EntryDetail;
+ dcerpc_info di; /* fake dcerpc_info struct */
+ dcerpc_call_value call_data;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ di.conformant_run = 0;
+ /* we need di->call_data->flags.NDR64 == 0 */
+ call_data.flags = 0;
+ di.call_data = &call_data;
+ di.dcerpc_procedure_name = "";
+
+ /* ActualLocalTimeStamp */
+ offset = dissect_dcerpc_uint64(tvb, offset, pinfo, tree, &di, drep,
+ hf_pn_io_actual_local_time_stamp, &u64ActualLocaltimeStamp);
+ /* NumberOfLogEntries */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_log_entries, &u16NumberOfLogEntries);
+
+ while (u16NumberOfLogEntries--) {
+ /* LocalTimeStamp */
+ offset = dissect_dcerpc_uint64(tvb, offset, pinfo, tree, &di, drep,
+ hf_pn_io_local_time_stamp, &u64LocaltimeStamp);
+ /* ARUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_uuid, &aruuid);
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ pn_init_append_aruuid_frame_setup_list(aruuid, pinfo->num);
+ }
+
+ /* PNIOStatus */
+ offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
+ /* EntryDetail */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_entry_detail, &u32EntryDetail);
+ }
+
+ return offset;
+}
+
+
+/* dissect the FS Hello block */
+static int
+dissect_FSHello_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32FSHelloMode;
+ guint32 u32FSHelloInterval;
+ guint32 u32FSHelloRetry;
+ guint32 u32FSHelloDelay;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* FSHelloMode */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fs_hello_mode, &u32FSHelloMode);
+ /* FSHelloInterval */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fs_hello_interval, &u32FSHelloInterval);
+ /* FSHelloRetry */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fs_hello_retry, &u32FSHelloRetry);
+ /* FSHelloDelay */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fs_hello_delay, &u32FSHelloDelay);
+
+ proto_item_append_text(item, ": Mode:%s, Interval:%ums, Retry:%u, Delay:%ums",
+ val_to_str(u32FSHelloMode, pn_io_fs_hello_mode_vals, "0x%x"),
+ u32FSHelloInterval, u32FSHelloRetry, u32FSHelloDelay);
+
+ return offset;
+}
+
+
+/* dissect the FS Parameter block */
+static int
+dissect_FSParameter_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint32 u32FSParameterMode;
+ e_guid_t FSParameterUUID;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* FSParameterMode */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fs_parameter_mode, &u32FSParameterMode);
+ /* FSParameterUUID */
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_fs_parameter_uuid, &FSParameterUUID);
+
+ proto_item_append_text(item, ": Mode:%s",
+ val_to_str(u32FSParameterMode, pn_io_fs_parameter_mode_vals, "0x%x"));
+
+ return offset;
+}
+
+
+
+
+/* dissect the FSUDataAdjust block */
+static int
+dissect_PDInterfaceFSUDataAdjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ tvbuff_t *new_tvb;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ u16BodyLength -= 2;
+
+ /* sub blocks */
+ new_tvb = tvb_new_subset_length(tvb, offset, u16BodyLength);
+ dissect_blocks(new_tvb, 0, pinfo, tree, drep);
+ offset += u16BodyLength;
+
+ return offset;
+}
+
+
+/* dissect the ARFSUDataAdjust block */
+static int
+dissect_ARFSUDataAdjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ tvbuff_t *new_tvb;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ u16BodyLength -= 2;
+
+ /* sub blocks */
+ new_tvb = tvb_new_subset_length(tvb, offset, u16BodyLength);
+ dissect_blocks(new_tvb, 0, pinfo, tree, drep);
+ offset += u16BodyLength;
+
+ return offset;
+}
+
+/* dissect the PE_EntityFilterData block */
+static int
+dissect_PE_EntityFilterData_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberOfAPIs;
+ guint32 u32Api;
+ guint16 u16NumberOfModules;
+ guint16 u16SlotNr;
+ guint32 u32ModuleIdentNumber;
+ guint16 u16NumberOfSubmodules;
+ guint16 u16SubslotNr;
+ guint32 u32SubmoduleIdentNumber;
+ proto_item* api_item;
+ proto_tree* api_tree;
+ guint32 u32ApiStart;
+ proto_item* module_item;
+ proto_tree* module_tree;
+ guint32 u32ModuleStart;
+ proto_item* sub_item;
+ proto_tree* sub_tree;
+ guint32 u32SubStart;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ // NumberOfAPIs,
+ // (API, NumberOfModules, (SlotNumber, ModuleIdentNumber, NumberOfSubmodules, (SubslotNumber, SubmoduleIdentNumber)*)*)*
+
+ /* NumberOfAPIs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+
+ proto_item_append_text(item, ": APIs:%u", u16NumberOfAPIs);
+
+ while (u16NumberOfAPIs--) {
+ api_item = proto_tree_add_item(tree, hf_pn_io_api_tree, tvb, offset, 0, ENC_NA);
+ api_tree = proto_item_add_subtree(api_item, ett_pn_io_api);
+ u32ApiStart = offset;
+
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_api, &u32Api);
+ /* NumberOfModules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_number_of_modules, &u16NumberOfModules);
+
+ proto_item_append_text(api_item, ": %u, Modules: %u",
+ u32Api, u16NumberOfModules);
+
+ proto_item_append_text(item, ", Modules:%u", u16NumberOfModules);
+
+ while (u16NumberOfModules--) {
+ module_item = proto_tree_add_item(api_tree, hf_pn_io_module_tree, tvb, offset, 0, ENC_NA);
+ module_tree = proto_item_add_subtree(module_item, ett_pn_io_module);
+ u32ModuleStart = offset;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* ModuleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
+ /* NumberOfSubmodules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_number_of_submodules, &u16NumberOfSubmodules);
+
+ proto_item_append_text(module_item, ": Slot 0x%x, Ident: 0x%x Submodules: %u",
+ u16SlotNr, u32ModuleIdentNumber,
+ u16NumberOfSubmodules);
+
+ proto_item_append_text(item, ", Submodules:%u", u16NumberOfSubmodules);
+
+ while (u16NumberOfSubmodules--) {
+ sub_item = proto_tree_add_item(module_tree, hf_pn_io_submodule_tree, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_submodule);
+ u32SubStart = offset;
+
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* SubmoduleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
+
+ proto_item_append_text(sub_item, ": Subslot 0x%x, IdentNumber: 0x%x",
+ u16SubslotNr, u32SubmoduleIdentNumber);
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+ } /* NumberOfSubmodules */
+
+ proto_item_set_len(module_item, offset - u32ModuleStart);
+ }
+
+ proto_item_set_len(api_item, offset - u32ApiStart);
+ }
+
+
+ return offset;
+}
+
+/* dissect the PE_EntityStatusData block */
+static int
+dissect_PE_EntityStatusData_block(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, proto_item* item _U_, guint8* drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberOfAPIs;
+ guint32 u32Api;
+ guint16 u16NumberOfModules;
+ guint16 u16SlotNr;
+ guint16 u16NumberOfSubmodules;
+ guint16 u16SubslotNr;
+ proto_item* api_item;
+ proto_tree* api_tree;
+ guint32 u32ApiStart;
+ proto_item* module_item;
+ proto_tree* module_tree;
+ guint32 u32ModuleStart;
+ proto_item* sub_item;
+ proto_tree* sub_tree;
+ guint32 u32SubStart;
+ guint8 u8PEOperationalMode;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ // NumberOfAPIs,
+ // (API, NumberOfModules, (SlotNumber, NumberOfSubmodules, (SubslotNumber, PE_OperationalMode, [Padding] * a)*)*)*
+
+ /* NumberOfAPIs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+
+ proto_item_append_text(item, ": APIs:%u", u16NumberOfAPIs);
+
+ while (u16NumberOfAPIs--) {
+ api_item = proto_tree_add_item(tree, hf_pn_io_api_tree, tvb, offset, 0, ENC_NA);
+ api_tree = proto_item_add_subtree(api_item, ett_pn_io_api);
+ u32ApiStart = offset;
+
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_api, &u32Api);
+ /* NumberOfModules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_number_of_modules, &u16NumberOfModules);
+
+ proto_item_append_text(api_item, ": %u, Modules: %u",
+ u32Api, u16NumberOfModules);
+
+ proto_item_append_text(item, ", Modules:%u", u16NumberOfModules);
+
+ while (u16NumberOfModules--) {
+ module_item = proto_tree_add_item(api_tree, hf_pn_io_module_tree, tvb, offset, 0, ENC_NA);
+ module_tree = proto_item_add_subtree(module_item, ett_pn_io_module);
+ u32ModuleStart = offset;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* NumberOfSubmodules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_number_of_submodules, &u16NumberOfSubmodules);
+
+ proto_item_append_text(module_item, ": Slot 0x%x, Submodules: %u",
+ u16SlotNr,
+ u16NumberOfSubmodules);
+
+ proto_item_append_text(item, ", Submodules:%u", u16NumberOfSubmodules);
+
+ while (u16NumberOfSubmodules--) {
+ sub_item = proto_tree_add_item(module_tree, hf_pn_io_submodule_tree, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_submodule);
+ u32SubStart = offset;
+
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ proto_item_append_text(sub_item, ": Subslot 0x%x",
+ u16SubslotNr);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pe_operational_mode, &u8PEOperationalMode);
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, sub_tree, 1);
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+ } /* NumberOfSubmodules */
+
+ proto_item_set_len(module_item, offset - u32ModuleStart);
+ }
+
+ proto_item_set_len(api_item, offset - u32ApiStart);
+ }
+
+
+ return offset;
+
+}
+
+static const char *
+decode_ARType_spezial(guint16 ARType, guint16 ARAccess)
+{
+ if (ARType == 0x0001)
+ return ("IO Controller AR");
+ else if (ARType == 0x0003)
+ return("IO Controller AR");
+ else if (ARType == 0x0010)
+ return("IO Controller AR (RT_CLASS_3)");
+ else if (ARType == 0x0020)
+ return("IO Controller AR (sysred/CiR)");
+ else if (ARType == 0x0006)
+ {
+ if (ARAccess) /*TRUE */
+ return("DeviceAccess AR");
+ else
+ return("IO Supervisor AR");
+ }
+ else
+ return("reserved");
+}
+
+/* dissect the ARBlockReq */
+static int
+dissect_ARBlockReq_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ pnio_ar_t ** ar)
+{
+ guint16 u16ARType;
+ guint32 u32ARProperties;
+ gboolean have_aruuid = FALSE;
+ e_guid_t aruuid;
+ e_guid_t uuid;
+ guint16 u16SessionKey;
+ guint8 mac[6];
+ guint16 u16TimeoutFactor;
+ guint16 u16UDPRTPort;
+ guint16 u16NameLength;
+ char *pStationName;
+ pnio_ar_t *par;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16ArNumber;
+ guint16 u16ArResource;
+ guint16 u16ArReserved;
+ proto_item *sub_item_selector;
+ proto_tree *sub_tree_selector;
+ conversation_t *conversation;
+ apduStatusSwitch *apdu_status_switch = NULL;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ u32ARProperties = ((drep[0] & DREP_LITTLE_ENDIAN)
+ ? tvb_get_letohl (tvb, offset + 2 + 16 +2 + 6 +12)
+ : tvb_get_ntohl (tvb, offset + 2 + 16 +2 + 6 +12));
+
+ u16ARType = ((drep[0] & DREP_LITTLE_ENDIAN)
+ ? tvb_get_letohs (tvb, offset)
+ : tvb_get_ntohs (tvb, offset));
+
+ if (tree) {
+ proto_tree_add_string_format(tree, hf_pn_io_artype_req, tvb, offset, 2,
+ "ARType", "ARType: (0x%04x) %s ",
+ u16ARType, decode_ARType_spezial(u16ARType, u32ARProperties));
+ }
+ offset = offset + 2;
+
+ if (u16ARType == 0x0020)
+ {
+ dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep, hf_pn_io_ar_uuid, &aruuid);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_ar_uuid, tvb, offset, 16, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_ar_info);
+
+ proto_tree_add_item(sub_tree, hf_pn_io_ar_discriminator, tvb, offset, 6, ENC_NA);
+ offset += 6;
+
+ proto_tree_add_item(sub_tree, hf_pn_io_ar_configid, tvb, offset, 8, ENC_NA);
+ offset += 8;
+
+ sub_item_selector = proto_tree_add_item(sub_tree, hf_pn_io_ar_selector, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree_selector = proto_item_add_subtree(sub_item_selector, ett_pn_io_ar_info);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree_selector, drep, hf_pn_io_ar_arnumber, &u16ArNumber);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree_selector, drep, hf_pn_io_ar_arresource, &u16ArResource);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree_selector, drep, hf_pn_io_ar_arreserved, &u16ArReserved);
+
+ /* When ARType==IOCARSR, then find or create conversation for this frame */
+ if (!PINFO_FD_VISITED(pinfo)) {
+ /* Get current conversation endpoints using MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_UDP, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, if no "Ident OK" frame as been dissected yet!
+ * Need to switch dl_src & dl_dst, as current packet is sent by controller and not by device.
+ * All conversations are based on Device MAC as addr1 */
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_UDP, 0, 0, 0);
+ }
+
+ /* Try to get apdu status switch information from the conversation */
+ apdu_status_switch = (apduStatusSwitch*)conversation_get_proto_data(conversation, proto_pn_io_apdu_status);
+
+ /* If apdu status switch is null, then fill it*/
+ /* If apdu status switch is not null, then update it*/
+ if (apdu_status_switch == NULL) {
+ /* apdu status switch information is valid for whole file*/
+ apdu_status_switch = wmem_new0(wmem_file_scope(), apduStatusSwitch);
+ copy_address_shallow(&apdu_status_switch->dl_src, conversation_key_addr1(conversation->key_ptr));
+ copy_address_shallow(&apdu_status_switch->dl_dst, conversation_key_addr2(conversation->key_ptr));
+ apdu_status_switch->isRedundancyActive = TRUE;
+ conversation_add_proto_data(conversation, proto_pn_io_apdu_status, apdu_status_switch);
+ }
+ else {
+ copy_address_shallow(&apdu_status_switch->dl_src, conversation_key_addr1(conversation->key_ptr));
+ copy_address_shallow(&apdu_status_switch->dl_dst, conversation_key_addr2(conversation->key_ptr));
+ apdu_status_switch->isRedundancyActive = TRUE;
+ }
+ }
+ }
+ else
+ {
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_uuid, &aruuid);
+ have_aruuid = TRUE;
+ }
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ pn_init_append_aruuid_frame_setup_list(aruuid, pinfo->num);
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sessionkey, &u16SessionKey);
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree,
+ hf_pn_io_cminitiator_macadd, mac);
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_cminitiator_objectuuid, &uuid);
+
+
+ offset = dissect_ARProperties(tvb, offset, pinfo, tree, item, drep);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_cminitiator_activitytimeoutfactor, &u16TimeoutFactor); /* XXX - special values */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_cminitiator_udprtport, &u16UDPRTPort);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_station_name_length, &u16NameLength);
+
+ proto_tree_add_item_ret_display_string (tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, ENC_ASCII, pinfo->pool, &pStationName);
+ offset += u16NameLength;
+
+ proto_item_append_text(item, ": %s, Session:%u, MAC:%02x:%02x:%02x:%02x:%02x:%02x, Port:0x%x, Station:%s",
+ decode_ARType_spezial(u16ARType, u32ARProperties),
+ u16SessionKey,
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+ u16UDPRTPort,
+ pStationName);
+
+ if (have_aruuid) {
+ par = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+ if (par == NULL) {
+ par = pnio_ar_new(&aruuid);
+ memcpy( (void *) (&par->controllermac), mac, sizeof(par->controllermac));
+ par->arType = u16ARType; /* store AR-type for filter generation */
+ /*strncpy( (char *) (&par->controllername), pStationName, sizeof(par->controllername));*/
+ } else {
+ /*expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "ARBlockReq: AR already existing!");*/
+ }
+ *ar = par;
+ } else {
+ *ar = NULL;
+ }
+
+ return offset;
+}
+
+
+/* dissect the ARBlockRes */
+static int
+dissect_ARBlockRes_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ pnio_ar_t **ar)
+{
+ guint16 u16ARType;
+ e_guid_t uuid;
+ guint16 u16SessionKey;
+ guint8 mac[6];
+ guint16 u16UDPRTPort;
+ pnio_ar_t *par;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_type, &u16ARType);
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_uuid, &uuid);
+
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ pn_init_append_aruuid_frame_setup_list(uuid, pinfo->num);
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sessionkey, &u16SessionKey);
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree,
+ hf_pn_io_cmresponder_macadd, mac);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_cmresponder_udprtport, &u16UDPRTPort);
+
+ proto_item_append_text(item, ": %s, Session:%u, MAC:%02x:%02x:%02x:%02x:%02x:%02x, Port:0x%x",
+ val_to_str(u16ARType, pn_io_ar_type, "0x%x"),
+ u16SessionKey,
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+ u16UDPRTPort);
+
+ /* The value NIL indicates the usage of the implicit AR*/
+ par = pnio_ar_find_by_aruuid(pinfo, &uuid);
+ if (par != NULL) {
+ memcpy( (void *) (&par->devicemac), mac, sizeof(par->controllermac));
+ }
+ *ar = par;
+
+ return offset;
+}
+
+
+/* dissect the IOCRBlockReq */
+static int
+dissect_IOCRBlockReq_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ pnio_ar_t *ar)
+{
+ guint16 u16IOCRType;
+ guint16 u16IOCRReference;
+ guint16 u16LT;
+ guint16 u16DataLength;
+ guint16 u16FrameID;
+ guint16 u16SendClockFactor;
+ guint16 u16ReductionRatio;
+ guint16 u16Phase;
+ guint16 u16Sequence;
+ guint32 u32FrameSendOffset;
+ guint16 u16WatchdogFactor;
+ guint16 u16DataHoldFactor;
+ guint16 u16IOCRTagHeader;
+ guint8 mac[6];
+ guint16 u16NumberOfAPIs;
+ guint32 u32Api;
+ guint16 u16NumberOfIODataObjectsInAPI;
+ guint16 u16NumberOfIODataObjectsInCR = 0U;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16IODataObjectFrameOffset;
+ guint16 u16NumberOfIOCSInAPI;
+ guint16 u16NumberOfIOCSInCR = 0U;
+ guint16 u16IOCSFrameOffset;
+ proto_item *api_item;
+ proto_tree *api_tree;
+ guint32 u32ApiStart;
+ guint16 u16Tmp;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+
+ conversation_t *conversation;
+ conversation_t *conversation_time_aware;
+ stationInfo *station_info = NULL;
+ iocsObject *iocs_object;
+ iocsObject *cmp_iocs_object;
+ ioDataObject *io_data_object;
+ ioDataObject *cmp_io_data_object;
+ wmem_list_frame_t *frame;
+ wmem_list_t *iocs_list;
+
+ ARUUIDFrame *current_aruuid_frame = NULL;
+ guint32 current_aruuid = 0;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_iocr_type, &u16IOCRType);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_iocr_reference, &u16IOCRReference);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_lt, &u16LT);
+
+ offset = dissect_IOCRProperties(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_data_length, &u16DataLength);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_frame_id, &u16FrameID);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_send_clock_factor, &u16SendClockFactor);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reduction_ratio, &u16ReductionRatio);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_phase, &u16Phase);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sequence, &u16Sequence);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_frame_send_offset, &u32FrameSendOffset);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_watchdog_factor, &u16WatchdogFactor);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_data_hold_factor, &u16DataHoldFactor);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_iocr_tag_header, &u16IOCRTagHeader);
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree,
+ hf_pn_io_iocr_multicast_mac_add, mac);
+
+ if (wmem_map_contains(pnio_time_aware_frame_map, GUINT_TO_POINTER(pinfo->num)))
+ {
+ address cyclic_mac_addr;
+ address iocr_mac_addr;
+
+ set_address(&cyclic_mac_addr, AT_ETHER, 6, mac);
+
+ iocr_mac_addr = (u16IOCRType == PN_INPUT_CR) ? pinfo->dl_dst : pinfo->dl_src;
+
+ /* Get current conversation endpoints using MAC addresses */
+ conversation_time_aware = find_conversation(pinfo->num, &cyclic_mac_addr, &iocr_mac_addr, CONVERSATION_NONE, 0, 0, 0);
+
+ if (conversation_time_aware == NULL) {
+ conversation_time_aware = conversation_new(pinfo->num, &iocr_mac_addr, &cyclic_mac_addr, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ conversation_add_proto_data(conversation_time_aware, proto_pn_io_time_aware_status, wmem_map_lookup(pnio_time_aware_frame_map, GUINT_TO_POINTER(pinfo->num)));
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+
+ proto_item_append_text(item, ": %s, Ref:0x%x, Len:%u, FrameID:0x%x, Clock:%u, Ratio:%u, Phase:%u APIs:%u",
+ val_to_str(u16IOCRType, pn_io_iocr_type, "0x%x"),
+ u16IOCRReference, u16DataLength, u16FrameID,
+ u16SendClockFactor, u16ReductionRatio, u16Phase, u16NumberOfAPIs);
+
+ while (u16NumberOfAPIs--) {
+ api_item = proto_tree_add_item(tree, hf_pn_io_api_tree, tvb, offset, 0, ENC_NA);
+ api_tree = proto_item_add_subtree(api_item, ett_pn_io_api);
+ u32ApiStart = offset;
+
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_api, &u32Api);
+ /* NumberOfIODataObjects */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_number_of_io_data_objects, &u16NumberOfIODataObjectsInAPI);
+
+ /* Set global Variant for Number of IO Data Objects */
+ /* Notice: Handle Input & Output seperate!!! */
+ if (!PINFO_FD_VISITED(pinfo)) {
+ /* Get current conversation endpoints using MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, if no "Ident OK" frame as been dissected yet!
+ * Need to switch dl_src & dl_dst, as Connect Request is sent by controller and not by device.
+ * All conversations are based on Device MAC as addr1 */
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ current_aruuid_frame = pn_find_aruuid_frame_setup(pinfo);
+
+ if (current_aruuid_frame != NULL) {
+ current_aruuid = current_aruuid_frame->aruuid.data1;
+ if (u16IOCRType == PN_INPUT_CR) {
+ current_aruuid_frame->inputframe = u16FrameID;
+ }
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, current_aruuid);
+ if (station_info == NULL) {
+ station_info = wmem_new0(wmem_file_scope(), stationInfo);
+ init_pnio_rtc1_station(station_info);
+ conversation_add_proto_data(conversation, current_aruuid, station_info);
+ }
+ u16NumberOfIODataObjectsInCR += u16NumberOfIODataObjectsInAPI;
+
+ pn_find_dcp_station_info(station_info, conversation);
+ }
+
+ u16Tmp = u16NumberOfIODataObjectsInAPI;
+ while (u16Tmp--) {
+ sub_item = proto_tree_add_item(api_tree, hf_pn_io_io_data_object, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_io_data_object);
+ u32SubStart = offset;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* IODataObjectFrameOffset */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_io_data_object_frame_offset, &u16IODataObjectFrameOffset);
+
+ proto_item_append_text(sub_item, ": Slot: 0x%x, Subslot: 0x%x FrameOffset: %u",
+ u16SlotNr, u16SubslotNr, u16IODataObjectFrameOffset);
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ if (!PINFO_FD_VISITED(pinfo) && station_info != NULL) {
+ io_data_object = wmem_new0(wmem_file_scope(), ioDataObject);
+ io_data_object->slotNr = u16SlotNr;
+ io_data_object->subSlotNr = u16SubslotNr;
+ io_data_object->frameOffset = u16IODataObjectFrameOffset;
+ /* initial - Will be added later with Write Request */
+ io_data_object->f_dest_adr = 0;
+ io_data_object->f_par_crc1 = 0;
+ io_data_object->f_src_adr = 0;
+ io_data_object->f_crc_seed = FALSE;
+ io_data_object->f_crc_len = 0;
+ /* Reset as a PNIO Connect Request of a known module appears */
+ io_data_object->last_sb_cb = 0;
+ io_data_object->lastToggleBit = 0;
+
+ if (u16IOCRType == PN_INPUT_CR) {
+ iocs_list = station_info->ioobject_data_in;
+ }
+ else {
+ iocs_list = station_info->ioobject_data_out;
+ }
+
+ for (frame = wmem_list_head(iocs_list); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ cmp_io_data_object = (ioDataObject*)wmem_list_frame_data(frame);
+ if (cmp_io_data_object->slotNr == u16SlotNr && cmp_io_data_object->subSlotNr == u16SubslotNr) {
+ /* Found identical existing object */
+ break;
+ }
+ }
+
+ if (frame == NULL) {
+ /* new io_object data incoming */
+ wmem_list_append(iocs_list, io_data_object);
+ }
+ }
+ }
+
+ /* NumberOfIOCS */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_number_of_iocs, &u16NumberOfIOCSInAPI);
+
+ /* Set global Vairant for NumberOfIOCS */
+ if (!PINFO_FD_VISITED(pinfo)) {
+ u16NumberOfIOCSInCR += u16NumberOfIOCSInAPI;
+ }
+
+ u16Tmp = u16NumberOfIOCSInAPI;
+ while (u16Tmp--) {
+ sub_item = proto_tree_add_item(api_tree, hf_pn_io_io_cs, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_io_cs);
+ u32SubStart = offset;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* IOCSFrameOffset */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_iocs_frame_offset, &u16IOCSFrameOffset);
+
+ proto_item_append_text(sub_item, ": Slot: 0x%x, Subslot: 0x%x FrameOffset: %u",
+ u16SlotNr, u16SubslotNr, u16IOCSFrameOffset);
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ if (station_info != NULL) {
+ if (u16IOCRType == PN_INPUT_CR) {
+ iocs_list = station_info->iocs_data_in;
+ }
+ else {
+ iocs_list = station_info->iocs_data_out;
+ }
+
+ for (frame = wmem_list_head(iocs_list); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ cmp_iocs_object = (iocsObject*)wmem_list_frame_data(frame);
+ if (cmp_iocs_object->slotNr == u16SlotNr && cmp_iocs_object->subSlotNr == u16SubslotNr) {
+ /* Found identical existing object */
+ break;
+ }
+ }
+
+ if (frame == NULL) {
+ /* new iocs_object data incoming */
+ iocs_object = wmem_new(wmem_file_scope(), iocsObject);
+ iocs_object->slotNr = u16SlotNr;
+ iocs_object->subSlotNr = u16SubslotNr;
+ iocs_object->frameOffset = u16IOCSFrameOffset;
+ wmem_list_append(iocs_list, iocs_object);
+ }
+ }
+ }
+ }
+
+ proto_item_append_text(api_item, ": 0x%x, NumberOfIODataObjects: %u NumberOfIOCS: %u",
+ u32Api, u16NumberOfIODataObjectsInAPI, u16NumberOfIOCSInAPI);
+
+ proto_item_set_len(api_item, offset - u32ApiStart);
+ }
+
+ /* Update global object count */
+ if (!PINFO_FD_VISITED(pinfo)) {
+ if (station_info != NULL) {
+ if (u16IOCRType == PN_INPUT_CR) {
+ station_info->iocsNr_in = u16NumberOfIOCSInCR;
+ station_info->ioDataObjectNr_in = u16NumberOfIODataObjectsInCR;
+ } else {
+ station_info->iocsNr_out = u16NumberOfIOCSInCR;
+ station_info->ioDataObjectNr_out = u16NumberOfIODataObjectsInCR;
+ }
+ }
+ }
+
+ if (ar != NULL) {
+ switch (u16IOCRType) {
+ case(1): /* Input CR */
+ if (ar->inputframeid != 0 && ar->inputframeid != u16FrameID) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_frame_id, "IOCRBlockReq: input frameID changed from %u to %u!", ar->inputframeid, u16FrameID);
+ }
+ ar->inputframeid = u16FrameID;
+ break;
+ case(2): /* Output CR */
+#if 0
+ /* will usually contain 0xffff here because the correct framid will be given in the connect.Cnf */
+ if (ar->outputframeid != 0 && ar->outputframeid != u16FrameID) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_frame_id, "IOCRBlockReq: output frameID changed from %u to %u!", ar->outputframeid, u16FrameID);
+ }
+ ar->outputframeid = u16FrameID;
+#endif
+ break;
+ default:
+ expert_add_info_format(pinfo, item, &ei_pn_io_iocr_type, "IOCRBlockReq: IOCRType %u undecoded!", u16IOCRType);
+ }
+ } else {
+ expert_add_info_format(pinfo, item, &ei_pn_io_ar_info_not_found, "IOCRBlockReq: no corresponding AR found!");
+ }
+
+ return offset;
+}
+
+
+/* dissect the AlarmCRBlockReq */
+static int
+dissect_AlarmCRBlockReq_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ pnio_ar_t *ar)
+{
+ guint16 u16AlarmCRType;
+ guint16 u16LT;
+ guint32 u32AlarmCRProperties;
+ guint16 u16RTATimeoutFactor;
+ guint16 u16RTARetries;
+ guint16 u16LocalAlarmReference;
+ guint16 u16MaxAlarmDataLength;
+ guint16 u16AlarmCRTagHeaderHigh;
+ guint16 u16AlarmCRTagHeaderLow;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_alarmcr_type, &u16AlarmCRType);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_lt, &u16LT);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_alarmcr_properties, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_alarmcr_properties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarmcr_properties_reserved, &u32AlarmCRProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarmcr_properties_transport, &u32AlarmCRProperties);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarmcr_properties_priority, &u32AlarmCRProperties);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rta_timeoutfactor, &u16RTATimeoutFactor);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rta_retries, &u16RTARetries);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_localalarmref, &u16LocalAlarmReference);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_maxalarmdatalength, &u16MaxAlarmDataLength);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_alarmcr_tagheaderhigh, &u16AlarmCRTagHeaderHigh);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_alarmcr_tagheaderlow, &u16AlarmCRTagHeaderLow);
+
+ proto_item_append_text(item, ": %s, LT:0x%x, TFactor:%u, Retries:%u, Ref:0x%x, Len:%u Tag:0x%x/0x%x",
+ val_to_str(u16AlarmCRType, pn_io_alarmcr_type, "0x%x"),
+ u16LT, u16RTATimeoutFactor, u16RTARetries, u16LocalAlarmReference, u16MaxAlarmDataLength,
+ u16AlarmCRTagHeaderHigh, u16AlarmCRTagHeaderLow);
+
+ if (ar != NULL) {
+ if (ar->controlleralarmref != 0xffff && ar->controlleralarmref != u16LocalAlarmReference) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_localalarmref, "AlarmCRBlockReq: local alarm ref changed from %u to %u!", ar->controlleralarmref, u16LocalAlarmReference);
+ }
+ ar->controlleralarmref = u16LocalAlarmReference;
+ } else {
+ expert_add_info_format(pinfo, item, &ei_pn_io_ar_info_not_found, "AlarmCRBlockReq: no corresponding AR found!");
+ }
+
+ return offset;
+}
+
+
+/* dissect the AlarmCRBlockRes */
+static int
+dissect_AlarmCRBlockRes_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ pnio_ar_t *ar)
+{
+ guint16 u16AlarmCRType;
+ guint16 u16LocalAlarmReference;
+ guint16 u16MaxAlarmDataLength;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_alarmcr_type, &u16AlarmCRType);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_localalarmref, &u16LocalAlarmReference);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_maxalarmdatalength, &u16MaxAlarmDataLength);
+
+ proto_item_append_text(item, ": %s, Ref:0x%04x, MaxDataLen:%u",
+ val_to_str(u16AlarmCRType, pn_io_alarmcr_type, "0x%x"),
+ u16LocalAlarmReference, u16MaxAlarmDataLength);
+
+ if (ar != NULL) {
+ if (ar->devicealarmref != 0xffff && ar->devicealarmref != u16LocalAlarmReference) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_localalarmref, "AlarmCRBlockRes: local alarm ref changed from %u to %u!", ar->devicealarmref, u16LocalAlarmReference);
+ }
+ ar->devicealarmref = u16LocalAlarmReference;
+ } else {
+ expert_add_info_format(pinfo, item, &ei_pn_io_ar_info_not_found, "AlarmCRBlockRes: no corresponding AR found!");
+ }
+
+ return offset;
+}
+
+/* dissect the ARServerBlock */
+static int
+dissect_ARServerBlock(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BodyLength)
+{
+ guint16 u16NameLength, u16padding;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_station_name_length, &u16NameLength);
+
+ proto_tree_add_item (tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, ENC_ASCII);
+ offset += u16NameLength;
+ /* Padding to next 4 byte alignment in this block */
+ u16padding = u16BodyLength - (2 + u16NameLength);
+ if (u16padding > 0)
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, u16padding);
+ return offset;
+}
+
+
+
+/* dissect the IOCRBlockRes */
+static int
+dissect_IOCRBlockRes_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ pnio_ar_t *ar)
+{
+ guint16 u16IOCRType;
+ guint16 u16IOCRReference;
+ guint16 u16FrameID;
+
+ ARUUIDFrame *current_aruuid_frame = NULL;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_iocr_type, &u16IOCRType);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_iocr_reference, &u16IOCRReference);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_frame_id, &u16FrameID);
+
+ proto_item_append_text(item, ": %s, Ref:0x%04x, FrameID:0x%04x",
+ val_to_str(u16IOCRType, pn_io_iocr_type, "0x%x"),
+ u16IOCRReference, u16FrameID);
+
+ if (ar != NULL) {
+ switch (u16IOCRType) {
+ case(1): /* Input CR */
+ if (ar->inputframeid != 0 && ar->inputframeid != u16FrameID) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_frame_id, "IOCRBlockRes: input frameID changed from %u to %u!", ar->inputframeid, u16FrameID);
+ }
+ ar->inputframeid = u16FrameID;
+ break;
+ case(2): /* Output CR */
+ if (ar->outputframeid != 0 && ar->outputframeid != u16FrameID) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_frame_id, "IOCRBlockRes: output frameID changed from %u to %u!", ar->outputframeid, u16FrameID);
+ }
+ ar->outputframeid = u16FrameID;
+ break;
+ default:
+ expert_add_info_format(pinfo, item, &ei_pn_io_iocr_type, "IOCRBlockRes: IOCRType %u undecoded!", u16IOCRType);
+ }
+ } else {
+ expert_add_info_format(pinfo, item, &ei_pn_io_ar_info_not_found, "IOCRBlockRes: no corresponding AR found!");
+ }
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ current_aruuid_frame = pn_find_aruuid_frame_setup(pinfo);
+ if (current_aruuid_frame != NULL) {
+ if (u16IOCRType == 1) {
+ current_aruuid_frame->inputframe = u16FrameID;
+ }
+ else if (u16IOCRType == 2) {
+ current_aruuid_frame->outputframe = u16FrameID;
+ }
+ }
+ }
+
+ return offset;
+}
+
+
+
+/* dissect the MCRBlockReq */
+static int
+dissect_MCRBlockReq_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16IOCRReference;
+ guint32 u32AddressResolutionProperties;
+ guint16 u16MCITimeoutFactor;
+ guint16 u16NameLength;
+ char *pStationName;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_iocr_reference, &u16IOCRReference);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_address_resolution_properties, &u32AddressResolutionProperties);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_mci_timeout_factor, &u16MCITimeoutFactor);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_station_name_length, &u16NameLength);
+
+ proto_tree_add_item_ret_display_string (tree, hf_pn_io_provider_station_name, tvb, offset, u16NameLength, ENC_ASCII, pinfo->pool, &pStationName);
+ offset += u16NameLength;
+
+ proto_item_append_text(item, ", CRRef:%u, Properties:0x%x, TFactor:%u, Station:%s",
+ u16IOCRReference, u32AddressResolutionProperties, u16MCITimeoutFactor, pStationName);
+
+ return offset;
+}
+
+
+
+/* dissect the SubFrameBlock */
+static int
+dissect_SubFrameBlock_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint16 u16IOCRReference;
+ guint8 mac[6];
+ guint32 u32SubFrameData;
+ guint16 u16Tmp;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* IOCRReference */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_iocr_reference, &u16IOCRReference);
+
+ /* CMInitiatorMACAdd */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree,
+ hf_pn_io_cminitiator_macadd, mac);
+
+ /* SubFrameData n*32 */
+ u16BodyLength -= 10;
+ u16Tmp = u16BodyLength;
+ do {
+ sub_item = proto_tree_add_item(tree, hf_pn_io_subframe_data, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_subframe_data);
+ /* 31-16 reserved_2 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subframe_data_reserved2, &u32SubFrameData);
+ /* 15- 8 DataLength */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subframe_data_length, &u32SubFrameData);
+ /* 7 reserved_1 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subframe_data_reserved1, &u32SubFrameData);
+ /* 6-0 Position */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subframe_data_position, &u32SubFrameData);
+
+ proto_item_append_text(sub_item, ", Length:%u, Pos:%u",
+ (u32SubFrameData & 0x0000FF00) >> 8, u32SubFrameData & 0x0000007F);
+ } while (u16Tmp -= 4);
+
+ proto_item_append_text(item, ", CRRef:%u, %u*Data",
+ u16IOCRReference, u16BodyLength/4);
+
+ return offset;
+}
+
+/* dissect the (PD)SubFrameBlock 0x022B */
+static int
+dissect_PDSubFrameBlock_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint32 u32SFIOCRProperties;
+ guint32 u32SubFrameData;
+ guint16 u16FrameID;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16RemainingLength;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ /* FrameID */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_frame_id, &u16FrameID);
+ /* SFIOCRProperties */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_SFIOCRProperties, tvb, offset, PD_SUB_FRAME_BLOCK_FIOCR_PROPERTIES_LENGTH, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_SFIOCRProperties);
+
+ /* dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_SFIOCRProperties, &u32SFIOCRProperties); */
+ /* Bit 31: SFIOCRProperties.SFCRC16 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_SFIOCRProperties_SFCRC16, &u32SFIOCRProperties);
+
+ /* Bit 30: SFIOCRProperties.DFPRedundantPathLayout */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_SFIOCRProperties_DFPRedundantPathLayout, &u32SFIOCRProperties);
+ /* Bit 29: SFIOCRProperties.DFPRedundantPathLayout */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_SFIOCRProperties_DFPType, &u32SFIOCRProperties);
+ /* Bit 28 - 29: SFIOCRProperties.reserved_2 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_SFIOCRProperties_reserved_2, &u32SFIOCRProperties);
+ /* Bit 24 - 27: SFIOCRProperties.reserved_1 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_SFIOCRProperties_reserved_1, &u32SFIOCRProperties);
+ /* Bit 16 - 23: SFIOCRProperties.DFPmode */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_SFIOCRProperties_DFPmode, &u32SFIOCRProperties);
+ /* Bit 8 - 15: SFIOCRProperties.RestartFactorForDistributedWD */
+ /* 0x00 Mandatory No restart delay necessary
+ 0x01 - 0x09 Optional Less than 1 s restart delay
+ 0x0A - 0x50 Mandatory 1 s to 8 s restart delay
+ 0x51 - 0xFF Optional More than 8 s restart delay */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_RestartFactorForDistributedWD, &u32SFIOCRProperties);
+ /* bit 0..7 SFIOCRProperties.DistributedWatchDogFactor */
+ offset = /* it is the last one, so advance! */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_DistributedWatchDogFactor, &u32SFIOCRProperties);
+
+ /* SubframeData */
+ u16RemainingLength = u16BodyLength - PD_SUB_FRAME_BLOCK_FIOCR_PROPERTIES_LENGTH - PD_SUB_FRAME_BLOCK_FRAME_ID_LENGTH;
+ while (u16RemainingLength >= PD_SUB_FRAME_BLOCK_SUB_FRAME_DATA_LENGTH)
+ {
+ guint8 Position,
+ DataLength;
+ sub_item = proto_tree_add_item(tree, hf_pn_io_subframe_data, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_subframe_data);
+
+ /* Bit 0 - 6: SubframeData.Position */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_subframe_data_position, &u32SubFrameData);
+ /* Bit 7: SubframeData.reserved_1 */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_subframe_reserved1, &u32SubFrameData);
+ /* Bit 8 - 15: SubframeData.dataLength */
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_subframe_data_length, &u32SubFrameData);
+ /* Bit 16 - 31: SubframeData.reserved_2 */
+ offset =
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_subframe_reserved2, &u32SubFrameData);
+ Position = (guint8) (u32SubFrameData & 0x7F); /* the lower 6 bits */
+ DataLength =(guint8) ((u32SubFrameData >>8) & 0x0ff); /* bit 8 to 15 */
+ proto_item_append_text(sub_item, ", Length:%u (0x%x), Pos:%u",
+ DataLength,DataLength, Position);
+ u16RemainingLength = u16RemainingLength - 4;
+ }
+ return offset;
+}
+
+
+/* dissect the IRInfoBlock */
+static int
+dissect_IRInfoBlock_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength _U_)
+{
+ guint16 u16NumberOfIOCR;
+ guint16 u16SubframeOffset;
+ guint32 u32SubframeData;
+ guint16 u16IOCRReference;
+ e_guid_t IRDataUUID;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_IRData_uuid, &IRDataUUID);
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ /* Numbers of IOCRs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_iocrs, &u16NumberOfIOCR);
+
+ while (u16NumberOfIOCR--)
+ { /* IOCRReference */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_iocr_reference, &u16IOCRReference);
+
+ /* SubframeOffset 16 */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_iocr_SubframeOffset, &u16SubframeOffset);
+
+ /* SubframeData 32 */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_iocr_SubframeData, &u32SubframeData);
+ }
+ return offset;
+}
+
+/* dissect the SRInfoBlock */
+static int
+dissect_SRInfoBlock_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength _U_)
+{
+ guint16 u16RedundancyDataHoldFactor;
+ guint32 u32sr_properties;
+ guint8 u8SRPropertiesMode;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_RedundancyDataHoldFactor, &u16RedundancyDataHoldFactor);
+
+ u32sr_properties = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
+ sub_item = proto_tree_add_item(tree, hf_pn_io_sr_properties, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_sr_properties);
+
+ u8SRPropertiesMode = (guint8)((u32sr_properties >> 2) & 0x01);
+
+ /* SRProperties.InputValidOnBackupAR with SRProperties.Mode == 1 */
+ if (u8SRPropertiesMode)
+ {
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_sr_properties_InputValidOnBackupAR_with_SRProperties_Mode_1, &u32sr_properties);
+ }
+ /* SRProperties.InputValidOnBackupAR with SRProperties.Mode == 0 */
+ else
+ {
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_sr_properties_InputValidOnBackupAR_with_SRProperties_Mode_0, &u32sr_properties);
+ }
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_sr_properties_Reserved_1, &u32sr_properties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_sr_properties_Mode, &u32sr_properties);
+
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_sr_properties_Reserved_2, &u32sr_properties);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_sr_properties_Reserved_3, &u32sr_properties);
+ return offset;
+}
+
+/* dissect the RSInfoBlock */
+static int
+dissect_RSInfoBlock_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+ guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow, guint16 u16BodyLength _U_)
+{
+ guint32 u32RSProperties;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* Padding 2 + 2 + 1 + 1 = 6 */
+ /* Therefore we need 2 byte padding to make the block u32 aligned */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_rs_properties, &u32RSProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_rs_properties_alarm_transport, &u32RSProperties);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_rs_properties_reserved1, &u32RSProperties);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_rs_properties_reserved2, &u32RSProperties);
+
+ return offset;
+}
+
+/* dissect the PDIRSubframeData block 0x022a */
+static int
+dissect_PDIRSubframeData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberOfSubframeBlocks;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_NumberOfSubframeBlocks, &u16NumberOfSubframeBlocks);
+
+ while (u16NumberOfSubframeBlocks --)
+ { /* dissect the Subframe Block */
+ offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep);
+ }
+
+ return offset;
+}
+
+static int
+dissect_ARVendorBlockReq_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength _U_)
+{
+ guint16 APStructureIdentifier;
+ guint32 gu32API;
+ guint32 guDataBytes;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ APStructureIdentifier = ((drep[0] & DREP_LITTLE_ENDIAN)
+ ? tvb_get_letohs(tvb, offset)
+ : tvb_get_ntohs(tvb, offset));
+
+ gu32API = ((drep[0] & DREP_LITTLE_ENDIAN)
+ ? tvb_get_letohl(tvb, offset + 2)
+ : tvb_get_ntohl (tvb, offset + 2));
+
+ if (tree)
+ {
+ if (gu32API == 0)
+ {
+ if (APStructureIdentifier <0x8000)
+ {
+ proto_tree_add_item(tree, hf_pn_io_arvendor_strucidentifier_if0_low, tvb, offset, 2, DREP_ENC_INTEGER(drep));
+ }
+ else
+ {
+ if (APStructureIdentifier > 0x8000)
+ {
+ proto_tree_add_item(tree, hf_pn_io_arvendor_strucidentifier_if0_high, tvb, offset, 2, DREP_ENC_INTEGER(drep));
+ }
+ else /* APStructureIdentifier == 0x8000 */
+ {
+ proto_tree_add_item(tree, hf_pn_io_arvendor_strucidentifier_if0_is8000, tvb, offset, 2, DREP_ENC_INTEGER(drep));
+ }
+ }
+ }
+ else
+ {
+ proto_tree_add_item(tree, hf_pn_io_arvendor_strucidentifier_not0, tvb, offset, 2, DREP_ENC_INTEGER(drep));
+ }
+ /* API */
+ proto_tree_add_item(tree, hf_pn_io_api, tvb, offset + 2, 4, DREP_ENC_INTEGER(drep));
+ }
+ offset += 6;
+ if (u16BodyLength < 6 )
+ return offset; /* there are no user bytes! */
+ guDataBytes = u16BodyLength - 6;
+
+ dissect_pn_user_data(tvb, offset, pinfo, tree, guDataBytes, "Data ");
+ return offset;
+}
+
+/* dissect the DataDescription */
+static int
+dissect_DataDescription(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, ioDataObject *tmp_io_data_object)
+{
+ guint16 u16DataDescription;
+ guint16 u16SubmoduleDataLength;
+ guint8 u8LengthIOCS;
+ guint8 u8LengthIOPS;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+
+ conversation_t *conversation;
+ stationInfo *station_info = NULL;
+ ioDataObject *io_data_object;
+ wmem_list_frame_t *frame;
+ wmem_list_t *ioobject_list;
+
+ ARUUIDFrame *current_aruuid_frame = NULL;
+ guint32 current_aruuid = 0;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_data_description_tree, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_data_description);
+ u32SubStart = offset;
+
+ /* DataDescription */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_data_description, &u16DataDescription);
+ /* SubmoduleDataLength */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_submodule_data_length, &u16SubmoduleDataLength);
+ /* LengthIOCS */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_length_iocs, &u8LengthIOCS);
+ /* LengthIOPS */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_length_iops, &u8LengthIOPS);
+
+ proto_item_append_text(sub_item, ": %s, SubmoduleDataLength: %u, LengthIOCS: %u, u8LengthIOPS: %u",
+ val_to_str(u16DataDescription, pn_io_data_description, "(0x%x)"),
+ u16SubmoduleDataLength, u8LengthIOCS, u8LengthIOPS);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ /* Save new data for IO Data Objects */
+ if (!PINFO_FD_VISITED(pinfo)) {
+ /* Get current conversation endpoints using MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, if no "Ident OK" frame as been dissected yet!
+ * Need to switch dl_src & dl_dst, as current packet is sent by controller and not by device.
+ * All conversations are based on Device MAC as addr1 */
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ current_aruuid_frame = pn_find_aruuid_frame_setup(pinfo);
+
+ if (current_aruuid_frame != NULL) {
+ current_aruuid = current_aruuid_frame->aruuid.data1;
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, current_aruuid);
+
+ if (station_info != NULL) {
+ pn_find_dcp_station_info(station_info, conversation);
+
+ if (u16DataDescription == PN_INPUT_DATADESCRITPION) {
+ /* INPUT HANDLING */
+ ioobject_list = station_info->ioobject_data_in;
+ }
+ else {
+ /* OUTPUT HANDLING */
+ ioobject_list = station_info->ioobject_data_out;
+ }
+
+ for (frame = wmem_list_head(ioobject_list); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ io_data_object = (ioDataObject*)wmem_list_frame_data(frame);
+ if (io_data_object->slotNr == tmp_io_data_object->slotNr && io_data_object->subSlotNr == tmp_io_data_object->subSlotNr) {
+ /* Write additional data from dissect_ExpectedSubmoduleBlockReq_block() to corresponding io_data_object */
+ io_data_object->api = tmp_io_data_object->api;
+ io_data_object->moduleIdentNr = tmp_io_data_object->moduleIdentNr;
+ io_data_object->subModuleIdentNr = tmp_io_data_object->subModuleIdentNr;
+ io_data_object->length = u16SubmoduleDataLength;
+
+ io_data_object->moduleNameStr = wmem_strdup(wmem_file_scope(), tmp_io_data_object->moduleNameStr);
+ io_data_object->profisafeSupported = tmp_io_data_object->profisafeSupported;
+ io_data_object->discardIOXS = tmp_io_data_object->discardIOXS;
+ io_data_object->amountInGSDML = tmp_io_data_object->amountInGSDML;
+ io_data_object->fParameterIndexNr = tmp_io_data_object->fParameterIndexNr;
+
+ break;
+ }
+ }
+ }
+ }
+
+ return offset;
+}
+
+
+static int
+resolve_pa_profile_submodule_name(ioDataObject *io_data_object)
+{
+ const uint32_t u32SubmoduleIdentNumber = io_data_object->subModuleIdentNr;
+ /* split components of submodule ident number */
+ const uint8_t variant = (u32SubmoduleIdentNumber >> 24u) & 0xFFu;
+ const uint8_t block_object = (u32SubmoduleIdentNumber >> 16u) & 0xFFu;
+ const uint8_t parent_class = (u32SubmoduleIdentNumber >> 8u) & 0xFFu;
+ const uint8_t class = (u32SubmoduleIdentNumber) & 0xFFu;
+
+ const gchar* parent_class_name = NULL;
+ const gchar* class_name = NULL;
+
+ const gchar* block_object_name = try_val_to_str(block_object, pn_io_pa_profile_block_object_vals);
+
+ if (block_object_name != NULL)
+ {
+ switch (block_object)
+ {
+ case PA_PROFILE_BLOCK_DAP:
+ if (parent_class == 0u)
+ {
+ class_name = try_val_to_str(class, pn_io_pa_profile_dap_submodule_vals);
+ if (class_name != NULL)
+ {
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "%s - %s", block_object_name, class_name);
+ }
+ }
+ else
+ {
+ /* we have an interface or a port */
+ if (class == 0u)
+ {
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "Interface %d", parent_class);
+ }
+ else
+ {
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "Port %d Interface %d", class, parent_class);
+ }
+ }
+ break;
+
+ case PA_PROFILE_BLOCK_PB:
+ parent_class_name = try_val_to_str(parent_class, pn_io_pa_profile_physical_block_parent_class_vals);
+ if (parent_class_name != NULL)
+ {
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "%s - %s", block_object_name, parent_class_name);
+ }
+ else
+ {
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "%s - Unknown", block_object_name);
+ }
+ break;
+
+ case PA_PROFILE_BLOCK_FB:
+ class_name = try_val_to_str(class, pn_io_pa_profile_function_block_class_vals);
+ if (class <= 2u)
+ {
+ parent_class_name = try_val_to_str(parent_class, pn_io_pa_profile_function_block_parent_class_vals);
+ }
+ else
+ {
+ parent_class_name = (class <= 4u) ? "Analog" : "";
+ }
+
+ if ((parent_class_name != NULL) && (class_name != NULL))
+ {
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "%s - %s %s", block_object_name, parent_class_name, class_name);
+ }
+ else
+ {
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "%s - Unknown", block_object_name);
+ }
+ break;
+
+ case PA_PROFILE_BLOCK_TB:
+ parent_class_name = try_val_to_str(parent_class, pn_io_pa_profile_transducer_block_parent_class_vals);
+ if (parent_class_name != NULL)
+ {
+ class_name = try_val_to_str(class, pn_io_pa_profile_transducer_block_class_vals[parent_class]);
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "%s - %s (%s)", block_object_name, parent_class_name, class_name);
+ }
+ else
+ {
+ (void)snprintf(io_data_object->moduleNameStr, MAX_NAMELENGTH, "%s - Unknown", block_object_name);
+ }
+ break;
+ }
+
+ if (variant != 0u)
+ {
+ g_strlcat (io_data_object->moduleNameStr, " (VARIANT)", MAX_NAMELENGTH);
+ }
+
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* dissect the ExpectedSubmoduleBlockReq */
+static int
+dissect_ExpectedSubmoduleBlockReq_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberOfAPIs;
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint32 u32ModuleIdentNumber;
+ guint16 u16ModuleProperties;
+ guint16 u16NumberOfSubmodules;
+ guint16 u16SubslotNr;
+ guint32 u32SubmoduleIdentNumber;
+ guint16 u16SubmoduleProperties;
+ proto_item *api_item;
+ proto_tree *api_tree;
+ guint32 u32ApiStart;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ proto_item *submodule_item;
+ proto_tree *submodule_tree;
+ guint32 u32SubStart;
+
+ /* Variable for the search of gsd file */
+ const char vendorIdStr[] = "VendorID=\"";
+ const char deviceIdStr[] = "DeviceID=\"";
+ const char moduleStr[] = "ModuleIdentNumber=\"";
+ const char subModuleStr[] = "SubmoduleIdentNumber=\"";
+ const char profisafeStr[] = "PROFIsafeSupported=\"true\"";
+ const char fParameterStr[] = "<F_ParameterRecordDataItem";
+ const char fParameterIndexStr[] = "Index=";
+ const char moduleNameInfo[] = "<Name";
+ const char moduleValueInfo[] = "Value=\"";
+
+ guint16 searchVendorID = 0;
+ guint16 searchDeviceID = 0;
+ gboolean vendorMatch;
+ gboolean deviceMatch;
+ conversation_t *conversation;
+ stationInfo *station_info = NULL;
+ ioDataObject *io_data_object = NULL; /* Used to transfer data to fct. "dissect_DataDescription()" */
+
+ /* Variable for the search of GSD-file */
+ guint32 read_vendor_id;
+ guint32 read_device_id;
+ guint32 read_module_id;
+ guint32 read_submodule_id;
+ gboolean gsdmlFoundFlag;
+ gchar tmp_moduletext[MAX_NAMELENGTH];
+ gchar *convertStr; /* GSD-file search */
+ gchar *pch; /* helppointer, to save temp. the found Networkpath of GSD-file */
+ gchar *puffer; /* used for fgets() during GSD-file search */
+ gchar *temp; /* used for fgets() during GSD-file search */
+ gchar *diropen = NULL; /* saves the final networkpath to open for GSD-files */
+ GDir *dir;
+ FILE *fp = NULL; /* filepointer */
+ const gchar *filename; /* saves the found GSD-file name */
+
+ ARUUIDFrame *current_aruuid_frame = NULL;
+ guint32 current_aruuid = 0;
+
+ /* Helppointer initial */
+ convertStr = (gchar*)wmem_alloc(pinfo->pool, MAX_NAMELENGTH);
+ convertStr[0] = '\0';
+ pch = (gchar*)wmem_alloc(pinfo->pool, MAX_LINE_LENGTH);
+ pch[0] = '\0';
+ puffer = (gchar*)wmem_alloc(pinfo->pool, MAX_LINE_LENGTH);
+ puffer[0] = '\0';
+ temp = (gchar*)wmem_alloc(pinfo->pool, MAX_LINE_LENGTH);
+ temp[0] = '\0';
+
+ /* Initial */
+ io_data_object = wmem_new0(wmem_file_scope(), ioDataObject);
+ io_data_object->profisafeSupported = FALSE;
+ io_data_object->moduleNameStr = (gchar*)wmem_alloc(wmem_file_scope(), MAX_NAMELENGTH);
+ (void) g_strlcpy(io_data_object->moduleNameStr, "Unknown", MAX_NAMELENGTH);
+ vendorMatch = FALSE;
+ deviceMatch = FALSE;
+ gsdmlFoundFlag = FALSE;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+
+ proto_item_append_text(item, ": APIs:%u", u16NumberOfAPIs);
+
+
+ /* Get current conversation endpoints using MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, if no "Ident OK" frame as been dissected yet!
+ * Need to switch dl_src & dl_dst, as current packet is sent by controller and not by device.
+ * All conversations are based on Device MAC as addr1 */
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ current_aruuid_frame = pn_find_aruuid_frame_setup(pinfo);
+
+ if (current_aruuid_frame != NULL) {
+ current_aruuid = current_aruuid_frame->aruuid.data1;
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, current_aruuid);
+
+ if (station_info != NULL) {
+ pn_find_dcp_station_info(station_info, conversation);
+
+ station_info->gsdFound = FALSE;
+ station_info->gsdPathLength = FALSE;
+
+ /* Set searchVendorID and searchDeviceID for GSDfile search */
+ searchVendorID = station_info->u16Vendor_id;
+ searchDeviceID = station_info->u16Device_id;
+
+ /* Use the given GSD-file networkpath of the PNIO-Preference */
+ if(pnio_ps_networkpath[0] != '\0') { /* check the length of the given networkpath (array overflow protection) */
+ station_info->gsdPathLength = TRUE;
+
+ if ((dir = g_dir_open(pnio_ps_networkpath, 0, NULL)) != NULL) {
+ /* Find all GSD-files within directory */
+ while ((filename = g_dir_read_name(dir)) != NULL) {
+
+ /* ---- complete the path to open a GSD-file ---- */
+ diropen = wmem_strdup_printf(pinfo->pool, "%s" G_DIR_SEPARATOR_S "%s", pnio_ps_networkpath, filename);
+
+ /* ---- Open the found GSD-file ---- */
+ fp = ws_fopen(diropen, "r");
+
+ if(fp != NULL) {
+ /* ---- Get VendorID & DeviceID ---- */
+ while(pn_fgets(puffer, MAX_LINE_LENGTH, fp, pinfo->pool) != NULL) {
+ /* ----- VendorID ------ */
+ if((strstr(puffer, vendorIdStr)) != NULL) {
+ memset (convertStr, 0, sizeof(*convertStr));
+ pch = strstr(puffer, vendorIdStr);
+ if (pch!= NULL && sscanf(pch, "VendorID=\"%199[^\"]", convertStr) == 1) {
+ read_vendor_id = (guint32) strtoul (convertStr, NULL, 0);
+
+ if(read_vendor_id == searchVendorID) {
+ vendorMatch = TRUE; /* found correct VendorID */
+ }
+ }
+ }
+
+ /* ----- DeviceID ------ */
+ if((strstr(puffer, deviceIdStr)) != NULL) {
+ memset(convertStr, 0, sizeof(*convertStr));
+ pch = strstr(puffer, deviceIdStr);
+ if (pch != NULL && sscanf(pch, "DeviceID=\"%199[^\"]", convertStr) == 1) {
+ read_device_id = (guint32)strtoul(convertStr, NULL, 0);
+
+ if(read_device_id == searchDeviceID) {
+ deviceMatch = TRUE; /* found correct DeviceID */
+ }
+ }
+ }
+ }
+
+ fclose(fp);
+ fp = NULL;
+
+ if(vendorMatch && deviceMatch) {
+ break; /* Found correct GSD-file! -> Break the searchloop */
+ }
+ else {
+ /* Couldn't find the correct GSD-file to the corresponding device */
+ vendorMatch = FALSE;
+ deviceMatch = FALSE;
+ gsdmlFoundFlag = FALSE;
+ diropen = ""; /* reset array for next search */
+ }
+ }
+ }
+
+ g_dir_close(dir);
+ }
+
+ /* ---- Found the correct GSD-file -> set Flag and save the completed path ---- */
+ if(vendorMatch && deviceMatch) {
+ gsdmlFoundFlag = TRUE;
+ station_info->gsdFound = TRUE;
+ station_info->gsdLocation = wmem_strdup(wmem_file_scope(), diropen);
+ }
+ else {
+ /* Copy searchpath to array for a detailed output message in cyclic data dissection */
+ station_info->gsdLocation = wmem_strdup_printf(wmem_file_scope(), "%s" G_DIR_SEPARATOR_S "*.xml", pnio_ps_networkpath);
+ }
+ }
+ else {
+ /* will be used later on in cyclic RTC1 data dissection for detailed output message */
+ station_info->gsdPathLength = FALSE;
+ }
+ }
+
+ while (u16NumberOfAPIs--) {
+ api_item = proto_tree_add_item(tree, hf_pn_io_api_tree, tvb, offset, 0, ENC_NA);
+ api_tree = proto_item_add_subtree(api_item, ett_pn_io_api);
+ u32ApiStart = offset;
+
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_api, &u32Api);
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* ModuleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
+ /* ModuleProperties */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_module_properties, &u16ModuleProperties);
+ /* NumberOfSubmodules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_number_of_submodules, &u16NumberOfSubmodules);
+
+ proto_item_append_text(api_item, ": %u, Slot:0x%x, IdentNumber:0x%x Properties:0x%x Submodules:%u",
+ u32Api, u16SlotNr, u32ModuleIdentNumber, u16ModuleProperties, u16NumberOfSubmodules);
+
+ proto_item_append_text(item, ", Submodules:%u", u16NumberOfSubmodules);
+
+ while (u16NumberOfSubmodules--) {
+ sub_item = proto_tree_add_item(api_tree, hf_pn_io_submodule_tree, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_submodule);
+ u32SubStart = offset;
+
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* SubmoduleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
+ /* SubmoduleProperties */
+ submodule_item = proto_tree_add_item(sub_tree, hf_pn_io_submodule_properties, tvb, offset, 2, ENC_BIG_ENDIAN);
+ submodule_tree = proto_item_add_subtree(submodule_item, ett_pn_io_submodule_properties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_properties_reserved, &u16SubmoduleProperties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_properties_discard_ioxs, &u16SubmoduleProperties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_properties_reduce_output_submodule_data_length, &u16SubmoduleProperties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_properties_reduce_input_submodule_data_length, &u16SubmoduleProperties);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_properties_shared_input, &u16SubmoduleProperties);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_properties_type, &u16SubmoduleProperties);
+
+ io_data_object->api = u32Api;
+ io_data_object->slotNr = u16SlotNr;
+ io_data_object->subSlotNr = u16SubslotNr;
+ io_data_object->moduleIdentNr = u32ModuleIdentNumber;
+ io_data_object->subModuleIdentNr = u32SubmoduleIdentNumber;
+ io_data_object->discardIOXS = u16SubmoduleProperties & 0x0020;
+
+ /* Before searching the GSD, check if we have a PA Profile 4.02 submodule. If yes
+ then the submodule's name is defined in the specification and can be resolved
+ without the GSD.
+ We still read the GSD afterwards, in case the user wants to override the specification's
+ names with a GSD.
+ Most PA Profile submodules are located in API 0x9700, but the DAP and the interfaces/ports
+ are located in API 0 per PROFINET specification, so we need to filter also on the DAP module
+ ident number.
+ */
+ if ((io_data_object->api == PA_PROFILE_API) ||
+ ((io_data_object->moduleIdentNr & PA_PROFILE_DAP_MASK) == PA_PROFILE_DAP_IDENT))
+ {
+ resolve_pa_profile_submodule_name(io_data_object);
+ }
+
+
+ /* Search the moduleID and subModuleID, find if PROFIsafe and also search for F-Par. Indexnumber
+ * ---------------------------------------------------------------------------------------------
+ * Speical case: Module has several ModuleIdentNr. in one GSD-file
+ * Also with the given parameters of wireshark, some modules were completely equal. For this
+ * special case a compromise for this problem has been made, to set the module name will
+ * be more generally displayed.
+ * Also this searchloop will find the F-Parameter Indexnumber, so that Wireshark is able to
+ * dissect those F-Parameters correctly, as this index can change between the vendors.
+ */
+
+ io_data_object->amountInGSDML = 0;
+ io_data_object->fParameterIndexNr = 0;
+ io_data_object->profisafeSupported = FALSE;
+
+ if (diropen != NULL) {
+ fp = ws_fopen(diropen, "r");
+ }
+ else {
+ fp = NULL;
+ }
+ if(fp != NULL && gsdmlFoundFlag) {
+ fseek(fp, 0, SEEK_SET);
+
+ /* Find Indexnumber for fParameter */
+ while(pn_fgets(temp, MAX_LINE_LENGTH, fp, pinfo->pool) != NULL) {
+ if((strstr(temp, fParameterStr)) != NULL) {
+ memset (convertStr, 0, sizeof(*convertStr));
+
+ pch = strstr(temp, fParameterIndexStr);
+ if (pch != NULL && sscanf(pch, "Index=\"%199[^\"]", convertStr) == 1) {
+ io_data_object->fParameterIndexNr = (guint32)strtoul(convertStr, NULL, 0);
+ }
+ break; /* found Indexnumber -> break search loop */
+ }
+ }
+
+ memset (temp, 0, sizeof(*temp));
+ fseek(fp, 0, SEEK_SET); /* Set filepointer to the beginning */
+
+ while(pn_fgets(temp, MAX_LINE_LENGTH, fp, pinfo->pool) != NULL) {
+ if((strstr(temp, moduleStr)) != NULL) { /* find the String "ModuleIdentNumber=" */
+ memset (convertStr, 0, sizeof(*convertStr));
+ pch = strstr(temp, moduleStr); /* search for "ModuleIdentNumber=\"" within GSD-file */
+ if (pch != NULL && sscanf(pch, "ModuleIdentNumber=\"%199[^\"]", convertStr) == 1) { /* Change format of Value string-->numeric string */
+ read_module_id = (guint32)strtoul(convertStr, NULL, 0); /* Change numeric string --> unsigned long; read_module_id contains the Value of the ModuleIdentNumber */
+
+ /* If the found ModuleID matches with the wanted ModuleID, search for the Submodule and break */
+ if (read_module_id == io_data_object->moduleIdentNr) {
+ ++io_data_object->amountInGSDML; /* Save the amount of same (!) Module- & SubmoduleIdentNr in one GSD-file */
+
+ while(pn_fgets(temp, MAX_LINE_LENGTH, fp, pinfo->pool) != NULL) {
+ if((strstr(temp, moduleNameInfo)) != NULL) { /* find the String "<Name" for the TextID */
+ long filePosRecord;
+
+ if (sscanf(temp, "%*s TextId=\"%199[^\"]", tmp_moduletext) != 1) /* saves the correct TextId for the next searchloop */
+ break;
+
+ filePosRecord = ftell(fp); /* save the current position of the filepointer (Offset) */
+ /* ftell() may return -1 for error, don't move fp in this case */
+ if (filePosRecord >= 0) {
+ while (pn_fgets(temp, MAX_LINE_LENGTH, fp, pinfo->pool) != NULL && io_data_object->amountInGSDML == 1) {
+ /* Find a String with the saved TextID and with a fitting value for it in the same line. This value is the name of the Module! */
+ if(((strstr(temp, tmp_moduletext)) != NULL) && ((strstr(temp, moduleValueInfo)) != NULL)) {
+ pch = strstr(temp, moduleValueInfo);
+ if (pch != NULL && sscanf(pch, "Value=\"%199[^\"]", io_data_object->moduleNameStr) == 1)
+ break; /* Found the name of the module */
+ }
+ }
+
+ fseek(fp, filePosRecord, SEEK_SET); /* set filepointer to the correct TextID */
+ }
+ }
+
+ /* Search for Submoduleidentnumber in GSD-file */
+ if((strstr(temp, subModuleStr)) != NULL) {
+ memset (convertStr, 0, sizeof(*convertStr));
+ pch = strstr(temp, subModuleStr);
+ if (pch != NULL && sscanf(pch, "SubmoduleIdentNumber=\"%199[^\"]", convertStr) == 1) {
+ read_submodule_id = (guint32) strtoul (convertStr, NULL, 0); /* read_submodule_id contains the Value of the SubModuleIdentNumber */
+
+ /* Find "PROFIsafeSupported" flag of the module in GSD-file */
+ if(read_submodule_id == io_data_object->subModuleIdentNr) {
+ if((strstr(temp, profisafeStr)) != NULL) {
+ io_data_object->profisafeSupported = TRUE; /* flag is in the same line as SubmoduleIdentNr */
+ break;
+ }
+ else { /* flag is not in the same line as Submoduleidentnumber -> search for it */
+ while(pn_fgets(temp, MAX_LINE_LENGTH, fp, pinfo->pool) != NULL) {
+ if((strstr(temp, profisafeStr)) != NULL) {
+ io_data_object->profisafeSupported = TRUE;
+ break; /* Found the PROFIsafeSupported flag of the module */
+ }
+
+ else if((strstr(temp, ">")) != NULL) {
+ break;
+ }
+ }
+ }
+ break; /* Found the PROFIsafe Module */
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ fclose(fp);
+ fp = NULL;
+ }
+
+ if(fp != NULL)
+ {
+ fclose(fp);
+ fp = NULL;
+ }
+
+ switch (u16SubmoduleProperties & 0x03) {
+ case(0x00): /* no input and no output data (one Input DataDescription Block follows) */
+ offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep, io_data_object);
+ break;
+ case(0x01): /* input data (one Input DataDescription Block follows) */
+ offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep, io_data_object);
+ break;
+ case(0x02): /* output data (one Output DataDescription Block follows) */
+ offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep, io_data_object);
+ break;
+ case(0x03): /* input and output data (one Input and one Output DataDescription Block follows) */
+ offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep, io_data_object);
+ offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep, io_data_object);
+ break;
+ default: /* will not execute because of the line preceding the switch */
+ break;
+ }
+
+ proto_item_append_text(sub_item, ": Subslot:0x%x, Ident:0x%x Properties:0x%x",
+ u16SubslotNr, u32SubmoduleIdentNumber, u16SubmoduleProperties);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+ }
+
+ proto_item_set_len(api_item, offset - u32ApiStart);
+ }
+
+ return offset;
+}
+
+
+/* dissect the ModuleDiffBlock */
+static int
+dissect_ModuleDiffBlock_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16NumberOfAPIs;
+ guint32 u32Api;
+ guint16 u16NumberOfModules;
+ guint16 u16SlotNr;
+ guint32 u32ModuleIdentNumber;
+ guint16 u16ModuleState;
+ guint16 u16NumberOfSubmodules;
+ guint16 u16SubslotNr;
+ guint32 u32SubmoduleIdentNumber;
+ guint16 u16SubmoduleState;
+ proto_item *api_item;
+ proto_tree *api_tree;
+ guint32 u32ApiStart;
+ proto_item *module_item;
+ proto_tree *module_tree;
+ guint32 u32ModuleStart;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ proto_item *submodule_item;
+ proto_tree *submodule_tree;
+ guint32 u32SubStart;
+
+ conversation_t *conversation;
+ stationInfo *station_info;
+ wmem_list_frame_t *frame;
+ moduleDiffInfo *module_diff_info;
+ moduleDiffInfo *cmp_module_diff_info;
+
+ ARUUIDFrame *current_aruuid_frame = NULL;
+ guint32 current_aruuid = 0;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* NumberOfAPIs */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+
+ proto_item_append_text(item, ": APIs:%u", u16NumberOfAPIs);
+
+ while (u16NumberOfAPIs--) {
+ api_item = proto_tree_add_item(tree, hf_pn_io_api_tree, tvb, offset, 0, ENC_NA);
+ api_tree = proto_item_add_subtree(api_item, ett_pn_io_api);
+ u32ApiStart = offset;
+
+ /* API */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_api, &u32Api);
+ /* NumberOfModules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
+ hf_pn_io_number_of_modules, &u16NumberOfModules);
+
+ proto_item_append_text(api_item, ": %u, Modules: %u",
+ u32Api, u16NumberOfModules);
+
+ proto_item_append_text(item, ", Modules:%u", u16NumberOfModules);
+
+ while (u16NumberOfModules--) {
+ module_item = proto_tree_add_item(api_tree, hf_pn_io_module_tree, tvb, offset, 0, ENC_NA);
+ module_tree = proto_item_add_subtree(module_item, ett_pn_io_module);
+ u32ModuleStart = offset;
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* ModuleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
+ /* ModuleState */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_module_state, &u16ModuleState);
+ /* NumberOfSubmodules */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
+ hf_pn_io_number_of_submodules, &u16NumberOfSubmodules);
+
+ proto_item_append_text(module_item, ": Slot 0x%x, Ident: 0x%x State: %s Submodules: %u",
+ u16SlotNr, u32ModuleIdentNumber,
+ val_to_str(u16ModuleState, pn_io_module_state, "(0x%x)"),
+ u16NumberOfSubmodules);
+
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ /* Get current conversation endpoints using MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ current_aruuid_frame = pn_find_aruuid_frame_setup(pinfo);
+
+ if (current_aruuid_frame != NULL) {
+ current_aruuid = current_aruuid_frame->aruuid.data1;
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, current_aruuid);
+
+ if (station_info != NULL) {
+ pn_find_dcp_station_info(station_info, conversation);
+
+ for (frame = wmem_list_head(station_info->diff_module); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ cmp_module_diff_info = (moduleDiffInfo*)wmem_list_frame_data(frame);
+ if (cmp_module_diff_info->slotNr == u16SlotNr) {
+ /* Found identical existing object */
+ break;
+ }
+ }
+
+ if (frame == NULL) {
+ /* new diffModuleInfo data incoming */
+ module_diff_info = wmem_new(wmem_file_scope(), moduleDiffInfo);
+ module_diff_info->slotNr = u16SlotNr;
+ module_diff_info->modulID = u32ModuleIdentNumber;
+ wmem_list_append(station_info->diff_module, module_diff_info);
+ }
+ }
+ }
+
+ proto_item_append_text(item, ", Submodules:%u", u16NumberOfSubmodules);
+
+ while (u16NumberOfSubmodules--) {
+ sub_item = proto_tree_add_item(module_tree, hf_pn_io_submodule_tree, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_submodule);
+ u32SubStart = offset;
+
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ /* SubmoduleIdentNumber */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
+ /* SubmoduleState */
+ submodule_item = proto_tree_add_item(sub_tree, hf_pn_io_submodule_state, tvb, offset, 2, ENC_BIG_ENDIAN);
+ submodule_tree = proto_item_add_subtree(submodule_item, ett_pn_io_submodule_state);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_format_indicator, &u16SubmoduleState);
+ if (u16SubmoduleState & 0x8000) {
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_ident_info, &u16SubmoduleState);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_ar_info, &u16SubmoduleState);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_fault, &u16SubmoduleState);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_maintenance_demanded, &u16SubmoduleState);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_maintenance_required, &u16SubmoduleState);
+ dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_advice, &u16SubmoduleState);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_add_info, &u16SubmoduleState);
+ } else {
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, submodule_tree, drep,
+ hf_pn_io_submodule_state_detail, &u16SubmoduleState);
+ }
+
+ proto_item_append_text(sub_item, ": Subslot 0x%x, IdentNumber: 0x%x, State: 0x%x",
+ u16SubslotNr, u32SubmoduleIdentNumber, u16SubmoduleState);
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+ } /* NumberOfSubmodules */
+
+ proto_item_set_len(module_item, offset - u32ModuleStart);
+ }
+
+ proto_item_set_len(api_item, offset - u32ApiStart);
+ }
+
+ return offset;
+}
+
+
+/* dissect the IsochronousModeData block */
+static int
+dissect_IsochronousModeData_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16ControllerApplicationCycleFactor;
+ guint16 u16TimeDataCycle;
+ guint32 u32TimeIOInput;
+ guint32 u32TimeIOOutput;
+ guint32 u32TimeIOInputValid;
+ guint32 u32TimeIOOutputValid;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* SlotNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ /* Subslotnumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ /* ControllerApplicationCycleFactor */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_controller_appl_cycle_factor, &u16ControllerApplicationCycleFactor);
+ /* TimeDataCycle */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_time_data_cycle, &u16TimeDataCycle);
+ /* TimeIOInput (ns) */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_time_io_input, &u32TimeIOInput);
+ /* TimeIOOutput (ns) */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_time_io_output, &u32TimeIOOutput);
+ /* TimeIOInputValid (ns) */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_time_io_input_valid, &u32TimeIOInputValid);
+ /* TimeIOOutputValid (ns) */
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_time_io_output_valid, &u32TimeIOOutputValid);
+
+
+ return offset+1;
+}
+
+static int
+dissect_CommunityName_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, const guint8 *drep _U_, int hfindex)
+{
+ guint8 u8CommunityNameLength;
+ proto_item* sub_item;
+ proto_item* sub_tree;
+
+ /* CommunityNameLength */
+ u8CommunityNameLength = tvb_get_guint8(tvb, offset);
+ sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, u8CommunityNameLength + 1, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_snmp_command_name);
+
+ proto_tree_add_item(sub_tree, hf_pn_io_snmp_community_name_length, tvb, offset, 1, DREP_ENC_INTEGER(drep));
+ offset += 1;
+
+ /* community Name */
+ proto_tree_add_item(sub_tree, hf_pn_io_snmp_community_name, tvb, offset, u8CommunityNameLength, ENC_ASCII | ENC_NA);
+
+ proto_item_append_text(sub_item, ": %s",
+ tvb_get_string_enc(wmem_packet_scope(), tvb, offset, u8CommunityNameLength, ENC_ASCII|ENC_NA));
+
+ offset += u8CommunityNameLength;
+ return offset;
+}
+
+/* dissect the CIMSNMPAdjust block */
+static int
+dissect_CIMSNMPAdjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint16 u16StartsAtOffset = offset;
+ guint16 u16padding;
+
+ if (u8BlockVersionHigh!=1 || u8BlockVersionLow!=0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* SNMPControl */
+ proto_tree_add_item(tree, hf_pn_io_snmp_control, tvb, offset, 2, DREP_ENC_INTEGER(drep));
+ offset += 2;
+
+ offset = dissect_CommunityName_block(tvb, offset, pinfo, tree, drep, hf_pn_io_snmp_read_community_name);
+ offset = dissect_CommunityName_block(tvb, offset, pinfo, tree, drep, hf_pn_io_snmp_write_community_name);
+
+ u16padding = u16BodyLength - (offset - u16StartsAtOffset);
+ if (u16padding > 0)
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, u16padding);
+
+ return offset;
+}
+
+/* dissect the MultipleBlockHeader block */
+static int
+dissect_MultipleBlockHeader_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16BodyLength)
+{
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ tvbuff_t *new_tvb;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ proto_item_append_text(item, ": Api:0x%x Slot:%u Subslot:0x%x",
+ u32Api, u16SlotNr, u16SubslotNr);
+
+ new_tvb = tvb_new_subset_length(tvb, offset, u16BodyLength-10);
+ offset = dissect_blocks(new_tvb, 0, pinfo, tree, drep);
+
+ /*offset += u16BodyLength;*/
+
+ return offset;
+}
+
+/* dissect Combined Object Container Content block */
+static int
+dissect_COContainerContent_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
+{
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+
+ if(u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_index, &u16Index);
+
+ proto_item_append_text(item, ": Api:0x%x Slot:%u Subslot:0x%x Index:0x%x",
+ u32Api, u16SlotNr, u16SubslotNr, u16Index);
+
+ if(u16Index != 0x80B0) {
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, u32RecDataLen, ar);
+ }
+
+ return offset;
+}
+
+
+static const gchar *
+indexReservedForProfiles(guint16 u16Index)
+{
+ /* "reserved for profiles" */
+ if (u16Index >= 0xb000 && u16Index <= 0xbfff) {
+ return "Reserved for Profiles (subslot specific)";
+ }
+ if (u16Index >= 0xd000 && u16Index <= 0xdfff) {
+ return "Reserved for Profiles (slot specific)";
+ }
+ if (u16Index >= 0xec00 && u16Index <= 0xefff) {
+ return "Reserved for Profiles (AR specific)";
+ }
+ if (u16Index >= 0xf400 && u16Index <= 0xf7ff) {
+ return "Reserved for Profiles (API specific)";
+ }
+ if (u16Index >= 0xfc00 /* up to 0xffff */) {
+ return "Reserved for Profiles (device specific)";
+ }
+
+ return NULL;
+}
+
+
+/* dissect the RecordDataReadQuery block */
+static int
+dissect_RecordDataReadQuery_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint8 *drep _U_, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow,
+ guint16 u16Index, guint16 u16BodyLength)
+{
+ const gchar *userProfile;
+
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ /* user specified format? */
+ if (u16Index < 0x8000) {
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, u16BodyLength, "User Specified Data");
+ return offset;
+ }
+
+ /* "reserved for profiles"? */
+ userProfile = indexReservedForProfiles(u16Index);
+ if (userProfile != NULL) {
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, u16BodyLength, userProfile);
+ return offset;
+ }
+
+ return dissect_pn_undecoded(tvb, offset, pinfo, tree, u16BodyLength);
+}
+
+/* dissect the RS_GetEvent block */
+static int
+dissect_RS_GetEvent_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+ guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ offset = dissect_RS_EventInfo(tvb, offset, pinfo, tree, drep);
+ return offset;
+}
+
+/* dissect the RS_AdjustControl */
+static int
+dissect_RS_AdjustControl(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep,
+ guint16 *u16RSBodyLength, guint16 *u16RSBlockType)
+{
+ guint16 u16ChannelNumber;
+ guint16 u16SoEMaxScanDelay;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint8 u8SoEAdjustSpecifierReserved;
+ guint8 u8SoEAdjustSpecifierIndicent;
+
+ switch (*u16RSBlockType) {
+ case(0xc010): /* SoE_DigitalInputObserver */
+
+ /* ChannelNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_channel_number, &u16ChannelNumber);
+
+ /* SoE_MaxScanDelay */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_soe_max_scan_delay, &u16SoEMaxScanDelay);
+
+ /* SoE_AdjustSpecifier */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_soe_adjust_specifier, tvb, offset, 1, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_soe_adjust_specifier);
+
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_soe_adjust_specifier_reserved, &u8SoEAdjustSpecifierReserved);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_soe_adjust_specifier_incident, &u8SoEAdjustSpecifierIndicent);
+
+ /* Padding 2 + 2 + 1 = 5 */
+ /* Therefore we need 3 byte padding to make the block u32 aligned */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 3);
+ break;
+ default:
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, *u16RSBodyLength, "UserData");
+ break;
+ }
+ return offset;
+}
+
+/* dissect the RS_AdjustBlock */
+static int
+dissect_RS_AdjustBlock(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ guint16 u16RSBodyLength;
+ guint16 u16RSBlockType;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_rs_adjust_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_rs_adjust_block);
+
+ /* RS_BlockHeader */
+ offset = dissect_RS_BlockHeader(tvb, offset, pinfo, sub_tree, sub_item, drep,
+ &u16RSBodyLength, &u16RSBlockType);
+
+ /* RS_AdjustControl */
+ offset = dissect_RS_AdjustControl(tvb, offset, pinfo, sub_tree, drep,
+ &u16RSBodyLength, &u16RSBlockType);
+
+ return offset;
+}
+
+/* dissect the RS_AdjustInfo */
+static int
+dissect_RS_AdjustInfo(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16NumberofEntries;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_rs_adjust_info, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_rs_adjust_info);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_number_of_rs_event_info, &u16NumberofEntries);
+
+ while (u16NumberofEntries > 0) {
+ u16NumberofEntries--;
+ offset = dissect_RS_AdjustBlock(tvb, offset, pinfo, sub_tree, drep);
+ }
+ return offset;
+}
+
+/* dissect the RS_AdjustObserver block */
+static int
+dissect_RS_AdjustObserver_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+ guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ offset = dissect_RS_AdjustInfo(tvb, offset, pinfo, tree, drep);
+ return offset;
+}
+
+static int
+dissect_RS_AckInfo(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16RSSpecifierSequenceNumber;
+
+ /* RS_Specifier.SequenceNumber */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_rs_specifier_sequence, &u16RSSpecifierSequenceNumber);
+
+ return offset;
+}
+
+/* dissect the RS_AckEvent block */
+static int
+dissect_RS_AckEvent_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep,
+ guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_io_block_version,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+ offset = dissect_RS_AckInfo(tvb, offset, pinfo, tree, drep);
+ return offset;
+}
+
+/* dissect one PN-IO block (depending on the block type) */
+static int
+dissect_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
+{
+ guint16 u16BlockType;
+ guint16 u16BlockLength;
+ guint8 u8BlockVersionHigh;
+ guint8 u8BlockVersionLow;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+ guint16 u16BodyLength;
+ proto_item *header_item;
+ proto_tree *header_tree;
+ gint remainingBytes;
+
+ /* from here, we only have big endian (network byte ordering)!!! */
+ drep[0] &= ~DREP_LITTLE_ENDIAN;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_block);
+ u32SubStart = offset;
+
+ header_item = proto_tree_add_item(sub_tree, hf_pn_io_block_header, tvb, offset, 6, ENC_NA);
+ header_tree = proto_item_add_subtree(header_item, ett_pn_io_block_header);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, header_tree, drep,
+ hf_pn_io_block_type, &u16BlockType);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, header_tree, drep,
+ hf_pn_io_block_length, &u16BlockLength);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, header_tree, drep,
+ hf_pn_io_block_version_high, &u8BlockVersionHigh);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, header_tree, drep,
+ hf_pn_io_block_version_low, &u8BlockVersionLow);
+
+ proto_item_append_text(header_item, ": Type=%s, Length=%u(+4), Version=%u.%u",
+ val_to_str(u16BlockType, pn_io_block_type, "Unknown (0x%04x)"),
+ u16BlockLength, u8BlockVersionHigh, u8BlockVersionLow);
+
+ proto_item_set_text(sub_item, "%s",
+ val_to_str(u16BlockType, pn_io_block_type, "Unknown (0x%04x)"));
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
+ val_to_str_const(u16BlockType, pn_io_block_type, "Unknown"));
+
+ /* block length is without type and length fields, but with version field */
+ /* as it's already dissected, remove it */
+ u16BodyLength = u16BlockLength - 2;
+ remainingBytes = tvb_reported_length_remaining(tvb, offset);
+ if (remainingBytes < 0)
+ remainingBytes = 0;
+ if (remainingBytes +2 < u16BodyLength)
+ {
+ proto_item_append_text(sub_item, " Block_Length: %d greater than remaining Bytes, trying with Blocklen = remaining (%d)", u16BodyLength, remainingBytes);
+ u16BodyLength = remainingBytes;
+ }
+ switch (u16BlockType) {
+ case(0x0001):
+ case(0x0002):
+ dissect_AlarmNotification_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16BodyLength);
+ break;
+ case(0x0008):
+ dissect_IODWriteReqHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16Index, u32RecDataLen, ar);
+ break;
+ case(0x0009):
+ dissect_IODReadReqHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16Index, u32RecDataLen, ar);
+ break;
+ case(0x0010):
+ dissect_DiagnosisData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16BodyLength);
+ break;
+ case(0x0012): /* ExpectedIdentificationData */
+ case(0x0013): /* RealIdentificationData */
+ dissect_IdentificationData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0014):
+ dissect_SubstituteValue_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16BodyLength);
+ break;
+ case(0x0015):
+ dissect_RecordInputDataObjectElement_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0016):
+ dissect_RecordOutputDataObjectElement_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ /* 0x0017 reserved */
+ case(0x0018):
+ dissect_ARData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0019):
+ dissect_LogData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x001A):
+ dissect_APIData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x001B):
+ dissect_SRLData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0020):
+ dissect_IandM0_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0021):
+ dissect_IandM1_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0022):
+ dissect_IandM2_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0023):
+ dissect_IandM3_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0024):
+ dissect_IandM4_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0025):
+ dissect_IandM5_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh,u8BlockVersionLow);
+ break;
+ case(0x0030):
+ dissect_IandM0FilterData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0031):
+ dissect_IandM0FilterData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0032):
+ dissect_IandM0FilterData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0034):
+ dissect_IandM5Data_block(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ break;
+ case(0x0035):
+ dissect_AssetManagementData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0036):
+ dissect_AM_FullInformation_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0037):
+ dissect_AM_HardwareOnlyInformation_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0038):
+ dissect_AM_FirmwareOnlyInformation_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0101):
+ dissect_ARBlockReq_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ ar);
+ break;
+ case(0x0102):
+ dissect_IOCRBlockReq_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ *ar);
+ break;
+ case(0x0103):
+ dissect_AlarmCRBlockReq_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ *ar);
+ break;
+ case(0x0104):
+ dissect_ExpectedSubmoduleBlockReq_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0106):
+ dissect_MCRBlockReq_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0107):
+ dissect_SubFrameBlock_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0108):
+ case(0x8108):
+ dissect_ARVendorBlockReq_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0109):
+ dissect_IRInfoBlock_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x010A):
+ dissect_SRInfoBlock_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x010C):
+ dissect_RSInfoBlock_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0110):
+ case(0x0111):
+ case(0x0112):
+ case(0x0113):
+ case(0x0114):
+ case(0x0116):
+ case(0x0117):
+ dissect_ControlPlugOrConnect_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, ar, u16BlockType);
+ break;
+
+ case(0x0118):
+ dissect_ControlBlockPrmBegin(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength, ar);
+ break;
+
+ case(0x0119):
+ dissect_SubmoduleListBlock(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength, ar);
+ break;
+
+ case(0x0200): /* PDPortDataCheck */
+ dissect_PDPortData_Check_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16BodyLength);
+ break;
+ case(0x0201):
+ dissect_PDevData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0202): /*dissect_PDPortData_Adjust_block */
+ dissect_PDPortData_Adjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16BodyLength);
+ break;
+ case(0x0203):
+ dissect_PDSyncData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0204):
+ dissect_IsochronousModeData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0205):
+ dissect_PDIRData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0206):
+ dissect_PDIRGlobalData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0207):
+ dissect_PDIRFrameData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16BodyLength);
+ break;
+ case(0x0208):
+ dissect_PDIRBeginEndData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16BodyLength);
+ break;
+ case(0x0209):
+ dissect_AdjustDomainBoundary_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x020A):
+ dissect_CheckPeers_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x020B):
+ dissect_CheckLineDelay_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x020C):
+ dissect_CheckMAUType_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x020E):
+ dissect_AdjustMAUType_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x020F):
+ dissect_PDPortDataReal_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0210):
+ dissect_AdjustMulticastBoundary_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0211):
+ dissect_PDInterfaceMrpDataAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0212):
+ dissect_PDInterfaceMrpDataReal_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0213):
+ dissect_PDInterfaceMrpDataCheck_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0214):
+ case(0x0215):
+ dissect_PDPortMrpData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0216):
+ dissect_MrpManagerParams_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0217):
+ dissect_MrpClientParams_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0218):
+ dissect_MrpRTModeManagerData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0219):
+ dissect_MrpRingStateData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x021A):
+ dissect_MrpRTStateData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x021B):
+ dissect_AdjustPortState_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x021C):
+ dissect_CheckPortState_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x021D):
+ dissect_MrpRTModeClientData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x021E):
+ dissect_CheckSyncDifference_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x021F):
+ dissect_CheckMAUTypeDifference_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0220):
+ dissect_PDPortFODataReal_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0221):
+ dissect_FiberOpticManufacturerSpecific_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0222):
+ dissect_PDPortFODataAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0223):
+ dissect_PDPortFODataCheck_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0224):
+ dissect_AdjustPeerToPeerBoundary_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0225):
+ dissect_AdjustDCPBoundary_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0226):
+ dissect_AdjustPreambleLength_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0227):
+ dissect_CheckMAUTypeExtension_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0228):
+ dissect_FiberOpticDiagnosisInfo_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0229):
+ dissect_AdjustMAUTypeExtension_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x022A):
+ dissect_PDIRSubframeData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x022B):
+ dissect_PDSubFrameBlock_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x022C):
+ dissect_PDPortDataRealExtended_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+
+ case(0x0230):
+ dissect_PDPortFODataCheck_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0231):
+ dissect_MrpInstanceDataAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0232):
+ dissect_MrpInstanceDataReal_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0233):
+ dissect_MrpInstanceDataCheck_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0240):
+ dissect_PDInterfaceDataReal_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0241) :
+ dissect_PDRsiInstances_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0250):
+ dissect_PDInterfaceAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0251):
+ dissect_PDPortStatistic_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0260):
+ dissect_OwnPort_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0261):
+ dissect_Neighbors_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0270):
+ dissect_TSNNetworkControlDataReal_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0271):
+ dissect_TSNNetworkControlDataAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0272):
+ dissect_TSNDomainPortConfig_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0273):
+ dissect_TSNDomainQueueConfig_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0274):
+ dissect_TSNTimeData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0275):
+ dissect_TSNStreamPathDataReal_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, FALSE);
+ break;
+ case(0x0276):
+ dissect_TSNSyncTreeData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0277):
+ dissect_TSNUploadNetworkAttributes_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0278):
+ dissect_TSNForwardingDelay_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0279):
+ dissect_TSNExpectedNetworkAttributes_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x027A):
+ dissect_TSNStreamPathDataReal_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, TRUE);
+ break;
+ case(0x027B):
+ dissect_TSNDomainPortIngressRateLimiter_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x027C):
+ dissect_TSNDomainQueueRateLimiter_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x027D):
+ dissect_TSNPortID_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x027E):
+ dissect_TSNExpectedNeighbor_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0300):
+ dissect_CIMSNMPAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0400):
+ dissect_MultipleBlockHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0401):
+ dissect_COContainerContent_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, *u16Index, u32RecDataLen, ar);
+ break;
+ case(0x0500):
+ dissect_RecordDataReadQuery_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, *u16Index, u16BodyLength);
+ break;
+ case(0x0600):
+ dissect_FSHello_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0601):
+ dissect_FSParameter_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0608):
+ dissect_PDInterfaceFSUDataAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x010B):
+ case(0x0609):
+ dissect_ARFSUDataAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x0810):
+ dissect_PE_EntityFilterData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0811):
+ dissect_PE_EntityStatusData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0900):
+ dissect_RS_AdjustObserver_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0901):
+ dissect_RS_GetEvent_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0902):
+ dissect_RS_AckEvent_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0f00) :
+ dissect_Maintenance_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x0f05):
+ dissect_PE_Alarm_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x8001):
+ case(0x8002):
+ dissect_Alarm_ack_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x8008):
+ dissect_IODWriteResHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16Index, u32RecDataLen, ar);
+ break;
+ case(0x8009):
+ dissect_IODReadResHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow,
+ u16Index, u32RecDataLen, ar);
+ break;
+ case(0x8101):
+ dissect_ARBlockRes_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, ar);
+ break;
+ case(0x8102):
+ dissect_IOCRBlockRes_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, *ar);
+ break;
+ case(0x8103):
+ dissect_AlarmCRBlockRes_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, *ar);
+ break;
+ case(0x8104):
+ dissect_ModuleDiffBlock_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow);
+ break;
+ case(0x8106):
+ dissect_ARServerBlock(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength);
+ break;
+ case(0x8110):
+ case(0x8111):
+ case(0x8112):
+ case(0x8113):
+ case(0x8114):
+ case(0x8116):
+ case(0x8117):
+ case(0x8118):
+ dissect_ControlPlugOrConnect_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, ar, u16BlockType);
+ break;
+ default:
+ dissect_pn_undecoded(tvb, offset, pinfo, sub_tree, u16BodyLength);
+ }
+ offset += u16BodyLength;
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+/* dissect any PN-IO block */
+static int
+dissect_a_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+
+ if (ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
+ return offset;
+}
+
+/* dissect any number of PN-IO blocks */
+int
+dissect_blocks(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+
+
+ while (tvb_captured_length(tvb) > (guint) offset) {
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ u16Index++;
+ }
+
+ if (ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
+ return offset;
+}
+
+
+/* dissect a PN-IO (DCE-RPC) request header */
+static int
+dissect_IPNIO_rqst_header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32ArgsMax;
+ guint32 u32ArgsLen;
+ guint32 u32MaxCount;
+ guint32 u32Offset;
+ guint32 u32ArraySize;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-CM");
+
+ /* args_max */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
+ hf_pn_io_args_max, &u32ArgsMax);
+ /* args_len */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
+ hf_pn_io_args_len, &u32ArgsLen);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_array, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io);
+ u32SubStart = offset;
+
+ /* RPC array header */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_pn_io_array_max_count, &u32MaxCount);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_pn_io_array_offset, &u32Offset);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_pn_io_array_act_count, &u32ArraySize);
+
+ proto_item_append_text(sub_item, ": Max: %u, Offset: %u, Size: %u",
+ u32MaxCount, u32Offset, u32ArraySize);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO (DCE-RPC) response header */
+static int
+dissect_IPNIO_resp_header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32ArgsLen;
+ guint32 u32MaxCount;
+ guint32 u32Offset;
+ guint32 u32ArraySize;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-CM");
+
+ offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
+
+ /* args_len */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
+ hf_pn_io_args_len, &u32ArgsLen);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_array, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io);
+ u32SubStart = offset;
+
+ /* RPC array header */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_pn_io_array_max_count, &u32MaxCount);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_pn_io_array_offset, &u32Offset);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_pn_io_array_act_count, &u32ArraySize);
+
+ proto_item_append_text(sub_item, ": Max: %u, Offset: %u, Size: %u",
+ u32MaxCount, u32Offset, u32ArraySize);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO request */
+static int
+dissect_IPNIO_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO response */
+static int
+dissect_IPNIO_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+/* dissect a PROFIDrive parameter request */
+static int
+dissect_ProfiDriveParameterRequest(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint8 request_reference;
+ guint8 request_id;
+ guint8 do_id;
+ guint8 no_of_parameters;
+ guint8 addr_idx;
+ proto_item *profidrive_item;
+ proto_tree *profidrive_tree;
+
+ profidrive_item = proto_tree_add_item(tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ profidrive_tree = proto_item_add_subtree(profidrive_item, ett_pn_io_profidrive_parameter_request);
+ proto_item_set_text(profidrive_item, "PROFIDrive Parameter Request: ");
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_request_reference, &request_reference);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_request_id, &request_id);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_do_id, &do_id);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_no_of_parameters, &no_of_parameters);
+
+ proto_item_append_text(profidrive_item, "ReqRef:0x%02x, ReqId:%s, DO:%u, NoOfParameters:%u",
+ request_reference, val_to_str_const(request_id, pn_io_profidrive_request_id_vals, "Unknown"),
+ do_id, no_of_parameters);
+
+ col_add_fstr(pinfo->cinfo, COL_INFO, "PROFIDrive Write Request, ReqRef:0x%02x, %s DO:%u",
+ request_reference,
+ request_id==0x01 ? "Read" :
+ request_id==0x02 ? "Change" :
+ "",
+ do_id);
+
+ /* Parameter address list */
+ for(addr_idx=0; addr_idx<no_of_parameters; addr_idx++) {
+ guint8 attribute;
+ guint8 no_of_elems;
+ guint16 parameter;
+ guint16 idx;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(profidrive_tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_profidrive_parameter_address);
+ proto_item_set_text(sub_item, "Parameter Address %u: ", addr_idx+1);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_attribute, &attribute);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_no_of_elems, &no_of_elems);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_number, &parameter);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_subindex, &idx);
+
+ proto_item_append_text(sub_item, "Attr:%s, Elems:%u, Parameter:%u, Index:%u",
+ val_to_str_const(attribute, pn_io_profidrive_attribute_vals, "Unknown"), no_of_elems,
+ parameter, idx);
+
+ if (no_of_elems>1) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", P%d[%d..%d]", parameter, idx, idx+no_of_elems-1);
+ }
+ else {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", P%d[%d]", parameter, idx);
+ }
+ }
+
+ /* in case of change request parameter value list */
+ if (request_id == 0x02) {
+ for(addr_idx=0; addr_idx<no_of_parameters; addr_idx++) {
+ guint8 format;
+ guint8 no_of_vals;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(profidrive_tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_profidrive_parameter_value);
+ proto_item_set_text(sub_item, "Parameter Value %u: ", addr_idx+1);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_format, &format);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_no_of_values, &no_of_vals);
+
+ proto_item_append_text(sub_item, "Format:%s, NoOfVals:%u",
+ val_to_str_const(format, pn_io_profidrive_format_vals, "Unknown"), no_of_vals);
+
+ while (no_of_vals--)
+ {
+ offset = dissect_profidrive_value(tvb, offset, pinfo, sub_tree, drep, format);
+ }
+ }
+ }
+
+ return offset;
+}
+
+static int
+dissect_ProfiDriveParameterResponse(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint8 request_reference;
+ guint8 response_id;
+ guint8 do_id;
+ guint8 no_of_parameters;
+ guint8 addr_idx;
+ proto_item *profidrive_item;
+ proto_tree *profidrive_tree;
+
+ profidrive_item = proto_tree_add_item(tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ profidrive_tree = proto_item_add_subtree(profidrive_item, ett_pn_io_profidrive_parameter_response);
+ proto_item_set_text(profidrive_item, "PROFIDrive Parameter Response: ");
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_request_reference, &request_reference);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_response_id, &response_id);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_do_id, &do_id);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_no_of_parameters, &no_of_parameters);
+ proto_item_append_text(profidrive_item, "ReqRef:0x%02x, RspId:%s, DO:%u, NoOfParameters:%u",
+ request_reference, val_to_str_const(response_id, pn_io_profidrive_response_id_vals, "Unknown"),
+ do_id, no_of_parameters);
+ col_add_fstr(pinfo->cinfo, COL_INFO, "PROFIDrive Read Response, ReqRef:0x%02x, RspId:%s",
+ request_reference,
+ val_to_str_const(response_id, pn_io_profidrive_response_id_vals, "Unknown response"));
+ /* in case of parameter response value list */
+ if (response_id == 0x01) {
+ for(addr_idx=0; addr_idx<no_of_parameters; addr_idx++) {
+ guint8 format;
+ guint8 no_of_vals;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(profidrive_tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_profidrive_parameter_value);
+ proto_item_set_text(sub_item, "Parameter Value %u: ", addr_idx+1);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_format, &format);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_no_of_values, &no_of_vals);
+
+ proto_item_append_text(sub_item, "Format:%s, NoOfVals:%u",
+ val_to_str_const(format, pn_io_profidrive_format_vals, "Unknown"), no_of_vals);
+
+ while (no_of_vals--)
+ {
+ offset = dissect_profidrive_value(tvb, offset, pinfo, sub_tree, drep, format);
+ }
+ }
+ }
+
+ if(response_id == 0x02){
+ // change parameter response ok, no data
+ }
+
+ if(response_id == 0x81){
+ for(addr_idx=0; addr_idx<no_of_parameters; addr_idx++) {
+ guint8 format;
+ guint8 no_of_vals;
+ guint16 value16;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(profidrive_tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_profidrive_parameter_value);
+ proto_item_set_text(sub_item, "Parameter Value %u: ", addr_idx+1);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_format, &format);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_no_of_values, &no_of_vals);
+
+ proto_item_append_text(sub_item, "Format:%s, NoOfVals:%u",
+ val_to_str_const(format, pn_io_profidrive_format_vals, "Unknown"), no_of_vals);
+
+ if(format == 0x44){
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_value_error, &value16);
+ if(value16 == 0x23){
+
+ addr_idx = no_of_parameters;
+ }
+ while (--no_of_vals)
+ {
+ switch(value16)
+ {
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ case 0x6:
+ case 0x7:
+ case 0x14:
+ case 0x20:
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_value_error_sub, &value16);
+ break;
+ default:
+ offset = dissect_profidrive_value(tvb, offset, pinfo, sub_tree, drep, 0x42);
+ break;
+ }
+ }
+ }else{
+ while (no_of_vals--){
+ offset = dissect_profidrive_value(tvb, offset, pinfo, sub_tree, drep, format);
+ }
+ }
+ }
+ }
+
+ if(response_id == 0x82){
+
+ for(addr_idx=0; addr_idx<no_of_parameters; addr_idx++) {
+ guint8 format;
+ guint8 no_of_vals;
+ guint16 value16;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(profidrive_tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_profidrive_parameter_value);
+ proto_item_set_text(sub_item, "Parameter Change Result %u: ", addr_idx+1);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_format, &format);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_no_of_values, &no_of_vals);
+
+ proto_item_append_text(sub_item, "Format:%s, NoOfVals:%u",
+ val_to_str_const(format, pn_io_profidrive_format_vals, "Unknown"), no_of_vals);
+
+ if(format == 0x44){
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_value_error, &value16);
+
+ if(value16 == 0x23){
+ addr_idx = no_of_parameters;
+ }
+
+ while (--no_of_vals)
+ {
+ switch(value16)
+ {
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ case 0x6:
+ case 0x7:
+ case 0x14:
+ case 0x20:
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_value_error_sub, &value16);
+ break;
+ default:
+ offset = dissect_profidrive_value(tvb, offset, pinfo, sub_tree, drep, 0x42);
+ break;
+ }
+
+ }
+
+ }
+ }
+ }
+ return offset;
+}
+
+static int
+dissect_RecordDataRead(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16Index, guint32 u32RecDataLen)
+{
+ const gchar *userProfile;
+ pnio_ar_t *ar = NULL;
+
+ /* profidrive parameter access response */
+ if (u16Index == 0xb02e || u16Index == 0xb02f || u16Index == 0x002f) {
+ return dissect_ProfiDriveParameterResponse(tvb, offset, pinfo, tree, drep);
+ }
+
+ /* user specified format? */
+ if (u16Index < 0x8000) {
+ return dissect_pn_user_data(tvb, offset, pinfo, tree, u32RecDataLen, "User Specified Data");
+ }
+
+
+
+ /* "reserved for profiles"? */
+ userProfile = indexReservedForProfiles(u16Index);
+ if (userProfile != NULL) {
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, u32RecDataLen, userProfile);
+ return offset;
+ }
+
+ /* see: pn_io_index */
+ /* single block only */
+ switch (u16Index) {
+ case(0x8010): /* Maintenance required in channel coding for one subslot */
+ case(0x8011): /* Maintenance demanded in channel coding for one subslot */
+ case(0x8012): /* Maintenance required in all codings for one subslot */
+ case(0x8013): /* Maintenance demanded in all codings for one subslot */
+ case(0x801e): /* SubstituteValues for one subslot */
+ case(0x8020): /* PDIRSubframeData for one subslot */
+ case(0x8027): /* PDPortDataRealExtended for one subslot */
+ case(0x8028): /* RecordInputDataObjectElement for one subslot */
+ case(0x8029): /* RecordOutputDataObjectElement for one subslot */
+ case(0x8050): /* PDInterfaceMrpDataReal for one subslot */
+ case(0x8051): /* PDInterfaceMrpDataCheck for one subslot */
+ case(0x8052): /* PDInterfaceMrpDataAdjust for one subslot */
+ case(0x8053): /* PDPortMrpDataAdjust for one subslot */
+ case(0x8054): /* PDPortMrpDataReal for one subslot */
+ case(0x80F0): /* TSNNetworkControlDataReal */
+ case(0x80F2): /* TSNSyncTreeData */
+ case(0x80F3): /* TSNUploadNetworkAttributes */
+ case(0x80F4): /* TSNExpectedNetworkAttributes */
+ case(0x80F5): /* TSNNetworkControlDataAdjust */
+ case(0x8060): /* PDPortFODataReal for one subslot */
+ case(0x8061): /* PDPortFODataCheck for one subslot */
+ case(0x8062): /* PDPortFODataAdjust for one subslot */
+ case(0x8063): /* PDPortSFPDataCheck for one subslot */
+ case(0x8070): /* PDNCDataCheck for one subslot */
+ case(0x8071): /* PDPortStatistic for one subslot */
+ case(0x8080): /* PDInterfaceDataReal */
+ case(0x8090): /* PDInterfaceFSUDataAdjust */
+ case(0x80AF): /* PE_EntityStatusData for one subslot */
+ case(0x80CF): /* RS_AdjustObserver */
+
+ case(0x8200): /* CIMSNMPAdjust */
+
+ case(0xaff0): /* I&M0 */
+ case(0xaff1): /* I&M1 */
+ case(0xaff2): /* I&M2 */
+ case(0xaff3): /* I&M3 */
+ case(0xaff4): /* I&M4 */
+ case(0xaff5): /* I&M5 */
+ case(0xaff6): /* I&M6 */
+ case(0xaff7): /* I&M7 */
+ case(0xaff8): /* I&M8 */
+ case(0xaff9): /* I&M9 */
+ case(0xaffa): /* I&M10 */
+ case(0xaffb): /* I&M11 */
+ case(0xaffc): /* I&M12 */
+ case(0xaffd): /* I&M13 */
+ case(0xaffe): /* I&M14 */
+ case(0xafff): /* I&M15 */
+
+ case(0xc010): /* Maintenance required in channel coding for one slot */
+ case(0xc011): /* Maintenance demanded in channel coding for one slot */
+ case(0xc012): /* Maintenance required in all codings for one slot */
+ case(0xc013): /* Maintenance demanded in all codings for one slot */
+
+ case(0xe002): /* ModuleDiffBlock for one AR */
+ case(0xe010): /* Maintenance required in channel coding for one AR */
+ case(0xe011): /* Maintenance demanded in channel coding for one AR */
+ case(0xe012): /* Maintenance required in all codings for one AR */
+ case(0xe013): /* Maintenance demanded in all codings for one AR */
+
+ case(0xe030): /* PE_EntityFilterData for one AR*/
+ case(0xe031): /* PE_EntityStatusData for one AR*/
+
+ case(0xf010): /* Maintenance required in channel coding for one API */
+ case(0xf011): /* Maintenance demanded in channel coding for one API */
+ case(0xf012): /* Maintenance required in all codings for one API */
+ case(0xf013): /* Maintenance demanded in all codings for one API */
+ case(0xf020): /* ARData for one API */
+
+ case(0xf820): /* ARData */
+ case(0xf821): /* APIData */
+ case(0xf830): /* LogData */
+ case(0xf831): /* PDevData */
+ case(0xf870): /* PE_EntityFilterData*/
+ case(0xf871): /* PE_EntityStatusData*/
+ case(0xf880) : /* AssetManagementData */
+ case(0xf8f1): /* PDRsiInstances */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ break;
+
+ case(0xf840): /* I&M0FilterData */
+ {
+ int end_offset = offset + u32RecDataLen;
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ if (end_offset > offset)
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ if (end_offset > offset)
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ }
+ break;
+
+ case(0xB050):
+ case(0xB051):
+ case(0xB060):
+ case(0xB061):
+
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ break;
+
+
+ /*** multiple blocks possible ***/
+ case(0x8000): /* ExpectedIdentificationData for one subslot */
+ case(0x8001): /* RealIdentificationData for one subslot */
+ case(0x800a): /* Diagnosis in channel decoding for one subslot */
+ case(0x800b): /* Diagnosis in all codings for one subslot */
+ case(0x800c): /* Diagnosis, Maintenance, Qualified and Status for one subslot */
+
+ case(0x802a): /* PDPortDataReal */
+ case(0x802b): /* PDPortDataCheck */
+ case(0x802d): /* Expected PDSyncData for one subslot with SyncID value 0 for PTCPoverRTA */
+ case(0x802e): /* Expected PDSyncData for one subslot with SyncID value 0 for PTCPoverRTC */
+ case(0x802f): /* PDPortDataAdjust */
+ case(0x8030): /* IsochronousModeData for one subslot */
+ case(0x8031): /* PDTimeData for one subslot */
+ case(0x8032):
+ case(0x8033):
+ case(0x8034):
+ case(0x8035):
+ case(0x8036):
+ case(0x8037):
+ case(0x8038):
+ case(0x8039):
+ case(0x803a):
+ case(0x803b):
+ case(0x803c):
+ case(0x803d):
+ case(0x803e):
+ case(0x803f):
+ case(0x8040): /* Expected PDSyncData for one subslot with SyncID value 2 ... 30 */
+ case(0x8041):
+ case(0x8042):
+ case(0x8043):
+ case(0x8044):
+ case(0x8045):
+ case(0x8046):
+ case(0x8047):
+ case(0x8048):
+ case(0x8049):
+ case(0x804a):
+ case(0x804b):
+ case(0x804c):
+ case(0x804d):
+ case(0x804e):
+ case(0x804f): /* Expected PDSyncData for one subslot with SyncID value 31 */
+ case(0x8055): /* PDPortMrpIcDataAdjust for one subslot */
+ case(0x8056): /* PDPortMrpIcDataCheck for one subslot */
+ case(0x8057): /* PDPortMrpIcDataReal for one subslot */
+ case(0x8072): /* PDPortStatistic for one subslot */
+ case(0xc000): /* ExpectedIdentificationData for one slot */
+ case(0xc001): /* RealIdentificationData for one slot */
+ case(0xc00a): /* Diagnosis in channel coding for one slot */
+ case(0xc00b): /* Diagnosis in all codings for one slot */
+ case(0xc00c): /* Diagnosis, Maintenance, Qualified and Status for one slot */
+
+ case(0xe000): /* ExpectedIdentificationData for one AR */
+ case(0xe001): /* RealIdentificationData for one AR */
+ case(0xe00a): /* Diagnosis in channel decoding for one AR */
+ case(0xe00b): /* Diagnosis in all codings for one AR */
+ case(0xe00c): /* Diagnosis, Maintenance, Qualified and Status for one AR */
+ case(0xE060): /* RS_GetEvent (using RecordDataRead service) */
+ case(0xf000): /* RealIdentificationData for one API */
+ case(0xf00a): /* Diagnosis in channel decoding for one API */
+ case(0xf00b): /* Diagnosis in all codings for one API */
+ case(0xf00c): /* Diagnosis, Maintenance, Qualified and Status for one API */
+ case(0xf80c): /* Diagnosis, Maintenance, Qualified and Status for one device */
+ case(0xf841): /* PDRealData */
+ case(0xf842): /* PDExpectedData */
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, u32RecDataLen);
+ }
+
+ return offset;
+}
+
+
+/* dissect a PN-IO read response */
+static int
+dissect_IPNIO_Read_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen = 0;
+ pnio_ar_t *ar = NULL;
+
+ offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, di, drep);
+
+ /* When PNIOStatus is Error */
+ if (!tvb_captured_length_remaining(tvb, offset))
+ return offset;
+
+ /* IODReadHeader */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+
+ /* RecordDataRead */
+ if (u32RecDataLen != 0) {
+ offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
+ }
+
+ if (ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
+ return offset;
+}
+
+/* F-Parameter record data object */
+static int
+dissect_ProfiSafeParameterRequest(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16Index, wmem_list_frame_t *frame)
+{
+ proto_item *f_item;
+ proto_tree *f_tree;
+ proto_item *flags1_item;
+ proto_tree *flags1_tree;
+ proto_item *flags2_item;
+ proto_tree *flags2_tree;
+ guint16 src_addr;
+ guint16 dst_addr;
+ guint16 wd_time;
+ guint16 par_crc;
+ guint32 ipar_crc = 0;
+ guint8 prm_flag1;
+ guint8 prm_flag1_chck_seq;
+ guint8 prm_flag1_chck_ipar;
+ guint8 prm_flag1_sil;
+ guint8 prm_flag1_crc_len;
+ guint8 prm_flag1_crc_seed;
+ guint8 prm_flag1_reserved;
+ guint8 prm_flag2;
+ guint8 prm_flag2_reserved;
+ guint8 prm_flag2_f_block_id;
+ guint8 prm_flag2_f_par_version;
+
+ conversation_t *conversation;
+ stationInfo *station_info;
+ ioDataObject *io_data_object;
+ wmem_list_frame_t *frame_out;
+
+ ARUUIDFrame *current_aruuid_frame = NULL;
+ guint32 current_aruuid = 0;
+
+ f_item = proto_tree_add_item(tree, hf_pn_io_block, tvb, offset, 0, ENC_NA);
+ f_tree = proto_item_add_subtree(f_item, ett_pn_io_profisafe_f_parameter);
+ proto_item_set_text(f_item, "F-Parameter: ");
+
+ flags1_item = proto_tree_add_item(f_tree, hf_pn_io_ps_f_prm_flag1, tvb, offset, 1, ENC_BIG_ENDIAN);
+ flags1_tree = proto_item_add_subtree(flags1_item, ett_pn_io_profisafe_f_parameter_prm_flag1);
+
+ /* dissection of F_Prm_Flag1 */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags1_tree, drep,
+ hf_pn_io_ps_f_prm_flag1_chck_seq, &prm_flag1_chck_seq);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags1_tree, drep,
+ hf_pn_io_ps_f_prm_flag1_chck_ipar, &prm_flag1_chck_ipar);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags1_tree, drep,
+ hf_pn_io_ps_f_prm_flag1_sil, &prm_flag1_sil);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags1_tree, drep,
+ hf_pn_io_ps_f_prm_flag1_crc_len, &prm_flag1_crc_len);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags1_tree, drep,
+ hf_pn_io_ps_f_prm_flag1_crc_seed, &prm_flag1_crc_seed);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags1_tree, drep,
+ hf_pn_io_ps_f_prm_flag1_reserved, &prm_flag1_reserved);
+ prm_flag1 = prm_flag1_chck_seq|prm_flag1_chck_ipar|prm_flag1_sil|prm_flag1_crc_len|prm_flag1_crc_seed|prm_flag1_reserved;
+ offset++;
+
+ flags2_item = proto_tree_add_item(f_tree, hf_pn_io_ps_f_prm_flag2, tvb, offset, 1, ENC_BIG_ENDIAN);
+ flags2_tree = proto_item_add_subtree(flags2_item, ett_pn_io_profisafe_f_parameter_prm_flag2);
+
+ /* dissection of F_Prm_Flag2 */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags2_tree, drep,
+ hf_pn_io_ps_f_prm_flag2_reserved, &prm_flag2_reserved);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags2_tree, drep,
+ hf_pn_io_ps_f_prm_flag2_f_block_id, &prm_flag2_f_block_id);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, flags2_tree, drep,
+ hf_pn_io_ps_f_prm_flag2_f_par_version, &prm_flag2_f_par_version);
+ prm_flag2 = prm_flag2_reserved|prm_flag2_f_block_id|prm_flag2_f_par_version;
+ offset++;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, f_item, drep,
+ hf_pn_io_ps_f_src_adr, &src_addr);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, f_item, drep,
+ hf_pn_io_ps_f_dest_adr, &dst_addr);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, f_item, drep,
+ hf_pn_io_ps_f_wd_time, &wd_time);
+
+ /* Dissection for F_iPar_CRC: see F_Prm_Flag2 -> F_Block_ID */
+ if( (prm_flag2_f_block_id & 0x08) && !(prm_flag2_f_block_id & 0x20) ) {
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, f_item, drep,
+ hf_pn_io_ps_f_ipar_crc, &ipar_crc);
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, f_item, drep,
+ hf_pn_io_ps_f_par_crc, &par_crc);
+
+
+ /* Differniate between ipar_crc and no_ipar_crc */
+ if( (prm_flag2_f_block_id & 0x08) && !(prm_flag2_f_block_id & 0x20) ) { /* include ipar_crc display */
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ ", F-Parameter record, prm_flag1:0x%02x, prm_flag2:0x%02x, src:0x%04x,"
+ " dst:0x%04x, wd_time:%d, ipar_crc:0x%04x, crc:0x%04x",
+ prm_flag1, prm_flag2, src_addr, dst_addr, wd_time, ipar_crc, par_crc);
+
+ proto_item_append_text(f_item, "prm_flag1:0x%02x, prm_flag2:0x%02x, src:0x%04x, dst:0x%04x, wd_time:%d, ipar_crc:0x%04x, par_crc:0x%04x",
+ prm_flag1, prm_flag2, src_addr, dst_addr, wd_time, ipar_crc, par_crc);
+ }
+ else { /* exclude ipar_crc display */
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ ", F-Parameter record, prm_flag1:0x%02x, prm_flag2:0x%02x, src:0x%04x,"
+ " dst:0x%04x, wd_time:%d, crc:0x%04x",
+ prm_flag1, prm_flag2, src_addr, dst_addr, wd_time, par_crc);
+
+ proto_item_append_text(f_item, "prm_flag1:0x%02x, prm_flag2:0x%02x, src:0x%04x, dst:0x%04x, wd_time:%d, par_crc:0x%04x",
+ prm_flag1, prm_flag2, src_addr, dst_addr, wd_time, par_crc);
+ }
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ /* Get current conversation endpoints using MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, if no "Ident OK" frame as been dissected yet!
+ * Need to switch dl_src & dl_dst, as current packet is sent by controller and not by device.
+ * All conversations are based on Device MAC as addr1 */
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ current_aruuid_frame = pn_find_aruuid_frame_setup(pinfo);
+
+ if (current_aruuid_frame != NULL) {
+ current_aruuid = current_aruuid_frame->aruuid.data1;
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, current_aruuid);
+
+ if (station_info != NULL) {
+ pn_find_dcp_station_info(station_info, conversation);
+
+ if (frame != NULL) {
+ io_data_object = (ioDataObject*)wmem_list_frame_data(frame);
+
+ io_data_object->f_par_crc1 = par_crc;
+ io_data_object->f_src_adr = src_addr;
+ io_data_object->f_dest_adr = dst_addr;
+ io_data_object->f_crc_seed = prm_flag1 & 0x40;
+ if (!(prm_flag1 & 0x10)) {
+ if (prm_flag1 & 0x20) {
+ io_data_object->f_crc_len = 4;
+ } else {
+ io_data_object->f_crc_len = 3;
+ }
+ }
+ }
+
+ /* Find same module within output data to saved data */
+ for (frame_out = wmem_list_head(station_info->ioobject_data_out); frame_out != NULL; frame_out = wmem_list_frame_next(frame_out)) {
+ io_data_object = (ioDataObject*)wmem_list_frame_data(frame_out);
+ if (u16Index == io_data_object->fParameterIndexNr && /* Check F-Parameter Indexnumber */
+ io_data_object->profisafeSupported && /* Arrayelement has to be PS-Module */
+ io_data_object->f_par_crc1 == 0) { /* Find following object with no f_par_crc1 */
+
+ io_data_object->f_par_crc1 = par_crc;
+ io_data_object->f_src_adr = src_addr;
+ io_data_object->f_dest_adr = dst_addr;
+ io_data_object->f_crc_seed = prm_flag1 & 0x40;
+ if (!(prm_flag1 & 0x10)) {
+ if (prm_flag1 & 0x20) {
+ io_data_object->f_crc_len = 4;
+ } else {
+ io_data_object->f_crc_len = 3;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ return offset;
+}
+
+static int
+dissect_RecordDataWrite(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16Index, guint32 u32RecDataLen)
+{
+ conversation_t *conversation;
+ stationInfo *station_info;
+ wmem_list_frame_t *frame;
+ ioDataObject *io_data_object;
+
+ const gchar *userProfile;
+ pnio_ar_t *ar = NULL;
+
+ ARUUIDFrame *current_aruuid_frame = NULL;
+ guint32 current_aruuid = 0;
+
+ /* PROFISafe */
+ /* Get current conversation endpoints using MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, if no "Ident OK" frame as been dissected yet!
+ * Need to switch dl_src & dl_dst, as current packet is sent by controller and not by device.
+ * All conversations are based on Device MAC as addr1 */
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ current_aruuid_frame = pn_find_aruuid_frame_setup(pinfo);
+
+ if (current_aruuid_frame != NULL) {
+ current_aruuid = current_aruuid_frame->aruuid.data1;
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, current_aruuid);
+
+ if (station_info != NULL) {
+ pn_find_dcp_station_info(station_info, conversation);
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ /* Search within the entire existing list for current input object data */
+ for (frame = wmem_list_head(station_info->ioobject_data_in); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ io_data_object = (ioDataObject*)wmem_list_frame_data(frame);
+ if (u16Index == io_data_object->fParameterIndexNr && /* Check F-Parameter Indexnumber */
+ io_data_object->profisafeSupported && /* Arrayelement has to be PS-Module */
+ io_data_object->f_par_crc1 == 0) { /* Find following object with no f_par_crc1 */
+
+ return dissect_ProfiSafeParameterRequest(tvb, offset, pinfo, tree, drep, u16Index, frame);
+ }
+ }
+ }
+ else {
+ /* User clicked another time the frame to see the data -> PROFIsafe data has already been saved
+ * Check whether the device contains an PROFIsafe supported submodule.
+ */
+
+ for (frame = wmem_list_head(station_info->ioobject_data_in); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ io_data_object = (ioDataObject*)wmem_list_frame_data(frame);
+ if (u16Index == io_data_object->fParameterIndexNr && /* Check F-Parameter Indexnumber */
+ io_data_object->profisafeSupported) { /* Arrayelement has to be PS-Module */
+
+ return dissect_ProfiSafeParameterRequest(tvb, offset, pinfo, tree, drep, u16Index, frame);
+ }
+ }
+
+ for (frame = wmem_list_head(station_info->ioobject_data_out); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ io_data_object = (ioDataObject*)wmem_list_frame_data(frame);
+ if (u16Index == io_data_object->fParameterIndexNr && /* Check F-Parameter Indexnumber */
+ io_data_object->profisafeSupported) { /* Arrayelement has to be PS-Module */
+
+ return dissect_ProfiSafeParameterRequest(tvb, offset, pinfo, tree, drep, u16Index, frame);
+ }
+ }
+ }
+ }
+ /* profidrive parameter request */
+ if (u16Index == 0xb02e || u16Index == 0xb02f || u16Index == 0x002f) {
+ return dissect_ProfiDriveParameterRequest(tvb, offset, pinfo, tree, drep);
+ }
+
+ /* user specified format? */
+ if (u16Index < 0x8000) {
+ return dissect_pn_user_data(tvb, offset, pinfo, tree, u32RecDataLen, "User Specified Data");
+ }
+
+
+
+ /* "reserved for profiles"? */
+ userProfile = indexReservedForProfiles(u16Index);
+ if (userProfile != NULL) {
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, u32RecDataLen, userProfile);
+ return offset;
+ }
+
+ /* see: pn_io_index */
+ switch (u16Index) {
+ case(0x8020): /* PDIRSubframeData */
+ case(0x801e): /* SubstituteValues for one subslot */
+ case(0x802b): /* PDPortDataCheck for one subslot */
+ case(0x802c): /* PDirData for one subslot */
+ case(0x802d): /* Expected PDSyncData for one subslot with SyncID value 0 for PTCPoverRTA */
+ case(0x802e): /* Expected PDSyncData for one subslot with SyncID value 0 for PTCPoverRTC */
+ case(0x802f): /* PDPortDataAdjust for one subslot */
+ case(0x8030): /* IsochronousModeData for one subslot */
+ case(0x8031): /* PDTimeData for one subslot */
+ case(0x8051): /* PDInterfaceMrpDataCheck for one subslot */
+ case(0x8052): /* PDInterfaceMrpDataAdjust for one subslot */
+ case(0x8053): /* PDPortMrpDataAdjust for one subslot */
+ case(0x8055): /* PDPortMrpIcDataAdjust for one subslot */
+ case(0x8056): /* PDPortMrpIcDataCheck for one subslot */
+ case(0x8061): /* PDPortFODataCheck for one subslot */
+ case(0x8062): /* PDPortFODataAdjust for one subslot */
+ case(0x8063): /* PDPortSFPDataCheck for one subslot */
+ case(0x8070): /* PDNCDataCheck for one subslot */
+ case(0x8071): /* PDInterfaceAdjust */
+ case(0x8090): /* PDInterfaceFSUDataAdjust */
+ case(0x80B0): /* CombinedObjectContainer*/
+ case(0x80CF): /* RS_AdjustObserver */
+ case(0x8200): /* CIMSNMPAdjust */
+ case(0xaff1): /* I&M1 */
+ case(0xaff2): /* I&M2 */
+ case(0xaff3): /* I&M3 */
+ case(0xe050): /* FastStartUp data for one AR */
+ case(0xe061): /* RS_AckEvent (using RecordDataWrite service) */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, u32RecDataLen);
+ }
+
+ return offset;
+}
+
+#define PN_IO_MAX_RECURSION_DEPTH 100
+
+static int
+dissect_IODWriteReq(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, pnio_ar_t **ar, guint recursion_count)
+{
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen = 0;
+
+ if (++recursion_count >= PN_IO_MAX_RECURSION_DEPTH) {
+ proto_tree_add_expert(tree, pinfo, &ei_pn_io_max_recursion_depth_reached,
+ tvb, 0, 0);
+ return tvb_captured_length(tvb);
+ }
+
+ /* IODWriteHeader */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, ar);
+
+ /* IODWriteMultipleReq? */
+ if (u16Index == 0xe040) {
+ while (tvb_captured_length_remaining(tvb, offset) > 0) {
+ offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, ar, recursion_count++);
+ }
+ } else {
+ tvbuff_t *new_tvb = tvb_new_subset_length(tvb, offset, u32RecDataLen);
+ /* RecordDataWrite */
+ offset += dissect_RecordDataWrite(new_tvb, 0, pinfo, tree, drep, u16Index, u32RecDataLen);
+
+ /* Padding */
+ switch (offset % 4) {
+ case(3):
+ offset += 1;
+ break;
+ case(2):
+ offset += 2;
+ break;
+ case(1):
+ offset += 3;
+ break;
+ default: /* will not execute because of the line preceding the switch */
+ break;
+ }
+ }
+
+ return offset;
+}
+
+/* dissect a PN-IO write request */
+static int
+dissect_IPNIO_Write_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ pnio_ar_t *ar = NULL;
+ guint recursion_count = 0;
+
+ offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar, recursion_count);
+
+ if (ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
+ return offset;
+}
+
+
+
+static int
+dissect_IODWriteRes(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+
+
+ /* IODWriteResHeader */
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+
+ /* IODWriteMultipleRes? */
+ if (u16Index == 0xe040) {
+ while (tvb_captured_length_remaining(tvb, offset) > 0) {
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
+ }
+ }
+
+ if (ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
+ return offset;
+}
+
+
+/* dissect a PN-IO write response */
+static int
+dissect_IPNIO_Write_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect any number of PN-RSI blocks */
+int
+dissect_rsi_blocks(tvbuff_t* tvb, int offset,
+ packet_info* pinfo, proto_tree* tree, guint8* drep, guint32 u32FOpnumOffsetOpnum, int type)
+{
+ pnio_ar_t* ar = NULL;
+ guint recursion_count = 0;
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen = 0;
+
+
+ switch (u32FOpnumOffsetOpnum) {
+ case(0x0): // Connect request or response
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+ break;
+ case(0x2): // Read request or response
+ offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
+ break;
+ case(0x3): // Write request or response
+ if (type == PDU_TYPE_REQ)
+ offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar, recursion_count);
+ else if (type == PDU_TYPE_RSP)
+ offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
+ break;
+ case(0x4): // Control request or response
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+ break;
+ case(0x5): // ReadImplicit request or response
+ offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
+ break;
+ case(0x6): // ReadConnectionless request or response
+ offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
+ break;
+ case(0x7): // ReadNotification request or response
+ offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
+ break;
+ case(0x8): // PrmWriteMore request or response
+ if (type == PDU_TYPE_REQ)
+ offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar, recursion_count);
+ else if (type == PDU_TYPE_RSP)
+ offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
+ break;
+ case(0x9): // PrmWriteEnd request or response
+ if (type == PDU_TYPE_REQ)
+ offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar, recursion_count);
+ else if (type == PDU_TYPE_RSP)
+ offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
+ break;
+ default:
+ col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
+ break;
+ }
+
+ if (ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
+ return offset;
+}
+
+
+/* dissect the IOxS (IOCS, IOPS) field */
+static int
+dissect_PNIO_IOxS(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, int hfindex)
+{
+
+ if (tree) {
+ guint8 u8IOxS;
+ proto_item *ioxs_item;
+ proto_tree *ioxs_tree;
+
+ u8IOxS = tvb_get_guint8(tvb, offset);
+
+ /* add ioxs subtree */
+ ioxs_item = proto_tree_add_uint(tree, hfindex, tvb, offset, 1, u8IOxS);
+ proto_item_append_text(ioxs_item,
+ " (%s%s)",
+ (u8IOxS & 0x01) ? "another IOxS follows " : "",
+ (u8IOxS & 0x80) ? "good" : "bad");
+ ioxs_tree = proto_item_add_subtree(ioxs_item, ett_pn_io_ioxs);
+
+ proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_datastate, tvb, offset, 1, u8IOxS);
+ proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_instance, tvb, offset, 1, u8IOxS);
+ proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_res14, tvb, offset, 1, u8IOxS);
+ proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_extension, tvb, offset, 1, u8IOxS);
+ }
+
+ return offset + 1;
+}
+
+
+/* dissect a PN-IO Cyclic Service Data Unit (on top of PN-RT protocol) */
+static int
+dissect_PNIO_C_SDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep _U_)
+{
+ proto_tree *data_tree = NULL;
+ /* gint iTotalLen = 0; */
+ /* gint iSubFrameLen = 0; */
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO");
+
+ if (tree) {
+ proto_item *data_item;
+ data_item = proto_tree_add_protocol_format(tree, proto_pn_io, tvb, offset, tvb_captured_length(tvb),
+ "PROFINET IO Cyclic Service Data Unit: %u bytes", tvb_captured_length(tvb));
+ data_tree = proto_item_add_subtree(data_item, ett_pn_io_rtc);
+ }
+
+ /*dissect_dcerpc_uint16(tvb, offset, pinfo, data_tree, drep, hf_pn_io_packedframe_SFCRC, &u16SFCRC);*/
+ if (dissect_CSF_SDU_heur(tvb, pinfo, data_tree, NULL))
+ return(tvb_captured_length(tvb));
+
+ /* XXX - dissect the remaining data */
+ /* this will be one or more DataItems followed by an optional GAP and RTCPadding */
+ /* as we don't have the required context information to dissect the specific DataItems, */
+ /* this will be tricky :-( */
+ /* actual: there may be an IOxS but most case there isn't so better display a data-stream */
+ /* offset = dissect_PNIO_IOxS(tvb, offset, pinfo, data_tree, drep, hf_pn_io_ioxs); */
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, tvb_captured_length_remaining(tvb, offset),
+ "User Data (including GAP and RTCPadding)");
+
+ return offset;
+}
+
+
+/* dissect a PN-IO RTA PDU (on top of PN-RT protocol) */
+static int
+dissect_PNIO_RTA(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16AlarmDstEndpoint;
+ guint16 u16AlarmSrcEndpoint;
+ guint8 u8PDUType;
+ guint8 u8PDUVersion;
+ guint8 u8WindowSize;
+ guint8 u8Tack;
+ guint16 u16SendSeqNum;
+ guint16 u16AckSeqNum;
+ guint16 u16VarPartLen;
+ int start_offset = offset;
+ guint16 u16Index = 0;
+ guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
+
+
+ proto_item *rta_item;
+ proto_tree *rta_tree;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-AL");
+
+ rta_item = proto_tree_add_protocol_format(tree, proto_pn_io, tvb, offset, tvb_captured_length(tvb),
+ "PROFINET IO Alarm");
+ rta_tree = proto_item_add_subtree(rta_item, ett_pn_io_rta);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_alarm_dst_endpoint, &u16AlarmDstEndpoint);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_alarm_src_endpoint, &u16AlarmSrcEndpoint);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: 0x%x, Dst: 0x%x",
+ u16AlarmSrcEndpoint, u16AlarmDstEndpoint);
+
+ /* PDU type */
+ sub_item = proto_tree_add_item(rta_tree, hf_pn_io_pdu_type, tvb, offset, 1, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pdu_type);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdu_type_type, &u8PDUType);
+ u8PDUType &= 0x0F;
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdu_type_version, &u8PDUVersion);
+ u8PDUVersion >>= 4;
+ proto_item_append_text(sub_item, ", Type: %s, Version: %u",
+ val_to_str_const(u8PDUType, pn_io_pdu_type, "Unknown"),
+ u8PDUVersion);
+
+ /* additional flags */
+ sub_item = proto_tree_add_item(rta_tree, hf_pn_io_add_flags, tvb, offset, 1, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_add_flags);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_window_size, &u8WindowSize);
+ u8WindowSize &= 0x0F;
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_tack, &u8Tack);
+ u8Tack >>= 4;
+ proto_item_append_text(sub_item, ", Window Size: %u, Tack: %u",
+ u8WindowSize, u8Tack);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_send_seq_num, &u16SendSeqNum);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_ack_seq_num, &u16AckSeqNum);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_var_part_len, &u16VarPartLen);
+
+ switch ( u8PDUType & 0x0F) {
+ case(1): /* Data-RTA */
+ col_append_str(pinfo->cinfo, COL_INFO, ", Data-RTA");
+ offset = dissect_block(tvb, offset, pinfo, rta_tree, drep, &u16Index, &u32RecDataLen, &ar);
+ break;
+ case(2): /* NACK-RTA */
+ col_append_str(pinfo->cinfo, COL_INFO, ", NACK-RTA");
+ /* no additional data */
+ break;
+ case(3): /* ACK-RTA */
+ col_append_str(pinfo->cinfo, COL_INFO, ", ACK-RTA");
+ /* no additional data */
+ break;
+ case(4): /* ERR-RTA */
+ col_append_str(pinfo->cinfo, COL_INFO, ", ERR-RTA");
+ offset = dissect_PNIO_status(tvb, offset, pinfo, rta_tree, drep);
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
+ }
+
+ proto_item_set_len(rta_item, offset - start_offset);
+
+ return offset;
+}
+
+
+/* possibly dissect a PN-IO related PN-RT packet */
+static gboolean
+dissect_PNIO_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ void *data)
+{
+ guint8 drep_data = 0;
+ guint8 *drep = &drep_data;
+ /* the sub tvb will NOT contain the frame_id here! */
+ guint16 u16FrameID = GPOINTER_TO_UINT(data);
+ heur_dtbl_entry_t *hdtbl_entry;
+ conversation_t* conversation;
+ guint8 isTimeAware = FALSE;
+
+ /*
+ * In case the packet is a protocol encoded in the basic PNIO transport stream,
+ * give that protocol a chance to make a heuristic dissection, before we continue
+ * to dissect it as a normal PNIO packet.
+ */
+ if (dissector_try_heuristic(heur_pn_subdissector_list, tvb, pinfo, tree, &hdtbl_entry, NULL))
+ return TRUE;
+
+ /* TimeAwareness Information needed for dissecting RTC3 - RTSteam frames */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+
+ if (conversation != NULL) {
+ isTimeAware = GPOINTER_TO_UINT(conversation_get_proto_data(conversation, proto_pn_io_time_aware_status));
+ }
+
+ /* is this a (none DFP) PNIO class 3 data packet? */
+ /* frame id must be in valid range (cyclic Real-Time, class=3) */
+ if (((u16FrameID >= 0x0100 && u16FrameID <= 0x06FF) || /* RTC3 non redundant */
+ (u16FrameID >= 0x0700 && u16FrameID <= 0x0fff)) && /* RTC3 redundant */
+ !isTimeAware) {
+ dissect_CSF_SDU_heur(tvb, pinfo, tree, data);
+ return TRUE;
+ }
+
+ /* is this a PNIO class stream data packet? */
+ /* frame id must be in valid range (cyclic Real-Time, class=Stream) */
+ if (((u16FrameID >= 0x1000 && u16FrameID <= 0x2FFF) ||
+ (u16FrameID >= 0x3800 && u16FrameID <= 0x3FFF)) &&
+ isTimeAware) {
+ dissect_CSF_SDU_heur(tvb, pinfo, tree, data);
+ return TRUE;
+ }
+
+ /* The following range is reserved for following developments */
+ /* frame id must be in valid range (Reserved) and
+ * first byte (CBA version field) has to be != 0x11 */
+ if (u16FrameID >= 0x4000 && u16FrameID <= 0x7fff) {
+ dissect_PNIO_C_SDU(tvb, 0, pinfo, tree, drep);
+ return TRUE;
+ }
+
+ /* is this a PNIO class 1 data packet? */
+ /* frame id must be in valid range (cyclic Real-Time, class=1) and
+ * first byte (CBA version field) has to be != 0x11 */
+ if (u16FrameID >= 0x8000 && u16FrameID < 0xbfff) {
+ dissect_PNIO_C_SDU_RTC1(tvb, 0, pinfo, tree, drep, u16FrameID);
+ return TRUE;
+ }
+
+ /* is this a PNIO class 1 (legacy) data packet? */
+ /* frame id must be in valid range (cyclic Real-Time, class=1, legacy) and
+ * first byte (CBA version field) has to be != 0x11 */
+ if (u16FrameID >= 0xc000 && u16FrameID < 0xfbff) {
+ dissect_PNIO_C_SDU_RTC1(tvb, 0, pinfo, tree, drep, u16FrameID);
+ return TRUE;
+ }
+
+ /* is this a PNIO high priority alarm packet? */
+ if (u16FrameID == 0xfc01) {
+ col_set_str(pinfo->cinfo, COL_INFO, "Alarm High");
+
+ dissect_PNIO_RTA(tvb, 0, pinfo, tree, drep);
+ return TRUE;
+ }
+
+ /* is this a PNIO low priority alarm packet? */
+ if (u16FrameID == 0xfe01) {
+ col_set_str(pinfo->cinfo, COL_INFO, "Alarm Low");
+
+ dissect_PNIO_RTA(tvb, 0, pinfo, tree, drep);
+ return TRUE;
+ }
+
+ /* is this a Remote Service Interface (RSI) packet*/
+ if (u16FrameID == 0xfe02) {
+ dissect_PNIO_RSI(tvb, 0, pinfo, tree, drep);
+ return TRUE;
+ }
+
+ /* this PN-RT packet doesn't seem to be PNIO specific */
+ return FALSE;
+}
+
+
+
+static gboolean
+pn_io_ar_conv_valid(packet_info *pinfo, void *user_data _U_)
+{
+ void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_pn_io, 0);
+
+ return ((profinet_type != NULL) && (GPOINTER_TO_UINT(profinet_type) == 10));
+}
+
+static gchar *
+pn_io_ar_conv_filter(packet_info *pinfo, void *user_data _U_)
+{
+ pnio_ar_t *ar = (pnio_ar_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pn_io, 0);
+ void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_pn_io, 0);
+ char *buf;
+ address controllermac_addr, devicemac_addr;
+
+ if ((profinet_type == NULL) || (GPOINTER_TO_UINT(profinet_type) != 10) || (ar == NULL)) {
+ return NULL;
+ }
+
+ set_address(&controllermac_addr, AT_ETHER, 6, ar->controllermac);
+ set_address(&devicemac_addr, AT_ETHER, 6, ar->devicemac);
+
+ buf = ws_strdup_printf(
+ "pn_io.ar_uuid == %s || " /* ARUUID */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s) || " /* Alarm CR (contr -> dev) */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s)", /* Alarm CR (dev -> contr) */
+ guid_to_str(pinfo->pool, (const e_guid_t*) &ar->aruuid),
+ ar->controlleralarmref, address_to_str(pinfo->pool, &controllermac_addr),
+ ar->devicealarmref, address_to_str(pinfo->pool, &devicemac_addr));
+ return buf;
+}
+
+static gchar *
+pn_io_ar_conv_data_filter(packet_info *pinfo, void *user_data _U_)
+{
+ pnio_ar_t *ar = (pnio_ar_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_pn_io, 0);
+ void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_pn_io, 0);
+ char *buf, *controllermac_str, *devicemac_str, *guid_str;
+ address controllermac_addr, devicemac_addr;
+
+ if ((profinet_type == NULL) || (GPOINTER_TO_UINT(profinet_type) != 10) || (ar == NULL)) {
+ return NULL;
+ }
+
+ set_address(&controllermac_addr, AT_ETHER, 6, ar->controllermac);
+ set_address(&devicemac_addr, AT_ETHER, 6, ar->devicemac);
+
+ controllermac_str = address_to_str(pinfo->pool, &controllermac_addr);
+ devicemac_str = address_to_str(pinfo->pool, &devicemac_addr);
+ guid_str = guid_to_str(pinfo->pool, (const e_guid_t*) &ar->aruuid);
+ if (ar->arType == 0x0010) /* IOCARSingle using RT_CLASS_3 */
+ {
+ buf = ws_strdup_printf(
+ "pn_io.ar_uuid == %s || " /* ARUUID */
+ "(pn_rt.frame_id == 0x%x) || (pn_rt.frame_id == 0x%x) || "
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s) || " /* Alarm CR (contr -> dev) */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s)", /* Alarm CR (dev -> contr) */
+ guid_str,
+ ar->inputframeid, ar->outputframeid,
+ ar->controlleralarmref, controllermac_str,
+ ar->devicealarmref, devicemac_str);
+ }
+ else
+ {
+ buf = ws_strdup_printf(
+ "pn_io.ar_uuid == %s || " /* ARUUID */
+ "(pn_rt.frame_id == 0x%x && eth.src == %s && eth.dst == %s) || " /* Input CR && dev MAC -> contr MAC */
+ "(pn_rt.frame_id == 0x%x && eth.src == %s && eth.dst == %s) || " /* Output CR && contr MAC -> dev MAC */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s) || " /* Alarm CR (contr -> dev) */
+ "(pn_io.alarm_src_endpoint == 0x%x && eth.src == %s)", /* Alarm CR (dev -> contr) */
+ guid_str,
+ ar->inputframeid, devicemac_str, controllermac_str,
+ ar->outputframeid, controllermac_str, devicemac_str,
+ ar->controlleralarmref, controllermac_str,
+ ar->devicealarmref, devicemac_str);
+ }
+ return buf;
+}
+
+
+
+/* the PNIO dcerpc interface table */
+static dcerpc_sub_dissector pn_io_dissectors[] = {
+ { 0, "Connect", dissect_IPNIO_rqst, dissect_IPNIO_resp },
+ { 1, "Release", dissect_IPNIO_rqst, dissect_IPNIO_resp },
+ { 2, "Read", dissect_IPNIO_rqst, dissect_IPNIO_Read_resp },
+ { 3, "Write", dissect_IPNIO_Write_rqst, dissect_IPNIO_Write_resp },
+ { 4, "Control", dissect_IPNIO_rqst, dissect_IPNIO_resp },
+ { 5, "Read Implicit", dissect_IPNIO_rqst, dissect_IPNIO_Read_resp },
+ { 0, NULL, NULL, NULL }
+};
+
+
+static void
+pnio_cleanup(void) {
+ g_list_free(pnio_ars);
+ pnio_ars = NULL;
+}
+
+
+static void
+pnio_setup(void) {
+ aruuid_frame_setup_list = wmem_list_new(wmem_file_scope());
+ pnio_time_aware_frame_map = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
+}
+
+
+void
+proto_register_pn_io (void)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_io_opnum,
+ { "Operation", "pn_io.opnum",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_reserved16,
+ { "Reserved", "pn_io.reserved16",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_array,
+ { "Array", "pn_io.array",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_args_max,
+ { "ArgsMaximum", "pn_io.args_max",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_args_len,
+ { "ArgsLength", "pn_io.args_len",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_array_max_count,
+ { "MaximumCount", "pn_io.array_max_count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_array_offset,
+ { "Offset", "pn_io.array_offset",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_array_act_count,
+ { "ActualCount", "pn_io.array_act_count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_ar_data,
+ { "ARDATA for AR:", "pn_io.ar_data",
+ FT_NONE, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_type,
+ { "ARType", "pn_io.ar_type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ar_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_cminitiator_macadd,
+ { "CMInitiatorMacAdd", "pn_io.cminitiator_mac_add",
+ FT_ETHER, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_cminitiator_objectuuid,
+ { "CMInitiatorObjectUUID", "pn_io.cminitiator_uuid",
+ FT_GUID, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_parameter_server_objectuuid,
+ { "ParameterServerObjectUUID", "pn_io.parameter_server_objectuuid",
+ FT_GUID, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties,
+ { "ARProperties", "pn_io.ar_properties",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_state,
+ { "State", "pn_io.ar_properties.state",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_state), 0x00000007,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_supervisor_takeover_allowed,
+ { "SupervisorTakeoverAllowed", "pn_io.ar_properties.supervisor_takeover_allowed",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_supervisor_takeover_allowed), 0x00000008,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_parameterization_server,
+ { "ParameterizationServer", "pn_io.ar_properties.parameterization_server",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_parameterization_server), 0x00000010,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_artype_req,
+ { "ARType", "pn_io.artype_req",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_pn_io_ar_properties_companion_ar,
+ { "CompanionAR", "pn_io.ar_properties.companion_ar",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_companion_ar), 0x00000600,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_achnowledge_companion_ar,
+ { "AcknowledgeCompanionAR", "pn_io.ar_properties.acknowledge_companion_ar",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_acknowldege_companion_ar), 0x00000800,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_reserved,
+ { "Reserved", "pn_io.ar_properties.reserved",
+ FT_UINT32, BASE_HEX, NULL, 0x0FFFF000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_time_aware_system,
+ { "TimeAwareSystem", "pn_io.ar_properties.time_aware_system",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_time_aware_system), 0x10000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_combined_object_container_with_legacy_startupmode,
+ { "CombinedObjectContainer", "pn_io.ar_properties.combined_object_container",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_combined_object_container_with_legacy_startupmode), 0x20000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_combined_object_container_with_advanced_startupmode,
+ { "CombinedObjectContainer", "pn_io.ar_properties.combined_object_container",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_combined_object_container_with_advanced_startupmode), 0x20000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_arproperties_StartupMode,
+ { "StartupMode", "pn_io.ar_properties.StartupMode",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arpropertiesStartupMode), 0x40000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_pull_module_alarm_allowed,
+ { "PullModuleAlarmAllowed", "pn_io.ar_properties.pull_module_alarm_allowed",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_pull_module_alarm_allowed), 0x80000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_RedundancyInfo,
+ { "RedundancyInfo.EndPoint", "pn_io.srl_data.redundancyInfo",
+ FT_UINT16, BASE_HEX, VALS(pn_io_RedundancyInfo), 0x0003,
+ NULL, HFILL }
+ },
+ { &hf_pn_RedundancyInfo_reserved,
+ { "RedundancyInfo.reserved", "pn_io.srl_data.redundancyInfoReserved",
+ FT_UINT16, BASE_HEX, NULL, 0xFFFC,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_ARDATAInfo,
+ { "ARDataInfo.NumberOfEntries", "pn_io.number_of_ARDATAInfo",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_cminitiator_activitytimeoutfactor,
+ { "CMInitiatorActivityTimeoutFactor", "pn_io.cminitiator_activitytimeoutfactor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - special values */
+ { &hf_pn_io_cminitiator_udprtport,
+ { "CMInitiatorUDPRTPort", "pn_io.cminitiator_udprtport",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - special values */
+ { &hf_pn_io_station_name_length,
+ { "StationNameLength", "pn_io.station_name_length",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_cminitiator_station_name,
+ { "CMInitiatorStationName", "pn_io.cminitiator_station_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_parameter_server_station_name,
+ { "ParameterServerStationName", "pn_io.parameter_server_station_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_cmresponder_macadd,
+ { "CMResponderMacAdd", "pn_io.cmresponder_macadd",
+ FT_ETHER, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_cmresponder_udprtport,
+ { "CMResponderUDPRTPort", "pn_io.cmresponder_udprtport",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - special values */
+ { &hf_pn_io_number_of_iocrs,
+ { "NumberOfIOCRs", "pn_io.number_of_iocrs",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_tree,
+ { "IOCR", "pn_io.iocr_tree",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_type,
+ { "IOCRType", "pn_io.iocr_type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_iocr_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_reference,
+ { "IOCRReference", "pn_io.iocr_reference",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_SubframeOffset,
+ { "-> SubframeOffset", "pn_io.subframe_offset",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_SubframeData,
+ { "SubframeData", "pn_io.subframe_data",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_RedundancyDataHoldFactor,
+ { "RedundancyDataHoldFactor", "pn_io.RedundancyDataHoldFactor",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_RedundancyDataHoldFactor), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sr_properties,
+ { "SRProperties", "pn_io.sr_properties",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sr_properties_InputValidOnBackupAR_with_SRProperties_Mode_0,
+ { "InputValidOnBackupAR", "pn_io.sr_properties.InputValidOnBackupAR",
+ FT_BOOLEAN, 32, TFS(&tfs_pn_io_sr_properties_BackupAR_with_SRProperties_Mode_0), 0x00000001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sr_properties_InputValidOnBackupAR_with_SRProperties_Mode_1,
+ { "InputValidOnBackupAR", "pn_io.sr_properties.InputValidOnBackupAR",
+ FT_BOOLEAN, 32, TFS(&tfs_pn_io_sr_properties_BackupAR_with_SRProperties_Mode_1), 0x00000001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sr_properties_Reserved_1,
+ { "Reserved_1", "pn_io.sr_properties.Reserved_1",
+ FT_BOOLEAN, 32, TFS(&tfs_pn_io_sr_properties_Reserved1), 0x00000002,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sr_properties_Mode,
+ { "Mode", "pn_io.sr_properties.Mode",
+ FT_BOOLEAN, 32, TFS(&tfs_pn_io_sr_properties_Mode), 0x00000004,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sr_properties_Reserved_2,
+ { "Reserved_2", "pn_io.sr_properties.Reserved_2",
+ FT_UINT32, BASE_HEX, NULL, 0x0000FFF8,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sr_properties_Reserved_3,
+ { "Reserved_3", "pn_io.sr_properties.Reserved_3",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_arvendor_strucidentifier_if0_low,
+ { "APStructureIdentifier: Vendor specific", "pn_io.structidentifier_api_0_low",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_arvendor_strucidentifier_if0_high,
+ { "APStructureIdentifier: Administrative number for common profiles", "pn_io.structidentifier_api_0_high",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_arvendor_strucidentifier_if0_is8000,
+ { "APStructureIdentifier: Extended identification rules", "pn_io.tructidentifier_api_0_is8000",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_arvendor_strucidentifier_not0,
+ { "APStructureIdentifier: Administrative number for application profiles", "pn_io.tructidentifier_api_not_0",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_lt,
+ { "LT", "pn_io.lt",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties,
+ { "IOCRProperties", "pn_io.iocr_properties",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties_rtclass,
+ { "RTClass", "pn_io.iocr_properties.rtclass",
+ FT_UINT32, BASE_HEX, VALS(pn_io_iocr_properties_rtclass), 0x0000000F,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties_reserved_1,
+ { "Reserved1", "pn_io.iocr_properties.reserved1",
+ FT_UINT32, BASE_HEX, NULL, 0x00000FF0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties_media_redundancy,
+ { "MediaRedundancy", "pn_io.iocr_properties.media_redundancy",
+ FT_UINT32, BASE_HEX, VALS(pn_io_iocr_properties_media_redundancy), 0x00000800,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties_reserved_2,
+ { "Reserved2", "pn_io.iocr_properties.reserved2",
+ FT_UINT32, BASE_HEX, NULL, 0x00FFF000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties_reserved_3,
+ { "Reserved3", "pn_io.iocr_properties.reserved3",
+ FT_UINT32, BASE_HEX, NULL, 0x0F000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties_fast_forwarding_mac_adr,
+ { "FastForwardingMACAdr", "pn_io.iocr_properties.fast_forwarding_mac_adr",
+ FT_UINT32, BASE_HEX, NULL, 0x20000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties_distributed_subframe_watchdog,
+ { "DistributedSubFrameWatchDog", "pn_io.iocr_properties.distributed_subframe_watchdog",
+ FT_UINT32, BASE_HEX, NULL, 0x40000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_properties_full_subframe_structure,
+ { "FullSubFrameStructure", "pn_io.iocr_properties.full_subframe_structure",
+ FT_UINT32, BASE_HEX, NULL, 0x80000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_SFIOCRProperties,
+ { "SFIOCRProperties", "pn_io.SFIOCRProperties",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_DistributedWatchDogFactor,
+ { "SFIOCRProperties.DistributedWatchDogFactor", "pn_io.SFIOCRProperties.DistributedWatchDogFactor",
+ FT_UINT32, BASE_HEX, NULL, 0x000000FF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_RestartFactorForDistributedWD,
+ { "SFIOCRProperties.RestartFactorForDistributedWD", "pn_io.SFIOCRProperties.RestartFactorForDistributedWD",
+ FT_UINT32, BASE_HEX, NULL, 0x0000ff00,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_SFIOCRProperties_DFPmode,
+ { "SFIOCRProperties.DFPmode", "pn_io.SFIOCRProperties.DFPmode",
+ FT_UINT32, BASE_HEX, NULL, 0x00FF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_SFIOCRProperties_reserved_1,
+ { "SFIOCRProperties.reserved_1", "pn_io.SFIOCRProperties.reserved_1",
+ FT_UINT32, BASE_HEX, NULL, 0x0F000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_SFIOCRProperties_reserved_2,
+ { "SFIOCRProperties.reserved_2", "pn_io.SFIOCRProperties.reserved_2",
+ FT_UINT32, BASE_HEX, NULL, 0x10000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_SFIOCRProperties_DFPType,
+ { "SFIOCRProperties.DFPType", "pn_io.SFIOCRProperties.DFPType",
+ FT_UINT32, BASE_HEX, VALS(pn_io_SFIOCRProperties_DFPType_vals), 0x20000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_SFIOCRProperties_DFPRedundantPathLayout,
+ { "SFIOCRProperties.DFPRedundantPathLayout", "pn_io.SFIOCRProperties.DFPRedundantPathLayout",
+ FT_UINT32, BASE_HEX, VALS(pn_io_DFPRedundantPathLayout_decode), 0x40000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_SFIOCRProperties_SFCRC16,
+ { "SFIOCRProperties.SFCRC16", "pn_io.SFIOCRProperties.SFCRC16",
+ FT_UINT32, BASE_HEX, VALS(pn_io_SFCRC16_Decode), 0x80000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_length,
+ { "DataLength", "pn_io.data_length",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ir_frame_data,
+ { "Frame data", "pn_io.ir_frame_data",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_id,
+ { "FrameID", "pn_io.frame_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_send_clock_factor,
+ { "SendClockFactor", "pn_io.send_clock_factor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - special values */
+ { &hf_pn_io_reduction_ratio,
+ { "ReductionRatio", "pn_io.reduction_ratio",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - special values */
+ { &hf_pn_io_phase,
+ { "Phase", "pn_io.phase",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sequence,
+ { "Sequence", "pn_io.sequence",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_send_offset,
+ { "FrameSendOffset", "pn_io.frame_send_offset",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_data_properties,
+ { "FrameDataProperties", "pn_io.frame_data_properties",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_data_properties_forwarding_Mode,
+ { "ForwardingMode", "pn_io.frame_data_properties_forwardingMode",
+ FT_UINT32, BASE_HEX, VALS(hf_pn_io_frame_data_properties_forwardingMode), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_data_properties_FastForwardingMulticastMACAdd,
+ { "FastForwardingMulticastMACAdd", "pn_io.frame_data_properties_MulticastMACAdd",
+ FT_UINT32, BASE_HEX, VALS(hf_pn_io_frame_data_properties_FFMulticastMACAdd), 0x06,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_data_properties_FragmentMode,
+ { "FragmentationMode", "pn_io.frame_data_properties_FragMode",
+ FT_UINT32, BASE_HEX, VALS(hf_pn_io_frame_data_properties_FragMode), 0x18,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_data_properties_reserved_1,
+ { "Reserved_1", "pn_io.frame_data.reserved_1",
+ FT_UINT32, BASE_HEX, NULL, 0x0000FFE0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_data_properties_reserved_2,
+ { "Reserved_2", "pn_io.frame_data.reserved_2",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_watchdog_factor,
+ { "WatchdogFactor", "pn_io.watchdog_factor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_hold_factor,
+ { "DataHoldFactor", "pn_io.data_hold_factor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_tag_header,
+ { "IOCRTagHeader", "pn_io.iocr_tag_header",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocr_multicast_mac_add,
+ { "IOCRMulticastMACAdd", "pn_io.iocr_multicast_mac_add",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_apis,
+ { "NumberOfAPIs", "pn_io.number_of_apis",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_io_data_objects,
+ { "NumberOfIODataObjects", "pn_io.number_of_io_data_objects",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_iocs,
+ { "NumberOfIOCS", "pn_io.number_of_iocs",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocs_frame_offset,
+ { "IOCSFrameOffset", "pn_io.iocs_frame_offset",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarmcr_type,
+ { "AlarmCRType", "pn_io.alarmcr_type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_alarmcr_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarmcr_properties,
+ { "AlarmCRProperties", "pn_io.alarmcr_properties",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarmcr_properties_priority,
+ { "priority", "pn_io.alarmcr_properties.priority",
+ FT_UINT32, BASE_HEX, VALS(pn_io_alarmcr_properties_priority), 0x00000001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarmcr_properties_transport,
+ { "Transport", "pn_io.alarmcr_properties.transport",
+ FT_UINT32, BASE_HEX, VALS(pn_io_alarmcr_properties_transport), 0x00000002,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarmcr_properties_reserved,
+ { "Reserved", "pn_io.alarmcr_properties.reserved",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFFFFFC,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rta_timeoutfactor,
+ { "RTATimeoutFactor", "pn_io.rta_timeoutfactor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - special values */
+ { &hf_pn_io_rta_retries,
+ { "RTARetries", "pn_io.rta_retries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - only values 3 - 15 allowed */
+ { &hf_pn_io_localalarmref,
+ { "LocalAlarmReference", "pn_io.localalarmref",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - special values */
+ { &hf_pn_io_remotealarmref,
+ { "RemoteAlarmReference", "pn_io.remotealarmref",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - special values */
+ { &hf_pn_io_maxalarmdatalength,
+ { "MaxAlarmDataLength", "pn_io.maxalarmdatalength",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - only values 200 - 1432 allowed */
+ { &hf_pn_io_alarmcr_tagheaderhigh,
+ { "AlarmCRTagHeaderHigh", "pn_io.alarmcr_tagheaderhigh",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - 16 bitfield! */
+ { &hf_pn_io_alarmcr_tagheaderlow,
+ { "AlarmCRTagHeaderLow", "pn_io.alarmcr_tagheaderlow",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ }, /* XXX - 16 bitfield!*/
+ { &hf_pn_io_api_tree,
+ { "API", "pn_io.api_tree",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_module_tree,
+ { "Module", "pn_io.module_tree",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_tree,
+ { "Submodule", "pn_io.submodule_tree",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_io_data_object,
+ { "IODataObject", "pn_io.io_data_object",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_io_data_object_frame_offset,
+ { "IODataObjectFrameOffset", "pn_io.io_data_object.frame_offset",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_io_cs,
+ { "IOCS", "pn_io.io_cs",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_substitutionmode,
+ { "Substitutionmode", "pn_io.substitutionmode",
+ FT_UINT16, BASE_HEX, VALS(pn_io_substitutionmode), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_IRData_uuid,
+ { "IRDataUUID", "pn_io.IRData_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_uuid,
+ { "ARUUID", "pn_io.ar_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_target_ar_uuid,
+ { "TargetARUUID", "pn_io.target_ar_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_discriminator,
+ { "Discriminator", "pn_io.ar_discriminator",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_configid,
+ { "ConfigID", "pn_io.ar_configid",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_arnumber,
+ { "ARnumber", "pn_io.ar_arnumber",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ar_arnumber), 0x0007,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_arresource,
+ { "ARresource", "pn_io.ar_arresource",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ar_arresource), 0x0018,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_arreserved,
+ { "ARreserved", "pn_io.ar_arreserved",
+ FT_UINT16, BASE_HEX, NULL, 0xFFE0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_selector,
+ { "Selector", "pn_io.ar_selector",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_api,
+ { "API", "pn_io.api",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_slot_nr,
+ { "SlotNumber", "pn_io.slot_nr",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subslot_nr,
+ { "SubslotNumber", "pn_io.subslot_nr",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_index,
+ { "Index", "pn_io.index",
+ FT_UINT16, BASE_HEX, VALS(pn_io_index), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_seq_number,
+ { "SeqNumber", "pn_io.seq_number",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_record_data_length,
+ { "RecordDataLength", "pn_io.record_data_length",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_add_val1,
+ { "AdditionalValue1", "pn_io.add_val1",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_add_val2,
+ { "AdditionalValue2", "pn_io.add_val2",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_block_header,
+ { "BlockHeader", "pn_io.block_header",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_block_type,
+ { "BlockType", "pn_io.block_type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_block_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_block_length,
+ { "BlockLength", "pn_io.block_length",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_block_version_high,
+ { "BlockVersionHigh", "pn_io.block_version_high",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_block_version_low,
+ { "BlockVersionLow", "pn_io.block_version_low",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sessionkey,
+ { "SessionKey", "pn_io.session_key",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_alarm_sequence_number,
+ { "AlarmSequenceNumber", "pn_io.control_alarm_sequence_number",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command,
+ { "ControlCommand", "pn_io.control_command",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_reserved,
+ { "ControlBlockProperties.reserved", "pn_io.control_properties_reserved",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_prmend,
+ { "PrmEnd", "pn_io.control_command.prmend",
+ FT_UINT16, BASE_DEC, NULL, 0x0001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_applready,
+ { "ApplicationReady", "pn_io.control_command.applready",
+ FT_UINT16, BASE_DEC, NULL, 0x0002,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_release,
+ { "Release", "pn_io.control_command.release",
+ FT_UINT16, BASE_DEC, NULL, 0x0004,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_done,
+ { "Done", "pn_io.control_command.done",
+ FT_UINT16, BASE_DEC, NULL, 0x0008,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_ready_for_companion,
+ { "ReadyForCompanion", "pn_io.control_command.ready_for_companion",
+ FT_UINT16, BASE_DEC, NULL, 0x0010,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_ready_for_rt_class3,
+ { "ReadyForRT Class 3", "pn_io.control_command.ready_for_rt_class3",
+ FT_UINT16, BASE_DEC, NULL, 0x0020,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_prmbegin,
+ { "PrmBegin", "pn_io.control_command.prmbegin",
+ FT_UINT16, BASE_DEC, VALS(pn_io_control_properties_prmbegin_vals), 0x0040,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_command_reserved_7_15,
+ { "ControlBlockProperties.reserved", "pn_io.control_properties_reserved_7_15",
+ FT_UINT16, BASE_HEX, NULL, 0xFF80,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_block_properties,
+ { "ControlBlockProperties", "pn_io.control_block_properties",
+ FT_UINT16, BASE_HEX, VALS(pn_io_control_properties_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_block_properties_applready,
+ { "ControlBlockProperties", "pn_io.control_block_properties.appl_ready",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_block_properties_applready_bit0,
+ { "ApplicationReady.Bit0", "pn_io.control_block_properties.appl_ready_bit0",
+ FT_UINT16, BASE_HEX, VALS(pn_io_control_properties_application_ready_bit0_vals), 0x0001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_block_properties_applready_bit1,
+ { "ApplicationReady.Bit1", "pn_io.control_block_properties.appl_ready_bit1",
+ FT_UINT16, BASE_HEX, VALS(pn_io_control_properties_application_ready_bit1_vals), 0x0002,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_control_block_properties_applready_otherbits,
+ { "ApplicationReady.Bit2-15(reserved)", "pn_io.control_block_properties.appl_ready_otherbits",
+ FT_UINT16, BASE_HEX, NULL, 0xFFFC,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_SubmoduleListEntries,
+ { "NumberOfEntries", "pn_io.SubmoduleListEntries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_block,
+ { "Block", "pn_io.block",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_type,
+ { "AlarmType", "pn_io.alarm_type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_alarm_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_specifier,
+ { "AlarmSpecifier", "pn_io.alarm_specifier",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_specifier_sequence,
+ { "SequenceNumber", "pn_io.alarm_specifier.sequence",
+ FT_UINT16, BASE_HEX, NULL, 0x07FF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_specifier_channel,
+ { "ChannelDiagnosis", "pn_io.alarm_specifier.channel",
+ FT_UINT16, BASE_HEX, NULL, 0x0800,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_specifier_manufacturer,
+ { "ManufacturerSpecificDiagnosis", "pn_io.alarm_specifier.manufacturer",
+ FT_UINT16, BASE_HEX, NULL, 0x1000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_specifier_submodule,
+ { "SubmoduleDiagnosisState", "pn_io.alarm_specifier.submodule",
+ FT_UINT16, BASE_HEX, NULL, 0x2000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_specifier_ardiagnosis,
+ { "ARDiagnosisState", "pn_io.alarm_specifier.ardiagnosis",
+ FT_UINT16, BASE_HEX, NULL, 0x8000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_dst_endpoint,
+ { "AlarmDstEndpoint", "pn_io.alarm_dst_endpoint",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_alarm_src_endpoint,
+ { "AlarmSrcEndpoint", "pn_io.alarm_src_endpoint",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdu_type,
+ { "PDUType", "pn_io.pdu_type",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdu_type_type,
+ { "Type", "pn_io.pdu_type.type",
+ FT_UINT8, BASE_HEX, VALS(pn_io_pdu_type), 0x0F,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdu_type_version,
+ { "Version", "pn_io.pdu_type.version",
+ FT_UINT8, BASE_HEX, NULL, 0xF0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_add_flags,
+ { "AddFlags", "pn_io.add_flags",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_window_size,
+ { "WindowSize", "pn_io.window_size",
+ FT_UINT8, BASE_DEC, NULL, 0x0F,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tack,
+ { "TACK", "pn_io.tack",
+ FT_UINT8, BASE_HEX, NULL, 0xF0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_send_seq_num,
+ { "SendSeqNum", "pn_io.send_seq_num",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ack_seq_num,
+ { "AckSeqNum", "pn_io.ack_seq_num",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_var_part_len,
+ { "VarPartLen", "pn_io.var_part_len",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_module_ident_number,
+ { "ModuleIdentNumber", "pn_io.module_ident_number",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_ident_number,
+ { "SubmoduleIdentNumber", "pn_io.submodule_ident_number",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_number_of_modules,
+ { "NumberOfModules", "pn_io.number_of_modules",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_module_properties,
+ { "ModuleProperties", "pn_io.module_properties",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_module_state,
+ { "ModuleState", "pn_io.module_state",
+ FT_UINT16, BASE_HEX, VALS(pn_io_module_state), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_submodules,
+ { "NumberOfSubmodules", "pn_io.number_of_submodules",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_submodule_properties,
+ { "SubmoduleProperties", "pn_io.submodule_properties",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_properties_type,
+ { "Type", "pn_io.submodule_properties.type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_properties_type), 0x0003,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_properties_shared_input,
+ { "SharedInput", "pn_io.submodule_properties.shared_input",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_properties_shared_input), 0x0004,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_properties_reduce_input_submodule_data_length,
+ { "ReduceInputSubmoduleDataLength", "pn_io.submodule_properties.reduce_input_submodule_data_length",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_properties_reduce_input_submodule_data_length), 0x0008,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_properties_reduce_output_submodule_data_length,
+ { "ReduceOutputSubmoduleDataLength", "pn_io.submodule_properties.reduce_output_submodule_data_length",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_properties_reduce_output_submodule_data_length), 0x0010,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_properties_discard_ioxs,
+ { "DiscardIOXS", "pn_io.submodule_properties.discard_ioxs",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_properties_discard_ioxs), 0x0020,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_properties_reserved,
+ { "Reserved", "pn_io.submodule_properties.reserved",
+ FT_UINT16, BASE_HEX, NULL, 0xFFC0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state,
+ { "SubmoduleState", "pn_io.submodule_state",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_format_indicator,
+ { "FormatIndicator", "pn_io.submodule_state.format_indicator",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_format_indicator), 0x8000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_add_info,
+ { "AddInfo", "pn_io.submodule_state.add_info",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_add_info), 0x0007,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_advice,
+ { "Advice", "pn_io.submodule_state.advice",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_advice), 0x0008,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_maintenance_required,
+ { "MaintenanceRequired", "pn_io.submodule_state.maintenance_required",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_maintenance_required), 0x0010,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_maintenance_demanded,
+ { "MaintenanceDemanded", "pn_io.submodule_state.maintenance_demanded",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_maintenance_demanded), 0x0020,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_fault,
+ { "Fault", "pn_io.submodule_state.fault",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_fault), 0x0040,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_ar_info,
+ { "ARInfo", "pn_io.submodule_state.ar_info",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_ar_info), 0x0780,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_ident_info,
+ { "IdentInfo", "pn_io.submodule_state.ident_info",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_ident_info), 0x7800,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_state_detail,
+ { "Detail", "pn_io.submodule_state.detail",
+ FT_UINT16, BASE_HEX, VALS(pn_io_submodule_state_detail), 0x7FFF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_description_tree,
+ { "DataDescription", "pn_io.data_description_tree",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_description,
+ { "DataDescription", "pn_io.data_description",
+ FT_UINT16, BASE_HEX, VALS(pn_io_data_description), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_submodule_data_length,
+ { "SubmoduleDataLength", "pn_io.submodule_data_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_iocs,
+ { "LengthIOCS", "pn_io.length_iocs",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_iops,
+ { "LengthIOPS", "pn_io.length_iops",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_iocs,
+ { "IOCS", "pn_io.ioxs",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iops,
+ { "IOPS", "pn_io.iops",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ioxs_extension,
+ { "Extension (1:another IOxS follows/0:no IOxS follows)", "pn_io.ioxs.extension",
+ FT_UINT8, BASE_HEX, NULL, 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ioxs_res14,
+ { "Reserved (should be zero)", "pn_io.ioxs.res14",
+ FT_UINT8, BASE_HEX, NULL, 0x1E,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ioxs_instance,
+ { "Instance (only valid, if DataState is bad)",
+ "pn_io.ioxs.instance", FT_UINT8, BASE_HEX, VALS(pn_io_ioxs),
+ 0x60, NULL, HFILL }
+ },
+ { &hf_pn_io_ioxs_datastate,
+ { "DataState (1:good/0:bad)", "pn_io.ioxs.datastate",
+ FT_UINT8, BASE_HEX, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_address_resolution_properties,
+ { "AddressResolutionProperties", "pn_io.address_resolution_properties",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mci_timeout_factor,
+ { "MCITimeoutFactor", "pn_io.mci_timeout_factor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_provider_station_name,
+ { "ProviderStationName", "pn_io.provider_station_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_user_structure_identifier,
+ { "UserStructureIdentifier", "pn_io.user_structure_identifier",
+ FT_UINT16, BASE_HEX, VALS(pn_io_user_structure_identifier), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_user_structure_identifier_manf,
+ { "UserStructureIdentifier manufacturer specific", "pn_io.user_structure_identifier_manf",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ar_properties_reserved_1,
+ { "Reserved_1", "pn_io.ar_properties.reserved_1",
+ FT_UINT32, BASE_HEX, NULL, 0x000000E0,
+ NULL, HFILL }},
+ { &hf_pn_io_ar_properties_device_access,
+ { "DeviceAccess", "pn_io.ar_properties.device_access",
+ FT_UINT32, BASE_HEX, VALS(pn_io_arproperties_DeviceAccess), 0x00000100,
+ NULL, HFILL }},
+ { &hf_pn_io_subframe_data,
+ { "SubFrameData", "pn_io.subframe_data",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subframe_reserved2,
+ { "Reserved2", "pn_io.subframe_data.reserved2",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subframe_data_length,
+ { "DataLength", "pn_io.subframe_data.data_length",
+ FT_UINT32, BASE_HEX, NULL, 0x0000FF00,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subframe_reserved1,
+ { "Reserved1", "pn_io.subframe_data.reserved1",
+ FT_UINT32, BASE_HEX, NULL, 0x00000080,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subframe_data_position,
+ { "DataPosition", "pn_io.subframe_data.position",
+ FT_UINT32, BASE_HEX, NULL, 0x0000007F,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subframe_data_reserved1,
+ { "Reserved1", "pn_io.subframe_data.reserved_1",
+ FT_UINT32, BASE_HEX, NULL, 0x00000080,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subframe_data_reserved2,
+ { "Reserved2", "pn_io.subframe_data.reserved_2",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_channel_number,
+ { "ChannelNumber", "pn_io.channel_number",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_channel_properties,
+ { "ChannelProperties", "pn_io.channel_properties",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_channel_properties_type,
+ { "Type", "pn_io.channel_properties.type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_channel_properties_type), 0x00FF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_channel_properties_accumulative,
+ { "Accumulative", "pn_io.channel_properties.accumulative",
+ FT_UINT16, BASE_HEX, VALS(pn_io_channel_properties_accumulative_vals), 0x0100,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_NumberOfSubframeBlocks,
+ { "NumberOfSubframeBlocks", "pn_io.NumberOfSubframeBlocks",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_channel_properties_maintenance,
+ { "Maintenance (Severity)", "pn_io.channel_properties.maintenance",
+ FT_UINT16, BASE_HEX, VALS(pn_io_channel_properties_maintenance), 0x0600,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_channel_properties_specifier,
+ { "Specifier", "pn_io.channel_properties.specifier",
+ FT_UINT16, BASE_HEX, VALS(pn_io_channel_properties_specifier), 0x1800,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_channel_properties_direction,
+ { "Direction", "pn_io.channel_properties.direction",
+ FT_UINT16, BASE_HEX, VALS(pn_io_channel_properties_direction), 0xE000,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_channel_error_type,
+ { "ChannelErrorType", "pn_io.channel_error_type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_channel_error_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type0",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8000,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type0800",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8000), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8001,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type8001",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8001), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8002,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type8002",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8002), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8003,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type8003",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8003), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8004,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type8004",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8004), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8005,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type8005",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8005), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8007,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type8007",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8007), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8008,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type8008",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8008), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x800A,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type800A",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x800A), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x800B,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type800B",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x800B), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x800C,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type800C",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x800C), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type0x8010,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type8010",
+ FT_UINT16, BASE_HEX, VALS(pn_io_ext_channel_error_type0x8010), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_error_type,
+ { "ExtChannelErrorType", "pn_io.ext_channel_error_type",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ext_channel_add_value,
+ { "ExtChannelAddValue", "pn_io.ext_channel_add_value",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_qualified_channel_qualifier,
+ { "QualifiedChannelQualifier", "pn_io.qualified_channel_qualifier",
+ FT_UINT32, BASE_HEX, VALS(pn_io_qualified_channel_qualifier), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ptcp_subdomain_id,
+ { "PTCPSubdomainID", "pn_io.ptcp_subdomain_id",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ir_data_id,
+ { "IRDataID", "pn_io.ir_data_id",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_max_bridge_delay,
+ { "MaxBridgeDelay", "pn_io.max_bridge_delay",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_ports,
+ { "NumberOfPorts", "pn_io.number_of_ports",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_max_port_tx_delay,
+ { "MaxPortTxDelay", "pn_io.max_port_tx_delay",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_max_port_rx_delay,
+ { "MaxPortRxDelay", "pn_io.max_port_rx_delay",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_max_line_rx_delay,
+ { "MaxLineRxDelay", "pn_io.max_line_rx_delay",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_yellowtime,
+ { "YellowTime", "pn_io.yellowtime",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_reserved_interval_begin,
+ { "ReservedIntervalBegin", "pn_io.reserved_interval_begin",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_reserved_interval_end,
+ { "ReservedIntervalEnd", "pn_io.reserved_interval_end",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pllwindow,
+ { "PLLWindow", "pn_io.pllwindow",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sync_send_factor,
+ { "SyncSendFactor", "pn_io.sync_send_factor",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sync_properties,
+ { "SyncProperties", "pn_io.sync_properties",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_sync_frame_address,
+ { "SyncFrameAddress", "pn_io.sync_frame_address",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ptcp_timeout_factor,
+ { "PTCPTimeoutFactor", "pn_io.ptcp_timeout_factor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ptcp_takeover_timeout_factor,
+ { "PTCPTakeoverTimeoutFactor", "pn_io.ptcp_takeover_timeout_factor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ptcp_master_startup_time,
+ { "PTCPMasterStartupTime", "pn_io.ptcp_master_startup_time",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ptcp_master_priority_1,
+ { "PTCP_MasterPriority1", "pn_io.ptcp_master_priority_1",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ptcp_master_priority_2,
+ { "PTCP_MasterPriority2", "pn_io.ptcp_master_priority_2",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ptcp_length_subdomain_name,
+ { "PTCPLengthSubdomainName", "pn_io.ptcp_length_subdomain_name",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ptcp_subdomain_name,
+ { "PTCPSubdomainName", "pn_io.ptcp_subdomain_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_MultipleInterfaceMode_NameOfDevice,
+ { "MultipleInterfaceMode.NameOfDevice", "pn_io.MultipleInterfaceMode_NameOfDevice",
+ FT_UINT32, BASE_HEX, VALS(pn_io_MultipleInterfaceMode_NameOfDevice), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_MultipleInterfaceMode_reserved_1,
+ { "MultipleInterfaceMode.Reserved_1", "pn_io.MultipleInterfaceMode_reserved_1",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFE,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_MultipleInterfaceMode_reserved_2,
+ { "MultipleInterfaceMode.Reserved_2", "pn_io.MultipleInterfaceMode_reserved_2",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_counter_status,
+ { "CounterStatus", "pn_io.CounterStatus",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_counter_status_ifInOctets,
+ { "CounterStatus.ifInOctets", "pn_io.CounterStatus.ifInOctets",
+ FT_BOOLEAN, 16, TFS(&pn_io_pdportstatistic_counter_status_contents), 0x0001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_counter_status_ifOutOctets,
+ { "CounterStatus.ifOutOctets", "pn_io.CounterStatus.ifOutOctets",
+ FT_BOOLEAN, 16, TFS(&pn_io_pdportstatistic_counter_status_contents), 0x0002,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_counter_status_ifInDiscards,
+ { "CounterStatus.ifInDiscards", "pn_io.CounterStatus.ifInDiscards",
+ FT_BOOLEAN, 16, TFS(&pn_io_pdportstatistic_counter_status_contents), 0x0004,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_counter_status_ifOutDiscards,
+ { "CounterStatus.ifOutDiscards", "pn_io.CounterStatus.ifOutDiscards",
+ FT_BOOLEAN, 16, TFS(&pn_io_pdportstatistic_counter_status_contents), 0x0008,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_counter_status_ifInErrors,
+ { "CounterStatus.ifInErrors", "pn_io.CounterStatus.ifInErrors",
+ FT_BOOLEAN, 16, TFS(&pn_io_pdportstatistic_counter_status_contents), 0x0010,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_counter_status_ifOutErrors,
+ { "CounterStatus.ifOutErrors", "pn_io.CounterStatus.ifOutErrors",
+ FT_BOOLEAN, 16, TFS(&pn_io_pdportstatistic_counter_status_contents), 0x0020,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_counter_status_reserved,
+ { "CounterStatus.Reserved", "pn_io.CounterStatus.Reserved",
+ FT_UINT16, BASE_HEX, VALS(pn_io_pdportstatistic_counter_status_reserved), 0xFFC0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_ifInOctets,
+ { "ifInOctets", "pn_io.ifInOctets",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_ifOutOctets,
+ { "ifOutOctets", "pn_io.ifOutOctets",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_ifInDiscards,
+ { "ifInDiscards", "pn_io.ifInDiscards",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_ifOutDiscards,
+ { "ifOutDiscards", "pn_io.ifOutDiscards",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_ifInErrors,
+ { "ifInErrors", "pn_io.ifInErrors",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pdportstatistic_ifOutErrors,
+ { "ifOutErrors", "pn_io.ifOutErrors",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_domain_boundary,
+ { "DomainBoundary", "pn_io.domain_boundary",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_domain_boundary_ingress,
+ { "DomainBoundaryIngress", "pn_io.domain_boundary.ingress",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_domain_boundary_egress,
+ { "DomainBoundaryEgress", "pn_io.domain_boundary.egress",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_multicast_boundary,
+ { "MulticastBoundary", "pn_io.multicast_boundary",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_adjust_properties,
+ { "AdjustProperties", "pn_io.adjust_properties",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_PreambleLength,
+ { "Preamble Length", "pn_io.preamble_length",
+ FT_UINT16, BASE_DEC_HEX, VALS(pn_io_preamble_length), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_max_supported_record_size,
+ { "MaxSupportedRecordSize", "pn_io.tsn_upload_network_attributes.max_supported_record_size",
+ FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_max_supported_record_size_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_transfer_time_tx,
+ { "TransferTimeTX", "pn_io.tsn_upload_network_attributes.transfer_time_tx",
+ FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_transfer_time_tx_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_transfer_time_rx,
+ { "TransferTimeRX", "pn_io.tsn_upload_network_attributes.transfer_time_rx",
+ FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_transfer_time_rx_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_number_of_queues,
+ { "NumberOfQueues", "pn_io.tsn_port_id_block.number_of_queues",
+ FT_UINT8, BASE_HEX, VALS(pn_io_tsn_number_of_queues_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_forwarding_delay_block_number_of_entries,
+ { "TSNForwardingDelayBlockNumberOfEntries", "pn_io.tsn_forward_delaying_block.number_of_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_port_id_block_number_of_entries,
+ { "TSNPortIDBlockNumberOfEntries", "pn_io.tsn_port_id_block.number_of_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_expected_neighbor_block_number_of_entries,
+ { "TSNExpectedNeighborBlockNumberOfEntries", "pn_io.tsn_expected_neighbor_block.number_of_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_port_capabilities_time_aware,
+ { "TSNPortCapabilities.TimeAware", "pn_io.tsn_port_capabilities.time_aware",
+ FT_UINT8, BASE_HEX, VALS(pn_io_tsn_port_capabilities_time_aware_vals), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_port_capabilities_preemption,
+ { "TSNPortCapabilities.Preemption", "pn_io.tsn_port_capabilities.preemption",
+ FT_UINT8, BASE_HEX, VALS(pn_io_tsn_port_capabilities_preemption_vals), 0x02,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_port_capabilities_queue_masking,
+ { "TSNPortCapabilities.QueueMasking", "pn_io.tsn_port_capabilities.queue_masking",
+ FT_UINT8, BASE_HEX, VALS(pn_io_tsn_port_capabilities_queue_masking_vals), 0x04,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_port_capabilities_reserved,
+ { "TSNPortCapabilities.Reserved", "pn_io.tsn_port_capabilities_reserved",
+ FT_UINT8, BASE_HEX, NULL, 0xF8,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_forwarding_group,
+ { "ForwardingGroup", "pn_io.tsn_port_id_block.forwarding_group",
+ FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_forwarding_group_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_forwarding_group_ingress,
+ { "ForwardingGroupIngress", "pn_io.tsn_port_id_block.forwarding_group_ingress",
+ FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_forwarding_group_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_forwarding_group_egress,
+ { "ForwardingGroupEgress", "pn_io.tsn_port_id_block.forwarding_group_egress",
+ FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_forwarding_group_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_stream_class,
+ { "StreamClass", "pn_io.tsn_forwarding_delay_entry.stream_class",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_stream_class_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_dependent_forwarding_delay,
+ { "DependentForwardDelay", "pn_io.tsn_forwarding_delay_entry.dependent_forwarding_delay",
+ FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_dependent_forwarding_delay_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_independent_forwarding_delay,
+ { "IndependentForwardDelay", "pn_io.tsn_forwarding_delay_entry.independent_forwarding_delay",
+ FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_independent_forwarding_delay_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_nme_parameter_uuid,
+ { "NMEParameterUUID", "pn_io.tsn_nme_parameter_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config,
+ { "TSNDomainVIDConfig", "pn_io.tsn_domain_vid_config",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_stream_high_vid,
+ { "TSNDomainVIDConfig.StreamHighVID", "pn_io.tsn_domain_vid_config.stream_high_vid",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_domain_vid_config_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_stream_high_red_vid,
+ { "TSNDomainVIDConfig.StreamHighRedVID", "pn_io.tsn_domain_vid_config.stream_high_red_vid",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_domain_vid_config_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_stream_low_vid,
+ { "TSNDomainVIDConfig.StreamLowVID", "pn_io.tsn_domain_vid_config.stream_low_vid",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_domain_vid_config_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_stream_low_red_vid,
+ { "TSNDomainVIDConfig.StreamLowRedVID", "pn_io.tsn_domain_vid_config.stream_low_red_vid",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_domain_vid_config_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_non_stream_vid,
+ { "TSNDomainVIDConfig.NonStreamVID", "pn_io.tsn_domain_vid_config.non_stream_vid",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_domain_vid_config_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_non_stream_vid_B,
+ { "TSNDomainVIDConfig.NonStreamVIDB", "pn_io.tsn_domain_vid_config.non_stream_vid_B",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_domain_vid_config_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_non_stream_vid_C,
+ { "TSNDomainVIDConfig.NonStreamVIDC", "pn_io.tsn_domain_vid_config.non_stream_vid_C",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_domain_vid_config_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_non_stream_vid_D,
+ { "TSNDomainVIDConfig.NonStreamVIDD", "pn_io.tsn_domain_vid_config.non_stream_vid_D",
+ FT_UINT16, BASE_HEX, VALS(pn_io_tsn_domain_vid_config_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_vid_config_reserved,
+ { "TSNDomainVIDConfig.Reserved", "pn_io.tsn_domain_vid_config.reserved",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_tsn_domain_port_config_entries,
+ { "TSNDomainPortConfig.NumberOfEntries", "pn_io.tsn_domain_port_config.number_of_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_tsn_time_data_block_entries,
+ { "TSNTimeDataBlock.NumberOfEntries", "pn_io.tsn_time_data_block.number_of_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_tsn_domain_queue_rate_limiter_entries,
+ { "TSNDomainQueueRateLimiter.NumberOfEntries", "pn_io.tsn_domain_queue_rate_limiter.number_of_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_tsn_domain_port_ingress_rate_limiter_entries,
+ { "TSNDomainPortIngressRateLimiter.NumberOfEntries", "pn_io.tsn_domain_port_ingress_limiter.number_of_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_config,
+ { "TSNDomainPortConfig", "pn_io.tsn_domain_port_config",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_config_preemption_enabled,
+ { "TSNDomainPortConfig.PreemptionEnabled", "pn_io.tsn_domain_port_config.preemption_enabled",
+ FT_UINT8, BASE_HEX, VALS(pn_io_tsn_domain_port_config_preemption_enabled_vals), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_config_boundary_port_config,
+ { "TSNDomainPortConfig.BoundaryPortConfig", "pn_io.tsn_domain_port_config.boundary_port_config",
+ FT_UINT8, BASE_HEX, VALS(pn_io_tsn_domain_port_config_boundary_port_config_vals), 0x0E,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_config_reserved,
+ { "TSNDomainPortConfig.Reserved", "pn_io.tsn_domain_port_config.reserved",
+ FT_UINT8, BASE_HEX, NULL, 0xF0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_ingress_rate_limiter,
+ { "TSNDomainPortIngressRateLimiter", "pn_io.tsn_domain_port_ingress_rate_limiter",
+ FT_UINT64, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_ingress_rate_limiter_cir,
+ { "TSNDomainPortIngressRateLimiter.Cir", "pn_io.tsn_domain_port_ingress_rate_limiter.cir",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_port_ingress_rate_limiter_cir), 0x000000000000FFFF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_ingress_rate_limiter_cbs,
+ { "TSNDomainPortIngressRateLimiter.Cbs", "pn_io.tsn_domain_port_ingress_rate_limiter.cbs",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_port_ingress_rate_limiter_cbs), 0x00000000FFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_ingress_rate_limiter_envelope,
+ { "TSNDomainPortIngressRateLimiter.Envelope", "pn_io.tsn_domain_port_ingress_rate_limiter.envelope",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_port_ingress_rate_limiter_envelope), 0x0000FFFF00000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_ingress_rate_limiter_rank,
+ { "TSNDomainPortIngressRateLimiter.Rank", "pn_io.tsn_domain_port_ingress_rate_limiter.rank",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_port_ingress_rate_limiter_rank), 0xFFFF000000000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_rate_limiter,
+ { "TSNDomainQueueRateLimiter", "pn_io.tsn_domain_port_queue_rate_limiter",
+ FT_UINT64, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_rate_limiter_cir,
+ { "TSNDomainQueueRateLimiter.Cir", "pn_io.tsn_domain_port_queue_rate_limiter.cir",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_queue_rate_limiter_cir), 0x000000000000FFFF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_rate_limiter_cbs,
+ { "TSNDomainQueueRateLimiter.Cbs", "pn_io.tsn_domain_port_queue_rate_limiter.cbs",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_queue_rate_limiter_cbs), 0x00000000FFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_rate_limiter_envelope,
+ { "TSNDomainQueueRateLimiter.Envelope", "pn_io.tsn_domain_port_queue_rate_limiter.envelope",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_queue_rate_limiter_envelope), 0x000000FF00000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_rate_limiter_rank,
+ { "TSNDomainQueueRateLimiter.Rank", "pn_io.tsn_domain_port_queue_rate_limiter.rank",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_queue_rate_limiter_rank), 0x0000FF0000000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_rate_limiter_queue_id,
+ { "TSNDomainQueueRateLimiter.QueueID", "pn_io.tsn_domain_port_queue_rate_limiter.queue_id",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_queue_rate_limiter_queue_id), 0x00FF000000000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_rate_limiter_reserved,
+ { "TSNDomainQueueRateLimiter.Reserved", "pn_io.tsn_domain_port_queue_rate_limiter.reserved",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_queue_rate_limiter_reserved), 0xFF00000000000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_tsn_domain_queue_config_entries,
+ { "TSNDomainQueueConfig.NumberOfEntries", "pn_io.tsn_domain_queue_config.number_of_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_config,
+ { "TSNDomainQueueConfig", "pn_io.tsn_domain_queue_config",
+ FT_UINT64, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_config_queue_id,
+ { "TSNDomainQueueConfig.QueueID", "pn_io.tsn_domain_queue_config.queue_id",
+ FT_UINT64, BASE_HEX, NULL, 0xF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_config_tci_pcp,
+ { "TSNDomainQueueConfig.TciPcp", "pn_io.tsn_domain_queue_config.tci_pcp",
+ FT_UINT64, BASE_HEX, NULL, 0x70,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_config_shaper,
+ { "TSNDomainQueueConfig.Shaper", "pn_io.tsn_domain_queue_config.shaper",
+ FT_UINT64, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_queue_config_shaper), 0x3F80,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_config_preemption_mode,
+ { "TSNDomainQueueConfig.PreemptionMode", "pn_io.tsn_domain_queue_config.preemption_mode",
+ FT_UINT64, BASE_HEX, NULL, 0xC000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_config_unmask_time_offset,
+ { "TSNDomainQueueConfig.UnmaskTimeOffset", "pn_io.tsn_domain_queue_config.unmask_time_offset",
+ FT_UINT64, BASE_HEX, NULL, 0xFFFFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_queue_config_mask_time_offset,
+ { "TSNDomainQueueConfig.MaskTimeOffset", "pn_io.tsn_domain_queue_config.mask_time_offset",
+ FT_UINT64, BASE_HEX, NULL, 0xFFFFFF0000000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_network_deadline,
+ { "NetworkDeadline", "pn_io.network_deadline",
+ FT_UINT32, BASE_DEC | BASE_RANGE_STRING, RVALS(pn_io_network_domain), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_domain_number,
+ { "TimeDomainNumber", "pn_io.time_domain_number",
+ FT_UINT16, BASE_HEX , VALS(pn_io_time_domain_number_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_pll_window,
+ { "TimePLLWindow", "pn_io.time_pll_window",
+ FT_UINT32, BASE_DEC , VALS(pn_io_time_pll_window_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_message_interval_factor,
+ { "MessageIntervalFactor", "pn_io.message_interval_factor",
+ FT_UINT32, BASE_DEC , VALS(pn_io_message_interval_factor_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_message_timeout_factor,
+ { "MessageTimeoutFactor", "pn_io.message_timeout_factor",
+ FT_UINT16, BASE_DEC | BASE_RANGE_STRING, RVALS(pn_io_message_timeout_factor), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_sync_properties,
+ { "TimeSyncProperties", "pn_io.time_sync_properties",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_sync_properties_role,
+ { "TimeSyncProperties.Role", "pn_io.time_sync_properties.role",
+ FT_UINT16, BASE_HEX, VALS(pn_io_time_sync_properties_vals), 0x3,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_sync_properties_reserved,
+ { "TimeSyncProperties.Reserved", "pn_io.time_sync_properties.reserved",
+ FT_UINT16, BASE_HEX, NULL, 0xFFFC,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_domain_uuid,
+ { "TimeDomainUUID", "pn_io.time_domain_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_domain_name_length,
+ { "TimeDomainNameLength", "pn_io.time_domain_name_length",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_domain_name,
+ { "TimeDomainName", "pn_io.time_domain_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_nme_name_uuid,
+ { "TSNNMENameUUID", "pn_io.tsn_nme_name_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_nme_name_length,
+ { "TSNNMENameLength", "pn_io.tsn_nme_name_length",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_nme_name,
+ { "TSNNMEName", "pn_io.tsn_nme_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_uuid,
+ { "TSNDomainUUID", "pn_io.tsn_domain_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_name_length,
+ { "TSNDomainNameLength", "pn_io.tsn_domain_name_length",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_name,
+ { "TSNDomainName", "pn_io.tsn_domain_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_fdb_command,
+ { "FDBCommand", "pn_io.tsn_fdb_command",
+ FT_UINT8, BASE_HEX, VALS(pn_io_tsn_fdb_command), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_dst_add,
+ { "DestinationAddress", "pn_io.tsn_dst_add",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_tsn_domain_sync_tree_entries,
+ { "NumberOfEntries", "pn_io.tsn_domain_sync_tree_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_port_id,
+ { "TSNDomainPortID", "pn_io.tsn_domain_port_id",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tsn_domain_sync_port_role,
+ { "SyncPortRole", "pn_io.tsn_domain_sync_port_rule",
+ FT_UINT8,BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_tsn_domain_sync_port_role_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mau_type,
+ { "MAUType", "pn_io.mau_type",
+ FT_UINT16, BASE_HEX, VALS(pn_io_mau_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mau_type_mode,
+ { "MAUTypeMode", "pn_io.mau_type_mode",
+ FT_UINT16, BASE_HEX, VALS(pn_io_mau_type_mode), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_dcp_boundary_value,
+ { "DCPBoundary", "pn_io.dcp_boundary_value",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_dcp_boundary_value_bit0,
+ { "DCPBoundary", "pn_io.dcp_boundary_value_bit0",
+ FT_UINT32, BASE_HEX, VALS(pn_io_dcp_boundary_value_bit0), 0x1,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_dcp_boundary_value_bit1,
+ { "DCPBoundary", "pn_io.dcp_boundary_value_bit1",
+ FT_UINT32, BASE_HEX, VALS(pn_io_dcp_boundary_value_bit1), 0x2,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_dcp_boundary_value_otherbits,
+ { "DCPBoundary", "pn_io.dcp_boundary_value_otherbits",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFFFFFC,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_to_peer_boundary_value,
+ { "AdjustPeerToPeer-Boundary", "pn_io.peer_to_peer_boundary_value",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_to_peer_boundary_value_bit0,
+ { "AdjustPeerToPeer-Boundary", "pn_io.peer_to_peer_boundary_value_bit0",
+ FT_UINT32, BASE_HEX, VALS(pn_io_peer_to_peer_boundary_value_bit0), 0x1,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_to_peer_boundary_value_bit1,
+ { "AdjustPeerToPeer-Boundary", "pn_io.peer_to_peer_boundary_value_bit1",
+ FT_UINT32, BASE_HEX, VALS(pn_io_peer_to_peer_boundary_value_bit1), 0x2,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_to_peer_boundary_value_bit2,
+ { "AdjustPeerToPeer-Boundary", "pn_io.peer_to_peer_boundary_value_bit2",
+ FT_UINT32, BASE_HEX, VALS(pn_io_peer_to_peer_boundary_value_bit2), 0x4,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_to_peer_boundary_value_otherbits,
+ { "AdjustPeerToPeer-Boundary", "pn_io.peer_to_peer_boundary_value_otherbits",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFFFFF8,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_port_state,
+ { "PortState", "pn_io.port_state",
+ FT_UINT16, BASE_HEX, VALS(pn_io_port_state), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_link_state_port,
+ { "LinkState.Port", "pn_io.link_state_port",
+ FT_UINT8, BASE_HEX, VALS(pn_io_link_state_port), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_link_state_link,
+ { "LinkState.Link", "pn_io.link_state_link",
+ FT_UINT8, BASE_HEX, VALS(pn_io_link_state_link), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_line_delay,
+ { "LineDelay", "pn_io.line_delay",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "LineDelay in nanoseconds", HFILL }
+ },
+ { &hf_pn_io_line_delay_value,
+ { "LineDelayValue", "pn_io.line_delay_value",
+ FT_UINT32, BASE_DEC | BASE_RANGE_STRING, RVALS(pn_io_line_delay_value), 0x7FFFFFFF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_cable_delay_value,
+ { "CableDelayValue", "pn_io.cable_delay_value",
+ FT_UINT32, BASE_DEC | BASE_RANGE_STRING, RVALS(pn_io_cable_delay_value), 0x7FFFFFFF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_line_delay_format_indicator,
+ { "LineDelayFormatIndicator", "pn_io.line_delay_format_indicator",
+ FT_UINT32, BASE_HEX, NULL, 0x80000000,
+ "LineDelay FormatIndicator", HFILL }
+ },
+ { &hf_pn_io_number_of_peers,
+ { "NumberOfPeers", "pn_io.number_of_peers",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_peer_port_id,
+ { "LengthPeerPortID", "pn_io.length_peer_port_id",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_port_id,
+ { "PeerPortID", "pn_io.peer_port_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_peer_chassis_id,
+ { "LengthPeerChassisID", "pn_io.length_peer_chassis_id",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_chassis_id,
+ { "PeerChassisID", "pn_io.peer_chassis_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_neighbor,
+ { "Neighbor", "pn_io.neighbor",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_peer_port_name,
+ { "LengthPeerPortName", "pn_io.length_peer_port_name",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_port_name,
+ { "PeerPortName", "pn_io.peer_port_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_peer_station_name,
+ { "LengthPeerStationName", "pn_io.length_peer_station_name",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_station_name,
+ { "PeerStationName", "pn_io.peer_station_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_own_chassis_id,
+ { "LengthOwnChassisID", "pn_io.length_own_chassis_id",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_own_chassis_id,
+ { "OwnChassisID", "pn_io.own_chassis_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rtclass3_port_status,
+ { "RTClass3_PortStatus", "pn_io.rtclass3_port_status",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_own_port_id,
+ { "LengthOwnPortID", "pn_io.length_own_port_id",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_own_port_id,
+ { "OwnPortID", "pn_io.own_port_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_peer_macadd,
+ { "PeerMACAddress", "pn_io.peer_macadd",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_macadd,
+ { "MACAddress", "pn_io.macadd",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_media_type,
+ { "MediaType", "pn_io.media_type",
+ FT_UINT32, BASE_HEX, VALS(pn_io_media_type), 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_ethertype,
+ { "Ethertype", "pn_io.ethertype",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rx_port,
+ { "RXPort", "pn_io.rx_port",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_details,
+ { "FrameDetails", "pn_io.frame_details",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_details_sync_frame,
+ { "SyncFrame", "pn_io.frame_details.sync_frame",
+ FT_UINT8, BASE_HEX, VALS(pn_io_frame_details_sync_master_vals), 0x03,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_details_meaning_frame_send_offset,
+ { "Meaning", "pn_io.frame_details.meaning_frame_send_offset",
+ FT_UINT8, BASE_HEX, VALS(pn_io_frame_details_meaning_frame_send_offset_vals), 0x0C,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_details_reserved,
+ { "Reserved", "pn_io.frame_details.reserved",
+ FT_UINT8, BASE_HEX, NULL, 0xF0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_nr_of_tx_port_groups,
+ { "NumberOfTxPortGroups", "pn_io.nr_of_tx_port_groups",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties,
+ { "TxPortGroupProperties", "pn_io.tx_port_properties",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties_bit0,
+ { "TxPortLocal", "pn_io.tx_port_properties_bit_0",
+ FT_UINT8, BASE_HEX, VALS(pn_io_txgroup_state), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties_bit1,
+ { "TxPort_1", "pn_io.tx_port_properties_bit_1",
+ FT_UINT8, BASE_HEX, VALS(pn_io_txgroup_state), 0x02,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties_bit2,
+ { "TxPort_2", "pn_io.tx_port_properties_bit_2",
+ FT_UINT8, BASE_HEX, VALS(pn_io_txgroup_state), 0x04,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties_bit3,
+ { "TxPort_3", "pn_io.tx_port_properties_bit_3",
+ FT_UINT8, BASE_HEX, VALS(pn_io_txgroup_state), 0x08,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties_bit4,
+ { "TxPort_4", "pn_io.tx_port_properties_bit_4",
+ FT_UINT8, BASE_HEX, VALS(pn_io_txgroup_state), 0x10,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties_bit5,
+ { "TxPort_5", "pn_io.tx_port_properties_bit_5",
+ FT_UINT8, BASE_HEX, VALS(pn_io_txgroup_state), 0x20,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties_bit6,
+ { "TxPort_6", "pn_io.tx_port_properties_bit_6",
+ FT_UINT8, BASE_HEX, VALS(pn_io_txgroup_state), 0x40,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_TxPortGroupProperties_bit7,
+ { "TxPort_7", "pn_io.tx_port_properties_bit_7",
+ FT_UINT8, BASE_HEX, VALS(pn_io_txgroup_state), 0x80,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_start_of_red_frame_id,
+ { "StartOfRedFrameID", "pn_io.start_of_red_frame_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_end_of_red_frame_id,
+ { "EndOfRedFrameID", "pn_io.end_of_red_frame_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ir_begin_end_port,
+ { "Port", "pn_io.ir_begin_end_port",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_assignments,
+ { "NumberOfAssignments", "pn_io.number_of_assignments",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_phases,
+ { "NumberOfPhases", "pn_io.number_of_phases",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_red_orange_period_begin_tx,
+ { "RedOrangePeriodBegin [TX]", "pn_io.red_orange_period_begin_tx",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_orange_period_begin_tx,
+ { "OrangePeriodBegin [TX]", "pn_io.orange_period_begin_tx",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_green_period_begin_tx,
+ { "GreenPeriodBegin [TX]", "pn_io.green_period_begin_tx",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_red_orange_period_begin_rx,
+ { "RedOrangePeriodBegin [RX]", "pn_io.red_orange_period_begin_rx",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_orange_period_begin_rx,
+ { "OrangePeriodBegin [RX]", "pn_io.orange_period_begin_rx",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_green_period_begin_rx,
+ { "GreenPeriodBegin [RX]", "pn_io.green_period_begin_rx",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_ir_tx_phase_assignment,
+ { "TXPhaseAssignment", "pn_io.tx_phase_assignment_sub",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tx_phase_assignment_begin_value,
+ { "AssignedValueForReservedBegin", "pn_io.tx_phase_assignment_begin_value",
+ FT_UINT16, BASE_DEC, NULL, 0x000F,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tx_phase_assignment_orange_begin,
+ { "AssignedValueForOrangeBegin", "pn_io.tx_phase_assignment_orange_begin",
+ FT_UINT16, BASE_DEC, NULL, 0x00F0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tx_phase_assignment_end_reserved,
+ { "AssignedValueForReservedEnd", "pn_io.tx_phase_assignment_end_reserved",
+ FT_UINT16, BASE_DEC, NULL, 0x0F00,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_tx_phase_assignment_reserved,
+ { "Reserved should be 0", "pn_io.tx_phase_assignment_reserved",
+ FT_UINT16, BASE_DEC, NULL, 0xF000,
+ NULL, HFILL }
+ },
+ { &hf_pn_ir_rx_phase_assignment,
+ { "RXPhaseAssignment", "pn_io.rx_phase_assignment_sub",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_slot,
+ { "Slot", "pn_io.slot",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subslot,
+ { "Subslot", "pn_io.subslot",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_slots,
+ { "NumberOfSlots", "pn_io.number_of_slots",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_subslots,
+ { "NumberOfSubslots", "pn_io.number_of_subslots",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_maintenance_required_power_budget,
+ { "MaintenanceRequiredPowerBudget", "pn_io.maintenance_required_power_budget",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_maintenance_demanded_power_budget,
+ { "MaintenanceDemandedPowerBudget", "pn_io.maintenance_demanded_power_budget",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_power_budget,
+ { "ErrorPowerBudget", "pn_io.error_power_budget",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_fiber_optic_type,
+ { "FiberOpticType", "pn_io.fiber_optic_type",
+ FT_UINT32, BASE_HEX, VALS(pn_io_fiber_optic_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_fiber_optic_cable_type,
+ { "FiberOpticCableType", "pn_io.fiber_optic_cable_type",
+ FT_UINT32, BASE_HEX, VALS(pn_io_fiber_optic_cable_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_controller_appl_cycle_factor,
+ { "ControllerApplicationCycleFactor", "pn_io.controller_appl_cycle_factor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_data_cycle,
+ { "TimeDataCycle", "pn_io.time_data_cycle",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_io_input,
+ { "TimeIOInput", "pn_io.time_io_input",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_io_output,
+ { "TimeIOOutput", "pn_io.time_io_output",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_io_input_valid,
+ { "TimeIOInputValid", "pn_io.time_io_input_valid",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_time_io_output_valid,
+ { "TimeIOOutputValid", "pn_io.time_io_output_valid",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_maintenance_status,
+ { "MaintenanceStatus", "pn_io.maintenance_status",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_maintenance_status_required,
+ { "Required", "pn_io.maintenance_status_required",
+ FT_UINT32, BASE_HEX, NULL, 0x0001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_maintenance_status_demanded,
+ { "Demanded", "pn_io.maintenance_status_demanded",
+ FT_UINT32, BASE_HEX, NULL, 0x0002,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_vendor_id_high,
+ { "VendorIDHigh", "pn_io.vendor_id_high",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_vendor_id_low,
+ { "VendorIDLow", "pn_io.vendor_id_low",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_vendor_block_type,
+ { "VendorBlockType", "pn_io.vendor_block_type",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_order_id,
+ { "OrderID", "pn_io.order_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_serial_number,
+ { "IMSerialNumber", "pn_io.im_serial_number",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_hardware_revision,
+ { "IMHardwareRevision", "pn_io.im_hardware_revision",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ /* XXX - better use a simple char here -> vals */
+ { &hf_pn_io_im_revision_prefix,
+ { "IMRevisionPrefix", "pn_io.im_revision_prefix",
+ FT_CHAR, BASE_HEX, VALS(pn_io_im_revision_prefix_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_sw_revision_functional_enhancement,
+ { "IMSWRevisionFunctionalEnhancement", "pn_io.im_sw_revision_functional_enhancement",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_revision_bugfix,
+ { "IM_SWRevisionBugFix", "pn_io.im_revision_bugfix",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_sw_revision_internal_change,
+ { "IMSWRevisionInternalChange", "pn_io.im_sw_revision_internal_change",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_revision_counter,
+ { "IMRevisionCounter", "pn_io.im_revision_counter",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_profile_id,
+ { "IMProfileID", "pn_io.im_profile_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_profile_specific_type,
+ { "IMProfileSpecificType", "pn_io.im_profile_specific_type",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_version_major,
+ { "IMVersionMajor", "pn_io.im_version_major",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_version_minor,
+ { "IMVersionMinor", "pn_io.im_version_minor",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_supported,
+ { "IM_Supported", "pn_io.im_supported",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_numberofentries,
+ { "NumberOfEntries", "pn_io.im_numberofentries",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_annotation,
+ { "IM Annotation", "pn_io.im_annotation",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_order_id,
+ { "IM Order ID", "pn_io.im_order_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_ars,
+ { "NumberOfARs", "pn_io.number_of_ars",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_cycle_counter,
+ { "CycleCounter", "pn_io.cycle_counter",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_status,
+ { "DataStatus", "pn_io.ds",
+ FT_UINT8, BASE_HEX, 0, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_status_res67,
+ { "Reserved (should be zero)", "pn_io.ds_res67",
+ FT_UINT8, BASE_HEX, 0, 0xc0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_status_ok,
+ { "StationProblemIndicator (1:Ok/0:Problem)", "pn_io.ds_ok",
+ FT_UINT8, BASE_HEX, 0, 0x20,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_status_operate,
+ { "ProviderState (1:Run/0:Stop)", "pn_io.ds_operate",
+ FT_UINT8, BASE_HEX, 0, 0x10,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_status_res3,
+ { "Reserved (should be zero)", "pn_io.ds_res3",
+ FT_UINT8, BASE_HEX, 0, 0x08,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_status_valid,
+ { "DataValid (1:Valid/0:Invalid)", "pn_io.ds_valid",
+ FT_UINT8, BASE_HEX, 0, 0x04,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_status_res1,
+ { "primary AR of a given AR-set is present (0:One/ 1:None)", "pn_io.ds_res1",
+ FT_UINT8, BASE_HEX, 0, 0x02,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_data_status_primary,
+ { "State (1:Primary/0:Backup)", "pn_io.ds_primary",
+ FT_UINT8, BASE_HEX, 0, 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_transfer_status,
+ { "TransferStatus", "pn_io.transfer_status",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_actual_local_time_stamp,
+ { "ActualLocalTimeStamp", "pn_io.actual_local_time_stamp",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_local_time_stamp,
+ { "LocalTimeStamp", "pn_io.local_time_stamp",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_log_entries,
+ { "NumberOfLogEntries", "pn_io.number_of_log_entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_entry_detail,
+ { "EntryDetail", "pn_io.entry_detail",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ip_address,
+ { "IPAddress", "pn_io.ip_address",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_subnetmask,
+ { "Subnetmask", "pn_io.subnetmask",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_standard_gateway,
+ { "StandardGateway", "pn_io.standard_gateway",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_mrp_domain_uuid,
+ { "MRP_DomainUUID", "pn_io.mrp_domain_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_role,
+ { "MRP_Role", "pn_io.mrp_role",
+ FT_UINT16, BASE_HEX, VALS(pn_io_mrp_role_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_length_domain_name,
+ { "MRP_LengthDomainName", "pn_io.mrp_length_domain_name",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_domain_name,
+ { "MRP_DomainName", "pn_io.mrp_domain_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_instances,
+ { "NumberOfMrpInstances", "pn_io.mrp_Number_MrpInstances",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_instance,
+ { "Mrp_Instance", "pn_io.mrp_MrpInstance",
+ FT_UINT8, BASE_DEC, VALS(pn_io_mrp_instance_no), 0x0,
+ NULL, HFILL }
+ },
+
+ { &hf_pn_io_mrp_prio,
+ { "MRP_Prio", "pn_io.mrp_prio",
+ FT_UINT16, BASE_HEX, VALS(pn_io_mrp_prio_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_topchgt,
+ { "MRP_TOPchgT", "pn_io.mrp_topchgt",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "time base 10ms", HFILL }
+ },
+ { &hf_pn_io_mrp_topnrmax,
+ { "MRP_TOPNRmax", "pn_io.mrp_topnrmax",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "number of iterations", HFILL }
+ },
+ { &hf_pn_io_mrp_tstshortt,
+ { "MRP_TSTshortT", "pn_io.mrp_tstshortt",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "time base 1 ms", HFILL }
+ },
+ { &hf_pn_io_mrp_tstdefaultt,
+ { "MRP_TSTdefaultT", "pn_io.mrp_tstdefaultt",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "time base 1ms", HFILL }
+ },
+ { &hf_pn_io_mrp_tstnrmax,
+ { "MRP_TSTNRmax", "pn_io.mrp_tstnrmax",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "number of outstanding test indications causes ring failure", HFILL }
+ },
+ { &hf_pn_io_mrp_check,
+ { "MRP_Check", "pn_io.mrp_check",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_check_mrm,
+ { "MRP_Check.MediaRedundancyManager", "pn_io.mrp_check.mrm",
+ FT_UINT32, BASE_HEX, VALS(pn_io_mrp_mrm_on), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_check_mrpdomain,
+ { "MRP_Check.MRP_DomainUUID", "pn_io.mrp_check.domainUUID",
+ FT_UINT32, BASE_HEX, VALS(pn_io_mrp_checkUUID), 0x02,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_check_reserved_1,
+ { "MRP_Check.reserved_1", "pn_io.mrp_check_reserved_1",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFFFC,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_check_reserved_2,
+ { "MRP_Check.reserved_2", "pn_io.mrp_check_reserved_2",
+ FT_UINT32, BASE_HEX, NULL, 0xFF000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_rtmode,
+ { "MRP_RTMode", "pn_io.mrp_rtmode",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_rtmode_rtclass12,
+ { "RTClass1_2", "pn_io.mrp_rtmode.class1_2",
+ FT_UINT32, BASE_HEX, VALS(pn_io_mrp_rtmode_rtclass12_vals), 0x00000001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_rtmode_rtclass3,
+ { "RTClass1_3", "pn_io.mrp_rtmode.class3",
+ FT_UINT32, BASE_HEX, VALS(pn_io_mrp_rtmode_rtclass3_vals), 0x00000002,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_rtmode_reserved1,
+ { "Reserved_1", "pn_io.mrp_rtmode.reserved_1",
+ FT_UINT32, BASE_HEX, NULL, 0x00fffffc,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_rtmode_reserved2,
+ { "Reserved_2", "pn_io.mrp_rtmode.reserved_2",
+ FT_UINT32, BASE_HEX, NULL, 0xff000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_lnkdownt,
+ { "MRP_LNKdownT", "pn_io.mrp_lnkdownt",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "Link down Interval in ms", HFILL }
+ },
+ { &hf_pn_io_mrp_lnkupt,
+ { "MRP_LNKupT", "pn_io.mrp_lnkupt",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "Link up Interval in ms", HFILL }
+ },
+ { &hf_pn_io_mrp_lnknrmax,
+ { "MRP_LNKNRmax", "pn_io.mrp_lnknrmax",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "number of iterations", HFILL }
+ },
+ { &hf_pn_io_mrp_version,
+ { "MRP_Version", "pn_io.mrp_version",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_substitute_active_flag,
+ { "SubstituteActiveFlag", "pn_io.substitute_active_flag",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_length_data,
+ { "LengthData", "pn_io.length_data",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_ring_state,
+ { "MRP_RingState", "pn_io.mrp_ring_state",
+ FT_UINT16, BASE_HEX, VALS(pn_io_mrp_ring_state_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mrp_rt_state,
+ { "MRP_RTState", "pn_io.mrp_rt_state",
+ FT_UINT16, BASE_HEX, VALS(pn_io_mrp_rt_state_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_tag_function,
+ { "IM_Tag_Function", "pn_io.im_tag_function",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_tag_location,
+ { "IM_Tag_Location", "pn_io.im_tag_location",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_date,
+ { "IM_Date", "pn_io.im_date",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_descriptor,
+ { "IM_Descriptor", "pn_io.im_descriptor",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_fs_hello_mode,
+ { "FSHelloMode", "pn_io.fs_hello_mode",
+ FT_UINT32, BASE_HEX, VALS(pn_io_fs_hello_mode_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_fs_hello_interval,
+ { "FSHelloInterval", "pn_io.fs_hello_interval",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "ms before conveying a second DCP_Hello.req", HFILL }
+ },
+ { &hf_pn_io_fs_hello_retry,
+ { "FSHelloRetry", "pn_io.fs_hello_retry",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_fs_hello_delay,
+ { "FSHelloDelay", "pn_io.fs_hello_delay",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_fs_parameter_mode,
+ { "FSParameterMode", "pn_io.fs_parameter_mode",
+ FT_UINT32, BASE_HEX, VALS(pn_io_fs_parameter_mode_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_fs_parameter_uuid,
+ { "FSParameterUUID", "pn_io.fs_parameter_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_check_sync_mode,
+ { "CheckSyncMode", "pn_io.check_sync_mode",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_check_sync_mode_reserved,
+ { "Reserved", "pn_io.check_sync_mode.reserved",
+ FT_UINT16, BASE_HEX, NULL, 0xFFFC,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_check_sync_mode_sync_master,
+ { "SyncMaster", "pn_io.check_sync_mode.sync_master",
+ FT_UINT16, BASE_HEX, NULL, 0x0002,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_check_sync_mode_cable_delay,
+ { "CableDelay", "pn_io.check_sync_mode.cable_delay",
+ FT_UINT16, BASE_HEX, NULL, 0x0001,
+ NULL, HFILL }
+ },
+ /* PROFIsafe F-Parameter */
+ { &hf_pn_io_ps_f_prm_flag1,
+ { "F_Prm_Flag1", "pn_io.ps.f_prm_flag1",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag1_chck_seq,
+ { "F_Check_SeqNr", "pn_io.ps.f_prm_flag1.f_check_seqnr",
+ FT_UINT8, BASE_HEX, VALS(pn_io_f_check_seqnr), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag1_chck_ipar,
+ { "F_Check_iPar", "pn_io.ps.f_prm_flag1.f_check_ipar",
+ FT_UINT8, BASE_HEX, VALS(pn_io_f_check_ipar), 0x02,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag1_sil,
+ { "F_SIL", "pn_io.ps.f_prm_flag1.f_sil",
+ FT_UINT8, BASE_HEX, VALS(pn_io_f_sil), 0xc,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag1_crc_len,
+ { "F_CRC_Length", "pn_io.ps.f_prm_flag1.f_crc_len",
+ FT_UINT8, BASE_HEX, VALS(pn_io_f_crc_len), 0x30,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag1_crc_seed,
+ { "F_CRC_Seed", "pn_io.ps.f_prm_flag1.f_crc_seed",
+ FT_UINT8, BASE_HEX, VALS(pn_io_f_crc_seed), 0x40,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag1_reserved,
+ { "Reserved", "pn_io.ps.f_prm_flag1.reserved",
+ FT_UINT8, BASE_HEX, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag2,
+ { "F_Prm_Flag2", "pn_io.ps.f_prm_flag2",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag2_reserved,
+ { "Reserved", "pn_io.ps.f_prm_flag2.reserved",
+ FT_UINT8, BASE_HEX, NULL, 0x07,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag2_f_block_id,
+ { "F_Block_ID", "pn_io.ps.f_prm_flag2.f_block_id",
+ FT_UINT8, BASE_HEX, VALS(pn_io_f_block_id), 0x38,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_prm_flag2_f_par_version,
+ { "F_Par_Version", "pn_io.ps.f_prm_flag2.f_par_version",
+ FT_UINT8, BASE_HEX, VALS(pn_io_f_par_version), 0xC0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_wd_time,
+ { "F_WD_Time", "pn_io.ps.f_wd_time",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_ipar_crc,
+ { "F_iPar_CRC", "pn_io.ps.f_ipar_crc",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_par_crc,
+ { "F_Par_CRC", "pn_io.ps.f_par_crc",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_dest_adr,
+ { "F_Dest_Add", "pn_io.ps.f_dest_add",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_src_adr,
+ { "F_Source_Add", "pn_io.ps.f_source_add",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ /* profidrive parameter access */
+ { &hf_pn_io_profidrive_request_reference,
+ { "RequestReference", "pn_io.profidrive.parameter.request_reference",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_request_id,
+ { "RequestID", "pn_io.profidrive.parameter.request_id",
+ FT_UINT8, BASE_HEX, VALS(pn_io_profidrive_request_id_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_do_id,
+ { "DO", "pn_io.profidrive.parameter.do",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_no_of_parameters,
+ { "NoOfParameters", "pn_io.profidrive.parameter.no_of_parameters",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_attribute,
+ { "Attribute", "pn_io.profidrive.parameter.attribute",
+ FT_UINT8, BASE_HEX, VALS(pn_io_profidrive_attribute_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_no_of_elems,
+ { "NoOfElements", "pn_io.profidrive.parameter.no_of_elems",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_number,
+ { "Parameter", "pn_io.profidrive.parameter.number",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_subindex,
+ { "Index", "pn_io.profidrive.parameter.index",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_response_id,
+ { "ResponseID", "pn_io.profidrive.parameter.response_id",
+ FT_UINT8, BASE_HEX, VALS(pn_io_profidrive_response_id_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_format,
+ { "Format", "pn_io.profidrive.parameter.format",
+ FT_UINT8, BASE_HEX, VALS(pn_io_profidrive_format_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_value_error,
+ { "Error Number", "pn_io.profidrive.parameter.error_num",
+ FT_UINT16, BASE_HEX, VALS(pn_io_profidrive_parameter_resp_errors), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_value_error_sub,
+ { "Error Subindex", "pn_io.profidrive.parameter.error_subindex",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_no_of_values,
+ { "NoOfValues", "pn_io.profidrive.parameter.no_of_values",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_value_byte,
+ { "Value", "pn_io.profidrive.parameter.value_b",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_value_word,
+ { "Value", "pn_io.profidrive.parameter.value_w",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_value_dword,
+ { "Value", "pn_io.profidrive.parameter.value_dw",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_value_float,
+ { "Value", "pn_io.profidrive.parameter.value_float",
+ FT_FLOAT, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_profidrive_param_value_string,
+ { "Value", "pn_io.profidrive.parameter.value_str",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_alarm_info_reserved_8_15,
+ { "RSAlarmInfo.Reserved2", "pn_io.rs_alarm_info_reserved_8_15",
+ FT_UINT16, BASE_HEX, NULL, 0xFF00,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_alarm_info_reserved_0_7,
+ { "RSAlarmInfo.Reserved1", "pn_io.rs_alarm_info_reserved_0_7",
+ FT_UINT16, BASE_HEX, NULL, 0x00FF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_alarm_info,
+ { "RS Alarm Info", "pn_io.rs_alarm_info",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_event_info,
+ { "RS Event Info", "pn_io.rs_event_info",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_event_block,
+ { "RS Event Block", "pn_io.rs_event_block",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_adjust_block,
+ { "RS Adjust Block", "pn_io.rs_adjust_block",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_event_data_extension,
+ { "RS Event Data Extension", "pn_io.rs_event_data_extension",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_rs_event_info,
+ { "RSEventInfo.NumberOfEntries", "pn_io.number_of_rs_event_info",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_block_type,
+ { "RS Block Type", "pn_io.rs_block_type",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_rs_block_type), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_block_length,
+ { "RS Block Length", "pn_io.rs_block_length",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_specifier,
+ { "RS_Specifier", "pn_io.rs_specifier",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_specifier_sequence,
+ { "RS_Specifier.SequenceNumber", "pn_io.rs_specifier.sequence",
+ FT_UINT16, BASE_HEX, NULL, 0x07FF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_specifier_reserved,
+ { "RS_Specifier.Reserved", "pn_io.rs_specifier_reserved",
+ FT_UINT16, BASE_HEX, NULL, 0x3800,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_specifier_specifier,
+ { "RS_Specifier.Specifier", "pn_io.rs_specifier.specifier",
+ FT_UINT16, BASE_HEX, VALS(pn_io_rs_specifier_specifier), 0xC000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_time_stamp,
+ { "RS_TimeStamp", "pn_io.rs_time_stamp",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_time_stamp_status,
+ { "RS_TimeStamp.Status", "pn_io.rs_time_stamp.status",
+ FT_UINT16, BASE_HEX, VALS(pn_io_rs_time_stamp_status), 0x0003,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_time_stamp_value,
+ { "RS_TimeStamp.Value", "pn_io.rs_time_stamp.value",
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_minus_error,
+ { "RS_MinusError", "pn_io.rs_minus_error",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_plus_error,
+ { "RS_PlusError", "pn_io.rs_plus_error",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_extension_block_type,
+ { "RS_ExtensionBlockType", "pn_io.rs_extension_block_type",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_extension_block_length,
+ { "RS_ExtensionBlockLength", "pn_io.rs_extension_block_length",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_reason_code,
+ { "RS_ReasonCode", "pn_io.rs_reason_code",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_reason_code_reason,
+ { "RS_ReasonCode.Reason", "pn_io.rs_reason_code.reason",
+ FT_UINT32, BASE_HEX, VALS(pn_io_rs_reason_code_reason), 0x0000FFFF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_reason_code_detail,
+ { "RS_ReasonCode.Detail", "pn_io.rs_reason_code.detail",
+ FT_UINT32, BASE_HEX, VALS(pn_io_rs_reason_code_detail), 0xFFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_domain_identification,
+ { "RS_DomainIdentification", "pn_io.rs_domain_identification",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_master_identification,
+ { "RS_MasterIdentification", "pn_io.rs_master_identification",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_soe_digital_input_current_value,
+ { "SoE_DigitalInputCurrentValue", "pn_io.soe_digital_input_current_value",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_soe_digital_input_current_value_value,
+ { "SoE_DigitalInputCurrentValue.Value", "pn_io.soe_digital_input_current_value.value",
+ FT_UINT16, BASE_HEX, VALS(pn_io_soe_digital_input_current_value_value), 0x0001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_soe_digital_input_current_value_reserved,
+ { "SoE_DigitalInputCurrentValue.Reserved", "pn_io.soe_digital_input_current_value.reserved",
+ FT_UINT16, BASE_HEX, NULL, 0xFFFE,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_device_identification,
+ { "AM_DeviceIdentification", "pn_io.am_device_identification",
+ FT_UINT64, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_device_identification_device_sub_id,
+ { "AM_DeviceIdentification.DeviceSubID", "pn_io.am_device_identification.device_sub_id",
+ FT_UINT64, BASE_HEX, NULL, 0x000000000000FFFF,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_device_identification_device_id,
+ { "AM_DeviceIdentification.DeviceID", "pn_io.am_device_identification.device_id",
+ FT_UINT64, BASE_HEX, NULL, 0x00000000FFFF0000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_device_identification_vendor_id,
+ { "AM_DeviceIdentification.VendorID", "pn_io.am_device_identification.vendor_id",
+ FT_UINT64, BASE_HEX, NULL, 0x0000FFFF00000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_device_identification_organization,
+ { "AM_DeviceIdentification.Organization", "pn_io.am_device_identification.organization",
+ FT_UINT64, BASE_HEX, NULL, 0xFFFF000000000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_adjust_info,
+ { "RS Adjust Info", "pn_io.rs_adjust_info",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_soe_max_scan_delay,
+ { "SoE_MaxScanDelay", "pn_io.soe_max_scan_delay",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_soe_adjust_specifier,
+ { "SoE_AdjustSpecifier", "pn_io.soe_adjust_specifier",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_soe_adjust_specifier_reserved,
+ { "SoE_AdjustSpecifier.Reserved", "pn_io.soe_adjust_specifier.reserved",
+ FT_UINT8, BASE_HEX, NULL, 0x3F,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_soe_adjust_specifier_incident,
+ { "SoE_AdjustSpecifier.Incident", "pn_io.soe_adjust_specifier.incident",
+ FT_UINT8, BASE_HEX, VALS(pn_io_soe_adjust_specifier_incident), 0xC0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_properties,
+ { "RSProperties", "pn_io.rs_properties",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_properties_alarm_transport,
+ { "RSProperties", "pn_io.rs_properties",
+ FT_UINT32, BASE_HEX, VALS(pn_io_rs_properties_alarm_transport), 0x00000001,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_properties_reserved1,
+ { "RSProperties.Reserved1", "pn_io.rs_properties.reserved1",
+ FT_UINT32, BASE_HEX, NULL, 0x00FFFFFE,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_rs_properties_reserved2,
+ { "RSProperties.Reserved2", "pn_io.rs_properties.reserved2",
+ FT_UINT32, BASE_HEX, NULL, 0xFF000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_asset_management_info,
+ { "Asset Management Info", "pn_io.asset_management_info",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_number_of_asset_management_info,
+ { "AssetManagementInfo.NumberOfEntries", "pn_io.number_of_asset_management_info",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_im_uniqueidentifier,
+ { "IM_UniqueIdentifier", "pn_io.IM_UniqueIdentifier",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_structure,
+ { "AM_Location.Structure", "pn_io.am_location.structure",
+ FT_UINT8, BASE_HEX, VALS(pn_io_am_location_structure_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location,
+ { "AM_Location", "pn_io.am_location",
+ FT_BYTES, BASE_NONE, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_0,
+ { "AM_Location Level 0", "pn_io.am_location.level_0",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_1,
+ { "AM_Location Level 1", "pn_io.am_location.level_1",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_2,
+ { "AM_Location Level 2", "pn_io.am_location.level_2",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_3,
+ { "AM_Location Level 3", "pn_io.am_location.level_3",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_4,
+ { "AM_Location Level 4", "pn_io.am_location.level_4",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_5,
+ { "AM_Location Level 5", "pn_io.am_location.level_5",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_6,
+ { "AM_Location Level 6", "pn_io.am_location.level_6",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_7,
+ { "AM_Location Level 7", "pn_io.am_location.level_7",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_8,
+ { "AM_Location Level 8", "pn_io.am_location.level_8",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_9,
+ { "AM_Location Level 9", "pn_io.am_location.level_9",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_10,
+ { "AM_Location Level 10", "pn_io.am_location.level_10",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_level_11,
+ { "AM_Location Level 11", "pn_io.am_location.level_11",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_am_location_level_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_reserved1,
+ { "AM_Location.Reserved1", "pn_io.am_location.reserved1",
+ FT_UINT8, BASE_HEX, VALS(pn_io_am_location_reserved_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_reserved2,
+ { "AM_Location.Reserved2", "pn_io.am_location.reserved2",
+ FT_UINT16, BASE_HEX, VALS(pn_io_am_location_reserved_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_reserved3,
+ { "AM_Location.Reserved3", "pn_io.am_location.reserved3",
+ FT_UINT16, BASE_HEX, VALS(pn_io_am_location_reserved_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_reserved4,
+ { "AM_Location.Reserved4", "pn_io.am_location.reserved4",
+ FT_UINT16, BASE_HEX, VALS(pn_io_am_location_reserved_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_beginslotnum,
+ { "AM_Location.BeginSlotNumber", "pn_io.slot_nr",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_beginsubslotnum,
+ { "AM_Location.BeginSubSlotNumber", "pn_io.subslot_nr",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_endslotnum,
+ { "AM_Location.EndSlotNumber", "pn_io.slot_nr",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_location_endsubslotnum,
+ { "AM_Location.EndSubSlotNumber", "pn_io.subslot_nr",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_software_revision,
+ { "AM Software Revision", "pn_io.am_software_revision",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_hardware_revision,
+ { "AM Hardware Revision", "pn_io.am_hardware_revision",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_type_identification,
+ { "AM Type Identification", "pn_io.am_type_identification",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_am_reserved,
+ { "AM Reserved", "pn_io.am_reserved",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_mau_type_extension,
+ { "MAUTypeExtension", "pn_io.mau_type_extension",
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_mau_type_extension), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_pe_operational_mode,
+ { "PE_OperationalMode", "pn_io.pe_operationalmode",
+ FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(pn_io_pe_operational_mode), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_snmp_control,
+ { "SNMPControl", "pn_io.snmp_control",
+ FT_UINT16, BASE_HEX, VALS(pn_io_snmp_control), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_snmp_community_name_length,
+ { "CommunityNameLength", "pn_io.snmp_community_name_length",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_snmp_community_name,
+ { "CommunityName", "pn_io.snmp_community_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_snmp_read_community_name,
+ { "SNMP read only community name", "pn_io.snmp_read_community_name",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_snmp_write_community_name,
+ { "SNMP read write community name", "pn_io.snmp_write_community_name",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ };
+
+ static gint *ett[] = {
+ &ett_pn_io,
+ &ett_pn_io_block,
+ &ett_pn_io_block_header,
+ &ett_pn_io_rtc,
+ &ett_pn_io_rta,
+ &ett_pn_io_pdu_type,
+ &ett_pn_io_add_flags,
+ &ett_pn_io_control_command,
+ &ett_pn_io_ioxs,
+ &ett_pn_io_api,
+ &ett_pn_io_data_description,
+ &ett_pn_io_module,
+ &ett_pn_io_submodule,
+ &ett_pn_io_io_data_object,
+ &ett_pn_io_io_cs,
+ &ett_pn_io_ar_properties,
+ &ett_pn_io_iocr_properties,
+ &ett_pn_io_submodule_properties,
+ &ett_pn_io_alarmcr_properties,
+ &ett_pn_io_submodule_state,
+ &ett_pn_io_channel_properties,
+ &ett_pn_io_slot,
+ &ett_pn_io_subslot,
+ &ett_pn_io_maintenance_status,
+ &ett_pn_io_data_status,
+ &ett_pn_io_iocr,
+ &ett_pn_io_mrp_rtmode,
+ &ett_pn_io_control_block_properties,
+ &ett_pn_io_check_sync_mode,
+ &ett_pn_io_ir_frame_data,
+ &ett_pn_FrameDataProperties,
+ &ett_pn_io_ar_info,
+ &ett_pn_io_ar_data,
+ &ett_pn_io_ir_begin_end_port,
+ &ett_pn_io_ir_tx_phase,
+ &ett_pn_io_ir_rx_phase,
+ &ett_pn_io_subframe_data,
+ &ett_pn_io_SFIOCRProperties,
+ &ett_pn_io_frame_defails,
+ &ett_pn_io_profisafe_f_parameter,
+ &ett_pn_io_profisafe_f_parameter_prm_flag1,
+ &ett_pn_io_profisafe_f_parameter_prm_flag2,
+ &ett_pn_io_profidrive_parameter_request,
+ &ett_pn_io_profidrive_parameter_response,
+ &ett_pn_io_profidrive_parameter_address,
+ &ett_pn_io_profidrive_parameter_value,
+ &ett_pn_io_GroupProperties,
+ &ett_pn_io_rs_alarm_info,
+ &ett_pn_io_rs_event_info,
+ &ett_pn_io_rs_event_block,
+ &ett_pn_io_rs_adjust_block,
+ &ett_pn_io_rs_event_data_extension,
+ &ett_pn_io_rs_specifier,
+ &ett_pn_io_rs_time_stamp,
+ &ett_pn_io_am_device_identification,
+ &ett_pn_io_rs_reason_code,
+ &ett_pn_io_soe_digital_input_current_value,
+ &ett_pn_io_rs_adjust_info,
+ &ett_pn_io_soe_adjust_specifier,
+ &ett_pn_io_asset_management_info,
+ &ett_pn_io_asset_management_block,
+ &ett_pn_io_am_location,
+ &ett_pn_io_sr_properties,
+ &ett_pn_io_line_delay,
+ &ett_pn_io_counter_status,
+ &ett_pn_io_dcp_boundary,
+ &ett_pn_io_peer_to_peer_boundary,
+ &ett_pn_io_mau_type_extension,
+ &ett_pn_io_pe_operational_mode,
+ &ett_pn_io_neighbor,
+ &ett_pn_io_tsn_domain_vid_config,
+ &ett_pn_io_tsn_domain_port_config,
+ &ett_pn_io_tsn_domain_queue_config,
+ &ett_pn_io_tsn_domain_port_ingress_rate_limiter,
+ &ett_pn_io_tsn_domain_queue_rate_limiter,
+ &ett_pn_io_time_sync_properties,
+ &ett_pn_io_tsn_domain_port_id,
+ &ett_pn_io_snmp_command_name
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_pn_io_block_version, { "pn_io.block_version.not_implemented", PI_UNDECODED, PI_WARN, "Block version not implemented yet!", EXPFILL }},
+ { &ei_pn_io_ar_info_not_found, { "pn_io.ar_info_not_found", PI_UNDECODED, PI_NOTE, "IODWriteReq: AR information not found!", EXPFILL }},
+ { &ei_pn_io_block_length, { "pn_io.block_length.invalid", PI_UNDECODED, PI_WARN, "Block length invalid!", EXPFILL }},
+ { &ei_pn_io_unsupported, { "pn_io.profidrive.parameter.format.invalid", PI_UNDECODED, PI_WARN, "Unknown Formatvalue", EXPFILL }},
+ { &ei_pn_io_mrp_instances, { "pn_io.mrp_Number_MrpInstances.invalid", PI_UNDECODED, PI_WARN, "Number of MrpInstances invalid", EXPFILL }},
+ { &ei_pn_io_frame_id, { "pn_io.frame_id.changed", PI_UNDECODED, PI_WARN, "FrameID changed", EXPFILL }},
+ { &ei_pn_io_iocr_type, { "pn_io.iocr_type.unknown", PI_UNDECODED, PI_WARN, "IOCRType undecoded!", EXPFILL }},
+ { &ei_pn_io_localalarmref, { "pn_io.localalarmref.changed", PI_UNDECODED, PI_WARN, "AlarmCRBlockReq: local alarm ref changed", EXPFILL }},
+ { &ei_pn_io_nr_of_tx_port_groups, { "pn_io.nr_of_tx_port_groups.not_allowed", PI_PROTOCOL, PI_WARN, "Not allowed value of NumberOfTxPortGroups", EXPFILL }},
+ { &ei_pn_io_max_recursion_depth_reached, { "pn_io.max_recursion_depth_reached", PI_PROTOCOL, PI_WARN, "Maximum allowed recursion depth reached - stopping dissection", EXPFILL }}
+ };
+
+ module_t *pnio_module;
+ expert_module_t* expert_pn_io;
+
+ proto_pn_io = proto_register_protocol ("PROFINET IO", "PNIO", "pn_io");
+
+ /* Register by name */
+ register_dissector("pnio", dissect_PNIO_heur, proto_pn_io);
+
+ /* Created to remove Decode As confusion */
+ proto_pn_io_device = proto_register_protocol_in_name_only("PROFINET IO (Device)", "PNIO (Device Interface)", "pn_io_device", proto_pn_io, FT_PROTOCOL);
+ proto_pn_io_controller = proto_register_protocol_in_name_only("PROFINET IO (Controller)", "PNIO (Controller Interface)", "pn_io_controller", proto_pn_io, FT_PROTOCOL);
+ proto_pn_io_supervisor = proto_register_protocol_in_name_only("PROFINET IO (Supervisor)", "PNIO (Supervisor Interface)", "pn_io_supervisor", proto_pn_io, FT_PROTOCOL);
+ proto_pn_io_parameterserver = proto_register_protocol_in_name_only("PROFINET IO (Parameter Server)", "PNIO (Parameter Server Interface)", "pn_io_parameterserver", proto_pn_io, FT_PROTOCOL);
+ proto_pn_io_implicitar = proto_register_protocol_in_name_only("PROFINET IO (Implicit Ar)", "PNIO (Implicit Ar)", "pn_io_implicitar", proto_pn_io, FT_PROTOCOL);
+ proto_pn_io_apdu_status = proto_register_protocol_in_name_only("PROFINET IO (Apdu Status)", "PNIO (Apdu Status)", "pn_io_apdu_status", proto_pn_io, FT_PROTOCOL);
+ proto_pn_io_time_aware_status = proto_register_protocol_in_name_only("PROFINET IO (Time Aware Status)", "PNIO (Time Aware Status)", "pn_io_time_aware_status", proto_pn_io, FT_PROTOCOL);
+
+ proto_register_field_array (proto_pn_io, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ expert_pn_io = expert_register_protocol(proto_pn_io);
+ expert_register_field_array(expert_pn_io, ei, array_length(ei));
+
+ /* Register preferences */
+ pnio_module = prefs_register_protocol(proto_pn_io, NULL);
+ prefs_register_bool_preference(pnio_module, "pnio_ps_selection",
+ "Enable detailed PROFIsafe dissection",
+ "Whether the PNIO dissector is allowed to use detailed PROFIsafe dissection of cyclic data frames",
+ &pnio_ps_selection);
+ prefs_register_directory_preference(pnio_module, "pnio_ps_networkpath",
+ "Folder containing GSD files", /* Title */
+ "Place GSD files in this folder.", /* Descreption */
+ &pnio_ps_networkpath); /* Variable in which to save the GSD file folder path */
+
+ /* subdissector code */
+ register_dissector("pn_io", dissect_PNIO_heur, proto_pn_io);
+ heur_pn_subdissector_list = register_heur_dissector_list("pn_io", proto_pn_io);
+
+ /* Initialise RTC1 dissection */
+ init_pn_io_rtc1(proto_pn_io);
+
+ /* Initialise RSI dissection */
+ init_pn_rsi(proto_pn_io);
+
+ /* Init functions of PNIO protocol */
+ register_init_routine(pnio_setup);
+
+ /* Cleanup functions of PNIO protocol */
+ register_cleanup_routine(pnio_cleanup);
+
+ register_conversation_filter("pn_io", "PN-IO AR", pn_io_ar_conv_valid, pn_io_ar_conv_filter, NULL);
+ register_conversation_filter("pn_io", "PN-IO AR (with data)", pn_io_ar_conv_valid, pn_io_ar_conv_data_filter, NULL);
+}
+
+
+void
+proto_reg_handoff_pn_io (void)
+{
+ /* Register the protocols as dcerpc */
+ dcerpc_init_uuid (proto_pn_io_device, ett_pn_io, &uuid_pn_io_device, ver_pn_io_device, pn_io_dissectors, hf_pn_io_opnum);
+ dcerpc_init_uuid (proto_pn_io_controller, ett_pn_io, &uuid_pn_io_controller, ver_pn_io_controller, pn_io_dissectors, hf_pn_io_opnum);
+ dcerpc_init_uuid (proto_pn_io_supervisor, ett_pn_io, &uuid_pn_io_supervisor, ver_pn_io_supervisor, pn_io_dissectors, hf_pn_io_opnum);
+ dcerpc_init_uuid (proto_pn_io_parameterserver, ett_pn_io, &uuid_pn_io_parameterserver, ver_pn_io_parameterserver, pn_io_dissectors, hf_pn_io_opnum);
+ dcerpc_init_uuid (proto_pn_io_implicitar, ett_pn_io, &uuid_pn_io_implicitar, ver_pn_io_implicitar, pn_io_dissectors, hf_pn_io_opnum);
+
+ heur_dissector_add("pn_rt", dissect_PNIO_heur, "PROFINET IO", "pn_io_pn_rt", proto_pn_io, HEURISTIC_ENABLE);
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-dcom-cba-acco.c b/plugins/epan/profinet/packet-dcom-cba-acco.c
new file mode 100644
index 0000000..6b3788a
--- /dev/null
+++ b/plugins/epan/profinet/packet-dcom-cba-acco.c
@@ -0,0 +1,5158 @@
+/* packet-dcom-cba-acco.c
+ * Routines for DCOM CBA
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <epan/addr_resolv.h>
+#include <epan/conversation_filter.h>
+#include <epan/proto_data.h>
+#include <epan/dissectors/packet-dcerpc.h>
+#include <epan/dissectors/packet-dcom.h>
+#include "packet-dcom-cba-acco.h"
+#include <epan/ws_printf.h>
+
+void proto_register_dcom_cba_acco(void);
+void proto_reg_handoff_dcom_cba_acco(void);
+
+static int hf_cba_acco_opnum = -1;
+
+static int hf_cba_acco_ping_factor = -1;
+
+static int hf_cba_acco_count = -1;
+
+static int hf_cba_acco_item = -1;
+static int hf_cba_acco_data = -1;
+static int hf_cba_acco_qc = -1;
+static int hf_cba_acco_time_stamp = -1;
+
+static int hf_cba_acco_conn_qos_type = -1;
+static int hf_cba_acco_conn_qos_value = -1;
+static int hf_cba_acco_conn_state = -1;
+static int hf_cba_acco_conn_cons_id = -1;
+static int hf_cba_acco_conn_version = -1;
+static int hf_cba_acco_conn_prov_id = -1;
+static int hf_cba_acco_conn_provider = -1;
+static int hf_cba_acco_conn_consumer = -1;
+static int hf_cba_acco_conn_provider_item = -1;
+static int hf_cba_acco_conn_consumer_item = -1;
+static int hf_cba_acco_conn_substitute = -1;
+static int hf_cba_acco_conn_epsilon = -1;
+static int hf_cba_acco_conn_persist = -1;
+
+static int hf_cba_acco_cb_length = -1;
+static int hf_cba_acco_cb_conn_data = -1;
+static int hf_cba_acco_cb_version = -1;
+static int hf_cba_acco_cb_flags = -1;
+static int hf_cba_acco_cb_count = -1;
+static int hf_cba_acco_cb_item = -1;
+static int hf_cba_acco_cb_item_hole = -1;
+static int hf_cba_acco_cb_item_length = -1;
+static int hf_cba_acco_cb_item_data = -1;
+
+static int hf_cba_connect_in = -1;
+static int hf_cba_disconnect_in = -1;
+static int hf_cba_connectcr_in = -1;
+static int hf_cba_disconnectcr_in = -1;
+static int hf_cba_disconnectme_in = -1;
+static int hf_cba_data_first_in = -1;
+static int hf_cba_data_last_in = -1;
+
+/* static int hf_cba_acco_server_pICBAAccoCallback = -1; */
+
+static int hf_cba_acco_server_first_connect = -1;
+
+static int hf_cba_acco_serversrt_prov_mac = -1;
+static int hf_cba_acco_serversrt_cons_mac = -1;
+
+static int hf_cba_acco_serversrt_cr_id = -1;
+static int hf_cba_acco_serversrt_cr_length = -1;
+static int hf_cba_acco_serversrt_cr_flags = -1;
+static int hf_cba_acco_serversrt_cr_flags_timestamped = -1;
+static int hf_cba_acco_serversrt_cr_flags_reconfigure = -1;
+static int hf_cba_acco_serversrt_record_length = -1;
+/* static int hf_cba_acco_serversrt_action = -1; */
+static int hf_cba_acco_serversrt_last_connect = -1;
+
+static int hf_cba_getprovconnout = -1;
+
+static int hf_cba_type_desc_len = -1;
+
+static int hf_cba_connectincr = -1;
+static int hf_cba_connectoutcr = -1;
+static int hf_cba_connectin = -1;
+static int hf_cba_connectout = -1;
+static int hf_cba_getconnectionout = -1;
+static int hf_cba_readitemout = -1;
+static int hf_cba_writeitemin = -1;
+static int hf_cba_addconnectionin = -1;
+static int hf_cba_addconnectionout = -1;
+static int hf_cba_getidout = -1;
+
+static int hf_cba_getconsconnout = -1;
+static int hf_cba_diagconsconnout = -1;
+static int hf_cba_acco_conn_error_state = -1;
+
+static int hf_cba_acco_info_max = -1;
+static int hf_cba_acco_info_curr = -1;
+
+static int hf_cba_acco_cdb_cookie = -1;
+
+static int hf_cba_acco_rtauto = -1;
+
+static int hf_cba_acco_prov_crid = -1;
+
+static int hf_cba_acco_diag_req = -1;
+static int hf_cba_acco_diag_in_length = -1;
+static int hf_cba_acco_diag_out_length = -1;
+static int hf_cba_acco_diag_data = -1;
+static int hf_cba_acco_dcom_call = -1;
+static int hf_cba_acco_srt_call = -1;
+
+gint ett_cba_connectincr = -1;
+gint ett_cba_connectoutcr = -1;
+gint ett_cba_connectin = -1;
+gint ett_cba_connectout = -1;
+gint ett_cba_getprovconnout = -1;
+gint ett_cba_addconnectionin = -1;
+gint ett_cba_addconnectionout = -1;
+gint ett_cba_getidout = -1;
+gint ett_cba_getconnectionout = -1;
+gint ett_cba_readitemout = -1;
+gint ett_cba_writeitemin = -1;
+gint ett_cba_acco_serversrt_cr_flags = -1;
+gint ett_cba_frame_info = -1;
+gint ett_cba_conn_info = -1;
+
+static expert_field ei_cba_acco_pdev_find = EI_INIT;
+static expert_field ei_cba_acco_prov_crid = EI_INIT;
+static expert_field ei_cba_acco_conn_consumer = EI_INIT;
+static expert_field ei_cba_acco_ldev_unknown = EI_INIT;
+static expert_field ei_cba_acco_no_request_info = EI_INIT;
+static expert_field ei_cba_acco_ipid_unknown = EI_INIT;
+static expert_field ei_cba_acco_qc = EI_INIT;
+static expert_field ei_cba_acco_pdev_find_unknown_interface = EI_INIT;
+static expert_field ei_cba_acco_disconnect = EI_INIT;
+static expert_field ei_cba_acco_connect = EI_INIT;
+
+static int proto_ICBAAccoMgt = -1;
+static gint ett_ICBAAccoMgt = -1;
+static e_guid_t uuid_ICBAAccoMgt = { 0xcba00041, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAAccoMgt = 0;
+
+static int proto_ICBAAccoMgt2 = -1;
+static e_guid_t uuid_ICBAAccoMgt2 = { 0xcba00046, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAAccoMgt2 = 0;
+
+static int proto_ICBAAccoCallback = -1;
+static gint ett_ICBAAccoCallback = -1;
+static gint ett_ICBAAccoCallback_Buffer = -1;
+static gint ett_ICBAAccoCallback_Item = -1;
+static e_guid_t uuid_ICBAAccoCallback = { 0xcba00042, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAAccoCallback = 0;
+
+static int proto_ICBAAccoCallback2 = -1;
+static e_guid_t uuid_ICBAAccoCallback2 = { 0xcba00047, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAAccoCallback2 = 0;
+
+static int proto_ICBAAccoServer = -1;
+static gint ett_ICBAAccoServer = -1;
+static e_guid_t uuid_ICBAAccoServer = { 0xcba00043, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAAccoServer = 0;
+
+static int proto_ICBAAccoServer2 = -1;
+static e_guid_t uuid_ICBAAccoServer2 = { 0xcba00048, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAAccoServer2 = 0;
+
+static int proto_ICBAAccoServerSRT = -1;
+static gint ett_ICBAAccoServerSRT = -1;
+static e_guid_t uuid_ICBAAccoServerSRT = { 0xcba00045, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAAccoServerSRT = 0;
+
+static int proto_ICBAAccoSync = -1;
+static gint ett_ICBAAccoSync = -1;
+static e_guid_t uuid_ICBAAccoSync = { 0xcba00044, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAAccoSync = 0;
+
+
+
+static const value_string cba_acco_qc_vals[] = {
+ { 0x1c, "BadOutOfService" },
+ { 0x44, "UncertainLastUsableValue" },
+ { 0x48, "UncertainSubstituteSet" },
+ { 0x50, "UncertainSensorNotAccurate" },
+ { 0x80, "GoodNonCascOk" },
+ { 0, NULL }
+};
+
+
+static const value_string cba_qos_type_vals[] = {
+ { 0x00, "Acyclic" },
+ { 0x01, "Acyclic seconds" }, /* obsolete */
+ { 0x02, "Acyclic status" },
+ { 0x03, "Acyclic HMI" },
+ { 0x20, "Constant" },
+ { 0x30, "Cyclic Real-Time" },
+ { 0, NULL }
+};
+
+
+static const value_string cba_persist_vals[] = {
+ { 0x00, "Volatile" },
+ { 0x01, "PendingPersistent" },
+ { 0x02, "Persistent" },
+ { 0, NULL }
+};
+
+
+static const value_string cba_acco_conn_state_vals[] = {
+ { 0x00, "Passive" },
+ { 0x01, "Active" },
+ { 0, NULL }
+};
+
+#if 0
+static const value_string cba_acco_serversrt_action_vals[] = {
+ { 0x00, "Activate" },
+ { 0x01, "Deactivate" },
+ { 0x02, "Remove" },
+ { 0, NULL }
+};
+#endif
+
+static const value_string cba_acco_serversrt_last_connect_vals[] = {
+ { 0x00, "CR not complete" },
+ { 0x01, "CR complete" },
+ { 0, NULL }
+};
+
+static const value_string cba_acco_diag_req_vals[] = {
+ { 0x0000, "Function directory" },
+ { 0x1000, "DevCat statistic" },
+ { 0x2000, "Reset statistic" },
+ { 0x3000, "Consumer Comm. Events" },
+ { 0x4000, "Provider Comm. Events" },
+ { 0, NULL }
+};
+
+static const true_false_string cba_acco_call_flags = {
+ "Consumer calls Provider (TRUE)",
+ "Provider calls Consumer (FALSE)"
+};
+
+static const value_string cba_qos_type_short_vals[] = {
+ { 0x00, "DCOM" },
+ { 0x01, "DCOM(sec)" }, /* obsolete */
+ { 0x02, "Status" },
+ { 0x03, "HMI" },
+ { 0x20, "Const" },
+ { 0x30, "SRT" },
+ { 0, NULL }
+};
+
+
+typedef struct cba_frame_s {
+ cba_ldev_t *consparent;
+ cba_ldev_t *provparent;
+ GList *conns;
+ guint packet_connect;
+ guint packet_disconnect;
+ guint packet_disconnectme;
+ guint packet_first;
+ guint packet_last;
+
+ guint16 length;
+ guint8 consmac[6];
+ guint16 conscrid;
+ guint32 provcrid;
+ guint32 conncrret;
+ guint16 qostype;
+ guint16 qosvalue;
+ guint16 offset;
+} cba_frame_t;
+
+typedef struct cba_connection_s {
+ cba_ldev_t *consparentacco;
+ cba_ldev_t *provparentacco;
+ cba_frame_t *parentframe;
+ guint packet_connect;
+ guint packet_disconnect;
+ guint packet_disconnectme;
+ guint packet_first;
+ guint packet_last;
+
+ guint16 length;
+ guint32 consid;
+ guint32 provid;
+ const gchar *provitem;
+ guint32 connret;
+ guint16 typedesclen;
+ guint16 *typedesc;
+ guint16 qostype;
+ guint16 qosvalue;
+ guint16 frame_offset;
+} cba_connection_t;
+
+
+typedef struct server_frame_call_s {
+ guint frame_count;
+ cba_frame_t **frames;
+} server_frame_call_t;
+
+
+typedef struct server_connect_call_s {
+ guint conn_count;
+ cba_frame_t *frame;
+ cba_connection_t **conns;
+} server_connect_call_t;
+
+typedef struct server_disconnectme_call_s {
+ cba_ldev_t *cons;
+ cba_ldev_t *prov;
+} server_disconnectme_call_t;
+
+
+GList *cba_pdevs;
+
+/* as we are a plugin, we cannot get this from libwireshark! */
+const true_false_string acco_flags_set_truth = { "Set", "Not set" };
+
+static gboolean
+cba_filter_valid(packet_info *pinfo, void *user_data _U_)
+{
+ void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0);
+
+ return ((profinet_type != NULL) && (GPOINTER_TO_UINT(profinet_type) < 10));
+}
+
+static gchar*
+cba_build_filter(packet_info *pinfo, void *user_data _U_)
+{
+ gboolean is_tcp = proto_is_frame_protocol(pinfo->layers, "tcp");
+ void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0);
+
+ if ((pinfo->net_src.type == AT_IPv4) && (pinfo->net_dst.type == AT_IPv4) && is_tcp) {
+ /* IPv4 */
+ switch(GPOINTER_TO_UINT(profinet_type)) {
+ case 1:
+ return ws_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 0)",
+ address_to_str(pinfo->pool, &pinfo->net_dst),
+ address_to_str(pinfo->pool, &pinfo->net_src),
+ address_to_str(pinfo->pool, &pinfo->net_src),
+ address_to_str(pinfo->pool, &pinfo->net_dst));
+ case 2:
+ return ws_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 0)",
+ address_to_str(pinfo->pool, &pinfo->net_src),
+ address_to_str(pinfo->pool, &pinfo->net_dst),
+ address_to_str(pinfo->pool, &pinfo->net_dst),
+ address_to_str(pinfo->pool, &pinfo->net_src));
+ case 3:
+ return ws_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.srt == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.srt == 0)",
+ address_to_str(pinfo->pool, &pinfo->net_dst),
+ address_to_str(pinfo->pool, &pinfo->net_src),
+ address_to_str(pinfo->pool, &pinfo->net_src),
+ address_to_str(pinfo->pool, &pinfo->net_dst));
+ case 4:
+ return ws_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.srt == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.srt == 0)",
+ address_to_str(pinfo->pool, &pinfo->net_src),
+ address_to_str(pinfo->pool, &pinfo->net_dst),
+ address_to_str(pinfo->pool, &pinfo->net_dst),
+ address_to_str(pinfo->pool, &pinfo->net_src));
+ default:
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+#if 0
+static void
+cba_connection_dump(cba_connection_t *conn, const char *role)
+{
+ if (conn->qostype != 0x30) {
+ ws_debug_printf(" %s#%5u: CID:0x%8x PID:0x%8x PItem:\"%s\" Type:%s QoS:%s/%u Ret:%s Data#%5u-#%5u",
+ role,
+ conn->packet_connect,
+ conn->consid, conn->provid, conn->provitem,
+ conn->typedesclen != 0 ? val_to_str(conn->typedesc[0], dcom_variant_type_vals, "Unknown (0x%08x)") : "-",
+ val_to_str(conn->qostype, cba_qos_type_short_vals, "0x%x"), conn->qosvalue,
+ conn->connret==0xffffffff ? "[pending]" : val_to_str(conn->connret, dcom_hresult_vals, "Unknown (0x%08x)"),
+ conn->packet_first, conn->packet_last);
+ } else {
+ ws_debug_printf(" %s#%5u: CID:0x%8x PID:0x%8x PItem:\"%s\" Type:%s QoS:%s/%u Ret:%s Off:%u",
+ role,
+ conn->packet_connect,
+ conn->consid, conn->provid, conn->provitem,
+ conn->typedesclen != 0 ? val_to_str(conn->typedesc[0], dcom_variant_type_vals, "Unknown (0x%08x)") : "-",
+ val_to_str(conn->qostype, cba_qos_type_short_vals, "0x%x"), conn->qosvalue,
+ conn->connret==0xffffffff ? "[pending]" : val_to_str(conn->connret, dcom_hresult_vals, "Unknown (0x%08x)"),
+ conn->frame_offset);
+ }
+}
+
+
+static void
+cba_object_dump(void)
+{
+ GList *pdevs;
+ GList *ldevs;
+ GList *frames;
+ GList *conns;
+ cba_pdev_t *pdev;
+ cba_ldev_t *ldev;
+ cba_frame_t *frame;
+ address addr;
+
+
+ for(pdevs = cba_pdevs; pdevs != NULL; pdevs = g_list_next(pdevs)) {
+ pdev = pdevs->data;
+ set_address(&addr, AT_IPv4, 4, pdev->ip);
+ ws_debug_printf("PDev #%5u: %s IFs:%u", pdev->first_packet, address_to_str(pinfo->pool, &addr),
+ pdev->object ? g_list_length(pdev->object->interfaces) : 0);
+
+ for(ldevs = pdev->ldevs; ldevs != NULL; ldevs = g_list_next(ldevs)) {
+ ldev = ldevs->data;
+ ws_debug_printf(" LDev#%5u: \"%s\" LDevIFs:%u AccoIFs:%u", ldev->first_packet, ldev->name,
+ ldev->ldev_object ? g_list_length(ldev->ldev_object->interfaces) : 0,
+ ldev->acco_object ? g_list_length(ldev->acco_object->interfaces) : 0);
+ for(frames = ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = frames->data;
+ ws_debug_printf(" ConsFrame#%5u: CCRID:0x%x PCRID:0x%x Len:%u Ret:%s Data#%5u-#%5u",
+ frame->packet_connect, frame->conscrid, frame->provcrid, frame->length,
+ frame->conncrret==0xffffffff ? "[pending]" : val_to_str(frame->conncrret, dcom_hresult_vals, "Unknown (0x%08x)"),
+ frame->packet_first, frame->packet_last);
+ for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
+ cba_connection_dump(conns->data, "ConsConn");
+ }
+ }
+ for(frames = ldev->provframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = frames->data;
+ ws_debug_printf(" ProvFrame#%5u: CCRID:0x%x PCRID:0x%x Len:%u Ret:%s Data#%5u-#%5u",
+ frame->packet_connect, frame->conscrid, frame->provcrid, frame->length,
+ frame->conncrret==0xffffffff ? "[pending]" : val_to_str(frame->conncrret, dcom_hresult_vals, "Unknown (0x%08x)"),
+ frame->packet_first, frame->packet_last);
+ for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
+ cba_connection_dump(conns->data, "ProvConn");
+ }
+ }
+ for(conns = ldev->consconns; conns != NULL; conns = g_list_next(conns)) {
+ cba_connection_dump(conns->data, "ConsConn");
+ }
+ for(conns = ldev->provconns; conns != NULL; conns = g_list_next(conns)) {
+ cba_connection_dump(conns->data, "ProvConn");
+ }
+ }
+ }
+}
+#endif
+
+
+cba_pdev_t *
+cba_pdev_find(packet_info *pinfo, const address *addr, e_guid_t *ipid)
+{
+ cba_pdev_t *pdev;
+ dcom_interface_t *interf;
+
+
+ interf = dcom_interface_find(pinfo, addr, ipid);
+ if (interf != NULL) {
+ pdev = (cba_pdev_t *)interf->parent->private_data;
+ if (pdev == NULL) {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_pdev_find, "pdev_find: no pdev for IP:%s IPID:%s",
+ address_to_str(pinfo->pool, addr), guids_resolve_guid_to_str(ipid, pinfo->pool));
+ }
+ } else {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_pdev_find_unknown_interface, "pdev_find: unknown interface of IP:%s IPID:%s",
+ address_to_str(pinfo->pool, addr), guids_resolve_guid_to_str(ipid, pinfo->pool));
+ pdev = NULL;
+ }
+
+ return pdev;
+}
+
+
+cba_pdev_t *
+cba_pdev_add(packet_info *pinfo, const address *addr)
+{
+ GList *cba_iter;
+ cba_pdev_t *pdev;
+
+
+ /* find pdev */
+ for(cba_iter = cba_pdevs; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ pdev = (cba_pdev_t *)cba_iter->data;
+ if (memcmp(pdev->ip, addr->data, 4) == 0) {
+ return pdev;
+ }
+ }
+
+ /* not found, create a new */
+ pdev = wmem_new(wmem_file_scope(), cba_pdev_t);
+ memcpy( (void *) (pdev->ip), addr->data, 4);
+ pdev->first_packet = pinfo->num;
+ pdev->ldevs = NULL;
+ pdev->object = NULL;
+ cba_pdevs = g_list_append(cba_pdevs, pdev);
+
+ return pdev;
+}
+
+
+void
+cba_pdev_link(packet_info *pinfo _U_, cba_pdev_t *pdev, dcom_interface_t *pdev_interf)
+{
+
+ /* "crosslink" pdev interface and its object */
+ pdev->object = pdev_interf->parent;
+ pdev_interf->private_data = pdev;
+ if (pdev_interf->parent) {
+ pdev_interf->parent->private_data = pdev;
+ }
+}
+
+
+void
+cba_ldev_link(packet_info *pinfo _U_, cba_ldev_t *ldev, dcom_interface_t *ldev_interf)
+{
+
+ /* "crosslink" interface and its object */
+ ldev->ldev_object = ldev_interf->parent;
+ ldev_interf->private_data = ldev;
+ if (ldev_interf->parent) {
+ ldev_interf->parent->private_data = ldev;
+ }
+}
+
+
+void
+cba_ldev_link_acco(packet_info *pinfo _U_, cba_ldev_t *ldev, dcom_interface_t *acco_interf)
+{
+
+ /* "crosslink" interface and its object */
+ ldev->acco_object = acco_interf->parent;
+ acco_interf->private_data = ldev;
+ if (acco_interf->parent) {
+ acco_interf->parent->private_data = ldev;
+ }
+}
+
+
+cba_ldev_t *
+cba_ldev_add(packet_info *pinfo, cba_pdev_t *pdev, const char *name)
+{
+ GList *cba_iter;
+ cba_ldev_t *ldev;
+
+
+ /* find ldev */
+ for(cba_iter = pdev->ldevs; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ ldev = (cba_ldev_t *)cba_iter->data;
+ if (strcmp(ldev->name, name) == 0) {
+ return ldev;
+ }
+ }
+
+ /* not found, create a new */
+ ldev = wmem_new(wmem_file_scope(), cba_ldev_t);
+ ldev->name = wmem_strdup(wmem_file_scope(), name);
+ ldev->first_packet = pinfo->num;
+ ldev->ldev_object = NULL;
+ ldev->acco_object = NULL;
+ ldev->parent = pdev;
+
+ ldev->provframes = NULL;
+ ldev->consframes = NULL;
+ ldev->provconns = NULL;
+ ldev->consconns = NULL;
+
+ pdev->ldevs = g_list_append(pdev->ldevs, ldev);
+
+ return ldev;
+}
+
+
+cba_ldev_t *
+cba_ldev_find(packet_info *pinfo, const address *addr, e_guid_t *ipid) {
+ dcom_interface_t *interf;
+ cba_ldev_t *ldev;
+
+
+ interf = dcom_interface_find(pinfo, addr, ipid);
+ if (interf != NULL) {
+ ldev = (cba_ldev_t *)interf->private_data;
+
+ if (ldev == NULL) {
+ ldev = (cba_ldev_t *)interf->parent->private_data;
+ }
+ if (ldev == NULL) {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_ldev_unknown, "Unknown LDev of %s",
+ address_to_str(pinfo->pool, addr));
+ }
+ } else {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_ipid_unknown, "Unknown IPID of %s",
+ address_to_str(pinfo->pool, addr));
+ ldev = NULL;
+ }
+
+ return ldev;
+}
+
+
+static cba_ldev_t *
+cba_acco_add(packet_info *pinfo, const char *acco)
+{
+ char *ip_str;
+ char *delim;
+ guint32 ip;
+ cba_pdev_t *pdev;
+ cba_ldev_t *ldev;
+ address addr;
+
+
+ ip_str = g_strdup(acco);
+ delim = strchr(ip_str, '!');
+ if (delim == NULL) {
+ g_free(ip_str);
+ return NULL;
+ }
+ *delim = 0;
+
+ if (!get_host_ipaddr(ip_str, &ip)) {
+ g_free(ip_str);
+ return NULL;
+ }
+
+ set_address(&addr, AT_IPv4, 4, &ip);
+ pdev = cba_pdev_add(pinfo, &addr);
+ delim++;
+
+ ldev = cba_ldev_add(pinfo, pdev, delim);
+
+ g_free(ip_str);
+
+ return ldev;
+}
+
+
+static gboolean
+cba_packet_in_range(packet_info *pinfo, guint packet_connect, guint packet_disconnect, guint packet_disconnectme)
+{
+
+ if (packet_connect == 0) {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_connect, "cba_packet_in_range#%u: packet_connect not set?", pinfo->num);
+ }
+
+ if (packet_connect == 0 || pinfo->num < packet_connect) {
+ return FALSE;
+ }
+ if (packet_disconnect != 0 && pinfo->num > packet_disconnect) {
+ return FALSE;
+ }
+ if (packet_disconnectme != 0 && pinfo->num > packet_disconnectme) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static void
+cba_frame_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, cba_frame_t *frame)
+{
+ if (tree) {
+ proto_item *item;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_frame_info, &sub_item,
+ "Cons:\"%s\" CCRID:0x%x Prov:\"%s\" PCRID:0x%x QoS:%s/%ums Len:%u",
+ frame->consparent ? frame->consparent->name : "", frame->conscrid,
+ frame->provparent ? frame->provparent->name : "", frame->provcrid,
+ val_to_str(frame->qostype, cba_qos_type_short_vals, "%u"),
+ frame->qosvalue, frame->length);
+ proto_item_set_generated(sub_item);
+
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_type, tvb, 0, 0, frame->qostype);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_value, tvb, 0, 0, frame->qosvalue);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_cr_id, tvb, 0, 0, frame->conscrid);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_prov_crid, tvb, 0, 0, frame->provcrid);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_cr_length, tvb, 0, 0, frame->length);
+ proto_item_set_generated(item);
+
+ if (frame->consparent != NULL) {
+ item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_consumer, tvb, 0, 0, frame->consparent->name);
+ proto_item_set_generated(item);
+ }
+ if (frame->provparent != NULL) {
+ item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_provider, tvb, 0, 0, frame->provparent->name);
+ proto_item_set_generated(item);
+ }
+
+ item = proto_tree_add_uint(sub_tree, hf_cba_connectcr_in,
+ tvb, 0, 0, frame->packet_connect);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_data_first_in,
+ tvb, 0, 0, frame->packet_first);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_data_last_in,
+ tvb, 0, 0, frame->packet_last);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_disconnectcr_in,
+ tvb, 0, 0, frame->packet_disconnect);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_disconnectme_in,
+ tvb, 0, 0, frame->packet_disconnectme);
+ proto_item_set_generated(item);
+ }
+}
+
+
+static cba_frame_t *
+cba_frame_connect(packet_info *pinfo, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev,
+ guint16 qostype, guint16 qosvalue, const guint8 *consmac, guint16 conscrid, guint16 length)
+{
+ GList *cba_iter;
+ cba_frame_t *frame;
+
+ /* find frame */
+ for(cba_iter = cons_ldev->consframes; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ frame = (cba_frame_t *)cba_iter->data;
+ if ( frame->conscrid == conscrid &&
+ memcmp(frame->consmac, consmac, 6) == 0 &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+ return frame;
+ }
+ }
+
+ frame = wmem_new(wmem_file_scope(), cba_frame_t);
+
+ frame->consparent = cons_ldev;
+ frame->provparent = prov_ldev;
+
+ frame->packet_connect = pinfo->num;
+ frame->packet_disconnect = 0;
+ frame->packet_disconnectme = 0;
+ frame->packet_first = 0;
+ frame->packet_last = 0;
+
+ frame->length = length;
+ memcpy( (guint8 *) (frame->consmac), consmac, sizeof(frame->consmac));
+ frame->conscrid = conscrid;
+ frame->qostype = qostype;
+ frame->qosvalue = qosvalue;
+
+ frame->offset = 4;
+ frame->conns = NULL;
+
+ frame->provcrid = 0;
+ frame->conncrret = -1;
+
+ cons_ldev->consframes = g_list_append(cons_ldev->consframes, frame);
+ prov_ldev->provframes = g_list_append(prov_ldev->provframes, frame);
+
+ return frame;
+}
+
+
+static void
+cba_frame_disconnect(packet_info *pinfo, cba_frame_t *frame)
+{
+
+ if (frame->packet_disconnect == 0) {
+ frame->packet_disconnect = pinfo->num;
+ }
+
+ if (frame->packet_disconnect != pinfo->num) {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_disconnect, "cba_frame_disconnect#%u: frame already disconnected in #%u",
+ pinfo->num, frame->packet_disconnect);
+ }
+}
+
+
+static void
+cba_frame_disconnectme(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev)
+{
+ GList *frames;
+ cba_frame_t *frame;
+
+
+ for(frames = cons_ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = (cba_frame_t *)frames->data;
+
+ if ( frame->provparent == prov_ldev &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+
+ cba_frame_info(tvb, pinfo, tree, frame);
+
+ if (frame->packet_disconnectme == 0) {
+ frame->packet_disconnectme = pinfo->num;
+ }
+
+ if (frame->packet_disconnectme != pinfo->num) {
+ expert_add_info_format(pinfo, tree, &ei_cba_acco_disconnect, "cba_frame_disconnectme#%u: frame already disconnectme'd in #%u",
+ pinfo->num, frame->packet_disconnectme);
+ }
+ }
+ }
+}
+
+
+static cba_frame_t *
+cba_frame_find_by_cons(packet_info *pinfo, const guint8 *consmac, guint16 conscrid)
+{
+ GList *pdevs;
+ GList *ldevs;
+ GList *frames;
+ cba_pdev_t *pdev;
+ cba_ldev_t *ldev;
+ cba_frame_t *frame;
+
+
+ /* find pdev */
+ for(pdevs = cba_pdevs; pdevs != NULL; pdevs = g_list_next(pdevs)) {
+ pdev = (cba_pdev_t *)pdevs->data;
+
+ /* find ldev */
+ for(ldevs = pdev->ldevs; ldevs != NULL; ldevs = g_list_next(ldevs)) {
+ ldev = (cba_ldev_t *)ldevs->data;
+
+ /* find frame */
+ for(frames = ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = (cba_frame_t *)frames->data;
+
+ if ( frame->conscrid == conscrid &&
+ memcmp(frame->consmac, consmac, 6) == 0 &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+ return frame;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+static cba_frame_t *
+cba_frame_find_by_provcrid(packet_info *pinfo, cba_ldev_t *prov_ldev, guint32 provcrid)
+{
+ GList *frames;
+ cba_frame_t *frame;
+
+
+ if (prov_ldev == NULL) {
+ return NULL;
+ }
+
+ for(frames = prov_ldev->provframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = (cba_frame_t *)frames->data;
+
+ if ( frame->provcrid == provcrid &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+ return frame;
+ }
+ }
+
+ expert_add_info(pinfo, NULL, &ei_cba_acco_prov_crid);
+
+ return NULL;
+}
+
+
+static void
+cba_frame_incoming_data(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, cba_frame_t *frame)
+{
+ if (frame->packet_first == 0) {
+ frame->packet_first = pinfo->num;
+ }
+
+ if ( pinfo->num > frame->packet_last &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+ frame->packet_last = pinfo->num;
+ }
+}
+
+
+static void
+cba_connection_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, cba_connection_t *conn)
+{
+ if (tree) {
+ proto_item *item;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ if (conn->qostype != 0x30) {
+ sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_conn_info, &sub_item,
+ "ProvItem:\"%s\" PID:0x%x CID:0x%x QoS:%s/%ums",
+ conn->provitem, conn->provid, conn->consid,
+ val_to_str(conn->qostype, cba_qos_type_short_vals, "%u"), conn->qosvalue);
+ } else {
+ sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_conn_info, &sub_item,
+ "ProvItem:\"%s\" PID:0x%x CID:0x%x Len:%u",
+ conn->provitem, conn->provid, conn->consid, conn->length);
+ }
+ proto_item_set_generated(sub_item);
+
+ item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_provider_item, tvb, 0, 0 /* len */, conn->provitem);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_prov_id, tvb, 0, 0 /* len */, conn->provid);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_cons_id, tvb, 0, 0 /* len */, conn->consid);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_record_length, tvb, 0, 0 /* len */, conn->length);
+ proto_item_set_generated(item);
+
+ if (conn->qostype != 0x30) {
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_type,
+ tvb, 0, 0, conn->qostype);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_value,
+ tvb, 0, 0, conn->qosvalue);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_connect_in,
+ tvb, 0, 0, conn->packet_connect);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_data_first_in,
+ tvb, 0, 0, conn->packet_first);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_data_last_in,
+ tvb, 0, 0, conn->packet_last);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_disconnect_in,
+ tvb, 0, 0, conn->packet_disconnect);
+ proto_item_set_generated(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_disconnectme_in,
+ tvb, 0, 0, conn->packet_disconnectme);
+ proto_item_set_generated(item);
+ }
+ }
+}
+
+
+static cba_connection_t *
+cba_connection_connect(packet_info *pinfo, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev, cba_frame_t *cons_frame,
+ guint16 qostype, guint16 qosvalue, const char *provitem, guint32 consid, guint16 length,
+ guint16 *typedesc, guint16 typedesclen)
+{
+ GList *cba_iter;
+ cba_connection_t *conn;
+
+
+ /* find connection */
+ if (cons_frame != NULL) {
+ /* SRT: search in frame */
+ for(cba_iter = cons_frame->conns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ conn = (cba_connection_t *)cba_iter->data;
+ if (conn->consid == consid) {
+ return conn;
+ }
+ }
+ } else {
+ /* DCOM: search in ldev */
+ for(cba_iter = cons_ldev->consconns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ conn = (cba_connection_t *)cba_iter->data;
+ if ( conn->consid == consid &&
+ cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
+ return conn;
+ }
+ }
+ }
+
+ conn = wmem_new(wmem_file_scope(), cba_connection_t);
+
+ conn->consparentacco = cons_ldev;
+ conn->provparentacco = prov_ldev;
+ conn->parentframe = cons_frame;
+
+ conn->packet_connect = pinfo->num;
+ conn->packet_disconnect = 0;
+ conn->packet_disconnectme = 0;
+ conn->packet_first = 0;
+ conn->packet_last = 0;
+
+ conn->consid = consid;
+ conn->provitem = wmem_strdup(wmem_file_scope(), provitem);
+ conn->typedesclen = typedesclen;
+ conn->typedesc = typedesc;
+ conn->qostype = qostype;
+ conn->qosvalue = qosvalue;
+ conn->length = length;
+
+ conn->provid = 0;
+ conn->connret = -1;
+
+ if (cons_frame != NULL) {
+ conn->frame_offset = cons_frame->offset;
+ conn->length = length;
+ cons_frame->offset += length;
+ cons_frame->conns = g_list_append(cons_frame->conns, conn);
+ } else {
+ conn->frame_offset = 0;
+ cons_ldev->consconns = g_list_append(cons_ldev->consconns, conn);
+ prov_ldev->provconns = g_list_append(prov_ldev->provconns, conn);
+ }
+
+ return conn;
+}
+
+
+static void
+cba_connection_disconnect(packet_info *pinfo, cba_connection_t *conn)
+{
+ /* XXX - detect multiple disconnects? */
+ if (conn->packet_disconnect == 0) {
+ conn->packet_disconnect = pinfo->num;
+ }
+
+ if (conn->packet_disconnect != pinfo->num) {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_disconnect, "connection_disconnect#%u: already disconnected",
+ conn->packet_disconnect);
+ }
+}
+
+
+static void
+cba_connection_disconnectme(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev)
+{
+ GList *conns;
+ cba_connection_t *conn;
+
+
+ for(conns = cons_ldev->consconns; conns != NULL; conns = g_list_next(conns)) {
+ conn = (cba_connection_t *)conns->data;
+
+ if ( conn->provparentacco == prov_ldev &&
+ cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
+
+ cba_connection_info(tvb, pinfo, tree, conn);
+
+ if (conn->packet_disconnectme == 0) {
+ conn->packet_disconnectme = pinfo->num;
+ }
+
+ if (conn->packet_disconnectme != pinfo->num) {
+ expert_add_info_format(pinfo, tree, &ei_cba_acco_disconnect, "connection_disconnectme#%u: already disconnectme'd",
+ conn->packet_disconnectme);
+ }
+ }
+ }
+}
+
+
+static cba_connection_t *
+cba_connection_find_by_provid(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, cba_ldev_t *prov_ldev, guint32 provid)
+{
+ GList *cba_iter;
+ cba_connection_t *conn;
+
+
+ for(cba_iter = prov_ldev->provconns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ conn = (cba_connection_t *)cba_iter->data;
+ if ( conn->provid == provid &&
+ cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
+ return conn;
+ }
+ }
+ return NULL;
+}
+
+
+static void
+cba_connection_incoming_data(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, cba_connection_t *conn)
+{
+ if (conn->packet_first == 0) {
+ conn->packet_first = pinfo->num;
+ }
+
+ if ( pinfo->num > conn->packet_last &&
+ cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
+ conn->packet_last = pinfo->num;
+ }
+}
+
+
+/* dissect a response containing an array of hresults (e.g: ICBAAccoMgt::RemoveConnections) */
+static int
+dissect_HResultArray_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult, u32Idx);
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_SetActivation_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+ proto_item *item;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult, u32Idx);
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_Disconnect_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+ proto_item *item;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult, u32Idx);
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_SetActivation_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+ proto_item *item;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult, u32Idx);
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_Connect_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16QoSType;
+ guint16 u16QoSValue;
+ guint8 u8State;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+
+ guint32 u32VariableOffset;
+ guint32 u32SubStart;
+ guint32 u32Pointer;
+ guint16 u16VarType;
+ guint32 u32ConsID;
+ gchar szItem[1000] = { 0 };
+ guint32 u32MaxItemLen = sizeof(szItem);
+ gchar szCons[1000] = { 0 };
+ guint32 u32MaxConsLen = sizeof(szCons);
+ guint32 u32Idx;
+
+ proto_item *item;
+ dcom_interface_t *cons_interf;
+ cba_ldev_t *cons_ldev;
+ cba_ldev_t *prov_ldev;
+ cba_connection_t *conn;
+ server_connect_call_t *call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
+
+ /* find the consumer ldev by its name */
+ cons_ldev = cba_acco_add(pinfo, szCons);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_type, &u16QoSType);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+ offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf);
+ if (cons_interf == NULL) {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer,
+ "Server_Connect: consumer interface invalid");
+ }
+
+ /* "crosslink" consumer interface and its object */
+ if (cons_interf != NULL && cons_ldev != NULL) {
+ cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
+ }
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /* link connections infos to the call */
+ if (prov_ldev != NULL && cons_ldev != NULL) {
+ call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
+ call->conn_count = 0;
+ call->frame = NULL;
+ call->conns = (cba_connection_t **) (call+1);
+ di->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
+ u32VariableOffset = offset + u32ArraySize*16;
+
+ /* array of CONNECTINs */
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectin);
+ u32SubStart = offset;
+
+ /* ProviderItem */
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider_item, szItem, u32MaxItemLen);
+ }
+
+ /* DataType */
+ offset = dissect_dcom_VARTYPE(tvb, offset, pinfo, sub_tree, di, drep,
+ &u16VarType);
+
+ /* Epsilon */
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_epsilon);
+ }
+ /* ConsumerID */
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID);
+
+ /* add to object database */
+ if (prov_ldev != NULL && cons_ldev != NULL) {
+ conn = cba_connection_connect(pinfo, cons_ldev, prov_ldev, /*cons_frame*/ NULL,
+ u16QoSType, u16QoSValue, szItem, u32ConsID, 0,
+ /* XXX - VarType must be translated to new type description if it includes an array (0x2000) */
+ (guint16 *)wmem_memdup(wmem_file_scope(), &u16VarType, 2), 1);
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ } else {
+ conn = NULL;
+ }
+
+ /* add to current call */
+ if (call != NULL) {
+ call->conn_count++;
+ call->conns[u32Idx-1] = conn;
+ }
+
+ /* update subtree header */
+ proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", VarType=%s",
+ u32Idx, u32ConsID, szItem,
+ val_to_str(u16VarType, dcom_variant_type_vals, "Unknown (0x%04x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Consumer=\"%s\" Cnt=%u", szCons, u32Count);
+
+ return u32VariableOffset;
+}
+
+static int
+dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16QoSType;
+ guint16 u16QoSValue;
+ guint8 u8State;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+
+ guint32 u32VariableOffset;
+ guint32 u32SubStart;
+ guint32 u32Pointer;
+ guint16 u16VarType;
+ guint32 u32ConsID;
+ gchar szItem[1000] = { 0 };
+ guint32 u32MaxItemLen = sizeof(szItem);
+ gchar szCons[1000] = { 0 };
+ guint32 u32MaxConsLen = sizeof(szCons);
+ guint32 u32Idx;
+ guint16 u16TypeDescLen;
+ guint32 u32ArraySize2;
+ guint32 u32Idx2;
+ guint16 u16VarType2 = -1;
+
+ proto_item *item;
+ dcom_interface_t *cons_interf;
+ cba_ldev_t *prov_ldev;
+ cba_ldev_t *cons_ldev;
+ cba_connection_t *conn;
+ guint16 typedesclen = 0;
+ guint16 *typedesc = NULL;
+ server_connect_call_t *call = NULL;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
+
+ /* find the consumer ldev by its name */
+ cons_ldev = cba_acco_add(pinfo, szCons);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_type, &u16QoSType);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+ offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf);
+ if (cons_interf == NULL) {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer,
+ "Server2_Connect2: consumer interface invalid");
+ }
+ } else {
+ /* GetConnectionData do it this way */
+ cons_interf = NULL;
+ }
+
+ /* "crosslink" consumer interface and its object */
+ if (cons_interf != NULL && cons_ldev != NULL) {
+ cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
+ }
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /* link connection infos to the call */
+ if (prov_ldev != NULL && cons_ldev != NULL) {
+ call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
+ call->conn_count = 0;
+ call->frame = NULL;
+ call->conns = (cba_connection_t **) (call+1);
+ di->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
+ u32VariableOffset = offset + u32ArraySize*20;
+
+ /* array of CONNECTINs */
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectin);
+ u32SubStart = offset;
+
+ /* ProviderItem */
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider_item, szItem, u32MaxItemLen);
+ }
+
+ /* TypeDescLen */
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_type_desc_len, &u16TypeDescLen);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ /* pTypeDesc */
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ &u32ArraySize2);
+
+ /* limit the allocation to a reasonable size */
+ if (u32ArraySize2 < 1000) {
+ typedesc = (guint16 *)wmem_alloc0(wmem_file_scope(), u32ArraySize2 * 2);
+ typedesclen = u32ArraySize2;
+ } else {
+ typedesc = NULL;
+ typedesclen = 0;
+ }
+
+ /* extended type description will build an array here */
+ u32Idx2 = 1;
+ while (u32ArraySize2--) {
+ /* ToBeDone: some of the type description values are counts */
+ u32VariableOffset = dissect_dcom_VARTYPE(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ &u16VarType);
+
+ if (typedesc != NULL && u32Idx2 <= typedesclen) {
+ typedesc[u32Idx2-1] = u16VarType;
+ }
+
+ /* remember first VarType only */
+ if (u32Idx2 == 1) {
+ u16VarType2 = u16VarType;
+ }
+ u32Idx2++;
+ }
+ }
+
+ /* Epsilon */
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_epsilon);
+ }
+ /* ConsumerID */
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID);
+
+ /* add to object database */
+ if (prov_ldev != NULL && cons_ldev != NULL) {
+ conn = cba_connection_connect(pinfo, cons_ldev, prov_ldev, /*cons_frame*/ NULL,
+ u16QoSType, u16QoSValue, szItem, u32ConsID, 0,
+ typedesc, typedesclen);
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ } else {
+ conn = NULL;
+ }
+
+ /* add to current call */
+ if (call != NULL) {
+ call->conn_count++;
+ call->conns[u32Idx-1] = conn;
+ }
+
+ /* update subtree header */
+ proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", TypeDesc=%s",
+ u32Idx, u32ConsID, szItem,
+ val_to_str(u16VarType2, dcom_variant_type_vals, "Unknown (0x%04x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Consumer=\"%s\" Cnt=%u", szCons, u32Count);
+
+
+ return u32VariableOffset;
+}
+
+
+static int
+dissect_ICBAAccoServer_Connect_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint8 u8FirstConnect;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32HResult;
+ guint32 u32Idx = 1;
+ guint32 u32ProvID;
+ guint32 u32SubStart;
+
+ proto_item *item;
+ cba_connection_t *conn;
+ server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ if (call == NULL) {
+ expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
+ }
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
+
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_server_first_connect, &u8FirstConnect);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /* array of CONNECTOUTs */
+ while(u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_connectout, tvb, offset, 8, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectout);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_prov_id, &u32ProvID);
+
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ /* put response data into the connection */
+ if (call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ conn->provid = u32ProvID;
+ conn->connret = u32HResult;
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ }
+
+ proto_item_append_text(sub_item, "[%u]: ProvID=0x%x %s",
+ u32Idx, u32ProvID,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ /* this might be a global HRESULT */
+ while(call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ conn->provid = 0;
+ conn->connret = u32HResult;
+ u32Idx++;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %s Cnt=%u -> %s",
+ (u8FirstConnect) ? "First" : "NotFirst",
+ u32Idx-1,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_Disconnect_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ProvID;
+
+ proto_item *item;
+ cba_ldev_t *prov_ldev;
+ cba_connection_t *conn;
+ server_connect_call_t *call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ /* link connection infos to the call */
+ if (prov_ldev != NULL) {
+ call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
+ call->conn_count = 0;
+ call->frame = NULL;
+ call->conns = (cba_connection_t **) (call+1);
+ di->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
+
+ /* add to current call */
+ if (call != NULL) {
+ conn = cba_connection_find_by_provid(tvb, pinfo, tree, prov_ldev, u32ProvID);
+ call->conn_count++;
+ call->conns[u32Idx-1] = conn;
+ }
+
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_Disconnect_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+
+ proto_item *item;
+ cba_connection_t *conn;
+ server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ if (call == NULL) {
+ expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
+ }
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult, u32Idx);
+
+ /* mark this connection as disconnected */
+ if (call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ if (conn != NULL) {
+ cba_connection_disconnect(pinfo, conn);
+ }
+ }
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_Disconnect_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ProvID;
+ proto_item *item;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ proto_item *item;
+ cba_ldev_t *prov_ldev;
+ cba_ldev_t *cons_ldev;
+ server_disconnectme_call_t *call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_consumer, szStr, u32MaxStr);
+
+ /* find the consumer ldev by its name */
+ cons_ldev = cba_acco_add(pinfo, szStr);
+
+ if (prov_ldev != NULL && cons_ldev != NULL) {
+ call = wmem_new(wmem_file_scope(), server_disconnectme_call_t);
+ call->cons = cons_ldev;
+ call->prov = prov_ldev;
+ di->call_data->private_data = call;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_DisconnectMe_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ proto_item *item;
+ server_disconnectme_call_t *call;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ call = (server_disconnectme_call_t *)di->call_data->private_data;
+ if (call) {
+ cba_connection_disconnectme(tvb, pinfo, tree, call->cons, call->prov);
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ proto_item *item;
+ cba_ldev_t *prov_ldev;
+ cba_ldev_t *cons_ldev;
+ server_disconnectme_call_t *call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_consumer, szStr, u32MaxStr);
+
+ /* find the consumer ldev by its name */
+ cons_ldev = cba_acco_add(pinfo, szStr);
+
+ if (prov_ldev != NULL && cons_ldev != NULL) {
+ call = wmem_new(wmem_file_scope(), server_disconnectme_call_t);
+ call->cons = cons_ldev;
+ call->prov = prov_ldev;
+ di->call_data->private_data = call;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_DisconnectMe_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ proto_item *item;
+ server_disconnectme_call_t *call;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ call = (server_disconnectme_call_t *)di->call_data->private_data;
+ if (call) {
+ cba_frame_disconnectme(tvb, pinfo, tree, call->cons, call->prov);
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_Ping_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ proto_item *item;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_SetActivation_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint8 u8State;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ProvID;
+ proto_item *item;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
+
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
+ u32Idx++;
+ }
+
+ /* update column info now */
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_SetActivation_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint8 u8State;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ProvID;
+ proto_item *item;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
+
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer_Ping_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ proto_item *item;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_consumer, szStr, u32MaxStr);
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_ConnectCR_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szCons[1000] = { 0 };
+ guint32 u32MaxConsLen = sizeof(szCons);
+ guint16 u16QoSType;
+ guint16 u16QoSValue;
+ guint8 u8ConsMac[6];
+ guint16 u16CRID = 0;
+ guint16 u16CRLength = 0;
+ guint32 u32Flags;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ proto_item *item;
+ proto_tree *flags_tree;
+ guint32 u32SubStart;
+ dcom_interface_t *cons_interf;
+ cba_ldev_t *prov_ldev;
+ cba_ldev_t *cons_ldev;
+ cba_frame_t *frame;
+ server_frame_call_t *call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
+
+ /* szCons */
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
+
+ /* find the consumer ldev by its name */
+ cons_ldev = cba_acco_add(pinfo, szCons);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_type, &u16QoSType);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf);
+ if (cons_interf == NULL) {
+ expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer,
+ "ServerSRT_ConnectCR: consumer interface invalid");
+ }
+
+ /* "crosslink" consumer interface and its object */
+ if (cons_interf != NULL && cons_ldev != NULL) {
+ cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
+ }
+
+ /* ConsumerMAC (big-endian, 1byte-aligned) */
+ tvb_memcpy(tvb, u8ConsMac, offset, 6);
+
+ proto_tree_add_ether(tree, hf_cba_acco_serversrt_cons_mac, tvb,
+ offset, 6, u8ConsMac);
+ offset += 6;
+
+ /* add flags subtree */
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL /*tree*/, di, drep,
+ 0 /* hfindex */, &u32Flags);
+ offset -= 4;
+ item = proto_tree_add_uint_format_value(tree, hf_cba_acco_serversrt_cr_flags,
+ tvb, offset, 4, u32Flags,
+ "0x%02x (%s, %s)", u32Flags,
+ (u32Flags & 0x2) ? "Reconfigure" : "not Reconfigure",
+ (u32Flags & 0x1) ? "Timestamped" : "not Timestamped");
+ flags_tree = proto_item_add_subtree(item, ett_cba_acco_serversrt_cr_flags);
+ proto_tree_add_boolean(flags_tree, hf_cba_acco_serversrt_cr_flags_reconfigure, tvb, offset, 4, u32Flags);
+ proto_tree_add_boolean(flags_tree, hf_cba_acco_serversrt_cr_flags_timestamped, tvb, offset, 4, u32Flags);
+ offset += 4;
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /* link frame infos to the call */
+ if (prov_ldev != NULL && cons_ldev != NULL && u32ArraySize < 100) {
+ call = (server_frame_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_frame_call_t) + u32ArraySize * sizeof(cba_frame_t *));
+ call->frame_count = 0;
+ call->frames = (cba_frame_t **) (call+1);
+ di->call_data->private_data = call;
+ } else {
+ call = NULL;
+ }
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* array of CONNECTINCRs */
+ sub_item = proto_tree_add_item(tree, hf_cba_connectincr, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectincr);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_serversrt_cr_id, &u16CRID);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_serversrt_cr_length, &u16CRLength);
+
+ /* add to object database */
+ if (prov_ldev != NULL && cons_ldev != NULL) {
+ frame = cba_frame_connect(pinfo, cons_ldev, prov_ldev, u16QoSType, u16QoSValue, u8ConsMac, u16CRID, u16CRLength);
+
+ cba_frame_info(tvb, pinfo, sub_tree, frame);
+ } else {
+ frame = NULL;
+ }
+
+ /* add to current call */
+ if (call != NULL) {
+ call->frame_count++;
+ call->frames[u32Idx-1] = frame;
+ }
+
+ /* update subtree header */
+ proto_item_append_text(sub_item, "[%u]: CRID=0x%x, CRLength=%u",
+ u32Idx, u16CRID, u16CRLength);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %sConsCRID=0x%x Len=%u QoS=%u",
+ (u32Flags & 0x2) ? "Reco " : "", u16CRID, u16CRLength, u16QoSValue);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_ConnectCR_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint8 u8FirstConnect;
+ guint8 u8ProvMac[6];
+ guint32 u32ProvCRID = 0;
+ guint32 u32HResult;
+ guint32 u32ArraySize;
+ guint32 u32Idx = 1;
+ guint32 u32Pointer;
+ guint32 u32SubStart;
+ proto_item *item;
+ cba_frame_t *frame;
+ server_frame_call_t *call = (server_frame_call_t *)di->call_data->private_data;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ if (call == NULL) {
+ expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
+ }
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
+
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_server_first_connect, &u8FirstConnect);
+
+ /* ProviderMAC (big-endian, 1byte-aligned) */
+ tvb_memcpy(tvb, u8ProvMac, offset, 6);
+
+ proto_tree_add_ether(tree, hf_cba_acco_serversrt_prov_mac, tvb,
+ offset, 6, u8ProvMac);
+ offset += 6;
+
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ while (u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* array of CONNECTOUTCRs */
+ sub_item = proto_tree_add_item(tree, hf_cba_connectoutcr, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectoutcr);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_prov_crid, &u32ProvCRID);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult);
+
+ /* put response data into the frame */
+ if (call && u32Idx <= call->frame_count) {
+ frame = call->frames[u32Idx-1];
+ frame->provcrid = u32ProvCRID;
+ frame->conncrret = u32HResult;
+
+ cba_frame_info(tvb, pinfo, sub_tree, frame);
+ }
+
+ /* update subtree header */
+ proto_item_append_text(sub_item, "[%u]: ProvCRID=0x%x, %s",
+ u32Idx, u32ProvCRID,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ /* this might be a global HRESULT */
+ while(call && u32Idx <= call->frame_count) {
+ frame = call->frames[u32Idx-1];
+ frame->provcrid = 0;
+ frame->conncrret = u32HResult;
+ u32Idx++;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %s PCRID=0x%x -> %s",
+ (u8FirstConnect) ? "FirstCR" : "NotFirstCR",
+ u32ProvCRID,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_DisconnectCR_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ProvCRID = 0;
+ proto_item *item;
+ cba_ldev_t *prov_ldev;
+ cba_frame_t *frame;
+ server_frame_call_t *call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /* link frame infos to the call */
+ if (prov_ldev != NULL) {
+ call = (server_frame_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_frame_call_t) + u32ArraySize * sizeof(cba_frame_t *));
+ call->frame_count = 0;
+ call->frames = (cba_frame_t **) (call+1);
+ di->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_prov_crid, &u32ProvCRID, u32Idx);
+
+ /* find frame and add it to current call */
+ if (call != NULL) {
+ frame = cba_frame_find_by_provcrid(pinfo, prov_ldev, u32ProvCRID);
+ call->frame_count++;
+ call->frames[u32Idx-1] = frame;
+ }
+
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": PCRID=0x%x",
+ u32ProvCRID);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_DisconnectCR_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+ cba_frame_t *frame;
+ proto_item *item;
+ server_frame_call_t *call = (server_frame_call_t *)di->call_data->private_data;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult, u32Idx);
+ /* put response data into the frame */
+ if (call && u32Idx <= call->frame_count) {
+ frame = call->frames[u32Idx-1];
+ if (frame != NULL) {
+ cba_frame_disconnect(pinfo, frame);
+ }
+ }
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_Connect_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32ProvCRID;
+ guint8 u8State;
+ guint8 u8LastConnect;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32VariableOffset;
+ guint32 u32Idx;
+ guint32 u32SubStart;
+ guint32 u32Pointer;
+ gchar szProvItem[1000] = { 0 };
+ guint32 u32MaxProvItemLen = sizeof(szProvItem);
+ guint16 u16TypeDescLen;
+ guint32 u32ArraySize2;
+ guint32 u32Idx2;
+ guint16 u16VarType2 = -1;
+ guint16 u16VarType;
+ guint32 u32ConsID;
+ guint16 u16RecordLength;
+
+ proto_item *item;
+ cba_ldev_t *prov_ldev;
+ cba_frame_t *frame = NULL;
+ guint16 typedesclen = 0;
+ guint16 *typedesc = NULL;
+
+ cba_connection_t *conn;
+ server_connect_call_t *call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_prov_crid, &u32ProvCRID);
+
+ frame = cba_frame_find_by_provcrid(pinfo, prov_ldev, u32ProvCRID);
+
+ if (frame != NULL) {
+ cba_frame_info(tvb, pinfo, tree, frame);
+ }
+
+ offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+
+ offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_serversrt_last_connect, &u8LastConnect);
+
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /* link connections infos to the call */
+ if (frame != NULL) {
+ call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
+ call->conn_count = 0;
+ call->frame = frame;
+ call->conns = (cba_connection_t **) (call+1);
+ di->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
+ u32VariableOffset = offset + u32ArraySize*20;
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* array of CONNECTINs */
+ sub_item = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectin);
+ u32SubStart = offset;
+
+ /* ProviderItem */
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
+ }
+
+ /* TypeDescLen */
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_type_desc_len, &u16TypeDescLen);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ /* pTypeDesc */
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ &u32ArraySize2);
+
+ typedesc = (guint16 *)wmem_alloc0(wmem_file_scope(), u32ArraySize2 * 2);
+ typedesclen = u32ArraySize2;
+
+ /* extended type description will build an array here */
+ u32Idx2 = 1;
+ while (u32ArraySize2--) {
+ /* ToBeDone: some of the type description values are counts */
+ u32VariableOffset = dissect_dcom_VARTYPE(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ &u16VarType);
+
+ if (u32Idx2 <= typedesclen) {
+ typedesc[u32Idx2-1] = u16VarType;
+ }
+
+ /* remember first VarType only */
+ if (u32Idx2 == 1) {
+ u16VarType2 = u16VarType;
+ }
+ u32Idx2++;
+ }
+ }
+
+ /* ConsumerID */
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID);
+
+ /* RecordLength */
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_serversrt_record_length, &u16RecordLength);
+
+ /* add to object database */
+ if (frame != NULL) {
+ conn = cba_connection_connect(pinfo, frame->consparent, frame->provparent, frame,
+ frame->qostype, frame->qosvalue, szProvItem, u32ConsID, u16RecordLength,
+ typedesc, typedesclen);
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ } else {
+ conn = NULL;
+ }
+
+ /* add to current call */
+ if (call != NULL) {
+ call->conn_count++;
+ call->conns[u32Idx-1] = conn;
+ }
+
+ /* update subtree header */
+ proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", TypeDesc=%s",
+ u32Idx, u32ConsID, szProvItem,
+ val_to_str(u16VarType2, dcom_variant_type_vals, "Unknown (0x%04x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %s Cnt=%u PCRID=0x%x",
+ (u8LastConnect) ? "LastOfCR" : "",
+ u32Idx-1,
+ u32ProvCRID);
+
+ return u32VariableOffset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_Connect_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Pointer;
+ guint32 u32ArraySize;
+ guint32 u32Idx = 1;
+ guint32 u32SubStart;
+ guint32 u32ProvID;
+ guint32 u32HResult;
+
+ proto_item *item;
+
+ server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data;
+ cba_connection_t *conn;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ if (call == NULL) {
+ expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
+ }
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (call && call->frame != NULL) {
+ cba_frame_info(tvb, pinfo, tree, call->frame);
+ }
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /* array of CONNECTOUTs */
+ while(u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_connectout, tvb, offset, 8, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectout);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_prov_id, &u32ProvID);
+
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ /* put response data into the frame */
+ if (call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ conn->provid = u32ProvID;
+ conn->connret = u32HResult;
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ }
+
+ proto_item_append_text(sub_item, "[%u]: ProvID=0x%x %s",
+ u32Idx, u32ProvID,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ /* this might be a global HRESULT */
+ while(call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ conn->provid = 0;
+ conn->connret = u32HResult;
+ u32Idx++;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32Idx-1,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_Server_GetProvIDs_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32Pointer;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ProvID;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ if (u32Count) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ProvID=", u32Count);
+ } else {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo,
+ tree, di, drep,
+ hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
+
+ if (u32Idx == 1) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ProvID);
+ } else if (u32Idx < 10) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ProvID);
+ } else if (u32Idx == 10) {
+ col_append_str(pinfo->cinfo, COL_INFO, ",...");
+ }
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_Server_GetProvConnections_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ProvID;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return offset;
+}
+
+
+static int
+dissect_Server_GetProvConnections_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32TmpCount;
+ guint32 u32Pointer;
+ guint32 u32VariableOffset;
+ guint32 u32Idx;
+ guint32 u32SubStart;
+ gchar szCons[1000] = { 0 };
+ guint32 u32MaxConsLen = sizeof(szCons);
+ gchar szProvItem[1000] = { 0 };
+ guint32 u32MaxProvItemLen = sizeof(szProvItem);
+ guint32 u32ConsID;
+ guint16 u16QoSType;
+ guint16 u16QoSValue;
+ guint8 u8State;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ u32VariableOffset = offset;
+
+ if (u32Pointer) {
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ u32VariableOffset = offset + u32Count*28;
+
+ /* array fixed part (including pointers to variable part) */
+ u32TmpCount = u32Count;
+ u32Idx = 1;
+ while (u32TmpCount--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_getprovconnout, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_getprovconnout);
+ u32SubStart = offset;
+
+ /* wszConsumer */
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
+ }
+ /* wszProviderItem */
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
+ }
+ /* dwConsID */
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID);
+
+ /* Epsilon */
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_epsilon);
+ }
+
+ /* QoS Type */
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_qos_type, &u16QoSType);
+ /* QoS Value */
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+ /* State */
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+ /* PartialResult */
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ proto_item_append_text(sub_item, "[%u]: %s",
+ u32Idx,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+ }
+
+ u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return u32VariableOffset;
+}
+
+
+#define CBA_MRSH_VERSION_DCOM 0x01
+#define CBA_MRSH_VERSION_SRT_WITH_CONSID 0x10
+#define CBA_MRSH_VERSION_SRT_WITHOUT_CONSID 0x11
+
+
+static int
+dissect_CBA_Connection_Data(tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_frame_t *frame)
+{
+ guint8 u8Version;
+ guint8 u8Flags;
+ guint16 u16CountFix;
+ guint16 u16Count;
+ guint32 u32ItemIdx;
+ guint32 u32HoleIdx;
+ proto_item *conn_data_item = NULL;
+ proto_tree *conn_data_tree = NULL;
+ guint16 u16Len;
+ guint32 u32ID;
+ guint8 u8QC;
+ guint16 u16DataLen;
+ guint16 u16HdrLen;
+ int offset = 0;
+ int offset_hole;
+ gboolean qc_reported = FALSE;
+ int qc_good = 0;
+ int qc_uncertain = 0;
+ int qc_bad = 0;
+ GList *conns;
+ int item_offset;
+ cba_connection_t *conn;
+
+
+ /*** ALL data in this buffer is NOT aligned and always little endian ordered ***/
+
+ if (tree) {
+ conn_data_item = proto_tree_add_item(tree, hf_cba_acco_cb_conn_data, tvb, offset, 0, ENC_NA);
+ conn_data_tree = proto_item_add_subtree(conn_data_item, ett_ICBAAccoCallback_Buffer);
+ }
+
+ /* add buffer header */
+ u8Version = tvb_get_guint8 (tvb, offset);
+ if (conn_data_tree) {
+ proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ }
+ offset += 1;
+
+ u8Flags = tvb_get_guint8 (tvb, offset);
+ if (conn_data_tree) {
+ proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ }
+ offset += 1;
+
+ u16Count = tvb_get_letohs (tvb, offset);
+ if (conn_data_tree) {
+ proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ }
+ offset += 2;
+ u16CountFix = u16Count;
+
+ /* show meta information */
+ if (frame) {
+ cba_frame_info(tvb, pinfo, conn_data_tree, frame);
+ } else {
+ if (cons_ldev && cons_ldev->name) {
+ proto_item *item;
+ item = proto_tree_add_string(conn_data_tree, hf_cba_acco_conn_consumer, tvb, offset, 0, cons_ldev->name);
+ proto_item_set_generated(item);
+ }
+ }
+
+ /* update column info now */
+#if 0
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Cnt=%u", u16Count);
+#endif
+
+ /* is this an OnDataChanged buffer format (version), we know? */
+ if ((u8Version != CBA_MRSH_VERSION_DCOM) &&
+ (u8Version != CBA_MRSH_VERSION_SRT_WITH_CONSID) &&
+ (u8Version != CBA_MRSH_VERSION_SRT_WITHOUT_CONSID))
+ {
+ return offset;
+ }
+
+ /* Timestamps are currently unused -> flags must be zero */
+ if (u8Flags != 0) {
+ return offset;
+ }
+
+ u32ItemIdx = 1;
+ u32HoleIdx = 1;
+ while (u16Count--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ proto_item *item;
+
+ /* find next record header */
+ u16Len = tvb_get_letohs (tvb, offset);
+
+ /* trapped inside an empty hole? -> try to find next record header */
+ if (u16Len == 0 &&
+ (u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID ||
+ u8Version == CBA_MRSH_VERSION_SRT_WITHOUT_CONSID))
+ {
+ u32HoleIdx++;
+ offset_hole = offset;
+ /* length smaller or larger than possible -> must be a hole */
+ while (u16Len == 0) {
+ offset++;
+ u16Len = tvb_get_letohs(tvb, offset);
+ /* this is a bit tricky here! we know: */
+ /* u16Len must be greater than 3 (min. size of header itself) */
+ /* u16Len must be a lot smaller than 0x300 (max. size of frame) */
+ /* -> if we found a length larger than 0x300, */
+ /* this must be actually the high byte, so do one more step */
+ if (u16Len > 0x300) {
+ u16Len = 0;
+ }
+ }
+ proto_tree_add_none_format(conn_data_tree, hf_cba_acco_cb_item_hole, tvb,
+ offset_hole, offset - offset_hole,
+ "Hole(--): -------------, offset=%2u, length=%2u",
+ offset_hole, offset - offset_hole);
+ }
+
+ /* add callback-item subtree */
+ sub_item = proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_item, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_ICBAAccoCallback_Item);
+
+ item_offset = offset;
+
+ /* add item header fields */
+ if (sub_tree) {
+ proto_tree_add_item(sub_tree, hf_cba_acco_cb_item_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ }
+ offset += 2;
+ u16HdrLen = 2;
+
+ if (u8Version == CBA_MRSH_VERSION_DCOM ||
+ u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID)
+ {
+ u32ID = tvb_get_letohl (tvb, offset);
+ if (sub_tree) {
+ proto_tree_add_item(sub_tree, hf_cba_acco_conn_cons_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ }
+ offset += 4;
+ u16HdrLen += 4;
+ } else {
+ u32ID = 0;
+ }
+
+ u8QC = tvb_get_guint8 (tvb, offset);
+ item = NULL;
+ if (sub_tree) {
+ item = proto_tree_add_item(sub_tree, hf_cba_acco_qc, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ }
+ offset += 1;
+ u16HdrLen += 1;
+
+ if ( u8QC != 0x80 && /* GoodNonCascOk */
+ u8QC != 0x1C && /* BadOutOfService (usually permanent, so don't report for every frame) */
+ qc_reported == 0) {
+ expert_add_info_format(pinfo, item, &ei_cba_acco_qc, "%s QC: %s",
+ u8Version == CBA_MRSH_VERSION_DCOM ? "DCOM" : "SRT",
+ val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)"));
+ qc_reported = 0;
+ }
+
+ switch(u8QC >> 6) {
+ case(00):
+ qc_bad++;
+ break;
+ case(01):
+ qc_uncertain++;
+ break;
+ default:
+ qc_good++;
+ }
+
+ /* user data length is item length without headers */
+ u16DataLen = u16Len - u16HdrLen;
+
+ /* append text to subtree header */
+ if (u8Version == CBA_MRSH_VERSION_DCOM ||
+ u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID)
+ {
+ proto_item_append_text(sub_item,
+ "[%2u]: ConsID=0x%08x, offset=%2u, length=%2u (user-length=%2u), QC=%s (0x%02x)",
+ u32ItemIdx, u32ID, offset - u16HdrLen, u16Len, u16DataLen,
+ val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)"), u8QC );
+ } else {
+ proto_item_append_text(sub_item,
+ "[%2u]: ConsID=-, offset=%2u, length=%2u (user-length=%2u), QC=%s (0x%02x)",
+ u32ItemIdx, offset - u16HdrLen, u16Len, u16DataLen,
+ val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)"), u8QC );
+ }
+ proto_item_set_len(sub_item, u16Len);
+
+ /* hexdump of user data */
+ proto_tree_add_item(sub_tree, hf_cba_acco_cb_item_data, tvb, offset, u16DataLen, ENC_NA);
+ offset += u16DataLen;
+
+ if (frame != NULL ) {
+ /* find offset in SRT */
+ /* XXX - expensive! */
+ cba_frame_incoming_data(tvb, pinfo, sub_tree, frame);
+ for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
+ conn = (cba_connection_t *)conns->data;
+ if (conn->frame_offset == item_offset) {
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ break;
+ }
+ }
+ } else {
+ /* find consID in ldev */
+ /* XXX - expensive! */
+ if (cons_ldev != NULL) {
+ for(conns = cons_ldev->consconns; conns != NULL; conns = g_list_next(conns)) {
+ conn = (cba_connection_t *)conns->data;
+ if (conn->consid == u32ID) {
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ cba_connection_incoming_data(tvb, pinfo, sub_tree, conn);
+ break;
+ }
+ }
+ }
+ }
+
+ u32ItemIdx++;
+ }
+
+ if (u8Version == 1) {
+ proto_item_append_text(conn_data_item,
+ ": Version=0x%x (DCOM), Flags=0x%x, Count=%u",
+ u8Version, u8Flags, u16CountFix);
+ } else {
+ proto_item_append_text(conn_data_item,
+ ": Version=0x%x (SRT), Flags=0x%x, Count=%u, Items=%u, Holes=%u",
+ u8Version, u8Flags, u16CountFix, u32ItemIdx-1, u32HoleIdx-1);
+ }
+ proto_item_set_len(conn_data_item, offset);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", QC (G:%u,U:%u,B:%u)",
+ qc_good, qc_uncertain, qc_bad);
+
+ return offset;
+}
+
+
+static gboolean
+dissect_CBA_Connection_Data_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ void *data)
+{
+ guint8 u8Version;
+ guint8 u8Flags;
+ /* the tvb will NOT contain the frame_id here! */
+ guint16 u16FrameID = GPOINTER_TO_UINT(data);
+ cba_frame_t *frame;
+
+ /* frame id must be in valid range (cyclic Real-Time, class=1 or class=2) */
+ if (u16FrameID < 0x8000 || u16FrameID >= 0xfb00) {
+ return FALSE;
+ }
+
+ u8Version = tvb_get_guint8 (tvb, 0);
+ u8Flags = tvb_get_guint8 (tvb, 1);
+
+ /* version and flags must be ok */
+ if (u8Version != 0x11 || u8Flags != 0x00) {
+ return FALSE;
+ }
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-CBA");
+
+ frame = cba_frame_find_by_cons(pinfo, (const guint8 *)pinfo->dl_dst.data, u16FrameID);
+
+ dissect_CBA_Connection_Data(tvb, pinfo, tree, frame ? frame->consparent : NULL, frame);
+
+ return TRUE;
+}
+
+
+static int
+dissect_ICBAAccoCallback_OnDataChanged_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Length;
+ guint32 u32ArraySize;
+ tvbuff_t *next_tvb;
+ proto_item *item;
+ cba_ldev_t *cons_ldev;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ /* get corresponding provider ldev */
+ cons_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
+
+ /* length */
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_cb_length, &u32Length);
+
+ /* array size */
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /*** the data below is NOT ndr encoded (especially NOT aligned)!!! ***/
+ /* dissect PROFINET component data (without header) */
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
+
+ offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree, cons_ldev, NULL /* frame */);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoCallback_OnDataChanged_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ proto_item *item;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoCallback_Gnip_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ proto_item *item;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoCallback_Gnip_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ proto_item *item;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer2_GetConnectionData_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ proto_item *item;
+ cba_ldev_t *cons_ldev;
+ cba_ldev_t **call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_consumer, szStr, u32MaxStr);
+
+ cons_ldev = cba_acco_add(pinfo, szStr);
+
+ /* link ldev to the call */
+ if (cons_ldev != NULL) {
+ call = (cba_ldev_t **)wmem_alloc(wmem_file_scope(), sizeof(cba_ldev_t *));
+ *call = cons_ldev;
+ di->call_data->private_data = call;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServer2_GetConnectionData_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Length;
+ guint32 u32ArraySize;
+ tvbuff_t *next_tvb;
+ guint32 u32Pointer;
+ guint32 u32HResult;
+ proto_item *item;
+ cba_ldev_t **call = (cba_ldev_t **)di->call_data->private_data;
+ cba_ldev_t *cons_ldev = (call!=NULL) ? *call : NULL;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ if (cons_ldev == NULL) {
+ expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
+ }
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ proto_item_set_generated(item);
+ p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
+
+ /* length */
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_cb_length, &u32Length);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ /* array size */
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ /*** the data below is NOT ndr encoded (especially NOT aligned)!!! ***/
+ /* dissect PROFINET component data (without header) */
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
+
+ offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree, (call != NULL) ? *call : NULL, NULL /* frame */);
+
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_AddConnections_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szConsumer[1000] = { 0 };
+ guint32 u32MaxConsLen = sizeof(szConsumer);
+ guint16 u16QoSType;
+ guint16 u16QoSValue;
+ guint8 u8State;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Pointer;
+ guint16 u16Persistence;
+ gchar szConsItem[1000] = { 0 };
+ guint32 u32MaxConsItemLen = sizeof(szConsItem);
+ gchar szProvItem[1000] = { 0 };
+ guint32 u32MaxProvItemLen = sizeof(szProvItem);
+ guint32 u32VariableOffset;
+ guint32 u32SubStart;
+ guint32 u32Idx;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_provider, szConsumer, u32MaxConsLen);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_type, &u16QoSType);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32VariableOffset = offset + u32ArraySize * 20;
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_addconnectionin, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_addconnectionin);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen);
+ }
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_persist, &u16Persistence);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_substitute);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_epsilon);
+ }
+ proto_item_append_text(sub_item, "[%u]: ConsItem=\"%s\" ProvItem=\"%s\" %s Pers=%u",
+ u32Idx, szConsItem, szProvItem,
+ val_to_str(u16Persistence, cba_persist_vals, "Unknown (0x%02x)"), u16Persistence);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Prov=\"%s\" State=%s Cnt=%u",
+ szConsumer,
+ val_to_str(u8State, cba_acco_conn_state_vals, "Unknown (0x%02x)"),
+ u32Count);
+
+ return u32VariableOffset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_AddConnections_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32ConsID;
+ guint16 u16ConnVersion;
+ guint32 u32HResult = 0;
+ guint32 u32Count = 0;
+ guint32 u32Idx;
+ guint32 u32SubStart;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Count = u32ArraySize;
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_addconnectionout, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_addconnectionout);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_version, &u16ConnVersion);
+
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ proto_item_append_text(sub_item, "[%u]: ConsID=0x%x Version=%u %s",
+ u32Idx, u32ConsID, u16ConnVersion,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_RemoveConnections_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ConsID;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx);
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_SetActivationState_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint8 u8State;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ConsID;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx);
+ u32Idx++;
+ }
+
+ /* update column info now */
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_GetInfo_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Max;
+ guint32 u32CurCnt;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_info_max, &u32Max);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_info_curr, &u32CurCnt);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %u/%u -> %s",
+ u32CurCnt, u32Max,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_GetIDs_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32Pointer;
+ guint32 u32ArraySize;
+ guint32 u32ConsID;
+ guint8 u8State;
+ guint16 u16Version;
+ guint32 u32HResult;
+ guint32 u32Idx;
+ guint32 u32SubStart;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ if (u32Count) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ConsID=", u32Count);
+ } else {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_getidout, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_getidout);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID);
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_version, &u16Version);
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ proto_item_append_text(sub_item, "[%u]: ConsID=0x%x State=%s Version=%u %s",
+ u32Idx, u32ConsID,
+ val_to_str(u8State, cba_acco_conn_state_vals, "Unknown (0x%02x)"),
+ u16Version,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ if (u32Idx == 1) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ConsID);
+ } else if (u32Idx < 10) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ConsID);
+ } else if (u32Idx == 10) {
+ col_append_str(pinfo->cinfo, COL_INFO, ",...");
+ }
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt2_GetConsIDs_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32Pointer;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+ guint32 u32ConsID;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ if (u32Count) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ConsID=", u32Count);
+ } else {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo,
+ tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx);
+
+ if (u32Idx == 1) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ConsID);
+ } else if (u32Idx < 10) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ConsID);
+ } else if (u32Idx == 10) {
+ col_append_str(pinfo->cinfo, COL_INFO, ",...");
+ }
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt2_GetConsConnections_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32TmpCount;
+ guint32 u32Pointer;
+ guint32 u32HResult;
+
+ guint16 u16QoSType;
+ guint16 u16QoSValue;
+ guint8 u8State;
+ guint16 u16Persistence;
+ guint32 u32SubStart;
+ guint32 u32Idx;
+ guint32 u32VariableOffset;
+ gchar szProv[1000] = { 0 };
+ guint32 u32MaxProvLen = sizeof(szProv);
+ gchar szProvItem[1000] = { 0 };
+ guint32 u32MaxProvItemLen = sizeof(szProvItem);
+ gchar szConsItem[1000] = { 0 };
+ guint32 u32MaxConsItemLen = sizeof(szConsItem);
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ u32VariableOffset = offset;
+
+ if (u32Pointer) {
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ u32VariableOffset = offset + u32Count*32;
+
+ /* array fixed part (including pointers to variable part) */
+ u32TmpCount = u32Count;
+ u32Idx = 1;
+ while (u32TmpCount--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_getconsconnout, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_getconnectionout);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider, szProv, u32MaxProvLen);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_substitute);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_epsilon);
+ }
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_qos_type, &u16QoSType);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_persist, &u16Persistence);
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ proto_item_append_text(sub_item, "[%u]: %s",
+ u32Idx,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+ }
+
+ u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return u32VariableOffset;
+}
+
+
+static int
+dissect_ICBAAccoMgt2_DiagConsConnections_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32TmpCount;
+ guint32 u32Pointer;
+ guint32 u32HResult;
+ guint8 u8State;
+ guint16 u16Persistence;
+ guint16 u16ConnVersion;
+ guint32 u32SubStart;
+ guint32 u32Idx;
+ guint32 u32VariableOffset;
+ guint32 u32ConnErrorState;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ u32VariableOffset = offset;
+
+ if (u32Pointer) {
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ u32VariableOffset = offset + u32Count*16;
+
+ /* array fixed part (including pointers to variable part) */
+ u32TmpCount = u32Count;
+ u32Idx = 1;
+ while (u32TmpCount--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ proto_item *state_item;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_diagconsconnout, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_getconnectionout);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_persist, &u16Persistence);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_version, &u16ConnVersion);
+ /* connection state */
+#if 0
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_error_state, &u32ConnErrorState);
+#endif
+ offset = dissect_dcom_HRESULT_item(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32ConnErrorState, hf_cba_acco_conn_error_state, &state_item);
+ proto_item_set_text(state_item, "ConnErrorState: %s (0x%x)",
+ val_to_str(u32ConnErrorState, dcom_hresult_vals, "Unknown (0x%08x)"),
+ u32ConnErrorState);
+
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ proto_item_append_text(sub_item, "[%u]: %s",
+ u32Idx,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+ }
+
+ u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return u32VariableOffset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_GetConnections_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32ConsID;
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ guint32 u32Idx;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ while (u32ArraySize--){
+ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx);
+ u32Idx++;
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_GetConnections_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32TmpCount;
+ guint32 u32Pointer;
+ guint32 u32HResult;
+
+ guint16 u16QoSType;
+ guint16 u16QoSValue;
+ guint8 u8State;
+ guint16 u16Persistence;
+ guint16 u16ConnVersion;
+ guint32 u32SubStart;
+ guint32 u32Idx;
+ guint32 u32VariableOffset;
+ gchar szProv[1000] = { 0 };
+ guint32 u32MaxProvLen = sizeof(szProv);
+ gchar szProvItem[1000] = { 0 };
+ guint32 u32MaxProvItemLen = sizeof(szProvItem);
+ gchar szConsItem[1000] = { 0 };
+ guint32 u32MaxConsItemLen = sizeof(szConsItem);
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ u32VariableOffset = offset;
+
+ if (u32Pointer) {
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ u32VariableOffset = offset + u32Count*36;
+
+ /* array fixed part (including pointers to variable part) */
+ u32TmpCount = u32Count;
+ u32Idx = 1;
+ while (u32TmpCount--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_getconnectionout, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_getconnectionout);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider, szProv, u32MaxProvLen);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_substitute);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_epsilon);
+ }
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_qos_type, &u16QoSType);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_state, &u8State);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_persist, &u16Persistence);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_conn_version, &u16ConnVersion);
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ proto_item_append_text(sub_item, "[%u]: %s",
+ u32Idx,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+ }
+
+ u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return u32VariableOffset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_ReviseQoS_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16QoSType;
+ guint16 u16QoSValue;
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_rtauto, szStr, u32MaxStr);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_type, &u16QoSType);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": RTAuto=\"%s\" QoSType=%s QoSValue=%u",
+ szStr,
+ val_to_str(u16QoSType, cba_qos_type_vals, "Unknown (0x%04x)"),
+ u16QoSValue);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_ReviseQoS_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16QoSValue;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_conn_qos_value, &u16QoSValue);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %u -> %s",
+ u16QoSValue,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_get_PingFactor_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16PF;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_ping_factor, &u16PF);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %u -> %s",
+ u16PF,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_put_PingFactor_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16PF;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_ping_factor, &u16PF);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", u16PF);
+
+ return offset;
+}
+
+
+
+static int
+dissect_ICBAAccoMgt_get_CDBCookie_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Cookie;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_cdb_cookie, &u32Cookie);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": CDBCookie=0x%x -> %s",
+ u32Cookie,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_GetDiagnosis_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Request;
+ guint32 u32InLength;
+ guint32 u32ArraySize;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_diag_req, &u32Request);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_diag_in_length, &u32InLength);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ if (u32ArraySize != 0) {
+ proto_tree_add_item(tree, hf_cba_acco_diag_data, tvb, offset, u32InLength, ENC_NA);
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %s: %u bytes",
+ val_to_str(u32Request, cba_acco_diag_req_vals, "Unknown request (0x%08x)"),
+ u32InLength);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoMgt_GetDiagnosis_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32OutLength;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_diag_out_length, &u32OutLength);
+
+ if (u32OutLength != 0) {
+ proto_tree_add_item(tree, hf_cba_acco_diag_data, tvb, offset, u32OutLength, ENC_NA);
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %u bytes",
+ u32OutLength);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoSync_ReadItems_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ guint32 u32Pointer;
+ guint32 u32ArraySize;
+ guint32 u32VariableOffset;
+ guint32 u32Idx;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32VariableOffset = offset + u32ArraySize*4;
+
+ u32Idx = 1;
+ while (u32ArraySize--) {
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_indexed_LPWSTR(tvb, u32VariableOffset, pinfo, tree, di, drep,
+ hf_cba_acco_item, szStr, u32MaxStr, u32Idx);
+ }
+
+ u32Idx++;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return u32VariableOffset;
+}
+
+
+
+
+static int
+dissect_ICBAAccoSync_ReadItems_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Pointer;
+ guint16 u16QC;
+ guint32 u32ArraySize = 0;
+ guint32 u32HResult;
+ guint32 u32Idx;
+ guint32 u32SubStart;
+ guint32 u32VariableOffset;
+ guint32 u32Tmp;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ u32VariableOffset = offset;
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32VariableOffset = offset + u32ArraySize * 20;
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while(u32Tmp--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_readitemout, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_readitemout);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_data);
+ }
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_qc, &u16QC);
+ offset = dissect_dcom_FILETIME(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_time_stamp, NULL);
+
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32HResult, u32Idx);
+
+ proto_item_append_text(sub_item, "[%u]: QC=%s (0x%02x) %s",
+ u32Idx,
+ val_to_str_const(u16QC, cba_acco_qc_vals, "Unknown"),
+ u16QC,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+ }
+
+ u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return u32VariableOffset;
+}
+
+
+static int
+dissect_ICBAAccoSync_WriteItems_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ guint32 u32Pointer;
+ guint32 u32VariableOffset;
+ guint32 u32SubStart;
+ guint32 u32Idx;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32VariableOffset = offset + u32ArraySize * 8;
+ u32Idx = 1;
+ while(u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_writeitemin, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_writeitemin);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_item, szStr, u32MaxStr);
+ }
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_data);
+ }
+
+ proto_item_append_text(sub_item, "[%u]: Item=\"%s\"", u32Idx, szStr);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ u32Idx++;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return u32VariableOffset;
+}
+
+
+
+static int
+dissect_ICBAAccoSync_WriteItemsQCD_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32ArraySize;
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ guint32 u32Pointer;
+ guint32 u32VariableOffset;
+ guint32 u32SubStart;
+ guint32 u32Idx;
+ guint16 u16QC;
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_acco_count, &u32Count);
+
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
+ &u32ArraySize);
+
+ u32VariableOffset = offset + u32ArraySize * 20;
+ u32Idx = 1;
+ while(u32ArraySize--) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_cba_writeitemin, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_writeitemin);
+ u32SubStart = offset;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_item, szStr, u32MaxStr);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_data);
+ }
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_qc, &u16QC);
+
+ offset = dissect_dcom_FILETIME(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_acco_time_stamp, NULL);
+
+ proto_item_append_text(sub_item, "[%u]: Item=\"%s\" QC=%s (0x%02x)",
+ u32Idx, szStr,
+ val_to_str_const(u16QC, cba_acco_qc_vals, "Unknown"), u16QC);
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+ u32Idx++;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+
+ return u32VariableOffset;
+}
+
+
+/* sub dissector table of ICBAAccoMgt / ICBAAccoMgt2 interface */
+static dcerpc_sub_dissector ICBAAccoMgt_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "AddConnections", dissect_ICBAAccoMgt_AddConnections_rqst, dissect_ICBAAccoMgt_AddConnections_resp },
+ { 4, "RemoveConnections", dissect_ICBAAccoMgt_RemoveConnections_rqst, dissect_HResultArray_resp },
+ { 5, "ClearConnections", dissect_dcom_simple_rqst, dissect_dcom_simple_resp },
+ { 6, "SetActivationState", dissect_ICBAAccoMgt_SetActivationState_rqst, dissect_HResultArray_resp },
+ { 7, "GetInfo", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_GetInfo_resp },
+ { 8, "GetIDs", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_GetIDs_resp },
+ { 9, "GetConnections", dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt_GetConnections_resp },
+ {10, "ReviseQoS", dissect_ICBAAccoMgt_ReviseQoS_rqst, dissect_ICBAAccoMgt_ReviseQoS_resp },
+ {11, "get_PingFactor", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_get_PingFactor_resp },
+ {12, "put_PingFactor", dissect_ICBAAccoMgt_put_PingFactor_rqst, dissect_dcom_simple_resp },
+ {13, "get_CDBCookie", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_get_CDBCookie_resp },
+ /* stage 2 */
+ {14, "GetConsIDs", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt2_GetConsIDs_resp },
+ {15, "GetConsConnections", dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt2_GetConsConnections_resp },
+ {16, "DiagConsConnections", dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt2_DiagConsConnections_resp },
+ {17, "GetProvIDs", dissect_dcom_simple_rqst, dissect_Server_GetProvIDs_resp },
+ {18, "GetProvConnections", dissect_Server_GetProvConnections_rqst, dissect_Server_GetProvConnections_resp },
+ {19, "GetDiagnosis", dissect_ICBAAccoMgt_GetDiagnosis_rqst, dissect_ICBAAccoMgt_GetDiagnosis_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAAccoCallback interface */
+static dcerpc_sub_dissector ICBAAccoCallback_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "OnDataChanged", dissect_ICBAAccoCallback_OnDataChanged_rqst, dissect_ICBAAccoCallback_OnDataChanged_resp },
+ /* stage 2 */
+ { 4, "Gnip", dissect_ICBAAccoCallback_Gnip_rqst, dissect_ICBAAccoCallback_Gnip_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAAccoServer interface */
+static dcerpc_sub_dissector ICBAAccoServer_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "Connect", dissect_ICBAAccoServer_Connect_rqst, dissect_ICBAAccoServer_Connect_resp },
+ { 4, "Disconnect", dissect_ICBAAccoServer_Disconnect_rqst, dissect_ICBAAccoServer_Disconnect_resp },
+ { 5, "DisconnectMe", dissect_ICBAAccoServer_DisconnectMe_rqst, dissect_ICBAAccoServer_DisconnectMe_resp },
+ { 6, "SetActivation", dissect_ICBAAccoServer_SetActivation_rqst, dissect_ICBAAccoServer_SetActivation_resp },
+ { 7, "Ping", dissect_ICBAAccoServer_Ping_rqst, dissect_ICBAAccoServer_Ping_resp },
+ /* stage 2 */
+ { 8, "Connect2", dissect_ICBAAccoServer2_Connect2_rqst, dissect_ICBAAccoServer_Connect_resp },
+ { 9, "GetConnectionData", dissect_ICBAAccoServer2_GetConnectionData_rqst, dissect_ICBAAccoServer2_GetConnectionData_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAAccoServerSRT interface (stage 2 only) */
+static dcerpc_sub_dissector ICBAAccoServerSRT_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "ConnectCR", dissect_ICBAAccoServerSRT_ConnectCR_rqst, dissect_ICBAAccoServerSRT_ConnectCR_resp },
+ { 4, "DisconnectCR", dissect_ICBAAccoServerSRT_DisconnectCR_rqst, dissect_ICBAAccoServerSRT_DisconnectCR_resp },
+ { 5, "Connect", dissect_ICBAAccoServerSRT_Connect_rqst, dissect_ICBAAccoServerSRT_Connect_resp },
+ { 6, "Disconnect", dissect_ICBAAccoServerSRT_Disconnect_rqst, dissect_ICBAAccoServerSRT_Disconnect_resp },
+ { 7, "DisconnectMe", dissect_ICBAAccoServerSRT_DisconnectMe_rqst, dissect_ICBAAccoServerSRT_DisconnectMe_resp },
+ { 8, "SetActivation", dissect_ICBAAccoServerSRT_SetActivation_rqst, dissect_ICBAAccoServerSRT_SetActivation_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAAccoSync interface */
+static dcerpc_sub_dissector ICBAAccoSync_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "ReadItems", dissect_ICBAAccoSync_ReadItems_rqst, dissect_ICBAAccoSync_ReadItems_resp },
+ { 4, "WriteItems", dissect_ICBAAccoSync_WriteItems_rqst, dissect_HResultArray_resp },
+ { 5, "WriteItemsQCD", dissect_ICBAAccoSync_WriteItemsQCD_rqst, dissect_HResultArray_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* register protocol */
+void
+proto_register_dcom_cba_acco (void)
+{
+ static gint *ett3[3];
+ static gint *ett4[4];
+ static gint *ett5[5];
+
+
+ static hf_register_info hf_cba_acco_array[] = {
+ { &hf_cba_acco_opnum,
+ { "Operation", "cba.acco.opnum",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_ping_factor,
+ { "PingFactor", "cba.acco.ping_factor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_count,
+ { "Count", "cba.acco.count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_info_max,
+ { "Max", "cba.acco.info_max",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_info_curr,
+ { "Current", "cba.acco.info_curr",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_rtauto,
+ { "RTAuto", "cba.acco.rtauto",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_item,
+ { "Item", "cba.acco.item",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_data,
+ { "Data", "cba.acco.data",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_qc,
+ { "QualityCode", "cba.acco.qc",
+ FT_UINT8, BASE_HEX, VALS(cba_acco_qc_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_time_stamp,
+ { "TimeStamp", "cba.acco.time_stamp",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_readitemout,
+ { "ReadItemOut", "cba.acco.readitemout",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_writeitemin,
+ { "WriteItemIn", "cba.acco.writeitemin",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cdb_cookie,
+ { "CDBCookie", "cba.acco.cdb_cookie",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ /* dcom_hresult_vals from packet-dcom.h doesn't work here, as length is unknown! */
+ { &hf_cba_acco_conn_error_state,
+ { "ConnErrorState", "cba.acco.conn_error_state",
+ FT_UINT32, BASE_HEX, NULL /*VALS(dcom_hresult_vals)*/, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_diag_req,
+ { "Request", "cba.acco.diag_req",
+ FT_UINT32, BASE_HEX, VALS(cba_acco_diag_req_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_diag_in_length,
+ { "InLength", "cba.acco.diag_in_length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_diag_out_length,
+ { "OutLength", "cba.acco.diag_out_length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_diag_data,
+ { "Data", "cba.acco.diag_data",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_dcom_call,
+ { "DcomRuntime", "cba.acco.dcom",
+ FT_BOOLEAN, BASE_NONE, TFS(&cba_acco_call_flags), 0x0,
+ "This is a DCOM runtime context", HFILL }
+ },
+ { &hf_cba_acco_srt_call,
+ { "SrtRuntime", "cba.acco.srt",
+ FT_BOOLEAN, BASE_NONE, TFS(&cba_acco_call_flags), 0x0,
+ "This is an SRT runtime context", HFILL }
+ }
+
+ };
+
+ static hf_register_info hf_cba_acco_server[] = {
+#if 0
+ { &hf_cba_acco_server_pICBAAccoCallback,
+ { "pICBAAccoCallback", "cba.acco.server_pICBAAccoCallback",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+#endif
+ { &hf_cba_acco_server_first_connect,
+ { "FirstConnect", "cba.acco.server_first_connect",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_getprovconnout,
+ { "GETPROVCONNOUT", "cba.acco.getprovconnout",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_serversrt_prov_mac,
+ { "ProviderMAC", "cba.acco.serversrt_prov_mac",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_serversrt_cons_mac,
+ { "ConsumerMAC", "cba.acco.serversrt_cons_mac",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_serversrt_cr_id,
+ { "ConsumerCRID", "cba.acco.serversrt_cr_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_serversrt_cr_length,
+ { "CRLength", "cba.acco.serversrt_cr_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_serversrt_cr_flags,
+ { "Flags", "cba.acco.serversrt_cr_flags",
+ FT_UINT32, BASE_HEX, 0, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_serversrt_cr_flags_timestamped,
+ { "Timestamped", "cba.acco.serversrt_cr_flags_timestamped",
+ FT_BOOLEAN, 32, TFS (&acco_flags_set_truth), 0x1,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_serversrt_cr_flags_reconfigure,
+ { "Reconfigure", "cba.acco.serversrt_cr_flags_reconfigure",
+ FT_BOOLEAN, 32, TFS (&acco_flags_set_truth), 0x2,
+ NULL, HFILL }
+ },
+ { &hf_cba_type_desc_len,
+ { "TypeDescLen", "cba.acco.type_desc_len",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_serversrt_record_length,
+ { "RecordLength", "cba.acco.serversrt_record_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+#if 0
+ { &hf_cba_acco_serversrt_action,
+ { "Action", "cba.acco.serversrt_action",
+ FT_UINT32, BASE_DEC, VALS(cba_acco_serversrt_action_vals), 0x0,
+ NULL, HFILL }
+ },
+#endif
+ { &hf_cba_acco_serversrt_last_connect,
+ { "LastConnect", "cba.acco.serversrt_last_connect",
+ FT_UINT8, BASE_DEC, VALS(cba_acco_serversrt_last_connect_vals), 0x0,
+ NULL, HFILL }
+ },
+ };
+
+ static hf_register_info hf_cba_connectcr_array[] = {
+ { &hf_cba_acco_prov_crid,
+ { "ProviderCRID", "cba.acco.prov_crid",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ };
+
+ static hf_register_info hf_cba_connect_array[] = {
+ { &hf_cba_addconnectionin,
+ { "ADDCONNECTIONIN", "cba.acco.addconnectionin",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_addconnectionout,
+ { "ADDCONNECTIONOUT", "cba.acco.addconnectionout",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_getidout,
+ { "GETIDOUT", "cba.acco.getidout",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_getconnectionout,
+ { "GETCONNECTIONOUT", "cba.acco.getconnectionout",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_getconsconnout,
+ { "GETCONSCONNOUT", "cba.acco.getconsconnout",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_diagconsconnout,
+ { "DIAGCONSCONNOUT", "cba.acco.diagconsconnout",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_connectincr,
+ { "CONNECTINCR", "cba.acco.connectincr",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_connectoutcr,
+ { "CONNECTOUTCR", "cba.acco.connectoutcr",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_connectin,
+ { "CONNECTIN", "cba.acco.connectin",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_connectout,
+ { "CONNECTOUT", "cba.acco.connectout",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_prov_id,
+ { "ProviderID", "cba.acco.conn_prov_id",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_cons_id,
+ { "ConsumerID", "cba.acco.conn_cons_id",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_version,
+ { "ConnVersion", "cba.acco.conn_version",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_consumer,
+ { "Consumer", "cba.acco.conn_consumer",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_qos_type,
+ { "QoSType", "cba.acco.conn_qos_type",
+ FT_UINT16, BASE_HEX, VALS(cba_qos_type_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_qos_value,
+ { "QoSValue", "cba.acco.conn_qos_value",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_state,
+ { "State", "cba.acco.conn_state",
+ FT_UINT8, BASE_HEX, VALS(cba_acco_conn_state_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_provider,
+ { "Provider", "cba.acco.conn_provider",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_provider_item,
+ { "ProviderItem", "cba.acco.conn_provider_item",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_consumer_item,
+ { "ConsumerItem", "cba.acco.conn_consumer_item",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_persist,
+ { "Persistence", "cba.acco.conn_persist",
+ FT_UINT16, BASE_HEX, VALS(cba_persist_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_epsilon,
+ { "Epsilon", "cba.acco.conn_epsilon",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_conn_substitute,
+ { "Substitute", "cba.acco.conn_substitute",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ };
+
+ static hf_register_info hf_cba_acco_cb[] = {
+ { &hf_cba_acco_cb_length,
+ { "Length", "cba.acco.cb_length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cb_version,
+ { "Version", "cba.acco.cb_version",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cb_flags,
+ { "Flags", "cba.acco.cb_flags",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cb_count,
+ { "Count", "cba.acco.cb_count",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cb_conn_data,
+ { "CBA Connection data", "cba.acco.cb_conn_data",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cb_item,
+ { "Item", "cba.acco.cb_item",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cb_item_hole,
+ { "Hole", "cba.acco.cb_item_hole",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cb_item_length,
+ { "Length", "cba.acco.cb_item_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_acco_cb_item_data,
+ { "Data(Hex)", "cba.acco.cb_item_data",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_cba_connect_in,
+ { "Connect in frame", "cba.connect_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0,
+ "This connection Connect was in the packet with this number", HFILL }
+ },
+ { &hf_cba_disconnect_in,
+ { "Disconnect in frame", "cba.disconnect_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0,
+ "This connection Disconnect was in the packet with this number", HFILL }
+ },
+ { &hf_cba_connectcr_in,
+ { "ConnectCR in frame", "cba.connect_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0,
+ "This frame ConnectCR was in the packet with this number", HFILL }
+ },
+ { &hf_cba_disconnectcr_in,
+ { "DisconnectCR in frame", "cba.disconnect_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0,
+ "This frame DisconnectCR was in the packet with this number", HFILL }
+ },
+ { &hf_cba_disconnectme_in,
+ { "DisconnectMe in frame", "cba.disconnectme_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0,
+ "This connection/frame DisconnectMe was in the packet with this number", HFILL }
+ },
+ { &hf_cba_data_first_in,
+ { "First data in frame", "cba.data_first_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0,
+ "The first data of this connection/frame in the packet with this number", HFILL }
+ },
+ { &hf_cba_data_last_in,
+ { "Last data in frame", "cba.data_last_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0,
+ "The last data of this connection/frame in the packet with this number", HFILL }
+ },
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_cba_acco_pdev_find, { "cba.acco.pdev_find.fail", PI_UNDECODED, PI_NOTE, "pdev_find: no pdev for IP", EXPFILL }},
+ { &ei_cba_acco_pdev_find_unknown_interface, { "cba.acco.pdev_find.unknown_interface", PI_UNDECODED, PI_NOTE, "pdev_find: unknown interface", EXPFILL }},
+ { &ei_cba_acco_ldev_unknown, { "cba.acco.ldev.unknown", PI_UNDECODED, PI_NOTE, "Unknown LDev", EXPFILL }},
+ { &ei_cba_acco_ipid_unknown, { "cba.acco.ipid.unknown", PI_UNDECODED, PI_NOTE, "Unknown IPID", EXPFILL }},
+ { &ei_cba_acco_prov_crid, { "cba.acco.prov_crid.unknown", PI_UNDECODED, PI_NOTE, "Unknown provider frame ProvCRID", EXPFILL }},
+ { &ei_cba_acco_conn_consumer, { "cba.acco.conn_consumer.invalid", PI_UNDECODED, PI_NOTE, "Consumer interface invalid", EXPFILL }},
+ { &ei_cba_acco_no_request_info, { "cba.acco.no_request_info", PI_UNDECODED, PI_NOTE, "No request info, response data ignored", EXPFILL }},
+ { &ei_cba_acco_qc, { "cba.acco.qc.expert", PI_RESPONSE_CODE, PI_CHAT, "expert QC", EXPFILL }},
+ { &ei_cba_acco_disconnect, { "cba.acco.disconnect", PI_SEQUENCE, PI_NOTE, "Disconnection sequence issue", EXPFILL }},
+ { &ei_cba_acco_connect, { "cba.acco.connect_not_set", PI_SEQUENCE, PI_NOTE, "packet_connect not set", EXPFILL }},
+ };
+
+ expert_module_t* expert_cba_acco;
+
+ ett5[0] = &ett_ICBAAccoMgt;
+ ett5[1] = &ett_cba_addconnectionin;
+ ett5[2] = &ett_cba_addconnectionout;
+ ett5[3] = &ett_cba_getidout;
+ ett5[4] = &ett_cba_getconnectionout;
+ proto_ICBAAccoMgt = proto_register_protocol ("ICBAAccoMgt", "ICBAAccoMgt", "cba_acco_mgt");
+ proto_register_field_array(proto_ICBAAccoMgt, hf_cba_acco_array, array_length(hf_cba_acco_array));
+ proto_register_field_array(proto_ICBAAccoMgt, hf_cba_connect_array, array_length(hf_cba_connect_array));
+ proto_register_field_array(proto_ICBAAccoMgt, hf_cba_connectcr_array, array_length(hf_cba_connectcr_array));
+ proto_register_subtree_array (ett5, array_length (ett5));
+
+ /* XXX - just pick a protocol to register the expert info in */
+ /* XXX - also, just pick a protocol to use proto_data for */
+ expert_cba_acco = expert_register_protocol(proto_ICBAAccoMgt);
+ expert_register_field_array(expert_cba_acco, ei, array_length(ei));
+
+ proto_ICBAAccoMgt2 = proto_register_protocol ("ICBAAccoMgt2", "ICBAAccoMgt2", "cba_acco_mgt2");
+
+ ett3[0] = &ett_ICBAAccoCallback;
+ ett3[1] = &ett_ICBAAccoCallback_Item;
+ ett3[2] = &ett_ICBAAccoCallback_Buffer;
+ proto_ICBAAccoCallback = proto_register_protocol ("ICBAAccoCallback", "ICBAAccoCB", "cba_acco_cb");
+ proto_register_field_array(proto_ICBAAccoCallback, hf_cba_acco_cb, array_length(hf_cba_acco_cb));
+ proto_register_subtree_array (ett3, array_length (ett3));
+
+ proto_ICBAAccoCallback2 = proto_register_protocol ("ICBAAccoCallback2", "ICBAAccoCB2", "cba_acco_cb2");
+
+ ett4[0] = &ett_ICBAAccoServer;
+ ett4[1] = &ett_cba_connectin;
+ ett4[2] = &ett_cba_connectout;
+ ett4[3] = &ett_cba_getprovconnout;
+ proto_ICBAAccoServer = proto_register_protocol ("ICBAAccoServer", "ICBAAccoServ", "cba_acco_server");
+ proto_register_field_array(proto_ICBAAccoServer, hf_cba_acco_server, array_length(hf_cba_acco_server));
+ proto_register_subtree_array (ett4, array_length (ett4));
+
+ proto_ICBAAccoServer2 = proto_register_protocol ("ICBAAccoServer2", "ICBAAccoServ2", "cba_acco_server2");
+
+ ett4[0] = &ett_ICBAAccoServerSRT;
+ ett4[1] = &ett_cba_acco_serversrt_cr_flags;
+ ett4[2] = &ett_cba_connectincr;
+ ett4[3] = &ett_cba_connectoutcr;
+ proto_ICBAAccoServerSRT = proto_register_protocol ("ICBAAccoServerSRT", "ICBAAccoServSRT", "cba_acco_server_srt");
+ proto_register_subtree_array (ett4, array_length (ett4));
+
+ ett5[0] = &ett_ICBAAccoSync;
+ ett5[1] = &ett_cba_readitemout;
+ ett5[2] = &ett_cba_writeitemin;
+ ett5[3] = &ett_cba_frame_info;
+ ett5[4] = &ett_cba_conn_info;
+ proto_ICBAAccoSync = proto_register_protocol ("ICBAAccoSync", "ICBAAccoSync", "cba_acco_sync");
+ proto_register_subtree_array (ett5, array_length (ett5));
+
+ register_conversation_filter("cba", "PN-CBA", cba_filter_valid, cba_build_filter, NULL);
+}
+
+
+/* handoff protocol */
+void
+proto_reg_handoff_dcom_cba_acco (void)
+{
+ /* Register the interfaces */
+ dcerpc_init_uuid(proto_ICBAAccoMgt, ett_ICBAAccoMgt,
+ &uuid_ICBAAccoMgt, ver_ICBAAccoMgt, ICBAAccoMgt_dissectors, hf_cba_acco_opnum);
+
+ dcerpc_init_uuid(proto_ICBAAccoMgt2, ett_ICBAAccoMgt,
+ &uuid_ICBAAccoMgt2, ver_ICBAAccoMgt2, ICBAAccoMgt_dissectors, hf_cba_acco_opnum);
+
+ dcerpc_init_uuid(proto_ICBAAccoCallback, ett_ICBAAccoCallback,
+ &uuid_ICBAAccoCallback, ver_ICBAAccoCallback, ICBAAccoCallback_dissectors, hf_cba_acco_opnum);
+
+ dcerpc_init_uuid(proto_ICBAAccoCallback2, ett_ICBAAccoCallback,
+ &uuid_ICBAAccoCallback2, ver_ICBAAccoCallback2, ICBAAccoCallback_dissectors, hf_cba_acco_opnum);
+
+ dcerpc_init_uuid(proto_ICBAAccoServer, ett_ICBAAccoServer,
+ &uuid_ICBAAccoServer, ver_ICBAAccoServer, ICBAAccoServer_dissectors, hf_cba_acco_opnum);
+
+ dcerpc_init_uuid(proto_ICBAAccoServer2, ett_ICBAAccoServer,
+ &uuid_ICBAAccoServer2, ver_ICBAAccoServer2, ICBAAccoServer_dissectors, hf_cba_acco_opnum);
+
+ dcerpc_init_uuid(proto_ICBAAccoServerSRT, ett_ICBAAccoServerSRT,
+ &uuid_ICBAAccoServerSRT, ver_ICBAAccoServerSRT, ICBAAccoServerSRT_dissectors, hf_cba_acco_opnum);
+
+ dcerpc_init_uuid(proto_ICBAAccoSync, ett_ICBAAccoSync,
+ &uuid_ICBAAccoSync, ver_ICBAAccoSync, ICBAAccoSync_dissectors, hf_cba_acco_opnum);
+
+
+ heur_dissector_add("pn_rt", dissect_CBA_Connection_Data_heur, "PROFINET CBA IO", "pn_cba_pn_rt", proto_ICBAAccoServer, HEURISTIC_ENABLE);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-dcom-cba-acco.h b/plugins/epan/profinet/packet-dcom-cba-acco.h
new file mode 100644
index 0000000..3171124
--- /dev/null
+++ b/plugins/epan/profinet/packet-dcom-cba-acco.h
@@ -0,0 +1,59 @@
+/* packet-dcom-cba-acco.h
+ * Routines for DCOM CBA
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef __PACKET_DCERPC_DCOM_CBA_ACCO_H
+#define __PACKET_DCERPC_DCOM_CBA_ACCO_H
+
+typedef struct cba_pdev_s {
+ GList *ldevs;
+ dcom_object_t *object;
+ gint first_packet;
+
+ guint8 ip[4];
+} cba_pdev_t;
+
+typedef struct cba_ldev_s {
+ GList *provframes;
+ GList *consframes;
+ GList *provconns;
+ GList *consconns;
+ dcom_object_t *ldev_object;
+ dcom_object_t *acco_object;
+ cba_pdev_t *parent;
+ gint first_packet;
+
+ const char *name;
+} cba_ldev_t;
+
+
+extern GList *cba_pdevs;
+
+extern cba_pdev_t *
+cba_pdev_find(packet_info *pinfo, const address *addr, e_guid_t *ipid);
+
+extern void
+cba_pdev_link(packet_info *pinfo, cba_pdev_t *pdev, dcom_interface_t *pdev_interf);
+
+extern cba_pdev_t *
+cba_pdev_add(packet_info *pinfo, const address *addr);
+
+extern void
+cba_ldev_link(packet_info *pinfo, cba_ldev_t *ldev, dcom_interface_t *ldev_interf);
+
+extern void
+cba_ldev_link_acco(packet_info *pinfo, cba_ldev_t *ldev, dcom_interface_t *acco_interf);
+
+extern cba_ldev_t *
+cba_ldev_find(packet_info *pinfo, const address *addr, e_guid_t *ipid);
+
+extern cba_ldev_t *
+cba_ldev_add(packet_info *pinfo, cba_pdev_t *pdev, const char *name);
+
+#endif /* packet-dcerpc-dcom-cba-acco.h */
diff --git a/plugins/epan/profinet/packet-dcom-cba.c b/plugins/epan/profinet/packet-dcom-cba.c
new file mode 100644
index 0000000..52c5017
--- /dev/null
+++ b/plugins/epan/profinet/packet-dcom-cba.c
@@ -0,0 +1,1730 @@
+/* packet-dcom-cba.c
+ * Routines for DCOM CBA
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <epan/dissectors/packet-dcerpc.h>
+#include <epan/dissectors/packet-dcom.h>
+#include <epan/dissectors/packet-dcom-dispatch.h>
+#include "packet-dcom-cba-acco.h"
+
+void proto_register_dcom_cba(void);
+void proto_reg_handoff_dcom_cba(void);
+
+static int hf_cba_opnum = -1;
+
+static int hf_cba_revision_major = -1;
+static int hf_cba_revision_minor = -1;
+static int hf_cba_revision_service_pack = -1;
+static int hf_cba_revision_build = -1;
+
+static int hf_cba_time = -1;
+
+static int hf_cba_name = -1;
+static int hf_cba_producer = -1;
+static int hf_cba_product = -1;
+static int hf_cba_production_date = -1;
+static int hf_cba_serial_no = -1;
+static int hf_cba_multi_app = -1;
+static int hf_cba_profinet_dcom_stack = -1;
+static int hf_cba_pdev_stamp = -1;
+
+static int hf_cba_browse_count = -1;
+static int hf_cba_browse_offset = -1;
+static int hf_cba_browse_max_return = -1;
+static int hf_cba_browse_item = -1;
+static int hf_cba_browse_data_type = -1;
+static int hf_cba_browse_access_right = -1;
+static int hf_cba_browse_selector = -1;
+static int hf_cba_browse_info1 = -1;
+static int hf_cba_browse_info2 = -1;
+
+static int hf_cba_cookie = -1;
+static int hf_cba_state = -1;
+static int hf_cba_new_state = -1;
+static int hf_cba_old_state = -1;
+static int hf_cba_grouperror = -1;
+static int hf_cba_new_grouperror = -1;
+static int hf_cba_old_grouperror = -1;
+
+static int hf_cba_component_id = -1;
+static int hf_cba_component_version = -1;
+static int hf_cba_pbaddress = -1;
+static int hf_cba_pbaddress_system_id = -1;
+static int hf_cba_pbaddress_address = -1;
+
+static int hf_cba_save_ldev_name = -1;
+static int hf_cba_save_result = -1;
+
+static expert_field ei_cba_acco_interface_pointer_unresolved = EI_INIT;
+
+static e_guid_t uuid_coclass_CBAPhysicalDevice = { 0xcba00000, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+
+
+/* CBA interfaces */
+static int proto_ICBAPhysicalDevice = -1;
+static gint ett_ICBAPhysicalDevice = -1;
+static e_guid_t uuid_ICBAPhysicalDevice = { 0xcba00001, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAPhysicalDevice = 0;
+
+static int proto_ICBAPhysicalDevice2 = -1;
+static e_guid_t uuid_ICBAPhysicalDevice2 = { 0xcba00006, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAPhysicalDevice2 = 0;
+
+static int proto_ICBABrowse = -1;
+static gint ett_ICBABrowse = -1;
+static e_guid_t uuid_ICBABrowse = { 0xcba00002, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBABrowse = 0;
+
+static int proto_ICBABrowse2 = -1;
+static e_guid_t uuid_ICBABrowse2 = { 0xcba00007, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBABrowse2 = 0;
+
+static int proto_ICBAPhysicalDevicePC = -1;
+static gint ett_ICBAPhysicalDevicePC = -1;
+static e_guid_t uuid_ICBAPhysicalDevicePC = { 0xcba00003, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAPhysicalDevicePC = 0;
+
+static int proto_ICBAPhysicalDevicePCEvent = -1;
+static gint ett_ICBAPhysicalDevicePCEvent = -1;
+static e_guid_t uuid_ICBAPhysicalDevicePCEvent = { 0xcba00004, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAPhysicalDevicePCEvent = 0;
+
+static int proto_ICBAPersist = -1;
+static gint ett_ICBAPersist = -1;
+static e_guid_t uuid_ICBAPersist = { 0xcba00005, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAPersist = 0;
+
+static int proto_ICBAPersist2 = -1;
+static e_guid_t uuid_ICBAPersist2 = { 0xcba00008, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAPersist2 = 0;
+
+static int proto_ICBALogicalDevice = -1;
+static gint ett_ICBALogicalDevice = -1;
+static e_guid_t uuid_ICBALogicalDevice = { 0xcba00011, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBALogicalDevice = 0;
+
+static int proto_ICBALogicalDevice2 = -1;
+static e_guid_t uuid_ICBALogicalDevice2 = { 0xcba00017, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBALogicalDevice2 = 0;
+
+static int proto_ICBAState = -1;
+static gint ett_ICBAState = -1;
+static e_guid_t uuid_ICBAState = { 0xcba00012, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAState = 0;
+
+static int proto_ICBAStateEvent = -1;
+static gint ett_ICBAStateEvent = -1;
+static e_guid_t uuid_ICBAStateEvent = { 0xcba00013, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAStateEvent = 0;
+
+static int proto_ICBATime = -1;
+static gint ett_ICBATime = -1;
+static e_guid_t uuid_ICBATime = { 0xcba00014, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBATime = 0;
+
+static int proto_ICBAGroupError = -1;
+static gint ett_ICBAGroupError = -1;
+static e_guid_t uuid_ICBAGroupError = { 0xcba00015, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAGroupError = 0;
+
+static int proto_ICBAGroupErrorEvent = -1;
+static gint ett_ICBAGroupErrorEvent = -1;
+static e_guid_t uuid_ICBAGroupErrorEvent = { 0xcba00016, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBAGroupErrorEvent = 0;
+
+static int proto_ICBARTAuto = -1;
+static gint ett_ICBARTAuto = -1;
+static e_guid_t uuid_ICBARTAuto = { 0xcba00051, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBARTAuto = 0;
+
+static int proto_ICBARTAuto2 = -1;
+static e_guid_t uuid_ICBARTAuto2 = { 0xcba00052, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBARTAuto2 = 0;
+
+static int proto_ICBASystemProperties = -1;
+static gint ett_ICBASystemProperties = -1;
+static e_guid_t uuid_ICBASystemProperties = { 0xcba00062, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
+static guint16 ver_ICBASystemProperties = 0;
+
+
+static gint ett_PBAddress = -1;
+
+
+static const value_string cba_state_vals[] = {
+ { 0x00, "NonExistent" },
+ { 0x01, "Initializing" },
+ { 0x02, "Ready" },
+ { 0x03, "Operating" },
+ { 0x04, "Defect" },
+ { 0, NULL }
+};
+
+
+static const value_string cba_grouperror_vals[] = {
+ { 0x00, "NonAccessible" },
+ { 0x01, "Okay" },
+ { 0x02, "Problem" },
+ { 0x03, "Unknown" },
+ { 0x04, "MaintenanceRequired" },
+ { 0x05, "MaintenanceDemanded" },
+ { 0x06, "MaintenanceRequiredAndDemanded" },
+ { 0x07, "ProblemAndMaintenanceRequired" },
+ { 0x08, "ProblemAndMaintenanceDemanded" },
+ { 0x09, "ProblemAndMaintenanceRequiredAndDemanded" },
+ { 0, NULL }
+};
+
+static const value_string dcom_boolean_vals[] = {
+ { 0x00, "FALSE" },
+ { 0x01, "TRUE" },
+ { 0xffff, "TRUE" },
+ { 0, NULL }
+};
+
+
+
+
+static int
+dissect_ICBABrowse_get_Count_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Count;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_browse_count, &u32Count);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ if (u32HResult) { /* !S_OK */
+ col_append_fstr(pinfo->cinfo, COL_INFO, "-> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ } else {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Cnt=%u -> S_OK", u32Count);
+ }
+
+
+ return offset;
+}
+
+
+static int
+dissect_ICBABrowse_BrowseItems_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Offset;
+ guint32 u32MaxReturn;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_browse_offset, &u32Offset);
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_browse_max_return, &u32MaxReturn);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Offset=%u MaxReturn=%u",
+ u32Offset, u32MaxReturn);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBABrowse_BrowseItems_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Pointer;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep, hf_cba_browse_item);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep, hf_cba_browse_data_type);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep, hf_cba_browse_access_right);
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBABrowse2_get_Count2_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Selector;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_browse_selector, &u32Selector);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Selector=%u",
+ u32Selector);
+
+ return offset;
+}
+
+
+
+static int
+dissect_ICBABrowse2_BrowseItems2_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Selector;
+ guint32 u32Offset;
+ guint32 u32MaxReturn;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_browse_selector, &u32Selector);
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_browse_offset, &u32Offset);
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_browse_max_return, &u32MaxReturn);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Sel=%u Offset=%u MaxReturn=%u",
+ u32Selector, u32Offset, u32MaxReturn);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBABrowse2_BrowseItems2_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Pointer;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep, hf_cba_browse_item);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep, hf_cba_browse_info1);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep, hf_cba_browse_info2);
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAPersist2_Save2_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Pointer;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep, hf_cba_save_ldev_name);
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep, hf_cba_save_result);
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+
+static int
+dissect_get_BSTR_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ guint32 u32Pointer;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, di, drep,
+ hfindex, szStr, u32MaxStr);
+ } else {
+ szStr[0] = '\0';
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\" -> %s", szStr,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_get_ProductionDate_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ gdouble r8Date;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DATE(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_production_date, &r8Date);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Date: %g -> %s",
+ r8Date,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_get_SerialNo_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_serial_no);
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBATime_get_Time_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ gdouble r8Date;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DATE(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_time, &r8Date);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Time: %g -> %s",
+ r8Date,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBATime_put_Time_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gdouble r8Date;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DATE(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_time, &r8Date);
+
+ return offset;
+}
+
+
+static int
+dissect_get_Producer_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+
+ return dissect_get_BSTR_resp(tvb, offset, pinfo, tree, di, drep, hf_cba_producer);
+}
+
+
+static int
+dissect_get_Product_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+
+ return dissect_get_BSTR_resp(tvb, offset, pinfo, tree, di, drep, hf_cba_product);
+}
+
+
+static int
+dissect_ICBAPhysicalDevice_get_LogicalDevice_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Pointer;
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ gchar *call;
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_name, szStr, u32MaxStr);
+ } else {
+ szStr[0] = '\0';
+ }
+
+ if (strlen(szStr) > 0) {
+ call = wmem_strdup(wmem_file_scope(), szStr);
+ di->call_data->private_data = call;
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"", szStr);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAPhysicalDevice_get_LogicalDevice_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ gchar *ldev_name = (gchar *)di->call_data->private_data;
+ dcom_interface_t *pdev_interf;
+ dcom_interface_t *ldev_interf;
+ cba_pdev_t *pdev;
+ cba_ldev_t *ldev;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &ldev_interf);
+
+ /* try to read the ldev name from the request */
+ if (ldev_name != NULL && ldev_interf != NULL) {
+ /* XXX - this is a hack to create a pdev interface */
+ /* as I currently don't understand the objref process for a root interface! */
+ pdev_interf = dcom_interface_new(pinfo, &pinfo->net_dst, &uuid_ICBAPhysicalDevice, 0, 0, &di->call_data->object_uuid);
+ if (pdev_interf != NULL) {
+ pdev = cba_pdev_add(pinfo, &pinfo->net_dst);
+ cba_pdev_link(pinfo, pdev, pdev_interf);
+
+ ldev = cba_ldev_add(pinfo, pdev, ldev_name);
+ cba_ldev_link(pinfo, ldev, ldev_interf);
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAPhysicalDevice2_Type_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16MultiApp;
+ guint16 u16PROFInetDCOMStack;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_VARIANT_BOOL(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_multi_app, &u16MultiApp);
+
+ offset = dissect_dcom_VARIANT_BOOL(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_profinet_dcom_stack, &u16PROFInetDCOMStack);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " App=%s Stack=%s -> %s",
+ (u16MultiApp) ? "Multi" : "Single",
+ (u16PROFInetDCOMStack) ? "PN-DCOM" : "MS-DCOM",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_PROFInetRevision_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16Major;
+ guint16 u16Minor;
+ guint16 u16ServicePack;
+ guint16 u16Build;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_revision_major, &u16Major);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_revision_minor, &u16Minor);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_revision_service_pack, &u16ServicePack);
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_revision_build, &u16Build);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Revision=%u.%u.%u.%u -> %s",
+ u16Major, u16Minor, u16ServicePack, u16Build,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAPhysicalDevice2_get_PDevStamp_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32PDevStamp;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_pdev_stamp, &u32PDevStamp);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " PDevStamp=0x%x -> %s",
+ u32PDevStamp,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_Revision_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16Major;
+ guint16 u16Minor;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_revision_major, &u16Major);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_revision_minor, &u16Minor);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": %u.%u -> %s",
+ u16Major, u16Minor,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBALogicalDevice_get_Name_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ guint32 u32Pointer;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_name, szStr, u32MaxStr);
+ } else {
+ szStr[0] = '\0';
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\" -> %s", szStr,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_RTAuto_get_Name_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+
+ return dissect_get_BSTR_resp(tvb, offset, pinfo, tree, di, drep, hf_cba_name);
+}
+
+
+static int
+dissect_ICBALogicalDevice_get_ACCO_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+ dcom_interface_t *acco_interf;
+ cba_ldev_t *ldev;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &acco_interf);
+ if (acco_interf == NULL) {
+ expert_add_info(pinfo, NULL, &ei_cba_acco_interface_pointer_unresolved);
+ }
+
+ ldev = cba_ldev_find(pinfo, &pinfo->net_src, &di->call_data->object_uuid);
+
+ /* "crosslink" interface and its object */
+ if (ldev != NULL && acco_interf != NULL) {
+ cba_ldev_link_acco(pinfo, ldev, acco_interf);
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBALogicalDevice_get_RTAuto_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, NULL);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBALogicalDevice_Get_RTAuto_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ guint32 u32Pointer;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_name, szStr, u32MaxStr);
+ } else {
+ szStr[0] = '\0';
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"", szStr);
+
+ return offset;
+}
+
+
+
+static int
+dissect_ComponentInfo_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ gchar szStr2[1000];
+ guint32 u32MaxStr2 = sizeof(szStr2);
+ guint32 u32HResult;
+ guint32 u32Pointer;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_component_id, szStr, u32MaxStr);
+ } else {
+ szStr[0] = '\0';
+ }
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_component_version, szStr2, u32MaxStr2);
+ } else {
+ szStr2[0] = '\0';
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": ID=\"%s\" Version=\"%s\" -> %s",
+ szStr, szStr2,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static void
+dissect_PBAddressInfo(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ guint32 u32VarType _U_, guint32 u32ArraySize)
+{
+ guint8 u8ID;
+ guint8 u8Addr;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+
+ while (u32ArraySize != 0) {
+ sub_item = proto_tree_add_item(tree, hf_cba_pbaddress, tvb, offset, 2, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_PBAddress);
+
+ offset = dissect_dcom_BYTE(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_pbaddress_system_id, &u8ID);
+ offset = dissect_dcom_BYTE(tvb, offset, pinfo, sub_tree, di, drep,
+ hf_cba_pbaddress_address, &u8Addr);
+ u32ArraySize-=2;
+
+ proto_item_append_text(sub_item, ": ID=0x%x Addr=%u", u8ID, u8Addr);
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", ID=0x%x Addr=%u",
+ u8ID, u8Addr);
+ }
+}
+
+
+static int
+dissect_PBAddressInfo_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32HResult;
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_SAFEARRAY(tvb, offset, pinfo, tree, di, drep, 0 /*hfindex _U_ */, dissect_PBAddressInfo);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_Advise_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, NULL);
+
+ return offset;
+}
+
+
+static int
+dissect_Advise_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Cookie;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_cookie, &u32Cookie);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cookie=0x%x -> %s",
+ u32Cookie,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_Unadvise_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Cookie;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_cookie, &u32Cookie);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cookie=0x%x",
+ u32Cookie);
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAState_get_State_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16State;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_state, &u16State);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": State=%s -> %s",
+ val_to_str(u16State, cba_state_vals, "Unknown (0x%08x)"),
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAStateEvent_OnStateChanged_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16NewState;
+ guint16 u16OldState;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_new_state, &u16NewState);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_old_state, &u16OldState);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": NewState=%s OldState=%s",
+ val_to_str(u16NewState, cba_state_vals, "Unknown (0x%04x)"),
+ val_to_str(u16OldState, cba_state_vals, "Unknown (0x%04x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAGroupError_OnGroupErrorChanged_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16NewGroupError;
+ guint16 u16OldGroupError;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_new_grouperror, &u16NewGroupError);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_old_grouperror, &u16OldGroupError);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": NewGE=%s OldGE=%s",
+ val_to_str(u16NewGroupError, cba_grouperror_vals, "Unknown (0x%04x)"),
+ val_to_str(u16OldGroupError, cba_grouperror_vals, "Unknown (0x%04x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAPhysicalDevicePCEvent_OnLogicalDeviceAdded_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint32 u32Cookie;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_cookie, &u32Cookie);
+
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, NULL);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cookie=0x%x %s",
+ u32Cookie,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAGroupError_GroupError_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
+{
+ guint16 u16GroupError;
+ guint32 u32Cookie;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
+
+ offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_grouperror, &u16GroupError);
+
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
+ hf_cba_cookie, &u32Cookie);
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
+ &u32HResult);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": GroupError=%s Cookie=0x%x -> %s",
+ val_to_str(u16GroupError, cba_grouperror_vals, "Unknown (0x%08x)"),
+ u32Cookie,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+
+ return offset;
+}
+
+
+/* sub dissector table of ICBAPhysicalDevice / ICBAPhysicalDevice2 interface */
+static dcerpc_sub_dissector ICBAPhysicalDevice_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "get_Producer", dissect_dcom_simple_rqst, dissect_get_Producer_resp },
+ { 8, "get_Product", dissect_dcom_simple_rqst, dissect_get_Product_resp },
+ { 9, "get_SerialNo", dissect_dcom_simple_rqst, dissect_get_SerialNo_resp },
+ {10, "get_ProductionDate", dissect_dcom_simple_rqst, dissect_get_ProductionDate_resp },
+ {11, "Revision", dissect_dcom_simple_rqst, dissect_Revision_resp },
+ {12, "get_LogicalDevice", dissect_ICBAPhysicalDevice_get_LogicalDevice_rqst, dissect_ICBAPhysicalDevice_get_LogicalDevice_resp },
+ /* stage 2 */
+ {13, "Type", dissect_dcom_simple_rqst, dissect_ICBAPhysicalDevice2_Type_resp },
+ {14, "PROFInetRevision", dissect_dcom_simple_rqst, dissect_PROFInetRevision_resp },
+ {15, "PDevStamp", dissect_dcom_simple_rqst, dissect_ICBAPhysicalDevice2_get_PDevStamp_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBABrowse / ICBABrowse2 interface */
+static dcerpc_sub_dissector ICBABrowse_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "get_Count", dissect_dcom_simple_rqst, dissect_ICBABrowse_get_Count_resp },
+ { 8, "BrowseItems", dissect_ICBABrowse_BrowseItems_rqst, dissect_ICBABrowse_BrowseItems_resp },
+ /* stage 2 */
+ { 9, "get_Count2", dissect_ICBABrowse2_get_Count2_rqst, dissect_ICBABrowse_get_Count_resp },
+ {10, "BrowseItems2", dissect_ICBABrowse2_BrowseItems2_rqst, dissect_ICBABrowse2_BrowseItems2_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAPersist / ICBAPersist2 interface */
+static dcerpc_sub_dissector ICBAPersist_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "Save", dissect_dcom_simple_rqst, dissect_dcom_simple_resp },
+ /* stage 2 */
+ { 8, "Save2", dissect_dcom_simple_rqst, dissect_ICBAPersist2_Save2_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAPhysicalDevicePC interface */
+/* (local COM interface, not to be called over network) */
+static dcerpc_sub_dissector ICBAPhysicalDevicePC_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "AddLogicalDevice", dissect_Advise_rqst, dissect_Advise_resp },
+ { 4, "RemoveLogicalDevice", dissect_Unadvise_rqst, dissect_dcom_simple_resp },
+ { 5, "AdvisePDevPC", dissect_Advise_rqst, dissect_Advise_resp },
+ { 6, "UnadvisePDevPC", dissect_Unadvise_rqst, dissect_dcom_simple_resp },
+ /* stage 2 */
+ { 7, "RegisterApplication", NULL, NULL },
+ { 8, "UnRegisterApplication", NULL, NULL },
+ { 9, "AddLogicalDevice2", NULL, NULL },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAPhysicalDevicePCEvent interface */
+static dcerpc_sub_dissector ICBAPhysicalDevicePCEvent_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "OnLogicalDeviceAdded", dissect_ICBAPhysicalDevicePCEvent_OnLogicalDeviceAdded_rqst, dissect_dcom_simple_resp },
+ { 4, "OnLogicalDeviceRemoved", dissect_Unadvise_rqst, dissect_dcom_simple_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBALogicalDevice / ICBALogicalDevice2 interface */
+static dcerpc_sub_dissector ICBALogicalDevice_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "get_Name", dissect_dcom_simple_rqst, dissect_ICBALogicalDevice_get_Name_resp },
+ { 8, "get_Producer", dissect_dcom_simple_rqst, dissect_get_Producer_resp },
+ { 9, "get_Product", dissect_dcom_simple_rqst, dissect_get_Product_resp },
+ {10, "get_SerialNo", dissect_dcom_simple_rqst, dissect_get_SerialNo_resp },
+ {11, "get_ProductionDate", dissect_dcom_simple_rqst, dissect_get_ProductionDate_resp },
+ {12, "Revision", dissect_dcom_simple_rqst, dissect_Revision_resp },
+ {13, "get_ACCO", dissect_dcom_simple_rqst, dissect_ICBALogicalDevice_get_ACCO_resp },
+ {14, "get_RTAuto", dissect_ICBALogicalDevice_Get_RTAuto_rqst, dissect_ICBALogicalDevice_get_RTAuto_resp },
+ /* stage 2 */
+ {15, "PROFInetRevision", dissect_dcom_simple_rqst, dissect_PROFInetRevision_resp },
+ {16, "ComponentInfo", dissect_dcom_simple_rqst, dissect_ComponentInfo_resp },
+ {17, "PBAddressInfo", dissect_dcom_simple_rqst, dissect_PBAddressInfo_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAState interface */
+static dcerpc_sub_dissector ICBAState_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "get_State", dissect_dcom_simple_rqst, dissect_ICBAState_get_State_resp },
+ { 8, "Activate", dissect_dcom_simple_rqst, dissect_dcom_simple_resp },
+ { 9, "Deactivate", dissect_dcom_simple_rqst, dissect_dcom_simple_resp },
+ {10, "Reset", dissect_dcom_simple_rqst, dissect_dcom_simple_resp },
+ {11, "AdviseState", dissect_Advise_rqst, dissect_Advise_resp },
+ {12, "UnadviseState", dissect_Unadvise_rqst, dissect_dcom_simple_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAStateEvent interface */
+static dcerpc_sub_dissector ICBAStateEvent_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "OnStateChanged", dissect_ICBAStateEvent_OnStateChanged_rqst, dissect_dcom_simple_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBATime interface */
+static dcerpc_sub_dissector ICBATime_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "get_Time", dissect_dcom_simple_rqst, dissect_ICBATime_get_Time_resp },
+ { 8, "put_Time", dissect_ICBATime_put_Time_rqst, dissect_dcom_simple_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAGroupError interface */
+static dcerpc_sub_dissector ICBAGroupError_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "GroupError", dissect_dcom_simple_rqst, dissect_ICBAGroupError_GroupError_resp },
+ { 8, "AdviseGroupError", dissect_Advise_rqst, dissect_Advise_resp },
+ { 9, "UnadviseGroupError", dissect_Unadvise_rqst, dissect_dcom_simple_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBAGroupErrorEvent interface */
+static dcerpc_sub_dissector ICBAGroupErrorEvent_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "OnGroupErrorChanged", dissect_ICBAGroupError_OnGroupErrorChanged_rqst, dissect_dcom_simple_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* sub dissector table of ICBARTAuto interface */
+static dcerpc_sub_dissector ICBARTAuto_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "get_Name", dissect_dcom_simple_rqst, dissect_RTAuto_get_Name_resp },
+ { 8, "Revision", dissect_dcom_simple_rqst, dissect_Revision_resp },
+
+ /* stage 2 */
+ { 9, "ComponentInfo", dissect_dcom_simple_rqst, dissect_ComponentInfo_resp },
+ { 0, NULL, NULL, NULL },
+};
+
+
+/* the interface ICBASystemProperties will NOT be seen on the ethernet */
+/* sub dissector table of ICBASystemProperties interface (stage 2 only) */
+/* (usually not called over network, no dissecting needed) */
+static dcerpc_sub_dissector ICBASystemProperties_dissectors[] = {
+ { 0, "QueryInterface", NULL, NULL },
+ { 1, "AddRef", NULL, NULL },
+ { 2, "Release", NULL, NULL },
+
+ { 3, "GetTypeInfoCount", dissect_dcom_simple_rqst, dissect_IDispatch_GetTypeInfoCount_resp },
+ { 4, "GetTypeInfo", dissect_IDispatch_GetTypeInfo_rqst, dissect_IDispatch_GetTypeInfo_resp },
+ { 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
+ { 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
+
+ { 7, "StateCollection", dissect_dcom_simple_rqst, NULL },
+ { 8, "StampCollection", dissect_dcom_simple_rqst, NULL },
+ { 0, NULL, NULL, NULL },
+};
+
+
+static void cba_cleanup(void) {
+ g_list_free(cba_pdevs);
+ cba_pdevs = NULL;
+}
+
+
+/* register protocol */
+void
+proto_register_dcom_cba (void)
+{
+ static hf_register_info hf_cba_browse_array[] = {
+ { &hf_cba_browse_count,
+ { "Count", "cba.browse.count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_browse_offset,
+ { "Offset", "cba.browse.offset",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_browse_max_return,
+ { "MaxReturn", "cba.browse.max_return",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_browse_item,
+ { "ItemNames", "cba.browse.item",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_browse_data_type,
+ { "DataTypes", "cba.browse.data_type",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_browse_access_right,
+ { "AccessRights", "cba.browse.access_right",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_browse_selector,
+ { "Selector", "cba.browse.selector",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_browse_info1,
+ { "Info1", "cba.browse.info1",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_browse_info2,
+ { "Info2", "cba.browse.info2",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ };
+
+
+ static hf_register_info hf_cba_pdev_array[] = {
+ { &hf_cba_revision_major,
+ { "Major", "cba.revision_major",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_revision_minor,
+ { "Minor", "cba.revision_minor",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_revision_service_pack,
+ { "ServicePack", "cba.revision_service_pack",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_revision_build,
+ { "Build", "cba_revision_build",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_producer,
+ { "Producer", "cba.producer",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_product,
+ { "Product", "cba.product",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_multi_app,
+ { "MultiApp", "cba.multi_app",
+ FT_UINT16, BASE_HEX, VALS(dcom_boolean_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_profinet_dcom_stack,
+ { "PROFInetDCOMStack", "cba.profinet_dcom_stack",
+ FT_UINT16, BASE_HEX, VALS(dcom_boolean_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_pdev_stamp,
+ { "PDevStamp", "cba.pdev_stamp",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_save_ldev_name,
+ { "LDevName", "cba.save_ldev_name",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_save_result,
+ { "PartialResult", "cba.save_result",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ };
+
+ static hf_register_info hf_cba_ldev_array[] = {
+ { &hf_cba_name,
+ { "Name", "cba.name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_component_id,
+ { "ComponentID", "cba.component_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_component_version,
+ { "Version", "cba.component_version",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_pbaddress,
+ { "PROFIBUS Address", "cba.pbaddress",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_pbaddress_system_id,
+ { "SystemID", "cba.pbaddress.system_id",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_pbaddress_address,
+ { "Address", "cba.pbaddress.address",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ };
+
+ static hf_register_info hf_cba_array[] = {
+ { &hf_cba_opnum,
+ { "Operation", "cba.opnum",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_production_date,
+ { "ProductionDate", "cba.production_date",
+ FT_DOUBLE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_time,
+ { "Time", "cba.time",
+ FT_DOUBLE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_serial_no,
+ { "SerialNo", "cba.serial_no",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_state,
+ { "State", "cba.state",
+ FT_UINT16, BASE_HEX, VALS(cba_state_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_new_state,
+ { "NewState", "cba.state_new",
+ FT_UINT16, BASE_HEX, VALS(cba_state_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_old_state,
+ { "OldState", "cba.state_old",
+ FT_UINT16, BASE_HEX, VALS(cba_state_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_cookie,
+ { "Cookie", "cba.cookie",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_grouperror,
+ { "GroupError", "cba.grouperror",
+ FT_UINT16, BASE_HEX, VALS(cba_grouperror_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_new_grouperror,
+ { "NewGroupError", "cba.grouperror_new",
+ FT_UINT16, BASE_HEX, VALS(cba_grouperror_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_cba_old_grouperror,
+ { "OldGroupError", "cba.grouperror_old",
+ FT_UINT16, BASE_HEX, VALS(cba_grouperror_vals), 0x0,
+ NULL, HFILL }},
+
+ };
+
+ static gint *ett_cba[] = {
+ &ett_ICBAPhysicalDevice,
+ &ett_ICBABrowse,
+ &ett_ICBAPhysicalDevicePC,
+ &ett_ICBAPhysicalDevicePCEvent,
+ &ett_ICBAPersist,
+ &ett_ICBALogicalDevice,
+ &ett_ICBAState,
+ &ett_ICBAStateEvent,
+ &ett_ICBATime,
+ &ett_ICBAGroupError,
+ &ett_ICBAGroupErrorEvent,
+ &ett_ICBARTAuto,
+ &ett_ICBASystemProperties,
+ &ett_PBAddress
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_cba_acco_interface_pointer_unresolved, { "cba.acco.interface_pointer_unresolved", PI_UNDECODED, PI_WARN, "LDev_get_ACCO: can't resolve ACCO interface pointer", EXPFILL }},
+ };
+
+ expert_module_t* expert_cba_acco;
+
+ proto_register_subtree_array (ett_cba, array_length (ett_cba));
+
+ proto_ICBAPhysicalDevice = proto_register_protocol ("ICBAPhysicalDevice", "ICBAPDev", "cba_pdev");
+ proto_register_field_array(proto_ICBAPhysicalDevice, hf_cba_pdev_array, array_length(hf_cba_pdev_array));
+
+ /* XXX - just pick a protocol to register the expert info in */
+ expert_cba_acco = expert_register_protocol(proto_ICBAPhysicalDevice);
+ expert_register_field_array(expert_cba_acco, ei, array_length(ei));
+
+ proto_ICBAPhysicalDevice2 = proto_register_protocol ("ICBAPhysicalDevice2", "ICBAPDev2", "cba_pdev2");
+
+ proto_ICBABrowse = proto_register_protocol ("ICBABrowse", "ICBABrowse", "cba_browse");
+ proto_register_field_array(proto_ICBABrowse, hf_cba_array, array_length(hf_cba_array));
+ proto_register_field_array(proto_ICBABrowse, hf_cba_browse_array, array_length(hf_cba_browse_array));
+
+ proto_ICBABrowse2 = proto_register_protocol ("ICBABrowse2", "ICBABrowse2", "cba_browse2");
+
+ proto_ICBAPhysicalDevicePC = proto_register_protocol ("ICBAPhysicalDevicePC", "ICBAPDevPC", "cba_pdev_pc");
+
+ proto_ICBAPhysicalDevicePCEvent = proto_register_protocol ("ICBAPhysicalDevicePCEvent", "ICBAPDevPCEvent", "cba_pdev_pc_event");
+
+ proto_ICBAPersist = proto_register_protocol ("ICBAPersist", "ICBAPersist", "cba_persist");
+
+ proto_ICBAPersist2 = proto_register_protocol ("ICBAPersist2", "ICBAPersist2", "cba_persist2");
+
+ proto_ICBALogicalDevice = proto_register_protocol ("ICBALogicalDevice", "ICBALDev", "cba_ldev");
+ proto_register_field_array(proto_ICBAPhysicalDevice, hf_cba_ldev_array, array_length(hf_cba_ldev_array));
+
+ proto_ICBALogicalDevice2 = proto_register_protocol ("ICBALogicalDevice2", "ICBALDev2", "cba_ldev2");
+
+ proto_ICBAState = proto_register_protocol ("ICBAState", "ICBAState", "cba_state");
+
+ proto_ICBAStateEvent = proto_register_protocol ("ICBAStateEvent", "ICBAStateEvent", "cba_state_event");
+
+ proto_ICBATime = proto_register_protocol ("ICBATime", "ICBATime", "cba_time");
+
+ proto_ICBAGroupError = proto_register_protocol ("ICBAGroupError", "ICBAGErr", "cba_grouperror");
+
+ proto_ICBAGroupErrorEvent = proto_register_protocol ("ICBAGroupErrorEvent", "ICBAGErrEvent", "cba_grouperror_event");
+
+ proto_ICBARTAuto = proto_register_protocol ("ICBARTAuto", "ICBARTAuto", "cba_rtauto");
+
+ proto_ICBARTAuto2 = proto_register_protocol ("ICBARTAuto2", "ICBARTAuto2", "cba_rtauto2");
+
+ proto_ICBASystemProperties = proto_register_protocol ("ICBASystemProperties", "ICBASysProp", "cba_sysprop");
+
+ register_cleanup_routine(cba_cleanup);
+}
+
+
+/* handoff protocol */
+void
+proto_reg_handoff_dcom_cba (void)
+{
+ /* Register the CBA class ID */
+ guids_add_uuid(&uuid_coclass_CBAPhysicalDevice, "CBA");
+
+ /* Register the interfaces */
+ dcerpc_init_uuid(proto_ICBAPhysicalDevice, ett_ICBAPhysicalDevice,
+ &uuid_ICBAPhysicalDevice, ver_ICBAPhysicalDevice,
+ ICBAPhysicalDevice_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAPhysicalDevice2, ett_ICBAPhysicalDevice,
+ &uuid_ICBAPhysicalDevice2, ver_ICBAPhysicalDevice2,
+ ICBAPhysicalDevice_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBABrowse, ett_ICBABrowse,
+ &uuid_ICBABrowse, ver_ICBABrowse,
+ ICBABrowse_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBABrowse2, ett_ICBABrowse,
+ &uuid_ICBABrowse2, ver_ICBABrowse2,
+ ICBABrowse_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAPhysicalDevicePC, ett_ICBAPhysicalDevicePC,
+ &uuid_ICBAPhysicalDevicePC, ver_ICBAPhysicalDevicePC,
+ ICBAPhysicalDevicePC_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAPhysicalDevicePCEvent, ett_ICBAPhysicalDevicePCEvent,
+ &uuid_ICBAPhysicalDevicePCEvent, ver_ICBAPhysicalDevicePCEvent,
+ ICBAPhysicalDevicePCEvent_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAPersist, ett_ICBAPersist,
+ &uuid_ICBAPersist, ver_ICBAPersist,
+ ICBAPersist_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAPersist2, ett_ICBAPersist,
+ &uuid_ICBAPersist2, ver_ICBAPersist2,
+ ICBAPersist_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBALogicalDevice, ett_ICBALogicalDevice,
+ &uuid_ICBALogicalDevice, ver_ICBALogicalDevice,
+ ICBALogicalDevice_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBALogicalDevice2, ett_ICBALogicalDevice,
+ &uuid_ICBALogicalDevice2, ver_ICBALogicalDevice2,
+ ICBALogicalDevice_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAState, ett_ICBAState,
+ &uuid_ICBAState, ver_ICBAState,
+ ICBAState_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAStateEvent, ett_ICBAStateEvent,
+ &uuid_ICBAStateEvent, ver_ICBAStateEvent,
+ ICBAStateEvent_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBATime, ett_ICBATime,
+ &uuid_ICBATime, ver_ICBATime,
+ ICBATime_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAGroupError, ett_ICBAGroupError,
+ &uuid_ICBAGroupError, ver_ICBAGroupError,
+ ICBAGroupError_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBAGroupErrorEvent, ett_ICBAGroupErrorEvent,
+ &uuid_ICBAGroupErrorEvent, ver_ICBAGroupErrorEvent,
+ ICBAGroupErrorEvent_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBARTAuto, ett_ICBARTAuto,
+ &uuid_ICBARTAuto, ver_ICBARTAuto,
+ ICBARTAuto_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBARTAuto2, ett_ICBARTAuto,
+ &uuid_ICBARTAuto2, ver_ICBARTAuto2,
+ ICBARTAuto_dissectors, hf_cba_opnum);
+
+ dcerpc_init_uuid(proto_ICBASystemProperties, ett_ICBASystemProperties,
+ &uuid_ICBASystemProperties, ver_ICBASystemProperties,
+ ICBASystemProperties_dissectors, hf_cba_opnum);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-pn-dcp.c b/plugins/epan/profinet/packet-pn-dcp.c
new file mode 100644
index 0000000..456c79c
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn-dcp.c
@@ -0,0 +1,2096 @@
+/* packet-pn-dcp.c
+ * Routines for PN-DCP (PROFINET Discovery and basic Configuration Protocol)
+ * packet dissection.
+ *
+ * IEC 61158-6-10 section 4.3
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * Cyclic PNIO RTC1 Data Dissection:
+ *
+ * Added new functions to packet-pn-dcp.c. The profinet plug-in will now save
+ * the information (Stationname, -type, -id) of "Ident OK" frames. Those
+ * informations will later be used for detailled dissection of cyclic PNIO RTC1
+ * dataframes.
+ *
+ * The declaration of the new added structures are within packet-pn.h to
+ * use the information within packet-pn-rtc-one.c
+ *
+ * Overview for cyclic PNIO RTC1 data dissection functions:
+ * -> dissect_PNDCP_Suboption_Device (Save Stationname, -type, -id)
+ */
+
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/exceptions.h>
+#include <epan/to_str.h>
+#include <epan/wmem_scopes.h>
+#include <epan/expert.h>
+#include <epan/conversation.h>
+
+#include "packet-pn.h"
+
+
+void proto_register_pn_dcp(void);
+void proto_reg_handoff_pn_dcp(void);
+
+int proto_pn_dcp = -1;
+
+static int hf_pn_dcp_service_id = -1;
+static int hf_pn_dcp_service_type = -1;
+static int hf_pn_dcp_xid = -1;
+static int hf_pn_dcp_reserved8 = -1;
+static int hf_pn_dcp_reserved16 = -1;
+static int hf_pn_dcp_response_delay = -1;
+static int hf_pn_dcp_data_length = -1;
+static int hf_pn_dcp_block_length = -1;
+
+static int hf_pn_dcp_block = -1;
+
+static int hf_pn_dcp_block_error = -1;
+
+static int hf_pn_dcp_option = -1;
+static int hf_pn_dcp_block_info = -1;
+static int hf_pn_dcp_block_qualifier = -1;
+static int hf_pn_dcp_blockqualifier = -1;
+static int hf_pn_dcp_blockqualifier_r2f = -1;
+
+static int hf_pn_dcp_suboption_ip = -1;
+static int hf_pn_dcp_suboption_ip_block_info = -1;
+static int hf_pn_dcp_suboption_ip_ip = -1;
+static int hf_pn_dcp_suboption_ip_subnetmask = -1;
+static int hf_pn_dcp_suboption_ip_standard_gateway = -1;
+static int hf_pn_dcp_suboption_ip_mac_address = -1;
+
+static int hf_pn_dcp_suboption_device = -1;
+static int hf_pn_dcp_suboption_device_typeofstation = -1;
+static int hf_pn_dcp_suboption_device_nameofstation = -1;
+static int hf_pn_dcp_suboption_vendor_id = -1;
+static int hf_pn_dcp_suboption_device_id = -1;
+static int hf_pn_dcp_suboption_device_role = -1;
+static int hf_pn_dcp_suboption_device_aliasname = -1;
+static int hf_pn_dcp_suboption_device_instance_high = -1;
+static int hf_pn_dcp_suboption_device_instance_low = -1;
+static int hf_pn_dcp_suboption_device_oem_ven_id = -1;
+static int hf_pn_dcp_suboption_device_oem_dev_id = -1;
+
+static int hf_pn_dcp_rsi_properties_value = -1;
+static int hf_pn_dcp_rsi_properties_value_bit0 = -1;
+static int hf_pn_dcp_rsi_properties_value_bit1 = -1;
+static int hf_pn_dcp_rsi_properties_value_bit2 = -1;
+static int hf_pn_dcp_rsi_properties_value_bit3 = -1;
+static int hf_pn_dcp_rsi_properties_value_bit4 = -1;
+static int hf_pn_dcp_rsi_properties_value_bit5 = -1;
+static int hf_pn_dcp_rsi_properties_value_otherbits = -1;
+
+static int hf_pn_dcp_suboption_tsn = -1;
+static int hf_pn_dcp_suboption_tsn_domain_name = -1;
+static int hf_pn_dcp_suboption_tsn_domain_uuid = -1;
+static int hf_pn_dcp_suboption_tsn_nme_prio = -1;
+static int hf_pn_dcp_suboption_tsn_nme_parameter_uuid = -1;
+static int hf_pn_dcp_suboption_tsn_nme_agent = -1;
+
+static int hf_pn_dcp_suboption_dhcp = -1;
+static int hf_pn_dcp_suboption_dhcp_option_code = -1;
+static int hf_pn_dcp_suboption_dhcp_parameter_length = -1;
+static int hf_pn_dcp_suboption_dhcp_parameter_data = -1;
+static int hf_pn_dcp_suboption_dhcp_arbitrary_client_id = -1;
+static int hf_pn_dcp_suboption_dhcp_control_parameter_data = -1;
+
+static int hf_pn_dcp_suboption_control = -1;
+static int hf_pn_dcp_suboption_control_option = -1;
+static int hf_pn_dcp_suboption_control_signal_value = -1;
+
+static int hf_pn_dcp_suboption_deviceinitiative = -1;
+static int hf_pn_dcp_deviceinitiative_value = -1;
+
+static int hf_pn_dcp_suboption_all = -1;
+
+static int hf_pn_dcp_suboption_manuf = -1;
+
+static int hf_pn_dcp_vendor_id_high = -1;
+static int hf_pn_dcp_vendor_id_low = -1;
+static int hf_pn_dcp_device_id_high = -1;
+static int hf_pn_dcp_device_id_low = -1;
+static int hf_pn_dcp_instance_id_high = -1;
+static int hf_pn_dcp_instance_id_low = -1;
+static gint ett_pn_dcp = -1;
+static gint ett_pn_dcp_block = -1;
+
+static gint ett_pn_dcp_rsi_properties_value = -1;
+
+static expert_field ei_pn_dcp_block_parse_error = EI_INIT;
+static expert_field ei_pn_dcp_block_error_unknown = EI_INIT;
+static expert_field ei_pn_dcp_ip_conflict = EI_INIT;
+
+#define PNDCP_SERVICE_ID_GET 0x03
+#define PNDCP_SERVICE_ID_SET 0x04
+#define PNDCP_SERVICE_ID_IDENTIFY 0x05
+#define PNDCP_SERVICE_ID_HELLO 0x06
+
+static const value_string pn_dcp_service_id[] = {
+ { 0x00, "reserved" },
+ { 0x01, "Manufacturer specific" },
+ { 0x02, "Manufacturer specific" },
+ { PNDCP_SERVICE_ID_GET, "Get" },
+ { PNDCP_SERVICE_ID_SET, "Set" },
+ { PNDCP_SERVICE_ID_IDENTIFY,"Identify" },
+ { PNDCP_SERVICE_ID_HELLO, "Hello" },
+ /* 0x07 - 0xff reserved */
+ { 0, NULL }
+};
+
+#define PNDCP_SERVICE_TYPE_REQUEST 0
+#define PNDCP_SERVICE_TYPE_RESPONSE_SUCCESS 1
+#define PNDCP_SERVICE_TYPE_RESPONSE_UNSUPPORTED 5
+
+static const value_string pn_dcp_service_type[] = {
+ { PNDCP_SERVICE_TYPE_REQUEST, "Request" },
+ { PNDCP_SERVICE_TYPE_RESPONSE_SUCCESS, "Response Success" },
+ { PNDCP_SERVICE_TYPE_RESPONSE_UNSUPPORTED, "Response - Request not supported" },
+ /* all others reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_block_error[] = {
+ { 0x00, "Ok" },
+ { 0x01, "Option unsupp." },
+ { 0x02, "Suboption unsupp. or no DataSet avail." },
+ { 0x03, "Suboption not set" },
+ { 0x04, "Resource Error" },
+ { 0x05, "SET not possible by local reasons" },
+ { 0x06, "In operation, SET not possible" },
+ /* all others reserved */
+ { 0, NULL }
+};
+
+static const range_string pn_dcp_block_info[] = {
+ { 0x0000, 0xFFFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_dcp_block_qualifier[] = {
+ { 0x0000, "Use the value temporary" },
+ { 0x0001, "Save the value permanent" },
+ /*0x0002 - 0xffff reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_BlockQualifier[] = {
+ { 0x0002, "Reset application data" },
+ { 0x0003, "Reset application data" },
+ { 0x0004, "Reset communication parameter" },
+ { 0x0005, "Reset communication parameter" },
+ { 0x0006, "Reset engineering parameter" },
+ { 0x0007, "Reset engineering parameter" },
+ { 0x0008, "Resets all stored data" },
+ { 0x0009, "Resets all stored data" },
+ { 0x000A, "Reset engineering parameter" },
+ { 0x000B, "Reset engineering parameter" },
+ { 0x000C, "Reserved" },
+ { 0x000D, "Reserved" },
+ { 0x000E, "Reserved" },
+ { 0x0010, "Resets all stored data in the IOD or IOC to its factory values" },
+ { 0x0011, "Resets all stored data in the IOD or IOC to its factory values" },
+ { 0x0012, "Reset and restore data" },
+ { 0x0013, "Reset and restore data" },
+ { 0x0014, "Reserved" },
+ { 0x0015, "Reserved" },
+ { 0x0016, "Reserved" },
+ { 0, NULL }
+};
+
+#define PNDCP_OPTION_IP 0x01
+#define PNDCP_OPTION_DEVICE 0x02
+#define PNDCP_OPTION_DHCP 0x03
+#define PNDCP_OPTION_RESERVED 0x04
+#define PNDCP_OPTION_CONTROL 0x05
+#define PNDCP_OPTION_DEVICEINITIATIVE 0x06
+#define PNDCP_OPTION_TSN 0x07
+#define PNDCP_OPTION_MANUF_X80 0x80
+#define PNDCP_OPTION_MANUF_XFE 0xFE
+#define PNDCP_OPTION_ALLSELECTOR 0xFF
+
+static const range_string pn_dcp_option[] = {
+ { 0x00, 0x00, "Reserved" },
+ { PNDCP_OPTION_IP , PNDCP_OPTION_IP , "IP" },
+ { PNDCP_OPTION_DEVICE , PNDCP_OPTION_DEVICE , "Device properties" },
+ { PNDCP_OPTION_DHCP , PNDCP_OPTION_DHCP , "DHCP" },
+ { PNDCP_OPTION_RESERVED , PNDCP_OPTION_RESERVED , "Reserved" },
+ { PNDCP_OPTION_CONTROL , PNDCP_OPTION_CONTROL , "Control" },
+ { PNDCP_OPTION_DEVICEINITIATIVE, PNDCP_OPTION_DEVICEINITIATIVE, "Device Initiative" },
+ { PNDCP_OPTION_TSN , PNDCP_OPTION_TSN , "TSN Domain"},
+ /*0x07 - 0x7F reserved */
+ /*0x80 - 0xFE manufacturer specific */
+ { PNDCP_OPTION_MANUF_X80 , PNDCP_OPTION_MANUF_XFE , "Manufacturer specific" },
+ { PNDCP_OPTION_ALLSELECTOR, PNDCP_OPTION_ALLSELECTOR, "All Selector" },
+ { 0, 0, NULL }
+};
+
+#define PNDCP_SUBOPTION_IP_MAC 0x01
+#define PNDCP_SUBOPTION_IP_IP 0x02
+#define PNDCP_SUBOPTION_IP_FULL_IP_SUITE 0x03
+
+static const value_string pn_dcp_suboption_ip[] = {
+ { 0x00, "Reserved" },
+ { PNDCP_SUBOPTION_IP_MAC, "MAC address" },
+ { PNDCP_SUBOPTION_IP_IP, "IP parameter" },
+ { PNDCP_SUBOPTION_IP_FULL_IP_SUITE, "Full IP suite" },
+ /*0x03 - 0xff reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_suboption_ip_block_info[] = {
+ { 0x0000, "IP not set" },
+ { 0x0001, "IP set" },
+ { 0x0002, "IP set by DHCP" },
+ { 0x0080, "IP not set (address conflict detected)" },
+ { 0x0081, "IP set (address conflict detected)" },
+ { 0x0082, "IP set by DHCP (address conflict detected)" },
+ /*0x0003 - 0xffff reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_suboption_control_signal_value[] = {
+ {0x0100, "Flash Once"},
+ {0, NULL}
+};
+
+#define PNDCP_SUBOPTION_DEVICE_MANUF 0x01
+#define PNDCP_SUBOPTION_DEVICE_NAMEOFSTATION 0x02
+#define PNDCP_SUBOPTION_DEVICE_DEV_ID 0x03
+#define PNDCP_SUBOPTION_DEVICE_DEV_ROLE 0x04
+#define PNDCP_SUBOPTION_DEVICE_DEV_OPTIONS 0x05
+#define PNDCP_SUBOPTION_DEVICE_ALIAS_NAME 0x06
+#define PNDCP_SUBOPTION_DEVICE_DEV_INSTANCE 0x07
+#define PNDCP_SUBOPTION_DEVICE_OEM_DEV_ID 0x08
+#define PNDCP_SUBOPTION_DEVICE_RSI_PROPERTIES 0x0A
+
+static const value_string pn_dcp_suboption_device[] = {
+ { 0x00, "Reserved" },
+ { PNDCP_SUBOPTION_DEVICE_MANUF, "Manufacturer specific (Type of Station)" },
+ { PNDCP_SUBOPTION_DEVICE_NAMEOFSTATION, "Name of Station" },
+ { PNDCP_SUBOPTION_DEVICE_DEV_ID, "Device ID" },
+ { PNDCP_SUBOPTION_DEVICE_DEV_ROLE, "Device Role" },
+ { PNDCP_SUBOPTION_DEVICE_DEV_OPTIONS, "Device Options" },
+ { PNDCP_SUBOPTION_DEVICE_ALIAS_NAME, "Alias Name" },
+ { PNDCP_SUBOPTION_DEVICE_DEV_INSTANCE, "Device Instance" },
+ { PNDCP_SUBOPTION_DEVICE_OEM_DEV_ID, "OEM Device ID"},
+ { PNDCP_SUBOPTION_DEVICE_RSI_PROPERTIES,"RSI Properties" },
+ /*0x09 - 0xff reserved */
+ { 0, NULL }
+};
+
+static const true_false_string pn_dcp_rsi_properties_value_bit =
+ { "Available", "Not available" } ;
+
+#define PNDCP_SUBOPTION_TSN_DOMAIN_NAME 0x01
+#define PNDCP_SUBOPTION_TSN_NME_MANAGER 0x02
+#define PNDCP_SUBOPTION_TSN_NME_PARAMETER_UUID 0x03
+#define PNDCP_SUBOPTION_TSN_NME_AGENT 0x04
+#define PNDCP_SUBOPTION_TSN_CIM_INTERFACE 0x05
+
+static const value_string pn_dcp_suboption_tsn[] = {
+ { 0x00, "Reserved" },
+ { PNDCP_SUBOPTION_TSN_DOMAIN_NAME, "TSN Domain Name" },
+ { PNDCP_SUBOPTION_TSN_NME_MANAGER, "NME Manager" },
+ { PNDCP_SUBOPTION_TSN_NME_PARAMETER_UUID, "NME Paramater UUID" },
+ { PNDCP_SUBOPTION_TSN_NME_AGENT, "NME Agent" },
+ { PNDCP_SUBOPTION_TSN_CIM_INTERFACE, "CIM Interface" },
+ { 0, NULL }
+};
+
+static const range_string pn_dcp_suboption_tsn_nme_prio[] =
+{
+ { 0x0000, 0x0000, "Highest priority NME manager" },
+ { 0x0001, 0x3000, "High priorities for NME manager" },
+ { 0x3001, 0x9FFF, "Low priorities for NME manager" },
+ { 0xA000, 0xA000, "Lowest priority for NME manager / Default priority for NME manager" },
+ { 0xA001, 0xFFFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+#define PNDCP_SUBOPTION_DHCP_CLIENT_ID 61
+#define PNDCP_SUBOPTION_DHCP_CONTROL_FOR_ADDRESS_RES 255
+
+static const value_string pn_dcp_suboption_dhcp[] = {
+ { 12, "Host name" },
+ { 43, "Vendor specific" },
+ { 54, "Server identifier" },
+ { 55, "Parameter request list" },
+ { 60, "Class identifier" },
+ { PNDCP_SUBOPTION_DHCP_CLIENT_ID, "DHCP client identifier" },
+ { 81, "FQDN, Fully Qualified Domain Name" },
+ { 97, "UUID/GUID-based Client" },
+ { PNDCP_SUBOPTION_DHCP_CONTROL_FOR_ADDRESS_RES, "Control DHCP for address resolution" },
+ /*all others reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_suboption_dhcp_control_parameter_data[] = {
+ { 0x00, "Don't use DHCP (Default)" },
+ { 0x01, "Don't use DHCP, all DHCPOptions set to Reset to Factory value" },
+ { 0x02, "Use DHCP with the given set of DHCPOptions" },
+ { 0, NULL }
+};
+
+#define PNDCP_SUBOPTION_CONTROL_START_TRANS 0x01
+#define PNDCP_SUBOPTION_CONTROL_END_TRANS 0x02
+#define PNDCP_SUBOPTION_CONTROL_SIGNAL 0x03
+#define PNDCP_SUBOPTION_CONTROL_RESPONSE 0x04
+#define PNDCP_SUBOPTION_CONTROL_FACT_RESET 0x05
+#define PNDCP_SUBOPTION_CONTROL_RESET_TO_FACT 0x06
+
+static const value_string pn_dcp_suboption_control[] = {
+ { 0x00, "Reserved" },
+ { PNDCP_SUBOPTION_CONTROL_START_TRANS, "Start Transaction" },
+ { PNDCP_SUBOPTION_CONTROL_END_TRANS, "End Transaction" },
+ { PNDCP_SUBOPTION_CONTROL_SIGNAL, "Signal" },
+ { PNDCP_SUBOPTION_CONTROL_RESPONSE, "Response" },
+ { PNDCP_SUBOPTION_CONTROL_FACT_RESET, "Reset Factory Settings" },
+ { PNDCP_SUBOPTION_CONTROL_RESET_TO_FACT,"Reset to Factory" },
+ /*0x07 - 0xff reserved */
+ { 0, NULL }
+};
+
+#define PNDCP_SUBOPTION_DEVICEINITIATIVE 0x01
+
+static const value_string pn_dcp_suboption_deviceinitiative[] = {
+ { 0x00, "Reserved" },
+ { PNDCP_SUBOPTION_DEVICEINITIATIVE, "Device Initiative" },
+ /*0x00 - 0xff reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_deviceinitiative_value[] = {
+ { 0x00, "Device does not issue a DCP-Hello-ReqPDU after power on" },
+ { 0x01, "Device does issue a DCP-Hello-ReqPDU after power on" },
+ /*0x02 - 0xff reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_suboption_all[] = {
+ { 0xff, "ALL Selector" },
+ /* all other reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_suboption_other[] = {
+ { 0x00, "Default" },
+ /* all other reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_dcp_suboption_manuf[] = {
+ /* none known */
+ { 0, NULL }
+};
+
+
+
+
+
+/* dissect the option field */
+static int
+dissect_PNDCP_Option(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *block_item, int hfindex, gboolean append_col)
+{
+ guint8 option;
+ guint8 suboption;
+ const value_string *val_str;
+
+ offset = dissect_pn_uint8 (tvb, offset, pinfo, tree, hfindex, &option);
+ switch (option) {
+ case PNDCP_OPTION_IP:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip, &suboption);
+ val_str = pn_dcp_suboption_ip;
+ break;
+ case PNDCP_OPTION_DEVICE:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device, &suboption);
+ val_str = pn_dcp_suboption_device;
+ break;
+ case PNDCP_OPTION_DHCP:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp, &suboption);
+ val_str = pn_dcp_suboption_dhcp;
+ break;
+ case PNDCP_OPTION_CONTROL:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_control, &suboption);
+ val_str = pn_dcp_suboption_control;
+ break;
+ case PNDCP_OPTION_DEVICEINITIATIVE:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_deviceinitiative, &suboption);
+ val_str = pn_dcp_suboption_deviceinitiative;
+ break;
+ case PNDCP_OPTION_TSN:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_tsn, &suboption);
+ val_str = pn_dcp_suboption_tsn;
+ break;
+ case PNDCP_OPTION_ALLSELECTOR:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_all, &suboption);
+ val_str = pn_dcp_suboption_all;
+ break;
+ default:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_manuf, &suboption);
+ val_str = pn_dcp_suboption_manuf;
+ }
+
+ proto_item_append_text(block_item, ", Status from %s - %s",
+ rval_to_str_const(option, pn_dcp_option, "Unknown"),
+ val_to_str_const(suboption, val_str, "Unknown"));
+
+ if (append_col) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(suboption, val_str, "Unknown"));
+ }
+
+ return offset;
+}
+
+
+/* dissect the "IP" suboption */
+static int
+dissect_PNDCP_Suboption_IP(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
+ guint8 service_id, gboolean is_response)
+{
+ guint8 suboption;
+ guint16 block_length;
+ guint16 block_info;
+ guint16 block_qualifier;
+ gboolean have_block_info = FALSE;
+ gboolean have_block_qualifier = FALSE;
+ guint8 mac[6];
+ guint32 ip;
+ proto_item *item = NULL;
+ address addr;
+
+
+ /* SuboptionIPParameter */
+ offset = dissect_pn_uint8 (tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip, &suboption);
+ /* DCPBlockLength */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);
+
+ switch (suboption) {
+ case PNDCP_SUBOPTION_IP_MAC:
+ /* MACAddressValue? */
+ pn_append_info(pinfo, dcp_item, ", MAC");
+ proto_item_append_text(block_item, "IP/MAC");
+
+ /* BlockInfo? */
+ if (((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
+ have_block_info = TRUE;
+ block_length -= 2;
+ }
+
+ /* BlockQualifier? */
+ if ((service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ have_block_qualifier = TRUE;
+ block_length -= 2;
+ }
+
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_mac_address, mac);
+ set_address(&addr, AT_ETHER, 6, mac);
+ proto_item_append_text(block_item, ", MACAddress: %s", address_to_str(pinfo->pool, &addr));
+ break;
+ case PNDCP_SUBOPTION_IP_IP:
+ pn_append_info(pinfo, dcp_item, ", IP");
+ proto_item_append_text(block_item, "IP/IP");
+
+ /* BlockInfo? */
+ if (((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
+ block_info = tvb_get_ntohs(tvb, offset);
+ if (tree) {
+ item = proto_tree_add_uint(tree, hf_pn_dcp_suboption_ip_block_info, tvb, offset, 2, block_info);
+ }
+ offset += 2;
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ val_to_str_const(block_info, pn_dcp_suboption_ip_block_info, "Undecoded"));
+ block_length -= 2;
+ if (block_info & 0x80) {
+ expert_add_info(pinfo, item, &ei_pn_dcp_ip_conflict);
+ }
+ }
+
+ /* BlockQualifier? */
+ if ( (service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ block_length -= 2;
+ }
+
+ /* IPParameterValue ... */
+
+ /* IPAddress */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_ip, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", IP: %s", address_to_str(pinfo->pool, &addr));
+
+ /* Subnetmask */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_subnetmask, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", Subnet: %s", address_to_str(pinfo->pool, &addr));
+
+ /* StandardGateway */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", Gateway: %s", address_to_str(pinfo->pool, &addr));
+ break;
+ case PNDCP_SUBOPTION_IP_FULL_IP_SUITE:
+ pn_append_info(pinfo, dcp_item, ", MAC");
+ proto_item_append_text(block_item, "IP/MAC");
+
+ /* BlockInfo? */
+ if (((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
+ have_block_info = TRUE;
+ block_length -= 2;
+ }
+
+ /* BlockQualifier? */
+ if ((service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ have_block_qualifier = TRUE;
+ block_length -= 2;
+ }
+
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+
+ /* IPAddress */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_ip, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", IP: %s", address_to_str(pinfo->pool, &addr));
+
+ /* Subnetmask */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_subnetmask, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", Subnet: %s", address_to_str(pinfo->pool, &addr));
+
+ /* StandardGateway */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", Gateway: %s", address_to_str(pinfo->pool, &addr));
+
+ /* IPAddress_1 */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_ip, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", DNSServerIP1: %s", address_to_str(pinfo->pool, &addr));
+
+ /* IPAddress_2 */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_subnetmask, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", DNSServerIP2: %s", address_to_str(pinfo->pool, &addr));
+
+ /* IPAddress_3 */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", DNSServerIP3: %s", address_to_str(pinfo->pool, &addr));
+
+ /* IPAddress_4 */
+ offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
+ set_address(&addr, AT_IPv4, 4, &ip);
+ proto_item_append_text(block_item, ", DNSServerIP4: %s", address_to_str(pinfo->pool, &addr));
+
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
+ }
+
+ return offset;
+}
+
+
+/* dissect the "device" suboption */
+static int
+dissect_PNDCP_Suboption_Device(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
+ guint8 service_id, gboolean is_response)
+{
+ guint8 suboption;
+ guint16 block_length;
+ gchar *info_str;
+ guint8 device_role;
+ guint16 vendor_id;
+ guint16 device_id;
+ char *typeofstation;
+ char *nameofstation;
+ char *aliasname;
+ guint16 block_info = 0;
+ guint16 block_qualifier = 0;
+ gboolean have_block_info = FALSE;
+ gboolean have_block_qualifier = FALSE;
+ guint8 device_instance_high;
+ guint8 device_instance_low;
+ guint16 oem_vendor_id;
+ guint16 oem_device_id;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ conversation_t *conversation;
+ stationInfo *station_info;
+
+ /* SuboptionDevice... */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device, &suboption);
+ /* DCPBlockLength */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);
+
+ /* BlockInfo? */
+ if ( ((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
+ have_block_info = TRUE;
+ block_length -= 2;
+ }
+
+ /* BlockQualifier? */
+ if ( (service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ have_block_qualifier = TRUE;
+ block_length -= 2;
+ }
+
+ switch (suboption) {
+ case PNDCP_SUBOPTION_DEVICE_MANUF:
+ /*
+ * XXX - IEC 61158-6-10 Edition 4.0, section 4.3, says this field
+ * "shall be coded as data type VisibleString", and that VisibleString
+ * is "ISO/IEC 646 - International Reference Version without the "del"
+ * (coding 0x7F) character", i.e. ASCII.
+ *
+ * However, at least one capture has a packet where 0xAE is used in
+ * a place where a registered trademark symbol would be appropriate,
+ * so the host sending it apparently extended ASCII to ISO 8859-n
+ * for some value of n. That may have just been an error on their
+ * part, not realizing that they should have done "(R)" or something
+ * such as that.
+ */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_dcp_suboption_device_typeofstation, tvb, offset, block_length, ENC_ASCII, pinfo->pool, &typeofstation);
+ pn_append_info(pinfo, dcp_item, ", DeviceVendorValue");
+ proto_item_append_text(block_item, "Device/Manufacturer specific");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info){
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ proto_item_append_text(block_item, ", DeviceVendorValue: \"%s\"", typeofstation);
+
+
+ if (PINFO_FD_VISITED(pinfo) == FALSE) {
+ /* Create a conversation between the MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, need to switch dl_src & dl_dst if not a response
+ * All conversations are based on Device MAC as addr1 */
+ if (is_response) {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ }
+ else {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_NONE, 0, 0, 0);
+ }
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
+ if (station_info == NULL) {
+ station_info = wmem_new0(wmem_file_scope(), stationInfo);
+ init_pnio_rtc1_station(station_info);
+ conversation_add_proto_data(conversation, proto_pn_dcp, station_info);
+ }
+
+ station_info->typeofstation = wmem_strdup(wmem_file_scope(), typeofstation);
+ }
+
+ offset += block_length;
+ break;
+
+ case PNDCP_SUBOPTION_DEVICE_NAMEOFSTATION:
+ /*
+ * XXX - IEC 61158-6-10 Edition 4.0 says, in section 4.3.1.4.15
+ * "Coding of the field NameOfStationValue", that "This field shall
+ * be coded as data type OctetString with 1 to 240 octets. The
+ * definition of IETF RFC 5890 and the following syntax applies: ..."
+ *
+ * RFC 5890 means Punycode; should we translate the domain name to
+ * UTF-8 and show both the untranslated and translated domain name?
+ *
+ * They don't mention anything about the RFC 1035 encoding of
+ * domain names as mentioned in section 3.1 "Name space definitions",
+ * with the labels being counted strings; does that mean that this
+ * is just an ASCII string to be interpreted as a Punycode Unicode
+ * domain name?
+ */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_dcp_suboption_device_nameofstation, tvb, offset, block_length, ENC_ASCII, pinfo->pool, &nameofstation);
+ pn_append_info(pinfo, dcp_item, wmem_strdup_printf(pinfo->pool, ", NameOfStation:\"%s\"", nameofstation));
+ proto_item_append_text(block_item, "Device/NameOfStation");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ proto_item_append_text(block_item, ", \"%s\"", nameofstation);
+
+
+ if (PINFO_FD_VISITED(pinfo) == FALSE) {
+ /* Create a conversation between the MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, need to switch dl_src & dl_dst if not a response
+ * All conversations are based on Device MAC as addr1 */
+ if (is_response) {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ }
+ else {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_NONE, 0, 0, 0);
+ }
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
+ if (station_info == NULL) {
+ station_info = wmem_new0(wmem_file_scope(), stationInfo);
+ init_pnio_rtc1_station(station_info);
+ conversation_add_proto_data(conversation, proto_pn_dcp, station_info);
+ }
+
+ station_info->nameofstation = wmem_strdup(wmem_file_scope(), nameofstation);
+ }
+
+ offset += block_length;
+ break;
+
+ case PNDCP_SUBOPTION_DEVICE_DEV_ID:
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_vendor_id, &vendor_id);
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_id, &device_id);
+
+ if (PINFO_FD_VISITED(pinfo) == FALSE) {
+ /* Create a conversation between the MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ /* Create new conversation, need to switch dl_src & dl_dst if not a response
+ * All conversations are based on Device MAC as addr1 */
+ if (is_response) {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ }
+ else {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_dst, &pinfo->dl_src, CONVERSATION_NONE, 0, 0, 0);
+ }
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
+ if (station_info == NULL) {
+ station_info = wmem_new0(wmem_file_scope(), stationInfo);
+ init_pnio_rtc1_station(station_info);
+ conversation_add_proto_data(conversation, proto_pn_dcp, station_info);
+ }
+
+ station_info->u16Vendor_id = vendor_id;
+ station_info->u16Device_id = device_id;
+ }
+
+
+ pn_append_info(pinfo, dcp_item, ", Dev-ID");
+ proto_item_append_text(block_item, "Device/Device ID");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ proto_item_append_text(block_item, ", VendorID: 0x%04x / DeviceID: 0x%04x", vendor_id, device_id);
+ break;
+ case PNDCP_SUBOPTION_DEVICE_DEV_ROLE:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_role, &device_role);
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_reserved8, NULL);
+ pn_append_info(pinfo, dcp_item, ", Dev-Role");
+ proto_item_append_text(block_item, "Device/Device Role");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info)
+ proto_item_append_text(block_item, ", BlockInfo: %s", rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ if (device_role & 0x01)
+ proto_item_append_text(block_item, ", IO-Device");
+ if (device_role & 0x02)
+ proto_item_append_text(block_item, ", IO-Controller");
+ if (device_role & 0x04)
+ proto_item_append_text(block_item, ", IO-Multidevice");
+ if (device_role & 0x08)
+ proto_item_append_text(block_item, ", PN-Supervisor");
+ break;
+ case PNDCP_SUBOPTION_DEVICE_DEV_OPTIONS:
+ info_str = wmem_strdup_printf(pinfo->pool, ", Dev-Options(%u)", block_length/2);
+ pn_append_info(pinfo, dcp_item, info_str);
+ proto_item_append_text(block_item, "Device/Device Options");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ proto_item_append_text(block_item, ", %u options", block_length/2);
+ for( ; block_length != 0; block_length -= 2) {
+ offset = dissect_PNDCP_Option(tvb, offset, pinfo, tree, NULL /*block_item*/, hf_pn_dcp_option,
+ FALSE /* append_col */);
+ }
+ break;
+ case PNDCP_SUBOPTION_DEVICE_ALIAS_NAME:
+ /*
+ * XXX - IEC 61158-6-10 Edition 4.0, section 4.3.1.4.17 "Coding of
+ * the field AliasNameValue", says this field "shall be coded as
+ * OctetString. The content shall be the concatenation of the content
+ * of the fields NameOfPort and NameOfStation.
+ *
+ * AliasNameValue = NameOfPort + "." + NameOfStation
+ *
+ * " and:
+ *
+ * It says in section 4.3.1.4.16 "Coding of the field NameOfPort"
+ * that "This field shall be coded as OctetString[8] or
+ * OctetString[14] as "port-xyz" or "port-xyz-rstuv" where x, y,
+ * z is in the range "0"-"9" from 001 up to 255 and r, s, t, u, v
+ * is in the range "0"-"9" from 00000 up to 65535. ...
+ * Furthermore, the definition of IETF RFC 5890 shall be applied."
+ *
+ * That suggests that the Octets are probably just ASCII characters;
+ * IETF RFC 5890 means Punycode, but there isn't anything in those
+ * string formats that requires non-ASCII characters - they're
+ * just literally "port-" followed by numbers and hyphens.
+ *
+ * It says in section 4.3.1.4.15 "Coding of the field
+ * NameOfStationValue" that it's a domain name, complete with
+ * RFC 5890 Punycode.
+ */
+ proto_tree_add_item_ret_display_string (tree, hf_pn_dcp_suboption_device_aliasname, tvb, offset, block_length, ENC_ASCII, pinfo->pool, &aliasname);
+ pn_append_info(pinfo, dcp_item, wmem_strdup_printf(pinfo->pool, ", AliasName:\"%s\"", aliasname));
+ proto_item_append_text(block_item, "Device/AliasName");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ proto_item_append_text(block_item, ", \"%s\"", aliasname);
+ offset += block_length;
+ break;
+ case PNDCP_SUBOPTION_DEVICE_DEV_INSTANCE:
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_instance_high, &device_instance_high);
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_instance_low, &device_instance_low);
+ pn_append_info(pinfo, dcp_item, ", Dev-Instance");
+ proto_item_append_text(block_item, "Device/Device Instance");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ proto_item_append_text(block_item, ", InstanceHigh: %d, Instance Low: %d",
+ device_instance_high, device_instance_low);
+ break;
+ case PNDCP_SUBOPTION_DEVICE_OEM_DEV_ID:
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_oem_ven_id, &oem_vendor_id);
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_oem_dev_id, &oem_device_id);
+ pn_append_info(pinfo, dcp_item, ", OEM-Dev-ID");
+ proto_item_append_text(block_item, "Device/OEM Device ID");
+ if(have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if(have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ proto_item_append_text(block_item, ", OEMVendorID: 0x%04x / OEMDeviceID: 0x%04x", oem_vendor_id, oem_device_id);
+ break;
+ case PNDCP_SUBOPTION_DEVICE_RSI_PROPERTIES:
+ sub_item = proto_tree_add_item(tree, hf_pn_dcp_rsi_properties_value, tvb, offset, 2, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_dcp_rsi_properties_value);
+
+ static int* const flags[] = {
+ &hf_pn_dcp_rsi_properties_value_bit0,
+ &hf_pn_dcp_rsi_properties_value_bit1,
+ &hf_pn_dcp_rsi_properties_value_bit2,
+ &hf_pn_dcp_rsi_properties_value_bit3,
+ &hf_pn_dcp_rsi_properties_value_bit4,
+ &hf_pn_dcp_rsi_properties_value_bit5,
+ &hf_pn_dcp_rsi_properties_value_otherbits,
+ NULL
+ };
+
+ proto_tree_add_bitmask(sub_tree, tvb, offset, hf_pn_dcp_rsi_properties_value, ett_pn_dcp_rsi_properties_value, flags, ENC_BIG_ENDIAN);
+
+ offset = offset + 2;
+
+ if (pinfo->fd->visited == FALSE) {
+ /* Create a conversation between the MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
+ if (station_info == NULL) {
+ station_info = wmem_new0(wmem_file_scope(), stationInfo);
+ init_pnio_rtc1_station(station_info);
+ conversation_add_proto_data(conversation, proto_pn_dcp, station_info);
+ }
+ }
+
+ pn_append_info(pinfo, dcp_item, ", RSI-Properties");
+ proto_item_append_text(block_item, "Device/RSI Properties");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
+ }
+
+ return offset;
+}
+
+/* dissect the "tsn" suboption */
+static int
+dissect_PNDCP_Suboption_TSN(tvbuff_t* tvb, int offset, packet_info* pinfo,
+ proto_tree* tree, proto_item* block_item, proto_item* dcp_item,
+ guint8 service_id, gboolean is_response)
+{
+ guint8 suboption;
+ guint16 block_length;
+ char *domain_name;
+ guint16 nme_prio;
+ e_guid_t tsn_domain_uuid;
+ e_guid_t nme_parameter_uuid;
+ e_guid_t nme_name_uuid;
+ guint16 vendor_id;
+ guint16 device_id;
+ guint16 block_info = 0;
+ guint16 block_qualifier = 0;
+ gboolean have_block_info = FALSE;
+ gboolean have_block_qualifier = FALSE;
+ guint8 instance_id_high;
+ guint8 instance_id_low;
+ conversation_t* conversation;
+ stationInfo* station_info;
+ gboolean is_zeros = TRUE;
+
+ /* SuboptionTSN... */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_tsn, &suboption);
+
+ /* DCPBlockLength */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);
+
+ /* BlockInfo? */
+ if (((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
+ have_block_info = TRUE;
+ block_length -= 2;
+ }
+
+ /* BlockQualifier? */
+ if ((service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ have_block_qualifier = TRUE;
+ block_length -= 2;
+ }
+
+ switch (suboption) {
+ case PNDCP_SUBOPTION_TSN_DOMAIN_NAME:
+
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_tsn_domain_uuid, &tsn_domain_uuid);
+ proto_tree_add_item_ret_display_string(tree, hf_pn_dcp_suboption_tsn_domain_name, tvb, offset, (block_length-16), ENC_ASCII | ENC_NA, pinfo->pool, &domain_name);
+
+ pn_append_info(pinfo, dcp_item, ", TSN-Domain Name");
+ proto_item_append_text(block_item, "TSN/TSN-Domain Name");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info)
+ proto_item_append_text(block_item, ", BlockInfo: %s", rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+
+ pn_append_info(pinfo, dcp_item, wmem_strdup_printf(pinfo->pool, ", DomainName:\"%s\"", domain_name));
+ proto_item_append_text(block_item, ", \"%s\"", domain_name);
+ offset += (block_length-16);
+ is_zeros = TRUE;
+
+ for (int i = 0; i < 8; i++)
+ {
+ if (tsn_domain_uuid.data4[i] != 0)
+ {
+ is_zeros = FALSE;
+ break;
+ }
+ }
+
+ if ((tsn_domain_uuid.data1 == 0) && (tsn_domain_uuid.data2 == 0) && (tsn_domain_uuid.data3 == 0) && (is_zeros))
+ proto_item_append_text(block_item, ", No TSN domain assigned");
+ else
+ proto_item_append_text(block_item, ", UUID identifying a TSN domain using SNMP/ LLDP/ DCP");
+
+ break;
+
+ case PNDCP_SUBOPTION_TSN_NME_MANAGER:
+
+ pn_append_info(pinfo, dcp_item, ", NME-Manager");
+ proto_item_append_text(block_item, "TSN/NME-Manager");
+
+ if (have_block_qualifier)
+ {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+
+ if (have_block_info)
+ {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_tsn_nme_prio, &nme_prio);
+ proto_item_append_text(block_item, ", BlockInfo: %s", rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+
+ if (nme_prio == 0x0000)
+ proto_item_append_text(block_item, ", Highest priority NME manager");
+ else if ((0x0001 <= nme_prio) && (nme_prio <= 0x3000))
+ proto_item_append_text(block_item, ", High priorities for NME manager");
+ else if ((0x3001 <= nme_prio) && (nme_prio <= 0x9FFF))
+ proto_item_append_text(block_item, ", Low priorities for NME manager");
+ else if (0xA000 == nme_prio)
+ proto_item_append_text(block_item, ", Lowest priority for NME manager / Default priority for NME manager");
+ else
+ proto_item_append_text(block_item, ", Reserved");
+ }
+
+ break;
+
+ case PNDCP_SUBOPTION_TSN_NME_PARAMETER_UUID:
+
+ pn_append_info(pinfo, dcp_item, ", NME-Parameter UUID");
+ proto_item_append_text(block_item, "TSN/NME-Parameter UUID");
+
+ if (block_length > 0)
+ {
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_tsn_nme_parameter_uuid, &nme_parameter_uuid);
+
+ if (have_block_qualifier)
+ {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info)
+ proto_item_append_text(block_item, ", BlockInfo: %s", rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+
+ is_zeros = TRUE;
+
+ for (int i = 0; i < 8; i++)
+ {
+ if (nme_parameter_uuid.data4[i] != 0)
+ {
+ is_zeros = FALSE;
+ break;
+ }
+ }
+ if ((nme_parameter_uuid.data1 == 0) && (nme_parameter_uuid.data2 == 0) && (nme_parameter_uuid.data3 == 0) && (is_zeros))
+ proto_item_append_text(block_item, ", Unconfigured");
+ else
+ proto_item_append_text(block_item, ", UUID identifying an NME parameter set within the TSN domain.");
+ }
+ break;
+
+ case PNDCP_SUBOPTION_TSN_NME_AGENT:
+
+ pn_append_info(pinfo, dcp_item, ", NME-Agent");
+ proto_item_append_text(block_item, "TSN/NME-Agent");
+
+ if (have_block_qualifier)
+ {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+
+ if (have_block_info)
+ {
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_tsn_nme_agent, &nme_name_uuid);
+ proto_item_append_text(block_item, ", BlockInfo: %s", rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+
+ is_zeros = TRUE;
+ for (int i = 0; i < 8; i++)
+ {
+ if (nme_name_uuid.data4[i] != 0)
+ {
+ is_zeros = FALSE;
+ break;
+ }
+ }
+
+ if ((nme_name_uuid.data1 == 0) && (nme_name_uuid.data2 == 0) && (nme_name_uuid.data3 == 0) && (is_zeros))
+ proto_item_append_text(block_item, ", No NME assigned");
+ else
+ proto_item_append_text(block_item, ", UUID identifying an NME using SNMP / LLDP / DCP");
+ }
+ break;
+
+ case PNDCP_SUBOPTION_TSN_CIM_INTERFACE:
+
+ pn_append_info(pinfo, dcp_item, ", CIM-Interface");
+ proto_item_append_text(block_item, "TSN/CIM-Interface");
+
+ if (have_block_qualifier)
+ {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info)
+ {
+ // CIMVDIValue
+ dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_vendor_id_high, &vendor_id);
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_vendor_id_low, &vendor_id);
+
+ dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_device_id_high, &device_id);
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_device_id_low, &device_id);
+
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_instance_id_high, &instance_id_high);
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_instance_id_low, &instance_id_low);
+
+ if (pinfo->fd->visited == FALSE) {
+ /* Create a conversation between the MAC addresses */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ if (conversation == NULL) {
+ conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
+ if (station_info == NULL) {
+ station_info = wmem_new0(wmem_file_scope(), stationInfo);
+ init_pnio_rtc1_station(station_info);
+ conversation_add_proto_data(conversation, proto_pn_dcp, station_info);
+ }
+
+ station_info->u16Vendor_id = vendor_id;
+ station_info->u16Device_id = device_id;
+ }
+
+ proto_item_append_text(block_item, ", BlockInfo: %s", rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+
+ proto_item_append_text(block_item, ", VendorID: 0x%04x / DeviceID: 0x%04x / InstanceIDHigh: 0x%04x / InstanceIDLow: 0x%04x", vendor_id, device_id, instance_id_high, instance_id_low);
+ }
+ break;
+
+ default:
+ pn_append_info(pinfo, dcp_item, ", TSN/Reserved");
+ proto_item_append_text(block_item, "TSN/Reserved");
+ }
+
+ return offset;
+}
+
+/* dissect the "DHCP" suboption */
+static int
+dissect_PNDCP_Suboption_DHCP(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
+ guint8 service_id _U_, gboolean is_response _U_)
+{
+ guint8 suboption;
+ guint8 option_code = 0;
+ guint16 block_length;
+ guint16 block_info = 0;
+ guint16 block_qualifier = 0;
+ guint8 dhcpparameterlength = 0;
+ guint8 dhcpparameterdata = 0;
+ guint8 dhcpcontrolparameterdata = 0;
+ gboolean have_block_info = FALSE;
+ gboolean have_block_qualifier = FALSE;
+ int expected_offset;
+
+
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp, &suboption);
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);
+
+ expected_offset = offset + block_length;
+
+ /* BlockInfo? */
+ if ( ((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
+ have_block_info=TRUE;
+ block_length -= 2;
+ }
+ /* BlockQualifier? */
+ if ( (service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ have_block_qualifier=TRUE;
+ block_length -= 2;
+ }
+
+ switch (suboption) {
+ case PNDCP_SUBOPTION_DHCP_CLIENT_ID:
+ pn_append_info(pinfo, dcp_item, ", DHCP client identifier");
+ proto_item_append_text(block_item, "DHCP/Client-ID");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_option_code, &option_code);
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_parameter_length, &dhcpparameterlength);
+ if (dhcpparameterlength > 0) {
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_parameter_data, &dhcpparameterdata);
+ if (dhcpparameterlength == 1) {
+ if (dhcpparameterdata == 1) {
+ proto_item_append_text(block_item, ", Client-ID: MAC Address");
+ }
+ else {
+ proto_item_append_text(block_item, ", Client-ID: Name of Station");
+ }
+ }
+ else {
+ proto_item_append_text(block_item, ", Client-ID: Arbitrary");
+ /*
+ * XXX - IEC 61158-6-10 Edition 4.0, section 4.3.1.4.21.5
+ * "Use of arbitrary client identifier", that this is an
+ * OctetString to be used as a client identifier with DHCP.
+ *
+ * Does that mean it should be FT_BYTES, possibly with
+ * the BASE_SHOW_ASCII_PRINTABLE flag to show it as ASCII
+ * iff it's printable? Or should packet-dhcp.c export
+ * dissect_dhcpopt_client_identifier(), so that we can
+ * use its heuristics?
+ */
+ proto_tree_add_item(tree, hf_pn_dcp_suboption_dhcp_arbitrary_client_id, tvb, offset, dhcpparameterlength - 1, ENC_ASCII);
+ offset += (dhcpparameterlength-1);
+ }
+ }
+ break;
+ case PNDCP_SUBOPTION_DHCP_CONTROL_FOR_ADDRESS_RES:
+ pn_append_info(pinfo, dcp_item, ", Control DHCP for address resolution");
+ proto_item_append_text(block_item, "DHCP/Control DHCP for address resolution");
+ if (have_block_qualifier) {
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ }
+ if (have_block_info) {
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ }
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_option_code, &option_code);
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_parameter_length, &dhcpparameterlength);
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_control_parameter_data, &dhcpcontrolparameterdata);
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
+ }
+
+ if (expected_offset > offset) {
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, expected_offset - offset, "Undefined");
+ }
+
+ return offset;
+}
+
+
+/* dissect the "control" suboption */
+static int
+dissect_PNDCP_Suboption_Control(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
+ guint8 service_id _U_, gboolean is_response _U_)
+{
+ guint8 suboption;
+ guint16 block_length;
+ guint16 block_qualifier;
+ guint16 BlockQualifier;
+ guint16 u16SignalValue;
+ gchar *info_str;
+ guint8 block_error;
+ proto_item *item = NULL;
+
+
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_control, &suboption);
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);
+
+ if (service_id == PNDCP_SERVICE_ID_SET && block_length == 0) {
+ pn_append_info(pinfo, dcp_item, ", Erroneous DCPSet block");
+ proto_item_append_text(block_item, "Control/Erroneous DCPSet block");
+ }
+ else {
+ switch (suboption) {
+ case PNDCP_SUBOPTION_CONTROL_START_TRANS:
+ pn_append_info(pinfo, dcp_item, ", Start-Trans");
+ proto_item_append_text(block_item, "Control/Start-Transaction");
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ break;
+ case PNDCP_SUBOPTION_CONTROL_END_TRANS:
+ pn_append_info(pinfo, dcp_item, ", End-Trans");
+ proto_item_append_text(block_item, "Control/End-Transaction");
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ break;
+ case PNDCP_SUBOPTION_CONTROL_SIGNAL:
+ pn_append_info(pinfo, dcp_item, ", Signal");
+ proto_item_append_text(block_item, "Control/Signal");
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ block_length -= 2;
+
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_control_signal_value, &u16SignalValue);
+ break;
+ case PNDCP_SUBOPTION_CONTROL_RESPONSE:
+ proto_item_append_text(block_item, "Control/Response");
+ offset = dissect_PNDCP_Option(tvb, offset, pinfo, tree, block_item, hf_pn_dcp_suboption_control_option,
+ FALSE /* append_col */);
+ block_error = tvb_get_guint8(tvb, offset);
+ if (tree) {
+ item = proto_tree_add_uint(tree, hf_pn_dcp_block_error, tvb, offset, 1, block_error);
+ }
+ offset += 1;
+ if (block_error != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_dcp_block_error_unknown, "%s",
+ val_to_str_const(block_error, pn_dcp_block_error, "Unknown"));
+ }
+ info_str = wmem_strdup_printf(pinfo->pool, ", Response(%s)",
+ val_to_str_const(block_error, pn_dcp_block_error, "Unknown"));
+ pn_append_info(pinfo, dcp_item, info_str);
+ proto_item_append_text(block_item, ", BlockError: %s",
+ val_to_str_const(block_error, pn_dcp_block_error, "Unknown"));
+
+ break;
+ case PNDCP_SUBOPTION_CONTROL_FACT_RESET:
+ pn_append_info(pinfo, dcp_item, ", Reset FactorySettings");
+ proto_item_append_text(block_item, "Control/Reset FactorySettings");
+ block_length -= 2;
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_blockqualifier, &BlockQualifier);
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(BlockQualifier, pn_dcp_suboption_other, "reserved"));
+ block_length -= 2;
+ break;
+
+ case PNDCP_SUBOPTION_CONTROL_RESET_TO_FACT:
+ pn_append_info(pinfo, dcp_item, ", Reset to Factory");
+ proto_item_append_text(block_item, "Reset to FactorySettings");
+
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_blockqualifier_r2f, &BlockQualifier);
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(BlockQualifier, pn_dcp_BlockQualifier, "reserved"));
+ block_length -= 2;
+
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
+ }
+ }
+
+ return offset;
+}
+
+
+/* dissect the "deviceinitaitve" suboption */
+static int
+dissect_PNDCP_Suboption_DeviceInitiative(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
+ guint8 service_id, gboolean is_response)
+{
+ guint8 suboption;
+ guint16 block_length;
+ guint16 block_info;
+ guint16 block_qualifier;
+ guint16 value;
+
+
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_deviceinitiative, &suboption);
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);
+
+ pn_append_info(pinfo, dcp_item, ", DeviceInitiative");
+ proto_item_append_text(block_item, "DeviceInitiative/DeviceInitiative");
+
+ /* BlockInfo? */
+ if ( ((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
+ ((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
+ proto_item_append_text(block_item, ", BlockInfo: %s",
+ rval_to_str_const(block_info, pn_dcp_block_info, "Unknown"));
+ block_length -= 2;
+ }
+
+ /* BlockQualifier? */
+ if ( (service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
+ proto_item_append_text(block_item, ", BlockQualifier: %s",
+ val_to_str_const(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
+ block_length -= 2;
+ }
+
+ /* DeviceInitiativeValue */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_deviceinitiative_value, &value);
+
+ return offset;
+}
+
+
+/* dissect the "all" suboption */
+static int
+dissect_PNDCP_Suboption_All(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
+ guint8 service_id _U_, gboolean is_response _U_)
+{
+ guint8 suboption;
+ guint16 block_length;
+
+
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_all, &suboption);
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);
+
+ switch (suboption) {
+ case 255: /* All */
+ pn_append_info(pinfo, dcp_item, ", All");
+ proto_item_append_text(block_item, "All/All");
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
+ }
+
+ return offset;
+}
+
+
+/* dissect the "manufacturer" suboption */
+static int
+dissect_PNDCP_Suboption_Manuf(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
+ guint8 service_id _U_, gboolean is_response _U_)
+{
+ guint16 block_length;
+
+ offset = dissect_pn_uint8( tvb, offset, pinfo, tree, hf_pn_dcp_suboption_manuf, NULL);
+
+ pn_append_info(pinfo, dcp_item, ", Manufacturer Specific");
+ proto_item_append_text(block_item, "Manufacturer Specific");
+
+ if (tvb_reported_length_remaining(tvb, offset)>0)
+ {
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
+ }
+ return offset;
+}
+
+
+/* dissect one DCP block */
+static int
+dissect_PNDCP_Block(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, proto_item *dcp_item,
+ guint8 service_id, gboolean is_response)
+{
+ guint8 option;
+ proto_item *block_item;
+ proto_tree *block_tree;
+ int ori_offset = offset;
+
+ /* subtree for block */
+ block_item = proto_tree_add_none_format(tree, hf_pn_dcp_block,
+ tvb, offset, 0, "Block: ");
+ block_tree = proto_item_add_subtree(block_item, ett_pn_dcp_block);
+
+
+ offset = dissect_pn_uint8(tvb, offset, pinfo, block_tree, hf_pn_dcp_option, &option);
+
+ if (option == PNDCP_OPTION_IP)
+ {
+ offset = dissect_PNDCP_Suboption_IP(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
+ }
+ else if (option == PNDCP_OPTION_DEVICE)
+ {
+ offset = dissect_PNDCP_Suboption_Device(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
+ }
+ else if (option == PNDCP_OPTION_DHCP)
+ {
+ offset = dissect_PNDCP_Suboption_DHCP(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
+ }
+ else if (option == PNDCP_OPTION_CONTROL)
+ {
+ offset = dissect_PNDCP_Suboption_Control(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
+ }
+ else if (option == PNDCP_OPTION_DEVICEINITIATIVE)
+ {
+ offset = dissect_PNDCP_Suboption_DeviceInitiative(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
+ }
+ else if (option == PNDCP_OPTION_TSN)
+ {
+ offset = dissect_PNDCP_Suboption_TSN(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
+ }
+ else if (option == PNDCP_OPTION_ALLSELECTOR)
+ {
+ offset = dissect_PNDCP_Suboption_All(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
+ }
+ else if (PNDCP_OPTION_MANUF_X80 <= option && option <= PNDCP_OPTION_MANUF_XFE)
+ {
+ offset = dissect_PNDCP_Suboption_Manuf(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
+ }
+ else
+ {
+ pn_append_info(pinfo, dcp_item, ", Reserved");
+ proto_item_append_text(block_item, "Reserved");
+ /* there isn't a predefined suboption type for reserved option, rest of the block will be seen as padding */
+ }
+
+ proto_item_set_len(block_item, offset-ori_offset);
+
+ if (((offset-ori_offset) & 1) && (tvb_reported_length_remaining(tvb, offset) > 0)) {
+ /* we have an odd number of bytes in this block, add a padding byte */
+ offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
+ }
+
+ return offset;
+}
+
+
+/* dissect a whole DCP PDU */
+static void
+dissect_PNDCP_PDU(tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *tree, proto_item *dcp_item)
+{
+ guint8 service_id;
+ guint8 service_type;
+ guint32 xid;
+ guint16 response_delay;
+ guint16 data_length;
+ int offset = 0;
+ gchar *xid_str;
+ gboolean is_response = FALSE;
+
+
+ offset = dissect_pn_uint8 (tvb, offset, pinfo, tree, hf_pn_dcp_service_id, &service_id);
+ offset = dissect_pn_uint8 (tvb, offset, pinfo, tree, hf_pn_dcp_service_type, &service_type);
+ proto_tree_add_item_ret_uint(tree, hf_pn_dcp_xid, tvb, offset, 4, ENC_BIG_ENDIAN, &xid);
+ offset += 4;
+ if (service_id == PNDCP_SERVICE_ID_IDENTIFY && service_type == PNDCP_SERVICE_TYPE_REQUEST) {
+ /* multicast header */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_response_delay, &response_delay);
+ } else {
+ /* unicast header */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_reserved16, NULL);
+ }
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_data_length, &data_length);
+
+ switch (service_id) {
+ case PNDCP_SERVICE_ID_GET:
+ pn_append_info(pinfo, dcp_item, "Get");
+ break;
+ case PNDCP_SERVICE_ID_SET:
+ pn_append_info(pinfo, dcp_item, "Set");
+ break;
+ case PNDCP_SERVICE_ID_IDENTIFY:
+ pn_append_info(pinfo, dcp_item, "Ident");
+ break;
+ case PNDCP_SERVICE_ID_HELLO:
+ pn_append_info(pinfo, dcp_item, "Hello");
+ break;
+ default:
+ dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length_remaining(tvb, offset));
+ return;
+ }
+
+ switch (service_type) {
+ case PNDCP_SERVICE_TYPE_REQUEST:
+ pn_append_info(pinfo, dcp_item, " Req");
+ break;
+ case PNDCP_SERVICE_TYPE_RESPONSE_SUCCESS:
+ pn_append_info(pinfo, dcp_item, " Ok ");
+ is_response = TRUE;
+ break;
+ case PNDCP_SERVICE_TYPE_RESPONSE_UNSUPPORTED:
+ pn_append_info(pinfo, dcp_item, " unsupported");
+ is_response = TRUE;
+ break;
+ default:
+ dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length_remaining(tvb, offset));
+ return;
+ }
+
+ xid_str = wmem_strdup_printf(pinfo->pool, ", Xid:0x%x", xid);
+ pn_append_info(pinfo, dcp_item, xid_str);
+
+ /* dissect a number of blocks (depending on the remaining length) */
+ while(data_length) {
+ int ori_offset = offset;
+
+ if (service_id == PNDCP_SERVICE_ID_GET && service_type == PNDCP_SERVICE_TYPE_REQUEST) {
+ /* Selectors */
+ offset = dissect_PNDCP_Option(tvb, offset, pinfo,
+ tree, dcp_item, hf_pn_dcp_option, TRUE /* append_col */);
+ } else {
+ offset = dissect_PNDCP_Block(tvb, offset, pinfo, tree, dcp_item, service_id, is_response);
+ }
+ /* prevent an infinite loop */
+ if (offset <= ori_offset || data_length < (offset - ori_offset)) {
+ proto_tree_add_expert(tree, pinfo, &ei_pn_dcp_block_parse_error,
+ tvb, ori_offset, tvb_captured_length_remaining(tvb, ori_offset));
+ break;
+ }
+ data_length -= (offset - ori_offset);
+ }
+}
+
+
+/* possibly dissect a PN-RT packet (frame ID must be in the appropriate range) */
+static gboolean
+dissect_PNDCP_Data_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ void *data)
+{
+ /* the tvb will NOT contain the frame_id here, so get it from dissection data! */
+ guint16 u16FrameID = GPOINTER_TO_UINT(data);
+ proto_item *item;
+ proto_tree *dcp_tree;
+
+
+ /* frame id must be in valid range (acyclic Real-Time, DCP) */
+ if (u16FrameID < FRAME_ID_DCP_HELLO || u16FrameID > FRAME_ID_DCP_IDENT_RES) {
+ /* we are not interested in this packet */
+ return FALSE;
+ }
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-DCP");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* subtree for DCP */
+ item = proto_tree_add_protocol_format(tree, proto_pn_dcp, tvb, 0, tvb_get_ntohs(tvb, 8) + 10,
+ "PROFINET DCP, ");
+ dcp_tree = proto_item_add_subtree(item, ett_pn_dcp);
+
+ /* dissect this PDU */
+ dissect_PNDCP_PDU(tvb, pinfo, dcp_tree, item);
+
+ return TRUE;
+}
+
+
+void
+proto_register_pn_dcp (void)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_dcp_service_id,
+ { "ServiceID", "pn_dcp.service_id",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_service_id), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_service_type,
+ { "ServiceType", "pn_dcp.service_type",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_service_type), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_xid,
+ { "Xid", "pn_dcp.xid",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_reserved8,
+ { "Reserved", "pn_dcp.reserved8",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_reserved16,
+ { "Reserved", "pn_dcp.reserved16",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_response_delay,
+ { "ResponseDelay", "pn_dcp.response_delay",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_data_length,
+ { "DCPDataLength", "pn_dcp.data_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_block_length,
+ { "DCPBlockLength", "pn_dcp.block_length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_option,
+ { "Option", "pn_dcp.option",
+ FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(pn_dcp_option), 0x0,
+ NULL, HFILL }},
+
+#if 0
+ { &hf_pn_dcp_suboption,
+ { "Suboption", "pn_dcp.suboption",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+#endif
+
+ { &hf_pn_dcp_block_error,
+ { "BlockError", "pn_dcp.block_error",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_block_error), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_block,
+ { "Block", "pn_dcp.block",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_block_info,
+ { "BlockInfo", "pn_dcp.block_info",
+ FT_UINT16, BASE_DEC|BASE_RANGE_STRING, RVALS(pn_dcp_block_info), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_block_qualifier,
+ { "BlockQualifier", "pn_dcp.block_qualifier",
+ FT_UINT16, BASE_DEC, VALS(pn_dcp_block_qualifier), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_blockqualifier_r2f,
+ { "BlockQualifier: ResettoFactory", "pn_dcp.block_qualifier_reset",
+ FT_UINT16, BASE_DEC, VALS(pn_dcp_BlockQualifier), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_blockqualifier,
+ { "BlockQualifier: ResetFactorySettings", "pn_dcp.block_qualifier_reset",
+ FT_UINT16, BASE_DEC, VALS(pn_dcp_suboption_other), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_ip,
+ { "Suboption", "pn_dcp.suboption_ip",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_ip), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_ip_block_info,
+ { "BlockInfo", "pn_dcp.suboption_ip_block_info",
+ FT_UINT16, BASE_DEC, VALS(pn_dcp_suboption_ip_block_info), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_ip_mac_address,
+ { "MAC Address", "pn_dcp.suboption_ip_mac_address",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_ip_ip,
+ { "IPaddress", "pn_dcp.suboption_ip_ip",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_ip_subnetmask,
+ { "Subnetmask", "pn_dcp.suboption_ip_subnetmask",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_ip_standard_gateway,
+ { "StandardGateway", "pn_dcp.suboption_ip_standard_gateway",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device,
+ { "Suboption", "pn_dcp.suboption_device",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_device), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_typeofstation,
+ { "DeviceVendorValue", "pn_dcp.suboption_device_devicevendorvalue",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_nameofstation,
+ { "NameOfStation", "pn_dcp.suboption_device_nameofstation",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_vendor_id,
+ { "VendorID", "pn_dcp.suboption_vendor_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_id,
+ { "DeviceID", "pn_dcp.suboption_device_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_role,
+ { "DeviceRoleDetails", "pn_dcp.suboption_device_role",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_aliasname,
+ { "AliasName", "pn_dcp.suboption_device_aliasname",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_instance_high,
+ { "DeviceInstanceHigh", "pn_dcp.suboption_device_instance",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_instance_low,
+ { "DeviceInstanceLow", "pn_dcp.suboption_device_instance",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_oem_ven_id,
+ { "OEMVendorID", "pn_dcp.suboption_device_oem_ven_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_device_oem_dev_id,
+ { "OEMDeviceID", "pn_dcp.suboption_device_oem_dev_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_rsi_properties_value,
+ { "RsiPropertiesValue", "pn_dcp.suboption_device_rsi_properties_value",
+ FT_UINT16, BASE_HEX, 0, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_rsi_properties_value_bit0,
+ { "IP Stack", "pn_dcp.suboption_device_rsi_properties_value.bit0",
+ FT_BOOLEAN, 16, TFS(&pn_dcp_rsi_properties_value_bit), 0x0001,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_rsi_properties_value_bit1,
+ { "CLRPC Interface", "pn_dcp.suboption_device_rsi_properties_value.bit1",
+ FT_BOOLEAN, 16, TFS(&pn_dcp_rsi_properties_value_bit), 0x0002,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_rsi_properties_value_bit2,
+ { "RSI AR Interface", "pn_dcp.suboption_device_rsi_properties_value.bit2",
+ FT_BOOLEAN, 16, TFS(&pn_dcp_rsi_properties_value_bit), 0x0004,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_rsi_properties_value_bit3,
+ { "RSI AR Read Implicit Interface", "pn_dcp.suboption_device_rsi_properties_value.bit3",
+ FT_BOOLEAN, 16, TFS(&pn_dcp_rsi_properties_value_bit), 0x0008,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_rsi_properties_value_bit4,
+ { "RSI CIM Interface", "pn_dcp.suboption_device_rsi_properties_value.bit4",
+ FT_BOOLEAN, 16, TFS(&pn_dcp_rsi_properties_value_bit), 0x0010,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_rsi_properties_value_bit5,
+ { "RSI CIM Read Implicit Interface", "pn_dcp.suboption_device_rsi_properties_value.bit5",
+ FT_BOOLEAN, 16, TFS(&pn_dcp_rsi_properties_value_bit), 0x0020,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_rsi_properties_value_otherbits,
+ { "RsiPropertiesValue.Bit6-15", "pn_dcp.suboption_device_rsi_properties_value.otherbits",
+ FT_UINT16, BASE_HEX, NULL, 0xFFC0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_vendor_id_high,
+ { "VendorIDHigh", "pn_dcp.vendor_id_high",
+ FT_UINT16, BASE_HEX, NULL, 0xFF00,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_vendor_id_low,
+ { "VendorIDLow", "pn_dcp.vendor_id_low",
+ FT_UINT16, BASE_HEX, NULL, 0x00FF,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_device_id_high,
+ { "DeviceIDHigh", "pn_dcp.device_id_high",
+ FT_UINT16, BASE_HEX, NULL, 0xFF00,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_device_id_low,
+ { "DeviceIDLow", "pn_dcp.device_id_low",
+ FT_UINT16, BASE_HEX, NULL, 0x00FF,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_instance_id_high,
+ { "InstanceHigh", "pn_dcp.instance_id_high",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_instance_id_low,
+ { "InstanceLow", "pn_dcp.instance_id_low",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_dhcp,
+ { "Suboption", "pn_dcp.suboption_dhcp",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_dhcp), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_dhcp_option_code,
+ { "Option-Code", "pn_dcp.suboption_dhcp_option_code",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_dhcp), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_dhcp_arbitrary_client_id,
+ { "Client ID", "pn_dcp.suboption_dhcp_client_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_dhcp_parameter_length,
+ { "DHCP Parameter Length", "pn_dcp.suboption_dhcp_parameter_length",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_dhcp_parameter_data,
+ { "DHCP Parameter Data", "pn_dcp.suboption_dhcp_parameter_data",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_dhcp_control_parameter_data,
+ { "DHCP Parameter Data", "pn_dcp.suboption_dhcp_parameter_data",
+ FT_UINT8, BASE_HEX, VALS(pn_dcp_suboption_dhcp_control_parameter_data), 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_control,
+ { "Suboption", "pn_dcp.suboption_control",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_control), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_control_option,
+ { "Option", "pn_dcp.suboption_control_option",
+ FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(pn_dcp_option), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_control_signal_value,
+ { "SignalValue", "pn_dcp.suboption_control_signal_value",
+ FT_UINT16, BASE_HEX, VALS(pn_dcp_suboption_control_signal_value), 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_deviceinitiative,
+ { "Suboption", "pn_dcp.suboption_deviceinitiative",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_deviceinitiative), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_deviceinitiative_value,
+ { "DeviceInitiativeValue", "pn_dcp.deviceinitiative_value",
+ FT_UINT16, BASE_DEC, VALS(pn_dcp_deviceinitiative_value), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_tsn,
+ { "Suboption", "pn_dcp.suboption_tsn",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_tsn), 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_tsn_domain_name,
+ { "TSNDomainName", "pn_dcp.suboption_tsn_domain_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_tsn_domain_uuid,
+ { "TSNDomainUUID", "pn_dcp.tsn_domain_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_tsn_nme_prio,
+ { "NMEPrio", "pn_dcp.suboption_tsn_nme_prio",
+ FT_UINT16, BASE_DEC | BASE_RANGE_STRING, RVALS(pn_dcp_suboption_tsn_nme_prio), 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_tsn_nme_parameter_uuid,
+ { "NMEParameterUUID", "pn_dcp.suboption_tsn_nme_parameter_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_tsn_nme_agent,
+ { "NMEAgent", "pn_dcp.suboption_tsn_nme_agent",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_dcp_suboption_all,
+ { "Suboption", "pn_dcp.suboption_all",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_all), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_dcp_suboption_manuf,
+ { "Suboption", "pn_dcp.suboption_manuf",
+ FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_manuf), 0x0,
+ NULL, HFILL }},
+
+ };
+
+ static gint *ett[] = {
+ &ett_pn_dcp,
+ &ett_pn_dcp_block,
+ &ett_pn_dcp_rsi_properties_value
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_pn_dcp_block_parse_error, { "pn_dcp.block_error.parse", PI_PROTOCOL, PI_ERROR, "parse error", EXPFILL }},
+ { &ei_pn_dcp_block_error_unknown, { "pn_dcp.block_error.unknown", PI_RESPONSE_CODE, PI_CHAT, "Unknown", EXPFILL }},
+ { &ei_pn_dcp_ip_conflict, { "pn_dcp.ip_conflict", PI_RESPONSE_CODE, PI_NOTE, "IP address conflict detected!", EXPFILL }},
+ };
+
+ expert_module_t* expert_pn_dcp;
+
+ proto_pn_dcp = proto_register_protocol ("PROFINET DCP", "PN-DCP", "pn_dcp");
+ proto_register_field_array (proto_pn_dcp, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ expert_pn_dcp = expert_register_protocol(proto_pn_dcp);
+ expert_register_field_array(expert_pn_dcp, ei, array_length(ei));
+}
+
+void
+proto_reg_handoff_pn_dcp (void)
+{
+ /* register ourself as an heuristic pn-rt payload dissector */
+ heur_dissector_add("pn_rt", dissect_PNDCP_Data_heur, "PROFINET DCP IO", "pn_dcp_pn_rt", proto_pn_dcp, HEURISTIC_ENABLE);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-pn-mrp.c b/plugins/epan/profinet/packet-pn-mrp.c
new file mode 100644
index 0000000..9efafe7
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn-mrp.c
@@ -0,0 +1,675 @@
+/* packet-pn-mrp.c
+ * Routines for PN-MRP (PROFINET Media Redundancy Protocol)
+ * packet dissection.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/oui.h>
+#include <epan/etypes.h>
+#include <epan/dissectors/packet-dcerpc.h>
+
+#include "packet-pn.h"
+
+void proto_register_pn_mrp(void);
+void proto_reg_handoff_pn_mrp(void);
+
+static dissector_handle_t mrp_handle;
+
+static int proto_pn_mrp = -1;
+
+static int hf_pn_mrp_type = -1;
+static int hf_pn_mrp_length = -1;
+static int hf_pn_mrp_version = -1;
+static int hf_pn_mrp_sequence_id = -1;
+static int hf_pn_mrp_sa = -1;
+static int hf_pn_mrp_prio = -1;
+static int hf_pn_mrp_port_role = -1;
+static int hf_pn_mrp_ring_state = -1;
+static int hf_pn_mrp_interval = -1;
+static int hf_pn_mrp_transition = -1;
+static int hf_pn_mrp_time_stamp = -1;
+static int hf_pn_mrp_blocked = -1;
+static int hf_pn_mrp_domain_uuid = -1;
+static int hf_pn_mrp_oui = -1;
+static int hf_pn_mrp_ed1type = -1;
+static int hf_pn_mrp_ed1_manufacturer_data = -1;
+static int hf_pn_mrp_sub_tlv_header_type = -1;
+static int hf_pn_mrp_sub_tlv_header_length = -1;
+static int hf_pn_mrp_sub_option2 = -1;
+static int hf_pn_mrp_other_mrm_prio = -1;
+static int hf_pn_mrp_other_mrm_sa = -1;
+static int hf_pn_mrp_manufacturer_data = -1;
+
+static gint ett_pn_mrp = -1;
+static gint ett_pn_mrp_type = -1;
+static gint ett_pn_sub_tlv = -1;
+
+static const value_string pn_mrp_block_type_vals[] = {
+ { 0x00, "MRP_End" },
+ { 0x01, "MRP_Common" },
+ { 0x02, "MRP_Test" },
+ { 0x03, "MRP_TopologyChange" },
+ { 0x04, "MRP_LinkDown" },
+ { 0x05, "MRP_LinkUp" },
+ { 0x06, "MRP_InTest" },
+ { 0x07, "MRP_InTopologyChange" },
+ { 0x08, "MRP_InLinkDown" },
+ { 0x09, "MRP_InLinkUp" },
+ { 0x0A, "MRP_InLinkStatusPoll" },
+ /*0x0B - 0x7E Reserved */
+ { 0x7F, "MRP_Option (Organizationally Specific)"},
+ { 0, NULL },
+};
+
+static const value_string pn_mrp_oui_vals[] = {
+ { OUI_PROFINET, "PROFINET" },
+ { OUI_SIEMENS, "SIEMENS" },
+
+ { 0, NULL }
+};
+
+
+
+static const value_string pn_mrp_port_role_vals[] = {
+ { 0x0000, "Primary ring port" },
+ { 0x0001, "Secondary ring port"},
+ /*0x0002 - 0xFFFF Reserved */
+
+ { 0, NULL }
+};
+
+#if 0
+static const value_string pn_mrp_role_vals[] = {
+ { 0x0000, "Media redundancy disabled" },
+ { 0x0001, "Media redundancy client" },
+ { 0x0002, "Media redundancy manager" },
+ { 0x0003, "Media redundancy manager (auto)" },
+ /*0x0004 - 0xFFFF Reserved */
+
+ { 0, NULL }
+};
+#endif
+
+static const value_string pn_mrp_ring_state_vals[] = {
+ { 0x0000, "Ring open" },
+ { 0x0001, "Ring closed"},
+ /*0x0002 - 0xFFFF Reserved */
+
+ { 0, NULL }
+};
+
+
+#if 0
+static const value_string pn_mrp_prio_vals[] = {
+ { 0x8000, "Default priority for redundancy manager" },
+
+ { 0, NULL }
+};
+#endif
+
+static const value_string pn_mrp_sub_tlv_header_type_vals[] = {
+ /* 0x00 Reserved */
+ { 0x01, "MRP_TestMgrNAck" },
+ { 0x02, "MRP_TestPropagate" },
+ { 0x03, "MRP_AutoMgr" },
+ /* 0x04 - 0xF0 Reserved for IEC specific functions */
+ { 0xF1, "Manufacturer specific functions" },
+ { 0xF2, "Manufacturer specific functions" },
+ { 0xF3, "Manufacturer specific functions" },
+ { 0xF4, "Manufacturer specific functions" },
+ { 0xF5, "Manufacturer specific functions" },
+ { 0xF6, "Manufacturer specific functions" },
+ { 0xF7, "Manufacturer specific functions" },
+ { 0xF8, "Manufacturer specific functions" },
+ { 0xF9, "Manufacturer specific functions" },
+ { 0xFA, "Manufacturer specific functions" },
+ { 0xFB, "Manufacturer specific functions" },
+ { 0xFC, "Manufacturer specific functions" },
+ { 0xFD, "Manufacturer specific functions" },
+ { 0xFE, "Manufacturer specific functions" },
+ { 0xFF, "Manufacturer specific functions" },
+ { 0, NULL },
+};
+
+static int
+dissect_PNMRP_Common(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_)
+{
+ guint16 sequence_id;
+ e_guid_t uuid;
+
+
+ /* MRP_SequenceID */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_sequence_id, &sequence_id);
+
+ /* MRP_DomainUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_mrp_domain_uuid, &uuid);
+
+ return offset;
+}
+
+
+static int
+dissect_PNMRP_Link(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_)
+{
+ guint8 mac[6];
+ guint16 port_role;
+ guint16 interval;
+ guint16 blocked;
+ proto_item *sub_item;
+
+ /* MRP_SA */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_mrp_sa, mac);
+
+ /* MRP_PortRole */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_port_role, &port_role);
+
+ /* MRP_Interval */
+ offset = dissect_pn_uint16_ret_item(tvb, offset, pinfo, tree, hf_pn_mrp_interval, &interval, &sub_item);
+ if (tree)
+ {
+ proto_item_append_text(sub_item," Interval for next topology change event (in ms)");
+ if (interval <0x07D1)
+ proto_item_append_text(sub_item," Mandatory");
+ else
+ proto_item_append_text(sub_item," Optional");
+ }
+
+ /* MRP_Blocked */
+ offset = dissect_pn_uint16_ret_item(tvb, offset, pinfo, tree, hf_pn_mrp_blocked, &blocked, &sub_item);
+ if (tree)
+ {
+ if (blocked == 0)
+ proto_item_append_text(sub_item," The MRC is not able to receive and forward frames to port in state blocked");
+ else
+ if (blocked == 1)
+ proto_item_append_text(sub_item," The MRC is able to receive and forward frames to port in state blocked");
+ else
+ proto_item_append_text(sub_item," Reserved");
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+ return offset;
+}
+
+static const char * mrp_Prio2msg(guint16 prio)
+{
+
+ if (prio == 0x0000)
+ return(" Highest priority redundancy manager");
+ if ((prio >= 0x1000) && (prio <= 0x7000))
+ return(" High priorities");
+ if (prio == 0x8000)
+ return(" Default priority for redundancy manager");
+ if ((prio >= 0x8001) && (prio <= 0x8FFF))
+ return(" Low priorities for redundancy manager");
+ if ((prio >= 0x9000) && (prio <= 0x9FFF))
+ return(" High priorities for redundancy manager (auto)");
+ if (prio == 0xA000)
+ return(" Default priority for redundancy manager (auto)");
+ if ((prio >= 0xA001) && (prio <= 0xF000))
+ return(" Low priorities for redundancy manager (auto)");
+ if (prio ==0xFFFF)
+ return(" Lowest priority for redundancy manager (auto)");
+
+ return(" Reserved");
+}
+
+static int
+dissect_PNMRP_Test(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_)
+{
+ guint16 prio;
+ guint8 mac[6];
+ guint16 port_role;
+ guint16 ring_state;
+ guint16 transition;
+ guint32 time_stamp;
+ proto_item *sub_item;
+
+
+ /* MRP_Prio */
+ offset = dissect_pn_uint16_ret_item(tvb, offset, pinfo, tree, hf_pn_mrp_prio, &prio, &sub_item);
+ if (tree)
+ proto_item_append_text(sub_item, "%s", mrp_Prio2msg(prio));
+
+ /* MRP_SA */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_mrp_sa, mac);
+
+ /* MRP_PortRole */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_port_role, &port_role);
+
+ /* MRP_RingState */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_ring_state, &ring_state);
+
+ /* MRP_Transition */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_transition, &transition);
+
+ /* MRP_TimeStamp */
+ proto_tree_add_item_ret_uint(tree, hf_pn_mrp_time_stamp, tvb, offset, 4, ENC_BIG_ENDIAN, &time_stamp);
+ offset += 4;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+
+static int
+dissect_PNMRP_TopologyChange(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_)
+{
+ guint16 prio;
+ guint8 mac[6];
+ guint16 interval;
+ proto_item *sub_item;
+
+
+ /* MRP_Prio */
+ offset = dissect_pn_uint16_ret_item(tvb, offset, pinfo, tree, hf_pn_mrp_prio, &prio, &sub_item);
+ if (tree)
+ proto_item_append_text(sub_item, "%s", mrp_Prio2msg(prio));
+
+ /* MRP_SA */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_mrp_sa, mac);
+
+ /* MRP_Interval */
+ offset = dissect_pn_uint16_ret_item(tvb, offset, pinfo, tree, hf_pn_mrp_interval, &interval, &sub_item);
+ if (tree)
+ {
+ proto_item_append_text(sub_item," Interval for next topology change event (in ms) ");
+ if (interval <0x07D1)
+ proto_item_append_text(sub_item,"Mandatory");
+ else
+ proto_item_append_text(sub_item,"Optional");
+ }
+ /* Padding */
+ /*offset = dissect_pn_align4(tvb, offset, pinfo, tree);*/
+
+ return offset;
+}
+
+static int
+dissect_PNMRP_Ed1ManufacturerData(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree, guint8 *pLength)
+{
+ guint16 u16MrpEd1ManufacturerData;
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_ed1_manufacturer_data,
+ &u16MrpEd1ManufacturerData);
+ *pLength -= 2;
+ return offset;
+}
+
+static int
+dissect_PNMRP_SubOption2(tvbuff_t *tvb, int offset,
+packet_info *pinfo, proto_tree *tree)
+{
+ guint8 u8SubType;
+ guint8 u8Sublength;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16Prio;
+ guint16 u16OtherPrio;
+ guint8 mac[6];
+ guint8 otherMac[6];
+
+ sub_item = proto_tree_add_item(tree, hf_pn_mrp_sub_option2, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_sub_tlv);
+
+ /*
+ MRP_SubTLVHeader (Type=0x01 or Type=0x02, Length = 0x12),
+ MRP_Prio,
+ MRP_SA,
+ MRP_OtherMRMPrio,
+ MRP_OtherMRMSA,
+ Padding (=0x00,0x00)
+ */
+ /* MRP_SubTLVHeader.Type */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, sub_tree, hf_pn_mrp_sub_tlv_header_type, &u8SubType);
+
+ /* MRP_SubTLVHeader.Length */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, sub_tree, hf_pn_mrp_sub_tlv_header_length, &u8Sublength);
+
+ if (u8SubType == 0x00)
+ {
+ // IEC area: 0x00: Reserved;
+ return offset;
+ }
+ else if ( u8SubType == 0x01 || u8SubType == 0x02 )
+ {
+ // IEC area: 0x01: MRP_TestMgrNAck;
+ // IEC area: 0x02: MRP_AutoMgr;
+
+ /* MRP_Prio */
+ offset = dissect_pn_uint16_ret_item(tvb, offset, pinfo, sub_tree, hf_pn_mrp_prio, &u16Prio, &sub_item);
+ proto_item_append_text(sub_item, "%s", mrp_Prio2msg(u16Prio));
+
+ /* MRP_SA */
+ offset = dissect_pn_mac(tvb, offset, pinfo, sub_tree, hf_pn_mrp_sa, mac);
+
+ /* MRP_OtherMRMPrio */
+ offset = dissect_pn_uint16_ret_item(tvb, offset, pinfo, sub_tree, hf_pn_mrp_other_mrm_prio,
+ &u16OtherPrio, &sub_item);
+ proto_item_append_text(sub_item, "%s", mrp_Prio2msg(u16OtherPrio));
+
+ /* MRP_OtherMRMSA */
+ offset = dissect_pn_mac(tvb, offset, pinfo, sub_tree, hf_pn_mrp_other_mrm_sa, otherMac);
+
+ offset = dissect_pn_align4(tvb, offset, pinfo, sub_tree);
+ }
+ else if ( 0xF1 <= u8SubType )
+ {
+ proto_tree_add_string_format(sub_tree, hf_pn_mrp_manufacturer_data, tvb, offset, u8Sublength, "data",
+ "Reserved for vendor specific data: %u byte", u8Sublength);
+ offset += u8Sublength;
+ }
+ return offset;
+}
+
+static int
+dissect_PNMRP_Option(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 length)
+{
+ guint32 oui;
+ guint8 u8MrpEd1Type;
+
+ /* OUI (organizational unique id) */
+ offset = dissect_pn_oid(tvb, offset, pinfo,tree, hf_pn_mrp_oui, &oui);
+
+ switch (oui)
+ {
+ case OUI_SIEMENS:
+ proto_item_append_text(item, "(SIEMENS)");
+ length -= 3;
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_mrp_ed1type, &u8MrpEd1Type);
+ length -= 1;
+ switch (u8MrpEd1Type)
+ {
+ case 0x00:
+ offset = dissect_PNMRP_Ed1ManufacturerData(tvb, offset, pinfo, tree, &length);
+ break;
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ break;
+ case 0x04:
+ offset = dissect_PNMRP_Ed1ManufacturerData(tvb, offset, pinfo, tree, &length);
+ break;
+ /* 0x05 to 0xFF*/
+ default:
+ break;
+ }
+ //offset = dissect_PNMRP_Ed1ManufacturerData(tvb, offset, pinfo, tree, &length);
+
+ if (length != 0)
+ {
+ offset = dissect_PNMRP_SubOption2(tvb, offset, pinfo, tree);
+ }
+ col_append_str(pinfo->cinfo, COL_INFO, "(Siemens)");
+ break;
+ default:
+ proto_item_append_text(item, " (Unknown-OUI)");
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length);
+
+ }
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+
+static int
+dissect_PNMRP_PDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint16 version;
+ guint8 type;
+ guint8 length;
+ gint i;
+ tvbuff_t *new_tvb;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* MRP_Version */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_version, &version);
+
+ /* the rest of the packet has 4byte alignment regarding to the beginning of the next TLV block! */
+ /* XXX - do we have to free this new tvb below? */
+ new_tvb = tvb_new_subset_remaining(tvb, offset);
+ offset = 0;
+
+ for(i=0; tvb_reported_length_remaining(tvb, offset) > 0; i++) {
+
+ sub_item = proto_tree_add_item(tree, hf_pn_mrp_type, new_tvb, offset, 1, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_mrp_type);
+
+ /* MRP_TLVHeader.Type */
+ offset = dissect_pn_uint8(new_tvb, offset, pinfo, sub_tree, hf_pn_mrp_type, &type);
+
+ /* MRP_TLVHeader.Length */
+ offset = dissect_pn_uint8(new_tvb, offset, pinfo, sub_tree, hf_pn_mrp_length, &length);
+
+ if (i != 0) {
+ col_append_str(pinfo->cinfo, COL_INFO, ", ");
+
+ proto_item_append_text(item, ", ");
+ } else {
+ proto_item_append_text(item, " ");
+ }
+ col_append_str(pinfo->cinfo, COL_INFO, val_to_str(type, pn_mrp_block_type_vals, "Unknown TLVType 0x%x"));
+ proto_item_append_text(item, "%s", val_to_str(type, pn_mrp_block_type_vals, "Unknown TLVType 0x%x"));
+
+ switch(type) {
+ case 0x00:
+ /* no content */
+ return offset;
+ break;
+ case 0x01:
+ offset = dissect_PNMRP_Common(new_tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x02:
+ offset = dissect_PNMRP_Test(new_tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x03:
+ offset = dissect_PNMRP_TopologyChange(new_tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x04:
+ case 0x05: /* dissection of up and down is identical! */
+ offset = dissect_PNMRP_Link(new_tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x7f:
+ offset = dissect_PNMRP_Option(new_tvb, offset, pinfo, sub_tree, sub_item, length);
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, sub_tree, length);
+
+ }
+ }
+
+ return offset;
+}
+
+
+/* Dissect MRP packets */
+static int
+dissect_PNMRP(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ proto_item *ti = NULL;
+ proto_tree *mrp_tree = NULL;
+
+ guint32 offset = 0;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-MRP");
+
+ /* Clear the information column on summary display */
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ if (tree)
+ {
+ ti = proto_tree_add_item(tree, proto_pn_mrp, tvb, offset, -1, ENC_NA);
+ mrp_tree = proto_item_add_subtree(ti, ett_pn_mrp);
+ }
+
+ dissect_PNMRP_PDU(tvb, offset, pinfo, mrp_tree, ti);
+ return tvb_captured_length(tvb);
+}
+
+
+void
+proto_register_pn_mrp (void)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_mrp_type,
+ { "MRP_TLVHeader.Type", "pn_mrp.type",
+ FT_UINT8, BASE_HEX, VALS(pn_mrp_block_type_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_length,
+ { "MRP_TLVHeader.Length", "pn_mrp.length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_version,
+ { "MRP_Version", "pn_mrp.version",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_sequence_id,
+ { "MRP_SequenceID", "pn_mrp.sequence_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "Unique sequence number to each outstanding service request", HFILL }},
+
+ { &hf_pn_mrp_sa,
+ { "MRP_SA", "pn_mrp.sa",
+ FT_ETHER, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_prio,
+ { "MRP_Prio", "pn_mrp.prio",
+ FT_UINT16, BASE_HEX, 0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_port_role,
+ { "MRP_PortRole", "pn_mrp.port_role",
+ FT_UINT16, BASE_HEX, VALS(pn_mrp_port_role_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_ring_state,
+ { "MRP_RingState", "pn_mrp.ring_state",
+ FT_UINT16, BASE_HEX, VALS(pn_mrp_ring_state_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_interval,
+ { "MRP_Interval", "pn_mrp.interval",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Interval for next topology change event (in ms)", HFILL }},
+
+ { &hf_pn_mrp_transition,
+ { "MRP_Transition", "pn_mrp.transition",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "Number of transitions between media redundancy lost and ok states", HFILL }},
+
+ { &hf_pn_mrp_time_stamp,
+ { "MRP_TimeStamp [ms]", "pn_mrp.time_stamp",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "Actual counter value of 1ms counter", HFILL }},
+
+ { &hf_pn_mrp_blocked,
+ { "MRP_Blocked", "pn_mrp.blocked",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_domain_uuid,
+ { "MRP_DomainUUID", "pn_mrp.domain_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_oui,
+ { "MRP_ManufacturerOUI", "pn_mrp.oui",
+ FT_UINT24, BASE_HEX, VALS(pn_mrp_oui_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_ed1type,
+ { "MRP_Ed1Type", "pn_mrp.ed1type",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_ed1_manufacturer_data,
+ { "MRP_Ed1ManufacturerData", "pn_mrp.ed1manufacturerdata",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_sub_option2,
+ { "MRP_SubOption2", "pn_mrp.sub_option2",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL } },
+
+ { &hf_pn_mrp_sub_tlv_header_type,
+ { "MRP_SubTLVHeader.Type", "pn_mrp.sub_type",
+ FT_UINT8, BASE_HEX, VALS(pn_mrp_sub_tlv_header_type_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_sub_tlv_header_length,
+ { "MRP_SubTLVHeader.Length", "pn_mrp.sub_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_other_mrm_prio,
+ { "MRP_OtherMRMPrio", "pn_mrp.other_mrm_prio",
+ FT_UINT16, BASE_HEX, 0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrp_other_mrm_sa,
+ { "MRP_OtherMRMSA", "pn_mrp.other_mrm_sa",
+ FT_ETHER, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }},
+ { &hf_pn_mrp_manufacturer_data,
+ { "MRP_ManufacturerData", "pn_mrp.manufacturer_data",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }}
+ };
+
+ static gint *ett[] = {
+ &ett_pn_mrp,
+ &ett_pn_mrp_type,
+ &ett_pn_sub_tlv
+ };
+
+ proto_pn_mrp = proto_register_protocol ("PROFINET MRP", "PN-MRP", "pn_mrp");
+ proto_register_field_array (proto_pn_mrp, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ mrp_handle = register_dissector("pn_mrp", dissect_PNMRP, proto_pn_mrp);
+}
+
+
+void
+proto_reg_handoff_pn_mrp (void)
+{
+ dissector_add_uint("ethertype", ETHERTYPE_MRP, mrp_handle);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-pn-mrrt.c b/plugins/epan/profinet/packet-pn-mrrt.c
new file mode 100644
index 0000000..5c332a5
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn-mrrt.c
@@ -0,0 +1,247 @@
+/* packet-pn-mrrt.c
+ * Routines for PN-MRRT (PROFINET Media Redundancy for cyclic realtime data)
+ * packet dissection.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/dissectors/packet-dcerpc.h>
+
+#include "packet-pn.h"
+
+void proto_register_pn_mrrt(void);
+void proto_reg_handoff_pn_mrrt(void);
+
+static int proto_pn_mrrt = -1;
+
+static int hf_pn_mrrt_sequence_id = -1;
+static int hf_pn_mrrt_domain_uuid = -1;
+static int hf_pn_mrrt_type = -1;
+static int hf_pn_mrrt_length = -1;
+static int hf_pn_mrrt_version = -1;
+static int hf_pn_mrrt_sa = -1;
+
+
+static gint ett_pn_mrrt = -1;
+
+
+
+static const value_string pn_mrrt_block_type_vals[] = {
+ { 0x00, "End" },
+ { 0x01, "Common" },
+ { 0x02, "Test" },
+ /*0x03 - 0x7E Reserved */
+ { 0x7F, "Organizationally Specific"},
+ { 0, NULL },
+};
+
+
+
+
+static int
+dissect_PNMRRT_Common(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 length _U_)
+{
+ guint16 sequence_id;
+ e_guid_t uuid;
+
+
+ /* MRRT_SequenceID */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrrt_sequence_id, &sequence_id);
+
+ /* MRRT_DomainUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_mrrt_domain_uuid, &uuid);
+
+ col_append_str(pinfo->cinfo, COL_INFO, "Common");
+
+ proto_item_append_text(item, "Common");
+
+ return offset;
+}
+
+
+static int
+dissect_PNMRRT_Test(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 length _U_)
+{
+ guint8 mac[6];
+
+
+ /* MRRT_SA */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_mrrt_sa, mac);
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ col_append_str(pinfo->cinfo, COL_INFO, "Test");
+
+ proto_item_append_text(item, "Test");
+
+ return offset;
+}
+
+static int
+dissect_PNMRRT_PDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint16 version;
+ guint8 type;
+ guint8 length;
+ gint i = 0;
+
+
+ /* MRRT_Version */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrrt_version, &version);
+
+ while (tvb_reported_length_remaining(tvb, offset) > 0) {
+ /* MRRT_TLVHeader.Type */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_mrrt_type, &type);
+
+ /* MRRT_TLVHeader.Length */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_mrrt_length, &length);
+
+
+ if (i != 0) {
+ col_append_str(pinfo->cinfo, COL_INFO, ", ");
+
+ proto_item_append_text(item, ", ");
+ }
+
+ i++;
+
+ switch(type) {
+ case 0x00:
+ /* no content */
+ col_append_str(pinfo->cinfo, COL_INFO, "End");
+ proto_item_append_text(item, "End");
+ return offset;
+ break;
+ case 0x01:
+ offset = dissect_PNMRRT_Common(tvb, offset, pinfo, tree, item, length);
+ break;
+ case 0x02:
+ offset = dissect_PNMRRT_Test(tvb, offset, pinfo, tree, item, length);
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Unknown TLVType 0x%x", type);
+ proto_item_append_text(item, "Unknown TLVType 0x%x", type);
+ break;
+ }
+ }
+
+ return offset;
+}
+
+
+/* possibly dissect a PN-RT packet (frame ID must be in the appropriate range) */
+static gboolean
+dissect_PNMRRT_Data_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ void *data)
+{
+ /* the tvb will NOT contain the frame_id here, so get it from dissector data! */
+ guint16 u16FrameID = GPOINTER_TO_UINT(data);
+ proto_item *item;
+ proto_tree *mrrt_tree;
+ int offset = 0;
+ guint32 u32SubStart;
+
+
+ /* frame id must be in valid range (MRRT) */
+ if (u16FrameID != 0xFF60) {
+ /* we are not interested in this packet */
+ return FALSE;
+ }
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-MRRT");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* subtree for MRRT */
+ item = proto_tree_add_protocol_format(tree, proto_pn_mrrt, tvb, 0, 0, "PROFINET MRRT, ");
+ mrrt_tree = proto_item_add_subtree(item, ett_pn_mrrt);
+ u32SubStart = offset;
+
+ offset = dissect_PNMRRT_PDU(tvb, offset, pinfo, mrrt_tree, item);
+
+ proto_item_set_len(item, offset - u32SubStart);
+
+ return TRUE;
+}
+
+
+void
+proto_register_pn_mrrt (void)
+{
+ static hf_register_info hf[] = {
+
+ { &hf_pn_mrrt_type,
+ { "Type", "pn_mrrt.type",
+ FT_UINT8, BASE_HEX, VALS(pn_mrrt_block_type_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrrt_length,
+ { "Length", "pn_mrrt.length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrrt_version,
+ { "Version", "pn_mrrt.version",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrrt_sequence_id,
+ { "SequenceID", "pn_mrrt.sequence_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "Unique sequence number to each outstanding service request", HFILL }},
+
+ { &hf_pn_mrrt_sa,
+ { "SA", "pn_mrrt.sa",
+ FT_ETHER, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_mrrt_domain_uuid,
+ { "DomainUUID", "pn_mrrt.domain_uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ };
+
+
+ static gint *ett[] = {
+ &ett_pn_mrrt
+ };
+
+ proto_pn_mrrt = proto_register_protocol ("PROFINET MRRT", "PN-MRRT", "pn_mrrt");
+ proto_register_field_array (proto_pn_mrrt, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+}
+
+
+void
+proto_reg_handoff_pn_mrrt (void)
+{
+
+ /* register ourself as an heuristic pn-rt payload dissector */
+ heur_dissector_add("pn_rt", dissect_PNMRRT_Data_heur, "PROFINET MRRT IO", "pn_mrrt_pn_rt", proto_pn_mrrt, HEURISTIC_ENABLE);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-pn-ptcp.c b/plugins/epan/profinet/packet-pn-ptcp.c
new file mode 100644
index 0000000..cd11896
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn-ptcp.c
@@ -0,0 +1,1093 @@
+/* packet-pn-ptcp.c
+ * Routines for PN-PTCP (PROFINET Precision Time Clock Protocol)
+ * packet dissection.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/oui.h>
+#include <epan/dissectors/packet-dcerpc.h>
+
+#include "packet-pn.h"
+
+void proto_register_pn_ptcp(void);
+void proto_reg_handoff_pn_ptcp(void);
+
+static int proto_pn_ptcp = -1;
+
+static int hf_pn_ptcp_header = -1;
+static int hf_pn_ptcp_block = -1;
+static int hf_pn_ptcp_block_tlvheader = -1;
+
+static int hf_pn_ptcp_res1 = -1;
+static int hf_pn_ptcp_res2 = -1;
+static int hf_pn_ptcp_delay10ns = -1;
+static int hf_pn_ptcp_seq_id = -1;
+static int hf_pn_ptcp_delay1ns_byte = -1;
+static int hf_pn_ptcp_delay1ns_fup = -1;
+static int hf_pn_ptcp_delay1ns = -1;
+
+static int hf_pn_ptcp_tl_length = -1;
+static int hf_pn_ptcp_tl_type = -1;
+
+static int hf_pn_ptcp_master_source_address = -1;
+static int hf_pn_ptcp_subdomain_uuid = -1;
+
+static int hf_pn_ptcp_port_mac_address = -1;
+
+static int hf_pn_ptcp_t2portrxdelay = -1;
+static int hf_pn_ptcp_t3porttxdelay = -1;
+
+static int hf_pn_ptcp_t2timestamp = -1;
+
+static int hf_pn_ptcp_epoch_number = -1;
+static int hf_pn_ptcp_seconds = -1;
+static int hf_pn_ptcp_nanoseconds = -1;
+
+static int hf_pn_ptcp_flags = -1;
+static int hf_pn_ptcp_currentutcoffset = -1;
+
+static int hf_pn_ptcp_master_priority1 = -1;
+static int hf_pn_ptcp_master_priority_level = -1;
+static int hf_pn_ptcp_master_priority1_res = -1;
+static int hf_pn_ptcp_master_priority1_act =-1;
+
+static int hf_pn_ptcp_master_priority2 = -1;
+static int hf_pn_ptcp_clock_class = -1;
+static int hf_pn_ptcp_clock_accuracy = -1;
+static int hf_pn_ptcp_clockvariance = -1;
+
+static int hf_pn_ptcp_oui = -1;
+static int hf_pn_ptcp_profinet_subtype = -1;
+static int hf_pn_ptcp_irdata_uuid = -1;
+
+static gint ett_pn_ptcp = -1;
+static gint ett_pn_ptcp_header = -1;
+static gint ett_pn_ptcp_block = -1;
+static gint ett_pn_ptcp_block_header = -1;
+
+#define OUI_PROFINET_MULTICAST 0x010ECF /* PROFIBUS Nutzerorganisation e.V. */
+
+
+#define PN_PTCP_BT_END 0x00
+#define PN_PTCP_BT_SUBDOMAIN 0x01
+#define PN_PTCP_BT_TIME 0x02
+#define PN_PTCP_BT_TIME_EXTENSION 0x03
+#define PN_PTCP_BT_MASTER 0x04
+#define PN_PTCP_BT_PORT_PARAMETER 0x05
+#define PN_PTCP_BT_DELAY_PARAMETER 0x06
+#define PN_PTCP_BT_PORT_TIME 0x07
+#define PN_PTCP_BT_OPTION 0x7F
+#define PN_PTCP_BT_RTDATA 0x7F
+
+
+static const value_string pn_ptcp_block_type[] = {
+ { PN_PTCP_BT_END, "End" },
+ { PN_PTCP_BT_SUBDOMAIN, "Subdomain"},
+ { PN_PTCP_BT_TIME, "Time"},
+ { PN_PTCP_BT_TIME_EXTENSION, "TimeExtension"},
+ { PN_PTCP_BT_MASTER, "Master"},
+ { PN_PTCP_BT_PORT_PARAMETER, "PortParameter"},
+ { PN_PTCP_BT_DELAY_PARAMETER, "DelayParameter"},
+ { PN_PTCP_BT_PORT_TIME, "PortTime"},
+ /*0x08 - 0x7E Reserved */
+ { PN_PTCP_BT_OPTION, "Organizationally Specific"},
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_oui_vals[] = {
+ { OUI_PROFINET, "PROFINET" },
+ { OUI_PROFINET_MULTICAST, "PROFINET" },
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_master_prio1_vals[] = {
+ { 0x00, "Sync slave" },
+ { 0x01, "Primary master" },
+ { 0x02, "Secondary master" },
+ { 0x03, "Reserved" },
+ { 0x04, "Reserved" },
+ { 0x05, "Reserved" },
+ { 0x06, "Reserved" },
+ { 0x07, "Reserved" },
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_master_prio1_levels[] = {
+ { 0x00, "Level 0 (highest)" },
+ { 0x01, "Level 1" },
+ { 0x02, "Level 2" },
+ { 0x03, "Level 3" },
+ { 0x04, "Level 4" },
+ { 0x05, "Level 5" },
+ { 0x06, "Level 6" },
+ { 0x07, "Level 7 (lowest)" },
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_master_prio1_vals_active[] = {
+ { 0x00, "inactive" },
+ { 0x01, "active" },
+ { 0, NULL }
+};
+
+#if 0
+static const value_string pn_ptcp_master_prio1_short_vals[] = {
+ { 0x01, "Primary" },
+ { 0x02, "Secondary" },
+ { 0, NULL }
+};
+#endif
+
+static const value_string pn_ptcp_master_prio2_vals[] = {
+ { 0xFF, "Default" },
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_clock_class_vals[] = {
+ { 0xFF, "Slave-only clock" },
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_clock_accuracy_vals[] = {
+ { 0x20, "25ns" },
+ { 0x21, "100ns (Default)" },
+ { 0x22, "250ns" },
+ { 0x23, "1us" },
+ { 0x24, "2.5us" },
+ { 0x25, "10us" },
+ { 0x26, "25us" },
+ { 0x27, "100us" },
+ { 0x28, "250us" },
+ { 0x29, "1ms" },
+ { 0xFE, "Unknown" },
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_profinet_subtype_vals[] = {
+ { 0x01, "RTData" },
+ { 0, NULL }
+};
+
+
+
+
+static int
+dissect_PNPTCP_TLVHeader(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 *type, guint16 *length)
+{
+ guint16 tl_type;
+ guint16 tl_length;
+
+
+ /* Type */
+ dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_tl_type, &tl_type);
+ *type = tl_type >> 9;
+
+ /* Length */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_tl_length, &tl_length);
+ *length = tl_length & 0x1FF;
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_Subdomain(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID)
+{
+ guint8 mac[6];
+ e_guid_t uuid;
+
+
+ /* MasterSourceAddress */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_ptcp_master_source_address, mac);
+
+ /* SubdomainUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_ptcp_subdomain_uuid, &uuid);
+
+ if ((u16FrameID == 0xff00) || (u16FrameID == 0xff01)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Master=%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ }
+
+ proto_item_append_text(item, ": MasterSource=%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ proto_item_append_text(item, ", Subdomain=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid.data1, uuid.data2, uuid.data3,
+ uuid.data4[0], uuid.data4[1],
+ uuid.data4[2], uuid.data4[3],
+ uuid.data4[4], uuid.data4[5],
+ uuid.data4[6], uuid.data4[7]);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_Time(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint16 EpochNumber;
+ guint32 Seconds;
+ guint32 NanoSeconds;
+
+
+ /* EpochNumber */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_epoch_number, &EpochNumber);
+
+ /* Seconds */
+ proto_tree_add_item_ret_uint(tree, hf_pn_ptcp_seconds, tvb, offset, 4, ENC_BIG_ENDIAN, &Seconds);
+ offset += 4;
+
+ /* NanoSeconds */
+ proto_tree_add_item_ret_uint(tree, hf_pn_ptcp_nanoseconds, tvb, offset, 4, ENC_BIG_ENDIAN, &NanoSeconds);
+ offset += 4;
+
+ proto_item_append_text(item, ": Seconds=%u NanoSeconds=%u EpochNumber=%u",
+ Seconds, NanoSeconds, EpochNumber);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Time: %4us %09uns, Epoch: %u",
+ Seconds, NanoSeconds, EpochNumber);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_TimeExtension(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint16 Flags;
+ guint16 CurrentUTCOffset;
+
+
+ /* Flags */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_flags, &Flags);
+
+ /* CurrentUTCOffset */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_currentutcoffset, &CurrentUTCOffset);
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ proto_item_append_text(item, ": Flags=0x%x, CurrentUTCOffset=%u", Flags, CurrentUTCOffset);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_Master(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint8 MasterPriority1;
+ guint8 MasterPriority2;
+ guint8 ClockClass;
+ guint8 ClockAccuracy;
+ gint16 ClockVariance;
+
+
+ /* MasterPriority1 is a bit field */
+ /* Bit 0 - 2: PTCP_MasterPriority1.Priority */
+ dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority1, &MasterPriority1);
+ /* Bit 3 - 5: PTCP_MasterPriority1.Level */
+ dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority_level, &MasterPriority1);
+ /* Bit 6: PTCP_MasterPriority1.Reserved */
+ dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority1_res, &MasterPriority1);
+ /* Bit 7: PTCP_MasterPriority1.Active */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority1_act, &MasterPriority1);
+
+ /* MasterPriority2 */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority2, &MasterPriority2);
+
+ /* ClockClass */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_clock_class, &ClockClass);
+
+ /* ClockAccuracy */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_clock_accuracy, &ClockAccuracy);
+
+ /* ClockVariance */
+ offset = dissect_pn_int16(tvb, offset, pinfo, tree, hf_pn_ptcp_clockvariance, &ClockVariance);
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Prio1=\"%s\"",
+ val_to_str(MasterPriority1 & 0x7, pn_ptcp_master_prio1_vals, "(Reserved: 0x%x)"));
+
+ if ((MasterPriority1 & 0x80) == 0) {
+ proto_item_append_text(item, ": Prio1=\"%s\", Prio2=%s, Clock: Class=\"%s\", Accuracy=%s, Variance=%d",
+ val_to_str(MasterPriority1 & 0x7, pn_ptcp_master_prio1_vals, "(Reserved: 0x%x)"),
+ val_to_str(MasterPriority2, pn_ptcp_master_prio2_vals, "(Reserved: 0x%x)"),
+ val_to_str(ClockClass, pn_ptcp_clock_class_vals, "(Reserved: 0x%x)"),
+ val_to_str(ClockAccuracy, pn_ptcp_clock_accuracy_vals, "(Reserved: 0x%x)"),
+ ClockVariance);
+ }
+ else {
+ col_append_str(pinfo->cinfo, COL_INFO, " active");
+ proto_item_append_text(item, ": Prio1=\"%s\" is active, Prio2=%s, Clock: Class=\"%s\", Accuracy=%s, Variance=%d",
+ val_to_str(MasterPriority1 & 0x7, pn_ptcp_master_prio1_vals, "(Reserved: 0x%x)"),
+ val_to_str(MasterPriority2, pn_ptcp_master_prio2_vals, "(Reserved: 0x%x)"),
+ val_to_str(ClockClass, pn_ptcp_clock_class_vals, "(Reserved: 0x%x)"),
+ val_to_str(ClockAccuracy, pn_ptcp_clock_accuracy_vals, "(Reserved: 0x%x)"),
+ ClockVariance);
+ }
+
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_PortParameter(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint32 t2portrxdelay;
+ guint32 t3porttxdelay;
+
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* T2PortRxDelay */
+ proto_tree_add_item_ret_uint(tree, hf_pn_ptcp_t2portrxdelay, tvb, offset, 4, ENC_BIG_ENDIAN, &t2portrxdelay);
+ offset += 4;
+
+ /* T3PortTxDelay */
+ proto_tree_add_item_ret_uint(tree, hf_pn_ptcp_t3porttxdelay, tvb, offset, 4, ENC_BIG_ENDIAN, &t3porttxdelay);
+ offset += 4;
+
+ proto_item_append_text(item, ": T2PortRxDelay=%uns, T3PortTxDelay=%uns",
+ t2portrxdelay, t3porttxdelay);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", T2Rx=%uns, T3Tx=%uns",
+ t2portrxdelay, t3porttxdelay);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_DelayParameter(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint8 mac[6];
+
+
+ /* PortMACAddress */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_ptcp_port_mac_address, mac);
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+
+ proto_item_append_text(item, ": PortMAC=%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", PortMAC=%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_PortTime(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint32 t2timestamp;
+
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* T2TimeStamp */
+ proto_tree_add_item_ret_uint(tree, hf_pn_ptcp_t2timestamp, tvb, offset, 4, ENC_BIG_ENDIAN, &t2timestamp);
+ offset += 4;
+
+ proto_item_append_text(item, ": T2TimeStamp=%uns", t2timestamp);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", T2TS=%uns", t2timestamp);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_Option_PROFINET(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length)
+{
+ guint8 subType;
+ e_guid_t uuid;
+
+ /* OUI already dissected! */
+
+ /* SubType */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_profinet_subtype, &subType);
+ length -= 1;
+
+ switch (subType) {
+ case 1: /* RTData */
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ /* IRDataUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_ptcp_irdata_uuid, &uuid);
+ proto_item_append_text(item, ": IRDataUUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid.data1, uuid.data2, uuid.data3,
+ uuid.data4[0], uuid.data4[1],
+ uuid.data4[2], uuid.data4[3],
+ uuid.data4[4], uuid.data4[5],
+ uuid.data4[6], uuid.data4[7]);
+
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length);
+ break;
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_Option(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length)
+{
+ guint32 oui;
+
+
+ /* verify remaining TLV length */
+ if (length < 4)
+ {
+ /* too short */
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length);
+ return (offset);
+ }
+
+ /* OUI (organizational unique id) */
+ offset = dissect_pn_oid(tvb, offset, pinfo,tree, hf_pn_ptcp_oui, &oui);
+ length -= 3;
+
+ switch (oui)
+ {
+ case OUI_PROFINET:
+ case OUI_PROFINET_MULTICAST:
+ proto_item_append_text(item, ": PROFINET");
+ offset = dissect_PNPTCP_Option_PROFINET(tvb, offset, pinfo, tree, item, length);
+ break;
+ default:
+ /* SubType */
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length);
+ }
+
+ return (offset);
+}
+
+
+static int
+dissect_PNPTCP_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, gboolean *end, guint16 u16FrameID)
+{
+ guint16 type;
+ guint16 length;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ proto_item *tlvheader_item;
+ proto_tree *tlvheader_tree;
+ guint32 u32SubStart;
+
+
+ *end = FALSE;
+
+ /* block subtree */
+ sub_item = proto_tree_add_item(tree, hf_pn_ptcp_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_ptcp_block);
+ u32SubStart = offset;
+
+ /* tlvheader subtree */
+ tlvheader_item = proto_tree_add_item(sub_tree, hf_pn_ptcp_block_tlvheader, tvb, offset, 2 /* len */, ENC_NA);
+ tlvheader_tree = proto_item_add_subtree(tlvheader_item, ett_pn_ptcp_block_header);
+
+ offset = dissect_PNPTCP_TLVHeader(tvb, offset, pinfo, tlvheader_tree, sub_item, &type, &length);
+
+ proto_item_set_text(sub_item, "%s",
+ val_to_str_const(type, pn_ptcp_block_type, "Unknown"));
+
+ proto_item_append_text(tlvheader_item, ": Type=%s (%x), Length=%u",
+ val_to_str_const(type, pn_ptcp_block_type, "Unknown"), type, length);
+
+ switch (type) {
+ case 0x00: /* End, no content */
+ *end = TRUE;
+ break;
+ case 0x01: /* Subdomain */
+ dissect_PNPTCP_Subdomain(tvb, offset, pinfo, sub_tree, sub_item, u16FrameID);
+ break;
+ case 0x02: /* Time */
+ dissect_PNPTCP_Time(tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x03: /* TimeExtension */
+ dissect_PNPTCP_TimeExtension(tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x04: /* Master */
+ dissect_PNPTCP_Master(tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x05: /* PortParameter */
+ dissect_PNPTCP_PortParameter(tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x06: /* DelayParameter */
+ dissect_PNPTCP_DelayParameter(tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x07: /* PortTime */
+ dissect_PNPTCP_PortTime(tvb, offset, pinfo, sub_tree, sub_item);
+ break;
+ case 0x7F: /* Organizational Specific */
+ dissect_PNPTCP_Option(tvb, offset, pinfo, sub_tree, sub_item, length);
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length);
+ }
+ offset += length;
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_blocks(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID)
+{
+ gboolean end = FALSE;
+
+ /* as long as we have some bytes, try a new block */
+ while (!end) {
+ offset = dissect_PNPTCP_block(tvb, offset, pinfo, tree, item, &end, u16FrameID);
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_FollowUpPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID,
+ const char *name, const char *name_short)
+{
+ proto_item *header_item;
+ proto_tree *header_tree;
+ guint16 seq_id;
+ gint32 delay1ns_fup;
+
+
+ /* dissect the header */
+ header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, ENC_NA);
+ header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header);
+
+ /* Padding 12 bytes */
+ offset = dissect_pn_padding(tvb, offset, pinfo, header_tree, 12);
+
+ /* SequenceID */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_seq_id, &seq_id);
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, header_tree);
+
+ /* Delay1ns_FUP */
+ proto_tree_add_item_ret_int(header_tree, hf_pn_ptcp_delay1ns_fup, tvb, offset, 4, ENC_BIG_ENDIAN, &delay1ns_fup);
+ offset += 4;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq=%3u, Delay=%11dns", name, seq_id, delay1ns_fup);
+ proto_item_append_text(item, "%s: Sequence=%u, Delay=%dns", name_short, seq_id, delay1ns_fup);
+ proto_item_append_text(header_item, ": Sequence=%u, Delay=%dns", seq_id, delay1ns_fup);
+
+
+ /* dissect the TLV blocks */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item, u16FrameID);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_RTSyncPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID,
+ const char *name, const char *name_short)
+{
+ proto_item *header_item;
+ proto_tree *header_tree;
+ guint32 delay10ns;
+ guint16 seq_id;
+ guint8 delay1ns_8;
+ guint64 delay1ns_64;
+ guint32 delay1ns_32;
+ guint32 delayms;
+
+
+ header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, ENC_NA);
+ header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header);
+
+ /* Reserved_1 */
+ proto_tree_add_item(tree, hf_pn_ptcp_res1, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+
+ /* Reserved_2 */
+ proto_tree_add_item(tree, hf_pn_ptcp_res2, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+
+ /* Delay10ns */
+ proto_tree_add_item_ret_uint(tree, hf_pn_ptcp_delay10ns, tvb, offset, 4, ENC_BIG_ENDIAN, &delay10ns);
+ offset += 4;
+
+ /* SequenceID */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_seq_id, &seq_id);
+
+ /* Delay1ns */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, header_tree, hf_pn_ptcp_delay1ns_byte, &delay1ns_8);
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, header_tree);
+
+ /* Delay1ns */
+ proto_tree_add_item_ret_uint(tree, hf_pn_ptcp_delay1ns, tvb, offset, 4, ENC_BIG_ENDIAN, &delay1ns_32);
+ offset += 4;
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+
+ delay1ns_64 = ((guint64) delay10ns) * 10 + delay1ns_8 + delay1ns_32;
+ delayms = (guint32) (delay1ns_64 / (1000 * 1000));
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq=%3u, Delay=%11" PRIu64 "ns",
+ name, seq_id, delay1ns_64);
+ proto_item_append_text(item, "%s: Sequence=%u, Delay=%" PRIu64 "ns",
+ name_short, seq_id, delay1ns_64);
+ proto_item_append_text(header_item, ": Sequence=%u, Delay=%" PRIu64 "ns",
+ seq_id, delay1ns_64);
+
+ if (delay1ns_64 != 0)
+ proto_item_append_text(header_item, " (%u.%03u,%03u,%03u sec)",
+ delayms / 1000,
+ delayms % 1000,
+ (delay10ns % (1000*100)) / 100,
+ delay10ns % 100 * 10 + delay1ns_8);
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item, u16FrameID);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_AnnouncePDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID,
+ const char *name, const char *name_short)
+{
+ proto_item *header_item;
+ proto_tree *header_tree;
+ guint16 seq_id;
+
+
+ /* dissect the header */
+ header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, ENC_NA);
+ header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header);
+
+ /* Padding 12 bytes */
+ offset = dissect_pn_padding(tvb, offset, pinfo, header_tree, 12);
+
+ /* SequenceID */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_seq_id, &seq_id);
+
+ /* Padding 6 bytes */
+ offset = dissect_pn_padding(tvb, offset, pinfo, header_tree, 6);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq=%3u", name, seq_id);
+ proto_item_append_text(item, "%s: Sequence=%u", name_short, seq_id);
+ proto_item_append_text(header_item, ": Sequence=%u", seq_id);
+
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item, u16FrameID);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_DelayPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID,
+ const char *name, const char *name_short)
+{
+ proto_item *header_item;
+ proto_tree *header_tree;
+ guint16 seq_id;
+ guint32 delay1ns;
+
+
+ /* dissect the header */
+ header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, ENC_NA);
+ header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header);
+
+ /* Padding 12 bytes */
+ offset = dissect_pn_padding(tvb, offset, pinfo, header_tree, 12);
+
+ /* SequenceID */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_seq_id, &seq_id);
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, header_tree);
+
+ /* Delay1ns_FUP */
+ proto_tree_add_item_ret_uint(tree, hf_pn_ptcp_delay1ns, tvb, offset, 4, ENC_BIG_ENDIAN, &delay1ns);
+ offset += 4;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq=%3u, Delay=%11uns", name, seq_id, delay1ns);
+ proto_item_append_text(item, "%s: Sequence=%u, Delay=%uns", name_short, seq_id, delay1ns);
+ proto_item_append_text(header_item, ": Sequence=%u, Delay=%uns", seq_id, delay1ns);
+
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item, u16FrameID);
+
+ return offset;
+}
+
+
+/* possibly dissect a PN-RT packet (frame ID must be in the appropriate range) */
+static gboolean
+dissect_PNPTCP_Data_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ /* the tvb will NOT contain the frame_id here, so get it from dissector data! */
+ guint16 u16FrameID = GPOINTER_TO_UINT(data);
+ proto_item *item;
+ proto_tree *ptcp_tree;
+ int offset = 0;
+ guint32 u32SubStart;
+
+
+ /* frame id must be in valid range (acyclic Real-Time, PTCP) */
+ /* 0x0000 - 0x007F: RTSyncPDU (with follow up) */
+ /* 0x0080 - 0x00FF: RTSyncPDU (without follow up) */
+ /* 0xFF00 - 0xFF1F: AnnouncePDU */
+ /* 0xFF20 - 0xFF3F: FollowUpPDU */
+ /* 0xFF40 - 0xFF5F: Delay...PDU */
+ if ( ((u16FrameID >= 0x0100) && (u16FrameID < 0xFF00)) || (u16FrameID > 0xFF5F) ) {
+ /* we are not interested in this packet */
+ return FALSE;
+ }
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-PTCP");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* subtree for PTCP */
+ item = proto_tree_add_protocol_format(tree, proto_pn_ptcp, tvb, 0, 0, "PROFINET PTCP, ");
+ ptcp_tree = proto_item_add_subtree(item, ett_pn_ptcp);
+ u32SubStart = offset;
+
+ switch (u16FrameID) {
+ /* range 1 (0x0000 - 0x007F) */
+ /* 0x0000 - 0x001F reserved */
+ case 0x0020:
+ offset = dissect_PNPTCP_RTSyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "RTSync FU (Clock)", "RTSync FU (Clock)");
+ break;
+ case 0x0021:
+ offset = dissect_PNPTCP_RTSyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "RTSync FU (Time)", "RTSync FU (Time)");
+ break;
+ /* 0x0022 - 0x007F reserved */
+
+ /* range 2 (0x0080 - 0x00FF) */
+ case 0x0080:
+ offset = dissect_PNPTCP_RTSyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "RTSync (Clock)", "RTSync (Clock)");
+ break;
+ case 0x0081:
+ offset = dissect_PNPTCP_RTSyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "RTSync (Time)", "RTSync (Time)");
+ break;
+ /* 0x0081 - 0x00FF reserved */
+
+ /* range 7 (0xFF00 - 0xFF5F) */
+ case 0xff00:
+ offset = dissect_PNPTCP_AnnouncePDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "Announce (Clock)", "Announce (Clock)");
+ break;
+ case 0xff01:
+ offset = dissect_PNPTCP_AnnouncePDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "Announce (Time)", "Announce (Time)");
+ break;
+ /* 0xFF02 - 0xFF1F reserved */
+ case 0xff20:
+ offset = dissect_PNPTCP_FollowUpPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "FollowUp (Clock)", "FollowUp (Clock)");
+ break;
+ case 0xff21:
+ offset = dissect_PNPTCP_FollowUpPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "FollowUp (Time)", "FollowUp (Time)");
+ break;
+ /* 0xFF22 - 0xFF3F reserved */
+ case 0xff40:
+ offset = dissect_PNPTCP_DelayPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "DelayReq ", "DelayReq");
+ break;
+ case 0xff41:
+ offset = dissect_PNPTCP_DelayPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "DelayRes ", "DelayRes");
+ break;
+ case 0xff42:
+ offset = dissect_PNPTCP_DelayPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "DelayFuRes ", "DelayFuRes");
+ break;
+ case 0xff43:
+ offset = dissect_PNPTCP_DelayPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID,
+ "DelayRes ", "DelayRes");
+ break;
+ /* 0xFF44 - 0xFF5F reserved */
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length_remaining(tvb, offset));
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Reserved FrameID 0x%04x", u16FrameID);
+
+ proto_item_append_text(item, "Reserved FrameID 0x%04x", u16FrameID);
+
+ offset += tvb_captured_length_remaining(tvb, offset);
+ break;
+ }
+
+ proto_item_set_len(item, offset - u32SubStart);
+
+ return TRUE;
+}
+
+
+void
+proto_register_pn_ptcp (void)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_ptcp_header,
+ { "Header", "pn_ptcp.header",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_block,
+ { "Block", "pn_ptcp.block",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_block_tlvheader,
+ { "TLVHeader", "pn_ptcp.tlvheader",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_res1,
+ { "Reserved 1", "pn_ptcp.res1",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_res2,
+ { "Reserved 2", "pn_ptcp.res2",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_delay10ns,
+ { "Delay10ns", "pn_ptcp.delay10ns",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_seq_id,
+ { "SequenceID", "pn_ptcp.sequence_id",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_delay1ns_byte,
+ { "Delay1ns_Byte", "pn_ptcp.delay1ns_byte",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_delay1ns,
+ { "Delay1ns", "pn_ptcp.delay1ns",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_delay1ns_fup,
+ { "Delay1ns_FUP", "pn_ptcp.delay1ns_fup",
+ FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_tl_length,
+ { "TypeLength.Length", "pn_ptcp.tl_length",
+ FT_UINT16, BASE_DEC, 0x0, 0x01FF,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_tl_type,
+ { "TypeLength.Type", "pn_ptcp.tl_type",
+ FT_UINT16, BASE_DEC, 0x0, 0xFE00,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_master_source_address,
+ { "MasterSourceAddress", "pn_ptcp.master_source_address",
+ FT_ETHER, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_subdomain_uuid,
+ { "SubdomainUUID", "pn_ptcp.subdomain_uuid",
+ FT_GUID, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_port_mac_address,
+ { "PortMACAddress", "pn_ptcp.port_mac_address",
+ FT_ETHER, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_t2portrxdelay,
+ { "T2PortRxDelay (ns)", "pn_ptcp.t2portrxdelay",
+ FT_UINT32, BASE_DEC, 0x0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_t3porttxdelay,
+ { "T3PortTxDelay (ns)", "pn_ptcp.t3porttxdelay",
+ FT_UINT32, BASE_DEC, 0x0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_t2timestamp,
+ { "T2TimeStamp (ns)", "pn_ptcp.t2timestamp",
+ FT_UINT32, BASE_DEC, 0x0, 0x0,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_epoch_number,
+ { "EpochNumber", "pn_ptcp.epoch_number",
+ FT_UINT16, BASE_DEC, 0x0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_seconds,
+ { "Seconds", "pn_ptcp.seconds",
+ FT_UINT32, BASE_DEC, 0x0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_nanoseconds,
+ { "NanoSeconds", "pn_ptcp.nanoseconds",
+ FT_UINT32, BASE_DEC, 0x0, 0x0,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_flags,
+ { "Flags", "pn_ptcp.flags",
+ FT_UINT16, BASE_HEX, 0x0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_currentutcoffset,
+ { "CurrentUTCOffset", "pn_ptcp.currentutcoffset",
+ FT_UINT16, BASE_DEC, 0x0, 0x0,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_master_priority1,
+ { "MasterPriority1.Priority", "pn_ptcp.master_priority1_prio",
+ FT_UINT8, BASE_HEX, VALS(pn_ptcp_master_prio1_vals), 0x07,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_master_priority_level,
+ { "MasterPriority1.Level", "pn_ptcp.master_priority1_level",
+ FT_UINT8, BASE_HEX, VALS(pn_ptcp_master_prio1_levels), 0x38,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_master_priority1_res,
+ { "MasterPriority1.Reserved", "pn_ptcp.master_priority1_res",
+ FT_UINT8, BASE_HEX, 0x0, 0x40,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_master_priority1_act,
+ { "MasterPriority1.Active", "pn_ptcp.master_priority1_act",
+ FT_UINT8, BASE_HEX, VALS(pn_ptcp_master_prio1_vals_active), 0x80,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_master_priority2,
+ { "MasterPriority2", "pn_ptcp.master_priority2",
+ FT_UINT8, BASE_DEC, VALS(pn_ptcp_master_prio2_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_clock_class,
+ { "ClockClass", "pn_ptcp.clock_class",
+ FT_UINT8, BASE_DEC, VALS(pn_ptcp_clock_class_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_clock_accuracy,
+ { "ClockAccuracy", "pn_ptcp.clock_accuracy",
+ FT_UINT8, BASE_DEC, VALS(pn_ptcp_clock_accuracy_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_clockvariance,
+ { "ClockVariance", "pn_ptcp.clockvariance",
+ FT_INT16, BASE_DEC, 0x0, 0x0,
+ NULL, HFILL }},
+
+
+ { &hf_pn_ptcp_oui,
+ { "Organizationally Unique Identifier", "pn_ptcp.oui",
+ FT_UINT24, BASE_HEX, VALS(pn_ptcp_oui_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_ptcp_profinet_subtype,
+ { "Subtype", "pn_ptcp.subtype",
+ FT_UINT8, BASE_HEX, VALS(pn_ptcp_profinet_subtype_vals), 0x0,
+ "PROFINET Subtype", HFILL }},
+
+
+ { &hf_pn_ptcp_irdata_uuid,
+ { "IRDataUUID", "pn_ptcp.irdata_uuid",
+ FT_GUID, BASE_NONE, 0x0, 0x0,
+ NULL, HFILL }},
+
+ };
+
+ static gint *ett[] = {
+ &ett_pn_ptcp,
+ &ett_pn_ptcp_header,
+ &ett_pn_ptcp_block,
+ &ett_pn_ptcp_block_header
+ };
+ proto_pn_ptcp = proto_register_protocol ("PROFINET PTCP", "PN-PTCP", "pn_ptcp");
+ proto_register_field_array (proto_pn_ptcp, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+}
+
+void
+proto_reg_handoff_pn_ptcp (void)
+{
+ /* register ourself as an heuristic pn-rt payload dissector */
+ heur_dissector_add("pn_rt", dissect_PNPTCP_Data_heur, "PROFINET PTCP IO", "pn_ptcp_pn_rt", proto_pn_ptcp, HEURISTIC_ENABLE);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-pn-rsi.c b/plugins/epan/profinet/packet-pn-rsi.c
new file mode 100644
index 0000000..94d61a8
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn-rsi.c
@@ -0,0 +1,1087 @@
+/* packet-pn-rsi.c
+ * Routines for PN-RSI
+ * packet dissection.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 Gerald Combs
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/exceptions.h>
+#include <epan/to_str.h>
+#include <epan/wmem_scopes.h>
+#include <epan/dissectors/packet-dcerpc.h>
+#include <epan/expert.h>
+#include <epan/conversation_filter.h>
+#include <epan/proto_data.h>
+#include <epan/reassemble.h>
+#include <epan/conversation.h>
+
+#include <wsutil/file_util.h>
+#include <epan/prefs.h>
+
+#include "packet-pn.h"
+
+void proto_register_pn_rsi(void);
+void proto_reg_handoff_pn_rsi(void);
+
+static int proto_pn_rsi = -1;
+
+static int hf_pn_rsi_dst_srv_access_point = -1;
+static int hf_pn_rsi_src_srv_access_point = -1;
+
+static int hf_pn_rsi_pdu_type = -1;
+static int hf_pn_rsi_pdu_type_type = -1;
+static int hf_pn_rsi_pdu_type_version = -1;
+
+static int hf_pn_rsi_add_flags = -1;
+static int hf_pn_rsi_add_flags_windowsize = -1;
+static int hf_pn_rsi_add_flags_reserved1 = -1;
+static int hf_pn_rsi_add_flags_tack = -1;
+static int hf_pn_rsi_add_flags_morefrag = -1;
+static int hf_pn_rsi_add_flags_notification = -1;
+static int hf_pn_rsi_add_flags_reserved2 = -1;
+
+static int hf_pn_rsi_send_seq_num = -1;
+static int hf_pn_rsi_ack_seq_num = -1;
+static int hf_pn_rsi_var_part_len = -1;
+
+static int hf_pn_rsi_f_opnum_offset = -1;
+static int hf_pn_rsi_f_opnum_offset_offset = -1;
+static int hf_pn_rsi_f_opnum_offset_opnum = -1;
+static int hf_pn_rsi_f_opnum_offset_callsequence = -1;
+
+static int hf_pn_rsi_conn_block = -1;
+static int hf_pn_rsi_rsp_max_length = -1;
+static int hf_pn_rsi_vendor_id = -1;
+static int hf_pn_rsi_device_id = -1;
+static int hf_pn_rsi_instance_id = -1;
+static int hf_pn_rsi_interface = -1;
+
+static int hf_pn_rsi_svcs_block = -1;
+
+static int hf_pn_rsi_number_of_entries = -1;
+static int hf_pn_rsi_pd_rsi_instance = -1;
+static int hf_pn_rsi_device_type = -1;
+static int hf_pn_rsi_order_id = -1;
+static int hf_pn_rsi_im_serial_number = -1;
+static int hf_pn_rsi_hw_revision = -1;
+static int hf_pn_rsi_sw_revision_prefix = -1;
+static int hf_pn_rsi_sw_revision = -1;
+
+static gint ett_pn_rsi = -1;
+static gint ett_pn_rsi_pdu_type = -1;
+static gint ett_pn_rsi_f_opnum_offset = -1;
+static gint ett_pn_rsi_conn_block = -1;
+static gint ett_pn_rsi_svcs_block = -1;
+static gint ett_pn_rsi_add_flags = -1;
+static gint ett_pn_rsi_rta = -1;
+static gint ett_pn_io_pd_rsi_instance = -1;
+
+static expert_field ei_pn_rsi_error = EI_INIT;
+
+static const range_string pn_rsi_alarm_endpoint[] = {
+ { 0x0000, 0x7FFF, "RSI Initiator Instance (ISAP) or RSI Responder Instance (RSAP)" },
+ { 0x8000, 0xFFFE, "Reserved" },
+ { 0xFFFF, 0xFFFF, "CON-SAP" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_rsi_pdu_type_type[] = {
+ { 0x00, 0x02, "Reserved" },
+ { 0x03, 0x03, "RTA_TYPE_ACK" },
+ { 0x04, 0x04, "RTA_TYPE_ERR" },
+ { 0x05, 0x05, "RTA_TYPE_FREQ" },
+ { 0x06, 0x06, "RTA_TYPE_FRSP" },
+ { 0x07, 0x0F, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_rsi_pdu_type_version[] = {
+ { 0x00, 0x00, "Reserved" },
+ { 0x01, 0x01, "Version 1 of the protocol" },
+ { 0x02, 0x02, "Version 2 of the protocol" },
+ { 0x03, 0X0F, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_rsi_add_flags_windowsize[] = {
+ { 0x00, "Reserved" },
+ { 0x01, "Unknown WindowSize" },
+ { 0x02, "Smallest WindowSize" },
+ { 0x03, "Optional usable WindowSize" },
+ { 0x04, "Optional usable WindowSize" },
+ { 0x05, "Optional usable WindowSize" },
+ { 0x06, "Optional usable WindowSize" },
+ { 0x07, "Optional usable WindowSize" },
+ { 0, NULL }
+};
+
+static const value_string pn_rsi_add_flags_tack[] = {
+ { 0x00, "No immediate acknowledge" },
+ { 0x01, "Immediate acknowledge" },
+ { 0, NULL }
+};
+
+static const value_string pn_rsi_add_flags_morefrag[] = {
+ { 0x00, "Last fragment" },
+ { 0x01, "More fragments follows" },
+ { 0, NULL }
+};
+
+static const value_string pn_rsi_add_flags_notification[] = {
+ { 0x00, "No action necessary" },
+ { 0x01, "The ApplicationReadyBlock is available for reading with the service ReadNotification" },
+ { 0, NULL }
+};
+
+static const range_string pn_rsi_seq_num[] = {
+ { 0x0000, 0x7FFF, "synchronization and transmission between initiator and responder" },
+ { 0x8000, 0xFFFD, "Reserved" },
+ { 0xFFFE, 0xFFFE, "synchronize initiator and responder for establishment of an AR" },
+ { 0xFFFF, 0xFFFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_rsi_var_part_len[] = {
+ { 0x0000, 0x0000, "No RTA-SDU or RSI-SDU exists" },
+ { 0x0001, 0x0598, "An RTA-SDU or RSI-PDU with VarPartLen octets exists" },
+ { 0x0599, 0xFFFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_rsi_f_opnum_offset_offset[] = {
+ { 0x00000000, 0x00000000, "First fragment" },
+ { 0x00000001, 0x00000003, "Reserved" },
+ { 0x00000004, 0x00FFFFFF, "Not first fragment" },
+ { 0, 0, NULL }
+};
+
+static const value_string pn_rsi_f_opnum_offset_opnum[] = {
+ { 0x00, "Connect" },
+ { 0x01, "Reserved" },
+ { 0x02, "Read" },
+ { 0x03, "Write" },
+ { 0x04, "Control" },
+ { 0x05, "ReadImplicit" },
+ { 0x06, "ReadConnectionless" },
+ { 0x07, "ReadNotification" },
+ { 0x08, "PrmWriteMore" },
+ { 0x09, "PrmWriteEnd" },
+ { 0x0A, "Reserved" },
+ { 0x0B, "Reserved" },
+ { 0x0C, "Reserved" },
+ { 0x0D, "Reserved" },
+ { 0x0E, "Reserved" },
+ { 0x0F, "Reserved" },
+ { 0x1F, "Reserved" },
+ { 0, NULL }
+};
+
+static const range_string pn_rsi_f_opnum_offset_callsequence[] = {
+ { 0x00, 0x07, "Allowed values" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_rsi_rsp_max_length[] = {
+ { 0x00000000, 0x00000003, "Reserved" },
+ { 0x00000004, 0x00FFFFFF, "Usable" },
+ { 0x01FFFFFF, 0xFFFFFFFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static const range_string pn_rsi_interface[] = {
+ { 0x00, 0x00, "IO device interface" },
+ { 0x01, 0x01, "Read Implicit IO device interface" },
+ { 0x02, 0x02, "CIM device interface" },
+ { 0x03, 0x03, "Read Implicit CIM device interface" },
+ { 0x04, 0xFF, "Reserved" },
+ { 0, 0, NULL }
+};
+
+static int
+dissect_FOpnumOffset(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, guint32 *u32FOpnumOffset)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_rsi_f_opnum_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_f_opnum_offset);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_f_opnum_offset_offset, u32FOpnumOffset);
+ dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_f_opnum_offset_opnum, u32FOpnumOffset);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_f_opnum_offset_callsequence, u32FOpnumOffset);
+
+ return offset;
+}
+
+static int hf_pn_rsi_data_payload = -1;
+
+static int hf_pn_rsi_segments = -1;
+static int hf_pn_rsi_segment = -1;
+//static int hf_pn_rsi_data = -1;
+static int hf_pn_rsi_segment_overlap = -1;
+static int hf_pn_rsi_segment_overlap_conflict = -1;
+static int hf_pn_rsi_segment_multiple_tails = -1;
+static int hf_pn_rsi_segment_too_long_segment = -1;
+static int hf_pn_rsi_segment_error = -1;
+static int hf_pn_rsi_segment_count = -1;
+static int hf_pn_rsi_reassembled_in = -1;
+static int hf_pn_rsi_reassembled_length = -1;
+
+static reassembly_table pn_rsi_reassembly_table;
+
+void
+pn_rsi_reassemble_init(void)
+{
+ reassembly_table_register(&pn_rsi_reassembly_table, &addresses_reassembly_table_functions);
+}
+
+static gint ett_pn_rsi_segments = -1;
+static gint ett_pn_rsi_segment = -1;
+//static gint ett_pn_rsi_data = -1;
+static gint ett_pn_rsi_data_payload = -1;
+
+static const fragment_items pn_rsi_frag_items = {
+ &ett_pn_rsi_segment,
+ &ett_pn_rsi_segments,
+ &hf_pn_rsi_segments,
+ &hf_pn_rsi_segment,
+ &hf_pn_rsi_segment_overlap,
+ &hf_pn_rsi_segment_overlap_conflict,
+ &hf_pn_rsi_segment_multiple_tails,
+ &hf_pn_rsi_segment_too_long_segment,
+ &hf_pn_rsi_segment_error,
+ &hf_pn_rsi_segment_count,
+ &hf_pn_rsi_reassembled_in,
+ &hf_pn_rsi_reassembled_length,
+ /* Reassembled data field */
+ NULL,
+ "segments"
+};
+
+static int
+dissect_pn_rta_remaining_user_data_bytes(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint8 *drep, guint32 length, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOpnum, int type)
+{
+ fragment_head *fd_frag;
+ fragment_head *fd_reass;
+ conversation_t *conv;
+ tvbuff_t *next_tvb;
+ proto_item *pn_rsi_tree_item;
+ proto_item *payload_item = NULL;
+ proto_item *payload_tree = NULL;
+ gboolean update_col_info = TRUE;
+
+ if (pinfo->srcport != 0 && pinfo->destport != 0) {
+ /* COTP over RFC1006/TCP, try reassembling */
+ conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, CONVERSATION_NONE,
+ pinfo->srcport, pinfo->destport, 0);
+ if (!conv) {
+ conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, CONVERSATION_NONE,
+ pinfo->srcport, pinfo->destport, 0);
+ }
+
+ /* XXX - don't know if this will work with multiple segmented Ack's in a single TCP stream */
+ fd_frag = fragment_get(&pn_rsi_reassembly_table, pinfo, conv->conv_index, NULL);
+ fd_reass = fragment_get_reassembled_id(&pn_rsi_reassembly_table, pinfo, conv->conv_index);
+ }
+ else {
+ /* plain COTP transport (without RFC1006/TCP), try reassembling */
+ conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, CONVERSATION_NONE,
+ pinfo->clnp_srcref, pinfo->clnp_dstref, 0);
+ if (!conv) {
+ conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, CONVERSATION_NONE,
+ pinfo->clnp_srcref, pinfo->clnp_dstref, 0);
+ }
+
+ /* XXX - don't know if this will work with multiple segmented Ack's in a single TCP stream */
+ fd_frag = fragment_get(&pn_rsi_reassembly_table, pinfo, conv->conv_index, NULL);
+ fd_reass = fragment_get_reassembled_id(&pn_rsi_reassembly_table, pinfo, conv->conv_index);
+ }
+
+ /* is this packet containing a "standalone" segment? */
+ if (!u8MoreFrag && !fd_frag && !fd_reass) {
+ /* "standalone" segment, simply show payload and return */
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+ return offset;
+ }
+
+ /* multiple segments */
+ if (!pinfo->fd->visited && conv != NULL) {
+ /* we haven't seen it before, add to list of segments */
+ fragment_add_seq_next(&pn_rsi_reassembly_table, tvb, offset, pinfo, conv->conv_index,
+ NULL /*Data comes from tvb as in packet-icmp-template.c */,
+ length,
+ u8MoreFrag);
+
+ fd_reass = fragment_get_reassembled_id(&pn_rsi_reassembly_table, pinfo, conv->conv_index);
+ }
+
+ /* update display */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " [%sPN IO RSI Segment]",
+ u8MoreFrag ? "" : "Last ");
+
+ /* reassembling completed? */
+ if (fd_reass != NULL) {
+ /* is this the packet to show the reassembed payload in? */
+ if (pinfo->fd->num == fd_reass->reassembled_in) {
+ next_tvb = process_reassembled_data(tvb, 0, pinfo,
+ "Reassembled PN IO RSI packet", fd_reass, &pn_rsi_frag_items, &update_col_info, tree);
+
+ /* XXX - create new parent tree item "Reassembled Data Segments" */
+ payload_item = proto_tree_add_item(tree, hf_pn_rsi_data_payload, next_tvb, 0, tvb_captured_length(next_tvb), ENC_NA);
+ payload_tree = proto_item_add_subtree(payload_item, ett_pn_rsi_data_payload);
+
+ offset = dissect_rsi_blocks(next_tvb, 0, pinfo, payload_tree, drep, u32FOpnumOffsetOpnum, type);
+
+ /* the toplevel fragment subtree is now behind all desegmented data,
+ * move it right behind the DE2 tree item */
+ // pn_rsi_tree_item = proto_tree_get_parent(tree);
+
+ }
+ else {
+ /* segment of a multiple segment payload */
+ proto_item *pi;
+
+ pn_rsi_tree_item = proto_tree_get_parent(tree);
+ pi = proto_tree_add_uint(pn_rsi_tree_item, hf_pn_rsi_reassembled_in,
+ tvb, 0, 0, fd_reass->reassembled_in);
+ proto_item_set_generated(pi);
+ }
+ }
+
+ return offset;
+}
+
+/* dissect a PN-IO RSI SVCS block (on top of PN-RT protocol) */
+static int
+dissect_RSI_SVCS_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
+{
+ proto_item* sub_item;
+ proto_tree *sub_tree;
+
+ guint32 u32RsiHeaderSize = 4;
+ guint32 u32RspMaxLength;
+
+ // PDU.FOpnumOffset.Offset + PDU.VarPartLen - 4 - RsiHeaderSize
+ gint32 length = u32FOpnumOffsetOffset + u16VarPartLen - 4 - u32RsiHeaderSize;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_rsi_svcs_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_svcs_block);
+
+ if (u32FOpnumOffsetOffset == 0)
+ {
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_rsp_max_length, &u32RspMaxLength);
+ }
+ else if (u8MoreFrag == 0)
+ {
+ proto_item_append_text(sub_item, ", RSI Header of SVCS is at first segment");
+ }
+
+ if (length > 0) {
+ offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, sub_tree, drep,
+ tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_REQ);
+ }
+ return offset;
+}
+
+/* dissect a PN-IO RSI CONN block (on top of PN-RT protocol) */
+static int
+dissect_RSI_CONN_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ guint32 u32RspMaxLength;
+ guint16 u16VendorId;
+ guint16 u16DeviceId;
+ guint16 u16InstanceId;
+ guint8 u8RsiInterface;
+ guint32 u32RsiHeaderSize = 4;
+
+ // PDU.FOpnumOffset.Offset + PDU.VarPartLen - 4 - RsiHeaderSize
+ gint32 length = u32FOpnumOffsetOffset + u16VarPartLen - 4 - u32RsiHeaderSize;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_rsi_conn_block, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_conn_block);
+
+ if (u32FOpnumOffsetOffset == 0) {
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_rsp_max_length, &u32RspMaxLength);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_vendor_id, &u16VendorId);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_device_id, &u16DeviceId);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_instance_id, &u16InstanceId);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_interface, &u8RsiInterface);
+
+ offset = dissect_pn_padding(tvb, offset, pinfo, sub_tree, 1);
+ }
+ else if (u8MoreFrag == 0)
+ {
+ proto_item_append_text(sub_item, ", RSI Header of CONN is at first segment");
+ }
+
+ if (length > 0) {
+ offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, sub_tree, drep,
+ tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_REQ);
+ }
+
+ return offset;
+}
+
+/* dissect a PN-IO RSI FREQ RTA PDU (on top of PN-RT protocol) */
+static int
+dissect_FREQ_RTA_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag)
+{
+ guint32 u32FOpnumOffset;
+ guint32 u32FOpnumOffsetOpnum;
+ guint32 u32FOpnumOffsetOffset;
+ offset = dissect_FOpnumOffset(tvb, offset, pinfo, tree, drep, &u32FOpnumOffset);
+ u32FOpnumOffsetOpnum = (u32FOpnumOffset & 0x1F000000) >> 24;
+ u32FOpnumOffsetOffset = u32FOpnumOffset & 0x00FFFFFF;
+ switch (u32FOpnumOffsetOpnum) {
+ case(0x0): /* RSI-CONN-PDU */
+ col_append_str(pinfo->cinfo, COL_INFO, "Connect request");
+ offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ case(0x1): /* Reserved */
+ col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
+ break;
+ case(0x2): /* RSI-SVCS-PDU (Only valid with ARUUID<>0) */
+ col_append_str(pinfo->cinfo, COL_INFO, "Read request");
+ offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ case(0x3): /* RSI-SVCS-PDU */
+ col_append_str(pinfo->cinfo, COL_INFO, "Write request");
+ offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ case(0x4): /* RSI-SVCS-PDU */
+ col_append_str(pinfo->cinfo, COL_INFO, "Control request");
+ offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ case(0x5): /* RSI-CONN-PDU (Only valid with ARUUID=0) */
+ col_append_str(pinfo->cinfo, COL_INFO, "ReadImplicit request");
+ offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ case(0x6): /* RSI-CONN-PDU (Only valid with ARUUID<>0) */
+ col_append_str(pinfo->cinfo, COL_INFO, "ReadConnectionless request");
+ offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ case(0x7): /* RSI-SVCS-PDU */
+ col_append_str(pinfo->cinfo, COL_INFO, "ReadNotification request");
+ offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ case(0x8): /* RSI-SVCS-PDU */
+ col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteMore request");
+ offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ case(0x9) : /* RSI-SVCS-PDU */
+ col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteEnd request");
+ offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ break;
+ default:
+ col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
+ break;
+ }
+ return offset;
+}
+
+/* dissect a PN-IO RSI RSP block (on top of PN-RT protocol) */
+static int
+dissect_RSI_RSP_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
+{
+ guint32 u32RsiHeaderSize = 4;
+
+ // PDU.FOpnumOffset.Offset + PDU.VarPartLen - 4 - RsiHeaderSize
+ gint32 length = u32FOpnumOffsetOffset + u16VarPartLen - 4 - u32RsiHeaderSize;
+
+ if (u32FOpnumOffsetOffset == 0)
+ {
+ offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
+ }
+
+ else if (u8MoreFrag == 0)
+ {
+ proto_item_append_text(tree, ", RSI Header of RSP is at first fragmented frame");
+ }
+
+ if (length > 0) {
+ offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, tree, drep,
+ tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_RSP);
+ }
+
+ return offset;
+}
+
+/* dissect a PN-IO RSI FRSP RTA PDU (on top of PN-RT protocol) */
+static int
+dissect_FRSP_RTA_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag)
+{
+ guint32 u32FOpnumOffset;
+ guint32 u32FOpnumOffsetOpnum;
+ guint32 u32FOpnumOffsetOffset;
+ offset = dissect_FOpnumOffset(tvb, offset, pinfo, tree, drep, &u32FOpnumOffset);
+ u32FOpnumOffsetOpnum = (u32FOpnumOffset & 0x1F000000) >> 24;
+ u32FOpnumOffsetOffset = u32FOpnumOffset & 0x00FFFFFF;
+ switch (u32FOpnumOffsetOpnum) {
+ case(0x0): /* Connect */
+ col_append_str(pinfo->cinfo, COL_INFO, "Connect response");
+ break;
+ case(0x1): /* Reserved */
+ col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
+ break;
+ case(0x2): /* Read */
+ col_append_str(pinfo->cinfo, COL_INFO, "Read response");
+ break;
+ case(0x3): /* Write */
+ col_append_str(pinfo->cinfo, COL_INFO, "Write response");
+ break;
+ case(0x4): /* Control */
+ col_append_str(pinfo->cinfo, COL_INFO, "Control response");
+ break;
+ case(0x5): /* ReadImplicit */
+ col_append_str(pinfo->cinfo, COL_INFO, "ReadImplicit response");
+ break;
+ case(0x6): /* ReadConnectionless */
+ col_append_str(pinfo->cinfo, COL_INFO, "ReadConnectionless response");
+ break;
+ case(0x7): /* ReadNotification */
+ col_append_str(pinfo->cinfo, COL_INFO, "ReadNotification response");
+ break;
+ case(0x8): /* PrmWriteMore */
+ col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteMore response");
+ break;
+ case(0x9) : /* PrmWriteEnd */
+ col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteEnd response");
+ break;
+ default:
+ col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
+ break;
+ }
+ offset = dissect_RSI_RSP_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
+ return offset;
+}
+
+static int
+dissect_RSIAdditionalFlags(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, guint8 *u8AddFlags)
+{
+ guint8 u8WindowSize;
+ guint8 u8Tack;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* additional flags */
+ sub_item = proto_tree_add_item(tree, hf_pn_rsi_add_flags, tvb, offset, 1, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_add_flags);
+ /* Bit 0 - 2 : AddFlags.WindowSize */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_add_flags_windowsize, u8AddFlags);
+ /* Bit 3: AddFlags.Reserved */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_add_flags_reserved1, u8AddFlags);
+ /* Bit 4: AddFlags.TACK */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_add_flags_tack, u8AddFlags);
+ /* Bit 5: AddFlags.MoreFrag */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_add_flags_morefrag, u8AddFlags);
+ /* Bit 6: AddFlags.Notification */
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_add_flags_notification, u8AddFlags);
+ /* Bit 7: AddFlags.Reserved */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_add_flags_reserved2, u8AddFlags);
+ u8WindowSize = *u8AddFlags & 0x03;
+ u8Tack = (*u8AddFlags & 0x10);
+ u8Tack = (u8Tack == 0x10) ? 1 : 0;
+
+ proto_item_append_text(sub_item, ", Window Size: %u, Tack: %u ",
+ u8WindowSize, u8Tack);
+ return offset;
+}
+
+/* dissect a PN-IO RTA RSI PDU (on top of PN-RT protocol) */
+int
+dissect_PNIO_RSI(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16DestinationServiceAccessPoint;
+ guint16 u16SourceServiceAccessPoint;
+ guint8 u8PDUType;
+ guint8 u8PDUVersion;
+ guint8 u8AddFlags;
+ guint8 u8MoreFrag;
+ guint16 u16SendSeqNum;
+ guint16 u16AckSeqNum;
+ guint16 u16VarPartLen;
+ int start_offset = offset;
+
+ proto_item *rta_item;
+ proto_tree *rta_tree;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-RSI");
+ rta_item = proto_tree_add_protocol_format(tree, proto_pn_rsi, tvb, offset, tvb_captured_length(tvb),
+ "PROFINET IO RSI");
+
+ rta_tree = proto_item_add_subtree(rta_item, ett_pn_rsi_rta);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_rsi_dst_srv_access_point, &u16DestinationServiceAccessPoint);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_rsi_src_srv_access_point, &u16SourceServiceAccessPoint);
+
+ //col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: 0x%x, Dst: 0x%x",
+ // u16SourceServiceAccessPoint, u16DestinationServiceAccessPoint);
+
+ /* PDU type */
+ sub_item = proto_tree_add_item(rta_tree, hf_pn_rsi_pdu_type, tvb, offset, 1, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_pdu_type);
+
+ /* PDU type type - version of RTA 2*/
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_pdu_type_type, &u8PDUType);
+ u8PDUType &= 0x0F;
+
+ /* PDU type version - version of RTA 2*/
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_pdu_type_version, &u8PDUVersion);
+ u8PDUVersion >>= 4;
+ //proto_item_append_text(sub_item, ", Type: %s, Version: %u",
+ // val_to_str(u8PDUType, pn_rsi_pdu_type_type, "Unknown"),
+ // u8PDUVersion);
+ offset = dissect_RSIAdditionalFlags(tvb, offset, pinfo, rta_tree, drep, &u8AddFlags);
+ u8MoreFrag = (u8AddFlags >> 5) & 0x1;
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_rsi_send_seq_num, &u16SendSeqNum);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_rsi_ack_seq_num, &u16AckSeqNum);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_rsi_var_part_len, &u16VarPartLen);
+
+ switch (u8PDUType & 0x0F) {
+ case(3): /* ACK-RTA */
+ col_append_str(pinfo->cinfo, COL_INFO, "ACK-RTA");
+
+ if (u8AddFlags & 0x40) {
+
+ col_append_str(pinfo->cinfo, COL_INFO, ", Application Ready Notification");
+ }
+ /* no additional data */
+ break;
+ case(4): /* ERR-RTA */
+ col_append_str(pinfo->cinfo, COL_INFO, "ERR-RTA");
+ offset = dissect_PNIO_status(tvb, offset, pinfo, rta_tree, drep);
+ break;
+ case(5): /* FREQ-RTA */
+ offset = dissect_FREQ_RTA_block(tvb, offset, pinfo, rta_tree, drep, u16VarPartLen, u8MoreFrag);
+ break;
+ case(6): /* FRSP-RTA */
+ offset = dissect_FRSP_RTA_block(tvb, offset, pinfo, rta_tree, drep, u16VarPartLen, u8MoreFrag);
+ break;
+ default:
+ offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
+ break;
+ }
+
+ proto_item_set_len(rta_item, offset - start_offset);
+
+ return offset;
+}
+
+int
+dissect_PDRsiInstances_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16NumberOfEntries;
+ guint16 u16VendorId;
+ guint16 u16DeviceId;
+ guint16 u16InstanceId;
+ guint8 u8RsiInterface;
+ const int deviceType_size = 25;
+ const int orderID_size = 20;
+ const int IMserialnumber_size = 16;
+ const int HWrevision_size = 5;
+ const int SWrevisionprefix_size = 1;
+ const int SWrevision_size = 9;
+
+ if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
+ expert_add_info_format(pinfo, item, &ei_pn_rsi_error,
+ "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
+ return offset;
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_rsi_number_of_entries, &u16NumberOfEntries);
+
+ proto_item_append_text(item, ": NumberOfEntries:%u", u16NumberOfEntries);
+
+ while (u16NumberOfEntries > 0) {
+ u16NumberOfEntries--;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_rsi_pd_rsi_instance, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pd_rsi_instance);
+ /* VendorID */
+ /* DeviceID */
+ /* InstanceID */
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_vendor_id, &u16VendorId);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_device_id, &u16DeviceId);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_instance_id, &u16InstanceId);
+
+ /* RSI Interface */
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_rsi_interface, &u8RsiInterface);
+
+ proto_item_append_text(sub_item, ": VendorID:%u, DeviceID:%u, InstanceID:%u, RsiInterface:%u",
+ u16VendorId, u16DeviceId, u16InstanceId, u8RsiInterface);
+
+ /* Padding */
+ offset = dissect_pn_padding(tvb, offset, pinfo, sub_tree, 1);
+ }
+
+ /* SystemIdentification */
+ /* DeviceType */
+ proto_tree_add_item(tree, hf_pn_rsi_device_type, tvb, offset, deviceType_size, ENC_UTF_8);
+ offset += deviceType_size + 1;
+
+ /* Blank */
+
+ /* OrderID */
+ proto_tree_add_item(tree, hf_pn_rsi_order_id, tvb, offset, orderID_size, ENC_UTF_8);
+ offset += orderID_size + 1;
+
+ /* Blank */
+
+ /* IM_Serial_Number */
+ proto_tree_add_item(tree, hf_pn_rsi_im_serial_number, tvb, offset, IMserialnumber_size, ENC_UTF_8);
+ offset += IMserialnumber_size + 1;
+
+ /* Blank */
+
+ /* HWRevision */
+ proto_tree_add_item(tree, hf_pn_rsi_hw_revision, tvb, offset, HWrevision_size, ENC_UTF_8);
+ offset += HWrevision_size + 1;
+
+ /* Blank */
+
+ /* SWRevisionPrefix */
+ proto_tree_add_item(tree, hf_pn_rsi_sw_revision_prefix, tvb, offset, SWrevisionprefix_size, ENC_UTF_8);
+ offset += SWrevisionprefix_size;
+
+ /* SWRevision */
+ proto_tree_add_item(tree, hf_pn_rsi_sw_revision, tvb, offset, SWrevision_size, ENC_UTF_8);
+ offset += SWrevision_size;
+ return offset;
+}
+
+void
+init_pn_rsi(int proto)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_rsi_dst_srv_access_point,
+ { "DestinationServiceAccessPoint", "pn_rsi.dst_srv_access_point",
+ FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_alarm_endpoint), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_src_srv_access_point,
+ { "SourceServiceAccessPoint", "pn_rsi.src_srv_access_point",
+ FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_alarm_endpoint), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_pdu_type,
+ { "PDUType", "pn_rsi.pdu_type",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_pdu_type_type,
+ { "Type", "pn_rsi.pdu_type.type",
+ FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_pdu_type_type), 0x0F,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_pdu_type_version,
+ { "Version", "pn_rsi.pdu_type.version",
+ FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_pdu_type_version), 0xF0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_add_flags,
+ { "AddFlags", "pn_rsi.add_flags",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_add_flags_windowsize,
+ { "WindowSize", "pn_rsi.add_flags_windowsize",
+ FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_windowsize), 0x07,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_add_flags_reserved1,
+ { "Reserved", "pn_rsi.add_flags_reserved",
+ FT_UINT8, BASE_HEX, NULL, 0x08,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_add_flags_tack,
+ { "TACK", "pn_rsi.add_flags_tack",
+ FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_tack), 0x10,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_add_flags_morefrag,
+ { "MoreFrag", "pn_rsi.add_flags_morefrag",
+ FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_morefrag), 0x20,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_add_flags_notification,
+ { "Notification", "pn_rsi.add_flags_notification",
+ FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_notification), 0x40,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_add_flags_reserved2,
+ { "Reserved", "pn_rsi.add_flags_reserved",
+ FT_UINT8, BASE_HEX, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_send_seq_num,
+ { "SendSeqNum", "pn_rsi.send_seq_num",
+ FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_seq_num), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_ack_seq_num,
+ { "AckSeqNum", "pn_rsi.ack_seq_num",
+ FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_seq_num), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_var_part_len,
+ { "VarPartLen", "pn_rsi.var_part_len",
+ FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_var_part_len), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_f_opnum_offset,
+ { "FOpnumOffset", "pn_rsi.f_opnum_offset",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_f_opnum_offset_offset,
+ { "FOpnumOffset.Offset", "pn_rsi.f_opnum_offset.offset",
+ FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_f_opnum_offset_offset), 0x00FFFFFF,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_f_opnum_offset_opnum,
+ { "FOpnumOffset.Opnum", "pn_rsi.f_opnum_offset.opnum",
+ FT_UINT32, BASE_HEX, VALS(pn_rsi_f_opnum_offset_opnum), 0x1F000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_f_opnum_offset_callsequence,
+ { "FOpnumOffset.CallSequence", "pn_rsi.f_opnum_offset.callsequence",
+ FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_f_opnum_offset_callsequence), 0xE0000000,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_conn_block,
+ { "RSI CONN Block", "pn_rsi.conn_block",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_rsp_max_length,
+ { "RspMaxLength", "pn_rsi.rsp_max_length",
+ FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_rsp_max_length), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_vendor_id,
+ { "VendorID", "pn_rsi.vendor_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_device_id,
+ { "DeviceID", "pn_rsi.device_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_instance_id,
+ { "InstanceID", "pn_rsi.instance_id",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_interface,
+ { "RsiInterface", "pn_rsi.interface",
+ FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_interface), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_svcs_block,
+ { "RSI SVCS Block", "pn_rsi.svcs_block",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_number_of_entries,
+ { "NumberOfEntries", "pn_rsi.number_of_entries",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_pd_rsi_instance,
+ { "PDRsiInstance", "pn_rsi.pd_rsi_instance",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_device_type,
+ { "DeviceType", "pn_rsi.device_type",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_order_id,
+ { "OrderID", "pn_rsi.order_id",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_im_serial_number,
+ { "IM_Serial_Number", "pn_rsi.im_serial_number",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_hw_revision,
+ { "HWRevision", "pn_rsi.hw_revision",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_sw_revision_prefix,
+ { "SWRevisionPrefix", "pn_rsi.sw_revision_prefix",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_sw_revision,
+ { "SWRevision", "pn_rsi.sw_revision",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ /*&hf_pn_rsi_segment_too_long_segment,
+ &hf_pn_rsi_segment_error,
+ &hf_pn_rsi_segment_count,
+ &hf_pn_rsi_reassembled_in,
+ &hf_pn_rsi_reassembled_length,*/
+ { &hf_pn_rsi_segment,
+ { "RSI Segment", "pn_rsi.segment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_segments,
+ { "PN RSI Segments", "pn_rsi.segments",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_segment_overlap,
+ { "Segment overlap", "pn_rsi.segment.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Segment overlaps with other segments", HFILL }
+ },
+ { &hf_pn_rsi_segment_overlap_conflict,
+ { "Conflicting data in segment overlap", "pn_rsi.segment.overlap.conflict",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Overlapping segments contained conflicting data", HFILL }
+ },
+ { &hf_pn_rsi_segment_multiple_tails,
+ { "Multiple tail segments found", "pn_rsi.segment.multipletails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Several tails were found when reassembling the packet", HFILL }
+ },
+ { &hf_pn_rsi_segment_too_long_segment,
+ { "Segment too long", "pn_rsi.segment.toolongsegment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Segment contained data past end of packet", HFILL }
+ },
+ { &hf_pn_rsi_segment_error,
+ { "Reassembly error", "pn_rsi.segment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "Reassembly error due to illegal segments", HFILL }
+ },
+ { &hf_pn_rsi_segment_count,
+ { "Segment count", "pn_rsi.segment.count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_rsi_reassembled_in,
+ { "Reassembled pn_rsi in frame", "pn_rsi.reassembled_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "This pn_rsi packet is reassembled in this frame", HFILL }
+ },
+ { &hf_pn_rsi_reassembled_length,
+ { "Reassembled pn_rsi length", "pn_rsi.reassembled.length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "The total length of the reassembled payload", HFILL }
+ },
+ { &hf_pn_rsi_data_payload,
+ { "PN IO RSI Data Payload", "pn_rsi.data_payload",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ "", HFILL }
+ }
+ };
+
+ static gint *ett[] = {
+ &ett_pn_rsi,
+ &ett_pn_rsi_pdu_type,
+ &ett_pn_rsi_f_opnum_offset,
+ &ett_pn_rsi_conn_block,
+ &ett_pn_rsi_svcs_block,
+ &ett_pn_rsi_add_flags,
+ &ett_pn_rsi_rta,
+ &ett_pn_io_pd_rsi_instance,
+ &ett_pn_rsi_segments,
+ &ett_pn_rsi_segment,
+ &ett_pn_rsi_data_payload
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_pn_rsi_error, { "pn_rsi.error", PI_UNDECODED, PI_NOTE, "Block version not implemented yet!", EXPFILL } }
+
+ };
+
+ expert_module_t* expert_pn_rsi;
+
+ proto_pn_rsi = proto;
+
+ proto_register_field_array(proto, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ expert_pn_rsi = expert_register_protocol(proto_pn_rsi);
+ expert_register_field_array(expert_pn_rsi, ei, array_length(ei));
+
+ register_init_routine(pn_rsi_reassemble_init);
+}
diff --git a/plugins/epan/profinet/packet-pn-rt.c b/plugins/epan/profinet/packet-pn-rt.c
new file mode 100644
index 0000000..581ff01
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn-rt.c
@@ -0,0 +1,1204 @@
+/* packet-pn-rt.c
+ * Routines for pn-rt (PROFINET Real-Time) packet dissection.
+ * This is the base for other PROFINET protocols like IO, CBA, DCP, ...
+ * (the "content subdissectors" will register themselves using a heuristic)
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/reassemble.h>
+#include <epan/prefs.h>
+#include <epan/etypes.h>
+#include <epan/expert.h>
+#include <epan/crc16-tvb.h>
+#include <epan/dissectors/packet-dcerpc.h>
+
+#include <wsutil/crc16-plain.h>
+#include "packet-pn.h"
+
+
+void proto_register_pn_rt(void);
+void proto_reg_handoff_pn_rt(void);
+
+#define PROFINET_UDP_PORT 0x8892
+
+/* Define the pn-rt proto */
+static int proto_pn_rt = -1;
+static gboolean pnio_desegment = TRUE;
+
+static dissector_handle_t pn_rt_handle;
+
+/* Define many header fields for pn-rt */
+static int hf_pn_rt_frame_id = -1;
+static int hf_pn_rt_cycle_counter = -1;
+static int hf_pn_rt_transfer_status = -1;
+static int hf_pn_rt_data_status = -1;
+static int hf_pn_rt_data_status_ignore = -1;
+static int hf_pn_rt_frame_info_type = -1;
+static int hf_pn_rt_frame_info_function_meaning_input_conv = -1;
+static int hf_pn_rt_frame_info_function_meaning_output_conv = -1;
+static int hf_pn_rt_data_status_Reserved_2 = -1;
+static int hf_pn_rt_data_status_ok = -1;
+static int hf_pn_rt_data_status_operate = -1;
+static int hf_pn_rt_data_status_res3 = -1;
+static int hf_pn_rt_data_status_valid = -1;
+static int hf_pn_rt_data_status_redundancy = -1;
+static int hf_pn_rt_data_status_redundancy_output_cr = -1;
+static int hf_pn_rt_data_status_redundancy_input_cr_state_is_backup = -1;
+static int hf_pn_rt_data_status_redundancy_input_cr_state_is_primary = -1;
+static int hf_pn_rt_data_status_primary = -1;
+
+static int hf_pn_rt_sf_crc16 = -1;
+static int hf_pn_rt_sf_crc16_status = -1;
+static int hf_pn_rt_sf = -1;
+static int hf_pn_rt_sf_position = -1;
+/* static int hf_pn_rt_sf_position_control = -1; */
+static int hf_pn_rt_sf_data_length = -1;
+static int hf_pn_rt_sf_cycle_counter = -1;
+
+static int hf_pn_rt_frag = -1;
+static int hf_pn_rt_frag_data_length = -1;
+static int hf_pn_rt_frag_status = -1;
+static int hf_pn_rt_frag_status_more_follows = -1;
+static int hf_pn_rt_frag_status_error = -1;
+static int hf_pn_rt_frag_status_fragment_number = -1;
+static int hf_pn_rt_frag_data = -1;
+
+
+/*
+ * Define the trees for pn-rt
+ * We need one tree for pn-rt itself and one for the pn-rt data status subtree
+ */
+static int ett_pn_rt = -1;
+static int ett_pn_rt_data_status = -1;
+static int ett_pn_rt_sf = -1;
+static int ett_pn_rt_frag = -1;
+static int ett_pn_rt_frag_status = -1;
+
+static expert_field ei_pn_rt_sf_crc16 = EI_INIT;
+
+/*
+ * Here are the global variables associated with
+ * the various user definable characteristics of the dissection
+ */
+/* Place summary in proto tree */
+static gboolean pn_rt_summary_in_tree = TRUE;
+
+/* heuristic to find the right pn-rt payload dissector */
+static heur_dissector_list_t heur_subdissector_list;
+
+
+#if 0
+static const value_string pn_rt_position_control[] = {
+ { 0x00, "CRC16 and CycleCounter shall not be checked" },
+ { 0x80, "CRC16 and CycleCounter valid" },
+ { 0, NULL }
+};
+#endif
+
+static const true_false_string tfs_pn_rt_ds_redundancy_output_cr =
+ { "Unknown", "Redundancy has no meaning for OutputCRs, it is set to the fixed value of zero" };
+
+static const true_false_string tfs_pn_rt_ds_redundancy_input_cr_state_is_backup =
+ { "None primary AR of a given AR-set is present", "Default - One primary AR of a given AR-set is present" };
+
+static const true_false_string tfs_pn_rt_ds_redundancy_input_cr_state_is_primary =
+ { "The ARState from the IO device point of view is Backup", "Default - The ARState from the IO device point of view is Primary" };
+
+static const value_string pn_rt_frame_info_function_meaning_input_conv[] = {
+ {0x00, "Backup Acknowledge without actual data" },
+ {0x02, "Primary Missing without actual data" },
+ {0x04, "Backup Acknowledge with actual data independent from the Arstate" },
+ {0x05, "Primary Acknowledge"},
+ {0x06, "Primary Missing with actual data independent from the Arstate" },
+ {0x07, "Primary Fault" },
+ {0, NULL}
+};
+
+static const value_string pn_rt_frame_info_function_meaning_output_conv[] = {
+ { 0x04, "Backup Request" },
+ { 0x05, "Primary Request" },
+ { 0, NULL }
+};
+
+static const true_false_string tfs_pn_rt_ds_redundancy =
+ { "None primary AR of a given AR-set is present", "Redundancy has no meaning for OutputCRs / One primary AR of a given AR-set is present" };
+
+static const value_string pn_rt_frag_status_error[] = {
+ { 0x00, "reserved" },
+ { 0x01, "reserved: invalid should be zero" },
+ { 0, NULL }
+};
+
+static const value_string pn_rt_frag_status_more_follows[] = {
+ { 0x00, "Last fragment" },
+ { 0x01, "More fragments follow" },
+ { 0, NULL }
+};
+
+/* Copied and renamed from proto.c because global value_strings don't work for plugins */
+static const value_string plugin_proto_checksum_vals[] = {
+ { PROTO_CHECKSUM_E_BAD, "Bad" },
+ { PROTO_CHECKSUM_E_GOOD, "Good" },
+ { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
+ { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
+
+ { 0, NULL }
+};
+
+static void
+dissect_DataStatus(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo, guint8 u8DataStatus)
+{
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint8 u8DataValid;
+ guint8 u8Redundancy;
+ guint8 u8State;
+ conversation_t *conversation;
+ gboolean inputFlag = FALSE;
+ gboolean outputFlag = FALSE;
+ apduStatusSwitch *apdu_status_switch;
+
+ u8State = (u8DataStatus & 0x01);
+ u8Redundancy = (u8DataStatus >> 1) & 0x01;
+ u8DataValid = (u8DataStatus >> 2) & 0x01;
+
+ /* if PN Connect Request has been read, IOC mac is dl_src and IOD mac is dl_dst */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_UDP, 0, 0, 0);
+
+ if (conversation != NULL) {
+ apdu_status_switch = (apduStatusSwitch*)conversation_get_proto_data(conversation, proto_pn_io_apdu_status);
+ if (apdu_status_switch != NULL && apdu_status_switch->isRedundancyActive) {
+ /* IOC -> IOD: OutputCR */
+ if (addresses_equal(&(pinfo->src), conversation_key_addr1(conversation->key_ptr)) && addresses_equal(&(pinfo->dst), conversation_key_addr2(conversation->key_ptr))) {
+ outputFlag = TRUE;
+ inputFlag = FALSE;
+ }
+ /* IOD -> IOC: InputCR */
+ if (addresses_equal(&(pinfo->dst), conversation_key_addr1(conversation->key_ptr)) && addresses_equal(&(pinfo->src), conversation_key_addr2(conversation->key_ptr))) {
+ inputFlag = TRUE;
+ outputFlag = FALSE;
+ }
+ }
+ }
+
+ /* input conversation is found */
+ if (inputFlag)
+ {
+ proto_tree_add_string_format_value(tree, hf_pn_rt_frame_info_type, tvb,
+ offset, 0, "Input", "Input Frame (IO_Device -> IO_Controller)");
+ }
+ /* output conversation is found. */
+ else if (outputFlag)
+ {
+ proto_tree_add_string_format_value(tree, hf_pn_rt_frame_info_type, tvb,
+ offset, 0, "Output", "Output Frame (IO_Controller -> IO_Device)");
+ }
+
+ sub_item = proto_tree_add_uint_format(tree, hf_pn_rt_data_status,
+ tvb, offset, 1, u8DataStatus,
+ "DataStatus: 0x%02x (Frame: %s and %s, Provider: %s and %s)",
+ u8DataStatus,
+ (u8DataStatus & 0x04) ? "Valid" : "Invalid",
+ (u8DataStatus & 0x01) ? "Primary" : "Backup",
+ (u8DataStatus & 0x20) ? "Ok" : "Problem",
+ (u8DataStatus & 0x10) ? "Run" : "Stop");
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_rt_data_status);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_ignore, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_Reserved_2, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_ok, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_operate, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_res3, tvb, offset, 1, u8DataStatus);
+ /* input conversation is found */
+ if (inputFlag)
+ {
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_valid, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(tree, hf_pn_rt_frame_info_function_meaning_input_conv, tvb, offset, 1, u8DataStatus);
+ if (u8State == 0 && u8Redundancy == 0 && u8DataValid == 1)
+ {
+ proto_tree_add_boolean(sub_tree, hf_pn_rt_data_status_redundancy_input_cr_state_is_backup, tvb, offset, 1, u8DataStatus);
+ }
+ else if (u8State == 0 && u8Redundancy == 0 && u8DataValid == 0)
+ {
+ proto_tree_add_boolean(sub_tree, hf_pn_rt_data_status_redundancy_input_cr_state_is_backup, tvb, offset, 1, u8DataStatus);
+ }
+ else if (u8State == 0 && u8Redundancy == 1 && u8DataValid == 1)
+ {
+ proto_tree_add_boolean(sub_tree, hf_pn_rt_data_status_redundancy_input_cr_state_is_backup, tvb, offset, 1, u8DataStatus);
+ }
+ else if (u8State == 0 && u8Redundancy == 1 && u8DataValid == 0)
+ {
+ proto_tree_add_boolean(sub_tree, hf_pn_rt_data_status_redundancy_input_cr_state_is_backup, tvb, offset, 1, u8DataStatus);
+ }
+ else if (u8State == 1 && u8Redundancy == 0 && u8DataValid == 1)
+ {
+ proto_tree_add_boolean(sub_tree, hf_pn_rt_data_status_redundancy_input_cr_state_is_primary, tvb, offset, 1, u8DataStatus);
+ }
+ else if (u8State == 1 && u8Redundancy == 1 && u8DataValid == 1)
+ {
+ proto_tree_add_boolean(sub_tree, hf_pn_rt_data_status_redundancy_input_cr_state_is_primary, tvb, offset, 1, u8DataStatus);
+ }
+
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_primary, tvb, offset, 1, u8DataStatus);
+ return;
+ }
+ // output conversation is found.
+ else if (outputFlag)
+ {
+ proto_tree_add_uint(tree, hf_pn_rt_frame_info_function_meaning_output_conv, tvb, offset, 1, u8DataStatus);
+
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_valid, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_boolean(sub_tree, hf_pn_rt_data_status_redundancy_output_cr, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_primary, tvb, offset, 1, u8DataStatus);
+
+ return;
+ }
+
+ // If no conversation is found
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_valid, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_boolean(sub_tree, hf_pn_rt_data_status_redundancy, tvb, offset, 1, u8DataStatus);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_primary, tvb, offset, 1, u8DataStatus);
+}
+
+
+static gboolean
+IsDFP_Frame(tvbuff_t *tvb, packet_info *pinfo, guint16 u16FrameID)
+{
+ guint16 u16SFCRC16;
+ guint8 u8SFPosition;
+ guint8 u8SFDataLength = 255;
+ int offset = 0;
+ guint32 u32SubStart;
+ guint16 crc;
+ gint tvb_len = 0;
+ unsigned char virtualFramebuffer[16];
+
+ /* try to build a temporaray buffer for generating this CRC */
+ if (!pinfo->src.data || !pinfo->dst.data ||
+ pinfo->dst.type != AT_ETHER || pinfo->src.type != AT_ETHER) {
+ /* if we don't have src/dst mac addresses then we assume it's not
+ * to avoid various crashes */
+ return FALSE;
+ }
+ memcpy(&virtualFramebuffer[0], pinfo->dst.data, 6);
+ memcpy(&virtualFramebuffer[6], pinfo->src.data, 6);
+ virtualFramebuffer[12] = 0x88;
+ virtualFramebuffer[13] = 0x92;
+ virtualFramebuffer[15] = (unsigned char) (u16FrameID &0xff);
+ virtualFramebuffer[14] = (unsigned char) (u16FrameID>>8);
+ crc = crc16_plain_init();
+ crc = crc16_plain_update(crc, &virtualFramebuffer[0], 16);
+ crc = crc16_plain_finalize(crc);
+ /* can check this CRC only by having built a temporary data buffer out of the pinfo data */
+ u16SFCRC16 = tvb_get_letohs(tvb, offset);
+ if (u16SFCRC16 != 0) /* no crc! */
+ {
+ if (u16SFCRC16 != crc)
+ {
+ return(FALSE);
+ }
+ }
+ /* end of first CRC check */
+
+ offset += 2; /*Skip first crc */
+ tvb_len = tvb_captured_length(tvb);
+ if (offset + 4 > tvb_len)
+ return FALSE;
+ if (tvb_get_letohs(tvb, offset) == 0)
+ return FALSE; /* no valid DFP frame */
+ while (1) {
+ u32SubStart = offset;
+
+ u8SFPosition = tvb_get_guint8(tvb, offset);
+ offset += 1;
+
+ u8SFDataLength = tvb_get_guint8(tvb, offset);
+ offset += 1;
+
+ if (u8SFDataLength == 0) {
+ break;
+ }
+
+ offset += 2;
+
+ offset += u8SFDataLength;
+ if (offset > tvb_len)
+ return /*TRUE; */FALSE;
+
+ u16SFCRC16 = tvb_get_letohs(tvb, offset);
+ if (u16SFCRC16 != 0) {
+ if (u8SFPosition & 0x80) {
+ crc = crc16_plain_tvb_offset_seed(tvb, u32SubStart, offset-u32SubStart, 0);
+ if (crc != u16SFCRC16) {
+ return FALSE;
+ } else {
+ }
+ } else {
+ }
+ }
+ offset += 2;
+ }
+ return TRUE;
+}
+
+/* possibly dissect a CSF_SDU related PN-RT packet */
+gboolean
+dissect_CSF_SDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ /* the sub tvb will NOT contain the frame_id here! */
+ guint16 u16FrameID = GPOINTER_TO_UINT(data);
+ guint16 u16SFCRC16;
+ guint8 u8SFPosition;
+ guint8 u8SFDataLength = 255;
+ guint8 u8SFCycleCounter;
+ guint8 u8SFDataStatus;
+ gint offset = 0;
+ guint32 u32SubStart;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 crc;
+
+
+ /* possible FrameID ranges for DFP */
+ if ((u16FrameID < 0x0100) || (u16FrameID > 0x3FFF))
+ return (FALSE);
+ if (IsDFP_Frame(tvb, pinfo, u16FrameID)) {
+ /* can't check this CRC, as the checked data bytes are not available */
+ u16SFCRC16 = tvb_get_letohs(tvb, offset);
+ if (u16SFCRC16 != 0) {
+ /* Checksum verify will always succeed */
+ /* XXX - should we combine the two calls to always show "unverified"? */
+ proto_tree_add_checksum(tree, tvb, offset, hf_pn_rt_sf_crc16, hf_pn_rt_sf_crc16_status, &ei_pn_rt_sf_crc16, pinfo, u16SFCRC16,
+ ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
+ }
+ else {
+ proto_tree_add_checksum(tree, tvb, offset, hf_pn_rt_sf_crc16, hf_pn_rt_sf_crc16_status, &ei_pn_rt_sf_crc16, pinfo, 0,
+ ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
+ }
+ offset += 2;
+
+ while (1) {
+ sub_item = proto_tree_add_item(tree, hf_pn_rt_sf, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_rt_sf);
+ u32SubStart = offset;
+
+ u8SFPosition = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_sf_position, tvb, offset, 1, u8SFPosition);
+ offset += 1;
+
+ u8SFDataLength = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_sf_data_length, tvb, offset, 1, u8SFDataLength);
+ offset += 1;
+
+ if (u8SFDataLength == 0) {
+ proto_item_append_text(sub_item, ": Pos:%u, Length:%u", u8SFPosition, u8SFDataLength);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+ break;
+ }
+
+ u8SFCycleCounter = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_sf_cycle_counter, tvb, offset, 1, u8SFCycleCounter);
+ offset += 1;
+
+ u8SFDataStatus = tvb_get_guint8(tvb, offset);
+ dissect_DataStatus(tvb, offset, sub_tree, pinfo, u8SFDataStatus);
+ offset += 1;
+
+ offset = dissect_pn_user_data(tvb, offset, pinfo, sub_tree, u8SFDataLength, "DataItem");
+
+ u16SFCRC16 = tvb_get_letohs(tvb, offset);
+
+ if (u16SFCRC16 != 0 /* "old check": u8SFPosition & 0x80 */) {
+ crc = crc16_plain_tvb_offset_seed(tvb, u32SubStart, offset-u32SubStart, 0);
+ proto_tree_add_checksum(tree, tvb, offset, hf_pn_rt_sf_crc16, hf_pn_rt_sf_crc16_status, &ei_pn_rt_sf_crc16, pinfo, crc,
+ ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
+ } else {
+ proto_tree_add_checksum(tree, tvb, offset, hf_pn_rt_sf_crc16, hf_pn_rt_sf_crc16_status, &ei_pn_rt_sf_crc16, pinfo, 0,
+ ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
+ }
+ offset += 2;
+
+ proto_item_append_text(sub_item, ": Pos:%u, Length:%u, Cycle:%u, Status: 0x%02x (%s,%s,%s,%s)",
+ u8SFPosition, u8SFDataLength, u8SFCycleCounter, u8SFDataStatus,
+ (u8SFDataStatus & 0x04) ? "Valid" : "Invalid",
+ (u8SFDataStatus & 0x01) ? "Primary" : "Backup",
+ (u8SFDataStatus & 0x20) ? "Ok" : "Problem",
+ (u8SFDataStatus & 0x10) ? "Run" : "Stop");
+
+ proto_item_set_len(sub_item, offset - u32SubStart);
+ }
+
+ return TRUE;
+ }
+
+ else {
+ dissect_pn_user_data(tvb, offset, pinfo, tree, tvb_captured_length_remaining(tvb, offset),
+ "PROFINET IO Cyclic Service Data Unit");
+ }
+
+ return FALSE;
+
+}
+
+/* for reasemble processing we need some inits.. */
+/* Register PNIO defrag table init routine. */
+
+static reassembly_table pdu_reassembly_table;
+static GHashTable *reasembled_frag_table = NULL;
+
+static dissector_table_t ethertype_subdissector_table;
+
+static guint32 start_frag_OR_ID[16];
+
+
+static void
+pnio_defragment_init(void)
+{
+ guint32 i;
+ for (i=0; i < 16; i++) /* init the reasemble help array */
+ start_frag_OR_ID[i] = 0;
+ reasembled_frag_table = g_hash_table_new(NULL, NULL);
+}
+
+static void
+pnio_defragment_cleanup(void)
+{
+ g_hash_table_destroy(reasembled_frag_table);
+}
+
+/* possibly dissect a FRAG_PDU related PN-RT packet */
+static gboolean
+dissect_FRAG_PDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ /* the sub tvb will NOT contain the frame_id here! */
+ guint16 u16FrameID = GPOINTER_TO_UINT(data);
+ int offset = 0;
+
+
+ /* possible FrameID ranges for FRAG_PDU */
+ if (u16FrameID >= 0xFF80 && u16FrameID <= 0xFF8F) {
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ proto_item *status_item;
+ proto_tree *status_tree;
+ guint8 u8FragDataLength;
+ guint8 u8FragStatus;
+ gboolean bMoreFollows;
+ guint8 uFragNumber;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_rt_frag, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_rt_frag);
+
+ u8FragDataLength = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(sub_tree, hf_pn_rt_frag_data_length, tvb, offset, 1, u8FragDataLength);
+ offset += 1;
+
+ status_item = proto_tree_add_item(sub_tree, hf_pn_rt_frag_status, tvb, offset, 1, ENC_NA);
+ status_tree = proto_item_add_subtree(status_item, ett_pn_rt_frag_status);
+
+ u8FragStatus = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(status_tree, hf_pn_rt_frag_status_more_follows, tvb, offset, 1, u8FragStatus);
+ proto_tree_add_uint(status_tree, hf_pn_rt_frag_status_error, tvb, offset, 1, u8FragStatus);
+ proto_tree_add_uint(status_tree, hf_pn_rt_frag_status_fragment_number, tvb, offset, 1, u8FragStatus);
+ offset += 1;
+ uFragNumber = u8FragStatus & 0x3F; /* bits 0 to 5 */
+ bMoreFollows = (u8FragStatus & 0x80) != 0;
+ proto_item_append_text(status_item, ": Number: %u, %s",
+ uFragNumber,
+ val_to_str_const( (u8FragStatus & 0x80) >> 7, pn_rt_frag_status_more_follows, "Unknown"));
+
+ /* Is this a string or a bunch of bytes? Should it be FT_BYTES? */
+ proto_tree_add_string_format(sub_tree, hf_pn_rt_frag_data, tvb, offset, tvb_captured_length_remaining(tvb, offset), "data",
+ "Fragment Length: %d bytes", tvb_captured_length_remaining(tvb, offset));
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Fragment Length: %d bytes", tvb_captured_length_remaining(tvb, offset));
+
+ dissect_pn_user_data_bytes(tvb, offset, pinfo, sub_tree, tvb_captured_length_remaining(tvb, offset), FRAG_DATA);
+ if ((guint)tvb_captured_length_remaining(tvb, offset) < (guint)(u8FragDataLength *8)) {
+ proto_item_append_text(status_item, ": FragDataLength out of Framerange -> discarding!");
+ return (TRUE);
+ }
+ /* defragmentation starts here */
+ if (pnio_desegment)
+ {
+ guint32 u32FragID;
+ guint32 u32ReasembleID /*= 0xfedc ??*/;
+ fragment_head *pdu_frag;
+
+ u32FragID = (u16FrameID & 0xf);
+ if (uFragNumber == 0)
+ { /* this is the first "new" fragment, so set up a new key Id */
+ guint32 u32FrameKey;
+ u32FrameKey = (pinfo->num << 2) | u32FragID;
+ /* store it in the array */
+ start_frag_OR_ID[u32FragID] = u32FrameKey;
+ }
+ u32ReasembleID = start_frag_OR_ID[u32FragID];
+ /* use frame data instead of "pnio fraglen" which sets 8 octet steps */
+ pdu_frag = fragment_add_seq(&pdu_reassembly_table, tvb, offset,
+ pinfo, u32ReasembleID, NULL, uFragNumber,
+ (tvb_captured_length_remaining(tvb, offset))/*u8FragDataLength*8*/, bMoreFollows, 0);
+
+ if (pdu_frag && !bMoreFollows) /* PDU is complete! and last fragment */
+ { /* store this fragment as the completed fragment in hash table */
+ g_hash_table_insert(reasembled_frag_table, GUINT_TO_POINTER(pinfo->num), pdu_frag);
+ start_frag_OR_ID[u32FragID] = 0; /* reset the starting frame counter */
+ }
+ if (!bMoreFollows) /* last fragment */
+ {
+ pdu_frag = (fragment_head *)g_hash_table_lookup(reasembled_frag_table, GUINT_TO_POINTER(pinfo->num));
+ if (pdu_frag) /* found a matching fragment; dissect it */
+ {
+ guint16 type;
+ tvbuff_t *pdu_tvb;
+
+ /* create the new tvb for defragmented frame */
+ pdu_tvb = tvb_new_chain(tvb, pdu_frag->tvb_data);
+ /* add the defragmented data to the data source list */
+ add_new_data_source(pinfo, pdu_tvb, "Reassembled Profinet Frame");
+ /* PDU is complete: look for the Ethertype and give it to the appropriate dissection routine */
+ type = tvb_get_ntohs(pdu_tvb, 0);
+ pdu_tvb = tvb_new_subset_remaining(pdu_tvb, 2);
+ if (!dissector_try_uint(ethertype_subdissector_table, type, pdu_tvb, pinfo, tree))
+ call_data_dissector(pdu_tvb, pinfo, tree);
+ }
+ }
+ return TRUE;
+ }
+ else
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ * dissect_pn_rt - The dissector for the Soft-Real-Time protocol
+ */
+static int
+dissect_pn_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ gint pdu_len;
+ gint data_len;
+ guint16 u16FrameID;
+ guint8 u8DataStatus;
+ guint8 u8TransferStatus;
+ guint16 u16CycleCounter;
+ const gchar *pszProtAddInfo;
+ const gchar *pszProtShort;
+ const gchar *pszProtSummary;
+ const gchar *pszProtComment;
+ proto_tree *pn_rt_tree, *ti;
+ gchar szFieldSummary[100];
+ tvbuff_t *next_tvb;
+ gboolean bCyclic;
+ heur_dtbl_entry_t *hdtbl_entry;
+ conversation_t* conversation;
+ guint8 isTimeAware = FALSE;
+
+ /* If the link-layer dissector for the protocol above us knows whether
+ * the packet, as handed to it, includes a link-layer FCS, what it
+ * hands to us should not include the FCS; if that's not the case,
+ * that's a bug in that dissector, and should be fixed there.
+ *
+ * If the link-layer dissector for the protocol above us doesn't know
+ * whether the packet, as handed to us, includes a link-layer FCS,
+ * there are limits as to what can be done there; the dissector
+ * ultimately needs a "yes, it has an FCS" preference setting, which
+ * both the Ethernet and 802.11 dissectors do. If that's not the case
+ * for a dissector, that's a deficiency in that dissector, and should
+ * be fixed there.
+ *
+ * Therefore, we assume we are not handed a packet that includes an
+ * FCS. If we are ever handed such a packet, either the link-layer
+ * dissector needs to be fixed or the link-layer dissector's preference
+ * needs to be set for your capture (even if that means adding such
+ * a preference). This dissector (and other dissectors for protcols
+ * running atop the link layer) should not attempt to process the
+ * FCS themselves, as that will just break things. */
+
+ /* Initialize variables */
+ pn_rt_tree = NULL;
+ ti = NULL;
+
+ /*
+ * Set the columns now, so that they'll be set correctly if we throw
+ * an exception. We can set them (or append things) later again ....
+ */
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-RT");
+ col_set_str(pinfo->cinfo, COL_INFO, "PROFINET Real-Time");
+
+ pdu_len = tvb_reported_length(tvb);
+ if (pdu_len < 6) {
+ dissect_pn_malformed(tvb, 0, pinfo, tree, pdu_len);
+ return 0;
+ }
+
+ /* TimeAwareness Information needed for differentiating RTC3 - RTSteam frames */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+
+ if (conversation != NULL) {
+ isTimeAware = GPOINTER_TO_UINT(conversation_get_proto_data(conversation, proto_pn_io_time_aware_status));
+ }
+
+ /* build some "raw" data */
+ u16FrameID = tvb_get_ntohs(tvb, 0);
+ if (u16FrameID <= 0x001F) {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "reserved, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x0000-0x001F: Reserved ID";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0x0021) {
+ pszProtShort = "PN-PTCP";
+ pszProtAddInfo = "Synchronization, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x0020-0x0021: Real-Time: Sync (with follow up)";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0x007F) {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "reserved, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x0022-0x007F: Reserved ID";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0x0081) {
+ pszProtShort = "PN-PTCP";
+ pszProtAddInfo = "Synchronization, ";
+ pszProtSummary = "Isochronous-Real-Time";
+ pszProtComment = "0x0080-0x0081: Real-Time: Sync (without follow up)";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0x00FF) {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "reserved, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x0082-0x00FF: Reserved ID";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0x6FF && !isTimeAware) {
+ pszProtShort = "PN-RTC3";
+ pszProtAddInfo = "RTC3, ";
+ pszProtSummary = "Isochronous-Real-Time";
+ pszProtComment = "0x0100-0x06FF: RED: Real-Time(class=3): non redundant, normal or DFP";
+ bCyclic = TRUE;
+ } else if (u16FrameID <= 0x0FFF && !isTimeAware) {
+ pszProtShort = "PN-RTC3";
+ pszProtAddInfo = "RTC3, ";
+ pszProtSummary = "Isochronous-Real-Time";
+ pszProtComment = "0x0700-0x0FFF: RED: Real-Time(class=3): redundant, normal or DFP";
+ bCyclic = TRUE;
+ } else if (u16FrameID <= 0x7FFF && !isTimeAware) {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "reserved, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x1000-0x7FFF: Reserved ID";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0x0FFF && isTimeAware) {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "reserved, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x0100-0x0FFF: Reserved ID";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0x2FFF && isTimeAware) {
+ pszProtShort = "PN-RTCS";
+ pszProtAddInfo = "RT_STREAM, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x1000-0x2FFF: RT_CLASS_STREAM";
+ bCyclic = TRUE;
+ } else if (u16FrameID <= 0x37FF && isTimeAware) {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "reserved, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x3000-0x37FF: Reserved ID";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0x3FFF && isTimeAware) {
+ pszProtShort = "PN-RTCS";
+ pszProtAddInfo = "RT_STREAM, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0x3800-0x3FFF: RT_CLASS_STREAM";
+ bCyclic = TRUE;
+ } else if (u16FrameID <= 0xBBFF) {
+ pszProtShort = "PN-RTC1";
+ pszProtAddInfo = "RTC1, ";
+ pszProtSummary = "cyclic Real-Time";
+ pszProtComment = "0x8000-0xBBFF: Real-Time(class=1 unicast): non redundant, normal";
+ bCyclic = TRUE;
+ } else if (u16FrameID <= 0xBFFF) {
+ pszProtShort = "PN-RTC1";
+ pszProtAddInfo = "RTC1, ";
+ pszProtSummary = "cyclic Real-Time";
+ pszProtComment = "0xBC00-0xBFFF: Real-Time(class=1 multicast): non redundant, normal";
+ bCyclic = TRUE;
+ } else if (u16FrameID <= 0xF7FF) {
+ /* check if udp frame on PNIO port */
+ if (pinfo->destport == 0x8892)
+ { /* UDP frame */
+ pszProtShort = "PN-RTCUDP,";
+ pszProtAddInfo = "RT_CLASS_UDP, ";
+ pszProtComment = "0xC000-0xF7FF: Real-Time(UDP unicast): Cyclic";
+ }
+ else
+ { /* layer 2 frame */
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "RTC1(legacy), ";
+ pszProtComment = "0xC000-0xF7FF: Real-Time(class=1 unicast): Cyclic";
+ }
+ pszProtSummary = "cyclic Real-Time";
+ bCyclic = TRUE;
+ } else if (u16FrameID <= 0xFBFF) {
+ if (pinfo->destport == 0x8892)
+ { /* UDP frame */
+ pszProtShort = "PN-RTCUDP,";
+ pszProtAddInfo = "RT_CLASS_UDP, ";
+ pszProtComment = "0xF800-0xFBFF:: Real-Time(UDP multicast): Cyclic";
+ }
+ else
+ { /* layer 2 frame */
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "RTC1(legacy), ";
+ pszProtComment = "0xF800-0xFBFF: Real-Time(class=1 multicast): Cyclic";
+ }
+ pszProtSummary = "cyclic Real-Time";
+ bCyclic = TRUE;
+ } else if (u16FrameID <= 0xFDFF) {
+ pszProtShort = "PN-RTA";
+ pszProtAddInfo = "Reserved, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "0xFC00-0xFDFF: Reserved";
+ bCyclic = FALSE;
+ if (u16FrameID == 0xfc01) {
+ pszProtShort = "PN-RTA";
+ pszProtAddInfo = "Alarm High, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "Real-Time: Acyclic PN-IO Alarm high priority";
+ }
+
+ } else if (u16FrameID <= 0xFEFF) {
+ pszProtShort = "PN-RTA";
+ pszProtAddInfo = "Reserved, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "0xFE00-0xFEFF: Real-Time: Reserved";
+ bCyclic = FALSE;
+ if (u16FrameID == 0xFE01) {
+ pszProtShort = "PN-RTA";
+ pszProtAddInfo = "Alarm Low, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "Real-Time: Acyclic PN-IO Alarm low priority";
+ }
+ if (u16FrameID == 0xFE02) {
+ pszProtShort = "PN-RSI";
+ pszProtAddInfo = "";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "Real-Time: Acyclic PN-IO RSI";
+ }
+ if (u16FrameID == FRAME_ID_DCP_HELLO) {
+ pszProtShort = "PN-RTA";
+ pszProtAddInfo = "";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "Real-Time: DCP (Dynamic Configuration Protocol) hello";
+ }
+ if (u16FrameID == FRAME_ID_DCP_GETORSET) {
+ pszProtShort = "PN-RTA";
+ pszProtAddInfo = "";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "Real-Time: DCP (Dynamic Configuration Protocol) get/set";
+ }
+ if (u16FrameID == FRAME_ID_DCP_IDENT_REQ) {
+ pszProtShort = "PN-RTA";
+ pszProtAddInfo = "";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "Real-Time: DCP (Dynamic Configuration Protocol) identify multicast request";
+ }
+ if (u16FrameID == FRAME_ID_DCP_IDENT_RES) {
+ pszProtShort = "PN-RTA";
+ pszProtAddInfo = "";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "Real-Time: DCP (Dynamic Configuration Protocol) identify response";
+ }
+ } else if (u16FrameID <= 0xFF01) {
+ pszProtShort = "PN-PTCP";
+ pszProtAddInfo = "RTA Sync, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "0xFF00-0xFF01: PTCP Announce";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0xFF1F) {
+ pszProtShort = "PN-PTCP";
+ pszProtAddInfo = "RTA Sync, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "0xFF02-0xFF1F: Reserved";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0xFF21) {
+ pszProtShort = "PN-PTCP";
+ pszProtAddInfo = "Follow Up, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "0xFF20-0xFF21: PTCP Follow Up";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0xFF22) {
+ pszProtShort = "PN-PTCP";
+ pszProtAddInfo = "Follow Up, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "0xFF22-0xFF3F: Reserved";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0xFF43) {
+ pszProtShort = "PN-PTCP";
+ pszProtAddInfo = "Delay, ";
+ pszProtSummary = "acyclic Real-Time";
+ pszProtComment = "0xFF40-0xFF43: Acyclic Real-Time: Delay";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0xFF7F) {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "Reserved, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0xFF44-0xFF7F: reserved ID";
+ bCyclic = FALSE;
+ } else if (u16FrameID <= 0xFF8F) {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "";
+ pszProtSummary = "Fragmentation";
+ pszProtComment = "0xFF80-0xFF8F: Fragmentation";
+ bCyclic = FALSE;
+ } else {
+ pszProtShort = "PN-RT";
+ pszProtAddInfo = "Reserved, ";
+ pszProtSummary = "Real-Time";
+ pszProtComment = "0xFF90-0xFFFF: reserved ID";
+ bCyclic = FALSE;
+ }
+
+ /* decode optional cyclic fields at the packet end and build the summary line */
+ if (bCyclic) {
+ /* cyclic transfer has cycle counter, data status and transfer status fields at the end */
+ u16CycleCounter = tvb_get_ntohs(tvb, pdu_len - 4);
+ u8DataStatus = tvb_get_guint8(tvb, pdu_len - 2);
+ u8TransferStatus = tvb_get_guint8(tvb, pdu_len - 1);
+
+ snprintf (szFieldSummary, sizeof(szFieldSummary),
+ "%sID:0x%04x, Len:%4u, Cycle:%5u (%s,%s,%s,%s)",
+ pszProtAddInfo, u16FrameID, pdu_len - 2 - 4, u16CycleCounter,
+ (u8DataStatus & 0x04) ? "Valid" : "Invalid",
+ (u8DataStatus & 0x01) ? "Primary" : "Backup",
+ (u8DataStatus & 0x20) ? "Ok" : "Problem",
+ (u8DataStatus & 0x10) ? "Run" : "Stop");
+
+ /* user data length is packet len - frame id - optional cyclic status fields */
+ data_len = pdu_len - 2 - 4;
+ } else {
+ /* satisfy the gcc compiler, so it won't throw an "uninitialized" warning */
+ u16CycleCounter = 0;
+ u8DataStatus = 0;
+ u8TransferStatus = 0;
+
+ /* acyclic transfer has no fields at the end */
+ snprintf (szFieldSummary, sizeof(szFieldSummary),
+ "%sID:0x%04x, Len:%4u",
+ pszProtAddInfo, u16FrameID, pdu_len - 2);
+
+ /* user data length is packet len - frame id field */
+ data_len = pdu_len - 2;
+ }
+
+ /* build protocol tree only, if tree is really used */
+ if (tree) {
+ /* build pn_rt protocol tree with summary line */
+ if (pn_rt_summary_in_tree) {
+ ti = proto_tree_add_protocol_format(tree, proto_pn_rt, tvb, 0, pdu_len,
+ "PROFINET %s, %s", pszProtSummary, szFieldSummary);
+ } else {
+ ti = proto_tree_add_item(tree, proto_pn_rt, tvb, 0, pdu_len, ENC_NA);
+ }
+ pn_rt_tree = proto_item_add_subtree(ti, ett_pn_rt);
+
+ /* add frame ID */
+ proto_tree_add_uint_format(pn_rt_tree, hf_pn_rt_frame_id, tvb,
+ 0, 2, u16FrameID, "FrameID: 0x%04x (%s)", u16FrameID, pszProtComment);
+
+ if (bCyclic) {
+ /* add cycle counter */
+ proto_tree_add_uint_format(pn_rt_tree, hf_pn_rt_cycle_counter, tvb,
+ pdu_len - 4, 2, u16CycleCounter, "CycleCounter: %u", u16CycleCounter);
+
+ /* add data status subtree */
+ dissect_DataStatus(tvb, pdu_len - 2, pn_rt_tree, pinfo, u8DataStatus);
+
+ /* add transfer status */
+ if (u8TransferStatus) {
+ proto_tree_add_uint_format(pn_rt_tree, hf_pn_rt_transfer_status, tvb,
+ pdu_len - 1, 1, u8TransferStatus,
+ "TransferStatus: 0x%02x (ignore this frame)", u8TransferStatus);
+ } else {
+ proto_tree_add_uint_format(pn_rt_tree, hf_pn_rt_transfer_status, tvb,
+ pdu_len - 1, 1, u8TransferStatus,
+ "TransferStatus: 0x%02x (OK)", u8TransferStatus);
+ }
+ }
+ }
+
+ /* update column info now */
+ if (u16FrameID == 0xFE02)
+ {
+ snprintf(szFieldSummary, sizeof(szFieldSummary), "%s", "");
+ }
+ col_add_str(pinfo->cinfo, COL_INFO, szFieldSummary);
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, pszProtShort);
+
+ /* get frame user data tvb (without header and footer) */
+ next_tvb = tvb_new_subset_length(tvb, 2, data_len);
+
+ /* ask heuristics, if some sub-dissector is interested in this packet payload */
+ if (!dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, GUINT_TO_POINTER( (guint32) u16FrameID))) {
+ /*col_set_str(pinfo->cinfo, COL_INFO, "Unknown");*/
+
+ /* Oh, well, we don't know this; dissect it as data. */
+ dissect_pn_undecoded(next_tvb, 0, pinfo, tree, tvb_captured_length(next_tvb));
+ }
+ return tvb_captured_length(tvb);
+}
+
+
+/* Register all the bits needed by the filtering engine */
+void
+proto_register_pn_rt(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_rt_frame_id,
+ { "FrameID", "pn_rt.frame_id",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_cycle_counter,
+ { "CycleCounter", "pn_rt.cycle_counter",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status,
+ { "DataStatus", "pn_rt.ds",
+ FT_UINT8, BASE_HEX, 0, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_ignore,
+ { "Ignore (1:Ignore/0:Evaluate)", "pn_rt.ds_ignore", FT_UINT8, BASE_HEX, 0, 0x80,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_frame_info_type,
+ { "PN Frame Type", "pn_rt.ds_frame_info_type", FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_frame_info_function_meaning_input_conv,
+ { "Function/Meaning", "pn_rt.ds_frame_info_meaning",
+ FT_UINT8, BASE_HEX, VALS(pn_rt_frame_info_function_meaning_input_conv), 0x7,
+ NULL, HFILL } },
+
+ { &hf_pn_rt_frame_info_function_meaning_output_conv,
+ { "Function/Meaning", "pn_rt.ds_frame_info_meaning",
+ FT_UINT8, BASE_HEX, VALS(pn_rt_frame_info_function_meaning_output_conv), 0x7,
+ NULL, HFILL } },
+
+ { &hf_pn_rt_data_status_Reserved_2,
+ { "Reserved_2 (should be zero)", "pn_rt.ds_Reserved_2",
+ FT_UINT8, BASE_HEX, 0, 0x40,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_ok,
+ { "StationProblemIndicator (1:Ok/0:Problem)", "pn_rt.ds_ok",
+ FT_UINT8, BASE_HEX, 0, 0x20,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_operate,
+ { "ProviderState (1:Run/0:Stop)", "pn_rt.ds_operate",
+ FT_UINT8, BASE_HEX, 0, 0x10,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_res3,
+ { "Reserved_3 (should be zero)", "pn_rt.ds_res3",
+ FT_UINT8, BASE_HEX, 0, 0x08,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_valid,
+ { "DataValid (1:Valid/0:Invalid)", "pn_rt.ds_valid",
+ FT_UINT8, BASE_HEX, 0, 0x04,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_redundancy,
+ { "Redundancy", "pn_rt.ds_redundancy",
+ FT_BOOLEAN, 8, TFS(&tfs_pn_rt_ds_redundancy), 0x02,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_redundancy_output_cr,
+ { "Redundancy", "pn_rt.ds_redundancy",
+ FT_BOOLEAN, 8, TFS(&tfs_pn_rt_ds_redundancy_output_cr), 0x02,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_redundancy_input_cr_state_is_backup,
+ { "Redundancy", "pn_rt.ds_redundancy",
+ FT_BOOLEAN, 8, TFS(&tfs_pn_rt_ds_redundancy_input_cr_state_is_backup), 0x02,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_redundancy_input_cr_state_is_primary,
+ { "Redundancy", "pn_rt.ds_redundancy",
+ FT_BOOLEAN, 8, TFS(&tfs_pn_rt_ds_redundancy_input_cr_state_is_primary), 0x02,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_data_status_primary,
+ { "State (1:Primary/0:Backup)", "pn_rt.ds_primary",
+ FT_UINT8, BASE_HEX, 0, 0x01,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_transfer_status,
+ { "TransferStatus", "pn_rt.transfer_status",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_sf,
+ { "SubFrame", "pn_rt.sf",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_sf_crc16,
+ { "SFCRC16", "pn_rt.sf.crc16",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_sf_crc16_status,
+ { "SFCRC16 status", "pn_rt.sf.crc16.status",
+ FT_UINT8, BASE_NONE, VALS(plugin_proto_checksum_vals), 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_sf_position,
+ { "Position", "pn_rt.sf.position",
+ FT_UINT8, BASE_DEC, NULL, 0x7F,
+ NULL, HFILL }},
+
+#if 0
+ { &hf_pn_rt_sf_position_control,
+ { "Control", "pn_rt.sf.position_control",
+ FT_UINT8, BASE_DEC, VALS(pn_rt_position_control), 0x80,
+ NULL, HFILL }},
+#endif
+
+ { &hf_pn_rt_sf_data_length,
+ { "DataLength", "pn_rt.sf.data_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_sf_cycle_counter,
+ { "CycleCounter", "pn_rt.sf.cycle_counter",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_frag,
+ { "PROFINET Fragment", "pn_rt.frag",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_frag_data_length,
+ { "FragDataLength", "pn_rt.frag_data_length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_frag_status,
+ { "FragStatus", "pn_rt.frag_status",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_frag_status_more_follows,
+ { "MoreFollows", "pn_rt.frag_status.more_follows",
+ FT_UINT8, BASE_HEX, VALS(pn_rt_frag_status_more_follows), 0x80,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_frag_status_error,
+ { "Reserved", "pn_rt.frag_status.error",
+ FT_UINT8, BASE_HEX, VALS(pn_rt_frag_status_error), 0x40,
+ NULL, HFILL }},
+
+ { &hf_pn_rt_frag_status_fragment_number,
+ { "FragmentNumber (zero based)", "pn_rt.frag_status.fragment_number",
+ FT_UINT8, BASE_DEC, NULL, 0x3F,
+ NULL, HFILL }},
+
+ /* Is this a string or a bunch of bytes? Should it be FT_BYTES? */
+ { &hf_pn_rt_frag_data,
+ { "FragData", "pn_rt.frag_data",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ };
+ static gint *ett[] = {
+ &ett_pn_rt,
+ &ett_pn_rt_data_status,
+ &ett_pn_rt_sf,
+ &ett_pn_rt_frag,
+ &ett_pn_rt_frag_status
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_pn_rt_sf_crc16, { "pn_rt.sf.crc16_bad", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
+ };
+
+ module_t *pn_rt_module;
+ expert_module_t* expert_pn_rt;
+
+ proto_pn_rt = proto_register_protocol("PROFINET Real-Time Protocol",
+ "PN-RT", "pn_rt");
+ pn_rt_handle = register_dissector("pn_rt", dissect_pn_rt, proto_pn_rt);
+
+ proto_register_field_array(proto_pn_rt, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ expert_pn_rt = expert_register_protocol(proto_pn_rt);
+ expert_register_field_array(expert_pn_rt, ei, array_length(ei));
+
+ /* Register our configuration options */
+
+ pn_rt_module = prefs_register_protocol(proto_pn_rt, NULL);
+
+ prefs_register_bool_preference(pn_rt_module, "summary_in_tree",
+ "Show PN-RT summary in protocol tree",
+ "Whether the PN-RT summary line should be shown in the protocol tree",
+ &pn_rt_summary_in_tree);
+
+ prefs_register_bool_preference(pn_rt_module, "desegment",
+ "reassemble PNIO Fragments",
+ "Reassemble PNIO Fragments and get them decoded",
+ &pnio_desegment);
+
+ /* register heuristics anchor for payload dissectors */
+ heur_subdissector_list = register_heur_dissector_list("pn_rt", proto_pn_rt);
+
+ init_pn (proto_pn_rt);
+ register_init_routine(pnio_defragment_init);
+ register_cleanup_routine(pnio_defragment_cleanup);
+ reassembly_table_register(&pdu_reassembly_table,
+ &addresses_reassembly_table_functions);
+}
+
+
+/* The registration hand-off routine is called at startup */
+void
+proto_reg_handoff_pn_rt(void)
+{
+ dissector_add_uint("ethertype", ETHERTYPE_PROFINET, pn_rt_handle);
+ dissector_add_uint_with_preference("udp.port", PROFINET_UDP_PORT, pn_rt_handle);
+
+ heur_dissector_add("pn_rt", dissect_CSF_SDU_heur, "PROFINET CSF_SDU IO", "pn_csf_sdu_pn_rt", proto_pn_rt, HEURISTIC_ENABLE);
+ heur_dissector_add("pn_rt", dissect_FRAG_PDU_heur, "PROFINET Frag PDU IO", "pn_frag_pn_rt", proto_pn_rt, HEURISTIC_ENABLE);
+
+ ethertype_subdissector_table = find_dissector_table("ethertype");
+}
+
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-pn-rtc-one.c b/plugins/epan/profinet/packet-pn-rtc-one.c
new file mode 100644
index 0000000..383909a
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn-rtc-one.c
@@ -0,0 +1,1356 @@
+/* packet-pn-rtc-one.c
+ * Routines for PROFINET IO - RTC1 dissection.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * The PN-IO protocol is a field bus protocol related to decentralized
+ * periphery and is developed by the PROFIBUS Nutzerorganisation e.V. (PNO),
+ * see: www.profibus.com
+ *
+ *
+ * PN-IO is based on the common DCE-RPC and the "lightweight" PN-RT
+ * (ethernet type 0x8892) protocols.
+ *
+ * The context manager (CM) part is handling context information
+ * (like establishing, ...) and is using DCE-RPC as its underlying
+ * protocol.
+ *
+ * The actual cyclic data transfer and acyclic notification uses the
+ * "lightweight" PN-RT protocol.
+ *
+ * There are some other related PROFINET protocols (e.g. PN-DCP, which is
+ * handling addressing topics).
+ *
+ * Please note: the PROFINET CBA protocol is independent of the PN-IO protocol!
+ */
+
+/*
+ * Cyclic PNIO RTC1 Data Dissection:
+ *
+ * To dissect cyclic PNIO RTC1 frames, this plug-in has to collect important module
+ * information out of "Ident OK", "Connect Request" and "Write Response"
+ * frames first.
+ *
+ * The data of Stationname-, -type and -id will be gained out of
+ * packet-pn-dcp.c. The header packet-pn.h will transfer those data between
+ * those two files.
+ *
+ * This file is used as a "addon" for packet-dcerpc-pn-io.c. Within "packet-dcerpc-pn-io.c"
+ * the defined structures in "packet-pn.h" will be filled with all necessary information.
+ * Those informations will be used in thise file to dissect cyclic PNIO RTC1 and PROFIsafe
+ * frames. Furthermore since RTC1 is a special frame type of PNIO, this dissection uses the
+ * already defined protocol PNIO.
+ *
+ * Overview for cyclic PNIO RTC1 data dissection functions:
+ * -> dissect_PNIO_C_SDU_RTC1 (general dissection of RTC1)
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/dissectors/packet-dcerpc.h>
+#include <epan/proto.h>
+#include <epan/expert.h>
+
+#include "packet-pn.h"
+
+
+#define F_MESSAGE_TRAILER_4BYTE 4 /* PROFIsafe: Defines the Amount of Bytes for CRC and Status-/Controlbyte in PROFIsafe 2.4 */
+#define F_MESSAGE_TRAILER_5BYTE 5 /* PROFIsafe: Defines the Amount of Bytes for CRC and Status-/Controlbyte in PROFIsafe 2.6 */
+#define PN_INPUT_CR 1 /* PROFINET Input Connect Request value */
+#define PN_INPUT_DATADESCRITPION 1 /* PROFINET Input Data Description value */
+
+#define PA_PROFILE_API 0x9700u
+
+static int proto_pn_io_rtc1 = -1;
+
+/* General module information */
+static int hf_pn_io_frame_info_type = -1;
+static int hf_pn_io_frame_info_vendor = -1;
+static int hf_pn_io_frame_info_nameofstation = -1;
+static int hf_pn_io_frame_info_gsd_found = -1;
+static int hf_pn_io_frame_info_gsd_error = -1;
+static int hf_pn_io_frame_info_gsd_path = -1;
+static int hf_pn_io_io_data_object = -1;
+static int hf_pn_io_io_data_object_info_module_diff = -1;
+static int hf_pn_io_io_data_object_info_moduleidentnumber = -1;
+static int hf_pn_io_io_data_object_info_submoduleidentnumber = -1;
+
+static int hf_pn_io_iocs = -1;
+static int hf_pn_io_iops = -1;
+static int hf_pn_io_ioxs_extension = -1;
+static int hf_pn_io_ioxs_res14 = -1;
+static int hf_pn_io_ioxs_instance = -1;
+static int hf_pn_io_ioxs_datastate = -1;
+
+/* PROFIsafe statusbyte and controlbyte */
+static int hf_pn_io_ps_sb = -1;
+static int hf_pn_io_ps_sb_iparOK = -1;
+static int hf_pn_io_ps_sb_DeviceFault = -1;
+static int hf_pn_io_ps_sb_CECRC = -1;
+static int hf_pn_io_ps_sb_WDtimeout = -1;
+static int hf_pn_io_ps_sb_FVactivated = -1;
+static int hf_pn_io_ps_sb_Toggle_d = -1;
+static int hf_pn_io_ps_sb_ConsNr_reset = -1;
+static int hf_pn_io_ps_sb_res = -1;
+static int hf_pn_io_ps_sb_toggelBitChanged = -1;
+static int hf_pn_io_ps_sb_toggelBitChange_slot_nr = -1;
+static int hf_pn_io_ps_sb_toggelBitChange_subslot_nr = -1;
+
+static int hf_pn_io_ps_cb = -1;
+static int hf_pn_io_ps_cb_iparEN = -1;
+static int hf_pn_io_ps_cb_OAReq = -1;
+static int hf_pn_io_ps_cb_resetConsNr = -1;
+static int hf_pn_io_ps_cb_useTO2 = -1;
+static int hf_pn_io_ps_cb_activateFV = -1;
+static int hf_pn_io_ps_cb_Toggle_h = -1;
+static int hf_pn_io_ps_cb_Chf_ACK = -1;
+static int hf_pn_io_ps_cb_loopcheck = -1;
+static int hf_pn_io_ps_cb_toggelBitChanged = -1;
+static int hf_pn_io_ps_cb_toggelBitChange_slot_nr = -1;
+static int hf_pn_io_ps_cb_toggelBitChange_subslot_nr = -1;
+
+/* PROFIsafe */
+static int hf_pn_io_ps_f_dest_adr = -1;
+static int hf_pn_io_ps_f_data = -1;
+
+/* PA Profile 4.02 */
+static int hf_pn_pa_profile_status = -1;
+static int hf_pn_pa_profile_status_quality = -1;
+static int hf_pn_pa_profile_status_substatus_bad = -1;
+static int hf_pn_pa_profile_status_substatus_uncertain = -1;
+static int hf_pn_pa_profile_status_substatus_good = -1;
+static int hf_pn_pa_profile_status_update_event = -1;
+static int hf_pn_pa_profile_status_simulate = -1;
+static int hf_pn_pa_profile_value_8bit = -1;
+static int hf_pn_pa_profile_value_16bit = -1;
+static int hf_pn_pa_profile_value_float = -1;
+
+static gint ett_pn_io_rtc = -1;
+static gint ett_pn_io_ioxs = -1;
+static gint ett_pn_io_io_data_object = -1;
+static gint ett_pn_pa_profile_status = -1;
+
+static expert_field ei_pn_io_too_many_data_objects = EI_INIT;
+
+static const value_string pn_io_ioxs_extension[] = {
+ { 0x00 /* 0*/, "No IOxS octet follows" },
+ { 0x01 /* 1*/, "One more IOxS octet follows" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_ioxs_instance[] = {
+ { 0x00 /* 0*/, "Detected by subslot" },
+ { 0x01 /* 1*/, "Detected by slot" },
+ { 0x02 /* 2*/, "Detected by IO device" },
+ { 0x03 /* 3*/, "Detected by IO controller" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_ioxs_datastate[] = {
+ { 0x00 /* 0*/, "Bad" },
+ { 0x01 /* 1*/, "Good" },
+ { 0, NULL }
+};
+
+static const value_string pn_pa_profile_status_quality[] = {
+ { 0x00 /* 0*/, "BAD" },
+ { 0x01 /* 1*/, "UNCERTAIN" },
+ { 0x02 /* 2*/, "GOOD" },
+ { 0, NULL }
+};
+
+static const value_string pn_pa_profile_status_substatus_bad[] = {
+ { 0x0, "Non specific" },
+ { 0x2, "Not connected" },
+ { 0x8, "Passivated" },
+ { 0x9, "Maintenance alarm, more diagnosis" },
+ { 0xA, "Process related, no maintenance" },
+ { 0xF, "Function check, value not usable" },
+ { 0, NULL }
+};
+
+static const value_string pn_pa_profile_status_substatus_uncertain[] = {
+ { 0x2, "Substitute set" },
+ { 0x3, "Initial value" },
+ { 0xA, "Maintenance demanded" },
+ { 0xE, "Process related, no maintenance" },
+ { 0, NULL }
+};
+
+static const value_string pn_pa_profile_status_substatus_good[] = {
+ { 0x0, "Good" },
+ { 0x7, "Local override" },
+ { 0x8, "Initial fail safe" },
+ { 0x9, "Maintenance required" },
+ { 0xA, "Maintenance demanded" },
+ { 0xF, "Function check" },
+ { 0, NULL }
+};
+
+static const value_string pn_pa_profile_status_update_event[] = {
+ { 0x0, "No event" },
+ { 0x1, "Update event" },
+ { 0, NULL }
+};
+
+static const value_string pn_pa_profile_status_simulate[] = {
+ { 0x0, "Simulation off" },
+ { 0x1, "Simulation active" },
+ { 0, NULL }
+};
+
+
+static int * const ps_sb_fields[] = {
+ &hf_pn_io_ps_sb_res,
+ &hf_pn_io_ps_sb_ConsNr_reset,
+ &hf_pn_io_ps_sb_Toggle_d,
+ &hf_pn_io_ps_sb_FVactivated,
+ &hf_pn_io_ps_sb_WDtimeout,
+ &hf_pn_io_ps_sb_CECRC,
+ &hf_pn_io_ps_sb_DeviceFault,
+ &hf_pn_io_ps_sb_iparOK,
+ NULL
+};
+
+static int * const ps_cb_fields[] = {
+ &hf_pn_io_ps_cb_loopcheck,
+ &hf_pn_io_ps_cb_Chf_ACK,
+ &hf_pn_io_ps_cb_Toggle_h,
+ &hf_pn_io_ps_cb_activateFV,
+ &hf_pn_io_ps_cb_useTO2,
+ &hf_pn_io_ps_cb_resetConsNr,
+ &hf_pn_io_ps_cb_OAReq,
+ &hf_pn_io_ps_cb_iparEN,
+ NULL
+};
+
+static int * const ioxs_fields[] = {
+ &hf_pn_io_ioxs_datastate,
+ &hf_pn_io_ioxs_instance,
+ &hf_pn_io_ioxs_res14,
+ &hf_pn_io_ioxs_extension,
+ NULL
+};
+
+/*
+static int * const pa_profile_status_fields[] = {
+ &hf_pn_pa_profile_status_quality,
+ &hf_pn_pa_profile_status_substatus_bad,
+ &hf_pn_pa_profile_status_substatus_uncertain,
+ &hf_pn_pa_profile_status_substatus_good,
+ &hf_pn_pa_profile_status_update_event,
+ &hf_pn_pa_profile_status_simulate,
+ NULL
+};
+*/
+
+/* Dissector for PROFIsafe Status Byte */
+static int
+dissect_pn_io_ps_SB(tvbuff_t *tvb, int offset,
+packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, int hfindex, int * const *fields)
+{
+
+ if (tree) {
+ guint8 u8StatusByte;
+ proto_item *sb_item;
+
+ u8StatusByte = tvb_get_guint8(tvb, offset);
+
+ /* Add Status Byte subtree */
+ sb_item = proto_tree_add_bitmask_with_flags(tree, tvb, offset, hfindex, ett_pn_io_ioxs, fields,
+ ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
+ proto_item_append_text(sb_item, " (%s)", ((u8StatusByte == 0x20) || (u8StatusByte == 0x00)) ? "normal" : "unnormal");
+ }
+
+ return offset + 1;
+}
+
+
+/* Dissector for PROFIsafe Control Byte */
+static int
+dissect_pn_io_ps_CB(tvbuff_t *tvb, int offset,
+packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, int hfindex, int * const *fields)
+{
+
+ if (tree) {
+ guint8 u8ControlByte;
+ proto_item *cb_item;
+
+ u8ControlByte = tvb_get_guint8(tvb, offset);
+
+ /* Add Status Byte subtree */
+ cb_item = proto_tree_add_bitmask_with_flags(tree, tvb, offset, hfindex, ett_pn_io_ioxs, fields,
+ ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
+ proto_item_append_text(cb_item, " (%s)", ((u8ControlByte == 0x20) || (u8ControlByte == 0x00) ||
+ (u8ControlByte == 0xa0) || (u8ControlByte == 0x80)) ? "normal" : "unnormal");
+ }
+
+ return offset + 1;
+}
+
+
+/* Dissector for IOCS (As each IOCS stands for a specific Slot & Subslot) */
+static int
+dissect_PNIO_IOCS(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree,
+ guint8 *drep _U_, int hfindex, guint16 slotNr, guint16 subSlotNr, int * const *fields)
+{
+
+ if (tree) {
+ guint8 u8IOxS;
+ proto_item *ioxs_item;
+
+ u8IOxS = tvb_get_guint8(tvb, offset);
+
+ /* Add ioxs subtree */
+ ioxs_item = proto_tree_add_bitmask_with_flags(tree, tvb, offset, hfindex,
+ ett_pn_io_ioxs, fields, ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
+ proto_item_append_text(ioxs_item,
+ " (%s%s), Slot: 0x%x, Subslot: 0x%x",
+ (u8IOxS & 0x01) ? "another IOxS follows " : "",
+ (u8IOxS & 0x80) ? "good" : "bad",
+ slotNr,
+ subSlotNr);
+ }
+
+ return offset + 1;
+}
+
+
+/* dissect the IOxS (IOCS, IOPS) field */
+static int
+dissect_PNIO_IOxS(tvbuff_t *tvb, int offset,
+packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, int hfindex, int * const *fields)
+{
+
+ if (tree) {
+ guint8 u8IOxS;
+ proto_item *ioxs_item;
+
+ u8IOxS = tvb_get_guint8(tvb, offset);
+
+ /* Add ioxs subtree */
+ ioxs_item = proto_tree_add_bitmask_with_flags(tree, tvb, offset, hfindex,
+ ett_pn_io_ioxs, fields, ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
+ proto_item_append_text(ioxs_item,
+ " (%s%s)",
+ (u8IOxS & 0x01) ? "another IOxS follows " : "",
+ (u8IOxS & 0x80) ? "good" : "bad");
+ }
+
+ return offset + 1;
+}
+
+
+/* Universel dissector for flexibel PROFIsafe Data 8 to 64 Bits */
+static int
+dissect_pn_io_ps_uint(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint8 *drep,
+int hfindex, guint8 bytelength, guint64 *pdata)
+{
+ guint64 data;
+ gboolean generalDissection;
+
+ generalDissection = FALSE;
+
+ switch (bytelength) {
+ case 1: /* 8 Bit Safety IO Data */
+ data = tvb_get_guint8(tvb, offset);
+ if (pdata)
+ *pdata = data;
+ break;
+
+ case 2: /* 16 Bit Safety IO Data */
+ data = tvb_get_letohs(tvb, offset);
+ if (pdata)
+ *pdata = data;
+ break;
+
+ case 3: /* 24 Bit Safety IO Data */
+ data = tvb_get_letoh24(tvb, offset);
+ if (pdata)
+ *pdata = data;
+ break;
+
+ case 4: /* 32 Bit Safety IO Data */
+ data = tvb_get_letohl(tvb, offset);
+ if (pdata)
+ *pdata = data;
+ break;
+
+ case 5: /* 40 Bit Safety IO Data */
+ data = tvb_get_letoh40(tvb, offset);
+ if (pdata)
+ *pdata = data;
+ break;
+
+ case 6: /* 48 Bit Safety IO Data */
+ data = tvb_get_letoh48(tvb, offset);
+ if (pdata)
+ *pdata = data;
+ break;
+
+ case 7: /* 56 Bit Safety IO Data */
+ data = tvb_get_letoh56(tvb, offset);
+ if (pdata)
+ *pdata = data;
+ break;
+
+ case 8: /* 64 Bit Safety IO Data */
+ data = tvb_get_letoh64(tvb, offset);
+ if (pdata)
+ *pdata = data;
+ break;
+
+ default: /* Safety IO Data is too big to save it into one variable */
+ dissect_pn_user_data(tvb, offset, pinfo, tree, bytelength, "Safety IO Data");
+ generalDissection = TRUE;
+ break;
+ }
+
+ if (tree && generalDissection == FALSE) {
+ proto_tree_add_item(tree, hfindex, tvb, offset, bytelength, DREP_ENC_INTEGER(drep));
+ }
+
+ return offset + bytelength;
+}
+
+
+/* dissect a PN-IO RTC1 Cyclic Service Data Unit */
+int
+dissect_PNIO_C_SDU_RTC1(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep _U_, guint16 frameid)
+{
+ proto_tree *data_tree = NULL;
+
+ /* Count & offset for comparation of the arrays */
+ guint16 frameOffset;
+ guint32 objectCounter;
+ gboolean inputFlag;
+ gboolean outputFlag;
+ gboolean psInfoText; /* Used to display only once per frame the info text "PROFIsafe Device" */
+
+ proto_item *data_item;
+ proto_item *IODataObject_item;
+ proto_item *IODataObject_item_info;
+ proto_tree *IODataObject_tree;
+ proto_item *ModuleID_item;
+ proto_item *ModuleDiff_item;
+
+ wmem_strbuf_t *moduleName;
+
+ guint8 toggleBitSb;
+ guint8 toggleBitCb;
+ guint64 f_data;
+
+ guint8 statusbyte;
+ guint8 controlbyte;
+ guint8 safety_io_data_length;
+
+ guint16 number_io_data_objects_input_cr;
+ guint16 number_iocs_input_cr;
+ guint16 number_io_data_objects_output_cr;
+ guint16 number_iocs_output_cr;
+
+ conversation_t *conversation;
+ stationInfo *station_info = NULL;
+ iocsObject *iocs_object;
+ ioDataObject *io_data_object;
+ moduleDiffInfo *module_diff_info;
+ wmem_list_frame_t *frame;
+ wmem_list_frame_t *frame_diff;
+
+ /* Initial */
+ frameOffset = 0;
+ f_data = 0;
+ inputFlag = FALSE;
+ outputFlag = FALSE;
+ psInfoText = FALSE;
+ number_io_data_objects_input_cr = 0;
+ number_iocs_input_cr = 0;
+ number_io_data_objects_output_cr = 0;
+ number_iocs_output_cr = 0;
+
+ wmem_list_frame_t *aruuid_frame;
+ ARUUIDFrame *current_aruuid_frame = NULL;
+ guint32 current_aruuid = 0;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO"); /* set protocol name */
+
+ data_item = proto_tree_add_protocol_format(tree, proto_pn_io_rtc1, tvb, offset, tvb_captured_length(tvb),
+ "PROFINET IO Cyclic Service Data Unit: %u bytes", tvb_captured_length(tvb));
+ data_tree = proto_item_add_subtree(data_item, ett_pn_io_rtc);
+
+ /* dissect_dcerpc_uint16(tvb, offset, pinfo, data_tree, drep, hf_pn_io_packedframe_SFCRC, &u16SFCRC); */
+ if (!(dissect_CSF_SDU_heur(tvb, pinfo, data_tree, NULL) == FALSE))
+ return(tvb_captured_length(tvb));
+
+ /* Only dissect cyclic RTC1 frames, if PN Connect Request has been read */
+ conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, CONVERSATION_NONE, 0, 0, 0);
+
+ /* Detect input data package and output data package */
+ if (conversation != NULL) {
+ if (aruuid_frame_setup_list != NULL) {
+ for (aruuid_frame = wmem_list_tail(aruuid_frame_setup_list); aruuid_frame != NULL; aruuid_frame = wmem_list_frame_prev(aruuid_frame)) {
+ current_aruuid_frame = (ARUUIDFrame*)wmem_list_frame_data(aruuid_frame);
+ /* There are prerequisites to dissect RTC frame data */
+ /* Current station info must be found before RTC frame dissection starts */
+ /* if RTC frame has setup frame and setup frame number is less than RTC frame number AND if RTC frame has release frame and release frame number is greater than RTC frame number */
+ /* if RTC frame has setup frame and setup frame number is less than RTC frame number AND RTC frame does not have release frame yet! */
+ /* then, get AR UUID of current station info */
+ if ((current_aruuid_frame->setupframe && current_aruuid_frame->setupframe < pinfo->num) &&
+ ((current_aruuid_frame->releaseframe && current_aruuid_frame->releaseframe > pinfo->num) ||
+ !current_aruuid_frame->releaseframe)) {
+ if (current_aruuid_frame->inputframe == frameid) {
+ current_aruuid = current_aruuid_frame->aruuid.data1;
+ break;
+ }
+ else if (current_aruuid_frame->outputframe == frameid) {
+ current_aruuid = current_aruuid_frame->aruuid.data1;
+ break;
+ }
+ }
+ }
+ }
+
+ station_info = (stationInfo*)conversation_get_proto_data(conversation, current_aruuid);
+
+ if (station_info != NULL) {
+ pn_find_dcp_station_info(station_info, conversation);
+
+ if (pnio_ps_selection == TRUE) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO_PS"); /* set PROFISsafe protocol name */
+ }
+
+ if (addresses_equal(&(pinfo->src), conversation_key_addr1(conversation->key_ptr)) && addresses_equal(&(pinfo->dst), conversation_key_addr2(conversation->key_ptr))) {
+ inputFlag = TRUE;
+ outputFlag = FALSE;
+ number_io_data_objects_input_cr = station_info->ioDataObjectNr_in;
+ number_iocs_input_cr = station_info->iocsNr_in;
+ }
+
+ if (addresses_equal(&(pinfo->dst), conversation_key_addr1(conversation->key_ptr)) && addresses_equal(&(pinfo->src), conversation_key_addr2(conversation->key_ptr))) {
+ outputFlag = TRUE;
+ inputFlag = FALSE;
+ number_io_data_objects_output_cr = station_info->ioDataObjectNr_out;
+ number_iocs_output_cr = station_info->iocsNr_out;
+ }
+ }
+ }
+
+ /* ------- Input (PNIO) / Response (PNIO_PS) Frame Handling ------- */
+ if (inputFlag) {
+ if (pnio_ps_selection == TRUE) {
+ proto_tree_add_string_format_value(data_tree, hf_pn_io_frame_info_type, tvb,
+ offset, 0, "Response", "Response Frame (IO_Device -> IO_Controller)");
+ }
+ else {
+ proto_tree_add_string_format_value(data_tree, hf_pn_io_frame_info_type, tvb,
+ offset, 0, "Input", "Input Frame (IO_Device -> IO_Controller)");
+ }
+
+ if (station_info != NULL) {
+ if (station_info->typeofstation != NULL) {
+ proto_tree_add_string_format_value(data_tree, hf_pn_io_frame_info_vendor, tvb, 0,
+ 0, station_info->typeofstation, "\"%s\"", station_info->typeofstation);
+ }
+ if (station_info->nameofstation != NULL) {
+ proto_tree_add_string_format_value(data_tree, hf_pn_io_frame_info_nameofstation, tvb, 0,
+ 0, station_info->nameofstation, "\"%s\"", station_info->nameofstation);
+ }
+
+ if (station_info->gsdPathLength == TRUE) { /* given path isn't too long for the array */
+ if (station_info->gsdFound == TRUE) { /* found a GSD-file */
+ if (station_info->gsdLocation != NULL) {
+ IODataObject_item_info = proto_tree_add_item(data_tree, hf_pn_io_frame_info_gsd_found, tvb, offset, 0, ENC_NA);
+ proto_item_append_text(IODataObject_item_info, ": \"%s\"", station_info->gsdLocation);
+ }
+ }
+ else {
+ if (station_info->gsdLocation != NULL) {
+ IODataObject_item_info = proto_tree_add_item(data_tree, hf_pn_io_frame_info_gsd_error, tvb, offset, 0, ENC_NA);
+ proto_item_append_text(IODataObject_item_info, " Please place relevant GSD-file under \"%s\"", station_info->gsdLocation);
+ }
+ }
+ }
+ else {
+ IODataObject_item_info = proto_tree_add_item(data_tree, hf_pn_io_frame_info_gsd_path, tvb, offset, 0, ENC_NA);
+ proto_item_append_text(IODataObject_item_info, " Please check your GSD-file networkpath. (No Path configured)");
+ }
+ }
+
+ /* ---- Input IOData-/IOCS-Object Handling ---- */
+ objectCounter = number_io_data_objects_input_cr + number_iocs_input_cr;
+ if (objectCounter > (guint)tvb_reported_length_remaining(tvb, offset)) {
+ expert_add_info_format(pinfo, data_item, &ei_pn_io_too_many_data_objects, "Too many data objects: %d", objectCounter);
+ return(tvb_captured_length(tvb));
+ }
+
+ while (objectCounter--) {
+ /* ---- Input IO Data Object Handling ---- */
+ if (station_info != NULL) {
+ for (frame = wmem_list_head(station_info->ioobject_data_in); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ io_data_object = (ioDataObject*)wmem_list_frame_data(frame);
+ if (io_data_object->frameOffset == frameOffset) {
+ /* Found following object */
+
+ IODataObject_item = proto_tree_add_item(data_tree, hf_pn_io_io_data_object, tvb, offset, 0, ENC_NA);
+ IODataObject_tree = proto_item_add_subtree(IODataObject_item, ett_pn_io_io_data_object);
+
+ /* Control: the Device still uses the correct ModuleIdentNumber? */
+ for (frame_diff = wmem_list_head(station_info->diff_module); frame_diff != NULL; frame_diff = wmem_list_frame_next(frame_diff)) {
+ module_diff_info = (moduleDiffInfo*)wmem_list_frame_data(frame_diff);
+ if (io_data_object->moduleIdentNr != module_diff_info->modulID) {
+ ModuleDiff_item = proto_tree_add_item(IODataObject_tree, hf_pn_io_io_data_object_info_module_diff, tvb, 0, 0, ENC_NA);
+ proto_item_append_text(ModuleDiff_item, ": Device using ModuleIdentNumber 0x%08x instead of 0x%08x", module_diff_info->modulID, io_data_object->moduleIdentNr);
+ break;
+ }
+ }
+
+ proto_tree_add_uint(IODataObject_tree, hf_pn_io_io_data_object_info_moduleidentnumber, tvb, 0, 0, io_data_object->moduleIdentNr);
+ proto_tree_add_uint(IODataObject_tree, hf_pn_io_io_data_object_info_submoduleidentnumber, tvb, 0, 0, io_data_object->subModuleIdentNr);
+
+ /* PROFIsafe Supported Inputmodule handling */
+ if (io_data_object->profisafeSupported == TRUE && pnio_ps_selection == TRUE) {
+ if (io_data_object->profisafeSupported == TRUE && psInfoText == FALSE) {
+ /* Only add one information string per device to the infotext */
+ col_append_str(pinfo->cinfo, COL_INFO, ", PROFIsafe Device"); /* Add string to wireshark infotext */
+ psInfoText = TRUE;
+ }
+
+ proto_tree_add_uint(IODataObject_tree, hf_pn_io_ps_f_dest_adr, tvb, 0, 0, io_data_object->f_dest_adr);
+
+ /* Get Safety IO Data */
+ if (io_data_object->f_crc_seed == FALSE) {
+ safety_io_data_length = io_data_object->length - F_MESSAGE_TRAILER_4BYTE;
+ } else {
+ safety_io_data_length = io_data_object->length - F_MESSAGE_TRAILER_5BYTE;
+ }
+
+ if (safety_io_data_length > 0) {
+ offset = dissect_pn_io_ps_uint(tvb, offset, pinfo, IODataObject_tree, drep, hf_pn_io_ps_f_data,
+ safety_io_data_length, &f_data);
+ }
+
+ /* ---- Check for new PNIO data using togglebit ---- */
+ statusbyte = tvb_get_guint8(tvb, offset);
+ toggleBitSb = statusbyte & 0x20; /* get ToggleBit of StatusByte */
+
+ if (io_data_object->lastToggleBit != toggleBitSb) { /* ToggleBit has changed --> new Data incoming */
+ /* Special Filter for ToggleBit within Statusbyte */
+ ModuleID_item = proto_tree_add_uint(IODataObject_tree, hf_pn_io_ps_sb_toggelBitChanged, tvb, offset, 0, toggleBitSb);
+ proto_item_set_hidden(ModuleID_item);
+
+ ModuleID_item = proto_tree_add_uint(IODataObject_tree, hf_pn_io_ps_sb_toggelBitChange_slot_nr, tvb, offset, 0, io_data_object->slotNr);
+ proto_item_set_hidden(ModuleID_item);
+
+ ModuleID_item = proto_tree_add_uint(IODataObject_tree, hf_pn_io_ps_sb_toggelBitChange_subslot_nr, tvb, offset, 0, io_data_object->subSlotNr);
+ proto_item_set_hidden(ModuleID_item);
+ }
+
+ offset = dissect_pn_io_ps_SB(tvb, offset, pinfo, IODataObject_tree, drep, hf_pn_io_ps_sb, ps_sb_fields);
+ offset = dissect_pn_user_data(tvb, offset, pinfo, IODataObject_tree, io_data_object->f_crc_len, "CRC");
+
+ io_data_object->last_sb_cb = statusbyte; /* save the value of current statusbyte */
+ io_data_object->lastToggleBit = toggleBitSb; /* save the value of current togglebit within statusbyte */
+ } /* END of PROFIsafe Module Handling */
+
+ else {
+ /* Module is not PROFIsafe supported */
+ if (io_data_object->api == PA_PROFILE_API)
+ {
+ offset = dissect_pn_pa_profile_data(tvb, offset, pinfo, IODataObject_tree, io_data_object->length, "IO Data");
+ }
+ else
+ {
+ offset = dissect_pn_user_data(tvb, offset, pinfo, IODataObject_tree, io_data_object->length, "IO Data");
+ }
+ }
+
+ if (io_data_object->discardIOXS == FALSE) {
+ offset = dissect_PNIO_IOxS(tvb, offset, pinfo, IODataObject_tree, drep, hf_pn_io_iops, ioxs_fields);
+ proto_item_set_len(IODataObject_item, io_data_object->length + 1); /* Length = Databytes + IOXS Byte */
+ }
+ else {
+ proto_item_set_len(IODataObject_item, io_data_object->length); /* Length = Databytes */
+ }
+
+ proto_item_append_text(IODataObject_item, ": Slot: 0x%x Subslot: 0x%x",
+ io_data_object->slotNr, io_data_object->subSlotNr);
+
+
+ /* ModuleIdentNr appears not only once in GSD-file -> set module name more generally */
+ if (io_data_object->amountInGSDML > 1) { /* if ModuleIdentNr only appears once in GSD-file, use the found GSD-file-ModuleName, else ... */
+ if (io_data_object->slotNr == 0) {
+ moduleName = wmem_strbuf_new(pinfo->pool, "Headstation");
+ }
+ else {
+ moduleName = wmem_strbuf_new(pinfo->pool, "Module");
+ }
+
+ if (io_data_object->profisafeSupported == TRUE) {
+ /* PROFIsafe */
+ if (io_data_object->length >= 5) { /* 5 due to 3 CRC bytes & 1 status byte & (at least) 1 data byte */
+ wmem_strbuf_append(moduleName, ", DI");
+ }
+ else {
+ wmem_strbuf_append(moduleName, ", DO");
+ }
+ }
+ else {
+ /* PROFINET */
+ if (io_data_object->length > 0) {
+ wmem_strbuf_append(moduleName, ", DI");
+ }
+ else {
+ wmem_strbuf_append(moduleName, ", DO");
+ }
+ }
+
+ io_data_object->moduleNameStr = wmem_strdup(wmem_file_scope(), wmem_strbuf_get_str(moduleName));
+ }
+
+ proto_item_append_text(IODataObject_item, " ModuleName: \"%s\"", io_data_object->moduleNameStr);
+
+ /* emphasize the PROFIsafe supported Modul */
+ if (io_data_object->profisafeSupported == TRUE && pnio_ps_selection == TRUE) {
+ (proto_item_append_text(IODataObject_item, " (PROFIsafe Module)"));
+ }
+
+
+ /* Set frameOffset to its new value, to find the next object */
+ frameOffset = frameOffset + io_data_object->length; /* frameOffset = current value + data bytes */
+ if (io_data_object->discardIOXS == FALSE) {
+ frameOffset = frameOffset + 1; /* frameOffset = current value + iops byte */
+ }
+ }
+ }
+ }
+
+ /* ---- Input IOCS Object Handling ---- */
+ if (station_info != NULL) {
+ for (frame = wmem_list_head(station_info->iocs_data_in); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ iocs_object = (iocsObject*)wmem_list_frame_data(frame);
+ if (iocs_object->frameOffset == frameOffset) {
+ offset = dissect_PNIO_IOCS(tvb, offset, pinfo, data_tree, drep, hf_pn_io_iocs, iocs_object->slotNr,
+ iocs_object->subSlotNr, ioxs_fields);
+
+ /* Set frameOffset to its new value, to find the next object */
+ frameOffset = frameOffset + 1; /* frameOffset = current value + iops byte */
+
+ break;
+ }
+ }
+ }
+ }
+
+ /* Dissect padding */
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, tvb_captured_length_remaining(tvb, offset), "GAP and RTCPadding");
+ } /* END of Input Frame Handling */
+
+ /* ----- Output (PNIO) / Request (PNIO_PS) Frame Handling ------ */
+ else if (outputFlag) {
+ if (pnio_ps_selection == TRUE) {
+ proto_tree_add_string_format_value(data_tree, hf_pn_io_frame_info_type, tvb,
+ offset, 0, "Request", "Request Frame (IO_Controller -> IO_Device)");
+ }
+ else {
+ proto_tree_add_string_format_value(data_tree, hf_pn_io_frame_info_type, tvb,
+ offset, 0, "Output", "Output Frame (IO_Controller -> IO_Device)");
+ }
+
+ if (station_info != NULL) {
+ if (station_info->typeofstation != NULL) {
+ proto_tree_add_string_format_value(data_tree, hf_pn_io_frame_info_vendor, tvb, 0,
+ 0, station_info->typeofstation, "\"%s\"", station_info->typeofstation);
+ }
+ if (station_info->nameofstation != NULL) {
+ proto_tree_add_string_format_value(data_tree, hf_pn_io_frame_info_nameofstation, tvb, 0,
+ 0, station_info->nameofstation, "\"%s\"", station_info->nameofstation);
+ }
+
+ if (station_info->gsdPathLength == TRUE) { /* given path isn't too long for the array */
+ if (station_info->gsdFound == TRUE) { /* found a GSD-file */
+ if (station_info->gsdLocation != NULL) {
+ IODataObject_item_info = proto_tree_add_item(data_tree, hf_pn_io_frame_info_gsd_found, tvb, offset, 0, ENC_NA);
+ proto_item_append_text(IODataObject_item_info, ": \"%s\"", station_info->gsdLocation);
+ }
+ }
+ else {
+ if (station_info->gsdLocation != NULL) {
+ IODataObject_item_info = proto_tree_add_item(data_tree, hf_pn_io_frame_info_gsd_error, tvb, offset, 0, ENC_NA);
+ proto_item_append_text(IODataObject_item_info, " Please place relevant GSD-file under \"%s\"", station_info->gsdLocation);
+ }
+ }
+ }
+ else {
+ IODataObject_item_info = proto_tree_add_item(data_tree, hf_pn_io_frame_info_gsd_path, tvb, offset, 0, ENC_NA);
+ proto_item_append_text(IODataObject_item_info, " Please check your GSD-file networkpath. (No Path configured)");
+ }
+ }
+
+ /* ---- Output IOData-/IOCS-Object Handling ---- */
+ objectCounter = number_io_data_objects_output_cr + number_iocs_output_cr;
+ if (objectCounter > (guint)tvb_reported_length_remaining(tvb, offset)) {
+ expert_add_info_format(pinfo, data_item, &ei_pn_io_too_many_data_objects, "Too many data objects: %d", objectCounter);
+ return(tvb_captured_length(tvb));
+ }
+ while (objectCounter--) {
+ /* ---- Output IO Data Object Handling ---- */
+ if (station_info != NULL) {
+ for (frame = wmem_list_head(station_info->ioobject_data_out); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ io_data_object = (ioDataObject*)wmem_list_frame_data(frame);
+ if (io_data_object != NULL && io_data_object->frameOffset == frameOffset) {
+ /* Found following object */
+
+ IODataObject_item = proto_tree_add_item(data_tree, hf_pn_io_io_data_object, tvb, offset, 0, ENC_NA);
+ IODataObject_tree = proto_item_add_subtree(IODataObject_item, ett_pn_io_io_data_object);
+
+ /* Control: the Device still uses the correct ModuleIdentNumber? */
+ for (frame_diff = wmem_list_head(station_info->diff_module); frame_diff != NULL; frame_diff = wmem_list_frame_next(frame_diff)) {
+ module_diff_info = (moduleDiffInfo*)wmem_list_frame_data(frame_diff);
+ if (io_data_object->moduleIdentNr != module_diff_info->modulID) {
+ ModuleDiff_item = proto_tree_add_item(IODataObject_tree, hf_pn_io_io_data_object_info_module_diff, tvb, 0, 0, ENC_NA);
+ proto_item_append_text(ModuleDiff_item, ": Device using ModuleIdentNumber 0x%08x instead of 0x%08x", module_diff_info->modulID, io_data_object->moduleIdentNr);
+ break;
+ }
+ }
+
+ proto_tree_add_uint(IODataObject_tree, hf_pn_io_io_data_object_info_moduleidentnumber, tvb, 0, 0, io_data_object->moduleIdentNr);
+ proto_tree_add_uint(IODataObject_tree, hf_pn_io_io_data_object_info_submoduleidentnumber, tvb, 0, 0, io_data_object->subModuleIdentNr);
+
+ if (io_data_object->profisafeSupported == TRUE && pnio_ps_selection == TRUE) {
+ if (io_data_object->profisafeSupported == TRUE && psInfoText == FALSE) {
+ /* Only add one information string per device to the infotext */
+ col_append_str(pinfo->cinfo, COL_INFO, ", PROFIsafe Device"); /* Add string to wireshark infotext */
+ psInfoText = TRUE;
+ }
+
+ proto_tree_add_uint(IODataObject_tree, hf_pn_io_ps_f_dest_adr, tvb, 0, 0, io_data_object->f_dest_adr);
+
+ /* Get Safety IO Data */
+ if (io_data_object->f_crc_seed == FALSE) {
+ safety_io_data_length = io_data_object->length - F_MESSAGE_TRAILER_4BYTE;
+ } else {
+ safety_io_data_length = io_data_object->length - F_MESSAGE_TRAILER_5BYTE;
+ }
+
+ if (safety_io_data_length > 0) {
+ offset = dissect_pn_io_ps_uint(tvb, offset, pinfo, IODataObject_tree, drep, hf_pn_io_ps_f_data,
+ safety_io_data_length, &f_data);
+ }
+
+ /* ---- Check for new PNIO data using togglebit ---- */
+ controlbyte = tvb_get_guint8(tvb, offset);
+ toggleBitCb = controlbyte & 0x20; /* get ToggleBit of Controlbyte */
+
+ if (io_data_object->lastToggleBit != toggleBitCb) { /* ToggleBit has changed --> new Data incoming */
+ /* Special Filter for ToggleBit within Controlbyte */
+ ModuleID_item = proto_tree_add_uint(IODataObject_tree, hf_pn_io_ps_cb_toggelBitChanged, tvb, offset, 0, toggleBitCb);
+ proto_item_set_hidden(ModuleID_item);
+
+ ModuleID_item = proto_tree_add_uint(IODataObject_tree, hf_pn_io_ps_cb_toggelBitChange_slot_nr, tvb, offset, 0, io_data_object->slotNr);
+ proto_item_set_hidden(ModuleID_item);
+
+ ModuleID_item = proto_tree_add_uint(IODataObject_tree, hf_pn_io_ps_cb_toggelBitChange_subslot_nr, tvb, offset, 0, io_data_object->subSlotNr);
+ proto_item_set_hidden(ModuleID_item);
+ }
+
+ offset = dissect_pn_io_ps_CB(tvb, offset, pinfo, IODataObject_tree, drep, hf_pn_io_ps_cb, ps_cb_fields);
+ offset = dissect_pn_user_data(tvb, offset, pinfo, IODataObject_tree, io_data_object->f_crc_len, "CRC");
+
+ io_data_object->last_sb_cb = controlbyte; /* save the value of current controlbyte */
+ io_data_object->lastToggleBit = toggleBitCb; /* save the value of current togglebit within controlbyte */
+ } /* End of PROFIsafe Module Handling */
+ else {
+ /* Module is not PROFIsafe supported */
+ if (io_data_object->api == PA_PROFILE_API)
+ {
+ offset = dissect_pn_pa_profile_data(tvb, offset, pinfo, IODataObject_tree, io_data_object->length, "IO Data");
+ }
+ else
+ {
+ offset = dissect_pn_user_data(tvb, offset, pinfo, IODataObject_tree, io_data_object->length, "IO Data");
+ }
+ }
+
+ if (io_data_object->discardIOXS == FALSE) {
+ offset = dissect_PNIO_IOxS(tvb, offset, pinfo, IODataObject_tree, drep, hf_pn_io_iops, ioxs_fields);
+ proto_item_set_len(IODataObject_item, io_data_object->length + 1); /* Length = Databytes + IOXS Byte */
+ }
+ else {
+ proto_item_set_len(IODataObject_item, io_data_object->length); /* Length = Databytes */
+ }
+
+ proto_item_append_text(IODataObject_item, ": Slot: 0x%x Subslot: 0x%x",
+ io_data_object->slotNr, io_data_object->subSlotNr);
+
+
+ /* ModuleIdentNr appears not only once in GSD-file -> set module name more generally */
+ if (io_data_object->amountInGSDML > 1) { /* if ModuleIdentNr only appears once in GSD-file, use the found GSD-file-ModuleName, else ... */
+ if (io_data_object->slotNr == 0) {
+ moduleName = wmem_strbuf_new(pinfo->pool, "Headstation");
+ }
+ else {
+ moduleName = wmem_strbuf_new(pinfo->pool, "Module");
+ }
+
+ if (io_data_object->profisafeSupported == TRUE) {
+ /* PROFIsafe */
+ if (io_data_object->length >= 5) { /* 5 due to 3 CRC bytes & 1 status byte & (at least) 1 data byte */
+ wmem_strbuf_append(moduleName, ", DO");
+ }
+ else {
+ wmem_strbuf_append(moduleName, ", DI");
+ }
+ }
+ else {
+ /* PROFINET */
+ if (io_data_object->length > 0) {
+ wmem_strbuf_append(moduleName, ", DO");
+ }
+ else {
+ wmem_strbuf_append(moduleName, ", DI");
+ }
+ }
+
+ io_data_object->moduleNameStr = wmem_strdup(wmem_file_scope(), wmem_strbuf_get_str(moduleName));
+ }
+
+ proto_item_append_text(IODataObject_item, " ModuleName: \"%s\"", io_data_object->moduleNameStr);
+
+ /* emphasize the PROFIsafe supported Modul */
+ if (io_data_object->profisafeSupported == TRUE && pnio_ps_selection == TRUE) {
+ proto_item_append_text(IODataObject_item, " (PROFIsafe Module)");
+ }
+
+ /* Set frameOffset to its new value, to find the next object */
+ frameOffset = frameOffset + io_data_object->length; /* frameOffset = current value + data bytes */
+ if (io_data_object->discardIOXS == FALSE) {
+ frameOffset = frameOffset + 1; /* frameOffset = current value + iops byte */
+ }
+ }
+ }
+ }
+
+ /* ---- Output IOCS Object Handling ---- */
+ if (station_info != NULL) {
+ for (frame = wmem_list_head(station_info->iocs_data_out); frame != NULL; frame = wmem_list_frame_next(frame)) {
+ iocs_object = (iocsObject*)wmem_list_frame_data(frame);
+ if (iocs_object->frameOffset == frameOffset) {
+ offset = dissect_PNIO_IOCS(tvb, offset, pinfo, data_tree, drep, hf_pn_io_iocs, iocs_object->slotNr,
+ iocs_object->subSlotNr, ioxs_fields);
+
+ /* Set frameOffset to its new value, to find the next object */
+ frameOffset = frameOffset + 1; /* frameOffset = current value + iops byte */
+
+ break;
+ }
+ }
+ }
+ }
+
+ /* Dissect padding */
+ offset = dissect_pn_user_data(tvb, offset, pinfo, tree, tvb_captured_length_remaining(tvb, offset), "GAP and RTCPadding");
+ } /* END of Output Frame Handling */
+
+ return offset;
+}
+
+
+/* dissect the PA Profile status field */
+static int
+dissect_pn_pa_profile_status(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, int hfindex)
+{
+
+ if (tree) {
+ guint8 u8status;
+ guint8 quality;
+ proto_item *status_item;
+ proto_tree *status_tree;
+ const gchar* quality_name = NULL;
+
+ u8status = tvb_get_guint8(tvb, offset);
+ quality = (u8status >> 6u) & 0x3u;
+
+ /* add status subtree */
+ status_item = proto_tree_add_uint(tree, hfindex, tvb, offset, 1, u8status);
+
+ quality_name = try_val_to_str(quality, pn_pa_profile_status_quality);
+
+ proto_item_append_text(status_item,
+ " (%s)",
+ (quality_name != NULL) ? quality_name : "invalid");
+
+ status_tree = proto_item_add_subtree(status_item, ett_pn_pa_profile_status);
+
+ proto_tree_add_item(status_tree, hf_pn_pa_profile_status_quality, tvb, offset, 1, ENC_NA);
+
+ switch(quality)
+ {
+ case 0:
+ proto_tree_add_item(status_tree, hf_pn_pa_profile_status_substatus_bad, tvb, offset, 1, ENC_NA);
+ break;
+ case 1:
+ proto_tree_add_item(status_tree, hf_pn_pa_profile_status_substatus_uncertain, tvb, offset, 1, ENC_NA);
+ break;
+ case 2:
+ proto_tree_add_item(status_tree, hf_pn_pa_profile_status_substatus_good, tvb, offset, 1, ENC_NA);
+ break;
+ default:
+ break;
+ }
+ proto_tree_add_item(status_tree, hf_pn_pa_profile_status_update_event, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(status_tree, hf_pn_pa_profile_status_simulate, tvb, offset, 1, ENC_NA);
+ }
+
+ return offset + 1;
+}
+
+int
+dissect_pn_pa_profile_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 length, const char *text)
+{
+ (void)text;
+ /*
+ All PA Profile submodules carry an 8-bit "status" plus the real data, which
+ currently is a float, an 8-bit integer or a 16-bit integer.
+ So we will have either 2, 3 or 5 bytes.
+ */
+ if (length == 2u)
+ {
+ proto_tree_add_item(tree, hf_pn_pa_profile_value_8bit, tvb, offset, 1, ENC_BIG_ENDIAN);
+ dissect_pn_pa_profile_status(tvb, offset+1, pinfo, tree, hf_pn_pa_profile_status);
+ }
+ else if (length == 3u)
+ {
+ proto_tree_add_item(tree, hf_pn_pa_profile_value_16bit, tvb, offset, 2, ENC_BIG_ENDIAN);
+ dissect_pn_pa_profile_status(tvb, offset+2, pinfo, tree, hf_pn_pa_profile_status);
+ }
+ else if (length == 5u)
+ {
+ proto_tree_add_item(tree, hf_pn_pa_profile_value_float, tvb, offset, 4, ENC_BIG_ENDIAN);
+ dissect_pn_pa_profile_status(tvb, offset+4, pinfo, tree, hf_pn_pa_profile_status);
+ }
+ else
+ {
+ /* Delegate to standard user data if unknown */
+ (void)dissect_pn_user_data(tvb, offset, pinfo, tree, length, "IO Data");
+ }
+
+ return offset + length;
+}
+
+void
+init_pn_io_rtc1(int proto)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_io_io_data_object,
+ { "IODataObject", "pn_io.io_data_object",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_io_data_object_info_module_diff,
+ { "Difference", "pn_io.io_data_object.diff_module",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_io_data_object_info_moduleidentnumber,
+ { "ModuleIdentNumber", "pn_io.io_data_object.module_nr",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_io_data_object_info_submoduleidentnumber,
+ { "SubmoduleIdentNumber", "pn_io.io_data_object.submodule_nr",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_info_type,
+ { "PN Frame Type", "pn_io.frame_info.type",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_info_vendor,
+ { "DeviceVendorValue", "pn_io.frame_info.vendor",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_info_nameofstation,
+ { "NameOfStation", "pn_io.frame_info.nameofstation",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_info_gsd_found,
+ { "GSD-file found", "pn_io.frame_info.gsd_found",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_info_gsd_error,
+ { "GSD-file not found.", "pn_io.frame_info.gsd_error",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_frame_info_gsd_path,
+ { "GSD-file networkpath failure!", "pn_io.frame_info.gsd_path",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iocs,
+ { "IOCS", "pn_io.ioxs",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_iops,
+ { "IOPS", "pn_io.ioxs",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ioxs_extension,
+ { "Extension", "pn_io.ioxs.extension",
+ FT_UINT8, BASE_HEX, VALS(pn_io_ioxs_extension), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ioxs_res14,
+ { "Reserved", "pn_io.ioxs.res14",
+ FT_UINT8, BASE_HEX, NULL, 0x1E,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ioxs_instance,
+ { "Instance", "pn_io.ioxs.instance",
+ FT_UINT8, BASE_HEX, VALS(pn_io_ioxs_instance), 0x60,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ioxs_datastate,
+ { "DataState", "pn_io.ioxs.datastate",
+ FT_UINT8, BASE_HEX, VALS(pn_io_ioxs_datastate), 0x80,
+ NULL, HFILL }
+ },
+ /* PROFIsafe parameter */
+ /* Status Byte & Control Byte for PROFIsafe --- dissector handle */
+ { &hf_pn_io_ps_sb,
+ { "Status Byte", "pn_io.ps.sb",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_toggelBitChanged,
+ { "Status Byte", "pn_io.ps.sb.toggle_d_changed",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_toggelBitChange_slot_nr,
+ { "Slot_Number", "pn_io.ps.sb.toggle_d_changed.slot",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_toggelBitChange_subslot_nr,
+ { "Sub_Slot_Number", "pn_io.ps.sb.toggle_d_changed.subslot",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb,
+ { "Control Byte", "pn_io.ps.cb",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_toggelBitChanged,
+ { "Control Byte", "pn_io.ps.cb.toggle_h_changed",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_toggelBitChange_slot_nr,
+ { "Slot_Number", "pn_io.ps.cb.toggle_h_changed.slot",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_toggelBitChange_subslot_nr,
+ { "Sub_Slot_Number", "pn_io.ps.cb.toggle_h_changed.subslot",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ /* Structures for dissecting Status Byte & Control Byte PROFIsafe ---dissector details */
+ { &hf_pn_io_ps_sb_iparOK,
+ { "iPar_OK - F-Device has new iParameter values assigned", "pn_io.ps.sb.iPar_OK",
+ FT_UINT8, BASE_HEX, NULL, 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_DeviceFault,
+ { "Device_Fault - Failure exists in F-Device or F-Module", "pn_io.ps.sb.DeviceFault",
+ FT_UINT8, BASE_HEX, NULL, 0x02,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_CECRC,
+ { "CE_CRC - CRC Communication fault", "pn_io.ps.sb.CE_CRC",
+ FT_UINT8, BASE_HEX, NULL, 0x04,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_WDtimeout,
+ { "WD_timeout - WatchDog timeout Communication fault", "pn_io.ps.sb.WD_timeout",
+ FT_UINT8, BASE_HEX, NULL, 0x08,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_FVactivated,
+ { "FV_activated - Fail-safe values (FV) activated", "pn_io.ps.sb.FV_activated",
+ FT_UINT8, BASE_HEX, NULL, 0x10,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_Toggle_d,
+ { "Toggle_d - Device-based Toggle Bit", "pn_io.ps.sb.Toggle_d",
+ FT_UINT8, BASE_HEX, NULL, 0x20,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_ConsNr_reset,
+ { "cons_nr_R - F-Device has reset its consecutive number counter", "pn_io.ps.sb.cons_nr_R",
+ FT_UINT8, BASE_HEX, NULL, 0x40,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_sb_res,
+ { "Bit7 - reserved for future releases", "pn_io.ps.sb.bit7",
+ FT_UINT8, BASE_HEX, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_iparEN,
+ { "iPar_EN - iParameter assignment deblocked", "pn_io.ps.cb.iparEN",
+ FT_UINT8, BASE_HEX, NULL, 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_OAReq,
+ { "OA_Req - Operator acknowledge requested", "pn_io.ps.cb.OA_Req",
+ FT_UINT8, BASE_HEX, NULL, 0x02,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_resetConsNr,
+ { "R_cons_nr - Set the Virtual Consecutive Number within the F-Device to be \"0\"", "pn_io.ps.cb.R_cons_nr",
+ FT_UINT8, BASE_HEX, NULL, 0x04,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_useTO2,
+ { "Bit3 - Reserved or Use the secondary watchdog (Use_TO2)", "pn_io.ps.cb.bit3",
+ FT_UINT8, BASE_HEX, NULL, 0x08,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_activateFV,
+ { "activate_FV - Fail-safe values (FV) to be activated", "pn_io.ps.cb.activate_FV",
+ FT_UINT8, BASE_HEX, NULL, 0x10,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_Toggle_h,
+ { "Toggle_h - Host-based Toggle Bit", "pn_io.ps.cb.Toggle_h",
+ FT_UINT8, BASE_HEX, NULL, 0x20,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_Chf_ACK,
+ { "Bit6 - Reserved or Operator acknowledge after cleared channel fault (ChF_Ack)", "pn_io.ps.cb.bit6",
+ FT_UINT8, BASE_HEX, NULL, 0x40,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_cb_loopcheck,
+ { "Bit7 - Reserved or Loop-back check (Loopcheck, shall be set to 1)", "pn_io.ps.cb.bit7",
+ FT_UINT8, BASE_HEX, NULL, 0x80,
+ NULL, HFILL }
+ },
+ /* PROFIsafe */
+ { &hf_pn_io_ps_f_dest_adr,
+ { "F_Dest_Add", "pn_io.ps.f_dest_add",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_ps_f_data,
+ { "SafetyIO Data", "pn_io.ps.f_data",
+ FT_UINT64, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_status,
+ { "Status", "pn_io.pa.status",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_status_quality,
+ { "Quality", "pn_io.pa.status.quality",
+ FT_UINT8, BASE_HEX, VALS(pn_pa_profile_status_quality), 0xC0,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_status_substatus_bad,
+ { "Substatus", "pn_io.pa.status.substatus",
+ FT_UINT8, BASE_HEX, VALS(pn_pa_profile_status_substatus_bad), 0x3C,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_status_substatus_uncertain,
+ { "Substatus", "pn_io.pa.status.substatus",
+ FT_UINT8, BASE_HEX, VALS(pn_pa_profile_status_substatus_uncertain), 0x3C,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_status_substatus_good,
+ { "Substatus", "pn_io.pa.status.substatus",
+ FT_UINT8, BASE_HEX, VALS(pn_pa_profile_status_substatus_good), 0x3C,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_status_update_event,
+ { "Update Event", "pn_io.pa.status.update",
+ FT_UINT8, BASE_HEX, VALS(pn_pa_profile_status_update_event), 0x02,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_status_simulate,
+ { "Simulate", "pn_io.pa.status.simulate",
+ FT_UINT8, BASE_HEX, VALS(pn_pa_profile_status_simulate), 0x01,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_value_8bit,
+ { "Value", "pn_io.pa.value",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_value_16bit,
+ { "Value", "pn_io.pa.value",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_pa_profile_value_float,
+ { "Value", "pn_io.pa.value.float",
+ FT_FLOAT, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ };
+
+ static gint *ett[] = {
+ &ett_pn_io_rtc,
+ &ett_pn_io_ioxs,
+ &ett_pn_io_io_data_object,
+ &ett_pn_pa_profile_status
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_pn_io_too_many_data_objects, { "pn_io.too_many_data_objects", PI_MALFORMED, PI_ERROR, "Too many data objects", EXPFILL }},
+ };
+
+ expert_module_t* expert_pn_io;
+
+ proto_pn_io_rtc1 = proto;
+ proto_register_field_array(proto, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ expert_pn_io = expert_register_protocol(proto_pn_io_rtc1);
+ expert_register_field_array(expert_pn_io, ei, array_length(ei));
+}
+
+
+/*
+* Editor modelines - https://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* vi: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/plugins/epan/profinet/packet-pn.c b/plugins/epan/profinet/packet-pn.c
new file mode 100644
index 0000000..9bdbc3c
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn.c
@@ -0,0 +1,1518 @@
+/* packet-pn.c
+ * Common functions for other PROFINET protocols like IO, CBA, DCP, ...
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+
+#include "config.h"
+
+#include <string.h>
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <epan/wmem_scopes.h>
+#include <epan/dissectors/packet-dcerpc.h>
+
+#include "packet-pn.h"
+
+static int hf_pn_padding = -1;
+static int hf_pn_undecoded_data = -1;
+static int hf_pn_user_data = -1;
+static int hf_pn_user_bytes = -1;
+static int hf_pn_frag_bytes = -1;
+static int hf_pn_malformed = -1;
+
+static int hf_pn_io_status = -1;
+
+static int hf_pn_io_error_code = -1;
+static int hf_pn_io_error_decode = -1;
+static int hf_pn_io_error_code1 = -1;
+static int hf_pn_io_error_code1_pniorw = -1;
+static int hf_pn_io_error_code1_pnio = -1;
+static int hf_pn_io_error_code2 = -1;
+static int hf_pn_io_error_code2_pniorw = -1;
+static int hf_pn_io_error_code2_pnio_1 = -1;
+static int hf_pn_io_error_code2_pnio_2 = -1;
+static int hf_pn_io_error_code2_pnio_3 = -1;
+static int hf_pn_io_error_code2_pnio_4 = -1;
+static int hf_pn_io_error_code2_pnio_5 = -1;
+static int hf_pn_io_error_code2_pnio_6 = -1;
+static int hf_pn_io_error_code2_pnio_7 = -1;
+static int hf_pn_io_error_code2_pnio_8 = -1;
+static int hf_pn_io_error_code2_pnio_13 = -1;
+static int hf_pn_io_error_code2_pnio_20 = -1;
+static int hf_pn_io_error_code2_pnio_21 = -1;
+static int hf_pn_io_error_code2_pnio_22 = -1;
+static int hf_pn_io_error_code2_pnio_23 = -1;
+static int hf_pn_io_error_code2_pnio_40 = -1;
+static int hf_pn_io_error_code2_pnio_60 = -1;
+static int hf_pn_io_error_code2_pnio_61 = -1;
+static int hf_pn_io_error_code2_pnio_62 = -1;
+static int hf_pn_io_error_code2_pnio_63 = -1;
+static int hf_pn_io_error_code2_pnio_64 = -1;
+static int hf_pn_io_error_code2_pnio_65 = -1;
+static int hf_pn_io_error_code2_pnio_66 = -1;
+static int hf_pn_io_error_code2_pnio_70 = -1;
+static int hf_pn_io_error_code2_pnio_71 = -1;
+static int hf_pn_io_error_code2_pnio_72 = -1;
+static int hf_pn_io_error_code2_pnio_73 = -1;
+static int hf_pn_io_error_code2_pnio_74 = -1;
+static int hf_pn_io_error_code2_pnio_75 = -1;
+static int hf_pn_io_error_code2_pnio_76 = -1;
+static int hf_pn_io_error_code2_pnio_77 = -1;
+static int hf_pn_io_error_code2_pnio_253 = -1;
+static int hf_pn_io_error_code2_pnio_255 = -1;
+
+static gint ett_pn_io_status = -1;
+
+static expert_field ei_pn_undecoded_data = EI_INIT;
+static expert_field ei_pn_io_error_code1 = EI_INIT;
+static expert_field ei_pn_io_error_code2 = EI_INIT;
+
+static const value_string pn_io_error_code[] = {
+ { 0x00, "OK" },
+ { 0x81, "PNIO" },
+ { 0xCF, "RTA error" },
+ { 0xDA, "AlarmAck" },
+ { 0xDB, "IODConnectRes" },
+ { 0xDC, "IODReleaseRes" },
+ { 0xDD, "IODControlRes" },
+ { 0xDE, "IODReadRes" },
+ { 0xDF, "IODWriteRes" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_decode[] = {
+ { 0x00, "OK" },
+ { 0x80, "PNIORW" },
+ { 0x81, "PNIO" },
+ { 0, NULL }
+};
+
+/* dummy for unknown decode */
+static const value_string pn_io_error_code1[] = {
+ { 0x00, "OK" },
+ { 0, NULL }
+};
+
+/* dummy for unknown decode/code1 combination */
+static const value_string pn_io_error_code2[] = {
+ { 0x00, "OK" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code1_pniorw[] = {
+ /* high nibble 0-9 not specified -> legacy codes */
+ { 0xa0, "application: read error" },
+ { 0xa1, "application: write error" },
+ { 0xa2, "application: module failure" },
+ { 0xa3, "application: not specified" },
+ { 0xa4, "application: not specified" },
+ { 0xa5, "application: not specified" },
+ { 0xa6, "application: not specified" },
+ { 0xa7, "application: busy" },
+ { 0xa8, "application: version conflict" },
+ { 0xa9, "application: feature not supported" },
+ { 0xaa, "application: User specific 1" },
+ { 0xab, "application: User specific 2" },
+ { 0xac, "application: User specific 3" },
+ { 0xad, "application: User specific 4" },
+ { 0xae, "application: User specific 5" },
+ { 0xaf, "application: User specific 6" },
+ { 0xb0, "access: invalid index" },
+ { 0xb1, "access: write length error" },
+ { 0xb2, "access: invalid slot/subslot" },
+ { 0xb3, "access: type conflict" },
+ { 0xb4, "access: invalid area" },
+ { 0xb5, "access: state conflict" },
+ { 0xb6, "access: access denied" },
+ { 0xb7, "access: invalid range" },
+ { 0xb8, "access: invalid parameter" },
+ { 0xb9, "access: invalid type" },
+ { 0xba, "access: backup" },
+ { 0xbb, "access: User specific 7" },
+ { 0xbc, "access: User specific 8" },
+ { 0xbd, "access: User specific 9" },
+ { 0xbe, "access: User specific 10" },
+ { 0xbf, "access: User specific 11" },
+ { 0xc0, "resource: read constrain conflict" },
+ { 0xc1, "resource: write constrain conflict" },
+ { 0xc2, "resource: resource busy" },
+ { 0xc3, "resource: resource unavailable" },
+ { 0xc4, "resource: not specified" },
+ { 0xc5, "resource: not specified" },
+ { 0xc6, "resource: not specified" },
+ { 0xc7, "resource: not specified" },
+ { 0xc8, "resource: User specific 12" },
+ { 0xc9, "resource: User specific 13" },
+ { 0xca, "resource: User specific 14" },
+ { 0xcb, "resource: User specific 15" },
+ { 0xcc, "resource: User specific 16" },
+ { 0xcd, "resource: User specific 17" },
+ { 0xce, "resource: User specific 18" },
+ { 0xcf, "resource: User specific 19" },
+ /* high nibble d-f user specific */
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pniorw[] = {
+ /* all values are user specified */
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code1_pnio[] = {
+ { 0x00 /* 0*/, "Reserved" },
+ { 0x01 /* 1*/, "Connect: Faulty ARBlockReq" },
+ { 0x02 /* 2*/, "Connect: Faulty IOCRBlockReq" },
+ { 0x03 /* 3*/, "Connect: Faulty ExpectedSubmoduleBlockReq" },
+ { 0x04 /* 4*/, "Connect: Faulty AlarmCRBlockReq" },
+ { 0x05 /* 5*/, "Connect: Faulty PrmServerBlockReq" },
+ { 0x06 /* 6*/, "Connect: Faulty MCRBlockReq" },
+ { 0x07 /* 7*/, "Connect: Faulty ARRPCBlockReq" },
+ { 0x08 /* 8*/, "Read/Write Record: Faulty Record" },
+ { 0x09 /* 9*/, "Connect: Faulty IRInfoBlock" },
+ { 0x0A /* 10*/, "Connect: Faulty SRInfoBlock" },
+ { 0x0B /* 11*/, "Connect: Faulty ARFSUBlock" },
+ { 0x0C /* 12*/, "Connect: Faulty ARVendorBlockReq" },
+ { 0x0D /* 13*/, "Connect: Faulty RSInfoBlock" },
+ { 0x14 /* 20*/, "IODControl: Faulty ControlBlockConnect" },
+ { 0x15 /* 21*/, "IODControl: Faulty ControlBlockPlug" },
+ { 0x16 /* 22*/, "IOXControl: Faulty ControlBlock after a connect est." },
+ { 0x17 /* 23*/, "IOXControl: Faulty ControlBlock a plug alarm" },
+ { 0x18 /* 24*/, "IOXControl: Faulty ControlBlockPrmBegin" },
+ { 0x19 /* 25*/, "IOXControl: Faulty SubmoduleListBlock" },
+
+ { 0x28 /* 40*/, "Release: Faulty ReleaseBlock" },
+
+ { 0x32 /* 50*/, "Response: Faulty ARBlockRes" },
+ { 0x33 /* 51*/, "Response: Faulty IOCRBlockRes" },
+ { 0x34 /* 52*/, "Response: Faulty AlarmCRBlockRes" },
+ { 0x35 /* 53*/, "Response: Faulty ModuleDifflock" },
+ { 0x36 /* 54*/, "Response: Faulty ARRPCBlockRes" },
+ { 0x37 /* 55*/, "Response: Faulty ARServerBlockRes" },
+ { 0x38 /* 56*/, "Response: Faulty ARVendorBlockRes" },
+
+ { 0x3c /* 60*/, "AlarmAck Error Codes" },
+ { 0x3d /* 61*/, "CMDEV" },
+ { 0x3e /* 62*/, "CMCTL" },
+ { 0x3f /* 63*/, "CTLDINA" },
+ { 0x40 /* 64*/, "CMRPC" },
+ { 0x41 /* 65*/, "ALPMI" },
+ { 0x42 /* 66*/, "ALPMR" },
+ { 0x43 /* 67*/, "LMPM" },
+ { 0x44 /* 68*/, "MAC" },
+ { 0x45 /* 69*/, "RPC" },
+ { 0x46 /* 70*/, "APMR" },
+ { 0x47 /* 71*/, "APMS" },
+ { 0x48 /* 72*/, "CPM" },
+ { 0x49 /* 73*/, "PPM" },
+ { 0x4a /* 74*/, "DCPUCS" },
+ { 0x4b /* 75*/, "DCPUCR" },
+ { 0x4c /* 76*/, "DCPMCS" },
+ { 0x4d /* 77*/, "DCPMCR" },
+ { 0x4e /* 78*/, "FSPM" },
+ { 0x4f /* 79*/, "RSI" },
+ { 0x50 /* 80*/, "RSIR" },
+
+ { 0x64 /*100*/, "CTLSM" },
+ { 0x65 /*101*/, "CTLRDI" },
+ { 0x66 /*102*/, "CTLRDR" },
+ { 0x67 /*103*/, "CTLWRI" },
+ { 0x68 /*104*/, "CTLWRR" },
+ { 0x69 /*105*/, "CTLIO" },
+ { 0x6a /*106*/, "CTLSU" },
+ { 0x6b /*107*/, "CTLRPC" },
+ { 0x6c /*108*/, "CTLBE" },
+ { 0x6d /*109*/, "CTLSRL" },
+ { 0x6e /*110*/, "NME" },
+ { 0x6f /*111*/, "TDE" },
+ { 0x70 /*112*/, "PCE" },
+ { 0x71 /*113*/, "NCE" },
+ { 0x72 /*114*/, "NUE" },
+ { 0x73 /*115*/, "BNME" },
+ { 0x74 /*116*/, "CTLSAM" },
+
+ { 0xc8 /*200*/, "CMSM" },
+ { 0xca /*202*/, "CMRDR" },
+ { 0xcc /*204*/, "CMWRR" },
+ { 0xcd /*205*/, "CMIO" },
+ { 0xce /*206*/, "CMSU" },
+ { 0xd0 /*208*/, "CMINA" },
+ { 0xd1 /*209*/, "CMPBE" },
+ { 0xd2 /*210*/, "CMSRL" },
+ { 0xd3 /*211*/, "CMDMC" },
+ { 0xd4 /*212*/, "CMSAM" },
+
+ { 0xfd /*253*/, "RTA_ERR_CLS_PROTOCOL" },
+ { 0xff /*255*/, "User specific" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_1[] = {
+ /* CheckingRules for ARBlockReq */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter ARType" },
+ { 5, "Error in Parameter ARUUID" },
+ { 7, "Error in Parameter CMInitiatorMACAddress" },
+ { 8, "Error in Parameter CMInitiatorObjectUUID" },
+ { 9, "Error in Parameter ARProperties" },
+ { 10, "Error in Parameter CMInitiatorActivityTimeoutFactor" },
+ { 11, "Error in Parameter InitiatorUDPRTPort" },
+ { 12, "Error in Parameter StationNameLength" },
+ { 13, "Error in Parameter CMInitiatorStationName" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_2[] = {
+ /* CheckingRules for IOCRBlockReq */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter IOCRType" },
+ { 5, "Error in Parameter IOCRReference" },
+ { 6, "Error in Parameter LT" },
+ { 7, "Error in Parameter IOCRProperties" },
+ { 8, "Error in Parameter DataLength" },
+ { 9, "Error in Parameter FrameID" },
+ { 10, "Error in Parameter SendClockFactor" },
+ { 11, "Error in Parameter ReductionRatio" },
+ { 12, "Error in Parameter Phase" },
+ { 14, "Error in Parameter FrameSendOffset" },
+ { 15, "Error in Parameter WatchdogFactor" },
+ { 16, "Error in Parameter DataHoldFactor" },
+ { 17, "Error in Parameter IOCRTagHeader" },
+ { 18, "Error in Parameter IOCRMulticastMacAddress" },
+ { 19, "Error in Parameter NumberOfAPI" },
+ { 20, "Error in Parameter API" },
+ { 21, "Error in Parameter NumberOfIODataObjects" },
+ { 22, "Error in Parameter SlotNumber" },
+ { 23, "Error in Parameter SubslotNumber" },
+ { 24, "Error in Parameter IODataObjectFrameOffset" },
+ { 25, "Error in Parameter NumberOfIOCS" },
+ { 26, "Error in Parameter SlotNumber" },
+ { 27, "Error in Parameter SubslotNumber" },
+ { 28, "Error in Parameter IOCSFrameOffset" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_3[] = {
+ /* CheckingRules for ExpectedSubmoduleBlockReq */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter NumberOfAPI" },
+ { 5, "Error in Parameter API" },
+ { 6, "Error in Parameter SlotNumber" },
+ { 7, "Error in Parameter ModuleIdentNumber" },
+ { 8, "Error in Parameter ModuleProperties" },
+ { 9, "Error in Parameter NumberOfSubmodules" },
+ { 10, "Error in Parameter SubslotNumber" },
+ { 12, "Error in Parameter SubmoduleProperties" },
+ { 13, "Error in Parameter DataDescription" },
+ { 14, "Error in Parameter SubmoduleDataLength" },
+ { 15, "Error in Parameter LengthIOPS" },
+ { 16, "Error in Parameter LengthIOCS" },
+ { 0, NULL }
+};
+
+
+static const value_string pn_io_error_code2_pnio_4[] = {
+ /* CheckingRules for AlarmCRBlockReq */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter AlarmCRType" },
+ { 5, "Error in Parameter LT" },
+ { 6, "Error in Parameter AlarmCRProperties" },
+ { 7, "Error in Parameter RTATimeoutFactor" },
+ { 8, "Error in Parameter RTARetries" },
+ { 10, "Error in Parameter MaxAlarmDataLength" },
+ { 11, "Error in Parameter AlarmCRTagHeaderHigh" },
+ { 12, "Error in Parameter AlarmCRTagHeaderLow" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_5[] = {
+ /* CheckingRules for PrmServerBlockReq */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 6, "Error in Parameter CMInitiatorActivityTimeoutFactor" },
+ { 7, "Error in Parameter StationNameLength" },
+ { 8, "Error in Parameter ParameterServerStationName" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_6[] = {
+ /* CheckingRules for MCRBlockReq */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter IOCRReference" },
+ { 5, "Error in Parameter AddressResolutionProperties" },
+ { 6, "Error in Parameter MCITimeoutFactor" },
+ { 7, "Error in Parameter StationNameLength" },
+ { 8, "Error in Parameter ProviderStationName" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_7[] = {
+ /* CheckingRules for MCRBlockReq */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter InitiatorRPCServerPort" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_8[] = {
+ /* CheckingRules for Read/Write ParameterReqHeader */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 5, "Error in Parameter ARUUID" },
+ { 6, "Error in Parameter API" },
+ { 7, "Error in Parameter SlotNumber" },
+ { 8, "Error in Parameter SubslotNumber" },
+ { 9, "Error in Parameter Padding" },
+ { 10, "Error in Parameter Index" },
+ { 11, "Error in Parameter RecordDataLength" },
+ { 12, "Error in Parameter TargetARUUID" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_13[] = {
+ /* CheckingRules for RSInfoBlock */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter Padding" },
+ { 5, "Error in Parameter RSProperties" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_20[] = {
+ /* CheckingRules for ControlBlockConnect */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter Padding" },
+ { 6, "Error in Parameter SessionKey" },
+ { 7, "Error in Parameter Padding" },
+ { 8, "Error in Parameter ControlCommand" },
+ { 9, "Error in Parameter ControlBlockProperties" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_21[] = {
+ /* CheckingRules for ControlBlockPlug */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter Padding" },
+ { 6, "Error in Parameter SessionKey" },
+ { 7, "Error in Parameter AlarmSequenceNumber" },
+ { 8, "Error in Parameter ControlCommand" },
+ { 9, "Error in Parameter ControlBlockProperties" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_22[] = {
+ /* CheckingRule for ControlBlockConnect */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter Padding" },
+ { 6, "Error in Parameter SessionKey" },
+ { 7, "Error in Parameter Padding" },
+ { 8, "Error in Parameter ControlCommand" },
+ { 9, "Error in Parameter ControlBlockProperties" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_23[] = {
+ /* CheckingRules for ControlBlockPlug */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter Padding" },
+ { 6, "Error in Parameter SessionKey" },
+ { 7, "Error in Parameter AlarmSequenceNumber" },
+ { 8, "Error in Parameter ControlCommand" },
+ { 9, "Error in Parameter ControlBlockProperties" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_40[] = {
+ /* CheckingRules for ReleaseBlock */
+ { 0, "Error in Parameter BlockType" },
+ { 1, "Error in Parameter BlockLength" },
+ { 2, "Error in Parameter BlockVersionHigh" },
+ { 3, "Error in Parameter BlockVersionLow" },
+ { 4, "Error in Parameter Padding" },
+ { 6, "Error in Parameter SessionKey" },
+ { 7, "Error in Parameter Padding" },
+ { 8, "Error in Parameter ControlCommand" },
+ { 9, "Error in Parameter ControlBlockProperties" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_60[] = {
+ /* AlarmAck Error Codes */
+ { 0, "Alarm Type Not Supported" },
+ { 1, "Wrong Submodule State" },
+ { 2, "IOCARSR Backup - Alarm not executed" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_61[] = {
+ /* CMDEV */
+ { 0, "State Conflict" },
+ { 1, "Resources" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_62[] = {
+ /* CMCTL */
+ { 0, "State Conflict" },
+ { 1, "Timeout" },
+ { 2, "No data send" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_63[] = {
+ /* NRPM */
+ { 0, "No DCP active" },
+ { 1, "DNS Unknown_RealStationName" },
+ { 2, "DCP No_RealStationName" },
+ { 3, "DCP Multiple_RealStationName" },
+ { 4, "DCP No_StationName" },
+ { 5, "No_IP_Addr" },
+ { 6, "DCP_Set_Error" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_64[] = {
+ /* RMPM */
+ { 0, "ArgsLength invalid" },
+ { 1, "Unknown Blocks" },
+ { 2, "IOCR Missing" },
+ { 3, "Wrong AlarmCRBlock count" },
+ { 4, "Out of AR Resources" },
+ { 5, "AR UUID unknown" },
+ { 6, "State conflict" },
+ { 7, "Out of Provider, Consumer or Alarm Resources" },
+ { 8, "Out of Memory" },
+ { 9, "Pdev already owned" },
+ { 10, "ARset State conflict during connection establishment" },
+ { 11, "ARset Parameter conflict during connection establishment" },
+ { 12, "Pdev, port(s) without interface" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_65[] = {
+ /* ALPMI */
+ { 0, "Invalid State" },
+ { 1, "Wrong ACK-PDU" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_66[] = {
+ /* ALPMR */
+ { 0, "Invalid State" },
+ { 1, "Wrong Notification PDU" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_70[] = {
+ /* APMR */
+ { 0, "Invalid State" },
+ { 1, "LMPM signaled error" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_71[] = {
+ /* APMS */
+ { 0, "Invalid State" },
+ { 1, "LMPM signaled error" },
+ { 2, "Timeout" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_72[] = {
+ /* CPM */
+ { 1, "Invalid State" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_73[] = {
+ /* PPM */
+ { 1, "Invalid State" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_74[] = {
+ /* DCPUCS */
+ { 0, "Invalid State" },
+ { 1, "LMPM signaled an error" },
+ { 2, "Timeout" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_75[] = {
+ /* DCPUCR */
+ { 0, "Invalid State" },
+ { 1, "LMPM signaled an error" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_76[] = {
+ /* DCPMCS */
+ { 0, "Invalid State" },
+ { 1, "LMPM signaled an error" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_77[] = {
+ /* DCPMCR */
+ { 0, "Invalid State" },
+ { 1, "LMPM signaled an error" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_253[] = {
+ { 0, "reserved" },
+ { 1, "Error within the coordination of sequence numbers (RTA_ERR_CODE_SEQ) error" },
+ { 2, "Instance closed (RTA_ERR_ABORT)" },
+ { 3, "AR out of memory (RTA_ERR_ABORT)" },
+ { 4, "AR add provider or consumer failed (RTA_ERR_ABORT)" },
+ { 5, "AR consumer DHT/WDT expired (RTA_ERR_ABORT)" },
+ { 6, "AR cmi timeout (RTA_ERR_ABORT)" },
+ { 7, "AR alarm-open failed (RTA_ERR_ABORT)" },
+ { 8, "AR alarm-send.cnf(-) (RTA_ERR_ABORT)" },
+ { 9, "AR alarm-ack-send.cnf(-) (RTA_ERR_ABORT)" },
+ { 10, "AR alarm data too long (RTA_ERR_ABORT)" },
+ { 11, "AR alarm.ind(err) (RTA_ERR_ABORT)" },
+ { 12, "AR rpc-client call.cnf(-) (RTA_ERR_ABORT)" },
+ { 13, "AR abort.req (RTA_ERR_ABORT)" },
+ { 14, "AR re-run aborts existing (RTA_ERR_ABORT)" },
+ { 15, "AR release.ind received (RTA_ERR_ABORT)" },
+ { 16, "AR device deactivated (RTA_ERR_ABORT)" },
+ { 17, "AR removed (RTA_ERR_ABORT)" },
+ { 18, "AR protocol violation (RTA_ERR_ABORT)" },
+ { 19, "AR name resolution error (RTA_ERR_ABORT)" },
+ { 20, "AR RPC-Bind error (RTA_ERR_ABORT)" },
+ { 21, "AR RPC-Connect error (RTA_ERR_ABORT)" },
+ { 22, "AR RPC-Read error (RTA_ERR_ABORT)" },
+ { 23, "AR RPC-Write error (RTA_ERR_ABORT)" },
+ { 24, "AR RPC-Control error (RTA_ERR_ABORT)" },
+ { 25, "AR forbidden pull or plug after check.rsp and before in-data.ind (RTA_ERR_ABORT)" },
+ { 26, "AR AP removed (RTA_ERR_ABORT)" },
+ { 27, "AR link down (RTA_ERR_ABORT)" },
+ { 28, "AR could not register multicast-mac address (RTA_ERR_ABORT)" },
+ { 29, "not synchronized (cannot start companion-ar) (RTA_ERR_ABORT)" },
+ { 30, "wrong topology (cannot start companion-ar) (RTA_ERR_ABORT)" },
+ { 31, "dcp, station-name changed (RTA_ERR_ABORT)" },
+ { 32, "dcp, reset to factory-settings (RTA_ERR_ABORT)" },
+ { 33, "cannot start companion-AR because a 0x8ipp submodule in the first AR... (RTA_ERR_ABORT)" },
+ { 34, "no irdata record yet (RTA_ERR_ABORT)" },
+ { 35, "PDEV (RTA_ERROR_ABORT)" },
+ { 36, "PDEV, no port offers required speed/duplexity (RTA_ERROR_ABORT)" },
+ { 37, "IP-Suite [of the IOC] changed by means of DCP_Set(IPParameter) or local engineering (RTA_ERROR_ABORT)" },
+ { 38, "IOCARSR, RDHT expired" },
+ { 39, "IOCARSR, Pdev, parameterization impossible" },
+ { 40, "Remote application ready timeout expired" },
+ { 41, "IOCARSR, Redundant interface list or access to the peripherals impossible" },
+ { 42, "IOCARSR, MTOT expired" },
+ { 43, "IOCARSR, AR protocol violation" },
+ { 44, "PDEV, plug port without CombinedObjectContainer" },
+ { 45, "NME, no or wrong configuration" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code2_pnio_255[] = {
+ /* User specific */
+ { 255, "User abort" },
+ { 0, NULL }
+};
+
+
+/* Initialize PNIO RTC1 stationInfo memory */
+void
+init_pnio_rtc1_station(stationInfo *station_info) {
+ station_info->iocs_data_in = wmem_list_new(wmem_file_scope());
+ station_info->iocs_data_out = wmem_list_new(wmem_file_scope());
+ station_info->ioobject_data_in = wmem_list_new(wmem_file_scope());
+ station_info->ioobject_data_out = wmem_list_new(wmem_file_scope());
+ station_info->diff_module = wmem_list_new(wmem_file_scope());
+}
+
+/* dissect an 8 bit unsigned integer */
+int
+dissect_pn_uint8(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, guint8 *pdata)
+{
+ guint8 data;
+
+ data = tvb_get_guint8 (tvb, offset);
+ proto_tree_add_uint(tree, hfindex, tvb, offset, 1, data);
+ if (pdata)
+ *pdata = data;
+ return offset + 1;
+}
+
+/* dissect a 16 bit unsigned integer; return the item through a pointer as well */
+int
+dissect_pn_uint16_ret_item(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, guint16 *pdata, proto_item ** new_item)
+{
+ guint16 data;
+ proto_item *item = NULL;
+
+ data = tvb_get_ntohs (tvb, offset);
+
+ item = proto_tree_add_uint(tree, hfindex, tvb, offset, 2, data);
+ if (pdata)
+ *pdata = data;
+ if (new_item)
+ *new_item = item;
+ return offset + 2;
+}
+
+/* dissect a 16 bit unsigned integer */
+int
+dissect_pn_uint16(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, guint16 *pdata)
+{
+ guint16 data;
+
+ data = tvb_get_ntohs (tvb, offset);
+
+ proto_tree_add_uint(tree, hfindex, tvb, offset, 2, data);
+ if (pdata)
+ *pdata = data;
+ return offset + 2;
+}
+
+/* dissect a 16 bit signed integer */
+int
+dissect_pn_int16(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, gint16 *pdata)
+{
+ gint16 data;
+
+ data = tvb_get_ntohs (tvb, offset);
+
+ proto_tree_add_int(tree, hfindex, tvb, offset, 2, data);
+ if (pdata)
+ *pdata = data;
+ return offset + 2;
+}
+
+/* dissect a 24bit OUI (IEC organizational unique id) */
+int
+dissect_pn_oid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, guint32 *pdata)
+{
+ guint32 data;
+
+ data = tvb_get_ntoh24(tvb, offset);
+
+ proto_tree_add_uint(tree, hfindex, tvb, offset, 3, data);
+ if (pdata)
+ *pdata = data;
+ return offset + 3;
+}
+
+/* dissect a 6 byte MAC address */
+int
+dissect_pn_mac(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, guint8 *pdata)
+{
+ guint8 data[6];
+
+ tvb_memcpy(tvb, data, offset, 6);
+ proto_tree_add_ether(tree, hfindex, tvb, offset, 6, data);
+
+ if (pdata)
+ memcpy(pdata, data, 6);
+
+ return offset + 6;
+}
+
+/* dissect an IPv4 address */
+int
+dissect_pn_ipv4(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, guint32 *pdata)
+{
+ guint32 data;
+
+ data = tvb_get_ipv4(tvb, offset);
+ proto_tree_add_ipv4(tree, hfindex, tvb, offset, 4, data);
+
+ if (pdata)
+ *pdata = data;
+
+ return offset + 4;
+}
+
+/* dissect a 16 byte UUID address */
+int
+dissect_pn_uuid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, e_guid_t *uuid)
+{
+ guint8 drep[2] = { 0,0 };
+
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hfindex, uuid);
+
+ return offset;
+}
+
+/* "dissect" some bytes still undecoded (with Expert warning) */
+int
+dissect_pn_undecoded(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 length)
+{
+ proto_item *item;
+
+
+ item = proto_tree_add_string_format(tree, hf_pn_undecoded_data, tvb, offset, length, "data",
+ "Undecoded Data: %d bytes", length);
+
+ expert_add_info_format(pinfo, item, &ei_pn_undecoded_data,
+ "Undecoded Data, %u bytes", length);
+
+ return offset + length;
+}
+
+/* "dissect" some user bytes */
+int
+dissect_pn_user_data_bytes(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 length, int iSelect)
+{
+ if(iSelect == FRAG_DATA)
+ proto_tree_add_item(tree, hf_pn_frag_bytes, tvb, offset, length, ENC_NA);
+ else
+ proto_tree_add_item(tree, hf_pn_user_bytes, tvb, offset, length, ENC_NA);
+
+ return offset + length;
+}
+
+int
+dissect_pn_user_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 length, const char *text)
+{
+ if (length != 0) {
+ proto_tree_add_string_format(tree, hf_pn_user_data, tvb, offset, length, "data",
+ "%s: %d byte", text, length);
+ }
+ return offset + length;
+}
+
+/* packet is malformed, mark it as such */
+int
+dissect_pn_malformed(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 length)
+{
+ proto_tree_add_item(tree, hf_pn_malformed, tvb, 0, 10000, ENC_NA);
+
+ return offset + length;
+}
+
+
+/* dissect some padding data (with the given length) */
+int
+dissect_pn_padding(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, int length)
+{
+ proto_tree_add_string_format(tree, hf_pn_padding, tvb, offset, length, "data",
+ "Padding: %u byte", length);
+
+ return offset + length;
+}
+
+/* align offset to 4 */
+int
+dissect_pn_align4(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint padding = 0;
+
+
+ if (offset % 4) {
+ padding = 4 - (offset % 4);
+
+ proto_tree_add_string_format(tree, hf_pn_padding, tvb, offset, padding, "data",
+ "Padding: %u byte", padding);
+ }
+
+ return offset + padding;
+}
+
+/* dissect the four status (error) fields */
+int
+dissect_PNIO_status(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint8 u8ErrorCode;
+ guint8 u8ErrorDecode;
+ guint8 u8ErrorCode1;
+ guint8 u8ErrorCode2;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+ int bytemask = (drep[0] & DREP_LITTLE_ENDIAN) ? 3 : 0;
+
+ const value_string *error_code1_vals;
+ const value_string *error_code2_vals = pn_io_error_code2; /* defaults */
+
+
+
+ /* status */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_status, tvb, offset, 0, ENC_NA);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_status);
+ u32SubStart = offset;
+
+ /* the PNIOStatus field is existing in both the RPC and the application data,
+ * depending on the current PDU.
+ * As the byte representation of these layers are different, this has to be handled
+ * in a somewhat different way than elsewhere. */
+
+ dissect_dcerpc_uint8(tvb, offset + (0 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code, &u8ErrorCode);
+ dissect_dcerpc_uint8(tvb, offset + (1 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_decode, &u8ErrorDecode);
+
+ switch (u8ErrorDecode) {
+ case(0x80): /* PNIORW */
+ dissect_dcerpc_uint8(tvb, offset + (2 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code1_pniorw, &u8ErrorCode1);
+ error_code1_vals = pn_io_error_code1_pniorw;
+
+ /* u8ErrorCode2 for PNIORW is always user specific */
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pniorw, &u8ErrorCode2);
+
+ error_code2_vals = pn_io_error_code2_pniorw;
+
+ break;
+ case(0x81): /* PNIO */
+ dissect_dcerpc_uint8(tvb, offset + (2 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code1_pnio, &u8ErrorCode1);
+ error_code1_vals = pn_io_error_code1_pnio;
+
+ switch (u8ErrorCode1) {
+ case(1):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_1, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_1;
+ break;
+ case(2):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_2, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_2;
+ break;
+ case(3):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_3, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_3;
+ break;
+ case(4):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_4, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_4;
+ break;
+ case(5):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_5, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_5;
+ break;
+ case(6):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_6, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_6;
+ break;
+ case(7):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_7, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_7;
+ break;
+ case(8):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_8, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_8;
+ break;
+ case(13):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_13, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_13;
+ break;
+ case(20):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_20, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_20;
+ break;
+ case(21):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_21, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_21;
+ break;
+ case(22):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_22, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_22;
+ break;
+ case(23):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_23, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_23;
+ break;
+ case(40):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_40, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_40;
+ break;
+ case(60):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_60, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_60;
+ break;
+ case(61):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_61, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_61;
+ break;
+ case(62):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_62, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_62;
+ break;
+ case(63):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_63, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_63;
+ break;
+ case(64):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_64, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_64;
+ break;
+ case(65):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_65, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_65;
+ break;
+ case(66):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_66, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_66;
+ break;
+ case(70):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_70, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_70;
+ break;
+ case(71):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_71, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_71;
+ break;
+ case(72):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_72, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_72;
+ break;
+ case(73):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_73, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_73;
+ break;
+ case(74):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_74, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_74;
+ break;
+ case(75):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_75, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_75;
+ break;
+ case(76):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_76, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_76;
+ break;
+ case(77):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_77, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_77;
+ break;
+ case(253):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_253, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_253;
+ break;
+ case(255):
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2_pnio_255, &u8ErrorCode2);
+ error_code2_vals = pn_io_error_code2_pnio_255;
+ break;
+ default:
+ /* don't know this u8ErrorCode1 for PNIO, use defaults */
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2, &u8ErrorCode2);
+ expert_add_info_format(pinfo, sub_item, &ei_pn_io_error_code1, "Unknown ErrorCode1 0x%x (for ErrorDecode==PNIO)", u8ErrorCode1);
+ break;
+ }
+ break;
+ default:
+ dissect_dcerpc_uint8(tvb, offset + (2 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code1, &u8ErrorCode1);
+ if (u8ErrorDecode != 0) {
+ expert_add_info_format(pinfo, sub_item, &ei_pn_io_error_code1, "Unknown ErrorDecode 0x%x", u8ErrorDecode);
+ }
+ error_code1_vals = pn_io_error_code1;
+
+ /* don't know this u8ErrorDecode, use defaults */
+ dissect_dcerpc_uint8(tvb, offset + (3 ^ bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2, &u8ErrorCode2);
+ if (u8ErrorDecode != 0) {
+ expert_add_info_format(pinfo, sub_item, &ei_pn_io_error_code2, "Unknown ErrorDecode 0x%x", u8ErrorDecode);
+ }
+ }
+
+ offset += 4;
+
+ if ((u8ErrorCode == 0) && (u8ErrorDecode == 0) && (u8ErrorCode1 == 0) && (u8ErrorCode2 == 0)) {
+ proto_item_append_text(sub_item, ": OK");
+ col_append_str(pinfo->cinfo, COL_INFO, ", OK");
+ }
+ else {
+ proto_item_append_text(sub_item, ": Error: \"%s\", \"%s\", \"%s\", \"%s\"",
+ val_to_str(u8ErrorCode, pn_io_error_code, "(0x%x)"),
+ val_to_str(u8ErrorDecode, pn_io_error_decode, "(0x%x)"),
+ val_to_str(u8ErrorCode1, error_code1_vals, "(0x%x)"),
+ val_to_str(u8ErrorCode2, error_code2_vals, "(0x%x)"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Error: \"%s\", \"%s\", \"%s\", \"%s\"",
+ val_to_str(u8ErrorCode, pn_io_error_code, "(0x%x)"),
+ val_to_str(u8ErrorDecode, pn_io_error_decode, "(0x%x)"),
+ val_to_str(u8ErrorCode1, error_code1_vals, "(0x%x)"),
+ val_to_str(u8ErrorCode2, error_code2_vals, "(0x%x)"));
+ }
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+
+/* append the given info text to item and column */
+void
+pn_append_info(packet_info *pinfo, proto_item *dcp_item, const char *text)
+{
+ col_append_str(pinfo->cinfo, COL_INFO, text);
+
+ proto_item_append_text(dcp_item, "%s", text);
+}
+
+void pn_init_append_aruuid_frame_setup_list(e_guid_t aruuid, guint32 setup) {
+
+ ARUUIDFrame* aruuid_frame;
+
+ aruuid_frame = wmem_new0(wmem_file_scope(), ARUUIDFrame);
+ aruuid_frame->aruuid = aruuid;
+ aruuid_frame->setupframe = setup;
+ aruuid_frame->releaseframe = 0;
+ aruuid_frame->inputframe = 0;
+ aruuid_frame->outputframe = 0;
+
+ wmem_list_append(aruuid_frame_setup_list, aruuid_frame);
+}
+
+ARUUIDFrame* pn_find_aruuid_frame_setup(packet_info* pinfo) {
+
+ wmem_list_frame_t* aruuid_frame;
+ ARUUIDFrame* current_aruuid_frame = NULL;
+
+ if (aruuid_frame_setup_list != NULL) {
+ for (aruuid_frame = wmem_list_head(aruuid_frame_setup_list); aruuid_frame != NULL; aruuid_frame = wmem_list_frame_next(aruuid_frame)) {
+ current_aruuid_frame = (ARUUIDFrame*)wmem_list_frame_data(aruuid_frame);
+ if (current_aruuid_frame->setupframe == pinfo->num) {
+ break;
+ }
+ }
+ }
+
+ return current_aruuid_frame;
+}
+
+void pn_find_dcp_station_info(stationInfo* station_info, conversation_t* conversation) {
+ stationInfo* dcp_station_info = NULL;
+ /* search for DCP Station Info */
+ dcp_station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
+ if (dcp_station_info != NULL) {
+ if (dcp_station_info->typeofstation != NULL) {
+ if (station_info->typeofstation == NULL || strcmp(dcp_station_info->typeofstation, station_info->typeofstation) != 0) {
+ station_info->typeofstation = wmem_strdup(wmem_file_scope(), dcp_station_info->typeofstation);
+ }
+ }
+ if (dcp_station_info->nameofstation != NULL) {
+ if (station_info->nameofstation == NULL || strcmp(dcp_station_info->nameofstation, station_info->nameofstation) != 0) {
+ station_info->nameofstation = wmem_strdup(wmem_file_scope(), dcp_station_info->nameofstation);
+ }
+ }
+ if (dcp_station_info->u16Vendor_id != station_info->u16Vendor_id || dcp_station_info->u16Device_id != station_info->u16Device_id) {
+ station_info->u16Vendor_id = dcp_station_info->u16Vendor_id;
+ station_info->u16Device_id = dcp_station_info->u16Device_id;
+ }
+ }
+}
+
+
+void
+init_pn (int proto)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_padding,
+ { "Padding", "pn.padding",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_undecoded_data,
+ { "Undecoded Data", "pn.undecoded",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_user_data,
+ { "User Data", "pn.user_data",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_user_bytes,
+ { "Substitute Data", "pn.user_bytes",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_frag_bytes,
+ { "Fragment Data", "pn.frag_bytes",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_malformed,
+ { "Malformed", "pn_rt.malformed",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_status,
+ { "Status", "pn_io.status",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code,
+ { "ErrorCode", "pn_io.error_code",
+ FT_UINT8, BASE_HEX, VALS(pn_io_error_code), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_decode,
+ { "ErrorDecode", "pn_io.error_decode",
+ FT_UINT8, BASE_HEX, VALS(pn_io_error_decode), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code1,
+ { "ErrorCode1", "pn_io.error_code1",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code1), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code1_pniorw,
+ { "ErrorCode1", "pn_io.error_code1",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code1_pniorw), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pniorw,
+ { "ErrorCode2 for PNIORW is user specified!", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code1_pnio,
+ { "ErrorCode1", "pn_io.error_code1",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code1_pnio), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_1,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_1), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_2,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_2), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_3,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_3), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_4,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_4), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_5,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_5), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_6,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_6), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_7,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_7), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_8,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_8), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_13,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_13), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_20,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_20), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_21,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_21), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_22,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_22), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_23,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_23), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_40,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_40), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_60,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_60), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_61,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_61), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_62,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_62), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_63,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_63), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_64,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_64), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_65,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_65), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_66,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_66), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_70,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_70), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_71,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_71), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_72,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_72), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_73,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_73), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_74,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_74), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_75,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_75), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_76,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_76), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_77,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_77), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_253,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_253), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pn_io_error_code2_pnio_255,
+ { "ErrorCode2", "pn_io.error_code2",
+ FT_UINT8, BASE_DEC, VALS(pn_io_error_code2_pnio_255), 0x0,
+ NULL, HFILL }
+ },
+
+ };
+
+ static gint *ett[] = {
+ &ett_pn_io_status
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_pn_undecoded_data, { "pn.undecoded_data", PI_UNDECODED, PI_WARN, "Undecoded Data", EXPFILL }},
+ { &ei_pn_io_error_code1, { "pn_io.error_code1.expert", PI_UNDECODED, PI_WARN, "Unknown ErrorCode1", EXPFILL }},
+ { &ei_pn_io_error_code2, { "pn_io.error_code2.expert", PI_UNDECODED, PI_WARN, "Unknown ErrorDecode", EXPFILL } },
+
+ };
+
+ expert_module_t* expert_pn;
+
+
+ proto_register_field_array (proto, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ expert_pn = expert_register_protocol(proto);
+ expert_register_field_array(expert_pn, ei, array_length(ei));
+}
+
+/* Read a string from an "xml" file, dropping xml comment blocks */
+char *pn_fgets(char *str, int n, FILE *stream, wmem_allocator_t *scope)
+{
+ const char XML_COMMENT_START[] = "<!--";
+ const char XML_COMMENT_END[] = "-->";
+
+ char *retVal = fgets(str, n, stream);
+ if (retVal == NULL) {
+ /* No input, we're done */
+ return retVal;
+ }
+
+ /* Search for the XML begin comment marker */
+ char *comment_start = strstr(str, XML_COMMENT_START);
+ char *common_start_end = comment_start + sizeof(XML_COMMENT_START) - 1;
+ if(comment_start == NULL) {
+ /* No comment start, we're done */
+ return retVal;
+ }
+
+ /* Terminate the input buffer at the comment start */
+ *comment_start = '\0';
+ size_t used_space = comment_start - str;
+ size_t remaining_space = n - used_space;
+
+ /* Read more data looking for the comment end */
+ char *comment_end = strstr(common_start_end, XML_COMMENT_END);
+ if (comment_end == NULL) {
+ // Not found in this line, read more lines until we do find it */
+ char *temp = (char*)wmem_alloc(scope, MAX_LINE_LENGTH);
+ char *next_line = temp;
+ while((comment_end == NULL) && (next_line != NULL)) {
+ next_line = fgets(temp, MAX_LINE_LENGTH, stream);
+ if (next_line == NULL) {
+ /* No more data, exit now */
+ break;
+ }
+ comment_end = strstr(next_line, XML_COMMENT_END);
+ }
+ }
+
+ if (comment_end == NULL) {
+ /* We didn't find the comment end, return what we have */
+ return retVal;
+ }
+
+ /* We did find a comment end, skip past the comment */
+ char *comment_end_end = comment_end + sizeof(XML_COMMENT_END) - 1;
+
+ /* Check we have space left in the buffer to move the trailing bytes after the comment end */
+ size_t remaining_bytes = strlen(comment_end_end) + 1;
+ if (remaining_bytes < remaining_space) {
+ (void) g_strlcat(str, comment_end_end, n);
+ }
+ else {
+ /* Seek the file back to the comment end so the next read picks it up */
+ fseek(stream, -(long)(remaining_bytes), SEEK_CUR);
+ }
+
+ return retVal;
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/epan/profinet/packet-pn.h b/plugins/epan/profinet/packet-pn.h
new file mode 100644
index 0000000..f2c0743
--- /dev/null
+++ b/plugins/epan/profinet/packet-pn.h
@@ -0,0 +1,204 @@
+/* packet-pn.h
+ * Common functions for other PROFINET protocols like DCP, MRP, ...
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * Cyclic PNIO RTC1 Data Dissection:
+ *
+ * Added new structures to packet-pn.h to transfer the gained data of
+ * packet-pn-dcp.c and packet-dcerpc-pn-io.c to packet-pn-rtc-one.c for
+ * detailled dissection of cyclic PNIO RTC1 dataframes.
+ *
+ */
+
+#define FRAME_ID_DCP_HELLO 0xfefc
+#define FRAME_ID_DCP_GETORSET 0xfefd
+#define FRAME_ID_DCP_IDENT_REQ 0xfefe
+#define FRAME_ID_DCP_IDENT_RES 0xfeff
+
+
+/* ---- Structures for pnio_rtc1 ---- */
+extern int proto_pn_dcp;
+extern int proto_pn_io_apdu_status;
+extern int proto_pn_io_time_aware_status;
+
+extern gboolean pnio_ps_selection; /* given by pnio preferences */
+
+/* Structure for general station information */
+typedef struct tagStationInfo {
+ /* general information */
+ gchar *typeofstation;
+ gchar *nameofstation;
+ guint16 u16Vendor_id;
+ guint16 u16Device_id;
+ /* frame structure */
+ guint16 ioDataObjectNr_in;
+ guint16 ioDataObjectNr_out;
+ guint16 iocsNr_in;
+ guint16 iocsNr_out;
+ /* GSDfile station information */
+ gboolean gsdFound;
+ gboolean gsdPathLength;
+ gchar *gsdLocation;
+ /* IOCS object data */
+ wmem_list_t *iocs_data_in;
+ wmem_list_t *iocs_data_out;
+ /* IOData object data */
+ wmem_list_t *ioobject_data_in;
+ wmem_list_t *ioobject_data_out;
+ /* Different ModuleIdentnumber */
+ wmem_list_t *diff_module;
+} stationInfo;
+
+typedef struct tagApduStatusSwitch
+{
+ gboolean isRedundancyActive;
+ address dl_dst;
+ address dl_src;
+}apduStatusSwitch;
+
+/* Structure for IOCS Frames */
+typedef struct tagIocsObject {
+ guint16 slotNr;
+ guint16 subSlotNr;
+ guint16 frameOffset;
+} iocsObject;
+
+/* Structure for IO Data Objects */
+typedef struct tagIoDataObject {
+ guint16 slotNr;
+ guint16 subSlotNr;
+ guint32 api;
+ guint32 moduleIdentNr;
+ guint32 subModuleIdentNr;
+ guint16 frameOffset;
+ guint16 length;
+ guint16 amountInGSDML;
+ guint32 fParameterIndexNr;
+ guint16 f_par_crc1;
+ guint16 f_src_adr;
+ guint16 f_dest_adr;
+ gboolean f_crc_seed;
+ guint8 f_crc_len;
+ address srcAddr;
+ address dstAddr;
+ gboolean profisafeSupported;
+ gboolean discardIOXS;
+ gchar *moduleNameStr;
+ tvbuff_t *tvb_slot;
+ tvbuff_t *tvb_subslot;
+ /* Status- or Controlbyte data*/
+ guint8 last_sb_cb;
+ guint8 lastToggleBit;
+} ioDataObject;
+
+/* Structure for Modules with different ModuleIdentnumber */
+typedef struct tagModuleDiffInfo {
+ guint16 slotNr;
+ guint32 modulID;
+} moduleDiffInfo;
+
+typedef struct tagARUUIDFrame {
+ e_guid_t aruuid;
+ guint32 setupframe;
+ guint32 releaseframe;
+ guint16 outputframe;
+ guint16 inputframe;
+} ARUUIDFrame;
+
+extern wmem_list_t *aruuid_frame_setup_list;
+
+extern void init_pn(int proto);
+extern void init_pn_io_rtc1(int proto);
+extern void init_pn_rsi(int proto);
+extern void pn_rsi_reassemble_init(void);
+
+extern void init_pnio_rtc1_station(stationInfo *station_info);
+
+extern int dissect_pn_uint8(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, guint8 *pdata);
+
+extern int dissect_pn_uint16_ret_item(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, guint16 *pdata, proto_item ** new_item);
+extern int dissect_pn_uint16(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, guint16 *pdata);
+
+extern int dissect_pn_int16(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, gint16 *pdata);
+
+extern int dissect_pn_oid(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, guint32 *pdata);
+
+extern int dissect_pn_mac(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, guint8 *pdata);
+
+extern int dissect_pn_ipv4(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, guint32 *pdata);
+
+extern int dissect_pn_uuid(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, e_guid_t *uuid);
+
+extern int dissect_pn_undecoded(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 length);
+
+extern int dissect_pn_user_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 length, const char *text);
+
+extern int dissect_pn_pa_profile_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 length, const char *text);
+
+extern int dissect_blocks(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep);
+
+#define PDU_TYPE_REQ 0x05
+#define PDU_TYPE_RSP 0x06
+
+extern int dissect_rsi_blocks(tvbuff_t* tvb, int offset, packet_info* pinfo, proto_tree* tree, guint8* drep, guint32 u32FOpnumOffsetOpnum, int type);
+
+#define SUBST_DATA 1
+#define FRAG_DATA 2
+
+extern int dissect_pn_user_data_bytes(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint32 length, int iSelect);
+
+extern int dissect_pn_malformed(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint32 length);
+
+extern int dissect_pn_padding(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, int length);
+
+extern int dissect_pn_align4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
+
+extern int dissect_PNIO_status(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint8 *drep);
+
+extern int dissect_PNIO_C_SDU_RTC1(tvbuff_t* tvb, int offset, packet_info* pinfo,
+ proto_tree* tree, guint8* drep _U_, guint16 frameid);
+
+extern int dissect_PNIO_RSI(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, guint8 *drep);
+
+extern int dissect_PDRsiInstances_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow);
+
+extern void pn_append_info(packet_info *pinfo, proto_item *dcp_item, const char *text);
+
+extern void pn_init_append_aruuid_frame_setup_list(e_guid_t aruuid, guint32 setup);
+
+extern ARUUIDFrame* pn_find_aruuid_frame_setup(packet_info* pinfo);
+
+extern void pn_find_dcp_station_info(stationInfo* station_info, conversation_t* conversation);
+
+extern gboolean dissect_CSF_SDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
+
+#define MAX_LINE_LENGTH 1024 /* used for fgets() */
+
+/* Read a string from an "xml" file, dropping xml comment blocks */
+#include <stdio.h>
+extern char *pn_fgets(char *str, int n, FILE *stream, wmem_allocator_t *scope);