3 * Routines to dissect WSP component of WAP traffic.
5 * $Id: packet-wsp.c,v 1.93 2003/12/07 18:09:52 obiot 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>
15 * Code optimizations, header value dissection simplification with parse error
16 * notification and macros, extra missing headers, WBXML registration
17 * by Olivier Biot <olivier.biot(ad)siemens.com>.
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 /* Edit with a 4-space tabulation */
43 #ifdef NEED_SNPRINTF_H
44 # include "snprintf.h"
49 #include <epan/packet.h>
50 #include <epan/ipv6-utils.h>
51 #include <epan/conversation.h>
53 #include "packet-wap.h"
54 #include "packet-wsp.h"
56 #define PLURALIZE(x) ( (x) == 1 ? "" : "s" )
58 /* Statistics (see doc/README.tapping) */
60 static int wsp_tap = -1;
63 /* File scoped variables for the protocol and registered fields */
64 static int proto_wsp = HF_EMPTY;
67 * Initialize the header field pointers
70 /* WSP header fields and their subfields if available */
71 static int hf_hdr_name = HF_EMPTY;
72 static int hf_hdr_id = HF_EMPTY;
73 static int hf_hdr_accept = HF_EMPTY;
74 static int hf_hdr_accept_charset = HF_EMPTY;
75 static int hf_hdr_accept_encoding = HF_EMPTY;
76 static int hf_hdr_accept_language = HF_EMPTY;
77 static int hf_hdr_accept_ranges = HF_EMPTY;
78 static int hf_hdr_age = HF_EMPTY;
79 static int hf_hdr_allow = HF_EMPTY;
80 static int hf_hdr_authorization = HF_EMPTY;
81 static int hf_hdr_authorization_scheme = HF_EMPTY; /* Subfield */
82 static int hf_hdr_authorization_user_id = HF_EMPTY; /* Subfield */
83 static int hf_hdr_authorization_password = HF_EMPTY; /* Subfield */
84 static int hf_hdr_cache_control = HF_EMPTY;
85 static int hf_hdr_connection = HF_EMPTY;
86 static int hf_hdr_content_base = HF_EMPTY;
87 static int hf_hdr_content_encoding = HF_EMPTY;
88 static int hf_hdr_content_language = HF_EMPTY;
89 static int hf_hdr_content_length = HF_EMPTY;
90 static int hf_hdr_content_location = HF_EMPTY;
91 static int hf_hdr_content_md5 = HF_EMPTY;
92 static int hf_hdr_content_range = HF_EMPTY;
93 static int hf_hdr_content_range_first_byte_pos = HF_EMPTY; /* Subfield */
94 static int hf_hdr_content_range_entity_length = HF_EMPTY; /* Subfield */
95 static int hf_hdr_content_type = HF_EMPTY;
96 static int hf_hdr_date = HF_EMPTY;
97 static int hf_hdr_etag = HF_EMPTY;
98 static int hf_hdr_expires = HF_EMPTY;
99 static int hf_hdr_from = HF_EMPTY;
100 static int hf_hdr_host = HF_EMPTY;
101 static int hf_hdr_if_modified_since = HF_EMPTY;
102 static int hf_hdr_if_match = HF_EMPTY;
103 static int hf_hdr_if_none_match = HF_EMPTY;
104 static int hf_hdr_if_range = HF_EMPTY;
105 static int hf_hdr_if_unmodified_since = HF_EMPTY;
106 static int hf_hdr_last_modified = HF_EMPTY;
107 static int hf_hdr_location = HF_EMPTY;
108 static int hf_hdr_max_forwards = HF_EMPTY;
109 static int hf_hdr_pragma = HF_EMPTY;
110 static int hf_hdr_proxy_authenticate = HF_EMPTY;
111 static int hf_hdr_proxy_authenticate_scheme = HF_EMPTY; /* Subfield */
112 static int hf_hdr_proxy_authenticate_realm = HF_EMPTY; /* Subfield */
113 static int hf_hdr_proxy_authorization = HF_EMPTY;
114 static int hf_hdr_proxy_authorization_scheme = HF_EMPTY; /* Subfield */
115 static int hf_hdr_proxy_authorization_user_id = HF_EMPTY; /* Subfield */
116 static int hf_hdr_proxy_authorization_password = HF_EMPTY; /* Subfield */
117 static int hf_hdr_public = HF_EMPTY;
118 static int hf_hdr_range = HF_EMPTY;
119 static int hf_hdr_range_first_byte_pos = HF_EMPTY; /* Subfield */
120 static int hf_hdr_range_last_byte_pos = HF_EMPTY; /* Subfield */
121 static int hf_hdr_range_suffix_length = HF_EMPTY; /* Subfield */
122 static int hf_hdr_referer = HF_EMPTY;
123 static int hf_hdr_retry_after = HF_EMPTY;
124 static int hf_hdr_server = HF_EMPTY;
125 static int hf_hdr_transfer_encoding = HF_EMPTY;
126 static int hf_hdr_upgrade = HF_EMPTY;
127 static int hf_hdr_user_agent = HF_EMPTY;
128 static int hf_hdr_vary = HF_EMPTY;
129 static int hf_hdr_via = HF_EMPTY;
130 static int hf_hdr_warning = HF_EMPTY;
131 static int hf_hdr_warning_code = HF_EMPTY; /* Subfield */
132 static int hf_hdr_warning_agent = HF_EMPTY; /* Subfield */
133 static int hf_hdr_warning_text = HF_EMPTY; /* Subfield */
134 static int hf_hdr_www_authenticate = HF_EMPTY;
135 static int hf_hdr_www_authenticate_scheme = HF_EMPTY; /* Subfield */
136 static int hf_hdr_www_authenticate_realm = HF_EMPTY; /* Subfield */
137 static int hf_hdr_content_disposition = HF_EMPTY;
138 static int hf_hdr_application_id = HF_EMPTY;
139 static int hf_hdr_content_uri = HF_EMPTY;
140 static int hf_hdr_initiator_uri = HF_EMPTY;
141 static int hf_hdr_bearer_indication = HF_EMPTY;
142 static int hf_hdr_push_flag = HF_EMPTY;
143 static int hf_hdr_push_flag_auth = HF_EMPTY; /* Subfield */
144 static int hf_hdr_push_flag_trust = HF_EMPTY; /* Subfield */
145 static int hf_hdr_push_flag_last = HF_EMPTY; /* Subfield */
146 static int hf_hdr_profile = HF_EMPTY;
147 static int hf_hdr_profile_diff = HF_EMPTY;
148 static int hf_hdr_profile_warning = HF_EMPTY;
149 static int hf_hdr_expect = HF_EMPTY;
150 static int hf_hdr_te = HF_EMPTY;
151 static int hf_hdr_trailer = HF_EMPTY;
152 static int hf_hdr_x_wap_tod = HF_EMPTY;
153 static int hf_hdr_content_id = HF_EMPTY;
154 static int hf_hdr_set_cookie = HF_EMPTY;
155 static int hf_hdr_cookie = HF_EMPTY;
156 static int hf_hdr_encoding_version = HF_EMPTY;
157 static int hf_hdr_x_wap_security = HF_EMPTY;
158 static int hf_hdr_x_wap_application_id = HF_EMPTY;
159 static int hf_hdr_accept_application = HF_EMPTY;
162 /* Openwave headers */
163 static int hf_hdr_openwave_x_up_proxy_operator_domain = HF_EMPTY;
164 static int hf_hdr_openwave_x_up_proxy_home_page = HF_EMPTY;
165 static int hf_hdr_openwave_x_up_proxy_uplink_version = HF_EMPTY;
166 static int hf_hdr_openwave_x_up_proxy_ba_realm = HF_EMPTY;
167 static int hf_hdr_openwave_x_up_proxy_request_uri = HF_EMPTY;
169 static int hf_hdr_openwave_x_up_proxy_client_id = HF_EMPTY;
171 static int hf_hdr_openwave_x_up_proxy_bookmark = HF_EMPTY;
172 static int hf_hdr_openwave_x_up_proxy_push_seq = HF_EMPTY;
173 static int hf_hdr_openwave_x_up_proxy_notify = HF_EMPTY;
174 static int hf_hdr_openwave_x_up_proxy_net_ask = HF_EMPTY;
175 static int hf_hdr_openwave_x_up_proxy_tod = HF_EMPTY;
176 static int hf_hdr_openwave_x_up_proxy_ba_enable = HF_EMPTY;
177 static int hf_hdr_openwave_x_up_proxy_redirect_enable = HF_EMPTY;
178 static int hf_hdr_openwave_x_up_proxy_redirect_status = HF_EMPTY;
179 static int hf_hdr_openwave_x_up_proxy_linger = HF_EMPTY;
180 static int hf_hdr_openwave_x_up_proxy_enable_trust = HF_EMPTY;
181 static int hf_hdr_openwave_x_up_proxy_trust = HF_EMPTY;
182 static int hf_hdr_openwave_x_up_devcap_has_color = HF_EMPTY;
183 static int hf_hdr_openwave_x_up_devcap_num_softkeys = HF_EMPTY;
184 static int hf_hdr_openwave_x_up_devcap_softkey_size = HF_EMPTY;
185 static int hf_hdr_openwave_x_up_devcap_screen_chars = HF_EMPTY;
186 static int hf_hdr_openwave_x_up_devcap_screen_pixels = HF_EMPTY;
187 static int hf_hdr_openwave_x_up_devcap_em_size = HF_EMPTY;
188 static int hf_hdr_openwave_x_up_devcap_screen_depth = HF_EMPTY;
189 static int hf_hdr_openwave_x_up_devcap_immed_alert = HF_EMPTY;
190 static int hf_hdr_openwave_x_up_devcap_gui = HF_EMPTY;
191 static int hf_hdr_openwave_x_up_proxy_trans_charset = HF_EMPTY;
192 static int hf_hdr_openwave_x_up_proxy_push_accept = HF_EMPTY;
195 /* WSP parameter fields */
196 static int hf_parameter_q = HF_EMPTY;
197 static int hf_parameter_charset = HF_EMPTY;
199 static int hf_parameter_textual = HF_EMPTY;
200 static int hf_parameter_type = HF_EMPTY;
201 static int hf_parameter_name = HF_EMPTY;
202 static int hf_parameter_filename = HF_EMPTY;
203 static int hf_parameter_start = HF_EMPTY;
204 static int hf_parameter_start_info = HF_EMPTY;
205 static int hf_parameter_comment = HF_EMPTY;
206 static int hf_parameter_domain = HF_EMPTY;
207 static int hf_parameter_path = HF_EMPTY;
208 static int hf_parameter_sec = HF_EMPTY;
209 static int hf_parameter_mac = HF_EMPTY;
210 static int hf_parameter_upart_type = HF_EMPTY;
211 static int hf_parameter_upart_type_value = HF_EMPTY;
212 static int hf_parameter_level = HF_EMPTY;
215 /* Old header fields */
217 static int hf_wsp_header_tid = HF_EMPTY;
218 static int hf_wsp_header_pdu_type = HF_EMPTY;
219 static int hf_wsp_version_major = HF_EMPTY;
220 static int hf_wsp_version_minor = HF_EMPTY;
221 static int hf_wsp_capability_length = HF_EMPTY;
222 static int hf_wsp_capabilities_section = HF_EMPTY;
223 static int hf_wsp_capabilities_client_SDU = HF_EMPTY;
224 static int hf_wsp_capabilities_server_SDU = HF_EMPTY;
225 static int hf_wsp_capabilities_protocol_opt = HF_EMPTY;
226 static int hf_wsp_capabilities_method_MOR = HF_EMPTY;
227 static int hf_wsp_capabilities_push_MOR = HF_EMPTY;
228 static int hf_wsp_capabilities_extended_methods = HF_EMPTY;
229 static int hf_wsp_capabilities_header_code_pages = HF_EMPTY;
230 static int hf_wsp_capabilities_aliases = HF_EMPTY;
231 static int hf_wsp_header_uri_len = HF_EMPTY;
232 static int hf_wsp_header_uri = HF_EMPTY;
233 static int hf_wsp_server_session_id = HF_EMPTY;
234 static int hf_wsp_header_status = HF_EMPTY;
235 static int hf_wsp_header_length = HF_EMPTY;
236 static int hf_wsp_headers_section = HF_EMPTY;
237 static int hf_wsp_header = HF_EMPTY;
238 static int hf_wsp_content_type = HF_EMPTY;
239 static int hf_wsp_content_type_str = HF_EMPTY;
240 static int hf_wsp_parameter_well_known_charset = HF_EMPTY;
241 static int hf_wsp_parameter_type = HF_EMPTY;
242 static int hf_wsp_parameter_name = HF_EMPTY;
243 static int hf_wsp_parameter_filename = HF_EMPTY;
244 static int hf_wsp_parameter_start = HF_EMPTY;
245 static int hf_wsp_parameter_start_info = HF_EMPTY;
246 static int hf_wsp_parameter_comment = HF_EMPTY;
247 static int hf_wsp_parameter_domain = HF_EMPTY;
248 static int hf_wsp_parameter_path = HF_EMPTY;
249 static int hf_wsp_parameter_sec = HF_EMPTY;
250 static int hf_wsp_parameter_mac = HF_EMPTY;
251 static int hf_wsp_parameter_upart_type = HF_EMPTY;
252 static int hf_wsp_parameter_upart_type_value = HF_EMPTY;
253 static int hf_wsp_parameter_level = HF_EMPTY;
254 static int hf_wsp_reply_data = HF_EMPTY;
255 static int hf_wsp_post_data = HF_EMPTY;
256 static int hf_wsp_push_data = HF_EMPTY;
257 static int hf_wsp_multipart_data = HF_EMPTY;
258 static int hf_wsp_mpart = HF_EMPTY;
260 /* Header code page shift sequence */
261 static int hf_wsp_header_shift_code = HF_EMPTY;
263 /* WSP Redirect fields */
264 static int hf_wsp_redirect_flags = HF_EMPTY;
265 static int hf_wsp_redirect_permanent = HF_EMPTY;
266 static int hf_wsp_redirect_reuse_security_session = HF_EMPTY;
267 static int hf_wsp_redirect_afl = HF_EMPTY;
268 static int hf_wsp_redirect_afl_bearer_type_included = HF_EMPTY;
269 static int hf_wsp_redirect_afl_port_number_included = HF_EMPTY;
270 static int hf_wsp_redirect_afl_address_len = HF_EMPTY;
271 static int hf_wsp_redirect_bearer_type = HF_EMPTY;
272 static int hf_wsp_redirect_port_num = HF_EMPTY;
273 static int hf_wsp_redirect_ipv4_addr = HF_EMPTY;
274 static int hf_wsp_redirect_ipv6_addr = HF_EMPTY;
275 static int hf_wsp_redirect_addr = HF_EMPTY;
278 * Initialize the subtree pointers
282 static gint ett_wsp = ETT_EMPTY;
283 /* WSP headers tree */
284 static gint ett_header = ETT_EMPTY;
285 /* WSP header subtree */
286 static gint ett_headers = ETT_EMPTY;
287 /* CO-WSP session capabilities */
288 static gint ett_capabilities = ETT_EMPTY;
289 static gint ett_post = ETT_EMPTY;
290 static gint ett_redirect_flags = ETT_EMPTY;
291 static gint ett_redirect_afl = ETT_EMPTY;
292 static gint ett_multiparts = ETT_EMPTY;
293 static gint ett_mpartlist = ETT_EMPTY;
297 /* Handle for WSP-over-UDP dissector */
298 static dissector_handle_t wsp_fromudp_handle;
300 /* Handle for WTP-over-UDP dissector */
301 static dissector_handle_t wtp_fromudp_handle;
303 /* Handle for WBXML dissector */
304 static dissector_handle_t wbxml_handle;
306 const value_string vals_pdu_type[] = {
307 { 0x00, "Reserved" },
309 { 0x02, "ConnectReply" },
310 { 0x03, "Redirect" },
312 { 0x05, "Disconnect" },
314 { 0x07, "ConfirmedPush" },
318 /* 0x10 - 0x3F Unassigned */
326 /* 0x45 - 0x4F Unassigned (Get PDU) */
327 /* 0x50 - 0x5F Extended method (Get PDU) */
328 { 0x50, "Extended Get Method 0"},
329 { 0x51, "Extended Get Method 1"},
330 { 0x52, "Extended Get Method 2"},
331 { 0x53, "Extended Get Method 3"},
332 { 0x54, "Extended Get Method 4"},
333 { 0x55, "Extended Get Method 5"},
334 { 0x56, "Extended Get Method 6"},
335 { 0x57, "Extended Get Method 7"},
336 { 0x58, "Extended Get Method 8"},
337 { 0x59, "Extended Get Method 9"},
338 { 0x5A, "Extended Get Method 10"},
339 { 0x5B, "Extended Get Method 11"},
340 { 0x5C, "Extended Get Method 12"},
341 { 0x5D, "Extended Get Method 13"},
342 { 0x5E, "Extended Get Method 14"},
343 { 0x5F, "Extended Get Method 15"},
348 /* 0x62 - 0x6F Unassigned (Post PDU) */
349 /* 0x70 - 0x7F Extended method (Post PDU) */
350 { 0x70, "Extended Post Method 0"},
351 { 0x71, "Extended Post Method 1"},
352 { 0x72, "Extended Post Method 2"},
353 { 0x73, "Extended Post Method 3"},
354 { 0x74, "Extended Post Method 4"},
355 { 0x75, "Extended Post Method 5"},
356 { 0x76, "Extended Post Method 6"},
357 { 0x77, "Extended Post Method 7"},
358 { 0x78, "Extended Post Method 8"},
359 { 0x79, "Extended Post Method 9"},
360 { 0x7A, "Extended Post Method 10"},
361 { 0x7B, "Extended Post Method 11"},
362 { 0x7C, "Extended Post Method 12"},
363 { 0x7D, "Extended Post Method 13"},
364 { 0x7E, "Extended Post Method 14"},
365 { 0x7F, "Extended Post Method 15"},
367 /* 0x80 - 0xFF Reserved */
373 /* The WSP status codes are inherited from the HTTP status codes */
374 const value_string vals_status[] = {
375 /* 0x00 - 0x0F Reserved */
377 { 0x10, "100 Continue" },
378 { 0x11, "101 Switching Protocols" },
381 { 0x21, "201 Created" },
382 { 0x22, "202 Accepted" },
383 { 0x23, "203 Non-Authoritative Information" },
384 { 0x24, "204 No Content" },
385 { 0x25, "205 Reset Content" },
386 { 0x26, "206 Partial Content" },
388 { 0x30, "300 Multiple Choices" },
389 { 0x31, "301 Moved Permanently" },
390 { 0x32, "302 Moved Temporarily" },
391 { 0x33, "303 See Other" },
392 { 0x34, "304 Not Modified" },
393 { 0x35, "305 Use Proxy" },
394 { 0x37, "307 Temporary Redirect" },
396 { 0x40, "400 Bad Request" },
397 { 0x41, "401 Unauthorised" },
398 { 0x42, "402 Payment Required" },
399 { 0x43, "403 Forbidden" },
400 { 0x44, "404 Not Found" },
401 { 0x45, "405 Method Not Allowed" },
402 { 0x46, "406 Not Acceptable" },
403 { 0x47, "407 Proxy Authentication Required" },
404 { 0x48, "408 Request Timeout" },
405 { 0x49, "409 Conflict" },
406 { 0x4A, "410 Gone" },
407 { 0x4B, "411 Length Required" },
408 { 0x4C, "412 Precondition Failed" },
409 { 0x4D, "413 Request Entity Too Large" },
410 { 0x4E, "414 Request-URI Too Large" },
411 { 0x4F, "415 Unsupported Media Type" },
412 { 0x50, "416 Requested Range Not Satisfiable" },
413 { 0x51, "417 Expectation Failed" },
415 { 0x60, "500 Internal Server Error" },
416 { 0x61, "501 Not Implemented" },
417 { 0x62, "502 Bad Gateway" },
418 { 0x63, "503 Service Unavailable" },
419 { 0x64, "504 Gateway Timeout" },
420 { 0x65, "505 WSP/HTTP Version Not Supported" },
425 const value_string vals_wsp_reason_codes[] = {
426 { 0xE0, "Protocol Error (Illegal PDU)" },
427 { 0xE1, "Session disconnected" },
428 { 0xE2, "Session suspended" },
429 { 0xE3, "Session resumed" },
430 { 0xE4, "Peer congested" },
431 { 0xE5, "Session connect failed" },
432 { 0xE6, "Maximum receive unit size exceeded" },
433 { 0xE7, "Maximum outstanding requests exceeded" },
434 { 0xE8, "Peer request" },
435 { 0xE9, "Network error" },
436 { 0xEA, "User request" },
437 { 0xEB, "No specific cause, no retries" },
438 { 0xEC, "Push message cannot be delivered" },
439 { 0xED, "Push message discarded" },
440 { 0xEE, "Content type cannot be processed" },
448 #define FN_ACCEPT 0x00
449 #define FN_ACCEPT_CHARSET_DEP 0x01 /* encoding version 1.1, deprecated */
450 #define FN_ACCEPT_ENCODING_DEP 0x02 /* encoding version 1.1, deprecated */
451 #define FN_ACCEPT_LANGUAGE 0x03
452 #define FN_ACCEPT_RANGES 0x04
454 #define FN_ALLOW 0x06
455 #define FN_AUTHORIZATION 0x07
456 #define FN_CACHE_CONTROL_DEP 0x08 /* encoding version 1.1, deprecated */
457 #define FN_CONNECTION 0x09
458 #define FN_CONTENT_BASE 0x0A
459 #define FN_CONTENT_ENCODING 0x0B
460 #define FN_CONTENT_LANGUAGE 0x0C
461 #define FN_CONTENT_LENGTH 0x0D
462 #define FN_CONTENT_LOCATION 0x0E
463 #define FN_CONTENT_MD5 0x0F
464 #define FN_CONTENT_RANGE_DEP 0x10 /* encoding version 1.1, deprecated */
465 #define FN_CONTENT_TYPE 0x11
468 #define FN_EXPIRES 0x14
471 #define FN_IF_MODIFIED_SINCE 0x17
472 #define FN_IF_MATCH 0x18
473 #define FN_IF_NONE_MATCH 0x19
474 #define FN_IF_RANGE 0x1A
475 #define FN_IF_UNMODIFIED_SINCE 0x1B
476 #define FN_LOCATION 0x1C
477 #define FN_LAST_MODIFIED 0x1D
478 #define FN_MAX_FORWARDS 0x1E
479 #define FN_PRAGMA 0x1F
480 #define FN_PROXY_AUTHENTICATE 0x20
481 #define FN_PROXY_AUTHORIZATION 0x21
482 #define FN_PUBLIC 0x22
483 #define FN_RANGE 0x23
484 #define FN_REFERER 0x24
485 #define FN_RETRY_AFTER 0x25
486 #define FN_SERVER 0x26
487 #define FN_TRANSFER_ENCODING 0x27
488 #define FN_UPGRADE 0x28
489 #define FN_USER_AGENT 0x29
492 #define FN_WARNING 0x2C
493 #define FN_WWW_AUTHENTICATE 0x2D
494 #define FN_CONTENT_DISPOSITION 0x2E
495 #define FN_X_WAP_APPLICATION_ID 0x2F
496 #define FN_X_WAP_CONTENT_URI 0x30
497 #define FN_X_WAP_INITIATOR_URI 0x31
498 #define FN_ACCEPT_APPLICATION 0x32
499 #define FN_BEARER_INDICATION 0x33
500 #define FN_PUSH_FLAG 0x34
501 #define FN_PROFILE 0x35
502 #define FN_PROFILE_DIFF 0x36
503 #define FN_PROFILE_WARNING 0x37
504 #define FN_EXPECT 0x38
506 #define FN_TRAILER 0x3A
507 #define FN_ACCEPT_CHARSET 0x3B /* encoding version 1.3 */
508 #define FN_ACCEPT_ENCODING 0x3C /* encoding version 1.3 */
509 #define FN_CACHE_CONTROL 0x3D /* encoding version 1.3 */
510 #define FN_CONTENT_RANGE 0x3E /* encoding version 1.3 */
511 #define FN_X_WAP_TOD 0x3F
512 #define FN_CONTENT_ID 0x40
513 #define FN_SET_COOKIE 0x41
514 #define FN_COOKIE 0x42
515 #define FN_ENCODING_VERSION 0x43
516 #define FN_PROFILE_WARNING14 0x44 /* encoding version 1.4 */
517 #define FN_CONTENT_DISPOSITION14 0x45 /* encoding version 1.4 */
518 #define FN_X_WAP_SECURITY 0x46
519 #define FN_CACHE_CONTROL14 0x47 /* encoding version 1.4 */
523 * Openwave field names.
525 #define FN_OPENWAVE_PROXY_PUSH_ADDR 0x00
526 #define FN_OPENWAVE_PROXY_PUSH_ACCEPT 0x01
527 #define FN_OPENWAVE_PROXY_PUSH_SEQ 0x02
528 #define FN_OPENWAVE_PROXY_NOTIFY 0x03
529 #define FN_OPENWAVE_PROXY_OPERATOR_DOMAIN 0x04
530 #define FN_OPENWAVE_PROXY_HOME_PAGE 0x05
531 #define FN_OPENWAVE_DEVCAP_HAS_COLOR 0x06
532 #define FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS 0x07
533 #define FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE 0x08
534 #define FN_OPENWAVE_DEVCAP_SCREEN_CHARS 0x09
535 #define FN_OPENWAVE_DEVCAP_SCREEN_PIXELS 0x0A
536 #define FN_OPENWAVE_DEVCAP_EM_SIZE 0x0B
537 #define FN_OPENWAVE_DEVCAP_SCREEN_DEPTH 0x0C
538 #define FN_OPENWAVE_DEVCAP_IMMED_ALERT 0x0D
539 #define FN_OPENWAVE_PROXY_NET_ASK 0x0E
540 #define FN_OPENWAVE_PROXY_UPLINK_VERSION 0x0F
541 #define FN_OPENWAVE_PROXY_TOD 0x10
542 #define FN_OPENWAVE_PROXY_BA_ENABLE 0x11
543 #define FN_OPENWAVE_PROXY_BA_REALM 0x12
544 #define FN_OPENWAVE_PROXY_REDIRECT_ENABLE 0x13
545 #define FN_OPENWAVE_PROXY_REQUEST_URI 0x14
546 #define FN_OPENWAVE_PROXY_REDIRECT_STATUS 0x15
547 #define FN_OPENWAVE_PROXY_TRANS_CHARSET 0x16
548 #define FN_OPENWAVE_PROXY_LINGER 0x17
549 #define FN_OPENWAVE_PROXY_CLIENT_ID 0x18
550 #define FN_OPENWAVE_PROXY_ENABLE_TRUST 0x19
551 #define FN_OPENWAVE_PROXY_TRUST_OLD 0x1A
552 #define FN_OPENWAVE_PROXY_TRUST 0x20
553 #define FN_OPENWAVE_PROXY_BOOKMARK 0x21
554 #define FN_OPENWAVE_DEVCAP_GUI 0x22
556 static const value_string vals_openwave_field_names[] = {
557 { FN_OPENWAVE_PROXY_PUSH_ADDR, "x-up-proxy-push-addr" },
558 { FN_OPENWAVE_PROXY_PUSH_ACCEPT, "x-up-proxy-push-accept" },
559 { FN_OPENWAVE_PROXY_PUSH_SEQ, "x-up-proxy-seq" },
560 { FN_OPENWAVE_PROXY_NOTIFY, "x-up-proxy-notify" },
561 { FN_OPENWAVE_PROXY_OPERATOR_DOMAIN, "x-up-proxy-operator-domain" },
562 { FN_OPENWAVE_PROXY_HOME_PAGE, "x-up-proxy-home-page" },
563 { FN_OPENWAVE_DEVCAP_HAS_COLOR, "x-up-devcap-has-color" },
564 { FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS, "x-up-devcap-num-softkeys" },
565 { FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE, "x-up-devcap-softkey-size" },
566 { FN_OPENWAVE_DEVCAP_SCREEN_CHARS, "x-up-devcap-screen-chars" },
567 { FN_OPENWAVE_DEVCAP_SCREEN_PIXELS, "x-up-devcap-screen-pixels" },
568 { FN_OPENWAVE_DEVCAP_EM_SIZE, "x-up-devcap-em-size" },
569 { FN_OPENWAVE_DEVCAP_SCREEN_DEPTH, "x-up-devcap-screen-depth" },
570 { FN_OPENWAVE_DEVCAP_IMMED_ALERT, "x-up-devcap-immed-alert" },
571 { FN_OPENWAVE_PROXY_NET_ASK, "x-up-proxy-net-ask" },
572 { FN_OPENWAVE_PROXY_UPLINK_VERSION, "x-up-proxy-uplink-version" },
573 { FN_OPENWAVE_PROXY_TOD, "x-up-proxy-tod" },
574 { FN_OPENWAVE_PROXY_BA_ENABLE, "x-up-proxy-ba-enable" },
575 { FN_OPENWAVE_PROXY_BA_REALM, "x-up-proxy-ba-realm" },
576 { FN_OPENWAVE_PROXY_REDIRECT_ENABLE, "x-up-proxy-redirect-enable" },
577 { FN_OPENWAVE_PROXY_REQUEST_URI, "x-up-proxy-request-uri" },
578 { FN_OPENWAVE_PROXY_REDIRECT_STATUS, "x-up-proxy-redirect-status" },
579 { FN_OPENWAVE_PROXY_TRANS_CHARSET, "x-up-proxy-trans-charset" },
580 { FN_OPENWAVE_PROXY_LINGER, "x-up-proxy-linger" },
581 { FN_OPENWAVE_PROXY_CLIENT_ID, "x-up-proxy-client-id" },
582 { FN_OPENWAVE_PROXY_ENABLE_TRUST, "x-up-proxy-enable-trust" },
583 { FN_OPENWAVE_PROXY_TRUST_OLD, "x-up-proxy-trust-old" },
584 { FN_OPENWAVE_PROXY_TRUST, "x-up-proxy-trust" },
585 { FN_OPENWAVE_PROXY_BOOKMARK, "x-up-proxy-bookmark" },
586 { FN_OPENWAVE_DEVCAP_GUI, "x-up-devcap-gui" },
591 static const value_string vals_field_names[] = {
592 { FN_ACCEPT, "Accept" },
593 { FN_ACCEPT_CHARSET_DEP, "Accept-Charset (encoding 1.1)" },
594 { FN_ACCEPT_ENCODING_DEP, "Accept-Encoding (encoding 1.1)" },
595 { FN_ACCEPT_LANGUAGE, "Accept-Language" },
596 { FN_ACCEPT_RANGES, "Accept-Ranges" },
598 { FN_ALLOW, "Allow" },
599 { FN_AUTHORIZATION, "Authorization" },
600 { FN_CACHE_CONTROL_DEP, "Cache-Control (encoding 1.1)" },
601 { FN_CONNECTION, "Connection" },
602 { FN_CONTENT_BASE, "Content-Base" },
603 { FN_CONTENT_ENCODING, "Content-Encoding" },
604 { FN_CONTENT_LANGUAGE, "Content-Language" },
605 { FN_CONTENT_LENGTH, "Content-Length" },
606 { FN_CONTENT_LOCATION, "Content-Location" },
607 { FN_CONTENT_MD5, "Content-MD5" },
608 { FN_CONTENT_RANGE_DEP, "Content-Range (encoding 1.1)" },
609 { FN_CONTENT_TYPE, "Content-Type" },
612 { FN_EXPIRES, "Expires" },
615 { FN_IF_MODIFIED_SINCE, "If-Modified-Since" },
616 { FN_IF_MATCH, "If-Match" },
617 { FN_IF_NONE_MATCH, "If-None-Match" },
618 { FN_IF_RANGE, "If-Range" },
619 { FN_IF_UNMODIFIED_SINCE, "If-Unmodified-Since" },
620 { FN_LOCATION, "Location" },
621 { FN_LAST_MODIFIED, "Last-Modified" },
622 { FN_MAX_FORWARDS, "Max-Forwards" },
623 { FN_PRAGMA, "Pragma" },
624 { FN_PROXY_AUTHENTICATE, "Proxy-Authenticate" },
625 { FN_PROXY_AUTHORIZATION, "Proxy-Authorization" },
626 { FN_PUBLIC, "Public" },
627 { FN_RANGE, "Range" },
628 { FN_REFERER, "Referer" },
629 { FN_RETRY_AFTER, "Retry-After" },
630 { FN_SERVER, "Server" },
631 { FN_TRANSFER_ENCODING, "Transfer-Encoding" },
632 { FN_UPGRADE, "Upgrade" },
633 { FN_USER_AGENT, "User-Agent" },
636 { FN_WARNING, "Warning" },
637 { FN_WWW_AUTHENTICATE, "WWW-Authenticate" },
638 { FN_CONTENT_DISPOSITION, "Content-Disposition" },
639 { FN_X_WAP_APPLICATION_ID, "X-Wap-Application-ID" },
640 { FN_X_WAP_CONTENT_URI, "X-Wap-Content-URI" },
641 { FN_X_WAP_INITIATOR_URI, "X-Wap-Initiator-URI" },
642 { FN_ACCEPT_APPLICATION, "Accept-Application" },
643 { FN_BEARER_INDICATION, "Bearer-Indication" },
644 { FN_PUSH_FLAG, "Push-Flag" },
645 { FN_PROFILE, "Profile" },
646 { FN_PROFILE_DIFF, "Profile-Diff" },
647 { FN_PROFILE_WARNING, "Profile-Warning" },
648 { FN_EXPECT, "Expect" },
650 { FN_TRAILER, "Trailer" },
651 { FN_ACCEPT_CHARSET, "Accept-Charset" },
652 { FN_ACCEPT_ENCODING, "Accept-Encoding" },
653 { FN_CACHE_CONTROL, "Cache-Control" },
654 { FN_CONTENT_RANGE, "Content-Range" },
655 { FN_X_WAP_TOD, "X-Wap-Tod" },
656 { FN_CONTENT_ID, "Content-ID" },
657 { FN_SET_COOKIE, "Set-Cookie" },
658 { FN_COOKIE, "Cookie" },
659 { FN_ENCODING_VERSION, "Encoding-Version" },
660 { FN_PROFILE_WARNING14, "Profile-Warning (encoding 1.4)" },
661 { FN_CONTENT_DISPOSITION14,"Content-Disposition (encoding 1.4)" },
662 { FN_X_WAP_SECURITY, "X-WAP-Security" },
663 { FN_CACHE_CONTROL14, "Cache-Control (encoding 1.4)" },
668 * Bearer types (from the WDP specification).
672 #define BT_GSM_USSD 0x02
673 #define BT_GSM_SMS 0x03
674 #define BT_ANSI_136_GUTS 0x04
675 #define BT_IS_95_SMS 0x05
676 #define BT_IS_95_CSD 0x06
677 #define BT_IS_95_PACKET_DATA 0x07
678 #define BT_ANSI_136_CSD 0x08
679 #define BT_ANSI_136_PACKET_DATA 0x09
680 #define BT_GSM_CSD 0x0A
681 #define BT_GSM_GPRS 0x0B
682 #define BT_GSM_USSD_IPv4 0x0C
683 #define BT_AMPS_CDPD 0x0D
684 #define BT_PDC_CSD 0x0E
685 #define BT_PDC_PACKET_DATA 0x0F
686 #define BT_IDEN_SMS 0x10
687 #define BT_IDEN_CSD 0x11
688 #define BT_IDEN_PACKET_DATA 0x12
689 #define BT_PAGING_FLEX 0x13
690 #define BT_PHS_SMS 0x14
691 #define BT_PHS_CSD 0x15
692 #define BT_GSM_USSD_GSM_SC 0x16
693 #define BT_TETRA_SDS_ITSI 0x17
694 #define BT_TETRA_SDS_MSISDN 0x18
695 #define BT_TETRA_PACKET_DATA 0x19
696 #define BT_PAGING_REFLEX 0x1A
697 #define BT_GSM_USSD_MSISDN 0x1B
698 #define BT_MOBITEX_MPAK 0x1C
699 #define BT_ANSI_136_GHOST 0x1D
701 static const value_string vals_bearer_types[] = {
704 { BT_GSM_USSD, "GSM USSD" },
705 { BT_GSM_SMS, "GSM SMS" },
706 { BT_ANSI_136_GUTS, "ANSI-136 GUTS/R-Data" },
707 { BT_IS_95_SMS, "IS-95 CDMA SMS" },
708 { BT_IS_95_CSD, "IS-95 CDMA CSD" },
709 { BT_IS_95_PACKET_DATA, "IS-95 CDMA Packet data" },
710 { BT_ANSI_136_CSD, "ANSI-136 CSD" },
711 { BT_ANSI_136_PACKET_DATA, "ANSI-136 Packet data" },
712 { BT_GSM_CSD, "GSM CSD" },
713 { BT_GSM_GPRS, "GSM GPRS" },
714 { BT_GSM_USSD_IPv4, "GSM USSD (IPv4 addresses)" },
715 { BT_AMPS_CDPD, "AMPS CDPD" },
716 { BT_PDC_CSD, "PDC CSD" },
717 { BT_PDC_PACKET_DATA, "PDC Packet data" },
718 { BT_IDEN_SMS, "IDEN SMS" },
719 { BT_IDEN_CSD, "IDEN CSD" },
720 { BT_IDEN_PACKET_DATA, "IDEN Packet data" },
721 { BT_PAGING_FLEX, "Paging network FLEX(TM)" },
722 { BT_PHS_SMS, "PHS SMS" },
723 { BT_PHS_CSD, "PHS CSD" },
724 { BT_GSM_USSD_GSM_SC, "GSM USSD (GSM Service Code addresses)" },
725 { BT_TETRA_SDS_ITSI, "TETRA SDS (ITSI addresses)" },
726 { BT_TETRA_SDS_MSISDN, "TETRA SDS (MSISDN addresses)" },
727 { BT_TETRA_PACKET_DATA, "TETRA Packet data" },
728 { BT_PAGING_REFLEX, "Paging network ReFLEX(TM)" },
729 { BT_GSM_USSD_MSISDN, "GSM USSD (MSISDN addresses)" },
730 { BT_MOBITEX_MPAK, "Mobitex MPAK" },
731 { BT_ANSI_136_GHOST, "ANSI-136 GHOST/R-Data" },
735 static const value_string vals_content_types[] = {
736 /* Well-known media types */
739 { 0x02, "text/html" },
740 { 0x03, "text/plain" },
741 { 0x04, "text/x-hdml" },
742 { 0x05, "text/x-ttml" },
743 { 0x06, "text/x-vCalendar" },
744 { 0x07, "text/x-vCard" },
745 { 0x08, "text/vnd.wap.wml" },
746 { 0x09, "text/vnd.wap.wmlscript" },
747 { 0x0A, "text/vnd.wap.channel" },
748 { 0x0B, "multipart/*" },
749 { 0x0C, "multipart/mixed" },
750 { 0x0D, "multipart/form-data" },
751 { 0x0E, "multipart/byteranges" },
752 { 0x0F, "multipart/alternative" },
753 { 0x10, "application/*" },
754 { 0x11, "application/java-vm" },
755 { 0x12, "application/x-www-form-urlencoded" },
756 { 0x13, "application/x-hdmlc" },
757 { 0x14, "application/vnd.wap.wmlc" },
758 { 0x15, "application/vnd.wap.wmlscriptc" },
759 { 0x16, "application/vnd.wap.channelc" },
760 { 0x17, "application/vnd.wap.uaprof" },
761 { 0x18, "application/vnd.wap.wtls-ca-certificate" },
762 { 0x19, "application/vnd.wap.wtls-user-certificate" },
763 { 0x1A, "application/x-x509-ca-cert" },
764 { 0x1B, "application/x-x509-user-cert" },
766 { 0x1D, "image/gif" },
767 { 0x1E, "image/jpeg" },
768 { 0x1F, "image/tiff" },
769 { 0x20, "image/png" },
770 { 0x21, "image/vnd.wap.wbmp" },
771 { 0x22, "application/vnd.wap.multipart.*" },
772 { 0x23, "application/vnd.wap.multipart.mixed" },
773 { 0x24, "application/vnd.wap.multipart.form-data" },
774 { 0x25, "application/vnd.wap.multipart.byteranges" },
775 { 0x26, "application/vnd.wap.multipart.alternative" },
776 { 0x27, "application/xml" },
777 { 0x28, "text/xml" },
778 { 0x29, "application/vnd.wap.wbxml" },
779 { 0x2A, "application/x-x968-cross-cert" },
780 { 0x2B, "application/x-x968-ca-cert" },
781 { 0x2C, "application/x-x968-user-cert" },
782 { 0x2D, "text/vnd.wap.si" },
783 { 0x2E, "application/vnd.wap.sic" },
784 { 0x2F, "text/vnd.wap.sl" },
785 { 0x30, "application/vnd.wap.slc" },
786 { 0x31, "text/vnd.wap.co" },
787 { 0x32, "application/vnd.wap.coc" },
788 { 0x33, "application/vnd.wap.multipart.related" },
789 { 0x34, "application/vnd.wap.sia" },
790 { 0x35, "text/vnd.wap.connectivity-xml" },
791 { 0x36, "application/vnd.wap.connectivity-wbxml" },
792 { 0x37, "application/pkcs7-mime" },
793 { 0x38, "application/vnd.wap.hashed-certificate" },
794 { 0x39, "application/vnd.wap.signed-certificate" },
795 { 0x3A, "application/vnd.wap.cert-response" },
796 { 0x3B, "application/xhtml+xml" },
797 { 0x3C, "application/wml+xml" },
798 { 0x3D, "text/css" },
799 { 0x3E, "application/vnd.wap.mms-message" },
800 { 0x3F, "application/vnd.wap.rollover-certificate" },
801 { 0x40, "application/vnd.wap.locc+wbxml"},
802 { 0x41, "application/vnd.wap.loc+xml"},
803 { 0x42, "application/vnd.syncml.dm+wbxml"},
804 { 0x43, "application/vnd.syncml.dm+xml"},
805 { 0x44, "application/vnd.syncml.notification"},
806 { 0x45, "application/vnd.wap.xhtml+xml"},
807 { 0x46, "application/vnd.wv.csp.cir"},
808 { 0x47, "application/vnd.oma.dd+xml"},
809 { 0x48, "application/vnd.oma.drm.message"},
810 { 0x49, "application/vnd.oma.drm.content"},
811 { 0x4A, "application/vnd.oma.drm.rights+xml"},
812 { 0x4B, "application/vnd.oma.drm.rights+wbxml"},
813 { 0x4C, "application/vnd.wv.csp+xml"},
814 { 0x4D, "application/vnd.wv.csp+wbxml"},
815 /* The following media types are registered by 3rd parties */
816 { 0x0201, "application/vnd.uplanet.cachop-wbxml" },
817 { 0x0202, "application/vnd.uplanet.signal" },
818 { 0x0203, "application/vnd.uplanet.alert-wbxml" },
819 { 0x0204, "application/vnd.uplanet.list-wbxml" },
820 { 0x0205, "application/vnd.uplanet.listcmd-wbxml" },
821 { 0x0206, "application/vnd.uplanet.channel-wbxml" },
822 { 0x0207, "application/vnd.uplanet.provisioning-status-uri" },
823 { 0x0208, "x-wap.multipart/vnd.uplanet.header-set" },
824 { 0x0209, "application/vnd.uplanet.bearer-choice-wbxml" },
825 { 0x020A, "application/vnd.phonecom.mmc-wbxml" },
826 { 0x020B, "application/vnd.nokia.syncset+wbxml" },
827 { 0x020C, "image/x-up-wpng"},
828 { 0x0300, "application/iota.mmc-wbxml"},
829 { 0x0301, "application/iota.mmc-xml"},
833 static const value_string vals_languages[] = {
834 { 0x01, "Afar (aa)" },
835 { 0x02, "Abkhazian (ab)" },
836 { 0x03, "Afrikaans (af)" },
837 { 0x04, "Amharic (am)" },
838 { 0x05, "Arabic (ar)" },
839 { 0x06, "Assamese (as)" },
840 { 0x07, "Aymara (ay)" },
841 { 0x08, "Azerbaijani (az)" },
842 { 0x09, "Bashkir (ba)" },
843 { 0x0A, "Byelorussian (be)" },
844 { 0x0B, "Bulgarian (bg)" },
845 { 0x0C, "Bihari (bh)" },
846 { 0x0D, "Bislama (bi)" },
847 { 0x0E, "Bengali; Bangla (bn)" },
848 { 0x0F, "Tibetan (bo)" },
849 { 0x10, "Breton (br)" },
850 { 0x11, "Catalan (ca)" },
851 { 0x12, "Corsican (co)" },
852 { 0x13, "Czech (cs)" },
853 { 0x14, "Welsh (cy)" },
854 { 0x15, "Danish (da)" },
855 { 0x16, "German (de)" },
856 { 0x17, "Bhutani (dz)" },
857 { 0x18, "Greek (el)" },
858 { 0x19, "English (en)" },
859 { 0x1A, "Esperanto (eo)" },
860 { 0x1B, "Spanish (es)" },
861 { 0x1C, "Estonian (et)" },
862 { 0x1D, "Basque (eu)" },
863 { 0x1E, "Persian (fa)" },
864 { 0x1F, "Finnish (fi)" },
865 { 0x20, "Fiji (fj)" },
866 { 0x21, "Urdu (ur)" },
867 { 0x22, "French (fr)" },
868 { 0x23, "Uzbek (uz)" },
869 { 0x24, "Irish (ga)" },
870 { 0x25, "Scots Gaelic (gd)" },
871 { 0x26, "Galician (gl)" },
872 { 0x27, "Guarani (gn)" },
873 { 0x28, "Gujarati (gu)" },
874 { 0x29, "Hausa (ha)" },
875 { 0x2A, "Hebrew (formerly iw) (he)" },
876 { 0x2B, "Hindi (hi)" },
877 { 0x2C, "Croatian (hr)" },
878 { 0x2D, "Hungarian (hu)" },
879 { 0x2E, "Armenian (hy)" },
880 { 0x2F, "Vietnamese (vi)" },
881 { 0x30, "Indonesian (formerly in) (id)" },
882 { 0x31, "Wolof (wo)" },
883 { 0x32, "Xhosa (xh)" },
884 { 0x33, "Icelandic (is)" },
885 { 0x34, "Italian (it)" },
886 { 0x35, "Yoruba (yo)" },
887 { 0x36, "Japanese (ja)" },
888 { 0x37, "Javanese (jw)" },
889 { 0x38, "Georgian (ka)" },
890 { 0x39, "Kazakh (kk)" },
891 { 0x3A, "Zhuang (za)" },
892 { 0x3B, "Cambodian (km)" },
893 { 0x3C, "Kannada (kn)" },
894 { 0x3D, "Korean (ko)" },
895 { 0x3E, "Kashmiri (ks)" },
896 { 0x3F, "Kurdish (ku)" },
897 { 0x40, "Kirghiz (ky)" },
898 { 0x41, "Chinese (zh)" },
899 { 0x42, "Lingala (ln)" },
900 { 0x43, "Laothian (lo)" },
901 { 0x44, "Lithuanian (lt)" },
902 { 0x45, "Latvian, Lettish (lv)" },
903 { 0x46, "Malagasy (mg)" },
904 { 0x47, "Maori (mi)" },
905 { 0x48, "Macedonian (mk)" },
906 { 0x49, "Malayalam (ml)" },
907 { 0x4A, "Mongolian (mn)" },
908 { 0x4B, "Moldavian (mo)" },
909 { 0x4C, "Marathi (mr)" },
910 { 0x4D, "Malay (ms)" },
911 { 0x4E, "Maltese (mt)" },
912 { 0x4F, "Burmese (my)" },
913 { 0x50, "Ukrainian (uk)" },
914 { 0x51, "Nepali (ne)" },
915 { 0x52, "Dutch (nl)" },
916 { 0x53, "Norwegian (no)" },
917 { 0x54, "Occitan (oc)" },
918 { 0x55, "(Afan) Oromo (om)" },
919 { 0x56, "Oriya (or)" },
920 { 0x57, "Punjabi (pa)" },
921 { 0x58, "Polish (po)" },
922 { 0x59, "Pashto, Pushto (ps)" },
923 { 0x5A, "Portuguese (pt)" },
924 { 0x5B, "Quechua (qu)" },
925 { 0x5C, "Zulu (zu)" },
926 { 0x5D, "Kirundi (rn)" },
927 { 0x5E, "Romanian (ro)" },
928 { 0x5F, "Russian (ru)" },
929 { 0x60, "Kinyarwanda (rw)" },
930 { 0x61, "Sanskrit (sa)" },
931 { 0x62, "Sindhi (sd)" },
932 { 0x63, "Sangho (sg)" },
933 { 0x64, "Serbo-Croatian (sh)" },
934 { 0x65, "Sinhalese (si)" },
935 { 0x66, "Slovak (sk)" },
936 { 0x67, "Slovenian (sl)" },
937 { 0x68, "Samoan (sm)" },
938 { 0x69, "Shona (sn)" },
939 { 0x6A, "Somali (so)" },
940 { 0x6B, "Albanian (sq)" },
941 { 0x6C, "Serbian (sr)" },
942 { 0x6D, "Siswati (ss)" },
943 { 0x6E, "Sesotho (st)" },
944 { 0x6F, "Sundanese (su)" },
945 { 0x70, "Swedish (sv)" },
946 { 0x71, "Swahili (sw)" },
947 { 0x72, "Tamil (ta)" },
948 { 0x73, "Telugu (te)" },
949 { 0x74, "Tajik (tg)" },
950 { 0x75, "Thai (th)" },
951 { 0x76, "Tigrinya (ti)" },
952 { 0x77, "Turkmen (tk)" },
953 { 0x78, "Tagalog (tl)" },
954 { 0x79, "Setswana (tn)" },
955 { 0x7A, "Tonga (to)" },
956 { 0x7B, "Turkish (tr)" },
957 { 0x7C, "Tsonga (ts)" },
958 { 0x7D, "Tatar (tt)" },
959 { 0x7E, "Twi (tw)" },
960 { 0x7F, "Uighur (ug)" },
961 { 0x81, "Nauru (na)" },
962 { 0x82, "Faeroese (fo)" },
963 { 0x83, "Frisian (fy)" },
964 { 0x84, "Interlingua (ia)" },
965 { 0x85, "Volapuk (vo)" },
966 { 0x86, "Interlingue (ie)" },
967 { 0x87, "Inupiak (ik)" },
968 { 0x88, "Yiddish (formerly ji) (yi)" },
969 { 0x89, "Inuktitut (iu)" },
970 { 0x8A, "Greenlandic (kl)" },
971 { 0x8B, "Latin (la)" },
972 { 0x8C, "Rhaeto-Romance (rm)" },
977 #define CACHE_CONTROL_NO_CACHE 0x00
978 #define CACHE_CONTROL_NO_STORE 0x01
979 #define CACHE_CONTROL_MAX_AGE 0x02
980 #define CACHE_CONTROL_MAX_STALE 0x03
981 #define CACHE_CONTROL_MIN_FRESH 0x04
982 #define CACHE_CONTROL_ONLY_IF_CACHED 0x05
983 #define CACHE_CONTROL_PUBLIC 0x06
984 #define CACHE_CONTROL_PRIVATE 0x07
985 #define CACHE_CONTROL_NO_TRANSFORM 0x08
986 #define CACHE_CONTROL_MUST_REVALIDATE 0x09
987 #define CACHE_CONTROL_PROXY_REVALIDATE 0x0A
988 #define CACHE_CONTROL_S_MAXAGE 0x0B
990 static const value_string vals_cache_control[] = {
991 { CACHE_CONTROL_NO_CACHE, "no-cache" },
992 { CACHE_CONTROL_NO_STORE, "no-store" },
993 { CACHE_CONTROL_MAX_AGE, "max-age" },
994 { CACHE_CONTROL_MAX_STALE, "max-stale" },
995 { CACHE_CONTROL_MIN_FRESH, "min-fresh" },
996 { CACHE_CONTROL_ONLY_IF_CACHED, "only-if-cached" },
997 { CACHE_CONTROL_PUBLIC, "public" },
998 { CACHE_CONTROL_PRIVATE, "private" },
999 { CACHE_CONTROL_NO_TRANSFORM, "no-transform" },
1000 { CACHE_CONTROL_MUST_REVALIDATE, "must-revalidate" },
1001 { CACHE_CONTROL_PROXY_REVALIDATE, "proxy-revalidate" },
1002 { CACHE_CONTROL_S_MAXAGE, "s-max-age" },
1007 static const value_string vals_wap_application_ids[] = {
1008 /* Well-known WAP applications */
1009 { 0x00, "x-wap-application:*"},
1010 { 0x01, "x-wap-application:push.sia"},
1011 { 0x02, "x-wap-application:wml.ua"},
1012 { 0x03, "x-wap-application:wta.ua"},
1013 { 0x04, "x-wap-application:mms.ua"},
1014 { 0x05, "x-wap-application:push.syncml"},
1015 { 0x06, "x-wap-application:loc.ua"},
1016 { 0x07, "x-wap-application:syncml.dm"},
1017 { 0x08, "x-wap-application:drm.ua"},
1018 { 0x09, "x-wap-application:emn.ua"},
1019 { 0x0A, "x-wap-application:wv.ua"},
1020 /* Registered by 3rd parties */
1021 { 0x8000, "x-wap-microsoft:localcontent.ua"},
1022 { 0x8001, "x-wap-microsoft:IMclient.ua"},
1023 { 0x8002, "x-wap-docomo:imode.mail.ua"},
1024 { 0x8003, "x-wap-docomo:imode.mr.ua"},
1025 { 0x8004, "x-wap-docomo:imode.mf.ua"},
1026 { 0x8005, "x-motorola:location.ua"},
1027 { 0x8006, "x-motorola:now.ua"},
1028 { 0x8007, "x-motorola:otaprov.ua"},
1029 { 0x8008, "x-motorola:browser.ua"},
1030 { 0x8009, "x-motorola:splash.ua"},
1031 /* 0x800A: unassigned */
1032 { 0x800B, "x-wap-nai:mvsw.command"},
1033 /* 0x800C -- 0x800F: unassigned */
1034 { 0x8010, "x-wap-openwave:iota.ua"},
1035 /* 0x8011 -- 0x8FFF: unassigned */
1036 { 0x9000, "x-wap-docomo:imode.mail2.ua"},
1037 { 0x9001, "x-oma-nec:otaprov.ua"},
1038 { 0x9002, "x-oma-nokia:call.ua"},
1039 { 0x9003, "x-oma-coremobility:sqa.ua"},
1045 /* Parameters and well-known encodings */
1046 static const value_string vals_wsp_parameter_sec[] = {
1047 { 0x00, "NETWPIN" },
1048 { 0x01, "USERPIN" },
1049 { 0x02, "USERNETWPIN" },
1050 { 0x03, "USERPINMAC" },
1055 /* Warning codes and mappings */
1056 static const value_string vals_wsp_warning_code[] = {
1057 { 10, "110 Response is stale" },
1058 { 11, "111 Revalidation failed" },
1059 { 12, "112 Disconnected operation" },
1060 { 13, "113 Heuristic expiration" },
1061 { 14, "214 Transformation applied" },
1062 { 99, "199/299 Miscellaneous warning" },
1067 static const value_string vals_wsp_warning_code_short[] = {
1078 /* Profile-Warning codes - see http://www.w3.org/TR/NOTE-CCPPexchange */
1079 static const value_string vals_wsp_profile_warning_code[] = {
1081 { 0x11, "101 Used stale profile" },
1082 { 0x12, "102 Not used profile" },
1083 { 0x20, "200 Not applied" },
1084 { 0x21, "101 Content selection applied" },
1085 { 0x22, "202 Content generation applied" },
1086 { 0x23, "203 Transformation applied" },
1091 /* Well-known TE values */
1092 static const value_string vals_well_known_te[] = {
1093 { 0x82, "chunked" },
1094 { 0x83, "identity" },
1096 { 0x85, "compress" },
1097 { 0x86, "deflate" },
1106 #define PERMANENT_REDIRECT 0x80
1107 #define REUSE_SECURITY_SESSION 0x40
1110 * Redirect address flags and length.
1112 #define BEARER_TYPE_INCLUDED 0x80
1113 #define PORT_NUMBER_INCLUDED 0x40
1114 #define ADDRESS_LEN 0x3f
1116 static const true_false_string yes_no_truth = {
1121 static const value_string vals_false_true[] = {
1128 WSP_PDU_RESERVED = 0x00,
1129 WSP_PDU_CONNECT = 0x01,
1130 WSP_PDU_CONNECTREPLY = 0x02,
1131 WSP_PDU_REDIRECT = 0x03, /* No sample data */
1132 WSP_PDU_REPLY = 0x04,
1133 WSP_PDU_DISCONNECT = 0x05,
1134 WSP_PDU_PUSH = 0x06, /* No sample data */
1135 WSP_PDU_CONFIRMEDPUSH = 0x07, /* No sample data */
1136 WSP_PDU_SUSPEND = 0x08, /* No sample data */
1137 WSP_PDU_RESUME = 0x09, /* No sample data */
1140 WSP_PDU_OPTIONS = 0x41, /* No sample data */
1141 WSP_PDU_HEAD = 0x42, /* No sample data */
1142 WSP_PDU_DELETE = 0x43, /* No sample data */
1143 WSP_PDU_TRACE = 0x44, /* No sample data */
1145 WSP_PDU_POST = 0x60,
1146 WSP_PDU_PUT = 0x61, /* No sample data */
1149 #define VAL_STRING_SIZE 200
1153 VALUE_IS_TEXT_STRING,
1157 static dissector_table_t wsp_dissector_table;
1158 static dissector_table_t wsp_dissector_table_text;
1159 static heur_dissector_list_t heur_subdissector_list;
1161 static void add_uri (proto_tree *, packet_info *, tvbuff_t *, guint, guint);
1163 static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
1164 static void add_multipart_data (proto_tree *, tvbuff_t *);
1166 static void add_capabilities (proto_tree *tree, tvbuff_t *tvb, int type);
1167 static void add_capability_vals(tvbuff_t *, gboolean, int, guint, guint, char *, size_t);
1168 static guint get_uintvar (tvbuff_t *, guint, guint);
1173 * Dissect the WSP header part.
1174 * This function calls wkh_XXX functions that dissect well-known headers.
1176 static void add_headers (proto_tree *tree, tvbuff_t *tvb);
1178 /* The following macros define WSP basic data structures as found
1179 * in the ABNF notation of WSP headers.
1180 * Currently all text data types are mapped to text_string.
1182 #define is_short_integer(x) ( (x) & 0x80 )
1183 #define is_long_integer(x) ( (x) <= 30 )
1184 #define is_date_value(x) is_long_integer(x)
1185 #define is_integer_value(x) (is_short_integer(x) || is_long_integer(x))
1186 #define is_delta_seconds_value(x) is_integer_value(x)
1187 /* Text string == *TEXT 0x00, thus also an empty string matches the rule! */
1188 #define is_text_string(x) ( ((x) == 0) || ( ((x) >= 32) && ((x) <= 127)) )
1189 #define is_quoted_string(x) ( (x) == 0x22 ) /* " */
1190 #define is_token_text(x) is_text_string(x)
1191 #define is_text_value(x) is_text_string(x)
1192 #define is_uri_value(x) is_text_string(x)
1194 #define get_uintvar_integer(val,tvb,start,len,ok) \
1195 val = tvb_get_guintvar(tvb,start,&len); \
1196 if (len>5) ok = FALSE; else ok = TRUE;
1197 #define get_short_integer(val,tvb,start,len,ok) \
1198 val = tvb_get_guint8(tvb,start); \
1199 if (val & 0x80) ok = TRUE; else ok=FALSE; \
1200 val &= 0x7F; len = 1;
1201 #define get_long_integer(val,tvb,start,len,ok) \
1202 len = tvb_get_guint8(tvb,start); \
1203 ok = TRUE; /* Valid lengths for us are 1-4 */ \
1204 if (len==1) { val = tvb_get_guint8(tvb,start+1); } \
1205 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \
1206 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \
1207 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \
1209 len++; /* Add the 1st octet to the length */
1210 #define get_integer_value(val,tvb,start,len,ok) \
1211 len = tvb_get_guint8(tvb,start); \
1213 if (len & 0x80) { val = len & 0x7F; len = 0; } \
1214 else if (len==1) { val = tvb_get_guint8(tvb,start+1); } \
1215 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \
1216 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \
1217 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \
1219 len++; /* Add the 1st octet to the length */
1220 #define get_date_value(val,tvb,start,len,ok) \
1221 get_long_integer(val,tvb,start,len,ok)
1222 #define get_delta_seconds_value(val,tvb,start,len,ok) \
1223 get_integer_value(val,tvb,start,len,ok)
1225 /* NOTE - Don't forget to g_free() the str value after its usage as the
1226 * tvb_get_string[z]() functions return g_malloc()ed memory! */
1227 #define get_text_string(str,tvb,start,len,ok) \
1228 if (is_text_string(tvb_get_guint8(tvb,start))) { \
1229 str = tvb_get_stringz(tvb,start,&len); \
1232 } else { len = 0; str = NULL; ok = FALSE; }
1233 #define get_token_text(str,tvb,start,len,ok) \
1234 get_text_string(str,tvb,start,len,ok)
1235 #define get_extension_media(str,tvb,start,len,ok) \
1236 get_text_string(str,tvb,start,len,ok)
1237 #define get_text_value(str,tvb,start,len,ok) \
1238 get_text_string(str,tvb,start,len,ok)
1239 #define get_quoted_string(str,tvb,start,len,ok) \
1240 get_text_string(str,tvb,start,len,ok)
1241 #define get_uri_value(str,tvb,start,len,ok) \
1242 get_text_string(str,tvb,start,len,ok)
1244 #define get_version_value(val,str,tvb,start,len,ok) \
1245 val = tvb_get_guint8(tvb,start); \
1247 if (val & 0x80) { /* High nibble "." Low nibble */ \
1250 str = g_strdup_printf("%u.%u", val >> 4, val & 0x0F); \
1251 } else { get_text_string(str,tvb,start,len,ok); }
1253 /* Parameter parser */
1255 parameter (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start, int len);
1257 parameter_value_q (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start);
1259 #define InvalidValueForHeader(hdr) \
1260 "<Error: Invalid value for the '" hdr "' header>"
1261 #define InvalidTextualHeader \
1262 "<Error: Invalid zero-length textual header>"
1263 #define TrailingQuoteWarning \
1264 " <Warning: Quoted-string value has been encoded with a trailing quote>"
1266 /* WSP well-known header parsing function prototypes;
1267 * will be listed in the function lookup table WellKnownHeaders[] */
1268 static guint32 wkh_default (proto_tree *tree, tvbuff_t *tvb,
1270 static guint32 wkh_accept (proto_tree *tree, tvbuff_t *tvb,
1272 static guint32 wkh_content_type (proto_tree *tree, tvbuff_t *tvb,
1274 static guint32 wkh_accept_charset (proto_tree *tree, tvbuff_t *tvb,
1276 static guint32 wkh_accept_language (proto_tree *tree, tvbuff_t *tvb,
1278 static guint32 wkh_connection (proto_tree *tree, tvbuff_t *tvb,
1280 static guint32 wkh_push_flag (proto_tree *tree, tvbuff_t *tvb,
1281 guint32 header_start);
1282 static guint32 wkh_vary (proto_tree *tree, tvbuff_t *tvb,
1284 static guint32 wkh_accept_ranges (proto_tree *tree, tvbuff_t *tvb,
1286 static guint32 wkh_content_disposition (proto_tree *tree, tvbuff_t *tvb,
1288 static guint32 wkh_accept_encoding (proto_tree *tree, tvbuff_t *tvb,
1290 static guint32 wkh_content_encoding (proto_tree *tree, tvbuff_t *tvb,
1292 static guint32 wkh_transfer_encoding (proto_tree *tree, tvbuff_t *tvb,
1294 static guint32 wkh_pragma (proto_tree *tree, tvbuff_t *tvb,
1296 /* Single short-integer value */
1297 static guint32 wkh_x_wap_security (proto_tree *tree, tvbuff_t *tvb,
1300 static guint32 wkh_content_base (proto_tree *tree, tvbuff_t *tvb,
1302 static guint32 wkh_content_location (proto_tree *tree, tvbuff_t *tvb,
1304 static guint32 wkh_etag (proto_tree *tree, tvbuff_t *tvb,
1306 static guint32 wkh_from (proto_tree *tree, tvbuff_t *tvb,
1308 static guint32 wkh_host (proto_tree *tree, tvbuff_t *tvb,
1310 static guint32 wkh_if_match (proto_tree *tree, tvbuff_t *tvb,
1312 static guint32 wkh_if_none_match (proto_tree *tree, tvbuff_t *tvb,
1314 static guint32 wkh_location (proto_tree *tree, tvbuff_t *tvb,
1316 static guint32 wkh_referer (proto_tree *tree, tvbuff_t *tvb,
1318 static guint32 wkh_server (proto_tree *tree, tvbuff_t *tvb,
1320 static guint32 wkh_user_agent (proto_tree *tree, tvbuff_t *tvb,
1322 static guint32 wkh_upgrade (proto_tree *tree, tvbuff_t *tvb,
1324 static guint32 wkh_via (proto_tree *tree, tvbuff_t *tvb,
1326 static guint32 wkh_content_uri (proto_tree *tree, tvbuff_t *tvb,
1328 static guint32 wkh_initiator_uri (proto_tree *tree, tvbuff_t *tvb,
1330 static guint32 wkh_profile (proto_tree *tree, tvbuff_t *tvb,
1332 static guint32 wkh_content_id (proto_tree *tree, tvbuff_t *tvb,
1334 /* Date-value or text */
1335 static guint32 wkh_if_range (proto_tree *tree, tvbuff_t *tvb,
1338 static guint32 wkh_date (proto_tree *tree, tvbuff_t *tvb,
1340 static guint32 wkh_expires (proto_tree *tree, tvbuff_t *tvb,
1342 static guint32 wkh_if_modified_since (proto_tree *tree, tvbuff_t *tvb,
1344 static guint32 wkh_if_unmodified_since (proto_tree *tree, tvbuff_t *tvb,
1346 static guint32 wkh_last_modified (proto_tree *tree, tvbuff_t *tvb,
1348 /* Date-value with special meaning */
1349 static guint32 wkh_x_wap_tod (proto_tree *tree, tvbuff_t *tvb,
1351 /* Delta-seconds-value */
1352 static guint32 wkh_age (proto_tree *tree, tvbuff_t *tvb,
1355 static guint32 wkh_proxy_authenticate (proto_tree *tree, tvbuff_t *tvb,
1357 static guint32 wkh_www_authenticate (proto_tree *tree, tvbuff_t *tvb,
1360 static guint32 wkh_authorization (proto_tree *tree, tvbuff_t *tvb,
1362 static guint32 wkh_proxy_authorization (proto_tree *tree, tvbuff_t *tvb,
1365 static guint32 wkh_pragma (proto_tree *tree, tvbuff_t *tvb,
1368 static guint32 wkh_content_length (proto_tree *tree, tvbuff_t *tvb,
1370 static guint32 wkh_max_forwards (proto_tree *tree, tvbuff_t *tvb,
1373 /* Integer lookup value */
1374 static guint32 wkh_bearer_indication (proto_tree *tree, tvbuff_t *tvb,
1377 /* WAP application ID value */
1378 static guint32 wkh_x_wap_application_id (proto_tree *tree, tvbuff_t *tvb,
1380 static guint32 wkh_accept_application (proto_tree *tree, tvbuff_t *tvb,
1382 static guint32 wkh_content_language (proto_tree *tree, tvbuff_t *tvb,
1385 /* Allow and Public */
1386 static guint32 wkh_allow(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start);
1387 static guint32 wkh_public(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start);
1390 static guint32 wkh_cache_control (proto_tree *tree, tvbuff_t *tvb,
1393 static guint32 wkh_warning (proto_tree *tree, tvbuff_t *tvb,
1395 /* Profile-warning */
1396 static guint32 wkh_profile_warning (proto_tree *tree, tvbuff_t *tvb,
1400 static guint32 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb,
1403 /* WSP encoding version */
1404 static guint32 wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb,
1407 /* Content-Range and Range */
1408 static guint32 wkh_content_range (proto_tree *tree, tvbuff_t *tvb,
1410 static guint32 wkh_range (proto_tree *tree, tvbuff_t *tvb,
1414 static guint32 wkh_te (proto_tree *tree, tvbuff_t *tvb,
1418 static guint32 wkh_trailer (proto_tree *tree, tvbuff_t *tvb,
1421 /* TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
1422 static guint32 wkh_retry_after (proto_tree *tree, tvbuff_t *tvb,
1424 static guint32 wkh_profile_diff (proto_tree *tree, tvbuff_t *tvb,
1426 static guint32 wkh_expect (proto_tree *tree, tvbuff_t *tvb,
1428 static guint32 wkh_set_cookie (proto_tree *tree, tvbuff_t *tvb,
1430 static guint32 wkh_cookie (proto_tree *tree, tvbuff_t *tvb,
1435 /* WSP well-known Openwave header parsing function prototypes;
1436 * will be listed in the function lookup table WellKnownOpenwaveHeaders[] */
1437 static guint32 wkh_openwave_default (proto_tree *tree, tvbuff_t *tvb,
1439 /* Textual headers */
1440 static guint32 wkh_openwave_x_up_proxy_operator_domain(proto_tree *tree,
1441 tvbuff_t *tvb, guint32 hdr_start);
1442 static guint32 wkh_openwave_x_up_proxy_home_page(proto_tree *tree,
1443 tvbuff_t *tvb, guint32 hdr_start);
1444 static guint32 wkh_openwave_x_up_proxy_uplink_version(proto_tree *tree,
1445 tvbuff_t *tvb, guint32 hdr_start);
1446 static guint32 wkh_openwave_x_up_proxy_ba_realm(proto_tree *tree,
1447 tvbuff_t *tvb, guint32 hdr_start);
1448 static guint32 wkh_openwave_x_up_proxy_request_uri(proto_tree *tree,
1449 tvbuff_t *tvb, guint32 hdr_start);
1450 static guint32 wkh_openwave_x_up_proxy_bookmark(proto_tree *tree,
1451 tvbuff_t *tvb, guint32 hdr_start);
1452 /* Integer headers */
1453 static guint32 wkh_openwave_x_up_proxy_push_seq(proto_tree *tree,
1454 tvbuff_t *tvb, guint32 hdr_start);
1455 static guint32 wkh_openwave_x_up_proxy_notify(proto_tree *tree,
1456 tvbuff_t *tvb, guint32 hdr_start);
1457 static guint32 wkh_openwave_x_up_proxy_net_ask(proto_tree *tree,
1458 tvbuff_t *tvb, guint32 hdr_start);
1459 static guint32 wkh_openwave_x_up_proxy_tod (proto_tree *tree,
1460 tvbuff_t *tvb, guint32 hdr_start);
1461 static guint32 wkh_openwave_x_up_proxy_ba_enable(proto_tree *tree,
1462 tvbuff_t *tvb, guint32 hdr_start);
1463 static guint32 wkh_openwave_x_up_proxy_redirect_enable(proto_tree *tree,
1464 tvbuff_t *tvb, guint32 hdr_start);
1465 static guint32 wkh_openwave_x_up_proxy_redirect_status(proto_tree *tree,
1466 tvbuff_t *tvb, guint32 hdr_start);
1467 static guint32 wkh_openwave_x_up_proxy_linger(proto_tree *tree,
1468 tvbuff_t *tvb, guint32 hdr_start);
1469 static guint32 wkh_openwave_x_up_proxy_enable_trust(proto_tree *tree,
1470 tvbuff_t *tvb, guint32 hdr_start);
1471 static guint32 wkh_openwave_x_up_proxy_trust(proto_tree *tree,
1472 tvbuff_t *tvb, guint32 hdr_start);
1473 static guint32 wkh_openwave_x_up_devcap_has_color(proto_tree *tree,
1474 tvbuff_t *tvb, guint32 hdr_start);
1475 static guint32 wkh_openwave_x_up_devcap_num_softkeys(proto_tree *tree,
1476 tvbuff_t *tvb, guint32 hdr_start);
1477 static guint32 wkh_openwave_x_up_devcap_softkey_size(proto_tree *tree,
1478 tvbuff_t *tvb, guint32 hdr_start);
1479 static guint32 wkh_openwave_x_up_devcap_screen_chars(proto_tree *tree,
1480 tvbuff_t *tvb, guint32 hdr_start);
1481 static guint32 wkh_openwave_x_up_devcap_screen_pixels(proto_tree *tree,
1482 tvbuff_t *tvb, guint32 hdr_start);
1483 static guint32 wkh_openwave_x_up_devcap_em_size(proto_tree *tree,
1484 tvbuff_t *tvb, guint32 hdr_start);
1485 static guint32 wkh_openwave_x_up_devcap_screen_depth(proto_tree *tree,
1486 tvbuff_t *tvb, guint32 hdr_start);
1487 static guint32 wkh_openwave_x_up_devcap_immed_alert(proto_tree *tree,
1488 tvbuff_t *tvb, guint32 hdr_start);
1489 static guint32 wkh_openwave_x_up_devcap_gui(proto_tree *tree,
1490 tvbuff_t *tvb, guint32 hdr_start);
1492 static guint32 wkh_openwave_x_up_proxy_trans_charset(proto_tree *tree,
1493 tvbuff_t *tvb, guint32 hdr_start);
1494 static guint32 wkh_openwave_x_up_proxy_push_accept(proto_tree *tree,
1495 tvbuff_t *tvb, guint32 hdr_start);
1498 /* Define a pointer to function data type for the well-known header
1499 * lookup table below */
1500 typedef guint32 (*hdr_parse_func_ptr) (proto_tree *, tvbuff_t *, guint32);
1502 /* Lookup table for well-known header parsing functions */
1503 static const hdr_parse_func_ptr WellKnownHeader[128] = {
1504 /* 0x00 */ wkh_accept, /* 0x01 */ wkh_accept_charset,
1505 /* 0x02 */ wkh_accept_encoding, /* 0x03 */ wkh_accept_language,
1506 /* 0x04 */ wkh_accept_ranges, /* 0x05 */ wkh_age,
1507 /* 0x06 */ wkh_allow, /* 0x07 */ wkh_authorization,
1508 /* 0x08 */ wkh_cache_control, /* 0x09 */ wkh_connection,
1509 /* 0x0A */ wkh_content_base, /* 0x0B */ wkh_content_encoding,
1510 /* 0x0C */ wkh_content_language, /* 0x0D */ wkh_content_length,
1511 /* 0x0E */ wkh_content_location, /* 0x0F */ wkh_content_md5,
1512 /* 0x10 */ wkh_content_range, /* 0x11 */ wkh_content_type,
1513 /* 0x12 */ wkh_date, /* 0x13 */ wkh_etag,
1514 /* 0x14 */ wkh_expires, /* 0x15 */ wkh_from,
1515 /* 0x16 */ wkh_host, /* 0x17 */ wkh_if_modified_since,
1516 /* 0x18 */ wkh_if_match, /* 0x19 */ wkh_if_none_match,
1517 /* 0x1A */ wkh_if_range, /* 0x1B */ wkh_if_unmodified_since,
1518 /* 0x1C */ wkh_location, /* 0x1D */ wkh_last_modified,
1519 /* 0x1E */ wkh_max_forwards, /* 0x1F */ wkh_pragma,
1520 /* 0x20 */ wkh_proxy_authenticate, /* 0x21 */ wkh_proxy_authorization,
1521 /* 0x22 */ wkh_public, /* 0x23 */ wkh_range,
1522 /* 0x24 */ wkh_referer, /* 0x25 */ wkh_default,
1523 /* 0x26 */ wkh_server, /* 0x27 */ wkh_transfer_encoding,
1524 /* 0x28 */ wkh_upgrade, /* 0x29 */ wkh_user_agent,
1525 /* 0x2A */ wkh_vary, /* 0x2B */ wkh_via,
1526 /* 0x2C */ wkh_warning, /* 0x2D */ wkh_www_authenticate,
1527 /* 0x2E */ wkh_content_disposition,/* 0x2F */ wkh_x_wap_application_id,
1528 /* 0x30 */ wkh_content_uri, /* 0x31 */ wkh_initiator_uri,
1529 /* 0x32 */ wkh_accept_application, /* 0x33 */ wkh_bearer_indication,
1530 /* 0x34 */ wkh_push_flag, /* 0x35 */ wkh_profile,
1531 /* 0x36 */ wkh_default, /* 0x37 */ wkh_profile_warning,
1532 /* 0x38 */ wkh_default, /* 0x39 */ wkh_te,
1533 /* 0x3A */ wkh_trailer, /* 0x3B */ wkh_accept_charset,
1534 /* 0x3C */ wkh_accept_encoding, /* 0x3D */ wkh_cache_control,
1535 /* 0x3E */ wkh_content_range, /* 0x3F */ wkh_x_wap_tod,
1536 /* 0x40 */ wkh_content_id, /* 0x41 */ wkh_default,
1537 /* 0x42 */ wkh_default, /* 0x43 */ wkh_encoding_version,
1538 /* 0x44 */ wkh_profile_warning, /* 0x45 */ wkh_content_disposition,
1539 /* 0x46 */ wkh_x_wap_security, /* 0x47 */ wkh_cache_control,
1540 /*******************************************************
1541 *** The following headers are not (yet) registered. ***
1542 *******************************************************/
1543 /* 0x48 */ wkh_default, /* 0x49 */ wkh_default,
1544 /* 0x4A */ wkh_default, /* 0x4B */ wkh_default,
1545 /* 0x4C */ wkh_default, /* 0x4D */ wkh_default,
1546 /* 0x4E */ wkh_default, /* 0x4F */ wkh_default,
1547 /* 0x50 */ wkh_default, /* 0x51 */ wkh_default,
1548 /* 0x52 */ wkh_default, /* 0x53 */ wkh_default,
1549 /* 0x54 */ wkh_default, /* 0x55 */ wkh_default,
1550 /* 0x56 */ wkh_default, /* 0x57 */ wkh_default,
1551 /* 0x58 */ wkh_default, /* 0x59 */ wkh_default,
1552 /* 0x5A */ wkh_default, /* 0x5B */ wkh_default,
1553 /* 0x5C */ wkh_default, /* 0x5D */ wkh_default,
1554 /* 0x5E */ wkh_default, /* 0x5F */ wkh_default,
1555 /* 0x60 */ wkh_default, /* 0x61 */ wkh_default,
1556 /* 0x62 */ wkh_default, /* 0x63 */ wkh_default,
1557 /* 0x64 */ wkh_default, /* 0x65 */ wkh_default,
1558 /* 0x66 */ wkh_default, /* 0x67 */ wkh_default,
1559 /* 0x68 */ wkh_default, /* 0x69 */ wkh_default,
1560 /* 0x6A */ wkh_default, /* 0x6B */ wkh_default,
1561 /* 0x6C */ wkh_default, /* 0x6D */ wkh_default,
1562 /* 0x6E */ wkh_default, /* 0x6F */ wkh_default,
1563 /* 0x70 */ wkh_default, /* 0x71 */ wkh_default,
1564 /* 0x72 */ wkh_default, /* 0x73 */ wkh_default,
1565 /* 0x74 */ wkh_default, /* 0x75 */ wkh_default,
1566 /* 0x76 */ wkh_default, /* 0x77 */ wkh_default,
1567 /* 0x78 */ wkh_default, /* 0x79 */ wkh_default,
1568 /* 0x7A */ wkh_default, /* 0x7B */ wkh_default,
1569 /* 0x7C */ wkh_default, /* 0x7D */ wkh_default,
1570 /* 0x7E */ wkh_default, /* 0x7F */ wkh_default,
1573 /* Lookup table for well-known header parsing functions */
1574 static const hdr_parse_func_ptr WellKnownOpenwaveHeader[128] = {
1575 /* 0x00 */ wkh_openwave_default,
1576 /* 0x01 */ wkh_openwave_x_up_proxy_push_accept,
1577 /* 0x02 */ wkh_openwave_x_up_proxy_push_seq,
1578 /* 0x03 */ wkh_openwave_x_up_proxy_notify,
1579 /* 0x04 */ wkh_openwave_x_up_proxy_operator_domain,
1580 /* 0x05 */ wkh_openwave_x_up_proxy_home_page,
1581 /* 0x06 */ wkh_openwave_x_up_devcap_has_color,
1582 /* 0x07 */ wkh_openwave_x_up_devcap_num_softkeys,
1583 /* 0x08 */ wkh_openwave_x_up_devcap_softkey_size,
1584 /* 0x09 */ wkh_openwave_x_up_devcap_screen_chars,
1585 /* 0x0A */ wkh_openwave_x_up_devcap_screen_pixels,
1586 /* 0x0B */ wkh_openwave_x_up_devcap_em_size,
1587 /* 0x0C */ wkh_openwave_x_up_devcap_screen_depth,
1588 /* 0x0D */ wkh_openwave_x_up_devcap_immed_alert,
1589 /* 0x0E */ wkh_openwave_x_up_proxy_net_ask,
1590 /* 0x0F */ wkh_openwave_x_up_proxy_uplink_version,
1591 /* 0x10 */ wkh_openwave_x_up_proxy_tod,
1592 /* 0x11 */ wkh_openwave_x_up_proxy_ba_enable,
1593 /* 0x12 */ wkh_openwave_x_up_proxy_ba_realm,
1594 /* 0x13 */ wkh_openwave_x_up_proxy_redirect_enable,
1595 /* 0x14 */ wkh_openwave_x_up_proxy_request_uri,
1596 /* 0x15 */ wkh_openwave_x_up_proxy_redirect_status,
1597 /* 0x16 */ wkh_openwave_x_up_proxy_trans_charset,
1598 /* 0x17 */ wkh_openwave_x_up_proxy_linger,
1599 /* 0x18 */ wkh_openwave_default,
1600 /* 0x19 */ wkh_openwave_x_up_proxy_enable_trust,
1601 /* 0x1A */ wkh_openwave_x_up_proxy_trust,
1602 /* 0x1B */ wkh_openwave_default,
1603 /* 0x1C */ wkh_openwave_default,
1604 /* 0x1D */ wkh_openwave_default,
1605 /* 0x1E */ wkh_openwave_default,
1606 /* 0x1F */ wkh_openwave_default,
1607 /* 0x20 */ wkh_openwave_x_up_proxy_trust,
1608 /* 0x21 */ wkh_openwave_x_up_proxy_bookmark,
1609 /* 0x22 */ wkh_openwave_x_up_devcap_gui,
1610 /*******************************************************
1611 *** The following headers are not (yet) registered. ***
1612 *******************************************************/
1613 /* 0x23 */ wkh_openwave_default,
1614 /* 0x24 */ wkh_openwave_default, /* 0x25 */ wkh_openwave_default,
1615 /* 0x26 */ wkh_openwave_default, /* 0x27 */ wkh_openwave_default,
1616 /* 0x28 */ wkh_openwave_default, /* 0x29 */ wkh_openwave_default,
1617 /* 0x2A */ wkh_openwave_default, /* 0x2B */ wkh_openwave_default,
1618 /* 0x2C */ wkh_openwave_default, /* 0x2D */ wkh_openwave_default,
1619 /* 0x2E */ wkh_openwave_default, /* 0x2F */ wkh_openwave_default,
1620 /* 0x30 */ wkh_openwave_default, /* 0x31 */ wkh_openwave_default,
1621 /* 0x32 */ wkh_openwave_default, /* 0x33 */ wkh_openwave_default,
1622 /* 0x34 */ wkh_openwave_default, /* 0x35 */ wkh_openwave_default,
1623 /* 0x36 */ wkh_openwave_default, /* 0x37 */ wkh_openwave_default,
1624 /* 0x38 */ wkh_openwave_default, /* 0x39 */ wkh_openwave_default,
1625 /* 0x3A */ wkh_openwave_default, /* 0x3B */ wkh_openwave_default,
1626 /* 0x3C */ wkh_openwave_default, /* 0x3D */ wkh_openwave_default,
1627 /* 0x3E */ wkh_openwave_default, /* 0x3F */ wkh_openwave_default,
1628 /* 0x40 */ wkh_openwave_default, /* 0x41 */ wkh_openwave_default,
1629 /* 0x42 */ wkh_openwave_default, /* 0x43 */ wkh_openwave_default,
1630 /* 0x44 */ wkh_openwave_default, /* 0x45 */ wkh_openwave_default,
1631 /* 0x46 */ wkh_openwave_default, /* 0x47 */ wkh_openwave_default,
1632 /* 0x48 */ wkh_openwave_default, /* 0x49 */ wkh_openwave_default,
1633 /* 0x4A */ wkh_openwave_default, /* 0x4B */ wkh_openwave_default,
1634 /* 0x4C */ wkh_openwave_default, /* 0x4D */ wkh_openwave_default,
1635 /* 0x4E */ wkh_openwave_default, /* 0x4F */ wkh_openwave_default,
1636 /* 0x50 */ wkh_openwave_default, /* 0x51 */ wkh_openwave_default,
1637 /* 0x52 */ wkh_openwave_default, /* 0x53 */ wkh_openwave_default,
1638 /* 0x54 */ wkh_openwave_default, /* 0x55 */ wkh_openwave_default,
1639 /* 0x56 */ wkh_openwave_default, /* 0x57 */ wkh_openwave_default,
1640 /* 0x58 */ wkh_openwave_default, /* 0x59 */ wkh_openwave_default,
1641 /* 0x5A */ wkh_openwave_default, /* 0x5B */ wkh_openwave_default,
1642 /* 0x5C */ wkh_openwave_default, /* 0x5D */ wkh_openwave_default,
1643 /* 0x5E */ wkh_openwave_default, /* 0x5F */ wkh_openwave_default,
1644 /* 0x60 */ wkh_openwave_default, /* 0x61 */ wkh_openwave_default,
1645 /* 0x62 */ wkh_openwave_default, /* 0x63 */ wkh_openwave_default,
1646 /* 0x64 */ wkh_openwave_default, /* 0x65 */ wkh_openwave_default,
1647 /* 0x66 */ wkh_openwave_default, /* 0x67 */ wkh_openwave_default,
1648 /* 0x68 */ wkh_openwave_default, /* 0x69 */ wkh_openwave_default,
1649 /* 0x6A */ wkh_openwave_default, /* 0x6B */ wkh_openwave_default,
1650 /* 0x6C */ wkh_openwave_default, /* 0x6D */ wkh_openwave_default,
1651 /* 0x6E */ wkh_openwave_default, /* 0x6F */ wkh_openwave_default,
1652 /* 0x70 */ wkh_openwave_default, /* 0x71 */ wkh_openwave_default,
1653 /* 0x72 */ wkh_openwave_default, /* 0x73 */ wkh_openwave_default,
1654 /* 0x74 */ wkh_openwave_default, /* 0x75 */ wkh_openwave_default,
1655 /* 0x76 */ wkh_openwave_default, /* 0x77 */ wkh_openwave_default,
1656 /* 0x78 */ wkh_openwave_default, /* 0x79 */ wkh_openwave_default,
1657 /* 0x7A */ wkh_openwave_default, /* 0x7B */ wkh_openwave_default,
1658 /* 0x7C */ wkh_openwave_default, /* 0x7D */ wkh_openwave_default,
1659 /* 0x7E */ wkh_openwave_default, /* 0x7F */ wkh_openwave_default,
1667 /* WSP header format
1668 * 1st byte: 0x00 : <Not allowed>
1669 * 1st byte: 0x01 -- 0x1F: <Shorthand Header Code Page switch>
1670 * 1st byte: 0x20 -- 0x7E: <Textual header (C string)>
1671 * Followed with: <Textual header value (C string)>
1672 * 1st byte: 0x7F : <Header Code Page switch>
1673 * Followed with: 2nd byte: <Header Code Page>
1674 * 1st byte: 0x80 -- 0xFF: <Binary header (7-bit encoded ID)>
1676 * 2nd byte: 0x00 -- 0x1E: <Value Length (bytes)>
1677 * Followed with: <Len> bytes of data
1678 * 2nd byte: 0x1F : <Value Length is a guintvar>
1679 * Followed with: <guintvar Len>
1680 * Followed with: <Len> bytes of data
1681 * 2nd byte: 0x20 -- 0x7F: <Textual header value (C string)>
1682 * 2nd byte: 0x80 -- 0xFF: <Binary value (7-bit encoded ID)>
1685 add_headers (proto_tree *tree, tvbuff_t *tvb)
1687 guint8 hdr_id, val_id, codepage = 1;
1688 gint32 tvb_len = tvb_length(tvb);
1689 gint32 offset = 0, hdr_len, hdr_start;
1690 gint32 val_len, val_start;
1691 guint8 *hdr_str, *val_str;
1692 proto_tree *wsp_headers;
1698 if (offset >= tvb_len)
1699 return; /* No headers! */
1701 ti = proto_tree_add_item(tree, hf_wsp_headers_section,
1702 tvb, offset, tvb_len, bo_little_endian);
1703 wsp_headers = proto_item_add_subtree(ti, ett_headers);
1705 while (offset < tvb_len) {
1707 hdr_id = tvb_get_guint8(tvb, offset);
1708 if (hdr_id & 0x80) { /* Well-known header */
1710 val_start = ++offset;
1711 val_id = tvb_get_guint8(tvb, val_start);
1712 /* Call header value dissector for given header */
1713 if (codepage == 1) { /* Default header code page */
1715 printf("DBG: %s\n", match_strval (hdr_id & 0x7f, vals_field_names));
1717 offset = WellKnownHeader[hdr_id & 0x7F](wsp_headers, tvb,
1719 } else { /* Openwave header code page */
1720 /* Here I'm delibarately assuming that Openwave is the only
1721 * company that defines a WSP header code page. */
1723 printf("DBG: %s\n", match_strval (hdr_id & 0x7f, vals_openwave_field_names));
1725 offset = WellKnownOpenwaveHeader[hdr_id & 0x7F](wsp_headers,
1728 } else if (hdr_id == 0x7F) { /* HCP shift sequence */
1729 codepage = tvb_get_guint8(tvb, offset+1);
1730 proto_tree_add_uint(wsp_headers, hf_wsp_header_shift_code,
1731 tvb, offset, 2, codepage);
1733 } else if (hdr_id >= 0x20) { /* Textual header */
1734 /* Header name MUST be NUL-ended string ==> tvb_get_stringz() */
1735 hdr_str = tvb_get_stringz(tvb, hdr_start, &hdr_len);
1736 val_start = hdr_start + hdr_len;
1737 val_id = tvb_get_guint8(tvb, val_start);
1738 /* Call header value dissector for given header */
1739 if (val_id >= 0x20 && val_id <=0x7E) { /* OK! */
1740 val_str = tvb_get_stringz(tvb, val_start, &val_len);
1742 offset = val_start + val_len;
1743 proto_tree_add_text(wsp_headers,tvb,hdr_start,offset-hdr_start,
1744 "%s: %s", hdr_str, val_str);
1747 /* Old-style X-WAP-TOD uses a non-textual value
1748 * after a textual header. */
1749 if (strcasecmp(hdr_str, "x-wap.tod") == 0) {
1750 get_delta_seconds_value(val, tvb, val_start, val_len, ok);
1753 ti = proto_tree_add_string (wsp_headers,
1755 tvb, hdr_start, hdr_len + val_len,
1756 "Requesting Time Of Day");
1760 val_str = abs_time_to_str(&tv);
1762 ti = proto_tree_add_string (wsp_headers,
1764 tvb, hdr_start, hdr_len + val_len, val_str);
1766 proto_item_append_text(ti, " <Warning: "
1767 "should be encoded as a textual value>");
1769 /* I prefer using X-Wap-Tod to the real hdr_str */
1770 proto_tree_add_string (wsp_headers, hf_hdr_x_wap_tod,
1771 tvb, hdr_start, hdr_len + val_len,
1772 InvalidValueForHeader("X-Wap-Tod"));
1775 proto_tree_add_text (wsp_headers, tvb, hdr_start, hdr_len,
1776 "<Error: Invalid value for the textual '%s' header"
1777 " (should be a textual value)>",
1782 proto_tree_add_string_hidden(wsp_headers, hf_hdr_name,
1783 tvb, hdr_start, offset - hdr_start, hdr_str);
1784 } else if (hdr_id > 0) { /* Shorthand HCP switch */
1786 proto_tree_add_uint (wsp_headers, hf_wsp_header_shift_code,
1787 tvb, offset, 1, codepage);
1790 proto_tree_add_text (wsp_headers, tvb, hdr_start, 1,
1791 InvalidTextualHeader);
1798 /* The following macros hide common processing for all well-known headers
1799 * and shortens the code to be written in a wkh_XXX() function.
1800 * Even declarations are hidden by a macro.
1802 * Define a wkh_XXX() function as follows:
1805 * wkh_XXX (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
1807 * wkh_0_Declarations;
1808 * << add other required declarations here >>
1810 * wkh_1_WellKnownValue;
1811 * << add well-known value proto item here; don't forget to set the
1812 * ok variable to TRUE if parsing was correct >>
1813 * wkh_2_TextualValue;
1814 * << add textual value proto item here; don't forget to set the
1815 * ok variable to TRUE if parsing was correct >>
1816 * wkh_3_ValueWithLength;
1817 * << add custom code for value processing and value proto item here >>
1820 * << This macro takes care of parse errors within the header value;
1821 * it requires the header field index if the header has not yet been
1822 * written to the protocol tree (ti == NULL). >>
1825 * NOTE: You only need to write parsing code for the successful case,
1826 * Errors are automatically reported through the wkh_4_End() macro
1830 /* The following code is the generic template with which the value of a
1831 * well-known header can be processed. Not all sections yield a semantically
1832 * correct result, so appropriate error information must be provided.
1836 #define wkh_0_Declarations /* Declarations for Parsing */ \
1837 gboolean ok = FALSE; /* Triggers error notification code at end */ \
1838 proto_item *ti = NULL; /* Needed for error notification at end */ \
1839 guint32 val_start = hdr_start + 1; \
1840 guint8 hdr_id = tvb_get_guint8 (tvb, hdr_start) & 0x7F; \
1841 guint8 val_id = tvb_get_guint8 (tvb, val_start); \
1842 guint32 offset = val_start; /* Offset to one past this header */ \
1843 guint32 val_len; /* length for value with length field */ \
1844 guint32 val_len_len; /* length of length field */ \
1845 guint8 *val_str = NULL
1847 #define wkh_1_WellKnownValue /* Parse Well Known Value */ \
1848 proto_tree_add_string_hidden(tree, hf_hdr_name, \
1849 tvb, hdr_start, offset - hdr_start, \
1850 val_to_str (hdr_id, vals_field_names, \
1851 "<Unknown WSP header field 0x%02X>")); \
1852 if (val_id & 0x80) { /* Well-known value */ \
1854 /* Well-known value processing starts HERE \
1858 #define wkh_2_TextualValue /* Parse Textual Value */ \
1860 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \
1861 val_str = tvb_get_stringz (tvb, val_start, &val_len); \
1862 g_assert(val_str); \
1863 offset = val_start + val_len; \
1864 /* Textual value processing starts HERE \
1868 #define wkh_3_ValueWithLength /* Parse Value With Length */ \
1871 } else { /* val_start points to 1st byte of length field */ \
1872 if (val_id == 0x1F) { /* Value Length = guintvar */ \
1873 val_len = tvb_get_guintvar(tvb, val_start + 1, &val_len_len); \
1874 val_len_len++; /* 0x1F length indicator byte */ \
1875 } else { /* Short length followed by Len data octets */ \
1876 val_len = tvb_get_guint8(tvb, offset); \
1879 offset += val_len_len + val_len; \
1880 /* Value with length processing starts HERE \
1881 * The value lies between val_start and offset: \
1882 * - Value Length: Start = val_start \
1883 * Length = val_len_len \
1884 * - Value Data : Start = val_start + val_len_len \
1885 * Length = val_len \
1886 * End = offset - 1 \
1889 #define wkh_4_End(hf) /* End of value parsing */ \
1892 /* Check for errors */ \
1894 if (ti) { /* Append to protocol tree item label */ \
1895 proto_item_append_text(ti, \
1896 " <Error: Invalid header value>"); \
1897 } else if (hf > 0) { /* Create protocol tree item */ \
1898 proto_tree_add_string(tree, hf, \
1899 tvb, hdr_start, offset - hdr_start, \
1900 " <Error: Invalid header value>"); \
1901 } else { /* Create anonymous header field entry */ \
1902 proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start, \
1903 "%s: <Error: Invalid header value>", \
1904 val_to_str (hdr_id, vals_field_names, \
1905 "<Unknown WSP header field 0x%02X>")); \
1912 * This yields the following default header value parser function body
1915 wkh_default(proto_tree *tree, tvbuff_t *tvb,
1920 ok = TRUE; /* Bypass error checking as we don't parse the values! */
1922 wkh_1_WellKnownValue;
1923 ti = proto_tree_add_text (tree, tvb, hdr_start, offset - hdr_start,
1924 "%s: (Undecoded well-known value 0x%02x)",
1925 val_to_str (hdr_id, vals_field_names,
1926 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F);
1928 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
1930 val_to_str (hdr_id, vals_field_names,
1931 "<Unknown WSP header field 0x%02X>"), val_str);
1932 wkh_3_ValueWithLength;
1933 ti = proto_tree_add_text (tree, tvb, hdr_start, offset - hdr_start,
1934 "%s: (Undecoded value in general form with length indicator)",
1935 val_to_str (hdr_id, vals_field_names,
1936 "<Unknown WSP header field 0x%02X>"));
1938 wkh_4_End(HF_EMPTY); /* The default parser has no associated hf_index;
1939 additionally the error code is always bypassed */
1943 /* Content-type processing uses the following common core: */
1944 #define wkh_content_type_header(underscored,Text) \
1946 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
1948 wkh_0_Declarations; \
1949 guint32 off, val = 0, len; \
1951 proto_tree *parameter_tree = NULL; \
1953 wkh_1_WellKnownValue; \
1954 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
1955 tvb, hdr_start, offset - hdr_start, \
1956 val_to_str(val_id & 0x7F, vals_content_types, \
1957 "(Unknown content type identifier 0x%X)")); \
1959 wkh_2_TextualValue; \
1960 /* Sometimes with a No-Content response, a NULL content type \
1961 * is reported. Process this correctly! */ \
1963 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
1964 tvb, hdr_start, offset - hdr_start, \
1967 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
1968 tvb, hdr_start, offset - hdr_start, \
1969 "<no content type has been specified>"); \
1972 wkh_3_ValueWithLength; \
1973 off = val_start + val_len_len; \
1974 peek = tvb_get_guint8(tvb, off); \
1975 if (is_text_string(peek)) { \
1976 get_extension_media(val_str, tvb, off, len, ok); \
1977 /* As we're using val_str, it is automatically g_free()d */ \
1978 off += len; /* off now points to 1st byte after string */ \
1979 ti = proto_tree_add_string (tree, hf_hdr_ ## underscored, \
1980 tvb, hdr_start, offset - hdr_start, val_str); \
1981 } else if (is_integer_value(peek)) { \
1982 get_integer_value(val, tvb, off, len, ok); \
1984 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
1985 tvb, hdr_start, offset - hdr_start, \
1986 val_to_str(val, vals_content_types, \
1987 "(Unknown content type identifier 0x%X)")); \
1991 /* Remember: offset == val_start + val_len + val_len_len */ \
1992 if (ok && (off < offset)) { /* Add parameters if any */ \
1993 parameter_tree = proto_item_add_subtree (ti, ett_header); \
1994 while (off < offset) { \
1995 off = parameter (parameter_tree, ti, tvb, off, offset - off); \
1999 wkh_4_End(hf_hdr_ ## underscored); \
2007 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2009 wkh_content_type_header(accept, "Accept")
2013 * Content-type-value =
2016 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2018 * Beware: this header should not appear as such; it is dissected elsewhere
2019 * and at the same time the content type is used for subdissectors.
2020 * It is here for the sake of completeness.
2022 wkh_content_type_header(content_type, "Content-Type")
2026 * Content-type-value =
2029 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2031 * This function adds the content type value to the protocol tree,
2032 * and computes either the numeric or textual media type in return,
2033 * which will be used for further subdissection (e.g., MMS, WBXML).
2036 add_content_type(proto_tree *tree, tvbuff_t *tvb, guint32 val_start,
2037 guint32 *well_known_content, const char **textual_content)
2039 /* Replace wkh_0_Declarations with slightly modified declarations
2040 * so we can still make use of the wkh_[1-4]_XXX macros! */
2041 guint32 hdr_start = val_start; /* No header name, only value! */
2042 guint8 hdr_id = FN_CONTENT_TYPE; /* Same remark */
2043 guint8 val_id = tvb_get_guint8 (tvb, val_start);
2044 guint32 offset = val_start; /* Offset to one past this header */
2045 guint32 val_len; /* length for value with length field */
2046 guint32 val_len_len; /* length of length field */
2047 guint8 *val_str = NULL;
2048 guint32 off, val = 0, len;
2050 gboolean ok = FALSE;
2051 proto_item *ti = NULL;
2052 proto_tree *parameter_tree = NULL;
2054 *textual_content = NULL;
2055 *well_known_content = 0;
2057 wkh_1_WellKnownValue;
2058 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2059 tvb, hdr_start, offset - hdr_start,
2060 val_to_str(val_id & 0x7F, vals_content_types,
2061 "<Unknown content type identifier 0x%X>"));
2062 *well_known_content = val_id & 0x7F;
2065 /* Sometimes with a No-Content response, a NULL content type
2066 * is reported. Process this correctly! */
2068 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2069 tvb, hdr_start, offset - hdr_start,
2071 /* As we're using val_str, it is automatically g_free()d */
2072 *textual_content = g_strdup(val_str);
2073 *well_known_content = 0;
2075 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2076 tvb, hdr_start, offset - hdr_start,
2077 "<no content type has been specified>");
2078 *textual_content = NULL;
2079 *well_known_content = 0;
2082 wkh_3_ValueWithLength;
2083 off = val_start + val_len_len;
2084 peek = tvb_get_guint8(tvb, off);
2085 if (is_text_string(peek)) {
2086 get_extension_media(val_str, tvb, off, len, ok);
2087 /* As we're using val_str, it is automatically g_free()d */
2088 /* ??? Not sure anymore, we're in wkh_3, not in wkh_2 ! */
2089 off += len; /* off now points to 1st byte after string */
2090 ti = proto_tree_add_string (tree, hf_hdr_content_type,
2091 tvb, hdr_start, offset - hdr_start, val_str);
2092 /* Following statement: required? */
2093 *textual_content = g_strdup(val_str);
2094 *well_known_content = 0;
2095 } else if (is_integer_value(peek)) {
2096 get_integer_value(val, tvb, off, len, ok);
2098 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2099 tvb, hdr_start, offset - hdr_start,
2100 val_to_str(val, vals_content_types,
2101 "<Unknown content type identifier 0x%X>"));
2102 *textual_content = NULL;
2103 *well_known_content = val;
2106 } /* else ok = FALSE */
2107 /* Remember: offset == val_start + val_len_len + val_len */
2108 if (ok && (off < offset)) { /* Add parameters if any */
2109 parameter_tree = proto_item_add_subtree (ti, ett_header);
2110 while (off < offset) {
2111 off = parameter (parameter_tree, ti, tvb, off, offset - off);
2115 wkh_4_End(hf_hdr_content_type);
2120 * Template for accept_X headers with optional Q parameter value
2122 #define wkh_accept_x_q_header(underscored,Text,valueString,valueName) \
2124 wkh_ ## underscored (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2126 wkh_0_Declarations; \
2127 guint32 off, val = 0, len; \
2129 proto_tree *parameter_tree = NULL; \
2131 wkh_1_WellKnownValue; \
2132 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2133 tvb, hdr_start, offset - hdr_start, \
2134 val_to_str(val_id & 0x7F, valueString, \
2135 "<Unknown " valueName " identifier 0x%X>")); \
2137 wkh_2_TextualValue; \
2138 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2139 tvb, hdr_start, offset - hdr_start, val_str); \
2141 wkh_3_ValueWithLength; \
2142 off = val_start + val_len_len; \
2143 peek = tvb_get_guint8(tvb, off); \
2144 if (is_text_string(peek)) { \
2145 get_token_text(val_str, tvb, off, len, ok); \
2146 /* As we're using val_str, it is automatically g_free()d */ \
2147 off += len; /* off now points to 1st byte after string */ \
2148 ti = proto_tree_add_string (tree, hf_hdr_ ## underscored, \
2149 tvb, hdr_start, offset - hdr_start, val_str); \
2150 } else if (is_integer_value(peek)) { \
2151 get_integer_value(val, tvb, off, len, ok); \
2153 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2154 tvb, hdr_start, offset - hdr_start, \
2155 val_to_str(val, valueString, \
2156 "<Unknown " valueName " identifier 0x%X>")); \
2159 } /* else ok = FALSE */ \
2160 /* Remember: offset == val_start + val_len */ \
2161 if (ok && (off < offset)) { /* Add Q-value if available */ \
2162 parameter_tree = proto_item_add_subtree (ti, ett_header); \
2163 off = parameter_value_q (parameter_tree, ti, tvb, off); \
2166 wkh_4_End(hf_hdr_ ## underscored); \
2170 * Accept-charset-value =
2173 * | ( Value-length ( Token-text | Integer-value ) [ Q-value ] )
2175 wkh_accept_x_q_header(accept_charset, "Accept-Charset",
2176 vals_character_sets, "character set")
2178 * Accept-language-value =
2181 * | ( Value-length ( Text-string | Integer-value ) [ Q-value ] )
2183 wkh_accept_x_q_header(accept_language, "Accept-Language",
2184 vals_languages, "language")
2188 * Push-flag-value = Short-integer
2191 wkh_push_flag(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2194 proto_tree *subtree = NULL;
2196 wkh_1_WellKnownValue;
2197 ti = proto_tree_add_string(tree, hf_hdr_push_flag,
2198 tvb, hdr_start, offset - hdr_start, "");
2199 subtree = proto_item_add_subtree(ti, ett_header);
2200 proto_tree_add_uint(subtree, hf_hdr_push_flag_auth,
2201 tvb, val_start, 1, val_id);
2202 proto_tree_add_uint(subtree, hf_hdr_push_flag_trust,
2203 tvb, val_start, 1, val_id);
2204 proto_tree_add_uint(subtree, hf_hdr_push_flag_last,
2205 tvb, val_start, 1, val_id);
2207 proto_item_append_string(ti, " (Initiator URI authenticated)");
2209 proto_item_append_string(ti, " (Content trusted)");
2211 proto_item_append_string(ti, " (Last push message)");
2213 proto_item_append_text(ti, " <Warning: Reserved flags set>");
2218 wkh_3_ValueWithLength;
2220 wkh_4_End(hf_hdr_push_flag);
2229 wkh_allow(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2233 wkh_1_WellKnownValue;
2235 if (val_id >= 0x40) { /* Valid WSP method */
2236 ti = proto_tree_add_string(tree, hf_hdr_allow,
2237 tvb, hdr_start, offset - hdr_start,
2238 val_to_str(val_id & 0x7F, vals_pdu_type,
2239 "<Unknown WSP method 0x%02X>"));
2244 wkh_3_ValueWithLength;
2246 wkh_4_End(hf_hdr_allow);
2252 * Token-text | Short-integer
2255 wkh_public(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2259 wkh_1_WellKnownValue;
2261 if (val_id >= 0x40) { /* Valid WSP method */
2262 ti = proto_tree_add_string(tree, hf_hdr_public,
2263 tvb, hdr_start, offset - hdr_start,
2264 val_to_str(val_id & 0x7F, vals_pdu_type,
2265 "<Unknown WSP method 0x%02X>"));
2269 ti = proto_tree_add_string(tree, hf_hdr_public,
2270 tvb, hdr_start, offset - hdr_start, val_str);
2272 wkh_3_ValueWithLength;
2274 wkh_4_End(hf_hdr_public);
2280 * Token-text | Short-integer
2283 wkh_vary(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2287 wkh_1_WellKnownValue;
2288 ti = proto_tree_add_string(tree, hf_hdr_vary,
2289 tvb, hdr_start, offset - hdr_start,
2290 val_to_str(val_id & 0x7F, vals_field_names,
2291 "<Unknown WSP header field 0x%02X>"));
2294 ti = proto_tree_add_string(tree, hf_hdr_vary,
2295 tvb, hdr_start, offset - hdr_start,
2298 wkh_3_ValueWithLength;
2300 wkh_4_End(hf_hdr_vary);
2305 * X-wap-security-value = 0x80
2308 wkh_x_wap_security(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2312 wkh_1_WellKnownValue;
2313 if (val_id == 0x80) {
2314 ti = proto_tree_add_string(tree, hf_hdr_x_wap_security,
2315 tvb, hdr_start, offset - hdr_start, "close-subordinate");
2320 wkh_3_ValueWithLength;
2322 wkh_4_End(hf_hdr_x_wap_security);
2327 * Connection-value = 0x80 | Token-text
2330 wkh_connection(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2334 wkh_1_WellKnownValue;
2335 if (val_id == 0x80) {
2336 ti = proto_tree_add_string(tree, hf_hdr_connection,
2337 tvb, hdr_start, offset - hdr_start, "close");
2341 ti = proto_tree_add_string(tree, hf_hdr_connection,
2342 tvb, hdr_start, offset - hdr_start, val_str);
2344 wkh_3_ValueWithLength;
2346 wkh_4_End(hf_hdr_connection);
2351 * Transfer-encoding-value = 0x80 | Token-text
2354 wkh_transfer_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2358 wkh_1_WellKnownValue;
2359 if (val_id == 0x80) {
2360 ti = proto_tree_add_string(tree, hf_hdr_transfer_encoding,
2361 tvb, hdr_start, offset - hdr_start, "chunked");
2365 ti = proto_tree_add_string(tree, hf_hdr_transfer_encoding,
2366 tvb, hdr_start, offset - hdr_start, val_str);
2368 wkh_3_ValueWithLength;
2370 wkh_4_End(hf_hdr_transfer_encoding);
2375 * Accept-range-value = 0x80 | 0x81 | Token-text
2378 wkh_accept_ranges(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2382 wkh_1_WellKnownValue;
2384 case 0x80: /* none */
2385 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2386 tvb, hdr_start, offset - hdr_start, "none");
2389 case 0x81: /* bytes */
2390 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2391 tvb, hdr_start, offset - hdr_start, "bytes");
2396 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2397 tvb, hdr_start, offset - hdr_start, val_str);
2399 wkh_3_ValueWithLength;
2401 wkh_4_End(hf_hdr_accept_ranges);
2406 * Content-encoding-value = 0x80 | 0x81 | 0x82 | Token-text
2409 wkh_content_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2413 wkh_1_WellKnownValue;
2415 case 0x80: /* gzip */
2416 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2417 tvb, hdr_start, offset - hdr_start, "gzip");
2420 case 0x81: /* compress */
2421 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2422 tvb, hdr_start, offset - hdr_start, "compress");
2425 case 0x82: /* deflate */
2426 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2427 tvb, hdr_start, offset - hdr_start, "deflate");
2432 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2433 tvb, hdr_start, offset - hdr_start, val_str);
2435 wkh_3_ValueWithLength;
2437 wkh_4_End(hf_hdr_content_encoding);
2442 * Accept-encoding-value =
2445 * | ( Value-length ( Short-integer | Text-string ) [ Q-value ] )
2448 wkh_accept_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2454 proto_tree *parameter_tree = NULL;
2456 wkh_1_WellKnownValue;
2458 case 0x80: /* gzip */
2459 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2460 tvb, hdr_start, offset - hdr_start, "gzip");
2463 case 0x81: /* compress */
2464 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2465 tvb, hdr_start, offset - hdr_start, "compress");
2468 case 0x82: /* deflate */
2469 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2470 tvb, hdr_start, offset - hdr_start, "deflate");
2475 proto_tree_add_string(tree, hf_hdr_accept_encoding,
2476 tvb, hdr_start, offset - hdr_start, val_str);
2478 wkh_3_ValueWithLength;
2479 off = val_start + val_len_len;
2480 peek = tvb_get_guint8(tvb, off);
2481 if (is_short_integer(peek)) {
2483 case 0x80: /* gzip */
2484 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2485 tvb, hdr_start, offset - hdr_start, "gzip");
2488 case 0x81: /* compress */
2489 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2490 tvb, hdr_start, offset - hdr_start, "compress");
2493 case 0x82: /* deflate */
2494 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2495 tvb, hdr_start, offset - hdr_start, "deflate");
2498 case 0x83: /* any */
2499 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2500 tvb, hdr_start, offset - hdr_start, "*");
2506 get_token_text(str, tvb, off, len, ok);
2508 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2509 tvb, hdr_start, offset - hdr_start, str);
2515 /* Remember: offset == val_start + val_len_len + val_len */
2516 if (off < offset) { /* Add Q-value if available */
2517 parameter_tree = proto_item_add_subtree(ti, ett_header);
2518 off = parameter_value_q(parameter_tree, ti, tvb, off);
2521 wkh_4_End(hf_hdr_accept_encoding);
2526 * Content-disposition-value = Value-length ( Disposition ) *( Parameter )
2527 * Disposition = Form-data | Attachment | Inline | Token-text
2531 * We handle this as:
2532 * Value-length ( Short-integer | Text-string ) *( Parameter )
2535 wkh_content_disposition(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2541 proto_tree *parameter_tree = NULL;
2543 wkh_1_WellKnownValue;
2547 wkh_3_ValueWithLength;
2548 off = val_start + val_len_len;
2549 peek = tvb_get_guint8(tvb, off);
2550 if (is_short_integer(peek)) {
2552 case 0x80: /* form-data */
2553 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2554 tvb, hdr_start, offset - hdr_start, "form-data");
2557 case 0x81: /* attachment */
2558 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2559 tvb, hdr_start, offset - hdr_start, "attachment");
2562 case 0x82: /* inline */
2563 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2564 tvb, hdr_start, offset - hdr_start, "inline");
2570 get_token_text(str, tvb, off, len, ok);
2572 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2573 tvb, hdr_start, offset - hdr_start, str);
2578 if ((ok) && (off < offset)) {
2579 /* Remember: offset == val_start + val_len_len + val_len */
2580 parameter_tree = proto_item_add_subtree(ti, ett_header);
2581 while (off < offset) { /* Add parameters if available */
2582 off = parameter(parameter_tree, ti, tvb, off, offset - off);
2585 wkh_4_End(hf_hdr_content_disposition);
2590 * Common code for headers with only a textual value
2591 * is written in the macro below:
2593 #define wkh_text_header(underscored,Text) \
2595 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2597 wkh_0_Declarations; \
2599 wkh_1_WellKnownValue; \
2601 wkh_2_TextualValue; \
2602 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2603 tvb, hdr_start, offset - hdr_start, val_str); \
2605 wkh_3_ValueWithLength; \
2607 wkh_4_End(hf_hdr_ ## underscored); \
2610 /* Text-only headers: */
2611 wkh_text_header(content_base, "Content-Base")
2612 wkh_text_header(content_location, "Content-Location")
2613 wkh_text_header(etag, "ETag")
2614 wkh_text_header(from, "From")
2615 wkh_text_header(host, "Host")
2616 wkh_text_header(if_match, "If-Match")
2617 wkh_text_header(if_none_match, "If-None-Match")
2618 wkh_text_header(location, "Location")
2619 wkh_text_header(referer, "Referer")
2620 wkh_text_header(server, "Server")
2621 wkh_text_header(user_agent, "User-Agent")
2622 wkh_text_header(upgrade, "Upgrade")
2623 wkh_text_header(via, "Via")
2624 wkh_text_header(content_uri, "Content-Uri")
2625 wkh_text_header(initiator_uri, "Initiator-Uri")
2626 wkh_text_header(profile, "Profile")
2629 * Same for quoted-string value
2631 #define wkh_quoted_string_header(underscored,Text) \
2633 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2635 wkh_0_Declarations; \
2638 wkh_1_WellKnownValue; \
2640 wkh_2_TextualValue; \
2641 if (is_quoted_string(val_str[0])) { \
2642 if (is_quoted_string(val_str[val_len-2])) { \
2643 /* Trailing quote - issue a warning */ \
2644 str = g_strdup_printf("%s" TrailingQuoteWarning, val_str); \
2645 } else { /* OK (no trailing quote) */ \
2646 str = g_strdup_printf("%s\"", val_str); \
2648 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2649 tvb, hdr_start, offset - hdr_start, str); \
2652 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2653 tvb, hdr_start, offset - hdr_start, val_str); \
2654 proto_item_append_text(ti, \
2655 " <Warning: should be encoded as a Quoted-string>"); \
2658 wkh_3_ValueWithLength; \
2660 wkh_4_End(hf_hdr_ ## underscored); \
2663 wkh_quoted_string_header(content_id, "Content-ID")
2667 * Common code for headers with only a textual or a date value
2668 * is written in the macro below:
2670 #define wkh_text_or_date_value_header(underscored,Text) \
2672 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2674 wkh_0_Declarations; \
2675 guint32 val = 0, off = val_start, len; \
2677 gchar *str; /* may not be freed! */ \
2679 wkh_1_WellKnownValue; \
2681 wkh_2_TextualValue; \
2682 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2683 tvb, hdr_start, offset - hdr_start, val_str); \
2685 wkh_3_ValueWithLength; \
2686 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2687 get_date_value(val, tvb, off, len, ok); \
2691 str = abs_time_to_str(&tv); \
2693 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2694 tvb, hdr_start, offset - hdr_start, str); \
2695 /* BEHOLD: do NOT try to free str, as this generates a core
2696 * dump! It looks like abs_time_to_str() is buggy or works
2697 * with static data. */ \
2700 wkh_4_End(hf_hdr_ ## underscored); \
2704 wkh_text_or_date_value_header(if_range,"If-Range")
2708 * Common code for headers with only a date value
2709 * is written in the macro below:
2711 #define wkh_date_value_header(underscored,Text) \
2713 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2715 wkh_0_Declarations; \
2716 guint32 val = 0, off = val_start, len; \
2718 gchar *str; /* may not be freed! */ \
2720 wkh_1_WellKnownValue; \
2722 wkh_2_TextualValue; \
2724 wkh_3_ValueWithLength; \
2725 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2726 get_date_value(val, tvb, off, len, ok); \
2730 str = abs_time_to_str(&tv); \
2732 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2733 tvb, hdr_start, offset - hdr_start, str); \
2734 /* BEHOLD: do NOT try to free str, as this generates a core
2735 * dump! It looks like abs_time_to_str() is buggy or works
2736 * with static data. */ \
2739 wkh_4_End(hf_hdr_ ## underscored); \
2742 /* Date-value only headers: */
2743 wkh_date_value_header(date, "Date")
2744 wkh_date_value_header(expires, "Expires")
2745 wkh_date_value_header(if_modified_since, "If-Modified-Since")
2746 wkh_date_value_header(if_unmodified_since, "If-Unmodified-Since")
2747 wkh_date_value_header(last_modified, "Last-Modified")
2750 /* Date-value with special interpretation of zero value */
2751 #define wkh_tod_value_header(underscored,Text) \
2753 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2755 wkh_0_Declarations; \
2756 guint32 val = 0, off = val_start, len; \
2758 gchar *str; /* may not be freed! */ \
2760 wkh_1_WellKnownValue; \
2761 if (val_id == 0x80) { /* Openwave TOD header uses this format */ \
2762 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2763 tvb, hdr_start, offset - hdr_start, \
2764 "Requesting Time Of Day"); \
2765 proto_item_append_text(ti, \
2766 " <Warning: should be encoded as long-integer>"); \
2769 /* It seems VERY unlikely that we'll see date values within the first \
2770 * 127 seconds of the UNIX 1-1-1970 00:00:00 start of the date clocks \
2771 * so I assume such a value is a genuine error */ \
2772 wkh_2_TextualValue; \
2774 wkh_3_ValueWithLength; \
2775 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2776 get_date_value(val, tvb, off, len, ok); \
2779 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2780 tvb, hdr_start, offset - hdr_start, \
2781 "Requesting Time Of Day"); \
2785 str = abs_time_to_str(&tv); \
2787 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2788 tvb, hdr_start, offset - hdr_start, str); \
2792 wkh_4_End(hf_hdr_ ## underscored); \
2795 wkh_tod_value_header(x_wap_tod, "X-Wap-Tod")
2799 * Age-value: Delta-seconds-value
2802 wkh_age(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2805 guint32 val = 0, off = val_start, len;
2807 wkh_1_WellKnownValue;
2808 val = val_id & 0x7F;
2809 val_str = g_strdup_printf("%u second%s", val, PLURALIZE(val));
2810 ti = proto_tree_add_string(tree, hf_hdr_age,
2811 tvb, hdr_start, offset - hdr_start, val_str);
2812 g_free(val_str); /* proto_XXX creates a copy */
2816 wkh_3_ValueWithLength;
2817 if (val_id <= 4) { /* Length field already parsed by macro! */
2818 get_long_integer(val, tvb, off, len, ok);
2820 val_str = g_strdup_printf("%u second%s", val, PLURALIZE(val));
2821 ti = proto_tree_add_string(tree, hf_hdr_age,
2822 tvb, hdr_start, offset - hdr_start, val_str);
2823 g_free(val_str); /* proto_XXX creates a copy */
2826 wkh_4_End(hf_hdr_age);
2831 * Template for Integer lookup or text value headers:
2833 #define wkh_integer_lookup_or_text_value(underscored,Text,valueString,valueName) \
2835 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2837 wkh_0_Declarations; \
2838 guint32 val = 0, off = val_start, len; \
2840 wkh_1_WellKnownValue; \
2841 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2842 tvb, hdr_start, offset - hdr_start, \
2843 val_to_str(val_id & 0x7F, valueString, \
2844 "(Unknown " valueName " identifier 0x%X)")); \
2846 wkh_2_TextualValue; \
2847 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2848 tvb, hdr_start, offset - hdr_start, val_str); \
2850 wkh_3_ValueWithLength; \
2851 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2852 get_long_integer(val, tvb, off, len, ok); \
2854 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2855 tvb, hdr_start, offset - hdr_start, \
2856 val_to_str(val_id & 0x7F, valueString, \
2857 "(Unknown " valueName " identifier 0x%X)")); \
2860 wkh_4_End(hf_hdr_ ## underscored); \
2864 * Wap-application-value: Uri-value | Integer-value
2866 wkh_integer_lookup_or_text_value(x_wap_application_id, "X-Wap-Application-Id",
2867 vals_wap_application_ids, "WAP application")
2868 wkh_integer_lookup_or_text_value(accept_application, "Accept-Application",
2869 vals_wap_application_ids, "WAP application")
2870 wkh_integer_lookup_or_text_value(content_language, "Content-Language",
2871 vals_languages, "language")
2872 /* NOTE - Although the WSP spec says this is an integer-value, the WSP headers
2873 * are encoded as a 7-bit entity! */
2874 wkh_integer_lookup_or_text_value(trailer, "Trailer",
2875 vals_field_names, "well-known-header")
2883 * Common code for headers with only a challenge value
2884 * is written in the macro below:
2886 #define wkh_challenge_value_header(underscored,Text) \
2888 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, \
2889 guint32 hdr_start) \
2891 wkh_0_Declarations; \
2894 proto_tree *subtree; \
2897 wkh_1_WellKnownValue; \
2899 wkh_2_TextualValue; \
2901 wkh_3_ValueWithLength; \
2902 off = val_start + val_len_len; \
2903 peek = tvb_get_guint8(tvb, off); \
2904 if (peek == 0x80) { /* Basic */ \
2905 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2906 tvb, hdr_start, offset - hdr_start, "basic"); \
2907 subtree = proto_item_add_subtree(ti, ett_header); \
2908 proto_tree_add_string(subtree, hf_hdr_ ## underscored ## _scheme, \
2909 tvb, off, 1, "basic"); \
2911 /* Realm: text-string */ \
2912 get_text_string(str,tvb,off,len,ok); \
2914 proto_tree_add_string(subtree, \
2915 hf_hdr_ ## underscored ## _realm, \
2916 tvb, off, len, str); \
2917 val_str = g_strdup_printf("; realm=%s", str); \
2918 proto_item_append_string(ti, val_str); \
2923 } else { /* Authentication-scheme: token-text */ \
2924 get_token_text(str, tvb, off, len, ok); \
2926 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2927 tvb, hdr_start, off - hdr_start, str); \
2928 subtree = proto_item_add_subtree(ti, ett_header); \
2929 proto_tree_add_string(subtree, \
2930 hf_hdr_ ## underscored ## _scheme, \
2931 tvb, hdr_start, off - hdr_start, str); \
2934 /* Realm: text-string */ \
2935 get_text_string(str,tvb,off,len,ok); \
2937 proto_tree_add_string(subtree, \
2938 hf_hdr_ ## underscored ## _realm, \
2939 tvb, off, len, str); \
2940 val_str = g_strdup_printf("; realm=%s", str); \
2941 proto_item_append_string(ti, val_str); \
2945 /* Auth-params: parameter - TODO */ \
2946 while (off < offset) /* Parse parameters */ \
2947 off = parameter(subtree, ti, tvb, off, offset - off); \
2951 wkh_4_End(hf_hdr_ ## underscored); \
2954 /* Challenge-value only headers: */
2955 wkh_challenge_value_header(www_authenticate, "WWW-Authenticate")
2956 wkh_challenge_value_header(proxy_authenticate, "Proxy-Authenticate")
2964 * Common code for headers with only a credentials value
2965 * is written in the macro below:
2967 #define wkh_credentials_value_header(underscored,Text) \
2969 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, \
2970 guint32 hdr_start) \
2972 wkh_0_Declarations; \
2975 proto_tree *subtree; \
2978 wkh_1_WellKnownValue; \
2980 wkh_2_TextualValue; \
2982 wkh_3_ValueWithLength; \
2983 off = val_start + val_len_len; \
2984 peek = tvb_get_guint8(tvb, off); \
2985 if (peek == 0x80) { /* Basic */ \
2986 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2987 tvb, hdr_start, offset - hdr_start, "basic"); \
2988 subtree = proto_item_add_subtree(ti, ett_header); \
2989 proto_tree_add_string(subtree, hf_hdr_ ## underscored ## _scheme, \
2990 tvb, off, 1, "basic"); \
2992 /* User-id: text-string */ \
2993 get_text_string(str,tvb,off,len,ok); \
2995 proto_tree_add_string(subtree, \
2996 hf_hdr_ ## underscored ## _user_id, \
2997 tvb, off, len, str); \
2998 val_str = g_strdup_printf("; user-id=%s", str); \
2999 proto_item_append_string(ti, val_str); \
3003 /* Password: text-string */ \
3004 get_text_string(str,tvb,off,len,ok); \
3006 proto_tree_add_string(subtree, \
3007 hf_hdr_ ## underscored ## _password, \
3008 tvb, off, len, str); \
3009 val_str = g_strdup_printf("; password=%s", str); \
3010 proto_item_append_string(ti, val_str); \
3016 } else { /* Authentication-scheme: token-text */ \
3017 get_token_text(str, tvb, off, len, ok); \
3019 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3020 tvb, hdr_start, off - hdr_start, str); \
3021 subtree = proto_item_add_subtree(ti, ett_header); \
3022 proto_tree_add_string(subtree, \
3023 hf_hdr_ ## underscored ## _scheme, \
3024 tvb, hdr_start, off - hdr_start, str); \
3027 /* Auth-params: parameter - TODO */ \
3028 while (off < offset) /* Parse parameters */ \
3029 off = parameter(subtree, ti, tvb, off, offset - off); \
3032 wkh_4_End(hf_hdr_ ## underscored); \
3035 /* Credentials-value only headers: */
3036 wkh_credentials_value_header(authorization, "Authorization")
3037 wkh_credentials_value_header(proxy_authorization, "Proxy-Authorization")
3041 * Content-md5-value = 16*16 OCTET
3044 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3049 wkh_1_WellKnownValue;
3053 wkh_3_ValueWithLength;
3054 off = val_start + val_len_len;
3055 if (val_len == 16) {
3056 val_str = g_strdup_printf(
3057 "%02x%02x%02x%02x%02x%02x%02x%02x"
3058 "%02x%02x%02x%02x%02x%02x%02x%02x",
3059 tvb_get_guint8(tvb, off),
3060 tvb_get_guint8(tvb, off + 1),
3061 tvb_get_guint8(tvb, off + 2),
3062 tvb_get_guint8(tvb, off + 3),
3063 tvb_get_guint8(tvb, off + 4),
3064 tvb_get_guint8(tvb, off + 5),
3065 tvb_get_guint8(tvb, off + 6),
3066 tvb_get_guint8(tvb, off + 7),
3067 tvb_get_guint8(tvb, off + 8),
3068 tvb_get_guint8(tvb, off + 9),
3069 tvb_get_guint8(tvb, off + 10),
3070 tvb_get_guint8(tvb, off + 11),
3071 tvb_get_guint8(tvb, off + 12),
3072 tvb_get_guint8(tvb, off + 13),
3073 tvb_get_guint8(tvb, off + 14),
3074 tvb_get_guint8(tvb, off + 15)
3076 ti = proto_tree_add_string(tree, hf_hdr_content_md5,
3077 tvb, hdr_start, offset - hdr_start, val_str);
3081 wkh_4_End(hf_hdr_content_md5);
3086 * Pragma-value = 0x80 | Length Parameter
3089 wkh_pragma(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3094 wkh_1_WellKnownValue;
3095 if (val_id == 0x80) {
3096 ti = proto_tree_add_string(tree, hf_hdr_pragma,
3097 tvb, hdr_start, offset - hdr_start, "no-cache");
3102 wkh_3_ValueWithLength;
3103 off = val_start + val_len_len;
3104 ti = proto_tree_add_string(tree, hf_hdr_pragma,
3105 tvb, hdr_start, off - hdr_start, "");
3106 /* NULL subtree for parameter() results in no subtree
3107 * TODO - provide a single parameter dissector that appends data
3108 * to the header field data. */
3109 off = parameter(NULL, ti, tvb, off, offset - off);
3111 wkh_4_End(hf_hdr_pragma);
3118 #define wkh_integer_value_header(underscored,Text) \
3120 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
3122 wkh_0_Declarations; \
3123 guint32 val = 0, off = val_start, len; \
3124 gchar *str; /* may not be freed! */ \
3126 wkh_1_WellKnownValue; \
3127 str = g_strdup_printf("%u", val_id & 0x7F); \
3128 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3129 tvb, hdr_start, offset - hdr_start, str); \
3132 wkh_2_TextualValue; \
3134 wkh_3_ValueWithLength; \
3135 if (val_id <= 4) { /* Length field already parsed by macro! */ \
3136 get_long_integer(val, tvb, off, len, ok); \
3138 str = g_strdup_printf("%u", val); \
3139 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3140 tvb, hdr_start, offset - hdr_start, str); \
3144 wkh_4_End(hf_hdr_ ## underscored); \
3147 wkh_integer_value_header(content_length, "Content-Length")
3148 wkh_integer_value_header(max_forwards, "Max-Forwards")
3151 #define wkh_integer_lookup_value_header(underscored,Text,valueString,valueName) \
3153 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
3155 wkh_0_Declarations; \
3156 guint32 val = 0, off = val_start, len; \
3158 wkh_1_WellKnownValue; \
3159 val_str = match_strval(val_id & 0x7F, valueString); \
3161 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3162 tvb, hdr_start, offset - hdr_start, val_str); \
3165 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3166 tvb, hdr_start, offset - hdr_start, \
3167 "<Unknown " valueName ">"); \
3169 wkh_2_TextualValue; \
3171 wkh_3_ValueWithLength; \
3172 if (val_id <= 4) { /* Length field already parsed by macro! */ \
3173 get_long_integer(val, tvb, off, len, ok); \
3175 val_str = match_strval(val_id & 0x7F, valueString); \
3177 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3178 tvb, hdr_start, offset - hdr_start, val_str); \
3181 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3182 tvb, hdr_start, offset - hdr_start, \
3183 "<Unknown " valueName ">"); \
3187 wkh_4_End(hf_hdr_ ## underscored); \
3190 wkh_integer_lookup_value_header(bearer_indication, "Bearer-Indication",
3191 vals_bearer_types, "bearer type")
3195 * Cache-control-value
3198 wkh_cache_control(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3201 guint32 off, len, val = 0;
3202 guint8 peek, cache_control_directive;
3205 wkh_1_WellKnownValue;
3206 val = val_id & 0x7F;
3207 val_str = match_strval(val, vals_cache_control);
3209 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3210 tvb, hdr_start, offset - hdr_start, val_str);
3214 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3215 tvb, hdr_start, offset - hdr_start, val_str);
3217 wkh_3_ValueWithLength;
3219 * ( no-cache | private ) 1*( Field-name )
3220 * | ( max-age | max-stale | min-fresh | s-maxage) Delta-seconds-value
3221 * | Token-text ( Integer-value | Text-value )
3223 * Field-name = Short-integer | Token-text
3225 off = val_start + val_len_len;
3226 cache_control_directive = tvb_get_guint8(tvb, off++);
3227 if (cache_control_directive & 0x80) { /* Well known cache directive */
3228 switch (cache_control_directive & 0x7F) {
3229 case CACHE_CONTROL_NO_CACHE:
3230 case CACHE_CONTROL_PRIVATE:
3231 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3232 tvb, hdr_start, offset - hdr_start,
3233 val_to_str (cache_control_directive & 0x7F, vals_cache_control,
3234 "<Unknown cache control directive 0x%02X>"));
3235 /* TODO: split multiple entries */
3236 while (ok && (off < offset)) { /* 1*( Field-name ) */
3238 peek = tvb_get_guint8(tvb, off);
3239 if (peek & 0x80) { /* Well-known-field-name */
3240 proto_item_append_string(ti,
3241 val_to_str (peek, vals_field_names,
3242 "<Unknown WSP header field 0x%02X>"));
3244 } else { /* Token-text */
3245 get_token_text(val_str, tvb, off, len, ok);
3247 proto_item_append_string(ti, val_str);
3255 case CACHE_CONTROL_MAX_AGE:
3256 case CACHE_CONTROL_MAX_STALE:
3257 case CACHE_CONTROL_MIN_FRESH:
3258 case CACHE_CONTROL_S_MAXAGE:
3259 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3260 tvb, hdr_start, offset - hdr_start,
3261 val_to_str (cache_control_directive & 0x7F, vals_cache_control,
3262 "<Unknown cache control directive 0x%02X>"));
3263 get_delta_seconds_value(val, tvb, off, len, ok);
3265 val_str = g_strdup_printf("=%u second%s",
3266 val, PLURALIZE(val));
3267 proto_item_append_string(ti, val_str);
3268 g_free(val_str); /* proto_XXX creates a copy */
3276 } else if (is_token_text(cache_control_directive)) {
3277 get_token_text(val_str, tvb, off, len, ok);
3279 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3280 tvb, hdr_start, offset - hdr_start, val_str);
3282 get_integer_value(val, tvb, off, len, ok);
3283 if (ok) { /* Integer-value */
3284 val_str = g_strdup_printf("=%u", val);
3285 proto_item_append_string(ti, val_str);
3286 g_free(val_str); /* proto_XXX creates a copy */
3287 } else { /* Text-value */
3288 get_text_string(val_str, tvb, off, len, ok);
3290 if (is_quoted_string(val_str[0])) {
3291 if (is_quoted_string(val_str[len-2])) {
3292 /* Trailing quote - issue a warning */
3293 str = g_strdup_printf("%s" TrailingQuoteWarning,
3295 } else { /* OK (no trailing quote) */
3296 str = g_strdup_printf("%s\"", val_str);
3298 proto_item_append_string(ti, str);
3300 } else { /* Token-text | 0x00 */
3301 /* TODO - check that we have Token-text or 0x00 */
3302 proto_item_append_string(ti, val_str);
3309 wkh_4_End(hf_hdr_cache_control);
3316 * | ( Value-length Short-integer Text-string Text-string )
3319 wkh_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3322 guint32 off, len, val;
3325 proto_tree *subtree;
3327 /* TODO - subtree with values */
3329 wkh_1_WellKnownValue;
3330 val = val_id & 0x7F;
3331 val_str = match_strval(val, vals_wsp_warning_code);
3333 ti = proto_tree_add_string(tree, hf_hdr_warning,
3334 tvb, hdr_start, offset - hdr_start, val_str);
3335 subtree = proto_item_add_subtree(ti, ett_header);
3336 proto_tree_add_uint(subtree, hf_hdr_warning_code,
3337 tvb, val_start, 1, val);
3342 wkh_3_ValueWithLength;
3343 /* TODO - subtree with individual values */
3344 off = val_start + val_len_len;
3345 warn_code = tvb_get_guint8(tvb, off);
3346 if (warn_code & 0x80) { /* Well known warn code */
3347 val = warn_code & 0x7f;
3348 val_str = match_strval(val, vals_wsp_warning_code_short);
3349 if (val_str) { /* OK */
3350 str = g_strdup_printf("code=%s", val_str);
3351 ti = proto_tree_add_string(tree, hf_hdr_warning,
3352 tvb, hdr_start, offset - hdr_start, str);
3354 subtree = proto_item_add_subtree(ti, ett_header);
3355 proto_tree_add_uint(subtree, hf_hdr_warning_code,
3357 off++; /* Now skip to the warn-agent subfield */
3358 get_text_string(str, tvb, off, len, ok);
3359 if (ok) { /* Valid warn-agent string */
3360 proto_tree_add_string(subtree, hf_hdr_warning_agent,
3361 tvb, off, len, str);
3362 val_str = g_strdup_printf("; agent=%s", str);
3363 proto_item_append_string(ti, val_str);
3364 g_free(val_str); /* proto_XXX creates a copy */
3367 get_text_string(str, tvb, off, len, ok);
3368 if (ok) { /* Valid warn-text string */
3369 proto_tree_add_string(subtree,
3370 hf_hdr_warning_text,
3371 tvb, off, len, str);
3372 val_str = g_strdup_printf("; text=%s", str);
3373 proto_item_append_string(ti, val_str);
3374 g_free(val_str); /* proto_XXX creates a copy */
3381 wkh_4_End(hf_hdr_warning);
3386 * Profile-warning-value =
3388 * | ( Value-length Short-integer Text-string *( Date-value ) )
3391 wkh_profile_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3394 guint32 off, len, val = 0;
3399 wkh_1_WellKnownValue;
3400 val = val_id & 0x7F;
3401 val_str = match_strval(val, vals_wsp_profile_warning_code);
3403 ti = proto_tree_add_string(tree, hf_hdr_profile_warning,
3404 tvb, hdr_start, offset - hdr_start, val_str);
3409 wkh_3_ValueWithLength;
3410 off = val_start + val_len_len;
3411 warn_code = tvb_get_guint8(tvb, off++);
3412 if (warn_code & 0x80) { /* Well known warn code */
3413 val_str = match_strval(val, vals_wsp_profile_warning_code);
3414 if (val_str) { /* OK */
3415 ti = proto_tree_add_string(tree, hf_hdr_profile_warning,
3416 tvb, hdr_start, offset - hdr_start, val_str);
3417 get_uri_value(str, tvb, off, len, ok);
3418 if (ok) { /* Valid warn-target string */
3420 str = g_strdup_printf("; target=%s", val_str);
3421 proto_item_append_string(ti, str);
3422 g_free(str); /* proto_XXX creates a copy */
3423 /* Add zero or more dates */
3424 while (ok && (off < offset)) {
3425 get_date_value(val, tvb, off, len, ok);
3426 if (ok) { /* Valid warn-text string */
3430 val_str = abs_time_to_str(&tv);
3432 str = g_strdup_printf("; date=%s", val_str);
3433 proto_item_append_string(ti, str);
3434 g_free(str); /* proto_XXX creates a copy */
3435 /* BEHOLD: do NOT try to free val_str, as this
3436 * generates a core dump!
3437 * It looks like abs_time_to_str() is
3438 * buggy or works with static data. */
3444 wkh_4_End(hf_hdr_profile_warning);
3448 /* Encoding-version-value =
3451 * | Length Short-integer [ Short-integer | text-string ]
3453 static guint32 wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb,
3457 guint32 off, val, len;
3460 wkh_1_WellKnownValue;
3461 val = val_id & 0x7F;
3462 val_str = g_strdup_printf("%u.%u", val >> 4, val & 0x0F);
3463 proto_tree_add_string(tree, hf_hdr_encoding_version,
3464 tvb, hdr_start, offset - hdr_start, val_str);
3468 proto_tree_add_string(tree, hf_hdr_encoding_version,
3469 tvb, hdr_start, offset - hdr_start, val_str);
3471 wkh_3_ValueWithLength;
3472 off = val_start + val_len_len;
3473 val = tvb_get_guint8(tvb, off);
3474 if (val & 0x80) { /* Header Code Page */
3475 val_str = g_strdup_printf("code-page=%u", val & 0x7F);
3476 ti = proto_tree_add_string(tree, hf_hdr_encoding_version,
3477 tvb, hdr_start, offset - hdr_start, val_str);
3481 if (off < offset) { /* Extra version-value */
3482 get_version_value(val,val_str,tvb,off,len,ok);
3483 if (ok) { /* Always creates a string if OK */
3484 str = g_strdup_printf(": %s", val_str);
3485 proto_item_append_string(ti, str);
3492 wkh_4_End(hf_hdr_encoding_version);
3496 /* Content-range-value =
3497 * Length Uintvar-integer ( 0x80 | Uintvar-integer )
3500 wkh_content_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3503 guint32 off, val, len;
3504 proto_tree *subtree = NULL;
3506 wkh_1_WellKnownValue;
3510 wkh_3_ValueWithLength;
3511 off = val_start + val_len_len;
3512 get_uintvar_integer (val, tvb, off, len, ok); /* Uintvar start */
3514 val_str = g_strdup_printf("first-byte-pos=%u", val);
3515 ti = proto_tree_add_string(tree, hf_hdr_content_range,
3516 tvb, hdr_start, offset - hdr_start, val_str);
3517 subtree = proto_item_add_subtree(ti, ett_header);
3518 proto_tree_add_uint(subtree, hf_hdr_content_range_first_byte_pos,
3519 tvb, off, len, val);
3522 /* Now check next value */
3523 val = tvb_get_guint8(tvb, off);
3524 if (val == 0x80) { /* Unknown length */
3525 proto_item_append_string(ti, "; entity-length=unknown");
3526 } else { /* Uintvar entity length */
3527 get_uintvar_integer (val, tvb, off, len, ok);
3529 val_str = g_strdup_printf("; entity-length=%u", val);
3530 proto_item_append_string(ti, val_str);
3531 proto_tree_add_uint(subtree,
3532 hf_hdr_content_range_entity_length,
3533 tvb, off, len, val);
3539 wkh_4_End(hf_hdr_content_range);
3545 * 0x80 Uintvar-integer [ Uintvar-integer ]
3546 * | 0x81 Uintvar-integer
3549 wkh_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3552 guint32 off, val, len;
3553 proto_tree *subtree = NULL;
3555 wkh_1_WellKnownValue;
3559 wkh_3_ValueWithLength;
3560 off = val_start + val_len_len;
3561 val = tvb_get_guint8(tvb, off);
3562 if (val == 0x80) { /* Byte-range */
3563 ti = proto_tree_add_string(tree, hf_hdr_range,
3564 tvb, hdr_start, offset - hdr_start, "byte-range");
3565 subtree = proto_item_add_subtree(ti, ett_header);
3566 /* Get the First-byte-pos (Uintvar-integer) */
3567 get_uintvar_integer (val, tvb, off, len, ok);
3569 val_str = g_strdup_printf("; first-byte-pos=%u", val);
3570 proto_item_append_string(ti, val_str);
3571 proto_tree_add_uint(subtree, hf_hdr_range_first_byte_pos,
3572 tvb, off, len, val);
3575 /* Get the optional Last-byte-pos (Uintvar-integer) */
3577 get_uintvar_integer (val, tvb, off, len, ok);
3579 val_str = g_strdup_printf("; last-byte-pos=%u", val);
3580 proto_item_append_string(ti, val_str);
3581 proto_tree_add_uint(subtree,
3582 hf_hdr_range_last_byte_pos,
3583 tvb, off, len, val);
3588 } else if (val == 0x81) { /* Suffix-byte-range */
3589 ti = proto_tree_add_string(tree, hf_hdr_range,
3590 tvb, hdr_start, offset - hdr_start, "suffix-byte-range");
3591 subtree = proto_item_add_subtree(ti, ett_header);
3592 /* Get the Suffix-length (Uintvar-integer) */
3593 get_uintvar_integer (val, tvb, off, len, ok);
3595 val_str = g_strdup_printf("; suffix-length=%u", val);
3596 proto_item_append_string(ti, val_str);
3597 proto_tree_add_uint(subtree, hf_hdr_range_suffix_length,
3598 tvb, off, len, val);
3603 wkh_4_End(hf_hdr_range);
3609 * | Value-length (0x82--0x86 | Token-text) [ Q-token Q-value ]
3611 static guint32 wkh_te (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3614 guint32 off, val, len;
3616 wkh_1_WellKnownValue;
3617 if (val_id == 0x81) {
3618 proto_tree_add_string(tree, hf_hdr_encoding_version,
3619 tvb, hdr_start, offset - hdr_start, "trailers");
3624 wkh_3_ValueWithLength;
3625 off = val_start + val_len_len;
3626 val = tvb_get_guint8(tvb, off);
3627 if (val & 0x80) { /* Well-known-TE */
3628 val_str = match_strval((val & 0x7F), vals_well_known_te);
3630 ti = proto_tree_add_string(tree, hf_hdr_te,
3631 tvb, hdr_start, off - hdr_start, val_str);
3635 } else { /* TE in Token-text format */
3636 get_token_text(val_str, tvb, off, len, ok);
3637 ti = proto_tree_add_string(tree, hf_hdr_te,
3638 tvb, hdr_start, off - hdr_start, val_str);
3643 if ((ok) && (off < offset)) { /* Q-token Q-value */
3647 wkh_4_End(hf_hdr_te);
3651 /****************************************************************************
3652 * O p e n w a v e h e a d e r s
3653 ****************************************************************************/
3659 * Redefine the WellKnownValue parsing so Openwave header field names are used
3660 * are used instead of the default WSP header field names
3662 #undef wkh_1_WellKnownValue
3663 #define wkh_1_WellKnownValue /* Parse Well Known Value */ \
3664 proto_tree_add_string_hidden(tree, hf_hdr_name, \
3665 tvb, hdr_start, offset - hdr_start, \
3666 val_to_str (hdr_id, vals_openwave_field_names, \
3667 "<Unknown WSP header field 0x%02X>")); \
3668 if (val_id & 0x80) { /* Well-known value */ \
3670 /* Well-known value processing starts HERE \
3675 * Redefine the End parsing so Openwave header field names are used
3676 * instead of the default WSP field names
3679 #define wkh_4_End(hf) /* End of value parsing */ \
3682 /* Check for errors */ \
3684 if (ti) { /* Append to protocol tree item label */ \
3685 proto_item_append_text(ti, \
3686 "<Error: Invalid header value>"); \
3687 } else if (hf > 0) { /* Create protocol tree item */ \
3688 proto_tree_add_string(tree, hf, \
3689 tvb, hdr_start, offset - hdr_start, \
3690 " <Error: Invalid header value>"); \
3691 } else { /* Create anonymous header field entry */ \
3692 proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start, \
3693 "%s: <Error: Invalid header value>", \
3694 val_to_str (hdr_id, vals_openwave_field_names, \
3695 "<Unknown WSP header field 0x%02X>")); \
3701 /* Dissect the Openwave header value (generic) */
3703 wkh_openwave_default(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3707 ok = TRUE; /* Bypass error checking as we don't parse the values! */
3709 wkh_1_WellKnownValue;
3710 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
3711 "%s: (Undecoded well-known value 0x%02x)",
3712 val_to_str (hdr_id, vals_openwave_field_names,
3713 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F);
3715 ti = proto_tree_add_text(tree,tvb,hdr_start, offset - hdr_start,
3717 val_to_str (hdr_id, vals_openwave_field_names,
3718 "<Unknown WSP header field 0x%02X>"), val_str);
3719 wkh_3_ValueWithLength;
3720 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
3721 "%s: (Undecoded value in general form with length indicator)",
3722 val_to_str (hdr_id, vals_openwave_field_names,
3723 "<Unknown WSP header field 0x%02X>"));
3725 wkh_4_End(HF_EMPTY); /* See wkh_default for explanation */
3729 /* Textual Openwave headers */
3730 wkh_text_header(openwave_x_up_proxy_operator_domain,
3731 "x-up-proxy-operator-domain");
3732 wkh_text_header(openwave_x_up_proxy_home_page,
3733 "x-up-proxy-home-page");
3734 wkh_text_header(openwave_x_up_proxy_uplink_version,
3735 "x-up-proxy-uplink-version");
3736 wkh_text_header(openwave_x_up_proxy_ba_realm,
3737 "x-up-proxy-ba-realm");
3738 wkh_text_header(openwave_x_up_proxy_request_uri,
3739 "x-up-proxy-request-uri");
3740 wkh_text_header(openwave_x_up_proxy_bookmark,
3741 "x-up-proxy-bookmark");
3743 /* Integer Openwave headers */
3744 wkh_integer_value_header(openwave_x_up_proxy_push_seq,
3745 "x-up-proxy-push-seq")
3746 wkh_integer_value_header(openwave_x_up_proxy_notify,
3747 "x-up-proxy-notify")
3748 wkh_integer_value_header(openwave_x_up_proxy_net_ask,
3749 "x-up-proxy-net-ask")
3750 wkh_integer_value_header(openwave_x_up_proxy_ba_enable,
3751 "x-up-proxy-ba-enable")
3752 wkh_integer_value_header(openwave_x_up_proxy_redirect_enable,
3753 "x-up-proxy-redirect-enable")
3754 wkh_integer_value_header(openwave_x_up_proxy_redirect_status,
3755 "x-up-proxy-redirect-status")
3756 wkh_integer_value_header(openwave_x_up_proxy_linger,
3757 "x-up-proxy-linger")
3758 wkh_integer_value_header(openwave_x_up_proxy_enable_trust,
3759 "x-up-proxy-enable-trust")
3760 wkh_integer_value_header(openwave_x_up_proxy_trust,
3763 wkh_integer_value_header(openwave_x_up_devcap_has_color,
3764 "x-up-devcap-has-color")
3765 wkh_integer_value_header(openwave_x_up_devcap_num_softkeys,
3766 "x-up-devcap-num-softkeys")
3767 wkh_integer_value_header(openwave_x_up_devcap_softkey_size,
3768 "x-up-devcap-softkey-size")
3769 wkh_integer_value_header(openwave_x_up_devcap_screen_chars,
3770 "x-up-devcap-screen-chars")
3771 wkh_integer_value_header(openwave_x_up_devcap_screen_pixels,
3772 "x-up-devcap-screen-pixels")
3773 wkh_integer_value_header(openwave_x_up_devcap_em_size,
3774 "x-up-devcap-em-size")
3775 wkh_integer_value_header(openwave_x_up_devcap_screen_depth,
3776 "x-up-devcap-screen-depth")
3777 wkh_integer_value_header(openwave_x_up_devcap_immed_alert,
3778 "x-up-devcap-immed_alert")
3779 wkh_integer_value_header(openwave_x_up_devcap_gui,
3782 /* Openwave Time-Of-Day value header */
3783 wkh_tod_value_header(openwave_x_up_proxy_tod,
3786 /* Openwave accept_x_q header */
3787 wkh_accept_x_q_header(openwave_x_up_proxy_trans_charset,
3788 "x-up-proxy-trans-charset",
3789 vals_character_sets, "character set")
3791 /* Openwave content type header */
3792 wkh_content_type_header(openwave_x_up_proxy_push_accept,
3793 "x-up-proxy-push-accept")
3796 * Header value parameter parsing
3798 #define InvalidParameterValue(parameter,value) \
3799 "<Error: Invalid " parameter " parameter value: invalid " value ">"
3805 #define parameter_text(hf,lowercase,Uppercase,value) \
3806 get_text_string(val_str, tvb, offset, val_len, ok); \
3808 proto_tree_add_string(tree, hf, \
3809 tvb, start, type_len + val_len, val_str); \
3810 str = g_strdup_printf("; " lowercase "=%s", val_str); \
3811 proto_item_append_string(ti, str); \
3814 offset += val_len; \
3816 proto_tree_add_string(tree, hf, tvb, start, len - start, \
3817 InvalidParameterValue(Uppercase, value)); \
3818 offset = start + len; /* Skip to end of buffer */ \
3821 #define parameter_text_value(hf,lowercase,Uppercase,value) \
3822 get_text_string(val_str, tvb, offset, val_len, ok); \
3824 if (is_quoted_string(val_str[0])) { \
3825 if (is_quoted_string(val_str[val_len-2])) { \
3826 /* Trailing quote - issue a warning */ \
3827 str = g_strdup_printf("%s" TrailingQuoteWarning, val_str); \
3828 proto_tree_add_string(tree, hf, \
3829 tvb, start, type_len + val_len, str); \
3831 str = g_strdup_printf("; " lowercase "=%s", val_str); \
3832 } else { /* OK (no trailing quote) */ \
3833 str = g_strdup_printf("%s\"", val_str); \
3834 proto_tree_add_string(tree, hf, \
3835 tvb, start, type_len + val_len, str); \
3837 str = g_strdup_printf("; " lowercase "=%s\"", val_str); \
3839 } else { /* Token-text | 0x00 */ \
3840 /* TODO - verify that we have either Token-text or 0x00 */ \
3841 proto_tree_add_string(tree, hf, \
3842 tvb, start, type_len + val_len, val_str); \
3843 str = g_strdup_printf("; " lowercase "=%s", val_str); \
3845 proto_item_append_string(ti, str); \
3848 offset += val_len; \
3850 proto_tree_add_string(tree, hf, tvb, start, len - start, \
3851 InvalidParameterValue(Uppercase, value)); \
3852 offset = start + len; /* Skip to end of buffer */ \
3856 /* Parameter = Untyped-parameter | Typed-parameter
3857 * Untyped-parameter = Token-text ( Integer-value | Text-value )
3860 * ( Integer-value | Date-value | Delta-seconds-value
3861 * | Q-value | Version-value | Uri-value )
3865 * Returns: next offset
3867 * TODO - Verify byte highlighting in case of invalid parameter values
3870 parameter (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start, int len)
3873 guint8 peek = tvb_get_guint8 (tvb,start);
3874 guint32 val = 0, type = 0, type_len, val_len;
3876 gchar *val_str = NULL;
3880 if (is_token_text (peek)) {
3884 get_token_text (str,tvb,start,val_len,ok); /* Should always succeed */
3885 if (ok) { /* Found a textual parameter name: str */
3887 get_text_value(val_str, tvb, offset, val_len, ok);
3888 if (ok) { /* Also found a textual parameter value: val_str */
3890 if (is_quoted_string(val_str[0])) { /* Add trailing quote! */
3891 if (is_quoted_string(val_str[val_len-2])) {
3892 /* Trailing quote - issue a warning */
3893 proto_tree_add_text(tree, tvb, start, offset - start,
3894 "%s: %s" TrailingQuoteWarning, str, val_str);
3895 s = g_strdup_printf("; %s=%s", str, val_str);
3896 } else { /* OK (no trailing quote) */
3897 proto_tree_add_text(tree, tvb, start, offset - start,
3898 "%s: %s\"", str, val_str);
3899 s = g_strdup_printf("; %s=%s\"", str, val_str);
3901 } else { /* Token-text | 0x00 */
3902 /* TODO - verify that it is either Token-text or 0x00
3903 * and flag with warning if invalid */
3904 proto_tree_add_text(tree, tvb, start, offset - start,
3905 "%s: %s", str, val_str);
3906 s = g_strdup_printf("; %s=%s", str, val_str);
3908 /* TODO - check if we can insert a searchable field in the
3909 * protocol tree for the untyped parameter case */
3910 proto_item_append_string(ti, s);
3913 } else { /* Try integer value */
3914 get_integer_value (val,tvb,offset,val_len,ok);
3915 if (ok) { /* Also found a valid integer parameter value: val */
3917 proto_tree_add_text(tree, tvb, start, offset - start,
3918 "%s: %u", str, val);
3919 s = g_strdup_printf("; %s=%u", str, val);
3920 proto_item_append_string(ti, s);
3922 /* TODO - check if we can insert a searchable field in the
3923 * protocol tree for the untyped parameter case */
3924 } else { /* Error: neither token-text not Integer-value */
3925 proto_tree_add_text (tree, tvb, start, offset - start,
3926 "<Error: Invalid untyped parameter definition>");
3927 offset = start + len; /* Skip to end of buffer */
3935 * Else: Typed parameter
3937 get_integer_value (type,tvb,start,type_len,ok);
3939 proto_tree_add_text (tree, tvb, start, offset - start,
3940 "<Error: Invalid typed parameter definition>");
3941 return (start + len); /* Skip to end of buffer */
3944 /* Now offset points to the parameter value */
3946 case 0x01: /* WSP 1.1 encoding - Charset: Well-known-charset */
3947 get_integer_value(val, tvb, offset, val_len, ok);
3949 val_str = val_to_str(val, vals_character_sets,
3950 "<Unknown character set Identifier 0x%X>");
3951 proto_tree_add_string(tree, hf_parameter_charset,
3952 tvb, start, type_len + val_len, val_str);
3953 str = g_strdup_printf("; charset=%s", val_str);
3954 proto_item_append_string(ti, str);
3958 proto_tree_add_text (tree, tvb, start, offset,
3959 InvalidParameterValue("Charset", "Integer-value"));
3960 offset = start + len; /* Skip to end of buffer */
3964 case 0x03: /* WSP 1.1 encoding - Type: Integer-value */
3965 get_integer_value (val,tvb,offset,val_len,ok);
3967 proto_tree_add_uint (tree, hf_wsp_parameter_type,
3968 tvb, start, type_len + val_len, val);
3969 s = g_strdup_printf("; Type=%u", val);
3970 proto_item_append_string (ti, s);
3974 proto_tree_add_text (tree, tvb, start, offset,
3975 InvalidParameterValue("Type", "Integer-value"));
3976 offset = start + len; /* Skip to end of buffer */
3980 case 0x05: /* WSP 1.1 encoding - Name: Text-string */
3981 parameter_text(hf_wsp_parameter_name, "name",
3982 "Name (WSP 1.1 encoding)", "Text-string");
3984 case 0x17: /* WSP 1.4 encoding - Name: Text-value */
3985 parameter_text_value(hf_wsp_parameter_name, "name",
3986 "Name (WSP 1.4 encoding)", "Text-value");
3989 case 0x06: /* WSP 1.1 encoding - Filename: Text-string */
3990 parameter_text(hf_wsp_parameter_filename, "filename",
3991 "Filename (WSP 1.1 encoding)", "Text-string");
3993 case 0x18: /* WSP 1.4 encoding - Filename: Text-value */
3994 parameter_text_value(hf_wsp_parameter_filename, "filename",
3995 "Filename (WSP 1.4 encoding)", "Text-value");
3998 case 0x09: /* WSP 1.2 encoding - Type (special): Constrained-encoding */
3999 /* This is similar to the Content-Type header decoding,
4000 * but it is much simpler:
4001 * Constrained-encoding = Short-integer | Extension-media
4002 * Extension-media = *TEXT <Octet 0>
4004 get_extension_media(val_str,tvb,offset,val_len,ok);
4005 if (ok) { /* Extension-media */
4008 get_short_integer(val,tvb,offset,val_len,ok);
4011 val_str = val_to_str(val, vals_content_types,
4012 "(Unknown content type identifier 0x%X)");
4013 } /* Else: invalid parameter value */
4016 proto_tree_add_string (tree, hf_wsp_parameter_upart_type,
4017 tvb, start, offset - start, val_str);
4018 str = g_strdup_printf("; type=%s", val_str);
4019 proto_item_append_string(ti, str);
4021 } else { /* Invalid parameter value */
4022 proto_tree_add_text (tree, tvb, start, len - start,
4023 InvalidParameterValue("Type",
4024 "Constrained-encoding"));
4025 offset = start + len; /* Skip the parameters */
4029 case 0x0A: /* WSP 1.2 encoding - Start: Text-string */
4030 parameter_text(hf_wsp_parameter_start, "start",
4031 "Start (WSP 1.2 encoding)", "Text-string");
4033 case 0x19: /* WSP 1.4 encoding - Start (with multipart/related): Text-value */
4034 parameter_text_value(hf_wsp_parameter_start, "start",
4035 "Start (WSP 1.4 encoding)", "Text-value");
4038 case 0x0B: /* WSP 1.2 encoding - Start-info: Text-string */
4039 parameter_text(hf_wsp_parameter_start_info, "start-info",
4040 "Start-info (WSP 1.2 encoding)", "Text-string");
4042 case 0x1A: /* WSP 1.4 encoding - Start-info (with multipart/related): Text-value */
4043 parameter_text_value(hf_wsp_parameter_start_info, "start-info",
4044 "Start-info (WSP 1.4 encoding)", "Text-value");
4047 case 0x0C: /* WSP 1.3 encoding - Comment: Text-string */
4048 parameter_text(hf_wsp_parameter_comment, "comment",
4049 "Comment (WSP 1.3 encoding)", "Text-string");
4051 case 0x1B: /* WSP 1.4 encoding - Comment: Text-value */
4052 parameter_text_value(hf_wsp_parameter_comment, "comment",
4053 "Comment (WSP 1.4 encoding)", "Text-value");
4056 case 0x0D: /* WSP 1.3 encoding - Domain: Text-string */
4057 parameter_text(hf_wsp_parameter_domain, "domain",
4058 "Domain (WSP 1.3 encoding)", "Text-string");
4060 case 0x1C: /* WSP 1.4 encoding - Domain: Text-value */
4061 parameter_text_value(hf_wsp_parameter_domain, "domain",
4062 "Domain (WSP 1.4 encoding)", "Text-value");
4065 case 0x0F: /* WSP 1.3 encoding - Path: Text-string */
4066 parameter_text(hf_wsp_parameter_path, "path",
4067 "Path (WSP 1.3 encoding)", "Text-string");
4069 case 0x1D: /* WSP 1.4 encoding - Path: Text-value */
4070 parameter_text_value(hf_wsp_parameter_path, "path",
4071 "Path (WSP 1.4 encoding)", "Text-value");
4074 case 0x11: /* WSP 1.4 encoding - SEC: Short-integer (OCTET) */
4075 peek = tvb_get_guint8 (tvb, start+1);
4076 if (peek & 0x80) { /* Valid Short-integer */
4078 proto_tree_add_uint (tree, hf_wsp_parameter_sec,
4079 tvb, start, 2, peek);
4080 str = match_strval(peek, vals_wsp_parameter_sec);
4081 proto_item_append_text (ti, "; SEC=%s", str);
4083 } else { /* Error */
4084 proto_tree_add_text (tree, tvb, start, len - start,
4085 InvalidParameterValue("SEC", "Short-integer"));
4086 offset = start + len; /* Skip to end of buffer */
4090 case 0x12: /* WSP 1.4 encoding - MAC: Text-value */
4091 parameter_text_value(hf_wsp_parameter_mac, "MAC",
4092 "MAC", "Text-value");
4095 case 0x02: /* WSP 1.1 encoding - Level: Version-value */
4096 get_version_value(val,str,tvb,offset,val_len,ok);
4098 proto_tree_add_string (tree, hf_wsp_parameter_level,
4099 tvb, start, type_len + val_len, str);
4100 proto_item_append_text (ti, "; level=%s", str);
4103 proto_tree_add_text (tree, tvb, start, len - start,
4104 InvalidParameterValue("Level", "Version-value"));
4105 offset = start + len; /* Skip to end of buffer */
4109 case 0x00: /* WSP 1.1 encoding - Q: Q-value */
4110 offset = parameter_value_q(tree, ti, tvb, offset);
4113 case 0x07: /* WSP 1.1 encoding - Differences: Field-name */
4114 case 0x08: /* WSP 1.1 encoding - Padding: Short-integer */
4115 case 0x0E: /* WSP 1.3 encoding - Max-Age: Delta-seconds-value */
4116 case 0x10: /* WSP 1.3 encoding - Secure: No-value */
4117 case 0x13: /* WSP 1.4 encoding - Creation-date: Date-value */
4118 case 0x14: /* WSP 1.4 encoding - Modification-date: Date-value */
4119 case 0x15: /* WSP 1.4 encoding - Read-date: Date-value */
4120 case 0x16: /* WSP 1.4 encoding - Size: Integer-value */
4122 proto_tree_add_text(tree, tvb, start, len - start,
4123 "Undecoded parameter type 0x%02x - decoding stopped",
4125 offset = start + len; /* Skip the parameters */
4133 * Dissects the Q-value parameter value.
4135 * Returns: next offset
4138 parameter_value_q (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start)
4141 guint32 val = 0, val_len;
4145 get_uintvar_integer (val, tvb, offset, val_len, ok);
4146 if (ok && (val < 1100)) {
4147 if (val <= 100) { /* Q-value in 0.01 steps */
4148 str = g_strdup_printf("0.%02u", val - 1);
4149 } else { /* Q-value in 0.001 steps */
4150 str = g_strdup_printf("0.%03u", val - 100);
4152 proto_item_append_text (ti, "; q=%s", str);
4153 proto_tree_add_string (tree, hf_parameter_q,
4154 tvb, start, val_len, str);
4158 proto_tree_add_text (tree, tvb, start, offset,
4159 InvalidParameterValue("Q", "Q-value"));
4166 /* Code to actually dissect the packets */
4173 dissect_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo,
4174 proto_tree *tree, dissector_handle_t dissector_handle)
4178 proto_tree *flags_tree;
4180 guint8 address_flags_len;
4182 proto_tree *atf_tree;
4184 guint32 address_ipv4;
4185 struct e_in6_addr address_ipv6;
4186 address redir_address;
4187 conversation_t *conv;
4189 flags = tvb_get_guint8 (tvb, offset);
4191 ti = proto_tree_add_uint (tree, hf_wsp_redirect_flags,
4192 tvb, offset, 1, flags);
4193 flags_tree = proto_item_add_subtree (ti, ett_redirect_flags);
4194 proto_tree_add_boolean (flags_tree, hf_wsp_redirect_permanent,
4195 tvb, offset, 1, flags);
4196 proto_tree_add_boolean (flags_tree, hf_wsp_redirect_reuse_security_session,
4197 tvb, offset, 1, flags);
4200 while (tvb_reported_length_remaining (tvb, offset) > 0) {
4201 address_flags_len = tvb_get_guint8 (tvb, offset);
4203 ti = proto_tree_add_uint (tree, hf_wsp_redirect_afl,
4204 tvb, offset, 1, address_flags_len);
4205 atf_tree = proto_item_add_subtree (ti, ett_redirect_afl);
4206 proto_tree_add_boolean (atf_tree, hf_wsp_redirect_afl_bearer_type_included,
4207 tvb, offset, 1, address_flags_len);
4208 proto_tree_add_boolean (atf_tree, hf_wsp_redirect_afl_port_number_included,
4209 tvb, offset, 1, address_flags_len);
4210 proto_tree_add_uint (atf_tree, hf_wsp_redirect_afl_address_len,
4211 tvb, offset, 1, address_flags_len);
4214 if (address_flags_len & BEARER_TYPE_INCLUDED) {
4215 bearer_type = tvb_get_guint8 (tvb, offset);
4217 proto_tree_add_uint (tree, hf_wsp_redirect_bearer_type,
4218 tvb, offset, 1, bearer_type);
4222 bearer_type = 0x00; /* XXX */
4223 if (address_flags_len & PORT_NUMBER_INCLUDED) {
4224 port_num = tvb_get_ntohs (tvb, offset);
4226 proto_tree_add_uint (tree, hf_wsp_redirect_port_num,
4227 tvb, offset, 2, port_num);
4232 * Redirecting to the same server port number as was
4233 * being used, i.e. the source port number of this
4236 port_num = pinfo->srcport;
4238 address_len = address_flags_len & ADDRESS_LEN;
4239 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
4241 * We don't have the bearer type in the message,
4242 * so we don't know the address type.
4243 * (It's the same bearer type as the original
4246 goto unknown_address_type;
4250 * We know the bearer type, so we know the address type.
4252 switch (bearer_type) {
4256 case BT_IS_95_PACKET_DATA:
4257 case BT_ANSI_136_CSD:
4258 case BT_ANSI_136_PACKET_DATA:
4261 case BT_GSM_USSD_IPv4:
4264 case BT_PDC_PACKET_DATA:
4266 case BT_IDEN_PACKET_DATA:
4268 case BT_TETRA_PACKET_DATA:
4272 if (address_len != 4) {
4276 goto unknown_address_type;
4278 tvb_memcpy(tvb, (guint8 *)&address_ipv4, offset, 4);
4280 proto_tree_add_ipv4 (tree,
4281 hf_wsp_redirect_ipv4_addr,
4282 tvb, offset, 4, address_ipv4);
4286 * Create a conversation so that the
4287 * redirected session will be dissected
4290 redir_address.type = AT_IPv4;
4291 redir_address.len = 4;
4292 redir_address.data = (const guint8 *)&address_ipv4;
4293 conv = find_conversation(&redir_address, &pinfo->dst,
4294 PT_UDP, port_num, 0, NO_PORT_B);
4296 conv = conversation_new(&redir_address,
4297 &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
4299 conversation_set_dissector(conv, dissector_handle);
4306 if (address_len != 16) {
4310 goto unknown_address_type;
4312 tvb_memcpy(tvb, (guint8 *)&address_ipv6, offset, 16);
4314 proto_tree_add_ipv6 (tree,
4315 hf_wsp_redirect_ipv6_addr,
4316 tvb, offset, 16, (guint8 *)&address_ipv6);
4320 * Create a conversation so that the
4321 * redirected session will be dissected
4324 redir_address.type = AT_IPv6;
4325 redir_address.len = 16;
4326 redir_address.data = (const guint8 *)&address_ipv4;
4327 conv = find_conversation(&redir_address, &pinfo->dst,
4328 PT_UDP, port_num, 0, NO_PORT_B);
4330 conv = conversation_new(&redir_address,
4331 &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
4333 conversation_set_dissector(conv, dissector_handle);
4336 unknown_address_type:
4338 if (address_len != 0) {
4340 proto_tree_add_item (tree,
4341 hf_wsp_redirect_addr,
4342 tvb, offset, address_len,
4348 offset += address_len;
4353 dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4354 dissector_handle_t dissector_handle, gboolean is_connectionless)
4359 guint8 reply_status;
4362 guint uriLength = 0;
4364 guint capabilityLength = 0;
4365 guint capabilityStart = 0;
4366 guint headersLength = 0;
4367 guint headerLength = 0;
4368 guint headerStart = 0;
4369 guint nextOffset = 0;
4370 guint contentTypeStart = 0;
4371 guint contentType = 0;
4372 const char *contentTypeStr;
4374 gboolean found_match;
4376 /* Set up structures we will need to add the protocol subtree and manage it */
4378 proto_tree *wsp_tree = NULL;
4380 wsp_info_value_t *stat_info;
4381 stat_info = g_malloc( sizeof(wsp_info_value_t) );
4382 stat_info->status_code = 0;
4384 /* This field shows up as the "Info" column in the display; you should make
4385 it, if possible, summarize what's in the packet, so that a user looking
4386 at the list of packets can tell what type of packet it is. */
4388 /* Connection-less mode has a TID first */
4389 if (is_connectionless)
4391 offset++; /* Skip the 1-byte Transaction ID */
4394 /* Find the PDU type */
4395 pdut = tvb_get_guint8 (tvb, offset);
4397 /* Develop the string to put in the Info column */
4398 if (check_col(pinfo->cinfo, COL_INFO))
4400 col_append_fstr(pinfo->cinfo, COL_INFO, "WSP %s",
4401 val_to_str (pdut, vals_pdu_type, "Unknown PDU type (0x%02x)"));
4404 /* In the interest of speed, if "tree" is NULL, don't do any work not
4405 * necessary to generate protocol tree items. */
4407 ti = proto_tree_add_item(tree, proto_wsp,
4408 tvb, 0, -1, bo_little_endian);
4409 wsp_tree = proto_item_add_subtree(ti, ett_wsp);
4411 /* Add common items: only TID and PDU Type */
4413 /* If this is connectionless, then the TID Field is always first */
4414 if (is_connectionless)
4416 ti = proto_tree_add_item (wsp_tree, hf_wsp_header_tid,
4417 tvb, 0, 1, bo_little_endian);
4419 ti = proto_tree_add_item( wsp_tree, hf_wsp_header_pdu_type,
4420 tvb, offset, 1, bo_little_endian);
4424 /* Map extended methods to the main method now the Column info has been
4425 * written; this way we can dissect the extended method PDUs. */
4426 if ((pdut >= 0x50) && (pdut <= 0x5F)) /* Extended GET --> GET */
4428 else if ((pdut >= 0x70) && (pdut <= 0x7F)) /* Extended POST --> POST */
4429 pdut = WSP_PDU_POST;
4433 case WSP_PDU_CONNECT:
4434 case WSP_PDU_CONNECTREPLY:
4435 case WSP_PDU_RESUME:
4437 if (pdut == WSP_PDU_CONNECT)
4439 ti = proto_tree_add_item (wsp_tree, hf_wsp_version_major,
4440 tvb, offset, 1, bo_little_endian);
4441 ti = proto_tree_add_item (wsp_tree, hf_wsp_version_minor,
4442 tvb, offset, 1, bo_little_endian);
4445 count = 0; /* Initialise count */
4446 value = tvb_get_guintvar (tvb, offset, &count);
4447 ti = proto_tree_add_uint (wsp_tree,
4448 hf_wsp_server_session_id,
4449 tvb, offset, count, value);
4452 capabilityStart = offset;
4453 count = 0; /* Initialise count */
4454 capabilityLength = tvb_get_guintvar (tvb, offset, &count);
4456 ti = proto_tree_add_uint (wsp_tree, hf_wsp_capability_length,
4457 tvb, capabilityStart, count, capabilityLength);
4459 if (pdut != WSP_PDU_RESUME)
4461 count = 0; /* Initialise count */
4462 headerLength = tvb_get_guintvar (tvb, offset, &count);
4463 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4464 tvb, offset, count, headerLength);
4466 capabilityStart = offset;
4467 headerStart = capabilityStart + capabilityLength;
4469 /* Resume computes the headerlength
4470 * by remaining bytes */
4471 capabilityStart = offset;
4472 headerStart = capabilityStart + capabilityLength;
4473 headerLength = tvb_reported_length_remaining (tvb,
4476 if (capabilityLength > 0)
4478 tmp_tvb = tvb_new_subset (tvb, offset,
4479 capabilityLength, capabilityLength);
4480 add_capabilities (wsp_tree, tmp_tvb, pdut);
4481 offset += capabilityLength;
4484 if (headerLength > 0)
4486 tmp_tvb = tvb_new_subset (tvb, offset,
4487 headerLength, headerLength);
4488 add_headers (wsp_tree, tmp_tvb);
4494 case WSP_PDU_REDIRECT:
4495 dissect_redirect(tvb, offset, pinfo, wsp_tree, dissector_handle);
4498 case WSP_PDU_DISCONNECT:
4499 case WSP_PDU_SUSPEND:
4501 count = 0; /* Initialise count */
4502 value = tvb_get_guintvar (tvb, offset, &count);
4503 ti = proto_tree_add_uint (wsp_tree,
4504 hf_wsp_server_session_id,
4505 tvb, offset, count, value);
4510 count = 0; /* Initialise count */
4511 /* Length of URI and size of URILen field */
4512 value = tvb_get_guintvar (tvb, offset, &count);
4513 nextOffset = offset + count;
4514 add_uri (wsp_tree, pinfo, tvb, offset, nextOffset);
4516 offset += value + count; /* VERIFY */
4517 tmp_tvb = tvb_new_subset (tvb, offset, -1, -1);
4518 add_headers (wsp_tree, tmp_tvb);
4524 count = 0; /* Initialise count */
4525 uriLength = tvb_get_guintvar (tvb, offset, &count);
4526 headerStart = uriStart+count;
4527 count = 0; /* Initialise count */
4528 headersLength = tvb_get_guintvar (tvb, headerStart, &count);
4529 offset = headerStart + count;
4531 add_uri (wsp_tree, pinfo, tvb, uriStart, offset);
4532 offset += uriLength;
4535 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4536 tvb, headerStart, count, headersLength);
4538 if (headersLength == 0)
4541 contentTypeStart = offset;
4542 nextOffset = add_content_type (wsp_tree,
4543 tvb, offset, &contentType, &contentTypeStr);
4546 /* Add headers subtree that will hold the headers fields */
4547 /* Runs from nextOffset for
4548 * headersLength - (length of content-type field) */
4549 headerLength = headersLength - (nextOffset - contentTypeStart);
4550 if (headerLength > 0)
4552 tmp_tvb = tvb_new_subset (tvb, nextOffset,
4553 headerLength, headerLength);
4554 add_headers (wsp_tree, tmp_tvb);
4556 offset = nextOffset+headerLength;
4558 /* WSP_PDU_POST data - First check whether a subdissector exists
4559 * for the content type */
4560 if (tvb_reported_length_remaining(tvb,
4561 headerStart + count + uriLength + headersLength) > 0)
4563 tmp_tvb = tvb_new_subset (tvb,
4564 headerStart + count + uriLength + headersLength,
4567 * Try finding a dissector for the content
4568 * first, then fallback.
4570 if (contentTypeStr == NULL) {
4572 * Content type is numeric.
4574 found_match = dissector_try_port(wsp_dissector_table,
4575 contentType, tmp_tvb, pinfo, tree);
4578 * Content type is a string.
4580 found_match = dissector_try_string(wsp_dissector_table_text,
4581 contentTypeStr, tmp_tvb, pinfo, tree);
4583 if (! found_match) {
4584 if (! dissector_try_heuristic(heur_subdissector_list,
4585 tmp_tvb, pinfo, tree))
4586 if (tree) /* Only display if needed */
4587 add_post_data (wsp_tree, tmp_tvb,
4588 contentType, contentTypeStr);
4594 count = 0; /* Initialise count */
4595 headersLength = tvb_get_guintvar (tvb, offset+1, &count);
4596 headerStart = offset + count + 1;
4597 reply_status = tvb_get_guint8(tvb, offset);
4599 ti = proto_tree_add_item (wsp_tree, hf_wsp_header_status,
4600 tvb, offset, 1, bo_little_endian);
4601 stat_info->status_code = (gint) tvb_get_guint8(tvb, offset);
4602 if (check_col(pinfo->cinfo, COL_INFO))
4603 { /* Append status code to INFO column */
4604 col_append_fstr(pinfo->cinfo, COL_INFO,
4605 ": \"0x%02x %s\"", reply_status,
4606 val_to_str (reply_status, vals_status,
4607 "Unknown response status (0x%02x)"));
4609 nextOffset = offset + 1 + count;
4611 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4612 tvb, offset + 1, count, headersLength);
4614 if (headersLength == 0)
4617 contentTypeStart = nextOffset;
4618 nextOffset = add_content_type (wsp_tree, tvb,
4619 nextOffset, &contentType, &contentTypeStr);
4622 /* Add headers subtree that will hold the headers fields */
4623 /* Runs from nextOffset for
4624 * headersLength - (length of content-type field) */
4625 headerLength = headersLength - (nextOffset - contentTypeStart);
4626 if (headerLength > 0)
4628 tmp_tvb = tvb_new_subset (tvb, nextOffset,
4629 headerLength, headerLength);
4630 add_headers (wsp_tree, tmp_tvb);
4632 offset += count+headersLength+1;
4634 /* WSP_PDU_REPLY data - First check whether a subdissector exists
4635 * for the content type */
4636 if (tvb_reported_length_remaining(tvb, headerStart + headersLength)
4639 tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength,
4642 * Try finding a dissector for the content
4643 * first, then fallback.
4645 if (contentTypeStr == NULL) {
4647 * Content type is numeric.
4649 found_match = dissector_try_port(wsp_dissector_table,
4650 contentType, tmp_tvb, pinfo, tree);
4653 * Content type is a string.
4655 found_match = dissector_try_string(wsp_dissector_table_text,
4656 contentTypeStr, tmp_tvb, pinfo, tree);
4658 if (! found_match) {
4659 if (! dissector_try_heuristic(heur_subdissector_list,
4660 tmp_tvb, pinfo, tree))
4661 if (tree) /* Only display if needed */
4662 ti = proto_tree_add_item (wsp_tree,
4664 tmp_tvb, 0, -1, bo_little_endian);
4670 case WSP_PDU_CONFIRMEDPUSH:
4671 count = 0; /* Initialise count */
4672 headersLength = tvb_get_guintvar (tvb, offset, &count);
4673 headerStart = offset + count;
4676 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4677 tvb, offset, count, headersLength);
4679 if (headersLength == 0)
4683 contentTypeStart = offset;
4684 nextOffset = add_content_type (wsp_tree,
4685 tvb, offset, &contentType, &contentTypeStr);
4688 /* Add headers subtree that will hold the headers fields */
4689 /* Runs from nextOffset for
4690 * headersLength-(length of content-type field) */
4691 headerLength = headersLength-(nextOffset-contentTypeStart);
4692 if (headerLength > 0)
4694 tmp_tvb = tvb_new_subset (tvb, nextOffset,
4695 headerLength, headerLength);
4696 add_headers (wsp_tree, tmp_tvb);
4698 offset += headersLength;
4700 /* WSP_PDU_PUSH data - First check whether a subdissector exists
4701 * for the content type */
4702 if (tvb_reported_length_remaining(tvb, headerStart + headersLength)
4705 tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength,
4708 * Try finding a dissector for the content
4709 * first, then fallback.
4711 if (contentTypeStr == NULL) {
4713 * Content type is numeric.
4715 found_match = dissector_try_port(wsp_dissector_table,
4716 contentType, tmp_tvb, pinfo, tree);
4719 * Content type is a string.
4721 found_match = dissector_try_string(wsp_dissector_table_text,
4722 contentTypeStr, tmp_tvb, pinfo, tree);
4724 if (! found_match) {
4725 if (! dissector_try_heuristic(heur_subdissector_list,
4726 tmp_tvb, pinfo, tree))
4727 if (tree) /* Only display if needed */
4728 ti = proto_tree_add_item (wsp_tree,
4730 tmp_tvb, 0, -1, bo_little_endian);
4736 stat_info->pdut = pdut;
4737 tap_queue_packet (wsp_tap, pinfo, stat_info);
4742 * Called directly from UDP.
4743 * Put "WSP" into the "Protocol" column.
4746 dissect_wsp_fromudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4748 if (check_col(pinfo->cinfo, COL_PROTOCOL))
4749 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSP" );
4750 if (check_col(pinfo->cinfo, COL_INFO))
4751 col_clear(pinfo->cinfo, COL_INFO);
4753 dissect_wsp_common(tvb, pinfo, tree, wsp_fromudp_handle, TRUE);
4758 * Called from a higher-level WAP dissector, in connection-oriented mode.
4759 * Leave the "Protocol" column alone - the dissector calling us should
4763 dissect_wsp_fromwap_co(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4766 * XXX - what about WTLS->WTP->WSP?
4768 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, FALSE);
4773 * Called from a higher-level WAP dissector, in connectionless mode.
4774 * Leave the "Protocol" column alone - the dissector calling us should
4778 dissect_wsp_fromwap_cl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4781 * XXX - what about WTLS->WSP?
4783 if (check_col(pinfo->cinfo, COL_INFO))
4785 col_clear(pinfo->cinfo, COL_INFO);
4787 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, TRUE);
4792 add_uri (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
4793 guint URILenOffset, guint URIOffset)
4798 guint uriLen = tvb_get_guintvar (tvb, URILenOffset, &count);
4801 ti = proto_tree_add_uint (tree, hf_wsp_header_uri_len,
4802 tvb, URILenOffset, count, uriLen);
4804 tvb_ensure_bytes_exist(tvb, URIOffset, uriLen);
4806 ti = proto_tree_add_item (tree, hf_wsp_header_uri,
4807 tvb, URIOffset, uriLen, bo_little_endian);
4808 if (check_col(pinfo->cinfo, COL_INFO)) {
4809 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
4810 tvb_format_text (tvb, URIOffset, uriLen));
4816 * CO-WSP capability negotiation
4819 add_capabilities (proto_tree *tree, tvbuff_t *tvb, int type)
4822 proto_tree *wsp_capabilities;
4824 guint offsetStr = 0;
4825 guint capabilitiesLen = tvb_reported_length (tvb);
4826 guint capabilitiesStart = 0;
4832 char valString[VAL_STRING_SIZE];
4835 fprintf (stderr, "dissect_wsp: Offset is %d, size is %d\n", offset, capabilitiesLen);
4839 if (capabilitiesLen <= 0)
4842 fprintf (stderr, "dissect_wsp: Capabilities = 0\n");
4848 fprintf (stderr, "dissect_wsp: capabilities to process\n");
4851 ti = proto_tree_add_item (tree, hf_wsp_capabilities_section,tvb,offset,capabilitiesLen,bo_little_endian);
4852 wsp_capabilities = proto_item_add_subtree( ti, ett_capabilities );
4856 while (offset < capabilitiesLen)
4858 /* Loop round each header */
4859 capabilitiesStart = offset;
4860 length = tvb_get_guint8 (tvb, capabilitiesStart);
4862 if (length >= 127) /* length */
4865 fprintf (stderr, "dissect_wsp: capabilities length invalid %d\n",length);
4871 peek = tvb_get_guint8 (tvb, offset);
4873 switch (peek & 0x7f)
4875 case 0x00 : /* Client-SDU-Size */
4876 value = get_uintvar (tvb, offset, length+capabilitiesStart+1);
4877 proto_tree_add_uint (wsp_capabilities, hf_wsp_capabilities_client_SDU, tvb, capabilitiesStart, length+1, value);
4879 case 0x01 : /* Server-SDU-Size */
4880 value = get_uintvar (tvb, offset, length+capabilitiesStart+1);
4881 proto_tree_add_uint (wsp_capabilities, hf_wsp_capabilities_server_SDU, tvb, capabilitiesStart, length+1, value);
4883 case 0x02 : /* Protocol Options */
4884 value = get_uintvar (tvb, offset, length+capabilitiesStart+1);
4889 ret = snprintf(valString+i,VAL_STRING_SIZE-i,"%s","(Confirmed push facility) ");
4890 if (ret == -1 || (unsigned int) ret >= VAL_STRING_SIZE-i) {
4892 * We've been truncated
4904 ret = snprintf(valString+i,VAL_STRING_SIZE-i,"%s","(Push facility) ");
4905 if (ret == -1 || (unsigned int) ret >= VAL_STRING_SIZE-i) {
4907 * We've been truncated
4919 ret = snprintf(valString+i,VAL_STRING_SIZE-i,"%s","(Session resume facility) ");
4920 if (ret == -1 || (unsigned int) ret >= VAL_STRING_SIZE-i) {
4922 * We've been truncated
4930 if (i >= VAL_STRING_SIZE) {
4934 ret = snprintf(valString+i,VAL_STRING_SIZE-i,"%s","(Acknowledgement headers) ");
4935 if (ret == -1 || (unsigned int) ret >= VAL_STRING_SIZE-i) {
4937 * We've been truncated
4944 valString[VAL_STRING_SIZE-1] = '\0';
4945 proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_protocol_opt, tvb, capabilitiesStart, length+1, valString);
4947 case 0x03 : /* Method-MOR */
4948 value = tvb_get_guint8(tvb, offset);
4949 proto_tree_add_uint (wsp_capabilities, hf_wsp_capabilities_method_MOR, tvb, capabilitiesStart, length+1, value);
4951 case 0x04 : /* Push-MOR */
4952 value = tvb_get_guint8(tvb, offset);
4953 proto_tree_add_uint (wsp_capabilities, hf_wsp_capabilities_push_MOR, tvb, capabilitiesStart, length+1, value);
4956 case 0x05 : /* Extended Methods */
4959 add_capability_vals(tvb, (type == WSP_PDU_CONNECT),
4960 offsetStr, length, capabilitiesStart,
4961 valString, sizeof valString);
4962 proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_extended_methods, tvb, capabilitiesStart, length+1, valString);
4964 case 0x06 : /* Header Code Pages */
4967 add_capability_vals(tvb, (type == WSP_PDU_CONNECT),
4968 offsetStr, length, capabilitiesStart,
4969 valString, sizeof valString);
4970 proto_tree_add_string(wsp_capabilities, hf_wsp_capabilities_header_code_pages, tvb, capabilitiesStart, length+1, valString);
4972 case 0x07 : /* Aliases */
4975 proto_tree_add_text (wsp_capabilities, tvb , capabilitiesStart, length+1,
4976 "Undecoded Header (0x%02X)", peek & 0x7F);
4979 offset=capabilitiesStart+length+1;
4984 add_capability_vals(tvbuff_t *tvb, gboolean add_string, int offsetStr,
4985 guint length, guint capabilitiesStart, char *valString,
4986 size_t valStringSize)
4994 while ((offsetStr-capabilitiesStart) <= length)
4996 value = tvb_get_guint8(tvb, offsetStr);
4997 if (i >= valStringSize) {
5003 ret = snprintf(valString+i,valStringSize-i,
5004 "(0x%02x - ",value);
5008 ret = snprintf(valString+i,valStringSize-i,"(0x%02x) ",
5011 if (ret == -1 || (unsigned int) ret >= valStringSize-i) {
5013 * We've been truncated.
5021 for (;(c = tvb_get_guint8(tvb, offsetStr))
5022 && i < valStringSize - 1; i++,offsetStr++)
5025 if (i < valStringSize - 2) {
5026 valString[i++] = ')';
5027 valString[i++] = ' ';
5031 valString[i] = '\0';
5036 get_uintvar (tvbuff_t *tvb, guint offset, guint offsetEnd)
5043 octet = tvb_get_guint8 (tvb, offset);
5046 value += octet & 0x7f;
5048 while ((offsetEnd > offset) && (octet & 0x80));
5054 add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType,
5055 const char *contentTypeStr)
5058 guint variableStart = 0;
5059 guint variableEnd = 0;
5060 guint valueStart = 0;
5064 proto_tree *sub_tree;
5066 /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,bo_little_endian); */
5067 ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,bo_little_endian);
5068 sub_tree = proto_item_add_subtree(ti, ett_post);
5070 if ( (contentTypeStr == NULL && contentType == 0x12)
5071 || (contentTypeStr && (strcasecmp(contentTypeStr,
5072 "application/x-www-form-urlencoded") == 0)) )
5076 * Iterate through post data.
5078 for (offset = 0; offset < tvb_reported_length (tvb); offset++)
5080 peek = tvb_get_guint8 (tvb, offset);
5083 variableEnd = offset;
5084 valueStart = offset+1;
5086 else if (peek == '&')
5088 if (variableEnd > 0)
5090 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5092 variableStart = offset+1;
5099 /* See if there's outstanding data */
5100 if (variableEnd > 0)
5102 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5105 else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x24) ||
5106 (contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33))
5108 add_multipart_data(sub_tree, tvb);
5113 add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint variableEnd, guint valueStart, guint valueEnd)
5115 int variableLength = variableEnd-variableStart;
5116 int valueLength = 0;
5117 char *variableBuffer;
5120 variableBuffer = g_malloc (variableLength+1);
5121 strncpy (variableBuffer, tvb_get_ptr (tvb, variableStart, variableLength), variableLength);
5122 variableBuffer[variableLength] = 0;
5124 if (valueEnd < valueStart)
5126 valueBuffer = g_malloc (1);
5128 valueEnd = valueStart;
5132 valueLength = valueEnd-valueStart;
5133 valueBuffer = g_malloc (valueLength+1);
5134 strncpy (valueBuffer, tvb_get_ptr (tvb, valueStart, valueLength), valueLength);
5135 valueBuffer[valueLength] = 0;
5138 /* Check for variables with no value */
5139 if (valueStart >= tvb_reported_length (tvb))
5141 valueStart = tvb_reported_length (tvb);
5142 valueEnd = valueStart;
5144 valueLength = valueEnd-valueStart;
5146 proto_tree_add_text (tree, tvb, variableStart, valueEnd-variableStart, "%s: %s", variableBuffer, valueBuffer);
5148 g_free (variableBuffer);
5149 g_free (valueBuffer);
5153 add_multipart_data (proto_tree *tree, tvbuff_t *tvb)
5161 guint contentType = 0;
5162 const char *contentTypeStr;
5167 proto_item *sub_tree = NULL,
5169 proto_tree *mpart_tree;
5172 printf("DBG: public: add_multipart_data: (offset = %u, 0x%02x): ", offset, tvb_get_guint8(tvb,offset));
5174 nEntries = tvb_get_guintvar (tvb, offset, &count);
5176 printf("parts = %u\n", nEntries);
5181 sub_tree = proto_tree_add_text(tree, tvb, offset - count, 0,
5183 proto_item_add_subtree(sub_tree, ett_mpartlist);
5188 printf("DBG: add_multipart_data: Parts to do after this: %u"
5189 " (offset = %u, 0x%02x): ",
5190 nEntries, offset, tvb_get_guint8(tvb,offset));
5192 part_start = offset;
5193 HeadersLen = tvb_get_guintvar (tvb, offset, &count);
5195 DataLen = tvb_get_guintvar (tvb, offset, &count);
5197 ti = proto_tree_add_uint(sub_tree, hf_wsp_mpart, tvb, part_start,
5198 HeadersLen + DataLen + (offset - part_start), partnr);
5199 mpart_tree = proto_item_add_subtree(ti, ett_multiparts);
5200 nextOffset = add_content_type (mpart_tree, tvb, offset, &contentType, &contentTypeStr);
5201 HeadersLen -= (nextOffset - offset);
5204 tmp_tvb = tvb_new_subset (tvb, nextOffset, HeadersLen, HeadersLen);
5205 add_headers (mpart_tree, tmp_tvb);
5207 offset = nextOffset + HeadersLen;
5208 /* TODO - Try the dissectors of the multipart content */
5209 proto_tree_add_item (mpart_tree, hf_wsp_multipart_data, tvb, offset, DataLen, bo_little_endian);
5216 /* Register the protocol with Ethereal */
5218 proto_register_wsp(void)
5221 /* Setup list of header fields */
5222 static hf_register_info hf[] = {
5223 { &hf_wsp_header_tid,
5226 FT_UINT8, BASE_HEX, NULL, 0x00,
5227 "Transaction ID", HFILL
5230 { &hf_wsp_header_pdu_type,
5233 FT_UINT8, BASE_HEX, VALS( vals_pdu_type ), 0x00,
5237 { &hf_wsp_version_major,
5238 { "Version (Major)",
5239 "wsp.version.major",
5240 FT_UINT8, BASE_DEC, NULL, 0xF0,
5241 "Version (Major)", HFILL
5244 { &hf_wsp_version_minor,
5245 { "Version (Minor)",
5246 "wsp.version.minor",
5247 FT_UINT8, BASE_DEC, NULL, 0x0F,
5248 "Version (Minor)", HFILL
5251 { &hf_wsp_capability_length,
5252 { "Capability Length",
5253 "wsp.capability.length",
5254 FT_UINT32, BASE_DEC, NULL, 0x00,
5255 "Capability Length", HFILL
5258 { &hf_wsp_header_length,
5260 "wsp.headers_length",
5261 FT_UINT32, BASE_DEC, NULL, 0x00,
5262 "Headers Length", HFILL
5265 { &hf_wsp_capabilities_section,
5268 FT_NONE, BASE_DEC, NULL, 0x00,
5269 "Capabilities", HFILL
5272 { &hf_wsp_headers_section,
5275 FT_NONE, BASE_DEC, NULL, 0x00,
5281 "wsp.headers.header",
5282 FT_NONE, BASE_DEC, NULL, 0x00,
5286 { &hf_wsp_header_uri_len,
5289 FT_UINT32, BASE_DEC, NULL, 0x00,
5293 { &hf_wsp_header_uri,
5296 FT_STRING, BASE_NONE, NULL, 0x00,
5300 { &hf_wsp_server_session_id,
5301 { "Server Session ID",
5302 "wsp.server.session_id",
5303 FT_UINT32, BASE_DEC, NULL, 0x00,
5304 "Server Session ID", HFILL
5307 { &hf_wsp_header_status,
5310 FT_UINT8, BASE_HEX, VALS( vals_status ), 0x00,
5314 { &hf_wsp_content_type,
5316 "wsp.content_type.type",
5317 FT_UINT8, BASE_HEX, VALS ( vals_content_types ), 0x00,
5318 "Content Type", HFILL
5321 { &hf_wsp_content_type_str,
5323 "wsp.content_type.type.string",
5324 FT_STRING, BASE_NONE, NULL, 0x00,
5325 "Content Type", HFILL
5328 { &hf_wsp_parameter_well_known_charset,
5330 "wsp.parameter.charset",
5331 FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00,
5335 { &hf_wsp_parameter_type,
5337 "wsp.parameter.type",
5338 FT_UINT32, BASE_DEC, NULL, 0x00,
5342 { &hf_wsp_parameter_name,
5344 "wsp.parameter.name",
5345 FT_STRING, BASE_NONE, NULL, 0x00,
5349 { &hf_wsp_parameter_filename,
5351 "wsp.parameter.filename",
5352 FT_STRING, BASE_NONE, NULL, 0x00,
5356 { &hf_wsp_parameter_start,
5358 "wsp.parameter.start",
5359 FT_STRING, BASE_NONE, NULL, 0x00,
5363 { &hf_wsp_parameter_start_info,
5365 "wsp.parameter.start_info",
5366 FT_STRING, BASE_NONE, NULL, 0x00,
5370 { &hf_wsp_parameter_comment,
5372 "wsp.parameter.comment",
5373 FT_STRING, BASE_NONE, NULL, 0x00,
5377 { &hf_wsp_parameter_domain,
5379 "wsp.parameter.domain",
5380 FT_STRING, BASE_NONE, NULL, 0x00,
5384 { &hf_wsp_parameter_path,
5386 "wsp.parameter.path",
5387 FT_STRING, BASE_NONE, NULL, 0x00,
5391 { &hf_wsp_parameter_sec,
5393 "wsp.parameter.sec",
5394 FT_UINT8, BASE_HEX, VALS (vals_wsp_parameter_sec), 0x00,
5395 "SEC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
5398 { &hf_wsp_parameter_mac,
5400 "wsp.parameter.mac",
5401 FT_STRING, BASE_NONE, NULL, 0x00,
5402 "MAC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
5405 { &hf_wsp_parameter_upart_type,
5407 "wsp.parameter.upart.type",
5408 FT_STRING, BASE_NONE, NULL, 0x00,
5409 "Multipart type", HFILL
5412 { &hf_wsp_parameter_upart_type_value,
5414 "wsp.parameter.upart.type.int",
5415 FT_UINT8, BASE_DEC, NULL, 0x00,
5416 "Multipart type (int value)", HFILL
5419 { &hf_wsp_parameter_level,
5421 "wsp.parameter.level",
5422 FT_STRING, BASE_NONE, NULL, 0x00,
5423 "Level parameter", HFILL
5426 { &hf_wsp_reply_data,
5429 FT_NONE, BASE_NONE, NULL, 0x00,
5433 { &hf_wsp_header_shift_code,
5434 { "Switching to WSP header code-page",
5436 FT_UINT8, BASE_DEC, NULL, 0x00,
5437 "Header code-page shift code", HFILL
5441 * CO-WSP capability negotiation
5443 { &hf_wsp_capabilities_client_SDU,
5445 "wsp.capabilities.client_SDU",
5446 FT_UINT8, BASE_DEC, NULL, 0x00,
5450 { &hf_wsp_capabilities_server_SDU,
5452 "wsp.capabilities.server_SDU",
5453 FT_UINT8, BASE_DEC, NULL, 0x00,
5457 { &hf_wsp_capabilities_protocol_opt,
5458 { "Protocol Options",
5459 "wsp.capabilities.protocol_opt",
5460 FT_STRING, BASE_HEX, NULL, 0x00,
5461 "Protocol Options", HFILL
5464 { &hf_wsp_capabilities_method_MOR,
5466 "wsp.capabilities.method_mor",
5467 FT_UINT8, BASE_DEC, NULL, 0x00,
5471 { &hf_wsp_capabilities_push_MOR,
5473 "wsp.capabilities.push_mor",
5474 FT_UINT8, BASE_DEC, NULL, 0x00,
5478 { &hf_wsp_capabilities_extended_methods,
5479 { "Extended Methods",
5480 "wsp.capabilities.extend_methods",
5481 FT_STRING, BASE_HEX, NULL, 0x00,
5482 "Extended Methods", HFILL
5485 { &hf_wsp_capabilities_header_code_pages,
5486 { "Header Code Pages",
5487 "wsp.capabilities.code_pages",
5488 FT_STRING, BASE_HEX, NULL, 0x00,
5489 "Header Code Pages", HFILL
5492 { &hf_wsp_capabilities_aliases,
5494 "wsp.capabilities.aliases",
5495 FT_UINT8, BASE_HEX, NULL, 0x00,
5499 { &hf_wsp_post_data,
5502 FT_NONE, BASE_NONE, NULL, 0x00,
5506 { &hf_wsp_push_data,
5509 FT_NONE, BASE_NONE, NULL, 0x00,
5513 { &hf_wsp_multipart_data,
5514 { "Data in this part",
5515 "wsp.multipart.data",
5516 FT_NONE, BASE_NONE, NULL, 0x00,
5517 "The data of 1 MIME-multipart part.", HFILL
5523 FT_UINT32, BASE_DEC, NULL, 0x00,
5524 "MIME part of multipart data.", HFILL
5527 { &hf_wsp_redirect_flags,
5529 "wsp.redirect_flags",
5530 FT_UINT8, BASE_HEX, NULL, 0x00,
5531 "Redirect Flags", HFILL
5534 { &hf_wsp_redirect_permanent,
5535 { "Permanent Redirect",
5536 "wsp.redirect_flags.permanent",
5537 FT_BOOLEAN, 8, TFS(&yes_no_truth), PERMANENT_REDIRECT,
5538 "Permanent Redirect", HFILL
5541 { &hf_wsp_redirect_reuse_security_session,
5542 { "Reuse Security Session",
5543 "wsp.redirect_flags.reuse_security_session",
5544 FT_BOOLEAN, 8, TFS(&yes_no_truth), REUSE_SECURITY_SESSION,
5545 "Permanent Redirect", HFILL
5548 { &hf_wsp_redirect_afl,
5551 FT_UINT8, BASE_HEX, NULL, 0x00,
5552 "Redirect Address Flags/Length", HFILL
5555 { &hf_wsp_redirect_afl_bearer_type_included,
5556 { "Bearer Type Included",
5557 "wsp.redirect_afl.bearer_type_included",
5558 FT_BOOLEAN, 8, TFS(&yes_no_truth), BEARER_TYPE_INCLUDED,
5559 "Redirect Address bearer type included", HFILL
5562 { &hf_wsp_redirect_afl_port_number_included,
5563 { "Port Number Included",
5564 "wsp.redirect_afl.port_number_included",
5565 FT_BOOLEAN, 8, TFS(&yes_no_truth), PORT_NUMBER_INCLUDED,
5566 "Redirect Address port number included", HFILL
5569 { &hf_wsp_redirect_afl_address_len,
5571 "wsp.redirect_afl.address_len",
5572 FT_UINT8, BASE_DEC, NULL, ADDRESS_LEN,
5573 "Redirect Address Length", HFILL
5576 { &hf_wsp_redirect_bearer_type,
5578 "wsp.redirect_bearer_type",
5579 FT_UINT8, BASE_HEX, VALS(vals_bearer_types), 0x0,
5580 "Redirect Bearer Type", HFILL
5583 { &hf_wsp_redirect_port_num,
5585 "wsp.redirect_port_num",
5586 FT_UINT16, BASE_DEC, NULL, 0x0,
5587 "Redirect Port Number", HFILL
5590 { &hf_wsp_redirect_ipv4_addr,
5592 "wsp.redirect_ipv4_addr",
5593 FT_IPv4, BASE_NONE, NULL, 0x0,
5594 "Redirect Address (IP)", HFILL
5597 { &hf_wsp_redirect_ipv6_addr,
5599 "wsp.redirect_ipv6_addr",
5600 FT_IPv6, BASE_NONE, NULL, 0x0,
5601 "Redirect Address (IPv6)", HFILL
5604 { &hf_wsp_redirect_addr,
5606 "wsp.redirect_addr",
5607 FT_BYTES, BASE_NONE, NULL, 0x0,
5608 "Redirect Address", HFILL
5614 * New WSP header fields
5618 /* WSP header name */
5622 FT_STRING, BASE_NONE, NULL, 0x00,
5623 "Name of the WSP header", HFILL
5626 /* WSP well-known header ID */
5628 { "Header well-known ID",
5630 FT_STRING, BASE_NONE, NULL, 0x00,
5631 "7-bit identifier of a well-known WSP header", HFILL
5634 /* WSP headers start here */
5638 FT_STRING, BASE_NONE, NULL, 0x00,
5639 "WSP header Accept", HFILL
5642 { &hf_hdr_accept_charset,
5644 "wsp.hdr.accept_charset",
5645 FT_STRING, BASE_NONE, NULL, 0x00,
5646 "WSP header Accept-Charset", HFILL
5649 { &hf_hdr_accept_encoding,
5650 { "Accept-Encoding",
5651 "wsp.hdr.accept_encoding",
5652 FT_STRING, BASE_NONE, NULL, 0x00,
5653 "WSP header Accept-Encoding", HFILL
5656 { &hf_hdr_accept_language,
5657 { "Accept-Language",
5658 "wsp.hdr.accept_language",
5659 FT_STRING, BASE_NONE, NULL, 0x00,
5660 "WSP header Accept-Language", HFILL
5663 { &hf_hdr_accept_ranges,
5665 "wsp.hdr.accept_ranges",
5666 FT_STRING, BASE_NONE, NULL, 0x00,
5667 "WSP header Accept-Ranges", HFILL
5673 FT_STRING, BASE_NONE, NULL, 0x00,
5674 "WSP header Age", HFILL
5680 FT_STRING, BASE_NONE, NULL, 0x00,
5681 "WSP header Allow", HFILL
5684 { &hf_hdr_authorization,
5686 "wsp.hdr.authorization",
5687 FT_STRING, BASE_NONE, NULL, 0x00,
5688 "WSP header Authorization", HFILL
5691 { &hf_hdr_authorization_scheme,
5692 { "Authorization Scheme",
5693 "wsp.hdr.authorization.scheme",
5694 FT_STRING, BASE_NONE, NULL, 0x00,
5695 "WSP header Authorization: used scheme", HFILL
5698 { &hf_hdr_authorization_user_id,
5700 "wsp.hdr.authorization.user_id",
5701 FT_STRING, BASE_NONE, NULL, 0x00,
5702 "WSP header Authorization: user ID for basic authorization", HFILL
5705 { &hf_hdr_authorization_password,
5707 "wsp.hdr.authorization.password",
5708 FT_STRING, BASE_NONE, NULL, 0x00,
5709 "WSP header Authorization: password for basic authorization", HFILL
5712 { &hf_hdr_cache_control,
5714 "wsp.hdr.cache_control",
5715 FT_STRING, BASE_NONE, NULL, 0x00,
5716 "WSP header Cache-Control", HFILL
5719 { &hf_hdr_connection,
5721 "wsp.hdr.connection",
5722 FT_STRING, BASE_NONE, NULL, 0x00,
5723 "WSP header Connection", HFILL
5726 { &hf_hdr_content_base,
5728 "wsp.hdr.content_base",
5729 FT_STRING, BASE_NONE, NULL, 0x00,
5730 "WSP header Content-Base", HFILL
5733 { &hf_hdr_content_encoding,
5734 { "Content-Encoding",
5735 "wsp.hdr.content_encoding",
5736 FT_STRING, BASE_NONE, NULL, 0x00,
5737 "WSP header Content-Encoding", HFILL
5740 { &hf_hdr_content_language,
5741 { "Content-Language",
5742 "wsp.hdr.content_language",
5743 FT_STRING, BASE_NONE, NULL, 0x00,
5744 "WSP header Content-Language", HFILL
5747 { &hf_hdr_content_length,
5749 "wsp.hdr.content_length",
5750 FT_STRING, BASE_NONE, NULL, 0x00,
5751 "WSP header Content-Length", HFILL
5754 { &hf_hdr_content_location,
5755 { "Content-Location",
5756 "wsp.hdr.content_location",
5757 FT_STRING, BASE_NONE, NULL, 0x00,
5758 "WSP header Content-Location", HFILL
5761 { &hf_hdr_content_md5,
5763 "wsp.hdr.content_md5",
5764 FT_STRING, BASE_NONE, NULL, 0x00,
5765 "WSP header Content-Md5", HFILL
5768 { &hf_hdr_content_range,
5770 "wsp.hdr.content_range",
5771 FT_STRING, BASE_NONE, NULL, 0x00,
5772 "WSP header Content-Range", HFILL
5775 { &hf_hdr_content_range_first_byte_pos,
5776 { "First-byte-position",
5777 "wsp.hdr.content_range.first_byte_pos",
5778 FT_UINT32, BASE_DEC, NULL, 0x00,
5779 "WSP header Content-Range: position of first byte", HFILL
5782 { &hf_hdr_content_range_entity_length,
5784 "wsp.hdr.content_range.entity_length",
5785 FT_UINT32, BASE_DEC, NULL, 0x00,
5786 "WSP header Content-Range: length of the entity", HFILL
5789 { &hf_hdr_content_type,
5791 "wsp.hdr.content_type",
5792 FT_STRING, BASE_NONE, NULL, 0x00,
5793 "WSP header Content-Type", HFILL
5799 FT_STRING, BASE_NONE, NULL, 0x00,
5800 "WSP header Date", HFILL
5806 FT_STRING, BASE_NONE, NULL, 0x00,
5807 "WSP header ETag", HFILL
5813 FT_STRING, BASE_NONE, NULL, 0x00,
5814 "WSP header Expires", HFILL
5820 FT_STRING, BASE_NONE, NULL, 0x00,
5821 "WSP header From", HFILL
5827 FT_STRING, BASE_NONE, NULL, 0x00,
5828 "WSP header Host", HFILL
5831 { &hf_hdr_if_modified_since,
5832 { "If-Modified-Since",
5833 "wsp.hdr.if_modified_since",
5834 FT_STRING, BASE_NONE, NULL, 0x00,
5835 "WSP header If-Modified-Since", HFILL
5841 FT_STRING, BASE_NONE, NULL, 0x00,
5842 "WSP header If-Match", HFILL
5845 { &hf_hdr_if_none_match,
5847 "wsp.hdr.if_none_match",
5848 FT_STRING, BASE_NONE, NULL, 0x00,
5849 "WSP header If-None-Match", HFILL
5855 FT_STRING, BASE_NONE, NULL, 0x00,
5856 "WSP header If-Range", HFILL
5859 { &hf_hdr_if_unmodified_since,
5860 { "If-Unmodified-Since",
5861 "wsp.hdr.if_unmodified_since",
5862 FT_STRING, BASE_NONE, NULL, 0x00,
5863 "WSP header If-Unmodified-Since", HFILL
5866 { &hf_hdr_last_modified,
5868 "wsp.hdr.last_modified",
5869 FT_STRING, BASE_NONE, NULL, 0x00,
5870 "WSP header Last-Modified", HFILL
5876 FT_STRING, BASE_NONE, NULL, 0x00,
5877 "WSP header Location", HFILL
5880 { &hf_hdr_max_forwards,
5882 "wsp.hdr.max_forwards",
5883 FT_STRING, BASE_NONE, NULL, 0x00,
5884 "WSP header Max-Forwards", HFILL
5890 FT_STRING, BASE_NONE, NULL, 0x00,
5891 "WSP header Pragma", HFILL
5894 { &hf_hdr_proxy_authenticate,
5895 { "Proxy-Authenticate",
5896 "wsp.hdr.proxy_authenticate",
5897 FT_STRING, BASE_NONE, NULL, 0x00,
5898 "WSP header Proxy-Authenticate", HFILL
5901 { &hf_hdr_proxy_authenticate_scheme,
5902 { "Authentication Scheme",
5903 "wsp.hdr.proxy_authenticate.scheme",
5904 FT_STRING, BASE_NONE, NULL, 0x00,
5905 "WSP header Proxy-Authenticate: used scheme", HFILL
5908 { &hf_hdr_proxy_authenticate_realm,
5909 { "Authentication Realm",
5910 "wsp.hdr.proxy_authenticate.realm",
5911 FT_STRING, BASE_NONE, NULL, 0x00,
5912 "WSP header Proxy-Authenticate: used realm", HFILL
5915 { &hf_hdr_proxy_authorization,
5916 { "Proxy-Authorization",
5917 "wsp.hdr.proxy_authorization",
5918 FT_STRING, BASE_NONE, NULL, 0x00,
5919 "WSP header Proxy-Authorization", HFILL
5922 { &hf_hdr_proxy_authorization_scheme,
5923 { "Authorization Scheme",
5924 "wsp.hdr.proxy_authorization.scheme",
5925 FT_STRING, BASE_NONE, NULL, 0x00,
5926 "WSP header Proxy-Authorization: used scheme", HFILL
5929 { &hf_hdr_proxy_authorization_user_id,
5931 "wsp.hdr.proxy_authorization.user_id",
5932 FT_STRING, BASE_NONE, NULL, 0x00,
5933 "WSP header Proxy-Authorization: user ID for basic authorization", HFILL
5936 { &hf_hdr_proxy_authorization_password,
5938 "wsp.hdr.proxy_authorization.password",
5939 FT_STRING, BASE_NONE, NULL, 0x00,
5940 "WSP header Proxy-Authorization: password for basic authorization", HFILL
5946 FT_STRING, BASE_NONE, NULL, 0x00,
5947 "WSP header Public", HFILL
5953 FT_STRING, BASE_NONE, NULL, 0x00,
5954 "WSP header Range", HFILL
5957 { &hf_hdr_range_first_byte_pos,
5958 { "First-byte-position",
5959 "wsp.hdr.range.first_byte_pos",
5960 FT_UINT32, BASE_DEC, NULL, 0x00,
5961 "WSP header Range: position of first byte", HFILL
5964 { &hf_hdr_range_last_byte_pos,
5965 { "Last-byte-position",
5966 "wsp.hdr.range.last_byte_pos",
5967 FT_UINT32, BASE_DEC, NULL, 0x00,
5968 "WSP header Range: position of last byte", HFILL
5971 { &hf_hdr_range_suffix_length,
5973 "wsp.hdr.range.suffix_length",
5974 FT_UINT32, BASE_DEC, NULL, 0x00,
5975 "WSP header Range: length of the suffix", HFILL
5981 FT_STRING, BASE_NONE, NULL, 0x00,
5982 "WSP header Referer", HFILL
5985 { &hf_hdr_retry_after,
5987 "wsp.hdr.retry_after",
5988 FT_STRING, BASE_NONE, NULL, 0x00,
5989 "WSP header Retry-After", HFILL
5995 FT_STRING, BASE_NONE, NULL, 0x00,
5996 "WSP header Server", HFILL
5999 { &hf_hdr_transfer_encoding,
6000 { "Transfer-Encoding",
6001 "wsp.hdr.transfer_encoding",
6002 FT_STRING, BASE_NONE, NULL, 0x00,
6003 "WSP header Transfer-Encoding", HFILL
6009 FT_STRING, BASE_NONE, NULL, 0x00,
6010 "WSP header Upgrade", HFILL
6013 { &hf_hdr_user_agent,
6015 "wsp.hdr.user_agent",
6016 FT_STRING, BASE_NONE, NULL, 0x00,
6017 "WSP header User-Agent", HFILL
6023 FT_STRING, BASE_NONE, NULL, 0x00,
6024 "WSP header Vary", HFILL
6030 FT_STRING, BASE_NONE, NULL, 0x00,
6031 "WSP header Via", HFILL
6037 FT_STRING, BASE_NONE, NULL, 0x00,
6038 "WSP header Warning", HFILL
6041 { &hf_hdr_warning_code,
6043 "wsp.hdr.warning.code",
6044 FT_UINT8, BASE_HEX, VALS(vals_wsp_warning_code), 0x00,
6045 "WSP header Warning code", HFILL
6048 { &hf_hdr_warning_agent,
6050 "wsp.hdr.warning.agent",
6051 FT_STRING, BASE_NONE, NULL, 0x00,
6052 "WSP header Warning agent", HFILL
6055 { &hf_hdr_warning_text,
6057 "wsp.hdr.warning.text",
6058 FT_STRING, BASE_NONE, NULL, 0x00,
6059 "WSP header Warning text", HFILL
6062 { &hf_hdr_www_authenticate,
6063 { "Www-Authenticate",
6064 "wsp.hdr.www_authenticate",
6065 FT_STRING, BASE_NONE, NULL, 0x00,
6066 "WSP header Www-Authenticate", HFILL
6069 { &hf_hdr_www_authenticate_scheme,
6070 { "Authentication Scheme",
6071 "wsp.hdr.www_authenticate.scheme",
6072 FT_STRING, BASE_NONE, NULL, 0x00,
6073 "WSP header WWW-Authenticate: used scheme", HFILL
6076 { &hf_hdr_www_authenticate_realm,
6077 { "Authentication Realm",
6078 "wsp.hdr.www_authenticate.realm",
6079 FT_STRING, BASE_NONE, NULL, 0x00,
6080 "WSP header WWW-Authenticate: used realm", HFILL
6083 { &hf_hdr_content_disposition,
6084 { "Content-Disposition",
6085 "wsp.hdr.content_disposition",
6086 FT_STRING, BASE_NONE, NULL, 0x00,
6087 "WSP header Content-Disposition", HFILL
6090 { &hf_hdr_application_id,
6092 "wsp.hdr.application_id",
6093 FT_STRING, BASE_NONE, NULL, 0x00,
6094 "WSP header Application-Id", HFILL
6097 { &hf_hdr_content_uri,
6099 "wsp.hdr.content_uri",
6100 FT_STRING, BASE_NONE, NULL, 0x00,
6101 "WSP header Content-Uri", HFILL
6104 { &hf_hdr_initiator_uri,
6106 "wsp.hdr.initiator_uri",
6107 FT_STRING, BASE_NONE, NULL, 0x00,
6108 "WSP header Initiator-Uri", HFILL
6111 { &hf_hdr_bearer_indication,
6112 { "Bearer-Indication",
6113 "wsp.hdr.bearer_indication",
6114 FT_STRING, BASE_NONE, NULL, 0x00,
6115 "WSP header Bearer-Indication", HFILL
6118 { &hf_hdr_push_flag,
6120 "wsp.hdr.push_flag",
6121 FT_STRING, BASE_NONE, NULL, 0x00,
6122 "WSP header Push-Flag", HFILL
6125 { &hf_hdr_push_flag_auth,
6126 { "Initiator URI is authenticated",
6127 "wsp.hdr.push_flag.authenticated",
6128 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x01,
6129 "The X-Wap-Initiator-URI has been authenticated.", HFILL
6132 { &hf_hdr_push_flag_trust,
6133 { "Content is trusted",
6134 "wsp.hdr.push_flag.trusted",
6135 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x02,
6136 "The push content is trusted.", HFILL
6139 { &hf_hdr_push_flag_last,
6140 { "Last push message",
6141 "wsp.hdr.push_flag.last",
6142 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x04,
6143 "Indicates whether this is the last push message.", HFILL
6149 FT_STRING, BASE_NONE, NULL, 0x00,
6150 "WSP header Profile", HFILL
6153 { &hf_hdr_profile_diff,
6155 "wsp.hdr.profile_diff",
6156 FT_STRING, BASE_NONE, NULL, 0x00,
6157 "WSP header Profile-Diff", HFILL
6160 { &hf_hdr_profile_warning,
6161 { "Profile-Warning",
6162 "wsp.hdr.profile_warning",
6163 FT_STRING, BASE_NONE, NULL, 0x00,
6164 "WSP header Profile-Warning", HFILL
6170 FT_STRING, BASE_NONE, NULL, 0x00,
6171 "WSP header Expect", HFILL
6177 FT_STRING, BASE_NONE, NULL, 0x00,
6178 "WSP header Te", HFILL
6184 FT_STRING, BASE_NONE, NULL, 0x00,
6185 "WSP header Trailer", HFILL
6188 { &hf_hdr_x_wap_tod,
6190 "wsp.hdr.x_wap_tod",
6191 FT_STRING, BASE_NONE, NULL, 0x00,
6192 "WSP header X-Wap-Tod", HFILL
6195 { &hf_hdr_content_id,
6197 "wsp.hdr.content_id",
6198 FT_STRING, BASE_NONE, NULL, 0x00,
6199 "WSP header Content-Id", HFILL
6202 { &hf_hdr_set_cookie,
6204 "wsp.hdr.set_cookie",
6205 FT_STRING, BASE_NONE, NULL, 0x00,
6206 "WSP header Set-Cookie", HFILL
6212 FT_STRING, BASE_NONE, NULL, 0x00,
6213 "WSP header Cookie", HFILL
6216 { &hf_hdr_encoding_version,
6217 { "Encoding-Version",
6218 "wsp.hdr.encoding_version",
6219 FT_STRING, BASE_NONE, NULL, 0x00,
6220 "WSP header Encoding-Version", HFILL
6223 { &hf_hdr_x_wap_security,
6225 "wsp.hdr.x_wap_security",
6226 FT_STRING, BASE_NONE, NULL, 0x00,
6227 "WSP header X-Wap-Security", HFILL
6230 { &hf_hdr_x_wap_application_id,
6231 { "X-Wap-Application-Id",
6232 "wsp.hdr.x_wap_application_id",
6233 FT_STRING, BASE_NONE, NULL, 0x00,
6234 "WSP header X-Wap-Application-Id", HFILL
6237 { &hf_hdr_accept_application,
6238 { "Accept-Application",
6239 "wsp.hdr.accept_application",
6240 FT_STRING, BASE_NONE, NULL, 0x00,
6241 "WSP header Accept-Application", HFILL
6250 /* Textual headers */
6251 { &hf_hdr_openwave_x_up_proxy_operator_domain,
6252 { "x-up-proxy-operator-domain",
6253 "wsp.hdr.openwave.x_up_proxy_operator_domain",
6254 FT_STRING, BASE_NONE, NULL, 0x00,
6255 "WSP Openwave header x-up-proxy-operator-domain", HFILL
6258 { &hf_hdr_openwave_x_up_proxy_home_page,
6259 { "x-up-proxy-home-page",
6260 "wsp.hdr.openwave.x_up_proxy_home_page",
6261 FT_STRING, BASE_NONE, NULL, 0x00,
6262 "WSP Openwave header x-up-proxy-home-page", HFILL
6265 { &hf_hdr_openwave_x_up_proxy_uplink_version,
6266 { "x-up-proxy-uplink-version",
6267 "wsp.hdr.openwave.x_up_proxy_uplink_version",
6268 FT_STRING, BASE_NONE, NULL, 0x00,
6269 "WSP Openwave header x-up-proxy-uplink-version", HFILL
6272 { &hf_hdr_openwave_x_up_proxy_ba_realm,
6273 { "x-up-proxy-ba-realm",
6274 "wsp.hdr.openwave.x_up_proxy_ba_realm",
6275 FT_STRING, BASE_NONE, NULL, 0x00,
6276 "WSP Openwave header x-up-proxy-ba-realm", HFILL
6279 { &hf_hdr_openwave_x_up_proxy_request_uri,
6280 { "x-up-proxy-request-uri",
6281 "wsp.hdr.openwave.x_up_proxy_request_uri",
6282 FT_STRING, BASE_NONE, NULL, 0x00,
6283 "WSP Openwave header x-up-proxy-request-uri", HFILL
6286 { &hf_hdr_openwave_x_up_proxy_bookmark,
6287 { "x-up-proxy-bookmark",
6288 "wsp.hdr.openwave.x_up_proxy_bookmark",
6289 FT_STRING, BASE_NONE, NULL, 0x00,
6290 "WSP Openwave header x-up-proxy-bookmark", HFILL
6293 /* Integer-value headers */
6294 { &hf_hdr_openwave_x_up_proxy_push_seq,
6295 { "x-up-proxy-push-seq",
6296 "wsp.hdr.openwave.x_up_proxy_push_seq",
6297 FT_STRING, BASE_NONE, NULL, 0x00,
6298 "WSP Openwave header x-up-proxy-push-seq", HFILL
6301 { &hf_hdr_openwave_x_up_proxy_notify,
6302 { "x-up-proxy-notify",
6303 "wsp.hdr.openwave.x_up_proxy_notify",
6304 FT_STRING, BASE_NONE, NULL, 0x00,
6305 "WSP Openwave header x-up-proxy-notify", HFILL
6308 { &hf_hdr_openwave_x_up_proxy_net_ask,
6309 { "x-up-proxy-net-ask",
6310 "wsp.hdr.openwave.x_up_proxy_net_ask",
6311 FT_STRING, BASE_NONE, NULL, 0x00,
6312 "WSP Openwave header x-up-proxy-net-ask", HFILL
6315 { &hf_hdr_openwave_x_up_proxy_tod,
6317 "wsp.hdr.openwave.x_up_proxy_tod",
6318 FT_STRING, BASE_NONE, NULL, 0x00,
6319 "WSP Openwave header x-up-proxy-tod", HFILL
6322 { &hf_hdr_openwave_x_up_proxy_ba_enable,
6323 { "x-up-proxy-ba-enable",
6324 "wsp.hdr.openwave.x_up_proxy_ba_enable",
6325 FT_STRING, BASE_NONE, NULL, 0x00,
6326 "WSP Openwave header x-up-proxy-ba-enable", HFILL
6329 { &hf_hdr_openwave_x_up_proxy_redirect_enable,
6330 { "x-up-proxy-redirect-enable",
6331 "wsp.hdr.openwave.x_up_proxy_redirect_enable",
6332 FT_STRING, BASE_NONE, NULL, 0x00,
6333 "WSP Openwave header x-up-proxy-redirect-enable", HFILL
6336 { &hf_hdr_openwave_x_up_proxy_redirect_status,
6337 { "x-up-proxy-redirect-status",
6338 "wsp.hdr.openwave.x_up_proxy_redirect_status",
6339 FT_STRING, BASE_NONE, NULL, 0x00,
6340 "WSP Openwave header x-up-proxy-redirect-status", HFILL
6343 { &hf_hdr_openwave_x_up_proxy_linger,
6344 { "x-up-proxy-linger",
6345 "wsp.hdr.openwave.x_up_proxy_linger",
6346 FT_STRING, BASE_NONE, NULL, 0x00,
6347 "WSP Openwave header x-up-proxy-linger", HFILL
6350 { &hf_hdr_openwave_x_up_proxy_enable_trust,
6351 { "x-up-proxy-enable-trust",
6352 "wsp.hdr.openwave.x_up_proxy_enable_trust",
6353 FT_STRING, BASE_NONE, NULL, 0x00,
6354 "WSP Openwave header x-up-proxy-enable-trust", HFILL
6357 { &hf_hdr_openwave_x_up_proxy_trust,
6358 { "x-up-proxy-trust",
6359 "wsp.hdr.openwave.x_up_proxy_trust",
6360 FT_STRING, BASE_NONE, NULL, 0x00,
6361 "WSP Openwave header x-up-proxy-trust", HFILL
6364 { &hf_hdr_openwave_x_up_devcap_has_color,
6365 { "x-up-devcap-has-color",
6366 "wsp.hdr.openwave.x_up_devcap_has_color",
6367 FT_STRING, BASE_NONE, NULL, 0x00,
6368 "WSP Openwave header x-up-devcap-has-color", HFILL
6371 { &hf_hdr_openwave_x_up_devcap_num_softkeys,
6372 { "x-up-devcap-num-softkeys",
6373 "wsp.hdr.openwave.x_up_devcap_num_softkeys",
6374 FT_STRING, BASE_NONE, NULL, 0x00,
6375 "WSP Openwave header x-up-devcap-num-softkeys", HFILL
6378 { &hf_hdr_openwave_x_up_devcap_softkey_size,
6379 { "x-up-devcap-softkey-size",
6380 "wsp.hdr.openwave.x_up_devcap_softkey_size",
6381 FT_STRING, BASE_NONE, NULL, 0x00,
6382 "WSP Openwave header x-up-devcap-softkey-size", HFILL
6385 { &hf_hdr_openwave_x_up_devcap_screen_chars,
6386 { "x-up-devcap-screen-chars",
6387 "wsp.hdr.openwave.x_up_devcap_screen_chars",
6388 FT_STRING, BASE_NONE, NULL, 0x00,
6389 "WSP Openwave header x-up-devcap-screen-chars", HFILL
6392 { &hf_hdr_openwave_x_up_devcap_screen_pixels,
6393 { "x-up-devcap-screen-pixels",
6394 "wsp.hdr.openwave.x_up_devcap_screen_pixels",
6395 FT_STRING, BASE_NONE, NULL, 0x00,
6396 "WSP Openwave header x-up-devcap-screen-pixels", HFILL
6399 { &hf_hdr_openwave_x_up_devcap_em_size,
6400 { "x-up-devcap-em-size",
6401 "wsp.hdr.openwave.x_up_devcap_em_size",
6402 FT_STRING, BASE_NONE, NULL, 0x00,
6403 "WSP Openwave header x-up-devcap-em-size", HFILL
6406 { &hf_hdr_openwave_x_up_devcap_screen_depth,
6407 { "x-up-devcap-screen-depth",
6408 "wsp.hdr.openwave.x_up_devcap_screen_depth",
6409 FT_STRING, BASE_NONE, NULL, 0x00,
6410 "WSP Openwave header x-up-devcap-screen-depth", HFILL
6413 { &hf_hdr_openwave_x_up_devcap_immed_alert,
6414 { "x-up-devcap-immed-alert",
6415 "wsp.hdr.openwave.x_up_devcap_immed_alert",
6416 FT_STRING, BASE_NONE, NULL, 0x00,
6417 "WSP Openwave header x-up-devcap-immed-alert", HFILL
6420 { &hf_hdr_openwave_x_up_devcap_gui,
6421 { "x-up-devcap-gui",
6422 "wsp.hdr.openwave.x_up_devcap_gui",
6423 FT_STRING, BASE_NONE, NULL, 0x00,
6424 "WSP Openwave header x-up-devcap-gui", HFILL
6427 { &hf_hdr_openwave_x_up_proxy_trans_charset,
6428 { "x-up-proxy-trans-charset",
6429 "wsp.hdr.openwave.x_up_proxy_trans_charset",
6430 FT_STRING, BASE_NONE, NULL, 0x00,
6431 "WSP Openwave header x-up-proxy-trans-charset", HFILL
6434 { &hf_hdr_openwave_x_up_proxy_push_accept,
6435 { "x-up-proxy-push-accept",
6436 "wsp.hdr.openwave.x_up_proxy_push_accept",
6437 FT_STRING, BASE_NONE, NULL, 0x00,
6438 "WSP Openwave header x-up-proxy-push-accept", HFILL
6443 { &hf_hdr_openwave_x_up_proxy_client_id,
6444 { "x-up-proxy-client-id",
6445 "wsp.hdr.openwave.x_up_proxy_client_id",
6446 FT_STRING, BASE_NONE, NULL, 0x00,
6447 "WSP Openwave header x-up-proxy-client-id", HFILL
6453 * Header value parameters
6459 FT_STRING, BASE_NONE, NULL, 0x00,
6460 "Q parameter", HFILL
6463 { &hf_parameter_charset,
6465 "wsp.parameter.charset",
6466 FT_STRING, BASE_NONE, NULL, 0x00,
6467 "Charset parameter", HFILL
6473 /* Setup protocol subtree array */
6474 static gint *ett[] = { /* TODO - remove unneeded subtrees */
6476 &ett_header, /* Header field subtree */
6477 &ett_headers, /* Subtree for WSP headers */
6478 &ett_capabilities, /* CO-WSP Session Capabilities */
6480 &ett_redirect_flags,
6486 /* Register the protocol name and description */
6487 proto_wsp = proto_register_protocol(
6488 "Wireless Session Protocol", /* protocol name for use by ethereal */
6489 "WSP", /* short version of name */
6490 "wap-wsp" /* Abbreviated protocol name,
6492 < URL:http://www.isi.edu/in-notes/iana/assignments/port-numbers/ >
6495 wsp_tap = register_tap("wsp");
6496 /* Init the hash table */
6497 /* wsp_sessions = g_hash_table_new(
6498 (GHashFunc) wsp_session_hash,
6499 (GEqualFunc)wsp_session_equal);*/
6501 /* Required function calls to register the header fields and subtrees used */
6502 proto_register_field_array(proto_wsp, hf, array_length(hf));
6503 proto_register_subtree_array(ett, array_length(ett));
6505 register_dissector("wsp-co", dissect_wsp_fromwap_co, proto_wsp);
6506 register_dissector("wsp-cl", dissect_wsp_fromwap_cl, proto_wsp);
6507 wsp_dissector_table = register_dissector_table(
6508 "wsp.content_type.integer",
6509 "WSP content type (well-known integer value)",
6510 FT_UINT32, BASE_HEX);
6511 /* As the media types for WSP and HTTP are the same, the WSP dissector
6512 * uses the same string dissector table as the HTTP protocol. This is
6513 * not true for the integer representation of the WSP media types. */
6514 wsp_dissector_table_text = find_dissector_table("media_type");
6515 register_heur_dissector_list("wsp", &heur_subdissector_list);
6517 wsp_fromudp_handle = create_dissector_handle(dissect_wsp_fromudp,
6522 proto_reg_handoff_wsp(void)
6525 * Get a handle for the WBXML dissector.
6527 wbxml_handle = find_dissector("wbxml");
6530 * And get a handle for the WTP-over-UDP dissector.
6532 wtp_fromudp_handle = find_dissector("wtp-udp");
6534 /* Only connection-less WSP has no previous handler */
6535 dissector_add("udp.port", UDP_PORT_WSP, wsp_fromudp_handle);
6536 dissector_add("udp.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
6538 /* SMPP dissector can also carry WSP */
6539 dissector_add("smpp.udh.port", UDP_PORT_WSP, wsp_fromudp_handle);
6540 dissector_add("smpp.udh.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
6542 /* This dissector is also called from the WTP and WTLS dissectors */