HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-xmpp-core.c
blob13a43992eddd10cbceda2360631cd043c622b4da
1 /* xmpp-core.c
2 * Wireshark's XMPP dissector.
4 * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
6 * $Id$
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.
27 #include "config.h"
29 #include <glib.h>
31 #include <epan/packet.h>
32 #include <epan/wmem/wmem.h>
33 #include <epan/conversation.h>
34 #include <epan/expert.h>
36 #include <epan/dissectors/packet-xml.h>
38 #include <packet-xmpp-utils.h>
39 #include <packet-xmpp.h>
40 #include <packet-xmpp-core.h>
41 #include <packet-xmpp-jingle.h>
42 #include <packet-xmpp-other.h>
43 #include <packet-xmpp-gtalk.h>
44 #include <packet-xmpp-conference.h>
46 #include <epan/strutil.h>
48 #include "epan/tvbparse.h"
50 tvbparse_wanted_t *want_ignore;
51 tvbparse_wanted_t *want_stream_end_tag;
52 tvbparse_wanted_t *want_stream_end_with_ns;
54 static void xmpp_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
55 static void xmpp_error_text(proto_tree *tree, tvbuff_t *tvb, xmpp_element_t *element);
57 static void xmpp_presence_status(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
59 static void xmpp_message_thread(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
60 static void xmpp_message_body(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
61 static void xmpp_message_subject(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element);
63 static void xmpp_failure_text(proto_tree *tree, tvbuff_t *tvb, xmpp_element_t *element);
65 static void xmpp_features_mechanisms(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet);
67 void
68 xmpp_init_parsers(void)
70 tvbparse_wanted_t *want_name;
71 tvbparse_wanted_t *want_stream_end;
73 want_name = tvbparse_chars(2,1,0,"abcdefghijklmnopqrstuvwxyz.-_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",NULL,NULL,NULL);
75 want_stream_end_with_ns = tvbparse_set_seq(3, NULL, NULL, NULL,
76 want_name,
77 tvbparse_char(4, ":", NULL, NULL, NULL),
78 want_name,
79 NULL);
81 want_stream_end = tvbparse_set_oneof(5, NULL, NULL, NULL,
82 want_stream_end_with_ns,
83 want_name,
84 NULL);
86 want_ignore = tvbparse_chars(1,1,0," \t\r\n",NULL,NULL,NULL);
88 want_stream_end_tag = tvbparse_set_seq(6, NULL, NULL, NULL,
89 tvbparse_string(-1,"</",NULL,NULL,NULL),
90 want_stream_end,
91 tvbparse_char(-1,">",NULL,NULL,NULL),
92 NULL);
95 void
96 xmpp_iq(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
98 proto_item *xmpp_iq_item;
99 proto_tree *xmpp_iq_tree;
101 xmpp_attr_t *attr_id, *attr_type;
103 xmpp_attr_info attrs_info[] = {
104 {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
105 {"id", hf_xmpp_id, TRUE, TRUE, NULL, NULL},
106 {"type", hf_xmpp_type, TRUE, TRUE, NULL, NULL},
107 {"from", hf_xmpp_from, FALSE, TRUE, NULL, NULL},
108 {"to", hf_xmpp_to, FALSE, TRUE, NULL, NULL},
109 {"xml:lang", -1, FALSE, FALSE, NULL, NULL}
112 conversation_t *conversation;
113 xmpp_conv_info_t *xmpp_info;
114 xmpp_transaction_t *reqresp_trans;
116 xmpp_elem_info elems_info [] = {
117 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","http://jabber.org/protocol/disco#items"), xmpp_disco_items_query, ONE},
118 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "jabber:iq:roster"), xmpp_roster_query, ONE},
119 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/disco#info"), xmpp_disco_info_query, ONE},
120 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/bytestreams"), xmpp_bytestreams_query, ONE},
121 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#owner"), xmpp_muc_owner_query, ONE},
122 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#admin"), xmpp_muc_admin_query, ONE},
123 {NAME, "bind", xmpp_iq_bind, ONE},
124 {NAME_AND_ATTR, xmpp_name_attr_struct("session", "xmlns", "urn:ietf:params:xml:ns:xmpp-session"), xmpp_session, ONE},
125 {NAME, "vCard", xmpp_vcard, ONE},
126 {NAME, "jingle", xmpp_jingle, ONE},
127 {NAME_AND_ATTR, xmpp_name_attr_struct("services", "xmlns", "http://jabber.org/protocol/jinglenodes"), xmpp_jinglenodes_services, ONE},
128 {NAME_AND_ATTR, xmpp_name_attr_struct("channel", "xmlns", "http://jabber.org/protocol/jinglenodes#channel"), xmpp_jinglenodes_channel, ONE},
129 {NAME_AND_ATTR, xmpp_name_attr_struct("open", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_open, ONE},
130 {NAME_AND_ATTR, xmpp_name_attr_struct("close", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_close, ONE},
131 {NAME_AND_ATTR, xmpp_name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE},
132 {NAME, "si", xmpp_si, ONE},
133 {NAME, "error", xmpp_error, ONE},
134 {NAME_AND_ATTR, xmpp_name_attr_struct("session", "xmlns", "http://www.google.com/session"), xmpp_gtalk_session, ONE},
135 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:jingleinfo"), xmpp_gtalk_jingleinfo_query, ONE},
136 {NAME_AND_ATTR, xmpp_name_attr_struct("usersetting", "xmlns","google:setting"), xmpp_gtalk_usersetting, ONE},
137 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:last"), xmpp_last_query, ONE},
138 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:version"), xmpp_version_query, ONE},
139 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:mail:notify"), xmpp_gtalk_mail_query, ONE},
140 {NAME, "mailbox", xmpp_gtalk_mail_mailbox, ONE},
141 {NAME, "new-mail", xmpp_gtalk_mail_new_mail, ONE},
142 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:shared-status"), xmpp_gtalk_status_query, ONE},
143 {NAME, "conference-info", xmpp_conference_info, ONE},
144 {NAME_AND_ATTR, xmpp_name_attr_struct("ping", "xmlns","urn:xmpp:ping"), xmpp_ping, ONE},
145 {NAME_AND_ATTR, xmpp_name_attr_struct("inputevt", "xmlns","http://jitsi.org/protocol/inputevt"), xmpp_jitsi_inputevt, ONE},
148 attr_id = xmpp_get_attr(packet, "id");
149 attr_type = xmpp_get_attr(packet, "type");
151 conversation = find_or_create_conversation(pinfo);
152 xmpp_info = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp);
154 xmpp_iq_item = proto_tree_add_item(tree, hf_xmpp_iq, tvb, packet->offset, packet->length, ENC_LITTLE_ENDIAN);
155 xmpp_iq_tree = proto_item_add_subtree(xmpp_iq_item,ett_xmpp_iq);
157 xmpp_display_attrs(xmpp_iq_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
160 col_add_fstr(pinfo->cinfo, COL_INFO, "IQ(%s) ", attr_type?attr_type->value:"");
162 xmpp_display_elems(xmpp_iq_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
164 /*displays generated info such as req/resp tracking, jingle sid
165 * in each packet related to specified jingle session and IBB sid in packet related to it*/
166 if(xmpp_info && attr_id)
168 gchar *jingle_sid, *ibb_sid, *gtalk_sid;
170 jingle_sid = (gchar *)wmem_tree_lookup_string(xmpp_info->jingle_sessions, attr_id->value, WMEM_TREE_STRING_NOCASE);
172 if (jingle_sid) {
173 proto_item *it = proto_tree_add_string(tree, hf_xmpp_jingle_session, tvb, 0, 0, jingle_sid);
174 PROTO_ITEM_SET_GENERATED(it);
177 ibb_sid = (gchar *)wmem_tree_lookup_string(xmpp_info->ibb_sessions, attr_id->value, WMEM_TREE_STRING_NOCASE);
179 if (ibb_sid) {
180 proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid);
181 PROTO_ITEM_SET_GENERATED(it);
184 gtalk_sid = (gchar *)wmem_tree_lookup_string(xmpp_info->gtalk_sessions, attr_id->value, WMEM_TREE_STRING_NOCASE);
186 if (gtalk_sid) {
187 proto_item *it = proto_tree_add_string(tree, hf_xmpp_gtalk, tvb, 0, 0, gtalk_sid);
188 PROTO_ITEM_SET_GENERATED(it);
191 reqresp_trans = (xmpp_transaction_t *)wmem_tree_lookup_string(xmpp_info->req_resp, attr_id->value, WMEM_TREE_STRING_NOCASE);
192 /*displays request/response field in each iq packet*/
193 if (reqresp_trans) {
195 if (reqresp_trans->req_frame == pinfo->fd->num) {
196 if (reqresp_trans->resp_frame) {
197 proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_in, tvb, 0, 0, reqresp_trans->resp_frame);
198 PROTO_ITEM_SET_GENERATED(it);
199 } else
201 expert_add_info(pinfo, xmpp_iq_item, &ei_xmpp_packet_without_response);
204 } else {
205 if (reqresp_trans->req_frame) {
206 proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_to, tvb, 0, 0, reqresp_trans->req_frame);
207 PROTO_ITEM_SET_GENERATED(it);
208 } else
210 expert_add_info(pinfo, xmpp_iq_item, &ei_xmpp_packet_without_response);
218 static void
219 xmpp_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
221 proto_item *error_item;
222 proto_tree *error_tree;
224 xmpp_element_t *text_element, *cond_element;
226 xmpp_attr_info attrs_info[] = {
227 {"type", hf_xmpp_error_type, TRUE, TRUE, NULL, NULL},
228 {"code", hf_xmpp_error_code, FALSE, TRUE, NULL, NULL},
229 {"condition", hf_xmpp_error_condition, TRUE, TRUE, NULL, NULL} /*TODO: validate list to the condition element*/
232 gchar *error_info;
234 xmpp_attr_t *fake_condition = NULL;
236 error_info = wmem_strdup(wmem_packet_scope(), "Stanza error");
238 error_item = proto_tree_add_item(tree, hf_xmpp_error, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
239 error_tree = proto_item_add_subtree(error_item, ett_xmpp_query_item);
241 cond_element = xmpp_steal_element_by_attr(element, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
242 if(cond_element)
244 fake_condition = xmpp_ep_init_attr_t(cond_element->name, cond_element->offset, cond_element->length);
245 g_hash_table_insert(element->attrs, (gpointer)"condition", fake_condition);
247 error_info = wmem_strdup_printf(wmem_packet_scope(), "%s: %s;", error_info, cond_element->name);
251 xmpp_display_attrs(error_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
253 while((text_element = xmpp_steal_element_by_name(element, "text")) != NULL)
255 xmpp_error_text(error_tree, tvb, text_element);
257 error_info = wmem_strdup_printf(wmem_packet_scope(), "%s Text: %s", error_info, text_element->data?text_element->data->value:"");
260 expert_add_info_format(pinfo, error_item, &ei_xmpp_response, "%s", error_info);
262 xmpp_unknown(error_tree, tvb, pinfo, element);
265 static void
266 xmpp_error_text(proto_tree *tree, tvbuff_t *tvb, xmpp_element_t *element)
268 proto_tree_add_string(tree, hf_xmpp_error_text, tvb, element->offset, element->length, element->data?element->data->value:"");
272 void
273 xmpp_presence(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
275 proto_item *presence_item;
276 proto_tree *presence_tree;
278 static const gchar *type_enums[] = {"error", "probe", "subscribe", "subscribed",
279 "unavailable", "unsubscribe", "unsubscribed"};
280 xmpp_array_t *type_array = xmpp_ep_init_array_t(type_enums, array_length(type_enums));
282 static const gchar *show_enums[] = {"away", "chat", "dnd", "xa"};
283 xmpp_array_t *show_array = xmpp_ep_init_array_t(show_enums, array_length(show_enums));
285 xmpp_attr_info attrs_info[] = {
286 {"from", hf_xmpp_from, FALSE, FALSE, NULL, NULL},
287 {"id", hf_xmpp_id, FALSE, TRUE, NULL, NULL},
288 {"to", hf_xmpp_to, FALSE, FALSE, NULL, NULL},
289 {"type", hf_xmpp_type, FALSE, TRUE, xmpp_val_enum_list, type_array},
290 {"xml:lang",-1, FALSE, FALSE, NULL,NULL},
291 {"show", hf_xmpp_presence_show, FALSE, TRUE, xmpp_val_enum_list, show_array},
292 {"priority", -1, FALSE, FALSE, NULL, NULL}
295 xmpp_elem_info elems_info[] = {
296 {NAME, "status", xmpp_presence_status, MANY},
297 {NAME_AND_ATTR, xmpp_name_attr_struct("c","xmlns","http://jabber.org/protocol/caps"), xmpp_presence_caps, ONE},
298 {NAME, "delay", xmpp_delay, ONE},
299 {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns", "jabber:x:delay"), xmpp_delay, ONE},
300 {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns", "vcard-temp:x:update"), xmpp_vcard_x_update, ONE},
301 {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","http://jabber.org/protocol/muc"), xmpp_muc_x, ONE},
302 {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","http://jabber.org/protocol/muc#user"), xmpp_muc_user_x, ONE},
303 {NAME, "error", xmpp_error, ONE},
304 {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:last"), xmpp_last_query, ONE}
308 xmpp_element_t *show, *priority;
310 col_set_str(pinfo->cinfo, COL_INFO, "PRESENCE ");
312 presence_item = proto_tree_add_item(tree, hf_xmpp_presence, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
313 presence_tree = proto_item_add_subtree(presence_item, ett_xmpp_presence);
315 if((show = xmpp_steal_element_by_name(packet, "show"))!=NULL)
317 xmpp_attr_t *fake_show = xmpp_ep_init_attr_t(show->data?show->data->value:"",show->offset, show->length);
318 g_hash_table_insert(packet->attrs, (gpointer)"show", fake_show);
321 if((priority = xmpp_steal_element_by_name(packet, "priority"))!=NULL)
323 xmpp_attr_t *fake_priority = xmpp_ep_init_attr_t(priority->data?priority->data->value:"",priority->offset, priority->length);
324 g_hash_table_insert(packet->attrs, (gpointer)"priority", fake_priority);
326 xmpp_display_attrs(presence_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
328 xmpp_display_elems(presence_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
331 static void
332 xmpp_presence_status(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
334 proto_item *status_item;
335 proto_tree *status_tree;
337 xmpp_attr_info attrs_info[] = {
338 {"xml:lang", -1, FALSE, TRUE, NULL, NULL},
339 {"value", -1, TRUE, TRUE, NULL, NULL}
342 xmpp_attr_t *fake_value;
344 status_item = proto_tree_add_item(tree, hf_xmpp_presence_status, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
345 status_tree = proto_item_add_subtree(status_item, ett_xmpp_presence_status);
347 if(element->data)
348 fake_value = xmpp_ep_init_attr_t(element->data->value, element->offset, element->length);
349 else
350 fake_value = xmpp_ep_init_attr_t("(empty)", element->offset, element->length);
353 g_hash_table_insert(element->attrs, (gpointer)"value", fake_value);
355 xmpp_display_attrs(status_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
357 xmpp_unknown(status_tree, tvb, pinfo, element);
361 void
362 xmpp_message(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
364 proto_item *message_item;
365 proto_tree *message_tree;
367 static const gchar *type_enums[] = {"chat", "error", "groupchat", "headline", "normal"};
368 xmpp_array_t *type_array = xmpp_ep_init_array_t(type_enums, array_length(type_enums));
370 xmpp_attr_info attrs_info[] = {
371 {"from", hf_xmpp_from, FALSE, FALSE, NULL, NULL},
372 {"id", hf_xmpp_id, FALSE, TRUE, NULL, NULL},
373 {"to", hf_xmpp_to, FALSE, FALSE, NULL, NULL},
374 {"type", hf_xmpp_type, FALSE, TRUE, xmpp_val_enum_list, type_array},
375 {"xml:lang",-1, FALSE, FALSE, NULL,NULL},
376 {"chatstate", hf_xmpp_message_chatstate, FALSE, TRUE, NULL, NULL}
379 xmpp_elem_info elems_info [] = {
380 {NAME_AND_ATTR, xmpp_name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE},
381 {NAME, "thread", xmpp_message_thread, ONE},
382 {NAME, "body", xmpp_message_body, MANY},
383 {NAME, "subject", xmpp_message_subject, MANY},
384 {NAME, "delay", xmpp_delay, ONE},
385 {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","jabber:x:event"), xmpp_x_event, ONE},
386 {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","http://jabber.org/protocol/muc#user"), xmpp_muc_user_x, ONE},
387 {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","google:nosave"), xmpp_gtalk_nosave_x, ONE},
388 {NAME, "error", xmpp_error, ONE}
391 xmpp_element_t *chatstate;
393 xmpp_attr_t *id;
395 conversation_t *conversation;
396 xmpp_conv_info_t *xmpp_info;
398 col_set_str(pinfo->cinfo, COL_INFO, "MESSAGE ");
400 id = xmpp_get_attr(packet, "id");
402 conversation = find_or_create_conversation(pinfo);
403 xmpp_info = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp);
405 message_item = proto_tree_add_item(tree, hf_xmpp_message, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
406 message_tree = proto_item_add_subtree(message_item, ett_xmpp_message);
408 if((chatstate = xmpp_steal_element_by_attr(packet, "xmlns", "http://jabber.org/protocol/chatstates"))!=NULL)
410 xmpp_attr_t *fake_chatstate_attr = xmpp_ep_init_attr_t(chatstate->name, chatstate->offset, chatstate->length);
411 g_hash_table_insert(packet->attrs, (gpointer)"chatstate", fake_chatstate_attr);
414 xmpp_display_attrs(message_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
416 xmpp_display_elems(message_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
418 /*Displays data about IBB session*/
419 if(xmpp_info && id)
421 gchar *ibb_sid;
423 ibb_sid = (gchar *)wmem_tree_lookup_string(xmpp_info->ibb_sessions, id->value, WMEM_TREE_STRING_NOCASE);
425 if (ibb_sid) {
426 proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid);
427 PROTO_ITEM_SET_GENERATED(it);
433 static void
434 xmpp_message_body(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
436 proto_item *body_item;
437 proto_tree *body_tree;
439 xmpp_attr_info attrs_info[] = {
440 {"xml:lang", -1, FALSE, TRUE, NULL, NULL},
441 {"value", -1, TRUE, TRUE, NULL, NULL}
444 xmpp_attr_t *fake_data_attr;
446 body_item = proto_tree_add_item(tree, hf_xmpp_message_body, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
447 body_tree = proto_item_add_subtree(body_item, ett_xmpp_message_body);
449 fake_data_attr = xmpp_ep_init_attr_t(element->data?element->data->value:"", element->offset, element->length);
450 g_hash_table_insert(element->attrs, (gpointer)"value", fake_data_attr);
453 xmpp_display_attrs(body_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
455 xmpp_unknown(body_tree, tvb, pinfo, element);
458 static void
459 xmpp_message_subject(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element) {
460 proto_item *subject_item;
461 proto_tree *subject_tree;
463 xmpp_attr_info attrs_info[] = {
464 {"xml:lang", -1, FALSE, TRUE, NULL, NULL},
465 {"value", -1, TRUE, FALSE, NULL, NULL}
468 xmpp_attr_t *fake_data_attr;
470 subject_item = proto_tree_add_item(tree, hf_xmpp_message_subject, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
471 subject_tree = proto_item_add_subtree(subject_item, ett_xmpp_message_subject);
473 fake_data_attr = xmpp_ep_init_attr_t(element->data?element->data->value:"", element->offset, element->length);
474 g_hash_table_insert(element->attrs, (gpointer)"value", fake_data_attr);
477 xmpp_display_attrs(subject_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
479 xmpp_unknown(subject_tree, tvb, pinfo, element);
482 static void
483 xmpp_message_thread(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
485 proto_item *thread_item;
486 proto_tree *thread_tree;
488 xmpp_attr_info attrs_info[] = {
489 {"parent", hf_xmpp_message_thread_parent, FALSE, TRUE, NULL, NULL},
490 {"value", -1, TRUE, TRUE, NULL, NULL}
493 xmpp_attr_t *fake_value;
495 thread_item = proto_tree_add_item(tree, hf_xmpp_message_thread, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
496 thread_tree = proto_item_add_subtree(thread_item, ett_xmpp_message_thread);
498 fake_value = xmpp_ep_init_attr_t(element->data?element->data->value:"", element->offset, element->length);
499 g_hash_table_insert(element->attrs, (gpointer)"value", fake_value);
502 xmpp_display_attrs(thread_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
504 xmpp_unknown(thread_tree, tvb, pinfo, element);
507 void
508 xmpp_auth(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
510 proto_item *auth_item;
511 proto_tree *auth_tree;
513 xmpp_attr_info_ext attrs_info[]={
514 {"urn:ietf:params:xml:ns:xmpp-sasl", {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}},
515 {"urn:ietf:params:xml:ns:xmpp-sasl", {"mechanism", -1, TRUE, TRUE, NULL, NULL}},
516 {"http://www.google.com/talk/protocol/auth", {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}},
517 {"http://www.google.com/talk/protocol/auth", {"client-uses-full-bind-result", -1, TRUE, TRUE, NULL, NULL}},
520 col_set_str(pinfo->cinfo, COL_INFO, "AUTH");
522 auth_item = proto_tree_add_item(tree, hf_xmpp_auth, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
523 auth_tree = proto_item_add_subtree(auth_item, ett_xmpp_auth);
525 xmpp_display_attrs_ext(auth_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
527 xmpp_cdata(auth_tree, tvb, packet, -1);
529 xmpp_unknown(auth_tree, tvb, pinfo, packet);
532 void
533 xmpp_challenge_response_success(proto_tree *tree, tvbuff_t *tvb,
534 packet_info *pinfo, xmpp_element_t *packet, expert_field* ei, gint ett, const char *col_info)
536 proto_item *item;
537 proto_tree *subtree;
539 xmpp_attr_info attrs_info[] = {
540 {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
543 col_set_str(pinfo->cinfo, COL_INFO, col_info);
545 item = proto_tree_add_expert(tree, pinfo, ei, tvb, packet->offset, packet->length);
546 subtree = proto_item_add_subtree(item, ett);
548 xmpp_display_attrs(subtree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
549 xmpp_cdata(subtree, tvb, packet, -1);
551 xmpp_unknown(subtree, tvb, pinfo, packet);
554 void
555 xmpp_failure(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
557 proto_item *fail_item;
558 proto_tree *fail_tree;
560 xmpp_attr_info attrs_info[] = {
561 {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
562 {"condition", -1, FALSE, TRUE, NULL, NULL}
565 static const gchar *fail_names[] = {"aborted","account-disabled", "credentials-expired",
566 "encryption-required", "incorrect-encoding", "invalid-authzid", "invalid-mechanism",
567 "malformed-request", "mechanism-too-weak", "not-authorized", "temporary-auth-failure",
568 "transition-needed"
571 xmpp_element_t *fail_condition, *text;
573 col_add_fstr(pinfo->cinfo, COL_INFO, "FAILURE ");
575 fail_item = proto_tree_add_item(tree, hf_xmpp_failure, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
576 fail_tree = proto_item_add_subtree(fail_item, ett_xmpp_failure);
578 if((fail_condition = xmpp_steal_element_by_names(packet, fail_names, array_length(fail_names)))!=NULL)
580 xmpp_attr_t *fake_cond = xmpp_ep_init_attr_t(fail_condition->name, fail_condition->offset, fail_condition->length);
581 g_hash_table_insert(packet->attrs, (gpointer)"condition", fake_cond);
584 if((text = xmpp_steal_element_by_name(packet, "text"))!=NULL)
586 xmpp_failure_text(fail_tree, tvb, text);
589 xmpp_display_attrs(fail_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
591 xmpp_unknown(fail_tree, tvb, pinfo, packet);
594 static void
595 xmpp_failure_text(proto_tree *tree, tvbuff_t *tvb, xmpp_element_t *element)
597 xmpp_attr_t *lang = xmpp_get_attr(element,"xml:lang");
599 proto_tree_add_text(tree, tvb, element->offset, element->length, "TEXT%s: %s",
600 lang?wmem_strdup_printf(wmem_packet_scope(), "(%s)",lang->value):"",
601 element->data?element->data->value:"");
604 void
605 xmpp_xml_header(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, xmpp_element_t *packet)
607 col_add_fstr(pinfo->cinfo, COL_INFO, "XML ");
608 proto_tree_add_text(tree, tvb, packet->offset, packet->length, "XML HEADER VER. %s","1.0");
611 void
612 xmpp_stream(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
614 proto_item *stream_item;
615 proto_tree *stream_tree;
617 xmpp_attr_info_ext attrs_info [] = {
618 {"http://etherx.jabber.org/streams",{"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL}},
619 {"http://etherx.jabber.org/streams",{"version", -1, FALSE, TRUE, NULL, NULL}},
620 {"http://etherx.jabber.org/streams",{"from",-1, FALSE, TRUE, NULL, NULL}},
621 {"http://etherx.jabber.org/streams",{"to",-1, FALSE, TRUE, NULL, NULL}},
622 {"http://etherx.jabber.org/streams",{"id",-1, FALSE, TRUE, NULL, NULL}},
623 {"http://etherx.jabber.org/streams",{"xml:lang",-1, FALSE, TRUE, NULL, NULL}},
624 {"jabber:client",{"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL}},
628 col_add_fstr(pinfo->cinfo, COL_INFO, "STREAM ");
630 stream_item = proto_tree_add_item(tree, hf_xmpp_stream, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
631 stream_tree = proto_item_add_subtree(stream_item, ett_xmpp_stream);
633 xmpp_display_attrs_ext(stream_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
634 xmpp_display_elems(stream_tree, packet, pinfo, tvb, NULL, 0);
637 /*returns TRUE if stream end occurs*/
638 gboolean
639 xmpp_stream_close(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo)
641 tvbparse_t *tt;
642 tvbparse_elem_t *elem;
644 tt = tvbparse_init(tvb,0,-1,NULL,want_ignore);
646 if((elem = tvbparse_get(tt,want_stream_end_tag))!=NULL)
648 proto_tree_add_text(tree, tvb, elem->offset, elem->len, "STREAM END");
649 col_add_fstr(pinfo->cinfo, COL_INFO, "STREAM END");
651 return TRUE;
653 return FALSE;
656 void
657 xmpp_features(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
659 proto_item *features_item;
660 proto_tree *features_tree;
662 xmpp_elem_info elems_info [] = {
663 {NAME, "mechanisms", xmpp_features_mechanisms, MANY}
666 features_item = proto_tree_add_item(tree, hf_xmpp_features, tvb, packet->offset, packet->length,
667 ENC_BIG_ENDIAN);
668 features_tree = proto_item_add_subtree(features_item, ett_xmpp_features);
670 col_add_fstr(pinfo->cinfo, COL_INFO, "FEATURES ");
672 xmpp_display_attrs(features_tree, packet, pinfo, tvb, NULL, 0);
673 xmpp_display_elems(features_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
676 static void
677 xmpp_features_mechanisms(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
679 proto_item *mechanisms_item;
680 proto_tree *mechanisms_tree;
682 xmpp_attr_info attrs_info [] = {
683 {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
686 xmpp_elem_info elems_info [] = {
687 {NAME, "mechanism", xmpp_simple_cdata_elem, MANY},
690 mechanisms_item = proto_tree_add_text(tree, tvb, packet->offset, packet->length, "MECHANISMS");
691 mechanisms_tree = proto_item_add_subtree(mechanisms_item, ett_xmpp_features_mechanisms);
693 xmpp_display_attrs(mechanisms_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
694 xmpp_display_elems(mechanisms_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
697 void
698 xmpp_starttls(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
699 xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info)
701 proto_item *tls_item;
702 proto_tree *tls_tree;
704 xmpp_attr_info attrs_info [] = {
705 {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
708 col_add_fstr(pinfo->cinfo, COL_INFO, "STARTTLS ");
710 tls_item = proto_tree_add_item(tree, hf_xmpp_starttls, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
711 tls_tree = proto_item_add_subtree(tls_item, ett_xmpp_starttls);
713 if (xmpp_info->ssl_start && xmpp_info->ssl_start != pinfo->fd->num) {
714 expert_add_info_format(pinfo, tls_item, &ei_xmpp_starttls_already_in_frame, "Already saw STARTTLS in frame %u", xmpp_info->ssl_start);
716 else {
717 xmpp_info->ssl_start = pinfo->fd->num;
720 xmpp_display_attrs(tls_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
721 xmpp_display_elems(tls_tree, packet, pinfo, tvb, NULL, 0);
724 void
725 xmpp_proceed(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
726 xmpp_element_t *packet, xmpp_conv_info_t *xmpp_info)
728 proto_item *proceed_item;
729 proto_tree *proceed_tree;
731 xmpp_attr_info attrs_info [] = {
732 {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
735 col_add_fstr(pinfo->cinfo, COL_INFO, "PROCEED ");
737 proceed_item = proto_tree_add_item(tree, hf_xmpp_proceed, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
738 proceed_tree = proto_item_add_subtree(proceed_item, ett_xmpp_proceed);
740 if (!xmpp_info->ssl_start) {
741 expert_add_info(pinfo, proceed_item, &ei_xmpp_starttls_missing);
744 if (xmpp_info->ssl_proceed && xmpp_info->ssl_proceed != pinfo->fd->num) {
745 expert_add_info_format(pinfo, proceed_item, &ei_xmpp_proceed_already_in_frame, "Already saw PROCEED in frame %u", xmpp_info->ssl_proceed);
747 else {
748 xmpp_info->ssl_proceed = pinfo->fd->num;
751 xmpp_display_attrs(proceed_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
752 xmpp_display_elems(proceed_tree, packet, pinfo, tvb, NULL, 0);
755 * Editor modelines - http://www.wireshark.org/tools/modelines.html
757 * Local variables:
758 * c-basic-offset: 4
759 * tab-width: 8
760 * indent-tabs-mode: nil
761 * End:
763 * ex: set shiftwidth=4 tabstop=8 expandtab:
764 * :indentSize=4:tabSize=8:noTabs=true: