aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorAlexis La Goutte <alexis.lagoutte@gmail.com>2011-11-12 10:51:01 +0000
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2011-11-12 10:51:01 +0000
commit292a5b6f93765751cf57278e77b67cd98a4f0bc8 (patch)
tree3522a4b1115ac505a66a52a6abeb6b6799122524 /epan/dissectors
parent640ad2b623e0b77f88c6a4814c1549862cbb4883 (diff)
From Mariusz Okrój and Sebastien Vincent via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6225
Enhance XMPP Dissector XMPP is communication protocol that is based on XML. Existing Jabber dissector has only few filtering possibilities and displays packets in inconvenient way. This dissector is a result of cooperation with Jitsi community as Google Summer of Code project (http://www.jitsi.org/index.php/GSOC2011/XmppWireshark). From me : Add Mariusz Okrój in AUTHORS File Add Modelines information svn path=/trunk/; revision=39799
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/Makefile.common13
-rw-r--r--epan/dissectors/packet-xmpp-conference.c293
-rw-r--r--epan/dissectors/packet-xmpp-conference.h33
-rw-r--r--epan/dissectors/packet-xmpp-core.c755
-rw-r--r--epan/dissectors/packet-xmpp-core.h43
-rw-r--r--epan/dissectors/packet-xmpp-gtalk.c701
-rw-r--r--epan/dissectors/packet-xmpp-gtalk.h40
-rw-r--r--epan/dissectors/packet-xmpp-jingle.c952
-rw-r--r--epan/dissectors/packet-xmpp-jingle.h34
-rw-r--r--epan/dissectors/packet-xmpp-other.c1357
-rw-r--r--epan/dissectors/packet-xmpp-other.h68
-rw-r--r--epan/dissectors/packet-xmpp-utils.c1139
-rw-r--r--epan/dissectors/packet-xmpp-utils.h287
-rw-r--r--epan/dissectors/packet-xmpp.c1485
-rw-r--r--epan/dissectors/packet-xmpp.h344
15 files changed, 7447 insertions, 97 deletions
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
index cf1ba5e774..c548f88811 100644
--- a/epan/dissectors/Makefile.common
+++ b/epan/dissectors/Makefile.common
@@ -1037,6 +1037,12 @@ DISSECTOR_SRC = \
packet-xml.c \
packet-xmcp.c \
packet-xmpp.c \
+ packet-xmpp-conference.c \
+ packet-xmpp-core.c \
+ packet-xmpp-gtalk.c \
+ packet-xmpp-jingle.c \
+ packet-xmpp-other.c \
+ packet-xmpp-utils.c \
packet-xot.c \
packet-xtp.c \
packet-xyplex.c \
@@ -1399,6 +1405,13 @@ DISSECTOR_INCLUDES = \
packet-x509if.h \
packet-x509sat.h \
packet-xml.h \
+ packet-xmpp-conference.h \
+ packet-xmpp-core.h \
+ packet-xmpp-gtalk.h \
+ packet-xmpp.h \
+ packet-xmpp-jingle.h \
+ packet-xmpp-other.h \
+ packet-xmpp-utils.h \
packet-ypbind.h \
packet-yppasswd.h \
packet-ypserv.h \
diff --git a/epan/dissectors/packet-xmpp-conference.c b/epan/dissectors/packet-xmpp-conference.c
new file mode 100644
index 0000000000..0d6ad51bfd
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-conference.c
@@ -0,0 +1,293 @@
+/* xmpp-conference.c
+ * Wireshark's XMPP dissector.
+ *
+ * XEP-0298: Delivering Conference Information to Jingle Participants (Coin)
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <stdio.h>
+
+#include <epan/proto.h>
+#include <epan/packet.h>
+#include <epan/packet_info.h>
+#include <epan/epan.h>
+#include <epan/expert.h>
+#include <epan/dissectors/packet-xml.h>
+
+#include <packet-xmpp.h>
+#include <packet-xmpp-utils.h>
+#include <packet-xmpp-conference.h>
+
+
+static void xmpp_conf_desc(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_conf_state(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_conf_users(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_conf_user(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_conf_endpoint(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_conf_media(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+void
+xmpp_conferece_info_advert(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *cinfo_item;
+ proto_tree *cinfo_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"isfocus", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ cinfo_item = proto_tree_add_item(tree, hf_xmpp_conf_info, tvb, element->offset, element->length,
+ ENC_BIG_ENDIAN);
+ cinfo_tree = proto_item_add_subtree(cinfo_item, ett_xmpp_conf_info);
+
+ display_attrs(cinfo_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(cinfo_tree, element, pinfo, tvb, NULL, 0);
+}
+
+void
+xmpp_conference_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *cinfo_item;
+ proto_tree *cinfo_tree;
+
+ const gchar *state_enums[] = {"full", "partial", "deleted"};
+ array_t *state_array = ep_init_array_t(state_enums, array_length(state_enums));
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"entity", -1, TRUE, TRUE, NULL, NULL},
+ {"state", -1, FALSE, TRUE, val_enum_list, state_array},
+ {"version", -1, FALSE, TRUE, NULL, NULL},
+ {"sid", hf_xmpp_conf_info_sid, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "conference-description", xmpp_conf_desc, ONE},
+ {NAME, "conference-state", xmpp_conf_state, ONE},
+ /*{NAME, "host-info", xmpp_conf_host_info, ONE},*/
+ {NAME, "users", xmpp_conf_users, ONE},
+ /*{NAME, "sidebars-by-ref", xmpp_conf_sidebars_by_ref, ONE},*/
+ /*{NAME, "sidebars-by-val", xmpp_conf_sidebars_by_val, ONE},*/
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "CONFERENC-INFO ");
+
+ cinfo_item = proto_tree_add_item(tree, hf_xmpp_conf_info, tvb, element->offset, element->length,
+ ENC_BIG_ENDIAN);
+ cinfo_tree = proto_item_add_subtree(cinfo_item, ett_xmpp_conf_info);
+
+ display_attrs(cinfo_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(cinfo_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_conf_desc(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *desc_item;
+ proto_tree *desc_tree;
+
+ attr_info attrs_info [] = {
+ {"subject", -1, FALSE, TRUE, NULL, NULL},
+ {"display-text", -1, FALSE, FALSE, NULL, NULL},
+ {"free-text", -1, FALSE, FALSE, NULL, NULL},
+ {"max-user-count", -1, FALSE, FALSE, NULL, NULL},
+ };
+
+/*
+ elem_info elems_info [] = {
+ {NAME, "keywords", xmpp_conf_desc_keywords, ONE},
+ {NAME, "conf-uris", xmpp_conf_desc_conf_uris, ONE},
+ {NAME, "service-uris", xmpp_conf_desc_serv_uris, ONE},
+ {NAME, "available-media", xmpp_conf_desc_avil_media, ONE},
+ };
+*/
+
+ desc_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "CONFERENCE DESCRIPTION");
+ desc_tree = proto_item_add_subtree(desc_item, ett_xmpp_conf_desc);
+
+ change_elem_to_attrib("subject", "subject", element, transform_func_cdata);
+ change_elem_to_attrib("display-text", "display-text", element, transform_func_cdata);
+ change_elem_to_attrib("free-text", "free-text", element, transform_func_cdata);
+ change_elem_to_attrib("maximum-user-count", "max-user-count", element, transform_func_cdata);
+
+ display_attrs(desc_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(desc_tree, element, pinfo, tvb, NULL,0);
+}
+
+static void
+xmpp_conf_state(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *state_item;
+ proto_tree *state_tree;
+
+ attr_info attrs_info [] = {
+ {"user-count", -1, FALSE, TRUE, NULL, NULL},
+ {"active", -1, FALSE, TRUE, NULL, NULL},
+ {"locked", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ state_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "CONFERENCE STATE");
+ state_tree = proto_item_add_subtree(state_item, ett_xmpp_conf_state);
+
+ change_elem_to_attrib("user-count", "user-count", element, transform_func_cdata);
+ change_elem_to_attrib("active", "active", element, transform_func_cdata);
+ change_elem_to_attrib("locked", "locked", element, transform_func_cdata);
+
+ display_attrs(state_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(state_tree, element, pinfo, tvb, NULL,0);
+
+}
+
+static void
+xmpp_conf_users(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *users_item;
+ proto_tree *users_tree;
+
+ attr_info attrs_info [] = {
+ {"state", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "user", xmpp_conf_user, MANY}
+ };
+
+ users_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "USERS");
+ users_tree = proto_item_add_subtree(users_item, ett_xmpp_conf_users);
+
+ display_attrs(users_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(users_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+static void
+xmpp_conf_user(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *user_item;
+ proto_tree *user_tree;
+
+ attr_info attrs_info [] = {
+ {"entity", -1, FALSE, TRUE, NULL, NULL},
+ {"state", -1, FALSE, TRUE, NULL, NULL},
+ {"display-text", -1, FALSE, TRUE, NULL, NULL},
+ {"cascaded-focus", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ /*{NAME, "associated-aors", xmpp_conf_assoc_aors, ONE},*/
+ /*{NAME, "roles", xmpp_conf_roles, ONE},*/
+ /*{NAME, "languages", xmpp_conf_langs, ONE},*/
+ {NAME, "endpoint", xmpp_conf_endpoint, MANY},
+ };
+
+ user_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "USERS");
+ user_tree = proto_item_add_subtree(user_item, ett_xmpp_conf_user);
+
+ change_elem_to_attrib("display-text", "display-text", element, transform_func_cdata);
+ change_elem_to_attrib("cascaded-focus", "cascaded-focus", element, transform_func_cdata);
+
+ display_attrs(user_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(user_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_conf_endpoint(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *endpoint_item;
+ proto_tree *endpoint_tree;
+
+ attr_info attrs_info [] = {
+ {"entity", -1, FALSE, TRUE, NULL, NULL},
+ {"state", -1, FALSE, TRUE, NULL, NULL},
+ {"display-text", -1, FALSE, TRUE, NULL, NULL},
+ {"status", -1, FALSE, TRUE, NULL, NULL},
+ {"joining-method", -1, FALSE, TRUE, NULL, NULL},
+ {"disconnection-method", -1, FALSE, TRUE, NULL, NULL},
+ };
+
+ elem_info elems_info [] = {
+ /*{NAME,"referred",...,ONE},*/
+ /*{NAME,"joining-info",...,ONE},*/
+ /*{NAME,"disconnection-info",...,ONE},*/
+ {NAME,"media", xmpp_conf_media, ONE},
+ /*{NAME,"call-info",...,ONE},*/
+
+ };
+
+ endpoint_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "ENDPOINT");
+ endpoint_tree = proto_item_add_subtree(endpoint_item, ett_xmpp_conf_endpoint);
+
+ change_elem_to_attrib("display-text", "display-text", element, transform_func_cdata);
+ change_elem_to_attrib("status", "status", element, transform_func_cdata);
+ change_elem_to_attrib("joining-method", "joining-method", element, transform_func_cdata);
+ change_elem_to_attrib("disconnection-method", "disconnection-method", element, transform_func_cdata);
+
+
+ display_attrs(endpoint_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(endpoint_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_conf_media(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *media_item;
+ proto_tree *media_tree;
+
+ attr_info attrs_info[] = {
+ {"id", -1, TRUE, TRUE, NULL, NULL},
+ {"display-text", -1, FALSE, TRUE, NULL, NULL},
+ {"type", -1, FALSE, TRUE, NULL, NULL},
+ {"label", -1, FALSE, TRUE, NULL, NULL},
+ {"src-id", -1, FALSE, TRUE, NULL, NULL},
+ {"status", -1, FALSE, TRUE, NULL, NULL},
+ };
+
+ media_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "MEDIA");
+ media_tree = proto_item_add_subtree(media_item, ett_xmpp_conf_media);
+
+ change_elem_to_attrib("display-text", "display-text", element, transform_func_cdata);
+ change_elem_to_attrib("type", "type", element, transform_func_cdata);
+ change_elem_to_attrib("label", "label", element, transform_func_cdata);
+ change_elem_to_attrib("src-id", "src-id", element, transform_func_cdata);
+ change_elem_to_attrib("status", "status", element, transform_func_cdata);
+
+ display_attrs(media_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(media_tree, element, pinfo, tvb, NULL, 0);
+}
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-xmpp-conference.h b/epan/dissectors/packet-xmpp-conference.h
new file mode 100644
index 0000000000..9f8d48b169
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-conference.h
@@ -0,0 +1,33 @@
+/* xmpp-conference.h
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef XMPP_CONFERENCE_H
+#define XMPP_CONFERENCE_H
+
+extern void xmpp_conferece_info_advert(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_conference_info(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+#endif /* XMPP_CONFERENCE_H */
+
diff --git a/epan/dissectors/packet-xmpp-core.c b/epan/dissectors/packet-xmpp-core.c
new file mode 100644
index 0000000000..3a1cf4c8b9
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-core.c
@@ -0,0 +1,755 @@
+/* xmpp-core.c
+ * Wireshark's XMPP dissector.
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include<stdio.h>
+#include<string.h>
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/proto.h>
+#include <epan/tvbuff.h>
+#include <epan/emem.h>
+#include <epan/conversation.h>
+#include <epan/strutil.h>
+#include <epan/expert.h>
+
+#include <epan/dissectors/packet-xml.h>
+
+#include <packet-xmpp-utils.h>
+#include <packet-xmpp.h>
+#include <packet-xmpp-core.h>
+#include <packet-xmpp-jingle.h>
+#include <packet-xmpp-other.h>
+#include <packet-xmpp-gtalk.h>
+#include <packet-xmpp-conference.h>
+
+#include <epan/strutil.h>
+
+#include "epan/tvbparse.h"
+
+
+void xmpp_auth(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+void xmpp_challenge_response_success(proto_tree *tree, tvbuff_t *tvb,
+ packet_info *pinfo, element_t *packet, gint hf, gint ett, const char *col_info);
+
+void xmpp_iq(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+
+static void xmpp_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_error_text(proto_tree *tree, tvbuff_t *tvb, element_t *element);
+
+void xmpp_presence(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+static void xmpp_presence_status(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+void xmpp_message(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+static void xmpp_message_thread(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_message_body(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_message_subject(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+void xmpp_failure(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+static void xmpp_failure_text(proto_tree *tree, tvbuff_t *tvb, element_t *element);
+
+static void xmpp_features_mechanisms(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+
+void
+xmpp_iq(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *xmpp_iq_item;
+ proto_tree *xmpp_iq_tree;
+
+ attr_t *attr_id, *attr_type;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"id", hf_xmpp_id, TRUE, TRUE, NULL, NULL},
+ {"type", hf_xmpp_type, TRUE, TRUE, NULL, NULL},
+ {"from", hf_xmpp_from, FALSE, TRUE, NULL, NULL},
+ {"to", hf_xmpp_to, FALSE, TRUE, NULL, NULL},
+ {"xml:lang", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ conversation_t *conversation = NULL;
+ xmpp_conv_info_t *xmpp_info = NULL;
+ xmpp_transaction_t *reqresp_trans = NULL;
+
+ elem_info elems_info [] = {
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns","http://jabber.org/protocol/disco#items"), xmpp_disco_items_query, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns", "jabber:iq:roster"), xmpp_roster_query, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns", "http://jabber.org/protocol/disco#info"), xmpp_disco_info_query, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns", "http://jabber.org/protocol/bytestreams"), xmpp_bytestreams_query, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#owner"), xmpp_muc_owner_query, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#admin"), xmpp_muc_admin_query, ONE},
+ {NAME, "bind", xmpp_iq_bind, ONE},
+ {NAME_AND_ATTR, name_attr_struct("session", "xmlns", "urn:ietf:params:xml:ns:xmpp-session"), xmpp_session, ONE},
+ {NAME, "vCard", xmpp_vcard, ONE},
+ {NAME, "jingle", xmpp_jingle, ONE},
+ {NAME_AND_ATTR, name_attr_struct("services", "xmlns", "http://jabber.org/protocol/jinglenodes"), xmpp_jinglenodes_services, ONE},
+ {NAME_AND_ATTR, name_attr_struct("channel", "xmlns", "http://jabber.org/protocol/jinglenodes#channel"), xmpp_jinglenodes_channel, ONE},
+ {NAME_AND_ATTR, name_attr_struct("open", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_open, ONE},
+ {NAME_AND_ATTR, name_attr_struct("close", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_close, ONE},
+ {NAME_AND_ATTR, name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE},
+ {NAME, "si", xmpp_si, ONE},
+ {NAME, "error", xmpp_error, ONE},
+ {NAME_AND_ATTR, name_attr_struct("session", "xmlns", "http://www.google.com/session"), xmpp_gtalk_session, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns","google:jingleinfo"), xmpp_gtalk_jingleinfo_query, ONE},
+ {NAME_AND_ATTR, name_attr_struct("usersetting", "xmlns","google:setting"), xmpp_gtalk_usersetting, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns","jabber:iq:last"), xmpp_last_query, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns","jabber:iq:version"), xmpp_version_query, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns","google:mail:notify"), xmpp_gtalk_mail_query, ONE},
+ {NAME, "mailbox", xmpp_gtalk_mail_mailbox, ONE},
+ {NAME, "new-mail", xmpp_gtalk_mail_new_mail, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns","google:shared-status"), xmpp_gtalk_status_query, ONE},
+ {NAME, "conference-info", xmpp_conference_info, ONE},
+ {NAME_AND_ATTR, name_attr_struct("ping", "xmlns","urn:xmpp:ping"), xmpp_ping, ONE},
+ {NAME_AND_ATTR, name_attr_struct("inputevt", "xmlns","http://jitsi.org/protocol/inputevt"), xmpp_jitsi_inputevt, ONE},
+ };
+
+ attr_id = get_attr(packet, "id");
+ attr_type = get_attr(packet, "type");
+
+ conversation = find_or_create_conversation(pinfo);
+ xmpp_info = conversation_get_proto_data(conversation, proto_xmpp);
+
+ xmpp_iq_item = proto_tree_add_item(tree, hf_xmpp_iq, tvb, packet->offset, packet->length, ENC_LITTLE_ENDIAN);
+ xmpp_iq_tree = proto_item_add_subtree(xmpp_iq_item,ett_xmpp_iq);
+
+ display_attrs(xmpp_iq_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_add_fstr(pinfo->cinfo, COL_INFO, "IQ(%s) ", attr_type?attr_type->value:"");
+
+ display_elems(xmpp_iq_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
+
+ /*displays generated info such as req/resp tracking, jingle sid
+ * in each packet related to specified jingle session and IBB sid in packet related to it*/
+ if(xmpp_info && attr_id)
+ {
+ gchar *jingle_sid, *ibb_sid, *gtalk_sid;
+
+ jingle_sid = se_tree_lookup_string(xmpp_info->jingle_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE);
+
+ if (jingle_sid) {
+ proto_item *it = proto_tree_add_string(tree, hf_xmpp_jingle_session, tvb, 0, 0, jingle_sid);
+ PROTO_ITEM_SET_GENERATED(it);
+ }
+
+ ibb_sid = se_tree_lookup_string(xmpp_info->ibb_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE);
+
+ if (ibb_sid) {
+ proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid);
+ PROTO_ITEM_SET_GENERATED(it);
+ }
+
+ gtalk_sid = se_tree_lookup_string(xmpp_info->gtalk_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE);
+
+ if (gtalk_sid) {
+ proto_item *it = proto_tree_add_string(tree, hf_xmpp_gtalk, tvb, 0, 0, gtalk_sid);
+ PROTO_ITEM_SET_GENERATED(it);
+ }
+
+ reqresp_trans = se_tree_lookup_string(xmpp_info->req_resp, attr_id->value, EMEM_TREE_STRING_NOCASE);
+ /*displays request/response field in each iq packet*/
+ if (reqresp_trans) {
+
+ if (reqresp_trans->req_frame == pinfo->fd->num) {
+ if (reqresp_trans->resp_frame) {
+ proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_in, tvb, 0, 0, reqresp_trans->resp_frame);
+ PROTO_ITEM_SET_GENERATED(it);
+ } else
+ {
+ expert_add_info_format(pinfo, xmpp_iq_item , PI_PROTOCOL, PI_CHAT, "Packet without response");
+ }
+
+ } else {
+ if (reqresp_trans->req_frame) {
+ proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_to, tvb, 0, 0, reqresp_trans->req_frame);
+ PROTO_ITEM_SET_GENERATED(it);
+ } else
+ {
+ expert_add_info_format(pinfo, xmpp_iq_item , PI_PROTOCOL, PI_CHAT, "Packet without response");
+ }
+ }
+ }
+ }
+
+
+}
+
+
+static void
+xmpp_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *error_item;
+ proto_tree *error_tree;
+
+ element_t *text_element, *cond_element;
+
+ attr_info attrs_info[] = {
+ {"type", hf_xmpp_error_type, TRUE, TRUE, NULL, NULL},
+ {"code", hf_xmpp_error_code, FALSE, TRUE, NULL, NULL},
+ {"condition", hf_xmpp_error_condition, TRUE, TRUE, NULL, NULL} /*TODO: validate list to the condition element*/
+ };
+
+ gchar *error_info;
+
+ attr_t *fake_condition = NULL;
+
+ error_info = ep_strdup("Stanza error");
+
+ error_item = proto_tree_add_item(tree, hf_xmpp_error, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ error_tree = proto_item_add_subtree(error_item, ett_xmpp_query_item);
+
+ cond_element = steal_element_by_attr(element, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ if(cond_element)
+ {
+ fake_condition = ep_init_attr_t(cond_element->name, cond_element->offset, cond_element->length);
+ g_hash_table_insert(element->attrs,"condition", fake_condition);
+
+ error_info = ep_strdup_printf("%s: %s;", error_info, cond_element->name);
+ }
+
+
+ display_attrs(error_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ while((text_element = steal_element_by_name(element, "text")) != NULL)
+ {
+ xmpp_error_text(error_tree, tvb, text_element);
+
+ error_info = ep_strdup_printf("%s Text: %s", error_info, text_element->data?text_element->data->value:"");
+ }
+
+ expert_add_info_format(pinfo, error_item, PI_RESPONSE_CODE, PI_CHAT,"%s", error_info);
+
+ xmpp_unknown(error_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_error_text(proto_tree *tree, tvbuff_t *tvb, element_t *element)
+{
+ proto_tree_add_string(tree, hf_xmpp_error_text, tvb, element->offset, element->length, element->data?element->data->value:"");
+}
+
+
+void
+xmpp_presence(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *presence_item;
+ proto_tree *presence_tree;
+
+ const gchar *type_enums[] = {"error", "probe", "subscribe", "subscribed",
+ "unavailable", "unsubscribe", "unsubscribed"};
+ array_t *type_array = ep_init_array_t(type_enums, array_length(type_enums));
+
+ const gchar *show_enums[] = {"away", "chat", "dnd", "xa"};
+ array_t *show_array = ep_init_array_t(show_enums, array_length(show_enums));
+
+ attr_info attrs_info[] = {
+ {"from", hf_xmpp_from, FALSE, FALSE, NULL, NULL},
+ {"id", hf_xmpp_id, FALSE, TRUE, NULL, NULL},
+ {"to", hf_xmpp_to, FALSE, FALSE, NULL, NULL},
+ {"type", hf_xmpp_type, FALSE, TRUE, val_enum_list, type_array},
+ {"xml:lang",-1, FALSE, FALSE, NULL,NULL},
+ {"show", hf_xmpp_presence_show, FALSE, TRUE, val_enum_list, show_array},
+ {"priority", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "status", xmpp_presence_status, MANY},
+ {NAME_AND_ATTR, name_attr_struct("c","xmlns","http://jabber.org/protocol/caps"), xmpp_presence_caps, ONE},
+ {NAME, "delay", xmpp_delay, ONE},
+ {NAME_AND_ATTR, name_attr_struct("x","xmlns", "jabber:x:delay"), xmpp_delay, ONE},
+ {NAME_AND_ATTR, name_attr_struct("x","xmlns", "vcard-temp:x:update"), xmpp_vcard_x_update, ONE},
+ {NAME_AND_ATTR, name_attr_struct("x","xmlns","http://jabber.org/protocol/muc"), xmpp_muc_x, ONE},
+ {NAME_AND_ATTR, name_attr_struct("x","xmlns","http://jabber.org/protocol/muc#user"), xmpp_muc_user_x, ONE},
+ {NAME, "error", xmpp_error, ONE},
+ {NAME_AND_ATTR, name_attr_struct("query", "xmlns","jabber:iq:last"), xmpp_last_query, ONE}
+ };
+
+
+ element_t *show, *priority;
+
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "PRESENCE ");
+
+ presence_item = proto_tree_add_item(tree, hf_xmpp_presence, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
+ presence_tree = proto_item_add_subtree(presence_item, ett_xmpp_presence);
+
+ if((show = steal_element_by_name(packet, "show"))!=NULL)
+ {
+ attr_t *fake_show = ep_init_attr_t(show->data?show->data->value:"",show->offset, show->length);
+ g_hash_table_insert(packet->attrs, "show", fake_show);
+ }
+
+ if((priority = steal_element_by_name(packet, "priority"))!=NULL)
+ {
+ attr_t *fake_priority = ep_init_attr_t(priority->data?priority->data->value:"",priority->offset, priority->length);
+ g_hash_table_insert(packet->attrs, "priority", fake_priority);
+ }
+ display_attrs(presence_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(presence_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_presence_status(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *status_item;
+ proto_tree *status_tree;
+
+ attr_info attrs_info[] = {
+ {"xml:lang", -1, FALSE, TRUE, NULL, NULL},
+ {"value", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ attr_t *fake_value;
+
+ status_item = proto_tree_add_item(tree, hf_xmpp_presence_status, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ status_tree = proto_item_add_subtree(status_item, ett_xmpp_presence_status);
+
+ if(element->data)
+ fake_value = ep_init_attr_t(element->data->value, element->offset, element->length);
+ else
+ fake_value = ep_init_attr_t("(empty)", element->offset, element->length);
+
+
+ g_hash_table_insert(element->attrs, "value", fake_value);
+
+ display_attrs(status_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(status_tree, tvb, pinfo, element);
+}
+
+
+void
+xmpp_message(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *message_item;
+ proto_tree *message_tree;
+
+ const gchar *type_enums[] = {"chat", "error", "groupchat", "headline", "normal"};
+ array_t *type_array = ep_init_array_t(type_enums, array_length(type_enums));
+
+ attr_info attrs_info[] = {
+ {"from", hf_xmpp_from, FALSE, FALSE, NULL, NULL},
+ {"id", hf_xmpp_id, FALSE, TRUE, NULL, NULL},
+ {"to", hf_xmpp_to, FALSE, FALSE, NULL, NULL},
+ {"type", hf_xmpp_type, FALSE, TRUE, val_enum_list, type_array},
+ {"xml:lang",-1, FALSE, FALSE, NULL,NULL},
+ {"chatstate", hf_xmpp_message_chatstate, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME_AND_ATTR, name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE},
+ {NAME, "thread", xmpp_message_thread, ONE},
+ {NAME, "body", xmpp_message_body, MANY},
+ {NAME, "subject", xmpp_message_subject, MANY},
+ {NAME, "delay", xmpp_delay, ONE},
+ {NAME_AND_ATTR, name_attr_struct("x","xmlns","jabber:x:event"), xmpp_x_event, ONE},
+ {NAME_AND_ATTR, name_attr_struct("x","xmlns","http://jabber.org/protocol/muc#user"), xmpp_muc_user_x, ONE},
+ {NAME_AND_ATTR, name_attr_struct("x","xmlns","google:nosave"), xmpp_gtalk_nosave_x, ONE},
+ {NAME, "error", xmpp_error, ONE}
+ };
+
+ element_t *chatstate;
+
+ attr_t *id = NULL;
+
+ conversation_t *conversation = NULL;
+ xmpp_conv_info_t *xmpp_info = NULL;
+
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "MESSAGE ");
+
+ id = get_attr(packet, "id");
+
+ conversation = find_or_create_conversation(pinfo);
+ xmpp_info = conversation_get_proto_data(conversation, proto_xmpp);
+
+ message_item = proto_tree_add_item(tree, hf_xmpp_message, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
+ message_tree = proto_item_add_subtree(message_item, ett_xmpp_message);
+
+ if((chatstate = steal_element_by_attr(packet, "xmlns", "http://jabber.org/protocol/chatstates"))!=NULL)
+ {
+ attr_t *fake_chatstate_attr = ep_init_attr_t(chatstate->name, chatstate->offset, chatstate->length);
+ g_hash_table_insert(packet->attrs, "chatstate", fake_chatstate_attr);
+ }
+
+ display_attrs(message_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(message_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
+
+ /*Displays data about IBB session*/
+ if(xmpp_info && id)
+ {
+ gchar *ibb_sid;
+
+ ibb_sid = se_tree_lookup_string(xmpp_info->ibb_sessions, id->value, EMEM_TREE_STRING_NOCASE);
+
+ if (ibb_sid) {
+ proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid);
+ PROTO_ITEM_SET_GENERATED(it);
+ }
+
+ }
+}
+
+static void
+xmpp_message_body(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *body_item;
+ proto_tree *body_tree;
+
+ attr_info attrs_info[] = {
+ {"xml:lang", -1, FALSE, TRUE, NULL, NULL},
+ {"value", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ attr_t *fake_data_attr;
+
+ body_item = proto_tree_add_item(tree, hf_xmpp_message_body, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ body_tree = proto_item_add_subtree(body_item, ett_xmpp_message_body);
+
+ fake_data_attr = ep_init_attr_t(element->data?element->data->value:"", element->offset, element->length);
+ g_hash_table_insert(element->attrs, "value", fake_data_attr);
+
+
+ display_attrs(body_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(body_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_message_subject(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element) {
+ proto_item *subject_item;
+ proto_tree *subject_tree;
+
+ attr_info attrs_info[] = {
+ {"xml:lang", -1, FALSE, TRUE, NULL, NULL},
+ {"value", -1, TRUE, FALSE, NULL, NULL}
+ };
+
+ attr_t *fake_data_attr;
+
+ subject_item = proto_tree_add_item(tree, hf_xmpp_message_subject, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ subject_tree = proto_item_add_subtree(subject_item, ett_xmpp_message_subject);
+
+ fake_data_attr = ep_init_attr_t(element->data?element->data->value:"", element->offset, element->length);
+ g_hash_table_insert(element->attrs, "value", fake_data_attr);
+
+
+ display_attrs(subject_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(subject_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_message_thread(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *thread_item;
+ proto_tree *thread_tree;
+
+ attr_info attrs_info[] = {
+ {"parent", hf_xmpp_message_thread_parent, FALSE, TRUE, NULL, NULL},
+ {"value", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ attr_t *fake_value;
+
+ thread_item = proto_tree_add_item(tree, hf_xmpp_message_thread, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ thread_tree = proto_item_add_subtree(thread_item, ett_xmpp_message_thread);
+
+ fake_value = ep_init_attr_t(element->data?element->data->value:"", element->offset, element->length);
+ g_hash_table_insert(element->attrs, "value", fake_value);
+
+
+ display_attrs(thread_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(thread_tree, tvb, pinfo, element);
+}
+
+void
+xmpp_auth(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *auth_item;
+ proto_tree *auth_tree;
+
+ attr_info_ext attrs_info[]={
+ {"urn:ietf:params:xml:ns:xmpp-sasl", {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}},
+ {"urn:ietf:params:xml:ns:xmpp-sasl", {"mechanism", -1, TRUE, TRUE, NULL, NULL}},
+ {"http://www.google.com/talk/protocol/auth", {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}},
+ {"http://www.google.com/talk/protocol/auth", {"client-uses-full-bind-result", -1, TRUE, TRUE, NULL, NULL}},
+ };
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, "AUTH");
+
+ auth_item = proto_tree_add_item(tree, hf_xmpp_auth, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
+ auth_tree = proto_item_add_subtree(auth_item, ett_xmpp_auth);
+
+ display_attrs_ext(auth_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_cdata(auth_tree, tvb, packet, -1);
+
+ xmpp_unknown(auth_tree, tvb, pinfo, packet);
+}
+
+void
+xmpp_challenge_response_success(proto_tree *tree, tvbuff_t *tvb,
+ packet_info *pinfo, element_t *packet, gint hf, gint ett, const char *col_info)
+{
+ proto_item *item;
+ proto_tree *subtree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, col_info);
+
+ item = proto_tree_add_item(tree, hf, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
+ subtree = proto_item_add_subtree(item, ett);
+
+ display_attrs(subtree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+ xmpp_cdata(subtree, tvb, packet, -1);
+
+ xmpp_unknown(subtree, tvb, pinfo, packet);
+}
+
+void
+xmpp_failure(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *fail_item;
+ proto_tree *fail_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"condition", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ const gchar *fail_names[] = {"aborted","account-disabled", "credentials-expired",
+ "encryption-required", "incorrect-encoding", "invalid-authzid", "invalid-mechanism",
+ "malformed-request", "mechanism-too-weak", "not-authorized", "temporary-auth-failure",
+ "transition-needed"
+ };
+
+ element_t *fail_condition, *text;
+
+ col_add_fstr(pinfo->cinfo, COL_INFO, "FAILURE ");
+
+ fail_item = proto_tree_add_item(tree, hf_xmpp_failure, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
+ fail_tree = proto_item_add_subtree(fail_item, ett_xmpp_failure);
+
+ if((fail_condition = steal_element_by_names(packet, fail_names, array_length(fail_names)))!=NULL)
+ {
+ attr_t *fake_cond = ep_init_attr_t(fail_condition->name, fail_condition->offset, fail_condition->length);
+ g_hash_table_insert(packet->attrs, "condition", fake_cond);
+ }
+
+ if((text = steal_element_by_name(packet, "text"))!=NULL)
+ {
+ xmpp_failure_text(fail_tree, tvb, text);
+ }
+
+ display_attrs(fail_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(fail_tree, tvb, pinfo, packet);
+}
+
+static void
+xmpp_failure_text(proto_tree *tree, tvbuff_t *tvb, element_t *element)
+{
+ attr_t *lang = get_attr(element,"xml:lang");
+
+ proto_tree_add_text(tree, tvb, element->offset, element->length, "TEXT%s: %s",
+ lang?ep_strdup_printf("(%s)",lang->value):"",
+ element->data?element->data->value:"");
+}
+
+void
+xmpp_xml_header(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, element_t *packet)
+{
+ col_add_fstr(pinfo->cinfo, COL_INFO, "XML ");
+ proto_tree_add_text(tree, tvb, packet->offset, packet->length, "XML HEADER VER. %s","1.0");
+}
+
+void
+xmpp_stream(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *stream_item;
+ proto_tree *stream_tree;
+
+ attr_info_ext attrs_info [] = {
+ {"http://etherx.jabber.org/streams",{"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL}},
+ {"http://etherx.jabber.org/streams",{"version", -1, FALSE, TRUE, NULL, NULL}},
+ {"http://etherx.jabber.org/streams",{"from",-1, FALSE, TRUE, NULL, NULL}},
+ {"http://etherx.jabber.org/streams",{"to",-1, FALSE, TRUE, NULL, NULL}},
+ {"http://etherx.jabber.org/streams",{"id",-1, FALSE, TRUE, NULL, NULL}},
+ {"http://etherx.jabber.org/streams",{"xml:lang",-1, FALSE, TRUE, NULL, NULL}},
+ {"jabber:client",{"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL}},
+
+ };
+
+ col_add_fstr(pinfo->cinfo, COL_INFO, "STREAM ");
+
+ stream_item = proto_tree_add_item(tree, hf_xmpp_stream, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
+ stream_tree = proto_item_add_subtree(stream_item, ett_xmpp_stream);
+
+ display_attrs_ext(stream_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(stream_tree, packet, pinfo, tvb, NULL, 0);
+}
+
+/*returns TRUE if stream end occurs*/
+gboolean
+xmpp_stream_close(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo)
+{
+ tvbparse_t* tt;
+ tvbparse_elem_t* elem;
+ tvbparse_wanted_t* want_ignore = tvbparse_chars(1,1,0," \t\r\n",NULL,NULL,NULL);
+ tvbparse_wanted_t* want_name = tvbparse_chars(2,1,0,"abcdefghijklmnopqrstuvwxyz.-_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",NULL,NULL,NULL);
+ tvbparse_wanted_t* want_stream_end_with_ns = tvbparse_set_seq(3, NULL, NULL, NULL,
+ want_name,
+ tvbparse_char(4, ":", NULL, NULL, NULL),
+ want_name,
+ NULL);
+
+ tvbparse_wanted_t* want_stream_end = tvbparse_set_oneof(5, NULL, NULL, NULL,
+ want_stream_end_with_ns,
+ want_name,
+ NULL);
+
+ tvbparse_wanted_t* want_stream_end_tag = tvbparse_set_seq(6, NULL, NULL, NULL,
+ tvbparse_string(-1,"</",NULL,NULL,NULL),
+ want_stream_end,
+ tvbparse_char(-1,">",NULL,NULL,NULL),
+ NULL);
+ tt = tvbparse_init(tvb,0,-1,NULL,want_ignore);
+
+ if((elem = tvbparse_get(tt,want_stream_end_tag))!=NULL)
+ {
+ proto_tree_add_text(tree, tvb, elem->offset, elem->len, "STREAM END");
+ col_add_fstr(pinfo->cinfo, COL_INFO, "STREAM END");
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+xmpp_features(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *features_item;
+ proto_tree *features_tree;
+
+ elem_info elems_info [] = {
+ {NAME, "mechanisms", xmpp_features_mechanisms, MANY}
+ };
+
+ features_item = proto_tree_add_item(tree, hf_xmpp_features, tvb, packet->offset, packet->length,
+ ENC_BIG_ENDIAN);
+ features_tree = proto_item_add_subtree(features_item, ett_xmpp_features);
+
+ col_add_fstr(pinfo->cinfo, COL_INFO, "FEATURES ");
+
+ display_attrs(features_tree, packet, pinfo, tvb, NULL, 0);
+ display_elems(features_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_features_mechanisms(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *mechanisms_item;
+ proto_tree *mechanisms_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "mechanism", xmpp_simple_cdata_elem, MANY},
+ };
+
+ mechanisms_item = proto_tree_add_text(tree, tvb, packet->offset, packet->length, "MECHANISMS");
+ mechanisms_tree = proto_item_add_subtree(mechanisms_item, ett_xmpp_features_mechanisms);
+
+ display_attrs(mechanisms_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(mechanisms_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+void
+xmpp_starttls(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *tls_item;
+ proto_tree *tls_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ };
+
+ col_add_fstr(pinfo->cinfo, COL_INFO, "STARTTLS ");
+
+ tls_item = proto_tree_add_item(tree, hf_xmpp_starttls, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
+ tls_tree = proto_item_add_subtree(tls_item, ett_xmpp_starttls);
+
+ display_attrs(tls_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(tls_tree, packet, pinfo, tvb, NULL, 0);
+}
+
+void
+xmpp_proceed(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet)
+{
+ proto_item *proceed_item;
+ proto_tree *proceed_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ };
+
+ col_add_fstr(pinfo->cinfo, COL_INFO, "PROCEED ");
+
+ proceed_item = proto_tree_add_item(tree, hf_xmpp_proceed, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
+ proceed_tree = proto_item_add_subtree(proceed_item, ett_xmpp_proceed);
+
+ display_attrs(proceed_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(proceed_tree, packet, pinfo, tvb, NULL, 0);
+}
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-xmpp-core.h b/epan/dissectors/packet-xmpp-core.h
new file mode 100644
index 0000000000..e3de62854e
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-core.h
@@ -0,0 +1,43 @@
+/* xmpp-core.h
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef XMPP_CORE_H
+#define XMPP_CORE_H
+
+extern void xmpp_iq(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern void xmpp_presence(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern void xmpp_message(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern void xmpp_auth(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern void xmpp_challenge_response_success(proto_tree *tree, tvbuff_t *tvb,
+ packet_info *pinfo, element_t *packet, gint hf, gint ett, const char *col_info);
+extern void xmpp_failure(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern void xmpp_xml_header(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern void xmpp_stream(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern gboolean xmpp_stream_close(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo);
+extern void xmpp_features(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern void xmpp_starttls(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+extern void xmpp_proceed(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *packet);
+#endif /* XMPP_CORE_H */
+
diff --git a/epan/dissectors/packet-xmpp-gtalk.c b/epan/dissectors/packet-xmpp-gtalk.c
new file mode 100644
index 0000000000..462c97261f
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-gtalk.c
@@ -0,0 +1,701 @@
+/* xmpp-gtalk.c
+ * Wireshark's XMPP dissector.
+ *
+ * GTalk extensions.
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include<stdio.h>
+#include<string.h>
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/proto.h>
+#include <epan/tvbuff.h>
+#include <epan/emem.h>
+#include <epan/conversation.h>
+#include <epan/strutil.h>
+#include <epan/expert.h>
+#include <epan/dissectors/packet-xml.h>
+
+#include <packet-xmpp.h>
+#include <packet-xmpp-utils.h>
+#include <packet-xmpp-gtalk.h>
+#include <packet-xmpp-conference.h>
+
+
+static void xmpp_gtalk_session_desc(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_session_desc_payload(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_session_cand(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_session_reason(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_jingleinfo_stun(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_jingleinfo_server(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_jingleinfo_relay(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_jingleinfo_relay_serv(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_nosave_item(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_mail_mail_info(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_mail_senders(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_mail_sender(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_mail_snippet(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_status_status_list(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_gtalk_transport_p2p_cand(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+
+void
+xmpp_gtalk_session(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *session_item;
+ proto_tree *session_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"type", hf_xmpp_gtalk_session_type, TRUE, TRUE, NULL, NULL},
+ {"initiator", -1, FALSE, TRUE, NULL, NULL},
+ {"id", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME,"description", xmpp_gtalk_session_desc, ONE},
+ {NAME, "candidate", xmpp_gtalk_session_cand, MANY},
+ {NAME, "reason", xmpp_gtalk_session_reason, ONE},
+ {NAME_AND_ATTR, name_attr_struct("transport", "xmlns", "http://www.google.com/transport/p2p"), xmpp_gtalk_transport_p2p, ONE},
+ {NAME, "conference-info", xmpp_conferece_info_advert, ONE}
+ };
+
+ attr_t *attr_type = get_attr(element, "type");
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "GTALK-SESSION(%s) ", attr_type?attr_type->value:"");
+
+ session_item = proto_tree_add_item(tree, hf_xmpp_gtalk_session, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ session_tree = proto_item_add_subtree(session_item, ett_xmpp_gtalk_session);
+
+ display_attrs(session_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(session_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_session_desc(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *desc_item;
+ proto_tree *desc_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"xml:lang", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "payload-type", xmpp_gtalk_session_desc_payload, MANY}
+ };
+
+ desc_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "DESCRIPTION");
+ desc_tree = proto_item_add_subtree(desc_item, ett_xmpp_gtalk_session_desc);
+
+ display_attrs(desc_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(desc_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_session_desc_payload(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *payload_item;
+ proto_tree *payload_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL},
+ {"id", -1, FALSE, TRUE, NULL, NULL},
+ {"name", -1, FALSE, TRUE, NULL, NULL},
+ {"channels", -1, FALSE, FALSE, NULL, NULL},
+ {"clockrate", -1, FALSE, FALSE, NULL, NULL},
+ {"bitrate", -1, FALSE, FALSE, NULL, NULL},
+ {"width", -1, FALSE, FALSE, NULL, NULL},
+ {"height", -1, FALSE, FALSE, NULL, NULL},
+ {"framerate", -1, FALSE, FALSE, NULL, NULL},
+ };
+
+ payload_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "PAYLOAD-TYPE");
+ payload_tree = proto_item_add_subtree(payload_item, ett_xmpp_gtalk_session_desc_payload);
+
+ display_attrs(payload_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(payload_tree, element, pinfo, tvb, NULL, 0);
+}
+
+static void
+xmpp_gtalk_session_cand(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *cand_item;
+ proto_tree *cand_tree;
+
+ attr_info attrs_info[] = {
+ {"name", -1, TRUE, TRUE, NULL, NULL},
+ {"address", -1, TRUE, FALSE, NULL, NULL},
+ {"port", -1, TRUE, FALSE, NULL, NULL},
+ {"preference", -1, TRUE, FALSE, NULL, NULL},
+ {"type", -1, TRUE, TRUE, NULL, NULL},
+ {"protocol", -1, TRUE, TRUE, NULL, NULL},
+ {"network", -1, TRUE, FALSE, NULL, NULL},
+ {"username", -1, TRUE, FALSE, NULL, NULL},
+ {"password", -1, TRUE, FALSE, NULL, NULL},
+ {"generation", -1, TRUE, FALSE, NULL, NULL},
+ {"foundation", -1, FALSE, FALSE, NULL, NULL},
+ {"component", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ cand_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "CANDIDATE");
+ cand_tree = proto_item_add_subtree(cand_item, ett_xmpp_gtalk_session_cand);
+
+ display_attrs(cand_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(cand_tree, element, pinfo, tvb, NULL, 0);
+}
+
+static void
+xmpp_gtalk_session_reason(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *reason_item;
+ proto_tree *reason_tree;
+
+ attr_info attrs_info[] = {
+ {"condition", -1, TRUE, TRUE, NULL, NULL},
+ {"text", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ element_t *condition;
+ element_t *text;
+
+ const gchar *reason_names[] = { "success", "busy", "cancel"};
+
+ reason_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "REASON");
+ reason_tree = proto_item_add_subtree(reason_item, ett_xmpp_gtalk_session_reason);
+
+
+ /*Looks for reason description.*/
+ if((condition = steal_element_by_names(element, reason_names, array_length(reason_names)))!=NULL)
+ {
+ attr_t *fake_cond = ep_init_attr_t(condition->name, condition->offset, condition->length);
+ g_hash_table_insert(element->attrs, "condition", fake_cond);
+
+ }
+
+ if((text = steal_element_by_name(element, "text"))!=NULL)
+ {
+ attr_t *fake_text = ep_init_attr_t(text->data?text->data->value:"", text->offset, text->length);
+ g_hash_table_insert(element->attrs, "text", fake_text);
+ }
+
+ display_attrs(reason_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(reason_tree, tvb, pinfo, element);
+}
+
+void
+xmpp_gtalk_jingleinfo_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "stun", xmpp_gtalk_jingleinfo_stun, ONE},
+ {NAME, "relay", xmpp_gtalk_jingleinfo_relay, ONE}
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(google:jingleinfo) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length,
+ ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(query_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_jingleinfo_stun(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *stun_item;
+ proto_tree *stun_tree;
+
+ elem_info elems_info [] = {
+ {NAME, "server", xmpp_gtalk_jingleinfo_server, MANY},
+ };
+
+ stun_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "STUN");
+ stun_tree = proto_item_add_subtree(stun_item, ett_xmpp_gtalk_jingleinfo_stun);
+
+ display_attrs(stun_tree, element, pinfo, tvb, NULL, 0);
+ display_elems(stun_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+
+}
+
+static void
+xmpp_gtalk_jingleinfo_server(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *serv_item;
+ proto_tree *serv_tree;
+
+ attr_info attrs_info[] = {
+ {"host", -1, TRUE, TRUE, NULL, NULL},
+ {"udp", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ serv_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "SERVER");
+ serv_tree = proto_item_add_subtree(serv_item, ett_xmpp_gtalk_jingleinfo_server);
+
+ display_attrs(serv_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(serv_tree, element, pinfo, tvb, NULL, 0);
+}
+
+static void
+xmpp_gtalk_jingleinfo_relay(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *relay_item;
+ proto_tree *relay_tree;
+
+ attr_info attrs_info[] = {
+ {"token", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "server", xmpp_gtalk_jingleinfo_relay_serv, ONE}
+ };
+
+ element_t *token;
+
+ relay_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "RELAY");
+ relay_tree = proto_item_add_subtree(relay_item, ett_xmpp_gtalk_jingleinfo_relay);
+
+ if((token = steal_element_by_name(element, "token"))!=NULL)
+ {
+ attr_t *fake_token = ep_init_attr_t(token->data?token->data->value:"", token->offset, token->length);
+ g_hash_table_insert(element->attrs, "token", fake_token);
+ }
+
+ display_attrs(relay_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(relay_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_jingleinfo_relay_serv(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *serv_item;
+ proto_tree *serv_tree;
+
+ attr_info attrs_info[] = {
+ {"host", -1, TRUE, TRUE, NULL, NULL},
+ {"udp", -1, FALSE, TRUE, NULL, NULL},
+ {"tcp", -1, FALSE, TRUE, NULL, NULL},
+ {"tcpssl", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ serv_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "SERVER");
+ serv_tree = proto_item_add_subtree(serv_item, ett_xmpp_gtalk_jingleinfo_relay_serv);
+
+ display_attrs(serv_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(serv_tree, element, pinfo, tvb, NULL, 0);
+}
+
+void
+xmpp_gtalk_usersetting(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *sett_item;
+ proto_tree *sett_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ guint i;
+
+ sett_item = proto_tree_add_item(tree, hf_xmpp_gtalk_setting, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ sett_tree = proto_item_add_subtree(sett_item, ett_xmpp_gtalk_setting);
+
+ display_attrs(sett_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ for(i = 0; i < g_list_length(element->elements); i++)
+ {
+ GList *elem_l = g_list_nth(element->elements,i);
+ element_t *elem = elem_l?elem_l->data:NULL;
+
+ if(elem)
+ {
+ attr_t *val = get_attr(elem,"value");
+ proto_tree_add_text(sett_tree, tvb, elem->offset, elem->length, "%s [%s]",elem->name,val?val->value:"");
+ }
+ }
+}
+
+void
+xmpp_gtalk_nosave_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element) {
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "item", xmpp_gtalk_nosave_item, MANY},
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(google:nosave) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length,
+ ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(query_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_nosave_item(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *item_item;
+ proto_tree *item_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL,NULL},
+ {"jid", -1, TRUE, TRUE, NULL, NULL},
+ {"source", -1, FALSE, TRUE, NULL, NULL},
+ {"value", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ item_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "ITEM");
+ item_tree = proto_item_add_subtree(item_item, ett_xmpp_query_item);
+
+ display_attrs(item_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(item_tree, element, pinfo, tvb, NULL, 0);
+}
+
+void
+xmpp_gtalk_nosave_x(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *x_item;
+ proto_tree *x_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"value", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ x_item = proto_tree_add_item(tree, hf_xmpp_gtalk_nosave_x, tvb, element->offset, element->length,
+ ENC_BIG_ENDIAN);
+ x_tree = proto_item_add_subtree(x_item, ett_xmpp_gtalk_nosave_x);
+
+ display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(x_tree, element, pinfo, tvb, NULL, 0);
+}
+
+void
+xmpp_gtalk_mail_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"newer-than-time", -1, FALSE, TRUE, NULL, NULL},
+ {"newer-than-tid", -1, FALSE, TRUE, NULL, NULL},
+ {"q", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(google:mail:notify) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length,
+ ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(query_tree, element, pinfo, tvb, NULL, 0);
+}
+
+void
+xmpp_gtalk_mail_mailbox(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *mail_item;
+ proto_tree *mail_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL},
+ {"result-time", -1, FALSE, TRUE, NULL, NULL},
+ {"total-matched", -1, FALSE, TRUE, NULL, NULL},
+ {"total-estimate", -1, FALSE, TRUE, NULL, NULL},
+ {"url", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME,"mail-thread-info", xmpp_gtalk_mail_mail_info, MANY}
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "MAILBOX ");
+
+ mail_item = proto_tree_add_item(tree, hf_xmpp_gtalk_mail_mailbox, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ mail_tree = proto_item_add_subtree(mail_item, ett_xmpp_gtalk_mail_mailbox);
+
+ display_attrs(mail_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(mail_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_mail_mail_info(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *mail_info_item;
+ proto_tree *mail_info_tree;
+
+ attr_info attrs_info [] = {
+ {"tid", -1, FALSE, FALSE, NULL, NULL},
+ {"participation", -1, FALSE, FALSE, NULL, NULL},
+ {"messages", -1, FALSE, TRUE, NULL, NULL},
+ {"date", -1, FALSE, TRUE, NULL, NULL},
+ {"url", -1, FALSE, FALSE, NULL, NULL},
+ {"labels", -1, FALSE, FALSE, NULL, NULL},
+ {"subject", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "senders", xmpp_gtalk_mail_senders, ONE},
+ {NAME, "snippet", xmpp_gtalk_mail_snippet, ONE}/*or MANY?*/
+ };
+
+ element_t *labels, *subject;
+
+ mail_info_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "MAIL-THREAD-INFO");
+ mail_info_tree = proto_item_add_subtree(mail_info_item,ett_xmpp_gtalk_mail_mail_info);
+
+ if((labels = steal_element_by_name(element,"labels"))!=NULL)
+ {
+ attr_t *fake_labels = ep_init_attr_t(labels->data?labels->data->value:"",labels->offset, labels->length);
+ g_hash_table_insert(element->attrs, "labels", fake_labels);
+ }
+ if((subject = steal_element_by_name(element,"subject"))!=NULL)
+ {
+ attr_t *fake_subject = ep_init_attr_t(subject->data?subject->data->value:"",subject->offset, subject->length);
+ g_hash_table_insert(element->attrs, "subject", fake_subject);
+ }
+
+ display_attrs(mail_info_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(mail_info_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+
+static void
+xmpp_gtalk_mail_senders(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *senders_item;
+ proto_tree *senders_tree;
+
+ elem_info elems_info [] = {
+ {NAME, "sender", xmpp_gtalk_mail_sender, MANY}
+ };
+
+ senders_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "SENDERS");
+ senders_tree = proto_item_add_subtree(senders_item, ett_xmpp_gtalk_mail_senders);
+
+ display_attrs(senders_tree, element, pinfo, tvb, NULL, 0);
+ display_elems(senders_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_mail_sender(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *sender_item;
+ proto_tree *sender_tree;
+
+ attr_info attrs_info [] = {
+ {"name", -1, FALSE, TRUE, NULL, NULL},
+ {"address", -1, FALSE, TRUE, NULL, NULL},
+ {"originator", -1, FALSE, TRUE, NULL, NULL},
+ {"unread", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ sender_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "SENDER");
+ sender_tree = proto_item_add_subtree(sender_item, ett_xmpp_gtalk_mail_sender);
+
+ display_attrs(sender_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(sender_tree, element, pinfo, tvb, NULL, 0);
+}
+
+static void
+xmpp_gtalk_mail_snippet(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_tree_add_text(tree, tvb, element->offset, element->length, "SNIPPET: %s",element->data?element->data->value:"");
+ xmpp_unknown(tree, tvb, pinfo, element);
+}
+
+void
+xmpp_gtalk_mail_new_mail(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ col_append_fstr(pinfo->cinfo, COL_INFO, "NEW-MAIL ");
+ proto_tree_add_item(tree, hf_xmpp_gtalk_mail_new_mail, tvb, element->offset, element->length,
+ ENC_BIG_ENDIAN);
+ xmpp_unknown(tree, tvb, pinfo, element);
+}
+
+
+void
+xmpp_gtalk_status_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"version", -1, FALSE, TRUE, NULL, NULL},
+ {"status-max", -1, FALSE, FALSE, NULL, NULL},
+ {"status-list-max", -1, FALSE, FALSE, NULL, NULL},
+ {"status-list-contents-max", -1, FALSE, FALSE, NULL, NULL},
+ {"status-min-ver", -1, FALSE, TRUE, NULL, NULL},
+ {"show", -1, FALSE, TRUE, NULL, NULL},
+ {"status", -1, FALSE, TRUE, NULL, NULL},
+ {"invisible", -1, FALSE, TRUE, NULL, NULL},
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "status-list", xmpp_gtalk_status_status_list, MANY}
+ };
+
+ element_t *status, *show, *invisible;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(google:shared-status) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length,
+ ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ if((status = steal_element_by_name(element,"status"))!=NULL)
+ {
+ attr_t *fake_status = ep_init_attr_t(status->data?status->data->value:"",status->offset, status->length);
+ g_hash_table_insert(element->attrs, "status", fake_status);
+ }
+
+ if((show = steal_element_by_name(element,"show"))!=NULL)
+ {
+ attr_t *fake_show = ep_init_attr_t(show->data?show->data->value:"",show->offset, show->length);
+ g_hash_table_insert(element->attrs, "show", fake_show);
+ }
+
+ if((invisible = steal_element_by_name(element,"invisible"))!=NULL)
+ {
+ attr_t *value = get_attr(invisible, "value");
+ attr_t *fake_invisible = ep_init_attr_t(value?value->value:"",invisible->offset, invisible->length);
+ g_hash_table_insert(element->attrs, "invisible", fake_invisible);
+ }
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(query_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_status_status_list(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *list_item;
+ proto_tree *list_tree;
+
+ attr_info attrs_info [] = {
+ {"show", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ element_t *status;
+
+ list_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "STATUS LIST");
+ list_tree = proto_item_add_subtree(list_item, ett_xmpp_gtalk_status_status_list);
+
+ while((status = steal_element_by_name(element, "status"))!=NULL)
+ {
+ proto_tree_add_text(list_tree, tvb, status->offset, status->length, "STATUS: %s",status->data?status->data->value:"");
+ }
+
+ display_attrs(list_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(list_tree, element, pinfo, tvb, NULL, 0);
+}
+
+/*http://www.google.com/transport/p2p*/
+void
+xmpp_gtalk_transport_p2p(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *trans_item;
+ proto_tree *trans_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "candidate", xmpp_gtalk_transport_p2p_cand, MANY}
+ };
+
+ trans_item = proto_tree_add_item(tree, hf_xmpp_gtalk_transport_p2p, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ trans_tree = proto_item_add_subtree(trans_item, ett_xmpp_gtalk_transport_p2p);
+
+ display_attrs(trans_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(trans_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_gtalk_transport_p2p_cand(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element) {
+ proto_item *cand_item;
+ proto_tree *cand_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"name", -1, FALSE, TRUE, NULL, NULL},
+ {"generation", -1, FALSE, FALSE, NULL, NULL},
+ {"network", -1, FALSE, FALSE, NULL, NULL},
+ {"component", -1, FALSE, FALSE, NULL, NULL},
+ {"type", -1, FALSE, FALSE, NULL, NULL},
+ {"protocol", -1, FALSE, TRUE, NULL, NULL},
+ {"preference", -1, FALSE, FALSE, NULL, NULL},
+ {"password", -1, FALSE, FALSE, NULL, NULL},
+ {"username", -1, FALSE, FALSE, NULL, NULL},
+ {"port", -1, FALSE, TRUE, NULL, NULL},
+ {"address", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ cand_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "CANDIDATE");
+ cand_tree = proto_item_add_subtree(cand_item, ett_xmpp_gtalk_transport_p2p_cand);
+
+ display_attrs(cand_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(cand_tree, element, pinfo, tvb, NULL, 0);
+
+}
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-xmpp-gtalk.h b/epan/dissectors/packet-xmpp-gtalk.h
new file mode 100644
index 0000000000..f699feb23f
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-gtalk.h
@@ -0,0 +1,40 @@
+/* xmpp-gtalk.h
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef XMPP_GTALK_H
+#define XMPP_GTALK_H
+
+extern void xmpp_gtalk_session(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_jingleinfo_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_usersetting(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_nosave_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_nosave_x(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_mail_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_mail_mailbox(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_mail_new_mail(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_status_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_gtalk_transport_p2p(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+#endif /* XMPP_GTALK_H */
+
diff --git a/epan/dissectors/packet-xmpp-jingle.c b/epan/dissectors/packet-xmpp-jingle.c
new file mode 100644
index 0000000000..d0c79997b4
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-jingle.c
@@ -0,0 +1,952 @@
+/* xmpp-jingle.c
+ * Wireshark's XMPP dissector.
+ *
+ * urn:xmpp:jingle:1
+ * urn:xmpp:jingle:apps:rtp:1
+ * urn:xmpp:jingle:apps:rtp:errors:1
+ * urn:xmpp:jingle:apps:rtp:info:1
+ * urn:xmpp:jingle:apps:rtp:rtp-hdrext:0
+ * urn:xmpp:jingle:apps:rtp:izrtp:1
+ *
+ * urn:xmpp:jingle:transports:ice-udp:1
+ * urn:xmpp:jingle:transports:raw-udp:1
+ * urn:xmpp:jingle:transports:s5b:1
+ * urn:xmpp:jingle:transports:ibb:1
+ *
+ * http://jabber.org/protocol/jinglenodes
+ * http://jabber.org/protocol/jinglenodes#channel
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <stdio.h>
+
+#include <epan/proto.h>
+#include <epan/packet.h>
+#include <epan/packet_info.h>
+#include <epan/epan.h>
+#include <epan/expert.h>
+#include <epan/dissectors/packet-xml.h>
+
+#include <packet-xmpp.h>
+#include <packet-xmpp-utils.h>
+#include <packet-xmpp-jingle.h>
+#include <packet-xmpp-conference.h>
+#include <packet-xmpp-gtalk.h>
+#include <packet-xmpp-other.h>
+
+void xmpp_jingle(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+static void xmpp_jingle_content(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_content_description_rtp(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_cont_desc_rtp_payload(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_cont_desc_rtp_payload_param(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element);
+static void xmpp_jingle_cont_desc_rtp_enc(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element);
+static void xmpp_jingle_cont_desc_rtp_enc_zrtp_hash(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element);
+static void xmpp_jingle_cont_desc_rtp_enc_crypto(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element);
+static void xmpp_jingle_cont_desc_rtp_bandwidth(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element);
+static void xmpp_jingle_cont_desc_rtp_hdrext(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element);
+static void xmpp_jingle_cont_trans_ice(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_ice_candidate(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_cont_trans_ice_remote_candidate(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_reason(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_rtp_info(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jinglenodes_relay_stun_tracker(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_raw(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_raw_candidate(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_cont_trans_s5b(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_s5b_candidate(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_s5b_activated(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_s5b_cand_used(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_s5b_cand_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_s5b_proxy_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_jingle_cont_trans_ibb(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+static void xmpp_jingle_file_transfer_desc(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_file_transfer_offer(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_file_transfer_file(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_file_transfer_request(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_file_transfer_received(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_file_transfer_abort(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_jingle_file_transfer_checksum(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+
+/*XEP-0166: Jingle urn:xmpp:jingle:1*/
+void
+xmpp_jingle(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *jingle_item;
+ proto_tree *jingle_tree;
+
+ const gchar *rtp_info_msgs[] = {"active", "hold", "mute", "ringing", "unhold", "unmute"};
+
+ const gchar *action_enums[] = {"content-accept","content-add", "content-modify",
+ "content-modify", "content-remove", "description-info", "security-info",
+ "session-accept", "session-info", "session-initiate", "session-terminate",
+ "transport-accept", "transport-info", "transport-reject", "transport-replace"
+ };
+
+ array_t *action_array = ep_init_array_t(action_enums,array_length(action_enums));
+ array_t *rtp_info_array = ep_init_array_t(rtp_info_msgs, array_length(rtp_info_msgs));
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"action", hf_xmpp_jingle_action, TRUE, TRUE, val_enum_list, action_array},
+ {"sid", hf_xmpp_jingle_sid, TRUE, FALSE, NULL, NULL},
+ {"initiator", hf_xmpp_jingle_initiator, FALSE, FALSE, NULL, NULL},
+ {"responder", hf_xmpp_jingle_responder, FALSE, FALSE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "content", xmpp_jingle_content, MANY},
+ {NAME, "reason", xmpp_jingle_reason, MANY},
+ {NAMES, rtp_info_array, xmpp_jingle_rtp_info, ONE},
+ {NAME, "conference-info", xmpp_conferece_info_advert, ONE}
+ };
+
+ attr_t *action = get_attr(element,"action");
+ col_append_fstr(pinfo->cinfo, COL_INFO, "JINGLE(%s) ", action?action->value:"");
+
+
+ jingle_item = proto_tree_add_item(tree, hf_xmpp_jingle, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ jingle_tree = proto_item_add_subtree(jingle_item, ett_xmpp_jingle);
+
+ display_attrs(jingle_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(jingle_item, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_content(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *content_item;
+ proto_tree *content_tree;
+
+ const gchar *creator_enums[] = {"initiator","responder"};
+ array_t *creator_enums_array = ep_init_array_t(creator_enums,array_length(creator_enums));
+
+ attr_info attrs_info[] = {
+ {"creator", hf_xmpp_jingle_content_creator, TRUE, FALSE, val_enum_list, creator_enums_array},
+ {"name", hf_xmpp_jingle_content_name, TRUE, TRUE, NULL, NULL},
+ {"disposition", hf_xmpp_jingle_content_disposition, FALSE, FALSE, NULL, NULL},
+ {"senders", hf_xmpp_jingle_content_senders, FALSE, FALSE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME_AND_ATTR, name_attr_struct("description", "xmlns", "urn:xmpp:jingle:apps:rtp:1"), xmpp_jingle_content_description_rtp, MANY},
+ {NAME_AND_ATTR, name_attr_struct("description", "xmlns", "urn:xmpp:jingle:apps:file-transfer:3"), xmpp_jingle_file_transfer_desc, MANY},
+ {NAME_AND_ATTR, name_attr_struct("transport", "xmlns", "urn:xmpp:jingle:transports:ice-udp:1"), xmpp_jingle_cont_trans_ice, MANY},
+ {NAME_AND_ATTR, name_attr_struct("transport", "xmlns", "urn:xmpp:jingle:transports:raw-udp:1"), xmpp_jingle_cont_trans_raw, MANY},
+ {NAME_AND_ATTR, name_attr_struct("transport", "xmlns", "urn:xmpp:jingle:transports:s5b:1"), xmpp_jingle_cont_trans_s5b, MANY},
+ {NAME_AND_ATTR, name_attr_struct("transport", "xmlns", "urn:xmpp:jingle:transports:ibb:1"), xmpp_jingle_cont_trans_ibb, MANY},
+ {NAME_AND_ATTR, name_attr_struct("transport", "xmlns", "http://www.google.com/transport/p2p"), xmpp_gtalk_transport_p2p, MANY},
+ {NAME_AND_ATTR, name_attr_struct("received", "xmlns", "urn:xmpp:jingle:apps:file-transfer:3"), xmpp_jingle_file_transfer_received, MANY},
+ {NAME_AND_ATTR, name_attr_struct("abort", "xmlns", "urn:xmpp:jingle:apps:file-transfer:3"), xmpp_jingle_file_transfer_abort, MANY},
+ {NAME_AND_ATTR, name_attr_struct("checksum", "xmlns", "urn:xmpp:jingle:apps:file-transfer:3"), xmpp_jingle_file_transfer_checksum, MANY},
+ {NAME_AND_ATTR, name_attr_struct("inputevt", "xmlns","http://jitsi.org/protocol/inputevt"), xmpp_jitsi_inputevt, ONE},
+ };
+
+ content_item = proto_tree_add_item(tree, hf_xmpp_jingle_content, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ content_tree = proto_item_add_subtree(content_item, ett_xmpp_jingle_content);
+
+ display_attrs(content_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(content_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_reason(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *reason_item;
+ proto_tree *reason_tree;
+
+ attr_info attrs_info[] = {
+ {"condition", hf_xmpp_jingle_reason_condition, TRUE, TRUE, NULL, NULL},
+ {"sid", -1, FALSE, TRUE, NULL, NULL},
+ {"rtp-error", -1, FALSE, TRUE, NULL, NULL},
+ {"text", hf_xmpp_jingle_reason_text, FALSE, FALSE, NULL, NULL}
+ };
+
+ element_t *condition; /*1?*/
+ element_t *text; /*0-1*/
+ element_t *rtp_error;
+
+ const gchar *reason_names[] = { "success", "busy", "failed-application", "cancel", "connectivity-error",
+ "decline", "expired", "failed-transport", "general-error", "gone", "incompatible-parameters",
+ "media-error", "security-error", "timeout", "unsupported-applications", "unsupported-transports"};
+
+ const gchar *rtp_error_names[] = {"crypto-required", "invalid-crypto"};
+
+ reason_item = proto_tree_add_item(tree, hf_xmpp_jingle_reason, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ reason_tree = proto_item_add_subtree(reason_item, ett_xmpp_jingle_reason);
+
+
+ /*Looks for reason description. "alternative-session" may contain "sid" element
+ Elements are changed into attribute*/
+ if((condition = steal_element_by_names(element, reason_names, array_length(reason_names)))!=NULL)
+ {
+ attr_t *fake_cond = ep_init_attr_t(condition->name, condition->offset, condition->length);
+ g_hash_table_insert(element->attrs, "condition", fake_cond);
+
+ } else if((condition = steal_element_by_name(element, "alternative-session"))!=NULL)
+ {
+ attr_t *fake_cond,*fake_alter_sid;
+ element_t *sid;
+
+ fake_cond = ep_init_attr_t(condition->name, condition->offset, condition->length);
+ g_hash_table_insert(element->attrs, "condition", fake_cond);
+
+
+ if((sid = steal_element_by_name(condition, "sid"))!=NULL)
+ {
+ fake_alter_sid = ep_init_attr_t(sid->name, sid->offset, sid->length);
+ g_hash_table_insert(element->attrs, "sid", fake_alter_sid);
+ }
+ }
+
+ if((rtp_error = steal_element_by_names(element, rtp_error_names, array_length(rtp_error_names)))!=NULL)
+ {
+ attr_t *fake_rtp_error = ep_init_attr_t(rtp_error->name, rtp_error->offset, rtp_error->length);
+ g_hash_table_insert(element->attrs, "rtp-error", fake_rtp_error);
+ }
+
+ if((text = steal_element_by_name(element, "text"))!=NULL)
+ {
+ attr_t *fake_text = ep_init_attr_t(text->data?text->data->value:"", text->offset, text->length);
+ g_hash_table_insert(element->attrs, "text", fake_text);
+ }
+
+ display_attrs(reason_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(reason_tree, tvb, pinfo, element);
+}
+
+/*XEP-0167: Jingle RTP Sessions urn:xmpp:jingle:apps:rtp:1*/
+static void
+xmpp_jingle_content_description_rtp(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *desc_item;
+ proto_tree *desc_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"media", hf_xmpp_jingle_content_description_media, TRUE, TRUE, NULL, NULL},
+ {"ssrc", hf_xmpp_jingle_content_description_ssrc , FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "payload-type", xmpp_jingle_cont_desc_rtp_payload, MANY},
+ {NAME, "bandwidth", xmpp_jingle_cont_desc_rtp_bandwidth, ONE},
+ {NAME, "encryption", xmpp_jingle_cont_desc_rtp_enc, ONE},
+ {NAME, "rtp-hdrext", xmpp_jingle_cont_desc_rtp_hdrext, MANY},
+ {NAME, "zrtp-hash", xmpp_jingle_cont_desc_rtp_enc_zrtp_hash, MANY}/*IMHO it shouldn't appear in description*/
+
+ };
+
+ desc_item = proto_tree_add_item(tree, hf_xmpp_jingle_content_description, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ desc_tree = proto_item_add_subtree(desc_item, ett_xmpp_jingle_content_description);
+
+ display_attrs(desc_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(desc_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_cont_desc_rtp_payload(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *payload_item;
+ proto_tree *payload_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"id", hf_xmpp_jingle_cont_desc_payload_id, TRUE, TRUE, NULL, NULL},
+ {"channels", hf_xmpp_jingle_cont_desc_payload_channels, FALSE, FALSE, NULL, NULL},
+ {"clockrate", hf_xmpp_jingle_cont_desc_payload_clockrate, FALSE, FALSE, NULL, NULL},
+ {"maxptime", hf_xmpp_jingle_cont_desc_payload_maxptime, FALSE, FALSE, NULL, NULL},
+ {"name", hf_xmpp_jingle_cont_desc_payload_name, FALSE, TRUE, NULL, NULL},
+ {"ptime", hf_xmpp_jingle_cont_desc_payload_ptime, FALSE, FALSE, NULL, NULL}
+ };
+
+ elem_info elems_info [] =
+ {
+ {NAME, "parameter", xmpp_jingle_cont_desc_rtp_payload_param, MANY}
+ };
+
+ payload_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_desc_payload, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ payload_tree = proto_item_add_subtree(payload_item, ett_xmpp_jingle_cont_desc_payload);
+
+ display_attrs(payload_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(payload_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_cont_desc_rtp_payload_param(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element)
+{
+ proto_item *param_item;
+ proto_tree *param_tree;
+
+ proto_item *parent_item;
+ attr_t *name, *value;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"name", hf_xmpp_jingle_cont_desc_payload_param_name, TRUE, TRUE, NULL, NULL},
+ {"value", hf_xmpp_jingle_cont_desc_payload_param_value, TRUE, TRUE, NULL, NULL}
+ };
+
+ name = get_attr(element, "name");
+ value = get_attr(element, "value");
+
+ if(name && value)
+ {
+ gchar *parent_item_label;
+
+ parent_item = proto_tree_get_parent(tree);
+
+ parent_item_label = proto_item_get_text(parent_item);
+
+ if(parent_item_label)
+ {
+ parent_item_label[strlen(parent_item_label)-1]= '\0';
+ proto_item_set_text(parent_item, "%s param(\"%s\")=%s]", parent_item_label ,name->value, value->value);
+ }
+ }
+
+ param_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_desc_payload_param, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ param_tree = proto_item_add_subtree(param_item, ett_xmpp_jingle_cont_desc_payload_param);
+
+ display_attrs(param_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(param_tree, tvb, pinfo, element);
+
+}
+
+static void
+xmpp_jingle_cont_desc_rtp_enc(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element)
+{
+ proto_item *enc_item;
+ proto_tree *enc_tree;
+
+ elem_info elems_info [] = {
+ {NAME, "zrtp-hash", xmpp_jingle_cont_desc_rtp_enc_zrtp_hash, MANY},
+ {NAME, "crypto", xmpp_jingle_cont_desc_rtp_enc_crypto, MANY}
+ };
+
+ enc_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_desc_enc, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ enc_tree = proto_item_add_subtree(enc_item, ett_xmpp_jingle_cont_desc_enc);
+
+ display_attrs(enc_tree, element, pinfo, tvb, NULL, 0);
+ display_elems(enc_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+/*urn:xmpp:jingle:apps:rtp:zrtp:1*/
+static void
+xmpp_jingle_cont_desc_rtp_enc_zrtp_hash(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element)
+{
+ proto_item *zrtp_hash_item;
+ proto_tree *zrtp_hash_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"version", -1, TRUE, TRUE,NULL,NULL},
+ {"hash", -1, TRUE, FALSE, NULL, NULL}
+ };
+
+ zrtp_hash_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_desc_enc_zrtp_hash, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ zrtp_hash_tree = proto_item_add_subtree(zrtp_hash_item, ett_xmpp_jingle_cont_desc_enc_zrtp_hash);
+
+ if(element->data)
+ {
+ attr_t *fake_hash = ep_init_attr_t(element->data->value, element->offset, element->length);
+ g_hash_table_insert(element->attrs, "hash", fake_hash);
+ }
+
+ display_attrs(zrtp_hash_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(zrtp_hash_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_jingle_cont_desc_rtp_enc_crypto(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element)
+{
+ proto_item *crypto_item;
+ proto_tree *crypto_tree;
+
+ attr_info attrs_info[] = {
+ {"crypto-suite", -1, TRUE, TRUE, NULL, NULL},
+ {"key-params", -1, TRUE, FALSE,NULL,NULL},
+ {"session-params", -1, FALSE, TRUE, NULL, NULL},
+ {"tag", -1, TRUE, FALSE, NULL, NULL}
+ };
+
+ crypto_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_desc_enc_crypto, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ crypto_tree = proto_item_add_subtree(crypto_item, ett_xmpp_jingle_cont_desc_enc_crypto);
+
+
+ display_attrs(crypto_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(crypto_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_jingle_cont_desc_rtp_bandwidth(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element)
+{
+ proto_item *bandwidth_item;
+ proto_tree *bandwidth_tree;
+
+ attr_info attrs_info[] = {
+ {"type", -1, TRUE, TRUE, NULL, NULL},
+ {"value", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ bandwidth_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_desc_bandwidth, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ bandwidth_tree = proto_item_add_subtree(bandwidth_item, ett_xmpp_jingle_cont_desc_bandwidth);
+
+ if(element->data)
+ {
+ attr_t *fake_value = ep_init_attr_t(element->data->value, element->offset, element->length);
+ g_hash_table_insert(element->attrs, "value", fake_value);
+ }
+
+ display_attrs(bandwidth_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ xmpp_unknown(bandwidth_tree, tvb, pinfo, element);
+}
+
+/*urn:xmpp:jingle:apps:rtp:rtp-hdrext:0*/
+static void
+xmpp_jingle_cont_desc_rtp_hdrext(proto_tree* tree, tvbuff_t* tvb, packet_info *pinfo, element_t* element)
+{
+ proto_item *rtp_hdr_item;
+ proto_tree *rtp_hdr_tree;
+
+ const gchar *senders[] = {"both", "initiator", "responder"};
+ array_t *senders_enums = ep_init_array_t(senders, 3);
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"id", -1, TRUE, FALSE, NULL, NULL},
+ {"uri", -1, TRUE, TRUE, NULL, NULL},
+ {"senders", -1, FALSE, TRUE, val_enum_list, senders_enums},
+ {"parameter", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *parameter;
+
+ rtp_hdr_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_desc_rtp_hdr, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ rtp_hdr_tree = proto_item_add_subtree(rtp_hdr_item, ett_xmpp_jingle_cont_desc_rtp_hdr);
+
+ if((parameter = steal_element_by_name(element, "parameter"))!=NULL)
+ {
+ attr_t *name = get_attr(element, "name");
+ attr_t *fake_attr = ep_init_attr_t(name?name->value:"", parameter->offset, parameter->length);
+ g_hash_table_insert(element->attrs, "parameter", fake_attr);
+ }
+
+ display_attrs(rtp_hdr_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(rtp_hdr_tree, tvb, pinfo, element);
+}
+
+/*urn:xmpp:jingle:apps:rtp:info:1*/
+static void
+xmpp_jingle_rtp_info(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *rtp_info_item;
+ proto_tree *rtp_info_tree;
+
+ const gchar *creator[] = {"initiator","responder"};
+ array_t *creator_enums = ep_init_array_t(creator, array_length(creator));
+
+ attr_info mute_attrs_info[] = {
+ {"creator", -1, TRUE, TRUE, val_enum_list, creator_enums},
+ {"name", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ rtp_info_item = proto_tree_add_string(tree, hf_xmpp_jingle_rtp_info, tvb, element->offset, element->length, element->name);
+ rtp_info_tree = proto_item_add_subtree(rtp_info_item, ett_xmpp_jingle_rtp_info);
+
+ if(strcmp("mute", element->name) == 0 || strcmp("unmute", element->name) == 0)
+ display_attrs(rtp_info_tree, element, pinfo, tvb, mute_attrs_info, array_length(mute_attrs_info));
+
+ xmpp_unknown(rtp_info_tree, tvb, pinfo, element);
+}
+
+/*XEP-0176: Jingle ICE-UDP Transport Method urn:xmpp:jingle:transports:ice-udp:1*/
+static void
+xmpp_jingle_cont_trans_ice(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *trans_item;
+ proto_tree *trans_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL},
+ {"pwd", hf_xmpp_jingle_cont_trans_pwd, FALSE, FALSE, NULL, NULL},
+ {"ufrag", hf_xmpp_jingle_cont_trans_ufrag, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "candidate", xmpp_jingle_cont_trans_ice_candidate, MANY},
+ {NAME, "remote-candidate", xmpp_jingle_cont_trans_ice_remote_candidate, ONE}
+ };
+
+ trans_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ trans_tree = proto_item_add_subtree(trans_item, ett_xmpp_jingle_cont_trans);
+
+ display_attrs(trans_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ display_elems(trans_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_cont_trans_ice_candidate(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *cand_item;
+ proto_tree *cand_tree;
+
+ const gchar *type_enums[] = {"host", "prflx", "relay", "srflx"};
+ array_t *type_enums_array = ep_init_array_t(type_enums,array_length(type_enums));
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"component", -1, TRUE, FALSE, NULL, NULL},
+ {"foundation", -1, TRUE, FALSE, NULL, NULL},
+ {"generation", -1, TRUE, FALSE, NULL, NULL},
+ {"id", -1, FALSE, FALSE, NULL, NULL}, /*in schemas id is marked as required, but in jitsi logs it doesn't appear*/
+ {"ip", -1, TRUE, TRUE, NULL, NULL},
+ {"network", -1, TRUE, FALSE, NULL, NULL},
+ {"port", -1, TRUE, FALSE, NULL, NULL},
+ {"priority", -1, TRUE, TRUE, NULL, NULL},
+ {"protocol", -1, TRUE, TRUE, NULL, NULL},
+ {"rel-addr", -1, FALSE, FALSE, NULL, NULL},
+ {"rel-port", -1, FALSE, FALSE, NULL, NULL},
+ {"type", -1, TRUE, TRUE, val_enum_list, type_enums_array}
+ };
+
+ cand_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans_cand, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ cand_tree = proto_item_add_subtree(cand_item, ett_xmpp_jingle_cont_trans_cand);
+
+ display_attrs(cand_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(cand_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_jingle_cont_trans_ice_remote_candidate(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *remote_cand_item;
+ proto_tree *remote_cand_tree;
+
+ attr_info attrs_info[] = {
+ {"component", -1, TRUE, FALSE, NULL, NULL},
+ {"ip", -1, TRUE, FALSE, NULL, NULL},
+ {"port", -1, TRUE, FALSE, NULL, NULL}
+ };
+
+ remote_cand_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans_rem_cand, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ remote_cand_tree = proto_item_add_subtree(remote_cand_item, ett_xmpp_jingle_cont_trans_rem_cand);
+
+ display_attrs(remote_cand_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(remote_cand_tree, tvb, pinfo, element);
+}
+
+/*XEP-0177: Jingle Raw UDP Transport Method urn:xmpp:jingle:transports:raw-udp:1*/
+static void
+xmpp_jingle_cont_trans_raw(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *trans_item;
+ proto_tree *trans_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "candidate", xmpp_jingle_cont_trans_raw_candidate, MANY}
+ };
+
+ trans_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ trans_tree = proto_item_add_subtree(trans_item, ett_xmpp_jingle_cont_trans);
+
+ display_attrs(trans_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(trans_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_cont_trans_raw_candidate(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *cand_item;
+ proto_tree *cand_tree;
+
+ const gchar *type_enums[] = {"host", "prflx", "relay", "srflx"};
+ array_t *type_enums_array = ep_init_array_t(type_enums,array_length(type_enums));
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"component", -1, TRUE, FALSE, NULL, NULL},
+ {"generation", -1, TRUE, FALSE, NULL, NULL},
+ {"id", -1, TRUE, FALSE, NULL, NULL},
+ {"ip", -1, TRUE, TRUE, NULL, NULL},
+ {"port", -1, TRUE, TRUE, NULL, NULL},
+ {"type", -1, TRUE, TRUE, val_enum_list, type_enums_array}
+ };
+
+ cand_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans_cand, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ cand_tree = proto_item_add_subtree(cand_item, ett_xmpp_jingle_cont_trans_cand);
+
+ display_attrs(cand_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(cand_tree, element, pinfo, tvb, NULL, 0);
+}
+
+/*XEP-0260: Jingle SOCKS5 Bytestreams Transport Method urn:xmpp:jingle:transports:s5b:1*/
+static void
+xmpp_jingle_cont_trans_s5b(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *trans_item;
+ proto_tree *trans_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL},
+ {"mode", -1, FALSE, TRUE, NULL, NULL},
+ {"sid", -1, FALSE, TRUE, NULL, NULL},
+ };
+
+ elem_info elems_info [] = {
+ {NAME, "candidate", xmpp_jingle_cont_trans_s5b_candidate, MANY},
+ {NAME, "activated", xmpp_jingle_cont_trans_s5b_activated, ONE},
+ {NAME, "candidate-used", xmpp_jingle_cont_trans_s5b_cand_used, ONE},
+ {NAME, "candidate-error", xmpp_jingle_cont_trans_s5b_cand_error, ONE},
+ {NAME, "proxy-error", xmpp_jingle_cont_trans_s5b_proxy_error, ONE},
+ };
+
+ trans_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ trans_tree = proto_item_add_subtree(trans_item, ett_xmpp_jingle_cont_trans);
+
+ display_attrs(trans_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(trans_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_cont_trans_s5b_candidate(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *cand_item;
+ proto_tree *cand_tree;
+
+ const gchar * type_enums[] = {"assisted", "direct", "proxy", "tunnel"};
+ array_t *type_enums_array = ep_init_array_t(type_enums, array_length(type_enums));
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"cid", -1, TRUE, TRUE, NULL, NULL},
+ {"jid", -1, TRUE, TRUE, NULL, NULL},
+ {"port", -1, FALSE, TRUE, NULL, NULL},
+ {"priority", -1, TRUE, TRUE, NULL, NULL},
+ {"type", -1, TRUE, TRUE, val_enum_list, type_enums_array}
+ };
+
+ cand_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans_cand, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ cand_tree = proto_item_add_subtree(cand_item, ett_xmpp_jingle_cont_trans_cand);
+
+ display_attrs(cand_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(cand_tree, element, pinfo, tvb, NULL, 0);
+}
+
+static void
+xmpp_jingle_cont_trans_s5b_activated(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *activated_item;
+ attr_t *cid = get_attr(element, "cid");
+
+ activated_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans_activated, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ proto_item_append_text(activated_item, " [cid=\"%s\"]",cid?cid->value:"");
+
+ xmpp_unknown(tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_jingle_cont_trans_s5b_cand_used(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *cand_used_item;
+ attr_t *cid = get_attr(element, "cid");
+
+ cand_used_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans_candidate_used, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ proto_item_append_text(cand_used_item, " [cid=\"%s\"]",cid?cid->value:"");
+
+ xmpp_unknown(tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_jingle_cont_trans_s5b_cand_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans_candidate_error, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ xmpp_unknown(tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_jingle_cont_trans_s5b_proxy_error(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans_proxy_error, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ xmpp_unknown(tree, tvb, pinfo, element);
+}
+
+/*XEP-0261: Jingle In-Band Bytestreams Transport Method urn:xmpp:jingle:transports:ibb:1*/
+static void
+xmpp_jingle_cont_trans_ibb(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element) {
+ proto_item *trans_item;
+ proto_tree *trans_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL},
+ {"block-size", -1, TRUE, TRUE, NULL, NULL},
+ {"sid", -1, TRUE, TRUE, NULL, NULL},
+ {"stanza", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ trans_item = proto_tree_add_item(tree, hf_xmpp_jingle_cont_trans, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ trans_tree = proto_item_add_subtree(trans_item, ett_xmpp_jingle_cont_trans);
+
+ display_attrs(trans_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(trans_tree, element, pinfo, tvb, NULL, 0);
+}
+
+/*XEP-0234: Jingle File Transfer urn:xmpp:jingle:apps:file-transfer:3*/
+static void
+xmpp_jingle_file_transfer_desc(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *desc_item;
+ proto_tree *desc_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "offer", xmpp_jingle_file_transfer_offer, ONE},
+ {NAME, "request", xmpp_jingle_file_transfer_request, ONE}
+ };
+
+ desc_item = proto_tree_add_item(tree, hf_xmpp_jingle_content_description, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ desc_tree = proto_item_add_subtree(desc_item, ett_xmpp_jingle_content_description);
+
+ display_attrs(desc_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(desc_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_file_transfer_offer(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *offer_item;
+ proto_tree *offer_tree;
+
+ elem_info elems_info[] = {
+ {NAME, "file", xmpp_jingle_file_transfer_file, MANY},
+ };
+
+ offer_item = proto_tree_add_item(tree, hf_xmpp_jingle_file_transfer_offer, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ offer_tree = proto_item_add_subtree(offer_item, ett_xmpp_jingle_file_transfer_offer);
+
+ display_attrs(offer_tree, element, pinfo, tvb, NULL, 0);
+ display_elems(offer_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_file_transfer_request(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *request_item;
+ proto_tree *request_tree;
+
+ elem_info elems_info[] = {
+ {NAME, "file", xmpp_jingle_file_transfer_file, MANY},
+ };
+
+ request_item = proto_tree_add_item(tree, hf_xmpp_jingle_file_transfer_request, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ request_tree = proto_item_add_subtree(request_item, ett_xmpp_jingle_file_transfer_request);
+
+ display_attrs(request_tree, element, pinfo, tvb, NULL, 0);
+ display_elems(request_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_file_transfer_received(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *received_item;
+ proto_tree *received_tree;
+
+ elem_info elems_info[] = {
+ {NAME, "file", xmpp_jingle_file_transfer_file, MANY},
+ };
+
+ received_item = proto_tree_add_item(tree, hf_xmpp_jingle_file_transfer_received, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ received_tree = proto_item_add_subtree(received_item, ett_xmpp_jingle_file_transfer_received);
+
+ display_attrs(received_tree, element, pinfo, tvb, NULL, 0);
+ display_elems(received_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_file_transfer_abort(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *abort_item;
+ proto_tree *abort_tree;
+
+ elem_info elems_info[] = {
+ {NAME, "file", xmpp_jingle_file_transfer_file, MANY},
+ };
+
+ abort_item = proto_tree_add_item(tree, hf_xmpp_jingle_file_transfer_abort, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ abort_tree = proto_item_add_subtree(abort_item, ett_xmpp_jingle_file_transfer_abort);
+
+ display_attrs(abort_tree, element, pinfo, tvb, NULL, 0);
+ display_elems(abort_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_file_transfer_checksum(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *checksum_item;
+ proto_tree *checksum_tree;
+
+ elem_info elems_info[] = {
+ {NAME, "file", xmpp_jingle_file_transfer_file, MANY},
+ };
+
+ checksum_item = proto_tree_add_item(tree, hf_xmpp_jingle_file_transfer_checksum, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ checksum_tree = proto_item_add_subtree(checksum_item, ett_xmpp_jingle_file_transfer_checksum);
+
+ display_attrs(checksum_tree, element, pinfo, tvb, NULL, 0);
+ display_elems(checksum_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jingle_file_transfer_file(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *file_item;
+ proto_tree *file_tree;
+
+ attr_info attrs_info[] = {
+ {"name", -1, FALSE, TRUE, NULL, NULL},
+ {"size", -1, FALSE, TRUE, NULL, NULL},
+ {"date", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "hashes", xmpp_hashes, ONE}
+ };
+
+ file_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "FILE");
+ file_tree = proto_item_add_subtree(file_item, ett_xmpp_jingle_file_transfer_file);
+
+ change_elem_to_attrib("name", "name", element, transform_func_cdata);
+ change_elem_to_attrib("size", "size", element, transform_func_cdata);
+ change_elem_to_attrib("date", "date", element, transform_func_cdata);
+
+ display_attrs(file_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(file_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+/*XEP-0278: Jingle Relay Nodes http://jabber.org/protocol/jinglenodes*/
+void
+xmpp_jinglenodes_services(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *services_item;
+ proto_tree *services_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "relay", xmpp_jinglenodes_relay_stun_tracker, ONE},
+ {NAME, "tracker", xmpp_jinglenodes_relay_stun_tracker, ONE},
+ {NAME, "stun", xmpp_jinglenodes_relay_stun_tracker, ONE},
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "SERVICES ");
+
+ services_item = proto_tree_add_item(tree, hf_xmpp_services, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ services_tree = proto_item_add_subtree(services_item, ett_xmpp_services);
+
+ display_attrs(services_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(services_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jinglenodes_relay_stun_tracker(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *relay_item;
+ proto_tree *relay_tree;
+
+ attr_info attrs_info[] = {
+ {"address", -1, TRUE, TRUE, NULL, NULL},
+ {"port", -1, FALSE, TRUE, NULL, NULL},
+ {"policy", -1, TRUE, TRUE, NULL, NULL},
+ {"protocol", -1, TRUE, TRUE, NULL, NULL},
+ };
+
+ relay_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "%s", element->name);
+ relay_tree = proto_item_add_subtree(relay_item, ett_xmpp_services_relay);
+
+ display_attrs(relay_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(relay_tree, element, pinfo, tvb, NULL, 0);
+}
+
+void
+xmpp_jinglenodes_channel(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *channel_item;
+ proto_tree *channel_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"id", -1, FALSE, FALSE, NULL, NULL},
+ {"host", -1, FALSE, TRUE, NULL, NULL},
+ {"localport", -1, FALSE, TRUE, NULL, NULL},
+ {"remoteport", -1, FALSE, TRUE, NULL, NULL},
+ {"protocol", -1, TRUE, TRUE, NULL, NULL},
+ {"maxkbps", -1, FALSE, FALSE, NULL, NULL},
+ {"expire", -1, FALSE, FALSE, NULL, NULL},
+ };
+
+ channel_item = proto_tree_add_item(tree, hf_xmpp_channel, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ channel_tree = proto_item_add_subtree(channel_item, ett_xmpp_channel);
+
+ display_attrs(channel_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(channel_tree, element, pinfo, tvb, NULL, 0);
+}
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-xmpp-jingle.h b/epan/dissectors/packet-xmpp-jingle.h
new file mode 100644
index 0000000000..e2ef77b806
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-jingle.h
@@ -0,0 +1,34 @@
+/* xmpp-jingle.h
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef XMPP_JINGLE_H
+#define XMPP_JINGLE_H
+
+extern void xmpp_jingle(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_jinglenodes_services(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_jinglenodes_channel(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+#endif /* XMPP_JINGLE_H */
+
diff --git a/epan/dissectors/packet-xmpp-other.c b/epan/dissectors/packet-xmpp-other.c
new file mode 100644
index 0000000000..9e1a24d012
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-other.c
@@ -0,0 +1,1357 @@
+/* xmpp-other.c
+ * Wireshark's XMPP dissector.
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include<stdio.h>
+#include<string.h>
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/proto.h>
+#include <epan/tvbuff.h>
+#include <epan/emem.h>
+#include <epan/conversation.h>
+#include <epan/strutil.h>
+#include <epan/expert.h>
+
+#include <epan/dissectors/packet-xml.h>
+
+#include <packet-xmpp-utils.h>
+#include <packet-xmpp.h>
+#include <packet-xmpp-jingle.h>
+#include <packet-xmpp-other.h>
+
+static void xmpp_disco_items_item(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element);
+
+static void xmpp_roster_item(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element);
+
+static void xmpp_disco_info_identity(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element);
+static void xmpp_disco_info_feature(proto_tree *tree, tvbuff_t *tvb, element_t *element);
+
+static void xmpp_bytestreams_streamhost(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_bytestreams_streamhost_used(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_bytestreams_activate(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_bytestreams_udpsuccess(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+static void xmpp_si_file(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_si_file_range(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+
+static void xmpp_x_data_field(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_x_data_field_option(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_x_data_field_value(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+static void xmpp_x_data_instr(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+
+static void xmpp_muc_history(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+static void xmpp_muc_user_item(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_muc_user_status(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+static void xmpp_muc_user_invite(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+static void xmpp_hashes_hash(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+static void xmpp_jitsi_inputevt_rmt_ctrl(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+void
+xmpp_iq_bind(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *bind_item;
+ proto_tree *bind_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"resource", hf_xmpp_iq_bind_resource, FALSE, TRUE, NULL, NULL},
+ {"jid", hf_xmpp_iq_bind_jid, FALSE, TRUE, NULL, NULL}
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "BIND ");
+
+ bind_item = proto_tree_add_item(tree, hf_xmpp_iq_bind, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ bind_tree = proto_item_add_subtree(bind_item, ett_xmpp_iq_bind);
+
+ change_elem_to_attrib("resource", "resource", element, transform_func_cdata);
+ change_elem_to_attrib("jid", "jid", element, transform_func_cdata);
+
+ display_attrs(bind_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(bind_tree, tvb, pinfo, element);
+}
+
+void
+xmpp_session(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *session_item;
+ proto_tree *session_tree;
+
+ attr_info attrs_info [] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ session_item = proto_tree_add_item(tree, hf_xmpp_iq_session, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ session_tree = proto_item_add_subtree(session_item, ett_xmpp_iq_session);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "SESSION ");
+
+ display_attrs(session_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(session_tree, element, pinfo, tvb, NULL, 0);
+}
+
+void
+xmpp_vcard(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *vcard_item;
+ proto_tree *vcard_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"value", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ element_t *cdata;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "VCARD ");
+
+ vcard_item = proto_tree_add_item(tree, hf_xmpp_vcard, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ vcard_tree = proto_item_add_subtree(vcard_item, ett_xmpp_vcard);
+
+ cdata = get_first_element(element);
+
+ if(cdata)
+ {
+ attr_t *fake_cdata;
+ fake_cdata = ep_init_attr_t(element_to_string(tvb, cdata), cdata->offset, cdata->length);
+ g_hash_table_insert(element->attrs,"value", fake_cdata);
+
+ }
+ display_attrs(vcard_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+}
+
+void
+xmpp_vcard_x_update(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *x_item;
+ proto_tree *x_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"photo", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ element_t *photo;
+
+ x_item = proto_tree_add_item(tree, hf_xmpp_vcard_x_update, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ x_tree = proto_item_add_subtree(x_item, ett_xmpp_vcard_x_update);
+
+ if((photo = steal_element_by_name(element, "photo"))!=NULL)
+ {
+ attr_t *fake_photo = ep_init_attr_t(photo->data?photo->data->value:"", photo->offset, photo->length);
+ g_hash_table_insert(element->attrs, "photo", fake_photo);
+ }
+
+ display_attrs(x_tree, element,pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(x_tree, tvb, pinfo, element);
+}
+
+void
+xmpp_disco_items_query(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"node", hf_xmpp_query_node, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *item;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(disco#items) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ while((item = steal_element_by_name(element, "item")) != NULL)
+ {
+ xmpp_disco_items_item(query_tree, tvb, pinfo, item);
+ }
+
+ xmpp_unknown(query_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_disco_items_item(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element)
+{
+ proto_item *item_item;
+ proto_tree *item_tree;
+
+ attr_info attrs_info[] = {
+ {"jid", hf_xmpp_query_item_jid, TRUE, TRUE, NULL, NULL},
+ {"name", hf_xmpp_query_item_name, FALSE, TRUE, NULL, NULL},
+ {"node", hf_xmpp_query_item_node, FALSE, TRUE, NULL, NULL}
+ };
+
+ item_item = proto_tree_add_item(tree, hf_xmpp_query_item, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ item_tree = proto_item_add_subtree(item_item, ett_xmpp_query_item);
+
+ display_attrs(item_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(item_tree, tvb, pinfo, element);
+}
+
+void
+xmpp_roster_query(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"ver", -1, FALSE, TRUE, NULL, NULL},
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "item", xmpp_roster_item, MANY},
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(jabber:iq:roster) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(query_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_roster_item(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element)
+{
+ proto_item *item_item;
+ proto_tree *item_tree;
+
+ const gchar *ask_enums[] = {"subscribe"};
+ const gchar *subscription_enums[] = {"both","from","none","remove","to"};
+
+ array_t *ask_enums_array = ep_init_array_t(ask_enums,array_length(ask_enums));
+ array_t *subscription_array = ep_init_array_t(subscription_enums,array_length(subscription_enums));
+
+ attr_info attrs_info[] = {
+ {"jid", hf_xmpp_query_item_jid, TRUE, TRUE, NULL, NULL},
+ {"name", hf_xmpp_query_item_name, FALSE, TRUE, NULL, NULL},
+ {"ask", hf_xmpp_query_item_ask, FALSE, TRUE, val_enum_list, ask_enums_array},
+ {"approved", hf_xmpp_query_item_approved, FALSE, TRUE, NULL, NULL},
+ {"subscription", hf_xmpp_query_item_subscription, FALSE, TRUE, val_enum_list, subscription_array},
+ };
+
+ element_t *group;
+
+ item_item = proto_tree_add_item(tree, hf_xmpp_query_item, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ item_tree = proto_item_add_subtree(item_item, ett_xmpp_query_item);
+
+ display_attrs(item_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ while((group = steal_element_by_name(element,"group"))!=NULL)
+ {
+ proto_tree_add_string(item_tree, hf_xmpp_query_item_group, tvb, group->offset, group->length, elem_cdata(group));
+ }
+
+ xmpp_unknown(item_tree, tvb, pinfo, element);
+}
+
+void
+xmpp_disco_info_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"node", hf_xmpp_query_node, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *identity, *feature, *x_data;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(disco#info) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+
+ while((identity = steal_element_by_name(element, "identity")) != NULL)
+ {
+ xmpp_disco_info_identity(query_tree, tvb, pinfo, identity);
+ }
+
+ while((feature = steal_element_by_name(element, "feature")) != NULL)
+ {
+ xmpp_disco_info_feature(query_tree, tvb, feature);
+ }
+
+ if((x_data = steal_element_by_name_and_attr(element, "x", "xmlns", "jabber:x:data")) != NULL)
+ {
+ xmpp_x_data(query_tree, tvb, pinfo, x_data);
+ }
+
+ xmpp_unknown(query_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_disco_info_identity(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element)
+{
+ proto_item *identity_item;
+ proto_tree *identity_tree;
+
+ attr_info attrs_info[] = {
+ {"category", hf_xmpp_query_identity_category, TRUE, TRUE, NULL, NULL},
+ {"name", hf_xmpp_query_identity_name, FALSE, TRUE, NULL, NULL},
+ {"type", hf_xmpp_query_identity_type, TRUE, TRUE, NULL, NULL}
+ };
+
+ identity_item = proto_tree_add_item(tree, hf_xmpp_query_identity, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ identity_tree = proto_item_add_subtree(identity_item, ett_xmpp_query_identity);
+
+ display_attrs(identity_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(identity_tree, tvb, pinfo, element);
+
+}
+
+static void
+xmpp_disco_info_feature(proto_tree *tree, tvbuff_t *tvb, element_t *element)
+{
+
+ attr_t *var = get_attr(element, "var");
+
+ if(var)
+ {
+ proto_tree_add_string_format(tree, hf_xmpp_query_feature, tvb, var->offset, var->length, var->value, "FEATURE [%s]", var->value);
+ }
+}
+
+void
+xmpp_bytestreams_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ const gchar *mode_enums[] = {"tcp", "udp"};
+ array_t *mode_array = ep_init_array_t(mode_enums, array_length(mode_enums));
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"sid", -1, FALSE, TRUE, NULL, NULL},
+ {"mode", -1, FALSE, TRUE, val_enum_list, mode_array},
+ {"dstaddr", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *streamhost, *streamhost_used, *activate, *udpsuccess;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(bytestreams) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+
+ while((streamhost = steal_element_by_name(element, "streamhost")) != NULL)
+ {
+ xmpp_bytestreams_streamhost(query_tree, tvb, pinfo, streamhost);
+ }
+
+ if((streamhost_used = steal_element_by_name(element, "streamhost-used")) != NULL)
+ {
+ xmpp_bytestreams_streamhost_used(query_tree, tvb, pinfo, streamhost_used);
+ }
+
+ if((activate = steal_element_by_name(element, "activate")) != NULL)
+ {
+ xmpp_bytestreams_activate(query_tree, tvb, pinfo, activate);
+ }
+
+ if((udpsuccess = steal_element_by_name(element, "udpsuccess")) != NULL)
+ {
+ xmpp_bytestreams_udpsuccess(query_tree, tvb, pinfo, udpsuccess);
+ }
+
+ xmpp_unknown(query_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_bytestreams_streamhost(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *sh_item;
+ proto_tree *sh_tree;
+
+ attr_info attrs_info[] = {
+ {"jid", -1, TRUE, TRUE, NULL, NULL},
+ {"host", -1, TRUE, TRUE, NULL, NULL},
+ {"port", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ sh_item = proto_tree_add_item(tree, hf_xmpp_query_streamhost, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ sh_tree = proto_item_add_subtree(sh_item, ett_xmpp_query_streamhost);
+
+ display_attrs(sh_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(sh_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_bytestreams_streamhost_used(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *shu_item;
+ proto_tree *shu_tree;
+
+ attr_info attrs_info[] = {
+ {"jid", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ shu_item = proto_tree_add_item(tree, hf_xmpp_query_streamhost_used, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ shu_tree = proto_item_add_subtree(shu_item, ett_xmpp_query_streamhost_used);
+
+ display_attrs(shu_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(shu_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_bytestreams_activate(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_tree_add_string(tree, hf_xmpp_query_activate, tvb, element->offset, element->length, elem_cdata(element));
+ xmpp_unknown(tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_bytestreams_udpsuccess(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *udps_item;
+ proto_tree *udps_tree;
+
+ attr_info attrs_info[] = {
+ {"dstaddr", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ udps_item = proto_tree_add_item(tree, hf_xmpp_query_udpsuccess, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ udps_tree =proto_item_add_subtree(udps_item, ett_xmpp_query_udpsuccess);
+
+ display_attrs(udps_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(udps_tree, tvb, pinfo, element);
+}
+
+
+
+/*SI File Transfer*/
+void
+xmpp_si(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *si_item;
+ proto_tree *si_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"id", -1, FALSE, FALSE, NULL, NULL},
+ {"mime-type", -1, FALSE, TRUE, NULL, NULL},
+ {"profile", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *file, *feature_neg;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "SI ");
+
+ si_item = proto_tree_add_item(tree, hf_xmpp_si, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ si_tree = proto_item_add_subtree(si_item, ett_xmpp_si);
+
+ display_attrs(si_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ while((file = steal_element_by_name(element, "file"))!=NULL)
+ {
+ xmpp_si_file(si_tree, tvb, pinfo, file);
+ }
+
+ while((feature_neg = steal_element_by_name(element, "feature"))!=NULL)
+ {
+ xmpp_feature_neg(si_tree, tvb, pinfo, feature_neg);
+ }
+
+
+
+ xmpp_unknown(si_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_si_file(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *file_item;
+ proto_tree *file_tree;
+
+ attr_info attrs_info[] ={
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"name", -1, TRUE, TRUE, NULL, NULL},
+ {"size", -1, TRUE, TRUE, NULL, NULL},
+ {"date", -1, FALSE, FALSE, NULL, NULL},
+ {"hash", -1, FALSE, FALSE, NULL, NULL},
+ {"desc", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ element_t *desc, *range;
+
+ file_item = proto_tree_add_item(tree, hf_xmpp_si_file, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ file_tree = proto_item_add_subtree(file_item, ett_xmpp_si_file);
+
+ if((desc = steal_element_by_name(element, "desc"))!=NULL)
+ {
+ attr_t *fake_desc = ep_init_attr_t(desc->data?desc->data->value:"", desc->offset, desc->length);
+ g_hash_table_insert(element->attrs, "desc", fake_desc);
+ }
+
+ if((range = steal_element_by_name(element, "range"))!=NULL)
+ {
+ xmpp_si_file_range(file_tree, tvb, pinfo, range);
+ }
+
+ display_attrs(file_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(file_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_si_file_range(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *range_item;
+ proto_tree *range_tree;
+
+ attr_info attrs_info[] = {
+ {"offset", -1, FALSE, TRUE, NULL, NULL},
+ {"length", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ range_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "RANGE: ");
+ range_tree = proto_item_add_subtree(range_item, ett_xmpp_si_file_range);
+
+ display_attrs(range_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(range_tree, tvb, pinfo, element);
+
+}
+
+/*Feature Negotiation*/
+void
+xmpp_feature_neg(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *feature_item;
+ proto_tree *feature_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ element_t *x_data;
+
+ feature_item = proto_tree_add_item(tree, hf_xmpp_iq_feature_neg, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ feature_tree = proto_item_add_subtree(feature_item, ett_xmpp_iq_feature_neg);
+
+ display_attrs(feature_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ while((x_data = steal_element_by_name_and_attr(element, "x", "xmlns", "jabber:x:data"))!=NULL)
+ {
+ xmpp_x_data(feature_tree, tvb, pinfo, x_data);
+ }
+
+ xmpp_unknown(feature_tree, tvb, pinfo, element);
+}
+
+
+/*jabber:x:data*/
+void
+xmpp_x_data(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *x_item;
+ proto_tree *x_tree;
+
+ const gchar *type_enums[] = {"cancel", "form", "result", "submit"};
+ array_t *type_array = ep_init_array_t(type_enums, array_length(type_enums));
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"type", -1, TRUE, TRUE, val_enum_list, type_array},
+ {"TITLE", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "instructions", xmpp_x_data_instr, MANY},
+ {NAME, "field", xmpp_x_data_field, MANY},
+ };
+ /*TODO reported, item*/
+
+ x_item = proto_tree_add_item(tree, hf_xmpp_x_data, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ x_tree = proto_item_add_subtree(x_item, ett_xmpp_x_data);
+
+ change_elem_to_attrib("title", "TITLE", element, transform_func_cdata);
+
+ display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(x_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_x_data_field(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *field_item;
+ proto_tree *field_tree;
+
+ const gchar *type_enums[] = {"boolean", "fixed", "hidden", "jid-multi",
+ "jid-single", "list-multi", "list-single", "text-multi", "text-single",
+ "text-private"
+ };
+ array_t *type_array = ep_init_array_t(type_enums, array_length(type_enums));
+
+ attr_info attrs_info[] =
+ {
+ {"label", -1, FALSE, TRUE, NULL, NULL},
+ {"type", -1, FALSE, TRUE, val_enum_list, type_array},
+ {"var", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t /**desc, *required,*/ *value, *option;
+
+ field_item = proto_tree_add_item(tree, hf_xmpp_x_data_field, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ field_tree = proto_item_add_subtree(field_item, ett_xmpp_x_data_field);
+
+ display_attrs(field_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ while((option = steal_element_by_name(element, "option"))!=NULL)
+ {
+ xmpp_x_data_field_option(field_tree, tvb, pinfo, option);
+ }
+
+ while((value = steal_element_by_name(element, "value"))!=NULL)
+ {
+ xmpp_x_data_field_value(field_tree, tvb, pinfo, value);
+ }
+
+ xmpp_unknown(field_item, tvb, pinfo, element);
+
+}
+
+static void
+xmpp_x_data_field_option(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *option_item;
+ proto_tree *option_tree;
+
+ attr_info attrs_info[] = {
+ {"label", -1, FALSE, TRUE, NULL, NULL},
+ {"value", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *value;
+
+ option_item = proto_tree_add_item(tree, hf_xmpp_x_data_field_value, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ option_tree = proto_item_add_subtree(option_item, ett_xmpp_x_data_field_value);
+
+ if((value = steal_element_by_name(element, "value"))!=NULL)
+ {
+ attr_t *fake_value = ep_init_attr_t(value->data?value->data->value:"",value->offset, value->length);
+ g_hash_table_insert(element->attrs, "value", fake_value);
+ }
+
+ display_attrs(option_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(option_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_x_data_field_value(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element)
+{
+ proto_item *value_item;
+ proto_tree *value_tree;
+
+ attr_info attrs_info[] = {
+ {"label", -1, FALSE, TRUE, NULL, NULL},
+ {"value", -1, TRUE, TRUE, NULL, NULL}
+ };
+ attr_t *fake_value;
+
+ value_item = proto_tree_add_item(tree, hf_xmpp_x_data_field_value, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ value_tree = proto_item_add_subtree(value_item, ett_xmpp_x_data_field_value);
+
+
+
+ fake_value = ep_init_attr_t(element->data?element->data->value:"",element->offset, element->length);
+ g_hash_table_insert(element->attrs, "value", fake_value);
+
+
+ display_attrs(value_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(value_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_x_data_instr(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo _U_, element_t* element)
+{
+ proto_tree_add_text(tree, tvb, element->offset, element->length, "INSTRUCTIONS: %s",elem_cdata(element));
+}
+
+/*In-Band Bytestreams*/
+void
+xmpp_ibb_open(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *open_item;
+ proto_tree *open_tree;
+
+ const gchar *stanza_enums[] = {"iq","message"};
+ array_t *stanza_array = ep_init_array_t(stanza_enums, array_length(stanza_enums));
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"sid", -1, TRUE, TRUE, NULL, NULL},
+ {"block-size", -1, TRUE, TRUE, NULL, NULL},
+ {"stanza", -1, FALSE, TRUE, val_enum_list, stanza_array}
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "IBB-OPEN ");
+
+ open_item = proto_tree_add_item(tree, hf_xmpp_ibb_open, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ open_tree = proto_item_add_subtree(open_item, ett_xmpp_ibb_open);
+
+ display_attrs(open_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ xmpp_unknown(open_tree, tvb, pinfo, element);
+}
+
+void
+xmpp_ibb_close(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *close_item;
+ proto_tree *close_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"sid", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "IBB-CLOSE ");
+
+ close_item = proto_tree_add_item(tree, hf_xmpp_ibb_close, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ close_tree = proto_item_add_subtree(close_item, ett_xmpp_ibb_close);
+
+ display_attrs(close_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ xmpp_unknown(close_tree, tvb, pinfo, element);
+}
+
+void
+xmpp_ibb_data(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *data_item;
+ proto_tree *data_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"sid", -1, TRUE, TRUE, NULL, NULL},
+ {"seq", -1, TRUE, TRUE, NULL, NULL},
+ {"value", -1, FALSE, FALSE, NULL, NULL}
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "IBB-DATA ");
+
+ data_item = proto_tree_add_item(tree, hf_xmpp_ibb_data, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ data_tree = proto_item_add_subtree(data_item, ett_xmpp_ibb_data);
+
+ if(element->data)
+ {
+ attr_t *fake_data = ep_init_attr_t(element->data->value, element->offset, element->length);
+ g_hash_table_insert(element->attrs, "value", fake_data);
+ }
+
+ display_attrs(data_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ xmpp_unknown(data_tree, tvb, pinfo, element);
+}
+
+
+/*Delayed Delivery urn:xmpp:delay and jabber:x:delay*/
+void
+xmpp_delay(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *delay_item;
+ proto_tree *delay_tree;
+
+ attr_info attrs_info[]={
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"from", -1, FALSE, TRUE, NULL, NULL},
+ {"stamp", -1, TRUE, TRUE, NULL, NULL},
+ {"value", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ delay_item = proto_tree_add_item(tree, hf_xmpp_delay, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ delay_tree = proto_item_add_subtree(delay_item, ett_xmpp_delay);
+
+ if(element->data)
+ {
+ attr_t *fake_value = ep_init_attr_t(element->data->value, element->offset, element->length);
+ g_hash_table_insert(element->attrs, "value", fake_value);
+ }
+
+ display_attrs(delay_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(delay_tree, tvb, pinfo, element);
+}
+
+/*Entity Capabilities http://jabber.org/protocol/caps*/
+void
+xmpp_presence_caps(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *caps_item;
+ proto_tree *caps_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"ext", -1, FALSE, FALSE, NULL, NULL},
+ {"hash", -1, TRUE, TRUE, NULL, NULL},
+ {"node", -1, TRUE, TRUE, NULL, NULL},
+ {"ver", -1, TRUE, FALSE, NULL, NULL}
+ };
+
+ caps_item = proto_tree_add_item(tree, hf_xmpp_presence_caps, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ caps_tree = proto_item_add_subtree(caps_item, ett_xmpp_presence_caps);
+
+ display_attrs(caps_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(caps_tree, tvb, pinfo, element);
+}
+
+/*Message Events jabber:x:event*/
+void
+xmpp_x_event(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *x_item;
+ proto_tree *x_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"condition", hf_xmpp_x_event_condition, TRUE, TRUE, NULL, NULL},
+ {"id", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ const gchar *cond_names[] = {"offline", "delivered", "displayed", "composing"};
+
+ attr_t *fake_cond;
+
+ element_t *cond, *id;
+
+ gchar *cond_value = ep_strdup("");
+
+ x_item = proto_tree_add_item(tree, hf_xmpp_x_event, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ x_tree = proto_item_add_subtree(x_item, ett_xmpp_x_event);
+
+ if((id = steal_element_by_name(element, "id"))!=NULL)
+ {
+ attr_t *fake_id = ep_init_attr_t(id->data?id->data->value:"", id->offset, id->length);
+ g_hash_table_insert(element->attrs, "id", fake_id);
+ }
+
+ while((cond = steal_element_by_names(element, cond_names, array_length(cond_names))) != NULL)
+ {
+ if(strcmp(cond_value,"") != 0)
+ cond_value = ep_strdup_printf("%s/%s",cond_value, cond->name);
+ else
+ cond_value = ep_strdup(cond->name);
+ }
+
+ fake_cond = ep_init_attr_t(cond_value, element->offset, element->length);
+ g_hash_table_insert(element->attrs, "condition", fake_cond);
+
+
+ display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(x_tree, tvb, pinfo, element);
+}
+
+/*Multi-User Chat http://jabber.org/protocol/muc*/
+void
+xmpp_muc_x(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *x_item;
+ proto_tree *x_tree;
+
+ attr_info attrs_info [] ={
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"password", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *pass, *hist;
+
+ x_item = proto_tree_add_item(tree, hf_xmpp_muc_x, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ x_tree = proto_item_add_subtree(x_item, ett_xmpp_muc_x);
+
+ if((pass = steal_element_by_name(element, "password"))!=NULL)
+ {
+ attr_t *fake_pass = ep_init_attr_t(pass->data?pass->data->value:"",pass->offset, pass->length);
+ g_hash_table_insert(element->attrs, "password", fake_pass);
+ }
+
+ display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ if((hist = steal_element_by_name(element, "history"))!=NULL)
+ {
+ xmpp_muc_history(x_tree, tvb, pinfo, hist);
+ }
+
+ xmpp_unknown(x_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_muc_history(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *hist_item;
+ proto_tree *hist_tree;
+
+ attr_info attrs_info[] = {
+ {"maxchars", -1, FALSE, TRUE, NULL, NULL},
+ {"maxstanzas", -1, FALSE, TRUE, NULL, NULL},
+ {"seconds", -1, FALSE, TRUE, NULL, NULL},
+ {"since", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ hist_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "HISTORY: ");
+ hist_tree = proto_item_add_subtree(hist_item, ett_xmpp_muc_hist);
+
+ display_attrs(hist_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(hist_tree, tvb, pinfo, element);
+}
+
+/*Multi-User Chat http://jabber.org/protocol/muc#user*/
+void
+xmpp_muc_user_x(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *x_item;
+ proto_tree *x_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
+ {"password", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *item, *status, *invite, *password;
+ /*TODO decline destroy*/
+
+ x_item = proto_tree_add_item(tree, hf_xmpp_muc_user_x, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ x_tree = proto_item_add_subtree(x_item, ett_xmpp_muc_user_x);
+
+ if((password = steal_element_by_name(element, "password"))!=NULL)
+ {
+ attr_t *fake_pass = ep_init_attr_t(password->data?password->data->value:"",password->offset, password->length);
+ g_hash_table_insert(element->attrs, "password", fake_pass);
+ }
+
+ display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ while((item = steal_element_by_name(element, "item"))!=NULL)
+ {
+ xmpp_muc_user_item(x_tree, tvb, pinfo, item);
+ }
+
+ while((status = steal_element_by_name(element, "status"))!=NULL)
+ {
+ xmpp_muc_user_status(x_tree, tvb, pinfo, status);
+ }
+
+ while((invite = steal_element_by_name(element, "invite"))!=NULL)
+ {
+ xmpp_muc_user_invite(x_tree, tvb, pinfo, invite);
+ }
+
+ xmpp_unknown(x_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_muc_user_item(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *item_item;
+ proto_tree *item_tree;
+
+ const gchar *affiliation_enums[] = {"admin", "member", "none", "outcast", "owner"};
+ array_t *affil_array = ep_init_array_t(affiliation_enums, array_length(affiliation_enums));
+
+ const gchar *role_enums[] = {"none", "moderator", "participant", "visitor"};
+ array_t *role_array = ep_init_array_t(role_enums, array_length(role_enums));
+
+ attr_info attrs_info [] ={
+ {"affiliation", -1, FALSE, TRUE, val_enum_list, affil_array},
+ {"jid", -1, FALSE, TRUE, NULL, NULL},
+ {"nick", -1, FALSE, TRUE, NULL, NULL},
+ {"role", -1, FALSE, TRUE, val_enum_list, role_array},
+ {"reason", -1, FALSE, TRUE, NULL, NULL},
+ {"actor_jid", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *reason, *actor;
+ /*TODO continue - it's not clear to me, in schema it's marked as empty, but in examples it has CDATA*/
+
+ item_item = proto_tree_add_item(tree, hf_xmpp_muc_user_item, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ item_tree = proto_item_add_subtree(item_item, ett_xmpp_muc_user_item);
+
+ if((reason = steal_element_by_name(element, "reason"))!=NULL)
+ {
+ attr_t *fake_reason = ep_init_attr_t(reason->data?reason->data->value:"",reason->offset, reason->length);
+ g_hash_table_insert(element->attrs,"reason",fake_reason);
+ }
+
+ if((actor = steal_element_by_name(element, "actor"))!=NULL)
+ {
+ attr_t *jid = get_attr(actor, "jid");
+ attr_t *fake_actor_jid = ep_init_attr_t(jid?jid->value:"",actor->offset, actor->length);
+ g_hash_table_insert(element->attrs, "actor_jid", fake_actor_jid);
+ }
+
+ display_attrs(item_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(item_tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_muc_user_status(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ attr_t *code = get_attr(element, "code");
+ proto_tree_add_text(tree, tvb, element->offset, element->length, "STATUS [code=\"%s\"]",code?code->value:"");
+
+ xmpp_unknown(tree, tvb, pinfo, element);
+}
+
+static void
+xmpp_muc_user_invite(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *invite_item;
+ proto_tree *invite_tree;
+
+ attr_info attrs_info[] = {
+ {"from", -1, FALSE, TRUE, NULL, NULL},
+ {"to", -1, FALSE, TRUE, NULL, NULL},
+ {"reason", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *reason;
+
+ invite_item = proto_tree_add_item(tree, hf_xmpp_muc_user_invite, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ invite_tree = proto_item_add_subtree(invite_item, ett_xmpp_muc_user_invite);
+
+ if((reason = steal_element_by_name(element, "reason"))!=NULL)
+ {
+ attr_t *fake_reason = ep_init_attr_t(reason->data?reason->data->value:"",reason->offset, reason->length);
+ g_hash_table_insert(element->attrs, "reason", fake_reason);
+ }
+
+ display_attrs(invite_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ xmpp_unknown(invite_tree, tvb, pinfo, element);
+}
+
+/*Multi-User Chat http://jabber.org/protocol/muc#owner*/
+void
+xmpp_muc_owner_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ element_t *x_data;
+ /*TODO destroy*/
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(muc#owner) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ if((x_data = steal_element_by_name_and_attr(element, "x", "xmlns", "jabber:x:data"))!=NULL)
+ {
+ xmpp_x_data(query_tree, tvb, pinfo, x_data);
+ }
+
+ xmpp_unknown(query_tree, tvb, pinfo, element);
+
+}
+
+/*Multi-User Chat http://jabber.org/protocol/muc#admin*/
+void
+xmpp_muc_admin_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
+ };
+
+ element_t *item;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(muc#admin) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+
+ while((item = steal_element_by_name(element, "item"))!=NULL)
+ {
+ /*from muc#user, because it is the same except continue element*/
+ xmpp_muc_user_item(query_tree, tvb, pinfo, item);
+ }
+
+ xmpp_unknown(query_tree, tvb, pinfo, element);
+}
+
+/*Last Activity jabber:iq:last*/
+void
+xmpp_last_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"seconds", -1, FALSE, TRUE, NULL, NULL},
+ {"value", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(jabber:iq:last) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ if(element->data)
+ {
+ attr_t *fake_data = ep_init_attr_t(element->data->value, element->data->offset, element->data->length);
+ g_hash_table_insert(element->attrs, "value", fake_data);
+ }
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(query_tree, element, pinfo, tvb, NULL, 0);
+}
+
+/*XEP-0092: Software Version jabber:iq:version*/
+void
+xmpp_version_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *query_item;
+ proto_tree *query_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"name", -1, FALSE, TRUE, NULL, NULL},
+ {"version", -1, FALSE, TRUE, NULL, NULL},
+ {"os", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ element_t *name, *version, *os;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "QUERY(jabber:iq:version) ");
+
+ query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
+
+ if((name = steal_element_by_name(element,"name"))!=NULL)
+ {
+ attr_t *fake_name = ep_init_attr_t(name->data?name->data->value:"", name->offset, name->length);
+ g_hash_table_insert(element->attrs, "name", fake_name);
+ }
+
+ if((version = steal_element_by_name(element,"version"))!=NULL)
+ {
+ attr_t *fake_version = ep_init_attr_t(version->data?version->data->value:"", version->offset, version->length);
+ g_hash_table_insert(element->attrs, "version", fake_version);
+ }
+
+ if((os = steal_element_by_name(element,"os"))!=NULL)
+ {
+ attr_t *fake_os = ep_init_attr_t(os->data?os->data->value:"", os->offset, os->length);
+ g_hash_table_insert(element->attrs, "os", fake_os);
+ }
+
+ display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(query_tree, element, pinfo, tvb, NULL, 0);
+}
+/*XEP-0199: XMPP Ping*/
+void
+xmpp_ping(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *ping_item;
+ proto_tree *ping_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ };
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "PING ");
+
+ ping_item = proto_tree_add_item(tree, hf_xmpp_ping, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ ping_tree = proto_item_add_subtree(ping_item, ett_xmpp_ping);
+
+ display_attrs(ping_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(ping_tree, element, pinfo, tvb, NULL, 0);
+}
+
+/*XEP-0300: Use of Cryptographic Hash Functions in XMPP urn:xmpp:hashes:0*/
+void
+xmpp_hashes(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element) {
+ proto_item *hashes_item;
+ proto_tree *hashes_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ };
+ elem_info elems_info[] = {
+ {NAME, "hash", xmpp_hashes_hash, MANY}
+ };
+
+ hashes_item = proto_tree_add_item(tree, hf_xmpp_hashes, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ hashes_tree = proto_item_add_subtree(hashes_item, ett_xmpp_hashes);
+
+ display_attrs(hashes_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(hashes_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_hashes_hash(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *hash_item;
+ proto_tree *hash_tree;
+
+ attr_info attrs_info[] = {
+ {"algo", -1, TRUE, TRUE, NULL, NULL},
+ {"value", -1, TRUE, TRUE, NULL, NULL}
+ };
+
+ attr_t *fake_cdata = ep_init_attr_t(elem_cdata(element), element->offset, element->length);
+ g_hash_table_insert(element->attrs, "value", fake_cdata);
+
+ hash_item = proto_tree_add_text(tree, tvb, element->offset, element->length, "HASH");
+ hash_tree = proto_item_add_subtree(hash_item, ett_xmpp_hashes_hash);
+
+ display_attrs(hash_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(hash_tree, element, pinfo, tvb, NULL, 0);
+}
+
+/*http://jitsi.org/protocol/inputevt*/
+void
+xmpp_jitsi_inputevt(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *inputevt_item;
+ proto_tree *inputevt_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
+ {"action", -1, FALSE, TRUE, NULL, NULL}
+ };
+
+ elem_info elems_info[] = {
+ {NAME, "remote-control", xmpp_jitsi_inputevt_rmt_ctrl, MANY}
+ };
+
+ inputevt_item = proto_tree_add_item(tree, hf_xmpp_jitsi_inputevt, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ inputevt_tree = proto_item_add_subtree(inputevt_item, ett_xmpp_jitsi_inputevt);
+
+ display_attrs(inputevt_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(inputevt_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
+}
+
+static void
+xmpp_jitsi_inputevt_rmt_ctrl(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ proto_item *rmt_ctrl_item;
+ proto_tree *rmt_ctrl_tree;
+
+ attr_info attrs_info[] = {
+ {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
+ {"action", -1, TRUE, TRUE, NULL, NULL},
+ {"x", -1, FALSE, TRUE, NULL, NULL},
+ {"y", -1, FALSE, TRUE, NULL, NULL},
+ {"btns", -1, FALSE, TRUE, NULL, NULL},
+ {"keycode", -1, FALSE, TRUE, NULL, NULL},
+ };
+
+ element_t *action;
+ const gchar *action_names[] = {"mouse-move","mouse-press", "mouse-release", "key-press", "key-release"};
+
+ if((action = steal_element_by_names(element, action_names, array_length(action_names)))!=NULL)
+ {
+ attr_t *fake_action = ep_init_attr_t(action->name, action->offset, action->length);
+ g_hash_table_insert(element->attrs,"action", fake_action);
+
+ if(strcmp(action->name,"mouse-move") == 0)
+ {
+ attr_t *x = get_attr(action,"x");
+ attr_t *y = get_attr(action,"y");
+
+ if(x)
+ g_hash_table_insert(element->attrs,"x",x);
+ if(y)
+ g_hash_table_insert(element->attrs,"y",y);
+ } else if(strcmp(action->name,"mouse-press") == 0 || strcmp(action->name,"mouse-release") == 0)
+ {
+ attr_t *btns = get_attr(action,"btns");
+
+ if(btns)
+ g_hash_table_insert(element->attrs,"btns",btns);
+ } else if(strcmp(action->name,"key-press") == 0 || strcmp(action->name,"key-release") == 0)
+ {
+ attr_t *keycode = get_attr(action,"keycode");
+
+ if(keycode)
+ g_hash_table_insert(element->attrs,"keycode",keycode);
+ }
+
+ }
+
+ rmt_ctrl_item = proto_tree_add_item(tree, hf_xmpp_jitsi_inputevt_rmt_ctrl, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
+ rmt_ctrl_tree = proto_item_add_subtree(rmt_ctrl_item, ett_xmpp_jitsi_inputevt_rmt_ctrl);
+
+ display_attrs(rmt_ctrl_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
+ display_elems(rmt_ctrl_tree, element, pinfo, tvb, NULL, 0);
+}
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-xmpp-other.h b/epan/dissectors/packet-xmpp-other.h
new file mode 100644
index 0000000000..8b13d47e48
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-other.h
@@ -0,0 +1,68 @@
+/* xmpp-others.h
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef XMPP_OTHER_H
+#define XMPP_OTHER_H
+
+extern void xmpp_iq_bind(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_session(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_vcard(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_disco_items_query(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element);
+extern void xmpp_roster_query(proto_tree *tree, tvbuff_t *tvb, packet_info* pinfo, element_t *element);
+extern void xmpp_disco_info_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_bytestreams_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_si(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+
+extern void xmpp_feature_neg(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+extern void xmpp_x_data(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+
+extern void xmpp_ibb_open(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_ibb_close(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_ibb_data(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_delay(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_presence_caps(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_vcard_x_update(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+
+extern void xmpp_x_event(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_muc_x(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_muc_user_x(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_muc_owner_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_muc_admin_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_last_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_version_query(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_ping(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+extern void xmpp_hashes(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_jitsi_inputevt(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+#endif /* XMPP_OTHER_H */
+
diff --git a/epan/dissectors/packet-xmpp-utils.c b/epan/dissectors/packet-xmpp-utils.c
new file mode 100644
index 0000000000..e89af2df3b
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-utils.c
@@ -0,0 +1,1139 @@
+/* xmpp-utils.c
+ * Wireshark's XMPP dissector.
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <glib.h>
+#include <stdio.h>
+
+#include <epan/conversation.h>
+#include <epan/proto.h>
+#include <epan/packet_info.h>
+#include <epan/epan.h>
+#include <epan/expert.h>
+#include <epan/tvbuff.h>
+#include <epan/tvbparse.h>
+
+#include <epan/dissectors/packet-xml.h>
+
+#include <packet-xmpp.h>
+#include <packet-xmpp-utils.h>
+
+#include <epan/strutil.h>
+
+void
+xmpp_iq_reqresp_track(packet_info *pinfo, element_t *packet, xmpp_conv_info_t *xmpp_info)
+{
+ xmpp_transaction_t *xmpp_trans = NULL;
+
+ attr_t *attr_id;
+ char *id;
+
+ attr_id = get_attr(packet, "id");
+ DISSECTOR_ASSERT(attr_id);
+ id = ep_strdup(attr_id->value);
+
+ if (!pinfo->fd->flags.visited) {
+ xmpp_trans = se_tree_lookup_string(xmpp_info->req_resp, id, EMEM_TREE_STRING_NOCASE);
+ if (xmpp_trans) {
+ xmpp_trans->resp_frame = pinfo->fd->num;
+
+ } else {
+ char *se_id = se_strdup(id);
+
+ xmpp_trans = se_alloc(sizeof (xmpp_transaction_t));
+ xmpp_trans->req_frame = pinfo->fd->num;
+ xmpp_trans->resp_frame = 0;
+
+ se_tree_insert_string(xmpp_info->req_resp, se_id, (void *) xmpp_trans, EMEM_TREE_STRING_NOCASE);
+
+ }
+
+ } else {
+ se_tree_lookup_string(xmpp_info->req_resp, id, EMEM_TREE_STRING_NOCASE);
+ }
+}
+
+void
+xmpp_jingle_session_track(packet_info *pinfo, element_t *packet, xmpp_conv_info_t *xmpp_info)
+{
+ element_t *jingle_packet;
+ GList *jingle_packet_l;
+
+ jingle_packet_l = find_element_by_name(packet,"jingle");
+ jingle_packet = jingle_packet_l?jingle_packet_l->data:NULL;
+
+ if (jingle_packet && !pinfo->fd->flags.visited) {
+ attr_t *attr_id;
+ attr_t *attr_sid;
+
+ char *se_id;
+ char *se_sid;
+
+
+ attr_id = get_attr(packet, "id");
+ DISSECTOR_ASSERT(attr_id);
+
+ se_id = se_strdup(attr_id->value);
+
+ attr_sid = get_attr(jingle_packet, "sid");
+ DISSECTOR_ASSERT(attr_sid);
+
+ se_sid = se_strdup(attr_sid->value);
+
+ se_tree_insert_string(xmpp_info->jingle_sessions, se_id, (void*) se_sid, EMEM_TREE_STRING_NOCASE);
+ }
+}
+
+void
+xmpp_gtalk_session_track(packet_info *pinfo, element_t *packet, xmpp_conv_info_t *xmpp_info)
+{
+ element_t *gtalk_packet;
+ GList *gtalk_packet_l;
+
+ gtalk_packet_l = find_element_by_name(packet,"session");
+ gtalk_packet = gtalk_packet_l?gtalk_packet_l->data:NULL;
+
+
+ if (gtalk_packet && !pinfo->fd->flags.visited) {
+ attr_t *attr_id;
+ attr_t *attr_sid;
+
+ char *se_id;
+ char *se_sid;
+
+ attr_t *xmlns = get_attr(gtalk_packet, "xmlns");
+ if(xmlns && strcmp(xmlns->value,"http://www.google.com/session") != 0)
+ return;
+
+
+ attr_id = get_attr(packet, "id");
+ DISSECTOR_ASSERT(attr_id);
+
+ se_id = se_strdup(attr_id->value);
+
+ attr_sid = get_attr(gtalk_packet, "id");
+ DISSECTOR_ASSERT(attr_sid);
+ se_sid = se_strdup(attr_sid->value);
+
+ se_tree_insert_string(xmpp_info->gtalk_sessions, se_id, (void*) se_sid, EMEM_TREE_STRING_NOCASE);
+ }
+}
+
+void
+xmpp_ibb_session_track(packet_info *pinfo, element_t *packet, xmpp_conv_info_t *xmpp_info)
+{
+ element_t *ibb_packet = NULL;
+ GList *ibb_packet_l;
+
+ if(strcmp(packet->name, "message") == 0)
+ {
+ ibb_packet_l = find_element_by_name(packet,"data");
+ ibb_packet = ibb_packet_l?ibb_packet_l->data:NULL;
+
+ } else if(strcmp(packet->name, "iq") == 0)
+ {
+ ibb_packet_l = find_element_by_name(packet,"open");
+
+ if(!ibb_packet_l)
+ ibb_packet_l = find_element_by_name(packet,"close");
+ if(!ibb_packet_l)
+ ibb_packet_l = find_element_by_name(packet,"data");
+
+ ibb_packet = ibb_packet_l?ibb_packet_l->data:NULL;
+ }
+
+ if (ibb_packet && !pinfo->fd->flags.visited) {
+ attr_t *attr_id;
+ attr_t *attr_sid;
+
+ char *se_id;
+ char *se_sid;
+
+
+ attr_id = get_attr(packet, "id");
+ attr_sid = get_attr(ibb_packet, "sid");
+ if(attr_id && attr_sid)
+ {
+ se_id = se_strdup(attr_id->value);
+ se_sid = se_strdup(attr_sid->value);
+ se_tree_insert_string(xmpp_info->ibb_sessions, se_id, (void*) se_sid, EMEM_TREE_STRING_NOCASE);
+ }
+ }
+}
+
+static void
+xmpp_unknown_items(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element, guint level)
+{
+ GList *childs = element->elements;
+
+ DISSECTOR_ASSERT( level < ETT_UNKNOWN_LEN );
+
+ xmpp_unknown_attrs(tree, tvb, pinfo, element, TRUE);
+
+ if(element->data)
+ {
+ proto_tree_add_text(tree, tvb, element->data->offset, element->data->length, "CDATA: %s",element->data->value);
+ }
+
+ while(childs)
+ {
+ element_t *child = childs->data;
+ proto_item *child_item = proto_tree_add_text(tree, tvb, child->offset, child->length, "%s", ep_string_upcase(child->name));
+ proto_tree *child_tree = proto_item_add_subtree(child_item, ett_unknown[level]);
+
+ if(child->default_ns_abbrev)
+ proto_item_append_text(child_item, "(%s)", child->default_ns_abbrev);
+
+ xmpp_unknown_items(child_tree, tvb, pinfo, child, level +1);
+
+ childs = childs->next;
+ }
+}
+
+void
+xmpp_unknown(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element)
+{
+ GList *childs = element->elements;
+
+ /*element has unrecognized elements*/
+ while(childs)
+ {
+ element_t *child = childs->data;
+ if(!child->was_read)
+ {
+ proto_item *unknown_item;
+ proto_tree *unknown_tree;
+
+#ifdef XMPP_DEBUG
+ unknown_item = proto_tree_add_string_format(tree,
+ hf_xmpp_unknown, tvb, child->offset, child->length, child->name,
+ "%s", ep_string_upcase(child->name));
+#else
+ unknown_item = proto_tree_add_text(tree, tvb, child->offset, child->length,
+ "%s", ep_string_upcase(child->name));
+#endif
+ unknown_tree = proto_item_add_subtree(unknown_item, ett_unknown[0]);
+
+ /*Add COL_INFO only if root element is IQ*/
+ if(strcmp(element->name,"iq")==0)
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", ep_string_upcase(child->name));
+
+ if(child->default_ns_abbrev)
+ proto_item_append_text(unknown_item,"(%s)",child->default_ns_abbrev);
+
+ xmpp_unknown_items(unknown_tree, tvb, pinfo, child, 1);
+#ifdef XMPP_DEBUG
+ proto_item_append_text(unknown_item, " [UNKNOWN]");
+
+ expert_add_info_format(pinfo, unknown_item, PI_UNDECODED, PI_NOTE,"Unknown element: %s", child->name);
+#endif
+ }
+ childs = childs->next;
+ }
+}
+
+void
+xmpp_unknown_attrs(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, element_t *element, gboolean displ_short_list)
+{
+ proto_item *item = proto_tree_get_parent(tree);
+
+ GList *keys = g_hash_table_get_keys(element->attrs);
+ GList *values = g_hash_table_get_values(element->attrs);
+
+ GList *keys_head = keys, *values_head = values;
+
+ gboolean short_list_started = FALSE;
+
+ while(keys && values)
+ {
+ attr_t *attr = (attr_t*) values->data;
+ if (!attr->was_read) {
+ if (displ_short_list) {
+ if (!short_list_started)
+ proto_item_append_text(item, " [");
+ else
+ proto_item_append_text(item, " ");
+ proto_item_append_text(item, "%s=\"%s\"", (gchar*) keys->data, attr->value);
+
+ short_list_started = TRUE;
+ }
+
+ /*If unknown element has xmlns attrib then header field hf_xmpp_xmlns is added to the tree.
+ In other case only text.*/
+ if (strcmp(keys->data, "xmlns") == 0)
+ proto_tree_add_string(tree, hf_xmpp_xmlns, tvb, attr->offset, attr->length, attr->value);
+ else {
+ /*xmlns may looks like xmlns:abbrev="sth"*/
+ gchar* xmlns_needle = epan_strcasestr(keys->data, "xmlns:");
+ if (xmlns_needle && xmlns_needle == keys->data) {
+ proto_tree_add_string_format(tree, hf_xmpp_xmlns, tvb, attr->offset, attr->length, attr->value,"%s: %s", (gchar*)keys->data, attr->value);
+ } else {
+
+#ifdef XMPP_DEBUG
+ proto_item* unknown_attr_item;
+ unknown_attr_item = proto_tree_add_string_format(tree,
+ hf_xmpp_unknown_attr, tvb, attr->offset, attr->length,
+ attr->name, "%s: %s", attr->name, attr->value);
+ proto_item_append_text(unknown_attr_item, " [UNKNOWN ATTR]");
+ expert_add_info_format(pinfo, unknown_attr_item, PI_UNDECODED, PI_NOTE, "Unknown attribute %s.", attr->name);
+#else
+ proto_tree_add_text(tree, tvb, attr->offset, attr->length,
+ "%s: %s", attr->name, attr->value);
+#endif
+ }
+ }
+ }
+ keys = keys->next;
+ values = values->next;
+ }
+
+ if(short_list_started && displ_short_list)
+ proto_item_append_text(item, "]");
+
+ g_list_free(keys_head);
+ g_list_free(values_head);
+}
+
+void
+xmpp_cdata(proto_tree *tree, tvbuff_t *tvb, element_t *element, gint hf)
+{
+ if(element->data)
+{
+ if (hf == -1) {
+ proto_tree_add_text(tree, tvb, element->data->offset, element->data->length, "CDATA: %s", element->data->value);
+ } else {
+ proto_tree_add_string(tree, hf, tvb, element->data->offset, element->data->length, element->data->value);
+ }
+ } else
+ {
+ if (hf == -1) {
+ proto_tree_add_text(tree, tvb, 0, 0, "CDATA: (empty)");
+ } else {
+ proto_tree_add_string(tree, hf, tvb, 0, 0, "");
+ }
+ }
+}
+
+/* displays element that looks like <element_name>element_value</element_name>
+ * ELEMENT_NAME: element_value as TEXT(proto_tree_add_text) int PROTO_TREE
+ */
+void
+xmpp_simple_cdata_elem(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, element_t *element)
+{
+ proto_tree_add_text(tree, tvb, element->offset, element->length, "%s: %s", ep_string_upcase(element->name), elem_cdata(element));
+}
+
+array_t*
+ep_init_array_t(const gchar** array, gint len)
+{
+ array_t *result;
+
+ result = ep_alloc(sizeof(array_t));
+ result->data = (gpointer) array;
+ result->length = len;
+
+ return result;
+}
+
+attr_t*
+ep_init_attr_t(gchar *value, gint offset, gint length)
+{
+ attr_t *result;
+ result = ep_alloc(sizeof(attr_t));
+ result->value = value;
+ result->offset = offset;
+ result->length = length;
+ result->name = NULL;
+
+ return result;
+}
+
+gchar*
+ep_string_upcase(const gchar* string)
+{
+ gint len = strlen(string);
+ gint i;
+ gchar* result = ep_alloc0(len+1);
+ for(i=0; i<len; i++)
+ {
+ result[i] = string[i];
+
+ if(string[i]>='a' && string[i]<='z')
+ result[i]-='a'-'A';
+
+ }
+ return result;
+}
+
+gint
+element_t_cmp(gconstpointer a, gconstpointer b)
+{
+ gint result = strcmp(((element_t*)a)->name,((element_t*)b)->name);
+
+ if(result == 0 && ((element_t*)a)->was_read)
+ result = -1;
+
+ return result;
+}
+
+GList*
+find_element_by_name(element_t *packet,const gchar *name)
+{
+ GList *found_elements;
+ element_t *search_element;
+
+ /*create fake element only with name*/
+ search_element = ep_alloc(sizeof(element_t));
+ search_element->name = ep_strdup(name);
+
+ found_elements = g_list_find_custom(packet->elements, search_element, element_t_cmp);
+
+ if(found_elements)
+ return found_elements;
+ else
+ return NULL;
+}
+
+
+/* steal_*
+ * function searches element in packet and sets it as read.
+ * if element doesn't exist, NULL is returned.
+ * If element is set as read, it is invisible for these functions.*/
+element_t*
+steal_element_by_name(element_t *packet,const gchar *name)
+{
+ GList *element_l;
+ element_t *element = NULL;
+
+ element_l = find_element_by_name(packet, name);
+
+ if(element_l)
+ {
+ element = element_l->data;
+ element->was_read = TRUE;
+ }
+
+ return element;
+
+}
+
+element_t*
+steal_element_by_names(element_t *packet, const gchar **names, gint names_len)
+{
+ gint i;
+ element_t *el = NULL;
+
+ for(i = 0; i<names_len; i++)
+ {
+ if((el = steal_element_by_name(packet, names[i])))
+ break;
+ }
+
+ return el;
+}
+
+element_t*
+steal_element_by_attr(element_t *packet, const gchar *attr_name, const gchar *attr_value)
+{
+ GList *childs = packet->elements;
+ element_t *result = NULL;
+
+ while (childs) {
+ element_t *child_elem = childs->data;
+ attr_t *attr = get_attr(child_elem, attr_name);
+
+ if(attr)
+ attr->was_read = FALSE;
+
+ if (!child_elem->was_read && attr && strcmp(attr->value, attr_value) == 0) {
+
+ result = childs->data;
+
+ result->was_read = TRUE;
+
+ break;
+ } else
+ childs = childs->next;
+ }
+
+ return result;
+}
+
+element_t*
+steal_element_by_name_and_attr(element_t *packet, const gchar *name, const gchar *attr_name, const gchar *attr_value)
+{
+ GList *childs = packet->elements;
+ element_t *result = NULL;
+
+ while (childs) {
+ element_t *child_elem = childs->data;
+ attr_t *attr = get_attr(child_elem, attr_name);
+
+ if(attr)
+ attr->was_read = FALSE;
+
+ if (!child_elem->was_read && attr && strcmp(child_elem->name, name) == 0 && strcmp(attr->value, attr_value) == 0) {
+
+ result = childs->data;
+
+ result->was_read = TRUE;
+
+ break;
+ } else
+ childs = childs->next;
+ }
+ return result;
+}
+
+element_t*
+get_first_element(element_t *packet)
+{
+ if(packet->elements && packet->elements->data)
+ return packet->elements->data;
+ else
+ return NULL;
+}
+
+/*
+Function converts xml_frame_t structure to element_t (simpler representation)
+*/
+element_t*
+xml_frame_to_element_t(xml_frame_t *xml_frame, element_t *parent, tvbuff_t *tvb)
+{
+ xml_frame_t *child;
+ element_t *node = ep_alloc0(sizeof(element_t));
+
+ tvbparse_wanted_t *want_ignore, *want_name, *want_scoped_name;
+ tvbparse_t* tt;
+ tvbparse_elem_t* elem;
+
+ node->attrs = g_hash_table_new(g_str_hash, g_str_equal);
+ node->elements = NULL;
+ node->data = NULL;
+ node->was_read = FALSE;
+ node->default_ns_abbrev = NULL;
+
+ node->name = ep_strdup(xml_frame->name_orig_case);
+ node->offset = 0;
+ node->length = 0;
+
+ node->namespaces = g_hash_table_new(g_str_hash, g_str_equal);
+ if(parent)
+ {
+ copy_hash_table(parent->namespaces, node->namespaces);
+ } else
+ {
+ g_hash_table_insert(node->namespaces, "", "jabber:client");
+ }
+
+ if(xml_frame->item != NULL)
+ {
+ node->length = xml_frame->item->finfo->length;
+ }
+
+ node->offset = xml_frame->start_offset;
+
+ /*looking for element's names that looks like ns:tag_name*/
+ want_ignore = tvbparse_chars(-1,1,0," \t\r\n</",NULL,NULL,NULL);
+ want_name = tvbparse_chars(-1,1,0,"abcdefghijklmnopqrstuvwxyz.-_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",NULL,NULL,NULL);
+ want_scoped_name = tvbparse_set_seq(-1, NULL, NULL, NULL, want_name, tvbparse_char(-1,":",NULL,NULL,NULL), want_name, NULL);
+
+ tt = tvbparse_init(tvb,node->offset,-1,NULL,want_ignore);
+
+ if((elem = tvbparse_get(tt,want_scoped_name))!=NULL)
+ {
+ node->default_ns_abbrev = tvb_get_ephemeral_string(elem->sub->tvb, elem->sub->offset, elem->sub->len);
+ }
+
+ child = xml_frame->first_child;
+
+ while(child)
+ {
+ if(child->type != XML_FRAME_TAG)
+ {
+ if(child->type == XML_FRAME_ATTRIB)
+ {
+ gint l;
+ gchar *value = NULL;
+ gchar *xmlns_needle = NULL;
+
+ attr_t *attr = ep_alloc(sizeof(attr_t));
+ attr->length = 0;
+ attr->offset = 0;
+ attr->was_read = FALSE;
+
+ if (child->value != NULL) {
+ l = tvb_reported_length(child->value);
+ value = ep_alloc0(l + 1);
+ tvb_memcpy(child->value, value, 0, l);
+ }
+
+ if(child->item)
+ {
+ attr->length = child->item->finfo->length;
+ }
+
+ attr->offset = child->start_offset;
+ attr->value = value;
+ attr->name = ep_strdup(child->name_orig_case);
+
+ g_hash_table_insert(node->attrs,(gpointer)attr->name,(gpointer)attr);
+
+ /*checking that attr->name looks like xmlns:ns*/
+ xmlns_needle = epan_strcasestr(attr->name, "xmlns");
+
+ if(xmlns_needle == attr->name)
+ {
+ if(attr->name[5] == ':' && strlen(attr->name) > 6)
+ {
+ g_hash_table_insert(node->namespaces, (gpointer)ep_strdup(&attr->name[6]), (gpointer)ep_strdup(attr->value));
+ } else if(attr->name[5] == '\0')
+ {
+ g_hash_table_insert(node->namespaces, "", (gpointer)ep_strdup(attr->value));
+ }
+ }
+
+
+ }
+ else if( child->type == XML_FRAME_CDATA)
+ {
+ data_t *data = NULL;
+ gint l;
+ gchar* value = NULL;
+
+ data = ep_alloc(sizeof(data_t));
+ data->length = 0;
+ data->offset = 0;
+
+ if (child->value != NULL) {
+ l = tvb_reported_length(child->value);
+ value = ep_alloc0(l + 1);
+ tvb_memcpy(child->value, value, 0, l);
+ }
+
+ data->value = value;
+
+ if(child->item)
+ {
+ data->length = child->item->finfo->length;
+ }
+ data->offset = child->start_offset;
+ node->data = data;
+ }
+ } else
+ {
+ node->elements = g_list_append(node->elements,(gpointer)xml_frame_to_element_t(child, node,tvb));
+ }
+
+ child = child->next_sibling;
+ }
+ return node;
+}
+
+void
+element_t_tree_free(element_t *root)
+{
+ GList *childs = root->elements;
+
+ g_hash_table_destroy(root->attrs);
+ g_hash_table_destroy(root->namespaces);
+
+ while(childs)
+ {
+ element_t *child = childs->data;
+
+ element_t_tree_free(child);
+ childs = childs->next;
+ }
+ g_list_free(root->elements);
+}
+
+/*Function recognize attribute names if they looks like xmlns:ns*/
+static gboolean
+attr_find_pred(gpointer key, gpointer value _U_, gpointer user_data)
+{
+ gchar *attr_name = (gchar*) user_data;
+
+ if( strcmp(attr_name, "xmlns") == 0 )
+ {
+ gchar *first_occur = epan_strcasestr(key, "xmlns:");
+ if(first_occur && first_occur == key)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ return FALSE;
+}
+
+/*Functions returns element's attibute by name and set as read*/
+attr_t*
+get_attr(element_t *element, const gchar* attr_name)
+{
+ attr_t *result = g_hash_table_lookup(element->attrs, attr_name);
+
+ if(!result)
+ {
+ result = g_hash_table_find(element->attrs, attr_find_pred, (gpointer)attr_name);
+ }
+
+ if(result)
+ result->was_read = TRUE;
+
+ return result;
+}
+
+/*Functions returns element's attibute by name and namespace abbrev*/
+static attr_t*
+get_attr_ext(element_t *element, const gchar* attr_name, const gchar* ns_abbrev)
+{
+ gchar* search_phrase;
+ attr_t *result;
+
+ if(strcmp(ns_abbrev,"")==0)
+ search_phrase = ep_strdup(attr_name);
+ else if(strcmp(attr_name, "xmlns") == 0)
+ search_phrase = ep_strdup_printf("%s:%s",attr_name, ns_abbrev);
+ else
+ search_phrase = ep_strdup_printf("%s:%s", ns_abbrev, attr_name);
+
+ result = g_hash_table_lookup(element->attrs, search_phrase);
+
+ if(!result)
+ {
+ result = g_hash_table_find(element->attrs, attr_find_pred, (gpointer)attr_name);
+ }
+
+ if(result)
+ result->was_read = TRUE;
+
+ return result;
+}
+
+
+
+gchar*
+element_to_string(tvbuff_t *tvb, element_t *element)
+{
+ gchar *buff = NULL;
+
+ if(tvb_offset_exists(tvb, element->offset+element->length-1))
+ {
+ buff = tvb_get_ephemeral_string(tvb, element->offset, element->length);
+ }
+ return buff;
+}
+
+gchar*
+attr_to_string(tvbuff_t *tvb, attr_t *attr)
+{
+ gchar *buff = NULL;
+
+ if(tvb_offset_exists(tvb, attr->offset + attr->length-1))
+ {
+ buff = tvb_get_ephemeral_string(tvb, attr->offset, attr->length);
+ }
+ return buff;
+}
+
+static void
+children_foreach_hide_func(proto_node *node, gpointer data)
+{
+ int *i = data;
+ if((*i) == 0)
+ PROTO_ITEM_SET_HIDDEN(node);
+ (*i)++;
+}
+
+static void
+children_foreach_show_func(proto_node *node, gpointer data)
+{
+ int *i = data;
+ if((*i) == 0)
+ PROTO_ITEM_SET_VISIBLE(node);
+ (*i)++;
+}
+
+void
+proto_tree_hide_first_child(proto_tree *tree)
+{
+ int i = 0;
+ proto_tree_children_foreach(tree, children_foreach_hide_func, &i);
+}
+
+void
+proto_tree_show_first_child(proto_tree *tree)
+{
+ int i = 0;
+ proto_tree_children_foreach(tree, children_foreach_show_func, &i);
+}
+
+gchar*
+proto_item_get_text(proto_item *item)
+{
+ field_info *fi = NULL;
+ gchar *result;
+
+ if(item == NULL)
+ return NULL;
+
+ fi = PITEM_FINFO(item);
+
+ if(fi==NULL)
+ return NULL;
+
+ if (fi->rep == NULL)
+ return NULL;
+
+
+ result = ep_strdup(fi->rep->representation);
+ return result;
+}
+
+
+void
+display_attrs(proto_tree *tree, element_t *element, packet_info *pinfo, tvbuff_t *tvb, attr_info *attrs, guint n)
+{
+ proto_item *item = proto_tree_get_parent(tree);
+ attr_t *attr;
+ guint i;
+ gboolean short_list_started = FALSE;
+
+ if(element->default_ns_abbrev)
+ proto_item_append_text(item, "(%s)",element->default_ns_abbrev);
+
+ proto_item_append_text(item," [");
+ for(i = 0; i < n && attrs!=NULL; i++)
+ {
+ attr = get_attr(element, attrs[i].name);
+ if(attr)
+ {
+ if(attrs[i].hf != -1)
+ {
+ if(attr->name)
+ proto_tree_add_string_format(tree, attrs[i].hf, tvb, attr->offset, attr->length, attr->value,"%s: %s", attr->name, attr->value);
+ else
+ proto_tree_add_string(tree, attrs[i].hf, tvb, attr->offset, attr->length, attr->value);
+ }
+ else
+ {
+ proto_tree_add_text(tree, tvb, attr->offset, attr->length, "%s: %s", attr->name?attr->name:attrs[i].name, attr->value);
+ }
+
+ if(attrs[i].in_short_list)
+ {
+ if(short_list_started)
+ {
+ proto_item_append_text(item," ");
+ }
+ proto_item_append_text(item,"%s=\"%s\"",attr->name?attr->name:attrs[i].name, attr->value);
+ short_list_started = TRUE;
+ }
+
+ } else if(attrs[i].is_required)
+ {
+ expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN,
+ "Required attribute \"%s\" doesn't appear in \"%s\".",attrs[i].name,
+ element->name);
+ }
+
+ if(attrs[i].val_func)
+ {
+ if(attr)
+ attrs[i].val_func(pinfo, item, attrs[i].name, attr->value, attrs[i].data);
+ else
+ attrs[i].val_func(pinfo, item, attrs[i].name, NULL, attrs[i].data);
+ }
+ }
+ proto_item_append_text(item,"]");
+
+ /*displays attributes that weren't recognized*/
+ xmpp_unknown_attrs(tree, tvb, pinfo, element, FALSE);
+}
+
+void
+display_attrs_ext(proto_tree *tree, element_t *element, packet_info *pinfo, tvbuff_t *tvb, attr_info_ext *attrs, guint n)
+{
+ proto_item *item = proto_tree_get_parent(tree);
+ attr_t *attr;
+ guint i;
+ gboolean short_list_started = FALSE;
+
+ GList *ns_abbrevs_head, *ns_abbrevs = g_hash_table_get_keys(element->namespaces);
+ GList *ns_fullnames_head, *ns_fullnames = g_hash_table_get_values(element->namespaces);
+ ns_abbrevs_head = ns_abbrevs;
+ ns_fullnames_head = ns_fullnames;
+
+ if(element->default_ns_abbrev)
+ proto_item_append_text(item, "(%s)",element->default_ns_abbrev);
+
+ proto_item_append_text(item," [");
+ while(ns_abbrevs && ns_fullnames)
+ {
+ for (i = 0; i < n && attrs != NULL; i++) {
+ if(strcmp(ns_fullnames->data, attrs[i].ns) == 0)
+ {
+ attr = get_attr_ext(element, attrs[i].info.name, ns_abbrevs->data);
+ if(!attr && element->default_ns_abbrev && strcmp(ns_abbrevs->data, element->default_ns_abbrev)==0)
+ attr = get_attr_ext(element, attrs[i].info.name, "");
+
+ if (attr) {
+ if (attrs[i].info.hf != -1) {
+ if (attr->name)
+ proto_tree_add_string_format(tree, attrs[i].info.hf, tvb, attr->offset, attr->length, attr->value, "%s: %s", attr->name, attr->value);
+ else
+ proto_tree_add_string(tree, attrs[i].info.hf, tvb, attr->offset, attr->length, attr->value);
+ } else {
+ proto_tree_add_text(tree, tvb, attr->offset, attr->length, "%s: %s", attr->name ? attr->name : attrs[i].info.name, attr->value);
+ }
+
+ if (attrs[i].info.in_short_list) {
+ if (short_list_started) {
+ proto_item_append_text(item, " ");
+ }
+ proto_item_append_text(item, "%s=\"%s\"", attr->name ? attr->name : attrs[i].info.name, attr->value);
+ short_list_started = TRUE;
+ }
+
+ } else if (attrs[i].info.is_required) {
+ expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN,
+ "Required attribute \"%s\" doesn't appear in \"%s\".", attrs[i].info.name,
+ element->name);
+ }
+
+ if (attrs[i].info.val_func) {
+ if (attr)
+ attrs[i].info.val_func(pinfo, item, attrs[i].info.name, attr->value, attrs[i].info.data);
+ else
+ attrs[i].info.val_func(pinfo, item, attrs[i].info.name, NULL, attrs[i].info.data);
+ }
+ }
+ }
+ ns_abbrevs = ns_abbrevs->next;
+ ns_fullnames = ns_fullnames->next;
+ }
+ proto_item_append_text(item,"]");
+
+ /*displays attributes that weren't recognized*/
+ xmpp_unknown_attrs(tree, tvb, pinfo, element, FALSE);
+
+ g_list_free(ns_abbrevs_head);
+ g_list_free(ns_fullnames_head);
+}
+
+struct name_attr_t
+{
+ gchar *name;
+ gchar *attr_name;
+ gchar *attr_value;
+};
+
+/*
+returns pointer to the struct that contains 3 strings(element name, attribute name, attribute value)
+*/
+gpointer
+name_attr_struct(gchar *name, gchar *attr_name, gchar *attr_value)
+{
+ struct name_attr_t *result;
+
+ result = ep_alloc(sizeof(struct name_attr_t));
+ result->name = name;
+ result->attr_name = attr_name;
+ result->attr_value = attr_value;
+ return result;
+}
+
+void
+display_elems(proto_tree *tree, element_t *parent, packet_info *pinfo, tvbuff_t *tvb, elem_info *elems, guint n)
+{
+ guint i;
+
+ for(i = 0; i < n && elems!=NULL; i++)
+ {
+ element_t *elem = NULL;
+
+ if(elems[i].type == NAME_AND_ATTR)
+ {
+ gboolean loop = TRUE;
+
+ struct
+ {
+ gchar *name;
+ gchar *attr_name;
+ gchar *attr_value;
+ } *a;
+
+ a = elems[i].data;
+
+ while(loop && (elem = steal_element_by_name_and_attr(parent, a->name, a->attr_name, a->attr_value))!=NULL)
+ {
+ elems[i].elem_func(tree, tvb, pinfo, elem);
+ if(elems[i].occurrence == ONE)
+ loop = FALSE;
+ }
+ } else if(elems[i].type == NAME)
+ {
+ gboolean loop = TRUE;
+ gchar *name = elems[i].data;
+
+ while(loop && (elem = steal_element_by_name(parent, name))!=NULL)
+ {
+ elems[i].elem_func(tree, tvb, pinfo, elem);
+ if(elems[i].occurrence == ONE)
+ loop = FALSE;
+ }
+ }
+ else if(elems[i].type == ATTR)
+ {
+ gboolean loop = TRUE;
+ struct {
+ gchar *name;
+ gchar *attr_name;
+ gchar *attr_value;
+ } *attr = elems[i].data;
+
+ while(loop && (elem = steal_element_by_attr(parent, attr->attr_name, attr->attr_value))!=NULL)
+ {
+ elems[i].elem_func(tree, tvb, pinfo, elem);
+ if(elems[i].occurrence == ONE)
+ loop = FALSE;
+ }
+
+ } else if(elems[i].type == NAMES)
+ {
+ gboolean loop = TRUE;
+ array_t *names = elems[i].data;
+
+ while(loop && (elem = steal_element_by_names(parent, (const gchar**)names->data, names->length))!=NULL)
+ {
+ elems[i].elem_func(tree, tvb, pinfo, elem);
+ if(elems[i].occurrence == ONE)
+ loop = FALSE;
+ }
+ }
+ }
+
+ xmpp_unknown(tree, tvb, pinfo, parent);
+}
+
+/*
+function checks that variable value is in array ((array_t)data)->data
+*/
+void
+val_enum_list(packet_info *pinfo, proto_item *item, gchar *name, gchar *value, gpointer data)
+{
+ array_t *enums_array = data;
+
+ gint i;
+ gboolean value_in_enums = FALSE;
+
+ gchar **enums = (char**)enums_array->data;
+
+ if (value != NULL) {
+ for (i = 0; i < enums_array->length; i++) {
+ if (strcmp(value, enums[i]) == 0) {
+ value_in_enums = TRUE;
+ break;
+ }
+ }
+ if (!value_in_enums) {
+ expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN,
+ "Field \"%s\" has unexpected value \"%s\"",
+ name, value);
+ }
+ }
+}
+
+
+void
+change_elem_to_attrib(const gchar *elem_name, const gchar *attr_name, element_t *parent, attr_t* (*transform_func)(element_t *element))
+{
+ element_t *element = NULL;
+ attr_t *fake_attr = NULL;
+
+ element = steal_element_by_name(parent, elem_name);
+ if(element)
+ fake_attr = transform_func(element);
+
+ if(fake_attr)
+ g_hash_table_insert(parent->attrs, (gpointer)attr_name, fake_attr);
+}
+
+attr_t*
+transform_func_cdata(element_t *elem)
+{
+ attr_t *result = ep_init_attr_t(elem->data?elem->data->value:"", elem->offset, elem->length);
+ return result;
+}
+
+static void
+copy_hash_table_func(gpointer key, gpointer value, gpointer user_data)
+{
+ GHashTable *dst = user_data;
+ g_hash_table_insert(dst, key, value);
+}
+
+void copy_hash_table(GHashTable *src, GHashTable *dst)
+{
+ g_hash_table_foreach(src, copy_hash_table_func, dst);
+}
+
+/*
+static void
+printf_hash_table_func(gpointer key, gpointer value, gpointer user_data _U_)
+{
+ printf("'%s' '%s'\n", (gchar*)key, (gchar*)value);
+}
+
+void
+printf_elements(element_t *root)
+{
+ GList *elems = root->elements;
+
+ printf("%s\n", root->name);
+ g_hash_table_foreach(root->namespaces, printf_hash_table_func, NULL);
+ while(elems)
+ {
+ printf_elements(elems->data);
+ elems = elems->next;
+ }
+}
+*/
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-xmpp-utils.h b/epan/dissectors/packet-xmpp-utils.h
new file mode 100644
index 0000000000..b6e18ebd53
--- /dev/null
+++ b/epan/dissectors/packet-xmpp-utils.h
@@ -0,0 +1,287 @@
+/* xmpp-utils.h
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef XMPP_UTILS_H
+#define XMPP_UTILS_H
+
+#define FI_RESET_FLAG(fi, flag) \
+ do { \
+ if (fi) \
+ (fi)->flags = (fi)->flags & !(flag); \
+ } while(0)
+
+#define PROTO_ITEM_SET_VISIBLE(proto_item) \
+ do { \
+ if (proto_item) \
+ FI_RESET_FLAG(PITEM_FINFO(proto_item), FI_HIDDEN); \
+ } while(0)
+
+#define elem_cdata(elem) \
+elem->data?elem->data->value:""
+
+typedef struct _array_t
+{
+ gpointer data;
+ gint length;
+} array_t;
+
+typedef struct _attr_t{
+ gchar *value;
+ gchar *name;
+ gint offset;
+ gint length;
+
+ gboolean was_read;
+} attr_t;
+
+typedef struct _data_t{
+ gchar *value;
+
+ gint offset;
+ gint length;
+} data_t;
+
+typedef struct _element_t{
+ gchar* name;
+
+ /*abbreviation that apprears before tag name (<nos:x .../>)
+ if abbrev doesn't appear then NULL*/
+ gchar* default_ns_abbrev;
+ /*pair of namespace abbrev and namespace*/
+ GHashTable *namespaces;
+
+ GHashTable *attrs;
+ GList *elements;
+ data_t *data;
+
+ gint offset;
+ gint length;
+
+ gboolean was_read;
+} element_t;
+
+/*informations about attributes that are displayed in proto tree*/
+typedef struct _attr_info{
+ gchar *name;
+ gint hf;
+ gboolean is_required;
+ gboolean in_short_list;
+
+ /*function validates this attribute
+ it may impose other restrictions (e.g. validating atribut's name, ...)*/
+ void (*val_func)(packet_info *pinfo, proto_item *item, gchar *name, gchar *value, gpointer data);
+ gpointer data;
+} attr_info;
+
+typedef struct _attr_info_ext{
+ gchar* ns;
+ attr_info info;
+} attr_info_ext;
+
+typedef enum _elem_info_type{
+ NAME,
+ ATTR,
+ NAME_AND_ATTR,
+ NAMES
+} elem_info_type;
+
+typedef enum _elem_info_occurrence
+{
+ ONE,MANY
+} elem_info_occurrence;
+
+/*informations about elements that are displayed in proto tree*/
+typedef struct _elem_info{
+ elem_info_type type;
+ gpointer data;
+ /*function that displays element in tree*/
+ void (*elem_func)(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, element_t* element);
+ elem_info_occurrence occurrence;
+} elem_info;
+
+typedef struct _xmpp_conv_info_t {
+ emem_tree_t *req_resp;
+ emem_tree_t *jingle_sessions;
+ emem_tree_t *ibb_sessions;
+ emem_tree_t *gtalk_sessions;
+} xmpp_conv_info_t;
+
+/** Struct conatins frame numbers (request frame(IQ set/get) and
+ * response frame(IQ result/error)).
+ */
+typedef struct _xmpp_reqresp_transaction_t {
+ guint32 req_frame;
+ guint32 resp_frame;
+} xmpp_transaction_t;
+
+/** Function that is responsibe for request/response tracking in IQ packets.
+ * Each IQ set/get packet should have the response in other IQ result/error packet.
+ * Both packet should have the same id attribute. Function saves in emem_tree pairs of
+ * packet id and struct xmpp_transaction_t.
+ */
+extern void xmpp_iq_reqresp_track(packet_info *pinfo, element_t *packet, xmpp_conv_info_t *xmpp_info);
+
+/** Function that is responsibe for jingle session tracking in IQ packets.
+ * Function saves in emem_tree pairs of packet's id and Jingle session's id.
+ */
+extern void xmpp_jingle_session_track(packet_info *pinfo, element_t *packet, xmpp_conv_info_t *xmpp_info);
+
+/** Function that is responsibe for ibb(in band bytestreams) session tracking in IQ packets.
+ * Function saves in emem_tree pairs of packet's id and In-Band Bytestreams session's id.
+ */
+extern void xmpp_ibb_session_track(packet_info *pinfo, element_t *packet, xmpp_conv_info_t *xmpp_info);
+
+/** Function that is responsibe for GTalk session(voice/video) tracking in IQ packets.
+ * Function saves in emem_tree pairs of packet's id and GTalk session's id.
+ */
+extern void xmpp_gtalk_session_track(packet_info *pinfo, element_t *packet, xmpp_conv_info_t *xmpp_info);
+
+/** Function detects unrecognized elements and displays them in tree.
+ * It uses ett_unknown to display packets. ett_unknown has const size described by
+ * ETT_UNKNOWN_LEN in packet-xmpp.h
+ */
+extern void xmpp_unknown(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+extern void xmpp_unknown_attrs(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element, gboolean displ_short_list);
+
+/** Displays CDATA from element in tree. You can use your own header field hf or
+ * pass -1. If you pass -1 then CDATA will be display as text(proto_tree_add_text):
+ * ELEMENT_NAME: CDATA
+ * ELEMENT_NAME = element->name, if element is empty CDATA = "(empty)"
+ */
+extern void xmpp_cdata(proto_tree *tree, tvbuff_t *tvb, element_t *element, gint hf);
+
+/** Function is similar to xmpp_cdata. But it display items only as a text and it is
+ * compatibile with function display_elems
+ */
+extern void xmpp_simple_cdata_elem(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, element_t *element);
+
+/** Converts xml_frame_t struct to element_t. Should be call with parent==NULL.
+ */
+extern element_t* xml_frame_to_element_t(xml_frame_t *xml_frame, element_t *parent, tvbuff_t *tvb);
+
+/** Frees all GLib structs in element_t struct. Should be call only for root element.
+ * It works recursively.
+ */
+extern void element_t_tree_free(element_t *root);
+
+/** Allocs ephemeral memory for array_t struct.*/
+extern array_t* ep_init_array_t(const gchar** array, gint len);
+
+/*Allocs ephemeral memory for attr_t struct*/
+extern attr_t* ep_init_attr_t(gchar *value, gint offset, gint length);
+
+/*Allocs ephemeral memory for upcased string*/
+extern gchar* ep_string_upcase(const gchar* string);
+
+/*Compares 2 element_t struct by names. Returns value is similar to the returned by strcmp*/
+extern gint element_t_cmp(gconstpointer a, gconstpointer b);
+
+/*Searches child element in parent element by name. GList element is returned.*/
+extern GList* find_element_by_name(element_t *packet,const gchar *name);
+
+/** steal_*
+ * Functions searches and marks as read found elements.
+ * If element is set as read, it is invisible for these functions.*/
+
+extern element_t* steal_element_by_name(element_t *packet, const gchar *name);
+extern element_t* steal_element_by_names(element_t *packet, const gchar **names, gint names_len);
+extern element_t* steal_element_by_attr(element_t *packet, const gchar *attr_name, const gchar *attr_value);
+extern element_t* steal_element_by_name_and_attr(element_t *packet, const gchar *name, const gchar *attr_name, const gchar *attr_value);
+
+/*Returns first child in element*/
+extern element_t* get_first_element(element_t *packet);
+
+/*Converts element to string. Returns memory allocated as ephemeral.*/
+extern gchar* element_to_string(tvbuff_t *tvb, element_t *element);
+
+/*Converts attribute to string. Returns memory allocated as ephemeral.*/
+extern gchar* attr_to_string(tvbuff_t *tvb, attr_t *attr);
+
+/* Returns attribute by name and set as read. If attrib is set as read, it may be found
+ * one more time, but it is invisible for function xmpp_unknown_attrib*/
+extern attr_t* get_attr(element_t *element, const gchar* attr_name);
+
+/*Function hides first element in tree.*/
+extern void proto_tree_hide_first_child(proto_tree *tree);
+
+/*Function shows first element in tree.*/
+extern void proto_tree_show_first_child(proto_tree *tree);
+
+/*Function returns item as text. Memory is allocated as ephemeral.*/
+extern gchar* proto_item_get_text(proto_item *item);
+
+/*Function returns struct that contains 3 strings. It is used to build attr_info struct.*/
+extern gpointer name_attr_struct(gchar *name, gchar *attr_name, gchar *attr_value);
+
+/** Function displays attributes from element in way described in attrs.
+ * Elements that doesn't exist in attrs are displayed as text.
+ * In ATTR_INFO struct you can define several things:
+ * - is_in_short_list - attribute should be displayed in short list e.g. ELEMENT_NAME [ATTR1='value' ATTR2='value']
+ * - is_required - attribute is required. If attribute doesn't appear then EXPERT INFO will be displayed
+ * - val_func - validate function
+ * - data - data passes to the val_func
+ */
+extern void display_attrs(proto_tree *tree, element_t *element, packet_info *pinfo, tvbuff_t *tvb, attr_info *attrs, guint n);
+
+/** Function does the same as shown above. It takes attrs(ATTR_INFO_EXT) argument
+ * that contains ATTR_INFO struct and string with namespace. It is used when packet
+ * contains several namespaces and each attribute belongs to particular namespace.
+ * E.g.
+ * <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
+ * mechanism='PLAIN'
+ * xmlns:ga='http://www.google.com/talk/protocol/auth'
+ * ga:client-uses-full-bind-result='true'>
+ * </auth>
+ */
+extern void display_attrs_ext(proto_tree *tree, element_t *element, packet_info *pinfo, tvbuff_t *tvb, attr_info_ext *attrs, guint n);
+
+/** Displays elements from parent element in a way described in elems(ELEM_INFO).
+ * ELEM_INFO describes how to find particular element and what action should be done
+ * for this element.
+ * Function calls xmpp_unknown.
+ */
+extern void display_elems(proto_tree *tree, element_t *parent, packet_info *pinfo, tvbuff_t *tvb, elem_info *elems, guint n);
+
+/* Validates attribute value. Takes string array(gchar**) in parameter data.
+ * Is used in ATTR_INFO struct.
+ */
+extern void val_enum_list(packet_info *pinfo, proto_item *item, gchar *name, gchar *value, gpointer data);
+
+/** Function changes element to attribute. It searches element by name in parent element,
+ * next it create attribute using transform_func and inserts it to parent attributes hash table
+ * using attr_name as key.
+ */
+extern void change_elem_to_attrib(const gchar *elem_name, const gchar *attr_name, element_t *parent, attr_t* (*transform_func)(element_t *element));
+
+/** transform_func that creates attribute with element's cdata as value
+ */
+extern attr_t* transform_func_cdata(element_t *elem);
+
+/*Copys keys and values from one hash table to another.
+ Hash tables must be initialized.*/
+extern void copy_hash_table(GHashTable *src, GHashTable *dst);
+
+#endif /* XMPP_UTILS_H */
diff --git a/epan/dissectors/packet-xmpp.c b/epan/dissectors/packet-xmpp.c
index 529d31b569..7edd166454 100644
--- a/epan/dissectors/packet-xmpp.c
+++ b/epan/dissectors/packet-xmpp.c
@@ -1,8 +1,7 @@
/* packet-xmpp.c
- * Routines for XMPP packet dissection
- * Copyright 2003, Brad Hards <bradh@frogmouth.net>
- * Heavily based in packet-acap.c, which in turn is heavily based on
- * packet-imap.c, Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
+ * Wireshark's XMPP dissector.
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
*
* $Id$
*
@@ -10,8 +9,6 @@
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
- * Copied from packet-acap.c
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -25,116 +22,1410 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Ref http://xmpp.org/
*/
#ifdef HAVE_CONFIG_H
-# include "config.h"
+#include "config.h"
#endif
+#include<stdio.h>
+#include<string.h>
#include <glib.h>
+
#include <epan/packet.h>
+#include <epan/proto.h>
+#include <epan/emem.h>
+#include <epan/conversation.h>
#include <epan/strutil.h>
+#include <epan/expert.h>
+#include <epan/prefs.h>
+
+#include <epan/dissectors/packet-xml.h>
+
+#include <packet-xmpp-utils.h>
+#include <packet-xmpp.h>
+#include <packet-xmpp-core.h>
+#include <packet-xmpp-jingle.h>
+
+#define XMPP_PORT 5222
+
+static dissector_handle_t xml_handle = NULL;
+
+int proto_xmpp = -1;
+
+static gboolean xmpp_desegment = TRUE;
+
+gint hf_xmpp_xmlns = -1;
+gint hf_xmpp_id = -1;
+gint hf_xmpp_from = -1;
+gint hf_xmpp_to = -1;
+gint hf_xmpp_type = -1;
+
+gint hf_xmpp_iq = -1;
+
+gint hf_xmpp_query = -1;
+gint hf_xmpp_query_node = -1;
+
+gint hf_xmpp_query_item = -1;
+gint hf_xmpp_query_item_jid = -1;
+gint hf_xmpp_query_item_name = -1;
+gint hf_xmpp_query_item_subscription = -1;
+gint hf_xmpp_query_item_ask = -1;
+gint hf_xmpp_query_item_group = -1;
+gint hf_xmpp_query_item_node = -1;
+gint hf_xmpp_query_item_approved = -1;
+
+gint hf_xmpp_query_identity = -1;
+gint hf_xmpp_query_identity_category = -1;
+gint hf_xmpp_query_identity_type = -1;
+gint hf_xmpp_query_identity_name = -1;
+gint hf_xmpp_query_identity_lang = -1;
+
+gint hf_xmpp_query_feature = -1;
+
+gint hf_xmpp_query_streamhost = -1;
+gint hf_xmpp_query_streamhost_used = -1;
+gint hf_xmpp_query_activate = -1;
+gint hf_xmpp_query_udpsuccess = -1;
+
+gint hf_xmpp_error = -1;
+gint hf_xmpp_error_type = -1;
+gint hf_xmpp_error_code = -1;
+gint hf_xmpp_error_condition = -1;
+gint hf_xmpp_error_text = -1;
+
+gint hf_xmpp_iq_bind = -1;
+gint hf_xmpp_iq_bind_jid = -1;
+gint hf_xmpp_iq_bind_resource = -1;
+
+gint hf_xmpp_services = -1;
+gint hf_xmpp_channel = -1;
+
+gint hf_xmpp_iq_session = -1;
+gint hf_xmpp_stream = -1;
+gint hf_xmpp_features = -1;
+
+gint hf_xmpp_vcard = -1;
+gint hf_xmpp_vcard_x_update = -1;
+
+gint hf_xmpp_jingle = -1;
+gint hf_xmpp_jingle_sid = -1;
+gint hf_xmpp_jingle_initiator = -1;
+gint hf_xmpp_jingle_responder = -1;
+gint hf_xmpp_jingle_action = -1;
+
+gint hf_xmpp_jingle_content = -1;
+gint hf_xmpp_jingle_content_creator = -1;
+gint hf_xmpp_jingle_content_name = -1;
+gint hf_xmpp_jingle_content_disposition = -1;
+gint hf_xmpp_jingle_content_senders = -1;
+
+gint hf_xmpp_jingle_content_description = -1;
+gint hf_xmpp_jingle_content_description_media = -1;
+gint hf_xmpp_jingle_content_description_ssrc = -1;
+
+gint hf_xmpp_jingle_cont_desc_payload = -1;
+gint hf_xmpp_jingle_cont_desc_payload_id = -1;
+gint hf_xmpp_jingle_cont_desc_payload_channels = -1;
+gint hf_xmpp_jingle_cont_desc_payload_clockrate = -1;
+gint hf_xmpp_jingle_cont_desc_payload_maxptime = -1;
+gint hf_xmpp_jingle_cont_desc_payload_name = -1;
+gint hf_xmpp_jingle_cont_desc_payload_ptime = -1;
+
+gint hf_xmpp_jingle_cont_desc_payload_param = -1;
+gint hf_xmpp_jingle_cont_desc_payload_param_value = -1;
+gint hf_xmpp_jingle_cont_desc_payload_param_name = -1;
+
+gint hf_xmpp_jingle_cont_desc_enc = -1;
+gint hf_xmpp_jingle_cont_desc_enc_zrtp_hash = -1;
+gint hf_xmpp_jingle_cont_desc_enc_crypto = -1;
+
+gint hf_xmpp_jingle_cont_desc_rtp_hdr = -1;
+gint hf_xmpp_jingle_cont_desc_bandwidth = -1;
+
+gint hf_xmpp_jingle_cont_trans = -1;
+gint hf_xmpp_jingle_cont_trans_pwd = -1;
+gint hf_xmpp_jingle_cont_trans_ufrag = -1;
+
+gint hf_xmpp_jingle_cont_trans_cand = -1;
+gint hf_xmpp_jingle_cont_trans_rem_cand = -1;
+gint hf_xmpp_jingle_cont_trans_activated = -1;
+gint hf_xmpp_jingle_cont_trans_candidate_error = -1;
+gint hf_xmpp_jingle_cont_trans_candidate_used = -1;
+gint hf_xmpp_jingle_cont_trans_proxy_error = -1;
+
+
+gint hf_xmpp_jingle_reason = -1;
+gint hf_xmpp_jingle_reason_condition = -1;
+gint hf_xmpp_jingle_reason_text = -1;
+
+gint hf_xmpp_jingle_rtp_info = -1;
+
+gint hf_xmpp_jingle_file_transfer_offer = -1;
+gint hf_xmpp_jingle_file_transfer_request = -1;
+gint hf_xmpp_jingle_file_transfer_received = -1;
+gint hf_xmpp_jingle_file_transfer_abort = -1;
+gint hf_xmpp_jingle_file_transfer_checksum = -1;
+
+gint hf_xmpp_si = -1;
+gint hf_xmpp_si_file = -1;
+
+gint hf_xmpp_iq_feature_neg = -1;
+gint hf_xmpp_x_data = -1;
+gint hf_xmpp_x_data_field = -1;
+gint hf_xmpp_x_data_field_value = -1;
+
+gint hf_xmpp_message = -1;
+gint hf_xmpp_message_chatstate = -1;
+
+gint hf_xmpp_message_thread = -1;
+gint hf_xmpp_message_thread_parent = -1;
+
+gint hf_xmpp_message_body = -1;
+gint hf_xmpp_message_subject = -1;
+
+gint hf_xmpp_ibb_open = -1;
+gint hf_xmpp_ibb_close = -1;
+gint hf_xmpp_ibb_data = -1;
+
+gint hf_xmpp_delay = -1;
+
+gint hf_xmpp_x_event = -1;
+gint hf_xmpp_x_event_condition = -1;
+
+gint hf_xmpp_presence = -1;
+gint hf_xmpp_presence_show = -1;
+gint hf_xmpp_presence_status = -1;
+gint hf_xmpp_presence_caps = -1;
+
+gint hf_xmpp_auth = -1;
+gint hf_xmpp_challenge = -1;
+gint hf_xmpp_response = -1;
+gint hf_xmpp_success = -1;
+gint hf_xmpp_failure = -1;
+gint hf_xmpp_starttls = -1;
+gint hf_xmpp_proceed = -1;
+
+gint hf_xmpp_muc_x = -1;
+gint hf_xmpp_muc_user_x = -1;
+gint hf_xmpp_muc_user_item = -1;
+gint hf_xmpp_muc_user_invite = -1;
+
+gint hf_xmpp_gtalk_session = -1;
+gint hf_xmpp_gtalk_session_type = -1;
+gint hf_xmpp_gtalk = -1;
+gint hf_xmpp_gtalk_setting = -1;
+gint hf_xmpp_gtalk_nosave_x = -1;
+gint hf_xmpp_gtalk_mail_mailbox = -1;
+gint hf_xmpp_gtalk_mail_new_mail = -1;
+gint hf_xmpp_gtalk_transport_p2p = -1;
+
+
+gint hf_xmpp_conf_info = -1;
+gint hf_xmpp_conf_info_sid = -1;
+
+gint hf_xmpp_unknown = -1;
+gint hf_xmpp_unknown_attr = -1;
+
+gint hf_xmpp_out = -1;
+gint hf_xmpp_in = -1;
+gint hf_xmpp_response_in = -1;
+gint hf_xmpp_response_to = -1;
+gint hf_xmpp_jingle_session = -1;
+gint hf_xmpp_ibb = -1;
+
+gint hf_xmpp_ping = -1;
+gint hf_xmpp_hashes = -1;
+
+gint hf_xmpp_jitsi_inputevt = -1;
+gint hf_xmpp_jitsi_inputevt_rmt_ctrl = -1;
+
+gint ett_xmpp = -1;
+gint ett_xmpp_iq = -1;
+gint ett_xmpp_query = -1;
+gint ett_xmpp_query_item = -1;
+gint ett_xmpp_query_identity = -1;
+gint ett_xmpp_query_feature = -1;
+
+gint ett_xmpp_query_streamhost = -1;
+gint ett_xmpp_query_streamhost_used = -1;
+gint ett_xmpp_query_udpsuccess = -1;
+
+gint ett_xmpp_iq_error = -1;
+gint ett_xmpp_iq_bind = -1;
+gint ett_xmpp_iq_session = -1;
+gint ett_xmpp_vcard = -1;
+gint ett_xmpp_vcard_x_update = -1;
+
+gint ett_xmpp_jingle = -1;
+gint ett_xmpp_jingle_content = -1;
+gint ett_xmpp_jingle_content_description = -1;
+gint ett_xmpp_jingle_cont_desc_enc = -1;
+gint ett_xmpp_jingle_cont_desc_enc_zrtp_hash = -1;
+gint ett_xmpp_jingle_cont_desc_enc_crypto = -1;
+gint ett_xmpp_jingle_cont_desc_rtp_hdr = -1;
+gint ett_xmpp_jingle_cont_desc_bandwidth = -1;
+gint ett_xmpp_jingle_cont_desc_payload = -1;
+gint ett_xmpp_jingle_cont_desc_payload_param = -1;
+gint ett_xmpp_jingle_cont_trans = -1;
+gint ett_xmpp_jingle_cont_trans_cand = -1;
+gint ett_xmpp_jingle_cont_trans_rem_cand = -1;
+gint ett_xmpp_jingle_reason = -1;
+gint ett_xmpp_jingle_rtp_info = -1;
+
+gint ett_xmpp_jingle_file_transfer_offer = -1;
+gint ett_xmpp_jingle_file_transfer_request = -1;
+gint ett_xmpp_jingle_file_transfer_abort = -1;
+gint ett_xmpp_jingle_file_transfer_received = -1;
+gint ett_xmpp_jingle_file_transfer_checksum = -1;
+gint ett_xmpp_jingle_file_transfer_file = -1;
+
+gint ett_xmpp_services = -1;
+gint ett_xmpp_services_relay = -1;
+gint ett_xmpp_channel = -1;
+
+gint ett_xmpp_si = -1;
+gint ett_xmpp_si_file = -1;
+gint ett_xmpp_si_file_range = -1;
+
+gint ett_xmpp_iq_feature_neg = -1;
+gint ett_xmpp_x_data = -1;
+gint ett_xmpp_x_data_field = -1;
+gint ett_xmpp_x_data_field_value = -1;
+
+gint ett_xmpp_ibb_open = -1;
+gint ett_xmpp_ibb_close = -1;
+gint ett_xmpp_ibb_data = -1;
+
+gint ett_xmpp_delay = -1;
+
+gint ett_xmpp_x_event = -1;
+
+gint ett_xmpp_message = -1;
+gint ett_xmpp_message_thread = -1;
+gint ett_xmpp_message_body = -1;
+gint ett_xmpp_message_subject = -1;
+
+gint ett_xmpp_presence = -1;
+gint ett_xmpp_presence_status = -1;
+gint ett_xmpp_presence_caps = -1;
-static int proto_xmpp = -1;
-static int hf_xmpp_response = -1;
-static int hf_xmpp_request = -1;
+gint ett_xmpp_auth = -1;
+gint ett_xmpp_challenge = -1;
+gint ett_xmpp_response = -1;
+gint ett_xmpp_success = -1;
+gint ett_xmpp_failure = -1;
+gint ett_xmpp_stream = -1;
+gint ett_xmpp_features = -1;
+gint ett_xmpp_features_mechanisms = -1;
+gint ett_xmpp_starttls = -1;
+gint ett_xmpp_proceed = -1;
-static gint ett_xmpp = -1;
-static gint ett_xmpp_reqresp = -1;
+gint ett_xmpp_muc_x = -1;
+gint ett_xmpp_muc_hist = -1;
+gint ett_xmpp_muc_user_x = -1;
+gint ett_xmpp_muc_user_item = -1;
+gint ett_xmpp_muc_user_invite = -1;
-#define TCP_PORT_XMPP 5222
-static dissector_handle_t xml_handle=NULL;
+gint ett_xmpp_gtalk_session = -1;
+gint ett_xmpp_gtalk_session_desc = -1;
+gint ett_xmpp_gtalk_session_cand = -1;
+gint ett_xmpp_gtalk_session_desc_payload = -1;
+gint ett_xmpp_gtalk_session_reason = -1;
+gint ett_xmpp_gtalk_jingleinfo_stun = -1;
+gint ett_xmpp_gtalk_jingleinfo_server = -1;
+gint ett_xmpp_gtalk_jingleinfo_relay = -1;
+gint ett_xmpp_gtalk_jingleinfo_relay_serv = -1;
+gint ett_xmpp_gtalk_setting = -1;
+gint ett_xmpp_gtalk_nosave_x = -1;
+gint ett_xmpp_gtalk_mail_mailbox = -1;
+gint ett_xmpp_gtalk_mail_mail_info = -1;
+gint ett_xmpp_gtalk_mail_senders = -1;
+gint ett_xmpp_gtalk_mail_sender = -1;
+gint ett_xmpp_gtalk_status_status_list = -1;
+gint ett_xmpp_gtalk_transport_p2p = -1;
+gint ett_xmpp_gtalk_transport_p2p_cand = -1;
+
+gint ett_xmpp_conf_info = -1;
+gint ett_xmpp_conf_desc = -1;
+gint ett_xmpp_conf_state = -1;
+gint ett_xmpp_conf_users = -1;
+gint ett_xmpp_conf_user = -1;
+gint ett_xmpp_conf_endpoint = -1;
+gint ett_xmpp_conf_media = -1;
+
+gint ett_xmpp_ping = -1;
+gint ett_xmpp_hashes = -1;
+gint ett_xmpp_hashes_hash = -1;
+
+gint ett_xmpp_jitsi_inputevt = -1;
+gint ett_xmpp_jitsi_inputevt_rmt_ctrl = -1;
+
+gint ett_unknown[ETT_UNKNOWN_LEN];
static void
-dissect_xmpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- gboolean is_request;
- proto_tree *xmpp_tree = NULL;
- proto_item *ti, *hidden_item;
- gint offset = 0;
- const guchar *line;
- gint next_offset;
- int linelen;
- tvbuff_t *xmltvb;
-
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "XMPP");
-
- /*
- * Find the end of the first line.
- *
- * Note that "tvb_find_line_end()" will return a value that is
- * not longer than what's in the buffer, so the "tvb_get_ptr()"
- * call won't throw an exception.
- */
- linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
- line = tvb_get_ptr(tvb, offset, linelen);
-
- if (pinfo->match_uint == pinfo->destport)
- is_request = TRUE;
- else
- is_request = FALSE;
-
- /*
- * Put the first line from the buffer into the summary
- * (but leave out the line terminator).
- */
- col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s",
- is_request ? "Request" : "Response",
- format_text(line, linelen));
-
- if (tree) {
- ti = proto_tree_add_item(tree, proto_xmpp, tvb, offset, -1,
- ENC_NA) ;
- xmpp_tree = proto_item_add_subtree(ti, ett_xmpp);
-
- if (is_request) {
- hidden_item = proto_tree_add_boolean(xmpp_tree,
- hf_xmpp_request, tvb, 0, 0, TRUE);
- } else {
- hidden_item = proto_tree_add_boolean(xmpp_tree,
- hf_xmpp_response, tvb, 0, 0, TRUE);
- }
- PROTO_ITEM_SET_HIDDEN(hidden_item);
- }
-
- xmltvb = tvb_new_subset_remaining(tvb, offset);
- call_dissector(xml_handle, xmltvb, pinfo, xmpp_tree);
+dissect_xmpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
+
+ xml_frame_t *xml_frame;
+ gboolean out_packet;
+
+ conversation_t *conversation;
+ xmpp_conv_info_t *xmpp_info;
+
+ proto_tree *xmpp_tree = NULL;
+ proto_item *xmpp_item = NULL;
+
+ element_t *packet = NULL;
+
+ /*check if desegment
+ * now it checks that last char is '>',
+ * TODO checks that first element in packet is closed*/
+ int index;
+ gchar last_char;
+
+ if (xmpp_desegment)
+ {
+ index = tvb_reported_length(tvb) - 1;
+ if (index >= 0)
+ {
+ last_char = tvb_get_guint8(tvb, index);
+
+ while (last_char <= ' ' && index - 1 >= 0)
+ {
+ index--;
+ last_char = tvb_get_guint8(tvb, index);
+ }
+
+ if (index >= 0 && last_char != '>')
+ {
+ pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
+ return;
+ }
+ }
+ }
+
+ if(check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "XMPP");
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /*if tree == NULL then xmpp_item and xmpp_tree will also NULL*/
+ xmpp_item = proto_tree_add_item(tree, proto_xmpp, tvb, 0, -1, ENC_NA);
+ xmpp_tree = proto_item_add_subtree(xmpp_item, ett_xmpp);
+
+ call_dissector(xml_handle,tvb,pinfo,xmpp_tree);
+
+ /*if stream end occurs then return*/
+ if(xmpp_stream_close(xmpp_tree,tvb, pinfo))
+ {
+ if(xmpp_tree)
+ proto_tree_hide_first_child(xmpp_tree);
+ return;
+ }
+
+ if(!pinfo->private_data)
+ return;
+
+ /*data from XML dissector*/
+ xml_frame = ((xml_frame_t*)pinfo->private_data)->first_child;
+
+ if(!xml_frame)
+ return;
+
+ conversation = find_or_create_conversation(pinfo);
+ xmpp_info = conversation_get_proto_data(conversation, proto_xmpp);
+
+ if (!xmpp_info) {
+ xmpp_info = se_alloc(sizeof (xmpp_conv_info_t));
+ xmpp_info->req_resp = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "xmpp_req_resp");
+ xmpp_info->jingle_sessions = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "xmpp_jingle_sessions");
+ xmpp_info->ibb_sessions = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "xmpp_ibb_sessions");
+ xmpp_info->gtalk_sessions = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "xmpp_gtalk_sessions");
+ conversation_add_proto_data(conversation, proto_xmpp, (void *) xmpp_info);
+ }
+
+
+ if (pinfo->match_uint == pinfo->destport)
+ out_packet = TRUE;
+ else
+ out_packet = FALSE;
+
+ while(xml_frame)
+ {
+ packet = xml_frame_to_element_t(xml_frame, NULL, tvb);
+ DISSECTOR_ASSERT(packet);
+
+ if (strcmp(packet->name, "iq") == 0) {
+ xmpp_iq_reqresp_track(pinfo, packet, xmpp_info);
+ xmpp_jingle_session_track(pinfo, packet, xmpp_info);
+ xmpp_gtalk_session_track(pinfo, packet, xmpp_info);
+ }
+
+ if (strcmp(packet->name, "iq") == 0 || strcmp(packet->name, "message") == 0) {
+ xmpp_ibb_session_track(pinfo, packet, xmpp_info);
+ }
+
+ if (tree) { /* we are being asked for details */
+ proto_item *outin_item;
+
+ if (out_packet)
+ outin_item = proto_tree_add_boolean(xmpp_tree, hf_xmpp_out, tvb, 0, 0, ENC_LITTLE_ENDIAN);
+ else
+ outin_item = proto_tree_add_boolean(xmpp_tree, hf_xmpp_in, tvb, 0, 0, ENC_LITTLE_ENDIAN);
+
+ PROTO_ITEM_SET_HIDDEN(outin_item);
+
+
+ /*it hides tree generated by XML dissector*/
+ proto_tree_hide_first_child(xmpp_tree);
+
+ if (strcmp(packet->name, "iq") == 0) {
+ xmpp_iq(xmpp_tree, tvb, pinfo, packet);
+ } else if (strcmp(packet->name, "presence") == 0) {
+ xmpp_presence(xmpp_tree, tvb, pinfo, packet);
+ } else if (strcmp(packet->name, "message") == 0) {
+ xmpp_message(xmpp_tree, tvb, pinfo, packet);
+ } else if (strcmp(packet->name, "auth") == 0) {
+ xmpp_auth(xmpp_tree, tvb, pinfo, packet);
+ } else if (strcmp(packet->name, "challenge") == 0) {
+ xmpp_challenge_response_success(xmpp_tree, tvb, pinfo, packet, hf_xmpp_challenge, ett_xmpp_challenge, "CHALLENGE");
+ } else if (strcmp(packet->name, "response") == 0) {
+ xmpp_challenge_response_success(xmpp_tree, tvb, pinfo, packet, hf_xmpp_response, ett_xmpp_response, "RESPONSE");
+ } else if (strcmp(packet->name, "success") == 0) {
+ xmpp_challenge_response_success(xmpp_tree, tvb, pinfo, packet, hf_xmpp_success, ett_xmpp_success, "SUCCESS");
+ } else if (strcmp(packet->name, "failure") == 0) {
+ xmpp_failure(xmpp_tree, tvb, pinfo, packet);
+ } else if (strcmp(packet->name, "xml") == 0) {
+ xmpp_xml_header(xmpp_tree, tvb, pinfo, packet);
+ } else if (strcmp(packet->name, "stream") == 0) {
+ xmpp_stream(xmpp_tree, tvb, pinfo, packet);
+ } else if (strcmp(packet->name, "features") == 0) {
+ xmpp_features(xmpp_tree, tvb, pinfo, packet);
+ } else if (strcmp(packet->name, "starttls") == 0) {
+ xmpp_starttls(xmpp_tree, tvb, pinfo, packet);
+ }else if (strcmp(packet->name, "proceed") == 0) {
+ xmpp_proceed(xmpp_tree, tvb, pinfo, packet);
+ }else {
+ proto_tree_show_first_child(xmpp_tree);
+ expert_add_info_format(pinfo, xmpp_tree, PI_UNDECODED, PI_NOTE, "Unknown packet: %s", packet->name);
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "UNKNOWN PACKET ");
+ }
+
+ /*appends to COL_INFO information about src or dst*/
+ if (pinfo->match_uint == pinfo->destport) {
+ attr_t *to = get_attr(packet, "to");
+ if (to)
+ col_append_fstr(pinfo->cinfo, COL_INFO, "> %s ", to->value);
+ } else {
+ attr_t *from = get_attr(packet, "from");
+ if (from)
+ col_append_fstr(pinfo->cinfo, COL_INFO, "< %s ", from->value);
+ }
+ }
+
+ element_t_tree_free(packet);
+ xml_frame = xml_frame->next_sibling;
+ }
}
+
void
-proto_register_xmpp(void)
-{
- static hf_register_info hf[] = {
- { &hf_xmpp_response,
- { "Response", "xmpp.response",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "TRUE if XMPP response", HFILL }},
-
- { &hf_xmpp_request,
- { "Request", "xmpp.request",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "TRUE if XMPP request", HFILL }}
- };
- static gint *ett[] = {
- &ett_xmpp,
- &ett_xmpp_reqresp,
- };
-
- proto_xmpp = proto_register_protocol("Extensible Messaging and Presence Protocol",
- "XMPP", "xmpp");
- proto_register_field_array(proto_xmpp, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
+proto_register_xmpp(void) {
+ static hf_register_info hf[] = {
+ { &hf_xmpp_iq,
+ {
+ "IQ", "xmpp.iq", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq packet", HFILL
+ }},
+ {&hf_xmpp_xmlns,
+ {
+ "xmlns", "xmpp.xmlns", FT_STRING, BASE_NONE, NULL, 0x0,
+ "element namespace", HFILL
+ }},
+ { &hf_xmpp_id,
+ {
+ "id", "xmpp.id", FT_STRING, BASE_NONE, NULL, 0x0,
+ "packet id", HFILL
+ }},
+ { &hf_xmpp_type,
+ {
+ "type", "xmpp.type", FT_STRING, BASE_NONE, NULL, 0x0,
+ "packet type", HFILL
+ }},
+ { &hf_xmpp_from,
+ {
+ "from", "xmpp.from", FT_STRING, BASE_NONE, NULL, 0x0,
+ "packet from", HFILL
+ }},
+ { &hf_xmpp_to,
+ {
+ "to", "xmpp.to", FT_STRING, BASE_NONE, NULL, 0x0,
+ "packet to", HFILL
+ }},
+ { &hf_xmpp_query,
+ {
+ "QUERY", "xmpp.query", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq query", HFILL
+ }},
+ { &hf_xmpp_query_node,
+ {
+ "node", "xmpp.query.node", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query node", HFILL
+ }},
+ { &hf_xmpp_query_item,
+ {
+ "ITEM", "xmpp.query.item", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq query item", HFILL
+
+ }},
+ { &hf_xmpp_query_item_jid,
+ {
+ "jid", "xmpp.query.item.jid", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query item jid", HFILL
+
+ }},
+ { &hf_xmpp_query_item_name,
+ {
+ "name", "xmpp.query.item.name", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query item name", HFILL
+ }},
+ { &hf_xmpp_query_item_subscription,
+ {
+ "subscription", "xmpp.query.item.subscription", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query item subscription", HFILL
+ }},
+ { &hf_xmpp_query_item_ask,
+ {
+ "ask", "xmpp.query.item.ask", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query item ask", HFILL
+ }},
+ { &hf_xmpp_query_item_group,
+ {
+ "GROUP", "xmpp.query.item.group", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query item group", HFILL
+
+ }},
+ { &hf_xmpp_query_item_approved,
+ {
+ "approved", "xmpp.query.item.approved", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query item approved", HFILL
+
+ }},
+ { &hf_xmpp_query_item_node,
+ {
+ "node", "xmpp.query.item.node", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query item node", HFILL
+
+ }},
+ { &hf_xmpp_query_identity,
+ {
+ "IDENTITY", "xmpp.query.identity", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq query identity", HFILL
+
+ }},
+ { &hf_xmpp_query_identity_category,
+ {
+ "category", "xmpp.query.identity.category", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query identity category", HFILL
+
+ }},
+ { &hf_xmpp_query_identity_type,
+ {
+ "type", "xmpp.query.identity.type", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query identity type", HFILL
+
+ }},
+ { &hf_xmpp_query_identity_name,
+ {
+ "name", "xmpp.query.identity.name", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query identity name", HFILL
+
+ }},
+ { &hf_xmpp_query_identity_lang,
+ {
+ "lang", "xmpp.query.identity.lang", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query identity lang", HFILL
+
+ }},
+ { &hf_xmpp_query_feature,
+ {
+ "FEATURE", "xmpp.query.feature", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query feature", HFILL
+
+ }},
+ { &hf_xmpp_query_streamhost,
+ {
+ "STREAMHOST", "xmpp.query.streamhost", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq query streamhost", HFILL
+
+ }},
+ { &hf_xmpp_query_streamhost_used,
+ {
+ "STREAMHOST-USED", "xmpp.query.streamhost-used", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq query streamhost-used", HFILL
+
+ }},
+ { &hf_xmpp_query_activate,
+ {
+ "ACTIVATE", "xmpp.query.activate", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq query activate", HFILL
+
+ }},
+ { &hf_xmpp_query_udpsuccess,
+ {
+ "UDPSUCCESS", "xmpp.query.udpsuccess", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq query streamhost-used", HFILL
+
+ }},
+ { &hf_xmpp_error,
+ {
+ "ERROR", "xmpp.error", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq error", HFILL
+ }},
+ { &hf_xmpp_error_code,
+ {
+ "code", "xmpp.error.code", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq stanza error code", HFILL
+
+ }},
+ { &hf_xmpp_error_type,
+ {
+ "type", "xmpp.error.type", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq error type", HFILL
+
+ }},
+ { &hf_xmpp_error_condition,
+ {
+ "CONDITION", "xmpp.error.condition", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq error condition", HFILL
+
+ }},
+ { &hf_xmpp_error_text,
+ {
+ "TEXT", "xmpp.error.text", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq error text", HFILL
+
+ }},
+ { &hf_xmpp_iq_bind,
+ {
+ "BIND", "xmpp.iq.bind", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq bind", HFILL
+
+ }},
+ { &hf_xmpp_iq_bind_jid,
+ {
+ "jid", "xmpp.iq.bind.jid", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq bind jid", HFILL
+
+ }},
+ { &hf_xmpp_iq_bind_resource,
+ {
+ "resource", "xmpp.iq.bind.resource", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq bind resource", HFILL
+
+ }},
+ { &hf_xmpp_services,
+ {
+ "SERVICES", "xmpp.services", FT_NONE, BASE_NONE, NULL, 0x0,
+ "http://jabber.org/protocol/jinglenodes services", HFILL
+ }},
+ { &hf_xmpp_channel,
+ {
+ "CHANNEL", "xmpp.channel", FT_NONE, BASE_NONE, NULL, 0x0,
+ "http://jabber.org/protocol/jinglenodes#channel", HFILL
+ }},
+ { &hf_xmpp_iq_session,
+ {
+ "SESSION", "xmpp.iq.session", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq session", HFILL
+ }},
+ { &hf_xmpp_vcard,
+ {
+ "VCARD", "xmpp.vcard", FT_NONE, BASE_NONE, NULL, 0x0,
+ "vcard-temp", HFILL
+ }},
+ { &hf_xmpp_vcard_x_update,
+ {
+ "X VCARD-UPDATE", "xmpp.vcard-update", FT_NONE, BASE_NONE, NULL, 0x0,
+ "vcard-temp:x:update", HFILL
+ }},
+ { &hf_xmpp_jingle,
+ {
+ "JINGLE", "xmpp.jingle", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle", HFILL
+ }},
+ { &hf_xmpp_jingle_action,
+ {
+ "action", "xmpp.jingle.action", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle action", HFILL
+ }},
+ { &hf_xmpp_jingle_sid,
+ {
+ "sid", "xmpp.jingle.sid", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle sid", HFILL
+ }},
+ { &hf_xmpp_jingle_initiator,
+ {
+ "initiator", "xmpp.jingle.initiator", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle initiator", HFILL
+ }},
+ { &hf_xmpp_jingle_responder,
+ {
+ "responder", "xmpp.jingle.responder", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle responder", HFILL
+ }},
+ { &hf_xmpp_jingle_content,
+ {
+ "CONTENT", "xmpp.jingle.content", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content", HFILL
+ }},
+ { &hf_xmpp_jingle_content_creator,
+ {
+ "creator", "xmpp.jingle.content.creator", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content creator", HFILL
+ }},
+ { &hf_xmpp_jingle_content_name,
+ {
+ "name", "xmpp.jingle.content.name", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content name", HFILL
+ }},
+ { &hf_xmpp_jingle_content_disposition,
+ {
+ "disposition", "xmpp.jingle.content.disposition", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content disposition", HFILL
+ }},
+ { &hf_xmpp_jingle_content_senders,
+ {
+ "senders", "xmpp.jingle.content.senders", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content senders", HFILL
+ }},
+ { &hf_xmpp_jingle_content_description,
+ {
+ "DESCRIPTION", "xmpp.jingle.content.description", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content description", HFILL
+ }},
+ { &hf_xmpp_jingle_content_description_media,
+ {
+ "media", "xmpp.jingle.content.description.media", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description", HFILL
+ }},
+ { &hf_xmpp_jingle_content_description_ssrc,
+ {
+ "ssrc", "xmpp.jingle.content.description.ssrc", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description ssrc", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload,
+ {
+ "PAYLOAD-TYPE", "xmpp.jingle.content.description.payload-type", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_id,
+ {
+ "id", "xmpp.jingle.content.description.payload-type.id", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type id", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_channels,
+ {
+ "channels", "xmpp.jingle.content.description.payload-type.channels", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type channels", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_clockrate,
+ {
+ "clockrate", "xmpp.jingle.content.description.payload-type.clockrate", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type clockrate", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_maxptime,
+ {
+ "maxptime", "xmpp.jingle.content.description.payload-type.maxptime", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type maxptime", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_name,
+ {
+ "name", "xmpp.jingle.content.description.payload-type.name", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type name", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_ptime,
+ {
+ "ptime", "xmpp.jingle.content.description.payload-type.ptime", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type ptime", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_param,
+ {
+ "PARAMETER", "xmpp.jingle.content.description.payload-type.parameter", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type parameter", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_param_name,
+ {
+ "name", "xmpp.jingle.content.description.payload-type.parameter.name", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type parameter name", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_payload_param_value,
+ {
+ "value", "xmpp.jingle.content.description.payload-type.parameter.value", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content description payload-type parameter value", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans,
+ {
+ "TRANSPORT", "xmpp.jingle.content.transport", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content transport", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans_ufrag,
+ {
+ "ufrag", "xmpp.jingle.content.transport.ufrag", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content transport ufrag", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans_pwd,
+ {
+ "pwd", "xmpp.jingle.content.transport.pwd", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle content transport pwd", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans_cand,
+ {
+ "CANDIDATE", "xmpp.jingle.content.transport.candidate", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content transport candidate", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans_rem_cand,
+ {
+ "REMOTE-CANDIDATE", "xmpp.jingle.content.transport.remote-candidate", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content transport remote-candidate", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans_activated,
+ {
+ "ACTIVATED", "xmpp.jingle.content.transport.activated", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:transports:s5b:1 activated", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans_candidate_used,
+ {
+ "CANDIDATE-USED", "xmpp.jingle.content.transport.candidate-used", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:transports:s5b:1 candidate-used", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans_candidate_error,
+ {
+ "CANDIDATE-ERROR", "xmpp.jingle.content.transport.candidate-error", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:transports:s5b:1 candidate-error", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_trans_proxy_error,
+ {
+ "PROXY-ERROR", "xmpp.jingle.content.transport.proxy-error", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:transports:s5b:1 proxy-error", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_enc,
+ {
+ "ENCRYPTION", "xmpp.jingle.content.description.encryption", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content descryption encryption", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_enc_zrtp_hash,
+ {
+ "ZRTP-HASH", "xmpp.jingle.content.description.encryption.zrtp-hash", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content descryption encryption zrtp-hash", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_enc_crypto,
+ {
+ "CRYPTO", "xmpp.jingle.content.description.encryption.crypto", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content descryption encryption crypto", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_bandwidth,
+ {
+ "BANDWIDTH", "xmpp.jingle.content.description.bandwidth", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content descryption bandwidth", HFILL
+ }},
+ { &hf_xmpp_jingle_cont_desc_rtp_hdr,
+ {
+ "RTP-HDREXT", "xmpp.jingle.content.description.rtp-hdrext", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle content descryption rtp-hdrext", HFILL
+ }},
+ { &hf_xmpp_jingle_reason,
+ {
+ "REASON", "xmpp.jingle.reason", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq jingle reason", HFILL
+ }},
+ { &hf_xmpp_jingle_reason_condition,
+ {
+ "CONDITION", "xmpp.jingle.reason.condition", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle reason condition", HFILL
+ }},
+ { &hf_xmpp_jingle_reason_text,
+ {
+ "TEXT", "xmpp.jingle.reason.text", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle reason text", HFILL
+ }},
+ { &hf_xmpp_jingle_rtp_info,
+ {
+ "RTP-INFO", "xmpp.jingle.rtp_info", FT_STRING, BASE_NONE, NULL, 0x0,
+ "iq jingle rtp-info(ringing, active, hold, mute, ...)", HFILL
+ }},
+ { &hf_xmpp_jingle_file_transfer_offer,
+ {
+ "OFFER", "xmpp.jingle.content.description.offer", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:apps:file-transfer:3 offer", HFILL
+ }},
+ { &hf_xmpp_jingle_file_transfer_request,
+ {
+ "REQUEST", "xmpp.jingle.content.description.request", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:apps:file-transfer:3 request", HFILL
+ }},
+ { &hf_xmpp_jingle_file_transfer_received,
+ {
+ "RECEIVED", "xmpp.jingle.content.received", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:apps:file-transfer:3 received", HFILL
+ }},
+ { &hf_xmpp_jingle_file_transfer_abort,
+ {
+ "ABORT", "xmpp.jingle.content.abort", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:apps:file-transfer:3 abort", HFILL
+ }},
+ { &hf_xmpp_jingle_file_transfer_checksum,
+ {
+ "CHECKSUM", "xmpp.jingle.content.checksum", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:jingle:apps:file-transfer:3 checksum", HFILL
+ }},
+ { &hf_xmpp_si,
+ {
+ "SI", "xmpp.si", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq si", HFILL
+ }},
+ { &hf_xmpp_si_file,
+ {
+ "FILE", "xmpp.si.file", FT_NONE, BASE_NONE, NULL, 0x0,
+ "iq si file", HFILL
+ }},
+ { &hf_xmpp_iq_feature_neg,
+ {
+ "FEATURE", "xmpp.feature-neg", FT_NONE, BASE_NONE, NULL, 0x0,
+ "http://jabber.org/protocol/feature-neg", HFILL
+ }},
+ { &hf_xmpp_x_data,
+ {
+ "X-DATA", "xmpp.x-data", FT_NONE, BASE_NONE, NULL, 0x0,
+ "jabber:x:data", HFILL
+ }},
+ { &hf_xmpp_x_data_field,
+ {
+ "FIELD", "xmpp.x-data.field", FT_NONE, BASE_NONE, NULL, 0x0,
+ "jabber:x:data field", HFILL
+ }},
+ { &hf_xmpp_x_data_field_value,
+ {
+ "VALUE", "xmpp.x-data.field.value", FT_NONE, BASE_NONE, NULL, 0x0,
+ "jabber:x:data field value", HFILL
+ }},
+ { &hf_xmpp_delay,
+ {
+ "DELAY", "xmpp.delay", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:delay", HFILL
+ }},
+ { &hf_xmpp_x_event,
+ {
+ "X EVENT", "xmpp.x-event", FT_NONE, BASE_NONE, NULL, 0x0,
+ "jabber:x:event", HFILL
+ }},
+ { &hf_xmpp_x_event_condition,
+ {
+ "CONDITION", "xmpp.x-event.condition", FT_STRING, BASE_NONE, NULL, 0x0,
+ "jabber:x:event condition", HFILL
+ }},
+ { &hf_xmpp_presence,
+ {
+ "PRESENCE", "xmpp.presence", FT_NONE, BASE_NONE, NULL, 0x0,
+ "presence packet", HFILL
+ }},
+ { &hf_xmpp_presence_show,
+ {
+ "SHOW", "xmpp.presence.show", FT_STRING, BASE_NONE, NULL, 0x0,
+ "presence show", HFILL
+ }},
+ { &hf_xmpp_presence_status,
+ {
+ "STATUS", "xmpp.presence.status", FT_NONE, BASE_NONE, NULL, 0x0,
+ "presence status", HFILL
+ }},
+ { &hf_xmpp_presence_caps,
+ {
+ "CAPS", "xmpp.presence.caps", FT_NONE, BASE_NONE, NULL, 0x0,
+ "presence caps", HFILL
+ }},
+ { &hf_xmpp_message,
+ {
+ "MESSAGE", "xmpp.message", FT_NONE, BASE_NONE, NULL, 0x0,
+ "message packet", HFILL
+ }},
+ { &hf_xmpp_message_chatstate,
+ {
+ "CHATSTATE", "xmpp.message.chatstate", FT_STRING, BASE_NONE, NULL, 0x0,
+ "message chatstate", HFILL
+ }},
+ { &hf_xmpp_message_thread,
+ {
+ "THREAD", "xmpp.message.thread", FT_NONE, BASE_NONE, NULL, 0x0,
+ "message thread", HFILL
+ }},
+ { &hf_xmpp_message_body,
+ {
+ "BODY", "xmpp.message.body", FT_NONE, BASE_NONE, NULL, 0x0,
+ "message body", HFILL
+ }},
+ { &hf_xmpp_message_subject,
+ {
+ "SUBJECT", "xmpp.message.subject", FT_NONE, BASE_NONE, NULL, 0x0,
+ "message subject", HFILL
+ }},
+ { &hf_xmpp_message_thread_parent,
+ {
+ "parent", "xmpp.message.thread.parent", FT_STRING, BASE_NONE, NULL, 0x0,
+ "message thread parent", HFILL
+ }},
+ { &hf_xmpp_auth,
+ {
+ "AUTH", "xmpp.auth", FT_NONE, BASE_NONE, NULL, 0x0,
+ "auth packet", HFILL
+ }},
+ { &hf_xmpp_stream,
+ {
+ "STREAM", "xmpp.stream", FT_NONE, BASE_NONE, NULL, 0x0,
+ "XMPP stream", HFILL
+ }},
+ { &hf_xmpp_challenge,
+ {
+ "CHALLENGE", "xmpp.challenge", FT_NONE, BASE_NONE, NULL, 0x0,
+ "challenge packet", HFILL
+ }},
+ { &hf_xmpp_response,
+ {
+ "RESPONSE", "xmpp.response", FT_NONE, BASE_NONE, NULL, 0x0,
+ "response packet", HFILL
+ }},
+ { &hf_xmpp_success,
+ {
+ "SUCCESS", "xmpp.success", FT_NONE, BASE_NONE, NULL, 0x0,
+ "success packet", HFILL
+ }},
+ { &hf_xmpp_failure,
+ {
+ "FAILURE", "xmpp.failure", FT_NONE, BASE_NONE, NULL, 0x0,
+ "failure packet", HFILL
+ }},
+ { &hf_xmpp_features,
+ {
+ "FEATURES", "xmpp.features", FT_NONE, BASE_NONE, NULL, 0x0,
+ "stream features", HFILL
+ }},
+ { &hf_xmpp_starttls,
+ {
+ "STARTTLS", "xmpp.starttls", FT_NONE, BASE_NONE, NULL, 0x0,
+ "starttls packet", HFILL
+ }},
+ { &hf_xmpp_proceed,
+ {
+ "PROCEED", "xmpp.proceed", FT_NONE, BASE_NONE, NULL, 0x0,
+ "proceed packet", HFILL
+ }},
+ { &hf_xmpp_unknown,
+ {
+ "UNKNOWN", "xmpp.unknown", FT_STRING, BASE_NONE, NULL, 0x0,
+ "unknown element", HFILL
+ }},
+ { &hf_xmpp_unknown_attr,
+ {
+ "UNKNOWN ATTR", "xmpp.unknown_attr", FT_STRING, BASE_NONE, NULL, 0x0,
+ "unknown attribute", HFILL
+ }},
+ { &hf_xmpp_ibb_open,
+ {
+ "IBB-OPEN", "xmpp.ibb.open", FT_NONE, BASE_NONE, NULL, 0x0,
+ "xmpp ibb open", HFILL
+ }},
+ { &hf_xmpp_ibb_close,
+ {
+ "IBB-CLOSE", "xmpp.ibb.close", FT_NONE, BASE_NONE, NULL, 0x0,
+ "xmpp ibb close", HFILL
+ }},
+ { &hf_xmpp_ibb_data,
+ {
+ "IBB-DATA", "xmpp.ibb.data", FT_NONE, BASE_NONE, NULL, 0x0,
+ "xmpp ibb data", HFILL
+ }},
+ { &hf_xmpp_muc_x,
+ {
+ "X MUC", "xmpp.muc-x", FT_NONE, BASE_NONE, NULL, 0x0,
+ "http://jabber.org/protocol/muc", HFILL
+ }},
+ { &hf_xmpp_muc_user_x,
+ {
+ "X MUC-USER", "xmpp.muc-user-x", FT_NONE, BASE_NONE, NULL, 0x0,
+ "http://jabber.org/protocol/muc#user", HFILL
+ }},
+ { &hf_xmpp_muc_user_item,
+ {
+ "ITEM", "xmpp.muc-user-x.item", FT_NONE, BASE_NONE, NULL, 0x0,
+ "muc#user item", HFILL
+ }},
+ { &hf_xmpp_muc_user_invite,
+ {
+ "INVITE", "xmpp.muc-user-x.invite", FT_NONE, BASE_NONE, NULL, 0x0,
+ "muc#user invite", HFILL
+ }},
+ { &hf_xmpp_gtalk_session,
+ {
+ "GTALK-SESSION", "xmpp.gtalk.session", FT_NONE, BASE_NONE, NULL, 0x0,
+ "GTalk session", HFILL
+ }},
+ { &hf_xmpp_gtalk_session_type,
+ {
+ "type", "xmpp.gtalk.session.type", FT_STRING, BASE_NONE, NULL, 0x0,
+ "GTalk session type", HFILL
+ }},
+ { &hf_xmpp_gtalk,
+ {
+ "GTALK SESSION", "xmpp.gtalk", FT_STRING, BASE_NONE, NULL, 0x0,
+ "GTalk SID", HFILL
+ }},
+ { &hf_xmpp_gtalk_setting,
+ {
+ "USERSETTING", "xmpp.gtalk.setting", FT_NONE, BASE_NONE, NULL, 0x0,
+ "google:setting usersetting", HFILL
+ }},
+ { &hf_xmpp_gtalk_nosave_x,
+ {
+ "X-NOSAVE", "xmpp.gtalk.nosave.x", FT_NONE, BASE_NONE, NULL, 0x0,
+ "google:nosave x", HFILL
+ }},
+ { &hf_xmpp_gtalk_mail_mailbox,
+ {
+ "MAILBOX", "xmpp.gtalk.mailbox", FT_NONE, BASE_NONE, NULL, 0x0,
+ "google:mail:notify mailbox", HFILL
+ }},
+ { &hf_xmpp_gtalk_mail_new_mail,
+ {
+ "NEW MAIL", "xmpp.gtalk.new-mail", FT_NONE, BASE_NONE, NULL, 0x0,
+ "google:mail:notify new-mail", HFILL
+ }},
+ { &hf_xmpp_gtalk_transport_p2p,
+ {
+ "TRANSPORT", "xmpp.gtalk.transport-p2p", FT_NONE, BASE_NONE, NULL, 0x0,
+ "google/transport/p2p", HFILL
+ }},
+ { &hf_xmpp_conf_info,
+ {
+ "CONFERENCE INFO", "xmpp.conf-info", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:ietf:params:xml:ns:conference-info", HFILL
+ }},
+ { &hf_xmpp_conf_info_sid,
+ {
+ "sid", "xmpp.conf-info.sid", FT_STRING, BASE_NONE, NULL, 0x0,
+ "urn:ietf:params:xml:ns:conference-info sid", HFILL
+ }},
+ { &hf_xmpp_response_in,
+ { "Response In", "xmpp.response_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "The response to this request is in this frame", HFILL }
+ },
+ { &hf_xmpp_response_to,
+ { "Request In", "xmpp.response_to",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "This is a response to the request in this frame", HFILL }
+ },
+ { &hf_xmpp_out,
+ {
+ "Out", "xmpp.out", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Outgoing packet", HFILL
+ }},
+ { &hf_xmpp_in,
+ {
+ "In", "xmpp.in", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Ingoing packet", HFILL
+ }},
+ { &hf_xmpp_ibb,
+ {
+ "IBB SESSION", "xmpp.ibb", FT_STRING, BASE_NONE, NULL, 0x0,
+ "In-Band Bytestreams session", HFILL
+ }},
+ { &hf_xmpp_jingle_session,
+ {
+ "JINGLE SESSION", "xmpp.jingle_session", FT_STRING, BASE_NONE, NULL, 0x0,
+ "Jingle SID", HFILL
+ }},
+ { &hf_xmpp_ping,
+ {
+ "PING", "xmpp.ping", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:ping", HFILL
+ }},
+ { &hf_xmpp_hashes,
+ {
+ "HASHES", "xmpp.hashes", FT_NONE, BASE_NONE, NULL, 0x0,
+ "urn:xmpp:hashes:0", HFILL
+ }},
+ { &hf_xmpp_jitsi_inputevt,
+ {
+ "INPUTEVT", "xmpp.inputevt", FT_NONE, BASE_NONE, NULL, 0x0,
+ "http://jitsi.org/protocol/inputevt", HFILL
+ }},
+ { &hf_xmpp_jitsi_inputevt_rmt_ctrl,
+ {
+ "REMOTE-CONTROL", "xmpp.inputevt.remote-control", FT_NONE, BASE_NONE, NULL, 0x0,
+ "http://jitsi.org/protocol/inputevt remote-control", HFILL
+ }},
+ };
+
+ static gint * ett[] = {
+ &ett_xmpp,
+ &ett_xmpp_iq,
+ &ett_xmpp_query,
+ &ett_xmpp_query_item,
+ &ett_xmpp_query_identity,
+ &ett_xmpp_query_feature,
+ &ett_xmpp_query_streamhost,
+ &ett_xmpp_query_streamhost_used,
+ &ett_xmpp_query_udpsuccess,
+ &ett_xmpp_iq_error,
+ &ett_xmpp_iq_bind,
+ &ett_xmpp_iq_session,
+ &ett_xmpp_vcard,
+ &ett_xmpp_vcard_x_update,
+ &ett_xmpp_jingle,
+ &ett_xmpp_jingle_content,
+ &ett_xmpp_jingle_content_description,
+ &ett_xmpp_jingle_cont_desc_payload,
+ &ett_xmpp_jingle_cont_desc_payload_param,
+ &ett_xmpp_jingle_cont_desc_enc,
+ &ett_xmpp_jingle_cont_desc_enc_zrtp_hash,
+ &ett_xmpp_jingle_cont_desc_enc_crypto,
+ &ett_xmpp_jingle_cont_desc_bandwidth,
+ &ett_xmpp_jingle_cont_desc_rtp_hdr,
+ &ett_xmpp_jingle_cont_trans,
+ &ett_xmpp_jingle_cont_trans_cand,
+ &ett_xmpp_jingle_cont_trans_rem_cand,
+ &ett_xmpp_jingle_reason,
+ &ett_xmpp_jingle_rtp_info,
+ &ett_xmpp_services,
+ &ett_xmpp_services_relay,
+ &ett_xmpp_channel,
+ &ett_xmpp_si,
+ &ett_xmpp_si_file,
+ &ett_xmpp_si_file_range,
+ &ett_xmpp_iq_feature_neg,
+ &ett_xmpp_x_data,
+ &ett_xmpp_x_data_field,
+ &ett_xmpp_x_data_field_value,
+ &ett_xmpp_ibb_open,
+ &ett_xmpp_ibb_close,
+ &ett_xmpp_ibb_data,
+ &ett_xmpp_delay,
+ &ett_xmpp_x_event,
+ &ett_xmpp_message,
+ &ett_xmpp_message_thread,
+ &ett_xmpp_message_subject,
+ &ett_xmpp_message_body,
+ &ett_xmpp_presence,
+ &ett_xmpp_presence_status,
+ &ett_xmpp_presence_caps,
+ &ett_xmpp_auth,
+ &ett_xmpp_challenge,
+ &ett_xmpp_response,
+ &ett_xmpp_success,
+ &ett_xmpp_failure,
+ &ett_xmpp_muc_x,
+ &ett_xmpp_muc_hist,
+ &ett_xmpp_muc_user_x,
+ &ett_xmpp_muc_user_item,
+ &ett_xmpp_muc_user_invite,
+ &ett_xmpp_gtalk_session,
+ &ett_xmpp_gtalk_session_desc,
+ &ett_xmpp_gtalk_session_desc_payload,
+ &ett_xmpp_gtalk_session_cand,
+ &ett_xmpp_gtalk_session_reason,
+ &ett_xmpp_gtalk_jingleinfo_stun,
+ &ett_xmpp_gtalk_jingleinfo_server,
+ &ett_xmpp_gtalk_jingleinfo_relay,
+ &ett_xmpp_gtalk_jingleinfo_relay_serv,
+ &ett_xmpp_gtalk_setting,
+ &ett_xmpp_gtalk_nosave_x,
+ &ett_xmpp_gtalk_mail_mailbox,
+ &ett_xmpp_gtalk_mail_mail_info,
+ &ett_xmpp_gtalk_mail_senders,
+ &ett_xmpp_gtalk_mail_sender,
+ &ett_xmpp_gtalk_status_status_list,
+ &ett_xmpp_conf_info,
+ &ett_xmpp_conf_desc,
+ &ett_xmpp_conf_state,
+ &ett_xmpp_conf_users,
+ &ett_xmpp_conf_user,
+ &ett_xmpp_conf_endpoint,
+ &ett_xmpp_conf_media,
+ &ett_xmpp_gtalk_transport_p2p,
+ &ett_xmpp_gtalk_transport_p2p_cand,
+ &ett_xmpp_ping,
+ &ett_xmpp_hashes_hash,
+ &ett_xmpp_hashes,
+ &ett_xmpp_jingle_file_transfer_offer,
+ &ett_xmpp_jingle_file_transfer_request,
+ &ett_xmpp_jingle_file_transfer_received,
+ &ett_xmpp_jingle_file_transfer_abort,
+ &ett_xmpp_jingle_file_transfer_checksum,
+ &ett_xmpp_jingle_file_transfer_file,
+ &ett_xmpp_jitsi_inputevt,
+ &ett_xmpp_jitsi_inputevt_rmt_ctrl,
+ &ett_xmpp_stream,
+ &ett_xmpp_features,
+ &ett_xmpp_features_mechanisms,
+ &ett_xmpp_starttls,
+ &ett_xmpp_proceed,
+ };
+
+ module_t *xmpp_module;
+
+ static gint* ett_unknown_ptr[ETT_UNKNOWN_LEN];
+ gint i;
+ for(i=0;i<ETT_UNKNOWN_LEN;i++)
+ {
+ ett_unknown[i] = -1;
+ ett_unknown_ptr[i] = &ett_unknown[i];
+ }
+
+
+
+ proto_xmpp = proto_register_protocol(
+ "XMPP Protocol", /* name */
+ "XMPP", /* short name */
+ "xmpp" /* abbrev */
+ );
+
+ xmpp_module = prefs_register_protocol(proto_xmpp, NULL);
+ prefs_register_bool_preference(xmpp_module, "desegment",
+ "Reasemble XMPP messages",
+ "Whether the XMPP dissector should reassemble messages. "
+ "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings",
+ &xmpp_desegment);
+
+ proto_register_field_array(proto_xmpp, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ proto_register_subtree_array(ett_unknown_ptr, array_length(ett_unknown_ptr));
+
+ register_dissector("xmpp", dissect_xmpp, proto_xmpp);
}
void
-proto_reg_handoff_xmpp(void)
-{
- dissector_handle_t xmpp_handle;
+proto_reg_handoff_xmpp(void) {
+ static dissector_handle_t xmpp_handle;
+
+ xml_handle = find_dissector("xml");
+
+ /*xmpp_handle = create_dissector_handle(dissect_xmpp, proto_xmpp);*/
+ xmpp_handle = find_dissector("xmpp");
- xml_handle = find_dissector("xml");
+ dissector_add_uint("tcp.port", XMPP_PORT, xmpp_handle);
- xmpp_handle = create_dissector_handle(dissect_xmpp, proto_xmpp);
- dissector_add_uint("tcp.port", TCP_PORT_XMPP, xmpp_handle);
}
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-xmpp.h b/epan/dissectors/packet-xmpp.h
new file mode 100644
index 0000000000..d9350523e0
--- /dev/null
+++ b/epan/dissectors/packet-xmpp.h
@@ -0,0 +1,344 @@
+/* packet-xmpp.h
+ *
+ * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PACKET_XMPP_H
+#define PACKET_XMPP_H
+
+#define ETT_UNKNOWN_LEN 20
+
+/*#define XMPP_DEBUG*/
+
+extern int proto_xmpp;
+
+extern gint hf_xmpp_xmlns;
+extern gint hf_xmpp_id;
+extern gint hf_xmpp_from;
+extern gint hf_xmpp_to;
+extern gint hf_xmpp_type;
+
+extern gint hf_xmpp_iq;
+
+
+extern gint hf_xmpp_query;
+extern gint hf_xmpp_query_node;
+
+extern gint hf_xmpp_query_item;
+extern gint hf_xmpp_query_item_jid;
+extern gint hf_xmpp_query_item_name;
+extern gint hf_xmpp_query_item_subscription;
+extern gint hf_xmpp_query_item_ask;
+extern gint hf_xmpp_query_item_group;
+extern gint hf_xmpp_query_item_node;
+extern gint hf_xmpp_query_item_approved;
+
+extern gint hf_xmpp_query_identity;
+extern gint hf_xmpp_query_identity_category;
+extern gint hf_xmpp_query_identity_type;
+extern gint hf_xmpp_query_identity_name;
+extern gint hf_xmpp_query_identity_lang;
+
+extern gint hf_xmpp_query_feature;
+
+extern gint hf_xmpp_query_streamhost;
+extern gint hf_xmpp_query_streamhost_used;
+extern gint hf_xmpp_query_activate;
+extern gint hf_xmpp_query_udpsuccess;
+
+extern gint hf_xmpp_error;
+extern gint hf_xmpp_error_type;
+extern gint hf_xmpp_error_code;
+extern gint hf_xmpp_error_condition;
+extern gint hf_xmpp_error_text;
+
+extern gint hf_xmpp_iq_bind;
+extern gint hf_xmpp_iq_bind_jid;
+extern gint hf_xmpp_iq_bind_resource;
+
+extern gint hf_xmpp_services;
+extern gint hf_xmpp_channel;
+
+extern gint hf_xmpp_iq_session;
+extern gint hf_xmpp_features;
+
+extern gint hf_xmpp_vcard;
+extern gint hf_xmpp_vcard_x_update;
+
+
+extern gint hf_xmpp_jingle;
+extern gint hf_xmpp_jingle_sid;
+extern gint hf_xmpp_jingle_initiator;
+extern gint hf_xmpp_jingle_responder;
+extern gint hf_xmpp_jingle_action;
+
+extern gint hf_xmpp_jingle_content;
+extern gint hf_xmpp_jingle_content_creator;
+extern gint hf_xmpp_jingle_content_name;
+extern gint hf_xmpp_jingle_content_disposition;
+extern gint hf_xmpp_jingle_content_senders;
+
+extern gint hf_xmpp_jingle_content_description;
+extern gint hf_xmpp_jingle_content_description_media;
+extern gint hf_xmpp_jingle_content_description_ssrc;
+
+extern gint hf_xmpp_jingle_cont_desc_payload;
+extern gint hf_xmpp_jingle_cont_desc_payload_id;
+extern gint hf_xmpp_jingle_cont_desc_payload_channels;
+extern gint hf_xmpp_jingle_cont_desc_payload_clockrate;
+extern gint hf_xmpp_jingle_cont_desc_payload_maxptime;
+extern gint hf_xmpp_jingle_cont_desc_payload_name;
+extern gint hf_xmpp_jingle_cont_desc_payload_ptime;
+
+extern gint hf_xmpp_jingle_cont_desc_payload_param;
+extern gint hf_xmpp_jingle_cont_desc_payload_param_value;
+extern gint hf_xmpp_jingle_cont_desc_payload_param_name;
+
+extern gint hf_xmpp_jingle_cont_desc_enc;
+extern gint hf_xmpp_jingle_cont_desc_enc_zrtp_hash;
+extern gint hf_xmpp_jingle_cont_desc_enc_crypto;
+
+extern gint hf_xmpp_jingle_cont_desc_rtp_hdr;
+extern gint hf_xmpp_jingle_cont_desc_bandwidth;
+
+extern gint hf_xmpp_jingle_cont_trans;
+extern gint hf_xmpp_jingle_cont_trans_pwd;
+extern gint hf_xmpp_jingle_cont_trans_ufrag;
+
+extern gint hf_xmpp_jingle_cont_trans_cand;
+extern gint hf_xmpp_jingle_cont_trans_rem_cand;
+
+extern gint hf_xmpp_jingle_cont_trans_activated;
+extern gint hf_xmpp_jingle_cont_trans_candidate_used;
+extern gint hf_xmpp_jingle_cont_trans_candidate_error;
+extern gint hf_xmpp_jingle_cont_trans_proxy_error;
+
+extern gint hf_xmpp_jingle_reason;
+extern gint hf_xmpp_jingle_reason_condition;
+extern gint hf_xmpp_jingle_reason_text;
+
+extern gint hf_xmpp_jingle_rtp_info;
+
+extern gint hf_xmpp_jingle_file_transfer_offer;
+extern gint hf_xmpp_jingle_file_transfer_request;
+extern gint hf_xmpp_jingle_file_transfer_received;
+extern gint hf_xmpp_jingle_file_transfer_abort;
+extern gint hf_xmpp_jingle_file_transfer_checksum;
+
+extern gint hf_xmpp_si;
+extern gint hf_xmpp_si_file;
+
+extern gint hf_xmpp_iq_feature_neg;
+extern gint hf_xmpp_x_data;
+extern gint hf_xmpp_x_data_field;
+extern gint hf_xmpp_x_data_field_value;
+
+extern gint hf_xmpp_message;
+extern gint hf_xmpp_message_chatstate;
+
+extern gint hf_xmpp_message_thread;
+extern gint hf_xmpp_message_thread_parent;
+
+extern gint hf_xmpp_message_body;
+extern gint hf_xmpp_message_subject;
+
+extern gint hf_xmpp_ibb_open;
+extern gint hf_xmpp_ibb_close;
+extern gint hf_xmpp_ibb_data;
+
+extern gint hf_xmpp_delay;
+
+extern gint hf_xmpp_x_event;
+extern gint hf_xmpp_x_event_condition;
+
+extern gint hf_xmpp_presence;
+extern gint hf_xmpp_presence_show;
+extern gint hf_xmpp_presence_status;
+extern gint hf_xmpp_presence_caps;
+
+extern gint hf_xmpp_auth;
+extern gint hf_xmpp_challenge;
+extern gint hf_xmpp_response;
+extern gint hf_xmpp_success;
+extern gint hf_xmpp_failure;
+extern gint hf_xmpp_stream;
+extern gint hf_xmpp_starttls;
+extern gint hf_xmpp_proceed;
+
+extern gint hf_xmpp_muc_x;
+extern gint hf_xmpp_muc_user_x;
+extern gint hf_xmpp_muc_user_item;
+extern gint hf_xmpp_muc_user_invite;
+
+extern gint hf_xmpp_gtalk_session;
+extern gint hf_xmpp_gtalk_session_type;
+extern gint hf_xmpp_gtalk;
+extern gint hf_xmpp_gtalk_setting;
+extern gint hf_xmpp_gtalk_nosave_x;
+extern gint hf_xmpp_gtalk_mail_mailbox;
+extern gint hf_xmpp_gtalk_mail_new_mail;
+extern gint hf_xmpp_gtalk_transport_p2p;
+
+extern gint hf_xmpp_conf_info;
+extern gint hf_xmpp_conf_info_sid;
+
+extern gint hf_xmpp_unknown;
+extern gint hf_xmpp_unknown_attr;
+
+extern gint hf_xmpp_out;
+extern gint hf_xmpp_in;
+extern gint hf_xmpp_response_in;
+extern gint hf_xmpp_response_to;
+extern gint hf_xmpp_jingle_session;
+extern gint hf_xmpp_ibb;
+
+extern gint hf_xmpp_ping;
+extern gint hf_xmpp_hashes;
+
+extern gint hf_xmpp_jitsi_inputevt;
+extern gint hf_xmpp_jitsi_inputevt_rmt_ctrl;
+
+extern gint ett_xmpp;
+extern gint ett_xmpp_iq;
+extern gint ett_xmpp_query;
+extern gint ett_xmpp_query_item;
+extern gint ett_xmpp_query_identity;
+extern gint ett_xmpp_query_feature;
+
+extern gint ett_xmpp_query_streamhost;
+extern gint ett_xmpp_query_streamhost_used;
+extern gint ett_xmpp_query_udpsuccess;
+
+extern gint ett_xmpp_iq_error;
+extern gint ett_xmpp_iq_bind;
+extern gint ett_xmpp_iq_session;
+extern gint ett_xmpp_vcard;
+extern gint ett_xmpp_vcard_x_update;
+
+extern gint ett_xmpp_jingle;
+extern gint ett_xmpp_jingle_content;
+extern gint ett_xmpp_jingle_content_description;
+extern gint ett_xmpp_jingle_cont_desc_enc;
+extern gint ett_xmpp_jingle_cont_desc_enc_zrtp_hash;
+extern gint ett_xmpp_jingle_cont_desc_enc_crypto;
+extern gint ett_xmpp_jingle_cont_desc_rtp_hdr;
+extern gint ett_xmpp_jingle_cont_desc_bandwidth;
+extern gint ett_xmpp_jingle_cont_desc_payload;
+extern gint ett_xmpp_jingle_cont_desc_payload_param;
+extern gint ett_xmpp_jingle_cont_trans;
+extern gint ett_xmpp_jingle_cont_trans_cand;
+extern gint ett_xmpp_jingle_cont_trans_rem_cand;
+extern gint ett_xmpp_jingle_reason;
+extern gint ett_xmpp_jingle_rtp_info;
+extern gint ett_xmpp_jingle_file_transfer_offer;
+extern gint ett_xmpp_jingle_file_transfer_request;
+extern gint ett_xmpp_jingle_file_transfer_received;
+extern gint ett_xmpp_jingle_file_transfer_abort;
+extern gint ett_xmpp_jingle_file_transfer_checksum;
+extern gint ett_xmpp_jingle_file_transfer_file;
+
+extern gint ett_xmpp_services;
+extern gint ett_xmpp_services_relay;
+extern gint ett_xmpp_channel;
+
+extern gint ett_xmpp_si;
+extern gint ett_xmpp_si_file;
+extern gint ett_xmpp_si_file_range;
+
+extern gint ett_xmpp_iq_feature_neg;
+extern gint ett_xmpp_x_data;
+extern gint ett_xmpp_x_data_field;
+extern gint ett_xmpp_x_data_field_value;
+
+extern gint ett_xmpp_ibb_open;
+extern gint ett_xmpp_ibb_close;
+extern gint ett_xmpp_ibb_data;
+
+extern gint ett_xmpp_delay;
+
+extern gint ett_xmpp_x_event;
+
+extern gint ett_xmpp_message;
+extern gint ett_xmpp_message_thread;
+extern gint ett_xmpp_message_body;
+extern gint ett_xmpp_message_subject;
+
+extern gint ett_xmpp_presence;
+extern gint ett_xmpp_presence_status;
+extern gint ett_xmpp_presence_caps;
+
+extern gint ett_xmpp_auth;
+extern gint ett_xmpp_challenge;
+extern gint ett_xmpp_response;
+extern gint ett_xmpp_success;
+extern gint ett_xmpp_failure;
+extern gint ett_xmpp_stream;
+extern gint ett_xmpp_features;
+extern gint ett_xmpp_features_mechanisms;
+extern gint ett_xmpp_proceed;
+extern gint ett_xmpp_starttls;
+
+extern gint ett_xmpp_muc_x;
+extern gint ett_xmpp_muc_hist;
+extern gint ett_xmpp_muc_user_x;
+extern gint ett_xmpp_muc_user_item;
+extern gint ett_xmpp_muc_user_invite;
+
+extern gint ett_xmpp_gtalk_session;
+extern gint ett_xmpp_gtalk_session_desc;
+extern gint ett_xmpp_gtalk_session_desc_payload;
+extern gint ett_xmpp_gtalk_session_cand;
+extern gint ett_xmpp_gtalk_session_reason;
+extern gint ett_xmpp_gtalk_jingleinfo_stun;
+extern gint ett_xmpp_gtalk_jingleinfo_server;
+extern gint ett_xmpp_gtalk_jingleinfo_relay;
+extern gint ett_xmpp_gtalk_jingleinfo_relay_serv;
+extern gint ett_xmpp_gtalk_setting;
+extern gint ett_xmpp_gtalk_nosave_x;
+extern gint ett_xmpp_gtalk_mail_mailbox;
+extern gint ett_xmpp_gtalk_mail_mail_info;
+extern gint ett_xmpp_gtalk_mail_senders;
+extern gint ett_xmpp_gtalk_mail_sender;
+extern gint ett_xmpp_gtalk_status_status_list;
+extern gint ett_xmpp_gtalk_transport_p2p;
+extern gint ett_xmpp_gtalk_transport_p2p_cand;
+
+
+extern gint ett_xmpp_conf_info;
+extern gint ett_xmpp_conf_desc;
+extern gint ett_xmpp_conf_state;
+extern gint ett_xmpp_conf_users;
+extern gint ett_xmpp_conf_user;
+extern gint ett_xmpp_conf_endpoint;
+extern gint ett_xmpp_conf_media;
+
+extern gint ett_xmpp_ping;
+extern gint ett_xmpp_hashes;
+extern gint ett_xmpp_hashes_hash;
+
+extern gint ett_xmpp_jitsi_inputevt;
+extern gint ett_xmpp_jitsi_inputevt_rmt_ctrl;
+
+extern gint ett_unknown[ETT_UNKNOWN_LEN];
+#endif /* PACKET_XMPP_H */
+