*
* Routines to dissect WSP component of WAP traffic.
*
- * $Id: packet-wsp.c,v 1.32 2001/07/30 21:24:29 guy Exp $
+ * $Id: packet-wsp.c,v 1.54 2002/02/22 07:23:24 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
- * Copyright 1998 Didier Jorand
+ * Copyright 1998 Gerald Combs
*
* 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)
+ * Openwave header support by Dermot Bradley <dermot.bradley@openwave.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#include <string.h>
#include <glib.h>
-#include "packet.h"
-#include "ipv6-utils.h"
-#include "conversation.h"
+#include <epan/packet.h>
+#include <epan/ipv6-utils.h>
+#include <epan/conversation.h>
#include "packet-wap.h"
#include "packet-wsp.h"
static int hf_wsp_parameter_comment = HF_EMPTY;
static int hf_wsp_parameter_domain = HF_EMPTY;
static int hf_wsp_parameter_path = HF_EMPTY;
+static int hf_wsp_parameter_upart_type = HF_EMPTY;
+static int hf_wsp_parameter_upart_type_value = HF_EMPTY;
static int hf_wsp_reply_data = HF_EMPTY;
static int hf_wsp_post_data = HF_EMPTY;
+static int hf_wsp_push_data = HF_EMPTY;
+static int hf_wsp_multipart_data = HF_EMPTY;
+static int hf_wsp_mpart = HF_EMPTY;
static int hf_wsp_header_shift_code = HF_EMPTY;
static int hf_wsp_header_accept = HF_EMPTY;
static int hf_wsp_header_cache_control = HF_EMPTY;
static int hf_wsp_header_cache_control_str = HF_EMPTY;
static int hf_wsp_header_cache_control_field_name = HF_EMPTY;
+static int hf_wsp_header_connection = HF_EMPTY;
+static int hf_wsp_header_connection_str = HF_EMPTY;
static int hf_wsp_header_cache_control_field_name_str = HF_EMPTY;
static int hf_wsp_header_content_length = HF_EMPTY;
static int hf_wsp_header_age = 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_content_ID = 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;
+static int hf_wsp_header_wap_application_id = HF_EMPTY;
+static int hf_wsp_header_wap_application_id_str = HF_EMPTY;
+
+
+/* Openwave-specific WSP headers */
+static int hf_wsp_header_openwave_proxy_push_addr = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_push_accept = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_push_seq = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_notify = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_operator_domain = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_home_page = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_has_color = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_num_softkeys = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_softkey_size = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_screen_chars = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_screen_pixels = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_em_size = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_screen_depth = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_immed_alert = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_net_ask = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_uplink_version = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_tod = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_ba_enable = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_ba_realm = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_redirect_enable = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_request_uri = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_redirect_status = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_trans_charset = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_trans_charset_str = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_linger = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_client_id = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_enable_trust = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_trust_old = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_trust = HF_EMPTY;
+static int hf_wsp_header_openwave_proxy_bookmark = HF_EMPTY;
+static int hf_wsp_header_openwave_devcap_gui = HF_EMPTY;
+
static int hf_wsp_redirect_flags = HF_EMPTY;
static int hf_wsp_redirect_permanent = HF_EMPTY;
static gint ett_content_type = ETT_EMPTY;
static gint ett_redirect_flags = ETT_EMPTY;
static gint ett_redirect_afl = ETT_EMPTY;
+static gint ett_multiparts = ETT_EMPTY;
+static gint ett_mpartlist = ETT_EMPTY;
+
+/* Handle for WSP-over-UDP dissector */
+static dissector_handle_t wsp_fromudp_handle;
+
+/* Handle for WTP-over-UDP dissector */
+static dissector_handle_t wtp_fromudp_handle;
/* Handle for WMLC dissector */
static dissector_handle_t wmlc_handle;
{ 0x33, "See Other" },
{ 0x34, "Not Modified" },
{ 0x35, "Use Proxy" },
+ { 0x37, "Temporary Redirect" },
{ 0x40, "Bad Request" },
{ 0x41, "Unauthorised" },
{ 0x4D, "Request Entity Too Large" },
{ 0x4E, "Request-URI Too Large" },
{ 0x4F, "Unsupported Media Type" },
+ { 0x50, "Requested Range Not Satisfiable" },
+ { 0x51, "Expectation Failed" },
{ 0x60, "Internal Server Error" },
{ 0x61, "Not Implemented" },
#define FN_SET_COOKIE 0x41
#define FN_COOKIE 0x42
#define FN_ENCODING_VERSION 0x43
+#define FN_PROFILE_WARNING14 0x44 /* encoding version 1.4 */
+#define FN_CONTENT_DISPOSITION14 0x45 /* encoding version 1.4 */
+#define FN_X_WAP_SECURITY 0x46
+#define FN_CACHE_CONTROL14 0x47 /* encoding version 1.4 */
+
+
+/*
+ * Openwave field names.
+ */
+#define FN_OPENWAVE_PROXY_PUSH_ADDR 0x00
+#define FN_OPENWAVE_PROXY_PUSH_ACCEPT 0x01
+#define FN_OPENWAVE_PROXY_PUSH_SEQ 0x02
+#define FN_OPENWAVE_PROXY_NOTIFY 0x03
+#define FN_OPENWAVE_PROXY_OPERATOR_DOMAIN 0x04
+#define FN_OPENWAVE_PROXY_HOME_PAGE 0x05
+#define FN_OPENWAVE_DEVCAP_HAS_COLOR 0x06
+#define FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS 0x07
+#define FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE 0x08
+#define FN_OPENWAVE_DEVCAP_SCREEN_CHARS 0x09
+#define FN_OPENWAVE_DEVCAP_SCREEN_PIXELS 0x0A
+#define FN_OPENWAVE_DEVCAP_EM_SIZE 0x0B
+#define FN_OPENWAVE_DEVCAP_SCREEN_DEPTH 0x0C
+#define FN_OPENWAVE_DEVCAP_IMMED_ALERT 0x0D
+#define FN_OPENWAVE_PROXY_NET_ASK 0x0E
+#define FN_OPENWAVE_PROXY_UPLINK_VERSION 0x0F
+#define FN_OPENWAVE_PROXY_TOD 0x10
+#define FN_OPENWAVE_PROXY_BA_ENABLE 0x11
+#define FN_OPENWAVE_PROXY_BA_REALM 0x12
+#define FN_OPENWAVE_PROXY_REDIRECT_ENABLE 0x13
+#define FN_OPENWAVE_PROXY_REQUEST_URI 0x14
+#define FN_OPENWAVE_PROXY_REDIRECT_STATUS 0x15
+#define FN_OPENWAVE_PROXY_TRANS_CHARSET 0x16
+#define FN_OPENWAVE_PROXY_LINGER 0x17
+#define FN_OPENWAVE_PROXY_CLIENT_ID 0x18
+#define FN_OPENWAVE_PROXY_ENABLE_TRUST 0x19
+#define FN_OPENWAVE_PROXY_TRUST_OLD 0x1A
+#define FN_OPENWAVE_PROXY_TRUST 0x20
+#define FN_OPENWAVE_PROXY_BOOKMARK 0x21
+#define FN_OPENWAVE_DEVCAP_GUI 0x22
+
+static const value_string vals_openwave_field_names[] = {
+ { FN_OPENWAVE_PROXY_PUSH_ADDR, "x-up-proxy-push-addr" },
+ { FN_OPENWAVE_PROXY_PUSH_ACCEPT, "x-up-proxy-push-accept" },
+ { FN_OPENWAVE_PROXY_PUSH_SEQ, "x-up-proxy-seq" },
+ { FN_OPENWAVE_PROXY_NOTIFY, "x-up-proxy-notify" },
+ { FN_OPENWAVE_PROXY_OPERATOR_DOMAIN, "x-up-proxy-operator-domain" },
+ { FN_OPENWAVE_PROXY_HOME_PAGE, "x-up-proxy-home-page" },
+ { FN_OPENWAVE_DEVCAP_HAS_COLOR, "x-up-devcap-has-color" },
+ { FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS, "x-up-devcap-num-softkeys" },
+ { FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE, "x-up-devcap-softkey-size" },
+ { FN_OPENWAVE_DEVCAP_SCREEN_CHARS, "x-up-devcap-screen-chars" },
+ { FN_OPENWAVE_DEVCAP_SCREEN_PIXELS, "x-up-devcap-screen-pixels" },
+ { FN_OPENWAVE_DEVCAP_EM_SIZE, "x-up-devcap-em-size" },
+ { FN_OPENWAVE_DEVCAP_SCREEN_DEPTH, "x-up-devcap-screen-depth" },
+ { FN_OPENWAVE_DEVCAP_IMMED_ALERT, "x-up-devcap-immed-alert" },
+ { FN_OPENWAVE_PROXY_NET_ASK, "x-up-proxy-net-ask" },
+ { FN_OPENWAVE_PROXY_UPLINK_VERSION, "x-up-proxy-uplink-version" },
+ { FN_OPENWAVE_PROXY_TOD, "x-up-proxy-tod" },
+ { FN_OPENWAVE_PROXY_BA_ENABLE, "x-up-proxy-ba-enable" },
+ { FN_OPENWAVE_PROXY_BA_REALM, "x-up-proxy-ba-realm" },
+ { FN_OPENWAVE_PROXY_REDIRECT_ENABLE, "x-up-proxy-redirect-enable" },
+ { FN_OPENWAVE_PROXY_REQUEST_URI, "x-up-proxy-request-uri" },
+ { FN_OPENWAVE_PROXY_REDIRECT_STATUS, "x-up-proxy-redirect-status" },
+ { FN_OPENWAVE_PROXY_TRANS_CHARSET, "x-up-proxy-trans-charset" },
+ { FN_OPENWAVE_PROXY_LINGER, "x-up-proxy-linger" },
+ { FN_OPENWAVE_PROXY_CLIENT_ID, "x-up-proxy-client-id" },
+ { FN_OPENWAVE_PROXY_ENABLE_TRUST, "x-up-proxy-enable-trust" },
+ { FN_OPENWAVE_PROXY_TRUST_OLD, "x-up-proxy-trust-old" },
+ { FN_OPENWAVE_PROXY_TRUST, "x-up-proxy-trust" },
+ { FN_OPENWAVE_PROXY_BOOKMARK, "x-up-proxy-bookmark" },
+ { FN_OPENWAVE_DEVCAP_GUI, "x-up-devcap-gui" },
+ { 0, NULL }
+};
+
static const value_string vals_field_names[] = {
{ FN_ACCEPT, "Accept" },
{ FN_SET_COOKIE, "Set-Cookie" },
{ FN_COOKIE, "Cookie" },
{ FN_ENCODING_VERSION, "Encoding-Version" },
+ { FN_PROFILE_WARNING14, "Profile-Warning (encoding 1.4)" },
+ { FN_CONTENT_DISPOSITION14,"Content-Disposition (encoding 1.4)" },
+ { FN_X_WAP_SECURITY, "X-WAP-Security" },
+ { FN_CACHE_CONTROL14, "Cache-Control (encoding 1.4)" },
{ 0, NULL }
};
{ 0x32, "application/vnd.wap.coc" },
{ 0x33, "application/vnd.wap.multipart.related" },
{ 0x34, "application/vnd.wap.sia" },
+ { 0x35, "text/vnd.wap.connectivity-xml" },
+ { 0x36, "application/vnd.wap.connectivity-wbxml" },
+ { 0x37, "application/pkcs7-mime" },
+ { 0x38, "application/vnd.wap.hashed-certificate" },
+ { 0x39, "application/vnd.wap.signed-certificate" },
+ { 0x3A, "application/vnd.wap.cert-response" },
+ { 0x3B, "application/xhtml+xml" },
+ { 0x3C, "application/wml+xml" },
+ { 0x3D, "text/css" },
+ { 0x3E, "application/vnd.wap.mms-message" },
+ { 0x3F, "application/vnd.wap.rollover-certificate" },
+ { 0x201, "application/vnd.uplanet.cachop-wbxml" },
+ { 0x202, "application/vnd.uplanet.signal" },
+ { 0x203, "application/vnd.uplanet.alert-wbxml" },
+ { 0x204, "application/vnd.uplanet.list-wbxml" },
+ { 0x205, "application/vnd.uplanet.listcmd-wbxml" },
+ { 0x206, "application/vnd.uplanet.channel-wbxml" },
+ { 0x207, "application/vnd.uplanet.provisioning-status-uri" },
+ { 0x208, "x-wap.multipart/vnd.uplanet.header-set" },
+ { 0x209, "application/vnd.uplanet.bearer-choice-wbxml" },
+ { 0x20A, "application/vnd.phonecom.mmc-wbxml" },
+ { 0x20B, "application/vnd.nokia.syncset+wbxml" },
{ 0x00, NULL }
};
{ 0x1E, "Persian (fa)" },
{ 0x1F, "Finnish (fi)" },
{ 0x20, "Fiji (fj)" },
+ { 0x21, "Urdu (ur)" },
{ 0x22, "French (fr)" },
+ { 0x23, "Uzbek (uz)" },
{ 0x24, "Irish (ga)" },
{ 0x25, "Scots Gaelic (gd)" },
{ 0x26, "Galician (gl)" },
{ 0x2C, "Croatian (hr)" },
{ 0x2D, "Hungarian (hu)" },
{ 0x2E, "Armenian (hy)" },
+ { 0x2F, "Vietnamese (vi)" },
{ 0x30, "Indonesian (formerly in) (id)" },
+ { 0x31, "Wolof (wo)" },
+ { 0x32, "Xhosa (xh)" },
+ { 0x33, "Icelandic (is)" },
+ { 0x34, "Italian (it)" },
+ { 0x35, "Yoruba (yo)" },
+ { 0x36, "Japanese (ja)" },
+ { 0x37, "Javanese (jw)" },
+ { 0x38, "Georgian (ka)" },
+ { 0x39, "Kazakh (kk)" },
+ { 0x3A, "Zhuang (za)" },
+ { 0x3B, "Cambodian (km)" },
+ { 0x3C, "Kannada (kn)" },
+ { 0x3D, "Korean (ko)" },
+ { 0x3E, "Kashmiri (ks)" },
+ { 0x3F, "Kurdish (ku)" },
+ { 0x40, "Kirghiz (ky)" },
+ { 0x41, "Chinese (zh)" },
+ { 0x42, "Lingala (ln)" },
+ { 0x43, "Laothian (lo)" },
+ { 0x44, "Lithuanian (lt)" },
+ { 0x45, "Latvian, Lettish (lv)" },
+ { 0x46, "Malagasy (mg)" },
{ 0x47, "Maori (mi)" },
{ 0x48, "Macedonian (mk)" },
{ 0x49, "Malayalam (ml)" },
{ 0x4D, "Malay (ms)" },
{ 0x4E, "Maltese (mt)" },
{ 0x4F, "Burmese (my)" },
+ { 0x50, "Ukrainian (uk)" },
{ 0x51, "Nepali (ne)" },
{ 0x52, "Dutch (nl)" },
{ 0x53, "Norwegian (no)" },
{ 0x59, "Pashto, Pushto (ps)" },
{ 0x5A, "Portuguese (pt)" },
{ 0x5B, "Quechua (qu)" },
+ { 0x5C, "Zulu (zu)" },
{ 0x5D, "Kirundi (rn)" },
{ 0x5E, "Romanian (ro)" },
{ 0x5F, "Russian (ru)" },
{ 0x74, "Tajik (tg)" },
{ 0x75, "Thai (th)" },
{ 0x76, "Tigrinya (ti)" },
+ { 0x77, "Turkmen (tk)" },
+ { 0x78, "Tagalog (tl)" },
+ { 0x79, "Setswana (tn)" },
+ { 0x7A, "Tonga (to)" },
+ { 0x7B, "Turkish (tr)" },
+ { 0x7C, "Tsonga (ts)" },
+ { 0x7D, "Tatar (tt)" },
+ { 0x7E, "Twi (tw)" },
+ { 0x7F, "Uighur (ug)" },
{ 0x81, "Nauru (na)" },
{ 0x82, "Faeroese (fo)" },
{ 0x83, "Frisian (fy)" },
{ 0x84, "Interlingua (ia)" },
+ { 0x85, "Volapuk (vo)" },
+ { 0x86, "Interlingue (ie)" },
+ { 0x87, "Inupiak (ik)" },
+ { 0x88, "Yiddish (formerly ji) (yi)" },
+ { 0x89, "Inuktitut (iu)" },
+ { 0x8A, "Greenlandic (kl)" },
+ { 0x8B, "Latin (la)" },
{ 0x8C, "Rhaeto-Romance (rm)" },
{ 0x00, NULL }
};
{ 0x00, NULL }
};
+static const value_string vals_connection[] = {
+ { 0x00, "Close" },
+ { 0x00, NULL }
+};
+
static const value_string vals_transfer_encoding[] = {
{ 0x00, "Chunked" },
{ 0x00, NULL }
enum {
RESERVED = 0x00,
CONNECT = 0x01,
- CONNECTREPLY = 0x02,
+ CONNECTREPLY = 0x02,
REDIRECT = 0x03, /* No sample data */
REPLY = 0x04,
DISCONNECT = 0x05,
PUSH = 0x06, /* No sample data */
- CONFIRMEDPUSH = 0x07, /* No sample data */
+ CONFIRMEDPUSH = 0x07, /* No sample data */
SUSPEND = 0x08, /* No sample data */
RESUME = 0x09, /* No sample data */
- GET = 0x40,
+ GET = 0x40,
OPTIONS = 0x41, /* No sample data */
HEAD = 0x42, /* No sample data */
DELETE = 0x43, /* No sample data */
TRACE = 0x44, /* No sample data */
POST = 0x60,
- PUT = 0x61, /* No sample data */
+ PUT = 0x61, /* No sample data */
};
typedef enum {
VALUE_IN_LEN,
} value_type_t;
-static void add_uri (proto_tree *, tvbuff_t *, guint, guint);
+static dissector_table_t wsp_dissector_table;
+static heur_dissector_list_t heur_subdissector_list;
+
+static void add_uri (proto_tree *, packet_info *, tvbuff_t *, guint, guint);
static void add_headers (proto_tree *, tvbuff_t *);
static int add_well_known_header (proto_tree *, tvbuff_t *, int, guint8);
static int add_unknown_header (proto_tree *, tvbuff_t *, int, guint8);
static void add_cache_control_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int);
static int add_cache_control_field_name (proto_tree *, tvbuff_t *, int, guint);
+static void add_connection_header (proto_tree *, tvbuff_t *, int,
+ tvbuff_t *, value_type_t, int);
static void add_content_type_value (proto_tree *, tvbuff_t *, int, int,
tvbuff_t *, value_type_t, int, int, int, guint *, const char **);
-static guint add_content_type (proto_tree *, tvbuff_t *, guint, guint *,
- const char **);
+static void add_wap_application_id_header (proto_tree *, tvbuff_t *, int,
+ tvbuff_t *, value_type_t, int);
+static void add_integer_value_header_common (proto_tree *, tvbuff_t *, int,
+ tvbuff_t *, value_type_t, int, int, guint8, const value_string *);
static void add_integer_value_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int, int, guint8);
+static void add_string_value_header_common (proto_tree *, tvbuff_t *, int,
+ tvbuff_t *, value_type_t, int, int, guint8, const value_string *);
static void add_string_value_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int, int, guint8);
+static void add_quoted_string_value_header (proto_tree *, tvbuff_t *, int,
+ tvbuff_t *, value_type_t, int, int, guint8);
static void add_date_value_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int, int, guint8);
static int add_parameter (proto_tree *, tvbuff_t *, int);
-static void add_untyped_parameter (proto_tree *, tvbuff_t *, int, int);
-static void add_parameter_charset (proto_tree *, tvbuff_t *, int, int);
-static void add_parameter_type (proto_tree *, tvbuff_t *, int, int);
-static void add_parameter_text (proto_tree *, tvbuff_t *, int, int, int,
- const char *paramName);
+static int add_untyped_parameter (proto_tree *, tvbuff_t *, int, int);
+static int add_parameter_charset (proto_tree *, tvbuff_t *, int, int);
+static int add_constrained_encoding (proto_tree *, tvbuff_t *, int, int);
+static int add_parameter_type (proto_tree *, tvbuff_t *, int, int);
+static int add_parameter_text (proto_tree *, tvbuff_t *, int, int, int, const char *);
static void add_post_data (proto_tree *, tvbuff_t *, guint, const char *);
static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
static void add_pragma_header (proto_tree *, tvbuff_t *, int, tvbuff_t *,
static void add_accept_application_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int);
static void add_capabilities (proto_tree *tree, tvbuff_t *tvb, int type);
+static void add_capability_vals(tvbuff_t *, gboolean, int, guint, guint, char *, size_t);
static value_type_t get_value_type_len (tvbuff_t *, int, guint *, int *, int *);
static guint get_uintvar (tvbuff_t *, guint, guint);
static gint get_integer (tvbuff_t *, guint, guint, value_type_t, guint *);
+static int add_well_known_openwave_header (proto_tree *, tvbuff_t *, int, guint8);
+static void add_openwave_integer_value_header (proto_tree *, tvbuff_t *, int,
+ tvbuff_t *, value_type_t, int, int, guint8);
+static void add_openwave_string_value_header (proto_tree *, tvbuff_t *, int,
+ tvbuff_t *, value_type_t, int, int, guint8);
+
+
/* Code to actually dissect the packets */
static void
dissect_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, dissector_t dissector)
+ proto_tree *tree, dissector_handle_t dissector_handle)
{
guint8 flags;
proto_item *ti;
PT_UDP, port_num, 0, NO_PORT_B);
if (conv == NULL) {
conv = conversation_new(&redir_address,
- &pinfo->dst, PT_UDP, port_num, 0,
- NULL, NO_PORT2);
+ &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
}
- conversation_set_dissector(conv, dissector);
+ conversation_set_dissector(conv, dissector_handle);
break;
case BT_IPv6:
PT_UDP, port_num, 0, NO_PORT_B);
if (conv == NULL) {
conv = conversation_new(&redir_address,
- &pinfo->dst, PT_UDP, port_num, 0,
- NULL, NO_PORT2);
+ &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
}
- conversation_set_dissector(conv, dissector);
+ conversation_set_dissector(conv, dissector_handle);
break;
unknown_address_type:
static void
dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- dissector_t dissector, gboolean is_connectionless)
+ dissector_handle_t dissector_handle, gboolean is_connectionless)
{
- frame_data *fdata = pinfo->fd;
int offset = 0;
guint8 pdut;
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. */
- /* 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 (is_connectionless)
{
pdut = tvb_get_guint8 (tvb, offset);
/* Develop the string to put in the Info column */
- if (check_col(fdata, COL_INFO))
+ if (check_col(pinfo->cinfo, COL_INFO))
{
- col_add_fstr(fdata, COL_INFO, "WSP %s",
+ col_append_fstr(pinfo->cinfo, 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
necessary to generate protocol tree items. */
if (tree) {
- ti = proto_tree_add_item(tree, proto_wsp, tvb, 0,
- tvb_length(tvb), bo_little_endian);
+ ti = proto_tree_add_item(tree, proto_wsp, tvb, 0, -1,
+ bo_little_endian);
wsp_tree = proto_item_add_subtree(ti, ett_wsp);
/* Code to process the packet goes here */
switch (pdut)
{
case CONNECT:
+ case CONNECTREPLY:
+ case RESUME:
if (tree) {
- ti = proto_tree_add_item (wsp_tree, hf_wsp_version_major,tvb,offset,1,bo_little_endian);
- 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);
- if (capabilityLength > 0)
- {
- tmp_tvb = tvb_new_subset (tvb, offset, capabilityLength, capabilityLength);
- add_capabilities (wsp_tree, tmp_tvb, CONNECT);
- offset += capabilityLength;
- }
-
- if (headerLength > 0)
+ if (pdut == CONNECT)
{
- tmp_tvb = tvb_new_subset (tvb, offset, headerLength, headerLength);
- add_headers (wsp_tree, tmp_tvb);
+ ti = proto_tree_add_item (wsp_tree, hf_wsp_version_major,tvb,offset,1,bo_little_endian);
+ ti = proto_tree_add_item (wsp_tree, hf_wsp_version_minor,tvb,offset,1,bo_little_endian);
+ offset++;
+ } else {
+ 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;
}
- }
-
- break;
-
- case CONNECTREPLY:
- if (tree) {
- 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_uint (wsp_tree, hf_wsp_header_length,tvb,headerStart,count,headerLength);
+ if (pdut != RESUME)
+ {
+ count = 0; /* Initialise count */
+ headerLength = tvb_get_guintvar (tvb, offset, &count);
+ ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,offset,count,headerLength);
+ offset += count;
+ capabilityStart = offset;
+ headerStart = capabilityStart + capabilityLength;
+ } else {
+ /* Resume computes the headerlength by remaining bytes */
+ capabilityStart = offset;
+ headerStart = capabilityStart + capabilityLength;
+ headerLength = tvb_reported_length_remaining (tvb, headerStart);
+ }
if (capabilityLength > 0)
{
tmp_tvb = tvb_new_subset (tvb, offset, capabilityLength, capabilityLength);
- add_capabilities (wsp_tree, tmp_tvb, CONNECTREPLY);
+ add_capabilities (wsp_tree, tmp_tvb, pdut);
offset += capabilityLength;
}
if (headerLength > 0)
{
-
- /*
- ti = proto_tree_add_item (wsp_tree, hf_wsp_headers_section,tvb,offset,headerLength,bo_little_endian);
- wsp_headers = proto_item_add_subtree( ti, ett_headers );
- */
tmp_tvb = tvb_new_subset (tvb, offset, headerLength, headerLength);
add_headers (wsp_tree, tmp_tvb);
}
case REDIRECT:
dissect_redirect(tvb, offset, pinfo, wsp_tree,
- dissector);
+ dissector_handle);
break;
case DISCONNECT:
+ case SUSPEND:
if (tree) {
count = 0; /* Initialise count */
value = tvb_get_guintvar (tvb, offset, &count);
break;
case GET:
- if (tree) {
- count = 0; /* Initialise count */
+ 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);
+ value = tvb_get_guintvar (tvb, offset, &count);
+ nextOffset = offset + count;
+ add_uri (wsp_tree, pinfo, tvb, offset, nextOffset);
+ if (tree) {
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;
+
+ add_uri (wsp_tree, pinfo, tvb, uriStart, offset);
if (tree) {
- 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;
-
- add_uri (wsp_tree, tvb, uriStart, offset);
offset += uriLength;
ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,headerStart,count,headersLength);
add_post_data (wsp_tree, tmp_tvb,
contentType, contentTypeStr);
}
+ if (tvb_reported_length_remaining(tvb, headerStart + count + uriLength + headersLength) > 0)
+ {
+ tmp_tvb = tvb_new_subset (tvb, headerStart + count + uriLength + headersLength, -1, -1);
+ if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
+ dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
+ }
break;
case REPLY:
+ count = 0; /* Initialise count */
+ headersLength = tvb_get_guintvar (tvb, offset+1, &count);
+ headerStart = offset + count + 1;
if (tree) {
ti = proto_tree_add_item (wsp_tree, hf_wsp_header_status,tvb,offset,1,bo_little_endian);
- count = 0; /* Initialise count */
- headersLength = tvb_get_guintvar (tvb, offset+1, &count);
nextOffset = offset + 1 + count;
ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,offset+1,count,headersLength);
tmp_tvb = tvb_new_subset (tvb, nextOffset, headerLength, headerLength);
add_headers (wsp_tree, tmp_tvb);
}
- offset += count+headerLength+1;
+ offset += count+headersLength+1;
/* TODO: Data - decode WMLC */
/* Runs from offset+1+count+headerLength+1 to end of frame */
- if (offset < tvb_reported_length (tvb))
+ if (tvb_reported_length_remaining (tvb, offset) > 0)
+ {
+ ti = proto_tree_add_item (wsp_tree, hf_wsp_reply_data,tvb,offset,-1,bo_little_endian);
+ }
+ }
+ if (tvb_reported_length_remaining(tvb, headerStart + headersLength) > 0)
+ {
+ tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength, -1, -1);
+ if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
+ dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
+ }
+ break;
+
+ case PUSH:
+ case CONFIRMEDPUSH:
+ count = 0; /* Initialise count */
+ headersLength = tvb_get_guintvar (tvb, offset, &count);
+ headerStart = offset + count;
+
+ if (tree) {
+ ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,offset,count,headersLength);
+
+ if (headersLength == 0)
+ break;
+
+ offset += count;
+ contentTypeStart = offset;
+ nextOffset = add_content_type (wsp_tree,
+ tvb, offset, &contentType,
+ &contentTypeStr);
+
+ /* Add headers subtree that will hold the headers fields */
+ /* Runs from nextOffset for headersLength-(length of content-type field)*/
+ headerLength = headersLength-(nextOffset-contentTypeStart);
+ if (headerLength > 0)
+ {
+ tmp_tvb = tvb_new_subset (tvb, nextOffset, headerLength, headerLength);
+ add_headers (wsp_tree, tmp_tvb);
+ }
+ offset += headersLength;
+
+ /* Push DATA */
+ if (tvb_reported_length_remaining (tvb, offset) > 0)
{
- ti = proto_tree_add_item (wsp_tree, hf_wsp_reply_data,tvb,offset,tvb_length_remaining(tvb, offset),bo_little_endian);
+ ti = proto_tree_add_item (wsp_tree, hf_wsp_push_data,tvb,offset,-1,bo_little_endian);
}
}
+ if (tvb_reported_length_remaining(tvb, headerStart + headersLength) > 0)
+ {
+ tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength, -1, -1);
+ if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
+ dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
+ }
break;
+
}
}
static void
dissect_wsp_fromudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- if (check_col(pinfo->fd, COL_PROTOCOL))
- col_set_str(pinfo->fd, COL_PROTOCOL, "WSP" );
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSP" );
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
- dissect_wsp_common(tvb, pinfo, tree, dissect_wsp_fromudp, TRUE);
+ dissect_wsp_common(tvb, pinfo, tree, wsp_fromudp_handle, TRUE);
}
/*
/*
* XXX - what about WTLS->WTP->WSP?
*/
- dissect_wsp_common(tvb, pinfo, tree, dissect_wtp_fromudp, FALSE);
+ dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, FALSE);
}
/*
/*
* XXX - what about WTLS->WSP?
*/
- dissect_wsp_common(tvb, pinfo, tree, dissect_wtp_fromudp, TRUE);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_clear(pinfo->cinfo, COL_INFO);
+ }
+ dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, TRUE);
}
static void
-add_uri (proto_tree *tree, tvbuff_t *tvb, guint URILenOffset, guint URIOffset)
+add_uri (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint URILenOffset, guint URIOffset)
{
proto_item *ti;
- guint8 terminator = 0;
char *newBuffer;
guint count = 0;
guint uriLen = tvb_get_guintvar (tvb, URILenOffset, &count);
- ti = proto_tree_add_uint (tree, hf_wsp_header_uri_len,tvb,URILenOffset,count,uriLen);
-
- /* If string doesn't end with a 0x00, we need to add one to be on the safe side */
- terminator = tvb_get_guint8 (tvb, URIOffset+uriLen-1);
- if (terminator != 0)
- {
- newBuffer = g_malloc (uriLen+1);
- strncpy (newBuffer, tvb_get_ptr (tvb, URIOffset, uriLen), uriLen);
- newBuffer[uriLen] = 0;
- ti = proto_tree_add_string (tree, hf_wsp_header_uri,tvb,URIOffset,uriLen,newBuffer);
- g_free (newBuffer);
- }
- else
- {
- ti = proto_tree_add_item (tree, hf_wsp_header_uri,tvb,URIOffset,uriLen,bo_little_endian);
- }
+ if (tree)
+ ti = proto_tree_add_uint (tree, hf_wsp_header_uri_len,tvb,URILenOffset,count,uriLen);
+
+ newBuffer = g_malloc (uriLen+2);
+ newBuffer[0] = ' '; /* This is for COL_INFO */
+ strncpy (newBuffer+1, tvb_get_ptr (tvb, URIOffset, uriLen), uriLen);
+ newBuffer[uriLen+1] = 0;
+ if (tree)
+ ti = proto_tree_add_string (tree, hf_wsp_header_uri,tvb,URIOffset,uriLen,newBuffer+1);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_str(pinfo->cinfo, COL_INFO, newBuffer);
+ };
+ g_free (newBuffer);
}
static void
proto_tree *wsp_headers;
guint offset = 0;
guint headersLen = tvb_reported_length (tvb);
- guint8 headerStart = 0;
+ guint headerStart = 0;
guint peek = 0;
guint pageCode = 1;
* Well-known-header; the lower 7 bits of "peek"
* are the header code.
*/
- if (pageCode == 1)
- {
+ switch (pageCode) {
+ case 1:
offset = add_well_known_header (wsp_headers,
tvb, headerStart, peek & 0x7F);
- }
- else
- {
+ break;
+
+ case 2:
+ case 16:
+ offset = add_well_known_openwave_header (wsp_headers,
+ tvb, headerStart, peek & 0x7F);
+ break;
+
+ default:
offset = add_unknown_header (wsp_headers,
tvb, headerStart, peek & 0x7F);
+ break;
}
}
}
break;
case FN_CACHE_CONTROL_DEP: /* Cache-Control */
+ case FN_CACHE_CONTROL:
+ case FN_CACHE_CONTROL14:
/*
- * XXX - should both encoding versions 1.1 and
- * 1.3 be handled this way?
+ * XXX - is the only difference in the three different
+ * versions (1.1, 1.3, 1.4) really only S_MAXAGE?
*/
add_cache_control_header (tree, header_buff, headerLen,
value_buff, valueType, valueLen);
break;
+ case FN_CONNECTION: /* Connection */
+ add_connection_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen);
+ break;
+
case FN_CONTENT_LENGTH: /* Content-Length */
add_integer_value_header (tree, header_buff, headerLen,
value_buff, valueType, valueLen,
hf_wsp_header_profile, headerType);
break;
+ case FN_X_WAP_APPLICATION_ID: /* X-Wap-Application-Id */
+ add_wap_application_id_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen);
+ break;
+
+ case FN_CONTENT_ID: /* Content-ID */
+ add_quoted_string_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_content_ID, headerType);
+ break;
+
default:
proto_tree_add_text (tree, header_buff, 0, headerLen,
"Unsupported Header: %s",
return offset;
}
+
static int
-add_unknown_header (proto_tree *tree, tvbuff_t *tvb, int offset,
+add_well_known_openwave_header (proto_tree *tree, tvbuff_t *tvb, int offset,
guint8 headerType)
{
int headerStart;
- int valueStart;
value_type_t valueType;
int headerLen;
guint valueLen;
- int valueOffset;
+ int valueStart;
+ tvbuff_t *header_buff;
+ tvbuff_t *value_buff;
+#ifdef DEBUG
+ fprintf (stderr, "dissect_wsp: Got Openwave header 0x%02x\n", headerType);
+#endif
headerStart = offset;
/*
*/
offset++;
- valueStart = offset;
-
/*
* Get the value type and length (or, if the type is VALUE_IN_LEN,
* meaning the value is a Short-integer, get the value type
* and the value itself).
*/
- valueType = get_value_type_len (tvb, valueStart, &valueLen,
- &valueOffset, &offset);
+ valueType = get_value_type_len (tvb, offset, &valueLen,
+ &valueStart, &offset);
headerLen = offset - headerStart;
- proto_tree_add_text (tree, tvb, headerStart, headerLen,
- "Unsupported Header (0x%02X)", headerType);
- return offset;
-}
-
-static int
-add_application_header (proto_tree *tree, tvbuff_t *tvb, int offset)
-{
- int startOffset;
- guint tokenSize;
- const guint8 *token;
- value_type_t valueType;
- int subvalueLen;
- int subvalueOffset;
- guint secs;
- struct timeval timeValue;
- int asvOffset;
- guint stringSize;
-
- startOffset = offset;
- tokenSize = tvb_strsize (tvb, startOffset);
- token = tvb_get_ptr (tvb, startOffset, tokenSize);
- offset += tokenSize;
+ /*
+ * Get a tvbuff for the entire header.
+ * XXX - cut the actual length short so that it doesn't run
+ * past the actual length of tvb.
+ */
+ header_buff = tvb_new_subset (tvb, headerStart, headerLen,
+ headerLen);
/*
- * Special case header "X-WAP.TOD" that is sometimes followed
- * by a 4-byte date value.
- *
- * XXX - according to the 4-May-2000 WSP spec, X-Wap-Tod is
- * encoded as a well known header, with a code of 0x3F.
+ * If the value wasn't in the length, get a tvbuff for the value.
+ * XXX - can valueLen be 0?
+ * XXX - cut the actual length short so that it doesn't run
+ * past the actual length of tvb.
*/
- if (tokenSize == 10 && strncasecmp ("x-wap.tod", token, 9) == 0)
- {
- valueType = get_value_type_len (tvb, offset,
- &subvalueLen, &subvalueOffset, &offset);
- if (get_integer (tvb, subvalueOffset, subvalueLen,
- valueType, &secs) == 0)
- {
- /*
- * Fill in the "struct timeval", and add it to the
- * protocol tree.
- * Note: this will succeed even if it's a Short-integer.
- * A Short-integer would work, but, as the time values
- * are UNIX seconds-since-the-Epoch value, and as
- * there weren't WAP phones or Web servers back in
- * late 1969/early 1970, they're unlikely to be used.
- */
- timeValue.tv_sec = secs;
- timeValue.tv_usec = 0;
- proto_tree_add_time (tree, hf_wsp_header_x_wap_tod,
- tvb, startOffset, offset - startOffset, &timeValue);
- }
- else
- {
- proto_tree_add_text (tree, tvb, startOffset,
- offset - startOffset,
- "%s: invalid date value", token);
- }
- }
- else
- {
- asvOffset = offset;
- stringSize = tvb_strsize (tvb, asvOffset);
- offset += stringSize;
- proto_tree_add_text (tree, tvb, startOffset,
- offset - startOffset,
- "%s: %s", token,
- tvb_get_ptr (tvb, asvOffset, stringSize));
+ if (valueType != VALUE_IN_LEN) {
+ value_buff = tvb_new_subset (tvb, valueStart, valueLen,
+ valueLen);
+ } else {
+ /*
+ * XXX - when the last dissector is tvbuffified,
+ * so that NULL is no longer a valid tvb pointer
+ * value in "proto_tree_add" calls, just
+ * set "value_buff" to NULL.
+ *
+ * XXX - can we already do that? I.e., will that
+ * cause us always to crash if we mistakenly try
+ * to fetch the value of a VALUE_IN_LEN item?
+ */
+ value_buff = tvb_new_subset (tvb, headerStart, 0, 0);
}
- return offset;
-}
-static void
-add_accept_header (proto_tree *tree, tvbuff_t *header_buff,
- int headerLen, tvbuff_t *value_buff, value_type_t valueType,
- int valueLen)
-{
- guint contentType;
- const char *contentTypeStr;
+ switch (headerType) {
- add_content_type_value (tree, header_buff, 0, headerLen, value_buff,
- valueType, valueLen, hf_wsp_header_accept,
- hf_wsp_header_accept_str, &contentType, &contentTypeStr);
-}
+/* case FN_OPENWAVE_PROXY_PUSH_ADDR: / x-up-proxy-push-addr */
+/* add_openwave_push_address_header (tree, header_buff, headerLen, */
+/* value_buff, valueType, valueLen); */
+/* break; */
-static void
-add_accept_xxx_header (proto_tree *tree, tvbuff_t *header_buff,
- int headerLen, tvbuff_t *value_buff, value_type_t valueType,
- int valueLen, int hf_numeric, int hf_string,
- const value_string *vals, const char *unknown_tag)
-{
- int offset = 0;
+ case FN_OPENWAVE_PROXY_PUSH_ACCEPT: /* x-up-proxy-push-accept */
+ add_accept_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen);
+ break;
+
+ case FN_OPENWAVE_PROXY_PUSH_SEQ: /* x-up-proxy-push-seq */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_push_seq,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_NOTIFY: /* x-up-proxy-notify */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_notify,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_OPERATOR_DOMAIN: /* x-up-proxy-operator-domain */
+ add_openwave_string_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_operator_domain, headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_HOME_PAGE: /* x-up-proxy-home-page */
+ add_openwave_string_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_home_page, headerType);
+ break;
+
+ case FN_OPENWAVE_DEVCAP_HAS_COLOR: /* x-up-devcap-has-color */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_has_color,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS: /* x-up-devcap-num-softkeys */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_num_softkeys,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE: /* x-up-devcap-softkey-size */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_softkey_size,
+ headerType);
+ break;
+
+/* case FN_OPENWAVE_DEVCAP_SCREEN_CHARS: / x-up-devcap-screen-chars */
+/* add_openwave_integer_value_header (tree, header_buff, headerLen, */
+/* value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_screen_chars, */
+/* headerType); */
+/* break; */
+
+/* case FN_OPENWAVE_DEVCAP_SCREEN_PIXELS: / x-up-devcap-screen-pixels */
+/* add_openwave_integer_value_header (tree, header_buff, headerLen, */
+/* value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_screen_pixels, */
+/* headerType); */
+/* break; */
+
+/* case FN_OPENWAVE_DEVCAP_EM_SIZE: / x-up-devcap-em-size */
+/* add_openwave_integer_value_header (tree, header_buff, headerLen, */
+/* value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_em_size, */
+/* headerType); */
+/* break; */
+
+ case FN_OPENWAVE_DEVCAP_SCREEN_DEPTH: /* x-up-devcap-screen-depth */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_screen_depth,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_DEVCAP_IMMED_ALERT: /* x-up-devcap-immed-alert */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_immed_alert,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_NET_ASK: /* x-up-proxy-net-ask */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_net_ask,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_UPLINK_VERSION: /* x-up-proxy-uplink-version */
+ add_openwave_string_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_uplink_version, headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_TOD: /* x-up-proxy-tod */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_tod, headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_BA_ENABLE: /* x-up-proxy-ba-enable */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_ba_enable, headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_BA_REALM: /* x-up-proxy-ba-realm */
+ add_openwave_string_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_ba_realm, headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_REDIRECT_ENABLE: /* x-up-proxy-redirect-enable */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_redirect_enable, headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_REQUEST_URI: /* x-up-proxy-request-uri */
+ add_openwave_string_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_request_uri, headerType);
+ break;
+
+/* case FN_OPENWAVE_PROXY_REDIRECT_STATUS: / x-up-proxy-redirect-status */
+/* add_openwave_integer_value_header (tree, header_buff, headerLen, */
+/* value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_redirect_status, */
+/* headerType); */
+/* break; */
+
+ case FN_OPENWAVE_PROXY_TRANS_CHARSET: /* x-up-proxy-trans-charset */
+ add_accept_xxx_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_trans_charset,
+ hf_wsp_header_openwave_proxy_trans_charset_str,
+ vals_character_sets, "Unknown charset (%u)");
+ break;
+
+ case FN_OPENWAVE_PROXY_LINGER: /* x-up-proxy-linger */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_linger,
+ headerType);
+ break;
+
+/* case FN_OPENWAVE_PROXY_CLIENT_ID: / x-up-proxy-client-id */
+/* add_openwave_string_value_header (tree, header_buff, headerLen, */
+/* value_buff, valueType, valueLen, */
+/* hf_wsp_header_openwave_proxy_client_id, headerType); */
+/* break; */
+
+ case FN_OPENWAVE_PROXY_ENABLE_TRUST: /* x-up-proxy-enable-trust */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_enable_trust,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_TRUST_OLD: /* x-up-proxy-trust old value */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_trust_old,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_TRUST: /* x-up-proxy-trust */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_trust,
+ headerType);
+ break;
+
+ case FN_OPENWAVE_PROXY_BOOKMARK: /* x-up-proxy-bookmark */
+ add_openwave_string_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen,
+ hf_wsp_header_openwave_proxy_bookmark, headerType);
+ break;
+
+ case FN_OPENWAVE_DEVCAP_GUI: /* x-up-devcap-gui */
+ add_openwave_integer_value_header (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_gui,
+ headerType);
+ break;
+
+ default:
+ proto_tree_add_text (tree, header_buff, 0, headerLen,
+ "Unsupported Openwave Header: %s",
+ val_to_str (headerType, vals_openwave_field_names, "Unknown (0x%02X)"));
+ break;
+ }
+ return offset;
+}
+
+static void
+add_openwave_push_address_header (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen)
+{
+
+/* ??? */
+
+}
+
+
+static int
+add_unknown_header (proto_tree *tree, tvbuff_t *tvb, int offset,
+ guint8 headerType)
+{
+ int headerStart;
+ int valueStart;
+ value_type_t valueType;
+ int headerLen;
+ guint valueLen;
+ int valueOffset;
+
+ headerStart = offset;
+
+ /*
+ * Skip the Short-Integer header type.
+ */
+ offset++;
+
+ valueStart = offset;
+
+ /*
+ * Get the value type and length (or, if the type is VALUE_IN_LEN,
+ * meaning the value is a Short-integer, get the value type
+ * and the value itself).
+ */
+ valueType = get_value_type_len (tvb, valueStart, &valueLen,
+ &valueOffset, &offset);
+ headerLen = offset - headerStart;
+
+ proto_tree_add_text (tree, tvb, headerStart, headerLen,
+ "Unsupported Header (0x%02X)", headerType);
+ return offset;
+}
+
+static int
+add_application_header (proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ int startOffset;
+ guint tokenSize;
+ const guint8 *token;
+ value_type_t valueType;
+ int subvalueLen;
+ int subvalueOffset;
+ guint secs;
+ nstime_t timeValue;
+ int asvOffset;
+ guint stringSize;
+
+ startOffset = offset;
+ tokenSize = tvb_strsize (tvb, startOffset);
+ token = tvb_get_ptr (tvb, startOffset, tokenSize);
+ offset += tokenSize;
+
+ /*
+ * Special case header "X-WAP.TOD" that is sometimes followed
+ * by a 4-byte date value.
+ *
+ * XXX - according to the 4-May-2000 WSP spec, X-Wap-Tod is
+ * encoded as a well known header, with a code of 0x3F.
+ */
+ if (tokenSize == 10 && strncasecmp ("x-wap.tod", token, 9) == 0)
+ {
+ valueType = get_value_type_len (tvb, offset,
+ &subvalueLen, &subvalueOffset, &offset);
+ if (get_integer (tvb, subvalueOffset, subvalueLen,
+ valueType, &secs) == 0)
+ {
+ /*
+ * Fill in the "struct timeval", and add it to the
+ * protocol tree.
+ * Note: this will succeed even if it's a Short-integer.
+ * A Short-integer would work, but, as the time values
+ * are UNIX seconds-since-the-Epoch value, and as
+ * there weren't WAP phones or Web servers back in
+ * late 1969/early 1970, they're unlikely to be used.
+ */
+ timeValue.secs = secs;
+ timeValue.nsecs = 0;
+ proto_tree_add_time (tree, hf_wsp_header_x_wap_tod,
+ tvb, startOffset, offset - startOffset, &timeValue);
+ }
+ else
+ {
+ proto_tree_add_text (tree, tvb, startOffset,
+ offset - startOffset,
+ "%s: invalid date value", token);
+ }
+ }
+ else
+ {
+ asvOffset = offset;
+ stringSize = tvb_strsize (tvb, asvOffset);
+ offset += stringSize;
+ proto_tree_add_text (tree, tvb, startOffset,
+ offset - startOffset,
+ "%s: %s", token,
+ tvb_get_ptr (tvb, asvOffset, stringSize));
+ }
+ return offset;
+}
+
+static void
+add_accept_header (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen)
+{
+ guint contentType;
+ const char *contentTypeStr;
+
+ add_content_type_value (tree, header_buff, 0, headerLen, value_buff,
+ valueType, valueLen, hf_wsp_header_accept,
+ hf_wsp_header_accept_str, &contentType, &contentTypeStr);
+}
+
+static void
+add_accept_xxx_header (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen, int hf_numeric, int hf_string,
+ const value_string *vals, const char *unknown_tag)
+{
+ int offset = 0;
int subvalueLen;
int subvalueOffset;
guint value = 0;
int headerLen, tvbuff_t *value_buff, value_type_t valueType,
int valueLen)
{
- int offset;
+ int offset = 0;
int subvalueLen;
int subvalueOffset;
guint value;
case MAX_AGE:
case MAX_STALE:
case MIN_FRESH:
+ case S_MAXAGE:
/*
* Get Delta-second-value.
*/
return offset;
}
+static void
+add_connection_header (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen)
+{
+ int offset = 0;
+
+ if (valueType == VALUE_LEN_SUPPLIED)
+ {
+ /*
+ * Invalid.
+ */
+ proto_tree_add_text (tree, header_buff, 0, headerLen,
+ "Invalid Connection value");
+ return;
+ }
+ if (valueType == VALUE_IS_TEXT_STRING)
+ {
+ /*
+ * Token-text.
+ */
+ proto_tree_add_string (tree,
+ hf_wsp_header_connection_str,
+ header_buff, 0, headerLen,
+ tvb_get_ptr (value_buff, 0, valueLen));
+ return;
+ }
+
+ /*
+ * First byte had the 8th bit set.
+ */
+ if (valueLen == 0) {
+ /*
+ * Close.
+ */
+ proto_tree_add_uint (tree, hf_wsp_header_connection,
+ header_buff, offset, headerLen, valueLen);
+ return;
+ }
+
+ /*
+ * Invalid.
+ */
+ proto_tree_add_text (tree, header_buff, 0, headerLen,
+ "Invalid Connection value");
+}
+
static void
add_pragma_header (proto_tree *tree, tvbuff_t *header_buff,
int headerLen, tvbuff_t *value_buff, value_type_t valueType,
{
int offset = 0;
- if (valueType == VALUE_IN_LEN)
+ if (valueType == VALUE_LEN_SUPPLIED)
{
/*
* Invalid.
}
}
+static void
+add_wap_application_id_header (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen)
+{
+ if (valueType == VALUE_IN_LEN)
+ {
+ /*
+ * Must application-id (the 8th bit was stripped off).
+ */
+ proto_tree_add_uint (tree, hf_wsp_header_wap_application_id,
+ header_buff, 0, headerLen,
+ valueLen); /* valueLen is the value */
+ return;
+ }
+ if (valueType == VALUE_IS_TEXT_STRING)
+ {
+ /*
+ * Token-text.
+ */
+ proto_tree_add_string (tree, hf_wsp_header_wap_application_id_str,
+ header_buff, 0, headerLen,
+ tvb_get_ptr (value_buff, 0, valueLen));
+ return;
+ }
+
+ /*
+ * Not valid.
+ */
+ fprintf(stderr, "dissect_wsp: Suprising format of X-Wap-Application-Id\n");
+ return;
+}
+
static void
add_capabilities (proto_tree *tree, tvbuff_t *tvb, int type)
{
guint offset = 0;
guint offsetStr = 0;
guint capabilitiesLen = tvb_reported_length (tvb);
- guint8 capabilitiesStart = 0;
+ guint capabilitiesStart = 0;
guint peek = 0;
guint length = 0;
guint value = 0;
guint i;
+ int ret;
char valString[200];
#ifdef DEBUG
valString[0]=0;
if (value & 0x80)
{
- i += snprintf(valString+i,200-1,"%s","(Confirmed push facility) ");
+ ret = snprintf(valString+i,200-i,"%s","(Confirmed push facility) ");
+ if (ret == -1) {
+ /*
+ * Some versions of snprintf
+ * return -1 if they'd
+ * truncate the output.
+ */
+ goto add_string;
+ }
+ i += ret;
}
if (value & 0x40)
{
- i += snprintf(valString+i,200-1,"%s","(Push facility) ");
+ if (i >= 200) {
+ /* No more room. */
+ goto add_string;
+ }
+ ret = snprintf(valString+i,200-i,"%s","(Push facility) ");
+ if (ret == -1) {
+ /*
+ * Some versions of snprintf
+ * return -1 if they'd
+ * truncate the output.
+ */
+ goto add_string;
+ }
+ i += ret;
}
if (value & 0x20)
{
- i += snprintf(valString+i,200-1,"%s","(Session resume facility) ");
+ if (i >= 200) {
+ /* No more room. */
+ goto add_string;
+ }
+ ret = snprintf(valString+i,200-i,"%s","(Session resume facility) ");
+ if (ret == -1) {
+ /*
+ * Some versions of snprintf
+ * return -1 if they'd
+ * truncate the output.
+ */
+ goto add_string;
+ }
+ i += ret;
}
if (value & 0x10)
{
- i += snprintf(valString+i,200-1,"%s","(Acknowledgement headers) ");
+ if (i >= 200) {
+ /* No more room. */
+ goto add_string;
+ }
+ ret = snprintf(valString+i,200-i,"%s","(Acknowledgement headers) ");
+ if (ret == -1) {
+ /*
+ * Some versions of snprintf
+ * return -1 if they'd
+ * truncate the output.
+ */
+ goto add_string;
+ }
+ i += ret;
}
+ add_string:
proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_protocol_opt, tvb, capabilitiesStart, length+1, valString);
break;
case 0x03 : /* Method-MOR */
case 0x05 : /* Extended Methods */
offsetStr = offset;
offset++;
- if (type == CONNECT)
- {
- i = 0;
- while ((offsetStr-capabilitiesStart) <= length)
- {
- value = tvb_get_guint8(tvb, offsetStr);
- i += snprintf(valString+i,200-i,"(%d - ",value);
- offsetStr++;
- for (;(valString[i] = tvb_get_guint8(tvb, offsetStr));i++,offsetStr++);
- offsetStr++;
- valString[i++] = ')';
- valString[i++] = ' ';
- }
- valString[i]=0;
- }
- else
- {
- i = 0;
- while ((offsetStr-capabilitiesStart) <= length)
- {
- value = tvb_get_guint8(tvb, offsetStr);
- i += snprintf(valString+i,200-i,"(%d) ",value);
- offsetStr++;
- }
- valString[i]=0;
- }
+ add_capability_vals(tvb, (type == CONNECT),
+ offsetStr, length, capabilitiesStart,
+ valString, sizeof valString);
proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_extended_methods, tvb, capabilitiesStart, length+1, valString);
break;
case 0x06 : /* Header Code Pages */
offsetStr = offset;
offset++;
- i = 0;
- while ((offsetStr-capabilitiesStart) <= length)
- {
- value = tvb_get_guint8(tvb, offsetStr);
- i += snprintf(valString+i,200-i,"(%d - ",value);
- offsetStr++;
- for (;(valString[i] = tvb_get_guint8(tvb, offsetStr));i++,offsetStr++);
- offsetStr++;
- valString[i++] = ')';
- valString[i++] = ' ';
- }
- valString[i]=0;
+ add_capability_vals(tvb, (type == CONNECT),
+ offsetStr, length, capabilitiesStart,
+ valString, sizeof valString);
proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_header_code_pages, tvb, capabilitiesStart, length+1, valString);
break;
case 0x07 : /* Aliases */
"Unsupported Header (0x%02X)", peek & 0x7F);
break;
}
- offset=capabilitiesStart+length+1;
+ offset=capabilitiesStart+length+1;
+ }
+}
+
+static void
+add_capability_vals(tvbuff_t *tvb, gboolean add_string, int offsetStr,
+ guint length, guint capabilitiesStart, char *valString,
+ size_t valStringSize)
+{
+ guint i;
+ int ret;
+ guint value;
+ guint8 c;
+
+ i = 0;
+ while ((offsetStr-capabilitiesStart) <= length)
+ {
+ value = tvb_get_guint8(tvb, offsetStr);
+ if (i >= valStringSize) {
+ /* No more room. */
+ break;
+ }
+ if (add_string)
+ {
+ ret = snprintf(valString+i,valStringSize-i,
+ "(%d - ",value);
+ }
+ else
+ {
+ ret = snprintf(valString+i,valStringSize-i,"(%d) ",
+ value);
+ }
+ if (ret == -1) {
+ /*
+ * Some versions of snprintf return -1
+ * if they'd truncate the output.
+ */
+ break;
+ }
+ i += ret;
+ offsetStr++;
+ if (add_string)
+ {
+ for (;(c = tvb_get_guint8(tvb, offsetStr))
+ && i < valStringSize - 1; i++,offsetStr++)
+ valString[i] = c;
+ offsetStr++;
+ if (i < valStringSize - 2) {
+ valString[i++] = ')';
+ valString[i++] = ' ';
+ }
+ }
}
+ valString[i] = '\0';
}
static value_type_t
guint8 peek;
guint32 len;
guint count;
- int stringlen;
/* Get value part of header */
peek = tvb_get_guint8 (tvb, offset);
offset = add_parameter (parameter_tree, value_buff, offset);
}
-static guint
+guint
add_content_type (proto_tree *tree, tvbuff_t *tvb, guint offset,
guint *contentTypep, const char **contentTypeStrp)
{
add_integer_value_header (proto_tree *tree, tvbuff_t *header_buff,
int headerLen, tvbuff_t *value_buff, value_type_t valueType,
int valueLen, int hf_numeric, guint8 headerType)
+{
+ add_integer_value_header_common (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_numeric, headerType,
+ vals_field_names);
+}
+
+static void
+add_openwave_integer_value_header (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen, int hf_numeric, guint8 headerType)
+{
+ add_integer_value_header_common (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_numeric, headerType,
+ vals_openwave_field_names);
+}
+
+static void
+add_integer_value_header_common (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen, int hf_numeric, guint8 headerType,
+ const value_string *vals)
{
guint value;
{
proto_tree_add_text (tree, header_buff, 0, headerLen,
"Invalid %s integer value",
- match_strval (headerType, vals_field_names));
+ match_strval (headerType, vals));
}
else
{
add_string_value_header (proto_tree *tree, tvbuff_t *header_buff,
int headerLen, tvbuff_t *value_buff, value_type_t valueType,
int valueLen, int hf_string, guint8 headerType)
+{
+ add_string_value_header_common (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_string, headerType,
+ vals_field_names);
+}
+
+static void
+add_openwave_string_value_header (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen, int hf_string, guint8 headerType)
+{
+ add_string_value_header_common (tree, header_buff, headerLen,
+ value_buff, valueType, valueLen, hf_string, headerType,
+ vals_openwave_field_names);
+}
+
+static void
+add_string_value_header_common (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen, int hf_string, guint8 headerType,
+ const value_string *vals)
{
if (valueType != VALUE_IS_TEXT_STRING)
{
proto_tree_add_text (tree, header_buff, 0, headerLen,
"Invalid %s string value",
- match_strval (headerType, vals_field_names));
+ match_strval (headerType, vals));
}
else
{
}
}
+static void
+add_quoted_string_value_header (proto_tree *tree, tvbuff_t *header_buff,
+ int headerLen, tvbuff_t *value_buff, value_type_t valueType,
+ int valueLen, int hf_string, guint8 headerType)
+{
+ if (valueType != VALUE_IS_TEXT_STRING)
+ {
+ proto_tree_add_text (tree, header_buff, 0, headerLen,
+ "Invalid %s quoted string value",
+ match_strval (headerType, vals_field_names));
+ }
+ else
+ {
+ proto_tree_add_string (tree, hf_string, header_buff,
+ 0, headerLen, tvb_get_ptr (value_buff, 1, valueLen - 1));
+ }
+}
+
/* Utility function to add a date value to the protocol tree */
static void
add_date_value_header (proto_tree *tree, tvbuff_t *header_buff,
int valueLen, int hf_time, guint8 headerType)
{
guint secs;
- struct timeval timeValue;
+ nstime_t timeValue;
/* Attempt to get the date value from the buffer */
if (get_integer (value_buff, 0, valueLen, valueType, &secs) == 0)
* there weren't WAP phones or Web servers back in
* late 1969/early 1970, they're unlikely to be used.
*/
- timeValue.tv_sec = secs;
- timeValue.tv_usec = 0;
+ timeValue.secs = secs;
+ timeValue.nsecs = 0;
proto_tree_add_time (tree, hf_time, header_buff, 0,
headerLen, &timeValue);
}
/*
* Untyped-parameter.
*/
- add_untyped_parameter (tree, value_buff, startOffset, offset);
+ offset = add_untyped_parameter (tree, value_buff, startOffset, offset);
return offset;
}
switch (value) {
case 0x01: /* Charset */
- add_parameter_charset (tree, value_buff, startOffset, offset);
+ offset = add_parameter_charset (tree, value_buff, startOffset, offset);
break;
case 0x03: /* Type */
- add_parameter_type (tree, value_buff, startOffset, offset);
+ offset = add_parameter_type (tree, value_buff, startOffset, offset);
break;
case 0x05: /* Name */
- add_parameter_text (tree, value_buff, startOffset, offset,
- hf_wsp_parameter_name, "Name");
+ offset = add_parameter_text (tree, value_buff, startOffset, offset,
+ hf_wsp_parameter_name, "Name");
break;
case 0x06: /* Filename */
- add_parameter_text (tree, value_buff, startOffset, offset,
- hf_wsp_parameter_filename, "Filename");
+ offset = add_parameter_text (tree, value_buff, startOffset, offset,
+ hf_wsp_parameter_filename, "Filename");
+ break;
+
+ case 0x09: /* Type (special) */
+ offset = add_constrained_encoding(tree, value_buff, startOffset, offset);
break;
case 0x0A: /* Start */
- add_parameter_text (tree, value_buff, startOffset, offset,
- hf_wsp_parameter_start, "Start");
+ offset = add_parameter_text (tree, value_buff, startOffset, offset,
+ hf_wsp_parameter_start, "Start");
break;
case 0x0B: /* Start-info */
- add_parameter_text (tree, value_buff, startOffset, offset,
- hf_wsp_parameter_start_info, "Start-info");
+ offset = add_parameter_text (tree, value_buff, startOffset, offset,
+ hf_wsp_parameter_start_info, "Start-info");
break;
case 0x0C: /* Comment */
- add_parameter_text (tree, value_buff, startOffset, offset,
- hf_wsp_parameter_comment, "Comment");
+ offset = add_parameter_text (tree, value_buff, startOffset, offset,
+ hf_wsp_parameter_comment, "Comment");
break;
case 0x0D: /* Domain */
- add_parameter_text (tree, value_buff, startOffset, offset,
- hf_wsp_parameter_domain, "Domain");
+ offset = add_parameter_text (tree, value_buff, startOffset, offset,
+ hf_wsp_parameter_domain, "Domain");
break;
case 0x0F: /* Path */
- add_parameter_text (tree, value_buff, startOffset, offset,
- hf_wsp_parameter_path, "Path");
+ offset = add_parameter_text (tree, value_buff, startOffset, offset,
+ hf_wsp_parameter_path, "Path");
break;
case 0x00: /* Q */
case 0x02: /* Level */
case 0x07: /* Differences */
case 0x08: /* Padding */
- case 0x09: /* Type (special) */
case 0x0E: /* Max-Age */
case 0x10: /* Secure */
default:
return offset;
}
-static void
+static int
add_untyped_parameter (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset)
{
- int tokenOffset;
- guint tokenSize;
const guint8 *token;
value_type_t valueType;
int subvalueLen;
int subvalueOffset;
guint value;
- int textvOffset;
- guint stringSize;
-
- tokenOffset = offset;
- tokenSize = tvb_strsize (value_buff, tokenOffset);
- token = tvb_get_ptr (value_buff, tokenOffset, tokenSize);
- offset += tokenSize;
+ int vOffset = offset;
+ token = tvb_get_ptr (value_buff, startOffset, offset - startOffset);
/*
* Now an Untyped-value; either an Integer-value or a Text-value.
*/
/*
* Text-value.
*/
- textvOffset = offset;
- stringSize = tvb_strsize (value_buff, textvOffset);
- if (stringSize == 1) {
+ if ((offset - vOffset) == 1) {
/*
* No-value. (stringSize includes the terminating
* null byte, so an empty string has a size of 1.)
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset,
"%s", token);
- return;
+ return offset;
}
- offset += stringSize;
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset,
"%s: %s", token,
- tvb_get_ptr (value_buff, textvOffset, stringSize));
+ tvb_get_ptr (value_buff, vOffset, offset - vOffset));
}
else
{
"%s: Invalid Integer-value", token);
}
}
+ return offset;
}
-static void
+static int
add_parameter_charset (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset)
{
proto_tree_add_uint (tree, hf_wsp_parameter_well_known_charset,
value_buff, startOffset, offset - startOffset,
subvalueLen); /* subvalueLen is the value */
- return;
+ return offset;
}
if (valueType == VALUE_IS_TEXT_STRING)
{
*/
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset, "Invalid Well-known charset");
- return;
+ return offset;
}
/*
*/
proto_tree_add_text (tree, value_buff, startOffset,
offset- startOffset, "*");
- return;
+ return offset;
}
if (get_integer(value_buff, subvalueOffset, subvalueLen,
proto_tree_add_uint (tree, hf_wsp_parameter_well_known_charset,
value_buff, startOffset, offset - startOffset, value);
}
+ return offset;
}
-static void
+static int
+add_constrained_encoding (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
+ int offset)
+{
+ value_type_t valueType;
+ int subvalueLen;
+ int subvalueOffset;
+ guint value;
+
+ valueType = get_value_type_len (value_buff, offset,
+ &subvalueLen, &subvalueOffset, &offset);
+ if (valueType == VALUE_IN_LEN)
+ {
+ /*
+ * Integer-value, invalid
+ */
+ proto_tree_add_text (tree, value_buff, startOffset,
+ offset - startOffset, "Invalid multipart type parameter");
+ return offset;
+ }
+ if (valueType == VALUE_IS_TEXT_STRING)
+ {
+ /*
+ * type-label.
+ */
+ proto_tree_add_string (tree, hf_wsp_parameter_upart_type,
+ value_buff, startOffset, offset - startOffset,
+ tvb_get_ptr (value_buff, subvalueOffset, subvalueLen));
+ return offset;
+ }
+ /*
+ * First byte had the 8th bit set.
+ */
+ get_integer(value_buff, subvalueOffset, subvalueLen, valueType, &value);
+ proto_tree_add_uint (tree, hf_wsp_parameter_upart_type_value,
+ value_buff, startOffset, offset - startOffset, value);
+ return offset;
+}
+
+static int
add_parameter_type (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset)
{
proto_tree_add_uint (tree, hf_wsp_parameter_type, value_buff,
startOffset, offset - startOffset, value);
}
+ return offset;
}
-static void
+static int
add_parameter_text (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset, int hf_string, const char *paramName)
{
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset, "Invalid %s", paramName);
} else {
- proto_tree_add_item (tree, hf_string, value_buff,
- startOffset, offset - startOffset, bo_little_endian);
+ proto_tree_add_string (tree, hf_string, value_buff,
+ startOffset, offset - startOffset,
+ tvb_get_ptr (value_buff, subvalueOffset, subvalueLen));
}
+ return offset;
}
static void
guint8 peek = 0;
proto_item *ti;
- /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,tvb_length_remaining(tvb, offset),bo_little_endian); */
- ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,tvb_reported_length(tvb),bo_little_endian);
+ /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,bo_little_endian); */
+ ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,bo_little_endian);
if (contentTypeStr == NULL && contentType == 0x12)
{
add_post_variable (ti, tvb, variableStart, variableEnd, valueStart, offset);
}
}
+ else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x23) || (contentType == 0x24) ||
+ (contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33))
+ {
+ add_multipart_data(ti, tvb);
+ }
}
static void
g_free (valueBuffer);
}
+void
+add_multipart_data (proto_tree *tree, tvbuff_t *tvb)
+{
+ int offset = 0;
+ guint nextOffset;
+ guint nEntries = 0;
+ guint count;
+ guint HeadersLen;
+ guint DataLen;
+ guint contentType = 0;
+ const char *contentTypeStr;
+ tvbuff_t *tmp_tvb;
+ int partnr = 1;
+ int part_start;
+
+ proto_item *sub_tree = NULL,
+ *ti;
+ proto_tree *mpart_tree;
+
+ nEntries = tvb_get_guintvar (tvb, offset, &count);
+ offset += count;
+ if (nEntries)
+ {
+ sub_tree = proto_tree_add_text(tree, tvb, offset - count, 0,
+ "Multipart body");
+ proto_item_add_subtree(sub_tree, ett_mpartlist);
+ }
+ while (nEntries--)
+ {
+ part_start = offset;
+ HeadersLen = tvb_get_guintvar (tvb, offset, &count);
+ offset += count;
+ DataLen = tvb_get_guintvar (tvb, offset, &count);
+ offset += count;
+ ti = proto_tree_add_uint(sub_tree, hf_wsp_mpart, tvb, part_start,
+ HeadersLen + DataLen + (offset - part_start), partnr);
+ mpart_tree = proto_item_add_subtree(ti, ett_multiparts);
+ nextOffset = add_content_type (mpart_tree, tvb, offset, &contentType, &contentTypeStr);
+ HeadersLen -= (nextOffset - offset);
+ if (HeadersLen > 0)
+ {
+ tmp_tvb = tvb_new_subset (tvb, nextOffset, HeadersLen, HeadersLen);
+ add_headers (mpart_tree, tmp_tvb);
+ }
+ offset = nextOffset + HeadersLen;
+ proto_tree_add_item (mpart_tree, hf_wsp_multipart_data, tvb, offset, DataLen, bo_little_endian);
+ offset += DataLen;
+ partnr++;
+ }
+}
+
static gint
get_integer (tvbuff_t *tvb, guint offset, guint valueLength,
value_type_t valueType, guint *value)
"Path", HFILL
}
},
+ { &hf_wsp_parameter_upart_type,
+ { "Type",
+ "wsp.content_type.parameter.upart.type",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Multipart type", HFILL
+ }
+ },
+ { &hf_wsp_parameter_upart_type_value,
+ { "Type",
+ "wsp.content_type.parameter.upart.type.int",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Multipart type (int value)", HFILL
+ }
+ },
{ &hf_wsp_reply_data,
{ "Data",
"wsp.reply.data",
"Age", HFILL
}
},
+ { &hf_wsp_header_openwave_proxy_push_addr,
+ { "x-up-proxy-push-addr",
+ "wsp.header.x-up-proxy-push-addr",
+ FT_BYTES, BASE_HEX, NULL, 0x00,
+ "The network address and port number that the handset can receive UPNOTIFY pushes on.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_push_accept,
+ { "x-up-proxy-push-accept",
+ "wsp.header.x-up-proxy-push-accept",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "The content types that the handset can handle when sent via UPNOTIFY pushes.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_push_seq,
+ { "x-up-proxy-push-seq",
+ "wsp.header.x-up-proxy-push-seq",
+ FT_UINT16, BASE_DEC, NULL, 0x00,
+ "Specifies the sequence number of the last UPNOTIFY push sent.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_notify,
+ { "x-up-proxy-notify",
+ "wsp.header.x-up-proxy-notify",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates to the handset that there are pending UPNOTIFY pushes waiting.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_operator_domain,
+ { "x-up-proxy-operator-domain",
+ "wsp.header.x-up-proxy-operator-domain",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Indicates the Trusted Provisioning Domain.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_home_page,
+ { "x-up-proxy-home-page",
+ "wsp.header.x-up-proxy-home-page",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Specifies the server-assigned home page URL.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_has_color,
+ { "x-up-devcap-has-color",
+ "wsp.header.x-up-devcap-has-color",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates if the handset supports colour.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_num_softkeys,
+ { "x-up-devcap-num-softkeys",
+ "wsp.header.x-up-devcap-num-softkeys",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "The number of softkeys that can be displayed on the handset.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_softkey_size,
+ { "x-up-devcap-softkey-size",
+ "wsp.header.x-up-devcap-softkey-size",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "The number of chars that can be displayed on a softkey label.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_screen_chars,
+ { "x-up-devcap-screen-chars",
+ "wsp.header.x-up-devcap-screen-chars",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "The height and width of the handset's display in characters.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_screen_pixels,
+ { "x-up-devcap-screen-pixels",
+ "wsp.header.x-up-devcap-screen-pixels",
+ FT_UINT32, BASE_DEC, NULL, 0x00,
+ "The height and width of the handset's display in pixels.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_em_size,
+ { "x-up-devcap-em-size",
+ "wsp.header.x-up-devcap-em-size",
+ FT_UINT32, BASE_DEC, NULL, 0x00,
+ "The height and width of an uppercase M in pixels in a handset.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_screen_depth,
+ { "x-up-devcap-screen-depth",
+ "wsp.header.x-up-devcap-screen-depth",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "The colour/gray depth of the display in bits.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_immed_alert,
+ { "x-up-devcap-immed-alert",
+ "wsp.header.x-up-devcap-immed-alert",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates if the handset has support for immediate UPNOTIFY alerts.", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_net_ask,
+ { "x-up-proxy-net-ask",
+ "wsp.header.x-up-proxy-net-ask",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates to browser if circuit switched call is allowed without user interaction", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_uplink_version,
+ { "x-up-proxy-uplink-version",
+ "wsp.header.x-up-proxy-uplink-version",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Version of the MAG WAP gateway", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_tod,
+ { "x-up-proxy-tod",
+ "wsp.header.x-up-proxy-tod",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Time of day", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_ba_enable,
+ { "x-up-proxy-ba-enable",
+ "wsp.header.x-up-proxy-ba-enable",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates if the WAP gateway should cache basic authentication details on behalf of the handset", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_ba_realm,
+ { "x-up-proxy-ba-realm",
+ "wsp.header.x-up-proxy-ba-realm",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Indicates the realm within which basic authentication credentials apply", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_redirect_enable,
+ { "x-up-proxy-redirect-enable",
+ "wsp.header.x-up-proxy-redirect-enable",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates if the handset wants the WAP gateway to handle HTTP redirects on its behalf", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_request_uri,
+ { "x-up-proxy-request-uri",
+ "wsp.header.x-up-proxy-request-uri",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Indicates to the handset that the previous request was redirected to the specified URI", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_redirect_status,
+ { "x-up-proxy-redirect-status",
+ "wsp.header.x-up-proxy-redirect-status",
+ FT_UINT32, BASE_DEC, NULL, 0x00,
+ "Indicates the status of a redirect performed on behalf of a handset", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_trans_charset,
+ { "x-up-proxy-trans-charset",
+ "wsp.header.x-up-proxy-trans-charset",
+ FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00,
+ "For POSTs indicates the charset encoding of a document", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_trans_charset_str,
+ { "x-up-proxy-trans-charset",
+ "wsp.header.x-up-proxy-trans-charset.string",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "For POSTs indicates the charset encoding of a document", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_linger,
+ { "x-up-proxy-linger",
+ "wsp.header.x-up-proxy-linger",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates the circuit linger time in seconds", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_client_id,
+ { "x-up-proxy-client-id",
+ "wsp.header.x-up-proxy-client-id",
+ FT_BYTES, BASE_DEC, NULL, 0x00,
+ "The ClientId of the handset", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_enable_trust,
+ { "x-up-proxy-enable-trust",
+ "wsp.header.x-up-proxy-enable-trust",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates whether to enable Trusted Provisioning Domain", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_trust_old,
+ { "x-up-proxy-trust-old",
+ "wsp.header.x-up-proxy-trust-old",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates if the content being returned was received from within the Trusted Provisioning Domain", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_trust,
+ { "x-up-proxy-trust",
+ "wsp.header.x-up-proxy-trust",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates if the content being returned was received from within the Trusted Provisioning Domain", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_proxy_bookmark,
+ { "x-up-proxy-bookmark",
+ "wsp.header.x-up-proxy-bookmark",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Specifies the URL to use for server-side bookmarks", HFILL
+ }
+ },
+ { &hf_wsp_header_openwave_devcap_gui,
+ { "x-up-devcap-gui",
+ "wsp.header.x-up-devcap-gui",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Indicates if the handset has a GUI", HFILL
+ }
+ },
{ &hf_wsp_header_bearer_indication,
/*
* XXX - I'm assuming that the bearer indication is
"Cache-Control field name", HFILL
}
},
+ { &hf_wsp_header_connection,
+ { "Connection",
+ "wsp.header.connection",
+ FT_UINT8, BASE_HEX, VALS ( vals_connection ), 0x00,
+ "Connection", HFILL
+ }
+ },
+ { &hf_wsp_header_connection_str,
+ { "Connection",
+ "wsp.header.connection_str",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Connection", HFILL
+ }
+ },
{ &hf_wsp_header_content_length,
{ "Content-Length",
"wsp.header.content_length",
"Via", HFILL
}
},
+ { &hf_wsp_header_wap_application_id,
+ { "X-Wap-Application-Id",
+ "wsp.header.wap_application_id",
+ FT_UINT8, BASE_HEX, NULL, 0x00,
+ "WAP application id", HFILL
+ }
+ },
+ { &hf_wsp_header_wap_application_id_str,
+ { "X-Wap-Application-Id",
+ "wsp.header.wap_application_id.string",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "WAP application id", HFILL
+ }
+ },
{ &hf_wsp_header_warning,
{ "Warning",
"wsp.header.warning",
"Application Header Value", HFILL
}
},
+ { &hf_wsp_header_content_ID,
+ { "Content-ID",
+ "wsp.header.content-id",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "Content-ID", HFILL
+ }
+ },
{ &hf_wsp_header_x_wap_tod,
{ "X-WAP.TOD",
"wsp.header.x_wap_tod",
"Post Data", HFILL
}
},
+ { &hf_wsp_push_data,
+ { "Push Data",
+ "wsp.push.data",
+ FT_NONE, BASE_NONE, NULL, 0x00,
+ "Push Data", HFILL
+ }
+ },
+ { &hf_wsp_multipart_data,
+ { "Data in this part",
+ "wsp.multipart.data",
+ FT_NONE, BASE_NONE, NULL, 0x00,
+ "The data of 1 MIME-multipart part.", HFILL
+ }
+ },
+ { &hf_wsp_mpart,
+ { "Part",
+ "wsp.multipart",
+ FT_UINT32, BASE_DEC, NULL, 0x00,
+ "MIME part of multipart data.", HFILL
+ }
+ },
{ &hf_wsp_redirect_flags,
{ "Flags",
"wsp.redirect_flags",
&ett_content_type,
&ett_redirect_flags,
&ett_redirect_afl,
+ &ett_multiparts,
+ &ett_mpartlist
};
/* Register the protocol name and description */
register_dissector("wsp-co", dissect_wsp_fromwap_co, proto_wsp);
register_dissector("wsp-cl", dissect_wsp_fromwap_cl, proto_wsp);
+ wsp_dissector_table = register_dissector_table("wsp.content_type.type",
+ "WSP content type", FT_UINT8, BASE_HEX);
+ register_heur_dissector_list("wsp", &heur_subdissector_list);
+
+ wsp_fromudp_handle = create_dissector_handle(dissect_wsp_fromudp,
+ proto_wsp);
};
void
proto_reg_handoff_wsp(void)
{
/*
- * Get a handle for the WMLC dissector
+ * Get a handle for the WMLC dissector.
*/
wmlc_handle = find_dissector("wmlc"); /* Coming soon :) */
+ /*
+ * And get a handle for the WTP-over-UDP dissector.
+ */
+ wtp_fromudp_handle = find_dissector("wtp-udp");
+
/* Only connection-less WSP has no previous handler */
- dissector_add("udp.port", UDP_PORT_WSP, dissect_wsp_fromudp, proto_wsp);
+ dissector_add("udp.port", UDP_PORT_WSP, wsp_fromudp_handle);
+ dissector_add("udp.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
/* This dissector is also called from the WTP and WTLS dissectors */
}