forked from osmocom/wireshark
PROFINET: Rsi dissection errors are fixed.
According to specification, size of PROFINETIOServiceResPDU is calculated and checked under dissect_RSI_RSP_block function. Moreover, dissect_rsi_blocks function is added and type of PDU and operation number (Opnum) are checked before dissection starts.
This commit is contained in:
parent
dbdfe53538
commit
e04ea5c108
|
@ -11311,6 +11311,68 @@ dissect_IPNIO_Write_resp(tvbuff_t *tvb, int offset,
|
|||
}
|
||||
|
||||
|
||||
/* dissect any number of PN-RSI blocks */
|
||||
int
|
||||
dissect_rsi_blocks(tvbuff_t* tvb, int offset,
|
||||
packet_info* pinfo, proto_tree* tree, guint8* drep, guint32 u32FOpnumOffsetOpnum, int type)
|
||||
{
|
||||
pnio_ar_t* ar = NULL;
|
||||
guint recursion_count = 0;
|
||||
guint16 u16Index = 0;
|
||||
guint32 u32RecDataLen = 0;
|
||||
|
||||
|
||||
switch (u32FOpnumOffsetOpnum) {
|
||||
case(0x0): // Connect request or response
|
||||
offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
|
||||
break;
|
||||
case(0x2): // Read request or response
|
||||
offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
|
||||
break;
|
||||
case(0x3): // Write request or response
|
||||
if (type == PDU_TYPE_REQ)
|
||||
offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar, recursion_count);
|
||||
else if (type == PDU_TYPE_RSP)
|
||||
offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
|
||||
break;
|
||||
case(0x4): // Control request or response
|
||||
offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
|
||||
break;
|
||||
case(0x5): // ReadImplicit request or response
|
||||
offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
|
||||
break;
|
||||
case(0x6): // ReadConnectionless request or response
|
||||
offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
|
||||
break;
|
||||
case(0x7): // ReadNotification request or response
|
||||
offset = dissect_RecordDataRead(tvb, offset, pinfo, tree, drep, u16Index, u32RecDataLen);
|
||||
break;
|
||||
case(0x8): // PrmWriteMore request or response
|
||||
if (type == PDU_TYPE_REQ)
|
||||
offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar, recursion_count);
|
||||
else if (type == PDU_TYPE_RSP)
|
||||
offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
|
||||
break;
|
||||
case(0x9): // PrmWriteEnd request or response
|
||||
if (type == PDU_TYPE_REQ)
|
||||
offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar, recursion_count);
|
||||
else if (type == PDU_TYPE_RSP)
|
||||
offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
|
||||
break;
|
||||
default:
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
|
||||
offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
|
||||
break;
|
||||
}
|
||||
|
||||
if (ar != NULL) {
|
||||
pnio_ar_info(tvb, pinfo, tree, ar);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/* dissect the IOxS (IOCS, IOPS) field */
|
||||
static int
|
||||
dissect_PNIO_IOxS(tvbuff_t *tvb, int offset,
|
||||
|
|
|
@ -295,7 +295,7 @@ static const fragment_items pn_rsi_frag_items = {
|
|||
|
||||
static int
|
||||
dissect_pn_rta_remaining_user_data_bytes(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
|
||||
proto_tree *tree, guint8 *drep, guint32 length, guint8 u8MoreFrag)
|
||||
proto_tree *tree, guint8 *drep, guint32 length, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOpnum, int type)
|
||||
{
|
||||
fragment_head *fd_frag;
|
||||
fragment_head *fd_reass;
|
||||
|
@ -366,7 +366,7 @@ dissect_pn_rta_remaining_user_data_bytes(tvbuff_t *tvb, int offset, packet_info
|
|||
payload_item = proto_tree_add_item(tree, hf_pn_rsi_data_payload, next_tvb, 0, tvb_captured_length(next_tvb), ENC_NA);
|
||||
payload_tree = proto_item_add_subtree(payload_item, ett_pn_rsi_data_payload);
|
||||
|
||||
offset = dissect_blocks(next_tvb, 0, pinfo, payload_tree, drep);
|
||||
offset = dissect_rsi_blocks(next_tvb, 0, pinfo, payload_tree, drep, u32FOpnumOffsetOpnum, type);
|
||||
|
||||
/* the toplevel fragment subtree is now behind all desegmented data,
|
||||
* move it right behind the DE2 tree item */
|
||||
|
@ -390,7 +390,7 @@ dissect_pn_rta_remaining_user_data_bytes(tvbuff_t *tvb, int offset, packet_info
|
|||
/* dissect a PN-IO RSI SVCS block (on top of PN-RT protocol) */
|
||||
static int
|
||||
dissect_RSI_SVCS_block(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset)
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
|
||||
{
|
||||
proto_item *sub_item;
|
||||
proto_tree *sub_tree;
|
||||
|
@ -410,14 +410,14 @@ dissect_RSI_SVCS_block(tvbuff_t *tvb, int offset,
|
|||
}
|
||||
|
||||
offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, sub_tree, drep,
|
||||
tvb_captured_length_remaining(tvb, offset), u8MoreFrag);
|
||||
tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_REQ);
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* dissect a PN-IO RSI CONN block (on top of PN-RT protocol) */
|
||||
static int
|
||||
dissect_RSI_CONN_block(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset)
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
|
||||
{
|
||||
proto_item *sub_item;
|
||||
proto_tree *sub_tree;
|
||||
|
@ -452,7 +452,7 @@ dissect_RSI_CONN_block(tvbuff_t *tvb, int offset,
|
|||
}
|
||||
|
||||
offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, sub_tree, drep,
|
||||
tvb_captured_length_remaining(tvb, offset), u8MoreFrag);
|
||||
tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_REQ);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ dissect_FREQ_RTA_block(tvbuff_t *tvb, int offset,
|
|||
switch (u32FOpnumOffsetOpnum) {
|
||||
case(0x0): /* RSI-CONN-PDU */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "Connect request");
|
||||
offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag,u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
case(0x1): /* Reserved */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
|
||||
|
@ -479,35 +479,35 @@ dissect_FREQ_RTA_block(tvbuff_t *tvb, int offset,
|
|||
break;
|
||||
case(0x2): /* RSI-SVCS-PDU (Only valid with ARUUID<>0) */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "Read request");
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
case(0x3): /* RSI-SVCS-PDU */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "Write request");
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
case(0x4): /* RSI-SVCS-PDU */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "Control request");
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
case(0x5): /* RSI-CONN-PDU (Only valid with ARUUID=0) */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "ReadImplicit request");
|
||||
offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
case(0x6): /* RSI-CONN-PDU (Only valid with ARUUID<>0) */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "ReadConnectionless request");
|
||||
offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
case(0x7): /* RSI-SVCS-PDU */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "ReadNotification request");
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
case(0x8): /* RSI-SVCS-PDU */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteMore request");
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
case(0x9) : /* RSI-SVCS-PDU */
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteEnd request");
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
break;
|
||||
default:
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
|
||||
|
@ -520,8 +520,13 @@ dissect_FREQ_RTA_block(tvbuff_t *tvb, int offset,
|
|||
/* dissect a PN-IO RSI RSP block (on top of PN-RT protocol) */
|
||||
static int
|
||||
dissect_RSI_RSP_block(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset)
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
|
||||
{
|
||||
guint32 u32RsiHeaderSize = 4;
|
||||
|
||||
// PDU.FOpnumOffset.Offset + PDU.VarPartLen - 4 - RsiHeaderSize
|
||||
gint32 length = u32FOpnumOffsetOffset + u16VarPartLen - 4 - u32RsiHeaderSize;
|
||||
|
||||
if (u32FOpnumOffsetOffset == 0)
|
||||
{
|
||||
offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
|
||||
|
@ -532,15 +537,18 @@ dissect_RSI_RSP_block(tvbuff_t *tvb, int offset,
|
|||
proto_item_append_text(tree, ", RSI Header of RSP is at first fragmented frame");
|
||||
}
|
||||
|
||||
offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, tree, drep,
|
||||
tvb_captured_length_remaining(tvb, offset), u8MoreFrag);
|
||||
if (length > 0) {
|
||||
offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, tree, drep,
|
||||
tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_RSP);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* dissect a PN-IO RSI FRSP RTA PDU (on top of PN-RT protocol) */
|
||||
static int
|
||||
dissect_FRSP_RTA_block(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag)
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag)
|
||||
{
|
||||
guint32 u32FOpnumOffset;
|
||||
guint32 u32FOpnumOffsetOpnum;
|
||||
|
@ -583,7 +591,7 @@ dissect_FRSP_RTA_block(tvbuff_t *tvb, int offset,
|
|||
col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
|
||||
break;
|
||||
}
|
||||
offset = dissect_RSI_RSP_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset);
|
||||
offset = dissect_RSI_RSP_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
@ -705,7 +713,7 @@ dissect_PNIO_RSI(tvbuff_t *tvb, int offset,
|
|||
offset = dissect_FREQ_RTA_block(tvb, offset, pinfo, rta_tree, drep, u8MoreFrag);
|
||||
break;
|
||||
case(6): /* FRSP-RTA */
|
||||
offset = dissect_FRSP_RTA_block(tvb, offset, pinfo, rta_tree, drep, u8MoreFrag);
|
||||
offset = dissect_FRSP_RTA_block(tvb, offset, pinfo, rta_tree, drep, u16VarPartLen, u8MoreFrag);
|
||||
break;
|
||||
default:
|
||||
offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
|
||||
|
|
|
@ -148,6 +148,11 @@ extern int dissect_pn_user_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U
|
|||
extern int dissect_blocks(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo, proto_tree *tree, guint8 *drep);
|
||||
|
||||
#define PDU_TYPE_REQ 0x05
|
||||
#define PDU_TYPE_RSP 0x06
|
||||
|
||||
extern int dissect_rsi_blocks(tvbuff_t* tvb, int offset, packet_info* pinfo, proto_tree* tree, guint8* drep, guint32 u32FOpnumOffsetOpnum, int type);
|
||||
|
||||
#define SUBST_DATA 1
|
||||
#define FRAG_DATA 2
|
||||
|
||||
|
@ -170,7 +175,7 @@ extern int dissect_PNIO_C_SDU_RTC1(tvbuff_t* tvb, int offset, packet_info* pinfo
|
|||
|
||||
extern int dissect_PNIO_RSI(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
proto_tree *tree, guint8 *drep);
|
||||
|
||||
|
||||
extern int dissect_PDRsiInstances_block(tvbuff_t *tvb, int offset,
|
||||
packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow);
|
||||
|
||||
|
|
Loading…
Reference in New Issue