aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-coap.c63
-rw-r--r--epan/dissectors/packet-coap.h10
2 files changed, 50 insertions, 23 deletions
diff --git a/epan/dissectors/packet-coap.c b/epan/dissectors/packet-coap.c
index 56695cbc2b..3acff1a913 100644
--- a/epan/dissectors/packet-coap.c
+++ b/epan/dissectors/packet-coap.c
@@ -1037,13 +1037,14 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
guint32 token_len;
guint8 code;
guint8 code_class;
- guint32 mid;
+ guint32 mid = 0;
gint coap_length;
gchar *coap_token_str;
coap_info *coinfo;
conversation_t *conversation;
coap_conv_info *ccinfo;
coap_transaction *coap_trans = NULL;
+ coap_request_response *coap_req_rsp = NULL;
// TODO support TCP/WebSocket/TCP with more than one PDU per packet.
// These probably require a unique coinfo for each.
@@ -1173,9 +1174,7 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
if ((!PINFO_FD_VISITED(pinfo)) && (code_class == 0)) {
/* New request - log it */
coap_trans = wmem_new0(wmem_file_scope(), coap_transaction);
- coap_trans->req_frame = pinfo->num;
- coap_trans->rsp_frame = 0;
- coap_trans->req_time = pinfo->abs_ts;
+ coap_trans->req_rsp = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
if (coinfo->uri_str_strbuf) {
/* Store the URI into CoAP transaction info */
coap_trans->uri_str_strbuf = wmem_strbuf_new(wmem_file_scope(), wmem_strbuf_get_str(coinfo->uri_str_strbuf));
@@ -1196,12 +1195,6 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
}
} else {
if ((code_class >= 2) && (code_class <= 5)) {
- if (!PINFO_FD_VISITED(pinfo)) {
- if (coap_trans->rsp_frame == 0) {
- /* Log the first matching response frame */
- coap_trans->rsp_frame = pinfo->num;
- }
- }
if (coap_trans->uri_str_strbuf) {
/* Copy the URI stored in matching transaction info into CoAP packet info */
coinfo->uri_str_strbuf = wmem_strbuf_new(wmem_packet_scope(), wmem_strbuf_get_str(coap_trans->uri_str_strbuf));
@@ -1232,6 +1225,30 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
}
}
}
+
+ if (coap_trans) {
+ coap_req_rsp = (coap_request_response *)wmem_map_lookup(coap_trans->req_rsp, GINT_TO_POINTER(mid));
+ if (!PINFO_FD_VISITED(pinfo)) {
+ if (!coap_req_rsp) {
+ coap_req_rsp = wmem_new0(wmem_file_scope(), coap_request_response);
+ wmem_map_insert(coap_trans->req_rsp, GINT_TO_POINTER(mid), (void *)coap_req_rsp);
+ }
+ if (code_class == 0) {
+ /* This is a request */
+ if (coap_req_rsp->req_frame == 0) {
+ /* Log the first request frame */
+ coap_req_rsp->req_frame = pinfo->num;
+ coap_req_rsp->req_time = pinfo->abs_ts;
+ }
+ } else if ((code_class >= 2) && (code_class <= 5)) {
+ /* This is a reply */
+ if (coap_req_rsp->rsp_frame == 0) {
+ /* Log the first matching response frame */
+ coap_req_rsp->rsp_frame = pinfo->num;
+ }
+ }
+ }
+ }
}
}
@@ -1250,45 +1267,51 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
if (wmem_strbuf_get_len(coinfo->uri_query_strbuf) > 0)
col_append_str(pinfo->cinfo, COL_INFO, wmem_strbuf_get_str(coinfo->uri_query_strbuf));
- if (coap_trans != NULL) {
+ if (coap_req_rsp != NULL) {
/* Print state tracking in the tree */
if (code_class == 0) {
/* This is a request */
- if (coap_trans->rsp_frame) {
+ if (coap_req_rsp->rsp_frame) {
proto_item *it;
it = proto_tree_add_uint(coap_tree, hf_coap_response_in,
- tvb, 0, 0, coap_trans->rsp_frame);
+ tvb, 0, 0, coap_req_rsp->rsp_frame);
proto_item_set_generated(it);
}
- if (coap_trans->req_frame != pinfo->num) {
+ if (coap_req_rsp->req_frame != pinfo->num) {
col_append_str(pinfo->cinfo, COL_INFO, " [Retransmission]");
proto_item *it = proto_tree_add_uint(coap_tree, hf_coap_request_resend_in,
- tvb, 0, 0, coap_trans->req_frame);
+ tvb, 0, 0, coap_req_rsp->req_frame);
proto_item_set_generated(it);
expert_add_info(pinfo, it, &ei_retransmitted);
}
} else if ((code_class >= 2) && (code_class <= 5)) {
/* This is a reply */
- if (coap_trans->req_frame) {
+ if (coap_req_rsp->req_frame) {
proto_item *it;
nstime_t ns;
it = proto_tree_add_uint(coap_tree, hf_coap_response_to,
- tvb, 0, 0, coap_trans->req_frame);
+ tvb, 0, 0, coap_req_rsp->req_frame);
proto_item_set_generated(it);
- nstime_delta(&ns, &pinfo->abs_ts, &coap_trans->req_time);
+ nstime_delta(&ns, &pinfo->abs_ts, &coap_req_rsp->req_time);
it = proto_tree_add_time(coap_tree, hf_coap_response_time, tvb, 0, 0, &ns);
proto_item_set_generated(it);
}
- if (coap_trans->rsp_frame != pinfo->num) {
+ if (coap_req_rsp->rsp_frame != pinfo->num) {
col_append_str(pinfo->cinfo, COL_INFO, " [Retransmission]");
proto_item *it = proto_tree_add_uint(coap_tree, hf_coap_response_resend_in,
- tvb, 0, 0, coap_trans->rsp_frame);
+ tvb, 0, 0, coap_req_rsp->rsp_frame);
proto_item_set_generated(it);
expert_add_info(pinfo, it, &ei_retransmitted);
}
+ }
+ }
+
+ if (coap_trans != NULL) {
+ if ((code_class >= 2) && (code_class <= 5)) {
+ /* This is a reply */
if (coinfo->object_security && coap_trans->oscore_info) {
proto_item *it;
diff --git a/epan/dissectors/packet-coap.h b/epan/dissectors/packet-coap.h
index 8e1e06441b..b8783c7ce2 100644
--- a/epan/dissectors/packet-coap.h
+++ b/epan/dissectors/packet-coap.h
@@ -44,13 +44,17 @@ typedef struct {
/* CoAP Transaction tracking information */
typedef struct {
- guint32 req_frame;
- guint32 rsp_frame;
- nstime_t req_time;
+ wmem_map_t *req_rsp;
wmem_strbuf_t *uri_str_strbuf;
oscore_info_t *oscore_info; /* OSCORE transaction to decrypt response */
} coap_transaction;
+typedef struct {
+ guint32 req_frame;
+ guint32 rsp_frame;
+ nstime_t req_time;
+} coap_request_response;
+
/* common header fields, subtrees and expert info for SSL and DTLS dissectors */
typedef struct coap_common_dissect {
struct {