3 * Routines to dissect WSP component of WAP traffic.
5 * $Id: packet-wsp.c,v 1.55 2002/04/02 20:16:19 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * WAP dissector based on original work by Ben Fowler
12 * Updated by Neil Hunter <neil.hunter@energis-squared.com>
13 * WTLS support by Alexandre P. Ferreira (Splice IP)
14 * Openwave header support by Dermot Bradley <dermot.bradley@openwave.com>
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #ifdef HAVE_SYS_TYPES_H
39 # include <sys/types.h>
42 #ifdef HAVE_NETINET_IN_H
43 # include <netinet/in.h>
46 #ifdef NEED_SNPRINTF_H
52 # include "snprintf.h"
57 #include <epan/packet.h>
58 #include <epan/ipv6-utils.h>
59 #include <epan/conversation.h>
60 #include "packet-wap.h"
61 #include "packet-wsp.h"
63 /* File scoped variables for the protocol and registered fields */
64 static int proto_wsp = HF_EMPTY;
66 /* These fields used by fixed part of header */
67 static int hf_wsp_header_tid = HF_EMPTY;
68 static int hf_wsp_header_pdu_type = HF_EMPTY;
69 static int hf_wsp_version_major = HF_EMPTY;
70 static int hf_wsp_version_minor = HF_EMPTY;
71 static int hf_wsp_capability_length = HF_EMPTY;
72 static int hf_wsp_capabilities_section = HF_EMPTY;
73 static int hf_wsp_capabilities_client_SDU = HF_EMPTY;
74 static int hf_wsp_capabilities_server_SDU = HF_EMPTY;
75 static int hf_wsp_capabilities_protocol_opt = HF_EMPTY;
76 static int hf_wsp_capabilities_method_MOR = HF_EMPTY;
77 static int hf_wsp_capabilities_push_MOR = HF_EMPTY;
78 static int hf_wsp_capabilities_extended_methods = HF_EMPTY;
79 static int hf_wsp_capabilities_header_code_pages = HF_EMPTY;
80 static int hf_wsp_capabilities_aliases = HF_EMPTY;
81 static int hf_wsp_header_uri_len = HF_EMPTY;
82 static int hf_wsp_header_uri = HF_EMPTY;
83 static int hf_wsp_server_session_id = HF_EMPTY;
84 static int hf_wsp_header_status = HF_EMPTY;
85 static int hf_wsp_header_length = HF_EMPTY;
86 static int hf_wsp_headers_section = HF_EMPTY;
87 static int hf_wsp_header = HF_EMPTY;
88 static int hf_wsp_content_type = HF_EMPTY;
89 static int hf_wsp_content_type_str = HF_EMPTY;
90 static int hf_wsp_parameter_well_known_charset = HF_EMPTY;
91 static int hf_wsp_parameter_type = HF_EMPTY;
92 static int hf_wsp_parameter_name = HF_EMPTY;
93 static int hf_wsp_parameter_filename = HF_EMPTY;
94 static int hf_wsp_parameter_start = HF_EMPTY;
95 static int hf_wsp_parameter_start_info = HF_EMPTY;
96 static int hf_wsp_parameter_comment = HF_EMPTY;
97 static int hf_wsp_parameter_domain = HF_EMPTY;
98 static int hf_wsp_parameter_path = HF_EMPTY;
99 static int hf_wsp_parameter_upart_type = HF_EMPTY;
100 static int hf_wsp_parameter_upart_type_value = HF_EMPTY;
101 static int hf_wsp_reply_data = HF_EMPTY;
102 static int hf_wsp_post_data = HF_EMPTY;
103 static int hf_wsp_push_data = HF_EMPTY;
104 static int hf_wsp_multipart_data = HF_EMPTY;
105 static int hf_wsp_mpart = HF_EMPTY;
107 static int hf_wsp_header_shift_code = HF_EMPTY;
108 static int hf_wsp_header_accept = HF_EMPTY;
109 static int hf_wsp_header_accept_str = HF_EMPTY;
110 static int hf_wsp_header_accept_application = HF_EMPTY;
111 static int hf_wsp_header_accept_application_str = HF_EMPTY;
112 static int hf_wsp_header_accept_charset = HF_EMPTY;
113 static int hf_wsp_header_accept_charset_str = HF_EMPTY;
114 static int hf_wsp_header_accept_language = HF_EMPTY;
115 static int hf_wsp_header_accept_language_str = HF_EMPTY;
116 static int hf_wsp_header_accept_ranges = HF_EMPTY;
117 static int hf_wsp_header_accept_ranges_str = HF_EMPTY;
118 static int hf_wsp_header_cache_control = HF_EMPTY;
119 static int hf_wsp_header_cache_control_str = HF_EMPTY;
120 static int hf_wsp_header_cache_control_field_name = HF_EMPTY;
121 static int hf_wsp_header_connection = HF_EMPTY;
122 static int hf_wsp_header_connection_str = HF_EMPTY;
123 static int hf_wsp_header_cache_control_field_name_str = HF_EMPTY;
124 static int hf_wsp_header_content_length = HF_EMPTY;
125 static int hf_wsp_header_age = HF_EMPTY;
126 static int hf_wsp_header_bearer_indication = HF_EMPTY;
127 static int hf_wsp_header_date = HF_EMPTY;
128 static int hf_wsp_header_etag = HF_EMPTY;
129 static int hf_wsp_header_expires = HF_EMPTY;
130 static int hf_wsp_header_last_modified = HF_EMPTY;
131 static int hf_wsp_header_location = HF_EMPTY;
132 static int hf_wsp_header_if_modified_since = HF_EMPTY;
133 static int hf_wsp_header_profile = HF_EMPTY;
134 static int hf_wsp_header_pragma = HF_EMPTY;
135 static int hf_wsp_header_server = HF_EMPTY;
136 static int hf_wsp_header_user_agent = HF_EMPTY;
137 static int hf_wsp_header_warning = HF_EMPTY;
138 static int hf_wsp_header_warning_code = HF_EMPTY;
139 static int hf_wsp_header_warning_agent = HF_EMPTY;
140 static int hf_wsp_header_warning_text = HF_EMPTY;
141 static int hf_wsp_header_application_header = HF_EMPTY;
142 static int hf_wsp_header_application_value = HF_EMPTY;
143 static int hf_wsp_header_x_wap_tod = HF_EMPTY;
144 static int hf_wsp_header_content_ID = HF_EMPTY;
145 static int hf_wsp_header_transfer_encoding = HF_EMPTY;
146 static int hf_wsp_header_transfer_encoding_str = HF_EMPTY;
147 static int hf_wsp_header_via = HF_EMPTY;
148 static int hf_wsp_header_wap_application_id = HF_EMPTY;
149 static int hf_wsp_header_wap_application_id_str = HF_EMPTY;
152 /* Openwave-specific WSP headers */
153 static int hf_wsp_header_openwave_proxy_push_addr = HF_EMPTY;
154 static int hf_wsp_header_openwave_proxy_push_accept = HF_EMPTY;
155 static int hf_wsp_header_openwave_proxy_push_seq = HF_EMPTY;
156 static int hf_wsp_header_openwave_proxy_notify = HF_EMPTY;
157 static int hf_wsp_header_openwave_proxy_operator_domain = HF_EMPTY;
158 static int hf_wsp_header_openwave_proxy_home_page = HF_EMPTY;
159 static int hf_wsp_header_openwave_devcap_has_color = HF_EMPTY;
160 static int hf_wsp_header_openwave_devcap_num_softkeys = HF_EMPTY;
161 static int hf_wsp_header_openwave_devcap_softkey_size = HF_EMPTY;
162 static int hf_wsp_header_openwave_devcap_screen_chars = HF_EMPTY;
163 static int hf_wsp_header_openwave_devcap_screen_pixels = HF_EMPTY;
164 static int hf_wsp_header_openwave_devcap_em_size = HF_EMPTY;
165 static int hf_wsp_header_openwave_devcap_screen_depth = HF_EMPTY;
166 static int hf_wsp_header_openwave_devcap_immed_alert = HF_EMPTY;
167 static int hf_wsp_header_openwave_proxy_net_ask = HF_EMPTY;
168 static int hf_wsp_header_openwave_proxy_uplink_version = HF_EMPTY;
169 static int hf_wsp_header_openwave_proxy_tod = HF_EMPTY;
170 static int hf_wsp_header_openwave_proxy_ba_enable = HF_EMPTY;
171 static int hf_wsp_header_openwave_proxy_ba_realm = HF_EMPTY;
172 static int hf_wsp_header_openwave_proxy_redirect_enable = HF_EMPTY;
173 static int hf_wsp_header_openwave_proxy_request_uri = HF_EMPTY;
174 static int hf_wsp_header_openwave_proxy_redirect_status = HF_EMPTY;
175 static int hf_wsp_header_openwave_proxy_trans_charset = HF_EMPTY;
176 static int hf_wsp_header_openwave_proxy_trans_charset_str = HF_EMPTY;
177 static int hf_wsp_header_openwave_proxy_linger = HF_EMPTY;
178 static int hf_wsp_header_openwave_proxy_client_id = HF_EMPTY;
179 static int hf_wsp_header_openwave_proxy_enable_trust = HF_EMPTY;
180 static int hf_wsp_header_openwave_proxy_trust_old = HF_EMPTY;
181 static int hf_wsp_header_openwave_proxy_trust = HF_EMPTY;
182 static int hf_wsp_header_openwave_proxy_bookmark = HF_EMPTY;
183 static int hf_wsp_header_openwave_devcap_gui = HF_EMPTY;
186 static int hf_wsp_redirect_flags = HF_EMPTY;
187 static int hf_wsp_redirect_permanent = HF_EMPTY;
188 static int hf_wsp_redirect_reuse_security_session = HF_EMPTY;
189 static int hf_wsp_redirect_afl = HF_EMPTY;
190 static int hf_wsp_redirect_afl_bearer_type_included = HF_EMPTY;
191 static int hf_wsp_redirect_afl_port_number_included = HF_EMPTY;
192 static int hf_wsp_redirect_afl_address_len = HF_EMPTY;
193 static int hf_wsp_redirect_bearer_type = HF_EMPTY;
194 static int hf_wsp_redirect_port_num = HF_EMPTY;
195 static int hf_wsp_redirect_ipv4_addr = HF_EMPTY;
196 static int hf_wsp_redirect_ipv6_addr = HF_EMPTY;
197 static int hf_wsp_redirect_addr = HF_EMPTY;
199 /* Initialize the subtree pointers */
200 static gint ett_wsp = ETT_EMPTY;
201 static gint ett_content_type_parameters = ETT_EMPTY;
202 static gint ett_header = ETT_EMPTY;
203 static gint ett_headers = ETT_EMPTY;
204 static gint ett_header_warning = ETT_EMPTY;
205 static gint ett_header_cache_control_parameters = ETT_EMPTY;
206 static gint ett_header_cache_control_field_names = ETT_EMPTY;
207 static gint ett_capabilities = ETT_EMPTY;
208 static gint ett_content_type = ETT_EMPTY;
209 static gint ett_redirect_flags = ETT_EMPTY;
210 static gint ett_redirect_afl = ETT_EMPTY;
211 static gint ett_multiparts = ETT_EMPTY;
212 static gint ett_mpartlist = ETT_EMPTY;
214 /* Handle for WSP-over-UDP dissector */
215 static dissector_handle_t wsp_fromudp_handle;
217 /* Handle for WTP-over-UDP dissector */
218 static dissector_handle_t wtp_fromudp_handle;
220 /* Handle for WMLC dissector */
221 static dissector_handle_t wmlc_handle;
223 static const value_string vals_pdu_type[] = {
224 { 0x00, "Reserved" },
226 { 0x02, "ConnectReply" },
227 { 0x03, "Redirect" },
229 { 0x05, "Disconnect" },
231 { 0x07, "ConfirmedPush" },
235 /* 0x10 - 0x3F Unassigned */
243 /* 0x45 - 0x4F Unassigned (Get PDU) */
244 /* 0x50 - 0x5F Extended method (Get PDU) */
249 /* 0x62 - 0x6F Unassigned (Post PDU) */
250 /* 0x70 - 0x7F Extended method (Post PDU) */
251 /* 0x80 - 0xFF Reserved */
257 static const value_string vals_status[] = {
258 /* 0x00 - 0x0F Reserved */
260 { 0x10, "Continue" },
261 { 0x11, "Switching Protocols" },
265 { 0x22, "Accepted" },
266 { 0x23, "Non-Authoritative Information" },
267 { 0x24, "No Content" },
268 { 0x25, "Reset Content" },
269 { 0x26, "Partial Content" },
271 { 0x30, "Multiple Choices" },
272 { 0x31, "Moved Permanently" },
273 { 0x32, "Moved Temporarily" },
274 { 0x33, "See Other" },
275 { 0x34, "Not Modified" },
276 { 0x35, "Use Proxy" },
277 { 0x37, "Temporary Redirect" },
279 { 0x40, "Bad Request" },
280 { 0x41, "Unauthorised" },
281 { 0x42, "Payment Required" },
282 { 0x43, "Forbidden" },
283 { 0x44, "Not Found" },
284 { 0x45, "Method Not Allowed" },
285 { 0x46, "Not Acceptable" },
286 { 0x47, "Proxy Authentication Required" },
287 { 0x48, "Request Timeout" },
288 { 0x49, "Conflict" },
290 { 0x4B, "Length Required" },
291 { 0x4C, "Precondition Failed" },
292 { 0x4D, "Request Entity Too Large" },
293 { 0x4E, "Request-URI Too Large" },
294 { 0x4F, "Unsupported Media Type" },
295 { 0x50, "Requested Range Not Satisfiable" },
296 { 0x51, "Expectation Failed" },
298 { 0x60, "Internal Server Error" },
299 { 0x61, "Not Implemented" },
300 { 0x62, "Bad Gateway" },
301 { 0x63, "Service Unavailable" },
302 { 0x64, "Gateway Timeout" },
303 { 0x65, "HTTP Version Not Supported" },
310 #define FN_ACCEPT 0x00
311 #define FN_ACCEPT_CHARSET_DEP 0x01 /* encoding version 1.1, deprecated */
312 #define FN_ACCEPT_ENCODING_DEP 0x02 /* encoding version 1.1, deprecated */
313 #define FN_ACCEPT_LANGUAGE 0x03
314 #define FN_ACCEPT_RANGES 0x04
316 #define FN_ALLOW 0x06
317 #define FN_AUTHORIZATION 0x07
318 #define FN_CACHE_CONTROL_DEP 0x08 /* encoding version 1.1, deprecated */
319 #define FN_CONNECTION 0x09
320 #define FN_CONTENT_BASE 0x0A
321 #define FN_CONTENT_ENCODING 0x0B
322 #define FN_CONTENT_LANGUAGE 0x0C
323 #define FN_CONTENT_LENGTH 0x0D
324 #define FN_CONTENT_LOCATION 0x0E
325 #define FN_CONTENT_MD5 0x0F
326 #define FN_CONTENT_RANGE_DEP 0x10 /* encoding version 1.1, deprecated */
327 #define FN_CONTENT_TYPE 0x11
330 #define FN_EXPIRES 0x14
333 #define FN_IF_MODIFIED_SINCE 0x17
334 #define FN_IF_MATCH 0x18
335 #define FN_IF_NONE_MATCH 0x19
336 #define FN_IF_RANGE 0x1A
337 #define FN_IF_UNMODIFIED_SINCE 0x1B
338 #define FN_LOCATION 0x1C
339 #define FN_LAST_MODIFIED 0x1D
340 #define FN_MAX_FORWARDS 0x1E
341 #define FN_PRAGMA 0x1F
342 #define FN_PROXY_AUTHENTICATE 0x20
343 #define FN_PROXY_AUTHORIZATION 0x21
344 #define FN_PUBLIC 0x22
345 #define FN_RANGE 0x23
346 #define FN_REFERER 0x24
347 #define FN_RETRY_AFTER 0x25
348 #define FN_SERVER 0x26
349 #define FN_TRANSFER_ENCODING 0x27
350 #define FN_UPGRADE 0x28
351 #define FN_USER_AGENT 0x29
354 #define FN_WARNING 0x2C
355 #define FN_WWW_AUTHENTICATE 0x2D
356 #define FN_CONTENT_DISPOSITION 0x2E
357 #define FN_X_WAP_APPLICATION_ID 0x2F
358 #define FN_X_WAP_CONTENT_URI 0x30
359 #define FN_X_WAP_INITIATOR_URI 0x31
360 #define FN_ACCEPT_APPLICATION 0x32
361 #define FN_BEARER_INDICATION 0x33
362 #define FN_PUSH_FLAG 0x34
363 #define FN_PROFILE 0x35
364 #define FN_PROFILE_DIFF 0x36
365 #define FN_PROFILE_WARNING 0x37
366 #define FN_EXPECT 0x38
368 #define FN_TRAILER 0x3A
369 #define FN_ACCEPT_CHARSET 0x3B /* encoding version 1.3 */
370 #define FN_ACCEPT_ENCODING 0x3C /* encoding version 1.3 */
371 #define FN_CACHE_CONTROL 0x3D /* encoding version 1.3 */
372 #define FN_CONTENT_RANGE 0x3E /* encoding version 1.3 */
373 #define FN_X_WAP_TOD 0x3F
374 #define FN_CONTENT_ID 0x40
375 #define FN_SET_COOKIE 0x41
376 #define FN_COOKIE 0x42
377 #define FN_ENCODING_VERSION 0x43
378 #define FN_PROFILE_WARNING14 0x44 /* encoding version 1.4 */
379 #define FN_CONTENT_DISPOSITION14 0x45 /* encoding version 1.4 */
380 #define FN_X_WAP_SECURITY 0x46
381 #define FN_CACHE_CONTROL14 0x47 /* encoding version 1.4 */
385 * Openwave field names.
387 #define FN_OPENWAVE_PROXY_PUSH_ADDR 0x00
388 #define FN_OPENWAVE_PROXY_PUSH_ACCEPT 0x01
389 #define FN_OPENWAVE_PROXY_PUSH_SEQ 0x02
390 #define FN_OPENWAVE_PROXY_NOTIFY 0x03
391 #define FN_OPENWAVE_PROXY_OPERATOR_DOMAIN 0x04
392 #define FN_OPENWAVE_PROXY_HOME_PAGE 0x05
393 #define FN_OPENWAVE_DEVCAP_HAS_COLOR 0x06
394 #define FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS 0x07
395 #define FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE 0x08
396 #define FN_OPENWAVE_DEVCAP_SCREEN_CHARS 0x09
397 #define FN_OPENWAVE_DEVCAP_SCREEN_PIXELS 0x0A
398 #define FN_OPENWAVE_DEVCAP_EM_SIZE 0x0B
399 #define FN_OPENWAVE_DEVCAP_SCREEN_DEPTH 0x0C
400 #define FN_OPENWAVE_DEVCAP_IMMED_ALERT 0x0D
401 #define FN_OPENWAVE_PROXY_NET_ASK 0x0E
402 #define FN_OPENWAVE_PROXY_UPLINK_VERSION 0x0F
403 #define FN_OPENWAVE_PROXY_TOD 0x10
404 #define FN_OPENWAVE_PROXY_BA_ENABLE 0x11
405 #define FN_OPENWAVE_PROXY_BA_REALM 0x12
406 #define FN_OPENWAVE_PROXY_REDIRECT_ENABLE 0x13
407 #define FN_OPENWAVE_PROXY_REQUEST_URI 0x14
408 #define FN_OPENWAVE_PROXY_REDIRECT_STATUS 0x15
409 #define FN_OPENWAVE_PROXY_TRANS_CHARSET 0x16
410 #define FN_OPENWAVE_PROXY_LINGER 0x17
411 #define FN_OPENWAVE_PROXY_CLIENT_ID 0x18
412 #define FN_OPENWAVE_PROXY_ENABLE_TRUST 0x19
413 #define FN_OPENWAVE_PROXY_TRUST_OLD 0x1A
414 #define FN_OPENWAVE_PROXY_TRUST 0x20
415 #define FN_OPENWAVE_PROXY_BOOKMARK 0x21
416 #define FN_OPENWAVE_DEVCAP_GUI 0x22
418 static const value_string vals_openwave_field_names[] = {
419 { FN_OPENWAVE_PROXY_PUSH_ADDR, "x-up-proxy-push-addr" },
420 { FN_OPENWAVE_PROXY_PUSH_ACCEPT, "x-up-proxy-push-accept" },
421 { FN_OPENWAVE_PROXY_PUSH_SEQ, "x-up-proxy-seq" },
422 { FN_OPENWAVE_PROXY_NOTIFY, "x-up-proxy-notify" },
423 { FN_OPENWAVE_PROXY_OPERATOR_DOMAIN, "x-up-proxy-operator-domain" },
424 { FN_OPENWAVE_PROXY_HOME_PAGE, "x-up-proxy-home-page" },
425 { FN_OPENWAVE_DEVCAP_HAS_COLOR, "x-up-devcap-has-color" },
426 { FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS, "x-up-devcap-num-softkeys" },
427 { FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE, "x-up-devcap-softkey-size" },
428 { FN_OPENWAVE_DEVCAP_SCREEN_CHARS, "x-up-devcap-screen-chars" },
429 { FN_OPENWAVE_DEVCAP_SCREEN_PIXELS, "x-up-devcap-screen-pixels" },
430 { FN_OPENWAVE_DEVCAP_EM_SIZE, "x-up-devcap-em-size" },
431 { FN_OPENWAVE_DEVCAP_SCREEN_DEPTH, "x-up-devcap-screen-depth" },
432 { FN_OPENWAVE_DEVCAP_IMMED_ALERT, "x-up-devcap-immed-alert" },
433 { FN_OPENWAVE_PROXY_NET_ASK, "x-up-proxy-net-ask" },
434 { FN_OPENWAVE_PROXY_UPLINK_VERSION, "x-up-proxy-uplink-version" },
435 { FN_OPENWAVE_PROXY_TOD, "x-up-proxy-tod" },
436 { FN_OPENWAVE_PROXY_BA_ENABLE, "x-up-proxy-ba-enable" },
437 { FN_OPENWAVE_PROXY_BA_REALM, "x-up-proxy-ba-realm" },
438 { FN_OPENWAVE_PROXY_REDIRECT_ENABLE, "x-up-proxy-redirect-enable" },
439 { FN_OPENWAVE_PROXY_REQUEST_URI, "x-up-proxy-request-uri" },
440 { FN_OPENWAVE_PROXY_REDIRECT_STATUS, "x-up-proxy-redirect-status" },
441 { FN_OPENWAVE_PROXY_TRANS_CHARSET, "x-up-proxy-trans-charset" },
442 { FN_OPENWAVE_PROXY_LINGER, "x-up-proxy-linger" },
443 { FN_OPENWAVE_PROXY_CLIENT_ID, "x-up-proxy-client-id" },
444 { FN_OPENWAVE_PROXY_ENABLE_TRUST, "x-up-proxy-enable-trust" },
445 { FN_OPENWAVE_PROXY_TRUST_OLD, "x-up-proxy-trust-old" },
446 { FN_OPENWAVE_PROXY_TRUST, "x-up-proxy-trust" },
447 { FN_OPENWAVE_PROXY_BOOKMARK, "x-up-proxy-bookmark" },
448 { FN_OPENWAVE_DEVCAP_GUI, "x-up-devcap-gui" },
453 static const value_string vals_field_names[] = {
454 { FN_ACCEPT, "Accept" },
455 { FN_ACCEPT_CHARSET_DEP, "Accept-Charset (encoding 1.1)" },
456 { FN_ACCEPT_ENCODING_DEP, "Accept-Encoding (encoding 1.1)" },
457 { FN_ACCEPT_LANGUAGE, "Accept-Language" },
458 { FN_ACCEPT_RANGES, "Accept-Ranges" },
460 { FN_ALLOW, "Allow" },
461 { FN_AUTHORIZATION, "Authorization" },
462 { FN_CACHE_CONTROL_DEP, "Cache-Control (encoding 1.1)" },
463 { FN_CONNECTION, "Connection" },
464 { FN_CONTENT_BASE, "Content-Base" },
465 { FN_CONTENT_ENCODING, "Content-Encoding" },
466 { FN_CONTENT_LANGUAGE, "Content-Language" },
467 { FN_CONTENT_LENGTH, "Content-Length" },
468 { FN_CONTENT_LOCATION, "Content-Location" },
469 { FN_CONTENT_MD5, "Content-MD5" },
470 { FN_CONTENT_RANGE_DEP, "Content-Range (encoding 1.1)" },
471 { FN_CONTENT_TYPE, "Content-Type" },
474 { FN_EXPIRES, "Expires" },
477 { FN_IF_MODIFIED_SINCE, "If-Modified-Since" },
478 { FN_IF_MATCH, "If-Match" },
479 { FN_IF_NONE_MATCH, "If-None-Match" },
480 { FN_IF_RANGE, "If-Range" },
481 { FN_IF_UNMODIFIED_SINCE, "If-Unmodified-Since" },
482 { FN_LOCATION, "Location" },
483 { FN_LAST_MODIFIED, "Last-Modified" },
484 { FN_MAX_FORWARDS, "Max-Forwards" },
485 { FN_PRAGMA, "Pragma" },
486 { FN_PROXY_AUTHENTICATE, "Proxy-Authenticate" },
487 { FN_PROXY_AUTHORIZATION, "Proxy-Authorization" },
488 { FN_PUBLIC, "Public" },
489 { FN_RANGE, "Range" },
490 { FN_REFERER, "Referer" },
491 { FN_RETRY_AFTER, "Retry-After" },
492 { FN_SERVER, "Server" },
493 { FN_TRANSFER_ENCODING, "Transfer-Encoding" },
494 { FN_UPGRADE, "Upgrade" },
495 { FN_USER_AGENT, "User-Agent" },
498 { FN_WARNING, "Warning" },
499 { FN_WWW_AUTHENTICATE, "WWW-Authenticate" },
500 { FN_CONTENT_DISPOSITION, "Content-Disposition" },
501 { FN_X_WAP_APPLICATION_ID, "X-Wap-Application-ID" },
502 { FN_X_WAP_CONTENT_URI, "X-Wap-Content-URI" },
503 { FN_X_WAP_INITIATOR_URI, "X-Wap-Initiator-URI" },
504 { FN_ACCEPT_APPLICATION, "Accept-Application" },
505 { FN_BEARER_INDICATION, "Bearer-Indication" },
506 { FN_PUSH_FLAG, "Push-Flag" },
507 { FN_PROFILE, "Profile" },
508 { FN_PROFILE_DIFF, "Profile-Diff" },
509 { FN_PROFILE_WARNING, "Profile-Warning" },
510 { FN_EXPECT, "Expect" },
512 { FN_TRAILER, "Trailer" },
513 { FN_ACCEPT_CHARSET, "Accept-Charset" },
514 { FN_ACCEPT_ENCODING, "Accept-Encoding" },
515 { FN_CACHE_CONTROL, "Cache-Control" },
516 { FN_CONTENT_RANGE, "Content-Range" },
517 { FN_X_WAP_TOD, "X-Wap-Tod" },
518 { FN_CONTENT_ID, "Content-ID" },
519 { FN_SET_COOKIE, "Set-Cookie" },
520 { FN_COOKIE, "Cookie" },
521 { FN_ENCODING_VERSION, "Encoding-Version" },
522 { FN_PROFILE_WARNING14, "Profile-Warning (encoding 1.4)" },
523 { FN_CONTENT_DISPOSITION14,"Content-Disposition (encoding 1.4)" },
524 { FN_X_WAP_SECURITY, "X-WAP-Security" },
525 { FN_CACHE_CONTROL14, "Cache-Control (encoding 1.4)" },
530 * Bearer types (from the WDP specification).
534 #define BT_GSM_USSD 0x02
535 #define BT_GSM_SMS 0x03
536 #define BT_ANSI_136_GUTS 0x04
537 #define BT_IS_95_SMS 0x05
538 #define BT_IS_95_CSD 0x06
539 #define BT_IS_95_PACKET_DATA 0x07
540 #define BT_ANSI_136_CSD 0x08
541 #define BT_ANSI_136_PACKET_DATA 0x09
542 #define BT_GSM_CSD 0x0A
543 #define BT_GSM_GPRS 0x0B
544 #define BT_GSM_USSD_IPv4 0x0C
545 #define BT_AMPS_CDPD 0x0D
546 #define BT_PDC_CSD 0x0E
547 #define BT_PDC_PACKET_DATA 0x0F
548 #define BT_IDEN_SMS 0x10
549 #define BT_IDEN_CSD 0x11
550 #define BT_IDEN_PACKET_DATA 0x12
551 #define BT_PAGING_FLEX 0x13
552 #define BT_PHS_SMS 0x14
553 #define BT_PHS_CSD 0x15
554 #define BT_GSM_USSD_GSM_SC 0x16
555 #define BT_TETRA_SDS_ITSI 0x17
556 #define BT_TETRA_SDS_MSISDN 0x18
557 #define BT_TETRA_PACKET_DATA 0x19
558 #define BT_PAGING_REFLEX 0x1A
559 #define BT_GSM_USSD_MSISDN 0x1B
560 #define BT_MOBITEX_MPAK 0x1C
561 #define BT_ANSI_136_GHOST 0x1D
563 static const value_string vals_bearer_types[] = {
566 { BT_GSM_USSD, "GSM USSD" },
567 { BT_GSM_SMS, "GSM SMS" },
568 { BT_ANSI_136_GUTS, "ANSI-136 GUTS/R-Data" },
569 { BT_IS_95_SMS, "IS-95 CDMA SMS" },
570 { BT_IS_95_CSD, "IS-95 CDMA CSD" },
571 { BT_IS_95_PACKET_DATA, "IS-95 CDMA Packet data" },
572 { BT_ANSI_136_CSD, "ANSI-136 CSD" },
573 { BT_ANSI_136_PACKET_DATA, "ANSI-136 Packet data" },
574 { BT_GSM_CSD, "GSM CSD" },
575 { BT_GSM_GPRS, "GSM GPRS" },
576 { BT_GSM_USSD_IPv4, "GSM USSD (IPv4 addresses)" },
577 { BT_AMPS_CDPD, "AMPS CDPD" },
578 { BT_PDC_CSD, "PDC CSD" },
579 { BT_PDC_PACKET_DATA, "PDC Packet data" },
580 { BT_IDEN_SMS, "IDEN SMS" },
581 { BT_IDEN_CSD, "IDEN CSD" },
582 { BT_IDEN_PACKET_DATA, "IDEN Packet data" },
583 { BT_PAGING_FLEX, "Paging network FLEX(TM)" },
584 { BT_PHS_SMS, "PHS SMS" },
585 { BT_PHS_CSD, "PHS CSD" },
586 { BT_GSM_USSD_GSM_SC, "GSM USSD (GSM Service Code addresses)" },
587 { BT_TETRA_SDS_ITSI, "TETRA SDS (ITSI addresses)" },
588 { BT_TETRA_SDS_MSISDN, "TETRA SDS (MSISDN addresses)" },
589 { BT_TETRA_PACKET_DATA, "TETRA Packet data" },
590 { BT_PAGING_REFLEX, "Paging network ReFLEX(TM)" },
591 { BT_GSM_USSD_MSISDN, "GSM USSD (MSISDN addresses)" },
592 { BT_MOBITEX_MPAK, "Mobitex MPAK" },
593 { BT_ANSI_136_GHOST, "ANSI-136 GHOST/R-Data" },
597 static const value_string vals_content_types[] = {
600 { 0x02, "text/html" },
601 { 0x03, "text/plain" },
602 { 0x04, "text/x-hdml" },
603 { 0x05, "text/x-ttml" },
604 { 0x06, "text/x-vCalendar" },
605 { 0x07, "text/x-vCard" },
606 { 0x08, "text/vnd.wap.wml" },
607 { 0x09, "text/vnd.wap.wmlscript" },
608 { 0x0A, "text/vnd.wap.channel" },
609 { 0x0B, "Multipart/*" },
610 { 0x0C, "Multipart/mixed" },
611 { 0x0D, "Multipart/form-data" },
612 { 0x0E, "Multipart/byteranges" },
613 { 0x0F, "Multipart/alternative" },
614 { 0x10, "application/*" },
615 { 0x11, "application/java-vm" },
616 { 0x12, "application/x-www-form-urlencoded" },
617 { 0x13, "application/x-hdmlc" },
618 { 0x14, "application/vnd.wap.wmlc" },
619 { 0x15, "application/vnd.wap.wmlscriptc" },
620 { 0x16, "application/vnd.wap.channelc" },
621 { 0x17, "application/vnd.wap.uaprof" },
622 { 0x18, "application/vnd.wap.wtls-ca-certificate" },
623 { 0x19, "application/vnd.wap.wtls-user-certificate" },
624 { 0x1A, "application/x-x509-ca-cert" },
625 { 0x1B, "application/x-x509-user-cert" },
627 { 0x1D, "image/gif" },
628 { 0x1E, "image/jpeg" },
629 { 0x1F, "image/tiff" },
630 { 0x20, "image/png" },
631 { 0x21, "image/vnd.wap.wbmp" },
632 { 0x22, "application/vnd.wap.multipart.*" },
633 { 0x23, "application/vnd.wap.multipart.mixed" },
634 { 0x24, "application/vnd.wap.multipart.form-data" },
635 { 0x25, "application/vnd.wap.multipart.byteranges" },
636 { 0x26, "application/vnd.wap.multipart.alternative" },
637 { 0x27, "application/xml" },
638 { 0x28, "text/xml" },
639 { 0x29, "application/vnd.wap.wbxml" },
640 { 0x2A, "application/x-x968-cross-cert" },
641 { 0x2B, "application/x-x968-ca-cert" },
642 { 0x2C, "application/x-x968-user-cert" },
643 { 0x2D, "text/vnd.wap.si" },
644 { 0x2E, "application/vnd.wap.sic" },
645 { 0x2F, "text/vnd.wap.sl" },
646 { 0x30, "application/vnd.wap.slc" },
647 { 0x31, "text/vnd.wap.co" },
648 { 0x32, "application/vnd.wap.coc" },
649 { 0x33, "application/vnd.wap.multipart.related" },
650 { 0x34, "application/vnd.wap.sia" },
651 { 0x35, "text/vnd.wap.connectivity-xml" },
652 { 0x36, "application/vnd.wap.connectivity-wbxml" },
653 { 0x37, "application/pkcs7-mime" },
654 { 0x38, "application/vnd.wap.hashed-certificate" },
655 { 0x39, "application/vnd.wap.signed-certificate" },
656 { 0x3A, "application/vnd.wap.cert-response" },
657 { 0x3B, "application/xhtml+xml" },
658 { 0x3C, "application/wml+xml" },
659 { 0x3D, "text/css" },
660 { 0x3E, "application/vnd.wap.mms-message" },
661 { 0x3F, "application/vnd.wap.rollover-certificate" },
662 { 0x201, "application/vnd.uplanet.cachop-wbxml" },
663 { 0x202, "application/vnd.uplanet.signal" },
664 { 0x203, "application/vnd.uplanet.alert-wbxml" },
665 { 0x204, "application/vnd.uplanet.list-wbxml" },
666 { 0x205, "application/vnd.uplanet.listcmd-wbxml" },
667 { 0x206, "application/vnd.uplanet.channel-wbxml" },
668 { 0x207, "application/vnd.uplanet.provisioning-status-uri" },
669 { 0x208, "x-wap.multipart/vnd.uplanet.header-set" },
670 { 0x209, "application/vnd.uplanet.bearer-choice-wbxml" },
671 { 0x20A, "application/vnd.phonecom.mmc-wbxml" },
672 { 0x20B, "application/vnd.nokia.syncset+wbxml" },
676 static const value_string vals_languages[] = {
677 { 0x01, "Afar (aa)" },
678 { 0x02, "Abkhazian (ab)" },
679 { 0x03, "Afrikaans (af)" },
680 { 0x04, "Amharic (am)" },
681 { 0x05, "Arabic (ar)" },
682 { 0x06, "Assamese (as)" },
683 { 0x07, "Aymara (ay)" },
684 { 0x08, "Azerbaijani (az)" },
685 { 0x09, "Bashkir (ba)" },
686 { 0x0A, "Byelorussian (be)" },
687 { 0x0B, "Bulgarian (bg)" },
688 { 0x0C, "Bihari (bh)" },
689 { 0x0D, "Bislama (bi)" },
690 { 0x0E, "Bengali; Bangla (bn)" },
691 { 0x0F, "Tibetan (bo)" },
692 { 0x10, "Breton (br)" },
693 { 0x11, "Catalan (ca)" },
694 { 0x12, "Corsican (co)" },
695 { 0x13, "Czech (cs)" },
696 { 0x14, "Welsh (cy)" },
697 { 0x15, "Danish (da)" },
698 { 0x16, "German (de)" },
699 { 0x17, "Bhutani (dz)" },
700 { 0x18, "Greek (el)" },
701 { 0x19, "English (en)" },
702 { 0x1A, "Esperanto (eo)" },
703 { 0x1B, "Spanish (es)" },
704 { 0x1C, "Estonian (et)" },
705 { 0x1D, "Basque (eu)" },
706 { 0x1E, "Persian (fa)" },
707 { 0x1F, "Finnish (fi)" },
708 { 0x20, "Fiji (fj)" },
709 { 0x21, "Urdu (ur)" },
710 { 0x22, "French (fr)" },
711 { 0x23, "Uzbek (uz)" },
712 { 0x24, "Irish (ga)" },
713 { 0x25, "Scots Gaelic (gd)" },
714 { 0x26, "Galician (gl)" },
715 { 0x27, "Guarani (gn)" },
716 { 0x28, "Gujarati (gu)" },
717 { 0x29, "Hausa (ha)" },
718 { 0x2A, "Hebrew (formerly iw) (he)" },
719 { 0x2B, "Hindi (hi)" },
720 { 0x2C, "Croatian (hr)" },
721 { 0x2D, "Hungarian (hu)" },
722 { 0x2E, "Armenian (hy)" },
723 { 0x2F, "Vietnamese (vi)" },
724 { 0x30, "Indonesian (formerly in) (id)" },
725 { 0x31, "Wolof (wo)" },
726 { 0x32, "Xhosa (xh)" },
727 { 0x33, "Icelandic (is)" },
728 { 0x34, "Italian (it)" },
729 { 0x35, "Yoruba (yo)" },
730 { 0x36, "Japanese (ja)" },
731 { 0x37, "Javanese (jw)" },
732 { 0x38, "Georgian (ka)" },
733 { 0x39, "Kazakh (kk)" },
734 { 0x3A, "Zhuang (za)" },
735 { 0x3B, "Cambodian (km)" },
736 { 0x3C, "Kannada (kn)" },
737 { 0x3D, "Korean (ko)" },
738 { 0x3E, "Kashmiri (ks)" },
739 { 0x3F, "Kurdish (ku)" },
740 { 0x40, "Kirghiz (ky)" },
741 { 0x41, "Chinese (zh)" },
742 { 0x42, "Lingala (ln)" },
743 { 0x43, "Laothian (lo)" },
744 { 0x44, "Lithuanian (lt)" },
745 { 0x45, "Latvian, Lettish (lv)" },
746 { 0x46, "Malagasy (mg)" },
747 { 0x47, "Maori (mi)" },
748 { 0x48, "Macedonian (mk)" },
749 { 0x49, "Malayalam (ml)" },
750 { 0x4A, "Mongolian (mn)" },
751 { 0x4B, "Moldavian (mo)" },
752 { 0x4C, "Marathi (mr)" },
753 { 0x4D, "Malay (ms)" },
754 { 0x4E, "Maltese (mt)" },
755 { 0x4F, "Burmese (my)" },
756 { 0x50, "Ukrainian (uk)" },
757 { 0x51, "Nepali (ne)" },
758 { 0x52, "Dutch (nl)" },
759 { 0x53, "Norwegian (no)" },
760 { 0x54, "Occitan (oc)" },
761 { 0x55, "(Afan) Oromo (om)" },
762 { 0x56, "Oriya (or)" },
763 { 0x57, "Punjabi (pa)" },
764 { 0x58, "Polish (po)" },
765 { 0x59, "Pashto, Pushto (ps)" },
766 { 0x5A, "Portuguese (pt)" },
767 { 0x5B, "Quechua (qu)" },
768 { 0x5C, "Zulu (zu)" },
769 { 0x5D, "Kirundi (rn)" },
770 { 0x5E, "Romanian (ro)" },
771 { 0x5F, "Russian (ru)" },
772 { 0x60, "Kinyarwanda (rw)" },
773 { 0x61, "Sanskrit (sa)" },
774 { 0x62, "Sindhi (sd)" },
775 { 0x63, "Sangho (sg)" },
776 { 0x64, "Serbo-Croatian (sh)" },
777 { 0x65, "Sinhalese (si)" },
778 { 0x66, "Slovak (sk)" },
779 { 0x67, "Slovenian (sl)" },
780 { 0x68, "Samoan (sm)" },
781 { 0x69, "Shona (sn)" },
782 { 0x6A, "Somali (so)" },
783 { 0x6B, "Albanian (sq)" },
784 { 0x6C, "Serbian (sr)" },
785 { 0x6D, "Siswati (ss)" },
786 { 0x6E, "Sesotho (st)" },
787 { 0x6F, "Sundanese (su)" },
788 { 0x70, "Swedish (sv)" },
789 { 0x71, "Swahili (sw)" },
790 { 0x72, "Tamil (ta)" },
791 { 0x73, "Telugu (te)" },
792 { 0x74, "Tajik (tg)" },
793 { 0x75, "Thai (th)" },
794 { 0x76, "Tigrinya (ti)" },
795 { 0x77, "Turkmen (tk)" },
796 { 0x78, "Tagalog (tl)" },
797 { 0x79, "Setswana (tn)" },
798 { 0x7A, "Tonga (to)" },
799 { 0x7B, "Turkish (tr)" },
800 { 0x7C, "Tsonga (ts)" },
801 { 0x7D, "Tatar (tt)" },
802 { 0x7E, "Twi (tw)" },
803 { 0x7F, "Uighur (ug)" },
804 { 0x81, "Nauru (na)" },
805 { 0x82, "Faeroese (fo)" },
806 { 0x83, "Frisian (fy)" },
807 { 0x84, "Interlingua (ia)" },
808 { 0x85, "Volapuk (vo)" },
809 { 0x86, "Interlingue (ie)" },
810 { 0x87, "Inupiak (ik)" },
811 { 0x88, "Yiddish (formerly ji) (yi)" },
812 { 0x89, "Inuktitut (iu)" },
813 { 0x8A, "Greenlandic (kl)" },
814 { 0x8B, "Latin (la)" },
815 { 0x8C, "Rhaeto-Romance (rm)" },
819 static const value_string vals_accept_ranges[] = {
825 #define NO_CACHE 0x00
826 #define NO_STORE 0x01
828 #define MAX_STALE 0x03
829 #define MIN_FRESH 0x04
830 #define ONLY_IF_CACHED 0x05
833 #define NO_TRANSFORM 0x08
834 #define MUST_REVALIDATE 0x09
835 #define PROXY_REVALIDATE 0x0A
836 #define S_MAXAGE 0x0B
838 static const value_string vals_cache_control[] = {
839 { NO_CACHE, "No-cache" },
840 { NO_STORE, "No-store" },
841 { MAX_AGE, "Max-age" },
842 { MAX_STALE, "Max-stale" },
843 { MIN_FRESH, "Min-fresh" },
844 { ONLY_IF_CACHED, "Only-if-cached" },
845 { PUBLIC, "Public" },
846 { PRIVATE, "Private" },
847 { NO_TRANSFORM, "No-transform" },
848 { MUST_REVALIDATE, "Must-revalidate" },
849 { PROXY_REVALIDATE, "Proxy-revalidate" },
850 { S_MAXAGE, "S-max-age" },
854 static const value_string vals_connection[] = {
859 static const value_string vals_transfer_encoding[] = {
867 #define PERMANENT_REDIRECT 0x80
868 #define REUSE_SECURITY_SESSION 0x40
871 * Redirect address flags and length.
873 #define BEARER_TYPE_INCLUDED 0x80
874 #define PORT_NUMBER_INCLUDED 0x40
875 #define ADDRESS_LEN 0x3f
877 static const true_false_string yes_no_truth = {
883 * Windows appears to define DELETE.
893 REDIRECT = 0x03, /* No sample data */
896 PUSH = 0x06, /* No sample data */
897 CONFIRMEDPUSH = 0x07, /* No sample data */
898 SUSPEND = 0x08, /* No sample data */
899 RESUME = 0x09, /* No sample data */
902 OPTIONS = 0x41, /* No sample data */
903 HEAD = 0x42, /* No sample data */
904 DELETE = 0x43, /* No sample data */
905 TRACE = 0x44, /* No sample data */
908 PUT = 0x61, /* No sample data */
913 VALUE_IS_TEXT_STRING,
917 static dissector_table_t wsp_dissector_table;
918 static heur_dissector_list_t heur_subdissector_list;
920 static void add_uri (proto_tree *, packet_info *, tvbuff_t *, guint, guint);
921 static void add_headers (proto_tree *, tvbuff_t *);
922 static int add_well_known_header (proto_tree *, tvbuff_t *, int, guint8);
923 static int add_unknown_header (proto_tree *, tvbuff_t *, int, guint8);
924 static int add_application_header (proto_tree *, tvbuff_t *, int);
925 static void add_accept_header (proto_tree *, tvbuff_t *, int,
926 tvbuff_t *, value_type_t, int);
927 static void add_accept_xxx_header (proto_tree *, tvbuff_t *, int,
928 tvbuff_t *, value_type_t, int, int, int, const value_string *,
930 static void add_accept_ranges_header (proto_tree *, tvbuff_t *, int,
931 tvbuff_t *, value_type_t, int);
932 static void add_cache_control_header (proto_tree *, tvbuff_t *, int,
933 tvbuff_t *, value_type_t, int);
934 static int add_cache_control_field_name (proto_tree *, tvbuff_t *, int, guint);
935 static void add_connection_header (proto_tree *, tvbuff_t *, int,
936 tvbuff_t *, value_type_t, int);
937 static void add_content_type_value (proto_tree *, tvbuff_t *, int, int,
938 tvbuff_t *, value_type_t, int, int, int, guint *, const char **);
939 static void add_wap_application_id_header (proto_tree *, tvbuff_t *, int,
940 tvbuff_t *, value_type_t, int);
941 static void add_integer_value_header_common (proto_tree *, tvbuff_t *, int,
942 tvbuff_t *, value_type_t, int, int, guint8, const value_string *);
943 static void add_integer_value_header (proto_tree *, tvbuff_t *, int,
944 tvbuff_t *, value_type_t, int, int, guint8);
945 static void add_string_value_header_common (proto_tree *, tvbuff_t *, int,
946 tvbuff_t *, value_type_t, int, int, guint8, const value_string *);
947 static void add_string_value_header (proto_tree *, tvbuff_t *, int,
948 tvbuff_t *, value_type_t, int, int, guint8);
949 static void add_quoted_string_value_header (proto_tree *, tvbuff_t *, int,
950 tvbuff_t *, value_type_t, int, int, guint8);
951 static void add_date_value_header (proto_tree *, tvbuff_t *, int,
952 tvbuff_t *, value_type_t, int, int, guint8);
953 static int add_parameter (proto_tree *, tvbuff_t *, int);
954 static int add_untyped_parameter (proto_tree *, tvbuff_t *, int, int);
955 static int add_parameter_charset (proto_tree *, tvbuff_t *, int, int);
956 static int add_constrained_encoding (proto_tree *, tvbuff_t *, int, int);
957 static int add_parameter_type (proto_tree *, tvbuff_t *, int, int);
958 static int add_parameter_text (proto_tree *, tvbuff_t *, int, int, int, const char *);
959 static void add_post_data (proto_tree *, tvbuff_t *, guint, const char *);
960 static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
961 static void add_pragma_header (proto_tree *, tvbuff_t *, int, tvbuff_t *,
963 static void add_transfer_encoding_header (proto_tree *, tvbuff_t *, int,
964 tvbuff_t *, value_type_t, int);
965 static void add_warning_header (proto_tree *, tvbuff_t *, int, tvbuff_t *,
967 static void add_accept_application_header (proto_tree *, tvbuff_t *, int,
968 tvbuff_t *, value_type_t, int);
969 static void add_capabilities (proto_tree *tree, tvbuff_t *tvb, int type);
970 static void add_capability_vals(tvbuff_t *, gboolean, int, guint, guint, char *, size_t);
971 static value_type_t get_value_type_len (tvbuff_t *, int, guint *, int *, int *);
972 static guint get_uintvar (tvbuff_t *, guint, guint);
973 static gint get_integer (tvbuff_t *, guint, guint, value_type_t, guint *);
975 static int add_well_known_openwave_header (proto_tree *, tvbuff_t *, int, guint8);
976 static void add_openwave_integer_value_header (proto_tree *, tvbuff_t *, int,
977 tvbuff_t *, value_type_t, int, int, guint8);
978 static void add_openwave_string_value_header (proto_tree *, tvbuff_t *, int,
979 tvbuff_t *, value_type_t, int, int, guint8);
982 /* Code to actually dissect the packets */
984 dissect_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo,
985 proto_tree *tree, dissector_handle_t dissector_handle)
989 proto_tree *flags_tree;
991 guint8 address_flags_len;
993 proto_tree *atf_tree;
995 guint32 address_ipv4;
996 struct e_in6_addr address_ipv6;
997 address redir_address;
998 conversation_t *conv;
1000 flags = tvb_get_guint8 (tvb, offset);
1002 ti = proto_tree_add_uint (tree, hf_wsp_redirect_flags,
1003 tvb, offset, 1, flags);
1004 flags_tree = proto_item_add_subtree (ti, ett_redirect_flags);
1005 proto_tree_add_boolean (flags_tree, hf_wsp_redirect_permanent,
1006 tvb, offset, 1, flags);
1007 proto_tree_add_boolean (flags_tree, hf_wsp_redirect_reuse_security_session,
1008 tvb, offset, 1, flags);
1011 while (tvb_reported_length_remaining (tvb, offset) > 0) {
1012 address_flags_len = tvb_get_guint8 (tvb, offset);
1014 ti = proto_tree_add_uint (tree, hf_wsp_redirect_afl,
1015 tvb, offset, 1, address_flags_len);
1016 atf_tree = proto_item_add_subtree (ti, ett_redirect_afl);
1017 proto_tree_add_boolean (atf_tree, hf_wsp_redirect_afl_bearer_type_included,
1018 tvb, offset, 1, address_flags_len);
1019 proto_tree_add_boolean (atf_tree, hf_wsp_redirect_afl_port_number_included,
1020 tvb, offset, 1, address_flags_len);
1021 proto_tree_add_uint (atf_tree, hf_wsp_redirect_afl_address_len,
1022 tvb, offset, 1, address_flags_len);
1025 if (address_flags_len & BEARER_TYPE_INCLUDED) {
1026 bearer_type = tvb_get_guint8 (tvb, offset);
1028 proto_tree_add_uint (tree, hf_wsp_redirect_bearer_type,
1029 tvb, offset, 1, bearer_type);
1033 bearer_type = 0x00; /* XXX */
1034 if (address_flags_len & PORT_NUMBER_INCLUDED) {
1035 port_num = tvb_get_ntohs (tvb, offset);
1037 proto_tree_add_uint (tree, hf_wsp_redirect_port_num,
1038 tvb, offset, 2, port_num);
1043 * Redirecting to the same server port number as was
1044 * being used, i.e. the source port number of this
1047 port_num = pinfo->srcport;
1049 address_len = address_flags_len & ADDRESS_LEN;
1050 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
1052 * We don't have the bearer type in the message,
1053 * so we don't know the address type.
1054 * (It's the same bearer type as the original
1057 goto unknown_address_type;
1061 * We know the bearer type, so we know the address type.
1063 switch (bearer_type) {
1067 case BT_IS_95_PACKET_DATA:
1068 case BT_ANSI_136_CSD:
1069 case BT_ANSI_136_PACKET_DATA:
1072 case BT_GSM_USSD_IPv4:
1075 case BT_PDC_PACKET_DATA:
1077 case BT_IDEN_PACKET_DATA:
1079 case BT_TETRA_PACKET_DATA:
1083 if (address_len != 4) {
1087 goto unknown_address_type;
1089 tvb_memcpy(tvb, (guint8 *)&address_ipv4, offset, 4);
1091 proto_tree_add_ipv4 (tree,
1092 hf_wsp_redirect_ipv4_addr,
1093 tvb, offset, 4, address_ipv4);
1097 * Create a conversation so that the
1098 * redirected session will be dissected
1101 redir_address.type = AT_IPv4;
1102 redir_address.len = 4;
1103 redir_address.data = (const guint8 *)&address_ipv4;
1104 conv = find_conversation(&redir_address, &pinfo->dst,
1105 PT_UDP, port_num, 0, NO_PORT_B);
1107 conv = conversation_new(&redir_address,
1108 &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
1110 conversation_set_dissector(conv, dissector_handle);
1117 if (address_len != 16) {
1121 goto unknown_address_type;
1123 tvb_memcpy(tvb, (guint8 *)&address_ipv6, offset, 16);
1125 proto_tree_add_ipv6 (tree,
1126 hf_wsp_redirect_ipv6_addr,
1127 tvb, offset, 16, (guint8 *)&address_ipv6);
1131 * Create a conversation so that the
1132 * redirected session will be dissected
1135 redir_address.type = AT_IPv6;
1136 redir_address.len = 16;
1137 redir_address.data = (const guint8 *)&address_ipv4;
1138 conv = find_conversation(&redir_address, &pinfo->dst,
1139 PT_UDP, port_num, 0, NO_PORT_B);
1141 conv = conversation_new(&redir_address,
1142 &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
1144 conversation_set_dissector(conv, dissector_handle);
1147 unknown_address_type:
1149 if (address_len != 0) {
1151 proto_tree_add_item (tree,
1152 hf_wsp_redirect_addr,
1153 tvb, offset, address_len,
1159 offset += address_len;
1164 dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1165 dissector_handle_t dissector_handle, gboolean is_connectionless)
1172 guint uriLength = 0;
1174 guint capabilityLength = 0;
1175 guint capabilityStart = 0;
1176 guint headersLength = 0;
1177 guint headerLength = 0;
1178 guint headerStart = 0;
1179 guint nextOffset = 0;
1180 guint contentTypeStart = 0;
1181 guint contentType = 0;
1182 const char *contentTypeStr;
1185 /* Set up structures we will need to add the protocol subtree and manage it */
1187 proto_tree *wsp_tree = NULL;
1188 /* proto_tree *wsp_header_fixed; */
1190 /* This field shows up as the "Info" column in the display; you should make
1191 it, if possible, summarize what's in the packet, so that a user looking
1192 at the list of packets can tell what type of packet it is. */
1194 /* Connection-less mode has a TID first */
1195 if (is_connectionless)
1200 /* Find the PDU type */
1201 pdut = tvb_get_guint8 (tvb, offset);
1203 /* Develop the string to put in the Info column */
1204 if (check_col(pinfo->cinfo, COL_INFO))
1206 col_append_fstr(pinfo->cinfo, COL_INFO, "WSP %s",
1207 val_to_str (pdut, vals_pdu_type, "Unknown PDU type (0x%02x)"));
1210 /* In the interest of speed, if "tree" is NULL, don't do any work not
1211 necessary to generate protocol tree items. */
1213 ti = proto_tree_add_item(tree, proto_wsp, tvb, 0, -1,
1215 wsp_tree = proto_item_add_subtree(ti, ett_wsp);
1217 /* Code to process the packet goes here */
1219 wsp_header_fixed = proto_item_add_subtree(ti, ett_header );
1222 /* Add common items: only TID and PDU Type */
1224 /* If this is connectionless, then the TID Field is always first */
1225 if (is_connectionless)
1227 ti = proto_tree_add_item (wsp_tree, hf_wsp_header_tid,tvb,
1228 0,1,bo_little_endian);
1231 ti = proto_tree_add_item(
1232 wsp_tree, /* tree */
1233 hf_wsp_header_pdu_type, /* id */
1235 offset, /* start of high light */
1236 1, /* length of high light */
1237 bo_little_endian /* value */
1248 if (pdut == CONNECT)
1250 ti = proto_tree_add_item (wsp_tree, hf_wsp_version_major,tvb,offset,1,bo_little_endian);
1251 ti = proto_tree_add_item (wsp_tree, hf_wsp_version_minor,tvb,offset,1,bo_little_endian);
1254 count = 0; /* Initialise count */
1255 value = tvb_get_guintvar (tvb, offset, &count);
1256 ti = proto_tree_add_uint (wsp_tree, hf_wsp_server_session_id,tvb,offset,count,value);
1259 capabilityStart = offset;
1260 count = 0; /* Initialise count */
1261 capabilityLength = tvb_get_guintvar (tvb, offset, &count);
1263 ti = proto_tree_add_uint (wsp_tree, hf_wsp_capability_length,tvb,capabilityStart,count,capabilityLength);
1267 count = 0; /* Initialise count */
1268 headerLength = tvb_get_guintvar (tvb, offset, &count);
1269 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,offset,count,headerLength);
1271 capabilityStart = offset;
1272 headerStart = capabilityStart + capabilityLength;
1274 /* Resume computes the headerlength by remaining bytes */
1275 capabilityStart = offset;
1276 headerStart = capabilityStart + capabilityLength;
1277 headerLength = tvb_reported_length_remaining (tvb, headerStart);
1279 if (capabilityLength > 0)
1281 tmp_tvb = tvb_new_subset (tvb, offset, capabilityLength, capabilityLength);
1282 add_capabilities (wsp_tree, tmp_tvb, pdut);
1283 offset += capabilityLength;
1286 if (headerLength > 0)
1288 tmp_tvb = tvb_new_subset (tvb, offset, headerLength, headerLength);
1289 add_headers (wsp_tree, tmp_tvb);
1296 dissect_redirect(tvb, offset, pinfo, wsp_tree,
1303 count = 0; /* Initialise count */
1304 value = tvb_get_guintvar (tvb, offset, &count);
1305 ti = proto_tree_add_uint (wsp_tree, hf_wsp_server_session_id,tvb,offset,count,value);
1310 count = 0; /* Initialise count */
1311 /* Length of URI and size of URILen field */
1312 value = tvb_get_guintvar (tvb, offset, &count);
1313 nextOffset = offset + count;
1314 add_uri (wsp_tree, pinfo, tvb, offset, nextOffset);
1316 offset += (value+count); /* VERIFY */
1317 tmp_tvb = tvb_new_subset (tvb, offset, -1, -1);
1318 add_headers (wsp_tree, tmp_tvb);
1324 count = 0; /* Initialise count */
1325 uriLength = tvb_get_guintvar (tvb, offset, &count);
1326 headerStart = uriStart+count;
1327 count = 0; /* Initialise count */
1328 headersLength = tvb_get_guintvar (tvb, headerStart, &count);
1329 offset = headerStart + count;
1331 add_uri (wsp_tree, pinfo, tvb, uriStart, offset);
1333 offset += uriLength;
1335 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,headerStart,count,headersLength);
1337 if (headersLength == 0)
1340 contentTypeStart = offset;
1341 nextOffset = add_content_type (wsp_tree,
1342 tvb, offset, &contentType,
1345 /* Add headers subtree that will hold the headers fields */
1346 /* Runs from nextOffset for headersLength-(length of content-type field)*/
1347 headerLength = headersLength-(nextOffset-contentTypeStart);
1348 if (headerLength > 0)
1350 tmp_tvb = tvb_new_subset (tvb, nextOffset, headerLength, headerLength);
1351 add_headers (wsp_tree, tmp_tvb);
1354 /* TODO: Post DATA */
1355 /* Runs from start of headers+headerLength to end of frame */
1356 offset = nextOffset+headerLength;
1357 tmp_tvb = tvb_new_subset (tvb, offset, tvb_reported_length (tvb)-offset, tvb_reported_length (tvb)-offset);
1358 add_post_data (wsp_tree, tmp_tvb,
1359 contentType, contentTypeStr);
1361 if (tvb_reported_length_remaining(tvb, headerStart + count + uriLength + headersLength) > 0)
1363 tmp_tvb = tvb_new_subset (tvb, headerStart + count + uriLength + headersLength, -1, -1);
1364 if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
1365 dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
1370 count = 0; /* Initialise count */
1371 headersLength = tvb_get_guintvar (tvb, offset+1, &count);
1372 headerStart = offset + count + 1;
1374 ti = proto_tree_add_item (wsp_tree, hf_wsp_header_status,tvb,offset,1,bo_little_endian);
1375 nextOffset = offset + 1 + count;
1376 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,offset+1,count,headersLength);
1378 if (headersLength == 0)
1381 contentTypeStart = nextOffset;
1382 nextOffset = add_content_type (wsp_tree,
1383 tvb, nextOffset, &contentType,
1386 /* Add headers subtree that will hold the headers fields */
1387 /* Runs from nextOffset for headersLength-(length of content-type field)*/
1388 headerLength = headersLength-(nextOffset-contentTypeStart);
1389 if (headerLength > 0)
1391 tmp_tvb = tvb_new_subset (tvb, nextOffset, headerLength, headerLength);
1392 add_headers (wsp_tree, tmp_tvb);
1394 offset += count+headersLength+1;
1396 /* TODO: Data - decode WMLC */
1397 /* Runs from offset+1+count+headerLength+1 to end of frame */
1398 if (tvb_reported_length_remaining (tvb, offset) > 0)
1400 ti = proto_tree_add_item (wsp_tree, hf_wsp_reply_data,tvb,offset,-1,bo_little_endian);
1403 if (tvb_reported_length_remaining(tvb, headerStart + headersLength) > 0)
1405 tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength, -1, -1);
1406 if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
1407 dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
1413 count = 0; /* Initialise count */
1414 headersLength = tvb_get_guintvar (tvb, offset, &count);
1415 headerStart = offset + count;
1418 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,offset,count,headersLength);
1420 if (headersLength == 0)
1424 contentTypeStart = offset;
1425 nextOffset = add_content_type (wsp_tree,
1426 tvb, offset, &contentType,
1429 /* Add headers subtree that will hold the headers fields */
1430 /* Runs from nextOffset for headersLength-(length of content-type field)*/
1431 headerLength = headersLength-(nextOffset-contentTypeStart);
1432 if (headerLength > 0)
1434 tmp_tvb = tvb_new_subset (tvb, nextOffset, headerLength, headerLength);
1435 add_headers (wsp_tree, tmp_tvb);
1437 offset += headersLength;
1440 if (tvb_reported_length_remaining (tvb, offset) > 0)
1442 ti = proto_tree_add_item (wsp_tree, hf_wsp_push_data,tvb,offset,-1,bo_little_endian);
1445 if (tvb_reported_length_remaining(tvb, headerStart + headersLength) > 0)
1447 tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength, -1, -1);
1448 if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
1449 dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
1457 * Called directly from UDP.
1458 * Put "WSP" into the "Protocol" column.
1461 dissect_wsp_fromudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1463 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1464 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSP" );
1465 if (check_col(pinfo->cinfo, COL_INFO))
1466 col_clear(pinfo->cinfo, COL_INFO);
1468 dissect_wsp_common(tvb, pinfo, tree, wsp_fromudp_handle, TRUE);
1472 * Called from a higher-level WAP dissector, in connection-oriented mode.
1473 * Leave the "Protocol" column alone - the dissector calling us should
1477 dissect_wsp_fromwap_co(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1480 * XXX - what about WTLS->WTP->WSP?
1482 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, FALSE);
1486 * Called from a higher-level WAP dissector, in connectionless mode.
1487 * Leave the "Protocol" column alone - the dissector calling us should
1491 dissect_wsp_fromwap_cl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1494 * XXX - what about WTLS->WSP?
1496 if (check_col(pinfo->cinfo, COL_INFO))
1498 col_clear(pinfo->cinfo, COL_INFO);
1500 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, TRUE);
1504 add_uri (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint URILenOffset, guint URIOffset)
1510 guint uriLen = tvb_get_guintvar (tvb, URILenOffset, &count);
1513 ti = proto_tree_add_uint (tree, hf_wsp_header_uri_len,tvb,URILenOffset,count,uriLen);
1515 newBuffer = g_malloc (uriLen+2);
1516 newBuffer[0] = ' '; /* This is for COL_INFO */
1517 strncpy (newBuffer+1, tvb_get_ptr (tvb, URIOffset, uriLen), uriLen);
1518 newBuffer[uriLen+1] = 0;
1520 ti = proto_tree_add_string (tree, hf_wsp_header_uri,tvb,URIOffset,uriLen,newBuffer+1);
1521 if (check_col(pinfo->cinfo, COL_INFO)) {
1522 col_append_str(pinfo->cinfo, COL_INFO, newBuffer);
1528 add_headers (proto_tree *tree, tvbuff_t *tvb)
1531 proto_tree *wsp_headers;
1533 guint headersLen = tvb_reported_length (tvb);
1534 guint headerStart = 0;
1539 fprintf (stderr, "dissect_wsp: Offset is %d, size is %d\n", offset, headersLen);
1543 if (headersLen <= 0)
1549 fprintf (stderr, "dissect_wsp: Headers to process\n");
1552 ti = proto_tree_add_item (tree, hf_wsp_headers_section,tvb,offset,headersLen,bo_little_endian);
1553 wsp_headers = proto_item_add_subtree( ti, ett_headers );
1557 while (offset < headersLen)
1559 /* Loop round each header */
1560 headerStart = offset;
1561 peek = tvb_get_guint8 (tvb, headerStart);
1563 if (peek < 32) /* Short-cut shift delimiter */
1566 proto_tree_add_uint (wsp_headers,
1567 hf_wsp_header_shift_code, tvb, offset, 1,
1572 else if (peek == 0x7F) /* Shift delimiter */
1574 pageCode = tvb_get_guint8(tvb, offset+1);
1575 proto_tree_add_uint (wsp_headers,
1576 hf_wsp_header_shift_code, tvb, offset, 2,
1581 else if (peek < 127)
1584 fprintf (stderr, "dissect_wsp: header: application-header start %d (0x%02X)\n", peek, peek);
1587 * Token-text, followed by Application-specific-value.
1589 offset = add_application_header (wsp_headers, tvb,
1592 else if (peek & 0x80)
1595 fprintf (stderr, "dissect_wsp: header: well-known %d (0x%02X)\n", peek, peek);
1598 * Well-known-header; the lower 7 bits of "peek"
1599 * are the header code.
1603 offset = add_well_known_header (wsp_headers,
1604 tvb, headerStart, peek & 0x7F);
1609 offset = add_well_known_openwave_header (wsp_headers,
1610 tvb, headerStart, peek & 0x7F);
1614 offset = add_unknown_header (wsp_headers,
1615 tvb, headerStart, peek & 0x7F);
1623 add_well_known_header (proto_tree *tree, tvbuff_t *tvb, int offset,
1627 value_type_t valueType;
1631 tvbuff_t *header_buff;
1632 tvbuff_t *value_buff;
1635 fprintf (stderr, "dissect_wsp: Got header 0x%02x\n", headerType);
1637 headerStart = offset;
1640 * Skip the Short-Integer header type.
1645 * Get the value type and length (or, if the type is VALUE_IN_LEN,
1646 * meaning the value is a Short-integer, get the value type
1647 * and the value itself).
1649 valueType = get_value_type_len (tvb, offset, &valueLen,
1650 &valueStart, &offset);
1651 headerLen = offset - headerStart;
1654 * Get a tvbuff for the entire header.
1655 * XXX - cut the actual length short so that it doesn't run
1656 * past the actual length of tvb.
1658 header_buff = tvb_new_subset (tvb, headerStart, headerLen,
1662 * If the value wasn't in the length, get a tvbuff for the value.
1663 * XXX - can valueLen be 0?
1664 * XXX - cut the actual length short so that it doesn't run
1665 * past the actual length of tvb.
1667 if (valueType != VALUE_IN_LEN) {
1668 value_buff = tvb_new_subset (tvb, valueStart, valueLen,
1672 * XXX - when the last dissector is tvbuffified,
1673 * so that NULL is no longer a valid tvb pointer
1674 * value in "proto_tree_add" calls, just
1675 * set "value_buff" to NULL.
1677 * XXX - can we already do that? I.e., will that
1678 * cause us always to crash if we mistakenly try
1679 * to fetch the value of a VALUE_IN_LEN item?
1681 value_buff = tvb_new_subset (tvb, headerStart, 0, 0);
1684 switch (headerType) {
1686 case FN_ACCEPT: /* Accept */
1687 add_accept_header (tree, header_buff, headerLen,
1688 value_buff, valueType, valueLen);
1691 case FN_ACCEPT_CHARSET_DEP: /* Accept-Charset */
1693 * XXX - should both encoding versions 1.1 and
1694 * 1.3 be handled this way?
1696 add_accept_xxx_header (tree, header_buff, headerLen,
1697 value_buff, valueType, valueLen,
1698 hf_wsp_header_accept_charset,
1699 hf_wsp_header_accept_charset_str,
1700 vals_character_sets, "Unknown charset (%u)");
1703 case FN_ACCEPT_LANGUAGE: /* Accept-Language */
1704 add_accept_xxx_header (tree, header_buff, headerLen,
1705 value_buff, valueType, valueLen,
1706 hf_wsp_header_accept_language,
1707 hf_wsp_header_accept_language_str,
1708 vals_languages, "Unknown language (%u)");
1711 case FN_ACCEPT_RANGES: /* Accept-Ranges */
1712 add_accept_ranges_header (tree, header_buff, headerLen,
1713 value_buff, valueType, valueLen);
1716 case FN_AGE: /* Age */
1717 add_integer_value_header (tree, header_buff, headerLen,
1718 value_buff, valueType, valueLen, hf_wsp_header_age,
1722 case FN_CACHE_CONTROL_DEP: /* Cache-Control */
1723 case FN_CACHE_CONTROL:
1724 case FN_CACHE_CONTROL14:
1726 * XXX - is the only difference in the three different
1727 * versions (1.1, 1.3, 1.4) really only S_MAXAGE?
1729 add_cache_control_header (tree, header_buff, headerLen,
1730 value_buff, valueType, valueLen);
1733 case FN_CONNECTION: /* Connection */
1734 add_connection_header (tree, header_buff, headerLen,
1735 value_buff, valueType, valueLen);
1738 case FN_CONTENT_LENGTH: /* Content-Length */
1739 add_integer_value_header (tree, header_buff, headerLen,
1740 value_buff, valueType, valueLen,
1741 hf_wsp_header_content_length,
1745 case FN_DATE: /* Date */
1746 add_date_value_header (tree, header_buff, headerLen,
1747 value_buff, valueType, valueLen,
1748 hf_wsp_header_date, headerType);
1751 case FN_ETAG: /* Etag */
1752 add_string_value_header (tree, header_buff, headerLen,
1753 value_buff, valueType, valueLen,
1754 hf_wsp_header_etag, headerType);
1757 case FN_EXPIRES: /* Expires */
1758 add_date_value_header (tree, header_buff, headerLen,
1759 value_buff, valueType, valueLen,
1760 hf_wsp_header_expires, headerType);
1763 case FN_IF_MODIFIED_SINCE: /* If-Modified-Since */
1764 add_date_value_header (tree, header_buff, headerLen,
1765 value_buff, valueType, valueLen,
1766 hf_wsp_header_if_modified_since, headerType);
1769 case FN_LOCATION: /* Location */
1770 add_string_value_header (tree, header_buff, headerLen,
1771 value_buff, valueType, valueLen,
1772 hf_wsp_header_location, headerType);
1775 case FN_LAST_MODIFIED: /* Last-Modified */
1776 add_date_value_header (tree, header_buff, headerLen,
1777 value_buff, valueType, valueLen,
1778 hf_wsp_header_last_modified, headerType);
1781 case FN_PRAGMA: /* Pragma */
1782 add_pragma_header (tree, header_buff, headerLen,
1783 value_buff, valueType, valueLen);
1786 case FN_SERVER: /* Server */
1787 add_string_value_header (tree, header_buff, headerLen,
1788 value_buff, valueType, valueLen,
1789 hf_wsp_header_server, headerType);
1792 case FN_TRANSFER_ENCODING: /* Transfer-Encoding */
1793 add_transfer_encoding_header (tree, header_buff, headerLen,
1794 value_buff, valueType, valueLen);
1797 case FN_USER_AGENT: /* User-Agent */
1798 add_string_value_header (tree, header_buff, headerLen,
1799 value_buff, valueType, valueLen,
1800 hf_wsp_header_user_agent, headerType);
1803 case FN_VIA: /* Via */
1804 add_string_value_header (tree, header_buff, headerLen,
1805 value_buff, valueType, valueLen,
1806 hf_wsp_header_via, headerType);
1809 case FN_WARNING: /* Warning */
1810 add_warning_header (tree, header_buff, headerLen,
1811 value_buff, valueType, valueLen);
1814 case FN_ACCEPT_APPLICATION: /* Accept-Application */
1815 add_accept_application_header (tree, header_buff, headerLen,
1816 value_buff, valueType, valueLen);
1819 case FN_BEARER_INDICATION: /* Bearer-Indication */
1820 add_integer_value_header (tree, header_buff, headerLen,
1821 value_buff, valueType, valueLen,
1822 hf_wsp_header_bearer_indication, headerType);
1825 case FN_PROFILE: /* Profile */
1826 add_string_value_header (tree, header_buff, headerLen,
1827 value_buff, valueType, valueLen,
1828 hf_wsp_header_profile, headerType);
1831 case FN_X_WAP_APPLICATION_ID: /* X-Wap-Application-Id */
1832 add_wap_application_id_header (tree, header_buff, headerLen,
1833 value_buff, valueType, valueLen);
1836 case FN_CONTENT_ID: /* Content-ID */
1837 add_quoted_string_value_header (tree, header_buff, headerLen,
1838 value_buff, valueType, valueLen,
1839 hf_wsp_header_content_ID, headerType);
1843 proto_tree_add_text (tree, header_buff, 0, headerLen,
1844 "Unsupported Header: %s",
1845 val_to_str (headerType, vals_field_names, "Unknown (0x%02X)"));
1853 add_well_known_openwave_header (proto_tree *tree, tvbuff_t *tvb, int offset,
1857 value_type_t valueType;
1861 tvbuff_t *header_buff;
1862 tvbuff_t *value_buff;
1865 fprintf (stderr, "dissect_wsp: Got Openwave header 0x%02x\n", headerType);
1867 headerStart = offset;
1870 * Skip the Short-Integer header type.
1875 * Get the value type and length (or, if the type is VALUE_IN_LEN,
1876 * meaning the value is a Short-integer, get the value type
1877 * and the value itself).
1879 valueType = get_value_type_len (tvb, offset, &valueLen,
1880 &valueStart, &offset);
1881 headerLen = offset - headerStart;
1884 * Get a tvbuff for the entire header.
1885 * XXX - cut the actual length short so that it doesn't run
1886 * past the actual length of tvb.
1888 header_buff = tvb_new_subset (tvb, headerStart, headerLen,
1892 * If the value wasn't in the length, get a tvbuff for the value.
1893 * XXX - can valueLen be 0?
1894 * XXX - cut the actual length short so that it doesn't run
1895 * past the actual length of tvb.
1897 if (valueType != VALUE_IN_LEN) {
1898 value_buff = tvb_new_subset (tvb, valueStart, valueLen,
1902 * XXX - when the last dissector is tvbuffified,
1903 * so that NULL is no longer a valid tvb pointer
1904 * value in "proto_tree_add" calls, just
1905 * set "value_buff" to NULL.
1907 * XXX - can we already do that? I.e., will that
1908 * cause us always to crash if we mistakenly try
1909 * to fetch the value of a VALUE_IN_LEN item?
1911 value_buff = tvb_new_subset (tvb, headerStart, 0, 0);
1914 switch (headerType) {
1916 /* case FN_OPENWAVE_PROXY_PUSH_ADDR: / x-up-proxy-push-addr */
1917 /* add_openwave_push_address_header (tree, header_buff, headerLen, */
1918 /* value_buff, valueType, valueLen); */
1921 case FN_OPENWAVE_PROXY_PUSH_ACCEPT: /* x-up-proxy-push-accept */
1922 add_accept_header (tree, header_buff, headerLen,
1923 value_buff, valueType, valueLen);
1926 case FN_OPENWAVE_PROXY_PUSH_SEQ: /* x-up-proxy-push-seq */
1927 add_openwave_integer_value_header (tree, header_buff, headerLen,
1928 value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_push_seq,
1932 case FN_OPENWAVE_PROXY_NOTIFY: /* x-up-proxy-notify */
1933 add_openwave_integer_value_header (tree, header_buff, headerLen,
1934 value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_notify,
1938 case FN_OPENWAVE_PROXY_OPERATOR_DOMAIN: /* x-up-proxy-operator-domain */
1939 add_openwave_string_value_header (tree, header_buff, headerLen,
1940 value_buff, valueType, valueLen,
1941 hf_wsp_header_openwave_proxy_operator_domain, headerType);
1944 case FN_OPENWAVE_PROXY_HOME_PAGE: /* x-up-proxy-home-page */
1945 add_openwave_string_value_header (tree, header_buff, headerLen,
1946 value_buff, valueType, valueLen,
1947 hf_wsp_header_openwave_proxy_home_page, headerType);
1950 case FN_OPENWAVE_DEVCAP_HAS_COLOR: /* x-up-devcap-has-color */
1951 add_openwave_integer_value_header (tree, header_buff, headerLen,
1952 value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_has_color,
1956 case FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS: /* x-up-devcap-num-softkeys */
1957 add_openwave_integer_value_header (tree, header_buff, headerLen,
1958 value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_num_softkeys,
1962 case FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE: /* x-up-devcap-softkey-size */
1963 add_openwave_integer_value_header (tree, header_buff, headerLen,
1964 value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_softkey_size,
1968 /* case FN_OPENWAVE_DEVCAP_SCREEN_CHARS: / x-up-devcap-screen-chars */
1969 /* add_openwave_integer_value_header (tree, header_buff, headerLen, */
1970 /* value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_screen_chars, */
1974 /* case FN_OPENWAVE_DEVCAP_SCREEN_PIXELS: / x-up-devcap-screen-pixels */
1975 /* add_openwave_integer_value_header (tree, header_buff, headerLen, */
1976 /* value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_screen_pixels, */
1980 /* case FN_OPENWAVE_DEVCAP_EM_SIZE: / x-up-devcap-em-size */
1981 /* add_openwave_integer_value_header (tree, header_buff, headerLen, */
1982 /* value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_em_size, */
1986 case FN_OPENWAVE_DEVCAP_SCREEN_DEPTH: /* x-up-devcap-screen-depth */
1987 add_openwave_integer_value_header (tree, header_buff, headerLen,
1988 value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_screen_depth,
1992 case FN_OPENWAVE_DEVCAP_IMMED_ALERT: /* x-up-devcap-immed-alert */
1993 add_openwave_integer_value_header (tree, header_buff, headerLen,
1994 value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_immed_alert,
1998 case FN_OPENWAVE_PROXY_NET_ASK: /* x-up-proxy-net-ask */
1999 add_openwave_integer_value_header (tree, header_buff, headerLen,
2000 value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_net_ask,
2004 case FN_OPENWAVE_PROXY_UPLINK_VERSION: /* x-up-proxy-uplink-version */
2005 add_openwave_string_value_header (tree, header_buff, headerLen,
2006 value_buff, valueType, valueLen,
2007 hf_wsp_header_openwave_proxy_uplink_version, headerType);
2010 case FN_OPENWAVE_PROXY_TOD: /* x-up-proxy-tod */
2011 add_openwave_integer_value_header (tree, header_buff, headerLen,
2012 value_buff, valueType, valueLen,
2013 hf_wsp_header_openwave_proxy_tod, headerType);
2016 case FN_OPENWAVE_PROXY_BA_ENABLE: /* x-up-proxy-ba-enable */
2017 add_openwave_integer_value_header (tree, header_buff, headerLen,
2018 value_buff, valueType, valueLen,
2019 hf_wsp_header_openwave_proxy_ba_enable, headerType);
2022 case FN_OPENWAVE_PROXY_BA_REALM: /* x-up-proxy-ba-realm */
2023 add_openwave_string_value_header (tree, header_buff, headerLen,
2024 value_buff, valueType, valueLen,
2025 hf_wsp_header_openwave_proxy_ba_realm, headerType);
2028 case FN_OPENWAVE_PROXY_REDIRECT_ENABLE: /* x-up-proxy-redirect-enable */
2029 add_openwave_integer_value_header (tree, header_buff, headerLen,
2030 value_buff, valueType, valueLen,
2031 hf_wsp_header_openwave_proxy_redirect_enable, headerType);
2034 case FN_OPENWAVE_PROXY_REQUEST_URI: /* x-up-proxy-request-uri */
2035 add_openwave_string_value_header (tree, header_buff, headerLen,
2036 value_buff, valueType, valueLen,
2037 hf_wsp_header_openwave_proxy_request_uri, headerType);
2040 /* case FN_OPENWAVE_PROXY_REDIRECT_STATUS: / x-up-proxy-redirect-status */
2041 /* add_openwave_integer_value_header (tree, header_buff, headerLen, */
2042 /* value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_redirect_status, */
2046 case FN_OPENWAVE_PROXY_TRANS_CHARSET: /* x-up-proxy-trans-charset */
2047 add_accept_xxx_header (tree, header_buff, headerLen,
2048 value_buff, valueType, valueLen,
2049 hf_wsp_header_openwave_proxy_trans_charset,
2050 hf_wsp_header_openwave_proxy_trans_charset_str,
2051 vals_character_sets, "Unknown charset (%u)");
2054 case FN_OPENWAVE_PROXY_LINGER: /* x-up-proxy-linger */
2055 add_openwave_integer_value_header (tree, header_buff, headerLen,
2056 value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_linger,
2060 /* case FN_OPENWAVE_PROXY_CLIENT_ID: / x-up-proxy-client-id */
2061 /* add_openwave_string_value_header (tree, header_buff, headerLen, */
2062 /* value_buff, valueType, valueLen, */
2063 /* hf_wsp_header_openwave_proxy_client_id, headerType); */
2066 case FN_OPENWAVE_PROXY_ENABLE_TRUST: /* x-up-proxy-enable-trust */
2067 add_openwave_integer_value_header (tree, header_buff, headerLen,
2068 value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_enable_trust,
2072 case FN_OPENWAVE_PROXY_TRUST_OLD: /* x-up-proxy-trust old value */
2073 add_openwave_integer_value_header (tree, header_buff, headerLen,
2074 value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_trust_old,
2078 case FN_OPENWAVE_PROXY_TRUST: /* x-up-proxy-trust */
2079 add_openwave_integer_value_header (tree, header_buff, headerLen,
2080 value_buff, valueType, valueLen, hf_wsp_header_openwave_proxy_trust,
2084 case FN_OPENWAVE_PROXY_BOOKMARK: /* x-up-proxy-bookmark */
2085 add_openwave_string_value_header (tree, header_buff, headerLen,
2086 value_buff, valueType, valueLen,
2087 hf_wsp_header_openwave_proxy_bookmark, headerType);
2090 case FN_OPENWAVE_DEVCAP_GUI: /* x-up-devcap-gui */
2091 add_openwave_integer_value_header (tree, header_buff, headerLen,
2092 value_buff, valueType, valueLen, hf_wsp_header_openwave_devcap_gui,
2097 proto_tree_add_text (tree, header_buff, 0, headerLen,
2098 "Unsupported Openwave Header: %s",
2099 val_to_str (headerType, vals_openwave_field_names, "Unknown (0x%02X)"));
2107 add_openwave_push_address_header (proto_tree *tree, tvbuff_t *header_buff,
2108 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2118 add_unknown_header (proto_tree *tree, tvbuff_t *tvb, int offset,
2123 value_type_t valueType;
2128 headerStart = offset;
2131 * Skip the Short-Integer header type.
2135 valueStart = offset;
2138 * Get the value type and length (or, if the type is VALUE_IN_LEN,
2139 * meaning the value is a Short-integer, get the value type
2140 * and the value itself).
2142 valueType = get_value_type_len (tvb, valueStart, &valueLen,
2143 &valueOffset, &offset);
2144 headerLen = offset - headerStart;
2146 proto_tree_add_text (tree, tvb, headerStart, headerLen,
2147 "Unsupported Header (0x%02X)", headerType);
2152 add_application_header (proto_tree *tree, tvbuff_t *tvb, int offset)
2156 const guint8 *token;
2157 value_type_t valueType;
2165 startOffset = offset;
2166 tokenSize = tvb_strsize (tvb, startOffset);
2167 token = tvb_get_ptr (tvb, startOffset, tokenSize);
2168 offset += tokenSize;
2171 * Special case header "X-WAP.TOD" that is sometimes followed
2172 * by a 4-byte date value.
2174 * XXX - according to the 4-May-2000 WSP spec, X-Wap-Tod is
2175 * encoded as a well known header, with a code of 0x3F.
2177 if (tokenSize == 10 && strncasecmp ("x-wap.tod", token, 9) == 0)
2179 valueType = get_value_type_len (tvb, offset,
2180 &subvalueLen, &subvalueOffset, &offset);
2181 if (get_integer (tvb, subvalueOffset, subvalueLen,
2182 valueType, &secs) == 0)
2185 * Fill in the "struct timeval", and add it to the
2187 * Note: this will succeed even if it's a Short-integer.
2188 * A Short-integer would work, but, as the time values
2189 * are UNIX seconds-since-the-Epoch value, and as
2190 * there weren't WAP phones or Web servers back in
2191 * late 1969/early 1970, they're unlikely to be used.
2193 timeValue.secs = secs;
2194 timeValue.nsecs = 0;
2195 proto_tree_add_time (tree, hf_wsp_header_x_wap_tod,
2196 tvb, startOffset, offset - startOffset, &timeValue);
2200 proto_tree_add_text (tree, tvb, startOffset,
2201 offset - startOffset,
2202 "%s: invalid date value", token);
2208 stringSize = tvb_strsize (tvb, asvOffset);
2209 offset += stringSize;
2210 proto_tree_add_text (tree, tvb, startOffset,
2211 offset - startOffset,
2213 tvb_get_ptr (tvb, asvOffset, stringSize));
2219 add_accept_header (proto_tree *tree, tvbuff_t *header_buff,
2220 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2224 const char *contentTypeStr;
2226 add_content_type_value (tree, header_buff, 0, headerLen, value_buff,
2227 valueType, valueLen, hf_wsp_header_accept,
2228 hf_wsp_header_accept_str, &contentType, &contentTypeStr);
2232 add_accept_xxx_header (proto_tree *tree, tvbuff_t *header_buff,
2233 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2234 int valueLen, int hf_numeric, int hf_string,
2235 const value_string *vals, const char *unknown_tag)
2241 char valString[100];
2242 const char *valMatch;
2244 double q_value = 1.0;
2246 if (valueType == VALUE_IN_LEN)
2249 * Constrained-{charset,language} (Short-Integer).
2251 proto_tree_add_uint (tree, hf_numeric,
2252 header_buff, 0, headerLen,
2253 valueLen); /* valueLen is the value */
2256 if (valueType == VALUE_IS_TEXT_STRING)
2259 * Constrained-{charset,language} (text, i.e.
2262 proto_tree_add_string (tree, hf_string,
2263 header_buff, 0, headerLen,
2264 tvb_get_ptr (value_buff, 0, valueLen));
2269 * First byte had the 8th bit set.
2271 if (valueLen == 0) {
2273 * Any-{charset,language}.
2275 proto_tree_add_string (tree, hf_string,
2276 header_buff, 0, headerLen,
2282 * Accept-{charset,language}-general-form; Value-length, followed
2283 * by Well-known-{charset,language} or {Token-text,Text-string},
2284 * possibly followed by a Q-value.
2288 valueType = get_value_type_len (value_buff, 0, &subvalueLen,
2289 &subvalueOffset, &offset);
2290 if (valueType == VALUE_IS_TEXT_STRING)
2293 * {Token-text,Text-string}.
2296 tvb_get_ptr (value_buff, subvalueOffset, subvalueLen);
2297 proto_tree_add_string (tree, hf_string,
2298 value_buff, 0, valueLen, valMatch);
2301 * Well-known-{charset,langugage}; starts with an
2304 if (get_integer (value_buff, subvalueOffset, subvalueLen,
2305 valueType, &value) < 0)
2307 valMatch = "Invalid integer";
2311 valMatch = val_to_str(value, vals, unknown_tag);
2315 /* Any remaining data relates to Q-value */
2316 if (offset < valueLen)
2318 peek = tvb_get_guintvar (value_buff, offset, NULL);
2320 peek = (peek - 1) * 10;
2325 q_value = peek/1000.0;
2328 /* Build string including Q-value if present */
2329 if (q_value == 1.0) /* Default */
2331 snprintf (valString, 100, "%s", valMatch);
2335 snprintf (valString, 100, "%s; Q=%5.3f", valMatch, q_value);
2337 /* Add string to tree */
2338 proto_tree_add_string (tree, hf_string,
2339 header_buff, 0, headerLen, valString);
2343 add_accept_ranges_header (proto_tree *tree, tvbuff_t *header_buff,
2344 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2347 if (valueType == VALUE_IN_LEN)
2350 * Must be 0 (None) or 1 (Bytes) (the 8th bit was stripped
2353 proto_tree_add_uint (tree, hf_wsp_header_accept_ranges,
2354 header_buff, 0, headerLen,
2355 valueLen); /* valueLen is the value */
2358 if (valueType == VALUE_IS_TEXT_STRING)
2363 proto_tree_add_string (tree, hf_wsp_header_accept_ranges_str,
2364 header_buff, 0, headerLen,
2365 tvb_get_ptr (value_buff, 0, valueLen));
2372 fprintf(stderr, "dissect_wsp: Accept-Ranges is neither None, Bytes, nor Token-text\n");
2377 add_cache_control_header (proto_tree *tree, tvbuff_t *header_buff,
2378 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2386 proto_tree *parameter_tree;
2387 proto_tree *field_names_tree;
2390 if (valueType == VALUE_IN_LEN)
2393 * No-cache, No-store, Max-age, Max-stale, Min-fresh,
2394 * Only-if-cached, Public, Private, No-transform,
2395 * Must-revalidate, Proxy-revalidate, or S-maxage.
2397 proto_tree_add_uint (tree, hf_wsp_header_cache_control,
2398 header_buff, 0, headerLen,
2399 valueLen); /* valueLen is the value */
2402 if (valueType == VALUE_IS_TEXT_STRING)
2407 proto_tree_add_string (tree, hf_wsp_header_cache_control_str,
2408 header_buff, 0, headerLen,
2409 tvb_get_ptr (value_buff, 0, valueLen));
2414 * Value-length Cache-directive.
2415 * Get first field of Cache-directive.
2417 valueType = get_value_type_len (value_buff, offset, &subvalueLen,
2418 &subvalueOffset, &offset);
2419 if (valueType == VALUE_IS_TEXT_STRING)
2422 * Cache-extension Parameter.
2424 ti = proto_tree_add_string (tree, hf_wsp_header_cache_control_str,
2425 header_buff, 0, headerLen,
2426 tvb_get_ptr (value_buff, 0, valueLen));
2427 parameter_tree = proto_item_add_subtree (ti,
2428 ett_header_cache_control_parameters);
2431 * Process the rest of the value as parameters.
2433 while (tvb_reported_length_remaining (value_buff, offset) > 0) {
2434 offset = add_parameter (parameter_tree, value_buff,
2439 if (get_integer (value_buff, subvalueOffset, subvalueLen, valueType,
2442 proto_tree_add_text (tree, header_buff, 0, headerLen,
2443 "Invalid Cache-Control Cache-directive value");
2452 * Loop, processing Field-names.
2454 ti = proto_tree_add_uint (tree,
2455 hf_wsp_header_cache_control,
2456 header_buff, 0, headerLen,
2458 field_names_tree = proto_item_add_subtree (ti,
2459 ett_header_cache_control_field_names);
2460 while (tvb_reported_length_remaining (value_buff, offset)
2462 offset = add_cache_control_field_name (tree,
2463 value_buff, offset, value);
2472 * Get Delta-second-value.
2474 valueType = get_value_type_len (value_buff, offset,
2475 &subvalueLen, &subvalueOffset, &offset);
2476 if (get_integer (value_buff, subvalueOffset,
2477 subvalueLen, valueType, &delta_secs) < 0)
2479 proto_tree_add_text (tree,
2480 header_buff, 0, headerLen,
2481 "Invalid Cache-Control %s Delta-second-value",
2482 match_strval (value, vals_cache_control));
2486 proto_tree_add_uint_format (tree,
2487 hf_wsp_header_cache_control,
2488 header_buff, 0, headerLen,
2490 "Cache-Control: %s %u secs",
2491 match_strval (value, vals_cache_control),
2498 * This should not happen, but handle it anyway.
2500 proto_tree_add_uint (tree,
2501 hf_wsp_header_cache_control,
2502 header_buff, 0, headerLen,
2510 add_cache_control_field_name (proto_tree *tree, tvbuff_t *value_buff,
2511 int offset, guint cache_control_value)
2513 value_type_t valueType;
2518 startOffset = offset;
2519 valueType = get_value_type_len (value_buff, offset,
2520 &subvalueLen, &subvalueOffset, &offset);
2521 if (valueType == VALUE_IS_TEXT_STRING)
2526 proto_tree_add_item (tree,
2527 hf_wsp_header_cache_control_field_name_str,
2528 value_buff, startOffset, offset - startOffset,
2531 else if (valueType == VALUE_IN_LEN)
2534 * Short-integer Field-name.
2536 proto_tree_add_uint (tree,
2537 hf_wsp_header_cache_control_field_name,
2538 value_buff, startOffset, offset - startOffset,
2544 * Long-integer - illegal.
2546 proto_tree_add_text (tree,
2547 value_buff, startOffset, offset - startOffset,
2548 "Invalid Cache-Control %s Field-name",
2549 match_strval (cache_control_value, vals_cache_control));
2555 add_connection_header (proto_tree *tree, tvbuff_t *header_buff,
2556 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2561 if (valueType == VALUE_LEN_SUPPLIED)
2566 proto_tree_add_text (tree, header_buff, 0, headerLen,
2567 "Invalid Connection value");
2570 if (valueType == VALUE_IS_TEXT_STRING)
2575 proto_tree_add_string (tree,
2576 hf_wsp_header_connection_str,
2577 header_buff, 0, headerLen,
2578 tvb_get_ptr (value_buff, 0, valueLen));
2583 * First byte had the 8th bit set.
2585 if (valueLen == 0) {
2589 proto_tree_add_uint (tree, hf_wsp_header_connection,
2590 header_buff, offset, headerLen, valueLen);
2597 proto_tree_add_text (tree, header_buff, 0, headerLen,
2598 "Invalid Connection value");
2602 add_pragma_header (proto_tree *tree, tvbuff_t *header_buff,
2603 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2610 if (valueType == VALUE_IN_LEN)
2615 proto_tree_add_text (tree, header_buff, 0, headerLen,
2619 if (valueType == VALUE_IS_TEXT_STRING)
2624 proto_tree_add_text (tree, header_buff, 0, headerLen,
2630 * First byte had the 8th bit set.
2632 if (valueLen == 0) {
2636 proto_tree_add_string (tree, hf_wsp_header_pragma,
2637 header_buff, 0, headerLen, "No-cache");
2642 * Value-length, followed by Parameter.
2646 valueType = get_value_type_len (value_buff, 0, &subvalueLen,
2647 &subvalueOffset, &offset);
2648 if (valueType == VALUE_IS_TEXT_STRING)
2651 * Parameter - a text string.
2653 proto_tree_add_string (tree, hf_wsp_header_pragma,
2654 header_buff, 0, headerLen,
2655 tvb_get_ptr (value_buff, subvalueOffset, subvalueLen));
2658 * Parameter - numeric; illegal?
2660 proto_tree_add_text (tree, header_buff, 0, headerLen,
2666 add_transfer_encoding_header (proto_tree *tree, tvbuff_t *header_buff,
2667 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2672 if (valueType == VALUE_LEN_SUPPLIED)
2677 proto_tree_add_text (tree, header_buff, 0, headerLen,
2678 "Invalid Transfer-Encoding value");
2681 if (valueType == VALUE_IS_TEXT_STRING)
2686 proto_tree_add_string (tree,
2687 hf_wsp_header_transfer_encoding_str,
2688 header_buff, 0, headerLen,
2689 tvb_get_ptr (value_buff, 0, valueLen));
2694 * First byte had the 8th bit set.
2696 if (valueLen == 0) {
2700 proto_tree_add_uint (tree, hf_wsp_header_transfer_encoding,
2701 header_buff, offset, headerLen, valueLen);
2708 proto_tree_add_text (tree, header_buff, 0, headerLen,
2709 "Invalid Transfer Encoding value");
2713 add_warning_header (proto_tree *tree, tvbuff_t *header_buff,
2714 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2719 proto_tree *warning_tree;
2724 * Put the items under a header.
2725 * XXX - make the text of the item summarize the elements.
2727 ti = proto_tree_add_item (tree, hf_wsp_header_warning,
2728 header_buff, 0, headerLen, bo_little_endian);
2729 warning_tree = proto_item_add_subtree(ti, ett_header_warning);
2731 if (valueType == VALUE_IN_LEN)
2734 * Warn-code (Short-integer).
2736 proto_tree_add_uint (warning_tree, hf_wsp_header_warning_code,
2737 header_buff, 0, headerLen,
2738 valueLen); /* valueLen is the value */
2741 if (valueType == VALUE_IS_TEXT_STRING)
2746 proto_tree_add_text (warning_tree, header_buff, 0, headerLen,
2747 "Invalid Warning (all text)");
2752 * Warning-value; Warn-code, followed by Warn-agent, followed by
2756 * Get Short-integer Warn-code.
2758 valueType = get_value_type_len (value_buff, offset, &subvalueLen,
2759 &subvalueOffset, &offset);
2760 if (valueType != VALUE_IN_LEN)
2763 * Not a Short-integer.
2765 proto_tree_add_text (warning_tree, value_buff, subvalueOffset,
2766 subvalueLen, "Invalid Warn-code (not a Short-integer)");
2769 proto_tree_add_uint (warning_tree, hf_wsp_header_warning_code,
2770 value_buff, subvalueOffset, 1,
2771 subvalueLen); /* subvalueLen is the value */
2774 * Warn-agent; must be text.
2776 valueType = get_value_type_len (value_buff, offset, &subvalueLen,
2777 &subvalueOffset, &offset);
2778 if (valueType != VALUE_IS_TEXT_STRING)
2783 proto_tree_add_text (warning_tree, value_buff, subvalueOffset,
2784 subvalueLen, "Invalid Warn-agent (not a text string)");
2787 proto_tree_add_item (warning_tree,
2788 hf_wsp_header_warning_agent,
2789 value_buff, subvalueOffset, subvalueLen, bo_little_endian);
2792 * Warn-text; must be text.
2794 valueType = get_value_type_len (value_buff, offset, &subvalueLen,
2795 &subvalueOffset, &offset);
2796 if (valueType != VALUE_IS_TEXT_STRING)
2801 proto_tree_add_text (warning_tree, value_buff, subvalueOffset,
2802 subvalueLen, "Invalid Warn-text (not a text string)");
2805 proto_tree_add_item (warning_tree,
2806 hf_wsp_header_warning_text,
2807 value_buff, subvalueOffset, subvalueLen, bo_little_endian);
2811 add_accept_application_header (proto_tree *tree, tvbuff_t *header_buff,
2812 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2817 if (valueType == VALUE_IN_LEN)
2820 * Application-id-value; numeric, so it's App-assigned-code.
2822 proto_tree_add_uint (tree, hf_wsp_header_accept_application,
2823 header_buff, 0, headerLen,
2824 valueLen); /* valueLen is the value */
2827 if (valueType == VALUE_IS_TEXT_STRING)
2832 proto_tree_add_string (tree, hf_wsp_header_accept_application_str,
2833 header_buff, 0, headerLen,
2834 tvb_get_ptr (value_buff, 0, valueLen));
2839 * First byte had the 8th bit set.
2841 if (valueLen == 0) {
2845 proto_tree_add_string (tree, hf_wsp_header_accept_application_str,
2846 header_buff, 0, headerLen,
2852 * Integer-value, hence App-assigned-code.
2854 if (get_integer (value_buff, 0, valueLen, valueType, &value) < 0)
2856 proto_tree_add_text (tree, header_buff, 0, headerLen,
2857 "Invalid Accept-Application App-assigned-code");
2861 proto_tree_add_uint (tree, hf_wsp_header_accept_application,
2862 header_buff, 0, headerLen, value);
2867 add_wap_application_id_header (proto_tree *tree, tvbuff_t *header_buff,
2868 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
2871 if (valueType == VALUE_IN_LEN)
2874 * Must application-id (the 8th bit was stripped off).
2876 proto_tree_add_uint (tree, hf_wsp_header_wap_application_id,
2877 header_buff, 0, headerLen,
2878 valueLen); /* valueLen is the value */
2881 if (valueType == VALUE_IS_TEXT_STRING)
2886 proto_tree_add_string (tree, hf_wsp_header_wap_application_id_str,
2887 header_buff, 0, headerLen,
2888 tvb_get_ptr (value_buff, 0, valueLen));
2895 fprintf(stderr, "dissect_wsp: Suprising format of X-Wap-Application-Id\n");
2900 add_capabilities (proto_tree *tree, tvbuff_t *tvb, int type)
2903 proto_tree *wsp_capabilities;
2905 guint offsetStr = 0;
2906 guint capabilitiesLen = tvb_reported_length (tvb);
2907 guint capabilitiesStart = 0;
2913 char valString[200];
2916 fprintf (stderr, "dissect_wsp: Offset is %d, size is %d\n", offset, capabilitiesLen);
2920 if (capabilitiesLen <= 0)
2922 fprintf (stderr, "dissect_wsp: Capabilities = 0\n");
2927 fprintf (stderr, "dissect_wsp: capabilities to process\n");
2930 ti = proto_tree_add_item (tree, hf_wsp_capabilities_section,tvb,offset,capabilitiesLen,bo_little_endian);
2931 wsp_capabilities = proto_item_add_subtree( ti, ett_capabilities );
2935 while (offset < capabilitiesLen)
2937 /* Loop round each header */
2938 capabilitiesStart = offset;
2939 length = tvb_get_guint8 (tvb, capabilitiesStart);
2941 if (length >= 127) /* length */
2944 fprintf (stderr, "dissect_wsp: capabilities length invalid %d\n",length);
2950 peek = tvb_get_guint8 (tvb, offset);
2952 switch (peek & 0x7f)
2954 case 0x00 : /* Client-SDU-Size */
2955 value = get_uintvar (tvb, offset, length+capabilitiesStart+1);
2956 proto_tree_add_uint (wsp_capabilities, hf_wsp_capabilities_client_SDU, tvb, capabilitiesStart, length+1, value);
2958 case 0x01 : /* Server-SDU-Size */
2959 value = get_uintvar (tvb, offset, length+capabilitiesStart+1);
2960 proto_tree_add_uint (wsp_capabilities, hf_wsp_capabilities_server_SDU, tvb, capabilitiesStart, length+1, value);
2962 case 0x02 : /* Protocol Options */
2963 value = get_uintvar (tvb, offset, length+capabilitiesStart+1);
2968 ret = snprintf(valString+i,200-i,"%s","(Confirmed push facility) ");
2971 * Some versions of snprintf
2972 * return -1 if they'd
2973 * truncate the output.
2985 ret = snprintf(valString+i,200-i,"%s","(Push facility) ");
2988 * Some versions of snprintf
2989 * return -1 if they'd
2990 * truncate the output.
3002 ret = snprintf(valString+i,200-i,"%s","(Session resume facility) ");
3005 * Some versions of snprintf
3006 * return -1 if they'd
3007 * truncate the output.
3019 ret = snprintf(valString+i,200-i,"%s","(Acknowledgement headers) ");
3022 * Some versions of snprintf
3023 * return -1 if they'd
3024 * truncate the output.
3031 proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_protocol_opt, tvb, capabilitiesStart, length+1, valString);
3033 case 0x03 : /* Method-MOR */
3034 value = tvb_get_guint8(tvb, offset);
3035 proto_tree_add_uint (wsp_capabilities, hf_wsp_capabilities_method_MOR, tvb, capabilitiesStart, length+1, value);
3037 case 0x04 : /* Push-MOR */
3038 value = tvb_get_guint8(tvb, offset);
3039 proto_tree_add_uint (wsp_capabilities, hf_wsp_capabilities_push_MOR, tvb, capabilitiesStart, length+1, value);
3042 case 0x05 : /* Extended Methods */
3045 add_capability_vals(tvb, (type == CONNECT),
3046 offsetStr, length, capabilitiesStart,
3047 valString, sizeof valString);
3048 proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_extended_methods, tvb, capabilitiesStart, length+1, valString);
3050 case 0x06 : /* Header Code Pages */
3053 add_capability_vals(tvb, (type == CONNECT),
3054 offsetStr, length, capabilitiesStart,
3055 valString, sizeof valString);
3056 proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_header_code_pages, tvb, capabilitiesStart, length+1, valString);
3058 case 0x07 : /* Aliases */
3061 proto_tree_add_text (wsp_capabilities, tvb , capabilitiesStart, length+1,
3062 "Unsupported Header (0x%02X)", peek & 0x7F);
3065 offset=capabilitiesStart+length+1;
3070 add_capability_vals(tvbuff_t *tvb, gboolean add_string, int offsetStr,
3071 guint length, guint capabilitiesStart, char *valString,
3072 size_t valStringSize)
3080 while ((offsetStr-capabilitiesStart) <= length)
3082 value = tvb_get_guint8(tvb, offsetStr);
3083 if (i >= valStringSize) {
3089 ret = snprintf(valString+i,valStringSize-i,
3094 ret = snprintf(valString+i,valStringSize-i,"(%d) ",
3099 * Some versions of snprintf return -1
3100 * if they'd truncate the output.
3108 for (;(c = tvb_get_guint8(tvb, offsetStr))
3109 && i < valStringSize - 1; i++,offsetStr++)
3112 if (i < valStringSize - 2) {
3113 valString[i++] = ')';
3114 valString[i++] = ' ';
3118 valString[i] = '\0';
3122 get_value_type_len (tvbuff_t *tvb, int offset, guint *valueLen,
3123 int *valueOffset, int *nextOffset)
3129 /* Get value part of header */
3130 peek = tvb_get_guint8 (tvb, offset);
3134 * The value follows "peek", and is "peek" octets long.
3137 fprintf (stderr, "dissect_wsp: Looking for %d octets\n", peek);
3140 *valueLen = len; /* Length of value */
3141 offset++; /* Skip the length */
3142 *valueOffset = offset; /* Offset of value */
3143 offset += len; /* Skip the value */
3144 *nextOffset = offset; /* Offset after value */
3145 return VALUE_LEN_SUPPLIED;
3147 else if (peek == 31)
3150 * A uintvar giving the length of the value follows
3151 * "peek", and the value follows that.
3154 fprintf (stderr, "dissect_wsp: Looking for uintvar octets\n");
3156 offset++; /* Skip the uintvar indicator */
3157 count = 0; /* Initialise count */
3158 len = tvb_get_guintvar (tvb, offset, &count);
3159 *valueLen = len; /* Length of value */
3160 offset += count; /* Skip the length */
3161 *valueOffset = offset; /* Offset of value */
3162 offset += len; /* Skip the value */
3163 *nextOffset = offset; /* Offset after value */
3164 return VALUE_LEN_SUPPLIED;
3166 else if (peek <= 127)
3169 * The value is a NUL-terminated string, and "peek"
3170 * is the first octet of the string.
3173 fprintf (stderr, "dissect_wsp: Looking for NUL-terminated string\n");
3175 len = tvb_strsize (tvb, offset);
3176 *valueLen = len; /* Length of value */
3177 *valueOffset = offset; /* Offset of value */
3178 offset += len; /* Skip the value */
3179 *nextOffset = offset; /* Offset after value */
3180 return VALUE_IS_TEXT_STRING;
3185 * "peek", with the 8th bit stripped off, is the value.
3188 fprintf (stderr, "dissect_wsp: Value is %d\n", (peek & 0x7F));
3190 *valueLen = peek & 0x7F; /* Return the value itself */
3191 *valueOffset = offset; /* Offset of value */
3192 offset++; /* Skip the value */
3193 *nextOffset = offset; /* Offset after value */
3194 return VALUE_IN_LEN;
3199 get_uintvar (tvbuff_t *tvb, guint offset, guint offsetEnd)
3206 octet = tvb_get_guint8 (tvb, offset);
3209 value += octet & 0x7f;
3211 while ((offsetEnd > offset) && (octet & 0x80));
3216 add_content_type_value (proto_tree *tree, tvbuff_t *header_buff,
3217 int headerOffset, int headerLen, tvbuff_t *value_buff,
3218 value_type_t valueType, int valueLen, int hf_numeric, int hf_string,
3219 guint *contentTypep, const char **contentTypeStrp)
3222 proto_tree *parameter_tree;
3223 const char *contentTypeStr;
3229 if (valueType == VALUE_IN_LEN)
3232 * Constrained-media (Short-Integer).
3234 proto_tree_add_uint (tree, hf_numeric,
3235 header_buff, headerOffset, headerLen,
3236 valueLen); /* valueLen is the value */
3239 * Return the numerical value, and a null string value
3240 * indicating that the value is numerical.
3242 *contentTypep = valueLen;
3243 *contentTypeStrp = NULL;
3246 if (valueType == VALUE_IS_TEXT_STRING)
3249 * Constrained-media (text, i.e. Extension-Media).
3251 contentTypeStr = tvb_get_ptr (value_buff, 0, valueLen);
3252 proto_tree_add_string (tree, hf_string,
3253 header_buff, headerOffset, headerLen,
3257 * Return the string value, and set the numerical value
3258 * to 0 (as it shouldn't be used).
3261 *contentTypeStrp = contentTypeStr;
3266 * Content-general-form; Value-length, followed by Media-range,
3267 * followed by optional Accept-parameters.
3271 valueType = get_value_type_len (value_buff, 0, &subvalueLen,
3272 &subvalueOffset, &offset);
3273 if (valueType == VALUE_IS_TEXT_STRING)
3276 * Extension-Media; value is a string.
3279 tvb_get_ptr (value_buff, subvalueOffset, subvalueLen);
3280 ti = proto_tree_add_string (tree, hf_string, header_buff,
3281 headerOffset, headerLen, contentTypeStr);
3284 * Return the string value, and set the numerical value
3285 * to 0 (as it shouldn't be used).
3288 *contentTypeStrp = contentTypeStr;
3293 * Well-known-media; value is an Integer.
3295 if (get_integer (value_buff, subvalueOffset, subvalueLen,
3296 valueType, &value) < 0)
3298 proto_tree_add_text (tree, header_buff,
3299 headerOffset, headerLen,
3300 "Invalid integer for Well-known-media");
3303 * Content type is invalid.
3304 * Don't try to parse the rest of the value.
3307 *contentTypeStrp = NULL;
3310 ti = proto_tree_add_uint (tree, hf_numeric,
3311 header_buff, headerOffset, headerLen, value);
3314 * Return the numerical value, and a null string value
3315 * indicating that the value is numerical.
3317 *contentTypep = value;
3318 *contentTypeStrp = NULL;
3322 * Process the rest of the value as parameters.
3324 parameter_tree = proto_item_add_subtree(ti,
3325 ett_content_type_parameters);
3326 while (tvb_reported_length_remaining (value_buff, offset) > 0)
3327 offset = add_parameter (parameter_tree, value_buff, offset);
3331 add_content_type (proto_tree *tree, tvbuff_t *tvb, guint offset,
3332 guint *contentTypep, const char **contentTypeStrp)
3335 value_type_t valueType;
3339 tvbuff_t *value_buff;
3341 valueStart = offset;
3344 * Get the value type and length (or, if the type is VALUE_IN_LEN,
3345 * meaning the value is a Short-integer, get the value type
3346 * and the value itself).
3348 valueType = get_value_type_len (tvb, valueStart, &valueLen,
3349 &valueOffset, &offset);
3350 valueTypeLen = offset - valueStart;
3353 * Get a tvbuff for the value.
3354 * XXX - can valueLen be 0?
3355 * XXX - cut the actual length short so that it doesn't run
3356 * past the actual length of tvb.
3358 if (valueType != VALUE_IN_LEN) {
3359 value_buff = tvb_new_subset (tvb, valueOffset, valueLen,
3363 * XXX - when the last dissector is tvbuffified,
3364 * so that NULL is no longer a valid tvb pointer
3365 * value in "proto_tree_add" calls, just
3366 * set "value_buff" to NULL.
3368 * XXX - can we already do that? I.e., will that
3369 * cause us always to crash if we mistakenly try
3370 * to fetch the value of a VALUE_IN_LEN item?
3372 value_buff = tvb_new_subset (tvb, valueStart, 0, 0);
3375 add_content_type_value (tree, tvb, valueStart, valueTypeLen, value_buff,
3376 valueType, valueLen, hf_wsp_content_type,
3377 hf_wsp_content_type_str, contentTypep, contentTypeStrp);
3383 add_integer_value_header (proto_tree *tree, tvbuff_t *header_buff,
3384 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
3385 int valueLen, int hf_numeric, guint8 headerType)
3387 add_integer_value_header_common (tree, header_buff, headerLen,
3388 value_buff, valueType, valueLen, hf_numeric, headerType,
3393 add_openwave_integer_value_header (proto_tree *tree, tvbuff_t *header_buff,
3394 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
3395 int valueLen, int hf_numeric, guint8 headerType)
3397 add_integer_value_header_common (tree, header_buff, headerLen,
3398 value_buff, valueType, valueLen, hf_numeric, headerType,
3399 vals_openwave_field_names);
3403 add_integer_value_header_common (proto_tree *tree, tvbuff_t *header_buff,
3404 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
3405 int valueLen, int hf_numeric, guint8 headerType,
3406 const value_string *vals)
3410 if (get_integer (value_buff, 0, valueLen, valueType, &value) < 0)
3412 proto_tree_add_text (tree, header_buff, 0, headerLen,
3413 "Invalid %s integer value",
3414 match_strval (headerType, vals));
3418 proto_tree_add_uint (tree, hf_numeric,
3419 header_buff, 0, headerLen, value);
3424 add_string_value_header (proto_tree *tree, tvbuff_t *header_buff,
3425 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
3426 int valueLen, int hf_string, guint8 headerType)
3428 add_string_value_header_common (tree, header_buff, headerLen,
3429 value_buff, valueType, valueLen, hf_string, headerType,
3434 add_openwave_string_value_header (proto_tree *tree, tvbuff_t *header_buff,
3435 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
3436 int valueLen, int hf_string, guint8 headerType)
3438 add_string_value_header_common (tree, header_buff, headerLen,
3439 value_buff, valueType, valueLen, hf_string, headerType,
3440 vals_openwave_field_names);
3444 add_string_value_header_common (proto_tree *tree, tvbuff_t *header_buff,
3445 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
3446 int valueLen, int hf_string, guint8 headerType,
3447 const value_string *vals)
3449 if (valueType != VALUE_IS_TEXT_STRING)
3451 proto_tree_add_text (tree, header_buff, 0, headerLen,
3452 "Invalid %s string value",
3453 match_strval (headerType, vals));
3457 proto_tree_add_string (tree, hf_string, header_buff,
3458 0, headerLen, tvb_get_ptr (value_buff, 0, valueLen));
3463 add_quoted_string_value_header (proto_tree *tree, tvbuff_t *header_buff,
3464 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
3465 int valueLen, int hf_string, guint8 headerType)
3467 if (valueType != VALUE_IS_TEXT_STRING)
3469 proto_tree_add_text (tree, header_buff, 0, headerLen,
3470 "Invalid %s quoted string value",
3471 match_strval (headerType, vals_field_names));
3475 proto_tree_add_string (tree, hf_string, header_buff,
3476 0, headerLen, tvb_get_ptr (value_buff, 1, valueLen - 1));
3480 /* Utility function to add a date value to the protocol tree */
3482 add_date_value_header (proto_tree *tree, tvbuff_t *header_buff,
3483 int headerLen, tvbuff_t *value_buff, value_type_t valueType,
3484 int valueLen, int hf_time, guint8 headerType)
3489 /* Attempt to get the date value from the buffer */
3490 if (get_integer (value_buff, 0, valueLen, valueType, &secs) == 0)
3493 * Fill in the "struct timeval", and add it to the
3495 * Note: this will succeed even if it's a Short-integer.
3496 * A Short-integer would work, but, as the time values
3497 * are UNIX seconds-since-the-Epoch value, and as
3498 * there weren't WAP phones or Web servers back in
3499 * late 1969/early 1970, they're unlikely to be used.
3501 timeValue.secs = secs;
3502 timeValue.nsecs = 0;
3503 proto_tree_add_time (tree, hf_time, header_buff, 0,
3504 headerLen, &timeValue);
3508 proto_tree_add_text (tree, header_buff, 0, headerLen,
3509 "Invalid %s date value",
3510 match_strval (headerType, vals_field_names));
3515 add_parameter (proto_tree *tree, tvbuff_t *value_buff, int offset)
3518 value_type_t valueType;
3523 startOffset = offset;
3524 valueType = get_value_type_len (value_buff, offset,
3525 &subvalueLen, &subvalueOffset, &offset);
3526 if (valueType == VALUE_IS_TEXT_STRING)
3529 * Untyped-parameter.
3531 offset = add_untyped_parameter (tree, value_buff, startOffset, offset);
3536 * Well-known-parameter-token.
3538 if (get_integer (value_buff, subvalueOffset,
3539 subvalueLen, valueType, &value) < 0)
3541 proto_tree_add_text (tree, value_buff, startOffset,
3542 offset - startOffset,
3543 "Invalid Well-known-parameter-token");
3549 case 0x01: /* Charset */
3550 offset = add_parameter_charset (tree, value_buff, startOffset, offset);
3553 case 0x03: /* Type */
3554 offset = add_parameter_type (tree, value_buff, startOffset, offset);
3557 case 0x05: /* Name */
3558 offset = add_parameter_text (tree, value_buff, startOffset, offset,
3559 hf_wsp_parameter_name, "Name");
3562 case 0x06: /* Filename */
3563 offset = add_parameter_text (tree, value_buff, startOffset, offset,
3564 hf_wsp_parameter_filename, "Filename");
3567 case 0x09: /* Type (special) */
3568 offset = add_constrained_encoding(tree, value_buff, startOffset, offset);
3571 case 0x0A: /* Start */
3572 offset = add_parameter_text (tree, value_buff, startOffset, offset,
3573 hf_wsp_parameter_start, "Start");
3576 case 0x0B: /* Start-info */
3577 offset = add_parameter_text (tree, value_buff, startOffset, offset,
3578 hf_wsp_parameter_start_info, "Start-info");
3581 case 0x0C: /* Comment */
3582 offset = add_parameter_text (tree, value_buff, startOffset, offset,
3583 hf_wsp_parameter_comment, "Comment");
3586 case 0x0D: /* Domain */
3587 offset = add_parameter_text (tree, value_buff, startOffset, offset,
3588 hf_wsp_parameter_domain, "Domain");
3591 case 0x0F: /* Path */
3592 offset = add_parameter_text (tree, value_buff, startOffset, offset,
3593 hf_wsp_parameter_path, "Path");
3597 case 0x02: /* Level */
3598 case 0x07: /* Differences */
3599 case 0x08: /* Padding */
3600 case 0x0E: /* Max-Age */
3601 case 0x10: /* Secure */
3610 add_untyped_parameter (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
3613 const guint8 *token;
3614 value_type_t valueType;
3618 int vOffset = offset;
3620 token = tvb_get_ptr (value_buff, startOffset, offset - startOffset);
3622 * Now an Untyped-value; either an Integer-value or a Text-value.
3624 valueType = get_value_type_len (value_buff, offset,
3625 &subvalueLen, &subvalueOffset, &offset);
3626 if (valueType == VALUE_IS_TEXT_STRING)
3631 if ((offset - vOffset) == 1) {
3633 * No-value. (stringSize includes the terminating
3634 * null byte, so an empty string has a size of 1.)
3636 proto_tree_add_text (tree, value_buff, startOffset,
3637 offset - startOffset,
3641 proto_tree_add_text (tree, value_buff, startOffset,
3642 offset - startOffset,
3644 tvb_get_ptr (value_buff, vOffset, offset - vOffset));
3651 if (get_integer (value_buff, subvalueOffset, subvalueLen,
3652 valueType, &value) == 0)
3654 proto_tree_add_text (tree, value_buff, startOffset,
3655 offset - startOffset,
3656 "%s: %u", token, value);
3660 proto_tree_add_text (tree, value_buff, startOffset,
3661 offset - startOffset,
3662 "%s: Invalid Integer-value", token);
3669 add_parameter_charset (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
3672 value_type_t valueType;
3677 valueType = get_value_type_len (value_buff, offset,
3678 &subvalueLen, &subvalueOffset, &offset);
3679 if (valueType == VALUE_IN_LEN)
3684 proto_tree_add_uint (tree, hf_wsp_parameter_well_known_charset,
3685 value_buff, startOffset, offset - startOffset,
3686 subvalueLen); /* subvalueLen is the value */
3689 if (valueType == VALUE_IS_TEXT_STRING)
3694 proto_tree_add_text (tree, value_buff, startOffset,
3695 offset - startOffset, "Invalid Well-known charset");
3700 * First byte had the 8th bit set.
3702 if (subvalueLen == 0) {
3705 * XXX - add this as a field?
3707 proto_tree_add_text (tree, value_buff, startOffset,
3708 offset- startOffset, "*");
3712 if (get_integer(value_buff, subvalueOffset, subvalueLen,
3713 valueType, &value) == -1) {
3714 proto_tree_add_text (tree, value_buff, startOffset,
3715 offset - startOffset, "Length %u not handled in Well-known charset",
3718 proto_tree_add_uint (tree, hf_wsp_parameter_well_known_charset,
3719 value_buff, startOffset, offset - startOffset, value);
3725 add_constrained_encoding (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
3728 value_type_t valueType;
3733 valueType = get_value_type_len (value_buff, offset,
3734 &subvalueLen, &subvalueOffset, &offset);
3735 if (valueType == VALUE_IN_LEN)
3738 * Integer-value, invalid
3740 proto_tree_add_text (tree, value_buff, startOffset,
3741 offset - startOffset, "Invalid multipart type parameter");
3744 if (valueType == VALUE_IS_TEXT_STRING)
3749 proto_tree_add_string (tree, hf_wsp_parameter_upart_type,
3750 value_buff, startOffset, offset - startOffset,
3751 tvb_get_ptr (value_buff, subvalueOffset, subvalueLen));
3755 * First byte had the 8th bit set.
3757 get_integer(value_buff, subvalueOffset, subvalueLen, valueType, &value);
3758 proto_tree_add_uint (tree, hf_wsp_parameter_upart_type_value,
3759 value_buff, startOffset, offset - startOffset, value);
3764 add_parameter_type (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
3767 value_type_t valueType;
3772 valueType = get_value_type_len (value_buff, offset,
3773 &subvalueLen, &subvalueOffset, &offset);
3774 if (get_integer(value_buff, subvalueOffset, subvalueLen,
3775 valueType, &value) == -1) {
3776 proto_tree_add_text (tree, value_buff, startOffset,
3777 offset - startOffset, "Invalid type");
3779 proto_tree_add_uint (tree, hf_wsp_parameter_type, value_buff,
3780 startOffset, offset - startOffset, value);
3786 add_parameter_text (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
3787 int offset, int hf_string, const char *paramName)
3789 value_type_t valueType;
3793 valueType = get_value_type_len (value_buff, offset,
3794 &subvalueLen, &subvalueOffset, &offset);
3795 if (valueType != VALUE_IS_TEXT_STRING) {
3796 proto_tree_add_text (tree, value_buff, startOffset,
3797 offset - startOffset, "Invalid %s", paramName);
3799 proto_tree_add_string (tree, hf_string, value_buff,
3800 startOffset, offset - startOffset,
3801 tvb_get_ptr (value_buff, subvalueOffset, subvalueLen));
3807 add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType,
3808 const char *contentTypeStr)
3811 guint variableStart = 0;
3812 guint variableEnd = 0;
3813 guint valueStart = 0;
3818 /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,bo_little_endian); */
3819 ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,bo_little_endian);
3821 if (contentTypeStr == NULL && contentType == 0x12)
3825 * Iterate through post data.
3827 for (offset = 0; offset < tvb_reported_length (tvb); offset++)
3829 peek = tvb_get_guint8 (tvb, offset);
3832 variableEnd = offset;
3833 valueStart = offset+1;
3835 else if (peek == '&')
3837 if (variableEnd > 0)
3839 add_post_variable (ti, tvb, variableStart, variableEnd, valueStart, offset);
3841 variableStart = offset+1;
3848 /* See if there's outstanding data */
3849 if (variableEnd > 0)
3851 add_post_variable (ti, tvb, variableStart, variableEnd, valueStart, offset);
3854 else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x23) || (contentType == 0x24) ||
3855 (contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33))
3857 add_multipart_data(ti, tvb);
3862 add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint variableEnd, guint valueStart, guint valueEnd)
3864 int variableLength = variableEnd-variableStart;
3865 int valueLength = 0;
3866 char *variableBuffer;
3869 variableBuffer = g_malloc (variableLength+1);
3870 strncpy (variableBuffer, tvb_get_ptr (tvb, variableStart, variableLength), variableLength);
3871 variableBuffer[variableLength] = 0;
3873 if (valueEnd < valueStart)
3875 valueBuffer = g_malloc (1);
3877 valueEnd = valueStart;
3881 valueLength = valueEnd-valueStart;
3882 valueBuffer = g_malloc (valueLength+1);
3883 strncpy (valueBuffer, tvb_get_ptr (tvb, valueStart, valueLength), valueLength);
3884 valueBuffer[valueLength] = 0;
3887 /* Check for variables with no value */
3888 if (valueStart >= tvb_reported_length (tvb))
3890 valueStart = tvb_reported_length (tvb);
3891 valueEnd = valueStart;
3893 valueLength = valueEnd-valueStart;
3895 proto_tree_add_text (tree, tvb, variableStart, valueEnd-variableStart, "%s: %s", variableBuffer, valueBuffer);
3897 g_free (variableBuffer);
3898 g_free (valueBuffer);
3902 add_multipart_data (proto_tree *tree, tvbuff_t *tvb)
3910 guint contentType = 0;
3911 const char *contentTypeStr;
3916 proto_item *sub_tree = NULL,
3918 proto_tree *mpart_tree;
3920 nEntries = tvb_get_guintvar (tvb, offset, &count);
3924 sub_tree = proto_tree_add_text(tree, tvb, offset - count, 0,
3926 proto_item_add_subtree(sub_tree, ett_mpartlist);
3930 part_start = offset;
3931 HeadersLen = tvb_get_guintvar (tvb, offset, &count);
3933 DataLen = tvb_get_guintvar (tvb, offset, &count);
3935 ti = proto_tree_add_uint(sub_tree, hf_wsp_mpart, tvb, part_start,
3936 HeadersLen + DataLen + (offset - part_start), partnr);
3937 mpart_tree = proto_item_add_subtree(ti, ett_multiparts);
3938 nextOffset = add_content_type (mpart_tree, tvb, offset, &contentType, &contentTypeStr);
3939 HeadersLen -= (nextOffset - offset);
3942 tmp_tvb = tvb_new_subset (tvb, nextOffset, HeadersLen, HeadersLen);
3943 add_headers (mpart_tree, tmp_tvb);
3945 offset = nextOffset + HeadersLen;
3946 proto_tree_add_item (mpart_tree, hf_wsp_multipart_data, tvb, offset, DataLen, bo_little_endian);
3953 get_integer (tvbuff_t *tvb, guint offset, guint valueLength,
3954 value_type_t valueType, guint *value)
3956 if (valueType == VALUE_IS_TEXT_STRING) {
3963 if (valueType == VALUE_IN_LEN) {
3967 *value = valueLength;
3974 switch (valueLength)
3977 *value = tvb_get_guint8(tvb, offset);
3980 *value = tvb_get_ntohs(tvb, offset);
3983 *value = tvb_get_ntoh24(tvb, offset);
3986 *value = tvb_get_ntohl(tvb, offset);
3989 /* TODO: Need to read peek octets */
3991 fprintf (stderr, "dissect_wsp: get_integer size %u NYI\n", valueLength);
3997 /* Register the protocol with Ethereal */
3999 proto_register_wsp(void)
4002 /* Setup list of header fields */
4003 static hf_register_info hf[] = {
4004 { &hf_wsp_header_tid,
4005 { "Transmission ID",
4007 FT_UINT8, BASE_HEX, NULL, 0x00,
4008 "Transmission ID", HFILL
4011 { &hf_wsp_header_pdu_type,
4014 FT_UINT8, BASE_HEX, VALS( vals_pdu_type ), 0x00,
4018 { &hf_wsp_version_major,
4019 { "Version (Major)",
4020 "wsp.version.major",
4021 FT_UINT8, BASE_DEC, NULL, 0xF0,
4022 "Version (Major)", HFILL
4025 { &hf_wsp_version_minor,
4026 { "Version (Minor)",
4027 "wsp.version.minor",
4028 FT_UINT8, BASE_DEC, NULL, 0x0F,
4029 "Version (Minor)", HFILL
4032 { &hf_wsp_capability_length,
4033 { "Capability Length",
4034 "wsp.capability.length",
4035 FT_UINT32, BASE_DEC, NULL, 0x00,
4036 "Capability Length", HFILL
4039 { &hf_wsp_header_length,
4041 "wsp.headers_length",
4042 FT_UINT32, BASE_DEC, NULL, 0x00,
4043 "Headers Length", HFILL
4046 { &hf_wsp_capabilities_section,
4049 FT_NONE, BASE_DEC, NULL, 0x00,
4050 "Capabilities", HFILL
4053 { &hf_wsp_headers_section,
4056 FT_NONE, BASE_DEC, NULL, 0x00,
4062 "wsp.headers.header",
4063 FT_NONE, BASE_DEC, NULL, 0x00,
4067 { &hf_wsp_header_uri_len,
4070 FT_UINT32, BASE_DEC, NULL, 0x00,
4074 { &hf_wsp_header_uri,
4077 FT_STRING, BASE_NONE, NULL, 0x00,
4081 { &hf_wsp_server_session_id,
4082 { "Server Session ID",
4083 "wsp.server.session_id",
4084 FT_UINT32, BASE_DEC, NULL, 0x00,
4085 "Server Session ID", HFILL
4088 { &hf_wsp_header_status,
4091 FT_UINT8, BASE_HEX, VALS( vals_status ), 0x00,
4095 { &hf_wsp_content_type,
4097 "wsp.content_type.type",
4098 FT_UINT8, BASE_HEX, VALS ( vals_content_types ), 0x00,
4099 "Content Type", HFILL
4102 { &hf_wsp_content_type_str,
4104 "wsp.content_type.type.string",
4105 FT_STRING, BASE_NONE, NULL, 0x00,
4106 "Content Type", HFILL
4109 { &hf_wsp_parameter_well_known_charset,
4111 "wsp.content_type.parameter.charset",
4112 FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00,
4116 { &hf_wsp_parameter_type,
4118 "wsp.content_type.parameter.type",
4119 FT_UINT32, BASE_DEC, NULL, 0x00,
4123 { &hf_wsp_parameter_name,
4125 "wsp.content_type.parameter.name",
4126 FT_STRING, BASE_NONE, NULL, 0x00,
4130 { &hf_wsp_parameter_filename,
4132 "wsp.content_type.parameter.filename",
4133 FT_STRING, BASE_NONE, NULL, 0x00,
4137 { &hf_wsp_parameter_start,
4139 "wsp.content_type.parameter.start",
4140 FT_STRING, BASE_NONE, NULL, 0x00,
4144 { &hf_wsp_parameter_start_info,
4146 "wsp.content_type.parameter.start_info",
4147 FT_STRING, BASE_NONE, NULL, 0x00,
4151 { &hf_wsp_parameter_comment,
4153 "wsp.content_type.parameter.comment",
4154 FT_STRING, BASE_NONE, NULL, 0x00,
4158 { &hf_wsp_parameter_domain,
4160 "wsp.content_type.parameter.domain",
4161 FT_STRING, BASE_NONE, NULL, 0x00,
4165 { &hf_wsp_parameter_path,
4167 "wsp.content_type.parameter.path",
4168 FT_STRING, BASE_NONE, NULL, 0x00,
4172 { &hf_wsp_parameter_upart_type,
4174 "wsp.content_type.parameter.upart.type",
4175 FT_STRING, BASE_NONE, NULL, 0x00,
4176 "Multipart type", HFILL
4179 { &hf_wsp_parameter_upart_type_value,
4181 "wsp.content_type.parameter.upart.type.int",
4182 FT_UINT8, BASE_DEC, NULL, 0x00,
4183 "Multipart type (int value)", HFILL
4186 { &hf_wsp_reply_data,
4189 FT_NONE, BASE_NONE, NULL, 0x00,
4193 { &hf_wsp_header_shift_code,
4196 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
4197 FT_UINT8, BASE_HEX, NULL, 0x00,
4201 { &hf_wsp_header_accept,
4203 "wsp.header.accept",
4204 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
4205 FT_UINT8, BASE_HEX, VALS ( vals_content_types ), 0x00,
4209 { &hf_wsp_header_accept_str,
4211 "wsp.header.accept.string",
4212 FT_STRING, BASE_NONE, NULL, 0x00,
4216 { &hf_wsp_header_accept_application,
4217 { "Accept-Application",
4218 "wsp.header.accept_application",
4219 FT_UINT32, BASE_HEX, NULL, 0x00,
4220 "Accept-Application", HFILL
4223 { &hf_wsp_header_accept_application_str,
4224 { "Accept-Application",
4225 "wsp.header.accept_application.string",
4226 FT_STRING, BASE_NONE, NULL, 0x00,
4227 "Accept-Application", HFILL
4230 { &hf_wsp_header_accept_charset,
4232 "wsp.header.accept_charset",
4233 FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00,
4234 "Accept-Charset", HFILL
4237 { &hf_wsp_header_accept_charset_str,
4239 "wsp.header.accept_charset.string",
4240 FT_STRING, BASE_NONE, NULL, 0x00,
4241 "Accept-Charset", HFILL
4244 { &hf_wsp_header_accept_language,
4245 { "Accept-Language",
4246 "wsp.header.accept_language",
4247 FT_UINT8, BASE_HEX, VALS ( vals_languages ), 0x00,
4248 "Accept-Language", HFILL
4251 { &hf_wsp_header_accept_language_str,
4252 { "Accept-Language",
4253 "wsp.header.accept_language.string",
4254 FT_STRING, BASE_NONE, NULL, 0x00,
4255 "Accept-Language", HFILL
4258 { &hf_wsp_header_accept_ranges,
4260 "wsp.header.accept_ranges",
4261 FT_UINT8, BASE_HEX, VALS ( vals_accept_ranges ), 0x00,
4262 "Accept-Ranges", HFILL
4265 { &hf_wsp_header_accept_ranges_str,
4267 "wsp.header.accept_ranges.string",
4268 FT_STRING, BASE_NONE, NULL, 0x00,
4269 "Accept-Ranges", HFILL
4272 { &hf_wsp_header_age,
4275 FT_UINT32, BASE_DEC, NULL, 0x00,
4279 { &hf_wsp_header_openwave_proxy_push_addr,
4280 { "x-up-proxy-push-addr",
4281 "wsp.header.x-up-proxy-push-addr",
4282 FT_BYTES, BASE_HEX, NULL, 0x00,
4283 "The network address and port number that the handset can receive UPNOTIFY pushes on.", HFILL
4286 { &hf_wsp_header_openwave_proxy_push_accept,
4287 { "x-up-proxy-push-accept",
4288 "wsp.header.x-up-proxy-push-accept",
4289 FT_STRING, BASE_NONE, NULL, 0x00,
4290 "The content types that the handset can handle when sent via UPNOTIFY pushes.", HFILL
4293 { &hf_wsp_header_openwave_proxy_push_seq,
4294 { "x-up-proxy-push-seq",
4295 "wsp.header.x-up-proxy-push-seq",
4296 FT_UINT16, BASE_DEC, NULL, 0x00,
4297 "Specifies the sequence number of the last UPNOTIFY push sent.", HFILL
4300 { &hf_wsp_header_openwave_proxy_notify,
4301 { "x-up-proxy-notify",
4302 "wsp.header.x-up-proxy-notify",
4303 FT_UINT8, BASE_DEC, NULL, 0x00,
4304 "Indicates to the handset that there are pending UPNOTIFY pushes waiting.", HFILL
4307 { &hf_wsp_header_openwave_proxy_operator_domain,
4308 { "x-up-proxy-operator-domain",
4309 "wsp.header.x-up-proxy-operator-domain",
4310 FT_STRING, BASE_NONE, NULL, 0x00,
4311 "Indicates the Trusted Provisioning Domain.", HFILL
4314 { &hf_wsp_header_openwave_proxy_home_page,
4315 { "x-up-proxy-home-page",
4316 "wsp.header.x-up-proxy-home-page",
4317 FT_STRING, BASE_NONE, NULL, 0x00,
4318 "Specifies the server-assigned home page URL.", HFILL
4321 { &hf_wsp_header_openwave_devcap_has_color,
4322 { "x-up-devcap-has-color",
4323 "wsp.header.x-up-devcap-has-color",
4324 FT_UINT8, BASE_DEC, NULL, 0x00,
4325 "Indicates if the handset supports colour.", HFILL
4328 { &hf_wsp_header_openwave_devcap_num_softkeys,
4329 { "x-up-devcap-num-softkeys",
4330 "wsp.header.x-up-devcap-num-softkeys",
4331 FT_UINT8, BASE_DEC, NULL, 0x00,
4332 "The number of softkeys that can be displayed on the handset.", HFILL
4335 { &hf_wsp_header_openwave_devcap_softkey_size,
4336 { "x-up-devcap-softkey-size",
4337 "wsp.header.x-up-devcap-softkey-size",
4338 FT_UINT8, BASE_DEC, NULL, 0x00,
4339 "The number of chars that can be displayed on a softkey label.", HFILL
4342 { &hf_wsp_header_openwave_devcap_screen_chars,
4343 { "x-up-devcap-screen-chars",
4344 "wsp.header.x-up-devcap-screen-chars",
4345 FT_UINT8, BASE_DEC, NULL, 0x00,
4346 "The height and width of the handset's display in characters.", HFILL
4349 { &hf_wsp_header_openwave_devcap_screen_pixels,
4350 { "x-up-devcap-screen-pixels",
4351 "wsp.header.x-up-devcap-screen-pixels",
4352 FT_UINT32, BASE_DEC, NULL, 0x00,
4353 "The height and width of the handset's display in pixels.", HFILL
4356 { &hf_wsp_header_openwave_devcap_em_size,
4357 { "x-up-devcap-em-size",
4358 "wsp.header.x-up-devcap-em-size",
4359 FT_UINT32, BASE_DEC, NULL, 0x00,
4360 "The height and width of an uppercase M in pixels in a handset.", HFILL
4363 { &hf_wsp_header_openwave_devcap_screen_depth,
4364 { "x-up-devcap-screen-depth",
4365 "wsp.header.x-up-devcap-screen-depth",
4366 FT_UINT8, BASE_DEC, NULL, 0x00,
4367 "The colour/gray depth of the display in bits.", HFILL
4370 { &hf_wsp_header_openwave_devcap_immed_alert,
4371 { "x-up-devcap-immed-alert",
4372 "wsp.header.x-up-devcap-immed-alert",
4373 FT_UINT8, BASE_DEC, NULL, 0x00,
4374 "Indicates if the handset has support for immediate UPNOTIFY alerts.", HFILL
4377 { &hf_wsp_header_openwave_proxy_net_ask,
4378 { "x-up-proxy-net-ask",
4379 "wsp.header.x-up-proxy-net-ask",
4380 FT_UINT8, BASE_DEC, NULL, 0x00,
4381 "Indicates to browser if circuit switched call is allowed without user interaction", HFILL
4384 { &hf_wsp_header_openwave_proxy_uplink_version,
4385 { "x-up-proxy-uplink-version",
4386 "wsp.header.x-up-proxy-uplink-version",
4387 FT_STRING, BASE_NONE, NULL, 0x00,
4388 "Version of the MAG WAP gateway", HFILL
4391 { &hf_wsp_header_openwave_proxy_tod,
4393 "wsp.header.x-up-proxy-tod",
4394 FT_UINT8, BASE_DEC, NULL, 0x00,
4395 "Time of day", HFILL
4398 { &hf_wsp_header_openwave_proxy_ba_enable,
4399 { "x-up-proxy-ba-enable",
4400 "wsp.header.x-up-proxy-ba-enable",
4401 FT_UINT8, BASE_DEC, NULL, 0x00,
4402 "Indicates if the WAP gateway should cache basic authentication details on behalf of the handset", HFILL
4405 { &hf_wsp_header_openwave_proxy_ba_realm,
4406 { "x-up-proxy-ba-realm",
4407 "wsp.header.x-up-proxy-ba-realm",
4408 FT_STRING, BASE_NONE, NULL, 0x00,
4409 "Indicates the realm within which basic authentication credentials apply", HFILL
4412 { &hf_wsp_header_openwave_proxy_redirect_enable,
4413 { "x-up-proxy-redirect-enable",
4414 "wsp.header.x-up-proxy-redirect-enable",
4415 FT_UINT8, BASE_DEC, NULL, 0x00,
4416 "Indicates if the handset wants the WAP gateway to handle HTTP redirects on its behalf", HFILL
4419 { &hf_wsp_header_openwave_proxy_request_uri,
4420 { "x-up-proxy-request-uri",
4421 "wsp.header.x-up-proxy-request-uri",
4422 FT_STRING, BASE_NONE, NULL, 0x00,
4423 "Indicates to the handset that the previous request was redirected to the specified URI", HFILL
4426 { &hf_wsp_header_openwave_proxy_redirect_status,
4427 { "x-up-proxy-redirect-status",
4428 "wsp.header.x-up-proxy-redirect-status",
4429 FT_UINT32, BASE_DEC, NULL, 0x00,
4430 "Indicates the status of a redirect performed on behalf of a handset", HFILL
4433 { &hf_wsp_header_openwave_proxy_trans_charset,
4434 { "x-up-proxy-trans-charset",
4435 "wsp.header.x-up-proxy-trans-charset",
4436 FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00,
4437 "For POSTs indicates the charset encoding of a document", HFILL
4440 { &hf_wsp_header_openwave_proxy_trans_charset_str,
4441 { "x-up-proxy-trans-charset",
4442 "wsp.header.x-up-proxy-trans-charset.string",
4443 FT_STRING, BASE_NONE, NULL, 0x00,
4444 "For POSTs indicates the charset encoding of a document", HFILL
4447 { &hf_wsp_header_openwave_proxy_linger,
4448 { "x-up-proxy-linger",
4449 "wsp.header.x-up-proxy-linger",
4450 FT_UINT8, BASE_DEC, NULL, 0x00,
4451 "Indicates the circuit linger time in seconds", HFILL
4454 { &hf_wsp_header_openwave_proxy_client_id,
4455 { "x-up-proxy-client-id",
4456 "wsp.header.x-up-proxy-client-id",
4457 FT_BYTES, BASE_DEC, NULL, 0x00,
4458 "The ClientId of the handset", HFILL
4461 { &hf_wsp_header_openwave_proxy_enable_trust,
4462 { "x-up-proxy-enable-trust",
4463 "wsp.header.x-up-proxy-enable-trust",
4464 FT_UINT8, BASE_DEC, NULL, 0x00,
4465 "Indicates whether to enable Trusted Provisioning Domain", HFILL
4468 { &hf_wsp_header_openwave_proxy_trust_old,
4469 { "x-up-proxy-trust-old",
4470 "wsp.header.x-up-proxy-trust-old",
4471 FT_UINT8, BASE_DEC, NULL, 0x00,
4472 "Indicates if the content being returned was received from within the Trusted Provisioning Domain", HFILL
4475 { &hf_wsp_header_openwave_proxy_trust,
4476 { "x-up-proxy-trust",
4477 "wsp.header.x-up-proxy-trust",
4478 FT_UINT8, BASE_DEC, NULL, 0x00,
4479 "Indicates if the content being returned was received from within the Trusted Provisioning Domain", HFILL
4482 { &hf_wsp_header_openwave_proxy_bookmark,
4483 { "x-up-proxy-bookmark",
4484 "wsp.header.x-up-proxy-bookmark",
4485 FT_STRING, BASE_NONE, NULL, 0x00,
4486 "Specifies the URL to use for server-side bookmarks", HFILL
4489 { &hf_wsp_header_openwave_devcap_gui,
4490 { "x-up-devcap-gui",
4491 "wsp.header.x-up-devcap-gui",
4492 FT_UINT8, BASE_DEC, NULL, 0x00,
4493 "Indicates if the handset has a GUI", HFILL
4496 { &hf_wsp_header_bearer_indication,
4498 * XXX - I'm assuming that the bearer indication is
4499 * just a bearer type.
4501 { "Bearer-indication",
4502 "wsp.header.bearer_indication",
4503 FT_UINT32, BASE_HEX, VALS(vals_bearer_types), 0x00,
4504 "Bearer-indication", HFILL
4507 { &hf_wsp_header_cache_control,
4509 "wsp.header.cache_control",
4510 FT_UINT8, BASE_HEX, VALS ( vals_cache_control ), 0x00,
4511 "Cache-Control", HFILL
4514 { &hf_wsp_header_cache_control_str,
4516 "wsp.header.cache_control.string",
4517 FT_STRING, BASE_NONE, NULL, 0x00,
4518 "Cache-Control", HFILL
4521 { &hf_wsp_header_cache_control_field_name,
4523 "wsp.header.cache_control.field_name",
4524 FT_UINT8, BASE_HEX, VALS ( vals_field_names ), 0x00,
4525 "Cache-Control field name", HFILL
4528 { &hf_wsp_header_cache_control_field_name_str,
4530 "wsp.header.cache_control.field_name.str",
4531 FT_STRING, BASE_NONE, NULL, 0x00,
4532 "Cache-Control field name", HFILL
4535 { &hf_wsp_header_connection,
4537 "wsp.header.connection",
4538 FT_UINT8, BASE_HEX, VALS ( vals_connection ), 0x00,
4542 { &hf_wsp_header_connection_str,
4544 "wsp.header.connection_str",
4545 FT_STRING, BASE_NONE, NULL, 0x00,
4549 { &hf_wsp_header_content_length,
4551 "wsp.header.content_length",
4552 FT_UINT32, BASE_DEC, NULL, 0x00,
4553 "Content-Length", HFILL
4556 { &hf_wsp_header_date,
4559 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4563 { &hf_wsp_header_etag,
4566 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
4567 FT_STRING, BASE_NONE, NULL, 0x00,
4571 { &hf_wsp_header_expires,
4573 "wsp.header.expires",
4574 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4578 { &hf_wsp_header_last_modified,
4580 "wsp.header.last_modified",
4581 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4582 "Last-Modified", HFILL
4585 { &hf_wsp_header_location,
4587 "wsp.header.location",
4588 FT_STRING, BASE_NONE, NULL, 0x00,
4592 { &hf_wsp_header_if_modified_since,
4593 { "If-Modified-Since",
4594 "wsp.header.if_modified_since",
4595 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4596 "If-Modified-Since", HFILL
4599 { &hf_wsp_header_pragma,
4601 "wsp.header.pragma",
4602 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
4603 FT_STRING, BASE_NONE, NULL, 0x00,
4607 { &hf_wsp_header_profile,
4609 "wsp.header.profile",
4610 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
4611 FT_STRING, BASE_NONE, NULL, 0x00,
4615 { &hf_wsp_header_server,
4617 "wsp.header.server",
4618 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
4619 FT_STRING, BASE_NONE, NULL, 0x00,
4623 { &hf_wsp_header_transfer_encoding,
4624 { "Transfer Encoding",
4625 "wsp.header.transfer_enc",
4626 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
4627 FT_UINT8, BASE_HEX, VALS ( vals_transfer_encoding ), 0x00,
4628 "Transfer Encoding", HFILL
4631 { &hf_wsp_header_transfer_encoding_str,
4632 { "Transfer Encoding",
4633 "wsp.header.transfer_enc_str",
4634 FT_STRING, BASE_NONE, NULL, 0x00,
4635 "Transfer Encoding", HFILL
4638 { &hf_wsp_header_user_agent,
4640 "wsp.header.user_agent",
4641 /*FT_NONE, BASE_DEC, NULL, 0x00,*/
4642 FT_STRING, BASE_NONE, NULL, 0x00,
4646 { &hf_wsp_header_via,
4649 FT_STRING, BASE_NONE, NULL, 0x00,
4653 { &hf_wsp_header_wap_application_id,
4654 { "X-Wap-Application-Id",
4655 "wsp.header.wap_application_id",
4656 FT_UINT8, BASE_HEX, NULL, 0x00,
4657 "WAP application id", HFILL
4660 { &hf_wsp_header_wap_application_id_str,
4661 { "X-Wap-Application-Id",
4662 "wsp.header.wap_application_id.string",
4663 FT_STRING, BASE_NONE, NULL, 0x00,
4664 "WAP application id", HFILL
4667 { &hf_wsp_header_warning,
4669 "wsp.header.warning",
4670 FT_NONE, BASE_NONE, NULL, 0x00,
4674 { &hf_wsp_header_warning_code,
4676 "wsp.header.warning.code",
4677 FT_UINT32, BASE_DEC, NULL, 0x00,
4678 "Warning Code", HFILL
4681 { &hf_wsp_header_warning_agent,
4683 "wsp.header.warning.agent",
4684 FT_STRING, BASE_NONE, NULL, 0x00,
4685 "Warning Agent", HFILL
4688 { &hf_wsp_header_warning_text,
4690 "wsp.header.warning.text",
4691 FT_STRING, BASE_NONE, NULL, 0x00,
4692 "Warning Text", HFILL
4695 { &hf_wsp_header_application_header,
4696 { "Application Header",
4697 "wsp.header.application_header",
4698 FT_STRING, BASE_NONE, NULL, 0x00,
4699 "Application Header", HFILL
4702 { &hf_wsp_header_application_value,
4703 { "Application Header Value",
4704 "wsp.header.application_header.value",
4705 FT_STRING, BASE_NONE, NULL, 0x00,
4706 "Application Header Value", HFILL
4709 { &hf_wsp_header_content_ID,
4711 "wsp.header.content-id",
4712 FT_STRING, BASE_NONE, NULL, 0x00,
4716 { &hf_wsp_header_x_wap_tod,
4718 "wsp.header.x_wap_tod",
4719 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4723 { &hf_wsp_capabilities_client_SDU,
4725 "wsp.capabilities.client_SDU",
4726 FT_UINT8, BASE_DEC, NULL, 0x00,
4730 { &hf_wsp_capabilities_server_SDU,
4732 "wsp.capabilities.server_SDU",
4733 FT_UINT8, BASE_DEC, NULL, 0x00,
4737 { &hf_wsp_capabilities_protocol_opt,
4738 { "Protocol Options",
4739 "wsp.capabilities.protocol_opt",
4740 FT_STRING, BASE_HEX, NULL, 0x00,
4741 "Protocol Options", HFILL
4744 { &hf_wsp_capabilities_method_MOR,
4746 "wsp.capabilities.method_mor",
4747 FT_UINT8, BASE_DEC, NULL, 0x00,
4751 { &hf_wsp_capabilities_push_MOR,
4753 "wsp.capabilities.push_mor",
4754 FT_UINT8, BASE_DEC, NULL, 0x00,
4758 { &hf_wsp_capabilities_extended_methods,
4759 { "Extended Methods",
4760 "wsp.capabilities.extend_methods",
4761 FT_STRING, BASE_HEX, NULL, 0x00,
4762 "Extended Methods", HFILL
4765 { &hf_wsp_capabilities_header_code_pages,
4766 { "Header Code Pages",
4767 "wsp.capabilities.code_pages",
4768 FT_STRING, BASE_HEX, NULL, 0x00,
4769 "Header Code Pages", HFILL
4772 { &hf_wsp_capabilities_aliases,
4774 "wsp.capabilities.aliases",
4775 FT_UINT8, BASE_HEX, NULL, 0x00,
4779 { &hf_wsp_post_data,
4782 FT_NONE, BASE_NONE, NULL, 0x00,
4786 { &hf_wsp_push_data,
4789 FT_NONE, BASE_NONE, NULL, 0x00,
4793 { &hf_wsp_multipart_data,
4794 { "Data in this part",
4795 "wsp.multipart.data",
4796 FT_NONE, BASE_NONE, NULL, 0x00,
4797 "The data of 1 MIME-multipart part.", HFILL
4803 FT_UINT32, BASE_DEC, NULL, 0x00,
4804 "MIME part of multipart data.", HFILL
4807 { &hf_wsp_redirect_flags,
4809 "wsp.redirect_flags",
4810 FT_UINT8, BASE_HEX, NULL, 0x00,
4811 "Redirect Flags", HFILL
4814 { &hf_wsp_redirect_permanent,
4815 { "Permanent Redirect",
4816 "wsp.redirect_flags.permanent",
4817 FT_BOOLEAN, 8, TFS(&yes_no_truth), PERMANENT_REDIRECT,
4818 "Permanent Redirect", HFILL
4821 { &hf_wsp_redirect_reuse_security_session,
4822 { "Reuse Security Session",
4823 "wsp.redirect_flags.reuse_security_session",
4824 FT_BOOLEAN, 8, TFS(&yes_no_truth), REUSE_SECURITY_SESSION,
4825 "Permanent Redirect", HFILL
4828 { &hf_wsp_redirect_afl,
4831 FT_UINT8, BASE_HEX, NULL, 0x00,
4832 "Redirect Address Flags/Length", HFILL
4835 { &hf_wsp_redirect_afl_bearer_type_included,
4836 { "Bearer Type Included",
4837 "wsp.redirect_afl.bearer_type_included",
4838 FT_BOOLEAN, 8, TFS(&yes_no_truth), BEARER_TYPE_INCLUDED,
4839 "Redirect Address bearer type included", HFILL
4842 { &hf_wsp_redirect_afl_port_number_included,
4843 { "Port Number Included",
4844 "wsp.redirect_afl.port_number_included",
4845 FT_BOOLEAN, 8, TFS(&yes_no_truth), PORT_NUMBER_INCLUDED,
4846 "Redirect Address port number included", HFILL
4849 { &hf_wsp_redirect_afl_address_len,
4851 "wsp.redirect_afl.address_len",
4852 FT_UINT8, BASE_DEC, NULL, ADDRESS_LEN,
4853 "Redirect Address Length", HFILL
4856 { &hf_wsp_redirect_bearer_type,
4858 "wsp.redirect_bearer_type",
4859 FT_UINT8, BASE_HEX, VALS(vals_bearer_types), 0x0,
4860 "Redirect Bearer Type", HFILL
4863 { &hf_wsp_redirect_port_num,
4865 "wsp.redirect_port_num",
4866 FT_UINT16, BASE_DEC, NULL, 0x0,
4867 "Redirect Port Number", HFILL
4870 { &hf_wsp_redirect_ipv4_addr,
4872 "wsp.redirect_ipv4_addr",
4873 FT_IPv4, BASE_NONE, NULL, 0x0,
4874 "Redirect Address (IP)", HFILL
4877 { &hf_wsp_redirect_ipv6_addr,
4879 "wsp.redirect_ipv6_addr",
4880 FT_IPv6, BASE_NONE, NULL, 0x0,
4881 "Redirect Address (IPv6)", HFILL
4884 { &hf_wsp_redirect_addr,
4886 "wsp.redirect_addr",
4887 FT_BYTES, BASE_NONE, NULL, 0x0,
4888 "Redirect Address", HFILL
4893 /* Setup protocol subtree array */
4894 static gint *ett[] = {
4896 &ett_content_type_parameters,
4899 &ett_header_warning,
4900 &ett_header_cache_control_parameters,
4901 &ett_header_cache_control_field_names,
4904 &ett_redirect_flags,
4910 /* Register the protocol name and description */
4911 proto_wsp = proto_register_protocol(
4912 "Wireless Session Protocol", /* protocol name for use by ethereal */
4913 "WSP", /* short version of name */
4914 "wap-wsp" /* Abbreviated protocol name, should Match IANA
4915 < URL:http://www.isi.edu/in-notes/iana/assignments/port-numbers/ >
4919 /* Required function calls to register the header fields and subtrees used */
4920 proto_register_field_array(proto_wsp, hf, array_length(hf));
4921 proto_register_subtree_array(ett, array_length(ett));
4923 register_dissector("wsp-co", dissect_wsp_fromwap_co, proto_wsp);
4924 register_dissector("wsp-cl", dissect_wsp_fromwap_cl, proto_wsp);
4925 wsp_dissector_table = register_dissector_table("wsp.content_type.type",
4926 "WSP content type", FT_UINT8, BASE_HEX);
4927 register_heur_dissector_list("wsp", &heur_subdissector_list);
4929 wsp_fromudp_handle = create_dissector_handle(dissect_wsp_fromudp,
4934 proto_reg_handoff_wsp(void)
4937 * Get a handle for the WMLC dissector.
4939 wmlc_handle = find_dissector("wmlc"); /* Coming soon :) */
4942 * And get a handle for the WTP-over-UDP dissector.
4944 wtp_fromudp_handle = find_dissector("wtp-udp");
4946 /* Only connection-less WSP has no previous handler */
4947 dissector_add("udp.port", UDP_PORT_WSP, wsp_fromudp_handle);
4948 dissector_add("udp.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
4950 /* This dissector is also called from the WTP and WTLS dissectors */