3 * Copyright 2015, Anders Broman <anders.broman[at]ericsson.com>
4 * Copyright 2019-2024, Triton Circonflexe <triton[at]kumal.info>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Note: used by proprietary dissectors (too).
15 #ifndef __PACKET_THRIFT_H__
16 #define __PACKET_THRIFT_H__
18 #include <epan/expert.h>
19 #include "ws_symbol_export.h"
23 DE_THRIFT_T_GENERIC
= -1, // Use this to delegate field dissection to generic dissector.
25 DE_THRIFT_T_VOID
, // DE_THRIFT_T_UNUSED_1?
29 DE_THRIFT_T_UNUSED_5
, // Intended for U16?
31 DE_THRIFT_T_UNUSED_7
, // Intended for U32?
33 DE_THRIFT_T_UNUSED_9
, // Intended for U64?
46 ME_THRIFT_T_EXCEPTION
,
48 } thrift_method_type_enum_t
;
51 * This is a list of flags even though not all combinations are available.
52 * - Framed is compatible with everything;
53 * - Default (0x00) is old binary;
54 * - Binary can be augmented with Strict (message header is different but content is the same);
55 * - Compact is incompatible with Binary & Strict as everything is coded differently;
56 * - If Compact bit is set, Strict bit will be ignored (0x06 ~= 0x04).
58 * Valid values go from 0x00 (old binary format) to 0x05 (framed compact).
60 * Note: Compact is not fully supported yet.
63 PROTO_THRIFT_BINARY
= 0x00,
64 PROTO_THRIFT_FRAMED
= 0x01,
65 PROTO_THRIFT_STRICT
= 0x02,
66 PROTO_THRIFT_COMPACT
= 0x04
67 } thrift_protocol_enum_t
;
69 #define THRIFT_OPTION_DATA_CANARY 0x8001da7a
70 #define THRIFT_REQUEST_REASSEMBLY (-1)
71 #define THRIFT_SUBDISSECTOR_ERROR (-2)
73 typedef struct _thrift_option_data_t
{
74 uint32_t canary
; /* Ensure that we don't read garbage.
75 * Sub-dissectors should check against THRIFT_OPTION_DATA_CANARY. */
76 thrift_method_type_enum_t mtype
; /* Method type necessary to know how to decode the message. */
77 thrift_protocol_enum_t tprotocol
; /* Type and version of Thrift TProtocol.
78 * Framed?((Strict? Binary)|Compact) */
79 int64_t reply_field_id
; /* First (and theoretically only) field id of the current REPLY.
80 * This is useful for the sub-dissectors to handle exceptions. */
81 int64_t previous_field_id
; /* Last field id that was present in the current struct.
82 * Set by dissect_thrift_t_struct after the field has been
84 * Read by the next dissect_thrift_t_field_header if only
85 * a delta is available (for TCompactProtocol). */
86 proto_tree
*reassembly_tree
; /* Tree were the reassembly was requested. */
87 /* Useful if the caller can't reassemble (Framed). */
88 int32_t reassembly_offset
; /* Where the incomplete data starts. */
89 int32_t reassembly_length
; /* Expected size of the data. */
90 uint32_t nested_type_depth
; /* Number of nested types allowed below the parameter or result type. */
91 bool use_std_dissector
; /* Allow the raw dissector to reactivate the standard dissector. */
92 void *data
; /* Pointer to the sub-dissector data. */
93 } thrift_option_data_t
;
95 #define TMFILL NULL, { .m = { NULL, NULL } }, NULL
97 typedef struct _thrift_member_t thrift_member_t
;
98 struct _thrift_member_t
{
99 const int *p_hf_id
; /* The hf field for the struct member. */
100 const int16_t fid
; /* The Thrift field id of the struct member. */
101 const bool optional
; /* true if element is optional, false otherwise. */
102 const thrift_type_enum_t type
; /* The thrift type of the struct member. */
103 const int *p_ett_id
; /* An ett field used for the subtree created if the member is a compound type. */
105 const unsigned encoding
; /* Encoding used for string display. */
106 const thrift_member_t
*element
; /* Description of the elements of a list or a set. */
108 const thrift_member_t
*members
; /* Array describing the members of a struct, union, or exception. */
109 expert_field
* expert_info
; /* Expert info associated to an exception for better problem diagnostics. */
112 const thrift_member_t
*key
; /* Description of the key elements of a map. */
113 const thrift_member_t
*value
; /* Description of the value elements of a map. */
116 const dissector_t raw_dissector
; /* Specific dissector for the field's raw data. */
119 /* These functions are to be used by dissectors dissecting Thrift based protocols similar to packet-ber.c
121 * param[in] tvb Pointer to the tvbuff_t holding the captured data.
122 * param[in] pinfo Pointer to the packet_info holding information about the currently dissected packet.
123 * param[in] tree Pointer to the proto_tree used to hold the display tree in Wireshark's interface.
124 * param[in] offset Offset from the beginning of the tvbuff_t where the Thrift field is. Function will dissect type, id, & data.
125 * param[in] thrift_opt Options from the Thrift dissector that will be necessary for sub-dissection (binary vs. compact, ...)
126 * param[in] is_field Indicate if the offset point to a field element and if field type and field id must be dissected.
127 * Only for containers internal use. Sub-dissectors must always use true except for struct (see below).
128 * param[in] field_id Thrift field identifier, to check that the right field is being dissected (in case of optional fields).
129 * param[in] hf_id Header field info that describes the field to display (display name, filter name, FT_TYPE, ...).
131 * param[in] encoding Encoding used for string display. (Only for dissect_thrift_t_string_enc)
132 * param[in] raw_dissector Specific dissector for the field's raw data.
134 * return Offset of the first non-dissected byte in case of success,
135 * THRIFT_REQUEST_REASSEMBLY (-1) in case reassembly is required, or
136 * THRIFT_SUBDISSECTOR_ERROR (-2) in case of error.
137 * Sub-dissector must follow the same convention on return.
138 * Replacing THRIFT_SUBDISSECTOR_ERROR with a 0 return value has the same effect
139 * as activating "Fallback to generic Thrift dissector if sub-dissector fails"
140 * in this dissector (thrift.fallback_on_generic option).
142 WS_DLL_PUBLIC
int dissect_thrift_t_stop (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, int offset
);
143 WS_DLL_PUBLIC
int 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
);
144 WS_DLL_PUBLIC
int 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
);
145 WS_DLL_PUBLIC
int 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
);
146 WS_DLL_PUBLIC
int 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
);
147 WS_DLL_PUBLIC
int 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
);
148 WS_DLL_PUBLIC
int 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
);
149 WS_DLL_PUBLIC
int 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
);
150 WS_DLL_PUBLIC
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
);
151 WS_DLL_PUBLIC
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
);
152 WS_DLL_PUBLIC
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
);
153 WS_DLL_PUBLIC
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 field_dissector
);
155 /* Dissect a Thrift struct
156 * Dissect a Thrift struct by calling the struct member dissector in turn from the thrift_member_t array
158 * param[in] tvb Pointer to the tvbuff_t holding the captured data.
159 * param[in] pinfo Pointer to the packet_info holding information about the currently dissected packet.
160 * param[in] tree Pointer to the proto_tree used to hold the display tree in Wireshark's interface.
161 * param[in] offset Offset from the beginning of the tvbuff_t where the Thrift field is. Function will dissect type, id, & data.
162 * param[in] thrift_opt Options from the Thrift dissector that will be necessary for sub-dissection (binary vs. compact, ...)
163 * param[in] is_field Indicate if the offset point to a field element and if field type and field id must be dissected.
164 * Only for internal use in containers. Sub-dissectors must always use true except for struct (see below).
165 * Sub-dissectors should always use true except in one case:
166 * - Define the parameters of the Thrift command as a struct (including T_STOP at the end)
167 * - Single call to dissect_thrift_t_struct with is_field = false.
168 * param[in] field_id Thrift field identifier, to check that the right field is being dissected (in case of optional fields).
169 * param[in] hf_id A header field of FT_BYTES which will be the struct header field
171 * param[in] ett_id An ett field used for the subtree created to list the container's elements.
173 * param[in] key Description of the map's key elements.
174 * param[in] val Description of the map's value elements.
176 * param[in] elt Description of the list's or set's elements.
178 * param[in] seq Sequence of descriptions of the structure's members.
179 * An array of thrift_member_t's containing thrift type of the struct members the hf variable to use etc.
181 * return Offset of the first non-dissected byte in case of success,
182 * Same error values and remarks as above.
184 WS_DLL_PUBLIC
int 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
*val
);
185 WS_DLL_PUBLIC
int 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
);
186 WS_DLL_PUBLIC
int 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
);
187 WS_DLL_PUBLIC
int 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
);
189 #endif /*__PACKET_THRIFT_H__ */