aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStig Bjørlykke <stig@bjorlykke.org>2020-06-10 10:07:52 +0200
committerStig Bjørlykke <stig@bjorlykke.org>2020-06-11 06:37:41 +0000
commitd3845de25674501dc9b57597b2b7a1ea4a8891a9 (patch)
treefe8c2f3e00235f840e7c565c76b31118d476432b
parent86c6befcabf00fa5ff68075c1012731edf2e12f2 (diff)
coap: Add block reassembly
Reassemble blocks before passing to payload dissector. Change-Id: I09d81abe016989c8d705355a117cf12e40f07e59 Reviewed-on: https://code.wireshark.org/review/37440 Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org> Tested-by: Petri Dish Buildbot Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
-rw-r--r--epan/dissectors/packet-coap.c110
1 files changed, 109 insertions, 1 deletions
diff --git a/epan/dissectors/packet-coap.c b/epan/dissectors/packet-coap.c
index cccaf4b435..0a21ad551b 100644
--- a/epan/dissectors/packet-coap.c
+++ b/epan/dissectors/packet-coap.c
@@ -25,6 +25,7 @@
#include <epan/conversation.h>
#include <epan/packet.h>
+#include <epan/reassemble.h>
#include <epan/proto_data.h>
#include <epan/expert.h>
#include <epan/wmem/wmem.h>
@@ -57,8 +58,22 @@ static int hf_coap_oscore_kid = -1;
static int hf_coap_oscore_kid_context = -1;
static int hf_coap_oscore_piv = -1;
+static int hf_blocks = -1;
+static int hf_block = -1;
+static int hf_block_overlap = -1;
+static int hf_block_overlap_conflicts = -1;
+static int hf_block_multiple_tails = -1;
+static int hf_block_too_long = -1;
+static int hf_block_error = -1;
+static int hf_block_count = -1;
+static int hf_block_reassembled_in = -1;
+static int hf_block_reassembled_length = -1;
+
static gint ett_coap = -1;
+static gint ett_block = -1;
+static gint ett_blocks = -1;
+
static expert_field ei_retransmitted = EI_INIT;
static COAP_COMMON_LIST_T(dissect_coap_hf);
@@ -248,6 +263,31 @@ static const value_string vals_ctype[] = {
static const char *nullstr = "(null)";
+static reassembly_table coap_block_reassembly_table;
+
+static const fragment_items coap_block_frag_items = {
+ /* Fragment subtrees */
+ &ett_block,
+ &ett_blocks,
+ /* Fragment fields */
+ &hf_blocks,
+ &hf_block,
+ &hf_block_overlap,
+ &hf_block_overlap_conflicts,
+ &hf_block_multiple_tails,
+ &hf_block_too_long,
+ &hf_block_error,
+ &hf_block_count,
+ /* Reassembled in field */
+ &hf_block_reassembled_in,
+ /* Reassembled length field */
+ &hf_block_reassembled_length,
+ /* Reassembled data field */
+ NULL,
+ /* Tag */
+ "Block fragments"
+};
+
void proto_reg_handoff_coap(void);
static conversation_t *
@@ -1367,7 +1407,21 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
/* dissect the payload */
if (coap_length > offset) {
- dissect_coap_payload(tvb, pinfo, coap_tree, parent_tree, offset, coap_length, code_class, coinfo, &dissect_coap_hf, FALSE);
+ if (coinfo->block_number == DEFAULT_COAP_BLOCK_NUMBER) {
+ dissect_coap_payload(tvb, pinfo, coap_tree, parent_tree, offset, coap_length,
+ code_class, coinfo, &dissect_coap_hf, FALSE);
+ } else {
+ fragment_head *frag_msg = fragment_add_seq_check(&coap_block_reassembly_table, tvb, offset,
+ pinfo, 0, NULL, coinfo->block_number,
+ coap_length - offset, coinfo->block_mflag);
+ tvbuff_t *frag_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled CoAP blocks",
+ frag_msg, &coap_block_frag_items, NULL, coap_tree);
+
+ if (frag_tvb) {
+ dissect_coap_payload(frag_tvb, pinfo, coap_tree, parent_tree, 0, tvb_reported_length(frag_tvb),
+ code_class, coinfo, &dissect_coap_hf, FALSE);
+ }
+ }
}
return coap_length;
@@ -1472,11 +1526,63 @@ proto_register_coap(void)
{ "OSCORE Partial IV", "coap.oscore_piv", FT_BYTES, BASE_NONE, NULL, 0x0,
"Matched OSCORE Partial IV", HFILL }
},
+ { &hf_blocks,
+ { "Blocks", "coap.blocks",
+ FT_NONE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_block,
+ { "Block", "coap.block",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_block_overlap,
+ { "Block overlap", "coap.block.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_block_overlap_conflicts,
+ { "Block overlapping with conflicting data", "coap.block.overlap.conflicts",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_block_multiple_tails,
+ { "Block has multiple tails", "coap.block.multiple_tails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_block_too_long,
+ { "Block too long", "coap.block.too_long",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_block_error,
+ { "Block defragmentation error", "coap.block.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_block_count,
+ { "Block count", "coap.block.count",
+ FT_UINT32, BASE_DEC, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_block_reassembled_in,
+ { "Reassembled in", "coap.block.reassembled.in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_block_reassembled_length,
+ { "Reassembled block length", "coap.block.reassembled.length",
+ FT_UINT32, BASE_DEC, NULL, 0x00,
+ NULL, HFILL }
+ },
COAP_COMMON_HF_LIST(dissect_coap_hf, "coap")
};
static gint *ett[] = {
&ett_coap,
+ &ett_block,
+ &ett_blocks,
COAP_COMMON_ETT_LIST(dissect_coap_hf)
};
@@ -1496,6 +1602,8 @@ proto_register_coap(void)
expert_coap = expert_register_protocol(proto_coap);
expert_register_field_array(expert_coap, ei, array_length(ei));
+ reassembly_table_register (&coap_block_reassembly_table, &addresses_reassembly_table_functions);
+
coap_handle = register_dissector("coap", dissect_coap, proto_coap);
}