aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/profinet
diff options
context:
space:
mode:
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>2007-08-03 19:29:34 +0000
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>2007-08-03 19:29:34 +0000
commit7891219b64642c0adc036370d19e6abdc4e1178c (patch)
tree4fb692fc40fc6c235177830931fbc23f90092390 /plugins/profinet
parente5997f66439dccdf375160c3a4ad1b37c015d569 (diff)
- add PDInterfaceFSUDataAdjust block
- start to implement an AR conversation handler git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@22444 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'plugins/profinet')
-rw-r--r--plugins/profinet/packet-dcerpc-pn-io.c383
1 files changed, 339 insertions, 44 deletions
diff --git a/plugins/profinet/packet-dcerpc-pn-io.c b/plugins/profinet/packet-dcerpc-pn-io.c
index cf59e3dc48..6c43ad819f 100644
--- a/plugins/profinet/packet-dcerpc-pn-io.c
+++ b/plugins/profinet/packet-dcerpc-pn-io.c
@@ -446,6 +446,7 @@ 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_io_ar_info = -1;
static e_uuid_t uuid_pn_io_device = { 0xDEA00001, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
static guint16 ver_pn_io_device = 1;
@@ -562,6 +563,7 @@ static const value_string pn_io_block_type[] = {
{ 0x0400, "MultipleBlockHeader"},
{ 0x0500, "RecordDataReadQuery"},
{ 0x0600, "FSHello"},
+ { 0x0608, "PDInterfaceFSUDataAdjust"},
{ 0x0F00, "MaintenanceItem"},
{ 0, NULL }
};
@@ -1083,8 +1085,10 @@ static const value_string pn_io_index[] = {
/*0x8063 - 0x806F reserved */
{ 0x8070, "PDNCDataCheck for one subslot" },
/*0x8071 - 0x807F reserved */
- { 0x8080, "PDInterfaceDataReal" },
- /*0x8081 - 0xAFEF reserved */
+ { 0x8080, "PDInterfaceDataReal" },
+ /*0x8081 - 0x808F reserved */
+ { 0x8090, "Expected PDInterfaceFSUDataAdjust" },
+ /*0x8091 - 0xAFEF reserved */
{ 0xAFF0, "I&M0" },
{ 0xAFF1, "I&M1" },
{ 0xAFF2, "I&M2" },
@@ -1433,8 +1437,71 @@ static const value_string pn_io_fs_hello_mode_vals[] = {
};
+GList *pnio_ars;
+
+typedef struct pnio_ar_s {
+ /* generic */
+ e_uuid_t aruuid;
+ guint16 inputframeid;
+ guint16 outputframeid;
+
+ /* controller only */
+ /*const char controllername[33];*/
+ const guint8 controllermac[6];
+ guint16 controlleralarmref;
+
+ /* device only */
+ const guint8 devicemac[6];
+ guint16 devicealarmref;
+} pnio_ar_t;
+
+
+
+static void
+pnio_ar_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pnio_ar_t *ar)
+{
+ proto_item *item;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+
+ pinfo->profinet_conv = ar;
+ pinfo->profinet_type = 10;
+
+ if (tree) {
+ sub_item = proto_tree_add_text(tree, tvb, 0, 0, "ARUUID:%s ContrMAC:%s ContrAlRef:0x%x DevMAC:%s DevAlRef:0x%x InCR:0x%x OutCR=0x%x",
+ guid_to_str((const e_guid_t*) &ar->aruuid),
+ ether_to_str((const guint8 *)ar->controllermac), ar->controlleralarmref,
+ ether_to_str((const guint8 *)ar->devicemac), ar->devicealarmref,
+ ar->inputframeid, ar->outputframeid);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_ar_info);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ item = proto_tree_add_guid(sub_tree, hf_pn_io_ar_uuid, tvb, 0, 0, (e_guid_t *) &ar->aruuid);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ item = proto_tree_add_ether(sub_tree, hf_pn_io_cminitiator_macadd, tvb, 0, 0, ar->controllermac);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_pn_io_localalarmref, tvb, 0, 0, ar->controlleralarmref);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ item = proto_tree_add_ether(sub_tree, hf_pn_io_cmresponder_macadd, tvb, 0, 0, ar->devicemac);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_pn_io_localalarmref, tvb, 0, 0, ar->devicealarmref);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ item = proto_tree_add_uint(sub_tree, hf_pn_io_frame_id, tvb, 0, 0, ar->inputframeid);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_pn_io_frame_id, tvb, 0, 0, ar->outputframeid);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+}
+
+
+
+
static int dissect_block(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen);
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar);
static int dissect_blocks(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep);
@@ -1446,6 +1513,46 @@ static int dissect_PNIO_IOxS(tvbuff_t *tvb, int offset,
+static pnio_ar_t *
+pnio_ar_find_by_aruuid(packet_info *pinfo, e_uuid_t *aruuid)
+{
+ GList *ars;
+ pnio_ar_t *ar;
+
+
+ /* find pdev */
+ for(ars = pnio_ars; ars != NULL; ars = g_list_next(ars)) {
+ ar = ars->data;
+
+ if( memcmp(&ar->aruuid, aruuid, sizeof(e_uuid_t)) == 0) {
+ return ar;
+ }
+ }
+
+ return NULL;
+}
+
+
+static pnio_ar_t *
+pnio_ar_new(e_uuid_t *aruuid)
+{
+ pnio_ar_t *ar;
+
+
+ ar = se_alloc0(sizeof(pnio_ar_t));
+
+ memcpy(&ar->aruuid, aruuid, sizeof(e_uuid_t));
+
+ ar->controlleralarmref = 0xffff;
+ ar->devicealarmref = 0xffff;
+
+ pnio_ars = g_list_append(pnio_ars, ar);
+
+ return ar;
+}
+
+
+
/* dissect the four status (error) fields */
static int
dissect_PNIO_status(tvbuff_t *tvb, int offset,
@@ -1674,6 +1781,7 @@ dissect_AlarmUserStructure(tvbuff_t *tvb, int offset,
guint32 u32ExtChannelAddValue;
guint16 u16Index;
guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
switch(u16UserStructureIdentifier) {
@@ -1700,7 +1808,7 @@ dissect_AlarmUserStructure(tvbuff_t *tvb, int offset,
*body_length -= 12;
break;
case(0x8100): /* MaintenanceItem */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
*body_length -= 12;
break;
/* XXX - dissect remaining user structures of [AlarmItem] */
@@ -2136,6 +2244,7 @@ dissect_RecordOutputDataObjectElement_block(tvbuff_t *tvb, int offset,
guint16 u16LengthData;
guint16 u16Index;
guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
/* SubstituteActiveFlag */
@@ -2159,7 +2268,7 @@ dissect_RecordOutputDataObjectElement_block(tvbuff_t *tvb, int offset,
offset = dissect_PNIO_IOxS(tvb, offset, pinfo, tree, drep, hf_pn_io_iops);
/* SubstituteValue */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
return offset;
}
@@ -2259,13 +2368,18 @@ dissect_ReadWrite_header(tvbuff_t *tvb, int offset,
/* dissect the write request block */
static int
dissect_IODWriteReqHeader_block(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t ** ar)
{
e_uuid_t aruuid;
e_uuid_t null_uuid;
offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, item, drep, u16Index, &aruuid);
+ *ar = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+ if(*ar == NULL) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IODWriteReq: AR not existing!");
+ }
+
offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
hf_pn_io_record_data_length, u32RecDataLen);
@@ -2290,13 +2404,18 @@ dissect_IODWriteReqHeader_block(tvbuff_t *tvb, int offset,
/* dissect the read request block */
static int
dissect_IODReadReqHeader_block(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
{
e_uuid_t aruuid;
e_uuid_t null_uuid;
offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, item, drep, u16Index, &aruuid);
+ *ar = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+ if(*ar == NULL) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IODReadReq: AR not existing!");
+ }
+
offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
hf_pn_io_record_data_length, u32RecDataLen);
@@ -2322,7 +2441,7 @@ dissect_IODReadReqHeader_block(tvbuff_t *tvb, int offset,
/* dissect the write response block */
static int
dissect_IODWriteResHeader_block(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
{
e_uuid_t aruuid;
guint16 u16AddVal1;
@@ -2331,6 +2450,11 @@ dissect_IODWriteResHeader_block(tvbuff_t *tvb, int offset,
offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, item, drep, u16Index, &aruuid);
+ *ar = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+ if(*ar == NULL) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IODWriteRes: AR not existing!");
+ }
+
offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
hf_pn_io_record_data_length, u32RecDataLen);
@@ -2356,7 +2480,7 @@ dissect_IODWriteResHeader_block(tvbuff_t *tvb, int offset,
/* dissect the read response block */
static int
dissect_IODReadResHeader_block(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
{
e_uuid_t aruuid;
guint16 u16AddVal1;
@@ -2365,6 +2489,11 @@ dissect_IODReadResHeader_block(tvbuff_t *tvb, int offset,
offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, item, drep, u16Index, &aruuid);
+ *ar = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+ if(*ar == NULL) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IODReadRes: AR not existing!");
+ }
+
offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
hf_pn_io_record_data_length, u32RecDataLen);
@@ -2390,7 +2519,7 @@ dissect_IODReadResHeader_block(tvbuff_t *tvb, int offset,
/* dissect the control/connect block */
static int
dissect_ControlConnect_block(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, pnio_ar_t **ar)
{
e_uuid_t ar_uuid;
guint16 u16SessionKey;
@@ -2406,6 +2535,11 @@ dissect_ControlConnect_block(tvbuff_t *tvb, int offset,
offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
hf_pn_io_ar_uuid, &ar_uuid);
+ *ar = pnio_ar_find_by_aruuid(pinfo, &ar_uuid);
+ if(*ar == NULL) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "ControlConnect: AR not existing!");
+ }
+
offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
hf_pn_io_sessionkey, &u16SessionKey);
@@ -3158,6 +3292,7 @@ dissect_PDPortFODataReal_block(tvbuff_t *tvb, int offset,
guint32 u32FiberOpticCableType;
guint16 u16Index;
guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
/* Padding */
@@ -3173,7 +3308,7 @@ dissect_PDPortFODataReal_block(tvbuff_t *tvb, int offset,
/* optional: FiberOpticManufacturerSpecific */
if(u16BodyLength != 10) {
- dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
}
return offset;
@@ -3420,6 +3555,7 @@ dissect_PDIRData_block(tvbuff_t *tvb, int offset,
guint16 u16SubslotNr;
guint16 u16Index;
guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
offset = dissect_pn_align4(tvb, offset, pinfo, tree);
@@ -3435,9 +3571,9 @@ dissect_PDIRData_block(tvbuff_t *tvb, int offset,
u16SlotNr, u16SubslotNr);
/* PDIRGlobalData */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
/* PDIRFrameData */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
return offset;
}
@@ -3881,12 +4017,44 @@ dissect_FSHello_block(tvbuff_t *tvb, int offset,
}
+
+
+/* dissect the FSUDataAdjust block */
+static int
+dissect_PDInterfaceFSUDataAdjust_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, guint16 u16BodyLength)
+{
+ tvbuff_t *tvb_new;
+
+
+ /* Padding */
+ offset = dissect_pn_align4(tvb, offset, pinfo, tree);
+
+ u16BodyLength -= 2;
+
+ /* sub blocks */
+ tvb_new = tvb_new_subset(tvb, offset, u16BodyLength, u16BodyLength);
+ dissect_blocks(tvb_new, 0, pinfo, tree, drep);
+ offset += u16BodyLength;
+
+#if 0
+ proto_item_append_text(item, ": Mode:%s, Interval:%ums, Retry:%u, Delay:%ums",
+ val_to_str(u32FSHelloMode, pn_io_fs_hello_mode_vals, "0x%x"),
+ u32FSHelloInterval, u32FSHelloRetry, u32FSHelloDelay);
+#endif
+
+ return offset;
+}
+
+
+
/* dissect the ARBlockReq */
static int
dissect_ARBlockReq(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, pnio_ar_t ** ar)
{
guint16 u16ARType;
+ e_uuid_t aruuid;
e_uuid_t uuid;
guint16 u16SessionKey;
guint8 mac[6];
@@ -3894,12 +4062,13 @@ dissect_ARBlockReq(tvbuff_t *tvb, int offset,
guint16 u16UDPRTPort;
guint16 u16NameLength;
char *pStationName;
+ pnio_ar_t * par;
offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
hf_pn_io_ar_type, &u16ARType);
offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
- hf_pn_io_ar_uuid, &uuid);
+ hf_pn_io_ar_uuid, &aruuid);
offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
hf_pn_io_sessionkey, &u16SessionKey);
offset = dissect_pn_mac(tvb, offset, pinfo, tree,
@@ -3930,6 +4099,16 @@ dissect_ARBlockReq(tvbuff_t *tvb, int offset,
u16UDPRTPort,
pStationName);
+ par = pnio_ar_find_by_aruuid(pinfo, &aruuid);
+ if(par == NULL) {
+ par = pnio_ar_new(&aruuid);
+ memcpy( (void *) (&par->controllermac), mac, sizeof(par->controllermac));
+ /*strncpy( (char *) (&par->controllername), pStationName, sizeof(par->controllername));*/
+ } else {
+ //expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "ARBlockReq: AR already existing!");
+ }
+ *ar = par;
+
return offset;
}
@@ -3937,13 +4116,14 @@ dissect_ARBlockReq(tvbuff_t *tvb, int offset,
/* dissect the ARBlockRes */
static int
dissect_ARBlockRes(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, pnio_ar_t ** ar)
{
guint16 u16ARType;
e_uuid_t uuid;
guint16 u16SessionKey;
guint8 mac[6];
guint16 u16UDPRTPort;
+ pnio_ar_t * par;
offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
@@ -3963,6 +4143,14 @@ dissect_ARBlockRes(tvbuff_t *tvb, int offset,
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
u16UDPRTPort);
+ par = pnio_ar_find_by_aruuid(pinfo, &uuid);
+ if(par == NULL) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "ARBlockRes: AR not existing!");
+ } else {
+ memcpy( (void *) (&par->devicemac), mac, sizeof(par->controllermac));
+ }
+ *ar = par;
+
return offset;
}
@@ -3970,7 +4158,7 @@ dissect_ARBlockRes(tvbuff_t *tvb, int offset,
/* dissect the IOCRBlockReq */
static int
dissect_IOCRBlockReq(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, pnio_ar_t *ar)
{
guint16 u16IOCRType;
guint16 u16IOCRReference;
@@ -4108,6 +4296,32 @@ dissect_IOCRBlockReq(tvbuff_t *tvb, int offset,
proto_item_set_len(api_item, offset - u32ApiStart);
}
+ if(ar != NULL) {
+ switch(u16IOCRType) {
+ case(1): /* Input CR */
+ if(ar->inputframeid != 0 && ar->inputframeid != u16FrameID) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IOCRBlockReq: input frameID changed from %u to %u!",
+ ar->inputframeid, u16FrameID);
+ }
+ ar->inputframeid = u16FrameID;
+ break;
+ case(2): /* Output CR */
+#if 0
+ /* will usually contain invalid marker 0xffff here */
+ if(ar->outputframeid != 0 && ar->outputframeid != u16FrameID) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IOCRBlockReq: output frameID changed from %u to %u!",
+ ar->outputframeid, u16FrameID);
+ }
+ ar->outputframeid = u16FrameID;
+#endif
+ break;
+ default:
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IOCRBlockReq: IOCRType %u undecoded!", u16IOCRType);
+ }
+ } else {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IOCRBlockReq: no corresponding AR found!");
+ }
+
return offset;
}
@@ -4115,7 +4329,7 @@ dissect_IOCRBlockReq(tvbuff_t *tvb, int offset,
/* dissect the AlarmCRBlockReq */
static int
dissect_AlarmCRBlockReq(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, pnio_ar_t *ar)
{
guint16 u16AlarmCRType;
guint16 u16LT;
@@ -4162,6 +4376,16 @@ dissect_AlarmCRBlockReq(tvbuff_t *tvb, int offset,
u16LT, u16RTATimeoutFactor, u16RTARetries, u16LocalAlarmReference, u16MaxAlarmDataLength,
u16AlarmCRTagHeaderHigh, u16AlarmCRTagHeaderLow);
+ if(ar != NULL) {
+ if(ar->controlleralarmref != 0xffff && ar->controlleralarmref != u16LocalAlarmReference) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "AlarmCRBlockReq: local alarm ref changed from %u to %u!",
+ ar->controlleralarmref, u16LocalAlarmReference);
+ }
+ ar->controlleralarmref = u16LocalAlarmReference;
+ } else {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "AlarmCRBlockReq: no corresponding AR found!");
+ }
+
return offset;
}
@@ -4169,7 +4393,7 @@ dissect_AlarmCRBlockReq(tvbuff_t *tvb, int offset,
/* dissect the AlarmCRBlockRes */
static int
dissect_AlarmCRBlockRes(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, pnio_ar_t *ar)
{
guint16 u16AlarmCRType;
guint16 u16LocalAlarmReference;
@@ -4187,6 +4411,17 @@ dissect_AlarmCRBlockRes(tvbuff_t *tvb, int offset,
val_to_str(u16AlarmCRType, pn_io_alarmcr_type, "0x%x"),
u16LocalAlarmReference, u16MaxAlarmDataLength);
+ if(ar != NULL) {
+ if(ar->devicealarmref != 0xffff && ar->devicealarmref != u16LocalAlarmReference) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "AlarmCRBlockRes: local alarm ref changed from %u to %u!",
+ ar->devicealarmref, u16LocalAlarmReference);
+ }
+ ar->devicealarmref = u16LocalAlarmReference;
+ } else {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "AlarmCRBlockRes: no corresponding AR found!");
+ }
+
+
return offset;
}
@@ -4195,7 +4430,7 @@ dissect_AlarmCRBlockRes(tvbuff_t *tvb, int offset,
/* dissect the IOCRBlockRes */
static int
dissect_IOCRBlockRes(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep)
+ packet_info *pinfo, proto_tree *tree, proto_item *item, guint8 *drep, pnio_ar_t *ar)
{
guint16 u16IOCRType;
guint16 u16IOCRReference;
@@ -4213,6 +4448,29 @@ dissect_IOCRBlockRes(tvbuff_t *tvb, int offset,
val_to_str(u16IOCRType, pn_io_iocr_type, "0x%x"),
u16IOCRReference, u16FrameID);
+ if(ar != NULL) {
+ switch(u16IOCRType) {
+ case(1): /* Input CR */
+ if(ar->inputframeid != 0 && ar->inputframeid != u16FrameID) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IOCRBlockRes: input frameID changed from %u to %u!",
+ ar->inputframeid, u16FrameID);
+ }
+ ar->inputframeid = u16FrameID;
+ break;
+ case(2): /* Output CR */
+ if(ar->outputframeid != 0 && ar->outputframeid != u16FrameID) {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IOCRBlockRes: output frameID changed from %u to %u!",
+ ar->outputframeid, u16FrameID);
+ }
+ ar->outputframeid = u16FrameID;
+ break;
+ default:
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IOCRBlockRes: IOCRType %u undecoded!", u16IOCRType);
+ }
+ } else {
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "IOCRBlockRes: no corresponding AR found!");
+ }
+
return offset;
}
@@ -4665,7 +4923,7 @@ dissect_RecordDataReadQuery_block(tvbuff_t *tvb, int offset,
/* dissect one PN-IO block (depending on the block type) */
static int
dissect_block(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen)
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen, pnio_ar_t **ar)
{
guint16 u16BlockType;
guint16 u16BlockLength;
@@ -4720,10 +4978,10 @@ dissect_block(tvbuff_t *tvb, int offset,
dissect_AlarmNotification_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16BodyLength);
break;
case(0x0008):
- dissect_IODWriteReqHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16Index, u32RecDataLen);
+ dissect_IODWriteReqHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16Index, u32RecDataLen, ar);
break;
case(0x0009):
- dissect_IODReadReqHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16Index, u32RecDataLen);
+ dissect_IODReadReqHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16Index, u32RecDataLen, ar);
break;
case(0x0010):
dissect_DiagnosisData_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16BodyLength, u8BlockVersionLow);
@@ -4776,13 +5034,13 @@ dissect_block(tvbuff_t *tvb, int offset,
dissect_IandM0FilterData_block(tvb, offset, pinfo, sub_tree, sub_item, drep);
break;
case(0x0101):
- dissect_ARBlockReq(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ dissect_ARBlockReq(tvb, offset, pinfo, sub_tree, sub_item, drep, ar);
break;
case(0x0102):
- dissect_IOCRBlockReq(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ dissect_IOCRBlockReq(tvb, offset, pinfo, sub_tree, sub_item, drep, *ar);
break;
case(0x0103):
- dissect_AlarmCRBlockReq(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ dissect_AlarmCRBlockReq(tvb, offset, pinfo, sub_tree, sub_item, drep, *ar);
break;
case(0x0104):
dissect_ExpectedSubmoduleBlockReq(tvb, offset, pinfo, sub_tree, sub_item, drep);
@@ -4795,7 +5053,7 @@ dissect_block(tvbuff_t *tvb, int offset,
case(0x0112):
case(0x0113):
case(0x0114):
- dissect_ControlConnect_block(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ dissect_ControlConnect_block(tvb, offset, pinfo, sub_tree, sub_item, drep, ar);
break;
case(0x0200):
dissect_PDPortData_Check_Adjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16BodyLength);
@@ -4912,6 +5170,9 @@ dissect_block(tvbuff_t *tvb, int offset,
case(0x0600):
dissect_FSHello_block(tvb, offset, pinfo, sub_tree, sub_item, drep);
break;
+ case(0x0608):
+ dissect_PDInterfaceFSUDataAdjust_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16BodyLength);
+ break;
case(0x0f00):
dissect_Maintenance_block(tvb, offset, pinfo, sub_tree, sub_item, drep);
break;
@@ -4920,19 +5181,19 @@ dissect_block(tvbuff_t *tvb, int offset,
dissect_Alarm_ack_block(tvb, offset, pinfo, sub_tree, sub_item, drep);
break;
case(0x8008):
- dissect_IODWriteResHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16Index, u32RecDataLen);
+ dissect_IODWriteResHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16Index, u32RecDataLen, ar);
break;
case(0x8009):
- dissect_IODReadResHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16Index, u32RecDataLen);
+ dissect_IODReadResHeader_block(tvb, offset, pinfo, sub_tree, sub_item, drep, u16Index, u32RecDataLen, ar);
break;
case(0x8101):
- dissect_ARBlockRes(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ dissect_ARBlockRes(tvb, offset, pinfo, sub_tree, sub_item, drep, ar);
break;
case(0x8102):
- dissect_IOCRBlockRes(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ dissect_IOCRBlockRes(tvb, offset, pinfo, sub_tree, sub_item, drep, *ar);
break;
case(0x8103):
- dissect_AlarmCRBlockRes(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ dissect_AlarmCRBlockRes(tvb, offset, pinfo, sub_tree, sub_item, drep, *ar);
break;
case(0x8104):
dissect_ModuleDiffBlock(tvb, offset, pinfo, sub_tree, sub_item, drep);
@@ -4942,7 +5203,7 @@ dissect_block(tvbuff_t *tvb, int offset,
case(0x8112):
case(0x8113):
case(0x8114):
- dissect_ControlConnect_block(tvb, offset, pinfo, sub_tree, sub_item, drep);
+ dissect_ControlConnect_block(tvb, offset, pinfo, sub_tree, sub_item, drep, ar);
break;
default:
dissect_pn_undecoded(tvb, offset, pinfo, sub_tree, u16BodyLength);
@@ -4962,13 +5223,18 @@ dissect_blocks(tvbuff_t *tvb, int offset,
{
guint16 u16Index = 0;
guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
while(tvb_length(tvb) > (guint) offset) {
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
u16Index++;
}
+ if(ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
return offset;
}
@@ -5096,6 +5362,7 @@ dissect_RecordDataRead(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16Index, guint32 u32RecDataLen)
{
const gchar *userProfile;
+ pnio_ar_t *ar = NULL;
/* user specified format? */
@@ -5131,6 +5398,7 @@ dissect_RecordDataRead(tvbuff_t *tvb, int offset,
case(0x8062): /* PDPortFODataAdjust for one subslot */
case(0x8070): /* PDNCDataCheck for one subslot */
case(0x8080): /* PDInterfaceDataReal */
+ case(0x8090): /* PDInterfaceFSUDataAdjust */
case(0xaff0): /* I&M0 */
case(0xaff1): /* I&M1 */
@@ -5171,7 +5439,7 @@ dissect_RecordDataRead(tvbuff_t *tvb, int offset,
case(0xf830): /* LogData */
case(0xf831): /* PDevData */
case(0xf840): /* I&M0FilterData */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
break;
/*** multiple blocks possible ***/
@@ -5257,17 +5525,22 @@ dissect_IPNIO_Read_resp(tvbuff_t *tvb, int offset,
{
guint16 u16Index = 0;
guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
/* IODReadHeader */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
/* RecordDataRead */
if(u32RecDataLen != 0) {
offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
}
+ if(ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
return offset;
}
@@ -5277,6 +5550,7 @@ dissect_RecordDataWrite(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16Index, guint32 u32RecDataLen)
{
const gchar *userProfile;
+ pnio_ar_t *ar = NULL;
/* user specified format? */
@@ -5306,10 +5580,11 @@ 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(0x8090): /* PDInterfaceFSUDataAdjust */
case(0xe030): /* IsochronousModeData for one AR */
case(0xe050): /* FastStartUp data for one AR */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
break;
default:
offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, u32RecDataLen);
@@ -5321,7 +5596,7 @@ dissect_RecordDataWrite(tvbuff_t *tvb, int offset,
static int
dissect_IODWriteReq(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree, guint8 *drep)
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, pnio_ar_t **ar)
{
gint remain;
guint16 u16Index = 0;
@@ -5329,12 +5604,12 @@ dissect_IODWriteReq(tvbuff_t *tvb, int offset,
/* IODWriteHeader */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, ar);
/* IODWriteMultipleReq? */
if(u16Index == 0xe040) {
while((remain = tvb_length_remaining(tvb, offset)) > 0) {
- offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep);
+ offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, ar);
}
} else {
/* RecordDataWrite */
@@ -5362,9 +5637,15 @@ static int
dissect_IPNIO_Write_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
+ pnio_ar_t *ar = NULL;
+
offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
- offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep);
+ offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar);
+
+ if(ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
return offset;
}
@@ -5378,10 +5659,11 @@ dissect_IODWriteRes(tvbuff_t *tvb, int offset,
gint remain;
guint16 u16Index = 0;
guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
/* IODWriteResHeader */
- offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, &ar);
/* IODWriteMultipleRes? */
if(u16Index == 0xe040) {
@@ -5390,6 +5672,10 @@ dissect_IODWriteRes(tvbuff_t *tvb, int offset,
}
}
+ if(ar != NULL) {
+ pnio_ar_info(tvb, pinfo, tree, ar);
+ }
+
return offset;
}
@@ -5484,6 +5770,7 @@ dissect_PNIO_RTA(tvbuff_t *tvb, int offset,
int start_offset = offset;
guint16 u16Index = 0;
guint32 u32RecDataLen;
+ pnio_ar_t *ar = NULL;
proto_item *rta_item;
@@ -5545,7 +5832,7 @@ dissect_PNIO_RTA(tvbuff_t *tvb, int offset,
case(1): /* Data-RTA */
if (check_col(pinfo->cinfo, COL_INFO))
col_append_str(pinfo->cinfo, COL_INFO, ", Data-RTA");
- offset = dissect_block(tvb, offset, pinfo, rta_tree, drep, &u16Index, &u32RecDataLen);
+ offset = dissect_block(tvb, offset, pinfo, rta_tree, drep, &u16Index, &u32RecDataLen, &ar);
break;
case(2): /* NACK-RTA */
if (check_col(pinfo->cinfo, COL_INFO))
@@ -5646,6 +5933,11 @@ static dcerpc_sub_dissector pn_io_dissectors[] = {
};
+static void pnio_reinit( void) {
+ pnio_ars = NULL;
+}
+
+
void
proto_register_pn_io (void)
{
@@ -6335,12 +6627,15 @@ proto_register_pn_io (void)
&ett_pn_io_mrp_rtmode,
&ett_pn_io_control_block_properties,
&ett_pn_io_check_sync_mode,
- &ett_pn_io_ir_frame_data
+ &ett_pn_io_ir_frame_data,
+ &ett_pn_io_ar_info
};
proto_pn_io = proto_register_protocol ("PROFINET IO", "PNIO", "pn_io");
proto_register_field_array (proto_pn_io, hf, array_length (hf));
proto_register_subtree_array (ett, array_length (ett));
+
+ register_init_routine(pnio_reinit);
}
void