Coverage Report

Created: 2026-03-30 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-xmpp-other.c
Line
Count
Source
1
/* packet-xmpp-other.c
2
 * Wireshark's XMPP dissector.
3
 *
4
 * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
16
#include <epan/packet.h>
17
#include "packet-xmpp.h"
18
#include "packet-xmpp-other.h"
19
20
static void xmpp_disco_items_item(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, xmpp_element_t *element);
21
22
static void xmpp_roster_item(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, xmpp_element_t *element);
23
24
static void xmpp_disco_info_identity(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, xmpp_element_t *element);
25
static void xmpp_disco_info_feature(proto_tree *tree, tvbuff_t *tvb, xmpp_element_t *element);
26
27
static void xmpp_bytestreams_streamhost(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
28
static void xmpp_bytestreams_streamhost_used(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
29
static void xmpp_bytestreams_activate(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
30
static void xmpp_bytestreams_udpsuccess(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
31
32
static void xmpp_si_file(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
33
static void xmpp_si_file_range(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
34
35
static void xmpp_x_data(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
36
37
static void xmpp_x_data_field(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
38
static void xmpp_x_data_field_option(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
39
static void xmpp_x_data_field_value(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
40
static void xmpp_x_data_instr(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
41
42
static void xmpp_muc_history(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
43
44
static void xmpp_muc_user_item(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
45
static void xmpp_muc_user_status(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
46
static void xmpp_muc_user_invite(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
47
48
static void xmpp_hashes_hash(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
49
50
static void xmpp_jitsi_inputevt_rmt_ctrl(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
51
52
static void xmpp_feature_neg(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
53
54
55
void
56
xmpp_iq_bind(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
57
0
{
58
0
    proto_item *bind_item;
59
0
    proto_tree *bind_tree;
60
61
0
    xmpp_attr_info attrs_info[] = {
62
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
63
0
        {"resource", &hf_xmpp_iq_bind_resource, false, true, NULL, NULL},
64
0
        {"jid", &hf_xmpp_iq_bind_jid, false, true, NULL, NULL}
65
0
    };
66
67
0
    col_append_str(pinfo->cinfo, COL_INFO, "BIND ");
68
69
0
    bind_item = proto_tree_add_item(tree, hf_xmpp_iq_bind, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
70
0
    bind_tree = proto_item_add_subtree(bind_item, ett_xmpp_iq_bind);
71
72
0
    xmpp_change_elem_to_attrib(pinfo->pool, "resource", "resource", element, xmpp_transform_func_cdata);
73
0
    xmpp_change_elem_to_attrib(pinfo->pool, "jid", "jid", element, xmpp_transform_func_cdata);
74
75
0
    xmpp_display_attrs(bind_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
76
77
0
    xmpp_unknown(bind_tree, tvb, pinfo, element);
78
0
}
79
80
void
81
xmpp_session(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
82
0
{
83
0
    proto_item *session_item;
84
0
    proto_tree *session_tree;
85
86
0
    xmpp_attr_info attrs_info [] = {
87
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL}
88
0
    };
89
90
0
    session_item = proto_tree_add_item(tree, hf_xmpp_iq_session, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
91
0
    session_tree = proto_item_add_subtree(session_item, ett_xmpp_iq_session);
92
93
0
    col_append_str(pinfo->cinfo, COL_INFO, "SESSION ");
94
95
0
    xmpp_display_attrs(session_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
96
0
    xmpp_display_elems(session_tree, element, pinfo, tvb, NULL, 0);
97
0
}
98
99
void
100
xmpp_vcard(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
101
0
{
102
0
    proto_item *vcard_item;
103
0
    proto_tree *vcard_tree;
104
105
0
    xmpp_attr_info attrs_info[] = {
106
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
107
0
        {"value", NULL, false, false, NULL, NULL}
108
0
    };
109
110
0
    xmpp_element_t *cdata;
111
112
0
    col_append_str(pinfo->cinfo, COL_INFO, "VCARD ");
113
114
0
    vcard_item = proto_tree_add_item(tree, hf_xmpp_vcard, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
115
0
    vcard_tree = proto_item_add_subtree(vcard_item, ett_xmpp_vcard);
116
117
0
    cdata = xmpp_get_first_element(element);
118
119
0
    if(cdata)
120
0
    {
121
0
        xmpp_attr_t *fake_cdata;
122
0
        fake_cdata = xmpp_ep_init_attr_t(pinfo->pool, xmpp_element_to_string(pinfo->pool, tvb, cdata), cdata->offset, cdata->length);
123
0
        g_hash_table_insert(element->attrs,(void *)"value", fake_cdata);
124
125
0
    }
126
0
    xmpp_display_attrs(vcard_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
127
128
0
}
129
130
void
131
xmpp_vcard_x_update(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
132
0
{
133
0
    proto_item *x_item;
134
0
    proto_tree *x_tree;
135
136
0
    xmpp_attr_info attrs_info[] = {
137
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
138
0
        {"photo", NULL, false, false, NULL, NULL}
139
0
    };
140
141
0
    xmpp_element_t *photo;
142
143
0
    x_item = proto_tree_add_item(tree, hf_xmpp_vcard_x_update, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
144
0
    x_tree = proto_item_add_subtree(x_item, ett_xmpp_vcard_x_update);
145
146
0
    if((photo = xmpp_steal_element_by_name(element, "photo"))!=NULL)
147
0
    {
148
0
        xmpp_attr_t *fake_photo = xmpp_ep_init_attr_t(pinfo->pool, photo->data?photo->data->value:"", photo->offset, photo->length);
149
0
        g_hash_table_insert(element->attrs, (void *)"photo", fake_photo);
150
0
    }
151
152
0
    xmpp_display_attrs(x_tree, element,pinfo, tvb, attrs_info, array_length(attrs_info));
153
154
0
    xmpp_unknown(x_tree, tvb, pinfo, element);
155
0
}
156
157
void
158
xmpp_disco_items_query(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, xmpp_element_t *element)
159
0
{
160
0
    proto_item *query_item;
161
0
    proto_tree *query_tree;
162
163
0
    xmpp_attr_info attrs_info[] = {
164
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
165
0
        {"node", &hf_xmpp_query_node, false, true, NULL, NULL}
166
0
    };
167
168
0
    xmpp_element_t *item;
169
170
0
    col_append_str(pinfo->cinfo, COL_INFO, "QUERY(disco#items) ");
171
172
0
    query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
173
0
    query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
174
175
0
    xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
176
177
0
    while((item = xmpp_steal_element_by_name(element, "item")) != NULL)
178
0
    {
179
0
        xmpp_disco_items_item(query_tree, tvb, pinfo, item);
180
0
    }
181
182
0
    xmpp_unknown(query_tree, tvb, pinfo, element);
183
0
}
184
185
static void
186
xmpp_disco_items_item(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, xmpp_element_t *element)
187
0
{
188
0
    proto_item *item_item;
189
0
    proto_tree *item_tree;
190
191
0
    xmpp_attr_info attrs_info[] = {
192
0
        {"jid", &hf_xmpp_query_item_jid, true, true, NULL, NULL},
193
0
        {"name", &hf_xmpp_query_item_name, false, true, NULL, NULL},
194
0
        {"node", &hf_xmpp_query_item_node, false, true, NULL, NULL}
195
0
    };
196
197
0
    item_item = proto_tree_add_item(tree, hf_xmpp_query_item, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
198
0
    item_tree = proto_item_add_subtree(item_item, ett_xmpp_query_item);
199
200
0
    xmpp_display_attrs(item_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
201
202
0
    xmpp_unknown(item_tree, tvb, pinfo, element);
203
0
}
204
205
void
206
xmpp_roster_query(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, xmpp_element_t *element)
207
0
{
208
0
    proto_item *query_item;
209
0
    proto_tree *query_tree;
210
211
0
    xmpp_attr_info attrs_info[] = {
212
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
213
0
        {"ver", NULL, false, true, NULL, NULL},
214
0
    };
215
216
0
    xmpp_elem_info elems_info[] = {
217
0
        {NAME, "item", xmpp_roster_item, MANY},
218
0
    };
219
220
0
    col_append_str(pinfo->cinfo, COL_INFO, "QUERY(jabber:iq:roster) ");
221
222
0
    query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
223
0
    query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
224
225
0
    xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
226
0
    xmpp_display_elems(query_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
227
0
}
228
229
static void
230
xmpp_roster_item(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, xmpp_element_t *element)
231
0
{
232
0
    proto_item *item_item;
233
0
    proto_tree *item_tree;
234
235
0
    static const char *ask_enums[] = {"subscribe"};
236
0
    static const char *subscription_enums[] = {"both", "from", "none", "remove", "to"};
237
238
0
    xmpp_array_t *ask_enums_array = xmpp_ep_init_array_t(pinfo->pool, ask_enums,array_length(ask_enums));
239
0
    xmpp_array_t *subscription_array = xmpp_ep_init_array_t(pinfo->pool, subscription_enums,array_length(subscription_enums));
240
241
0
    xmpp_attr_info attrs_info[] = {
242
0
        {"jid", &hf_xmpp_query_item_jid, true, true, NULL, NULL},
243
0
        {"name", &hf_xmpp_query_item_name, false, true, NULL, NULL},
244
0
        {"ask", &hf_xmpp_query_item_ask, false, true, xmpp_val_enum_list, ask_enums_array},
245
0
        {"approved", &hf_xmpp_query_item_approved, false, true, NULL, NULL},
246
0
        {"subscription", &hf_xmpp_query_item_subscription, false, true, xmpp_val_enum_list, subscription_array},
247
0
    };
248
249
0
    xmpp_element_t *group;
250
251
0
    item_item = proto_tree_add_item(tree, hf_xmpp_query_item, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
252
0
    item_tree = proto_item_add_subtree(item_item, ett_xmpp_query_item);
253
254
0
    xmpp_display_attrs(item_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
255
256
0
    while((group = xmpp_steal_element_by_name(element,"group"))!=NULL)
257
0
    {
258
0
        proto_tree_add_string(item_tree, hf_xmpp_query_item_group, tvb, group->offset, group->length, xmpp_elem_cdata(group));
259
0
    }
260
261
0
    xmpp_unknown(item_tree, tvb, pinfo, element);
262
0
}
263
264
void
265
xmpp_disco_info_query(proto_tree *tree,  tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
266
0
{
267
0
    proto_item *query_item;
268
0
    proto_tree *query_tree;
269
270
0
    xmpp_attr_info attrs_info[] = {
271
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
272
0
        {"node", &hf_xmpp_query_node, false, true, NULL, NULL}
273
0
    };
274
275
0
    xmpp_element_t *identity, *feature, *x_data;
276
277
0
    col_append_str(pinfo->cinfo, COL_INFO, "QUERY(disco#info) ");
278
279
0
    query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
280
0
    query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
281
282
0
    xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
283
284
285
0
    while((identity = xmpp_steal_element_by_name(element, "identity")) != NULL)
286
0
    {
287
0
        xmpp_disco_info_identity(query_tree, tvb, pinfo, identity);
288
0
    }
289
290
0
    while((feature = xmpp_steal_element_by_name(element, "feature")) != NULL)
291
0
    {
292
0
        xmpp_disco_info_feature(query_tree, tvb, feature);
293
0
    }
294
295
0
    if((x_data = xmpp_steal_element_by_name_and_attr(element, "x", "xmlns", "jabber:x:data")) != NULL)
296
0
    {
297
0
        xmpp_x_data(query_tree, tvb, pinfo, x_data);
298
0
    }
299
300
0
    xmpp_unknown(query_tree, tvb, pinfo, element);
301
0
}
302
303
static void
304
xmpp_disco_info_identity(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, xmpp_element_t *element)
305
0
{
306
0
    proto_item *identity_item;
307
0
    proto_tree *identity_tree;
308
309
0
    xmpp_attr_info attrs_info[] = {
310
0
        {"category", &hf_xmpp_query_identity_category, true, true, NULL, NULL},
311
0
        {"name", &hf_xmpp_query_identity_name, false, true, NULL, NULL},
312
0
        {"type", &hf_xmpp_query_identity_type, true, true, NULL, NULL}
313
0
    };
314
315
0
    identity_item = proto_tree_add_item(tree, hf_xmpp_query_identity, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
316
0
    identity_tree = proto_item_add_subtree(identity_item, ett_xmpp_query_identity);
317
318
0
    xmpp_display_attrs(identity_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
319
320
0
    xmpp_unknown(identity_tree, tvb, pinfo, element);
321
322
0
}
323
324
static void
325
xmpp_disco_info_feature(proto_tree *tree, tvbuff_t *tvb, xmpp_element_t *element)
326
0
{
327
328
0
    xmpp_attr_t *var = xmpp_get_attr(element, "var");
329
330
0
    if(var)
331
0
    {
332
0
        proto_tree_add_string_format(tree, hf_xmpp_query_feature, tvb, var->offset, var->length, var->value, "FEATURE [%s]", var->value);
333
0
    }
334
0
}
335
336
void
337
xmpp_bytestreams_query(proto_tree *tree,  tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
338
0
{
339
0
    proto_item *query_item;
340
0
    proto_tree *query_tree;
341
342
0
    static const char *mode_enums[] = {"tcp", "udp"};
343
0
    xmpp_array_t *mode_array = xmpp_ep_init_array_t(pinfo->pool, mode_enums, array_length(mode_enums));
344
345
0
    xmpp_attr_info attrs_info[] = {
346
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
347
0
        {"sid", NULL, false, true, NULL, NULL},
348
0
        {"mode", NULL, false, true, xmpp_val_enum_list, mode_array},
349
0
        {"dstaddr", NULL, false, true, NULL, NULL}
350
0
    };
351
352
0
    xmpp_element_t *streamhost, *streamhost_used, *activate, *udpsuccess;
353
354
0
    col_append_str(pinfo->cinfo, COL_INFO, "QUERY(bytestreams) ");
355
356
0
    query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
357
0
    query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
358
359
0
    xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
360
361
362
0
    while((streamhost = xmpp_steal_element_by_name(element, "streamhost")) != NULL)
363
0
    {
364
0
        xmpp_bytestreams_streamhost(query_tree, tvb, pinfo, streamhost);
365
0
    }
366
367
0
    if((streamhost_used = xmpp_steal_element_by_name(element, "streamhost-used")) != NULL)
368
0
    {
369
0
        xmpp_bytestreams_streamhost_used(query_tree, tvb, pinfo, streamhost_used);
370
0
    }
371
372
0
    if((activate = xmpp_steal_element_by_name(element, "activate")) != NULL)
373
0
    {
374
0
        xmpp_bytestreams_activate(query_tree, tvb, pinfo, activate);
375
0
    }
376
377
0
    if((udpsuccess = xmpp_steal_element_by_name(element, "udpsuccess")) != NULL)
378
0
    {
379
0
        xmpp_bytestreams_udpsuccess(query_tree, tvb, pinfo, udpsuccess);
380
0
    }
381
382
0
    xmpp_unknown(query_tree, tvb, pinfo, element);
383
0
}
384
385
static void
386
xmpp_bytestreams_streamhost(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
387
0
{
388
0
    proto_item *sh_item;
389
0
    proto_tree *sh_tree;
390
391
0
    xmpp_attr_info attrs_info[] = {
392
0
        {"jid", NULL, true, true, NULL, NULL},
393
0
        {"host", NULL, true, true, NULL, NULL},
394
0
        {"port", NULL, false, true, NULL, NULL}
395
0
    };
396
397
0
    sh_item = proto_tree_add_item(tree, hf_xmpp_query_streamhost, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
398
0
    sh_tree = proto_item_add_subtree(sh_item, ett_xmpp_query_streamhost);
399
400
0
    xmpp_display_attrs(sh_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
401
402
0
    xmpp_unknown(sh_tree, tvb, pinfo, element);
403
0
}
404
405
static void
406
xmpp_bytestreams_streamhost_used(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
407
0
{
408
0
    proto_item *shu_item;
409
0
    proto_tree *shu_tree;
410
411
0
    xmpp_attr_info attrs_info[] = {
412
0
        {"jid", NULL, true, true, NULL, NULL}
413
0
    };
414
415
0
    shu_item = proto_tree_add_item(tree, hf_xmpp_query_streamhost_used, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
416
0
    shu_tree = proto_item_add_subtree(shu_item, ett_xmpp_query_streamhost_used);
417
418
0
    xmpp_display_attrs(shu_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
419
420
0
    xmpp_unknown(shu_tree, tvb, pinfo, element);
421
0
}
422
423
static void
424
xmpp_bytestreams_activate(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
425
0
{
426
0
    proto_tree_add_string(tree, hf_xmpp_query_activate, tvb, element->offset, element->length, xmpp_elem_cdata(element));
427
0
    xmpp_unknown(tree, tvb, pinfo, element);
428
0
}
429
430
static void
431
xmpp_bytestreams_udpsuccess(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
432
0
{
433
0
    proto_item *udps_item;
434
0
    proto_tree *udps_tree;
435
436
0
    xmpp_attr_info attrs_info[] = {
437
0
        {"dstaddr", NULL, true, true, NULL, NULL}
438
0
    };
439
440
0
    udps_item = proto_tree_add_item(tree, hf_xmpp_query_udpsuccess, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
441
0
    udps_tree =proto_item_add_subtree(udps_item, ett_xmpp_query_udpsuccess);
442
443
0
    xmpp_display_attrs(udps_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
444
445
0
    xmpp_unknown(udps_tree, tvb, pinfo, element);
446
0
}
447
448
449
450
/*SI File Transfer*/
451
void
452
xmpp_si(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
453
0
{
454
0
    proto_item *si_item;
455
0
    proto_tree *si_tree;
456
457
0
    xmpp_attr_info attrs_info[] = {
458
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
459
0
        {"id", NULL, false, false, NULL, NULL},
460
0
        {"mime-type", NULL, false, true, NULL, NULL},
461
0
        {"profile", NULL, false, true, NULL, NULL}
462
0
    };
463
464
0
    xmpp_element_t *file, *feature_neg;
465
466
0
    col_append_str(pinfo->cinfo, COL_INFO, "SI ");
467
468
0
    si_item = proto_tree_add_item(tree, hf_xmpp_si, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
469
0
    si_tree = proto_item_add_subtree(si_item, ett_xmpp_si);
470
471
0
    xmpp_display_attrs(si_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
472
473
0
    while((file = xmpp_steal_element_by_name(element, "file"))!=NULL)
474
0
    {
475
0
        xmpp_si_file(si_tree, tvb, pinfo, file);
476
0
    }
477
478
0
    while((feature_neg = xmpp_steal_element_by_name(element, "feature"))!=NULL)
479
0
    {
480
0
        xmpp_feature_neg(si_tree, tvb, pinfo, feature_neg);
481
0
    }
482
483
484
485
0
    xmpp_unknown(si_tree, tvb, pinfo, element);
486
0
}
487
488
static void
489
xmpp_si_file(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
490
0
{
491
0
    proto_item *file_item;
492
0
    proto_tree *file_tree;
493
494
0
    xmpp_attr_info attrs_info[] = {
495
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
496
0
        {"name", NULL, true, true, NULL, NULL},
497
0
        {"size", NULL, true, true, NULL, NULL},
498
0
        {"date", NULL, false, false, NULL, NULL},
499
0
        {"hash", NULL, false, false, NULL, NULL},
500
0
        {"desc", NULL, false, false, NULL, NULL}
501
0
    };
502
503
0
    xmpp_element_t *desc, *range;
504
505
0
    file_item = proto_tree_add_item(tree, hf_xmpp_si_file, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
506
0
    file_tree = proto_item_add_subtree(file_item, ett_xmpp_si_file);
507
508
0
    if((desc = xmpp_steal_element_by_name(element, "desc"))!=NULL)
509
0
    {
510
0
         xmpp_attr_t *fake_desc = xmpp_ep_init_attr_t(pinfo->pool, desc->data?desc->data->value:"", desc->offset, desc->length);
511
0
         g_hash_table_insert(element->attrs, (void *)"desc", fake_desc);
512
0
    }
513
514
0
    if((range = xmpp_steal_element_by_name(element, "range"))!=NULL)
515
0
    {
516
0
        xmpp_si_file_range(file_tree, tvb, pinfo, range);
517
0
    }
518
519
0
    xmpp_display_attrs(file_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
520
521
0
    xmpp_unknown(file_tree, tvb, pinfo, element);
522
0
}
523
524
static void
525
xmpp_si_file_range(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
526
0
{
527
0
    proto_tree *range_tree;
528
529
0
    xmpp_attr_info attrs_info[] = {
530
0
        {"offset", NULL, false, true, NULL, NULL},
531
0
        {"length", NULL, false, true, NULL, NULL}
532
0
    };
533
534
0
    range_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_si_file_range, NULL, "RANGE: ");
535
536
0
    xmpp_display_attrs(range_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
537
538
0
    xmpp_unknown(range_tree, tvb, pinfo, element);
539
540
0
}
541
542
/*Feature Negotiation*/
543
static void
544
xmpp_feature_neg(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
545
0
{
546
0
    proto_item *feature_item;
547
0
    proto_tree *feature_tree;
548
549
0
    xmpp_attr_info attrs_info[] = {
550
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL}
551
0
    };
552
553
0
    xmpp_element_t *x_data;
554
555
0
    feature_item = proto_tree_add_item(tree, hf_xmpp_iq_feature_neg, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
556
0
    feature_tree = proto_item_add_subtree(feature_item, ett_xmpp_iq_feature_neg);
557
558
0
    xmpp_display_attrs(feature_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
559
560
0
    while((x_data = xmpp_steal_element_by_name_and_attr(element, "x", "xmlns", "jabber:x:data"))!=NULL)
561
0
    {
562
0
        xmpp_x_data(feature_tree, tvb, pinfo, x_data);
563
0
    }
564
565
0
    xmpp_unknown(feature_tree, tvb, pinfo, element);
566
0
}
567
568
569
/*jabber:x:data*/
570
static void
571
xmpp_x_data(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
572
0
{
573
0
    proto_item *x_item;
574
0
    proto_tree *x_tree;
575
576
0
    static const char *type_enums[] = {"cancel", "form", "result", "submit"};
577
0
    xmpp_array_t *type_array = xmpp_ep_init_array_t(pinfo->pool, type_enums, array_length(type_enums));
578
579
0
    xmpp_attr_info attrs_info[] = {
580
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
581
0
        {"type", NULL, true, true, xmpp_val_enum_list, type_array},
582
0
        {"TITLE", NULL, false, true, NULL, NULL}
583
0
    };
584
585
0
    xmpp_elem_info elems_info[] = {
586
0
        {NAME, "instructions", xmpp_x_data_instr, MANY},
587
0
        {NAME, "field", xmpp_x_data_field, MANY},
588
0
    };
589
    /*TODO reported, item*/
590
591
0
    x_item = proto_tree_add_item(tree, hf_xmpp_x_data, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
592
0
    x_tree = proto_item_add_subtree(x_item, ett_xmpp_x_data);
593
594
0
    xmpp_change_elem_to_attrib(pinfo->pool, "title", "TITLE", element, xmpp_transform_func_cdata);
595
596
0
    xmpp_display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
597
0
    xmpp_display_elems(x_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
598
0
}
599
600
static void
601
xmpp_x_data_field(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
602
0
{
603
0
    proto_item *field_item;
604
0
    proto_tree *field_tree;
605
606
0
    static const char *type_enums[] = {"boolean", "fixed", "hidden", "jid-multi",
607
0
        "jid-single", "list-multi", "list-single", "text-multi", "text-single",
608
0
        "text-private"
609
0
    };
610
0
    xmpp_array_t *type_array = xmpp_ep_init_array_t(pinfo->pool, type_enums, array_length(type_enums));
611
612
0
    xmpp_attr_info attrs_info[] = {
613
0
        {"label", NULL, false, true, NULL, NULL},
614
0
        {"type", NULL, false, true, xmpp_val_enum_list, type_array},
615
0
        {"var", NULL, false, true, NULL, NULL}
616
0
    };
617
618
0
    xmpp_element_t /**desc, *required,*/ *value, *option;
619
620
0
    field_item = proto_tree_add_item(tree, hf_xmpp_x_data_field, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
621
0
    field_tree = proto_item_add_subtree(field_item, ett_xmpp_x_data_field);
622
623
0
    xmpp_display_attrs(field_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
624
625
0
    while((option = xmpp_steal_element_by_name(element, "option"))!=NULL)
626
0
    {
627
0
        xmpp_x_data_field_option(field_tree, tvb, pinfo, option);
628
0
    }
629
630
0
    while((value = xmpp_steal_element_by_name(element, "value"))!=NULL)
631
0
    {
632
0
        xmpp_x_data_field_value(field_tree, tvb, pinfo, value);
633
0
    }
634
635
0
    xmpp_unknown(field_item, tvb, pinfo, element);
636
637
0
}
638
639
static void
640
xmpp_x_data_field_option(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
641
0
{
642
0
    proto_item *option_item;
643
0
    proto_tree *option_tree;
644
645
0
    xmpp_attr_info attrs_info[] = {
646
0
        {"label", NULL, false, true, NULL, NULL},
647
0
        {"value", NULL, false, true, NULL, NULL}
648
0
    };
649
650
0
    xmpp_element_t *value;
651
652
0
    option_item = proto_tree_add_item(tree, hf_xmpp_x_data_field_value, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
653
0
    option_tree = proto_item_add_subtree(option_item, ett_xmpp_x_data_field_value);
654
655
0
    if((value = xmpp_steal_element_by_name(element, "value"))!=NULL)
656
0
    {
657
0
        xmpp_attr_t *fake_value = xmpp_ep_init_attr_t(pinfo->pool, value->data?value->data->value:"",value->offset, value->length);
658
0
        g_hash_table_insert(element->attrs, (void *)"value", fake_value);
659
0
    }
660
661
0
    xmpp_display_attrs(option_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
662
663
0
    xmpp_unknown(option_tree, tvb, pinfo, element);
664
0
}
665
666
static void
667
xmpp_x_data_field_value(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
668
0
{
669
0
    proto_item *value_item;
670
0
    proto_tree *value_tree;
671
672
0
    xmpp_attr_info attrs_info[] = {
673
0
        {"label", NULL, false, true, NULL, NULL},
674
0
        {"value", NULL, true, true, NULL, NULL}
675
0
    };
676
0
    xmpp_attr_t *fake_value;
677
678
0
    value_item = proto_tree_add_item(tree, hf_xmpp_x_data_field_value, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
679
0
    value_tree = proto_item_add_subtree(value_item, ett_xmpp_x_data_field_value);
680
681
682
683
0
   fake_value = xmpp_ep_init_attr_t(pinfo->pool, element->data?element->data->value:"",element->offset, element->length);
684
0
   g_hash_table_insert(element->attrs, (void *)"value", fake_value);
685
686
687
0
    xmpp_display_attrs(value_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
688
689
0
    xmpp_unknown(value_tree, tvb, pinfo, element);
690
0
}
691
692
static void
693
xmpp_x_data_instr(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo _U_, xmpp_element_t* element)
694
0
{
695
0
    proto_tree_add_string(tree, hf_xmpp_x_data_instructions, tvb, element->offset, element->length, xmpp_elem_cdata(element));
696
0
}
697
698
/*In-Band Bytestreams*/
699
void
700
xmpp_ibb_open(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
701
0
{
702
0
    proto_item *open_item;
703
0
    proto_tree *open_tree;
704
705
0
    static const char *stanza_enums[] = {"iq", "message"};
706
0
    xmpp_array_t *stanza_array = xmpp_ep_init_array_t(pinfo->pool, stanza_enums, array_length(stanza_enums));
707
708
0
    xmpp_attr_info attrs_info[] = {
709
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
710
0
        {"sid", NULL, true, true, NULL, NULL},
711
0
        {"block-size", NULL, true, true, NULL, NULL},
712
0
        {"stanza", NULL, false, true, xmpp_val_enum_list, stanza_array}
713
0
    };
714
715
0
    col_append_str(pinfo->cinfo, COL_INFO, "IBB-OPEN ");
716
717
0
    open_item = proto_tree_add_item(tree, hf_xmpp_ibb_open, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
718
0
    open_tree = proto_item_add_subtree(open_item, ett_xmpp_ibb_open);
719
720
0
    xmpp_display_attrs(open_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
721
0
    xmpp_unknown(open_tree, tvb, pinfo, element);
722
0
}
723
724
void
725
xmpp_ibb_close(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
726
0
{
727
0
    proto_item *close_item;
728
0
    proto_tree *close_tree;
729
730
0
    xmpp_attr_info attrs_info[] = {
731
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
732
0
        {"sid", NULL, true, true, NULL, NULL}
733
0
    };
734
735
0
    col_append_str(pinfo->cinfo, COL_INFO, "IBB-CLOSE ");
736
737
0
    close_item = proto_tree_add_item(tree, hf_xmpp_ibb_close, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
738
0
    close_tree = proto_item_add_subtree(close_item, ett_xmpp_ibb_close);
739
740
0
    xmpp_display_attrs(close_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
741
0
    xmpp_unknown(close_tree, tvb, pinfo, element);
742
0
}
743
744
void
745
xmpp_ibb_data(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
746
0
{
747
0
    proto_item *data_item;
748
0
    proto_tree *data_tree;
749
750
0
    xmpp_attr_info attrs_info[] = {
751
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
752
0
        {"sid", NULL, true, true, NULL, NULL},
753
0
        {"seq", NULL, true, true, NULL, NULL},
754
0
        {"value", NULL, false, false, NULL, NULL}
755
0
    };
756
757
0
    col_append_str(pinfo->cinfo, COL_INFO, "IBB-DATA ");
758
759
0
    data_item = proto_tree_add_item(tree, hf_xmpp_ibb_data, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
760
0
    data_tree = proto_item_add_subtree(data_item, ett_xmpp_ibb_data);
761
762
0
    if(element->data)
763
0
    {
764
0
        xmpp_attr_t *fake_data = xmpp_ep_init_attr_t(pinfo->pool, element->data->value, element->offset, element->length);
765
0
        g_hash_table_insert(element->attrs, (void *)"value", fake_data);
766
0
    }
767
768
0
    xmpp_display_attrs(data_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
769
0
    xmpp_unknown(data_tree, tvb, pinfo, element);
770
0
}
771
772
773
/*Delayed Delivery urn:xmpp:delay and jabber:x:delay*/
774
void
775
xmpp_delay(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
776
0
{
777
0
    proto_item *delay_item;
778
0
    proto_tree *delay_tree;
779
780
0
    xmpp_attr_info attrs_info[]={
781
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
782
0
        {"from", NULL, false, true, NULL, NULL},
783
0
        {"stamp", NULL, true, true, NULL, NULL},
784
0
        {"value", NULL, false, true, NULL, NULL}
785
0
    };
786
787
0
    delay_item = proto_tree_add_item(tree, hf_xmpp_delay, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
788
0
    delay_tree = proto_item_add_subtree(delay_item, ett_xmpp_delay);
789
790
0
    if(element->data)
791
0
    {
792
0
        xmpp_attr_t *fake_value = xmpp_ep_init_attr_t(pinfo->pool, element->data->value, element->offset, element->length);
793
0
        g_hash_table_insert(element->attrs, (void *)"value", fake_value);
794
0
    }
795
796
0
    xmpp_display_attrs(delay_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
797
798
0
    xmpp_unknown(delay_tree, tvb, pinfo, element);
799
0
}
800
801
/*Entity Capabilities http://jabber.org/protocol/caps*/
802
void
803
xmpp_presence_caps(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
804
0
{
805
0
    proto_item *caps_item;
806
0
    proto_tree *caps_tree;
807
808
0
    xmpp_attr_info attrs_info[] = {
809
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
810
0
        {"ext", NULL, false, false, NULL, NULL},
811
0
        {"hash", NULL, true, true, NULL, NULL},
812
0
        {"node", NULL, true, true, NULL, NULL},
813
0
        {"ver", NULL, true, false, NULL, NULL}
814
0
    };
815
816
0
    caps_item = proto_tree_add_item(tree, hf_xmpp_presence_caps, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
817
0
    caps_tree = proto_item_add_subtree(caps_item, ett_xmpp_presence_caps);
818
819
0
    xmpp_display_attrs(caps_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
820
821
0
    xmpp_unknown(caps_tree, tvb, pinfo, element);
822
0
}
823
824
/*Message Events jabber:x:event*/
825
void
826
xmpp_x_event(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
827
0
{
828
0
    proto_item *x_item;
829
0
    proto_tree *x_tree;
830
831
0
    xmpp_attr_info attrs_info[] = {
832
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
833
0
        {"condition", &hf_xmpp_x_event_condition, true, true, NULL, NULL},
834
0
        {"id", NULL, false, true, NULL, NULL}
835
0
    };
836
837
0
    static const char *cond_names[] = {"offline", "delivered", "displayed", "composing"};
838
839
0
    xmpp_attr_t *fake_cond;
840
841
0
    xmpp_element_t *cond, *id;
842
843
0
    char *cond_value = wmem_strdup(pinfo->pool, "");
844
845
0
    x_item =  proto_tree_add_item(tree, hf_xmpp_x_event, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
846
0
    x_tree = proto_item_add_subtree(x_item, ett_xmpp_x_event);
847
848
0
    if((id = xmpp_steal_element_by_name(element, "id"))!=NULL)
849
0
    {
850
0
        xmpp_attr_t *fake_id = xmpp_ep_init_attr_t(pinfo->pool, id->data?id->data->value:"", id->offset, id->length);
851
0
        g_hash_table_insert(element->attrs, (void *)"id", fake_id);
852
0
    }
853
854
0
    while((cond = xmpp_steal_element_by_names(element, cond_names, array_length(cond_names))) != NULL)
855
0
    {
856
0
        if(strcmp(cond_value,"") != 0)
857
0
            cond_value = wmem_strdup_printf(pinfo->pool, "%s/%s",cond_value, cond->name);
858
0
        else
859
0
            cond_value = wmem_strdup(pinfo->pool, cond->name);
860
0
    }
861
862
0
    fake_cond = xmpp_ep_init_attr_t(pinfo->pool, cond_value, element->offset, element->length);
863
0
    g_hash_table_insert(element->attrs, (void *)"condition", fake_cond);
864
865
866
0
    xmpp_display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
867
868
0
    xmpp_unknown(x_tree, tvb, pinfo, element);
869
0
}
870
871
/*Multi-User Chat http://jabber.org/protocol/muc*/
872
void
873
xmpp_muc_x(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
874
0
{
875
0
    proto_item *x_item;
876
0
    proto_tree *x_tree;
877
878
0
    xmpp_attr_info attrs_info [] ={
879
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
880
0
        {"password", NULL, false, true, NULL, NULL}
881
0
    };
882
883
0
    xmpp_element_t *pass, *hist;
884
885
0
    x_item = proto_tree_add_item(tree, hf_xmpp_muc_x, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
886
0
    x_tree = proto_item_add_subtree(x_item, ett_xmpp_muc_x);
887
888
0
    if((pass = xmpp_steal_element_by_name(element, "password"))!=NULL)
889
0
    {
890
0
        xmpp_attr_t *fake_pass = xmpp_ep_init_attr_t(pinfo->pool, pass->data?pass->data->value:"",pass->offset, pass->length);
891
0
        g_hash_table_insert(element->attrs, (void *)"password", fake_pass);
892
0
    }
893
894
0
    xmpp_display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
895
896
0
    if((hist = xmpp_steal_element_by_name(element, "history"))!=NULL)
897
0
    {
898
0
        xmpp_muc_history(x_tree, tvb, pinfo, hist);
899
0
    }
900
901
0
    xmpp_unknown(x_tree, tvb, pinfo, element);
902
0
}
903
904
static void
905
xmpp_muc_history(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
906
0
{
907
0
    proto_tree *hist_tree;
908
909
0
    xmpp_attr_info attrs_info[] = {
910
0
        {"maxchars", NULL, false, true, NULL, NULL},
911
0
        {"maxstanzas", NULL, false, true, NULL, NULL},
912
0
        {"seconds", NULL, false, true, NULL, NULL},
913
0
        {"since", NULL, false, true, NULL, NULL}
914
0
    };
915
916
0
    hist_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_muc_hist, NULL, "HISTORY: ");
917
918
0
    xmpp_display_attrs(hist_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
919
920
0
    xmpp_unknown(hist_tree, tvb, pinfo, element);
921
0
}
922
923
/*Multi-User Chat http://jabber.org/protocol/muc#user*/
924
void
925
xmpp_muc_user_x(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
926
0
{
927
0
    proto_item *x_item;
928
0
    proto_tree *x_tree;
929
930
0
    xmpp_attr_info attrs_info[] = {
931
0
        {"xmlns", &hf_xmpp_xmlns, true, false, NULL, NULL},
932
0
        {"password", NULL, false, true, NULL, NULL}
933
0
    };
934
935
0
    xmpp_element_t *item, *status, *invite, *password;
936
    /*TODO decline destroy*/
937
938
0
    x_item = proto_tree_add_item(tree, hf_xmpp_muc_user_x, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
939
0
    x_tree = proto_item_add_subtree(x_item, ett_xmpp_muc_user_x);
940
941
0
    if((password = xmpp_steal_element_by_name(element, "password"))!=NULL)
942
0
    {
943
0
        xmpp_attr_t *fake_pass = xmpp_ep_init_attr_t(pinfo->pool, password->data?password->data->value:"",password->offset, password->length);
944
0
        g_hash_table_insert(element->attrs, (void *)"password", fake_pass);
945
0
    }
946
947
0
    xmpp_display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
948
949
0
    while((item = xmpp_steal_element_by_name(element, "item"))!=NULL)
950
0
    {
951
0
        xmpp_muc_user_item(x_tree, tvb, pinfo, item);
952
0
    }
953
954
0
    while((status = xmpp_steal_element_by_name(element, "status"))!=NULL)
955
0
    {
956
0
        xmpp_muc_user_status(x_tree, tvb, pinfo, status);
957
0
    }
958
959
0
    while((invite = xmpp_steal_element_by_name(element, "invite"))!=NULL)
960
0
    {
961
0
        xmpp_muc_user_invite(x_tree, tvb, pinfo, invite);
962
0
    }
963
964
0
    xmpp_unknown(x_tree, tvb, pinfo, element);
965
0
}
966
967
static void
968
xmpp_muc_user_item(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
969
0
{
970
0
    proto_item *item_item;
971
0
    proto_tree *item_tree;
972
973
0
    static const char *affiliation_enums[] = {"admin", "member", "none", "outcast", "owner"};
974
0
    xmpp_array_t  *affil_array = xmpp_ep_init_array_t(pinfo->pool, affiliation_enums, array_length(affiliation_enums));
975
976
0
    static const char *role_enums[] = {"none", "moderator", "participant", "visitor"};
977
0
    xmpp_array_t *role_array = xmpp_ep_init_array_t(pinfo->pool, role_enums, array_length(role_enums));
978
979
0
    xmpp_attr_info attrs_info [] ={
980
0
        {"affiliation", NULL, false, true, xmpp_val_enum_list, affil_array},
981
0
        {"jid", NULL, false, true, NULL, NULL},
982
0
        {"nick", NULL, false, true, NULL, NULL},
983
0
        {"role", NULL, false, true, xmpp_val_enum_list, role_array},
984
0
        {"reason", NULL, false, true, NULL, NULL},
985
0
        {"actor_jid", NULL, false, true, NULL, NULL}
986
0
    };
987
988
0
    xmpp_element_t *reason, *actor;
989
    /*TODO continue - it's not clear to me, in schema it's marked as empty, but in examples it has CDATA*/
990
991
0
    item_item = proto_tree_add_item(tree, hf_xmpp_muc_user_item, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
992
0
    item_tree = proto_item_add_subtree(item_item, ett_xmpp_muc_user_item);
993
994
0
    if((reason = xmpp_steal_element_by_name(element, "reason"))!=NULL)
995
0
    {
996
0
        xmpp_attr_t *fake_reason = xmpp_ep_init_attr_t(pinfo->pool, reason->data?reason->data->value:"",reason->offset, reason->length);
997
0
        g_hash_table_insert(element->attrs,(void *)"reason",fake_reason);
998
0
    }
999
1000
0
    if((actor = xmpp_steal_element_by_name(element, "actor"))!=NULL)
1001
0
    {
1002
0
        xmpp_attr_t *jid = xmpp_get_attr(actor, "jid");
1003
0
        xmpp_attr_t *fake_actor_jid = xmpp_ep_init_attr_t(pinfo->pool, jid?jid->value:"",actor->offset, actor->length);
1004
0
        g_hash_table_insert(element->attrs, (void *)"actor_jid", fake_actor_jid);
1005
0
    }
1006
1007
0
    xmpp_display_attrs(item_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1008
1009
0
    xmpp_unknown(item_tree, tvb, pinfo, element);
1010
0
}
1011
1012
static void
1013
xmpp_muc_user_status(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1014
0
{
1015
0
    xmpp_attr_t *code = xmpp_get_attr(element, "code");
1016
0
    proto_tree_add_string_format(tree, hf_xmpp_muc_user_status, tvb, element->offset, element->length,
1017
0
                                  code?code->value:"", "STATUS [code=\"%s\"]", code?code->value:"");
1018
1019
0
    xmpp_unknown(tree, tvb, pinfo, element);
1020
0
}
1021
1022
static void
1023
xmpp_muc_user_invite(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1024
0
{
1025
0
    proto_item *invite_item;
1026
0
    proto_tree *invite_tree;
1027
1028
0
    xmpp_attr_info attrs_info[] = {
1029
0
        {"from", NULL, false, true, NULL, NULL},
1030
0
        {"to", NULL, false, true, NULL, NULL},
1031
0
        {"reason", NULL, false, true, NULL, NULL}
1032
0
    };
1033
1034
0
    xmpp_element_t *reason;
1035
1036
0
    invite_item = proto_tree_add_item(tree, hf_xmpp_muc_user_invite, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1037
0
    invite_tree = proto_item_add_subtree(invite_item, ett_xmpp_muc_user_invite);
1038
1039
0
    if((reason = xmpp_steal_element_by_name(element, "reason"))!=NULL)
1040
0
    {
1041
0
        xmpp_attr_t *fake_reason = xmpp_ep_init_attr_t(pinfo->pool, reason->data?reason->data->value:"",reason->offset, reason->length);
1042
0
        g_hash_table_insert(element->attrs, (void *)"reason", fake_reason);
1043
0
    }
1044
1045
0
    xmpp_display_attrs(invite_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1046
1047
0
    xmpp_unknown(invite_tree, tvb, pinfo, element);
1048
0
}
1049
1050
/*Multi-User Chat http://jabber.org/protocol/muc#owner*/
1051
void
1052
xmpp_muc_owner_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1053
0
{
1054
0
    proto_item *query_item;
1055
0
    proto_tree *query_tree;
1056
1057
0
    xmpp_attr_info attrs_info[] = {
1058
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL}
1059
0
    };
1060
1061
0
    xmpp_element_t *x_data;
1062
    /*TODO destroy*/
1063
1064
0
    col_append_str(pinfo->cinfo, COL_INFO, "QUERY(muc#owner) ");
1065
1066
0
    query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1067
0
    query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
1068
1069
0
    xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1070
1071
0
    if((x_data = xmpp_steal_element_by_name_and_attr(element, "x", "xmlns", "jabber:x:data"))!=NULL)
1072
0
    {
1073
0
        xmpp_x_data(query_tree, tvb, pinfo, x_data);
1074
0
    }
1075
1076
0
    xmpp_unknown(query_tree, tvb, pinfo, element);
1077
1078
0
}
1079
1080
/*Multi-User Chat http://jabber.org/protocol/muc#admin*/
1081
void
1082
xmpp_muc_admin_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1083
0
{
1084
0
    proto_item *query_item;
1085
0
    proto_tree *query_tree;
1086
1087
0
    xmpp_attr_info attrs_info[] = {
1088
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL}
1089
0
    };
1090
1091
0
    xmpp_element_t *item;
1092
1093
0
    col_append_str(pinfo->cinfo, COL_INFO, "QUERY(muc#admin) ");
1094
1095
0
    query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1096
0
    query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
1097
1098
0
    xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1099
1100
0
    while((item = xmpp_steal_element_by_name(element, "item"))!=NULL)
1101
0
    {
1102
        /*from muc#user, because it is the same except continue element*/
1103
0
        xmpp_muc_user_item(query_tree, tvb, pinfo, item);
1104
0
    }
1105
1106
0
    xmpp_unknown(query_tree, tvb, pinfo, element);
1107
0
}
1108
1109
/*Last Activity jabber:iq:last*/
1110
void
1111
xmpp_last_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1112
0
{
1113
0
    proto_item *query_item;
1114
0
    proto_tree *query_tree;
1115
1116
0
    xmpp_attr_info attrs_info[] = {
1117
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
1118
0
        {"seconds", NULL, false, true, NULL, NULL},
1119
0
        {"value", NULL, false, true, NULL, NULL}
1120
0
    };
1121
1122
0
    col_append_str(pinfo->cinfo, COL_INFO, "QUERY(jabber:iq:last) ");
1123
1124
0
    query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1125
0
    query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
1126
1127
0
    if(element->data)
1128
0
    {
1129
0
        xmpp_attr_t *fake_data = xmpp_ep_init_attr_t(pinfo->pool, element->data->value, element->data->offset, element->data->length);
1130
0
        g_hash_table_insert(element->attrs, (void *)"value", fake_data);
1131
0
    }
1132
1133
0
    xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1134
0
    xmpp_display_elems(query_tree, element, pinfo, tvb, NULL, 0);
1135
0
}
1136
1137
/*XEP-0092: Software Version jabber:iq:version*/
1138
void
1139
xmpp_version_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1140
0
{
1141
0
    proto_item *query_item;
1142
0
    proto_tree *query_tree;
1143
1144
0
    xmpp_attr_info attrs_info[] = {
1145
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
1146
0
        {"name", NULL, false, true, NULL, NULL},
1147
0
        {"version", NULL, false, true, NULL, NULL},
1148
0
        {"os", NULL, false, true, NULL, NULL}
1149
0
    };
1150
1151
0
    xmpp_element_t *name, *version, *os;
1152
1153
0
    col_append_str(pinfo->cinfo, COL_INFO, "QUERY(jabber:iq:version) ");
1154
1155
0
    query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1156
0
    query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
1157
1158
0
    if((name = xmpp_steal_element_by_name(element,"name"))!=NULL)
1159
0
    {
1160
0
        xmpp_attr_t *fake_name = xmpp_ep_init_attr_t(pinfo->pool, name->data?name->data->value:"", name->offset, name->length);
1161
0
        g_hash_table_insert(element->attrs, (void *)"name", fake_name);
1162
0
    }
1163
1164
0
    if((version = xmpp_steal_element_by_name(element,"version"))!=NULL)
1165
0
    {
1166
0
        xmpp_attr_t *fake_version = xmpp_ep_init_attr_t(pinfo->pool, version->data?version->data->value:"", version->offset, version->length);
1167
0
        g_hash_table_insert(element->attrs, (void *)"version", fake_version);
1168
0
    }
1169
1170
0
    if((os = xmpp_steal_element_by_name(element,"os"))!=NULL)
1171
0
    {
1172
0
        xmpp_attr_t *fake_os = xmpp_ep_init_attr_t(pinfo->pool, os->data?os->data->value:"", os->offset, os->length);
1173
0
        g_hash_table_insert(element->attrs, (void *)"os", fake_os);
1174
0
    }
1175
1176
0
    xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1177
0
    xmpp_display_elems(query_tree, element, pinfo, tvb, NULL, 0);
1178
0
}
1179
/*XEP-0199: XMPP Ping*/
1180
void
1181
xmpp_ping(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1182
0
{
1183
0
    proto_item *ping_item;
1184
0
    proto_tree *ping_tree;
1185
1186
0
    xmpp_attr_info attrs_info[] = {
1187
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
1188
0
    };
1189
1190
0
    col_append_str(pinfo->cinfo, COL_INFO, "PING ");
1191
1192
0
    ping_item = proto_tree_add_item(tree, hf_xmpp_ping, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1193
0
    ping_tree = proto_item_add_subtree(ping_item, ett_xmpp_ping);
1194
1195
0
    xmpp_display_attrs(ping_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1196
0
    xmpp_display_elems(ping_tree, element, pinfo, tvb, NULL, 0);
1197
0
}
1198
1199
/*XEP-0300: Use of Cryptographic Hash Functions in XMPP urn:xmpp:hashes:0*/
1200
void
1201
0
xmpp_hashes(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element) {
1202
0
    proto_item *hashes_item;
1203
0
    proto_tree *hashes_tree;
1204
1205
0
    xmpp_attr_info attrs_info[] = {
1206
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
1207
0
    };
1208
0
    xmpp_elem_info elems_info[] = {
1209
0
        {NAME, "hash", xmpp_hashes_hash, MANY}
1210
0
    };
1211
1212
0
    hashes_item = proto_tree_add_item(tree, hf_xmpp_hashes, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1213
0
    hashes_tree = proto_item_add_subtree(hashes_item, ett_xmpp_hashes);
1214
1215
0
    xmpp_display_attrs(hashes_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1216
0
    xmpp_display_elems(hashes_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
1217
0
}
1218
1219
static void
1220
xmpp_hashes_hash(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1221
0
{
1222
0
    proto_tree *hash_tree;
1223
1224
0
    xmpp_attr_info attrs_info[] = {
1225
0
        {"algo", NULL, true, true, NULL, NULL},
1226
0
        {"value", NULL, true, true, NULL, NULL}
1227
0
    };
1228
1229
0
    xmpp_attr_t *fake_cdata = xmpp_ep_init_attr_t(pinfo->pool, xmpp_elem_cdata(element), element->offset, element->length);
1230
0
    g_hash_table_insert(element->attrs, (void *)"value", fake_cdata);
1231
1232
0
    hash_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_hashes_hash, NULL, "HASH");
1233
1234
0
    xmpp_display_attrs(hash_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1235
0
    xmpp_display_elems(hash_tree, element, pinfo, tvb, NULL, 0);
1236
0
}
1237
1238
/*http://jitsi.org/protocol/inputevt*/
1239
void
1240
xmpp_jitsi_inputevt(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1241
0
{
1242
0
    proto_item *inputevt_item;
1243
0
    proto_tree *inputevt_tree;
1244
1245
0
    xmpp_attr_info attrs_info[] = {
1246
0
        {"xmlns", &hf_xmpp_xmlns, true, true, NULL, NULL},
1247
0
        {"action", NULL, false, true, NULL, NULL}
1248
0
    };
1249
1250
0
    xmpp_elem_info elems_info[] = {
1251
0
        {NAME, "remote-control", xmpp_jitsi_inputevt_rmt_ctrl, MANY}
1252
0
    };
1253
1254
0
    inputevt_item = proto_tree_add_item(tree, hf_xmpp_jitsi_inputevt, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1255
0
    inputevt_tree = proto_item_add_subtree(inputevt_item, ett_xmpp_jitsi_inputevt);
1256
1257
0
    xmpp_display_attrs(inputevt_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1258
0
    xmpp_display_elems(inputevt_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
1259
0
}
1260
1261
static void
1262
xmpp_jitsi_inputevt_rmt_ctrl(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
1263
0
{
1264
0
    proto_item *rmt_ctrl_item;
1265
0
    proto_tree *rmt_ctrl_tree;
1266
1267
0
    xmpp_attr_info attrs_info[] = {
1268
0
        {"xmlns", &hf_xmpp_xmlns, false, false, NULL, NULL},
1269
0
        {"action", NULL, true, true, NULL, NULL},
1270
0
        {"x", NULL, false, true, NULL, NULL},
1271
0
        {"y", NULL, false, true, NULL, NULL},
1272
0
        {"btns", NULL, false, true, NULL, NULL},
1273
0
        {"keycode", NULL, false, true, NULL, NULL},
1274
0
    };
1275
1276
0
    xmpp_element_t *action;
1277
0
    static const char *action_names[] = {"mouse-move", "mouse-press", "mouse-release", "key-press", "key-release"};
1278
1279
0
    if((action = xmpp_steal_element_by_names(element, action_names, array_length(action_names)))!=NULL)
1280
0
    {
1281
0
        xmpp_attr_t *fake_action = xmpp_ep_init_attr_t(pinfo->pool, action->name, action->offset, action->length);
1282
0
        g_hash_table_insert(element->attrs,(void *)"action", fake_action);
1283
1284
0
        if(strcmp(action->name,"mouse-move") == 0)
1285
0
        {
1286
0
            xmpp_attr_t *x = xmpp_get_attr(action,"x");
1287
0
            xmpp_attr_t *y = xmpp_get_attr(action,"y");
1288
1289
0
            if(x)
1290
0
                g_hash_table_insert(element->attrs,(void *)"x",x);
1291
0
            if(y)
1292
0
                g_hash_table_insert(element->attrs,(void *)"y",y);
1293
0
        } else if(strcmp(action->name,"mouse-press") == 0 || strcmp(action->name,"mouse-release") == 0)
1294
0
        {
1295
0
            xmpp_attr_t *btns = xmpp_get_attr(action,"btns");
1296
1297
0
            if(btns)
1298
0
                g_hash_table_insert(element->attrs,(void *)"btns",btns);
1299
0
        } else if(strcmp(action->name,"key-press") == 0 || strcmp(action->name,"key-release") == 0)
1300
0
        {
1301
0
            xmpp_attr_t *keycode = xmpp_get_attr(action,"keycode");
1302
1303
0
            if(keycode)
1304
0
                g_hash_table_insert(element->attrs,(void *)"keycode",keycode);
1305
0
        }
1306
1307
0
    }
1308
1309
0
    rmt_ctrl_item = proto_tree_add_item(tree, hf_xmpp_jitsi_inputevt_rmt_ctrl, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
1310
0
    rmt_ctrl_tree = proto_item_add_subtree(rmt_ctrl_item, ett_xmpp_jitsi_inputevt_rmt_ctrl);
1311
1312
0
    xmpp_display_attrs(rmt_ctrl_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
1313
    xmpp_display_elems(rmt_ctrl_tree, element, pinfo, tvb, NULL, 0);
1314
0
}
1315
/*
1316
* Editor modelines - https://www.wireshark.org/tools/modelines.html
1317
*
1318
* Local variables:
1319
* c-basic-offset: 4
1320
* tab-width: 8
1321
* indent-tabs-mode: nil
1322
* End:
1323
*
1324
* ex: set shiftwidth=4 tabstop=8 expandtab:
1325
* :indentSize=4:tabSize=8:noTabs=true:
1326
*/