diff options
-rw-r--r-- | AUTHORS | 4 | ||||
-rw-r--r-- | plugins/profinet/packet-dcerpc-pn-io.c | 953 | ||||
-rw-r--r-- | plugins/profinet/packet-pn-dcp.c | 6 | ||||
-rw-r--r-- | plugins/profinet/packet-pn-mrp.c | 165 | ||||
-rw-r--r-- | plugins/profinet/packet-pn-ptcp.c | 67 | ||||
-rw-r--r-- | plugins/profinet/packet-pn-rt.c | 236 | ||||
-rw-r--r-- | plugins/profinet/packet-pn.c | 8 | ||||
-rw-r--r-- | plugins/profinet/packet-pn.h | 6 |
8 files changed, 1181 insertions, 264 deletions
@@ -3477,6 +3477,10 @@ Michal Labedzki <michal.labedzki[at]tieto.com> { Bluetooth HCI USB transport dissector } +Wido Kelling <kellingwido[At]aol.com> { + Profinet: Updated disecction regarding the IEC 61158 +} + and by: diff --git a/plugins/profinet/packet-dcerpc-pn-io.c b/plugins/profinet/packet-dcerpc-pn-io.c index 0b12c67a58..0e3ac584ac 100644 --- a/plugins/profinet/packet-dcerpc-pn-io.c +++ b/plugins/profinet/packet-dcerpc-pn-io.c @@ -74,6 +74,7 @@ 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; @@ -123,6 +124,11 @@ static int hf_pn_io_sr_properties = -1; static int hf_pn_io_sr_properties_InputValidOnBackupAR = -1; static int hf_pn_io_sr_properties_ActivateRedundancyAlarm = -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; @@ -144,6 +150,11 @@ 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; @@ -160,6 +171,7 @@ 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; @@ -337,10 +349,8 @@ 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; -#if 0 /* replaced with 2 bit values */ -static int hf_pn_io_channel_properties_maintenance_required = -1; -static int hf_pn_io_channel_properties_maintenance_demanded = -1; -#endif + + 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; @@ -386,6 +396,9 @@ 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_ifInOctets = -1; static int hf_pn_io_pdportstatistic_ifOutOctets = -1; @@ -440,10 +453,19 @@ 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 = -1; -static int hf_pn_io_orange_period_begin = -1; -static int hf_pn_io_green_period_begin = -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; @@ -516,6 +538,8 @@ 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; @@ -524,6 +548,10 @@ 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; @@ -621,9 +649,12 @@ 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_frame_defails = -1; static gint ett_pn_io_profisafe_f_parameter = -1; @@ -705,7 +736,8 @@ static const value_string pn_io_block_type[] = { { 0x0106, "MCRBlockReq"}, { 0x8106, "ARServerBlock"}, { 0x0107, "SubFrameBlock"}, - { 0x0108, "ARVendorBlock"}, + { 0x0108, "ARVendorBlockReq"}, + { 0x8108, "ARVendorBlockRes"}, { 0x0109, "IRInfoBlock"}, { 0x010A, "SRInfoBlock"}, { 0x010B, "ARFSUBlock"}, @@ -771,7 +803,11 @@ static const value_string pn_io_block_type[] = { { 0x022A, "PDIRSubframeData"}, { 0x022B, "SubframeBlock"}, { 0x0230, "PDNCDataCheck"}, + { 0x0231, "MrpInstanceDataAdjust"}, + { 0x0232, "MrpInstanceDataReal"}, + { 0x0233, "MrpInstanceDataCheck"}, { 0x0240, "PDInterfaceDataReal"}, + { 0x0250, "PDInterfaceAdjust"}, { 0x0251, "PDPortStatistic"}, { 0x0400, "MultipleBlockHeader"}, { 0x0500, "RecordDataReadQuery"}, @@ -836,15 +872,28 @@ static const value_string pn_io_pdu_type[] = { { 0, NULL } }; -static const value_string pn_io_frame_data_properties[] = { - { 0x00, "absolute mode use interface MAC" }, - { 0x01, "relative mode use interface MAC" }, - { 0x02, "absolute mode use RT_CLASS_3 destination MAC" }, - { 0x03, "relative mode use RT_CLASS_3 destination MAC" }, - { 0x04, "absolute mode use FastForwarding destination MAC" }, - { 0x05, "relative mode use FastForwarding destination MAC" }, - { 0x06, "absolute mode use FastForwarding MAC" }, - { 0x07, "relative mode use FastForwarding MAC" }, +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 } }; @@ -1390,16 +1439,16 @@ static const value_string pn_io_ioxs[] = { static const value_string pn_io_ar_type[] = { { 0x0000, "reserved" }, - { 0x0001, "IOCARSingle" }, + { 0x0001, "IO Controller AR"}, { 0x0002, "reserved" }, { 0x0003, "IOCARCIR" }, - { 0x0004, "IOCAR_IOControllerRedundant" }, - { 0x0005, "IOCAR_IODeviceRedundant" }, - { 0x0006, "IOSAR" }, + { 0x0004, "reserved" }, + { 0x0005, "reserved" }, + { 0x0006, "IO Supervisor AR / DeviceAccess AR" }, /*0x0007 - 0x000F reserved */ - { 0x0010, "IOCARSingle using RT_CLASS_3"}, + { 0x0010, "IO Controller AR (RT_CLASS_3)" }, /*0x0011 - 0x001F reserved */ - { 0x0020, "IOCARSR" }, + { 0x0020, "IO Controller AR (sysred/CiR)" }, /*0x0007 - 0xFFFF reserved */ { 0, NULL } }; @@ -1522,6 +1571,12 @@ static const value_string pn_io_iocr_properties_rtclass[] = { { 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 value_string pn_io_sr_properties_BackupAR[] = { { 0x00000000, "The device may deliver valid input data" }, { 0x00000001, "The device shall deliver valid input data" }, @@ -2010,10 +2065,56 @@ static const value_string pn_io_ext_channel_error_type0x8001[] = { static const value_string pn_io_ext_channel_error_type0x8002[] = { /* 0x0000 Reserved */ /* 0x0001 - 0x7FFF Manufacturer specific */ - { 0x8000, "Manager role fail"}, - { 0x8001, "MRP ring open"}, + { 0x8000, "Manager role fail MRP-instance 1"}, + { 0x8001, "MRP-instance 1 ring open"}, { 0x8002, "Reserved"}, - { 0x8003, "Multiple mananger"}, + { 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 */ @@ -2273,6 +2374,37 @@ static const value_string pn_io_mrp_role_vals[] = { { 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" }, @@ -2887,12 +3019,6 @@ dissect_ChannelProperties(tvbuff_t *tvb, int offset, hf_pn_io_channel_properties_direction, &u16ChannelProperties); dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_channel_properties_specifier, &u16ChannelProperties); -#if 0 /* replaced with 2 bit values */ - dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep, - hf_pn_io_channel_properties_maintenance_demanded, &u16ChannelProperties); - dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep, - hf_pn_io_channel_properties_maintenance_required, &u16ChannelProperties); -#endif 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, @@ -3448,7 +3574,7 @@ dissect_SubstituteValue_block(tvbuff_t *tvb, int offset, 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, "SubstituteDataObjectElement"); + dissect_pn_user_data_bytes(tvb, offset, pinfo, tree, u16BodyLength, SUBST_DATA); return offset; } @@ -4272,17 +4398,19 @@ dissect_PDInterfaceMrpDataAdjust_block(tvbuff_t *tvb, int offset, e_uuid_t uuid; guint16 u16Role; guint8 u8LengthDomainName; + guint8 u8NumberOfMrpInstances; char *pDomainName; int iStartOffset = offset; - if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { + if(u8BlockVersionHigh != 1 || u8BlockVersionLow > 1) { /* added low version == 1 */ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow); return offset; } - /* Padding */ + if(u8BlockVersionLow == 0) /*dissect LowVersion == 0 */ + { offset = dissect_pn_align4(tvb, offset, pinfo, tree); /* MRP_DomainUUID */ @@ -4310,6 +4438,25 @@ dissect_PDInterfaceMrpDataAdjust_block(tvbuff_t *tvb, int offset, { offset = dissect_blocks(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, PI_UNDECODED, PI_WARN, + "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; } @@ -4322,6 +4469,7 @@ dissect_PDInterfaceMrpDataReal_block(tvbuff_t *tvb, int offset, guint16 u16Role; guint16 u16Version; guint8 u8LengthDomainName; + guint8 u8NumberOfMrpInstances; char *pDomainName; int endoffset = offset + u16BodyLength; @@ -4332,6 +4480,8 @@ dissect_PDInterfaceMrpDataReal_block(tvbuff_t *tvb, int offset, return offset; } + if(u8BlockVersionLow < 2) /* dissect low versions 0 and 1 */ + { /* Padding */ offset = dissect_pn_align4(tvb, offset, pinfo, tree); @@ -4365,10 +4515,29 @@ dissect_PDInterfaceMrpDataReal_block(tvbuff_t *tvb, int offset, /* Padding */ offset = dissect_pn_align4(tvb, offset, pinfo, tree); - while (endoffset < offset) + 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, PI_UNDECODED, PI_WARN, + "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; } @@ -4378,15 +4547,17 @@ 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_uuid_t uuid; - guint16 u16Check; - + guint32 u32Check; + guint8 u8NumberOfMrpInstances; - if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { + /* BlockVersionLow == 1 added */ + if(u8BlockVersionHigh != 1 || u8BlockVersionLow > 1) { expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow); return offset; } - + if(u8BlockVersionLow == 0) + { offset = dissect_pn_align4(tvb, offset, pinfo, tree); /* MRP_DomainUUID */ @@ -4394,10 +4565,36 @@ dissect_PDInterfaceMrpDataCheck_block(tvbuff_t *tvb, int offset, hf_pn_io_mrp_domain_uuid, &uuid); /* MRP_Check */ - /* XXX - this field is 32bit in the spec but 16 bit in the implementation */ - /* this will be fixed in the next implementation release */ - offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, - hf_pn_io_mrp_check, &u16Check); + 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, PI_UNDECODED, PI_WARN, + "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; } @@ -4408,16 +4605,25 @@ 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_uuid_t uuid; + guint8 u8MrpInstance; - - if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { + /* added BlockVersionLow == 1 */ + if(u8BlockVersionHigh != 1 || u8BlockVersionLow > 1) { expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "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); @@ -5100,44 +5306,164 @@ dissect_PDPortFODataCheck_block(tvbuff_t *tvb, int offset, return offset; } -#if 0 -/* dissect the PDNCDataCheck block */ static int -dissect_PDNCDataCheck_block(tvbuff_t *tvb, int offset, - packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow) +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) { - guint32 u32NCDropBudget; + guint8 u8MrpInstance; + e_uuid_t uuid; + guint16 u16Role; + guint8 u8LengthDomainName; + char* pDomainName; + int endoffset = offset + u16BodyLength; + + if(u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { + expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, + "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 */ + pDomainName = ep_alloc(u8LengthDomainName+1); + tvb_memcpy(tvb, (guint8 *) pDomainName, offset, u8LengthDomainName); + pDomainName[u8LengthDomainName] = '\0'; + proto_tree_add_string (tree, hf_pn_io_mrp_domain_name, tvb, offset, u8LengthDomainName, pDomainName); + 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_uuid_t uuid; + guint16 u16Role; + guint16 u16Version; + guint8 u8LengthDomainName; + char* pDomainName; + int endoffset = offset + u16BodyLength; if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "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 */ + pDomainName = ep_alloc(u8LengthDomainName+1); + tvb_memcpy(tvb, (guint8 *) pDomainName, offset, u8LengthDomainName); + pDomainName[u8LengthDomainName] = '\0'; + proto_tree_add_string (tree, hf_pn_io_mrp_domain_name, tvb, offset, u8LengthDomainName, pDomainName); + offset += u8LengthDomainName; /* Padding */ offset = dissect_pn_align4(tvb, offset, pinfo, tree); - /* MaintenanceRequiredDropBudget */ - /* XXX - decode the u32NCDropBudget better */ - offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, - hf_pn_io_maintenance_required_drop_budget, &u32NCDropBudget); + 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_uuid_t uuid; - /* MaintenanceDemandedDropBudget */ - offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, - hf_pn_io_maintenance_demanded_drop_budget, &u32NCDropBudget); + if(u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { + expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, + "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); - /* ErrorDropBudget */ - offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, - hf_pn_io_error_drop_budget, &u32NCDropBudget); + /* 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 */ -/* - proto_item_append_text(item, ": %s", - val_to_str(u16PortState, pn_io_port_state, "0x%x"));*/ + 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, PI_UNDECODED, PI_WARN, + "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; } -#endif /* PDPortStatistic for one subslot */ static int @@ -5511,8 +5837,19 @@ dissect_PDIRFrameData_block(tvbuff_t *tvb, int offset, u16EndOffset = offset + u16BodyLength -2; if (u8BlockVersionLow > 0) { /* for low version 1 FrameDataProperties is added */ - offset = dissect_dcerpc_uint32(tvb, offset, pinfo, ir_frame_data_tree, drep, - hf_pn_io_frame_data_properties, &u32FrameDataProperties); + 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) @@ -5609,10 +5946,20 @@ dissect_PDIRBeginEndData_block(tvbuff_t *tvb, int offset, guint32 u32GreenPeriodBegin; guint16 u16TXPhaseAssignment; guint16 u16RXPhaseAssignment; + proto_tree *ir_begin_end_port_tree = NULL; + proto_tree *ir_begin_tx_phase_tree = NULL; + proto_item *ir_begin_tx_phase_sub_item = NULL; + proto_item *ir_begin_end_port_sub_item = NULL; 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, PI_UNDECODED, PI_WARN, @@ -5631,54 +5978,101 @@ dissect_PDIRBeginEndData_block(tvbuff_t *tvb, int offset, hf_pn_io_number_of_ports, &u32NumberOfPorts); u32Tmp2 = u32NumberOfPorts; while (u32Tmp2--) { - proto_tree *ir_begin_end_port_tree; - proto_item *ir_begin_end_port_sub_item; - /* 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); + 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, &u32RedOrangePeriodBegin); + 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, &u32OrangePeriodBegin); + 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, &u32GreenPeriodBegin); + 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, &u32RedOrangePeriodBegin); + 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, &u32OrangePeriodBegin); + 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, &u32GreenPeriodBegin); + 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--) { - offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_end_port_tree, drep, - hf_pn_io_tx_phase_assignment, &u16TXPhaseAssignment); - offset = dissect_dcerpc_uint16(tvb, offset, pinfo, ir_begin_end_port_tree, drep, - hf_pn_io_rx_phase_assignment, &u16RXPhaseAssignment); + /* 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, ": StartOfRed: 0x%x, EndOfRed: 0x%x, Ports:%u", + proto_item_append_text(item, ": StartOfRedFrameID: 0x%x, EndOfRedFrameID: 0x%x, Ports: %u", u16StartOfRedFrameID, u16EndOfRedFrameID, u32NumberOfPorts); return offset+u16BodyLength; @@ -6329,6 +6723,27 @@ dissect_ARFSUDataAdjust_block(tvbuff_t *tvb, int offset, return offset; } +static 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, @@ -6336,6 +6751,7 @@ dissect_ARBlockReq_block(tvbuff_t *tvb, int offset, pnio_ar_t ** ar) { guint16 u16ARType; + guint32 u32ARProperties; e_uuid_t aruuid; e_uuid_t uuid; guint16 u16SessionKey; @@ -6353,8 +6769,18 @@ dissect_ARBlockReq_block(tvbuff_t *tvb, int offset, return offset; } - offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, - hf_pn_io_ar_type, &u16ARType); + 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; offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep, hf_pn_io_ar_uuid, &aruuid); offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, @@ -6381,7 +6807,7 @@ dissect_ARBlockReq_block(tvbuff_t *tvb, int offset, offset += u16NameLength; proto_item_append_text(item, ": %s, Session:%u, MAC:%02x:%02x:%02x:%02x:%02x:%02x, Port:0x%x, Station:%s", - val_to_str(u16ARType, pn_io_ar_type, "0x%x"), + decode_ARType_spezial(u16ARType,u32ARProperties), u16SessionKey, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], u16UDPRTPort, @@ -6935,6 +7361,8 @@ dissect_PDSubFrameBlock_block(tvbuff_t *tvb, int offset, guint32 u32SFIOCRProperties; guint32 u32SubFrameData; guint16 u16FrameID; + proto_item *sub_item; + proto_tree *sub_tree; if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, @@ -6960,23 +7388,30 @@ dissect_PDSubFrameBlock_block(tvbuff_t *tvb, int offset, /* Bit 28 - 29: SFIOCRProperties.reserved_2 */ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_SFIOCRProperties_reserved_2, &u32SFIOCRProperties); /* Bit 30: SFIOCRProperties.DFPRedundantPathLayout */ + dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_SFIOCRProperties_DFPType, &u32SFIOCRProperties); + /* Bit 30: SFIOCRProperties.DFPRedundantPathLayout */ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_SFIOCRProperties_DFPRedundantPathLayout, &u32SFIOCRProperties); /* Bit 31: SFIOCRProperties.SFCRC16 */ offset = /* it is the last one, so advance! */ dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_SFIOCRProperties_SFCRC16, &u32SFIOCRProperties); /* SubframeData */ - dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_subframe_data, &u32SubFrameData); + while (tvb_bytes_exist(tvb, offset, 4)) + { +/* dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, hf_pn_io_subframe_data, &u32SubFrameData); */ + 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, tree, drep, hf_pn_io_subframe_data_position, &u32SubFrameData); + 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, tree, drep, hf_pn_io_subframe_reserved1, &u32SubFrameData); + 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, tree, drep, hf_pn_io_subframe_data_length, &u32SubFrameData); + 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, tree, drep, hf_pn_io_subframe_reserved2, &u32SubFrameData); - + dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep, hf_pn_io_subframe_reserved2, &u32SubFrameData); + } return offset; } @@ -7055,9 +7490,6 @@ 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; - proto_item *sub_item; - proto_tree *sub_tree; - if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, @@ -7068,57 +7500,70 @@ dissect_PDIRSubframeData_block(tvbuff_t *tvb, int offset, while (u16NumberOfSubframeBlocks --) { /* dissect the Subframe Block */ - 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); - dissect_a_block(tvb, offset, pinfo, sub_tree, drep); - + offset = dissect_a_block(tvb, offset, pinfo, /*sub_*/tree, drep); } return offset; } - static int -dissect_IRTFrameBlock_block(tvbuff_t *tvb, int offset, +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 u16IOCRReference; - guint8 u8IOCRTxPortsRedundantPort; - guint8 u8IOCRTxPortsPort; - guint32 u32FrameSendOffset; - + guint16 APStructureIdentifier; + guint32 gu32API; + guint32 guDataBytes; if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) { expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow); return offset; } - offset = dissect_pn_padding(tvb, offset, pinfo, tree, 2); + APStructureIdentifier = ((drep[0] & DREP_LITTLE_ENDIAN) + ? tvb_get_letohs(tvb, offset) + : tvb_get_ntohs(tvb, offset)); - /* IOCRReference */ - offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, - hf_pn_io_iocr_reference, &u16IOCRReference); - - /* IOCRTxPortsRedundantPort */ - offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep, - hf_pn_io_iocr_txports_redundantport, &u8IOCRTxPortsRedundantPort); - - /* IOCRTxPortsPort */ - offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep, - hf_pn_io_iocr_txports_port, &u8IOCRTxPortsPort); + gu32API = ((drep[0] & DREP_LITTLE_ENDIAN) + ? tvb_get_letohl(tvb, offset + 2) + : tvb_get_ntohl (tvb, offset + 2)); - /* FrameSendOffset */ - offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep, - hf_pn_io_frame_send_offset, &u32FrameSendOffset); - - proto_item_append_text(item, ", CRRef:%u, Port:%u, RedPort:%u, Offset:%u", - u16IOCRReference, u8IOCRTxPortsPort, u8IOCRTxPortsRedundantPort, u32FrameSendOffset); + 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, @@ -7704,7 +8149,8 @@ dissect_block(tvbuff_t *tvb, int offset, dissect_SubFrameBlock_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength); break; case(0x0108): - dissect_IRTFrameBlock_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u8BlockVersionHigh, u8BlockVersionLow, u16BodyLength); + 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); @@ -7852,9 +8298,22 @@ dissect_block(tvbuff_t *tvb, int offset, 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(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; @@ -8340,8 +8799,18 @@ dissect_RecordDataRead(tvbuff_t *tvb, int offset, case(0xf821): /* APIData */ case(0xf830): /* LogData */ case(0xf831): /* PDevData */ + 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): @@ -8581,6 +9050,7 @@ dissect_RecordDataWrite(tvbuff_t *tvb, int offset, case(0x8061): /* PDPortFODataCheck for one subslot */ case(0x8062): /* PDPortFODataAdjust for one subslot */ case(0x8070): /* PDNCDataCheck for one subslot */ + case(0x8071): /* PDInterfaceAdjust */ case(0x8090): /* PDInterfaceFSUDataAdjust */ case(0xe030): /* IsochronousModeData for one AR */ @@ -8700,8 +9170,8 @@ dissect_PNIO_IOxS(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, int hfindex) { guint8 u8IOxS; - proto_item *ioxs_item; - proto_tree *ioxs_tree; + proto_item *ioxs_item = NULL; + proto_tree *ioxs_tree = NULL; u8IOxS = tvb_get_guint8(tvb, offset); @@ -8872,7 +9342,7 @@ dissect_PNIO_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, * to dissect it as a normal PNIO packet. */ if (dissector_try_heuristic(heur_pn_subdissector_list, tvb, pinfo, tree, NULL)) - return FALSE; + return TRUE; /* the sub tvb will NOT contain the frame_id here! */ u16FrameID = GPOINTER_TO_UINT(pinfo->private_data); @@ -9115,16 +9585,10 @@ proto_register_pn_io (void) 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_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, @@ -9285,6 +9749,26 @@ proto_register_pn_io (void) FT_UINT32, BASE_HEX, NULL, 0x0FFFF0000, 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", @@ -9364,7 +9848,12 @@ proto_register_pn_io (void) }, { &hf_pn_io_SFIOCRProperties_reserved_2, { "SFIOCRProperties.reserved_2", "pn_io.SFIOCRProperties.reserved_2", - FT_UINT32, BASE_HEX, NULL, 0x030000000, + FT_UINT32, BASE_HEX, NULL, 0x010000000, + NULL, HFILL } + }, + { &hf_pn_io_SFIOCRProperties_DFPType, + { "SFIOCRProperties.DFPType", "pn_io.SFIOCRProperties.DFPType", + FT_UINT32, BASE_HEX, VALS(pn_io_SFIOCRProperties_DFPType_vals), 0x020000000, NULL, HFILL } }, { &hf_pn_io_SFIOCRProperties_DFPRedundantPathLayout, @@ -9420,9 +9909,35 @@ proto_register_pn_io (void) }, { &hf_pn_io_frame_data_properties, { "FrameDataProperties", "pn_io.frame_data_properties", - FT_UINT32, BASE_HEX, VALS(pn_io_frame_data_properties), 0x0, + 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, @@ -10208,34 +10723,49 @@ proto_register_pn_io (void) FT_UINT16, BASE_HEX, VALS(pn_io_user_structure_identifier), 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, - { "Reserved1", "pn_io.subframe_data.reserved1", - FT_UINT32, BASE_DEC, NULL, 0xFFFF0000, + { "Reserved1", "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_DEC, NULL, 0x0000FF00, + FT_UINT32, BASE_HEX, NULL, 0x0000FF00, NULL, HFILL } }, { &hf_pn_io_subframe_reserved1, { "Reserved1", "pn_io.subframe_data.reserved1", - FT_UINT32, BASE_DEC, NULL, 0x00000080, + FT_UINT32, BASE_HEX, NULL, 0x00000080, NULL, HFILL } }, { &hf_pn_io_subframe_data_position, { "DataPosition", "pn_io.subframe_data.position", - FT_UINT32, BASE_DEC, NULL, 0x0000007F, + 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, + { "Reserved1", "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, VALS(pn_io_channel_number), 0x0, @@ -10257,18 +10787,7 @@ proto_register_pn_io (void) FT_UINT16, BASE_HEX, NULL, 0x0100, NULL, HFILL } }, -#if 0 /* replaced with 2 bit values */ - { &hf_pn_io_channel_properties_maintenance_required, - { "MaintenanceRequired", "pn_io.channel_properties.maintenance_required", - FT_UINT16, BASE_HEX, NULL, 0x0200, - NULL, HFILL } - }, - { &hf_pn_io_channel_properties_maintenance_demanded, - { "MaintenanceDemanded", "pn_io.channel_properties.maintenance_demanded", - FT_UINT16, BASE_HEX, NULL, 0x0400, - NULL, HFILL } - }, -#endif + { &hf_pn_io_NumberOfSubframeBlocks, { "NumberOfSubframeBlocks", "pn_io.NumberOfSubframeBlocks", FT_UINT16, BASE_DEC, NULL, 0x0, @@ -10475,6 +10994,12 @@ proto_register_pn_io (void) 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_ifInOctets, { "ifInOctets", "pn_io.ifInOctets", FT_UINT32, BASE_HEX, NULL, 0x0, @@ -10723,18 +11248,33 @@ proto_register_pn_io (void) FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, - { &hf_pn_io_red_orange_period_begin, - { "RedOrangePeriodBegin", "pn_io.red_orange_period_begin", + { &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, - { "OrangePeriodBegin", "pn_io.orange_period_begin", + { &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, - { "GreenPeriodBegin", "pn_io.green_period_begin", + { &hf_pn_io_green_period_begin_rx, + { "GreenPeriodBegin [RX]", "pn_io.green_period_begin_rx", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, @@ -10743,6 +11283,36 @@ proto_register_pn_io (void) FT_UINT16, 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, 0x0F, + NULL, HFILL } + }, + { &hf_pn_io_tx_phase_assignment_orange_begin, + { "AssignedValueForOrangeBegin", "pn_io.tx_phase_assignment_orange_begin", + FT_UINT16, BASE_DEC, NULL, 0x0F0, + 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, 0x0F000, + 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_rx_phase_assignment, { "RXPhaseAssignment", "pn_io.rx_phase_assignment", FT_UINT16, BASE_DEC, NULL, 0x0, @@ -11057,6 +11627,16 @@ proto_register_pn_io (void) 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", @@ -11090,7 +11670,27 @@ proto_register_pn_io (void) }, { &hf_pn_io_mrp_check, { "MRP_Check", "pn_io.mrp_check", - FT_UINT16, BASE_HEX, NULL, 0x0, + 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, 0x0FFFFFC, + NULL, HFILL } + }, + { &hf_pn_io_mrp_check_reserved_2, + { "MRP_Check.reserved_2", "pn_io.mrp_check_reserved_2", + FT_UINT32, BASE_HEX, NULL, 0x0FF000000, NULL, HFILL } }, @@ -11409,9 +12009,12 @@ proto_register_pn_io (void) &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_frame_defails, &ett_pn_io_profisafe_f_parameter, diff --git a/plugins/profinet/packet-pn-dcp.c b/plugins/profinet/packet-pn-dcp.c index aae9bbe407..12dc1db683 100644 --- a/plugins/profinet/packet-pn-dcp.c +++ b/plugins/profinet/packet-pn-dcp.c @@ -467,13 +467,13 @@ dissect_PNDCP_Suboption_Device(tvbuff_t *tvb, int offset, packet_info *pinfo, tvb_memcpy(tvb, (guint8 *) typeofstation, offset, block_length); typeofstation[block_length] = '\0'; proto_tree_add_string (tree, hf_pn_dcp_suboption_device_typeofstation, tvb, offset, block_length, typeofstation); - pn_append_info(pinfo, dcp_item, ", 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(block_qualifier, pn_dcp_block_qualifier, "Unknown")); if(have_block_info) proto_item_append_text(block_item, ", BlockInfo: %s", val_to_str(block_info, pn_dcp_block_info, "Unknown")); - proto_item_append_text(block_item, ", TypeOfStation: \"%s\"", typeofstation); + proto_item_append_text(block_item, ", DeviceVendorValue: \"%s\"", typeofstation); offset += block_length; break; case(PNDCP_SUBOPTION_DEVICE_NAMEOFSTATION): @@ -998,7 +998,7 @@ proto_register_pn_dcp (void) { &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, - { "TypeOfStation", "pn_dcp.suboption_device_typeofstation", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { "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, diff --git a/plugins/profinet/packet-pn-mrp.c b/plugins/profinet/packet-pn-mrp.c index 7afc858b89..3bd88eb580 100644 --- a/plugins/profinet/packet-pn-mrp.c +++ b/plugins/profinet/packet-pn-mrp.c @@ -48,7 +48,10 @@ 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; +#if 0 /* XXX: not used ? */ static int hf_pn_mrp_manufacturer_oui = -1; +#endif +static int hf_pn_manufacturer_data = -1; static int hf_pn_mrp_domain_uuid = -1; static int hf_pn_mrp_oui = -1; @@ -85,6 +88,15 @@ static const value_string pn_mrp_port_role_vals[] = { { 0, NULL } }; +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 } +}; static const value_string pn_mrp_ring_state_vals[] = { { 0x0000, "Ring open" }, @@ -100,6 +112,26 @@ static const value_string pn_mrp_prio_vals[] = { { 0, NULL } }; +/* routine disecting an uint16 and returning that item as well */ +/* dissect a 16 bit unsigned integer */ +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); + + if (tree) { + item = proto_tree_add_uint(tree, hfindex, tvb, offset, 2, data); + } + if (pdata) + *pdata = data; + if(new_item) + *new_item = item; + return offset + 2; +} @@ -124,7 +156,7 @@ dissect_PNMRP_Common(tvbuff_t *tvb, int offset, return offset; } - +#if 0 static int dissect_PNMRP_LinkUp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, proto_item *item) @@ -155,7 +187,7 @@ dissect_PNMRP_LinkUp(tvbuff_t *tvb, int offset, return offset; } - +#endif static int dissect_PNMRP_LinkDown(tvbuff_t *tvb, int offset, @@ -165,6 +197,7 @@ dissect_PNMRP_LinkDown(tvbuff_t *tvb, int offset, 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); @@ -173,10 +206,24 @@ dissect_PNMRP_LinkDown(tvbuff_t *tvb, int offset, offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_port_role, &port_role); /* MRP_Interval */ - offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_interval, &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(tvb, offset, pinfo, tree, hf_pn_mrp_blocked, &blocked); + offset = dissect_pn_uint16_ret_item(tvb, offset, pinfo, tree, hf_pn_mrp_blocked, &blocked, &sub_item); + 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); @@ -188,6 +235,28 @@ dissect_PNMRP_LinkDown(tvbuff_t *tvb, int offset, return offset; } +static 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, @@ -198,11 +267,14 @@ dissect_PNMRP_Test(tvbuff_t *tvb, int offset, guint16 port_role; guint16 ring_state; guint16 transition; - guint16 time_stamp; + guint32 time_stamp; + proto_item *sub_item; /* MRP_Prio */ - offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_prio, &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); @@ -217,13 +289,13 @@ dissect_PNMRP_Test(tvbuff_t *tvb, int offset, offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_transition, &transition); /* MRP_TimeStamp */ - offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_time_stamp, &time_stamp); + offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_mrp_time_stamp, &time_stamp); /* Padding */ offset = dissect_pn_align4(tvb, offset, pinfo, tree); col_append_str(pinfo->cinfo, COL_INFO, "Test"); - + if(tree) proto_item_append_text(item, "Test"); return offset; @@ -237,27 +309,50 @@ dissect_PNMRP_TopologyChange(tvbuff_t *tvb, int offset, guint16 prio; guint8 mac[6]; guint16 interval; + proto_item *sub_item; /* MRP_Prio */ - offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_mrp_prio, &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(tvb, offset, pinfo, tree, hf_pn_mrp_interval, &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);*/ col_append_str(pinfo->cinfo, COL_INFO, "TopologyChange"); - + if(tree) proto_item_append_text(item, "TopologyChange"); return offset; } +/* "dissect" Manufacture DATA */ +static int +dissect_pn_ManuData(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, + proto_tree *tree, guint32 length) +{ + + + proto_tree_add_string_format(tree, hf_pn_manufacturer_data, tvb, offset, length, "data", + "MRP_ManufacturerData: %d bytes", length); + + return offset + length; +} + static int dissect_PNMRP_Option(tvbuff_t *tvb, int offset, @@ -274,13 +369,13 @@ dissect_PNMRP_Option(tvbuff_t *tvb, int offset, { case OUI_SIEMENS: proto_item_append_text(item, "Option(SIEMENS)"); - /* Padding */ + /* No Padding ! if (offset % 4) { length -= 4 - (offset % 4); offset = dissect_pn_align4(tvb, offset, pinfo, tree); - } + } */ if(length != 0) { - offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length); + offset = dissect_pn_ManuData(tvb, offset, pinfo, tree, length); } col_append_str(pinfo->cinfo, COL_INFO, "Option(Siemens)"); break; @@ -291,8 +386,6 @@ dissect_PNMRP_Option(tvbuff_t *tvb, int offset, col_append_str(pinfo->cinfo, COL_INFO, "Option"); } - offset += length; - /* Padding */ offset = dissect_pn_align4(tvb, offset, pinfo, tree); @@ -349,11 +442,9 @@ dissect_PNMRP_PDU(tvbuff_t *tvb, int offset, offset = dissect_PNMRP_TopologyChange(new_tvb, offset, pinfo, tree, item); break; case(0x04): + case(0x05): /* dissection of up and down is identical! */ offset = dissect_PNMRP_LinkDown(new_tvb, offset, pinfo, tree, item); break; - case(0x05): - offset = dissect_PNMRP_LinkUp(new_tvb, offset, pinfo, tree, item); - break; case(0x7f): offset = dissect_PNMRP_Option(new_tvb, offset, pinfo, tree, item, length); break; @@ -398,35 +489,35 @@ proto_register_pn_mrp (void) { static hf_register_info hf[] = { { &hf_pn_mrp_type, - { "Type", "pn_mrp.type", FT_UINT8, BASE_HEX, VALS(pn_mrp_block_type_vals), 0x0, NULL, HFILL }}, + { "MRP_TLVHeader.Type", "pn_mrp.type", FT_UINT8, BASE_HEX, VALS(pn_mrp_block_type_vals), 0x0, NULL, HFILL }}, { &hf_pn_mrp_length, - { "Length", "pn_mrp.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { "MRP_TLVHeader.Length", "pn_mrp.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_pn_mrp_version, - { "Version", "pn_mrp.version", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { "MRP_Version", "pn_mrp.version", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_pn_mrp_sequence_id, - { "SequenceID", "pn_mrp.sequence_id", FT_UINT16, BASE_HEX, NULL, 0x0, "Unique sequence number to each outstanding service request", HFILL }}, + { "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, - { "SA", "pn_mrp.sa", FT_ETHER, BASE_NONE, 0x0, 0x0, NULL, HFILL }}, + { "MRP_SA", "pn_mrp.sa", FT_ETHER, BASE_NONE, 0x0, 0x0, NULL, HFILL }}, { &hf_pn_mrp_prio, - { "Prio", "pn_mrp.prio", FT_UINT16, BASE_HEX, VALS(pn_mrp_prio_vals), 0x0, NULL, HFILL }}, + { "MRP_Prio", "pn_mrp.prio", FT_UINT16, BASE_HEX, 0, 0x0, NULL, HFILL }}, { &hf_pn_mrp_port_role, - { "PortRole", "pn_mrp.port_role", FT_UINT16, BASE_HEX, VALS(pn_mrp_port_role_vals), 0x0, NULL, HFILL }}, + { "MRP_PortRole", "pn_mrp.port_role", FT_UINT16, BASE_HEX, VALS(pn_mrp_port_role_vals), 0x0, NULL, HFILL }}, { &hf_pn_mrp_ring_state, - { "RingState", "pn_mrp.ring_state", FT_UINT16, BASE_HEX, VALS(pn_mrp_ring_state_vals), 0x0, NULL, HFILL }}, + { "MRP_RingState", "pn_mrp.ring_state", FT_UINT16, BASE_HEX, VALS(pn_mrp_ring_state_vals), 0x0, NULL, HFILL }}, { &hf_pn_mrp_interval, - { "Interval", "pn_mrp.interval", FT_UINT16, BASE_DEC, NULL, 0x0, "Interval for next topology change event (in ms)", HFILL }}, + { "MRP_Interval", "pn_mrp.interval", FT_UINT16, BASE_DEC, NULL, 0x0, "Interval for next topology change event (in ms)", HFILL }}, { &hf_pn_mrp_transition, - { "Transition", "pn_mrp.transition", FT_UINT16, BASE_HEX, NULL, 0x0, "Number of transitions between media redundancy lost and ok states", HFILL }}, + { "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, - { "TimeStamp", "pn_mrp.time_stamp", FT_UINT16, BASE_HEX, NULL, 0x0, "Actual counter value of 1ms counter", HFILL }}, + { "MRP_TimeStamp [ms]", "pn_mrp.time_stamp", FT_UINT32, BASE_HEX, NULL, 0x0, "Actual counter value of 1ms counter", HFILL }}, { &hf_pn_mrp_blocked, - { "Blocked", "pn_mrp.blocked", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, - { &hf_pn_mrp_manufacturer_oui, - { "ManufacturerOUI", "pn_mrp.manufacturer_oui", FT_UINT24, BASE_HEX, VALS(pn_mrp_oui_vals), 0x0, NULL, HFILL }}, + { "MRP_Blocked", "pn_mrp.blocked", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_pn_manufacturer_data, + { "MRP_ManufacturerData", "pn_mrp.ManufacturerData", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_pn_mrp_domain_uuid, - { "DomainUUID", "pn_mrp.domain_uuid", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { "MRP_DomainUUID", "pn_mrp.domain_uuid", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_pn_mrp_oui, - { "Organizationally Unique Identifier", "pn_mrp.oui", FT_UINT24, BASE_HEX, + { "MRP_ManufacturerOUIr", "pn_mrp.oui", FT_UINT24, BASE_HEX, VALS(pn_mrp_oui_vals), 0x0, NULL, HFILL }}, }; diff --git a/plugins/profinet/packet-pn-ptcp.c b/plugins/profinet/packet-pn-ptcp.c index 706c99187e..164b88762d 100644 --- a/plugins/profinet/packet-pn-ptcp.c +++ b/plugins/profinet/packet-pn-ptcp.c @@ -70,6 +70,10 @@ 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; @@ -120,8 +124,32 @@ static const value_string pn_ptcp_oui_vals[] = { }; static const value_string pn_ptcp_master_prio1_vals[] = { - { 0x01, "Primary sync. master" }, - { 0x02, "Secondary sync. master" }, + { 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 } }; @@ -279,8 +307,15 @@ dissect_PNPTCP_Master(tvbuff_t *tvb, int offset, gint16 ClockVariance; - /* MasterPriority1 */ - offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority1, &MasterPriority1); + /* 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); @@ -298,14 +333,26 @@ dissect_PNPTCP_Master(tvbuff_t *tvb, int offset, offset = dissect_pn_align4(tvb, offset, pinfo, tree); col_append_fstr(pinfo->cinfo, COL_INFO, ", Prio1=\"%s\"", - val_to_str(MasterPriority1, pn_ptcp_master_prio1_short_vals, "(Reserved: 0x%x)")); + 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, pn_ptcp_master_prio1_short_vals, "(Reserved: 0x%x)"), + 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_fstr(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; } @@ -880,7 +927,13 @@ proto_register_pn_ptcp (void) { "CurrentUTCOffset", "pn_ptcp.currentutcoffset", FT_UINT16, BASE_DEC, 0x0, 0x0, NULL, HFILL }}, { &hf_pn_ptcp_master_priority1, - { "MasterPriority1", "pn_ptcp.master_priority1", FT_UINT8, BASE_DEC, VALS(pn_ptcp_master_prio1_vals), 0x0, NULL, HFILL }}, + { "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, diff --git a/plugins/profinet/packet-pn-rt.c b/plugins/profinet/packet-pn-rt.c index 600177075f..53463df918 100644 --- a/plugins/profinet/packet-pn-rt.c +++ b/plugins/profinet/packet-pn-rt.c @@ -35,6 +35,7 @@ #endif #include <epan/packet.h> +#include <epan/reassemble.h> #include <epan/addr_resolv.h> #include <epan/prefs.h> #include <epan/strutil.h> @@ -43,10 +44,13 @@ #include <epan/dissectors/packet-dcerpc.h> #include <epan/crc16-tvb.h> +#include <wsutil/crc16.h> +#include <wsutil/crc16-plain.h> #include "packet-pn.h" /* Define the pn-rt proto */ static int proto_pn_rt = -1; +static gboolean pnio_desegment = TRUE; /* Define many header fields for pn-rt */ static int hf_pn_rt_frame_id = -1; @@ -63,6 +67,8 @@ 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; +static int hf_pn_rt_sf_crc16_ok = -1; +static int hf_pn_rt_sf_crc16_null = -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; @@ -111,8 +117,8 @@ static const value_string pn_rt_ds_redundancy[] = { }; static const value_string pn_rt_frag_status_error[] = { - { 0x00, "No error" }, - { 0x01, "An error occured, all earlier fragments shall be dropped" }, + { 0x00, "reserved" }, + { 0x01, "reserved: invalid should be zero" }, { 0, NULL } }; @@ -122,8 +128,6 @@ static const value_string pn_rt_frag_status_more_follows[] = { { 0, NULL } }; - - static void dissect_DataStatus(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 u8DataStatus) { @@ -150,20 +154,53 @@ dissect_DataStatus(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 u8DataSta } -static gboolean IsDFP_Frame(tvbuff_t *tvb) +static gboolean IsDFP_Frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 u16SFCRC16; guint8 u8SFPosition; guint8 u8SFDataLength = 255; +#if 0 /* XXX: set but not used ? */ + guint8 u8SFCycleCounter = 0; + guint8 u8SFDataStatus; +#endif int offset = 0; guint32 u32SubStart; guint16 crc; gint tvb_len =0; + unsigned char virtualFramebuffer[16]; + guint16 u16FrameID; + + /* the sub tvb will NOT contain the frame_id here! */ + u16FrameID = GPOINTER_TO_UINT(pinfo->private_data); + + /* try to bild a temporaray buffer for generating this CRC */ + 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) + { + proto_item_append_text(tree, ", no packed frame: SFCRC16 is 0x%x should be 0x%x", u16SFCRC16, crc); + return(FALSE); + } + } + /* end of first CRC check */ - offset += 2; /*Skip first crc because data is no more available */ + offset += 2; /*Skip first crc */ tvb_len = tvb_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; @@ -177,8 +214,13 @@ static gboolean IsDFP_Frame(tvbuff_t *tvb) break; } +#if 0 /* XXX: set but not used ? */ + u8SFCycleCounter = tvb_get_guint8(tvb, offset); +#endif offset += 1; - +#if 0 /* XXX: set but not used ? */ + u8SFDataStatus = tvb_get_guint8(tvb, offset); +#endif offset += 1; offset += u8SFDataLength; @@ -224,12 +266,15 @@ dissect_CSF_SDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, u16FrameID = GPOINTER_TO_UINT(pinfo->private_data); /* possible FrameID ranges for DFP */ - if((u16FrameID < 0x100) || (u16FrameID > 0x0fff)) + if((u16FrameID < 0x100) || (u16FrameID > 0x0FFF)) return (FALSE); - if (IsDFP_Frame(tvb)) { + if (IsDFP_Frame(tvb, pinfo, tree)) { /* 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); + if(u16SFCRC16 != 0) + proto_tree_add_uint(tree, hf_pn_rt_sf_crc16_ok, tvb, offset, 2, u16SFCRC16); + else + proto_tree_add_uint(tree, hf_pn_rt_sf_crc16_null, tvb, offset, 2, u16SFCRC16); offset += 2; while(1) { @@ -293,7 +338,38 @@ dissect_CSF_SDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, return FALSE; } +static void +dissect_pn_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + +/* for reasemble processing we need some inits.. */ +/* Register PNIO defrag table init routine. */ + +static GHashTable *pdu_frag_table = NULL; +static GHashTable *reasembled_frag_table = NULL; +static dissector_handle_t data_handle; +static dissector_table_t ethertype_subdissector_table; + +static guint32 start_frag_OR_ID[16]; + + +static void +pnio_defragment_init(void) +{ + guint32 i; + if( reasembled_frag_table != NULL ) { + g_hash_table_destroy( reasembled_frag_table ); + reasembled_frag_table = NULL; + } + + for (i=0; i < 16;i++) /* init the reasemble help array */ + start_frag_OR_ID[i] = 0; + fragment_table_init(&pdu_frag_table); + if (reasembled_frag_table == NULL) + { + reasembled_frag_table = g_hash_table_new(NULL, NULL); + } +} /* possibly dissect a FRAG_PDU related PN-RT packet */ static gboolean @@ -301,6 +377,10 @@ dissect_FRAG_PDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { guint16 u16FrameID; + guint32 u32FrameKey = 0; + guint32 u32FragID = 0; + guint16 pdu_length = 0; + guint32 u32ReasembleID =0xfedc; int offset = 0; proto_item *sub_item; proto_tree *sub_tree; @@ -308,6 +388,10 @@ dissect_FRAG_PDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *status_item; proto_tree *status_tree; guint8 u8FragStatus; + gboolean bMoreFollows; + guint8 uFragNumber; + fragment_data *pdu_frag; + tvbuff_t *pdu_tvb = NULL; /* the sub tvb will NOT contain the frame_id here! */ @@ -330,23 +414,64 @@ dissect_FRAG_PDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, 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; - proto_item_append_text(status_item, ": Number: %u, %s, %s", - u8FragStatus & 0x3F, - val_to_str( (u8FragStatus & 0x80) >> 7, pn_rt_frag_status_more_follows, "Unknown"), - val_to_str( (u8FragStatus & 0x40) >> 6, pn_rt_frag_status_error, "Unknown")); - + uFragNumber = u8FragStatus & 0x3F; /* bits 0 to 5 */ + bMoreFollows = (u8FragStatus & 0x80) != 0; + proto_item_append_text(status_item, ": Number: %u, %s", + uFragNumber, + val_to_str( (u8FragStatus & 0x80) >> 7, pn_rt_frag_status_more_follows, "Unknown")); 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 */ - dissect_pn_undecoded(tvb, offset, pinfo, sub_tree, tvb_length(tvb) - offset); + "Fragment Length: %d bytes", tvb_length(tvb) - offset); + col_append_fstr(pinfo->cinfo, COL_INFO," Fragment Length: %d bytes", tvb_length(tvb) - offset); + dissect_pn_user_data_bytes(tvb, offset, pinfo, sub_tree, tvb_length(tvb) - offset, FRAG_DATA); + if((guint)(tvb_length(tvb) - offset) < (guint)(u8FragDataLength *8)){ + proto_item_append_text(status_item, ": FragDataLength out of Framerange -> discarding!"); + return (TRUE); + } + /* defragmentation starts here */ + if(pnio_desegment) + { + u32FragID = (u16FrameID & 0xf); + if(uFragNumber == 0) + { /* this is the first "new" fragment, so set up a new key Id */ + u32FrameKey = (pinfo->fd->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(tvb, offset, pinfo, u32ReasembleID, pdu_frag_table, uFragNumber, (tvb_length(tvb) - offset)/*u8FragDataLength*8*/, bMoreFollows); + + if(pdu_frag && !bMoreFollows) /* PDU is complete! and last fragment */ + { /* store this frag as the completed frag in hash table */ + g_hash_table_insert(reasembled_frag_table,GUINT_TO_POINTER(pinfo->fd->num),pdu_frag); + start_frag_OR_ID[u32FragID] = 0; /* reset the starting frame counter */ + } + if(!bMoreFollows) /* last fragment */ + { + pdu_frag = g_hash_table_lookup(reasembled_frag_table,GUINT_TO_POINTER(pinfo->fd->num)); + if(pdu_frag) /* found a matching frag dissect it */ + { + guint16 type; + pdu_length = pdu_frag->len; + /* create the new tvb for defraged frame */ + pdu_tvb = tvb_new_child_real_data(tvb, pdu_frag->data, pdu_length, pdu_length); + /* 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_dissector(data_handle, pdu_tvb, pinfo, tree); + } + } return TRUE; } - + else + return TRUE; + } return FALSE; - } @@ -443,7 +568,6 @@ dissect_pn_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) pszProtSummary = "Real-Time"; pszProtComment = "0x0082-0x00FF: Reserved ID"; bCyclic = FALSE; - } else if (u16FrameID <= 0x6FF) { pszProtShort = "PN-RTC3"; pszProtAddInfo = "RTC3, "; @@ -463,28 +587,47 @@ dissect_pn_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) pszProtComment = "0x1000-0x7FFF: Reserved ID"; bCyclic = FALSE; } else if (u16FrameID <= 0xBBFF){ - pszProtShort = "PN-RTC2"; - pszProtAddInfo = "RTC2, "; + pszProtShort = "PN-RTC1"; + pszProtAddInfo = "RTC1, "; pszProtSummary = "cyclic Real-Time"; - pszProtComment = "0x8000-0xBBFF: Real-Time(class=2): non redundant, normal"; + pszProtComment = "0x8000-0xBBFF: Real-Time(class=1 unicast): non redundant, normal"; bCyclic = TRUE; } else if (u16FrameID <= 0xBFFF){ - pszProtShort = "PN-RTC2"; - pszProtAddInfo = "RTC2, "; + pszProtShort = "PN-RTC1"; + pszProtAddInfo = "RTC1, "; pszProtSummary = "cyclic Real-Time"; - pszProtComment = "0xBC00-0xBFFF: Real-Time(class=2 multicast): non redundant, normal"; + pszProtComment = "0xBC00-0xBFFF: Real-Time(class=1 multicast): non redundant, normal"; bCyclic = TRUE; } else if (u16FrameID <= 0xF7FF){ - pszProtShort = "PN-RTC1/UDP"; - pszProtAddInfo = "RTC1/UDP, "; + /* 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"; - pszProtComment = "0xC000-0xF7FF: Real-Time(class=1/UDP): Cyclic"; bCyclic = TRUE; } else if (u16FrameID <= 0xFBFF){ - pszProtShort = "PN-RTC1/UDP"; - pszProtAddInfo = "Multicast, "; + 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"; - pszProtComment = "0xF800-0xFBFF: Real-Time(class=1/UDP multicast): Cyclic"; bCyclic = TRUE; } else if (u16FrameID <= 0xFDFF){ pszProtShort = "PN-RTA"; @@ -573,8 +716,8 @@ dissect_pn_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) bCyclic = FALSE; } else if (u16FrameID <= 0xFF8F){ pszProtShort = "PN-RT"; - pszProtAddInfo = "Fragmentation, "; - pszProtSummary = "Real-Time"; + pszProtAddInfo = ""; + pszProtSummary = "Fragmentation"; pszProtComment = "0xFF80-0xFF8F: Fragmentation"; bCyclic = FALSE; } else { @@ -638,7 +781,7 @@ dissect_pn_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) pdu_len - 4, 2, u16CycleCounter, "CycleCounter: %u", u16CycleCounter); /* add data status subtree */ - dissect_DataStatus(tvb, pdu_len - 2, tree, u8DataStatus); + dissect_DataStatus(tvb, pdu_len - 2, pn_rt_tree, u8DataStatus); /* add transfer status */ if (u8TransferStatus) { @@ -705,6 +848,10 @@ proto_register_pn_rt(void) "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_ok, { + "SFCRC16 checked [ok]", "pn_rt.sf.crc16_ok", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_pn_rt_sf_crc16_null, { + "SFCRC16 not checked but ok", "pn_rt.sf.crc16_null", 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, { @@ -714,7 +861,7 @@ proto_register_pn_rt(void) { &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 Real-Time Fragment", "pn_rt.frag", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + "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, { @@ -722,11 +869,11 @@ proto_register_pn_rt(void) { &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, { - "Error", "pn_rt.frag_status.error", FT_UINT8, BASE_HEX, VALS(pn_rt_frag_status_error), 0x40, NULL, HFILL }}, + "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 }}, { &hf_pn_rt_frag_data, { - "FragData", "pn_rt.frag_data", FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }}, + "FragData", "pn_rt.frag_data", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL }}, }; static gint *ett[] = { &ett_pn_rt, @@ -752,10 +899,16 @@ proto_register_pn_rt(void) "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 */ register_heur_dissector_list("pn_rt", &heur_subdissector_list); init_pn (proto_pn_rt); + register_init_routine(pnio_defragment_init); } @@ -772,5 +925,8 @@ proto_reg_handoff_pn_rt(void) heur_dissector_add("pn_rt", dissect_CSF_SDU_heur, proto_pn_rt); heur_dissector_add("pn_rt", dissect_FRAG_PDU_heur, proto_pn_rt); + data_handle = find_dissector("data"); + + ethertype_subdissector_table = find_dissector_table("ethertype"); } diff --git a/plugins/profinet/packet-pn.c b/plugins/profinet/packet-pn.c index cd5f590f71..47be00850b 100644 --- a/plugins/profinet/packet-pn.c +++ b/plugins/profinet/packet-pn.c @@ -40,6 +40,7 @@ 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; @@ -212,8 +213,11 @@ dissect_pn_undecoded(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, /* "dissect" some user bytes */ int dissect_pn_user_data_bytes(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, - proto_tree *tree, guint32 length, const char *text _U_) + proto_tree *tree, guint32 length, int iSelect) { + if(iSelect == FRAG_DATA) + proto_tree_add_bytes(tree, hf_pn_frag_bytes, tvb, offset, length, tvb_get_ptr(tvb,offset, length)); + else proto_tree_add_bytes(tree, hf_pn_user_bytes, tvb, offset, length, tvb_get_ptr(tvb,offset, length)); return offset + length; @@ -291,6 +295,8 @@ init_pn (int proto) { "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 }} }; diff --git a/plugins/profinet/packet-pn.h b/plugins/profinet/packet-pn.h index 86b02d1872..3fef27e835 100644 --- a/plugins/profinet/packet-pn.h +++ b/plugins/profinet/packet-pn.h @@ -63,8 +63,12 @@ extern int dissect_pn_undecoded(tvbuff_t *tvb, int offset, packet_info *pinfo, extern int dissect_pn_user_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint32 length, const char *text); +#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, const char *text); + 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); |