summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-xmpp-utils.h
blob: cf54f9f56ea16fbc94637b902566d43732edfa20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/* xmpp-utils.h
 *
 * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#ifndef XMPP_UTILS_H
#define XMPP_UTILS_H

#include "ws_symbol_export.h"
#include "tvbuff.h"
#include "dissectors/packet-xml.h"
#include <epan/wmem_scopes.h>

#define xmpp_elem_cdata(elem) \
elem->data?elem->data->value:""

typedef struct _xmpp_array_t
{
    gpointer data;
    gint length;
} xmpp_array_t;

typedef struct _xmpp_attr_t{
    const gchar *value;
    const gchar *name;
    gint offset;
    gint length;

    gboolean was_read;
} xmpp_attr_t;

typedef struct _xmpp_data_t{
    gchar *value;

    gint offset;
    gint length;
} xmpp_data_t;

typedef struct _xmpp_element_t{
    gchar* name;

    /*abbreviation that apprears before tag name (<nos:x .../>)
     if abbrev doesn't appear then NULL*/
    gchar* default_ns_abbrev;
    /*pair of namespace abbrev and namespace*/
    GHashTable *namespaces;

    GHashTable *attrs;
    GList *elements;
    xmpp_data_t *data;

    gint offset;
    gint length;

    gboolean was_read;
} xmpp_element_t;

/*informations about attributes that are displayed in proto tree*/
typedef struct _xmpp_attr_info{
    const gchar *name;
    const gint *phf;
    gboolean is_required;
    gboolean in_short_list;

    /*function validates this attribute
    it may impose other restrictions (e.g. validating atribut's name, ...)*/
    void (*val_func)(packet_info *pinfo, proto_item *item, const gchar *name, const gchar *value, gconstpointer data);
    gpointer data;
} xmpp_attr_info;

typedef struct _xmpp_attr_info_ext{
    const gchar* ns;
    xmpp_attr_info info;
} xmpp_attr_info_ext;

typedef enum _xmpp_elem_info_type{
    NAME,
    ATTR,
    NAME_AND_ATTR,
    NAMES
} xmpp_elem_info_type;

typedef enum _xmpp_elem_info_occurrence
{
    ONE,MANY
} xmpp_elem_info_occurrence;

/*informations about elements that are displayed in proto tree*/
typedef struct _xmpp_elem_info{
    xmpp_elem_info_type type;
    gconstpointer data;
    /*function that displays element in tree*/
    void (*elem_func)(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
    xmpp_elem_info_occurrence occurrence;
} xmpp_elem_info;

typedef struct _xmpp_conv_info_t {
    wmem_tree_t *req_resp;
    wmem_tree_t *jingle_sessions;
    wmem_tree_t *ibb_sessions;
    wmem_tree_t *gtalk_sessions;
    guint32      ssl_start;
} xmpp_conv_info_t;

/** Struct conatins frame numbers (request frame(IQ set/get) and
 * response frame(IQ result/error)).
 */
typedef struct _xmpp_reqresp_transaction_t {
    guint32 req_frame;
    guint32 resp_frame;
} xmpp_transaction_t;

/** Function that is responsibe for request/response tracking in IQ packets.
 * Each IQ set/get packet should have the response in other IQ result/error packet.
 * Both packet should have the same id attribute. Function saves in wmem_tree pairs of
 * packet id and struct xmpp_transaction_t.
 */
extern void xmpp_iq_reqresp_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info);

/** Function that is responsibe for jingle session tracking in IQ packets.
 * Function saves in wmem_tree pairs of packet's id and Jingle session's id.
 */
extern void xmpp_jingle_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info);

/** Function that is responsibe for ibb(in band bytestreams) session tracking in IQ packets.
 * Function saves in wmem_tree pairs of packet's id and In-Band Bytestreams session's id.
 */
extern void xmpp_ibb_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info);

/** Function that is responsibe for GTalk session(voice/video) tracking in IQ packets.
 * Function saves in wmem_tree pairs of packet's id and GTalk session's id.
 */
extern void xmpp_gtalk_session_track(packet_info *pinfo, xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info);

/** Function detects unrecognized elements and displays them in tree.
 * It uses ett_unknown to display packets. ett_unknown has const size described by
 * ETT_UNKNOWN_LEN in packet-xmpp.h
 */
extern void xmpp_unknown(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);

/** Displays CDATA from element in tree. You can use your own header field hf or
 * pass -1. If you pass -1 then CDATA will be display as text:
 * ELEMENT_NAME: CDATA
 * ELEMENT_NAME = element->name, if element is empty CDATA = "(empty)"
 */
extern void xmpp_cdata(proto_tree *tree, tvbuff_t *tvb, xmpp_element_t *element, gint hf);

/** Function is similar to xmpp_cdata. But it display items only as a text and it is
 * compatibile with function display_elems
 */
extern void xmpp_simple_cdata_elem(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);

/** Converts xml_frame_t struct to xmpp_element_t. Should be call with parent==NULL.
 */
extern xmpp_element_t* xmpp_xml_frame_to_element_t(packet_info *pinfo, xml_frame_t *xml_frame, xmpp_element_t *parent, tvbuff_t *tvb);

/** Frees all GLib structs in xmpp_element_t struct. Should be call only for root element.
 * It works recursively.
 */
extern void xmpp_element_t_tree_free(xmpp_element_t *root);

/** Allocs ephemeral memory for xmpp_array_t struct.*/
extern xmpp_array_t* xmpp_ep_init_array_t(wmem_allocator_t *pool, const gchar** array, gint len);

/*Allocs ephemeral memory for xmpp_attr_t struct*/
extern xmpp_attr_t* xmpp_ep_init_attr_t(wmem_allocator_t *pool, const gchar *value, gint offset, gint length);

/** steal_*
 * Functions searches and marks as read found elements.
 * If element is set as read, it is invisible for these functions.*/

extern xmpp_element_t* xmpp_steal_element_by_name(xmpp_element_t *packet, const gchar *name);
extern xmpp_element_t* xmpp_steal_element_by_names(xmpp_element_t *packet, const gchar **names, gint names_len);
extern xmpp_element_t* xmpp_steal_element_by_attr(xmpp_element_t *packet, const gchar *attr_name, const gchar *attr_value);
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);

/*Returns first child in element*/
extern xmpp_element_t* xmpp_get_first_element(xmpp_element_t *packet);

/*Converts element to string. Returns memory allocated from the given pool.*/
extern gchar* xmpp_element_to_string(wmem_allocator_t *pool, tvbuff_t *tvb, xmpp_element_t *element);

/* Returns attribute by name and set as read. If attrib is set as read, it may be found
 * one more time, but it is invisible for function xmpp_unknown_attrib*/
extern xmpp_attr_t* xmpp_get_attr(xmpp_element_t *element, const gchar* attr_name);

/*Function hides first element in tree.*/
extern void xmpp_proto_tree_hide_first_child(proto_tree *tree);

/*Function shows first element in tree.*/
extern void xmpp_proto_tree_show_first_child(proto_tree *tree);

/*Function returns item as text. Memory is allocated from the given pool.*/
extern gchar* proto_item_get_text(wmem_allocator_t *pool, proto_item *item);

/*Function returns struct that contains 3 strings. It is used to build xmpp_attr_info struct.*/
extern gpointer xmpp_name_attr_struct(wmem_allocator_t *pool, const gchar *name, const gchar *attr_name, const gchar *attr_value);

/** Function displays attributes from element in way described in attrs.
 * Elements that doesn't exist in attrs are displayed as text.
 * In XMPP_ATTR_INFO struct you can define several things:
 * - is_in_short_list - attribute should be displayed in short list e.g. ELEMENT_NAME [ATTR1='value' ATTR2='value']
 * - is_required - attribute is required. If attribute doesn't appear then EXPERT INFO will be displayed
 * - val_func - validate function
 * - data - data passes to the val_func
 */
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);

/** Function does the same as shown above. It takes attrs(XMPP_ATTR_INFO_EXT) argument
 * that contains XMPP_ATTR_INFO struct and string with namespace. It is used when packet
 * contains several namespaces and each attribute belongs to particular namespace.
 * E.g.
 * @code
 * <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
 *  mechanism='PLAIN'
 *  xmlns:ga='http://www.google.com/talk/protocol/auth'
 *  ga:client-uses-full-bind-result='true'>
 * </auth>
 * @endcode
 */
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);

/** Displays elements from parent element in a way described in elems(XMPP_ELEM_INFO).
 * XMPP_ELEM_INFO describes how to find particular element and what action should be done
 * for this element.
 * Function calls xmpp_unknown.
 */
extern void xmpp_display_elems(proto_tree *tree, xmpp_element_t *parent, packet_info *pinfo, tvbuff_t *tvb, xmpp_elem_info *elems, guint n);

/* Validates attribute value. Takes string array(gchar**) in parameter data.
 * Is used in XMPP_ATTR_INFO struct.
 */
extern void xmpp_val_enum_list(packet_info *pinfo, proto_item *item, const gchar *name, const gchar *value, gconstpointer data);

/** Function changes element to attribute. It searches element by name in parent element,
 * next it create attribute using transform_func and inserts it to parent attributes hash table
 * using attr_name as key.
 */
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));

/** transform_func that creates attribute with element's cdata as value
 */
extern xmpp_attr_t* xmpp_transform_func_cdata(wmem_allocator_t *pool, xmpp_element_t *elem);

#endif /* XMPP_UTILS_H */