3 * Routines to dissect WSP component of WAP traffic.
5 * Refer to the AUTHORS file or the AUTHORS section in the man page
6 * for contacting the author(s) of this file.
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * WAP dissector based on original work by Ben Fowler
13 * Updated by Neil Hunter.
15 * WTLS support by Alexandre P. Ferreira (Splice IP).
17 * Openwave header support by Dermot Bradley (Openwave).
19 * Code optimizations, header value dissection simplification with parse error
20 * notification and macros, extra missing headers, WBXML registration,
21 * summary line of WSP PDUs,
22 * Session Initiation Request dissection
25 * TODO - Move parts of dissection before and other parts after "if (tree)",
26 * for example skip almost all but content type in replies if tree is closed.
28 * SPDX-License-Identifier: GPL-2.0-or-later
33 #include <epan/packet.h>
34 #include <epan/to_str.h>
35 #include <epan/expert.h>
36 #include <epan/conversation.h>
37 #include <epan/iana_charsets.h>
39 #include <wsutil/str_util.h>
41 #include "packet-wap.h"
42 #include "packet-wsp.h"
44 /* Statistics (see doc/README.tapping) */
45 #include <epan/stat_tap_ui.h>
48 void proto_register_wsp(void);
49 void proto_reg_handoff_wsp(void);
50 void proto_register_sir(void);
51 void proto_reg_handoff_sir(void);
53 static int wsp_tap = -1;
56 /* File scoped variables for the protocol and registered fields */
57 static int proto_wsp = -1;
58 static int proto_sir = -1;
61 * Initialize the header field pointers
64 /* WSP header fields and their subfields if available */
65 static int hf_hdr_name_value = -1;
66 static int hf_hdr_name_string = -1;
67 static int hf_hdr_accept = -1;
68 static int hf_hdr_accept_charset = -1;
69 static int hf_hdr_accept_encoding = -1;
70 static int hf_hdr_accept_language = -1;
71 static int hf_hdr_accept_ranges = -1;
72 static int hf_hdr_age = -1;
73 static int hf_hdr_allow = -1;
74 static int hf_hdr_authorization = -1;
75 static int hf_hdr_authorization_scheme = -1; /* Subfield */
76 static int hf_hdr_authorization_user_id = -1; /* Subfield */
77 static int hf_hdr_authorization_password = -1; /* Subfield */
78 static int hf_hdr_cache_control = -1;
79 static int hf_hdr_connection = -1;
80 static int hf_hdr_content_base = -1;
81 static int hf_hdr_content_encoding = -1;
82 static int hf_hdr_content_language = -1;
83 static int hf_hdr_content_length = -1;
84 static int hf_hdr_content_location = -1;
85 static int hf_hdr_content_md5 = -1;
86 static int hf_hdr_content_range = -1;
87 static int hf_hdr_content_range_first_byte_pos = -1; /* Subfield */
88 static int hf_hdr_content_range_entity_length = -1; /* Subfield */
89 static int hf_hdr_content_type = -1;
90 static int hf_hdr_date = -1;
91 static int hf_hdr_etag = -1;
92 static int hf_hdr_expires = -1;
93 static int hf_hdr_from = -1;
94 static int hf_hdr_host = -1;
95 static int hf_hdr_if_modified_since = -1;
96 static int hf_hdr_if_match = -1;
97 static int hf_hdr_if_none_match = -1;
98 static int hf_hdr_if_range = -1;
99 static int hf_hdr_if_unmodified_since = -1;
100 static int hf_hdr_last_modified = -1;
101 static int hf_hdr_location = -1;
102 static int hf_hdr_max_forwards = -1;
103 static int hf_hdr_pragma = -1;
104 static int hf_hdr_proxy_authenticate = -1;
105 static int hf_hdr_proxy_authenticate_scheme = -1; /* Subfield */
106 static int hf_hdr_proxy_authenticate_realm = -1; /* Subfield */
107 static int hf_hdr_proxy_authorization = -1;
108 static int hf_hdr_proxy_authorization_scheme = -1; /* Subfield */
109 static int hf_hdr_proxy_authorization_user_id = -1; /* Subfield */
110 static int hf_hdr_proxy_authorization_password = -1; /* Subfield */
111 static int hf_hdr_public = -1;
112 static int hf_hdr_range = -1;
113 static int hf_hdr_range_first_byte_pos = -1; /* Subfield */
114 static int hf_hdr_range_last_byte_pos = -1; /* Subfield */
115 static int hf_hdr_range_suffix_length = -1; /* Subfield */
116 static int hf_hdr_referer = -1;
117 static int hf_hdr_retry_after = -1;
118 static int hf_hdr_server = -1;
119 static int hf_hdr_transfer_encoding = -1;
120 static int hf_hdr_upgrade = -1;
121 static int hf_hdr_user_agent = -1;
122 static int hf_hdr_vary = -1;
123 static int hf_hdr_via = -1;
124 static int hf_hdr_warning = -1;
125 static int hf_hdr_warning_code = -1; /* Subfield */
126 static int hf_hdr_warning_agent = -1; /* Subfield */
127 static int hf_hdr_warning_text = -1; /* Subfield */
128 static int hf_hdr_www_authenticate = -1;
129 static int hf_hdr_www_authenticate_scheme = -1; /* Subfield */
130 static int hf_hdr_www_authenticate_realm = -1; /* Subfield */
131 static int hf_hdr_content_disposition = -1;
132 static int hf_hdr_application_id = -1;
133 static int hf_hdr_content_uri = -1;
134 static int hf_hdr_initiator_uri = -1;
135 static int hf_hdr_bearer_indication = -1;
136 static int hf_hdr_push_flag = -1;
137 static int hf_hdr_push_flag_auth = -1; /* Subfield */
138 static int hf_hdr_push_flag_trust = -1; /* Subfield */
139 static int hf_hdr_push_flag_last = -1; /* Subfield */
140 static int hf_hdr_profile = -1;
141 static int hf_hdr_profile_diff = -1;
142 static int hf_hdr_profile_warning = -1;
143 static int hf_hdr_expect = -1;
144 static int hf_hdr_te = -1;
145 static int hf_hdr_trailer = -1;
146 static int hf_hdr_x_wap_tod = -1;
147 static int hf_hdr_content_id = -1;
148 static int hf_hdr_set_cookie = -1;
149 static int hf_hdr_cookie = -1;
150 static int hf_hdr_encoding_version = -1;
151 static int hf_hdr_x_wap_security = -1;
152 static int hf_hdr_x_wap_application_id = -1;
153 static int hf_hdr_accept_application = -1;
156 /* Openwave headers */
157 static int hf_hdr_openwave_default_int = -1;
158 static int hf_hdr_openwave_default_string = -1;
159 static int hf_hdr_openwave_default_val_len = -1;
160 static int hf_hdr_openwave_name_value = -1;
161 static int hf_hdr_openwave_x_up_proxy_operator_domain = -1;
162 static int hf_hdr_openwave_x_up_proxy_home_page = -1;
163 static int hf_hdr_openwave_x_up_proxy_uplink_version = -1;
164 static int hf_hdr_openwave_x_up_proxy_ba_realm = -1;
165 static int hf_hdr_openwave_x_up_proxy_request_uri = -1;
167 static int hf_hdr_openwave_x_up_proxy_client_id = -1;
169 static int hf_hdr_openwave_x_up_proxy_bookmark = -1;
170 static int hf_hdr_openwave_x_up_proxy_push_seq = -1;
171 static int hf_hdr_openwave_x_up_proxy_notify = -1;
172 static int hf_hdr_openwave_x_up_proxy_net_ask = -1;
173 static int hf_hdr_openwave_x_up_proxy_tod = -1;
174 static int hf_hdr_openwave_x_up_proxy_ba_enable = -1;
175 static int hf_hdr_openwave_x_up_proxy_redirect_enable = -1;
176 static int hf_hdr_openwave_x_up_proxy_redirect_status = -1;
177 static int hf_hdr_openwave_x_up_proxy_linger = -1;
178 static int hf_hdr_openwave_x_up_proxy_enable_trust = -1;
179 static int hf_hdr_openwave_x_up_proxy_trust = -1;
180 static int hf_hdr_openwave_x_up_devcap_has_color = -1;
181 static int hf_hdr_openwave_x_up_devcap_num_softkeys = -1;
182 static int hf_hdr_openwave_x_up_devcap_softkey_size = -1;
183 static int hf_hdr_openwave_x_up_devcap_screen_chars = -1;
184 static int hf_hdr_openwave_x_up_devcap_screen_pixels = -1;
185 static int hf_hdr_openwave_x_up_devcap_em_size = -1;
186 static int hf_hdr_openwave_x_up_devcap_screen_depth = -1;
187 static int hf_hdr_openwave_x_up_devcap_immed_alert = -1;
188 static int hf_hdr_openwave_x_up_devcap_gui = -1;
189 static int hf_hdr_openwave_x_up_proxy_trans_charset = -1;
190 static int hf_hdr_openwave_x_up_proxy_push_accept = -1;
193 /* WSP parameter fields */
194 static int hf_parameter_q = -1;
195 static int hf_parameter_charset = -1;
197 /* Old header fields */
199 static int hf_wsp_header_tid = -1;
200 static int hf_wsp_header_pdu_type = -1;
201 static int hf_wsp_version_major = -1;
202 static int hf_wsp_version_minor = -1;
203 /* Session capabilities (CO-WSP) */
204 static int hf_capabilities_length = -1;
205 static int hf_capabilities_section = -1;
206 static int hf_capa_client_sdu_size = -1;
207 static int hf_capa_server_sdu_size = -1;
208 static int hf_capa_protocol_options = -1;
209 static int hf_capa_protocol_option_confirmed_push = -1; /* Subfield */
210 static int hf_capa_protocol_option_push = -1; /* Subfield */
211 static int hf_capa_protocol_option_session_resume = -1; /* Subfield */
212 static int hf_capa_protocol_option_ack_headers = -1; /* Subfield */
213 static int hf_capa_protocol_option_large_data_transfer = -1; /* Subfield */
214 static int hf_capa_method_mor = -1;
215 static int hf_capa_push_mor = -1;
216 static int hf_capa_extended_method = -1;
217 static int hf_capa_header_code_page = -1;
218 static int hf_capa_aliases = -1;
219 static int hf_capa_client_message_size = -1;
220 static int hf_capa_server_message_size = -1;
222 static int hf_wsp_header_uri_len = -1;
223 static int hf_wsp_header_uri = -1;
224 static int hf_wsp_server_session_id = -1;
225 static int hf_wsp_header_status = -1;
226 static int hf_wsp_header_length = -1;
227 static int hf_wsp_headers_section = -1;
228 static int hf_wsp_parameter_untype_quote_text = -1;
229 static int hf_wsp_parameter_untype_text = -1;
230 static int hf_wsp_parameter_untype_int = -1;
231 static int hf_wsp_parameter_type = -1;
232 static int hf_wsp_parameter_int_type = -1;
233 static int hf_wsp_parameter_name = -1;
234 static int hf_wsp_parameter_filename = -1;
235 static int hf_wsp_parameter_start = -1;
236 static int hf_wsp_parameter_start_info = -1;
237 static int hf_wsp_parameter_comment = -1;
238 static int hf_wsp_parameter_domain = -1;
239 static int hf_wsp_parameter_path = -1;
240 static int hf_wsp_parameter_sec = -1;
241 static int hf_wsp_parameter_mac = -1;
242 static int hf_wsp_parameter_upart_type = -1;
243 static int hf_wsp_parameter_level = -1;
244 static int hf_wsp_parameter_size = -1;
246 static int hf_wsp_reply_data = -1;
248 static int hf_wsp_post_data = -1;
250 static int hf_wsp_push_data = -1;
251 static int hf_wsp_multipart_data = -1;
253 static int hf_wsp_mpart = -1;
254 static int hf_wsp_header_text_value = -1;
255 static int hf_wsp_variable_value = -1;
256 static int hf_wsp_default_int = -1;
257 static int hf_wsp_default_string = -1;
258 static int hf_wsp_default_val_len = -1;
260 /* Header code page shift sequence */
261 static int hf_wsp_header_shift_code = -1;
263 /* WSP Redirect fields */
264 static int hf_wsp_redirect_flags = -1;
265 static int hf_wsp_redirect_permanent = -1;
266 static int hf_wsp_redirect_reuse_security_session = -1;
267 static int hf_redirect_addresses = -1;
270 static int hf_address_entry = -1;
271 static int hf_address_flags_length = -1;
272 static int hf_address_flags_length_bearer_type_included = -1; /* Subfield */
273 static int hf_address_flags_length_port_number_included = -1; /* Subfield */
274 static int hf_address_flags_length_address_len = -1; /* Subfield */
275 static int hf_address_bearer_type = -1;
276 static int hf_address_port_num = -1;
277 static int hf_address_ipv4_addr = -1;
278 static int hf_address_ipv6_addr = -1;
279 static int hf_address_addr = -1;
281 /* Session Initiation Request fields */
282 static int hf_sir_section = -1;
283 static int hf_sir_version = -1;
284 static int hf_sir_app_id_list_len = -1;
285 static int hf_sir_app_id_list = -1;
286 static int hf_sir_wsp_contact_points_len = -1;
287 static int hf_sir_wsp_contact_points = -1;
288 static int hf_sir_contact_points_len = -1;
289 static int hf_sir_contact_points = -1;
290 static int hf_sir_protocol_options_len = -1;
291 static int hf_sir_protocol_options = -1;
292 static int hf_sir_prov_url_len = -1;
293 static int hf_sir_prov_url = -1;
294 static int hf_sir_cpi_tag_len = -1;
295 static int hf_sir_cpi_tag = -1;
298 * Initialize the subtree pointers
302 static int ett_wsp = -1;
303 /* WSP headers tree */
304 static int ett_header = -1;
305 /* WSP header subtree */
306 static int ett_headers = -1;
307 static int ett_wsp_parameter_type = -1;
308 static int ett_content_type_header = -1;
309 /* CO-WSP session capabilities */
310 static int ett_capabilities = -1;
311 static int ett_capabilities_entry = -1;
312 static int ett_proto_option_capability = -1;
313 static int ett_capabilities_header_code_pages = -1;
314 static int ett_capabilities_extended_methods = -1;
315 static int ett_post = -1;
316 static int ett_redirect_flags = -1;
317 static int ett_address_flags = -1;
318 static int ett_multiparts = -1;
319 static int ett_mpartlist = -1;
320 /* Session Initiation Request tree */
321 static int ett_sir = -1;
322 static int ett_addresses = -1;
323 static int ett_address = -1;
325 static int ett_default = -1;
326 static int ett_add_content_type = -1;
327 static int ett_accept_x_q_header = -1;
328 static int ett_push_flag = -1;
329 static int ett_profile_diff_wbxml = -1;
330 static int ett_allow = -1;
331 static int ett_public = -1;
332 static int ett_vary = -1;
333 static int ett_x_wap_security = -1;
334 static int ett_connection = -1;
335 static int ett_transfer_encoding = -1;
336 static int ett_accept_ranges = -1;
337 static int ett_content_encoding = -1;
338 static int ett_accept_encoding = -1;
339 static int ett_content_disposition = -1;
340 static int ett_text_header = -1;
341 static int ett_content_id = -1;
342 static int ett_text_or_date_value = -1;
343 static int ett_date_value = -1;
344 static int ett_tod_value = -1;
345 static int ett_age = -1;
346 static int ett_integer_lookup = -1;
347 static int ett_challenge = -1;
348 static int ett_credentials_value = -1;
349 static int ett_content_md5 = -1;
350 static int ett_pragma = -1;
351 static int ett_integer_value = -1;
352 static int ett_integer_lookup_value = -1;
353 static int ett_cache_control = -1;
354 static int ett_warning = -1;
355 static int ett_profile_warning = -1;
356 static int ett_encoding_version = -1;
357 static int ett_content_range = -1;
358 static int ett_range = -1;
359 static int ett_te_value = -1;
360 static int ett_openwave_default = -1;
362 static expert_field ei_wsp_capability_invalid = EI_INIT;
363 static expert_field ei_wsp_capability_length_invalid = EI_INIT;
364 static expert_field ei_wsp_capability_encoding_invalid = EI_INIT;
365 static expert_field ei_wsp_text_field_invalid = EI_INIT;
366 static expert_field ei_wsp_header_invalid_value = EI_INIT;
367 static expert_field ei_wsp_invalid_parameter_value = EI_INIT;
368 static expert_field ei_wsp_undecoded_parameter = EI_INIT;
369 static expert_field ei_hdr_x_wap_tod = EI_INIT;
370 static expert_field ei_wsp_trailing_quote = EI_INIT;
371 static expert_field ei_wsp_header_invalid = EI_INIT;
372 static expert_field ei_wsp_oversized_uintvar = EI_INIT;
375 /* Handle for WSP-over-UDP dissector */
376 static dissector_handle_t wsp_fromudp_handle;
378 /* Handle for WTP-over-UDP dissector */
379 static dissector_handle_t wtp_fromudp_handle;
381 /* Handle for generic media dissector */
382 static dissector_handle_t media_handle;
384 /* Handle for WBXML-encoded UAPROF dissector */
385 static dissector_handle_t wbxml_uaprof_handle;
387 static const value_string wsp_vals_pdu_type[] = {
388 { 0x00, "Reserved" },
390 { 0x02, "ConnectReply" },
391 { 0x03, "Redirect" },
393 { 0x05, "Disconnect" },
395 { 0x07, "ConfirmedPush" },
399 /* 0x10 - 0x3F Unassigned */
407 /* 0x45 - 0x4F Unassigned (Get PDU) */
408 /* 0x50 - 0x5F Extended method (Get PDU) */
409 { 0x50, "Extended Get Method 0"},
410 { 0x51, "Extended Get Method 1"},
411 { 0x52, "Extended Get Method 2"},
412 { 0x53, "Extended Get Method 3"},
413 { 0x54, "Extended Get Method 4"},
414 { 0x55, "Extended Get Method 5"},
415 { 0x56, "Extended Get Method 6"},
416 { 0x57, "Extended Get Method 7"},
417 { 0x58, "Extended Get Method 8"},
418 { 0x59, "Extended Get Method 9"},
419 { 0x5A, "Extended Get Method 10"},
420 { 0x5B, "Extended Get Method 11"},
421 { 0x5C, "Extended Get Method 12"},
422 { 0x5D, "Extended Get Method 13"},
423 { 0x5E, "Extended Get Method 14"},
424 { 0x5F, "Extended Get Method 15"},
429 /* 0x62 - 0x6F Unassigned (Post PDU) */
430 /* 0x70 - 0x7F Extended method (Post PDU) */
431 { 0x70, "Extended Post Method 0"},
432 { 0x71, "Extended Post Method 1"},
433 { 0x72, "Extended Post Method 2"},
434 { 0x73, "Extended Post Method 3"},
435 { 0x74, "Extended Post Method 4"},
436 { 0x75, "Extended Post Method 5"},
437 { 0x76, "Extended Post Method 6"},
438 { 0x77, "Extended Post Method 7"},
439 { 0x78, "Extended Post Method 8"},
440 { 0x79, "Extended Post Method 9"},
441 { 0x7A, "Extended Post Method 10"},
442 { 0x7B, "Extended Post Method 11"},
443 { 0x7C, "Extended Post Method 12"},
444 { 0x7D, "Extended Post Method 13"},
445 { 0x7E, "Extended Post Method 14"},
446 { 0x7F, "Extended Post Method 15"},
448 /* 0x80 - 0xFF Reserved */
453 value_string_ext wsp_vals_pdu_type_ext = VALUE_STRING_EXT_INIT(wsp_vals_pdu_type);
455 /* The WSP status codes are inherited from the HTTP status codes */
456 static const value_string wsp_vals_status[] = {
457 /* 0x00 - 0x0F Reserved */
459 { 0x10, "100 Continue" },
460 { 0x11, "101 Switching Protocols" },
463 { 0x21, "201 Created" },
464 { 0x22, "202 Accepted" },
465 { 0x23, "203 Non-Authoritative Information" },
466 { 0x24, "204 No Content" },
467 { 0x25, "205 Reset Content" },
468 { 0x26, "206 Partial Content" },
470 { 0x30, "300 Multiple Choices" },
471 { 0x31, "301 Moved Permanently" },
472 { 0x32, "302 Moved Temporarily" },
473 { 0x33, "303 See Other" },
474 { 0x34, "304 Not Modified" },
475 { 0x35, "305 Use Proxy" },
476 { 0x37, "307 Temporary Redirect" },
478 { 0x40, "400 Bad Request" },
479 { 0x41, "401 Unauthorised" },
480 { 0x42, "402 Payment Required" },
481 { 0x43, "403 Forbidden" },
482 { 0x44, "404 Not Found" },
483 { 0x45, "405 Method Not Allowed" },
484 { 0x46, "406 Not Acceptable" },
485 { 0x47, "407 Proxy Authentication Required" },
486 { 0x48, "408 Request Timeout" },
487 { 0x49, "409 Conflict" },
488 { 0x4A, "410 Gone" },
489 { 0x4B, "411 Length Required" },
490 { 0x4C, "412 Precondition Failed" },
491 { 0x4D, "413 Request Entity Too Large" },
492 { 0x4E, "414 Request-URI Too Large" },
493 { 0x4F, "415 Unsupported Media Type" },
494 { 0x50, "416 Requested Range Not Satisfiable" },
495 { 0x51, "417 Expectation Failed" },
497 { 0x60, "500 Internal Server Error" },
498 { 0x61, "501 Not Implemented" },
499 { 0x62, "502 Bad Gateway" },
500 { 0x63, "503 Service Unavailable" },
501 { 0x64, "504 Gateway Timeout" },
502 { 0x65, "505 WSP/HTTP Version Not Supported" },
506 value_string_ext wsp_vals_status_ext = VALUE_STRING_EXT_INIT(wsp_vals_status);
508 static const value_string vals_wsp_reason_codes[] = {
509 { 0xE0, "Protocol Error (Illegal PDU)" },
510 { 0xE1, "Session disconnected" },
511 { 0xE2, "Session suspended" },
512 { 0xE3, "Session resumed" },
513 { 0xE4, "Peer congested" },
514 { 0xE5, "Session connect failed" },
515 { 0xE6, "Maximum receive unit size exceeded" },
516 { 0xE7, "Maximum outstanding requests exceeded" },
517 { 0xE8, "Peer request" },
518 { 0xE9, "Network error" },
519 { 0xEA, "User request" },
520 { 0xEB, "No specific cause, no retries" },
521 { 0xEC, "Push message cannot be delivered" },
522 { 0xED, "Push message discarded" },
523 { 0xEE, "Content type cannot be processed" },
527 value_string_ext vals_wsp_reason_codes_ext = VALUE_STRING_EXT_INIT(vals_wsp_reason_codes);
532 #define FN_ACCEPT 0x00
533 #define FN_ACCEPT_CHARSET_DEP 0x01 /* encoding version 1.1, deprecated */
534 #define FN_ACCEPT_ENCODING_DEP 0x02 /* encoding version 1.1, deprecated */
535 #define FN_ACCEPT_LANGUAGE 0x03
536 #define FN_ACCEPT_RANGES 0x04
538 #define FN_ALLOW 0x06
539 #define FN_AUTHORIZATION 0x07
540 #define FN_CACHE_CONTROL_DEP 0x08 /* encoding version 1.1, deprecated */
541 #define FN_CONNECTION 0x09
542 #define FN_CONTENT_BASE 0x0A
543 #define FN_CONTENT_ENCODING 0x0B
544 #define FN_CONTENT_LANGUAGE 0x0C
545 #define FN_CONTENT_LENGTH 0x0D
546 #define FN_CONTENT_LOCATION 0x0E
547 #define FN_CONTENT_MD5 0x0F
548 #define FN_CONTENT_RANGE_DEP 0x10 /* encoding version 1.1, deprecated */
549 #define FN_CONTENT_TYPE 0x11
552 #define FN_EXPIRES 0x14
555 #define FN_IF_MODIFIED_SINCE 0x17
556 #define FN_IF_MATCH 0x18
557 #define FN_IF_NONE_MATCH 0x19
558 #define FN_IF_RANGE 0x1A
559 #define FN_IF_UNMODIFIED_SINCE 0x1B
560 #define FN_LOCATION 0x1C
561 #define FN_LAST_MODIFIED 0x1D
562 #define FN_MAX_FORWARDS 0x1E
563 #define FN_PRAGMA 0x1F
564 #define FN_PROXY_AUTHENTICATE 0x20
565 #define FN_PROXY_AUTHORIZATION 0x21
566 #define FN_PUBLIC 0x22
567 #define FN_RANGE 0x23
568 #define FN_REFERER 0x24
569 #define FN_RETRY_AFTER 0x25
570 #define FN_SERVER 0x26
571 #define FN_TRANSFER_ENCODING 0x27
572 #define FN_UPGRADE 0x28
573 #define FN_USER_AGENT 0x29
576 #define FN_WARNING 0x2C
577 #define FN_WWW_AUTHENTICATE 0x2D
578 #define FN_CONTENT_DISPOSITION 0x2E
579 #define FN_X_WAP_APPLICATION_ID 0x2F
580 #define FN_X_WAP_CONTENT_URI 0x30
581 #define FN_X_WAP_INITIATOR_URI 0x31
582 #define FN_ACCEPT_APPLICATION 0x32
583 #define FN_BEARER_INDICATION 0x33
584 #define FN_PUSH_FLAG 0x34
585 #define FN_PROFILE 0x35
586 #define FN_PROFILE_DIFF 0x36
587 #define FN_PROFILE_WARNING 0x37
588 #define FN_EXPECT 0x38
590 #define FN_TRAILER 0x3A
591 #define FN_ACCEPT_CHARSET 0x3B /* encoding version 1.3 */
592 #define FN_ACCEPT_ENCODING 0x3C /* encoding version 1.3 */
593 #define FN_CACHE_CONTROL 0x3D /* encoding version 1.3 */
594 #define FN_CONTENT_RANGE 0x3E /* encoding version 1.3 */
595 #define FN_X_WAP_TOD 0x3F
596 #define FN_CONTENT_ID 0x40
597 #define FN_SET_COOKIE 0x41
598 #define FN_COOKIE 0x42
599 #define FN_ENCODING_VERSION 0x43
600 #define FN_PROFILE_WARNING14 0x44 /* encoding version 1.4 */
601 #define FN_CONTENT_DISPOSITION14 0x45 /* encoding version 1.4 */
602 #define FN_X_WAP_SECURITY 0x46
603 #define FN_CACHE_CONTROL14 0x47 /* encoding version 1.4 */
604 #define FN_EXPECT15 0x48 /* encoding version 1.5 */
605 #define FN_X_WAP_LOC_INVOCATION 0x49
606 #define FN_X_WAP_LOC_DELIVERY 0x4A
610 * Openwave field names.
612 #define FN_OPENWAVE_PROXY_PUSH_ADDR 0x00
613 #define FN_OPENWAVE_PROXY_PUSH_ACCEPT 0x01
614 #define FN_OPENWAVE_PROXY_PUSH_SEQ 0x02
615 #define FN_OPENWAVE_PROXY_NOTIFY 0x03
616 #define FN_OPENWAVE_PROXY_OPERATOR_DOMAIN 0x04
617 #define FN_OPENWAVE_PROXY_HOME_PAGE 0x05
618 #define FN_OPENWAVE_DEVCAP_HAS_COLOR 0x06
619 #define FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS 0x07
620 #define FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE 0x08
621 #define FN_OPENWAVE_DEVCAP_SCREEN_CHARS 0x09
622 #define FN_OPENWAVE_DEVCAP_SCREEN_PIXELS 0x0A
623 #define FN_OPENWAVE_DEVCAP_EM_SIZE 0x0B
624 #define FN_OPENWAVE_DEVCAP_SCREEN_DEPTH 0x0C
625 #define FN_OPENWAVE_DEVCAP_IMMED_ALERT 0x0D
626 #define FN_OPENWAVE_PROXY_NET_ASK 0x0E
627 #define FN_OPENWAVE_PROXY_UPLINK_VERSION 0x0F
628 #define FN_OPENWAVE_PROXY_TOD 0x10
629 #define FN_OPENWAVE_PROXY_BA_ENABLE 0x11
630 #define FN_OPENWAVE_PROXY_BA_REALM 0x12
631 #define FN_OPENWAVE_PROXY_REDIRECT_ENABLE 0x13
632 #define FN_OPENWAVE_PROXY_REQUEST_URI 0x14
633 #define FN_OPENWAVE_PROXY_REDIRECT_STATUS 0x15
634 #define FN_OPENWAVE_PROXY_TRANS_CHARSET 0x16
635 #define FN_OPENWAVE_PROXY_LINGER 0x17
636 #define FN_OPENWAVE_PROXY_CLIENT_ID 0x18
637 #define FN_OPENWAVE_PROXY_ENABLE_TRUST 0x19
638 #define FN_OPENWAVE_PROXY_TRUST_OLD 0x1A
639 #define FN_OPENWAVE_PROXY_TRUST 0x20
640 #define FN_OPENWAVE_PROXY_BOOKMARK 0x21
641 #define FN_OPENWAVE_DEVCAP_GUI 0x22
643 static const value_string vals_openwave_field_names[] = {
644 { FN_OPENWAVE_PROXY_PUSH_ADDR, "x-up-proxy-push-addr" },
645 { FN_OPENWAVE_PROXY_PUSH_ACCEPT, "x-up-proxy-push-accept" },
646 { FN_OPENWAVE_PROXY_PUSH_SEQ, "x-up-proxy-seq" },
647 { FN_OPENWAVE_PROXY_NOTIFY, "x-up-proxy-notify" },
648 { FN_OPENWAVE_PROXY_OPERATOR_DOMAIN, "x-up-proxy-operator-domain" },
649 { FN_OPENWAVE_PROXY_HOME_PAGE, "x-up-proxy-home-page" },
650 { FN_OPENWAVE_DEVCAP_HAS_COLOR, "x-up-devcap-has-color" },
651 { FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS, "x-up-devcap-num-softkeys" },
652 { FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE, "x-up-devcap-softkey-size" },
653 { FN_OPENWAVE_DEVCAP_SCREEN_CHARS, "x-up-devcap-screen-chars" },
654 { FN_OPENWAVE_DEVCAP_SCREEN_PIXELS, "x-up-devcap-screen-pixels" },
655 { FN_OPENWAVE_DEVCAP_EM_SIZE, "x-up-devcap-em-size" },
656 { FN_OPENWAVE_DEVCAP_SCREEN_DEPTH, "x-up-devcap-screen-depth" },
657 { FN_OPENWAVE_DEVCAP_IMMED_ALERT, "x-up-devcap-immed-alert" },
658 { FN_OPENWAVE_PROXY_NET_ASK, "x-up-proxy-net-ask" },
659 { FN_OPENWAVE_PROXY_UPLINK_VERSION, "x-up-proxy-uplink-version" },
660 { FN_OPENWAVE_PROXY_TOD, "x-up-proxy-tod" },
661 { FN_OPENWAVE_PROXY_BA_ENABLE, "x-up-proxy-ba-enable" },
662 { FN_OPENWAVE_PROXY_BA_REALM, "x-up-proxy-ba-realm" },
663 { FN_OPENWAVE_PROXY_REDIRECT_ENABLE, "x-up-proxy-redirect-enable" },
664 { FN_OPENWAVE_PROXY_REQUEST_URI, "x-up-proxy-request-uri" },
665 { FN_OPENWAVE_PROXY_REDIRECT_STATUS, "x-up-proxy-redirect-status" },
666 { FN_OPENWAVE_PROXY_TRANS_CHARSET, "x-up-proxy-trans-charset" },
667 { FN_OPENWAVE_PROXY_LINGER, "x-up-proxy-linger" },
668 { FN_OPENWAVE_PROXY_CLIENT_ID, "x-up-proxy-client-id" },
669 { FN_OPENWAVE_PROXY_ENABLE_TRUST, "x-up-proxy-enable-trust" },
670 { FN_OPENWAVE_PROXY_TRUST_OLD, "x-up-proxy-trust-old" },
671 { FN_OPENWAVE_PROXY_TRUST, "x-up-proxy-trust" },
672 { FN_OPENWAVE_PROXY_BOOKMARK, "x-up-proxy-bookmark" },
673 { FN_OPENWAVE_DEVCAP_GUI, "x-up-devcap-gui" },
676 static value_string_ext vals_openwave_field_names_ext = VALUE_STRING_EXT_INIT(vals_openwave_field_names);
678 static const value_string vals_field_names[] = {
679 { FN_ACCEPT, "Accept" },
680 { FN_ACCEPT_CHARSET_DEP, "Accept-Charset (encoding 1.1)" },
681 { FN_ACCEPT_ENCODING_DEP, "Accept-Encoding (encoding 1.1)" },
682 { FN_ACCEPT_LANGUAGE, "Accept-Language" },
683 { FN_ACCEPT_RANGES, "Accept-Ranges" },
685 { FN_ALLOW, "Allow" },
686 { FN_AUTHORIZATION, "Authorization" },
687 { FN_CACHE_CONTROL_DEP, "Cache-Control (encoding 1.1)" },
688 { FN_CONNECTION, "Connection" },
689 { FN_CONTENT_BASE, "Content-Base" },
690 { FN_CONTENT_ENCODING, "Content-Encoding" },
691 { FN_CONTENT_LANGUAGE, "Content-Language" },
692 { FN_CONTENT_LENGTH, "Content-Length" },
693 { FN_CONTENT_LOCATION, "Content-Location" },
694 { FN_CONTENT_MD5, "Content-MD5" },
695 { FN_CONTENT_RANGE_DEP, "Content-Range (encoding 1.1)" },
696 { FN_CONTENT_TYPE, "Content-Type" },
699 { FN_EXPIRES, "Expires" },
702 { FN_IF_MODIFIED_SINCE, "If-Modified-Since" },
703 { FN_IF_MATCH, "If-Match" },
704 { FN_IF_NONE_MATCH, "If-None-Match" },
705 { FN_IF_RANGE, "If-Range" },
706 { FN_IF_UNMODIFIED_SINCE, "If-Unmodified-Since" },
707 { FN_LOCATION, "Location" },
708 { FN_LAST_MODIFIED, "Last-Modified" },
709 { FN_MAX_FORWARDS, "Max-Forwards" },
710 { FN_PRAGMA, "Pragma" },
711 { FN_PROXY_AUTHENTICATE, "Proxy-Authenticate" },
712 { FN_PROXY_AUTHORIZATION, "Proxy-Authorization" },
713 { FN_PUBLIC, "Public" },
714 { FN_RANGE, "Range" },
715 { FN_REFERER, "Referer" },
716 { FN_RETRY_AFTER, "Retry-After" },
717 { FN_SERVER, "Server" },
718 { FN_TRANSFER_ENCODING, "Transfer-Encoding" },
719 { FN_UPGRADE, "Upgrade" },
720 { FN_USER_AGENT, "User-Agent" },
723 { FN_WARNING, "Warning" },
724 { FN_WWW_AUTHENTICATE, "WWW-Authenticate" },
725 { FN_CONTENT_DISPOSITION, "Content-Disposition" },
726 { FN_X_WAP_APPLICATION_ID, "X-Wap-Application-ID" },
727 { FN_X_WAP_CONTENT_URI, "X-Wap-Content-URI" },
728 { FN_X_WAP_INITIATOR_URI, "X-Wap-Initiator-URI" },
729 { FN_ACCEPT_APPLICATION, "Accept-Application" },
730 { FN_BEARER_INDICATION, "Bearer-Indication" },
731 { FN_PUSH_FLAG, "Push-Flag" },
732 { FN_PROFILE, "Profile" },
733 { FN_PROFILE_DIFF, "Profile-Diff" },
734 { FN_PROFILE_WARNING, "Profile-Warning" },
735 { FN_EXPECT, "Expect" },
737 { FN_TRAILER, "Trailer" },
738 { FN_ACCEPT_CHARSET, "Accept-Charset" },
739 { FN_ACCEPT_ENCODING, "Accept-Encoding" },
740 { FN_CACHE_CONTROL, "Cache-Control" },
741 { FN_CONTENT_RANGE, "Content-Range" },
742 { FN_X_WAP_TOD, "X-Wap-Tod" },
743 { FN_CONTENT_ID, "Content-ID" },
744 { FN_SET_COOKIE, "Set-Cookie" },
745 { FN_COOKIE, "Cookie" },
746 { FN_ENCODING_VERSION, "Encoding-Version" },
747 { FN_PROFILE_WARNING14, "Profile-Warning (encoding 1.4)" },
748 { FN_CONTENT_DISPOSITION14,"Content-Disposition (encoding 1.4)" },
749 { FN_X_WAP_SECURITY, "X-WAP-Security" },
750 { FN_CACHE_CONTROL14, "Cache-Control (encoding 1.4)" },
751 /* encoding-version 1.5 */
752 { FN_EXPECT15, "Expect (encoding 1.5)" },
753 { FN_X_WAP_LOC_INVOCATION, "X-Wap-Loc-Invocation" },
754 { FN_X_WAP_LOC_DELIVERY, "X-Wap-Loc-Delivery" },
757 static value_string_ext vals_field_names_ext = VALUE_STRING_EXT_INIT(vals_field_names);
760 * Bearer types (from the WDP specification).
764 #define BT_GSM_USSD 0x02
765 #define BT_GSM_SMS 0x03
766 #define BT_ANSI_136_GUTS 0x04
767 #define BT_IS_95_SMS 0x05
768 #define BT_IS_95_CSD 0x06
769 #define BT_IS_95_PACKET_DATA 0x07
770 #define BT_ANSI_136_CSD 0x08
771 #define BT_ANSI_136_PACKET_DATA 0x09
772 #define BT_GSM_CSD 0x0A
773 #define BT_GSM_GPRS 0x0B
774 #define BT_GSM_USSD_IPv4 0x0C
775 #define BT_AMPS_CDPD 0x0D
776 #define BT_PDC_CSD 0x0E
777 #define BT_PDC_PACKET_DATA 0x0F
778 #define BT_IDEN_SMS 0x10
779 #define BT_IDEN_CSD 0x11
780 #define BT_IDEN_PACKET_DATA 0x12
781 #define BT_PAGING_FLEX 0x13
782 #define BT_PHS_SMS 0x14
783 #define BT_PHS_CSD 0x15
784 #define BT_GSM_USSD_GSM_SC 0x16
785 #define BT_TETRA_SDS_ITSI 0x17
786 #define BT_TETRA_SDS_MSISDN 0x18
787 #define BT_TETRA_PACKET_DATA 0x19
788 #define BT_PAGING_REFLEX 0x1A
789 #define BT_GSM_USSD_MSISDN 0x1B
790 #define BT_MOBITEX_MPAK 0x1C
791 #define BT_ANSI_136_GHOST 0x1D
793 static const value_string vals_bearer_types[] = {
796 { BT_GSM_USSD, "GSM USSD" },
797 { BT_GSM_SMS, "GSM SMS" },
798 { BT_ANSI_136_GUTS, "ANSI-136 GUTS/R-Data" },
799 { BT_IS_95_SMS, "IS-95 CDMA SMS" },
800 { BT_IS_95_CSD, "IS-95 CDMA CSD" },
801 { BT_IS_95_PACKET_DATA, "IS-95 CDMA Packet data" },
802 { BT_ANSI_136_CSD, "ANSI-136 CSD" },
803 { BT_ANSI_136_PACKET_DATA, "ANSI-136 Packet data" },
804 { BT_GSM_CSD, "GSM CSD" },
805 { BT_GSM_GPRS, "GSM GPRS" },
806 { BT_GSM_USSD_IPv4, "GSM USSD (IPv4 addresses)" },
807 { BT_AMPS_CDPD, "AMPS CDPD" },
808 { BT_PDC_CSD, "PDC CSD" },
809 { BT_PDC_PACKET_DATA, "PDC Packet data" },
810 { BT_IDEN_SMS, "IDEN SMS" },
811 { BT_IDEN_CSD, "IDEN CSD" },
812 { BT_IDEN_PACKET_DATA, "IDEN Packet data" },
813 { BT_PAGING_FLEX, "Paging network FLEX(TM)" },
814 { BT_PHS_SMS, "PHS SMS" },
815 { BT_PHS_CSD, "PHS CSD" },
816 { BT_GSM_USSD_GSM_SC, "GSM USSD (GSM Service Code addresses)" },
817 { BT_TETRA_SDS_ITSI, "TETRA SDS (ITSI addresses)" },
818 { BT_TETRA_SDS_MSISDN, "TETRA SDS (MSISDN addresses)" },
819 { BT_TETRA_PACKET_DATA, "TETRA Packet data" },
820 { BT_PAGING_REFLEX, "Paging network ReFLEX(TM)" },
821 { BT_GSM_USSD_MSISDN, "GSM USSD (MSISDN addresses)" },
822 { BT_MOBITEX_MPAK, "Mobitex MPAK" },
823 { BT_ANSI_136_GHOST, "ANSI-136 GHOST/R-Data" },
826 static value_string_ext vals_bearer_types_ext = VALUE_STRING_EXT_INIT(vals_bearer_types);
828 static const value_string vals_content_types[] = {
829 /* Well-known media types */
830 /* XXX: hack: "..." "..." used to define several strings so that checkAPIs & etc won't see a 'start of comment' */
831 { 0x00, "*" "/" "*" },
832 { 0x01, "text/" "*" },
833 { 0x02, "text/html" },
834 { 0x03, "text/plain" },
835 { 0x04, "text/x-hdml" },
836 { 0x05, "text/x-ttml" },
837 { 0x06, "text/x-vCalendar" },
838 { 0x07, "text/x-vCard" },
839 { 0x08, "text/vnd.wap.wml" },
840 { 0x09, "text/vnd.wap.wmlscript" },
841 { 0x0A, "text/vnd.wap.channel" },
842 { 0x0B, "multipart/" "*" },
843 { 0x0C, "multipart/mixed" },
844 { 0x0D, "multipart/form-data" },
845 { 0x0E, "multipart/byteranges" },
846 { 0x0F, "multipart/alternative" },
847 { 0x10, "application/" "*" },
848 { 0x11, "application/java-vm" },
849 { 0x12, "application/x-www-form-urlencoded" },
850 { 0x13, "application/x-hdmlc" },
851 { 0x14, "application/vnd.wap.wmlc" },
852 { 0x15, "application/vnd.wap.wmlscriptc" },
853 { 0x16, "application/vnd.wap.channelc" },
854 { 0x17, "application/vnd.wap.uaprof" },
855 { 0x18, "application/vnd.wap.wtls-ca-certificate" },
856 { 0x19, "application/vnd.wap.wtls-user-certificate" },
857 { 0x1A, "application/x-x509-ca-cert" },
858 { 0x1B, "application/x-x509-user-cert" },
859 { 0x1C, "image/" "*" },
860 { 0x1D, "image/gif" },
861 { 0x1E, "image/jpeg" },
862 { 0x1F, "image/tiff" },
863 { 0x20, "image/png" },
864 { 0x21, "image/vnd.wap.wbmp" },
865 { 0x22, "application/vnd.wap.multipart.*" },
866 { 0x23, "application/vnd.wap.multipart.mixed" },
867 { 0x24, "application/vnd.wap.multipart.form-data" },
868 { 0x25, "application/vnd.wap.multipart.byteranges" },
869 { 0x26, "application/vnd.wap.multipart.alternative" },
870 { 0x27, "application/xml" },
871 { 0x28, "text/xml" },
872 { 0x29, "application/vnd.wap.wbxml" },
873 { 0x2A, "application/x-x968-cross-cert" },
874 { 0x2B, "application/x-x968-ca-cert" },
875 { 0x2C, "application/x-x968-user-cert" },
876 { 0x2D, "text/vnd.wap.si" },
877 { 0x2E, "application/vnd.wap.sic" },
878 { 0x2F, "text/vnd.wap.sl" },
879 { 0x30, "application/vnd.wap.slc" },
880 { 0x31, "text/vnd.wap.co" },
881 { 0x32, "application/vnd.wap.coc" },
882 { 0x33, "application/vnd.wap.multipart.related" },
883 { 0x34, "application/vnd.wap.sia" },
884 { 0x35, "text/vnd.wap.connectivity-xml" },
885 { 0x36, "application/vnd.wap.connectivity-wbxml" },
886 { 0x37, "application/pkcs7-mime" },
887 { 0x38, "application/vnd.wap.hashed-certificate" },
888 { 0x39, "application/vnd.wap.signed-certificate" },
889 { 0x3A, "application/vnd.wap.cert-response" },
890 { 0x3B, "application/xhtml+xml" },
891 { 0x3C, "application/wml+xml" },
892 { 0x3D, "text/css" },
893 { 0x3E, "application/vnd.wap.mms-message" },
894 { 0x3F, "application/vnd.wap.rollover-certificate" },
895 { 0x40, "application/vnd.wap.locc+wbxml"},
896 { 0x41, "application/vnd.wap.loc+xml"},
897 { 0x42, "application/vnd.syncml.dm+wbxml"},
898 { 0x43, "application/vnd.syncml.dm+xml"},
899 { 0x44, "application/vnd.syncml.notification"},
900 { 0x45, "application/vnd.wap.xhtml+xml"},
901 { 0x46, "application/vnd.wv.csp.cir"},
902 { 0x47, "application/vnd.oma.dd+xml"},
903 { 0x48, "application/vnd.oma.drm.message"},
904 { 0x49, "application/vnd.oma.drm.content"},
905 { 0x4A, "application/vnd.oma.drm.rights+xml"},
906 { 0x4B, "application/vnd.oma.drm.rights+wbxml"},
907 { 0x4C, "application/vnd.wv.csp+xml"},
908 { 0x4D, "application/vnd.wv.csp+wbxml"},
909 /* The following media types are registered by 3rd parties */
910 { 0x0201, "application/vnd.uplanet.cachop-wbxml" },
911 { 0x0202, "application/vnd.uplanet.signal" },
912 { 0x0203, "application/vnd.uplanet.alert-wbxml" },
913 { 0x0204, "application/vnd.uplanet.list-wbxml" },
914 { 0x0205, "application/vnd.uplanet.listcmd-wbxml" },
915 { 0x0206, "application/vnd.uplanet.channel-wbxml" },
916 { 0x0207, "application/vnd.uplanet.provisioning-status-uri" },
917 { 0x0208, "x-wap.multipart/vnd.uplanet.header-set" },
918 { 0x0209, "application/vnd.uplanet.bearer-choice-wbxml" },
919 { 0x020A, "application/vnd.phonecom.mmc-wbxml" },
920 { 0x020B, "application/vnd.nokia.syncset+wbxml" },
921 { 0x020C, "image/x-up-wpng"},
922 { 0x0300, "application/iota.mmc-wbxml"},
923 { 0x0301, "application/iota.mmc-xml"},
926 static value_string_ext vals_content_types_ext = VALUE_STRING_EXT_INIT(vals_content_types);
928 static const value_string vals_languages[] = {
930 { 0x01, "Afar (aa)" },
931 { 0x02, "Abkhazian (ab)" },
932 { 0x03, "Afrikaans (af)" },
933 { 0x04, "Amharic (am)" },
934 { 0x05, "Arabic (ar)" },
935 { 0x06, "Assamese (as)" },
936 { 0x07, "Aymara (ay)" },
937 { 0x08, "Azerbaijani (az)" },
938 { 0x09, "Bashkir (ba)" },
939 { 0x0A, "Byelorussian (be)" },
940 { 0x0B, "Bulgarian (bg)" },
941 { 0x0C, "Bihari (bh)" },
942 { 0x0D, "Bislama (bi)" },
943 { 0x0E, "Bengali; Bangla (bn)" },
944 { 0x0F, "Tibetan (bo)" },
945 { 0x10, "Breton (br)" },
946 { 0x11, "Catalan (ca)" },
947 { 0x12, "Corsican (co)" },
948 { 0x13, "Czech (cs)" },
949 { 0x14, "Welsh (cy)" },
950 { 0x15, "Danish (da)" },
951 { 0x16, "German (de)" },
952 { 0x17, "Bhutani (dz)" },
953 { 0x18, "Greek (el)" },
954 { 0x19, "English (en)" },
955 { 0x1A, "Esperanto (eo)" },
956 { 0x1B, "Spanish (es)" },
957 { 0x1C, "Estonian (et)" },
958 { 0x1D, "Basque (eu)" },
959 { 0x1E, "Persian (fa)" },
960 { 0x1F, "Finnish (fi)" },
961 { 0x20, "Fiji (fj)" },
962 { 0x21, "Urdu (ur)" },
963 { 0x22, "French (fr)" },
964 { 0x23, "Uzbek (uz)" },
965 { 0x24, "Irish (ga)" },
966 { 0x25, "Scots Gaelic (gd)" },
967 { 0x26, "Galician (gl)" },
968 { 0x27, "Guarani (gn)" },
969 { 0x28, "Gujarati (gu)" },
970 { 0x29, "Hausa (ha)" },
971 { 0x2A, "Hebrew (formerly iw) (he)" },
972 { 0x2B, "Hindi (hi)" },
973 { 0x2C, "Croatian (hr)" },
974 { 0x2D, "Hungarian (hu)" },
975 { 0x2E, "Armenian (hy)" },
976 { 0x2F, "Vietnamese (vi)" },
977 { 0x30, "Indonesian (formerly in) (id)" },
978 { 0x31, "Wolof (wo)" },
979 { 0x32, "Xhosa (xh)" },
980 { 0x33, "Icelandic (is)" },
981 { 0x34, "Italian (it)" },
982 { 0x35, "Yoruba (yo)" },
983 { 0x36, "Japanese (ja)" },
984 { 0x37, "Javanese (jw)" },
985 { 0x38, "Georgian (ka)" },
986 { 0x39, "Kazakh (kk)" },
987 { 0x3A, "Zhuang (za)" },
988 { 0x3B, "Cambodian (km)" },
989 { 0x3C, "Kannada (kn)" },
990 { 0x3D, "Korean (ko)" },
991 { 0x3E, "Kashmiri (ks)" },
992 { 0x3F, "Kurdish (ku)" },
993 { 0x40, "Kirghiz (ky)" },
994 { 0x41, "Chinese (zh)" },
995 { 0x42, "Lingala (ln)" },
996 { 0x43, "Laothian (lo)" },
997 { 0x44, "Lithuanian (lt)" },
998 { 0x45, "Latvian, Lettish (lv)" },
999 { 0x46, "Malagasy (mg)" },
1000 { 0x47, "Maori (mi)" },
1001 { 0x48, "Macedonian (mk)" },
1002 { 0x49, "Malayalam (ml)" },
1003 { 0x4A, "Mongolian (mn)" },
1004 { 0x4B, "Moldavian (mo)" },
1005 { 0x4C, "Marathi (mr)" },
1006 { 0x4D, "Malay (ms)" },
1007 { 0x4E, "Maltese (mt)" },
1008 { 0x4F, "Burmese (my)" },
1009 { 0x50, "Ukrainian (uk)" },
1010 { 0x51, "Nepali (ne)" },
1011 { 0x52, "Dutch (nl)" },
1012 { 0x53, "Norwegian (no)" },
1013 { 0x54, "Occitan (oc)" },
1014 { 0x55, "(Afan) Oromo (om)" },
1015 { 0x56, "Oriya (or)" },
1016 { 0x57, "Punjabi (pa)" },
1017 { 0x58, "Polish (po)" },
1018 { 0x59, "Pashto, Pushto (ps)" },
1019 { 0x5A, "Portuguese (pt)" },
1020 { 0x5B, "Quechua (qu)" },
1021 { 0x5C, "Zulu (zu)" },
1022 { 0x5D, "Kirundi (rn)" },
1023 { 0x5E, "Romanian (ro)" },
1024 { 0x5F, "Russian (ru)" },
1025 { 0x60, "Kinyarwanda (rw)" },
1026 { 0x61, "Sanskrit (sa)" },
1027 { 0x62, "Sindhi (sd)" },
1028 { 0x63, "Sangho (sg)" },
1029 { 0x64, "Serbo-Croatian (sh)" },
1030 { 0x65, "Sinhalese (si)" },
1031 { 0x66, "Slovak (sk)" },
1032 { 0x67, "Slovenian (sl)" },
1033 { 0x68, "Samoan (sm)" },
1034 { 0x69, "Shona (sn)" },
1035 { 0x6A, "Somali (so)" },
1036 { 0x6B, "Albanian (sq)" },
1037 { 0x6C, "Serbian (sr)" },
1038 { 0x6D, "Siswati (ss)" },
1039 { 0x6E, "Sesotho (st)" },
1040 { 0x6F, "Sundanese (su)" },
1041 { 0x70, "Swedish (sv)" },
1042 { 0x71, "Swahili (sw)" },
1043 { 0x72, "Tamil (ta)" },
1044 { 0x73, "Telugu (te)" },
1045 { 0x74, "Tajik (tg)" },
1046 { 0x75, "Thai (th)" },
1047 { 0x76, "Tigrinya (ti)" },
1048 { 0x77, "Turkmen (tk)" },
1049 { 0x78, "Tagalog (tl)" },
1050 { 0x79, "Setswana (tn)" },
1051 { 0x7A, "Tonga (to)" },
1052 { 0x7B, "Turkish (tr)" },
1053 { 0x7C, "Tsonga (ts)" },
1054 { 0x7D, "Tatar (tt)" },
1055 { 0x7E, "Twi (tw)" },
1056 { 0x7F, "Uighur (ug)" },
1057 { 0x81, "Nauru (na)" },
1058 { 0x82, "Faeroese (fo)" },
1059 { 0x83, "Frisian (fy)" },
1060 { 0x84, "Interlingua (ia)" },
1061 { 0x85, "Volapuk (vo)" },
1062 { 0x86, "Interlingue (ie)" },
1063 { 0x87, "Inupiak (ik)" },
1064 { 0x88, "Yiddish (formerly ji) (yi)" },
1065 { 0x89, "Inuktitut (iu)" },
1066 { 0x8A, "Greenlandic (kl)" },
1067 { 0x8B, "Latin (la)" },
1068 { 0x8C, "Rhaeto-Romance (rm)" },
1071 static value_string_ext vals_languages_ext = VALUE_STRING_EXT_INIT(vals_languages);
1074 #define CACHE_CONTROL_NO_CACHE 0x00
1075 #define CACHE_CONTROL_NO_STORE 0x01
1076 #define CACHE_CONTROL_MAX_AGE 0x02
1077 #define CACHE_CONTROL_MAX_STALE 0x03
1078 #define CACHE_CONTROL_MIN_FRESH 0x04
1079 #define CACHE_CONTROL_ONLY_IF_CACHED 0x05
1080 #define CACHE_CONTROL_PUBLIC 0x06
1081 #define CACHE_CONTROL_PRIVATE 0x07
1082 #define CACHE_CONTROL_NO_TRANSFORM 0x08
1083 #define CACHE_CONTROL_MUST_REVALIDATE 0x09
1084 #define CACHE_CONTROL_PROXY_REVALIDATE 0x0A
1085 #define CACHE_CONTROL_S_MAXAGE 0x0B
1087 static const value_string vals_cache_control[] = {
1088 { CACHE_CONTROL_NO_CACHE, "no-cache" },
1089 { CACHE_CONTROL_NO_STORE, "no-store" },
1090 { CACHE_CONTROL_MAX_AGE, "max-age" },
1091 { CACHE_CONTROL_MAX_STALE, "max-stale" },
1092 { CACHE_CONTROL_MIN_FRESH, "min-fresh" },
1093 { CACHE_CONTROL_ONLY_IF_CACHED, "only-if-cached" },
1094 { CACHE_CONTROL_PUBLIC, "public" },
1095 { CACHE_CONTROL_PRIVATE, "private" },
1096 { CACHE_CONTROL_NO_TRANSFORM, "no-transform" },
1097 { CACHE_CONTROL_MUST_REVALIDATE, "must-revalidate" },
1098 { CACHE_CONTROL_PROXY_REVALIDATE, "proxy-revalidate" },
1099 { CACHE_CONTROL_S_MAXAGE, "s-max-age" },
1103 static value_string_ext vals_cache_control_ext = VALUE_STRING_EXT_INIT(vals_cache_control);
1105 static const value_string vals_wap_application_ids[] = {
1106 /* Well-known WAP applications */
1107 { 0x0000, "x-wap-application:*"},
1108 { 0x0001, "x-wap-application:push.sia"},
1109 { 0x0002, "x-wap-application:wml.ua"},
1110 { 0x0003, "x-wap-application:wta.ua"},
1111 { 0x0004, "x-wap-application:mms.ua"},
1112 { 0x0005, "x-wap-application:push.syncml"},
1113 { 0x0006, "x-wap-application:loc.ua"},
1114 { 0x0007, "x-wap-application:syncml.dm"},
1115 { 0x0008, "x-wap-application:drm.ua"},
1116 { 0x0009, "x-wap-application:emn.ua"},
1117 { 0x000A, "x-wap-application:wv.ua"},
1118 /* Registered by 3rd parties */
1119 { 0x8000, "x-wap-microsoft:localcontent.ua"},
1120 { 0x8001, "x-wap-microsoft:IMclient.ua"},
1121 { 0x8002, "x-wap-docomo:imode.mail.ua"},
1122 { 0x8003, "x-wap-docomo:imode.mr.ua"},
1123 { 0x8004, "x-wap-docomo:imode.mf.ua"},
1124 { 0x8005, "x-motorola:location.ua"},
1125 { 0x8006, "x-motorola:now.ua"},
1126 { 0x8007, "x-motorola:otaprov.ua"},
1127 { 0x8008, "x-motorola:browser.ua"},
1128 { 0x8009, "x-motorola:splash.ua"},
1129 /* 0x800A: unassigned */
1130 { 0x800B, "x-wap-nai:mvsw.command"},
1131 /* 0x800C -- 0x800F: unassigned */
1132 { 0x8010, "x-wap-openwave:iota.ua"},
1133 /* 0x8011 -- 0x8FFF: unassigned */
1134 { 0x9000, "x-wap-docomo:imode.mail2.ua"},
1135 { 0x9001, "x-oma-nec:otaprov.ua"},
1136 { 0x9002, "x-oma-nokia:call.ua"},
1137 { 0x9003, "x-oma-coremobility:sqa.ua"},
1141 static value_string_ext vals_wap_application_ids_ext = VALUE_STRING_EXT_INIT(vals_wap_application_ids);
1144 /* Parameters and well-known encodings */
1145 static const value_string vals_wsp_parameter_sec[] = {
1146 { 0x00, "NETWPIN" },
1147 { 0x01, "USERPIN" },
1148 { 0x02, "USERNETWPIN" },
1149 { 0x03, "USERPINMAC" },
1153 static value_string_ext vals_wsp_parameter_sec_ext = VALUE_STRING_EXT_INIT(vals_wsp_parameter_sec);
1155 /* Warning codes and mappings */
1156 static const value_string vals_wsp_warning_code[] = {
1157 { 10, "110 Response is stale" },
1158 { 11, "111 Revalidation failed" },
1159 { 12, "112 Disconnected operation" },
1160 { 13, "113 Heuristic expiration" },
1161 { 14, "214 Transformation applied" },
1162 { 99, "199/299 Miscellaneous warning" },
1166 static value_string_ext vals_wsp_warning_code_ext = VALUE_STRING_EXT_INIT(vals_wsp_warning_code);
1168 static const value_string vals_wsp_warning_code_short[] = {
1178 static value_string_ext vals_wsp_warning_code_short_ext = VALUE_STRING_EXT_INIT(vals_wsp_warning_code_short);
1180 /* Profile-Warning codes - see http://www.w3.org/TR/NOTE-CCPPexchange */
1181 static const value_string vals_wsp_profile_warning_code[] = {
1183 { 0x11, "101 Used stale profile" },
1184 { 0x12, "102 Not used profile" },
1185 { 0x20, "200 Not applied" },
1186 { 0x21, "101 Content selection applied" },
1187 { 0x22, "202 Content generation applied" },
1188 { 0x23, "203 Transformation applied" },
1192 static value_string_ext vals_wsp_profile_warning_code_ext = VALUE_STRING_EXT_INIT(vals_wsp_profile_warning_code);
1194 /* Well-known TE values */
1195 static const value_string vals_well_known_te[] = {
1196 { 0x82, "chunked" },
1197 { 0x83, "identity" },
1199 { 0x85, "compress" },
1200 { 0x86, "deflate" },
1204 static value_string_ext vals_well_known_te_ext = VALUE_STRING_EXT_INIT(vals_well_known_te);
1210 #define PERMANENT_REDIRECT 0x80
1211 #define REUSE_SECURITY_SESSION 0x40
1214 * Redirect address flags and length.
1216 #define BEARER_TYPE_INCLUDED 0x80
1217 #define PORT_NUMBER_INCLUDED 0x40
1218 #define ADDRESS_LEN 0x3f
1220 static const value_string vals_false_true[] = {
1227 WSP_PDU_RESERVED = 0x00,
1228 WSP_PDU_CONNECT = 0x01,
1229 WSP_PDU_CONNECTREPLY = 0x02,
1230 WSP_PDU_REDIRECT = 0x03, /* No sample data */
1231 WSP_PDU_REPLY = 0x04,
1232 WSP_PDU_DISCONNECT = 0x05,
1233 WSP_PDU_PUSH = 0x06, /* No sample data */
1234 WSP_PDU_CONFIRMEDPUSH = 0x07, /* No sample data */
1235 WSP_PDU_SUSPEND = 0x08, /* No sample data */
1236 WSP_PDU_RESUME = 0x09, /* No sample data */
1239 WSP_PDU_OPTIONS = 0x41, /* No sample data */
1240 WSP_PDU_HEAD = 0x42, /* No sample data */
1241 WSP_PDU_DELETE = 0x43, /* No sample data */
1242 WSP_PDU_TRACE = 0x44, /* No sample data */
1244 WSP_PDU_POST = 0x60,
1245 WSP_PDU_PUT = 0x61 /* No sample data */
1249 /* Dissector tables for handoff */
1250 static dissector_table_t media_type_table;
1251 static heur_dissector_list_t heur_subdissector_list;
1253 static void add_uri (proto_tree *, packet_info *, tvbuff_t *, guint, guint, proto_item *);
1255 static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
1256 static void add_multipart_data (proto_tree *, tvbuff_t *, packet_info *pinfo);
1258 static void add_capabilities (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint8 pdu_type);
1262 * Dissect the WSP header part.
1263 * This function calls wkh_XXX functions that dissect well-known headers.
1265 static void add_headers (proto_tree *tree, tvbuff_t *tvb, int hf, packet_info *pinfo);
1267 /* The following macros define WSP basic data structures as found
1268 * in the ABNF notation of WSP headers.
1269 * Currently all text data types are mapped to text_string.
1271 #define is_short_integer(x) ( (x) & 0x80 )
1272 #define is_long_integer(x) ( (x) <= 30 )
1273 #define is_date_value(x) is_long_integer(x)
1274 #define is_integer_value(x) (is_short_integer(x) || is_long_integer(x))
1275 #define is_delta_seconds_value(x) is_integer_value(x)
1276 /* Text string == *TEXT 0x00, thus also an empty string matches the rule! */
1277 #define is_text_string(x) ( ((x) == 0) || ( ((x) >= 32) && ((x) <= 127)) )
1278 #define is_quoted_string(x) ( (x) == 0x22 ) /* " */
1279 #define is_token_text(x) is_text_string(x)
1280 #define is_text_value(x) is_text_string(x)
1281 #define is_uri_value(x) is_text_string(x)
1283 #define get_uintvar_integer(val,tvb,start,len,ok) \
1284 val = tvb_get_guintvar(tvb,start,&len, pinfo, &ei_wsp_oversized_uintvar); \
1285 if (len>5) ok = FALSE; else ok = TRUE;
1286 #define get_short_integer(val,tvb,start,len,ok) \
1287 val = tvb_get_guint8(tvb,start); \
1288 if (val & 0x80) ok = TRUE; else ok=FALSE; \
1289 val &= 0x7F; len = 1;
1290 #define get_long_integer(val,tvb,start,len,ok) \
1291 len = tvb_get_guint8(tvb,start); \
1292 ok = TRUE; /* Valid lengths for us are 1-4 */ \
1293 if (len==1) { val = tvb_get_guint8(tvb,start+1); } \
1294 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \
1295 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \
1296 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \
1298 len++; /* Add the 1st octet to the length */
1299 #define get_integer_value(val,tvb,start,len,ok) \
1300 len = tvb_get_guint8(tvb,start); \
1302 if (len & 0x80) { val = len & 0x7F; len = 0; } \
1303 else if (len==1) { val = tvb_get_guint8(tvb,start+1); } \
1304 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \
1305 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \
1306 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \
1308 len++; /* Add the 1st octet to the length */
1309 #define get_date_value(val,tvb,start,len,ok) \
1310 get_long_integer(val,tvb,start,len,ok)
1311 #define get_delta_seconds_value(val,tvb,start,len,ok) \
1312 get_integer_value(val,tvb,start,len,ok)
1314 /* NOTE - Do NOT call g_free() for the str returned after using it because the
1315 * get_text_string() macro now returns wmem_alloc'd memory. */
1316 #define get_text_string(str,tvb,start,len,ok) \
1317 if (is_text_string(tvb_get_guint8(tvb,start))) { \
1318 str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb,start,(gint *)&len,ENC_ASCII); \
1320 } else { len = 0; str = NULL; ok = FALSE; }
1321 #define get_token_text(str,tvb,start,len,ok) \
1322 get_text_string(str,tvb,start,len,ok)
1323 #define get_extension_media(str,tvb,start,len,ok) \
1324 get_text_string(str,tvb,start,len,ok)
1325 #define get_text_value(str,tvb,start,len,ok) \
1326 get_text_string(str,tvb,start,len,ok)
1327 #define get_quoted_string(str,tvb,start,len,ok) \
1328 get_text_string(str,tvb,start,len,ok)
1329 #define get_uri_value(str,tvb,start,len,ok) \
1330 get_text_string(str,tvb,start,len,ok)
1332 #define get_version_value(val,str,tvb,start,len,ok) \
1333 val = tvb_get_guint8(tvb,start); \
1335 if (val & 0x80) { /* High nibble "." Low nibble */ \
1338 str = wmem_strdup_printf(wmem_packet_scope(), "%u.%u", val >> 4, val & 0x0F); \
1339 } else { get_text_string(str,tvb,start,len,ok); }
1341 /* Parameter parser */
1343 parameter (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start, int len);
1345 parameter_value_q (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start);
1347 /* The following macros hide common processing for all well-known headers
1348 * and shortens the code to be written in a wkh_XXX() function.
1349 * Even declarations are hidden by a macro.
1351 * Define a wkh_XXX() function as follows:
1354 * wkh_XXX (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
1356 * wkh_0_Declarations;
1357 * << add other required declarations here >>
1359 * wkh_1_WellKnownValue;
1360 * << add well-known value proto item here; don't forget to set the
1361 * ok variable to TRUE if parsing was correct >>
1362 * wkh_2_TextualValue;
1363 * << add textual value proto item here; don't forget to set the
1364 * ok variable to TRUE if parsing was correct >>
1365 * wkh_3_ValueWithLength;
1366 * << add custom code for value processing and value proto item here >>
1369 * << This macro takes care of parse errors within the header value;
1370 * it requires the header field index if the header has not yet been
1371 * written to the protocol tree (ti == NULL). >>
1374 * NOTE: You only need to write parsing code for the successful case,
1375 * Errors are automatically reported through the wkh_4_End() macro
1379 /* The following code is the generic template with which the value of a
1380 * well-known header can be processed. Not all sections yield a semantically
1381 * correct result, so appropriate error information must be provided.
1385 #define wkh_0a_Declarations /* Declarations for Parsing */ \
1386 gboolean ok = FALSE; /* Triggers error notification code at end */ \
1387 proto_tree *header_tree; /* base tree for all fields */ \
1388 proto_item *header_item; /* base item for all fields */ \
1389 guint32 val_start = hdr_start + 1; \
1390 guint8 val_id = tvb_get_guint8 (tvb, val_start); \
1391 guint32 offset = val_start; /* Offset to one past this header */ \
1392 guint32 val_len; /* length for value with length field */ \
1393 guint32 val_len_len /* length of length field */
1395 #define wkh_0_Declarations \
1396 wkh_0a_Declarations; \
1397 const gchar *val_str = NULL
1399 #define wkh_1_WellKnownValue(hf_hdr, ett, header) /* Parse Well Known Value */ \
1400 header_tree = proto_tree_add_subtree(tree, tvb, hdr_start, offset - hdr_start, ett, \
1401 &header_item, header); \
1402 proto_tree_add_item(header_tree, hf_hdr, tvb, hdr_start, 1, ENC_NA); \
1403 if (val_id & 0x80) { /* Well-known value */ \
1405 /* Well-known value processing starts HERE \
1409 #define wkh_2_TextualValue /* Parse Textual Value */ \
1411 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \
1412 val_str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (gint *)&val_len, ENC_ASCII); \
1413 offset = val_start + val_len; \
1414 /* Textual value processing starts HERE \
1418 #define wkh_2_TextualValueInv /* Parse Textual Value */ \
1420 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \
1421 /*val_str = (gchar *)*/tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (gint *)&val_len, ENC_ASCII); \
1422 offset = val_start + val_len; \
1423 /* Textual value processing starts HERE \
1427 #define wkh_3_ValueWithLength /* Parse Value With Length */ \
1429 } else { /* val_start points to 1st byte of length field */ \
1430 if (val_id == 0x1F) { /* Value Length = guintvar */ \
1431 val_len = tvb_get_guintvar(tvb, val_start + 1, &val_len_len, pinfo, &ei_wsp_oversized_uintvar); \
1432 val_len_len++; /* 0x1F length indicator byte */ \
1433 } else { /* Short length followed by Len data octets */ \
1434 val_len = tvb_get_guint8(tvb, offset); \
1437 offset += val_len_len + val_len; \
1438 /* Value with length processing starts HERE \
1439 * The value lies between val_start and offset: \
1440 * - Value Length: Start = val_start \
1441 * Length = val_len_len \
1442 * - Value Data : Start = val_start + val_len_len \
1443 * Length = val_len \
1444 * End = offset - 1 \
1447 #define wkh_4_End() /* End of value parsing */ \
1450 /* Check for errors */ \
1452 expert_add_info(pinfo, header_item, &ei_wsp_header_invalid_value); \
1458 * This yields the following default header value parser function body
1461 wkh_default(proto_tree *tree, tvbuff_t *tvb,
1462 guint32 hdr_start, packet_info *pinfo _U_)
1465 guint8 hdr_id = tvb_get_guint8 (tvb, hdr_start) & 0x7F;
1467 ok = TRUE; /* Bypass error checking as we don't parse the values! */
1469 wkh_1_WellKnownValue(hf_hdr_name_value, ett_default, "default");
1470 proto_tree_add_uint_format(tree, hf_wsp_default_int, tvb, hdr_start, offset - hdr_start,
1471 val_id & 0x7F, "%s: (Undecoded well-known value 0x%02x)",
1472 val_to_str_ext (hdr_id, &vals_field_names_ext,
1473 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F);
1475 proto_tree_add_string_format(tree, hf_wsp_default_string, tvb, hdr_start, offset - hdr_start,
1477 val_to_str_ext (hdr_id, &vals_field_names_ext,
1478 "<Unknown WSP header field 0x%02X>"), val_str);
1479 wkh_3_ValueWithLength;
1480 proto_tree_add_uint_format(tree, hf_wsp_default_val_len, tvb, hdr_start, offset - hdr_start,
1481 val_len, "%s: (Undecoded value in general form with length indicator)",
1482 val_to_str_ext (hdr_id, &vals_field_names_ext,
1483 "<Unknown WSP header field 0x%02X>"));
1485 wkh_4_End(); /* The default parser has no associated hf_index;
1486 additionally the error code is always bypassed */
1490 /* Content-type processing uses the following common core: */
1492 wkh_content_type_header(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name)
1495 guint32 off, val = 0, len;
1497 proto_item *ti = NULL;
1498 proto_tree *parameter_tree = NULL;
1499 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Content type: %s", name);
1501 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_type_header, header_name);
1502 proto_tree_add_string(header_tree, hf, tvb, val_start, 1,
1503 val_to_str_ext(val_id & 0x7F, &vals_content_types_ext,
1504 "(Unknown content type identifier 0x%X)"));
1505 proto_item_set_len(header_item, 2);
1508 /* Sometimes with a No-Content response, a NULL content type
1509 * is reported. Process this correctly! */
1511 proto_tree_add_string(header_tree, hf, tvb, val_start, val_len, val_str);
1512 proto_item_set_len(header_item, val_len+1);
1514 proto_tree_add_string(header_tree, hf, tvb, val_start, 0,
1515 "<no content type has been specified>");
1516 proto_item_set_len(header_item, 2);
1519 wkh_3_ValueWithLength;
1520 off = val_start + val_len_len;
1521 peek = tvb_get_guint8(tvb, off);
1522 if (is_text_string(peek)) {
1523 val_str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, off, (gint*)&len, ENC_ASCII);
1524 off += len; /* off now points to 1st byte after string */
1525 ti = proto_tree_add_string (header_tree, hf, tvb, hdr_start, offset - hdr_start, val_str);
1526 } else if (is_integer_value(peek)) {
1527 get_integer_value(val, tvb, off, len, ok);
1529 ti = proto_tree_add_string(header_tree, hf,
1530 tvb, hdr_start, offset - hdr_start,
1531 val_to_str_ext(val, &vals_content_types_ext,
1532 "(Unknown content type identifier 0x%X)"));
1539 /* Remember: offset == val_start + val_len + val_len_len */
1540 if (ok && (off < offset)) { /* Add parameters if any */
1541 parameter_tree = proto_item_add_subtree (ti, ett_header);
1542 while (off < offset) {
1543 off = parameter (parameter_tree, pinfo, ti, tvb, off, offset - off);
1554 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
1557 wkh_accept(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
1559 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_accept, "Accept");
1564 * Content-type-value =
1567 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
1569 * Beware: this header should not appear as such; it is dissected elsewhere
1570 * and at the same time the content type is used for subdissectors.
1571 * It is here for the sake of completeness.
1574 wkh_content_type(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
1576 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_content_type, "Content-Type");
1581 * Content-type-value =
1584 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
1586 * This function adds the content type value to the protocol tree,
1587 * and computes either the numeric or textual media type in return,
1588 * which will be used for further subdissection (e.g., MMS, WBXML).
1591 add_content_type(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint32 val_start,
1592 guint32 *well_known_content, const char **textual_content)
1594 /* Replace wkh_0_Declarations with slightly modified declarations
1595 * so we can still make use of the wkh_[1-4]_XXX macros! */
1596 guint32 hdr_start = val_start; /* No header name, only value! */
1597 guint8 val_id = tvb_get_guint8 (tvb, val_start);
1598 guint32 offset = val_start; /* Offset to one past this header */
1599 guint32 val_len; /* length for value with length field */
1600 guint32 val_len_len; /* length of length field */
1601 gchar *val_str = NULL;
1602 guint32 off, val = 0, len;
1604 gboolean ok = FALSE;
1605 proto_item *ti = NULL;
1606 proto_tree *parameter_tree = NULL;
1607 proto_tree *header_tree;
1608 proto_item *header_item;
1610 *textual_content = NULL;
1611 *well_known_content = 0;
1613 wkh_1_WellKnownValue(hf_hdr_name_value, ett_add_content_type, "Content-Type");
1614 *textual_content = val_to_str_ext(val_id & 0x7F, &vals_content_types_ext,
1615 "<Unknown media type identifier 0x%X>");
1616 proto_tree_add_string(tree, hf_hdr_content_type,
1617 tvb, hdr_start, offset - hdr_start,
1619 *well_known_content = val_id & 0x7F;
1622 /* Sometimes with a No-Content response, a NULL content type
1623 * is reported. Process this correctly! */
1625 proto_tree_add_string(tree, hf_hdr_content_type,
1626 tvb, hdr_start, offset - hdr_start,
1628 *textual_content = wmem_strdup(pinfo->pool, val_str);
1629 *well_known_content = 0;
1631 proto_tree_add_string(tree, hf_hdr_content_type,
1632 tvb, hdr_start, offset - hdr_start,
1633 "<no media type has been specified>");
1634 *textual_content = NULL;
1635 *well_known_content = 0;
1638 wkh_3_ValueWithLength;
1639 off = val_start + val_len_len;
1640 peek = tvb_get_guint8(tvb, off);
1641 if (is_text_string(peek)) {
1642 get_extension_media(val_str, tvb, off, len, ok);
1644 off += len; /* off now points to 1st byte after string */
1645 ti = proto_tree_add_string (tree, hf_hdr_content_type,
1646 tvb, hdr_start, offset - hdr_start, val_str);
1648 /* Following statement: required? */
1649 *textual_content = wmem_strdup(pinfo->pool, val_str);
1650 *well_known_content = 0;
1651 } else if (is_integer_value(peek)) {
1652 get_integer_value(val, tvb, off, len, ok);
1654 *textual_content = val_to_str_ext(val, &vals_content_types_ext,
1655 "<Unknown media type identifier 0x%X>");
1656 ti = proto_tree_add_string(tree, hf_hdr_content_type,
1657 tvb, hdr_start, offset - hdr_start,
1659 *well_known_content = val;
1662 } /* else ok = FALSE */
1663 /* Remember: offset == val_start + val_len_len + val_len */
1664 if (ok && (off < offset)) { /* Add parameters if any */
1665 parameter_tree = proto_item_add_subtree (ti, ett_header);
1666 while (off < offset) {
1667 off = parameter (parameter_tree, pinfo, ti, tvb, off, offset - off);
1676 * Template for accept_X headers with optional Q parameter value
1678 #define wkh_accept_x_q_header(underscored,Text,valueStringExtAddr,valueName) \
1680 wkh_ ## underscored (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
1682 return wkh_accept_x_q_header_func(tree, tvb, hdr_start, pinfo, \
1683 hf_hdr_ ## underscored, Text, valueStringExtAddr, \
1684 "<Unknown " valueName " identifier 0x%X>"); \
1688 wkh_accept_x_q_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo,
1689 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format)
1690 G_GNUC_PRINTF(8, 0);
1693 wkh_accept_x_q_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo,
1694 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format)
1697 guint32 off, val = 0, len;
1699 proto_item *ti = NULL;
1700 proto_tree *parameter_tree = NULL;
1701 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Accept X: %s", name);
1703 wkh_1_WellKnownValue(hf_hdr_name_value, ett_accept_x_q_header, header_name);
1704 proto_tree_add_string(tree, hf,
1705 tvb, hdr_start, offset - hdr_start,
1706 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, value_format));
1709 proto_tree_add_string(tree, hf,
1710 tvb, hdr_start, offset - hdr_start, val_str);
1712 wkh_3_ValueWithLength;
1713 off = val_start + val_len_len;
1714 peek = tvb_get_guint8(tvb, off);
1715 if (is_text_string(peek)) {
1716 get_token_text(val_str, tvb, off, len, ok);
1718 off += len; /* off now points to 1st byte after string */
1719 ti = proto_tree_add_string (tree, hf,
1720 tvb, hdr_start, offset - hdr_start, val_str);
1722 } else if (is_integer_value(peek)) {
1723 get_integer_value(val, tvb, off, len, ok);
1725 ti = proto_tree_add_string(tree, hf,
1726 tvb, hdr_start, offset - hdr_start,
1727 val_to_str_ext(val, valueStringExtAddr, value_format));
1730 } /* else ok = FALSE */
1731 /* Remember: offset == val_start + val_len */
1732 if (ok && (off < offset)) { /* Add Q-value if available */
1733 parameter_tree = proto_item_add_subtree (ti, ett_header);
1734 /*off =*/ parameter_value_q (parameter_tree, pinfo, ti, tvb, off);
1741 * Accept-charset-value =
1744 * | ( Value-length ( Token-text | Integer-value ) [ Q-value ] )
1746 wkh_accept_x_q_header(accept_charset, "Accept-Charset",
1747 &mibenum_vals_character_sets_ext, "character set")
1749 * Accept-language-value =
1752 * | ( Value-length ( Text-string | Integer-value ) [ Q-value ] )
1754 wkh_accept_x_q_header(accept_language, "Accept-Language",
1755 &vals_languages_ext, "language")
1759 * Push-flag-value = Short-integer
1762 wkh_push_flag(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
1764 wkh_0a_Declarations;
1765 proto_item *ti = NULL;
1766 proto_tree *subtree = NULL;
1767 wmem_strbuf_t *push_flag_str = wmem_strbuf_new(wmem_packet_scope(), "");
1769 wkh_1_WellKnownValue(hf_hdr_name_value, ett_push_flag, "Push Flag");
1771 wmem_strbuf_append(push_flag_str, " (Initiator URI authenticated)");
1773 wmem_strbuf_append(push_flag_str, " (Content trusted)");
1775 wmem_strbuf_append(push_flag_str, " (Last push message)");
1777 wmem_strbuf_append(push_flag_str, " <Warning: Reserved flags set>");
1781 ti = proto_tree_add_string(tree, hf_hdr_push_flag,
1782 tvb, hdr_start, offset - hdr_start, wmem_strbuf_get_str(push_flag_str));
1783 subtree = proto_item_add_subtree(ti, ett_header);
1784 proto_tree_add_uint(subtree, hf_hdr_push_flag_auth,
1785 tvb, val_start, 1, val_id);
1786 proto_tree_add_uint(subtree, hf_hdr_push_flag_trust,
1787 tvb, val_start, 1, val_id);
1788 proto_tree_add_uint(subtree, hf_hdr_push_flag_last,
1789 tvb, val_start, 1, val_id);
1791 wkh_2_TextualValueInv;
1793 wkh_3_ValueWithLength;
1800 * Profile-Diff (with WBXML): Profile-diff-value =
1801 * Value-length <WBXML-Content>
1803 static guint32 wkh_profile_diff_wbxml (proto_tree *tree, tvbuff_t *tvb,
1804 guint32 hdr_start, packet_info *pinfo)
1806 wkh_0a_Declarations;
1808 proto_item *ti = NULL;
1809 proto_tree *subtree;
1811 ok = TRUE; /* Bypass error checking as we don't parse the values! */
1813 wkh_1_WellKnownValue(hf_hdr_name_value, ett_profile_diff_wbxml, "Profile-Diff (with WBXML)");
1815 wkh_2_TextualValueInv;
1817 wkh_3_ValueWithLength;
1818 ti = proto_tree_add_string(tree, hf_hdr_profile_diff, tvb, hdr_start, offset - hdr_start,
1819 "(Profile-Diff value as WBXML)");
1820 subtree = proto_item_add_subtree(ti, ett_header);
1821 tmp_tvb = tvb_new_subset_length(tvb, val_start + val_len_len, val_len); /* TODO: fix 2nd length */
1822 call_dissector(wbxml_uaprof_handle, tmp_tvb, pinfo, subtree);
1833 wkh_allow(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
1835 wkh_0a_Declarations;
1837 wkh_1_WellKnownValue(hf_hdr_name_value, ett_allow, "Allow");
1839 if (val_id >= 0x40) { /* Valid WSP method */
1840 proto_tree_add_string(tree, hf_hdr_allow,
1841 tvb, hdr_start, offset - hdr_start,
1842 val_to_str_ext(val_id & 0x7F, &wsp_vals_pdu_type_ext,
1843 "<Unknown WSP method 0x%02X>"));
1846 wkh_2_TextualValueInv;
1848 wkh_3_ValueWithLength;
1856 * Token-text | Short-integer
1859 wkh_public(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
1863 wkh_1_WellKnownValue(hf_hdr_name_value, ett_public, "Public");
1865 if (val_id >= 0x40) { /* Valid WSP method */
1866 proto_tree_add_string(tree, hf_hdr_public,
1867 tvb, hdr_start, offset - hdr_start,
1868 val_to_str_ext(val_id & 0x7F, &wsp_vals_pdu_type_ext,
1869 "<Unknown WSP method 0x%02X>"));
1873 proto_tree_add_string(tree, hf_hdr_public,
1874 tvb, hdr_start, offset - hdr_start, val_str);
1876 wkh_3_ValueWithLength;
1884 * Token-text | Short-integer
1887 wkh_vary(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
1891 wkh_1_WellKnownValue(hf_hdr_name_value, ett_vary, "Vary");
1892 proto_tree_add_string(tree, hf_hdr_vary,
1893 tvb, hdr_start, offset - hdr_start,
1894 val_to_str_ext(val_id & 0x7F, &vals_field_names_ext,
1895 "<Unknown WSP header field 0x%02X>"));
1898 proto_tree_add_string(tree, hf_hdr_vary,
1899 tvb, hdr_start, offset - hdr_start,
1902 wkh_3_ValueWithLength;
1909 * X-wap-security-value = 0x80
1912 wkh_x_wap_security(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
1914 wkh_0a_Declarations;
1916 wkh_1_WellKnownValue(hf_hdr_name_value, ett_x_wap_security, "X-wap-security-value");
1917 if (val_id == 0x80) {
1918 proto_tree_add_string(tree, hf_hdr_x_wap_security,
1919 tvb, hdr_start, offset - hdr_start, "close-subordinate");
1922 wkh_2_TextualValueInv;
1924 wkh_3_ValueWithLength;
1931 * Connection-value = 0x80 | Token-text
1934 wkh_connection(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
1938 wkh_1_WellKnownValue(hf_hdr_name_value, ett_connection, "Connection");
1939 if (val_id == 0x80) {
1940 proto_tree_add_string(tree, hf_hdr_connection,
1941 tvb, hdr_start, offset - hdr_start, "close");
1945 proto_tree_add_string(tree, hf_hdr_connection,
1946 tvb, hdr_start, offset - hdr_start, val_str);
1948 wkh_3_ValueWithLength;
1955 * Transfer-encoding-value = 0x80 | Token-text
1958 wkh_transfer_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
1962 wkh_1_WellKnownValue(hf_hdr_name_value, ett_transfer_encoding, "Transfer encoding");
1963 if (val_id == 0x80) {
1964 proto_tree_add_string(tree, hf_hdr_transfer_encoding,
1965 tvb, hdr_start, offset - hdr_start, "chunked");
1969 proto_tree_add_string(tree, hf_hdr_transfer_encoding,
1970 tvb, hdr_start, offset - hdr_start, val_str);
1972 wkh_3_ValueWithLength;
1979 * Accept-range-value = 0x80 | 0x81 | Token-text
1982 wkh_accept_ranges(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
1986 wkh_1_WellKnownValue(hf_hdr_name_value, ett_accept_ranges, "Accept Ranges");
1988 case 0x80: /* none */
1989 proto_tree_add_string(tree, hf_hdr_accept_ranges,
1990 tvb, hdr_start, offset - hdr_start, "none");
1993 case 0x81: /* bytes */
1994 proto_tree_add_string(tree, hf_hdr_accept_ranges,
1995 tvb, hdr_start, offset - hdr_start, "bytes");
2000 proto_tree_add_string(tree, hf_hdr_accept_ranges,
2001 tvb, hdr_start, offset - hdr_start, val_str);
2003 wkh_3_ValueWithLength;
2010 * Content-encoding-value = 0x80 | 0x81 | 0x82 | Token-text
2013 wkh_content_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2017 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_encoding, "Content Encoding");
2019 case 0x80: /* gzip */
2020 proto_tree_add_string(tree, hf_hdr_content_encoding,
2021 tvb, hdr_start, offset - hdr_start, "gzip");
2024 case 0x81: /* compress */
2025 proto_tree_add_string(tree, hf_hdr_content_encoding,
2026 tvb, hdr_start, offset - hdr_start, "compress");
2029 case 0x82: /* deflate */
2030 proto_tree_add_string(tree, hf_hdr_content_encoding,
2031 tvb, hdr_start, offset - hdr_start, "deflate");
2036 proto_tree_add_string(tree, hf_hdr_content_encoding,
2037 tvb, hdr_start, offset - hdr_start, val_str);
2039 wkh_3_ValueWithLength;
2046 * Accept-encoding-value =
2049 * | ( Value-length ( Short-integer | Text-string ) [ Q-value ] )
2052 wkh_accept_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
2058 proto_item *ti = NULL;
2059 proto_tree *parameter_tree = NULL;
2061 wkh_1_WellKnownValue(hf_hdr_name_value, ett_accept_encoding, "Accept Encoding");
2063 case 0x80: /* gzip */
2064 proto_tree_add_string(tree, hf_hdr_accept_encoding,
2065 tvb, hdr_start, offset - hdr_start, "gzip");
2068 case 0x81: /* compress */
2069 proto_tree_add_string(tree, hf_hdr_accept_encoding,
2070 tvb, hdr_start, offset - hdr_start, "compress");
2073 case 0x82: /* deflate */
2074 proto_tree_add_string(tree, hf_hdr_accept_encoding,
2075 tvb, hdr_start, offset - hdr_start, "deflate");
2079 proto_tree_add_string(tree, hf_hdr_accept_encoding,
2080 tvb, hdr_start, offset - hdr_start, "*");
2085 proto_tree_add_string(tree, hf_hdr_accept_encoding,
2086 tvb, hdr_start, offset - hdr_start, val_str);
2088 wkh_3_ValueWithLength;
2089 off = val_start + val_len_len;
2090 peek = tvb_get_guint8(tvb, off);
2091 if (is_short_integer(peek)) {
2093 case 0x80: /* gzip */
2094 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2095 tvb, hdr_start, offset - hdr_start, "gzip");
2098 case 0x81: /* compress */
2099 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2100 tvb, hdr_start, offset - hdr_start, "compress");
2103 case 0x82: /* deflate */
2104 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2105 tvb, hdr_start, offset - hdr_start, "deflate");
2108 case 0x83: /* any */
2109 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2110 tvb, hdr_start, offset - hdr_start, "*");
2116 get_token_text(str, tvb, off, len, ok);
2118 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2119 tvb, hdr_start, offset - hdr_start, str);
2124 /* Remember: offset == val_start + val_len_len + val_len */
2125 if (off < offset) { /* Add Q-value if available */
2126 parameter_tree = proto_item_add_subtree(ti, ett_header);
2127 parameter_value_q(parameter_tree, pinfo, ti, tvb, off);
2135 * Content-disposition-value = Value-length ( Disposition ) *( Parameter )
2136 * Disposition = Form-data | Attachment | Inline | Token-text
2140 * We handle this as:
2141 * Value-length ( Short-integer | Text-string ) *( Parameter )
2144 wkh_content_disposition(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
2146 wkh_0a_Declarations;
2150 proto_item *ti = NULL;
2151 proto_tree *parameter_tree = NULL;
2153 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_disposition, "Content Disposition");
2155 wkh_2_TextualValueInv;
2157 wkh_3_ValueWithLength;
2158 off = val_start + val_len_len;
2159 peek = tvb_get_guint8(tvb, off);
2160 if (is_short_integer(peek)) {
2162 case 0x80: /* form-data */
2163 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2164 tvb, hdr_start, offset - hdr_start, "form-data");
2167 case 0x81: /* attachment */
2168 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2169 tvb, hdr_start, offset - hdr_start, "attachment");
2172 case 0x82: /* inline */
2173 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2174 tvb, hdr_start, offset - hdr_start, "inline");
2180 get_token_text(str, tvb, off, len, ok);
2182 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2183 tvb, hdr_start, offset - hdr_start, str);
2187 if ((ok) && (off < offset)) {
2188 /* Remember: offset == val_start + val_len_len + val_len */
2189 parameter_tree = proto_item_add_subtree(ti, ett_header);
2190 while (off < offset) { /* Add parameters if available */
2191 off = parameter(parameter_tree, pinfo, ti, tvb, off, offset - off);
2199 * Common code for headers with only a textual value
2200 * is written in the macro below:
2202 #define wkh_text_header(underscored,Text) \
2204 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2206 return wkh_text_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2210 wkh_text_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name)
2213 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Header: %s", name);
2215 wkh_1_WellKnownValue(hf_hdr_name_value, ett_text_header, header_name);
2218 proto_tree_add_string(tree, hf,
2219 tvb, hdr_start, offset - hdr_start, val_str);
2221 wkh_3_ValueWithLength;
2226 /* Text-only headers: */
2227 wkh_text_header(content_base, "Content-Base")
2228 wkh_text_header(content_location, "Content-Location")
2229 wkh_text_header(etag, "ETag")
2230 wkh_text_header(from, "From")
2231 wkh_text_header(host, "Host")
2232 wkh_text_header(if_match, "If-Match")
2233 wkh_text_header(if_none_match, "If-None-Match")
2234 wkh_text_header(location, "Location")
2235 wkh_text_header(referer, "Referer")
2236 wkh_text_header(server, "Server")
2237 wkh_text_header(user_agent, "User-Agent")
2238 wkh_text_header(upgrade, "Upgrade")
2239 wkh_text_header(via, "Via")
2240 wkh_text_header(content_uri, "Content-Uri")
2241 wkh_text_header(initiator_uri, "Initiator-Uri")
2242 wkh_text_header(profile, "Profile")
2245 * Same for quoted-string value
2248 wkh_content_id(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
2252 proto_item *ti = NULL;
2254 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_id, "Content ID");
2257 if (is_quoted_string(val_str[0])) {
2258 if (is_quoted_string(val_str[val_len-2])) {
2259 /* Trailing quote - issue a warning */
2260 ti = proto_tree_add_string(tree, hf_hdr_content_id,
2261 tvb, hdr_start, offset - hdr_start, val_str);
2262 expert_add_info(pinfo, ti, &ei_wsp_trailing_quote);
2263 } else { /* OK (no trailing quote) */
2264 str = wmem_strdup_printf(wmem_packet_scope(), "%s\"", val_str);
2265 proto_tree_add_string(tree, hf_hdr_content_id,
2266 tvb, hdr_start, offset - hdr_start, str);
2269 ti = proto_tree_add_string(tree, hf_hdr_content_id,
2270 tvb, hdr_start, offset - hdr_start, val_str);
2271 expert_add_info(pinfo, ti, &ei_wsp_trailing_quote);
2274 wkh_3_ValueWithLength;
2281 * Common code for headers with only a textual or a date value
2282 * is written in the macro below:
2284 #define wkh_text_or_date_value_header(underscored,Text) \
2286 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
2288 return wkh_text_or_date_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2292 wkh_text_or_date_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name)
2295 guint32 val = 0, off = val_start, len;
2296 gchar *str; /* may not be freed! */
2297 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Text or Date: %s", name);
2299 wkh_1_WellKnownValue(hf_hdr_name_value, ett_text_or_date_value, header_name);
2302 proto_tree_add_string(tree, hf,
2303 tvb, hdr_start, offset - hdr_start, val_str);
2305 wkh_3_ValueWithLength;
2306 if (val_id <= 4) { /* Length field already parsed by macro! */
2307 get_date_value(val, tvb, off, len, ok);
2309 str = abs_time_secs_to_str(wmem_packet_scope(), val, ABSOLUTE_TIME_LOCAL, TRUE);
2310 proto_tree_add_string(tree, hf,
2311 tvb, hdr_start, offset - hdr_start, str);
2318 wkh_text_or_date_value_header(if_range,"If-Range")
2322 * Common code for headers with only a date value
2323 * is written in the macro below:
2325 #define wkh_date_value_header(underscored,Text) \
2327 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
2329 return wkh_date_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2333 wkh_date_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name)
2335 wkh_0a_Declarations;
2336 guint32 val = 0, off = val_start, len;
2337 gchar *str; /* may not be freed! */
2338 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Date: %s", name);
2340 wkh_1_WellKnownValue(hf_hdr_name_value, ett_date_value, header_name);
2342 wkh_2_TextualValueInv;
2344 wkh_3_ValueWithLength;
2345 if (val_id <= 4) { /* Length field already parsed by macro! */
2346 get_date_value(val, tvb, off, len, ok);
2348 str = abs_time_secs_to_str(wmem_packet_scope(), val, ABSOLUTE_TIME_LOCAL, TRUE);
2349 proto_tree_add_string(tree, hf,
2350 tvb, hdr_start, offset - hdr_start, str);
2351 /* BEHOLD: do NOT try to free str, as
2352 * abs_time_secs_to_str(wmem_packet_scope(), ) returns wmem_allocated data */
2358 /* Date-value only headers: */
2359 wkh_date_value_header(date, "Date")
2360 wkh_date_value_header(expires, "Expires")
2361 wkh_date_value_header(if_modified_since, "If-Modified-Since")
2362 wkh_date_value_header(if_unmodified_since, "If-Unmodified-Since")
2363 wkh_date_value_header(last_modified, "Last-Modified")
2366 /* Date-value with special interpretation of zero value */
2367 #define wkh_tod_value_header(underscored,Text) \
2369 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
2371 return wkh_tod_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2375 wkh_tod_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name)
2377 wkh_0a_Declarations;
2378 guint32 val = 0, off = val_start, len;
2379 proto_item *ti = NULL;
2380 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Time of Day: %s", name);
2383 wkh_1_WellKnownValue(hf_hdr_name_value, ett_tod_value, header_name);
2384 if (val_id == 0x80) { /* Openwave TOD header uses this format */
2387 ti = proto_tree_add_time_format_value(tree, hf,
2388 tvb, hdr_start, offset - hdr_start, &t,
2389 "Requesting Time Of Day");
2390 proto_item_append_text(ti,
2391 " <Warning: should be encoded as long-integer>");
2394 /* It seems VERY unlikely that we'll see date values within the first
2395 * 127 seconds of the UNIX 1-1-1970 00:00:00 start of the date clocks
2396 * so I assume such a value is a genuine error */
2397 wkh_2_TextualValueInv;
2399 wkh_3_ValueWithLength;
2400 if (val_id <= 4) { /* Length field already parsed by macro! */
2401 get_date_value(val, tvb, off, len, ok);
2403 t.secs = (time_t)val;
2406 proto_tree_add_time_format_value(tree, hf,
2407 tvb, hdr_start, offset - hdr_start, &t,
2408 "Requesting Time Of Day");
2410 proto_tree_add_time(tree, hf,
2411 tvb, hdr_start, offset - hdr_start, &t);
2418 wkh_tod_value_header(x_wap_tod, "X-Wap-Tod")
2422 * Age-value: Delta-seconds-value
2425 wkh_age(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2428 guint32 val = 0, off = val_start, len;
2430 wkh_1_WellKnownValue(hf_hdr_name_value, ett_age, "Age");
2431 val = val_id & 0x7F;
2432 val_str = wmem_strdup_printf(wmem_packet_scope(), "%u second%s", val, plurality(val, "", "s"));
2433 proto_tree_add_string(tree, hf_hdr_age,
2434 tvb, hdr_start, offset - hdr_start, val_str);
2436 wkh_2_TextualValueInv;
2438 wkh_3_ValueWithLength;
2439 if (val_id <= 4) { /* Length field already parsed by macro! */
2440 get_long_integer(val, tvb, off, len, ok);
2442 val_str = wmem_strdup_printf(wmem_packet_scope(), "%u second%s", val, plurality(val, "", "s"));
2443 proto_tree_add_string(tree, hf_hdr_age,
2444 tvb, hdr_start, offset - hdr_start, val_str);
2452 * Template for Integer lookup or text value headers:
2454 #define wkh_integer_lookup_or_text_value(underscored,Text,valueStringExtAddr,valueName) \
2456 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
2458 return wkh_integer_lookup_or_text_value_func(tree, tvb, hdr_start, pinfo, \
2459 hf_hdr_ ## underscored, Text,valueStringExtAddr, \
2460 "<Unknown " valueName " identifier 0x%X>"); \
2464 wkh_integer_lookup_or_text_value_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo,
2465 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format)
2466 G_GNUC_PRINTF(8, 0);
2469 wkh_integer_lookup_or_text_value_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo,
2470 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format)
2473 guint32 off = val_start, len;
2474 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer lookup: %s", name);
2476 wkh_1_WellKnownValue(hf_hdr_name_value, ett_integer_lookup, header_name);
2477 proto_tree_add_string(tree, hf,
2478 tvb, hdr_start, offset - hdr_start,
2479 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, value_format));
2482 proto_tree_add_string(tree, hf,
2483 tvb, hdr_start, offset - hdr_start, val_str);
2485 wkh_3_ValueWithLength;
2486 if (val_id <= 4) { /* Length field already parsed by macro! */
2487 len = tvb_get_guint8(tvb,off);
2488 ok = (len >= 1 && len <= 4); /* Valid lengths for us are 1-4 */
2490 proto_tree_add_string(tree, hf,
2491 tvb, hdr_start, offset - hdr_start,
2492 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, value_format));
2499 * Wap-application-value: Uri-value | Integer-value
2501 wkh_integer_lookup_or_text_value(x_wap_application_id, "X-Wap-Application-Id",
2502 &vals_wap_application_ids_ext, "WAP application")
2503 wkh_integer_lookup_or_text_value(accept_application, "Accept-Application",
2504 &vals_wap_application_ids_ext, "WAP application")
2505 wkh_integer_lookup_or_text_value(content_language, "Content-Language",
2506 &vals_languages_ext, "language")
2507 /* NOTE - Although the WSP spec says this is an integer-value, the WSP headers
2508 * are encoded as a 7-bit entity! */
2509 wkh_integer_lookup_or_text_value(trailer, "Trailer",
2510 &vals_field_names_ext, "well-known-header")
2518 * Common code for headers with only a challenge value
2519 * is written in the macro below:
2521 #define wkh_challenge_value_header(underscored,Text) \
2523 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
2525 return wkh_challenge_value_header_func(tree, tvb, hdr_start, pinfo, \
2526 hf_hdr_ ## underscored, hf_hdr_ ## underscored ## _scheme, \
2527 hf_hdr_ ## underscored ## _realm, Text); \
2531 wkh_challenge_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo,
2532 int hf, int hf_scheme, int hf_realm, const char* name)
2534 wkh_0a_Declarations;
2537 proto_tree *subtree;
2539 proto_item *ti = NULL;
2540 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Challenge: %s", name);
2542 wkh_1_WellKnownValue(hf_hdr_name_value, ett_challenge, header_name);
2544 wkh_2_TextualValueInv;
2546 wkh_3_ValueWithLength;
2547 off = val_start + val_len_len;
2548 peek = tvb_get_guint8(tvb, off);
2549 if (peek == 0x80) { /* Basic */
2550 ti = proto_tree_add_string(tree, hf,
2551 tvb, hdr_start, offset - hdr_start, "basic");
2552 subtree = proto_item_add_subtree(ti, ett_header);
2553 proto_tree_add_string(subtree, hf_scheme,
2554 tvb, off, 1, "basic");
2556 /* Realm: text-string */
2557 get_text_string(str,tvb,off,len,ok);
2559 proto_tree_add_string(subtree,
2561 tvb, off, len, str);
2562 proto_item_append_text(ti, "; realm=%s", str);
2565 } else { /* Authentication-scheme: token-text */
2566 get_token_text(str, tvb, off, len, ok);
2568 ti = proto_tree_add_string(tree, hf,
2569 tvb, hdr_start, off - hdr_start, str);
2570 subtree = proto_item_add_subtree(ti, ett_header);
2571 proto_tree_add_string(subtree,
2573 tvb, hdr_start, off - hdr_start, str);
2575 /* Realm: text-string */
2576 get_text_string(str,tvb,off,len,ok);
2578 proto_tree_add_string(subtree,
2580 tvb, off, len, str);
2581 proto_item_append_text(ti, "; realm=%s", str);
2583 /* Auth-params: parameter - TODO */
2584 while (off < offset) /* Parse parameters */
2585 off = parameter(subtree, pinfo, ti, tvb, off, offset - off);
2592 /* Challenge-value only headers: */
2593 wkh_challenge_value_header(www_authenticate, "WWW-Authenticate")
2594 wkh_challenge_value_header(proxy_authenticate, "Proxy-Authenticate")
2602 * Common code for headers with only a credentials value
2603 * is written in the macro below:
2605 #define wkh_credentials_value_header(underscored,Text) \
2607 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
2609 return wkh_credentials_value_header_func(tree, tvb, hdr_start, pinfo, \
2610 hf_hdr_ ## underscored, hf_hdr_ ## underscored ## _scheme, \
2611 hf_hdr_ ## underscored ## _user_id, hf_hdr_ ## underscored ## _password, Text); \
2615 wkh_credentials_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo,
2616 int hf, int hf_scheme, int hf_userid, int hf_password, const char* name)
2618 wkh_0a_Declarations;
2621 proto_tree *subtree;
2623 proto_item *ti = NULL;
2624 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Credentials: %s", name);
2626 wkh_1_WellKnownValue(hf_hdr_name_value, ett_credentials_value, header_name);
2628 wkh_2_TextualValueInv;
2630 wkh_3_ValueWithLength;
2631 off = val_start + val_len_len;
2632 peek = tvb_get_guint8(tvb, off);
2633 if (peek == 0x80) { /* Basic */
2634 ti = proto_tree_add_string(tree, hf,
2635 tvb, hdr_start, offset - hdr_start, "basic");
2636 subtree = proto_item_add_subtree(ti, ett_header);
2637 proto_tree_add_string(subtree, hf_scheme,
2638 tvb, off, 1, "basic");
2640 /* User-id: text-string */
2641 get_text_string(str,tvb,off,len,ok);
2643 proto_tree_add_string(subtree,
2645 tvb, off, len, str);
2646 proto_item_append_text(ti, "; user-id=%s", str);
2648 /* Password: text-string */
2649 get_text_string(str,tvb,off,len,ok);
2651 proto_tree_add_string(subtree,
2653 tvb, off, len, str);
2654 proto_item_append_text(ti, "; password=%s", str);
2658 } else { /* Authentication-scheme: token-text */
2659 get_token_text(str, tvb, off, len, ok);
2661 ti = proto_tree_add_string(tree, hf,
2662 tvb, hdr_start, off - hdr_start, str);
2663 subtree = proto_item_add_subtree(ti, ett_header);
2664 proto_tree_add_string(subtree,
2666 tvb, hdr_start, off - hdr_start, str);
2668 /* Auth-params: parameter - TODO */
2669 while (off < offset) /* Parse parameters */
2670 off = parameter(subtree, pinfo, ti, tvb, off, offset - off);
2676 /* Credentials-value only headers: */
2677 wkh_credentials_value_header(authorization, "Authorization")
2678 wkh_credentials_value_header(proxy_authorization, "Proxy-Authorization")
2682 * Content-md5-value = 16*16 OCTET
2685 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2687 wkh_0a_Declarations;
2690 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_md5, "Content-md5");
2692 wkh_2_TextualValueInv;
2694 wkh_3_ValueWithLength;
2695 off = val_start + val_len_len;
2696 if (val_len == 16) {
2697 proto_tree_add_item(tree, hf_hdr_content_md5,
2698 tvb, off, val_len, ENC_NA);
2706 * Pragma-value = 0x80 | Length Parameter
2709 wkh_pragma(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
2711 wkh_0a_Declarations;
2713 proto_item *ti = NULL;
2715 wkh_1_WellKnownValue(hf_hdr_name_value, ett_pragma, "Pragma");
2716 if (val_id == 0x80) {
2717 proto_tree_add_string(tree, hf_hdr_pragma,
2718 tvb, hdr_start, offset - hdr_start, "no-cache");
2721 wkh_2_TextualValueInv;
2723 wkh_3_ValueWithLength;
2724 off = val_start + val_len_len;
2725 ti = proto_tree_add_string(tree, hf_hdr_pragma,
2726 tvb, hdr_start, off - hdr_start, "");
2727 /* NULL subtree for parameter() results in no subtree
2728 * TODO - provide a single parameter dissector that appends data
2729 * to the header field data. */
2730 parameter(NULL, pinfo, ti, tvb, off, offset - off);
2739 #define wkh_integer_value_header(underscored,Text) \
2741 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
2743 return wkh_integer_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2747 wkh_integer_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name)
2749 wkh_0a_Declarations;
2750 guint32 val = 0, off = val_start, len;
2751 gchar *str; /* may not be freed! */
2752 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer-value: %s", name);
2754 wkh_1_WellKnownValue(hf_hdr_name_value, ett_integer_value, header_name);
2755 str = wmem_strdup_printf(wmem_packet_scope(), "%u", val_id & 0x7F);
2756 proto_tree_add_string(tree, hf,
2757 tvb, hdr_start, offset - hdr_start, str);
2759 wkh_2_TextualValueInv;
2761 wkh_3_ValueWithLength;
2762 if (val_id <= 4) { /* Length field already parsed by macro! */
2763 get_long_integer(val, tvb, off, len, ok);
2765 str = wmem_strdup_printf(wmem_packet_scope(), "%u", val);
2766 proto_tree_add_string(tree, hf,
2767 tvb, hdr_start, offset - hdr_start, str);
2773 wkh_integer_value_header(content_length, "Content-Length")
2774 wkh_integer_value_header(max_forwards, "Max-Forwards")
2777 #define wkh_integer_lookup_value_header(underscored,Text,valueStringExtAddr,valueName) \
2779 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \
2781 return wkh_integer_lookup_value_header_func(tree, tvb, hdr_start, pinfo, \
2782 hf_hdr_ ## underscored, Text,valueStringExtAddr, valueName); \
2786 wkh_integer_lookup_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo,
2787 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_name)
2790 guint32 off = val_start, len;
2791 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer lookup: %s", name);
2792 gchar* value_name_str = wmem_strdup_printf(wmem_packet_scope(), "<Unknown %s>", value_name);
2794 wkh_1_WellKnownValue(hf_hdr_name_value, ett_integer_lookup_value, header_name);
2795 val_str = try_val_to_str_ext(val_id & 0x7F, valueStringExtAddr);
2797 proto_tree_add_string(tree, hf,
2798 tvb, hdr_start, offset - hdr_start, val_str);
2801 proto_tree_add_string(tree, hf,
2802 tvb, hdr_start, offset - hdr_start,
2805 wkh_2_TextualValueInv;
2807 wkh_3_ValueWithLength;
2808 if (val_id <= 4) { /* Length field already parsed by macro! */
2809 len = tvb_get_guint8(tvb,off);
2810 ok = (len >= 1 && len <= 4); /* Valid lengths for us are 1-4 */
2812 val_str = try_val_to_str_ext(val_id & 0x7F, valueStringExtAddr);
2814 proto_tree_add_string(tree, hf,
2815 tvb, hdr_start, offset - hdr_start, val_str);
2818 proto_tree_add_string(tree, hf,
2819 tvb, hdr_start, offset - hdr_start,
2827 wkh_integer_lookup_value_header(bearer_indication, "Bearer-Indication",
2828 &vals_bearer_types_ext, "bearer type")
2832 * Cache-control-value
2835 wkh_cache_control(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2838 guint32 off, len, val = 0;
2839 guint8 peek, cache_control_directive;
2840 proto_item *ti = NULL;
2841 wmem_strbuf_t *cache_str;
2843 wkh_1_WellKnownValue(hf_hdr_name_value, ett_cache_control, "Cache-control");
2844 val = val_id & 0x7F;
2845 val_str = try_val_to_str_ext(val, &vals_cache_control_ext);
2847 proto_tree_add_string(tree, hf_hdr_cache_control,
2848 tvb, hdr_start, offset - hdr_start, val_str);
2852 proto_tree_add_string(tree, hf_hdr_cache_control,
2853 tvb, hdr_start, offset - hdr_start, val_str);
2855 wkh_3_ValueWithLength;
2857 * ( no-cache | private ) 1*( Field-name )
2858 * | ( max-age | max-stale | min-fresh | s-maxage) Delta-seconds-value
2859 * | Token-text ( Integer-value | Text-value )
2861 * Field-name = Short-integer | Token-text
2863 off = val_start + val_len_len;
2864 cache_control_directive = tvb_get_guint8(tvb, off++);
2865 if (cache_control_directive & 0x80) { /* Well known cache directive */
2866 switch (cache_control_directive & 0x7F) {
2867 case CACHE_CONTROL_NO_CACHE:
2868 case CACHE_CONTROL_PRIVATE:
2869 cache_str = wmem_strbuf_new(wmem_packet_scope(), val_to_str_ext (cache_control_directive & 0x7F, &vals_cache_control_ext,
2870 "<Unknown cache control directive 0x%02X>"));
2871 /* TODO: split multiple entries */
2873 while (ok && (off < offset)) { /* 1*( Field-name ) */
2874 peek = tvb_get_guint8(tvb, off);
2875 if (peek & 0x80) { /* Well-known-field-name */
2876 wmem_strbuf_append(cache_str,
2877 val_to_str (peek, vals_field_names,
2878 "<Unknown WSP header field 0x%02X>"));
2880 } else { /* Token-text */
2881 get_token_text(val_str, tvb, off, len, ok);
2883 wmem_strbuf_append(cache_str, val_str);
2888 proto_tree_add_string(tree, hf_hdr_cache_control,
2889 tvb, hdr_start, offset - hdr_start,
2890 wmem_strbuf_get_str(cache_str));
2893 case CACHE_CONTROL_MAX_AGE:
2894 case CACHE_CONTROL_MAX_STALE:
2895 case CACHE_CONTROL_MIN_FRESH:
2896 case CACHE_CONTROL_S_MAXAGE:
2897 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
2898 tvb, hdr_start, offset - hdr_start,
2899 val_to_str_ext (cache_control_directive & 0x7F, &vals_cache_control_ext,
2900 "<Unknown cache control directive 0x%02X>"));
2901 get_delta_seconds_value(val, tvb, off, len, ok);
2903 proto_item_append_text(ti, "=%u second%s", val, plurality(val, "", "s"));
2911 } else if (is_token_text(cache_control_directive)) {
2912 get_token_text(val_str, tvb, off, len, ok);
2914 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
2915 tvb, hdr_start, offset - hdr_start, val_str);
2916 get_integer_value(val, tvb, off, len, ok);
2917 if (ok) { /* Integer-value */
2918 proto_item_append_text(ti, "=%u", val);
2919 } else { /* Text-value */
2920 get_text_string(val_str, tvb, off, len, ok);
2922 if (is_quoted_string(val_str[0])) {
2923 if (is_quoted_string(val_str[len-2])) {
2924 /* Trailing quote - issue a warning */
2925 expert_add_info(pinfo, ti, &ei_wsp_trailing_quote);
2926 } else { /* OK (no trailing quote) */
2927 proto_item_append_text(ti, "%s\"", val_str);
2929 } else { /* Token-text | 0x00 */
2930 /* TODO - check that we have Token-text or 0x00 */
2931 proto_item_append_text(ti, "%s", val_str);
2944 * | ( Value-length Short-integer Text-string Text-string )
2947 wkh_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2950 guint32 off, len, val;
2953 proto_item *ti = NULL;
2954 proto_tree *subtree;
2956 /* TODO - subtree with values */
2958 wkh_1_WellKnownValue(hf_hdr_name_value, ett_warning, "Warning");
2959 val = val_id & 0x7F;
2960 val_str = try_val_to_str_ext(val, &vals_wsp_warning_code_ext);
2962 ti = proto_tree_add_string(tree, hf_hdr_warning,
2963 tvb, hdr_start, offset - hdr_start, val_str);
2964 subtree = proto_item_add_subtree(ti, ett_header);
2965 proto_tree_add_uint(subtree, hf_hdr_warning_code,
2966 tvb, val_start, 1, val);
2969 wkh_2_TextualValueInv;
2971 wkh_3_ValueWithLength;
2972 /* TODO - subtree with individual values */
2973 off = val_start + val_len_len;
2974 warn_code = tvb_get_guint8(tvb, off);
2975 if (warn_code & 0x80) { /* Well known warn code */
2976 val = warn_code & 0x7f;
2977 val_str = try_val_to_str_ext(val, &vals_wsp_warning_code_short_ext);
2978 if (val_str) { /* OK */
2979 str = wmem_strdup_printf(wmem_packet_scope(), "code=%s", val_str);
2980 ti = proto_tree_add_string(tree, hf_hdr_warning,
2981 tvb, hdr_start, offset - hdr_start, str);
2982 subtree = proto_item_add_subtree(ti, ett_header);
2983 proto_tree_add_uint(subtree, hf_hdr_warning_code,
2985 off++; /* Now skip to the warn-agent subfield */
2986 get_text_string(str, tvb, off, len, ok);
2987 if (ok) { /* Valid warn-agent string */
2988 proto_tree_add_string(subtree, hf_hdr_warning_agent,
2989 tvb, off, len, str);
2990 proto_item_append_text(ti, "; agent=%s", str);
2992 get_text_string(str, tvb, off, len, ok);
2993 if (ok) { /* Valid warn-text string */
2994 proto_tree_add_string(subtree,
2995 hf_hdr_warning_text,
2996 tvb, off, len, str);
2997 proto_item_append_text(ti, "; text=%s", str);
3008 * Profile-warning-value =
3010 * | ( Value-length Short-integer Text-string *( Date-value ) )
3013 wkh_profile_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3016 guint32 off, len, val = 0;
3018 proto_item *ti = NULL;
3020 wkh_1_WellKnownValue(hf_hdr_name_value, ett_profile_warning, "Profile-warning");
3021 val = val_id & 0x7F;
3022 val_str = try_val_to_str_ext(val, &vals_wsp_profile_warning_code_ext);
3024 proto_tree_add_string(tree, hf_hdr_profile_warning,
3025 tvb, hdr_start, offset - hdr_start, val_str);
3028 wkh_2_TextualValueInv;
3030 wkh_3_ValueWithLength;
3031 off = val_start + val_len_len;
3032 warn_code = tvb_get_guint8(tvb, off++);
3033 if (warn_code & 0x80) { /* Well known warn code */
3034 val_str = try_val_to_str_ext(val, &vals_wsp_profile_warning_code_ext);
3035 if (val_str) { /* OK */
3036 ti = proto_tree_add_string(tree, hf_hdr_profile_warning,
3037 tvb, hdr_start, offset - hdr_start, val_str);
3038 get_uri_value(val_str, tvb, off, len, ok);
3039 if (ok) { /* Valid warn-target string */
3040 /* TODO: Why did we just call get_uri_value() and not use
3041 * the str, since the pointer to it is immediately
3042 * forgotten with the call to g_strdup_printf()? */
3044 proto_item_append_text(ti, "; target=%s", val_str);
3045 /* Add zero or more dates */
3046 while (ok && (off < offset)) {
3047 get_date_value(val, tvb, off, len, ok);
3048 if (ok) { /* Valid warn-text string */
3050 proto_item_append_text(ti, "; date=%s", abs_time_secs_to_str(wmem_packet_scope(), val, ABSOLUTE_TIME_LOCAL, TRUE));
3060 /* Encoding-version-value =
3063 * | Length Short-integer [ Short-integer | text-string ]
3065 static guint32 wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb,
3066 guint32 hdr_start, packet_info *pinfo _U_)
3069 proto_item *ti = NULL;
3070 guint32 off, val, len;
3072 wkh_1_WellKnownValue(hf_hdr_name_value, ett_encoding_version, "Encoding-version");
3073 val = val_id & 0x7F;
3074 val_str = wmem_strdup_printf(wmem_packet_scope(), "%u.%u", val >> 4, val & 0x0F);
3075 proto_tree_add_string(tree, hf_hdr_encoding_version,
3076 tvb, hdr_start, offset - hdr_start, val_str);
3079 proto_tree_add_string(tree, hf_hdr_encoding_version,
3080 tvb, hdr_start, offset - hdr_start, val_str);
3082 wkh_3_ValueWithLength;
3083 off = val_start + val_len_len;
3084 val = tvb_get_guint8(tvb, off);
3085 if (val & 0x80) { /* Header Code Page */
3086 val_str = wmem_strdup_printf(wmem_packet_scope(), "code-page=%u", val & 0x7F);
3087 ti = proto_tree_add_string(tree, hf_hdr_encoding_version,
3088 tvb, hdr_start, offset - hdr_start, val_str);
3091 if (off < offset) { /* Extra version-value */
3092 get_version_value(val,val_str,tvb,off,len,ok);
3093 if (ok) { /* Always creates a string if OK */
3094 proto_item_append_text(ti, ": %s", val_str);
3103 /* Content-range-value =
3104 * Length Uintvar-integer ( 0x80 | Uintvar-integer )
3107 wkh_content_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3110 guint32 off, val, len;
3111 proto_item *ti = NULL;
3112 proto_tree *subtree = NULL;
3114 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_range, "Content range");
3116 wkh_2_TextualValueInv;
3118 wkh_3_ValueWithLength;
3119 off = val_start + val_len_len;
3120 get_uintvar_integer (val, tvb, off, len, ok); /* Uintvar start */
3122 val_str = wmem_strdup_printf(wmem_packet_scope(), "first-byte-pos=%u", val);
3123 ti = proto_tree_add_string(tree, hf_hdr_content_range,
3124 tvb, hdr_start, offset - hdr_start, val_str);
3125 subtree = proto_item_add_subtree(ti, ett_header);
3126 proto_tree_add_uint(subtree, hf_hdr_content_range_first_byte_pos,
3127 tvb, off, len, val);
3129 /* Now check next value */
3130 val = tvb_get_guint8(tvb, off);
3131 if (val == 0x80) { /* Unknown length */
3132 proto_item_append_text(ti, "%s", "; entity-length=unknown");
3133 } else { /* Uintvar entity length */
3134 get_uintvar_integer (val, tvb, off, len, ok);
3136 proto_item_append_text(ti, "; entity-length=%u", val);
3137 proto_tree_add_uint(subtree,
3138 hf_hdr_content_range_entity_length,
3139 tvb, off, len, val);
3150 * 0x80 Uintvar-integer [ Uintvar-integer ]
3151 * | 0x81 Uintvar-integer
3154 wkh_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3156 wkh_0a_Declarations;
3157 guint32 off, val, len;
3158 proto_item *ti = NULL;
3159 proto_tree *subtree = NULL;
3161 wkh_1_WellKnownValue(hf_hdr_name_value, ett_range, "Range");
3163 wkh_2_TextualValueInv;
3165 wkh_3_ValueWithLength;
3166 off = val_start + val_len_len;
3167 val = tvb_get_guint8(tvb, off);
3168 if (val == 0x80) { /* Byte-range */
3169 ti = proto_tree_add_string(tree, hf_hdr_range,
3170 tvb, hdr_start, offset - hdr_start, "byte-range");
3171 subtree = proto_item_add_subtree(ti, ett_header);
3172 /* Get the First-byte-pos (Uintvar-integer) */
3173 get_uintvar_integer (val, tvb, off, len, ok);
3175 proto_item_append_text(ti, "; first-byte-pos=%u", val);
3176 proto_tree_add_uint(subtree, hf_hdr_range_first_byte_pos,
3177 tvb, off, len, val);
3179 /* Get the optional Last-byte-pos (Uintvar-integer) */
3181 get_uintvar_integer (val, tvb, off, len, ok);
3183 proto_item_append_text(ti, "; last-byte-pos=%u", val);
3184 proto_tree_add_uint(subtree,
3185 hf_hdr_range_last_byte_pos,
3186 tvb, off, len, val);
3190 } else if (val == 0x81) { /* Suffix-byte-range */
3191 ti = proto_tree_add_string(tree, hf_hdr_range,
3192 tvb, hdr_start, offset - hdr_start, "suffix-byte-range");
3193 subtree = proto_item_add_subtree(ti, ett_header);
3194 /* Get the Suffix-length (Uintvar-integer) */
3195 get_uintvar_integer (val, tvb, off, len, ok);
3197 proto_item_append_text(ti, "; suffix-length=%u", val);
3198 proto_tree_add_uint(subtree, hf_hdr_range_suffix_length,
3199 tvb, off, len, val);
3209 * | Value-length (0x82--0x86 | Token-text) [ Q-token Q-value ]
3211 static guint32 wkh_te (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3214 guint32 off, val, len;
3216 wkh_1_WellKnownValue(hf_hdr_name_value, ett_te_value, "TE-value");
3217 if (val_id == 0x81) {
3218 proto_tree_add_string(tree, hf_hdr_encoding_version,
3219 tvb, hdr_start, offset - hdr_start, "trailers");
3222 wkh_2_TextualValueInv;
3224 wkh_3_ValueWithLength;
3225 off = val_start + val_len_len;
3226 val = tvb_get_guint8(tvb, off);
3227 if (val & 0x80) { /* Well-known-TE */
3228 val_str = try_val_to_str_ext((val & 0x7F), &vals_well_known_te_ext);
3230 proto_tree_add_string(tree, hf_hdr_te,
3231 tvb, hdr_start, off - hdr_start, val_str);
3235 } else { /* TE in Token-text format */
3236 get_token_text(val_str, tvb, off, len, ok);
3238 proto_tree_add_string(tree, hf_hdr_te,
3239 tvb, hdr_start, off - hdr_start, val_str);
3243 if ((ok) && (off < offset)) { /* Q-token Q-value */
3251 /****************************************************************************
3252 * O p e n w a v e h e a d e r s
3253 ****************************************************************************/
3256 /* Dissect the Openwave header value (generic) */
3258 wkh_openwave_default(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3261 guint8 hdr_id = tvb_get_guint8 (tvb, hdr_start) & 0x7F;
3263 ok = TRUE; /* Bypass error checking as we don't parse the values! */
3265 wkh_1_WellKnownValue(hf_hdr_openwave_name_value, ett_openwave_default, "Default");
3266 proto_tree_add_uint_format(tree, hf_hdr_openwave_default_int, tvb, hdr_start, offset - hdr_start,
3267 val_id & 0x7F, "%s: (Undecoded well-known value 0x%02x)",
3268 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext,
3269 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F);
3271 proto_tree_add_string_format(tree, hf_hdr_openwave_default_string, tvb, hdr_start, offset - hdr_start,
3273 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext,
3274 "<Unknown WSP header field 0x%02X>"), val_str);
3275 wkh_3_ValueWithLength;
3276 proto_tree_add_uint_format(tree, hf_hdr_openwave_default_val_len, tvb, hdr_start, offset - hdr_start,
3277 val_len, "%s: (Undecoded value in general form with length indicator)",
3278 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext,
3279 "<Unknown WSP header field 0x%02X>"));
3281 wkh_4_End(); /* See wkh_default for explanation */
3285 /* Textual Openwave headers */
3286 wkh_text_header(openwave_x_up_proxy_operator_domain,
3287 "x-up-proxy-operator-domain")
3288 wkh_text_header(openwave_x_up_proxy_home_page,
3289 "x-up-proxy-home-page")
3290 wkh_text_header(openwave_x_up_proxy_uplink_version,
3291 "x-up-proxy-uplink-version")
3292 wkh_text_header(openwave_x_up_proxy_ba_realm,
3293 "x-up-proxy-ba-realm")
3294 wkh_text_header(openwave_x_up_proxy_request_uri,
3295 "x-up-proxy-request-uri")
3296 wkh_text_header(openwave_x_up_proxy_bookmark,
3297 "x-up-proxy-bookmark")
3299 /* Integer Openwave headers */
3300 wkh_integer_value_header(openwave_x_up_proxy_push_seq,
3301 "x-up-proxy-push-seq")
3302 wkh_integer_value_header(openwave_x_up_proxy_notify,
3303 "x-up-proxy-notify")
3304 wkh_integer_value_header(openwave_x_up_proxy_net_ask,
3305 "x-up-proxy-net-ask")
3306 wkh_integer_value_header(openwave_x_up_proxy_ba_enable,
3307 "x-up-proxy-ba-enable")
3308 wkh_integer_value_header(openwave_x_up_proxy_redirect_enable,
3309 "x-up-proxy-redirect-enable")
3310 wkh_integer_value_header(openwave_x_up_proxy_redirect_status,
3311 "x-up-proxy-redirect-status")
3312 wkh_integer_value_header(openwave_x_up_proxy_linger,
3313 "x-up-proxy-linger")
3314 wkh_integer_value_header(openwave_x_up_proxy_enable_trust,
3315 "x-up-proxy-enable-trust")
3316 wkh_integer_value_header(openwave_x_up_proxy_trust,
3319 wkh_integer_value_header(openwave_x_up_devcap_has_color,
3320 "x-up-devcap-has-color")
3321 wkh_integer_value_header(openwave_x_up_devcap_num_softkeys,
3322 "x-up-devcap-num-softkeys")
3323 wkh_integer_value_header(openwave_x_up_devcap_softkey_size,
3324 "x-up-devcap-softkey-size")
3325 wkh_integer_value_header(openwave_x_up_devcap_screen_chars,
3326 "x-up-devcap-screen-chars")
3327 wkh_integer_value_header(openwave_x_up_devcap_screen_pixels,
3328 "x-up-devcap-screen-pixels")
3329 wkh_integer_value_header(openwave_x_up_devcap_em_size,
3330 "x-up-devcap-em-size")
3331 wkh_integer_value_header(openwave_x_up_devcap_screen_depth,
3332 "x-up-devcap-screen-depth")
3333 wkh_integer_value_header(openwave_x_up_devcap_immed_alert,
3334 "x-up-devcap-immed_alert")
3335 wkh_integer_value_header(openwave_x_up_devcap_gui,
3338 /* Openwave Time-Of-Day value header */
3339 wkh_tod_value_header(openwave_x_up_proxy_tod,
3342 /* Openwave accept_x_q header */
3343 wkh_accept_x_q_header(openwave_x_up_proxy_trans_charset,
3344 "x-up-proxy-trans-charset",
3345 &mibenum_vals_character_sets_ext, "character set")
3347 /* Openwave content type header */
3349 wkh_openwave_x_up_proxy_push_accept(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo)
3351 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_openwave_x_up_proxy_push_accept, "x-up-proxy-push-accept");
3355 static gboolean parameter_text(proto_tree *tree, tvbuff_t *tvb, int *offset, proto_item *ti, int hf)
3361 get_text_string(val_str, tvb, (*offset), val_len, ok);
3363 proto_tree_add_string(tree, hf, tvb, *offset, val_len, val_str);
3364 proto_item_append_text(ti, "; %s=%s", proto_registrar_get_name(hf), val_str);
3365 (*offset) += val_len;
3371 static gboolean parameter_text_value(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int *offset, proto_item *ti, int hf)
3373 gchar *val_str, *str;
3378 get_text_string(val_str, tvb, (*offset), val_len, ok);
3380 if (is_quoted_string(val_str[0])) {
3381 if (is_quoted_string(val_str[val_len-2])) {
3382 /* Trailing quote - issue a warning */
3383 ti2 = proto_tree_add_string(tree, hf,
3384 tvb, *offset, val_len, val_str);
3385 expert_add_info(pinfo, ti2, &ei_wsp_trailing_quote);
3386 } else { /* OK (no trailing quote) */
3387 str = wmem_strdup_printf(wmem_packet_scope(), "%s\"", val_str);
3388 proto_tree_add_string(tree, hf,
3389 tvb, *offset, val_len, str);
3391 } else { /* Token-text | 0x00 */
3392 /* TODO - verify that we have either Token-text or 0x00 */
3393 proto_tree_add_string(tree, hf,
3394 tvb, *offset, val_len, val_str);
3396 proto_item_append_text(ti, "; %s=%s", proto_registrar_get_name(hf), val_str);
3397 (*offset) += val_len;
3403 static const value_string parameter_type_vals[] = {
3404 { 0x00, "Q: Q-value" },
3405 { 0x01, "Well-known-charset" },
3406 { 0x02, "Level: Version-value" },
3407 { 0x03, "Integer-value" },
3408 { 0x05, "Name (Text-string)" },
3409 { 0x06, "Filename (Text-string)" },
3410 { 0x07, "Differences" },
3411 { 0x08, "Padding" },
3412 { 0x09, "Special Constrained-encoding" },
3413 { 0x0A, "Start (Text-string)" },
3414 { 0x0B, "Start-info (Text-string)" },
3415 { 0x0C, "Comment (Text-string)" },
3416 { 0x0D, "Domain (Text-string)" },
3417 { 0x0E, "Max-Age" },
3418 { 0x0F, "Path (Text-string)" },
3420 { 0x11, "SEC: Short-integer" },
3421 { 0x12, "MAC: Text-value" },
3422 { 0x13, "Creation-date" },
3423 { 0x14, "Modification-date" },
3424 { 0x15, "Read-date" },
3425 { 0x16, "Size: Integer-value" },
3426 { 0x17, "Name (Text-value)" },
3427 { 0x18, "Filename (Text-value)" },
3428 { 0x19, "Start (with multipart/related) (Text-value)" },
3429 { 0x1A, "Start-info (with multipart/related) (Text-value)" },
3430 { 0x1B, "Comment (Text-value)" },
3431 { 0x1C, "Domain (Text-value)" },
3432 { 0x1D, "Path (Text-value)" },
3437 value_string_ext parameter_type_vals_ext = VALUE_STRING_EXT_INIT(parameter_type_vals);
3439 /* Parameter = Untyped-parameter | Typed-parameter
3440 * Untyped-parameter = Token-text ( Integer-value | Text-value )
3443 * ( Integer-value | Date-value | Delta-seconds-value
3444 * | Q-value | Version-value | Uri-value )
3448 * Returns: next offset
3450 * TODO - Verify byte highlighting in case of invalid parameter values
3453 parameter (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start, int len)
3456 guint8 peek = tvb_get_guint8 (tvb,start);
3457 guint32 val = 0, type = 0, type_len, val_len;
3458 const gchar *str = NULL;
3459 const gchar *val_str = NULL;
3463 if (is_token_text (peek)) {
3467 get_token_text (str,tvb,start,val_len,ok); /* Should always succeed */
3468 if (ok) { /* Found a textual parameter name: str */
3470 get_text_value(val_str, tvb, offset, val_len, ok);
3471 if (ok) { /* Also found a textual parameter value: val_str */
3473 if (is_quoted_string(val_str[0])) { /* Add trailing quote! */
3474 if (is_quoted_string(val_str[val_len-2])) {
3475 /* Trailing quote - issue a warning */
3476 ti2 = proto_tree_add_string_format(tree, hf_wsp_parameter_untype_quote_text,
3477 tvb, start, offset - start, val_str,
3478 "%s: %s", str, val_str);
3479 expert_add_info(pinfo, ti2, &ei_wsp_trailing_quote);
3480 proto_item_append_text(ti, "; %s=%s", str, val_str);
3481 } else { /* OK (no trailing quote) */
3482 proto_tree_add_string_format(tree, hf_wsp_parameter_untype_quote_text,
3483 tvb, start, offset - start, val_str,
3484 "%s: %s\"", str, val_str);
3485 proto_item_append_text(ti, "; %s=%s\"", str, val_str);
3487 } else { /* Token-text | 0x00 */
3488 /* TODO - verify that it is either Token-text or 0x00
3489 * and flag with warning if invalid */
3490 proto_tree_add_string_format(tree, hf_wsp_parameter_untype_text,
3491 tvb, start, offset - start, val_str,
3492 "%s: %s", str, val_str);
3493 proto_item_append_text(ti, "; %s=%s", str, val_str);
3495 } else { /* Try integer value */
3496 get_integer_value (val,tvb,offset,val_len,ok);
3497 if (ok) { /* Also found a valid integer parameter value: val */
3499 proto_tree_add_uint_format(tree, hf_wsp_parameter_untype_int, tvb, start, offset - start,
3500 val, "%s: %u", str, val);
3501 proto_item_append_text(ti, "; %s=%u", str, val);
3502 } else { /* Error: neither token-text not Integer-value */
3503 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, offset - start,
3504 "Invalid untyped parameter definition");
3505 offset = start + len; /* Skip to end of buffer */
3512 * Else: Typed parameter
3514 get_integer_value (type,tvb,start,type_len,ok);
3516 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, offset - start,
3517 "Invalid typed parameter definition");
3518 return (start + len); /* Skip to end of buffer */
3521 /* Now offset points to the parameter value */
3522 proto_tree_add_uint(tree, hf_wsp_parameter_type, tvb, start, type_len, type);
3525 case 0x01: /* WSP 1.1 encoding - Charset: Well-known-charset */
3526 get_integer_value(val, tvb, offset, val_len, ok);
3528 val_str = val_to_str_ext(val, &mibenum_vals_character_sets_ext,
3529 "<Unknown character set Identifier %u>");
3530 proto_tree_add_string(tree, hf_parameter_charset,
3531 tvb, offset, val_len, val_str);
3532 proto_item_append_text(ti, "; charset=%s", val_str);
3535 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3536 "Invalid Charset parameter value: invalid Integer-value");
3537 offset = start + len; /* Skip to end of buffer */
3541 case 0x03: /* WSP 1.1 encoding - Type: Integer-value */
3542 get_integer_value (val,tvb,offset,val_len,ok);
3544 proto_tree_add_uint (tree, hf_wsp_parameter_int_type,
3545 tvb, offset, val_len, val);
3546 proto_item_append_text(ti, "; Type=%u", val);
3549 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3550 "Invalid Type parameter value: invalid Integer-value");
3551 offset = start + len; /* Skip to end of buffer */
3555 case 0x05: /* WSP 1.1 encoding - Name: Text-string */
3556 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_name))
3558 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3559 "Invalid Name (WSP 1.1 encoding) parameter value: invalid Text-string");
3560 offset = start + len; /* Skip to end of buffer */
3563 case 0x17: /* WSP 1.4 encoding - Name: Text-value */
3564 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_name))
3566 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3567 "Invalid Name (WSP 1.4 encoding) parameter value: invalid Text-value");
3568 offset = start + len; /* Skip to end of buffer */
3572 case 0x06: /* WSP 1.1 encoding - Filename: Text-string */
3573 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_filename))
3575 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3576 "Invalid Filename (WSP 1.1 encoding) parameter value: invalid Text-string");
3577 offset = start + len; /* Skip to end of buffer */
3580 case 0x18: /* WSP 1.4 encoding - Filename: Text-value */
3581 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_filename))
3583 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3584 "Invalid Filename (WSP 1.4 encoding) parameter value: invalid Text-value");
3585 offset = start + len; /* Skip to end of buffer */
3589 case 0x09: /* WSP 1.2 encoding - Type (special): Constrained-encoding */
3590 /* This is similar to the Content-Type header decoding,
3591 * but it is much simpler:
3592 * Constrained-encoding = Short-integer | Extension-media
3593 * Extension-media = *TEXT <Octet 0>
3595 get_extension_media(val_str,tvb,offset,val_len,ok);
3596 if (ok) { /* Extension-media */
3597 proto_tree_add_string (tree, hf_wsp_parameter_upart_type,
3598 tvb, offset, val_len, val_str);
3599 proto_item_append_text(ti, "; type=%s", val_str);
3602 get_short_integer(val,tvb,offset,val_len,ok);
3604 proto_tree_add_string (tree, hf_wsp_parameter_upart_type,
3605 tvb, offset, val_len, val_to_str_ext(val, &vals_content_types_ext,
3606 "(Unknown content type identifier 0x%X)"));
3608 } /* Else: invalid parameter value */
3611 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3612 "Invalid Type parameter value: invalid Constrained-encoding");
3613 offset = start + len; /* Skip the parameters */
3617 case 0x0A: /* WSP 1.2 encoding - Start: Text-string */
3618 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_start))
3620 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3621 "Invalid Start (WSP 1.2 encoding) parameter value: invalid Text-string");
3622 offset = start + len; /* Skip to end of buffer */
3625 case 0x19: /* WSP 1.4 encoding - Start (with multipart/related): Text-value */
3626 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_start))
3628 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3629 "Invalid Start (with multipart/related) parameter value: invalid Text-value");
3630 offset = start + len; /* Skip to end of buffer */
3634 case 0x0B: /* WSP 1.2 encoding - Start-info: Text-string */
3635 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_start_info))
3637 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3638 "Invalid Start-info (WSP 1.2 encoding) parameter value: invalid Text-string");
3639 offset = start + len; /* Skip to end of buffer */
3642 case 0x1A: /* WSP 1.4 encoding - Start-info (with multipart/related): Text-value */
3643 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_start_info))
3645 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3646 "Invalid Start-info (WSP 1.4 encoding) parameter value: invalid Text-value");
3647 offset = start + len; /* Skip to end of buffer */
3651 case 0x0C: /* WSP 1.3 encoding - Comment: Text-string */
3652 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_comment))
3654 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3655 "Invalid Comment (WSP 1.3 encoding) parameter value: invalid Text-string");
3656 offset = start + len; /* Skip to end of buffer */
3659 case 0x1B: /* WSP 1.4 encoding - Comment: Text-value */
3660 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_comment))
3662 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3663 "Invalid Comment (WSP 1.4 encoding) parameter value: invalid Text-value");
3664 offset = start + len; /* Skip to end of buffer */
3668 case 0x0D: /* WSP 1.3 encoding - Domain: Text-string */
3669 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_domain))
3671 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3672 "Invalid Domain (WSP 1.3 encoding) parameter value: invalid Text-string");
3673 offset = start + len; /* Skip to end of buffer */
3676 case 0x1C: /* WSP 1.4 encoding - Domain: Text-value */
3677 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_domain))
3679 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3680 "Invalid Domain (WSP 1.4 encoding) parameter value: invalid Text-value");
3681 offset = start + len; /* Skip to end of buffer */
3685 case 0x0F: /* WSP 1.3 encoding - Path: Text-string */
3686 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_path))
3688 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3689 "Invalid Path (WSP 1.3 encoding) parameter value: invalid Text-string");
3690 offset = start + len; /* Skip to end of buffer */
3693 case 0x1D: /* WSP 1.4 encoding - Path: Text-value */
3694 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_path))
3696 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3697 "Invalid Path (WSP 1.4 encoding) parameter value: invalid Text-value");
3698 offset = start + len; /* Skip to end of buffer */
3702 case 0x11: /* WSP 1.4 encoding - SEC: Short-integer (OCTET) */
3703 peek = tvb_get_guint8 (tvb, start+1);
3704 if (peek & 0x80) { /* Valid Short-integer */
3706 proto_tree_add_uint (tree, hf_wsp_parameter_sec,
3707 tvb, offset, 1, peek);
3708 proto_item_append_text(ti, "; SEC=%s", val_to_str_ext_const(peek, &vals_wsp_parameter_sec_ext, "Undefined"));
3710 } else { /* Error */
3711 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3712 "Invalid SEC parameter value: invalid Short-integer-value");
3713 offset = start + len; /* Skip to end of buffer */
3717 case 0x12: /* WSP 1.4 encoding - MAC: Text-value */
3718 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_mac))
3720 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3721 "Invalid MAC (WSP 1.4 encoding) parameter value: invalid Text-value");
3722 offset = start + len; /* Skip to end of buffer */
3726 case 0x02: /* WSP 1.1 encoding - Level: Version-value */
3727 get_version_value(val,str,tvb,offset,val_len,ok);
3729 proto_tree_add_string (tree, hf_wsp_parameter_level,
3730 tvb, offset, val_len, str);
3731 proto_item_append_text(ti, "; level=%s", str);
3734 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3735 "Invalid Level parameter value: invalid Version-value");
3736 offset = start + len; /* Skip to end of buffer */
3740 case 0x00: /* WSP 1.1 encoding - Q: Q-value */
3741 offset = parameter_value_q(tree, pinfo, ti, tvb, offset);
3744 case 0x16: /* WSP 1.4 encoding - Size: Integer-value */
3745 get_integer_value (val,tvb,offset,val_len,ok);
3747 proto_tree_add_uint (tree, hf_wsp_parameter_size,
3748 tvb, offset, val_len, val);
3749 proto_item_append_text(ti, "; Size=%u", val);
3752 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len,
3753 "Invalid Size parameter value: invalid Integer-value");
3754 offset = start + len; /* Skip to end of buffer */
3762 case 0x07: /* WSP 1.1 encoding - Differences: Field-name */
3763 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start,
3764 "Undecoded parameter Differences");
3765 offset = start + len; /* Skip the parameters */
3768 case 0x08: /* WSP 1.1 encoding - Padding: Short-integer */
3769 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start,
3770 "Undecoded parameter Padding");
3771 offset = start + len; /* Skip the parameters */
3774 case 0x0E: /* WSP 1.3 encoding - Max-Age: Delta-seconds-value */
3775 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start,
3776 "Undecoded parameter Max-Age");
3777 offset = start + len; /* Skip the parameters */
3780 case 0x10: /* WSP 1.3 encoding - Secure: No-value */
3781 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start,
3782 "Undecoded parameter Secure");
3783 offset = start + len; /* Skip the parameters */
3786 case 0x13: /* WSP 1.4 encoding - Creation-date: Date-value */
3787 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start,
3788 "Undecoded parameter Creation-Date");
3789 offset = start + len; /* Skip the parameters */
3792 case 0x14: /* WSP 1.4 encoding - Modification-date: Date-value */
3793 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start,
3794 "Undecoded parameter Modification-Date");
3795 offset = start + len; /* Skip the parameters */
3798 case 0x15: /* WSP 1.4 encoding - Read-date: Date-value */
3799 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start,
3800 "Undecoded parameter Read-Date");
3801 offset = start + len; /* Skip the parameters */
3805 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start,
3806 "Undecoded parameter type 0x%02x", type);
3807 offset = start + len; /* Skip the parameters */
3815 * Dissects the Q-value parameter value.
3817 * Returns: next offset
3820 parameter_value_q (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start)
3823 guint32 val = 0, val_len;
3827 get_uintvar_integer (val, tvb, offset, val_len, ok);
3828 if (ok && (val < 1100)) {
3829 if (val <= 100) { /* Q-value in 0.01 steps */
3830 str = wmem_strdup_printf(wmem_packet_scope(), "0.%02u", val - 1);
3831 } else { /* Q-value in 0.001 steps */
3832 str = wmem_strdup_printf(wmem_packet_scope(), "0.%03u", val - 100);
3834 proto_item_append_text(ti, "; q=%s", str);
3835 proto_tree_add_string (tree, hf_parameter_q,
3836 tvb, start, val_len, str);
3839 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, offset,
3840 "Invalid Q parameter value: invalid Q-value");
3846 static const int * address_length_flags[] = {
3847 &hf_address_flags_length_bearer_type_included,
3848 &hf_address_flags_length_port_number_included,
3849 &hf_address_flags_length_address_len,
3853 /* Code to actually dissect the packets */
3859 /* Dissect a WSP redirect PDU.
3860 * Looks up or builds conversations, so parts of the code must always run,
3861 * even if tree is NULL.
3864 dissect_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo,
3865 proto_tree *tree, dissector_handle_t dissector_handle)
3868 proto_tree *addresses_tree = NULL;
3869 proto_tree *addr_tree = NULL;
3871 guint8 address_flags_len;
3874 guint32 address_ipv4;
3875 ws_in6_addr address_ipv6;
3876 address redir_address;
3877 conversation_t *conv;
3878 guint32 idx = 0; /* Address index */
3879 guint32 address_record_len; /* Length of the entire address record */
3880 static const int * flags[] = {
3881 &hf_wsp_redirect_permanent,
3882 &hf_wsp_redirect_reuse_security_session,
3890 proto_tree_add_bitmask(tree, tvb, offset, hf_wsp_redirect_flags, ett_redirect_flags, flags, ENC_NA);
3894 * Redirect addresses.
3897 ti = proto_tree_add_item(tree, hf_redirect_addresses,
3898 tvb, 0, -1, ENC_NA);
3899 addresses_tree = proto_item_add_subtree(ti, ett_addresses);
3902 while (tvb_reported_length_remaining (tvb, offset) > 0) {
3905 * Read a single address at a time.
3907 address_flags_len = tvb_get_guint8 (tvb, offset);
3908 address_len = address_flags_len & ADDRESS_LEN;
3909 address_record_len = address_len
3910 + (address_flags_len & BEARER_TYPE_INCLUDED ? 1 : 0)
3911 + (address_flags_len & PORT_NUMBER_INCLUDED ? 2 : 0)
3914 ti = proto_tree_add_uint(addresses_tree, hf_address_entry,
3915 tvb, offset, 1 + address_record_len, idx);
3916 addr_tree = proto_item_add_subtree(ti, ett_address);
3918 proto_tree_add_bitmask(addr_tree, tvb, offset, hf_address_flags_length, ett_address_flags, address_length_flags, ENC_NA);
3920 if (address_flags_len & BEARER_TYPE_INCLUDED) {
3921 bearer_type = tvb_get_guint8 (tvb, offset);
3922 proto_tree_add_uint (addr_tree, hf_address_bearer_type,
3923 tvb, offset, 1, bearer_type);
3926 bearer_type = 0x00; /* XXX */
3928 if (address_flags_len & PORT_NUMBER_INCLUDED) {
3929 port_num = tvb_get_ntohs (tvb, offset);
3930 proto_tree_add_uint (addr_tree, hf_address_port_num,
3931 tvb, offset, 2, port_num);
3935 * Redirecting to the same server port number as was
3936 * being used, i.e. the source port number of this
3939 port_num = pinfo->srcport;
3941 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
3943 * We don't have the bearer type in the message,
3944 * so we don't know the address type.
3945 * (It's the same bearer type as the original
3948 goto unknown_address_type;
3952 * We know the bearer type, so we know the address type.
3954 switch (bearer_type) {
3958 case BT_IS_95_PACKET_DATA:
3959 case BT_ANSI_136_CSD:
3960 case BT_ANSI_136_PACKET_DATA:
3963 case BT_GSM_USSD_IPv4:
3966 case BT_PDC_PACKET_DATA:
3968 case BT_IDEN_PACKET_DATA:
3970 case BT_TETRA_PACKET_DATA:
3974 if (address_len != 4) {
3978 goto unknown_address_type;
3980 address_ipv4 = tvb_get_ipv4(tvb, offset);
3982 proto_tree_add_ipv4 (addr_tree,
3983 hf_address_ipv4_addr,
3984 tvb, offset, 4, address_ipv4);
3988 * Create a conversation so that the
3989 * redirected session will be dissected
3992 redir_address.type = AT_IPv4;
3993 redir_address.len = 4;
3994 redir_address.data = (const guint8 *)&address_ipv4;
3995 /* Find a conversation based on redir_address and pinfo->dst */
3996 conv = find_conversation(pinfo->num, &redir_address, &pinfo->dst,
3997 ENDPOINT_UDP, port_num, 0, NO_PORT_B);
3998 if (conv == NULL) { /* This conversation does not exist yet */
3999 conv = conversation_new(pinfo->num, &redir_address,
4000 &pinfo->dst, ENDPOINT_UDP, port_num, 0, NO_PORT2);
4002 /* Apply WSP dissection to the conversation */
4003 conversation_set_dissector(conv, dissector_handle);
4010 if (address_len != 16) {
4014 goto unknown_address_type;
4016 tvb_get_ipv6(tvb, offset, &address_ipv6);
4018 proto_tree_add_ipv6 (addr_tree,
4019 hf_address_ipv6_addr,
4020 tvb, offset, 16, &address_ipv6);
4024 * Create a conversation so that the
4025 * redirected session will be dissected
4028 redir_address.type = AT_IPv6;
4029 redir_address.len = 16;
4030 redir_address.data = (const guint8 *)&address_ipv6;
4031 /* Find a conversation based on redir_address and pinfo->dst */
4032 conv = find_conversation(pinfo->num, &redir_address, &pinfo->dst,
4033 ENDPOINT_UDP, port_num, 0, NO_PORT_B);
4034 if (conv == NULL) { /* This conversation does not exist yet */
4035 conv = conversation_new(pinfo->num, &redir_address,
4036 &pinfo->dst, ENDPOINT_UDP, port_num, 0, NO_PORT2);
4038 /* Apply WSP dissection to the conversation */
4039 conversation_set_dissector(conv, dissector_handle);
4042 unknown_address_type:
4044 if (address_len != 0) {
4046 proto_tree_add_item (addr_tree, hf_address_addr,
4047 tvb, offset, address_len, ENC_NA);
4052 offset += address_len;
4056 /* Add addresses to the protocol tree.
4057 * This is a display-only function, so return if tree is NULL
4060 add_addresses(proto_tree *tree, tvbuff_t *tvb, int hf)
4063 proto_tree *addresses_tree;
4064 proto_tree *addr_tree;
4066 guint8 address_flags_len;
4068 guint32 tvb_len = tvb_reported_length(tvb);
4070 guint32 idx = 0; /* Address index */
4071 guint32 address_record_len; /* Length of the entire address record */
4073 /* Skip needless processing */
4076 if (offset >= tvb_len)
4082 /* XXX: the field pointed to by hf has a type of FT_NONE */
4083 ti = proto_tree_add_item(tree, hf, tvb, 0, -1, ENC_NA);
4084 addresses_tree = proto_item_add_subtree(ti, ett_addresses);
4086 while (offset < tvb_len) {
4089 * Read a single address at a time.
4091 address_flags_len = tvb_get_guint8 (tvb, offset);
4092 address_len = address_flags_len & ADDRESS_LEN;
4093 address_record_len = address_len
4094 + (address_flags_len & BEARER_TYPE_INCLUDED ? 1 : 0)
4095 + (address_flags_len & PORT_NUMBER_INCLUDED ? 2 : 0)
4098 ti = proto_tree_add_uint(addresses_tree, hf_address_entry,
4099 tvb, offset, 1 + address_record_len, idx);
4100 addr_tree = proto_item_add_subtree(ti, ett_address);
4102 proto_tree_add_bitmask(addr_tree, tvb, offset, hf_address_flags_length, ett_address_flags, address_length_flags, ENC_NA);
4104 if (address_flags_len & BEARER_TYPE_INCLUDED) {
4105 bearer_type = tvb_get_guint8 (tvb, offset);
4106 proto_tree_add_uint (addr_tree, hf_address_bearer_type,
4107 tvb, offset, 1, bearer_type);
4110 bearer_type = 0x00; /* XXX */
4112 if (address_flags_len & PORT_NUMBER_INCLUDED) {
4113 proto_tree_add_uint (addr_tree, hf_address_port_num,
4114 tvb, offset, 2, ENC_BIG_ENDIAN);
4117 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
4119 * We don't have the bearer type in the message,
4120 * so we don't know the address type.
4121 * (It's the same bearer type as the original
4124 goto unknown_address_type;
4128 * We know the bearer type, so we know the address type.
4130 switch (bearer_type) {
4134 case BT_IS_95_PACKET_DATA:
4135 case BT_ANSI_136_CSD:
4136 case BT_ANSI_136_PACKET_DATA:
4139 case BT_GSM_USSD_IPv4:
4142 case BT_PDC_PACKET_DATA:
4144 case BT_IDEN_PACKET_DATA:
4146 case BT_TETRA_PACKET_DATA:
4150 if (address_len != 4) {
4154 goto unknown_address_type;
4156 proto_tree_add_item (addr_tree, hf_address_ipv4_addr,
4157 tvb, offset, 4, ENC_NA);
4164 if (address_len != 16) {
4168 goto unknown_address_type;
4170 proto_tree_add_item (addr_tree, hf_address_ipv6_addr,
4171 tvb, offset, 16, ENC_NA);
4174 unknown_address_type:
4176 if (address_len != 0) {
4177 proto_tree_add_item (addr_tree, hf_address_addr,
4178 tvb, offset, address_len, ENC_NA);
4182 offset += address_len;
4186 /* Define a pointer to function data type for the well-known header
4187 * lookup table below */
4188 typedef guint32 (*hdr_parse_func_ptr) (proto_tree *, tvbuff_t *, guint32, packet_info *);
4190 /* Lookup table for well-known header parsing functions */
4191 static const hdr_parse_func_ptr WellKnownHeader[128] = {
4192 /* 0x00 */ wkh_accept, /* 0x01 */ wkh_accept_charset,
4193 /* 0x02 */ wkh_accept_encoding, /* 0x03 */ wkh_accept_language,
4194 /* 0x04 */ wkh_accept_ranges, /* 0x05 */ wkh_age,
4195 /* 0x06 */ wkh_allow, /* 0x07 */ wkh_authorization,
4196 /* 0x08 */ wkh_cache_control, /* 0x09 */ wkh_connection,
4197 /* 0x0A */ wkh_content_base, /* 0x0B */ wkh_content_encoding,
4198 /* 0x0C */ wkh_content_language, /* 0x0D */ wkh_content_length,
4199 /* 0x0E */ wkh_content_location, /* 0x0F */ wkh_content_md5,
4200 /* 0x10 */ wkh_content_range, /* 0x11 */ wkh_content_type,
4201 /* 0x12 */ wkh_date, /* 0x13 */ wkh_etag,
4202 /* 0x14 */ wkh_expires, /* 0x15 */ wkh_from,
4203 /* 0x16 */ wkh_host, /* 0x17 */ wkh_if_modified_since,
4204 /* 0x18 */ wkh_if_match, /* 0x19 */ wkh_if_none_match,
4205 /* 0x1A */ wkh_if_range, /* 0x1B */ wkh_if_unmodified_since,
4206 /* 0x1C */ wkh_location, /* 0x1D */ wkh_last_modified,
4207 /* 0x1E */ wkh_max_forwards, /* 0x1F */ wkh_pragma,
4208 /* 0x20 */ wkh_proxy_authenticate, /* 0x21 */ wkh_proxy_authorization,
4209 /* 0x22 */ wkh_public, /* 0x23 */ wkh_range,
4210 /* 0x24 */ wkh_referer, /* 0x25 */ wkh_default,
4211 /* 0x26 */ wkh_server, /* 0x27 */ wkh_transfer_encoding,
4212 /* 0x28 */ wkh_upgrade, /* 0x29 */ wkh_user_agent,
4213 /* 0x2A */ wkh_vary, /* 0x2B */ wkh_via,
4214 /* 0x2C */ wkh_warning, /* 0x2D */ wkh_www_authenticate,
4215 /* 0x2E */ wkh_content_disposition,/* 0x2F */ wkh_x_wap_application_id,
4216 /* 0x30 */ wkh_content_uri, /* 0x31 */ wkh_initiator_uri,
4217 /* 0x32 */ wkh_accept_application, /* 0x33 */ wkh_bearer_indication,
4218 /* 0x34 */ wkh_push_flag, /* 0x35 */ wkh_profile,
4219 /* 0x36 */ wkh_profile_diff_wbxml, /* 0x37 */ wkh_profile_warning,
4220 /* 0x38 */ wkh_default, /* 0x39 */ wkh_te,
4221 /* 0x3A */ wkh_trailer, /* 0x3B */ wkh_accept_charset,
4222 /* 0x3C */ wkh_accept_encoding, /* 0x3D */ wkh_cache_control,
4223 /* 0x3E */ wkh_content_range, /* 0x3F */ wkh_x_wap_tod,
4224 /* 0x40 */ wkh_content_id, /* 0x41 */ wkh_default,
4225 /* 0x42 */ wkh_default, /* 0x43 */ wkh_encoding_version,
4226 /* 0x44 */ wkh_profile_warning, /* 0x45 */ wkh_content_disposition,
4227 /* 0x46 */ wkh_x_wap_security, /* 0x47 */ wkh_cache_control,
4228 /*******************************************************
4229 *** The following headers are not (yet) registered. ***
4230 *******************************************************/
4231 /* 0x48 */ wkh_default, /* 0x49 */ wkh_default,
4232 /* 0x4A */ wkh_default, /* 0x4B */ wkh_default,
4233 /* 0x4C */ wkh_default, /* 0x4D */ wkh_default,
4234 /* 0x4E */ wkh_default, /* 0x4F */ wkh_default,
4235 /* 0x50 */ wkh_default, /* 0x51 */ wkh_default,
4236 /* 0x52 */ wkh_default, /* 0x53 */ wkh_default,
4237 /* 0x54 */ wkh_default, /* 0x55 */ wkh_default,
4238 /* 0x56 */ wkh_default, /* 0x57 */ wkh_default,
4239 /* 0x58 */ wkh_default, /* 0x59 */ wkh_default,
4240 /* 0x5A */ wkh_default, /* 0x5B */ wkh_default,
4241 /* 0x5C */ wkh_default, /* 0x5D */ wkh_default,
4242 /* 0x5E */ wkh_default, /* 0x5F */ wkh_default,
4243 /* 0x60 */ wkh_default, /* 0x61 */ wkh_default,
4244 /* 0x62 */ wkh_default, /* 0x63 */ wkh_default,
4245 /* 0x64 */ wkh_default, /* 0x65 */ wkh_default,
4246 /* 0x66 */ wkh_default, /* 0x67 */ wkh_default,
4247 /* 0x68 */ wkh_default, /* 0x69 */ wkh_default,
4248 /* 0x6A */ wkh_default, /* 0x6B */ wkh_default,
4249 /* 0x6C */ wkh_default, /* 0x6D */ wkh_default,
4250 /* 0x6E */ wkh_default, /* 0x6F */ wkh_default,
4251 /* 0x70 */ wkh_default, /* 0x71 */ wkh_default,
4252 /* 0x72 */ wkh_default, /* 0x73 */ wkh_default,
4253 /* 0x74 */ wkh_default, /* 0x75 */ wkh_default,
4254 /* 0x76 */ wkh_default, /* 0x77 */ wkh_default,
4255 /* 0x78 */ wkh_default, /* 0x79 */ wkh_default,
4256 /* 0x7A */ wkh_default, /* 0x7B */ wkh_default,
4257 /* 0x7C */ wkh_default, /* 0x7D */ wkh_default,
4258 /* 0x7E */ wkh_default, /* 0x7F */ wkh_default,
4261 /* Lookup table for well-known header parsing functions */
4262 static const hdr_parse_func_ptr WellKnownOpenwaveHeader[128] = {
4263 /* 0x00 */ wkh_openwave_default,
4264 /* 0x01 */ wkh_openwave_x_up_proxy_push_accept,
4265 /* 0x02 */ wkh_openwave_x_up_proxy_push_seq,
4266 /* 0x03 */ wkh_openwave_x_up_proxy_notify,
4267 /* 0x04 */ wkh_openwave_x_up_proxy_operator_domain,
4268 /* 0x05 */ wkh_openwave_x_up_proxy_home_page,
4269 /* 0x06 */ wkh_openwave_x_up_devcap_has_color,
4270 /* 0x07 */ wkh_openwave_x_up_devcap_num_softkeys,
4271 /* 0x08 */ wkh_openwave_x_up_devcap_softkey_size,
4272 /* 0x09 */ wkh_openwave_x_up_devcap_screen_chars,
4273 /* 0x0A */ wkh_openwave_x_up_devcap_screen_pixels,
4274 /* 0x0B */ wkh_openwave_x_up_devcap_em_size,
4275 /* 0x0C */ wkh_openwave_x_up_devcap_screen_depth,
4276 /* 0x0D */ wkh_openwave_x_up_devcap_immed_alert,
4277 /* 0x0E */ wkh_openwave_x_up_proxy_net_ask,
4278 /* 0x0F */ wkh_openwave_x_up_proxy_uplink_version,
4279 /* 0x10 */ wkh_openwave_x_up_proxy_tod,
4280 /* 0x11 */ wkh_openwave_x_up_proxy_ba_enable,
4281 /* 0x12 */ wkh_openwave_x_up_proxy_ba_realm,
4282 /* 0x13 */ wkh_openwave_x_up_proxy_redirect_enable,
4283 /* 0x14 */ wkh_openwave_x_up_proxy_request_uri,
4284 /* 0x15 */ wkh_openwave_x_up_proxy_redirect_status,
4285 /* 0x16 */ wkh_openwave_x_up_proxy_trans_charset,
4286 /* 0x17 */ wkh_openwave_x_up_proxy_linger,
4287 /* 0x18 */ wkh_openwave_default,
4288 /* 0x19 */ wkh_openwave_x_up_proxy_enable_trust,
4289 /* 0x1A */ wkh_openwave_x_up_proxy_trust,
4290 /* 0x1B */ wkh_openwave_default,
4291 /* 0x1C */ wkh_openwave_default,
4292 /* 0x1D */ wkh_openwave_default,
4293 /* 0x1E */ wkh_openwave_default,
4294 /* 0x1F */ wkh_openwave_default,
4295 /* 0x20 */ wkh_openwave_x_up_proxy_trust,
4296 /* 0x21 */ wkh_openwave_x_up_proxy_bookmark,
4297 /* 0x22 */ wkh_openwave_x_up_devcap_gui,
4298 /*******************************************************
4299 *** The following headers are not (yet) registered. ***
4300 *******************************************************/
4301 /* 0x23 */ wkh_openwave_default,
4302 /* 0x24 */ wkh_openwave_default, /* 0x25 */ wkh_openwave_default,
4303 /* 0x26 */ wkh_openwave_default, /* 0x27 */ wkh_openwave_default,
4304 /* 0x28 */ wkh_openwave_default, /* 0x29 */ wkh_openwave_default,
4305 /* 0x2A */ wkh_openwave_default, /* 0x2B */ wkh_openwave_default,
4306 /* 0x2C */ wkh_openwave_default, /* 0x2D */ wkh_openwave_default,
4307 /* 0x2E */ wkh_openwave_default, /* 0x2F */ wkh_openwave_default,
4308 /* 0x30 */ wkh_openwave_default, /* 0x31 */ wkh_openwave_default,
4309 /* 0x32 */ wkh_openwave_default, /* 0x33 */ wkh_openwave_default,
4310 /* 0x34 */ wkh_openwave_default, /* 0x35 */ wkh_openwave_default,
4311 /* 0x36 */ wkh_openwave_default, /* 0x37 */ wkh_openwave_default,
4312 /* 0x38 */ wkh_openwave_default, /* 0x39 */ wkh_openwave_default,
4313 /* 0x3A */ wkh_openwave_default, /* 0x3B */ wkh_openwave_default,
4314 /* 0x3C */ wkh_openwave_default, /* 0x3D */ wkh_openwave_default,
4315 /* 0x3E */ wkh_openwave_default, /* 0x3F */ wkh_openwave_default,
4316 /* 0x40 */ wkh_openwave_default, /* 0x41 */ wkh_openwave_default,
4317 /* 0x42 */ wkh_openwave_default, /* 0x43 */ wkh_openwave_default,
4318 /* 0x44 */ wkh_openwave_default, /* 0x45 */ wkh_openwave_default,
4319 /* 0x46 */ wkh_openwave_default, /* 0x47 */ wkh_openwave_default,
4320 /* 0x48 */ wkh_openwave_default, /* 0x49 */ wkh_openwave_default,
4321 /* 0x4A */ wkh_openwave_default, /* 0x4B */ wkh_openwave_default,
4322 /* 0x4C */ wkh_openwave_default, /* 0x4D */ wkh_openwave_default,
4323 /* 0x4E */ wkh_openwave_default, /* 0x4F */ wkh_openwave_default,
4324 /* 0x50 */ wkh_openwave_default, /* 0x51 */ wkh_openwave_default,
4325 /* 0x52 */ wkh_openwave_default, /* 0x53 */ wkh_openwave_default,
4326 /* 0x54 */ wkh_openwave_default, /* 0x55 */ wkh_openwave_default,
4327 /* 0x56 */ wkh_openwave_default, /* 0x57 */ wkh_openwave_default,
4328 /* 0x58 */ wkh_openwave_default, /* 0x59 */ wkh_openwave_default,
4329 /* 0x5A */ wkh_openwave_default, /* 0x5B */ wkh_openwave_default,
4330 /* 0x5C */ wkh_openwave_default, /* 0x5D */ wkh_openwave_default,
4331 /* 0x5E */ wkh_openwave_default, /* 0x5F */ wkh_openwave_default,
4332 /* 0x60 */ wkh_openwave_default, /* 0x61 */ wkh_openwave_default,
4333 /* 0x62 */ wkh_openwave_default, /* 0x63 */ wkh_openwave_default,
4334 /* 0x64 */ wkh_openwave_default, /* 0x65 */ wkh_openwave_default,
4335 /* 0x66 */ wkh_openwave_default, /* 0x67 */ wkh_openwave_default,
4336 /* 0x68 */ wkh_openwave_default, /* 0x69 */ wkh_openwave_default,
4337 /* 0x6A */ wkh_openwave_default, /* 0x6B */ wkh_openwave_default,
4338 /* 0x6C */ wkh_openwave_default, /* 0x6D */ wkh_openwave_default,
4339 /* 0x6E */ wkh_openwave_default, /* 0x6F */ wkh_openwave_default,
4340 /* 0x70 */ wkh_openwave_default, /* 0x71 */ wkh_openwave_default,
4341 /* 0x72 */ wkh_openwave_default, /* 0x73 */ wkh_openwave_default,
4342 /* 0x74 */ wkh_openwave_default, /* 0x75 */ wkh_openwave_default,
4343 /* 0x76 */ wkh_openwave_default, /* 0x77 */ wkh_openwave_default,
4344 /* 0x78 */ wkh_openwave_default, /* 0x79 */ wkh_openwave_default,
4345 /* 0x7A */ wkh_openwave_default, /* 0x7B */ wkh_openwave_default,
4346 /* 0x7C */ wkh_openwave_default, /* 0x7D */ wkh_openwave_default,
4347 /* 0x7E */ wkh_openwave_default, /* 0x7F */ wkh_openwave_default
4352 /* WSP header format
4353 * 1st byte: 0x00 : <Not allowed>
4354 * 1st byte: 0x01 -- 0x1F: <Shorthand Header Code Page switch>
4355 * 1st byte: 0x20 -- 0x7E: <Textual header (C string)>
4356 * Followed with: <Textual header value (C string)>
4357 * 1st byte: 0x7F : <Header Code Page switch>
4358 * Followed with: 2nd byte: <Header Code Page>
4359 * 1st byte: 0x80 -- 0xFF: <Binary header (7-bit encoded ID)>
4361 * 2nd byte: 0x00 -- 0x1E: <Value Length (bytes)>
4362 * Followed with: <Len> bytes of data
4363 * 2nd byte: 0x1F : <Value Length is a guintvar>
4364 * Followed with: <guintvar Len>
4365 * Followed with: <Len> bytes of data
4366 * 2nd byte: 0x20 -- 0x7F: <Textual header value (C string)>
4367 * 2nd byte: 0x80 -- 0xFF: <Binary value (7-bit encoded ID)>
4370 add_headers (proto_tree *tree, tvbuff_t *tvb, int hf, packet_info *pinfo)
4372 guint8 hdr_id, val_id, codepage = 1;
4373 gint32 tvb_len = tvb_reported_length(tvb);
4376 gint32 hdr_len, hdr_start;
4377 gint32 val_len, val_start;
4378 gchar *hdr_str, *val_str;
4379 proto_tree *wsp_headers;
4380 proto_item *ti, *hidden_item;
4384 if (offset >= tvb_len)
4385 return; /* No headers! */
4387 /* XXX: the field pointed to by hf has a type of FT_NONE */
4388 ti = proto_tree_add_item(tree, hf,
4389 tvb, offset, tvb_len, ENC_NA);
4390 wsp_headers = proto_item_add_subtree(ti, ett_headers);
4392 while (offset < tvb_len) {
4394 hdr_id = tvb_get_guint8(tvb, offset);
4395 if (hdr_id & 0x80) { /* Well-known header */
4397 /* Call header value dissector for given header */
4398 if (codepage == 1) { /* Default header code page */
4399 save_offset = offset;
4400 offset = WellKnownHeader[hdr_id & 0x7F](wsp_headers, tvb,
4402 /* Make sure we're progressing forward */
4403 if (save_offset <= offset) {
4404 expert_add_info(pinfo, ti, &ei_wsp_header_invalid);
4407 } else { /* Openwave header code page */
4408 /* Here I'm delibarately assuming that Openwave is the only
4409 * company that defines a WSP header code page. */
4410 save_offset = offset;
4411 offset = WellKnownOpenwaveHeader[hdr_id & 0x7F](wsp_headers,
4412 tvb, hdr_start, pinfo);
4413 /* Make sure we're progressing forward */
4414 if (save_offset <= offset) {
4415 expert_add_info(pinfo, ti, &ei_wsp_header_invalid);
4419 } else if (hdr_id == 0x7F) { /* HCP shift sequence */
4420 codepage = tvb_get_guint8(tvb, offset+1);
4421 proto_tree_add_uint(wsp_headers, hf_wsp_header_shift_code,
4422 tvb, offset, 2, codepage);
4424 } else if (hdr_id >= 0x20) { /* Textual header */
4425 /* Header name MUST be NUL-ended string ==> tvb_get_stringz_enc() */
4426 hdr_str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, hdr_start, (gint *)&hdr_len, ENC_ASCII);
4427 val_start = hdr_start + hdr_len;
4428 val_id = tvb_get_guint8(tvb, val_start);
4429 /* Call header value dissector for given header */
4430 if (val_id >= 0x20 && val_id <=0x7E) { /* OK! */
4431 val_str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (gint *)&val_len, ENC_ASCII);
4432 offset = val_start + val_len;
4433 proto_tree_add_string_format(wsp_headers, hf_wsp_header_text_value, tvb, hdr_start, offset-hdr_start,
4434 val_str, "%s: %s", hdr_str, val_str);
4436 /* Old-style X-WAP-TOD uses a non-textual value
4437 * after a textual header. */
4438 if (g_ascii_strcasecmp(hdr_str, "x-wap.tod") == 0) {
4439 get_delta_seconds_value(val, tvb, val_start, val_len, ok);
4442 t.secs = (time_t)val;
4445 ti = proto_tree_add_time_format_value(wsp_headers, hf_hdr_x_wap_tod,
4446 tvb, hdr_start, hdr_len + val_len, &t,
4447 "Requesting Time Of Day");
4449 ti = proto_tree_add_time(wsp_headers, hf_hdr_x_wap_tod,
4450 tvb, hdr_start, hdr_len + val_len, &t);
4452 expert_add_info(pinfo, ti, &ei_hdr_x_wap_tod);
4454 /* I prefer using X-Wap-Tod to the real hdr_str */
4455 proto_tree_add_expert_format(wsp_headers, pinfo, &ei_wsp_text_field_invalid,
4456 tvb, hdr_start, hdr_len + val_len,
4457 "Invalid value for the 'X-Wap-Tod' header");
4461 proto_tree_add_expert_format(wsp_headers, pinfo, &ei_wsp_text_field_invalid, tvb, hdr_start, hdr_len,
4462 "Invalid value for the textual '%s' header (should be a textual value)",
4467 hidden_item = proto_tree_add_string(wsp_headers, hf_hdr_name_string,
4468 tvb, hdr_start, offset - hdr_start, hdr_str);
4469 PROTO_ITEM_SET_HIDDEN(hidden_item);
4470 } else if (hdr_id > 0) { /* Shorthand HCP switch */
4472 proto_tree_add_uint (wsp_headers, hf_wsp_header_shift_code,
4473 tvb, offset, 1, codepage);
4476 proto_tree_add_expert_format (wsp_headers, pinfo, &ei_wsp_text_field_invalid, tvb, hdr_start, 1,
4477 "Invalid zero-length textual header");
4484 static const value_string vals_sir_protocol_options[] = {
4485 { 0, "OTA-HTTP, no CPITag present" },
4486 { 1, "OTA-HTTP, CPITag present" },
4487 /* 2--255 are reserved */
4488 /* 256--16383 are available for private WINA registration */
4494 /* Dissect a Session Initiation Request.
4496 * Arguably this should be a separate dissector, but SIR does not make sense
4497 * outside of WSP anyway.
4500 dissect_sir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4504 guint32 val_len_save;
4509 proto_tree *subtree;
4512 /* Append status code to INFO column */
4513 col_append_str(pinfo->cinfo, COL_INFO, ": WAP Session Initiation Request");
4515 ti = proto_tree_add_item(tree, hf_sir_section,
4516 tvb, 0, -1, ENC_NA);
4517 subtree = proto_item_add_subtree(ti, ett_sir);
4520 version = tvb_get_guint8(tvb, 0);
4521 proto_tree_add_uint(subtree, hf_sir_version,
4522 tvb, 0, 1, version);
4524 /* Length of Application-Id headers list */
4525 val_len = tvb_get_guintvar(tvb, 1, &len, pinfo, &ei_wsp_oversized_uintvar);
4526 proto_tree_add_uint(subtree, hf_sir_app_id_list_len,
4527 tvb, 1, len, val_len);
4529 /* Application-Id headers */
4530 tmp_tvb = tvb_new_subset_length(tvb, offset, val_len);
4531 add_headers (subtree, tmp_tvb, hf_sir_app_id_list, pinfo);
4534 /* Length of WSP contact points list */
4535 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
4536 proto_tree_add_uint(subtree, hf_sir_wsp_contact_points_len,
4537 tvb, offset, len, val_len);
4539 /* WSP contact point list */
4540 tmp_tvb = tvb_new_subset_length (tvb, offset, val_len);
4541 add_addresses(subtree, tmp_tvb, hf_sir_wsp_contact_points);
4543 /* End of version 0 SIR content */
4549 /* Length of non-WSP contact points list */
4550 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
4551 proto_tree_add_uint(subtree, hf_sir_contact_points_len,
4552 tvb, offset, len, val_len);
4554 /* Non-WSP contact point list */
4555 tmp_tvb = tvb_new_subset_length(tvb, offset, val_len);
4556 add_addresses(subtree, tmp_tvb, hf_sir_contact_points);
4560 /* Number of entries in the Protocol Options list */
4561 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
4562 proto_tree_add_uint(subtree, hf_sir_protocol_options_len,
4563 tvb, offset, len, val_len);
4565 /* Protocol Options list.
4566 * Each protocol option is encoded as a guintvar */
4568 val_len_save = val_len;
4569 for (i = 0; i < val_len_save; i++) {
4570 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
4571 proto_tree_add_uint(subtree, hf_sir_protocol_options,
4572 tvb, offset, len, val_len);
4576 /* Length of ProvURL */
4577 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
4578 proto_tree_add_uint(subtree, hf_sir_prov_url_len,
4579 tvb, offset, len, val_len);
4582 proto_tree_add_item (tree, hf_sir_prov_url,
4583 tvb, offset, val_len, ENC_ASCII|ENC_NA);
4586 /* Number of entries in the CPITag list */
4587 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
4588 proto_tree_add_uint(subtree, hf_sir_cpi_tag_len,
4589 tvb, offset, len, val_len);
4593 * Each CPITag is encoded as 4 octets of opaque data.
4594 * In OTA-HTTP, it is conveyed in the X-Wap-CPITag header
4595 * but with a Base64 encoding of the 4 bytes. */
4596 for (i = 0; i < val_len; i++) {
4597 proto_tree_add_item(subtree, hf_sir_cpi_tag,
4598 tvb, offset, 4, ENC_NA);
4601 return tvb_captured_length(tvb);
4605 dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4606 dissector_handle_t dissector_handle, gboolean is_connectionless)
4613 guint uriLength = 0;
4615 guint capabilityLength = 0;
4616 guint headersLength = 0;
4617 guint headerLength = 0;
4618 guint headerStart = 0;
4619 guint nextOffset = 0;
4620 guint contentTypeStart = 0;
4621 guint contentType = 0;
4622 const char *contentTypeStr;
4625 heur_dtbl_entry_t *hdtbl_entry;
4628 /* Set up structures we will need to add the protocol subtree and manage it */
4629 proto_item *proto_ti = NULL; /* for the proto entry */
4630 proto_tree *wsp_tree = NULL;
4632 wsp_info_value_t *stat_info;
4633 stat_info = (wsp_info_value_t *)wmem_alloc(wmem_packet_scope(), sizeof(wsp_info_value_t));
4634 stat_info->status_code = 0;
4636 /* This field shows up as the "Info" column in the display; you should make
4637 it, if possible, summarize what's in the packet, so that a user looking
4638 at the list of packets can tell what type of packet it is. */
4640 /* Connection-less mode has a TID first */
4641 if (is_connectionless)
4643 offset++; /* Skip the 1-byte Transaction ID */
4646 /* Find the PDU type */
4647 pdut = tvb_get_guint8 (tvb, offset);
4649 /* Develop the string to put in the Info column */
4650 col_append_fstr(pinfo->cinfo, COL_INFO, "WSP %s (0x%02x)",
4651 val_to_str_ext (pdut, &wsp_vals_pdu_type_ext, "Unknown PDU type (0x%02x)"),
4654 /* In the interest of speed, if "tree" is NULL, don't do any work not
4655 * necessary to generate protocol tree items. */
4657 proto_ti = proto_tree_add_item(tree, proto_wsp,
4658 tvb, 0, -1, ENC_NA);
4659 wsp_tree = proto_item_add_subtree(proto_ti, ett_wsp);
4660 proto_item_append_text(proto_ti, ", Method: %s (0x%02x)",
4661 val_to_str_ext (pdut, &wsp_vals_pdu_type_ext, "Unknown (0x%02x)"),
4664 /* Add common items: only TID and PDU Type */
4666 /* If this is connectionless, then the TID Field is always first */
4667 if (is_connectionless)
4669 proto_tree_add_item (wsp_tree, hf_wsp_header_tid,
4670 tvb, 0, 1, ENC_LITTLE_ENDIAN);
4672 proto_tree_add_item( wsp_tree, hf_wsp_header_pdu_type,
4673 tvb, offset, 1, ENC_LITTLE_ENDIAN);
4677 /* Map extended methods to the main method now the Column info has been
4678 * written; this way we can dissect the extended method PDUs. */
4679 if ((pdut >= 0x50) && (pdut <= 0x5F)) /* Extended GET --> GET */
4681 else if ((pdut >= 0x70) && (pdut <= 0x7F)) /* Extended POST --> POST */
4682 pdut = WSP_PDU_POST;
4686 case WSP_PDU_CONNECT:
4687 case WSP_PDU_CONNECTREPLY:
4688 case WSP_PDU_RESUME:
4689 if (pdut == WSP_PDU_CONNECT)
4691 proto_tree_add_item (wsp_tree, hf_wsp_version_major,
4692 tvb, offset, 1, ENC_LITTLE_ENDIAN);
4693 proto_tree_add_item (wsp_tree, hf_wsp_version_minor,
4694 tvb, offset, 1, ENC_LITTLE_ENDIAN);
4696 guint8 ver = tvb_get_guint8(tvb, offset);
4697 proto_item_append_text(proto_ti, ", Version: %u.%u",
4698 ver >> 4, ver & 0x0F);
4702 count = 0; /* Initialise count */
4703 value = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4704 proto_tree_add_uint (wsp_tree,
4705 hf_wsp_server_session_id,
4706 tvb, offset, count, value);
4707 proto_item_append_text(proto_ti, ", Session ID: %u", value);
4710 count = 0; /* Initialise count */
4711 capabilityLength = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4712 ti = proto_tree_add_uint (wsp_tree, hf_capabilities_length,
4713 tvb, offset, count, capabilityLength);
4715 if (capabilityLength > tvb_reported_length(tvb))
4717 expert_add_info(pinfo, ti, &ei_wsp_capability_length_invalid);
4721 if (pdut != WSP_PDU_RESUME)
4723 count = 0; /* Initialise count */
4724 headerLength = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4725 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4726 tvb, offset, count, headerLength);
4730 /* Resume computes the headerlength
4731 * by remaining bytes */
4732 headerStart = offset + capabilityLength;
4733 headerLength = tvb_reported_length_remaining (tvb,
4736 if (capabilityLength > 0)
4738 tmp_tvb = tvb_new_subset_length (tvb, offset,
4740 add_capabilities (wsp_tree, pinfo, tmp_tvb, pdut);
4741 offset += capabilityLength;
4744 if (headerLength > 0)
4746 tmp_tvb = tvb_new_subset_length (tvb, offset,
4748 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4753 case WSP_PDU_REDIRECT:
4754 dissect_redirect(tvb, offset, pinfo, wsp_tree, dissector_handle);
4757 case WSP_PDU_DISCONNECT:
4758 case WSP_PDU_SUSPEND:
4760 count = 0; /* Initialise count */
4761 value = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4762 proto_tree_add_uint (wsp_tree,
4763 hf_wsp_server_session_id,
4764 tvb, offset, count, value);
4765 proto_item_append_text(proto_ti, ", Session ID: %u", value);
4770 case WSP_PDU_OPTIONS:
4772 case WSP_PDU_DELETE:
4774 count = 0; /* Initialise count */
4775 /* Length of URI and size of URILen field */
4776 value = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4777 nextOffset = offset + count;
4778 add_uri (wsp_tree, pinfo, tvb, offset, nextOffset, proto_ti);
4780 offset += value + count; /* VERIFY */
4781 tmp_tvb = tvb_new_subset_remaining (tvb, offset);
4782 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4789 count = 0; /* Initialise count */
4790 uriLength = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4791 headerStart = uriStart+count;
4792 count = 0; /* Initialise count */
4793 headersLength = tvb_get_guintvar (tvb, headerStart, &count, pinfo, &ei_wsp_oversized_uintvar);
4794 offset = headerStart + count;
4796 add_uri (wsp_tree, pinfo, tvb, uriStart, offset, proto_ti);
4797 offset += uriLength;
4800 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4801 tvb, headerStart, count, headersLength);
4803 /* Stop processing POST PDU if length of headers is zero;
4804 * this should not happen as we expect at least Content-Type. */
4805 if (headersLength == 0)
4808 contentTypeStart = offset;
4809 nextOffset = add_content_type (wsp_tree, pinfo,
4810 tvb, offset, &contentType, &contentTypeStr);
4812 /* Add content type to protocol summary line */
4813 if (contentTypeStr) {
4814 proto_item_append_text(proto_ti, ", Content-Type: %s",
4817 proto_item_append_text(proto_ti, ", Content-Type: 0x%X",
4821 /* Add headers subtree that will hold the headers fields */
4822 /* Runs from nextOffset for
4823 * headersLength - (length of content-type field) */
4824 headerLength = headersLength - (nextOffset - contentTypeStart);
4825 if (headerLength > 0)
4827 tmp_tvb = tvb_new_subset_length (tvb, nextOffset,
4829 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4831 /* XXX - offset is no longer used after this point */
4832 /* offset = nextOffset+headerLength; */
4834 /* WSP_PDU_POST data - First check whether a subdissector exists
4835 * for the content type */
4836 if (tvb_reported_length_remaining(tvb,
4837 headerStart + count + uriLength + headersLength) > 0)
4839 tmp_tvb = tvb_new_subset_remaining (tvb,
4840 headerStart + count + uriLength + headersLength);
4842 * Try finding a dissector for the content
4843 * first, then fallback.
4846 if (contentTypeStr) {
4848 * Content type is a string.
4850 found_match = dissector_try_string(media_type_table,
4851 contentTypeStr, tmp_tvb, pinfo, tree, NULL);
4853 if (! found_match) {
4854 if (! dissector_try_heuristic(heur_subdissector_list,
4855 tmp_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
4857 pinfo->match_string = contentTypeStr;
4858 call_dissector_with_data(media_handle, tmp_tvb, pinfo, tree, NULL /* TODO: parameters */);
4860 if (tree) /* Only display if needed */
4861 add_post_data (wsp_tree, tmp_tvb,
4862 contentType, contentTypeStr, pinfo);
4870 count = 0; /* Initialise count */
4871 headersLength = tvb_get_guintvar (tvb, offset+1, &count, pinfo, &ei_wsp_oversized_uintvar);
4872 headerStart = offset + count + 1;
4874 guint8 reply_status = tvb_get_guint8(tvb, offset);
4875 const char *reply_status_str;
4877 reply_status_str = val_to_str_ext_const (reply_status, &wsp_vals_status_ext, "(Unknown response status)");
4879 proto_tree_add_item (wsp_tree, hf_wsp_header_status,
4880 tvb, offset, 1, ENC_LITTLE_ENDIAN);
4881 proto_item_append_text(proto_ti, ", Status: %s (0x%02x)",
4882 reply_status_str, reply_status);
4884 stat_info->status_code = (gint) reply_status;
4885 /* Append status code to INFO column */
4886 col_append_fstr(pinfo->cinfo, COL_INFO,
4888 reply_status_str, reply_status);
4890 nextOffset = offset + 1 + count;
4892 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4893 tvb, offset + 1, count, headersLength);
4895 if (headersLength == 0)
4898 contentTypeStart = nextOffset;
4899 nextOffset = add_content_type (wsp_tree, pinfo, tvb,
4900 nextOffset, &contentType, &contentTypeStr);
4902 /* Add content type to protocol summary line */
4903 if (contentTypeStr) {
4904 proto_item_append_text(proto_ti, ", Content-Type: %s",
4907 proto_item_append_text(proto_ti, ", Content-Type: 0x%X",
4911 /* Add headers subtree that will hold the headers fields */
4912 /* Runs from nextOffset for
4913 * headersLength - (length of Content-Type field) */
4914 headerLength = headersLength - (nextOffset - contentTypeStart);
4915 if (headerLength > 0)
4917 tmp_tvb = tvb_new_subset_length (tvb, nextOffset,
4919 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4921 /* XXX - offset is no longer used after this point */
4922 /* offset += count+headersLength+1;*/
4924 /* WSP_PDU_REPLY data - First check whether a subdissector exists
4925 * for the content type */
4926 if (tvb_reported_length_remaining(tvb, headerStart + headersLength)
4929 tmp_tvb = tvb_new_subset_remaining (tvb, headerStart + headersLength);
4931 * Try finding a dissector for the content
4932 * first, then fallback.
4935 if (contentTypeStr) {
4937 * Content type is a string.
4939 found_match = dissector_try_string(media_type_table,
4940 contentTypeStr, tmp_tvb, pinfo, tree, NULL);
4942 if (! found_match) {
4943 if (! dissector_try_heuristic(heur_subdissector_list,
4944 tmp_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
4946 pinfo->match_string = contentTypeStr;
4947 call_dissector_with_data(media_handle, tmp_tvb, pinfo, tree, NULL /* TODO: parameters */);
4949 if (tree) / * Only display if needed * /
4950 proto_tree_add_item (wsp_tree,
4952 tmp_tvb, 0, -1, ENC_NA);
4960 case WSP_PDU_CONFIRMEDPUSH:
4961 count = 0; /* Initialise count */
4962 headersLength = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4963 headerStart = offset + count;
4965 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4966 tvb, offset, count, headersLength);
4968 if (headersLength == 0)
4972 contentTypeStart = offset;
4973 nextOffset = add_content_type (wsp_tree, pinfo,
4974 tvb, offset, &contentType, &contentTypeStr);
4976 /* Add content type to protocol summary line */
4977 if (contentTypeStr) {
4978 proto_item_append_text(proto_ti, ", Content-Type: %s",
4981 proto_item_append_text(proto_ti, ", Content-Type: 0x%X",
4985 /* Add headers subtree that will hold the headers fields */
4986 /* Runs from nextOffset for
4987 * headersLength-(length of Content-Type field) */
4988 headerLength = headersLength-(nextOffset-contentTypeStart);
4989 if (headerLength > 0)
4991 tmp_tvb = tvb_new_subset_length (tvb, nextOffset,
4993 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4995 /* XXX - offset is no longer used after this point */
4996 /*offset += headersLength;*/
4998 /* WSP_PDU_PUSH data - First check whether a subdissector exists
4999 * for the content type */
5000 if (tvb_reported_length_remaining(tvb, headerStart + headersLength)
5003 tmp_tvb = tvb_new_subset_remaining (tvb, headerStart + headersLength);
5005 * Try finding a dissector for the content
5006 * first, then fallback.
5009 if (contentTypeStr) {
5011 * Content type is a string.
5014 if (g_ascii_strcasecmp(contentTypeStr, "application/vnd.wap.sia") == 0) {
5015 dissect_sir(tree, tmp_tvb);
5018 found_match = dissector_try_string(media_type_table,
5019 contentTypeStr, tmp_tvb, pinfo, tree, NULL);
5021 if (! found_match) {
5022 if (! dissector_try_heuristic(heur_subdissector_list,
5023 tmp_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
5025 pinfo->match_string = contentTypeStr;
5026 call_dissector_with_data(media_handle, tmp_tvb, pinfo, tree, NULL /* TODO: parameters */);
5028 if (tree) /* Only display if needed */
5029 proto_tree_add_item (wsp_tree,
5031 tmp_tvb, 0, -1, ENC_NA);
5039 stat_info->pdut = pdut;
5040 tap_queue_packet (wsp_tap, pinfo, stat_info);
5045 * Called directly from UDP.
5046 * Put "WSP" into the "Protocol" column.
5049 dissect_wsp_fromudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5051 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSP");
5052 col_clear(pinfo->cinfo, COL_INFO);
5054 dissect_wsp_common(tvb, pinfo, tree, wsp_fromudp_handle, TRUE);
5055 return tvb_captured_length(tvb);
5060 * Called from a higher-level WAP dissector, in connection-oriented mode.
5061 * Leave the "Protocol" column alone - the dissector calling us should
5065 dissect_wsp_fromwap_co(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5068 * XXX - what about WTLS->WTP->WSP?
5070 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, FALSE);
5071 return tvb_captured_length(tvb);
5076 * Called from a higher-level WAP dissector, in connectionless mode.
5077 * Leave the "Protocol" column alone - the dissector calling us should
5081 dissect_wsp_fromwap_cl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5084 * XXX - what about WTLS->WSP?
5086 col_clear(pinfo->cinfo, COL_INFO);
5087 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, TRUE);
5088 return tvb_captured_length(tvb);
5093 add_uri (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
5094 guint URILenOffset, guint URIOffset, proto_item *proto_ti)
5097 guint uriLen = tvb_get_guintvar (tvb, URILenOffset, &count, pinfo, &ei_wsp_oversized_uintvar);
5100 proto_tree_add_uint (tree, hf_wsp_header_uri_len,
5101 tvb, URILenOffset, count, uriLen);
5103 proto_tree_add_item (tree, hf_wsp_header_uri,
5104 tvb, URIOffset, uriLen, ENC_ASCII|ENC_NA);
5106 str = tvb_format_text (tvb, URIOffset, uriLen);
5107 /* XXX - tvb_format_text() returns a pointer to a static text string
5108 * so please DO NOT attempt at g_free()ing it!
5110 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", str);
5113 proto_item_append_text(proto_ti, ", URI: %s", str);
5118 * CO-WSP capability negotiation
5122 WSP_CAPA_CLIENT_SDU_SIZE = 0x00,
5123 WSP_CAPA_SERVER_SDU_SIZE,
5124 WSP_CAPA_PROTOCOL_OPTIONS,
5125 WSP_CAPA_METHOD_MOR,
5127 WSP_CAPA_EXTENDED_METHODS,
5128 WSP_CAPA_HEADER_CODE_PAGES,
5130 WSP_CAPA_CLIENT_MESSAGE_SIZE,
5131 WSP_CAPA_SERVER_MESSAGE_SIZE
5134 static const value_string wsp_capability_vals [] = {
5135 { WSP_CAPA_CLIENT_SDU_SIZE, "Client SDU Size" },
5136 { WSP_CAPA_SERVER_SDU_SIZE, "Server SDU Size" },
5137 { WSP_CAPA_PROTOCOL_OPTIONS, "Protocol Options" },
5138 { WSP_CAPA_METHOD_MOR, "Method MOR" },
5139 { WSP_CAPA_PUSH_MOR, "Push MOR" },
5140 { WSP_CAPA_EXTENDED_METHODS, "Extended Methods" },
5141 { WSP_CAPA_HEADER_CODE_PAGES, "Header Code Pages" },
5142 { WSP_CAPA_ALIASES, "Aliases" },
5143 { WSP_CAPA_CLIENT_MESSAGE_SIZE, "Client Message Size" },
5144 { WSP_CAPA_SERVER_MESSAGE_SIZE, "Server Message Size" },
5149 add_capabilities (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint8 pdu_type)
5151 proto_tree *wsp_capabilities, *cap_subtree, *cap_subtree2;
5152 proto_item *ti, *cap_item, *cap_item2;
5154 char *capaName, *str;
5157 guint32 capaStart = 0; /* Start offset of the capability */
5158 guint32 capaLen = 0; /* Length of the entire capability */
5159 guint32 capaValueLen = 0; /* Length of the capability value & type */
5160 guint32 tvb_len = tvb_reported_length(tvb);
5161 gboolean ok = FALSE;
5169 ti = proto_tree_add_item(tree, hf_capabilities_section,
5170 tvb, 0, tvb_len, ENC_NA);
5171 wsp_capabilities = proto_item_add_subtree(ti, ett_capabilities);
5173 while (offset < tvb_len) {
5175 * WSP capabilities consist of:
5176 * - a guint32 length field,
5177 * - a capability identifier as Token-text or Short-integer,
5178 * - a capability-specific sequence of <length> octets.
5182 * Now Offset points to the 1st byte of a capability field.
5183 * Get the length of the capability field
5185 capaValueLen = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
5186 capaLen = capaValueLen + len;
5188 cap_subtree = proto_tree_add_subtree(wsp_capabilities, tvb, offset, capaLen, ett_capabilities_entry, &cap_item, "Capability");
5189 if (capaValueLen > tvb_len)
5193 * Now offset points to the 1st byte of the capability type.
5194 * Get the capability identifier.
5196 peek = tvb_get_guint8(tvb, offset);
5197 if (is_token_text(peek)) { /* Literal capability name */
5198 /* 1. Get the string from the tvb */
5199 capaName = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, capaStart, (gint *)&len, ENC_ASCII);
5201 /* 2. Look up the string capability name */
5202 if (g_ascii_strcasecmp(capaName, "client-sdu-size") == 0) {
5203 peek = WSP_CAPA_CLIENT_SDU_SIZE;
5204 } else if (g_ascii_strcasecmp(capaName, "server-sdu-size") == 0) {
5205 peek = WSP_CAPA_SERVER_SDU_SIZE;
5206 } else if (g_ascii_strcasecmp(capaName, "protocol options") == 0) {
5207 peek = WSP_CAPA_PROTOCOL_OPTIONS;
5208 } else if (g_ascii_strcasecmp(capaName, "method-mor") == 0) {
5209 peek = WSP_CAPA_METHOD_MOR;
5210 } else if (g_ascii_strcasecmp(capaName, "push-mor") == 0) {
5211 peek = WSP_CAPA_PUSH_MOR;
5212 } else if (g_ascii_strcasecmp(capaName, "extended methods") == 0) {
5213 peek = WSP_CAPA_EXTENDED_METHODS;
5214 } else if (g_ascii_strcasecmp(capaName, "header code pages") == 0) {
5215 peek = WSP_CAPA_HEADER_CODE_PAGES;
5216 } else if (g_ascii_strcasecmp(capaName, "aliases") == 0) {
5217 peek = WSP_CAPA_ALIASES;
5218 } else if (g_ascii_strcasecmp(capaName, "client-message-size") == 0) {
5219 peek = WSP_CAPA_CLIENT_MESSAGE_SIZE;
5220 } else if (g_ascii_strcasecmp(capaName, "server-message-size") == 0) {
5221 peek = WSP_CAPA_SERVER_MESSAGE_SIZE;
5223 expert_add_info_format(pinfo, cap_item, &ei_wsp_capability_invalid,
5224 "Unknown or invalid textual capability: %s", capaName);
5225 /* Skip this capability */
5226 offset = capaStart + capaLen;
5230 /* Now offset points to the 1st value byte of the capability. */
5231 } else if (peek < 0x80) {
5232 expert_add_info_format(pinfo, cap_item, &ei_wsp_capability_invalid,
5233 "Invalid well-known capability: 0x%02X", peek);
5234 /* Skip further capability parsing */
5237 if (peek & 0x80) { /* Well-known capability */
5241 /* Now offset points to the 1st value byte of the capability. */
5244 proto_item_append_text(cap_item, ": %s", val_to_str_const(peek, wsp_capability_vals, "Invalid capability"));
5245 /* Now the capability type is known */
5247 case WSP_CAPA_CLIENT_SDU_SIZE:
5248 value = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
5249 proto_tree_add_uint(cap_subtree, hf_capa_client_sdu_size,
5250 tvb, offset, len, value);
5252 case WSP_CAPA_SERVER_SDU_SIZE:
5253 value = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
5254 proto_tree_add_uint(cap_subtree, hf_capa_server_sdu_size,
5255 tvb, offset, len, value);
5257 case WSP_CAPA_PROTOCOL_OPTIONS:
5259 * The bits are stored in one or more octets, not an
5260 * uintvar-integer! Note that capability name and value
5261 * have length capaValueLength, and that the capability
5262 * name has length = len. Hence the remaining length is
5263 * given by capaValueLen - len.
5265 if (capaValueLen - len == 1) {
5266 static const int * capabilities[] = {
5267 &hf_capa_protocol_option_confirmed_push,
5268 &hf_capa_protocol_option_push,
5269 &hf_capa_protocol_option_session_resume,
5270 &hf_capa_protocol_option_ack_headers,
5271 &hf_capa_protocol_option_large_data_transfer,
5275 proto_tree_add_bitmask_with_flags(cap_subtree, tvb, offset, hf_capa_protocol_options,
5276 ett_proto_option_capability, capabilities, ENC_NA, BMT_NO_FALSE);
5281 * The WSP spec foresees that this bit field can be
5282 * extended in the future. This does not make sense yet.
5284 proto_item_append_text(cap_item,
5285 " <warning: bit field too large>");
5286 offset = capaStart + capaLen;
5290 case WSP_CAPA_METHOD_MOR:
5291 proto_tree_add_item(cap_subtree, hf_capa_method_mor, tvb, offset, len, ENC_NA);
5293 case WSP_CAPA_PUSH_MOR:
5294 proto_tree_add_item(cap_subtree, hf_capa_push_mor, tvb, offset, len, ENC_NA);
5296 case WSP_CAPA_EXTENDED_METHODS:
5297 /* Extended Methods capability format:
5298 * Connect PDU: collection of { Method (octet), Method-name (Token-text) }
5299 * ConnectReply PDU: collection of accepted { Method (octet) }
5301 cap_subtree2 = proto_tree_add_subtree(cap_subtree, tvb, capaStart, capaLen, ett_capabilities_extended_methods, &cap_item2, "Extended Methods");
5302 if (pdu_type == WSP_PDU_CONNECT) {
5303 while (offset < capaStart + capaLen) {
5304 ti = proto_tree_add_item(cap_subtree2, hf_capa_extended_method, tvb, offset, 1, ENC_NA);
5307 get_text_string(str, tvb, offset, len, ok);
5309 expert_add_info(pinfo, ti, &ei_wsp_capability_encoding_invalid);
5312 proto_item_append_text(ti, " = %s", str);
5313 proto_item_set_len(ti, len+1);
5317 while (offset < capaStart + capaLen) {
5318 proto_tree_add_item(cap_subtree2, hf_capa_extended_method, tvb, offset, 1, ENC_NA);
5323 case WSP_CAPA_HEADER_CODE_PAGES:
5324 /* Header Code Pages capability format:
5325 * Connect PDU: collection of { Page-id (octet), Page-name (Token-text) }
5326 * ConnectReply PDU: collection of accepted { Page-id (octet) }
5328 cap_subtree2 = proto_tree_add_subtree(cap_subtree, tvb, capaStart, capaLen, ett_capabilities_header_code_pages, &cap_item2, "Header Code Pages");
5329 if (pdu_type == WSP_PDU_CONNECT) {
5330 while (offset < capaStart + capaLen) {
5331 ti = proto_tree_add_item(cap_subtree2, hf_capa_header_code_page, tvb, offset, 1, ENC_NA);
5334 get_text_string(str, tvb, offset, len, ok);
5336 expert_add_info(pinfo, ti, &ei_wsp_capability_encoding_invalid);
5339 proto_item_append_text(ti, " = %s", str);
5340 proto_item_set_len(ti, len+1);
5344 while (offset < capaStart + capaLen) {
5345 proto_tree_add_item(cap_subtree2, hf_capa_header_code_page, tvb, offset, 1, ENC_NA);
5350 case WSP_CAPA_ALIASES:
5351 /* TODO - same format as redirect addresses */
5352 proto_tree_add_item(cap_subtree, hf_capa_aliases,
5353 tvb, capaStart, capaLen, ENC_NA);
5355 case WSP_CAPA_CLIENT_MESSAGE_SIZE:
5356 value = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
5357 proto_tree_add_uint(cap_subtree, hf_capa_client_message_size,
5358 tvb, offset, len, value);
5360 case WSP_CAPA_SERVER_MESSAGE_SIZE:
5361 value = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
5362 proto_tree_add_uint(cap_subtree, hf_capa_server_message_size,
5363 tvb, offset, len, value);
5366 expert_add_info_format(pinfo, cap_item, &ei_wsp_capability_invalid,
5367 "Unknown well-known capability: 0x%02X", peek);
5370 offset = capaStart + capaLen;
5375 add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType,
5376 const char *contentTypeStr, packet_info *pinfo)
5379 guint variableStart = 0;
5380 guint variableEnd = 0;
5381 guint valueStart = 0;
5384 proto_tree *sub_tree = NULL;
5386 /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,ENC_NA); */
5388 ti = proto_tree_add_item (tree, hf_wsp_post_data,
5389 tvb, offset, -1, ENC_NA);
5390 sub_tree = proto_item_add_subtree(ti, ett_post);
5393 if ( (contentTypeStr == NULL && contentType == 0x12)
5394 || (contentTypeStr && (g_ascii_strcasecmp(contentTypeStr,
5395 "application/x-www-form-urlencoded") == 0)) )
5400 * Iterate through post data.
5402 for (offset = 0; offset < tvb_reported_length (tvb); offset++)
5404 peek = tvb_get_guint8 (tvb, offset);
5407 variableEnd = offset;
5408 valueStart = offset+1;
5410 else if (peek == '&')
5412 if (variableEnd > 0)
5414 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5416 variableStart = offset+1;
5422 /* See if there's outstanding data */
5423 if (variableEnd > 0)
5425 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5429 else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x24) ||
5430 (contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33))
5432 /* add_multipart_data takes also care of subdissection */
5433 add_multipart_data(sub_tree, tvb, pinfo);
5438 add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint variableEnd, guint valueStart, guint valueEnd)
5440 int variableLength = variableEnd-variableStart;
5441 int valueLength = 0;
5442 char *variableBuffer;
5445 variableBuffer = tvb_get_string_enc(wmem_packet_scope(), tvb, variableStart, variableLength, ENC_ASCII);
5447 if (valueEnd < valueStart)
5449 valueBuffer = (char *)wmem_alloc(wmem_packet_scope(), 1);
5451 valueEnd = valueStart;
5455 valueLength = valueEnd-valueStart;
5456 valueBuffer = tvb_get_string_enc(wmem_packet_scope(), tvb, valueStart, valueLength, ENC_ASCII);
5459 /* Check for variables with no value */
5460 if (valueStart >= tvb_reported_length (tvb))
5462 valueStart = tvb_reported_length (tvb);
5463 valueEnd = valueStart;
5465 valueLength = valueEnd-valueStart;
5467 proto_tree_add_string_format(tree, hf_wsp_variable_value, tvb, variableStart, valueLength, valueBuffer, "%s: %s", variableBuffer, valueBuffer);
5472 add_multipart_data (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo)
5480 guint contentType = 0;
5481 const char *contentTypeStr;
5485 int found_match = 0;
5487 proto_item *sub_tree = NULL;
5488 proto_item *ti = NULL;
5489 proto_tree *mpart_tree = NULL;
5491 heur_dtbl_entry_t *hdtbl_entry;
5493 nEntries = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
5497 sub_tree = proto_tree_add_subtree(tree, tvb, offset - count, 0,
5498 ett_mpartlist, NULL, "Multipart body");
5502 part_start = offset;
5503 HeadersLen = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
5505 DataLen = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
5508 ti = proto_tree_add_uint(sub_tree, hf_wsp_mpart, tvb, part_start,
5509 HeadersLen + DataLen + (offset - part_start), partnr);
5510 mpart_tree = proto_item_add_subtree(ti, ett_multiparts);
5512 nextOffset = add_content_type (mpart_tree, pinfo, tvb, offset,
5513 &contentType, &contentTypeStr);
5516 /* Add content type to protocol summary line */
5517 if (contentTypeStr) {
5518 proto_item_append_text(ti, ", content-type: %s",
5521 proto_item_append_text(ti, ", content-type: 0x%X",
5526 HeadersLen -= (nextOffset - offset);
5529 tmp_tvb = tvb_new_subset_length (tvb, nextOffset, HeadersLen);
5530 add_headers (mpart_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
5532 offset = nextOffset + HeadersLen;
5534 * Try the dissectors of the multipart content.
5536 * TODO - handle nested multipart documents.
5538 tmp_tvb = tvb_new_subset_length(tvb, offset, DataLen);
5540 * Try finding a dissector for the content
5541 * first, then fallback.
5544 if (contentTypeStr) {
5546 * Content type is a string.
5548 found_match = dissector_try_string(media_type_table,
5549 contentTypeStr, tmp_tvb, pinfo, mpart_tree, NULL);
5551 if (! found_match) {
5552 if (! dissector_try_heuristic(heur_subdissector_list,
5553 tmp_tvb, pinfo, mpart_tree, &hdtbl_entry, NULL)) {
5555 pinfo->match_string = contentTypeStr;
5556 call_dissector_with_data(media_handle, tmp_tvb, pinfo, mpart_tree, NULL /* TODO: parameters */);
5558 if (tree) /* Only display if needed */
5559 proto_tree_add_item (mpart_tree, hf_wsp_multipart_data,
5560 tvb, offset, DataLen, ENC_NA);
5573 MESSAGE_TYPE_COLUMN = 0,
5577 static stat_tap_table_item wsp_stat_fields[] = {
5578 {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Type / Code", "%-25s"},
5579 {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Packets", "%d"}
5582 static int unknown_pt_idx;
5583 static int unknown_sc_idx;
5585 static void wsp_stat_init(stat_tap_table_ui* new_stat, stat_tap_gui_init_cb gui_callback, void* gui_data)
5587 int num_fields = sizeof(wsp_stat_fields)/sizeof(stat_tap_table_item);
5588 stat_tap_table* pt_table = stat_tap_init_table("PDU Types", num_fields, 0, NULL, gui_callback, gui_data);
5589 stat_tap_table_item_type pt_items[sizeof(wsp_stat_fields)/sizeof(stat_tap_table_item)];
5590 stat_tap_table* sc_table = stat_tap_init_table("Status Codes", num_fields, 0, NULL, gui_callback, gui_data);
5591 stat_tap_table_item_type sc_items[sizeof(wsp_stat_fields)/sizeof(stat_tap_table_item)];
5594 stat_tap_add_table(new_stat, pt_table);
5595 stat_tap_add_table(new_stat, sc_table);
5597 /* Add a row for each PDU type and status code */
5599 memset(pt_items, 0, sizeof(pt_items));
5600 pt_items[MESSAGE_TYPE_COLUMN].type = TABLE_ITEM_STRING;
5601 pt_items[PACKET_COLUMN].type = TABLE_ITEM_UINT;
5602 while (wsp_vals_pdu_type[table_idx].strptr)
5604 pt_items[MESSAGE_TYPE_COLUMN].value.string_value = g_strdup(wsp_vals_pdu_type[table_idx].strptr);
5605 pt_items[MESSAGE_TYPE_COLUMN].user_data.uint_value = wsp_vals_pdu_type[table_idx].value;
5607 stat_tap_init_table_row(pt_table, table_idx, num_fields, pt_items);
5610 pt_items[MESSAGE_TYPE_COLUMN].value.string_value = g_strdup("Unknown PDU type");
5611 pt_items[MESSAGE_TYPE_COLUMN].user_data.uint_value = 0;
5612 stat_tap_init_table_row(pt_table, table_idx, num_fields, pt_items);
5613 unknown_pt_idx = table_idx;
5616 memset(sc_items, 0, sizeof(sc_items));
5617 sc_items[MESSAGE_TYPE_COLUMN].type = TABLE_ITEM_STRING;
5618 sc_items[PACKET_COLUMN].type = TABLE_ITEM_UINT;
5619 while (wsp_vals_status[table_idx].strptr)
5621 sc_items[MESSAGE_TYPE_COLUMN].value.string_value = g_strdup(wsp_vals_status[table_idx].strptr);
5622 sc_items[MESSAGE_TYPE_COLUMN].user_data.uint_value = wsp_vals_status[table_idx].value;
5624 stat_tap_init_table_row(sc_table, table_idx, num_fields, sc_items);
5627 sc_items[MESSAGE_TYPE_COLUMN].value.string_value = g_strdup("Unknown status code");
5628 sc_items[MESSAGE_TYPE_COLUMN].user_data.uint_value = 0;
5629 stat_tap_init_table_row(sc_table, table_idx, num_fields, sc_items);
5630 unknown_sc_idx = table_idx;
5634 wsp_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *wiv_ptr)
5636 stat_data_t* stat_data = (stat_data_t*)tapdata;
5637 const wsp_info_value_t *value = (const wsp_info_value_t *)wiv_ptr;
5638 stat_tap_table *pt_table, *sc_table;
5640 stat_tap_table_item_type* item_data;
5643 pt_table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 0);
5644 sc_table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 1);
5647 for (element = 0; element < pt_table->num_elements; element++) {
5648 item_data = stat_tap_get_field_data(pt_table, element, MESSAGE_TYPE_COLUMN);
5649 if (value->pdut == item_data->user_data.uint_value) {
5655 element = unknown_pt_idx;
5657 item_data = stat_tap_get_field_data(pt_table, element, PACKET_COLUMN);
5658 item_data->value.uint_value++;
5659 stat_tap_set_field_data(pt_table, element, PACKET_COLUMN, item_data);
5661 if (value->status_code != 0) {
5663 for (element = 0; element < sc_table->num_elements; element++) {
5664 item_data = stat_tap_get_field_data(sc_table, element, MESSAGE_TYPE_COLUMN);
5665 if (value->status_code == (int) item_data->user_data.uint_value) {
5671 element = unknown_sc_idx;
5673 item_data = stat_tap_get_field_data(sc_table, element, PACKET_COLUMN);
5674 item_data->value.uint_value++;
5675 stat_tap_set_field_data(sc_table, element, PACKET_COLUMN, item_data);
5682 wsp_stat_reset(stat_tap_table* table)
5685 stat_tap_table_item_type* item_data;
5687 for (element = 0; element < table->num_elements; element++)
5689 item_data = stat_tap_get_field_data(table, element, PACKET_COLUMN);
5690 item_data->value.uint_value = 0;
5691 stat_tap_set_field_data(table, element, PACKET_COLUMN, item_data);
5696 wsp_stat_free_table_item(stat_tap_table* table _U_, guint row _U_, guint column, stat_tap_table_item_type* field_data)
5698 if (column != MESSAGE_TYPE_COLUMN) return;
5699 g_free((char*)field_data->value.string_value);
5700 field_data->value.string_value = NULL;
5703 /* Register the protocol with Wireshark */
5705 proto_register_wsp(void)
5708 /* Setup list of header fields */
5709 static hf_register_info hf[] = {
5710 { &hf_wsp_header_tid,
5713 FT_UINT8, BASE_HEX, NULL, 0x00,
5714 "WSP Transaction ID (for connectionless WSP)", HFILL
5717 { &hf_wsp_header_pdu_type,
5720 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &wsp_vals_pdu_type_ext, 0x00,
5724 { &hf_wsp_version_major,
5725 { "Version (Major)",
5726 "wsp.version.major",
5727 FT_UINT8, BASE_DEC, NULL, 0xF0,
5731 { &hf_wsp_version_minor,
5732 { "Version (Minor)",
5733 "wsp.version.minor",
5734 FT_UINT8, BASE_DEC, NULL, 0x0F,
5738 { &hf_capabilities_length,
5739 { "Capabilities Length",
5740 "wsp.capabilities.length",
5741 FT_UINT32, BASE_DEC, NULL, 0x00,
5742 "Length of Capabilities field (bytes)", HFILL
5745 { &hf_wsp_header_length,
5747 "wsp.headers_length",
5748 FT_UINT32, BASE_DEC, NULL, 0x00,
5749 "Length of Headers field (bytes)", HFILL
5752 { &hf_capabilities_section,
5755 FT_NONE, BASE_NONE, NULL, 0x00,
5759 { &hf_wsp_headers_section,
5762 FT_NONE, BASE_NONE, NULL, 0x00,
5766 { &hf_wsp_header_uri_len,
5769 FT_UINT32, BASE_DEC, NULL, 0x00,
5770 "Length of URI field", HFILL
5773 { &hf_wsp_header_uri,
5776 FT_STRING, BASE_NONE, NULL, 0x00,
5780 { &hf_wsp_server_session_id,
5781 { "Server Session ID",
5782 "wsp.server.session_id",
5783 FT_UINT32, BASE_DEC, NULL, 0x00,
5787 { &hf_wsp_header_status,
5790 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &wsp_vals_status_ext, 0x00,
5791 "Reply Status", HFILL
5794 { &hf_wsp_parameter_untype_quote_text,
5795 { "Untyped quoted text",
5796 "wsp.untype.quote_text",
5797 FT_STRING, BASE_NONE, NULL, 0x00,
5801 { &hf_wsp_parameter_untype_text,
5804 FT_STRING, BASE_NONE, NULL, 0x00,
5808 { &hf_wsp_parameter_untype_int,
5809 { "Untyped integer",
5811 FT_UINT32, BASE_DEC, NULL, 0x00,
5815 { &hf_wsp_parameter_type,
5817 "wsp.parameter.type",
5818 FT_UINT32, BASE_DEC|BASE_EXT_STRING, ¶meter_type_vals_ext, 0x00,
5822 { &hf_wsp_parameter_int_type,
5824 "wsp.parameter.int_type",
5825 FT_UINT32, BASE_DEC, NULL, 0x00,
5826 "Type parameter", HFILL
5829 { &hf_wsp_parameter_name,
5831 "wsp.parameter.name",
5832 FT_STRING, BASE_NONE, NULL, 0x00,
5833 "Name parameter", HFILL
5836 { &hf_wsp_parameter_filename,
5838 "wsp.parameter.filename",
5839 FT_STRING, BASE_NONE, NULL, 0x00,
5840 "Filename parameter", HFILL
5843 { &hf_wsp_parameter_start,
5845 "wsp.parameter.start",
5846 FT_STRING, BASE_NONE, NULL, 0x00,
5847 "Start parameter", HFILL
5850 { &hf_wsp_parameter_start_info,
5852 "wsp.parameter.start_info",
5853 FT_STRING, BASE_NONE, NULL, 0x00,
5854 "Start-info parameter", HFILL
5857 { &hf_wsp_parameter_comment,
5859 "wsp.parameter.comment",
5860 FT_STRING, BASE_NONE, NULL, 0x00,
5861 "Comment parameter", HFILL
5864 { &hf_wsp_parameter_domain,
5866 "wsp.parameter.domain",
5867 FT_STRING, BASE_NONE, NULL, 0x00,
5868 "Domain parameter", HFILL
5871 { &hf_wsp_parameter_path,
5873 "wsp.parameter.path",
5874 FT_STRING, BASE_NONE, NULL, 0x00,
5875 "Path parameter", HFILL
5878 { &hf_wsp_parameter_sec,
5880 "wsp.parameter.sec",
5881 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_wsp_parameter_sec_ext, 0x00,
5882 "SEC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
5885 { &hf_wsp_parameter_mac,
5887 "wsp.parameter.mac",
5888 FT_STRING, BASE_NONE, NULL, 0x00,
5889 "MAC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
5892 { &hf_wsp_parameter_upart_type,
5894 "wsp.parameter.upart.type",
5895 FT_STRING, BASE_NONE, NULL, 0x00,
5896 "Multipart type parameter", HFILL
5899 { &hf_wsp_parameter_level,
5901 "wsp.parameter.level",
5902 FT_STRING, BASE_NONE, NULL, 0x00,
5903 "Level parameter", HFILL
5906 { &hf_wsp_parameter_size,
5908 "wsp.parameter.size",
5909 FT_UINT32, BASE_DEC, NULL, 0x00,
5910 "Size parameter", HFILL
5914 { &hf_wsp_reply_data,
5917 FT_NONE, BASE_NONE, NULL, 0x00,
5922 { &hf_wsp_header_shift_code,
5923 { "Switching to WSP header code-page",
5925 FT_UINT8, BASE_DEC, NULL, 0x00,
5926 "Header code-page shift code", HFILL
5930 * CO-WSP capability negotiation
5932 { &hf_capa_client_sdu_size,
5933 { "Client SDU Size",
5934 "wsp.capability.client_sdu_size",
5935 FT_UINT8, BASE_DEC, NULL, 0x00,
5936 "Client Service Data Unit size (bytes)", HFILL
5939 { &hf_capa_server_sdu_size,
5940 { "Server SDU Size",
5941 "wsp.capability.server_sdu_size",
5942 FT_UINT8, BASE_DEC, NULL, 0x00,
5943 "Server Service Data Unit size (bytes)", HFILL
5946 { &hf_capa_protocol_options,
5947 { "Protocol Options",
5948 "wsp.capability.protocol_opt",
5949 FT_UINT8, BASE_HEX, NULL, 0x00,
5953 { &hf_capa_protocol_option_confirmed_push,
5954 { "Confirmed Push facility",
5955 "wsp.capability.protocol_option.confirmed_push",
5956 FT_BOOLEAN, 8, NULL, 0x80,
5957 "If set, this CO-WSP session supports the Confirmed Push facility", HFILL
5960 { &hf_capa_protocol_option_push,
5962 "wsp.capability.protocol_option.push",
5963 FT_BOOLEAN, 8, NULL, 0x40,
5964 "If set, this CO-WSP session supports the Push facility", HFILL
5967 { &hf_capa_protocol_option_session_resume,
5968 { "Session Resume facility",
5969 "wsp.capability.protocol_option.session_resume",
5970 FT_BOOLEAN, 8, NULL, 0x20,
5971 "If set, this CO-WSP session supports the Session Resume facility", HFILL
5974 { &hf_capa_protocol_option_ack_headers,
5975 { "Acknowledgement headers",
5976 "wsp.capability.protocol_option.ack_headers",
5977 FT_BOOLEAN, 8, NULL, 0x10,
5978 "If set, this CO-WSP session supports Acknowledgement headers", HFILL
5981 { &hf_capa_protocol_option_large_data_transfer,
5982 { "Large data transfer",
5983 "wsp.capability.protocol_option.large_data_transfer",
5984 FT_BOOLEAN, 8, NULL, 0x08,
5985 "If set, this CO-WSP session supports Large data transfer", HFILL
5988 { &hf_capa_method_mor,
5990 "wsp.capability.method_mor",
5991 FT_UINT8, BASE_DEC, NULL, 0x00,
5995 { &hf_capa_push_mor,
5997 "wsp.capability.push_mor",
5998 FT_UINT8, BASE_DEC, NULL, 0x00,
6002 { &hf_capa_extended_method,
6003 { "Extended Method",
6004 "wsp.capability.extended_method",
6005 FT_UINT8, BASE_HEX, NULL, 0x00,
6009 { &hf_capa_header_code_page,
6010 { "Header Code Page",
6011 "wsp.capability.code_page",
6012 FT_UINT8, BASE_HEX, NULL, 0x00,
6018 "wsp.capability.aliases",
6019 FT_BYTES, BASE_NONE, NULL, 0x00,
6023 { &hf_capa_client_message_size,
6024 { "Client Message Size",
6025 "wsp.capability.client_message_size",
6026 FT_UINT8, BASE_DEC, NULL, 0x00,
6027 "Client Message size (bytes)", HFILL
6030 { &hf_capa_server_message_size,
6031 { "Server Message Size",
6032 "wsp.capability.server_message_size",
6033 FT_UINT8, BASE_DEC, NULL, 0x00,
6034 "Server Message size (bytes)", HFILL
6037 { &hf_wsp_post_data,
6040 FT_NONE, BASE_NONE, NULL, 0x00,
6045 { &hf_wsp_push_data,
6048 FT_NONE, BASE_NONE, NULL, 0x00,
6052 { &hf_wsp_multipart_data,
6053 { "Data in this part",
6054 "wsp.multipart.data",
6055 FT_NONE, BASE_NONE, NULL, 0x00,
6056 "The data of 1 MIME-multipart part.", HFILL
6063 FT_UINT32, BASE_DEC, NULL, 0x00,
6064 "MIME part of multipart data.", HFILL
6067 { &hf_wsp_header_text_value,
6068 { "Header textual value",
6069 "wsp.header_text_value",
6070 FT_STRING, BASE_NONE, NULL, 0x00,
6074 { &hf_wsp_variable_value,
6076 "wsp.variable_value",
6077 FT_STRING, BASE_NONE, NULL, 0x00,
6081 { &hf_wsp_default_int,
6082 { "Default integer",
6084 FT_UINT32, BASE_DEC, NULL, 0x00,
6088 { &hf_wsp_default_string,
6089 { "Default string value",
6090 "wsp.default_string",
6091 FT_STRING, BASE_NONE, NULL, 0x00,
6095 { &hf_wsp_default_val_len,
6096 { "Default value len",
6097 "wsp.default_val_len",
6098 FT_UINT32, BASE_DEC, NULL, 0x00,
6102 { &hf_wsp_redirect_flags,
6104 "wsp.redirect.flags",
6105 FT_UINT8, BASE_HEX, NULL, 0x00,
6106 "Redirect Flags", HFILL
6109 { &hf_wsp_redirect_permanent,
6110 { "Permanent Redirect",
6111 "wsp.redirect.flags.permanent",
6112 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PERMANENT_REDIRECT,
6116 { &hf_wsp_redirect_reuse_security_session,
6117 { "Reuse Security Session",
6118 "wsp.redirect.flags.reuse_security_session",
6119 FT_BOOLEAN, 8, TFS(&tfs_yes_no), REUSE_SECURITY_SESSION,
6120 "If set, the existing Security Session may be reused", HFILL
6123 { &hf_redirect_addresses,
6124 { "Redirect Addresses",
6125 "wsp.redirect.addresses",
6126 FT_NONE, BASE_NONE, NULL, 0x00,
6127 "List of Redirect Addresses", HFILL
6134 { &hf_address_entry,
6137 FT_UINT32, BASE_DEC, NULL, 0x00,
6141 { &hf_address_flags_length,
6143 "wsp.address.flags",
6144 FT_UINT8, BASE_HEX, NULL, 0x00,
6145 "Address Flags/Length", HFILL
6148 { &hf_address_flags_length_bearer_type_included,
6149 { "Bearer Type Included",
6150 "wsp.address.flags.bearer_type_included",
6151 FT_BOOLEAN, 8, TFS(&tfs_yes_no), BEARER_TYPE_INCLUDED,
6152 "Address bearer type included", HFILL
6155 { &hf_address_flags_length_port_number_included,
6156 { "Port Number Included",
6157 "wsp.address.flags.port_number_included",
6158 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PORT_NUMBER_INCLUDED,
6159 "Address port number included", HFILL
6162 { &hf_address_flags_length_address_len,
6164 "wsp.address.flags.length",
6165 FT_UINT8, BASE_DEC, NULL, ADDRESS_LEN,
6169 { &hf_address_bearer_type,
6171 "wsp.address.bearer_type",
6172 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_bearer_types_ext, 0x0,
6176 { &hf_address_port_num,
6179 FT_UINT16, BASE_DEC, NULL, 0x0,
6183 { &hf_address_ipv4_addr,
6186 FT_IPv4, BASE_NONE, NULL, 0x0,
6187 "Address (IPv4)", HFILL
6190 { &hf_address_ipv6_addr,
6193 FT_IPv6, BASE_NONE, NULL, 0x0,
6194 "Address (IPv6)", HFILL
6199 "wsp.address.unknown",
6200 FT_BYTES, BASE_NONE, NULL, 0x0,
6201 "Address (unknown)", HFILL
6207 * New WSP header fields
6211 /* WSP header name */
6212 { &hf_hdr_name_value,
6214 "wsp.header.name_value",
6215 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &vals_field_names_ext, 0x7F,
6216 "Name of the WSP header as numeric value", HFILL
6219 { &hf_hdr_name_string,
6221 "wsp.header.name_string",
6222 FT_STRING, BASE_NONE, NULL, 0x0,
6223 "Name of the WSP header as string", HFILL
6226 /* WSP headers start here */
6229 "wsp.header.accept",
6230 FT_STRING, BASE_NONE, NULL, 0x00,
6231 "WSP header Accept", HFILL
6234 { &hf_hdr_accept_charset,
6236 "wsp.header.accept_charset",
6237 FT_STRING, BASE_NONE, NULL, 0x00,
6238 "WSP header Accept-Charset", HFILL
6241 { &hf_hdr_accept_encoding,
6242 { "Accept-Encoding",
6243 "wsp.header.accept_encoding",
6244 FT_STRING, BASE_NONE, NULL, 0x00,
6245 "WSP header Accept-Encoding", HFILL
6248 { &hf_hdr_accept_language,
6249 { "Accept-Language",
6250 "wsp.header.accept_language",
6251 FT_STRING, BASE_NONE, NULL, 0x00,
6252 "WSP header Accept-Language", HFILL
6255 { &hf_hdr_accept_ranges,
6257 "wsp.header.accept_ranges",
6258 FT_STRING, BASE_NONE, NULL, 0x00,
6259 "WSP header Accept-Ranges", HFILL
6265 FT_STRING, BASE_NONE, NULL, 0x00,
6266 "WSP header Age", HFILL
6272 FT_STRING, BASE_NONE, NULL, 0x00,
6273 "WSP header Allow", HFILL
6276 { &hf_hdr_authorization,
6278 "wsp.header.authorization",
6279 FT_STRING, BASE_NONE, NULL, 0x00,
6280 "WSP header Authorization", HFILL
6283 { &hf_hdr_authorization_scheme,
6284 { "Authorization Scheme",
6285 "wsp.header.authorization.scheme",
6286 FT_STRING, BASE_NONE, NULL, 0x00,
6287 "WSP header Authorization: used scheme", HFILL
6290 { &hf_hdr_authorization_user_id,
6292 "wsp.header.authorization.user_id",
6293 FT_STRING, BASE_NONE, NULL, 0x00,
6294 "WSP header Authorization: user ID for basic authorization", HFILL
6297 { &hf_hdr_authorization_password,
6299 "wsp.header.authorization.password",
6300 FT_STRING, BASE_NONE, NULL, 0x00,
6301 "WSP header Authorization: password for basic authorization", HFILL
6304 { &hf_hdr_cache_control,
6306 "wsp.header.cache_control",
6307 FT_STRING, BASE_NONE, NULL, 0x00,
6308 "WSP header Cache-Control", HFILL
6311 { &hf_hdr_connection,
6313 "wsp.header.connection",
6314 FT_STRING, BASE_NONE, NULL, 0x00,
6315 "WSP header Connection", HFILL
6318 { &hf_hdr_content_base,
6320 "wsp.header.content_base",
6321 FT_STRING, BASE_NONE, NULL, 0x00,
6322 "WSP header Content-Base", HFILL
6325 { &hf_hdr_content_encoding,
6326 { "Content-Encoding",
6327 "wsp.header.content_encoding",
6328 FT_STRING, BASE_NONE, NULL, 0x00,
6329 "WSP header Content-Encoding", HFILL
6332 { &hf_hdr_content_language,
6333 { "Content-Language",
6334 "wsp.header.content_language",
6335 FT_STRING, BASE_NONE, NULL, 0x00,
6336 "WSP header Content-Language", HFILL
6339 { &hf_hdr_content_length,
6341 "wsp.header.content_length",
6342 FT_STRING, BASE_NONE, NULL, 0x00,
6343 "WSP header Content-Length", HFILL
6346 { &hf_hdr_content_location,
6347 { "Content-Location",
6348 "wsp.header.content_location",
6349 FT_STRING, BASE_NONE, NULL, 0x00,
6350 "WSP header Content-Location", HFILL
6353 { &hf_hdr_content_md5,
6355 "wsp.header.content_md5",
6356 FT_BYTES, BASE_NONE, NULL, 0x00,
6357 "WSP header Content-Md5", HFILL
6360 { &hf_hdr_content_range,
6362 "wsp.header.content_range",
6363 FT_STRING, BASE_NONE, NULL, 0x00,
6364 "WSP header Content-Range", HFILL
6367 { &hf_hdr_content_range_first_byte_pos,
6368 { "First-byte-position",
6369 "wsp.header.content_range.first_byte_pos",
6370 FT_UINT32, BASE_DEC, NULL, 0x00,
6371 "WSP header Content-Range: position of first byte", HFILL
6374 { &hf_hdr_content_range_entity_length,
6376 "wsp.header.content_range.entity_length",
6377 FT_UINT32, BASE_DEC, NULL, 0x00,
6378 "WSP header Content-Range: length of the entity", HFILL
6381 { &hf_hdr_content_type,
6383 "wsp.header.content_type",
6384 FT_STRING, BASE_NONE, NULL, 0x00,
6385 "WSP header Content-Type", HFILL
6391 FT_STRING, BASE_NONE, NULL, 0x00,
6392 "WSP header Date", HFILL
6398 FT_STRING, BASE_NONE, NULL, 0x00,
6399 "WSP header ETag", HFILL
6404 "wsp.header.expires",
6405 FT_STRING, BASE_NONE, NULL, 0x00,
6406 "WSP header Expires", HFILL
6412 FT_STRING, BASE_NONE, NULL, 0x00,
6413 "WSP header From", HFILL
6419 FT_STRING, BASE_NONE, NULL, 0x00,
6420 "WSP header Host", HFILL
6423 { &hf_hdr_if_modified_since,
6424 { "If-Modified-Since",
6425 "wsp.header.if_modified_since",
6426 FT_STRING, BASE_NONE, NULL, 0x00,
6427 "WSP header If-Modified-Since", HFILL
6432 "wsp.header.if_match",
6433 FT_STRING, BASE_NONE, NULL, 0x00,
6434 "WSP header If-Match", HFILL
6437 { &hf_hdr_if_none_match,
6439 "wsp.header.if_none_match",
6440 FT_STRING, BASE_NONE, NULL, 0x00,
6441 "WSP header If-None-Match", HFILL
6446 "wsp.header.if_range",
6447 FT_STRING, BASE_NONE, NULL, 0x00,
6448 "WSP header If-Range", HFILL
6451 { &hf_hdr_if_unmodified_since,
6452 { "If-Unmodified-Since",
6453 "wsp.header.if_unmodified_since",
6454 FT_STRING, BASE_NONE, NULL, 0x00,
6455 "WSP header If-Unmodified-Since", HFILL
6458 { &hf_hdr_last_modified,
6460 "wsp.header.last_modified",
6461 FT_STRING, BASE_NONE, NULL, 0x00,
6462 "WSP header Last-Modified", HFILL
6467 "wsp.header.location",
6468 FT_STRING, BASE_NONE, NULL, 0x00,
6469 "WSP header Location", HFILL
6472 { &hf_hdr_max_forwards,
6474 "wsp.header.max_forwards",
6475 FT_STRING, BASE_NONE, NULL, 0x00,
6476 "WSP header Max-Forwards", HFILL
6481 "wsp.header.pragma",
6482 FT_STRING, BASE_NONE, NULL, 0x00,
6483 "WSP header Pragma", HFILL
6486 { &hf_hdr_proxy_authenticate,
6487 { "Proxy-Authenticate",
6488 "wsp.header.proxy_authenticate",
6489 FT_STRING, BASE_NONE, NULL, 0x00,
6490 "WSP header Proxy-Authenticate", HFILL
6493 { &hf_hdr_proxy_authenticate_scheme,
6494 { "Authentication Scheme",
6495 "wsp.header.proxy_authenticate.scheme",
6496 FT_STRING, BASE_NONE, NULL, 0x00,
6497 "WSP header Proxy-Authenticate: used scheme", HFILL
6500 { &hf_hdr_proxy_authenticate_realm,
6501 { "Authentication Realm",
6502 "wsp.header.proxy_authenticate.realm",
6503 FT_STRING, BASE_NONE, NULL, 0x00,
6504 "WSP header Proxy-Authenticate: used realm", HFILL
6507 { &hf_hdr_proxy_authorization,
6508 { "Proxy-Authorization",
6509 "wsp.header.proxy_authorization",
6510 FT_STRING, BASE_NONE, NULL, 0x00,
6511 "WSP header Proxy-Authorization", HFILL
6514 { &hf_hdr_proxy_authorization_scheme,
6515 { "Authorization Scheme",
6516 "wsp.header.proxy_authorization.scheme",
6517 FT_STRING, BASE_NONE, NULL, 0x00,
6518 "WSP header Proxy-Authorization: used scheme", HFILL
6521 { &hf_hdr_proxy_authorization_user_id,
6523 "wsp.header.proxy_authorization.user_id",
6524 FT_STRING, BASE_NONE, NULL, 0x00,
6525 "WSP header Proxy-Authorization: user ID for basic authorization", HFILL
6528 { &hf_hdr_proxy_authorization_password,
6530 "wsp.header.proxy_authorization.password",
6531 FT_STRING, BASE_NONE, NULL, 0x00,
6532 "WSP header Proxy-Authorization: password for basic authorization", HFILL
6537 "wsp.header.public",
6538 FT_STRING, BASE_NONE, NULL, 0x00,
6539 "WSP header Public", HFILL
6545 FT_STRING, BASE_NONE, NULL, 0x00,
6546 "WSP header Range", HFILL
6549 { &hf_hdr_range_first_byte_pos,
6550 { "First-byte-position",
6551 "wsp.header.range.first_byte_pos",
6552 FT_UINT32, BASE_DEC, NULL, 0x00,
6553 "WSP header Range: position of first byte", HFILL
6556 { &hf_hdr_range_last_byte_pos,
6557 { "Last-byte-position",
6558 "wsp.header.range.last_byte_pos",
6559 FT_UINT32, BASE_DEC, NULL, 0x00,
6560 "WSP header Range: position of last byte", HFILL
6563 { &hf_hdr_range_suffix_length,
6565 "wsp.header.range.suffix_length",
6566 FT_UINT32, BASE_DEC, NULL, 0x00,
6567 "WSP header Range: length of the suffix", HFILL
6572 "wsp.header.referer",
6573 FT_STRING, BASE_NONE, NULL, 0x00,
6574 "WSP header Referer", HFILL
6577 { &hf_hdr_retry_after,
6579 "wsp.header.retry_after",
6580 FT_STRING, BASE_NONE, NULL, 0x00,
6581 "WSP header Retry-After", HFILL
6586 "wsp.header.server",
6587 FT_STRING, BASE_NONE, NULL, 0x00,
6588 "WSP header Server", HFILL
6591 { &hf_hdr_transfer_encoding,
6592 { "Transfer-Encoding",
6593 "wsp.header.transfer_encoding",
6594 FT_STRING, BASE_NONE, NULL, 0x00,
6595 "WSP header Transfer-Encoding", HFILL
6600 "wsp.header.upgrade",
6601 FT_STRING, BASE_NONE, NULL, 0x00,
6602 "WSP header Upgrade", HFILL
6605 { &hf_hdr_user_agent,
6607 "wsp.header.user_agent",
6608 FT_STRING, BASE_NONE, NULL, 0x00,
6609 "WSP header User-Agent", HFILL
6615 FT_STRING, BASE_NONE, NULL, 0x00,
6616 "WSP header Vary", HFILL
6622 FT_STRING, BASE_NONE, NULL, 0x00,
6623 "WSP header Via", HFILL
6628 "wsp.header.warning",
6629 FT_STRING, BASE_NONE, NULL, 0x00,
6630 "WSP header Warning", HFILL
6633 { &hf_hdr_warning_code,
6635 "wsp.header.warning.code",
6636 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_wsp_warning_code_ext, 0x00,
6637 "WSP header Warning code", HFILL
6640 { &hf_hdr_warning_agent,
6642 "wsp.header.warning.agent",
6643 FT_STRING, BASE_NONE, NULL, 0x00,
6644 "WSP header Warning agent", HFILL
6647 { &hf_hdr_warning_text,
6649 "wsp.header.warning.text",
6650 FT_STRING, BASE_NONE, NULL, 0x00,
6651 "WSP header Warning text", HFILL
6654 { &hf_hdr_www_authenticate,
6655 { "Www-Authenticate",
6656 "wsp.header.www_authenticate",
6657 FT_STRING, BASE_NONE, NULL, 0x00,
6658 "WSP header Www-Authenticate", HFILL
6661 { &hf_hdr_www_authenticate_scheme,
6662 { "Authentication Scheme",
6663 "wsp.header.www_authenticate.scheme",
6664 FT_STRING, BASE_NONE, NULL, 0x00,
6665 "WSP header WWW-Authenticate: used scheme", HFILL
6668 { &hf_hdr_www_authenticate_realm,
6669 { "Authentication Realm",
6670 "wsp.header.www_authenticate.realm",
6671 FT_STRING, BASE_NONE, NULL, 0x00,
6672 "WSP header WWW-Authenticate: used realm", HFILL
6675 { &hf_hdr_content_disposition,
6676 { "Content-Disposition",
6677 "wsp.header.content_disposition",
6678 FT_STRING, BASE_NONE, NULL, 0x00,
6679 "WSP header Content-Disposition", HFILL
6682 { &hf_hdr_application_id,
6684 "wsp.header.application_id",
6685 FT_STRING, BASE_NONE, NULL, 0x00,
6686 "WSP header Application-Id", HFILL
6689 { &hf_hdr_content_uri,
6691 "wsp.header.content_uri",
6692 FT_STRING, BASE_NONE, NULL, 0x00,
6693 "WSP header Content-Uri", HFILL
6696 { &hf_hdr_initiator_uri,
6698 "wsp.header.initiator_uri",
6699 FT_STRING, BASE_NONE, NULL, 0x00,
6700 "WSP header Initiator-Uri", HFILL
6703 { &hf_hdr_bearer_indication,
6704 { "Bearer-Indication",
6705 "wsp.header.bearer_indication",
6706 FT_STRING, BASE_NONE, NULL, 0x00,
6707 "WSP header Bearer-Indication", HFILL
6710 { &hf_hdr_push_flag,
6712 "wsp.header.push_flag",
6713 FT_STRING, BASE_NONE, NULL, 0x00,
6714 "WSP header Push-Flag", HFILL
6717 { &hf_hdr_push_flag_auth,
6718 { "Initiator URI is authenticated",
6719 "wsp.header.push_flag.authenticated",
6720 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x01,
6721 "The X-Wap-Initiator-URI has been authenticated.", HFILL
6724 { &hf_hdr_push_flag_trust,
6725 { "Content is trusted",
6726 "wsp.header.push_flag.trusted",
6727 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x02,
6728 "The push content is trusted.", HFILL
6731 { &hf_hdr_push_flag_last,
6732 { "Last push message",
6733 "wsp.header.push_flag.last",
6734 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x04,
6735 "Indicates whether this is the last push message.", HFILL
6740 "wsp.header.profile",
6741 FT_STRING, BASE_NONE, NULL, 0x00,
6742 "WSP header Profile", HFILL
6745 { &hf_hdr_profile_diff,
6747 "wsp.header.profile_diff",
6748 FT_STRING, BASE_NONE, NULL, 0x00,
6749 "WSP header Profile-Diff", HFILL
6752 { &hf_hdr_profile_warning,
6753 { "Profile-Warning",
6754 "wsp.header.profile_warning",
6755 FT_STRING, BASE_NONE, NULL, 0x00,
6756 "WSP header Profile-Warning", HFILL
6761 "wsp.header.expect",
6762 FT_STRING, BASE_NONE, NULL, 0x00,
6763 "WSP header Expect", HFILL
6769 FT_STRING, BASE_NONE, NULL, 0x00,
6770 "WSP header Te", HFILL
6775 "wsp.header.trailer",
6776 FT_STRING, BASE_NONE, NULL, 0x00,
6777 "WSP header Trailer", HFILL
6780 { &hf_hdr_x_wap_tod,
6782 "wsp.header.x_wap_tod",
6783 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
6784 "WSP header X-Wap-Tod", HFILL
6787 { &hf_hdr_content_id,
6789 "wsp.header.content_id",
6790 FT_STRING, BASE_NONE, NULL, 0x00,
6791 "WSP header Content-Id", HFILL
6794 { &hf_hdr_set_cookie,
6796 "wsp.header.set_cookie",
6797 FT_STRING, BASE_NONE, NULL, 0x00,
6798 "WSP header Set-Cookie", HFILL
6803 "wsp.header.cookie",
6804 FT_STRING, BASE_NONE, NULL, 0x00,
6805 "WSP header Cookie", HFILL
6808 { &hf_hdr_encoding_version,
6809 { "Encoding-Version",
6810 "wsp.header.encoding_version",
6811 FT_STRING, BASE_NONE, NULL, 0x00,
6812 "WSP header Encoding-Version", HFILL
6815 { &hf_hdr_x_wap_security,
6817 "wsp.header.x_wap_security",
6818 FT_STRING, BASE_NONE, NULL, 0x00,
6819 "WSP header X-Wap-Security", HFILL
6822 { &hf_hdr_x_wap_application_id,
6823 { "X-Wap-Application-Id",
6824 "wsp.header.x_wap_application_id",
6825 FT_STRING, BASE_NONE, NULL, 0x00,
6826 "WSP header X-Wap-Application-Id", HFILL
6829 { &hf_hdr_accept_application,
6830 { "Accept-Application",
6831 "wsp.header.accept_application",
6832 FT_STRING, BASE_NONE, NULL, 0x00,
6833 "WSP header Accept-Application", HFILL
6840 * Header Code Page: x-up-1
6842 { &hf_hdr_openwave_default_int,
6843 { "Default integer",
6845 FT_UINT32, BASE_DEC, NULL, 0x00,
6849 { &hf_hdr_openwave_default_string,
6850 { "Default string value",
6851 "wsp.default_string",
6852 FT_STRING, BASE_NONE, NULL, 0x00,
6856 { &hf_hdr_openwave_default_val_len,
6857 { "Default value len",
6858 "wsp.default_val_len",
6859 FT_UINT32, BASE_DEC, NULL, 0x00,
6863 { &hf_hdr_openwave_name_value,
6865 "wsp.header.name_value",
6866 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &vals_openwave_field_names_ext, 0x7F,
6867 "WSP Openwave header as numeric value", HFILL
6871 /* Textual headers */
6872 { &hf_hdr_openwave_x_up_proxy_operator_domain,
6873 { "x-up-proxy-operator-domain",
6874 "wsp.header.x_up_1.x_up_proxy_operator_domain",
6875 FT_STRING, BASE_NONE, NULL, 0x00,
6876 "WSP Openwave header x-up-proxy-operator-domain", HFILL
6879 { &hf_hdr_openwave_x_up_proxy_home_page,
6880 { "x-up-proxy-home-page",
6881 "wsp.header.x_up_1.x_up_proxy_home_page",
6882 FT_STRING, BASE_NONE, NULL, 0x00,
6883 "WSP Openwave header x-up-proxy-home-page", HFILL
6886 { &hf_hdr_openwave_x_up_proxy_uplink_version,
6887 { "x-up-proxy-uplink-version",
6888 "wsp.header.x_up_1.x_up_proxy_uplink_version",
6889 FT_STRING, BASE_NONE, NULL, 0x00,
6890 "WSP Openwave header x-up-proxy-uplink-version", HFILL
6893 { &hf_hdr_openwave_x_up_proxy_ba_realm,
6894 { "x-up-proxy-ba-realm",
6895 "wsp.header.x_up_1.x_up_proxy_ba_realm",
6896 FT_STRING, BASE_NONE, NULL, 0x00,
6897 "WSP Openwave header x-up-proxy-ba-realm", HFILL
6900 { &hf_hdr_openwave_x_up_proxy_request_uri,
6901 { "x-up-proxy-request-uri",
6902 "wsp.header.x_up_1.x_up_proxy_request_uri",
6903 FT_STRING, BASE_NONE, NULL, 0x00,
6904 "WSP Openwave header x-up-proxy-request-uri", HFILL
6907 { &hf_hdr_openwave_x_up_proxy_bookmark,
6908 { "x-up-proxy-bookmark",
6909 "wsp.header.x_up_1.x_up_proxy_bookmark",
6910 FT_STRING, BASE_NONE, NULL, 0x00,
6911 "WSP Openwave header x-up-proxy-bookmark", HFILL
6914 /* Integer-value headers */
6915 { &hf_hdr_openwave_x_up_proxy_push_seq,
6916 { "x-up-proxy-push-seq",
6917 "wsp.header.x_up_1.x_up_proxy_push_seq",
6918 FT_STRING, BASE_NONE, NULL, 0x00,
6919 "WSP Openwave header x-up-proxy-push-seq", HFILL
6922 { &hf_hdr_openwave_x_up_proxy_notify,
6923 { "x-up-proxy-notify",
6924 "wsp.header.x_up_1.x_up_proxy_notify",
6925 FT_STRING, BASE_NONE, NULL, 0x00,
6926 "WSP Openwave header x-up-proxy-notify", HFILL
6929 { &hf_hdr_openwave_x_up_proxy_net_ask,
6930 { "x-up-proxy-net-ask",
6931 "wsp.header.x_up_1.x_up_proxy_net_ask",
6932 FT_STRING, BASE_NONE, NULL, 0x00,
6933 "WSP Openwave header x-up-proxy-net-ask", HFILL
6936 { &hf_hdr_openwave_x_up_proxy_tod,
6938 "wsp.header.x_up_1.x_up_proxy_tod",
6939 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
6940 "WSP Openwave header x-up-proxy-tod", HFILL
6943 { &hf_hdr_openwave_x_up_proxy_ba_enable,
6944 { "x-up-proxy-ba-enable",
6945 "wsp.header.x_up_1.x_up_proxy_ba_enable",
6946 FT_STRING, BASE_NONE, NULL, 0x00,
6947 "WSP Openwave header x-up-proxy-ba-enable", HFILL
6950 { &hf_hdr_openwave_x_up_proxy_redirect_enable,
6951 { "x-up-proxy-redirect-enable",
6952 "wsp.header.x_up_1.x_up_proxy_redirect_enable",
6953 FT_STRING, BASE_NONE, NULL, 0x00,
6954 "WSP Openwave header x-up-proxy-redirect-enable", HFILL
6957 { &hf_hdr_openwave_x_up_proxy_redirect_status,
6958 { "x-up-proxy-redirect-status",
6959 "wsp.header.x_up_1.x_up_proxy_redirect_status",
6960 FT_STRING, BASE_NONE, NULL, 0x00,
6961 "WSP Openwave header x-up-proxy-redirect-status", HFILL
6964 { &hf_hdr_openwave_x_up_proxy_linger,
6965 { "x-up-proxy-linger",
6966 "wsp.header.x_up_1.x_up_proxy_linger",
6967 FT_STRING, BASE_NONE, NULL, 0x00,
6968 "WSP Openwave header x-up-proxy-linger", HFILL
6971 { &hf_hdr_openwave_x_up_proxy_enable_trust,
6972 { "x-up-proxy-enable-trust",
6973 "wsp.header.x_up_1.x_up_proxy_enable_trust",
6974 FT_STRING, BASE_NONE, NULL, 0x00,
6975 "WSP Openwave header x-up-proxy-enable-trust", HFILL
6978 { &hf_hdr_openwave_x_up_proxy_trust,
6979 { "x-up-proxy-trust",
6980 "wsp.header.x_up_1.x_up_proxy_trust",
6981 FT_STRING, BASE_NONE, NULL, 0x00,
6982 "WSP Openwave header x-up-proxy-trust", HFILL
6985 { &hf_hdr_openwave_x_up_devcap_has_color,
6986 { "x-up-devcap-has-color",
6987 "wsp.header.x_up_1.x_up_devcap_has_color",
6988 FT_STRING, BASE_NONE, NULL, 0x00,
6989 "WSP Openwave header x-up-devcap-has-color", HFILL
6992 { &hf_hdr_openwave_x_up_devcap_num_softkeys,
6993 { "x-up-devcap-num-softkeys",
6994 "wsp.header.x_up_1.x_up_devcap_num_softkeys",
6995 FT_STRING, BASE_NONE, NULL, 0x00,
6996 "WSP Openwave header x-up-devcap-num-softkeys", HFILL
6999 { &hf_hdr_openwave_x_up_devcap_softkey_size,
7000 { "x-up-devcap-softkey-size",
7001 "wsp.header.x_up_1.x_up_devcap_softkey_size",
7002 FT_STRING, BASE_NONE, NULL, 0x00,
7003 "WSP Openwave header x-up-devcap-softkey-size", HFILL
7006 { &hf_hdr_openwave_x_up_devcap_screen_chars,
7007 { "x-up-devcap-screen-chars",
7008 "wsp.header.x_up_1.x_up_devcap_screen_chars",
7009 FT_STRING, BASE_NONE, NULL, 0x00,
7010 "WSP Openwave header x-up-devcap-screen-chars", HFILL
7013 { &hf_hdr_openwave_x_up_devcap_screen_pixels,
7014 { "x-up-devcap-screen-pixels",
7015 "wsp.header.x_up_1.x_up_devcap_screen_pixels",
7016 FT_STRING, BASE_NONE, NULL, 0x00,
7017 "WSP Openwave header x-up-devcap-screen-pixels", HFILL
7020 { &hf_hdr_openwave_x_up_devcap_em_size,
7021 { "x-up-devcap-em-size",
7022 "wsp.header.x_up_1.x_up_devcap_em_size",
7023 FT_STRING, BASE_NONE, NULL, 0x00,
7024 "WSP Openwave header x-up-devcap-em-size", HFILL
7027 { &hf_hdr_openwave_x_up_devcap_screen_depth,
7028 { "x-up-devcap-screen-depth",
7029 "wsp.header.x_up_1.x_up_devcap_screen_depth",
7030 FT_STRING, BASE_NONE, NULL, 0x00,
7031 "WSP Openwave header x-up-devcap-screen-depth", HFILL
7034 { &hf_hdr_openwave_x_up_devcap_immed_alert,
7035 { "x-up-devcap-immed-alert",
7036 "wsp.header.x_up_1.x_up_devcap_immed_alert",
7037 FT_STRING, BASE_NONE, NULL, 0x00,
7038 "WSP Openwave header x-up-devcap-immed-alert", HFILL
7041 { &hf_hdr_openwave_x_up_devcap_gui,
7042 { "x-up-devcap-gui",
7043 "wsp.header.x_up_1.x_up_devcap_gui",
7044 FT_STRING, BASE_NONE, NULL, 0x00,
7045 "WSP Openwave header x-up-devcap-gui", HFILL
7048 { &hf_hdr_openwave_x_up_proxy_trans_charset,
7049 { "x-up-proxy-trans-charset",
7050 "wsp.header.x_up_1.x_up_proxy_trans_charset",
7051 FT_STRING, BASE_NONE, NULL, 0x00,
7052 "WSP Openwave header x-up-proxy-trans-charset", HFILL
7055 { &hf_hdr_openwave_x_up_proxy_push_accept,
7056 { "x-up-proxy-push-accept",
7057 "wsp.header.x_up_1.x_up_proxy_push_accept",
7058 FT_STRING, BASE_NONE, NULL, 0x00,
7059 "WSP Openwave header x-up-proxy-push-accept", HFILL
7064 /* Not used for now */
7065 { &hf_hdr_openwave_x_up_proxy_client_id,
7066 { "x-up-proxy-client-id",
7067 "wsp.header.x_up_1.x_up_proxy_client_id",
7068 FT_STRING, BASE_NONE, NULL, 0x00,
7069 "WSP Openwave header x-up-proxy-client-id", HFILL
7075 * Header value parameters
7081 FT_STRING, BASE_NONE, NULL, 0x00,
7082 "Q parameter", HFILL
7085 { &hf_parameter_charset,
7087 "wsp.parameter.charset",
7088 FT_STRING, BASE_NONE, NULL, 0x00,
7089 "Charset parameter", HFILL
7094 /* Setup protocol subtree array */
7095 static gint *ett[] = {
7097 &ett_header, /* Header field subtree */
7098 &ett_headers, /* Subtree for WSP headers */
7099 &ett_content_type_header,
7100 &ett_wsp_parameter_type,
7101 &ett_capabilities, /* CO-WSP Session Capabilities */
7102 &ett_capabilities_entry,
7103 &ett_proto_option_capability, /* CO-WSP Session single Capability */
7104 &ett_capabilities_extended_methods,
7105 &ett_capabilities_header_code_pages,
7107 &ett_redirect_flags,
7111 &ett_addresses, /* Addresses */
7112 &ett_address, /* Single address */
7114 &ett_add_content_type,
7115 &ett_accept_x_q_header,
7117 &ett_profile_diff_wbxml,
7121 &ett_x_wap_security,
7123 &ett_transfer_encoding,
7125 &ett_content_encoding,
7126 &ett_accept_encoding,
7127 &ett_content_disposition,
7130 &ett_text_or_date_value,
7134 &ett_integer_lookup,
7136 &ett_credentials_value,
7140 &ett_integer_lookup_value,
7143 &ett_profile_warning,
7144 &ett_encoding_version,
7148 &ett_openwave_default,
7151 static ei_register_info ei[] = {
7152 { &ei_wsp_capability_invalid, { "wsp.capability.invalid", PI_PROTOCOL, PI_WARN, "Invalid capability", EXPFILL }},
7153 { &ei_wsp_capability_length_invalid, { "wsp.capabilities.length.invalid", PI_PROTOCOL, PI_WARN, "Invalid capability length", EXPFILL }},
7154 { &ei_wsp_capability_encoding_invalid, { "wsp.capability_encoding.invalid", PI_PROTOCOL, PI_WARN, "Invalid capability encoding", EXPFILL }},
7155 { &ei_wsp_text_field_invalid, { "wsp.text_field_invalid", PI_PROTOCOL, PI_WARN, "Text field invalid", EXPFILL }},
7156 { &ei_wsp_invalid_parameter_value, { "wsp.invalid_parameter_value", PI_PROTOCOL, PI_WARN, "Invalid parameter value", EXPFILL }},
7157 { &ei_wsp_header_invalid_value, { "wsp.header_invalid_value", PI_PROTOCOL, PI_WARN, "Invalid header value", EXPFILL }},
7158 { &ei_hdr_x_wap_tod, { "wsp.header.x_wap_tod.not_text", PI_PROTOCOL, PI_WARN, "Should be encoded as a textual value", EXPFILL }},
7159 { &ei_wsp_undecoded_parameter, { "wsp.undecoded_parameter", PI_UNDECODED, PI_WARN, "Invalid parameter value", EXPFILL }},
7160 { &ei_wsp_trailing_quote, { "wsp.trailing_quote", PI_PROTOCOL, PI_WARN, "Quoted-string value has been encoded with a trailing quote", EXPFILL }},
7161 { &ei_wsp_header_invalid, { "wsp.header_invalid", PI_MALFORMED, PI_ERROR, "Malformed header", EXPFILL }},
7162 { &ei_wsp_oversized_uintvar, { "wsp.oversized_uintvar", PI_MALFORMED, PI_ERROR, "Uintvar is oversized", EXPFILL }}
7165 expert_module_t* expert_wsp;
7167 /* Register the protocol name and description */
7168 proto_wsp = proto_register_protocol( "Wireless Session Protocol", "WSP", "wsp");
7169 wsp_tap = register_tap("wsp");
7171 /* Init the hash table */
7172 /* wsp_sessions = g_hash_table_new(
7173 (GHashFunc) wsp_session_hash,
7174 (GEqualFunc)wsp_session_equal);*/
7176 /* Required function calls to register the header fields and subtrees used */
7177 proto_register_field_array(proto_wsp, hf, array_length(hf));
7178 proto_register_subtree_array(ett, array_length(ett));
7179 expert_wsp = expert_register_protocol(proto_wsp);
7180 expert_register_field_array(expert_wsp, ei, array_length(ei));
7182 register_dissector("wsp-co", dissect_wsp_fromwap_co, proto_wsp);
7183 register_dissector("wsp-cl", dissect_wsp_fromwap_cl, proto_wsp);
7184 heur_subdissector_list = register_heur_dissector_list("wsp", proto_wsp);
7186 wsp_fromudp_handle = create_dissector_handle(dissect_wsp_fromudp,
7191 proto_reg_handoff_wsp(void)
7194 * Get a handle for the WTP-over-UDP and the generic media dissectors.
7196 wtp_fromudp_handle = find_dissector_add_dependency("wtp-udp", proto_wsp);
7197 media_handle = find_dissector_add_dependency("media", proto_wsp);
7198 wbxml_uaprof_handle = find_dissector_add_dependency("wbxml-uaprof", proto_wsp);
7200 /* Only connection-less WSP has no previous handler */
7201 dissector_add_uint_range_with_preference("udp.port", UDP_PORT_WSP_RANGE, wsp_fromudp_handle);
7203 /* GSM SMS UD dissector can also carry WSP */
7204 dissector_add_uint("gsm_sms_ud.udh.port", UDP_PORT_WSP, wsp_fromudp_handle);
7205 dissector_add_uint("gsm_sms_ud.udh.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
7207 /* GSM SMS dissector can also carry WSP */
7208 dissector_add_uint("gsm_sms.udh.port", UDP_PORT_WSP, wsp_fromudp_handle);
7209 dissector_add_uint("gsm_sms.udh.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
7211 /* As the media types for WSP and HTTP are the same, the WSP dissector
7212 * uses the same string dissector table as the HTTP protocol. */
7213 media_type_table = find_dissector_table("media_type");
7215 /* This dissector is also called from the WTP and WTLS dissectors */
7219 * Session Initiation Request
7222 /* Register the protocol with Wireshark */
7224 proto_register_sir(void)
7226 /* Setup list of header fields */
7227 static hf_register_info hf[] = {
7229 { "Session Initiation Request",
7231 FT_NONE, BASE_NONE, NULL, 0x00,
7232 "Session Initiation Request content", HFILL
7238 FT_UINT8, BASE_DEC, NULL, 0x00,
7239 "Version of the Session Initiation Request document", HFILL
7242 { &hf_sir_app_id_list_len,
7243 { "Application-ID List Length",
7244 "wap.sir.app_id_list.length",
7245 FT_UINT32, BASE_DEC, NULL, 0x00,
7246 "Length of the Application-ID list (bytes)", HFILL
7249 { &hf_sir_app_id_list,
7250 { "Application-ID List",
7251 "wap.sir.app_id_list",
7252 FT_NONE, BASE_NONE, NULL, 0x00,
7256 { &hf_sir_wsp_contact_points_len,
7257 { "WSP Contact Points Length",
7258 "wap.sir.wsp_contact_points.length",
7259 FT_UINT32, BASE_DEC, NULL, 0x00,
7260 "Length of the WSP Contact Points list (bytes)", HFILL
7263 { &hf_sir_wsp_contact_points,
7264 { "WSP Contact Points",
7265 "wap.sir.wsp_contact_points",
7266 FT_NONE, BASE_NONE, NULL, 0x00,
7267 "WSP Contact Points list", HFILL
7270 { &hf_sir_contact_points_len,
7271 { "Non-WSP Contact Points Length",
7272 "wap.sir.contact_points.length",
7273 FT_UINT32, BASE_DEC, NULL, 0x00,
7274 "Length of the Non-WSP Contact Points list (bytes)", HFILL
7277 { &hf_sir_contact_points,
7278 { "Non-WSP Contact Points",
7279 "wap.sir.contact_points",
7280 FT_NONE, BASE_NONE, NULL, 0x00,
7281 "Non-WSP Contact Points list", HFILL
7284 { &hf_sir_protocol_options_len,
7285 { "Protocol Options List Entries",
7286 "wap.sir.protocol_options.length",
7287 FT_UINT32, BASE_DEC, NULL, 0x00,
7288 "Number of entries in the Protocol Options list", HFILL
7291 { &hf_sir_protocol_options,
7292 { "Protocol Options",
7293 "wap.sir.protocol_options",
7294 FT_UINT16, BASE_DEC, VALS(vals_sir_protocol_options), 0x00,
7295 "Protocol Options list", HFILL
7298 { &hf_sir_prov_url_len,
7299 { "X-Wap-ProvURL Length",
7300 "wap.sir.prov_url.length",
7301 FT_UINT32, BASE_DEC, NULL, 0x00,
7302 "Length of the X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL
7308 FT_STRING, BASE_NONE, NULL, 0x00,
7309 "X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL
7312 { &hf_sir_cpi_tag_len,
7313 { "CPITag List Entries",
7314 "wap.sir.cpi_tag.length",
7315 FT_UINT32, BASE_DEC, NULL, 0x00,
7316 "Number of entries in the CPITag list", HFILL
7322 FT_BYTES, BASE_NONE, NULL, 0x00,
7323 "CPITag (OTA-HTTP)", HFILL
7328 /* Setup protocol subtree array */
7329 static gint *ett[] = {
7330 &ett_sir /* Session Initiation Request */
7333 static tap_param wsp_stat_params[] = {
7334 { PARAM_FILTER, "filter", "Filter", NULL, TRUE }
7337 static stat_tap_table_ui wsp_stat_table = {
7338 REGISTER_STAT_GROUP_TELEPHONY,
7339 "WAP-WSP Packet Counter",
7345 wsp_stat_free_table_item,
7347 sizeof(wsp_stat_fields)/sizeof(stat_tap_table_item), wsp_stat_fields,
7348 sizeof(wsp_stat_params)/sizeof(tap_param), wsp_stat_params,
7354 /* Register the dissector */
7355 proto_sir = proto_register_protocol(
7356 "WAP Session Initiation Request", /* protocol name for use by wireshark */
7357 "WAP SIR", /* short version of name */
7358 "wap-sir" /* Abbreviated protocol name,
7360 < URL:http://www.iana.org/assignments/port-numbers/ >
7364 /* Register header fields and protocol subtrees */
7365 proto_register_field_array(proto_sir, hf, array_length(hf));
7366 proto_register_subtree_array(ett, array_length(ett));
7368 register_stat_tap_table_ui(&wsp_stat_table);
7373 proto_reg_handoff_sir(void)
7375 dissector_handle_t sir_handle;
7377 sir_handle = create_dissector_handle(dissect_sir, proto_sir);
7379 /* Add dissector bindings for SIR dissection */
7380 dissector_add_string("media_type", "application/vnd.wap.sia", sir_handle);
7391 * indent-tabs-mode: nil
7394 * ex: set shiftwidth=4 tabstop=8 expandtab:
7395 * :indentSize=4:tabSize=8:noTabs=true: