diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/wscbor.h | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/wscbor.h')
-rw-r--r-- | epan/wscbor.h | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/epan/wscbor.h b/epan/wscbor.h new file mode 100644 index 00000000..51d612cb --- /dev/null +++ b/epan/wscbor.h @@ -0,0 +1,320 @@ +/** @file + * Definitions for the Wireshark CBOR item decoding API. + * References: + * RFC 8949: https://tools.ietf.org/html/rfc8949 + * + * Copyright 2019-2021, Brian Sipos <brian.sipos@gmail.com> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef __WSCBOR_H__ +#define __WSCBOR_H__ + +#include <ws_symbol_export.h> +#include <epan/tvbuff.h> +#include <epan/proto.h> +#include <epan/expert.h> +#include <wsutil/wmem/wmem_list.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** Register expert info and other wireshark data. + */ +WS_DLL_PUBLIC +void wscbor_init(void); + +/** Expose available expert info for this library. + * @param[out] size Set to the size of the array. + * @return The array of expert info objects. + */ +WS_DLL_PUBLIC +const ei_register_info * wscbor_expert_items(int *size); + +/// The same enumeration from libcbor-0.5 +typedef enum cbor_type { + CBOR_TYPE_UINT = 0, ///< positive integers + CBOR_TYPE_NEGINT = 1, ///< negative integers + CBOR_TYPE_BYTESTRING = 2, ///< byte strings + CBOR_TYPE_STRING = 3, ///< text strings + CBOR_TYPE_ARRAY = 4, ///< arrays + CBOR_TYPE_MAP = 5, ///< maps + CBOR_TYPE_TAG = 6, ///< tags + CBOR_TYPE_FLOAT_CTRL = 7, ///< decimals and special values (true, false, nil, ...) +} cbor_type; + +/// The same enumeration from libcbor-0.5 +typedef enum { + CBOR_CTRL_NONE = 0, + CBOR_CTRL_FALSE = 20, + CBOR_CTRL_TRUE = 21, + CBOR_CTRL_NULL = 22, + CBOR_CTRL_UNDEF = 23 +} _cbor_ctrl; + +/// Decoding or require_* error +typedef struct { + /// The associated expert info + expert_field *ei; + /// Optional specific text + const char *msg; +} wscbor_error_t; + +/** Construct a new error object. + * + * @param alloc The allocator to use. + * @param ei The specific error type. + * @param format If non-NULL, a message format string. + * @return The new object. + */ +WS_DLL_PUBLIC +wscbor_error_t * wscbor_error_new(wmem_allocator_t *alloc, expert_field *ei, const char *format, ...); + +/// Tag metadata and value +typedef struct { + /// The start offset of this tag head + gint start; + /// The length of just this tag head + gint length; + /// The tag value + guint64 value; +} wscbor_tag_t; + +struct _wscbor_chunk_priv_t; +typedef struct _wscbor_chunk_priv_t wscbor_chunk_priv_t; +/// A data-containing, optionally-tagged chunk of CBOR +typedef struct { + /// Internal private data + wscbor_chunk_priv_t *_priv; + + /// The start offset of this chunk + gint start; + /// The length of just this header and any preceding tags + gint head_length; + /// The length of this chunk and its immediate definite data (i.e. strings) + gint data_length; + /// Errors processing this chunk (type wscbor_error_t*) + wmem_list_t *errors; + /// Tags on this chunk, in encoded order (type wscbor_tag_t*) + wmem_list_t *tags; + + /// Major type of this block. + /// This will be one of the cbor_type values. + cbor_type type_major; + /// Minor type of this item + guint8 type_minor; + /// The header-encoded value + guint64 head_value; +} wscbor_chunk_t; + +/** Scan for a tagged chunk of headers. + * The chunk of byte string and text string items includes the data content + * in its @c offset. + * + * @param alloc The allocator to use. + * @param tvb The TVB to read from. + * @param[in,out] offset The offset with in @c tvb. + * This is updated to be just past the new chunk. + * @return The chunk of data found, including any errors. + * This never returns NULL. + * @post This can throw ReportedBoundsError or ContainedBoundsError + * if the read itself ran out of data. + */ +WS_DLL_PUBLIC +wscbor_chunk_t * wscbor_chunk_read(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *offset); + +/** Free a chunk and its lists. + */ +WS_DLL_PUBLIC +void wscbor_chunk_free(wscbor_chunk_t *chunk); + +/** After both reading and decoding a chunk, report on any errors found. + * @param pinfo The associated packet. + * @param item The associated tree item. + * @param chunk The chunk with possible errors. + * @return The error count. + */ +WS_DLL_PUBLIC +guint64 wscbor_chunk_mark_errors(packet_info *pinfo, proto_item *item, const wscbor_chunk_t *chunk); + +/** Determine if a chunk has errors. + * @param chunk The chunk with possible errors. + * @return The error count. + */ +WS_DLL_PUBLIC +guint wscbor_has_errors(const wscbor_chunk_t *chunk); + +/** Determine if an indefinite break is present. + * + * @param chunk The chunk to check. + * @return True if it's an indefinite break. + */ +WS_DLL_PUBLIC +gboolean wscbor_is_indefinite_break(const wscbor_chunk_t *chunk); + +/** Recursively skip items from a stream. + * + * @param alloc The allocator to use. + * @param tvb The data buffer. + * @param[in,out] offset The initial offset to read and skip over. + * Will be set to one-past the last valid CBOR (possibly nested) present. + * @return True if the skipped item was fully valid. + * @post This can throw ReportedBoundsError or ContainedBoundsError + * if the read itself ran out of data. + */ +WS_DLL_PUBLIC +gboolean wscbor_skip_next_item(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *offset); + +/** Skip over an item if a chunk has errors. + * This allows skipping an entire array or map if the major type or size is + * not as expected. + * + * @param alloc The allocator to use. + * @param tvb The data buffer. + * @param[in,out] offset The initial offset to read and skip over. + * @param chunk The chunk with possible errors. + * @return True if there were errors and the item skipped. + */ +WS_DLL_PUBLIC +gboolean wscbor_skip_if_errors(wmem_allocator_t *alloc, tvbuff_t *tvb, gint *offset, const wscbor_chunk_t *chunk); + + +/** Require a specific item major type. + * + * @param[in,out] chunk The chunk to read from and write errors on. + * @param major The required major type. + * @return True if the item is that type. + */ +WS_DLL_PUBLIC +gboolean wscbor_require_major_type(wscbor_chunk_t *chunk, cbor_type major); + +/** Require an array item. + * + * @param[in,out] chunk The chunk to read from and write errors on. + * @return True if the item is an array. + */ +WS_DLL_PUBLIC +gboolean wscbor_require_array(wscbor_chunk_t *chunk); + +/** Require an array have a specific ranged size. + * + * @param[in,out] chunk The chunk to read from and write errors on. + * @param count_min The minimum acceptable size. + * @param count_max The maximum acceptable size. + * @return True if the size is acceptable. + */ +WS_DLL_PUBLIC +gboolean wscbor_require_array_size(wscbor_chunk_t *chunk, guint64 count_min, guint64 count_max); + +/** Require a map item. + * + * @param[in,out] chunk The chunk to read from and write errors on. + * @return True if the item is a map. + */ +WS_DLL_PUBLIC +gboolean wscbor_require_map(wscbor_chunk_t *chunk); + +/** Require a CBOR item to have a boolean value. + * + * @param alloc The allocator to use. + * @param[in,out] chunk The chunk to read from and write errors on. + * @return Pointer to the boolean value, if the item was boolean. + * The value can be deleted with wscbor_require_delete(). + */ +WS_DLL_PUBLIC +gboolean * wscbor_require_boolean(wmem_allocator_t *alloc, wscbor_chunk_t *chunk); + +/** Require a CBOR item to have an unsigned-integer value. + * @note This reader will clip the most significant bit of the value. + * + * @param alloc The allocator to use. + * @param[in,out] chunk The chunk to read from and write errors on. + * @return Pointer to the boolean value, if the item was an integer. + * The value can be deleted with wscbor_require_delete(). + */ +WS_DLL_PUBLIC +guint64 * wscbor_require_uint64(wmem_allocator_t *alloc, wscbor_chunk_t *chunk); + +/** Require a CBOR item to have an signed- or unsigned-integer value. + * @note This reader will clip the most significant bit of the value. + * + * @param alloc The allocator to use. + * @param[in,out] chunk The chunk to read from and write errors on. + * @return Pointer to the value, if the item was an integer. + * The value can be deleted with wscbor_require_delete(). + */ +WS_DLL_PUBLIC +gint64 * wscbor_require_int64(wmem_allocator_t *alloc, wscbor_chunk_t *chunk); + +/** Require a CBOR item to have a text-string value. + * If the actual text string is not needed, use the following to avoid an + * unnecessary allocation. + * @code + * wscbor_require_major_type(chunk, CBOR_TYPE_STRING) + * @endcode + * + * @param alloc The allocator to use. + * @param[in,out] chunk The chunk to read from and write errors on. + * @return Pointer to the null-terminated UTF-8, if the item was a tstr. + * @post This can throw ContainedBoundsError string ran out of data. + */ +WS_DLL_PUBLIC +char * wscbor_require_tstr(wmem_allocator_t *alloc, wscbor_chunk_t *chunk); + +/** Require a CBOR item to have a byte-string value. + * Use tvb_memdup() or similar if the raw byte-string is needed. + * + * @param alloc The allocator to use. + * @param[in,out] chunk The chunk to read from and write errors on. + * @return Pointer to the value, if the item was an bstr. + * The value is memory managed by wireshark. + */ +WS_DLL_PUBLIC +tvbuff_t * wscbor_require_bstr(wmem_allocator_t *alloc, wscbor_chunk_t *chunk); + +/** Add an item representing an array or map container. + * If the item is type FT_UINT* or FT_INT* the count of (array) items + * or map (pairs) is used as the iterm value. + */ +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_container(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk); + +/** Add an item representing a non-boolean, non-float control value. + */ +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_ctrl(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk); + +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_boolean(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk, const gboolean *value); + +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_uint64(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk, const guint64 *value); + +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_int64(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk, const gint64 *value); + +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_bitmask(proto_tree *tree, int hfindex, const gint ett, int *const *fields, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk, const guint64 *value); + +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_tstr(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk); + +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_bstr(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk); + +/** Add an item representing the length of a bstr or tstr value. + */ +WS_DLL_PUBLIC +proto_item * proto_tree_add_cbor_strlen(proto_tree *tree, int hfindex, packet_info *pinfo, tvbuff_t *tvb, const wscbor_chunk_t *chunk); + +#ifdef __cplusplus +} +#endif + +#endif /* __WSCBOR_H__ */ |