diff options
author | Guy Harris <gharris@sonic.net> | 2022-09-13 12:44:57 -0700 |
---|---|---|
committer | A Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org> | 2022-09-13 19:47:58 +0000 |
commit | 8724c249e1cd2a91e726a682d85924a58ae10b18 (patch) | |
tree | dd125f180221ac5296d006fab62cb882119f1d5a | |
parent | fd84d481fcfe1413599fb800b1159df211cb4ef3 (diff) |
coap, thread: special-case application/octet-stream for CoAP for TMF.
Have a "CoAP for TMF" dissector that the user can use Decode As to
assign to a UDP port.
Have a "coap_tmf_media_type" dissector table in which the TMF code can
register itself for the media type "application/octet-stream".
Have the "CoAP for TMF" dissector pass a "this is for TMF" flag to the
common dissection code. In the common dissection code, if that flag is
set, first try the media type with the "coap_tmf_media_type" dissector
table before trying it in the regular "media_type" table.
This allows a user to specify UDP ports that 1) should be decoded as
CoAP and 2) should have an application/octet-stream payload dissected as
a TMF message, which should address concerns raised for Thread in issue
-rw-r--r-- | epan/dissectors/packet-coap.c | 73 | ||||
-rw-r--r-- | epan/dissectors/packet-coap.h | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-thread.c | 1 |
3 files changed, 68 insertions, 7 deletions
diff --git a/epan/dissectors/packet-coap.c b/epan/dissectors/packet-coap.c index e8366fe377..ea49e6d079 100644 --- a/epan/dissectors/packet-coap.c +++ b/epan/dissectors/packet-coap.c @@ -39,9 +39,22 @@ void proto_register_coap(void); +static dissector_table_t coap_tmf_media_type_dissector_table; static dissector_table_t media_type_dissector_table; static int proto_coap = -1; +/* + * Used only to register the "CoAP for Thread Management Framework" + * dissector, which uses the same protocol and field IDs as the + * regular CoAP dissector, as it's just "CoAP except that we interpret + * application/octet-stream as meaning Thread Management Framework + * messages", because the Thread protocol, for whatever reasons (trying + * to keep the CoAP layer of their messages as short and simple to parse + * as possible, to save power and reduce the chances of low-power + * transmissions being misreceived?), did not register a media type for + * its messages and a 'cf' value for that media type. + */ +static int proto_coap_for_tmf = -1; static int hf_coap_length = -1; static int hf_coap_version = -1; @@ -84,6 +97,7 @@ static COAP_COMMON_LIST_T(dissect_coap_hf); static dissector_handle_t coap_tcp_tls_handle; static dissector_handle_t coap_other_handle; +static dissector_handle_t coap_for_tmf_handle; static dissector_handle_t oscore_handle; /* CoAP's IANA-assigned TCP/UDP port numbers */ @@ -1068,6 +1082,7 @@ dissect_coap_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *coap_tree, p const char *coap_ctype_str_dis; http_message_info_t message_info; char str_payload[80]; + int result = 0; /* coinfo->ctype_value == DEFAULT_COAP_CTYPE_VALUE: No Content-Format option present */ if (coinfo->ctype_value == DEFAULT_COAP_CTYPE_VALUE) { @@ -1114,9 +1129,33 @@ dissect_coap_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *coap_tree, p message_info.type = HTTP_OTHERS; message_info.media_str = wmem_strbuf_get_str(coinfo->uri_str_strbuf); - dissector_try_string(media_type_dissector_table, coap_ctype_str_dis, - payload_tvb, pinfo, parent_tree, &message_info); - + /* + * The Thread protocol uses application/octet-stream for its + * messages, rather than having its own media type for those + * messages, as, for example, the Internet Printing Protocol + * does. + * + * Handle "application/octet-stream" specially if this is + * being dissected by the "CoAP for Thread Management Framework" + * dissector. + */ + if (coinfo->is_coap_for_tmf) { + /* + * Try the media type dissector table for CoAP-TMF first. + */ + result = dissector_try_string(coap_tmf_media_type_dissector_table, + coap_ctype_str_dis, payload_tvb, pinfo, parent_tree, + &message_info); + } + if (result == 0) { + /* + * That either failed or we didn't try it. + * Now try the regular media type table. + */ + dissector_try_string(media_type_dissector_table, + coap_ctype_str_dis, payload_tvb, pinfo, parent_tree, + &message_info); + } if (coinfo->object_security && !oscore) { proto_item_set_text(payload_item, "Encrypted OSCORE Data"); call_dissector_with_data(oscore_handle, payload_tvb, pinfo, parent_tree, coinfo->oscore_info); @@ -1160,7 +1199,7 @@ coap_frame_length(tvbuff_t *tvb, guint offset, gint *size) } static int -dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, coap_parent_protocol parent_protocol) +dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, coap_parent_protocol parent_protocol, gboolean is_coap_for_tmf) { gint offset = 0; proto_item *coap_root; @@ -1192,6 +1231,9 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, p_add_proto_data(wmem_file_scope(), pinfo, proto_coap, 0, coinfo); } +// coinfo->parent_protocol = parent_protocol; + coinfo->is_coap_for_tmf = is_coap_for_tmf; + /* initialize the CoAP length and the content-Format */ /* * The length of CoAP message is not specified in the CoAP header using @@ -1507,19 +1549,25 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, static int dissect_coap_tcp_tls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - return dissect_coap_message(tvb, pinfo, tree, PARENT_TCP_TLS); + return dissect_coap_message(tvb, pinfo, tree, PARENT_TCP_TLS, FALSE); } static int dissect_coap_websockets(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - return dissect_coap_message(tvb, pinfo, tree, PARENT_WEBSOCKETS); + return dissect_coap_message(tvb, pinfo, tree, PARENT_WEBSOCKETS, FALSE); } static int dissect_coap_other(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - return dissect_coap_message(tvb, pinfo, tree, PARENT_OTHER); + return dissect_coap_message(tvb, pinfo, tree, PARENT_OTHER, FALSE); +} + +static int +dissect_coap_for_tmf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + return dissect_coap_message(tvb, pinfo, tree, PARENT_OTHER, TRUE); } /* @@ -1686,6 +1734,14 @@ proto_register_coap(void) coap_other_handle = register_dissector("coap", dissect_coap_other, proto_coap); coap_tcp_tls_handle = register_dissector("coap_tcp_tls", dissect_coap_tcp_tls, proto_coap); + coap_for_tmf_handle = register_dissector_with_description("coap_for_tmf", "CoAP-TMF", dissect_coap_for_tmf, proto_coap_for_tmf); + + /* + * Set up a subdissector table for media types for CoAP-TMF. + */ + coap_tmf_media_type_dissector_table = + register_dissector_table("coap_tmf_media_type", + "Internet media type for CoAP-TMF", proto_coap, FT_STRING, BASE_NONE); } void @@ -1708,6 +1764,9 @@ proto_reg_handoff_coap(void) coap_websockets_handle = create_dissector_handle(dissect_coap_websockets, proto_coap); dissector_add_string("ws.protocol", "coap", coap_websockets_handle); + /* CoAP for Thread Management Framework */ + dissector_add_for_decode_as("udp.port", coap_for_tmf_handle); + oscore_handle = find_dissector("oscore"); } diff --git a/epan/dissectors/packet-coap.h b/epan/dissectors/packet-coap.h index cffd2cb9ae..765aa0d7df 100644 --- a/epan/dissectors/packet-coap.h +++ b/epan/dissectors/packet-coap.h @@ -39,6 +39,7 @@ typedef struct { guint block_mflag; wmem_strbuf_t *uri_str_strbuf; /* the maximum is 1024 > 510 = Uri-Host:255 + Uri-Path:255 x 2 */ wmem_strbuf_t *uri_query_strbuf; /* the maximum is 1024 > 765 = Uri-Query:255 x 3 */ + gboolean is_coap_for_tmf; /* CoAP for Thread Management Framework */ gboolean object_security; oscore_info_t *oscore_info; /* OSCORE data needed to decrypt */ } coap_info; diff --git a/epan/dissectors/packet-thread.c b/epan/dissectors/packet-thread.c index 808ab838ac..efa08351b1 100644 --- a/epan/dissectors/packet-thread.c +++ b/epan/dissectors/packet-thread.c @@ -3391,6 +3391,7 @@ proto_register_thread_coap(void) proto_thread_coap = proto_register_protocol("Thread CoAP", "Thread CoAP", "thread_coap"); thread_coap_handle = register_dissector("thread_coap", dissect_thread_coap, proto_thread_coap); + dissector_add_string("coap_tmf_media_type", "application/octet-stream", thread_coap_handle); thread_coap_namespace = register_dissector_table("thread.coap_namespace", "Thread CoAP namespace", proto_thread_coap, FT_STRING, BASE_NONE); } |