Wireshark  2.9.0-477-g68ec514b
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_NON_COMPRESSED_MASK 0x80
22 #define COAP_OBJECT_SECURITY_EXPAND_MASK 0x40
23 #define COAP_OBJECT_SECURITY_SIGNATURE_MASK 0x20
24 #define COAP_OBJECT_SECURITY_KID_CONTEXT_MASK 0x10
25 #define COAP_OBJECT_SECURITY_KID_MASK 0x08
26 #define COAP_OBJECT_SECURITY_PIVLEN_MASK 0x07
27 
28 /* CoAP Message information */
29 typedef struct {
30  const gchar *ctype_str;
31  guint ctype_value;
32  guint block_number;
33  guint block_mflag;
34  wmem_strbuf_t *uri_str_strbuf; /* the maximum is 1024 > 510 = Uri-Host:255 + Uri-Path:255 x 2 */
35  wmem_strbuf_t *uri_query_strbuf; /* the maximum is 1024 > 765 = Uri-Query:255 x 3 */
36  gboolean object_security;
37  oscore_info_t *oscore_info; /* OSCORE data needed to decrypt */
38 } coap_info;
39 
40 /* CoAP Conversation information */
41 typedef struct {
42  wmem_map_t *messages;
44 
45 /* CoAP Transaction tracking information */
46 typedef struct {
47  guint32 req_frame;
48  guint32 rsp_frame;
49  nstime_t req_time;
50  const gchar *req_ctype_str;
51  guint req_ctype_value;
52  wmem_strbuf_t *uri_str_strbuf;
53  oscore_info_t *oscore_info; /* OSCORE transaction to decrypt response */
55 
56 /* common header fields, subtrees and expert info for SSL and DTLS dissectors */
57 typedef struct coap_common_dissect {
58  struct {
59  /* Header fields */
60  int code;
61  /* Payload fields */
62  int payload;
63  int payload_desc;
64  int payload_length;
65 
66  /* Option fields */
67  int opt_name;
68  int opt_desc;
69  int opt_delta;
70  int opt_delta_ext;
71  int opt_length;
72  int opt_length_ext;
73  int opt_end_marker;
74  int opt_ctype;
75  int opt_max_age;
76  int opt_proxy_uri;
77  int opt_proxy_scheme;
78  int opt_size1;
79  int opt_etag;
80  int opt_uri_host;
81  int opt_location_path;
82  int opt_uri_port;
83  int opt_location_query;
84  int opt_uri_path;
85  int opt_uri_path_recon;
86  int opt_observe;
87  int opt_accept;
88  int opt_if_match;
89  int opt_block_number;
90  int opt_block_mflag;
91  int opt_block_size;
92  int opt_uri_query;
93  int opt_unknown;
94  int opt_object_security_non_compressed;
95  int opt_object_security_expand;
96  int opt_object_security_signature;
97  int opt_object_security_kid_context_present;
98  int opt_object_security_kid_present;
99  int opt_object_security_piv_len;
100  int opt_object_security_piv;
101  int opt_object_security_kid_context_len;
102  int opt_object_security_kid_context;
103  int opt_object_security_kid;
104 
105  /* do not forget to update COAP_COMMON_LIST_T and COAP_COMMON_HF_LIST! */
106  } hf;
107 
108  struct {
109  gint payload;
110  gint option;
111 
112  /* do not forget to update COAP_COMMON_LIST_T and COAP_COMMON_ETT_LIST! */
113  } ett;
114 
115  struct {
116  /* Generic expert info for malformed packets. */
117  expert_field opt_invalid_number;
118  expert_field opt_invalid_range;
119  expert_field opt_length_bad;
120  expert_field opt_object_security_bad;
121 
122  /* do not forget to update COAP_COMMON_LIST_T and COAP_COMMON_EI_LIST! */
123  } ei;
125 
126 guint8 dissect_coap_code(tvbuff_t *tvb, proto_tree *coap_tree, gint *offset, coap_common_dissect_t *dissect_hf, guint8 *code_class);
127 int dissect_coap_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *coap_tree, gint offset, gint offset_end, coap_info *coinfo, coap_common_dissect_t *dissect_hf);
128 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);
129 
130 extern const value_string coap_vals_observe_options[];
131 extern value_string_ext coap_vals_code_ext;
132 
133 /* {{{ */
134 #define COAP_COMMON_LIST_T(name) \
135 coap_common_dissect_t name = { \
136  /* hf */ { \
137  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
138  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
139  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
140  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
141  -1, \
142  }, \
143  /* ett */ { \
144  -1, -1, \
145  }, \
146  /* ei */ { \
147  EI_INIT, EI_INIT, EI_INIT, EI_INIT, \
148  }, \
149 }
150 /* }}} */
151 
152 /* {{{ */
153 #define COAP_COMMON_HF_LIST(name, prefix) \
154  { & name .hf.code, \
155  { "Code", prefix ".code", \
156  FT_UINT8, BASE_DEC | BASE_EXT_STRING, &coap_vals_code_ext, 0x0, \
157  NULL, HFILL } \
158  }, \
159  { & name .hf.payload, \
160  { "Payload", prefix ".payload", \
161  FT_STRING, BASE_NONE, NULL, 0x0, \
162  NULL, HFILL } \
163  }, \
164  { & name .hf.payload_desc, \
165  { "Payload Desc", prefix ".payload_desc", \
166  FT_STRING, BASE_NONE, NULL, 0x0, \
167  NULL, HFILL } \
168  }, \
169  { & name .hf.payload_length, \
170  { "Payload Length", prefix ".payload_length", \
171  FT_UINT32, BASE_DEC, NULL, 0x0, \
172  NULL, HFILL } \
173  }, \
174  { & name .hf.opt_name, \
175  { "Opt Name", prefix ".opt.name", \
176  FT_STRING, BASE_NONE, NULL, 0x0, \
177  NULL, HFILL } \
178  }, \
179  { & name .hf.opt_desc, \
180  { "Opt Desc", prefix ".opt.desc", \
181  FT_STRING, BASE_NONE, NULL, 0x0, \
182  NULL, HFILL } \
183  }, \
184  { & name .hf.opt_delta, \
185  { "Opt Delta", prefix ".opt.delta", \
186  FT_UINT8, BASE_DEC, NULL, 0xf0, \
187  NULL, HFILL } \
188  }, \
189  { & name .hf.opt_delta_ext, \
190  { "Opt Delta extended", prefix ".opt.delta_ext", \
191  FT_UINT16, BASE_DEC, NULL, 0x0, \
192  NULL, HFILL } \
193  }, \
194  { & name .hf.opt_length, \
195  { "Opt Length", prefix ".opt.length", \
196  FT_UINT8, BASE_DEC, NULL, 0x0f, \
197  "Option Length", HFILL } \
198  }, \
199  { & name .hf.opt_length_ext, \
200  { "Opt Length extended", prefix ".opt.length_ext", \
201  FT_UINT16, BASE_DEC, NULL, 0x0, \
202  NULL, HFILL } \
203  }, \
204  { & name .hf.opt_end_marker, \
205  { "End of options marker", prefix ".opt.end_marker", \
206  FT_UINT8, BASE_DEC, NULL, 0x00, \
207  NULL, HFILL } \
208  }, \
209  { & name .hf.opt_ctype, \
210  { "Content-type", prefix ".opt.ctype", \
211  FT_STRING, BASE_NONE, NULL, 0x0, \
212  NULL, HFILL } \
213  }, \
214  { & name .hf.opt_max_age, \
215  { "Max-age", prefix ".opt.max_age", \
216  FT_UINT32, BASE_DEC, NULL, 0x0, \
217  NULL, HFILL } \
218  }, \
219  { & name .hf.opt_proxy_uri, \
220  { "Proxy-Uri", prefix ".opt.proxy_uri", \
221  FT_STRING, BASE_NONE, NULL, 0x0, \
222  NULL, HFILL } \
223  }, \
224  { & name .hf.opt_proxy_scheme, \
225  { "Proxy-Scheme", prefix ".opt.proxy_scheme", \
226  FT_STRING, BASE_NONE, NULL, 0x0, \
227  NULL, HFILL } \
228  }, \
229  { & name .hf.opt_size1, \
230  { "Size1", prefix ".opt.size1", \
231  FT_UINT32, BASE_DEC, NULL, 0x0, \
232  NULL, HFILL } \
233  }, \
234  { & name .hf.opt_etag, \
235  { "Etag", prefix ".opt.etag", \
236  FT_BYTES, BASE_NONE, NULL, 0x0, \
237  "Option Etag", HFILL } \
238  }, \
239  { & name .hf.opt_uri_host, \
240  { "Uri-Host", prefix ".opt.uri_host", \
241  FT_STRING, BASE_NONE, NULL, 0x0, \
242  NULL, HFILL } \
243  }, \
244  { & name .hf.opt_location_path, \
245  { "Location-Path", prefix ".opt.location_path", \
246  FT_STRING, BASE_NONE, NULL, 0x0, \
247  NULL, HFILL } \
248  }, \
249  { & name .hf.opt_uri_port, \
250  { "Uri-Port", prefix ".opt.uri_port", \
251  FT_UINT16, BASE_DEC, NULL, 0x0, \
252  NULL, HFILL } \
253  }, \
254  { & name .hf.opt_location_query, \
255  { "Location-Query", prefix ".opt.location_query", \
256  FT_STRING, BASE_NONE, NULL, 0x0, \
257  NULL, HFILL } \
258  }, \
259  { & name .hf.opt_object_security_non_compressed, \
260  { "Non-compressed COSE message", prefix ".opt.object_security_non_compressed",\
261  FT_BOOLEAN, 8, NULL, COAP_OBJECT_SECURITY_NON_COMPRESSED_MASK, \
262  NULL, HFILL } \
263  }, \
264  { & name .hf.opt_object_security_expand, \
265  { "Expanded Flag Byte", prefix ".opt.object_security_expand", \
266  FT_BOOLEAN, 8, NULL, COAP_OBJECT_SECURITY_EXPAND_MASK, \
267  NULL, HFILL } \
268  }, \
269  { & name .hf.opt_object_security_signature, \
270  { "Signature Present", prefix ".opt.object_security_signature", \
271  FT_BOOLEAN, 8, NULL, COAP_OBJECT_SECURITY_SIGNATURE_MASK, \
272  NULL, HFILL } \
273  }, \
274  { & name .hf.opt_object_security_kid_context_present, \
275  { "Key ID Context Present", prefix ".opt.object_security_kid_context_present",\
276  FT_BOOLEAN, 8, NULL, COAP_OBJECT_SECURITY_KID_CONTEXT_MASK, \
277  NULL, HFILL } \
278  }, \
279  { & name .hf.opt_object_security_kid_present, \
280  { "Key ID Present", prefix ".opt.object_security_kid", \
281  FT_BOOLEAN, 8, NULL, COAP_OBJECT_SECURITY_KID_MASK, \
282  NULL, HFILL } \
283  }, \
284  { & name .hf.opt_object_security_piv_len, \
285  { "Partial IV Length", prefix ".opt.object_security_piv_len", \
286  FT_UINT8, BASE_DEC, NULL, COAP_OBJECT_SECURITY_PIVLEN_MASK, \
287  NULL, HFILL } \
288  }, \
289  { & name .hf.opt_object_security_piv, \
290  { "Partial IV", prefix ".opt.object_security_piv", \
291  FT_BYTES, BASE_NONE, NULL, 0x00, \
292  NULL, HFILL } \
293  }, \
294  { & name .hf.opt_object_security_kid_context_len, \
295  { "Key ID Context Length", prefix ".opt.object_security_kid_context_len",\
296  FT_UINT8, BASE_DEC, NULL, 0x00, \
297  NULL, HFILL } \
298  }, \
299  { & name .hf.opt_object_security_kid_context, \
300  { "Partial IV", prefix ".opt.object_security_kid_context", \
301  FT_BYTES, BASE_NONE, NULL, 0x00, \
302  NULL, HFILL } \
303  }, \
304  { & name .hf.opt_object_security_kid, \
305  { "Key ID", prefix ".opt.object_security_kid", \
306  FT_BYTES, BASE_NONE, NULL, 0x00, \
307  NULL, HFILL } \
308  }, \
309  { & name .hf.opt_uri_path, \
310  { "Uri-Path", prefix ".opt.uri_path", \
311  FT_STRING, BASE_NONE, NULL, 0x0, \
312  NULL, HFILL } \
313  }, \
314  { & name .hf.opt_uri_path_recon, \
315  { "Uri-Path", prefix ".opt.uri_path_recon", \
316  FT_STRING, BASE_NONE, NULL, 0x0, \
317  NULL, HFILL } \
318  }, \
319  { & name .hf.opt_observe, \
320  { "Observe", prefix ".opt.observe", \
321  FT_UINT32, BASE_DEC, VALS(coap_vals_observe_options), 0x0, \
322  NULL, HFILL } \
323  }, \
324  { & name .hf.opt_accept, \
325  { "Accept", prefix ".opt.accept", \
326  FT_STRING, BASE_NONE, NULL, 0x0, \
327  NULL, HFILL } \
328  }, \
329  { & name .hf.opt_if_match, \
330  { "If-Match", prefix ".opt.if_match", \
331  FT_BYTES, BASE_NONE, NULL, 0x0, \
332  NULL, HFILL } \
333  }, \
334  { & name .hf.opt_block_number, \
335  { "Block Number", prefix ".opt.block_number", \
336  FT_UINT32, BASE_DEC, NULL, 0x0, \
337  NULL, HFILL } \
338  }, \
339  { & name .hf.opt_block_mflag, \
340  { "More Flag", prefix ".opt.block_mflag", \
341  FT_UINT8, BASE_DEC, NULL, COAP_BLOCK_MFLAG_MASK, \
342  NULL, HFILL } \
343  }, \
344  { & name .hf.opt_block_size, \
345  { "Encoded Block Size", prefix ".opt.block_size", \
346  FT_UINT8, BASE_DEC, NULL, COAP_BLOCK_SIZE_MASK, \
347  NULL, HFILL } \
348  }, \
349  { & name .hf.opt_uri_query, \
350  { "Uri-Query", prefix ".opt.uri_query", \
351  FT_STRING, BASE_NONE, NULL, 0x0, \
352  NULL, HFILL } \
353  }, \
354  { & name .hf.opt_unknown, \
355  { "Unknown", prefix ".opt.unknown", \
356  FT_BYTES, BASE_NONE, NULL, 0x0, \
357  NULL, HFILL } \
358  }, \
359 /* }}} */
360 
361 /* {{{ */
362 #define COAP_COMMON_ETT_LIST(name) \
363  & name .ett.payload, \
364  & name .ett.option, \
365 
366 /* }}} */
367 
368 /* {{{ */
369 #define COAP_COMMON_EI_LIST(name, prefix) \
370  { & name .ei.opt_invalid_number, \
371  { prefix ".invalid_option_number", PI_MALFORMED, PI_WARN, \
372  "Invalid Option Number", EXPFILL } \
373  }, \
374  { & name .ei.opt_invalid_range, \
375  { prefix ".invalid_option_range", PI_MALFORMED, PI_WARN, \
376  "Invalid Option Range", EXPFILL } \
377  }, \
378  { & name .ei.opt_length_bad, \
379  { prefix ".option_length_bad", PI_MALFORMED, PI_WARN, \
380  "Option length bad", EXPFILL } \
381  }, \
382  { & name .ei.opt_object_security_bad, \
383  { prefix ".option_object_security_bad", PI_MALFORMED, PI_WARN, \
384  "Invalid Object-Security Option Format", EXPFILL } \
385  }, \
386 
387 /* }}} */
388 
389 #endif /* __PACKET_COAP_H__ */
390 
391 /*
392  * Editor modelines - http://www.wireshark.org/tools/modelines.html
393  *
394  * Local variables:
395  * c-basic-offset: 8
396  * tab-width: 8
397  * indent-tabs-mode: t
398  * End:
399  *
400  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
401  * :indentSize=8:tabSize=8:noTabs=false:
402  */
Definition: wmem_map.c:44
Definition: packet_info.h:44
Definition: packet-coap.h:57
Definition: tvbuff-int.h:35
Definition: nstime.h:27
Definition: pcapng.c:148
Definition: packet-coap.h:41
Definition: wmem_strbuf.c:36
Definition: packet-coap.h:29
Definition: expert.h:37
Definition: packet-oscore.h:49
Definition: value_string.h:24
Definition: value_string.h:164
Definition: proto.h:759
Definition: packet-coap.h:46