Added two new arguments to epan_init() and proto_init() to
[obnox/wireshark/wip.git] / packet-wsp.c
index d00a837a824573e7bde820d1b82d2e541bbac431..9dcf16b7fe72a6448b59527098c6be532aec096a 100644 (file)
@@ -1,14 +1,17 @@
-/* packet-wsp.c (c) 2000 Neil Hunter
- * Based on original work by Ben Fowler
+/* packet-wsp.c
  *
  * Routines to dissect WSP component of WAP traffic.
  * 
- * $Id: packet-wsp.c,v 1.5 2000/12/02 08:41:08 guy Exp $
+ * $Id: packet-wsp.c,v 1.19 2001/02/19 21:02:33 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
  * Copyright 1998 Didier Jorand
  *
+ * WAP dissector based on original work by Ben Fowler
+ * Updated by Neil Hunter <neil.hunter@energis-squared.com>
+ * WTLS support by Alexandre P. Ferreira (Splice IP)
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -79,7 +82,9 @@ static int hf_wsp_post_data                                           = HF_EMPTY;
 static int hf_wsp_header_accept                                        = HF_EMPTY;
 static int hf_wsp_header_accept_str                            = HF_EMPTY;
 static int hf_wsp_header_accept_charset                        = HF_EMPTY;
+static int hf_wsp_header_accept_charset_str            = HF_EMPTY;
 static int hf_wsp_header_accept_language               = HF_EMPTY;
+static int hf_wsp_header_accept_language_str   = HF_EMPTY;
 static int hf_wsp_header_accept_ranges                 = HF_EMPTY;
 static int hf_wsp_header_cache_control                 = HF_EMPTY;
 static int hf_wsp_header_content_length                        = HF_EMPTY;
@@ -95,6 +100,9 @@ static int hf_wsp_header_user_agent                          = HF_EMPTY;
 static int hf_wsp_header_application_header            = HF_EMPTY;
 static int hf_wsp_header_application_value             = HF_EMPTY;
 static int hf_wsp_header_x_wap_tod                             = HF_EMPTY;
+static int hf_wsp_header_transfer_encoding             = HF_EMPTY;
+static int hf_wsp_header_transfer_encoding_str = HF_EMPTY;
+static int hf_wsp_header_via                                   = HF_EMPTY;
 
 /* Initialize the subtree pointers */
 static gint ett_wsp                                                    = ETT_EMPTY;
@@ -103,6 +111,9 @@ static gint ett_headers                                                     = ETT_EMPTY;
 static gint ett_capabilities                                   = ETT_EMPTY;
 static gint ett_content_type                                   = ETT_EMPTY;
 
+/* Handle for WMLC dissector */
+static dissector_handle_t wmlc_handle;
+
 static const value_string vals_pdu_type[] = {
        { 0x00, "Reserved" },
        { 0x01, "Connect" },
@@ -133,6 +144,8 @@ static const value_string vals_pdu_type[] = {
        /* 0x70 - 0x7F Extended method (Post PDU) */
        /* 0x80 - 0xFF Reserved */
 
+       { 0x00, NULL }
+
 };
 
 static const value_string vals_status[] = {
@@ -179,6 +192,7 @@ static const value_string vals_status[] = {
        { 0x63, "Service Unavailable" },
        { 0x64, "Gateway Timeout" },
        { 0x65, "HTTP Version Not Supported" },
+       { 0x00, NULL }
 };
 
 static const value_string vals_content_types[] = {
@@ -235,32 +249,113 @@ static const value_string vals_content_types[] = {
        { 0x32, "application/vnd.wap.coc" },
        { 0x33, "application/vnd.wap.multipart.related" },
        { 0x34, "application/vnd.wap.sia" },
-};
-
-static const value_string vals_character_sets[] = {
-       { 0x0003, "us-ascii" },
-       { 0x0004, "iso-8859-1" },
-       { 0x0005, "iso-8859-2" },
-       { 0x0006, "iso-8859-3" },
-       { 0x0007, "iso-8859-4" },
-       { 0x0008, "iso-8859-5" },
-       { 0x0009, "iso-8859-6" },
-       { 0x000A, "iso-8859-7" },
-       { 0x000B, "iso-8859-8" },
-       { 0x000C, "iso-8859-9" },
-       { 0x0011, "shift_JIS" },
-       { 0x006A, "utf-8" },
-       { 0x03E8, "iso-10646-ucs-2" },
-       { 0x07EA, "big5" },
+       { 0x00, NULL }
 };
 
 static const value_string vals_languages[] = {
+       { 0x01, "Afar (aa)" },
+       { 0x02, "Abkhazian (ab)" },
+       { 0x03, "Afrikaans (af)" },
+       { 0x04, "Amharic (am)" },
+       { 0x05, "Arabic (ar)" },
+       { 0x06, "Assamese (as)" },
+       { 0x07, "Aymara (ay)" },
+       { 0x08, "Azerbaijani (az)" },
+       { 0x09, "Bashkir (ba)" },
+       { 0x0A, "Byelorussian (be)" },
+       { 0x0B, "Bulgarian (bg)" },
+       { 0x0C, "Bihari (bh)" },
+       { 0x0D, "Bislama (bi)" },
+       { 0x0E, "Bengali; Bangla (bn)" },
+       { 0x0F, "Tibetan (bo)" },
+       { 0x10, "Breton (br)" },
+       { 0x11, "Catalan (ca)" },
+       { 0x12, "Corsican (co)" },
+       { 0x13, "Czech (cs)" },
+       { 0x14, "Welsh (cy)" },
+       { 0x15, "Danish (da)" },
+       { 0x16, "German (de)" },
+       { 0x17, "Bhutani (dz)" },
+       { 0x18, "Greek (el)" },
        { 0x19, "English (en)" },
+       { 0x1A, "Esperanto (eo)" },
+       { 0x1B, "Spanish (es)" },
+       { 0x1C, "Estonian (et)" },
+       { 0x1D, "Basque (eu)" },
+       { 0x1E, "Persian (fa)" },
+       { 0x1F, "Finnish (fi)" },
+       { 0x20, "Fiji (fj)" },
+       { 0x22, "French (fr)" },
+       { 0x24, "Irish (ga)" },
+       { 0x25, "Scots Gaelic (gd)" },
+       { 0x26, "Galician (gl)" },
+       { 0x27, "Guarani (gn)" },
+       { 0x28, "Gujarati (gu)" },
+       { 0x29, "Hausa (ha)" },
+       { 0x2A, "Hebrew (formerly iw) (he)" },
+       { 0x2B, "Hindi (hi)" },
+       { 0x2C, "Croatian (hr)" },
+       { 0x2D, "Hungarian (hu)" },
+       { 0x2E, "Armenian (hy)" },
+       { 0x30, "Indonesian (formerly in) (id)" },
+       { 0x47, "Maori (mi)" },
+       { 0x48, "Macedonian (mk)" },
+       { 0x49, "Malayalam (ml)" },
+       { 0x4A, "Mongolian (mn)" },
+       { 0x4B, "Moldavian (mo)" },
+       { 0x4C, "Marathi (mr)" },
+       { 0x4D, "Malay (ms)" },
+       { 0x4E, "Maltese (mt)" },
+       { 0x4F, "Burmese (my)" },
+       { 0x51, "Nepali (ne)" },
+       { 0x52, "Dutch (nl)" },
+       { 0x53, "Norwegian (no)" },
+       { 0x54, "Occitan (oc)" },
+       { 0x55, "(Afan) Oromo (om)" },
+       { 0x56, "Oriya (or)" },
+       { 0x57, "Punjabi (pa)" },
+       { 0x58, "Polish (po)" },
+       { 0x59, "Pashto, Pushto (ps)" },
+       { 0x5A, "Portuguese (pt)" },
+       { 0x5B, "Quechua (qu)" },
+       { 0x5D, "Kirundi (rn)" },
+       { 0x5E, "Romanian (ro)" },
+       { 0x5F, "Russian (ru)" },
+       { 0x60, "Kinyarwanda (rw)" },
+       { 0x61, "Sanskrit (sa)" },
+       { 0x62, "Sindhi (sd)" },
+       { 0x63, "Sangho (sg)" },
+       { 0x64, "Serbo-Croatian (sh)" },
+       { 0x65, "Sinhalese (si)" },
+       { 0x66, "Slovak (sk)" },
+       { 0x67, "Slovenian (sl)" },
+       { 0x68, "Samoan (sm)" },
+       { 0x69, "Shona (sn)" },
+       { 0x6A, "Somali (so)" },
+       { 0x6B, "Albanian (sq)" },
+       { 0x6C, "Serbian (sr)" },
+       { 0x6D, "Siswati (ss)" },
+       { 0x6E, "Sesotho (st)" },
+       { 0x6F, "Sundanese (su)" },
+       { 0x70, "Swedish (sv)" },
+       { 0x71, "Swahili (sw)" },
+       { 0x72, "Tamil (ta)" },
+       { 0x73, "Telugu (te)" },
+       { 0x74, "Tajik (tg)" },
+       { 0x75, "Thai (th)" },
+       { 0x76, "Tigrinya (ti)" },
+       { 0x81, "Nauru (na)" },
+       { 0x82, "Faeroese (fo)" },
+       { 0x83, "Frisian (fy)" },
+       { 0x84, "Interlingua (ia)" },
+       { 0x8C, "Rhaeto-Romance (rm)" },
+       { 0x00, NULL }
 };
 
 static const value_string vals_accept_ranges[] = {
        { 0x80, "None" },
        { 0x81, "Bytes" },
+       { 0x00, NULL }
 };
 
 static const value_string vals_cache_control[] = {
@@ -275,6 +370,12 @@ static const value_string vals_cache_control[] = {
        { 0x88, "No-transform" },
        { 0x89, "Must-revalidate" },
        { 0x8A, "Proxy-revalidate" },
+       { 0x00, NULL }
+};
+
+static const value_string vals_transfer_encoding[] = {
+       { 0x80, "Chunked" },
+       { 0x00, NULL }
 };
 
 /*
@@ -306,78 +407,27 @@ enum {
        PUT                             = 0x61,                 /* No sample data */
 };
 
-void add_uri (proto_tree *, tvbuff_t *, guint, guint);
-void add_headers (proto_tree *, tvbuff_t *);
-void add_header (proto_tree *, tvbuff_t *, tvbuff_t *);
-guint get_value_length (tvbuff_t *, guint, guint *);
-guint add_content_type (proto_tree *, tvbuff_t *, guint, guint *);
-guint add_parameter (proto_tree *, tvbuff_t *, guint);
-guint add_parameter_charset (proto_tree *, tvbuff_t *, guint, guint);
-void add_post_data (proto_tree *, tvbuff_t *, guint);
-void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
-
-/* 
- * Accessor to retrieve variable length int as used in WAP protocol.
- * The value is encoded in the lower 7 bits. If the top bit is set, then the
- * value continues into the next byte.
- * The octetCount parameter holds the number of bytes read in order to return
- * the final value. Can be pre-initialised to start at offset+count.
-*/
-guint
-tvb_get_guintvar (tvbuff_t *tvb, guint offset, guint *octetCount)
-{
-       guint value = 0;
-       guint octet;
-       guint counter = 0;
-       char cont = 1;
-       
-       if (octetCount != NULL)
-       {
-#ifdef DEBUG
-               fprintf (stderr, "dissect_wsp: Starting tvb_get_guintvar at offset %d, count=NULL\n", offset);
-#endif
-       }
-       else
-       {
-#ifdef DEBUG
-               fprintf (stderr, "dissect_wsp: Starting tvb_get_guintvar at offset %d, count=%d\n", offset, *octetCount);
-#endif
-               counter = *octetCount;
-       }
-
-       while (cont != 0)
-       {
-               value<<=7;      /* Value only exists in 7 of the 8 bits */
-               octet = tvb_get_guint8 (tvb, offset+counter);
-               counter++;
-               value += (octet & 0x7F);
-               cont = (octet & 0x80);
-#ifdef DEBUG
-               fprintf (stderr, "dissect_wsp: octet is %d (0x%02x), count=%d, value=%d, cont=%d\n", octet, octet, counter, value, cont);
-#endif
-       }
-
-       if (octetCount != NULL)
-       {
-               *octetCount = counter;
-#ifdef DEBUG
-               fprintf (stderr, "dissect_wsp: Leaving tvb_get_guintvar count=%d\n", *octetCount);
-#endif
-       }
-
-       return (value);
-}
+static void add_uri (proto_tree *, tvbuff_t *, guint, guint);
+static void add_headers (proto_tree *, tvbuff_t *);
+static void add_header (proto_tree *, tvbuff_t *, tvbuff_t *);
+static guint get_value_length (tvbuff_t *, guint, guint *);
+static guint add_content_type (proto_tree *, tvbuff_t *, guint, guint *);
+static gint get_date_value (tvbuff_t * ,guint ,struct timeval *);
+static void add_date_value (tvbuff_t * ,guint ,proto_tree * ,int ,
+       tvbuff_t * ,guint ,guint ,struct timeval *, const char *);
+static guint add_parameter (proto_tree *, tvbuff_t *, guint);
+static guint add_parameter_charset (proto_tree *, tvbuff_t *, guint, guint);
+static void add_post_data (proto_tree *, tvbuff_t *, guint);
+static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
 
 /* Code to actually dissect the packets */
-void
+static void
 dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
        frame_data *fdata = pinfo->fd;
        int offset = 0;
 
-       char szInfo[ 50 ];
-       int cchInfo;
-       char pdut;
+       guint8 pdut;
        guint count = 0;
        guint value = 0;
        guint uriLength = 0;
@@ -398,10 +448,6 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 /*     proto_tree *wsp_header_fixed; */
        proto_tree *wsp_capabilities;
        
-       CHECK_DISPLAY_AS_DATA(proto_wsp, tvb, pinfo, tree);
-
-       pinfo->current_proto = "WSP";
-
 /* This field shows up as the "Info" column in the display; you should make
    it, if possible, summarize what's in the packet, so that a user looking
    at the list of packets can tell what type of packet it is. */
@@ -420,8 +466,15 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                }
        }
 
+       /* Clear the Info column before we fetch anything from the packet */
+       if (check_col(fdata, COL_INFO))
+       {
+               col_clear(fdata, COL_INFO);
+       }
+
        /* Connection-less mode has a TID first */
-       if ((pinfo->match_port == UDP_PORT_WSP) || (pinfo->match_port == UDP_PORT_WTLS_WSP))
+       if (    (pinfo->match_port == UDP_PORT_WSP) ||
+                       (pinfo->match_port == UDP_PORT_WTLS_WSP))
        {
                offset++;
        };
@@ -430,10 +483,10 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        pdut = tvb_get_guint8 (tvb, offset);
 
        /* Develop the string to put in the Info column */
-       cchInfo = snprintf( szInfo, sizeof( szInfo ), "WSP %s",
-               match_strval (( int )pdut, vals_pdu_type));
-       if (check_col(fdata, COL_INFO)) {
-               col_add_str(fdata, COL_INFO, szInfo );
+       if (check_col(fdata, COL_INFO))
+       {
+               col_add_fstr(fdata, COL_INFO, "WSP %s",
+                       val_to_str (pdut, vals_pdu_type, "Unknown PDU type (0x%02x)"));
        };
 
 /* In the interest of speed, if "tree" is NULL, don't do any work not
@@ -445,18 +498,17 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
 /* Code to process the packet goes here */
 /*
-                       wsp_header_fixed = proto_item_add_subtree(
-                                       ti, 
-                                       ett_header 
-                               );
+                       wsp_header_fixed = proto_item_add_subtree(ti, ett_header );
 */
 
                        /* Add common items: only TID and PDU Type */
 
-                       /* TID Field is always first (if it exists) */
-                       if ((pinfo->match_port == UDP_PORT_WSP) || (pinfo->match_port == UDP_PORT_WTLS_WSP))
+                       /* If this is connectionless, then the TID Field is always first */
+                       if (    (pinfo->match_port == UDP_PORT_WSP) ||
+                                       (pinfo->match_port == UDP_PORT_WTLS_WSP))
                        {
-                               ti = proto_tree_add_item (wsp_tree, hf_wsp_header_tid,tvb,0,1,bo_little_endian);
+                               ti = proto_tree_add_item (wsp_tree, hf_wsp_header_tid,tvb,
+                                       0,1,bo_little_endian);
                        }
 
                        ti = proto_tree_add_item(
@@ -475,11 +527,13 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                        ti = proto_tree_add_item (wsp_tree, hf_wsp_version_minor,tvb,offset,1,bo_little_endian);
                                        offset++;
                                        capabilityStart = offset;
+                                       count = 0;      /* Initialise count */
                                        capabilityLength = tvb_get_guintvar (tvb, offset, &count);
                                        offset += count;
                                        ti = proto_tree_add_uint (wsp_tree, hf_wsp_capability_length,tvb,capabilityStart,count,capabilityLength);
 
                                        headerStart = offset;
+                                       count = 0;      /* Initialise count */
                                        headerLength = tvb_get_guintvar (tvb, offset, &count);
                                        offset += count;
                                        ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,headerStart,count,headerLength);
@@ -499,19 +553,22 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                        break;
 
                                case CONNECTREPLY:
+                                       count = 0;      /* Initialise count */
                                        value = tvb_get_guintvar (tvb, offset, &count);
                                        ti = proto_tree_add_uint (wsp_tree, hf_wsp_server_session_id,tvb,offset,count,value);
                                        offset += count;
 
                                        capabilityStart = offset;
+                                       count = 0;      /* Initialise count */
                                        capabilityLength = tvb_get_guintvar (tvb, offset, &count);
                                        offset += count;
                                        ti = proto_tree_add_uint (wsp_tree, hf_wsp_capability_length,tvb,capabilityStart,count,capabilityLength);
 
                                        headerStart = offset;
+                                       count = 0;      /* Initialise count */
                                        headerLength = tvb_get_guintvar (tvb, offset, &count);
                                        offset += count;
-                                       ti = proto_tree_add_item (wsp_tree, hf_wsp_header_length,tvb,headerStart,count,bo_little_endian);
+                                       ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,headerStart,count,headerLength);
                                        if (capabilityLength > 0)
                                        {
                                                ti = proto_tree_add_item (wsp_tree, hf_wsp_capabilities_section,tvb,offset,capabilityLength,bo_little_endian);
@@ -533,24 +590,28 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                        break;
 
                                case DISCONNECT:
+                                       count = 0;      /* Initialise count */
                                        value = tvb_get_guintvar (tvb, offset, &count);
                                        ti = proto_tree_add_uint (wsp_tree, hf_wsp_server_session_id,tvb,offset,count,value);
                                        break;
 
                                case GET:
+                                       count = 0;      /* Initialise count */
                                        /* Length of URI and size of URILen field */
                                        value = tvb_get_guintvar (tvb, offset, &count);
                                        nextOffset = offset + count;
                                        add_uri (wsp_tree, tvb, offset, nextOffset);
-                                       offset += (value+1);
+                                       offset += (value+count); /* VERIFY */
                                        tmp_tvb = tvb_new_subset (tvb, offset, -1, -1);
                                        add_headers (wsp_tree, tmp_tvb);
                                        break;
 
                                case POST:
                                        uriStart = offset;
+                                       count = 0;      /* Initialise count */
                                        uriLength = tvb_get_guintvar (tvb, offset, &count);
                                        headerStart = uriStart+count;
+                                       count = 0;      /* Initialise count */
                                        headersLength = tvb_get_guintvar (tvb, headerStart, &count);
                                        offset = headerStart + count;
 
@@ -577,9 +638,10 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
                                case REPLY:
                                        ti = proto_tree_add_item (wsp_tree, hf_wsp_header_status,tvb,offset,1,bo_little_endian);
+                                       count = 0;      /* Initialise count */
                                        value = tvb_get_guintvar (tvb, offset+1, &count);
                                        nextOffset = offset + 1 + count;
-                                       ti = proto_tree_add_item (wsp_tree, hf_wsp_header_length,tvb,offset+1,count,bo_little_endian);
+                                       ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,offset+1,count,value);
 
                                        contentTypeStart = nextOffset;
                                        nextOffset = add_content_type (wsp_tree, tvb, nextOffset, &contentType);
@@ -602,7 +664,7 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        }
 }
 
-void
+static void
 add_uri (proto_tree *tree, tvbuff_t *tvb, guint URILenOffset, guint URIOffset)
 {
        proto_item *ti;
@@ -630,7 +692,7 @@ add_uri (proto_tree *tree, tvbuff_t *tvb, guint URILenOffset, guint URIOffset)
        }
 }
 
-void
+static void
 add_headers (proto_tree *tree, tvbuff_t *tvb)
 {
        proto_item *ti;
@@ -703,7 +765,7 @@ add_headers (proto_tree *tree, tvbuff_t *tvb)
 #ifdef DEBUG
                        fprintf (stderr, "dissect_wsp: Looking for %d octets\n", peek);
 #endif
-                       valueStart++;
+                       /* VERIFY: valueStart++; */
                        valueEnd = offset+1+peek;
                        offset += (peek+1);
                }
@@ -712,6 +774,7 @@ add_headers (proto_tree *tree, tvbuff_t *tvb)
 #ifdef DEBUG
                        fprintf (stderr, "dissect_wsp: Looking for uintvar octets\n");
 #endif
+                       count = 0;      /* Initialise count */
                        tvb_get_guintvar (tvb, valueStart, &count);
                        valueEnd = offset+1+count;
                        offset += (count+1);
@@ -744,10 +807,11 @@ add_headers (proto_tree *tree, tvbuff_t *tvb)
        }
 }
 
-void
+static void
 add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
 {
        guint offset = 0;
+       guint valueStart = 0;
        guint8 headerType = 0;
        proto_item *ti;
        guint headerLen = tvb_reported_length (header_buff);
@@ -755,6 +819,14 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
        guint peek = 0;
        struct timeval timeValue;
        guint value = 0;
+       guint valueLength = 0;
+       char valString[100];
+       char *valMatch = NULL;
+       double q_value = 1.0;
+
+       /* Initialise time values */
+       timeValue.tv_sec=0;
+       timeValue.tv_usec = 0;
 
        headerType = tvb_get_guint8 (header_buff, 0);
        peek = tvb_get_guint8 (value_buff, 0);
@@ -786,38 +858,155 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
                                break;
 
                        case 0x01:              /* Accept-Charset */
+                               if (peek <= 31)                         /* Accept-charset-general-form */
+                               {
+                                       /* Get Value-Length */
+                                       valueLength = get_value_length (value_buff, offset,
+                                               &valueStart);
+                                       offset = valueStart;
+
+                                       peek = tvb_get_guint8 (value_buff, offset);
+                                       if ((peek >= 0x80) || (peek <= 30))     /* Well-known-charset */
+                                       {
+                                               if (peek == 0x80)               /* Any */
+                                               {
+                                                       value = peek;
+                                                       offset++;
+                                               }
+                                               else if (peek & 0x80)   /* Short-Integer */
+                                               {
+                                                       value = peek & 0x7F;
+                                                       offset++;
+                                               }
+                                               else if (peek <= 30)    /* Long-Integer */
+                                               {
+                                                       offset++;
+       
+                                                       switch (peek)
+                                                       {
+                                                               case 1:
+                                                                       value = tvb_get_guint8 (value_buff, offset);
+                                                                       break;
+                                                               case 2:
+                                                                       value = tvb_get_ntohs (value_buff, offset);
+                                                                       break;
+                                                               case 3:
+                                                                       value = tvb_get_ntoh24 (value_buff, offset);
+                                                                       break;
+                                                               case 4:
+                                                                       value = tvb_get_ntohl (value_buff, offset);
+                                                                       break;
+                                                               default:
+                                                                       /* TODO: Need to read peek octets */
+                                                                       value = 0;
+                                                                       fprintf (stderr, "dissect_wsp: accept-charset size %d NYI\n", peek);
+                                                                       break;
+                                                       }
+                                                       offset += peek;
+                                               }
+                                               valMatch = match_strval(value, vals_character_sets);
+                                       }
+                                       else                                            /* Assume Token-text */
+                                       {
+                                               fprintf (stderr, "dissect_wsp: Accept-Charset Token-text NYI\n");
+                                       }
+
+                                       /* Any remaining data relates to Q-Value */
+                                       if (offset < valueLen)
+                                       {
+                                               peek = tvb_get_guintvar (value_buff, offset, NULL);
+                                               if (peek <= 100) {
+                                                       peek = (peek - 1) * 10;
+                                               }
+                                               else {
+                                                       peek -= 100;
+                                               }
+                                               q_value = peek/1000.0;
+                                       }
+
+                                       /* Build string including Q values if present */
+                                       if (q_value == 1.0)                     /* Default */
+                                       {
+                                               if (valMatch == NULL)
+                                               {
+                                                       snprintf (valString, 100, "Unknown (%X)", peek);
+                                               }
+                                               else
+                                               {
+                                                       snprintf (valString, 100, "%s", valMatch);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               if (valMatch == NULL)
+                                               {
+                                                       snprintf (valString, 100, "Unknown (%X); Q=%5.3f", peek,q_value);
+                                               }
+                                               else
+                                               {
+                                                       snprintf (valString, 100, "%s; Q=%5.3f", valMatch,q_value);
+                                               }
+                                       }
+
+                                       /* Add string to tree */
+                                       proto_tree_add_string (tree, hf_wsp_header_accept_charset_str,
+                                               header_buff, 0, headerLen, valString);
+                               }
+                               else                                            /* Constrained-charset */
+                               {
+                                       if (peek == 0x80)               /* Any-charset */
+                                       {
+                                               proto_tree_add_string (tree, hf_wsp_header_accept_charset,
+                                                       header_buff, offset, headerLen,
+                                                       "*");
+                                       }
+                                       else if (peek & 0x80)   /* Short-Integer */
+                                       {
+                                               proto_tree_add_uint (tree, hf_wsp_header_accept_charset,
+                                                       header_buff, offset, headerLen, (peek & 0x7F) );
+                                       }
+                                       else                                    /* Assume *TEXT */
+                                       {
+                                               proto_tree_add_string (tree, hf_wsp_header_accept_charset,
+                                                       header_buff, offset, headerLen,
+                                                       tvb_get_ptr (value_buff, 0, valueLen));
+                                       }
+                               }
+                               break;
+
+                       case 0x03:              /* Accept-Language */
                                if (peek < 31)
                                {
                                        /* Peek contains the number of octets to follow */
                                        switch (peek)
                                        {
                                                case 1:
-                                                       proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_guint8 (value_buff, 1) );
-                                                       break;
+                                                       proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, 
+                                                               headerLen, tvb_get_guint8 (value_buff, 1) );
+                                               break;
                                                case 2:
-                                                       proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_ntohs (value_buff, 1) );
-                                                       break;
+                                                       proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, 
+                                                               headerLen, tvb_get_ntohs (value_buff, 1) );
+                                               break;
                                                case 4:
-                                                       proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_ntohl (value_buff, 1) );
-                                                       break;
+                                                       proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, 
+                                                               headerLen, tvb_get_ntohl (value_buff, 1) );
+                                               break;
                                                default:
-                                                       fprintf (stderr, "dissect_wsp: accept-charset size %d NYI\n", peek);
+                                                       fprintf (stderr, "dissect_wsp: accept-language size %d NYI\n", peek);
                                        }
                                }
                                else if (peek & 0x80)
                                {
-                                       proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, (peek & 0x7F) );
+                                       proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, headerLen, (peek & 0x7F) );
                                }
                                else
                                {
-                                       fprintf (stderr, "dissect_wsp: Accept-Charset value %d (0x%02X) NYI\n", peek, peek);
+                                       proto_tree_add_string (tree, hf_wsp_header_accept_language_str, header_buff, offset,headerLen,
+                                               tvb_get_ptr (value_buff, 0, valueLen));
                                }
                                break;
 
-                       case 0x03:              /* Accept-Language */
-                               proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, headerLen, (peek & 0x7F));
-                               break;
-
                        case 0x04:              /* Accept-Ranges */
                                if ((peek == 128) || (peek == 129))
                                {
@@ -862,8 +1051,11 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
                                                        value = tvb_get_guint8 (value_buff, 1);
                                                        if (value & 0x80)
                                                        {
-                                                               proto_tree_add_text (tree, header_buff, 0, headerLen, "Cache-Control: %s %d (0x%02X)",
-                                                                       match_strval ((int) peek, vals_cache_control), (value & 0x7F), peek);
+                                                               proto_tree_add_text (tree, header_buff, 0,
+                                                                       headerLen, "Cache-Control: %s %d (0x%02X)",
+                                                               val_to_str (peek, vals_cache_control,
+                                                                       "Unknown (0x%02x)"),
+                                                               (value & 0x7F), peek);
                                                        }
                                                        else
                                                        {
@@ -887,7 +1079,36 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
                                break;
                                
                        case 0x0D:              /* Content-Length */
-                               if (peek & 0x80)
+                               if (peek < 31)
+                               {
+                                       switch (peek)
+                                       {
+                                               case 1:
+                                                       proto_tree_add_uint (tree,
+                                                               hf_wsp_header_content_length, header_buff, offset,
+                                                               headerLen, tvb_get_guint8 (value_buff, 1) );
+                                                       break;
+                                               case 2:
+                                                       proto_tree_add_uint (tree,
+                                                               hf_wsp_header_content_length, header_buff, offset,
+                                                               headerLen, tvb_get_ntohs (value_buff, 1) );
+                                                       break;
+                                               case 3:
+                                                       proto_tree_add_uint (tree,
+                                                               hf_wsp_header_content_length, header_buff, offset,
+                                                               headerLen, (tvb_get_ntohs (value_buff, 1) << 8) +
+                                                               tvb_get_guint8 (value_buff, 3) );
+                                                       break;
+                                               case 4:
+                                                       proto_tree_add_uint (tree,
+                                                               hf_wsp_header_content_length, header_buff, offset,
+                                                               headerLen, tvb_get_ntohl (value_buff, 1) );
+                                                       break;
+                                               default:
+                                                       fprintf (stderr, "dissect_wsp: accept-charset size %d NYI\n", peek);
+                                       }
+                               }
+                               else if (peek & 0x80)
                                {
                                        proto_tree_add_uint (tree, hf_wsp_header_content_length, header_buff, offset, headerLen, (peek & 0x7F));
                                }
@@ -898,8 +1119,9 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
                                break;
                                
                        case 0x12:              /* Date */
-                               timeValue.tv_sec = tvb_get_ntohl (value_buff, 0);
-                               ti = proto_tree_add_time (tree, hf_wsp_header_date, header_buff, offset, headerLen, &timeValue);
+                               add_date_value (value_buff, 0, tree,
+                                       hf_wsp_header_date, header_buff, offset,
+                                       headerLen, &timeValue, "Date");
                                break;
 
                        case 0x13:              /* Etag */
@@ -907,32 +1129,15 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
                                break;
 
                        case 0x14:              /* Expires */
-                               switch (valueLen)
-                               {
-                                       case 1:
-                                       case 2:
-                                               fprintf (stderr, "dissect_wsp: Expires value length %d NYI\n", valueLen);
-                                               break;
-                                       case 3:
-                                               timeValue.tv_sec = tvb_get_ntoh24 (value_buff, 0);
-                                               break;
-                                       case 4:
-                                               timeValue.tv_sec = tvb_get_ntohl (value_buff, 0);
-                                               break;
-                               };
-                               ti = proto_tree_add_time (tree, hf_wsp_header_expires, header_buff, offset, headerLen, &timeValue);
+                               add_date_value (value_buff, 0, tree,
+                                       hf_wsp_header_expires, header_buff, offset,
+                                       headerLen, &timeValue, "Expires");
                                break;
 
                        case 0x17:              /* If-Modified-Since */
-                               if (valueLen == 4)
-                               {
-                                       timeValue.tv_sec = tvb_get_ntohl (value_buff, 0);
-                               }
-                               else
-                               {
-                                       timeValue.tv_sec = 0;
-                               }
-                               ti = proto_tree_add_time (tree, hf_wsp_header_if_modified_since, header_buff, offset, headerLen, &timeValue);
+                               add_date_value (value_buff, 0, tree,
+                                       hf_wsp_header_if_modified_since, header_buff, offset,
+                                       headerLen, &timeValue, "If-Modified-Since");
                                break;
                                
                        case 0x1C:              /* Location */
@@ -940,8 +1145,9 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
                                break;
 
                        case 0x1D:              /* Last-Modified */
-                               timeValue.tv_sec = tvb_get_ntohl (value_buff, 0);
-                               ti = proto_tree_add_time (tree, hf_wsp_header_last_modified, header_buff, offset, headerLen, &timeValue);
+                               add_date_value (value_buff, 0, tree,
+                                       hf_wsp_header_last_modified, header_buff, offset,
+                                       headerLen, &timeValue, "Last-Modified");
                                break;
                                
                        case 0x1F:              /* Pragma */
@@ -959,10 +1165,29 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
                                ti = proto_tree_add_string (tree, hf_wsp_header_server,header_buff,offset,headerLen,tvb_get_ptr (value_buff, 0, valueLen));
                                break;
 
+                       case 0x27:              /* Transfer encoding */
+                               if (peek & 0x80)
+                               {
+                                       proto_tree_add_uint (tree, hf_wsp_header_transfer_encoding,
+                                               header_buff, offset, headerLen, peek);
+                               }
+                               else
+                               {
+                                       proto_tree_add_string (tree,
+                                               hf_wsp_header_transfer_encoding_str, header_buff, offset,
+                                               headerLen,tvb_get_ptr (value_buff, 0, valueLen));
+                               }
+                               break;
+
                        case 0x29:              /* User-Agent */
                                ti = proto_tree_add_string (tree, hf_wsp_header_user_agent,header_buff,offset,headerLen,tvb_get_ptr (value_buff, 0, valueLen));
                                break;
 
+                       case 0x2B:              /* Via */
+                               ti = proto_tree_add_string (tree, hf_wsp_header_via, header_buff,
+                                       offset, headerLen, tvb_get_ptr (value_buff, 0, valueLen));
+                               break;
+
                        default:
                                ti = proto_tree_add_text (tree, header_buff, 0, headerLen, "Unsupported Header (0x%02X)", (tvb_get_guint8 (header_buff, 0) & 0x7F));
                                break;
@@ -974,14 +1199,34 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
                 * by a 4-byte date value */
                if (strncasecmp ("x-wap.tod", tvb_get_ptr (header_buff, 0, headerLen), 9) == 0)
                {
-                       if (tvb_reported_length (value_buff) == 4)      /* Probably a date value */
+                       peek = tvb_get_guint8 (value_buff,offset);
+                       if (peek < 31) 
                        {
-                               timeValue.tv_sec = tvb_get_ntohl (value_buff, 0);
+                               timeValue.tv_usec = 0;
+                               switch (peek)
+                               {
+                                       case 1:
+                                               timeValue.tv_sec = tvb_get_guint8 (value_buff, 1);
+                                               break;
+                                       case 2:
+                                               timeValue.tv_sec = tvb_get_ntohs (value_buff, 1);
+                                               break;
+                                       case 3:
+                                               timeValue.tv_sec = tvb_get_ntoh24 (value_buff, 1);
+                                               break;
+                                       case 4:
+                                               timeValue.tv_sec = tvb_get_ntohl (value_buff, 1);
+                                               break;
+                                       default:
+                                               timeValue.tv_sec = 0;
+                                               fprintf (stderr, "dissect_wsp: X-WAP.TOD NYI\n");
+                                               break;
+                               }
                                ti = proto_tree_add_time (tree, hf_wsp_header_x_wap_tod, header_buff, offset, headerLen, &timeValue);
                        }
                        else
-                       {
-                               ti = proto_tree_add_text (tree, header_buff, 0, headerLen, "%s: %s", tvb_get_ptr (header_buff, 0, headerLen), tvb_get_ptr (value_buff, 0, valueLen));
+                       {
+                               fprintf (stderr, "dissect_wsp: X-WAP.TOD peek %X NYI\n",peek);
                        }
                }
                else
@@ -992,7 +1237,7 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff)
 
 }
 
-guint
+static guint
 get_value_length (tvbuff_t *tvb, guint offset, guint *nextOffset)
 {
        guint value = 0;
@@ -1017,7 +1262,7 @@ get_value_length (tvbuff_t *tvb, guint offset, guint *nextOffset)
        return (value);
 }
 
-guint
+static guint
 add_content_type (proto_tree *tree, tvbuff_t *tvb, guint offset, guint *contentType)
 {
        proto_tree *contentTypeTree;
@@ -1053,7 +1298,71 @@ add_content_type (proto_tree *tree, tvbuff_t *tvb, guint offset, guint *contentT
        return (offset+totalSizeOfField);
 }
 
-guint
+/* Utility function to extract date values from the packet */
+static gint
+get_date_value (tvbuff_t *buffer, guint offset, struct timeval *timeValue)
+{
+       guint ShortLength = 0;
+
+       /* Initialise time values */
+       timeValue->tv_sec=0;
+       timeValue->tv_usec = 0;
+
+       /* Date values are encoded as: Short-length Multi-octet-integer
+        * Where Short-length = 0-30
+        */
+       ShortLength = tvb_get_guint8 (buffer, offset++);
+       if (ShortLength > 30)
+       {
+               fprintf (stderr, "dissect_wsp: Invalid Date-value (Short-length=%d)\n",
+                       ShortLength);
+               return (-1);
+       }
+
+       switch (ShortLength)
+       {
+               case 1:
+                       timeValue->tv_sec = tvb_get_guint8 (buffer, offset);
+                       break;
+               case 2:
+                       timeValue->tv_sec = tvb_get_ntohs (buffer, offset);
+                       break;
+               case 3:
+                       timeValue->tv_sec = tvb_get_ntoh24 (buffer, offset);
+                       break;
+               case 4:
+                       timeValue->tv_sec = tvb_get_ntohl (buffer, offset);
+                       break;
+               default:
+                       fprintf (stderr, "dissect_wsp: Date-value Short-length of %d NYI\n",
+                               ShortLength);
+                       return (-1);
+                       break;
+       }
+
+       return (0);
+}
+
+/* Utility function to add a date value to the protocol tree */
+static void
+add_date_value (tvbuff_t *buffer, guint offset, proto_tree *tree,
+               int header, tvbuff_t *headerBuffer, guint headerOffset,
+               guint headerLen, struct timeval *timeValue, const char *fieldName)
+{
+       /* Attempt to get the date value from the buffer */
+       if (get_date_value (buffer, offset, timeValue) == 0)
+       {
+               /* If successful, add it to the protocol tree */
+               proto_tree_add_time (tree, header, headerBuffer, headerOffset,
+                       headerLen, timeValue);
+       }
+       else
+       {
+               fprintf (stderr, "dissect_wsp: Invalid %s value\n", fieldName);
+       }
+}
+
+static guint
 add_parameter (proto_tree *tree, tvbuff_t *tvb, guint offset)
 {
        guint octet = tvb_get_guint8 (tvb, offset);
@@ -1079,7 +1388,7 @@ add_parameter (proto_tree *tree, tvbuff_t *tvb, guint offset)
        return (offset);
 }
 
-guint
+static guint
 add_parameter_charset (proto_tree *tree, tvbuff_t *tvb, guint offset, guint startOffset)
 {
        guint octet = tvb_get_guint8 (tvb, offset);
@@ -1097,7 +1406,7 @@ add_parameter_charset (proto_tree *tree, tvbuff_t *tvb, guint offset, guint star
        return offset;
 }
 
-void
+static void
 add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType)
 {
        guint offset = 0;
@@ -1108,7 +1417,8 @@ add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType)
        guint8 peek = 0;
        proto_item *ti;
        
-       ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,END_OF_FRAME,bo_little_endian);
+       /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,END_OF_FRAME,bo_little_endian); */
+       ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,tvb_reported_length(tvb),bo_little_endian);
 
        if (contentType == 0x12)        /* URL Encoded data */
        {
@@ -1118,7 +1428,7 @@ add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType)
                        peek = tvb_get_guint8 (tvb, offset);
                        if (peek == '=')
                        {
-                               variableEnd = offset-1;
+                               variableEnd = offset;
                                valueStart = offset+1;
                        }
                        else if (peek == '&')
@@ -1142,7 +1452,7 @@ add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType)
        }
 }
 
-void
+static void
 add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint variableEnd, guint valueStart, guint valueEnd)
 {
        int variableLength = variableEnd-variableStart;
@@ -1151,10 +1461,10 @@ add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint v
        char *valueBuffer;
 
        variableBuffer = g_malloc (variableLength+1);
-       strncpy (variableBuffer, tvb_get_ptr (tvb, variableStart, variableLength), variableLength+1);
-       variableBuffer[variableLength+1] = 0;
+       strncpy (variableBuffer, tvb_get_ptr (tvb, variableStart, variableLength), variableLength);
+       variableBuffer[variableLength] = 0;
 
-       if (valueEnd == 0)
+       if (valueEnd < valueStart)
        {
                valueBuffer = g_malloc (1);
                valueBuffer[0] = 0;
@@ -1198,7 +1508,7 @@ proto_register_wsp(void)
                },
                { &hf_wsp_header_pdu_type,
                        {       "PDU Type",           
-                               "wsp.pdu-type",
+                               "wsp.pdu_type",
                                 FT_UINT8, BASE_HEX, VALS( vals_pdu_type ), 0x00,
                                "PDU Type" 
                        }
@@ -1226,7 +1536,7 @@ proto_register_wsp(void)
                },
                { &hf_wsp_header_length,
                        {       "Headers Length",           
-                               "wsp.headers-length",
+                               "wsp.headers_length",
                                 FT_UINT32, BASE_DEC, NULL, 0x00,
                                "Headers Length" 
                        }
@@ -1254,7 +1564,7 @@ proto_register_wsp(void)
                },
                { &hf_wsp_header_uri_len,
                        {       "URI Length",           
-                               "wsp.uri-length",
+                               "wsp.uri_length",
                                 FT_UINT32, BASE_DEC, NULL, 0x00,
                                "URI Length" 
                        }
@@ -1268,7 +1578,7 @@ proto_register_wsp(void)
                },
                { &hf_wsp_server_session_id,
                        {       "Server Session ID",           
-                               "wsp.server.session-id",
+                               "wsp.server.session_id",
                                 FT_UINT32, BASE_DEC, NULL, 0x00,
                                "Server Session ID" 
                        }
@@ -1282,14 +1592,14 @@ proto_register_wsp(void)
                },
                { &hf_wsp_content_type,
                        {       "Content Type",           
-                               "wsp.content-type.type",
+                               "wsp.content_type.type",
                                 FT_UINT8, BASE_HEX, VALS ( vals_content_types ), 0x00,
                                "Content Type" 
                        }
                },
                { &hf_wsp_parameter_well_known_charset,
                        {       "Charset",           
-                               "wsp.content-type.parameter.charset",
+                               "wsp.content_type.parameter.charset",
                                 FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00,
                                "Charset" 
                        }
@@ -1318,21 +1628,35 @@ proto_register_wsp(void)
                },
                { &hf_wsp_header_accept_charset,
                        {       "Accept-Charset",           
-                               "wsp.header.accept-charset",
+                               "wsp.header.accept_charset",
                                 FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00,
                                "Accept-Charset" 
                        }
                },
+               { &hf_wsp_header_accept_charset_str,
+                       {       "Accept-Charset",           
+                               "wsp.header.accept_charset.string",
+                                FT_STRING, BASE_NONE, NULL, 0x00,
+                               "Accept-Charset" 
+                       }
+               },
                { &hf_wsp_header_accept_language,
                        {       "Accept-Language",           
-                               "wsp.header.accept-language",
+                               "wsp.header.accept_language",
                                 FT_UINT8, BASE_HEX, VALS ( vals_languages ), 0x00,
                                "Accept-Language" 
                        }
                },
+               { &hf_wsp_header_accept_language_str,
+                       {       "Accept-Language",           
+                               "wsp.header.accept_language.string",
+                                FT_STRING, BASE_NONE, NULL, 0x00,
+                               "Accept-Language" 
+                       }
+               },
                { &hf_wsp_header_accept_ranges,
                        {       "Accept-Ranges",           
-                               "wsp.header.accept-ranges",
+                               "wsp.header.accept_ranges",
                                 FT_UINT8, BASE_HEX, VALS ( vals_accept_ranges ), 0x00,
                                "Accept-Ranges" 
                        }
@@ -1346,14 +1670,14 @@ proto_register_wsp(void)
                },
                { &hf_wsp_header_cache_control,
                        {       "Cache-Control",           
-                               "wsp.header.cache-control",
+                               "wsp.header.cache_control",
                                 FT_UINT8, BASE_HEX, VALS ( vals_cache_control ), 0x00,
                                "Cache-Control" 
                        }
                },
                { &hf_wsp_header_content_length,
                        {       "Content-Length",           
-                               "wsp.header.content-length",
+                               "wsp.header.content_length",
                                 FT_UINT32, BASE_DEC, NULL, 0x00,
                                "Content-Length" 
                        }
@@ -1382,7 +1706,7 @@ proto_register_wsp(void)
                },
                { &hf_wsp_header_last_modified,
                        {       "Last-Modified",           
-                               "wsp.header.last-modified",
+                               "wsp.header.last_modified",
                                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
                                "Last-Modified" 
                        }
@@ -1396,7 +1720,7 @@ proto_register_wsp(void)
                },
                { &hf_wsp_header_if_modified_since,
                        {       "If-Modified-Since",           
-                               "wsp.header.if-modified-since",
+                               "wsp.header.if_modified_since",
                                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
                                "If-Modified-Since" 
                        }
@@ -1409,24 +1733,46 @@ proto_register_wsp(void)
                                "Server" 
                        }
                },
+               { &hf_wsp_header_transfer_encoding,
+                       {       "Transfer Encoding",           
+                               "wsp.header.transfer_enc",
+                                /*FT_NONE, BASE_DEC, NULL, 0x00,*/
+                                FT_UINT8, BASE_HEX, VALS ( vals_transfer_encoding ), 0x00,
+                               "Transfer Encoding" 
+                       }
+               },
+               { &hf_wsp_header_transfer_encoding_str,
+                       {       "Transfer Encoding",           
+                               "wsp.header.transfer_enc_str",
+                                FT_STRING, BASE_NONE, NULL, 0x00,
+                               "Transfer Encoding" 
+                       }
+               },
                { &hf_wsp_header_user_agent,
                        {       "User-Agent",           
-                               "wsp.header.user-agent",
+                               "wsp.header.user_agent",
                                 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
                                 FT_STRING, BASE_NONE, NULL, 0x00,
                                "User-Agent" 
                        }
                },
+               { &hf_wsp_header_via,
+                       {       "Via",           
+                               "wsp.header.via",
+                                FT_STRING, BASE_NONE, NULL, 0x00,
+                               "Via" 
+                       }
+               },
                { &hf_wsp_header_application_header,
                        {       "Application Header",           
-                               "wsp.header.application-header",
+                               "wsp.header.application_header",
                                 FT_STRING, BASE_NONE, NULL, 0x00,
                                "Application Header" 
                        }
                },
                { &hf_wsp_header_application_value,
                        {       "Application Header Value",           
-                               "wsp.header.application-header.value",
+                               "wsp.header.application_header.value",
                                 FT_STRING, BASE_NONE, NULL, 0x00,
                                "Application Header Value" 
                        }
@@ -1459,6 +1805,7 @@ proto_register_wsp(void)
 /* Register the protocol name and description */
        proto_wsp = proto_register_protocol(
                "Wireless Session Protocol",    /* protocol name for use by ethereal */ 
+               "WSP",                          /* short version of name */
                "wap-wsp"                       /* Abbreviated protocol name, should Match IANA 
                                                    < URL:http://www.isi.edu/in-notes/iana/assignments/port-numbers/ >
                                                  */
@@ -1467,14 +1814,20 @@ proto_register_wsp(void)
 /* Required function calls to register the header fields and subtrees used  */
        proto_register_field_array(proto_wsp, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
+
+       register_dissector("wsp", dissect_wsp, proto_wsp);
 };
 
 void
 proto_reg_handoff_wsp(void)
 {
+       /*
+        * Get a handle for the WMLC dissector
+        */
+       wmlc_handle = find_dissector("wmlc");   /* Coming soon :) */
+
        /* Only connection-less WSP has no previous handler */
-       dissector_add("udp.port", UDP_PORT_WSP, dissect_wsp);
-       /* dissector_add("udp.port", UDP_PORT_WTP_WSP, dissect_wsp); */
-       /* dissector_add("udp.port", UDP_PORT_WTLS_WSP, dissect_wsp); */
-       /* dissector_add("udp.port", UDP_PORT_WTLS_WTP_WSP, dissect_wsp); */
+       dissector_add("udp.port", UDP_PORT_WSP, dissect_wsp, proto_wsp);
+
+       /* This dissector is also called from the WTP and WTLS dissectors */
 }