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