diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:53 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:53 +0000 |
commit | a86c5f7cae7ec9a3398300555a0b644689d946a1 (patch) | |
tree | 39fe4b107c71174fd1e8a8ceb9a4d2aa14116248 /epan/dissectors/packet-thrift.c | |
parent | Releasing progress-linux version 4.2.6-1~progress7.99u1. (diff) | |
download | wireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.tar.xz wireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.zip |
Merging upstream version 4.4.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-thrift.c')
-rw-r--r-- | epan/dissectors/packet-thrift.c | 930 |
1 files changed, 595 insertions, 335 deletions
diff --git a/epan/dissectors/packet-thrift.c b/epan/dissectors/packet-thrift.c index a620fc7f..c5899098 100644 --- a/epan/dissectors/packet-thrift.c +++ b/epan/dissectors/packet-thrift.c @@ -7,7 +7,7 @@ * * Copyright 2015, Anders Broman <anders.broman[at]ericsson.com> * Copyright 2021, Richard van der Hoff <richard[at]matrix.org> - * Copyright 2019-2021, Triton Circonflexe <triton[at]kumal.info> + * Copyright 2019-2024, Triton Circonflexe <triton[at]kumal.info> * * Wireshark - Network traffic analyzer * By Gerald Combs <gerald@wireshark.org> @@ -71,12 +71,12 @@ void proto_reg_handoff_thrift(void); static dissector_handle_t thrift_handle; static dissector_handle_t thrift_http_handle; -static gboolean framed_desegment = TRUE; -static guint thrift_tls_port = 0; +static bool framed_desegment = true; +static unsigned thrift_tls_port; -static gboolean show_internal_thrift_fields = FALSE; -static gboolean try_generic_if_sub_dissector_fails = FALSE; -static guint nested_type_depth = 25; +static bool show_internal_thrift_fields; +static bool try_generic_if_sub_dissector_fails; +static unsigned nested_type_depth = 25; static dissector_table_t thrift_method_name_dissector_table; @@ -110,7 +110,7 @@ static const int TBP_THRIFT_LINEAR_LEN = 5; /* Elements type + number of element * - T_I8 * - T_DOUBLE (endianness is inverted, though) */ -static const int TCP_THRIFT_DELTA_NOT_SET = 0; +static const int TCP_THRIFT_DELTA_NOT_SET; static const int TCP_THRIFT_LENGTH_LARGER = 0xf; static const int TCP_THRIFT_MAP_TYPES_LEN = 1; /* High nibble = key type, low nibble = value type. */ static const int TCP_THRIFT_NIBBLE_SHIFT = 4; @@ -124,79 +124,79 @@ static const int TCP_THRIFT_MIN_VARINT_LEN = 1; static const int TCP_THRIFT_STRUCT_LEN = 1; /* Empty struct still contains T_STOP. */ static const int TCP_THRIFT_MIN_MESSAGE_LEN = 5; /* Protocol id + (Method type + Version) + Name length [+ Name] + Sequence Identifier + T_STOP */ -static const guint32 TCP_THRIFT_NIBBLE_MASK = 0xf; +static const uint32_t TCP_THRIFT_NIBBLE_MASK = 0xf; static const int OCTETS_TO_BITS_SHIFT = 3; /* 8 bits per octets = 3 shifts left. */ static const int DISABLE_SUBTREE = -1; -static int proto_thrift = -1; -static int hf_thrift_frame_length = -1; -static int hf_thrift_protocol_id = -1; -static int hf_thrift_version = -1; -static int hf_thrift_mtype = -1; -static int hf_thrift_str_len = -1; -static int hf_thrift_method = -1; -static int hf_thrift_seq_id = -1; -static int hf_thrift_type = -1; -static int hf_thrift_key_type = -1; -static int hf_thrift_value_type = -1; -static int hf_thrift_compact_struct_type = -1; -static int hf_thrift_fid = -1; -static int hf_thrift_fid_delta = -1; -static int hf_thrift_bool = -1; -static int hf_thrift_i8 = -1; -static int hf_thrift_i16 = -1; -static int hf_thrift_i32 = -1; -static int hf_thrift_i64 = -1; -static int hf_thrift_uuid = -1; -static int hf_thrift_binary = -1; -static int hf_thrift_string = -1; -static int hf_thrift_struct = -1; -static int hf_thrift_list = -1; -static int hf_thrift_set = -1; -static int hf_thrift_map = -1; -static int hf_thrift_num_list_item = -1; -static int hf_thrift_num_list_pos = -1; -static int hf_thrift_num_set_item = -1; -static int hf_thrift_num_set_pos = -1; -static int hf_thrift_num_map_item = -1; -static int hf_thrift_large_container = -1; -static int hf_thrift_double = -1; -static int hf_thrift_exception = -1; -static int hf_thrift_exception_message = -1; -static int hf_thrift_exception_type = -1; - -static int ett_thrift = -1; -static int ett_thrift_header = -1; -static int ett_thrift_params = -1; -static int ett_thrift_field = -1; -static int ett_thrift_struct = -1; -static int ett_thrift_list = -1; -static int ett_thrift_set = -1; -static int ett_thrift_map = -1; -static int ett_thrift_error = -1; /* Error while reading the header. */ -static int ett_thrift_exception = -1; /* ME_THRIFT_T_EXCEPTION */ - -static expert_field ei_thrift_wrong_type = EI_INIT; -static expert_field ei_thrift_wrong_field_id = EI_INIT; -static expert_field ei_thrift_negative_length = EI_INIT; -static expert_field ei_thrift_wrong_proto_version = EI_INIT; -static expert_field ei_thrift_struct_fid_not_in_seq = EI_INIT; -static expert_field ei_thrift_frame_too_short = EI_INIT; -static expert_field ei_thrift_not_enough_data = EI_INIT; -static expert_field ei_thrift_frame_too_long = EI_INIT; -static expert_field ei_thrift_varint_too_large = EI_INIT; -static expert_field ei_thrift_undefined_field_id = EI_INIT; -static expert_field ei_thrift_negative_field_id = EI_INIT; -static expert_field ei_thrift_unordered_field_id = EI_INIT; -static expert_field ei_thrift_application_exception = EI_INIT; -static expert_field ei_thrift_protocol_exception = EI_INIT; -static expert_field ei_thrift_too_many_subtypes = EI_INIT; +static int proto_thrift; +static int hf_thrift_frame_length; +static int hf_thrift_protocol_id; +static int hf_thrift_version; +static int hf_thrift_mtype; +static int hf_thrift_str_len; +static int hf_thrift_method; +static int hf_thrift_seq_id; +static int hf_thrift_type; +static int hf_thrift_key_type; +static int hf_thrift_value_type; +static int hf_thrift_compact_struct_type; +static int hf_thrift_fid; +static int hf_thrift_fid_delta; +static int hf_thrift_bool; +static int hf_thrift_i8; +static int hf_thrift_i16; +static int hf_thrift_i32; +static int hf_thrift_i64; +static int hf_thrift_uuid; +static int hf_thrift_binary; +static int hf_thrift_string; +static int hf_thrift_struct; +static int hf_thrift_list; +static int hf_thrift_set; +static int hf_thrift_map; +static int hf_thrift_num_list_item; +static int hf_thrift_num_list_pos; +static int hf_thrift_num_set_item; +static int hf_thrift_num_set_pos; +static int hf_thrift_num_map_item; +static int hf_thrift_large_container; +static int hf_thrift_double; +static int hf_thrift_exception; +static int hf_thrift_exception_message; +static int hf_thrift_exception_type; + +static int ett_thrift; +static int ett_thrift_header; +static int ett_thrift_params; +static int ett_thrift_field; +static int ett_thrift_struct; +static int ett_thrift_list; +static int ett_thrift_set; +static int ett_thrift_map; +static int ett_thrift_error; /* Error while reading the header. */ +static int ett_thrift_exception; /* ME_THRIFT_T_EXCEPTION */ + +static expert_field ei_thrift_wrong_type; +static expert_field ei_thrift_wrong_field_id; +static expert_field ei_thrift_negative_length; +static expert_field ei_thrift_wrong_proto_version; +static expert_field ei_thrift_struct_fid_not_in_seq; +static expert_field ei_thrift_frame_too_short; +static expert_field ei_thrift_not_enough_data; +static expert_field ei_thrift_frame_too_long; +static expert_field ei_thrift_varint_too_large; +static expert_field ei_thrift_undefined_field_id; +static expert_field ei_thrift_negative_field_id; +static expert_field ei_thrift_unordered_field_id; +static expert_field ei_thrift_application_exception; +static expert_field ei_thrift_protocol_exception; +static expert_field ei_thrift_too_many_subtypes; static const thrift_member_t thrift_exception[] = { - { &hf_thrift_exception_message, 1, TRUE, DE_THRIFT_T_BINARY, NULL, { .encoding = ENC_UTF_8|ENC_NA } }, - { &hf_thrift_exception_type, 2, FALSE, DE_THRIFT_T_I32, TMFILL }, - { NULL, 0, FALSE, DE_THRIFT_T_STOP, TMFILL } + { &hf_thrift_exception_message, 1, true, DE_THRIFT_T_BINARY, NULL, { .encoding = ENC_UTF_8 }, NULL }, + { &hf_thrift_exception_type, 2, false, DE_THRIFT_T_I32, TMFILL }, + { NULL, 0, false, DE_THRIFT_T_STOP, TMFILL } }; typedef enum { @@ -222,7 +222,7 @@ typedef struct _thrift_field_header_t { thrift_compact_type_enum_t compact; } type; int type_offset; - gint64 field_id; + int64_t field_id; int fid_offset; int fid_length; proto_item *type_pi; @@ -305,7 +305,7 @@ static const value_string thrift_mtype_vals[] = { #define DECODE_BINARY_AS_UTF32BE 6 #define DECODE_BINARY_AS_UTF32LE 7 -static gint32 binary_decode = DECODE_BINARY_AS_AUTO_UTF8; +static int32_t binary_decode = DECODE_BINARY_AS_AUTO_UTF8; static const enum_val_t binary_display_options[] = { { "auto", "UTF-8 if printable", DECODE_BINARY_AS_AUTO_UTF8 }, @@ -321,49 +321,49 @@ static const enum_val_t binary_display_options[] = { static int dissect_thrift_binary_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt, proto_tree *header_tree, int type, proto_item *type_pi); static int dissect_thrift_compact_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt, proto_tree *header_tree, int type, proto_item *type_pi); -static int dissect_thrift_t_struct_expert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, gint ett_id, const thrift_member_t *seq, expert_field* ei); +static int dissect_thrift_t_struct_expert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, int ett_id, const thrift_member_t *seq, expert_field* ei); /*=====BEGIN GENERIC HELPERS=====*/ /* Check that the 4-byte value match a Thrift Strict TBinaryProtocol version * - 0x8001 The version itself * - 0x?? An undetermined byte (not used) * - 0x0m The method type between 1 and 4. - * Values above 4 will be accepted if ignore_msg_type is TRUE. + * Values above 4 will be accepted if ignore_msg_type is true. */ -static gboolean -is_thrift_strict_version(guint32 header, gboolean ignore_msg_type) +static bool +is_thrift_strict_version(uint32_t header, bool ignore_msg_type) { int msg_type; if ((header & THRIFT_BINARY_VERSION_MASK) == THRIFT_BINARY_VERSION_1) { if (ignore_msg_type) { - return TRUE; + return true; } msg_type = (header & THRIFT_BINARY_MESSAGE_MASK); if ((ME_THRIFT_T_CALL <= msg_type) && (msg_type <= ME_THRIFT_T_ONEWAY)) { - return TRUE; + return true; } } - return FALSE; + return false; } /* Check that the 2-byte value match a Thrift TCompactProtocol version * - 0x82 The protocol id. * - 0bmmmvvvvv The method on the 3 MSbits and version on the 5 LSbits. */ -static gboolean -is_thrift_compact_version(guint16 header, gboolean ignore_msg_type) +static bool +is_thrift_compact_version(uint16_t header, bool ignore_msg_type) { int msg_type; if ((header & THRIFT_COMPACT_VERSION_MASK) == THRIFT_COMPACT_VERSION_1) { if (ignore_msg_type) { - return TRUE; + return true; } msg_type = (header & THRIFT_COMPACT_MESSAGE_MASK) >> THRIFT_COMPACT_MESSAGE_SHIFT; if ((ME_THRIFT_T_CALL <= msg_type) && (msg_type <= ME_THRIFT_T_ONEWAY)) { - return TRUE; + return true; } } - return FALSE; + return false; } /* @@ -376,18 +376,18 @@ is_thrift_compact_version(guint16 header, gboolean ignore_msg_type) * - Check UTF-8 vs. binary before adding to tree must check for reported length. */ static int -thrift_binary_utf8_isprint(tvbuff_t *tvb, int offset, int max_len, gboolean accept_crlf) +thrift_binary_utf8_isprint(tvbuff_t *tvb, int offset, int max_len, bool accept_crlf) { int check_len = tvb_reported_length_remaining(tvb, offset); int pos, remaining = 0; /* position in tvb, remaining bytes for multi-byte characters. */ - guint8 min_next = 0x80, max_next = 0xBF; - gboolean ended = FALSE; + uint8_t min_next = 0x80, max_next = 0xBF; + bool ended = false; int printable_len = 0; /* In case the string ends with several NUL bytes. */ if (max_len < check_len) { check_len = max_len; } for (pos = offset; pos < offset + check_len; pos++) { - guint8 current = tvb_get_guint8(tvb, pos); + uint8_t current = tvb_get_uint8(tvb, pos); if (ended) { if (current != 0) { return -1; @@ -395,7 +395,7 @@ thrift_binary_utf8_isprint(tvbuff_t *tvb, int offset, int max_len, gboolean acce } else if (remaining == 0) { /* We are at the beginning of a character. */ if (current == 0) { - ended = TRUE; + ended = true; continue; /* Avoid counting this NUL byte as printable. */ } else if ((current & 0x80) == 0) { if (!g_ascii_isprint(current)) { @@ -474,9 +474,9 @@ thrift_binary_utf8_isprint(tvbuff_t *tvb, int offset, int max_len, gboolean acce * a positive value indicating the length of the varint otherwise. */ static int -thrift_get_varint_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int max_length, guint64 *value, const guint encoding) +thrift_get_varint_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int max_length, uint64_t *value, const unsigned encoding) { - guint length; + unsigned length; int readable = tvb_reported_length_remaining(tvb, offset); if (readable <= 0) { return THRIFT_REQUEST_REASSEMBLY; @@ -497,7 +497,7 @@ thrift_get_varint_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o return length; } -static gboolean +static bool is_thrift_compact_bool_type(thrift_compact_type_enum_t type) { return type == DE_THRIFT_C_BOOL_TRUE || type == DE_THRIFT_C_BOOL_FALSE; @@ -509,7 +509,7 @@ is_thrift_compact_bool_type(thrift_compact_type_enum_t type) * @param[in] pinfo: Pointer to the packet_info holding information about the currently dissected packet. * @param[in] tree: Pointer to the proto_tree used to hold the display tree in Wireshark's interface. * The caller may set it to NULL to prevent the creation of the field header sub-tree. - * This possibility is used by sub-dissector when show_internal_thrift_fields is FALSE, + * This possibility is used by sub-dissector when show_internal_thrift_fields is false, * and by dissect_thrift_common to differentiate between successful and exception T_REPLY. * @param[in] offset: Offset from the beginning of the tvbuff_t where the Thrift field is. Function will dissect type, id, & data. * @param[in] thrift_opt: Options from the Thrift dissector that will be necessary for sub-dissection (binary vs. compact, ...) @@ -518,7 +518,7 @@ is_thrift_compact_bool_type(thrift_compact_type_enum_t type) * @return See "GENERIC DISSECTION PARAMETERS DOCUMENTATION". */ static int -dissect_thrift_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt, thrift_field_header_t *header, gboolean gen_bool) +dissect_thrift_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt, thrift_field_header_t *header, bool gen_bool) { /* * Binary protocol field header (3 bytes): @@ -552,9 +552,9 @@ dissect_thrift_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ABORT_SUBDISSECTION_ON_ISSUE(*offset); /* In case of sub-dissection functions. */ ABORT_ON_INCOMPLETE_PDU(TBP_THRIFT_TYPE_LEN); /* In all dissection cases. */ - guint8 dfid_type = tvb_get_guint8(tvb, *offset); - gint32 delta = TCP_THRIFT_DELTA_NOT_SET; - gint64 fid = 0; + uint8_t dfid_type = tvb_get_uint8(tvb, *offset); + int32_t delta = TCP_THRIFT_DELTA_NOT_SET; + int64_t fid = 0; memset(header, 0, sizeof(thrift_field_header_t)); @@ -605,7 +605,7 @@ dissect_thrift_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, /* Create the field header sub-tree if requested only. */ if (tree != NULL) { - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); if (nested_count >= thrift_opt->nested_type_depth) { expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_thrift_too_many_subtypes); return THRIFT_REQUEST_REASSEMBLY; @@ -623,6 +623,10 @@ dissect_thrift_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *bool_item = proto_tree_add_boolean(tree, hf_thrift_bool, tvb, header->type_offset, TBP_THRIFT_TYPE_LEN, 2 - header->type.compact); proto_item_set_generated(bool_item); } + if (gen_bool && is_thrift_compact_bool_type(header->type.compact)) { + proto_item *bool_item = proto_tree_add_boolean(tree, hf_thrift_bool, tvb, header->type_offset, TBP_THRIFT_TYPE_LEN, 2 - header->type.compact); + proto_item_set_generated(bool_item); + } } else { header->type_pi = proto_tree_add_item(header->fh_tree, hf_thrift_type, tvb, header->type_offset, TBP_THRIFT_TYPE_LEN, ENC_BIG_ENDIAN); } @@ -635,12 +639,12 @@ dissect_thrift_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, return THRIFT_REQUEST_REASSEMBLY; } } else { - if ((gint64)INT16_MIN > header->field_id || header->field_id > (gint64)INT16_MAX) { + if ((int64_t)INT16_MIN > header->field_id || header->field_id > (int64_t)INT16_MAX) { header->fid_pi = proto_tree_add_int64(header->fh_tree, hf_thrift_i64, tvb, header->fid_offset, header->fid_length, header->field_id); expert_add_info(pinfo, header->fid_pi, &ei_thrift_varint_too_large); /* We continue anyway as the field id was displayed successfully. */ } else { - header->fid_pi = proto_tree_add_int(header->fh_tree, hf_thrift_fid, tvb, header->fid_offset, header->fid_length, (gint16)header->field_id); + header->fid_pi = proto_tree_add_int(header->fh_tree, hf_thrift_fid, tvb, header->fid_offset, header->fid_length, (int16_t)header->field_id); } proto_item_set_generated(header->fid_pi); } @@ -657,10 +661,27 @@ dissect_thrift_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, expert_add_info(pinfo, header->fid_pi, &ei_thrift_unordered_field_id); } } - } else if (header->fid_length <= 0) { - /* Varint for field id was too long to decode, handle the error without the sub-tree. */ - proto_tree_add_expert(tree, pinfo, &ei_thrift_varint_too_large, tvb, header->fid_offset, TCP_THRIFT_MAX_I16_LEN); - return THRIFT_REQUEST_REASSEMBLY; + } else { + /* The fid_pi value (proto_item for field_id) is required for sub-dissectors. + * Create it even in the absence of tree. */ + if (delta == TCP_THRIFT_DELTA_NOT_SET) { + if (header->fid_length > 0) { + header->fid_pi = proto_tree_add_item(header->fh_tree, hf_thrift_fid, tvb, header->fid_offset, header->fid_length, ENC_BIG_ENDIAN); + } else { + /* Varint for field id was too long to decode, handle the error without the sub-tree. */ + proto_tree_add_expert(tree, pinfo, &ei_thrift_varint_too_large, tvb, header->fid_offset, TCP_THRIFT_MAX_I16_LEN); + return THRIFT_REQUEST_REASSEMBLY; + } + } else { + if ((int64_t)INT16_MIN > header->field_id || header->field_id > (int64_t)INT16_MAX) { + header->fid_pi = proto_tree_add_int64(header->fh_tree, hf_thrift_i64, tvb, header->fid_offset, header->fid_length, header->field_id); + expert_add_info(pinfo, header->fid_pi, &ei_thrift_varint_too_large); + /* We continue anyway as the field id was displayed successfully. */ + } else { + header->fid_pi = proto_tree_add_int(header->fh_tree, hf_thrift_fid, tvb, header->fid_offset, header->fid_length, (int16_t)header->field_id); + } + proto_item_set_generated(header->fid_pi); + } } return *offset; @@ -682,13 +703,14 @@ dissect_thrift_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, * @param[in] hf_id: The hf_id that needs to be used for the display. * If the found integer is larger that the expected integer size (driven by max_length parameter), * the integer will always be displayed as a generic T_I64 and an expert info will be added. + * @param[in] raw_dissector Dissector for raw integer (we need to create a tvbuff_t with the flatten integer. * * @return See "GENERIC DISSECTION PARAMETERS DOCUMENTATION". */ static int -dissect_thrift_varint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt, int max_length, int hf_id) +dissect_thrift_varint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt, int max_length, int hf_id, dissector_t raw_dissector) { - gint64 varint; + int64_t varint; proto_item *pi; int length = thrift_get_varint_enc(tvb, pinfo, tree, *offset, max_length, &varint, ENC_VARINT_ZIGZAG); switch (length) { @@ -702,26 +724,64 @@ dissect_thrift_varint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int * default: switch (max_length) { case TCP_THRIFT_MAX_I16_LEN: - if ((gint64)INT16_MIN > varint || varint > (gint64)INT16_MAX) { + if ((int64_t)INT16_MIN > varint || varint > (int64_t)INT16_MAX) { pi = proto_tree_add_int64(tree, hf_thrift_i64, tvb, *offset, length, varint); expert_add_info(pinfo, pi, &ei_thrift_varint_too_large); /* We continue anyway as the varint was indeed decoded. */ } else { - proto_tree_add_int(tree, hf_id, tvb, *offset, length, (gint16)varint); + if (raw_dissector != NULL) { + uint8_t *data = wmem_alloc(wmem_packet_scope(), TBP_THRIFT_I16_LEN); + data[0] = (varint >> 8) & 0xFF; + data[1] = varint & 0xFF; + tvbuff_t* sub_tvb = tvb_new_child_real_data(tvb, data, TBP_THRIFT_I16_LEN, TBP_THRIFT_I16_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_int(tree, hf_id, tvb, *offset, length, (int16_t)varint); + } } break; case TCP_THRIFT_MAX_I32_LEN: - if ((gint64)INT32_MIN > varint || varint > (gint64)INT32_MAX) { + if ((int64_t)INT32_MIN > varint || varint > (int64_t)INT32_MAX) { pi = proto_tree_add_int64(tree, hf_thrift_i64, tvb, *offset, length, varint); expert_add_info(pinfo, pi, &ei_thrift_varint_too_large); /* We continue anyway as the varint was indeed decoded. */ } else { - proto_tree_add_int(tree, hf_id, tvb, *offset, length, (gint32)varint); + if (raw_dissector != NULL) { + uint8_t *data = wmem_alloc(wmem_packet_scope(), TBP_THRIFT_I32_LEN); + data[0] = (varint >> 24) & 0xFF; + data[1] = (varint >> 16) & 0xFF; + data[2] = (varint >> 8) & 0xFF; + data[3] = varint & 0xFF; + tvbuff_t* sub_tvb = tvb_new_child_real_data(tvb, data, TBP_THRIFT_I32_LEN, TBP_THRIFT_I32_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_int(tree, hf_id, tvb, *offset, length, (int32_t)varint); + } } break; case TCP_THRIFT_MAX_I64_LEN: default: - proto_tree_add_int64(tree, hf_id, tvb, *offset, length, varint); + if (raw_dissector != NULL) { + uint8_t *data = wmem_alloc(wmem_packet_scope(), TBP_THRIFT_I64_LEN); + data[0] = (varint >> 56) & 0xFF; + data[1] = (varint >> 48) & 0xFF; + data[2] = (varint >> 40) & 0xFF; + data[3] = (varint >> 32) & 0xFF; + data[4] = (varint >> 24) & 0xFF; + data[5] = (varint >> 16) & 0xFF; + data[6] = (varint >> 8) & 0xFF; + data[7] = varint & 0xFF; + tvbuff_t* sub_tvb = tvb_new_child_real_data(tvb, data, TBP_THRIFT_I64_LEN, TBP_THRIFT_I64_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_int64(tree, hf_id, tvb, *offset, length, varint); + } break; } *offset += length; @@ -764,7 +824,7 @@ dissect_thrift_string_as_preferred(tvbuff_t *tvb, packet_info *pinfo, proto_tree * but a buffer containing only NUL bytes is a binary. * If not entirely captured, consider it as a binary. */ if (tvb_captured_length_remaining(tvb, *offset) >= str_len && - (str_len == 0 || thrift_binary_utf8_isprint(tvb, *offset, str_len, TRUE) > 0)) { + (str_len == 0 || thrift_binary_utf8_isprint(tvb, *offset, str_len, true) > 0)) { proto_tree_add_item(tree, hf_thrift_string, tvb, *offset, str_len, ENC_UTF_8); break; } @@ -825,7 +885,7 @@ compact_struct_type_to_generic_type(thrift_compact_type_enum_t compact) * Helper functions to use within custom sub-dissectors. * * Behavior: - * 1. If is_field is TRUE, dissect the field header (field type + field id). + * 1. If is_field is true, dissect the field header (field type + field id). * 1.a. Check the type in the PDU against the expected one according to the call. * 2. If requested, add the type and field id to the tree (internal thrift fields). * 3. Dissect the value of the field. @@ -845,7 +905,7 @@ dissect_thrift_t_stop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o return THRIFT_REQUEST_REASSEMBLY; } - if (tvb_get_guint8(tvb, offset) != DE_THRIFT_T_STOP) { + if (tvb_get_uint8(tvb, offset) != DE_THRIFT_T_STOP) { proto_tree_add_expert(tree, pinfo, &ei_thrift_wrong_type, tvb, offset, TBP_THRIFT_TYPE_LEN); return THRIFT_SUBDISSECTOR_ERROR; } @@ -893,7 +953,7 @@ dissect_thrift_t_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre internal_tree = tree; } /* Read the entire field header using the dedicated function. */ - if (dissect_thrift_field_header(tvb, pinfo, internal_tree, &offset, thrift_opt, &field_header, FALSE) == THRIFT_REQUEST_REASSEMBLY) { + if (dissect_thrift_field_header(tvb, pinfo, internal_tree, &offset, thrift_opt, &field_header, false) == THRIFT_REQUEST_REASSEMBLY) { if (offset == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; } else { @@ -916,7 +976,7 @@ dissect_thrift_t_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre } /* Once we know it's the expected type (which is /not/ T_STOP), we can read the field id. */ - if (field_header.field_id != (gint64)field_id) { + if (field_header.field_id != (int64_t)field_id) { expert_add_info_format(pinfo, field_header.fid_pi, &ei_thrift_wrong_field_id, "Sub-dissector expects field id = %d, found %" PRId64 " instead.", field_id, field_header.field_id); } @@ -929,16 +989,17 @@ dissect_thrift_t_field_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre return offset; } -int -dissect_thrift_t_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) +static int +dissect_thrift_raw_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, dissector_t raw_dissector) { int dt_offset = offset; - gboolean bool_val = FALSE; + bool bool_val = false; /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); ABORT_SUBDISSECTION_ON_ISSUE(offset); + thrift_opt->use_std_dissector = true; if (is_field) { /* In case of Compact protocol struct field (or command parameter / return value), * the boolean type also indicates the boolean value. */ @@ -947,8 +1008,8 @@ dissect_thrift_t_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_TYPE_LEN) { return THRIFT_REQUEST_REASSEMBLY; } - if (((tvb_get_guint8(tvb, offset) >> TCP_THRIFT_NIBBLE_SHIFT) & TCP_THRIFT_NIBBLE_MASK) == DE_THRIFT_C_BOOL_TRUE) { - bool_val = TRUE; + if (((tvb_get_uint8(tvb, offset) >> TCP_THRIFT_NIBBLE_SHIFT) & TCP_THRIFT_NIBBLE_MASK) == DE_THRIFT_C_BOOL_TRUE) { + bool_val = true; } /* If we have neither DE_THRIFT_C_BOOL_TRUE nor DE_THRIFT_C_BOOL_FALSE as the type, * dissect_thrift_t_field_header will catch the issue anyway. */ @@ -956,9 +1017,17 @@ dissect_thrift_t_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o offset = dissect_thrift_t_field_header(tvb, pinfo, tree, offset, thrift_opt, DE_THRIFT_T_BOOL, field_id, NULL); ABORT_SUBDISSECTION_ON_ISSUE(offset); if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { - /* The value must be in the top-level tree, /after/ the field header tree. */ - proto_item *pi = proto_tree_add_boolean(tree, hf_id, tvb, dt_offset, TBP_THRIFT_TYPE_LEN, bool_val); - proto_item_set_generated(pi); + /* It is the responsibility of the sub-dissector to only use the least significant bit. */ + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, offset, TBP_THRIFT_BOOL_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + /* The value must be in the top-level tree, /after/ the field header tree. */ + proto_item *pi = proto_tree_add_boolean(tree, hf_id, tvb, dt_offset, TBP_THRIFT_TYPE_LEN, bool_val); + proto_item_set_generated(pi); + } return offset; } } @@ -967,7 +1036,14 @@ dissect_thrift_t_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o } /* Either in a list/set/map or in a Binary protocol encoding. */ - proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_BOOL_LEN, ENC_BIG_ENDIAN); + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, offset, TBP_THRIFT_BOOL_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_BOOL_LEN, ENC_BIG_ENDIAN); + } offset += TBP_THRIFT_BOOL_LEN; if (is_field) { @@ -977,7 +1053,15 @@ dissect_thrift_t_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o } int -dissect_thrift_t_i8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) +dissect_thrift_t_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_bool(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, NULL); +} + +static int +dissect_thrift_raw_i8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, dissector_t raw_dissector) { /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -991,8 +1075,16 @@ dissect_thrift_t_i8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int off return THRIFT_REQUEST_REASSEMBLY; } + thrift_opt->use_std_dissector = true; /* Compact protocol does not use varint for T_I8 as it would be counter-productive. */ - proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_I8_LEN, ENC_BIG_ENDIAN); + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, offset, TBP_THRIFT_I8_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_I8_LEN, ENC_BIG_ENDIAN); + } offset += TBP_THRIFT_I8_LEN; if (is_field) { @@ -1002,7 +1094,15 @@ dissect_thrift_t_i8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int off } int -dissect_thrift_t_i16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) +dissect_thrift_t_i8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_i8(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, NULL); +} + +static int +dissect_thrift_raw_i16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, dissector_t raw_dissector) { /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -1012,8 +1112,9 @@ dissect_thrift_t_i16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of offset = dissect_thrift_t_field_header(tvb, pinfo, tree, offset, thrift_opt, DE_THRIFT_T_I16, field_id, NULL); } ABORT_SUBDISSECTION_ON_ISSUE(offset); + thrift_opt->use_std_dissector = true; if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { - int result = dissect_thrift_varint(tvb, pinfo, tree, &offset, thrift_opt, TCP_THRIFT_MAX_I16_LEN, hf_id); + int result = dissect_thrift_varint(tvb, pinfo, tree, &offset, thrift_opt, TCP_THRIFT_MAX_I16_LEN, hf_id, raw_dissector); if (result == THRIFT_REQUEST_REASSEMBLY) { if (offset == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; @@ -1024,7 +1125,14 @@ dissect_thrift_t_i16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of } else if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_I16_LEN) { return THRIFT_REQUEST_REASSEMBLY; } else { - proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_I16_LEN, ENC_BIG_ENDIAN); + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, offset, TBP_THRIFT_I16_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_I16_LEN, ENC_BIG_ENDIAN); + } offset += TBP_THRIFT_I16_LEN; } @@ -1035,7 +1143,15 @@ dissect_thrift_t_i16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of } int -dissect_thrift_t_i32(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) +dissect_thrift_t_i16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_i16(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, NULL); +} + +static int +dissect_thrift_raw_i32(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, dissector_t raw_dissector) { /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -1045,8 +1161,9 @@ dissect_thrift_t_i32(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of offset = dissect_thrift_t_field_header(tvb, pinfo, tree, offset, thrift_opt, DE_THRIFT_T_I32, field_id, NULL); } ABORT_SUBDISSECTION_ON_ISSUE(offset); + thrift_opt->use_std_dissector = true; if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { - int result = dissect_thrift_varint(tvb, pinfo, tree, &offset, thrift_opt, TCP_THRIFT_MAX_I32_LEN, hf_id); + int result = dissect_thrift_varint(tvb, pinfo, tree, &offset, thrift_opt, TCP_THRIFT_MAX_I32_LEN, hf_id, raw_dissector); if (result == THRIFT_REQUEST_REASSEMBLY) { if (offset == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; @@ -1057,7 +1174,14 @@ dissect_thrift_t_i32(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of } else if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_I32_LEN) { return THRIFT_REQUEST_REASSEMBLY; } else { - proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_I32_LEN, ENC_BIG_ENDIAN); + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, offset, TBP_THRIFT_I32_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_I32_LEN, ENC_BIG_ENDIAN); + } offset += TBP_THRIFT_I32_LEN; } @@ -1068,7 +1192,15 @@ dissect_thrift_t_i32(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of } int -dissect_thrift_t_i64(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) +dissect_thrift_t_i32(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_i32(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, NULL); +} + +static int +dissect_thrift_raw_i64(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, dissector_t raw_dissector) { /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -1078,8 +1210,9 @@ dissect_thrift_t_i64(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of offset = dissect_thrift_t_field_header(tvb, pinfo, tree, offset, thrift_opt, DE_THRIFT_T_I64, field_id, NULL); } ABORT_SUBDISSECTION_ON_ISSUE(offset); + thrift_opt->use_std_dissector = true; if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { - int result = dissect_thrift_varint(tvb, pinfo, tree, &offset, thrift_opt, TCP_THRIFT_MAX_I64_LEN, hf_id); + int result = dissect_thrift_varint(tvb, pinfo, tree, &offset, thrift_opt, TCP_THRIFT_MAX_I64_LEN, hf_id, raw_dissector); if (result == THRIFT_REQUEST_REASSEMBLY) { if (offset == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; @@ -1090,7 +1223,14 @@ dissect_thrift_t_i64(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of } else if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_I64_LEN) { return THRIFT_REQUEST_REASSEMBLY; } else { - proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_I64_LEN, ENC_BIG_ENDIAN); + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, offset, TBP_THRIFT_I64_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_I64_LEN, ENC_BIG_ENDIAN); + } offset += TBP_THRIFT_I64_LEN; } @@ -1101,7 +1241,15 @@ dissect_thrift_t_i64(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of } int -dissect_thrift_t_double(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) +dissect_thrift_t_i64(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_i64(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, NULL); +} + +static int +dissect_thrift_raw_double(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, dissector_t raw_dissector) { /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -1115,10 +1263,33 @@ dissect_thrift_t_double(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int return THRIFT_REQUEST_REASSEMBLY; } - if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { - proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_DOUBLE_LEN, ENC_LITTLE_ENDIAN); - } else { - proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_DOUBLE_LEN, ENC_BIG_ENDIAN); + thrift_opt->use_std_dissector = true; + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb; + if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { + /* Create a sub-tvbuff_t in big endian format as documented. */ + uint8_t *data = wmem_alloc(wmem_packet_scope(), TBP_THRIFT_DOUBLE_LEN); + data[0] = tvb_get_uint8(tvb, offset + 7); + data[1] = tvb_get_uint8(tvb, offset + 6); + data[2] = tvb_get_uint8(tvb, offset + 5); + data[3] = tvb_get_uint8(tvb, offset + 4); + data[4] = tvb_get_uint8(tvb, offset + 3); + data[5] = tvb_get_uint8(tvb, offset + 2); + data[6] = tvb_get_uint8(tvb, offset + 1); + data[7] = tvb_get_uint8(tvb, offset); + sub_tvb = tvb_new_child_real_data(tvb, data, TBP_THRIFT_DOUBLE_LEN, TBP_THRIFT_DOUBLE_LEN); + } else { + sub_tvb = tvb_new_subset_length(tvb, offset, TBP_THRIFT_DOUBLE_LEN); + } + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { + proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_DOUBLE_LEN, ENC_LITTLE_ENDIAN); + } else { + proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_DOUBLE_LEN, ENC_BIG_ENDIAN); + } } offset += TBP_THRIFT_DOUBLE_LEN; @@ -1129,7 +1300,15 @@ dissect_thrift_t_double(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int } int -dissect_thrift_t_uuid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) +dissect_thrift_t_double(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_double(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, NULL); +} + +static int +dissect_thrift_raw_uuid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, dissector_t raw_dissector) { /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -1145,7 +1324,15 @@ dissect_thrift_t_uuid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o return THRIFT_REQUEST_REASSEMBLY; } - proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_UUID_LEN, ENC_BIG_ENDIAN); + thrift_opt->use_std_dissector = true; + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, offset, TBP_THRIFT_UUID_LEN); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_item(tree, hf_id, tvb, offset, TBP_THRIFT_UUID_LEN, ENC_BIG_ENDIAN); + } offset += TBP_THRIFT_UUID_LEN; if (is_field) { @@ -1155,19 +1342,15 @@ dissect_thrift_t_uuid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o } int -dissect_thrift_t_binary(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) +dissect_thrift_t_uuid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) { - return dissect_thrift_t_string_enc(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ENC_NA); -} - -int -dissect_thrift_t_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id) -{ - return dissect_thrift_t_string_enc(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ENC_UTF_8|ENC_NA); + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_uuid(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, NULL); } -int -dissect_thrift_t_string_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, guint encoding) +static int +dissect_thrift_raw_binary(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, unsigned encoding, dissector_t raw_dissector) { /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -1175,8 +1358,8 @@ dissect_thrift_t_string_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *header_tree = NULL; proto_item *len_item = NULL; - gint32 str_len, len_len; - gint64 varint; + int32_t str_len, len_len; + int64_t varint; /* Dissect field header if necessary. */ if (is_field) { @@ -1197,12 +1380,12 @@ dissect_thrift_t_string_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, default: break; } - if ((gint64)INT32_MIN > varint || varint > (gint64)INT32_MAX) { + if ((int64_t)INT32_MIN > varint || varint > (int64_t)INT32_MAX) { len_item = proto_tree_add_int64(header_tree, hf_thrift_i64, tvb, offset, len_len, varint); expert_add_info(pinfo, len_item, &ei_thrift_varint_too_large); return THRIFT_REQUEST_REASSEMBLY; } - str_len = (gint32)varint; + str_len = (int32_t)varint; if (show_internal_thrift_fields) { len_item = proto_tree_add_int(header_tree, hf_thrift_str_len, tvb, offset, len_len, str_len); } @@ -1232,7 +1415,15 @@ dissect_thrift_t_string_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, return THRIFT_REQUEST_REASSEMBLY; } - proto_tree_add_item(tree, hf_id, tvb, offset, str_len, encoding); + thrift_opt->use_std_dissector = true; + if (raw_dissector != NULL) { + tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, offset, str_len); + thrift_opt->use_std_dissector = false; + raw_dissector(sub_tvb, pinfo, tree, thrift_opt); + } + if (thrift_opt->use_std_dissector) { + proto_tree_add_item(tree, hf_id, tvb, offset, str_len, encoding); + } offset = offset + str_len; if (is_field) { @@ -1241,35 +1432,98 @@ dissect_thrift_t_string_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, return offset; } +int +dissect_thrift_t_binary(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_binary(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ENC_NA, NULL); +} + +int +dissect_thrift_t_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_binary(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ENC_UTF_8, NULL); +} + +int +dissect_thrift_t_string_enc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, unsigned encoding) +{ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + return dissect_thrift_raw_binary(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, encoding, NULL); +} + +int +dissect_thrift_t_raw_data(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset, thrift_option_data_t* thrift_opt, bool is_field, int field_id, int hf_id, thrift_type_enum_t type, dissector_t raw_dissector) +{ + /* Get the current state of dissection. */ + DISSECTOR_ASSERT(thrift_opt); + DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); + + switch (type) { + case DE_THRIFT_T_BOOL: + offset = dissect_thrift_raw_bool(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, raw_dissector); + break; + case DE_THRIFT_T_I8: + offset = dissect_thrift_raw_i8(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, raw_dissector); + break; + case DE_THRIFT_T_I16: + offset = dissect_thrift_raw_i16(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, raw_dissector); + break; + case DE_THRIFT_T_I32: + offset = dissect_thrift_raw_i32(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, raw_dissector); + break; + case DE_THRIFT_T_I64: + offset = dissect_thrift_raw_i64(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, raw_dissector); + break; + case DE_THRIFT_T_DOUBLE: + offset = dissect_thrift_raw_double(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, raw_dissector); + break; + case DE_THRIFT_T_BINARY: + offset = dissect_thrift_raw_binary(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ENC_NA, raw_dissector); + break; + case DE_THRIFT_T_UUID: + offset = dissect_thrift_raw_uuid(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, raw_dissector); + break; + default: + REPORT_DISSECTOR_BUG("Only simple data types support raw dissection."); + break; + } + return offset; +} + /* Simple dispatch function for lists, sets, maps, and structs internal elements to avoid code duplication. */ static int // NOLINTNEXTLINE(misc-no-recursion) -dissect_thrift_t_member(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, const thrift_member_t *elt) +dissect_thrift_t_member(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, const thrift_member_t *elt) { switch (elt->type) { case DE_THRIFT_T_STOP: offset = dissect_thrift_t_stop(tvb, pinfo, tree, offset); break; case DE_THRIFT_T_BOOL: - offset = dissect_thrift_t_bool(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id); + offset = dissect_thrift_raw_bool(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, elt->raw_dissector); break; case DE_THRIFT_T_I8: - offset = dissect_thrift_t_i8(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id); + offset = dissect_thrift_raw_i8(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, elt->raw_dissector); break; case DE_THRIFT_T_I16: - offset = dissect_thrift_t_i16(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id); + offset = dissect_thrift_raw_i16(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, elt->raw_dissector); break; case DE_THRIFT_T_I32: - offset = dissect_thrift_t_i32(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id); + offset = dissect_thrift_raw_i32(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, elt->raw_dissector); break; case DE_THRIFT_T_I64: - offset = dissect_thrift_t_i64(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id); + offset = dissect_thrift_raw_i64(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, elt->raw_dissector); break; case DE_THRIFT_T_DOUBLE: - offset = dissect_thrift_t_double(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id); + offset = dissect_thrift_raw_double(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, elt->raw_dissector); break; case DE_THRIFT_T_BINARY: - offset = dissect_thrift_t_string(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id); + offset = dissect_thrift_raw_binary(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, elt->u.encoding, elt->raw_dissector); break; case DE_THRIFT_T_LIST: offset = dissect_thrift_t_list(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, *elt->p_ett_id, elt->u.element); @@ -1284,7 +1538,7 @@ dissect_thrift_t_member(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset = dissect_thrift_t_struct_expert(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, *elt->p_ett_id, elt->u.s.members, elt->u.s.expert_info); break; case DE_THRIFT_T_UUID: - offset = dissect_thrift_t_uuid(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id); + offset = dissect_thrift_raw_uuid(tvb, pinfo, tree, offset, thrift_opt, is_field, elt->fid, *elt->p_hf_id, elt->raw_dissector); break; default: REPORT_DISSECTOR_BUG("Unexpected Thrift type dissection requested."); @@ -1301,14 +1555,14 @@ dissect_thrift_t_member(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int */ static int // NOLINTNEXTLINE(misc-no-recursion) -dissect_thrift_b_linear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, gint ett_id, const thrift_member_t *key, const thrift_member_t *val, thrift_type_enum_t expected) +dissect_thrift_b_linear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, int ett_id, const thrift_member_t *key, const thrift_member_t *val, thrift_type_enum_t expected) { proto_item *container_pi = NULL; proto_item *len_pi = NULL; proto_tree *sub_tree; - gint32 key_type, val_type; - gint32 length; - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + int32_t key_type, val_type; + int32_t length; + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -1335,7 +1589,7 @@ dissect_thrift_b_linear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_TYPE_LEN) { return THRIFT_REQUEST_REASSEMBLY; } - key_type = tvb_get_guint8(tvb, offset); + key_type = tvb_get_uint8(tvb, offset); if (show_internal_thrift_fields) { proto_tree_add_item(sub_tree, hf_thrift_type, tvb, offset, TBP_THRIFT_TYPE_LEN, ENC_BIG_ENDIAN); } @@ -1350,7 +1604,7 @@ dissect_thrift_b_linear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_TYPE_LEN) { return THRIFT_REQUEST_REASSEMBLY; } - val_type = tvb_get_guint8(tvb, offset); + val_type = tvb_get_uint8(tvb, offset); if (show_internal_thrift_fields) { proto_tree_add_item(sub_tree, hf_thrift_type, tvb, offset, TBP_THRIFT_TYPE_LEN, ENC_BIG_ENDIAN); } @@ -1366,7 +1620,7 @@ dissect_thrift_b_linear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int } length = tvb_get_ntohil(tvb, offset); if (show_internal_thrift_fields) { - gint hf_num_item; + int hf_num_item; switch (expected) { case DE_THRIFT_T_MAP: hf_num_item = hf_thrift_num_map_item; @@ -1391,9 +1645,9 @@ dissect_thrift_b_linear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int /* Read the content of the container. */ for(int i = 0; i < length; ++i) { if (expected == DE_THRIFT_T_MAP) { - offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, FALSE, key); + offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, false, key); } - offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, FALSE, val); + offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, false, val); /* Avoid continuing the loop if anything went sideways. */ ABORT_SUBDISSECTION_ON_ISSUE(offset); } @@ -1410,21 +1664,21 @@ dissect_thrift_b_linear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int */ static int // NOLINTNEXTLINE(misc-no-recursion) -dissect_thrift_c_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, gint ett_id, const thrift_member_t *elt, gboolean is_list) +dissect_thrift_c_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, int ett_id, const thrift_member_t *elt, bool is_list) { proto_item *container_pi; proto_item *type_pi = NULL; proto_item *len_pi = NULL; proto_tree *sub_tree = NULL; - guint32 len_type; + uint32_t len_type; thrift_compact_type_enum_t elt_type; - gint32 container_len, len_len, i; - guint64 varint; + int32_t container_len, len_len, i; + uint64_t varint; int lt_offset; int hf_num_item = hf_thrift_num_set_item; int hf_pos_item = hf_thrift_num_set_pos; thrift_type_enum_t expected = DE_THRIFT_T_SET; - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); if (is_list) { hf_num_item = hf_thrift_num_list_item; @@ -1457,7 +1711,7 @@ dissect_thrift_c_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i /* Read the type of the elements (and length if lower than 15). */ lt_offset = offset; - len_type = tvb_get_guint8(tvb, lt_offset); + len_type = tvb_get_uint8(tvb, lt_offset); offset += TBP_THRIFT_TYPE_LEN; elt_type = (thrift_compact_type_enum_t)(len_type & TCP_THRIFT_NIBBLE_MASK); if (show_internal_thrift_fields) { @@ -1487,12 +1741,12 @@ dissect_thrift_c_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i /* In case of error, the offset stay at the error position. */ return THRIFT_SUBDISSECTOR_ERROR; default: - if (varint > (guint64)INT32_MAX) { + if (varint > (uint64_t)INT32_MAX) { len_pi = proto_tree_add_int64(sub_tree, hf_thrift_i64, tvb, offset, len_len, varint); expert_add_info(pinfo, len_pi, &ei_thrift_varint_too_large); return THRIFT_SUBDISSECTOR_ERROR; } - container_len = (guint32)varint; + container_len = (uint32_t)varint; if (show_internal_thrift_fields) { proto_tree_add_int(sub_tree, hf_num_item, tvb, offset, len_len, container_len); } @@ -1505,7 +1759,7 @@ dissect_thrift_c_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i /* Read the content of the container. */ for (i = 0; i < container_len; ++i) { - offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, FALSE, elt); + offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, false, elt); /* Avoid continuing the loop if anything went sideways. */ ABORT_SUBDISSECTION_ON_ISSUE(offset); } @@ -1518,11 +1772,11 @@ dissect_thrift_c_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i int // NOLINTNEXTLINE(misc-no-recursion) -dissect_thrift_t_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, gint ett_id, const thrift_member_t *elt) +dissect_thrift_t_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, int ett_id, const thrift_member_t *elt) { int result; if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { - result = dissect_thrift_c_list_set(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ett_id, elt, TRUE); + result = dissect_thrift_c_list_set(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ett_id, elt, true); } else { result = dissect_thrift_b_linear(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ett_id, NULL, elt, DE_THRIFT_T_LIST); } @@ -1535,11 +1789,11 @@ dissect_thrift_t_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o int // NOLINTNEXTLINE(misc-no-recursion) -dissect_thrift_t_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, gint ett_id, const thrift_member_t *elt) +dissect_thrift_t_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, int ett_id, const thrift_member_t *elt) { int result; if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { - result = dissect_thrift_c_list_set(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ett_id, elt, FALSE); + result = dissect_thrift_c_list_set(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ett_id, elt, false); } else { result = dissect_thrift_b_linear(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ett_id, NULL, elt, DE_THRIFT_T_SET); } @@ -1552,7 +1806,7 @@ dissect_thrift_t_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of int // NOLINTNEXTLINE(misc-no-recursion) -dissect_thrift_t_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, gint ett_id, const thrift_member_t *key, const thrift_member_t *value) +dissect_thrift_t_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, int ett_id, const thrift_member_t *key, const thrift_member_t *value) { int result; /* Get the current state of dissection. */ @@ -1566,11 +1820,11 @@ dissect_thrift_t_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of proto_item *container_pi; proto_item *ktype_pi = NULL; proto_item *vtype_pi = NULL; - gint32 container_len, len_len, i, types; - gint32 len_offset = offset; + int32_t container_len, len_len, i, types; + int32_t len_offset = offset; thrift_compact_type_enum_t ktype, vtype; - guint64 varint; - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + uint64_t varint; + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); /* Dissect field header if necessary. */ if (is_field) { @@ -1592,12 +1846,12 @@ dissect_thrift_t_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of /* In case of error, the offset stay at the error position. */ return THRIFT_SUBDISSECTOR_ERROR; default: - if (varint > (guint64)INT32_MAX) { + if (varint > (uint64_t)INT32_MAX) { proto_item *len_pi = proto_tree_add_int64(sub_tree, hf_thrift_i64, tvb, offset, len_len, varint); expert_add_info(pinfo, len_pi, &ei_thrift_varint_too_large); return THRIFT_SUBDISSECTOR_ERROR; } - container_len = (guint32)varint; + container_len = (uint32_t)varint; offset += len_len; break; } @@ -1622,7 +1876,7 @@ dissect_thrift_t_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_TYPE_LEN) { return THRIFT_REQUEST_REASSEMBLY; } - types = tvb_get_guint8(tvb, offset); + types = tvb_get_uint8(tvb, offset); ktype = (thrift_compact_type_enum_t)((types >> TCP_THRIFT_NIBBLE_SHIFT) & TCP_THRIFT_NIBBLE_MASK); vtype = (thrift_compact_type_enum_t)(types & TCP_THRIFT_NIBBLE_MASK); if (show_internal_thrift_fields) { @@ -1651,8 +1905,8 @@ dissect_thrift_t_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of /* Read the content of the container. */ for (i = 0; i < container_len; ++i) { - offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, FALSE, key); - offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, FALSE, value); + offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, false, key); + offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, false, value); /* Avoid continuing the loop if anything went sideways. */ ABORT_SUBDISSECTION_ON_ISSUE(offset); } @@ -1671,21 +1925,21 @@ dissect_thrift_t_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of } int -dissect_thrift_t_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, gint ett_id, const thrift_member_t *seq) +dissect_thrift_t_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, int ett_id, const thrift_member_t *seq) { return dissect_thrift_t_struct_expert(tvb, pinfo, tree, offset, thrift_opt, is_field, field_id, hf_id, ett_id, seq, NULL); } static int // NOLINTNEXTLINE(misc-no-recursion) -dissect_thrift_t_struct_expert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, gboolean is_field, int field_id, gint hf_id, gint ett_id, const thrift_member_t *seq, expert_field* ei) +dissect_thrift_t_struct_expert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, thrift_option_data_t *thrift_opt, bool is_field, int field_id, int hf_id, int ett_id, const thrift_member_t *seq, expert_field* ei) { thrift_field_header_t field_header; proto_tree *sub_tree = NULL; proto_item *type_pi = NULL; - gboolean enable_subtree = (ett_id != DISABLE_SUBTREE) || (hf_id != DISABLE_SUBTREE); - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + bool enable_subtree = (ett_id != DISABLE_SUBTREE) || (hf_id != DISABLE_SUBTREE); + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -1727,7 +1981,7 @@ dissect_thrift_t_struct_expert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr * Never create the field header sub-tree here as it will be handled by the field's own dissector. * We only want to get the type & field id information to compare them against what we expect. */ - if (dissect_thrift_field_header(tvb, pinfo, NULL, &local_offset, thrift_opt, &field_header, FALSE) == THRIFT_REQUEST_REASSEMBLY) { + if (dissect_thrift_field_header(tvb, pinfo, NULL, &local_offset, thrift_opt, &field_header, false) == THRIFT_REQUEST_REASSEMBLY) { if (local_offset == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; } else { @@ -1760,12 +2014,12 @@ dissect_thrift_t_struct_expert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr if (seq->type != DE_THRIFT_T_GENERIC) { /* Type is not T_STOP and field id matches one we know how to dissect. */ - offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, TRUE, seq); + offset = dissect_thrift_t_member(tvb, pinfo, sub_tree, offset, thrift_opt, true, seq); } else { /* The field is not defined in the struct, switch back to generic dissection. * Re-read the header ensuring it is displayed (no need to check result, * we already dissected it but without the header tree creation. */ - dissect_thrift_field_header(tvb, pinfo, sub_tree, &offset, thrift_opt, &field_header, FALSE); + dissect_thrift_field_header(tvb, pinfo, sub_tree, &offset, thrift_opt, &field_header, false); expert_add_info(pinfo, field_header.fid_pi, &ei_thrift_undefined_field_id); // Then dissect just this field. if (thrift_opt->tprotocol & PROTO_THRIFT_COMPACT) { @@ -1862,7 +2116,7 @@ dissect_thrift_binary_binary(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree * In particular, it might be larger than the number * of characters in an UTF-8 string. */ - gint32 str_len; + int32_t str_len; proto_item *pi; ABORT_ON_INCOMPLETE_PDU(TBP_THRIFT_BINARY_LEN); if (header_tree == NULL) { @@ -1904,14 +2158,14 @@ dissect_thrift_binary_linear(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree proto_tree *sub_tree; proto_item *container_pi, *len_pi, *vtype_pi; proto_item *ktype_pi = NULL; // Avoid a false positive warning. - gint32 ktype, vtype; - gint32 container_len, i; - int ett = -1; - int hf_container = -1; - int hf_num_item = -1; + int32_t ktype, vtype; + int32_t container_len, i; + int ett = 0; + int hf_container = 0; + int hf_num_item = 0; int hf_vtype = hf_thrift_type; int min_len = TBP_THRIFT_LINEAR_LEN; - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); /* Set the different hf_id & ett depending on effective type. */ switch (expected) { @@ -2030,8 +2284,8 @@ dissect_thrift_binary_fields(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree }; thrift_opt->previous_field_id = 0; - while (TRUE) { - if (dissect_thrift_field_header(tvb, pinfo, tree, offset, thrift_opt, &field_header, TRUE) == THRIFT_REQUEST_REASSEMBLY) { + while (true) { + if (dissect_thrift_field_header(tvb, pinfo, tree, offset, thrift_opt, &field_header, true) == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; } if (field_header.type.binary == DE_THRIFT_T_STOP) { @@ -2054,7 +2308,7 @@ dissect_thrift_binary_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree */ proto_tree *sub_tree; proto_item *pi; - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); ABORT_ON_INCOMPLETE_PDU(TBP_THRIFT_STRUCT_LEN); if (nested_count >= thrift_opt->nested_type_depth) { @@ -2171,9 +2425,9 @@ dissect_thrift_compact_binary(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre * In particular, it might be larger than the number * of characters in an UTF-8 string. */ - gint32 str_len; + int32_t str_len; proto_item *pi; - gint64 varint; + int64_t varint; if (header_tree == NULL) { header_tree = tree; @@ -2195,12 +2449,12 @@ dissect_thrift_compact_binary(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre if (header_tree != tree) { proto_item_set_end(proto_tree_get_parent(header_tree), tvb, *offset); } - if ((gint64)INT32_MIN > varint || varint > (gint64)INT32_MAX) { + if ((int64_t)INT32_MIN > varint || varint > (int64_t)INT32_MAX) { pi = proto_tree_add_int64(header_tree, hf_thrift_i64, tvb, *offset, len_len, varint); expert_add_info(pinfo, pi, &ei_thrift_varint_too_large); return THRIFT_REQUEST_REASSEMBLY; } - str_len = (gint32)varint; + str_len = (int32_t)varint; pi = proto_tree_add_int(header_tree, hf_thrift_str_len, tvb, *offset, len_len, str_len); if (str_len < 0) { expert_add_info(pinfo, pi, &ei_thrift_negative_length); @@ -2212,7 +2466,7 @@ dissect_thrift_compact_binary(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre static int // NOLINTNEXTLINE(misc-no-recursion) -dissect_thrift_compact_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt, gboolean is_list) +dissect_thrift_compact_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt, bool is_list) { /* Compact protocol list/set (short form, 1 byte): * +--------+--------+...+--------+ @@ -2231,15 +2485,15 @@ dissect_thrift_compact_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t */ proto_tree *sub_tree; proto_item *container_pi, *type_pi, *len_pi; - guint32 len_type, type; - gint32 container_len, len_len, i; - guint64 varint; + uint32_t len_type, type; + int32_t container_len, len_len, i; + uint64_t varint; int lt_offset = *offset; int ett = ett_thrift_set; int hf_container = hf_thrift_set; int hf_num_item = hf_thrift_num_set_item; int hf_pos_item = hf_thrift_num_set_pos; - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); ABORT_ON_INCOMPLETE_PDU(TBP_THRIFT_TYPE_LEN); /* Set the different hf_id & ett depending on effective type. */ @@ -2260,7 +2514,7 @@ dissect_thrift_compact_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t sub_tree = proto_item_add_subtree(container_pi, ett); /* Read the type of the elements (and length if lower than 15). */ - len_type = tvb_get_guint8(tvb, lt_offset); + len_type = tvb_get_uint8(tvb, lt_offset); *offset += TBP_THRIFT_TYPE_LEN; type = len_type & TCP_THRIFT_NIBBLE_MASK; type_pi = proto_tree_add_bits_item(sub_tree, hf_thrift_type, tvb, (lt_offset << OCTETS_TO_BITS_SHIFT) + TCP_THRIFT_NIBBLE_SHIFT, TCP_THRIFT_NIBBLE_SHIFT, ENC_BIG_ENDIAN); @@ -2280,12 +2534,12 @@ dissect_thrift_compact_list_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t /* In case of error, the offset stay at the error position. */ return THRIFT_REQUEST_REASSEMBLY; default: - if (varint > (guint64)INT32_MAX) { + if (varint > (uint64_t)INT32_MAX) { len_pi = proto_tree_add_int64(sub_tree, hf_thrift_i64, tvb, *offset, len_len, varint); expert_add_info(pinfo, len_pi, &ei_thrift_varint_too_large); return THRIFT_REQUEST_REASSEMBLY; } - container_len = (guint32)varint; + container_len = (uint32_t)varint; len_pi = proto_tree_add_int(sub_tree, hf_num_item, tvb, *offset, len_len, container_len); *offset += len_len; break; @@ -2314,14 +2568,14 @@ static int // NOLINTNEXTLINE(misc-no-recursion) dissect_thrift_compact_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt) { - return dissect_thrift_compact_list_set(tvb, pinfo, tree, offset, thrift_opt, TRUE); + return dissect_thrift_compact_list_set(tvb, pinfo, tree, offset, thrift_opt, true); } static int // NOLINTNEXTLINE(misc-no-recursion) dissect_thrift_compact_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, thrift_option_data_t *thrift_opt) { - return dissect_thrift_compact_list_set(tvb, pinfo, tree, offset, thrift_opt, FALSE); + return dissect_thrift_compact_list_set(tvb, pinfo, tree, offset, thrift_opt, false); } static int @@ -2347,10 +2601,10 @@ dissect_thrift_compact_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *sub_tree; proto_item *container_pi, *len_pi, *ktype_pi, *vtype_pi; - guint32 types, ktype, vtype; - gint32 container_len, len_len, i; - guint64 varint; - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + uint32_t types, ktype, vtype; + int32_t container_len, len_len, i; + uint64_t varint; + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); ABORT_ON_INCOMPLETE_PDU(TCP_THRIFT_MIN_VARINT_LEN); /* Create the sub-tree. */ @@ -2373,12 +2627,12 @@ dissect_thrift_compact_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, /* In case of error, the offset stay at the error position. */ return THRIFT_REQUEST_REASSEMBLY; default: - if (varint > (guint64)INT32_MAX) { + if (varint > (uint64_t)INT32_MAX) { len_pi = proto_tree_add_int64(sub_tree, hf_thrift_i64, tvb, *offset, len_len, varint); expert_add_info(pinfo, len_pi, &ei_thrift_varint_too_large); return THRIFT_REQUEST_REASSEMBLY; } - container_len = (guint32)varint; + container_len = (uint32_t)varint; len_pi = proto_tree_add_int(sub_tree, hf_thrift_num_map_item, tvb, *offset, len_len, container_len); *offset += len_len; break; @@ -2391,7 +2645,7 @@ dissect_thrift_compact_map(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, /* Do not try to read the key & value types of an empty map. */ if (container_len > 0) { /* If the map is not empty, read the types of keys and values. */ - types = tvb_get_guint8(tvb, *offset); + types = tvb_get_uint8(tvb, *offset); ktype = (types >> TCP_THRIFT_NIBBLE_SHIFT) & TCP_THRIFT_NIBBLE_MASK; ktype_pi = proto_tree_add_bits_item(sub_tree, hf_thrift_key_type, tvb, *offset << OCTETS_TO_BITS_SHIFT, TCP_THRIFT_NIBBLE_SHIFT, ENC_BIG_ENDIAN); vtype = types & TCP_THRIFT_NIBBLE_MASK; @@ -2451,8 +2705,8 @@ dissect_thrift_compact_fields(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre }; thrift_opt->previous_field_id = 0; - while (TRUE) { - if (dissect_thrift_field_header(tvb, pinfo, tree, offset, thrift_opt, &field_header, TRUE) == THRIFT_REQUEST_REASSEMBLY) { + while (true) { + if (dissect_thrift_field_header(tvb, pinfo, tree, offset, thrift_opt, &field_header, true) == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; } if (field_header.type.compact == DE_THRIFT_C_STOP) { @@ -2477,7 +2731,7 @@ dissect_thrift_compact_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre */ proto_tree *sub_tree; proto_item *pi; - guint nested_count = p_get_proto_depth(pinfo, proto_thrift); + unsigned nested_count = p_get_proto_depth(pinfo, proto_thrift); ABORT_ON_INCOMPLETE_PDU(TCP_THRIFT_STRUCT_LEN); if (nested_count >= thrift_opt->nested_type_depth) { @@ -2519,17 +2773,17 @@ dissect_thrift_compact_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, *offset += TBP_THRIFT_I8_LEN; break; case DE_THRIFT_C_I16: - if (dissect_thrift_varint(tvb, pinfo, tree, offset, thrift_opt, TCP_THRIFT_MAX_I16_LEN, hf_thrift_i16) == THRIFT_REQUEST_REASSEMBLY) { + if (dissect_thrift_varint(tvb, pinfo, tree, offset, thrift_opt, TCP_THRIFT_MAX_I16_LEN, hf_thrift_i16, NULL) == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; } break; case DE_THRIFT_C_I32: - if (dissect_thrift_varint(tvb, pinfo, tree, offset, thrift_opt, TCP_THRIFT_MAX_I32_LEN, hf_thrift_i32) == THRIFT_REQUEST_REASSEMBLY) { + if (dissect_thrift_varint(tvb, pinfo, tree, offset, thrift_opt, TCP_THRIFT_MAX_I32_LEN, hf_thrift_i32, NULL) == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; } break; case DE_THRIFT_C_I64: - if (dissect_thrift_varint(tvb, pinfo, tree, offset, thrift_opt, TCP_THRIFT_MAX_I64_LEN, hf_thrift_i64) == THRIFT_REQUEST_REASSEMBLY) { + if (dissect_thrift_varint(tvb, pinfo, tree, offset, thrift_opt, TCP_THRIFT_MAX_I64_LEN, hf_thrift_i64, NULL) == THRIFT_REQUEST_REASSEMBLY) { return THRIFT_REQUEST_REASSEMBLY; } break; @@ -2681,17 +2935,17 @@ dissect_thrift_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o proto_item *fid_pi = NULL; int start_offset = offset; int header_offset = 0, data_offset = 0; - gint32 seqid_len = TCP_THRIFT_MAX_I32_LEN; - gint32 str_len_len = TCP_THRIFT_MAX_I32_LEN; - guint8 mtype; - guint16 version; - gint32 str_len, seq_id; - gint64 varint; - guint8 *method_str; + int32_t seqid_len = TCP_THRIFT_MAX_I32_LEN; + int32_t str_len_len = TCP_THRIFT_MAX_I32_LEN; + uint8_t mtype; + uint16_t version; + int32_t str_len, seq_id; + int64_t varint; + uint8_t *method_str; int remaining; tvbuff_t *msg_tvb; int len, tframe_length = 0; - gboolean is_framed, is_compact, request_reasm; + bool is_framed, is_compact, request_reasm; /* Get the current state of dissection. */ DISSECTOR_ASSERT(thrift_opt); @@ -2747,21 +3001,21 @@ dissect_thrift_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o return seqid_len; } offset += seqid_len; - if (varint > (gint64)INT32_MAX || varint < (gint64)INT32_MIN) { + if (varint > (int64_t)INT32_MAX || varint < (int64_t)INT32_MIN) { expert_add_info(pinfo, thrift_pi, &ei_thrift_varint_too_large); /* Sequence id is only informative, we may be just fine. */ } - seq_id = (gint32)varint; + seq_id = (int32_t)varint; /* Read length of method name */ str_len_len = thrift_get_varint_enc(tvb, pinfo, tree, offset, TCP_THRIFT_MAX_I32_LEN, &varint, ENC_VARINT_PROTOBUF); if (str_len_len <= 0) { return str_len_len; } - if (varint > (gint64)INT32_MAX) { + if (varint > (int64_t)INT32_MAX) { expert_add_info(pinfo, thrift_pi, &ei_thrift_varint_too_large); return 0; } - str_len = (gint32)varint; + str_len = (int32_t)varint; if (str_len < 0) { expert_add_info(pinfo, thrift_pi, &ei_thrift_negative_length); return 0; @@ -2771,14 +3025,14 @@ dissect_thrift_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o if (tvb_reported_length_remaining(tvb, offset) < str_len) { goto add_expert_and_reassemble; } - method_str = tvb_get_string_enc(pinfo->pool, tvb, offset, str_len, ENC_UTF_8|ENC_NA); + method_str = tvb_get_string_enc(pinfo->pool, tvb, offset, str_len, ENC_UTF_8); offset += str_len; } else if (thrift_opt->tprotocol & PROTO_THRIFT_STRICT) { if (remaining < TBP_THRIFT_STRICT_MIN_MESSAGE_LEN) { goto add_expert_and_reassemble; } version = tvb_get_ntohs(tvb, offset) & THRIFT_BINARY_VERSION_VALUE_MASK; - mtype = tvb_get_guint8(tvb, offset + TBP_THRIFT_MTYPE_OFFSET) & THRIFT_BINARY_MESSAGE_MASK; + mtype = tvb_get_uint8(tvb, offset + TBP_THRIFT_MTYPE_OFFSET) & THRIFT_BINARY_MESSAGE_MASK; str_len = tvb_get_ntohil(tvb, offset + TBP_THRIFT_VERSION_LEN); if (str_len < 0) { expert_add_info(pinfo, thrift_pi, &ei_thrift_negative_length); @@ -2788,7 +3042,7 @@ dissect_thrift_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o goto add_expert_and_reassemble; } offset += TBP_THRIFT_VERSION_LEN + TBP_THRIFT_LENGTH_LEN; - method_str = tvb_get_string_enc(pinfo->pool, tvb, offset, str_len, ENC_UTF_8|ENC_NA); + method_str = tvb_get_string_enc(pinfo->pool, tvb, offset, str_len, ENC_UTF_8); offset += str_len; seq_id = tvb_get_ntohil(tvb, offset); @@ -2807,9 +3061,9 @@ dissect_thrift_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o goto add_expert_and_reassemble; } offset += TBP_THRIFT_LENGTH_LEN; - method_str = tvb_get_string_enc(pinfo->pool, tvb, offset, str_len, ENC_UTF_8|ENC_NA); + method_str = tvb_get_string_enc(pinfo->pool, tvb, offset, str_len, ENC_UTF_8); offset += str_len; - mtype = tvb_get_guint8(tvb, offset + TBP_THRIFT_LENGTH_LEN + str_len) & THRIFT_BINARY_MESSAGE_MASK; + mtype = tvb_get_uint8(tvb, offset + TBP_THRIFT_LENGTH_LEN + str_len) & THRIFT_BINARY_MESSAGE_MASK; offset += TBP_THRIFT_TYPE_LEN; seq_id = tvb_get_ntohil(tvb, offset); @@ -2905,7 +3159,7 @@ dissect_thrift_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o * We read this before checking for sub-dissectors as the information might be useful to them. */ int result = data_offset; - result = dissect_thrift_field_header(tvb, pinfo, NULL, &result, thrift_opt, &header, FALSE); + result = dissect_thrift_field_header(tvb, pinfo, NULL, &result, thrift_opt, &header, false); switch (result) { case THRIFT_REQUEST_REASSEMBLY: goto add_expert_and_reassemble; @@ -2925,7 +3179,7 @@ dissect_thrift_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o /* Attach the expert_info to the method type as it is a protocol-level exception. */ expert_add_info(pinfo, mtype_pi, &ei_thrift_protocol_exception); /* Leverage the sub-dissector capabilities to dissect Thrift exceptions. */ - len = dissect_thrift_t_struct(msg_tvb, pinfo, thrift_tree, 0, thrift_opt, FALSE, 0, hf_thrift_exception, ett_thrift_exception, thrift_exception); + len = dissect_thrift_t_struct(msg_tvb, pinfo, thrift_tree, 0, thrift_opt, false, 0, hf_thrift_exception, ett_thrift_exception, thrift_exception); } if (len > 0) { /* The sub dissector dissected the tvb*/ @@ -2988,10 +3242,10 @@ reassemble_pdu: /* When detected by any called function (that already added the } /* For tcp_dissect_pdus. */ -static guint +static unsigned get_framed_thrift_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) { - return (guint)TBP_THRIFT_LENGTH_LEN + tvb_get_ntohl(tvb, offset); + return (unsigned)TBP_THRIFT_LENGTH_LEN + tvb_get_ntohl(tvb, offset); } /* Effective dissection once the exact encoding has been determined. @@ -3002,10 +3256,10 @@ get_framed_thrift_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, voi static int dissect_thrift_loop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, thrift_option_data_t *thrift_opt) { - gint32 offset = 0; - gint32 hdr_offset = 0; - gint32 last_pdu_start_offset = 0; - gint32 remaining = tvb_reported_length_remaining(tvb, offset); + int32_t offset = 0; + int32_t hdr_offset = 0; + int32_t last_pdu_start_offset = 0; + int32_t remaining = tvb_reported_length_remaining(tvb, offset); DISSECTOR_ASSERT(thrift_opt); DISSECTOR_ASSERT(thrift_opt->canary == THRIFT_OPTION_DATA_CANARY); @@ -3024,9 +3278,9 @@ dissect_thrift_loop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, thrift_ * In particular, client could send a first request in old format to get * the server version and switch to strict if the server is up-to-date * or if it rejected explicitly the old format (there's an example for that). */ - if (tvb_get_gint8(tvb, offset + hdr_offset) < 0) { + if (tvb_get_int8(tvb, offset + hdr_offset) < 0) { /* Strict header (If only the message type is incorrect, assume this is a new one. */ - if (!is_thrift_strict_version(tvb_get_ntohl(tvb, offset + hdr_offset), TRUE)) { + if (!is_thrift_strict_version(tvb_get_ntohl(tvb, offset + hdr_offset), true)) { expert_add_info(pinfo, NULL, &ei_thrift_wrong_proto_version); return tvb_reported_length_remaining(tvb, 0); } @@ -3064,9 +3318,9 @@ reassemble_pdu: static int dissect_thrift_framed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { - gint32 offset = 0; - gint32 frame_len = 0; - gint32 reported = tvb_reported_length_remaining(tvb, offset); + int32_t offset = 0; + int32_t frame_len = 0; + int32_t reported = tvb_reported_length_remaining(tvb, offset); thrift_option_data_t *thrift_opt = (thrift_option_data_t *)data; DISSECTOR_ASSERT(thrift_opt); @@ -3095,14 +3349,14 @@ dissect_thrift_framed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void static int dissect_thrift_transport(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - gint32 str_len, length = tvb_reported_length(tvb); + int32_t str_len, length = tvb_reported_length(tvb); thrift_option_data_t thrift_opt; memset(&thrift_opt, 0, sizeof(thrift_option_data_t)); thrift_opt.nested_type_depth = nested_type_depth; /* Starting without even the version / frame length / name length probably means a Keep-Alive at the beginning of the capture. */ if (length < TBP_THRIFT_VERSION_LEN) { - if (tvb_get_guint8(tvb, 0) != (THRIFT_COMPACT_VERSION_1 >> 8)) { + if (tvb_get_uint8(tvb, 0) != (THRIFT_COMPACT_VERSION_1 >> 8)) { proto_tree_add_expert(tree, pinfo, &ei_thrift_not_enough_data, tvb, 0, length); /* Not a Thrift packet, maybe a keep-alive at the beginning of the capture. */ return NOT_A_VALID_PDU; @@ -3122,7 +3376,7 @@ dissect_thrift_transport(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo /* MSb of first byte is 1 for compact and binary strict protocols * and 0 for framed transport and old binary protocol. */ - if (tvb_get_gint8(tvb, 0) >= 0) { + if (tvb_get_int8(tvb, 0) >= 0) { /* Option 1 = old binary * Option 2 = framed strict binary * Option 3 = framed old binary @@ -3146,7 +3400,7 @@ dissect_thrift_transport(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo return THRIFT_REQUEST_REASSEMBLY; } - if (thrift_binary_utf8_isprint(tvb, TBP_THRIFT_LENGTH_LEN, str_len, FALSE) == str_len) { + if (thrift_binary_utf8_isprint(tvb, TBP_THRIFT_LENGTH_LEN, str_len, false) == str_len) { /* UTF-8 valid data means first byte is greater than 0x20 and not between 0x80 and 0xbf (neither 0x80 nor 0x82 in particular). * This would indicate a method name longer than 512 MiB in Framed old binary protocol which is insane. * Therefore, most sane option is old binary without any framing. */ @@ -3162,12 +3416,12 @@ dissect_thrift_transport(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo /* This is /not/ valid Framed data. */ return NOT_A_VALID_PDU; } - if (tvb_get_gint8(tvb, TBP_THRIFT_LENGTH_LEN) >= 0) { + if (tvb_get_int8(tvb, TBP_THRIFT_LENGTH_LEN) >= 0) { /* Framed old binary format is the only matching option remaining. */ thrift_opt.canary = THRIFT_OPTION_DATA_CANARY; thrift_opt.tprotocol = PROTO_THRIFT_FRAMED; } else { - if (is_thrift_strict_version(tvb_get_ntohl(tvb, TBP_THRIFT_LENGTH_LEN), TRUE)) { + if (is_thrift_strict_version(tvb_get_ntohl(tvb, TBP_THRIFT_LENGTH_LEN), true)) { /* Framed strict binary protocol. */ thrift_opt.canary = THRIFT_OPTION_DATA_CANARY; thrift_opt.tprotocol = (thrift_protocol_enum_t)(PROTO_THRIFT_FRAMED | PROTO_THRIFT_STRICT); @@ -3177,12 +3431,12 @@ dissect_thrift_transport(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo } } } - } else if (is_thrift_strict_version(tvb_get_ntohl(tvb, 0), TRUE)) { + } else if (is_thrift_strict_version(tvb_get_ntohl(tvb, 0), true)) { /* We don't need all the checks from the heuristic because the user prefs told us it /is/ Thrift data. * If it fails, it will probably pass through otherwise hard-to-reach code-paths so that's good for tests. */ thrift_opt.canary = THRIFT_OPTION_DATA_CANARY; thrift_opt.tprotocol = PROTO_THRIFT_STRICT; - } else if (tvb_get_guint8(tvb, 0) == 0x82) { + } else if (tvb_get_uint8(tvb, 0) == 0x82) { /* Same thing here so 0x82 gives us the TCompactProtocol answer. */ thrift_opt.canary = THRIFT_OPTION_DATA_CANARY; thrift_opt.tprotocol = PROTO_THRIFT_COMPACT; @@ -3215,13 +3469,13 @@ reassemble_pdu: * Due to that, we might have false negative if the capture is too much shorten * but it would have been useless anyway. */ -static gboolean +static bool test_thrift_strict(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, thrift_option_data_t *thrift_opt) { - gint tframe_length = 0; + int tframe_length = 0; int offset = 0; - guint length = tvb_captured_length(tvb); - gint32 str_len; + unsigned length = tvb_captured_length(tvb); + int32_t str_len; /* This heuristic only detects strict binary protocol, possibly framed. * Detection of old binary protocol is tricky due to the lack of fixed data. @@ -3236,21 +3490,21 @@ test_thrift_strict(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, * 6. First field type (1 byte, content not verified). */ /* Enough data for elements 2 to 6? */ - if (length < (guint)TBP_THRIFT_STRICT_HEADER_LEN) { - return FALSE; + if (length < (unsigned)TBP_THRIFT_STRICT_HEADER_LEN) { + return false; } /* 1. Check if it is framed (and if the frame length is large enough for a complete message). */ - if (tvb_get_gint8(tvb, offset) >= 0) { + if (tvb_get_int8(tvb, offset) >= 0) { /* It is framed. */ tframe_length = tvb_get_ntohil(tvb, offset); if (tframe_length < TBP_THRIFT_STRICT_MIN_MESSAGE_LEN) { - return FALSE; + return false; } offset = TBP_THRIFT_LENGTH_LEN; /* Strict header starts after frame length. */ - if (length < (guint)(offset + TBP_THRIFT_STRICT_HEADER_LEN)) { - return FALSE; + if (length < (unsigned)(offset + TBP_THRIFT_STRICT_HEADER_LEN)) { + return false; } } if (thrift_opt) { @@ -3263,8 +3517,8 @@ test_thrift_strict(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, } else REPORT_DISSECTOR_BUG("%s called without data structure.", G_STRFUNC); /* 2. Thrift version & method type (heuristic does /not/ ignore the message type). */ - if (!is_thrift_strict_version(tvb_get_ntohl(tvb, offset), FALSE)) { - return FALSE; + if (!is_thrift_strict_version(tvb_get_ntohl(tvb, offset), false)) { + return false; } offset += TBP_THRIFT_VERSION_LEN; @@ -3272,41 +3526,41 @@ test_thrift_strict(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, str_len = tvb_get_ntohil(tvb, offset); if ((tframe_length > 0) && (tframe_length < TBP_THRIFT_STRICT_MIN_MESSAGE_LEN + str_len)) { /* The frame cannot even contain an empty Thrift message (no data, only T_STOP after the sequence id). */ - return FALSE; + return false; } offset += TBP_THRIFT_LENGTH_LEN; /* 4. Check method name itself. */ if (tvb_captured_length_remaining(tvb, offset) < str_len) { /* Method name is no entirely captured, we cannot check it. */ - return FALSE; + return false; } - if (thrift_binary_utf8_isprint(tvb, offset, str_len, FALSE) < str_len) { - return FALSE; + if (thrift_binary_utf8_isprint(tvb, offset, str_len, false) < str_len) { + return false; } offset += str_len; /* 5 & 6. Check that there is enough data remaining for a sequence ID and a field type (but no need for it to be captured). */ if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_LENGTH_LEN + TBP_THRIFT_TYPE_LEN) { - return FALSE; + return false; } thrift_opt->canary = THRIFT_OPTION_DATA_CANARY; - return TRUE; + return true; } /* Test if the captured packet matches a Thrift compact packet header. * Same comments as for test_thrift_strict. */ -static gboolean +static bool test_thrift_compact(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, thrift_option_data_t *thrift_opt) { - gint tframe_length = 0; + int tframe_length = 0; int offset = 0; - guint length = tvb_captured_length(tvb); + unsigned length = tvb_captured_length(tvb); int len_len; - gint32 str_len = 0; - guint64 seq_id; + int32_t str_len = 0; + uint64_t seq_id; /* This heuristic detects compact protocol, possibly framed. * Note: It assumes a maximum size of 127 bytes for the method name. @@ -3321,21 +3575,21 @@ test_thrift_compact(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, * 6. First field type (1 byte, content not verified). */ /* Enough data for elements 2 to 6? */ - if (length < (guint)TCP_THRIFT_MIN_MESSAGE_LEN) { - return FALSE; + if (length < (unsigned)TCP_THRIFT_MIN_MESSAGE_LEN) { + return false; } /* 1. Check if it is framed (and if the frame length is large enough for a complete message). */ - if (tvb_get_gint8(tvb, offset) >= 0) { + if (tvb_get_int8(tvb, offset) >= 0) { /* It is framed. */ tframe_length = tvb_get_ntohil(tvb, offset); if (tframe_length < TCP_THRIFT_MIN_MESSAGE_LEN) { - return FALSE; + return false; } offset = TBP_THRIFT_LENGTH_LEN; /* Compact header starts after frame length. */ - if (length < (guint)(offset + TCP_THRIFT_MIN_MESSAGE_LEN)) { - return FALSE; + if (length < (unsigned)(offset + TCP_THRIFT_MIN_MESSAGE_LEN)) { + return false; } } if (thrift_opt) { @@ -3349,8 +3603,8 @@ test_thrift_compact(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, } else REPORT_DISSECTOR_BUG("%s called without data structure.", G_STRFUNC); /* 2. Thrift version & method type (heuristic does /not/ ignore the message type). */ - if (!is_thrift_compact_version(tvb_get_ntohs(tvb, offset), FALSE)) { - return FALSE; + if (!is_thrift_compact_version(tvb_get_ntohs(tvb, offset), false)) { + return false; } offset += TCP_THRIFT_VERSION_LEN; @@ -3360,43 +3614,43 @@ test_thrift_compact(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, len_len = TCP_THRIFT_MAX_I32_LEN; } len_len = tvb_get_varint(tvb, offset, len_len, &seq_id, ENC_VARINT_ZIGZAG); - if (len_len == 0) return FALSE; + if (len_len == 0) return false; offset += len_len; /* 4. Get method name length and check against what we have. */ - if ((guint)offset >= length) return FALSE; - str_len = tvb_get_guint8(tvb, offset); + if ((unsigned)offset >= length) return false; + str_len = tvb_get_uint8(tvb, offset); // MSb = 1 means the method length is greater than 127 bytes long. if ((str_len & 0x80) != 0) { - return FALSE; // Reject it to avoid too many false positive. + return false; // Reject it to avoid too many false positive. } ++offset; if ((tframe_length > 0) && (TBP_THRIFT_LENGTH_LEN + tframe_length < offset + str_len)) { /* The frame cannot even contain an empty Thrift message (no data, only T_STOP after the sequence id). */ - return FALSE; + return false; } /* 5. Check method name itself. */ if (tvb_captured_length_remaining(tvb, offset) < str_len) { /* Method name is no entirely captured, we cannot check it. */ - return FALSE; + return false; } - if (thrift_binary_utf8_isprint(tvb, offset, str_len, FALSE) < str_len) { - return FALSE; + if (thrift_binary_utf8_isprint(tvb, offset, str_len, false) < str_len) { + return false; } offset += str_len; /* 6. Check that there is enough data remaining for a field type (but no need for it to be captured). */ if (tvb_reported_length_remaining(tvb, offset) < TBP_THRIFT_TYPE_LEN) { - return FALSE; + return false; } thrift_opt->canary = THRIFT_OPTION_DATA_CANARY; - return TRUE; + return true; } /* Thrift heuristic dissection when the packet is not grabbed by another protocol dissector. */ -static gboolean +static bool dissect_thrift_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { thrift_option_data_t thrift_opt; @@ -3404,7 +3658,7 @@ dissect_thrift_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d thrift_opt.nested_type_depth = nested_type_depth; if (!test_thrift_strict(tvb, pinfo, tree, &thrift_opt) && !test_thrift_compact(tvb, pinfo, tree, &thrift_opt)) { - return FALSE; + return false; } col_set_str(pinfo->cinfo, COL_PROTOCOL, "THRIFT"); @@ -3417,7 +3671,13 @@ dissect_thrift_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d dissect_thrift_loop(tvb, pinfo, tree, &thrift_opt); } - return TRUE; + return true; +} + +static int +dissect_thrift_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +{ + return dissect_thrift_heur(tvb, pinfo, tree, data) ? tvb_captured_length(tvb) : 0; } /*=====END HEADER GENERIC DISSECTION=====*/ @@ -3604,7 +3864,7 @@ proto_register_thrift(void) /* setup protocol subtree arrays */ - static gint *ett[] = { + static int *ett[] = { &ett_thrift, &ett_thrift_header, &ett_thrift_params, @@ -3655,7 +3915,7 @@ proto_register_thrift(void) /* register dissector */ thrift_handle = register_dissector("thrift", dissect_thrift_transport, proto_thrift); - thrift_http_handle = register_dissector("thrift.http", dissect_thrift_heur, proto_thrift); + thrift_http_handle = register_dissector("thrift.http", dissect_thrift_http, proto_thrift); thrift_module = prefs_register_protocol(proto_thrift, proto_reg_handoff_thrift); @@ -3665,7 +3925,7 @@ proto_register_thrift(void) prefs_register_enum_preference(thrift_module, "decode_binary", "Display binary as bytes or strings", "How the binary should be decoded", - &binary_decode, binary_display_options, FALSE); + &binary_decode, binary_display_options, false); prefs_register_uint_preference(thrift_module, "tls.port", "Thrift TLS port", @@ -3700,11 +3960,11 @@ proto_register_thrift(void) void proto_reg_handoff_thrift(void) { - static guint saved_thrift_tls_port; - static gboolean thrift_initialized = FALSE; + static unsigned saved_thrift_tls_port; + static bool thrift_initialized = false; if (!thrift_initialized) { - thrift_initialized = TRUE; + thrift_initialized = true; heur_dissector_add("tcp", dissect_thrift_heur, "Thrift over TCP", "thrift_tcp", proto_thrift, HEURISTIC_ENABLE); heur_dissector_add("udp", dissect_thrift_heur, "Thrift over UDP", "thrift_udp", proto_thrift, HEURISTIC_ENABLE); heur_dissector_add("usb.bulk", dissect_thrift_heur, "Thrift over USB", "thrift_usb_bulk", proto_thrift, HEURISTIC_ENABLE); |