attr_dissector_fn_t
[wireshark-sm.git] / epan / wscbor.h
blobdabcb8df27f8983a2c7d6b66a40eca1f52d52b26
1 /** @file
2 * Definitions for the Wireshark CBOR item decoding API.
3 * References:
4 * RFC 8949: https://tools.ietf.org/html/rfc8949
6 * Copyright 2019-2021, Brian Sipos <brian.sipos@gmail.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: LGPL-2.1-or-later
15 #ifndef __WSCBOR_H__
16 #define __WSCBOR_H__
18 #include <ws_symbol_export.h>
19 #include <epan/tvbuff.h>
20 #include <epan/proto.h>
21 #include <epan/expert.h>
22 #include <wsutil/wmem/wmem_list.h>
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
28 /** Register expert info and other wireshark data.
30 WS_DLL_PUBLIC
31 void wscbor_init(void);
33 /** Expose available expert info for this library.
34 * @param[out] size Set to the size of the array.
35 * @return The array of expert info objects.
37 WS_DLL_PUBLIC
38 const ei_register_info * wscbor_expert_items(int *size);
40 /// The same enumeration from libcbor-0.5
41 typedef enum cbor_type {
42 CBOR_TYPE_UINT = 0, ///< positive integers
43 CBOR_TYPE_NEGINT = 1, ///< negative integers
44 CBOR_TYPE_BYTESTRING = 2, ///< byte strings
45 CBOR_TYPE_STRING = 3, ///< text strings
46 CBOR_TYPE_ARRAY = 4, ///< arrays
47 CBOR_TYPE_MAP = 5, ///< maps
48 CBOR_TYPE_TAG = 6, ///< tags
49 CBOR_TYPE_FLOAT_CTRL = 7, ///< decimals and special values (true, false, nil, ...)
50 } cbor_type;
52 /// The same enumeration from libcbor-0.5
53 typedef enum {
54 CBOR_CTRL_NONE = 0,
55 CBOR_CTRL_FALSE = 20,
56 CBOR_CTRL_TRUE = 21,
57 CBOR_CTRL_NULL = 22,
58 CBOR_CTRL_UNDEF = 23
59 } _cbor_ctrl;
61 /// Decoding or require_* error
62 typedef struct {
63 /// The associated expert info
64 expert_field *ei;
65 /// Optional specific text
66 const char *msg;
67 } wscbor_error_t;
69 /** Construct a new error object.
71 * @param alloc The allocator to use.
72 * @param ei The specific error type.
73 * @param format If non-NULL, a message format string.
74 * @return The new object.
76 WS_DLL_PUBLIC
77 wscbor_error_t * wscbor_error_new(wmem_allocator_t *alloc, expert_field *ei, const char *format, ...);
79 /// Tag metadata and value
80 typedef struct {
81 /// The start offset of this tag head
82 int start;
83 /// The length of just this tag head
84 int length;
85 /// The tag value
86 uint64_t value;
87 } wscbor_tag_t;
89 struct _wscbor_chunk_priv_t;
90 typedef struct _wscbor_chunk_priv_t wscbor_chunk_priv_t;
91 /// A data-containing, optionally-tagged chunk of CBOR
92 typedef struct {
93 /// Internal private data
94 wscbor_chunk_priv_t *_priv;
96 /// The start offset of this chunk
97 int start;
98 /// The length of just this header and any preceding tags
99 int head_length;
100 /// The length of this chunk and its immediate definite data (i.e. strings)
101 int data_length;
102 /// Errors processing this chunk (type wscbor_error_t*)
103 wmem_list_t *errors;
104 /// Tags on this chunk, in encoded order (type wscbor_tag_t*)
105 wmem_list_t *tags;
107 /// Major type of this block.
108 /// This will be one of the cbor_type values.
109 cbor_type type_major;
110 /// Minor type of this item
111 uint8_t type_minor;
112 /// The header-encoded value
113 uint64_t head_value;
114 } wscbor_chunk_t;
116 /** Scan for a tagged chunk of headers.
117 * The chunk of byte string and text string items includes the data content
118 * in its @c offset.
120 * @param alloc The allocator to use.
121 * @param tvb The TVB to read from.
122 * @param[in,out] offset The offset with in @c tvb.
123 * This is updated to be just past the new chunk.
124 * @return The chunk of data found, including any errors.
125 * This never returns NULL.
126 * @post This can throw ReportedBoundsError or ContainedBoundsError
127 * if the read itself ran out of data.
129 WS_DLL_PUBLIC
130 wscbor_chunk_t * wscbor_chunk_read(wmem_allocator_t *alloc, tvbuff_t *tvb, int *offset);
132 /** Free a chunk and its lists.
134 WS_DLL_PUBLIC
135 void wscbor_chunk_free(wscbor_chunk_t *chunk);
137 /** After both reading and decoding a chunk, report on any errors found.
138 * @param pinfo The associated packet.
139 * @param item The associated tree item.
140 * @param chunk The chunk with possible errors.
141 * @return The error count.
143 WS_DLL_PUBLIC
144 uint64_t wscbor_chunk_mark_errors(packet_info *pinfo, proto_item *item, const wscbor_chunk_t *chunk);
146 /** Determine if a chunk has errors.
147 * @param chunk The chunk with possible errors.
148 * @return The error count.
150 WS_DLL_PUBLIC
151 unsigned wscbor_has_errors(const wscbor_chunk_t *chunk);
153 /** Determine if an indefinite break is present.
155 * @param chunk The chunk to check.
156 * @return True if it's an indefinite break.
158 WS_DLL_PUBLIC
159 bool wscbor_is_indefinite_break(const wscbor_chunk_t *chunk);
161 /** Recursively skip items from a stream.
163 * @param alloc The allocator to use.
164 * @param tvb The data buffer.
165 * @param[in,out] offset The initial offset to read and skip over.
166 * Will be set to one-past the last valid CBOR (possibly nested) present.
167 * @return True if the skipped item was fully valid.
168 * @post This can throw ReportedBoundsError or ContainedBoundsError
169 * if the read itself ran out of data.
171 WS_DLL_PUBLIC
172 bool wscbor_skip_next_item(wmem_allocator_t *alloc, tvbuff_t *tvb, int *offset);
174 /** Skip over an item if a chunk has errors.
175 * This allows skipping an entire array or map if the major type or size is
176 * not as expected.
178 * @param alloc The allocator to use.
179 * @param tvb The data buffer.
180 * @param[in,out] offset The initial offset to read and skip over.
181 * @param chunk The chunk with possible errors.
182 * @return True if there were errors and the item skipped.
184 WS_DLL_PUBLIC
185 bool wscbor_skip_if_errors(wmem_allocator_t *alloc, tvbuff_t *tvb, int *offset, const wscbor_chunk_t *chunk);
188 /** Require a specific item major type.
190 * @param[in,out] chunk The chunk to read from and write errors on.
191 * @param major The required major type.
192 * @return True if the item is that type.
194 WS_DLL_PUBLIC
195 bool wscbor_require_major_type(wscbor_chunk_t *chunk, cbor_type major);
197 /** Require an array item.
199 * @param[in,out] chunk The chunk to read from and write errors on.
200 * @return True if the item is an array.
202 WS_DLL_PUBLIC
203 bool wscbor_require_array(wscbor_chunk_t *chunk);
205 /** Require an array have a specific ranged size.
207 * @param[in,out] chunk The chunk to read from and write errors on.
208 * @param count_min The minimum acceptable size.
209 * @param count_max The maximum acceptable size.
210 * @return True if the size is acceptable.
212 WS_DLL_PUBLIC
213 bool wscbor_require_array_size(wscbor_chunk_t *chunk, uint64_t count_min, uint64_t count_max);
215 /** Require a map item.
217 * @param[in,out] chunk The chunk to read from and write errors on.
218 * @return True if the item is a map.
220 WS_DLL_PUBLIC
221 bool wscbor_require_map(wscbor_chunk_t *chunk);
223 /** Require a CBOR item to have a boolean value.
225 * @param alloc The allocator to use.
226 * @param[in,out] chunk The chunk to read from and write errors on.
227 * @return Pointer to the boolean value, if the item was boolean.
228 * The value can be deleted with wscbor_require_delete().
230 WS_DLL_PUBLIC
231 bool * wscbor_require_boolean(wmem_allocator_t *alloc, wscbor_chunk_t *chunk);
233 /** Require a CBOR item to have an unsigned-integer value.
234 * @note This reader will clip the most significant bit of the value.
236 * @param alloc The allocator to use.
237 * @param[in,out] chunk The chunk to read from and write errors on.
238 * @return Pointer to the boolean value, if the item was an integer.
239 * The value can be deleted with wscbor_require_delete().
241 WS_DLL_PUBLIC
242 uint64_t * wscbor_require_uint64(wmem_allocator_t *alloc, wscbor_chunk_t *chunk);
244 /** Require a CBOR item to have an signed- or unsigned-integer value.
245 * @note This reader will clip the most significant bit of the value.
247 * @param alloc The allocator to use.
248 * @param[in,out] chunk The chunk to read from and write errors on.
249 * @return Pointer to the value, if the item was an integer.
250 * The value can be deleted with wscbor_require_delete().
252 WS_DLL_PUBLIC
253 int64_t * wscbor_require_int64(wmem_allocator_t *alloc, wscbor_chunk_t *chunk);
255 /** Require a CBOR item to have a text-string value.
256 * If the actual text string is not needed, use the following to avoid an
257 * unnecessary allocation.
258 * @code
259 * wscbor_require_major_type(chunk, CBOR_TYPE_STRING)
260 * @endcode
262 * @param alloc The allocator to use.
263 * @param[in,out] chunk The chunk to read from and write errors on.
264 * @return Pointer to the null-terminated UTF-8, if the item was a tstr.
265 * @post This can throw ContainedBoundsError string ran out of data.
267 WS_DLL_PUBLIC
268 char * wscbor_require_tstr(wmem_allocator_t *alloc, wscbor_chunk_t *chunk);
270 /** Require a CBOR item to have a byte-string value.
271 * Use tvb_memdup() or similar if the raw byte-string is needed.
273 * @param alloc The allocator to use.
274 * @param[in,out] chunk The chunk to read from and write errors on.
275 * @return Pointer to the value, if the item was an bstr.
276 * The value is memory managed by wireshark.
278 WS_DLL_PUBLIC
279 tvbuff_t * wscbor_require_bstr(wmem_allocator_t *alloc, wscbor_chunk_t *chunk);
281 /** Add an item representing an array or map container.
282 * If the item is type FT_UINT* or FT_INT* the count of (array) items
283 * or map (pairs) is used as the iterm value.
285 WS_DLL_PUBLIC
286 proto_item * proto_tree_add_cbor_container(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk);
288 /** Add an item representing a non-boolean, non-float control value.
290 WS_DLL_PUBLIC
291 proto_item * proto_tree_add_cbor_ctrl(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk);
293 WS_DLL_PUBLIC
294 proto_item * proto_tree_add_cbor_boolean(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk, const bool *value);
296 WS_DLL_PUBLIC
297 proto_item * proto_tree_add_cbor_uint64(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk, const uint64_t *value);
299 WS_DLL_PUBLIC
300 proto_item * proto_tree_add_cbor_int64(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk, const int64_t *value);
302 WS_DLL_PUBLIC
303 proto_item * proto_tree_add_cbor_bitmask(proto_tree *tree, int hfindex, const int ett, int *const *fields, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk, const uint64_t *value);
305 WS_DLL_PUBLIC
306 proto_item * proto_tree_add_cbor_tstr(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk);
308 WS_DLL_PUBLIC
309 proto_item * proto_tree_add_cbor_bstr(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk);
311 /** Add an item representing the length of a bstr or tstr value.
313 WS_DLL_PUBLIC
314 proto_item * proto_tree_add_cbor_strlen(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk);
316 #ifdef __cplusplus
318 #endif
320 #endif /* __WSCBOR_H__ */