From Mariusz Okrój and Sebastien Vincent via https://bugs.wireshark.org/bugzilla...
authoralagoutte <alagoutte@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 12 Nov 2011 10:51:01 +0000 (10:51 +0000)
committeralagoutte <alagoutte@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 12 Nov 2011 10:51:01 +0000 (10:51 +0000)
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

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@39799 f5534014-38df-0310-8fa8-9805f1628bb7

17 files changed:
AUTHORS
epan/CMakeLists.txt
epan/dissectors/Makefile.common
epan/dissectors/packet-xmpp-conference.c [new file with mode: 0644]
epan/dissectors/packet-xmpp-conference.h [new file with mode: 0644]
epan/dissectors/packet-xmpp-core.c [new file with mode: 0644]
epan/dissectors/packet-xmpp-core.h [new file with mode: 0644]
epan/dissectors/packet-xmpp-gtalk.c [new file with mode: 0644]
epan/dissectors/packet-xmpp-gtalk.h [new file with mode: 0644]
epan/dissectors/packet-xmpp-jingle.c [new file with mode: 0644]
epan/dissectors/packet-xmpp-jingle.h [new file with mode: 0644]
epan/dissectors/packet-xmpp-other.c [new file with mode: 0644]
epan/dissectors/packet-xmpp-other.h [new file with mode: 0644]
epan/dissectors/packet-xmpp-utils.c [new file with mode: 0644]
epan/dissectors/packet-xmpp-utils.h [new file with mode: 0644]
epan/dissectors/packet-xmpp.c
epan/dissectors/packet-xmpp.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index c76dc9d..8c5872d 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -3343,7 +3343,9 @@ Martin Renold             <reld [AT] zhaw.ch> {
 Iain Arnell            <iarnell [AT] epo.org> {
        ajp13 enhancements
 }
-
+Mariusz Okrój                 <okrojmariusz [AT]gmail.com>{
+       XMPP enhancements
+}
 and by:
 
 Pavel Roskin            <proski [AT] gnu.org>
index 4e7186d..2a1486f 100644 (file)
@@ -1118,6 +1118,12 @@ set(DISSECTOR_SRC
        dissectors/packet-xml.c
        dissectors/packet-xmcp.c
        dissectors/packet-xmpp.c
+       dissectors/packet-xmpp-conference.c
+       dissectors/packet-xmpp-core.c
+       dissectors/packet-xmpp-gtalk.c
+       dissectors/packet-xmpp-jingle.c
+       dissectors/packet-xmpp-other.c
+       dissectors/packet-xmpp-utils.c
        dissectors/packet-xot.c
        dissectors/packet-xtp.c
        dissectors/packet-xyplex.c
index cf1ba5e..c548f88 100644 (file)
@@ -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 (file)
index 0000000..0d6ad51
--- /dev/null
@@ -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 (file)
index 0000000..9f8d48b
--- /dev/null
@@ -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 (file)
index 0000000..3a1cf4c
--- /dev/null
@@ -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 (file)
index 0000000..e3de628
--- /dev/null
@@ -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 (file)
index 0000000..462c972
--- /dev/null
@@ -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 (file)
index 0000000..f699feb
--- /dev/null
@@ -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 (file)
index 0000000..d0c7999
--- /dev/null
@@ -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 (file)
index 0000000..e2ef77b
--- /dev/null
@@ -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 (file)
index 0000000..9e1a24d
--- /dev/null
@@ -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 (file)
index 0000000..8b13d47
--- /dev/null
@@ -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 (file)
index 0000000..e89af2d
--- /dev/null
@@ -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 (file)
index 0000000..b6e18eb
--- /dev/null
@@ -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 */
index 529d31b..7edd166 100644 (file)
@@ -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
  * 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 (file)
index 0000000..d935052
--- /dev/null
@@ -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 */
+