3 * Routines to dissect WSP component of WAP traffic.
5 * $Id: packet-wsp.c,v 1.100 2003/12/21 05:51:34 jmayer 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 * Session Initiation Request dissection
18 * by Olivier Biot <olivier.biot(ad)siemens.com>.
20 * TODO - Move parts of dissection before and other parts after "if (tree)",
21 * for example skip almost all but content type in replies if tree is closed.
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version 2
26 * of the License, or (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 /* Edit with a 4-space tabulation */
47 #ifdef NEED_SNPRINTF_H
48 # include "snprintf.h"
53 #include <epan/packet.h>
54 #include <epan/ipv6-utils.h>
55 #include <epan/conversation.h>
57 #include "packet-wap.h"
58 #include "packet-wsp.h"
60 #define PLURALIZE(x) ( (x) == 1 ? "" : "s" )
62 /* General-purpose debug logger.
63 * Requires double parentheses because of variable arguments of printf().
65 * Enable debug logging for WSP by defining AM_CFLAGS
66 * so that it contains "-DDEBUG_wsp"
70 printf("%s:%u: ", __FILE__, __LINE__); \
77 /* Statistics (see doc/README.tapping) */
79 static int wsp_tap = -1;
82 /* File scoped variables for the protocol and registered fields */
83 static int proto_wsp = HF_EMPTY;
86 * Initialize the header field pointers
89 /* WSP header fields and their subfields if available */
90 static int hf_hdr_name = HF_EMPTY;
91 static int hf_hdr_accept = HF_EMPTY;
92 static int hf_hdr_accept_charset = HF_EMPTY;
93 static int hf_hdr_accept_encoding = HF_EMPTY;
94 static int hf_hdr_accept_language = HF_EMPTY;
95 static int hf_hdr_accept_ranges = HF_EMPTY;
96 static int hf_hdr_age = HF_EMPTY;
97 static int hf_hdr_allow = HF_EMPTY;
98 static int hf_hdr_authorization = HF_EMPTY;
99 static int hf_hdr_authorization_scheme = HF_EMPTY; /* Subfield */
100 static int hf_hdr_authorization_user_id = HF_EMPTY; /* Subfield */
101 static int hf_hdr_authorization_password = HF_EMPTY; /* Subfield */
102 static int hf_hdr_cache_control = HF_EMPTY;
103 static int hf_hdr_connection = HF_EMPTY;
104 static int hf_hdr_content_base = HF_EMPTY;
105 static int hf_hdr_content_encoding = HF_EMPTY;
106 static int hf_hdr_content_language = HF_EMPTY;
107 static int hf_hdr_content_length = HF_EMPTY;
108 static int hf_hdr_content_location = HF_EMPTY;
109 static int hf_hdr_content_md5 = HF_EMPTY;
110 static int hf_hdr_content_range = HF_EMPTY;
111 static int hf_hdr_content_range_first_byte_pos = HF_EMPTY; /* Subfield */
112 static int hf_hdr_content_range_entity_length = HF_EMPTY; /* Subfield */
113 static int hf_hdr_content_type = HF_EMPTY;
114 static int hf_hdr_date = HF_EMPTY;
115 static int hf_hdr_etag = HF_EMPTY;
116 static int hf_hdr_expires = HF_EMPTY;
117 static int hf_hdr_from = HF_EMPTY;
118 static int hf_hdr_host = HF_EMPTY;
119 static int hf_hdr_if_modified_since = HF_EMPTY;
120 static int hf_hdr_if_match = HF_EMPTY;
121 static int hf_hdr_if_none_match = HF_EMPTY;
122 static int hf_hdr_if_range = HF_EMPTY;
123 static int hf_hdr_if_unmodified_since = HF_EMPTY;
124 static int hf_hdr_last_modified = HF_EMPTY;
125 static int hf_hdr_location = HF_EMPTY;
126 static int hf_hdr_max_forwards = HF_EMPTY;
127 static int hf_hdr_pragma = HF_EMPTY;
128 static int hf_hdr_proxy_authenticate = HF_EMPTY;
129 static int hf_hdr_proxy_authenticate_scheme = HF_EMPTY; /* Subfield */
130 static int hf_hdr_proxy_authenticate_realm = HF_EMPTY; /* Subfield */
131 static int hf_hdr_proxy_authorization = HF_EMPTY;
132 static int hf_hdr_proxy_authorization_scheme = HF_EMPTY; /* Subfield */
133 static int hf_hdr_proxy_authorization_user_id = HF_EMPTY; /* Subfield */
134 static int hf_hdr_proxy_authorization_password = HF_EMPTY; /* Subfield */
135 static int hf_hdr_public = HF_EMPTY;
136 static int hf_hdr_range = HF_EMPTY;
137 static int hf_hdr_range_first_byte_pos = HF_EMPTY; /* Subfield */
138 static int hf_hdr_range_last_byte_pos = HF_EMPTY; /* Subfield */
139 static int hf_hdr_range_suffix_length = HF_EMPTY; /* Subfield */
140 static int hf_hdr_referer = HF_EMPTY;
141 static int hf_hdr_retry_after = HF_EMPTY;
142 static int hf_hdr_server = HF_EMPTY;
143 static int hf_hdr_transfer_encoding = HF_EMPTY;
144 static int hf_hdr_upgrade = HF_EMPTY;
145 static int hf_hdr_user_agent = HF_EMPTY;
146 static int hf_hdr_vary = HF_EMPTY;
147 static int hf_hdr_via = HF_EMPTY;
148 static int hf_hdr_warning = HF_EMPTY;
149 static int hf_hdr_warning_code = HF_EMPTY; /* Subfield */
150 static int hf_hdr_warning_agent = HF_EMPTY; /* Subfield */
151 static int hf_hdr_warning_text = HF_EMPTY; /* Subfield */
152 static int hf_hdr_www_authenticate = HF_EMPTY;
153 static int hf_hdr_www_authenticate_scheme = HF_EMPTY; /* Subfield */
154 static int hf_hdr_www_authenticate_realm = HF_EMPTY; /* Subfield */
155 static int hf_hdr_content_disposition = HF_EMPTY;
156 static int hf_hdr_application_id = HF_EMPTY;
157 static int hf_hdr_content_uri = HF_EMPTY;
158 static int hf_hdr_initiator_uri = HF_EMPTY;
159 static int hf_hdr_bearer_indication = HF_EMPTY;
160 static int hf_hdr_push_flag = HF_EMPTY;
161 static int hf_hdr_push_flag_auth = HF_EMPTY; /* Subfield */
162 static int hf_hdr_push_flag_trust = HF_EMPTY; /* Subfield */
163 static int hf_hdr_push_flag_last = HF_EMPTY; /* Subfield */
164 static int hf_hdr_profile = HF_EMPTY;
165 static int hf_hdr_profile_diff = HF_EMPTY;
166 static int hf_hdr_profile_warning = HF_EMPTY;
167 static int hf_hdr_expect = HF_EMPTY;
168 static int hf_hdr_te = HF_EMPTY;
169 static int hf_hdr_trailer = HF_EMPTY;
170 static int hf_hdr_x_wap_tod = HF_EMPTY;
171 static int hf_hdr_content_id = HF_EMPTY;
172 static int hf_hdr_set_cookie = HF_EMPTY;
173 static int hf_hdr_cookie = HF_EMPTY;
174 static int hf_hdr_encoding_version = HF_EMPTY;
175 static int hf_hdr_x_wap_security = HF_EMPTY;
176 static int hf_hdr_x_wap_application_id = HF_EMPTY;
177 static int hf_hdr_accept_application = HF_EMPTY;
180 /* Openwave headers */
181 static int hf_hdr_openwave_x_up_proxy_operator_domain = HF_EMPTY;
182 static int hf_hdr_openwave_x_up_proxy_home_page = HF_EMPTY;
183 static int hf_hdr_openwave_x_up_proxy_uplink_version = HF_EMPTY;
184 static int hf_hdr_openwave_x_up_proxy_ba_realm = HF_EMPTY;
185 static int hf_hdr_openwave_x_up_proxy_request_uri = HF_EMPTY;
187 static int hf_hdr_openwave_x_up_proxy_client_id = HF_EMPTY;
189 static int hf_hdr_openwave_x_up_proxy_bookmark = HF_EMPTY;
190 static int hf_hdr_openwave_x_up_proxy_push_seq = HF_EMPTY;
191 static int hf_hdr_openwave_x_up_proxy_notify = HF_EMPTY;
192 static int hf_hdr_openwave_x_up_proxy_net_ask = HF_EMPTY;
193 static int hf_hdr_openwave_x_up_proxy_tod = HF_EMPTY;
194 static int hf_hdr_openwave_x_up_proxy_ba_enable = HF_EMPTY;
195 static int hf_hdr_openwave_x_up_proxy_redirect_enable = HF_EMPTY;
196 static int hf_hdr_openwave_x_up_proxy_redirect_status = HF_EMPTY;
197 static int hf_hdr_openwave_x_up_proxy_linger = HF_EMPTY;
198 static int hf_hdr_openwave_x_up_proxy_enable_trust = HF_EMPTY;
199 static int hf_hdr_openwave_x_up_proxy_trust = HF_EMPTY;
200 static int hf_hdr_openwave_x_up_devcap_has_color = HF_EMPTY;
201 static int hf_hdr_openwave_x_up_devcap_num_softkeys = HF_EMPTY;
202 static int hf_hdr_openwave_x_up_devcap_softkey_size = HF_EMPTY;
203 static int hf_hdr_openwave_x_up_devcap_screen_chars = HF_EMPTY;
204 static int hf_hdr_openwave_x_up_devcap_screen_pixels = HF_EMPTY;
205 static int hf_hdr_openwave_x_up_devcap_em_size = HF_EMPTY;
206 static int hf_hdr_openwave_x_up_devcap_screen_depth = HF_EMPTY;
207 static int hf_hdr_openwave_x_up_devcap_immed_alert = HF_EMPTY;
208 static int hf_hdr_openwave_x_up_devcap_gui = HF_EMPTY;
209 static int hf_hdr_openwave_x_up_proxy_trans_charset = HF_EMPTY;
210 static int hf_hdr_openwave_x_up_proxy_push_accept = HF_EMPTY;
213 /* WSP parameter fields */
214 static int hf_parameter_q = HF_EMPTY;
215 static int hf_parameter_charset = HF_EMPTY;
217 static int hf_parameter_textual = HF_EMPTY;
218 static int hf_parameter_type = HF_EMPTY;
219 static int hf_parameter_name = HF_EMPTY;
220 static int hf_parameter_filename = HF_EMPTY;
221 static int hf_parameter_start = HF_EMPTY;
222 static int hf_parameter_start_info = HF_EMPTY;
223 static int hf_parameter_comment = HF_EMPTY;
224 static int hf_parameter_domain = HF_EMPTY;
225 static int hf_parameter_path = HF_EMPTY;
226 static int hf_parameter_sec = HF_EMPTY;
227 static int hf_parameter_mac = HF_EMPTY;
228 static int hf_parameter_upart_type = HF_EMPTY;
229 static int hf_parameter_upart_type_value = HF_EMPTY;
230 static int hf_parameter_level = HF_EMPTY;
233 /* Old header fields */
235 static int hf_wsp_header_tid = HF_EMPTY;
236 static int hf_wsp_header_pdu_type = HF_EMPTY;
237 static int hf_wsp_version_major = HF_EMPTY;
238 static int hf_wsp_version_minor = HF_EMPTY;
239 /* Session capabilities (CO-WSP) */
240 static int hf_capabilities_length = HF_EMPTY;
241 static int hf_capabilities_section = HF_EMPTY;
242 static int hf_capa_client_sdu_size = HF_EMPTY;
243 static int hf_capa_server_sdu_size = HF_EMPTY;
244 static int hf_capa_protocol_options = HF_EMPTY;
245 static int hf_capa_protocol_option_confirmed_push = HF_EMPTY; /* Subfield */
246 static int hf_capa_protocol_option_push = HF_EMPTY; /* Subfield */
247 static int hf_capa_protocol_option_session_resume = HF_EMPTY; /* Subfield */
248 static int hf_capa_protocol_option_ack_headers = HF_EMPTY; /* Subfield */
249 static int hf_capa_protocol_option_large_data_transfer = HF_EMPTY; /* Subfield */
250 static int hf_capa_method_mor = HF_EMPTY;
251 static int hf_capa_push_mor = HF_EMPTY;
252 static int hf_capa_extended_methods = HF_EMPTY;
253 static int hf_capa_header_code_pages = HF_EMPTY;
254 static int hf_capa_aliases = HF_EMPTY;
255 static int hf_capa_client_message_size = HF_EMPTY;
256 static int hf_capa_server_message_size = HF_EMPTY;
258 static int hf_wsp_header_uri_len = HF_EMPTY;
259 static int hf_wsp_header_uri = HF_EMPTY;
260 static int hf_wsp_server_session_id = HF_EMPTY;
261 static int hf_wsp_header_status = HF_EMPTY;
262 static int hf_wsp_header_length = HF_EMPTY;
263 static int hf_wsp_headers_section = HF_EMPTY;
264 static int hf_wsp_parameter_type = HF_EMPTY;
265 static int hf_wsp_parameter_name = HF_EMPTY;
266 static int hf_wsp_parameter_filename = HF_EMPTY;
267 static int hf_wsp_parameter_start = HF_EMPTY;
268 static int hf_wsp_parameter_start_info = HF_EMPTY;
269 static int hf_wsp_parameter_comment = HF_EMPTY;
270 static int hf_wsp_parameter_domain = HF_EMPTY;
271 static int hf_wsp_parameter_path = HF_EMPTY;
272 static int hf_wsp_parameter_sec = HF_EMPTY;
273 static int hf_wsp_parameter_mac = HF_EMPTY;
274 static int hf_wsp_parameter_upart_type = HF_EMPTY;
275 static int hf_wsp_parameter_level = HF_EMPTY;
276 static int hf_wsp_reply_data = HF_EMPTY;
277 static int hf_wsp_post_data = HF_EMPTY;
278 static int hf_wsp_push_data = HF_EMPTY;
279 static int hf_wsp_multipart_data = HF_EMPTY;
280 static int hf_wsp_mpart = HF_EMPTY;
282 /* Header code page shift sequence */
283 static int hf_wsp_header_shift_code = HF_EMPTY;
285 /* WSP Redirect fields */
286 static int hf_wsp_redirect_flags = HF_EMPTY;
287 static int hf_wsp_redirect_permanent = HF_EMPTY;
288 static int hf_wsp_redirect_reuse_security_session = HF_EMPTY;
289 static int hf_redirect_addresses = HF_EMPTY;
292 static int hf_address_entry = HF_EMPTY;
293 static int hf_address_flags_length = HF_EMPTY;
294 static int hf_address_flags_length_bearer_type_included = HF_EMPTY; /* Subfield */
295 static int hf_address_flags_length_port_number_included = HF_EMPTY; /* Subfield */
296 static int hf_address_flags_length_address_len = HF_EMPTY; /* Subfield */
297 static int hf_address_bearer_type = HF_EMPTY;
298 static int hf_address_port_num = HF_EMPTY;
299 static int hf_address_ipv4_addr = HF_EMPTY;
300 static int hf_address_ipv6_addr = HF_EMPTY;
301 static int hf_address_addr = HF_EMPTY;
303 /* Session Initiation Request fields */
304 static int hf_sir_section = HF_EMPTY;
305 static int hf_sir_version = HF_EMPTY;
306 static int hf_sir_app_id_list_len = HF_EMPTY;
307 static int hf_sir_app_id_list = HF_EMPTY;
308 static int hf_sir_wsp_contact_points_len = HF_EMPTY;
309 static int hf_sir_wsp_contact_points = HF_EMPTY;
310 static int hf_sir_contact_points_len = HF_EMPTY;
311 static int hf_sir_contact_points = HF_EMPTY;
312 static int hf_sir_protocol_options_len = HF_EMPTY;
313 static int hf_sir_protocol_options = HF_EMPTY;
314 static int hf_sir_prov_url_len = HF_EMPTY;
315 static int hf_sir_prov_url = HF_EMPTY;
316 static int hf_sir_cpi_tag_len = HF_EMPTY;
317 static int hf_sir_cpi_tag = HF_EMPTY;
320 * Initialize the subtree pointers
324 static int ett_wsp = ETT_EMPTY;
325 /* WSP headers tree */
326 static int ett_header = ETT_EMPTY;
327 /* WSP header subtree */
328 static int ett_headers = ETT_EMPTY;
329 /* CO-WSP session capabilities */
330 static int ett_capabilities = ETT_EMPTY;
331 static int ett_capability = ETT_EMPTY;
332 static int ett_post = ETT_EMPTY;
333 static int ett_redirect_flags = ETT_EMPTY;
334 static int ett_address_flags = ETT_EMPTY;
335 static int ett_multiparts = ETT_EMPTY;
336 static int ett_mpartlist = ETT_EMPTY;
337 /* Session Initiation Request tree */
338 static int ett_sir = ETT_EMPTY;
339 static int ett_addresses = ETT_EMPTY;
340 static int ett_address = ETT_EMPTY;
344 /* Handle for WSP-over-UDP dissector */
345 static dissector_handle_t wsp_fromudp_handle;
347 /* Handle for WTP-over-UDP dissector */
348 static dissector_handle_t wtp_fromudp_handle;
350 const value_string vals_pdu_type[] = {
351 { 0x00, "Reserved" },
353 { 0x02, "ConnectReply" },
354 { 0x03, "Redirect" },
356 { 0x05, "Disconnect" },
358 { 0x07, "ConfirmedPush" },
362 /* 0x10 - 0x3F Unassigned */
370 /* 0x45 - 0x4F Unassigned (Get PDU) */
371 /* 0x50 - 0x5F Extended method (Get PDU) */
372 { 0x50, "Extended Get Method 0"},
373 { 0x51, "Extended Get Method 1"},
374 { 0x52, "Extended Get Method 2"},
375 { 0x53, "Extended Get Method 3"},
376 { 0x54, "Extended Get Method 4"},
377 { 0x55, "Extended Get Method 5"},
378 { 0x56, "Extended Get Method 6"},
379 { 0x57, "Extended Get Method 7"},
380 { 0x58, "Extended Get Method 8"},
381 { 0x59, "Extended Get Method 9"},
382 { 0x5A, "Extended Get Method 10"},
383 { 0x5B, "Extended Get Method 11"},
384 { 0x5C, "Extended Get Method 12"},
385 { 0x5D, "Extended Get Method 13"},
386 { 0x5E, "Extended Get Method 14"},
387 { 0x5F, "Extended Get Method 15"},
392 /* 0x62 - 0x6F Unassigned (Post PDU) */
393 /* 0x70 - 0x7F Extended method (Post PDU) */
394 { 0x70, "Extended Post Method 0"},
395 { 0x71, "Extended Post Method 1"},
396 { 0x72, "Extended Post Method 2"},
397 { 0x73, "Extended Post Method 3"},
398 { 0x74, "Extended Post Method 4"},
399 { 0x75, "Extended Post Method 5"},
400 { 0x76, "Extended Post Method 6"},
401 { 0x77, "Extended Post Method 7"},
402 { 0x78, "Extended Post Method 8"},
403 { 0x79, "Extended Post Method 9"},
404 { 0x7A, "Extended Post Method 10"},
405 { 0x7B, "Extended Post Method 11"},
406 { 0x7C, "Extended Post Method 12"},
407 { 0x7D, "Extended Post Method 13"},
408 { 0x7E, "Extended Post Method 14"},
409 { 0x7F, "Extended Post Method 15"},
411 /* 0x80 - 0xFF Reserved */
417 /* The WSP status codes are inherited from the HTTP status codes */
418 const value_string vals_status[] = {
419 /* 0x00 - 0x0F Reserved */
421 { 0x10, "100 Continue" },
422 { 0x11, "101 Switching Protocols" },
425 { 0x21, "201 Created" },
426 { 0x22, "202 Accepted" },
427 { 0x23, "203 Non-Authoritative Information" },
428 { 0x24, "204 No Content" },
429 { 0x25, "205 Reset Content" },
430 { 0x26, "206 Partial Content" },
432 { 0x30, "300 Multiple Choices" },
433 { 0x31, "301 Moved Permanently" },
434 { 0x32, "302 Moved Temporarily" },
435 { 0x33, "303 See Other" },
436 { 0x34, "304 Not Modified" },
437 { 0x35, "305 Use Proxy" },
438 { 0x37, "307 Temporary Redirect" },
440 { 0x40, "400 Bad Request" },
441 { 0x41, "401 Unauthorised" },
442 { 0x42, "402 Payment Required" },
443 { 0x43, "403 Forbidden" },
444 { 0x44, "404 Not Found" },
445 { 0x45, "405 Method Not Allowed" },
446 { 0x46, "406 Not Acceptable" },
447 { 0x47, "407 Proxy Authentication Required" },
448 { 0x48, "408 Request Timeout" },
449 { 0x49, "409 Conflict" },
450 { 0x4A, "410 Gone" },
451 { 0x4B, "411 Length Required" },
452 { 0x4C, "412 Precondition Failed" },
453 { 0x4D, "413 Request Entity Too Large" },
454 { 0x4E, "414 Request-URI Too Large" },
455 { 0x4F, "415 Unsupported Media Type" },
456 { 0x50, "416 Requested Range Not Satisfiable" },
457 { 0x51, "417 Expectation Failed" },
459 { 0x60, "500 Internal Server Error" },
460 { 0x61, "501 Not Implemented" },
461 { 0x62, "502 Bad Gateway" },
462 { 0x63, "503 Service Unavailable" },
463 { 0x64, "504 Gateway Timeout" },
464 { 0x65, "505 WSP/HTTP Version Not Supported" },
469 const value_string vals_wsp_reason_codes[] = {
470 { 0xE0, "Protocol Error (Illegal PDU)" },
471 { 0xE1, "Session disconnected" },
472 { 0xE2, "Session suspended" },
473 { 0xE3, "Session resumed" },
474 { 0xE4, "Peer congested" },
475 { 0xE5, "Session connect failed" },
476 { 0xE6, "Maximum receive unit size exceeded" },
477 { 0xE7, "Maximum outstanding requests exceeded" },
478 { 0xE8, "Peer request" },
479 { 0xE9, "Network error" },
480 { 0xEA, "User request" },
481 { 0xEB, "No specific cause, no retries" },
482 { 0xEC, "Push message cannot be delivered" },
483 { 0xED, "Push message discarded" },
484 { 0xEE, "Content type cannot be processed" },
492 #define FN_ACCEPT 0x00
493 #define FN_ACCEPT_CHARSET_DEP 0x01 /* encoding version 1.1, deprecated */
494 #define FN_ACCEPT_ENCODING_DEP 0x02 /* encoding version 1.1, deprecated */
495 #define FN_ACCEPT_LANGUAGE 0x03
496 #define FN_ACCEPT_RANGES 0x04
498 #define FN_ALLOW 0x06
499 #define FN_AUTHORIZATION 0x07
500 #define FN_CACHE_CONTROL_DEP 0x08 /* encoding version 1.1, deprecated */
501 #define FN_CONNECTION 0x09
502 #define FN_CONTENT_BASE 0x0A
503 #define FN_CONTENT_ENCODING 0x0B
504 #define FN_CONTENT_LANGUAGE 0x0C
505 #define FN_CONTENT_LENGTH 0x0D
506 #define FN_CONTENT_LOCATION 0x0E
507 #define FN_CONTENT_MD5 0x0F
508 #define FN_CONTENT_RANGE_DEP 0x10 /* encoding version 1.1, deprecated */
509 #define FN_CONTENT_TYPE 0x11
512 #define FN_EXPIRES 0x14
515 #define FN_IF_MODIFIED_SINCE 0x17
516 #define FN_IF_MATCH 0x18
517 #define FN_IF_NONE_MATCH 0x19
518 #define FN_IF_RANGE 0x1A
519 #define FN_IF_UNMODIFIED_SINCE 0x1B
520 #define FN_LOCATION 0x1C
521 #define FN_LAST_MODIFIED 0x1D
522 #define FN_MAX_FORWARDS 0x1E
523 #define FN_PRAGMA 0x1F
524 #define FN_PROXY_AUTHENTICATE 0x20
525 #define FN_PROXY_AUTHORIZATION 0x21
526 #define FN_PUBLIC 0x22
527 #define FN_RANGE 0x23
528 #define FN_REFERER 0x24
529 #define FN_RETRY_AFTER 0x25
530 #define FN_SERVER 0x26
531 #define FN_TRANSFER_ENCODING 0x27
532 #define FN_UPGRADE 0x28
533 #define FN_USER_AGENT 0x29
536 #define FN_WARNING 0x2C
537 #define FN_WWW_AUTHENTICATE 0x2D
538 #define FN_CONTENT_DISPOSITION 0x2E
539 #define FN_X_WAP_APPLICATION_ID 0x2F
540 #define FN_X_WAP_CONTENT_URI 0x30
541 #define FN_X_WAP_INITIATOR_URI 0x31
542 #define FN_ACCEPT_APPLICATION 0x32
543 #define FN_BEARER_INDICATION 0x33
544 #define FN_PUSH_FLAG 0x34
545 #define FN_PROFILE 0x35
546 #define FN_PROFILE_DIFF 0x36
547 #define FN_PROFILE_WARNING 0x37
548 #define FN_EXPECT 0x38
550 #define FN_TRAILER 0x3A
551 #define FN_ACCEPT_CHARSET 0x3B /* encoding version 1.3 */
552 #define FN_ACCEPT_ENCODING 0x3C /* encoding version 1.3 */
553 #define FN_CACHE_CONTROL 0x3D /* encoding version 1.3 */
554 #define FN_CONTENT_RANGE 0x3E /* encoding version 1.3 */
555 #define FN_X_WAP_TOD 0x3F
556 #define FN_CONTENT_ID 0x40
557 #define FN_SET_COOKIE 0x41
558 #define FN_COOKIE 0x42
559 #define FN_ENCODING_VERSION 0x43
560 #define FN_PROFILE_WARNING14 0x44 /* encoding version 1.4 */
561 #define FN_CONTENT_DISPOSITION14 0x45 /* encoding version 1.4 */
562 #define FN_X_WAP_SECURITY 0x46
563 #define FN_CACHE_CONTROL14 0x47 /* encoding version 1.4 */
564 #define FN_EXPECT15 0x48 /* encoding version 1.5 */
565 #define FN_X_WAP_LOC_INVOCATION 0x49
566 #define FN_X_WAP_LOC_DELIVERY 0x4A
570 * Openwave field names.
572 #define FN_OPENWAVE_PROXY_PUSH_ADDR 0x00
573 #define FN_OPENWAVE_PROXY_PUSH_ACCEPT 0x01
574 #define FN_OPENWAVE_PROXY_PUSH_SEQ 0x02
575 #define FN_OPENWAVE_PROXY_NOTIFY 0x03
576 #define FN_OPENWAVE_PROXY_OPERATOR_DOMAIN 0x04
577 #define FN_OPENWAVE_PROXY_HOME_PAGE 0x05
578 #define FN_OPENWAVE_DEVCAP_HAS_COLOR 0x06
579 #define FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS 0x07
580 #define FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE 0x08
581 #define FN_OPENWAVE_DEVCAP_SCREEN_CHARS 0x09
582 #define FN_OPENWAVE_DEVCAP_SCREEN_PIXELS 0x0A
583 #define FN_OPENWAVE_DEVCAP_EM_SIZE 0x0B
584 #define FN_OPENWAVE_DEVCAP_SCREEN_DEPTH 0x0C
585 #define FN_OPENWAVE_DEVCAP_IMMED_ALERT 0x0D
586 #define FN_OPENWAVE_PROXY_NET_ASK 0x0E
587 #define FN_OPENWAVE_PROXY_UPLINK_VERSION 0x0F
588 #define FN_OPENWAVE_PROXY_TOD 0x10
589 #define FN_OPENWAVE_PROXY_BA_ENABLE 0x11
590 #define FN_OPENWAVE_PROXY_BA_REALM 0x12
591 #define FN_OPENWAVE_PROXY_REDIRECT_ENABLE 0x13
592 #define FN_OPENWAVE_PROXY_REQUEST_URI 0x14
593 #define FN_OPENWAVE_PROXY_REDIRECT_STATUS 0x15
594 #define FN_OPENWAVE_PROXY_TRANS_CHARSET 0x16
595 #define FN_OPENWAVE_PROXY_LINGER 0x17
596 #define FN_OPENWAVE_PROXY_CLIENT_ID 0x18
597 #define FN_OPENWAVE_PROXY_ENABLE_TRUST 0x19
598 #define FN_OPENWAVE_PROXY_TRUST_OLD 0x1A
599 #define FN_OPENWAVE_PROXY_TRUST 0x20
600 #define FN_OPENWAVE_PROXY_BOOKMARK 0x21
601 #define FN_OPENWAVE_DEVCAP_GUI 0x22
603 static const value_string vals_openwave_field_names[] = {
604 { FN_OPENWAVE_PROXY_PUSH_ADDR, "x-up-proxy-push-addr" },
605 { FN_OPENWAVE_PROXY_PUSH_ACCEPT, "x-up-proxy-push-accept" },
606 { FN_OPENWAVE_PROXY_PUSH_SEQ, "x-up-proxy-seq" },
607 { FN_OPENWAVE_PROXY_NOTIFY, "x-up-proxy-notify" },
608 { FN_OPENWAVE_PROXY_OPERATOR_DOMAIN, "x-up-proxy-operator-domain" },
609 { FN_OPENWAVE_PROXY_HOME_PAGE, "x-up-proxy-home-page" },
610 { FN_OPENWAVE_DEVCAP_HAS_COLOR, "x-up-devcap-has-color" },
611 { FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS, "x-up-devcap-num-softkeys" },
612 { FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE, "x-up-devcap-softkey-size" },
613 { FN_OPENWAVE_DEVCAP_SCREEN_CHARS, "x-up-devcap-screen-chars" },
614 { FN_OPENWAVE_DEVCAP_SCREEN_PIXELS, "x-up-devcap-screen-pixels" },
615 { FN_OPENWAVE_DEVCAP_EM_SIZE, "x-up-devcap-em-size" },
616 { FN_OPENWAVE_DEVCAP_SCREEN_DEPTH, "x-up-devcap-screen-depth" },
617 { FN_OPENWAVE_DEVCAP_IMMED_ALERT, "x-up-devcap-immed-alert" },
618 { FN_OPENWAVE_PROXY_NET_ASK, "x-up-proxy-net-ask" },
619 { FN_OPENWAVE_PROXY_UPLINK_VERSION, "x-up-proxy-uplink-version" },
620 { FN_OPENWAVE_PROXY_TOD, "x-up-proxy-tod" },
621 { FN_OPENWAVE_PROXY_BA_ENABLE, "x-up-proxy-ba-enable" },
622 { FN_OPENWAVE_PROXY_BA_REALM, "x-up-proxy-ba-realm" },
623 { FN_OPENWAVE_PROXY_REDIRECT_ENABLE, "x-up-proxy-redirect-enable" },
624 { FN_OPENWAVE_PROXY_REQUEST_URI, "x-up-proxy-request-uri" },
625 { FN_OPENWAVE_PROXY_REDIRECT_STATUS, "x-up-proxy-redirect-status" },
626 { FN_OPENWAVE_PROXY_TRANS_CHARSET, "x-up-proxy-trans-charset" },
627 { FN_OPENWAVE_PROXY_LINGER, "x-up-proxy-linger" },
628 { FN_OPENWAVE_PROXY_CLIENT_ID, "x-up-proxy-client-id" },
629 { FN_OPENWAVE_PROXY_ENABLE_TRUST, "x-up-proxy-enable-trust" },
630 { FN_OPENWAVE_PROXY_TRUST_OLD, "x-up-proxy-trust-old" },
631 { FN_OPENWAVE_PROXY_TRUST, "x-up-proxy-trust" },
632 { FN_OPENWAVE_PROXY_BOOKMARK, "x-up-proxy-bookmark" },
633 { FN_OPENWAVE_DEVCAP_GUI, "x-up-devcap-gui" },
638 static const value_string vals_field_names[] = {
639 { FN_ACCEPT, "Accept" },
640 { FN_ACCEPT_CHARSET_DEP, "Accept-Charset (encoding 1.1)" },
641 { FN_ACCEPT_ENCODING_DEP, "Accept-Encoding (encoding 1.1)" },
642 { FN_ACCEPT_LANGUAGE, "Accept-Language" },
643 { FN_ACCEPT_RANGES, "Accept-Ranges" },
645 { FN_ALLOW, "Allow" },
646 { FN_AUTHORIZATION, "Authorization" },
647 { FN_CACHE_CONTROL_DEP, "Cache-Control (encoding 1.1)" },
648 { FN_CONNECTION, "Connection" },
649 { FN_CONTENT_BASE, "Content-Base" },
650 { FN_CONTENT_ENCODING, "Content-Encoding" },
651 { FN_CONTENT_LANGUAGE, "Content-Language" },
652 { FN_CONTENT_LENGTH, "Content-Length" },
653 { FN_CONTENT_LOCATION, "Content-Location" },
654 { FN_CONTENT_MD5, "Content-MD5" },
655 { FN_CONTENT_RANGE_DEP, "Content-Range (encoding 1.1)" },
656 { FN_CONTENT_TYPE, "Content-Type" },
659 { FN_EXPIRES, "Expires" },
662 { FN_IF_MODIFIED_SINCE, "If-Modified-Since" },
663 { FN_IF_MATCH, "If-Match" },
664 { FN_IF_NONE_MATCH, "If-None-Match" },
665 { FN_IF_RANGE, "If-Range" },
666 { FN_IF_UNMODIFIED_SINCE, "If-Unmodified-Since" },
667 { FN_LOCATION, "Location" },
668 { FN_LAST_MODIFIED, "Last-Modified" },
669 { FN_MAX_FORWARDS, "Max-Forwards" },
670 { FN_PRAGMA, "Pragma" },
671 { FN_PROXY_AUTHENTICATE, "Proxy-Authenticate" },
672 { FN_PROXY_AUTHORIZATION, "Proxy-Authorization" },
673 { FN_PUBLIC, "Public" },
674 { FN_RANGE, "Range" },
675 { FN_REFERER, "Referer" },
676 { FN_RETRY_AFTER, "Retry-After" },
677 { FN_SERVER, "Server" },
678 { FN_TRANSFER_ENCODING, "Transfer-Encoding" },
679 { FN_UPGRADE, "Upgrade" },
680 { FN_USER_AGENT, "User-Agent" },
683 { FN_WARNING, "Warning" },
684 { FN_WWW_AUTHENTICATE, "WWW-Authenticate" },
685 { FN_CONTENT_DISPOSITION, "Content-Disposition" },
686 { FN_X_WAP_APPLICATION_ID, "X-Wap-Application-ID" },
687 { FN_X_WAP_CONTENT_URI, "X-Wap-Content-URI" },
688 { FN_X_WAP_INITIATOR_URI, "X-Wap-Initiator-URI" },
689 { FN_ACCEPT_APPLICATION, "Accept-Application" },
690 { FN_BEARER_INDICATION, "Bearer-Indication" },
691 { FN_PUSH_FLAG, "Push-Flag" },
692 { FN_PROFILE, "Profile" },
693 { FN_PROFILE_DIFF, "Profile-Diff" },
694 { FN_PROFILE_WARNING, "Profile-Warning" },
695 { FN_EXPECT, "Expect" },
697 { FN_TRAILER, "Trailer" },
698 { FN_ACCEPT_CHARSET, "Accept-Charset" },
699 { FN_ACCEPT_ENCODING, "Accept-Encoding" },
700 { FN_CACHE_CONTROL, "Cache-Control" },
701 { FN_CONTENT_RANGE, "Content-Range" },
702 { FN_X_WAP_TOD, "X-Wap-Tod" },
703 { FN_CONTENT_ID, "Content-ID" },
704 { FN_SET_COOKIE, "Set-Cookie" },
705 { FN_COOKIE, "Cookie" },
706 { FN_ENCODING_VERSION, "Encoding-Version" },
707 { FN_PROFILE_WARNING14, "Profile-Warning (encoding 1.4)" },
708 { FN_CONTENT_DISPOSITION14,"Content-Disposition (encoding 1.4)" },
709 { FN_X_WAP_SECURITY, "X-WAP-Security" },
710 { FN_CACHE_CONTROL14, "Cache-Control (encoding 1.4)" },
711 /* encoding-version 1.5 */
712 { FN_EXPECT15, "Expect (encoding 1.5)" },
713 { FN_X_WAP_LOC_INVOCATION, "X-Wap-Loc-Invocation" },
714 { FN_X_WAP_LOC_DELIVERY, "X-Wap-Loc-Delivery" },
719 * Bearer types (from the WDP specification).
723 #define BT_GSM_USSD 0x02
724 #define BT_GSM_SMS 0x03
725 #define BT_ANSI_136_GUTS 0x04
726 #define BT_IS_95_SMS 0x05
727 #define BT_IS_95_CSD 0x06
728 #define BT_IS_95_PACKET_DATA 0x07
729 #define BT_ANSI_136_CSD 0x08
730 #define BT_ANSI_136_PACKET_DATA 0x09
731 #define BT_GSM_CSD 0x0A
732 #define BT_GSM_GPRS 0x0B
733 #define BT_GSM_USSD_IPv4 0x0C
734 #define BT_AMPS_CDPD 0x0D
735 #define BT_PDC_CSD 0x0E
736 #define BT_PDC_PACKET_DATA 0x0F
737 #define BT_IDEN_SMS 0x10
738 #define BT_IDEN_CSD 0x11
739 #define BT_IDEN_PACKET_DATA 0x12
740 #define BT_PAGING_FLEX 0x13
741 #define BT_PHS_SMS 0x14
742 #define BT_PHS_CSD 0x15
743 #define BT_GSM_USSD_GSM_SC 0x16
744 #define BT_TETRA_SDS_ITSI 0x17
745 #define BT_TETRA_SDS_MSISDN 0x18
746 #define BT_TETRA_PACKET_DATA 0x19
747 #define BT_PAGING_REFLEX 0x1A
748 #define BT_GSM_USSD_MSISDN 0x1B
749 #define BT_MOBITEX_MPAK 0x1C
750 #define BT_ANSI_136_GHOST 0x1D
752 static const value_string vals_bearer_types[] = {
755 { BT_GSM_USSD, "GSM USSD" },
756 { BT_GSM_SMS, "GSM SMS" },
757 { BT_ANSI_136_GUTS, "ANSI-136 GUTS/R-Data" },
758 { BT_IS_95_SMS, "IS-95 CDMA SMS" },
759 { BT_IS_95_CSD, "IS-95 CDMA CSD" },
760 { BT_IS_95_PACKET_DATA, "IS-95 CDMA Packet data" },
761 { BT_ANSI_136_CSD, "ANSI-136 CSD" },
762 { BT_ANSI_136_PACKET_DATA, "ANSI-136 Packet data" },
763 { BT_GSM_CSD, "GSM CSD" },
764 { BT_GSM_GPRS, "GSM GPRS" },
765 { BT_GSM_USSD_IPv4, "GSM USSD (IPv4 addresses)" },
766 { BT_AMPS_CDPD, "AMPS CDPD" },
767 { BT_PDC_CSD, "PDC CSD" },
768 { BT_PDC_PACKET_DATA, "PDC Packet data" },
769 { BT_IDEN_SMS, "IDEN SMS" },
770 { BT_IDEN_CSD, "IDEN CSD" },
771 { BT_IDEN_PACKET_DATA, "IDEN Packet data" },
772 { BT_PAGING_FLEX, "Paging network FLEX(TM)" },
773 { BT_PHS_SMS, "PHS SMS" },
774 { BT_PHS_CSD, "PHS CSD" },
775 { BT_GSM_USSD_GSM_SC, "GSM USSD (GSM Service Code addresses)" },
776 { BT_TETRA_SDS_ITSI, "TETRA SDS (ITSI addresses)" },
777 { BT_TETRA_SDS_MSISDN, "TETRA SDS (MSISDN addresses)" },
778 { BT_TETRA_PACKET_DATA, "TETRA Packet data" },
779 { BT_PAGING_REFLEX, "Paging network ReFLEX(TM)" },
780 { BT_GSM_USSD_MSISDN, "GSM USSD (MSISDN addresses)" },
781 { BT_MOBITEX_MPAK, "Mobitex MPAK" },
782 { BT_ANSI_136_GHOST, "ANSI-136 GHOST/R-Data" },
786 static const value_string vals_content_types[] = {
787 /* Well-known media types */
790 { 0x02, "text/html" },
791 { 0x03, "text/plain" },
792 { 0x04, "text/x-hdml" },
793 { 0x05, "text/x-ttml" },
794 { 0x06, "text/x-vCalendar" },
795 { 0x07, "text/x-vCard" },
796 { 0x08, "text/vnd.wap.wml" },
797 { 0x09, "text/vnd.wap.wmlscript" },
798 { 0x0A, "text/vnd.wap.channel" },
799 { 0x0B, "multipart/*" },
800 { 0x0C, "multipart/mixed" },
801 { 0x0D, "multipart/form-data" },
802 { 0x0E, "multipart/byteranges" },
803 { 0x0F, "multipart/alternative" },
804 { 0x10, "application/*" },
805 { 0x11, "application/java-vm" },
806 { 0x12, "application/x-www-form-urlencoded" },
807 { 0x13, "application/x-hdmlc" },
808 { 0x14, "application/vnd.wap.wmlc" },
809 { 0x15, "application/vnd.wap.wmlscriptc" },
810 { 0x16, "application/vnd.wap.channelc" },
811 { 0x17, "application/vnd.wap.uaprof" },
812 { 0x18, "application/vnd.wap.wtls-ca-certificate" },
813 { 0x19, "application/vnd.wap.wtls-user-certificate" },
814 { 0x1A, "application/x-x509-ca-cert" },
815 { 0x1B, "application/x-x509-user-cert" },
817 { 0x1D, "image/gif" },
818 { 0x1E, "image/jpeg" },
819 { 0x1F, "image/tiff" },
820 { 0x20, "image/png" },
821 { 0x21, "image/vnd.wap.wbmp" },
822 { 0x22, "application/vnd.wap.multipart.*" },
823 { 0x23, "application/vnd.wap.multipart.mixed" },
824 { 0x24, "application/vnd.wap.multipart.form-data" },
825 { 0x25, "application/vnd.wap.multipart.byteranges" },
826 { 0x26, "application/vnd.wap.multipart.alternative" },
827 { 0x27, "application/xml" },
828 { 0x28, "text/xml" },
829 { 0x29, "application/vnd.wap.wbxml" },
830 { 0x2A, "application/x-x968-cross-cert" },
831 { 0x2B, "application/x-x968-ca-cert" },
832 { 0x2C, "application/x-x968-user-cert" },
833 { 0x2D, "text/vnd.wap.si" },
834 { 0x2E, "application/vnd.wap.sic" },
835 { 0x2F, "text/vnd.wap.sl" },
836 { 0x30, "application/vnd.wap.slc" },
837 { 0x31, "text/vnd.wap.co" },
838 { 0x32, "application/vnd.wap.coc" },
839 { 0x33, "application/vnd.wap.multipart.related" },
840 { 0x34, "application/vnd.wap.sia" },
841 { 0x35, "text/vnd.wap.connectivity-xml" },
842 { 0x36, "application/vnd.wap.connectivity-wbxml" },
843 { 0x37, "application/pkcs7-mime" },
844 { 0x38, "application/vnd.wap.hashed-certificate" },
845 { 0x39, "application/vnd.wap.signed-certificate" },
846 { 0x3A, "application/vnd.wap.cert-response" },
847 { 0x3B, "application/xhtml+xml" },
848 { 0x3C, "application/wml+xml" },
849 { 0x3D, "text/css" },
850 { 0x3E, "application/vnd.wap.mms-message" },
851 { 0x3F, "application/vnd.wap.rollover-certificate" },
852 { 0x40, "application/vnd.wap.locc+wbxml"},
853 { 0x41, "application/vnd.wap.loc+xml"},
854 { 0x42, "application/vnd.syncml.dm+wbxml"},
855 { 0x43, "application/vnd.syncml.dm+xml"},
856 { 0x44, "application/vnd.syncml.notification"},
857 { 0x45, "application/vnd.wap.xhtml+xml"},
858 { 0x46, "application/vnd.wv.csp.cir"},
859 { 0x47, "application/vnd.oma.dd+xml"},
860 { 0x48, "application/vnd.oma.drm.message"},
861 { 0x49, "application/vnd.oma.drm.content"},
862 { 0x4A, "application/vnd.oma.drm.rights+xml"},
863 { 0x4B, "application/vnd.oma.drm.rights+wbxml"},
864 { 0x4C, "application/vnd.wv.csp+xml"},
865 { 0x4D, "application/vnd.wv.csp+wbxml"},
866 /* The following media types are registered by 3rd parties */
867 { 0x0201, "application/vnd.uplanet.cachop-wbxml" },
868 { 0x0202, "application/vnd.uplanet.signal" },
869 { 0x0203, "application/vnd.uplanet.alert-wbxml" },
870 { 0x0204, "application/vnd.uplanet.list-wbxml" },
871 { 0x0205, "application/vnd.uplanet.listcmd-wbxml" },
872 { 0x0206, "application/vnd.uplanet.channel-wbxml" },
873 { 0x0207, "application/vnd.uplanet.provisioning-status-uri" },
874 { 0x0208, "x-wap.multipart/vnd.uplanet.header-set" },
875 { 0x0209, "application/vnd.uplanet.bearer-choice-wbxml" },
876 { 0x020A, "application/vnd.phonecom.mmc-wbxml" },
877 { 0x020B, "application/vnd.nokia.syncset+wbxml" },
878 { 0x020C, "image/x-up-wpng"},
879 { 0x0300, "application/iota.mmc-wbxml"},
880 { 0x0301, "application/iota.mmc-xml"},
884 static const value_string vals_languages[] = {
885 { 0x01, "Afar (aa)" },
886 { 0x02, "Abkhazian (ab)" },
887 { 0x03, "Afrikaans (af)" },
888 { 0x04, "Amharic (am)" },
889 { 0x05, "Arabic (ar)" },
890 { 0x06, "Assamese (as)" },
891 { 0x07, "Aymara (ay)" },
892 { 0x08, "Azerbaijani (az)" },
893 { 0x09, "Bashkir (ba)" },
894 { 0x0A, "Byelorussian (be)" },
895 { 0x0B, "Bulgarian (bg)" },
896 { 0x0C, "Bihari (bh)" },
897 { 0x0D, "Bislama (bi)" },
898 { 0x0E, "Bengali; Bangla (bn)" },
899 { 0x0F, "Tibetan (bo)" },
900 { 0x10, "Breton (br)" },
901 { 0x11, "Catalan (ca)" },
902 { 0x12, "Corsican (co)" },
903 { 0x13, "Czech (cs)" },
904 { 0x14, "Welsh (cy)" },
905 { 0x15, "Danish (da)" },
906 { 0x16, "German (de)" },
907 { 0x17, "Bhutani (dz)" },
908 { 0x18, "Greek (el)" },
909 { 0x19, "English (en)" },
910 { 0x1A, "Esperanto (eo)" },
911 { 0x1B, "Spanish (es)" },
912 { 0x1C, "Estonian (et)" },
913 { 0x1D, "Basque (eu)" },
914 { 0x1E, "Persian (fa)" },
915 { 0x1F, "Finnish (fi)" },
916 { 0x20, "Fiji (fj)" },
917 { 0x21, "Urdu (ur)" },
918 { 0x22, "French (fr)" },
919 { 0x23, "Uzbek (uz)" },
920 { 0x24, "Irish (ga)" },
921 { 0x25, "Scots Gaelic (gd)" },
922 { 0x26, "Galician (gl)" },
923 { 0x27, "Guarani (gn)" },
924 { 0x28, "Gujarati (gu)" },
925 { 0x29, "Hausa (ha)" },
926 { 0x2A, "Hebrew (formerly iw) (he)" },
927 { 0x2B, "Hindi (hi)" },
928 { 0x2C, "Croatian (hr)" },
929 { 0x2D, "Hungarian (hu)" },
930 { 0x2E, "Armenian (hy)" },
931 { 0x2F, "Vietnamese (vi)" },
932 { 0x30, "Indonesian (formerly in) (id)" },
933 { 0x31, "Wolof (wo)" },
934 { 0x32, "Xhosa (xh)" },
935 { 0x33, "Icelandic (is)" },
936 { 0x34, "Italian (it)" },
937 { 0x35, "Yoruba (yo)" },
938 { 0x36, "Japanese (ja)" },
939 { 0x37, "Javanese (jw)" },
940 { 0x38, "Georgian (ka)" },
941 { 0x39, "Kazakh (kk)" },
942 { 0x3A, "Zhuang (za)" },
943 { 0x3B, "Cambodian (km)" },
944 { 0x3C, "Kannada (kn)" },
945 { 0x3D, "Korean (ko)" },
946 { 0x3E, "Kashmiri (ks)" },
947 { 0x3F, "Kurdish (ku)" },
948 { 0x40, "Kirghiz (ky)" },
949 { 0x41, "Chinese (zh)" },
950 { 0x42, "Lingala (ln)" },
951 { 0x43, "Laothian (lo)" },
952 { 0x44, "Lithuanian (lt)" },
953 { 0x45, "Latvian, Lettish (lv)" },
954 { 0x46, "Malagasy (mg)" },
955 { 0x47, "Maori (mi)" },
956 { 0x48, "Macedonian (mk)" },
957 { 0x49, "Malayalam (ml)" },
958 { 0x4A, "Mongolian (mn)" },
959 { 0x4B, "Moldavian (mo)" },
960 { 0x4C, "Marathi (mr)" },
961 { 0x4D, "Malay (ms)" },
962 { 0x4E, "Maltese (mt)" },
963 { 0x4F, "Burmese (my)" },
964 { 0x50, "Ukrainian (uk)" },
965 { 0x51, "Nepali (ne)" },
966 { 0x52, "Dutch (nl)" },
967 { 0x53, "Norwegian (no)" },
968 { 0x54, "Occitan (oc)" },
969 { 0x55, "(Afan) Oromo (om)" },
970 { 0x56, "Oriya (or)" },
971 { 0x57, "Punjabi (pa)" },
972 { 0x58, "Polish (po)" },
973 { 0x59, "Pashto, Pushto (ps)" },
974 { 0x5A, "Portuguese (pt)" },
975 { 0x5B, "Quechua (qu)" },
976 { 0x5C, "Zulu (zu)" },
977 { 0x5D, "Kirundi (rn)" },
978 { 0x5E, "Romanian (ro)" },
979 { 0x5F, "Russian (ru)" },
980 { 0x60, "Kinyarwanda (rw)" },
981 { 0x61, "Sanskrit (sa)" },
982 { 0x62, "Sindhi (sd)" },
983 { 0x63, "Sangho (sg)" },
984 { 0x64, "Serbo-Croatian (sh)" },
985 { 0x65, "Sinhalese (si)" },
986 { 0x66, "Slovak (sk)" },
987 { 0x67, "Slovenian (sl)" },
988 { 0x68, "Samoan (sm)" },
989 { 0x69, "Shona (sn)" },
990 { 0x6A, "Somali (so)" },
991 { 0x6B, "Albanian (sq)" },
992 { 0x6C, "Serbian (sr)" },
993 { 0x6D, "Siswati (ss)" },
994 { 0x6E, "Sesotho (st)" },
995 { 0x6F, "Sundanese (su)" },
996 { 0x70, "Swedish (sv)" },
997 { 0x71, "Swahili (sw)" },
998 { 0x72, "Tamil (ta)" },
999 { 0x73, "Telugu (te)" },
1000 { 0x74, "Tajik (tg)" },
1001 { 0x75, "Thai (th)" },
1002 { 0x76, "Tigrinya (ti)" },
1003 { 0x77, "Turkmen (tk)" },
1004 { 0x78, "Tagalog (tl)" },
1005 { 0x79, "Setswana (tn)" },
1006 { 0x7A, "Tonga (to)" },
1007 { 0x7B, "Turkish (tr)" },
1008 { 0x7C, "Tsonga (ts)" },
1009 { 0x7D, "Tatar (tt)" },
1010 { 0x7E, "Twi (tw)" },
1011 { 0x7F, "Uighur (ug)" },
1012 { 0x81, "Nauru (na)" },
1013 { 0x82, "Faeroese (fo)" },
1014 { 0x83, "Frisian (fy)" },
1015 { 0x84, "Interlingua (ia)" },
1016 { 0x85, "Volapuk (vo)" },
1017 { 0x86, "Interlingue (ie)" },
1018 { 0x87, "Inupiak (ik)" },
1019 { 0x88, "Yiddish (formerly ji) (yi)" },
1020 { 0x89, "Inuktitut (iu)" },
1021 { 0x8A, "Greenlandic (kl)" },
1022 { 0x8B, "Latin (la)" },
1023 { 0x8C, "Rhaeto-Romance (rm)" },
1028 #define CACHE_CONTROL_NO_CACHE 0x00
1029 #define CACHE_CONTROL_NO_STORE 0x01
1030 #define CACHE_CONTROL_MAX_AGE 0x02
1031 #define CACHE_CONTROL_MAX_STALE 0x03
1032 #define CACHE_CONTROL_MIN_FRESH 0x04
1033 #define CACHE_CONTROL_ONLY_IF_CACHED 0x05
1034 #define CACHE_CONTROL_PUBLIC 0x06
1035 #define CACHE_CONTROL_PRIVATE 0x07
1036 #define CACHE_CONTROL_NO_TRANSFORM 0x08
1037 #define CACHE_CONTROL_MUST_REVALIDATE 0x09
1038 #define CACHE_CONTROL_PROXY_REVALIDATE 0x0A
1039 #define CACHE_CONTROL_S_MAXAGE 0x0B
1041 static const value_string vals_cache_control[] = {
1042 { CACHE_CONTROL_NO_CACHE, "no-cache" },
1043 { CACHE_CONTROL_NO_STORE, "no-store" },
1044 { CACHE_CONTROL_MAX_AGE, "max-age" },
1045 { CACHE_CONTROL_MAX_STALE, "max-stale" },
1046 { CACHE_CONTROL_MIN_FRESH, "min-fresh" },
1047 { CACHE_CONTROL_ONLY_IF_CACHED, "only-if-cached" },
1048 { CACHE_CONTROL_PUBLIC, "public" },
1049 { CACHE_CONTROL_PRIVATE, "private" },
1050 { CACHE_CONTROL_NO_TRANSFORM, "no-transform" },
1051 { CACHE_CONTROL_MUST_REVALIDATE, "must-revalidate" },
1052 { CACHE_CONTROL_PROXY_REVALIDATE, "proxy-revalidate" },
1053 { CACHE_CONTROL_S_MAXAGE, "s-max-age" },
1058 static const value_string vals_wap_application_ids[] = {
1059 /* Well-known WAP applications */
1060 { 0x00, "x-wap-application:*"},
1061 { 0x01, "x-wap-application:push.sia"},
1062 { 0x02, "x-wap-application:wml.ua"},
1063 { 0x03, "x-wap-application:wta.ua"},
1064 { 0x04, "x-wap-application:mms.ua"},
1065 { 0x05, "x-wap-application:push.syncml"},
1066 { 0x06, "x-wap-application:loc.ua"},
1067 { 0x07, "x-wap-application:syncml.dm"},
1068 { 0x08, "x-wap-application:drm.ua"},
1069 { 0x09, "x-wap-application:emn.ua"},
1070 { 0x0A, "x-wap-application:wv.ua"},
1071 /* Registered by 3rd parties */
1072 { 0x8000, "x-wap-microsoft:localcontent.ua"},
1073 { 0x8001, "x-wap-microsoft:IMclient.ua"},
1074 { 0x8002, "x-wap-docomo:imode.mail.ua"},
1075 { 0x8003, "x-wap-docomo:imode.mr.ua"},
1076 { 0x8004, "x-wap-docomo:imode.mf.ua"},
1077 { 0x8005, "x-motorola:location.ua"},
1078 { 0x8006, "x-motorola:now.ua"},
1079 { 0x8007, "x-motorola:otaprov.ua"},
1080 { 0x8008, "x-motorola:browser.ua"},
1081 { 0x8009, "x-motorola:splash.ua"},
1082 /* 0x800A: unassigned */
1083 { 0x800B, "x-wap-nai:mvsw.command"},
1084 /* 0x800C -- 0x800F: unassigned */
1085 { 0x8010, "x-wap-openwave:iota.ua"},
1086 /* 0x8011 -- 0x8FFF: unassigned */
1087 { 0x9000, "x-wap-docomo:imode.mail2.ua"},
1088 { 0x9001, "x-oma-nec:otaprov.ua"},
1089 { 0x9002, "x-oma-nokia:call.ua"},
1090 { 0x9003, "x-oma-coremobility:sqa.ua"},
1096 /* Parameters and well-known encodings */
1097 static const value_string vals_wsp_parameter_sec[] = {
1098 { 0x00, "NETWPIN" },
1099 { 0x01, "USERPIN" },
1100 { 0x02, "USERNETWPIN" },
1101 { 0x03, "USERPINMAC" },
1106 /* Warning codes and mappings */
1107 static const value_string vals_wsp_warning_code[] = {
1108 { 10, "110 Response is stale" },
1109 { 11, "111 Revalidation failed" },
1110 { 12, "112 Disconnected operation" },
1111 { 13, "113 Heuristic expiration" },
1112 { 14, "214 Transformation applied" },
1113 { 99, "199/299 Miscellaneous warning" },
1118 static const value_string vals_wsp_warning_code_short[] = {
1129 /* Profile-Warning codes - see http://www.w3.org/TR/NOTE-CCPPexchange */
1130 static const value_string vals_wsp_profile_warning_code[] = {
1132 { 0x11, "101 Used stale profile" },
1133 { 0x12, "102 Not used profile" },
1134 { 0x20, "200 Not applied" },
1135 { 0x21, "101 Content selection applied" },
1136 { 0x22, "202 Content generation applied" },
1137 { 0x23, "203 Transformation applied" },
1142 /* Well-known TE values */
1143 static const value_string vals_well_known_te[] = {
1144 { 0x82, "chunked" },
1145 { 0x83, "identity" },
1147 { 0x85, "compress" },
1148 { 0x86, "deflate" },
1157 #define PERMANENT_REDIRECT 0x80
1158 #define REUSE_SECURITY_SESSION 0x40
1161 * Redirect address flags and length.
1163 #define BEARER_TYPE_INCLUDED 0x80
1164 #define PORT_NUMBER_INCLUDED 0x40
1165 #define ADDRESS_LEN 0x3f
1167 static const true_false_string yes_no_truth = {
1172 static const value_string vals_false_true[] = {
1179 WSP_PDU_RESERVED = 0x00,
1180 WSP_PDU_CONNECT = 0x01,
1181 WSP_PDU_CONNECTREPLY = 0x02,
1182 WSP_PDU_REDIRECT = 0x03, /* No sample data */
1183 WSP_PDU_REPLY = 0x04,
1184 WSP_PDU_DISCONNECT = 0x05,
1185 WSP_PDU_PUSH = 0x06, /* No sample data */
1186 WSP_PDU_CONFIRMEDPUSH = 0x07, /* No sample data */
1187 WSP_PDU_SUSPEND = 0x08, /* No sample data */
1188 WSP_PDU_RESUME = 0x09, /* No sample data */
1191 WSP_PDU_OPTIONS = 0x41, /* No sample data */
1192 WSP_PDU_HEAD = 0x42, /* No sample data */
1193 WSP_PDU_DELETE = 0x43, /* No sample data */
1194 WSP_PDU_TRACE = 0x44, /* No sample data */
1196 WSP_PDU_POST = 0x60,
1197 WSP_PDU_PUT = 0x61 /* No sample data */
1201 /* Dissector tables for handoff */
1202 static dissector_table_t media_type_table;
1203 static heur_dissector_list_t heur_subdissector_list;
1205 static void add_uri (proto_tree *, packet_info *, tvbuff_t *, guint, guint);
1207 static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
1208 static void add_multipart_data (proto_tree *, tvbuff_t *);
1210 static void add_capabilities (proto_tree *tree, tvbuff_t *tvb, guint8 pdu_type);
1214 * Dissect the WSP header part.
1215 * This function calls wkh_XXX functions that dissect well-known headers.
1217 static void add_headers (proto_tree *tree, tvbuff_t *tvb, int hf);
1219 /* The following macros define WSP basic data structures as found
1220 * in the ABNF notation of WSP headers.
1221 * Currently all text data types are mapped to text_string.
1223 #define is_short_integer(x) ( (x) & 0x80 )
1224 #define is_long_integer(x) ( (x) <= 30 )
1225 #define is_date_value(x) is_long_integer(x)
1226 #define is_integer_value(x) (is_short_integer(x) || is_long_integer(x))
1227 #define is_delta_seconds_value(x) is_integer_value(x)
1228 /* Text string == *TEXT 0x00, thus also an empty string matches the rule! */
1229 #define is_text_string(x) ( ((x) == 0) || ( ((x) >= 32) && ((x) <= 127)) )
1230 #define is_quoted_string(x) ( (x) == 0x22 ) /* " */
1231 #define is_token_text(x) is_text_string(x)
1232 #define is_text_value(x) is_text_string(x)
1233 #define is_uri_value(x) is_text_string(x)
1235 #define get_uintvar_integer(val,tvb,start,len,ok) \
1236 val = tvb_get_guintvar(tvb,start,&len); \
1237 if (len>5) ok = FALSE; else ok = TRUE;
1238 #define get_short_integer(val,tvb,start,len,ok) \
1239 val = tvb_get_guint8(tvb,start); \
1240 if (val & 0x80) ok = TRUE; else ok=FALSE; \
1241 val &= 0x7F; len = 1;
1242 #define get_long_integer(val,tvb,start,len,ok) \
1243 len = tvb_get_guint8(tvb,start); \
1244 ok = TRUE; /* Valid lengths for us are 1-4 */ \
1245 if (len==1) { val = tvb_get_guint8(tvb,start+1); } \
1246 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \
1247 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \
1248 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \
1250 len++; /* Add the 1st octet to the length */
1251 #define get_integer_value(val,tvb,start,len,ok) \
1252 len = tvb_get_guint8(tvb,start); \
1254 if (len & 0x80) { val = len & 0x7F; len = 0; } \
1255 else if (len==1) { val = tvb_get_guint8(tvb,start+1); } \
1256 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \
1257 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \
1258 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \
1260 len++; /* Add the 1st octet to the length */
1261 #define get_date_value(val,tvb,start,len,ok) \
1262 get_long_integer(val,tvb,start,len,ok)
1263 #define get_delta_seconds_value(val,tvb,start,len,ok) \
1264 get_integer_value(val,tvb,start,len,ok)
1266 /* NOTE - Don't forget to g_free() the str value after its usage as the
1267 * tvb_get_string[z]() functions return g_malloc()ed memory! */
1268 #define get_text_string(str,tvb,start,len,ok) \
1269 if (is_text_string(tvb_get_guint8(tvb,start))) { \
1270 str = tvb_get_stringz(tvb,start,&len); \
1273 } else { len = 0; str = NULL; ok = FALSE; }
1274 #define get_token_text(str,tvb,start,len,ok) \
1275 get_text_string(str,tvb,start,len,ok)
1276 #define get_extension_media(str,tvb,start,len,ok) \
1277 get_text_string(str,tvb,start,len,ok)
1278 #define get_text_value(str,tvb,start,len,ok) \
1279 get_text_string(str,tvb,start,len,ok)
1280 #define get_quoted_string(str,tvb,start,len,ok) \
1281 get_text_string(str,tvb,start,len,ok)
1282 #define get_uri_value(str,tvb,start,len,ok) \
1283 get_text_string(str,tvb,start,len,ok)
1285 #define get_version_value(val,str,tvb,start,len,ok) \
1286 val = tvb_get_guint8(tvb,start); \
1288 if (val & 0x80) { /* High nibble "." Low nibble */ \
1291 str = g_strdup_printf("%u.%u", val >> 4, val & 0x0F); \
1292 } else { get_text_string(str,tvb,start,len,ok); }
1294 /* Parameter parser */
1296 parameter (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start, int len);
1298 parameter_value_q (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start);
1300 #define InvalidValueForHeader(hdr) \
1301 "<Error: Invalid value for the '" hdr "' header>"
1302 #define InvalidTextualHeader \
1303 "<Error: Invalid zero-length textual header>"
1304 #define TrailingQuoteWarning \
1305 " <Warning: Quoted-string value has been encoded with a trailing quote>"
1307 /* WSP well-known header parsing function prototypes;
1308 * will be listed in the function lookup table WellKnownHeaders[] */
1309 static guint32 wkh_default (proto_tree *tree, tvbuff_t *tvb,
1311 static guint32 wkh_accept (proto_tree *tree, tvbuff_t *tvb,
1313 static guint32 wkh_content_type (proto_tree *tree, tvbuff_t *tvb,
1315 static guint32 wkh_accept_charset (proto_tree *tree, tvbuff_t *tvb,
1317 static guint32 wkh_accept_language (proto_tree *tree, tvbuff_t *tvb,
1319 static guint32 wkh_connection (proto_tree *tree, tvbuff_t *tvb,
1321 static guint32 wkh_push_flag (proto_tree *tree, tvbuff_t *tvb,
1322 guint32 header_start);
1323 static guint32 wkh_vary (proto_tree *tree, tvbuff_t *tvb,
1325 static guint32 wkh_accept_ranges (proto_tree *tree, tvbuff_t *tvb,
1327 static guint32 wkh_content_disposition (proto_tree *tree, tvbuff_t *tvb,
1329 static guint32 wkh_accept_encoding (proto_tree *tree, tvbuff_t *tvb,
1331 static guint32 wkh_content_encoding (proto_tree *tree, tvbuff_t *tvb,
1333 static guint32 wkh_transfer_encoding (proto_tree *tree, tvbuff_t *tvb,
1335 static guint32 wkh_pragma (proto_tree *tree, tvbuff_t *tvb,
1337 /* Single short-integer value */
1338 static guint32 wkh_x_wap_security (proto_tree *tree, tvbuff_t *tvb,
1341 static guint32 wkh_content_base (proto_tree *tree, tvbuff_t *tvb,
1343 static guint32 wkh_content_location (proto_tree *tree, tvbuff_t *tvb,
1345 static guint32 wkh_etag (proto_tree *tree, tvbuff_t *tvb,
1347 static guint32 wkh_from (proto_tree *tree, tvbuff_t *tvb,
1349 static guint32 wkh_host (proto_tree *tree, tvbuff_t *tvb,
1351 static guint32 wkh_if_match (proto_tree *tree, tvbuff_t *tvb,
1353 static guint32 wkh_if_none_match (proto_tree *tree, tvbuff_t *tvb,
1355 static guint32 wkh_location (proto_tree *tree, tvbuff_t *tvb,
1357 static guint32 wkh_referer (proto_tree *tree, tvbuff_t *tvb,
1359 static guint32 wkh_server (proto_tree *tree, tvbuff_t *tvb,
1361 static guint32 wkh_user_agent (proto_tree *tree, tvbuff_t *tvb,
1363 static guint32 wkh_upgrade (proto_tree *tree, tvbuff_t *tvb,
1365 static guint32 wkh_via (proto_tree *tree, tvbuff_t *tvb,
1367 static guint32 wkh_content_uri (proto_tree *tree, tvbuff_t *tvb,
1369 static guint32 wkh_initiator_uri (proto_tree *tree, tvbuff_t *tvb,
1371 static guint32 wkh_profile (proto_tree *tree, tvbuff_t *tvb,
1373 static guint32 wkh_content_id (proto_tree *tree, tvbuff_t *tvb,
1375 /* Date-value or text */
1376 static guint32 wkh_if_range (proto_tree *tree, tvbuff_t *tvb,
1379 static guint32 wkh_date (proto_tree *tree, tvbuff_t *tvb,
1381 static guint32 wkh_expires (proto_tree *tree, tvbuff_t *tvb,
1383 static guint32 wkh_if_modified_since (proto_tree *tree, tvbuff_t *tvb,
1385 static guint32 wkh_if_unmodified_since (proto_tree *tree, tvbuff_t *tvb,
1387 static guint32 wkh_last_modified (proto_tree *tree, tvbuff_t *tvb,
1389 /* Date-value with special meaning */
1390 static guint32 wkh_x_wap_tod (proto_tree *tree, tvbuff_t *tvb,
1392 /* Delta-seconds-value */
1393 static guint32 wkh_age (proto_tree *tree, tvbuff_t *tvb,
1396 static guint32 wkh_proxy_authenticate (proto_tree *tree, tvbuff_t *tvb,
1398 static guint32 wkh_www_authenticate (proto_tree *tree, tvbuff_t *tvb,
1401 static guint32 wkh_authorization (proto_tree *tree, tvbuff_t *tvb,
1403 static guint32 wkh_proxy_authorization (proto_tree *tree, tvbuff_t *tvb,
1406 static guint32 wkh_pragma (proto_tree *tree, tvbuff_t *tvb,
1409 static guint32 wkh_content_length (proto_tree *tree, tvbuff_t *tvb,
1411 static guint32 wkh_max_forwards (proto_tree *tree, tvbuff_t *tvb,
1414 /* Integer lookup value */
1415 static guint32 wkh_bearer_indication (proto_tree *tree, tvbuff_t *tvb,
1418 /* WAP application ID value */
1419 static guint32 wkh_x_wap_application_id (proto_tree *tree, tvbuff_t *tvb,
1421 static guint32 wkh_accept_application (proto_tree *tree, tvbuff_t *tvb,
1423 static guint32 wkh_content_language (proto_tree *tree, tvbuff_t *tvb,
1426 /* Allow and Public */
1427 static guint32 wkh_allow(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start);
1428 static guint32 wkh_public(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start);
1431 static guint32 wkh_cache_control (proto_tree *tree, tvbuff_t *tvb,
1434 static guint32 wkh_warning (proto_tree *tree, tvbuff_t *tvb,
1436 /* Profile-warning */
1437 static guint32 wkh_profile_warning (proto_tree *tree, tvbuff_t *tvb,
1441 static guint32 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb,
1444 /* WSP encoding version */
1445 static guint32 wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb,
1448 /* Content-Range and Range */
1449 static guint32 wkh_content_range (proto_tree *tree, tvbuff_t *tvb,
1451 static guint32 wkh_range (proto_tree *tree, tvbuff_t *tvb,
1455 static guint32 wkh_te (proto_tree *tree, tvbuff_t *tvb,
1459 static guint32 wkh_trailer (proto_tree *tree, tvbuff_t *tvb,
1462 /* TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
1463 static guint32 wkh_retry_after (proto_tree *tree, tvbuff_t *tvb,
1465 static guint32 wkh_profile_diff (proto_tree *tree, tvbuff_t *tvb,
1467 static guint32 wkh_expect (proto_tree *tree, tvbuff_t *tvb,
1469 static guint32 wkh_set_cookie (proto_tree *tree, tvbuff_t *tvb,
1471 static guint32 wkh_cookie (proto_tree *tree, tvbuff_t *tvb,
1476 /* WSP well-known Openwave header parsing function prototypes;
1477 * will be listed in the function lookup table WellKnownOpenwaveHeaders[] */
1478 static guint32 wkh_openwave_default (proto_tree *tree, tvbuff_t *tvb,
1480 /* Textual headers */
1481 static guint32 wkh_openwave_x_up_proxy_operator_domain(proto_tree *tree,
1482 tvbuff_t *tvb, guint32 hdr_start);
1483 static guint32 wkh_openwave_x_up_proxy_home_page(proto_tree *tree,
1484 tvbuff_t *tvb, guint32 hdr_start);
1485 static guint32 wkh_openwave_x_up_proxy_uplink_version(proto_tree *tree,
1486 tvbuff_t *tvb, guint32 hdr_start);
1487 static guint32 wkh_openwave_x_up_proxy_ba_realm(proto_tree *tree,
1488 tvbuff_t *tvb, guint32 hdr_start);
1489 static guint32 wkh_openwave_x_up_proxy_request_uri(proto_tree *tree,
1490 tvbuff_t *tvb, guint32 hdr_start);
1491 static guint32 wkh_openwave_x_up_proxy_bookmark(proto_tree *tree,
1492 tvbuff_t *tvb, guint32 hdr_start);
1493 /* Integer headers */
1494 static guint32 wkh_openwave_x_up_proxy_push_seq(proto_tree *tree,
1495 tvbuff_t *tvb, guint32 hdr_start);
1496 static guint32 wkh_openwave_x_up_proxy_notify(proto_tree *tree,
1497 tvbuff_t *tvb, guint32 hdr_start);
1498 static guint32 wkh_openwave_x_up_proxy_net_ask(proto_tree *tree,
1499 tvbuff_t *tvb, guint32 hdr_start);
1500 static guint32 wkh_openwave_x_up_proxy_tod (proto_tree *tree,
1501 tvbuff_t *tvb, guint32 hdr_start);
1502 static guint32 wkh_openwave_x_up_proxy_ba_enable(proto_tree *tree,
1503 tvbuff_t *tvb, guint32 hdr_start);
1504 static guint32 wkh_openwave_x_up_proxy_redirect_enable(proto_tree *tree,
1505 tvbuff_t *tvb, guint32 hdr_start);
1506 static guint32 wkh_openwave_x_up_proxy_redirect_status(proto_tree *tree,
1507 tvbuff_t *tvb, guint32 hdr_start);
1508 static guint32 wkh_openwave_x_up_proxy_linger(proto_tree *tree,
1509 tvbuff_t *tvb, guint32 hdr_start);
1510 static guint32 wkh_openwave_x_up_proxy_enable_trust(proto_tree *tree,
1511 tvbuff_t *tvb, guint32 hdr_start);
1512 static guint32 wkh_openwave_x_up_proxy_trust(proto_tree *tree,
1513 tvbuff_t *tvb, guint32 hdr_start);
1514 static guint32 wkh_openwave_x_up_devcap_has_color(proto_tree *tree,
1515 tvbuff_t *tvb, guint32 hdr_start);
1516 static guint32 wkh_openwave_x_up_devcap_num_softkeys(proto_tree *tree,
1517 tvbuff_t *tvb, guint32 hdr_start);
1518 static guint32 wkh_openwave_x_up_devcap_softkey_size(proto_tree *tree,
1519 tvbuff_t *tvb, guint32 hdr_start);
1520 static guint32 wkh_openwave_x_up_devcap_screen_chars(proto_tree *tree,
1521 tvbuff_t *tvb, guint32 hdr_start);
1522 static guint32 wkh_openwave_x_up_devcap_screen_pixels(proto_tree *tree,
1523 tvbuff_t *tvb, guint32 hdr_start);
1524 static guint32 wkh_openwave_x_up_devcap_em_size(proto_tree *tree,
1525 tvbuff_t *tvb, guint32 hdr_start);
1526 static guint32 wkh_openwave_x_up_devcap_screen_depth(proto_tree *tree,
1527 tvbuff_t *tvb, guint32 hdr_start);
1528 static guint32 wkh_openwave_x_up_devcap_immed_alert(proto_tree *tree,
1529 tvbuff_t *tvb, guint32 hdr_start);
1530 static guint32 wkh_openwave_x_up_devcap_gui(proto_tree *tree,
1531 tvbuff_t *tvb, guint32 hdr_start);
1533 static guint32 wkh_openwave_x_up_proxy_trans_charset(proto_tree *tree,
1534 tvbuff_t *tvb, guint32 hdr_start);
1535 static guint32 wkh_openwave_x_up_proxy_push_accept(proto_tree *tree,
1536 tvbuff_t *tvb, guint32 hdr_start);
1539 /* Define a pointer to function data type for the well-known header
1540 * lookup table below */
1541 typedef guint32 (*hdr_parse_func_ptr) (proto_tree *, tvbuff_t *, guint32);
1543 /* Lookup table for well-known header parsing functions */
1544 static const hdr_parse_func_ptr WellKnownHeader[128] = {
1545 /* 0x00 */ wkh_accept, /* 0x01 */ wkh_accept_charset,
1546 /* 0x02 */ wkh_accept_encoding, /* 0x03 */ wkh_accept_language,
1547 /* 0x04 */ wkh_accept_ranges, /* 0x05 */ wkh_age,
1548 /* 0x06 */ wkh_allow, /* 0x07 */ wkh_authorization,
1549 /* 0x08 */ wkh_cache_control, /* 0x09 */ wkh_connection,
1550 /* 0x0A */ wkh_content_base, /* 0x0B */ wkh_content_encoding,
1551 /* 0x0C */ wkh_content_language, /* 0x0D */ wkh_content_length,
1552 /* 0x0E */ wkh_content_location, /* 0x0F */ wkh_content_md5,
1553 /* 0x10 */ wkh_content_range, /* 0x11 */ wkh_content_type,
1554 /* 0x12 */ wkh_date, /* 0x13 */ wkh_etag,
1555 /* 0x14 */ wkh_expires, /* 0x15 */ wkh_from,
1556 /* 0x16 */ wkh_host, /* 0x17 */ wkh_if_modified_since,
1557 /* 0x18 */ wkh_if_match, /* 0x19 */ wkh_if_none_match,
1558 /* 0x1A */ wkh_if_range, /* 0x1B */ wkh_if_unmodified_since,
1559 /* 0x1C */ wkh_location, /* 0x1D */ wkh_last_modified,
1560 /* 0x1E */ wkh_max_forwards, /* 0x1F */ wkh_pragma,
1561 /* 0x20 */ wkh_proxy_authenticate, /* 0x21 */ wkh_proxy_authorization,
1562 /* 0x22 */ wkh_public, /* 0x23 */ wkh_range,
1563 /* 0x24 */ wkh_referer, /* 0x25 */ wkh_default,
1564 /* 0x26 */ wkh_server, /* 0x27 */ wkh_transfer_encoding,
1565 /* 0x28 */ wkh_upgrade, /* 0x29 */ wkh_user_agent,
1566 /* 0x2A */ wkh_vary, /* 0x2B */ wkh_via,
1567 /* 0x2C */ wkh_warning, /* 0x2D */ wkh_www_authenticate,
1568 /* 0x2E */ wkh_content_disposition,/* 0x2F */ wkh_x_wap_application_id,
1569 /* 0x30 */ wkh_content_uri, /* 0x31 */ wkh_initiator_uri,
1570 /* 0x32 */ wkh_accept_application, /* 0x33 */ wkh_bearer_indication,
1571 /* 0x34 */ wkh_push_flag, /* 0x35 */ wkh_profile,
1572 /* 0x36 */ wkh_default, /* 0x37 */ wkh_profile_warning,
1573 /* 0x38 */ wkh_default, /* 0x39 */ wkh_te,
1574 /* 0x3A */ wkh_trailer, /* 0x3B */ wkh_accept_charset,
1575 /* 0x3C */ wkh_accept_encoding, /* 0x3D */ wkh_cache_control,
1576 /* 0x3E */ wkh_content_range, /* 0x3F */ wkh_x_wap_tod,
1577 /* 0x40 */ wkh_content_id, /* 0x41 */ wkh_default,
1578 /* 0x42 */ wkh_default, /* 0x43 */ wkh_encoding_version,
1579 /* 0x44 */ wkh_profile_warning, /* 0x45 */ wkh_content_disposition,
1580 /* 0x46 */ wkh_x_wap_security, /* 0x47 */ wkh_cache_control,
1581 /*******************************************************
1582 *** The following headers are not (yet) registered. ***
1583 *******************************************************/
1584 /* 0x48 */ wkh_default, /* 0x49 */ wkh_default,
1585 /* 0x4A */ wkh_default, /* 0x4B */ wkh_default,
1586 /* 0x4C */ wkh_default, /* 0x4D */ wkh_default,
1587 /* 0x4E */ wkh_default, /* 0x4F */ wkh_default,
1588 /* 0x50 */ wkh_default, /* 0x51 */ wkh_default,
1589 /* 0x52 */ wkh_default, /* 0x53 */ wkh_default,
1590 /* 0x54 */ wkh_default, /* 0x55 */ wkh_default,
1591 /* 0x56 */ wkh_default, /* 0x57 */ wkh_default,
1592 /* 0x58 */ wkh_default, /* 0x59 */ wkh_default,
1593 /* 0x5A */ wkh_default, /* 0x5B */ wkh_default,
1594 /* 0x5C */ wkh_default, /* 0x5D */ wkh_default,
1595 /* 0x5E */ wkh_default, /* 0x5F */ wkh_default,
1596 /* 0x60 */ wkh_default, /* 0x61 */ wkh_default,
1597 /* 0x62 */ wkh_default, /* 0x63 */ wkh_default,
1598 /* 0x64 */ wkh_default, /* 0x65 */ wkh_default,
1599 /* 0x66 */ wkh_default, /* 0x67 */ wkh_default,
1600 /* 0x68 */ wkh_default, /* 0x69 */ wkh_default,
1601 /* 0x6A */ wkh_default, /* 0x6B */ wkh_default,
1602 /* 0x6C */ wkh_default, /* 0x6D */ wkh_default,
1603 /* 0x6E */ wkh_default, /* 0x6F */ wkh_default,
1604 /* 0x70 */ wkh_default, /* 0x71 */ wkh_default,
1605 /* 0x72 */ wkh_default, /* 0x73 */ wkh_default,
1606 /* 0x74 */ wkh_default, /* 0x75 */ wkh_default,
1607 /* 0x76 */ wkh_default, /* 0x77 */ wkh_default,
1608 /* 0x78 */ wkh_default, /* 0x79 */ wkh_default,
1609 /* 0x7A */ wkh_default, /* 0x7B */ wkh_default,
1610 /* 0x7C */ wkh_default, /* 0x7D */ wkh_default,
1611 /* 0x7E */ wkh_default, /* 0x7F */ wkh_default,
1614 /* Lookup table for well-known header parsing functions */
1615 static const hdr_parse_func_ptr WellKnownOpenwaveHeader[128] = {
1616 /* 0x00 */ wkh_openwave_default,
1617 /* 0x01 */ wkh_openwave_x_up_proxy_push_accept,
1618 /* 0x02 */ wkh_openwave_x_up_proxy_push_seq,
1619 /* 0x03 */ wkh_openwave_x_up_proxy_notify,
1620 /* 0x04 */ wkh_openwave_x_up_proxy_operator_domain,
1621 /* 0x05 */ wkh_openwave_x_up_proxy_home_page,
1622 /* 0x06 */ wkh_openwave_x_up_devcap_has_color,
1623 /* 0x07 */ wkh_openwave_x_up_devcap_num_softkeys,
1624 /* 0x08 */ wkh_openwave_x_up_devcap_softkey_size,
1625 /* 0x09 */ wkh_openwave_x_up_devcap_screen_chars,
1626 /* 0x0A */ wkh_openwave_x_up_devcap_screen_pixels,
1627 /* 0x0B */ wkh_openwave_x_up_devcap_em_size,
1628 /* 0x0C */ wkh_openwave_x_up_devcap_screen_depth,
1629 /* 0x0D */ wkh_openwave_x_up_devcap_immed_alert,
1630 /* 0x0E */ wkh_openwave_x_up_proxy_net_ask,
1631 /* 0x0F */ wkh_openwave_x_up_proxy_uplink_version,
1632 /* 0x10 */ wkh_openwave_x_up_proxy_tod,
1633 /* 0x11 */ wkh_openwave_x_up_proxy_ba_enable,
1634 /* 0x12 */ wkh_openwave_x_up_proxy_ba_realm,
1635 /* 0x13 */ wkh_openwave_x_up_proxy_redirect_enable,
1636 /* 0x14 */ wkh_openwave_x_up_proxy_request_uri,
1637 /* 0x15 */ wkh_openwave_x_up_proxy_redirect_status,
1638 /* 0x16 */ wkh_openwave_x_up_proxy_trans_charset,
1639 /* 0x17 */ wkh_openwave_x_up_proxy_linger,
1640 /* 0x18 */ wkh_openwave_default,
1641 /* 0x19 */ wkh_openwave_x_up_proxy_enable_trust,
1642 /* 0x1A */ wkh_openwave_x_up_proxy_trust,
1643 /* 0x1B */ wkh_openwave_default,
1644 /* 0x1C */ wkh_openwave_default,
1645 /* 0x1D */ wkh_openwave_default,
1646 /* 0x1E */ wkh_openwave_default,
1647 /* 0x1F */ wkh_openwave_default,
1648 /* 0x20 */ wkh_openwave_x_up_proxy_trust,
1649 /* 0x21 */ wkh_openwave_x_up_proxy_bookmark,
1650 /* 0x22 */ wkh_openwave_x_up_devcap_gui,
1651 /*******************************************************
1652 *** The following headers are not (yet) registered. ***
1653 *******************************************************/
1654 /* 0x23 */ wkh_openwave_default,
1655 /* 0x24 */ wkh_openwave_default, /* 0x25 */ wkh_openwave_default,
1656 /* 0x26 */ wkh_openwave_default, /* 0x27 */ wkh_openwave_default,
1657 /* 0x28 */ wkh_openwave_default, /* 0x29 */ wkh_openwave_default,
1658 /* 0x2A */ wkh_openwave_default, /* 0x2B */ wkh_openwave_default,
1659 /* 0x2C */ wkh_openwave_default, /* 0x2D */ wkh_openwave_default,
1660 /* 0x2E */ wkh_openwave_default, /* 0x2F */ wkh_openwave_default,
1661 /* 0x30 */ wkh_openwave_default, /* 0x31 */ wkh_openwave_default,
1662 /* 0x32 */ wkh_openwave_default, /* 0x33 */ wkh_openwave_default,
1663 /* 0x34 */ wkh_openwave_default, /* 0x35 */ wkh_openwave_default,
1664 /* 0x36 */ wkh_openwave_default, /* 0x37 */ wkh_openwave_default,
1665 /* 0x38 */ wkh_openwave_default, /* 0x39 */ wkh_openwave_default,
1666 /* 0x3A */ wkh_openwave_default, /* 0x3B */ wkh_openwave_default,
1667 /* 0x3C */ wkh_openwave_default, /* 0x3D */ wkh_openwave_default,
1668 /* 0x3E */ wkh_openwave_default, /* 0x3F */ wkh_openwave_default,
1669 /* 0x40 */ wkh_openwave_default, /* 0x41 */ wkh_openwave_default,
1670 /* 0x42 */ wkh_openwave_default, /* 0x43 */ wkh_openwave_default,
1671 /* 0x44 */ wkh_openwave_default, /* 0x45 */ wkh_openwave_default,
1672 /* 0x46 */ wkh_openwave_default, /* 0x47 */ wkh_openwave_default,
1673 /* 0x48 */ wkh_openwave_default, /* 0x49 */ wkh_openwave_default,
1674 /* 0x4A */ wkh_openwave_default, /* 0x4B */ wkh_openwave_default,
1675 /* 0x4C */ wkh_openwave_default, /* 0x4D */ wkh_openwave_default,
1676 /* 0x4E */ wkh_openwave_default, /* 0x4F */ wkh_openwave_default,
1677 /* 0x50 */ wkh_openwave_default, /* 0x51 */ wkh_openwave_default,
1678 /* 0x52 */ wkh_openwave_default, /* 0x53 */ wkh_openwave_default,
1679 /* 0x54 */ wkh_openwave_default, /* 0x55 */ wkh_openwave_default,
1680 /* 0x56 */ wkh_openwave_default, /* 0x57 */ wkh_openwave_default,
1681 /* 0x58 */ wkh_openwave_default, /* 0x59 */ wkh_openwave_default,
1682 /* 0x5A */ wkh_openwave_default, /* 0x5B */ wkh_openwave_default,
1683 /* 0x5C */ wkh_openwave_default, /* 0x5D */ wkh_openwave_default,
1684 /* 0x5E */ wkh_openwave_default, /* 0x5F */ wkh_openwave_default,
1685 /* 0x60 */ wkh_openwave_default, /* 0x61 */ wkh_openwave_default,
1686 /* 0x62 */ wkh_openwave_default, /* 0x63 */ wkh_openwave_default,
1687 /* 0x64 */ wkh_openwave_default, /* 0x65 */ wkh_openwave_default,
1688 /* 0x66 */ wkh_openwave_default, /* 0x67 */ wkh_openwave_default,
1689 /* 0x68 */ wkh_openwave_default, /* 0x69 */ wkh_openwave_default,
1690 /* 0x6A */ wkh_openwave_default, /* 0x6B */ wkh_openwave_default,
1691 /* 0x6C */ wkh_openwave_default, /* 0x6D */ wkh_openwave_default,
1692 /* 0x6E */ wkh_openwave_default, /* 0x6F */ wkh_openwave_default,
1693 /* 0x70 */ wkh_openwave_default, /* 0x71 */ wkh_openwave_default,
1694 /* 0x72 */ wkh_openwave_default, /* 0x73 */ wkh_openwave_default,
1695 /* 0x74 */ wkh_openwave_default, /* 0x75 */ wkh_openwave_default,
1696 /* 0x76 */ wkh_openwave_default, /* 0x77 */ wkh_openwave_default,
1697 /* 0x78 */ wkh_openwave_default, /* 0x79 */ wkh_openwave_default,
1698 /* 0x7A */ wkh_openwave_default, /* 0x7B */ wkh_openwave_default,
1699 /* 0x7C */ wkh_openwave_default, /* 0x7D */ wkh_openwave_default,
1700 /* 0x7E */ wkh_openwave_default, /* 0x7F */ wkh_openwave_default,
1708 /* WSP header format
1709 * 1st byte: 0x00 : <Not allowed>
1710 * 1st byte: 0x01 -- 0x1F: <Shorthand Header Code Page switch>
1711 * 1st byte: 0x20 -- 0x7E: <Textual header (C string)>
1712 * Followed with: <Textual header value (C string)>
1713 * 1st byte: 0x7F : <Header Code Page switch>
1714 * Followed with: 2nd byte: <Header Code Page>
1715 * 1st byte: 0x80 -- 0xFF: <Binary header (7-bit encoded ID)>
1717 * 2nd byte: 0x00 -- 0x1E: <Value Length (bytes)>
1718 * Followed with: <Len> bytes of data
1719 * 2nd byte: 0x1F : <Value Length is a guintvar>
1720 * Followed with: <guintvar Len>
1721 * Followed with: <Len> bytes of data
1722 * 2nd byte: 0x20 -- 0x7F: <Textual header value (C string)>
1723 * 2nd byte: 0x80 -- 0xFF: <Binary value (7-bit encoded ID)>
1726 add_headers (proto_tree *tree, tvbuff_t *tvb, int hf)
1728 guint8 hdr_id, val_id, codepage = 1;
1729 gint32 tvb_len = tvb_length(tvb);
1730 gint32 offset = 0, hdr_len, hdr_start;
1731 gint32 val_len, val_start;
1732 guint8 *hdr_str, *val_str;
1733 proto_tree *wsp_headers;
1739 if (offset >= tvb_len)
1740 return; /* No headers! */
1742 ti = proto_tree_add_item(tree, hf,
1743 tvb, offset, tvb_len, bo_little_endian);
1744 wsp_headers = proto_item_add_subtree(ti, ett_headers);
1746 while (offset < tvb_len) {
1748 hdr_id = tvb_get_guint8(tvb, offset);
1749 if (hdr_id & 0x80) { /* Well-known header */
1751 val_start = ++offset;
1752 val_id = tvb_get_guint8(tvb, val_start);
1753 /* Call header value dissector for given header */
1754 if (codepage == 1) { /* Default header code page */
1755 DebugLog(("add_headers(code page 0): %s\n",
1756 match_strval (hdr_id & 0x7f, vals_field_names)));
1757 offset = WellKnownHeader[hdr_id & 0x7F](wsp_headers, tvb,
1759 } else { /* Openwave header code page */
1760 /* Here I'm delibarately assuming that Openwave is the only
1761 * company that defines a WSP header code page. */
1762 DebugLog(("add_headers(code page 0x%02x - assumed to be x-up-1): %s\n",
1763 codepage, match_strval (hdr_id & 0x7f, vals_openwave_field_names)));
1764 offset = WellKnownOpenwaveHeader[hdr_id & 0x7F](wsp_headers,
1767 } else if (hdr_id == 0x7F) { /* HCP shift sequence */
1768 codepage = tvb_get_guint8(tvb, offset+1);
1769 proto_tree_add_uint(wsp_headers, hf_wsp_header_shift_code,
1770 tvb, offset, 2, codepage);
1772 } else if (hdr_id >= 0x20) { /* Textual header */
1773 /* Header name MUST be NUL-ended string ==> tvb_get_stringz() */
1774 hdr_str = tvb_get_stringz(tvb, hdr_start, &hdr_len);
1775 val_start = hdr_start + hdr_len;
1776 val_id = tvb_get_guint8(tvb, val_start);
1777 /* Call header value dissector for given header */
1778 if (val_id >= 0x20 && val_id <=0x7E) { /* OK! */
1779 val_str = tvb_get_stringz(tvb, val_start, &val_len);
1781 offset = val_start + val_len;
1782 proto_tree_add_text(wsp_headers,tvb,hdr_start,offset-hdr_start,
1783 "%s: %s", hdr_str, val_str);
1786 /* Old-style X-WAP-TOD uses a non-textual value
1787 * after a textual header. */
1788 if (strcasecmp(hdr_str, "x-wap.tod") == 0) {
1789 get_delta_seconds_value(val, tvb, val_start, val_len, ok);
1792 ti = proto_tree_add_string (wsp_headers,
1794 tvb, hdr_start, hdr_len + val_len,
1795 "Requesting Time Of Day");
1799 val_str = abs_time_to_str(&tv);
1801 ti = proto_tree_add_string (wsp_headers,
1803 tvb, hdr_start, hdr_len + val_len, val_str);
1805 proto_item_append_text(ti, " <Warning: "
1806 "should be encoded as a textual value>");
1808 /* I prefer using X-Wap-Tod to the real hdr_str */
1809 proto_tree_add_string (wsp_headers, hf_hdr_x_wap_tod,
1810 tvb, hdr_start, hdr_len + val_len,
1811 InvalidValueForHeader("X-Wap-Tod"));
1814 proto_tree_add_text (wsp_headers, tvb, hdr_start, hdr_len,
1815 "<Error: Invalid value for the textual '%s' header"
1816 " (should be a textual value)>",
1821 proto_tree_add_string_hidden(wsp_headers, hf_hdr_name,
1822 tvb, hdr_start, offset - hdr_start, hdr_str);
1823 } else if (hdr_id > 0) { /* Shorthand HCP switch */
1825 proto_tree_add_uint (wsp_headers, hf_wsp_header_shift_code,
1826 tvb, offset, 1, codepage);
1829 proto_tree_add_text (wsp_headers, tvb, hdr_start, 1,
1830 InvalidTextualHeader);
1837 /* The following macros hide common processing for all well-known headers
1838 * and shortens the code to be written in a wkh_XXX() function.
1839 * Even declarations are hidden by a macro.
1841 * Define a wkh_XXX() function as follows:
1844 * wkh_XXX (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
1846 * wkh_0_Declarations;
1847 * << add other required declarations here >>
1849 * wkh_1_WellKnownValue;
1850 * << add well-known value proto item here; don't forget to set the
1851 * ok variable to TRUE if parsing was correct >>
1852 * wkh_2_TextualValue;
1853 * << add textual value proto item here; don't forget to set the
1854 * ok variable to TRUE if parsing was correct >>
1855 * wkh_3_ValueWithLength;
1856 * << add custom code for value processing and value proto item here >>
1859 * << This macro takes care of parse errors within the header value;
1860 * it requires the header field index if the header has not yet been
1861 * written to the protocol tree (ti == NULL). >>
1864 * NOTE: You only need to write parsing code for the successful case,
1865 * Errors are automatically reported through the wkh_4_End() macro
1869 /* The following code is the generic template with which the value of a
1870 * well-known header can be processed. Not all sections yield a semantically
1871 * correct result, so appropriate error information must be provided.
1875 #define wkh_0_Declarations /* Declarations for Parsing */ \
1876 gboolean ok = FALSE; /* Triggers error notification code at end */ \
1877 proto_item *ti = NULL; /* Needed for error notification at end */ \
1878 guint32 val_start = hdr_start + 1; \
1879 guint8 hdr_id = tvb_get_guint8 (tvb, hdr_start) & 0x7F; \
1880 guint8 val_id = tvb_get_guint8 (tvb, val_start); \
1881 guint32 offset = val_start; /* Offset to one past this header */ \
1882 guint32 val_len; /* length for value with length field */ \
1883 guint32 val_len_len; /* length of length field */ \
1884 guint8 *val_str = NULL
1886 #define wkh_1_WellKnownValue /* Parse Well Known Value */ \
1887 proto_tree_add_string_hidden(tree, hf_hdr_name, \
1888 tvb, hdr_start, offset - hdr_start, \
1889 val_to_str (hdr_id, vals_field_names, \
1890 "<Unknown WSP header field 0x%02X>")); \
1891 if (val_id & 0x80) { /* Well-known value */ \
1893 /* Well-known value processing starts HERE \
1897 #define wkh_2_TextualValue /* Parse Textual Value */ \
1899 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \
1900 val_str = tvb_get_stringz (tvb, val_start, &val_len); \
1901 g_assert(val_str); \
1902 offset = val_start + val_len; \
1903 /* Textual value processing starts HERE \
1907 #define wkh_3_ValueWithLength /* Parse Value With Length */ \
1910 } else { /* val_start points to 1st byte of length field */ \
1911 if (val_id == 0x1F) { /* Value Length = guintvar */ \
1912 val_len = tvb_get_guintvar(tvb, val_start + 1, &val_len_len); \
1913 val_len_len++; /* 0x1F length indicator byte */ \
1914 } else { /* Short length followed by Len data octets */ \
1915 val_len = tvb_get_guint8(tvb, offset); \
1918 offset += val_len_len + val_len; \
1919 /* Value with length processing starts HERE \
1920 * The value lies between val_start and offset: \
1921 * - Value Length: Start = val_start \
1922 * Length = val_len_len \
1923 * - Value Data : Start = val_start + val_len_len \
1924 * Length = val_len \
1925 * End = offset - 1 \
1928 #define wkh_4_End(hf) /* End of value parsing */ \
1931 /* Check for errors */ \
1933 if (ti) { /* Append to protocol tree item label */ \
1934 proto_item_append_text(ti, \
1935 " <Error: Invalid header value>"); \
1936 } else if (hf > 0) { /* Create protocol tree item */ \
1937 proto_tree_add_string(tree, hf, \
1938 tvb, hdr_start, offset - hdr_start, \
1939 " <Error: Invalid header value>"); \
1940 } else { /* Create anonymous header field entry */ \
1941 proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start, \
1942 "%s: <Error: Invalid header value>", \
1943 val_to_str (hdr_id, vals_field_names, \
1944 "<Unknown WSP header field 0x%02X>")); \
1951 * This yields the following default header value parser function body
1954 wkh_default(proto_tree *tree, tvbuff_t *tvb,
1959 ok = TRUE; /* Bypass error checking as we don't parse the values! */
1961 wkh_1_WellKnownValue;
1962 ti = proto_tree_add_text (tree, tvb, hdr_start, offset - hdr_start,
1963 "%s: (Undecoded well-known value 0x%02x)",
1964 val_to_str (hdr_id, vals_field_names,
1965 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F);
1967 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
1969 val_to_str (hdr_id, vals_field_names,
1970 "<Unknown WSP header field 0x%02X>"), val_str);
1971 wkh_3_ValueWithLength;
1972 ti = proto_tree_add_text (tree, tvb, hdr_start, offset - hdr_start,
1973 "%s: (Undecoded value in general form with length indicator)",
1974 val_to_str (hdr_id, vals_field_names,
1975 "<Unknown WSP header field 0x%02X>"));
1977 wkh_4_End(HF_EMPTY); /* The default parser has no associated hf_index;
1978 additionally the error code is always bypassed */
1982 /* Content-type processing uses the following common core: */
1983 #define wkh_content_type_header(underscored,Text) \
1985 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
1987 wkh_0_Declarations; \
1988 guint32 off, val = 0, len; \
1990 proto_tree *parameter_tree = NULL; \
1992 wkh_1_WellKnownValue; \
1993 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
1994 tvb, hdr_start, offset - hdr_start, \
1995 val_to_str(val_id & 0x7F, vals_content_types, \
1996 "(Unknown content type identifier 0x%X)")); \
1998 wkh_2_TextualValue; \
1999 /* Sometimes with a No-Content response, a NULL content type \
2000 * is reported. Process this correctly! */ \
2002 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2003 tvb, hdr_start, offset - hdr_start, \
2006 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2007 tvb, hdr_start, offset - hdr_start, \
2008 "<no content type has been specified>"); \
2011 wkh_3_ValueWithLength; \
2012 off = val_start + val_len_len; \
2013 peek = tvb_get_guint8(tvb, off); \
2014 if (is_text_string(peek)) { \
2015 get_extension_media(val_str, tvb, off, len, ok); \
2016 /* As we're using val_str, it is automatically g_free()d */ \
2017 off += len; /* off now points to 1st byte after string */ \
2018 ti = proto_tree_add_string (tree, hf_hdr_ ## underscored, \
2019 tvb, hdr_start, offset - hdr_start, val_str); \
2020 } else if (is_integer_value(peek)) { \
2021 get_integer_value(val, tvb, off, len, ok); \
2023 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2024 tvb, hdr_start, offset - hdr_start, \
2025 val_to_str(val, vals_content_types, \
2026 "(Unknown content type identifier 0x%X)")); \
2030 /* Remember: offset == val_start + val_len + val_len_len */ \
2031 if (ok && (off < offset)) { /* Add parameters if any */ \
2032 parameter_tree = proto_item_add_subtree (ti, ett_header); \
2033 while (off < offset) { \
2034 off = parameter (parameter_tree, ti, tvb, off, offset - off); \
2038 wkh_4_End(hf_hdr_ ## underscored); \
2046 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2048 wkh_content_type_header(accept, "Accept")
2052 * Content-type-value =
2055 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2057 * Beware: this header should not appear as such; it is dissected elsewhere
2058 * and at the same time the content type is used for subdissectors.
2059 * It is here for the sake of completeness.
2061 wkh_content_type_header(content_type, "Content-Type")
2065 * Content-type-value =
2068 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2070 * This function adds the content type value to the protocol tree,
2071 * and computes either the numeric or textual media type in return,
2072 * which will be used for further subdissection (e.g., MMS, WBXML).
2075 add_content_type(proto_tree *tree, tvbuff_t *tvb, guint32 val_start,
2076 guint32 *well_known_content, const char **textual_content)
2078 /* Replace wkh_0_Declarations with slightly modified declarations
2079 * so we can still make use of the wkh_[1-4]_XXX macros! */
2080 guint32 hdr_start = val_start; /* No header name, only value! */
2081 guint8 hdr_id = FN_CONTENT_TYPE; /* Same remark */
2082 guint8 val_id = tvb_get_guint8 (tvb, val_start);
2083 guint32 offset = val_start; /* Offset to one past this header */
2084 guint32 val_len; /* length for value with length field */
2085 guint32 val_len_len; /* length of length field */
2086 guint8 *val_str = NULL;
2087 guint32 off, val = 0, len;
2089 gboolean ok = FALSE;
2090 proto_item *ti = NULL;
2091 proto_tree *parameter_tree = NULL;
2093 *textual_content = NULL;
2094 *well_known_content = 0;
2096 DebugLog(("add_content_type() - START\n"));
2098 wkh_1_WellKnownValue;
2099 DebugLog(("add_content_type() - Well-known - Start\n"));
2100 *textual_content = val_to_str(val_id & 0x7F, vals_content_types,
2101 "<Unknown media type identifier 0x%X>");
2102 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2103 tvb, hdr_start, offset - hdr_start,
2105 *well_known_content = val_id & 0x7F;
2107 DebugLog(("add_content_type() - Well-known - End\n"));
2109 DebugLog(("add_content_type() - Textual - Start\n"));
2110 /* Sometimes with a No-Content response, a NULL content type
2111 * is reported. Process this correctly! */
2113 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2114 tvb, hdr_start, offset - hdr_start,
2116 /* As we're using val_str, it is automatically g_free()d */
2117 *textual_content = g_strdup(val_str);
2118 *well_known_content = 0;
2120 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2121 tvb, hdr_start, offset - hdr_start,
2122 "<no media type has been specified>");
2123 *textual_content = NULL;
2124 *well_known_content = 0;
2127 DebugLog(("add_content_type() - Textual - End\n"));
2128 wkh_3_ValueWithLength;
2129 DebugLog(("add_content_type() - General form - Start\n"));
2130 off = val_start + val_len_len;
2131 peek = tvb_get_guint8(tvb, off);
2132 if (is_text_string(peek)) {
2133 DebugLog(("add_content_type() - General form - extension-media\n"));
2134 get_extension_media(val_str, tvb, off, len, ok);
2135 /* As we're using val_str, it is automatically g_free()d */
2136 /* ??? Not sure anymore, we're in wkh_3, not in wkh_2 ! */
2137 off += len; /* off now points to 1st byte after string */
2138 ti = proto_tree_add_string (tree, hf_hdr_content_type,
2139 tvb, hdr_start, offset - hdr_start, val_str);
2140 /* Following statement: required? */
2141 *textual_content = g_strdup(val_str);
2142 *well_known_content = 0;
2143 } else if (is_integer_value(peek)) {
2144 DebugLog(("add_content_type() - General form - integer_value\n"));
2145 get_integer_value(val, tvb, off, len, ok);
2147 *textual_content = val_to_str(val, vals_content_types,
2148 "<Unknown media type identifier 0x%X>");
2149 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2150 tvb, hdr_start, offset - hdr_start,
2152 *well_known_content = val;
2155 } /* else ok = FALSE */
2156 /* Remember: offset == val_start + val_len_len + val_len */
2157 if (ok && (off < offset)) { /* Add parameters if any */
2158 DebugLog(("add_content_type() - General form - parameters\n"));
2159 parameter_tree = proto_item_add_subtree (ti, ett_header);
2160 while (off < offset) {
2161 DebugLog(("add_content_type() - General form - parameter start "
2162 "(off = %u)\n", off));
2163 off = parameter (parameter_tree, ti, tvb, off, offset - off);
2164 DebugLog(("add_content_type() - General form - parameter end "
2165 "(off = %u)\n", off));
2168 DebugLog(("add_content_type() - General form - End\n"));
2170 wkh_4_End(hf_hdr_content_type);
2175 * Template for accept_X headers with optional Q parameter value
2177 #define wkh_accept_x_q_header(underscored,Text,valueString,valueName) \
2179 wkh_ ## underscored (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2181 wkh_0_Declarations; \
2182 guint32 off, val = 0, len; \
2184 proto_tree *parameter_tree = NULL; \
2186 wkh_1_WellKnownValue; \
2187 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2188 tvb, hdr_start, offset - hdr_start, \
2189 val_to_str(val_id & 0x7F, valueString, \
2190 "<Unknown " valueName " identifier 0x%X>")); \
2192 wkh_2_TextualValue; \
2193 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2194 tvb, hdr_start, offset - hdr_start, val_str); \
2196 wkh_3_ValueWithLength; \
2197 off = val_start + val_len_len; \
2198 peek = tvb_get_guint8(tvb, off); \
2199 if (is_text_string(peek)) { \
2200 get_token_text(val_str, tvb, off, len, ok); \
2201 /* As we're using val_str, it is automatically g_free()d */ \
2202 off += len; /* off now points to 1st byte after string */ \
2203 ti = proto_tree_add_string (tree, hf_hdr_ ## underscored, \
2204 tvb, hdr_start, offset - hdr_start, val_str); \
2205 } else if (is_integer_value(peek)) { \
2206 get_integer_value(val, tvb, off, len, ok); \
2208 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2209 tvb, hdr_start, offset - hdr_start, \
2210 val_to_str(val, valueString, \
2211 "<Unknown " valueName " identifier 0x%X>")); \
2214 } /* else ok = FALSE */ \
2215 /* Remember: offset == val_start + val_len */ \
2216 if (ok && (off < offset)) { /* Add Q-value if available */ \
2217 parameter_tree = proto_item_add_subtree (ti, ett_header); \
2218 off = parameter_value_q (parameter_tree, ti, tvb, off); \
2221 wkh_4_End(hf_hdr_ ## underscored); \
2225 * Accept-charset-value =
2228 * | ( Value-length ( Token-text | Integer-value ) [ Q-value ] )
2230 wkh_accept_x_q_header(accept_charset, "Accept-Charset",
2231 vals_character_sets, "character set")
2233 * Accept-language-value =
2236 * | ( Value-length ( Text-string | Integer-value ) [ Q-value ] )
2238 wkh_accept_x_q_header(accept_language, "Accept-Language",
2239 vals_languages, "language")
2243 * Push-flag-value = Short-integer
2246 wkh_push_flag(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2249 proto_tree *subtree = NULL;
2251 wkh_1_WellKnownValue;
2252 ti = proto_tree_add_string(tree, hf_hdr_push_flag,
2253 tvb, hdr_start, offset - hdr_start, "");
2254 subtree = proto_item_add_subtree(ti, ett_header);
2255 proto_tree_add_uint(subtree, hf_hdr_push_flag_auth,
2256 tvb, val_start, 1, val_id);
2257 proto_tree_add_uint(subtree, hf_hdr_push_flag_trust,
2258 tvb, val_start, 1, val_id);
2259 proto_tree_add_uint(subtree, hf_hdr_push_flag_last,
2260 tvb, val_start, 1, val_id);
2262 proto_item_append_string(ti, " (Initiator URI authenticated)");
2264 proto_item_append_string(ti, " (Content trusted)");
2266 proto_item_append_string(ti, " (Last push message)");
2268 proto_item_append_text(ti, " <Warning: Reserved flags set>");
2273 wkh_3_ValueWithLength;
2275 wkh_4_End(hf_hdr_push_flag);
2284 wkh_allow(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2288 wkh_1_WellKnownValue;
2290 if (val_id >= 0x40) { /* Valid WSP method */
2291 ti = proto_tree_add_string(tree, hf_hdr_allow,
2292 tvb, hdr_start, offset - hdr_start,
2293 val_to_str(val_id & 0x7F, vals_pdu_type,
2294 "<Unknown WSP method 0x%02X>"));
2299 wkh_3_ValueWithLength;
2301 wkh_4_End(hf_hdr_allow);
2307 * Token-text | Short-integer
2310 wkh_public(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2314 wkh_1_WellKnownValue;
2316 if (val_id >= 0x40) { /* Valid WSP method */
2317 ti = proto_tree_add_string(tree, hf_hdr_public,
2318 tvb, hdr_start, offset - hdr_start,
2319 val_to_str(val_id & 0x7F, vals_pdu_type,
2320 "<Unknown WSP method 0x%02X>"));
2324 ti = proto_tree_add_string(tree, hf_hdr_public,
2325 tvb, hdr_start, offset - hdr_start, val_str);
2327 wkh_3_ValueWithLength;
2329 wkh_4_End(hf_hdr_public);
2335 * Token-text | Short-integer
2338 wkh_vary(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2342 wkh_1_WellKnownValue;
2343 ti = proto_tree_add_string(tree, hf_hdr_vary,
2344 tvb, hdr_start, offset - hdr_start,
2345 val_to_str(val_id & 0x7F, vals_field_names,
2346 "<Unknown WSP header field 0x%02X>"));
2349 ti = proto_tree_add_string(tree, hf_hdr_vary,
2350 tvb, hdr_start, offset - hdr_start,
2353 wkh_3_ValueWithLength;
2355 wkh_4_End(hf_hdr_vary);
2360 * X-wap-security-value = 0x80
2363 wkh_x_wap_security(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2367 wkh_1_WellKnownValue;
2368 if (val_id == 0x80) {
2369 ti = proto_tree_add_string(tree, hf_hdr_x_wap_security,
2370 tvb, hdr_start, offset - hdr_start, "close-subordinate");
2375 wkh_3_ValueWithLength;
2377 wkh_4_End(hf_hdr_x_wap_security);
2382 * Connection-value = 0x80 | Token-text
2385 wkh_connection(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2389 wkh_1_WellKnownValue;
2390 if (val_id == 0x80) {
2391 ti = proto_tree_add_string(tree, hf_hdr_connection,
2392 tvb, hdr_start, offset - hdr_start, "close");
2396 ti = proto_tree_add_string(tree, hf_hdr_connection,
2397 tvb, hdr_start, offset - hdr_start, val_str);
2399 wkh_3_ValueWithLength;
2401 wkh_4_End(hf_hdr_connection);
2406 * Transfer-encoding-value = 0x80 | Token-text
2409 wkh_transfer_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2413 wkh_1_WellKnownValue;
2414 if (val_id == 0x80) {
2415 ti = proto_tree_add_string(tree, hf_hdr_transfer_encoding,
2416 tvb, hdr_start, offset - hdr_start, "chunked");
2420 ti = proto_tree_add_string(tree, hf_hdr_transfer_encoding,
2421 tvb, hdr_start, offset - hdr_start, val_str);
2423 wkh_3_ValueWithLength;
2425 wkh_4_End(hf_hdr_transfer_encoding);
2430 * Accept-range-value = 0x80 | 0x81 | Token-text
2433 wkh_accept_ranges(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2437 wkh_1_WellKnownValue;
2439 case 0x80: /* none */
2440 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2441 tvb, hdr_start, offset - hdr_start, "none");
2444 case 0x81: /* bytes */
2445 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2446 tvb, hdr_start, offset - hdr_start, "bytes");
2451 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2452 tvb, hdr_start, offset - hdr_start, val_str);
2454 wkh_3_ValueWithLength;
2456 wkh_4_End(hf_hdr_accept_ranges);
2461 * Content-encoding-value = 0x80 | 0x81 | 0x82 | Token-text
2464 wkh_content_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2468 wkh_1_WellKnownValue;
2470 case 0x80: /* gzip */
2471 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2472 tvb, hdr_start, offset - hdr_start, "gzip");
2475 case 0x81: /* compress */
2476 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2477 tvb, hdr_start, offset - hdr_start, "compress");
2480 case 0x82: /* deflate */
2481 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2482 tvb, hdr_start, offset - hdr_start, "deflate");
2487 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2488 tvb, hdr_start, offset - hdr_start, val_str);
2490 wkh_3_ValueWithLength;
2492 wkh_4_End(hf_hdr_content_encoding);
2497 * Accept-encoding-value =
2500 * | ( Value-length ( Short-integer | Text-string ) [ Q-value ] )
2503 wkh_accept_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2509 proto_tree *parameter_tree = NULL;
2511 wkh_1_WellKnownValue;
2513 case 0x80: /* gzip */
2514 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2515 tvb, hdr_start, offset - hdr_start, "gzip");
2518 case 0x81: /* compress */
2519 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2520 tvb, hdr_start, offset - hdr_start, "compress");
2523 case 0x82: /* deflate */
2524 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2525 tvb, hdr_start, offset - hdr_start, "deflate");
2530 proto_tree_add_string(tree, hf_hdr_accept_encoding,
2531 tvb, hdr_start, offset - hdr_start, val_str);
2533 wkh_3_ValueWithLength;
2534 off = val_start + val_len_len;
2535 peek = tvb_get_guint8(tvb, off);
2536 if (is_short_integer(peek)) {
2538 case 0x80: /* gzip */
2539 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2540 tvb, hdr_start, offset - hdr_start, "gzip");
2543 case 0x81: /* compress */
2544 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2545 tvb, hdr_start, offset - hdr_start, "compress");
2548 case 0x82: /* deflate */
2549 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2550 tvb, hdr_start, offset - hdr_start, "deflate");
2553 case 0x83: /* any */
2554 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2555 tvb, hdr_start, offset - hdr_start, "*");
2561 get_token_text(str, tvb, off, len, ok);
2563 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2564 tvb, hdr_start, offset - hdr_start, str);
2570 /* Remember: offset == val_start + val_len_len + val_len */
2571 if (off < offset) { /* Add Q-value if available */
2572 parameter_tree = proto_item_add_subtree(ti, ett_header);
2573 off = parameter_value_q(parameter_tree, ti, tvb, off);
2576 wkh_4_End(hf_hdr_accept_encoding);
2581 * Content-disposition-value = Value-length ( Disposition ) *( Parameter )
2582 * Disposition = Form-data | Attachment | Inline | Token-text
2586 * We handle this as:
2587 * Value-length ( Short-integer | Text-string ) *( Parameter )
2590 wkh_content_disposition(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2596 proto_tree *parameter_tree = NULL;
2598 wkh_1_WellKnownValue;
2602 wkh_3_ValueWithLength;
2603 off = val_start + val_len_len;
2604 peek = tvb_get_guint8(tvb, off);
2605 if (is_short_integer(peek)) {
2607 case 0x80: /* form-data */
2608 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2609 tvb, hdr_start, offset - hdr_start, "form-data");
2612 case 0x81: /* attachment */
2613 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2614 tvb, hdr_start, offset - hdr_start, "attachment");
2617 case 0x82: /* inline */
2618 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2619 tvb, hdr_start, offset - hdr_start, "inline");
2625 get_token_text(str, tvb, off, len, ok);
2627 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2628 tvb, hdr_start, offset - hdr_start, str);
2633 if ((ok) && (off < offset)) {
2634 /* Remember: offset == val_start + val_len_len + val_len */
2635 parameter_tree = proto_item_add_subtree(ti, ett_header);
2636 while (off < offset) { /* Add parameters if available */
2637 off = parameter(parameter_tree, ti, tvb, off, offset - off);
2640 wkh_4_End(hf_hdr_content_disposition);
2645 * Common code for headers with only a textual value
2646 * is written in the macro below:
2648 #define wkh_text_header(underscored,Text) \
2650 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2652 wkh_0_Declarations; \
2654 wkh_1_WellKnownValue; \
2656 wkh_2_TextualValue; \
2657 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2658 tvb, hdr_start, offset - hdr_start, val_str); \
2660 wkh_3_ValueWithLength; \
2662 wkh_4_End(hf_hdr_ ## underscored); \
2665 /* Text-only headers: */
2666 wkh_text_header(content_base, "Content-Base")
2667 wkh_text_header(content_location, "Content-Location")
2668 wkh_text_header(etag, "ETag")
2669 wkh_text_header(from, "From")
2670 wkh_text_header(host, "Host")
2671 wkh_text_header(if_match, "If-Match")
2672 wkh_text_header(if_none_match, "If-None-Match")
2673 wkh_text_header(location, "Location")
2674 wkh_text_header(referer, "Referer")
2675 wkh_text_header(server, "Server")
2676 wkh_text_header(user_agent, "User-Agent")
2677 wkh_text_header(upgrade, "Upgrade")
2678 wkh_text_header(via, "Via")
2679 wkh_text_header(content_uri, "Content-Uri")
2680 wkh_text_header(initiator_uri, "Initiator-Uri")
2681 wkh_text_header(profile, "Profile")
2684 * Same for quoted-string value
2686 #define wkh_quoted_string_header(underscored,Text) \
2688 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2690 wkh_0_Declarations; \
2693 wkh_1_WellKnownValue; \
2695 wkh_2_TextualValue; \
2696 if (is_quoted_string(val_str[0])) { \
2697 if (is_quoted_string(val_str[val_len-2])) { \
2698 /* Trailing quote - issue a warning */ \
2699 str = g_strdup_printf("%s" TrailingQuoteWarning, val_str); \
2700 } else { /* OK (no trailing quote) */ \
2701 str = g_strdup_printf("%s\"", val_str); \
2703 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2704 tvb, hdr_start, offset - hdr_start, str); \
2707 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2708 tvb, hdr_start, offset - hdr_start, val_str); \
2709 proto_item_append_text(ti, \
2710 " <Warning: should be encoded as a Quoted-string>"); \
2713 wkh_3_ValueWithLength; \
2715 wkh_4_End(hf_hdr_ ## underscored); \
2718 wkh_quoted_string_header(content_id, "Content-ID")
2722 * Common code for headers with only a textual or a date value
2723 * is written in the macro below:
2725 #define wkh_text_or_date_value_header(underscored,Text) \
2727 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2729 wkh_0_Declarations; \
2730 guint32 val = 0, off = val_start, len; \
2732 gchar *str; /* may not be freed! */ \
2734 wkh_1_WellKnownValue; \
2736 wkh_2_TextualValue; \
2737 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2738 tvb, hdr_start, offset - hdr_start, val_str); \
2740 wkh_3_ValueWithLength; \
2741 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2742 get_date_value(val, tvb, off, len, ok); \
2746 str = abs_time_to_str(&tv); \
2748 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2749 tvb, hdr_start, offset - hdr_start, str); \
2750 /* BEHOLD: do NOT try to free str, as this generates a core
2751 * dump! It looks like abs_time_to_str() is buggy or works
2752 * with static data. */ \
2755 wkh_4_End(hf_hdr_ ## underscored); \
2759 wkh_text_or_date_value_header(if_range,"If-Range")
2763 * Common code for headers with only a date value
2764 * is written in the macro below:
2766 #define wkh_date_value_header(underscored,Text) \
2768 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2770 wkh_0_Declarations; \
2771 guint32 val = 0, off = val_start, len; \
2773 gchar *str; /* may not be freed! */ \
2775 wkh_1_WellKnownValue; \
2777 wkh_2_TextualValue; \
2779 wkh_3_ValueWithLength; \
2780 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2781 get_date_value(val, tvb, off, len, ok); \
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); \
2789 /* BEHOLD: do NOT try to free str, as this generates a core
2790 * dump! It looks like abs_time_to_str() is buggy or works
2791 * with static data. */ \
2794 wkh_4_End(hf_hdr_ ## underscored); \
2797 /* Date-value only headers: */
2798 wkh_date_value_header(date, "Date")
2799 wkh_date_value_header(expires, "Expires")
2800 wkh_date_value_header(if_modified_since, "If-Modified-Since")
2801 wkh_date_value_header(if_unmodified_since, "If-Unmodified-Since")
2802 wkh_date_value_header(last_modified, "Last-Modified")
2805 /* Date-value with special interpretation of zero value */
2806 #define wkh_tod_value_header(underscored,Text) \
2808 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2810 wkh_0_Declarations; \
2811 guint32 val = 0, off = val_start, len; \
2813 gchar *str; /* may not be freed! */ \
2815 wkh_1_WellKnownValue; \
2816 if (val_id == 0x80) { /* Openwave TOD header uses this format */ \
2817 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2818 tvb, hdr_start, offset - hdr_start, \
2819 "Requesting Time Of Day"); \
2820 proto_item_append_text(ti, \
2821 " <Warning: should be encoded as long-integer>"); \
2824 /* It seems VERY unlikely that we'll see date values within the first \
2825 * 127 seconds of the UNIX 1-1-1970 00:00:00 start of the date clocks \
2826 * so I assume such a value is a genuine error */ \
2827 wkh_2_TextualValue; \
2829 wkh_3_ValueWithLength; \
2830 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2831 get_date_value(val, tvb, off, len, ok); \
2834 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2835 tvb, hdr_start, offset - hdr_start, \
2836 "Requesting Time Of Day"); \
2840 str = abs_time_to_str(&tv); \
2842 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2843 tvb, hdr_start, offset - hdr_start, str); \
2847 wkh_4_End(hf_hdr_ ## underscored); \
2850 wkh_tod_value_header(x_wap_tod, "X-Wap-Tod")
2854 * Age-value: Delta-seconds-value
2857 wkh_age(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
2860 guint32 val = 0, off = val_start, len;
2862 wkh_1_WellKnownValue;
2863 val = val_id & 0x7F;
2864 val_str = g_strdup_printf("%u second%s", val, PLURALIZE(val));
2865 ti = proto_tree_add_string(tree, hf_hdr_age,
2866 tvb, hdr_start, offset - hdr_start, val_str);
2867 g_free(val_str); /* proto_XXX creates a copy */
2871 wkh_3_ValueWithLength;
2872 if (val_id <= 4) { /* Length field already parsed by macro! */
2873 get_long_integer(val, tvb, off, len, ok);
2875 val_str = g_strdup_printf("%u second%s", val, PLURALIZE(val));
2876 ti = proto_tree_add_string(tree, hf_hdr_age,
2877 tvb, hdr_start, offset - hdr_start, val_str);
2878 g_free(val_str); /* proto_XXX creates a copy */
2881 wkh_4_End(hf_hdr_age);
2886 * Template for Integer lookup or text value headers:
2888 #define wkh_integer_lookup_or_text_value(underscored,Text,valueString,valueName) \
2890 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
2892 wkh_0_Declarations; \
2893 guint32 val = 0, off = val_start, len; \
2895 wkh_1_WellKnownValue; \
2896 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2897 tvb, hdr_start, offset - hdr_start, \
2898 val_to_str(val_id & 0x7F, valueString, \
2899 "(Unknown " valueName " identifier 0x%X)")); \
2901 wkh_2_TextualValue; \
2902 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2903 tvb, hdr_start, offset - hdr_start, val_str); \
2905 wkh_3_ValueWithLength; \
2906 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2907 get_long_integer(val, tvb, off, len, ok); \
2909 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2910 tvb, hdr_start, offset - hdr_start, \
2911 val_to_str(val_id & 0x7F, valueString, \
2912 "(Unknown " valueName " identifier 0x%X)")); \
2915 wkh_4_End(hf_hdr_ ## underscored); \
2919 * Wap-application-value: Uri-value | Integer-value
2921 wkh_integer_lookup_or_text_value(x_wap_application_id, "X-Wap-Application-Id",
2922 vals_wap_application_ids, "WAP application")
2923 wkh_integer_lookup_or_text_value(accept_application, "Accept-Application",
2924 vals_wap_application_ids, "WAP application")
2925 wkh_integer_lookup_or_text_value(content_language, "Content-Language",
2926 vals_languages, "language")
2927 /* NOTE - Although the WSP spec says this is an integer-value, the WSP headers
2928 * are encoded as a 7-bit entity! */
2929 wkh_integer_lookup_or_text_value(trailer, "Trailer",
2930 vals_field_names, "well-known-header")
2938 * Common code for headers with only a challenge value
2939 * is written in the macro below:
2941 #define wkh_challenge_value_header(underscored,Text) \
2943 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, \
2944 guint32 hdr_start) \
2946 wkh_0_Declarations; \
2949 proto_tree *subtree; \
2952 wkh_1_WellKnownValue; \
2954 wkh_2_TextualValue; \
2956 wkh_3_ValueWithLength; \
2957 off = val_start + val_len_len; \
2958 peek = tvb_get_guint8(tvb, off); \
2959 if (peek == 0x80) { /* Basic */ \
2960 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2961 tvb, hdr_start, offset - hdr_start, "basic"); \
2962 subtree = proto_item_add_subtree(ti, ett_header); \
2963 proto_tree_add_string(subtree, hf_hdr_ ## underscored ## _scheme, \
2964 tvb, off, 1, "basic"); \
2966 /* Realm: text-string */ \
2967 get_text_string(str,tvb,off,len,ok); \
2969 proto_tree_add_string(subtree, \
2970 hf_hdr_ ## underscored ## _realm, \
2971 tvb, off, len, str); \
2972 val_str = g_strdup_printf("; realm=%s", str); \
2973 proto_item_append_string(ti, val_str); \
2978 } else { /* Authentication-scheme: token-text */ \
2979 get_token_text(str, tvb, off, len, ok); \
2981 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2982 tvb, hdr_start, off - hdr_start, str); \
2983 subtree = proto_item_add_subtree(ti, ett_header); \
2984 proto_tree_add_string(subtree, \
2985 hf_hdr_ ## underscored ## _scheme, \
2986 tvb, hdr_start, off - hdr_start, str); \
2989 /* Realm: text-string */ \
2990 get_text_string(str,tvb,off,len,ok); \
2992 proto_tree_add_string(subtree, \
2993 hf_hdr_ ## underscored ## _realm, \
2994 tvb, off, len, str); \
2995 val_str = g_strdup_printf("; realm=%s", str); \
2996 proto_item_append_string(ti, val_str); \
3000 /* Auth-params: parameter - TODO */ \
3001 while (off < offset) /* Parse parameters */ \
3002 off = parameter(subtree, ti, tvb, off, offset - off); \
3006 wkh_4_End(hf_hdr_ ## underscored); \
3009 /* Challenge-value only headers: */
3010 wkh_challenge_value_header(www_authenticate, "WWW-Authenticate")
3011 wkh_challenge_value_header(proxy_authenticate, "Proxy-Authenticate")
3019 * Common code for headers with only a credentials value
3020 * is written in the macro below:
3022 #define wkh_credentials_value_header(underscored,Text) \
3024 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, \
3025 guint32 hdr_start) \
3027 wkh_0_Declarations; \
3030 proto_tree *subtree; \
3033 wkh_1_WellKnownValue; \
3035 wkh_2_TextualValue; \
3037 wkh_3_ValueWithLength; \
3038 off = val_start + val_len_len; \
3039 peek = tvb_get_guint8(tvb, off); \
3040 if (peek == 0x80) { /* Basic */ \
3041 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3042 tvb, hdr_start, offset - hdr_start, "basic"); \
3043 subtree = proto_item_add_subtree(ti, ett_header); \
3044 proto_tree_add_string(subtree, hf_hdr_ ## underscored ## _scheme, \
3045 tvb, off, 1, "basic"); \
3047 /* User-id: text-string */ \
3048 get_text_string(str,tvb,off,len,ok); \
3050 proto_tree_add_string(subtree, \
3051 hf_hdr_ ## underscored ## _user_id, \
3052 tvb, off, len, str); \
3053 val_str = g_strdup_printf("; user-id=%s", str); \
3054 proto_item_append_string(ti, val_str); \
3058 /* Password: text-string */ \
3059 get_text_string(str,tvb,off,len,ok); \
3061 proto_tree_add_string(subtree, \
3062 hf_hdr_ ## underscored ## _password, \
3063 tvb, off, len, str); \
3064 val_str = g_strdup_printf("; password=%s", str); \
3065 proto_item_append_string(ti, val_str); \
3071 } else { /* Authentication-scheme: token-text */ \
3072 get_token_text(str, tvb, off, len, ok); \
3074 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3075 tvb, hdr_start, off - hdr_start, str); \
3076 subtree = proto_item_add_subtree(ti, ett_header); \
3077 proto_tree_add_string(subtree, \
3078 hf_hdr_ ## underscored ## _scheme, \
3079 tvb, hdr_start, off - hdr_start, str); \
3082 /* Auth-params: parameter - TODO */ \
3083 while (off < offset) /* Parse parameters */ \
3084 off = parameter(subtree, ti, tvb, off, offset - off); \
3087 wkh_4_End(hf_hdr_ ## underscored); \
3090 /* Credentials-value only headers: */
3091 wkh_credentials_value_header(authorization, "Authorization")
3092 wkh_credentials_value_header(proxy_authorization, "Proxy-Authorization")
3096 * Content-md5-value = 16*16 OCTET
3099 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3104 wkh_1_WellKnownValue;
3108 wkh_3_ValueWithLength;
3109 off = val_start + val_len_len;
3110 if (val_len == 16) {
3111 val_str = g_strdup_printf(
3112 "%02x%02x%02x%02x%02x%02x%02x%02x"
3113 "%02x%02x%02x%02x%02x%02x%02x%02x",
3114 tvb_get_guint8(tvb, off),
3115 tvb_get_guint8(tvb, off + 1),
3116 tvb_get_guint8(tvb, off + 2),
3117 tvb_get_guint8(tvb, off + 3),
3118 tvb_get_guint8(tvb, off + 4),
3119 tvb_get_guint8(tvb, off + 5),
3120 tvb_get_guint8(tvb, off + 6),
3121 tvb_get_guint8(tvb, off + 7),
3122 tvb_get_guint8(tvb, off + 8),
3123 tvb_get_guint8(tvb, off + 9),
3124 tvb_get_guint8(tvb, off + 10),
3125 tvb_get_guint8(tvb, off + 11),
3126 tvb_get_guint8(tvb, off + 12),
3127 tvb_get_guint8(tvb, off + 13),
3128 tvb_get_guint8(tvb, off + 14),
3129 tvb_get_guint8(tvb, off + 15)
3131 ti = proto_tree_add_string(tree, hf_hdr_content_md5,
3132 tvb, hdr_start, offset - hdr_start, val_str);
3136 wkh_4_End(hf_hdr_content_md5);
3141 * Pragma-value = 0x80 | Length Parameter
3144 wkh_pragma(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3149 wkh_1_WellKnownValue;
3150 if (val_id == 0x80) {
3151 ti = proto_tree_add_string(tree, hf_hdr_pragma,
3152 tvb, hdr_start, offset - hdr_start, "no-cache");
3157 wkh_3_ValueWithLength;
3158 off = val_start + val_len_len;
3159 ti = proto_tree_add_string(tree, hf_hdr_pragma,
3160 tvb, hdr_start, off - hdr_start, "");
3161 /* NULL subtree for parameter() results in no subtree
3162 * TODO - provide a single parameter dissector that appends data
3163 * to the header field data. */
3164 off = parameter(NULL, ti, tvb, off, offset - off);
3166 wkh_4_End(hf_hdr_pragma);
3173 #define wkh_integer_value_header(underscored,Text) \
3175 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
3177 wkh_0_Declarations; \
3178 guint32 val = 0, off = val_start, len; \
3179 gchar *str; /* may not be freed! */ \
3181 wkh_1_WellKnownValue; \
3182 str = g_strdup_printf("%u", val_id & 0x7F); \
3183 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3184 tvb, hdr_start, offset - hdr_start, str); \
3187 wkh_2_TextualValue; \
3189 wkh_3_ValueWithLength; \
3190 if (val_id <= 4) { /* Length field already parsed by macro! */ \
3191 get_long_integer(val, tvb, off, len, ok); \
3193 str = g_strdup_printf("%u", val); \
3194 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3195 tvb, hdr_start, offset - hdr_start, str); \
3199 wkh_4_End(hf_hdr_ ## underscored); \
3202 wkh_integer_value_header(content_length, "Content-Length")
3203 wkh_integer_value_header(max_forwards, "Max-Forwards")
3206 #define wkh_integer_lookup_value_header(underscored,Text,valueString,valueName) \
3208 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start) \
3210 wkh_0_Declarations; \
3211 guint32 val = 0, off = val_start, len; \
3213 wkh_1_WellKnownValue; \
3214 val_str = match_strval(val_id & 0x7F, valueString); \
3216 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3217 tvb, hdr_start, offset - hdr_start, val_str); \
3220 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3221 tvb, hdr_start, offset - hdr_start, \
3222 "<Unknown " valueName ">"); \
3224 wkh_2_TextualValue; \
3226 wkh_3_ValueWithLength; \
3227 if (val_id <= 4) { /* Length field already parsed by macro! */ \
3228 get_long_integer(val, tvb, off, len, ok); \
3230 val_str = match_strval(val_id & 0x7F, valueString); \
3232 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3233 tvb, hdr_start, offset - hdr_start, val_str); \
3236 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3237 tvb, hdr_start, offset - hdr_start, \
3238 "<Unknown " valueName ">"); \
3242 wkh_4_End(hf_hdr_ ## underscored); \
3245 wkh_integer_lookup_value_header(bearer_indication, "Bearer-Indication",
3246 vals_bearer_types, "bearer type")
3250 * Cache-control-value
3253 wkh_cache_control(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3256 guint32 off, len, val = 0;
3257 guint8 peek, cache_control_directive;
3260 wkh_1_WellKnownValue;
3261 val = val_id & 0x7F;
3262 val_str = match_strval(val, vals_cache_control);
3264 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3265 tvb, hdr_start, offset - hdr_start, val_str);
3269 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3270 tvb, hdr_start, offset - hdr_start, val_str);
3272 wkh_3_ValueWithLength;
3274 * ( no-cache | private ) 1*( Field-name )
3275 * | ( max-age | max-stale | min-fresh | s-maxage) Delta-seconds-value
3276 * | Token-text ( Integer-value | Text-value )
3278 * Field-name = Short-integer | Token-text
3280 off = val_start + val_len_len;
3281 cache_control_directive = tvb_get_guint8(tvb, off++);
3282 if (cache_control_directive & 0x80) { /* Well known cache directive */
3283 switch (cache_control_directive & 0x7F) {
3284 case CACHE_CONTROL_NO_CACHE:
3285 case CACHE_CONTROL_PRIVATE:
3286 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3287 tvb, hdr_start, offset - hdr_start,
3288 val_to_str (cache_control_directive & 0x7F, vals_cache_control,
3289 "<Unknown cache control directive 0x%02X>"));
3290 /* TODO: split multiple entries */
3291 while (ok && (off < offset)) { /* 1*( Field-name ) */
3293 peek = tvb_get_guint8(tvb, off);
3294 if (peek & 0x80) { /* Well-known-field-name */
3295 proto_item_append_string(ti,
3296 val_to_str (peek, vals_field_names,
3297 "<Unknown WSP header field 0x%02X>"));
3299 } else { /* Token-text */
3300 get_token_text(val_str, tvb, off, len, ok);
3302 proto_item_append_string(ti, val_str);
3310 case CACHE_CONTROL_MAX_AGE:
3311 case CACHE_CONTROL_MAX_STALE:
3312 case CACHE_CONTROL_MIN_FRESH:
3313 case CACHE_CONTROL_S_MAXAGE:
3314 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3315 tvb, hdr_start, offset - hdr_start,
3316 val_to_str (cache_control_directive & 0x7F, vals_cache_control,
3317 "<Unknown cache control directive 0x%02X>"));
3318 get_delta_seconds_value(val, tvb, off, len, ok);
3320 val_str = g_strdup_printf("=%u second%s",
3321 val, PLURALIZE(val));
3322 proto_item_append_string(ti, val_str);
3323 g_free(val_str); /* proto_XXX creates a copy */
3331 } else if (is_token_text(cache_control_directive)) {
3332 get_token_text(val_str, tvb, off, len, ok);
3334 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3335 tvb, hdr_start, offset - hdr_start, val_str);
3337 get_integer_value(val, tvb, off, len, ok);
3338 if (ok) { /* Integer-value */
3339 val_str = g_strdup_printf("=%u", val);
3340 proto_item_append_string(ti, val_str);
3341 g_free(val_str); /* proto_XXX creates a copy */
3342 } else { /* Text-value */
3343 get_text_string(val_str, tvb, off, len, ok);
3345 if (is_quoted_string(val_str[0])) {
3346 if (is_quoted_string(val_str[len-2])) {
3347 /* Trailing quote - issue a warning */
3348 str = g_strdup_printf("%s" TrailingQuoteWarning,
3350 } else { /* OK (no trailing quote) */
3351 str = g_strdup_printf("%s\"", val_str);
3353 proto_item_append_string(ti, str);
3355 } else { /* Token-text | 0x00 */
3356 /* TODO - check that we have Token-text or 0x00 */
3357 proto_item_append_string(ti, val_str);
3364 wkh_4_End(hf_hdr_cache_control);
3371 * | ( Value-length Short-integer Text-string Text-string )
3374 wkh_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3377 guint32 off, len, val;
3380 proto_tree *subtree;
3382 /* TODO - subtree with values */
3384 wkh_1_WellKnownValue;
3385 val = val_id & 0x7F;
3386 val_str = match_strval(val, vals_wsp_warning_code);
3388 ti = proto_tree_add_string(tree, hf_hdr_warning,
3389 tvb, hdr_start, offset - hdr_start, val_str);
3390 subtree = proto_item_add_subtree(ti, ett_header);
3391 proto_tree_add_uint(subtree, hf_hdr_warning_code,
3392 tvb, val_start, 1, val);
3397 wkh_3_ValueWithLength;
3398 /* TODO - subtree with individual values */
3399 off = val_start + val_len_len;
3400 warn_code = tvb_get_guint8(tvb, off);
3401 if (warn_code & 0x80) { /* Well known warn code */
3402 val = warn_code & 0x7f;
3403 val_str = match_strval(val, vals_wsp_warning_code_short);
3404 if (val_str) { /* OK */
3405 str = g_strdup_printf("code=%s", val_str);
3406 ti = proto_tree_add_string(tree, hf_hdr_warning,
3407 tvb, hdr_start, offset - hdr_start, str);
3409 subtree = proto_item_add_subtree(ti, ett_header);
3410 proto_tree_add_uint(subtree, hf_hdr_warning_code,
3412 off++; /* Now skip to the warn-agent subfield */
3413 get_text_string(str, tvb, off, len, ok);
3414 if (ok) { /* Valid warn-agent string */
3415 proto_tree_add_string(subtree, hf_hdr_warning_agent,
3416 tvb, off, len, str);
3417 val_str = g_strdup_printf("; agent=%s", str);
3418 proto_item_append_string(ti, val_str);
3419 g_free(val_str); /* proto_XXX creates a copy */
3422 get_text_string(str, tvb, off, len, ok);
3423 if (ok) { /* Valid warn-text string */
3424 proto_tree_add_string(subtree,
3425 hf_hdr_warning_text,
3426 tvb, off, len, str);
3427 val_str = g_strdup_printf("; text=%s", str);
3428 proto_item_append_string(ti, val_str);
3429 g_free(val_str); /* proto_XXX creates a copy */
3436 wkh_4_End(hf_hdr_warning);
3441 * Profile-warning-value =
3443 * | ( Value-length Short-integer Text-string *( Date-value ) )
3446 wkh_profile_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3449 guint32 off, len, val = 0;
3454 wkh_1_WellKnownValue;
3455 val = val_id & 0x7F;
3456 val_str = match_strval(val, vals_wsp_profile_warning_code);
3458 ti = proto_tree_add_string(tree, hf_hdr_profile_warning,
3459 tvb, hdr_start, offset - hdr_start, val_str);
3464 wkh_3_ValueWithLength;
3465 off = val_start + val_len_len;
3466 warn_code = tvb_get_guint8(tvb, off++);
3467 if (warn_code & 0x80) { /* Well known warn code */
3468 val_str = match_strval(val, vals_wsp_profile_warning_code);
3469 if (val_str) { /* OK */
3470 ti = proto_tree_add_string(tree, hf_hdr_profile_warning,
3471 tvb, hdr_start, offset - hdr_start, val_str);
3472 get_uri_value(str, tvb, off, len, ok);
3473 if (ok) { /* Valid warn-target string */
3475 str = g_strdup_printf("; target=%s", val_str);
3476 proto_item_append_string(ti, str);
3477 g_free(str); /* proto_XXX creates a copy */
3478 /* Add zero or more dates */
3479 while (ok && (off < offset)) {
3480 get_date_value(val, tvb, off, len, ok);
3481 if (ok) { /* Valid warn-text string */
3485 val_str = abs_time_to_str(&tv);
3487 str = g_strdup_printf("; date=%s", val_str);
3488 proto_item_append_string(ti, str);
3489 g_free(str); /* proto_XXX creates a copy */
3490 /* BEHOLD: do NOT try to free val_str, as this
3491 * generates a core dump!
3492 * It looks like abs_time_to_str() is
3493 * buggy or works with static data. */
3499 wkh_4_End(hf_hdr_profile_warning);
3503 /* Encoding-version-value =
3506 * | Length Short-integer [ Short-integer | text-string ]
3508 static guint32 wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb,
3512 guint32 off, val, len;
3515 wkh_1_WellKnownValue;
3516 val = val_id & 0x7F;
3517 val_str = g_strdup_printf("%u.%u", val >> 4, val & 0x0F);
3518 proto_tree_add_string(tree, hf_hdr_encoding_version,
3519 tvb, hdr_start, offset - hdr_start, val_str);
3523 proto_tree_add_string(tree, hf_hdr_encoding_version,
3524 tvb, hdr_start, offset - hdr_start, val_str);
3526 wkh_3_ValueWithLength;
3527 off = val_start + val_len_len;
3528 val = tvb_get_guint8(tvb, off);
3529 if (val & 0x80) { /* Header Code Page */
3530 val_str = g_strdup_printf("code-page=%u", val & 0x7F);
3531 ti = proto_tree_add_string(tree, hf_hdr_encoding_version,
3532 tvb, hdr_start, offset - hdr_start, val_str);
3536 if (off < offset) { /* Extra version-value */
3537 get_version_value(val,val_str,tvb,off,len,ok);
3538 if (ok) { /* Always creates a string if OK */
3539 str = g_strdup_printf(": %s", val_str);
3540 proto_item_append_string(ti, str);
3547 wkh_4_End(hf_hdr_encoding_version);
3551 /* Content-range-value =
3552 * Length Uintvar-integer ( 0x80 | Uintvar-integer )
3555 wkh_content_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3558 guint32 off, val, len;
3559 proto_tree *subtree = NULL;
3561 wkh_1_WellKnownValue;
3565 wkh_3_ValueWithLength;
3566 off = val_start + val_len_len;
3567 get_uintvar_integer (val, tvb, off, len, ok); /* Uintvar start */
3569 val_str = g_strdup_printf("first-byte-pos=%u", val);
3570 ti = proto_tree_add_string(tree, hf_hdr_content_range,
3571 tvb, hdr_start, offset - hdr_start, val_str);
3572 subtree = proto_item_add_subtree(ti, ett_header);
3573 proto_tree_add_uint(subtree, hf_hdr_content_range_first_byte_pos,
3574 tvb, off, len, val);
3577 /* Now check next value */
3578 val = tvb_get_guint8(tvb, off);
3579 if (val == 0x80) { /* Unknown length */
3580 proto_item_append_string(ti, "; entity-length=unknown");
3581 } else { /* Uintvar entity length */
3582 get_uintvar_integer (val, tvb, off, len, ok);
3584 val_str = g_strdup_printf("; entity-length=%u", val);
3585 proto_item_append_string(ti, val_str);
3586 proto_tree_add_uint(subtree,
3587 hf_hdr_content_range_entity_length,
3588 tvb, off, len, val);
3594 wkh_4_End(hf_hdr_content_range);
3600 * 0x80 Uintvar-integer [ Uintvar-integer ]
3601 * | 0x81 Uintvar-integer
3604 wkh_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3607 guint32 off, val, len;
3608 proto_tree *subtree = NULL;
3610 wkh_1_WellKnownValue;
3614 wkh_3_ValueWithLength;
3615 off = val_start + val_len_len;
3616 val = tvb_get_guint8(tvb, off);
3617 if (val == 0x80) { /* Byte-range */
3618 ti = proto_tree_add_string(tree, hf_hdr_range,
3619 tvb, hdr_start, offset - hdr_start, "byte-range");
3620 subtree = proto_item_add_subtree(ti, ett_header);
3621 /* Get the First-byte-pos (Uintvar-integer) */
3622 get_uintvar_integer (val, tvb, off, len, ok);
3624 val_str = g_strdup_printf("; first-byte-pos=%u", val);
3625 proto_item_append_string(ti, val_str);
3626 proto_tree_add_uint(subtree, hf_hdr_range_first_byte_pos,
3627 tvb, off, len, val);
3630 /* Get the optional Last-byte-pos (Uintvar-integer) */
3632 get_uintvar_integer (val, tvb, off, len, ok);
3634 val_str = g_strdup_printf("; last-byte-pos=%u", val);
3635 proto_item_append_string(ti, val_str);
3636 proto_tree_add_uint(subtree,
3637 hf_hdr_range_last_byte_pos,
3638 tvb, off, len, val);
3643 } else if (val == 0x81) { /* Suffix-byte-range */
3644 ti = proto_tree_add_string(tree, hf_hdr_range,
3645 tvb, hdr_start, offset - hdr_start, "suffix-byte-range");
3646 subtree = proto_item_add_subtree(ti, ett_header);
3647 /* Get the Suffix-length (Uintvar-integer) */
3648 get_uintvar_integer (val, tvb, off, len, ok);
3650 val_str = g_strdup_printf("; suffix-length=%u", val);
3651 proto_item_append_string(ti, val_str);
3652 proto_tree_add_uint(subtree, hf_hdr_range_suffix_length,
3653 tvb, off, len, val);
3658 wkh_4_End(hf_hdr_range);
3664 * | Value-length (0x82--0x86 | Token-text) [ Q-token Q-value ]
3666 static guint32 wkh_te (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3669 guint32 off, val, len;
3671 wkh_1_WellKnownValue;
3672 if (val_id == 0x81) {
3673 proto_tree_add_string(tree, hf_hdr_encoding_version,
3674 tvb, hdr_start, offset - hdr_start, "trailers");
3679 wkh_3_ValueWithLength;
3680 off = val_start + val_len_len;
3681 val = tvb_get_guint8(tvb, off);
3682 if (val & 0x80) { /* Well-known-TE */
3683 val_str = match_strval((val & 0x7F), vals_well_known_te);
3685 ti = proto_tree_add_string(tree, hf_hdr_te,
3686 tvb, hdr_start, off - hdr_start, val_str);
3690 } else { /* TE in Token-text format */
3691 get_token_text(val_str, tvb, off, len, ok);
3692 ti = proto_tree_add_string(tree, hf_hdr_te,
3693 tvb, hdr_start, off - hdr_start, val_str);
3698 if ((ok) && (off < offset)) { /* Q-token Q-value */
3702 wkh_4_End(hf_hdr_te);
3706 /****************************************************************************
3707 * O p e n w a v e h e a d e r s
3708 ****************************************************************************/
3714 * Redefine the WellKnownValue parsing so Openwave header field names are used
3715 * are used instead of the default WSP header field names
3717 #undef wkh_1_WellKnownValue
3718 #define wkh_1_WellKnownValue /* Parse Well Known Value */ \
3719 proto_tree_add_string_hidden(tree, hf_hdr_name, \
3720 tvb, hdr_start, offset - hdr_start, \
3721 val_to_str (hdr_id, vals_openwave_field_names, \
3722 "<Unknown WSP header field 0x%02X>")); \
3723 if (val_id & 0x80) { /* Well-known value */ \
3725 /* Well-known value processing starts HERE \
3730 * Redefine the End parsing so Openwave header field names are used
3731 * instead of the default WSP field names
3734 #define wkh_4_End(hf) /* End of value parsing */ \
3737 /* Check for errors */ \
3739 if (ti) { /* Append to protocol tree item label */ \
3740 proto_item_append_text(ti, \
3741 "<Error: Invalid header value>"); \
3742 } else if (hf > 0) { /* Create protocol tree item */ \
3743 proto_tree_add_string(tree, hf, \
3744 tvb, hdr_start, offset - hdr_start, \
3745 " <Error: Invalid header value>"); \
3746 } else { /* Create anonymous header field entry */ \
3747 proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start, \
3748 "%s: <Error: Invalid header value>", \
3749 val_to_str (hdr_id, vals_openwave_field_names, \
3750 "<Unknown WSP header field 0x%02X>")); \
3756 /* Dissect the Openwave header value (generic) */
3758 wkh_openwave_default(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start)
3762 ok = TRUE; /* Bypass error checking as we don't parse the values! */
3764 wkh_1_WellKnownValue;
3765 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
3766 "%s: (Undecoded well-known value 0x%02x)",
3767 val_to_str (hdr_id, vals_openwave_field_names,
3768 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F);
3770 ti = proto_tree_add_text(tree,tvb,hdr_start, offset - hdr_start,
3772 val_to_str (hdr_id, vals_openwave_field_names,
3773 "<Unknown WSP header field 0x%02X>"), val_str);
3774 wkh_3_ValueWithLength;
3775 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
3776 "%s: (Undecoded value in general form with length indicator)",
3777 val_to_str (hdr_id, vals_openwave_field_names,
3778 "<Unknown WSP header field 0x%02X>"));
3780 wkh_4_End(HF_EMPTY); /* See wkh_default for explanation */
3784 /* Textual Openwave headers */
3785 wkh_text_header(openwave_x_up_proxy_operator_domain,
3786 "x-up-proxy-operator-domain")
3787 wkh_text_header(openwave_x_up_proxy_home_page,
3788 "x-up-proxy-home-page")
3789 wkh_text_header(openwave_x_up_proxy_uplink_version,
3790 "x-up-proxy-uplink-version")
3791 wkh_text_header(openwave_x_up_proxy_ba_realm,
3792 "x-up-proxy-ba-realm")
3793 wkh_text_header(openwave_x_up_proxy_request_uri,
3794 "x-up-proxy-request-uri")
3795 wkh_text_header(openwave_x_up_proxy_bookmark,
3796 "x-up-proxy-bookmark")
3798 /* Integer Openwave headers */
3799 wkh_integer_value_header(openwave_x_up_proxy_push_seq,
3800 "x-up-proxy-push-seq")
3801 wkh_integer_value_header(openwave_x_up_proxy_notify,
3802 "x-up-proxy-notify")
3803 wkh_integer_value_header(openwave_x_up_proxy_net_ask,
3804 "x-up-proxy-net-ask")
3805 wkh_integer_value_header(openwave_x_up_proxy_ba_enable,
3806 "x-up-proxy-ba-enable")
3807 wkh_integer_value_header(openwave_x_up_proxy_redirect_enable,
3808 "x-up-proxy-redirect-enable")
3809 wkh_integer_value_header(openwave_x_up_proxy_redirect_status,
3810 "x-up-proxy-redirect-status")
3811 wkh_integer_value_header(openwave_x_up_proxy_linger,
3812 "x-up-proxy-linger")
3813 wkh_integer_value_header(openwave_x_up_proxy_enable_trust,
3814 "x-up-proxy-enable-trust")
3815 wkh_integer_value_header(openwave_x_up_proxy_trust,
3818 wkh_integer_value_header(openwave_x_up_devcap_has_color,
3819 "x-up-devcap-has-color")
3820 wkh_integer_value_header(openwave_x_up_devcap_num_softkeys,
3821 "x-up-devcap-num-softkeys")
3822 wkh_integer_value_header(openwave_x_up_devcap_softkey_size,
3823 "x-up-devcap-softkey-size")
3824 wkh_integer_value_header(openwave_x_up_devcap_screen_chars,
3825 "x-up-devcap-screen-chars")
3826 wkh_integer_value_header(openwave_x_up_devcap_screen_pixels,
3827 "x-up-devcap-screen-pixels")
3828 wkh_integer_value_header(openwave_x_up_devcap_em_size,
3829 "x-up-devcap-em-size")
3830 wkh_integer_value_header(openwave_x_up_devcap_screen_depth,
3831 "x-up-devcap-screen-depth")
3832 wkh_integer_value_header(openwave_x_up_devcap_immed_alert,
3833 "x-up-devcap-immed_alert")
3834 wkh_integer_value_header(openwave_x_up_devcap_gui,
3837 /* Openwave Time-Of-Day value header */
3838 wkh_tod_value_header(openwave_x_up_proxy_tod,
3841 /* Openwave accept_x_q header */
3842 wkh_accept_x_q_header(openwave_x_up_proxy_trans_charset,
3843 "x-up-proxy-trans-charset",
3844 vals_character_sets, "character set")
3846 /* Openwave content type header */
3847 wkh_content_type_header(openwave_x_up_proxy_push_accept,
3848 "x-up-proxy-push-accept")
3851 * Header value parameter parsing
3853 #define InvalidParameterValue(parameter,value) \
3854 "<Error: Invalid " parameter " parameter value: invalid " value ">"
3860 #define parameter_text(hf,lowercase,Uppercase,value) \
3861 DebugLog(("parameter with text_string value: " Uppercase "\n")); \
3862 get_text_string(val_str, tvb, offset, val_len, ok); \
3864 DebugLog(("OK, valid text_string value found!\n")); \
3865 DebugLog(("Adding val_str to the header field in proto tree\n")); \
3866 proto_tree_add_string(tree, hf, \
3867 tvb, start, type_len + val_len, val_str); \
3868 DebugLog(("Creating str to append to ti\n")); \
3869 str = g_strdup_printf("; " lowercase "=%s", val_str); \
3870 DebugLog(("Appending str to ti\n")); \
3871 proto_item_append_string(ti, str); \
3872 DebugLog(("\tFreeing str [%s]\n", str)); \
3874 DebugLog(("\tFreeing val_str [%s]\n", val_str)); \
3876 offset += val_len; \
3878 DebugLog(("\tError: invalid parameter value!\n")); \
3879 proto_tree_add_string(tree, hf, tvb, start, len - start, \
3880 InvalidParameterValue(Uppercase, value)); \
3881 offset = start + len; /* Skip to end of buffer */ \
3883 DebugLog(("parameter with text_string value - END\n"));
3886 #define parameter_text_value(hf,lowercase,Uppercase,value) \
3887 get_text_string(val_str, tvb, offset, val_len, ok); \
3889 if (is_quoted_string(val_str[0])) { \
3890 if (is_quoted_string(val_str[val_len-2])) { \
3891 /* Trailing quote - issue a warning */ \
3892 str = g_strdup_printf("%s" TrailingQuoteWarning, val_str); \
3893 proto_tree_add_string(tree, hf, \
3894 tvb, start, type_len + val_len, str); \
3896 str = g_strdup_printf("; " lowercase "=%s", val_str); \
3897 } else { /* OK (no trailing quote) */ \
3898 str = g_strdup_printf("%s\"", val_str); \
3899 proto_tree_add_string(tree, hf, \
3900 tvb, start, type_len + val_len, str); \
3902 str = g_strdup_printf("; " lowercase "=%s\"", val_str); \
3904 } else { /* Token-text | 0x00 */ \
3905 /* TODO - verify that we have either Token-text or 0x00 */ \
3906 proto_tree_add_string(tree, hf, \
3907 tvb, start, type_len + val_len, val_str); \
3908 str = g_strdup_printf("; " lowercase "=%s", val_str); \
3910 proto_item_append_string(ti, str); \
3913 offset += val_len; \
3915 proto_tree_add_string(tree, hf, tvb, start, len - start, \
3916 InvalidParameterValue(Uppercase, value)); \
3917 offset = start + len; /* Skip to end of buffer */ \
3921 /* Parameter = Untyped-parameter | Typed-parameter
3922 * Untyped-parameter = Token-text ( Integer-value | Text-value )
3925 * ( Integer-value | Date-value | Delta-seconds-value
3926 * | Q-value | Version-value | Uri-value )
3930 * Returns: next offset
3932 * TODO - Verify byte highlighting in case of invalid parameter values
3935 parameter (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start, int len)
3938 guint8 peek = tvb_get_guint8 (tvb,start);
3939 guint32 val = 0, type = 0, type_len, val_len;
3941 gchar *val_str = NULL;
3945 DebugLog(("parameter(start = %u, len = %u)\n", start, len));
3946 if (is_token_text (peek)) {
3950 DebugLog(("parameter() - Untyped - Start\n"));
3951 get_token_text (str,tvb,start,val_len,ok); /* Should always succeed */
3952 if (ok) { /* Found a textual parameter name: str */
3954 get_text_value(val_str, tvb, offset, val_len, ok);
3955 if (ok) { /* Also found a textual parameter value: val_str */
3956 DebugLog(("Trying textual parameter value.\n"));
3958 if (is_quoted_string(val_str[0])) { /* Add trailing quote! */
3959 if (is_quoted_string(val_str[val_len-2])) {
3960 /* Trailing quote - issue a warning */
3961 proto_tree_add_text(tree, tvb, start, offset - start,
3962 "%s: %s" TrailingQuoteWarning, str, val_str);
3963 s = g_strdup_printf("; %s=%s", str, val_str);
3964 } else { /* OK (no trailing quote) */
3965 proto_tree_add_text(tree, tvb, start, offset - start,
3966 "%s: %s\"", str, val_str);
3967 s = g_strdup_printf("; %s=%s\"", str, val_str);
3969 } else { /* Token-text | 0x00 */
3970 /* TODO - verify that it is either Token-text or 0x00
3971 * and flag with warning if invalid */
3972 proto_tree_add_text(tree, tvb, start, offset - start,
3973 "%s: %s", str, val_str);
3974 s = g_strdup_printf("; %s=%s", str, val_str);
3976 /* TODO - check if we can insert a searchable field in the
3977 * protocol tree for the untyped parameter case */
3978 DebugLog(("parameter() - Untyped: %s\n", s));
3979 proto_item_append_string(ti, s);
3980 DebugLog(("Freeing s\n"));
3982 DebugLog(("Freeing val_str\n"));
3984 DebugLog(("Done!\n"));
3985 } else { /* Try integer value */
3986 DebugLog(("Trying integer parameter value.\n"));
3987 get_integer_value (val,tvb,offset,val_len,ok);
3988 if (ok) { /* Also found a valid integer parameter value: val */
3990 proto_tree_add_text(tree, tvb, start, offset - start,
3991 "%s: %u", str, val);
3992 s = g_strdup_printf("; %s=%u", str, val);
3993 proto_item_append_string(ti, s);
3994 DebugLog(("parameter() - Untyped: %s\n", s));
3996 /* TODO - check if we can insert a searchable field in the
3997 * protocol tree for the untyped parameter case */
3998 } else { /* Error: neither token-text not Integer-value */
3999 DebugLog(("Invalid untyped parameter value!\n"));
4000 proto_tree_add_text (tree, tvb, start, offset - start,
4001 "<Error: Invalid untyped parameter definition>");
4002 offset = start + len; /* Skip to end of buffer */
4007 DebugLog(("parameter() - Untyped - End\n"));
4011 * Else: Typed parameter
4013 DebugLog(("parameter() - Typed - Start\n"));
4014 get_integer_value (type,tvb,start,type_len,ok);
4016 proto_tree_add_text (tree, tvb, start, offset - start,
4017 "<Error: Invalid typed parameter definition>");
4018 return (start + len); /* Skip to end of buffer */
4021 /* Now offset points to the parameter value */
4022 DebugLog(("Typed parameter = 0x%02x\n", type));
4024 case 0x01: /* WSP 1.1 encoding - Charset: Well-known-charset */
4025 get_integer_value(val, tvb, offset, val_len, ok);
4027 val_str = val_to_str(val, vals_character_sets,
4028 "<Unknown character set Identifier 0x%X>");
4029 proto_tree_add_string(tree, hf_parameter_charset,
4030 tvb, start, type_len + val_len, val_str);
4031 str = g_strdup_printf("; charset=%s", val_str);
4032 proto_item_append_string(ti, str);
4036 proto_tree_add_text (tree, tvb, start, offset,
4037 InvalidParameterValue("Charset", "Integer-value"));
4038 offset = start + len; /* Skip to end of buffer */
4042 case 0x03: /* WSP 1.1 encoding - Type: Integer-value */
4043 get_integer_value (val,tvb,offset,val_len,ok);
4045 proto_tree_add_uint (tree, hf_wsp_parameter_type,
4046 tvb, start, type_len + val_len, val);
4047 s = g_strdup_printf("; Type=%u", val);
4048 proto_item_append_string (ti, s);
4052 proto_tree_add_text (tree, tvb, start, offset,
4053 InvalidParameterValue("Type", "Integer-value"));
4054 offset = start + len; /* Skip to end of buffer */
4058 case 0x05: /* WSP 1.1 encoding - Name: Text-string */
4059 parameter_text(hf_wsp_parameter_name, "name",
4060 "Name (WSP 1.1 encoding)", "Text-string");
4062 case 0x17: /* WSP 1.4 encoding - Name: Text-value */
4063 parameter_text_value(hf_wsp_parameter_name, "name",
4064 "Name (WSP 1.4 encoding)", "Text-value");
4067 case 0x06: /* WSP 1.1 encoding - Filename: Text-string */
4068 parameter_text(hf_wsp_parameter_filename, "filename",
4069 "Filename (WSP 1.1 encoding)", "Text-string");
4071 case 0x18: /* WSP 1.4 encoding - Filename: Text-value */
4072 parameter_text_value(hf_wsp_parameter_filename, "filename",
4073 "Filename (WSP 1.4 encoding)", "Text-value");
4076 case 0x09: /* WSP 1.2 encoding - Type (special): Constrained-encoding */
4077 /* This is similar to the Content-Type header decoding,
4078 * but it is much simpler:
4079 * Constrained-encoding = Short-integer | Extension-media
4080 * Extension-media = *TEXT <Octet 0>
4082 get_extension_media(val_str,tvb,offset,val_len,ok);
4083 if (ok) { /* Extension-media */
4086 get_short_integer(val,tvb,offset,val_len,ok);
4089 val_str = val_to_str(val, vals_content_types,
4090 "(Unknown content type identifier 0x%X)");
4091 } /* Else: invalid parameter value */
4094 proto_tree_add_string (tree, hf_wsp_parameter_upart_type,
4095 tvb, start, offset - start, val_str);
4096 str = g_strdup_printf("; type=%s", val_str);
4097 proto_item_append_string(ti, str);
4099 } else { /* Invalid parameter value */
4100 proto_tree_add_text (tree, tvb, start, len - start,
4101 InvalidParameterValue("Type",
4102 "Constrained-encoding"));
4103 offset = start + len; /* Skip the parameters */
4107 case 0x0A: /* WSP 1.2 encoding - Start: Text-string */
4108 parameter_text(hf_wsp_parameter_start, "start",
4109 "Start (WSP 1.2 encoding)", "Text-string");
4111 case 0x19: /* WSP 1.4 encoding - Start (with multipart/related): Text-value */
4112 parameter_text_value(hf_wsp_parameter_start, "start",
4113 "Start (WSP 1.4 encoding)", "Text-value");
4116 case 0x0B: /* WSP 1.2 encoding - Start-info: Text-string */
4117 parameter_text(hf_wsp_parameter_start_info, "start-info",
4118 "Start-info (WSP 1.2 encoding)", "Text-string");
4120 case 0x1A: /* WSP 1.4 encoding - Start-info (with multipart/related): Text-value */
4121 parameter_text_value(hf_wsp_parameter_start_info, "start-info",
4122 "Start-info (WSP 1.4 encoding)", "Text-value");
4125 case 0x0C: /* WSP 1.3 encoding - Comment: Text-string */
4126 parameter_text(hf_wsp_parameter_comment, "comment",
4127 "Comment (WSP 1.3 encoding)", "Text-string");
4129 case 0x1B: /* WSP 1.4 encoding - Comment: Text-value */
4130 parameter_text_value(hf_wsp_parameter_comment, "comment",
4131 "Comment (WSP 1.4 encoding)", "Text-value");
4134 case 0x0D: /* WSP 1.3 encoding - Domain: Text-string */
4135 parameter_text(hf_wsp_parameter_domain, "domain",
4136 "Domain (WSP 1.3 encoding)", "Text-string");
4138 case 0x1C: /* WSP 1.4 encoding - Domain: Text-value */
4139 parameter_text_value(hf_wsp_parameter_domain, "domain",
4140 "Domain (WSP 1.4 encoding)", "Text-value");
4143 case 0x0F: /* WSP 1.3 encoding - Path: Text-string */
4144 parameter_text(hf_wsp_parameter_path, "path",
4145 "Path (WSP 1.3 encoding)", "Text-string");
4147 case 0x1D: /* WSP 1.4 encoding - Path: Text-value */
4148 parameter_text_value(hf_wsp_parameter_path, "path",
4149 "Path (WSP 1.4 encoding)", "Text-value");
4152 case 0x11: /* WSP 1.4 encoding - SEC: Short-integer (OCTET) */
4153 peek = tvb_get_guint8 (tvb, start+1);
4154 if (peek & 0x80) { /* Valid Short-integer */
4156 proto_tree_add_uint (tree, hf_wsp_parameter_sec,
4157 tvb, start, 2, peek);
4158 str = match_strval(peek, vals_wsp_parameter_sec);
4159 proto_item_append_text (ti, "; SEC=%s", str);
4161 } else { /* Error */
4162 proto_tree_add_text (tree, tvb, start, len - start,
4163 InvalidParameterValue("SEC", "Short-integer"));
4164 offset = start + len; /* Skip to end of buffer */
4168 case 0x12: /* WSP 1.4 encoding - MAC: Text-value */
4169 parameter_text_value(hf_wsp_parameter_mac, "MAC",
4170 "MAC", "Text-value");
4173 case 0x02: /* WSP 1.1 encoding - Level: Version-value */
4174 get_version_value(val,str,tvb,offset,val_len,ok);
4176 proto_tree_add_string (tree, hf_wsp_parameter_level,
4177 tvb, start, type_len + val_len, str);
4178 proto_item_append_text (ti, "; level=%s", str);
4181 proto_tree_add_text (tree, tvb, start, len - start,
4182 InvalidParameterValue("Level", "Version-value"));
4183 offset = start + len; /* Skip to end of buffer */
4187 case 0x00: /* WSP 1.1 encoding - Q: Q-value */
4188 offset = parameter_value_q(tree, ti, tvb, offset);
4191 case 0x07: /* WSP 1.1 encoding - Differences: Field-name */
4192 case 0x08: /* WSP 1.1 encoding - Padding: Short-integer */
4193 case 0x0E: /* WSP 1.3 encoding - Max-Age: Delta-seconds-value */
4194 case 0x10: /* WSP 1.3 encoding - Secure: No-value */
4195 case 0x13: /* WSP 1.4 encoding - Creation-date: Date-value */
4196 case 0x14: /* WSP 1.4 encoding - Modification-date: Date-value */
4197 case 0x15: /* WSP 1.4 encoding - Read-date: Date-value */
4198 case 0x16: /* WSP 1.4 encoding - Size: Integer-value */
4200 DebugLog(("Skipping remaining parameters from here\n"));
4201 proto_tree_add_text(tree, tvb, start, len - start,
4202 "Undecoded parameter type 0x%02x - decoding stopped",
4204 offset = start + len; /* Skip the parameters */
4207 DebugLog(("parameter() - Typed - End\n"));
4213 * Dissects the Q-value parameter value.
4215 * Returns: next offset
4218 parameter_value_q (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start)
4221 guint32 val = 0, val_len;
4225 get_uintvar_integer (val, tvb, offset, val_len, ok);
4226 if (ok && (val < 1100)) {
4227 if (val <= 100) { /* Q-value in 0.01 steps */
4228 str = g_strdup_printf("0.%02u", val - 1);
4229 } else { /* Q-value in 0.001 steps */
4230 str = g_strdup_printf("0.%03u", val - 100);
4232 proto_item_append_text (ti, "; q=%s", str);
4233 proto_tree_add_string (tree, hf_parameter_q,
4234 tvb, start, val_len, str);
4238 proto_tree_add_text (tree, tvb, start, offset,
4239 InvalidParameterValue("Q", "Q-value"));
4246 /* Code to actually dissect the packets */
4253 dissect_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo,
4254 proto_tree *tree, dissector_handle_t dissector_handle)
4258 proto_tree *addresses_tree;
4259 proto_tree *addr_tree = NULL;
4260 proto_tree *flags_tree;
4262 guint8 address_flags_len;
4264 proto_tree *address_flags_tree;
4266 guint32 address_ipv4;
4267 struct e_in6_addr address_ipv6;
4268 address redir_address;
4269 conversation_t *conv;
4270 guint32 index = 0; /* Address index */
4275 flags = tvb_get_guint8 (tvb, offset);
4277 ti = proto_tree_add_uint (tree, hf_wsp_redirect_flags,
4278 tvb, offset, 1, flags);
4279 flags_tree = proto_item_add_subtree (ti, ett_redirect_flags);
4280 proto_tree_add_boolean (flags_tree, hf_wsp_redirect_permanent,
4281 tvb, offset, 1, flags);
4282 proto_tree_add_boolean (flags_tree, hf_wsp_redirect_reuse_security_session,
4283 tvb, offset, 1, flags);
4288 * Redirect addresses.
4290 ti = proto_tree_add_item(tree, hf_redirect_addresses, tvb, 0, -1, bo_little_endian);
4291 addresses_tree = proto_item_add_subtree(ti, ett_addresses);
4293 while (tvb_reported_length_remaining (tvb, offset) > 0) {
4296 * Read a single address at a time.
4298 address_flags_len = tvb_get_guint8 (tvb, offset);
4299 address_len = address_flags_len & ADDRESS_LEN;
4302 ti = proto_tree_add_uint(addresses_tree, hf_address_entry,
4303 tvb, offset, 1 + address_len, index);
4304 addr_tree = proto_item_add_subtree(ti, ett_address);
4306 ti = proto_tree_add_uint (addr_tree, hf_address_flags_length,
4307 tvb, offset, 1, address_flags_len);
4308 address_flags_tree = proto_item_add_subtree (ti, ett_address_flags);
4309 proto_tree_add_boolean (address_flags_tree, hf_address_flags_length_bearer_type_included,
4310 tvb, offset, 1, address_flags_len);
4311 proto_tree_add_boolean (address_flags_tree, hf_address_flags_length_port_number_included,
4312 tvb, offset, 1, address_flags_len);
4313 proto_tree_add_uint (address_flags_tree, hf_address_flags_length_address_len,
4314 tvb, offset, 1, address_flags_len);
4317 if (address_flags_len & BEARER_TYPE_INCLUDED) {
4318 bearer_type = tvb_get_guint8 (tvb, offset);
4320 proto_tree_add_uint (addr_tree, hf_address_bearer_type,
4321 tvb, offset, 1, bearer_type);
4325 bearer_type = 0x00; /* XXX */
4327 if (address_flags_len & PORT_NUMBER_INCLUDED) {
4328 port_num = tvb_get_ntohs (tvb, offset);
4330 proto_tree_add_uint (addr_tree, hf_address_port_num,
4331 tvb, offset, 2, port_num);
4336 * Redirecting to the same server port number as was
4337 * being used, i.e. the source port number of this
4340 port_num = pinfo->srcport;
4342 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
4344 * We don't have the bearer type in the message,
4345 * so we don't know the address type.
4346 * (It's the same bearer type as the original
4349 goto unknown_address_type;
4353 * We know the bearer type, so we know the address type.
4355 switch (bearer_type) {
4359 case BT_IS_95_PACKET_DATA:
4360 case BT_ANSI_136_CSD:
4361 case BT_ANSI_136_PACKET_DATA:
4364 case BT_GSM_USSD_IPv4:
4367 case BT_PDC_PACKET_DATA:
4369 case BT_IDEN_PACKET_DATA:
4371 case BT_TETRA_PACKET_DATA:
4375 if (address_len != 4) {
4379 goto unknown_address_type;
4381 tvb_memcpy(tvb, (guint8 *)&address_ipv4, offset, 4);
4383 proto_tree_add_ipv4 (addr_tree,
4384 hf_address_ipv4_addr,
4385 tvb, offset, 4, address_ipv4);
4389 * Create a conversation so that the
4390 * redirected session will be dissected
4393 redir_address.type = AT_IPv4;
4394 redir_address.len = 4;
4395 redir_address.data = (const guint8 *)&address_ipv4;
4396 conv = find_conversation(&redir_address, &pinfo->dst,
4397 PT_UDP, port_num, 0, NO_PORT_B);
4399 conv = conversation_new(&redir_address,
4400 &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
4402 conversation_set_dissector(conv, dissector_handle);
4409 if (address_len != 16) {
4413 goto unknown_address_type;
4415 tvb_memcpy(tvb, (guint8 *)&address_ipv6, offset, 16);
4417 proto_tree_add_ipv6 (addr_tree,
4418 hf_address_ipv6_addr,
4419 tvb, offset, 16, (guint8 *)&address_ipv6);
4423 * Create a conversation so that the
4424 * redirected session will be dissected
4427 redir_address.type = AT_IPv6;
4428 redir_address.len = 16;
4429 redir_address.data = (const guint8 *)&address_ipv4;
4430 conv = find_conversation(&redir_address, &pinfo->dst,
4431 PT_UDP, port_num, 0, NO_PORT_B);
4433 conv = conversation_new(&redir_address,
4434 &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
4436 conversation_set_dissector(conv, dissector_handle);
4439 unknown_address_type:
4441 if (address_len != 0) {
4443 proto_tree_add_item (addr_tree, hf_address_addr,
4444 tvb, offset, address_len, bo_little_endian);
4449 offset += address_len;
4454 add_addresses(proto_tree *tree, tvbuff_t *tvb, int hf)
4457 proto_tree *addresses_tree;
4458 proto_tree *addr_tree;
4460 guint8 address_flags_len;
4462 proto_tree *address_flags_tree;
4464 guint32 address_ipv4;
4465 struct e_in6_addr address_ipv6;
4466 guint32 tvb_len = tvb_length(tvb);
4468 guint32 index = 0; /* Address index */
4470 /* Skip needless processing */
4473 if (offset >= tvb_len)
4479 ti = proto_tree_add_item(tree, hf, tvb, 0, -1, bo_little_endian);
4480 addresses_tree = proto_item_add_subtree(ti, ett_addresses);
4482 while (offset < tvb_len) {
4485 * Read a single address at a time.
4487 address_flags_len = tvb_get_guint8 (tvb, offset);
4488 address_len = address_flags_len & ADDRESS_LEN;
4490 ti = proto_tree_add_uint(addresses_tree, hf_address_entry,
4491 tvb, offset, 1 + address_len, index);
4492 addr_tree = proto_item_add_subtree(ti, ett_address);
4494 ti = proto_tree_add_uint (addr_tree, hf_address_flags_length,
4495 tvb, offset, 1, address_flags_len);
4496 address_flags_tree = proto_item_add_subtree (ti, ett_address_flags);
4497 proto_tree_add_boolean (address_flags_tree, hf_address_flags_length_bearer_type_included,
4498 tvb, offset, 1, address_flags_len);
4499 proto_tree_add_boolean (address_flags_tree, hf_address_flags_length_port_number_included,
4500 tvb, offset, 1, address_flags_len);
4501 proto_tree_add_uint (address_flags_tree, hf_address_flags_length_address_len,
4502 tvb, offset, 1, address_flags_len);
4504 if (address_flags_len & BEARER_TYPE_INCLUDED) {
4505 bearer_type = tvb_get_guint8 (tvb, offset);
4506 proto_tree_add_uint (addr_tree, hf_address_bearer_type,
4507 tvb, offset, 1, bearer_type);
4510 bearer_type = 0x00; /* XXX */
4512 if (address_flags_len & PORT_NUMBER_INCLUDED) {
4513 port_num = tvb_get_ntohs (tvb, offset);
4514 proto_tree_add_uint (addr_tree, hf_address_port_num,
4515 tvb, offset, 2, port_num);
4519 * Redirecting to the same server port number as was
4520 * being used, i.e. the source port number of this
4525 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
4527 * We don't have the bearer type in the message,
4528 * so we don't know the address type.
4529 * (It's the same bearer type as the original
4532 goto unknown_address_type;
4536 * We know the bearer type, so we know the address type.
4538 switch (bearer_type) {
4542 case BT_IS_95_PACKET_DATA:
4543 case BT_ANSI_136_CSD:
4544 case BT_ANSI_136_PACKET_DATA:
4547 case BT_GSM_USSD_IPv4:
4550 case BT_PDC_PACKET_DATA:
4552 case BT_IDEN_PACKET_DATA:
4554 case BT_TETRA_PACKET_DATA:
4558 if (address_len != 4) {
4562 goto unknown_address_type;
4564 tvb_memcpy(tvb, (guint8 *)&address_ipv4, offset, 4);
4565 proto_tree_add_ipv4 (addr_tree, hf_address_ipv4_addr,
4566 tvb, offset, 4, address_ipv4);
4573 if (address_len != 16) {
4577 goto unknown_address_type;
4579 tvb_memcpy(tvb, (guint8 *)&address_ipv6, offset, 16);
4580 proto_tree_add_ipv6 (addr_tree, hf_address_ipv6_addr,
4581 tvb, offset, 16, (guint8 *)&address_ipv6);
4584 unknown_address_type:
4586 if (address_len != 0) {
4587 proto_tree_add_item (addr_tree, hf_address_addr,
4588 tvb, offset, address_len, bo_little_endian);
4592 offset += address_len;
4596 static const value_string vals_sir_protocol_options[] = {
4597 { 0, "OTA-HTTP, no CPITag present" },
4598 { 1, "OTA-HTTP, CPITag present" },
4599 /* 2--255 are reserved */
4600 /* 256--16383 are available for private WINA registration */
4606 * Dissect a Session Initiation Request.
4608 * Arguably this should be a separate dissector, but SIR does not make sense
4609 * outside of WSP anyway.
4612 dissect_sir(proto_tree *tree, tvbuff_t *tvb)
4620 proto_tree *subtree;
4626 ti = proto_tree_add_item(tree, hf_sir_section,
4627 tvb, 0, -1, bo_little_endian);
4628 subtree = proto_item_add_subtree(ti, ett_sir);
4631 version = tvb_get_guint8(tvb, 0);
4632 proto_tree_add_uint(subtree, hf_sir_version,
4633 tvb, 0, 1, version);
4635 /* Length of Application-Id headers list */
4636 val_len = tvb_get_guintvar(tvb, 1, &len);
4637 proto_tree_add_uint(subtree, hf_sir_app_id_list_len,
4638 tvb, 1, len, val_len);
4640 /* Application-Id headers */
4641 tmp_tvb = tvb_new_subset(tvb, offset, val_len, val_len);
4642 add_headers (subtree, tmp_tvb, hf_sir_app_id_list);
4645 /* Length of WSP contact points list */
4646 val_len = tvb_get_guintvar(tvb, offset, &len);
4647 proto_tree_add_uint(subtree, hf_sir_wsp_contact_points_len,
4648 tvb, offset, len, val_len);
4650 /* WSP contact point list */
4651 tmp_tvb = tvb_new_subset (tvb, offset, val_len, val_len);
4652 add_addresses(subtree, tmp_tvb, hf_sir_wsp_contact_points);
4655 /* End of version 0 SIR content */
4659 /* Length of non-WSP contact points list */
4660 val_len = tvb_get_guintvar(tvb, offset, &len);
4661 proto_tree_add_uint(subtree, hf_sir_contact_points_len,
4662 tvb, offset, len, val_len);
4664 /* Non-WSP contact point list */
4665 tmp_tvb = tvb_new_subset (tvb, offset, val_len, val_len);
4666 add_addresses(subtree, tmp_tvb, hf_sir_contact_points);
4669 /* Number of entries in the Protocol Options list */
4670 val_len = tvb_get_guintvar(tvb, offset, &len);
4671 proto_tree_add_uint(subtree, hf_sir_protocol_options_len,
4672 tvb, offset, len, val_len);
4674 /* Protocol Options list.
4675 * Each protocol option is encoded as a guintvar */
4676 for (i = 0; i < val_len; i++) {
4677 val_len = tvb_get_guintvar(tvb, offset, &len);
4678 proto_tree_add_uint(subtree, hf_sir_protocol_options,
4679 tvb, offset, len, val_len);
4683 /* Length of ProvURL */
4684 val_len = tvb_get_guintvar(tvb, offset, &len);
4685 proto_tree_add_uint(subtree, hf_sir_prov_url_len,
4686 tvb, offset, len, val_len);
4689 tvb_ensure_bytes_exist(tvb, offset, val_len);
4690 ti = proto_tree_add_item (tree, hf_sir_prov_url,
4691 tvb, offset, val_len, bo_little_endian);
4694 /* Number of entries in the CPITag list */
4695 val_len = tvb_get_guintvar(tvb, offset, &len);
4696 proto_tree_add_uint(subtree, hf_sir_cpi_tag_len,
4697 tvb, offset, len, val_len);
4700 * Each CPITag is encoded as 4 octets of opaque data.
4701 * In OTA-HTTP, it is conveyed in the X-Wap-CPITag header
4702 * but with a Base64 encoding of the 4 bytes. */
4703 for (i = 0; i < val_len; i++) {
4704 val_len = tvb_get_guintvar(tvb, offset, &len);
4705 proto_tree_add_item(subtree, hf_sir_cpi_tag,
4706 tvb, offset, 4, val_len);
4712 dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4713 dissector_handle_t dissector_handle, gboolean is_connectionless)
4718 guint8 reply_status;
4721 guint uriLength = 0;
4723 guint capabilityLength = 0;
4724 guint capabilityStart = 0;
4725 guint headersLength = 0;
4726 guint headerLength = 0;
4727 guint headerStart = 0;
4728 guint nextOffset = 0;
4729 guint contentTypeStart = 0;
4730 guint contentType = 0;
4731 const char *contentTypeStr;
4733 gboolean found_match;
4735 /* Set up structures we will need to add the protocol subtree and manage it */
4737 proto_tree *wsp_tree = NULL;
4739 wsp_info_value_t *stat_info;
4740 stat_info = g_malloc( sizeof(wsp_info_value_t) );
4741 stat_info->status_code = 0;
4743 /* This field shows up as the "Info" column in the display; you should make
4744 it, if possible, summarize what's in the packet, so that a user looking
4745 at the list of packets can tell what type of packet it is. */
4747 /* Connection-less mode has a TID first */
4748 if (is_connectionless)
4750 offset++; /* Skip the 1-byte Transaction ID */
4753 /* Find the PDU type */
4754 pdut = tvb_get_guint8 (tvb, offset);
4756 /* Develop the string to put in the Info column */
4757 if (check_col(pinfo->cinfo, COL_INFO))
4759 col_append_fstr(pinfo->cinfo, COL_INFO, "WSP %s",
4760 val_to_str (pdut, vals_pdu_type, "Unknown PDU type (0x%02x)"));
4763 /* In the interest of speed, if "tree" is NULL, don't do any work not
4764 * necessary to generate protocol tree items. */
4766 ti = proto_tree_add_item(tree, proto_wsp,
4767 tvb, 0, -1, bo_little_endian);
4768 wsp_tree = proto_item_add_subtree(ti, ett_wsp);
4770 /* Add common items: only TID and PDU Type */
4772 /* If this is connectionless, then the TID Field is always first */
4773 if (is_connectionless)
4775 ti = proto_tree_add_item (wsp_tree, hf_wsp_header_tid,
4776 tvb, 0, 1, bo_little_endian);
4778 ti = proto_tree_add_item( wsp_tree, hf_wsp_header_pdu_type,
4779 tvb, offset, 1, bo_little_endian);
4783 /* Map extended methods to the main method now the Column info has been
4784 * written; this way we can dissect the extended method PDUs. */
4785 if ((pdut >= 0x50) && (pdut <= 0x5F)) /* Extended GET --> GET */
4787 else if ((pdut >= 0x70) && (pdut <= 0x7F)) /* Extended POST --> POST */
4788 pdut = WSP_PDU_POST;
4792 case WSP_PDU_CONNECT:
4793 case WSP_PDU_CONNECTREPLY:
4794 case WSP_PDU_RESUME:
4796 if (pdut == WSP_PDU_CONNECT)
4798 ti = proto_tree_add_item (wsp_tree, hf_wsp_version_major,
4799 tvb, offset, 1, bo_little_endian);
4800 ti = proto_tree_add_item (wsp_tree, hf_wsp_version_minor,
4801 tvb, offset, 1, bo_little_endian);
4804 count = 0; /* Initialise count */
4805 value = tvb_get_guintvar (tvb, offset, &count);
4806 ti = proto_tree_add_uint (wsp_tree,
4807 hf_wsp_server_session_id,
4808 tvb, offset, count, value);
4811 capabilityStart = offset;
4812 count = 0; /* Initialise count */
4813 capabilityLength = tvb_get_guintvar (tvb, offset, &count);
4815 ti = proto_tree_add_uint (wsp_tree, hf_capabilities_length,
4816 tvb, capabilityStart, count, capabilityLength);
4818 if (pdut != WSP_PDU_RESUME)
4820 count = 0; /* Initialise count */
4821 headerLength = tvb_get_guintvar (tvb, offset, &count);
4822 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4823 tvb, offset, count, headerLength);
4825 capabilityStart = offset;
4826 headerStart = capabilityStart + capabilityLength;
4828 /* Resume computes the headerlength
4829 * by remaining bytes */
4830 capabilityStart = offset;
4831 headerStart = capabilityStart + capabilityLength;
4832 headerLength = tvb_reported_length_remaining (tvb,
4835 if (capabilityLength > 0)
4837 tmp_tvb = tvb_new_subset (tvb, offset,
4838 capabilityLength, capabilityLength);
4839 add_capabilities (wsp_tree, tmp_tvb, pdut);
4840 offset += capabilityLength;
4843 if (headerLength > 0)
4845 tmp_tvb = tvb_new_subset (tvb, offset,
4846 headerLength, headerLength);
4847 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section);
4853 case WSP_PDU_REDIRECT:
4854 dissect_redirect(tvb, offset, pinfo, wsp_tree, dissector_handle);
4857 case WSP_PDU_DISCONNECT:
4858 case WSP_PDU_SUSPEND:
4860 count = 0; /* Initialise count */
4861 value = tvb_get_guintvar (tvb, offset, &count);
4862 ti = proto_tree_add_uint (wsp_tree,
4863 hf_wsp_server_session_id,
4864 tvb, offset, count, value);
4869 count = 0; /* Initialise count */
4870 /* Length of URI and size of URILen field */
4871 value = tvb_get_guintvar (tvb, offset, &count);
4872 nextOffset = offset + count;
4873 add_uri (wsp_tree, pinfo, tvb, offset, nextOffset);
4875 offset += value + count; /* VERIFY */
4876 tmp_tvb = tvb_new_subset (tvb, offset, -1, -1);
4877 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section);
4883 count = 0; /* Initialise count */
4884 uriLength = tvb_get_guintvar (tvb, offset, &count);
4885 headerStart = uriStart+count;
4886 count = 0; /* Initialise count */
4887 headersLength = tvb_get_guintvar (tvb, headerStart, &count);
4888 offset = headerStart + count;
4890 add_uri (wsp_tree, pinfo, tvb, uriStart, offset);
4891 offset += uriLength;
4894 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4895 tvb, headerStart, count, headersLength);
4897 if (headersLength == 0)
4900 contentTypeStart = offset;
4901 nextOffset = add_content_type (wsp_tree,
4902 tvb, offset, &contentType, &contentTypeStr);
4905 /* Add headers subtree that will hold the headers fields */
4906 /* Runs from nextOffset for
4907 * headersLength - (length of content-type field) */
4908 headerLength = headersLength - (nextOffset - contentTypeStart);
4909 if (headerLength > 0)
4911 tmp_tvb = tvb_new_subset (tvb, nextOffset,
4912 headerLength, headerLength);
4913 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section);
4915 offset = nextOffset+headerLength;
4917 /* WSP_PDU_POST data - First check whether a subdissector exists
4918 * for the content type */
4919 if (tvb_reported_length_remaining(tvb,
4920 headerStart + count + uriLength + headersLength) > 0)
4922 tmp_tvb = tvb_new_subset (tvb,
4923 headerStart + count + uriLength + headersLength,
4926 * Try finding a dissector for the content
4927 * first, then fallback.
4929 found_match = FALSE;
4930 if (contentTypeStr) {
4932 * Content type is a string.
4934 found_match = dissector_try_string(media_type_table,
4935 contentTypeStr, tmp_tvb, pinfo, tree);
4937 if (! found_match) {
4938 if (! dissector_try_heuristic(heur_subdissector_list,
4939 tmp_tvb, pinfo, tree))
4940 if (tree) /* Only display if needed */
4941 add_post_data (wsp_tree, tmp_tvb,
4942 contentType, contentTypeStr);
4948 count = 0; /* Initialise count */
4949 headersLength = tvb_get_guintvar (tvb, offset+1, &count);
4950 headerStart = offset + count + 1;
4951 reply_status = tvb_get_guint8(tvb, offset);
4953 ti = proto_tree_add_item (wsp_tree, hf_wsp_header_status,
4954 tvb, offset, 1, bo_little_endian);
4955 stat_info->status_code = (gint) tvb_get_guint8(tvb, offset);
4956 if (check_col(pinfo->cinfo, COL_INFO))
4957 { /* Append status code to INFO column */
4958 col_append_fstr(pinfo->cinfo, COL_INFO,
4959 ": \"0x%02x %s\"", reply_status,
4960 val_to_str (reply_status, vals_status,
4961 "Unknown response status (0x%02x)"));
4963 nextOffset = offset + 1 + count;
4965 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4966 tvb, offset + 1, count, headersLength);
4968 if (headersLength == 0)
4971 contentTypeStart = nextOffset;
4972 nextOffset = add_content_type (wsp_tree, tvb,
4973 nextOffset, &contentType, &contentTypeStr);
4976 /* Add headers subtree that will hold the headers fields */
4977 /* Runs from nextOffset for
4978 * headersLength - (length of content-type field) */
4979 headerLength = headersLength - (nextOffset - contentTypeStart);
4980 if (headerLength > 0)
4982 tmp_tvb = tvb_new_subset (tvb, nextOffset,
4983 headerLength, headerLength);
4984 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section);
4986 offset += count+headersLength+1;
4988 /* WSP_PDU_REPLY data - First check whether a subdissector exists
4989 * for the content type */
4990 if (tvb_reported_length_remaining(tvb, headerStart + headersLength)
4993 tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength,
4996 * Try finding a dissector for the content
4997 * first, then fallback.
4999 found_match = FALSE;
5000 if (contentTypeStr) {
5002 * Content type is a string.
5004 found_match = dissector_try_string(media_type_table,
5005 contentTypeStr, tmp_tvb, pinfo, tree);
5007 if (! found_match) {
5008 if (! dissector_try_heuristic(heur_subdissector_list,
5009 tmp_tvb, pinfo, tree))
5010 if (tree) /* Only display if needed */
5011 ti = proto_tree_add_item (wsp_tree,
5013 tmp_tvb, 0, -1, bo_little_endian);
5019 case WSP_PDU_CONFIRMEDPUSH:
5020 count = 0; /* Initialise count */
5021 headersLength = tvb_get_guintvar (tvb, offset, &count);
5022 headerStart = offset + count;
5025 ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
5026 tvb, offset, count, headersLength);
5028 if (headersLength == 0)
5032 contentTypeStart = offset;
5033 nextOffset = add_content_type (wsp_tree,
5034 tvb, offset, &contentType, &contentTypeStr);
5037 /* Add headers subtree that will hold the headers fields */
5038 /* Runs from nextOffset for
5039 * headersLength-(length of content-type field) */
5040 headerLength = headersLength-(nextOffset-contentTypeStart);
5041 if (headerLength > 0)
5043 tmp_tvb = tvb_new_subset (tvb, nextOffset,
5044 headerLength, headerLength);
5045 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section);
5047 offset += headersLength;
5049 /* WSP_PDU_PUSH data - First check whether a subdissector exists
5050 * for the content type */
5051 if (tvb_reported_length_remaining(tvb, headerStart + headersLength)
5054 tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength,
5057 * Try finding a dissector for the content
5058 * first, then fallback.
5060 found_match = FALSE;
5061 if (contentTypeStr) {
5063 * Content type is a string.
5065 if (strcasecmp(contentTypeStr, "application/vnd.wap.sia") == 0) {
5066 dissect_sir(tree, tmp_tvb);
5068 found_match = dissector_try_string(media_type_table,
5069 contentTypeStr, tmp_tvb, pinfo, tree);
5071 if (! found_match) {
5072 if (! dissector_try_heuristic(heur_subdissector_list,
5073 tmp_tvb, pinfo, tree))
5074 if (tree) /* Only display if needed */
5075 ti = proto_tree_add_item (wsp_tree,
5077 tmp_tvb, 0, -1, bo_little_endian);
5083 stat_info->pdut = pdut;
5084 tap_queue_packet (wsp_tap, pinfo, stat_info);
5089 * Called directly from UDP.
5090 * Put "WSP" into the "Protocol" column.
5093 dissect_wsp_fromudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5095 if (check_col(pinfo->cinfo, COL_PROTOCOL))
5096 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSP" );
5097 if (check_col(pinfo->cinfo, COL_INFO))
5098 col_clear(pinfo->cinfo, COL_INFO);
5100 dissect_wsp_common(tvb, pinfo, tree, wsp_fromudp_handle, TRUE);
5105 * Called from a higher-level WAP dissector, in connection-oriented mode.
5106 * Leave the "Protocol" column alone - the dissector calling us should
5110 dissect_wsp_fromwap_co(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5113 * XXX - what about WTLS->WTP->WSP?
5115 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, FALSE);
5120 * Called from a higher-level WAP dissector, in connectionless mode.
5121 * Leave the "Protocol" column alone - the dissector calling us should
5125 dissect_wsp_fromwap_cl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5128 * XXX - what about WTLS->WSP?
5130 if (check_col(pinfo->cinfo, COL_INFO))
5132 col_clear(pinfo->cinfo, COL_INFO);
5134 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, TRUE);
5139 add_uri (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
5140 guint URILenOffset, guint URIOffset)
5145 guint uriLen = tvb_get_guintvar (tvb, URILenOffset, &count);
5148 ti = proto_tree_add_uint (tree, hf_wsp_header_uri_len,
5149 tvb, URILenOffset, count, uriLen);
5151 tvb_ensure_bytes_exist(tvb, URIOffset, uriLen);
5153 ti = proto_tree_add_item (tree, hf_wsp_header_uri,
5154 tvb, URIOffset, uriLen, bo_little_endian);
5155 if (check_col(pinfo->cinfo, COL_INFO)) {
5156 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
5157 tvb_format_text (tvb, URIOffset, uriLen));
5163 * CO-WSP capability negotiation
5167 WSP_CAPA_CLIENT_SDU_SIZE = 0x00,
5168 WSP_CAPA_SERVER_SDU_SIZE,
5169 WSP_CAPA_PROTOCOL_OPTIONS,
5170 WSP_CAPA_METHOD_MOR,
5172 WSP_CAPA_EXTENDED_METHODS,
5173 WSP_CAPA_HEADER_CODE_PAGES,
5175 WSP_CAPA_CLIENT_MESSAGE_SIZE,
5176 WSP_CAPA_SERVER_MESSAGE_SIZE
5180 add_capabilities (proto_tree *tree, tvbuff_t *tvb, guint8 pdu_type)
5182 proto_tree *wsp_capabilities;
5183 proto_tree *capa_subtree;
5185 char *capaName, *str, *valStr;
5188 guint32 capaStart = 0; /* Start offset of the capability */
5189 guint32 capaLen = 0; /* Length of the entire capability */
5190 guint32 capaValueLen = 0; /* Length of the capability value & type */
5191 guint32 tvb_len = tvb_reported_length(tvb);
5192 gboolean ok = FALSE;
5197 DebugLog(("add_capabilities(): Capabilities = 0\n"));
5201 DebugLog(("add_capabilities(): capabilities to process\n"));
5203 ti = proto_tree_add_item(tree, hf_capabilities_section,
5204 tvb, 0, tvb_len, bo_little_endian);
5205 wsp_capabilities = proto_item_add_subtree(ti, ett_capabilities);
5207 while (offset < tvb_len) {
5209 * WSP capabilities consist of:
5210 * - a guint32 length field,
5211 * - a capability identifier as Token-text or Short-integer,
5212 * - a capability-specific sequence of <length> octets.
5216 * Now Offset points to the 1st byte of a capability field.
5217 * Get the length of the capability field
5219 capaValueLen = tvb_get_guintvar(tvb, offset, &len);
5220 capaLen = capaValueLen + len;
5223 * Now offset points to the 1st byte of the capability type.
5224 * Get the capability identifier.
5226 peek = tvb_get_guint8(tvb, offset);
5227 if (is_token_text(peek)) { /* Literal capability name */
5228 /* 1. Get the string from the tvb */
5229 get_token_text(capaName, tvb, offset, len, ok);
5231 DebugLog(("add_capabilities(): expecting capability name as token_text "
5232 "at offset %u (1st char = 0x%02x)\n", offset, peek));
5235 /* 2. Look up the string capability name */
5236 if (strcasecmp(capaName, "client-sdu-size") == 0) {
5237 peek = WSP_CAPA_CLIENT_SDU_SIZE;
5238 } else if (strcasecmp(capaName, "server-sdu-size") == 0) {
5239 peek = WSP_CAPA_SERVER_SDU_SIZE;
5240 } else if (strcasecmp(capaName, "protocol options") == 0) {
5241 peek = WSP_CAPA_PROTOCOL_OPTIONS;
5242 } else if (strcasecmp(capaName, "method-mor") == 0) {
5243 peek = WSP_CAPA_METHOD_MOR;
5244 } else if (strcasecmp(capaName, "push-mor") == 0) {
5245 peek = WSP_CAPA_PUSH_MOR;
5246 } else if (strcasecmp(capaName, "extended methods") == 0) {
5247 peek = WSP_CAPA_EXTENDED_METHODS;
5248 } else if (strcasecmp(capaName, "header code pages") == 0) {
5249 peek = WSP_CAPA_HEADER_CODE_PAGES;
5250 } else if (strcasecmp(capaName, "aliases") == 0) {
5251 peek = WSP_CAPA_ALIASES;
5252 } else if (strcasecmp(capaName, "client-message-size") == 0) {
5253 peek = WSP_CAPA_CLIENT_MESSAGE_SIZE;
5254 } else if (strcasecmp(capaName, "server-message-size") == 0) {
5255 peek = WSP_CAPA_SERVER_MESSAGE_SIZE;
5257 DebugLog(("add_capabilities(): unknown capability '%s' at offset %u\n",
5259 proto_tree_add_text(wsp_capabilities, tvb, capaStart, capaLen,
5260 "Unknown or invalid textual capability: %s", capaName);
5262 /* Skip this capability */
5263 offset = capaStart + capaLen;
5268 /* Now offset points to the 1st value byte of the capability. */
5269 } else if (peek < 0x80) {
5270 DebugLog(("add_capabilities(): invalid capability type identifier 0x%02X at offset %u.",
5272 proto_tree_add_text(wsp_capabilities, tvb, capaStart, capaLen,
5273 "Invalid well-known capability: 0x%02X", peek);
5274 /* Skip further capability parsing */
5277 if (peek & 0x80) { /* Well-known capability */
5281 /* Now offset points to the 1st value byte of the capability. */
5283 /* Now the capability type is known */
5285 case WSP_CAPA_CLIENT_SDU_SIZE:
5286 value = tvb_get_guintvar(tvb, offset, &len);
5287 DebugLog(("add_capabilities(client-sdu-size): "
5288 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5289 value, value, offset, tvb_get_guint8(tvb, offset), len));
5290 proto_tree_add_uint(wsp_capabilities, hf_capa_client_sdu_size,
5291 tvb, capaStart, capaLen, value);
5293 case WSP_CAPA_SERVER_SDU_SIZE:
5294 value = tvb_get_guintvar(tvb, offset, &len);
5295 DebugLog(("add_capabilities(server-sdu-size): "
5296 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5297 value, value, offset, tvb_get_guint8(tvb, offset), len));
5298 proto_tree_add_uint(wsp_capabilities, hf_capa_server_sdu_size,
5299 tvb, capaStart, capaLen, value);
5301 case WSP_CAPA_PROTOCOL_OPTIONS:
5302 ti = proto_tree_add_string(wsp_capabilities, hf_capa_protocol_options,
5303 tvb, capaStart, capaLen, "");
5304 capa_subtree = proto_item_add_subtree(ti, ett_capability);
5306 * The bits are stored in one or more octets, not an
5307 * uintvar-integer! Note that capability name and value
5308 * have length capaValueLength, and that the capability
5309 * name has length = len. Hence the remaining length is
5310 * given by capaValueLen - len.
5312 switch (capaValueLen - len) {
5314 value = tvb_get_guint8(tvb, offset);
5319 * The WSP spec foresees that this bit field can be
5320 * extended in the future. This does not make sense yet.
5322 DebugLog(("add_capabilities(protocol options): "
5323 "bit field too large (%u bytes)\n",
5325 proto_item_append_text(ti,
5326 " <warning: bit field too large>");
5327 offset = capaStart + capaLen;
5330 DebugLog(("add_capabilities(protocol options): "
5331 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5332 value, value, offset, tvb_get_guint8(tvb, offset), len));
5334 proto_item_append_string(ti, " (confirmed push facility)");
5336 proto_item_append_string(ti, " (push facility)");
5338 proto_item_append_string(ti, " (session resume facility)");
5340 proto_item_append_string(ti, " (acknowledgement headers)");
5342 proto_item_append_string(ti, " (large data transfer)");
5343 if (value & 0xFFFFFF07)
5344 proto_item_append_text(ti, " <warning: reserved bits have been set>");
5345 proto_tree_add_boolean(capa_subtree,
5346 hf_capa_protocol_option_confirmed_push,
5347 tvb, offset, len, value);
5348 proto_tree_add_boolean(capa_subtree,
5349 hf_capa_protocol_option_push,
5350 tvb, offset, len, value);
5351 proto_tree_add_boolean(capa_subtree,
5352 hf_capa_protocol_option_session_resume,
5353 tvb, offset, len, value);
5354 proto_tree_add_boolean(capa_subtree,
5355 hf_capa_protocol_option_ack_headers,
5356 tvb, offset, len, value);
5357 proto_tree_add_boolean(capa_subtree,
5358 hf_capa_protocol_option_large_data_transfer,
5359 tvb, offset, len, value);
5361 case WSP_CAPA_METHOD_MOR:
5362 value = tvb_get_guint8(tvb, offset);
5363 proto_tree_add_uint (wsp_capabilities,
5365 tvb, capaStart, capaLen, value);
5367 case WSP_CAPA_PUSH_MOR:
5368 value = tvb_get_guint8(tvb, offset);
5369 proto_tree_add_uint (wsp_capabilities,
5371 tvb, capaStart, capaLen, value);
5373 case WSP_CAPA_EXTENDED_METHODS:
5374 /* Extended Methods capability format:
5375 * Connect PDU: collection of { Method (octet), Method-name (Token-text) }
5376 * ConnectReply PDU: collection of accepted { Method (octet) }
5378 ti = proto_tree_add_string(wsp_capabilities,
5379 hf_capa_extended_methods,
5380 tvb, capaStart, capaLen, "");
5381 if (pdu_type == WSP_PDU_CONNECT) {
5382 while (offset < capaStart + capaLen) {
5383 peek = tvb_get_guint8(tvb, offset++);
5384 get_text_string(str, tvb, offset, len, ok);
5386 proto_item_append_text(ti, " <error: invalid capability encoding>");
5387 DebugLog(("add_capability(extended methods): "
5388 "invalid method name at offset %u "
5389 "(octet = 0x%02X)\n",
5390 offset, tvb_get_guint8(tvb, offset)));
5393 valStr = g_strdup_printf(" (0x%02x = %s)", peek, str);
5394 DebugLog(("add_capabilities(extended methods):%s\n",
5396 proto_item_append_string(ti, valStr);
5402 while (offset < capaStart + capaLen) {
5403 peek = tvb_get_guint8(tvb, offset++);
5404 valStr = g_strdup_printf(" (0x%02x)", peek);
5405 DebugLog(("add_capabilities(extended methods):%s\n",
5407 proto_item_append_string(ti, valStr);
5412 case WSP_CAPA_HEADER_CODE_PAGES:
5413 /* Header Code Pages capability format:
5414 * Connect PDU: collection of { Page-id (octet), Page-name (Token-text) }
5415 * ConnectReply PDU: collection of accepted { Page-id (octet) }
5417 ti = proto_tree_add_string(wsp_capabilities,
5418 hf_capa_header_code_pages,
5419 tvb, capaStart, capaLen, "");
5420 if (pdu_type == WSP_PDU_CONNECT) {
5421 while (offset < capaStart + capaLen) {
5422 peek = tvb_get_guint8(tvb, offset++);
5423 get_text_string(str, tvb, offset, len, ok);
5425 proto_item_append_text(ti,
5426 " <error: invalid capability encoding>");
5427 DebugLog(("add_capability(header code pages): "
5428 "invalid header code page name at offset %u "
5429 "(octet = 0x%02X)\n",
5430 offset, tvb_get_guint8(tvb, offset)));
5433 valStr = g_strdup_printf(" (0x%02x = %s)", peek, str);
5434 DebugLog(("add_capabilities(header code pages):%s\n",
5436 proto_item_append_string(ti, valStr);
5442 while (offset < capaStart + capaLen) {
5443 peek = tvb_get_guint8(tvb, offset++);
5444 valStr = g_strdup_printf(" (0x%02x)", peek);
5445 DebugLog(("add_capabilities(header code pages):%s\n",
5447 proto_item_append_string(ti, valStr);
5452 case WSP_CAPA_ALIASES:
5453 /* TODO - same format as redirect addresses */
5454 proto_tree_add_item(wsp_capabilities, hf_capa_aliases,
5455 tvb, capaStart, capaLen, bo_little_endian);
5457 case WSP_CAPA_CLIENT_MESSAGE_SIZE:
5458 value = tvb_get_guintvar(tvb, offset, &len);
5459 DebugLog(("add_capabilities(client-message-size): "
5460 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5461 value, value, offset, tvb_get_guint8(tvb, offset), len));
5462 proto_tree_add_uint(wsp_capabilities, hf_capa_client_message_size,
5463 tvb, capaStart, capaLen, value);
5465 case WSP_CAPA_SERVER_MESSAGE_SIZE:
5466 value = tvb_get_guintvar(tvb, offset, &len);
5467 DebugLog(("add_capabilities(server-message-size): "
5468 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5469 value, value, offset, tvb_get_guint8(tvb, offset), len));
5470 proto_tree_add_uint(wsp_capabilities, hf_capa_server_message_size,
5471 tvb, capaStart, capaLen, value);
5474 proto_tree_add_text(wsp_capabilities, tvb, capaStart, capaLen,
5475 "Unknown well-known capability: 0x%02X", peek);
5478 offset = capaStart + capaLen;
5483 add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType,
5484 const char *contentTypeStr)
5487 guint variableStart = 0;
5488 guint variableEnd = 0;
5489 guint valueStart = 0;
5493 proto_tree *sub_tree;
5495 DebugLog(("add_post_data() - START\n"));
5497 /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,bo_little_endian); */
5498 ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,bo_little_endian);
5499 sub_tree = proto_item_add_subtree(ti, ett_post);
5501 if ( (contentTypeStr == NULL && contentType == 0x12)
5502 || (contentTypeStr && (strcasecmp(contentTypeStr,
5503 "application/x-www-form-urlencoded") == 0)) )
5507 * Iterate through post data.
5509 for (offset = 0; offset < tvb_reported_length (tvb); offset++)
5511 peek = tvb_get_guint8 (tvb, offset);
5514 variableEnd = offset;
5515 valueStart = offset+1;
5517 else if (peek == '&')
5519 if (variableEnd > 0)
5521 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5523 variableStart = offset+1;
5530 /* See if there's outstanding data */
5531 if (variableEnd > 0)
5533 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5536 else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x24) ||
5537 (contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33))
5539 add_multipart_data(sub_tree, tvb);
5541 DebugLog(("add_post_data() - END\n"));
5545 add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint variableEnd, guint valueStart, guint valueEnd)
5547 int variableLength = variableEnd-variableStart;
5548 int valueLength = 0;
5549 char *variableBuffer;
5552 variableBuffer = g_malloc (variableLength+1);
5553 strncpy (variableBuffer, tvb_get_ptr (tvb, variableStart, variableLength), variableLength);
5554 variableBuffer[variableLength] = 0;
5556 if (valueEnd < valueStart)
5558 valueBuffer = g_malloc (1);
5560 valueEnd = valueStart;
5564 valueLength = valueEnd-valueStart;
5565 valueBuffer = g_malloc (valueLength+1);
5566 strncpy (valueBuffer, tvb_get_ptr (tvb, valueStart, valueLength), valueLength);
5567 valueBuffer[valueLength] = 0;
5570 /* Check for variables with no value */
5571 if (valueStart >= tvb_reported_length (tvb))
5573 valueStart = tvb_reported_length (tvb);
5574 valueEnd = valueStart;
5576 valueLength = valueEnd-valueStart;
5578 proto_tree_add_text (tree, tvb, variableStart, valueEnd-variableStart, "%s: %s", variableBuffer, valueBuffer);
5580 g_free (variableBuffer);
5581 g_free (valueBuffer);
5585 add_multipart_data (proto_tree *tree, tvbuff_t *tvb)
5593 guint contentType = 0;
5594 const char *contentTypeStr;
5599 proto_item *sub_tree = NULL,
5601 proto_tree *mpart_tree;
5603 DebugLog(("add_multipart_data(): offset = %u, byte = 0x%02x: ",
5604 offset, tvb_get_guint8(tvb,offset)));
5605 nEntries = tvb_get_guintvar (tvb, offset, &count);
5606 DebugLog(("parts = %u\n", nEntries));
5610 sub_tree = proto_tree_add_text(tree, tvb, offset - count, 0,
5612 proto_item_add_subtree(sub_tree, ett_mpartlist);
5616 DebugLog(("add_multipart_data(): Parts to do after this: %u"
5617 " (offset = %u, 0x%02x): ",
5618 nEntries, offset, tvb_get_guint8(tvb,offset)));
5619 part_start = offset;
5620 HeadersLen = tvb_get_guintvar (tvb, offset, &count);
5622 DataLen = tvb_get_guintvar (tvb, offset, &count);
5624 ti = proto_tree_add_uint(sub_tree, hf_wsp_mpart, tvb, part_start,
5625 HeadersLen + DataLen + (offset - part_start), partnr);
5626 mpart_tree = proto_item_add_subtree(ti, ett_multiparts);
5627 nextOffset = add_content_type (mpart_tree, tvb, offset, &contentType, &contentTypeStr);
5628 HeadersLen -= (nextOffset - offset);
5631 tmp_tvb = tvb_new_subset (tvb, nextOffset, HeadersLen, HeadersLen);
5632 add_headers (mpart_tree, tmp_tvb, hf_wsp_headers_section);
5634 offset = nextOffset + HeadersLen;
5635 /* TODO - Try the dissectors of the multipart content */
5636 proto_tree_add_item (mpart_tree, hf_wsp_multipart_data, tvb, offset, DataLen, bo_little_endian);
5643 /* Register the protocol with Ethereal */
5645 proto_register_wsp(void)
5648 /* Setup list of header fields */
5649 static hf_register_info hf[] = {
5650 { &hf_wsp_header_tid,
5653 FT_UINT8, BASE_HEX, NULL, 0x00,
5654 "WSP Transaction ID (for connectionless WSP)", HFILL
5657 { &hf_wsp_header_pdu_type,
5660 FT_UINT8, BASE_HEX, VALS( vals_pdu_type ), 0x00,
5664 { &hf_wsp_version_major,
5665 { "Version (Major)",
5666 "wsp.version.major",
5667 FT_UINT8, BASE_DEC, NULL, 0xF0,
5668 "Version (Major)", HFILL
5671 { &hf_wsp_version_minor,
5672 { "Version (Minor)",
5673 "wsp.version.minor",
5674 FT_UINT8, BASE_DEC, NULL, 0x0F,
5675 "Version (Minor)", HFILL
5678 { &hf_capabilities_length,
5679 { "Capabilities Length",
5680 "wsp.capabilities.length",
5681 FT_UINT32, BASE_DEC, NULL, 0x00,
5682 "Length of Capabilities field (bytes)", HFILL
5685 { &hf_wsp_header_length,
5687 "wsp.headers_length",
5688 FT_UINT32, BASE_DEC, NULL, 0x00,
5689 "Length of Headers field (bytes)", HFILL
5692 { &hf_capabilities_section,
5695 FT_NONE, BASE_DEC, NULL, 0x00,
5696 "Capabilities", HFILL
5699 { &hf_wsp_headers_section,
5702 FT_NONE, BASE_DEC, NULL, 0x00,
5706 { &hf_wsp_header_uri_len,
5709 FT_UINT32, BASE_DEC, NULL, 0x00,
5710 "Length of URI field", HFILL
5713 { &hf_wsp_header_uri,
5716 FT_STRING, BASE_NONE, NULL, 0x00,
5720 { &hf_wsp_server_session_id,
5721 { "Server Session ID",
5722 "wsp.server.session_id",
5723 FT_UINT32, BASE_DEC, NULL, 0x00,
5724 "Server Session ID", HFILL
5727 { &hf_wsp_header_status,
5730 FT_UINT8, BASE_HEX, VALS( vals_status ), 0x00,
5731 "Reply Status", HFILL
5734 { &hf_wsp_parameter_type,
5736 "wsp.parameter.type",
5737 FT_UINT32, BASE_DEC, NULL, 0x00,
5741 { &hf_wsp_parameter_name,
5743 "wsp.parameter.name",
5744 FT_STRING, BASE_NONE, NULL, 0x00,
5748 { &hf_wsp_parameter_filename,
5750 "wsp.parameter.filename",
5751 FT_STRING, BASE_NONE, NULL, 0x00,
5755 { &hf_wsp_parameter_start,
5757 "wsp.parameter.start",
5758 FT_STRING, BASE_NONE, NULL, 0x00,
5762 { &hf_wsp_parameter_start_info,
5764 "wsp.parameter.start_info",
5765 FT_STRING, BASE_NONE, NULL, 0x00,
5769 { &hf_wsp_parameter_comment,
5771 "wsp.parameter.comment",
5772 FT_STRING, BASE_NONE, NULL, 0x00,
5776 { &hf_wsp_parameter_domain,
5778 "wsp.parameter.domain",
5779 FT_STRING, BASE_NONE, NULL, 0x00,
5783 { &hf_wsp_parameter_path,
5785 "wsp.parameter.path",
5786 FT_STRING, BASE_NONE, NULL, 0x00,
5790 { &hf_wsp_parameter_sec,
5792 "wsp.parameter.sec",
5793 FT_UINT8, BASE_HEX, VALS (vals_wsp_parameter_sec), 0x00,
5794 "SEC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
5797 { &hf_wsp_parameter_mac,
5799 "wsp.parameter.mac",
5800 FT_STRING, BASE_NONE, NULL, 0x00,
5801 "MAC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
5804 { &hf_wsp_parameter_upart_type,
5806 "wsp.parameter.upart.type",
5807 FT_STRING, BASE_NONE, NULL, 0x00,
5808 "Multipart type", HFILL
5811 { &hf_wsp_parameter_level,
5813 "wsp.parameter.level",
5814 FT_STRING, BASE_NONE, NULL, 0x00,
5815 "Level parameter", HFILL
5818 { &hf_wsp_reply_data,
5821 FT_NONE, BASE_NONE, NULL, 0x00,
5825 { &hf_wsp_header_shift_code,
5826 { "Switching to WSP header code-page",
5828 FT_UINT8, BASE_DEC, NULL, 0x00,
5829 "Header code-page shift code", HFILL
5833 * CO-WSP capability negotiation
5835 { &hf_capa_client_sdu_size,
5836 { "Client SDU Size",
5837 "wsp.capability.client_sdu_size",
5838 FT_UINT8, BASE_DEC, NULL, 0x00,
5839 "Client Service Data Unit size (bytes)", HFILL
5842 { &hf_capa_server_sdu_size,
5843 { "Server SDU Size",
5844 "wsp.capability.server_sdu_size",
5845 FT_UINT8, BASE_DEC, NULL, 0x00,
5846 "Server Service Data Unit size (bytes)", HFILL
5849 { &hf_capa_protocol_options,
5850 { "Protocol Options",
5851 "wsp.capability.protocol_opt",
5852 FT_STRING, BASE_HEX, NULL, 0x00,
5853 "Protocol Options", HFILL
5856 { &hf_capa_protocol_option_confirmed_push,
5857 { "Confirmed Push facility",
5858 "wsp.capability.protocol_option.confirmed_push",
5859 FT_BOOLEAN, 8, NULL, 0x80,
5860 "If set, this CO-WSP session supports the Confirmed Push facility", HFILL
5863 { &hf_capa_protocol_option_push,
5865 "wsp.capability.protocol_option.push",
5866 FT_BOOLEAN, 8, NULL, 0x40,
5867 "If set, this CO-WSP session supports the Push facility", HFILL
5870 { &hf_capa_protocol_option_session_resume,
5871 { "Session Resume facility",
5872 "wsp.capability.protocol_option.session_resume",
5873 FT_BOOLEAN, 8, NULL, 0x20,
5874 "If set, this CO-WSP session supports the Session Resume facility", HFILL
5877 { &hf_capa_protocol_option_ack_headers,
5878 { "Acknowledgement headers",
5879 "wsp.capability.protocol_option.ack_headers",
5880 FT_BOOLEAN, 8, NULL, 0x10,
5881 "If set, this CO-WSP session supports Acknowledgement headers", HFILL
5884 { &hf_capa_protocol_option_large_data_transfer,
5885 { "Large data transfer",
5886 "wsp.capability.protocol_option.large_data_transfer",
5887 FT_BOOLEAN, 8, NULL, 0x08,
5888 "If set, this CO-WSP session supports Large data transfer", HFILL
5891 { &hf_capa_method_mor,
5893 "wsp.capability.method_mor",
5894 FT_UINT8, BASE_DEC, NULL, 0x00,
5898 { &hf_capa_push_mor,
5900 "wsp.capability.push_mor",
5901 FT_UINT8, BASE_DEC, NULL, 0x00,
5905 { &hf_capa_extended_methods,
5906 { "Extended Methods",
5907 "wsp.capability.extended_methods",
5908 FT_STRING, BASE_HEX, NULL, 0x00,
5909 "Extended Methods", HFILL
5912 { &hf_capa_header_code_pages,
5913 { "Header Code Pages",
5914 "wsp.capability.code_pages",
5915 FT_STRING, BASE_HEX, NULL, 0x00,
5916 "Header Code Pages", HFILL
5921 "wsp.capability.aliases",
5922 FT_BYTES, BASE_NONE, NULL, 0x00,
5926 { &hf_capa_client_message_size,
5927 { "Client Message Size",
5928 "wsp.capability.client_message_size",
5929 FT_UINT8, BASE_DEC, NULL, 0x00,
5930 "Client Message size (bytes)", HFILL
5933 { &hf_capa_server_message_size,
5934 { "Server Message Size",
5935 "wsp.capability.server_message_size",
5936 FT_UINT8, BASE_DEC, NULL, 0x00,
5937 "Server Message size (bytes)", HFILL
5940 { &hf_wsp_post_data,
5943 FT_NONE, BASE_NONE, NULL, 0x00,
5947 { &hf_wsp_push_data,
5950 FT_NONE, BASE_NONE, NULL, 0x00,
5954 { &hf_wsp_multipart_data,
5955 { "Data in this part",
5956 "wsp.multipart.data",
5957 FT_NONE, BASE_NONE, NULL, 0x00,
5958 "The data of 1 MIME-multipart part.", HFILL
5964 FT_UINT32, BASE_DEC, NULL, 0x00,
5965 "MIME part of multipart data.", HFILL
5968 { &hf_wsp_redirect_flags,
5970 "wsp.redirect.flags",
5971 FT_UINT8, BASE_HEX, NULL, 0x00,
5972 "Redirect Flags", HFILL
5975 { &hf_wsp_redirect_permanent,
5976 { "Permanent Redirect",
5977 "wsp.redirect.flags.permanent",
5978 FT_BOOLEAN, 8, TFS(&yes_no_truth), PERMANENT_REDIRECT,
5979 "Permanent Redirect", HFILL
5982 { &hf_wsp_redirect_reuse_security_session,
5983 { "Reuse Security Session",
5984 "wsp.redirect.flags.reuse_security_session",
5985 FT_BOOLEAN, 8, TFS(&yes_no_truth), REUSE_SECURITY_SESSION,
5986 "If set, the existing Security Session may be reused", HFILL
5989 { &hf_redirect_addresses,
5990 { "Redirect Addresses",
5991 "wsp.redirect.addresses",
5992 FT_NONE, BASE_NONE, NULL, 0x00,
5993 "List of Redirect Addresses", HFILL
6000 { &hf_address_entry,
6003 FT_UINT32, BASE_DEC, NULL, 0x00,
6004 "Address Record", HFILL
6007 { &hf_address_flags_length,
6009 "wsp.address.flags",
6010 FT_UINT8, BASE_HEX, NULL, 0x00,
6011 "Address Flags/Length", HFILL
6014 { &hf_address_flags_length_bearer_type_included,
6015 { "Bearer Type Included",
6016 "wsp.address.flags.bearer_type_included",
6017 FT_BOOLEAN, 8, TFS(&yes_no_truth), BEARER_TYPE_INCLUDED,
6018 "Address bearer type included", HFILL
6021 { &hf_address_flags_length_port_number_included,
6022 { "Port Number Included",
6023 "wsp.address.flags.port_number_included",
6024 FT_BOOLEAN, 8, TFS(&yes_no_truth), PORT_NUMBER_INCLUDED,
6025 "Address port number included", HFILL
6028 { &hf_address_flags_length_address_len,
6030 "wsp.address.flags.length",
6031 FT_UINT8, BASE_DEC, NULL, ADDRESS_LEN,
6032 "Address Length", HFILL
6035 { &hf_address_bearer_type,
6037 "wsp.address.bearer_type",
6038 FT_UINT8, BASE_HEX, VALS(vals_bearer_types), 0x0,
6039 "Bearer Type", HFILL
6042 { &hf_address_port_num,
6045 FT_UINT16, BASE_DEC, NULL, 0x0,
6046 "Port Number", HFILL
6049 { &hf_address_ipv4_addr,
6052 FT_IPv4, BASE_NONE, NULL, 0x0,
6053 "Address (IPv4)", HFILL
6056 { &hf_address_ipv6_addr,
6059 FT_IPv6, BASE_NONE, NULL, 0x0,
6060 "Address (IPv6)", HFILL
6065 "wsp.address.unknown",
6066 FT_BYTES, BASE_NONE, NULL, 0x0,
6067 "Address (unknown)", HFILL
6073 * New WSP header fields
6077 /* WSP header name */
6081 FT_STRING, BASE_NONE, NULL, 0x00,
6082 "Name of the WSP header", HFILL
6085 /* WSP headers start here */
6088 "wsp.header.accept",
6089 FT_STRING, BASE_NONE, NULL, 0x00,
6090 "WSP header Accept", HFILL
6093 { &hf_hdr_accept_charset,
6095 "wsp.header.accept_charset",
6096 FT_STRING, BASE_NONE, NULL, 0x00,
6097 "WSP header Accept-Charset", HFILL
6100 { &hf_hdr_accept_encoding,
6101 { "Accept-Encoding",
6102 "wsp.header.accept_encoding",
6103 FT_STRING, BASE_NONE, NULL, 0x00,
6104 "WSP header Accept-Encoding", HFILL
6107 { &hf_hdr_accept_language,
6108 { "Accept-Language",
6109 "wsp.header.accept_language",
6110 FT_STRING, BASE_NONE, NULL, 0x00,
6111 "WSP header Accept-Language", HFILL
6114 { &hf_hdr_accept_ranges,
6116 "wsp.header.accept_ranges",
6117 FT_STRING, BASE_NONE, NULL, 0x00,
6118 "WSP header Accept-Ranges", HFILL
6124 FT_STRING, BASE_NONE, NULL, 0x00,
6125 "WSP header Age", HFILL
6131 FT_STRING, BASE_NONE, NULL, 0x00,
6132 "WSP header Allow", HFILL
6135 { &hf_hdr_authorization,
6137 "wsp.header.authorization",
6138 FT_STRING, BASE_NONE, NULL, 0x00,
6139 "WSP header Authorization", HFILL
6142 { &hf_hdr_authorization_scheme,
6143 { "Authorization Scheme",
6144 "wsp.header.authorization.scheme",
6145 FT_STRING, BASE_NONE, NULL, 0x00,
6146 "WSP header Authorization: used scheme", HFILL
6149 { &hf_hdr_authorization_user_id,
6151 "wsp.header.authorization.user_id",
6152 FT_STRING, BASE_NONE, NULL, 0x00,
6153 "WSP header Authorization: user ID for basic authorization", HFILL
6156 { &hf_hdr_authorization_password,
6158 "wsp.header.authorization.password",
6159 FT_STRING, BASE_NONE, NULL, 0x00,
6160 "WSP header Authorization: password for basic authorization", HFILL
6163 { &hf_hdr_cache_control,
6165 "wsp.header.cache_control",
6166 FT_STRING, BASE_NONE, NULL, 0x00,
6167 "WSP header Cache-Control", HFILL
6170 { &hf_hdr_connection,
6172 "wsp.header.connection",
6173 FT_STRING, BASE_NONE, NULL, 0x00,
6174 "WSP header Connection", HFILL
6177 { &hf_hdr_content_base,
6179 "wsp.header.content_base",
6180 FT_STRING, BASE_NONE, NULL, 0x00,
6181 "WSP header Content-Base", HFILL
6184 { &hf_hdr_content_encoding,
6185 { "Content-Encoding",
6186 "wsp.header.content_encoding",
6187 FT_STRING, BASE_NONE, NULL, 0x00,
6188 "WSP header Content-Encoding", HFILL
6191 { &hf_hdr_content_language,
6192 { "Content-Language",
6193 "wsp.header.content_language",
6194 FT_STRING, BASE_NONE, NULL, 0x00,
6195 "WSP header Content-Language", HFILL
6198 { &hf_hdr_content_length,
6200 "wsp.header.content_length",
6201 FT_STRING, BASE_NONE, NULL, 0x00,
6202 "WSP header Content-Length", HFILL
6205 { &hf_hdr_content_location,
6206 { "Content-Location",
6207 "wsp.header.content_location",
6208 FT_STRING, BASE_NONE, NULL, 0x00,
6209 "WSP header Content-Location", HFILL
6212 { &hf_hdr_content_md5,
6214 "wsp.header.content_md5",
6215 FT_STRING, BASE_NONE, NULL, 0x00,
6216 "WSP header Content-Md5", HFILL
6219 { &hf_hdr_content_range,
6221 "wsp.header.content_range",
6222 FT_STRING, BASE_NONE, NULL, 0x00,
6223 "WSP header Content-Range", HFILL
6226 { &hf_hdr_content_range_first_byte_pos,
6227 { "First-byte-position",
6228 "wsp.header.content_range.first_byte_pos",
6229 FT_UINT32, BASE_DEC, NULL, 0x00,
6230 "WSP header Content-Range: position of first byte", HFILL
6233 { &hf_hdr_content_range_entity_length,
6235 "wsp.header.content_range.entity_length",
6236 FT_UINT32, BASE_DEC, NULL, 0x00,
6237 "WSP header Content-Range: length of the entity", HFILL
6240 { &hf_hdr_content_type,
6242 "wsp.header.content_type",
6243 FT_STRING, BASE_NONE, NULL, 0x00,
6244 "WSP header Content-Type", HFILL
6250 FT_STRING, BASE_NONE, NULL, 0x00,
6251 "WSP header Date", HFILL
6257 FT_STRING, BASE_NONE, NULL, 0x00,
6258 "WSP header ETag", HFILL
6263 "wsp.header.expires",
6264 FT_STRING, BASE_NONE, NULL, 0x00,
6265 "WSP header Expires", HFILL
6271 FT_STRING, BASE_NONE, NULL, 0x00,
6272 "WSP header From", HFILL
6278 FT_STRING, BASE_NONE, NULL, 0x00,
6279 "WSP header Host", HFILL
6282 { &hf_hdr_if_modified_since,
6283 { "If-Modified-Since",
6284 "wsp.header.if_modified_since",
6285 FT_STRING, BASE_NONE, NULL, 0x00,
6286 "WSP header If-Modified-Since", HFILL
6291 "wsp.header.if_match",
6292 FT_STRING, BASE_NONE, NULL, 0x00,
6293 "WSP header If-Match", HFILL
6296 { &hf_hdr_if_none_match,
6298 "wsp.header.if_none_match",
6299 FT_STRING, BASE_NONE, NULL, 0x00,
6300 "WSP header If-None-Match", HFILL
6305 "wsp.header.if_range",
6306 FT_STRING, BASE_NONE, NULL, 0x00,
6307 "WSP header If-Range", HFILL
6310 { &hf_hdr_if_unmodified_since,
6311 { "If-Unmodified-Since",
6312 "wsp.header.if_unmodified_since",
6313 FT_STRING, BASE_NONE, NULL, 0x00,
6314 "WSP header If-Unmodified-Since", HFILL
6317 { &hf_hdr_last_modified,
6319 "wsp.header.last_modified",
6320 FT_STRING, BASE_NONE, NULL, 0x00,
6321 "WSP header Last-Modified", HFILL
6326 "wsp.header.location",
6327 FT_STRING, BASE_NONE, NULL, 0x00,
6328 "WSP header Location", HFILL
6331 { &hf_hdr_max_forwards,
6333 "wsp.header.max_forwards",
6334 FT_STRING, BASE_NONE, NULL, 0x00,
6335 "WSP header Max-Forwards", HFILL
6340 "wsp.header.pragma",
6341 FT_STRING, BASE_NONE, NULL, 0x00,
6342 "WSP header Pragma", HFILL
6345 { &hf_hdr_proxy_authenticate,
6346 { "Proxy-Authenticate",
6347 "wsp.header.proxy_authenticate",
6348 FT_STRING, BASE_NONE, NULL, 0x00,
6349 "WSP header Proxy-Authenticate", HFILL
6352 { &hf_hdr_proxy_authenticate_scheme,
6353 { "Authentication Scheme",
6354 "wsp.header.proxy_authenticate.scheme",
6355 FT_STRING, BASE_NONE, NULL, 0x00,
6356 "WSP header Proxy-Authenticate: used scheme", HFILL
6359 { &hf_hdr_proxy_authenticate_realm,
6360 { "Authentication Realm",
6361 "wsp.header.proxy_authenticate.realm",
6362 FT_STRING, BASE_NONE, NULL, 0x00,
6363 "WSP header Proxy-Authenticate: used realm", HFILL
6366 { &hf_hdr_proxy_authorization,
6367 { "Proxy-Authorization",
6368 "wsp.header.proxy_authorization",
6369 FT_STRING, BASE_NONE, NULL, 0x00,
6370 "WSP header Proxy-Authorization", HFILL
6373 { &hf_hdr_proxy_authorization_scheme,
6374 { "Authorization Scheme",
6375 "wsp.header.proxy_authorization.scheme",
6376 FT_STRING, BASE_NONE, NULL, 0x00,
6377 "WSP header Proxy-Authorization: used scheme", HFILL
6380 { &hf_hdr_proxy_authorization_user_id,
6382 "wsp.header.proxy_authorization.user_id",
6383 FT_STRING, BASE_NONE, NULL, 0x00,
6384 "WSP header Proxy-Authorization: user ID for basic authorization", HFILL
6387 { &hf_hdr_proxy_authorization_password,
6389 "wsp.header.proxy_authorization.password",
6390 FT_STRING, BASE_NONE, NULL, 0x00,
6391 "WSP header Proxy-Authorization: password for basic authorization", HFILL
6396 "wsp.header.public",
6397 FT_STRING, BASE_NONE, NULL, 0x00,
6398 "WSP header Public", HFILL
6404 FT_STRING, BASE_NONE, NULL, 0x00,
6405 "WSP header Range", HFILL
6408 { &hf_hdr_range_first_byte_pos,
6409 { "First-byte-position",
6410 "wsp.header.range.first_byte_pos",
6411 FT_UINT32, BASE_DEC, NULL, 0x00,
6412 "WSP header Range: position of first byte", HFILL
6415 { &hf_hdr_range_last_byte_pos,
6416 { "Last-byte-position",
6417 "wsp.header.range.last_byte_pos",
6418 FT_UINT32, BASE_DEC, NULL, 0x00,
6419 "WSP header Range: position of last byte", HFILL
6422 { &hf_hdr_range_suffix_length,
6424 "wsp.header.range.suffix_length",
6425 FT_UINT32, BASE_DEC, NULL, 0x00,
6426 "WSP header Range: length of the suffix", HFILL
6431 "wsp.header.referer",
6432 FT_STRING, BASE_NONE, NULL, 0x00,
6433 "WSP header Referer", HFILL
6436 { &hf_hdr_retry_after,
6438 "wsp.header.retry_after",
6439 FT_STRING, BASE_NONE, NULL, 0x00,
6440 "WSP header Retry-After", HFILL
6445 "wsp.header.server",
6446 FT_STRING, BASE_NONE, NULL, 0x00,
6447 "WSP header Server", HFILL
6450 { &hf_hdr_transfer_encoding,
6451 { "Transfer-Encoding",
6452 "wsp.header.transfer_encoding",
6453 FT_STRING, BASE_NONE, NULL, 0x00,
6454 "WSP header Transfer-Encoding", HFILL
6459 "wsp.header.upgrade",
6460 FT_STRING, BASE_NONE, NULL, 0x00,
6461 "WSP header Upgrade", HFILL
6464 { &hf_hdr_user_agent,
6466 "wsp.header.user_agent",
6467 FT_STRING, BASE_NONE, NULL, 0x00,
6468 "WSP header User-Agent", HFILL
6474 FT_STRING, BASE_NONE, NULL, 0x00,
6475 "WSP header Vary", HFILL
6481 FT_STRING, BASE_NONE, NULL, 0x00,
6482 "WSP header Via", HFILL
6487 "wsp.header.warning",
6488 FT_STRING, BASE_NONE, NULL, 0x00,
6489 "WSP header Warning", HFILL
6492 { &hf_hdr_warning_code,
6494 "wsp.header.warning.code",
6495 FT_UINT8, BASE_HEX, VALS(vals_wsp_warning_code), 0x00,
6496 "WSP header Warning code", HFILL
6499 { &hf_hdr_warning_agent,
6501 "wsp.header.warning.agent",
6502 FT_STRING, BASE_NONE, NULL, 0x00,
6503 "WSP header Warning agent", HFILL
6506 { &hf_hdr_warning_text,
6508 "wsp.header.warning.text",
6509 FT_STRING, BASE_NONE, NULL, 0x00,
6510 "WSP header Warning text", HFILL
6513 { &hf_hdr_www_authenticate,
6514 { "Www-Authenticate",
6515 "wsp.header.www_authenticate",
6516 FT_STRING, BASE_NONE, NULL, 0x00,
6517 "WSP header Www-Authenticate", HFILL
6520 { &hf_hdr_www_authenticate_scheme,
6521 { "Authentication Scheme",
6522 "wsp.header.www_authenticate.scheme",
6523 FT_STRING, BASE_NONE, NULL, 0x00,
6524 "WSP header WWW-Authenticate: used scheme", HFILL
6527 { &hf_hdr_www_authenticate_realm,
6528 { "Authentication Realm",
6529 "wsp.header.www_authenticate.realm",
6530 FT_STRING, BASE_NONE, NULL, 0x00,
6531 "WSP header WWW-Authenticate: used realm", HFILL
6534 { &hf_hdr_content_disposition,
6535 { "Content-Disposition",
6536 "wsp.header.content_disposition",
6537 FT_STRING, BASE_NONE, NULL, 0x00,
6538 "WSP header Content-Disposition", HFILL
6541 { &hf_hdr_application_id,
6543 "wsp.header.application_id",
6544 FT_STRING, BASE_NONE, NULL, 0x00,
6545 "WSP header Application-Id", HFILL
6548 { &hf_hdr_content_uri,
6550 "wsp.header.content_uri",
6551 FT_STRING, BASE_NONE, NULL, 0x00,
6552 "WSP header Content-Uri", HFILL
6555 { &hf_hdr_initiator_uri,
6557 "wsp.header.initiator_uri",
6558 FT_STRING, BASE_NONE, NULL, 0x00,
6559 "WSP header Initiator-Uri", HFILL
6562 { &hf_hdr_bearer_indication,
6563 { "Bearer-Indication",
6564 "wsp.header.bearer_indication",
6565 FT_STRING, BASE_NONE, NULL, 0x00,
6566 "WSP header Bearer-Indication", HFILL
6569 { &hf_hdr_push_flag,
6571 "wsp.header.push_flag",
6572 FT_STRING, BASE_NONE, NULL, 0x00,
6573 "WSP header Push-Flag", HFILL
6576 { &hf_hdr_push_flag_auth,
6577 { "Initiator URI is authenticated",
6578 "wsp.header.push_flag.authenticated",
6579 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x01,
6580 "The X-Wap-Initiator-URI has been authenticated.", HFILL
6583 { &hf_hdr_push_flag_trust,
6584 { "Content is trusted",
6585 "wsp.header.push_flag.trusted",
6586 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x02,
6587 "The push content is trusted.", HFILL
6590 { &hf_hdr_push_flag_last,
6591 { "Last push message",
6592 "wsp.header.push_flag.last",
6593 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x04,
6594 "Indicates whether this is the last push message.", HFILL
6599 "wsp.header.profile",
6600 FT_STRING, BASE_NONE, NULL, 0x00,
6601 "WSP header Profile", HFILL
6604 { &hf_hdr_profile_diff,
6606 "wsp.header.profile_diff",
6607 FT_STRING, BASE_NONE, NULL, 0x00,
6608 "WSP header Profile-Diff", HFILL
6611 { &hf_hdr_profile_warning,
6612 { "Profile-Warning",
6613 "wsp.header.profile_warning",
6614 FT_STRING, BASE_NONE, NULL, 0x00,
6615 "WSP header Profile-Warning", HFILL
6620 "wsp.header.expect",
6621 FT_STRING, BASE_NONE, NULL, 0x00,
6622 "WSP header Expect", HFILL
6628 FT_STRING, BASE_NONE, NULL, 0x00,
6629 "WSP header Te", HFILL
6634 "wsp.header.trailer",
6635 FT_STRING, BASE_NONE, NULL, 0x00,
6636 "WSP header Trailer", HFILL
6639 { &hf_hdr_x_wap_tod,
6641 "wsp.header.x_wap_tod",
6642 FT_STRING, BASE_NONE, NULL, 0x00,
6643 "WSP header X-Wap-Tod", HFILL
6646 { &hf_hdr_content_id,
6648 "wsp.header.content_id",
6649 FT_STRING, BASE_NONE, NULL, 0x00,
6650 "WSP header Content-Id", HFILL
6653 { &hf_hdr_set_cookie,
6655 "wsp.header.set_cookie",
6656 FT_STRING, BASE_NONE, NULL, 0x00,
6657 "WSP header Set-Cookie", HFILL
6662 "wsp.header.cookie",
6663 FT_STRING, BASE_NONE, NULL, 0x00,
6664 "WSP header Cookie", HFILL
6667 { &hf_hdr_encoding_version,
6668 { "Encoding-Version",
6669 "wsp.header.encoding_version",
6670 FT_STRING, BASE_NONE, NULL, 0x00,
6671 "WSP header Encoding-Version", HFILL
6674 { &hf_hdr_x_wap_security,
6676 "wsp.header.x_wap_security",
6677 FT_STRING, BASE_NONE, NULL, 0x00,
6678 "WSP header X-Wap-Security", HFILL
6681 { &hf_hdr_x_wap_application_id,
6682 { "X-Wap-Application-Id",
6683 "wsp.header.x_wap_application_id",
6684 FT_STRING, BASE_NONE, NULL, 0x00,
6685 "WSP header X-Wap-Application-Id", HFILL
6688 { &hf_hdr_accept_application,
6689 { "Accept-Application",
6690 "wsp.header.accept_application",
6691 FT_STRING, BASE_NONE, NULL, 0x00,
6692 "WSP header Accept-Application", HFILL
6699 * Header Code Page: x-up-1
6702 /* Textual headers */
6703 { &hf_hdr_openwave_x_up_proxy_operator_domain,
6704 { "x-up-proxy-operator-domain",
6705 "wsp.header.x_up_1.x_up_proxy_operator_domain",
6706 FT_STRING, BASE_NONE, NULL, 0x00,
6707 "WSP Openwave header x-up-proxy-operator-domain", HFILL
6710 { &hf_hdr_openwave_x_up_proxy_home_page,
6711 { "x-up-proxy-home-page",
6712 "wsp.header.x_up_1.x_up_proxy_home_page",
6713 FT_STRING, BASE_NONE, NULL, 0x00,
6714 "WSP Openwave header x-up-proxy-home-page", HFILL
6717 { &hf_hdr_openwave_x_up_proxy_uplink_version,
6718 { "x-up-proxy-uplink-version",
6719 "wsp.header.x_up_1.x_up_proxy_uplink_version",
6720 FT_STRING, BASE_NONE, NULL, 0x00,
6721 "WSP Openwave header x-up-proxy-uplink-version", HFILL
6724 { &hf_hdr_openwave_x_up_proxy_ba_realm,
6725 { "x-up-proxy-ba-realm",
6726 "wsp.header.x_up_1.x_up_proxy_ba_realm",
6727 FT_STRING, BASE_NONE, NULL, 0x00,
6728 "WSP Openwave header x-up-proxy-ba-realm", HFILL
6731 { &hf_hdr_openwave_x_up_proxy_request_uri,
6732 { "x-up-proxy-request-uri",
6733 "wsp.header.x_up_1.x_up_proxy_request_uri",
6734 FT_STRING, BASE_NONE, NULL, 0x00,
6735 "WSP Openwave header x-up-proxy-request-uri", HFILL
6738 { &hf_hdr_openwave_x_up_proxy_bookmark,
6739 { "x-up-proxy-bookmark",
6740 "wsp.header.x_up_1.x_up_proxy_bookmark",
6741 FT_STRING, BASE_NONE, NULL, 0x00,
6742 "WSP Openwave header x-up-proxy-bookmark", HFILL
6745 /* Integer-value headers */
6746 { &hf_hdr_openwave_x_up_proxy_push_seq,
6747 { "x-up-proxy-push-seq",
6748 "wsp.header.x_up_1.x_up_proxy_push_seq",
6749 FT_STRING, BASE_NONE, NULL, 0x00,
6750 "WSP Openwave header x-up-proxy-push-seq", HFILL
6753 { &hf_hdr_openwave_x_up_proxy_notify,
6754 { "x-up-proxy-notify",
6755 "wsp.header.x_up_1.x_up_proxy_notify",
6756 FT_STRING, BASE_NONE, NULL, 0x00,
6757 "WSP Openwave header x-up-proxy-notify", HFILL
6760 { &hf_hdr_openwave_x_up_proxy_net_ask,
6761 { "x-up-proxy-net-ask",
6762 "wsp.header.x_up_1.x_up_proxy_net_ask",
6763 FT_STRING, BASE_NONE, NULL, 0x00,
6764 "WSP Openwave header x-up-proxy-net-ask", HFILL
6767 { &hf_hdr_openwave_x_up_proxy_tod,
6769 "wsp.header.x_up_1.x_up_proxy_tod",
6770 FT_STRING, BASE_NONE, NULL, 0x00,
6771 "WSP Openwave header x-up-proxy-tod", HFILL
6774 { &hf_hdr_openwave_x_up_proxy_ba_enable,
6775 { "x-up-proxy-ba-enable",
6776 "wsp.header.x_up_1.x_up_proxy_ba_enable",
6777 FT_STRING, BASE_NONE, NULL, 0x00,
6778 "WSP Openwave header x-up-proxy-ba-enable", HFILL
6781 { &hf_hdr_openwave_x_up_proxy_redirect_enable,
6782 { "x-up-proxy-redirect-enable",
6783 "wsp.header.x_up_1.x_up_proxy_redirect_enable",
6784 FT_STRING, BASE_NONE, NULL, 0x00,
6785 "WSP Openwave header x-up-proxy-redirect-enable", HFILL
6788 { &hf_hdr_openwave_x_up_proxy_redirect_status,
6789 { "x-up-proxy-redirect-status",
6790 "wsp.header.x_up_1.x_up_proxy_redirect_status",
6791 FT_STRING, BASE_NONE, NULL, 0x00,
6792 "WSP Openwave header x-up-proxy-redirect-status", HFILL
6795 { &hf_hdr_openwave_x_up_proxy_linger,
6796 { "x-up-proxy-linger",
6797 "wsp.header.x_up_1.x_up_proxy_linger",
6798 FT_STRING, BASE_NONE, NULL, 0x00,
6799 "WSP Openwave header x-up-proxy-linger", HFILL
6802 { &hf_hdr_openwave_x_up_proxy_enable_trust,
6803 { "x-up-proxy-enable-trust",
6804 "wsp.header.x_up_1.x_up_proxy_enable_trust",
6805 FT_STRING, BASE_NONE, NULL, 0x00,
6806 "WSP Openwave header x-up-proxy-enable-trust", HFILL
6809 { &hf_hdr_openwave_x_up_proxy_trust,
6810 { "x-up-proxy-trust",
6811 "wsp.header.x_up_1.x_up_proxy_trust",
6812 FT_STRING, BASE_NONE, NULL, 0x00,
6813 "WSP Openwave header x-up-proxy-trust", HFILL
6816 { &hf_hdr_openwave_x_up_devcap_has_color,
6817 { "x-up-devcap-has-color",
6818 "wsp.header.x_up_1.x_up_devcap_has_color",
6819 FT_STRING, BASE_NONE, NULL, 0x00,
6820 "WSP Openwave header x-up-devcap-has-color", HFILL
6823 { &hf_hdr_openwave_x_up_devcap_num_softkeys,
6824 { "x-up-devcap-num-softkeys",
6825 "wsp.header.x_up_1.x_up_devcap_num_softkeys",
6826 FT_STRING, BASE_NONE, NULL, 0x00,
6827 "WSP Openwave header x-up-devcap-num-softkeys", HFILL
6830 { &hf_hdr_openwave_x_up_devcap_softkey_size,
6831 { "x-up-devcap-softkey-size",
6832 "wsp.header.x_up_1.x_up_devcap_softkey_size",
6833 FT_STRING, BASE_NONE, NULL, 0x00,
6834 "WSP Openwave header x-up-devcap-softkey-size", HFILL
6837 { &hf_hdr_openwave_x_up_devcap_screen_chars,
6838 { "x-up-devcap-screen-chars",
6839 "wsp.header.x_up_1.x_up_devcap_screen_chars",
6840 FT_STRING, BASE_NONE, NULL, 0x00,
6841 "WSP Openwave header x-up-devcap-screen-chars", HFILL
6844 { &hf_hdr_openwave_x_up_devcap_screen_pixels,
6845 { "x-up-devcap-screen-pixels",
6846 "wsp.header.x_up_1.x_up_devcap_screen_pixels",
6847 FT_STRING, BASE_NONE, NULL, 0x00,
6848 "WSP Openwave header x-up-devcap-screen-pixels", HFILL
6851 { &hf_hdr_openwave_x_up_devcap_em_size,
6852 { "x-up-devcap-em-size",
6853 "wsp.header.x_up_1.x_up_devcap_em_size",
6854 FT_STRING, BASE_NONE, NULL, 0x00,
6855 "WSP Openwave header x-up-devcap-em-size", HFILL
6858 { &hf_hdr_openwave_x_up_devcap_screen_depth,
6859 { "x-up-devcap-screen-depth",
6860 "wsp.header.x_up_1.x_up_devcap_screen_depth",
6861 FT_STRING, BASE_NONE, NULL, 0x00,
6862 "WSP Openwave header x-up-devcap-screen-depth", HFILL
6865 { &hf_hdr_openwave_x_up_devcap_immed_alert,
6866 { "x-up-devcap-immed-alert",
6867 "wsp.header.x_up_1.x_up_devcap_immed_alert",
6868 FT_STRING, BASE_NONE, NULL, 0x00,
6869 "WSP Openwave header x-up-devcap-immed-alert", HFILL
6872 { &hf_hdr_openwave_x_up_devcap_gui,
6873 { "x-up-devcap-gui",
6874 "wsp.header.x_up_1.x_up_devcap_gui",
6875 FT_STRING, BASE_NONE, NULL, 0x00,
6876 "WSP Openwave header x-up-devcap-gui", HFILL
6879 { &hf_hdr_openwave_x_up_proxy_trans_charset,
6880 { "x-up-proxy-trans-charset",
6881 "wsp.header.x_up_1.x_up_proxy_trans_charset",
6882 FT_STRING, BASE_NONE, NULL, 0x00,
6883 "WSP Openwave header x-up-proxy-trans-charset", HFILL
6886 { &hf_hdr_openwave_x_up_proxy_push_accept,
6887 { "x-up-proxy-push-accept",
6888 "wsp.header.x_up_1.x_up_proxy_push_accept",
6889 FT_STRING, BASE_NONE, NULL, 0x00,
6890 "WSP Openwave header x-up-proxy-push-accept", HFILL
6895 { &hf_hdr_openwave_x_up_proxy_client_id,
6896 { "x-up-proxy-client-id",
6897 "wsp.header.x_up_1.x_up_proxy_client_id",
6898 FT_STRING, BASE_NONE, NULL, 0x00,
6899 "WSP Openwave header x-up-proxy-client-id", HFILL
6905 * Header value parameters
6911 FT_STRING, BASE_NONE, NULL, 0x00,
6912 "Q parameter", HFILL
6915 { &hf_parameter_charset,
6917 "wsp.parameter.charset",
6918 FT_STRING, BASE_NONE, NULL, 0x00,
6919 "Charset parameter", HFILL
6924 * Session Initiation Request
6927 { "Session Initiation Request",
6929 FT_NONE, BASE_NONE, NULL, 0x00,
6930 "Session Initiation Request content", HFILL
6936 FT_UINT8, BASE_DEC, NULL, 0x00,
6937 "Version of the Session Initiation Request document", HFILL
6940 { &hf_sir_app_id_list_len,
6941 { "Application-ID List Length",
6942 "wsp.sir.app_id_list.length",
6943 FT_UINT32, BASE_DEC, NULL, 0x00,
6944 "Length of the Application-ID list (bytes)", HFILL
6947 { &hf_sir_app_id_list,
6948 { "Application-ID List",
6949 "wsp.sir.app_id_list",
6950 FT_NONE, BASE_NONE, NULL, 0x00,
6951 "Application-ID list", HFILL
6954 { &hf_sir_wsp_contact_points_len,
6955 { "WSP Contact Points Length",
6956 "wsp.sir.wsp_contact_points.length",
6957 FT_UINT32, BASE_DEC, NULL, 0x00,
6958 "Length of the WSP Contact Points list (bytes)", HFILL
6961 { &hf_sir_wsp_contact_points,
6962 { "WSP Contact Points",
6963 "wsp.sir.wsp_contact_points",
6964 FT_NONE, BASE_NONE, NULL, 0x00,
6965 "WSP Contact Points list", HFILL
6968 { &hf_sir_contact_points_len,
6969 { "Non-WSP Contact Points Length",
6970 "wsp.sir.contact_points.length",
6971 FT_UINT32, BASE_DEC, NULL, 0x00,
6972 "Length of the Non-WSP Contact Points list (bytes)", HFILL
6975 { &hf_sir_contact_points,
6976 { "Non-WSP Contact Points",
6977 "wsp.sir.contact_points",
6978 FT_NONE, BASE_NONE, NULL, 0x00,
6979 "Non-WSP Contact Points list", HFILL
6982 { &hf_sir_protocol_options_len,
6983 { "Protocol Options List Entries",
6984 "wsp.sir.protocol_options.length",
6985 FT_UINT32, BASE_DEC, NULL, 0x00,
6986 "Number of entries in the Protocol Options list", HFILL
6989 { &hf_sir_protocol_options,
6990 { "Protocol Options",
6991 "wsp.sir.protocol_options",
6992 FT_UINT16, BASE_DEC, VALS(vals_sir_protocol_options), 0x00,
6993 "Protocol Options list", HFILL
6996 { &hf_sir_prov_url_len,
6997 { "X-Wap-ProvURL Length",
6998 "wsp.sir.prov_url.length",
6999 FT_UINT32, BASE_DEC, NULL, 0x00,
7000 "Length of the X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL
7006 FT_STRING, BASE_NONE, NULL, 0x00,
7007 "X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL
7010 { &hf_sir_cpi_tag_len,
7011 { "CPITag List Entries",
7012 "wsp.sir.cpi_tag.length",
7013 FT_UINT32, BASE_DEC, NULL, 0x00,
7014 "Number of entries in the CPITag list", HFILL
7020 FT_BYTES, BASE_HEX, NULL, 0x00,
7021 "CPITag (OTA-HTTP)", HFILL
7029 /* Setup protocol subtree array */
7030 static gint *ett[] = { /* TODO - remove unneeded subtrees */
7032 &ett_header, /* Header field subtree */
7033 &ett_headers, /* Subtree for WSP headers */
7034 &ett_capabilities, /* CO-WSP Session Capabilities */
7035 &ett_capability, /* CO-WSP Session single Capability */
7037 &ett_redirect_flags,
7041 &ett_sir, /* Session Initiation Request */
7042 &ett_addresses, /* Addresses */
7043 &ett_address, /* Single address */
7046 /* Register the protocol name and description */
7047 proto_wsp = proto_register_protocol(
7048 "Wireless Session Protocol", /* protocol name for use by ethereal */
7049 "WSP", /* short version of name */
7050 "wsp" /* Abbreviated protocol name,
7052 < URL:http://www.isi.edu/in-notes/iana/assignments/port-numbers/ >
7055 wsp_tap = register_tap("wsp");
7056 /* Init the hash table */
7057 /* wsp_sessions = g_hash_table_new(
7058 (GHashFunc) wsp_session_hash,
7059 (GEqualFunc)wsp_session_equal);*/
7061 /* Required function calls to register the header fields and subtrees used */
7062 proto_register_field_array(proto_wsp, hf, array_length(hf));
7063 proto_register_subtree_array(ett, array_length(ett));
7065 register_dissector("wsp-co", dissect_wsp_fromwap_co, proto_wsp);
7066 register_dissector("wsp-cl", dissect_wsp_fromwap_cl, proto_wsp);
7067 /* As the media types for WSP and HTTP are the same, the WSP dissector
7068 * uses the same string dissector table as the HTTP protocol. */
7069 media_type_table = find_dissector_table("media_type");
7070 register_heur_dissector_list("wsp", &heur_subdissector_list);
7072 wsp_fromudp_handle = create_dissector_handle(dissect_wsp_fromudp,
7077 proto_reg_handoff_wsp(void)
7080 * And get a handle for the WTP-over-UDP dissector.
7082 wtp_fromudp_handle = find_dissector("wtp-udp");
7084 /* Only connection-less WSP has no previous handler */
7085 dissector_add("udp.port", UDP_PORT_WSP, wsp_fromudp_handle);
7086 dissector_add("udp.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
7088 /* SMPP dissector can also carry WSP */
7089 dissector_add("smpp.udh.port", UDP_PORT_WSP, wsp_fromudp_handle);
7090 dissector_add("smpp.udh.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
7092 /* This dissector is also called from the WTP and WTLS dissectors */