From Wido Kelling:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 1 Dec 2011 05:58:55 +0000 (05:58 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 1 Dec 2011 05:58:55 +0000 (05:58 +0000)
Enhancements to profinet decoding (IEC 61158) V2.3.

https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6605

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@40058 f5534014-38df-0310-8fa8-9805f1628bb7

plugins/profinet/packet-dcerpc-pn-io.c
plugins/profinet/packet-pn-rt.c
plugins/profinet/packet-pn.h

index 1d733ede0fb2aa00edb4e6f414ee76345bb99465..45e637ef0c42fce2cb6ec9386badb8de8af0e018 100644 (file)
@@ -84,6 +84,7 @@ static int hf_pn_io_ar_type = -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;
@@ -227,6 +228,8 @@ 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_applready0 = -1;
@@ -593,6 +596,7 @@ 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 = -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;
@@ -625,6 +629,7 @@ 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_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_subframe_data =-1;
 static gint ett_pn_io_frame_defails = -1;
@@ -711,22 +716,22 @@ static const value_string pn_io_block_type[] = {
     { 0x0109, "IRInfoBlock"},
     { 0x010A, "SRInfoBlock"},
     { 0x010B, "ARFSUBlock"},
-    { 0x0110, "IODBlockReq"},
-    { 0x8110, "IODBlockRes"},
-    { 0x0111, "IODBlockReq"},
-    { 0x8111, "IODBlockRes"},
-    { 0x0112, "IOXBlockReq"},
-    { 0x8112, "IOXBlockRes"},
-    { 0x0113, "IOXBlockReq"},
-    { 0x8113, "IOXBlockRes"},
-    { 0x0114, "ReleaseBlockReq"},
-    { 0x8114, "ReleaseBlockRes"},
+       { 0x0110, "IODControlReq Prm End.req"},
+       { 0x8110, "IODControlRes Prm End.rsp"},
+       { 0x0111, "IODControlReq Prm End.req"},
+       { 0x8111, "IODControlRes Prm End.rsp"},
+       { 0x0112, "IOXBlockReq Application Ready.req"},
+       { 0x8112, "IOXBlockRes Application Ready.rsp"},
+       { 0x0113, "IOXBlockReq Application Ready.req"},
+       { 0x8113, "IOXBlockRes Application Ready.rsp"},
+       { 0x0114, "IODReleaseReq"},
+       { 0x8114, "IODReleaseRes"},
     { 0x0115, "ARRPCServerBlockReq"},
     { 0x8115, "ARRPCServerBlockRes"},
-    { 0x0116, "IOXBlockReq"},
-    { 0x8116, "IOXBlockRes"},
-    { 0x0117, "IOXBlockReq"},
-    { 0x8117, "IOXBlockRes"},
+       { 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, "ControlBlockPrmBegin"},
     { 0x0119, "SubmoduleListBlock"},
     { 0x8118, "ControlBlockPrmBeginRes"},
@@ -2315,6 +2320,11 @@ static const value_string pn_io_control_properties_vals[] = {
     { 0, NULL }
 };
 
+static const value_string pn_io_control_properties_prmbegin_vals[] = {
+    { 0x0000, "No PrmBegin" },
+    { 0x0001, "The IO controller starts the transmisson of the stored start-up parameter" },
+    { 0, NULL }
+};
 static const value_string pn_io_control_properties_application_ready_vals[] = {
     { 0x0000, "Wait for explicit ControlCommand.ReadyForCompanion" },
     { 0x0001, "Implicit ControlCommand.ReadyForCompanion" },
@@ -3870,8 +3880,11 @@ dissect_ControlConnect_block(tvbuff_t *tvb, int offset,
                         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);
-    offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+    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 */
@@ -3921,6 +3934,8 @@ dissect_ControlBlockPrmBegin(tvbuff_t *tvb, int offset,
     e_uuid_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, PI_UNDECODED, PI_WARN,
@@ -3948,11 +3963,27 @@ dissect_ControlBlockPrmBegin(tvbuff_t *tvb, int offset,
     offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
 
     /* ControlCommand */
-    offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_control_command, &u16Command);
-    if(u16Command == 0x40)
-    {
-        proto_item_append_text(item, " PrmBegin");
-    }
+    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);
@@ -5812,8 +5843,11 @@ dissect_ARData_block(tvbuff_t *tvb, int offset,
     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) {
@@ -5827,26 +5861,30 @@ dissect_ARData_block(tvbuff_t *tvb, int offset,
     /* BlockversionLow:  0 */ 
     if(u8BlockVersionLow == 0){
     while(u16NumberOfARs--) {
-        offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+                       ar_item = proto_tree_add_item(tree, hf_pn_io_ar_data, tvb, offset, 0, ENC_BIG_ENDIAN);
+                       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);
-    offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+                       proto_item_append_text(ar_item,"ARUUID:%s",guid_to_str((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, tree, item, drep);
-        offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+                       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, tree, drep,
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
                         hf_pn_io_station_name_length, &u16NameLength);
         pStationName = ep_alloc(u16NameLength+1);
         tvb_memcpy(tvb, (guint8 *) pStationName, offset, u16NameLength);
         pStationName[u16NameLength] = '\0';
-        proto_tree_add_string (tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, pStationName);
+                       proto_tree_add_string (ar_tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, pStationName);
         offset += u16NameLength;
 
-    offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+                       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(tree, hf_pn_io_iocr_tree, tvb, offset, 0, ENC_NA);
+            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;
 
@@ -5907,89 +5945,98 @@ dissect_ARData_block(tvbuff_t *tvb, int offset,
         }
 
         /* AlarmCRType */
-    offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
                         hf_pn_io_alarmcr_type, &u16AlarmCRType);
         /* LocalAlarmReference */
-    offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
                         hf_pn_io_localalarmref, &u16LocalAlarmReference);
         /* RemoteAlarmReference */
-    offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
                         hf_pn_io_remotealarmref, &u16RemoteAlarmReference);
         /* ParameterServerObjectUUID */
-        offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
+                       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, tree, drep,
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
                         hf_pn_io_station_name_length, &u16NameLength);
         /* ParameterServerStationName */
         pStationName = ep_alloc(u16NameLength+1);
         tvb_memcpy(tvb, (guint8 *) pStationName, offset, u16NameLength);
         pStationName[u16NameLength] = '\0';
-        proto_tree_add_string (tree, hf_pn_io_parameter_server_station_name, tvb, offset, u16NameLength, pStationName);
+                       proto_tree_add_string (ar_tree, hf_pn_io_parameter_server_station_name, tvb, offset, u16NameLength, pStationName);
         offset += u16NameLength;
         /* NumberOfAPIs */
-    offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep,
                         hf_pn_io_number_of_apis, &u16NumberOfAPIs);
         /* API */
         if (u16NumberOfAPIs > 0){
-            offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+                               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, tree, drep, hf_pn_io_ar_uuid, &aruuid);
+                       offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_ar_uuid, &aruuid);
+                       proto_item_append_text(ar_item,"ARUUID:%s",guid_to_str((const e_guid_t*) &aruuid));
             /* CMInitiatorObjectUUID */
-            offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep, hf_pn_io_cminitiator_objectuuid, &uuid);
+                       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, tree, drep, hf_pn_io_parameter_server_objectuuid, &uuid);
+                       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, tree, item, drep);
+                       offset = dissect_ARProperties(tvb, offset, pinfo, ar_tree, item, drep);
             /* ARType*/
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_ar_type, &u16ARType);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_ar_type, &u16ARType);
             /* AlarmCRType */
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_alarmcr_type, &u16AlarmCRType);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_alarmcr_type, &u16AlarmCRType);
             /* LocalAlarmReference */
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_localalarmref, &u16LocalAlarmReference);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_localalarmref, &u16LocalAlarmReference);
             /* RemoteAlarmReference */
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_remotealarmref, &u16RemoteAlarmReference);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_remotealarmref, &u16RemoteAlarmReference);
             /* InitiatorUDPRTPort*/
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_cminitiator_udprtport, &u16UDPRTPort);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_cminitiator_udprtport, &u16UDPRTPort);
             /* ResponderUDPRTPort*/
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_cmresponder_udprtport, &u16UDPRTPort);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_cmresponder_udprtport, &u16UDPRTPort);
             /* CMInitiatorStationName*/
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_station_name_length, &u16NameLength);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_station_name_length, &u16NameLength);
             pStationName = ep_alloc(u16NameLength+1);
             tvb_memcpy(tvb, (guint8 *) pStationName, offset, u16NameLength);
             pStationName[u16NameLength] = '\0';
-            proto_tree_add_string (tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, pStationName);
+                       proto_tree_add_string (ar_tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, pStationName);
             offset += u16NameLength;
             /** align padding! **/
-            offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+                       offset = dissect_pn_align4(tvb, offset, pinfo, ar_tree);
 
             /* StationNameLength */
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_station_name_length, &u16NameLength);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_station_name_length, &u16NameLength);
             if(u16NameLength != 0){
                 /* ParameterServerStationName */
                 pStationName = ep_alloc(u16NameLength+1);
                 tvb_memcpy(tvb, (guint8 *) pStationName, offset, u16NameLength);
                 pStationName[u16NameLength] = '\0';
-                proto_tree_add_string (tree, hf_pn_io_parameter_server_station_name, tvb, offset, u16NameLength, pStationName);
+                               proto_tree_add_string (ar_tree, hf_pn_io_parameter_server_station_name, tvb, offset, u16NameLength, pStationName);
                 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, tree);
+                       offset = dissect_pn_align4(tvb, offset, pinfo, ar_tree);
 
             /* NumberOfIOCRs*/
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,hf_pn_io_number_of_iocrs, &u16NumberOfIOCRs);
+                       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, tree, 2);
+                       offset = dissect_pn_padding(tvb, offset, pinfo, ar_tree, 2);
 
             while(u16NumberOfIOCRs--) {
-                iocr_item = proto_tree_add_item(tree, hf_pn_io_iocr_tree, tvb, offset, 0, ENC_NA);
+                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;
 
@@ -6039,24 +6086,26 @@ dissect_ARData_block(tvbuff_t *tvb, int offset,
                         "TransferStatus: 0x%02x (OK)", u8TransferStatus);
                 }
                 offset++;
+                               proto_item_set_len(iocr_item, offset - u32IOCRStart);
             }
             /* NumberOfAPIs */
-            offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_number_of_apis, &u16NumberOfAPIs);
+                       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, tree, 2);
+                       offset = dissect_pn_padding(tvb, offset, pinfo, ar_tree, 2);
             /* API */
             if (u16NumberOfAPIs > 0){
-                offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_api, &u32Api);
+                               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, tree, drep, hf_pn_io_number_of_ARDATAInfo, &u16NumberofEntries);
+                       offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ar_tree, drep, hf_pn_io_number_of_ARDATAInfo, &u16NumberofEntries);
 
-            offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2);
+                       offset = dissect_pn_padding(tvb, offset, pinfo, ar_tree, 2);
 
             while ((offset < i32EndOffset) && (u16NumberofEntries > 0)){
-                offset = dissect_a_block(tvb, offset, pinfo, tree, drep);
+                               offset = dissect_a_block(tvb, offset, pinfo, ar_tree, drep);
                 u16NumberofEntries--;
             }
+                       proto_item_set_len(ar_item, offset - u32ARDataStart);
         }
     }
     return offset;
@@ -8682,6 +8731,8 @@ dissect_PNIO_C_SDU(tvbuff_t *tvb, int offset,
 {
     proto_item *data_item;
     proto_tree *data_tree;
+    gint iTotalLen = 0;
+    gint iSubFrameLen = 0;
 
 
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO");
@@ -8691,11 +8742,13 @@ dissect_PNIO_C_SDU(tvbuff_t *tvb, int offset,
                     "PROFINET IO Cyclic Service Data Unit: %u bytes", tvb_length(tvb));
         data_tree = proto_item_add_subtree(data_item, ett_pn_io_rtc);
 
-        offset = dissect_PNIO_IOxS(tvb, offset, pinfo, data_tree, drep, hf_pn_io_ioxs);
-
+        /*dissect_dcerpc_uint16(tvb, offset, pinfo, data_tree, drep,hf_pn_io_packedframe_SFCRC, &u16SFCRC);*/
+        if(!(dissect_CSF_SDU_heur(tvb, pinfo, data_tree) == FALSE))
+            return(tvb_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 :-( */
+        offset = dissect_PNIO_IOxS(tvb, offset, pinfo, data_tree, drep, hf_pn_io_ioxs);
         offset = dissect_pn_user_data(tvb, offset, pinfo, tree, tvb_length_remaining(tvb, offset), "User Data (including GAP and RTCPadding)");
 
     }
@@ -8984,6 +9037,8 @@ proto_register_pn_io (void)
     { &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,
@@ -9247,6 +9302,10 @@ proto_register_pn_io (void)
       { "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, 0x0FF80, 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 }},
@@ -9784,7 +9843,7 @@ proto_register_pn_io (void)
     { &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,
-      { "Reserved (should be zero)", "pn_io.ds_res1", FT_UINT8, BASE_HEX, 0, 0x02, NULL, HFILL }},
+         { "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,
@@ -9946,7 +10005,9 @@ proto_register_pn_io (void)
     { &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,
-      { "Value", "pn_io.profidrive.parameter.value", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}
+      { "Value", "pn_io.profidrive.parameter.value", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+    { &hf_pn_io_packedframe_SFCRC,
+      { "SFCRC16", "pn_io.packedframe.sfcrc", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}
     };
 
     static gint *ett[] = {
@@ -9982,6 +10043,7 @@ proto_register_pn_io (void)
         &ett_pn_io_check_sync_mode,
         &ett_pn_io_ir_frame_data,
         &ett_pn_io_ar_info,
+        &ett_pn_io_ar_data,
         &ett_pn_io_ir_begin_end_port,
         &ett_pn_io_subframe_data,
         &ett_pn_io_frame_defails,
index 891093a3e19343fa24dc6f9cec6af0e1695eeb39..0975da66ab6e281bf0800f789e35b9ff937b8f37 100644 (file)
@@ -56,12 +56,12 @@ 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_data_status_subframe_sender_mode = -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_res1 = -1;
+static int hf_pn_rt_data_status_redundancy = -1;
 static int hf_pn_rt_data_status_primary = -1;
 
 static int hf_pn_rt_sf_crc16 = -1;
@@ -106,6 +106,11 @@ static const value_string pn_rt_position_control[] = {
     { 0x80, "CRC16 and CycleCounter valid" },
     { 0, NULL }
 };
+static const value_string pn_rt_ds_redundancy[] = {
+       { 0x00, "One primary AR of a given AR-set is present" },
+       { 0x01, "None primary AR of a given AR-set is present" },
+    { 0, NULL }
+};
 
 static const value_string pn_rt_frag_status_error[] = {
     { 0x00, "No error" },
@@ -137,18 +142,74 @@ dissect_DataStatus(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 u8DataSta
         (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_subframe_sender_mode, 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);
     proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_valid, tvb, offset, 1, u8DataStatus);
-    proto_tree_add_uint(sub_tree, hf_pn_rt_data_status_res1, tvb, offset, 1, u8DataStatus);
+    proto_tree_add_uint(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)
+{
+       guint16 u16SFCRC16;
+       guint8  u8SFPosition;
+       guint8  u8SFDataLength   = 255;
+       guint8  u8SFCycleCounter = 0;
+       guint8  u8SFDataStatus;
+       int offset = 0;
+       guint32 u32SubStart;
+       guint16 crc;
+    gint tvb_len =0;
+
+    offset += 2;    /*Skip first crc because data is no more available */
+    tvb_len = tvb_length(tvb);
+    if(offset + 4 > tvb_len)
+        return FALSE;
+    while(1) {
+        u32SubStart = offset;
+
+        u8SFPosition = tvb_get_guint8(tvb, offset);
+        offset += 1;
+
+        u8SFDataLength = tvb_get_guint8(tvb, offset);
+        offset += 1;
+
+        if(u8SFDataLength == 0) {
+            break;
+        }
+
+        u8SFCycleCounter = tvb_get_guint8(tvb, offset);
+        offset += 1;
+
+        u8SFDataStatus = tvb_get_guint8(tvb, offset);
+
+        offset += 1;
+
+        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(tvb, u32SubStart, offset-u32SubStart);
+                if(crc != u16SFCRC16) {
+                    return FALSE;
+                } else {
+                }
+            } else {
+            }
+        }
+        offset += 2;
+    }
+    return TRUE;
+}
+
 /* possibly dissect a CSF_SDU related PN-RT packet */
-static gboolean
+gboolean
 dissect_CSF_SDU_heur(tvbuff_t *tvb,
     packet_info *pinfo, proto_tree *tree)
 {
@@ -158,7 +219,7 @@ dissect_CSF_SDU_heur(tvbuff_t *tvb,
     guint8  u8SFDataLength = 255;
     guint8  u8SFCycleCounter;
     guint8  u8SFDataStatus;
-    int offset = 0;
+       gint offset = 0;
     guint32 u32SubStart;
     proto_item *sub_item;
     proto_tree *sub_tree;
@@ -170,12 +231,9 @@ dissect_CSF_SDU_heur(tvbuff_t *tvb,
     u16FrameID = GPOINTER_TO_UINT(pinfo->private_data);
 
     /* possible FrameID ranges for DFP */
-    if ((u16FrameID >= 0x0500 && u16FrameID < 0x05ff) ||
-        (u16FrameID >= 0x0600 && u16FrameID < 0x07ff) ||
-        (u16FrameID >= 0x4800 && u16FrameID < 0x4fff) ||
-        (u16FrameID >= 0x5800 && u16FrameID < 0x5fff) ||
-        (u16FrameID >= 0x6800 && u16FrameID < 0x6fff) ||
-        (u16FrameID >= 0x7800 && u16FrameID < 0x7fff)) {
+    if((u16FrameID < 0x100) || (u16FrameID > 0x0fff))
+        return (FALSE);
+    if (IsDFP_Frame(tvb)) {
         /* can't check this CRC, as the checked data bytes are not available */
         u16SFCRC16 = tvb_get_letohs(tvb, offset);
         proto_tree_add_uint(tree, hf_pn_rt_sf_crc16, tvb, offset, 2, u16SFCRC16);
@@ -187,7 +245,6 @@ dissect_CSF_SDU_heur(tvbuff_t *tvb,
             u32SubStart = offset;
 
             u8SFPosition = tvb_get_guint8(tvb, offset);
-            proto_tree_add_uint(sub_tree, hf_pn_rt_sf_position_control, tvb, offset, 1, u8SFPosition);
             proto_tree_add_uint(sub_tree, hf_pn_rt_sf_position, tvb, offset, 1, u8SFPosition);
             offset += 1;
 
@@ -214,7 +271,7 @@ dissect_CSF_SDU_heur(tvbuff_t *tvb,
             u16SFCRC16 = tvb_get_letohs(tvb, offset);
             item = proto_tree_add_uint(sub_tree, hf_pn_rt_sf_crc16, tvb, offset, 2, u16SFCRC16);
 
-            if(u8SFPosition & 0x80) {
+            if(u16SFCRC16 != 0 /* "old check": u8SFPosition & 0x80 */) {
                 crc = crc16_plain_tvb_offset(tvb, u32SubStart, offset-u32SubStart);
                 if(crc != u16SFCRC16) {
                     proto_item_append_text(item, " [Preliminary check: incorrect, should be: %u]", crc);
@@ -223,7 +280,7 @@ dissect_CSF_SDU_heur(tvbuff_t *tvb,
                     proto_item_append_text(item, " [Preliminary check: Correct]");
                 }
             } else {
-                proto_item_append_text(item, " [No preliminary check, Control bit not set]");
+                proto_item_append_text(item, " [No check, supplied CRC == zero]");
             }
             offset += 2;
 
@@ -264,7 +321,7 @@ dissect_FRAG_PDU_heur(tvbuff_t *tvb,
     u16FrameID = GPOINTER_TO_UINT(pinfo->private_data);
 
     /* possible FrameID ranges for FRAG_PDU */
-    if (u16FrameID >= 0xFF80 && u16FrameID < 0xFF8F) {
+    if (u16FrameID >= 0xFF80 && u16FrameID <= 0xFF8F) {
         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);
 
@@ -286,8 +343,7 @@ dissect_FRAG_PDU_heur(tvbuff_t *tvb,
             val_to_str( (u8FragStatus & 0x40) >> 6, pn_rt_frag_status_error, "Unknown"));
 
 
-        /* XXX - should this use u8FragDataLength? */
-        proto_tree_add_none_format(sub_tree, hf_pn_rt_frag_data, tvb, offset, tvb_length(tvb) - offset,
+               proto_tree_add_string_format(sub_tree, hf_pn_rt_frag_data, tvb, offset, tvb_length(tvb) - offset, "data", 
             "FragData: %d bytes", tvb_length(tvb) - offset);
 
         /* note: the actual defragmentation implementation is still missing here */
@@ -395,78 +451,24 @@ dissect_pn_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         pszProtComment  = "0x0082-0x00FF: Reserved ID";
         bCyclic         = FALSE;
 
-    } else if (u16FrameID <= 0x04FF){
+    } else if (u16FrameID <= 0x6FF) {
         pszProtShort    = "PN-RTC3";
         pszProtAddInfo  = "RTC3, ";
         pszProtSummary  = "Isochronous-Real-Time";
-        pszProtComment  = "0x0100-0x04FF: Isochronous-Real-Time(class=3): non redundant, normal";
-        bCyclic         = TRUE;
-    } else if (u16FrameID <= 0x05FF){
-        pszProtShort    = "PN-RTC3";
-        pszProtAddInfo  = "RTC3, ";
-        pszProtSummary  = "Isochronous-Real-Time";
-        pszProtComment  = "0x0500-0x05FF: Isochronous-Real-Time(class=3): non redundant, DFP";
-        bCyclic         = TRUE;
-    } else if (u16FrameID <= 0x07FF){
-        pszProtShort    = "PN-RTC3";
-        pszProtAddInfo  = "RTC3, ";
-        pszProtSummary  = "Isochronous-Real-Time";
-        pszProtComment  = "0x0600-0x07FF: Isochronous-Real-Time(class=3): redundant, DFP";
+        pszProtComment = "0x0100-0x06FF: RED: Real-Time(class=3): non redundant, normal or DFP";
         bCyclic         = TRUE;
     } else if (u16FrameID <= 0x0FFF){
         pszProtShort    = "PN-RTC3";
         pszProtAddInfo  = "RTC3, ";
         pszProtSummary  = "Isochronous-Real-Time";
-        pszProtComment  = "0x0800-0x0FFF: Isochronous-Real-Time(class=3): redundant, normal";
+        pszProtComment = "0x0700-0x0FFF: RED: Real-Time(class=3): redundant, normal or DFP";
         bCyclic         = TRUE;
-    } else if (u16FrameID <= 0x47FF) {
+    } else if (u16FrameID <= 0x7FFF) {
         pszProtShort    = "PN-RT";
         pszProtAddInfo  = "reserved, ";
         pszProtSummary  = "Real-Time";
-        pszProtComment  = "0x1000-0x47FF: Reserved ID";
+        pszProtComment = "0x1000-0x7FFF: Reserved ID";
         bCyclic         = FALSE;
-    } else if (u16FrameID <= 0x4FFF){
-        pszProtShort    = "PN-RTC2";
-        pszProtAddInfo  = "RTC2, ";
-        pszProtSummary  = "cyclic Real-Time";
-        pszProtComment  = "0x4800-0x4FFF: Real-Time(class=2): redundant, DFP";
-        bCyclic         = TRUE;
-    } else if (u16FrameID < 0x57FF){
-        pszProtShort    = "PN-RTC2";
-        pszProtAddInfo  = "RTC2, ";
-        pszProtSummary  = "cyclic Real-Time";
-        pszProtComment  = "0x5000-0x57FF: Real-Time(class=2): redundant, normal";
-        bCyclic         = TRUE;
-    } else if (u16FrameID <= 0x5FFF){
-        pszProtShort    = "PN-RTC2";
-        pszProtAddInfo  = "RTC2, ";
-        pszProtSummary  = "cyclic Real-Time";
-        pszProtComment  = "0x5800-0x5FFF: Real-Time(class=2): non redundant, DFP";
-        bCyclic         = TRUE;
-    } else if (u16FrameID <= 0x67FF){
-        pszProtShort    = "PN-RTC2";
-        pszProtAddInfo  = "RTC2, ";
-        pszProtSummary  = "cyclic Real-Time";
-        pszProtComment  = "0x6000-0x67FF: Real-Time(class=2): non redundant, normal";
-        bCyclic         = TRUE;
-    } else if (u16FrameID <= 0x6FFF){
-        pszProtShort    = "PN-RTC2";
-        pszProtAddInfo  = "RTC2, ";
-        pszProtSummary  = "cyclic Real-Time";
-        pszProtComment  = "0x6800-0x6FFF: Real-Time(class=2): redundant, DFP";
-        bCyclic         = TRUE;
-    } else if (u16FrameID <= 0x77FF){
-        pszProtShort    = "PN-RTC2";
-        pszProtAddInfo  = "RTC2, ";
-        pszProtSummary  = "cyclic Real-Time";
-        pszProtComment  = "0x7000-0x77FF: Real-Time(class=2): redundant, normal";
-        bCyclic         = TRUE;
-    } else if (u16FrameID <= 0x7FFF){
-        pszProtShort    = "PN-RTC2";
-        pszProtAddInfo  = "RTC2, ";
-        pszProtSummary  = "cyclic Real-Time";
-        pszProtComment  = "0x7800-0x7FFF: Real-Time(class=2): non redundant, DFP";
-        bCyclic         = TRUE;
     } else if (u16FrameID <= 0xBBFF){
         pszProtShort    = "PN-RTC2";
         pszProtAddInfo  = "RTC2, ";
@@ -690,18 +692,18 @@ proto_register_pn_rt(void)
         "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_data_status_subframe_sender_mode, {
-        "SubFrameSenderMode", "pn_rt.ds_subframe_sender_mode", FT_UINT8, BASE_HEX, 0, 0x40, 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 (should be zero)", "pn_rt.ds_res3", FT_UINT8, BASE_HEX, 0, 0x08, NULL, HFILL }},
+        "Reserved_1 (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_res1, {
-        "Reserved (should be zero)", "pn_rt.ds_res1", FT_UINT8, BASE_HEX, 0, 0x02, NULL, HFILL }},
+    { &hf_pn_rt_data_status_redundancy, { 
+        "Redundancy", "pn_rt.ds_redundancy", FT_UINT8, BASE_HEX, VALS(pn_rt_ds_redundancy), 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,
@@ -709,7 +711,7 @@ proto_register_pn_rt(void)
     { &hf_pn_rt_sf, {
         "SubFrame", "pn_rt.sf", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
     { &hf_pn_rt_sf_crc16, {
-        "CRC16", "pn_rt.sf.crc16", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        "SFCRC16", "pn_rt.sf.crc16", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
     { &hf_pn_rt_sf_position, {
         "Position", "pn_rt.sf.position", FT_UINT8, BASE_DEC, NULL, 0x7F, NULL, HFILL }},
     { &hf_pn_rt_sf_position_control, {
index 769f6a58c2060cbde72d0e32afcc8043493eec59..45d10a65d817da21e4a38104cccc4daf4f7d8046 100644 (file)
@@ -74,3 +74,5 @@ extern int dissect_pn_padding(tvbuff_t *tvb, int offset, packet_info *pinfo,
 extern int dissect_pn_align4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
 
 extern void pn_append_info(packet_info *pinfo, proto_item *dcp_item, const char *text);
+
+extern gboolean dissect_CSF_SDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);