aboutsummaryrefslogtreecommitdiffstats
path: root/packet-wbxml.c
diff options
context:
space:
mode:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2003-05-01 18:18:20 +0000
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2003-05-01 18:18:20 +0000
commitae966142af4517259511886bba3a6662ed33d5db (patch)
treecaa80aea44f1dbd42d1390851d3b4ea918afefc4 /packet-wbxml.c
parent07126a7929b3261b3de0f54c0786e4c25a6f1fb6 (diff)
From Olivier Biot:
* Support correct processing of code page switches * Provide a new datatype containing scarce array of const value_string arrays (value_valuestring) allowing an efficient support for WBXML code pages. * Minor fix (XML PI was always decoded without mapping known tokens) * Add support for decoding of more WBXML content types (SyncML 1.0, SyncML 1.1, CHANNEL 1.0, EMN 1.0). git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@7626 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'packet-wbxml.c')
-rw-r--r--packet-wbxml.c2020
1 files changed, 1430 insertions, 590 deletions
diff --git a/packet-wbxml.c b/packet-wbxml.c
index d56aa77b92..c1d54bf29d 100644
--- a/packet-wbxml.c
+++ b/packet-wbxml.c
@@ -2,7 +2,7 @@
* Routines for wbxml dissection
* Copyright 2003, Olivier Biot <olivier.biot (ad) siemens.com>
*
- * $Id: packet-wbxml.c,v 1.8 2003/04/16 18:29:38 guy Exp $
+ * $Id: packet-wbxml.c,v 1.9 2003/05/01 18:18:20 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -55,13 +55,16 @@
*
* NOTES:
*
- * - Although Code Page processing is already foreseen in the tag and
- * attribute parsing code, there is no mechanism available yet to
- * properly deal with multiple code pages (see, e.g., the wbxml_map[]
- * array). As a consequence, the same token rendering will occur,
- * irrespective of the code pages in use.
- * As there currently is no registered WBXML type with support of more
- * than one tag or attribute code page, this is a safe assumption.
+ * - Code page switches only apply to the following token. In the WBXML/1.x
+ * ABNF notation, it can be proven that the switch_page can only precede
+ * the following tokens:
+ * o stag : TAG | LITERAL | LITERAL_A | LITERAL_C | LITERAL_AC
+ * o attr : ATTRSTART | ATTRVALUE
+ * o extension : EXT_I | EXT_T | EXT
+ * Code page switches are displayed in a separate column. The only allowed
+ * code page switches are from code page 0 to another codepage (by means of
+ * a SWITCH_PAGE token), and from this other code page back to code page 0
+ * (this happens automatically).
*
* - In order to render the XML content, recursion is inevitable at some
* point (when a tag with content occurs in the content of a tag with
@@ -74,10 +77,45 @@
* is defined for the parsed WBXML content, then the XML rendering is
* displayed with appropriate indentation (maximum nesting level = 255,
* after which the nesting and level will safely roll-over to 0).
+ *
+ * - The WAP Forum defines the order of precedence for finding out the
+ * WBXML content type (same rules for charset) as follows:
+ * 1. Look in the Content-Type WSP header
+ * 2. Look in the WBXML header
+ * Currently there is no means of using content type parameters:
+ * o Type=<some_type>
+ * o Charset=<charset_of_the_content>
+ * So it is possible some WBXML content types are incorrectly parsed.
+ * This would only be the case when the content type declaration in the
+ * WSP Content-Type header would be different (or would have parameters
+ * which are relevant to the WBXML decoding) from the content type
+ * identifier specified in the WBXML header.
+ * TODO: investigate this and provide correct decoding at all times.
*/
+typedef struct _value_valuestring {
+ guint32 value;
+ const value_string *valstrptr;
+} value_valuestring;
+
+/* Tries to match val against each element in the value_value_string array vvs.
+ * Returns the associated value_string ptr on a match, or NULL on failure. */
+static const value_string *
+val_to_valstr(guint32 val, const value_valuestring *vvs)
+{
+ gint i = 0;
+
+ while (vvs[i].valstrptr) {
+ if (vvs[i].value == val)
+ return(vvs[i].valstrptr);
+ i++;
+ }
+
+ return(NULL);
+}
+
-/************************* Variable declarations *************************/
+/************************** Variable declarations **************************/
/* Initialize the protocol and registered fields */
@@ -93,25 +131,11 @@ static gint ett_wbxml_str_tbl = -1;
static gint ett_wbxml_content = -1;
+/**************** WBXML related declarations and definitions ****************/
-/********** WBXML related declarations and definitions **********/
-
-/* See http://www.wapforum.org/wina/ for an up-to-date list. */
-#define WBXML_WML_10 0x02
-#define WBXML_WTA_10 0x03
-#define WBXML_WML_11 0x04
-#define WBXML_SI_10 0x05
-#define WBXML_SL_10 0x06
-#define WBXML_CO_10 0x07
-#define WBXML_CHANNEL_10 0x08
-#define WBXML_WML_12 0x09
-#define WBXML_WML_13 0x0a
-#define WBXML_PROV_10 0x0b
-#define WBXML_WTAWML_12 0x0c
-#define WBXML_EMN_10 0x0d
-#define WBXML_DRMREL_10 0x0e
- /* http://www.wapforum.org/wina/wbxml-public-docid.htm */
+/* WBXML public ID mappings. For an up-to-date list, see
+ * http://www.wapforum.org/wina/wbxml-public-docid.htm */
static const value_string vals_wbxml_public_ids[] = {
/* 0x00 = literal public identifier */
{ 0x01, "Unknown / missing Public Identifier" },
@@ -129,7 +153,11 @@ static const value_string vals_wbxml_public_ids[] = {
{ 0x0d, "-//WAPFORUM//DTD EMN 1.0//EN (Email Notification 1.0)" },
{ 0x0e, "-//WAPFORUM//DTD DRMREL 1.0//EN (DRMREL 1.0)" },
- /* Registered values */
+ /* Registered values - www.syncml.org */
+ { 0x0fd1, "-//SYNCML//DTD SyncML 1.0//EN (SyncML 1.0)" },
+ { 0x0fd3, "-//SYNCML//DTD SyncML 1.1//EN (SyncML 1.1)" },
+
+ /* Registered values - www.wapforum.org/wina/ */
{ 0x1100, "-//PHONE.COM//DTD ALERT 1.0//EN" },
{ 0x1101, "-//PHONE.COM//DTD CACHE-OPERATION 1.0//EN" },
{ 0x1102, "-//PHONE.COM//DTD SIGNAL 1.0//EN" },
@@ -149,13 +177,11 @@ static const value_string vals_wbxml_public_ids[] = {
{ 0x00, NULL }
};
-
-
static const value_string vals_wbxml_versions[] = {
- { 0x00, "1.0" },
- { 0x01, "1.1" },
- { 0x02, "1.2" },
- { 0x03, "1.3" },
+ { 0x00, "1.0" }, /* WAP-104-WBXML */
+ { 0x01, "1.1" }, /* WAP-135-WBXML */
+ { 0x02, "1.2" }, /* WAP-154-WBXML */
+ { 0x03, "1.3" }, /* WAP-192-WBXML */
{ 0x00, NULL }
};
@@ -219,12 +245,16 @@ static const value_string vals_wbxml1x_global_tokens[] = {
};
-/****************************************************************************/
+/********************** WBXML token mapping definition **********************/
+
-/*******************************************
- * WML 1.0 - Global tokens (EXT) *
- *******************************************/
-static const value_string vals_wmlc10_global[] = {
+/* WML 1.0
+ *
+ * Wireless Markup Language
+ ***************************************/
+
+/***** Global extension tokens *****/
+static const value_string wbxml_wmlc10_global_cp0[] = {
{ 0x40, "Variable substitution - escaped" },
{ 0x41, "Variable substitution - unescaped" },
{ 0x42, "Variable substitution - no transformation" },
@@ -238,10 +268,8 @@ static const value_string vals_wmlc10_global[] = {
{ 0x00, NULL }
};
-/*******************************************
- * WML 1.0 - Tags *
- *******************************************/
-static const value_string vals_wmlc10_tags[] = {
+/***** Tag tokens *****/
+static const value_string wbxml_wmlc10_tags_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
/* 0x05 -- 0xE1 */
{ 0xE2, "A" },
@@ -278,10 +306,8 @@ static const value_string vals_wmlc10_tags[] = {
{ 0x00, NULL }
};
-/*******************************************
- * WML 1.0 - Attribute Start *
- *******************************************/
-static const value_string vals_wmlc10_attrStart[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_wmlc10_attrStart_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "ACCEPT-CHARSET=" },
{ 0x06, "ALIGN='BOTTOM'" },
@@ -360,10 +386,8 @@ static const value_string vals_wmlc10_attrStart[] = {
{ 0x00, NULL }
};
-/*******************************************
- * WML 1.0 - Attribute Value *
- *******************************************/
-static const value_string vals_wmlc10_attrValue[] = {
+/***** Attribute Value tokens *****/
+static const value_string wbxml_wmlc10_attrValue_cp0[] = {
/* 0x80 -- 0x84 GLOBAL */
{ 0x85, "'.com/'" },
{ 0x86, "'.edu/'" },
@@ -398,17 +422,41 @@ static const value_string vals_wmlc10_attrValue[] = {
{ 0x00, NULL }
};
-/****************************************************************************/
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_wmlc10_global[] = {
+ { 0, wbxml_wmlc10_global_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_wmlc10_tags[] = {
+ { 0, wbxml_wmlc10_tags_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_wmlc10_attrStart[] = {
+ { 0, wbxml_wmlc10_attrStart_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_wmlc10_attrValue[] = {
+ { 0, wbxml_wmlc10_attrValue_cp0 },
+ { 0, NULL }
+};
+
+
-/*******************************************
- * WML 1.1 - Global tokens (EXT) *
- *******************************************/
-#define vals_wmlc11_global vals_wmlc10_global
-/*******************************************
- * WML 1.1 - Tags *
- *******************************************/
-static const value_string vals_wmlc11_tags[] = {
+
+/* WML 1.1
+ *
+ * Wireless Markup Language
+ ***************************************/
+
+/***** Global extension tokens *****/
+/* Same as in WML 1.0 */
+
+/***** Tag tokens *****/
+static const value_string wbxml_wmlc11_tags_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
/* 0x05 -- 0x1B */
{ 0x1C, "a" },
@@ -451,10 +499,8 @@ static const value_string vals_wmlc11_tags[] = {
{ 0x00, NULL }
};
-/*******************************************
- * WML 1.1 - Attribute Start *
- *******************************************/
-static const value_string vals_wmlc11_attrStart[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_wmlc11_attrStart_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "accept-charset=" },
{ 0x06, "align='bottom'" },
@@ -543,10 +589,8 @@ static const value_string vals_wmlc11_attrStart[] = {
{ 0x00, NULL }
};
-/*******************************************
- * WML 1.1 - Attribute Value *
- *******************************************/
-static const value_string vals_wmlc11_attrValue[] = {
+/***** Attribute Value tokens *****/
+static const value_string wbxml_wmlc11_attrValue_cp0[] = {
/* 0x80 -- 0x84 GLOBAL */
{ 0x85, "'.com/'" },
{ 0x86, "'.edu/'" },
@@ -581,17 +625,41 @@ static const value_string vals_wmlc11_attrValue[] = {
{ 0x00, NULL }
};
-/****************************************************************************/
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_wmlc11_global[] = {
+ { 0, wbxml_wmlc10_global_cp0 }, /* Same as WML 1.0 */
+ { 0, NULL }
+};
-/*******************************************
- * WML 1.2 - Global tokens (EXT) *
- *******************************************/
-#define vals_wmlc12_global vals_wmlc11_global
-
-/*******************************************
- * WML 1.2 - Tags *
- *******************************************/
-static const value_string vals_wmlc12_tags[] = {
+static const value_valuestring wbxml_wmlc11_tags[] = {
+ { 0, wbxml_wmlc11_tags_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_wmlc11_attrStart[] = {
+ { 0, wbxml_wmlc11_attrStart_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_wmlc11_attrValue[] = {
+ { 0, wbxml_wmlc11_attrValue_cp0 },
+ { 0, NULL }
+};
+
+
+
+
+
+/* WML 1.2
+ *
+ * Wireless Markup Language
+ ***************************************/
+
+/***** Global extension tokens *****/
+/* Same as in WML 1.0 */
+
+/***** Tag tokens *****/
+static const value_string wbxml_wmlc12_tags_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
/* 0x05 -- 0x1A */
{ 0x1B, "pre" },
@@ -635,10 +703,8 @@ static const value_string vals_wmlc12_tags[] = {
{ 0x00, NULL }
};
-/*******************************************
- * WML 1.2 - Attribute Start *
- *******************************************/
-static const value_string vals_wmlc12_attrStart[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_wmlc12_attrStart_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "accept-charset=" },
{ 0x06, "align='bottom'" },
@@ -731,30 +797,47 @@ static const value_string vals_wmlc12_attrStart[] = {
{ 0x00, NULL }
};
-/*******************************************
- * WML 1.2 - Attribute Value *
- *******************************************/
-#define vals_wmlc12_attrValue vals_wmlc11_attrValue
-/* Same as WML 1.1 */
+/***** Attribute Value tokens *****/
+/* Same as in WML 1.1 */
+
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_wmlc12_global[] = {
+ { 0, wbxml_wmlc10_global_cp0 }, /* Same as WML 1.0 */
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_wmlc12_tags[] = {
+ { 0, wbxml_wmlc12_tags_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_wmlc12_attrStart[] = {
+ { 0, wbxml_wmlc12_attrStart_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_wmlc12_attrValue[] = {
+ { 0, wbxml_wmlc11_attrValue_cp0 }, /* Same as WML 1.1 */
+ { 0, NULL }
+};
+
+
-/****************************************************************************/
-/*******************************************
- * WML 1.3 - Global tokens (EXT) *
- *******************************************/
-#define vals_wmlc13_global vals_wmlc11_global
+/* WML 1.3
+ *
+ * Wireless Markup Language
+ ***************************************/
+
+/***** Global extension tokens *****/
+/* Same as in WML 1.0 */
-/*******************************************
- * WML 1.3 - Tags *
- *******************************************/
-#define vals_wmlc13_tags vals_wmlc12_tags
-/* Same as WML 1.1 */
+/***** Tag tokens *****/
+/* Same as in WML 1.2 */
-/*******************************************
- * WML 1.3 - Attribute Start *
- *******************************************/
-static const value_string vals_wmlc13_attrStart[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_wmlc13_attrStart_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "accept-charset=" },
{ 0x06, "align='bottom'" },
@@ -850,27 +933,43 @@ static const value_string vals_wmlc13_attrStart[] = {
{ 0x00, NULL }
};
-/*******************************************
- * WML 1.3 - Attribute Value *
- *******************************************/
-#define vals_wmlc13_attrValue vals_wmlc11_attrValue
-/* Same as WML 1.1 */
+/***** Attribute Value tokens *****/
+/* Same as in WML 1.1 */
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_wmlc13_global[] = {
+ { 0, wbxml_wmlc10_global_cp0 }, /* Same as WML 1.0 */
+ { 0, NULL }
+};
-/****************************************************************************/
+static const value_valuestring wbxml_wmlc13_tags[] = {
+ { 0, wbxml_wmlc12_tags_cp0 },
+ { 0, NULL }
+};
-/*******************************************
- * SI 1.0 - Global tokens (EXT) *
- *******************************************/
-static const value_string vals_sic10_global[] = {
- { 0x00, NULL }
+static const value_valuestring wbxml_wmlc13_attrStart[] = {
+ { 0, wbxml_wmlc13_attrStart_cp0 },
+ { 0, NULL }
};
+static const value_valuestring wbxml_wmlc13_attrValue[] = {
+ { 0, wbxml_wmlc11_attrValue_cp0 }, /* Same as WML 1.1 */
+ { 0, NULL }
+};
-/*******************************************
- * SI 1.0 - Tags *
- *******************************************/
-static const value_string vals_sic10_tags[] = {
+
+
+
+
+/* SI 1.0
+ *
+ * Service Indication
+ ***************************************/
+
+/***** Global extension tokens *****/
+
+/***** Tag tokens *****/
+static const value_string wbxml_sic10_tags_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "si" },
{ 0x06, "indication" },
@@ -880,10 +979,8 @@ static const value_string vals_sic10_tags[] = {
{ 0x00, NULL }
};
-/*******************************************
- * SI 1.0 - Attribute Start *
- *******************************************/
-static const value_string vals_sic10_attrStart[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_sic10_attrStart_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "action='signal-none'" },
{ 0x06, "action='signal-low'" },
@@ -903,10 +1000,8 @@ static const value_string vals_sic10_attrStart[] = {
{ 0x00, NULL }
};
-/*******************************************
- * SI 1.0 - Attribute Value *
- *******************************************/
-static const value_string vals_sic10_attrValue[] = {
+/***** Attribute Value tokens *****/
+static const value_string wbxml_sic10_attrValue_cp0[] = {
/* 0x80 -- 0x84 GLOBAL */
{ 0x85, "'.com/'" },
{ 0x86, "'.edu/'" },
@@ -916,31 +1011,43 @@ static const value_string vals_sic10_attrValue[] = {
{ 0x00, NULL }
};
-/****************************************************************************/
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_sic10_tags[] = {
+ { 0, wbxml_sic10_tags_cp0 },
+ { 0, NULL }
+};
+static const value_valuestring wbxml_sic10_attrStart[] = {
+ { 0, wbxml_sic10_attrStart_cp0 },
+ { 0, NULL }
+};
-/*******************************************
- * SL 1.0 - Global tokens (EXT) *
- *******************************************/
-static const value_string vals_slc10_global[] = {
- { 0x00, NULL }
+static const value_valuestring wbxml_sic10_attrValue[] = {
+ { 0, wbxml_sic10_attrValue_cp0 },
+ { 0, NULL }
};
-/*******************************************
- * SL 1.0 - Tags *
- *******************************************/
-static const value_string vals_slc10_tags[] = {
+
+
+
+/* SL 1.0
+ *
+ * Service Loading
+ ***************************************/
+
+/***** Global extension tokens *****/
+
+/***** Tag tokens *****/
+static const value_string wbxml_slc10_tags_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "sl" },
{ 0x00, NULL }
};
-/*******************************************
- * SL 1.0 - Attribute Start *
- *******************************************/
-static const value_string vals_slc10_attrStart[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_slc10_attrStart_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "action='execute-low'" },
{ 0x06, "action='execute-high'" },
@@ -954,34 +1061,38 @@ static const value_string vals_slc10_attrStart[] = {
{ 0x00, NULL }
};
-/*******************************************
- * SL 1.0 - Attribute Value *
- *******************************************/
-static const value_string vals_slc10_attrValue[] = {
- /* 0x80 -- 0x84 GLOBAL */
- { 0x85, "'.com/'" },
- { 0x86, "'.edu/'" },
- { 0x87, "'.net/'" },
- { 0x88, "'.org/'" },
+/***** Attribute Value tokens *****/
+/* Same as in SI 1.0 */
- { 0x00, NULL }
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_slc10_tags[] = {
+ { 0, wbxml_slc10_tags_cp0 },
+ { 0, NULL }
};
-/****************************************************************************/
-
+static const value_valuestring wbxml_slc10_attrStart[] = {
+ { 0, wbxml_slc10_attrStart_cp0 },
+ { 0, NULL }
+};
-/*******************************************
- * CO 1.0 - Global tokens (EXT) *
- *******************************************/
-static const value_string vals_coc10_global[] = {
- { 0x00, NULL }
+static const value_valuestring wbxml_slc10_attrValue[] = {
+ { 0, wbxml_sic10_attrValue_cp0 }, /* Same as SI 1.0 */
+ { 0, NULL }
};
-/*******************************************
- * CO 1.0 - Tags *
- *******************************************/
-static const value_string vals_coc10_tags[] = {
+
+
+
+/* CO 1.0
+ *
+ * Cache Operation
+ ***************************************/
+
+/***** Global extension tokens *****/
+
+/***** Tag tokens *****/
+static const value_string wbxml_coc10_tags_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "co" },
{ 0x06, "invalidate-object" },
@@ -990,10 +1101,8 @@ static const value_string vals_coc10_tags[] = {
{ 0x00, NULL }
};
-/*******************************************
- * CO 1.0 - Attribute Start *
- *******************************************/
-static const value_string vals_coc10_attrStart[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_coc10_attrStart_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "uri=" },
{ 0x06, "uri='http://'" },
@@ -1004,35 +1113,38 @@ static const value_string vals_coc10_attrStart[] = {
{ 0x00, NULL }
};
-/*******************************************
- * CO 1.0 - Attribute Value *
- *******************************************/
-static const value_string vals_coc10_attrValue[] = {
- /* 0x80 -- 0x84 GLOBAL */
- { 0x85, "'.com/'" },
- { 0x86, "'.edu/'" },
- { 0x87, "'.net/'" },
- { 0x88, "'.org/'" },
+/***** Attribute Value tokens *****/
+/* Same as in SI 1.0 */
- { 0x00, NULL }
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_coc10_tags[] = {
+ { 0, wbxml_coc10_tags_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_coc10_attrStart[] = {
+ { 0, wbxml_coc10_attrStart_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_coc10_attrValue[] = {
+ { 0, wbxml_sic10_attrValue_cp0 }, /* Same as SI 1.0 */
+ { 0, NULL }
};
-/****************************************************************************/
-/*******************************************
- * PROV 1.0 - Global tokens (EXT) *
- *******************************************/
-static const value_string vals_provc10_global[] = {
- { 0x00, NULL }
-};
+/* PROV 1.0
+ *
+ * Client Provisioning
+ ***************************************/
+
+/***** Global extension tokens *****/
-/*******************************************
- * PROV 1.0 - Tags *
- *******************************************/
-static const value_string vals_provc10_tags[] = {
+/***** Tag tokens *****/
+static const value_string wbxml_provc10_tags_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "wap-provisioningdoc" },
{ 0x06, "characteristic" },
@@ -1041,10 +1153,8 @@ static const value_string vals_provc10_tags[] = {
{ 0x00, NULL }
};
-/*******************************************
- * PROV 1.0 - Attribute Start *
- *******************************************/
-static const value_string vals_provc10_attrStart[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_provc10_attrStart_cp0[] = {
/* 0x00 -- 0x04 GLOBAL */
{ 0x05, "name=" },
{ 0x06, "value=" },
@@ -1122,10 +1232,8 @@ static const value_string vals_provc10_attrStart[] = {
{ 0x00, NULL }
};
-/*******************************************
- * PROV 1.0 - Attribute Value *
- *******************************************/
-static const value_string vals_provc10_attrValue[] = {
+/***** Attribute Start tokens *****/
+static const value_string wbxml_provc10_attrValue_cp0[] = {
/* 0x80 -- 0x84 GLOBAL */
{ 0x85, "'IPV4'" },
{ 0x86, "'IPV6'" },
@@ -1186,160 +1294,572 @@ static const value_string vals_provc10_attrValue[] = {
{ 0x00, NULL }
};
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_provc10_tags[] = {
+ { 0, wbxml_provc10_tags_cp0 },
+ { 0, NULL }
+};
-/****************************************************************************/
+static const value_valuestring wbxml_provc10_attrStart[] = {
+ { 0, wbxml_provc10_attrStart_cp0 },
+ { 0, NULL }
+};
+static const value_valuestring wbxml_provc10_attrValue[] = {
+ { 0, wbxml_provc10_attrValue_cp0 },
+ { 0, NULL }
+};
-/* The struct object contains references to objects defined above!
- */
-typedef struct {
- const guint8 defined;
- const value_string *global;
- const value_string *tags;
- const value_string *attrStart;
- const value_string *attrValue;
-} wbxml_mapping_table;
-/* BEWARE: values 0 and 1 are not defined, so we start from 2
+
+/* EMN 1.0
+ *
+ * Email Notification
+ ***************************************/
+
+/***** Global extension tokens *****/
+
+/***** Tag tokens *****/
+static const value_string wbxml_emnc10_tags_cp0[] = {
+ /* 0x00 -- 0x04 GLOBAL */
+ { 0x05, "emn" },
+
+ { 0x00, NULL }
+};
+
+/***** Attribute Start tokens *****/
+static const value_string wbxml_emnc10_attrStart_cp0[] = {
+ /* 0x00 -- 0x04 GLOBAL */
+ { 0x05, "timestamp=" },
+ { 0x06, "mailbox=" },
+ { 0x07, "mailbox='mailat:'" },
+ { 0x08, "mailbox='pop://'" },
+ { 0x09, "mailbox='imap://'" },
+ { 0x0a, "mailbox='http://'" },
+ { 0x0b, "mailbox='http://www.'" },
+ { 0x0c, "mailbox='https://'" },
+ { 0x0D, "mailbox='https://www.'" },
+
+ { 0x00, NULL }
+};
+
+/***** Attribute Value tokens *****/
+/* Same as in SI 1.0 */
+
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_emnc10_tags[] = {
+ { 0, wbxml_emnc10_tags_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_emnc10_attrStart[] = {
+ { 0, wbxml_emnc10_attrStart_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_emnc10_attrValue[] = {
+ { 0, wbxml_sic10_attrValue_cp0 }, /* Same as SI 1.0 */
+ { 0, NULL }
+};
+
+
+
+
+
+/* SyncML 1.0
+ *
+ * SyncML Representation Protocol
+ ***************************************/
+
+/***** Global extension tokens *****/
+
+/***** Tag tokens *****/
+static const value_string wbxml_syncmlc10_tags_cp0[] = { /* SyncML 1.0 */
+ /* 0x00 -- 0x04 GLOBAL */
+ { 0x05, "Add" },
+ { 0x06, "Alert" },
+ { 0x07, "Archive" },
+ { 0x08, "Atomic" },
+ { 0x09, "Chal" },
+ { 0x0A, "Cmd" },
+ { 0x0B, "CmdID" },
+ { 0x0C, "CmdRef" },
+ { 0x0D, "Copy" },
+ { 0x0E, "Cred" },
+ { 0x0F, "Data" },
+ { 0x10, "Delete" },
+ { 0x11, "Exec" },
+ { 0x12, "Final" },
+ { 0x13, "Get" },
+ { 0x14, "Item" },
+ { 0x15, "Lang" },
+ { 0x16, "LocName" },
+ { 0x17, "LocURI" },
+ { 0x18, "Map" },
+ { 0x19, "MapItem" },
+ { 0x1A, "Meta" },
+ { 0x1B, "MsgID" },
+ { 0x1C, "MsgRef" },
+ { 0x1D, "NoResp" },
+ { 0x1E, "NoResults" },
+ { 0x1F, "Put" },
+ { 0x20, "Replace" },
+ { 0x21, "RespURI" },
+ { 0x22, "Results" },
+ { 0x23, "Search" },
+ { 0x24, "Sequence" },
+ { 0x25, "SessionID" },
+ { 0x26, "SftDel" },
+ { 0x27, "Source" },
+ { 0x28, "SourceRef" },
+ { 0x29, "Status" },
+ { 0x2A, "Sync" },
+ { 0x2B, "SyncBody" },
+ { 0x2C, "SyncHdr" },
+ { 0x2D, "SyncML" },
+ { 0x2E, "Target" },
+ { 0x2F, "TargetRef" },
+ /* 0x30 - Reserved */
+ { 0x31, "VerDTD" },
+ { 0x32, "VerProto" },
+
+ { 0x00, NULL }
+};
+
+static const value_string wbxml_syncmlc10_tags_cp1[] = { /* MetInf 1.0 */
+ /* 0x00 -- 0x04 GLOBAL */
+ { 0x05, "Anchor" },
+ { 0x06, "EMI" },
+ { 0x07, "Format" },
+ { 0x08, "FreeID" },
+ { 0x09, "FreeMem" },
+ { 0x0A, "Last" },
+ { 0x0B, "Mark" },
+ { 0x0C, "MaxMsgSize" },
+ { 0x0D, "Mem" },
+ { 0x0E, "MetInf" },
+ { 0x0F, "Next" },
+ { 0x10, "NextNonce" },
+ { 0x11, "SharedMem" },
+ { 0x12, "Size" },
+ { 0x13, "Type" },
+ { 0x14, "Version" },
+
+ { 0x00, NULL }
+};
+
+/***** Attribute Start tokens *****/
+
+/***** Attribute Value tokens *****/
+
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_syncmlc10_tags[] = {
+ { 0, wbxml_syncmlc10_tags_cp0 }, /* -//SYNCML//DTD SyncML 1.0//EN */
+ { 0, wbxml_syncmlc10_tags_cp1 }, /* -//SYNCML//DTD MetInf 1.0//EN */
+ { 0, NULL }
+};
+
+
+
+
+
+/* SyncML 1.1
+ *
+ * SyncML Representation Protocol
+ ***************************************/
+
+/***** Global extension tokens *****/
+
+/***** Tag tokens *****/
+static const value_string wbxml_syncmlc11_tags_cp0[] = { /* SyncML 1.1 */
+ /* 0x00 -- 0x04 GLOBAL */
+ { 0x05, "Add" },
+ { 0x06, "Alert" },
+ { 0x07, "Archive" },
+ { 0x08, "Atomic" },
+ { 0x09, "Chal" },
+ { 0x0a, "Cmd" },
+ { 0x0b, "CmdID" },
+ { 0x0c, "CmdRef" },
+ { 0x0d, "Copy" },
+ { 0x0e, "Cred" },
+ { 0x0f, "Data" },
+ { 0x10, "Delete" },
+ { 0x11, "Exec" },
+ { 0x12, "Final" },
+ { 0x13, "Get" },
+ { 0x14, "Item" },
+ { 0x15, "Lang" },
+ { 0x16, "LocName" },
+ { 0x17, "LocURI" },
+ { 0x18, "Map" },
+ { 0x19, "MapItem" },
+ { 0x1a, "Meta" },
+ { 0x1b, "MsgID" },
+ { 0x1c, "MsgRef" },
+ { 0x1d, "NoResp" },
+ { 0x1e, "NoResults" },
+ { 0x1f, "Put" },
+ { 0x20, "Replace" },
+ { 0x21, "RespURI" },
+ { 0x22, "Results" },
+ { 0x23, "Search" },
+ { 0x24, "Sequence" },
+ { 0x25, "SessionID" },
+ { 0x26, "SftDel" },
+ { 0x27, "Source" },
+ { 0x28, "SourceRef" },
+ { 0x29, "Status" },
+ { 0x2a, "Sync" },
+ { 0x2b, "SyncBody" },
+ { 0x2c, "SyncHdr" },
+ { 0x2d, "SyncML" },
+ { 0x2e, "Target" },
+ { 0x2f, "TargetRef" },
+ /* 0x30 - Reserved */
+ { 0x31, "VerDTD" },
+ { 0x32, "VerProto" },
+ { 0x33, "NumberOfChanges" },
+ { 0x34, "MoreData" },
+
+ { 0x00, NULL }
+};
+
+static const value_string wbxml_syncmlc11_tags_cp1[] = { /* MetInf 1.1 */
+ /* 0x00 -- 0x04 GLOBAL */
+ { 0x05, "Anchor" },
+ { 0x06, "EMI" },
+ { 0x07, "Format" },
+ { 0x08, "FreeID" },
+ { 0x09, "FreeMem" },
+ { 0x0A, "Last" },
+ { 0x0B, "Mark" },
+ { 0x0C, "MaxMsgSize" },
+ { 0x0D, "Mem" },
+ { 0x0E, "MetInf" },
+ { 0x0F, "Next" },
+ { 0x10, "NextNonce" },
+ { 0x11, "SharedMem" },
+ { 0x12, "Size" },
+ { 0x13, "Type" },
+ { 0x14, "Version" },
+ { 0x15, "MaxObjSize" },
+
+ { 0x00, NULL }
+};
+
+/***** Attribute Start tokens *****/
+
+/***** Attribute Value tokens *****/
+
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_syncmlc11_tags[] = {
+ { 0, wbxml_syncmlc11_tags_cp0 }, /* -//SYNCML//DTD SyncML 1.1//EN */
+ { 0, wbxml_syncmlc11_tags_cp1 }, /* -//SYNCML//DTD MetInf 1.1//EN */
+ { 0, NULL }
+};
+
+
+
+
+
+/* CHANNEL 1.0
+ *
+ * WTA Channel
+ ***************************************/
+
+/***** Global extension tokens *****/
+
+/***** Tag tokens *****/
+static const value_string wbxml_channelc10_tags_cp0[] = {
+ /* 0x00 -- 0x04 GLOBAL */
+ { 0x05, "channel" },
+ { 0x06, "title" },
+ { 0x07, "abstract" },
+ { 0x08, "resource" },
+
+ { 0x00, NULL }
+};
+
+/***** Attribute Start tokens *****/
+static const value_string wbxml_channelc10_attrStart_cp0[] = {
+ /* 0x00 -- 0x04 GLOBAL */
+ { 0x05, "maxspace" },
+ { 0x06, "base" },
+ { 0x07, "href" },
+ { 0x08, "href='http://'" },
+ { 0x09, "href='https://'" },
+ { 0x0A, "lastmod" },
+ { 0x0B, "etag" },
+ { 0x0C, "md5" },
+ { 0x0D, "success" },
+ { 0x0E, "success='http://'" },
+ { 0x0F, "success='https://'" },
+ { 0x10, "failure" },
+ { 0x11, "failure='http://'" },
+ { 0x12, "failure='https://'" },
+ { 0x13, "EventId" },
+
+ { 0x00, NULL }
+};
+
+/***** Attribute Value tokens *****/
+
+/***** Token code page aggregation *****/
+static const value_valuestring wbxml_channelc10_tags[] = {
+ { 0, wbxml_channelc10_tags_cp0 },
+ { 0, NULL }
+};
+
+static const value_valuestring wbxml_channelc10_attrStart[] = {
+ { 0, wbxml_channelc10_attrStart_cp0 },
+ { 0, NULL }
+};
+
+
+
+
+
+/********************** WBXML token mapping aggregation **********************/
+
+
+/* The following structure links content types to their token mapping and
+ * contains arrays of pointers to value_string arrays (one per code page).
*/
-static const wbxml_mapping_table wbxml_map[] = {
- { /* 0x00 = literal public identifier */
- FALSE, NULL, NULL, NULL, NULL
+typedef struct _wbxml_token_map {
+ const guint32 publicid; /* WBXML DTD number - see WINA */
+ const guint8 defined; /* Are there mapping tables defined */
+ const value_valuestring *global; /* Global token map */
+ const value_valuestring *tags; /* Tag token map */
+ const value_valuestring *attrStart; /* Attribute Start token map */
+ const value_valuestring *attrValue; /* Attribute Value token map */
+} wbxml_token_map;
+
+static const wbxml_token_map *wbxml_content_map (guint32 publicid);
+
+/**
+ ** Aggregation of content type and aggregated code pages
+ ** Content type map lookup will stop at the 1st entry with 2nd member = FALSE
+ **/
+static const wbxml_token_map map[] = {
+#ifdef Test_the_parsers_without_token_mappings
+ { 0, FALSE, NULL, NULL, NULL, NULL },
+#endif
+ { 0x02, TRUE, /* WML 1.0 */
+ wbxml_wmlc10_global,
+ wbxml_wmlc10_tags,
+ wbxml_wmlc10_attrStart,
+ wbxml_wmlc10_attrValue
},
- { /* 0x01 = Unknown or missing public identifier */
- FALSE, NULL, NULL, NULL, NULL
+#ifdef remove_directive_and_set_TRUE_if_mapping_available
+ { 0x03, FALSE, /* WTA 1.0 (deprecated) */
+ NULL, NULL, NULL, NULL
},
- { /* 0x02 = WML 1.0 */
- TRUE, vals_wmlc10_global, vals_wmlc10_tags,
- vals_wmlc10_attrStart, vals_wmlc10_attrValue
+#endif
+ { 0x04, TRUE, /* WML 1.1 */
+ wbxml_wmlc11_global,
+ wbxml_wmlc11_tags,
+ wbxml_wmlc11_attrStart,
+ wbxml_wmlc11_attrValue
},
- { /* 0x03 = WTA 1.0 - Deprecated */
- FALSE, NULL, NULL, NULL, NULL
+ { 0x05, TRUE, /* SI 1.0 */
+ NULL, /* wbxml_sic10_global - does not exist */
+ wbxml_sic10_tags,
+ wbxml_sic10_attrStart,
+ wbxml_sic10_attrValue
},
- { /* 0x04 = WML 1.1 */
- TRUE, vals_wmlc11_global, vals_wmlc11_tags,
- vals_wmlc11_attrStart, vals_wmlc11_attrValue
+ { 0x06, TRUE, /* SL 1.0 */
+ NULL, /* wbxml_slc10_global - does not exist */
+ wbxml_slc10_tags,
+ wbxml_slc10_attrStart,
+ wbxml_slc10_attrValue
},
- { /* 0x05 = SI 1.0 */
- TRUE, vals_sic10_global, vals_sic10_tags,
- vals_sic10_attrStart, vals_sic10_attrValue
+ { 0x07, TRUE, /* CO 1.0 */
+ NULL, /* wbxml_coc10_global - does not exist */
+ wbxml_coc10_tags,
+ wbxml_coc10_attrStart,
+ wbxml_coc10_attrValue
},
- { /* 0x06 = SL 1.0 */
- TRUE, vals_slc10_global, vals_slc10_tags,
- vals_slc10_attrStart, vals_slc10_attrValue
+ { 0x08, TRUE, /* CHANNEL 1.0 (deprecated) */
+ NULL, /* wbxml_channelc10_global - does not exist */
+ wbxml_channelc10_tags,
+ wbxml_channelc10_attrStart,
+ NULL, /* wbxml_channelc10_attrValue - does not exist */
},
- { /* 0x07 = CO 1.0 */
- TRUE, vals_coc10_global, vals_coc10_tags,
- vals_coc10_attrStart, vals_coc10_attrValue
+ { 0x09, TRUE, /* WML 1.2 */
+ wbxml_wmlc12_global,
+ wbxml_wmlc12_tags,
+ wbxml_wmlc12_attrStart,
+ wbxml_wmlc12_attrValue
},
- { /* 0x08 = CHANNEL 1.0 */
- FALSE, NULL, NULL, NULL, NULL
+ { 0x0A, TRUE, /* WML 1.3 */
+ wbxml_wmlc13_global,
+ wbxml_wmlc13_tags,
+ wbxml_wmlc13_attrStart,
+ wbxml_wmlc13_attrValue
},
- { /* 0x09 = WML 1.2 */
- TRUE, vals_wmlc12_global, vals_wmlc12_tags,
- vals_wmlc12_attrStart, vals_wmlc12_attrValue
+ { 0x0B, TRUE, /* PROV 1.0 */
+ NULL, /* wbxml_provc10_global - does not exist */
+ wbxml_provc10_tags,
+ wbxml_provc10_attrStart,
+ wbxml_provc10_attrValue
},
- { /* 0x0A = WML 1.3 */
- TRUE, vals_wmlc13_global, vals_wmlc13_tags,
- vals_wmlc13_attrStart, vals_wmlc13_attrValue
+#ifdef remove_directive_and_set_TRUE_if_mapping_available
+ { 0x0C, FALSE, /* WTA-WML 1.2 */
+ NULL, NULL, NULL, NULL
},
- { /* 0x0B = PROV 1.0 */
- TRUE, vals_provc10_global, vals_provc10_tags,
- vals_provc10_attrStart, vals_provc10_attrValue
+#endif
+ { 0x0D, TRUE, /* EMN 1.0 */
+ NULL, /* wbxml_emnc10_global - does not exist */
+ wbxml_emnc10_tags,
+ wbxml_emnc10_attrStart,
+ wbxml_emnc10_attrValue
},
- { /* 0x0C = WTA-WML 1.2 */
- FALSE, NULL, NULL, NULL, NULL
+#ifdef remove_directive_and_set_TRUE_if_mapping_available
+ { 0x0E, FALSE, /* DRMREL 1.0 */
+ NULL, NULL, NULL, NULL
},
- { /* 0x0D = EMN 1.0 */
- FALSE, NULL, NULL, NULL, NULL
+#endif
+ { 0x0FD1, TRUE, /* SyncML 1.0 */
+ NULL, /* wbxml_syncmlc10_global - does not exist */
+ wbxml_syncmlc10_tags,
+ NULL, /* wbxml_syncmlc10_attrStart - does not exist */
+ NULL, /* wbxml_syncmlc10_attrValue - does not exist */
},
- { /* 0x0E = DRMREL 1.0 */
- FALSE, NULL, NULL, NULL, NULL
+ { 0x0FD3, TRUE, /* SyncML 1.1 */
+ NULL, /* wbxml_syncmlc11_global - does not exist */
+ wbxml_syncmlc11_tags,
+ NULL, /* wbxml_syncmlc11_attrStart - does not exist */
+ NULL, /* wbxml_syncmlc11_attrValue - does not exist */
},
+ { 0x1108, TRUE, /* Phone.com - WML+ 1.1 */
+ /* Note: I assumed WML+ 1.1 would be not that different from WML 1.1,
+ * the real mapping should come from Phone.com (OpenWave)! */
+ wbxml_wmlc11_global, /* Not 100% true */
+ wbxml_wmlc11_tags, /* Not 100% true */
+ wbxml_wmlc11_attrStart, /* Not 100% true */
+ wbxml_wmlc11_attrValue /* Not 100% true */
+ },
+ { 0x110D, TRUE, /* Phone.com - WML+ 1.3 */
+ /* Note: I assumed WML+ 1.3 would be not that different from WML 1.3,
+ * the real mapping should come from Phone.com (OpenWave)! */
+ wbxml_wmlc13_global, /* Not 100% true */
+ wbxml_wmlc13_tags, /* Not 100% true */
+ wbxml_wmlc13_attrStart, /* Not 100% true */
+ wbxml_wmlc13_attrValue /* Not 100% true */
+ },
+
+ { 0, FALSE, NULL, NULL, NULL, NULL }
};
-/* Update the entry below when the table above is appended */
-#define WBXML_MAP_MAX_ID 0x0E
+/* WBXML content token mapping depends on the following parameters:
+ * - Content type (guint32)
+ * - Token type (global, tags, attrStart, attrValue)
+ * - Code page for tag and attribute
+ *
+ * This results in the following steps:
+ * 1. Retrieve content type mapping
+ * 2. If exists, retrieve token type mapping
+ * 3. If exists, retrieve required code page
+ * 4. If exists, retrieve token mapping
+ */
+
+/* Return token mapping for a given content mapping entry. */
+static const char *
+map_token (const value_valuestring *token_map, guint8 codepage, guint8 token) {
+ const value_string *vs;
+ const char *s;
+
+ if (token_map) { /* Found map */
+ if ((vs = val_to_valstr (codepage, token_map))) {
+ /* Found codepage map */
+ s = match_strval (token, vs);
+ if (s) /* Found valid token */
+ return s;
+ /* No valid token mapping in specified code page of token map */
+ return "(Requested token not defined for this content type)";
+ }
+ /* There is no token map entry for the requested code page */
+ return "(Requested token code page not defined for this content type)";
+ }
+ /* The token map does not exist */
+ return "(Requested token map not defined for this content type)";
+}
+
+/* Returns a pointer to the WBXML token map for the given WBXML public
+ * identifier value (see WINA for a table with defined identifiers). */
+static const wbxml_token_map *wbxml_content_map (guint32 publicid) {
+ gint i = 0;
+
+ while (map[i].defined) {
+ if (map[i].publicid == publicid)
+ return &(map[i]);
+ i++;
+ }
+ return NULL;
+}
-/************************** Function prototypes **************************/
+/************************** Function prototypes **************************/
static void
dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-
void
proto_register_wbxml(void);
-
-/* Parse and display the WBXML string table
- */
+/* 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);
-
/* Return a pointer to the string in the string table.
- * Can also be hacked for inline string retrieval.
- */
+ * Can also be hacked for inline string retrieval. */
static const char*
strtbl_lookup (tvbuff_t *tvb, guint32 str_tbl, guint32 offset, guint32 *len);
-
-/* Parse data while in STAG state
- */
+/* Parse data while in STAG state */
static void
parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
guint32 str_tbl, guint8 *level,
- guint8 *codepage_stag, guint8 *codepage_attr, guint32 *parsed_length);
-
+ guint32 *parsed_length);
/* Parse data while in STAG state;
- * interpret tokens as defined by content type
- */
+ * interpret tokens as defined by content type */
static void
parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
guint32 str_tbl, guint8 *level,
- guint8 *codepage_stag, guint8 *codepage_attr, guint32 *parsed_length,
- const wbxml_mapping_table *map);
-
+ guint32 *parsed_length,
+ const wbxml_token_map *map);
-/* Parse data while in ATTR state
- */
+/* Parse data while in ATTR state */
static void
parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
guint32 offset, guint32 str_tbl, guint8 level,
- guint8 *codepage_attr, guint32 *parsed_length);
-
+ guint32 *parsed_length);
/* Parse data while in ATTR state;
- * interpret tokens as defined by content type
- */
+ * interpret tokens as defined by content type */
static void
parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
guint32 offset, guint32 str_tbl, guint8 level,
- guint8 *codepage_attr, guint32 *parsed_length,
- const wbxml_mapping_table *map);
-
-
+ guint32 *parsed_length,
+ const wbxml_token_map *map);
/****************** WBXML protocol dissection functions ******************/
-
-
/* Code to actually dissect the packets */
static void
dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-
-/* Set up structures needed to add the protocol subtree and manage it */
+ /* 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 */
@@ -1356,8 +1876,7 @@ dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint32 str_tbl;
guint32 str_tbl_len;
guint8 level = 0; /* WBXML recursion level */
- guint8 codepage_stag = 0; /* Initial codepage in state = STAG */
- guint8 codepage_attr = 0; /* Initial codepage in state = ATTR */
+ const wbxml_token_map *content_map = NULL;
/* WBXML format
*
@@ -1430,7 +1949,6 @@ dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
str_tbl_len = tvb_get_guintvar (tvb, offset, &len);
str_tbl = offset + len; /* Start of 1st string in string table */
-
/* Now we can add public ID, charset (if available),
* and string table */
if ( ! publicid ) { /* Read Public ID from string table */
@@ -1468,56 +1986,49 @@ dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* 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).
- */
+ * RESERVED_2 (WBXML 1.0) or OPAQUE (WBXML 1.x with x > 0). */
if (wbxml_tree) { /* Show only if visible */
if (publicid) {
-#ifdef DEBUG
- printf ("WBXML - Content Type : \"%s\"\n",
- match_strval (publicid, vals_wbxml_public_ids));
-#endif
- /* Look in wbxml_map[] table for defined mapping */
- if (publicid < WBXML_MAP_MAX_ID) {
- if (wbxml_map[publicid].defined) {
+ /* Retrieve the content token mapping if available */
+ content_map = wbxml_content_map (publicid);
+ if (content_map) {
+ /* Is there a defined token mapping for publicid? */
+ if (content_map->defined) {
proto_tree_add_text (wbxml_content_tree, tvb,
offset, -1,
- "Level | State "
+ "Level | State | Codepage "
"| WBXML Token Description "
"| Rendering");
parse_wbxml_tag_defined (wbxml_content_tree,
tvb, offset, str_tbl, &level,
- &codepage_stag, &codepage_attr, &len,
- wbxml_map + publicid);
+ &len, content_map);
return;
}
- proto_tree_add_text (wbxml_content_tree, tvb,
- offset, -1,
- "Rendering of this content type"
- " not (yet) supported");
}
+ proto_tree_add_text (wbxml_content_tree, tvb,
+ offset, -1,
+ "[Rendering of this content type"
+ " not (yet) supported]");
}
/* Default: WBXML only, no interpretation of the content */
proto_tree_add_text (wbxml_content_tree, tvb, offset, -1,
- "Level | State | WBXML Token Description "
+ "Level | State | Codepage "
+ "| WBXML Token Description "
"| Rendering");
parse_wbxml_tag (wbxml_content_tree, tvb, offset,
- str_tbl, &level,
- &codepage_stag, &codepage_attr, &len);
+ str_tbl, &level, &len);
return;
} else {
proto_tree_add_text (wbxml_content_tree, tvb, offset, -1,
- "WBXML 1.0 decoding not yet supported");
+ "WBXML 1.0 decoding not (yet) supported");
}
return;
}
}
-
-
/* Return a pointer to the string in the string table.
- * Can also be hacked for inline string retrieval.
- */
+ * Can also be hacked for inline string retrieval. */
static const char*
strtbl_lookup (tvbuff_t *tvb, guint32 str_tbl, guint32 offset, guint32 *len)
{
@@ -1531,8 +2042,6 @@ strtbl_lookup (tvbuff_t *tvb, guint32 str_tbl, guint32 offset, guint32 *len)
}
-
-
/* Parse and display the WBXML string table (in a 3-column table format).
* This function displays:
* - the offset in the string table,
@@ -1561,8 +2070,6 @@ show_wbxml_string_table (proto_tree *tree, tvbuff_t *tvb, guint32 str_tbl,
}
-
-
/* Indentation code is based on a static const array of space characters.
* At least one single space is returned */
static const char indent_buffer[514] = " "
@@ -1581,8 +2088,6 @@ static const char * Indent (guint8 level) {
}
-
-
/********************
* WBXML tag tokens *
********************
@@ -1607,19 +2112,19 @@ static const char * Indent (guint8 level) {
* CONTENT
* </tag>
*
- * NOTE: an XML PI is parsed as an attribute list (same syntax).
+ * NOTES
+ * - An XML PI is parsed as an attribute list (same syntax).
+ * - A code page switch only applies to the single token that follows.
*/
-
-
/* 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().
*
- * The wbxml_mapping_table entry *map contains the actual token mapping.
+ * The wbxml_token_map 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
@@ -1627,15 +2132,20 @@ static const char * Indent (guint8 level) {
* This is achieved by means of the parsing_tag_content and tag_save*
* variables.
*
- * NOTE: Code page switches not yet processed in the code!
- *
* 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 void
parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
guint32 str_tbl, guint8 *level,
- guint8 *codepage_stag, guint8 *codepage_attr, guint32 *parsed_length,
- const wbxml_mapping_table *map)
+ guint32 *parsed_length,
+ const wbxml_token_map *map)
{
guint32 tvb_len = tvb_reported_length (tvb);
guint32 off = offset;
@@ -1649,6 +2159,7 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
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 codepage_stag = 0; /* Initial codepage in state = STAG */
guint8 parsing_tag_content = FALSE; /* Are we parsing content from a
tag with content: <x>Content</x>
@@ -1670,36 +2181,41 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
if ((peek & 0x3F) < 4) switch (peek) { /* Global tokens in state = STAG
but not the LITERAL tokens */
case 0x00: /* SWITCH_PAGE */
- peek = tvb_get_guint8 (tvb, off+1);
+ codepage_stag = tvb_get_guint8 (tvb, off+1);
proto_tree_add_text (tree, tvb, off, 2,
- " Tag | SWITCH_PAGE (Tag code page) "
- "| Code page switch (was: %d, is: %d)",
- *codepage_stag, peek);
- *codepage_stag = peek;
+ " | Tag | T 0->%3d "
+ "| SWITCH_PAGE (Tag code page) "
+ "|",
+ codepage_stag);
off += 2;
break;
case 0x01: /* END: only possible for Tag with Content */
- if (tag_save_known) {
+ if (tag_save_known) { /* Known TAG */
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | END (Known Tag 0x%02X) "
+ " %3d | Tag | "
+ "| END (Known Tag 0x%02X) "
"| %s</%s>",
*level, tag_save_known, Indent (*level),
- match_strval (tag_save_known, map->tags));
+ tag_save_literal); /* We already looked it up! */
} else { /* Literal TAG */
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | END (Literal Tag) "
+ " %3d | Tag | "
+ "| END (Literal Tag) "
"| %s</%s>",
- *level, Indent (*level), tag_save_literal);
+ *level, Indent (*level),
+ tag_save_literal);
}
(*level)--;
off++;
*parsed_length = off - offset;
+ /* Reset code page: not needed as return from recursion */
return;
break;
case 0x02: /* ENTITY */
ent = tvb_get_guintvar (tvb, off+1, &len);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | ENTITY "
+ " %3d | Tag | "
+ "| ENTITY "
"| %s'&#%u;'",
*level, Indent (*level), ent);
off += 1+len;
@@ -1708,7 +2224,8 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* Hack the string table lookup function */
str = strtbl_lookup (tvb, off+1, 0, &len);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | STR_I (Inline string) "
+ " %3d | Tag | "
+ "| STR_I (Inline string) "
"| %s\'%s\'",
*level, Indent(*level), str);
off += 1+len;
@@ -1719,23 +2236,37 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* Extension tokens */
/* Hack the string table lookup function */
str = strtbl_lookup (tvb, off+1, 0, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | EXT_I_%1x (Extension Token) "
- "| %s(%s: \'%s\')",
- *level, peek & 0x0f, Indent (*level),
- match_strval (peek, map->global), str);
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Tag | T %3d->0 "
+ "| EXT_I_%1x (Extension Token) "
+ "| %s(%s: \'%s\')",
+ *level, codepage_stag, peek & 0x0f, Indent (*level),
+ map_token (map->global, codepage_stag, peek), str);
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Tag | "
+ "| EXT_I_%1x (Extension Token) "
+ "| %s(%s: \'%s\')",
+ *level, peek & 0x0f, Indent (*level),
+ map_token (map->global, codepage_stag, peek), str);
+ }
off += 1+len;
break;
case 0x43: /* PI */
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | PI (XML Processing Instruction) "
+ " %3d | Tag | "
+ "| PI (XML Processing Instruction) "
"| %s<?xml",
*level, Indent (*level));
- parse_wbxml_attribute_list (tree, tvb, off, str_tbl,
- *level, codepage_attr, &len);
+ parse_wbxml_attribute_list_defined (tree, tvb, off, str_tbl,
+ *level, &len, map);
off += len;
proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | END (PI) "
+ " %3d | Tag | "
+ "| END (PI) "
"| %s?>",
*level, Indent (*level));
break;
@@ -1745,18 +2276,31 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* Extension tokens */
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | EXT_T_%1x (Extension Token) "
- "| %s(%s: \'%s\')",
- *level, peek & 0x0f, Indent (*level),
- match_strval (peek, map->global), str);
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Tag | T %3d->0 "
+ "| EXT_T_%1x (Extension Token) "
+ "| %s(%s: \'%s\')",
+ *level, codepage_stag, peek & 0x0f, Indent (*level),
+ map_token (map->global, codepage_stag, peek), str);
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Tag | "
+ "| EXT_T_%1x (Extension Token) "
+ "| %s(%s: \'%s\')",
+ *level, peek & 0x0f, Indent (*level),
+ map_token (map->global, codepage_stag, peek), str);
+ }
off += 1+len;
break;
case 0x83: /* STR_T */
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | STR_T (Tableref string) "
+ " %3d | Tag | "
+ "| STR_T (Tableref string) "
"| %s\'%s\'",
*level, Indent (*level), str);
off += 1+len;
@@ -1765,24 +2309,38 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
case 0xC1: /* EXT_1 */
case 0xC2: /* EXT_2 */
/* Extension tokens */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | EXT_%1x (Extension Token) "
- "| %s(%s)",
- *level, peek & 0x0f, Indent (*level),
- match_strval (peek, map->global));
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| EXT_%1x (Extension Token) "
+ "| %s(%s)",
+ *level, codepage_stag, peek & 0x0f, Indent (*level),
+ map_token (map->global, codepage_stag, peek));
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| EXT_%1x (Extension Token) "
+ "| %s(%s)",
+ *level, peek & 0x0f, Indent (*level),
+ map_token (map->global, codepage_stag, peek));
+ }
off++;
break;
case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
index = tvb_get_guintvar (tvb, off+1, &len);
proto_tree_add_text (tree, tvb, off, 1 + len + index,
- " %3d | Tag | OPAQUE (Opaque data) "
+ " %3d | Tag | "
+ "| OPAQUE (Opaque data) "
"| %s(%d bytes of opaque data)",
*level, Indent (*level), index);
off += 1+len+index;
} else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
proto_tree_add_text (tree, tvb, off, 1,
- " Tag | RESERVED_2 (Invalid Token!) "
+ " Tag | "
+ "| RESERVED_2 (Invalid Token!) "
"| WBXML 1.0 parsing stops here.");
/* Stop processing as it is impossible to parse now */
off = tvb_len;
@@ -1793,8 +2351,10 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* 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.
+ /* 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:
*
@@ -1810,14 +2370,14 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
index = tvb_get_guintvar (tvb, off+1, &tag_len);
tag_new_literal = strtbl_lookup (tvb, str_tbl, index, NULL);
tag_new_known = 0; /* invalidate known tag_new */
- } else {
+ } else { /* Known tag */
tag_new_known = peek & 0x3F;
- tag_new_literal = NULL; /* invalidate LITERAL tag_new */
+ tag_new_literal = map_token (map->tags, codepage_stag,
+ tag_new_known);
+ /* Stored looked up tag name string */
}
- /*
- * Parsing of TAG starts HERE
- */
+ /* Parsing of TAG starts HERE */
if (peek & 0x40) { /* Content present */
/* Content follows
* [!] An explicit END token is expected in these cases!
@@ -1832,56 +2392,84 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
* recursion will take care of it */
(*level)++;
parse_wbxml_tag_defined (tree, tvb, off, str_tbl, level,
- codepage_stag, codepage_attr, &len, map);
+ &len, 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) {
+ if ((peek & 0x3F) == 4) { /* Literal tag */
tag_save_literal = tag_new_literal;
tag_save_known = 0;
- } else {
+ } else { /* Known tag */
tag_save_known = tag_new_known;
- tag_save_literal = NULL;
+ 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 "
- "| Known Tag 0x%02X (AC) "
- "| %s<%s",
- *level, tag_new_known, Indent (*level),
- match_strval (tag_new_known, map->tags));
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| Known Tag 0x%02X (AC) "
+ "| %s<%s",
+ *level, codepage_stag, tag_new_known,
+ Indent (*level), tag_new_literal);
+ /* Tag string already looked up earlier! */
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| Known Tag 0x%02X (AC) "
+ "| %s<%s",
+ *level, 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 "
+ " %3d | Tag | "
"| LITERAL_AC (Literal tag) (AC) "
"| %s<%s",
*level, Indent (*level), tag_new_literal);
off += 1 + tag_len;
}
parse_wbxml_attribute_list_defined (tree, tvb,
- off, str_tbl,
- *level, codepage_attr, &len, map);
+ off, str_tbl, *level, &len, map);
off += len;
proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag "
+ " %3d | Tag | "
"| END (attribute list) "
"| %s>",
*level, Indent (*level));
} else { /* Content, no Attribute list */
if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag "
- "| Known Tag 0x%02X (.C) "
- "| %s<%s>",
- *level, tag_new_known, Indent (*level),
- match_strval (tag_new_known, map->tags));
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| Known Tag 0x%02X (.C) "
+ "| %s<%s>",
+ *level, codepage_stag, tag_new_known,
+ Indent (*level),
+ tag_new_literal);
+ /* Tag string already looked up earlier! */
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| Known Tag 0x%02X (.C) "
+ "| %s<%s>",
+ *level, 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 "
+ " %3d | Tag | "
"| LITERAL_C (Literal Tag) (.C) "
"| %s<%s>",
*level, Indent (*level), tag_new_literal);
@@ -1907,51 +2495,75 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
(*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 "
- "| Known Tag 0x%02X (A.) "
- "| %s<%s",
- *level, tag_new_known, Indent (*level),
- match_strval (tag_new_known, map->tags));
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| Known Tag 0x%02X (A.) "
+ "| %s<%s",
+ *level, codepage_stag, tag_new_known,
+ Indent (*level), tag_new_literal);
+ /* Tag string already looked up earlier! */
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| Known Tag 0x%02X (A.) "
+ "| %s<%s",
+ *level, tag_new_known,
+ Indent (*level), tag_new_literal);
+ /* Tag string already looked up earlier! */
+ }
off++;
parse_wbxml_attribute_list_defined (tree, tvb,
- off, str_tbl,
- *level, codepage_attr, &len, map);
+ off, str_tbl, *level, &len, map);
off += len;
proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag "
+ " %3d | Tag | "
"| END (Known Tag) "
"| %s/>",
*level, Indent (*level));
} else { /* LITERAL tag */
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag "
+ " %3d | Tag | "
"| LITERAL_A (Literal Tag) (A.) "
"| %s<%s",
*level, Indent (*level), tag_new_literal);
off += 1 + tag_len;
parse_wbxml_attribute_list_defined (tree, tvb,
- off, str_tbl,
- *level, codepage_attr, &len, map);
+ off, str_tbl, *level, &len, map);
off += len;
proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag "
+ " %3d | Tag | "
"| END (Literal Tag) "
"| %s/>",
*level, Indent (*level));
}
} else { /* No Content, No Attribute list */
if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag "
- "| Known Tag 0x%02x (..) "
- "| %s<%s />",
- *level, tag_new_known, Indent (*level),
- match_strval (tag_new_known, map->tags));
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| Known Tag 0x%02x (..) "
+ "| %s<%s />",
+ *level, codepage_stag, tag_new_known,
+ Indent (*level), tag_new_literal);
+ /* Tag string already looked up earlier! */
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| Known Tag 0x%02x (..) "
+ "| %s<%s />",
+ *level, 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 "
+ " %3d | Tag | "
"| LITERAL (Literal Tag) (..) "
"| %s<%s />",
*level, Indent (*level), tag_new_literal);
@@ -1959,25 +2571,22 @@ parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
}
}
(*level)--;
+ /* TODO: Do I have to reset code page here? */
}
} /* if (tag & 0x3F) >= 5 */
} /* while */
}
-
-
/* This function performs the WBXML decoding as in parse_wbxml_tag_defined()
* but this time no WBXML mapping is performed.
*
* Attribute parsing is done in parse_wbxml_attribute_list().
- *
- * NOTE: Code page switches not yet processed in the code!
*/
static void
parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
guint32 str_tbl, guint8 *level,
- guint8 *codepage_stag, guint8 *codepage_attr, guint32 *parsed_length)
+ guint32 *parsed_length)
{
guint32 tvb_len = tvb_reported_length (tvb);
guint32 off = offset;
@@ -1991,6 +2600,9 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
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 */
+ char tag_save_buf[10]; /* Will contain "tag_0x%02X" */
+ char tag_new_buf[10]; /* Will contain "tag_0x%02X" */
+ guint8 codepage_stag = 0; /* Initial codepage in state = STAG */
guint8 parsing_tag_content = FALSE; /* Are we parsing content from a
tag with content: <x>Content</x>
@@ -2012,36 +2624,41 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
if ((peek & 0x3F) < 4) switch (peek) { /* Global tokens in state = STAG
but not the LITERAL tokens */
case 0x00: /* SWITCH_PAGE */
- peek = tvb_get_guint8 (tvb, off+1);
+ codepage_stag = tvb_get_guint8 (tvb, off+1);
proto_tree_add_text (tree, tvb, off, 2,
- " Tag | SWITCH_PAGE (Tag code page) "
- "| Code page switch (was: %d, is: %d)",
- *codepage_stag, peek);
- *codepage_stag = peek;
+ " | Tag | T 0->%3d "
+ "| SWITCH_PAGE (Tag code page) "
+ "|",
+ codepage_stag);
off += 2;
break;
case 0x01: /* END: only possible for Tag with Content */
- if (tag_save_known) {
+ if (tag_save_known) { /* Known TAG */
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | END (Known Tag 0x%02X) "
- "| %s</Tag_0x%02X>",
+ " %3d | Tag | "
+ "| END (Known Tag 0x%02X) "
+ "| %s</%s>",
*level, tag_save_known, Indent (*level),
- tag_save_known);
+ tag_save_literal); /* We already looked it up! */
} else { /* Literal TAG */
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | END (Literal Tag) "
+ " %3d | Tag | "
+ "| END (Literal Tag) "
"| %s</%s>",
- *level, Indent (*level), tag_save_literal);
+ *level, Indent (*level),
+ tag_save_literal);
}
(*level)--;
off++;
*parsed_length = off - offset;
+ /* Reset code page: not needed as return from recursion */
return;
break;
case 0x02: /* ENTITY */
ent = tvb_get_guintvar (tvb, off+1, &len);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | ENTITY "
+ " %3d | Tag | "
+ "| ENTITY "
"| %s'&#%u;'",
*level, Indent (*level), ent);
off += 1+len;
@@ -2050,7 +2667,8 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* Hack the string table lookup function */
str = strtbl_lookup (tvb, off+1, 0, &len);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | STR_I (Inline string) "
+ " %3d | Tag | "
+ "| STR_I (Inline string) "
"| %s\'%s\'",
*level, Indent(*level), str);
off += 1+len;
@@ -2061,22 +2679,37 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* Extension tokens */
/* Hack the string table lookup function */
str = strtbl_lookup (tvb, off+1, 0, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | EXT_I_%1x (Extension Token) "
- "| %s(Inline string extension: \'%s\')",
- *level, peek & 0x0f, Indent (*level), str);
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Tag | T %3d->0 "
+ "| EXT_I_%1x (Extension Token) "
+ "| %s(Inline string extension: \'%s\')",
+ *level, codepage_stag, peek & 0x0f, Indent (*level),
+ str);
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Tag | "
+ "| EXT_I_%1x (Extension Token) "
+ "| %s(Inline string extension: \'%s\')",
+ *level, peek & 0x0f, Indent (*level),
+ str);
+ }
off += 1+len;
break;
case 0x43: /* PI */
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | PI (XML Processing Instruction) "
+ " %3d | Tag | "
+ "| PI (XML Processing Instruction) "
"| %s<?xml",
*level, Indent (*level));
parse_wbxml_attribute_list (tree, tvb, off, str_tbl,
- *level, codepage_attr, &len);
+ *level, &len);
off += len;
proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag | END (PI) "
+ " %3d | Tag | "
+ "| END (PI) "
"| %s?>",
*level, Indent (*level));
break;
@@ -2086,17 +2719,31 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* Extension tokens */
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | EXT_T_%1x (Extension Token) "
- "| %s(Tableref string extension: \'%s\')",
- *level, peek & 0x0f, Indent (*level), str);
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Tag | T %3d->0 "
+ "| EXT_T_%1x (Extension Token) "
+ "| %s(Tableref string extension: \'%s\')",
+ *level, codepage_stag, peek & 0x0f, Indent (*level),
+ str);
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Tag | "
+ "| EXT_T_%1x (Extension Token) "
+ "| %s(Tableref string extension: \'%s\')",
+ *level, peek & 0x0f, Indent (*level),
+ str);
+ }
off += 1+len;
break;
case 0x83: /* STR_T */
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Tag | STR_T (Tableref string) "
+ " %3d | Tag | "
+ "| STR_T (Tableref string) "
"| %s\'%s\'",
*level, Indent (*level), str);
off += 1+len;
@@ -2105,23 +2752,37 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
case 0xC1: /* EXT_1 */
case 0xC2: /* EXT_2 */
/* Extension tokens */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag | EXT_%1x (Extension Token) "
- "| %s(Single-byte extension)",
- *level, peek & 0x0f, Indent (*level));
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| EXT_%1x (Extension Token) "
+ "| %s(Single-byte extension)",
+ *level, codepage_stag, peek & 0x0f,
+ Indent (*level));
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| EXT_%1x (Extension Token) "
+ "| %s(Single-byte extension)",
+ *level, 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) */
index = tvb_get_guintvar (tvb, off+1, &len);
proto_tree_add_text (tree, tvb, off, 1 + len + index,
- " %3d | Tag | OPAQUE (Opaque data) "
+ " %3d | Tag | "
+ "| OPAQUE (Opaque data) "
"| %s(%d bytes of opaque data)",
*level, Indent (*level), index);
off += 1+len+index;
} else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
proto_tree_add_text (tree, tvb, off, 1,
- " Tag | RESERVED_2 (Invalid Token!) "
+ " Tag | "
+ "| RESERVED_2 (Invalid Token!) "
"| WBXML 1.0 parsing stops here.");
/* Stop processing as it is impossible to parse now */
off = tvb_len;
@@ -2132,8 +2793,10 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
/* 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.
+ /* 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:
*
@@ -2149,14 +2812,15 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
index = tvb_get_guintvar (tvb, off+1, &tag_len);
tag_new_literal = strtbl_lookup (tvb, str_tbl, index, NULL);
tag_new_known = 0; /* invalidate known tag_new */
- } else {
+ } else { /* Known tag */
tag_new_known = peek & 0x3F;
- tag_new_literal = NULL; /* invalidate LITERAL tag_new */
+ sprintf (tag_new_buf, "Tag_0x%02X",
+ tag_new_known);
+ tag_new_literal = tag_new_buf;
+ /* Stored looked up tag name string */
}
- /*
- * Parsing of TAG starts HERE
- */
+ /* Parsing of TAG starts HERE */
if (peek & 0x40) { /* Content present */
/* Content follows
* [!] An explicit END token is expected in these cases!
@@ -2171,55 +2835,86 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
* recursion will take care of it */
(*level)++;
parse_wbxml_tag (tree, tvb, off, str_tbl, level,
- codepage_stag, codepage_attr, &len);
+ &len);
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) {
+ if ((peek & 0x3F) == 4) { /* Literal tag */
tag_save_literal = tag_new_literal;
tag_save_known = 0;
- } else {
+ } else { /* Known tag */
tag_save_known = tag_new_known;
- tag_save_literal = NULL;
+ sprintf (tag_save_buf, "Tag_0x%02X",
+ tag_new_known);
+ tag_save_literal = tag_save_buf;
+ /* 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 "
- "| Known Tag 0x%02X (AC) "
- "| %s<Tag_0x%02X",
- *level, tag_new_known, Indent (*level),
- tag_new_known);
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| Known Tag 0x%02X (AC) "
+ "| %s<%s",
+ *level, codepage_stag, tag_new_known,
+ Indent (*level), tag_new_literal);
+ /* Tag string already looked up earlier! */
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| Known Tag 0x%02X (AC) "
+ "| %s<%s",
+ *level, 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 "
+ " %3d | Tag | "
"| LITERAL_AC (Literal tag) (AC) "
"| %s<%s",
*level, Indent (*level), tag_new_literal);
off += 1 + tag_len;
}
- parse_wbxml_attribute_list (tree, tvb, off, str_tbl,
- *level, codepage_attr, &len);
+ parse_wbxml_attribute_list (tree, tvb,
+ off, str_tbl, *level, &len);
off += len;
proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag "
+ " %3d | Tag | "
"| END (attribute list) "
"| %s>",
*level, Indent (*level));
} else { /* Content, no Attribute list */
if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag "
- "| Known Tag 0x%02X (.C) "
- "| %s<Tag_0x%02X>",
- *level, tag_new_known, Indent (*level),
- tag_new_known);
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| Known Tag 0x%02X (.C) "
+ "| %s<%s>",
+ *level, codepage_stag, tag_new_known,
+ Indent (*level),
+ tag_new_literal);
+ /* Tag string already looked up earlier! */
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| Known Tag 0x%02X (.C) "
+ "| %s<%s>",
+ *level, 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 "
+ " %3d | Tag | "
"| LITERAL_C (Literal Tag) (.C) "
"| %s<%s>",
*level, Indent (*level), tag_new_literal);
@@ -2245,49 +2940,75 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
(*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 "
- "| Known Tag 0x%02X (A.) "
- "| %s<Tag 0x%02X",
- *level, tag_new_known, Indent (*level),
- tag_new_known);
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| Known Tag 0x%02X (A.) "
+ "| %s<%s",
+ *level, codepage_stag, tag_new_known,
+ Indent (*level), tag_new_literal);
+ /* Tag string already looked up earlier! */
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| Known Tag 0x%02X (A.) "
+ "| %s<%s",
+ *level, tag_new_known,
+ Indent (*level), tag_new_literal);
+ /* Tag string already looked up earlier! */
+ }
off++;
- parse_wbxml_attribute_list (tree, tvb, off, str_tbl,
- *level, codepage_attr, &len);
+ parse_wbxml_attribute_list (tree, tvb,
+ off, str_tbl, *level, &len);
off += len;
proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag "
+ " %3d | Tag | "
"| END (Known Tag) "
"| %s/>",
*level, Indent (*level));
} else { /* LITERAL tag */
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag "
+ " %3d | Tag | "
"| LITERAL_A (Literal Tag) (A.) "
"| %s<%s",
*level, Indent (*level), tag_new_literal);
off += 1 + tag_len;
- parse_wbxml_attribute_list (tree, tvb, off, str_tbl,
- *level, codepage_attr, &len);
+ parse_wbxml_attribute_list (tree, tvb,
+ off, str_tbl, *level, &len);
off += len;
proto_tree_add_text (tree, tvb, off-1, 1,
- " %3d | Tag "
+ " %3d | Tag | "
"| END (Literal Tag) "
"| %s/>",
*level, Indent (*level));
}
} else { /* No Content, No Attribute list */
if (tag_new_known) { /* Known tag */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Tag "
- "| Known Tag 0x%02x (..) "
- "| %s<Tag_0x%02X />",
- *level, tag_new_known, Indent (*level),
- tag_new_known);
+ if (codepage_stag) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | T %3d->0 "
+ "| Known Tag 0x%02x (..) "
+ "| %s<%s />",
+ *level, codepage_stag, tag_new_known,
+ Indent (*level), tag_new_literal);
+ /* Tag string already looked up earlier! */
+ /* Reset code page */
+ codepage_stag = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Tag | "
+ "| Known Tag 0x%02x (..) "
+ "| %s<%s />",
+ *level, 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 "
+ " %3d | Tag | "
"| LITERAL (Literal Tag) (..) "
"| %s<%s />",
*level, Indent (*level), tag_new_literal);
@@ -2295,45 +3016,40 @@ parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
}
}
(*level)--;
+ /* TODO: Do I have to reset code page here? */
}
} /* if (tag & 0x3F) >= 5 */
} /* while */
}
-
-
/**************************
* 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)
+ * 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.
*
* This function performs attribute list parsing.
*
- * The wbxml_mapping_table entry *map contains the actual token mapping.
+ * The wbxml_token_map entry *map contains the actual token mapping.
*
* NOTE: See above for known token mappings.
- *
- * NOTE: Code page switches not yet processed in the code!
*/
static void
parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
guint32 offset, guint32 str_tbl, guint8 level,
- guint8 *codepage_attr, guint32 *parsed_length,
- const wbxml_mapping_table *map)
+ guint32 *parsed_length,
+ const wbxml_token_map *map)
{
guint32 tvb_len = tvb_reported_length (tvb);
guint32 off = offset;
@@ -2342,6 +3058,7 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
guint32 index;
const char* str;
guint8 peek;
+ guint8 codepage_attr = 0; /* Initial codepage in state = ATTR */
#ifdef DEBUG
printf ("WBXML - parse_wbxml_attr_defined (level = %d, offset = %d)\n",
@@ -2358,18 +3075,17 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
if ((peek & 0x3F) < 5) switch (peek) { /* Global tokens
in state = ATTR */
case 0x00: /* SWITCH_PAGE */
- peek = tvb_get_guint8 (tvb, off+1);
+ codepage_attr = tvb_get_guint8 (tvb, off+1);
proto_tree_add_text (tree, tvb, off, 2,
- " Attr | SWITCH_PAGE (Attr code page) "
- "| Code page switch (was: %d, is: %d)",
- *codepage_attr, peek);
- *codepage_attr = peek;
+ " | Attr | A 0->%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 trated separately.
+ * and as a consequence both must be treated separately.
* This is done in the TAG state parser.
*/
off++;
@@ -2378,7 +3094,8 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
case 0x02: /* ENTITY */
ent = tvb_get_guintvar (tvb, off+1, &len);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | ENTITY "
+ " %3d | Attr | "
+ "| ENTITY "
"| %s'&#%u;'",
level, Indent (level), ent);
off += 1+len;
@@ -2387,7 +3104,8 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
/* Hack the string table lookup function */
str = strtbl_lookup (tvb, off+1, 0, &len);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | STR_I (Inline string) "
+ " %3d | Attr | "
+ "| STR_I (Inline string) "
"| %s\'%s\'",
level, Indent (level), str);
off += 1+len;
@@ -2396,7 +3114,8 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | LITERAL (Literal Attribute) "
+ " %3d | Attr | "
+ "| LITERAL (Literal Attribute) "
"| %s<%s />",
level, Indent (level), str);
off += 1+len;
@@ -2407,11 +3126,23 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
/* Extension tokens */
/* Hack the string table lookup function */
str = strtbl_lookup (tvb, off+1, 0, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | EXT_I_%1x (Extension Token) "
- "| %s(%s: \'%s\')",
- level, peek & 0x0f, Indent (level),
- match_strval (peek, map->global), str);
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Attr | A %3d->0 "
+ "| EXT_I_%1x (Extension Token) "
+ "| %s(%s: \'%s\')",
+ level, codepage_attr, peek & 0x0f, Indent (level),
+ map_token (map->global, codepage_attr, peek), str);
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Attr | "
+ "| EXT_I_%1x (Extension Token) "
+ "| %s(%s: \'%s\')",
+ level, peek & 0x0f, Indent (level),
+ map_token (map->global, codepage_attr, peek), str);
+ }
off += 1+len;
break;
/* 0x43 impossible in ATTR state */
@@ -2422,18 +3153,31 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
/* Extension tokens */
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | EXT_T_%1x (Extension Token) "
- "| %s(%s: \'%s\')",
- level, peek & 0x0f, Indent (level),
- match_strval (peek, map->global), str);
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Attr | A %3d->0 "
+ "| EXT_T_%1x (Extension Token) "
+ "| %s(%s: \'%s\')",
+ level, codepage_attr, peek & 0x0f, Indent (level),
+ map_token (map->global, codepage_attr, peek), str);
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Attr | "
+ "| EXT_T_%1x (Extension Token) "
+ "| %s(%s: \'%s\')",
+ level, peek & 0x0f, Indent (level),
+ map_token (map->global, codepage_attr, peek), str);
+ }
off += 1+len;
break;
- case 0x83: /* EXT_T */
+ case 0x83: /* STR_T */
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | STR_T (Tableref string) "
+ " %3d | Attr | "
+ "| STR_T (Tableref string) "
"| %s\'%s\'",
level, Indent (level), str);
off += 1+len;
@@ -2443,24 +3187,38 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
case 0xC1: /* EXT_1 */
case 0xC2: /* EXT_2 */
/* Extension tokens */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | EXT_%1x (Extension Token) "
- "| %s(%s)",
- level, peek & 0x0f, Indent (level),
- match_strval (peek, map->global));
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | A %3d->0 "
+ "| EXT_%1x (Extension Token) "
+ "| %s(%s)",
+ level, codepage_attr, peek & 0x0f, Indent (level),
+ map_token (map->global, codepage_attr, peek));
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | "
+ "| EXT_%1x (Extension Token) "
+ "| %s(%s)",
+ level, peek & 0x0f, Indent (level),
+ map_token (map->global, codepage_attr, peek));
+ }
off++;
break;
case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
index = tvb_get_guintvar (tvb, off+1, &len);
proto_tree_add_text (tree, tvb, off, 1 + len + index,
- " %3d | Attr | OPAQUE (Opaque data) "
+ " %3d | Attr | "
+ "| OPAQUE (Opaque data) "
"| %s(%d bytes of opaque data)",
level, Indent (level), index);
off += 1+len+index;
} else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
proto_tree_add_text (tree, tvb, off, 1,
- " Attr | RESERVED_2 (Invalid Token!) "
+ " Attr | "
+ "| RESERVED_2 (Invalid Token!) "
"| WBXML 1.0 parsing stops here.");
/* Stop processing as it is impossible to parse now */
off = tvb_len;
@@ -2471,7 +3229,8 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
/* 0xC4 impossible in ATTR state */
default:
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | %-10s (Invalid Token!) "
+ " %3d | Attr | "
+ "| %-10s (Invalid Token!) "
"| WBXML parsing stops here.",
level, match_strval (peek, vals_wbxml1x_global_tokens));
/* Move to end of buffer */
@@ -2479,18 +3238,42 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
break;
} else { /* Known atribute token */
if (peek & 0x80) { /* attrValue */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | Known attrValue 0x%02X "
- "| %s%s",
- level, peek & 0x7f, Indent (level),
- match_strval (peek, map->attrValue));
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | A %3d->0 "
+ "| Known attrValue 0x%02X "
+ "| %s%s",
+ level, codepage_attr, peek & 0x7f, Indent (level),
+ map_token (map->attrValue, codepage_attr, peek));
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | "
+ "| Known attrValue 0x%02X "
+ "| %s%s",
+ level, peek & 0x7f, Indent (level),
+ map_token (map->attrValue, codepage_attr, peek));
+ }
off++;
} else { /* attrStart */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | Known attrStart 0x%02X "
- "| %s%s",
- level, peek & 0x7f, Indent (level),
- match_strval (peek, map->attrStart));
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | A %3d->0 "
+ "| Known attrStart 0x%02X "
+ "| %s%s",
+ level, codepage_attr, peek & 0x7f, Indent (level),
+ map_token (map->attrStart, codepage_attr, peek));
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | "
+ "| Known attrStart 0x%02X "
+ "| %s%s",
+ level, peek & 0x7f, Indent (level),
+ map_token (map->attrStart, codepage_attr, peek));
+ }
off++;
}
}
@@ -2498,8 +3281,6 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
}
-
-
/* This function performs the WBXML attribute decoding as in
* parse_wbxml_attribute_list_defined() but this time no WBXML mapping
* is performed.
@@ -2511,7 +3292,7 @@ parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
static void
parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
guint32 offset, guint32 str_tbl, guint8 level,
- guint8 *codepage_attr, guint32 *parsed_length)
+ guint32 *parsed_length)
{
guint32 tvb_len = tvb_reported_length (tvb);
guint32 off = offset;
@@ -2520,9 +3301,10 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
guint32 index;
const char* str;
guint8 peek;
+ guint8 codepage_attr = 0; /* Initial codepage in state = ATTR */
#ifdef DEBUG
- printf ("WBXML - parse_wbxml_attr_defined (level = %d, offset = %d)\n",
+ printf ("WBXML - parse_wbxml_attr (level = %d, offset = %d)\n",
level, offset);
#endif
/* Parse attributes */
@@ -2536,18 +3318,17 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
if ((peek & 0x3F) < 5) switch (peek) { /* Global tokens
in state = ATTR */
case 0x00: /* SWITCH_PAGE */
- peek = tvb_get_guint8 (tvb, off+1);
+ codepage_attr = tvb_get_guint8 (tvb, off+1);
proto_tree_add_text (tree, tvb, off, 2,
- " Attr | SWITCH_PAGE (Attr code page) "
- "| Code page switch (was: %d, is: %d)",
- *codepage_attr, peek);
- *codepage_attr = peek;
+ " | Attr | A 0->%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 trated separately.
+ * and as a consequence both must be treated separately.
* This is done in the TAG state parser.
*/
off++;
@@ -2556,7 +3337,8 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
case 0x02: /* ENTITY */
ent = tvb_get_guintvar (tvb, off+1, &len);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | ENTITY "
+ " %3d | Attr | "
+ "| ENTITY "
"| %s'&#%u;'",
level, Indent (level), ent);
off += 1+len;
@@ -2565,7 +3347,8 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
/* Hack the string table lookup function */
str = strtbl_lookup (tvb, off+1, 0, &len);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | STR_I (Inline string) "
+ " %3d | Attr | "
+ "| STR_I (Inline string) "
"| %s\'%s\'",
level, Indent (level), str);
off += 1+len;
@@ -2574,7 +3357,8 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | LITERAL (Literal Attribute) "
+ " %3d | Attr | "
+ "| LITERAL (Literal Attribute) "
"| %s<%s />",
level, Indent (level), str);
off += 1+len;
@@ -2585,10 +3369,23 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
/* Extension tokens */
/* Hack the string table lookup function */
str = strtbl_lookup (tvb, off+1, 0, &len);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | EXT_I_%1x (Extension Token) "
- "| %s(Inline string extension: \'%s\')",
- level, peek & 0x0f, Indent (level), str);
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Attr | A %3d->0 "
+ "| EXT_I_%1x (Extension Token) "
+ "| %s(Inline string extension: \'%s\')",
+ level, codepage_attr, peek & 0x0f, Indent (level),
+ str);
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Attr | "
+ "| EXT_I_%1x (Extension Token) "
+ "| %s(Inline string extension: \'%s\')",
+ level, peek & 0x0f, Indent (level),
+ str);
+ }
off += 1+len;
break;
/* 0x43 impossible in ATTR state */
@@ -2599,17 +3396,31 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
/* Extension tokens */
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
- proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | EXT_T_%1x (Extension Token) "
- "| %s(Tableref string extension: \'%s\')",
- level, peek & 0x0f, Indent (level), str);
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Attr | A %3d->0 "
+ "| EXT_T_%1x (Extension Token) "
+ "| %s(Tableref string extension: \'%s\')",
+ level, codepage_attr, peek & 0x0f, Indent (level),
+ str);
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1+len,
+ " %3d | Attr | "
+ "| EXT_T_%1x (Extension Token) "
+ "| %s(Tableref string extension: \'%s\')",
+ level, peek & 0x0f, Indent (level),
+ str);
+ }
off += 1+len;
break;
- case 0x83: /* EXT_T */
+ case 0x83: /* STR_T */
index = tvb_get_guintvar (tvb, off+1, &len);
str = strtbl_lookup (tvb, str_tbl, index, NULL);
proto_tree_add_text (tree, tvb, off, 1+len,
- " %3d | Attr | STR_T (Tableref string) "
+ " %3d | Attr | "
+ "| STR_T (Tableref string) "
"| %s\'%s\'",
level, Indent (level), str);
off += 1+len;
@@ -2619,23 +3430,36 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
case 0xC1: /* EXT_1 */
case 0xC2: /* EXT_2 */
/* Extension tokens */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | EXT_%1x (Extension Token) "
- "| %s(Single-byte extension)",
- level, peek & 0x0f, Indent (level));
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | A %3d->0 "
+ "| EXT_%1x (Extension Token) "
+ "| %s(Single-byte extension)",
+ level, codepage_attr, peek & 0x0f, Indent (level));
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | "
+ "| EXT_%1x (Extension Token) "
+ "| %s(Single-byte extension)",
+ level, 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) */
index = tvb_get_guintvar (tvb, off+1, &len);
proto_tree_add_text (tree, tvb, off, 1 + len + index,
- " %3d | Attr | OPAQUE (Opaque data) "
+ " %3d | Attr | "
+ "| OPAQUE (Opaque data) "
"| %s(%d bytes of opaque data)",
level, Indent (level), index);
off += 1+len+index;
} else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
proto_tree_add_text (tree, tvb, off, 1,
- " Attr | RESERVED_2 (Invalid Token!) "
+ " Attr | "
+ "| RESERVED_2 (Invalid Token!) "
"| WBXML 1.0 parsing stops here.");
/* Stop processing as it is impossible to parse now */
off = tvb_len;
@@ -2646,7 +3470,8 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
/* 0xC4 impossible in ATTR state */
default:
proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | %-10s (Invalid Token!) "
+ " %3d | Attr | "
+ "| %-10s (Invalid Token!) "
"| WBXML parsing stops here.",
level, match_strval (peek, vals_wbxml1x_global_tokens));
/* Move to end of buffer */
@@ -2654,16 +3479,42 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
break;
} else { /* Known atribute token */
if (peek & 0x80) { /* attrValue */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | Known attrValue 0x%02X "
- "| %sattrValue_0x%02X",
- level, peek & 0x7f, Indent (level), peek);
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | A %3d->0 "
+ "| Known attrValue 0x%02X "
+ "| %sattrValue_0x%02X",
+ level, codepage_attr, peek & 0x7f, Indent (level),
+ peek);
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | "
+ "| Known attrValue 0x%02X "
+ "| %sattrValue_0x%02X",
+ level, peek & 0x7f, Indent (level),
+ peek);
+ }
off++;
} else { /* attrStart */
- proto_tree_add_text (tree, tvb, off, 1,
- " %3d | Attr | Known attrStart 0x%02X "
- "| %sattrStart_0x%02X",
- level, peek & 0x7f, Indent (level), peek);
+ if (codepage_attr) { /* Not default code page */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | A %3d->0 "
+ "| Known attrStart 0x%02X "
+ "| %sattrStart_0x%02X",
+ level, codepage_attr, peek & 0x7f, Indent (level),
+ peek);
+ /* Reset code page */
+ codepage_attr = 0;
+ } else { /* Code page 0 */
+ proto_tree_add_text (tree, tvb, off, 1,
+ " %3d | Attr | "
+ "| Known attrStart 0x%02X "
+ "| %sattrStart_0x%02X",
+ level, peek & 0x7f, Indent (level),
+ peek);
+ }
off++;
}
}
@@ -2671,19 +3522,15 @@ parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
}
-
-
/****************** Register the protocol with Ethereal ******************/
+
/* This format is required because a script is used to build the C function
- * that calls the protocol registration.
- */
+ * that calls the protocol registration. */
void
proto_register_wbxml(void)
-{
-
-/* Setup list of header fields See Section 1.6.1 for details*/
+{ /* Setup list of header fields. See Section 1.6.1 for details. */
static hf_register_info hf[] = {
{ &hf_wbxml_version,
{ "Version",
@@ -2692,25 +3539,20 @@ proto_register_wbxml(void)
VALS ( vals_wbxml_versions ), 0x00,
"WBXML Version", HFILL }
},
-
{ &hf_wbxml_public_id_known,
{ "Public Identifier (known)",
"wbxml.public_id.known",
FT_UINT32, BASE_HEX,
VALS ( vals_wbxml_public_ids ), 0x00,
- "WBXML Known Public Identifier (integer)",
- HFILL }
+ "WBXML Known Public Identifier (integer)", HFILL }
},
-
{ &hf_wbxml_public_id_literal,
{ "Public Identifier (literal)",
"wbxml.public_id.literal",
FT_STRING, BASE_NONE,
NULL, 0x00,
- "WBXML Literal Public Identifier (text string)",
- HFILL }
+ "WBXML Literal Public Identifier (text string)", HFILL }
},
-
{ &hf_wbxml_charset,
{ "Character Set",
"wbxml.charset",
@@ -2718,30 +3560,28 @@ proto_register_wbxml(void)
VALS ( vals_character_sets ), 0x00,
"WBXML Character Set", HFILL }
},
-
};
-/* Setup protocol subtree array */
+ /* Setup protocol subtree array */
static gint *ett[] = {
&ett_wbxml,
&ett_wbxml_str_tbl,
&ett_wbxml_content,
};
-/* Register the protocol name and description */
+ /* Register the protocol name and description */
proto_wbxml = proto_register_protocol(
"WAP Binary XML",
"WBXML",
"wbxml"
);
-/* Required function calls to register the header fields and subtrees used */
+ /* Required function calls to register the header fields
+ * and subtrees used */
proto_register_field_array(proto_wbxml, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("wbxml", dissect_wbxml, proto_wbxml);
-/* register_init_routine(dissect_wbxml); */
- /* wbxml_handle = find_dissector("wsp-co"); */
};