2005-09-08 21:14:24 +00:00
|
|
|
/* packet-xml.c
|
2006-05-28 19:49:07 +00:00
|
|
|
* wireshark's xml dissector .
|
2005-09-08 21:14:24 +00:00
|
|
|
*
|
|
|
|
* (C) 2005, Luis E. Garcia Ontanon.
|
|
|
|
*
|
2005-09-08 21:21:05 +00:00
|
|
|
* $Id$
|
|
|
|
*
|
2005-09-08 21:14:24 +00:00
|
|
|
* Refer to the AUTHORS file or the AUTHORS section in the man page
|
|
|
|
* for contacting the author(s) of this file.
|
|
|
|
*
|
2006-05-21 04:49:01 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
2005-09-08 21:14:24 +00:00
|
|
|
* 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
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
#ifdef HAVE_DIRENT_H
|
|
|
|
#include <dirent.h>
|
|
|
|
#endif
|
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h>
|
2005-09-17 17:05:46 +00:00
|
|
|
#include <errno.h>
|
2005-09-08 21:14:24 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
#include <glib.h>
|
|
|
|
#include <epan/emem.h>
|
|
|
|
#include <epan/packet.h>
|
|
|
|
#include <epan/strutil.h>
|
|
|
|
#include <epan/tvbparse.h>
|
2005-09-10 17:29:15 +00:00
|
|
|
#include <epan/dtd.h>
|
2005-09-17 17:05:46 +00:00
|
|
|
#include <epan/report_err.h>
|
|
|
|
#include <epan/filesystem.h>
|
2006-02-09 13:05:32 +00:00
|
|
|
#include <epan/prefs.h>
|
2007-04-30 19:24:25 +00:00
|
|
|
#include <epan/garrayfix.h>
|
2005-09-10 17:29:15 +00:00
|
|
|
|
strcasecmp(), strncasecmp(), g_strcasecmp(), and g_strncasecmp() delenda
est. Use g_ascii_strcasecmp() and g_ascii_strncasecmp(), and supply our
own versions if they're missing from GLib (as is the case with GLib
1.x).
In the code to build the list of named fields for Diameter, don't use
g_strdown(); do our own g_ascii_-style upper-case to lower-case mapping
in the hash function and use g_ascii_strcasecmp() in the compare
function.
We do this because there is no guarantee that toupper(), tolower(), and
functions that use them will, for example, map between "I" and "i" in
all locales; in Turkish locales, for example, there are, in both
upper case and lower case, versions of "i" with and without a dot, and
the upper-case version of "i" is "I"-with-a-dot and the lower-case
version of "I" is "i"-without-a-dot. This causes strings that should
match not to match.
This finishes fixing bug 2010 - an earlier checkin prevented the crash
(as there are other ways to produce the same crash, e.g. a bogus
dictionary.xml file), but didn't fix the case-insensitive string matching.
svn path=/trunk/; revision=23623
2007-11-27 18:52:51 +00:00
|
|
|
#ifdef NEED_G_ASCII_STRCASECMP_H
|
|
|
|
#include "g_ascii_strcasecmp.h"
|
|
|
|
#endif
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
typedef struct _xml_ns_t {
|
2006-07-07 00:45:54 +00:00
|
|
|
/* the name of this namespace */
|
2005-09-10 17:29:15 +00:00
|
|
|
gchar* name;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
|
|
|
/* its fully qualified name */
|
2005-09-17 17:05:46 +00:00
|
|
|
gchar* fqn;
|
|
|
|
|
|
|
|
/* the contents of the whole element from <> to </> */
|
2005-09-10 17:29:15 +00:00
|
|
|
int hf_tag;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
/* chunks of cdata from <> to </> excluding sub tags */
|
2005-09-10 17:29:15 +00:00
|
|
|
int hf_cdata;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
/* the subtree for its sub items */
|
2005-09-10 17:29:15 +00:00
|
|
|
gint ett;
|
|
|
|
|
|
|
|
GHashTable* attributes;
|
2005-09-17 17:05:46 +00:00
|
|
|
/* key: the attribute name
|
|
|
|
value: hf_id of what's between quotes */
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
/* the namespace's namespaces */
|
|
|
|
GHashTable* elements;
|
|
|
|
/* key: the element name
|
|
|
|
value: the child namespace */
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
GPtrArray* element_names;
|
|
|
|
/* imported directly from the parser and used while building the namespace */
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
} xml_ns_t;
|
2005-09-08 21:14:24 +00:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
proto_tree* tree;
|
|
|
|
proto_item* item;
|
|
|
|
proto_item* last_item;
|
2005-09-17 17:05:46 +00:00
|
|
|
xml_ns_t* ns;
|
2005-09-08 21:14:24 +00:00
|
|
|
int start_offset;
|
|
|
|
} xml_frame_t;
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
struct _attr_reg_data {
|
|
|
|
GArray* hf;
|
|
|
|
gchar* basename;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
static gint ett_dtd = -1;
|
2005-09-10 17:29:15 +00:00
|
|
|
static gint ett_xmpli = -1;
|
2005-09-08 21:14:24 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
static int hf_unknowwn_attrib = -1;
|
2005-09-08 21:14:24 +00:00
|
|
|
static int hf_comment = -1;
|
|
|
|
static int hf_xmlpi = -1;
|
|
|
|
static int hf_dtd_tag = -1;
|
|
|
|
static int hf_doctype = -1;
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
/* dissector handles */
|
2005-09-08 21:14:24 +00:00
|
|
|
static dissector_handle_t xml_handle;
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
/* parser definitions */
|
2005-09-08 21:14:24 +00:00
|
|
|
static tvbparse_wanted_t* want;
|
|
|
|
static tvbparse_wanted_t* want_ignore;
|
2006-02-09 13:05:32 +00:00
|
|
|
static tvbparse_wanted_t* want_heur;
|
2005-09-08 21:14:24 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
static GHashTable* xmpli_names;
|
|
|
|
static GHashTable* media_types;
|
2005-09-08 21:14:24 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
static xml_ns_t xml_ns = {"xml","/",-1,-1,-1,NULL,NULL,NULL};
|
|
|
|
static xml_ns_t unknown_ns = {"unknown","?",-1,-1,-1,NULL,NULL,NULL};
|
|
|
|
static xml_ns_t* root_ns;
|
2005-09-08 21:14:24 +00:00
|
|
|
|
2007-08-04 14:20:37 +00:00
|
|
|
static gboolean pref_heuristic_media = FALSE;
|
|
|
|
static gboolean pref_heuristic_tcp = FALSE;
|
2007-08-07 23:07:27 +00:00
|
|
|
static gboolean pref_heuristic_media_save = FALSE;
|
|
|
|
static gboolean pref_heuristic_tcp_save = FALSE;
|
2007-08-04 14:20:37 +00:00
|
|
|
static range_t *global_xml_tcp_range = NULL;
|
|
|
|
static range_t *xml_tcp_range = NULL;
|
2006-02-09 13:05:32 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
#define XML_CDATA -1000
|
2005-09-17 17:05:46 +00:00
|
|
|
#define XML_SCOPED_NAME -1001
|
2005-09-10 17:29:15 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
|
|
|
|
GArray* hf_arr;
|
2005-09-10 17:29:15 +00:00
|
|
|
GArray* ett_arr;
|
2005-09-08 21:14:24 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
static const gchar* default_media_types[] = {
|
2006-07-07 00:45:54 +00:00
|
|
|
"text/xml",
|
|
|
|
"text/vnd.wap.wml",
|
|
|
|
"text/vnd.wap.si",
|
|
|
|
"text/vnd.wap.sl",
|
|
|
|
"text/vnd.wap.co",
|
|
|
|
"text/vnd.wap.emn",
|
|
|
|
"application/auth-policy+xml",
|
2006-04-20 15:24:04 +00:00
|
|
|
"application/cpim-pidf+xml",
|
|
|
|
"application/cpl+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"application/mathml+xml",
|
2006-10-03 18:04:15 +00:00
|
|
|
"application/media_control+xml",
|
2007-08-08 19:50:39 +00:00
|
|
|
"application/note+xml",
|
2006-04-19 18:58:13 +00:00
|
|
|
"application/pidf+xml",
|
2006-04-20 15:24:04 +00:00
|
|
|
"application/poc-settings+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"application/rdf+xml",
|
2006-04-20 15:24:04 +00:00
|
|
|
"application/reginfo+xml",
|
2006-04-19 18:58:13 +00:00
|
|
|
"application/resource-lists+xml",
|
|
|
|
"application/rlmi+xml",
|
2006-04-20 15:24:04 +00:00
|
|
|
"application/rls-services+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"application/smil",
|
2006-04-20 15:24:04 +00:00
|
|
|
"application/simple-filter+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"application/soap+xml",
|
|
|
|
"application/vnd.wv.csp+xml",
|
2006-04-19 18:58:13 +00:00
|
|
|
"application/vnd.wv.csp.xml",
|
2006-04-20 15:24:04 +00:00
|
|
|
"application/watcherinfo+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"application/xcap-att+xml",
|
|
|
|
"application/xcap-caps+xml",
|
2007-08-08 19:50:39 +00:00
|
|
|
"application/xcap-diff+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"application/xcap-el+xml",
|
|
|
|
"application/xcap-error+xml",
|
2007-08-08 19:50:39 +00:00
|
|
|
"application/xcap-ns+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"application/xml",
|
|
|
|
"application/xml-dtd",
|
2006-05-16 19:04:53 +00:00
|
|
|
"application/xpidf+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"application/xslt+xml",
|
2007-10-24 21:47:13 +00:00
|
|
|
"application/x-wms-logconnectstats",
|
|
|
|
"application/x-wms-logplaystats",
|
|
|
|
"application/x-wms-sendevent",
|
2007-11-15 23:59:54 +00:00
|
|
|
"application/rss+xml",
|
2006-07-07 00:45:54 +00:00
|
|
|
"image/svg+xml",
|
2005-09-17 17:05:46 +00:00
|
|
|
};
|
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
static void
|
2005-09-10 17:29:15 +00:00
|
|
|
dissect_xml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
2005-09-08 21:14:24 +00:00
|
|
|
{
|
|
|
|
tvbparse_t* tt;
|
|
|
|
tvbparse_elem_t* tok = NULL;
|
|
|
|
static GPtrArray* stack = NULL;
|
|
|
|
xml_frame_t* current_frame;
|
2007-08-10 21:03:26 +00:00
|
|
|
char* colinfo_str;
|
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
if(!tree) return;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
if (stack != NULL)
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_free(stack,TRUE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
stack = g_ptr_array_new();
|
|
|
|
current_frame = ep_alloc(sizeof(xml_frame_t));
|
|
|
|
g_ptr_array_add(stack,current_frame);
|
|
|
|
|
|
|
|
tt = tvbparse_init(tvb,0,-1,stack,want_ignore);
|
2005-09-10 17:29:15 +00:00
|
|
|
current_frame->start_offset = 0;
|
2005-09-21 15:03:19 +00:00
|
|
|
|
|
|
|
root_ns = NULL;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-21 15:03:19 +00:00
|
|
|
if (pinfo->match_string)
|
|
|
|
root_ns = g_hash_table_lookup(media_types,pinfo->match_string);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
if (! root_ns ) {
|
2005-09-17 17:05:46 +00:00
|
|
|
root_ns = &xml_ns;
|
2007-08-10 21:03:26 +00:00
|
|
|
colinfo_str = "/XML";
|
|
|
|
} else {
|
|
|
|
colinfo_str = ep_strdup_printf("/%s",root_ns->name);
|
|
|
|
g_strup(colinfo_str);
|
2005-09-10 17:29:15 +00:00
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2007-08-10 21:03:26 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_append_str(pinfo->cinfo, COL_PROTOCOL, colinfo_str);
|
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
current_frame->ns = root_ns;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
current_frame->item = proto_tree_add_item(tree,current_frame->ns->hf_tag,tvb,0,-1,FALSE);
|
|
|
|
current_frame->tree = proto_item_add_subtree(current_frame->item,current_frame->ns->ett);
|
2005-09-08 21:14:24 +00:00
|
|
|
current_frame->last_item = current_frame->item;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
while(( tok = tvbparse_get(tt, want) )) ;
|
2006-07-07 00:45:54 +00:00
|
|
|
}
|
2005-09-08 21:14:24 +00:00
|
|
|
|
2006-02-09 13:05:32 +00:00
|
|
|
static gboolean dissect_xml_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
2007-08-04 14:20:37 +00:00
|
|
|
if ( (pref_heuristic_media || pref_heuristic_tcp)
|
|
|
|
&& tvbparse_peek(tvbparse_init(tvb,0,-1,NULL,want_ignore), want_heur)) {
|
2006-02-09 13:05:32 +00:00
|
|
|
dissect_xml(tvb, pinfo, tree);
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2005-09-08 21:14:24 +00:00
|
|
|
|
|
|
|
static void after_token(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok) {
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
|
|
|
int hfid;
|
|
|
|
proto_item* pi;
|
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
if (tok->id == XML_CDATA) {
|
2005-09-22 21:18:19 +00:00
|
|
|
hfid = current_frame->ns ? current_frame->ns->hf_cdata : xml_ns.hf_cdata;
|
2005-09-10 17:29:15 +00:00
|
|
|
} else if ( tok->id > 0) {
|
2005-09-08 21:14:24 +00:00
|
|
|
hfid = tok->id;
|
2005-09-10 17:29:15 +00:00
|
|
|
} else {
|
2005-09-17 17:05:46 +00:00
|
|
|
hfid = xml_ns.hf_cdata;
|
2005-09-10 17:29:15 +00:00
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
pi = proto_tree_add_item(current_frame->tree, hfid, tok->tvb, tok->offset, tok->len, FALSE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
proto_item_set_text(pi, "%s",
|
2005-09-10 17:29:15 +00:00
|
|
|
tvb_format_text(tok->tvb,tok->offset,tok->len));
|
2005-09-08 21:14:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void before_xmpli(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok) {
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
|
|
|
proto_item* pi;
|
|
|
|
proto_tree* pt;
|
|
|
|
tvbparse_elem_t* name_tok = tok->sub->next;
|
2007-03-26 11:06:26 +00:00
|
|
|
gchar* name = (gchar*)tvb_get_ephemeral_string(name_tok->tvb,name_tok->offset,name_tok->len);
|
2005-09-17 17:05:46 +00:00
|
|
|
xml_ns_t* ns = g_hash_table_lookup(xmpli_names,name);
|
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
int hf_tag;
|
|
|
|
gint ett;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-12 07:55:14 +00:00
|
|
|
g_strdown(name);
|
2005-09-10 17:29:15 +00:00
|
|
|
if (!ns) {
|
|
|
|
hf_tag = hf_xmlpi;
|
|
|
|
ett = ett_xmpli;
|
|
|
|
} else {
|
|
|
|
hf_tag = ns->hf_tag;
|
|
|
|
ett = ns->ett;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
pi = proto_tree_add_item(current_frame->tree,hf_tag,tok->tvb,tok->offset,tok->len,FALSE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
|
|
|
proto_item_set_text(pi, "%s", tvb_format_text(tok->tvb,tok->offset,(name_tok->offset - tok->offset) + name_tok->len));
|
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
pt = proto_item_add_subtree(pi,ett);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
current_frame = ep_alloc(sizeof(xml_frame_t));
|
|
|
|
current_frame->item = pi;
|
|
|
|
current_frame->last_item = pi;
|
|
|
|
current_frame->tree = pt;
|
|
|
|
current_frame->start_offset = tok->offset;
|
2005-09-10 17:29:15 +00:00
|
|
|
current_frame->ns = ns;
|
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
g_ptr_array_add(stack,current_frame);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void after_xmlpi(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok) {
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
proto_tree_add_text(current_frame->tree,
|
|
|
|
tok->tvb, tok->offset, tok->len,
|
|
|
|
tvb_format_text(tok->tvb,tok->offset,tok->len));
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
if (stack->len > 1) {
|
|
|
|
g_ptr_array_remove_index_fast(stack,stack->len - 1);
|
|
|
|
} else {
|
2005-09-10 17:29:15 +00:00
|
|
|
proto_tree_add_text(current_frame->tree,tok->tvb,tok->offset,tok->len,"[ ERROR: Closing an unopened xmpli tag ]");
|
2005-09-08 21:14:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void before_tag(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok) {
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
2005-09-10 17:29:15 +00:00
|
|
|
tvbparse_elem_t* name_tok = tok->sub->next;
|
2005-09-17 17:05:46 +00:00
|
|
|
gchar* root_name;
|
|
|
|
gchar* name;
|
|
|
|
xml_ns_t* ns;
|
2005-09-10 17:29:15 +00:00
|
|
|
xml_frame_t* new_frame;
|
2005-09-08 21:14:24 +00:00
|
|
|
proto_item* pi;
|
|
|
|
proto_tree* pt;
|
2005-09-17 17:05:46 +00:00
|
|
|
|
|
|
|
if (name_tok->sub->id == XML_SCOPED_NAME) {
|
|
|
|
tvbparse_elem_t* root_tok = name_tok->sub->sub;
|
|
|
|
tvbparse_elem_t* leaf_tok = name_tok->sub->sub->next->next;
|
|
|
|
xml_ns_t* nameroot_ns;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2007-03-26 11:06:26 +00:00
|
|
|
root_name = (gchar*)tvb_get_ephemeral_string(root_tok->tvb,root_tok->offset,root_tok->len);
|
|
|
|
name = (gchar*)tvb_get_ephemeral_string(leaf_tok->tvb,leaf_tok->offset,leaf_tok->len);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
nameroot_ns = g_hash_table_lookup(xml_ns.elements,root_name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if(nameroot_ns) {
|
|
|
|
ns = g_hash_table_lookup(nameroot_ns->elements,name);
|
|
|
|
if (!ns) {
|
2006-07-07 00:45:54 +00:00
|
|
|
ns = &unknown_ns;
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ns = &unknown_ns;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
} else {
|
2007-03-26 11:06:26 +00:00
|
|
|
name = (gchar*)tvb_get_ephemeral_string(name_tok->tvb,name_tok->offset,name_tok->len);
|
2005-09-17 17:05:46 +00:00
|
|
|
g_strdown(name);
|
2005-09-22 21:18:19 +00:00
|
|
|
|
|
|
|
if(current_frame->ns) {
|
|
|
|
ns = g_hash_table_lookup(current_frame->ns->elements,name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-22 21:18:19 +00:00
|
|
|
if (!ns) {
|
|
|
|
if (! ( ns = g_hash_table_lookup(root_ns->elements,name) ) ) {
|
|
|
|
ns = &unknown_ns;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ns = &unknown_ns;
|
|
|
|
}
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pi = proto_tree_add_item(current_frame->tree,ns->hf_tag,tok->tvb,tok->offset,tok->len,FALSE);
|
2006-07-07 00:45:54 +00:00
|
|
|
proto_item_set_text(pi, "%s", tvb_format_text(tok->tvb,tok->offset,(name_tok->offset - tok->offset) + name_tok->len));
|
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
pt = proto_item_add_subtree(pi,ns->ett);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
new_frame = ep_alloc(sizeof(xml_frame_t));
|
|
|
|
new_frame->item = pi;
|
|
|
|
new_frame->last_item = pi;
|
|
|
|
new_frame->tree = pt;
|
|
|
|
new_frame->start_offset = tok->offset;
|
|
|
|
new_frame->ns = ns;
|
|
|
|
|
|
|
|
g_ptr_array_add(stack,new_frame);
|
2005-09-08 21:14:24 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
static void after_open_tag(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok _U_) {
|
2005-09-08 21:14:24 +00:00
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
|
|
|
|
|
|
|
proto_item_append_text(current_frame->last_item,">");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void after_closed_tag(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok) {
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
|
|
|
|
2006-07-07 00:45:54 +00:00
|
|
|
proto_item_append_text(current_frame->last_item,"/>");
|
2005-09-08 21:14:24 +00:00
|
|
|
|
|
|
|
if (stack->len > 1) {
|
|
|
|
g_ptr_array_remove_index_fast(stack,stack->len - 1);
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(current_frame->tree,tok->tvb,tok->offset,tok->len,"[ ERROR: Closing an unopened tag ]");
|
2006-07-07 00:45:54 +00:00
|
|
|
}
|
2005-09-08 21:14:24 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 12:51:14 +00:00
|
|
|
static void after_untag(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok){
|
2005-09-08 21:14:24 +00:00
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
|
|
|
|
|
|
|
proto_item_set_len(current_frame->item, (tok->offset - current_frame->start_offset) + tok->len);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
proto_tree_add_text(current_frame->tree,tok->tvb,tok->offset,tok->len,"%s",
|
2005-09-10 17:29:15 +00:00
|
|
|
tvb_format_text(tok->tvb,tok->offset,tok->len));
|
2005-09-08 21:14:24 +00:00
|
|
|
|
|
|
|
if (stack->len > 1) {
|
|
|
|
g_ptr_array_remove_index_fast(stack,stack->len - 1);
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(current_frame->tree,tok->tvb,tok->offset,tok->len,
|
|
|
|
"[ ERROR: Closing an unopened tag ]");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void before_dtd_doctype(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok){
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
|
|
|
tvbparse_elem_t* name_tok = tok->sub->next->next->next->sub->sub;
|
|
|
|
proto_tree* dtd_item = proto_tree_add_item(current_frame->tree, hf_doctype,
|
|
|
|
name_tok->tvb, name_tok->offset, name_tok->len, FALSE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
proto_item_set_text(dtd_item,"%s",tvb_format_text(tok->tvb,tok->offset,tok->len));
|
2005-09-08 21:14:24 +00:00
|
|
|
|
|
|
|
current_frame = ep_alloc(sizeof(xml_frame_t));
|
|
|
|
current_frame->item = dtd_item;
|
|
|
|
current_frame->last_item = dtd_item;
|
|
|
|
current_frame->tree = proto_item_add_subtree(dtd_item,ett_dtd);
|
|
|
|
current_frame->start_offset = tok->offset;
|
2005-09-10 17:29:15 +00:00
|
|
|
current_frame->ns = NULL;
|
2005-09-08 21:14:24 +00:00
|
|
|
|
|
|
|
g_ptr_array_add(stack,current_frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pop_stack(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok _U_) {
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
|
|
|
|
|
|
|
if (stack->len > 1) {
|
|
|
|
g_ptr_array_remove_index_fast(stack,stack->len - 1);
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(current_frame->tree,tok->tvb,tok->offset,tok->len,
|
|
|
|
"[ ERROR: Closing an unopened tag ]");
|
2006-07-07 00:45:54 +00:00
|
|
|
}
|
2005-09-08 21:14:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void after_dtd_close(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok){
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
proto_tree_add_text(current_frame->tree,tok->tvb,tok->offset,tok->len,"%s",
|
2005-09-10 17:29:15 +00:00
|
|
|
tvb_format_text(tok->tvb,tok->offset,tok->len));
|
2005-09-08 21:14:24 +00:00
|
|
|
if (stack->len > 1) {
|
|
|
|
g_ptr_array_remove_index_fast(stack,stack->len - 1);
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(current_frame->tree,tok->tvb,tok->offset,tok->len,"[ ERROR: Closing an unopened tag ]");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void get_attrib_value(void* tvbparse_data _U_, const void* wanted_data _U_, tvbparse_elem_t* tok) {
|
|
|
|
tok->data = tok->sub;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void after_attrib(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok) {
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
2007-03-26 11:06:26 +00:00
|
|
|
gchar* name = (gchar*)tvb_get_ephemeral_string(tok->sub->tvb,tok->sub->offset,tok->sub->len);
|
2005-09-08 21:14:24 +00:00
|
|
|
tvbparse_elem_t* value = tok->sub->next->next->data;
|
2005-09-10 17:29:15 +00:00
|
|
|
int* hfidp;
|
|
|
|
int hfid;
|
2005-09-08 21:14:24 +00:00
|
|
|
|
2005-09-12 07:55:14 +00:00
|
|
|
g_strdown(name);
|
|
|
|
if(current_frame->ns && (hfidp = g_hash_table_lookup(current_frame->ns->attributes,name) )) {
|
2005-09-10 17:29:15 +00:00
|
|
|
hfid = *hfidp;
|
|
|
|
} else {
|
|
|
|
hfid = hf_unknowwn_attrib;
|
|
|
|
value = tok;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
current_frame->last_item = proto_tree_add_item(current_frame->tree,hfid,value->tvb,value->offset,value->len,FALSE);
|
|
|
|
proto_item_set_text(current_frame->last_item, "%s", tvb_format_text(tok->tvb,tok->offset,tok->len));
|
2005-09-08 21:14:24 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void unrecognized_token(void* tvbparse_data, const void* wanted_data _U_, tvbparse_elem_t* tok _U_){
|
|
|
|
GPtrArray* stack = tvbparse_data;
|
|
|
|
xml_frame_t* current_frame = g_ptr_array_index(stack,stack->len - 1);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
proto_tree_add_text(current_frame->tree,tok->tvb,tok->offset,tok->len,"[ ERROR: Unrecognized text ]");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-07-07 00:45:54 +00:00
|
|
|
static void init_xml_parser(void) {
|
2006-01-30 22:43:08 +00:00
|
|
|
tvbparse_wanted_t* want_name = tvbparse_chars(-1,1,0,"abcdefghijklmnopqrstuvwxyz-_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",NULL,NULL,NULL);
|
|
|
|
tvbparse_wanted_t* want_attr_name = tvbparse_chars(-1,1,0,"abcdefghijklmnopqrstuvwxyz-_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:",NULL,NULL,NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_scoped_name = tvbparse_set_seq(XML_SCOPED_NAME, NULL, NULL, NULL,
|
|
|
|
want_name,
|
|
|
|
tvbparse_char(-1,":",NULL,NULL,NULL),
|
|
|
|
want_name,
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
tvbparse_wanted_t* want_tag_name = tvbparse_set_oneof(0, NULL, NULL, NULL,
|
2005-09-27 22:57:07 +00:00
|
|
|
want_scoped_name,
|
2005-09-17 17:05:46 +00:00
|
|
|
want_name,
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_attrib_value = tvbparse_set_oneof(0, NULL, NULL, get_attrib_value,
|
|
|
|
tvbparse_quoted(-1, NULL, NULL, tvbparse_shrink_token_cb,'\"','\\'),
|
|
|
|
tvbparse_quoted(-1, NULL, NULL, tvbparse_shrink_token_cb,'\'','\\'),
|
|
|
|
tvbparse_chars(-1,1,0,"0123456789",NULL,NULL,NULL),
|
|
|
|
want_name,
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
tvbparse_wanted_t* want_attributes = tvbparse_one_or_more(-1, NULL, NULL, NULL,
|
2005-09-10 17:29:15 +00:00
|
|
|
tvbparse_set_seq(-1, NULL, NULL, after_attrib,
|
2005-09-27 22:57:07 +00:00
|
|
|
want_attr_name,
|
2005-09-08 21:14:24 +00:00
|
|
|
tvbparse_char(-1,"=",NULL,NULL,NULL),
|
2005-09-27 22:57:07 +00:00
|
|
|
want_attrib_value,
|
2005-09-08 21:14:24 +00:00
|
|
|
NULL));
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
tvbparse_wanted_t* want_stoptag = tvbparse_set_oneof(-1,NULL,NULL,NULL,
|
|
|
|
tvbparse_char(-1, ">", NULL, NULL, after_open_tag),
|
|
|
|
tvbparse_string(-1, "/>", NULL, NULL, after_closed_tag),
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
tvbparse_wanted_t* want_stopxmlpi = tvbparse_string(-1,"?>",NULL,NULL,after_xmlpi);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_comment = tvbparse_set_seq(hf_comment,NULL,NULL,after_token,
|
|
|
|
tvbparse_string(-1,"<!--",NULL,NULL,NULL),
|
|
|
|
tvbparse_until(-1,NULL,NULL,NULL,
|
|
|
|
tvbparse_string(-1,"-->",NULL,NULL,NULL),
|
2005-09-28 21:32:47 +00:00
|
|
|
TP_UNTIL_INCLUDE),
|
2005-09-27 22:57:07 +00:00
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_xmlpi = tvbparse_set_seq(hf_xmlpi,NULL,before_xmpli,NULL,
|
|
|
|
tvbparse_string(-1,"<?",NULL,NULL,NULL),
|
|
|
|
want_name,
|
|
|
|
tvbparse_set_oneof(-1,NULL,NULL,NULL,
|
|
|
|
want_stopxmlpi,
|
|
|
|
tvbparse_set_seq(-1,NULL,NULL,NULL,
|
|
|
|
want_attributes,
|
|
|
|
want_stopxmlpi,
|
|
|
|
NULL),
|
|
|
|
NULL),
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_closing_tag = tvbparse_set_seq(0,NULL,NULL,after_untag,
|
|
|
|
tvbparse_char(-1, "<", NULL, NULL, NULL),
|
|
|
|
tvbparse_char(-1, "/", NULL, NULL, NULL),
|
|
|
|
want_tag_name,
|
|
|
|
tvbparse_char(-1, ">", NULL, NULL, NULL),
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_doctype_start = tvbparse_set_seq(-1,NULL,before_dtd_doctype,NULL,
|
|
|
|
tvbparse_char(-1,"<",NULL,NULL,NULL),
|
|
|
|
tvbparse_char(-1,"!",NULL,NULL,NULL),
|
|
|
|
tvbparse_casestring(-1,"DOCTYPE",NULL,NULL,NULL),
|
|
|
|
tvbparse_set_oneof(-1,NULL,NULL,NULL,
|
|
|
|
tvbparse_set_seq(-1,NULL,NULL,NULL,
|
|
|
|
want_name,
|
|
|
|
tvbparse_char(-1,"[",NULL,NULL,NULL),
|
|
|
|
NULL),
|
|
|
|
tvbparse_set_seq(-1,NULL,NULL,pop_stack,
|
|
|
|
want_name,
|
|
|
|
tvbparse_set_oneof(-1,NULL,NULL,NULL,
|
|
|
|
tvbparse_casestring(-1,"PUBLIC",NULL,NULL,NULL),
|
|
|
|
tvbparse_casestring(-1,"SYSTEM",NULL,NULL,NULL),
|
|
|
|
NULL),
|
|
|
|
tvbparse_until(-1,NULL,NULL,NULL,
|
|
|
|
tvbparse_char(-1,">",NULL,NULL,NULL),
|
2005-09-28 21:32:47 +00:00
|
|
|
TP_UNTIL_INCLUDE),
|
2005-09-27 22:57:07 +00:00
|
|
|
NULL),
|
|
|
|
NULL),
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_dtd_tag = tvbparse_set_seq(hf_dtd_tag,NULL,NULL,after_token,
|
|
|
|
tvbparse_char(-1,"<",NULL,NULL,NULL),
|
|
|
|
tvbparse_char(-1,"!",NULL,NULL,NULL),
|
|
|
|
tvbparse_until(-1,NULL,NULL,NULL,
|
|
|
|
tvbparse_char(-1, ">", NULL, NULL, NULL),
|
2005-09-28 21:32:47 +00:00
|
|
|
TP_UNTIL_INCLUDE),
|
2005-09-27 22:57:07 +00:00
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_tag = tvbparse_set_seq(-1, NULL, before_tag, NULL,
|
|
|
|
tvbparse_char(-1,"<",NULL,NULL,NULL),
|
|
|
|
want_tag_name,
|
|
|
|
tvbparse_set_oneof(-1,NULL,NULL,NULL,
|
|
|
|
tvbparse_set_seq(-1,NULL,NULL,NULL,
|
|
|
|
want_attributes,
|
|
|
|
want_stoptag,
|
|
|
|
NULL),
|
|
|
|
want_stoptag,
|
|
|
|
NULL),
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
tvbparse_wanted_t* want_dtd_close = tvbparse_set_seq(-1,NULL,NULL,after_dtd_close,
|
|
|
|
tvbparse_char(-1,"]",NULL,NULL,NULL),
|
|
|
|
tvbparse_char(-1,">",NULL,NULL,NULL),
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
want_ignore = tvbparse_chars(-1,1,0," \t\r\n",NULL,NULL,NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
want = tvbparse_set_oneof(-1, NULL, NULL, NULL,
|
2005-09-27 22:57:07 +00:00
|
|
|
want_comment,
|
|
|
|
want_xmlpi,
|
|
|
|
want_closing_tag,
|
|
|
|
want_doctype_start,
|
|
|
|
want_dtd_close,
|
|
|
|
want_dtd_tag,
|
|
|
|
want_tag,
|
|
|
|
tvbparse_not_chars(XML_CDATA,1,0,"<",NULL,NULL,after_token),
|
|
|
|
tvbparse_not_chars(-1,1,0," \t\r\n",NULL,NULL,unrecognized_token),
|
2005-09-08 21:14:24 +00:00
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2006-02-09 13:05:32 +00:00
|
|
|
want_heur = tvbparse_set_oneof(-1, NULL, NULL, NULL,
|
|
|
|
want_comment,
|
|
|
|
want_xmlpi,
|
|
|
|
want_doctype_start,
|
|
|
|
want_dtd_tag,
|
|
|
|
want_tag,
|
|
|
|
NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-22 12:51:14 +00:00
|
|
|
static xml_ns_t* xml_new_namespace(GHashTable* hash, gchar* name, ...) {
|
2005-09-17 17:05:46 +00:00
|
|
|
xml_ns_t* ns = g_malloc(sizeof(xml_ns_t));
|
2005-09-10 17:29:15 +00:00
|
|
|
va_list ap;
|
|
|
|
gchar* attr_name;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
ns->name = g_strdup(name);
|
|
|
|
ns->hf_tag = -1;
|
|
|
|
ns->hf_cdata = -1;
|
|
|
|
ns->ett = -1;
|
|
|
|
ns->attributes = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
ns->elements = g_hash_table_new(g_str_hash,g_str_equal);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
va_start(ap,name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
while(( attr_name = va_arg(ap,gchar*) )) {
|
|
|
|
int* hfp = g_malloc(sizeof(int));
|
|
|
|
*hfp = -1;
|
|
|
|
g_hash_table_insert(ns->attributes,g_strdup(attr_name),hfp);
|
|
|
|
};
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
va_end(ap);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
g_hash_table_insert(hash,ns->name,ns);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
return ns;
|
|
|
|
}
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
|
2005-11-22 12:51:14 +00:00
|
|
|
static void add_xml_field(GArray* hfs, int* p_id, gchar* name, gchar* fqn) {
|
2005-09-10 17:29:15 +00:00
|
|
|
hf_register_info hfri;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
hfri.p_id = p_id;
|
|
|
|
hfri.hfinfo.name = name;
|
|
|
|
hfri.hfinfo.abbrev = fqn;
|
2005-09-10 17:29:15 +00:00
|
|
|
hfri.hfinfo.type = FT_STRING;
|
|
|
|
hfri.hfinfo.display = BASE_NONE;
|
|
|
|
hfri.hfinfo.strings = NULL;
|
|
|
|
hfri.hfinfo.bitmask = 0x0;
|
2005-09-17 17:05:46 +00:00
|
|
|
hfri.hfinfo.blurb = "";
|
2005-09-10 17:29:15 +00:00
|
|
|
hfri.hfinfo.id = 0;
|
|
|
|
hfri.hfinfo.parent = 0;
|
|
|
|
hfri.hfinfo.ref_count = 0;
|
|
|
|
hfri.hfinfo.bitshift = 0;
|
|
|
|
hfri.hfinfo.same_name_next = NULL;
|
|
|
|
hfri.hfinfo.same_name_prev = NULL;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
|
|
|
g_array_append_val(hfs,hfri);
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 12:51:14 +00:00
|
|
|
static void add_xml_attribute_names(gpointer k, gpointer v, gpointer p) {
|
2005-09-17 17:05:46 +00:00
|
|
|
struct _attr_reg_data* d = p;
|
|
|
|
gchar* basename = g_strdup_printf("%s.%s",d->basename,(gchar*)k);
|
|
|
|
add_xml_field(d->hf, (int*) v, (gchar*)k, basename);
|
2005-09-10 17:29:15 +00:00
|
|
|
}
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
|
2005-11-22 12:51:14 +00:00
|
|
|
static void add_xmlpi_namespace(gpointer k _U_, gpointer v, gpointer p) {
|
2005-09-17 17:05:46 +00:00
|
|
|
xml_ns_t* ns = v;
|
2005-09-10 17:29:15 +00:00
|
|
|
gchar* basename = g_strdup_printf("%s.%s",(gchar*)p,ns->name);
|
|
|
|
gint* ett_p = &(ns->ett);
|
2005-09-17 17:05:46 +00:00
|
|
|
struct _attr_reg_data d;
|
|
|
|
|
|
|
|
add_xml_field(hf_arr, &(ns->hf_tag), basename, basename);
|
2005-09-10 17:29:15 +00:00
|
|
|
|
|
|
|
g_array_append_val(ett_arr,ett_p);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
d.basename = basename;
|
|
|
|
d.hf = hf_arr;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_hash_table_foreach(ns->attributes,add_xml_attribute_names,&d);
|
2005-09-10 17:29:15 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
static void destroy_dtd_data(dtd_build_data_t* dtd_data) {
|
2005-09-10 17:29:15 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if(dtd_data->proto_name) g_free(dtd_data->proto_name);
|
|
|
|
if(dtd_data->media_type) g_free(dtd_data->media_type);
|
|
|
|
if(dtd_data->description) g_free(dtd_data->description);
|
|
|
|
if(dtd_data->proto_root) g_free(dtd_data->proto_root);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-10-06 22:01:52 +00:00
|
|
|
g_string_free(dtd_data->error,TRUE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
|
|
|
|
while(dtd_data->elements->len) {
|
|
|
|
dtd_named_list_t* nl = g_ptr_array_remove_index_fast(dtd_data->elements,0);
|
|
|
|
g_ptr_array_free(nl->list,TRUE);
|
|
|
|
g_free(nl);
|
|
|
|
}
|
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_free(dtd_data->elements,TRUE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
while(dtd_data->attributes->len) {
|
2006-07-20 17:32:10 +00:00
|
|
|
dtd_named_list_t* nl = g_ptr_array_remove_index_fast(dtd_data->attributes,0);
|
2005-09-17 17:05:46 +00:00
|
|
|
g_ptr_array_free(nl->list,TRUE);
|
|
|
|
g_free(nl);
|
|
|
|
}
|
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_free(dtd_data->attributes,TRUE);
|
2005-09-17 17:05:46 +00:00
|
|
|
|
|
|
|
g_free(dtd_data);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void copy_attrib_item(gpointer k, gpointer v _U_, gpointer p) {
|
|
|
|
gchar* key = g_strdup(k);
|
|
|
|
int* value = g_malloc(sizeof(int));
|
|
|
|
GHashTable* dst = p;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
*value = -1;
|
|
|
|
g_hash_table_insert(dst,key,value);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static GHashTable* copy_attributes_hash(GHashTable* src) {
|
|
|
|
GHashTable* dst = g_hash_table_new(g_str_hash,g_str_equal);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_hash_table_foreach(src,copy_attrib_item,dst);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
static xml_ns_t* duplicate_element(xml_ns_t* orig) {
|
|
|
|
xml_ns_t* new_item = g_malloc(sizeof(xml_ns_t));
|
|
|
|
guint i;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
new_item->name = g_strdup(orig->name);
|
|
|
|
new_item->hf_tag = -1;
|
|
|
|
new_item->hf_cdata = -1;
|
|
|
|
new_item->ett = -1;
|
|
|
|
new_item->attributes = copy_attributes_hash(orig->attributes);
|
|
|
|
new_item->elements = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
new_item->element_names = g_ptr_array_new();
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
for(i=0; i < orig->element_names->len; i++) {
|
|
|
|
g_ptr_array_add(new_item->element_names,
|
|
|
|
g_ptr_array_index(orig->element_names,i));
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
return new_item;
|
|
|
|
}
|
|
|
|
|
2006-11-15 18:40:37 +00:00
|
|
|
static gchar* fully_qualified_name(GPtrArray* hier, gchar* name, gchar* proto_name) {
|
2005-09-17 17:05:46 +00:00
|
|
|
guint i;
|
2006-11-15 18:40:37 +00:00
|
|
|
GString* s = g_string_new(proto_name);
|
2005-09-17 17:05:46 +00:00
|
|
|
gchar* str;
|
2006-11-15 18:40:37 +00:00
|
|
|
g_string_append(s,".");
|
|
|
|
|
|
|
|
for (i = 1; i < hier->len; i++) {
|
2005-09-17 17:05:46 +00:00
|
|
|
g_string_sprintfa(s, "%s.",(gchar*)g_ptr_array_index(hier,i));
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_string_append(s,name);
|
|
|
|
str = s->str;
|
|
|
|
g_string_free(s,FALSE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static xml_ns_t* make_xml_hier(gchar* elem_name,
|
|
|
|
xml_ns_t* root,
|
|
|
|
GHashTable* elements,
|
|
|
|
GPtrArray* hier,
|
|
|
|
GString* error,
|
|
|
|
GArray* hfs,
|
2006-11-15 18:40:37 +00:00
|
|
|
GArray* etts,
|
|
|
|
char* proto_name) {
|
2005-09-17 17:05:46 +00:00
|
|
|
xml_ns_t* new;
|
2005-09-24 19:03:35 +00:00
|
|
|
xml_ns_t* orig;
|
2005-09-17 17:05:46 +00:00
|
|
|
gchar* fqn;
|
|
|
|
gint* ett_p;
|
|
|
|
struct _attr_reg_data d;
|
|
|
|
gboolean recurred = FALSE;
|
2005-09-24 19:03:35 +00:00
|
|
|
guint i;
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if ( g_str_equal(elem_name,root->name) ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
if (! ( orig = g_hash_table_lookup(elements,elem_name) )) {
|
2005-09-17 17:05:46 +00:00
|
|
|
g_string_sprintfa(error,"element '%s' is not defined\n", elem_name);
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
for (i = 0; i < hier->len; i++) {
|
|
|
|
if( strcmp(elem_name,(gchar*) g_ptr_array_index(hier,i) ) == 0 ) {
|
|
|
|
recurred = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
if (recurred) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2006-11-15 18:40:37 +00:00
|
|
|
fqn = fully_qualified_name(hier,elem_name,proto_name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
new = duplicate_element(orig);
|
|
|
|
new->fqn = fqn;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-27 22:57:07 +00:00
|
|
|
add_xml_field(hfs, &(new->hf_tag), g_strdup(elem_name), fqn);
|
|
|
|
add_xml_field(hfs, &(new->hf_cdata), g_strdup(elem_name), fqn);
|
2005-09-17 17:05:46 +00:00
|
|
|
|
|
|
|
ett_p = &new->ett;
|
|
|
|
g_array_append_val(etts,ett_p);
|
|
|
|
|
|
|
|
d.basename = fqn;
|
|
|
|
d.hf = hfs;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_hash_table_foreach(new->attributes,add_xml_attribute_names,&d);
|
|
|
|
|
|
|
|
while(new->element_names->len) {
|
|
|
|
gchar* child_name = g_ptr_array_remove_index(new->element_names,0);
|
|
|
|
xml_ns_t* child_element = NULL;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_add(hier,elem_name);
|
2006-11-15 18:40:37 +00:00
|
|
|
child_element = make_xml_hier(child_name, root, elements, hier,error,hfs,etts,proto_name);
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_remove_index_fast(hier,hier->len - 1);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if (child_element) {
|
|
|
|
g_hash_table_insert(new->elements,child_element->name,child_element);
|
|
|
|
}
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_free(new->element_names,TRUE);
|
2005-09-17 17:05:46 +00:00
|
|
|
new->element_names = NULL;
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2005-09-22 16:41:53 +00:00
|
|
|
static gboolean free_both(gpointer k, gpointer v, gpointer p _U_) {
|
|
|
|
g_free(k);
|
|
|
|
g_free(v);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean free_elements(gpointer k _U_, gpointer v, gpointer p _U_) {
|
|
|
|
xml_ns_t* e = v;
|
|
|
|
g_free(e->name);
|
|
|
|
g_hash_table_foreach_remove(e->attributes,free_both,NULL);
|
|
|
|
g_hash_table_destroy(e->attributes);
|
|
|
|
g_hash_table_destroy(e->elements);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
while (e->element_names->len) {
|
|
|
|
g_free(g_ptr_array_remove_index(e->element_names,0));
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-22 16:41:53 +00:00
|
|
|
g_ptr_array_free(e->element_names,TRUE);
|
|
|
|
g_free(e);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-22 16:41:53 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
static void register_dtd(dtd_build_data_t* dtd_data, GString* errors) {
|
|
|
|
GHashTable* elements = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
gchar* root_name = NULL;
|
|
|
|
xml_ns_t* root_element = NULL;
|
|
|
|
GArray* hfs;
|
|
|
|
GArray* etts;
|
|
|
|
GPtrArray* hier;
|
|
|
|
gchar* curr_name;
|
|
|
|
GPtrArray* element_names = g_ptr_array_new();
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
/* we first populate elements with the those coming from the parser */
|
|
|
|
while(dtd_data->elements->len) {
|
|
|
|
dtd_named_list_t* nl = g_ptr_array_remove_index(dtd_data->elements,0);
|
|
|
|
xml_ns_t* element = g_malloc(sizeof(xml_ns_t));
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
/* we will use the first element found as root in case no other one was given. */
|
2005-09-24 19:03:35 +00:00
|
|
|
if (root_name == NULL)
|
|
|
|
root_name = g_strdup(nl->name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
element->name = nl->name;
|
|
|
|
element->element_names = nl->list;
|
|
|
|
element->hf_tag = -1;
|
|
|
|
element->hf_cdata = -1;
|
|
|
|
element->ett = -1;
|
|
|
|
element->attributes = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
element->elements = g_hash_table_new(g_str_hash,g_str_equal);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
if( g_hash_table_lookup(elements,element->name) ) {
|
|
|
|
g_string_sprintfa(errors,"element %s defined more than once\n", element->name);
|
|
|
|
free_elements(NULL,element,NULL);
|
|
|
|
} else {
|
|
|
|
g_hash_table_insert(elements,element->name,element);
|
|
|
|
g_ptr_array_add(element_names,g_strdup(element->name));
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_free(nl);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* then we add the attributes to its relative elements */
|
|
|
|
while(dtd_data->attributes->len) {
|
|
|
|
dtd_named_list_t* nl = g_ptr_array_remove_index(dtd_data->attributes,0);
|
|
|
|
xml_ns_t* element = g_hash_table_lookup(elements,nl->name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if (!element) {
|
2005-09-24 19:03:35 +00:00
|
|
|
g_string_sprintfa(errors,"element %s is not defined\n", nl->name);
|
2005-09-17 17:05:46 +00:00
|
|
|
|
|
|
|
goto next_attribute;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
while(nl->list->len) {
|
|
|
|
gchar* name = g_ptr_array_remove_index(nl->list,0);
|
|
|
|
int* id_p = g_malloc(sizeof(int));
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
*id_p = -1;
|
|
|
|
g_hash_table_insert(element->attributes,name,id_p);
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
next_attribute:
|
|
|
|
g_free(nl->name);
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_free(nl->list,TRUE);
|
2005-09-17 17:05:46 +00:00
|
|
|
g_free(nl);
|
|
|
|
}
|
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
/* if a proto_root is defined in the dtd we'll use that as root */
|
2005-09-17 17:05:46 +00:00
|
|
|
if( dtd_data->proto_root ) {
|
2005-09-24 19:03:35 +00:00
|
|
|
if(root_name)
|
|
|
|
g_free(root_name);
|
2005-09-17 17:05:46 +00:00
|
|
|
root_name = g_strdup(dtd_data->proto_root);
|
|
|
|
}
|
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
/* we use a stack with the names to avoid recurring infinitelly */
|
2005-09-17 17:05:46 +00:00
|
|
|
hier = g_ptr_array_new();
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
/*
|
|
|
|
* if a proto name was given in the dtd the dtd will be used as a protocol
|
|
|
|
* or else the dtd will be loaded as a branch of the xml namespace
|
|
|
|
*/
|
2005-09-17 17:05:46 +00:00
|
|
|
if( ! dtd_data->proto_name ) {
|
|
|
|
hfs = hf_arr;
|
|
|
|
etts = ett_arr;
|
2006-07-07 00:45:54 +00:00
|
|
|
g_ptr_array_add(hier,g_strdup("xml"));
|
2005-09-17 17:05:46 +00:00
|
|
|
root_element = &xml_ns;
|
|
|
|
} else {
|
2005-09-24 19:03:35 +00:00
|
|
|
/*
|
|
|
|
* if we were given a proto_name the namespace will be registered
|
|
|
|
* as an indipendent protocol with its own hf and ett arrays.
|
2006-07-07 00:45:54 +00:00
|
|
|
*/
|
2005-09-17 17:05:46 +00:00
|
|
|
hfs = g_array_new(FALSE,FALSE,sizeof(hf_register_info));
|
|
|
|
etts = g_array_new(FALSE,FALSE,sizeof(gint*));
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
/* the root element of the dtd's namespace */
|
2005-09-17 17:05:46 +00:00
|
|
|
root_element = g_malloc(sizeof(xml_ns_t));
|
|
|
|
root_element->name = g_strdup(root_name);
|
2006-11-15 18:40:37 +00:00
|
|
|
root_element->fqn = dtd_data->proto_name ? g_strdup(dtd_data->proto_name) : root_element->name;
|
2005-09-17 17:05:46 +00:00
|
|
|
root_element->hf_tag = -1;
|
|
|
|
root_element->hf_cdata = -1;
|
|
|
|
root_element->ett = -1;
|
|
|
|
root_element->elements = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
root_element->element_names = element_names;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
/*
|
|
|
|
* we can either create a namespace as a flat namespace
|
|
|
|
* in which all the elements are at the root level
|
|
|
|
* or we can create a recursive namespace
|
|
|
|
*/
|
2005-09-17 17:05:46 +00:00
|
|
|
if (dtd_data->recursion) {
|
|
|
|
xml_ns_t* orig_root;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2006-11-15 18:40:37 +00:00
|
|
|
make_xml_hier(root_name, root_element, elements,hier,errors,hfs,etts,dtd_data->proto_name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_hash_table_insert(root_element->elements,root_element->name,root_element);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
orig_root = g_hash_table_lookup(elements,root_name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
/* if the root element was defined copy its attrlist to the child */
|
2006-07-07 00:45:54 +00:00
|
|
|
if(orig_root) {
|
2005-09-17 17:05:46 +00:00
|
|
|
struct _attr_reg_data d;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2006-11-15 18:40:37 +00:00
|
|
|
d.basename = dtd_data->proto_name;
|
2005-09-17 17:05:46 +00:00
|
|
|
d.hf = hfs;
|
|
|
|
|
|
|
|
root_element->attributes = copy_attributes_hash(orig_root->attributes);
|
|
|
|
g_hash_table_foreach(root_element->attributes,add_xml_attribute_names,&d);
|
|
|
|
} else {
|
|
|
|
root_element->attributes = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
}
|
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
/* we then create all the sub hierachies to catch the recurred cases */
|
2005-09-17 17:05:46 +00:00
|
|
|
g_ptr_array_add(hier,root_name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
while(root_element->element_names->len) {
|
|
|
|
curr_name = g_ptr_array_remove_index(root_element->element_names,0);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if( ! g_hash_table_lookup(root_element->elements,curr_name) ) {
|
2006-11-15 18:40:37 +00:00
|
|
|
xml_ns_t* new = make_xml_hier(curr_name, root_element, elements,hier,errors,hfs,etts,dtd_data->proto_name);
|
2005-09-17 17:05:46 +00:00
|
|
|
g_hash_table_insert(root_element->elements,new->name,new);
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_free(curr_name);
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
} else {
|
2005-09-24 19:03:35 +00:00
|
|
|
/* a flat namespace */
|
2005-09-17 17:05:46 +00:00
|
|
|
g_ptr_array_add(hier,root_name);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
root_element->attributes = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
|
|
|
|
while(root_element->element_names->len) {
|
|
|
|
xml_ns_t* new;
|
|
|
|
gint* ett_p;
|
|
|
|
struct _attr_reg_data d;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
curr_name = g_ptr_array_remove_index(root_element->element_names,0);
|
|
|
|
new = duplicate_element(g_hash_table_lookup(elements,curr_name));
|
2006-11-15 18:40:37 +00:00
|
|
|
new->fqn = fully_qualified_name(hier, curr_name, root_name);
|
2005-09-17 17:05:46 +00:00
|
|
|
|
|
|
|
add_xml_field(hfs, &(new->hf_tag), curr_name, new->fqn);
|
|
|
|
add_xml_field(hfs, &(new->hf_cdata), curr_name, new->fqn);
|
|
|
|
|
|
|
|
d.basename = new->fqn;
|
|
|
|
d.hf = hfs;
|
|
|
|
|
|
|
|
g_hash_table_foreach(new->attributes,add_xml_attribute_names,&d);
|
|
|
|
|
|
|
|
ett_p = &new->ett;
|
|
|
|
g_array_append_val(etts,ett_p);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_free(new->element_names,TRUE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_hash_table_insert(root_element->elements,new->name,new);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_free(element_names,TRUE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_ptr_array_free(hier,TRUE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
/*
|
|
|
|
* if we were given a proto_name the namespace will be registered
|
|
|
|
* as an indipendent protocol.
|
|
|
|
*/
|
2005-09-17 17:05:46 +00:00
|
|
|
if( dtd_data->proto_name ) {
|
|
|
|
gint* ett_p;
|
|
|
|
|
|
|
|
if ( ! dtd_data->description) {
|
|
|
|
dtd_data->description = g_strdup(root_name);
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
ett_p = &root_element->ett;
|
|
|
|
g_array_append_val(etts,ett_p);
|
|
|
|
|
|
|
|
add_xml_field(hfs, &root_element->hf_cdata, root_element->name, root_element->fqn);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2006-11-15 18:40:37 +00:00
|
|
|
root_element->hf_tag = proto_register_protocol(dtd_data->description, dtd_data->proto_name, dtd_data->proto_name);
|
2007-04-30 19:24:25 +00:00
|
|
|
proto_register_field_array(root_element->hf_tag, (hf_register_info*)g_array_data(hfs), hfs->len);
|
|
|
|
proto_register_subtree_array((gint**)g_array_data(etts), etts->len);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if (dtd_data->media_type) {
|
|
|
|
g_hash_table_insert(media_types,dtd_data->media_type,root_element);
|
|
|
|
dtd_data->media_type = NULL;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
dtd_data->description = NULL;
|
|
|
|
dtd_data->proto_name = NULL;
|
|
|
|
g_array_free(hfs,FALSE);
|
2005-09-24 19:03:35 +00:00
|
|
|
g_array_free(etts,TRUE);
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_hash_table_insert(xml_ns.elements,root_element->name,root_element);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-22 16:41:53 +00:00
|
|
|
g_hash_table_foreach_remove(elements,free_elements,NULL);
|
2005-09-24 19:03:35 +00:00
|
|
|
g_hash_table_destroy(elements);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
destroy_dtd_data(dtd_data);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
if (root_name)
|
|
|
|
g_free(root_name);
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if GLIB_MAJOR_VERSION < 2
|
|
|
|
# define DIRECTORY_T DIR
|
|
|
|
# define FILE_T struct dirent
|
|
|
|
# define OPENDIR_OP(name) opendir(name)
|
|
|
|
# define DIRGETNEXT_OP(dir) readdir(dir)
|
|
|
|
# define GETFNAME_OP(file) (gchar *)file->d_name
|
|
|
|
# define CLOSEDIR_OP(dir) closedir(dir)
|
|
|
|
#else /* GLIB 2 */
|
|
|
|
# define DIRECTORY_T GDir
|
|
|
|
# define FILE_T gchar
|
|
|
|
# define OPENDIR_OP(name) g_dir_open(name, 0, dummy)
|
|
|
|
# define DIRGETNEXT_OP(dir) g_dir_read_name(dir)
|
|
|
|
# define GETFNAME_OP(file) (file);
|
|
|
|
# define CLOSEDIR_OP(dir) g_dir_close(dir)
|
|
|
|
#endif
|
|
|
|
|
2005-11-22 12:51:14 +00:00
|
|
|
static void init_xml_names(void) {
|
2005-09-17 17:05:46 +00:00
|
|
|
xml_ns_t* xmlpi_xml_ns;
|
|
|
|
guint i;
|
2005-12-20 08:35:53 +00:00
|
|
|
DIRECTORY_T* dir;
|
|
|
|
const FILE_T* file;
|
|
|
|
const gchar* filename;
|
|
|
|
gchar* dirname;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
#if GLIB_MAJOR_VERSION >= 2
|
2005-12-20 08:35:53 +00:00
|
|
|
GError** dummy = g_malloc(sizeof(GError *));
|
|
|
|
*dummy = NULL;
|
2005-09-17 17:05:46 +00:00
|
|
|
#endif
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
xmpli_names = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
media_types = g_hash_table_new(g_str_hash,g_str_equal);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
unknown_ns.elements = xml_ns.elements = g_hash_table_new(g_str_hash,g_str_equal);
|
|
|
|
unknown_ns.attributes = xml_ns.attributes = g_hash_table_new(g_str_hash,g_str_equal);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
xmlpi_xml_ns = xml_new_namespace(xmpli_names,"xml","version","encoding","standalone",NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
g_hash_table_destroy(xmlpi_xml_ns->elements);
|
|
|
|
xmlpi_xml_ns->elements = NULL;
|
2005-09-17 17:05:46 +00:00
|
|
|
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
dirname = get_persconffile_path("dtds", FALSE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if (test_for_directory(dirname) != EISDIR) {
|
2005-12-20 08:35:53 +00:00
|
|
|
/* Although dir isn't a directory it may still use memory */
|
|
|
|
g_free(dirname);
|
2005-09-17 17:05:46 +00:00
|
|
|
dirname = get_datafile_path("dtds");
|
2005-12-20 08:35:53 +00:00
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
if (test_for_directory(dirname) == EISDIR) {
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
if ((dir = OPENDIR_OP(dirname)) != NULL) {
|
|
|
|
while ((file = DIRGETNEXT_OP(dir)) != NULL) {
|
|
|
|
guint namelen;
|
|
|
|
filename = GETFNAME_OP(file);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
namelen = strlen(filename);
|
strcasecmp(), strncasecmp(), g_strcasecmp(), and g_strncasecmp() delenda
est. Use g_ascii_strcasecmp() and g_ascii_strncasecmp(), and supply our
own versions if they're missing from GLib (as is the case with GLib
1.x).
In the code to build the list of named fields for Diameter, don't use
g_strdown(); do our own g_ascii_-style upper-case to lower-case mapping
in the hash function and use g_ascii_strcasecmp() in the compare
function.
We do this because there is no guarantee that toupper(), tolower(), and
functions that use them will, for example, map between "I" and "i" in
all locales; in Turkish locales, for example, there are, in both
upper case and lower case, versions of "i" with and without a dot, and
the upper-case version of "i" is "I"-with-a-dot and the lower-case
version of "I" is "i"-without-a-dot. This causes strings that should
match not to match.
This finishes fixing bug 2010 - an earlier checkin prevented the crash
(as there are other ways to produce the same crash, e.g. a bogus
dictionary.xml file), but didn't fix the case-insensitive string matching.
svn path=/trunk/; revision=23623
2007-11-27 18:52:51 +00:00
|
|
|
if ( namelen > 4 && ( g_ascii_strcasecmp(filename+(namelen-4),".dtd") == 0 ) ) {
|
2005-12-20 08:35:53 +00:00
|
|
|
GString* errors = g_string_new("");
|
|
|
|
GString* preparsed = dtd_preparse(dirname, filename, errors);
|
|
|
|
dtd_build_data_t* dtd_data;
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
if (errors->len) {
|
|
|
|
report_failure("Dtd Preparser in file %s%c%s: %s",dirname,G_DIR_SEPARATOR,filename,errors->str);
|
|
|
|
continue;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
dtd_data = dtd_parse(preparsed);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
g_string_free(preparsed,TRUE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
if (dtd_data->error->len) {
|
|
|
|
report_failure("Dtd Parser in file %s%c%s: %s",dirname,G_DIR_SEPARATOR,filename,dtd_data->error->str);
|
|
|
|
destroy_dtd_data(dtd_data);
|
|
|
|
continue;
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
register_dtd(dtd_data,errors);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
if (errors->len) {
|
|
|
|
report_failure("Dtd Registration in file: %s%c%s: %s",dirname,G_DIR_SEPARATOR,filename,errors->str);
|
|
|
|
g_string_free(errors,TRUE);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-12-20 08:35:53 +00:00
|
|
|
CLOSEDIR_OP(dir);
|
|
|
|
}
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
for(i=0;i<array_length(default_media_types);i++) {
|
|
|
|
if( ! g_hash_table_lookup(media_types,default_media_types[i]) ) {
|
|
|
|
g_hash_table_insert(media_types,(gpointer)default_media_types[i],&xml_ns);
|
|
|
|
}
|
|
|
|
}
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
g_hash_table_foreach(xmpli_names,add_xmlpi_namespace,"xml.xmlpi");
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
#if GLIB_MAJOR_VERSION >= 2
|
2005-12-20 08:35:53 +00:00
|
|
|
g_free(dummy);
|
2006-07-07 00:45:54 +00:00
|
|
|
#endif
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
2005-09-10 17:29:15 +00:00
|
|
|
|
2007-08-04 14:20:37 +00:00
|
|
|
static void range_delete_xml_tcp_callback(guint32 port) {
|
|
|
|
dissector_delete("tcp.port", port, xml_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void range_add_xml_tcp_callback(guint32 port) {
|
|
|
|
dissector_add("tcp.port", port, xml_handle);
|
|
|
|
}
|
|
|
|
|
2006-02-09 13:05:32 +00:00
|
|
|
static void apply_prefs(void) {
|
2007-08-07 23:07:27 +00:00
|
|
|
if (pref_heuristic_media_save != pref_heuristic_media) {
|
|
|
|
if (pref_heuristic_media) {
|
|
|
|
heur_dissector_add("http", dissect_xml_heur, xml_ns.hf_tag);
|
|
|
|
heur_dissector_add("sip", dissect_xml_heur, xml_ns.hf_tag);
|
|
|
|
heur_dissector_add("media", dissect_xml_heur, xml_ns.hf_tag);
|
|
|
|
pref_heuristic_media_save = TRUE;
|
|
|
|
} else {
|
|
|
|
heur_dissector_delete("http", dissect_xml_heur, xml_ns.hf_tag);
|
|
|
|
heur_dissector_delete("sip", dissect_xml_heur, xml_ns.hf_tag);
|
|
|
|
heur_dissector_delete("media", dissect_xml_heur, xml_ns.hf_tag);
|
|
|
|
pref_heuristic_media_save = FALSE;
|
|
|
|
}
|
|
|
|
}
|
2007-08-04 14:20:37 +00:00
|
|
|
|
2007-08-07 23:07:27 +00:00
|
|
|
if (pref_heuristic_tcp_save != pref_heuristic_tcp ) {
|
|
|
|
if (pref_heuristic_tcp) {
|
|
|
|
heur_dissector_add("tcp", dissect_xml_heur, xml_ns.hf_tag);
|
|
|
|
pref_heuristic_tcp_save = TRUE;
|
|
|
|
} else {
|
|
|
|
heur_dissector_delete("tcp", dissect_xml_heur, xml_ns.hf_tag);
|
|
|
|
pref_heuristic_tcp_save = FALSE;
|
|
|
|
}
|
|
|
|
}
|
2007-08-04 14:20:37 +00:00
|
|
|
|
|
|
|
range_foreach(xml_tcp_range, range_delete_xml_tcp_callback);
|
|
|
|
g_free(xml_tcp_range);
|
|
|
|
xml_tcp_range = range_copy(global_xml_tcp_range);
|
|
|
|
range_foreach(xml_tcp_range, range_add_xml_tcp_callback);
|
2006-02-09 13:05:32 +00:00
|
|
|
}
|
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
void
|
|
|
|
proto_register_xml(void) {
|
2005-09-10 17:29:15 +00:00
|
|
|
static gint *ett_base[] = {
|
|
|
|
&unknown_ns.ett,
|
|
|
|
&xml_ns.ett,
|
2005-09-08 21:14:24 +00:00
|
|
|
&ett_dtd,
|
2005-09-10 17:29:15 +00:00
|
|
|
&ett_xmpli
|
2005-09-08 21:14:24 +00:00
|
|
|
};
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
static hf_register_info hf_base[] = {
|
2005-09-08 21:14:24 +00:00
|
|
|
{ &hf_xmlpi, {"XMLPI", "xml.xmlpi", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }},
|
|
|
|
{ &hf_comment, {"Comment", "xml.comment", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }},
|
2005-09-10 17:29:15 +00:00
|
|
|
{ &hf_unknowwn_attrib, {"Attribute", "xml.attribute", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }},
|
2005-09-08 21:14:24 +00:00
|
|
|
{ &hf_doctype, {"Doctype", "xml.doctype", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }},
|
|
|
|
{ &hf_dtd_tag, {"DTD Tag", "xml.dtdtag", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }},
|
2005-09-10 17:29:15 +00:00
|
|
|
{ &unknown_ns.hf_cdata, {"CDATA", "xml.cdata", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }},
|
|
|
|
{ &unknown_ns.hf_tag, {"Tag", "xml.tag", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }},
|
2005-09-17 17:05:46 +00:00
|
|
|
{ &xml_ns.hf_cdata, {"Unknown", "xml.unknown", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}
|
2006-02-09 13:05:32 +00:00
|
|
|
};
|
|
|
|
module_t* xml_module;
|
2005-09-10 17:29:15 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
hf_arr = g_array_new(FALSE,FALSE,sizeof(hf_register_info));
|
2005-09-10 17:29:15 +00:00
|
|
|
ett_arr = g_array_new(FALSE,FALSE,sizeof(gint*));
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_array_append_vals(hf_arr,hf_base,array_length(hf_base));
|
2005-09-10 17:29:15 +00:00
|
|
|
g_array_append_vals(ett_arr,ett_base,array_length(ett_base));
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
init_xml_names();
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
xml_ns.hf_tag = proto_register_protocol("eXtensible Markup Language", "XML", xml_ns.name);
|
2005-09-10 17:29:15 +00:00
|
|
|
|
2007-04-30 19:24:25 +00:00
|
|
|
proto_register_field_array(xml_ns.hf_tag, (hf_register_info*)g_array_data(hf_arr), hf_arr->len);
|
|
|
|
proto_register_subtree_array((gint**)g_array_data(ett_arr), ett_arr->len);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2006-02-09 13:05:32 +00:00
|
|
|
xml_module = prefs_register_protocol(xml_ns.hf_tag,apply_prefs);
|
2007-08-04 14:20:37 +00:00
|
|
|
prefs_register_bool_preference(xml_module, "heuristic", "Use Heuristics for media types",
|
2006-05-16 19:04:53 +00:00
|
|
|
"Try to recognize XML for unknown media types",
|
2007-08-04 14:20:37 +00:00
|
|
|
&pref_heuristic_media);
|
|
|
|
prefs_register_bool_preference(xml_module, "heuristic_tcp", "Use Heuristics for tcp",
|
|
|
|
"Try to recognize XML for unknown TCP ports",
|
|
|
|
&pref_heuristic_tcp);
|
|
|
|
prefs_register_range_preference(xml_module, "tcp.port", "TCP Ports",
|
|
|
|
"TCP Ports range",
|
|
|
|
&global_xml_tcp_range, 65535);
|
|
|
|
|
2005-09-24 19:03:35 +00:00
|
|
|
g_array_free(hf_arr,FALSE);
|
|
|
|
g_array_free(ett_arr,TRUE);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-10 17:29:15 +00:00
|
|
|
register_dissector("xml", dissect_xml, xml_ns.hf_tag);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
init_xml_parser();
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2007-08-04 14:20:37 +00:00
|
|
|
xml_tcp_range = range_empty();
|
|
|
|
|
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 12:51:14 +00:00
|
|
|
static void add_dissector_media(gpointer k, gpointer v _U_, gpointer p _U_) {
|
2005-09-17 17:05:46 +00:00
|
|
|
dissector_add_string("media_type", (gchar*)k, xml_handle);
|
2005-09-08 21:14:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_xml(void)
|
|
|
|
{
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
xml_handle = find_dissector("xml");
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-17 17:05:46 +00:00
|
|
|
g_hash_table_foreach(media_types,add_dissector_media,NULL);
|
2006-07-07 00:45:54 +00:00
|
|
|
|
2005-09-08 21:14:24 +00:00
|
|
|
}
|