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