2 * Wireshark's XMPP dissector.
4 * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/packet.h>
34 #include <epan/wmem/wmem.h>
36 #include <epan/dissectors/packet-xml.h>
38 #include <packet-xmpp-utils.h>
39 #include <packet-xmpp.h>
40 #include <packet-xmpp-other.h>
42 static void xmpp_disco_items_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
);
44 static void xmpp_roster_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
);
46 static void xmpp_disco_info_identity(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
);
47 static void xmpp_disco_info_feature(proto_tree
*tree
, tvbuff_t
*tvb
, xmpp_element_t
*element
);
49 static void xmpp_bytestreams_streamhost(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
50 static void xmpp_bytestreams_streamhost_used(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
51 static void xmpp_bytestreams_activate(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
52 static void xmpp_bytestreams_udpsuccess(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
54 static void xmpp_si_file(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
);
55 static void xmpp_si_file_range(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
);
57 static void xmpp_x_data_field(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
);
58 static void xmpp_x_data_field_option(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
);
59 static void xmpp_x_data_field_value(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
);
60 static void xmpp_x_data_instr(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
);
62 static void xmpp_muc_history(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
64 static void xmpp_muc_user_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
65 static void xmpp_muc_user_status(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
66 static void xmpp_muc_user_invite(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
68 static void xmpp_hashes_hash(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
70 static void xmpp_jitsi_inputevt_rmt_ctrl(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
);
73 xmpp_iq_bind(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
75 proto_item
*bind_item
;
76 proto_tree
*bind_tree
;
78 xmpp_attr_info attrs_info
[] = {
79 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
80 {"resource", hf_xmpp_iq_bind_resource
, FALSE
, TRUE
, NULL
, NULL
},
81 {"jid", hf_xmpp_iq_bind_jid
, FALSE
, TRUE
, NULL
, NULL
}
84 col_append_str(pinfo
->cinfo
, COL_INFO
, "BIND ");
86 bind_item
= proto_tree_add_item(tree
, hf_xmpp_iq_bind
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
87 bind_tree
= proto_item_add_subtree(bind_item
, ett_xmpp_iq_bind
);
89 xmpp_change_elem_to_attrib("resource", "resource", element
, xmpp_transform_func_cdata
);
90 xmpp_change_elem_to_attrib("jid", "jid", element
, xmpp_transform_func_cdata
);
92 xmpp_display_attrs(bind_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
94 xmpp_unknown(bind_tree
, tvb
, pinfo
, element
);
98 xmpp_session(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
100 proto_item
*session_item
;
101 proto_tree
*session_tree
;
103 xmpp_attr_info attrs_info
[] = {
104 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
}
107 session_item
= proto_tree_add_item(tree
, hf_xmpp_iq_session
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
108 session_tree
= proto_item_add_subtree(session_item
, ett_xmpp_iq_session
);
110 col_append_str(pinfo
->cinfo
, COL_INFO
, "SESSION ");
112 xmpp_display_attrs(session_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
113 xmpp_display_elems(session_tree
, element
, pinfo
, tvb
, NULL
, 0);
117 xmpp_vcard(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
119 proto_item
*vcard_item
;
120 proto_tree
*vcard_tree
;
122 xmpp_attr_info attrs_info
[] = {
123 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
124 {"value", -1, FALSE
, FALSE
, NULL
, NULL
}
127 xmpp_element_t
*cdata
;
129 col_append_str(pinfo
->cinfo
, COL_INFO
, "VCARD ");
131 vcard_item
= proto_tree_add_item(tree
, hf_xmpp_vcard
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
132 vcard_tree
= proto_item_add_subtree(vcard_item
, ett_xmpp_vcard
);
134 cdata
= xmpp_get_first_element(element
);
138 xmpp_attr_t
*fake_cdata
;
139 fake_cdata
= xmpp_ep_init_attr_t(xmpp_element_to_string(tvb
, cdata
), cdata
->offset
, cdata
->length
);
140 g_hash_table_insert(element
->attrs
,(gpointer
)"value", fake_cdata
);
143 xmpp_display_attrs(vcard_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
148 xmpp_vcard_x_update(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
153 xmpp_attr_info attrs_info
[] = {
154 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
155 {"photo", -1, FALSE
, FALSE
, NULL
, NULL
}
158 xmpp_element_t
*photo
;
160 x_item
= proto_tree_add_item(tree
, hf_xmpp_vcard_x_update
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
161 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_vcard_x_update
);
163 if((photo
= xmpp_steal_element_by_name(element
, "photo"))!=NULL
)
165 xmpp_attr_t
*fake_photo
= xmpp_ep_init_attr_t(photo
->data
?photo
->data
->value
:"", photo
->offset
, photo
->length
);
166 g_hash_table_insert(element
->attrs
, (gpointer
)"photo", fake_photo
);
169 xmpp_display_attrs(x_tree
, element
,pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
171 xmpp_unknown(x_tree
, tvb
, pinfo
, element
);
175 xmpp_disco_items_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
177 proto_item
*query_item
;
178 proto_tree
*query_tree
;
180 xmpp_attr_info attrs_info
[] = {
181 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
182 {"node", hf_xmpp_query_node
, FALSE
, TRUE
, NULL
, NULL
}
185 xmpp_element_t
*item
;
187 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(disco#items) ");
189 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
190 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
192 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
194 while((item
= xmpp_steal_element_by_name(element
, "item")) != NULL
)
196 xmpp_disco_items_item(query_tree
, tvb
, pinfo
, item
);
199 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
203 xmpp_disco_items_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
205 proto_item
*item_item
;
206 proto_tree
*item_tree
;
208 xmpp_attr_info attrs_info
[] = {
209 {"jid", hf_xmpp_query_item_jid
, TRUE
, TRUE
, NULL
, NULL
},
210 {"name", hf_xmpp_query_item_name
, FALSE
, TRUE
, NULL
, NULL
},
211 {"node", hf_xmpp_query_item_node
, FALSE
, TRUE
, NULL
, NULL
}
214 item_item
= proto_tree_add_item(tree
, hf_xmpp_query_item
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
215 item_tree
= proto_item_add_subtree(item_item
, ett_xmpp_query_item
);
217 xmpp_display_attrs(item_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
219 xmpp_unknown(item_tree
, tvb
, pinfo
, element
);
223 xmpp_roster_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
225 proto_item
*query_item
;
226 proto_tree
*query_tree
;
228 xmpp_attr_info attrs_info
[] = {
229 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
230 {"ver", -1, FALSE
, TRUE
, NULL
, NULL
},
233 xmpp_elem_info elems_info
[] = {
234 {NAME
, "item", xmpp_roster_item
, MANY
},
237 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(jabber:iq:roster) ");
239 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
240 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
242 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
243 xmpp_display_elems(query_tree
, element
, pinfo
, tvb
, elems_info
, array_length(elems_info
));
247 xmpp_roster_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
249 proto_item
*item_item
;
250 proto_tree
*item_tree
;
252 static const gchar
*ask_enums
[] = {"subscribe"};
253 static const gchar
*subscription_enums
[] = {"both", "from", "none", "remove", "to"};
255 xmpp_array_t
*ask_enums_array
= xmpp_ep_init_array_t(ask_enums
,array_length(ask_enums
));
256 xmpp_array_t
*subscription_array
= xmpp_ep_init_array_t(subscription_enums
,array_length(subscription_enums
));
258 xmpp_attr_info attrs_info
[] = {
259 {"jid", hf_xmpp_query_item_jid
, TRUE
, TRUE
, NULL
, NULL
},
260 {"name", hf_xmpp_query_item_name
, FALSE
, TRUE
, NULL
, NULL
},
261 {"ask", hf_xmpp_query_item_ask
, FALSE
, TRUE
, xmpp_val_enum_list
, ask_enums_array
},
262 {"approved", hf_xmpp_query_item_approved
, FALSE
, TRUE
, NULL
, NULL
},
263 {"subscription", hf_xmpp_query_item_subscription
, FALSE
, TRUE
, xmpp_val_enum_list
, subscription_array
},
266 xmpp_element_t
*group
;
268 item_item
= proto_tree_add_item(tree
, hf_xmpp_query_item
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
269 item_tree
= proto_item_add_subtree(item_item
, ett_xmpp_query_item
);
271 xmpp_display_attrs(item_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
273 while((group
= xmpp_steal_element_by_name(element
,"group"))!=NULL
)
275 proto_tree_add_string(item_tree
, hf_xmpp_query_item_group
, tvb
, group
->offset
, group
->length
, xmpp_elem_cdata(group
));
278 xmpp_unknown(item_tree
, tvb
, pinfo
, element
);
282 xmpp_disco_info_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
284 proto_item
*query_item
;
285 proto_tree
*query_tree
;
287 xmpp_attr_info attrs_info
[] = {
288 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
289 {"node", hf_xmpp_query_node
, FALSE
, TRUE
, NULL
, NULL
}
292 xmpp_element_t
*identity
, *feature
, *x_data
;
294 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(disco#info) ");
296 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
297 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
299 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
302 while((identity
= xmpp_steal_element_by_name(element
, "identity")) != NULL
)
304 xmpp_disco_info_identity(query_tree
, tvb
, pinfo
, identity
);
307 while((feature
= xmpp_steal_element_by_name(element
, "feature")) != NULL
)
309 xmpp_disco_info_feature(query_tree
, tvb
, feature
);
312 if((x_data
= xmpp_steal_element_by_name_and_attr(element
, "x", "xmlns", "jabber:x:data")) != NULL
)
314 xmpp_x_data(query_tree
, tvb
, pinfo
, x_data
);
317 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
321 xmpp_disco_info_identity(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, xmpp_element_t
*element
)
323 proto_item
*identity_item
;
324 proto_tree
*identity_tree
;
326 xmpp_attr_info attrs_info
[] = {
327 {"category", hf_xmpp_query_identity_category
, TRUE
, TRUE
, NULL
, NULL
},
328 {"name", hf_xmpp_query_identity_name
, FALSE
, TRUE
, NULL
, NULL
},
329 {"type", hf_xmpp_query_identity_type
, TRUE
, TRUE
, NULL
, NULL
}
332 identity_item
= proto_tree_add_item(tree
, hf_xmpp_query_identity
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
333 identity_tree
= proto_item_add_subtree(identity_item
, ett_xmpp_query_identity
);
335 xmpp_display_attrs(identity_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
337 xmpp_unknown(identity_tree
, tvb
, pinfo
, element
);
342 xmpp_disco_info_feature(proto_tree
*tree
, tvbuff_t
*tvb
, xmpp_element_t
*element
)
345 xmpp_attr_t
*var
= xmpp_get_attr(element
, "var");
349 proto_tree_add_string_format(tree
, hf_xmpp_query_feature
, tvb
, var
->offset
, var
->length
, var
->value
, "FEATURE [%s]", var
->value
);
354 xmpp_bytestreams_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
356 proto_item
*query_item
;
357 proto_tree
*query_tree
;
359 static const gchar
*mode_enums
[] = {"tcp", "udp"};
360 xmpp_array_t
*mode_array
= xmpp_ep_init_array_t(mode_enums
, array_length(mode_enums
));
362 xmpp_attr_info attrs_info
[] = {
363 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
364 {"sid", -1, FALSE
, TRUE
, NULL
, NULL
},
365 {"mode", -1, FALSE
, TRUE
, xmpp_val_enum_list
, mode_array
},
366 {"dstaddr", -1, FALSE
, TRUE
, NULL
, NULL
}
369 xmpp_element_t
*streamhost
, *streamhost_used
, *activate
, *udpsuccess
;
371 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(bytestreams) ");
373 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
374 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
376 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
379 while((streamhost
= xmpp_steal_element_by_name(element
, "streamhost")) != NULL
)
381 xmpp_bytestreams_streamhost(query_tree
, tvb
, pinfo
, streamhost
);
384 if((streamhost_used
= xmpp_steal_element_by_name(element
, "streamhost-used")) != NULL
)
386 xmpp_bytestreams_streamhost_used(query_tree
, tvb
, pinfo
, streamhost_used
);
389 if((activate
= xmpp_steal_element_by_name(element
, "activate")) != NULL
)
391 xmpp_bytestreams_activate(query_tree
, tvb
, pinfo
, activate
);
394 if((udpsuccess
= xmpp_steal_element_by_name(element
, "udpsuccess")) != NULL
)
396 xmpp_bytestreams_udpsuccess(query_tree
, tvb
, pinfo
, udpsuccess
);
399 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
403 xmpp_bytestreams_streamhost(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
408 xmpp_attr_info attrs_info
[] = {
409 {"jid", -1, TRUE
, TRUE
, NULL
, NULL
},
410 {"host", -1, TRUE
, TRUE
, NULL
, NULL
},
411 {"port", -1, FALSE
, TRUE
, NULL
, NULL
}
414 sh_item
= proto_tree_add_item(tree
, hf_xmpp_query_streamhost
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
415 sh_tree
= proto_item_add_subtree(sh_item
, ett_xmpp_query_streamhost
);
417 xmpp_display_attrs(sh_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
419 xmpp_unknown(sh_tree
, tvb
, pinfo
, element
);
423 xmpp_bytestreams_streamhost_used(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
425 proto_item
*shu_item
;
426 proto_tree
*shu_tree
;
428 xmpp_attr_info attrs_info
[] = {
429 {"jid", -1, TRUE
, TRUE
, NULL
, NULL
}
432 shu_item
= proto_tree_add_item(tree
, hf_xmpp_query_streamhost_used
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
433 shu_tree
= proto_item_add_subtree(shu_item
, ett_xmpp_query_streamhost_used
);
435 xmpp_display_attrs(shu_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
437 xmpp_unknown(shu_tree
, tvb
, pinfo
, element
);
441 xmpp_bytestreams_activate(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
443 proto_tree_add_string(tree
, hf_xmpp_query_activate
, tvb
, element
->offset
, element
->length
, xmpp_elem_cdata(element
));
444 xmpp_unknown(tree
, tvb
, pinfo
, element
);
448 xmpp_bytestreams_udpsuccess(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
450 proto_item
*udps_item
;
451 proto_tree
*udps_tree
;
453 xmpp_attr_info attrs_info
[] = {
454 {"dstaddr", -1, TRUE
, TRUE
, NULL
, NULL
}
457 udps_item
= proto_tree_add_item(tree
, hf_xmpp_query_udpsuccess
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
458 udps_tree
=proto_item_add_subtree(udps_item
, ett_xmpp_query_udpsuccess
);
460 xmpp_display_attrs(udps_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
462 xmpp_unknown(udps_tree
, tvb
, pinfo
, element
);
469 xmpp_si(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
474 xmpp_attr_info attrs_info
[] = {
475 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
476 {"id", -1, FALSE
, FALSE
, NULL
, NULL
},
477 {"mime-type", -1, FALSE
, TRUE
, NULL
, NULL
},
478 {"profile", -1, FALSE
, TRUE
, NULL
, NULL
}
481 xmpp_element_t
*file
, *feature_neg
;
483 col_append_str(pinfo
->cinfo
, COL_INFO
, "SI ");
485 si_item
= proto_tree_add_item(tree
, hf_xmpp_si
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
486 si_tree
= proto_item_add_subtree(si_item
, ett_xmpp_si
);
488 xmpp_display_attrs(si_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
490 while((file
= xmpp_steal_element_by_name(element
, "file"))!=NULL
)
492 xmpp_si_file(si_tree
, tvb
, pinfo
, file
);
495 while((feature_neg
= xmpp_steal_element_by_name(element
, "feature"))!=NULL
)
497 xmpp_feature_neg(si_tree
, tvb
, pinfo
, feature_neg
);
502 xmpp_unknown(si_tree
, tvb
, pinfo
, element
);
506 xmpp_si_file(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
508 proto_item
*file_item
;
509 proto_tree
*file_tree
;
511 xmpp_attr_info attrs_info
[] ={
512 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
513 {"name", -1, TRUE
, TRUE
, NULL
, NULL
},
514 {"size", -1, TRUE
, TRUE
, NULL
, NULL
},
515 {"date", -1, FALSE
, FALSE
, NULL
, NULL
},
516 {"hash", -1, FALSE
, FALSE
, NULL
, NULL
},
517 {"desc", -1, FALSE
, FALSE
, NULL
, NULL
}
520 xmpp_element_t
*desc
, *range
;
522 file_item
= proto_tree_add_item(tree
, hf_xmpp_si_file
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
523 file_tree
= proto_item_add_subtree(file_item
, ett_xmpp_si_file
);
525 if((desc
= xmpp_steal_element_by_name(element
, "desc"))!=NULL
)
527 xmpp_attr_t
*fake_desc
= xmpp_ep_init_attr_t(desc
->data
?desc
->data
->value
:"", desc
->offset
, desc
->length
);
528 g_hash_table_insert(element
->attrs
, (gpointer
)"desc", fake_desc
);
531 if((range
= xmpp_steal_element_by_name(element
, "range"))!=NULL
)
533 xmpp_si_file_range(file_tree
, tvb
, pinfo
, range
);
536 xmpp_display_attrs(file_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
538 xmpp_unknown(file_tree
, tvb
, pinfo
, element
);
542 xmpp_si_file_range(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
544 proto_item
*range_item
;
545 proto_tree
*range_tree
;
547 xmpp_attr_info attrs_info
[] = {
548 {"offset", -1, FALSE
, TRUE
, NULL
, NULL
},
549 {"length", -1, FALSE
, TRUE
, NULL
, NULL
}
552 range_item
= proto_tree_add_text(tree
, tvb
, element
->offset
, element
->length
, "RANGE: ");
553 range_tree
= proto_item_add_subtree(range_item
, ett_xmpp_si_file_range
);
555 xmpp_display_attrs(range_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
557 xmpp_unknown(range_tree
, tvb
, pinfo
, element
);
561 /*Feature Negotiation*/
563 xmpp_feature_neg(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
565 proto_item
*feature_item
;
566 proto_tree
*feature_tree
;
568 xmpp_attr_info attrs_info
[] = {
569 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
}
572 xmpp_element_t
*x_data
;
574 feature_item
= proto_tree_add_item(tree
, hf_xmpp_iq_feature_neg
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
575 feature_tree
= proto_item_add_subtree(feature_item
, ett_xmpp_iq_feature_neg
);
577 xmpp_display_attrs(feature_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
579 while((x_data
= xmpp_steal_element_by_name_and_attr(element
, "x", "xmlns", "jabber:x:data"))!=NULL
)
581 xmpp_x_data(feature_tree
, tvb
, pinfo
, x_data
);
584 xmpp_unknown(feature_tree
, tvb
, pinfo
, element
);
590 xmpp_x_data(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
595 static const gchar
*type_enums
[] = {"cancel", "form", "result", "submit"};
596 xmpp_array_t
*type_array
= xmpp_ep_init_array_t(type_enums
, array_length(type_enums
));
598 xmpp_attr_info attrs_info
[] = {
599 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
600 {"type", -1, TRUE
, TRUE
, xmpp_val_enum_list
, type_array
},
601 {"TITLE", -1, FALSE
, TRUE
, NULL
, NULL
}
604 xmpp_elem_info elems_info
[] = {
605 {NAME
, "instructions", xmpp_x_data_instr
, MANY
},
606 {NAME
, "field", xmpp_x_data_field
, MANY
},
608 /*TODO reported, item*/
610 x_item
= proto_tree_add_item(tree
, hf_xmpp_x_data
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
611 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_x_data
);
613 xmpp_change_elem_to_attrib("title", "TITLE", element
, xmpp_transform_func_cdata
);
615 xmpp_display_attrs(x_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
616 xmpp_display_elems(x_tree
, element
, pinfo
, tvb
, elems_info
, array_length(elems_info
));
620 xmpp_x_data_field(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
622 proto_item
*field_item
;
623 proto_tree
*field_tree
;
625 static const gchar
*type_enums
[] = {"boolean", "fixed", "hidden", "jid-multi",
626 "jid-single", "list-multi", "list-single", "text-multi", "text-single",
629 xmpp_array_t
*type_array
= xmpp_ep_init_array_t(type_enums
, array_length(type_enums
));
631 xmpp_attr_info attrs_info
[] =
633 {"label", -1, FALSE
, TRUE
, NULL
, NULL
},
634 {"type", -1, FALSE
, TRUE
, xmpp_val_enum_list
, type_array
},
635 {"var", -1, FALSE
, TRUE
, NULL
, NULL
}
638 xmpp_element_t
/**desc, *required,*/ *value
, *option
;
640 field_item
= proto_tree_add_item(tree
, hf_xmpp_x_data_field
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
641 field_tree
= proto_item_add_subtree(field_item
, ett_xmpp_x_data_field
);
643 xmpp_display_attrs(field_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
645 while((option
= xmpp_steal_element_by_name(element
, "option"))!=NULL
)
647 xmpp_x_data_field_option(field_tree
, tvb
, pinfo
, option
);
650 while((value
= xmpp_steal_element_by_name(element
, "value"))!=NULL
)
652 xmpp_x_data_field_value(field_tree
, tvb
, pinfo
, value
);
655 xmpp_unknown(field_item
, tvb
, pinfo
, element
);
660 xmpp_x_data_field_option(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
662 proto_item
*option_item
;
663 proto_tree
*option_tree
;
665 xmpp_attr_info attrs_info
[] = {
666 {"label", -1, FALSE
, TRUE
, NULL
, NULL
},
667 {"value", -1, FALSE
, TRUE
, NULL
, NULL
}
670 xmpp_element_t
*value
;
672 option_item
= proto_tree_add_item(tree
, hf_xmpp_x_data_field_value
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
673 option_tree
= proto_item_add_subtree(option_item
, ett_xmpp_x_data_field_value
);
675 if((value
= xmpp_steal_element_by_name(element
, "value"))!=NULL
)
677 xmpp_attr_t
*fake_value
= xmpp_ep_init_attr_t(value
->data
?value
->data
->value
:"",value
->offset
, value
->length
);
678 g_hash_table_insert(element
->attrs
, (gpointer
)"value", fake_value
);
681 xmpp_display_attrs(option_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
683 xmpp_unknown(option_tree
, tvb
, pinfo
, element
);
687 xmpp_x_data_field_value(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, xmpp_element_t
* element
)
689 proto_item
*value_item
;
690 proto_tree
*value_tree
;
692 xmpp_attr_info attrs_info
[] = {
693 {"label", -1, FALSE
, TRUE
, NULL
, NULL
},
694 {"value", -1, TRUE
, TRUE
, NULL
, NULL
}
696 xmpp_attr_t
*fake_value
;
698 value_item
= proto_tree_add_item(tree
, hf_xmpp_x_data_field_value
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
699 value_tree
= proto_item_add_subtree(value_item
, ett_xmpp_x_data_field_value
);
703 fake_value
= xmpp_ep_init_attr_t(element
->data
?element
->data
->value
:"",element
->offset
, element
->length
);
704 g_hash_table_insert(element
->attrs
, (gpointer
)"value", fake_value
);
707 xmpp_display_attrs(value_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
709 xmpp_unknown(value_tree
, tvb
, pinfo
, element
);
713 xmpp_x_data_instr(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo _U_
, xmpp_element_t
* element
)
715 proto_tree_add_text(tree
, tvb
, element
->offset
, element
->length
, "INSTRUCTIONS: %s",xmpp_elem_cdata(element
));
718 /*In-Band Bytestreams*/
720 xmpp_ibb_open(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
722 proto_item
*open_item
;
723 proto_tree
*open_tree
;
725 static const gchar
*stanza_enums
[] = {"iq", "message"};
726 xmpp_array_t
*stanza_array
= xmpp_ep_init_array_t(stanza_enums
, array_length(stanza_enums
));
728 xmpp_attr_info attrs_info
[] = {
729 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
730 {"sid", -1, TRUE
, TRUE
, NULL
, NULL
},
731 {"block-size", -1, TRUE
, TRUE
, NULL
, NULL
},
732 {"stanza", -1, FALSE
, TRUE
, xmpp_val_enum_list
, stanza_array
}
735 col_append_str(pinfo
->cinfo
, COL_INFO
, "IBB-OPEN ");
737 open_item
= proto_tree_add_item(tree
, hf_xmpp_ibb_open
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
738 open_tree
= proto_item_add_subtree(open_item
, ett_xmpp_ibb_open
);
740 xmpp_display_attrs(open_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
741 xmpp_unknown(open_tree
, tvb
, pinfo
, element
);
745 xmpp_ibb_close(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
747 proto_item
*close_item
;
748 proto_tree
*close_tree
;
750 xmpp_attr_info attrs_info
[] = {
751 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
752 {"sid", -1, TRUE
, TRUE
, NULL
, NULL
}
755 col_append_str(pinfo
->cinfo
, COL_INFO
, "IBB-CLOSE ");
757 close_item
= proto_tree_add_item(tree
, hf_xmpp_ibb_close
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
758 close_tree
= proto_item_add_subtree(close_item
, ett_xmpp_ibb_close
);
760 xmpp_display_attrs(close_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
761 xmpp_unknown(close_tree
, tvb
, pinfo
, element
);
765 xmpp_ibb_data(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
767 proto_item
*data_item
;
768 proto_tree
*data_tree
;
770 xmpp_attr_info attrs_info
[] = {
771 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
772 {"sid", -1, TRUE
, TRUE
, NULL
, NULL
},
773 {"seq", -1, TRUE
, TRUE
, NULL
, NULL
},
774 {"value", -1, FALSE
, FALSE
, NULL
, NULL
}
777 col_append_str(pinfo
->cinfo
, COL_INFO
, "IBB-DATA ");
779 data_item
= proto_tree_add_item(tree
, hf_xmpp_ibb_data
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
780 data_tree
= proto_item_add_subtree(data_item
, ett_xmpp_ibb_data
);
784 xmpp_attr_t
*fake_data
= xmpp_ep_init_attr_t(element
->data
->value
, element
->offset
, element
->length
);
785 g_hash_table_insert(element
->attrs
, (gpointer
)"value", fake_data
);
788 xmpp_display_attrs(data_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
789 xmpp_unknown(data_tree
, tvb
, pinfo
, element
);
793 /*Delayed Delivery urn:xmpp:delay and jabber:x:delay*/
795 xmpp_delay(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
797 proto_item
*delay_item
;
798 proto_tree
*delay_tree
;
800 xmpp_attr_info attrs_info
[]={
801 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
802 {"from", -1, FALSE
, TRUE
, NULL
, NULL
},
803 {"stamp", -1, TRUE
, TRUE
, NULL
, NULL
},
804 {"value", -1, FALSE
, TRUE
, NULL
, NULL
}
807 delay_item
= proto_tree_add_item(tree
, hf_xmpp_delay
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
808 delay_tree
= proto_item_add_subtree(delay_item
, ett_xmpp_delay
);
812 xmpp_attr_t
*fake_value
= xmpp_ep_init_attr_t(element
->data
->value
, element
->offset
, element
->length
);
813 g_hash_table_insert(element
->attrs
, (gpointer
)"value", fake_value
);
816 xmpp_display_attrs(delay_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
818 xmpp_unknown(delay_tree
, tvb
, pinfo
, element
);
821 /*Entity Capabilities http://jabber.org/protocol/caps*/
823 xmpp_presence_caps(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
825 proto_item
*caps_item
;
826 proto_tree
*caps_tree
;
828 xmpp_attr_info attrs_info
[] = {
829 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
830 {"ext", -1, FALSE
, FALSE
, NULL
, NULL
},
831 {"hash", -1, TRUE
, TRUE
, NULL
, NULL
},
832 {"node", -1, TRUE
, TRUE
, NULL
, NULL
},
833 {"ver", -1, TRUE
, FALSE
, NULL
, NULL
}
836 caps_item
= proto_tree_add_item(tree
, hf_xmpp_presence_caps
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
837 caps_tree
= proto_item_add_subtree(caps_item
, ett_xmpp_presence_caps
);
839 xmpp_display_attrs(caps_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
841 xmpp_unknown(caps_tree
, tvb
, pinfo
, element
);
844 /*Message Events jabber:x:event*/
846 xmpp_x_event(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
851 xmpp_attr_info attrs_info
[] = {
852 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
853 {"condition", hf_xmpp_x_event_condition
, TRUE
, TRUE
, NULL
, NULL
},
854 {"id", -1, FALSE
, TRUE
, NULL
, NULL
}
857 static const gchar
*cond_names
[] = {"offline", "delivered", "displayed", "composing"};
859 xmpp_attr_t
*fake_cond
;
861 xmpp_element_t
*cond
, *id
;
863 gchar
*cond_value
= wmem_strdup(wmem_packet_scope(), "");
865 x_item
= proto_tree_add_item(tree
, hf_xmpp_x_event
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
866 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_x_event
);
868 if((id
= xmpp_steal_element_by_name(element
, "id"))!=NULL
)
870 xmpp_attr_t
*fake_id
= xmpp_ep_init_attr_t(id
->data
?id
->data
->value
:"", id
->offset
, id
->length
);
871 g_hash_table_insert(element
->attrs
, (gpointer
)"id", fake_id
);
874 while((cond
= xmpp_steal_element_by_names(element
, cond_names
, array_length(cond_names
))) != NULL
)
876 if(strcmp(cond_value
,"") != 0)
877 cond_value
= wmem_strdup_printf(wmem_packet_scope(), "%s/%s",cond_value
, cond
->name
);
879 cond_value
= wmem_strdup(wmem_packet_scope(), cond
->name
);
882 fake_cond
= xmpp_ep_init_attr_t(cond_value
, element
->offset
, element
->length
);
883 g_hash_table_insert(element
->attrs
, (gpointer
)"condition", fake_cond
);
886 xmpp_display_attrs(x_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
888 xmpp_unknown(x_tree
, tvb
, pinfo
, element
);
891 /*Multi-User Chat http://jabber.org/protocol/muc*/
893 xmpp_muc_x(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
898 xmpp_attr_info attrs_info
[] ={
899 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
900 {"password", -1, FALSE
, TRUE
, NULL
, NULL
}
903 xmpp_element_t
*pass
, *hist
;
905 x_item
= proto_tree_add_item(tree
, hf_xmpp_muc_x
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
906 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_muc_x
);
908 if((pass
= xmpp_steal_element_by_name(element
, "password"))!=NULL
)
910 xmpp_attr_t
*fake_pass
= xmpp_ep_init_attr_t(pass
->data
?pass
->data
->value
:"",pass
->offset
, pass
->length
);
911 g_hash_table_insert(element
->attrs
, (gpointer
)"password", fake_pass
);
914 xmpp_display_attrs(x_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
916 if((hist
= xmpp_steal_element_by_name(element
, "history"))!=NULL
)
918 xmpp_muc_history(x_tree
, tvb
, pinfo
, hist
);
921 xmpp_unknown(x_tree
, tvb
, pinfo
, element
);
925 xmpp_muc_history(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
927 proto_item
*hist_item
;
928 proto_tree
*hist_tree
;
930 xmpp_attr_info attrs_info
[] = {
931 {"maxchars", -1, FALSE
, TRUE
, NULL
, NULL
},
932 {"maxstanzas", -1, FALSE
, TRUE
, NULL
, NULL
},
933 {"seconds", -1, FALSE
, TRUE
, NULL
, NULL
},
934 {"since", -1, FALSE
, TRUE
, NULL
, NULL
}
937 hist_item
= proto_tree_add_text(tree
, tvb
, element
->offset
, element
->length
, "HISTORY: ");
938 hist_tree
= proto_item_add_subtree(hist_item
, ett_xmpp_muc_hist
);
940 xmpp_display_attrs(hist_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
942 xmpp_unknown(hist_tree
, tvb
, pinfo
, element
);
945 /*Multi-User Chat http://jabber.org/protocol/muc#user*/
947 xmpp_muc_user_x(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
952 xmpp_attr_info attrs_info
[] = {
953 {"xmlns", hf_xmpp_xmlns
, TRUE
, FALSE
, NULL
, NULL
},
954 {"password", -1, FALSE
, TRUE
, NULL
, NULL
}
957 xmpp_element_t
*item
, *status
, *invite
, *password
;
958 /*TODO decline destroy*/
960 x_item
= proto_tree_add_item(tree
, hf_xmpp_muc_user_x
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
961 x_tree
= proto_item_add_subtree(x_item
, ett_xmpp_muc_user_x
);
963 if((password
= xmpp_steal_element_by_name(element
, "password"))!=NULL
)
965 xmpp_attr_t
*fake_pass
= xmpp_ep_init_attr_t(password
->data
?password
->data
->value
:"",password
->offset
, password
->length
);
966 g_hash_table_insert(element
->attrs
, (gpointer
)"password", fake_pass
);
969 xmpp_display_attrs(x_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
971 while((item
= xmpp_steal_element_by_name(element
, "item"))!=NULL
)
973 xmpp_muc_user_item(x_tree
, tvb
, pinfo
, item
);
976 while((status
= xmpp_steal_element_by_name(element
, "status"))!=NULL
)
978 xmpp_muc_user_status(x_tree
, tvb
, pinfo
, status
);
981 while((invite
= xmpp_steal_element_by_name(element
, "invite"))!=NULL
)
983 xmpp_muc_user_invite(x_tree
, tvb
, pinfo
, invite
);
986 xmpp_unknown(x_tree
, tvb
, pinfo
, element
);
990 xmpp_muc_user_item(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
992 proto_item
*item_item
;
993 proto_tree
*item_tree
;
995 static const gchar
*affiliation_enums
[] = {"admin", "member", "none", "outcast", "owner"};
996 xmpp_array_t
*affil_array
= xmpp_ep_init_array_t(affiliation_enums
, array_length(affiliation_enums
));
998 static const gchar
*role_enums
[] = {"none", "moderator", "participant", "visitor"};
999 xmpp_array_t
*role_array
= xmpp_ep_init_array_t(role_enums
, array_length(role_enums
));
1001 xmpp_attr_info attrs_info
[] ={
1002 {"affiliation", -1, FALSE
, TRUE
, xmpp_val_enum_list
, affil_array
},
1003 {"jid", -1, FALSE
, TRUE
, NULL
, NULL
},
1004 {"nick", -1, FALSE
, TRUE
, NULL
, NULL
},
1005 {"role", -1, FALSE
, TRUE
, xmpp_val_enum_list
, role_array
},
1006 {"reason", -1, FALSE
, TRUE
, NULL
, NULL
},
1007 {"actor_jid", -1, FALSE
, TRUE
, NULL
, NULL
}
1010 xmpp_element_t
*reason
, *actor
;
1011 /*TODO continue - it's not clear to me, in schema it's marked as empty, but in examples it has CDATA*/
1013 item_item
= proto_tree_add_item(tree
, hf_xmpp_muc_user_item
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1014 item_tree
= proto_item_add_subtree(item_item
, ett_xmpp_muc_user_item
);
1016 if((reason
= xmpp_steal_element_by_name(element
, "reason"))!=NULL
)
1018 xmpp_attr_t
*fake_reason
= xmpp_ep_init_attr_t(reason
->data
?reason
->data
->value
:"",reason
->offset
, reason
->length
);
1019 g_hash_table_insert(element
->attrs
,(gpointer
)"reason",fake_reason
);
1022 if((actor
= xmpp_steal_element_by_name(element
, "actor"))!=NULL
)
1024 xmpp_attr_t
*jid
= xmpp_get_attr(actor
, "jid");
1025 xmpp_attr_t
*fake_actor_jid
= xmpp_ep_init_attr_t(jid
?jid
->value
:"",actor
->offset
, actor
->length
);
1026 g_hash_table_insert(element
->attrs
, (gpointer
)"actor_jid", fake_actor_jid
);
1029 xmpp_display_attrs(item_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1031 xmpp_unknown(item_tree
, tvb
, pinfo
, element
);
1035 xmpp_muc_user_status(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1037 xmpp_attr_t
*code
= xmpp_get_attr(element
, "code");
1038 proto_tree_add_text(tree
, tvb
, element
->offset
, element
->length
, "STATUS [code=\"%s\"]",code
?code
->value
:"");
1040 xmpp_unknown(tree
, tvb
, pinfo
, element
);
1044 xmpp_muc_user_invite(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1046 proto_item
*invite_item
;
1047 proto_tree
*invite_tree
;
1049 xmpp_attr_info attrs_info
[] = {
1050 {"from", -1, FALSE
, TRUE
, NULL
, NULL
},
1051 {"to", -1, FALSE
, TRUE
, NULL
, NULL
},
1052 {"reason", -1, FALSE
, TRUE
, NULL
, NULL
}
1055 xmpp_element_t
*reason
;
1057 invite_item
= proto_tree_add_item(tree
, hf_xmpp_muc_user_invite
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1058 invite_tree
= proto_item_add_subtree(invite_item
, ett_xmpp_muc_user_invite
);
1060 if((reason
= xmpp_steal_element_by_name(element
, "reason"))!=NULL
)
1062 xmpp_attr_t
*fake_reason
= xmpp_ep_init_attr_t(reason
->data
?reason
->data
->value
:"",reason
->offset
, reason
->length
);
1063 g_hash_table_insert(element
->attrs
, (gpointer
)"reason", fake_reason
);
1066 xmpp_display_attrs(invite_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1068 xmpp_unknown(invite_tree
, tvb
, pinfo
, element
);
1071 /*Multi-User Chat http://jabber.org/protocol/muc#owner*/
1073 xmpp_muc_owner_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1075 proto_item
*query_item
;
1076 proto_tree
*query_tree
;
1078 xmpp_attr_info attrs_info
[] = {
1079 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
}
1082 xmpp_element_t
*x_data
;
1085 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(muc#owner) ");
1087 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1088 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
1090 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1092 if((x_data
= xmpp_steal_element_by_name_and_attr(element
, "x", "xmlns", "jabber:x:data"))!=NULL
)
1094 xmpp_x_data(query_tree
, tvb
, pinfo
, x_data
);
1097 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
1101 /*Multi-User Chat http://jabber.org/protocol/muc#admin*/
1103 xmpp_muc_admin_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1105 proto_item
*query_item
;
1106 proto_tree
*query_tree
;
1108 xmpp_attr_info attrs_info
[] = {
1109 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
}
1112 xmpp_element_t
*item
;
1114 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(muc#admin) ");
1116 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1117 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
1119 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1121 while((item
= xmpp_steal_element_by_name(element
, "item"))!=NULL
)
1123 /*from muc#user, because it is the same except continue element*/
1124 xmpp_muc_user_item(query_tree
, tvb
, pinfo
, item
);
1127 xmpp_unknown(query_tree
, tvb
, pinfo
, element
);
1130 /*Last Activity jabber:iq:last*/
1132 xmpp_last_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1134 proto_item
*query_item
;
1135 proto_tree
*query_tree
;
1137 xmpp_attr_info attrs_info
[] = {
1138 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
1139 {"seconds", -1, FALSE
, TRUE
, NULL
, NULL
},
1140 {"value", -1, FALSE
, TRUE
, NULL
, NULL
}
1143 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(jabber:iq:last) ");
1145 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1146 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
1150 xmpp_attr_t
*fake_data
= xmpp_ep_init_attr_t(element
->data
->value
, element
->data
->offset
, element
->data
->length
);
1151 g_hash_table_insert(element
->attrs
, (gpointer
)"value", fake_data
);
1154 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1155 xmpp_display_elems(query_tree
, element
, pinfo
, tvb
, NULL
, 0);
1158 /*XEP-0092: Software Version jabber:iq:version*/
1160 xmpp_version_query(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1162 proto_item
*query_item
;
1163 proto_tree
*query_tree
;
1165 xmpp_attr_info attrs_info
[] = {
1166 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
1167 {"name", -1, FALSE
, TRUE
, NULL
, NULL
},
1168 {"version", -1, FALSE
, TRUE
, NULL
, NULL
},
1169 {"os", -1, FALSE
, TRUE
, NULL
, NULL
}
1172 xmpp_element_t
*name
, *version
, *os
;
1174 col_append_str(pinfo
->cinfo
, COL_INFO
, "QUERY(jabber:iq:version) ");
1176 query_item
= proto_tree_add_item(tree
, hf_xmpp_query
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1177 query_tree
= proto_item_add_subtree(query_item
, ett_xmpp_query
);
1179 if((name
= xmpp_steal_element_by_name(element
,"name"))!=NULL
)
1181 xmpp_attr_t
*fake_name
= xmpp_ep_init_attr_t(name
->data
?name
->data
->value
:"", name
->offset
, name
->length
);
1182 g_hash_table_insert(element
->attrs
, (gpointer
)"name", fake_name
);
1185 if((version
= xmpp_steal_element_by_name(element
,"version"))!=NULL
)
1187 xmpp_attr_t
*fake_version
= xmpp_ep_init_attr_t(version
->data
?version
->data
->value
:"", version
->offset
, version
->length
);
1188 g_hash_table_insert(element
->attrs
, (gpointer
)"version", fake_version
);
1191 if((os
= xmpp_steal_element_by_name(element
,"os"))!=NULL
)
1193 xmpp_attr_t
*fake_os
= xmpp_ep_init_attr_t(os
->data
?os
->data
->value
:"", os
->offset
, os
->length
);
1194 g_hash_table_insert(element
->attrs
, (gpointer
)"os", fake_os
);
1197 xmpp_display_attrs(query_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1198 xmpp_display_elems(query_tree
, element
, pinfo
, tvb
, NULL
, 0);
1200 /*XEP-0199: XMPP Ping*/
1202 xmpp_ping(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1204 proto_item
*ping_item
;
1205 proto_tree
*ping_tree
;
1207 xmpp_attr_info attrs_info
[] = {
1208 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
1211 col_append_str(pinfo
->cinfo
, COL_INFO
, "PING ");
1213 ping_item
= proto_tree_add_item(tree
, hf_xmpp_ping
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1214 ping_tree
= proto_item_add_subtree(ping_item
, ett_xmpp_ping
);
1216 xmpp_display_attrs(ping_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1217 xmpp_display_elems(ping_tree
, element
, pinfo
, tvb
, NULL
, 0);
1220 /*XEP-0300: Use of Cryptographic Hash Functions in XMPP urn:xmpp:hashes:0*/
1222 xmpp_hashes(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
) {
1223 proto_item
*hashes_item
;
1224 proto_tree
*hashes_tree
;
1226 xmpp_attr_info attrs_info
[] = {
1227 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
1229 xmpp_elem_info elems_info
[] = {
1230 {NAME
, "hash", xmpp_hashes_hash
, MANY
}
1233 hashes_item
= proto_tree_add_item(tree
, hf_xmpp_hashes
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1234 hashes_tree
= proto_item_add_subtree(hashes_item
, ett_xmpp_hashes
);
1236 xmpp_display_attrs(hashes_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1237 xmpp_display_elems(hashes_tree
, element
, pinfo
, tvb
, elems_info
, array_length(elems_info
));
1241 xmpp_hashes_hash(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1243 proto_item
*hash_item
;
1244 proto_tree
*hash_tree
;
1246 xmpp_attr_info attrs_info
[] = {
1247 {"algo", -1, TRUE
, TRUE
, NULL
, NULL
},
1248 {"value", -1, TRUE
, TRUE
, NULL
, NULL
}
1251 xmpp_attr_t
*fake_cdata
= xmpp_ep_init_attr_t(xmpp_elem_cdata(element
), element
->offset
, element
->length
);
1252 g_hash_table_insert(element
->attrs
, (gpointer
)"value", fake_cdata
);
1254 hash_item
= proto_tree_add_text(tree
, tvb
, element
->offset
, element
->length
, "HASH");
1255 hash_tree
= proto_item_add_subtree(hash_item
, ett_xmpp_hashes_hash
);
1257 xmpp_display_attrs(hash_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1258 xmpp_display_elems(hash_tree
, element
, pinfo
, tvb
, NULL
, 0);
1261 /*http://jitsi.org/protocol/inputevt*/
1263 xmpp_jitsi_inputevt(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1265 proto_item
*inputevt_item
;
1266 proto_tree
*inputevt_tree
;
1268 xmpp_attr_info attrs_info
[] = {
1269 {"xmlns", hf_xmpp_xmlns
, TRUE
, TRUE
, NULL
, NULL
},
1270 {"action", -1, FALSE
, TRUE
, NULL
, NULL
}
1273 xmpp_elem_info elems_info
[] = {
1274 {NAME
, "remote-control", xmpp_jitsi_inputevt_rmt_ctrl
, MANY
}
1277 inputevt_item
= proto_tree_add_item(tree
, hf_xmpp_jitsi_inputevt
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1278 inputevt_tree
= proto_item_add_subtree(inputevt_item
, ett_xmpp_jitsi_inputevt
);
1280 xmpp_display_attrs(inputevt_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1281 xmpp_display_elems(inputevt_tree
, element
, pinfo
, tvb
, elems_info
, array_length(elems_info
));
1285 xmpp_jitsi_inputevt_rmt_ctrl(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, xmpp_element_t
*element
)
1287 proto_item
*rmt_ctrl_item
;
1288 proto_tree
*rmt_ctrl_tree
;
1290 xmpp_attr_info attrs_info
[] = {
1291 {"xmlns", hf_xmpp_xmlns
, FALSE
, FALSE
, NULL
, NULL
},
1292 {"action", -1, TRUE
, TRUE
, NULL
, NULL
},
1293 {"x", -1, FALSE
, TRUE
, NULL
, NULL
},
1294 {"y", -1, FALSE
, TRUE
, NULL
, NULL
},
1295 {"btns", -1, FALSE
, TRUE
, NULL
, NULL
},
1296 {"keycode", -1, FALSE
, TRUE
, NULL
, NULL
},
1299 xmpp_element_t
*action
;
1300 static const gchar
*action_names
[] = {"mouse-move", "mouse-press", "mouse-release", "key-press", "key-release"};
1302 if((action
= xmpp_steal_element_by_names(element
, action_names
, array_length(action_names
)))!=NULL
)
1304 xmpp_attr_t
*fake_action
= xmpp_ep_init_attr_t(action
->name
, action
->offset
, action
->length
);
1305 g_hash_table_insert(element
->attrs
,(gpointer
)"action", fake_action
);
1307 if(strcmp(action
->name
,"mouse-move") == 0)
1309 xmpp_attr_t
*x
= xmpp_get_attr(action
,"x");
1310 xmpp_attr_t
*y
= xmpp_get_attr(action
,"y");
1313 g_hash_table_insert(element
->attrs
,(gpointer
)"x",x
);
1315 g_hash_table_insert(element
->attrs
,(gpointer
)"y",y
);
1316 } else if(strcmp(action
->name
,"mouse-press") == 0 || strcmp(action
->name
,"mouse-release") == 0)
1318 xmpp_attr_t
*btns
= xmpp_get_attr(action
,"btns");
1321 g_hash_table_insert(element
->attrs
,(gpointer
)"btns",btns
);
1322 } else if(strcmp(action
->name
,"key-press") == 0 || strcmp(action
->name
,"key-release") == 0)
1324 xmpp_attr_t
*keycode
= xmpp_get_attr(action
,"keycode");
1327 g_hash_table_insert(element
->attrs
,(gpointer
)"keycode",keycode
);
1332 rmt_ctrl_item
= proto_tree_add_item(tree
, hf_xmpp_jitsi_inputevt_rmt_ctrl
, tvb
, element
->offset
, element
->length
, ENC_BIG_ENDIAN
);
1333 rmt_ctrl_tree
= proto_item_add_subtree(rmt_ctrl_item
, ett_xmpp_jitsi_inputevt_rmt_ctrl
);
1335 xmpp_display_attrs(rmt_ctrl_tree
, element
, pinfo
, tvb
, attrs_info
, array_length(attrs_info
));
1336 xmpp_display_elems(rmt_ctrl_tree
, element
, pinfo
, tvb
, NULL
, 0);
1339 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1344 * indent-tabs-mode: nil
1347 * ex: set shiftwidth=4 tabstop=8 expandtab:
1348 * :indentSize=4:tabSize=8:noTabs=true: