3 * Routines to dissect WSP component of WAP traffic.
7 * Refer to the AUTHORS file or the AUTHORS section in the man page
8 * for contacting the author(s) of this file.
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * WAP dissector based on original work by Ben Fowler
15 * Updated by Neil Hunter.
17 * WTLS support by Alexandre P. Ferreira (Splice IP).
19 * Openwave header support by Dermot Bradley (Openwave).
21 * Code optimizations, header value dissection simplification with parse error
22 * notification and macros, extra missing headers, WBXML registration,
23 * summary line of WSP PDUs,
24 * Session Initiation Request dissection
27 * TODO - Move parts of dissection before and other parts after "if (tree)",
28 * for example skip almost all but content type in replies if tree is closed.
30 * This program is free software; you can redistribute it and/or
31 * modify it under the terms of the GNU General Public License
32 * as published by the Free Software Foundation; either version 2
33 * of the License, or (at your option) any later version.
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
50 #include <epan/packet.h>
51 #include <epan/conversation.h>
53 #include "packet-wap.h"
54 #include "packet-wsp.h"
56 /* General-purpose debug logger.
57 * Requires double parentheses because of variable arguments of printf().
59 * Enable debug logging for WSP by defining AM_CFLAGS
60 * so that it contains "-DDEBUG_wsp"
64 g_print("%s:%u: ", __FILE__, __LINE__); \
70 /* Statistics (see doc/README.tapping) */
72 static int wsp_tap = -1;
75 /* File scoped variables for the protocol and registered fields */
76 static int proto_wsp = HF_EMPTY;
77 static int proto_sir = HF_EMPTY;
80 * Initialize the header field pointers
83 /* WSP header fields and their subfields if available */
84 static int hf_hdr_name = HF_EMPTY;
85 static int hf_hdr_accept = HF_EMPTY;
86 static int hf_hdr_accept_charset = HF_EMPTY;
87 static int hf_hdr_accept_encoding = HF_EMPTY;
88 static int hf_hdr_accept_language = HF_EMPTY;
89 static int hf_hdr_accept_ranges = HF_EMPTY;
90 static int hf_hdr_age = HF_EMPTY;
91 static int hf_hdr_allow = HF_EMPTY;
92 static int hf_hdr_authorization = HF_EMPTY;
93 static int hf_hdr_authorization_scheme = HF_EMPTY; /* Subfield */
94 static int hf_hdr_authorization_user_id = HF_EMPTY; /* Subfield */
95 static int hf_hdr_authorization_password = HF_EMPTY; /* Subfield */
96 static int hf_hdr_cache_control = HF_EMPTY;
97 static int hf_hdr_connection = HF_EMPTY;
98 static int hf_hdr_content_base = HF_EMPTY;
99 static int hf_hdr_content_encoding = HF_EMPTY;
100 static int hf_hdr_content_language = HF_EMPTY;
101 static int hf_hdr_content_length = HF_EMPTY;
102 static int hf_hdr_content_location = HF_EMPTY;
103 static int hf_hdr_content_md5 = HF_EMPTY;
104 static int hf_hdr_content_range = HF_EMPTY;
105 static int hf_hdr_content_range_first_byte_pos = HF_EMPTY; /* Subfield */
106 static int hf_hdr_content_range_entity_length = HF_EMPTY; /* Subfield */
107 static int hf_hdr_content_type = HF_EMPTY;
108 static int hf_hdr_date = HF_EMPTY;
109 static int hf_hdr_etag = HF_EMPTY;
110 static int hf_hdr_expires = HF_EMPTY;
111 static int hf_hdr_from = HF_EMPTY;
112 static int hf_hdr_host = HF_EMPTY;
113 static int hf_hdr_if_modified_since = HF_EMPTY;
114 static int hf_hdr_if_match = HF_EMPTY;
115 static int hf_hdr_if_none_match = HF_EMPTY;
116 static int hf_hdr_if_range = HF_EMPTY;
117 static int hf_hdr_if_unmodified_since = HF_EMPTY;
118 static int hf_hdr_last_modified = HF_EMPTY;
119 static int hf_hdr_location = HF_EMPTY;
120 static int hf_hdr_max_forwards = HF_EMPTY;
121 static int hf_hdr_pragma = HF_EMPTY;
122 static int hf_hdr_proxy_authenticate = HF_EMPTY;
123 static int hf_hdr_proxy_authenticate_scheme = HF_EMPTY; /* Subfield */
124 static int hf_hdr_proxy_authenticate_realm = HF_EMPTY; /* Subfield */
125 static int hf_hdr_proxy_authorization = HF_EMPTY;
126 static int hf_hdr_proxy_authorization_scheme = HF_EMPTY; /* Subfield */
127 static int hf_hdr_proxy_authorization_user_id = HF_EMPTY; /* Subfield */
128 static int hf_hdr_proxy_authorization_password = HF_EMPTY; /* Subfield */
129 static int hf_hdr_public = HF_EMPTY;
130 static int hf_hdr_range = HF_EMPTY;
131 static int hf_hdr_range_first_byte_pos = HF_EMPTY; /* Subfield */
132 static int hf_hdr_range_last_byte_pos = HF_EMPTY; /* Subfield */
133 static int hf_hdr_range_suffix_length = HF_EMPTY; /* Subfield */
134 static int hf_hdr_referer = HF_EMPTY;
135 static int hf_hdr_retry_after = HF_EMPTY;
136 static int hf_hdr_server = HF_EMPTY;
137 static int hf_hdr_transfer_encoding = HF_EMPTY;
138 static int hf_hdr_upgrade = HF_EMPTY;
139 static int hf_hdr_user_agent = HF_EMPTY;
140 static int hf_hdr_vary = HF_EMPTY;
141 static int hf_hdr_via = HF_EMPTY;
142 static int hf_hdr_warning = HF_EMPTY;
143 static int hf_hdr_warning_code = HF_EMPTY; /* Subfield */
144 static int hf_hdr_warning_agent = HF_EMPTY; /* Subfield */
145 static int hf_hdr_warning_text = HF_EMPTY; /* Subfield */
146 static int hf_hdr_www_authenticate = HF_EMPTY;
147 static int hf_hdr_www_authenticate_scheme = HF_EMPTY; /* Subfield */
148 static int hf_hdr_www_authenticate_realm = HF_EMPTY; /* Subfield */
149 static int hf_hdr_content_disposition = HF_EMPTY;
150 static int hf_hdr_application_id = HF_EMPTY;
151 static int hf_hdr_content_uri = HF_EMPTY;
152 static int hf_hdr_initiator_uri = HF_EMPTY;
153 static int hf_hdr_bearer_indication = HF_EMPTY;
154 static int hf_hdr_push_flag = HF_EMPTY;
155 static int hf_hdr_push_flag_auth = HF_EMPTY; /* Subfield */
156 static int hf_hdr_push_flag_trust = HF_EMPTY; /* Subfield */
157 static int hf_hdr_push_flag_last = HF_EMPTY; /* Subfield */
158 static int hf_hdr_profile = HF_EMPTY;
159 static int hf_hdr_profile_diff = HF_EMPTY;
160 static int hf_hdr_profile_warning = HF_EMPTY;
161 static int hf_hdr_expect = HF_EMPTY;
162 static int hf_hdr_te = HF_EMPTY;
163 static int hf_hdr_trailer = HF_EMPTY;
164 static int hf_hdr_x_wap_tod = HF_EMPTY;
165 static int hf_hdr_content_id = HF_EMPTY;
166 static int hf_hdr_set_cookie = HF_EMPTY;
167 static int hf_hdr_cookie = HF_EMPTY;
168 static int hf_hdr_encoding_version = HF_EMPTY;
169 static int hf_hdr_x_wap_security = HF_EMPTY;
170 static int hf_hdr_x_wap_application_id = HF_EMPTY;
171 static int hf_hdr_accept_application = HF_EMPTY;
174 /* Openwave headers */
175 static int hf_hdr_openwave_x_up_proxy_operator_domain = HF_EMPTY;
176 static int hf_hdr_openwave_x_up_proxy_home_page = HF_EMPTY;
177 static int hf_hdr_openwave_x_up_proxy_uplink_version = HF_EMPTY;
178 static int hf_hdr_openwave_x_up_proxy_ba_realm = HF_EMPTY;
179 static int hf_hdr_openwave_x_up_proxy_request_uri = HF_EMPTY;
181 static int hf_hdr_openwave_x_up_proxy_client_id = HF_EMPTY;
183 static int hf_hdr_openwave_x_up_proxy_bookmark = HF_EMPTY;
184 static int hf_hdr_openwave_x_up_proxy_push_seq = HF_EMPTY;
185 static int hf_hdr_openwave_x_up_proxy_notify = HF_EMPTY;
186 static int hf_hdr_openwave_x_up_proxy_net_ask = HF_EMPTY;
187 static int hf_hdr_openwave_x_up_proxy_tod = HF_EMPTY;
188 static int hf_hdr_openwave_x_up_proxy_ba_enable = HF_EMPTY;
189 static int hf_hdr_openwave_x_up_proxy_redirect_enable = HF_EMPTY;
190 static int hf_hdr_openwave_x_up_proxy_redirect_status = HF_EMPTY;
191 static int hf_hdr_openwave_x_up_proxy_linger = HF_EMPTY;
192 static int hf_hdr_openwave_x_up_proxy_enable_trust = HF_EMPTY;
193 static int hf_hdr_openwave_x_up_proxy_trust = HF_EMPTY;
194 static int hf_hdr_openwave_x_up_devcap_has_color = HF_EMPTY;
195 static int hf_hdr_openwave_x_up_devcap_num_softkeys = HF_EMPTY;
196 static int hf_hdr_openwave_x_up_devcap_softkey_size = HF_EMPTY;
197 static int hf_hdr_openwave_x_up_devcap_screen_chars = HF_EMPTY;
198 static int hf_hdr_openwave_x_up_devcap_screen_pixels = HF_EMPTY;
199 static int hf_hdr_openwave_x_up_devcap_em_size = HF_EMPTY;
200 static int hf_hdr_openwave_x_up_devcap_screen_depth = HF_EMPTY;
201 static int hf_hdr_openwave_x_up_devcap_immed_alert = HF_EMPTY;
202 static int hf_hdr_openwave_x_up_devcap_gui = HF_EMPTY;
203 static int hf_hdr_openwave_x_up_proxy_trans_charset = HF_EMPTY;
204 static int hf_hdr_openwave_x_up_proxy_push_accept = HF_EMPTY;
207 /* WSP parameter fields */
208 static int hf_parameter_q = HF_EMPTY;
209 static int hf_parameter_charset = HF_EMPTY;
211 static int hf_parameter_textual = HF_EMPTY;
212 static int hf_parameter_type = HF_EMPTY;
213 static int hf_parameter_name = HF_EMPTY;
214 static int hf_parameter_filename = HF_EMPTY;
215 static int hf_parameter_start = HF_EMPTY;
216 static int hf_parameter_start_info = HF_EMPTY;
217 static int hf_parameter_comment = HF_EMPTY;
218 static int hf_parameter_domain = HF_EMPTY;
219 static int hf_parameter_path = HF_EMPTY;
220 static int hf_parameter_sec = HF_EMPTY;
221 static int hf_parameter_mac = HF_EMPTY;
222 static int hf_parameter_upart_type = HF_EMPTY;
223 static int hf_parameter_upart_type_value = HF_EMPTY;
224 static int hf_parameter_level = HF_EMPTY;
227 /* Old header fields */
229 static int hf_wsp_header_tid = HF_EMPTY;
230 static int hf_wsp_header_pdu_type = HF_EMPTY;
231 static int hf_wsp_version_major = HF_EMPTY;
232 static int hf_wsp_version_minor = HF_EMPTY;
233 /* Session capabilities (CO-WSP) */
234 static int hf_capabilities_length = HF_EMPTY;
235 static int hf_capabilities_section = HF_EMPTY;
236 static int hf_capa_client_sdu_size = HF_EMPTY;
237 static int hf_capa_server_sdu_size = HF_EMPTY;
238 static int hf_capa_protocol_options = HF_EMPTY;
239 static int hf_capa_protocol_option_confirmed_push = HF_EMPTY; /* Subfield */
240 static int hf_capa_protocol_option_push = HF_EMPTY; /* Subfield */
241 static int hf_capa_protocol_option_session_resume = HF_EMPTY; /* Subfield */
242 static int hf_capa_protocol_option_ack_headers = HF_EMPTY; /* Subfield */
243 static int hf_capa_protocol_option_large_data_transfer = HF_EMPTY; /* Subfield */
244 static int hf_capa_method_mor = HF_EMPTY;
245 static int hf_capa_push_mor = HF_EMPTY;
246 static int hf_capa_extended_methods = HF_EMPTY;
247 static int hf_capa_header_code_pages = HF_EMPTY;
248 static int hf_capa_aliases = HF_EMPTY;
249 static int hf_capa_client_message_size = HF_EMPTY;
250 static int hf_capa_server_message_size = HF_EMPTY;
252 static int hf_wsp_header_uri_len = HF_EMPTY;
253 static int hf_wsp_header_uri = HF_EMPTY;
254 static int hf_wsp_server_session_id = HF_EMPTY;
255 static int hf_wsp_header_status = HF_EMPTY;
256 static int hf_wsp_header_length = HF_EMPTY;
257 static int hf_wsp_headers_section = HF_EMPTY;
258 static int hf_wsp_parameter_type = HF_EMPTY;
259 static int hf_wsp_parameter_name = HF_EMPTY;
260 static int hf_wsp_parameter_filename = HF_EMPTY;
261 static int hf_wsp_parameter_start = HF_EMPTY;
262 static int hf_wsp_parameter_start_info = HF_EMPTY;
263 static int hf_wsp_parameter_comment = HF_EMPTY;
264 static int hf_wsp_parameter_domain = HF_EMPTY;
265 static int hf_wsp_parameter_path = HF_EMPTY;
266 static int hf_wsp_parameter_sec = HF_EMPTY;
267 static int hf_wsp_parameter_mac = HF_EMPTY;
268 static int hf_wsp_parameter_upart_type = HF_EMPTY;
269 static int hf_wsp_parameter_level = HF_EMPTY;
270 static int hf_wsp_parameter_size = HF_EMPTY;
272 static int hf_wsp_reply_data = HF_EMPTY;
274 static int hf_wsp_post_data = HF_EMPTY;
276 static int hf_wsp_push_data = HF_EMPTY;
277 static int hf_wsp_multipart_data = HF_EMPTY;
279 static int hf_wsp_mpart = HF_EMPTY;
281 /* Header code page shift sequence */
282 static int hf_wsp_header_shift_code = HF_EMPTY;
284 /* WSP Redirect fields */
285 static int hf_wsp_redirect_flags = HF_EMPTY;
286 static int hf_wsp_redirect_permanent = HF_EMPTY;
287 static int hf_wsp_redirect_reuse_security_session = HF_EMPTY;
288 static int hf_redirect_addresses = HF_EMPTY;
291 static int hf_address_entry = HF_EMPTY;
292 static int hf_address_flags_length = HF_EMPTY;
293 static int hf_address_flags_length_bearer_type_included = HF_EMPTY; /* Subfield */
294 static int hf_address_flags_length_port_number_included = HF_EMPTY; /* Subfield */
295 static int hf_address_flags_length_address_len = HF_EMPTY; /* Subfield */
296 static int hf_address_bearer_type = HF_EMPTY;
297 static int hf_address_port_num = HF_EMPTY;
298 static int hf_address_ipv4_addr = HF_EMPTY;
299 static int hf_address_ipv6_addr = HF_EMPTY;
300 static int hf_address_addr = HF_EMPTY;
302 /* Session Initiation Request fields */
303 static int hf_sir_section = HF_EMPTY;
304 static int hf_sir_version = HF_EMPTY;
305 static int hf_sir_app_id_list_len = HF_EMPTY;
306 static int hf_sir_app_id_list = HF_EMPTY;
307 static int hf_sir_wsp_contact_points_len = HF_EMPTY;
308 static int hf_sir_wsp_contact_points = HF_EMPTY;
309 static int hf_sir_contact_points_len = HF_EMPTY;
310 static int hf_sir_contact_points = HF_EMPTY;
311 static int hf_sir_protocol_options_len = HF_EMPTY;
312 static int hf_sir_protocol_options = HF_EMPTY;
313 static int hf_sir_prov_url_len = HF_EMPTY;
314 static int hf_sir_prov_url = HF_EMPTY;
315 static int hf_sir_cpi_tag_len = HF_EMPTY;
316 static int hf_sir_cpi_tag = HF_EMPTY;
319 * Initialize the subtree pointers
323 static int ett_wsp = ETT_EMPTY;
324 /* WSP headers tree */
325 static int ett_header = ETT_EMPTY;
326 /* WSP header subtree */
327 static int ett_headers = ETT_EMPTY;
328 /* CO-WSP session capabilities */
329 static int ett_capabilities = ETT_EMPTY;
330 static int ett_capability = ETT_EMPTY;
331 static int ett_post = ETT_EMPTY;
332 static int ett_redirect_flags = ETT_EMPTY;
333 static int ett_address_flags = ETT_EMPTY;
334 static int ett_multiparts = ETT_EMPTY;
335 static int ett_mpartlist = ETT_EMPTY;
336 /* Session Initiation Request tree */
337 static int ett_sir = ETT_EMPTY;
338 static int ett_addresses = ETT_EMPTY;
339 static int ett_address = ETT_EMPTY;
343 /* Handle for WSP-over-UDP dissector */
344 static dissector_handle_t wsp_fromudp_handle;
346 /* Handle for WTP-over-UDP dissector */
347 static dissector_handle_t wtp_fromudp_handle;
349 /* Handle for generic media dissector */
350 static dissector_handle_t media_handle;
352 /* Handle for WBXML-encoded UAPROF dissector */
353 static dissector_handle_t wbxml_uaprof_handle;
355 static const value_string wsp_vals_pdu_type[] = {
356 { 0x00, "Reserved" },
358 { 0x02, "ConnectReply" },
359 { 0x03, "Redirect" },
361 { 0x05, "Disconnect" },
363 { 0x07, "ConfirmedPush" },
367 /* 0x10 - 0x3F Unassigned */
375 /* 0x45 - 0x4F Unassigned (Get PDU) */
376 /* 0x50 - 0x5F Extended method (Get PDU) */
377 { 0x50, "Extended Get Method 0"},
378 { 0x51, "Extended Get Method 1"},
379 { 0x52, "Extended Get Method 2"},
380 { 0x53, "Extended Get Method 3"},
381 { 0x54, "Extended Get Method 4"},
382 { 0x55, "Extended Get Method 5"},
383 { 0x56, "Extended Get Method 6"},
384 { 0x57, "Extended Get Method 7"},
385 { 0x58, "Extended Get Method 8"},
386 { 0x59, "Extended Get Method 9"},
387 { 0x5A, "Extended Get Method 10"},
388 { 0x5B, "Extended Get Method 11"},
389 { 0x5C, "Extended Get Method 12"},
390 { 0x5D, "Extended Get Method 13"},
391 { 0x5E, "Extended Get Method 14"},
392 { 0x5F, "Extended Get Method 15"},
397 /* 0x62 - 0x6F Unassigned (Post PDU) */
398 /* 0x70 - 0x7F Extended method (Post PDU) */
399 { 0x70, "Extended Post Method 0"},
400 { 0x71, "Extended Post Method 1"},
401 { 0x72, "Extended Post Method 2"},
402 { 0x73, "Extended Post Method 3"},
403 { 0x74, "Extended Post Method 4"},
404 { 0x75, "Extended Post Method 5"},
405 { 0x76, "Extended Post Method 6"},
406 { 0x77, "Extended Post Method 7"},
407 { 0x78, "Extended Post Method 8"},
408 { 0x79, "Extended Post Method 9"},
409 { 0x7A, "Extended Post Method 10"},
410 { 0x7B, "Extended Post Method 11"},
411 { 0x7C, "Extended Post Method 12"},
412 { 0x7D, "Extended Post Method 13"},
413 { 0x7E, "Extended Post Method 14"},
414 { 0x7F, "Extended Post Method 15"},
416 /* 0x80 - 0xFF Reserved */
421 value_string_ext wsp_vals_pdu_type_ext = VALUE_STRING_EXT_INIT(wsp_vals_pdu_type);
423 /* The WSP status codes are inherited from the HTTP status codes */
424 static const value_string wsp_vals_status[] = {
425 /* 0x00 - 0x0F Reserved */
427 { 0x10, "100 Continue" },
428 { 0x11, "101 Switching Protocols" },
431 { 0x21, "201 Created" },
432 { 0x22, "202 Accepted" },
433 { 0x23, "203 Non-Authoritative Information" },
434 { 0x24, "204 No Content" },
435 { 0x25, "205 Reset Content" },
436 { 0x26, "206 Partial Content" },
438 { 0x30, "300 Multiple Choices" },
439 { 0x31, "301 Moved Permanently" },
440 { 0x32, "302 Moved Temporarily" },
441 { 0x33, "303 See Other" },
442 { 0x34, "304 Not Modified" },
443 { 0x35, "305 Use Proxy" },
444 { 0x37, "307 Temporary Redirect" },
446 { 0x40, "400 Bad Request" },
447 { 0x41, "401 Unauthorised" },
448 { 0x42, "402 Payment Required" },
449 { 0x43, "403 Forbidden" },
450 { 0x44, "404 Not Found" },
451 { 0x45, "405 Method Not Allowed" },
452 { 0x46, "406 Not Acceptable" },
453 { 0x47, "407 Proxy Authentication Required" },
454 { 0x48, "408 Request Timeout" },
455 { 0x49, "409 Conflict" },
456 { 0x4A, "410 Gone" },
457 { 0x4B, "411 Length Required" },
458 { 0x4C, "412 Precondition Failed" },
459 { 0x4D, "413 Request Entity Too Large" },
460 { 0x4E, "414 Request-URI Too Large" },
461 { 0x4F, "415 Unsupported Media Type" },
462 { 0x50, "416 Requested Range Not Satisfiable" },
463 { 0x51, "417 Expectation Failed" },
465 { 0x60, "500 Internal Server Error" },
466 { 0x61, "501 Not Implemented" },
467 { 0x62, "502 Bad Gateway" },
468 { 0x63, "503 Service Unavailable" },
469 { 0x64, "504 Gateway Timeout" },
470 { 0x65, "505 WSP/HTTP Version Not Supported" },
474 value_string_ext wsp_vals_status_ext = VALUE_STRING_EXT_INIT(wsp_vals_status);
476 static const value_string vals_wsp_reason_codes[] = {
477 { 0xE0, "Protocol Error (Illegal PDU)" },
478 { 0xE1, "Session disconnected" },
479 { 0xE2, "Session suspended" },
480 { 0xE3, "Session resumed" },
481 { 0xE4, "Peer congested" },
482 { 0xE5, "Session connect failed" },
483 { 0xE6, "Maximum receive unit size exceeded" },
484 { 0xE7, "Maximum outstanding requests exceeded" },
485 { 0xE8, "Peer request" },
486 { 0xE9, "Network error" },
487 { 0xEA, "User request" },
488 { 0xEB, "No specific cause, no retries" },
489 { 0xEC, "Push message cannot be delivered" },
490 { 0xED, "Push message discarded" },
491 { 0xEE, "Content type cannot be processed" },
495 value_string_ext vals_wsp_reason_codes_ext = VALUE_STRING_EXT_INIT(vals_wsp_reason_codes);
500 #define FN_ACCEPT 0x00
501 #define FN_ACCEPT_CHARSET_DEP 0x01 /* encoding version 1.1, deprecated */
502 #define FN_ACCEPT_ENCODING_DEP 0x02 /* encoding version 1.1, deprecated */
503 #define FN_ACCEPT_LANGUAGE 0x03
504 #define FN_ACCEPT_RANGES 0x04
506 #define FN_ALLOW 0x06
507 #define FN_AUTHORIZATION 0x07
508 #define FN_CACHE_CONTROL_DEP 0x08 /* encoding version 1.1, deprecated */
509 #define FN_CONNECTION 0x09
510 #define FN_CONTENT_BASE 0x0A
511 #define FN_CONTENT_ENCODING 0x0B
512 #define FN_CONTENT_LANGUAGE 0x0C
513 #define FN_CONTENT_LENGTH 0x0D
514 #define FN_CONTENT_LOCATION 0x0E
515 #define FN_CONTENT_MD5 0x0F
516 #define FN_CONTENT_RANGE_DEP 0x10 /* encoding version 1.1, deprecated */
517 #define FN_CONTENT_TYPE 0x11
520 #define FN_EXPIRES 0x14
523 #define FN_IF_MODIFIED_SINCE 0x17
524 #define FN_IF_MATCH 0x18
525 #define FN_IF_NONE_MATCH 0x19
526 #define FN_IF_RANGE 0x1A
527 #define FN_IF_UNMODIFIED_SINCE 0x1B
528 #define FN_LOCATION 0x1C
529 #define FN_LAST_MODIFIED 0x1D
530 #define FN_MAX_FORWARDS 0x1E
531 #define FN_PRAGMA 0x1F
532 #define FN_PROXY_AUTHENTICATE 0x20
533 #define FN_PROXY_AUTHORIZATION 0x21
534 #define FN_PUBLIC 0x22
535 #define FN_RANGE 0x23
536 #define FN_REFERER 0x24
537 #define FN_RETRY_AFTER 0x25
538 #define FN_SERVER 0x26
539 #define FN_TRANSFER_ENCODING 0x27
540 #define FN_UPGRADE 0x28
541 #define FN_USER_AGENT 0x29
544 #define FN_WARNING 0x2C
545 #define FN_WWW_AUTHENTICATE 0x2D
546 #define FN_CONTENT_DISPOSITION 0x2E
547 #define FN_X_WAP_APPLICATION_ID 0x2F
548 #define FN_X_WAP_CONTENT_URI 0x30
549 #define FN_X_WAP_INITIATOR_URI 0x31
550 #define FN_ACCEPT_APPLICATION 0x32
551 #define FN_BEARER_INDICATION 0x33
552 #define FN_PUSH_FLAG 0x34
553 #define FN_PROFILE 0x35
554 #define FN_PROFILE_DIFF 0x36
555 #define FN_PROFILE_WARNING 0x37
556 #define FN_EXPECT 0x38
558 #define FN_TRAILER 0x3A
559 #define FN_ACCEPT_CHARSET 0x3B /* encoding version 1.3 */
560 #define FN_ACCEPT_ENCODING 0x3C /* encoding version 1.3 */
561 #define FN_CACHE_CONTROL 0x3D /* encoding version 1.3 */
562 #define FN_CONTENT_RANGE 0x3E /* encoding version 1.3 */
563 #define FN_X_WAP_TOD 0x3F
564 #define FN_CONTENT_ID 0x40
565 #define FN_SET_COOKIE 0x41
566 #define FN_COOKIE 0x42
567 #define FN_ENCODING_VERSION 0x43
568 #define FN_PROFILE_WARNING14 0x44 /* encoding version 1.4 */
569 #define FN_CONTENT_DISPOSITION14 0x45 /* encoding version 1.4 */
570 #define FN_X_WAP_SECURITY 0x46
571 #define FN_CACHE_CONTROL14 0x47 /* encoding version 1.4 */
572 #define FN_EXPECT15 0x48 /* encoding version 1.5 */
573 #define FN_X_WAP_LOC_INVOCATION 0x49
574 #define FN_X_WAP_LOC_DELIVERY 0x4A
578 * Openwave field names.
580 #define FN_OPENWAVE_PROXY_PUSH_ADDR 0x00
581 #define FN_OPENWAVE_PROXY_PUSH_ACCEPT 0x01
582 #define FN_OPENWAVE_PROXY_PUSH_SEQ 0x02
583 #define FN_OPENWAVE_PROXY_NOTIFY 0x03
584 #define FN_OPENWAVE_PROXY_OPERATOR_DOMAIN 0x04
585 #define FN_OPENWAVE_PROXY_HOME_PAGE 0x05
586 #define FN_OPENWAVE_DEVCAP_HAS_COLOR 0x06
587 #define FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS 0x07
588 #define FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE 0x08
589 #define FN_OPENWAVE_DEVCAP_SCREEN_CHARS 0x09
590 #define FN_OPENWAVE_DEVCAP_SCREEN_PIXELS 0x0A
591 #define FN_OPENWAVE_DEVCAP_EM_SIZE 0x0B
592 #define FN_OPENWAVE_DEVCAP_SCREEN_DEPTH 0x0C
593 #define FN_OPENWAVE_DEVCAP_IMMED_ALERT 0x0D
594 #define FN_OPENWAVE_PROXY_NET_ASK 0x0E
595 #define FN_OPENWAVE_PROXY_UPLINK_VERSION 0x0F
596 #define FN_OPENWAVE_PROXY_TOD 0x10
597 #define FN_OPENWAVE_PROXY_BA_ENABLE 0x11
598 #define FN_OPENWAVE_PROXY_BA_REALM 0x12
599 #define FN_OPENWAVE_PROXY_REDIRECT_ENABLE 0x13
600 #define FN_OPENWAVE_PROXY_REQUEST_URI 0x14
601 #define FN_OPENWAVE_PROXY_REDIRECT_STATUS 0x15
602 #define FN_OPENWAVE_PROXY_TRANS_CHARSET 0x16
603 #define FN_OPENWAVE_PROXY_LINGER 0x17
604 #define FN_OPENWAVE_PROXY_CLIENT_ID 0x18
605 #define FN_OPENWAVE_PROXY_ENABLE_TRUST 0x19
606 #define FN_OPENWAVE_PROXY_TRUST_OLD 0x1A
607 #define FN_OPENWAVE_PROXY_TRUST 0x20
608 #define FN_OPENWAVE_PROXY_BOOKMARK 0x21
609 #define FN_OPENWAVE_DEVCAP_GUI 0x22
611 static const value_string vals_openwave_field_names[] = {
612 { FN_OPENWAVE_PROXY_PUSH_ADDR, "x-up-proxy-push-addr" },
613 { FN_OPENWAVE_PROXY_PUSH_ACCEPT, "x-up-proxy-push-accept" },
614 { FN_OPENWAVE_PROXY_PUSH_SEQ, "x-up-proxy-seq" },
615 { FN_OPENWAVE_PROXY_NOTIFY, "x-up-proxy-notify" },
616 { FN_OPENWAVE_PROXY_OPERATOR_DOMAIN, "x-up-proxy-operator-domain" },
617 { FN_OPENWAVE_PROXY_HOME_PAGE, "x-up-proxy-home-page" },
618 { FN_OPENWAVE_DEVCAP_HAS_COLOR, "x-up-devcap-has-color" },
619 { FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS, "x-up-devcap-num-softkeys" },
620 { FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE, "x-up-devcap-softkey-size" },
621 { FN_OPENWAVE_DEVCAP_SCREEN_CHARS, "x-up-devcap-screen-chars" },
622 { FN_OPENWAVE_DEVCAP_SCREEN_PIXELS, "x-up-devcap-screen-pixels" },
623 { FN_OPENWAVE_DEVCAP_EM_SIZE, "x-up-devcap-em-size" },
624 { FN_OPENWAVE_DEVCAP_SCREEN_DEPTH, "x-up-devcap-screen-depth" },
625 { FN_OPENWAVE_DEVCAP_IMMED_ALERT, "x-up-devcap-immed-alert" },
626 { FN_OPENWAVE_PROXY_NET_ASK, "x-up-proxy-net-ask" },
627 { FN_OPENWAVE_PROXY_UPLINK_VERSION, "x-up-proxy-uplink-version" },
628 { FN_OPENWAVE_PROXY_TOD, "x-up-proxy-tod" },
629 { FN_OPENWAVE_PROXY_BA_ENABLE, "x-up-proxy-ba-enable" },
630 { FN_OPENWAVE_PROXY_BA_REALM, "x-up-proxy-ba-realm" },
631 { FN_OPENWAVE_PROXY_REDIRECT_ENABLE, "x-up-proxy-redirect-enable" },
632 { FN_OPENWAVE_PROXY_REQUEST_URI, "x-up-proxy-request-uri" },
633 { FN_OPENWAVE_PROXY_REDIRECT_STATUS, "x-up-proxy-redirect-status" },
634 { FN_OPENWAVE_PROXY_TRANS_CHARSET, "x-up-proxy-trans-charset" },
635 { FN_OPENWAVE_PROXY_LINGER, "x-up-proxy-linger" },
636 { FN_OPENWAVE_PROXY_CLIENT_ID, "x-up-proxy-client-id" },
637 { FN_OPENWAVE_PROXY_ENABLE_TRUST, "x-up-proxy-enable-trust" },
638 { FN_OPENWAVE_PROXY_TRUST_OLD, "x-up-proxy-trust-old" },
639 { FN_OPENWAVE_PROXY_TRUST, "x-up-proxy-trust" },
640 { FN_OPENWAVE_PROXY_BOOKMARK, "x-up-proxy-bookmark" },
641 { FN_OPENWAVE_DEVCAP_GUI, "x-up-devcap-gui" },
644 static value_string_ext vals_openwave_field_names_ext = VALUE_STRING_EXT_INIT(vals_openwave_field_names);
646 static const value_string vals_field_names[] = {
647 { FN_ACCEPT, "Accept" },
648 { FN_ACCEPT_CHARSET_DEP, "Accept-Charset (encoding 1.1)" },
649 { FN_ACCEPT_ENCODING_DEP, "Accept-Encoding (encoding 1.1)" },
650 { FN_ACCEPT_LANGUAGE, "Accept-Language" },
651 { FN_ACCEPT_RANGES, "Accept-Ranges" },
653 { FN_ALLOW, "Allow" },
654 { FN_AUTHORIZATION, "Authorization" },
655 { FN_CACHE_CONTROL_DEP, "Cache-Control (encoding 1.1)" },
656 { FN_CONNECTION, "Connection" },
657 { FN_CONTENT_BASE, "Content-Base" },
658 { FN_CONTENT_ENCODING, "Content-Encoding" },
659 { FN_CONTENT_LANGUAGE, "Content-Language" },
660 { FN_CONTENT_LENGTH, "Content-Length" },
661 { FN_CONTENT_LOCATION, "Content-Location" },
662 { FN_CONTENT_MD5, "Content-MD5" },
663 { FN_CONTENT_RANGE_DEP, "Content-Range (encoding 1.1)" },
664 { FN_CONTENT_TYPE, "Content-Type" },
667 { FN_EXPIRES, "Expires" },
670 { FN_IF_MODIFIED_SINCE, "If-Modified-Since" },
671 { FN_IF_MATCH, "If-Match" },
672 { FN_IF_NONE_MATCH, "If-None-Match" },
673 { FN_IF_RANGE, "If-Range" },
674 { FN_IF_UNMODIFIED_SINCE, "If-Unmodified-Since" },
675 { FN_LOCATION, "Location" },
676 { FN_LAST_MODIFIED, "Last-Modified" },
677 { FN_MAX_FORWARDS, "Max-Forwards" },
678 { FN_PRAGMA, "Pragma" },
679 { FN_PROXY_AUTHENTICATE, "Proxy-Authenticate" },
680 { FN_PROXY_AUTHORIZATION, "Proxy-Authorization" },
681 { FN_PUBLIC, "Public" },
682 { FN_RANGE, "Range" },
683 { FN_REFERER, "Referer" },
684 { FN_RETRY_AFTER, "Retry-After" },
685 { FN_SERVER, "Server" },
686 { FN_TRANSFER_ENCODING, "Transfer-Encoding" },
687 { FN_UPGRADE, "Upgrade" },
688 { FN_USER_AGENT, "User-Agent" },
691 { FN_WARNING, "Warning" },
692 { FN_WWW_AUTHENTICATE, "WWW-Authenticate" },
693 { FN_CONTENT_DISPOSITION, "Content-Disposition" },
694 { FN_X_WAP_APPLICATION_ID, "X-Wap-Application-ID" },
695 { FN_X_WAP_CONTENT_URI, "X-Wap-Content-URI" },
696 { FN_X_WAP_INITIATOR_URI, "X-Wap-Initiator-URI" },
697 { FN_ACCEPT_APPLICATION, "Accept-Application" },
698 { FN_BEARER_INDICATION, "Bearer-Indication" },
699 { FN_PUSH_FLAG, "Push-Flag" },
700 { FN_PROFILE, "Profile" },
701 { FN_PROFILE_DIFF, "Profile-Diff" },
702 { FN_PROFILE_WARNING, "Profile-Warning" },
703 { FN_EXPECT, "Expect" },
705 { FN_TRAILER, "Trailer" },
706 { FN_ACCEPT_CHARSET, "Accept-Charset" },
707 { FN_ACCEPT_ENCODING, "Accept-Encoding" },
708 { FN_CACHE_CONTROL, "Cache-Control" },
709 { FN_CONTENT_RANGE, "Content-Range" },
710 { FN_X_WAP_TOD, "X-Wap-Tod" },
711 { FN_CONTENT_ID, "Content-ID" },
712 { FN_SET_COOKIE, "Set-Cookie" },
713 { FN_COOKIE, "Cookie" },
714 { FN_ENCODING_VERSION, "Encoding-Version" },
715 { FN_PROFILE_WARNING14, "Profile-Warning (encoding 1.4)" },
716 { FN_CONTENT_DISPOSITION14,"Content-Disposition (encoding 1.4)" },
717 { FN_X_WAP_SECURITY, "X-WAP-Security" },
718 { FN_CACHE_CONTROL14, "Cache-Control (encoding 1.4)" },
719 /* encoding-version 1.5 */
720 { FN_EXPECT15, "Expect (encoding 1.5)" },
721 { FN_X_WAP_LOC_INVOCATION, "X-Wap-Loc-Invocation" },
722 { FN_X_WAP_LOC_DELIVERY, "X-Wap-Loc-Delivery" },
725 static value_string_ext vals_field_names_ext = VALUE_STRING_EXT_INIT(vals_field_names);
728 * Bearer types (from the WDP specification).
732 #define BT_GSM_USSD 0x02
733 #define BT_GSM_SMS 0x03
734 #define BT_ANSI_136_GUTS 0x04
735 #define BT_IS_95_SMS 0x05
736 #define BT_IS_95_CSD 0x06
737 #define BT_IS_95_PACKET_DATA 0x07
738 #define BT_ANSI_136_CSD 0x08
739 #define BT_ANSI_136_PACKET_DATA 0x09
740 #define BT_GSM_CSD 0x0A
741 #define BT_GSM_GPRS 0x0B
742 #define BT_GSM_USSD_IPv4 0x0C
743 #define BT_AMPS_CDPD 0x0D
744 #define BT_PDC_CSD 0x0E
745 #define BT_PDC_PACKET_DATA 0x0F
746 #define BT_IDEN_SMS 0x10
747 #define BT_IDEN_CSD 0x11
748 #define BT_IDEN_PACKET_DATA 0x12
749 #define BT_PAGING_FLEX 0x13
750 #define BT_PHS_SMS 0x14
751 #define BT_PHS_CSD 0x15
752 #define BT_GSM_USSD_GSM_SC 0x16
753 #define BT_TETRA_SDS_ITSI 0x17
754 #define BT_TETRA_SDS_MSISDN 0x18
755 #define BT_TETRA_PACKET_DATA 0x19
756 #define BT_PAGING_REFLEX 0x1A
757 #define BT_GSM_USSD_MSISDN 0x1B
758 #define BT_MOBITEX_MPAK 0x1C
759 #define BT_ANSI_136_GHOST 0x1D
761 static const value_string vals_bearer_types[] = {
764 { BT_GSM_USSD, "GSM USSD" },
765 { BT_GSM_SMS, "GSM SMS" },
766 { BT_ANSI_136_GUTS, "ANSI-136 GUTS/R-Data" },
767 { BT_IS_95_SMS, "IS-95 CDMA SMS" },
768 { BT_IS_95_CSD, "IS-95 CDMA CSD" },
769 { BT_IS_95_PACKET_DATA, "IS-95 CDMA Packet data" },
770 { BT_ANSI_136_CSD, "ANSI-136 CSD" },
771 { BT_ANSI_136_PACKET_DATA, "ANSI-136 Packet data" },
772 { BT_GSM_CSD, "GSM CSD" },
773 { BT_GSM_GPRS, "GSM GPRS" },
774 { BT_GSM_USSD_IPv4, "GSM USSD (IPv4 addresses)" },
775 { BT_AMPS_CDPD, "AMPS CDPD" },
776 { BT_PDC_CSD, "PDC CSD" },
777 { BT_PDC_PACKET_DATA, "PDC Packet data" },
778 { BT_IDEN_SMS, "IDEN SMS" },
779 { BT_IDEN_CSD, "IDEN CSD" },
780 { BT_IDEN_PACKET_DATA, "IDEN Packet data" },
781 { BT_PAGING_FLEX, "Paging network FLEX(TM)" },
782 { BT_PHS_SMS, "PHS SMS" },
783 { BT_PHS_CSD, "PHS CSD" },
784 { BT_GSM_USSD_GSM_SC, "GSM USSD (GSM Service Code addresses)" },
785 { BT_TETRA_SDS_ITSI, "TETRA SDS (ITSI addresses)" },
786 { BT_TETRA_SDS_MSISDN, "TETRA SDS (MSISDN addresses)" },
787 { BT_TETRA_PACKET_DATA, "TETRA Packet data" },
788 { BT_PAGING_REFLEX, "Paging network ReFLEX(TM)" },
789 { BT_GSM_USSD_MSISDN, "GSM USSD (MSISDN addresses)" },
790 { BT_MOBITEX_MPAK, "Mobitex MPAK" },
791 { BT_ANSI_136_GHOST, "ANSI-136 GHOST/R-Data" },
794 static value_string_ext vals_bearer_types_ext = VALUE_STRING_EXT_INIT(vals_bearer_types);
796 static const value_string vals_content_types[] = {
797 /* Well-known media types */
800 { 0x02, "text/html" },
801 { 0x03, "text/plain" },
802 { 0x04, "text/x-hdml" },
803 { 0x05, "text/x-ttml" },
804 { 0x06, "text/x-vCalendar" },
805 { 0x07, "text/x-vCard" },
806 { 0x08, "text/vnd.wap.wml" },
807 { 0x09, "text/vnd.wap.wmlscript" },
808 { 0x0A, "text/vnd.wap.channel" },
809 { 0x0B, "multipart/*" },
810 { 0x0C, "multipart/mixed" },
811 { 0x0D, "multipart/form-data" },
812 { 0x0E, "multipart/byteranges" },
813 { 0x0F, "multipart/alternative" },
814 { 0x10, "application/*" },
815 { 0x11, "application/java-vm" },
816 { 0x12, "application/x-www-form-urlencoded" },
817 { 0x13, "application/x-hdmlc" },
818 { 0x14, "application/vnd.wap.wmlc" },
819 { 0x15, "application/vnd.wap.wmlscriptc" },
820 { 0x16, "application/vnd.wap.channelc" },
821 { 0x17, "application/vnd.wap.uaprof" },
822 { 0x18, "application/vnd.wap.wtls-ca-certificate" },
823 { 0x19, "application/vnd.wap.wtls-user-certificate" },
824 { 0x1A, "application/x-x509-ca-cert" },
825 { 0x1B, "application/x-x509-user-cert" },
827 { 0x1D, "image/gif" },
828 { 0x1E, "image/jpeg" },
829 { 0x1F, "image/tiff" },
830 { 0x20, "image/png" },
831 { 0x21, "image/vnd.wap.wbmp" },
832 { 0x22, "application/vnd.wap.multipart.*" },
833 { 0x23, "application/vnd.wap.multipart.mixed" },
834 { 0x24, "application/vnd.wap.multipart.form-data" },
835 { 0x25, "application/vnd.wap.multipart.byteranges" },
836 { 0x26, "application/vnd.wap.multipart.alternative" },
837 { 0x27, "application/xml" },
838 { 0x28, "text/xml" },
839 { 0x29, "application/vnd.wap.wbxml" },
840 { 0x2A, "application/x-x968-cross-cert" },
841 { 0x2B, "application/x-x968-ca-cert" },
842 { 0x2C, "application/x-x968-user-cert" },
843 { 0x2D, "text/vnd.wap.si" },
844 { 0x2E, "application/vnd.wap.sic" },
845 { 0x2F, "text/vnd.wap.sl" },
846 { 0x30, "application/vnd.wap.slc" },
847 { 0x31, "text/vnd.wap.co" },
848 { 0x32, "application/vnd.wap.coc" },
849 { 0x33, "application/vnd.wap.multipart.related" },
850 { 0x34, "application/vnd.wap.sia" },
851 { 0x35, "text/vnd.wap.connectivity-xml" },
852 { 0x36, "application/vnd.wap.connectivity-wbxml" },
853 { 0x37, "application/pkcs7-mime" },
854 { 0x38, "application/vnd.wap.hashed-certificate" },
855 { 0x39, "application/vnd.wap.signed-certificate" },
856 { 0x3A, "application/vnd.wap.cert-response" },
857 { 0x3B, "application/xhtml+xml" },
858 { 0x3C, "application/wml+xml" },
859 { 0x3D, "text/css" },
860 { 0x3E, "application/vnd.wap.mms-message" },
861 { 0x3F, "application/vnd.wap.rollover-certificate" },
862 { 0x40, "application/vnd.wap.locc+wbxml"},
863 { 0x41, "application/vnd.wap.loc+xml"},
864 { 0x42, "application/vnd.syncml.dm+wbxml"},
865 { 0x43, "application/vnd.syncml.dm+xml"},
866 { 0x44, "application/vnd.syncml.notification"},
867 { 0x45, "application/vnd.wap.xhtml+xml"},
868 { 0x46, "application/vnd.wv.csp.cir"},
869 { 0x47, "application/vnd.oma.dd+xml"},
870 { 0x48, "application/vnd.oma.drm.message"},
871 { 0x49, "application/vnd.oma.drm.content"},
872 { 0x4A, "application/vnd.oma.drm.rights+xml"},
873 { 0x4B, "application/vnd.oma.drm.rights+wbxml"},
874 { 0x4C, "application/vnd.wv.csp+xml"},
875 { 0x4D, "application/vnd.wv.csp+wbxml"},
876 /* The following media types are registered by 3rd parties */
877 { 0x0201, "application/vnd.uplanet.cachop-wbxml" },
878 { 0x0202, "application/vnd.uplanet.signal" },
879 { 0x0203, "application/vnd.uplanet.alert-wbxml" },
880 { 0x0204, "application/vnd.uplanet.list-wbxml" },
881 { 0x0205, "application/vnd.uplanet.listcmd-wbxml" },
882 { 0x0206, "application/vnd.uplanet.channel-wbxml" },
883 { 0x0207, "application/vnd.uplanet.provisioning-status-uri" },
884 { 0x0208, "x-wap.multipart/vnd.uplanet.header-set" },
885 { 0x0209, "application/vnd.uplanet.bearer-choice-wbxml" },
886 { 0x020A, "application/vnd.phonecom.mmc-wbxml" },
887 { 0x020B, "application/vnd.nokia.syncset+wbxml" },
888 { 0x020C, "image/x-up-wpng"},
889 { 0x0300, "application/iota.mmc-wbxml"},
890 { 0x0301, "application/iota.mmc-xml"},
893 static value_string_ext vals_content_types_ext = VALUE_STRING_EXT_INIT(vals_content_types);
895 static const value_string vals_languages[] = {
897 { 0x01, "Afar (aa)" },
898 { 0x02, "Abkhazian (ab)" },
899 { 0x03, "Afrikaans (af)" },
900 { 0x04, "Amharic (am)" },
901 { 0x05, "Arabic (ar)" },
902 { 0x06, "Assamese (as)" },
903 { 0x07, "Aymara (ay)" },
904 { 0x08, "Azerbaijani (az)" },
905 { 0x09, "Bashkir (ba)" },
906 { 0x0A, "Byelorussian (be)" },
907 { 0x0B, "Bulgarian (bg)" },
908 { 0x0C, "Bihari (bh)" },
909 { 0x0D, "Bislama (bi)" },
910 { 0x0E, "Bengali; Bangla (bn)" },
911 { 0x0F, "Tibetan (bo)" },
912 { 0x10, "Breton (br)" },
913 { 0x11, "Catalan (ca)" },
914 { 0x12, "Corsican (co)" },
915 { 0x13, "Czech (cs)" },
916 { 0x14, "Welsh (cy)" },
917 { 0x15, "Danish (da)" },
918 { 0x16, "German (de)" },
919 { 0x17, "Bhutani (dz)" },
920 { 0x18, "Greek (el)" },
921 { 0x19, "English (en)" },
922 { 0x1A, "Esperanto (eo)" },
923 { 0x1B, "Spanish (es)" },
924 { 0x1C, "Estonian (et)" },
925 { 0x1D, "Basque (eu)" },
926 { 0x1E, "Persian (fa)" },
927 { 0x1F, "Finnish (fi)" },
928 { 0x20, "Fiji (fj)" },
929 { 0x21, "Urdu (ur)" },
930 { 0x22, "French (fr)" },
931 { 0x23, "Uzbek (uz)" },
932 { 0x24, "Irish (ga)" },
933 { 0x25, "Scots Gaelic (gd)" },
934 { 0x26, "Galician (gl)" },
935 { 0x27, "Guarani (gn)" },
936 { 0x28, "Gujarati (gu)" },
937 { 0x29, "Hausa (ha)" },
938 { 0x2A, "Hebrew (formerly iw) (he)" },
939 { 0x2B, "Hindi (hi)" },
940 { 0x2C, "Croatian (hr)" },
941 { 0x2D, "Hungarian (hu)" },
942 { 0x2E, "Armenian (hy)" },
943 { 0x2F, "Vietnamese (vi)" },
944 { 0x30, "Indonesian (formerly in) (id)" },
945 { 0x31, "Wolof (wo)" },
946 { 0x32, "Xhosa (xh)" },
947 { 0x33, "Icelandic (is)" },
948 { 0x34, "Italian (it)" },
949 { 0x35, "Yoruba (yo)" },
950 { 0x36, "Japanese (ja)" },
951 { 0x37, "Javanese (jw)" },
952 { 0x38, "Georgian (ka)" },
953 { 0x39, "Kazakh (kk)" },
954 { 0x3A, "Zhuang (za)" },
955 { 0x3B, "Cambodian (km)" },
956 { 0x3C, "Kannada (kn)" },
957 { 0x3D, "Korean (ko)" },
958 { 0x3E, "Kashmiri (ks)" },
959 { 0x3F, "Kurdish (ku)" },
960 { 0x40, "Kirghiz (ky)" },
961 { 0x41, "Chinese (zh)" },
962 { 0x42, "Lingala (ln)" },
963 { 0x43, "Laothian (lo)" },
964 { 0x44, "Lithuanian (lt)" },
965 { 0x45, "Latvian, Lettish (lv)" },
966 { 0x46, "Malagasy (mg)" },
967 { 0x47, "Maori (mi)" },
968 { 0x48, "Macedonian (mk)" },
969 { 0x49, "Malayalam (ml)" },
970 { 0x4A, "Mongolian (mn)" },
971 { 0x4B, "Moldavian (mo)" },
972 { 0x4C, "Marathi (mr)" },
973 { 0x4D, "Malay (ms)" },
974 { 0x4E, "Maltese (mt)" },
975 { 0x4F, "Burmese (my)" },
976 { 0x50, "Ukrainian (uk)" },
977 { 0x51, "Nepali (ne)" },
978 { 0x52, "Dutch (nl)" },
979 { 0x53, "Norwegian (no)" },
980 { 0x54, "Occitan (oc)" },
981 { 0x55, "(Afan) Oromo (om)" },
982 { 0x56, "Oriya (or)" },
983 { 0x57, "Punjabi (pa)" },
984 { 0x58, "Polish (po)" },
985 { 0x59, "Pashto, Pushto (ps)" },
986 { 0x5A, "Portuguese (pt)" },
987 { 0x5B, "Quechua (qu)" },
988 { 0x5C, "Zulu (zu)" },
989 { 0x5D, "Kirundi (rn)" },
990 { 0x5E, "Romanian (ro)" },
991 { 0x5F, "Russian (ru)" },
992 { 0x60, "Kinyarwanda (rw)" },
993 { 0x61, "Sanskrit (sa)" },
994 { 0x62, "Sindhi (sd)" },
995 { 0x63, "Sangho (sg)" },
996 { 0x64, "Serbo-Croatian (sh)" },
997 { 0x65, "Sinhalese (si)" },
998 { 0x66, "Slovak (sk)" },
999 { 0x67, "Slovenian (sl)" },
1000 { 0x68, "Samoan (sm)" },
1001 { 0x69, "Shona (sn)" },
1002 { 0x6A, "Somali (so)" },
1003 { 0x6B, "Albanian (sq)" },
1004 { 0x6C, "Serbian (sr)" },
1005 { 0x6D, "Siswati (ss)" },
1006 { 0x6E, "Sesotho (st)" },
1007 { 0x6F, "Sundanese (su)" },
1008 { 0x70, "Swedish (sv)" },
1009 { 0x71, "Swahili (sw)" },
1010 { 0x72, "Tamil (ta)" },
1011 { 0x73, "Telugu (te)" },
1012 { 0x74, "Tajik (tg)" },
1013 { 0x75, "Thai (th)" },
1014 { 0x76, "Tigrinya (ti)" },
1015 { 0x77, "Turkmen (tk)" },
1016 { 0x78, "Tagalog (tl)" },
1017 { 0x79, "Setswana (tn)" },
1018 { 0x7A, "Tonga (to)" },
1019 { 0x7B, "Turkish (tr)" },
1020 { 0x7C, "Tsonga (ts)" },
1021 { 0x7D, "Tatar (tt)" },
1022 { 0x7E, "Twi (tw)" },
1023 { 0x7F, "Uighur (ug)" },
1024 { 0x81, "Nauru (na)" },
1025 { 0x82, "Faeroese (fo)" },
1026 { 0x83, "Frisian (fy)" },
1027 { 0x84, "Interlingua (ia)" },
1028 { 0x85, "Volapuk (vo)" },
1029 { 0x86, "Interlingue (ie)" },
1030 { 0x87, "Inupiak (ik)" },
1031 { 0x88, "Yiddish (formerly ji) (yi)" },
1032 { 0x89, "Inuktitut (iu)" },
1033 { 0x8A, "Greenlandic (kl)" },
1034 { 0x8B, "Latin (la)" },
1035 { 0x8C, "Rhaeto-Romance (rm)" },
1038 static value_string_ext vals_languages_ext = VALUE_STRING_EXT_INIT(vals_languages);
1041 #define CACHE_CONTROL_NO_CACHE 0x00
1042 #define CACHE_CONTROL_NO_STORE 0x01
1043 #define CACHE_CONTROL_MAX_AGE 0x02
1044 #define CACHE_CONTROL_MAX_STALE 0x03
1045 #define CACHE_CONTROL_MIN_FRESH 0x04
1046 #define CACHE_CONTROL_ONLY_IF_CACHED 0x05
1047 #define CACHE_CONTROL_PUBLIC 0x06
1048 #define CACHE_CONTROL_PRIVATE 0x07
1049 #define CACHE_CONTROL_NO_TRANSFORM 0x08
1050 #define CACHE_CONTROL_MUST_REVALIDATE 0x09
1051 #define CACHE_CONTROL_PROXY_REVALIDATE 0x0A
1052 #define CACHE_CONTROL_S_MAXAGE 0x0B
1054 static const value_string vals_cache_control[] = {
1055 { CACHE_CONTROL_NO_CACHE, "no-cache" },
1056 { CACHE_CONTROL_NO_STORE, "no-store" },
1057 { CACHE_CONTROL_MAX_AGE, "max-age" },
1058 { CACHE_CONTROL_MAX_STALE, "max-stale" },
1059 { CACHE_CONTROL_MIN_FRESH, "min-fresh" },
1060 { CACHE_CONTROL_ONLY_IF_CACHED, "only-if-cached" },
1061 { CACHE_CONTROL_PUBLIC, "public" },
1062 { CACHE_CONTROL_PRIVATE, "private" },
1063 { CACHE_CONTROL_NO_TRANSFORM, "no-transform" },
1064 { CACHE_CONTROL_MUST_REVALIDATE, "must-revalidate" },
1065 { CACHE_CONTROL_PROXY_REVALIDATE, "proxy-revalidate" },
1066 { CACHE_CONTROL_S_MAXAGE, "s-max-age" },
1070 static value_string_ext vals_cache_control_ext = VALUE_STRING_EXT_INIT(vals_cache_control);
1072 static const value_string vals_wap_application_ids[] = {
1073 /* Well-known WAP applications */
1074 { 0x00, "x-wap-application:*"},
1075 { 0x01, "x-wap-application:push.sia"},
1076 { 0x02, "x-wap-application:wml.ua"},
1077 { 0x03, "x-wap-application:wta.ua"},
1078 { 0x04, "x-wap-application:mms.ua"},
1079 { 0x05, "x-wap-application:push.syncml"},
1080 { 0x06, "x-wap-application:loc.ua"},
1081 { 0x07, "x-wap-application:syncml.dm"},
1082 { 0x08, "x-wap-application:drm.ua"},
1083 { 0x09, "x-wap-application:emn.ua"},
1084 { 0x0A, "x-wap-application:wv.ua"},
1085 /* Registered by 3rd parties */
1086 { 0x8000, "x-wap-microsoft:localcontent.ua"},
1087 { 0x8001, "x-wap-microsoft:IMclient.ua"},
1088 { 0x8002, "x-wap-docomo:imode.mail.ua"},
1089 { 0x8003, "x-wap-docomo:imode.mr.ua"},
1090 { 0x8004, "x-wap-docomo:imode.mf.ua"},
1091 { 0x8005, "x-motorola:location.ua"},
1092 { 0x8006, "x-motorola:now.ua"},
1093 { 0x8007, "x-motorola:otaprov.ua"},
1094 { 0x8008, "x-motorola:browser.ua"},
1095 { 0x8009, "x-motorola:splash.ua"},
1096 /* 0x800A: unassigned */
1097 { 0x800B, "x-wap-nai:mvsw.command"},
1098 /* 0x800C -- 0x800F: unassigned */
1099 { 0x8010, "x-wap-openwave:iota.ua"},
1100 /* 0x8011 -- 0x8FFF: unassigned */
1101 { 0x9000, "x-wap-docomo:imode.mail2.ua"},
1102 { 0x9001, "x-oma-nec:otaprov.ua"},
1103 { 0x9002, "x-oma-nokia:call.ua"},
1104 { 0x9003, "x-oma-coremobility:sqa.ua"},
1108 static value_string_ext vals_wap_application_ids_ext = VALUE_STRING_EXT_INIT(vals_wap_application_ids);
1111 /* Parameters and well-known encodings */
1112 static const value_string vals_wsp_parameter_sec[] = {
1113 { 0x00, "NETWPIN" },
1114 { 0x01, "USERPIN" },
1115 { 0x02, "USERNETWPIN" },
1116 { 0x03, "USERPINMAC" },
1120 static value_string_ext vals_wsp_parameter_sec_ext = VALUE_STRING_EXT_INIT(vals_wsp_parameter_sec);
1122 /* Warning codes and mappings */
1123 static const value_string vals_wsp_warning_code[] = {
1124 { 10, "110 Response is stale" },
1125 { 11, "111 Revalidation failed" },
1126 { 12, "112 Disconnected operation" },
1127 { 13, "113 Heuristic expiration" },
1128 { 14, "214 Transformation applied" },
1129 { 99, "199/299 Miscellaneous warning" },
1133 static value_string_ext vals_wsp_warning_code_ext = VALUE_STRING_EXT_INIT(vals_wsp_warning_code);
1135 static const value_string vals_wsp_warning_code_short[] = {
1145 static value_string_ext vals_wsp_warning_code_short_ext = VALUE_STRING_EXT_INIT(vals_wsp_warning_code_short);
1147 /* Profile-Warning codes - see http://www.w3.org/TR/NOTE-CCPPexchange */
1148 static const value_string vals_wsp_profile_warning_code[] = {
1150 { 0x11, "101 Used stale profile" },
1151 { 0x12, "102 Not used profile" },
1152 { 0x20, "200 Not applied" },
1153 { 0x21, "101 Content selection applied" },
1154 { 0x22, "202 Content generation applied" },
1155 { 0x23, "203 Transformation applied" },
1159 static value_string_ext vals_wsp_profile_warning_code_ext = VALUE_STRING_EXT_INIT(vals_wsp_profile_warning_code);
1161 /* Well-known TE values */
1162 static const value_string vals_well_known_te[] = {
1163 { 0x82, "chunked" },
1164 { 0x83, "identity" },
1166 { 0x85, "compress" },
1167 { 0x86, "deflate" },
1171 static value_string_ext vals_well_known_te_ext = VALUE_STRING_EXT_INIT(vals_well_known_te);
1177 #define PERMANENT_REDIRECT 0x80
1178 #define REUSE_SECURITY_SESSION 0x40
1181 * Redirect address flags and length.
1183 #define BEARER_TYPE_INCLUDED 0x80
1184 #define PORT_NUMBER_INCLUDED 0x40
1185 #define ADDRESS_LEN 0x3f
1187 static const value_string vals_false_true[] = {
1194 WSP_PDU_RESERVED = 0x00,
1195 WSP_PDU_CONNECT = 0x01,
1196 WSP_PDU_CONNECTREPLY = 0x02,
1197 WSP_PDU_REDIRECT = 0x03, /* No sample data */
1198 WSP_PDU_REPLY = 0x04,
1199 WSP_PDU_DISCONNECT = 0x05,
1200 WSP_PDU_PUSH = 0x06, /* No sample data */
1201 WSP_PDU_CONFIRMEDPUSH = 0x07, /* No sample data */
1202 WSP_PDU_SUSPEND = 0x08, /* No sample data */
1203 WSP_PDU_RESUME = 0x09, /* No sample data */
1206 WSP_PDU_OPTIONS = 0x41, /* No sample data */
1207 WSP_PDU_HEAD = 0x42, /* No sample data */
1208 WSP_PDU_DELETE = 0x43, /* No sample data */
1209 WSP_PDU_TRACE = 0x44, /* No sample data */
1211 WSP_PDU_POST = 0x60,
1212 WSP_PDU_PUT = 0x61 /* No sample data */
1216 /* Dissector tables for handoff */
1217 static dissector_table_t media_type_table;
1218 static heur_dissector_list_t heur_subdissector_list;
1220 static void add_uri (proto_tree *, packet_info *, tvbuff_t *, guint, guint, proto_item *);
1222 static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
1223 static void add_multipart_data (proto_tree *, tvbuff_t *, packet_info *pinfo);
1225 static void add_capabilities (proto_tree *tree, tvbuff_t *tvb, guint8 pdu_type);
1229 * Dissect the WSP header part.
1230 * This function calls wkh_XXX functions that dissect well-known headers.
1232 static void add_headers (proto_tree *tree, tvbuff_t *tvb, int hf, packet_info *pinfo);
1234 /* The following macros define WSP basic data structures as found
1235 * in the ABNF notation of WSP headers.
1236 * Currently all text data types are mapped to text_string.
1238 #define is_short_integer(x) ( (x) & 0x80 )
1239 #define is_long_integer(x) ( (x) <= 30 )
1240 #define is_date_value(x) is_long_integer(x)
1241 #define is_integer_value(x) (is_short_integer(x) || is_long_integer(x))
1242 #define is_delta_seconds_value(x) is_integer_value(x)
1243 /* Text string == *TEXT 0x00, thus also an empty string matches the rule! */
1244 #define is_text_string(x) ( ((x) == 0) || ( ((x) >= 32) && ((x) <= 127)) )
1245 #define is_quoted_string(x) ( (x) == 0x22 ) /* " */
1246 #define is_token_text(x) is_text_string(x)
1247 #define is_text_value(x) is_text_string(x)
1248 #define is_uri_value(x) is_text_string(x)
1250 #define get_uintvar_integer(val,tvb,start,len,ok) \
1251 val = tvb_get_guintvar(tvb,start,&len); \
1252 if (len>5) ok = FALSE; else ok = TRUE;
1253 #define get_short_integer(val,tvb,start,len,ok) \
1254 val = tvb_get_guint8(tvb,start); \
1255 if (val & 0x80) ok = TRUE; else ok=FALSE; \
1256 val &= 0x7F; len = 1;
1257 #define get_long_integer(val,tvb,start,len,ok) \
1258 len = tvb_get_guint8(tvb,start); \
1259 ok = TRUE; /* Valid lengths for us are 1-4 */ \
1260 if (len==1) { val = tvb_get_guint8(tvb,start+1); } \
1261 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \
1262 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \
1263 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \
1265 len++; /* Add the 1st octet to the length */
1266 #define get_integer_value(val,tvb,start,len,ok) \
1267 len = tvb_get_guint8(tvb,start); \
1269 if (len & 0x80) { val = len & 0x7F; len = 0; } \
1270 else if (len==1) { val = tvb_get_guint8(tvb,start+1); } \
1271 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \
1272 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \
1273 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \
1275 len++; /* Add the 1st octet to the length */
1276 #define get_date_value(val,tvb,start,len,ok) \
1277 get_long_integer(val,tvb,start,len,ok)
1278 #define get_delta_seconds_value(val,tvb,start,len,ok) \
1279 get_integer_value(val,tvb,start,len,ok)
1281 /* NOTE - Do NOT call g_free() for the str returned after using it because the
1282 * get_text_string() macro now returns ep_alloc'd memory. */
1283 #define get_text_string(str,tvb,start,len,ok) \
1284 if (is_text_string(tvb_get_guint8(tvb,start))) { \
1285 str = (gchar *)tvb_get_ephemeral_stringz(tvb,start,(gint *)&len); \
1287 } else { len = 0; str = NULL; ok = FALSE; }
1288 #define get_token_text(str,tvb,start,len,ok) \
1289 get_text_string(str,tvb,start,len,ok)
1290 #define get_extension_media(str,tvb,start,len,ok) \
1291 get_text_string(str,tvb,start,len,ok)
1292 #define get_text_value(str,tvb,start,len,ok) \
1293 get_text_string(str,tvb,start,len,ok)
1294 #define get_quoted_string(str,tvb,start,len,ok) \
1295 get_text_string(str,tvb,start,len,ok)
1296 #define get_uri_value(str,tvb,start,len,ok) \
1297 get_text_string(str,tvb,start,len,ok)
1299 #define get_version_value(val,str,tvb,start,len,ok) \
1300 val = tvb_get_guint8(tvb,start); \
1302 if (val & 0x80) { /* High nibble "." Low nibble */ \
1305 str = g_strdup_printf("%u.%u", val >> 4, val & 0x0F); \
1306 } else { get_text_string(str,tvb,start,len,ok); }
1308 /* Parameter parser */
1310 parameter (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start, int len);
1312 parameter_value_q (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start);
1314 #define InvalidValueForHeader(hdr) \
1315 "<Error: Invalid value for the '" hdr "' header>"
1316 #define InvalidTextualHeader \
1317 "<Error: Invalid zero-length textual header>"
1318 #define TrailingQuoteWarning \
1319 " <Warning: Quoted-string value has been encoded with a trailing quote>"
1321 /* WSP well-known header parsing function prototypes;
1322 * will be listed in the function lookup table WellKnownHeaders[] */
1323 static guint32 wkh_default (proto_tree *tree, tvbuff_t *tvb,
1324 guint32 hdr_start, packet_info *pinfo _U_);
1325 static guint32 wkh_accept (proto_tree *tree, tvbuff_t *tvb,
1326 guint32 hdr_start, packet_info *pinfo _U_);
1327 static guint32 wkh_content_type (proto_tree *tree, tvbuff_t *tvb,
1328 guint32 hdr_start, packet_info *pinfo _U_);
1329 static guint32 wkh_accept_charset (proto_tree *tree, tvbuff_t *tvb,
1330 guint32 hdr_start, packet_info *pinfo _U_);
1331 static guint32 wkh_accept_language (proto_tree *tree, tvbuff_t *tvb,
1332 guint32 hdr_start, packet_info *pinfo _U_);
1333 static guint32 wkh_connection (proto_tree *tree, tvbuff_t *tvb,
1334 guint32 hdr_start, packet_info *pinfo _U_);
1335 static guint32 wkh_push_flag (proto_tree *tree, tvbuff_t *tvb,
1336 guint32 header_start, packet_info *pinfo _U_);
1337 static guint32 wkh_vary (proto_tree *tree, tvbuff_t *tvb,
1338 guint32 hdr_start, packet_info *pinfo _U_);
1339 static guint32 wkh_accept_ranges (proto_tree *tree, tvbuff_t *tvb,
1340 guint32 hdr_start, packet_info *pinfo _U_);
1341 static guint32 wkh_content_disposition (proto_tree *tree, tvbuff_t *tvb,
1342 guint32 hdr_start, packet_info *pinfo _U_);
1343 static guint32 wkh_accept_encoding (proto_tree *tree, tvbuff_t *tvb,
1344 guint32 hdr_start, packet_info *pinfo _U_);
1345 static guint32 wkh_content_encoding (proto_tree *tree, tvbuff_t *tvb,
1346 guint32 hdr_start, packet_info *pinfo _U_);
1347 static guint32 wkh_transfer_encoding (proto_tree *tree, tvbuff_t *tvb,
1348 guint32 hdr_start, packet_info *pinfo _U_);
1349 static guint32 wkh_pragma (proto_tree *tree, tvbuff_t *tvb,
1350 guint32 hdr_start, packet_info *pinfo _U_);
1351 /* Single short-integer value */
1352 static guint32 wkh_x_wap_security (proto_tree *tree, tvbuff_t *tvb,
1353 guint32 hdr_start, packet_info *pinfo _U_);
1355 static guint32 wkh_content_base (proto_tree *tree, tvbuff_t *tvb,
1356 guint32 hdr_start, packet_info *pinfo _U_);
1357 static guint32 wkh_content_location (proto_tree *tree, tvbuff_t *tvb,
1358 guint32 hdr_start, packet_info *pinfo _U_);
1359 static guint32 wkh_etag (proto_tree *tree, tvbuff_t *tvb,
1360 guint32 hdr_start, packet_info *pinfo _U_);
1361 static guint32 wkh_from (proto_tree *tree, tvbuff_t *tvb,
1362 guint32 hdr_start, packet_info *pinfo _U_);
1363 static guint32 wkh_host (proto_tree *tree, tvbuff_t *tvb,
1364 guint32 hdr_start, packet_info *pinfo _U_);
1365 static guint32 wkh_if_match (proto_tree *tree, tvbuff_t *tvb,
1366 guint32 hdr_start, packet_info *pinfo _U_);
1367 static guint32 wkh_if_none_match (proto_tree *tree, tvbuff_t *tvb,
1368 guint32 hdr_start, packet_info *pinfo _U_);
1369 static guint32 wkh_location (proto_tree *tree, tvbuff_t *tvb,
1370 guint32 hdr_start, packet_info *pinfo _U_);
1371 static guint32 wkh_referer (proto_tree *tree, tvbuff_t *tvb,
1372 guint32 hdr_start, packet_info *pinfo _U_);
1373 static guint32 wkh_server (proto_tree *tree, tvbuff_t *tvb,
1374 guint32 hdr_start, packet_info *pinfo _U_);
1375 static guint32 wkh_user_agent (proto_tree *tree, tvbuff_t *tvb,
1376 guint32 hdr_start, packet_info *pinfo _U_);
1377 static guint32 wkh_upgrade (proto_tree *tree, tvbuff_t *tvb,
1378 guint32 hdr_start, packet_info *pinfo _U_);
1379 static guint32 wkh_via (proto_tree *tree, tvbuff_t *tvb,
1380 guint32 hdr_start, packet_info *pinfo _U_);
1381 static guint32 wkh_content_uri (proto_tree *tree, tvbuff_t *tvb,
1382 guint32 hdr_start, packet_info *pinfo _U_);
1383 static guint32 wkh_initiator_uri (proto_tree *tree, tvbuff_t *tvb,
1384 guint32 hdr_start, packet_info *pinfo _U_);
1385 static guint32 wkh_profile (proto_tree *tree, tvbuff_t *tvb,
1386 guint32 hdr_start, packet_info *pinfo _U_);
1387 static guint32 wkh_content_id (proto_tree *tree, tvbuff_t *tvb,
1388 guint32 hdr_start, packet_info *pinfo _U_);
1389 /* Date-value or text */
1390 static guint32 wkh_if_range (proto_tree *tree, tvbuff_t *tvb,
1391 guint32 hdr_start, packet_info *pinfo _U_);
1393 static guint32 wkh_date (proto_tree *tree, tvbuff_t *tvb,
1394 guint32 hdr_start, packet_info *pinfo _U_);
1395 static guint32 wkh_expires (proto_tree *tree, tvbuff_t *tvb,
1396 guint32 hdr_start, packet_info *pinfo _U_);
1397 static guint32 wkh_if_modified_since (proto_tree *tree, tvbuff_t *tvb,
1398 guint32 hdr_start, packet_info *pinfo _U_);
1399 static guint32 wkh_if_unmodified_since (proto_tree *tree, tvbuff_t *tvb,
1400 guint32 hdr_start, packet_info *pinfo _U_);
1401 static guint32 wkh_last_modified (proto_tree *tree, tvbuff_t *tvb,
1402 guint32 hdr_start, packet_info *pinfo _U_);
1403 /* Date-value with special meaning */
1404 static guint32 wkh_x_wap_tod (proto_tree *tree, tvbuff_t *tvb,
1405 guint32 hdr_start, packet_info *pinfo _U_);
1406 /* Delta-seconds-value */
1407 static guint32 wkh_age (proto_tree *tree, tvbuff_t *tvb,
1408 guint32 hdr_start, packet_info *pinfo _U_);
1410 static guint32 wkh_proxy_authenticate (proto_tree *tree, tvbuff_t *tvb,
1411 guint32 hdr_start, packet_info *pinfo _U_);
1412 static guint32 wkh_www_authenticate (proto_tree *tree, tvbuff_t *tvb,
1413 guint32 hdr_start, packet_info *pinfo _U_);
1415 static guint32 wkh_authorization (proto_tree *tree, tvbuff_t *tvb,
1416 guint32 hdr_start, packet_info *pinfo _U_);
1417 static guint32 wkh_proxy_authorization (proto_tree *tree, tvbuff_t *tvb,
1418 guint32 hdr_start, packet_info *pinfo _U_);
1420 static guint32 wkh_pragma (proto_tree *tree, tvbuff_t *tvb,
1421 guint32 hdr_start, packet_info *pinfo _U_);
1423 static guint32 wkh_content_length (proto_tree *tree, tvbuff_t *tvb,
1424 guint32 hdr_start, packet_info *pinfo _U_);
1425 static guint32 wkh_max_forwards (proto_tree *tree, tvbuff_t *tvb,
1426 guint32 hdr_start, packet_info *pinfo _U_);
1428 /* Integer lookup value */
1429 static guint32 wkh_bearer_indication (proto_tree *tree, tvbuff_t *tvb,
1430 guint32 hdr_start, packet_info *pinfo _U_);
1432 /* WAP application ID value */
1433 static guint32 wkh_x_wap_application_id (proto_tree *tree, tvbuff_t *tvb,
1434 guint32 hdr_start, packet_info *pinfo _U_);
1435 static guint32 wkh_accept_application (proto_tree *tree, tvbuff_t *tvb,
1436 guint32 hdr_start, packet_info *pinfo _U_);
1437 static guint32 wkh_content_language (proto_tree *tree, tvbuff_t *tvb,
1438 guint32 hdr_start, packet_info *pinfo _U_);
1440 /* Allow and Public */
1441 static guint32 wkh_allow(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1442 static guint32 wkh_public(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1445 static guint32 wkh_cache_control (proto_tree *tree, tvbuff_t *tvb,
1446 guint32 hdr_start, packet_info *pinfo _U_);
1448 static guint32 wkh_warning (proto_tree *tree, tvbuff_t *tvb,
1449 guint32 hdr_start, packet_info *pinfo _U_);
1450 /* Profile-warning */
1451 static guint32 wkh_profile_warning (proto_tree *tree, tvbuff_t *tvb,
1452 guint32 hdr_start, packet_info *pinfo _U_);
1455 static guint32 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb,
1456 guint32 hdr_start, packet_info *pinfo _U_);
1458 /* WSP encoding version */
1459 static guint32 wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb,
1460 guint32 hdr_start, packet_info *pinfo _U_);
1462 /* Content-Range and Range */
1463 static guint32 wkh_content_range (proto_tree *tree, tvbuff_t *tvb,
1464 guint32 hdr_start, packet_info *pinfo _U_);
1465 static guint32 wkh_range (proto_tree *tree, tvbuff_t *tvb,
1466 guint32 hdr_start, packet_info *pinfo _U_);
1469 static guint32 wkh_te (proto_tree *tree, tvbuff_t *tvb,
1470 guint32 hdr_start, packet_info *pinfo _U_);
1473 static guint32 wkh_trailer (proto_tree *tree, tvbuff_t *tvb,
1474 guint32 hdr_start, packet_info *pinfo _U_);
1476 /* Profile-Diff with WBXML UAPROF document */
1477 static guint32 wkh_profile_diff_wbxml (proto_tree *tree, tvbuff_t *tvb,
1478 guint32 hdr_start, packet_info *pinfo);
1480 /* TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
1481 static guint32 wkh_retry_after (proto_tree *tree, tvbuff_t *tvb,
1482 guint32 hdr_start, packet_info *pinfo _U_);
1483 static guint32 wkh_expect (proto_tree *tree, tvbuff_t *tvb,
1484 guint32 hdr_start, packet_info *pinfo _U_);
1485 static guint32 wkh_set_cookie (proto_tree *tree, tvbuff_t *tvb,
1486 guint32 hdr_start, packet_info *pinfo _U_);
1487 static guint32 wkh_cookie (proto_tree *tree, tvbuff_t *tvb,
1488 guint32 hdr_start, packet_info *pinfo _U_);
1492 /* WSP well-known Openwave header parsing function prototypes;
1493 * will be listed in the function lookup table WellKnownOpenwaveHeaders[] */
1494 static guint32 wkh_openwave_default (proto_tree *tree, tvbuff_t *tvb,
1495 guint32 hdr_start, packet_info *pinfo _U_);
1496 /* Textual headers */
1497 static guint32 wkh_openwave_x_up_proxy_operator_domain(proto_tree *tree,
1498 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1499 static guint32 wkh_openwave_x_up_proxy_home_page(proto_tree *tree,
1500 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1501 static guint32 wkh_openwave_x_up_proxy_uplink_version(proto_tree *tree,
1502 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1503 static guint32 wkh_openwave_x_up_proxy_ba_realm(proto_tree *tree,
1504 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1505 static guint32 wkh_openwave_x_up_proxy_request_uri(proto_tree *tree,
1506 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1507 static guint32 wkh_openwave_x_up_proxy_bookmark(proto_tree *tree,
1508 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1509 /* Integer headers */
1510 static guint32 wkh_openwave_x_up_proxy_push_seq(proto_tree *tree,
1511 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1512 static guint32 wkh_openwave_x_up_proxy_notify(proto_tree *tree,
1513 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1514 static guint32 wkh_openwave_x_up_proxy_net_ask(proto_tree *tree,
1515 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1516 static guint32 wkh_openwave_x_up_proxy_tod (proto_tree *tree,
1517 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1518 static guint32 wkh_openwave_x_up_proxy_ba_enable(proto_tree *tree,
1519 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1520 static guint32 wkh_openwave_x_up_proxy_redirect_enable(proto_tree *tree,
1521 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1522 static guint32 wkh_openwave_x_up_proxy_redirect_status(proto_tree *tree,
1523 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1524 static guint32 wkh_openwave_x_up_proxy_linger(proto_tree *tree,
1525 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1526 static guint32 wkh_openwave_x_up_proxy_enable_trust(proto_tree *tree,
1527 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1528 static guint32 wkh_openwave_x_up_proxy_trust(proto_tree *tree,
1529 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1530 static guint32 wkh_openwave_x_up_devcap_has_color(proto_tree *tree,
1531 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1532 static guint32 wkh_openwave_x_up_devcap_num_softkeys(proto_tree *tree,
1533 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1534 static guint32 wkh_openwave_x_up_devcap_softkey_size(proto_tree *tree,
1535 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1536 static guint32 wkh_openwave_x_up_devcap_screen_chars(proto_tree *tree,
1537 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1538 static guint32 wkh_openwave_x_up_devcap_screen_pixels(proto_tree *tree,
1539 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1540 static guint32 wkh_openwave_x_up_devcap_em_size(proto_tree *tree,
1541 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1542 static guint32 wkh_openwave_x_up_devcap_screen_depth(proto_tree *tree,
1543 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1544 static guint32 wkh_openwave_x_up_devcap_immed_alert(proto_tree *tree,
1545 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1546 static guint32 wkh_openwave_x_up_devcap_gui(proto_tree *tree,
1547 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1549 static guint32 wkh_openwave_x_up_proxy_trans_charset(proto_tree *tree,
1550 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1551 static guint32 wkh_openwave_x_up_proxy_push_accept(proto_tree *tree,
1552 tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_);
1555 /* Define a pointer to function data type for the well-known header
1556 * lookup table below */
1557 typedef guint32 (*hdr_parse_func_ptr) (proto_tree *, tvbuff_t *, guint32, packet_info *);
1559 /* Lookup table for well-known header parsing functions */
1560 static const hdr_parse_func_ptr WellKnownHeader[128] = {
1561 /* 0x00 */ wkh_accept, /* 0x01 */ wkh_accept_charset,
1562 /* 0x02 */ wkh_accept_encoding, /* 0x03 */ wkh_accept_language,
1563 /* 0x04 */ wkh_accept_ranges, /* 0x05 */ wkh_age,
1564 /* 0x06 */ wkh_allow, /* 0x07 */ wkh_authorization,
1565 /* 0x08 */ wkh_cache_control, /* 0x09 */ wkh_connection,
1566 /* 0x0A */ wkh_content_base, /* 0x0B */ wkh_content_encoding,
1567 /* 0x0C */ wkh_content_language, /* 0x0D */ wkh_content_length,
1568 /* 0x0E */ wkh_content_location, /* 0x0F */ wkh_content_md5,
1569 /* 0x10 */ wkh_content_range, /* 0x11 */ wkh_content_type,
1570 /* 0x12 */ wkh_date, /* 0x13 */ wkh_etag,
1571 /* 0x14 */ wkh_expires, /* 0x15 */ wkh_from,
1572 /* 0x16 */ wkh_host, /* 0x17 */ wkh_if_modified_since,
1573 /* 0x18 */ wkh_if_match, /* 0x19 */ wkh_if_none_match,
1574 /* 0x1A */ wkh_if_range, /* 0x1B */ wkh_if_unmodified_since,
1575 /* 0x1C */ wkh_location, /* 0x1D */ wkh_last_modified,
1576 /* 0x1E */ wkh_max_forwards, /* 0x1F */ wkh_pragma,
1577 /* 0x20 */ wkh_proxy_authenticate, /* 0x21 */ wkh_proxy_authorization,
1578 /* 0x22 */ wkh_public, /* 0x23 */ wkh_range,
1579 /* 0x24 */ wkh_referer, /* 0x25 */ wkh_default,
1580 /* 0x26 */ wkh_server, /* 0x27 */ wkh_transfer_encoding,
1581 /* 0x28 */ wkh_upgrade, /* 0x29 */ wkh_user_agent,
1582 /* 0x2A */ wkh_vary, /* 0x2B */ wkh_via,
1583 /* 0x2C */ wkh_warning, /* 0x2D */ wkh_www_authenticate,
1584 /* 0x2E */ wkh_content_disposition,/* 0x2F */ wkh_x_wap_application_id,
1585 /* 0x30 */ wkh_content_uri, /* 0x31 */ wkh_initiator_uri,
1586 /* 0x32 */ wkh_accept_application, /* 0x33 */ wkh_bearer_indication,
1587 /* 0x34 */ wkh_push_flag, /* 0x35 */ wkh_profile,
1588 /* 0x36 */ wkh_profile_diff_wbxml, /* 0x37 */ wkh_profile_warning,
1589 /* 0x38 */ wkh_default, /* 0x39 */ wkh_te,
1590 /* 0x3A */ wkh_trailer, /* 0x3B */ wkh_accept_charset,
1591 /* 0x3C */ wkh_accept_encoding, /* 0x3D */ wkh_cache_control,
1592 /* 0x3E */ wkh_content_range, /* 0x3F */ wkh_x_wap_tod,
1593 /* 0x40 */ wkh_content_id, /* 0x41 */ wkh_default,
1594 /* 0x42 */ wkh_default, /* 0x43 */ wkh_encoding_version,
1595 /* 0x44 */ wkh_profile_warning, /* 0x45 */ wkh_content_disposition,
1596 /* 0x46 */ wkh_x_wap_security, /* 0x47 */ wkh_cache_control,
1597 /*******************************************************
1598 *** The following headers are not (yet) registered. ***
1599 *******************************************************/
1600 /* 0x48 */ wkh_default, /* 0x49 */ wkh_default,
1601 /* 0x4A */ wkh_default, /* 0x4B */ wkh_default,
1602 /* 0x4C */ wkh_default, /* 0x4D */ wkh_default,
1603 /* 0x4E */ wkh_default, /* 0x4F */ wkh_default,
1604 /* 0x50 */ wkh_default, /* 0x51 */ wkh_default,
1605 /* 0x52 */ wkh_default, /* 0x53 */ wkh_default,
1606 /* 0x54 */ wkh_default, /* 0x55 */ wkh_default,
1607 /* 0x56 */ wkh_default, /* 0x57 */ wkh_default,
1608 /* 0x58 */ wkh_default, /* 0x59 */ wkh_default,
1609 /* 0x5A */ wkh_default, /* 0x5B */ wkh_default,
1610 /* 0x5C */ wkh_default, /* 0x5D */ wkh_default,
1611 /* 0x5E */ wkh_default, /* 0x5F */ wkh_default,
1612 /* 0x60 */ wkh_default, /* 0x61 */ wkh_default,
1613 /* 0x62 */ wkh_default, /* 0x63 */ wkh_default,
1614 /* 0x64 */ wkh_default, /* 0x65 */ wkh_default,
1615 /* 0x66 */ wkh_default, /* 0x67 */ wkh_default,
1616 /* 0x68 */ wkh_default, /* 0x69 */ wkh_default,
1617 /* 0x6A */ wkh_default, /* 0x6B */ wkh_default,
1618 /* 0x6C */ wkh_default, /* 0x6D */ wkh_default,
1619 /* 0x6E */ wkh_default, /* 0x6F */ wkh_default,
1620 /* 0x70 */ wkh_default, /* 0x71 */ wkh_default,
1621 /* 0x72 */ wkh_default, /* 0x73 */ wkh_default,
1622 /* 0x74 */ wkh_default, /* 0x75 */ wkh_default,
1623 /* 0x76 */ wkh_default, /* 0x77 */ wkh_default,
1624 /* 0x78 */ wkh_default, /* 0x79 */ wkh_default,
1625 /* 0x7A */ wkh_default, /* 0x7B */ wkh_default,
1626 /* 0x7C */ wkh_default, /* 0x7D */ wkh_default,
1627 /* 0x7E */ wkh_default, /* 0x7F */ wkh_default,
1630 /* Lookup table for well-known header parsing functions */
1631 static const hdr_parse_func_ptr WellKnownOpenwaveHeader[128] = {
1632 /* 0x00 */ wkh_openwave_default,
1633 /* 0x01 */ wkh_openwave_x_up_proxy_push_accept,
1634 /* 0x02 */ wkh_openwave_x_up_proxy_push_seq,
1635 /* 0x03 */ wkh_openwave_x_up_proxy_notify,
1636 /* 0x04 */ wkh_openwave_x_up_proxy_operator_domain,
1637 /* 0x05 */ wkh_openwave_x_up_proxy_home_page,
1638 /* 0x06 */ wkh_openwave_x_up_devcap_has_color,
1639 /* 0x07 */ wkh_openwave_x_up_devcap_num_softkeys,
1640 /* 0x08 */ wkh_openwave_x_up_devcap_softkey_size,
1641 /* 0x09 */ wkh_openwave_x_up_devcap_screen_chars,
1642 /* 0x0A */ wkh_openwave_x_up_devcap_screen_pixels,
1643 /* 0x0B */ wkh_openwave_x_up_devcap_em_size,
1644 /* 0x0C */ wkh_openwave_x_up_devcap_screen_depth,
1645 /* 0x0D */ wkh_openwave_x_up_devcap_immed_alert,
1646 /* 0x0E */ wkh_openwave_x_up_proxy_net_ask,
1647 /* 0x0F */ wkh_openwave_x_up_proxy_uplink_version,
1648 /* 0x10 */ wkh_openwave_x_up_proxy_tod,
1649 /* 0x11 */ wkh_openwave_x_up_proxy_ba_enable,
1650 /* 0x12 */ wkh_openwave_x_up_proxy_ba_realm,
1651 /* 0x13 */ wkh_openwave_x_up_proxy_redirect_enable,
1652 /* 0x14 */ wkh_openwave_x_up_proxy_request_uri,
1653 /* 0x15 */ wkh_openwave_x_up_proxy_redirect_status,
1654 /* 0x16 */ wkh_openwave_x_up_proxy_trans_charset,
1655 /* 0x17 */ wkh_openwave_x_up_proxy_linger,
1656 /* 0x18 */ wkh_openwave_default,
1657 /* 0x19 */ wkh_openwave_x_up_proxy_enable_trust,
1658 /* 0x1A */ wkh_openwave_x_up_proxy_trust,
1659 /* 0x1B */ wkh_openwave_default,
1660 /* 0x1C */ wkh_openwave_default,
1661 /* 0x1D */ wkh_openwave_default,
1662 /* 0x1E */ wkh_openwave_default,
1663 /* 0x1F */ wkh_openwave_default,
1664 /* 0x20 */ wkh_openwave_x_up_proxy_trust,
1665 /* 0x21 */ wkh_openwave_x_up_proxy_bookmark,
1666 /* 0x22 */ wkh_openwave_x_up_devcap_gui,
1667 /*******************************************************
1668 *** The following headers are not (yet) registered. ***
1669 *******************************************************/
1670 /* 0x23 */ wkh_openwave_default,
1671 /* 0x24 */ wkh_openwave_default, /* 0x25 */ wkh_openwave_default,
1672 /* 0x26 */ wkh_openwave_default, /* 0x27 */ wkh_openwave_default,
1673 /* 0x28 */ wkh_openwave_default, /* 0x29 */ wkh_openwave_default,
1674 /* 0x2A */ wkh_openwave_default, /* 0x2B */ wkh_openwave_default,
1675 /* 0x2C */ wkh_openwave_default, /* 0x2D */ wkh_openwave_default,
1676 /* 0x2E */ wkh_openwave_default, /* 0x2F */ wkh_openwave_default,
1677 /* 0x30 */ wkh_openwave_default, /* 0x31 */ wkh_openwave_default,
1678 /* 0x32 */ wkh_openwave_default, /* 0x33 */ wkh_openwave_default,
1679 /* 0x34 */ wkh_openwave_default, /* 0x35 */ wkh_openwave_default,
1680 /* 0x36 */ wkh_openwave_default, /* 0x37 */ wkh_openwave_default,
1681 /* 0x38 */ wkh_openwave_default, /* 0x39 */ wkh_openwave_default,
1682 /* 0x3A */ wkh_openwave_default, /* 0x3B */ wkh_openwave_default,
1683 /* 0x3C */ wkh_openwave_default, /* 0x3D */ wkh_openwave_default,
1684 /* 0x3E */ wkh_openwave_default, /* 0x3F */ wkh_openwave_default,
1685 /* 0x40 */ wkh_openwave_default, /* 0x41 */ wkh_openwave_default,
1686 /* 0x42 */ wkh_openwave_default, /* 0x43 */ wkh_openwave_default,
1687 /* 0x44 */ wkh_openwave_default, /* 0x45 */ wkh_openwave_default,
1688 /* 0x46 */ wkh_openwave_default, /* 0x47 */ wkh_openwave_default,
1689 /* 0x48 */ wkh_openwave_default, /* 0x49 */ wkh_openwave_default,
1690 /* 0x4A */ wkh_openwave_default, /* 0x4B */ wkh_openwave_default,
1691 /* 0x4C */ wkh_openwave_default, /* 0x4D */ wkh_openwave_default,
1692 /* 0x4E */ wkh_openwave_default, /* 0x4F */ wkh_openwave_default,
1693 /* 0x50 */ wkh_openwave_default, /* 0x51 */ wkh_openwave_default,
1694 /* 0x52 */ wkh_openwave_default, /* 0x53 */ wkh_openwave_default,
1695 /* 0x54 */ wkh_openwave_default, /* 0x55 */ wkh_openwave_default,
1696 /* 0x56 */ wkh_openwave_default, /* 0x57 */ wkh_openwave_default,
1697 /* 0x58 */ wkh_openwave_default, /* 0x59 */ wkh_openwave_default,
1698 /* 0x5A */ wkh_openwave_default, /* 0x5B */ wkh_openwave_default,
1699 /* 0x5C */ wkh_openwave_default, /* 0x5D */ wkh_openwave_default,
1700 /* 0x5E */ wkh_openwave_default, /* 0x5F */ wkh_openwave_default,
1701 /* 0x60 */ wkh_openwave_default, /* 0x61 */ wkh_openwave_default,
1702 /* 0x62 */ wkh_openwave_default, /* 0x63 */ wkh_openwave_default,
1703 /* 0x64 */ wkh_openwave_default, /* 0x65 */ wkh_openwave_default,
1704 /* 0x66 */ wkh_openwave_default, /* 0x67 */ wkh_openwave_default,
1705 /* 0x68 */ wkh_openwave_default, /* 0x69 */ wkh_openwave_default,
1706 /* 0x6A */ wkh_openwave_default, /* 0x6B */ wkh_openwave_default,
1707 /* 0x6C */ wkh_openwave_default, /* 0x6D */ wkh_openwave_default,
1708 /* 0x6E */ wkh_openwave_default, /* 0x6F */ wkh_openwave_default,
1709 /* 0x70 */ wkh_openwave_default, /* 0x71 */ wkh_openwave_default,
1710 /* 0x72 */ wkh_openwave_default, /* 0x73 */ wkh_openwave_default,
1711 /* 0x74 */ wkh_openwave_default, /* 0x75 */ wkh_openwave_default,
1712 /* 0x76 */ wkh_openwave_default, /* 0x77 */ wkh_openwave_default,
1713 /* 0x78 */ wkh_openwave_default, /* 0x79 */ wkh_openwave_default,
1714 /* 0x7A */ wkh_openwave_default, /* 0x7B */ wkh_openwave_default,
1715 /* 0x7C */ wkh_openwave_default, /* 0x7D */ wkh_openwave_default,
1716 /* 0x7E */ wkh_openwave_default, /* 0x7F */ wkh_openwave_default
1721 /* WSP header format
1722 * 1st byte: 0x00 : <Not allowed>
1723 * 1st byte: 0x01 -- 0x1F: <Shorthand Header Code Page switch>
1724 * 1st byte: 0x20 -- 0x7E: <Textual header (C string)>
1725 * Followed with: <Textual header value (C string)>
1726 * 1st byte: 0x7F : <Header Code Page switch>
1727 * Followed with: 2nd byte: <Header Code Page>
1728 * 1st byte: 0x80 -- 0xFF: <Binary header (7-bit encoded ID)>
1730 * 2nd byte: 0x00 -- 0x1E: <Value Length (bytes)>
1731 * Followed with: <Len> bytes of data
1732 * 2nd byte: 0x1F : <Value Length is a guintvar>
1733 * Followed with: <guintvar Len>
1734 * Followed with: <Len> bytes of data
1735 * 2nd byte: 0x20 -- 0x7F: <Textual header value (C string)>
1736 * 2nd byte: 0x80 -- 0xFF: <Binary value (7-bit encoded ID)>
1739 add_headers (proto_tree *tree, tvbuff_t *tvb, int hf, packet_info *pinfo)
1741 guint8 hdr_id, val_id, codepage = 1;
1742 gint32 tvb_len = tvb_length(tvb);
1743 gint32 offset = 0, hdr_len, hdr_start;
1744 gint32 val_len, val_start;
1745 gchar *hdr_str, *val_str;
1746 proto_tree *wsp_headers;
1747 proto_item *ti, *hidden_item;
1753 if (offset >= tvb_len)
1754 return; /* No headers! */
1756 /* XXX: the field pointed to by hf has a type of FT_NONE */
1757 ti = proto_tree_add_item(tree, hf,
1758 tvb, offset, tvb_len, ENC_NA);
1759 wsp_headers = proto_item_add_subtree(ti, ett_headers);
1761 while (offset < tvb_len) {
1763 hdr_id = tvb_get_guint8(tvb, offset);
1764 if (hdr_id & 0x80) { /* Well-known header */
1766 val_start = ++offset;
1767 val_id = tvb_get_guint8(tvb, val_start);
1768 /* Call header value dissector for given header */
1769 if (codepage == 1) { /* Default header code page */
1770 DebugLog(("add_headers(code page 0): %s\n",
1771 val_to_str_ext_const (hdr_id & 0x7f, &vals_field_names_ext, "Undefined")));
1772 offset = WellKnownHeader[hdr_id & 0x7F](wsp_headers, tvb,
1774 } else { /* Openwave header code page */
1775 /* Here I'm delibarately assuming that Openwave is the only
1776 * company that defines a WSP header code page. */
1777 DebugLog(("add_headers(code page 0x%02x - assumed to be x-up-1): %s\n",
1778 codepage, val_to_str_ext_const (hdr_id & 0x7f, &vals_openwave_field_names_ext, "Undefined")));
1779 offset = WellKnownOpenwaveHeader[hdr_id & 0x7F](wsp_headers,
1780 tvb, hdr_start, pinfo);
1782 } else if (hdr_id == 0x7F) { /* HCP shift sequence */
1783 codepage = tvb_get_guint8(tvb, offset+1);
1784 proto_tree_add_uint(wsp_headers, hf_wsp_header_shift_code,
1785 tvb, offset, 2, codepage);
1787 } else if (hdr_id >= 0x20) { /* Textual header */
1788 /* Header name MUST be NUL-ended string ==> tvb_get_stringz() */
1789 hdr_str = (gchar *)tvb_get_ephemeral_stringz(tvb, hdr_start, (gint *)&hdr_len);
1790 val_start = hdr_start + hdr_len;
1791 val_id = tvb_get_guint8(tvb, val_start);
1792 /* Call header value dissector for given header */
1793 if (val_id >= 0x20 && val_id <=0x7E) { /* OK! */
1794 val_str = (gchar *)tvb_get_ephemeral_stringz(tvb, val_start, (gint *)&val_len);
1795 offset = val_start + val_len;
1796 tvb_ensure_bytes_exist(tvb, hdr_start, offset-hdr_start);
1797 proto_tree_add_text(wsp_headers,tvb,hdr_start,offset-hdr_start,
1798 "%s: %s", hdr_str, val_str);
1800 /* Old-style X-WAP-TOD uses a non-textual value
1801 * after a textual header. */
1802 if (g_ascii_strcasecmp(hdr_str, "x-wap.tod") == 0) {
1803 get_delta_seconds_value(val, tvb, val_start, val_len, ok);
1806 ti = proto_tree_add_string (wsp_headers,
1808 tvb, hdr_start, hdr_len + val_len,
1809 "Requesting Time Of Day");
1811 val_str = abs_time_secs_to_str(val, ABSOLUTE_TIME_LOCAL, TRUE);
1812 ti = proto_tree_add_string (wsp_headers,
1814 tvb, hdr_start, hdr_len + val_len, val_str);
1816 proto_item_append_text(ti, " <Warning: "
1817 "should be encoded as a textual value>");
1819 /* I prefer using X-Wap-Tod to the real hdr_str */
1820 proto_tree_add_string (wsp_headers, hf_hdr_x_wap_tod,
1821 tvb, hdr_start, hdr_len + val_len,
1822 InvalidValueForHeader("X-Wap-Tod"));
1825 proto_tree_add_text (wsp_headers, tvb, hdr_start, hdr_len,
1826 "<Error: Invalid value for the textual '%s' header"
1827 " (should be a textual value)>",
1832 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
1833 hidden_item = proto_tree_add_string(wsp_headers, hf_hdr_name,
1834 tvb, hdr_start, offset - hdr_start, hdr_str);
1835 PROTO_ITEM_SET_HIDDEN(hidden_item);
1836 } else if (hdr_id > 0) { /* Shorthand HCP switch */
1838 proto_tree_add_uint (wsp_headers, hf_wsp_header_shift_code,
1839 tvb, offset, 1, codepage);
1842 proto_tree_add_text (wsp_headers, tvb, hdr_start, 1,
1843 InvalidTextualHeader);
1850 /* The following macros hide common processing for all well-known headers
1851 * and shortens the code to be written in a wkh_XXX() function.
1852 * Even declarations are hidden by a macro.
1854 * Define a wkh_XXX() function as follows:
1857 * wkh_XXX (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
1859 * wkh_0_Declarations;
1860 * << add other required declarations here >>
1862 * wkh_1_WellKnownValue;
1863 * << add well-known value proto item here; don't forget to set the
1864 * ok variable to TRUE if parsing was correct >>
1865 * wkh_2_TextualValue;
1866 * << add textual value proto item here; don't forget to set the
1867 * ok variable to TRUE if parsing was correct >>
1868 * wkh_3_ValueWithLength;
1869 * << add custom code for value processing and value proto item here >>
1872 * << This macro takes care of parse errors within the header value;
1873 * it requires the header field index if the header has not yet been
1874 * written to the protocol tree (ti == NULL). >>
1877 * NOTE: You only need to write parsing code for the successful case,
1878 * Errors are automatically reported through the wkh_4_End() macro
1882 /* The following code is the generic template with which the value of a
1883 * well-known header can be processed. Not all sections yield a semantically
1884 * correct result, so appropriate error information must be provided.
1888 #define wkh_0a_Declarations /* Declarations for Parsing */ \
1889 gboolean ok = FALSE; /* Triggers error notification code at end */ \
1890 proto_item *ti = NULL; /* Needed for error notification at end */ \
1891 proto_item *hidden_item = NULL; \
1892 guint32 val_start = hdr_start + 1; \
1893 guint8 hdr_id = tvb_get_guint8 (tvb, hdr_start) & 0x7F; \
1894 guint8 val_id = tvb_get_guint8 (tvb, val_start); \
1895 guint32 offset = val_start; /* Offset to one past this header */ \
1896 guint32 val_len; /* length for value with length field */ \
1897 guint32 val_len_len /* length of length field */
1899 #define wkh_0_Declarations \
1900 wkh_0a_Declarations; \
1901 const gchar *val_str = NULL
1903 #define wkh_1_WellKnownValue /* Parse Well Known Value */ \
1904 hidden_item = proto_tree_add_string(tree, hf_hdr_name, \
1905 tvb, hdr_start, offset - hdr_start, \
1906 val_to_str_ext (hdr_id, &vals_field_names_ext, \
1907 "<Unknown WSP header field 0x%02X>")); \
1908 PROTO_ITEM_SET_HIDDEN(hidden_item); \
1909 if (val_id & 0x80) { /* Well-known value */ \
1911 /* Well-known value processing starts HERE \
1915 #define wkh_2_TextualValue /* Parse Textual Value */ \
1917 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \
1918 val_str = (gchar *)tvb_get_ephemeral_stringz (tvb, val_start, (gint *)&val_len); \
1919 offset = val_start + val_len; \
1920 /* Textual value processing starts HERE \
1924 #define wkh_2_TextualValueInv /* Parse Textual Value */ \
1926 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \
1927 /*val_str = (gchar *)*/tvb_get_ephemeral_stringz (tvb, val_start, (gint *)&val_len); \
1928 offset = val_start + val_len; \
1929 /* Textual value processing starts HERE \
1933 #define wkh_3_ValueWithLength /* Parse Value With Length */ \
1935 } else { /* val_start points to 1st byte of length field */ \
1936 if (val_id == 0x1F) { /* Value Length = guintvar */ \
1937 val_len = tvb_get_guintvar(tvb, val_start + 1, &val_len_len); \
1938 val_len_len++; /* 0x1F length indicator byte */ \
1939 } else { /* Short length followed by Len data octets */ \
1940 val_len = tvb_get_guint8(tvb, offset); \
1943 offset += val_len_len + val_len; \
1944 /* Value with length processing starts HERE \
1945 * The value lies between val_start and offset: \
1946 * - Value Length: Start = val_start \
1947 * Length = val_len_len \
1948 * - Value Data : Start = val_start + val_len_len \
1949 * Length = val_len \
1950 * End = offset - 1 \
1953 #define wkh_4_End(hf) /* End of value parsing */ \
1956 /* Check for errors */ \
1958 if (ti) { /* Append to protocol tree item label */ \
1959 proto_item_append_text(ti, \
1960 " <Error: Invalid header value>"); \
1961 } else if (hf > 0) { /* Create protocol tree item */ \
1962 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
1963 proto_tree_add_string(tree, hf, \
1964 tvb, hdr_start, offset - hdr_start, \
1965 " <Error: Invalid header value>"); \
1966 } else { /* Create anonymous header field entry */ \
1967 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
1968 proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start, \
1969 "%s: <Error: Invalid header value>", \
1970 val_to_str_ext (hdr_id, &vals_field_names_ext, \
1971 "<Unknown WSP header field 0x%02X>")); \
1978 * This yields the following default header value parser function body
1981 wkh_default(proto_tree *tree, tvbuff_t *tvb,
1982 guint32 hdr_start, packet_info *pinfo _U_)
1986 ok = TRUE; /* Bypass error checking as we don't parse the values! */
1988 wkh_1_WellKnownValue;
1989 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
1990 ti = proto_tree_add_text (tree, tvb, hdr_start, offset - hdr_start,
1991 "%s: (Undecoded well-known value 0x%02x)",
1992 val_to_str_ext (hdr_id, &vals_field_names_ext,
1993 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F);
1995 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
1996 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
1998 val_to_str_ext (hdr_id, &vals_field_names_ext,
1999 "<Unknown WSP header field 0x%02X>"), val_str);
2000 wkh_3_ValueWithLength;
2001 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2002 ti = proto_tree_add_text (tree, tvb, hdr_start, offset - hdr_start,
2003 "%s: (Undecoded value in general form with length indicator)",
2004 val_to_str_ext (hdr_id, &vals_field_names_ext,
2005 "<Unknown WSP header field 0x%02X>"));
2007 wkh_4_End(HF_EMPTY); /* The default parser has no associated hf_index;
2008 additionally the error code is always bypassed */
2012 /* Content-type processing uses the following common core: */
2013 #define wkh_content_type_header(underscored,Text) \
2015 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2017 wkh_0_Declarations; \
2018 guint32 off, val = 0, len; \
2020 proto_tree *parameter_tree = NULL; \
2022 wkh_1_WellKnownValue; \
2023 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2024 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2025 tvb, hdr_start, offset - hdr_start, \
2026 val_to_str_ext(val_id & 0x7F, &vals_content_types_ext, \
2027 "(Unknown content type identifier 0x%X)")); \
2029 wkh_2_TextualValue; \
2030 /* Sometimes with a No-Content response, a NULL content type \
2031 * is reported. Process this correctly! */ \
2033 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2034 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2035 tvb, hdr_start, offset - hdr_start, \
2038 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2039 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2040 tvb, hdr_start, offset - hdr_start, \
2041 "<no content type has been specified>"); \
2044 wkh_3_ValueWithLength; \
2045 off = val_start + val_len_len; \
2046 peek = tvb_get_guint8(tvb, off); \
2047 if (is_text_string(peek)) { \
2048 get_extension_media(val_str, tvb, off, len, ok); \
2050 off += len; /* off now points to 1st byte after string */ \
2051 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2052 ti = proto_tree_add_string (tree, hf_hdr_ ## underscored, \
2053 tvb, hdr_start, offset - hdr_start, val_str); \
2055 } else if (is_integer_value(peek)) { \
2056 get_integer_value(val, tvb, off, len, ok); \
2058 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2059 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2060 tvb, hdr_start, offset - hdr_start, \
2061 val_to_str_ext(val, &vals_content_types_ext, \
2062 "(Unknown content type identifier 0x%X)")); \
2066 /* Remember: offset == val_start + val_len + val_len_len */ \
2067 if (ok && (off < offset)) { /* Add parameters if any */ \
2068 parameter_tree = proto_item_add_subtree (ti, ett_header); \
2069 while (off < offset) { \
2070 off = parameter (parameter_tree, ti, tvb, off, offset - off); \
2074 wkh_4_End(hf_hdr_ ## underscored); \
2082 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2084 wkh_content_type_header(accept, "Accept")
2088 * Content-type-value =
2091 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2093 * Beware: this header should not appear as such; it is dissected elsewhere
2094 * and at the same time the content type is used for subdissectors.
2095 * It is here for the sake of completeness.
2097 wkh_content_type_header(content_type, "Content-Type")
2101 * Content-type-value =
2104 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
2106 * This function adds the content type value to the protocol tree,
2107 * and computes either the numeric or textual media type in return,
2108 * which will be used for further subdissection (e.g., MMS, WBXML).
2111 add_content_type(proto_tree *tree, tvbuff_t *tvb, guint32 val_start,
2112 guint32 *well_known_content, const char **textual_content)
2114 /* Replace wkh_0_Declarations with slightly modified declarations
2115 * so we can still make use of the wkh_[1-4]_XXX macros! */
2116 guint32 hdr_start = val_start; /* No header name, only value! */
2117 guint8 hdr_id = FN_CONTENT_TYPE; /* Same remark */
2118 guint8 val_id = tvb_get_guint8 (tvb, val_start);
2119 guint32 offset = val_start; /* Offset to one past this header */
2120 guint32 val_len; /* length for value with length field */
2121 guint32 val_len_len; /* length of length field */
2122 gchar *val_str = NULL;
2123 guint32 off, val = 0, len;
2125 gboolean ok = FALSE;
2126 proto_item *ti = NULL;
2127 proto_item *hidden_item = NULL;
2128 proto_tree *parameter_tree = NULL;
2130 *textual_content = NULL;
2131 *well_known_content = 0;
2133 DebugLog(("add_content_type() - START\n"));
2135 wkh_1_WellKnownValue;
2136 DebugLog(("add_content_type() - Well-known - Start\n"));
2137 *textual_content = val_to_str_ext(val_id & 0x7F, &vals_content_types_ext,
2138 "<Unknown media type identifier 0x%X>");
2139 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2140 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2141 tvb, hdr_start, offset - hdr_start,
2143 *well_known_content = val_id & 0x7F;
2145 DebugLog(("add_content_type() - Well-known - End\n"));
2147 DebugLog(("add_content_type() - Textual - Start\n"));
2148 /* Sometimes with a No-Content response, a NULL content type
2149 * is reported. Process this correctly! */
2151 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2152 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2153 tvb, hdr_start, offset - hdr_start,
2155 *textual_content = g_strdup(val_str);
2156 *well_known_content = 0;
2158 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2159 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2160 tvb, hdr_start, offset - hdr_start,
2161 "<no media type has been specified>");
2162 *textual_content = NULL;
2163 *well_known_content = 0;
2166 DebugLog(("add_content_type() - Textual - End\n"));
2167 wkh_3_ValueWithLength;
2168 DebugLog(("add_content_type() - General form - Start\n"));
2169 off = val_start + val_len_len;
2170 peek = tvb_get_guint8(tvb, off);
2171 if (is_text_string(peek)) {
2172 DebugLog(("add_content_type() - General form - extension-media\n"));
2173 get_extension_media(val_str, tvb, off, len, ok);
2175 off += len; /* off now points to 1st byte after string */
2176 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2177 ti = proto_tree_add_string (tree, hf_hdr_content_type,
2178 tvb, hdr_start, offset - hdr_start, val_str);
2180 /* Following statement: required? */
2181 *textual_content = g_strdup(val_str);
2182 *well_known_content = 0;
2183 } else if (is_integer_value(peek)) {
2184 DebugLog(("add_content_type() - General form - integer_value\n"));
2185 get_integer_value(val, tvb, off, len, ok);
2187 *textual_content = val_to_str_ext(val, &vals_content_types_ext,
2188 "<Unknown media type identifier 0x%X>");
2189 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2190 ti = proto_tree_add_string(tree, hf_hdr_content_type,
2191 tvb, hdr_start, offset - hdr_start,
2193 *well_known_content = val;
2196 } /* else ok = FALSE */
2197 /* Remember: offset == val_start + val_len_len + val_len */
2198 if (ok && (off < offset)) { /* Add parameters if any */
2199 DebugLog(("add_content_type() - General form - parameters\n"));
2200 parameter_tree = proto_item_add_subtree (ti, ett_header);
2201 while (off < offset) {
2202 DebugLog(("add_content_type() - General form - parameter start "
2203 "(off = %u)\n", off));
2204 off = parameter (parameter_tree, ti, tvb, off, offset - off);
2205 DebugLog(("add_content_type() - General form - parameter end "
2206 "(off = %u)\n", off));
2209 DebugLog(("add_content_type() - General form - End\n"));
2211 wkh_4_End(hf_hdr_content_type);
2216 * Template for accept_X headers with optional Q parameter value
2218 #define wkh_accept_x_q_header(underscored,Text,valueStringExtAddr,valueName) \
2220 wkh_ ## underscored (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2222 wkh_0_Declarations; \
2223 guint32 off, val = 0, len; \
2225 proto_tree *parameter_tree = NULL; \
2227 wkh_1_WellKnownValue; \
2228 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2229 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2230 tvb, hdr_start, offset - hdr_start, \
2231 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, \
2232 "<Unknown " valueName " identifier 0x%X>")); \
2234 wkh_2_TextualValue; \
2235 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2236 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2237 tvb, hdr_start, offset - hdr_start, val_str); \
2239 wkh_3_ValueWithLength; \
2240 off = val_start + val_len_len; \
2241 peek = tvb_get_guint8(tvb, off); \
2242 if (is_text_string(peek)) { \
2243 get_token_text(val_str, tvb, off, len, ok); \
2245 off += len; /* off now points to 1st byte after string */ \
2246 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2247 ti = proto_tree_add_string (tree, hf_hdr_ ## underscored, \
2248 tvb, hdr_start, offset - hdr_start, val_str); \
2250 } else if (is_integer_value(peek)) { \
2251 get_integer_value(val, tvb, off, len, ok); \
2253 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2254 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2255 tvb, hdr_start, offset - hdr_start, \
2256 val_to_str_ext(val, valueStringExtAddr, \
2257 "<Unknown " valueName " identifier 0x%X>")); \
2260 } /* else ok = FALSE */ \
2261 /* Remember: offset == val_start + val_len */ \
2262 if (ok && (off < offset)) { /* Add Q-value if available */ \
2263 parameter_tree = proto_item_add_subtree (ti, ett_header); \
2264 off = parameter_value_q (parameter_tree, ti, tvb, off); \
2267 wkh_4_End(hf_hdr_ ## underscored); \
2271 * Accept-charset-value =
2274 * | ( Value-length ( Token-text | Integer-value ) [ Q-value ] )
2276 wkh_accept_x_q_header(accept_charset, "Accept-Charset",
2277 &vals_character_sets_ext, "character set")
2279 * Accept-language-value =
2282 * | ( Value-length ( Text-string | Integer-value ) [ Q-value ] )
2284 wkh_accept_x_q_header(accept_language, "Accept-Language",
2285 &vals_languages_ext, "language")
2289 * Push-flag-value = Short-integer
2292 wkh_push_flag(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2294 wkh_0a_Declarations;
2295 proto_tree *subtree = NULL;
2297 wkh_1_WellKnownValue;
2298 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2299 ti = proto_tree_add_string(tree, hf_hdr_push_flag,
2300 tvb, hdr_start, offset - hdr_start, "");
2301 subtree = proto_item_add_subtree(ti, ett_header);
2302 proto_tree_add_uint(subtree, hf_hdr_push_flag_auth,
2303 tvb, val_start, 1, val_id);
2304 proto_tree_add_uint(subtree, hf_hdr_push_flag_trust,
2305 tvb, val_start, 1, val_id);
2306 proto_tree_add_uint(subtree, hf_hdr_push_flag_last,
2307 tvb, val_start, 1, val_id);
2309 proto_item_append_string(ti, " (Initiator URI authenticated)");
2311 proto_item_append_string(ti, " (Content trusted)");
2313 proto_item_append_string(ti, " (Last push message)");
2315 proto_item_append_text(ti, " <Warning: Reserved flags set>");
2318 wkh_2_TextualValueInv;
2320 wkh_3_ValueWithLength;
2322 wkh_4_End(hf_hdr_push_flag);
2327 * Profile-Diff (with WBXML): Profile-diff-value =
2328 * Value-length <WBXML-Content>
2330 static guint32 wkh_profile_diff_wbxml (proto_tree *tree, tvbuff_t *tvb,
2331 guint32 hdr_start, packet_info *pinfo)
2333 wkh_0a_Declarations;
2335 proto_tree *subtree;
2337 ok = TRUE; /* Bypass error checking as we don't parse the values! */
2339 wkh_1_WellKnownValue;
2341 wkh_2_TextualValueInv;
2343 wkh_3_ValueWithLength;
2344 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2345 ti = proto_tree_add_string(tree, hf_hdr_profile_diff, tvb, hdr_start, offset - hdr_start,
2346 "(Profile-Diff value as WBXML)");
2347 subtree = proto_item_add_subtree(ti, ett_header);
2348 tmp_tvb = tvb_new_subset(tvb, val_start + val_len_len, val_len, val_len); /* TODO: fix 2nd length */
2349 call_dissector(wbxml_uaprof_handle, tmp_tvb, pinfo, subtree);
2351 wkh_4_End(hf_hdr_profile_diff);
2360 wkh_allow(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *apinfo _U_)
2362 wkh_0a_Declarations;
2364 wkh_1_WellKnownValue;
2366 if (val_id >= 0x40) { /* Valid WSP method */
2367 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2368 ti = proto_tree_add_string(tree, hf_hdr_allow,
2369 tvb, hdr_start, offset - hdr_start,
2370 val_to_str_ext(val_id & 0x7F, &wsp_vals_pdu_type_ext,
2371 "<Unknown WSP method 0x%02X>"));
2374 wkh_2_TextualValueInv;
2376 wkh_3_ValueWithLength;
2378 wkh_4_End(hf_hdr_allow);
2384 * Token-text | Short-integer
2387 wkh_public(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *apinfo _U_)
2391 wkh_1_WellKnownValue;
2393 if (val_id >= 0x40) { /* Valid WSP method */
2394 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2395 ti = proto_tree_add_string(tree, hf_hdr_public,
2396 tvb, hdr_start, offset - hdr_start,
2397 val_to_str_ext(val_id & 0x7F, &wsp_vals_pdu_type_ext,
2398 "<Unknown WSP method 0x%02X>"));
2402 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2403 ti = proto_tree_add_string(tree, hf_hdr_public,
2404 tvb, hdr_start, offset - hdr_start, val_str);
2406 wkh_3_ValueWithLength;
2408 wkh_4_End(hf_hdr_public);
2414 * Token-text | Short-integer
2417 wkh_vary(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2421 wkh_1_WellKnownValue;
2422 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2423 ti = proto_tree_add_string(tree, hf_hdr_vary,
2424 tvb, hdr_start, offset - hdr_start,
2425 val_to_str_ext(val_id & 0x7F, &vals_field_names_ext,
2426 "<Unknown WSP header field 0x%02X>"));
2429 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2430 ti = proto_tree_add_string(tree, hf_hdr_vary,
2431 tvb, hdr_start, offset - hdr_start,
2434 wkh_3_ValueWithLength;
2436 wkh_4_End(hf_hdr_vary);
2441 * X-wap-security-value = 0x80
2444 wkh_x_wap_security(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2446 wkh_0a_Declarations;
2448 wkh_1_WellKnownValue;
2449 if (val_id == 0x80) {
2450 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2451 ti = proto_tree_add_string(tree, hf_hdr_x_wap_security,
2452 tvb, hdr_start, offset - hdr_start, "close-subordinate");
2455 wkh_2_TextualValueInv;
2457 wkh_3_ValueWithLength;
2459 wkh_4_End(hf_hdr_x_wap_security);
2464 * Connection-value = 0x80 | Token-text
2467 wkh_connection(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *apinfo _U_)
2471 wkh_1_WellKnownValue;
2472 if (val_id == 0x80) {
2473 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2474 ti = proto_tree_add_string(tree, hf_hdr_connection,
2475 tvb, hdr_start, offset - hdr_start, "close");
2479 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2480 ti = proto_tree_add_string(tree, hf_hdr_connection,
2481 tvb, hdr_start, offset - hdr_start, val_str);
2483 wkh_3_ValueWithLength;
2485 wkh_4_End(hf_hdr_connection);
2490 * Transfer-encoding-value = 0x80 | Token-text
2493 wkh_transfer_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2497 wkh_1_WellKnownValue;
2498 if (val_id == 0x80) {
2499 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2500 ti = proto_tree_add_string(tree, hf_hdr_transfer_encoding,
2501 tvb, hdr_start, offset - hdr_start, "chunked");
2505 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2506 ti = proto_tree_add_string(tree, hf_hdr_transfer_encoding,
2507 tvb, hdr_start, offset - hdr_start, val_str);
2509 wkh_3_ValueWithLength;
2511 wkh_4_End(hf_hdr_transfer_encoding);
2516 * Accept-range-value = 0x80 | 0x81 | Token-text
2519 wkh_accept_ranges(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2523 wkh_1_WellKnownValue;
2525 case 0x80: /* none */
2526 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2527 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2528 tvb, hdr_start, offset - hdr_start, "none");
2531 case 0x81: /* bytes */
2532 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2533 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2534 tvb, hdr_start, offset - hdr_start, "bytes");
2539 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2540 ti = proto_tree_add_string(tree, hf_hdr_accept_ranges,
2541 tvb, hdr_start, offset - hdr_start, val_str);
2543 wkh_3_ValueWithLength;
2545 wkh_4_End(hf_hdr_accept_ranges);
2550 * Content-encoding-value = 0x80 | 0x81 | 0x82 | Token-text
2553 wkh_content_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2557 wkh_1_WellKnownValue;
2559 case 0x80: /* gzip */
2560 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2561 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2562 tvb, hdr_start, offset - hdr_start, "gzip");
2565 case 0x81: /* compress */
2566 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2567 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2568 tvb, hdr_start, offset - hdr_start, "compress");
2571 case 0x82: /* deflate */
2572 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2573 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2574 tvb, hdr_start, offset - hdr_start, "deflate");
2579 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2580 ti = proto_tree_add_string(tree, hf_hdr_content_encoding,
2581 tvb, hdr_start, offset - hdr_start, val_str);
2583 wkh_3_ValueWithLength;
2585 wkh_4_End(hf_hdr_content_encoding);
2590 * Accept-encoding-value =
2593 * | ( Value-length ( Short-integer | Text-string ) [ Q-value ] )
2596 wkh_accept_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2602 proto_tree *parameter_tree = NULL;
2604 wkh_1_WellKnownValue;
2606 case 0x80: /* gzip */
2607 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2608 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2609 tvb, hdr_start, offset - hdr_start, "gzip");
2612 case 0x81: /* compress */
2613 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2614 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2615 tvb, hdr_start, offset - hdr_start, "compress");
2618 case 0x82: /* deflate */
2619 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2620 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2621 tvb, hdr_start, offset - hdr_start, "deflate");
2625 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2626 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2627 tvb, hdr_start, offset - hdr_start, "*");
2632 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2633 proto_tree_add_string(tree, hf_hdr_accept_encoding,
2634 tvb, hdr_start, offset - hdr_start, val_str);
2636 wkh_3_ValueWithLength;
2637 off = val_start + val_len_len;
2638 peek = tvb_get_guint8(tvb, off);
2639 if (is_short_integer(peek)) {
2641 case 0x80: /* gzip */
2642 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2643 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2644 tvb, hdr_start, offset - hdr_start, "gzip");
2647 case 0x81: /* compress */
2648 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2649 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2650 tvb, hdr_start, offset - hdr_start, "compress");
2653 case 0x82: /* deflate */
2654 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2655 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2656 tvb, hdr_start, offset - hdr_start, "deflate");
2659 case 0x83: /* any */
2660 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2661 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2662 tvb, hdr_start, offset - hdr_start, "*");
2668 get_token_text(str, tvb, off, len, ok);
2670 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2671 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding,
2672 tvb, hdr_start, offset - hdr_start, str);
2677 /* Remember: offset == val_start + val_len_len + val_len */
2678 if (off < offset) { /* Add Q-value if available */
2679 parameter_tree = proto_item_add_subtree(ti, ett_header);
2680 off = parameter_value_q(parameter_tree, ti, tvb, off);
2683 wkh_4_End(hf_hdr_accept_encoding);
2688 * Content-disposition-value = Value-length ( Disposition ) *( Parameter )
2689 * Disposition = Form-data | Attachment | Inline | Token-text
2693 * We handle this as:
2694 * Value-length ( Short-integer | Text-string ) *( Parameter )
2697 wkh_content_disposition(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2699 wkh_0a_Declarations;
2703 proto_tree *parameter_tree = NULL;
2705 wkh_1_WellKnownValue;
2707 wkh_2_TextualValueInv;
2709 wkh_3_ValueWithLength;
2710 off = val_start + val_len_len;
2711 peek = tvb_get_guint8(tvb, off);
2712 if (is_short_integer(peek)) {
2714 case 0x80: /* form-data */
2715 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2716 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2717 tvb, hdr_start, offset - hdr_start, "form-data");
2720 case 0x81: /* attachment */
2721 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2722 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2723 tvb, hdr_start, offset - hdr_start, "attachment");
2726 case 0x82: /* inline */
2727 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2728 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2729 tvb, hdr_start, offset - hdr_start, "inline");
2735 get_token_text(str, tvb, off, len, ok);
2737 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2738 ti = proto_tree_add_string(tree, hf_hdr_content_disposition,
2739 tvb, hdr_start, offset - hdr_start, str);
2743 if ((ok) && (off < offset)) {
2744 /* Remember: offset == val_start + val_len_len + val_len */
2745 parameter_tree = proto_item_add_subtree(ti, ett_header);
2746 while (off < offset) { /* Add parameters if available */
2747 off = parameter(parameter_tree, ti, tvb, off, offset - off);
2750 wkh_4_End(hf_hdr_content_disposition);
2755 * Common code for headers with only a textual value
2756 * is written in the macro below:
2758 #define wkh_text_header(underscored,Text) \
2760 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2762 wkh_0_Declarations; \
2764 wkh_1_WellKnownValue; \
2766 wkh_2_TextualValue; \
2767 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2768 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2769 tvb, hdr_start, offset - hdr_start, val_str); \
2771 wkh_3_ValueWithLength; \
2773 wkh_4_End(hf_hdr_ ## underscored); \
2776 /* Text-only headers: */
2777 wkh_text_header(content_base, "Content-Base")
2778 wkh_text_header(content_location, "Content-Location")
2779 wkh_text_header(etag, "ETag")
2780 wkh_text_header(from, "From")
2781 wkh_text_header(host, "Host")
2782 wkh_text_header(if_match, "If-Match")
2783 wkh_text_header(if_none_match, "If-None-Match")
2784 wkh_text_header(location, "Location")
2785 wkh_text_header(referer, "Referer")
2786 wkh_text_header(server, "Server")
2787 wkh_text_header(user_agent, "User-Agent")
2788 wkh_text_header(upgrade, "Upgrade")
2789 wkh_text_header(via, "Via")
2790 wkh_text_header(content_uri, "Content-Uri")
2791 wkh_text_header(initiator_uri, "Initiator-Uri")
2792 wkh_text_header(profile, "Profile")
2795 * Same for quoted-string value
2797 #define wkh_quoted_string_header(underscored,Text) \
2799 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2801 wkh_0_Declarations; \
2804 wkh_1_WellKnownValue; \
2806 wkh_2_TextualValue; \
2807 if (is_quoted_string(val_str[0])) { \
2808 if (is_quoted_string(val_str[val_len-2])) { \
2809 /* Trailing quote - issue a warning */ \
2810 str = g_strdup_printf("%s" TrailingQuoteWarning, val_str); \
2811 } else { /* OK (no trailing quote) */ \
2812 str = g_strdup_printf("%s\"", val_str); \
2814 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2815 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2816 tvb, hdr_start, offset - hdr_start, str); \
2819 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2820 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2821 tvb, hdr_start, offset - hdr_start, val_str); \
2822 proto_item_append_text(ti, \
2823 " <Warning: should be encoded as a Quoted-string>"); \
2826 wkh_3_ValueWithLength; \
2828 wkh_4_End(hf_hdr_ ## underscored); \
2831 wkh_quoted_string_header(content_id, "Content-ID")
2835 * Common code for headers with only a textual or a date value
2836 * is written in the macro below:
2838 #define wkh_text_or_date_value_header(underscored,Text) \
2840 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2842 wkh_0_Declarations; \
2843 guint32 val = 0, off = val_start, len; \
2844 gchar *str; /* may not be freed! */ \
2846 wkh_1_WellKnownValue; \
2848 wkh_2_TextualValue; \
2849 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2850 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2851 tvb, hdr_start, offset - hdr_start, val_str); \
2853 wkh_3_ValueWithLength; \
2854 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2855 get_date_value(val, tvb, off, len, ok); \
2857 str = abs_time_secs_to_str(val, ABSOLUTE_TIME_LOCAL, TRUE); \
2858 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2859 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2860 tvb, hdr_start, offset - hdr_start, str); \
2861 /* BEHOLD: do NOT try to free str, as \
2862 * abs_time_secs_to_str() returns ep_allocated data */ \
2865 wkh_4_End(hf_hdr_ ## underscored); \
2869 wkh_text_or_date_value_header(if_range,"If-Range")
2873 * Common code for headers with only a date value
2874 * is written in the macro below:
2876 #define wkh_date_value_header(underscored,Text) \
2878 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2880 wkh_0a_Declarations; \
2881 guint32 val = 0, off = val_start, len; \
2882 gchar *str; /* may not be freed! */ \
2884 wkh_1_WellKnownValue; \
2886 wkh_2_TextualValueInv; \
2888 wkh_3_ValueWithLength; \
2889 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2890 get_date_value(val, tvb, off, len, ok); \
2892 str = abs_time_secs_to_str(val, ABSOLUTE_TIME_LOCAL, TRUE); \
2893 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2894 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2895 tvb, hdr_start, offset - hdr_start, str); \
2896 /* BEHOLD: do NOT try to free str, as \
2897 * abs_time_secs_to_str() returns ep_allocated data */ \
2900 wkh_4_End(hf_hdr_ ## underscored); \
2903 /* Date-value only headers: */
2904 wkh_date_value_header(date, "Date")
2905 wkh_date_value_header(expires, "Expires")
2906 wkh_date_value_header(if_modified_since, "If-Modified-Since")
2907 wkh_date_value_header(if_unmodified_since, "If-Unmodified-Since")
2908 wkh_date_value_header(last_modified, "Last-Modified")
2911 /* Date-value with special interpretation of zero value */
2912 #define wkh_tod_value_header(underscored,Text) \
2914 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2916 wkh_0a_Declarations; \
2917 guint32 val = 0, off = val_start, len; \
2918 gchar *str; /* may not be freed! */ \
2920 wkh_1_WellKnownValue; \
2921 if (val_id == 0x80) { /* Openwave TOD header uses this format */ \
2922 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2923 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2924 tvb, hdr_start, offset - hdr_start, \
2925 "Requesting Time Of Day"); \
2926 proto_item_append_text(ti, \
2927 " <Warning: should be encoded as long-integer>"); \
2930 /* It seems VERY unlikely that we'll see date values within the first \
2931 * 127 seconds of the UNIX 1-1-1970 00:00:00 start of the date clocks \
2932 * so I assume such a value is a genuine error */ \
2933 wkh_2_TextualValueInv; \
2935 wkh_3_ValueWithLength; \
2936 if (val_id <= 4) { /* Length field already parsed by macro! */ \
2937 get_date_value(val, tvb, off, len, ok); \
2940 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2941 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2942 tvb, hdr_start, offset - hdr_start, \
2943 "Requesting Time Of Day"); \
2945 str = abs_time_secs_to_str(val, ABSOLUTE_TIME_LOCAL, TRUE); \
2946 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
2947 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
2948 tvb, hdr_start, offset - hdr_start, str); \
2952 wkh_4_End(hf_hdr_ ## underscored); \
2955 wkh_tod_value_header(x_wap_tod, "X-Wap-Tod")
2959 * Age-value: Delta-seconds-value
2962 wkh_age(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
2965 guint32 val = 0, off = val_start, len;
2967 wkh_1_WellKnownValue;
2968 val = val_id & 0x7F;
2969 val_str = g_strdup_printf("%u second%s", val, plurality(val, "", "s"));
2970 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2971 ti = proto_tree_add_string(tree, hf_hdr_age,
2972 tvb, hdr_start, offset - hdr_start, val_str);
2973 g_free( (gpointer) val_str); /* proto_XXX creates a copy */
2975 wkh_2_TextualValueInv;
2977 wkh_3_ValueWithLength;
2978 if (val_id <= 4) { /* Length field already parsed by macro! */
2979 get_long_integer(val, tvb, off, len, ok);
2981 val_str = g_strdup_printf("%u second%s", val, plurality(val, "", "s"));
2982 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
2983 ti = proto_tree_add_string(tree, hf_hdr_age,
2984 tvb, hdr_start, offset - hdr_start, val_str);
2985 g_free( (gpointer) val_str); /* proto_XXX creates a copy */
2988 wkh_4_End(hf_hdr_age);
2993 * Template for Integer lookup or text value headers:
2995 #define wkh_integer_lookup_or_text_value(underscored,Text,valueStringExtAddr,valueName) \
2997 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
2999 wkh_0_Declarations; \
3000 guint32 val = 0, off = val_start, len; \
3002 wkh_1_WellKnownValue; \
3003 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3004 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3005 tvb, hdr_start, offset - hdr_start, \
3006 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, \
3007 "(Unknown " valueName " identifier 0x%X)")); \
3009 wkh_2_TextualValue; \
3010 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3011 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3012 tvb, hdr_start, offset - hdr_start, val_str); \
3014 wkh_3_ValueWithLength; \
3015 if (val_id <= 4) { /* Length field already parsed by macro! */ \
3016 get_long_integer(val, tvb, off, len, ok); \
3018 val = val; /* hack to prevent 'set but not used' gcc warning */ \
3019 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3020 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3021 tvb, hdr_start, offset - hdr_start, \
3022 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, \
3023 "(Unknown " valueName " identifier 0x%X)")); \
3026 wkh_4_End(hf_hdr_ ## underscored); \
3030 * Wap-application-value: Uri-value | Integer-value
3032 wkh_integer_lookup_or_text_value(x_wap_application_id, "X-Wap-Application-Id",
3033 &vals_wap_application_ids_ext, "WAP application")
3034 wkh_integer_lookup_or_text_value(accept_application, "Accept-Application",
3035 &vals_wap_application_ids_ext, "WAP application")
3036 wkh_integer_lookup_or_text_value(content_language, "Content-Language",
3037 &vals_languages_ext, "language")
3038 /* NOTE - Although the WSP spec says this is an integer-value, the WSP headers
3039 * are encoded as a 7-bit entity! */
3040 wkh_integer_lookup_or_text_value(trailer, "Trailer",
3041 &vals_field_names_ext, "well-known-header")
3049 * Common code for headers with only a challenge value
3050 * is written in the macro below:
3052 #define wkh_challenge_value_header(underscored,Text) \
3054 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, \
3055 guint32 hdr_start, packet_info *pinfo _U_) \
3057 wkh_0_Declarations; \
3060 proto_tree *subtree; \
3063 wkh_1_WellKnownValue; \
3065 wkh_2_TextualValueInv; \
3067 wkh_3_ValueWithLength; \
3068 off = val_start + val_len_len; \
3069 peek = tvb_get_guint8(tvb, off); \
3070 if (peek == 0x80) { /* Basic */ \
3071 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3072 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3073 tvb, hdr_start, offset - hdr_start, "basic"); \
3074 subtree = proto_item_add_subtree(ti, ett_header); \
3075 proto_tree_add_string(subtree, hf_hdr_ ## underscored ## _scheme, \
3076 tvb, off, 1, "basic"); \
3078 /* Realm: text-string */ \
3079 get_text_string(str,tvb,off,len,ok); \
3081 proto_tree_add_string(subtree, \
3082 hf_hdr_ ## underscored ## _realm, \
3083 tvb, off, len, str); \
3084 val_str = g_strdup_printf("; realm=%s", str); \
3085 proto_item_append_string(ti, val_str); \
3086 g_free( (gpointer) val_str); \
3089 } else { /* Authentication-scheme: token-text */ \
3090 get_token_text(str, tvb, off, len, ok); \
3092 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3093 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3094 tvb, hdr_start, off - hdr_start, str); \
3095 subtree = proto_item_add_subtree(ti, ett_header); \
3096 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3097 proto_tree_add_string(subtree, \
3098 hf_hdr_ ## underscored ## _scheme, \
3099 tvb, hdr_start, off - hdr_start, str); \
3101 /* Realm: text-string */ \
3102 get_text_string(str,tvb,off,len,ok); \
3104 proto_tree_add_string(subtree, \
3105 hf_hdr_ ## underscored ## _realm, \
3106 tvb, off, len, str); \
3107 val_str = g_strdup_printf("; realm=%s", str); \
3108 proto_item_append_string(ti, val_str); \
3109 g_free( (gpointer) val_str); \
3111 /* Auth-params: parameter - TODO */ \
3112 while (off < offset) /* Parse parameters */ \
3113 off = parameter(subtree, ti, tvb, off, offset - off); \
3117 wkh_4_End(hf_hdr_ ## underscored); \
3120 /* Challenge-value only headers: */
3121 wkh_challenge_value_header(www_authenticate, "WWW-Authenticate")
3122 wkh_challenge_value_header(proxy_authenticate, "Proxy-Authenticate")
3130 * Common code for headers with only a credentials value
3131 * is written in the macro below:
3133 #define wkh_credentials_value_header(underscored,Text) \
3135 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, \
3136 guint32 hdr_start, packet_info *pinfo _U_) \
3138 wkh_0_Declarations; \
3141 proto_tree *subtree; \
3144 wkh_1_WellKnownValue; \
3146 wkh_2_TextualValueInv; \
3148 wkh_3_ValueWithLength; \
3149 off = val_start + val_len_len; \
3150 peek = tvb_get_guint8(tvb, off); \
3151 if (peek == 0x80) { /* Basic */ \
3152 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3153 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3154 tvb, hdr_start, offset - hdr_start, "basic"); \
3155 subtree = proto_item_add_subtree(ti, ett_header); \
3156 proto_tree_add_string(subtree, hf_hdr_ ## underscored ## _scheme, \
3157 tvb, off, 1, "basic"); \
3159 /* User-id: text-string */ \
3160 get_text_string(str,tvb,off,len,ok); \
3162 proto_tree_add_string(subtree, \
3163 hf_hdr_ ## underscored ## _user_id, \
3164 tvb, off, len, str); \
3165 val_str = g_strdup_printf("; user-id=%s", str); \
3166 proto_item_append_string(ti, val_str); \
3167 g_free( (gpointer) val_str); \
3169 /* Password: text-string */ \
3170 get_text_string(str,tvb,off,len,ok); \
3172 proto_tree_add_string(subtree, \
3173 hf_hdr_ ## underscored ## _password, \
3174 tvb, off, len, str); \
3175 val_str = g_strdup_printf("; password=%s", str); \
3176 proto_item_append_string(ti, val_str); \
3177 g_free( (gpointer) val_str); \
3181 } else { /* Authentication-scheme: token-text */ \
3182 get_token_text(str, tvb, off, len, ok); \
3184 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3185 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3186 tvb, hdr_start, off - hdr_start, str); \
3187 subtree = proto_item_add_subtree(ti, ett_header); \
3188 proto_tree_add_string(subtree, \
3189 hf_hdr_ ## underscored ## _scheme, \
3190 tvb, hdr_start, off - hdr_start, str); \
3192 /* Auth-params: parameter - TODO */ \
3193 while (off < offset) /* Parse parameters */ \
3194 off = parameter(subtree, ti, tvb, off, offset - off); \
3197 wkh_4_End(hf_hdr_ ## underscored); \
3200 /* Credentials-value only headers: */
3201 wkh_credentials_value_header(authorization, "Authorization")
3202 wkh_credentials_value_header(proxy_authorization, "Proxy-Authorization")
3206 * Content-md5-value = 16*16 OCTET
3209 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3214 wkh_1_WellKnownValue;
3216 wkh_2_TextualValueInv;
3218 wkh_3_ValueWithLength;
3219 off = val_start + val_len_len;
3220 if (val_len == 16) {
3221 val_str = g_strdup_printf(
3222 "%02x%02x%02x%02x%02x%02x%02x%02x"
3223 "%02x%02x%02x%02x%02x%02x%02x%02x",
3224 tvb_get_guint8(tvb, off),
3225 tvb_get_guint8(tvb, off + 1),
3226 tvb_get_guint8(tvb, off + 2),
3227 tvb_get_guint8(tvb, off + 3),
3228 tvb_get_guint8(tvb, off + 4),
3229 tvb_get_guint8(tvb, off + 5),
3230 tvb_get_guint8(tvb, off + 6),
3231 tvb_get_guint8(tvb, off + 7),
3232 tvb_get_guint8(tvb, off + 8),
3233 tvb_get_guint8(tvb, off + 9),
3234 tvb_get_guint8(tvb, off + 10),
3235 tvb_get_guint8(tvb, off + 11),
3236 tvb_get_guint8(tvb, off + 12),
3237 tvb_get_guint8(tvb, off + 13),
3238 tvb_get_guint8(tvb, off + 14),
3239 tvb_get_guint8(tvb, off + 15)
3241 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3242 ti = proto_tree_add_string(tree, hf_hdr_content_md5,
3243 tvb, hdr_start, offset - hdr_start, val_str);
3244 g_free( (gpointer) val_str);
3247 wkh_4_End(hf_hdr_content_md5);
3252 * Pragma-value = 0x80 | Length Parameter
3255 wkh_pragma(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3257 wkh_0a_Declarations;
3260 wkh_1_WellKnownValue;
3261 if (val_id == 0x80) {
3262 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3263 ti = proto_tree_add_string(tree, hf_hdr_pragma,
3264 tvb, hdr_start, offset - hdr_start, "no-cache");
3267 wkh_2_TextualValueInv;
3269 wkh_3_ValueWithLength;
3270 off = val_start + val_len_len;
3271 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3272 ti = proto_tree_add_string(tree, hf_hdr_pragma,
3273 tvb, hdr_start, off - hdr_start, "");
3274 /* NULL subtree for parameter() results in no subtree
3275 * TODO - provide a single parameter dissector that appends data
3276 * to the header field data. */
3277 off = parameter(NULL, ti, tvb, off, offset - off);
3279 wkh_4_End(hf_hdr_pragma);
3286 #define wkh_integer_value_header(underscored,Text) \
3288 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
3290 wkh_0a_Declarations; \
3291 guint32 val = 0, off = val_start, len; \
3292 gchar *str; /* may not be freed! */ \
3294 wkh_1_WellKnownValue; \
3295 str = g_strdup_printf("%u", val_id & 0x7F); \
3296 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3297 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3298 tvb, hdr_start, offset - hdr_start, str); \
3301 wkh_2_TextualValueInv; \
3303 wkh_3_ValueWithLength; \
3304 if (val_id <= 4) { /* Length field already parsed by macro! */ \
3305 get_long_integer(val, tvb, off, len, ok); \
3307 str = g_strdup_printf("%u", val); \
3308 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3309 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3310 tvb, hdr_start, offset - hdr_start, str); \
3314 wkh_4_End(hf_hdr_ ## underscored); \
3317 wkh_integer_value_header(content_length, "Content-Length")
3318 wkh_integer_value_header(max_forwards, "Max-Forwards")
3321 #define wkh_integer_lookup_value_header(underscored,Text,valueStringExtAddr,valueName) \
3323 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \
3325 wkh_0_Declarations; \
3326 guint32 val = 0, off = val_start, len; \
3328 wkh_1_WellKnownValue; \
3329 val_str = match_strval_ext(val_id & 0x7F, valueStringExtAddr); \
3331 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3332 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3333 tvb, hdr_start, offset - hdr_start, val_str); \
3336 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3337 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3338 tvb, hdr_start, offset - hdr_start, \
3339 "<Unknown " valueName ">"); \
3341 wkh_2_TextualValueInv; \
3343 wkh_3_ValueWithLength; \
3344 if (val_id <= 4) { /* Length field already parsed by macro! */ \
3345 get_long_integer(val, tvb, off, len, ok); \
3347 val = val; /* hack to prevent 'set but not used' gcc warning */ \
3348 val_str = match_strval_ext(val_id & 0x7F, valueStringExtAddr); \
3350 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3351 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3352 tvb, hdr_start, offset - hdr_start, val_str); \
3355 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3356 ti = proto_tree_add_string(tree, hf_hdr_ ## underscored, \
3357 tvb, hdr_start, offset - hdr_start, \
3358 "<Unknown " valueName ">"); \
3362 wkh_4_End(hf_hdr_ ## underscored); \
3365 wkh_integer_lookup_value_header(bearer_indication, "Bearer-Indication",
3366 &vals_bearer_types_ext, "bearer type")
3370 * Cache-control-value
3373 wkh_cache_control(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3376 guint32 off, len, val = 0;
3377 guint8 peek, cache_control_directive;
3380 wkh_1_WellKnownValue;
3381 val = val_id & 0x7F;
3382 val_str = match_strval_ext(val, &vals_cache_control_ext);
3384 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3385 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3386 tvb, hdr_start, offset - hdr_start, val_str);
3390 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3391 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3392 tvb, hdr_start, offset - hdr_start, val_str);
3394 wkh_3_ValueWithLength;
3396 * ( no-cache | private ) 1*( Field-name )
3397 * | ( max-age | max-stale | min-fresh | s-maxage) Delta-seconds-value
3398 * | Token-text ( Integer-value | Text-value )
3400 * Field-name = Short-integer | Token-text
3402 off = val_start + val_len_len;
3403 cache_control_directive = tvb_get_guint8(tvb, off++);
3404 if (cache_control_directive & 0x80) { /* Well known cache directive */
3405 switch (cache_control_directive & 0x7F) {
3406 case CACHE_CONTROL_NO_CACHE:
3407 case CACHE_CONTROL_PRIVATE:
3408 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3409 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3410 tvb, hdr_start, offset - hdr_start,
3411 val_to_str_ext (cache_control_directive & 0x7F, &vals_cache_control_ext,
3412 "<Unknown cache control directive 0x%02X>"));
3413 /* TODO: split multiple entries */
3415 while (ok && (off < offset)) { /* 1*( Field-name ) */
3416 peek = tvb_get_guint8(tvb, off);
3417 if (peek & 0x80) { /* Well-known-field-name */
3418 proto_item_append_string(ti,
3419 val_to_str (peek, vals_field_names,
3420 "<Unknown WSP header field 0x%02X>"));
3422 } else { /* Token-text */
3423 get_token_text(val_str, tvb, off, len, ok);
3425 proto_item_append_string(ti, val_str);
3432 case CACHE_CONTROL_MAX_AGE:
3433 case CACHE_CONTROL_MAX_STALE:
3434 case CACHE_CONTROL_MIN_FRESH:
3435 case CACHE_CONTROL_S_MAXAGE:
3436 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3437 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3438 tvb, hdr_start, offset - hdr_start,
3439 val_to_str_ext (cache_control_directive & 0x7F, &vals_cache_control_ext,
3440 "<Unknown cache control directive 0x%02X>"));
3441 get_delta_seconds_value(val, tvb, off, len, ok);
3443 val_str = g_strdup_printf("=%u second%s",
3444 val, plurality(val, "", "s"));
3445 proto_item_append_string(ti, val_str);
3446 g_free( (gpointer) val_str); /* proto_XXX creates a copy */
3454 } else if (is_token_text(cache_control_directive)) {
3455 get_token_text(val_str, tvb, off, len, ok);
3457 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3458 ti = proto_tree_add_string(tree, hf_hdr_cache_control,
3459 tvb, hdr_start, offset - hdr_start, val_str);
3460 get_integer_value(val, tvb, off, len, ok);
3461 if (ok) { /* Integer-value */
3462 val_str = g_strdup_printf("=%u", val);
3463 proto_item_append_string(ti, val_str);
3464 g_free( (gpointer) val_str); /* proto_XXX creates a copy */
3465 } else { /* Text-value */
3466 get_text_string(val_str, tvb, off, len, ok);
3468 if (is_quoted_string(val_str[0])) {
3469 if (is_quoted_string(val_str[len-2])) {
3470 /* Trailing quote - issue a warning */
3471 str = g_strdup_printf("%s" TrailingQuoteWarning,
3473 } else { /* OK (no trailing quote) */
3474 str = g_strdup_printf("%s\"", val_str);
3476 proto_item_append_string(ti, str);
3478 } else { /* Token-text | 0x00 */
3479 /* TODO - check that we have Token-text or 0x00 */
3480 proto_item_append_string(ti, val_str);
3486 wkh_4_End(hf_hdr_cache_control);
3493 * | ( Value-length Short-integer Text-string Text-string )
3496 wkh_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3499 guint32 off, len, val;
3502 proto_tree *subtree;
3504 /* TODO - subtree with values */
3506 wkh_1_WellKnownValue;
3507 val = val_id & 0x7F;
3508 val_str = match_strval_ext(val, &vals_wsp_warning_code_ext);
3510 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3511 ti = proto_tree_add_string(tree, hf_hdr_warning,
3512 tvb, hdr_start, offset - hdr_start, val_str);
3513 subtree = proto_item_add_subtree(ti, ett_header);
3514 proto_tree_add_uint(subtree, hf_hdr_warning_code,
3515 tvb, val_start, 1, val);
3518 wkh_2_TextualValueInv;
3520 wkh_3_ValueWithLength;
3521 /* TODO - subtree with individual values */
3522 off = val_start + val_len_len;
3523 warn_code = tvb_get_guint8(tvb, off);
3524 if (warn_code & 0x80) { /* Well known warn code */
3525 val = warn_code & 0x7f;
3526 val_str = match_strval_ext(val, &vals_wsp_warning_code_short_ext);
3527 if (val_str) { /* OK */
3528 str = g_strdup_printf("code=%s", val_str);
3529 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3530 ti = proto_tree_add_string(tree, hf_hdr_warning,
3531 tvb, hdr_start, offset - hdr_start, str);
3533 subtree = proto_item_add_subtree(ti, ett_header);
3534 proto_tree_add_uint(subtree, hf_hdr_warning_code,
3536 off++; /* Now skip to the warn-agent subfield */
3537 get_text_string(str, tvb, off, len, ok);
3538 if (ok) { /* Valid warn-agent string */
3539 proto_tree_add_string(subtree, hf_hdr_warning_agent,
3540 tvb, off, len, str);
3541 val_str = g_strdup_printf("; agent=%s", str);
3542 proto_item_append_string(ti, val_str);
3543 g_free( (gpointer) val_str); /* proto_XXX creates a copy */
3545 get_text_string(str, tvb, off, len, ok);
3546 if (ok) { /* Valid warn-text string */
3547 proto_tree_add_string(subtree,
3548 hf_hdr_warning_text,
3549 tvb, off, len, str);
3550 val_str = g_strdup_printf("; text=%s", str);
3551 proto_item_append_string(ti, val_str);
3552 g_free( (gpointer) val_str); /* proto_XXX creates a copy */
3558 wkh_4_End(hf_hdr_warning);
3563 * Profile-warning-value =
3565 * | ( Value-length Short-integer Text-string *( Date-value ) )
3568 wkh_profile_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3571 guint32 off, len, val = 0;
3575 wkh_1_WellKnownValue;
3576 val = val_id & 0x7F;
3577 val_str = match_strval_ext(val, &vals_wsp_profile_warning_code_ext);
3579 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3580 ti = proto_tree_add_string(tree, hf_hdr_profile_warning,
3581 tvb, hdr_start, offset - hdr_start, val_str);
3584 wkh_2_TextualValueInv;
3586 wkh_3_ValueWithLength;
3587 off = val_start + val_len_len;
3588 warn_code = tvb_get_guint8(tvb, off++);
3589 if (warn_code & 0x80) { /* Well known warn code */
3590 val_str = match_strval_ext(val, &vals_wsp_profile_warning_code_ext);
3591 if (val_str) { /* OK */
3592 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3593 ti = proto_tree_add_string(tree, hf_hdr_profile_warning,
3594 tvb, hdr_start, offset - hdr_start, val_str);
3595 get_uri_value(str, tvb, off, len, ok);
3596 if (ok) { /* Valid warn-target string */
3597 /* TODO: Why did we just call get_uri_value() and not use
3598 * the str, since the pointer to it is immediately
3599 * forgotten with the call to g_strdup_printf()? */
3601 str = g_strdup_printf("; target=%s", val_str);
3602 proto_item_append_string(ti, str);
3603 g_free(str); /* proto_XXX creates a copy */
3604 /* Add zero or more dates */
3605 while (ok && (off < offset)) {
3606 get_date_value(val, tvb, off, len, ok);
3607 if (ok) { /* Valid warn-text string */
3609 val_str = abs_time_secs_to_str(val, ABSOLUTE_TIME_LOCAL, TRUE);
3610 str = g_strdup_printf("; date=%s", val_str);
3611 proto_item_append_string(ti, str);
3612 g_free(str); /* proto_XXX creates a copy */
3613 /* BEHOLD: do NOT try to free str, as \
3614 * abs_time_secs_to_str() returns ep_allocated data */ \
3620 wkh_4_End(hf_hdr_profile_warning);
3624 /* Encoding-version-value =
3627 * | Length Short-integer [ Short-integer | text-string ]
3629 static guint32 wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb,
3630 guint32 hdr_start, packet_info *pinfo _U_)
3633 guint32 off, val, len;
3636 wkh_1_WellKnownValue;
3637 val = val_id & 0x7F;
3638 val_str = g_strdup_printf("%u.%u", val >> 4, val & 0x0F);
3639 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3640 proto_tree_add_string(tree, hf_hdr_encoding_version,
3641 tvb, hdr_start, offset - hdr_start, val_str);
3642 g_free( (gpointer) val_str);
3645 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3646 proto_tree_add_string(tree, hf_hdr_encoding_version,
3647 tvb, hdr_start, offset - hdr_start, val_str);
3649 wkh_3_ValueWithLength;
3650 off = val_start + val_len_len;
3651 val = tvb_get_guint8(tvb, off);
3652 if (val & 0x80) { /* Header Code Page */
3653 val_str = g_strdup_printf("code-page=%u", val & 0x7F);
3654 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3655 ti = proto_tree_add_string(tree, hf_hdr_encoding_version,
3656 tvb, hdr_start, offset - hdr_start, val_str);
3657 g_free( (gpointer) val_str);
3660 if (off < offset) { /* Extra version-value */
3661 get_version_value(val,val_str,tvb,off,len,ok);
3662 if (ok) { /* Always creates a string if OK */
3663 str = g_strdup_printf(": %s", val_str);
3664 proto_item_append_string(ti, str);
3670 wkh_4_End(hf_hdr_encoding_version);
3674 /* Content-range-value =
3675 * Length Uintvar-integer ( 0x80 | Uintvar-integer )
3678 wkh_content_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3681 guint32 off, val, len;
3682 proto_tree *subtree = NULL;
3684 wkh_1_WellKnownValue;
3686 wkh_2_TextualValueInv;
3688 wkh_3_ValueWithLength;
3689 off = val_start + val_len_len;
3690 get_uintvar_integer (val, tvb, off, len, ok); /* Uintvar start */
3692 val_str = g_strdup_printf("first-byte-pos=%u", val);
3693 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3694 ti = proto_tree_add_string(tree, hf_hdr_content_range,
3695 tvb, hdr_start, offset - hdr_start, val_str);
3696 subtree = proto_item_add_subtree(ti, ett_header);
3697 proto_tree_add_uint(subtree, hf_hdr_content_range_first_byte_pos,
3698 tvb, off, len, val);
3699 g_free( (gpointer) val_str);
3701 /* Now check next value */
3702 val = tvb_get_guint8(tvb, off);
3703 if (val == 0x80) { /* Unknown length */
3704 proto_item_append_string(ti, "; entity-length=unknown");
3705 } else { /* Uintvar entity length */
3706 get_uintvar_integer (val, tvb, off, len, ok);
3708 val_str = g_strdup_printf("; entity-length=%u", val);
3709 proto_item_append_string(ti, val_str);
3710 proto_tree_add_uint(subtree,
3711 hf_hdr_content_range_entity_length,
3712 tvb, off, len, val);
3713 g_free( (gpointer) val_str);
3718 wkh_4_End(hf_hdr_content_range);
3724 * 0x80 Uintvar-integer [ Uintvar-integer ]
3725 * | 0x81 Uintvar-integer
3728 wkh_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3731 guint32 off, val, len;
3732 proto_tree *subtree = NULL;
3734 wkh_1_WellKnownValue;
3736 wkh_2_TextualValueInv;
3738 wkh_3_ValueWithLength;
3739 off = val_start + val_len_len;
3740 val = tvb_get_guint8(tvb, off);
3741 if (val == 0x80) { /* Byte-range */
3742 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3743 ti = proto_tree_add_string(tree, hf_hdr_range,
3744 tvb, hdr_start, offset - hdr_start, "byte-range");
3745 subtree = proto_item_add_subtree(ti, ett_header);
3746 /* Get the First-byte-pos (Uintvar-integer) */
3747 get_uintvar_integer (val, tvb, off, len, ok);
3749 val_str = g_strdup_printf("; first-byte-pos=%u", val);
3750 proto_item_append_string(ti, val_str);
3751 proto_tree_add_uint(subtree, hf_hdr_range_first_byte_pos,
3752 tvb, off, len, val);
3753 g_free( (gpointer) val_str);
3755 /* Get the optional Last-byte-pos (Uintvar-integer) */
3757 get_uintvar_integer (val, tvb, off, len, ok);
3759 val_str = g_strdup_printf("; last-byte-pos=%u", val);
3760 proto_item_append_string(ti, val_str);
3761 proto_tree_add_uint(subtree,
3762 hf_hdr_range_last_byte_pos,
3763 tvb, off, len, val);
3764 g_free( (gpointer) val_str);
3768 } else if (val == 0x81) { /* Suffix-byte-range */
3769 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3770 ti = proto_tree_add_string(tree, hf_hdr_range,
3771 tvb, hdr_start, offset - hdr_start, "suffix-byte-range");
3772 subtree = proto_item_add_subtree(ti, ett_header);
3773 /* Get the Suffix-length (Uintvar-integer) */
3774 get_uintvar_integer (val, tvb, off, len, ok);
3776 val_str = g_strdup_printf("; suffix-length=%u", val);
3777 proto_item_append_string(ti, val_str);
3778 proto_tree_add_uint(subtree, hf_hdr_range_suffix_length,
3779 tvb, off, len, val);
3780 g_free( (gpointer) val_str);
3784 wkh_4_End(hf_hdr_range);
3790 * | Value-length (0x82--0x86 | Token-text) [ Q-token Q-value ]
3792 static guint32 wkh_te (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3795 guint32 off, val, len;
3797 wkh_1_WellKnownValue;
3798 if (val_id == 0x81) {
3799 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3800 proto_tree_add_string(tree, hf_hdr_encoding_version,
3801 tvb, hdr_start, offset - hdr_start, "trailers");
3804 wkh_2_TextualValueInv;
3806 wkh_3_ValueWithLength;
3807 off = val_start + val_len_len;
3808 val = tvb_get_guint8(tvb, off);
3809 if (val & 0x80) { /* Well-known-TE */
3810 val_str = match_strval_ext((val & 0x7F), &vals_well_known_te_ext);
3812 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3813 ti = proto_tree_add_string(tree, hf_hdr_te,
3814 tvb, hdr_start, off - hdr_start, val_str);
3818 } else { /* TE in Token-text format */
3819 get_token_text(val_str, tvb, off, len, ok);
3821 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3822 ti = proto_tree_add_string(tree, hf_hdr_te,
3823 tvb, hdr_start, off - hdr_start, val_str);
3827 if ((ok) && (off < offset)) { /* Q-token Q-value */
3831 wkh_4_End(hf_hdr_te);
3835 /****************************************************************************
3836 * O p e n w a v e h e a d e r s
3837 ****************************************************************************/
3843 * Redefine the WellKnownValue parsing so Openwave header field names are used
3844 * are used instead of the default WSP header field names
3846 #undef wkh_1_WellKnownValue
3847 #define wkh_1_WellKnownValue /* Parse Well Known Value */ \
3848 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3849 hidden_item = proto_tree_add_string(tree, hf_hdr_name, \
3850 tvb, hdr_start, offset - hdr_start, \
3851 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext, \
3852 "<Unknown WSP header field 0x%02X>")); \
3853 PROTO_ITEM_SET_HIDDEN(hidden_item); \
3854 if (val_id & 0x80) { /* Well-known value */ \
3856 /* Well-known value processing starts HERE \
3861 * Redefine the End parsing so Openwave header field names are used
3862 * instead of the default WSP field names
3865 #define wkh_4_End(hf) /* End of value parsing */ \
3868 /* Check for errors */ \
3870 if (ti) { /* Append to protocol tree item label */ \
3871 proto_item_append_text(ti, \
3872 "<Error: Invalid header value>"); \
3873 } else if (hf > 0) { /* Create protocol tree item */ \
3874 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3875 proto_tree_add_string(tree, hf, \
3876 tvb, hdr_start, offset - hdr_start, \
3877 " <Error: Invalid header value>"); \
3878 } else { /* Create anonymous header field entry */ \
3879 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start); \
3880 proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start, \
3881 "%s: <Error: Invalid header value>", \
3882 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext, \
3883 "<Unknown WSP header field 0x%02X>")); \
3889 /* Dissect the Openwave header value (generic) */
3891 wkh_openwave_default(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_)
3895 ok = TRUE; /* Bypass error checking as we don't parse the values! */
3897 wkh_1_WellKnownValue;
3898 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3899 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
3900 "%s: (Undecoded well-known value 0x%02x)",
3901 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext,
3902 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F);
3904 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3905 ti = proto_tree_add_text(tree,tvb,hdr_start, offset - hdr_start,
3907 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext,
3908 "<Unknown WSP header field 0x%02X>"), val_str);
3909 wkh_3_ValueWithLength;
3910 tvb_ensure_bytes_exist(tvb, hdr_start, offset - hdr_start);
3911 ti = proto_tree_add_text(tree, tvb, hdr_start, offset - hdr_start,
3912 "%s: (Undecoded value in general form with length indicator)",
3913 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext,
3914 "<Unknown WSP header field 0x%02X>"));
3916 wkh_4_End(HF_EMPTY); /* See wkh_default for explanation */
3920 /* Textual Openwave headers */
3921 wkh_text_header(openwave_x_up_proxy_operator_domain,
3922 "x-up-proxy-operator-domain")
3923 wkh_text_header(openwave_x_up_proxy_home_page,
3924 "x-up-proxy-home-page")
3925 wkh_text_header(openwave_x_up_proxy_uplink_version,
3926 "x-up-proxy-uplink-version")
3927 wkh_text_header(openwave_x_up_proxy_ba_realm,
3928 "x-up-proxy-ba-realm")
3929 wkh_text_header(openwave_x_up_proxy_request_uri,
3930 "x-up-proxy-request-uri")
3931 wkh_text_header(openwave_x_up_proxy_bookmark,
3932 "x-up-proxy-bookmark")
3934 /* Integer Openwave headers */
3935 wkh_integer_value_header(openwave_x_up_proxy_push_seq,
3936 "x-up-proxy-push-seq")
3937 wkh_integer_value_header(openwave_x_up_proxy_notify,
3938 "x-up-proxy-notify")
3939 wkh_integer_value_header(openwave_x_up_proxy_net_ask,
3940 "x-up-proxy-net-ask")
3941 wkh_integer_value_header(openwave_x_up_proxy_ba_enable,
3942 "x-up-proxy-ba-enable")
3943 wkh_integer_value_header(openwave_x_up_proxy_redirect_enable,
3944 "x-up-proxy-redirect-enable")
3945 wkh_integer_value_header(openwave_x_up_proxy_redirect_status,
3946 "x-up-proxy-redirect-status")
3947 wkh_integer_value_header(openwave_x_up_proxy_linger,
3948 "x-up-proxy-linger")
3949 wkh_integer_value_header(openwave_x_up_proxy_enable_trust,
3950 "x-up-proxy-enable-trust")
3951 wkh_integer_value_header(openwave_x_up_proxy_trust,
3954 wkh_integer_value_header(openwave_x_up_devcap_has_color,
3955 "x-up-devcap-has-color")
3956 wkh_integer_value_header(openwave_x_up_devcap_num_softkeys,
3957 "x-up-devcap-num-softkeys")
3958 wkh_integer_value_header(openwave_x_up_devcap_softkey_size,
3959 "x-up-devcap-softkey-size")
3960 wkh_integer_value_header(openwave_x_up_devcap_screen_chars,
3961 "x-up-devcap-screen-chars")
3962 wkh_integer_value_header(openwave_x_up_devcap_screen_pixels,
3963 "x-up-devcap-screen-pixels")
3964 wkh_integer_value_header(openwave_x_up_devcap_em_size,
3965 "x-up-devcap-em-size")
3966 wkh_integer_value_header(openwave_x_up_devcap_screen_depth,
3967 "x-up-devcap-screen-depth")
3968 wkh_integer_value_header(openwave_x_up_devcap_immed_alert,
3969 "x-up-devcap-immed_alert")
3970 wkh_integer_value_header(openwave_x_up_devcap_gui,
3973 /* Openwave Time-Of-Day value header */
3974 wkh_tod_value_header(openwave_x_up_proxy_tod,
3977 /* Openwave accept_x_q header */
3978 wkh_accept_x_q_header(openwave_x_up_proxy_trans_charset,
3979 "x-up-proxy-trans-charset",
3980 &vals_character_sets_ext, "character set")
3982 /* Openwave content type header */
3983 wkh_content_type_header(openwave_x_up_proxy_push_accept,
3984 "x-up-proxy-push-accept")
3987 * Header value parameter parsing
3989 #define InvalidParameterValue(parameter,value) \
3990 "<Error: Invalid " parameter " parameter value: invalid " value ">"
3996 #define parameter_text(hf,lowercase,Uppercase,value) \
3997 DebugLog(("parameter with text_string value: " Uppercase "\n")); \
3998 get_text_string(val_str, tvb, offset, val_len, ok); \
4000 DebugLog(("OK, valid text_string value found!\n")); \
4001 DebugLog(("Adding val_str to the header field in proto tree\n")); \
4002 proto_tree_add_string(tree, hf, \
4003 tvb, start, type_len + val_len, val_str); \
4004 DebugLog(("Creating str to append to ti\n")); \
4005 str = g_strdup_printf("; " lowercase "=%s", val_str); \
4006 DebugLog(("Appending str to ti\n")); \
4007 proto_item_append_string(ti, str); \
4008 DebugLog(("\tFreeing str [%s]\n", str)); \
4010 offset += val_len; \
4012 DebugLog(("\tError: invalid parameter value!\n")); \
4013 proto_tree_add_string(tree, hf, tvb, start, len, \
4014 InvalidParameterValue(Uppercase, value)); \
4015 offset = start + len; /* Skip to end of buffer */ \
4017 DebugLog(("parameter with text_string value - END\n"));
4020 #define parameter_text_value(hf,lowercase,Uppercase,value) \
4021 get_text_string(val_str, tvb, offset, val_len, ok); \
4023 if (is_quoted_string(val_str[0])) { \
4024 if (is_quoted_string(val_str[val_len-2])) { \
4025 /* Trailing quote - issue a warning */ \
4026 str = g_strdup_printf("%s" TrailingQuoteWarning, val_str); \
4027 proto_tree_add_string(tree, hf, \
4028 tvb, start, type_len + val_len, str); \
4030 str = g_strdup_printf("; " lowercase "=%s", val_str); \
4031 } else { /* OK (no trailing quote) */ \
4032 str = g_strdup_printf("%s\"", val_str); \
4033 proto_tree_add_string(tree, hf, \
4034 tvb, start, type_len + val_len, str); \
4036 str = g_strdup_printf("; " lowercase "=%s\"", val_str); \
4038 } else { /* Token-text | 0x00 */ \
4039 /* TODO - verify that we have either Token-text or 0x00 */ \
4040 proto_tree_add_string(tree, hf, \
4041 tvb, start, type_len + val_len, val_str); \
4042 str = g_strdup_printf("; " lowercase "=%s", val_str); \
4044 proto_item_append_string(ti, str); \
4046 offset += val_len; \
4048 proto_tree_add_string(tree, hf, tvb, start, len, \
4049 InvalidParameterValue(Uppercase, value)); \
4050 offset = start + len; /* Skip to end of buffer */ \
4054 /* Parameter = Untyped-parameter | Typed-parameter
4055 * Untyped-parameter = Token-text ( Integer-value | Text-value )
4058 * ( Integer-value | Date-value | Delta-seconds-value
4059 * | Q-value | Version-value | Uri-value )
4063 * Returns: next offset
4065 * TODO - Verify byte highlighting in case of invalid parameter values
4068 parameter (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start, int len)
4071 guint8 peek = tvb_get_guint8 (tvb,start);
4072 guint32 val = 0, type = 0, type_len, val_len;
4074 const gchar *val_str = NULL;
4078 DebugLog(("parameter(start = %u, len = %u)\n", start, len));
4079 if (is_token_text (peek)) {
4083 DebugLog(("parameter() - Untyped - Start\n"));
4084 get_token_text (str,tvb,start,val_len,ok); /* Should always succeed */
4085 if (ok) { /* Found a textual parameter name: str */
4087 get_text_value(val_str, tvb, offset, val_len, ok);
4088 if (ok) { /* Also found a textual parameter value: val_str */
4089 DebugLog(("Trying textual parameter value.\n"));
4091 if (is_quoted_string(val_str[0])) { /* Add trailing quote! */
4092 if (is_quoted_string(val_str[val_len-2])) {
4093 /* Trailing quote - issue a warning */
4094 tvb_ensure_bytes_exist(tvb, start, offset - start);
4095 proto_tree_add_text(tree, tvb, start, offset - start,
4096 "%s: %s" TrailingQuoteWarning, str, val_str);
4097 s = g_strdup_printf("; %s=%s", str, val_str);
4098 } else { /* OK (no trailing quote) */
4099 tvb_ensure_bytes_exist(tvb, start, offset - start);
4100 proto_tree_add_text(tree, tvb, start, offset - start,
4101 "%s: %s\"", str, val_str);
4102 s = g_strdup_printf("; %s=%s\"", str, val_str);
4104 } else { /* Token-text | 0x00 */
4105 /* TODO - verify that it is either Token-text or 0x00
4106 * and flag with warning if invalid */
4107 tvb_ensure_bytes_exist(tvb, start, offset - start);
4108 proto_tree_add_text(tree, tvb, start, offset - start,
4109 "%s: %s", str, val_str);
4110 s = g_strdup_printf("; %s=%s", str, val_str);
4112 /* TODO - check if we can insert a searchable field in the
4113 * protocol tree for the untyped parameter case */
4114 DebugLog(("parameter() - Untyped: %s\n", s));
4115 proto_item_append_string(ti, s);
4116 DebugLog(("Freeing s\n"));
4118 DebugLog(("Done!\n"));
4119 } else { /* Try integer value */
4120 DebugLog(("Trying integer parameter value.\n"));
4121 get_integer_value (val,tvb,offset,val_len,ok);
4122 if (ok) { /* Also found a valid integer parameter value: val */
4124 tvb_ensure_bytes_exist(tvb, start, offset - start);
4125 proto_tree_add_text(tree, tvb, start, offset - start,
4126 "%s: %u", str, val);
4127 s = g_strdup_printf("; %s=%u", str, val);
4128 proto_item_append_string(ti, s);
4129 DebugLog(("parameter() - Untyped: %s\n", s));
4131 /* TODO - check if we can insert a searchable field in the
4132 * protocol tree for the untyped parameter case */
4133 } else { /* Error: neither token-text not Integer-value */
4134 DebugLog(("Invalid untyped parameter value!\n"));
4135 tvb_ensure_bytes_exist(tvb, start, offset - start);
4136 proto_tree_add_text (tree, tvb, start, offset - start,
4137 "<Error: Invalid untyped parameter definition>");
4138 offset = start + len; /* Skip to end of buffer */
4142 DebugLog(("parameter() - Untyped - End\n"));
4146 * Else: Typed parameter
4148 DebugLog(("parameter() - Typed - Start\n"));
4149 get_integer_value (type,tvb,start,type_len,ok);
4151 tvb_ensure_bytes_exist(tvb, start, offset - start);
4152 proto_tree_add_text (tree, tvb, start, offset - start,
4153 "<Error: Invalid typed parameter definition>");
4154 return (start + len); /* Skip to end of buffer */
4157 /* Now offset points to the parameter value */
4158 DebugLog(("Typed parameter = 0x%02x\n", type));
4160 case 0x01: /* WSP 1.1 encoding - Charset: Well-known-charset */
4161 get_integer_value(val, tvb, offset, val_len, ok);
4163 val_str = val_to_str_ext(val, &vals_character_sets_ext,
4164 "<Unknown character set Identifier 0x%X>");
4165 proto_tree_add_string(tree, hf_parameter_charset,
4166 tvb, start, type_len + val_len, val_str);
4167 str = g_strdup_printf("; charset=%s", val_str);
4168 proto_item_append_string(ti, str);
4172 proto_tree_add_text (tree, tvb, start, offset,
4173 InvalidParameterValue("Charset", "Integer-value"));
4174 offset = start + len; /* Skip to end of buffer */
4178 case 0x03: /* WSP 1.1 encoding - Type: Integer-value */
4179 get_integer_value (val,tvb,offset,val_len,ok);
4181 proto_tree_add_uint (tree, hf_wsp_parameter_type,
4182 tvb, start, type_len + val_len, val);
4183 s = g_strdup_printf("; Type=%u", val);
4184 proto_item_append_string (ti, s);
4188 proto_tree_add_text (tree, tvb, start, offset,
4189 InvalidParameterValue("Type", "Integer-value"));
4190 offset = start + len; /* Skip to end of buffer */
4194 case 0x05: /* WSP 1.1 encoding - Name: Text-string */
4195 parameter_text(hf_wsp_parameter_name, "name",
4196 "Name (WSP 1.1 encoding)", "Text-string");
4198 case 0x17: /* WSP 1.4 encoding - Name: Text-value */
4199 parameter_text_value(hf_wsp_parameter_name, "name",
4200 "Name (WSP 1.4 encoding)", "Text-value");
4203 case 0x06: /* WSP 1.1 encoding - Filename: Text-string */
4204 parameter_text(hf_wsp_parameter_filename, "filename",
4205 "Filename (WSP 1.1 encoding)", "Text-string");
4207 case 0x18: /* WSP 1.4 encoding - Filename: Text-value */
4208 parameter_text_value(hf_wsp_parameter_filename, "filename",
4209 "Filename (WSP 1.4 encoding)", "Text-value");
4212 case 0x09: /* WSP 1.2 encoding - Type (special): Constrained-encoding */
4213 /* This is similar to the Content-Type header decoding,
4214 * but it is much simpler:
4215 * Constrained-encoding = Short-integer | Extension-media
4216 * Extension-media = *TEXT <Octet 0>
4218 get_extension_media(val_str,tvb,offset,val_len,ok);
4219 if (ok) { /* Extension-media */
4222 get_short_integer(val,tvb,offset,val_len,ok);
4225 val_str = val_to_str_ext(val, &vals_content_types_ext,
4226 "(Unknown content type identifier 0x%X)");
4227 } /* Else: invalid parameter value */
4230 tvb_ensure_bytes_exist(tvb, start, offset - start);
4231 proto_tree_add_string (tree, hf_wsp_parameter_upart_type,
4232 tvb, start, offset - start, val_str);
4233 str = g_strdup_printf("; type=%s", val_str);
4234 proto_item_append_string(ti, str);
4236 } else { /* Invalid parameter value */
4237 proto_tree_add_text (tree, tvb, start, len,
4238 InvalidParameterValue("Type",
4239 "Constrained-encoding"));
4240 offset = start + len; /* Skip the parameters */
4244 case 0x0A: /* WSP 1.2 encoding - Start: Text-string */
4245 parameter_text(hf_wsp_parameter_start, "start",
4246 "Start (WSP 1.2 encoding)", "Text-string");
4248 case 0x19: /* WSP 1.4 encoding - Start (with multipart/related): Text-value */
4249 parameter_text_value(hf_wsp_parameter_start, "start",
4250 "Start (WSP 1.4 encoding)", "Text-value");
4253 case 0x0B: /* WSP 1.2 encoding - Start-info: Text-string */
4254 parameter_text(hf_wsp_parameter_start_info, "start-info",
4255 "Start-info (WSP 1.2 encoding)", "Text-string");
4257 case 0x1A: /* WSP 1.4 encoding - Start-info (with multipart/related): Text-value */
4258 parameter_text_value(hf_wsp_parameter_start_info, "start-info",
4259 "Start-info (WSP 1.4 encoding)", "Text-value");
4262 case 0x0C: /* WSP 1.3 encoding - Comment: Text-string */
4263 parameter_text(hf_wsp_parameter_comment, "comment",
4264 "Comment (WSP 1.3 encoding)", "Text-string");
4266 case 0x1B: /* WSP 1.4 encoding - Comment: Text-value */
4267 parameter_text_value(hf_wsp_parameter_comment, "comment",
4268 "Comment (WSP 1.4 encoding)", "Text-value");
4271 case 0x0D: /* WSP 1.3 encoding - Domain: Text-string */
4272 parameter_text(hf_wsp_parameter_domain, "domain",
4273 "Domain (WSP 1.3 encoding)", "Text-string");
4275 case 0x1C: /* WSP 1.4 encoding - Domain: Text-value */
4276 parameter_text_value(hf_wsp_parameter_domain, "domain",
4277 "Domain (WSP 1.4 encoding)", "Text-value");
4280 case 0x0F: /* WSP 1.3 encoding - Path: Text-string */
4281 parameter_text(hf_wsp_parameter_path, "path",
4282 "Path (WSP 1.3 encoding)", "Text-string");
4284 case 0x1D: /* WSP 1.4 encoding - Path: Text-value */
4285 parameter_text_value(hf_wsp_parameter_path, "path",
4286 "Path (WSP 1.4 encoding)", "Text-value");
4289 case 0x11: /* WSP 1.4 encoding - SEC: Short-integer (OCTET) */
4290 peek = tvb_get_guint8 (tvb, start+1);
4291 if (peek & 0x80) { /* Valid Short-integer */
4293 proto_tree_add_uint (tree, hf_wsp_parameter_sec,
4294 tvb, start, 2, peek);
4295 str = (gchar *) val_to_str_ext_const(peek, &vals_wsp_parameter_sec_ext, "Undefined");
4296 s = g_strdup_printf("; SEC=%s", str);
4297 proto_item_append_string (ti, s);
4300 } else { /* Error */
4301 proto_tree_add_text (tree, tvb, start, len,
4302 InvalidParameterValue("SEC", "Short-integer"));
4303 offset = start + len; /* Skip to end of buffer */
4307 case 0x12: /* WSP 1.4 encoding - MAC: Text-value */
4308 parameter_text_value(hf_wsp_parameter_mac, "MAC",
4309 "MAC", "Text-value");
4312 case 0x02: /* WSP 1.1 encoding - Level: Version-value */
4313 get_version_value(val,str,tvb,offset,val_len,ok);
4315 proto_tree_add_string (tree, hf_wsp_parameter_level,
4316 tvb, start, type_len + val_len, str);
4317 s = g_strdup_printf("; level=%s", str);
4318 proto_item_append_string (ti, s);
4322 proto_tree_add_text (tree, tvb, start, len,
4323 InvalidParameterValue("Level", "Version-value"));
4324 offset = start + len; /* Skip to end of buffer */
4328 case 0x00: /* WSP 1.1 encoding - Q: Q-value */
4329 offset = parameter_value_q(tree, ti, tvb, offset);
4332 case 0x16: /* WSP 1.4 encoding - Size: Integer-value */
4333 get_integer_value (val,tvb,offset,val_len,ok);
4335 proto_tree_add_uint (tree, hf_wsp_parameter_size,
4336 tvb, start, type_len + val_len, val);
4337 s = g_strdup_printf("; Size=%u", val);
4338 proto_item_append_string (ti, s);
4342 proto_tree_add_text (tree, tvb, start, offset,
4343 InvalidParameterValue("Size", "Integer-value"));
4344 offset = start + len; /* Skip to end of buffer */
4352 case 0x07: /* WSP 1.1 encoding - Differences: Field-name */
4353 DebugLog(("Skipping remaining parameters from here\n"));
4354 tvb_ensure_bytes_exist(tvb, start, offset - start);
4355 proto_tree_add_text(tree, tvb, start, offset - start,
4356 "Undecoded parameter Differences - decoding stopped");
4359 case 0x08: /* WSP 1.1 encoding - Padding: Short-integer */
4360 DebugLog(("Skipping remaining parameters from here\n"));
4361 tvb_ensure_bytes_exist(tvb, start, offset - start);
4362 proto_tree_add_text(tree, tvb, start, offset - start,
4363 "Undecoded parameter Padding - decoding stopped");
4366 case 0x0E: /* WSP 1.3 encoding - Max-Age: Delta-seconds-value */
4367 DebugLog(("Skipping remaining parameters from here\n"));
4368 tvb_ensure_bytes_exist(tvb, start, offset - start);
4369 proto_tree_add_text(tree, tvb, start, offset - start,
4370 "Undecoded parameter Max-Age - decoding stopped");
4373 case 0x10: /* WSP 1.3 encoding - Secure: No-value */
4374 DebugLog(("Skipping remaining parameters from here\n"));
4375 tvb_ensure_bytes_exist(tvb, start, offset - start);
4376 proto_tree_add_text(tree, tvb, start, offset - start,
4377 "Undecoded parameter Secure - decoding stopped");
4380 case 0x13: /* WSP 1.4 encoding - Creation-date: Date-value */
4381 DebugLog(("Skipping remaining parameters from here\n"));
4382 tvb_ensure_bytes_exist(tvb, start, offset - start);
4383 proto_tree_add_text(tree, tvb, start, offset - start,
4384 "Undecoded parameter Creation-Date - decoding stopped");
4387 case 0x14: /* WSP 1.4 encoding - Modification-date: Date-value */
4388 DebugLog(("Skipping remaining parameters from here\n"));
4389 tvb_ensure_bytes_exist(tvb, start, offset - start);
4390 proto_tree_add_text(tree, tvb, start, offset - start,
4391 "Undecoded parameter Modification-Date - decoding stopped");
4394 case 0x15: /* WSP 1.4 encoding - Read-date: Date-value */
4395 DebugLog(("Skipping remaining parameters from here\n"));
4396 tvb_ensure_bytes_exist(tvb, start, offset - start);
4397 proto_tree_add_text(tree, tvb, start, offset - start,
4398 "Undecoded parameter Read-Date - decoding stopped");
4402 DebugLog(("Skipping remaining parameters from here\n"));
4403 tvb_ensure_bytes_exist(tvb, start, offset - start);
4404 proto_tree_add_text(tree, tvb, start, offset - start,
4405 "Undecoded parameter type 0x%02x - decoding stopped",
4407 offset = start + len; /* Skip the parameters */
4410 DebugLog(("parameter() - Typed - End\n"));
4416 * Dissects the Q-value parameter value.
4418 * Returns: next offset
4421 parameter_value_q (proto_tree *tree, proto_item *ti, tvbuff_t *tvb, int start)
4424 guint32 val = 0, val_len;
4425 gchar *str = NULL, *s = NULL;
4428 get_uintvar_integer (val, tvb, offset, val_len, ok);
4429 if (ok && (val < 1100)) {
4430 if (val <= 100) { /* Q-value in 0.01 steps */
4431 str = g_strdup_printf("0.%02u", val - 1);
4432 } else { /* Q-value in 0.001 steps */
4433 str = g_strdup_printf("0.%03u", val - 100);
4435 s = g_strdup_printf("; q=%s", str);
4436 proto_item_append_string (ti, s);
4438 proto_tree_add_string (tree, hf_parameter_q,
4439 tvb, start, val_len, str);
4443 proto_tree_add_text (tree, tvb, start, offset,
4444 InvalidParameterValue("Q", "Q-value"));
4451 /* Code to actually dissect the packets */
4457 /* Dissect a WSP redirect PDU.
4458 * Looks up or builds conversations, so parts of the code must always run,
4459 * even if tree is NULL.
4462 dissect_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo,
4463 proto_tree *tree, dissector_handle_t dissector_handle)
4467 proto_tree *addresses_tree = NULL;
4468 proto_tree *addr_tree = NULL;
4469 proto_tree *flags_tree;
4471 guint8 address_flags_len;
4473 proto_tree *address_flags_tree;
4475 guint32 address_ipv4;
4476 struct e_in6_addr address_ipv6;
4477 address redir_address;
4478 conversation_t *conv;
4479 guint32 idx = 0; /* Address index */
4480 guint32 address_record_len; /* Length of the entire address record */
4485 flags = tvb_get_guint8 (tvb, offset);
4487 ti = proto_tree_add_uint (tree, hf_wsp_redirect_flags,
4488 tvb, offset, 1, flags);
4489 flags_tree = proto_item_add_subtree (ti, ett_redirect_flags);
4490 proto_tree_add_boolean (flags_tree, hf_wsp_redirect_permanent,
4491 tvb, offset, 1, flags);
4492 proto_tree_add_boolean (flags_tree, hf_wsp_redirect_reuse_security_session,
4493 tvb, offset, 1, flags);
4498 * Redirect addresses.
4501 ti = proto_tree_add_item(tree, hf_redirect_addresses,
4502 tvb, 0, -1, ENC_NA);
4503 addresses_tree = proto_item_add_subtree(ti, ett_addresses);
4506 while (tvb_reported_length_remaining (tvb, offset) > 0) {
4509 * Read a single address at a time.
4511 address_flags_len = tvb_get_guint8 (tvb, offset);
4512 address_len = address_flags_len & ADDRESS_LEN;
4513 address_record_len = address_len
4514 + (address_flags_len & BEARER_TYPE_INCLUDED ? 1 : 0)
4515 + (address_flags_len & PORT_NUMBER_INCLUDED ? 2 : 0)
4519 ti = proto_tree_add_uint(addresses_tree, hf_address_entry,
4520 tvb, offset, 1 + address_record_len, idx);
4521 addr_tree = proto_item_add_subtree(ti, ett_address);
4523 ti = proto_tree_add_uint (addr_tree, hf_address_flags_length,
4524 tvb, offset, 1, address_flags_len);
4525 address_flags_tree = proto_item_add_subtree (ti, ett_address_flags);
4526 proto_tree_add_boolean (address_flags_tree, hf_address_flags_length_bearer_type_included,
4527 tvb, offset, 1, address_flags_len);
4528 proto_tree_add_boolean (address_flags_tree, hf_address_flags_length_port_number_included,
4529 tvb, offset, 1, address_flags_len);
4530 proto_tree_add_uint (address_flags_tree, hf_address_flags_length_address_len,
4531 tvb, offset, 1, address_flags_len);
4534 if (address_flags_len & BEARER_TYPE_INCLUDED) {
4535 bearer_type = tvb_get_guint8 (tvb, offset);
4537 proto_tree_add_uint (addr_tree, hf_address_bearer_type,
4538 tvb, offset, 1, bearer_type);
4542 bearer_type = 0x00; /* XXX */
4544 if (address_flags_len & PORT_NUMBER_INCLUDED) {
4545 port_num = tvb_get_ntohs (tvb, offset);
4547 proto_tree_add_uint (addr_tree, hf_address_port_num,
4548 tvb, offset, 2, port_num);
4553 * Redirecting to the same server port number as was
4554 * being used, i.e. the source port number of this
4557 port_num = pinfo->srcport;
4559 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
4561 * We don't have the bearer type in the message,
4562 * so we don't know the address type.
4563 * (It's the same bearer type as the original
4566 goto unknown_address_type;
4570 * We know the bearer type, so we know the address type.
4572 switch (bearer_type) {
4576 case BT_IS_95_PACKET_DATA:
4577 case BT_ANSI_136_CSD:
4578 case BT_ANSI_136_PACKET_DATA:
4581 case BT_GSM_USSD_IPv4:
4584 case BT_PDC_PACKET_DATA:
4586 case BT_IDEN_PACKET_DATA:
4588 case BT_TETRA_PACKET_DATA:
4592 if (address_len != 4) {
4596 goto unknown_address_type;
4598 address_ipv4 = tvb_get_ipv4(tvb, offset);
4600 proto_tree_add_ipv4 (addr_tree,
4601 hf_address_ipv4_addr,
4602 tvb, offset, 4, address_ipv4);
4606 * Create a conversation so that the
4607 * redirected session will be dissected
4610 redir_address.type = AT_IPv4;
4611 redir_address.len = 4;
4612 redir_address.data = (const guint8 *)&address_ipv4;
4613 /* Find a conversation based on redir_address and pinfo->dst */
4614 conv = find_conversation(pinfo->fd->num, &redir_address, &pinfo->dst,
4615 PT_UDP, port_num, 0, NO_PORT_B);
4616 if (conv == NULL) { /* This conversation does not exist yet */
4617 conv = conversation_new(pinfo->fd->num, &redir_address,
4618 &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
4620 /* Apply WSP dissection to the conversation */
4621 conversation_set_dissector(conv, dissector_handle);
4628 if (address_len != 16) {
4632 goto unknown_address_type;
4634 tvb_get_ipv6(tvb, offset, &address_ipv6);
4636 proto_tree_add_ipv6 (addr_tree,
4637 hf_address_ipv6_addr,
4638 tvb, offset, 16, (guint8 *)&address_ipv6);
4642 * Create a conversation so that the
4643 * redirected session will be dissected
4646 redir_address.type = AT_IPv6;
4647 redir_address.len = 16;
4648 redir_address.data = (const guint8 *)&address_ipv6;
4649 /* Find a conversation based on redir_address and pinfo->dst */
4650 conv = find_conversation(pinfo->fd->num, &redir_address, &pinfo->dst,
4651 PT_UDP, port_num, 0, NO_PORT_B);
4652 if (conv == NULL) { /* This conversation does not exist yet */
4653 conv = conversation_new(pinfo->fd->num, &redir_address,
4654 &pinfo->dst, PT_UDP, port_num, 0, NO_PORT2);
4656 /* Apply WSP dissection to the conversation */
4657 conversation_set_dissector(conv, dissector_handle);
4660 unknown_address_type:
4662 if (address_len != 0) {
4664 proto_tree_add_item (addr_tree, hf_address_addr,
4665 tvb, offset, address_len, ENC_NA);
4670 offset += address_len;
4674 /* Add addresses to the protocol tree.
4675 * This is a display-only function, so return if tree is NULL
4678 add_addresses(proto_tree *tree, tvbuff_t *tvb, int hf)
4681 proto_tree *addresses_tree;
4682 proto_tree *addr_tree;
4684 guint8 address_flags_len;
4686 proto_tree *address_flags_tree;
4688 guint32 address_ipv4;
4689 struct e_in6_addr address_ipv6;
4690 guint32 tvb_len = tvb_length(tvb);
4692 guint32 idx = 0; /* Address index */
4693 guint32 address_record_len; /* Length of the entire address record */
4695 /* Skip needless processing */
4698 if (offset >= tvb_len)
4704 /* XXX: the field pointed to by hf has a type of FT_NONE */
4705 ti = proto_tree_add_item(tree, hf, tvb, 0, -1, ENC_NA);
4706 addresses_tree = proto_item_add_subtree(ti, ett_addresses);
4708 while (offset < tvb_len) {
4711 * Read a single address at a time.
4713 address_flags_len = tvb_get_guint8 (tvb, offset);
4714 address_len = address_flags_len & ADDRESS_LEN;
4715 address_record_len = address_len
4716 + (address_flags_len & BEARER_TYPE_INCLUDED ? 1 : 0)
4717 + (address_flags_len & PORT_NUMBER_INCLUDED ? 2 : 0)
4720 ti = proto_tree_add_uint(addresses_tree, hf_address_entry,
4721 tvb, offset, 1 + address_record_len, idx);
4722 addr_tree = proto_item_add_subtree(ti, ett_address);
4724 ti = proto_tree_add_uint (addr_tree, hf_address_flags_length,
4725 tvb, offset, 1, address_flags_len);
4726 address_flags_tree = proto_item_add_subtree (ti, ett_address_flags);
4727 proto_tree_add_boolean (address_flags_tree, hf_address_flags_length_bearer_type_included,
4728 tvb, offset, 1, address_flags_len);
4729 proto_tree_add_boolean (address_flags_tree, hf_address_flags_length_port_number_included,
4730 tvb, offset, 1, address_flags_len);
4731 proto_tree_add_uint (address_flags_tree, hf_address_flags_length_address_len,
4732 tvb, offset, 1, address_flags_len);
4734 if (address_flags_len & BEARER_TYPE_INCLUDED) {
4735 bearer_type = tvb_get_guint8 (tvb, offset);
4736 proto_tree_add_uint (addr_tree, hf_address_bearer_type,
4737 tvb, offset, 1, bearer_type);
4740 bearer_type = 0x00; /* XXX */
4742 if (address_flags_len & PORT_NUMBER_INCLUDED) {
4743 port_num = tvb_get_ntohs (tvb, offset);
4744 proto_tree_add_uint (addr_tree, hf_address_port_num,
4745 tvb, offset, 2, port_num);
4749 * Redirecting to the same server port number as was
4750 * being used, i.e. the source port number of this
4755 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
4757 * We don't have the bearer type in the message,
4758 * so we don't know the address type.
4759 * (It's the same bearer type as the original
4762 goto unknown_address_type;
4766 * We know the bearer type, so we know the address type.
4768 switch (bearer_type) {
4772 case BT_IS_95_PACKET_DATA:
4773 case BT_ANSI_136_CSD:
4774 case BT_ANSI_136_PACKET_DATA:
4777 case BT_GSM_USSD_IPv4:
4780 case BT_PDC_PACKET_DATA:
4782 case BT_IDEN_PACKET_DATA:
4784 case BT_TETRA_PACKET_DATA:
4788 if (address_len != 4) {
4792 goto unknown_address_type;
4794 address_ipv4 = tvb_get_ipv4(tvb, offset);
4795 proto_tree_add_ipv4 (addr_tree, hf_address_ipv4_addr,
4796 tvb, offset, 4, address_ipv4);
4803 if (address_len != 16) {
4807 goto unknown_address_type;
4809 tvb_get_ipv6(tvb, offset, &address_ipv6);
4810 proto_tree_add_ipv6 (addr_tree, hf_address_ipv6_addr,
4811 tvb, offset, 16, (guint8 *)&address_ipv6);
4814 unknown_address_type:
4816 if (address_len != 0) {
4817 proto_tree_add_item (addr_tree, hf_address_addr,
4818 tvb, offset, address_len, ENC_NA);
4822 offset += address_len;
4826 static const value_string vals_sir_protocol_options[] = {
4827 { 0, "OTA-HTTP, no CPITag present" },
4828 { 1, "OTA-HTTP, CPITag present" },
4829 /* 2--255 are reserved */
4830 /* 256--16383 are available for private WINA registration */
4835 /* Dissect a Session Initiation Request.
4837 * Arguably this should be a separate dissector, but SIR does not make sense
4838 * outside of WSP anyway.
4841 dissect_sir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4845 guint32 val_len_save;
4850 proto_tree *subtree;
4853 if (check_col(pinfo->cinfo, COL_INFO))
4854 { /* Append status code to INFO column */
4855 col_append_str(pinfo->cinfo, COL_INFO,
4856 ": WAP Session Initiation Request");
4859 /* The remainder of the code adds items to the protocol tree */
4863 ti = proto_tree_add_item(tree, hf_sir_section,
4864 tvb, 0, -1, ENC_NA);
4865 subtree = proto_item_add_subtree(ti, ett_sir);
4868 version = tvb_get_guint8(tvb, 0);
4869 proto_tree_add_uint(subtree, hf_sir_version,
4870 tvb, 0, 1, version);
4872 /* Length of Application-Id headers list */
4873 val_len = tvb_get_guintvar(tvb, 1, &len);
4874 proto_tree_add_uint(subtree, hf_sir_app_id_list_len,
4875 tvb, 1, len, val_len);
4877 /* Application-Id headers */
4878 tmp_tvb = tvb_new_subset(tvb, offset, val_len, val_len);
4879 add_headers (subtree, tmp_tvb, hf_sir_app_id_list, pinfo);
4882 /* Length of WSP contact points list */
4883 val_len = tvb_get_guintvar(tvb, offset, &len);
4884 proto_tree_add_uint(subtree, hf_sir_wsp_contact_points_len,
4885 tvb, offset, len, val_len);
4887 /* WSP contact point list */
4888 tmp_tvb = tvb_new_subset (tvb, offset, val_len, val_len);
4889 add_addresses(subtree, tmp_tvb, hf_sir_wsp_contact_points);
4891 /* End of version 0 SIR content */
4897 /* Length of non-WSP contact points list */
4898 val_len = tvb_get_guintvar(tvb, offset, &len);
4899 proto_tree_add_uint(subtree, hf_sir_contact_points_len,
4900 tvb, offset, len, val_len);
4902 /* Non-WSP contact point list */
4903 tmp_tvb = tvb_new_subset (tvb, offset, val_len, val_len);
4904 add_addresses(subtree, tmp_tvb, hf_sir_contact_points);
4908 /* Number of entries in the Protocol Options list */
4909 val_len = tvb_get_guintvar(tvb, offset, &len);
4910 proto_tree_add_uint(subtree, hf_sir_protocol_options_len,
4911 tvb, offset, len, val_len);
4913 /* Protocol Options list.
4914 * Each protocol option is encoded as a guintvar */
4916 val_len_save = val_len;
4917 for (i = 0; i < val_len_save; i++) {
4918 val_len = tvb_get_guintvar(tvb, offset, &len);
4919 proto_tree_add_uint(subtree, hf_sir_protocol_options,
4920 tvb, offset, len, val_len);
4924 /* Length of ProvURL */
4925 val_len = tvb_get_guintvar(tvb, offset, &len);
4926 proto_tree_add_uint(subtree, hf_sir_prov_url_len,
4927 tvb, offset, len, val_len);
4930 tvb_ensure_bytes_exist(tvb, offset, val_len);
4931 ti = proto_tree_add_item (tree, hf_sir_prov_url,
4932 tvb, offset, val_len, ENC_ASCII|ENC_NA);
4935 /* Number of entries in the CPITag list */
4936 val_len = tvb_get_guintvar(tvb, offset, &len);
4937 proto_tree_add_uint(subtree, hf_sir_cpi_tag_len,
4938 tvb, offset, len, val_len);
4942 * Each CPITag is encoded as 4 octets of opaque data.
4943 * In OTA-HTTP, it is conveyed in the X-Wap-CPITag header
4944 * but with a Base64 encoding of the 4 bytes. */
4945 for (i = 0; i < val_len; i++) {
4946 proto_tree_add_item(subtree, hf_sir_cpi_tag,
4947 tvb, offset, 4, ENC_NA);
4953 dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4954 dissector_handle_t dissector_handle, gboolean is_connectionless)
4961 guint uriLength = 0;
4963 guint capabilityLength = 0;
4964 guint capabilityStart = 0;
4965 guint headersLength = 0;
4966 guint headerLength = 0;
4967 guint headerStart = 0;
4968 guint nextOffset = 0;
4969 guint contentTypeStart = 0;
4970 guint contentType = 0;
4971 const char *contentTypeStr;
4973 gboolean found_match;
4975 /* Set up structures we will need to add the protocol subtree and manage it */
4976 proto_item *proto_ti = NULL; /* for the proto entry */
4977 proto_tree *wsp_tree = NULL;
4979 wsp_info_value_t *stat_info;
4980 stat_info = (wsp_info_value_t *)ep_alloc(sizeof(wsp_info_value_t));
4981 stat_info->status_code = 0;
4983 /* This field shows up as the "Info" column in the display; you should make
4984 it, if possible, summarize what's in the packet, so that a user looking
4985 at the list of packets can tell what type of packet it is. */
4987 /* Connection-less mode has a TID first */
4988 if (is_connectionless)
4990 offset++; /* Skip the 1-byte Transaction ID */
4993 /* Find the PDU type */
4994 pdut = tvb_get_guint8 (tvb, offset);
4996 /* Develop the string to put in the Info column */
4997 if (check_col(pinfo->cinfo, COL_INFO))
4999 col_append_fstr(pinfo->cinfo, COL_INFO, "WSP %s (0x%02x)",
5000 val_to_str_ext (pdut, &wsp_vals_pdu_type_ext, "Unknown PDU type (0x%02x)"),
5004 /* In the interest of speed, if "tree" is NULL, don't do any work not
5005 * necessary to generate protocol tree items. */
5008 /* We use proto_item_append_string() in a number of places.
5009 * It does not work with the TRY_TO_FAKE_THIS_ITEM speed
5010 * optimization, so we have to disable that one and become
5011 * "slow" by pretending that the tree is "visible".
5013 * This code must be present for the MMSE dissector which
5014 * calls this function; otherwise, this causes a
5015 * dissector_assert [bug 492] (proto_item_append_string()
5016 * issue), and similar problems occur in other places.
5018 proto_tree_set_visible(tree, TRUE);
5020 proto_ti = proto_tree_add_item(tree, proto_wsp,
5021 tvb, 0, -1, ENC_NA);
5022 wsp_tree = proto_item_add_subtree(proto_ti, ett_wsp);
5023 proto_item_append_text(proto_ti, ", Method: %s (0x%02x)",
5024 val_to_str_ext (pdut, &wsp_vals_pdu_type_ext, "Unknown (0x%02x)"),
5027 /* Add common items: only TID and PDU Type */
5029 /* If this is connectionless, then the TID Field is always first */
5030 if (is_connectionless)
5032 proto_tree_add_item (wsp_tree, hf_wsp_header_tid,
5033 tvb, 0, 1, ENC_LITTLE_ENDIAN);
5035 proto_tree_add_item( wsp_tree, hf_wsp_header_pdu_type,
5036 tvb, offset, 1, ENC_LITTLE_ENDIAN);
5040 /* Map extended methods to the main method now the Column info has been
5041 * written; this way we can dissect the extended method PDUs. */
5042 if ((pdut >= 0x50) && (pdut <= 0x5F)) /* Extended GET --> GET */
5044 else if ((pdut >= 0x70) && (pdut <= 0x7F)) /* Extended POST --> POST */
5045 pdut = WSP_PDU_POST;
5049 case WSP_PDU_CONNECT:
5050 case WSP_PDU_CONNECTREPLY:
5051 case WSP_PDU_RESUME:
5053 if (pdut == WSP_PDU_CONNECT)
5055 proto_tree_add_item (wsp_tree, hf_wsp_version_major,
5056 tvb, offset, 1, ENC_LITTLE_ENDIAN);
5057 proto_tree_add_item (wsp_tree, hf_wsp_version_minor,
5058 tvb, offset, 1, ENC_LITTLE_ENDIAN);
5060 guint8 ver = tvb_get_guint8(tvb, offset);
5061 proto_item_append_text(proto_ti, ", Version: %u.%u",
5062 ver >> 4, ver & 0x0F);
5066 count = 0; /* Initialise count */
5067 value = tvb_get_guintvar (tvb, offset, &count);
5068 proto_tree_add_uint (wsp_tree,
5069 hf_wsp_server_session_id,
5070 tvb, offset, count, value);
5071 proto_item_append_text(proto_ti, ", Session ID: %u", value);
5074 capabilityStart = offset;
5075 count = 0; /* Initialise count */
5076 capabilityLength = tvb_get_guintvar (tvb, offset, &count);
5078 proto_tree_add_uint (wsp_tree, hf_capabilities_length,
5079 tvb, capabilityStart, count, capabilityLength);
5081 if (pdut != WSP_PDU_RESUME)
5083 count = 0; /* Initialise count */
5084 headerLength = tvb_get_guintvar (tvb, offset, &count);
5085 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
5086 tvb, offset, count, headerLength);
5088 capabilityStart = offset;
5089 headerStart = capabilityStart + capabilityLength;
5091 /* Resume computes the headerlength
5092 * by remaining bytes */
5093 capabilityStart = offset;
5094 headerStart = capabilityStart + capabilityLength;
5095 headerLength = tvb_reported_length_remaining (tvb,
5098 if (capabilityLength > 0)
5100 tmp_tvb = tvb_new_subset (tvb, offset,
5101 capabilityLength, capabilityLength);
5102 add_capabilities (wsp_tree, tmp_tvb, pdut);
5103 offset += capabilityLength;
5106 if (headerLength > 0)
5108 tmp_tvb = tvb_new_subset (tvb, offset,
5109 headerLength, headerLength);
5110 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
5116 case WSP_PDU_REDIRECT:
5117 dissect_redirect(tvb, offset, pinfo, wsp_tree, dissector_handle);
5120 case WSP_PDU_DISCONNECT:
5121 case WSP_PDU_SUSPEND:
5123 count = 0; /* Initialise count */
5124 value = tvb_get_guintvar (tvb, offset, &count);
5125 proto_tree_add_uint (wsp_tree,
5126 hf_wsp_server_session_id,
5127 tvb, offset, count, value);
5128 proto_item_append_text(proto_ti, ", Session ID: %u", value);
5133 case WSP_PDU_OPTIONS:
5135 case WSP_PDU_DELETE:
5137 count = 0; /* Initialise count */
5138 /* Length of URI and size of URILen field */
5139 value = tvb_get_guintvar (tvb, offset, &count);
5140 nextOffset = offset + count;
5141 add_uri (wsp_tree, pinfo, tvb, offset, nextOffset, proto_ti);
5143 offset += value + count; /* VERIFY */
5144 tmp_tvb = tvb_new_subset_remaining (tvb, offset);
5145 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
5152 count = 0; /* Initialise count */
5153 uriLength = tvb_get_guintvar (tvb, offset, &count);
5154 headerStart = uriStart+count;
5155 count = 0; /* Initialise count */
5156 headersLength = tvb_get_guintvar (tvb, headerStart, &count);
5157 offset = headerStart + count;
5159 add_uri (wsp_tree, pinfo, tvb, uriStart, offset, proto_ti);
5160 offset += uriLength;
5163 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
5164 tvb, headerStart, count, headersLength);
5166 /* Stop processing POST PDU if length of headers is zero;
5167 * this should not happen as we expect at least Content-Type. */
5168 if (headersLength == 0)
5171 contentTypeStart = offset;
5172 nextOffset = add_content_type (wsp_tree,
5173 tvb, offset, &contentType, &contentTypeStr);
5176 /* Add content type to protocol summary line */
5177 if (contentTypeStr) {
5178 proto_item_append_text(proto_ti, ", Content-Type: %s",
5181 proto_item_append_text(proto_ti, ", Content-Type: 0x%X",
5185 /* Add headers subtree that will hold the headers fields */
5186 /* Runs from nextOffset for
5187 * headersLength - (length of content-type field) */
5188 headerLength = headersLength - (nextOffset - contentTypeStart);
5189 if (headerLength > 0)
5191 tmp_tvb = tvb_new_subset (tvb, nextOffset,
5192 headerLength, headerLength);
5193 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
5195 /* XXX - offset is no longer used after this point */
5196 offset = nextOffset+headerLength;
5198 /* WSP_PDU_POST data - First check whether a subdissector exists
5199 * for the content type */
5200 if (tvb_reported_length_remaining(tvb,
5201 headerStart + count + uriLength + headersLength) > 0)
5203 tmp_tvb = tvb_new_subset_remaining (tvb,
5204 headerStart + count + uriLength + headersLength);
5206 * Try finding a dissector for the content
5207 * first, then fallback.
5209 found_match = FALSE;
5210 if (contentTypeStr) {
5212 * Content type is a string.
5214 found_match = dissector_try_string(media_type_table,
5215 contentTypeStr, tmp_tvb, pinfo, tree);
5217 if (! found_match) {
5218 if (! dissector_try_heuristic(heur_subdissector_list,
5219 tmp_tvb, pinfo, tree)) {
5220 guint8* save_private_data = pinfo->private_data;
5222 pinfo->match_string = contentTypeStr;
5223 pinfo->private_data = NULL; /* TODO: parameters */
5224 call_dissector(media_handle, tmp_tvb, pinfo, tree);
5225 pinfo->private_data = save_private_data;
5227 if (tree) /* Only display if needed */
5228 add_post_data (wsp_tree, tmp_tvb,
5229 contentType, contentTypeStr, pinfo);
5237 count = 0; /* Initialise count */
5238 headersLength = tvb_get_guintvar (tvb, offset+1, &count);
5239 headerStart = offset + count + 1;
5241 guint8 reply_status = tvb_get_guint8(tvb, offset);
5242 const char *reply_status_str;
5244 reply_status_str = val_to_str_ext_const (reply_status, &wsp_vals_status_ext, "(Unknown response status)");
5246 proto_tree_add_item (wsp_tree, hf_wsp_header_status,
5247 tvb, offset, 1, ENC_LITTLE_ENDIAN);
5248 proto_item_append_text(proto_ti, ", Status: %s (0x%02x)",
5249 reply_status_str, reply_status);
5251 stat_info->status_code = (gint) reply_status;
5252 if (check_col(pinfo->cinfo, COL_INFO))
5253 { /* Append status code to INFO column */
5254 col_append_fstr(pinfo->cinfo, COL_INFO,
5256 reply_status_str, reply_status);
5259 nextOffset = offset + 1 + count;
5261 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
5262 tvb, offset + 1, count, headersLength);
5264 if (headersLength == 0)
5267 contentTypeStart = nextOffset;
5268 nextOffset = add_content_type (wsp_tree, tvb,
5269 nextOffset, &contentType, &contentTypeStr);
5272 /* Add content type to protocol summary line */
5273 if (contentTypeStr) {
5274 proto_item_append_text(proto_ti, ", Content-Type: %s",
5277 proto_item_append_text(proto_ti, ", Content-Type: 0x%X",
5281 /* Add headers subtree that will hold the headers fields */
5282 /* Runs from nextOffset for
5283 * headersLength - (length of Content-Type field) */
5284 headerLength = headersLength - (nextOffset - contentTypeStart);
5285 if (headerLength > 0)
5287 tmp_tvb = tvb_new_subset (tvb, nextOffset,
5288 headerLength, headerLength);
5289 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
5291 /* XXX - offset is no longer used after this point */
5292 offset += count+headersLength+1;
5294 /* WSP_PDU_REPLY data - First check whether a subdissector exists
5295 * for the content type */
5296 if (tvb_reported_length_remaining(tvb, headerStart + headersLength)
5299 tmp_tvb = tvb_new_subset_remaining (tvb, headerStart + headersLength);
5301 * Try finding a dissector for the content
5302 * first, then fallback.
5304 found_match = FALSE;
5305 if (contentTypeStr) {
5307 * Content type is a string.
5309 found_match = dissector_try_string(media_type_table,
5310 contentTypeStr, tmp_tvb, pinfo, tree);
5312 if (! found_match) {
5313 if (! dissector_try_heuristic(heur_subdissector_list,
5314 tmp_tvb, pinfo, tree)) {
5315 guint8* save_private_data = pinfo->private_data;
5317 pinfo->match_string = contentTypeStr;
5318 pinfo->private_data = NULL; /* TODO: parameters */
5319 call_dissector(media_handle, tmp_tvb, pinfo, tree);
5320 pinfo->private_data = save_private_data;
5322 if (tree) / * Only display if needed * /
5323 proto_tree_add_item (wsp_tree,
5325 tmp_tvb, 0, -1, ENC_NA);
5333 case WSP_PDU_CONFIRMEDPUSH:
5334 count = 0; /* Initialise count */
5335 headersLength = tvb_get_guintvar (tvb, offset, &count);
5336 headerStart = offset + count;
5339 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
5340 tvb, offset, count, headersLength);
5342 if (headersLength == 0)
5346 contentTypeStart = offset;
5347 nextOffset = add_content_type (wsp_tree,
5348 tvb, offset, &contentType, &contentTypeStr);
5351 /* Add content type to protocol summary line */
5352 if (contentTypeStr) {
5353 proto_item_append_text(proto_ti, ", Content-Type: %s",
5356 proto_item_append_text(proto_ti, ", Content-Type: 0x%X",
5360 /* Add headers subtree that will hold the headers fields */
5361 /* Runs from nextOffset for
5362 * headersLength-(length of Content-Type field) */
5363 headerLength = headersLength-(nextOffset-contentTypeStart);
5364 if (headerLength > 0)
5366 tmp_tvb = tvb_new_subset (tvb, nextOffset,
5367 headerLength, headerLength);
5368 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
5370 /* XXX - offset is no longer used after this point */
5371 offset += headersLength;
5373 /* WSP_PDU_PUSH data - First check whether a subdissector exists
5374 * for the content type */
5375 if (tvb_reported_length_remaining(tvb, headerStart + headersLength)
5378 tmp_tvb = tvb_new_subset_remaining (tvb, headerStart + headersLength);
5380 * Try finding a dissector for the content
5381 * first, then fallback.
5383 found_match = FALSE;
5384 if (contentTypeStr) {
5386 * Content type is a string.
5389 if (g_ascii_strcasecmp(contentTypeStr, "application/vnd.wap.sia") == 0) {
5390 dissect_sir(tree, tmp_tvb);
5393 found_match = dissector_try_string(media_type_table,
5394 contentTypeStr, tmp_tvb, pinfo, tree);
5396 if (! found_match) {
5397 if (! dissector_try_heuristic(heur_subdissector_list,
5398 tmp_tvb, pinfo, tree)) {
5399 guint8* save_private_data = pinfo->private_data;
5401 pinfo->match_string = contentTypeStr;
5402 pinfo->private_data = NULL; /* TODO: parameters */
5403 call_dissector(media_handle, tmp_tvb, pinfo, tree);
5404 pinfo->private_data = save_private_data;
5406 if (tree) /* Only display if needed */
5407 proto_tree_add_item (wsp_tree,
5409 tmp_tvb, 0, -1, ENC_NA);
5417 stat_info->pdut = pdut;
5418 tap_queue_packet (wsp_tap, pinfo, stat_info);
5423 * Called directly from UDP.
5424 * Put "WSP" into the "Protocol" column.
5427 dissect_wsp_fromudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5429 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSP");
5430 col_clear(pinfo->cinfo, COL_INFO);
5432 dissect_wsp_common(tvb, pinfo, tree, wsp_fromudp_handle, TRUE);
5437 * Called from a higher-level WAP dissector, in connection-oriented mode.
5438 * Leave the "Protocol" column alone - the dissector calling us should
5442 dissect_wsp_fromwap_co(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5445 * XXX - what about WTLS->WTP->WSP?
5447 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, FALSE);
5452 * Called from a higher-level WAP dissector, in connectionless mode.
5453 * Leave the "Protocol" column alone - the dissector calling us should
5457 dissect_wsp_fromwap_cl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5460 * XXX - what about WTLS->WSP?
5462 col_clear(pinfo->cinfo, COL_INFO);
5463 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, TRUE);
5468 add_uri (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
5469 guint URILenOffset, guint URIOffset, proto_item *proto_ti)
5472 guint uriLen = tvb_get_guintvar (tvb, URILenOffset, &count);
5476 proto_tree_add_uint (tree, hf_wsp_header_uri_len,
5477 tvb, URILenOffset, count, uriLen);
5479 tvb_ensure_bytes_exist(tvb, URIOffset, uriLen);
5481 proto_tree_add_item (tree, hf_wsp_header_uri,
5482 tvb, URIOffset, uriLen, ENC_ASCII|ENC_NA);
5484 str = tvb_format_text (tvb, URIOffset, uriLen);
5485 /* XXX - tvb_format_text() returns a pointer to a static text string
5486 * so please DO NOT attempt at g_free()ing it!
5488 if (check_col(pinfo->cinfo, COL_INFO)) {
5489 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", str);
5492 proto_item_append_text(proto_ti, ", URI: %s", str);
5497 * CO-WSP capability negotiation
5501 WSP_CAPA_CLIENT_SDU_SIZE = 0x00,
5502 WSP_CAPA_SERVER_SDU_SIZE,
5503 WSP_CAPA_PROTOCOL_OPTIONS,
5504 WSP_CAPA_METHOD_MOR,
5506 WSP_CAPA_EXTENDED_METHODS,
5507 WSP_CAPA_HEADER_CODE_PAGES,
5509 WSP_CAPA_CLIENT_MESSAGE_SIZE,
5510 WSP_CAPA_SERVER_MESSAGE_SIZE
5514 add_capabilities (proto_tree *tree, tvbuff_t *tvb, guint8 pdu_type)
5516 proto_tree *wsp_capabilities;
5517 proto_tree *capa_subtree;
5519 char *capaName, *str, *valStr;
5522 guint32 capaStart = 0; /* Start offset of the capability */
5523 guint32 capaLen = 0; /* Length of the entire capability */
5524 guint32 capaValueLen = 0; /* Length of the capability value & type */
5525 guint32 tvb_len = tvb_reported_length(tvb);
5526 gboolean ok = FALSE;
5531 DebugLog(("add_capabilities(): Capabilities = 0\n"));
5535 DebugLog(("add_capabilities(): capabilities to process\n"));
5537 ti = proto_tree_add_item(tree, hf_capabilities_section,
5538 tvb, 0, tvb_len, ENC_NA);
5539 wsp_capabilities = proto_item_add_subtree(ti, ett_capabilities);
5541 while (offset < tvb_len) {
5543 * WSP capabilities consist of:
5544 * - a guint32 length field,
5545 * - a capability identifier as Token-text or Short-integer,
5546 * - a capability-specific sequence of <length> octets.
5550 * Now Offset points to the 1st byte of a capability field.
5551 * Get the length of the capability field
5553 capaValueLen = tvb_get_guintvar(tvb, offset, &len);
5554 capaLen = capaValueLen + len;
5555 tvb_ensure_bytes_exist(tvb, offset, capaLen);
5558 * Now offset points to the 1st byte of the capability type.
5559 * Get the capability identifier.
5561 peek = tvb_get_guint8(tvb, offset);
5562 if (is_token_text(peek)) { /* Literal capability name */
5563 /* 1. Get the string from the tvb */
5564 get_token_text(capaName, tvb, offset, len, ok);
5566 DebugLog(("add_capabilities(): expecting capability name as token_text "
5567 "at offset %u (1st char = 0x%02x)\n", offset, peek));
5570 /* 2. Look up the string capability name */
5571 if (g_ascii_strcasecmp(capaName, "client-sdu-size") == 0) {
5572 peek = WSP_CAPA_CLIENT_SDU_SIZE;
5573 } else if (g_ascii_strcasecmp(capaName, "server-sdu-size") == 0) {
5574 peek = WSP_CAPA_SERVER_SDU_SIZE;
5575 } else if (g_ascii_strcasecmp(capaName, "protocol options") == 0) {
5576 peek = WSP_CAPA_PROTOCOL_OPTIONS;
5577 } else if (g_ascii_strcasecmp(capaName, "method-mor") == 0) {
5578 peek = WSP_CAPA_METHOD_MOR;
5579 } else if (g_ascii_strcasecmp(capaName, "push-mor") == 0) {
5580 peek = WSP_CAPA_PUSH_MOR;
5581 } else if (g_ascii_strcasecmp(capaName, "extended methods") == 0) {
5582 peek = WSP_CAPA_EXTENDED_METHODS;
5583 } else if (g_ascii_strcasecmp(capaName, "header code pages") == 0) {
5584 peek = WSP_CAPA_HEADER_CODE_PAGES;
5585 } else if (g_ascii_strcasecmp(capaName, "aliases") == 0) {
5586 peek = WSP_CAPA_ALIASES;
5587 } else if (g_ascii_strcasecmp(capaName, "client-message-size") == 0) {
5588 peek = WSP_CAPA_CLIENT_MESSAGE_SIZE;
5589 } else if (g_ascii_strcasecmp(capaName, "server-message-size") == 0) {
5590 peek = WSP_CAPA_SERVER_MESSAGE_SIZE;
5592 DebugLog(("add_capabilities(): unknown capability '%s' at offset %u\n",
5594 proto_tree_add_text(wsp_capabilities, tvb, capaStart, capaLen,
5595 "Unknown or invalid textual capability: %s", capaName);
5596 /* Skip this capability */
5597 offset = capaStart + capaLen;
5601 /* Now offset points to the 1st value byte of the capability. */
5602 } else if (peek < 0x80) {
5603 DebugLog(("add_capabilities(): invalid capability type identifier 0x%02X at offset %u.",
5605 proto_tree_add_text(wsp_capabilities, tvb, capaStart, capaLen,
5606 "Invalid well-known capability: 0x%02X", peek);
5607 /* Skip further capability parsing */
5610 if (peek & 0x80) { /* Well-known capability */
5614 /* Now offset points to the 1st value byte of the capability. */
5616 /* Now the capability type is known */
5618 case WSP_CAPA_CLIENT_SDU_SIZE:
5619 value = tvb_get_guintvar(tvb, offset, &len);
5620 DebugLog(("add_capabilities(client-sdu-size): "
5621 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5622 value, value, offset, tvb_get_guint8(tvb, offset), len));
5623 proto_tree_add_uint(wsp_capabilities, hf_capa_client_sdu_size,
5624 tvb, capaStart, capaLen, value);
5626 case WSP_CAPA_SERVER_SDU_SIZE:
5627 value = tvb_get_guintvar(tvb, offset, &len);
5628 DebugLog(("add_capabilities(server-sdu-size): "
5629 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5630 value, value, offset, tvb_get_guint8(tvb, offset), len));
5631 proto_tree_add_uint(wsp_capabilities, hf_capa_server_sdu_size,
5632 tvb, capaStart, capaLen, value);
5634 case WSP_CAPA_PROTOCOL_OPTIONS:
5635 ti = proto_tree_add_string(wsp_capabilities, hf_capa_protocol_options,
5636 tvb, capaStart, capaLen, "");
5637 capa_subtree = proto_item_add_subtree(ti, ett_capability);
5639 * The bits are stored in one or more octets, not an
5640 * uintvar-integer! Note that capability name and value
5641 * have length capaValueLength, and that the capability
5642 * name has length = len. Hence the remaining length is
5643 * given by capaValueLen - len.
5645 switch (capaValueLen - len) {
5647 value = tvb_get_guint8(tvb, offset);
5652 * The WSP spec foresees that this bit field can be
5653 * extended in the future. This does not make sense yet.
5655 DebugLog(("add_capabilities(protocol options): "
5656 "bit field too large (%u bytes)\n",
5658 proto_item_append_text(ti,
5659 " <warning: bit field too large>");
5660 offset = capaStart + capaLen;
5663 DebugLog(("add_capabilities(protocol options): "
5664 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5665 value, value, offset, tvb_get_guint8(tvb, offset), len));
5667 proto_item_append_string(ti, " (confirmed push facility)");
5669 proto_item_append_string(ti, " (push facility)");
5671 proto_item_append_string(ti, " (session resume facility)");
5673 proto_item_append_string(ti, " (acknowledgement headers)");
5675 proto_item_append_string(ti, " (large data transfer)");
5676 if (value & 0xFFFFFF07)
5677 proto_item_append_text(ti, " <warning: reserved bits have been set>");
5678 proto_tree_add_boolean(capa_subtree,
5679 hf_capa_protocol_option_confirmed_push,
5680 tvb, offset, len, value);
5681 proto_tree_add_boolean(capa_subtree,
5682 hf_capa_protocol_option_push,
5683 tvb, offset, len, value);
5684 proto_tree_add_boolean(capa_subtree,
5685 hf_capa_protocol_option_session_resume,
5686 tvb, offset, len, value);
5687 proto_tree_add_boolean(capa_subtree,
5688 hf_capa_protocol_option_ack_headers,
5689 tvb, offset, len, value);
5690 proto_tree_add_boolean(capa_subtree,
5691 hf_capa_protocol_option_large_data_transfer,
5692 tvb, offset, len, value);
5694 case WSP_CAPA_METHOD_MOR:
5695 value = tvb_get_guint8(tvb, offset);
5696 proto_tree_add_uint (wsp_capabilities,
5698 tvb, capaStart, capaLen, value);
5700 case WSP_CAPA_PUSH_MOR:
5701 value = tvb_get_guint8(tvb, offset);
5702 proto_tree_add_uint (wsp_capabilities,
5704 tvb, capaStart, capaLen, value);
5706 case WSP_CAPA_EXTENDED_METHODS:
5707 /* Extended Methods capability format:
5708 * Connect PDU: collection of { Method (octet), Method-name (Token-text) }
5709 * ConnectReply PDU: collection of accepted { Method (octet) }
5711 ti = proto_tree_add_string(wsp_capabilities,
5712 hf_capa_extended_methods,
5713 tvb, capaStart, capaLen, "");
5714 if (pdu_type == WSP_PDU_CONNECT) {
5715 while (offset < capaStart + capaLen) {
5716 peek = tvb_get_guint8(tvb, offset++);
5717 get_text_string(str, tvb, offset, len, ok);
5719 proto_item_append_text(ti, " <error: invalid capability encoding>");
5720 DebugLog(("add_capability(extended methods): "
5721 "invalid method name at offset %u "
5722 "(octet = 0x%02X)\n",
5723 offset, tvb_get_guint8(tvb, offset)));
5726 valStr = g_strdup_printf(" (0x%02x = %s)", peek, str);
5727 DebugLog(("add_capabilities(extended methods):%s\n",
5729 proto_item_append_string(ti, valStr);
5734 while (offset < capaStart + capaLen) {
5735 peek = tvb_get_guint8(tvb, offset++);
5736 valStr = g_strdup_printf(" (0x%02x)", peek);
5737 DebugLog(("add_capabilities(extended methods):%s\n",
5739 proto_item_append_string(ti, valStr);
5744 case WSP_CAPA_HEADER_CODE_PAGES:
5745 /* Header Code Pages capability format:
5746 * Connect PDU: collection of { Page-id (octet), Page-name (Token-text) }
5747 * ConnectReply PDU: collection of accepted { Page-id (octet) }
5749 ti = proto_tree_add_string(wsp_capabilities,
5750 hf_capa_header_code_pages,
5751 tvb, capaStart, capaLen, "");
5752 if (pdu_type == WSP_PDU_CONNECT) {
5753 while (offset < capaStart + capaLen) {
5754 peek = tvb_get_guint8(tvb, offset++);
5755 get_text_string(str, tvb, offset, len, ok);
5757 proto_item_append_text(ti,
5758 " <error: invalid capability encoding>");
5759 DebugLog(("add_capability(header code pages): "
5760 "invalid header code page name at offset %u "
5761 "(octet = 0x%02X)\n",
5762 offset, tvb_get_guint8(tvb, offset)));
5765 valStr = g_strdup_printf(" (0x%02x = %s)", peek, str);
5766 DebugLog(("add_capabilities(header code pages):%s\n",
5768 proto_item_append_string(ti, valStr);
5773 while (offset < capaStart + capaLen) {
5774 peek = tvb_get_guint8(tvb, offset++);
5775 valStr = g_strdup_printf(" (0x%02x)", peek);
5776 DebugLog(("add_capabilities(header code pages):%s\n",
5778 proto_item_append_string(ti, valStr);
5783 case WSP_CAPA_ALIASES:
5784 /* TODO - same format as redirect addresses */
5785 proto_tree_add_item(wsp_capabilities, hf_capa_aliases,
5786 tvb, capaStart, capaLen, ENC_NA);
5788 case WSP_CAPA_CLIENT_MESSAGE_SIZE:
5789 value = tvb_get_guintvar(tvb, offset, &len);
5790 DebugLog(("add_capabilities(client-message-size): "
5791 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5792 value, value, offset, tvb_get_guint8(tvb, offset), len));
5793 proto_tree_add_uint(wsp_capabilities, hf_capa_client_message_size,
5794 tvb, capaStart, capaLen, value);
5796 case WSP_CAPA_SERVER_MESSAGE_SIZE:
5797 value = tvb_get_guintvar(tvb, offset, &len);
5798 DebugLog(("add_capabilities(server-message-size): "
5799 "guintvar = %u (0x%X) at offset %u (1st byte = 0x%02X) (len = %u)\n",
5800 value, value, offset, tvb_get_guint8(tvb, offset), len));
5801 proto_tree_add_uint(wsp_capabilities, hf_capa_server_message_size,
5802 tvb, capaStart, capaLen, value);
5805 proto_tree_add_text(wsp_capabilities, tvb, capaStart, capaLen,
5806 "Unknown well-known capability: 0x%02X", peek);
5809 offset = capaStart + capaLen;
5814 add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType,
5815 const char *contentTypeStr, packet_info *pinfo)
5818 guint variableStart = 0;
5819 guint variableEnd = 0;
5820 guint valueStart = 0;
5823 proto_tree *sub_tree = NULL;
5825 DebugLog(("add_post_data() - START\n"));
5827 /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,ENC_NA); */
5829 ti = proto_tree_add_item (tree, hf_wsp_post_data,
5830 tvb, offset, -1, ENC_NA);
5831 sub_tree = proto_item_add_subtree(ti, ett_post);
5834 if ( (contentTypeStr == NULL && contentType == 0x12)
5835 || (contentTypeStr && (g_ascii_strcasecmp(contentTypeStr,
5836 "application/x-www-form-urlencoded") == 0)) )
5841 * Iterate through post data.
5843 for (offset = 0; offset < tvb_reported_length (tvb); offset++)
5845 peek = tvb_get_guint8 (tvb, offset);
5848 variableEnd = offset;
5849 valueStart = offset+1;
5851 else if (peek == '&')
5853 if (variableEnd > 0)
5855 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5857 variableStart = offset+1;
5863 /* See if there's outstanding data */
5864 if (variableEnd > 0)
5866 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5870 else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x24) ||
5871 (contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33))
5873 /* add_multipart_data takes also care of subdissection */
5874 add_multipart_data(sub_tree, tvb, pinfo);
5876 DebugLog(("add_post_data() - END\n"));
5880 add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint variableEnd, guint valueStart, guint valueEnd)
5882 int variableLength = variableEnd-variableStart;
5883 int valueLength = 0;
5884 char *variableBuffer;
5887 variableBuffer = tvb_get_ephemeral_string(tvb, variableStart, variableLength);
5889 if (valueEnd < valueStart)
5891 valueBuffer = g_malloc (1);
5893 valueEnd = valueStart;
5897 valueLength = valueEnd-valueStart;
5898 /* XXX - if this throws an exception, "variableBuffer"
5900 valueBuffer = tvb_get_ephemeral_string(tvb, valueStart, valueLength);
5903 /* Check for variables with no value */
5904 if (valueStart >= tvb_reported_length (tvb))
5906 valueStart = tvb_reported_length (tvb);
5907 valueEnd = valueStart;
5909 valueLength = valueEnd-valueStart;
5911 proto_tree_add_text (tree, tvb, variableStart, valueEnd-variableStart, "%s: %s", variableBuffer, valueBuffer);
5916 add_multipart_data (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo)
5924 guint contentType = 0;
5925 const char *contentTypeStr;
5929 gboolean found_match = FALSE;
5931 proto_item *sub_tree = NULL;
5932 proto_item *ti = NULL;
5933 proto_tree *mpart_tree = NULL;
5935 DebugLog(("add_multipart_data(): offset = %u, byte = 0x%02x: ",
5936 offset, tvb_get_guint8(tvb,offset)));
5937 nEntries = tvb_get_guintvar (tvb, offset, &count);
5938 DebugLog(("parts = %u\n", nEntries));
5942 ti = proto_tree_add_text(tree, tvb, offset - count, 0,
5944 sub_tree = proto_item_add_subtree(ti, ett_mpartlist);
5948 DebugLog(("add_multipart_data(): Parts to do after this: %u"
5949 " (offset = %u, 0x%02x): ",
5950 nEntries, offset, tvb_get_guint8(tvb,offset)));
5951 part_start = offset;
5952 HeadersLen = tvb_get_guintvar (tvb, offset, &count);
5954 DataLen = tvb_get_guintvar (tvb, offset, &count);
5957 tvb_ensure_bytes_exist(tvb, part_start, HeadersLen + DataLen + (offset - part_start));
5958 ti = proto_tree_add_uint(sub_tree, hf_wsp_mpart, tvb, part_start,
5959 HeadersLen + DataLen + (offset - part_start), partnr);
5960 mpart_tree = proto_item_add_subtree(ti, ett_multiparts);
5962 nextOffset = add_content_type (mpart_tree, tvb, offset,
5963 &contentType, &contentTypeStr);
5966 /* Add content type to protocol summary line */
5967 if (contentTypeStr) {
5968 proto_item_append_text(ti, ", content-type: %s",
5971 proto_item_append_text(ti, ", content-type: 0x%X",
5976 HeadersLen -= (nextOffset - offset);
5979 tmp_tvb = tvb_new_subset (tvb, nextOffset, HeadersLen, HeadersLen);
5980 add_headers (mpart_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
5982 offset = nextOffset + HeadersLen;
5984 * Try the dissectors of the multipart content.
5986 * TODO - handle nested multipart documents.
5988 tmp_tvb = tvb_new_subset(tvb, offset, DataLen, DataLen);
5990 * Try finding a dissector for the content
5991 * first, then fallback.
5993 found_match = FALSE;
5994 if (contentTypeStr) {
5996 * Content type is a string.
5998 found_match = dissector_try_string(media_type_table,
5999 contentTypeStr, tmp_tvb, pinfo, mpart_tree);
6001 if (! found_match) {
6002 if (! dissector_try_heuristic(heur_subdissector_list,
6003 tmp_tvb, pinfo, mpart_tree)) {
6004 guint8* save_private_data = pinfo->private_data;
6006 pinfo->match_string = contentTypeStr;
6007 pinfo->private_data = NULL; /* TODO: parameters */
6008 call_dissector(media_handle, tmp_tvb, pinfo, mpart_tree);
6009 pinfo->private_data = save_private_data;
6011 if (tree) /* Only display if needed */
6012 proto_tree_add_item (mpart_tree, hf_wsp_multipart_data,
6013 tvb, offset, DataLen, ENC_NA);
6024 /* Register the protocol with Wireshark */
6026 proto_register_wsp(void)
6029 /* Setup list of header fields */
6030 static hf_register_info hf[] = {
6031 { &hf_wsp_header_tid,
6034 FT_UINT8, BASE_HEX, NULL, 0x00,
6035 "WSP Transaction ID (for connectionless WSP)", HFILL
6038 { &hf_wsp_header_pdu_type,
6041 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &wsp_vals_pdu_type_ext, 0x00,
6045 { &hf_wsp_version_major,
6046 { "Version (Major)",
6047 "wsp.version.major",
6048 FT_UINT8, BASE_DEC, NULL, 0xF0,
6052 { &hf_wsp_version_minor,
6053 { "Version (Minor)",
6054 "wsp.version.minor",
6055 FT_UINT8, BASE_DEC, NULL, 0x0F,
6059 { &hf_capabilities_length,
6060 { "Capabilities Length",
6061 "wsp.capabilities.length",
6062 FT_UINT32, BASE_DEC, NULL, 0x00,
6063 "Length of Capabilities field (bytes)", HFILL
6066 { &hf_wsp_header_length,
6068 "wsp.headers_length",
6069 FT_UINT32, BASE_DEC, NULL, 0x00,
6070 "Length of Headers field (bytes)", HFILL
6073 { &hf_capabilities_section,
6076 FT_NONE, BASE_NONE, NULL, 0x00,
6080 { &hf_wsp_headers_section,
6083 FT_NONE, BASE_NONE, NULL, 0x00,
6087 { &hf_wsp_header_uri_len,
6090 FT_UINT32, BASE_DEC, NULL, 0x00,
6091 "Length of URI field", HFILL
6094 { &hf_wsp_header_uri,
6097 FT_STRING, BASE_NONE, NULL, 0x00,
6101 { &hf_wsp_server_session_id,
6102 { "Server Session ID",
6103 "wsp.server.session_id",
6104 FT_UINT32, BASE_DEC, NULL, 0x00,
6108 { &hf_wsp_header_status,
6111 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &wsp_vals_status_ext, 0x00,
6112 "Reply Status", HFILL
6115 { &hf_wsp_parameter_type,
6117 "wsp.parameter.type",
6118 FT_UINT32, BASE_DEC, NULL, 0x00,
6119 "Type parameter", HFILL
6122 { &hf_wsp_parameter_name,
6124 "wsp.parameter.name",
6125 FT_STRING, BASE_NONE, NULL, 0x00,
6126 "Name parameter", HFILL
6129 { &hf_wsp_parameter_filename,
6131 "wsp.parameter.filename",
6132 FT_STRING, BASE_NONE, NULL, 0x00,
6133 "Filename parameter", HFILL
6136 { &hf_wsp_parameter_start,
6138 "wsp.parameter.start",
6139 FT_STRING, BASE_NONE, NULL, 0x00,
6140 "Start parameter", HFILL
6143 { &hf_wsp_parameter_start_info,
6145 "wsp.parameter.start_info",
6146 FT_STRING, BASE_NONE, NULL, 0x00,
6147 "Start-info parameter", HFILL
6150 { &hf_wsp_parameter_comment,
6152 "wsp.parameter.comment",
6153 FT_STRING, BASE_NONE, NULL, 0x00,
6154 "Comment parameter", HFILL
6157 { &hf_wsp_parameter_domain,
6159 "wsp.parameter.domain",
6160 FT_STRING, BASE_NONE, NULL, 0x00,
6161 "Domain parameter", HFILL
6164 { &hf_wsp_parameter_path,
6166 "wsp.parameter.path",
6167 FT_STRING, BASE_NONE, NULL, 0x00,
6168 "Path parameter", HFILL
6171 { &hf_wsp_parameter_sec,
6173 "wsp.parameter.sec",
6174 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_wsp_parameter_sec_ext, 0x00,
6175 "SEC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
6178 { &hf_wsp_parameter_mac,
6180 "wsp.parameter.mac",
6181 FT_STRING, BASE_NONE, NULL, 0x00,
6182 "MAC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
6185 { &hf_wsp_parameter_upart_type,
6187 "wsp.parameter.upart.type",
6188 FT_STRING, BASE_NONE, NULL, 0x00,
6189 "Multipart type parameter", HFILL
6192 { &hf_wsp_parameter_level,
6194 "wsp.parameter.level",
6195 FT_STRING, BASE_NONE, NULL, 0x00,
6196 "Level parameter", HFILL
6199 { &hf_wsp_parameter_size,
6201 "wsp.parameter.size",
6202 FT_UINT32, BASE_DEC, NULL, 0x00,
6203 "Size parameter", HFILL
6207 { &hf_wsp_reply_data,
6210 FT_NONE, BASE_NONE, NULL, 0x00,
6215 { &hf_wsp_header_shift_code,
6216 { "Switching to WSP header code-page",
6218 FT_UINT8, BASE_DEC, NULL, 0x00,
6219 "Header code-page shift code", HFILL
6223 * CO-WSP capability negotiation
6225 { &hf_capa_client_sdu_size,
6226 { "Client SDU Size",
6227 "wsp.capability.client_sdu_size",
6228 FT_UINT8, BASE_DEC, NULL, 0x00,
6229 "Client Service Data Unit size (bytes)", HFILL
6232 { &hf_capa_server_sdu_size,
6233 { "Server SDU Size",
6234 "wsp.capability.server_sdu_size",
6235 FT_UINT8, BASE_DEC, NULL, 0x00,
6236 "Server Service Data Unit size (bytes)", HFILL
6239 { &hf_capa_protocol_options,
6240 { "Protocol Options",
6241 "wsp.capability.protocol_opt",
6242 FT_STRING, BASE_NONE, NULL, 0x00,
6246 { &hf_capa_protocol_option_confirmed_push,
6247 { "Confirmed Push facility",
6248 "wsp.capability.protocol_option.confirmed_push",
6249 FT_BOOLEAN, 8, NULL, 0x80,
6250 "If set, this CO-WSP session supports the Confirmed Push facility", HFILL
6253 { &hf_capa_protocol_option_push,
6255 "wsp.capability.protocol_option.push",
6256 FT_BOOLEAN, 8, NULL, 0x40,
6257 "If set, this CO-WSP session supports the Push facility", HFILL
6260 { &hf_capa_protocol_option_session_resume,
6261 { "Session Resume facility",
6262 "wsp.capability.protocol_option.session_resume",
6263 FT_BOOLEAN, 8, NULL, 0x20,
6264 "If set, this CO-WSP session supports the Session Resume facility", HFILL
6267 { &hf_capa_protocol_option_ack_headers,
6268 { "Acknowledgement headers",
6269 "wsp.capability.protocol_option.ack_headers",
6270 FT_BOOLEAN, 8, NULL, 0x10,
6271 "If set, this CO-WSP session supports Acknowledgement headers", HFILL
6274 { &hf_capa_protocol_option_large_data_transfer,
6275 { "Large data transfer",
6276 "wsp.capability.protocol_option.large_data_transfer",
6277 FT_BOOLEAN, 8, NULL, 0x08,
6278 "If set, this CO-WSP session supports Large data transfer", HFILL
6281 { &hf_capa_method_mor,
6283 "wsp.capability.method_mor",
6284 FT_UINT8, BASE_DEC, NULL, 0x00,
6288 { &hf_capa_push_mor,
6290 "wsp.capability.push_mor",
6291 FT_UINT8, BASE_DEC, NULL, 0x00,
6295 { &hf_capa_extended_methods,
6296 { "Extended Methods",
6297 "wsp.capability.extended_methods",
6298 FT_STRING, BASE_NONE, NULL, 0x00,
6302 { &hf_capa_header_code_pages,
6303 { "Header Code Pages",
6304 "wsp.capability.code_pages",
6305 FT_STRING, BASE_NONE, NULL, 0x00,
6311 "wsp.capability.aliases",
6312 FT_BYTES, BASE_NONE, NULL, 0x00,
6316 { &hf_capa_client_message_size,
6317 { "Client Message Size",
6318 "wsp.capability.client_message_size",
6319 FT_UINT8, BASE_DEC, NULL, 0x00,
6320 "Client Message size (bytes)", HFILL
6323 { &hf_capa_server_message_size,
6324 { "Server Message Size",
6325 "wsp.capability.server_message_size",
6326 FT_UINT8, BASE_DEC, NULL, 0x00,
6327 "Server Message size (bytes)", HFILL
6330 { &hf_wsp_post_data,
6333 FT_NONE, BASE_NONE, NULL, 0x00,
6338 { &hf_wsp_push_data,
6341 FT_NONE, BASE_NONE, NULL, 0x00,
6345 { &hf_wsp_multipart_data,
6346 { "Data in this part",
6347 "wsp.multipart.data",
6348 FT_NONE, BASE_NONE, NULL, 0x00,
6349 "The data of 1 MIME-multipart part.", HFILL
6356 FT_UINT32, BASE_DEC, NULL, 0x00,
6357 "MIME part of multipart data.", HFILL
6360 { &hf_wsp_redirect_flags,
6362 "wsp.redirect.flags",
6363 FT_UINT8, BASE_HEX, NULL, 0x00,
6364 "Redirect Flags", HFILL
6367 { &hf_wsp_redirect_permanent,
6368 { "Permanent Redirect",
6369 "wsp.redirect.flags.permanent",
6370 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PERMANENT_REDIRECT,
6374 { &hf_wsp_redirect_reuse_security_session,
6375 { "Reuse Security Session",
6376 "wsp.redirect.flags.reuse_security_session",
6377 FT_BOOLEAN, 8, TFS(&tfs_yes_no), REUSE_SECURITY_SESSION,
6378 "If set, the existing Security Session may be reused", HFILL
6381 { &hf_redirect_addresses,
6382 { "Redirect Addresses",
6383 "wsp.redirect.addresses",
6384 FT_NONE, BASE_NONE, NULL, 0x00,
6385 "List of Redirect Addresses", HFILL
6392 { &hf_address_entry,
6395 FT_UINT32, BASE_DEC, NULL, 0x00,
6399 { &hf_address_flags_length,
6401 "wsp.address.flags",
6402 FT_UINT8, BASE_HEX, NULL, 0x00,
6403 "Address Flags/Length", HFILL
6406 { &hf_address_flags_length_bearer_type_included,
6407 { "Bearer Type Included",
6408 "wsp.address.flags.bearer_type_included",
6409 FT_BOOLEAN, 8, TFS(&tfs_yes_no), BEARER_TYPE_INCLUDED,
6410 "Address bearer type included", HFILL
6413 { &hf_address_flags_length_port_number_included,
6414 { "Port Number Included",
6415 "wsp.address.flags.port_number_included",
6416 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PORT_NUMBER_INCLUDED,
6417 "Address port number included", HFILL
6420 { &hf_address_flags_length_address_len,
6422 "wsp.address.flags.length",
6423 FT_UINT8, BASE_DEC, NULL, ADDRESS_LEN,
6427 { &hf_address_bearer_type,
6429 "wsp.address.bearer_type",
6430 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_bearer_types_ext, 0x0,
6434 { &hf_address_port_num,
6437 FT_UINT16, BASE_DEC, NULL, 0x0,
6441 { &hf_address_ipv4_addr,
6444 FT_IPv4, BASE_NONE, NULL, 0x0,
6445 "Address (IPv4)", HFILL
6448 { &hf_address_ipv6_addr,
6451 FT_IPv6, BASE_NONE, NULL, 0x0,
6452 "Address (IPv6)", HFILL
6457 "wsp.address.unknown",
6458 FT_BYTES, BASE_NONE, NULL, 0x0,
6459 "Address (unknown)", HFILL
6465 * New WSP header fields
6469 /* WSP header name */
6473 FT_STRING, BASE_NONE, NULL, 0x00,
6474 "Name of the WSP header", HFILL
6477 /* WSP headers start here */
6480 "wsp.header.accept",
6481 FT_STRING, BASE_NONE, NULL, 0x00,
6482 "WSP header Accept", HFILL
6485 { &hf_hdr_accept_charset,
6487 "wsp.header.accept_charset",
6488 FT_STRING, BASE_NONE, NULL, 0x00,
6489 "WSP header Accept-Charset", HFILL
6492 { &hf_hdr_accept_encoding,
6493 { "Accept-Encoding",
6494 "wsp.header.accept_encoding",
6495 FT_STRING, BASE_NONE, NULL, 0x00,
6496 "WSP header Accept-Encoding", HFILL
6499 { &hf_hdr_accept_language,
6500 { "Accept-Language",
6501 "wsp.header.accept_language",
6502 FT_STRING, BASE_NONE, NULL, 0x00,
6503 "WSP header Accept-Language", HFILL
6506 { &hf_hdr_accept_ranges,
6508 "wsp.header.accept_ranges",
6509 FT_STRING, BASE_NONE, NULL, 0x00,
6510 "WSP header Accept-Ranges", HFILL
6516 FT_STRING, BASE_NONE, NULL, 0x00,
6517 "WSP header Age", HFILL
6523 FT_STRING, BASE_NONE, NULL, 0x00,
6524 "WSP header Allow", HFILL
6527 { &hf_hdr_authorization,
6529 "wsp.header.authorization",
6530 FT_STRING, BASE_NONE, NULL, 0x00,
6531 "WSP header Authorization", HFILL
6534 { &hf_hdr_authorization_scheme,
6535 { "Authorization Scheme",
6536 "wsp.header.authorization.scheme",
6537 FT_STRING, BASE_NONE, NULL, 0x00,
6538 "WSP header Authorization: used scheme", HFILL
6541 { &hf_hdr_authorization_user_id,
6543 "wsp.header.authorization.user_id",
6544 FT_STRING, BASE_NONE, NULL, 0x00,
6545 "WSP header Authorization: user ID for basic authorization", HFILL
6548 { &hf_hdr_authorization_password,
6550 "wsp.header.authorization.password",
6551 FT_STRING, BASE_NONE, NULL, 0x00,
6552 "WSP header Authorization: password for basic authorization", HFILL
6555 { &hf_hdr_cache_control,
6557 "wsp.header.cache_control",
6558 FT_STRING, BASE_NONE, NULL, 0x00,
6559 "WSP header Cache-Control", HFILL
6562 { &hf_hdr_connection,
6564 "wsp.header.connection",
6565 FT_STRING, BASE_NONE, NULL, 0x00,
6566 "WSP header Connection", HFILL
6569 { &hf_hdr_content_base,
6571 "wsp.header.content_base",
6572 FT_STRING, BASE_NONE, NULL, 0x00,
6573 "WSP header Content-Base", HFILL
6576 { &hf_hdr_content_encoding,
6577 { "Content-Encoding",
6578 "wsp.header.content_encoding",
6579 FT_STRING, BASE_NONE, NULL, 0x00,
6580 "WSP header Content-Encoding", HFILL
6583 { &hf_hdr_content_language,
6584 { "Content-Language",
6585 "wsp.header.content_language",
6586 FT_STRING, BASE_NONE, NULL, 0x00,
6587 "WSP header Content-Language", HFILL
6590 { &hf_hdr_content_length,
6592 "wsp.header.content_length",
6593 FT_STRING, BASE_NONE, NULL, 0x00,
6594 "WSP header Content-Length", HFILL
6597 { &hf_hdr_content_location,
6598 { "Content-Location",
6599 "wsp.header.content_location",
6600 FT_STRING, BASE_NONE, NULL, 0x00,
6601 "WSP header Content-Location", HFILL
6604 { &hf_hdr_content_md5,
6606 "wsp.header.content_md5",
6607 FT_STRING, BASE_NONE, NULL, 0x00,
6608 "WSP header Content-Md5", HFILL
6611 { &hf_hdr_content_range,
6613 "wsp.header.content_range",
6614 FT_STRING, BASE_NONE, NULL, 0x00,
6615 "WSP header Content-Range", HFILL
6618 { &hf_hdr_content_range_first_byte_pos,
6619 { "First-byte-position",
6620 "wsp.header.content_range.first_byte_pos",
6621 FT_UINT32, BASE_DEC, NULL, 0x00,
6622 "WSP header Content-Range: position of first byte", HFILL
6625 { &hf_hdr_content_range_entity_length,
6627 "wsp.header.content_range.entity_length",
6628 FT_UINT32, BASE_DEC, NULL, 0x00,
6629 "WSP header Content-Range: length of the entity", HFILL
6632 { &hf_hdr_content_type,
6634 "wsp.header.content_type",
6635 FT_STRING, BASE_NONE, NULL, 0x00,
6636 "WSP header Content-Type", HFILL
6642 FT_STRING, BASE_NONE, NULL, 0x00,
6643 "WSP header Date", HFILL
6649 FT_STRING, BASE_NONE, NULL, 0x00,
6650 "WSP header ETag", HFILL
6655 "wsp.header.expires",
6656 FT_STRING, BASE_NONE, NULL, 0x00,
6657 "WSP header Expires", HFILL
6663 FT_STRING, BASE_NONE, NULL, 0x00,
6664 "WSP header From", HFILL
6670 FT_STRING, BASE_NONE, NULL, 0x00,
6671 "WSP header Host", HFILL
6674 { &hf_hdr_if_modified_since,
6675 { "If-Modified-Since",
6676 "wsp.header.if_modified_since",
6677 FT_STRING, BASE_NONE, NULL, 0x00,
6678 "WSP header If-Modified-Since", HFILL
6683 "wsp.header.if_match",
6684 FT_STRING, BASE_NONE, NULL, 0x00,
6685 "WSP header If-Match", HFILL
6688 { &hf_hdr_if_none_match,
6690 "wsp.header.if_none_match",
6691 FT_STRING, BASE_NONE, NULL, 0x00,
6692 "WSP header If-None-Match", HFILL
6697 "wsp.header.if_range",
6698 FT_STRING, BASE_NONE, NULL, 0x00,
6699 "WSP header If-Range", HFILL
6702 { &hf_hdr_if_unmodified_since,
6703 { "If-Unmodified-Since",
6704 "wsp.header.if_unmodified_since",
6705 FT_STRING, BASE_NONE, NULL, 0x00,
6706 "WSP header If-Unmodified-Since", HFILL
6709 { &hf_hdr_last_modified,
6711 "wsp.header.last_modified",
6712 FT_STRING, BASE_NONE, NULL, 0x00,
6713 "WSP header Last-Modified", HFILL
6718 "wsp.header.location",
6719 FT_STRING, BASE_NONE, NULL, 0x00,
6720 "WSP header Location", HFILL
6723 { &hf_hdr_max_forwards,
6725 "wsp.header.max_forwards",
6726 FT_STRING, BASE_NONE, NULL, 0x00,
6727 "WSP header Max-Forwards", HFILL
6732 "wsp.header.pragma",
6733 FT_STRING, BASE_NONE, NULL, 0x00,
6734 "WSP header Pragma", HFILL
6737 { &hf_hdr_proxy_authenticate,
6738 { "Proxy-Authenticate",
6739 "wsp.header.proxy_authenticate",
6740 FT_STRING, BASE_NONE, NULL, 0x00,
6741 "WSP header Proxy-Authenticate", HFILL
6744 { &hf_hdr_proxy_authenticate_scheme,
6745 { "Authentication Scheme",
6746 "wsp.header.proxy_authenticate.scheme",
6747 FT_STRING, BASE_NONE, NULL, 0x00,
6748 "WSP header Proxy-Authenticate: used scheme", HFILL
6751 { &hf_hdr_proxy_authenticate_realm,
6752 { "Authentication Realm",
6753 "wsp.header.proxy_authenticate.realm",
6754 FT_STRING, BASE_NONE, NULL, 0x00,
6755 "WSP header Proxy-Authenticate: used realm", HFILL
6758 { &hf_hdr_proxy_authorization,
6759 { "Proxy-Authorization",
6760 "wsp.header.proxy_authorization",
6761 FT_STRING, BASE_NONE, NULL, 0x00,
6762 "WSP header Proxy-Authorization", HFILL
6765 { &hf_hdr_proxy_authorization_scheme,
6766 { "Authorization Scheme",
6767 "wsp.header.proxy_authorization.scheme",
6768 FT_STRING, BASE_NONE, NULL, 0x00,
6769 "WSP header Proxy-Authorization: used scheme", HFILL
6772 { &hf_hdr_proxy_authorization_user_id,
6774 "wsp.header.proxy_authorization.user_id",
6775 FT_STRING, BASE_NONE, NULL, 0x00,
6776 "WSP header Proxy-Authorization: user ID for basic authorization", HFILL
6779 { &hf_hdr_proxy_authorization_password,
6781 "wsp.header.proxy_authorization.password",
6782 FT_STRING, BASE_NONE, NULL, 0x00,
6783 "WSP header Proxy-Authorization: password for basic authorization", HFILL
6788 "wsp.header.public",
6789 FT_STRING, BASE_NONE, NULL, 0x00,
6790 "WSP header Public", HFILL
6796 FT_STRING, BASE_NONE, NULL, 0x00,
6797 "WSP header Range", HFILL
6800 { &hf_hdr_range_first_byte_pos,
6801 { "First-byte-position",
6802 "wsp.header.range.first_byte_pos",
6803 FT_UINT32, BASE_DEC, NULL, 0x00,
6804 "WSP header Range: position of first byte", HFILL
6807 { &hf_hdr_range_last_byte_pos,
6808 { "Last-byte-position",
6809 "wsp.header.range.last_byte_pos",
6810 FT_UINT32, BASE_DEC, NULL, 0x00,
6811 "WSP header Range: position of last byte", HFILL
6814 { &hf_hdr_range_suffix_length,
6816 "wsp.header.range.suffix_length",
6817 FT_UINT32, BASE_DEC, NULL, 0x00,
6818 "WSP header Range: length of the suffix", HFILL
6823 "wsp.header.referer",
6824 FT_STRING, BASE_NONE, NULL, 0x00,
6825 "WSP header Referer", HFILL
6828 { &hf_hdr_retry_after,
6830 "wsp.header.retry_after",
6831 FT_STRING, BASE_NONE, NULL, 0x00,
6832 "WSP header Retry-After", HFILL
6837 "wsp.header.server",
6838 FT_STRING, BASE_NONE, NULL, 0x00,
6839 "WSP header Server", HFILL
6842 { &hf_hdr_transfer_encoding,
6843 { "Transfer-Encoding",
6844 "wsp.header.transfer_encoding",
6845 FT_STRING, BASE_NONE, NULL, 0x00,
6846 "WSP header Transfer-Encoding", HFILL
6851 "wsp.header.upgrade",
6852 FT_STRING, BASE_NONE, NULL, 0x00,
6853 "WSP header Upgrade", HFILL
6856 { &hf_hdr_user_agent,
6858 "wsp.header.user_agent",
6859 FT_STRING, BASE_NONE, NULL, 0x00,
6860 "WSP header User-Agent", HFILL
6866 FT_STRING, BASE_NONE, NULL, 0x00,
6867 "WSP header Vary", HFILL
6873 FT_STRING, BASE_NONE, NULL, 0x00,
6874 "WSP header Via", HFILL
6879 "wsp.header.warning",
6880 FT_STRING, BASE_NONE, NULL, 0x00,
6881 "WSP header Warning", HFILL
6884 { &hf_hdr_warning_code,
6886 "wsp.header.warning.code",
6887 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_wsp_warning_code_ext, 0x00,
6888 "WSP header Warning code", HFILL
6891 { &hf_hdr_warning_agent,
6893 "wsp.header.warning.agent",
6894 FT_STRING, BASE_NONE, NULL, 0x00,
6895 "WSP header Warning agent", HFILL
6898 { &hf_hdr_warning_text,
6900 "wsp.header.warning.text",
6901 FT_STRING, BASE_NONE, NULL, 0x00,
6902 "WSP header Warning text", HFILL
6905 { &hf_hdr_www_authenticate,
6906 { "Www-Authenticate",
6907 "wsp.header.www_authenticate",
6908 FT_STRING, BASE_NONE, NULL, 0x00,
6909 "WSP header Www-Authenticate", HFILL
6912 { &hf_hdr_www_authenticate_scheme,
6913 { "Authentication Scheme",
6914 "wsp.header.www_authenticate.scheme",
6915 FT_STRING, BASE_NONE, NULL, 0x00,
6916 "WSP header WWW-Authenticate: used scheme", HFILL
6919 { &hf_hdr_www_authenticate_realm,
6920 { "Authentication Realm",
6921 "wsp.header.www_authenticate.realm",
6922 FT_STRING, BASE_NONE, NULL, 0x00,
6923 "WSP header WWW-Authenticate: used realm", HFILL
6926 { &hf_hdr_content_disposition,
6927 { "Content-Disposition",
6928 "wsp.header.content_disposition",
6929 FT_STRING, BASE_NONE, NULL, 0x00,
6930 "WSP header Content-Disposition", HFILL
6933 { &hf_hdr_application_id,
6935 "wsp.header.application_id",
6936 FT_STRING, BASE_NONE, NULL, 0x00,
6937 "WSP header Application-Id", HFILL
6940 { &hf_hdr_content_uri,
6942 "wsp.header.content_uri",
6943 FT_STRING, BASE_NONE, NULL, 0x00,
6944 "WSP header Content-Uri", HFILL
6947 { &hf_hdr_initiator_uri,
6949 "wsp.header.initiator_uri",
6950 FT_STRING, BASE_NONE, NULL, 0x00,
6951 "WSP header Initiator-Uri", HFILL
6954 { &hf_hdr_bearer_indication,
6955 { "Bearer-Indication",
6956 "wsp.header.bearer_indication",
6957 FT_STRING, BASE_NONE, NULL, 0x00,
6958 "WSP header Bearer-Indication", HFILL
6961 { &hf_hdr_push_flag,
6963 "wsp.header.push_flag",
6964 FT_STRING, BASE_NONE, NULL, 0x00,
6965 "WSP header Push-Flag", HFILL
6968 { &hf_hdr_push_flag_auth,
6969 { "Initiator URI is authenticated",
6970 "wsp.header.push_flag.authenticated",
6971 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x01,
6972 "The X-Wap-Initiator-URI has been authenticated.", HFILL
6975 { &hf_hdr_push_flag_trust,
6976 { "Content is trusted",
6977 "wsp.header.push_flag.trusted",
6978 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x02,
6979 "The push content is trusted.", HFILL
6982 { &hf_hdr_push_flag_last,
6983 { "Last push message",
6984 "wsp.header.push_flag.last",
6985 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x04,
6986 "Indicates whether this is the last push message.", HFILL
6991 "wsp.header.profile",
6992 FT_STRING, BASE_NONE, NULL, 0x00,
6993 "WSP header Profile", HFILL
6996 { &hf_hdr_profile_diff,
6998 "wsp.header.profile_diff",
6999 FT_STRING, BASE_NONE, NULL, 0x00,
7000 "WSP header Profile-Diff", HFILL
7003 { &hf_hdr_profile_warning,
7004 { "Profile-Warning",
7005 "wsp.header.profile_warning",
7006 FT_STRING, BASE_NONE, NULL, 0x00,
7007 "WSP header Profile-Warning", HFILL
7012 "wsp.header.expect",
7013 FT_STRING, BASE_NONE, NULL, 0x00,
7014 "WSP header Expect", HFILL
7020 FT_STRING, BASE_NONE, NULL, 0x00,
7021 "WSP header Te", HFILL
7026 "wsp.header.trailer",
7027 FT_STRING, BASE_NONE, NULL, 0x00,
7028 "WSP header Trailer", HFILL
7031 { &hf_hdr_x_wap_tod,
7033 "wsp.header.x_wap_tod",
7034 FT_STRING, BASE_NONE, NULL, 0x00,
7035 "WSP header X-Wap-Tod", HFILL
7038 { &hf_hdr_content_id,
7040 "wsp.header.content_id",
7041 FT_STRING, BASE_NONE, NULL, 0x00,
7042 "WSP header Content-Id", HFILL
7045 { &hf_hdr_set_cookie,
7047 "wsp.header.set_cookie",
7048 FT_STRING, BASE_NONE, NULL, 0x00,
7049 "WSP header Set-Cookie", HFILL
7054 "wsp.header.cookie",
7055 FT_STRING, BASE_NONE, NULL, 0x00,
7056 "WSP header Cookie", HFILL
7059 { &hf_hdr_encoding_version,
7060 { "Encoding-Version",
7061 "wsp.header.encoding_version",
7062 FT_STRING, BASE_NONE, NULL, 0x00,
7063 "WSP header Encoding-Version", HFILL
7066 { &hf_hdr_x_wap_security,
7068 "wsp.header.x_wap_security",
7069 FT_STRING, BASE_NONE, NULL, 0x00,
7070 "WSP header X-Wap-Security", HFILL
7073 { &hf_hdr_x_wap_application_id,
7074 { "X-Wap-Application-Id",
7075 "wsp.header.x_wap_application_id",
7076 FT_STRING, BASE_NONE, NULL, 0x00,
7077 "WSP header X-Wap-Application-Id", HFILL
7080 { &hf_hdr_accept_application,
7081 { "Accept-Application",
7082 "wsp.header.accept_application",
7083 FT_STRING, BASE_NONE, NULL, 0x00,
7084 "WSP header Accept-Application", HFILL
7091 * Header Code Page: x-up-1
7094 /* Textual headers */
7095 { &hf_hdr_openwave_x_up_proxy_operator_domain,
7096 { "x-up-proxy-operator-domain",
7097 "wsp.header.x_up_1.x_up_proxy_operator_domain",
7098 FT_STRING, BASE_NONE, NULL, 0x00,
7099 "WSP Openwave header x-up-proxy-operator-domain", HFILL
7102 { &hf_hdr_openwave_x_up_proxy_home_page,
7103 { "x-up-proxy-home-page",
7104 "wsp.header.x_up_1.x_up_proxy_home_page",
7105 FT_STRING, BASE_NONE, NULL, 0x00,
7106 "WSP Openwave header x-up-proxy-home-page", HFILL
7109 { &hf_hdr_openwave_x_up_proxy_uplink_version,
7110 { "x-up-proxy-uplink-version",
7111 "wsp.header.x_up_1.x_up_proxy_uplink_version",
7112 FT_STRING, BASE_NONE, NULL, 0x00,
7113 "WSP Openwave header x-up-proxy-uplink-version", HFILL
7116 { &hf_hdr_openwave_x_up_proxy_ba_realm,
7117 { "x-up-proxy-ba-realm",
7118 "wsp.header.x_up_1.x_up_proxy_ba_realm",
7119 FT_STRING, BASE_NONE, NULL, 0x00,
7120 "WSP Openwave header x-up-proxy-ba-realm", HFILL
7123 { &hf_hdr_openwave_x_up_proxy_request_uri,
7124 { "x-up-proxy-request-uri",
7125 "wsp.header.x_up_1.x_up_proxy_request_uri",
7126 FT_STRING, BASE_NONE, NULL, 0x00,
7127 "WSP Openwave header x-up-proxy-request-uri", HFILL
7130 { &hf_hdr_openwave_x_up_proxy_bookmark,
7131 { "x-up-proxy-bookmark",
7132 "wsp.header.x_up_1.x_up_proxy_bookmark",
7133 FT_STRING, BASE_NONE, NULL, 0x00,
7134 "WSP Openwave header x-up-proxy-bookmark", HFILL
7137 /* Integer-value headers */
7138 { &hf_hdr_openwave_x_up_proxy_push_seq,
7139 { "x-up-proxy-push-seq",
7140 "wsp.header.x_up_1.x_up_proxy_push_seq",
7141 FT_STRING, BASE_NONE, NULL, 0x00,
7142 "WSP Openwave header x-up-proxy-push-seq", HFILL
7145 { &hf_hdr_openwave_x_up_proxy_notify,
7146 { "x-up-proxy-notify",
7147 "wsp.header.x_up_1.x_up_proxy_notify",
7148 FT_STRING, BASE_NONE, NULL, 0x00,
7149 "WSP Openwave header x-up-proxy-notify", HFILL
7152 { &hf_hdr_openwave_x_up_proxy_net_ask,
7153 { "x-up-proxy-net-ask",
7154 "wsp.header.x_up_1.x_up_proxy_net_ask",
7155 FT_STRING, BASE_NONE, NULL, 0x00,
7156 "WSP Openwave header x-up-proxy-net-ask", HFILL
7159 { &hf_hdr_openwave_x_up_proxy_tod,
7161 "wsp.header.x_up_1.x_up_proxy_tod",
7162 FT_STRING, BASE_NONE, NULL, 0x00,
7163 "WSP Openwave header x-up-proxy-tod", HFILL
7166 { &hf_hdr_openwave_x_up_proxy_ba_enable,
7167 { "x-up-proxy-ba-enable",
7168 "wsp.header.x_up_1.x_up_proxy_ba_enable",
7169 FT_STRING, BASE_NONE, NULL, 0x00,
7170 "WSP Openwave header x-up-proxy-ba-enable", HFILL
7173 { &hf_hdr_openwave_x_up_proxy_redirect_enable,
7174 { "x-up-proxy-redirect-enable",
7175 "wsp.header.x_up_1.x_up_proxy_redirect_enable",
7176 FT_STRING, BASE_NONE, NULL, 0x00,
7177 "WSP Openwave header x-up-proxy-redirect-enable", HFILL
7180 { &hf_hdr_openwave_x_up_proxy_redirect_status,
7181 { "x-up-proxy-redirect-status",
7182 "wsp.header.x_up_1.x_up_proxy_redirect_status",
7183 FT_STRING, BASE_NONE, NULL, 0x00,
7184 "WSP Openwave header x-up-proxy-redirect-status", HFILL
7187 { &hf_hdr_openwave_x_up_proxy_linger,
7188 { "x-up-proxy-linger",
7189 "wsp.header.x_up_1.x_up_proxy_linger",
7190 FT_STRING, BASE_NONE, NULL, 0x00,
7191 "WSP Openwave header x-up-proxy-linger", HFILL
7194 { &hf_hdr_openwave_x_up_proxy_enable_trust,
7195 { "x-up-proxy-enable-trust",
7196 "wsp.header.x_up_1.x_up_proxy_enable_trust",
7197 FT_STRING, BASE_NONE, NULL, 0x00,
7198 "WSP Openwave header x-up-proxy-enable-trust", HFILL
7201 { &hf_hdr_openwave_x_up_proxy_trust,
7202 { "x-up-proxy-trust",
7203 "wsp.header.x_up_1.x_up_proxy_trust",
7204 FT_STRING, BASE_NONE, NULL, 0x00,
7205 "WSP Openwave header x-up-proxy-trust", HFILL
7208 { &hf_hdr_openwave_x_up_devcap_has_color,
7209 { "x-up-devcap-has-color",
7210 "wsp.header.x_up_1.x_up_devcap_has_color",
7211 FT_STRING, BASE_NONE, NULL, 0x00,
7212 "WSP Openwave header x-up-devcap-has-color", HFILL
7215 { &hf_hdr_openwave_x_up_devcap_num_softkeys,
7216 { "x-up-devcap-num-softkeys",
7217 "wsp.header.x_up_1.x_up_devcap_num_softkeys",
7218 FT_STRING, BASE_NONE, NULL, 0x00,
7219 "WSP Openwave header x-up-devcap-num-softkeys", HFILL
7222 { &hf_hdr_openwave_x_up_devcap_softkey_size,
7223 { "x-up-devcap-softkey-size",
7224 "wsp.header.x_up_1.x_up_devcap_softkey_size",
7225 FT_STRING, BASE_NONE, NULL, 0x00,
7226 "WSP Openwave header x-up-devcap-softkey-size", HFILL
7229 { &hf_hdr_openwave_x_up_devcap_screen_chars,
7230 { "x-up-devcap-screen-chars",
7231 "wsp.header.x_up_1.x_up_devcap_screen_chars",
7232 FT_STRING, BASE_NONE, NULL, 0x00,
7233 "WSP Openwave header x-up-devcap-screen-chars", HFILL
7236 { &hf_hdr_openwave_x_up_devcap_screen_pixels,
7237 { "x-up-devcap-screen-pixels",
7238 "wsp.header.x_up_1.x_up_devcap_screen_pixels",
7239 FT_STRING, BASE_NONE, NULL, 0x00,
7240 "WSP Openwave header x-up-devcap-screen-pixels", HFILL
7243 { &hf_hdr_openwave_x_up_devcap_em_size,
7244 { "x-up-devcap-em-size",
7245 "wsp.header.x_up_1.x_up_devcap_em_size",
7246 FT_STRING, BASE_NONE, NULL, 0x00,
7247 "WSP Openwave header x-up-devcap-em-size", HFILL
7250 { &hf_hdr_openwave_x_up_devcap_screen_depth,
7251 { "x-up-devcap-screen-depth",
7252 "wsp.header.x_up_1.x_up_devcap_screen_depth",
7253 FT_STRING, BASE_NONE, NULL, 0x00,
7254 "WSP Openwave header x-up-devcap-screen-depth", HFILL
7257 { &hf_hdr_openwave_x_up_devcap_immed_alert,
7258 { "x-up-devcap-immed-alert",
7259 "wsp.header.x_up_1.x_up_devcap_immed_alert",
7260 FT_STRING, BASE_NONE, NULL, 0x00,
7261 "WSP Openwave header x-up-devcap-immed-alert", HFILL
7264 { &hf_hdr_openwave_x_up_devcap_gui,
7265 { "x-up-devcap-gui",
7266 "wsp.header.x_up_1.x_up_devcap_gui",
7267 FT_STRING, BASE_NONE, NULL, 0x00,
7268 "WSP Openwave header x-up-devcap-gui", HFILL
7271 { &hf_hdr_openwave_x_up_proxy_trans_charset,
7272 { "x-up-proxy-trans-charset",
7273 "wsp.header.x_up_1.x_up_proxy_trans_charset",
7274 FT_STRING, BASE_NONE, NULL, 0x00,
7275 "WSP Openwave header x-up-proxy-trans-charset", HFILL
7278 { &hf_hdr_openwave_x_up_proxy_push_accept,
7279 { "x-up-proxy-push-accept",
7280 "wsp.header.x_up_1.x_up_proxy_push_accept",
7281 FT_STRING, BASE_NONE, NULL, 0x00,
7282 "WSP Openwave header x-up-proxy-push-accept", HFILL
7287 /* Not used for now */
7288 { &hf_hdr_openwave_x_up_proxy_client_id,
7289 { "x-up-proxy-client-id",
7290 "wsp.header.x_up_1.x_up_proxy_client_id",
7291 FT_STRING, BASE_NONE, NULL, 0x00,
7292 "WSP Openwave header x-up-proxy-client-id", HFILL
7298 * Header value parameters
7304 FT_STRING, BASE_NONE, NULL, 0x00,
7305 "Q parameter", HFILL
7308 { &hf_parameter_charset,
7310 "wsp.parameter.charset",
7311 FT_STRING, BASE_NONE, NULL, 0x00,
7312 "Charset parameter", HFILL
7317 /* Setup protocol subtree array */
7318 static gint *ett[] = {
7320 &ett_header, /* Header field subtree */
7321 &ett_headers, /* Subtree for WSP headers */
7322 &ett_capabilities, /* CO-WSP Session Capabilities */
7323 &ett_capability, /* CO-WSP Session single Capability */
7325 &ett_redirect_flags,
7329 &ett_addresses, /* Addresses */
7330 &ett_address /* Single address */
7333 /* Register the protocol name and description */
7334 proto_wsp = proto_register_protocol(
7335 "Wireless Session Protocol", /* protocol name for use by wireshark */
7336 "WSP", /* short version of name */
7337 "wsp" /* Abbreviated protocol name,
7339 < URL:http://www.iana.org/assignments/port-numbers/ >
7342 wsp_tap = register_tap("wsp");
7343 /* Init the hash table */
7344 /* wsp_sessions = g_hash_table_new(
7345 (GHashFunc) wsp_session_hash,
7346 (GEqualFunc)wsp_session_equal);*/
7348 /* Required function calls to register the header fields and subtrees used */
7349 proto_register_field_array(proto_wsp, hf, array_length(hf));
7350 proto_register_subtree_array(ett, array_length(ett));
7352 register_dissector("wsp-co", dissect_wsp_fromwap_co, proto_wsp);
7353 register_dissector("wsp-cl", dissect_wsp_fromwap_cl, proto_wsp);
7354 register_heur_dissector_list("wsp", &heur_subdissector_list);
7356 wsp_fromudp_handle = create_dissector_handle(dissect_wsp_fromudp,
7361 proto_reg_handoff_wsp(void)
7364 * Get a handle for the WTP-over-UDP and the generic media dissectors.
7366 wtp_fromudp_handle = find_dissector("wtp-udp");
7367 media_handle = find_dissector("media");
7368 wbxml_uaprof_handle = find_dissector("wbxml-uaprof");
7370 /* Only connection-less WSP has no previous handler */
7371 dissector_add_uint("udp.port", UDP_PORT_WSP, wsp_fromudp_handle);
7372 dissector_add_uint("udp.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
7374 /* GSM SMS UD dissector can also carry WSP */
7375 dissector_add_uint("gsm-sms-ud.udh.port", UDP_PORT_WSP, wsp_fromudp_handle);
7376 dissector_add_uint("gsm-sms-ud.udh.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
7378 /* GSM SMS dissector can also carry WSP */
7379 dissector_add_uint("gsm-sms.udh.port", UDP_PORT_WSP, wsp_fromudp_handle);
7380 dissector_add_uint("gsm-sms.udh.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle);
7382 /* As the media types for WSP and HTTP are the same, the WSP dissector
7383 * uses the same string dissector table as the HTTP protocol. */
7384 media_type_table = find_dissector_table("media_type");
7386 /* This dissector is also called from the WTP and WTLS dissectors */
7390 * Session Initiation Request
7393 /* Register the protocol with Wireshark */
7395 proto_register_sir(void)
7397 /* Setup list of header fields */
7398 static hf_register_info hf[] = {
7400 { "Session Initiation Request",
7402 FT_NONE, BASE_NONE, NULL, 0x00,
7403 "Session Initiation Request content", HFILL
7409 FT_UINT8, BASE_DEC, NULL, 0x00,
7410 "Version of the Session Initiation Request document", HFILL
7413 { &hf_sir_app_id_list_len,
7414 { "Application-ID List Length",
7415 "wap.sir.app_id_list.length",
7416 FT_UINT32, BASE_DEC, NULL, 0x00,
7417 "Length of the Application-ID list (bytes)", HFILL
7420 { &hf_sir_app_id_list,
7421 { "Application-ID List",
7422 "wap.sir.app_id_list",
7423 FT_NONE, BASE_NONE, NULL, 0x00,
7427 { &hf_sir_wsp_contact_points_len,
7428 { "WSP Contact Points Length",
7429 "wap.sir.wsp_contact_points.length",
7430 FT_UINT32, BASE_DEC, NULL, 0x00,
7431 "Length of the WSP Contact Points list (bytes)", HFILL
7434 { &hf_sir_wsp_contact_points,
7435 { "WSP Contact Points",
7436 "wap.sir.wsp_contact_points",
7437 FT_NONE, BASE_NONE, NULL, 0x00,
7438 "WSP Contact Points list", HFILL
7441 { &hf_sir_contact_points_len,
7442 { "Non-WSP Contact Points Length",
7443 "wap.sir.contact_points.length",
7444 FT_UINT32, BASE_DEC, NULL, 0x00,
7445 "Length of the Non-WSP Contact Points list (bytes)", HFILL
7448 { &hf_sir_contact_points,
7449 { "Non-WSP Contact Points",
7450 "wap.sir.contact_points",
7451 FT_NONE, BASE_NONE, NULL, 0x00,
7452 "Non-WSP Contact Points list", HFILL
7455 { &hf_sir_protocol_options_len,
7456 { "Protocol Options List Entries",
7457 "wap.sir.protocol_options.length",
7458 FT_UINT32, BASE_DEC, NULL, 0x00,
7459 "Number of entries in the Protocol Options list", HFILL
7462 { &hf_sir_protocol_options,
7463 { "Protocol Options",
7464 "wap.sir.protocol_options",
7465 FT_UINT16, BASE_DEC, VALS(vals_sir_protocol_options), 0x00,
7466 "Protocol Options list", HFILL
7469 { &hf_sir_prov_url_len,
7470 { "X-Wap-ProvURL Length",
7471 "wap.sir.prov_url.length",
7472 FT_UINT32, BASE_DEC, NULL, 0x00,
7473 "Length of the X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL
7479 FT_STRING, BASE_NONE, NULL, 0x00,
7480 "X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL
7483 { &hf_sir_cpi_tag_len,
7484 { "CPITag List Entries",
7485 "wap.sir.cpi_tag.length",
7486 FT_UINT32, BASE_DEC, NULL, 0x00,
7487 "Number of entries in the CPITag list", HFILL
7493 FT_BYTES, BASE_NONE, NULL, 0x00,
7494 "CPITag (OTA-HTTP)", HFILL
7499 /* Setup protocol subtree array */
7500 static gint *ett[] = {
7501 &ett_sir /* Session Initiation Request */
7504 /* Register the dissector */
7505 proto_sir = proto_register_protocol(
7506 "WAP Session Initiation Request", /* protocol name for use by wireshark */
7507 "WAP SIR", /* short version of name */
7508 "wap-sir" /* Abbreviated protocol name,
7510 < URL:http://www.iana.org/assignments/port-numbers/ >
7514 /* Register header fields and protocol subtrees */
7515 proto_register_field_array(proto_sir, hf, array_length(hf));
7516 proto_register_subtree_array(ett, array_length(ett));
7520 proto_reg_handoff_sir(void)
7522 dissector_handle_t sir_handle;
7524 sir_handle = create_dissector_handle(dissect_sir, proto_sir);
7526 /* Add dissector bindings for SIR dissection */
7527 dissector_add_string("media_type", "application/vnd.wap.sia", sir_handle);
7538 * indent-tabs-mode: nil
7541 * ex: set shiftwidth=4 tabstop=8 expandtab:
7542 * :indentSize=4:tabSize=8:noTabs=true: