aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/profinet/ChangeLog7
-rw-r--r--plugins/profinet/Makefile.am2
-rw-r--r--plugins/profinet/Makefile.nmake2
-rw-r--r--plugins/profinet/moduleinfo.h2
-rw-r--r--plugins/profinet/packet-pn-ptcp.c1081
-rw-r--r--plugins/profinet/profinet.c6
6 files changed, 1094 insertions, 6 deletions
diff --git a/plugins/profinet/ChangeLog b/plugins/profinet/ChangeLog
index 7cfcdc9193..ea88df6040 100644
--- a/plugins/profinet/ChangeLog
+++ b/plugins/profinet/ChangeLog
@@ -20,4 +20,9 @@ Version 0.1.1:
Version 0.1.2:
-* PN-DCP: dissection of "DHCP/DHCP client identifier" suboption was added \ No newline at end of file
+* 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
+
diff --git a/plugins/profinet/Makefile.am b/plugins/profinet/Makefile.am
index 7a162159ed..3f24e71d92 100644
--- a/plugins/profinet/Makefile.am
+++ b/plugins/profinet/Makefile.am
@@ -27,7 +27,7 @@ INCLUDES = -I$(top_srcdir)
plugindir = @plugindir@
plugin_LTLIBRARIES = profinet.la
-profinet_la_SOURCES = profinet.c packet-dcerpc-pn-io.c packet-pn-dcp.c moduleinfo.h
+profinet_la_SOURCES = profinet.c packet-dcerpc-pn-io.c packet-pn-dcp.c packet-pn-ptcp.c moduleinfo.h
profinet_la_LDFLAGS = -module -avoid-version
profinet_la_LIBADD = @PLUGIN_LIBS@
diff --git a/plugins/profinet/Makefile.nmake b/plugins/profinet/Makefile.nmake
index c6430a4ec5..7c3b086449 100644
--- a/plugins/profinet/Makefile.nmake
+++ b/plugins/profinet/Makefile.nmake
@@ -15,7 +15,7 @@ LDFLAGS = /NOLOGO /INCREMENTAL:no /MACHINE:I386 $(LOCAL_LDFLAGS)
LINK_PLUGIN_WITH=..\..\epan\libethereal.lib
CFLAGS=/DHAVE_WIN32_LIBETHEREAL_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS)
-OBJECTS=profinet.obj packet-dcerpc-pn-io.obj packet-pn-dcp.obj
+OBJECTS=profinet.obj packet-dcerpc-pn-io.obj packet-pn-dcp.obj packet-pn-ptcp.obj
profinet.dll profinet.exp profinet.lib : $(OBJECTS) $(LINK_PLUGIN_WITH)
link -dll /out:profinet.dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \
diff --git a/plugins/profinet/moduleinfo.h b/plugins/profinet/moduleinfo.h
index 336667db6b..2782ab2fa4 100644
--- a/plugins/profinet/moduleinfo.h
+++ b/plugins/profinet/moduleinfo.h
@@ -13,5 +13,5 @@
#endif
/* Version number of package */
-#define VERSION "0.1.2"
+#define VERSION "0.2.0"
diff --git a/plugins/profinet/packet-pn-ptcp.c b/plugins/profinet/packet-pn-ptcp.c
new file mode 100644
index 0000000000..f21794caac
--- /dev/null
+++ b/plugins/profinet/packet-pn-ptcp.c
@@ -0,0 +1,1081 @@
+/* packet-pn-ptcp.c
+ * Routines for PN-PTCP (PROFINET Precision Time Clock Protocol)
+ * packet dissection.
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/dissectors/packet-dcerpc.h>
+#include <epan/oui.h>
+
+static int proto_pn_ptcp = -1;
+
+static int hf_pn_ptcp = -1;
+static int hf_pn_ptcp_data = -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 = -1;
+static int hf_pn_ptcp_padding8 = -1;
+static int hf_pn_ptcp_padding16 = -1;
+static int hf_pn_ptcp_delay1ps = -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_request_source_address = -1;
+static int hf_pn_ptcp_request_port_id = -1;
+static int hf_pn_ptcp_sync_id = -1;
+
+static int hf_pn_ptcp_t2portrxdelay = -1;
+static int hf_pn_ptcp_t3porttxdelay = -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_epochnumber = -1;
+static int hf_pn_ptcp_currentutcoffset = -1;
+
+static int hf_pn_ptcp_clock_uuid = -1;
+static int hf_pn_ptcp_clockstratum = -1;
+static int hf_pn_ptcp_clockvariance = -1;
+static int hf_pn_ptcp_clockrole = -1;
+
+static int hf_pn_ptcp_oui = -1;
+static int hf_pn_ptcp_unknown_subtype = -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;
+
+
+
+static const value_string pn_ptcp_block_type[] = {
+ { 0x00, "End" },
+ { 0x01, "Subdomain"},
+ { 0x02, "Time"},
+ { 0x03, "TimeExtension"},
+ { 0x04, "Master"},
+ { 0x05, "PortParameter"},
+ { 0x06, "DelayParameter"},
+ /*0x07 - 0x7E Reserved */
+ { 0x7F, "Organizationally Specific"},
+
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_clock_stratum_vals[] = {
+ { 0x00, "Force" },
+ { 0x01, "Primary"},
+ { 0x02, "Secondary"},
+ { 0x03, "TimingSignal"},
+ { 0x04, "NoTimingSignal"},
+ /*0x05 - 0xFE Reserved */
+ { 0xFF, "Default"},
+
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_clock_role_vals[] = {
+ { 0x00, "Reserved" },
+ { 0x01, "Primary PTCP-Master"},
+ { 0x02, "Secondary PTCP-Master"},
+ /*0x03 - 0xFF Reserved */
+
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_oui_vals[] = {
+ { OUI_PROFINET, "PROFINET" },
+
+ { 0, NULL }
+};
+
+static const value_string pn_ptcp_profinet_subtype_vals[] = {
+ { 0x01, "RTData" },
+
+ { 0, NULL }
+};
+
+
+/* XXX - use include file instead for these helpers */
+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(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, guint16 *pdata);
+
+extern int dissect_pn_uint32(tvbuff_t *tvb, gint offset, packet_info *pinfo,
+ proto_tree *tree, int hfindex, guint32 *pdata);
+
+
+
+/* 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);
+ if (tree) {
+ proto_tree_add_uint(tree, hfindex, tvb, offset, 1, data);
+ }
+ if (pdata)
+ *pdata = data;
+ return offset + 1;
+}
+
+/* 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);
+
+ if (tree) {
+ proto_tree_add_uint(tree, hfindex, tvb, offset, 2, data);
+ }
+ if (pdata)
+ *pdata = data;
+ return offset + 2;
+}
+
+/* dissect a 32 bit unsigned integer */
+int
+dissect_pn_uint32(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, guint32 *pdata)
+{
+ guint32 data;
+
+ data = tvb_get_ntohl (tvb, offset);
+
+ if (tree) {
+ proto_tree_add_uint(tree, hfindex, tvb, offset, 4, data);
+ }
+ if (pdata)
+ *pdata = data;
+ return offset+4;
+}
+
+/* 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);
+
+ if (tree) {
+ 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);
+
+ if (tree) {
+ 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);
+ if(tree)
+ proto_tree_add_ether(tree, hfindex, tvb, offset, 6, data);
+
+ if (pdata)
+ memcpy(pdata, data, 6);
+
+ return offset + 6;
+}
+
+/* dissect a 12 byte UUID address */
+int
+dissect_pn_uuid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
+ proto_tree *tree, int hfindex, e_uuid_t *uuid)
+{
+ guint8 drep[2] = { 0,0 };
+
+ offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+ hfindex, uuid);
+
+ return offset;
+}
+
+
+
+
+static int
+dissect_PNPTCP_TLVHeader(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, 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)
+{
+ guint8 mac[6];
+ e_uuid_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);
+
+ 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 padding16;
+ guint32 Seconds;
+ guint32 NanoSeconds;
+
+
+ /* Padding16 */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_padding16, &padding16);
+
+ /* Seconds */
+ offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_seconds, &Seconds);
+
+ /* NanoSeconds */
+ offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_nanoseconds, &NanoSeconds);
+
+ proto_item_append_text(item, ": Seconds=%u NanoSeconds=%u",
+ Seconds, NanoSeconds);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Time: %4us %09uns", Seconds, NanoSeconds);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_TimeExtension(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ guint16 Flags;
+ guint16 EpochNumber;
+ guint16 CurrentUTCOffset;
+
+
+ /* Flags */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_flags, &Flags);
+
+ /* EpochNumber */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_epochnumber, &EpochNumber);
+
+ /* CurrentUTCOffset */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_currentutcoffset, &CurrentUTCOffset);
+
+ proto_item_append_text(item, ": Flags=0x%x, EpochNumber=%u, CurrentUTCOffset=%u",
+ Flags, EpochNumber, CurrentUTCOffset);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_Master(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+ e_uuid_t uuid;
+ guint8 ClockStratum;
+ gint16 ClockVariance;
+ gint8 ClockRole;
+
+ /* ClockVariance */
+ offset = dissect_pn_int16(tvb, offset, pinfo, tree, hf_pn_ptcp_clockvariance, &ClockVariance);
+
+ /* ClockUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_ptcp_clock_uuid, &uuid);
+
+ /* ClockStratum */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_clockstratum, &ClockStratum);
+
+ /* ClockRole */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_clockrole, &ClockRole);
+
+ proto_item_append_text(item, ": ClockUUID=%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]);
+
+ proto_item_append_text(item, ", ClockStratum=%s, ClockVariance=%d",
+ val_to_str(ClockStratum, pn_ptcp_clock_stratum_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)
+{
+ guint16 padding16;
+ guint32 t2portrxdelay;
+ guint32 t3porttxdelay;
+
+
+ /* Padding16 */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_padding16, &padding16);
+
+ /* T2PortRxDelay */
+ offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_t2portrxdelay, &t2portrxdelay);
+
+ /* T3PortTxDelay */
+ offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_t3porttxdelay, &t3porttxdelay);
+
+ proto_item_append_text(item, ": T2PortRxDelay=%uns, T3PortTxDelay=%uns",
+ t2portrxdelay, t3porttxdelay);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ 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];
+ guint8 requestportid;
+ guint8 syncid;
+
+
+ /* RequestSourceAddress */
+ offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_ptcp_request_source_address, mac);
+
+ /* RequestPortID */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_request_port_id, &requestportid);
+
+ /* SyncID */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_sync_id, &syncid);
+
+
+ proto_item_append_text(item, ": RequestSource=%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ proto_item_append_text(item, ", RequestPortID=0x%02x, SyncID=0x%02x",
+ requestportid, syncid);
+
+ 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;
+ guint8 padding8;
+ e_uuid_t uuid;
+
+ /* OUI already dissected! */
+
+ /* SubType */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_profinet_subtype, &subType);
+ length --;
+
+ switch(subType) {
+ case 1: /* RTData */
+ /* Padding8 */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_padding8, &padding8);
+
+ /* IRDataUUID */
+ offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_ptcp_irdata_uuid, &uuid);
+ break;
+ default:
+ proto_tree_add_string_format(tree, hf_pn_ptcp_data, tvb, offset, length, "data",
+ "PROFINET Data: %d bytes", 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;
+ guint8 subType;
+
+
+ /* verify remaining TLV length */
+ if (length < 4)
+ {
+ if (tree) {
+ proto_tree_add_string_format(tree, hf_pn_ptcp_data, tvb, offset, length, "data",
+ "Length: %u (too short, must be >= 4)", 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:
+ offset = dissect_PNPTCP_Option_PROFINET(tvb, offset, pinfo, tree, item, length);
+ break;
+ default:
+ /* SubType */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_unknown_subtype, &subType);
+ length --;
+ proto_tree_add_string_format(tree, hf_pn_ptcp_data, tvb, offset, length, "data",
+ "Unknown OUI Data: %d bytes", length);
+ }
+
+ return (offset);
+}
+
+
+static int
+dissect_PNPTCP_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, gboolean *end)
+{
+ 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, FALSE);
+ 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 */, FALSE);
+ 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_append_text(sub_item, "%s",
+ val_to_str(type, pn_ptcp_block_type, "Unknown"));
+
+ proto_item_append_text(tlvheader_item, ": Type=%s (%x), Length=%u",
+ val_to_str(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);
+ 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(0x7F): /* Organizational Specific */
+ dissect_PNPTCP_Option(tvb, offset, pinfo, sub_tree, sub_item, length);
+ break;
+ default:
+ proto_tree_add_string_format(sub_tree, hf_pn_ptcp_data, tvb, offset, length, "data",
+ "PN-PTCP Unknown BlockType 0x%x, Data: %d bytes", type, 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)
+{
+ 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);
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_Header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, gboolean delay_valid)
+{
+ proto_item *header_item;
+ proto_tree *header_tree;
+ guint32 res_1;
+ guint32 res_2;
+ guint32 delay10ns;
+ guint16 seq_id;
+ guint8 delay1ns;
+ guint8 padding8;
+ guint16 padding16;
+ guint16 delay1ps;
+ guint64 delayns;
+ guint32 delayms;
+
+
+ header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, FALSE);
+ header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header);
+
+ /* Reserved_1 */
+ offset = dissect_pn_uint32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_res1, &res_1);
+
+ /* Reserved_2 */
+ offset = dissect_pn_uint32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_res2, &res_2);
+
+ /* Delay10ns */
+ offset = dissect_pn_uint32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_delay10ns, &delay10ns);
+
+ /* 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, &delay1ns);
+
+ /* Padding8 */
+ offset = dissect_pn_uint8(tvb, offset, pinfo, header_tree, hf_pn_ptcp_padding8, &padding8);
+
+ /* Delay1ps */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_delay1ps, &delay1ps);
+
+ /* Padding16 */
+ offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_padding16, &padding16);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Seq=%3u", seq_id);
+ proto_item_append_text(item, ": Sequence=%u", seq_id);
+ proto_item_append_text(header_item, ": Sequence=%u", seq_id);
+
+ /* the delay field is meaningful only in specific PDU's */
+ if(delay_valid) {
+ delayns = ((guint64) delay10ns) * 10 + delay1ns;
+ delayms = (guint32) (delayns / (1000 * 1000));
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Delay=%11" PRIu64 "ns",
+ delayns);
+ proto_item_append_text(item, ", Delay=%" PRIu64 "ns", delayns);
+
+ if(delayns != 0) {
+ proto_item_append_text(header_item, ", Delay=%" PRIu64 "ns (%u.%03u,%03u,%03u sec)",
+ delayns,
+ delayms / 1000,
+ delayms % 1000,
+ (delay10ns % (1000*100)) / 100,
+ delay10ns % 100 * 10 + delay1ns);
+ } else {
+ proto_item_append_text(header_item, ", Delay=%" PRIu64 "ns",
+ delayns);
+ }
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_FollowUpPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID)
+{
+
+ switch(u16FrameID) {
+ case(0xFF20):
+ proto_item_append_text(item, "%s", "FollowUp (Clock)");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "FollowUp (Clock), ");
+ break;
+ case(0xFF21):
+ proto_item_append_text(item, "%s", "FollowUp (Time)");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "FollowUp (Time) , ");
+ break;
+ default:
+ proto_item_append_text(item, "%s", "FollowUp");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "FollowUp, ");
+ }
+
+ /* dissect the header */
+ offset = dissect_PNPTCP_Header(tvb, offset, pinfo, tree, item, FALSE /* !delay_valid*/);
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_RTASyncPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID)
+{
+
+ switch(u16FrameID) {
+ case(0x0000):
+ case(0x0020):
+ proto_item_append_text(item, "%s", "RTASync (Clock)");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "RTASync (Clock), ");
+ break;
+ case(0x0001):
+ case(0x0021):
+ proto_item_append_text(item, "%s", "RTASync (Time)");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "RTASync (Time) , ");
+ break;
+ default:
+ proto_item_append_text(item, "%s", "RTASync");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "RTASync, ");
+ }
+
+ /* dissect the header */
+ offset = dissect_PNPTCP_Header(tvb, offset, pinfo, tree, item, FALSE /* !delay_valid*/);
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_RTCSyncPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "RTCSync, ");
+
+ proto_item_append_text(item, "%s", "RTCSync");
+
+ /* dissect the header */
+ offset = dissect_PNPTCP_Header(tvb, offset, pinfo, tree, item, FALSE /* !delay_valid*/);
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_AnnouncePDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID)
+{
+
+ switch(u16FrameID) {
+ case(0xFF00):
+ proto_item_append_text(item, "%s", "Announce (Clock)");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "Announce (Clock), ");
+ break;
+ case(0xFF01):
+ proto_item_append_text(item, "%s", "Announce (Time)");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "Announce (Time) , ");
+ break;
+ default:
+ proto_item_append_text(item, "%s", "Announce");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "Announce, ");
+ }
+
+ /* dissect the header */
+ offset = dissect_PNPTCP_Header(tvb, offset, pinfo, tree, item, FALSE /* !delay_valid*/);
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_DelayReqPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "DelayReq, ");
+
+ proto_item_append_text(item, "%s", "DelayReq");
+
+ /* dissect the header */
+ offset = dissect_PNPTCP_Header(tvb, offset, pinfo, tree, item, FALSE /* !delay_valid*/);
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_DelayResPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "DelayRes, ");
+
+ proto_item_append_text(item, "%s", "DelayRes");
+
+ /* dissect the header */
+ offset = dissect_PNPTCP_Header(tvb, offset, pinfo, tree, item, TRUE /* delay_valid*/);
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item);
+
+ return offset;
+}
+
+
+static int
+dissect_PNPTCP_DelayFuResPDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item)
+{
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, "DelayFuRes, ");
+
+ proto_item_append_text(item, "%s", "DelayFuRes");
+
+ /* dissect the header */
+ offset = dissect_PNPTCP_Header(tvb, offset, pinfo, tree, item, TRUE /* delay_valid*/);
+
+ /* dissect the PDU */
+ offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item);
+
+ 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)
+{
+ guint16 u16FrameID;
+ proto_item *item = NULL;
+ proto_tree *ptcp_tree = NULL;
+ int offset = 0;
+ guint32 u32SubStart;
+
+
+ /* the tvb will NOT contain the frame_id here, so get it from our private data! */
+ u16FrameID = GPOINTER_TO_UINT(pinfo->private_data);
+
+ /* frame id must be in valid range (acyclic Real-Time, DCP) */
+ /* 0x0000 - 0x007F: RTASyncPDU */
+ /* 0x0080 - 0x00FF: RTCSyncPDU */
+ /* 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;
+ }
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_add_str(pinfo->cinfo, COL_PROTOCOL, "PN-PTCP");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_str(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) */
+ case(0x0000):
+ case(0x0001):
+ /* Send clock and phase synchronization */
+ offset = dissect_PNPTCP_RTASyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID);
+ break;
+ /* 0x0002 - 0x001F reserved */
+ case(0x0020):
+ case(0x0021):
+ /* Time synchronization */
+ offset = dissect_PNPTCP_RTASyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID);
+ break;
+ /* 0x0022 - 0x007F reserved */
+
+ /* range 2 (0x0080 - 0x00FF) */
+ case(0x0080):
+ /* class 3 synchronization */
+ offset = dissect_PNPTCP_RTCSyncPDU(tvb, offset, pinfo, ptcp_tree, item);
+ break;
+ /* 0x0081 - 0x00FF reserved */
+
+ /* range 7 (0xFF00 - 0xFF5F) */
+ case(0xff00):
+ case(0xff01):
+ offset = dissect_PNPTCP_AnnouncePDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID);
+ break;
+ /* 0xFF02 - 0xFF1F reserved */
+ case(0xff20):
+ case(0xff21):
+ offset = dissect_PNPTCP_FollowUpPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID);
+ break;
+ /* 0xFF22 - 0xFF3F reserved */
+ case(0xff40):
+ offset = dissect_PNPTCP_DelayReqPDU(tvb, offset, pinfo, ptcp_tree, item);
+ break;
+ case(0xff41):
+ offset = dissect_PNPTCP_DelayResPDU(tvb, offset, pinfo, ptcp_tree, item);
+ break;
+ case(0xff42):
+ offset = dissect_PNPTCP_DelayFuResPDU(tvb, offset, pinfo, ptcp_tree, item);
+ break;
+ case(0xff43):
+ offset = dissect_PNPTCP_DelayResPDU(tvb, offset, pinfo, ptcp_tree, item);
+ break;
+ /* 0xFF44 - 0xFF5F reserved */
+ default:
+ proto_tree_add_string_format(ptcp_tree, hf_pn_ptcp_data, tvb, offset, tvb_length_remaining(tvb, offset), "data",
+ "PN-PTCP Reserved FrameID 0x%04x, Data: %d bytes", u16FrameID, tvb_length_remaining(tvb, offset));
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Reserved FrameID 0x%04x", u16FrameID);
+
+ proto_item_append_text(item, "Reserved FrameID 0x%04x", u16FrameID);
+
+ offset += tvb_length_remaining(tvb, offset);
+ }
+
+ proto_item_set_len(item, offset - u32SubStart);
+
+ return TRUE;
+}
+
+
+void
+proto_register_pn_ptcp (void)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_ptcp,
+ { "PROFINET PTCP", "pn_ptcp", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_data,
+ { "Undecoded Data", "pn_ptcp.data", FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_header,
+ { "Header", "pn_ptcp.header", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_block,
+ { "", "pn_ptcp.block", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_block_tlvheader,
+ { "TLVHeader", "pn_ptcp.tlvheader", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+
+ { &hf_pn_ptcp_res1,
+ { "Reserved 1", "pn_ptcp.res1", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_res2,
+ { "Reserved 2", "pn_ptcp.res2", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_delay10ns,
+ { "Delay10ns", "pn_ptcp.delay10ns", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_seq_id,
+ { "SequenceID", "pn_ptcp.sequence_id", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_delay1ns,
+ { "Delay1ns", "pn_ptcp.delay1ns", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_padding8,
+ { "Padding", "pn_ptcp.padding8", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_padding16,
+ { "Padding", "pn_ptcp.padding16", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_delay1ps,
+ { "Delay1ps", "pn_ptcp.delay1ps", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+
+ { &hf_pn_ptcp_tl_length,
+ { "TypeLength.Length", "pn_ptcp.tl_length", FT_UINT16, BASE_DEC, 0x0, 0x1FF, "", HFILL }},
+ { &hf_pn_ptcp_tl_type,
+ { "TypeLength.Type", "pn_ptcp.tl_type", FT_UINT16, BASE_DEC, 0x0, 0xFE00, "", HFILL }},
+
+ { &hf_pn_ptcp_master_source_address,
+ { "MasterSourceAddress", "pn_ptcp.master_source_address", FT_ETHER, BASE_HEX, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_subdomain_uuid,
+ { "SubdomainUUID", "pn_ptcp.subdomain_uuid", FT_STRING, BASE_NONE, 0x0, 0x0, "", HFILL }},
+
+ { &hf_pn_ptcp_request_source_address,
+ { "RequestSourceAddress", "pn_ptcp.request_source_address", FT_ETHER, BASE_HEX, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_request_port_id,
+ { "RequestPortID", "pn_ptcp.request_port_id", FT_UINT8, BASE_HEX, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_sync_id,
+ { "SyncID", "pn_ptcp.sync_id", FT_UINT8, BASE_HEX, 0x0, 0x0, "", HFILL }},
+
+ { &hf_pn_ptcp_t2portrxdelay,
+ { "T2PortRxDelay (ns)", "pn_ptcp.t2portrxdelay", FT_UINT32, BASE_DEC, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_t3porttxdelay,
+ { "T3PortTxDelay (ns)", "pn_ptcp.t3porttxdelay", FT_UINT32, BASE_DEC, 0x0, 0x0, "", HFILL }},
+
+ { &hf_pn_ptcp_seconds,
+ { "Seconds", "pn_ptcp.seconds", FT_UINT32, BASE_DEC, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_nanoseconds,
+ { "NanoSeconds", "pn_ptcp.nanoseconds", FT_UINT32, BASE_DEC, 0x0, 0x0, "", HFILL }},
+
+ { &hf_pn_ptcp_flags,
+ { "Flags", "pn_ptcp.flags", FT_UINT16, BASE_HEX, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_epochnumber,
+ { "EpochNumber", "pn_ptcp.epochnumber", FT_UINT16, BASE_DEC, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_currentutcoffset,
+ { "CurrentUTCOffset", "pn_ptcp.currentutcoffset", FT_UINT16, BASE_DEC, 0x0, 0x0, "", HFILL }},
+
+
+ { &hf_pn_ptcp_clock_uuid,
+ { "ClockUUID", "pn_ptcp.clock_uuid", FT_STRING, BASE_NONE, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_clockstratum,
+ { "ClockStratum", "pn_ptcp.clockstratum", FT_UINT8, BASE_HEX, VALS(pn_ptcp_clock_stratum_vals), 0x0, "", HFILL }},
+ { &hf_pn_ptcp_clockvariance,
+ { "ClockVariance", "pn_ptcp.clockvariance", FT_INT16, BASE_DEC, 0x0, 0x0, "", HFILL }},
+ { &hf_pn_ptcp_clockrole,
+ { "ClockRole", "pn_ptcp.clockrole", FT_UINT8, BASE_HEX, VALS(pn_ptcp_clock_role_vals), 0x0, "", HFILL }},
+
+ { &hf_pn_ptcp_oui,
+ { "Organizationally Unique Identifier", "pn_ptcp.oui", FT_UINT24, BASE_HEX,
+ VALS(pn_ptcp_oui_vals), 0x0, "", 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_unknown_subtype,
+ { "Subtype", "pn_ptcp.subtype", FT_UINT8, BASE_HEX, 0x0, 0x0, "Unkown Subtype", HFILL }},
+
+ { &hf_pn_ptcp_irdata_uuid,
+ { "IRDataUUID", "pn_ptcp.irdata_uuid", FT_STRING, BASE_NONE, 0x0, 0x0, "", 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, proto_pn_ptcp);
+}
diff --git a/plugins/profinet/profinet.c b/plugins/profinet/profinet.c
index f8ca6da330..f3e6b806fa 100644
--- a/plugins/profinet/profinet.c
+++ b/plugins/profinet/profinet.c
@@ -46,8 +46,8 @@ extern void proto_register_pn_io (void);
extern void proto_reg_handoff_pn_io (void);
extern void proto_register_pn_dcp (void);
extern void proto_reg_handoff_pn_dcp (void);
-
-
+extern void proto_register_pn_ptcp (void);
+extern void proto_reg_handoff_pn_ptcp (void);
/* Start the functions we need for the plugin stuff */
@@ -60,6 +60,7 @@ plugin_register(void)
if (plugin_registered == FALSE) { /* execute protocol initialization only once */
proto_register_pn_io();
proto_register_pn_dcp();
+ proto_register_pn_ptcp();
plugin_registered = TRUE;
}
@@ -69,6 +70,7 @@ G_MODULE_EXPORT void
plugin_reg_handoff(void){
proto_reg_handoff_pn_io();
proto_reg_handoff_pn_dcp();
+ proto_reg_handoff_pn_ptcp();
}
#endif