aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-xml.c
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2005-09-17 17:05:46 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2005-09-17 17:05:46 +0000
commit4c14b12c25291919fc7e409f9cfe95c16cefe678 (patch)
tree432eb53c8e154b0e76f997c778b30c476637985c /epan/dissectors/packet-xml.c
parent8ace2749f38daec92df4da8cf2d1eda298cf36ff (diff)
Because there's more than just text in XML...
DTDs are imported to create fields svn path=/trunk/; revision=15851
Diffstat (limited to 'epan/dissectors/packet-xml.c')
-rw-r--r--epan/dissectors/packet-xml.c696
1 files changed, 589 insertions, 107 deletions
diff --git a/epan/dissectors/packet-xml.c b/epan/dissectors/packet-xml.c
index 5c3ac3238a..e98598198c 100644
--- a/epan/dissectors/packet-xml.c
+++ b/epan/dissectors/packet-xml.c
@@ -31,10 +31,15 @@
#include "config.h"
#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
+#include <errno.h>
#include <stdio.h>
@@ -44,58 +49,109 @@
#include <epan/strutil.h>
#include <epan/tvbparse.h>
#include <epan/dtd.h>
+#include <epan/report_err.h>
+#include <epan/filesystem.h>
-typedef struct _xml_names_t {
+typedef struct _xml_ns_t {
+ /* the name of this namespace */
gchar* name;
- gchar* longname;
- gchar* blurb;
+
+ /* its fully qualified name */
+ gchar* fqn;
+
+ /* the contents of the whole element from <> to </> */
int hf_tag;
+
+ /* chunks of cdata from <> to </> excluding sub tags */
int hf_cdata;
+
+ /* the subtree for its sub items */
gint ett;
-
- gboolean is_root;
GHashTable* attributes;
- GHashTable* elements;
-} xml_names_t;
+ /* key: the attribute name
+ value: hf_id of what's between quotes */
+
+ /* the namespace's namespaces */
+ GHashTable* elements;
+ /* key: the element name
+ value: the child namespace */
+
+ GPtrArray* element_names;
+ /* imported directly from the parser and used while building the namespace */
+
+} xml_ns_t;
typedef struct {
proto_tree* tree;
proto_item* item;
proto_item* last_item;
- xml_names_t* ns;
+ xml_ns_t* ns;
int start_offset;
} xml_frame_t;
+struct _attr_reg_data {
+ GArray* hf;
+ gchar* basename;
+};
+
+
static gint ett_dtd = -1;
static gint ett_xmpli = -1;
-static int hf_junk = -1;
static int hf_unknowwn_attrib = -1;
static int hf_comment = -1;
static int hf_xmlpi = -1;
static int hf_dtd_tag = -1;
static int hf_doctype = -1;
-/* Dissector handles */
+/* dissector handles */
static dissector_handle_t xml_handle;
-/* tokenizer defs */
+/* parser definitions */
static tvbparse_wanted_t* want;
static tvbparse_wanted_t* want_ignore;
static GHashTable* xmpli_names;
static GHashTable* media_types;
-static xml_names_t xml_ns = {"xml","eXtesible Markup Language","XML",-1,-1,-1,TRUE,NULL,NULL};
-static xml_names_t unknown_ns = {"","","",-1,-1,-1,TRUE,NULL,NULL};
-static xml_names_t* root_ns;
+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;
#define XML_CDATA -1000
+#define XML_SCOPED_NAME -1001
-GArray* hf;
+
+GArray* hf_arr;
GArray* ett_arr;
+static const gchar* default_media_types[] = {
+ "text/xml",
+ "application/xml",
+ "application/soap+xml",
+ "application/xml-dtd",
+ "text/vnd.wap.wml",
+ "text/vnd.wap.si",
+ "text/vnd.wap.sl",
+ "text/vnd.wap.co",
+ "text/vnd.wap.emn",
+ "application/vnd.wv.csp+xml",
+ "application/xcap-el+xml",
+ "application/xcap-att+xml",
+ "application/xcap-error+xml",
+ "application/xcap-caps+xml",
+ "application/auth-policy+xml",
+ "application/smil",
+ "application/cpim-pidf+xml",
+ "application/rdf+xml",
+ "application/xslt+xml",
+ "application/mathml+xml",
+ "image/svg+xml",
+ "application/vnd.wv.csp.xml",
+};
+
+
static void
dissect_xml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
@@ -119,13 +175,13 @@ dissect_xml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
root_ns = g_hash_table_lookup(media_types,pinfo->match_string);
if (! root_ns ) {
- root_ns = &unknown_ns;
+ root_ns = &xml_ns;
}
current_frame->ns = root_ns;
- current_frame->item = proto_tree_add_item(tree,xml_ns.hf_tag,tvb,0,-1,FALSE);
- current_frame->tree = proto_item_add_subtree(current_frame->item,xml_ns.ett);
+ 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);
current_frame->last_item = current_frame->item;
while(( tok = tvbparse_get(tt, want) )) ;
@@ -143,7 +199,7 @@ static void after_token(void* tvbparse_data, const void* wanted_data _U_, tvbpar
} else if ( tok->id > 0) {
hfid = tok->id;
} else {
- hfid = hf_junk;
+ hfid = xml_ns.hf_cdata;
}
pi = proto_tree_add_item(current_frame->tree, hfid, tok->tvb, tok->offset, tok->len, FALSE);
@@ -159,7 +215,8 @@ static void before_xmpli(void* tvbparse_data, const void* wanted_data _U_, tvbpa
proto_tree* pt;
tvbparse_elem_t* name_tok = tok->sub->next;
gchar* name = tvb_get_ephemeral_string(name_tok->tvb,name_tok->offset,name_tok->len);
- xml_names_t* ns = g_hash_table_lookup(xmpli_names,name);
+ xml_ns_t* ns = g_hash_table_lookup(xmpli_names,name);
+
int hf_tag;
gint ett;
@@ -208,20 +265,46 @@ static void before_tag(void* tvbparse_data, const void* wanted_data _U_, tvbpars
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;
- gchar* name =tvb_get_ephemeral_string(name_tok->tvb,name_tok->offset,name_tok->len);
- xml_names_t* ns = g_hash_table_lookup(current_frame->ns->elements,name);
+ gchar* root_name;
+ gchar* name;
+ xml_ns_t* ns;
xml_frame_t* new_frame;
proto_item* pi;
proto_tree* pt;
-
- g_strdown(name);
- if (!ns) {
- if (! ( ns = g_hash_table_lookup(root_ns->elements,name) ) ) {
- ns = &unknown_ns;
- }
- }
-
- pi = proto_tree_add_item(current_frame->tree,ns->hf_tag,tok->tvb,tok->offset,tok->len,FALSE);
+
+ 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;
+
+ root_name = tvb_get_ephemeral_string(root_tok->tvb,root_tok->offset,root_tok->len);
+ name = tvb_get_ephemeral_string(leaf_tok->tvb,leaf_tok->offset,leaf_tok->len);
+
+ nameroot_ns = g_hash_table_lookup(xml_ns.elements,root_name);
+
+ if(nameroot_ns) {
+ ns = g_hash_table_lookup(nameroot_ns->elements,name);
+ if (!ns) {
+ ns = &unknown_ns;
+ }
+ } else {
+ ns = &unknown_ns;
+ }
+
+ } else {
+ name = tvb_get_ephemeral_string(name_tok->tvb,name_tok->offset,name_tok->len);
+ g_strdown(name);
+
+ ns = g_hash_table_lookup(current_frame->ns->elements,name);
+
+ if (!ns) {
+ if (! ( ns = g_hash_table_lookup(root_ns->elements,name) ) ) {
+ ns = &unknown_ns;
+ }
+ }
+ }
+
+ pi = proto_tree_add_item(current_frame->tree,ns->hf_tag,tok->tvb,tok->offset,tok->len,FALSE);
proto_item_set_text(pi,tvb_format_text(tok->tvb,tok->offset,(name_tok->offset - tok->offset) + name_tok->len));
pt = proto_item_add_subtree(pi,ns->ett);
@@ -354,11 +437,20 @@ static void unrecognized_token(void* tvbparse_data, const void* wanted_data _U_,
void init_xml_parser(void) {
- tvbparse_wanted_t* want_name = tvbparse_chars(-1,0,0,"abcdefghijklmnopqrstuvwxyz-_:ABCDEFGHIJKLMNOPQRSTUVWXYZ",NULL,NULL,NULL);
-
+ tvbparse_wanted_t* want_name = tvbparse_chars(-1,0,0,"abcdefghijklmnopqrstuvwxyz-_ABCDEFGHIJKLMNOPQRSTUVWXYZ",NULL,NULL,NULL);
+
+ tvbparse_wanted_t* want_tag_name = tvbparse_set_oneof(0, NULL, NULL, NULL,
+ tvbparse_set_seq(XML_SCOPED_NAME, NULL, NULL, NULL,
+ want_name,
+ tvbparse_char(-1,":",NULL,NULL,NULL),
+ want_name,
+ NULL),
+ want_name,
+ NULL);
+
tvbparse_wanted_t* want_attributes = tvbparse_one_or_more(-1, NULL, NULL, NULL,
tvbparse_set_seq(-1, NULL, NULL, after_attrib,
- want_name,
+ tvbparse_chars(-1,0,0,"abcdefghijklmnopqrstuvwxyz-_ABCDEFGHIJKLMNOPQRSTUVWXYZ:",NULL,NULL,NULL),
tvbparse_char(-1,"=",NULL,NULL,NULL),
tvbparse_set_oneof(0, NULL, NULL, get_attrib_value,
tvbparse_quoted(-1, NULL, NULL, tvbparse_shrink_token_cb,'\"','\\'),
@@ -398,7 +490,7 @@ void init_xml_parser(void) {
tvbparse_set_seq(0,NULL,NULL,after_untag,
tvbparse_char(-1, "<", NULL, NULL, NULL),
tvbparse_char(-1, "/", NULL, NULL, NULL),
- want_name,
+ want_tag_name,
tvbparse_char(-1, ">", NULL, NULL, NULL),
NULL),
tvbparse_set_seq(-1,NULL,before_dtd_doctype,NULL,
@@ -435,7 +527,7 @@ void init_xml_parser(void) {
NULL),
tvbparse_set_seq(-1, NULL, before_tag, NULL,
tvbparse_char(-1,"<",NULL,NULL,NULL),
- want_name,
+ want_tag_name,
tvbparse_set_oneof(-1,NULL,NULL,NULL,
tvbparse_set_seq(-1,NULL,NULL,NULL,
want_attributes,
@@ -452,21 +544,19 @@ void init_xml_parser(void) {
}
-xml_names_t* xml_new_namespace(GHashTable* hash, gchar* name, gchar* longname, gchar* blurb, ...) {
- xml_names_t* ns = g_malloc(sizeof(xml_names_t));
+xml_ns_t* xml_new_namespace(GHashTable* hash, gchar* name, ...) {
+ xml_ns_t* ns = g_malloc(sizeof(xml_ns_t));
va_list ap;
gchar* attr_name;
ns->name = g_strdup(name);
- ns->longname = g_strdup(longname);
- ns->blurb = g_strdup(blurb);
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);
- va_start(ap,blurb);
+ va_start(ap,name);
while(( attr_name = va_arg(ap,gchar*) )) {
int* hfp = g_malloc(sizeof(int));
@@ -481,18 +571,18 @@ xml_names_t* xml_new_namespace(GHashTable* hash, gchar* name, gchar* longname, g
return ns;
}
-void add_xml_attribute_names(gpointer k, gpointer v, gpointer p) {
- gchar* basename = g_strdup_printf("%s.%s",(gchar*)p,(gchar*)k);
+
+void add_xml_field(GArray* hfs, int* p_id, gchar* name, gchar* fqn) {
hf_register_info hfri;
- hfri.p_id = (int*)v;
- hfri.hfinfo.name = basename;
- hfri.hfinfo.abbrev = basename;
+ hfri.p_id = p_id;
+ hfri.hfinfo.name = name;
+ hfri.hfinfo.abbrev = fqn;
hfri.hfinfo.type = FT_STRING;
hfri.hfinfo.display = BASE_NONE;
hfri.hfinfo.strings = NULL;
hfri.hfinfo.bitmask = 0x0;
- hfri.hfinfo.blurb = basename;
+ hfri.hfinfo.blurb = "";
hfri.hfinfo.id = 0;
hfri.hfinfo.parent = 0;
hfri.hfinfo.ref_count = 0;
@@ -500,55 +590,469 @@ void add_xml_attribute_names(gpointer k, gpointer v, gpointer p) {
hfri.hfinfo.same_name_next = NULL;
hfri.hfinfo.same_name_prev = NULL;
- g_array_append_val(hf,hfri);
+ g_array_append_val(hfs,hfri);
+}
+
+void add_xml_attribute_names(gpointer k, gpointer v, gpointer p) {
+ 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);
}
+
void add_xmlpi_namespace(gpointer k _U_, gpointer v, gpointer p) {
- xml_names_t* ns = v;
- hf_register_info hfri;
+ xml_ns_t* ns = v;
gchar* basename = g_strdup_printf("%s.%s",(gchar*)p,ns->name);
gint* ett_p = &(ns->ett);
-
- hfri.p_id = &(ns->hf_tag);
- hfri.hfinfo.name = basename;
- hfri.hfinfo.abbrev = basename;
- hfri.hfinfo.type = FT_STRING;
- hfri.hfinfo.display = BASE_NONE;
- hfri.hfinfo.strings = NULL;
- hfri.hfinfo.bitmask = 0x0;
- hfri.hfinfo.blurb = basename;
- 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;
+ struct _attr_reg_data d;
+
+ add_xml_field(hf_arr, &(ns->hf_tag), basename, basename);
- g_array_append_val(hf,hfri);
g_array_append_val(ett_arr,ett_p);
- g_hash_table_foreach(ns->attributes,add_xml_attribute_names,basename);
+ d.basename = basename;
+ d.hf = hf_arr;
+
+ g_hash_table_foreach(ns->attributes,add_xml_attribute_names,&d);
}
-void init_xml_names(void) {
- xml_names_t* xmlpi_xml_ns;
+static void destroy_dtd_data(dtd_build_data_t* dtd_data) {
+ 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);
+
+ if(dtd_data->location) g_free(dtd_data->location);
+ g_string_free(dtd_data->error,TRUE);
+
+
+ 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);
+ }
+
+ g_ptr_array_free(dtd_data->elements,FALSE);
+
+ while(dtd_data->attributes->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);
+ }
+
+ g_ptr_array_free(dtd_data->attributes,FALSE);
+
+ 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;
+
+ *value = -1;
+ g_hash_table_insert(dst,key,value);
+
+}
+
+static GHashTable* copy_attributes_hash(GHashTable* src) {
+ GHashTable* dst = g_hash_table_new(g_str_hash,g_str_equal);
+
+ g_hash_table_foreach(src,copy_attrib_item,dst);
+
+ 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;
+
+ 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();
+
+ 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));
+ }
+
+ return new_item;
+}
+
+static gchar* fully_qualified_name(GPtrArray* hier, gchar* name) {
+ guint i;
+ GString* s = g_string_new("");
+ gchar* str;
+
+ for (i = 0; i < hier->len; i++) {
+ g_string_sprintfa(s, "%s.",(gchar*)g_ptr_array_index(hier,i));
+ }
+
+ g_string_append(s,name);
+ str = s->str;
+ g_string_free(s,FALSE);
+
+ return str;
+}
+
+
+static xml_ns_t* make_xml_hier(gchar* elem_name,
+ xml_ns_t* root,
+ GHashTable* elements,
+ GPtrArray* hier,
+ GString* error,
+ GArray* hfs,
+ GArray* etts) {
+ xml_ns_t* new;
+ xml_ns_t* orig = g_hash_table_lookup(elements,elem_name);
+ gchar* fqn;
+ gint* ett_p;
+ struct _attr_reg_data d;
+ gboolean recurred = FALSE;
+
+ if ( g_str_equal(elem_name,root->name) ) {
+ return NULL;
+ }
+
+ if (! orig) {
+ g_string_sprintfa(error,"element '%s' is not defined\n", elem_name);
+ return NULL;
+ }
+
+ fqn = fully_qualified_name(hier,elem_name);
+
+ new = duplicate_element(orig);
+ new->fqn = fqn;
+
+ add_xml_field(hfs, &(new->hf_tag), elem_name, fqn);
+ add_xml_field(hfs, &(new->hf_cdata), elem_name, fqn);
+
+ ett_p = &new->ett;
+ g_array_append_val(etts,ett_p);
+
+ d.basename = fqn;
+ d.hf = hfs;
+
+ 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;
+ guint i;
+
+ for (i = 0; i < hier->len; i++) {
+ if( strcmp(child_name,(gchar*) g_ptr_array_index(hier,i) ) == 0 ) {
+ recurred = TRUE;
+ }
+ }
+
+ if( ! recurred ) {
+ g_ptr_array_add(hier,elem_name);
+ child_element = make_xml_hier(child_name, root, elements, hier,error,hfs,etts);
+ g_ptr_array_remove_index_fast(hier,hier->len - 1);
+ }
+
+ if (child_element) {
+ g_hash_table_insert(new->elements,child_element->name,child_element);
+ }
+ }
+
+ g_ptr_array_free(new->element_names,FALSE);
+ new->element_names = NULL;
+ return new;
+}
+
+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();
+
+ /* 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));
+
+ /* we will use the first element found as root in case no other one was given. */
+ if (root_name == NULL) root_name = g_strdup(nl->name);
+
+ 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);
+
+ g_hash_table_insert(elements,element->name,element);
+ g_ptr_array_add(element_names,element->name);
+
+ 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);
+
+ if (!element) {
+ g_string_sprintfa(errors,"no element %s is been defined\n", nl->name);
+
+ goto next_attribute;
+ }
+
+ while(nl->list->len) {
+ gchar* name = g_ptr_array_remove_index(nl->list,0);
+ int* id_p = g_malloc(sizeof(int));
+
+ *id_p = -1;
+ g_hash_table_insert(element->attributes,name,id_p);
+ }
+
+next_attribute:
+ g_free(nl->name);
+ g_ptr_array_free(nl->list,FALSE);
+ g_free(nl);
+ }
+
+
+
+ if( dtd_data->proto_root ) {
+ if(root_name) g_free(root_name);
+ root_name = g_strdup(dtd_data->proto_root);
+ }
+
+ hier = g_ptr_array_new();
+
+ if( ! dtd_data->proto_name ) {
+ hfs = hf_arr;
+ etts = ett_arr;
+ g_ptr_array_add(hier,g_strdup("xml"));
+ root_element = &xml_ns;
+ } else {
+ hfs = g_array_new(FALSE,FALSE,sizeof(hf_register_info));
+ etts = g_array_new(FALSE,FALSE,sizeof(gint*));
+ }
+
+ root_element = g_malloc(sizeof(xml_ns_t));
+ root_element->name = g_strdup(root_name);
+ root_element->fqn = root_element->name;
+ 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;
+
+ if (dtd_data->recursion) {
+ xml_ns_t* orig_root;
+
+ make_xml_hier(root_name, root_element, elements,hier,errors,hfs,etts);
+
+ g_hash_table_insert(root_element->elements,root_element->name,root_element);
+
+ orig_root = g_hash_table_lookup(elements,root_name);
+
+ if(orig_root) {
+ struct _attr_reg_data d;
+
+ d.basename = root_name;
+ 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);
+ }
+
+ g_ptr_array_add(hier,root_name);
+
+ while(root_element->element_names->len) {
+ curr_name = g_ptr_array_remove_index(root_element->element_names,0);
+
+ if( ! g_hash_table_lookup(root_element->elements,curr_name) ) {
+ xml_ns_t* new = make_xml_hier(curr_name, root_element, elements,hier,errors,hfs,etts);
+ g_hash_table_insert(root_element->elements,new->name,new);
+ }
+ }
+ } else {
+ g_ptr_array_add(hier,root_name);
+
+ 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;
+
+ curr_name = g_ptr_array_remove_index(root_element->element_names,0);
+ new = duplicate_element(g_hash_table_lookup(elements,curr_name));
+ new->fqn = fully_qualified_name(hier, curr_name);
+
+ 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);
+
+ g_hash_table_insert(root_element->elements,new->name,new);
+
+ }
+ }
+
+ g_ptr_array_free(element_names,FALSE);
+
+ g_ptr_array_free(hier,FALSE);
+
+ if( dtd_data->proto_name ) {
+ gint* ett_p;
+
+ if ( ! dtd_data->description) {
+ dtd_data->description = g_strdup(root_name);
+ }
+
+ 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);
+
+ root_element->hf_tag = proto_register_protocol(dtd_data->description, dtd_data->proto_name, root_element->name);
+ proto_register_field_array(root_element->hf_tag, (hf_register_info*)hfs->data, hfs->len);
+ proto_register_subtree_array((gint**)etts->data, etts->len);
+
+ if (dtd_data->media_type) {
+ g_hash_table_insert(media_types,dtd_data->media_type,root_element);
+ dtd_data->media_type = NULL;
+ }
+
+ dtd_data->description = NULL;
+ dtd_data->proto_name = NULL;
+ g_array_free(hfs,FALSE);
+ g_array_free(etts,FALSE);
+ }
+
+ g_hash_table_insert(xml_ns.elements,root_element->name,root_element);
+
+ destroy_dtd_data(dtd_data);
+}
+
+#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
+
+void init_xml_names(void) {
+ xml_ns_t* xmlpi_xml_ns;
+ guint i;
+ DIRECTORY_T* dir;
+ const FILE_T* file;
+ const gchar* filename;
+ gchar* dirname;
+
+#if GLIB_MAJOR_VERSION >= 2
+ GError** dummy = g_malloc(sizeof(GError *));
+ *dummy = NULL;
+#endif
+
xmpli_names = g_hash_table_new(g_str_hash,g_str_equal);
media_types = g_hash_table_new(g_str_hash,g_str_equal);
- unknown_ns.elements = g_hash_table_new(g_str_hash,g_str_equal);
- unknown_ns.attributes = g_hash_table_new(g_str_hash,g_str_equal);
+ 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);
- xmlpi_xml_ns = xml_new_namespace(xmpli_names,"xml","XML XMLPI","XML XMLPI",
- "version","encoding","standalone",NULL);
+ xmlpi_xml_ns = xml_new_namespace(xmpli_names,"xml","version","encoding","standalone",NULL);
g_hash_table_destroy(xmlpi_xml_ns->elements);
xmlpi_xml_ns->elements = NULL;
+
+
+ dirname = get_persconffile_path("dtds", FALSE);
+
+ if (test_for_directory(dirname) != EISDIR) {
+ dirname = get_datafile_path("dtds");
+ }
+
+ if (test_for_directory(dirname) == EISDIR) {
+
+ if ((dir = OPENDIR_OP(dirname)) != NULL) {
+ while ((file = DIRGETNEXT_OP(dir)) != NULL) {
+ guint namelen;
+ filename = GETFNAME_OP(file);
+
+ namelen = strlen(filename);
+ if ( namelen > 4 && ( g_strcasecmp(filename+(namelen-4),".dtd") == 0 ) ) {
+ GString* errors = g_string_new("");
+ GString* preparsed = dtd_preparse(dirname, filename, errors);
+ dtd_build_data_t* dtd_data;
+
+ if (errors->len) {
+ report_failure("Dtd Preparser in file %s%c%s: %s",dirname,G_DIR_SEPARATOR,filename,errors->str);
+ continue;
+ }
+
+ dtd_data = dtd_parse(preparsed);
+
+ g_string_free(preparsed,TRUE);
+
+ 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;
+ }
+
+ register_dtd(dtd_data,errors);
+
+ 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;
+ }
+ }
+ }
+
+ CLOSEDIR_OP(dir);
+ }
+ }
+
+ 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);
+ }
+ }
g_hash_table_foreach(xmpli_names,add_xmlpi_namespace,"xml.xmlpi");
-}
+#if GLIB_MAJOR_VERSION >= 2
+ g_free(dummy);
+#endif
+}
void
proto_register_xml(void) {
@@ -568,25 +1072,30 @@ proto_register_xml(void) {
{ &hf_dtd_tag, {"DTD Tag", "xml.dtdtag", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }},
{ &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 }},
- { &hf_junk, {"Unknown", "xml.unknown", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}
+ { &xml_ns.hf_cdata, {"Unknown", "xml.unknown", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}
};
- hf = g_array_new(FALSE,FALSE,sizeof(hf_register_info));
+ hf_arr = g_array_new(FALSE,FALSE,sizeof(hf_register_info));
ett_arr = g_array_new(FALSE,FALSE,sizeof(gint*));
- g_array_append_vals(hf,hf_base,array_length(hf_base));
+ g_array_append_vals(hf_arr,hf_base,array_length(hf_base));
g_array_append_vals(ett_arr,ett_base,array_length(ett_base));
init_xml_names();
- xml_ns.hf_tag = proto_register_protocol(xml_ns.blurb, xml_ns.longname, xml_ns.name);
+ xml_ns.hf_tag = proto_register_protocol("eXtensible Markup Language", "XML", xml_ns.name);
- proto_register_field_array(xml_ns.hf_tag, (hf_register_info*)hf->data, hf->len);
+ proto_register_field_array(xml_ns.hf_tag, (hf_register_info*)hf_arr->data, hf_arr->len);
proto_register_subtree_array((gint**)ett_arr->data, ett_arr->len);
register_dissector("xml", dissect_xml, xml_ns.hf_tag);
init_xml_parser();
+
+}
+
+void add_dissector_media(gpointer k, gpointer v _U_, gpointer p _U_) {
+ dissector_add_string("media_type", (gchar*)k, xml_handle);
}
void
@@ -595,33 +1104,6 @@ proto_reg_handoff_xml(void)
xml_handle = find_dissector("xml");
- dissector_add_string("media_type", "text/xml", xml_handle);
- dissector_add_string("media_type", "application/xml", xml_handle);
- dissector_add_string("media_type", "application/soap+xml", xml_handle);
- dissector_add_string("media_type", "application/xml-dtd", xml_handle);
- /* WAP and OMA XML media */
- dissector_add_string("media_type", "text/vnd.wap.wml", xml_handle);
- dissector_add_string("media_type", "text/vnd.wap.si", xml_handle);
- dissector_add_string("media_type", "text/vnd.wap.sl", xml_handle);
- dissector_add_string("media_type", "text/vnd.wap.co", xml_handle);
- dissector_add_string("media_type", "text/vnd.wap.emn", xml_handle);
- dissector_add_string("media_type", "application/vnd.wv.csp+xml", xml_handle);
- /* The Extensible Markup Language (XML) Configuration Access Protocol (XCAP)
- * draft-ietf-simple-xcap-06
- */
- dissector_add_string("media_type", "application/xcap-el+xml", xml_handle);
- dissector_add_string("media_type", "application/xcap-att+xml", xml_handle);
- dissector_add_string("media_type", "application/xcap-error+xml", xml_handle);
- dissector_add_string("media_type", "application/xcap-caps+xml", xml_handle);
- /* draft-ietf-simple-presence-rules-02 */
- dissector_add_string("media_type", "application/auth-policy+xml", xml_handle);
- /* Other */
- dissector_add_string("media_type", "application/smil", xml_handle);
- dissector_add_string("media_type", "application/cpim-pidf+xml", xml_handle);
- dissector_add_string("media_type", "application/rdf+xml", xml_handle);
- dissector_add_string("media_type", "application/xslt+xml", xml_handle);
- dissector_add_string("media_type", "application/mathml+xml", xml_handle);
- dissector_add_string("media_type", "image/svg+xml", xml_handle);
- dissector_add_string("media_type", "application/vnd.wv.csp.xml", xml_handle);
+ g_hash_table_foreach(media_types,add_dissector_media,NULL);
}