2 * Definitions for the Wireshark CBOR item decoding API.
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
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>
28 /** Register expert info and other wireshark data.
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.
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, ...)
52 /// The same enumeration from libcbor-0.5
61 /// Decoding or require_* error
63 /// The associated expert info
65 /// Optional specific text
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.
77 wscbor_error_t
* wscbor_error_new(wmem_allocator_t
*alloc
, expert_field
*ei
, const char *format
, ...);
79 /// Tag metadata and value
81 /// The start offset of this tag head
83 /// The length of just this tag head
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
93 /// Internal private data
94 wscbor_chunk_priv_t
*_priv
;
96 /// The start offset of this chunk
98 /// The length of just this header and any preceding tags
100 /// The length of this chunk and its immediate definite data (i.e. strings)
102 /// Errors processing this chunk (type wscbor_error_t*)
104 /// Tags on this chunk, in encoded order (type wscbor_tag_t*)
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
112 /// The header-encoded value
116 /** Scan for a tagged chunk of headers.
117 * The chunk of byte string and text string items includes the data content
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.
130 wscbor_chunk_t
* wscbor_chunk_read(wmem_allocator_t
*alloc
, tvbuff_t
*tvb
, int *offset
);
132 /** Free a chunk and its lists.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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().
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().
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().
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.
259 * wscbor_require_major_type(chunk, CBOR_TYPE_STRING)
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.
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.
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.
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.
291 proto_item
* proto_tree_add_cbor_ctrl(proto_tree
*tree
, int hfindex
, packet_info
*pinfo
, tvbuff_t
*tvb
, const wscbor_chunk_t
*chunk
);
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
);
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
);
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
);
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
);
306 proto_item
* proto_tree_add_cbor_tstr(proto_tree
*tree
, int hfindex
, packet_info
*pinfo
, tvbuff_t
*tvb
, const wscbor_chunk_t
*chunk
);
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.
314 proto_item
* proto_tree_add_cbor_strlen(proto_tree
*tree
, int hfindex
, packet_info
*pinfo
, tvbuff_t
*tvb
, const wscbor_chunk_t
*chunk
);
320 #endif /* __WSCBOR_H__ */