2 * Wireshark's XMPP dissector.
4 * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include "packet-xmpp.h"
18 #include "packet-xmpp-other.h"
20 static void xmpp_disco_items_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
);
22 static void xmpp_roster_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
);
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
);
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
);
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
);
35 static void xmpp_x_data(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
);
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
);
42 static void xmpp_muc_history(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
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
);
48 static void xmpp_hashes_hash(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
50 static void xmpp_jitsi_inputevt_rmt_ctrl(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
52 static void xmpp_feature_neg(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
);
56 xmpp_iq_bind(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
58 proto_item
*bind_item
;
59 proto_tree
*bind_tree
;
61 xmpp_attr_info attrs_info
[] = {
62 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
63 {"resource", &hf_xmpp_iq_bind_resource
, false, true, NULL
, NULL
},
64 {"jid", &hf_xmpp_iq_bind_jid
, false, true, NULL
, NULL
}
67 col_append_str(pinfo
->cinfo
, COL_INFO
, "BIND ");
69 bind_item
= proto_tree_add_item(tree
, hf_xmpp_iq_bind
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
70 bind_tree
= proto_item_add_subtree(bind_item
, ett_xmpp_iq_bind
);
72 xmpp_change_elem_to_attrib(pinfo
->pool
, "resource", "resource", element
, xmpp_transform_func_cdata
);
73 xmpp_change_elem_to_attrib(pinfo
->pool
, "jid", "jid", element
, xmpp_transform_func_cdata
);
75 xmpp_display_attrs(bind_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
77 xmpp_unknown(bind_tree
, tvb
, pinfo
, element
);
81 xmpp_session(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
83 proto_item
*session_item
;
84 proto_tree
*session_tree
;
86 xmpp_attr_info attrs_info
[] = {
87 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
}
90 session_item
= proto_tree_add_item(tree
, hf_xmpp_iq_session
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
91 session_tree
= proto_item_add_subtree(session_item
, ett_xmpp_iq_session
);
93 col_append_str(pinfo
->cinfo
, COL_INFO
, "SESSION ");
95 xmpp_display_attrs(session_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
96 xmpp_display_elems(session_tree
, element
, pinfo
, tvb
, NULL
, 0);
100 xmpp_vcard(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
102 proto_item
*vcard_item
;
103 proto_tree
*vcard_tree
;
105 xmpp_attr_info attrs_info
[] = {
106 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
107 {"value", NULL
, false, false, NULL
, NULL
}
110 xmpp_element_t
*cdata
;
112 col_append_str(pinfo
->cinfo
, COL_INFO
, "VCARD ");
114 vcard_item
= proto_tree_add_item(tree
, hf_xmpp_vcard
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
115 vcard_tree
= proto_item_add_subtree(vcard_item
, ett_xmpp_vcard
);
117 cdata
= xmpp_get_first_element(element
);
121 xmpp_attr_t
*fake_cdata
;
122 fake_cdata
= xmpp_ep_init_attr_t(pinfo
->pool
, xmpp_element_to_string(pinfo
->pool
, tvb
, cdata
), cdata
->offset
, cdata
->length
);
123 g_hash_table_insert(element
->attrs
,(void *)"value", fake_cdata
);
126 xmpp_display_attrs(vcard_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
131 xmpp_vcard_x_update(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
136 xmpp_attr_info attrs_info
[] = {
137 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
138 {"photo", NULL
, false, false, NULL
, NULL
}
141 xmpp_element_t
*photo
;
143 x_item
= proto_tree_add_item(tree
, hf_xmpp_vcard_x_update
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
144 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_vcard_x_update
);
146 if((photo
= xmpp_steal_element_by_name(element
, "photo"))!=NULL
)
148 xmpp_attr_t
*fake_photo
= xmpp_ep_init_attr_t(pinfo
->pool
, photo
->data
?photo
->data
->value
:"", photo
->offset
, photo
->length
);
149 g_hash_table_insert(element
->attrs
, (void *)"photo", fake_photo
);
152 xmpp_display_attrs(x_tree
, element
,pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
154 xmpp_unknown(x_tree
, tvb
, pinfo
, element
);
158 xmpp_disco_items_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
160 proto_item
*query_item
;
161 proto_tree
*query_tree
;
163 xmpp_attr_info attrs_info
[] = {
164 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
165 {"node", &hf_xmpp_query_node
, false, true, NULL
, NULL
}
168 xmpp_element_t
*item
;
170 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(disco#items) ");
172 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
173 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
175 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
177 while((item
= xmpp_steal_element_by_name(element
, "item")) != NULL
)
179 xmpp_disco_items_item(query_tree
, tvb
, pinfo
, item
);
182 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
186 xmpp_disco_items_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
188 proto_item
*item_item
;
189 proto_tree
*item_tree
;
191 xmpp_attr_info attrs_info
[] = {
192 {"jid", &hf_xmpp_query_item_jid
, true, true, NULL
, NULL
},
193 {"name", &hf_xmpp_query_item_name
, false, true, NULL
, NULL
},
194 {"node", &hf_xmpp_query_item_node
, false, true, NULL
, NULL
}
197 item_item
= proto_tree_add_item(tree
, hf_xmpp_query_item
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
198 item_tree
= proto_item_add_subtree(item_item
, ett_xmpp_query_item
);
200 xmpp_display_attrs(item_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
202 xmpp_unknown(item_tree
, tvb
, pinfo
, element
);
206 xmpp_roster_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
208 proto_item
*query_item
;
209 proto_tree
*query_tree
;
211 xmpp_attr_info attrs_info
[] = {
212 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
213 {"ver", NULL
, false, true, NULL
, NULL
},
216 xmpp_elem_info elems_info
[] = {
217 {NAME
, "item", xmpp_roster_item
, MANY
},
220 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(jabber:iq:roster) ");
222 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
223 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
225 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
226 xmpp_display_elems(query_tree
, element
, pinfo
, tvb
, elems_info
, array_length(elems_info
));
230 xmpp_roster_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
232 proto_item
*item_item
;
233 proto_tree
*item_tree
;
235 static const char *ask_enums
[] = {"subscribe"};
236 static const char *subscription_enums
[] = {"both", "from", "none", "remove", "to"};
238 xmpp_array_t
*ask_enums_array
= xmpp_ep_init_array_t(pinfo
->pool
, ask_enums
,array_length(ask_enums
));
239 xmpp_array_t
*subscription_array
= xmpp_ep_init_array_t(pinfo
->pool
, subscription_enums
,array_length(subscription_enums
));
241 xmpp_attr_info attrs_info
[] = {
242 {"jid", &hf_xmpp_query_item_jid
, true, true, NULL
, NULL
},
243 {"name", &hf_xmpp_query_item_name
, false, true, NULL
, NULL
},
244 {"ask", &hf_xmpp_query_item_ask
, false, true, xmpp_val_enum_list
, ask_enums_array
},
245 {"approved", &hf_xmpp_query_item_approved
, false, true, NULL
, NULL
},
246 {"subscription", &hf_xmpp_query_item_subscription
, false, true, xmpp_val_enum_list
, subscription_array
},
249 xmpp_element_t
*group
;
251 item_item
= proto_tree_add_item(tree
, hf_xmpp_query_item
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
252 item_tree
= proto_item_add_subtree(item_item
, ett_xmpp_query_item
);
254 xmpp_display_attrs(item_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
256 while((group
= xmpp_steal_element_by_name(element
,"group"))!=NULL
)
258 proto_tree_add_string(item_tree
, hf_xmpp_query_item_group
, tvb
, group
->offset
, group
->length
, xmpp_elem_cdata(group
));
261 xmpp_unknown(item_tree
, tvb
, pinfo
, element
);
265 xmpp_disco_info_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
267 proto_item
*query_item
;
268 proto_tree
*query_tree
;
270 xmpp_attr_info attrs_info
[] = {
271 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
272 {"node", &hf_xmpp_query_node
, false, true, NULL
, NULL
}
275 xmpp_element_t
*identity
, *feature
, *x_data
;
277 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(disco#info) ");
279 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
280 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
282 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
285 while((identity
= xmpp_steal_element_by_name(element
, "identity")) != NULL
)
287 xmpp_disco_info_identity(query_tree
, tvb
, pinfo
, identity
);
290 while((feature
= xmpp_steal_element_by_name(element
, "feature")) != NULL
)
292 xmpp_disco_info_feature(query_tree
, tvb
, feature
);
295 if((x_data
= xmpp_steal_element_by_name_and_attr(element
, "x", "xmlns", "jabber:x:data")) != NULL
)
297 xmpp_x_data(query_tree
, tvb
, pinfo
, x_data
);
300 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
304 xmpp_disco_info_identity(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
306 proto_item
*identity_item
;
307 proto_tree
*identity_tree
;
309 xmpp_attr_info attrs_info
[] = {
310 {"category", &hf_xmpp_query_identity_category
, true, true, NULL
, NULL
},
311 {"name", &hf_xmpp_query_identity_name
, false, true, NULL
, NULL
},
312 {"type", &hf_xmpp_query_identity_type
, true, true, NULL
, NULL
}
315 identity_item
= proto_tree_add_item(tree
, hf_xmpp_query_identity
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
316 identity_tree
= proto_item_add_subtree(identity_item
, ett_xmpp_query_identity
);
318 xmpp_display_attrs(identity_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
320 xmpp_unknown(identity_tree
, tvb
, pinfo
, element
);
325 xmpp_disco_info_feature(proto_tree
*tree
, tvbuff_t
*tvb
, xmpp_element_t
*element
)
328 xmpp_attr_t
*var
= xmpp_get_attr(element
, "var");
332 proto_tree_add_string_format(tree
, hf_xmpp_query_feature
, tvb
, var
->offset
, var
->length
, var
->value
, "FEATURE [%s]", var
->value
);
337 xmpp_bytestreams_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
339 proto_item
*query_item
;
340 proto_tree
*query_tree
;
342 static const char *mode_enums
[] = {"tcp", "udp"};
343 xmpp_array_t
*mode_array
= xmpp_ep_init_array_t(pinfo
->pool
, mode_enums
, array_length(mode_enums
));
345 xmpp_attr_info attrs_info
[] = {
346 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
347 {"sid", NULL
, false, true, NULL
, NULL
},
348 {"mode", NULL
, false, true, xmpp_val_enum_list
, mode_array
},
349 {"dstaddr", NULL
, false, true, NULL
, NULL
}
352 xmpp_element_t
*streamhost
, *streamhost_used
, *activate
, *udpsuccess
;
354 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(bytestreams) ");
356 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
357 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
359 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
362 while((streamhost
= xmpp_steal_element_by_name(element
, "streamhost")) != NULL
)
364 xmpp_bytestreams_streamhost(query_tree
, tvb
, pinfo
, streamhost
);
367 if((streamhost_used
= xmpp_steal_element_by_name(element
, "streamhost-used")) != NULL
)
369 xmpp_bytestreams_streamhost_used(query_tree
, tvb
, pinfo
, streamhost_used
);
372 if((activate
= xmpp_steal_element_by_name(element
, "activate")) != NULL
)
374 xmpp_bytestreams_activate(query_tree
, tvb
, pinfo
, activate
);
377 if((udpsuccess
= xmpp_steal_element_by_name(element
, "udpsuccess")) != NULL
)
379 xmpp_bytestreams_udpsuccess(query_tree
, tvb
, pinfo
, udpsuccess
);
382 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
386 xmpp_bytestreams_streamhost(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
391 xmpp_attr_info attrs_info
[] = {
392 {"jid", NULL
, true, true, NULL
, NULL
},
393 {"host", NULL
, true, true, NULL
, NULL
},
394 {"port", NULL
, false, true, NULL
, NULL
}
397 sh_item
= proto_tree_add_item(tree
, hf_xmpp_query_streamhost
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
398 sh_tree
= proto_item_add_subtree(sh_item
, ett_xmpp_query_streamhost
);
400 xmpp_display_attrs(sh_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
402 xmpp_unknown(sh_tree
, tvb
, pinfo
, element
);
406 xmpp_bytestreams_streamhost_used(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
408 proto_item
*shu_item
;
409 proto_tree
*shu_tree
;
411 xmpp_attr_info attrs_info
[] = {
412 {"jid", NULL
, true, true, NULL
, NULL
}
415 shu_item
= proto_tree_add_item(tree
, hf_xmpp_query_streamhost_used
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
416 shu_tree
= proto_item_add_subtree(shu_item
, ett_xmpp_query_streamhost_used
);
418 xmpp_display_attrs(shu_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
420 xmpp_unknown(shu_tree
, tvb
, pinfo
, element
);
424 xmpp_bytestreams_activate(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
426 proto_tree_add_string(tree
, hf_xmpp_query_activate
, tvb
, element
->offset
, element
->length
, xmpp_elem_cdata(element
));
427 xmpp_unknown(tree
, tvb
, pinfo
, element
);
431 xmpp_bytestreams_udpsuccess(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
433 proto_item
*udps_item
;
434 proto_tree
*udps_tree
;
436 xmpp_attr_info attrs_info
[] = {
437 {"dstaddr", NULL
, true, true, NULL
, NULL
}
440 udps_item
= proto_tree_add_item(tree
, hf_xmpp_query_udpsuccess
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
441 udps_tree
=proto_item_add_subtree(udps_item
, ett_xmpp_query_udpsuccess
);
443 xmpp_display_attrs(udps_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
445 xmpp_unknown(udps_tree
, tvb
, pinfo
, element
);
452 xmpp_si(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
457 xmpp_attr_info attrs_info
[] = {
458 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
459 {"id", NULL
, false, false, NULL
, NULL
},
460 {"mime-type", NULL
, false, true, NULL
, NULL
},
461 {"profile", NULL
, false, true, NULL
, NULL
}
464 xmpp_element_t
*file
, *feature_neg
;
466 col_append_str(pinfo
->cinfo
, COL_INFO
, "SI ");
468 si_item
= proto_tree_add_item(tree
, hf_xmpp_si
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
469 si_tree
= proto_item_add_subtree(si_item
, ett_xmpp_si
);
471 xmpp_display_attrs(si_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
473 while((file
= xmpp_steal_element_by_name(element
, "file"))!=NULL
)
475 xmpp_si_file(si_tree
, tvb
, pinfo
, file
);
478 while((feature_neg
= xmpp_steal_element_by_name(element
, "feature"))!=NULL
)
480 xmpp_feature_neg(si_tree
, tvb
, pinfo
, feature_neg
);
485 xmpp_unknown(si_tree
, tvb
, pinfo
, element
);
489 xmpp_si_file(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
491 proto_item
*file_item
;
492 proto_tree
*file_tree
;
494 xmpp_attr_info attrs_info
[] = {
495 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
496 {"name", NULL
, true, true, NULL
, NULL
},
497 {"size", NULL
, true, true, NULL
, NULL
},
498 {"date", NULL
, false, false, NULL
, NULL
},
499 {"hash", NULL
, false, false, NULL
, NULL
},
500 {"desc", NULL
, false, false, NULL
, NULL
}
503 xmpp_element_t
*desc
, *range
;
505 file_item
= proto_tree_add_item(tree
, hf_xmpp_si_file
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
506 file_tree
= proto_item_add_subtree(file_item
, ett_xmpp_si_file
);
508 if((desc
= xmpp_steal_element_by_name(element
, "desc"))!=NULL
)
510 xmpp_attr_t
*fake_desc
= xmpp_ep_init_attr_t(pinfo
->pool
, desc
->data
?desc
->data
->value
:"", desc
->offset
, desc
->length
);
511 g_hash_table_insert(element
->attrs
, (void *)"desc", fake_desc
);
514 if((range
= xmpp_steal_element_by_name(element
, "range"))!=NULL
)
516 xmpp_si_file_range(file_tree
, tvb
, pinfo
, range
);
519 xmpp_display_attrs(file_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
521 xmpp_unknown(file_tree
, tvb
, pinfo
, element
);
525 xmpp_si_file_range(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
527 proto_tree
*range_tree
;
529 xmpp_attr_info attrs_info
[] = {
530 {"offset", NULL
, false, true, NULL
, NULL
},
531 {"length", NULL
, false, true, NULL
, NULL
}
534 range_tree
= proto_tree_add_subtree(tree
, tvb
, element
->offset
, element
->length
, ett_xmpp_si_file_range
, NULL
, "RANGE: ");
536 xmpp_display_attrs(range_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
538 xmpp_unknown(range_tree
, tvb
, pinfo
, element
);
542 /*Feature Negotiation*/
544 xmpp_feature_neg(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
546 proto_item
*feature_item
;
547 proto_tree
*feature_tree
;
549 xmpp_attr_info attrs_info
[] = {
550 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
}
553 xmpp_element_t
*x_data
;
555 feature_item
= proto_tree_add_item(tree
, hf_xmpp_iq_feature_neg
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
556 feature_tree
= proto_item_add_subtree(feature_item
, ett_xmpp_iq_feature_neg
);
558 xmpp_display_attrs(feature_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
560 while((x_data
= xmpp_steal_element_by_name_and_attr(element
, "x", "xmlns", "jabber:x:data"))!=NULL
)
562 xmpp_x_data(feature_tree
, tvb
, pinfo
, x_data
);
565 xmpp_unknown(feature_tree
, tvb
, pinfo
, element
);
571 xmpp_x_data(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
576 static const char *type_enums
[] = {"cancel", "form", "result", "submit"};
577 xmpp_array_t
*type_array
= xmpp_ep_init_array_t(pinfo
->pool
, type_enums
, array_length(type_enums
));
579 xmpp_attr_info attrs_info
[] = {
580 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
581 {"type", NULL
, true, true, xmpp_val_enum_list
, type_array
},
582 {"TITLE", NULL
, false, true, NULL
, NULL
}
585 xmpp_elem_info elems_info
[] = {
586 {NAME
, "instructions", xmpp_x_data_instr
, MANY
},
587 {NAME
, "field", xmpp_x_data_field
, MANY
},
589 /*TODO reported, item*/
591 x_item
= proto_tree_add_item(tree
, hf_xmpp_x_data
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
592 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_x_data
);
594 xmpp_change_elem_to_attrib(pinfo
->pool
, "title", "TITLE", element
, xmpp_transform_func_cdata
);
596 xmpp_display_attrs(x_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
597 xmpp_display_elems(x_tree
, element
, pinfo
, tvb
, elems_info
, array_length(elems_info
));
601 xmpp_x_data_field(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
603 proto_item
*field_item
;
604 proto_tree
*field_tree
;
606 static const char *type_enums
[] = {"boolean", "fixed", "hidden", "jid-multi",
607 "jid-single", "list-multi", "list-single", "text-multi", "text-single",
610 xmpp_array_t
*type_array
= xmpp_ep_init_array_t(pinfo
->pool
, type_enums
, array_length(type_enums
));
612 xmpp_attr_info attrs_info
[] = {
613 {"label", NULL
, false, true, NULL
, NULL
},
614 {"type", NULL
, false, true, xmpp_val_enum_list
, type_array
},
615 {"var", NULL
, false, true, NULL
, NULL
}
618 xmpp_element_t
/**desc, *required,*/ *value
, *option
;
620 field_item
= proto_tree_add_item(tree
, hf_xmpp_x_data_field
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
621 field_tree
= proto_item_add_subtree(field_item
, ett_xmpp_x_data_field
);
623 xmpp_display_attrs(field_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
625 while((option
= xmpp_steal_element_by_name(element
, "option"))!=NULL
)
627 xmpp_x_data_field_option(field_tree
, tvb
, pinfo
, option
);
630 while((value
= xmpp_steal_element_by_name(element
, "value"))!=NULL
)
632 xmpp_x_data_field_value(field_tree
, tvb
, pinfo
, value
);
635 xmpp_unknown(field_item
, tvb
, pinfo
, element
);
640 xmpp_x_data_field_option(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
642 proto_item
*option_item
;
643 proto_tree
*option_tree
;
645 xmpp_attr_info attrs_info
[] = {
646 {"label", NULL
, false, true, NULL
, NULL
},
647 {"value", NULL
, false, true, NULL
, NULL
}
650 xmpp_element_t
*value
;
652 option_item
= proto_tree_add_item(tree
, hf_xmpp_x_data_field_value
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
653 option_tree
= proto_item_add_subtree(option_item
, ett_xmpp_x_data_field_value
);
655 if((value
= xmpp_steal_element_by_name(element
, "value"))!=NULL
)
657 xmpp_attr_t
*fake_value
= xmpp_ep_init_attr_t(pinfo
->pool
, value
->data
?value
->data
->value
:"",value
->offset
, value
->length
);
658 g_hash_table_insert(element
->attrs
, (void *)"value", fake_value
);
661 xmpp_display_attrs(option_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
663 xmpp_unknown(option_tree
, tvb
, pinfo
, element
);
667 xmpp_x_data_field_value(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
669 proto_item
*value_item
;
670 proto_tree
*value_tree
;
672 xmpp_attr_info attrs_info
[] = {
673 {"label", NULL
, false, true, NULL
, NULL
},
674 {"value", NULL
, true, true, NULL
, NULL
}
676 xmpp_attr_t
*fake_value
;
678 value_item
= proto_tree_add_item(tree
, hf_xmpp_x_data_field_value
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
679 value_tree
= proto_item_add_subtree(value_item
, ett_xmpp_x_data_field_value
);
683 fake_value
= xmpp_ep_init_attr_t(pinfo
->pool
, element
->data
?element
->data
->value
:"",element
->offset
, element
->length
);
684 g_hash_table_insert(element
->attrs
, (void *)"value", fake_value
);
687 xmpp_display_attrs(value_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
689 xmpp_unknown(value_tree
, tvb
, pinfo
, element
);
693 xmpp_x_data_instr(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo _U_
, xmpp_element_t
* element
)
695 proto_tree_add_string(tree
, hf_xmpp_x_data_instructions
, tvb
, element
->offset
, element
->length
, xmpp_elem_cdata(element
));
698 /*In-Band Bytestreams*/
700 xmpp_ibb_open(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
702 proto_item
*open_item
;
703 proto_tree
*open_tree
;
705 static const char *stanza_enums
[] = {"iq", "message"};
706 xmpp_array_t
*stanza_array
= xmpp_ep_init_array_t(pinfo
->pool
, stanza_enums
, array_length(stanza_enums
));
708 xmpp_attr_info attrs_info
[] = {
709 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
710 {"sid", NULL
, true, true, NULL
, NULL
},
711 {"block-size", NULL
, true, true, NULL
, NULL
},
712 {"stanza", NULL
, false, true, xmpp_val_enum_list
, stanza_array
}
715 col_append_str(pinfo
->cinfo
, COL_INFO
, "IBB-OPEN ");
717 open_item
= proto_tree_add_item(tree
, hf_xmpp_ibb_open
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
718 open_tree
= proto_item_add_subtree(open_item
, ett_xmpp_ibb_open
);
720 xmpp_display_attrs(open_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
721 xmpp_unknown(open_tree
, tvb
, pinfo
, element
);
725 xmpp_ibb_close(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
727 proto_item
*close_item
;
728 proto_tree
*close_tree
;
730 xmpp_attr_info attrs_info
[] = {
731 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
732 {"sid", NULL
, true, true, NULL
, NULL
}
735 col_append_str(pinfo
->cinfo
, COL_INFO
, "IBB-CLOSE ");
737 close_item
= proto_tree_add_item(tree
, hf_xmpp_ibb_close
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
738 close_tree
= proto_item_add_subtree(close_item
, ett_xmpp_ibb_close
);
740 xmpp_display_attrs(close_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
741 xmpp_unknown(close_tree
, tvb
, pinfo
, element
);
745 xmpp_ibb_data(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
747 proto_item
*data_item
;
748 proto_tree
*data_tree
;
750 xmpp_attr_info attrs_info
[] = {
751 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
752 {"sid", NULL
, true, true, NULL
, NULL
},
753 {"seq", NULL
, true, true, NULL
, NULL
},
754 {"value", NULL
, false, false, NULL
, NULL
}
757 col_append_str(pinfo
->cinfo
, COL_INFO
, "IBB-DATA ");
759 data_item
= proto_tree_add_item(tree
, hf_xmpp_ibb_data
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
760 data_tree
= proto_item_add_subtree(data_item
, ett_xmpp_ibb_data
);
764 xmpp_attr_t
*fake_data
= xmpp_ep_init_attr_t(pinfo
->pool
, element
->data
->value
, element
->offset
, element
->length
);
765 g_hash_table_insert(element
->attrs
, (void *)"value", fake_data
);
768 xmpp_display_attrs(data_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
769 xmpp_unknown(data_tree
, tvb
, pinfo
, element
);
773 /*Delayed Delivery urn:xmpp:delay and jabber:x:delay*/
775 xmpp_delay(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
777 proto_item
*delay_item
;
778 proto_tree
*delay_tree
;
780 xmpp_attr_info attrs_info
[]={
781 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
782 {"from", NULL
, false, true, NULL
, NULL
},
783 {"stamp", NULL
, true, true, NULL
, NULL
},
784 {"value", NULL
, false, true, NULL
, NULL
}
787 delay_item
= proto_tree_add_item(tree
, hf_xmpp_delay
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
788 delay_tree
= proto_item_add_subtree(delay_item
, ett_xmpp_delay
);
792 xmpp_attr_t
*fake_value
= xmpp_ep_init_attr_t(pinfo
->pool
, element
->data
->value
, element
->offset
, element
->length
);
793 g_hash_table_insert(element
->attrs
, (void *)"value", fake_value
);
796 xmpp_display_attrs(delay_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
798 xmpp_unknown(delay_tree
, tvb
, pinfo
, element
);
801 /*Entity Capabilities http://jabber.org/protocol/caps*/
803 xmpp_presence_caps(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
805 proto_item
*caps_item
;
806 proto_tree
*caps_tree
;
808 xmpp_attr_info attrs_info
[] = {
809 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
810 {"ext", NULL
, false, false, NULL
, NULL
},
811 {"hash", NULL
, true, true, NULL
, NULL
},
812 {"node", NULL
, true, true, NULL
, NULL
},
813 {"ver", NULL
, true, false, NULL
, NULL
}
816 caps_item
= proto_tree_add_item(tree
, hf_xmpp_presence_caps
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
817 caps_tree
= proto_item_add_subtree(caps_item
, ett_xmpp_presence_caps
);
819 xmpp_display_attrs(caps_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
821 xmpp_unknown(caps_tree
, tvb
, pinfo
, element
);
824 /*Message Events jabber:x:event*/
826 xmpp_x_event(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
831 xmpp_attr_info attrs_info
[] = {
832 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
833 {"condition", &hf_xmpp_x_event_condition
, true, true, NULL
, NULL
},
834 {"id", NULL
, false, true, NULL
, NULL
}
837 static const char *cond_names
[] = {"offline", "delivered", "displayed", "composing"};
839 xmpp_attr_t
*fake_cond
;
841 xmpp_element_t
*cond
, *id
;
843 char *cond_value
= wmem_strdup(pinfo
->pool
, "");
845 x_item
= proto_tree_add_item(tree
, hf_xmpp_x_event
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
846 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_x_event
);
848 if((id
= xmpp_steal_element_by_name(element
, "id"))!=NULL
)
850 xmpp_attr_t
*fake_id
= xmpp_ep_init_attr_t(pinfo
->pool
, id
->data
?id
->data
->value
:"", id
->offset
, id
->length
);
851 g_hash_table_insert(element
->attrs
, (void *)"id", fake_id
);
854 while((cond
= xmpp_steal_element_by_names(element
, cond_names
, array_length(cond_names
))) != NULL
)
856 if(strcmp(cond_value
,"") != 0)
857 cond_value
= wmem_strdup_printf(pinfo
->pool
, "%s/%s",cond_value
, cond
->name
);
859 cond_value
= wmem_strdup(pinfo
->pool
, cond
->name
);
862 fake_cond
= xmpp_ep_init_attr_t(pinfo
->pool
, cond_value
, element
->offset
, element
->length
);
863 g_hash_table_insert(element
->attrs
, (void *)"condition", fake_cond
);
866 xmpp_display_attrs(x_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
868 xmpp_unknown(x_tree
, tvb
, pinfo
, element
);
871 /*Multi-User Chat http://jabber.org/protocol/muc*/
873 xmpp_muc_x(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
878 xmpp_attr_info attrs_info
[] ={
879 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
880 {"password", NULL
, false, true, NULL
, NULL
}
883 xmpp_element_t
*pass
, *hist
;
885 x_item
= proto_tree_add_item(tree
, hf_xmpp_muc_x
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
886 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_muc_x
);
888 if((pass
= xmpp_steal_element_by_name(element
, "password"))!=NULL
)
890 xmpp_attr_t
*fake_pass
= xmpp_ep_init_attr_t(pinfo
->pool
, pass
->data
?pass
->data
->value
:"",pass
->offset
, pass
->length
);
891 g_hash_table_insert(element
->attrs
, (void *)"password", fake_pass
);
894 xmpp_display_attrs(x_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
896 if((hist
= xmpp_steal_element_by_name(element
, "history"))!=NULL
)
898 xmpp_muc_history(x_tree
, tvb
, pinfo
, hist
);
901 xmpp_unknown(x_tree
, tvb
, pinfo
, element
);
905 xmpp_muc_history(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
907 proto_tree
*hist_tree
;
909 xmpp_attr_info attrs_info
[] = {
910 {"maxchars", NULL
, false, true, NULL
, NULL
},
911 {"maxstanzas", NULL
, false, true, NULL
, NULL
},
912 {"seconds", NULL
, false, true, NULL
, NULL
},
913 {"since", NULL
, false, true, NULL
, NULL
}
916 hist_tree
= proto_tree_add_subtree(tree
, tvb
, element
->offset
, element
->length
, ett_xmpp_muc_hist
, NULL
, "HISTORY: ");
918 xmpp_display_attrs(hist_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
920 xmpp_unknown(hist_tree
, tvb
, pinfo
, element
);
923 /*Multi-User Chat http://jabber.org/protocol/muc#user*/
925 xmpp_muc_user_x(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
930 xmpp_attr_info attrs_info
[] = {
931 {"xmlns", &hf_xmpp_xmlns
, true, false, NULL
, NULL
},
932 {"password", NULL
, false, true, NULL
, NULL
}
935 xmpp_element_t
*item
, *status
, *invite
, *password
;
936 /*TODO decline destroy*/
938 x_item
= proto_tree_add_item(tree
, hf_xmpp_muc_user_x
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
939 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_muc_user_x
);
941 if((password
= xmpp_steal_element_by_name(element
, "password"))!=NULL
)
943 xmpp_attr_t
*fake_pass
= xmpp_ep_init_attr_t(pinfo
->pool
, password
->data
?password
->data
->value
:"",password
->offset
, password
->length
);
944 g_hash_table_insert(element
->attrs
, (void *)"password", fake_pass
);
947 xmpp_display_attrs(x_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
949 while((item
= xmpp_steal_element_by_name(element
, "item"))!=NULL
)
951 xmpp_muc_user_item(x_tree
, tvb
, pinfo
, item
);
954 while((status
= xmpp_steal_element_by_name(element
, "status"))!=NULL
)
956 xmpp_muc_user_status(x_tree
, tvb
, pinfo
, status
);
959 while((invite
= xmpp_steal_element_by_name(element
, "invite"))!=NULL
)
961 xmpp_muc_user_invite(x_tree
, tvb
, pinfo
, invite
);
964 xmpp_unknown(x_tree
, tvb
, pinfo
, element
);
968 xmpp_muc_user_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
970 proto_item
*item_item
;
971 proto_tree
*item_tree
;
973 static const char *affiliation_enums
[] = {"admin", "member", "none", "outcast", "owner"};
974 xmpp_array_t
*affil_array
= xmpp_ep_init_array_t(pinfo
->pool
, affiliation_enums
, array_length(affiliation_enums
));
976 static const char *role_enums
[] = {"none", "moderator", "participant", "visitor"};
977 xmpp_array_t
*role_array
= xmpp_ep_init_array_t(pinfo
->pool
, role_enums
, array_length(role_enums
));
979 xmpp_attr_info attrs_info
[] ={
980 {"affiliation", NULL
, false, true, xmpp_val_enum_list
, affil_array
},
981 {"jid", NULL
, false, true, NULL
, NULL
},
982 {"nick", NULL
, false, true, NULL
, NULL
},
983 {"role", NULL
, false, true, xmpp_val_enum_list
, role_array
},
984 {"reason", NULL
, false, true, NULL
, NULL
},
985 {"actor_jid", NULL
, false, true, NULL
, NULL
}
988 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*/
991 item_item
= proto_tree_add_item(tree
, hf_xmpp_muc_user_item
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
992 item_tree
= proto_item_add_subtree(item_item
, ett_xmpp_muc_user_item
);
994 if((reason
= xmpp_steal_element_by_name(element
, "reason"))!=NULL
)
996 xmpp_attr_t
*fake_reason
= xmpp_ep_init_attr_t(pinfo
->pool
, reason
->data
?reason
->data
->value
:"",reason
->offset
, reason
->length
);
997 g_hash_table_insert(element
->attrs
,(void *)"reason",fake_reason
);
1000 if((actor
= xmpp_steal_element_by_name(element
, "actor"))!=NULL
)
1002 xmpp_attr_t
*jid
= xmpp_get_attr(actor
, "jid");
1003 xmpp_attr_t
*fake_actor_jid
= xmpp_ep_init_attr_t(pinfo
->pool
, jid
?jid
->value
:"",actor
->offset
, actor
->length
);
1004 g_hash_table_insert(element
->attrs
, (void *)"actor_jid", fake_actor_jid
);
1007 xmpp_display_attrs(item_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1009 xmpp_unknown(item_tree
, tvb
, pinfo
, element
);
1013 xmpp_muc_user_status(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1015 xmpp_attr_t
*code
= xmpp_get_attr(element
, "code");
1016 proto_tree_add_string_format(tree
, hf_xmpp_muc_user_status
, tvb
, element
->offset
, element
->length
,
1017 code
?code
->value
:"", "STATUS [code=\"%s\"]", code
?code
->value
:"");
1019 xmpp_unknown(tree
, tvb
, pinfo
, element
);
1023 xmpp_muc_user_invite(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1025 proto_item
*invite_item
;
1026 proto_tree
*invite_tree
;
1028 xmpp_attr_info attrs_info
[] = {
1029 {"from", NULL
, false, true, NULL
, NULL
},
1030 {"to", NULL
, false, true, NULL
, NULL
},
1031 {"reason", NULL
, false, true, NULL
, NULL
}
1034 xmpp_element_t
*reason
;
1036 invite_item
= proto_tree_add_item(tree
, hf_xmpp_muc_user_invite
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1037 invite_tree
= proto_item_add_subtree(invite_item
, ett_xmpp_muc_user_invite
);
1039 if((reason
= xmpp_steal_element_by_name(element
, "reason"))!=NULL
)
1041 xmpp_attr_t
*fake_reason
= xmpp_ep_init_attr_t(pinfo
->pool
, reason
->data
?reason
->data
->value
:"",reason
->offset
, reason
->length
);
1042 g_hash_table_insert(element
->attrs
, (void *)"reason", fake_reason
);
1045 xmpp_display_attrs(invite_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1047 xmpp_unknown(invite_tree
, tvb
, pinfo
, element
);
1050 /*Multi-User Chat http://jabber.org/protocol/muc#owner*/
1052 xmpp_muc_owner_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1054 proto_item
*query_item
;
1055 proto_tree
*query_tree
;
1057 xmpp_attr_info attrs_info
[] = {
1058 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
}
1061 xmpp_element_t
*x_data
;
1064 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(muc#owner) ");
1066 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1067 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
1069 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1071 if((x_data
= xmpp_steal_element_by_name_and_attr(element
, "x", "xmlns", "jabber:x:data"))!=NULL
)
1073 xmpp_x_data(query_tree
, tvb
, pinfo
, x_data
);
1076 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
1080 /*Multi-User Chat http://jabber.org/protocol/muc#admin*/
1082 xmpp_muc_admin_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1084 proto_item
*query_item
;
1085 proto_tree
*query_tree
;
1087 xmpp_attr_info attrs_info
[] = {
1088 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
}
1091 xmpp_element_t
*item
;
1093 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(muc#admin) ");
1095 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1096 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
1098 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1100 while((item
= xmpp_steal_element_by_name(element
, "item"))!=NULL
)
1102 /*from muc#user, because it is the same except continue element*/
1103 xmpp_muc_user_item(query_tree
, tvb
, pinfo
, item
);
1106 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
1109 /*Last Activity jabber:iq:last*/
1111 xmpp_last_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1113 proto_item
*query_item
;
1114 proto_tree
*query_tree
;
1116 xmpp_attr_info attrs_info
[] = {
1117 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
1118 {"seconds", NULL
, false, true, NULL
, NULL
},
1119 {"value", NULL
, false, true, NULL
, NULL
}
1122 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(jabber:iq:last) ");
1124 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1125 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
1129 xmpp_attr_t
*fake_data
= xmpp_ep_init_attr_t(pinfo
->pool
, element
->data
->value
, element
->data
->offset
, element
->data
->length
);
1130 g_hash_table_insert(element
->attrs
, (void *)"value", fake_data
);
1133 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1134 xmpp_display_elems(query_tree
, element
, pinfo
, tvb
, NULL
, 0);
1137 /*XEP-0092: Software Version jabber:iq:version*/
1139 xmpp_version_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1141 proto_item
*query_item
;
1142 proto_tree
*query_tree
;
1144 xmpp_attr_info attrs_info
[] = {
1145 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
1146 {"name", NULL
, false, true, NULL
, NULL
},
1147 {"version", NULL
, false, true, NULL
, NULL
},
1148 {"os", NULL
, false, true, NULL
, NULL
}
1151 xmpp_element_t
*name
, *version
, *os
;
1153 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(jabber:iq:version) ");
1155 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1156 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
1158 if((name
= xmpp_steal_element_by_name(element
,"name"))!=NULL
)
1160 xmpp_attr_t
*fake_name
= xmpp_ep_init_attr_t(pinfo
->pool
, name
->data
?name
->data
->value
:"", name
->offset
, name
->length
);
1161 g_hash_table_insert(element
->attrs
, (void *)"name", fake_name
);
1164 if((version
= xmpp_steal_element_by_name(element
,"version"))!=NULL
)
1166 xmpp_attr_t
*fake_version
= xmpp_ep_init_attr_t(pinfo
->pool
, version
->data
?version
->data
->value
:"", version
->offset
, version
->length
);
1167 g_hash_table_insert(element
->attrs
, (void *)"version", fake_version
);
1170 if((os
= xmpp_steal_element_by_name(element
,"os"))!=NULL
)
1172 xmpp_attr_t
*fake_os
= xmpp_ep_init_attr_t(pinfo
->pool
, os
->data
?os
->data
->value
:"", os
->offset
, os
->length
);
1173 g_hash_table_insert(element
->attrs
, (void *)"os", fake_os
);
1176 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1177 xmpp_display_elems(query_tree
, element
, pinfo
, tvb
, NULL
, 0);
1179 /*XEP-0199: XMPP Ping*/
1181 xmpp_ping(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1183 proto_item
*ping_item
;
1184 proto_tree
*ping_tree
;
1186 xmpp_attr_info attrs_info
[] = {
1187 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
1190 col_append_str(pinfo
->cinfo
, COL_INFO
, "PING ");
1192 ping_item
= proto_tree_add_item(tree
, hf_xmpp_ping
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1193 ping_tree
= proto_item_add_subtree(ping_item
, ett_xmpp_ping
);
1195 xmpp_display_attrs(ping_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1196 xmpp_display_elems(ping_tree
, element
, pinfo
, tvb
, NULL
, 0);
1199 /*XEP-0300: Use of Cryptographic Hash Functions in XMPP urn:xmpp:hashes:0*/
1201 xmpp_hashes(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
) {
1202 proto_item
*hashes_item
;
1203 proto_tree
*hashes_tree
;
1205 xmpp_attr_info attrs_info
[] = {
1206 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
1208 xmpp_elem_info elems_info
[] = {
1209 {NAME
, "hash", xmpp_hashes_hash
, MANY
}
1212 hashes_item
= proto_tree_add_item(tree
, hf_xmpp_hashes
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1213 hashes_tree
= proto_item_add_subtree(hashes_item
, ett_xmpp_hashes
);
1215 xmpp_display_attrs(hashes_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1216 xmpp_display_elems(hashes_tree
, element
, pinfo
, tvb
, elems_info
, array_length(elems_info
));
1220 xmpp_hashes_hash(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1222 proto_tree
*hash_tree
;
1224 xmpp_attr_info attrs_info
[] = {
1225 {"algo", NULL
, true, true, NULL
, NULL
},
1226 {"value", NULL
, true, true, NULL
, NULL
}
1229 xmpp_attr_t
*fake_cdata
= xmpp_ep_init_attr_t(pinfo
->pool
, xmpp_elem_cdata(element
), element
->offset
, element
->length
);
1230 g_hash_table_insert(element
->attrs
, (void *)"value", fake_cdata
);
1232 hash_tree
= proto_tree_add_subtree(tree
, tvb
, element
->offset
, element
->length
, ett_xmpp_hashes_hash
, NULL
, "HASH");
1234 xmpp_display_attrs(hash_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1235 xmpp_display_elems(hash_tree
, element
, pinfo
, tvb
, NULL
, 0);
1238 /*http://jitsi.org/protocol/inputevt*/
1240 xmpp_jitsi_inputevt(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1242 proto_item
*inputevt_item
;
1243 proto_tree
*inputevt_tree
;
1245 xmpp_attr_info attrs_info
[] = {
1246 {"xmlns", &hf_xmpp_xmlns
, true, true, NULL
, NULL
},
1247 {"action", NULL
, false, true, NULL
, NULL
}
1250 xmpp_elem_info elems_info
[] = {
1251 {NAME
, "remote-control", xmpp_jitsi_inputevt_rmt_ctrl
, MANY
}
1254 inputevt_item
= proto_tree_add_item(tree
, hf_xmpp_jitsi_inputevt
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1255 inputevt_tree
= proto_item_add_subtree(inputevt_item
, ett_xmpp_jitsi_inputevt
);
1257 xmpp_display_attrs(inputevt_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1258 xmpp_display_elems(inputevt_tree
, element
, pinfo
, tvb
, elems_info
, array_length(elems_info
));
1262 xmpp_jitsi_inputevt_rmt_ctrl(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1264 proto_item
*rmt_ctrl_item
;
1265 proto_tree
*rmt_ctrl_tree
;
1267 xmpp_attr_info attrs_info
[] = {
1268 {"xmlns", &hf_xmpp_xmlns
, false, false, NULL
, NULL
},
1269 {"action", NULL
, true, true, NULL
, NULL
},
1270 {"x", NULL
, false, true, NULL
, NULL
},
1271 {"y", NULL
, false, true, NULL
, NULL
},
1272 {"btns", NULL
, false, true, NULL
, NULL
},
1273 {"keycode", NULL
, false, true, NULL
, NULL
},
1276 xmpp_element_t
*action
;
1277 static const char *action_names
[] = {"mouse-move", "mouse-press", "mouse-release", "key-press", "key-release"};
1279 if((action
= xmpp_steal_element_by_names(element
, action_names
, array_length(action_names
)))!=NULL
)
1281 xmpp_attr_t
*fake_action
= xmpp_ep_init_attr_t(pinfo
->pool
, action
->name
, action
->offset
, action
->length
);
1282 g_hash_table_insert(element
->attrs
,(void *)"action", fake_action
);
1284 if(strcmp(action
->name
,"mouse-move") == 0)
1286 xmpp_attr_t
*x
= xmpp_get_attr(action
,"x");
1287 xmpp_attr_t
*y
= xmpp_get_attr(action
,"y");
1290 g_hash_table_insert(element
->attrs
,(void *)"x",x
);
1292 g_hash_table_insert(element
->attrs
,(void *)"y",y
);
1293 } else if(strcmp(action
->name
,"mouse-press") == 0 || strcmp(action
->name
,"mouse-release") == 0)
1295 xmpp_attr_t
*btns
= xmpp_get_attr(action
,"btns");
1298 g_hash_table_insert(element
->attrs
,(void *)"btns",btns
);
1299 } else if(strcmp(action
->name
,"key-press") == 0 || strcmp(action
->name
,"key-release") == 0)
1301 xmpp_attr_t
*keycode
= xmpp_get_attr(action
,"keycode");
1304 g_hash_table_insert(element
->attrs
,(void *)"keycode",keycode
);
1309 rmt_ctrl_item
= proto_tree_add_item(tree
, hf_xmpp_jitsi_inputevt_rmt_ctrl
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1310 rmt_ctrl_tree
= proto_item_add_subtree(rmt_ctrl_item
, ett_xmpp_jitsi_inputevt_rmt_ctrl
);
1312 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);
1316 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1321 * indent-tabs-mode: nil
1324 * ex: set shiftwidth=4 tabstop=8 expandtab:
1325 * :indentSize=4:tabSize=8:noTabs=true: