1 /* xmpp-utils.h
2  *
3  * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #ifndef XMPP_UTILS_H
13 #define XMPP_UTILS_H
14 
15 #include "ws_symbol_export.h"
16 #include "tvbuff.h"
17 #include "dissectors/packet-xml.h"
18 #include <epan/wmem_scopes.h>
19 
20 #define xmpp_elem_cdata(elem) \
21 elem->data?elem->data->value:""
22 
23 typedef struct _xmpp_array_t
24 {
25     gpointer data;
26     gint length;
27 } xmpp_array_t;
28 
29 typedef struct _xmpp_attr_t{
30     const gchar *value;
31     const gchar *name;
32     gint offset;
33     gint length;
34 
35     gboolean was_read;
36 } xmpp_attr_t;
37 
38 typedef struct _xmpp_data_t{
39     gchar *value;
40 
41     gint offset;
42     gint length;
43 } xmpp_data_t;
44 
45 typedef struct _xmpp_element_t{
46     gchar* name;
47 
48     /*abbreviation that apprears before tag name (<nos:x .../>)
49      if abbrev doesn't appear then NULL*/
50     gchar* default_ns_abbrev;
51     /*pair of namespace abbrev and namespace*/
52     GHashTable *namespaces;
53 
54     GHashTable *attrs;
55     GList *elements;
56     xmpp_data_t *data;
57 
58     gint offset;
59     gint length;
60 
61     gboolean was_read;
62 } xmpp_element_t;
63 
64 /*informations about attributes that are displayed in proto tree*/
65 typedef struct _xmpp_attr_info{
66     const gchar *name;
67     const gint *phf;
68     gboolean is_required;
69     gboolean in_short_list;
70 
71     /*function validates this attribute
72     it may impose other restrictions (e.g. validating atribut's name, ...)*/
73     void (*val_func)(packet_info *pinfo, proto_item *item, const gchar *name, const gchar *value, gconstpointer data);
74     gpointer data;
75 } xmpp_attr_info;
76 
77 typedef struct _xmpp_attr_info_ext{
78     const gchar* ns;
79     xmpp_attr_info info;
80 } xmpp_attr_info_ext;
81 
82 typedef enum _xmpp_elem_info_type{
83     NAME,
84     ATTR,
85     NAME_AND_ATTR,
86     NAMES
87 } xmpp_elem_info_type;
88 
89 typedef enum _xmpp_elem_info_occurrence
90 {
91     ONE,MANY
92 } xmpp_elem_info_occurrence;
93 
94 /*informations about elements that are displayed in proto tree*/
95 typedef struct _xmpp_elem_info{
96     xmpp_elem_info_type type;
97     gconstpointer data;
98     /*function that displays element in tree*/
99     void (*elem_func)(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
100     xmpp_elem_info_occurrence occurrence;
101 } xmpp_elem_info;
102 
103 typedef struct _xmpp_conv_info_t {
104     wmem_tree_t *req_resp;
105     wmem_tree_t *jingle_sessions;
106     wmem_tree_t *ibb_sessions;
107     wmem_tree_t *gtalk_sessions;
108     guint32      ssl_start;
109 } xmpp_conv_info_t;
110 
111 /** Struct conatins frame numbers (request frame(IQ set/get) and
112  * response frame(IQ result/error)).
113  */
114 typedef struct _xmpp_reqresp_transaction_t {
115     guint32 req_frame;
116     guint32 resp_frame;
117 } xmpp_transaction_t;
118 
119 /** Function that is responsibe for request/response tracking in IQ packets.
120  * Each IQ set/get packet should have the response in other IQ result/error packet.
121  * Both packet should have the same id attribute. Function saves in wmem_tree pairs of
122  * packet id and struct xmpp_transaction_t.
123  */
124 extern void xmpp_iq_reqresp_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info);
125 
126 /** Function that is responsibe for jingle session tracking in IQ packets.
127  * Function saves in wmem_tree pairs of packet's id and Jingle session's id.
128  */
129 extern void xmpp_jingle_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info);
130 
131 /** Function that is responsibe for ibb(in band bytestreams) session tracking in IQ packets.
132  * Function saves in wmem_tree pairs of packet's id and In-Band Bytestreams session's id.
133  */
134 extern void xmpp_ibb_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info);
135 
136 /** Function that is responsibe for GTalk session(voice/video) tracking in IQ packets.
137  * Function saves in wmem_tree pairs of packet's id and GTalk session's id.
138  */
139 extern void xmpp_gtalk_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info);
140 
141 /** Function detects unrecognized elements and displays them in tree.
142  * It uses ett_unknown to display packets. ett_unknown has const size described by
143  * ETT_UNKNOWN_LEN in packet-xmpp.h
144  */
145 extern void xmpp_unknown(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
146 
147 /** Displays CDATA from element in tree. You can use your own header field hf or
148  * pass -1. If you pass -1 then CDATA will be display as text:
149  * ELEMENT_NAME: CDATA
150  * ELEMENT_NAME = element->name, if element is empty CDATA = "(empty)"
151  */
152 extern void xmpp_cdata(proto_tree *tree, tvbuff_t *tvb, xmpp_element_t *element, gint hf);
153 
154 /** Function is similar to xmpp_cdata. But it display items only as a text and it is
155  * compatibile with function display_elems
156  */
157 extern void xmpp_simple_cdata_elem(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
158 
159 /** Converts xml_frame_t struct to xmpp_element_t. Should be call with parent==NULL.
160  */
161 extern xmpp_element_t* xmpp_xml_frame_to_element_t(wmem_allocator_t *pool, xml_frame_t *xml_frame, xmpp_element_t *parent, tvbuff_t *tvb);
162 
163 /** Frees all GLib structs in xmpp_element_t struct. Should be call only for root element.
164  * It works recursively.
165  */
166 extern void xmpp_element_t_tree_free(xmpp_element_t *root);
167 
168 /** Allocs ephemeral memory for xmpp_array_t struct.*/
169 extern xmpp_array_t* xmpp_ep_init_array_t(wmem_allocator_t *pool, const gchar** array, gint len);
170 
171 /*Allocs ephemeral memory for xmpp_attr_t struct*/
172 extern xmpp_attr_t* xmpp_ep_init_attr_t(wmem_allocator_t *pool, const gchar *value, gint offset, gint length);
173 
174 /** steal_*
175  * Functions searches and marks as read found elements.
176  * If element is set as read, it is invisible for these functions.*/
177 
178 extern xmpp_element_t* xmpp_steal_element_by_name(xmpp_element_t *packet, const gchar *name);
179 extern xmpp_element_t* xmpp_steal_element_by_names(xmpp_element_t *packet, const gchar **names, gint names_len);
180 extern xmpp_element_t* xmpp_steal_element_by_attr(xmpp_element_t *packet, const gchar *attr_name, const gchar *attr_value);
181 extern xmpp_element_t* xmpp_steal_element_by_name_and_attr(xmpp_element_t *packet, const gchar *name, const gchar *attr_name, const gchar *attr_value);
182 
183 /*Returns first child in element*/
184 extern xmpp_element_t* xmpp_get_first_element(xmpp_element_t *packet);
185 
186 /*Converts element to string. Returns memory allocated from the given pool.*/
187 extern gchar* xmpp_element_to_string(wmem_allocator_t *pool, tvbuff_t *tvb, xmpp_element_t *element);
188 
189 /* Returns attribute by name and set as read. If attrib is set as read, it may be found
190  * one more time, but it is invisible for function xmpp_unknown_attrib*/
191 extern xmpp_attr_t* xmpp_get_attr(xmpp_element_t *element, const gchar* attr_name);
192 
193 /*Function hides first element in tree.*/
194 extern void xmpp_proto_tree_hide_first_child(proto_tree *tree);
195 
196 /*Function shows first element in tree.*/
197 extern void xmpp_proto_tree_show_first_child(proto_tree *tree);
198 
199 /*Function returns item as text. Memory is allocated from the given pool.*/
200 extern gchar* proto_item_get_text(wmem_allocator_t *pool, proto_item *item);
201 
202 /*Function returns struct that contains 3 strings. It is used to build xmpp_attr_info struct.*/
203 extern gpointer xmpp_name_attr_struct(wmem_allocator_t *pool, const gchar *name, const gchar *attr_name, const gchar *attr_value);
204 
205 /** Function displays attributes from element in way described in attrs.
206  * Elements that doesn't exist in attrs are displayed as text.
207  * In XMPP_ATTR_INFO struct you can define several things:
208  * - is_in_short_list - attribute should be displayed in short list e.g. ELEMENT_NAME [ATTR1='value' ATTR2='value']
209  * - is_required - attribute is required. If attribute doesn't appear then EXPERT INFO will be displayed
210  * - val_func - validate function
211  * - data - data passes to the val_func
212  */
213 extern void xmpp_display_attrs(proto_tree *tree, xmpp_element_t *element, packet_info *pinfo, tvbuff_t *tvb, const xmpp_attr_info *attrs, guint n);
214 
215 /** Function does the same as shown above. It takes attrs(XMPP_ATTR_INFO_EXT) argument
216  * that contains XMPP_ATTR_INFO struct and string with namespace. It is used when packet
217  * contains several namespaces and each attribute belongs to particular namespace.
218  * E.g.
219  * @code
220  * <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
221  *  mechanism='PLAIN'
222  *  xmlns:ga='http://www.google.com/talk/protocol/auth'
223  *  ga:client-uses-full-bind-result='true'>
224  * </auth>
225  * @endcode
226  */
227 extern void xmpp_display_attrs_ext(proto_tree *tree, xmpp_element_t *element, packet_info *pinfo, tvbuff_t *tvb, const xmpp_attr_info_ext *attrs, guint n);
228 
229 /** Displays elements from parent element in a way described in elems(XMPP_ELEM_INFO).
230  * XMPP_ELEM_INFO describes how to find particular element and what action should be done
231  * for this element.
232  * Function calls xmpp_unknown.
233  */
234 extern void xmpp_display_elems(proto_tree *tree, xmpp_element_t *parent, packet_info *pinfo, tvbuff_t *tvb, xmpp_elem_info *elems, guint n);
235 
236 /* Validates attribute value. Takes string array(gchar**) in parameter data.
237  * Is used in XMPP_ATTR_INFO struct.
238  */
239 extern void xmpp_val_enum_list(packet_info *pinfo, proto_item *item, const gchar *name, const gchar *value, gconstpointer data);
240 
241 /** Function changes element to attribute. It searches element by name in parent element,
242  * next it create attribute using transform_func and inserts it to parent attributes hash table
243  * using attr_name as key.
244  */
245 extern void xmpp_change_elem_to_attrib(wmem_allocator_t *pool, const gchar *elem_name, const gchar *attr_name, xmpp_element_t *parent, xmpp_attr_t* (*transform_func)(wmem_allocator_t *pool, xmpp_element_t *element));
246 
247 /** transform_func that creates attribute with element's cdata as value
248  */
249 extern xmpp_attr_t* xmpp_transform_func_cdata(wmem_allocator_t *pool, xmpp_element_t *elem);
250 
251 #endif /* XMPP_UTILS_H */
252