aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-wbxml.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2015-08-09 18:33:30 -0400
committerAnders Broman <a.broman58@gmail.com>2015-08-10 04:47:19 +0000
commitc462f1b54ed4459c0c93dabbf5fe30f224e796a6 (patch)
tree8be86a109a8ef268fe54022886c4b26e798a3fb5 /epan/dissectors/packet-wbxml.c
parent6d8b4afb49f766cfdb4bb7bae0433ec077c9bb50 (diff)
Eliminate proto_tree_add_text from packet-wbxml.c
While I was at it, some (mostly) duplicate functionality allowed rearranging of functions to eliminate most forward declarations. Change-Id: I2d7027d336c391d81dfe81c7a1ebf0d56c0826b2 Reviewed-on: https://code.wireshark.org/review/9951 Reviewed-by: Michael Mann <mmann78@netscape.net> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-wbxml.c')
-rw-r--r--epan/dissectors/packet-wbxml.c1992
1 files changed, 756 insertions, 1236 deletions
diff --git a/epan/dissectors/packet-wbxml.c b/epan/dissectors/packet-wbxml.c
index 143019f1a2..0bbf0b8e6a 100644
--- a/epan/dissectors/packet-wbxml.c
+++ b/epan/dissectors/packet-wbxml.c
@@ -48,6 +48,7 @@
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <epan/prefs.h>
+#include <epan/expert.h>
/* We need the function tvb_get_guintvar() */
#include "packet-wap.h"
@@ -130,6 +131,56 @@ void proto_reg_handoff_wbxml(void);
* TODO: investigate this and provide correct decoding at all times.
*/
+
+/************************** Variable declarations **************************/
+
+
+/* Initialize the protocol and registered fields */
+static int proto_wbxml = -1;
+static int hf_wbxml_version = -1;
+static int hf_wbxml_public_id_known = -1;
+static int hf_wbxml_public_id_literal = -1;
+static int hf_wbxml_charset = -1;
+static int hf_wbxml_string_table_item = -1;
+static int hf_wbxml_switch_page = -1;
+static int hf_wbxml_known_tag = -1;
+static int hf_wbxml_end_known_tag = -1;
+static int hf_wbxml_end_known_tag_uint = -1;
+static int hf_wbxml_str_i = -1;
+static int hf_wbxml_str_t = -1;
+static int hf_wbxml_opaque_data = -1;
+static int hf_wbxml_entity = -1;
+static int hf_wbxml_literal = -1;
+static int hf_wbxml_ext_i = -1;
+static int hf_wbxml_ext_t = -1;
+static int hf_wbxml_extension_token = -1;
+static int hf_wbxml_reserved_2 = -1;
+static int hf_wbxml_invalid_token = -1;
+static int hf_wbxml_known_attrvalue = -1;
+static int hf_wbxml_known_attrstart = -1;
+static int hf_wbxml_end_literal_tag = -1;
+static int hf_wbxml_literal_a = -1;
+static int hf_wbxml_literal_c = -1;
+static int hf_wbxml_literal_ac = -1;
+static int hf_wbxml_end_pi = -1;
+static int hf_wbxml_end_attribute_list = -1;
+static int hf_wbxml_pi_xml = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_wbxml = -1;
+static gint ett_wbxml_str_tbl = -1;
+static gint ett_wbxml_content = -1;
+static gint ett_wbxml_tags = -1;
+
+static expert_field ei_wbxml_data_not_shown = EI_INIT;
+static expert_field ei_wbxml_content_type_not_supported = EI_INIT;
+static expert_field ei_wbxml_content_type_disabled = EI_INIT;
+
+/* WBXML Preferences */
+static gboolean skip_wbxml_token_mapping = FALSE;
+static gboolean disable_wbxml_token_parsing = FALSE;
+
+
typedef struct _value_valuestring {
guint32 value;
const value_string *valstrptr;
@@ -1044,26 +1095,6 @@ typedef struct _wbxml_literal_list {
const wbxml_decoding *map;
} wbxml_literal_list;
-/************************** Variable declarations **************************/
-
-
-/* Initialize the protocol and registered fields */
-static int proto_wbxml = -1;
-static int hf_wbxml_version = -1;
-static int hf_wbxml_public_id_known = -1;
-static int hf_wbxml_public_id_literal = -1;
-static int hf_wbxml_charset = -1;
-
-/* Initialize the subtree pointers */
-static gint ett_wbxml = -1;
-static gint ett_wbxml_str_tbl = -1;
-static gint ett_wbxml_content = -1;
-
-/* WBXML Preferences */
-static gboolean skip_wbxml_token_mapping = FALSE;
-static gboolean disable_wbxml_token_parsing = FALSE;
-
-
/**************** WBXML related declarations and definitions ****************/
@@ -6912,288 +6943,6 @@ map_token (const value_valuestring *token_map, guint8 codepage, guint8 token) {
-
-
-/************************** Function prototypes **************************/
-
-
-static void
-dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-
-static void
-dissect_uaprof(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-
-static void
-dissect_wbxml_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- const wbxml_decoding *override_content_map);
-
-/* Parse and display the WBXML string table */
-static void
-show_wbxml_string_table (proto_tree *tree, tvbuff_t *tvb, guint32 str_tbl,
- guint32 str_tbl_len);
-
-/* Parse data while in STAG state */
-static guint32
-parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
- guint32 str_tbl, guint8 *level, guint8 *codepage_stag, guint8 *codepage_attr);
-
-/* Parse data while in STAG state;
- * interpret tokens as defined by content type */
-static guint32
-parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
- guint32 str_tbl, guint8 *level, guint8 *codepage_stag, guint8 *codepage_attr,
- const wbxml_decoding *map);
-
-/* Parse data while in ATTR state */
-static guint32
-parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
- guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr);
-
-/* Parse data while in ATTR state;
- * interpret tokens as defined by content type */
-static guint32
-parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
- guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr,
- const wbxml_decoding *map);
-
-
-/****************** WBXML protocol dissection functions ******************/
-
-
-static void
-dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- dissect_wbxml_common(tvb, pinfo, tree, NULL);
-}
-
-static void
-dissect_uaprof(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- dissect_wbxml_common(tvb, pinfo, tree, &decode_uaprof_wap_248);
-}
-
-/* Code to actually dissect the packets */
-static void
-dissect_wbxml_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- const wbxml_decoding *override_content_map)
-{
- /* Set up structures needed to add the protocol subtree and manage it */
- proto_item *ti;
- proto_tree *wbxml_tree; /* Main WBXML tree */
- proto_tree *wbxml_str_tbl_tree; /* String table subtree */
- proto_tree *wbxml_content_tree; /* Content subtree */
- guint8 version;
- guint offset = 0;
- guint32 len;
- guint32 charset = 0;
- guint32 charset_len = 0;
- guint32 publicid;
- guint32 publicid_index = 0;
- guint32 publicid_len;
- guint32 str_tbl;
- guint32 str_tbl_len;
- guint32 str_tbl_len_len = 0;
- guint8 level = 0; /* WBXML recursion level */
- const wbxml_decoding *content_map = NULL;
- gchar *summary = NULL;
- guint8 codepage_stag = 0;
- guint8 codepage_attr = 0;
-
- DebugLog(("dissect_wbxml: Dissecting packet %u\n", pinfo->fd->num));
- /* WBXML format
- *
- * Version 1.0: version publicid strtbl BODY
- * Version 1.x: version publicid charset strtbl BODY
- *
- * Last valid format: WBXML 1.3
- */
- switch ( version = tvb_get_guint8 (tvb, 0) ) {
- case 0x00: /* WBXML/1.0 */
- break;
-
- case 0x01: /* WBXML/1.1 */
- case 0x02: /* WBXML/1.2 */
- case 0x03: /* WBXML/1.3 */
- break;
-
- default:
- /* Put some information here, so that the user knows what's going on. */
-
- /* Add summary to INFO column if it is enabled */
- col_append_fstr(pinfo->cinfo, COL_INFO, " (Unknown WBXML version 0x%02x)", version);
- ti = proto_tree_add_item (tree, proto_wbxml, tvb, 0, -1, ENC_NA);
- proto_item_append_text(ti, ", Unknown version 0x%02x", version);
- return;
- }
-
- /* In order to properly construct the packet summary,
- * I need to read the entire WBXML header
- * up to the string table length.
- */
-
- /* Public ID */
- publicid = tvb_get_guintvar(tvb, 1, &publicid_len);
- if (! publicid) {
- /* Public identifier in string table */
- publicid_index = tvb_get_guintvar (tvb, 1+publicid_len, &len);
- publicid_len += len;
- }
- offset = 1 + publicid_len;
-
- /* Version-specific handling of Charset */
- switch ( version ) {
- case 0x00: /* WBXML/1.0 */
- /* No charset */
- break;
-
- case 0x01: /* WBXML/1.1 */
- case 0x02: /* WBXML/1.2 */
- case 0x03: /* WBXML/1.3 */
- /* Get charset */
- charset = tvb_get_guintvar (tvb, offset, &charset_len);
- offset += charset_len;
- break;
-
- default: /* Impossible since we returned already earlier */
- DISSECTOR_ASSERT_NOT_REACHED();
- break;
- }
-
- /* String table: read string table length in bytes */
- tvb_get_guintvar (tvb, offset, &str_tbl_len_len);
- str_tbl = offset + str_tbl_len_len; /* Start of 1st string in string table */
-
- /* Compose the summary line */
- if ( publicid ) {
- summary = wmem_strdup_printf(wmem_packet_scope(), "%s, Public ID: \"%s\"",
- val_to_str_ext (version, &vals_wbxml_versions_ext, "(unknown 0x%x)"),
- val_to_str_ext (publicid, &vals_wbxml_public_ids_ext, "(unknown 0x%x)"));
- } else {
- /* Read length of Public ID from string table */
- len = tvb_strsize (tvb, str_tbl + publicid_index);
- summary = wmem_strdup_printf(wmem_packet_scope(), "%s, Public ID: \"%s\"",
- val_to_str_ext (version, &vals_wbxml_versions_ext, "(unknown 0x%x)"),
- tvb_format_text (tvb, str_tbl + publicid_index, len - 1));
- }
-
- /* Add summary to INFO column if it is enabled */
- col_append_fstr(pinfo->cinfo, COL_INFO, " (WBXML %s)", summary);
-
- /* create display subtree for the protocol */
- ti = proto_tree_add_item (tree, proto_wbxml, tvb, 0, -1, ENC_NA);
- proto_item_append_text(ti, ", Version: %s", summary);
-
- /*
- * Now show the protocol subtree, if tree is set.
- */
- if ( tree ) {
- wbxml_tree = proto_item_add_subtree(ti, ett_wbxml);
-
- /* WBXML Version */
- proto_tree_add_uint (wbxml_tree, hf_wbxml_version,
- tvb, 0, 1, version);
-
- /* Public ID */
- if (publicid) { /* Known Public ID */
- proto_tree_add_uint(wbxml_tree, hf_wbxml_public_id_known,
- tvb, 1, publicid_len, publicid);
- } else { /* Public identifier in string table */
- proto_tree_add_item (wbxml_tree, hf_wbxml_public_id_literal,
- tvb, 1, publicid_len, ENC_ASCII|ENC_NA);
- }
- offset = 1 + publicid_len;
-
- if ( version ) { /* Charset */
- proto_tree_add_uint (wbxml_tree, hf_wbxml_charset,
- tvb, 1 + publicid_len, charset_len, charset);
- offset += charset_len;
- }
-
- str_tbl_len = tvb_get_guintvar (tvb, offset, &len);
- str_tbl = offset + len; /* Start of 1st string in string table */
-
- /* String Table */
- ti = proto_tree_add_text(wbxml_tree,
- tvb, offset, len + str_tbl_len, "String table: %u bytes",
- str_tbl_len);
-
- if (wbxml_tree && str_tbl_len) { /* Display string table as subtree */
- wbxml_str_tbl_tree = proto_item_add_subtree (ti,
- ett_wbxml_str_tbl);
- show_wbxml_string_table (wbxml_str_tbl_tree, tvb,
- str_tbl, str_tbl_len);
- }
-
- /* Data starts HERE */
- offset += len + str_tbl_len;
-
- /* The WBXML BODY starts here */
- if (disable_wbxml_token_parsing) {
- proto_tree_add_text (wbxml_tree, tvb, offset, -1,
- "Data representation not shown "
- "(edit WBXML preferences to show)");
- return;
- } /* Else: render the WBXML tokens */
- wbxml_content_tree = proto_tree_add_subtree(wbxml_tree, tvb, offset, -1,
- ett_wbxml_content, &ti, "Data representation");
-
- /* The parse_wbxml_X() functions will process the content correctly,
- * irrespective of the WBXML version used. For the WBXML body, this
- * means that there is a different processing for the global token
- * RESERVED_2 (WBXML 1.0) or OPAQUE (WBXML 1.x with x > 0). */
- if (wbxml_tree) { /* Show only if visible */
- if (override_content_map != NULL) {
- content_map = override_content_map;
- proto_item_append_text(ti,
- " is based on: %s",
- content_map->name);
- } else {
- /* Retrieve the content token mapping if available */
- content_map = get_wbxml_decoding_from_public_id (publicid);
- if (! content_map) {
- content_map = get_wbxml_decoding_from_content_type(
- pinfo->match_string, tvb, offset);
- if (! content_map) {
- proto_tree_add_text (wbxml_content_tree,
- tvb, offset, -1,
- "[Rendering of this content type"
- " not (yet) supported]");
- } else {
- proto_item_append_text(ti,
- " is based on Content-Type: %s "
- "(chosen decoding: %s)",
- pinfo->match_string, content_map->name);
- }
- }
- }
- if (content_map && skip_wbxml_token_mapping) {
- proto_tree_add_text (wbxml_content_tree,
- tvb, offset, -1,
- "[Rendering of this content type"
- " has been disabled "
- "(edit WBXML preferences to enable)]");
- content_map = NULL;
- }
- proto_tree_add_text (wbxml_content_tree, tvb,
- offset, -1,
- "Level | State | Codepage "
- "| WBXML Token Description "
- "| Rendering");
- if (content_map) {
- len = parse_wbxml_tag_defined (wbxml_content_tree,
- tvb, offset, str_tbl, &level, &codepage_stag,
- &codepage_attr, content_map);
- } else {
- /* Default: WBXML only, no interpretation of the content */
- len = parse_wbxml_tag (wbxml_content_tree, tvb, offset,
- str_tbl, &level, &codepage_stag, &codepage_attr);
- }
- }
- return;
- }
-}
-
-
/* Parse and display the WBXML string table (in a 3-column table format).
* This function displays:
* - the offset in the string table,
@@ -7207,15 +6956,12 @@ show_wbxml_string_table (proto_tree *tree, tvbuff_t *tvb, guint32 str_tbl,
guint32 off = str_tbl;
guint32 len = 0;
guint32 end = str_tbl + str_tbl_len;
+ gchar* str;
- proto_tree_add_text (tree, tvb, off, end,
- "Start | Length | String");
while (off < end) {
len = tvb_strsize (tvb, off);
- proto_tree_add_text (tree, tvb, off, len,
- "%6d | %6d | '%s'",
- off - str_tbl, len,
- tvb_format_text (tvb, off, len-1));
+ str = tvb_format_text (tvb, off, len-1);
+ proto_tree_add_string_format(tree, hf_wbxml_string_table_item, tvb, off, len, str, "%s", str);
off += len;
}
}
@@ -7268,108 +7014,96 @@ static const char * Indent (guint8 level) {
* - A code page switch only applies to the single token that follows.
*/
+/**************************
+ * WBXML Attribute tokens *
+ **************************
+ * Bit Mask : Example
+ * -------------------
+ * 0... .... : attr= (attribute name)
+ * href='http://' (attribute name with start of attribute value)
+ * 1... .... : 'www.' (attribute value, or part of it)
+ *
+ */
+
/* This function parses the WBXML and maps known token interpretations
* to the WBXML tokens. As a result, the original XML document can be
* recreated. Indentation is generated in order to ease reading.
*
- * Attribute parsing is done in parse_wbxml_attribute_list_defined().
+ * This function performs attribute list parsing.
*
* The wbxml_decoding entry *map contains the actual token mapping.
*
- * NOTE: In order to parse the content, some recursion is required.
- * However, for performance reasons, recursion has been avoided
- * where possible (tags without content within tags with content).
- * This is achieved by means of the parsing_tag_content and tag_save*
- * variables.
- *
* NOTE: See above for known token mappings.
- *
- * NOTE: As tags can be opened and closed, a tag representation lookup
- * may happen once or twice for a given tag. For efficiency reasons,
- * the literal tag value is stored and used throughout the code.
- * With the introduction of code page support, this solution is robust
- * as the lookup only occurs once, removing the need for storage of
- * the used code page.
*/
static guint32
-parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
- guint32 str_tbl, guint8 *level, guint8 *codepage_stag, guint8 *codepage_attr,
- const wbxml_decoding *map)
+parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
+ guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr,
+ const wbxml_decoding *map)
{
- guint32 tvb_len = tvb_reported_length (tvb);
- guint32 off = offset;
+ guint32 tvb_len = tvb_reported_length (tvb);
+ guint32 off = offset;
guint32 len;
guint str_len;
guint32 ent;
guint32 idx;
guint8 peek;
- guint32 tag_len; /* Length of the index (uintvar) from a LITERAL tag */
- guint8 tag_save_known = 0; /* Will contain peek & 0x3F (tag identity) */
- guint8 tag_new_known = 0; /* Will contain peek & 0x3F (tag identity) */
- const char *tag_save_literal; /* Will contain the LITERAL tag identity */
- const char *tag_new_literal; /* Will contain the LITERAL tag identity */
- guint8 parsing_tag_content = FALSE; /* Are we parsing content from a
- tag with content: <x>Content</x>
-
- The initial state is FALSE.
- This state will trigger recursion. */
- tag_save_literal = NULL; /* Prevents compiler warning */
+ guint8 attr_save_known = 0; /* Will contain peek & 0x3F (attr identity) */
+ const char *attr_save_literal = NULL; /* Will contain the LITERAL attr identity */
+ gchar *str;
- DebugLog(("parse_wbxml_tag_defined (level = %u, offset = %u)\n", *level, offset));
+ DebugLog(("parse_wbxml_attr_defined (level = %u, offset = %u)\n", level, offset));
+ /* Parse attributes */
while (off < tvb_len) {
peek = tvb_get_guint8 (tvb, off);
- DebugLog(("STAG: (top of while) level = %3u, peek = 0x%02X, off = %u, tvb_len = %u\n", *level, peek, off, tvb_len));
- if ((peek & 0x3F) < 4) switch (peek) { /* Global tokens in state = STAG
- but not the LITERAL tokens */
+ DebugLog(("ATTR: (top of while) level = %3u, peek = 0x%02X, "
+ "off = %u, tvb_len = %u\n", level, peek, off, tvb_len));
+ if ((peek & 0x3F) < 5) switch (peek) { /* Global tokens
+ in state = ATTR */
case 0x00: /* SWITCH_PAGE */
- *codepage_stag = tvb_get_guint8 (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 2,
- " | Tag | T -->%3d "
- "| SWITCH_PAGE (Tag code page) "
- "|",
- *codepage_stag);
+ *codepage_attr = tvb_get_guint8 (tvb, off+1);
+ proto_tree_add_uint_format(tree, hf_wbxml_switch_page, tvb, off, 2, *codepage_attr,
+ " | Attr | A -->%3d | SWITCH_PAGE (Attr code page) |",
+ *codepage_attr);
off += 2;
break;
- case 0x01: /* END: only possible for Tag with Content */
- if (tag_save_known) { /* Known TAG */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| END (Known Tag 0x%02X) "
- "| %s</%s>",
- *level, *codepage_stag,
- tag_save_known, Indent (*level),
- tag_save_literal); /* We already looked it up! */
- } else { /* Literal TAG */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| END (Literal Tag) "
- "| %s</%s>",
- *level, *codepage_stag, Indent (*level),
- tag_save_literal ? tag_save_literal : "");
- }
- (*level)--;
+ case 0x01: /* END */
+ /* BEWARE
+ * The Attribute END token means either ">" or "/>"
+ * and as a consequence both must be treated separately.
+ * This is done in the TAG state parser.
+ */
off++;
- /* Reset code page: not needed as return from recursion */
- DebugLog(("STAG: level = %u, Return: len = %u\n", *level, off - offset));
+ DebugLog(("ATTR: level = %u, Return: len = %u\n",
+ level, off - offset));
return (off - offset);
case 0x02: /* ENTITY */
ent = tvb_get_guintvar (tvb, off+1, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| ENTITY "
- "| %s'&#%u;'",
- *level, *codepage_stag, Indent (*level), ent);
+ proto_tree_add_uint_format(tree, hf_wbxml_entity, tvb, off, 1+len, ent,
+ " %3d | Attr | A %3d | ENTITY | %s'&#%u;'",
+ level, *codepage_attr, Indent (level), ent);
off += 1+len;
break;
case 0x03: /* STR_I */
len = tvb_strsize (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| STR_I (Inline string) "
- "| %s\'%s\'",
- *level, *codepage_stag, Indent(*level),
- tvb_format_text (tvb, off+1, len-1));
+ str = tvb_format_text (tvb, off+1, len-1);
+ proto_tree_add_string_format(tree, hf_wbxml_str_i, tvb, off, 1+len, str,
+ " %3d | Attr | A %3d | STR_I (Inline string) | %s\'%s\'",
+ level, *codepage_attr, Indent (level), str);
+ off += 1+len;
+ break;
+ case 0x04: /* LITERAL */
+ /* ALWAYS means the start of a new attribute,
+ * and may only contain the NAME of the attribute.
+ */
+ idx = tvb_get_guintvar (tvb, off+1, &len);
+ str_len = tvb_strsize (tvb, str_tbl+idx);
+ attr_save_known = 0;
+ attr_save_literal = tvb_format_text (tvb,
+ str_tbl+idx, str_len-1);
+ proto_tree_add_string_format(tree, hf_wbxml_literal, tvb, off, 1+len, attr_save_literal,
+ " %3d | Attr | A %3d | LITERAL (Literal Attribute) | %s<%s />",
+ level, *codepage_attr, Indent (level), attr_save_literal);
off += 1+len;
break;
case 0x40: /* EXT_I_0 */
@@ -7377,55 +7111,35 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
case 0x42: /* EXT_I_2 */
/* Extension tokens */
len = tvb_strsize (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| EXT_I_%1x (Extension Token) "
- "| %s(%s: \'%s\')",
- *level, *codepage_stag,
- peek & 0x0f, Indent (*level),
- map_token (map->global, 0, peek),
- tvb_format_text (tvb, off+1, len-1));
+ str = tvb_format_text (tvb, off+1, len-1);
+ proto_tree_add_string_format(tree, hf_wbxml_ext_i, tvb, off, 1+len, str,
+ " %3d | Attr | A %3d | EXT_I_%1x (Extension Token) | %s(%s: \'%s\')",
+ level, *codepage_attr, peek & 0x0f, Indent (level),
+ ((map != NULL) ? map_token (map->global, 0, peek) : "Inline string extension"), str);
off += 1+len;
break;
- case 0x43: /* PI */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| PI (XML Processing Instruction) "
- "| %s<?xml",
- *level, *codepage_stag, Indent (*level));
- len = parse_wbxml_attribute_list_defined (tree, tvb, off,
- str_tbl, *level, codepage_attr, map);
- /* Check that there is still room in packet */
- off += len;
- if (off >= tvb_len) {
- DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
- /*
- * TODO - Do we need to free g_malloc()ed memory?
- */
- THROW(ReportedBoundsError);
- }
- proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | T %3d "
- "| END (PI) "
- "| %s?>",
- *level, *codepage_stag, Indent (*level));
- break;
+ /* 0x43 impossible in ATTR state */
+ /* 0x44 impossible in ATTR state */
case 0x80: /* EXT_T_0 */
case 0x81: /* EXT_T_1 */
case 0x82: /* EXT_T_2 */
/* Extension tokens */
idx = tvb_get_guintvar (tvb, off+1, &len);
- { char *s;
- if (map->ext_t[peek & 0x03])
- s = (map->ext_t[peek & 0x03])(tvb, idx, str_tbl);
- else
- s = wmem_strdup_printf(wmem_packet_scope(), "EXT_T_%1x (%s)", peek & 0x03,
- map_token (map->global, 0, peek));
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| EXT_T_%1x (Extension Token) "
- "| %s%s",
- *level, *codepage_stag, peek & 0x0f, Indent (*level),
+ {
+ char *s;
+ if (map != NULL) {
+
+ if (map->ext_t[peek & 0x03])
+ s = (map->ext_t[peek & 0x03])(tvb, idx, str_tbl);
+ else
+ s = wmem_strdup_printf(wmem_packet_scope(), "EXT_T_%1x (%s)", peek & 0x03,
+ map_token (map->global, 0, peek));
+ } else {
+ s = wmem_strdup_printf(wmem_packet_scope(), "Extension Token, integer value: (%u", idx);
+ }
+ proto_tree_add_string_format(tree, hf_wbxml_ext_t, tvb, off, 1+len, s,
+ " %3d | Tag | T %3d | EXT_T_%1x (Extension Token) | %s%s)",
+ level, *codepage_attr, peek & 0x0f, Indent (level),
s);
}
off += 1+len;
@@ -7433,299 +7147,155 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
case 0x83: /* STR_T */
idx = tvb_get_guintvar (tvb, off+1, &len);
str_len = tvb_strsize (tvb, str_tbl+idx);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| STR_T (Tableref string) "
- "| %s\'%s\'",
- *level, *codepage_stag, Indent (*level),
- tvb_format_text (tvb, str_tbl+idx, str_len-1));
+ str = tvb_format_text (tvb, str_tbl+idx, str_len-1);
+ proto_tree_add_string_format(tree, hf_wbxml_str_t, tvb, off, 1+len, str,
+ " %3d | Attr | A %3d | STR_T (Tableref string) | %s\'%s\'",
+ level, *codepage_attr, Indent (level), str);
off += 1+len;
break;
+ /* 0x84 impossible in ATTR state */
case 0xC0: /* EXT_0 */
case 0xC1: /* EXT_1 */
case 0xC2: /* EXT_2 */
/* Extension tokens */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| EXT_%1x (Extension Token) "
- "| %s(%s)",
- *level, *codepage_stag, peek & 0x0f, Indent (*level),
- map_token (map->global, 0, peek));
+ str = (char*)((map != NULL) ? map_token (map->global, 0, peek) : "Single-byte extension");
+ proto_tree_add_string_format(tree, hf_wbxml_extension_token, tvb, off, 1, str,
+ " %3d | Attr | A %3d | EXT_%1x (Extension Token) | %s(%s)",
+ level, *codepage_attr, peek & 0x0f, Indent (level), str);
off++;
break;
case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
- char *str;
- if (tag_save_known) { /* Knwon tag */
- if (map->opaque_binary_tag) {
- str = map->opaque_binary_tag(tvb, off + 1,
- tag_save_known, *codepage_stag, &len);
- } else {
- str = default_opaque_binary_tag(tvb, off + 1,
- tag_save_known, *codepage_stag, &len);
- }
- } else { /* lITERAL tag */
- if (map->opaque_literal_tag) {
- str = map->opaque_literal_tag(tvb, off + 1,
- tag_save_literal, *codepage_stag, &len);
- } else {
- str = default_opaque_literal_tag(tvb, off + 1,
- tag_save_literal, *codepage_stag, &len);
+ if (map != NULL) {
+ char *tmp_str;
+ if (attr_save_known) { /* Knwon attribute */
+ if (map->opaque_binary_attr) {
+ tmp_str = map->opaque_binary_attr(tvb, off + 1,
+ attr_save_known, *codepage_attr, &len);
+ } else {
+ tmp_str = default_opaque_binary_attr(tvb, off + 1,
+ attr_save_known, *codepage_attr, &len);
+ }
+ } else { /* lITERAL attribute */
+ if (map->opaque_literal_tag) {
+ tmp_str = map->opaque_literal_attr(tvb, off + 1,
+ attr_save_literal, *codepage_attr, &len);
+ } else {
+ tmp_str = default_opaque_literal_attr(tvb, off + 1,
+ attr_save_literal, *codepage_attr, &len);
+ }
}
+ proto_tree_add_bytes_format(tree, hf_wbxml_opaque_data, tvb, off, 1 + len, NULL,
+ " %3d | Attr | A %3d | OPAQUE (Opaque data) | %s%s",
+ level, *codepage_attr, Indent (level), tmp_str);
+ off += 1 + len;
+ } else {
+ idx = tvb_get_guintvar (tvb, off+1, &len);
+ proto_tree_add_bytes_format(tree, hf_wbxml_opaque_data, tvb, off, 1 + len + idx, NULL,
+ " %3d | Attr | A %3d | OPAQUE (Opaque data) | %s(%d bytes of opaque data)",
+ level, *codepage_attr, Indent (level), idx);
+ off += 1+len+idx;
}
- proto_tree_add_text (tree, tvb, off, 1 + len,
- " %3d | Tag | T %3d "
- "| OPAQUE (Opaque data) "
- "| %s%s",
- *level, *codepage_stag, Indent (*level), str);
- off += 1 + len;
} else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| RESERVED_2 (Invalid Token!) "
- "| WBXML 1.0 parsing stops here.",
- *level, *codepage_stag);
+ proto_tree_add_none_format(tree, hf_wbxml_reserved_2, tvb, off, 1,
+ " %3d | Attr | A %3d | RESERVED_2 (Invalid Token!) | WBXML 1.0 parsing stops here.",
+ level, *codepage_attr);
/* Stop processing as it is impossible to parse now */
off = tvb_len;
- DebugLog(("STAG: level = %u, Return: len = %u\n", *level, off - offset));
+ DebugLog(("ATTR: level = %u, Return: len = %u\n",
+ level, off - offset));
return (off - offset);
}
break;
-
- /* No default clause, as all cases have been treated */
- } else { /* LITERAL or Known TAG */
- /* We must store the initial tag, and also retrieve the new tag.
- * For efficiency reasons, we store the literal tag representation
- * for known tags too, so we can easily close the tag without the
- * need of a new lookup and avoiding storage of token codepage.
- *
- * There are 4 possibilities:
- *
- * 1. Known tag followed by a known tag
- * 2. Known tag followed by a LITERAL tag
- * 3. LITERAL tag followed by Known tag
- * 4. LITERAL tag followed by LITERAL tag
- */
-
- /* Store the new tag */
- tag_len = 0;
- if ((peek & 0x3F) == 4) { /* LITERAL */
- DebugLog(("STAG: LITERAL tag (peek = 0x%02X, off = %u) - TableRef follows!\n", peek, off));
- idx = tvb_get_guintvar (tvb, off+1, &tag_len);
- str_len = tvb_strsize (tvb, str_tbl+idx);
- tag_new_literal = (const gchar*)tvb_get_ptr (tvb, str_tbl+idx, str_len);
- tag_new_known = 0; /* invalidate known tag_new */
- } else { /* Known tag */
- tag_new_known = peek & 0x3F;
- tag_new_literal = map_token (map->tags, *codepage_stag,
- tag_new_known);
- /* Stored looked up tag name string */
- }
-
- /* Parsing of TAG starts HERE */
- if (peek & 0x40) { /* Content present */
- /* Content follows
- * [!] An explicit END token is expected in these cases!
- * ==> Recursion possible if we encounter a tag with content;
- * recursion will return at the explicit END token.
- */
- if (parsing_tag_content) { /* Recurse */
- DebugLog(("STAG: Tag in Tag - RECURSE! (off = %u)\n", off));
- /* Do not process the attribute list:
- * recursion will take care of it */
- (*level)++;
- len = parse_wbxml_tag_defined (tree, tvb, off, str_tbl,
- level, codepage_stag, codepage_attr, map);
- off += len;
- } else { /* Now we will have content to parse */
- /* Save the start tag so we can properly close it later. */
- if ((peek & 0x3F) == 4) { /* Literal tag */
- tag_save_literal = tag_new_literal;
- tag_save_known = 0;
- } else { /* Known tag */
- tag_save_known = tag_new_known;
- tag_save_literal = tag_new_literal;
- /* The last statement avoids needless lookups */
- }
- /* Process the attribute list if present */
- if (peek & 0x80) { /* Content and Attribute list present */
- if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| Known Tag 0x%02X (AC) "
- "| %s<%s",
- *level, *codepage_stag, tag_new_known,
- Indent (*level), tag_new_literal);
- /* Tag string already looked up earlier! */
- off++;
- } else { /* LITERAL tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| LITERAL_AC (Literal tag) (AC) "
- "| %s<%s",
- *level, *codepage_stag, Indent (*level), tag_new_literal);
- off += 1 + tag_len;
- }
- len = parse_wbxml_attribute_list_defined (tree, tvb,
- off, str_tbl, *level, codepage_attr, map);
- /* Check that there is still room in packet */
- off += len;
- if (off >= tvb_len) {
- DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n",
- *level, off - offset));
- /*
- * TODO - Do we need to free g_malloc()ed memory?
- */
- THROW(ReportedBoundsError);
- }
- proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | T %3d "
- "| END (attribute list) "
- "| %s>",
- *level, *codepage_stag, Indent (*level));
- } else { /* Content, no Attribute list */
- if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| Known Tag 0x%02X (.C) "
- "| %s<%s>",
- *level, *codepage_stag, tag_new_known,
- Indent (*level), tag_new_literal);
- /* Tag string already looked up earlier! */
- off++;
- } else { /* LITERAL tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| LITERAL_C (Literal Tag) (.C) "
- "| %s<%s>",
- *level, *codepage_stag, Indent (*level),
- tag_new_literal);
- off += 1 + tag_len;
- }
- }
- /* The data that follows in the parsing process
- * represents content for the opening tag
- * we've just processed in the lines above.
- * Next time we encounter a tag with content: recurse
- */
- parsing_tag_content = TRUE;
- DebugLog(("Tag in Tag - No recursion this time! (off = %u)\n", off));
+ /* 0xC4 impossible in ATTR state */
+ default:
+ proto_tree_add_none_format(tree, hf_wbxml_invalid_token, tvb, off, 1,
+ " %3d | Attr | A %3d | %-10s (Invalid Token!) | WBXML parsing stops here.",
+ level, *codepage_attr, val_to_str_ext (peek, &vals_wbxml1x_global_tokens_ext, "(unknown 0x%x)"));
+ /* Move to end of buffer */
+ off = tvb_len;
+ break;
+ } else { /* Known atribute token */
+ char* s;
+ if (peek & 0x80) { /* attrValue */
+ if (map != NULL) {
+ s = (char*)map_token (map->attrValue, *codepage_attr, peek);
+ } else {
+ s = wmem_strdup_printf(wmem_packet_scope(), "attrValue_0x%02X", peek);
}
- } else { /* No Content */
- DebugLog(("<Tag/> in Tag - No recursion! (off = %u)\n", off));
- (*level)++;
- if (peek & 0x80) { /* No Content, Attribute list present */
- if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| Known Tag 0x%02X (A.) "
- "| %s<%s",
- *level, *codepage_stag, tag_new_known,
- Indent (*level), tag_new_literal);
- /* Tag string already looked up earlier! */
- off++;
- len = parse_wbxml_attribute_list_defined (tree, tvb,
- off, str_tbl, *level, codepage_attr, map);
- /* Check that there is still room in packet */
- off += len;
- if (off > tvb_len) {
- DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
- /*
- * TODO - Do we need to free g_malloc()ed memory?
- */
- THROW(ReportedBoundsError);
- }
- proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | T %3d "
- "| END (Known Tag) "
- "| %s/>",
- *level, *codepage_stag, Indent (*level));
- } else { /* LITERAL tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| LITERAL_A (Literal Tag) (A.) "
- "| %s<%s",
- *level, *codepage_stag, Indent (*level), tag_new_literal);
- off += 1 + tag_len;
- len = parse_wbxml_attribute_list_defined (tree, tvb,
- off, str_tbl, *level, codepage_attr, map);
- /* Check that there is still room in packet */
- off += len;
- if (off >= tvb_len) {
- DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
- /*
- * TODO - Do we need to free g_malloc()ed memory?
- */
- THROW(ReportedBoundsError);
- }
- proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | T %3d "
- "| END (Literal Tag) "
- "| %s/>",
- *level, *codepage_stag, Indent (*level));
- }
- } else { /* No Content, No Attribute list */
- if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| Known Tag 0x%02x (..) "
- "| %s<%s />",
- *level, *codepage_stag, tag_new_known,
- Indent (*level), tag_new_literal);
- /* Tag string already looked up earlier! */
- off++;
- } else { /* LITERAL tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| LITERAL (Literal Tag) (..) "
- "| %s<%s />",
- *level, *codepage_stag, Indent (*level),
- tag_new_literal);
- off += 1 + tag_len;
- }
+ proto_tree_add_string_format(tree, hf_wbxml_known_attrvalue, tvb, off, 1, s,
+ " %3d | Attr | A %3d | Known attrValue 0x%02X | %s%s",
+ level, *codepage_attr, peek & 0x7f, Indent (level),
+ s);
+ off++;
+ } else { /* attrStart */
+ if (map != NULL) {
+ s = (char*)map_token (map->attrStart, *codepage_attr, peek);
+ } else {
+ s = wmem_strdup_printf(wmem_packet_scope(), "attrStart_0x%02X", peek);
}
- (*level)--;
- /* TODO: Do I have to reset code page here? */
+ proto_tree_add_string_format(tree, hf_wbxml_known_attrstart, tvb, off, 1, s,
+ " %3d | Attr | A %3d | Known attrStart 0x%02X | %s%s",
+ level, *codepage_attr, peek & 0x7f, Indent (level),
+ s);
+ off++;
}
- } /* if (tag & 0x3F) >= 5 */
- } /* while */
- DebugLog(("STAG: level = %u, Return: len = %u (end of function body)\n", *level, off - offset));
+ }
+ } /* End WHILE */
+ DebugLog(("ATTR: level = %u, Return: len = %u (end of function body)\n",
+ level, off - offset));
return (off - offset);
}
-/* This function performs the WBXML decoding as in parse_wbxml_tag_defined()
- * but this time no WBXML mapping is performed.
+/* This function parses the WBXML and maps known token interpretations
+ * to the WBXML tokens. As a result, the original XML document can be
+ * recreated. Indentation is generated in order to ease reading.
+ *
+ * Attribute parsing is done in parse_wbxml_attribute_list_defined().
*
- * Attribute parsing is done in parse_wbxml_attribute_list().
+ * The wbxml_decoding entry *map contains the actual token mapping.
+ *
+ * NOTE: In order to parse the content, some recursion is required.
+ * However, for performance reasons, recursion has been avoided
+ * where possible (tags without content within tags with content).
+ * This is achieved by means of the parsing_tag_content and tag_save*
+ * variables.
+ *
+ * NOTE: See above for known token mappings.
+ *
+ * NOTE: As tags can be opened and closed, a tag representation lookup
+ * may happen once or twice for a given tag. For efficiency reasons,
+ * the literal tag value is stored and used throughout the code.
+ * With the introduction of code page support, this solution is robust
+ * as the lookup only occurs once, removing the need for storage of
+ * the used code page.
*/
static guint32
-parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
- guint32 str_tbl, guint8 *level,
- guint8 *codepage_stag, guint8 *codepage_attr)
+parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
+ guint32 str_tbl, guint8 *level, guint8 *codepage_stag, guint8 *codepage_attr,
+ const wbxml_decoding *map)
{
- guint32 tvb_len = tvb_reported_length (tvb);
- guint32 off = offset;
+ guint32 tvb_len = tvb_reported_length (tvb);
+ guint32 off = offset;
guint32 len;
guint str_len;
guint32 ent;
guint32 idx;
guint8 peek;
- guint32 tag_len; /* Length of the idx (uintvar) from a LITERAL tag */
+ guint32 tag_len; /* Length of the index (uintvar) from a LITERAL tag */
guint8 tag_save_known = 0; /* Will contain peek & 0x3F (tag identity) */
guint8 tag_new_known = 0; /* Will contain peek & 0x3F (tag identity) */
- const char *tag_save_literal; /* Will contain the LITERAL tag identity */
+ const char *tag_save_literal = NULL; /* Will contain the LITERAL tag identity */
const char *tag_new_literal; /* Will contain the LITERAL tag identity */
- char *tag_save_buf = NULL; /* Will contain "tag_0x%02X" */
- char *tag_new_buf = NULL; /* Will contain "tag_0x%02X" */
+ gchar *str;
guint8 parsing_tag_content = FALSE; /* Are we parsing content from a
tag with content: <x>Content</x>
The initial state is FALSE.
This state will trigger recursion. */
- tag_save_literal = NULL; /* Prevents compiler warning */
- DebugLog(("parse_wbxml_tag (level = %u, offset = %u)\n", *level, offset));
+ DebugLog(("parse_wbxml_tag_defined (level = %u, offset = %u)\n", *level, offset));
while (off < tvb_len) {
peek = tvb_get_guint8 (tvb, off);
DebugLog(("STAG: (top of while) level = %3u, peek = 0x%02X, off = %u, tvb_len = %u\n", *level, peek, off, tvb_len));
@@ -7733,53 +7303,42 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
but not the LITERAL tokens */
case 0x00: /* SWITCH_PAGE */
*codepage_stag = tvb_get_guint8 (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 2,
- " | Tag | T -->%3d "
- "| SWITCH_PAGE (Tag code page) "
- "|",
+ proto_tree_add_uint_format(tree, hf_wbxml_switch_page, tvb, off, 2, *codepage_stag,
+ " | Tag | T -->%3d | SWITCH_PAGE (Tag code page) |",
*codepage_stag);
off += 2;
break;
case 0x01: /* END: only possible for Tag with Content */
if (tag_save_known) { /* Known TAG */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| END (Known Tag 0x%02X) "
- "| %s</%s>",
- *level, *codepage_stag, tag_save_known,
- Indent (*level),
+ proto_tree_add_string_format(tree, hf_wbxml_end_known_tag, tvb, off, 1, tag_save_literal,
+ " %3d | Tag | T %3d | END (Known Tag 0x%02X) | %s</%s>",
+ *level, *codepage_stag,
+ tag_save_known, Indent (*level),
tag_save_literal); /* We already looked it up! */
} else { /* Literal TAG */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| END (Literal Tag) "
- "| %s</%s>",
- *level, *codepage_stag, Indent (*level),
- tag_save_literal ? tag_save_literal : "");
+ proto_tree_add_string_format(tree, hf_wbxml_end_literal_tag, tvb, off, 1, tag_save_literal ? tag_save_literal : "",
+ " %3d | Tag | T %3d | END (Literal Tag) | %s</%s>",
+ *level, *codepage_stag, Indent (*level), tag_save_literal ? tag_save_literal : "");
}
(*level)--;
off++;
/* Reset code page: not needed as return from recursion */
- DebugLog(("STAG: level = %u, Return: len = %u\n",
- *level, off - offset));
+ DebugLog(("STAG: level = %u, Return: len = %u\n", *level, off - offset));
return (off - offset);
case 0x02: /* ENTITY */
ent = tvb_get_guintvar (tvb, off+1, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| ENTITY "
- "| %s'&#%u;'",
+ proto_tree_add_uint_format(tree, hf_wbxml_entity, tvb, off, 1+len, ent,
+ " %3d | Tag | T %3d | ENTITY | %s'&#%u;'",
*level, *codepage_stag, Indent (*level), ent);
off += 1+len;
break;
case 0x03: /* STR_I */
len = tvb_strsize (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| STR_I (Inline string) "
- "| %s\'%s\'",
+ str = tvb_format_text (tvb, off+1, len-1);
+ proto_tree_add_string_format(tree, hf_wbxml_str_i, tvb, off, 1+len, str,
+ " %3d | Tag | T %3d | STR_I (Inline string) | %s\'%s\'",
*level, *codepage_stag, Indent(*level),
- tvb_format_text (tvb, off+1, len-1));
+ str);
off += 1+len;
break;
case 0x40: /* EXT_I_0 */
@@ -7787,36 +7346,32 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
case 0x42: /* EXT_I_2 */
/* Extension tokens */
len = tvb_strsize (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| EXT_I_%1x (Extension Token) "
- "| %s(Inline string extension: \'%s\')",
- *level, *codepage_stag, peek & 0x0f, Indent (*level),
- tvb_format_text (tvb, off+1, len-1));
+ str = tvb_format_text (tvb, off+1, len-1);
+ proto_tree_add_string_format(tree, hf_wbxml_ext_i, tvb, off, 1+len, str,
+ " %3d | Tag | T %3d | EXT_I_%1x (Extension Token) | %s(%s: \'%s\')",
+ *level, *codepage_stag,
+ peek & 0x0f, Indent (*level),
+ ((map != NULL) ? map_token (map->global, 0, peek) : "Inline string extension"),
+ str);
off += 1+len;
break;
case 0x43: /* PI */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| PI (XML Processing Instruction) "
- "| %s<?xml",
+ proto_tree_add_none_format(tree, hf_wbxml_pi_xml, tvb, off, 1,
+ " %3d | Tag | T %3d | PI (XML Processing Instruction) | %s<?xml",
*level, *codepage_stag, Indent (*level));
- len = parse_wbxml_attribute_list (tree, tvb, off, str_tbl,
- *level, codepage_attr);
+ len = parse_wbxml_attribute_list_defined (tree, tvb, off,
+ str_tbl, *level, codepage_attr, map);
/* Check that there is still room in packet */
off += len;
if (off >= tvb_len) {
- DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n",
- *level, off - offset));
+ DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
/*
* TODO - Do we need to free g_malloc()ed memory?
*/
THROW(ReportedBoundsError);
}
- proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | T %3d "
- "| END (PI) "
- "| %s?>",
+ proto_tree_add_none_format(tree, hf_wbxml_end_pi, tvb, off-1, 1,
+ " %3d | Tag | T %3d | END (PI) | %s?>",
*level, *codepage_stag, Indent (*level));
break;
case 0x80: /* EXT_T_0 */
@@ -7824,55 +7379,85 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
case 0x82: /* EXT_T_2 */
/* Extension tokens */
idx = tvb_get_guintvar (tvb, off+1, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| EXT_T_%1x (Extension Token) "
- "| %s(Extension Token, integer value: %u)",
- *level, *codepage_stag, peek & 0x0f, Indent (*level),
- idx);
+ {
+ char *s;
+ if (map)
+ {
+ if (map->ext_t[peek & 0x03])
+ s = (map->ext_t[peek & 0x03])(tvb, idx, str_tbl);
+ else
+ s = wmem_strdup_printf(wmem_packet_scope(), "EXT_T_%1x (%s)", peek & 0x03,
+ map_token (map->global, 0, peek));
+ }
+ else
+ {
+ s = wmem_strdup_printf(wmem_packet_scope(), "(Extension Token, integer value: %u)", idx);
+ }
+ proto_tree_add_string_format(tree, hf_wbxml_ext_t, tvb, off, 1+len, s,
+ " %3d | Tag | T %3d | EXT_T_%1x (Extension Token) | %s%s",
+ *level, *codepage_stag, peek & 0x0f, Indent (*level), s);
+ }
off += 1+len;
break;
case 0x83: /* STR_T */
idx = tvb_get_guintvar (tvb, off+1, &len);
str_len = tvb_strsize (tvb, str_tbl+idx);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| STR_T (Tableref string) "
- "| %s\'%s\'",
- *level, *codepage_stag, Indent (*level),
- tvb_format_text (tvb, str_tbl+idx, str_len-1));
+ str = tvb_format_text (tvb, str_tbl+idx, str_len-1);
+ proto_tree_add_string_format(tree, hf_wbxml_str_t, tvb, off, 1+len, str,
+ " %3d | Tag | T %3d | STR_T (Tableref string) | %s\'%s\'",
+ *level, *codepage_stag, Indent (*level), str);
off += 1+len;
break;
case 0xC0: /* EXT_0 */
case 0xC1: /* EXT_1 */
case 0xC2: /* EXT_2 */
/* Extension tokens */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| EXT_%1x (Extension Token) "
- "| %s(Single-byte extension)",
- *level, *codepage_stag, peek & 0x0f, Indent (*level));
+ str = (char*)((map != NULL) ? map_token (map->global, 0, peek) : "Single-byte extension");
+ proto_tree_add_string_format(tree, hf_wbxml_extension_token, tvb, off, 1, str,
+ " %3d | Tag | T %3d | EXT_%1x (Extension Token) | %s(%s)",
+ *level, *codepage_stag, peek & 0x0f, Indent (*level), str);
off++;
break;
case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
- idx = tvb_get_guintvar (tvb, off+1, &len);
- proto_tree_add_text (tree, tvb, off, 1 + len + idx,
- " %3d | Tag | T %3d "
- "| OPAQUE (Opaque data) "
- "| %s(%d bytes of opaque data)",
+ if (map != NULL)
+ {
+ char *tmp_str;
+ if (tag_save_known) { /* Knwon tag */
+ if (map->opaque_binary_tag) {
+ tmp_str = map->opaque_binary_tag(tvb, off + 1,
+ tag_save_known, *codepage_stag, &len);
+ } else {
+ tmp_str = default_opaque_binary_tag(tvb, off + 1,
+ tag_save_known, *codepage_stag, &len);
+ }
+ } else { /* lITERAL tag */
+ if (map->opaque_literal_tag) {
+ tmp_str = map->opaque_literal_tag(tvb, off + 1,
+ tag_save_literal, *codepage_stag, &len);
+ } else {
+ tmp_str = default_opaque_literal_tag(tvb, off + 1,
+ tag_save_literal, *codepage_stag, &len);
+ }
+ }
+ proto_tree_add_bytes_format(tree, hf_wbxml_opaque_data, tvb, off, 1 + len, NULL,
+ " %3d | Tag | T %3d | OPAQUE (Opaque data) | %s%s",
+ *level, *codepage_stag, Indent (*level), tmp_str);
+ off += 1 + len;
+ } else {
+ idx = tvb_get_guintvar (tvb, off+1, &len);
+ proto_tree_add_bytes_format(tree, hf_wbxml_opaque_data, tvb, off, 1 + len + idx, NULL,
+ " %3d | Tag | T %3d | OPAQUE (Opaque data) | %s(%d bytes of opaque data)",
*level, *codepage_stag, Indent (*level), idx);
- off += 1+len+idx;
+ off += 1+len+idx;
+ }
} else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| RESERVED_2 (Invalid Token!) "
- "| WBXML 1.0 parsing stops here.",
+ proto_tree_add_none_format(tree, hf_wbxml_reserved_2, tvb, off, 1,
+ " %3d | Tag | T %3d | RESERVED_2 (Invalid Token!) | WBXML 1.0 parsing stops here.",
*level, *codepage_stag);
/* Stop processing as it is impossible to parse now */
off = tvb_len;
- DebugLog(("STAG: level = %u, Return: len = %u\n",
- *level, off - offset));
+ DebugLog(("STAG: level = %u, Return: len = %u\n", *level, off - offset));
return (off - offset);
}
break;
@@ -7895,17 +7480,20 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* Store the new tag */
tag_len = 0;
if ((peek & 0x3F) == 4) { /* LITERAL */
- DebugLog(("STAG: LITERAL tag (peek = 0x%02X, off = %u)"
- " - TableRef follows!\n", peek, off));
+ DebugLog(("STAG: LITERAL tag (peek = 0x%02X, off = %u) - TableRef follows!\n", peek, off));
idx = tvb_get_guintvar (tvb, off+1, &tag_len);
str_len = tvb_strsize (tvb, str_tbl+idx);
tag_new_literal = (const gchar*)tvb_get_ptr (tvb, str_tbl+idx, str_len);
tag_new_known = 0; /* invalidate known tag_new */
} else { /* Known tag */
tag_new_known = peek & 0x3F;
- tag_new_buf=wmem_strdup_printf(wmem_packet_scope(), "Tag_0x%02X",
- tag_new_known);
- tag_new_literal = tag_new_buf;
+ if (map != NULL) {
+ tag_new_literal = map_token (map->tags, *codepage_stag,
+ tag_new_known);
+ } else {
+ tag_new_literal = wmem_strdup_printf(wmem_packet_scope(), "Tag_0x%02X",
+ tag_new_known);
+ }
/* Stored looked up tag name string */
}
@@ -7921,8 +7509,8 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* Do not process the attribute list:
* recursion will take care of it */
(*level)++;
- len = parse_wbxml_tag (tree, tvb, off, str_tbl, level,
- codepage_stag, codepage_attr);
+ len = parse_wbxml_tag_defined (tree, tvb, off, str_tbl,
+ level, codepage_stag, codepage_attr, map);
off += len;
} else { /* Now we will have content to parse */
/* Save the start tag so we can properly close it later. */
@@ -7931,66 +7519,51 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
tag_save_known = 0;
} else { /* Known tag */
tag_save_known = tag_new_known;
- tag_save_buf=wmem_strdup_printf(wmem_packet_scope(), "Tag_0x%02X",
- tag_new_known);
- tag_save_literal = tag_save_buf;
+ tag_save_literal = tag_new_literal;
/* The last statement avoids needless lookups */
}
/* Process the attribute list if present */
if (peek & 0x80) { /* Content and Attribute list present */
if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| Known Tag 0x%02X (AC) "
- "| %s<%s",
+ proto_tree_add_string_format(tree, hf_wbxml_known_tag, tvb, off, 1, tag_new_literal,
+ " %3d | Tag | T %3d | Known Tag 0x%02X (AC) | %s<%s",
*level, *codepage_stag, tag_new_known,
Indent (*level), tag_new_literal);
/* Tag string already looked up earlier! */
off++;
} else { /* LITERAL tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| LITERAL_AC (Literal tag) (AC) "
- "| %s<%s",
- *level, *codepage_stag, Indent (*level),
- tag_new_literal);
+ proto_tree_add_string_format(tree, hf_wbxml_literal_ac, tvb, off, 1, tag_new_literal,
+ " %3d | Tag | T %3d | LITERAL_AC (Literal tag) (AC) | %s<%s",
+ *level, *codepage_stag, Indent (*level), tag_new_literal);
off += 1 + tag_len;
}
- len = parse_wbxml_attribute_list (tree, tvb,
- off, str_tbl, *level, codepage_attr);
+ len = parse_wbxml_attribute_list_defined (tree, tvb,
+ off, str_tbl, *level, codepage_attr, map);
/* Check that there is still room in packet */
off += len;
if (off >= tvb_len) {
- DebugLog(("STAG: level = %u, ThrowException: "
- "len = %u (short frame)\n",
+ DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n",
*level, off - offset));
/*
* TODO - Do we need to free g_malloc()ed memory?
*/
THROW(ReportedBoundsError);
}
- proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | T %3d "
- "| END (attribute list) "
- "| %s>",
+ proto_tree_add_none_format(tree, hf_wbxml_end_attribute_list, tvb, off-1, 1,
+ " %3d | Tag | T %3d | END (attribute list) | %s>",
*level, *codepage_stag, Indent (*level));
} else { /* Content, no Attribute list */
if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| Known Tag 0x%02X (.C) "
- "| %s<%s>",
+ proto_tree_add_string_format(tree, hf_wbxml_known_tag, tvb, off, 1, tag_new_literal,
+ " %3d | Tag | T %3d | Known Tag 0x%02X (.C) | %s<%s>",
*level, *codepage_stag, tag_new_known,
Indent (*level), tag_new_literal);
/* Tag string already looked up earlier! */
off++;
} else { /* LITERAL tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| LITERAL_C (Literal Tag) (.C) "
- "| %s<%s>",
- *level, *codepage_stag, Indent (*level),
- tag_new_literal);
+ proto_tree_add_string_format(tree, hf_wbxml_literal_c, tvb, off, 1, tag_new_literal,
+ " %3d | Tag | T %3d | LITERAL_C (Literal Tag) (.C) | %s<%s>",
+ *level, *codepage_stag, Indent (*level), tag_new_literal);
off += 1 + tag_len;
}
}
@@ -8000,82 +7573,64 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
* Next time we encounter a tag with content: recurse
*/
parsing_tag_content = TRUE;
- DebugLog(("Tag in Tag - No recursion this time! "
- "(off = %u)\n", off));
+ DebugLog(("Tag in Tag - No recursion this time! (off = %u)\n", off));
}
} else { /* No Content */
DebugLog(("<Tag/> in Tag - No recursion! (off = %u)\n", off));
(*level)++;
if (peek & 0x80) { /* No Content, Attribute list present */
if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| Known Tag 0x%02X (A.) "
- "| %s<%s",
+ proto_tree_add_string_format(tree, hf_wbxml_known_tag, tvb, off, 1, tag_new_literal,
+ " %3d | Tag | T %3d | Known Tag 0x%02X (A.) | %s<%s",
*level, *codepage_stag, tag_new_known,
Indent (*level), tag_new_literal);
/* Tag string already looked up earlier! */
off++;
- len = parse_wbxml_attribute_list (tree, tvb,
- off, str_tbl, *level, codepage_attr);
+ len = parse_wbxml_attribute_list_defined (tree, tvb,
+ off, str_tbl, *level, codepage_attr, map);
/* Check that there is still room in packet */
off += len;
- if (off >= tvb_len) {
- DebugLog(("STAG: level = %u, ThrowException: "
- "len = %u (short frame)\n",
- *level, off - offset));
+ if (off > tvb_len) {
+ DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
/*
* TODO - Do we need to free g_malloc()ed memory?
*/
THROW(ReportedBoundsError);
}
- proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | T %3d "
- "| END (Known Tag) "
- "| %s/>",
+ proto_tree_add_uint_format(tree, hf_wbxml_end_known_tag_uint, tvb, off-1, 1, *codepage_stag,
+ " %3d | Tag | T %3d | END (Known Tag) | %s/>",
*level, *codepage_stag, Indent (*level));
} else { /* LITERAL tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| LITERAL_A (Literal Tag) (A.) "
- "| %s<%s",
- *level, *codepage_stag, Indent (*level),
- tag_new_literal);
+ proto_tree_add_string_format(tree, hf_wbxml_literal_a, tvb, off, 1, tag_new_literal,
+ " %3d | Tag | T %3d | LITERAL_A (Literal Tag) (A.) | %s<%s",
+ *level, *codepage_stag, Indent (*level), tag_new_literal);
off += 1 + tag_len;
- len = parse_wbxml_attribute_list (tree, tvb,
- off, str_tbl, *level, codepage_attr);
+ len = parse_wbxml_attribute_list_defined (tree, tvb,
+ off, str_tbl, *level, codepage_attr, map);
/* Check that there is still room in packet */
off += len;
if (off >= tvb_len) {
- DebugLog(("STAG: level = %u, ThrowException: "
- "len = %u (short frame)\n",
- *level, off - offset));
+ DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
/*
* TODO - Do we need to free g_malloc()ed memory?
*/
THROW(ReportedBoundsError);
}
- proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | T %3d "
- "| END (Literal Tag) "
- "| %s/>",
+ proto_tree_add_string_format(tree, hf_wbxml_end_literal_tag, tvb, off-1, 1, "",
+ " %3d | Tag | T %3d | END (Literal Tag) | %s/>",
*level, *codepage_stag, Indent (*level));
}
} else { /* No Content, No Attribute list */
if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| Known Tag 0x%02x (..) "
- "| %s<%s />",
+ proto_tree_add_string_format(tree, hf_wbxml_known_tag, tvb, off, 1, tag_new_literal,
+ " %3d | Tag | T %3d | Known Tag 0x%02x (..) | %s<%s />",
*level, *codepage_stag, tag_new_known,
Indent (*level), tag_new_literal);
/* Tag string already looked up earlier! */
off++;
} else { /* LITERAL tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | T %3d "
- "| LITERAL (Literal Tag) (..) "
- "| %s<%s />",
+ proto_tree_add_string_format(tree, hf_wbxml_literal, tvb, off, 1, tag_new_literal,
+ " %3d | Tag | T %3d | LITERAL (Literal Tag) (..) | %s<%s />",
*level, *codepage_stag, Indent (*level),
tag_new_literal);
off += 1 + tag_len;
@@ -8086,436 +7641,222 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
}
} /* if (tag & 0x3F) >= 5 */
} /* while */
- DebugLog(("STAG: level = %u, Return: len = %u (end of function body)\n",
- *level, off - offset));
+ DebugLog(("STAG: level = %u, Return: len = %u (end of function body)\n", *level, off - offset));
return (off - offset);
}
+/****************** WBXML protocol dissection functions ******************/
-/**************************
- * WBXML Attribute tokens *
- **************************
- * Bit Mask : Example
- * -------------------
- * 0... .... : attr= (attribute name)
- * href='http://' (attribute name with start of attribute value)
- * 1... .... : 'www.' (attribute value, or part of it)
- *
- */
+/* Code to actually dissect the packets */
+static void
+dissect_wbxml_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ const wbxml_decoding *override_content_map)
+{
+ /* Set up structures needed to add the protocol subtree and manage it */
+ proto_item *ti;
+ proto_tree *wbxml_tree; /* Main WBXML tree */
+ proto_tree *wbxml_str_tbl_tree; /* String table subtree */
+ proto_tree *wbxml_content_tree; /* Content subtree */
+ proto_tree *tag_tree;
+ guint8 version;
+ guint offset = 0;
+ guint32 len;
+ guint32 charset = 0;
+ guint32 charset_len = 0;
+ guint32 publicid;
+ guint32 publicid_index = 0;
+ guint32 publicid_len;
+ guint32 str_tbl;
+ guint32 str_tbl_len;
+ guint32 str_tbl_len_len = 0;
+ guint8 level = 0; /* WBXML recursion level */
+ const wbxml_decoding *content_map = NULL;
+ gchar *summary = NULL;
+ guint8 codepage_stag = 0;
+ guint8 codepage_attr = 0;
+ DebugLog(("dissect_wbxml: Dissecting packet %u\n", pinfo->fd->num));
+ /* WBXML format
+ *
+ * Version 1.0: version publicid strtbl BODY
+ * Version 1.x: version publicid charset strtbl BODY
+ *
+ * Last valid format: WBXML 1.3
+ */
+ switch ( version = tvb_get_guint8 (tvb, 0) ) {
+ case 0x00: /* WBXML/1.0 */
+ break;
-/* This function parses the WBXML and maps known token interpretations
- * to the WBXML tokens. As a result, the original XML document can be
- * recreated. Indentation is generated in order to ease reading.
- *
- * This function performs attribute list parsing.
- *
- * The wbxml_decoding entry *map contains the actual token mapping.
- *
- * NOTE: See above for known token mappings.
- */
-static guint32
-parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
- guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr,
- const wbxml_decoding *map)
-{
- guint32 tvb_len = tvb_reported_length (tvb);
- guint32 off = offset;
- guint32 len;
- guint str_len;
- guint32 ent;
- guint32 idx;
- guint8 peek;
- guint8 attr_save_known = 0; /* Will contain peek & 0x3F (attr identity) */
- const char *attr_save_literal = NULL; /* Will contain the LITERAL attr identity */
+ case 0x01: /* WBXML/1.1 */
+ case 0x02: /* WBXML/1.2 */
+ case 0x03: /* WBXML/1.3 */
+ break;
- DebugLog(("parse_wbxml_attr_defined (level = %u, offset = %u)\n",
- level, offset));
- /* Parse attributes */
- while (off < tvb_len) {
- peek = tvb_get_guint8 (tvb, off);
- DebugLog(("ATTR: (top of while) level = %3u, peek = 0x%02X, "
- "off = %u, tvb_len = %u\n", level, peek, off, tvb_len));
- if ((peek & 0x3F) < 5) switch (peek) { /* Global tokens
- in state = ATTR */
- case 0x00: /* SWITCH_PAGE */
- *codepage_attr = tvb_get_guint8 (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 2,
- " | Attr | A -->%3d "
- "| SWITCH_PAGE (Attr code page) |",
- *codepage_attr);
- off += 2;
- break;
- case 0x01: /* END */
- /* BEWARE
- * The Attribute END token means either ">" or "/>"
- * and as a consequence both must be treated separately.
- * This is done in the TAG state parser.
- */
- off++;
- DebugLog(("ATTR: level = %u, Return: len = %u\n",
- level, off - offset));
- return (off - offset);
- case 0x02: /* ENTITY */
- ent = tvb_get_guintvar (tvb, off+1, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| ENTITY "
- "| %s'&#%u;'",
- level, *codepage_attr, Indent (level), ent);
- off += 1+len;
- break;
- case 0x03: /* STR_I */
- len = tvb_strsize (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| STR_I (Inline string) "
- "| %s\'%s\'",
- level, *codepage_attr, Indent (level),
- tvb_format_text (tvb, off+1, len-1));
- off += 1+len;
- break;
- case 0x04: /* LITERAL */
- /* ALWAYS means the start of a new attribute,
- * and may only contain the NAME of the attribute.
- */
- idx = tvb_get_guintvar (tvb, off+1, &len);
- str_len = tvb_strsize (tvb, str_tbl+idx);
- attr_save_known = 0;
- attr_save_literal = tvb_format_text (tvb,
- str_tbl+idx, str_len-1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| LITERAL (Literal Attribute) "
- "| %s<%s />",
- level, *codepage_attr, Indent (level),
- attr_save_literal);
- off += 1+len;
- break;
- case 0x40: /* EXT_I_0 */
- case 0x41: /* EXT_I_1 */
- case 0x42: /* EXT_I_2 */
- /* Extension tokens */
- len = tvb_strsize (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| EXT_I_%1x (Extension Token) "
- "| %s(%s: \'%s\')",
- level, *codepage_attr, peek & 0x0f, Indent (level),
- map_token (map->global, 0, peek),
- tvb_format_text (tvb, off+1, len-1));
- off += 1+len;
- break;
- /* 0x43 impossible in ATTR state */
- /* 0x44 impossible in ATTR state */
- case 0x80: /* EXT_T_0 */
- case 0x81: /* EXT_T_1 */
- case 0x82: /* EXT_T_2 */
- /* Extension tokens */
- idx = tvb_get_guintvar (tvb, off+1, &len);
- { char *s;
+ default:
+ /* Put some information here, so that the user knows what's going on. */
- if (map->ext_t[peek & 0x03])
- s = (map->ext_t[peek & 0x03])(tvb, idx, str_tbl);
- else
- s = wmem_strdup_printf(wmem_packet_scope(), "EXT_T_%1x (%s)", peek & 0x03,
- map_token (map->global, 0, peek));
+ /* Add summary to INFO column if it is enabled */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " (Unknown WBXML version 0x%02x)", version);
+ ti = proto_tree_add_item (tree, proto_wbxml, tvb, 0, -1, ENC_NA);
+ proto_item_append_text(ti, ", Unknown version 0x%02x", version);
+ return;
+ }
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | T %3d "
- "| EXT_T_%1x (Extension Token) "
- "| %s%s)",
- level, *codepage_attr, peek & 0x0f, Indent (level),
- s);
- }
- off += 1+len;
- break;
- case 0x83: /* STR_T */
- idx = tvb_get_guintvar (tvb, off+1, &len);
- str_len = tvb_strsize (tvb, str_tbl+idx);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| STR_T (Tableref string) "
- "| %s\'%s\'",
- level, *codepage_attr, Indent (level),
- tvb_format_text (tvb, str_tbl+idx, str_len-1));
- off += 1+len;
- break;
- /* 0x84 impossible in ATTR state */
- case 0xC0: /* EXT_0 */
- case 0xC1: /* EXT_1 */
- case 0xC2: /* EXT_2 */
- /* Extension tokens */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| EXT_%1x (Extension Token) "
- "| %s(%s)",
- level, *codepage_attr, peek & 0x0f, Indent (level),
- map_token (map->global, 0, peek));
- off++;
- break;
- case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
- if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
- char *str;
- if (attr_save_known) { /* Knwon attribute */
- if (map->opaque_binary_attr) {
- str = map->opaque_binary_attr(tvb, off + 1,
- attr_save_known, *codepage_attr, &len);
- } else {
- str = default_opaque_binary_attr(tvb, off + 1,
- attr_save_known, *codepage_attr, &len);
- }
- } else { /* lITERAL attribute */
- if (map->opaque_literal_tag) {
- str = map->opaque_literal_attr(tvb, off + 1,
- attr_save_literal, *codepage_attr, &len);
- } else {
- str = default_opaque_literal_attr(tvb, off + 1,
- attr_save_literal, *codepage_attr, &len);
- }
- }
- proto_tree_add_text (tree, tvb, off, 1 + len,
- " %3d | Attr | A %3d "
- "| OPAQUE (Opaque data) "
- "| %s%s",
- level, *codepage_attr, Indent (level), str);
- off += 1 + len;
- } else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| RESERVED_2 (Invalid Token!) "
- "| WBXML 1.0 parsing stops here.",
- level, *codepage_attr);
- /* Stop processing as it is impossible to parse now */
- off = tvb_len;
- DebugLog(("ATTR: level = %u, Return: len = %u\n",
- level, off - offset));
- return (off - offset);
- }
- break;
- /* 0xC4 impossible in ATTR state */
- default:
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| %-10s (Invalid Token!) "
- "| WBXML parsing stops here.",
- level, *codepage_attr,
- val_to_str_ext (peek, &vals_wbxml1x_global_tokens_ext, "(unknown 0x%x)"));
- /* Move to end of buffer */
- off = tvb_len;
- break;
- } else { /* Known atribute token */
- if (peek & 0x80) { /* attrValue */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| Known attrValue 0x%02X "
- "| %s%s",
- level, *codepage_attr, peek & 0x7f, Indent (level),
- map_token (map->attrValue, *codepage_attr, peek));
- off++;
- } else { /* attrStart */
- attr_save_known = peek & 0x7f;
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| Known attrStart 0x%02X "
- "| %s%s",
- level, *codepage_attr, attr_save_known, Indent (level),
- map_token (map->attrStart, *codepage_attr, peek));
- off++;
+ /* In order to properly construct the packet summary,
+ * I need to read the entire WBXML header
+ * up to the string table length.
+ */
+
+ /* Public ID */
+ publicid = tvb_get_guintvar(tvb, 1, &publicid_len);
+ if (! publicid) {
+ /* Public identifier in string table */
+ publicid_index = tvb_get_guintvar (tvb, 1+publicid_len, &len);
+ publicid_len += len;
+ }
+ offset = 1 + publicid_len;
+
+ /* Version-specific handling of Charset */
+ switch ( version ) {
+ case 0x00: /* WBXML/1.0 */
+ /* No charset */
+ break;
+
+ case 0x01: /* WBXML/1.1 */
+ case 0x02: /* WBXML/1.2 */
+ case 0x03: /* WBXML/1.3 */
+ /* Get charset */
+ charset = tvb_get_guintvar (tvb, offset, &charset_len);
+ offset += charset_len;
+ break;
+
+ default: /* Impossible since we returned already earlier */
+ DISSECTOR_ASSERT_NOT_REACHED();
+ break;
+ }
+
+ /* String table: read string table length in bytes */
+ tvb_get_guintvar (tvb, offset, &str_tbl_len_len);
+ str_tbl = offset + str_tbl_len_len; /* Start of 1st string in string table */
+
+ /* Compose the summary line */
+ if ( publicid ) {
+ summary = wmem_strdup_printf(wmem_packet_scope(), "%s, Public ID: \"%s\"",
+ val_to_str_ext (version, &vals_wbxml_versions_ext, "(unknown 0x%x)"),
+ val_to_str_ext (publicid, &vals_wbxml_public_ids_ext, "(unknown 0x%x)"));
+ } else {
+ /* Read length of Public ID from string table */
+ len = tvb_strsize (tvb, str_tbl + publicid_index);
+ summary = wmem_strdup_printf(wmem_packet_scope(), "%s, Public ID: \"%s\"",
+ val_to_str_ext (version, &vals_wbxml_versions_ext, "(unknown 0x%x)"),
+ tvb_format_text (tvb, str_tbl + publicid_index, len - 1));
+ }
+
+ /* Add summary to INFO column if it is enabled */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " (WBXML %s)", summary);
+
+ /* create display subtree for the protocol */
+ ti = proto_tree_add_item (tree, proto_wbxml, tvb, 0, -1, ENC_NA);
+ proto_item_append_text(ti, ", Version: %s", summary);
+
+ /*
+ * Now show the protocol subtree, if tree is set.
+ */
+ wbxml_tree = proto_item_add_subtree(ti, ett_wbxml);
+
+ /* WBXML Version */
+ proto_tree_add_uint (wbxml_tree, hf_wbxml_version,
+ tvb, 0, 1, version);
+
+ /* Public ID */
+ if (publicid) { /* Known Public ID */
+ proto_tree_add_uint(wbxml_tree, hf_wbxml_public_id_known,
+ tvb, 1, publicid_len, publicid);
+ } else { /* Public identifier in string table */
+ proto_tree_add_item (wbxml_tree, hf_wbxml_public_id_literal,
+ tvb, 1, publicid_len, ENC_ASCII|ENC_NA);
+ }
+ offset = 1 + publicid_len;
+
+ if ( charset ) { /* Charset */
+ proto_tree_add_uint (wbxml_tree, hf_wbxml_charset,
+ tvb, 1 + publicid_len, charset_len, charset);
+ offset += charset_len;
+ }
+
+ str_tbl_len = tvb_get_guintvar (tvb, offset, &len);
+ str_tbl = offset + len; /* Start of 1st string in string table */
+
+ /* String Table */
+ wbxml_str_tbl_tree = proto_tree_add_subtree_format(wbxml_tree,
+ tvb, offset, len + str_tbl_len, ett_wbxml_str_tbl, NULL, "String table: %u bytes",
+ str_tbl_len);
+
+ if (str_tbl_len) { /* Display string table as subtree */
+ show_wbxml_string_table (wbxml_str_tbl_tree, tvb,
+ str_tbl, str_tbl_len);
+ }
+
+ /* Data starts HERE */
+ offset += len + str_tbl_len;
+
+ wbxml_content_tree = proto_tree_add_subtree(wbxml_tree, tvb, offset, -1,
+ ett_wbxml_content, &ti, "Data representation");
+ /* The WBXML BODY starts here */
+ if (disable_wbxml_token_parsing) {
+ expert_add_info(pinfo, ti, &ei_wbxml_data_not_shown);
+ return;
+ }
+
+ /* The parse_wbxml_X() functions will process the content correctly,
+ * irrespective of the WBXML version used. For the WBXML body, this
+ * means that there is a different processing for the global token
+ * RESERVED_2 (WBXML 1.0) or OPAQUE (WBXML 1.x with x > 0). */
+ if (override_content_map != NULL) {
+ content_map = override_content_map;
+ proto_item_append_text(ti,
+ " is based on: %s",
+ content_map->name);
+ } else {
+ /* Retrieve the content token mapping if available */
+ content_map = get_wbxml_decoding_from_public_id (publicid);
+ if (! content_map) {
+ content_map = get_wbxml_decoding_from_content_type(
+ pinfo->match_string, tvb, offset);
+ if (! content_map) {
+ expert_add_info(pinfo, ti, &ei_wbxml_content_type_not_supported);
+ } else {
+ proto_item_append_text(ti,
+ " is based on Content-Type: %s "
+ "(chosen decoding: %s)",
+ pinfo->match_string, content_map->name);
}
}
- } /* End WHILE */
- DebugLog(("ATTR: level = %u, Return: len = %u (end of function body)\n",
- level, off - offset));
- return (off - offset);
-}
+ }
+ if (content_map && skip_wbxml_token_mapping) {
+ expert_add_info(pinfo, ti, &ei_wbxml_content_type_disabled);
+ content_map = NULL;
+ }
+ tag_tree = proto_tree_add_subtree(wbxml_content_tree, tvb, offset, -1, ett_wbxml_tags, NULL,
+ "Level | State | Codepage | WBXML Token Description | Rendering");
+ /* If content_map == NULL, WBXML only, no interpretation of the content */
+ len = parse_wbxml_tag_defined (tag_tree,
+ tvb, offset, str_tbl, &level, &codepage_stag,
+ &codepage_attr, content_map);
+}
-/* This function performs the WBXML attribute decoding as in
- * parse_wbxml_attribute_list_defined() but this time no WBXML mapping
- * is performed.
- *
- * This function performs attribute list parsing.
- *
- * NOTE: Code page switches not yet processed in the code!
- */
-static guint32
-parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
- guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr)
+static void
+dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- guint32 tvb_len = tvb_reported_length (tvb);
- guint32 off = offset;
- guint32 len;
- guint str_len;
- guint32 ent;
- guint32 idx;
- guint8 peek;
-
- DebugLog(("parse_wbxml_attr (level = %u, offset = %u)\n", level, offset));
- /* Parse attributes */
- while (off < tvb_len) {
- peek = tvb_get_guint8 (tvb, off);
- DebugLog(("ATTR: (top of while) level = %3u, peek = 0x%02X, "
- "off = %u, tvb_len = %u\n", level, peek, off, tvb_len));
- if ((peek & 0x3F) < 5) switch (peek) { /* Global tokens
- in state = ATTR */
- case 0x00: /* SWITCH_PAGE */
- *codepage_attr = tvb_get_guint8 (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 2,
- " | Attr | A -->%3d "
- "| SWITCH_PAGE (Attr code page) |",
- *codepage_attr);
- off += 2;
- break;
- case 0x01: /* END */
- /* BEWARE
- * The Attribute END token means either ">" or "/>"
- * and as a consequence both must be treated separately.
- * This is done in the TAG state parser.
- */
- off++;
- DebugLog(("ATTR: level = %u, Return: len = %u\n",
- level, off - offset));
- return (off - offset);
- case 0x02: /* ENTITY */
- ent = tvb_get_guintvar (tvb, off+1, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| ENTITY "
- "| %s'&#%u;'",
- level, *codepage_attr, Indent (level), ent);
- off += 1+len;
- break;
- case 0x03: /* STR_I */
- len = tvb_strsize (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| STR_I (Inline string) "
- "| %s\'%s\'",
- level, *codepage_attr, Indent (level),
- tvb_format_text (tvb, off+1, len-1));
- off += 1+len;
- break;
- case 0x04: /* LITERAL */
- idx = tvb_get_guintvar (tvb, off+1, &len);
- str_len = tvb_strsize (tvb, str_tbl+idx);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| LITERAL (Literal Attribute) "
- "| %s<%s />",
- level, *codepage_attr, Indent (level),
- tvb_format_text (tvb, str_tbl+idx, str_len-1));
- off += 1+len;
- break;
- case 0x40: /* EXT_I_0 */
- case 0x41: /* EXT_I_1 */
- case 0x42: /* EXT_I_2 */
- /* Extension tokens */
- len = tvb_strsize (tvb, off+1);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| EXT_I_%1x (Extension Token) "
- "| %s(Inline string extension: \'%s\')",
- level, *codepage_attr, peek & 0x0f, Indent (level),
- tvb_format_text (tvb, off+1, len-1));
- off += 1+len;
- break;
- /* 0x43 impossible in ATTR state */
- /* 0x44 impossible in ATTR state */
- case 0x80: /* EXT_T_0 */
- case 0x81: /* EXT_T_1 */
- case 0x82: /* EXT_T_2 */
- /* Extension tokens */
- idx = tvb_get_guintvar (tvb, off+1, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| EXT_T_%1x (Extension Token) "
- "| %s(Extension Token, integer value: %u)",
- level, *codepage_attr, peek & 0x0f, Indent (level),
- idx);
- off += 1+len;
- break;
- case 0x83: /* STR_T */
- idx = tvb_get_guintvar (tvb, off+1, &len);
- str_len = tvb_strsize (tvb, str_tbl+idx);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | A %3d "
- "| STR_T (Tableref string) "
- "| %s\'%s\'",
- level, *codepage_attr, Indent (level),
- tvb_format_text (tvb, str_tbl+idx, str_len-1));
- off += 1+len;
- break;
- /* 0x84 impossible in ATTR state */
- case 0xC0: /* EXT_0 */
- case 0xC1: /* EXT_1 */
- case 0xC2: /* EXT_2 */
- /* Extension tokens */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| EXT_%1x (Extension Token) "
- "| %s(Single-byte extension)",
- level, *codepage_attr, peek & 0x0f, Indent (level));
- off++;
- break;
- case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
- if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
- idx = tvb_get_guintvar (tvb, off+1, &len);
- proto_tree_add_text (tree, tvb, off, 1 + len + idx,
- " %3d | Attr | A %3d "
- "| OPAQUE (Opaque data) "
- "| %s(%d bytes of opaque data)",
- level, *codepage_attr, Indent (level), idx);
- off += 1+len+idx;
- } else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| RESERVED_2 (Invalid Token!) "
- "| WBXML 1.0 parsing stops here.",
- level, *codepage_attr);
- /* Stop processing as it is impossible to parse now */
- off = tvb_len;
- DebugLog(("ATTR: level = %u, Return: len = %u\n",
- level, off - offset));
- return (off - offset);
- }
- break;
- /* 0xC4 impossible in ATTR state */
- default:
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| %-10s (Invalid Token!) "
- "| WBXML parsing stops here.",
- level, *codepage_attr,
- val_to_str_ext (peek, &vals_wbxml1x_global_tokens_ext, "(unknown 0x%x)"));
- /* Move to end of buffer */
- off = tvb_len;
- break;
- } else { /* Known atribute token */
- if (peek & 0x80) { /* attrValue */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| Known attrValue 0x%02X "
- "| %sattrValue_0x%02X",
- level, *codepage_attr, peek & 0x7f, Indent (level),
- peek);
- off++;
- } else { /* attrStart */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | A %3d "
- "| Known attrStart 0x%02X "
- "| %sattrStart_0x%02X",
- level, *codepage_attr, peek & 0x7f, Indent (level),
- peek);
- off++;
- }
- }
- } /* End WHILE */
- DebugLog(("ATTR: level = %u, Return: len = %u (end of function body)\n",
- level, off - offset));
- return (off - offset);
+ dissect_wbxml_common(tvb, pinfo, tree, NULL);
}
+static void
+dissect_uaprof(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ dissect_wbxml_common(tvb, pinfo, tree, &decode_uaprof_wap_248);
+}
/****************** Register the protocol with Wireshark ******************/
@@ -8558,6 +7899,174 @@ proto_register_wbxml(void)
&wap_mib_enum_vals_character_sets_ext, 0x00,
"WBXML Character Set", HFILL }
},
+ { &hf_wbxml_string_table_item,
+ { "String table item",
+ "wbxml.string_table_item",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_switch_page,
+ { "SWITCH_PAGE",
+ "wbxml.switch_page",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_known_tag,
+ { "Known Tag",
+ "wbxml.known_tag",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_end_known_tag,
+ { "END Known Tag",
+ "wbxml.end_known_tag",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_end_known_tag_uint,
+ { "END Known Tag",
+ "wbxml.end_known_tag.uint",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_str_i,
+ { "STR_I",
+ "wbxml.str_i",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_str_t,
+ { "STR_T",
+ "wbxml.str_t",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_opaque_data,
+ { "Opaque Data",
+ "wbxml.opaque_data",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_entity,
+ { "ENTITY",
+ "wbxml.entity",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_literal,
+ { "LITERAL",
+ "wbxml.literal",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_ext_i,
+ { "EXT_I",
+ "wbxml.ext_i",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_ext_t,
+ { "EXT_T",
+ "wbxml.ext_t",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_extension_token,
+ { "Extension Token",
+ "wbxml.extension_token",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_reserved_2,
+ { "RESERVED_2",
+ "wbxml.reserved_2",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_invalid_token,
+ { "Invalid token",
+ "wbxml.invalid_token",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_known_attrvalue,
+ { "Known attrValue",
+ "wbxml.known_attrvalue",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_known_attrstart,
+ { "Known attrStart",
+ "wbxml.known_attrstart",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_end_literal_tag,
+ { "END (Literal Tag)",
+ "wbxml.end_literal_tag",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_literal_a,
+ { "LITERAL_A",
+ "wbxml.literal_a",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_literal_c,
+ { "LITERAL_C",
+ "wbxml.literal_c",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_literal_ac,
+ { "LITERAL_AC",
+ "wbxml.literal_ac",
+ FT_STRING, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_end_pi,
+ { "END (PI)",
+ "wbxml.end_pi",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_end_attribute_list,
+ { "END (attribute list)",
+ "wbxml.end_attribute_list",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_wbxml_pi_xml,
+ { "PI (XML Processing Instruction)",
+ "wbxml.pi_xml",
+ FT_NONE, BASE_NONE,
+ NULL, 0x00,
+ NULL, HFILL }
+ },
};
/* Setup protocol subtree array */
@@ -8565,8 +8074,17 @@ proto_register_wbxml(void)
&ett_wbxml,
&ett_wbxml_str_tbl,
&ett_wbxml_content,
+ &ett_wbxml_tags,
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_wbxml_data_not_shown, { "wbxml.data_not_shown", PI_PROTOCOL, PI_NOTE, "Data representation not shown (edit WBXML preferences to show)", EXPFILL }},
+ { &ei_wbxml_content_type_not_supported, { "wbxml.content_type.not_supported", PI_UNDECODED, PI_WARN, "Rendering of this content type not (yet) supported", EXPFILL }},
+ { &ei_wbxml_content_type_disabled, { "wbxml.content_type.disabled", PI_PROTOCOL, PI_NOTE, "Rendering of this content type has been disabled (edit WBXML preferences to enable)", EXPFILL }},
};
+ expert_module_t* expert_wbxml;
+
/* Register the protocol name and description */
proto_wbxml = proto_register_protocol(
"WAP Binary XML",
@@ -8578,6 +8096,8 @@ proto_register_wbxml(void)
* and subtrees used */
proto_register_field_array(proto_wbxml, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ expert_wbxml = expert_register_protocol(proto_wbxml);
+ expert_register_field_array(expert_wbxml, ei, array_length(ei));
/* Preferences */
wbxml_module = prefs_register_protocol(proto_wbxml, NULL);