From 16988d2b4f4bca2b9564b19debdd90577b4b52ea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Aug 2018 17:02:37 +0200 Subject: packet-iwarp-mpa: make use of tcp_dissect_pdus() to reassamble pdus There might be more than one mpa frame in a tcp pdu or one mpa frame spans more than one tcp pdu. Signed-off-by: Stefan Metzmacher --- epan/dissectors/packet-iwarp-mpa.c | 100 ++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/epan/dissectors/packet-iwarp-mpa.c b/epan/dissectors/packet-iwarp-mpa.c index 6da357c4c6..2e14c1e1dd 100644 --- a/epan/dissectors/packet-iwarp-mpa.c +++ b/epan/dissectors/packet-iwarp-mpa.c @@ -829,6 +829,104 @@ dissect_iwarp_mpa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat return FALSE; } +static guint +iwrap_mpa_pdu_length(packet_info *pinfo _U_, tvbuff_t *tvb, + int offset, void *data _U_) +{ + guint64 tag; + gint remaining = tvb_captured_length_remaining(tvb, offset); + guint pdu_length = 0; + guint16 PD_Length; + + tag = tvb_get_ntoh64(tvb, offset); + if (tag != MPA_REQ_REP_FRAME) { + /* FPDU */ + guint16 ULPDU_Length; + guint8 pad_length; + + ULPDU_Length = tvb_get_ntohs(tvb, offset); + pad_length = fpdu_pad_length(ULPDU_Length); + + pdu_length += MPA_ULPDU_LENGTH_LEN; + pdu_length += ULPDU_Length; + pdu_length += pad_length; + pdu_length += MPA_CRC_LEN; + + return pdu_length; + } + + /* + * MPA Request and Reply Frame Format... + */ + + if (remaining < MPA_REQ_REP_FRAME_HEADER_LEN) { + /* + * We need more data. + */ + return 0; + } + + offset += MPA_REQ_REP_FRAME_HEADER_LEN; + offset -= MPA_REQ_REP_PDLENGTH_LEN; + + PD_Length = tvb_get_ntohs(tvb, offset); + + pdu_length += MPA_REQ_REP_FRAME_HEADER_LEN; + pdu_length += PD_Length; + + return pdu_length; +} + +static int +dissect_iwarp_mpa_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +{ + gboolean ok; + guint len; + + len = iwrap_mpa_pdu_length(pinfo, tvb, 0, data); + ok = dissect_iwarp_mpa(tvb, pinfo, tree, data); + if (!ok) { + return -1; + } + + return len; +} + +static gboolean +dissect_iwarp_mpa_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +{ + struct tcpinfo *tcpinfo = NULL; + gboolean is_mpa_pdu = FALSE; + + if (data == NULL) + return FALSE; + tcpinfo = (struct tcpinfo *)data; + + /* MPA REQUEST or MPA REPLY */ + if (tvb_captured_length(tvb) >= MPA_REQ_REP_FRAME_HEADER_LEN) { + if (is_mpa_req(tvb, pinfo)) { + is_mpa_pdu = TRUE; + } else if (is_mpa_rep(tvb, pinfo)) { + is_mpa_pdu = TRUE; + } + } + if (tvb_captured_length(tvb) >= MPA_SMALLEST_FPDU_LEN && is_mpa_fpdu(pinfo)) { + is_mpa_pdu = TRUE; + } + + if (!is_mpa_pdu) { + return FALSE; + } + + tcp_dissect_pdus(tvb, pinfo, tree, + TRUE, /* proto_desegment*/ + MPA_SMALLEST_FPDU_LEN, + iwrap_mpa_pdu_length, + dissect_iwarp_mpa_pdu, + tcpinfo); + return TRUE; +} + /* registers this protocol with Wireshark */ void proto_register_mpa(void) { @@ -949,7 +1047,7 @@ proto_reg_handoff_mpa(void) * MPA does not use any specific TCP port so, when not on a specific * port, try this dissector whenever there is TCP traffic. */ - heur_dissector_add("tcp", dissect_iwarp_mpa, "IWARP_MPA over TCP", "iwarp_mpa_tcp", proto_iwarp_mpa, HEURISTIC_ENABLE); + heur_dissector_add("tcp", dissect_iwarp_mpa_heur, "IWARP_MPA over TCP", "iwarp_mpa_tcp", proto_iwarp_mpa, HEURISTIC_ENABLE); ddp_rdmap_handle = find_dissector_add_dependency("iwarp_ddp_rdmap", proto_iwarp_mpa); } -- cgit v1.2.3