Wireshark  4.3.0
The Wireshark network protocol analyzer
packet-coap.h
1 /* packet-coap.h
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9 
10 #ifndef __PACKET_COAP_H__
11 #define __PACKET_COAP_H__
12 
13 #include "packet-oscore.h"
14 
15 /* bitmasks */
16 #define COAP_VERSION_MASK 0xC0
17 #define COAP_TYPE_MASK 0x30
18 #define COAP_TOKEN_LEN_MASK 0x0F
19 #define COAP_BLOCK_MFLAG_MASK 0x08
20 #define COAP_BLOCK_SIZE_MASK 0x07
21 #define COAP_OBJECT_SECURITY_RESERVED_MASK 0xE0
22 #define COAP_OBJECT_SECURITY_KID_CONTEXT_MASK 0x10
23 #define COAP_OBJECT_SECURITY_KID_MASK 0x08
24 #define COAP_OBJECT_SECURITY_PIVLEN_MASK 0x07
25 
26 /* Parent protocol for CoAP */
27 typedef enum {
28  PARENT_WEBSOCKETS, /* WebSockets */
29  PARENT_TCP_TLS, /* TCP or TLS */
30  PARENT_OTHER /* UDP, WAP, other packet-based protocols */
31 } coap_parent_protocol;
32 
33 /* CoAP Message information */
34 typedef struct {
35  const gchar *ctype_str;
36  guint ctype_value;
37  guint block_option; /* Indicates Block1 or Block2 option */
38  guint block_number;
39  guint block_mflag;
40  wmem_strbuf_t *uri_str_strbuf; /* the maximum is 1024 > 510 = Uri-Host:255 + Uri-Path:255 x 2 */
41  wmem_strbuf_t *uri_query_strbuf; /* the maximum is 1024 > 765 = Uri-Query:255 x 3 */
42  gboolean is_coap_for_tmf; /* CoAP for Thread Management Framework */
43  gboolean object_security;
44  oscore_info_t *oscore_info; /* OSCORE data needed to decrypt */
45 } coap_info;
46 
47 /* CoAP Conversation information */
48 typedef struct {
49  wmem_map_t *messages;
51 
52 /* CoAP Transaction tracking information */
53 typedef struct {
54  wmem_map_t *req_rsp;
55  wmem_strbuf_t *uri_str_strbuf;
56  oscore_info_t *oscore_info; /* OSCORE transaction to decrypt response */
58 
59 typedef struct {
60  guint32 req_frame;
61  guint32 rsp_frame;
62  nstime_t req_time;
64 
65 /* common header fields, subtrees and expert info for SSL and DTLS dissectors */
66 typedef struct coap_common_dissect {
67  struct {
68  /* Header fields */
69  int code;
70  /* Payload fields */
71  int payload;
72  int payload_desc;
73  int payload_length;
74 
75  /* Option fields */
76  int opt_name;
77  int opt_desc;
78  int opt_delta;
79  int opt_delta_ext;
80  int opt_length;
81  int opt_length_ext;
82  int opt_end_marker;
83  int opt_ctype;
84  int opt_max_age;
85  int opt_proxy_uri;
86  int opt_proxy_scheme;
87  int opt_size1;
88  int opt_etag;
89  int opt_uri_host;
90  int opt_location_path;
91  int opt_uri_port;
92  int opt_location_query;
93  int opt_uri_path;
94  int opt_uri_path_recon;
95  int opt_observe_req;
96  int opt_observe_rsp;
97  int opt_hop_limit;
98  int opt_accept;
99  int opt_if_match;
100  int opt_block_number;
101  int opt_block_mflag;
102  int opt_block_size;
103  int opt_uri_query;
104  int opt_echo;
105  int opt_no_response;
106  int opt_request_tag;
107  int opt_ocf_version;
108  int opt_ocf_accept_version;
109  int opt_unknown;
110  int opt_object_security_reserved;
111  int opt_object_security_kid_context_present;
112  int opt_object_security_kid_present;
113  int opt_object_security_piv_len;
114  int opt_object_security_piv;
115  int opt_object_security_kid_context_len;
116  int opt_object_security_kid_context;
117  int opt_object_security_kid;
118 
119  /* do not forget to update COAP_COMMON_LIST_T and COAP_COMMON_HF_LIST! */
120  } hf;
121 
122  struct {
123  gint payload;
124  gint option;
125 
126  /* do not forget to update COAP_COMMON_LIST_T and COAP_COMMON_ETT_LIST! */
127  } ett;
128 
129  struct {
130  /* Generic expert info for malformed packets. */
131  expert_field opt_unknown_number;
132  expert_field opt_invalid_number;
133  expert_field opt_invalid_range;
134  expert_field opt_length_bad;
135  expert_field opt_object_security_bad;
136 
137  /* do not forget to update COAP_COMMON_LIST_T and COAP_COMMON_EI_LIST! */
138  } ei;
140 
141 guint8 dissect_coap_code(tvbuff_t *tvb, proto_tree *coap_tree, gint *offset, coap_common_dissect_t *dissect_hf, guint8 *code_class);
142 int dissect_coap_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *coap_tree, gint offset, gint offset_end, guint8 code_class, coap_info *coinfo, coap_common_dissect_t *dissect_hf);
143 void dissect_coap_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *coap_tree, proto_tree *parent_tree, gint offset, gint offset_end, guint8 code_class, coap_info *coinfo, coap_common_dissect_t *dissect_hf, gboolean oscore);
144 
145 extern const value_string coap_vals_observe_options[];
146 extern value_string_ext coap_vals_code_ext;
147 
148 /* {{{ */
149 #define COAP_COMMON_LIST_T(name) \
150 coap_common_dissect_t name = { \
151  /* hf */ { \
152  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
153  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
154  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
155  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
156  -1, -1, -1, -1, -1, -1, \
157  }, \
158  /* ett */ { \
159  -1, -1, \
160  }, \
161  /* ei */ { \
162  EI_INIT, EI_INIT, EI_INIT, EI_INIT, EI_INIT, \
163  }, \
164 }
165 /* }}} */
166 
167 /* {{{ */
168 #define COAP_COMMON_HF_LIST(name, prefix) \
169  { & name .hf.code, \
170  { "Code", prefix ".code", \
171  FT_UINT8, BASE_DEC | BASE_EXT_STRING, &coap_vals_code_ext, 0x0, \
172  NULL, HFILL } \
173  }, \
174  { & name .hf.payload, \
175  { "Payload", prefix ".payload", \
176  FT_STRING, BASE_NONE, NULL, 0x0, \
177  NULL, HFILL } \
178  }, \
179  { & name .hf.payload_desc, \
180  { "Payload Desc", prefix ".payload_desc", \
181  FT_STRING, BASE_NONE, NULL, 0x0, \
182  NULL, HFILL } \
183  }, \
184  { & name .hf.payload_length, \
185  { "Payload Length", prefix ".payload_length", \
186  FT_UINT32, BASE_DEC, NULL, 0x0, \
187  NULL, HFILL } \
188  }, \
189  { & name .hf.opt_name, \
190  { "Opt Name", prefix ".opt.name", \
191  FT_STRING, BASE_NONE, NULL, 0x0, \
192  NULL, HFILL } \
193  }, \
194  { & name .hf.opt_desc, \
195  { "Opt Desc", prefix ".opt.desc", \
196  FT_STRING, BASE_NONE, NULL, 0x0, \
197  NULL, HFILL } \
198  }, \
199  { & name .hf.opt_delta, \
200  { "Opt Delta", prefix ".opt.delta", \
201  FT_UINT8, BASE_DEC, NULL, 0xf0, \
202  NULL, HFILL } \
203  }, \
204  { & name .hf.opt_delta_ext, \
205  { "Opt Delta extended", prefix ".opt.delta_ext", \
206  FT_UINT16, BASE_DEC, NULL, 0x0, \
207  NULL, HFILL } \
208  }, \
209  { & name .hf.opt_length, \
210  { "Opt Length", prefix ".opt.length", \
211  FT_UINT8, BASE_DEC, NULL, 0x0f, \
212  "Option Length", HFILL } \
213  }, \
214  { & name .hf.opt_length_ext, \
215  { "Opt Length extended", prefix ".opt.length_ext", \
216  FT_UINT16, BASE_DEC, NULL, 0x0, \
217  NULL, HFILL } \
218  }, \
219  { & name .hf.opt_end_marker, \
220  { "End of options marker", prefix ".opt.end_marker", \
221  FT_UINT8, BASE_DEC, NULL, 0x00, \
222  NULL, HFILL } \
223  }, \
224  { & name .hf.opt_ctype, \
225  { "Content-type", prefix ".opt.ctype", \
226  FT_STRING, BASE_NONE, NULL, 0x0, \
227  NULL, HFILL } \
228  }, \
229  { & name .hf.opt_max_age, \
230  { "Max-age", prefix ".opt.max_age", \
231  FT_UINT32, BASE_DEC, NULL, 0x0, \
232  NULL, HFILL } \
233  }, \
234  { & name .hf.opt_proxy_uri, \
235  { "Proxy-Uri", prefix ".opt.proxy_uri", \
236  FT_STRING, BASE_NONE, NULL, 0x0, \
237  NULL, HFILL } \
238  }, \
239  { & name .hf.opt_proxy_scheme, \
240  { "Proxy-Scheme", prefix ".opt.proxy_scheme", \
241  FT_STRING, BASE_NONE, NULL, 0x0, \
242  NULL, HFILL } \
243  }, \
244  { & name .hf.opt_size1, \
245  { "Size1", prefix ".opt.size1", \
246  FT_UINT32, BASE_DEC, NULL, 0x0, \
247  NULL, HFILL } \
248  }, \
249  { & name .hf.opt_etag, \
250  { "Etag", prefix ".opt.etag", \
251  FT_BYTES, BASE_NONE, NULL, 0x0, \
252  "Option Etag", HFILL } \
253  }, \
254  { & name .hf.opt_uri_host, \
255  { "Uri-Host", prefix ".opt.uri_host", \
256  FT_STRING, BASE_NONE, NULL, 0x0, \
257  NULL, HFILL } \
258  }, \
259  { & name .hf.opt_location_path, \
260  { "Location-Path", prefix ".opt.location_path", \
261  FT_STRING, BASE_NONE, NULL, 0x0, \
262  NULL, HFILL } \
263  }, \
264  { & name .hf.opt_uri_port, \
265  { "Uri-Port", prefix ".opt.uri_port", \
266  FT_UINT16, BASE_DEC, NULL, 0x0, \
267  NULL, HFILL } \
268  }, \
269  { & name .hf.opt_location_query, \
270  { "Location-Query", prefix ".opt.location_query", \
271  FT_STRING, BASE_NONE, NULL, 0x0, \
272  NULL, HFILL } \
273  }, \
274  { & name .hf.opt_object_security_reserved, \
275  { "Reserved", prefix ".opt.object_security_reserved", \
276  FT_BOOLEAN, 8, NULL, COAP_OBJECT_SECURITY_RESERVED_MASK, \
277  NULL, HFILL } \
278  }, \
279  { & name .hf.opt_object_security_kid_context_present, \
280  { "Key ID Context Present", prefix ".opt.object_security_kid_context_present",\
281  FT_BOOLEAN, 8, NULL, COAP_OBJECT_SECURITY_KID_CONTEXT_MASK, \
282  NULL, HFILL } \
283  }, \
284  { & name .hf.opt_object_security_kid_present, \
285  { "Key ID Present", prefix ".opt.object_security_kid_present", \
286  FT_BOOLEAN, 8, NULL, COAP_OBJECT_SECURITY_KID_MASK, \
287  NULL, HFILL } \
288  }, \
289  { & name .hf.opt_object_security_piv_len, \
290  { "Partial IV Length", prefix ".opt.object_security_piv_len", \
291  FT_UINT8, BASE_DEC, NULL, COAP_OBJECT_SECURITY_PIVLEN_MASK, \
292  NULL, HFILL } \
293  }, \
294  { & name .hf.opt_object_security_piv, \
295  { "Partial IV", prefix ".opt.object_security_piv", \
296  FT_BYTES, BASE_NONE, NULL, 0x00, \
297  NULL, HFILL } \
298  }, \
299  { & name .hf.opt_object_security_kid_context_len, \
300  { "Key ID Context Length", prefix ".opt.object_security_kid_context_len",\
301  FT_UINT8, BASE_DEC, NULL, 0x00, \
302  NULL, HFILL } \
303  }, \
304  { & name .hf.opt_object_security_kid_context, \
305  { "Key ID Context", prefix ".opt.object_security_kid_context", \
306  FT_BYTES, BASE_NONE, NULL, 0x00, \
307  NULL, HFILL } \
308  }, \
309  { & name .hf.opt_object_security_kid, \
310  { "Key ID", prefix ".opt.object_security_kid", \
311  FT_BYTES, BASE_NONE, NULL, 0x00, \
312  NULL, HFILL } \
313  }, \
314  { & name .hf.opt_uri_path, \
315  { "Uri-Path", prefix ".opt.uri_path", \
316  FT_STRING, BASE_NONE, NULL, 0x0, \
317  NULL, HFILL } \
318  }, \
319  { & name .hf.opt_uri_path_recon, \
320  { "Uri-Path", prefix ".opt.uri_path_recon", \
321  FT_STRING, BASE_NONE, NULL, 0x0, \
322  NULL, HFILL } \
323  }, \
324  { & name .hf.opt_observe_req, \
325  { "Observe", prefix ".opt.observe", \
326  FT_UINT32, BASE_DEC, VALS(coap_vals_observe_options), 0x0, \
327  NULL, HFILL } \
328  }, \
329  { & name .hf.opt_observe_rsp, \
330  { "Observe sequence number", prefix ".opt.observe", \
331  FT_UINT32, BASE_DEC, NULL, 0x0, \
332  NULL, HFILL } \
333  }, \
334  { & name .hf.opt_hop_limit, \
335  { "Hop Limit", prefix ".opt.hop_limit", \
336  FT_UINT8, BASE_DEC, NULL, 0x0, \
337  NULL, HFILL } \
338  }, \
339  { & name .hf.opt_accept, \
340  { "Accept", prefix ".opt.accept", \
341  FT_STRING, BASE_NONE, NULL, 0x0, \
342  NULL, HFILL } \
343  }, \
344  { & name .hf.opt_if_match, \
345  { "If-Match", prefix ".opt.if_match", \
346  FT_BYTES, BASE_NONE, NULL, 0x0, \
347  NULL, HFILL } \
348  }, \
349  { & name .hf.opt_block_number, \
350  { "Block Number", prefix ".opt.block_number", \
351  FT_UINT32, BASE_DEC, NULL, 0x0, \
352  NULL, HFILL } \
353  }, \
354  { & name .hf.opt_block_mflag, \
355  { "More Flag", prefix ".opt.block_mflag", \
356  FT_UINT8, BASE_DEC, NULL, COAP_BLOCK_MFLAG_MASK, \
357  NULL, HFILL } \
358  }, \
359  { & name .hf.opt_block_size, \
360  { "Encoded Block Size", prefix ".opt.block_size", \
361  FT_UINT8, BASE_DEC, NULL, COAP_BLOCK_SIZE_MASK, \
362  NULL, HFILL } \
363  }, \
364  { & name .hf.opt_uri_query, \
365  { "Uri-Query", prefix ".opt.uri_query", \
366  FT_STRING, BASE_NONE, NULL, 0x0, \
367  NULL, HFILL } \
368  }, \
369  { & name .hf.opt_echo, \
370  { "Echo", prefix ".opt.opt_echo", \
371  FT_BYTES, BASE_NONE, NULL, 0x0, \
372  NULL, HFILL } \
373  }, \
374  { & name .hf.opt_no_response, \
375  { "No-Response", prefix ".opt.opt_no_response", \
376  FT_UINT8, BASE_DEC, NULL, 0x0, \
377  NULL, HFILL } \
378  }, \
379  { & name .hf.opt_request_tag, \
380  { "Request-Tag", prefix ".opt.opt_request_tag", \
381  FT_BYTES, BASE_NONE, NULL, 0x0, \
382  NULL, HFILL } \
383  }, \
384  { & name .hf.opt_ocf_version, \
385  { "OCF-Content-Format-Version", \
386  prefix ".opt.opt_ocf_version", \
387  FT_UINT8, BASE_DEC, NULL, 0x0, \
388  NULL, HFILL } \
389  }, \
390  { & name .hf.opt_ocf_accept_version, \
391  { "OCF-Accept-Content-Format-Version", \
392  prefix ".opt.opt_ocf_accept_version", \
393  FT_UINT8, BASE_DEC, NULL, 0x0, \
394  NULL, HFILL } \
395  }, \
396  { & name .hf.opt_unknown, \
397  { "Unknown", prefix ".opt.unknown", \
398  FT_BYTES, BASE_NONE, NULL, 0x0, \
399  NULL, HFILL } \
400  }, \
401 /* }}} */
402 
403 /* {{{ */
404 #define COAP_COMMON_ETT_LIST(name) \
405  & name .ett.payload, \
406  & name .ett.option, \
407 
408 /* }}} */
409 
410 /* {{{ */
411 #define COAP_COMMON_EI_LIST(name, prefix) \
412  { & name .ei.opt_unknown_number, \
413  { prefix ".unknown_option_number", PI_UNDECODED, PI_WARN, \
414  "Unknown Option Number", EXPFILL } \
415  }, \
416  { & name .ei.opt_invalid_number, \
417  { prefix ".invalid_option_number", PI_MALFORMED, PI_WARN, \
418  "Invalid Option Number", EXPFILL } \
419  }, \
420  { & name .ei.opt_invalid_range, \
421  { prefix ".invalid_option_range", PI_MALFORMED, PI_WARN, \
422  "Invalid Option Range", EXPFILL } \
423  }, \
424  { & name .ei.opt_length_bad, \
425  { prefix ".option_length_bad", PI_MALFORMED, PI_WARN, \
426  "Option length bad", EXPFILL } \
427  }, \
428  { & name .ei.opt_object_security_bad, \
429  { prefix ".option_oscore_bad", PI_MALFORMED, PI_WARN, \
430  "Invalid OSCORE Option Format", EXPFILL } \
431  }, \
432 
433 /* }}} */
434 
435 #endif /* __PACKET_COAP_H__ */
436 
437 /*
438  * Editor modelines - https://www.wireshark.org/tools/modelines.html
439  *
440  * Local variables:
441  * c-basic-offset: 8
442  * tab-width: 8
443  * indent-tabs-mode: t
444  * End:
445  *
446  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
447  * :indentSize=8:tabSize=8:noTabs=false:
448  */
Definition: packet_info.h:44
Definition: proto.h:897
Definition: value_string.h:170
Definition: value_string.h:26
Definition: wmem_map.c:44
Definition: wmem_strbuf.h:42
Definition: packet-coap.h:66
Definition: packet-coap.h:48
Definition: packet-coap.h:34
Definition: packet-coap.h:59
Definition: packet-coap.h:53
Definition: expert.h:39
Definition: nstime.h:26
Definition: packet-oscore.h:51
Definition: tvbuff-int.h:35