1 /* packet-wsp.c 2 * 3 * Routines to dissect WSP component of WAP traffic. 4 * 5 * Refer to the AUTHORS file or the AUTHORS section in the man page 6 * for contacting the author(s) of this file. 7 * 8 * Wireshark - Network traffic analyzer 9 * By Gerald Combs <gerald@wireshark.org> 10 * Copyright 1998 Gerald Combs 11 * 12 * WAP dissector based on original work by Ben Fowler 13 * Updated by Neil Hunter. 14 * 15 * WTLS support by Alexandre P. Ferreira (Splice IP). 16 * 17 * Openwave header support by Dermot Bradley (Openwave). 18 * 19 * Code optimizations, header value dissection simplification with parse error 20 * notification and macros, extra missing headers, WBXML registration, 21 * summary line of WSP PDUs, 22 * Session Initiation Request dissection 23 * by Olivier Biot. 24 * 25 * SPDX-License-Identifier: GPL-2.0-or-later 26 */ 27 28 #include "config.h" 29 30 #include <epan/packet.h> 31 #include <epan/to_str.h> 32 #include <epan/expert.h> 33 #include <epan/conversation.h> 34 #include <epan/iana_charsets.h> 35 36 #include <wsutil/str_util.h> 37 38 #include "packet-wap.h" 39 #include "packet-wsp.h" 40 41 /* Statistics (see doc/README.tapping) */ 42 #include <epan/stat_tap_ui.h> 43 #include <epan/tap.h> 44 45 void proto_register_wsp(void); 46 void proto_reg_handoff_wsp(void); 47 void proto_register_sir(void); 48 void proto_reg_handoff_sir(void); 49 50 static int wsp_tap = -1; 51 52 53 /* File scoped variables for the protocol and registered fields */ 54 static int proto_wsp = -1; 55 static int proto_sir = -1; 56 57 /* 58 * Initialize the header field pointers 59 */ 60 61 /* WSP header fields and their subfields if available */ 62 static int hf_hdr_name_value = -1; 63 static int hf_hdr_name_string = -1; 64 static int hf_hdr_accept = -1; 65 static int hf_hdr_accept_charset = -1; 66 static int hf_hdr_accept_encoding = -1; 67 static int hf_hdr_accept_language = -1; 68 static int hf_hdr_accept_ranges = -1; 69 static int hf_hdr_age = -1; 70 static int hf_hdr_allow = -1; 71 static int hf_hdr_authorization = -1; 72 static int hf_hdr_authorization_scheme = -1; /* Subfield */ 73 static int hf_hdr_authorization_user_id = -1; /* Subfield */ 74 static int hf_hdr_authorization_password = -1; /* Subfield */ 75 static int hf_hdr_cache_control = -1; 76 static int hf_hdr_connection = -1; 77 static int hf_hdr_content_base = -1; 78 static int hf_hdr_content_encoding = -1; 79 static int hf_hdr_content_language = -1; 80 static int hf_hdr_content_length = -1; 81 static int hf_hdr_content_location = -1; 82 static int hf_hdr_content_md5 = -1; 83 static int hf_hdr_content_range = -1; 84 static int hf_hdr_content_range_first_byte_pos = -1; /* Subfield */ 85 static int hf_hdr_content_range_entity_length = -1; /* Subfield */ 86 static int hf_hdr_content_type = -1; 87 static int hf_hdr_date = -1; 88 static int hf_hdr_etag = -1; 89 static int hf_hdr_expires = -1; 90 static int hf_hdr_from = -1; 91 static int hf_hdr_host = -1; 92 static int hf_hdr_if_modified_since = -1; 93 static int hf_hdr_if_match = -1; 94 static int hf_hdr_if_none_match = -1; 95 static int hf_hdr_if_range = -1; 96 static int hf_hdr_if_unmodified_since = -1; 97 static int hf_hdr_last_modified = -1; 98 static int hf_hdr_location = -1; 99 static int hf_hdr_max_forwards = -1; 100 static int hf_hdr_pragma = -1; 101 static int hf_hdr_proxy_authenticate = -1; 102 static int hf_hdr_proxy_authenticate_scheme = -1; /* Subfield */ 103 static int hf_hdr_proxy_authenticate_realm = -1; /* Subfield */ 104 static int hf_hdr_proxy_authorization = -1; 105 static int hf_hdr_proxy_authorization_scheme = -1; /* Subfield */ 106 static int hf_hdr_proxy_authorization_user_id = -1; /* Subfield */ 107 static int hf_hdr_proxy_authorization_password = -1; /* Subfield */ 108 static int hf_hdr_public = -1; 109 static int hf_hdr_range = -1; 110 static int hf_hdr_range_first_byte_pos = -1; /* Subfield */ 111 static int hf_hdr_range_last_byte_pos = -1; /* Subfield */ 112 static int hf_hdr_range_suffix_length = -1; /* Subfield */ 113 static int hf_hdr_referer = -1; 114 static int hf_hdr_retry_after = -1; 115 static int hf_hdr_server = -1; 116 static int hf_hdr_transfer_encoding = -1; 117 static int hf_hdr_upgrade = -1; 118 static int hf_hdr_user_agent = -1; 119 static int hf_hdr_vary = -1; 120 static int hf_hdr_via = -1; 121 static int hf_hdr_warning = -1; 122 static int hf_hdr_warning_code = -1; /* Subfield */ 123 static int hf_hdr_warning_agent = -1; /* Subfield */ 124 static int hf_hdr_warning_text = -1; /* Subfield */ 125 static int hf_hdr_www_authenticate = -1; 126 static int hf_hdr_www_authenticate_scheme = -1; /* Subfield */ 127 static int hf_hdr_www_authenticate_realm = -1; /* Subfield */ 128 static int hf_hdr_content_disposition = -1; 129 static int hf_hdr_application_id = -1; 130 static int hf_hdr_content_uri = -1; 131 static int hf_hdr_initiator_uri = -1; 132 static int hf_hdr_bearer_indication = -1; 133 static int hf_hdr_push_flag = -1; 134 static int hf_hdr_push_flag_auth = -1; /* Subfield */ 135 static int hf_hdr_push_flag_trust = -1; /* Subfield */ 136 static int hf_hdr_push_flag_last = -1; /* Subfield */ 137 static int hf_hdr_profile = -1; 138 static int hf_hdr_profile_diff = -1; 139 static int hf_hdr_profile_warning = -1; 140 static int hf_hdr_expect = -1; 141 static int hf_hdr_te = -1; 142 static int hf_hdr_trailer = -1; 143 static int hf_hdr_x_wap_tod = -1; 144 static int hf_hdr_content_id = -1; 145 static int hf_hdr_set_cookie = -1; 146 static int hf_hdr_cookie = -1; 147 static int hf_hdr_encoding_version = -1; 148 static int hf_hdr_x_wap_security = -1; 149 static int hf_hdr_x_wap_application_id = -1; 150 static int hf_hdr_accept_application = -1; 151 152 153 /* Openwave headers */ 154 static int hf_hdr_openwave_default_int = -1; 155 static int hf_hdr_openwave_default_string = -1; 156 static int hf_hdr_openwave_default_val_len = -1; 157 static int hf_hdr_openwave_name_value = -1; 158 static int hf_hdr_openwave_x_up_proxy_operator_domain = -1; 159 static int hf_hdr_openwave_x_up_proxy_home_page = -1; 160 static int hf_hdr_openwave_x_up_proxy_uplink_version = -1; 161 static int hf_hdr_openwave_x_up_proxy_ba_realm = -1; 162 static int hf_hdr_openwave_x_up_proxy_request_uri = -1; 163 #if 0 164 static int hf_hdr_openwave_x_up_proxy_client_id = -1; 165 #endif 166 static int hf_hdr_openwave_x_up_proxy_bookmark = -1; 167 static int hf_hdr_openwave_x_up_proxy_push_seq = -1; 168 static int hf_hdr_openwave_x_up_proxy_notify = -1; 169 static int hf_hdr_openwave_x_up_proxy_net_ask = -1; 170 static int hf_hdr_openwave_x_up_proxy_tod = -1; 171 static int hf_hdr_openwave_x_up_proxy_ba_enable = -1; 172 static int hf_hdr_openwave_x_up_proxy_redirect_enable = -1; 173 static int hf_hdr_openwave_x_up_proxy_redirect_status = -1; 174 static int hf_hdr_openwave_x_up_proxy_linger = -1; 175 static int hf_hdr_openwave_x_up_proxy_enable_trust = -1; 176 static int hf_hdr_openwave_x_up_proxy_trust = -1; 177 static int hf_hdr_openwave_x_up_devcap_has_color = -1; 178 static int hf_hdr_openwave_x_up_devcap_num_softkeys = -1; 179 static int hf_hdr_openwave_x_up_devcap_softkey_size = -1; 180 static int hf_hdr_openwave_x_up_devcap_screen_chars = -1; 181 static int hf_hdr_openwave_x_up_devcap_screen_pixels = -1; 182 static int hf_hdr_openwave_x_up_devcap_em_size = -1; 183 static int hf_hdr_openwave_x_up_devcap_screen_depth = -1; 184 static int hf_hdr_openwave_x_up_devcap_immed_alert = -1; 185 static int hf_hdr_openwave_x_up_devcap_gui = -1; 186 static int hf_hdr_openwave_x_up_proxy_trans_charset = -1; 187 static int hf_hdr_openwave_x_up_proxy_push_accept = -1; 188 189 190 /* WSP parameter fields */ 191 static int hf_parameter_q = -1; 192 static int hf_parameter_charset = -1; 193 194 /* Old header fields */ 195 196 static int hf_wsp_header_tid = -1; 197 static int hf_wsp_header_pdu_type = -1; 198 static int hf_wsp_version_major = -1; 199 static int hf_wsp_version_minor = -1; 200 /* Session capabilities (CO-WSP) */ 201 static int hf_capabilities_length = -1; 202 static int hf_capabilities_section = -1; 203 static int hf_capa_client_sdu_size = -1; 204 static int hf_capa_server_sdu_size = -1; 205 static int hf_capa_protocol_options = -1; 206 static int hf_capa_protocol_option_confirmed_push = -1; /* Subfield */ 207 static int hf_capa_protocol_option_push = -1; /* Subfield */ 208 static int hf_capa_protocol_option_session_resume = -1; /* Subfield */ 209 static int hf_capa_protocol_option_ack_headers = -1; /* Subfield */ 210 static int hf_capa_protocol_option_large_data_transfer = -1; /* Subfield */ 211 static int hf_capa_method_mor = -1; 212 static int hf_capa_push_mor = -1; 213 static int hf_capa_extended_method = -1; 214 static int hf_capa_header_code_page = -1; 215 static int hf_capa_aliases = -1; 216 static int hf_capa_client_message_size = -1; 217 static int hf_capa_server_message_size = -1; 218 219 static int hf_wsp_header_uri_len = -1; 220 static int hf_wsp_header_uri = -1; 221 static int hf_wsp_server_session_id = -1; 222 static int hf_wsp_header_status = -1; 223 static int hf_wsp_header_length = -1; 224 static int hf_wsp_headers_section = -1; 225 static int hf_wsp_parameter_untype_quote_text = -1; 226 static int hf_wsp_parameter_untype_text = -1; 227 static int hf_wsp_parameter_untype_int = -1; 228 static int hf_wsp_parameter_type = -1; 229 static int hf_wsp_parameter_int_type = -1; 230 static int hf_wsp_parameter_name = -1; 231 static int hf_wsp_parameter_filename = -1; 232 static int hf_wsp_parameter_start = -1; 233 static int hf_wsp_parameter_start_info = -1; 234 static int hf_wsp_parameter_comment = -1; 235 static int hf_wsp_parameter_domain = -1; 236 static int hf_wsp_parameter_path = -1; 237 static int hf_wsp_parameter_sec = -1; 238 static int hf_wsp_parameter_mac = -1; 239 static int hf_wsp_parameter_upart_type = -1; 240 static int hf_wsp_parameter_level = -1; 241 static int hf_wsp_parameter_size = -1; 242 #if 0 243 static int hf_wsp_reply_data = -1; 244 #endif 245 static int hf_wsp_post_data = -1; 246 #if 0 247 static int hf_wsp_push_data = -1; 248 static int hf_wsp_multipart_data = -1; 249 #endif 250 static int hf_wsp_mpart = -1; 251 static int hf_wsp_header_text_value = -1; 252 static int hf_wsp_variable_value = -1; 253 static int hf_wsp_default_int = -1; 254 static int hf_wsp_default_string = -1; 255 static int hf_wsp_default_val_len = -1; 256 257 /* Header code page shift sequence */ 258 static int hf_wsp_header_shift_code = -1; 259 260 /* WSP Redirect fields */ 261 static int hf_wsp_redirect_flags = -1; 262 static int hf_wsp_redirect_permanent = -1; 263 static int hf_wsp_redirect_reuse_security_session = -1; 264 static int hf_redirect_addresses = -1; 265 266 /* Address fields */ 267 static int hf_address_entry = -1; 268 static int hf_address_flags_length = -1; 269 static int hf_address_flags_length_bearer_type_included = -1; /* Subfield */ 270 static int hf_address_flags_length_port_number_included = -1; /* Subfield */ 271 static int hf_address_flags_length_address_len = -1; /* Subfield */ 272 static int hf_address_bearer_type = -1; 273 static int hf_address_port_num = -1; 274 static int hf_address_ipv4_addr = -1; 275 static int hf_address_ipv6_addr = -1; 276 static int hf_address_addr = -1; 277 278 /* Session Initiation Request fields */ 279 static int hf_sir_section = -1; 280 static int hf_sir_version = -1; 281 static int hf_sir_app_id_list_len = -1; 282 static int hf_sir_app_id_list = -1; 283 static int hf_sir_wsp_contact_points_len = -1; 284 static int hf_sir_wsp_contact_points = -1; 285 static int hf_sir_contact_points_len = -1; 286 static int hf_sir_contact_points = -1; 287 static int hf_sir_protocol_options_len = -1; 288 static int hf_sir_protocol_options = -1; 289 static int hf_sir_prov_url_len = -1; 290 static int hf_sir_prov_url = -1; 291 static int hf_sir_cpi_tag_len = -1; 292 static int hf_sir_cpi_tag = -1; 293 294 /* 295 * Initialize the subtree pointers 296 */ 297 298 /* WSP tree */ 299 static int ett_wsp = -1; 300 /* WSP headers tree */ 301 static int ett_header = -1; 302 /* WSP header subtree */ 303 static int ett_headers = -1; 304 static int ett_wsp_parameter_type = -1; 305 static int ett_content_type_header = -1; 306 /* CO-WSP session capabilities */ 307 static int ett_capabilities = -1; 308 static int ett_capabilities_entry = -1; 309 static int ett_proto_option_capability = -1; 310 static int ett_capabilities_header_code_pages = -1; 311 static int ett_capabilities_extended_methods = -1; 312 static int ett_post = -1; 313 static int ett_redirect_flags = -1; 314 static int ett_address_flags = -1; 315 static int ett_multiparts = -1; 316 static int ett_mpartlist = -1; 317 /* Session Initiation Request tree */ 318 static int ett_sir = -1; 319 static int ett_addresses = -1; 320 static int ett_address = -1; 321 322 static int ett_default = -1; 323 static int ett_add_content_type = -1; 324 static int ett_accept_x_q_header = -1; 325 static int ett_push_flag = -1; 326 static int ett_profile_diff_wbxml = -1; 327 static int ett_allow = -1; 328 static int ett_public = -1; 329 static int ett_vary = -1; 330 static int ett_x_wap_security = -1; 331 static int ett_connection = -1; 332 static int ett_transfer_encoding = -1; 333 static int ett_accept_ranges = -1; 334 static int ett_content_encoding = -1; 335 static int ett_accept_encoding = -1; 336 static int ett_content_disposition = -1; 337 static int ett_text_header = -1; 338 static int ett_content_id = -1; 339 static int ett_text_or_date_value = -1; 340 static int ett_date_value = -1; 341 static int ett_tod_value = -1; 342 static int ett_age = -1; 343 static int ett_integer_lookup = -1; 344 static int ett_challenge = -1; 345 static int ett_credentials_value = -1; 346 static int ett_content_md5 = -1; 347 static int ett_pragma = -1; 348 static int ett_integer_value = -1; 349 static int ett_integer_lookup_value = -1; 350 static int ett_cache_control = -1; 351 static int ett_warning = -1; 352 static int ett_profile_warning = -1; 353 static int ett_encoding_version = -1; 354 static int ett_content_range = -1; 355 static int ett_range = -1; 356 static int ett_te_value = -1; 357 static int ett_openwave_default = -1; 358 359 static expert_field ei_wsp_capability_invalid = EI_INIT; 360 static expert_field ei_wsp_capability_length_invalid = EI_INIT; 361 static expert_field ei_wsp_capability_encoding_invalid = EI_INIT; 362 static expert_field ei_wsp_text_field_invalid = EI_INIT; 363 static expert_field ei_wsp_header_invalid_value = EI_INIT; 364 static expert_field ei_wsp_invalid_parameter_value = EI_INIT; 365 static expert_field ei_wsp_undecoded_parameter = EI_INIT; 366 static expert_field ei_hdr_x_wap_tod = EI_INIT; 367 static expert_field ei_wsp_trailing_quote = EI_INIT; 368 static expert_field ei_wsp_header_invalid = EI_INIT; 369 static expert_field ei_wsp_oversized_uintvar = EI_INIT; 370 371 372 /* Handle for WSP-over-UDP dissector */ 373 static dissector_handle_t wsp_fromudp_handle; 374 375 /* Handle for WTP-over-UDP dissector */ 376 static dissector_handle_t wtp_fromudp_handle; 377 378 /* Handle for coap dissector */ 379 static dissector_handle_t coap_handle; 380 381 /* Handle for generic media dissector */ 382 static dissector_handle_t media_handle; 383 384 /* Handle for WBXML-encoded UAPROF dissector */ 385 static dissector_handle_t wbxml_uaprof_handle; 386 387 static const value_string wsp_vals_pdu_type[] = { 388 { 0x00, "Reserved" }, 389 { 0x01, "Connect" }, 390 { 0x02, "ConnectReply" }, 391 { 0x03, "Redirect" }, 392 { 0x04, "Reply" }, 393 { 0x05, "Disconnect" }, 394 { 0x06, "Push" }, 395 { 0x07, "ConfirmedPush" }, 396 { 0x08, "Suspend" }, 397 { 0x09, "Resume" }, 398 399 /* 0x10 - 0x3F Unassigned */ 400 401 { 0x40, "Get" }, 402 { 0x41, "Options" }, 403 { 0x42, "Head" }, 404 { 0x43, "Delete" }, 405 { 0x44, "Trace" }, 406 407 /* 0x45 - 0x4F Unassigned (Get PDU) */ 408 /* 0x50 - 0x5F Extended method (Get PDU) */ 409 { 0x50, "Extended Get Method 0"}, 410 { 0x51, "Extended Get Method 1"}, 411 { 0x52, "Extended Get Method 2"}, 412 { 0x53, "Extended Get Method 3"}, 413 { 0x54, "Extended Get Method 4"}, 414 { 0x55, "Extended Get Method 5"}, 415 { 0x56, "Extended Get Method 6"}, 416 { 0x57, "Extended Get Method 7"}, 417 { 0x58, "Extended Get Method 8"}, 418 { 0x59, "Extended Get Method 9"}, 419 { 0x5A, "Extended Get Method 10"}, 420 { 0x5B, "Extended Get Method 11"}, 421 { 0x5C, "Extended Get Method 12"}, 422 { 0x5D, "Extended Get Method 13"}, 423 { 0x5E, "Extended Get Method 14"}, 424 { 0x5F, "Extended Get Method 15"}, 425 426 { 0x60, "Post" }, 427 { 0x61, "Put" }, 428 429 /* 0x62 - 0x6F Unassigned (Post PDU) */ 430 /* 0x70 - 0x7F Extended method (Post PDU) */ 431 { 0x70, "Extended Post Method 0"}, 432 { 0x71, "Extended Post Method 1"}, 433 { 0x72, "Extended Post Method 2"}, 434 { 0x73, "Extended Post Method 3"}, 435 { 0x74, "Extended Post Method 4"}, 436 { 0x75, "Extended Post Method 5"}, 437 { 0x76, "Extended Post Method 6"}, 438 { 0x77, "Extended Post Method 7"}, 439 { 0x78, "Extended Post Method 8"}, 440 { 0x79, "Extended Post Method 9"}, 441 { 0x7A, "Extended Post Method 10"}, 442 { 0x7B, "Extended Post Method 11"}, 443 { 0x7C, "Extended Post Method 12"}, 444 { 0x7D, "Extended Post Method 13"}, 445 { 0x7E, "Extended Post Method 14"}, 446 { 0x7F, "Extended Post Method 15"}, 447 448 /* 0x80 - 0xFF Reserved */ 449 450 { 0x00, NULL } 451 452 }; 453 value_string_ext wsp_vals_pdu_type_ext = VALUE_STRING_EXT_INIT(wsp_vals_pdu_type); 454 455 /* The WSP status codes are inherited from the HTTP status codes */ 456 static const value_string wsp_vals_status[] = { 457 /* 0x00 - 0x0F Reserved */ 458 459 { 0x10, "100 Continue" }, 460 { 0x11, "101 Switching Protocols" }, 461 462 { 0x20, "200 OK" }, 463 { 0x21, "201 Created" }, 464 { 0x22, "202 Accepted" }, 465 { 0x23, "203 Non-Authoritative Information" }, 466 { 0x24, "204 No Content" }, 467 { 0x25, "205 Reset Content" }, 468 { 0x26, "206 Partial Content" }, 469 470 { 0x30, "300 Multiple Choices" }, 471 { 0x31, "301 Moved Permanently" }, 472 { 0x32, "302 Moved Temporarily" }, 473 { 0x33, "303 See Other" }, 474 { 0x34, "304 Not Modified" }, 475 { 0x35, "305 Use Proxy" }, 476 { 0x37, "307 Temporary Redirect" }, 477 478 { 0x40, "400 Bad Request" }, 479 { 0x41, "401 Unauthorised" }, 480 { 0x42, "402 Payment Required" }, 481 { 0x43, "403 Forbidden" }, 482 { 0x44, "404 Not Found" }, 483 { 0x45, "405 Method Not Allowed" }, 484 { 0x46, "406 Not Acceptable" }, 485 { 0x47, "407 Proxy Authentication Required" }, 486 { 0x48, "408 Request Timeout" }, 487 { 0x49, "409 Conflict" }, 488 { 0x4A, "410 Gone" }, 489 { 0x4B, "411 Length Required" }, 490 { 0x4C, "412 Precondition Failed" }, 491 { 0x4D, "413 Request Entity Too Large" }, 492 { 0x4E, "414 Request-URI Too Large" }, 493 { 0x4F, "415 Unsupported Media Type" }, 494 { 0x50, "416 Requested Range Not Satisfiable" }, 495 { 0x51, "417 Expectation Failed" }, 496 497 { 0x60, "500 Internal Server Error" }, 498 { 0x61, "501 Not Implemented" }, 499 { 0x62, "502 Bad Gateway" }, 500 { 0x63, "503 Service Unavailable" }, 501 { 0x64, "504 Gateway Timeout" }, 502 { 0x65, "505 WSP/HTTP Version Not Supported" }, 503 504 { 0x00, NULL } 505 }; 506 value_string_ext wsp_vals_status_ext = VALUE_STRING_EXT_INIT(wsp_vals_status); 507 508 static const value_string vals_wsp_reason_codes[] = { 509 { 0xE0, "Protocol Error (Illegal PDU)" }, 510 { 0xE1, "Session disconnected" }, 511 { 0xE2, "Session suspended" }, 512 { 0xE3, "Session resumed" }, 513 { 0xE4, "Peer congested" }, 514 { 0xE5, "Session connect failed" }, 515 { 0xE6, "Maximum receive unit size exceeded" }, 516 { 0xE7, "Maximum outstanding requests exceeded" }, 517 { 0xE8, "Peer request" }, 518 { 0xE9, "Network error" }, 519 { 0xEA, "User request" }, 520 { 0xEB, "No specific cause, no retries" }, 521 { 0xEC, "Push message cannot be delivered" }, 522 { 0xED, "Push message discarded" }, 523 { 0xEE, "Content type cannot be processed" }, 524 525 { 0x00, NULL } 526 }; 527 value_string_ext vals_wsp_reason_codes_ext = VALUE_STRING_EXT_INIT(vals_wsp_reason_codes); 528 529 /* 530 * Field names. 531 */ 532 #define FN_ACCEPT 0x00 533 #define FN_ACCEPT_CHARSET_DEP 0x01 /* encoding version 1.1, deprecated */ 534 #define FN_ACCEPT_ENCODING_DEP 0x02 /* encoding version 1.1, deprecated */ 535 #define FN_ACCEPT_LANGUAGE 0x03 536 #define FN_ACCEPT_RANGES 0x04 537 #define FN_AGE 0x05 538 #define FN_ALLOW 0x06 539 #define FN_AUTHORIZATION 0x07 540 #define FN_CACHE_CONTROL_DEP 0x08 /* encoding version 1.1, deprecated */ 541 #define FN_CONNECTION 0x09 542 #define FN_CONTENT_BASE 0x0A 543 #define FN_CONTENT_ENCODING 0x0B 544 #define FN_CONTENT_LANGUAGE 0x0C 545 #define FN_CONTENT_LENGTH 0x0D 546 #define FN_CONTENT_LOCATION 0x0E 547 #define FN_CONTENT_MD5 0x0F 548 #define FN_CONTENT_RANGE_DEP 0x10 /* encoding version 1.1, deprecated */ 549 #define FN_CONTENT_TYPE 0x11 550 #define FN_DATE 0x12 551 #define FN_ETAG 0x13 552 #define FN_EXPIRES 0x14 553 #define FN_FROM 0x15 554 #define FN_HOST 0x16 555 #define FN_IF_MODIFIED_SINCE 0x17 556 #define FN_IF_MATCH 0x18 557 #define FN_IF_NONE_MATCH 0x19 558 #define FN_IF_RANGE 0x1A 559 #define FN_IF_UNMODIFIED_SINCE 0x1B 560 #define FN_LOCATION 0x1C 561 #define FN_LAST_MODIFIED 0x1D 562 #define FN_MAX_FORWARDS 0x1E 563 #define FN_PRAGMA 0x1F 564 #define FN_PROXY_AUTHENTICATE 0x20 565 #define FN_PROXY_AUTHORIZATION 0x21 566 #define FN_PUBLIC 0x22 567 #define FN_RANGE 0x23 568 #define FN_REFERER 0x24 569 #define FN_RETRY_AFTER 0x25 570 #define FN_SERVER 0x26 571 #define FN_TRANSFER_ENCODING 0x27 572 #define FN_UPGRADE 0x28 573 #define FN_USER_AGENT 0x29 574 #define FN_VARY 0x2A 575 #define FN_VIA 0x2B 576 #define FN_WARNING 0x2C 577 #define FN_WWW_AUTHENTICATE 0x2D 578 #define FN_CONTENT_DISPOSITION 0x2E 579 #define FN_X_WAP_APPLICATION_ID 0x2F 580 #define FN_X_WAP_CONTENT_URI 0x30 581 #define FN_X_WAP_INITIATOR_URI 0x31 582 #define FN_ACCEPT_APPLICATION 0x32 583 #define FN_BEARER_INDICATION 0x33 584 #define FN_PUSH_FLAG 0x34 585 #define FN_PROFILE 0x35 586 #define FN_PROFILE_DIFF 0x36 587 #define FN_PROFILE_WARNING 0x37 588 #define FN_EXPECT 0x38 589 #define FN_TE 0x39 590 #define FN_TRAILER 0x3A 591 #define FN_ACCEPT_CHARSET 0x3B /* encoding version 1.3 */ 592 #define FN_ACCEPT_ENCODING 0x3C /* encoding version 1.3 */ 593 #define FN_CACHE_CONTROL 0x3D /* encoding version 1.3 */ 594 #define FN_CONTENT_RANGE 0x3E /* encoding version 1.3 */ 595 #define FN_X_WAP_TOD 0x3F 596 #define FN_CONTENT_ID 0x40 597 #define FN_SET_COOKIE 0x41 598 #define FN_COOKIE 0x42 599 #define FN_ENCODING_VERSION 0x43 600 #define FN_PROFILE_WARNING14 0x44 /* encoding version 1.4 */ 601 #define FN_CONTENT_DISPOSITION14 0x45 /* encoding version 1.4 */ 602 #define FN_X_WAP_SECURITY 0x46 603 #define FN_CACHE_CONTROL14 0x47 /* encoding version 1.4 */ 604 #define FN_EXPECT15 0x48 /* encoding version 1.5 */ 605 #define FN_X_WAP_LOC_INVOCATION 0x49 606 #define FN_X_WAP_LOC_DELIVERY 0x4A 607 608 609 /* 610 * Openwave field names. 611 */ 612 #define FN_OPENWAVE_PROXY_PUSH_ADDR 0x00 613 #define FN_OPENWAVE_PROXY_PUSH_ACCEPT 0x01 614 #define FN_OPENWAVE_PROXY_PUSH_SEQ 0x02 615 #define FN_OPENWAVE_PROXY_NOTIFY 0x03 616 #define FN_OPENWAVE_PROXY_OPERATOR_DOMAIN 0x04 617 #define FN_OPENWAVE_PROXY_HOME_PAGE 0x05 618 #define FN_OPENWAVE_DEVCAP_HAS_COLOR 0x06 619 #define FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS 0x07 620 #define FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE 0x08 621 #define FN_OPENWAVE_DEVCAP_SCREEN_CHARS 0x09 622 #define FN_OPENWAVE_DEVCAP_SCREEN_PIXELS 0x0A 623 #define FN_OPENWAVE_DEVCAP_EM_SIZE 0x0B 624 #define FN_OPENWAVE_DEVCAP_SCREEN_DEPTH 0x0C 625 #define FN_OPENWAVE_DEVCAP_IMMED_ALERT 0x0D 626 #define FN_OPENWAVE_PROXY_NET_ASK 0x0E 627 #define FN_OPENWAVE_PROXY_UPLINK_VERSION 0x0F 628 #define FN_OPENWAVE_PROXY_TOD 0x10 629 #define FN_OPENWAVE_PROXY_BA_ENABLE 0x11 630 #define FN_OPENWAVE_PROXY_BA_REALM 0x12 631 #define FN_OPENWAVE_PROXY_REDIRECT_ENABLE 0x13 632 #define FN_OPENWAVE_PROXY_REQUEST_URI 0x14 633 #define FN_OPENWAVE_PROXY_REDIRECT_STATUS 0x15 634 #define FN_OPENWAVE_PROXY_TRANS_CHARSET 0x16 635 #define FN_OPENWAVE_PROXY_LINGER 0x17 636 #define FN_OPENWAVE_PROXY_CLIENT_ID 0x18 637 #define FN_OPENWAVE_PROXY_ENABLE_TRUST 0x19 638 #define FN_OPENWAVE_PROXY_TRUST_OLD 0x1A 639 #define FN_OPENWAVE_PROXY_TRUST 0x20 640 #define FN_OPENWAVE_PROXY_BOOKMARK 0x21 641 #define FN_OPENWAVE_DEVCAP_GUI 0x22 642 643 static const value_string vals_openwave_field_names[] = { 644 { FN_OPENWAVE_PROXY_PUSH_ADDR, "x-up-proxy-push-addr" }, 645 { FN_OPENWAVE_PROXY_PUSH_ACCEPT, "x-up-proxy-push-accept" }, 646 { FN_OPENWAVE_PROXY_PUSH_SEQ, "x-up-proxy-seq" }, 647 { FN_OPENWAVE_PROXY_NOTIFY, "x-up-proxy-notify" }, 648 { FN_OPENWAVE_PROXY_OPERATOR_DOMAIN, "x-up-proxy-operator-domain" }, 649 { FN_OPENWAVE_PROXY_HOME_PAGE, "x-up-proxy-home-page" }, 650 { FN_OPENWAVE_DEVCAP_HAS_COLOR, "x-up-devcap-has-color" }, 651 { FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS, "x-up-devcap-num-softkeys" }, 652 { FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE, "x-up-devcap-softkey-size" }, 653 { FN_OPENWAVE_DEVCAP_SCREEN_CHARS, "x-up-devcap-screen-chars" }, 654 { FN_OPENWAVE_DEVCAP_SCREEN_PIXELS, "x-up-devcap-screen-pixels" }, 655 { FN_OPENWAVE_DEVCAP_EM_SIZE, "x-up-devcap-em-size" }, 656 { FN_OPENWAVE_DEVCAP_SCREEN_DEPTH, "x-up-devcap-screen-depth" }, 657 { FN_OPENWAVE_DEVCAP_IMMED_ALERT, "x-up-devcap-immed-alert" }, 658 { FN_OPENWAVE_PROXY_NET_ASK, "x-up-proxy-net-ask" }, 659 { FN_OPENWAVE_PROXY_UPLINK_VERSION, "x-up-proxy-uplink-version" }, 660 { FN_OPENWAVE_PROXY_TOD, "x-up-proxy-tod" }, 661 { FN_OPENWAVE_PROXY_BA_ENABLE, "x-up-proxy-ba-enable" }, 662 { FN_OPENWAVE_PROXY_BA_REALM, "x-up-proxy-ba-realm" }, 663 { FN_OPENWAVE_PROXY_REDIRECT_ENABLE, "x-up-proxy-redirect-enable" }, 664 { FN_OPENWAVE_PROXY_REQUEST_URI, "x-up-proxy-request-uri" }, 665 { FN_OPENWAVE_PROXY_REDIRECT_STATUS, "x-up-proxy-redirect-status" }, 666 { FN_OPENWAVE_PROXY_TRANS_CHARSET, "x-up-proxy-trans-charset" }, 667 { FN_OPENWAVE_PROXY_LINGER, "x-up-proxy-linger" }, 668 { FN_OPENWAVE_PROXY_CLIENT_ID, "x-up-proxy-client-id" }, 669 { FN_OPENWAVE_PROXY_ENABLE_TRUST, "x-up-proxy-enable-trust" }, 670 { FN_OPENWAVE_PROXY_TRUST_OLD, "x-up-proxy-trust-old" }, 671 { FN_OPENWAVE_PROXY_TRUST, "x-up-proxy-trust" }, 672 { FN_OPENWAVE_PROXY_BOOKMARK, "x-up-proxy-bookmark" }, 673 { FN_OPENWAVE_DEVCAP_GUI, "x-up-devcap-gui" }, 674 { 0, NULL } 675 }; 676 static value_string_ext vals_openwave_field_names_ext = VALUE_STRING_EXT_INIT(vals_openwave_field_names); 677 678 static const value_string vals_field_names[] = { 679 { FN_ACCEPT, "Accept" }, 680 { FN_ACCEPT_CHARSET_DEP, "Accept-Charset (encoding 1.1)" }, 681 { FN_ACCEPT_ENCODING_DEP, "Accept-Encoding (encoding 1.1)" }, 682 { FN_ACCEPT_LANGUAGE, "Accept-Language" }, 683 { FN_ACCEPT_RANGES, "Accept-Ranges" }, 684 { FN_AGE, "Age" }, 685 { FN_ALLOW, "Allow" }, 686 { FN_AUTHORIZATION, "Authorization" }, 687 { FN_CACHE_CONTROL_DEP, "Cache-Control (encoding 1.1)" }, 688 { FN_CONNECTION, "Connection" }, 689 { FN_CONTENT_BASE, "Content-Base" }, 690 { FN_CONTENT_ENCODING, "Content-Encoding" }, 691 { FN_CONTENT_LANGUAGE, "Content-Language" }, 692 { FN_CONTENT_LENGTH, "Content-Length" }, 693 { FN_CONTENT_LOCATION, "Content-Location" }, 694 { FN_CONTENT_MD5, "Content-MD5" }, 695 { FN_CONTENT_RANGE_DEP, "Content-Range (encoding 1.1)" }, 696 { FN_CONTENT_TYPE, "Content-Type" }, 697 { FN_DATE, "Date" }, 698 { FN_ETAG, "ETag" }, 699 { FN_EXPIRES, "Expires" }, 700 { FN_FROM, "From" }, 701 { FN_HOST, "Host" }, 702 { FN_IF_MODIFIED_SINCE, "If-Modified-Since" }, 703 { FN_IF_MATCH, "If-Match" }, 704 { FN_IF_NONE_MATCH, "If-None-Match" }, 705 { FN_IF_RANGE, "If-Range" }, 706 { FN_IF_UNMODIFIED_SINCE, "If-Unmodified-Since" }, 707 { FN_LOCATION, "Location" }, 708 { FN_LAST_MODIFIED, "Last-Modified" }, 709 { FN_MAX_FORWARDS, "Max-Forwards" }, 710 { FN_PRAGMA, "Pragma" }, 711 { FN_PROXY_AUTHENTICATE, "Proxy-Authenticate" }, 712 { FN_PROXY_AUTHORIZATION, "Proxy-Authorization" }, 713 { FN_PUBLIC, "Public" }, 714 { FN_RANGE, "Range" }, 715 { FN_REFERER, "Referer" }, 716 { FN_RETRY_AFTER, "Retry-After" }, 717 { FN_SERVER, "Server" }, 718 { FN_TRANSFER_ENCODING, "Transfer-Encoding" }, 719 { FN_UPGRADE, "Upgrade" }, 720 { FN_USER_AGENT, "User-Agent" }, 721 { FN_VARY, "Vary" }, 722 { FN_VIA, "Via" }, 723 { FN_WARNING, "Warning" }, 724 { FN_WWW_AUTHENTICATE, "WWW-Authenticate" }, 725 { FN_CONTENT_DISPOSITION, "Content-Disposition" }, 726 { FN_X_WAP_APPLICATION_ID, "X-Wap-Application-ID" }, 727 { FN_X_WAP_CONTENT_URI, "X-Wap-Content-URI" }, 728 { FN_X_WAP_INITIATOR_URI, "X-Wap-Initiator-URI" }, 729 { FN_ACCEPT_APPLICATION, "Accept-Application" }, 730 { FN_BEARER_INDICATION, "Bearer-Indication" }, 731 { FN_PUSH_FLAG, "Push-Flag" }, 732 { FN_PROFILE, "Profile" }, 733 { FN_PROFILE_DIFF, "Profile-Diff" }, 734 { FN_PROFILE_WARNING, "Profile-Warning" }, 735 { FN_EXPECT, "Expect" }, 736 { FN_TE, "TE" }, 737 { FN_TRAILER, "Trailer" }, 738 { FN_ACCEPT_CHARSET, "Accept-Charset" }, 739 { FN_ACCEPT_ENCODING, "Accept-Encoding" }, 740 { FN_CACHE_CONTROL, "Cache-Control" }, 741 { FN_CONTENT_RANGE, "Content-Range" }, 742 { FN_X_WAP_TOD, "X-Wap-Tod" }, 743 { FN_CONTENT_ID, "Content-ID" }, 744 { FN_SET_COOKIE, "Set-Cookie" }, 745 { FN_COOKIE, "Cookie" }, 746 { FN_ENCODING_VERSION, "Encoding-Version" }, 747 { FN_PROFILE_WARNING14, "Profile-Warning (encoding 1.4)" }, 748 { FN_CONTENT_DISPOSITION14,"Content-Disposition (encoding 1.4)" }, 749 { FN_X_WAP_SECURITY, "X-WAP-Security" }, 750 { FN_CACHE_CONTROL14, "Cache-Control (encoding 1.4)" }, 751 /* encoding-version 1.5 */ 752 { FN_EXPECT15, "Expect (encoding 1.5)" }, 753 { FN_X_WAP_LOC_INVOCATION, "X-Wap-Loc-Invocation" }, 754 { FN_X_WAP_LOC_DELIVERY, "X-Wap-Loc-Delivery" }, 755 { 0, NULL } 756 }; 757 static value_string_ext vals_field_names_ext = VALUE_STRING_EXT_INIT(vals_field_names); 758 759 /* 760 * Bearer types (from the WDP specification). 761 */ 762 #define BT_IPv4 0x00 763 #define BT_IPv6 0x01 764 #define BT_GSM_USSD 0x02 765 #define BT_GSM_SMS 0x03 766 #define BT_ANSI_136_GUTS 0x04 767 #define BT_IS_95_SMS 0x05 768 #define BT_IS_95_CSD 0x06 769 #define BT_IS_95_PACKET_DATA 0x07 770 #define BT_ANSI_136_CSD 0x08 771 #define BT_ANSI_136_PACKET_DATA 0x09 772 #define BT_GSM_CSD 0x0A 773 #define BT_GSM_GPRS 0x0B 774 #define BT_GSM_USSD_IPv4 0x0C 775 #define BT_AMPS_CDPD 0x0D 776 #define BT_PDC_CSD 0x0E 777 #define BT_PDC_PACKET_DATA 0x0F 778 #define BT_IDEN_SMS 0x10 779 #define BT_IDEN_CSD 0x11 780 #define BT_IDEN_PACKET_DATA 0x12 781 #define BT_PAGING_FLEX 0x13 782 #define BT_PHS_SMS 0x14 783 #define BT_PHS_CSD 0x15 784 #define BT_GSM_USSD_GSM_SC 0x16 785 #define BT_TETRA_SDS_ITSI 0x17 786 #define BT_TETRA_SDS_MSISDN 0x18 787 #define BT_TETRA_PACKET_DATA 0x19 788 #define BT_PAGING_REFLEX 0x1A 789 #define BT_GSM_USSD_MSISDN 0x1B 790 #define BT_MOBITEX_MPAK 0x1C 791 #define BT_ANSI_136_GHOST 0x1D 792 793 static const value_string vals_bearer_types[] = { 794 { BT_IPv4, "IPv4" }, 795 { BT_IPv6, "IPv6" }, 796 { BT_GSM_USSD, "GSM USSD" }, 797 { BT_GSM_SMS, "GSM SMS" }, 798 { BT_ANSI_136_GUTS, "ANSI-136 GUTS/R-Data" }, 799 { BT_IS_95_SMS, "IS-95 CDMA SMS" }, 800 { BT_IS_95_CSD, "IS-95 CDMA CSD" }, 801 { BT_IS_95_PACKET_DATA, "IS-95 CDMA Packet data" }, 802 { BT_ANSI_136_CSD, "ANSI-136 CSD" }, 803 { BT_ANSI_136_PACKET_DATA, "ANSI-136 Packet data" }, 804 { BT_GSM_CSD, "GSM CSD" }, 805 { BT_GSM_GPRS, "GSM GPRS" }, 806 { BT_GSM_USSD_IPv4, "GSM USSD (IPv4 addresses)" }, 807 { BT_AMPS_CDPD, "AMPS CDPD" }, 808 { BT_PDC_CSD, "PDC CSD" }, 809 { BT_PDC_PACKET_DATA, "PDC Packet data" }, 810 { BT_IDEN_SMS, "IDEN SMS" }, 811 { BT_IDEN_CSD, "IDEN CSD" }, 812 { BT_IDEN_PACKET_DATA, "IDEN Packet data" }, 813 { BT_PAGING_FLEX, "Paging network FLEX(TM)" }, 814 { BT_PHS_SMS, "PHS SMS" }, 815 { BT_PHS_CSD, "PHS CSD" }, 816 { BT_GSM_USSD_GSM_SC, "GSM USSD (GSM Service Code addresses)" }, 817 { BT_TETRA_SDS_ITSI, "TETRA SDS (ITSI addresses)" }, 818 { BT_TETRA_SDS_MSISDN, "TETRA SDS (MSISDN addresses)" }, 819 { BT_TETRA_PACKET_DATA, "TETRA Packet data" }, 820 { BT_PAGING_REFLEX, "Paging network ReFLEX(TM)" }, 821 { BT_GSM_USSD_MSISDN, "GSM USSD (MSISDN addresses)" }, 822 { BT_MOBITEX_MPAK, "Mobitex MPAK" }, 823 { BT_ANSI_136_GHOST, "ANSI-136 GHOST/R-Data" }, 824 { 0, NULL } 825 }; 826 static value_string_ext vals_bearer_types_ext = VALUE_STRING_EXT_INIT(vals_bearer_types); 827 828 static const value_string vals_content_types[] = { 829 /* Well-known media types */ 830 /* XXX: hack: "..." "..." used to define several strings so that checkAPIs & etc won't see a 'start of comment' */ 831 { 0x00, "*" "/" "*" }, 832 { 0x01, "text/" "*" }, 833 { 0x02, "text/html" }, 834 { 0x03, "text/plain" }, 835 { 0x04, "text/x-hdml" }, 836 { 0x05, "text/x-ttml" }, 837 { 0x06, "text/x-vCalendar" }, 838 { 0x07, "text/x-vCard" }, 839 { 0x08, "text/vnd.wap.wml" }, 840 { 0x09, "text/vnd.wap.wmlscript" }, 841 { 0x0A, "text/vnd.wap.channel" }, 842 { 0x0B, "multipart/" "*" }, 843 { 0x0C, "multipart/mixed" }, 844 { 0x0D, "multipart/form-data" }, 845 { 0x0E, "multipart/byteranges" }, 846 { 0x0F, "multipart/alternative" }, 847 { 0x10, "application/" "*" }, 848 { 0x11, "application/java-vm" }, 849 { 0x12, "application/x-www-form-urlencoded" }, 850 { 0x13, "application/x-hdmlc" }, 851 { 0x14, "application/vnd.wap.wmlc" }, 852 { 0x15, "application/vnd.wap.wmlscriptc" }, 853 { 0x16, "application/vnd.wap.channelc" }, 854 { 0x17, "application/vnd.wap.uaprof" }, 855 { 0x18, "application/vnd.wap.wtls-ca-certificate" }, 856 { 0x19, "application/vnd.wap.wtls-user-certificate" }, 857 { 0x1A, "application/x-x509-ca-cert" }, 858 { 0x1B, "application/x-x509-user-cert" }, 859 { 0x1C, "image/" "*" }, 860 { 0x1D, "image/gif" }, 861 { 0x1E, "image/jpeg" }, 862 { 0x1F, "image/tiff" }, 863 { 0x20, "image/png" }, 864 { 0x21, "image/vnd.wap.wbmp" }, 865 { 0x22, "application/vnd.wap.multipart.*" }, 866 { 0x23, "application/vnd.wap.multipart.mixed" }, 867 { 0x24, "application/vnd.wap.multipart.form-data" }, 868 { 0x25, "application/vnd.wap.multipart.byteranges" }, 869 { 0x26, "application/vnd.wap.multipart.alternative" }, 870 { 0x27, "application/xml" }, 871 { 0x28, "text/xml" }, 872 { 0x29, "application/vnd.wap.wbxml" }, 873 { 0x2A, "application/x-x968-cross-cert" }, 874 { 0x2B, "application/x-x968-ca-cert" }, 875 { 0x2C, "application/x-x968-user-cert" }, 876 { 0x2D, "text/vnd.wap.si" }, 877 { 0x2E, "application/vnd.wap.sic" }, 878 { 0x2F, "text/vnd.wap.sl" }, 879 { 0x30, "application/vnd.wap.slc" }, 880 { 0x31, "text/vnd.wap.co" }, 881 { 0x32, "application/vnd.wap.coc" }, 882 { 0x33, "application/vnd.wap.multipart.related" }, 883 { 0x34, "application/vnd.wap.sia" }, 884 { 0x35, "text/vnd.wap.connectivity-xml" }, 885 { 0x36, "application/vnd.wap.connectivity-wbxml" }, 886 { 0x37, "application/pkcs7-mime" }, 887 { 0x38, "application/vnd.wap.hashed-certificate" }, 888 { 0x39, "application/vnd.wap.signed-certificate" }, 889 { 0x3A, "application/vnd.wap.cert-response" }, 890 { 0x3B, "application/xhtml+xml" }, 891 { 0x3C, "application/wml+xml" }, 892 { 0x3D, "text/css" }, 893 { 0x3E, "application/vnd.wap.mms-message" }, 894 { 0x3F, "application/vnd.wap.rollover-certificate" }, 895 { 0x40, "application/vnd.wap.locc+wbxml"}, 896 { 0x41, "application/vnd.wap.loc+xml"}, 897 { 0x42, "application/vnd.syncml.dm+wbxml"}, 898 { 0x43, "application/vnd.syncml.dm+xml"}, 899 { 0x44, "application/vnd.syncml.notification"}, 900 { 0x45, "application/vnd.wap.xhtml+xml"}, 901 { 0x46, "application/vnd.wv.csp.cir"}, 902 { 0x47, "application/vnd.oma.dd+xml"}, 903 { 0x48, "application/vnd.oma.drm.message"}, 904 { 0x49, "application/vnd.oma.drm.content"}, 905 { 0x4A, "application/vnd.oma.drm.rights+xml"}, 906 { 0x4B, "application/vnd.oma.drm.rights+wbxml"}, 907 { 0x4C, "application/vnd.wv.csp+xml"}, 908 { 0x4D, "application/vnd.wv.csp+wbxml"}, 909 { 0x5A, "application/octet-stream"}, 910 /* The following media types are registered by 3rd parties */ 911 { 0x0201, "application/vnd.uplanet.cachop-wbxml" }, 912 { 0x0202, "application/vnd.uplanet.signal" }, 913 { 0x0203, "application/vnd.uplanet.alert-wbxml" }, 914 { 0x0204, "application/vnd.uplanet.list-wbxml" }, 915 { 0x0205, "application/vnd.uplanet.listcmd-wbxml" }, 916 { 0x0206, "application/vnd.uplanet.channel-wbxml" }, 917 { 0x0207, "application/vnd.uplanet.provisioning-status-uri" }, 918 { 0x0208, "x-wap.multipart/vnd.uplanet.header-set" }, 919 { 0x0209, "application/vnd.uplanet.bearer-choice-wbxml" }, 920 { 0x020A, "application/vnd.phonecom.mmc-wbxml" }, 921 { 0x020B, "application/vnd.nokia.syncset+wbxml" }, 922 { 0x020C, "image/x-up-wpng"}, 923 { 0x0300, "application/iota.mmc-wbxml"}, 924 { 0x0301, "application/iota.mmc-xml"}, 925 { 0x00, NULL } 926 }; 927 static value_string_ext vals_content_types_ext = VALUE_STRING_EXT_INIT(vals_content_types); 928 929 static const value_string vals_languages[] = { 930 { 0x00, "*" }, 931 { 0x01, "Afar (aa)" }, 932 { 0x02, "Abkhazian (ab)" }, 933 { 0x03, "Afrikaans (af)" }, 934 { 0x04, "Amharic (am)" }, 935 { 0x05, "Arabic (ar)" }, 936 { 0x06, "Assamese (as)" }, 937 { 0x07, "Aymara (ay)" }, 938 { 0x08, "Azerbaijani (az)" }, 939 { 0x09, "Bashkir (ba)" }, 940 { 0x0A, "Byelorussian (be)" }, 941 { 0x0B, "Bulgarian (bg)" }, 942 { 0x0C, "Bihari (bh)" }, 943 { 0x0D, "Bislama (bi)" }, 944 { 0x0E, "Bengali; Bangla (bn)" }, 945 { 0x0F, "Tibetan (bo)" }, 946 { 0x10, "Breton (br)" }, 947 { 0x11, "Catalan (ca)" }, 948 { 0x12, "Corsican (co)" }, 949 { 0x13, "Czech (cs)" }, 950 { 0x14, "Welsh (cy)" }, 951 { 0x15, "Danish (da)" }, 952 { 0x16, "German (de)" }, 953 { 0x17, "Bhutani (dz)" }, 954 { 0x18, "Greek (el)" }, 955 { 0x19, "English (en)" }, 956 { 0x1A, "Esperanto (eo)" }, 957 { 0x1B, "Spanish (es)" }, 958 { 0x1C, "Estonian (et)" }, 959 { 0x1D, "Basque (eu)" }, 960 { 0x1E, "Persian (fa)" }, 961 { 0x1F, "Finnish (fi)" }, 962 { 0x20, "Fiji (fj)" }, 963 { 0x21, "Urdu (ur)" }, 964 { 0x22, "French (fr)" }, 965 { 0x23, "Uzbek (uz)" }, 966 { 0x24, "Irish (ga)" }, 967 { 0x25, "Scots Gaelic (gd)" }, 968 { 0x26, "Galician (gl)" }, 969 { 0x27, "Guarani (gn)" }, 970 { 0x28, "Gujarati (gu)" }, 971 { 0x29, "Hausa (ha)" }, 972 { 0x2A, "Hebrew (formerly iw) (he)" }, 973 { 0x2B, "Hindi (hi)" }, 974 { 0x2C, "Croatian (hr)" }, 975 { 0x2D, "Hungarian (hu)" }, 976 { 0x2E, "Armenian (hy)" }, 977 { 0x2F, "Vietnamese (vi)" }, 978 { 0x30, "Indonesian (formerly in) (id)" }, 979 { 0x31, "Wolof (wo)" }, 980 { 0x32, "Xhosa (xh)" }, 981 { 0x33, "Icelandic (is)" }, 982 { 0x34, "Italian (it)" }, 983 { 0x35, "Yoruba (yo)" }, 984 { 0x36, "Japanese (ja)" }, 985 { 0x37, "Javanese (jw)" }, 986 { 0x38, "Georgian (ka)" }, 987 { 0x39, "Kazakh (kk)" }, 988 { 0x3A, "Zhuang (za)" }, 989 { 0x3B, "Cambodian (km)" }, 990 { 0x3C, "Kannada (kn)" }, 991 { 0x3D, "Korean (ko)" }, 992 { 0x3E, "Kashmiri (ks)" }, 993 { 0x3F, "Kurdish (ku)" }, 994 { 0x40, "Kirghiz (ky)" }, 995 { 0x41, "Chinese (zh)" }, 996 { 0x42, "Lingala (ln)" }, 997 { 0x43, "Laothian (lo)" }, 998 { 0x44, "Lithuanian (lt)" }, 999 { 0x45, "Latvian, Lettish (lv)" }, 1000 { 0x46, "Malagasy (mg)" }, 1001 { 0x47, "Maori (mi)" }, 1002 { 0x48, "Macedonian (mk)" }, 1003 { 0x49, "Malayalam (ml)" }, 1004 { 0x4A, "Mongolian (mn)" }, 1005 { 0x4B, "Moldavian (mo)" }, 1006 { 0x4C, "Marathi (mr)" }, 1007 { 0x4D, "Malay (ms)" }, 1008 { 0x4E, "Maltese (mt)" }, 1009 { 0x4F, "Burmese (my)" }, 1010 { 0x50, "Ukrainian (uk)" }, 1011 { 0x51, "Nepali (ne)" }, 1012 { 0x52, "Dutch (nl)" }, 1013 { 0x53, "Norwegian (no)" }, 1014 { 0x54, "Occitan (oc)" }, 1015 { 0x55, "(Afan) Oromo (om)" }, 1016 { 0x56, "Oriya (or)" }, 1017 { 0x57, "Punjabi (pa)" }, 1018 { 0x58, "Polish (po)" }, 1019 { 0x59, "Pashto, Pushto (ps)" }, 1020 { 0x5A, "Portuguese (pt)" }, 1021 { 0x5B, "Quechua (qu)" }, 1022 { 0x5C, "Zulu (zu)" }, 1023 { 0x5D, "Kirundi (rn)" }, 1024 { 0x5E, "Romanian (ro)" }, 1025 { 0x5F, "Russian (ru)" }, 1026 { 0x60, "Kinyarwanda (rw)" }, 1027 { 0x61, "Sanskrit (sa)" }, 1028 { 0x62, "Sindhi (sd)" }, 1029 { 0x63, "Sangho (sg)" }, 1030 { 0x64, "Serbo-Croatian (sh)" }, 1031 { 0x65, "Sinhalese (si)" }, 1032 { 0x66, "Slovak (sk)" }, 1033 { 0x67, "Slovenian (sl)" }, 1034 { 0x68, "Samoan (sm)" }, 1035 { 0x69, "Shona (sn)" }, 1036 { 0x6A, "Somali (so)" }, 1037 { 0x6B, "Albanian (sq)" }, 1038 { 0x6C, "Serbian (sr)" }, 1039 { 0x6D, "Siswati (ss)" }, 1040 { 0x6E, "Sesotho (st)" }, 1041 { 0x6F, "Sundanese (su)" }, 1042 { 0x70, "Swedish (sv)" }, 1043 { 0x71, "Swahili (sw)" }, 1044 { 0x72, "Tamil (ta)" }, 1045 { 0x73, "Telugu (te)" }, 1046 { 0x74, "Tajik (tg)" }, 1047 { 0x75, "Thai (th)" }, 1048 { 0x76, "Tigrinya (ti)" }, 1049 { 0x77, "Turkmen (tk)" }, 1050 { 0x78, "Tagalog (tl)" }, 1051 { 0x79, "Setswana (tn)" }, 1052 { 0x7A, "Tonga (to)" }, 1053 { 0x7B, "Turkish (tr)" }, 1054 { 0x7C, "Tsonga (ts)" }, 1055 { 0x7D, "Tatar (tt)" }, 1056 { 0x7E, "Twi (tw)" }, 1057 { 0x7F, "Uighur (ug)" }, 1058 { 0x81, "Nauru (na)" }, 1059 { 0x82, "Faeroese (fo)" }, 1060 { 0x83, "Frisian (fy)" }, 1061 { 0x84, "Interlingua (ia)" }, 1062 { 0x85, "Volapuk (vo)" }, 1063 { 0x86, "Interlingue (ie)" }, 1064 { 0x87, "Inupiak (ik)" }, 1065 { 0x88, "Yiddish (formerly ji) (yi)" }, 1066 { 0x89, "Inuktitut (iu)" }, 1067 { 0x8A, "Greenlandic (kl)" }, 1068 { 0x8B, "Latin (la)" }, 1069 { 0x8C, "Rhaeto-Romance (rm)" }, 1070 { 0x00, NULL } 1071 }; 1072 static value_string_ext vals_languages_ext = VALUE_STRING_EXT_INIT(vals_languages); 1073 1074 1075 #define CACHE_CONTROL_NO_CACHE 0x00 1076 #define CACHE_CONTROL_NO_STORE 0x01 1077 #define CACHE_CONTROL_MAX_AGE 0x02 1078 #define CACHE_CONTROL_MAX_STALE 0x03 1079 #define CACHE_CONTROL_MIN_FRESH 0x04 1080 #define CACHE_CONTROL_ONLY_IF_CACHED 0x05 1081 #define CACHE_CONTROL_PUBLIC 0x06 1082 #define CACHE_CONTROL_PRIVATE 0x07 1083 #define CACHE_CONTROL_NO_TRANSFORM 0x08 1084 #define CACHE_CONTROL_MUST_REVALIDATE 0x09 1085 #define CACHE_CONTROL_PROXY_REVALIDATE 0x0A 1086 #define CACHE_CONTROL_S_MAXAGE 0x0B 1087 1088 static const value_string vals_cache_control[] = { 1089 { CACHE_CONTROL_NO_CACHE, "no-cache" }, 1090 { CACHE_CONTROL_NO_STORE, "no-store" }, 1091 { CACHE_CONTROL_MAX_AGE, "max-age" }, 1092 { CACHE_CONTROL_MAX_STALE, "max-stale" }, 1093 { CACHE_CONTROL_MIN_FRESH, "min-fresh" }, 1094 { CACHE_CONTROL_ONLY_IF_CACHED, "only-if-cached" }, 1095 { CACHE_CONTROL_PUBLIC, "public" }, 1096 { CACHE_CONTROL_PRIVATE, "private" }, 1097 { CACHE_CONTROL_NO_TRANSFORM, "no-transform" }, 1098 { CACHE_CONTROL_MUST_REVALIDATE, "must-revalidate" }, 1099 { CACHE_CONTROL_PROXY_REVALIDATE, "proxy-revalidate" }, 1100 { CACHE_CONTROL_S_MAXAGE, "s-max-age" }, 1101 1102 { 0x00, NULL } 1103 }; 1104 static value_string_ext vals_cache_control_ext = VALUE_STRING_EXT_INIT(vals_cache_control); 1105 1106 static const value_string vals_wap_application_ids[] = { 1107 /* Well-known WAP applications */ 1108 { 0x0000, "x-wap-application:*"}, 1109 { 0x0001, "x-wap-application:push.sia"}, 1110 { 0x0002, "x-wap-application:wml.ua"}, 1111 { 0x0003, "x-wap-application:wta.ua"}, 1112 { 0x0004, "x-wap-application:mms.ua"}, 1113 { 0x0005, "x-wap-application:push.syncml"}, 1114 { 0x0006, "x-wap-application:loc.ua"}, 1115 { 0x0007, "x-wap-application:syncml.dm"}, 1116 { 0x0008, "x-wap-application:drm.ua"}, 1117 { 0x0009, "x-wap-application:emn.ua"}, 1118 { 0x000A, "x-wap-application:wv.ua"}, 1119 { 0x001A, "x-wap-application:lwm2m.dm"}, 1120 /* Registered by 3rd parties */ 1121 { 0x8000, "x-wap-microsoft:localcontent.ua"}, 1122 { 0x8001, "x-wap-microsoft:IMclient.ua"}, 1123 { 0x8002, "x-wap-docomo:imode.mail.ua"}, 1124 { 0x8003, "x-wap-docomo:imode.mr.ua"}, 1125 { 0x8004, "x-wap-docomo:imode.mf.ua"}, 1126 { 0x8005, "x-motorola:location.ua"}, 1127 { 0x8006, "x-motorola:now.ua"}, 1128 { 0x8007, "x-motorola:otaprov.ua"}, 1129 { 0x8008, "x-motorola:browser.ua"}, 1130 { 0x8009, "x-motorola:splash.ua"}, 1131 /* 0x800A: unassigned */ 1132 { 0x800B, "x-wap-nai:mvsw.command"}, 1133 /* 0x800C -- 0x800F: unassigned */ 1134 { 0x8010, "x-wap-openwave:iota.ua"}, 1135 /* 0x8011 -- 0x8FFF: unassigned */ 1136 { 0x9000, "x-wap-docomo:imode.mail2.ua"}, 1137 { 0x9001, "x-oma-nec:otaprov.ua"}, 1138 { 0x9002, "x-oma-nokia:call.ua"}, 1139 { 0x9003, "x-oma-coremobility:sqa.ua"}, 1140 1141 { 0x00, NULL } 1142 }; 1143 static value_string_ext vals_wap_application_ids_ext = VALUE_STRING_EXT_INIT(vals_wap_application_ids); 1144 1145 1146 /* Parameters and well-known encodings */ 1147 static const value_string vals_wsp_parameter_sec[] = { 1148 { 0x00, "NETWPIN" }, 1149 { 0x01, "USERPIN" }, 1150 { 0x02, "USERNETWPIN" }, 1151 { 0x03, "USERPINMAC" }, 1152 1153 { 0x00, NULL } 1154 }; 1155 static value_string_ext vals_wsp_parameter_sec_ext = VALUE_STRING_EXT_INIT(vals_wsp_parameter_sec); 1156 1157 /* Warning codes and mappings */ 1158 static const value_string vals_wsp_warning_code[] = { 1159 { 10, "110 Response is stale" }, 1160 { 11, "111 Revalidation failed" }, 1161 { 12, "112 Disconnected operation" }, 1162 { 13, "113 Heuristic expiration" }, 1163 { 14, "214 Transformation applied" }, 1164 { 99, "199/299 Miscellaneous warning" }, 1165 1166 { 0, NULL } 1167 }; 1168 static value_string_ext vals_wsp_warning_code_ext = VALUE_STRING_EXT_INIT(vals_wsp_warning_code); 1169 1170 static const value_string vals_wsp_warning_code_short[] = { 1171 { 10, "110" }, 1172 { 11, "111" }, 1173 { 12, "112" }, 1174 { 13, "113" }, 1175 { 14, "214" }, 1176 { 99, "199/299" }, 1177 1178 { 0, NULL } 1179 }; 1180 static value_string_ext vals_wsp_warning_code_short_ext = VALUE_STRING_EXT_INIT(vals_wsp_warning_code_short); 1181 1182 /* Profile-Warning codes - see http://www.w3.org/TR/NOTE-CCPPexchange */ 1183 static const value_string vals_wsp_profile_warning_code[] = { 1184 { 0x10, "100 OK" }, 1185 { 0x11, "101 Used stale profile" }, 1186 { 0x12, "102 Not used profile" }, 1187 { 0x20, "200 Not applied" }, 1188 { 0x21, "101 Content selection applied" }, 1189 { 0x22, "202 Content generation applied" }, 1190 { 0x23, "203 Transformation applied" }, 1191 1192 { 0x00, NULL } 1193 }; 1194 static value_string_ext vals_wsp_profile_warning_code_ext = VALUE_STRING_EXT_INIT(vals_wsp_profile_warning_code); 1195 1196 /* Well-known TE values */ 1197 static const value_string vals_well_known_te[] = { 1198 { 0x82, "chunked" }, 1199 { 0x83, "identity" }, 1200 { 0x84, "gzip" }, 1201 { 0x85, "compress" }, 1202 { 0x86, "deflate" }, 1203 1204 { 0x00, NULL } 1205 }; 1206 static value_string_ext vals_well_known_te_ext = VALUE_STRING_EXT_INIT(vals_well_known_te); 1207 1208 1209 /* 1210 * Redirect flags. 1211 */ 1212 #define PERMANENT_REDIRECT 0x80 1213 #define REUSE_SECURITY_SESSION 0x40 1214 1215 /* 1216 * Redirect address flags and length. 1217 */ 1218 #define BEARER_TYPE_INCLUDED 0x80 1219 #define PORT_NUMBER_INCLUDED 0x40 1220 #define ADDRESS_LEN 0x3f 1221 1222 static const value_string vals_false_true[] = { 1223 { 0, "False" }, 1224 { 1, "True" }, 1225 { 0, NULL } 1226 }; 1227 1228 enum { 1229 WSP_PDU_RESERVED = 0x00, 1230 WSP_PDU_CONNECT = 0x01, 1231 WSP_PDU_CONNECTREPLY = 0x02, 1232 WSP_PDU_REDIRECT = 0x03, /* No sample data */ 1233 WSP_PDU_REPLY = 0x04, 1234 WSP_PDU_DISCONNECT = 0x05, 1235 WSP_PDU_PUSH = 0x06, /* No sample data */ 1236 WSP_PDU_CONFIRMEDPUSH = 0x07, /* No sample data */ 1237 WSP_PDU_SUSPEND = 0x08, /* No sample data */ 1238 WSP_PDU_RESUME = 0x09, /* No sample data */ 1239 1240 WSP_PDU_GET = 0x40, 1241 WSP_PDU_OPTIONS = 0x41, /* No sample data */ 1242 WSP_PDU_HEAD = 0x42, /* No sample data */ 1243 WSP_PDU_DELETE = 0x43, /* No sample data */ 1244 WSP_PDU_TRACE = 0x44, /* No sample data */ 1245 1246 WSP_PDU_POST = 0x60, 1247 WSP_PDU_PUT = 0x61 /* No sample data */ 1248 }; 1249 1250 1251 /* Dissector tables for handoff */ 1252 static dissector_table_t media_type_table; 1253 static heur_dissector_list_t heur_subdissector_list; 1254 1255 static void add_uri (proto_tree *, packet_info *, tvbuff_t *, guint, guint, proto_item *); 1256 1257 static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint); 1258 static void add_multipart_data (proto_tree *, tvbuff_t *, packet_info *pinfo); 1259 1260 static void add_capabilities (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint8 pdu_type); 1261 1262 1263 /* 1264 * Dissect the WSP header part. 1265 * This function calls wkh_XXX functions that dissect well-known headers. 1266 */ 1267 static void add_headers (proto_tree *tree, tvbuff_t *tvb, int hf, packet_info *pinfo); 1268 1269 /* The following macros define WSP basic data structures as found 1270 * in the ABNF notation of WSP headers. 1271 * Currently all text data types are mapped to text_string. 1272 */ 1273 #define is_short_integer(x) ( (x) & 0x80 ) 1274 #define is_long_integer(x) ( (x) <= 30 ) 1275 #define is_date_value(x) is_long_integer(x) 1276 #define is_integer_value(x) (is_short_integer(x) || is_long_integer(x)) 1277 #define is_delta_seconds_value(x) is_integer_value(x) 1278 /* Text string == *TEXT 0x00, thus also an empty string matches the rule! */ 1279 #define is_text_string(x) ( ((x) == 0) || ( ((x) >= 32) && ((x) <= 127)) ) 1280 #define is_quoted_string(x) ( (x) == 0x22 ) /* " */ 1281 #define is_token_text(x) is_text_string(x) 1282 #define is_text_value(x) is_text_string(x) 1283 #define is_uri_value(x) is_text_string(x) 1284 1285 #define get_uintvar_integer(val,tvb,start,len,ok) \ 1286 val = tvb_get_guintvar(tvb,start,&len, pinfo, &ei_wsp_oversized_uintvar); \ 1287 if (len>5 || len==0) ok = FALSE; else ok = TRUE; 1288 #define get_short_integer(val,tvb,start,len,ok) \ 1289 val = tvb_get_guint8(tvb,start); \ 1290 if (val & 0x80) ok = TRUE; else ok=FALSE; \ 1291 val &= 0x7F; len = 1; 1292 #define get_long_integer(val,tvb,start,len,ok) \ 1293 len = tvb_get_guint8(tvb,start); \ 1294 ok = TRUE; /* Valid lengths for us are 1-4 */ \ 1295 if (len==1) { val = tvb_get_guint8(tvb,start+1); } \ 1296 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \ 1297 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \ 1298 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \ 1299 else ok = FALSE; \ 1300 len++; /* Add the 1st octet to the length */ 1301 #define get_integer_value(val,tvb,start,len,ok) \ 1302 len = tvb_get_guint8(tvb,start); \ 1303 ok = TRUE; \ 1304 if (len & 0x80) { val = len & 0x7F; len = 0; } \ 1305 else if (len==1) { val = tvb_get_guint8(tvb,start+1); } \ 1306 else if (len==2) { val = tvb_get_ntohs(tvb,start+1); } \ 1307 else if (len==3) { val = tvb_get_ntoh24(tvb,start+1); } \ 1308 else if (len==4) { val = tvb_get_ntohl(tvb,start+1); } \ 1309 else ok = FALSE; \ 1310 len++; /* Add the 1st octet to the length */ 1311 #define get_date_value(val,tvb,start,len,ok) \ 1312 get_long_integer(val,tvb,start,len,ok) 1313 #define get_delta_seconds_value(val,tvb,start,len,ok) \ 1314 get_integer_value(val,tvb,start,len,ok) 1315 1316 /* NOTE - Do NOT call g_free() for the str returned after using it because the 1317 * get_text_string() macro now returns wmem_alloc'd memory. */ 1318 #define get_text_string(str,tvb,start,len,ok) \ 1319 if (is_text_string(tvb_get_guint8(tvb,start))) { \ 1320 str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb,start,(gint *)&len,ENC_ASCII); \ 1321 ok = TRUE; \ 1322 } else { len = 0; str = NULL; ok = FALSE; } 1323 #define get_token_text(str,tvb,start,len,ok) \ 1324 get_text_string(str,tvb,start,len,ok) 1325 #define get_extension_media(str,tvb,start,len,ok) \ 1326 get_text_string(str,tvb,start,len,ok) 1327 #define get_text_value(str,tvb,start,len,ok) \ 1328 get_text_string(str,tvb,start,len,ok) 1329 #define get_quoted_string(str,tvb,start,len,ok) \ 1330 get_text_string(str,tvb,start,len,ok) 1331 #define get_uri_value(str,tvb,start,len,ok) \ 1332 get_text_string(str,tvb,start,len,ok) 1333 1334 #define get_version_value(val,str,tvb,start,len,ok) \ 1335 val = tvb_get_guint8(tvb,start); \ 1336 ok = TRUE; \ 1337 if (val & 0x80) { /* High nibble "." Low nibble */ \ 1338 len = 1; \ 1339 val &= 0x7F; \ 1340 str = wmem_strdup_printf(wmem_packet_scope(), "%u.%u", val >> 4, val & 0x0F); \ 1341 } else { get_text_string(str,tvb,start,len,ok); } 1342 1343 /* Parameter parser */ 1344 static int 1345 parameter (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start, int len); 1346 static int 1347 parameter_value_q (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start); 1348 1349 /* The following macros hide common processing for all well-known headers 1350 * and shortens the code to be written in a wkh_XXX() function. 1351 * Even declarations are hidden by a macro. 1352 * 1353 * Define a wkh_XXX() function as follows: 1354 * 1355 * static guint32 1356 * wkh_XXX (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 1357 * { 1358 * wkh_0_Declarations; 1359 * << add other required declarations here >> 1360 * 1361 * wkh_1_WellKnownValue; 1362 * << add well-known value proto item here; don't forget to set the 1363 * ok variable to TRUE if parsing was correct >> 1364 * wkh_2_TextualValue; 1365 * << add textual value proto item here; don't forget to set the 1366 * ok variable to TRUE if parsing was correct >> 1367 * wkh_3_ValueWithLength; 1368 * << add custom code for value processing and value proto item here >> 1369 * 1370 * wkh_4_End(); 1371 * << This macro takes care of parse errors within the header value; 1372 * it requires the header field index if the header has not yet been 1373 * written to the protocol tree (ti == NULL). >> 1374 * } 1375 * 1376 * NOTE: You only need to write parsing code for the successful case, 1377 * Errors are automatically reported through the wkh_4_End() macro 1378 * when ok <> TRUE. 1379 */ 1380 1381 /* The following code is the generic template with which the value of a 1382 * well-known header can be processed. Not all sections yield a semantically 1383 * correct result, so appropriate error information must be provided. 1384 */ 1385 1386 1387 #define wkh_0a_Declarations /* Declarations for Parsing */ \ 1388 gboolean ok = FALSE; /* Triggers error notification code at end */ \ 1389 proto_tree *header_tree; /* base tree for all fields */ \ 1390 proto_item *header_item; /* base item for all fields */ \ 1391 guint32 val_start = hdr_start + 1; \ 1392 guint8 val_id = tvb_get_guint8 (tvb, val_start); \ 1393 guint32 offset = val_start; /* Offset to one past this header */ \ 1394 guint32 val_len; /* length for value with length field */ \ 1395 guint32 val_len_len /* length of length field */ 1396 1397 #define wkh_0_Declarations \ 1398 wkh_0a_Declarations; \ 1399 const gchar *val_str = NULL 1400 1401 #define wkh_1_WellKnownValue(hf_hdr, ett, header) /* Parse Well Known Value */ \ 1402 header_tree = proto_tree_add_subtree(tree, tvb, hdr_start, offset - hdr_start, ett, \ 1403 &header_item, header); \ 1404 proto_tree_add_item(header_tree, hf_hdr, tvb, hdr_start, 1, ENC_NA); \ 1405 if (val_id & 0x80) { /* Well-known value */ \ 1406 offset++; \ 1407 /* Well-known value processing starts HERE \ 1408 * \ 1409 * BEGIN */ 1410 1411 #define wkh_2_TextualValue /* Parse Textual Value */ \ 1412 /* END */ \ 1413 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \ 1414 val_str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (gint *)&val_len, ENC_ASCII); \ 1415 offset = val_start + val_len; \ 1416 /* Textual value processing starts HERE \ 1417 * \ 1418 * BEGIN */ 1419 1420 #define wkh_2_TextualValueInv /* Parse Textual Value */ \ 1421 /* END */ \ 1422 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \ 1423 /*val_str = (gchar *)*/tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (gint *)&val_len, ENC_ASCII); \ 1424 offset = val_start + val_len; \ 1425 /* Textual value processing starts HERE \ 1426 * \ 1427 * BEGIN */ 1428 1429 #define wkh_3_ValueWithLength /* Parse Value With Length */ \ 1430 /* END */ \ 1431 } else { /* val_start points to 1st byte of length field */ \ 1432 if (val_id == 0x1F) { /* Value Length = guintvar */ \ 1433 val_len = tvb_get_guintvar(tvb, val_start + 1, &val_len_len, pinfo, &ei_wsp_oversized_uintvar); \ 1434 val_len_len++; /* 0x1F length indicator byte */ \ 1435 } else { /* Short length followed by Len data octets */ \ 1436 val_len = tvb_get_guint8(tvb, offset); \ 1437 val_len_len = 1; \ 1438 } \ 1439 offset += val_len_len + val_len; \ 1440 /* Value with length processing starts HERE \ 1441 * The value lies between val_start and offset: \ 1442 * - Value Length: Start = val_start \ 1443 * Length = val_len_len \ 1444 * - Value Data : Start = val_start + val_len_len \ 1445 * Length = val_len \ 1446 * End = offset - 1 \ 1447 * BEGIN */ 1448 1449 #define wkh_4_End() /* End of value parsing */ \ 1450 /* END */ \ 1451 } \ 1452 /* Check for errors */ \ 1453 if (! ok) { \ 1454 expert_add_info(pinfo, header_item, &ei_wsp_header_invalid_value); \ 1455 } \ 1456 return offset; 1457 1458 1459 /* 1460 * This yields the following default header value parser function body 1461 */ 1462 static guint32 1463 wkh_default(proto_tree *tree, tvbuff_t *tvb, 1464 guint32 hdr_start, packet_info *pinfo _U_) 1465 { 1466 wkh_0_Declarations; 1467 guint8 hdr_id = tvb_get_guint8 (tvb, hdr_start) & 0x7F; 1468 1469 ok = TRUE; /* Bypass error checking as we don't parse the values! */ 1470 1471 wkh_1_WellKnownValue(hf_hdr_name_value, ett_default, "default"); 1472 proto_tree_add_uint_format(tree, hf_wsp_default_int, tvb, hdr_start, offset - hdr_start, 1473 val_id & 0x7F, "%s: (Undecoded well-known value 0x%02x)", 1474 val_to_str_ext (hdr_id, &vals_field_names_ext, 1475 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F); 1476 wkh_2_TextualValue; 1477 proto_tree_add_string_format(tree, hf_wsp_default_string, tvb, hdr_start, offset - hdr_start, 1478 "%s: %s", 1479 val_to_str_ext (hdr_id, &vals_field_names_ext, 1480 "<Unknown WSP header field 0x%02X>"), val_str); 1481 wkh_3_ValueWithLength; 1482 proto_tree_add_uint_format(tree, hf_wsp_default_val_len, tvb, hdr_start, offset - hdr_start, 1483 val_len, "%s: (Undecoded value in general form with length indicator)", 1484 val_to_str_ext (hdr_id, &vals_field_names_ext, 1485 "<Unknown WSP header field 0x%02X>")); 1486 1487 wkh_4_End(); /* The default parser has no associated hf_index; 1488 additionally the error code is always bypassed */ 1489 } 1490 1491 1492 /* Content-type processing uses the following common core: */ 1493 static guint32 1494 wkh_content_type_header(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name) 1495 { 1496 wkh_0_Declarations; 1497 guint32 off, val = 0, len; 1498 guint8 peek; 1499 proto_item *ti = NULL; 1500 proto_tree *parameter_tree = NULL; 1501 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Content type: %s", name); 1502 1503 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_type_header, header_name); 1504 proto_tree_add_string(header_tree, hf, tvb, val_start, 1, 1505 val_to_str_ext(val_id & 0x7F, &vals_content_types_ext, 1506 "(Unknown content type identifier 0x%X)")); 1507 proto_item_set_len(header_item, 2); 1508 ok = TRUE; 1509 wkh_2_TextualValue; 1510 /* Sometimes with a No-Content response, a NULL content type 1511 * is reported. Process this correctly! */ 1512 if (*val_str) { 1513 proto_tree_add_string(header_tree, hf, tvb, val_start, val_len, val_str); 1514 proto_item_set_len(header_item, val_len+1); 1515 } else { 1516 proto_tree_add_string(header_tree, hf, tvb, val_start, 0, 1517 "<no content type has been specified>"); 1518 proto_item_set_len(header_item, 2); 1519 } 1520 ok = TRUE; 1521 wkh_3_ValueWithLength; 1522 off = val_start + val_len_len; 1523 peek = tvb_get_guint8(tvb, off); 1524 if (is_text_string(peek)) { 1525 val_str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, off, (gint*)&len, ENC_ASCII); 1526 off += len; /* off now points to 1st byte after string */ 1527 ti = proto_tree_add_string (header_tree, hf, tvb, hdr_start, offset - hdr_start, val_str); 1528 } else if (is_integer_value(peek)) { 1529 get_integer_value(val, tvb, off, len, ok); 1530 if (ok) { 1531 ti = proto_tree_add_string(header_tree, hf, 1532 tvb, hdr_start, offset - hdr_start, 1533 val_to_str_ext(val, &vals_content_types_ext, 1534 "(Unknown content type identifier 0x%X)")); 1535 } 1536 off += len; 1537 } else { 1538 ok = FALSE; 1539 } 1540 1541 /* Remember: offset == val_start + val_len + val_len_len */ 1542 if (ok && (off < offset)) { /* Add parameters if any */ 1543 parameter_tree = proto_item_add_subtree (ti, ett_header); 1544 while (off < offset) { 1545 off = parameter (parameter_tree, pinfo, ti, tvb, off, offset - off); 1546 } 1547 } 1548 wkh_4_End(); 1549 } 1550 1551 1552 /* 1553 * Accept-value = 1554 * Short-integer 1555 * | Extension-media 1556 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) ) 1557 */ 1558 static guint32 1559 wkh_accept(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 1560 { 1561 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_accept, "Accept"); 1562 } 1563 1564 1565 /* 1566 * Content-type-value = 1567 * Short-integer 1568 * | Extension-media 1569 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) ) 1570 * 1571 * Beware: this header should not appear as such; it is dissected elsewhere 1572 * and at the same time the content type is used for subdissectors. 1573 * It is here for the sake of completeness. 1574 */ 1575 static guint32 1576 wkh_content_type(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 1577 { 1578 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_content_type, "Content-Type"); 1579 } 1580 1581 1582 /* 1583 * Content-type-value = 1584 * Short-integer 1585 * | Extension-media 1586 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) ) 1587 * 1588 * This function adds the content type value to the protocol tree, 1589 * and computes either the numeric or textual media type in return, 1590 * which will be used for further subdissection (e.g., MMS, WBXML). 1591 */ 1592 guint32 1593 add_content_type(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint32 val_start, 1594 guint32 *well_known_content, const char **textual_content) 1595 { 1596 /* Replace wkh_0_Declarations with slightly modified declarations 1597 * so we can still make use of the wkh_[1-4]_XXX macros! */ 1598 guint32 hdr_start = val_start; /* No header name, only value! */ 1599 guint8 val_id = tvb_get_guint8 (tvb, val_start); 1600 guint32 offset = val_start; /* Offset to one past this header */ 1601 guint32 val_len; /* length for value with length field */ 1602 guint32 val_len_len; /* length of length field */ 1603 gchar *val_str = NULL; 1604 guint32 off, val = 0, len; 1605 guint8 peek; 1606 gboolean ok = FALSE; 1607 proto_item *ti = NULL; 1608 proto_tree *parameter_tree = NULL; 1609 proto_tree *header_tree; 1610 proto_item *header_item; 1611 1612 *textual_content = NULL; 1613 *well_known_content = 0; 1614 1615 wkh_1_WellKnownValue(hf_hdr_name_value, ett_add_content_type, "Content-Type"); 1616 *textual_content = val_to_str_ext(val_id & 0x7F, &vals_content_types_ext, 1617 "<Unknown media type identifier 0x%X>"); 1618 proto_tree_add_string(tree, hf_hdr_content_type, 1619 tvb, hdr_start, offset - hdr_start, 1620 *textual_content); 1621 *well_known_content = val_id & 0x7F; 1622 ok = TRUE; 1623 wkh_2_TextualValue; 1624 /* Sometimes with a No-Content response, a NULL content type 1625 * is reported. Process this correctly! */ 1626 if (*val_str) { 1627 proto_tree_add_string(tree, hf_hdr_content_type, 1628 tvb, hdr_start, offset - hdr_start, 1629 val_str); 1630 *textual_content = wmem_strdup(pinfo->pool, val_str); 1631 *well_known_content = 0; 1632 } else { 1633 proto_tree_add_string(tree, hf_hdr_content_type, 1634 tvb, hdr_start, offset - hdr_start, 1635 "<no media type has been specified>"); 1636 *textual_content = NULL; 1637 *well_known_content = 0; 1638 } 1639 ok = TRUE; 1640 wkh_3_ValueWithLength; 1641 off = val_start + val_len_len; 1642 peek = tvb_get_guint8(tvb, off); 1643 if (is_text_string(peek)) { 1644 get_extension_media(val_str, tvb, off, len, ok); 1645 if (ok) { 1646 off += len; /* off now points to 1st byte after string */ 1647 ti = proto_tree_add_string (tree, hf_hdr_content_type, 1648 tvb, hdr_start, offset - hdr_start, val_str); 1649 } 1650 /* Following statement: required? */ 1651 *textual_content = wmem_strdup(pinfo->pool, val_str); 1652 *well_known_content = 0; 1653 } else if (is_integer_value(peek)) { 1654 get_integer_value(val, tvb, off, len, ok); 1655 if (ok) { 1656 *textual_content = val_to_str_ext(val, &vals_content_types_ext, 1657 "<Unknown media type identifier 0x%X>"); 1658 ti = proto_tree_add_string(tree, hf_hdr_content_type, 1659 tvb, hdr_start, offset - hdr_start, 1660 *textual_content); 1661 *well_known_content = val; 1662 } 1663 off += len; 1664 } /* else ok = FALSE */ 1665 /* Remember: offset == val_start + val_len_len + val_len */ 1666 if (ok && (off < offset)) { /* Add parameters if any */ 1667 parameter_tree = proto_item_add_subtree (ti, ett_header); 1668 while (off < offset) { 1669 off = parameter (parameter_tree, pinfo, ti, tvb, off, offset - off); 1670 } 1671 } 1672 1673 wkh_4_End(); 1674 } 1675 1676 1677 /* 1678 * Template for accept_X headers with optional Q parameter value 1679 */ 1680 #define wkh_accept_x_q_header(underscored,Text,valueStringExtAddr,valueName) \ 1681 static guint32 \ 1682 wkh_ ## underscored (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 1683 { \ 1684 return wkh_accept_x_q_header_func(tree, tvb, hdr_start, pinfo, \ 1685 hf_hdr_ ## underscored, Text, valueStringExtAddr, \ 1686 "<Unknown " valueName " identifier 0x%X>"); \ 1687 } 1688 1689 static guint32 1690 wkh_accept_x_q_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, 1691 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format) 1692 G_GNUC_PRINTF(8, 0); 1693 1694 static guint32 1695 wkh_accept_x_q_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, 1696 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format) 1697 { 1698 wkh_0_Declarations; 1699 guint32 off, val = 0, len; 1700 guint8 peek; 1701 proto_item *ti = NULL; 1702 proto_tree *parameter_tree = NULL; 1703 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Accept X: %s", name); 1704 1705 wkh_1_WellKnownValue(hf_hdr_name_value, ett_accept_x_q_header, header_name); 1706 proto_tree_add_string(tree, hf, 1707 tvb, hdr_start, offset - hdr_start, 1708 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, value_format)); 1709 ok = TRUE; 1710 wkh_2_TextualValue; 1711 proto_tree_add_string(tree, hf, 1712 tvb, hdr_start, offset - hdr_start, val_str); 1713 ok = TRUE; 1714 wkh_3_ValueWithLength; 1715 off = val_start + val_len_len; 1716 peek = tvb_get_guint8(tvb, off); 1717 if (is_text_string(peek)) { 1718 get_token_text(val_str, tvb, off, len, ok); 1719 if (ok) { 1720 off += len; /* off now points to 1st byte after string */ 1721 ti = proto_tree_add_string (tree, hf, 1722 tvb, hdr_start, offset - hdr_start, val_str); 1723 } 1724 } else if (is_integer_value(peek)) { 1725 get_integer_value(val, tvb, off, len, ok); 1726 if (ok) { 1727 ti = proto_tree_add_string(tree, hf, 1728 tvb, hdr_start, offset - hdr_start, 1729 val_to_str_ext(val, valueStringExtAddr, value_format)); 1730 } 1731 off += len; 1732 } /* else ok = FALSE */ 1733 /* Remember: offset == val_start + val_len */ 1734 if (ok && (off < offset)) { /* Add Q-value if available */ 1735 parameter_tree = proto_item_add_subtree (ti, ett_header); 1736 /*off =*/ parameter_value_q (parameter_tree, pinfo, ti, tvb, off); 1737 } 1738 1739 wkh_4_End(); 1740 } 1741 1742 /* 1743 * Accept-charset-value = 1744 * Short-integer 1745 * | Extension-media 1746 * | ( Value-length ( Token-text | Integer-value ) [ Q-value ] ) 1747 */ 1748 wkh_accept_x_q_header(accept_charset, "Accept-Charset", 1749 &mibenum_vals_character_sets_ext, "character set") 1750 /* 1751 * Accept-language-value = 1752 * Short-integer 1753 * | Extension-media 1754 * | ( Value-length ( Text-string | Integer-value ) [ Q-value ] ) 1755 */ 1756 wkh_accept_x_q_header(accept_language, "Accept-Language", 1757 &vals_languages_ext, "language") 1758 1759 1760 /* 1761 * Push-flag-value = Short-integer 1762 */ 1763 static guint32 1764 wkh_push_flag(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 1765 { 1766 wkh_0a_Declarations; 1767 proto_item *ti = NULL; 1768 proto_tree *subtree = NULL; 1769 wmem_strbuf_t *push_flag_str = wmem_strbuf_new(wmem_packet_scope(), ""); 1770 1771 wkh_1_WellKnownValue(hf_hdr_name_value, ett_push_flag, "Push Flag"); 1772 if (val_id & 0x01) 1773 wmem_strbuf_append(push_flag_str, " (Initiator URI authenticated)"); 1774 if (val_id & 0x02) 1775 wmem_strbuf_append(push_flag_str, " (Content trusted)"); 1776 if (val_id & 0x04) 1777 wmem_strbuf_append(push_flag_str, " (Last push message)"); 1778 if (val_id & 0x78) 1779 wmem_strbuf_append(push_flag_str, " <Warning: Reserved flags set>"); 1780 else 1781 ok = TRUE; 1782 1783 ti = proto_tree_add_string(tree, hf_hdr_push_flag, 1784 tvb, hdr_start, offset - hdr_start, wmem_strbuf_get_str(push_flag_str)); 1785 subtree = proto_item_add_subtree(ti, ett_header); 1786 proto_tree_add_uint(subtree, hf_hdr_push_flag_auth, 1787 tvb, val_start, 1, val_id); 1788 proto_tree_add_uint(subtree, hf_hdr_push_flag_trust, 1789 tvb, val_start, 1, val_id); 1790 proto_tree_add_uint(subtree, hf_hdr_push_flag_last, 1791 tvb, val_start, 1, val_id); 1792 1793 wkh_2_TextualValueInv; 1794 /* Invalid */ 1795 wkh_3_ValueWithLength; 1796 /* Invalid */ 1797 wkh_4_End(); 1798 } 1799 1800 1801 /* 1802 * Profile-Diff (with WBXML): Profile-diff-value = 1803 * Value-length <WBXML-Content> 1804 */ 1805 static guint32 wkh_profile_diff_wbxml (proto_tree *tree, tvbuff_t *tvb, 1806 guint32 hdr_start, packet_info *pinfo) 1807 { 1808 wkh_0a_Declarations; 1809 tvbuff_t *tmp_tvb; 1810 proto_item *ti = NULL; 1811 proto_tree *subtree; 1812 1813 ok = TRUE; /* Bypass error checking as we don't parse the values! */ 1814 1815 wkh_1_WellKnownValue(hf_hdr_name_value, ett_profile_diff_wbxml, "Profile-Diff (with WBXML)"); 1816 /* Invalid */ 1817 wkh_2_TextualValueInv; 1818 /* Invalid */ 1819 wkh_3_ValueWithLength; 1820 ti = proto_tree_add_string(tree, hf_hdr_profile_diff, tvb, hdr_start, offset - hdr_start, 1821 "(Profile-Diff value as WBXML)"); 1822 subtree = proto_item_add_subtree(ti, ett_header); 1823 tmp_tvb = tvb_new_subset_length(tvb, val_start + val_len_len, val_len); /* TODO: fix 2nd length */ 1824 call_dissector(wbxml_uaprof_handle, tmp_tvb, pinfo, subtree); 1825 ok = TRUE; 1826 wkh_4_End(); 1827 } 1828 1829 1830 /* 1831 * Allow-value = 1832 * Short-integer 1833 1 */ 1834 static guint32 1835 wkh_allow(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 1836 { 1837 wkh_0a_Declarations; 1838 1839 wkh_1_WellKnownValue(hf_hdr_name_value, ett_allow, "Allow"); 1840 val_id &= 0x7F; 1841 if (val_id >= 0x40) { /* Valid WSP method */ 1842 proto_tree_add_string(tree, hf_hdr_allow, 1843 tvb, hdr_start, offset - hdr_start, 1844 val_to_str_ext(val_id & 0x7F, &wsp_vals_pdu_type_ext, 1845 "<Unknown WSP method 0x%02X>")); 1846 ok = TRUE; 1847 } 1848 wkh_2_TextualValueInv; 1849 /* Invalid */ 1850 wkh_3_ValueWithLength; 1851 /* Invalid */ 1852 wkh_4_End(); 1853 } 1854 1855 1856 /* 1857 * Public-value = 1858 * Token-text | Short-integer 1859 2 */ 1860 static guint32 1861 wkh_public(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 1862 { 1863 wkh_0_Declarations; 1864 1865 wkh_1_WellKnownValue(hf_hdr_name_value, ett_public, "Public"); 1866 val_id &= 0x7F; 1867 if (val_id >= 0x40) { /* Valid WSP method */ 1868 proto_tree_add_string(tree, hf_hdr_public, 1869 tvb, hdr_start, offset - hdr_start, 1870 val_to_str_ext(val_id & 0x7F, &wsp_vals_pdu_type_ext, 1871 "<Unknown WSP method 0x%02X>")); 1872 ok = TRUE; 1873 } 1874 wkh_2_TextualValue; 1875 proto_tree_add_string(tree, hf_hdr_public, 1876 tvb, hdr_start, offset - hdr_start, val_str); 1877 ok = TRUE; 1878 wkh_3_ValueWithLength; 1879 /* Invalid */ 1880 wkh_4_End(); 1881 } 1882 1883 1884 /* 1885 * Vary-value = 1886 * Token-text | Short-integer 1887 */ 1888 static guint32 1889 wkh_vary(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 1890 { 1891 wkh_0_Declarations; 1892 1893 wkh_1_WellKnownValue(hf_hdr_name_value, ett_vary, "Vary"); 1894 proto_tree_add_string(tree, hf_hdr_vary, 1895 tvb, hdr_start, offset - hdr_start, 1896 val_to_str_ext(val_id & 0x7F, &vals_field_names_ext, 1897 "<Unknown WSP header field 0x%02X>")); 1898 ok = TRUE; 1899 wkh_2_TextualValue; 1900 proto_tree_add_string(tree, hf_hdr_vary, 1901 tvb, hdr_start, offset - hdr_start, 1902 val_str); 1903 ok = TRUE; 1904 wkh_3_ValueWithLength; 1905 /* Invalid */ 1906 wkh_4_End(); 1907 } 1908 1909 1910 /* 1911 * X-wap-security-value = 0x80 1912 */ 1913 static guint32 1914 wkh_x_wap_security(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 1915 { 1916 wkh_0a_Declarations; 1917 1918 wkh_1_WellKnownValue(hf_hdr_name_value, ett_x_wap_security, "X-wap-security-value"); 1919 if (val_id == 0x80) { 1920 proto_tree_add_string(tree, hf_hdr_x_wap_security, 1921 tvb, hdr_start, offset - hdr_start, "close-subordinate"); 1922 ok = TRUE; 1923 } 1924 wkh_2_TextualValueInv; 1925 /* Invalid */ 1926 wkh_3_ValueWithLength; 1927 /* Invalid */ 1928 wkh_4_End(); 1929 } 1930 1931 1932 /* 1933 * Connection-value = 0x80 | Token-text 1934 5 */ 1935 static guint32 1936 wkh_connection(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 1937 { 1938 wkh_0_Declarations; 1939 1940 wkh_1_WellKnownValue(hf_hdr_name_value, ett_connection, "Connection"); 1941 if (val_id == 0x80) { 1942 proto_tree_add_string(tree, hf_hdr_connection, 1943 tvb, hdr_start, offset - hdr_start, "close"); 1944 ok = TRUE; 1945 } 1946 wkh_2_TextualValue; 1947 proto_tree_add_string(tree, hf_hdr_connection, 1948 tvb, hdr_start, offset - hdr_start, val_str); 1949 ok = TRUE; 1950 wkh_3_ValueWithLength; 1951 /* Invalid */ 1952 wkh_4_End(); 1953 } 1954 1955 1956 /* 1957 * Transfer-encoding-value = 0x80 | Token-text 1958 */ 1959 static guint32 1960 wkh_transfer_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 1961 { 1962 wkh_0_Declarations; 1963 1964 wkh_1_WellKnownValue(hf_hdr_name_value, ett_transfer_encoding, "Transfer encoding"); 1965 if (val_id == 0x80) { 1966 proto_tree_add_string(tree, hf_hdr_transfer_encoding, 1967 tvb, hdr_start, offset - hdr_start, "chunked"); 1968 ok = TRUE; 1969 } 1970 wkh_2_TextualValue; 1971 proto_tree_add_string(tree, hf_hdr_transfer_encoding, 1972 tvb, hdr_start, offset - hdr_start, val_str); 1973 ok = TRUE; 1974 wkh_3_ValueWithLength; 1975 /* Invalid */ 1976 wkh_4_End(); 1977 } 1978 1979 1980 /* 1981 * Accept-range-value = 0x80 | 0x81 | Token-text 1982 */ 1983 static guint32 1984 wkh_accept_ranges(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 1985 { 1986 wkh_0_Declarations; 1987 1988 wkh_1_WellKnownValue(hf_hdr_name_value, ett_accept_ranges, "Accept Ranges"); 1989 switch (val_id) { 1990 case 0x80: /* none */ 1991 proto_tree_add_string(tree, hf_hdr_accept_ranges, 1992 tvb, hdr_start, offset - hdr_start, "none"); 1993 ok = TRUE; 1994 break; 1995 case 0x81: /* bytes */ 1996 proto_tree_add_string(tree, hf_hdr_accept_ranges, 1997 tvb, hdr_start, offset - hdr_start, "bytes"); 1998 ok = TRUE; 1999 break; 2000 } 2001 wkh_2_TextualValue; 2002 proto_tree_add_string(tree, hf_hdr_accept_ranges, 2003 tvb, hdr_start, offset - hdr_start, val_str); 2004 ok = TRUE; 2005 wkh_3_ValueWithLength; 2006 /* Invalid */ 2007 wkh_4_End(); 2008 } 2009 2010 2011 /* 2012 * Content-encoding-value = 0x80 | 0x81 | 0x82 | Token-text 2013 */ 2014 static guint32 2015 wkh_content_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 2016 { 2017 wkh_0_Declarations; 2018 2019 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_encoding, "Content Encoding"); 2020 switch (val_id) { 2021 case 0x80: /* gzip */ 2022 proto_tree_add_string(tree, hf_hdr_content_encoding, 2023 tvb, hdr_start, offset - hdr_start, "gzip"); 2024 ok = TRUE; 2025 break; 2026 case 0x81: /* compress */ 2027 proto_tree_add_string(tree, hf_hdr_content_encoding, 2028 tvb, hdr_start, offset - hdr_start, "compress"); 2029 ok = TRUE; 2030 break; 2031 case 0x82: /* deflate */ 2032 proto_tree_add_string(tree, hf_hdr_content_encoding, 2033 tvb, hdr_start, offset - hdr_start, "deflate"); 2034 ok = TRUE; 2035 break; 2036 } 2037 wkh_2_TextualValue; 2038 proto_tree_add_string(tree, hf_hdr_content_encoding, 2039 tvb, hdr_start, offset - hdr_start, val_str); 2040 ok = TRUE; 2041 wkh_3_ValueWithLength; 2042 /* Invalid */ 2043 wkh_4_End(); 2044 } 2045 2046 2047 /* 2048 * Accept-encoding-value = 2049 * Short-integer 2050 * | Token-text 2051 * | ( Value-length ( Short-integer | Text-string ) [ Q-value ] ) 2052 */ 2053 static guint32 2054 wkh_accept_encoding(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 2055 { 2056 wkh_0_Declarations; 2057 guint32 len, off; 2058 guint8 peek; 2059 gchar *str; 2060 proto_item *ti = NULL; 2061 proto_tree *parameter_tree = NULL; 2062 2063 wkh_1_WellKnownValue(hf_hdr_name_value, ett_accept_encoding, "Accept Encoding"); 2064 switch (val_id) { 2065 case 0x80: /* gzip */ 2066 proto_tree_add_string(tree, hf_hdr_accept_encoding, 2067 tvb, hdr_start, offset - hdr_start, "gzip"); 2068 ok = TRUE; 2069 break; 2070 case 0x81: /* compress */ 2071 proto_tree_add_string(tree, hf_hdr_accept_encoding, 2072 tvb, hdr_start, offset - hdr_start, "compress"); 2073 ok = TRUE; 2074 break; 2075 case 0x82: /* deflate */ 2076 proto_tree_add_string(tree, hf_hdr_accept_encoding, 2077 tvb, hdr_start, offset - hdr_start, "deflate"); 2078 ok = TRUE; 2079 break; 2080 case 0x83: /* * */ 2081 proto_tree_add_string(tree, hf_hdr_accept_encoding, 2082 tvb, hdr_start, offset - hdr_start, "*"); 2083 ok = TRUE; 2084 break; 2085 } 2086 wkh_2_TextualValue; 2087 proto_tree_add_string(tree, hf_hdr_accept_encoding, 2088 tvb, hdr_start, offset - hdr_start, val_str); 2089 ok = TRUE; 2090 wkh_3_ValueWithLength; 2091 off = val_start + val_len_len; 2092 peek = tvb_get_guint8(tvb, off); 2093 if (is_short_integer(peek)) { 2094 switch (peek) { 2095 case 0x80: /* gzip */ 2096 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding, 2097 tvb, hdr_start, offset - hdr_start, "gzip"); 2098 ok = TRUE; 2099 break; 2100 case 0x81: /* compress */ 2101 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding, 2102 tvb, hdr_start, offset - hdr_start, "compress"); 2103 ok = TRUE; 2104 break; 2105 case 0x82: /* deflate */ 2106 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding, 2107 tvb, hdr_start, offset - hdr_start, "deflate"); 2108 ok = TRUE; 2109 break; 2110 case 0x83: /* any */ 2111 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding, 2112 tvb, hdr_start, offset - hdr_start, "*"); 2113 ok = TRUE; 2114 break; 2115 } 2116 off++; 2117 } else { 2118 get_token_text(str, tvb, off, len, ok); 2119 if (ok) { 2120 ti = proto_tree_add_string(tree, hf_hdr_accept_encoding, 2121 tvb, hdr_start, offset - hdr_start, str); 2122 } 2123 off += len; 2124 } 2125 if (ok) { 2126 /* Remember: offset == val_start + val_len_len + val_len */ 2127 if (off < offset) { /* Add Q-value if available */ 2128 parameter_tree = proto_item_add_subtree(ti, ett_header); 2129 parameter_value_q(parameter_tree, pinfo, ti, tvb, off); 2130 } 2131 } 2132 wkh_4_End(); 2133 } 2134 2135 2136 /* 2137 * Content-disposition-value = Value-length ( Disposition ) *( Parameter ) 2138 * Disposition = Form-data | Attachment | Inline | Token-text 2139 * Form-data = 0x80 2140 * Attachment = 0x81 2141 * Inline = 0x82 2142 * We handle this as: 2143 * Value-length ( Short-integer | Text-string ) *( Parameter ) 2144 */ 2145 static guint32 2146 wkh_content_disposition(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 2147 { 2148 wkh_0a_Declarations; 2149 guint32 len, off; 2150 guint8 peek; 2151 gchar *str; 2152 proto_item *ti = NULL; 2153 proto_tree *parameter_tree = NULL; 2154 2155 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_disposition, "Content Disposition"); 2156 /* Invalid */ 2157 wkh_2_TextualValueInv; 2158 /* Invalid */ 2159 wkh_3_ValueWithLength; 2160 off = val_start + val_len_len; 2161 peek = tvb_get_guint8(tvb, off); 2162 if (is_short_integer(peek)) { 2163 switch (peek) { 2164 case 0x80: /* form-data */ 2165 ti = proto_tree_add_string(tree, hf_hdr_content_disposition, 2166 tvb, hdr_start, offset - hdr_start, "form-data"); 2167 ok = TRUE; 2168 break; 2169 case 0x81: /* attachment */ 2170 ti = proto_tree_add_string(tree, hf_hdr_content_disposition, 2171 tvb, hdr_start, offset - hdr_start, "attachment"); 2172 ok = TRUE; 2173 break; 2174 case 0x82: /* inline */ 2175 ti = proto_tree_add_string(tree, hf_hdr_content_disposition, 2176 tvb, hdr_start, offset - hdr_start, "inline"); 2177 ok = TRUE; 2178 break; 2179 } 2180 off++; 2181 } else { 2182 get_token_text(str, tvb, off, len, ok); 2183 if (ok) { 2184 ti = proto_tree_add_string(tree, hf_hdr_content_disposition, 2185 tvb, hdr_start, offset - hdr_start, str); 2186 } 2187 off += len; 2188 } 2189 if ((ok) && (off < offset)) { 2190 /* Remember: offset == val_start + val_len_len + val_len */ 2191 parameter_tree = proto_item_add_subtree(ti, ett_header); 2192 while (off < offset) { /* Add parameters if available */ 2193 off = parameter(parameter_tree, pinfo, ti, tvb, off, offset - off); 2194 } 2195 } 2196 wkh_4_End(); 2197 } 2198 2199 2200 /* 2201 * Common code for headers with only a textual value 2202 * is written in the macro below: 2203 */ 2204 #define wkh_text_header(underscored,Text) \ 2205 static guint32 \ 2206 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) \ 2207 { \ 2208 return wkh_text_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \ 2209 } 2210 2211 static guint32 2212 wkh_text_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name) 2213 { 2214 wkh_0_Declarations; 2215 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Header: %s", name); 2216 2217 wkh_1_WellKnownValue(hf_hdr_name_value, ett_text_header, header_name); 2218 /* Invalid */ 2219 wkh_2_TextualValue; 2220 proto_tree_add_string(tree, hf, 2221 tvb, hdr_start, offset - hdr_start, val_str); 2222 ok = TRUE; 2223 wkh_3_ValueWithLength; 2224 /* Invalid */ 2225 wkh_4_End(); 2226 } 2227 2228 /* Text-only headers: */ 2229 wkh_text_header(content_base, "Content-Base") 2230 wkh_text_header(content_location, "Content-Location") 2231 wkh_text_header(etag, "ETag") 2232 wkh_text_header(from, "From") 2233 wkh_text_header(host, "Host") 2234 wkh_text_header(if_match, "If-Match") 2235 wkh_text_header(if_none_match, "If-None-Match") 2236 wkh_text_header(location, "Location") 2237 wkh_text_header(referer, "Referer") 2238 wkh_text_header(server, "Server") 2239 wkh_text_header(user_agent, "User-Agent") 2240 wkh_text_header(upgrade, "Upgrade") 2241 wkh_text_header(via, "Via") 2242 wkh_text_header(content_uri, "Content-Uri") 2243 wkh_text_header(initiator_uri, "Initiator-Uri") 2244 wkh_text_header(profile, "Profile") 2245 2246 /* 2247 * Same for quoted-string value 2248 */ 2249 static guint32 2250 wkh_content_id(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 2251 { 2252 wkh_0_Declarations; 2253 gchar *str; 2254 proto_item *ti = NULL; 2255 2256 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_id, "Content ID"); 2257 /* Invalid */ 2258 wkh_2_TextualValue; 2259 if (is_quoted_string(val_str[0])) { 2260 if (is_quoted_string(val_str[val_len-2])) { 2261 /* Trailing quote - issue a warning */ 2262 ti = proto_tree_add_string(tree, hf_hdr_content_id, 2263 tvb, hdr_start, offset - hdr_start, val_str); 2264 expert_add_info(pinfo, ti, &ei_wsp_trailing_quote); 2265 } else { /* OK (no trailing quote) */ 2266 str = wmem_strdup_printf(wmem_packet_scope(), "%s\"", val_str); 2267 proto_tree_add_string(tree, hf_hdr_content_id, 2268 tvb, hdr_start, offset - hdr_start, str); 2269 } 2270 } else { 2271 ti = proto_tree_add_string(tree, hf_hdr_content_id, 2272 tvb, hdr_start, offset - hdr_start, val_str); 2273 expert_add_info(pinfo, ti, &ei_wsp_trailing_quote); 2274 } 2275 ok = TRUE; 2276 wkh_3_ValueWithLength; 2277 /* Invalid */ 2278 wkh_4_End(); 2279 } 2280 2281 2282 /* 2283 * Common code for headers with only a textual or a date value 2284 * is written in the macro below: 2285 */ 2286 #define wkh_text_or_date_value_header(underscored,Text) \ 2287 static guint32 \ 2288 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 2289 { \ 2290 return wkh_text_or_date_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \ 2291 } 2292 2293 static guint32 2294 wkh_text_or_date_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name) 2295 { 2296 wkh_0_Declarations; 2297 guint32 val = 0, off = val_start, len; 2298 gchar *str; /* may not be freed! */ 2299 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Text or Date: %s", name); 2300 2301 wkh_1_WellKnownValue(hf_hdr_name_value, ett_text_or_date_value, header_name); 2302 /* Invalid */ 2303 wkh_2_TextualValue; 2304 proto_tree_add_string(tree, hf, 2305 tvb, hdr_start, offset - hdr_start, val_str); 2306 ok = TRUE; 2307 wkh_3_ValueWithLength; 2308 if (val_id <= 4) { /* Length field already parsed by macro! */ 2309 get_date_value(val, tvb, off, len, ok); 2310 if (ok) { 2311 str = abs_time_secs_to_str(wmem_packet_scope(), val, ABSOLUTE_TIME_LOCAL, TRUE); 2312 proto_tree_add_string(tree, hf, 2313 tvb, hdr_start, offset - hdr_start, str); 2314 } 2315 } 2316 wkh_4_End(); 2317 } 2318 2319 /* If-Range */ 2320 wkh_text_or_date_value_header(if_range,"If-Range") 2321 2322 2323 /* 2324 * Common code for headers with only a date value 2325 * is written in the macro below: 2326 */ 2327 #define wkh_date_value_header(underscored,Text) \ 2328 static guint32 \ 2329 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 2330 { \ 2331 return wkh_date_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \ 2332 } 2333 2334 static guint32 2335 wkh_date_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name) 2336 { 2337 wkh_0a_Declarations; 2338 guint32 val = 0, off = val_start, len; 2339 gchar *str; /* may not be freed! */ 2340 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Date: %s", name); 2341 2342 wkh_1_WellKnownValue(hf_hdr_name_value, ett_date_value, header_name); 2343 /* Invalid */ 2344 wkh_2_TextualValueInv; 2345 /* Invalid */ 2346 wkh_3_ValueWithLength; 2347 if (val_id <= 4) { /* Length field already parsed by macro! */ 2348 get_date_value(val, tvb, off, len, ok); 2349 if (ok) { 2350 str = abs_time_secs_to_str(wmem_packet_scope(), val, ABSOLUTE_TIME_LOCAL, TRUE); 2351 proto_tree_add_string(tree, hf, 2352 tvb, hdr_start, offset - hdr_start, str); 2353 /* BEHOLD: do NOT try to free str, as 2354 * abs_time_secs_to_str(wmem_packet_scope(), ) returns wmem_allocated data */ 2355 } 2356 } 2357 wkh_4_End(); 2358 } 2359 2360 /* Date-value only headers: */ 2361 wkh_date_value_header(date, "Date") 2362 wkh_date_value_header(expires, "Expires") 2363 wkh_date_value_header(if_modified_since, "If-Modified-Since") 2364 wkh_date_value_header(if_unmodified_since, "If-Unmodified-Since") 2365 wkh_date_value_header(last_modified, "Last-Modified") 2366 2367 2368 /* Date-value with special interpretation of zero value */ 2369 #define wkh_tod_value_header(underscored,Text) \ 2370 static guint32 \ 2371 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 2372 { \ 2373 return wkh_tod_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \ 2374 } 2375 2376 static guint32 2377 wkh_tod_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name) 2378 { 2379 wkh_0a_Declarations; 2380 guint32 val = 0, off = val_start, len; 2381 proto_item *ti = NULL; 2382 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Time of Day: %s", name); 2383 nstime_t t; 2384 2385 wkh_1_WellKnownValue(hf_hdr_name_value, ett_tod_value, header_name); 2386 if (val_id == 0x80) { /* Openwave TOD header uses this format */ 2387 t.secs = 0; 2388 t.nsecs = 0; 2389 ti = proto_tree_add_time_format_value(tree, hf, 2390 tvb, hdr_start, offset - hdr_start, &t, 2391 "Requesting Time Of Day"); 2392 proto_item_append_text(ti, 2393 " <Warning: should be encoded as long-integer>"); 2394 ok = TRUE; 2395 } 2396 /* It seems VERY unlikely that we'll see date values within the first 2397 * 127 seconds of the UNIX 1-1-1970 00:00:00 start of the date clocks 2398 * so I assume such a value is a genuine error */ 2399 wkh_2_TextualValueInv; 2400 /* Invalid */ 2401 wkh_3_ValueWithLength; 2402 if (val_id <= 4) { /* Length field already parsed by macro! */ 2403 get_date_value(val, tvb, off, len, ok); 2404 if (ok) { 2405 t.secs = (time_t)val; 2406 t.nsecs = 0; 2407 if (val == 0) { 2408 proto_tree_add_time_format_value(tree, hf, 2409 tvb, hdr_start, offset - hdr_start, &t, 2410 "Requesting Time Of Day"); 2411 } else { 2412 proto_tree_add_time(tree, hf, 2413 tvb, hdr_start, offset - hdr_start, &t); 2414 } 2415 } 2416 } 2417 wkh_4_End(); 2418 } 2419 2420 wkh_tod_value_header(x_wap_tod, "X-Wap-Tod") 2421 2422 2423 /* 2424 * Age-value: Delta-seconds-value 2425 */ 2426 static guint32 2427 wkh_age(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 2428 { 2429 wkh_0_Declarations; 2430 guint32 val = 0, off = val_start, len; 2431 2432 wkh_1_WellKnownValue(hf_hdr_name_value, ett_age, "Age"); 2433 val = val_id & 0x7F; 2434 val_str = wmem_strdup_printf(wmem_packet_scope(), "%u second%s", val, plurality(val, "", "s")); 2435 proto_tree_add_string(tree, hf_hdr_age, 2436 tvb, hdr_start, offset - hdr_start, val_str); 2437 ok = TRUE; 2438 wkh_2_TextualValueInv; 2439 /* Invalid */ 2440 wkh_3_ValueWithLength; 2441 if (val_id <= 4) { /* Length field already parsed by macro! */ 2442 get_long_integer(val, tvb, off, len, ok); 2443 if (ok) { 2444 val_str = wmem_strdup_printf(wmem_packet_scope(), "%u second%s", val, plurality(val, "", "s")); 2445 proto_tree_add_string(tree, hf_hdr_age, 2446 tvb, hdr_start, offset - hdr_start, val_str); 2447 } 2448 } 2449 wkh_4_End(); 2450 } 2451 2452 2453 /* 2454 * Template for Integer lookup or text value headers: 2455 */ 2456 #define wkh_integer_lookup_or_text_value(underscored,Text,valueStringExtAddr,valueName) \ 2457 static guint32 \ 2458 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 2459 { \ 2460 return wkh_integer_lookup_or_text_value_func(tree, tvb, hdr_start, pinfo, \ 2461 hf_hdr_ ## underscored, Text,valueStringExtAddr, \ 2462 "<Unknown " valueName " identifier 0x%X>"); \ 2463 } 2464 2465 static guint32 2466 wkh_integer_lookup_or_text_value_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, 2467 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format) 2468 G_GNUC_PRINTF(8, 0); 2469 2470 static guint32 2471 wkh_integer_lookup_or_text_value_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, 2472 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format) 2473 { 2474 wkh_0_Declarations; 2475 guint32 off = val_start, len; 2476 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer lookup: %s", name); 2477 2478 wkh_1_WellKnownValue(hf_hdr_name_value, ett_integer_lookup, header_name); 2479 proto_tree_add_string(tree, hf, 2480 tvb, hdr_start, offset - hdr_start, 2481 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, value_format)); 2482 ok = TRUE; 2483 wkh_2_TextualValue; 2484 proto_tree_add_string(tree, hf, 2485 tvb, hdr_start, offset - hdr_start, val_str); 2486 ok = TRUE; 2487 wkh_3_ValueWithLength; 2488 if (val_id <= 4) { /* Length field already parsed by macro! */ 2489 len = tvb_get_guint8(tvb,off); 2490 ok = (len >= 1 && len <= 4); /* Valid lengths for us are 1-4 */ 2491 if (ok) { 2492 proto_tree_add_string(tree, hf, 2493 tvb, hdr_start, offset - hdr_start, 2494 val_to_str_ext(val_id & 0x7F, valueStringExtAddr, value_format)); 2495 } 2496 } 2497 wkh_4_End(); 2498 } 2499 2500 /* 2501 * Wap-application-value: Uri-value | Integer-value 2502 */ 2503 wkh_integer_lookup_or_text_value(x_wap_application_id, "X-Wap-Application-Id", 2504 &vals_wap_application_ids_ext, "WAP application") 2505 wkh_integer_lookup_or_text_value(accept_application, "Accept-Application", 2506 &vals_wap_application_ids_ext, "WAP application") 2507 wkh_integer_lookup_or_text_value(content_language, "Content-Language", 2508 &vals_languages_ext, "language") 2509 /* NOTE - Although the WSP spec says this is an integer-value, the WSP headers 2510 * are encoded as a 7-bit entity! */ 2511 wkh_integer_lookup_or_text_value(trailer, "Trailer", 2512 &vals_field_names_ext, "well-known-header") 2513 2514 2515 /* 2516 * Challenge 2517 */ 2518 2519 /* 2520 * Common code for headers with only a challenge value 2521 * is written in the macro below: 2522 */ 2523 #define wkh_challenge_value_header(underscored,Text) \ 2524 static guint32 \ 2525 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 2526 { \ 2527 return wkh_challenge_value_header_func(tree, tvb, hdr_start, pinfo, \ 2528 hf_hdr_ ## underscored, hf_hdr_ ## underscored ## _scheme, \ 2529 hf_hdr_ ## underscored ## _realm, Text); \ 2530 } 2531 2532 static guint32 2533 wkh_challenge_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, 2534 int hf, int hf_scheme, int hf_realm, const char* name) 2535 { 2536 wkh_0a_Declarations; 2537 guint8 peek; 2538 guint32 off, len; 2539 proto_tree *subtree; 2540 gchar *str; 2541 proto_item *ti = NULL; 2542 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Challenge: %s", name); 2543 2544 wkh_1_WellKnownValue(hf_hdr_name_value, ett_challenge, header_name); 2545 /* Invalid */ 2546 wkh_2_TextualValueInv; 2547 /* Invalid */ 2548 wkh_3_ValueWithLength; 2549 off = val_start + val_len_len; 2550 peek = tvb_get_guint8(tvb, off); 2551 if (peek == 0x80) { /* Basic */ 2552 ti = proto_tree_add_string(tree, hf, 2553 tvb, hdr_start, offset - hdr_start, "basic"); 2554 subtree = proto_item_add_subtree(ti, ett_header); 2555 proto_tree_add_string(subtree, hf_scheme, 2556 tvb, off, 1, "basic"); 2557 off++; 2558 /* Realm: text-string */ 2559 get_text_string(str,tvb,off,len,ok); 2560 if (ok) { 2561 proto_tree_add_string(subtree, 2562 hf_realm, 2563 tvb, off, len, str); 2564 proto_item_append_text(ti, "; realm=%s", str); 2565 /*off += len;*/ 2566 } 2567 } else { /* Authentication-scheme: token-text */ 2568 get_token_text(str, tvb, off, len, ok); 2569 if (ok) { 2570 ti = proto_tree_add_string(tree, hf, 2571 tvb, hdr_start, off - hdr_start, str); 2572 subtree = proto_item_add_subtree(ti, ett_header); 2573 proto_tree_add_string(subtree, 2574 hf_scheme, 2575 tvb, hdr_start, off - hdr_start, str); 2576 off += len; 2577 /* Realm: text-string */ 2578 get_text_string(str,tvb,off,len,ok); 2579 if (ok) { 2580 proto_tree_add_string(subtree, 2581 hf_realm, 2582 tvb, off, len, str); 2583 proto_item_append_text(ti, "; realm=%s", str); 2584 off += len; 2585 /* Auth-params: parameter - TODO */ 2586 while (off < offset) /* Parse parameters */ 2587 off = parameter(subtree, pinfo, ti, tvb, off, offset - off); 2588 } 2589 } 2590 } 2591 wkh_4_End(); 2592 } 2593 2594 /* Challenge-value only headers: */ 2595 wkh_challenge_value_header(www_authenticate, "WWW-Authenticate") 2596 wkh_challenge_value_header(proxy_authenticate, "Proxy-Authenticate") 2597 2598 2599 /* 2600 * Credentials 2601 */ 2602 2603 /* 2604 * Common code for headers with only a credentials value 2605 * is written in the macro below: 2606 */ 2607 #define wkh_credentials_value_header(underscored,Text) \ 2608 static guint32 \ 2609 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 2610 { \ 2611 return wkh_credentials_value_header_func(tree, tvb, hdr_start, pinfo, \ 2612 hf_hdr_ ## underscored, hf_hdr_ ## underscored ## _scheme, \ 2613 hf_hdr_ ## underscored ## _user_id, hf_hdr_ ## underscored ## _password, Text); \ 2614 } 2615 2616 static guint32 2617 wkh_credentials_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, 2618 int hf, int hf_scheme, int hf_userid, int hf_password, const char* name) 2619 { 2620 wkh_0a_Declarations; 2621 guint8 peek; 2622 guint32 off, len; 2623 proto_tree *subtree; 2624 gchar *str; 2625 proto_item *ti = NULL; 2626 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Credentials: %s", name); 2627 2628 wkh_1_WellKnownValue(hf_hdr_name_value, ett_credentials_value, header_name); 2629 /* Invalid */ 2630 wkh_2_TextualValueInv; 2631 /* Invalid */ 2632 wkh_3_ValueWithLength; 2633 off = val_start + val_len_len; 2634 peek = tvb_get_guint8(tvb, off); 2635 if (peek == 0x80) { /* Basic */ 2636 ti = proto_tree_add_string(tree, hf, 2637 tvb, hdr_start, offset - hdr_start, "basic"); 2638 subtree = proto_item_add_subtree(ti, ett_header); 2639 proto_tree_add_string(subtree, hf_scheme, 2640 tvb, off, 1, "basic"); 2641 off++; 2642 /* User-id: text-string */ 2643 get_text_string(str,tvb,off,len,ok); 2644 if (ok) { 2645 proto_tree_add_string(subtree, 2646 hf_userid, 2647 tvb, off, len, str); 2648 proto_item_append_text(ti, "; user-id=%s", str); 2649 off += len; 2650 /* Password: text-string */ 2651 get_text_string(str,tvb,off,len,ok); 2652 if (ok) { 2653 proto_tree_add_string(subtree, 2654 hf_password, 2655 tvb, off, len, str); 2656 proto_item_append_text(ti, "; password=%s", str); 2657 /*off += len;*/ 2658 } 2659 } 2660 } else { /* Authentication-scheme: token-text */ 2661 get_token_text(str, tvb, off, len, ok); 2662 if (ok) { 2663 ti = proto_tree_add_string(tree, hf, 2664 tvb, hdr_start, off - hdr_start, str); 2665 subtree = proto_item_add_subtree(ti, ett_header); 2666 proto_tree_add_string(subtree, 2667 hf_scheme, 2668 tvb, hdr_start, off - hdr_start, str); 2669 off += len; 2670 /* Auth-params: parameter - TODO */ 2671 while (off < offset) /* Parse parameters */ 2672 off = parameter(subtree, pinfo, ti, tvb, off, offset - off); 2673 } 2674 } 2675 wkh_4_End(); 2676 } 2677 2678 /* Credentials-value only headers: */ 2679 wkh_credentials_value_header(authorization, "Authorization") 2680 wkh_credentials_value_header(proxy_authorization, "Proxy-Authorization") 2681 2682 2683 /* 2684 * Content-md5-value = 16*16 OCTET 2685 */ 2686 static guint32 2687 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 2688 { 2689 wkh_0a_Declarations; 2690 guint32 off; 2691 2692 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_md5, "Content-md5"); 2693 /* Invalid */ 2694 wkh_2_TextualValueInv; 2695 /* Invalid */ 2696 wkh_3_ValueWithLength; 2697 off = val_start + val_len_len; 2698 if (val_len == 16) { 2699 proto_tree_add_item(tree, hf_hdr_content_md5, 2700 tvb, off, val_len, ENC_NA); 2701 ok = TRUE; 2702 } 2703 wkh_4_End(); 2704 } 2705 2706 2707 /* 2708 * Pragma-value = 0x80 | Length Parameter 2709 */ 2710 static guint32 2711 wkh_pragma(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 2712 { 2713 wkh_0a_Declarations; 2714 guint32 off; 2715 proto_item *ti = NULL; 2716 2717 wkh_1_WellKnownValue(hf_hdr_name_value, ett_pragma, "Pragma"); 2718 if (val_id == 0x80) { 2719 proto_tree_add_string(tree, hf_hdr_pragma, 2720 tvb, hdr_start, offset - hdr_start, "no-cache"); 2721 ok = TRUE; 2722 } 2723 wkh_2_TextualValueInv; 2724 /* Invalid */ 2725 wkh_3_ValueWithLength; 2726 off = val_start + val_len_len; 2727 ti = proto_tree_add_string(tree, hf_hdr_pragma, 2728 tvb, hdr_start, off - hdr_start, ""); 2729 /* NULL subtree for parameter() results in no subtree 2730 * TODO - provide a single parameter dissector that appends data 2731 * to the header field data. */ 2732 parameter(NULL, pinfo, ti, tvb, off, offset - off); 2733 ok = TRUE; 2734 wkh_4_End(); 2735 } 2736 2737 2738 /* 2739 * Integer-value 2740 */ 2741 #define wkh_integer_value_header(underscored,Text) \ 2742 static guint32 \ 2743 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 2744 { \ 2745 return wkh_integer_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \ 2746 } 2747 2748 static guint32 2749 wkh_integer_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, int hf, const char* name) 2750 { 2751 wkh_0a_Declarations; 2752 guint32 val = 0, off = val_start, len; 2753 gchar *str; /* may not be freed! */ 2754 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer-value: %s", name); 2755 2756 wkh_1_WellKnownValue(hf_hdr_name_value, ett_integer_value, header_name); 2757 str = wmem_strdup_printf(wmem_packet_scope(), "%u", val_id & 0x7F); 2758 proto_tree_add_string(tree, hf, 2759 tvb, hdr_start, offset - hdr_start, str); 2760 ok = TRUE; 2761 wkh_2_TextualValueInv; 2762 /* Invalid */ 2763 wkh_3_ValueWithLength; 2764 if (val_id <= 4) { /* Length field already parsed by macro! */ 2765 get_long_integer(val, tvb, off, len, ok); 2766 if (ok) { 2767 str = wmem_strdup_printf(wmem_packet_scope(), "%u", val); 2768 proto_tree_add_string(tree, hf, 2769 tvb, hdr_start, offset - hdr_start, str); 2770 } 2771 } 2772 wkh_4_End(); 2773 } 2774 2775 wkh_integer_value_header(content_length, "Content-Length") 2776 wkh_integer_value_header(max_forwards, "Max-Forwards") 2777 2778 2779 #define wkh_integer_lookup_value_header(underscored,Text,valueStringExtAddr,valueName) \ 2780 static guint32 \ 2781 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) \ 2782 { \ 2783 return wkh_integer_lookup_value_header_func(tree, tvb, hdr_start, pinfo, \ 2784 hf_hdr_ ## underscored, Text,valueStringExtAddr, valueName); \ 2785 } 2786 2787 static guint32 2788 wkh_integer_lookup_value_header_func(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo, 2789 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_name) 2790 { 2791 wkh_0_Declarations; 2792 guint32 off = val_start, len; 2793 gchar* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer lookup: %s", name); 2794 gchar* value_name_str = wmem_strdup_printf(wmem_packet_scope(), "<Unknown %s>", value_name); 2795 2796 wkh_1_WellKnownValue(hf_hdr_name_value, ett_integer_lookup_value, header_name); 2797 val_str = try_val_to_str_ext(val_id & 0x7F, valueStringExtAddr); 2798 if (val_str) { 2799 proto_tree_add_string(tree, hf, 2800 tvb, hdr_start, offset - hdr_start, val_str); 2801 ok = TRUE; 2802 } else { 2803 proto_tree_add_string(tree, hf, 2804 tvb, hdr_start, offset - hdr_start, 2805 value_name_str); 2806 } 2807 wkh_2_TextualValueInv; 2808 /* Invalid */ 2809 wkh_3_ValueWithLength; 2810 if (val_id <= 4) { /* Length field already parsed by macro! */ 2811 len = tvb_get_guint8(tvb,off); 2812 ok = (len >= 1 && len <= 4); /* Valid lengths for us are 1-4 */ 2813 if (ok) { 2814 val_str = try_val_to_str_ext(val_id & 0x7F, valueStringExtAddr); 2815 if (val_str) { 2816 proto_tree_add_string(tree, hf, 2817 tvb, hdr_start, offset - hdr_start, val_str); 2818 ok = TRUE; 2819 } else { 2820 proto_tree_add_string(tree, hf, 2821 tvb, hdr_start, offset - hdr_start, 2822 value_name_str); 2823 } 2824 } 2825 } 2826 wkh_4_End(); 2827 } 2828 2829 wkh_integer_lookup_value_header(bearer_indication, "Bearer-Indication", 2830 &vals_bearer_types_ext, "bearer type") 2831 2832 2833 /* 2834 * Cache-control-value 2835 */ 2836 static guint32 2837 wkh_cache_control(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 2838 { 2839 wkh_0_Declarations; 2840 guint32 off, len, val = 0; 2841 guint8 peek, cache_control_directive; 2842 proto_item *ti = NULL; 2843 wmem_strbuf_t *cache_str; 2844 2845 wkh_1_WellKnownValue(hf_hdr_name_value, ett_cache_control, "Cache-control"); 2846 val = val_id & 0x7F; 2847 val_str = try_val_to_str_ext(val, &vals_cache_control_ext); 2848 if (val_str) { 2849 proto_tree_add_string(tree, hf_hdr_cache_control, 2850 tvb, hdr_start, offset - hdr_start, val_str); 2851 ok = TRUE; 2852 } 2853 wkh_2_TextualValue; 2854 proto_tree_add_string(tree, hf_hdr_cache_control, 2855 tvb, hdr_start, offset - hdr_start, val_str); 2856 ok = TRUE; 2857 wkh_3_ValueWithLength; 2858 /* General form: 2859 * ( no-cache | private ) 1*( Field-name ) 2860 * | ( max-age | max-stale | min-fresh | s-maxage) Delta-seconds-value 2861 * | Token-text ( Integer-value | Text-value ) 2862 * Where: 2863 * Field-name = Short-integer | Token-text 2864 */ 2865 off = val_start + val_len_len; 2866 cache_control_directive = tvb_get_guint8(tvb, off++); 2867 if (cache_control_directive & 0x80) { /* Well known cache directive */ 2868 switch (cache_control_directive & 0x7F) { 2869 case CACHE_CONTROL_NO_CACHE: 2870 case CACHE_CONTROL_PRIVATE: 2871 cache_str = wmem_strbuf_new(wmem_packet_scope(), val_to_str_ext (cache_control_directive & 0x7F, &vals_cache_control_ext, 2872 "<Unknown cache control directive 0x%02X>")); 2873 /* TODO: split multiple entries */ 2874 ok = TRUE; 2875 while (ok && (off < offset)) { /* 1*( Field-name ) */ 2876 peek = tvb_get_guint8(tvb, off); 2877 if (peek & 0x80) { /* Well-known-field-name */ 2878 wmem_strbuf_append(cache_str, 2879 val_to_str (peek, vals_field_names, 2880 "<Unknown WSP header field 0x%02X>")); 2881 off++; 2882 } else { /* Token-text */ 2883 get_token_text(val_str, tvb, off, len, ok); 2884 if (ok) { 2885 wmem_strbuf_append(cache_str, val_str); 2886 off += len; 2887 } 2888 } 2889 } 2890 proto_tree_add_string(tree, hf_hdr_cache_control, 2891 tvb, hdr_start, offset - hdr_start, 2892 wmem_strbuf_get_str(cache_str)); 2893 break; 2894 2895 case CACHE_CONTROL_MAX_AGE: 2896 case CACHE_CONTROL_MAX_STALE: 2897 case CACHE_CONTROL_MIN_FRESH: 2898 case CACHE_CONTROL_S_MAXAGE: 2899 ti = proto_tree_add_string(tree, hf_hdr_cache_control, 2900 tvb, hdr_start, offset - hdr_start, 2901 val_to_str_ext (cache_control_directive & 0x7F, &vals_cache_control_ext, 2902 "<Unknown cache control directive 0x%02X>")); 2903 get_delta_seconds_value(val, tvb, off, len, ok); 2904 if (ok) { 2905 proto_item_append_text(ti, "=%u second%s", val, plurality(val, "", "s")); 2906 } 2907 break; 2908 2909 default: 2910 /* ok = FALSE */ 2911 break; 2912 } 2913 } else if (is_token_text(cache_control_directive)) { 2914 get_token_text(val_str, tvb, off, len, ok); 2915 if (ok) { 2916 ti = proto_tree_add_string(tree, hf_hdr_cache_control, 2917 tvb, hdr_start, offset - hdr_start, val_str); 2918 get_integer_value(val, tvb, off, len, ok); 2919 if (ok) { /* Integer-value */ 2920 proto_item_append_text(ti, "=%u", val); 2921 } else { /* Text-value */ 2922 get_text_string(val_str, tvb, off, len, ok); 2923 if (ok) { 2924 if (is_quoted_string(val_str[0])) { 2925 if (is_quoted_string(val_str[len-2])) { 2926 /* Trailing quote - issue a warning */ 2927 expert_add_info(pinfo, ti, &ei_wsp_trailing_quote); 2928 } else { /* OK (no trailing quote) */ 2929 proto_item_append_text(ti, "%s\"", val_str); 2930 } 2931 } else { /* Token-text | 0x00 */ 2932 /* TODO - check that we have Token-text or 0x00 */ 2933 proto_item_append_text(ti, "%s", val_str); 2934 } 2935 } 2936 } 2937 } 2938 } 2939 wkh_4_End(); 2940 } 2941 2942 2943 /* 2944 * Warning-value = 2945 * Short-integer 2946 * | ( Value-length Short-integer Text-string Text-string ) 2947 */ 2948 static guint32 2949 wkh_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 2950 { 2951 wkh_0_Declarations; 2952 guint32 off, len, val; 2953 guint8 warn_code; 2954 gchar *str; 2955 proto_item *ti = NULL; 2956 proto_tree *subtree; 2957 2958 /* TODO - subtree with values */ 2959 2960 wkh_1_WellKnownValue(hf_hdr_name_value, ett_warning, "Warning"); 2961 val = val_id & 0x7F; 2962 val_str = try_val_to_str_ext(val, &vals_wsp_warning_code_ext); 2963 if (val_str) { 2964 ti = proto_tree_add_string(tree, hf_hdr_warning, 2965 tvb, hdr_start, offset - hdr_start, val_str); 2966 subtree = proto_item_add_subtree(ti, ett_header); 2967 proto_tree_add_uint(subtree, hf_hdr_warning_code, 2968 tvb, val_start, 1, val); 2969 ok = TRUE; 2970 } 2971 wkh_2_TextualValueInv; 2972 /* Invalid */ 2973 wkh_3_ValueWithLength; 2974 /* TODO - subtree with individual values */ 2975 off = val_start + val_len_len; 2976 warn_code = tvb_get_guint8(tvb, off); 2977 if (warn_code & 0x80) { /* Well known warn code */ 2978 val = warn_code & 0x7f; 2979 val_str = try_val_to_str_ext(val, &vals_wsp_warning_code_short_ext); 2980 if (val_str) { /* OK */ 2981 str = wmem_strdup_printf(wmem_packet_scope(), "code=%s", val_str); 2982 ti = proto_tree_add_string(tree, hf_hdr_warning, 2983 tvb, hdr_start, offset - hdr_start, str); 2984 subtree = proto_item_add_subtree(ti, ett_header); 2985 proto_tree_add_uint(subtree, hf_hdr_warning_code, 2986 tvb, off, 1, val); 2987 off++; /* Now skip to the warn-agent subfield */ 2988 get_text_string(str, tvb, off, len, ok); 2989 if (ok) { /* Valid warn-agent string */ 2990 proto_tree_add_string(subtree, hf_hdr_warning_agent, 2991 tvb, off, len, str); 2992 proto_item_append_text(ti, "; agent=%s", str); 2993 off += len; 2994 get_text_string(str, tvb, off, len, ok); 2995 if (ok) { /* Valid warn-text string */ 2996 proto_tree_add_string(subtree, 2997 hf_hdr_warning_text, 2998 tvb, off, len, str); 2999 proto_item_append_text(ti, "; text=%s", str); 3000 /*off += len;*/ 3001 } 3002 } 3003 } 3004 } 3005 wkh_4_End(); 3006 } 3007 3008 3009 /* 3010 * Profile-warning-value = 3011 * Short-integer 3012 * | ( Value-length Short-integer Text-string *( Date-value ) ) 3013 */ 3014 static guint32 3015 wkh_profile_warning(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 3016 { 3017 wkh_0_Declarations; 3018 guint32 off, len, val = 0; 3019 guint8 warn_code; 3020 proto_item *ti = NULL; 3021 3022 wkh_1_WellKnownValue(hf_hdr_name_value, ett_profile_warning, "Profile-warning"); 3023 val = val_id & 0x7F; 3024 val_str = try_val_to_str_ext(val, &vals_wsp_profile_warning_code_ext); 3025 if (val_str) { 3026 proto_tree_add_string(tree, hf_hdr_profile_warning, 3027 tvb, hdr_start, offset - hdr_start, val_str); 3028 ok = TRUE; 3029 } 3030 wkh_2_TextualValueInv; 3031 /* Invalid */ 3032 wkh_3_ValueWithLength; 3033 off = val_start + val_len_len; 3034 warn_code = tvb_get_guint8(tvb, off++); 3035 if (warn_code & 0x80) { /* Well known warn code */ 3036 val_str = try_val_to_str_ext(val, &vals_wsp_profile_warning_code_ext); 3037 if (val_str) { /* OK */ 3038 ti = proto_tree_add_string(tree, hf_hdr_profile_warning, 3039 tvb, hdr_start, offset - hdr_start, val_str); 3040 get_uri_value(val_str, tvb, off, len, ok); 3041 if (ok) { /* Valid warn-target string */ 3042 /* TODO: Why did we just call get_uri_value() and not use 3043 * the str, since the pointer to it is immediately 3044 * forgotten with the call to g_strdup_printf()? */ 3045 off += len; 3046 proto_item_append_text(ti, "; target=%s", val_str); 3047 /* Add zero or more dates */ 3048 while (ok && (off < offset)) { 3049 get_date_value(val, tvb, off, len, ok); 3050 if (ok) { /* Valid warn-text string */ 3051 off += len; 3052 proto_item_append_text(ti, "; date=%s", abs_time_secs_to_str(wmem_packet_scope(), val, ABSOLUTE_TIME_LOCAL, TRUE)); 3053 } 3054 } 3055 } 3056 } 3057 } 3058 wkh_4_End(); 3059 } 3060 3061 3062 /* Encoding-version-value = 3063 * Short-integer 3064 * | Text-string 3065 * | Length Short-integer [ Short-integer | text-string ] 3066 */ 3067 static guint32 wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb, 3068 guint32 hdr_start, packet_info *pinfo _U_) 3069 { 3070 wkh_0_Declarations; 3071 proto_item *ti = NULL; 3072 guint32 off, val, len; 3073 3074 wkh_1_WellKnownValue(hf_hdr_name_value, ett_encoding_version, "Encoding-version"); 3075 val = val_id & 0x7F; 3076 val_str = wmem_strdup_printf(wmem_packet_scope(), "%u.%u", val >> 4, val & 0x0F); 3077 proto_tree_add_string(tree, hf_hdr_encoding_version, 3078 tvb, hdr_start, offset - hdr_start, val_str); 3079 ok = TRUE; 3080 wkh_2_TextualValue; 3081 proto_tree_add_string(tree, hf_hdr_encoding_version, 3082 tvb, hdr_start, offset - hdr_start, val_str); 3083 ok = TRUE; 3084 wkh_3_ValueWithLength; 3085 off = val_start + val_len_len; 3086 val = tvb_get_guint8(tvb, off); 3087 if (val & 0x80) { /* Header Code Page */ 3088 val_str = wmem_strdup_printf(wmem_packet_scope(), "code-page=%u", val & 0x7F); 3089 ti = proto_tree_add_string(tree, hf_hdr_encoding_version, 3090 tvb, hdr_start, offset - hdr_start, val_str); 3091 off++; 3092 ok = TRUE; 3093 if (off < offset) { /* Extra version-value */ 3094 get_version_value(val,val_str,tvb,off,len,ok); 3095 if (ok) { /* Always creates a string if OK */ 3096 proto_item_append_text(ti, ": %s", val_str); 3097 } 3098 } 3099 } 3100 3101 wkh_4_End(); 3102 } 3103 3104 3105 /* Content-range-value = 3106 * Length Uintvar-integer ( 0x80 | Uintvar-integer ) 3107 */ 3108 static guint32 3109 wkh_content_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 3110 { 3111 wkh_0_Declarations; 3112 guint32 off, val, len; 3113 proto_item *ti = NULL; 3114 proto_tree *subtree = NULL; 3115 3116 wkh_1_WellKnownValue(hf_hdr_name_value, ett_content_range, "Content range"); 3117 /* Invalid */ 3118 wkh_2_TextualValueInv; 3119 /* Invalid */ 3120 wkh_3_ValueWithLength; 3121 off = val_start + val_len_len; 3122 get_uintvar_integer (val, tvb, off, len, ok); /* Uintvar start */ 3123 if (ok) { 3124 val_str = wmem_strdup_printf(wmem_packet_scope(), "first-byte-pos=%u", val); 3125 ti = proto_tree_add_string(tree, hf_hdr_content_range, 3126 tvb, hdr_start, offset - hdr_start, val_str); 3127 subtree = proto_item_add_subtree(ti, ett_header); 3128 proto_tree_add_uint(subtree, hf_hdr_content_range_first_byte_pos, 3129 tvb, off, len, val); 3130 off += len; 3131 /* Now check next value */ 3132 val = tvb_get_guint8(tvb, off); 3133 if (val == 0x80) { /* Unknown length */ 3134 proto_item_append_text(ti, "%s", "; entity-length=unknown"); 3135 } else { /* Uintvar entity length */ 3136 get_uintvar_integer (val, tvb, off, len, ok); 3137 if (ok) { 3138 proto_item_append_text(ti, "; entity-length=%u", val); 3139 proto_tree_add_uint(subtree, 3140 hf_hdr_content_range_entity_length, 3141 tvb, off, len, val); 3142 } 3143 } 3144 } 3145 3146 wkh_4_End(); 3147 } 3148 3149 3150 /* Range-value = 3151 * Length 3152 * 0x80 Uintvar-integer [ Uintvar-integer ] 3153 * | 0x81 Uintvar-integer 3154 */ 3155 static guint32 3156 wkh_range(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 3157 { 3158 wkh_0a_Declarations; 3159 guint32 off, val, len; 3160 proto_item *ti = NULL; 3161 proto_tree *subtree = NULL; 3162 3163 wkh_1_WellKnownValue(hf_hdr_name_value, ett_range, "Range"); 3164 /* Invalid */ 3165 wkh_2_TextualValueInv; 3166 /* Invalid */ 3167 wkh_3_ValueWithLength; 3168 off = val_start + val_len_len; 3169 val = tvb_get_guint8(tvb, off); 3170 if (val == 0x80) { /* Byte-range */ 3171 ti = proto_tree_add_string(tree, hf_hdr_range, 3172 tvb, hdr_start, offset - hdr_start, "byte-range"); 3173 subtree = proto_item_add_subtree(ti, ett_header); 3174 /* Get the First-byte-pos (Uintvar-integer) */ 3175 get_uintvar_integer (val, tvb, off, len, ok); 3176 if (ok) { 3177 proto_item_append_text(ti, "; first-byte-pos=%u", val); 3178 proto_tree_add_uint(subtree, hf_hdr_range_first_byte_pos, 3179 tvb, off, len, val); 3180 off += len; 3181 /* Get the optional Last-byte-pos (Uintvar-integer) */ 3182 if (off < offset) { 3183 get_uintvar_integer (val, tvb, off, len, ok); 3184 if (ok) { 3185 proto_item_append_text(ti, "; last-byte-pos=%u", val); 3186 proto_tree_add_uint(subtree, 3187 hf_hdr_range_last_byte_pos, 3188 tvb, off, len, val); 3189 } 3190 } 3191 } 3192 } else if (val == 0x81) { /* Suffix-byte-range */ 3193 ti = proto_tree_add_string(tree, hf_hdr_range, 3194 tvb, hdr_start, offset - hdr_start, "suffix-byte-range"); 3195 subtree = proto_item_add_subtree(ti, ett_header); 3196 /* Get the Suffix-length (Uintvar-integer) */ 3197 get_uintvar_integer (val, tvb, off, len, ok); 3198 if (ok) { 3199 proto_item_append_text(ti, "; suffix-length=%u", val); 3200 proto_tree_add_uint(subtree, hf_hdr_range_suffix_length, 3201 tvb, off, len, val); 3202 } 3203 } 3204 3205 wkh_4_End(); 3206 } 3207 3208 3209 /* TE-value = 3210 * 0x81 3211 * | Value-length (0x82--0x86 | Token-text) [ Q-token Q-value ] 3212 */ 3213 static guint32 wkh_te (proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 3214 { 3215 wkh_0_Declarations; 3216 guint32 off, val, len; 3217 3218 wkh_1_WellKnownValue(hf_hdr_name_value, ett_te_value, "TE-value"); 3219 if (val_id == 0x81) { 3220 proto_tree_add_string(tree, hf_hdr_encoding_version, 3221 tvb, hdr_start, offset - hdr_start, "trailers"); 3222 ok = TRUE; 3223 } 3224 wkh_2_TextualValueInv; 3225 /* Invalid */ 3226 wkh_3_ValueWithLength; 3227 off = val_start + val_len_len; 3228 val = tvb_get_guint8(tvb, off); 3229 if (val & 0x80) { /* Well-known-TE */ 3230 val_str = try_val_to_str_ext((val & 0x7F), &vals_well_known_te_ext); 3231 if (val_str) { 3232 proto_tree_add_string(tree, hf_hdr_te, 3233 tvb, hdr_start, off - hdr_start, val_str); 3234 off++; 3235 ok = TRUE; 3236 } 3237 } else { /* TE in Token-text format */ 3238 get_token_text(val_str, tvb, off, len, ok); 3239 if (ok) { 3240 proto_tree_add_string(tree, hf_hdr_te, 3241 tvb, hdr_start, off - hdr_start, val_str); 3242 off += len; 3243 } 3244 } 3245 if ((ok) && (off < offset)) { /* Q-token Q-value */ 3246 /* TODO */ 3247 } 3248 3249 wkh_4_End(); 3250 } 3251 3252 3253 /**************************************************************************** 3254 * O p e n w a v e h e a d e r s 3255 ****************************************************************************/ 3256 3257 3258 /* Dissect the Openwave header value (generic) */ 3259 static guint32 3260 wkh_openwave_default(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo _U_) 3261 { 3262 wkh_0_Declarations; 3263 guint8 hdr_id = tvb_get_guint8 (tvb, hdr_start) & 0x7F; 3264 3265 ok = TRUE; /* Bypass error checking as we don't parse the values! */ 3266 3267 wkh_1_WellKnownValue(hf_hdr_openwave_name_value, ett_openwave_default, "Default"); 3268 proto_tree_add_uint_format(tree, hf_hdr_openwave_default_int, tvb, hdr_start, offset - hdr_start, 3269 val_id & 0x7F, "%s: (Undecoded well-known value 0x%02x)", 3270 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext, 3271 "<Unknown WSP header field 0x%02X>"), val_id & 0x7F); 3272 wkh_2_TextualValue; 3273 proto_tree_add_string_format(tree, hf_hdr_openwave_default_string, tvb, hdr_start, offset - hdr_start, 3274 "%s: %s", 3275 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext, 3276 "<Unknown WSP header field 0x%02X>"), val_str); 3277 wkh_3_ValueWithLength; 3278 proto_tree_add_uint_format(tree, hf_hdr_openwave_default_val_len, tvb, hdr_start, offset - hdr_start, 3279 val_len, "%s: (Undecoded value in general form with length indicator)", 3280 val_to_str_ext (hdr_id, &vals_openwave_field_names_ext, 3281 "<Unknown WSP header field 0x%02X>")); 3282 3283 wkh_4_End(); /* See wkh_default for explanation */ 3284 } 3285 3286 3287 /* Textual Openwave headers */ 3288 wkh_text_header(openwave_x_up_proxy_operator_domain, 3289 "x-up-proxy-operator-domain") 3290 wkh_text_header(openwave_x_up_proxy_home_page, 3291 "x-up-proxy-home-page") 3292 wkh_text_header(openwave_x_up_proxy_uplink_version, 3293 "x-up-proxy-uplink-version") 3294 wkh_text_header(openwave_x_up_proxy_ba_realm, 3295 "x-up-proxy-ba-realm") 3296 wkh_text_header(openwave_x_up_proxy_request_uri, 3297 "x-up-proxy-request-uri") 3298 wkh_text_header(openwave_x_up_proxy_bookmark, 3299 "x-up-proxy-bookmark") 3300 3301 /* Integer Openwave headers */ 3302 wkh_integer_value_header(openwave_x_up_proxy_push_seq, 3303 "x-up-proxy-push-seq") 3304 wkh_integer_value_header(openwave_x_up_proxy_notify, 3305 "x-up-proxy-notify") 3306 wkh_integer_value_header(openwave_x_up_proxy_net_ask, 3307 "x-up-proxy-net-ask") 3308 wkh_integer_value_header(openwave_x_up_proxy_ba_enable, 3309 "x-up-proxy-ba-enable") 3310 wkh_integer_value_header(openwave_x_up_proxy_redirect_enable, 3311 "x-up-proxy-redirect-enable") 3312 wkh_integer_value_header(openwave_x_up_proxy_redirect_status, 3313 "x-up-proxy-redirect-status") 3314 wkh_integer_value_header(openwave_x_up_proxy_linger, 3315 "x-up-proxy-linger") 3316 wkh_integer_value_header(openwave_x_up_proxy_enable_trust, 3317 "x-up-proxy-enable-trust") 3318 wkh_integer_value_header(openwave_x_up_proxy_trust, 3319 "x-up-proxy-trust") 3320 3321 wkh_integer_value_header(openwave_x_up_devcap_has_color, 3322 "x-up-devcap-has-color") 3323 wkh_integer_value_header(openwave_x_up_devcap_num_softkeys, 3324 "x-up-devcap-num-softkeys") 3325 wkh_integer_value_header(openwave_x_up_devcap_softkey_size, 3326 "x-up-devcap-softkey-size") 3327 wkh_integer_value_header(openwave_x_up_devcap_screen_chars, 3328 "x-up-devcap-screen-chars") 3329 wkh_integer_value_header(openwave_x_up_devcap_screen_pixels, 3330 "x-up-devcap-screen-pixels") 3331 wkh_integer_value_header(openwave_x_up_devcap_em_size, 3332 "x-up-devcap-em-size") 3333 wkh_integer_value_header(openwave_x_up_devcap_screen_depth, 3334 "x-up-devcap-screen-depth") 3335 wkh_integer_value_header(openwave_x_up_devcap_immed_alert, 3336 "x-up-devcap-immed_alert") 3337 wkh_integer_value_header(openwave_x_up_devcap_gui, 3338 "x-up-devcap-gui") 3339 3340 /* Openwave Time-Of-Day value header */ 3341 wkh_tod_value_header(openwave_x_up_proxy_tod, 3342 "x-up-proxy-tod") 3343 3344 /* Openwave accept_x_q header */ 3345 wkh_accept_x_q_header(openwave_x_up_proxy_trans_charset, 3346 "x-up-proxy-trans-charset", 3347 &mibenum_vals_character_sets_ext, "character set") 3348 3349 /* Openwave content type header */ 3350 static guint32 3351 wkh_openwave_x_up_proxy_push_accept(proto_tree *tree, tvbuff_t *tvb, guint32 hdr_start, packet_info *pinfo) 3352 { 3353 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_openwave_x_up_proxy_push_accept, "x-up-proxy-push-accept"); 3354 } 3355 3356 3357 static gboolean parameter_text(proto_tree *tree, tvbuff_t *tvb, int *offset, proto_item *ti, int hf) 3358 { 3359 gchar *val_str; 3360 gboolean ok; 3361 guint32 val_len; 3362 3363 get_text_string(val_str, tvb, (*offset), val_len, ok); 3364 if (ok) { 3365 proto_tree_add_string(tree, hf, tvb, *offset, val_len, val_str); 3366 proto_item_append_text(ti, "; %s=%s", proto_registrar_get_name(hf), val_str); 3367 (*offset) += val_len; 3368 } 3369 3370 return ok; 3371 } 3372 3373 static gboolean parameter_text_value(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int *offset, proto_item *ti, int hf) 3374 { 3375 gchar *val_str, *str; 3376 gboolean ok; 3377 guint32 val_len; 3378 proto_item* ti2; 3379 3380 get_text_string(val_str, tvb, (*offset), val_len, ok); 3381 if (ok) { 3382 if (is_quoted_string(val_str[0])) { 3383 if (is_quoted_string(val_str[val_len-2])) { 3384 /* Trailing quote - issue a warning */ 3385 ti2 = proto_tree_add_string(tree, hf, 3386 tvb, *offset, val_len, val_str); 3387 expert_add_info(pinfo, ti2, &ei_wsp_trailing_quote); 3388 } else { /* OK (no trailing quote) */ 3389 str = wmem_strdup_printf(wmem_packet_scope(), "%s\"", val_str); 3390 proto_tree_add_string(tree, hf, 3391 tvb, *offset, val_len, str); 3392 } 3393 } else { /* Token-text | 0x00 */ 3394 /* TODO - verify that we have either Token-text or 0x00 */ 3395 proto_tree_add_string(tree, hf, 3396 tvb, *offset, val_len, val_str); 3397 } 3398 proto_item_append_text(ti, "; %s=%s", proto_registrar_get_name(hf), val_str); 3399 (*offset) += val_len; 3400 } 3401 3402 return ok; 3403 } 3404 3405 static const value_string parameter_type_vals[] = { 3406 { 0x00, "Q: Q-value" }, 3407 { 0x01, "Well-known-charset" }, 3408 { 0x02, "Level: Version-value" }, 3409 { 0x03, "Integer-value" }, 3410 { 0x05, "Name (Text-string)" }, 3411 { 0x06, "Filename (Text-string)" }, 3412 { 0x07, "Differences" }, 3413 { 0x08, "Padding" }, 3414 { 0x09, "Special Constrained-encoding" }, 3415 { 0x0A, "Start (Text-string)" }, 3416 { 0x0B, "Start-info (Text-string)" }, 3417 { 0x0C, "Comment (Text-string)" }, 3418 { 0x0D, "Domain (Text-string)" }, 3419 { 0x0E, "Max-Age" }, 3420 { 0x0F, "Path (Text-string)" }, 3421 { 0x10, "Secure" }, 3422 { 0x11, "SEC: Short-integer" }, 3423 { 0x12, "MAC: Text-value" }, 3424 { 0x13, "Creation-date" }, 3425 { 0x14, "Modification-date" }, 3426 { 0x15, "Read-date" }, 3427 { 0x16, "Size: Integer-value" }, 3428 { 0x17, "Name (Text-value)" }, 3429 { 0x18, "Filename (Text-value)" }, 3430 { 0x19, "Start (with multipart/related) (Text-value)" }, 3431 { 0x1A, "Start-info (with multipart/related) (Text-value)" }, 3432 { 0x1B, "Comment (Text-value)" }, 3433 { 0x1C, "Domain (Text-value)" }, 3434 { 0x1D, "Path (Text-value)" }, 3435 3436 { 0x00, NULL } 3437 }; 3438 3439 static value_string_ext parameter_type_vals_ext = VALUE_STRING_EXT_INIT(parameter_type_vals); 3440 3441 /* Parameter = Untyped-parameter | Typed-parameter 3442 * Untyped-parameter = Token-text ( Integer-value | Text-value ) 3443 * Typed-parameter = 3444 * Integer-value ( 3445 * ( Integer-value | Date-value | Delta-seconds-value 3446 * | Q-value | Version-value | Uri-value ) 3447 * | Text-value ) 3448 * 3449 * 3450 * Returns: next offset 3451 * 3452 * TODO - Verify byte highlighting in case of invalid parameter values 3453 */ 3454 static int 3455 parameter (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start, int len) 3456 { 3457 int offset = start; 3458 guint8 peek = tvb_get_guint8 (tvb,start); 3459 guint32 val = 0, type = 0, type_len, val_len; 3460 const gchar *str = NULL; 3461 const gchar *val_str = NULL; 3462 gboolean ok; 3463 proto_item* ti2; 3464 3465 if (is_token_text (peek)) { 3466 /* 3467 * Untyped parameter 3468 */ 3469 get_token_text (str,tvb,start,val_len,ok); /* Should always succeed */ 3470 if (ok) { /* Found a textual parameter name: str */ 3471 offset += val_len; 3472 get_text_value(val_str, tvb, offset, val_len, ok); 3473 if (ok) { /* Also found a textual parameter value: val_str */ 3474 offset += val_len; 3475 if (is_quoted_string(val_str[0])) { /* Add trailing quote! */ 3476 if (is_quoted_string(val_str[val_len-2])) { 3477 /* Trailing quote - issue a warning */ 3478 ti2 = proto_tree_add_string_format(tree, hf_wsp_parameter_untype_quote_text, 3479 tvb, start, offset - start, val_str, 3480 "%s: %s", str, val_str); 3481 expert_add_info(pinfo, ti2, &ei_wsp_trailing_quote); 3482 proto_item_append_text(ti, "; %s=%s", str, val_str); 3483 } else { /* OK (no trailing quote) */ 3484 proto_tree_add_string_format(tree, hf_wsp_parameter_untype_quote_text, 3485 tvb, start, offset - start, val_str, 3486 "%s: %s\"", str, val_str); 3487 proto_item_append_text(ti, "; %s=%s\"", str, val_str); 3488 } 3489 } else { /* Token-text | 0x00 */ 3490 /* TODO - verify that it is either Token-text or 0x00 3491 * and flag with warning if invalid */ 3492 proto_tree_add_string_format(tree, hf_wsp_parameter_untype_text, 3493 tvb, start, offset - start, val_str, 3494 "%s: %s", str, val_str); 3495 proto_item_append_text(ti, "; %s=%s", str, val_str); 3496 } 3497 } else { /* Try integer value */ 3498 get_integer_value (val,tvb,offset,val_len,ok); 3499 if (ok) { /* Also found a valid integer parameter value: val */ 3500 offset += val_len; 3501 proto_tree_add_uint_format(tree, hf_wsp_parameter_untype_int, tvb, start, offset - start, 3502 val, "%s: %u", str, val); 3503 proto_item_append_text(ti, "; %s=%u", str, val); 3504 } else { /* Error: neither token-text not Integer-value */ 3505 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, offset - start, 3506 "Invalid untyped parameter definition"); 3507 offset = start + len; /* Skip to end of buffer */ 3508 } 3509 } 3510 } 3511 return offset; 3512 } 3513 /* 3514 * Else: Typed parameter 3515 */ 3516 get_integer_value (type,tvb,start,type_len,ok); 3517 if (!ok) { 3518 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, offset - start, 3519 "Invalid typed parameter definition"); 3520 return (start + len); /* Skip to end of buffer */ 3521 } 3522 offset += type_len; 3523 /* Now offset points to the parameter value */ 3524 proto_tree_add_uint(tree, hf_wsp_parameter_type, tvb, start, type_len, type); 3525 3526 switch (type) { 3527 case 0x01: /* WSP 1.1 encoding - Charset: Well-known-charset */ 3528 get_integer_value(val, tvb, offset, val_len, ok); 3529 if (ok) { 3530 val_str = val_to_str_ext(val, &mibenum_vals_character_sets_ext, 3531 "<Unknown character set Identifier %u>"); 3532 proto_tree_add_string(tree, hf_parameter_charset, 3533 tvb, offset, val_len, val_str); 3534 proto_item_append_text(ti, "; charset=%s", val_str); 3535 offset += val_len; 3536 } else { 3537 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3538 "Invalid Charset parameter value: invalid Integer-value"); 3539 offset = start + len; /* Skip to end of buffer */ 3540 } 3541 break; 3542 3543 case 0x03: /* WSP 1.1 encoding - Type: Integer-value */ 3544 get_integer_value (val,tvb,offset,val_len,ok); 3545 if (ok) { 3546 proto_tree_add_uint (tree, hf_wsp_parameter_int_type, 3547 tvb, offset, val_len, val); 3548 proto_item_append_text(ti, "; Type=%u", val); 3549 offset += val_len; 3550 } else { 3551 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3552 "Invalid Type parameter value: invalid Integer-value"); 3553 offset = start + len; /* Skip to end of buffer */ 3554 } 3555 break; 3556 3557 case 0x05: /* WSP 1.1 encoding - Name: Text-string */ 3558 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_name)) 3559 { 3560 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3561 "Invalid Name (WSP 1.1 encoding) parameter value: invalid Text-string"); 3562 offset = start + len; /* Skip to end of buffer */ 3563 } 3564 break; 3565 case 0x17: /* WSP 1.4 encoding - Name: Text-value */ 3566 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_name)) 3567 { 3568 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3569 "Invalid Name (WSP 1.4 encoding) parameter value: invalid Text-value"); 3570 offset = start + len; /* Skip to end of buffer */ 3571 } 3572 break; 3573 3574 case 0x06: /* WSP 1.1 encoding - Filename: Text-string */ 3575 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_filename)) 3576 { 3577 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3578 "Invalid Filename (WSP 1.1 encoding) parameter value: invalid Text-string"); 3579 offset = start + len; /* Skip to end of buffer */ 3580 } 3581 break; 3582 case 0x18: /* WSP 1.4 encoding - Filename: Text-value */ 3583 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_filename)) 3584 { 3585 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3586 "Invalid Filename (WSP 1.4 encoding) parameter value: invalid Text-value"); 3587 offset = start + len; /* Skip to end of buffer */ 3588 } 3589 break; 3590 3591 case 0x09: /* WSP 1.2 encoding - Type (special): Constrained-encoding */ 3592 /* This is similar to the Content-Type header decoding, 3593 * but it is much simpler: 3594 * Constrained-encoding = Short-integer | Extension-media 3595 * Extension-media = *TEXT <Octet 0> 3596 */ 3597 get_extension_media(val_str,tvb,offset,val_len,ok); 3598 if (ok) { /* Extension-media */ 3599 proto_tree_add_string (tree, hf_wsp_parameter_upart_type, 3600 tvb, offset, val_len, val_str); 3601 proto_item_append_text(ti, "; type=%s", val_str); 3602 offset += val_len; 3603 } else { 3604 get_short_integer(val,tvb,offset,val_len,ok); 3605 if (ok) { 3606 proto_tree_add_string (tree, hf_wsp_parameter_upart_type, 3607 tvb, offset, val_len, val_to_str_ext(val, &vals_content_types_ext, 3608 "(Unknown content type identifier 0x%X)")); 3609 offset += val_len; 3610 } /* Else: invalid parameter value */ 3611 } 3612 if (!ok) { 3613 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3614 "Invalid Type parameter value: invalid Constrained-encoding"); 3615 offset = start + len; /* Skip the parameters */ 3616 } 3617 break; 3618 3619 case 0x0A: /* WSP 1.2 encoding - Start: Text-string */ 3620 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_start)) 3621 { 3622 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3623 "Invalid Start (WSP 1.2 encoding) parameter value: invalid Text-string"); 3624 offset = start + len; /* Skip to end of buffer */ 3625 } 3626 break; 3627 case 0x19: /* WSP 1.4 encoding - Start (with multipart/related): Text-value */ 3628 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_start)) 3629 { 3630 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3631 "Invalid Start (with multipart/related) parameter value: invalid Text-value"); 3632 offset = start + len; /* Skip to end of buffer */ 3633 } 3634 break; 3635 3636 case 0x0B: /* WSP 1.2 encoding - Start-info: Text-string */ 3637 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_start_info)) 3638 { 3639 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3640 "Invalid Start-info (WSP 1.2 encoding) parameter value: invalid Text-string"); 3641 offset = start + len; /* Skip to end of buffer */ 3642 } 3643 break; 3644 case 0x1A: /* WSP 1.4 encoding - Start-info (with multipart/related): Text-value */ 3645 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_start_info)) 3646 { 3647 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3648 "Invalid Start-info (WSP 1.4 encoding) parameter value: invalid Text-value"); 3649 offset = start + len; /* Skip to end of buffer */ 3650 } 3651 break; 3652 3653 case 0x0C: /* WSP 1.3 encoding - Comment: Text-string */ 3654 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_comment)) 3655 { 3656 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3657 "Invalid Comment (WSP 1.3 encoding) parameter value: invalid Text-string"); 3658 offset = start + len; /* Skip to end of buffer */ 3659 } 3660 break; 3661 case 0x1B: /* WSP 1.4 encoding - Comment: Text-value */ 3662 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_comment)) 3663 { 3664 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3665 "Invalid Comment (WSP 1.4 encoding) parameter value: invalid Text-value"); 3666 offset = start + len; /* Skip to end of buffer */ 3667 } 3668 break; 3669 3670 case 0x0D: /* WSP 1.3 encoding - Domain: Text-string */ 3671 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_domain)) 3672 { 3673 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3674 "Invalid Domain (WSP 1.3 encoding) parameter value: invalid Text-string"); 3675 offset = start + len; /* Skip to end of buffer */ 3676 } 3677 break; 3678 case 0x1C: /* WSP 1.4 encoding - Domain: Text-value */ 3679 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_domain)) 3680 { 3681 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3682 "Invalid Domain (WSP 1.4 encoding) parameter value: invalid Text-value"); 3683 offset = start + len; /* Skip to end of buffer */ 3684 } 3685 break; 3686 3687 case 0x0F: /* WSP 1.3 encoding - Path: Text-string */ 3688 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_path)) 3689 { 3690 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3691 "Invalid Path (WSP 1.3 encoding) parameter value: invalid Text-string"); 3692 offset = start + len; /* Skip to end of buffer */ 3693 } 3694 break; 3695 case 0x1D: /* WSP 1.4 encoding - Path: Text-value */ 3696 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_path)) 3697 { 3698 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3699 "Invalid Path (WSP 1.4 encoding) parameter value: invalid Text-value"); 3700 offset = start + len; /* Skip to end of buffer */ 3701 } 3702 break; 3703 3704 case 0x11: /* WSP 1.4 encoding - SEC: Short-integer (OCTET) */ 3705 peek = tvb_get_guint8 (tvb, start+1); 3706 if (peek & 0x80) { /* Valid Short-integer */ 3707 peek &= 0x7F; 3708 proto_tree_add_uint (tree, hf_wsp_parameter_sec, 3709 tvb, offset, 1, peek); 3710 proto_item_append_text(ti, "; SEC=%s", val_to_str_ext_const(peek, &vals_wsp_parameter_sec_ext, "Undefined")); 3711 offset++; 3712 } else { /* Error */ 3713 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3714 "Invalid SEC parameter value: invalid Short-integer-value"); 3715 offset = start + len; /* Skip to end of buffer */ 3716 } 3717 break; 3718 3719 case 0x12: /* WSP 1.4 encoding - MAC: Text-value */ 3720 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_mac)) 3721 { 3722 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3723 "Invalid MAC (WSP 1.4 encoding) parameter value: invalid Text-value"); 3724 offset = start + len; /* Skip to end of buffer */ 3725 } 3726 break; 3727 3728 case 0x02: /* WSP 1.1 encoding - Level: Version-value */ 3729 get_version_value(val,str,tvb,offset,val_len,ok); 3730 if (ok) { 3731 proto_tree_add_string (tree, hf_wsp_parameter_level, 3732 tvb, offset, val_len, str); 3733 proto_item_append_text(ti, "; level=%s", str); 3734 offset += val_len; 3735 } else { 3736 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3737 "Invalid Level parameter value: invalid Version-value"); 3738 offset = start + len; /* Skip to end of buffer */ 3739 } 3740 break; 3741 3742 case 0x00: /* WSP 1.1 encoding - Q: Q-value */ 3743 offset = parameter_value_q(tree, pinfo, ti, tvb, offset); 3744 break; 3745 3746 case 0x16: /* WSP 1.4 encoding - Size: Integer-value */ 3747 get_integer_value (val,tvb,offset,val_len,ok); 3748 if (ok) { 3749 proto_tree_add_uint (tree, hf_wsp_parameter_size, 3750 tvb, offset, val_len, val); 3751 proto_item_append_text(ti, "; Size=%u", val); 3752 offset += val_len; 3753 } else { 3754 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, len, 3755 "Invalid Size parameter value: invalid Integer-value"); 3756 offset = start + len; /* Skip to end of buffer */ 3757 } 3758 break; 3759 3760 /* 3761 * TODO 3762 */ 3763 3764 case 0x07: /* WSP 1.1 encoding - Differences: Field-name */ 3765 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start, 3766 "Undecoded parameter Differences"); 3767 offset = start + len; /* Skip the parameters */ 3768 break; 3769 3770 case 0x08: /* WSP 1.1 encoding - Padding: Short-integer */ 3771 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start, 3772 "Undecoded parameter Padding"); 3773 offset = start + len; /* Skip the parameters */ 3774 break; 3775 3776 case 0x0E: /* WSP 1.3 encoding - Max-Age: Delta-seconds-value */ 3777 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start, 3778 "Undecoded parameter Max-Age"); 3779 offset = start + len; /* Skip the parameters */ 3780 break; 3781 3782 case 0x10: /* WSP 1.3 encoding - Secure: No-value */ 3783 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start, 3784 "Undecoded parameter Secure"); 3785 offset = start + len; /* Skip the parameters */ 3786 break; 3787 3788 case 0x13: /* WSP 1.4 encoding - Creation-date: Date-value */ 3789 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start, 3790 "Undecoded parameter Creation-Date"); 3791 offset = start + len; /* Skip the parameters */ 3792 break; 3793 3794 case 0x14: /* WSP 1.4 encoding - Modification-date: Date-value */ 3795 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start, 3796 "Undecoded parameter Modification-Date"); 3797 offset = start + len; /* Skip the parameters */ 3798 break; 3799 3800 case 0x15: /* WSP 1.4 encoding - Read-date: Date-value */ 3801 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start, 3802 "Undecoded parameter Read-Date"); 3803 offset = start + len; /* Skip the parameters */ 3804 break; 3805 3806 default: 3807 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_undecoded_parameter, tvb, start, offset - start, 3808 "Undecoded parameter type 0x%02x", type); 3809 offset = start + len; /* Skip the parameters */ 3810 break; 3811 } 3812 return offset; 3813 } 3814 3815 3816 /* 3817 * Dissects the Q-value parameter value. 3818 * 3819 * Returns: next offset 3820 */ 3821 static int 3822 parameter_value_q (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start) 3823 { 3824 int offset = start; 3825 guint32 val = 0, val_len; 3826 gchar *str = NULL; 3827 guint8 ok; 3828 3829 get_uintvar_integer (val, tvb, offset, val_len, ok); 3830 if (ok && (val < 1100)) { 3831 if (val <= 100) { /* Q-value in 0.01 steps */ 3832 str = wmem_strdup_printf(wmem_packet_scope(), "0.%02u", val - 1); 3833 } else { /* Q-value in 0.001 steps */ 3834 str = wmem_strdup_printf(wmem_packet_scope(), "0.%03u", val - 100); 3835 } 3836 proto_item_append_text(ti, "; q=%s", str); 3837 proto_tree_add_string (tree, hf_parameter_q, 3838 tvb, start, val_len, str); 3839 offset += val_len; 3840 } else { 3841 proto_tree_add_expert_format(tree, pinfo, &ei_wsp_invalid_parameter_value, tvb, start, offset, 3842 "Invalid Q parameter value: invalid Q-value"); 3843 offset += val_len; 3844 } 3845 return offset; 3846 } 3847 3848 static int * const address_length_flags[] = { 3849 &hf_address_flags_length_bearer_type_included, 3850 &hf_address_flags_length_port_number_included, 3851 &hf_address_flags_length_address_len, 3852 NULL 3853 }; 3854 3855 /* Code to actually dissect the packets */ 3856 3857 /* 3858 * WSP redirect 3859 */ 3860 3861 /* Dissect a WSP redirect PDU. 3862 * Looks up or builds conversations, so parts of the code must always run, 3863 * even if tree is NULL. 3864 */ 3865 static void 3866 dissect_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo, 3867 proto_tree *tree, dissector_handle_t dissector_handle) 3868 { 3869 proto_item *ti; 3870 proto_tree *addresses_tree; 3871 proto_tree *addr_tree = NULL; 3872 guint8 bearer_type; 3873 guint8 address_flags_len; 3874 int address_len; 3875 guint16 port_num; 3876 guint32 address_ipv4; 3877 ws_in6_addr address_ipv6; 3878 address redir_address; 3879 conversation_t *conv; 3880 guint32 idx = 0; /* Address index */ 3881 guint32 address_record_len; /* Length of the entire address record */ 3882 static int * const flags[] = { 3883 &hf_wsp_redirect_permanent, 3884 &hf_wsp_redirect_reuse_security_session, 3885 NULL 3886 }; 3887 3888 3889 /* 3890 * Redirect flags. 3891 */ 3892 proto_tree_add_bitmask(tree, tvb, offset, hf_wsp_redirect_flags, ett_redirect_flags, flags, ENC_NA); 3893 offset++; 3894 3895 /* 3896 * Redirect addresses. 3897 */ 3898 ti = proto_tree_add_item(tree, hf_redirect_addresses, tvb, 0, -1, ENC_NA); 3899 addresses_tree = proto_item_add_subtree(ti, ett_addresses); 3900 3901 while (tvb_reported_length_remaining (tvb, offset) > 0) { 3902 idx++; 3903 /* 3904 * Read a single address at a time. 3905 */ 3906 address_flags_len = tvb_get_guint8 (tvb, offset); 3907 address_len = address_flags_len & ADDRESS_LEN; 3908 address_record_len = address_len 3909 + (address_flags_len & BEARER_TYPE_INCLUDED ? 1 : 0) 3910 + (address_flags_len & PORT_NUMBER_INCLUDED ? 2 : 0) 3911 ; 3912 3913 ti = proto_tree_add_uint(addresses_tree, hf_address_entry, 3914 tvb, offset, 1 + address_record_len, idx); 3915 addr_tree = proto_item_add_subtree(ti, ett_address); 3916 3917 proto_tree_add_bitmask(addr_tree, tvb, offset, hf_address_flags_length, ett_address_flags, address_length_flags, ENC_NA); 3918 offset++; 3919 if (address_flags_len & BEARER_TYPE_INCLUDED) { 3920 bearer_type = tvb_get_guint8 (tvb, offset); 3921 proto_tree_add_uint (addr_tree, hf_address_bearer_type, 3922 tvb, offset, 1, bearer_type); 3923 offset++; 3924 } else { 3925 bearer_type = 0x00; /* XXX */ 3926 } 3927 if (address_flags_len & PORT_NUMBER_INCLUDED) { 3928 port_num = tvb_get_ntohs (tvb, offset); 3929 proto_tree_add_uint (addr_tree, hf_address_port_num, 3930 tvb, offset, 2, port_num); 3931 offset += 2; 3932 } else { 3933 /* 3934 * Redirecting to the same server port number as was 3935 * being used, i.e. the source port number of this 3936 * redirect. 3937 */ 3938 port_num = pinfo->srcport; 3939 } 3940 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) { 3941 /* 3942 * We don't have the bearer type in the message, 3943 * so we don't know the address type. 3944 * (It's the same bearer type as the original 3945 * connection.) 3946 */ 3947 goto unknown_address_type; 3948 } 3949 3950 /* 3951 * We know the bearer type, so we know the address type. 3952 */ 3953 switch (bearer_type) { 3954 3955 case BT_IPv4: 3956 case BT_IS_95_CSD: 3957 case BT_IS_95_PACKET_DATA: 3958 case BT_ANSI_136_CSD: 3959 case BT_ANSI_136_PACKET_DATA: 3960 case BT_GSM_CSD: 3961 case BT_GSM_GPRS: 3962 case BT_GSM_USSD_IPv4: 3963 case BT_AMPS_CDPD: 3964 case BT_PDC_CSD: 3965 case BT_PDC_PACKET_DATA: 3966 case BT_IDEN_CSD: 3967 case BT_IDEN_PACKET_DATA: 3968 case BT_PHS_CSD: 3969 case BT_TETRA_PACKET_DATA: 3970 /* 3971 * IPv4. 3972 */ 3973 if (address_len != 4) { 3974 /* 3975 * Say what? 3976 */ 3977 goto unknown_address_type; 3978 } 3979 address_ipv4 = tvb_get_ipv4(tvb, offset); 3980 proto_tree_add_ipv4 (addr_tree, hf_address_ipv4_addr, 3981 tvb, offset, 4, address_ipv4); 3982 3983 /* 3984 * Create a conversation so that the 3985 * redirected session will be dissected 3986 * as WAP. 3987 */ 3988 redir_address.type = AT_IPv4; 3989 redir_address.len = 4; 3990 redir_address.data = (const guint8 *)&address_ipv4; 3991 /* Find a conversation based on redir_address and pinfo->dst */ 3992 conv = find_conversation(pinfo->num, &redir_address, &pinfo->dst, 3993 ENDPOINT_UDP, port_num, 0, NO_PORT_B); 3994 if (conv == NULL) { /* This conversation does not exist yet */ 3995 conv = conversation_new(pinfo->num, &redir_address, 3996 &pinfo->dst, ENDPOINT_UDP, port_num, 0, NO_PORT2); 3997 } 3998 /* Apply WSP dissection to the conversation */ 3999 conversation_set_dissector(conv, dissector_handle); 4000 break; 4001 4002 case BT_IPv6: 4003 /* 4004 * IPv6. 4005 */ 4006 if (address_len != 16) { 4007 /* 4008 * Say what? 4009 */ 4010 goto unknown_address_type; 4011 } 4012 tvb_get_ipv6(tvb, offset, &address_ipv6); 4013 proto_tree_add_ipv6 (addr_tree, hf_address_ipv6_addr, 4014 tvb, offset, 16, &address_ipv6); 4015 4016 /* 4017 * Create a conversation so that the 4018 * redirected session will be dissected 4019 * as WAP. 4020 */ 4021 redir_address.type = AT_IPv6; 4022 redir_address.len = 16; 4023 redir_address.data = (const guint8 *)&address_ipv6; 4024 /* Find a conversation based on redir_address and pinfo->dst */ 4025 conv = find_conversation(pinfo->num, &redir_address, &pinfo->dst, 4026 ENDPOINT_UDP, port_num, 0, NO_PORT_B); 4027 if (conv == NULL) { /* This conversation does not exist yet */ 4028 conv = conversation_new(pinfo->num, &redir_address, 4029 &pinfo->dst, ENDPOINT_UDP, port_num, 0, NO_PORT2); 4030 } 4031 /* Apply WSP dissection to the conversation */ 4032 conversation_set_dissector(conv, dissector_handle); 4033 break; 4034 4035 unknown_address_type: 4036 default: 4037 if (address_len != 0) { 4038 proto_tree_add_item (addr_tree, hf_address_addr, 4039 tvb, offset, address_len, ENC_NA); 4040 } 4041 break; 4042 } 4043 offset += address_len; 4044 } /* while */ 4045 } 4046 4047 /* Add addresses to the protocol tree. 4048 * This is a display-only function, so return if tree is NULL 4049 */ 4050 static void 4051 add_addresses(proto_tree *tree, tvbuff_t *tvb, int hf) 4052 { 4053 proto_item *ti; 4054 proto_tree *addresses_tree; 4055 proto_tree *addr_tree; 4056 guint8 bearer_type; 4057 guint8 address_flags_len; 4058 int address_len; 4059 guint32 tvb_len = tvb_reported_length(tvb); 4060 guint32 offset = 0; 4061 guint32 idx = 0; /* Address index */ 4062 guint32 address_record_len; /* Length of the entire address record */ 4063 4064 /* Skip needless processing */ 4065 if (! tree) 4066 return; 4067 if (offset >= tvb_len) 4068 return; 4069 4070 /* 4071 * Addresses. 4072 */ 4073 /* XXX: the field pointed to by hf has a type of FT_NONE */ 4074 ti = proto_tree_add_item(tree, hf, tvb, 0, -1, ENC_NA); 4075 addresses_tree = proto_item_add_subtree(ti, ett_addresses); 4076 4077 while (offset < tvb_len) { 4078 idx++; 4079 /* 4080 * Read a single address at a time. 4081 */ 4082 address_flags_len = tvb_get_guint8 (tvb, offset); 4083 address_len = address_flags_len & ADDRESS_LEN; 4084 address_record_len = address_len 4085 + (address_flags_len & BEARER_TYPE_INCLUDED ? 1 : 0) 4086 + (address_flags_len & PORT_NUMBER_INCLUDED ? 2 : 0) 4087 ; 4088 4089 ti = proto_tree_add_uint(addresses_tree, hf_address_entry, 4090 tvb, offset, 1 + address_record_len, idx); 4091 addr_tree = proto_item_add_subtree(ti, ett_address); 4092 4093 proto_tree_add_bitmask(addr_tree, tvb, offset, hf_address_flags_length, ett_address_flags, address_length_flags, ENC_NA); 4094 offset++; 4095 if (address_flags_len & BEARER_TYPE_INCLUDED) { 4096 bearer_type = tvb_get_guint8 (tvb, offset); 4097 proto_tree_add_uint (addr_tree, hf_address_bearer_type, 4098 tvb, offset, 1, bearer_type); 4099 offset++; 4100 } else { 4101 bearer_type = 0x00; /* XXX */ 4102 } 4103 if (address_flags_len & PORT_NUMBER_INCLUDED) { 4104 proto_tree_add_uint (addr_tree, hf_address_port_num, 4105 tvb, offset, 2, ENC_BIG_ENDIAN); 4106 offset += 2; 4107 } 4108 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) { 4109 /* 4110 * We don't have the bearer type in the message, 4111 * so we don't know the address type. 4112 * (It's the same bearer type as the original 4113 * connection.) 4114 */ 4115 goto unknown_address_type; 4116 } 4117 4118 /* 4119 * We know the bearer type, so we know the address type. 4120 */ 4121 switch (bearer_type) { 4122 4123 case BT_IPv4: 4124 case BT_IS_95_CSD: 4125 case BT_IS_95_PACKET_DATA: 4126 case BT_ANSI_136_CSD: 4127 case BT_ANSI_136_PACKET_DATA: 4128 case BT_GSM_CSD: 4129 case BT_GSM_GPRS: 4130 case BT_GSM_USSD_IPv4: 4131 case BT_AMPS_CDPD: 4132 case BT_PDC_CSD: 4133 case BT_PDC_PACKET_DATA: 4134 case BT_IDEN_CSD: 4135 case BT_IDEN_PACKET_DATA: 4136 case BT_PHS_CSD: 4137 case BT_TETRA_PACKET_DATA: 4138 /* 4139 * IPv4. 4140 */ 4141 if (address_len != 4) { 4142 /* 4143 * Say what? 4144 */ 4145 goto unknown_address_type; 4146 } 4147 proto_tree_add_item (addr_tree, hf_address_ipv4_addr, 4148 tvb, offset, 4, ENC_NA); 4149 break; 4150 4151 case BT_IPv6: 4152 /* 4153 * IPv6. 4154 */ 4155 if (address_len != 16) { 4156 /* 4157 * Say what? 4158 */ 4159 goto unknown_address_type; 4160 } 4161 proto_tree_add_item (addr_tree, hf_address_ipv6_addr, 4162 tvb, offset, 16, ENC_NA); 4163 break; 4164 4165 unknown_address_type: 4166 default: 4167 if (address_len != 0) { 4168 proto_tree_add_item (addr_tree, hf_address_addr, 4169 tvb, offset, address_len, ENC_NA); 4170 } 4171 break; 4172 } 4173 offset += address_len; 4174 } /* while */ 4175 } 4176 4177 /* Define a pointer to function data type for the well-known header 4178 * lookup table below */ 4179 typedef guint32 (*hdr_parse_func_ptr) (proto_tree *, tvbuff_t *, guint32, packet_info *); 4180 4181 /* Lookup table for well-known header parsing functions */ 4182 static const hdr_parse_func_ptr WellKnownHeader[128] = { 4183 /* 0x00 */ wkh_accept, /* 0x01 */ wkh_accept_charset, 4184 /* 0x02 */ wkh_accept_encoding, /* 0x03 */ wkh_accept_language, 4185 /* 0x04 */ wkh_accept_ranges, /* 0x05 */ wkh_age, 4186 /* 0x06 */ wkh_allow, /* 0x07 */ wkh_authorization, 4187 /* 0x08 */ wkh_cache_control, /* 0x09 */ wkh_connection, 4188 /* 0x0A */ wkh_content_base, /* 0x0B */ wkh_content_encoding, 4189 /* 0x0C */ wkh_content_language, /* 0x0D */ wkh_content_length, 4190 /* 0x0E */ wkh_content_location, /* 0x0F */ wkh_content_md5, 4191 /* 0x10 */ wkh_content_range, /* 0x11 */ wkh_content_type, 4192 /* 0x12 */ wkh_date, /* 0x13 */ wkh_etag, 4193 /* 0x14 */ wkh_expires, /* 0x15 */ wkh_from, 4194 /* 0x16 */ wkh_host, /* 0x17 */ wkh_if_modified_since, 4195 /* 0x18 */ wkh_if_match, /* 0x19 */ wkh_if_none_match, 4196 /* 0x1A */ wkh_if_range, /* 0x1B */ wkh_if_unmodified_since, 4197 /* 0x1C */ wkh_location, /* 0x1D */ wkh_last_modified, 4198 /* 0x1E */ wkh_max_forwards, /* 0x1F */ wkh_pragma, 4199 /* 0x20 */ wkh_proxy_authenticate, /* 0x21 */ wkh_proxy_authorization, 4200 /* 0x22 */ wkh_public, /* 0x23 */ wkh_range, 4201 /* 0x24 */ wkh_referer, /* 0x25 */ wkh_default, 4202 /* 0x26 */ wkh_server, /* 0x27 */ wkh_transfer_encoding, 4203 /* 0x28 */ wkh_upgrade, /* 0x29 */ wkh_user_agent, 4204 /* 0x2A */ wkh_vary, /* 0x2B */ wkh_via, 4205 /* 0x2C */ wkh_warning, /* 0x2D */ wkh_www_authenticate, 4206 /* 0x2E */ wkh_content_disposition,/* 0x2F */ wkh_x_wap_application_id, 4207 /* 0x30 */ wkh_content_uri, /* 0x31 */ wkh_initiator_uri, 4208 /* 0x32 */ wkh_accept_application, /* 0x33 */ wkh_bearer_indication, 4209 /* 0x34 */ wkh_push_flag, /* 0x35 */ wkh_profile, 4210 /* 0x36 */ wkh_profile_diff_wbxml, /* 0x37 */ wkh_profile_warning, 4211 /* 0x38 */ wkh_default, /* 0x39 */ wkh_te, 4212 /* 0x3A */ wkh_trailer, /* 0x3B */ wkh_accept_charset, 4213 /* 0x3C */ wkh_accept_encoding, /* 0x3D */ wkh_cache_control, 4214 /* 0x3E */ wkh_content_range, /* 0x3F */ wkh_x_wap_tod, 4215 /* 0x40 */ wkh_content_id, /* 0x41 */ wkh_default, 4216 /* 0x42 */ wkh_default, /* 0x43 */ wkh_encoding_version, 4217 /* 0x44 */ wkh_profile_warning, /* 0x45 */ wkh_content_disposition, 4218 /* 0x46 */ wkh_x_wap_security, /* 0x47 */ wkh_cache_control, 4219 /******************************************************* 4220 *** The following headers are not (yet) registered. *** 4221 *******************************************************/ 4222 /* 0x48 */ wkh_default, /* 0x49 */ wkh_default, 4223 /* 0x4A */ wkh_default, /* 0x4B */ wkh_default, 4224 /* 0x4C */ wkh_default, /* 0x4D */ wkh_default, 4225 /* 0x4E */ wkh_default, /* 0x4F */ wkh_default, 4226 /* 0x50 */ wkh_default, /* 0x51 */ wkh_default, 4227 /* 0x52 */ wkh_default, /* 0x53 */ wkh_default, 4228 /* 0x54 */ wkh_default, /* 0x55 */ wkh_default, 4229 /* 0x56 */ wkh_default, /* 0x57 */ wkh_default, 4230 /* 0x58 */ wkh_default, /* 0x59 */ wkh_default, 4231 /* 0x5A */ wkh_default, /* 0x5B */ wkh_default, 4232 /* 0x5C */ wkh_default, /* 0x5D */ wkh_default, 4233 /* 0x5E */ wkh_default, /* 0x5F */ wkh_default, 4234 /* 0x60 */ wkh_default, /* 0x61 */ wkh_default, 4235 /* 0x62 */ wkh_default, /* 0x63 */ wkh_default, 4236 /* 0x64 */ wkh_default, /* 0x65 */ wkh_default, 4237 /* 0x66 */ wkh_default, /* 0x67 */ wkh_default, 4238 /* 0x68 */ wkh_default, /* 0x69 */ wkh_default, 4239 /* 0x6A */ wkh_default, /* 0x6B */ wkh_default, 4240 /* 0x6C */ wkh_default, /* 0x6D */ wkh_default, 4241 /* 0x6E */ wkh_default, /* 0x6F */ wkh_default, 4242 /* 0x70 */ wkh_default, /* 0x71 */ wkh_default, 4243 /* 0x72 */ wkh_default, /* 0x73 */ wkh_default, 4244 /* 0x74 */ wkh_default, /* 0x75 */ wkh_default, 4245 /* 0x76 */ wkh_default, /* 0x77 */ wkh_default, 4246 /* 0x78 */ wkh_default, /* 0x79 */ wkh_default, 4247 /* 0x7A */ wkh_default, /* 0x7B */ wkh_default, 4248 /* 0x7C */ wkh_default, /* 0x7D */ wkh_default, 4249 /* 0x7E */ wkh_default, /* 0x7F */ wkh_default, 4250 }; 4251 4252 /* Lookup table for well-known header parsing functions */ 4253 static const hdr_parse_func_ptr WellKnownOpenwaveHeader[128] = { 4254 /* 0x00 */ wkh_openwave_default, 4255 /* 0x01 */ wkh_openwave_x_up_proxy_push_accept, 4256 /* 0x02 */ wkh_openwave_x_up_proxy_push_seq, 4257 /* 0x03 */ wkh_openwave_x_up_proxy_notify, 4258 /* 0x04 */ wkh_openwave_x_up_proxy_operator_domain, 4259 /* 0x05 */ wkh_openwave_x_up_proxy_home_page, 4260 /* 0x06 */ wkh_openwave_x_up_devcap_has_color, 4261 /* 0x07 */ wkh_openwave_x_up_devcap_num_softkeys, 4262 /* 0x08 */ wkh_openwave_x_up_devcap_softkey_size, 4263 /* 0x09 */ wkh_openwave_x_up_devcap_screen_chars, 4264 /* 0x0A */ wkh_openwave_x_up_devcap_screen_pixels, 4265 /* 0x0B */ wkh_openwave_x_up_devcap_em_size, 4266 /* 0x0C */ wkh_openwave_x_up_devcap_screen_depth, 4267 /* 0x0D */ wkh_openwave_x_up_devcap_immed_alert, 4268 /* 0x0E */ wkh_openwave_x_up_proxy_net_ask, 4269 /* 0x0F */ wkh_openwave_x_up_proxy_uplink_version, 4270 /* 0x10 */ wkh_openwave_x_up_proxy_tod, 4271 /* 0x11 */ wkh_openwave_x_up_proxy_ba_enable, 4272 /* 0x12 */ wkh_openwave_x_up_proxy_ba_realm, 4273 /* 0x13 */ wkh_openwave_x_up_proxy_redirect_enable, 4274 /* 0x14 */ wkh_openwave_x_up_proxy_request_uri, 4275 /* 0x15 */ wkh_openwave_x_up_proxy_redirect_status, 4276 /* 0x16 */ wkh_openwave_x_up_proxy_trans_charset, 4277 /* 0x17 */ wkh_openwave_x_up_proxy_linger, 4278 /* 0x18 */ wkh_openwave_default, 4279 /* 0x19 */ wkh_openwave_x_up_proxy_enable_trust, 4280 /* 0x1A */ wkh_openwave_x_up_proxy_trust, 4281 /* 0x1B */ wkh_openwave_default, 4282 /* 0x1C */ wkh_openwave_default, 4283 /* 0x1D */ wkh_openwave_default, 4284 /* 0x1E */ wkh_openwave_default, 4285 /* 0x1F */ wkh_openwave_default, 4286 /* 0x20 */ wkh_openwave_x_up_proxy_trust, 4287 /* 0x21 */ wkh_openwave_x_up_proxy_bookmark, 4288 /* 0x22 */ wkh_openwave_x_up_devcap_gui, 4289 /******************************************************* 4290 *** The following headers are not (yet) registered. *** 4291 *******************************************************/ 4292 /* 0x23 */ wkh_openwave_default, 4293 /* 0x24 */ wkh_openwave_default, /* 0x25 */ wkh_openwave_default, 4294 /* 0x26 */ wkh_openwave_default, /* 0x27 */ wkh_openwave_default, 4295 /* 0x28 */ wkh_openwave_default, /* 0x29 */ wkh_openwave_default, 4296 /* 0x2A */ wkh_openwave_default, /* 0x2B */ wkh_openwave_default, 4297 /* 0x2C */ wkh_openwave_default, /* 0x2D */ wkh_openwave_default, 4298 /* 0x2E */ wkh_openwave_default, /* 0x2F */ wkh_openwave_default, 4299 /* 0x30 */ wkh_openwave_default, /* 0x31 */ wkh_openwave_default, 4300 /* 0x32 */ wkh_openwave_default, /* 0x33 */ wkh_openwave_default, 4301 /* 0x34 */ wkh_openwave_default, /* 0x35 */ wkh_openwave_default, 4302 /* 0x36 */ wkh_openwave_default, /* 0x37 */ wkh_openwave_default, 4303 /* 0x38 */ wkh_openwave_default, /* 0x39 */ wkh_openwave_default, 4304 /* 0x3A */ wkh_openwave_default, /* 0x3B */ wkh_openwave_default, 4305 /* 0x3C */ wkh_openwave_default, /* 0x3D */ wkh_openwave_default, 4306 /* 0x3E */ wkh_openwave_default, /* 0x3F */ wkh_openwave_default, 4307 /* 0x40 */ wkh_openwave_default, /* 0x41 */ wkh_openwave_default, 4308 /* 0x42 */ wkh_openwave_default, /* 0x43 */ wkh_openwave_default, 4309 /* 0x44 */ wkh_openwave_default, /* 0x45 */ wkh_openwave_default, 4310 /* 0x46 */ wkh_openwave_default, /* 0x47 */ wkh_openwave_default, 4311 /* 0x48 */ wkh_openwave_default, /* 0x49 */ wkh_openwave_default, 4312 /* 0x4A */ wkh_openwave_default, /* 0x4B */ wkh_openwave_default, 4313 /* 0x4C */ wkh_openwave_default, /* 0x4D */ wkh_openwave_default, 4314 /* 0x4E */ wkh_openwave_default, /* 0x4F */ wkh_openwave_default, 4315 /* 0x50 */ wkh_openwave_default, /* 0x51 */ wkh_openwave_default, 4316 /* 0x52 */ wkh_openwave_default, /* 0x53 */ wkh_openwave_default, 4317 /* 0x54 */ wkh_openwave_default, /* 0x55 */ wkh_openwave_default, 4318 /* 0x56 */ wkh_openwave_default, /* 0x57 */ wkh_openwave_default, 4319 /* 0x58 */ wkh_openwave_default, /* 0x59 */ wkh_openwave_default, 4320 /* 0x5A */ wkh_openwave_default, /* 0x5B */ wkh_openwave_default, 4321 /* 0x5C */ wkh_openwave_default, /* 0x5D */ wkh_openwave_default, 4322 /* 0x5E */ wkh_openwave_default, /* 0x5F */ wkh_openwave_default, 4323 /* 0x60 */ wkh_openwave_default, /* 0x61 */ wkh_openwave_default, 4324 /* 0x62 */ wkh_openwave_default, /* 0x63 */ wkh_openwave_default, 4325 /* 0x64 */ wkh_openwave_default, /* 0x65 */ wkh_openwave_default, 4326 /* 0x66 */ wkh_openwave_default, /* 0x67 */ wkh_openwave_default, 4327 /* 0x68 */ wkh_openwave_default, /* 0x69 */ wkh_openwave_default, 4328 /* 0x6A */ wkh_openwave_default, /* 0x6B */ wkh_openwave_default, 4329 /* 0x6C */ wkh_openwave_default, /* 0x6D */ wkh_openwave_default, 4330 /* 0x6E */ wkh_openwave_default, /* 0x6F */ wkh_openwave_default, 4331 /* 0x70 */ wkh_openwave_default, /* 0x71 */ wkh_openwave_default, 4332 /* 0x72 */ wkh_openwave_default, /* 0x73 */ wkh_openwave_default, 4333 /* 0x74 */ wkh_openwave_default, /* 0x75 */ wkh_openwave_default, 4334 /* 0x76 */ wkh_openwave_default, /* 0x77 */ wkh_openwave_default, 4335 /* 0x78 */ wkh_openwave_default, /* 0x79 */ wkh_openwave_default, 4336 /* 0x7A */ wkh_openwave_default, /* 0x7B */ wkh_openwave_default, 4337 /* 0x7C */ wkh_openwave_default, /* 0x7D */ wkh_openwave_default, 4338 /* 0x7E */ wkh_openwave_default, /* 0x7F */ wkh_openwave_default 4339 }; 4340 4341 4342 4343 /* WSP header format 4344 * 1st byte: 0x00 : <Not allowed> 4345 * 1st byte: 0x01 -- 0x1F: <Shorthand Header Code Page switch> 4346 * 1st byte: 0x20 -- 0x7E: <Textual header (C string)> 4347 * Followed with: <Textual header value (C string)> 4348 * 1st byte: 0x7F : <Header Code Page switch> 4349 * Followed with: 2nd byte: <Header Code Page> 4350 * 1st byte: 0x80 -- 0xFF: <Binary header (7-bit encoded ID)> 4351 * Followed with: 4352 * 2nd byte: 0x00 -- 0x1E: <Value Length (bytes)> 4353 * Followed with: <Len> bytes of data 4354 * 2nd byte: 0x1F : <Value Length is a guintvar> 4355 * Followed with: <guintvar Len> 4356 * Followed with: <Len> bytes of data 4357 * 2nd byte: 0x20 -- 0x7F: <Textual header value (C string)> 4358 * 2nd byte: 0x80 -- 0xFF: <Binary value (7-bit encoded ID)> 4359 */ 4360 static void 4361 add_headers (proto_tree *tree, tvbuff_t *tvb, int hf, packet_info *pinfo) 4362 { 4363 guint8 hdr_id, val_id, codepage = 1; 4364 gint32 tvb_len = tvb_reported_length(tvb); 4365 gint32 offset = 0; 4366 gint32 save_offset; 4367 gint32 hdr_len, hdr_start; 4368 gint32 val_len, val_start; 4369 gchar *hdr_str, *val_str; 4370 proto_tree *wsp_headers; 4371 proto_item *ti, *hidden_item; 4372 guint8 ok; 4373 guint32 val = 0; 4374 4375 if (offset >= tvb_len) 4376 return; /* No headers! */ 4377 4378 /* XXX: the field pointed to by hf has a type of FT_NONE */ 4379 ti = proto_tree_add_item(tree, hf, 4380 tvb, offset, tvb_len, ENC_NA); 4381 wsp_headers = proto_item_add_subtree(ti, ett_headers); 4382 4383 while (offset < tvb_len) { 4384 hdr_start = offset; 4385 hdr_id = tvb_get_guint8(tvb, offset); 4386 if (hdr_id & 0x80) { /* Well-known header */ 4387 hdr_len = 1; 4388 /* Call header value dissector for given header */ 4389 if (codepage == 1) { /* Default header code page */ 4390 save_offset = offset; 4391 offset = WellKnownHeader[hdr_id & 0x7F](wsp_headers, tvb, 4392 hdr_start, pinfo); 4393 /* Make sure we're progressing forward */ 4394 if (save_offset >= offset) { 4395 expert_add_info(pinfo, ti, &ei_wsp_header_invalid); 4396 break; 4397 } 4398 } else { /* Openwave header code page */ 4399 /* Here I'm delibarately assuming that Openwave is the only 4400 * company that defines a WSP header code page. */ 4401 save_offset = offset; 4402 offset = WellKnownOpenwaveHeader[hdr_id & 0x7F](wsp_headers, 4403 tvb, hdr_start, pinfo); 4404 /* Make sure we're progressing forward */ 4405 if (save_offset >= offset) { 4406 expert_add_info(pinfo, ti, &ei_wsp_header_invalid); 4407 break; 4408 } 4409 } 4410 } else if (hdr_id == 0x7F) { /* HCP shift sequence */ 4411 codepage = tvb_get_guint8(tvb, offset+1); 4412 proto_tree_add_uint(wsp_headers, hf_wsp_header_shift_code, 4413 tvb, offset, 2, codepage); 4414 offset += 2; 4415 } else if (hdr_id >= 0x20) { /* Textual header */ 4416 /* Header name MUST be NUL-ended string ==> tvb_get_stringz_enc() */ 4417 hdr_str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, hdr_start, (gint *)&hdr_len, ENC_ASCII); 4418 val_start = hdr_start + hdr_len; 4419 val_id = tvb_get_guint8(tvb, val_start); 4420 /* Call header value dissector for given header */ 4421 if (val_id >= 0x20 && val_id <=0x7E) { /* OK! */ 4422 val_str = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (gint *)&val_len, ENC_ASCII); 4423 offset = val_start + val_len; 4424 proto_tree_add_string_format(wsp_headers, hf_wsp_header_text_value, tvb, hdr_start, offset-hdr_start, 4425 val_str, "%s: %s", hdr_str, val_str); 4426 } else { 4427 /* Old-style X-WAP-TOD uses a non-textual value 4428 * after a textual header. */ 4429 if (g_ascii_strcasecmp(hdr_str, "x-wap.tod") == 0) { 4430 get_delta_seconds_value(val, tvb, val_start, val_len, ok); 4431 if (ok) { 4432 nstime_t t; 4433 t.secs = (time_t)val; 4434 t.nsecs = 0; 4435 if (val == 0) { 4436 ti = proto_tree_add_time_format_value(wsp_headers, hf_hdr_x_wap_tod, 4437 tvb, hdr_start, hdr_len + val_len, &t, 4438 "Requesting Time Of Day"); 4439 } else { 4440 ti = proto_tree_add_time(wsp_headers, hf_hdr_x_wap_tod, 4441 tvb, hdr_start, hdr_len + val_len, &t); 4442 } 4443 expert_add_info(pinfo, ti, &ei_hdr_x_wap_tod); 4444 } else { 4445 /* I prefer using X-Wap-Tod to the real hdr_str */ 4446 proto_tree_add_expert_format(wsp_headers, pinfo, &ei_wsp_text_field_invalid, 4447 tvb, hdr_start, hdr_len + val_len, 4448 "Invalid value for the 'X-Wap-Tod' header"); 4449 4450 } 4451 } else { 4452 /* Otherwise, non-textual values are invalid; parse them 4453 * enough to get the value length. */ 4454 guint32 val_len_len; /* length of length field */ 4455 4456 val_len = 1; /* for the first octet */ 4457 if (val_id <= 0x1E) { 4458 /* value is val_id octets long */ 4459 val_len += val_id; 4460 } else if (val_id == 0x1F) { 4461 /* value is a uintvar following the val_id */ 4462 val_len += tvb_get_guintvar(tvb, val_start + 1, &val_len_len, pinfo, &ei_wsp_oversized_uintvar); 4463 val_len += val_len_len; /* count the length itself */ 4464 } 4465 proto_tree_add_expert_format(wsp_headers, pinfo, &ei_wsp_text_field_invalid, tvb, hdr_start, hdr_len, 4466 "Invalid value for the textual '%s' header (should be a textual value)", 4467 hdr_str); 4468 } 4469 offset = val_start + val_len; 4470 } 4471 hidden_item = proto_tree_add_string(wsp_headers, hf_hdr_name_string, 4472 tvb, hdr_start, offset - hdr_start, hdr_str); 4473 proto_item_set_hidden(hidden_item); 4474 } else if (hdr_id > 0) { /* Shorthand HCP switch */ 4475 codepage = hdr_id; 4476 proto_tree_add_uint (wsp_headers, hf_wsp_header_shift_code, 4477 tvb, offset, 1, codepage); 4478 offset++; 4479 } else { 4480 proto_tree_add_expert_format (wsp_headers, pinfo, &ei_wsp_text_field_invalid, tvb, hdr_start, 1, 4481 "Invalid zero-length textual header"); 4482 4483 offset = tvb_len; 4484 } 4485 } 4486 } 4487 4488 static const value_string vals_sir_protocol_options[] = { 4489 { 0, "OTA-HTTP, no CPITag present" }, 4490 { 1, "OTA-HTTP, CPITag present" }, 4491 /* 2--255 are reserved */ 4492 /* 256--16383 are available for private WINA registration */ 4493 4494 { 0x00, NULL } 4495 }; 4496 4497 4498 /* Dissect a Session Initiation Request. 4499 * 4500 * Arguably this should be a separate dissector, but SIR does not make sense 4501 * outside of WSP anyway. 4502 */ 4503 static int 4504 dissect_sir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) 4505 { 4506 guint8 version; 4507 guint32 val_len; 4508 guint32 val_len_save; 4509 guint32 len; 4510 guint32 offset = 0; 4511 guint32 i; 4512 tvbuff_t *tmp_tvb; 4513 proto_tree *subtree; 4514 proto_item *ti; 4515 4516 /* Append status code to INFO column */ 4517 col_append_str(pinfo->cinfo, COL_INFO, ": WAP Session Initiation Request"); 4518 4519 ti = proto_tree_add_item(tree, hf_sir_section, 4520 tvb, 0, -1, ENC_NA); 4521 subtree = proto_item_add_subtree(ti, ett_sir); 4522 4523 /* Version */ 4524 version = tvb_get_guint8(tvb, 0); 4525 proto_tree_add_uint(subtree, hf_sir_version, 4526 tvb, 0, 1, version); 4527 4528 /* Length of Application-Id headers list */ 4529 val_len = tvb_get_guintvar(tvb, 1, &len, pinfo, &ei_wsp_oversized_uintvar); 4530 proto_tree_add_uint(subtree, hf_sir_app_id_list_len, 4531 tvb, 1, len, val_len); 4532 offset = 1 + len; 4533 /* Application-Id headers */ 4534 tmp_tvb = tvb_new_subset_length(tvb, offset, val_len); 4535 add_headers (subtree, tmp_tvb, hf_sir_app_id_list, pinfo); 4536 offset += val_len; 4537 4538 /* Length of WSP contact points list */ 4539 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 4540 proto_tree_add_uint(subtree, hf_sir_wsp_contact_points_len, 4541 tvb, offset, len, val_len); 4542 offset += len; 4543 /* WSP contact point list */ 4544 tmp_tvb = tvb_new_subset_length (tvb, offset, val_len); 4545 add_addresses(subtree, tmp_tvb, hf_sir_wsp_contact_points); 4546 4547 /* End of version 0 SIR content */ 4548 if (version == 0) 4549 return offset; 4550 4551 offset += val_len; 4552 4553 /* Length of non-WSP contact points list */ 4554 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 4555 proto_tree_add_uint(subtree, hf_sir_contact_points_len, 4556 tvb, offset, len, val_len); 4557 offset += len; 4558 /* Non-WSP contact point list */ 4559 tmp_tvb = tvb_new_subset_length(tvb, offset, val_len); 4560 add_addresses(subtree, tmp_tvb, hf_sir_contact_points); 4561 4562 offset += val_len; 4563 4564 /* Number of entries in the Protocol Options list */ 4565 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 4566 proto_tree_add_uint(subtree, hf_sir_protocol_options_len, 4567 tvb, offset, len, val_len); 4568 offset += len; 4569 /* Protocol Options list. 4570 * Each protocol option is encoded as a guintvar */ 4571 4572 val_len_save = val_len; 4573 for (i = 0; i < val_len_save; i++) { 4574 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 4575 proto_tree_add_uint(subtree, hf_sir_protocol_options, 4576 tvb, offset, len, val_len); 4577 offset += len; 4578 } 4579 4580 /* Length of ProvURL */ 4581 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 4582 proto_tree_add_uint(subtree, hf_sir_prov_url_len, 4583 tvb, offset, len, val_len); 4584 offset += len; 4585 /* ProvURL */ 4586 proto_tree_add_item (tree, hf_sir_prov_url, 4587 tvb, offset, val_len, ENC_ASCII|ENC_NA); 4588 offset += val_len; 4589 4590 /* Number of entries in the CPITag list */ 4591 val_len = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 4592 proto_tree_add_uint(subtree, hf_sir_cpi_tag_len, 4593 tvb, offset, len, val_len); 4594 offset += len; 4595 4596 /* CPITag list. 4597 * Each CPITag is encoded as 4 octets of opaque data. 4598 * In OTA-HTTP, it is conveyed in the X-Wap-CPITag header 4599 * but with a Base64 encoding of the 4 bytes. */ 4600 for (i = 0; i < val_len; i++) { 4601 proto_tree_add_item(subtree, hf_sir_cpi_tag, 4602 tvb, offset, 4, ENC_NA); 4603 offset += 4; 4604 } 4605 return tvb_captured_length(tvb); 4606 } 4607 4608 static void 4609 dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, 4610 dissector_handle_t dissector_handle, gboolean is_connectionless) 4611 { 4612 int offset = 0; 4613 4614 guint8 pdut; 4615 guint count = 0; 4616 guint value = 0; 4617 guint uriLength = 0; 4618 guint uriStart = 0; 4619 guint capabilityLength = 0; 4620 guint headersLength = 0; 4621 guint headerLength = 0; 4622 guint headerStart = 0; 4623 guint nextOffset = 0; 4624 guint contentTypeStart = 0; 4625 guint contentType = 0; 4626 const char *contentTypeStr; 4627 tvbuff_t *tmp_tvb; 4628 int found_match; 4629 heur_dtbl_entry_t *hdtbl_entry; 4630 proto_item* ti; 4631 4632 /* Set up structures we will need to add the protocol subtree and manage it */ 4633 proto_item *proto_ti = NULL; /* for the proto entry */ 4634 proto_tree *wsp_tree = NULL; 4635 4636 wsp_info_value_t *stat_info; 4637 stat_info = wmem_new(wmem_packet_scope(), wsp_info_value_t); 4638 stat_info->status_code = 0; 4639 4640 /* This field shows up as the "Info" column in the display; you should make 4641 it, if possible, summarize what's in the packet, so that a user looking 4642 at the list of packets can tell what type of packet it is. */ 4643 4644 /* Connection-less mode has a TID first */ 4645 if (is_connectionless) 4646 { 4647 offset++; /* Skip the 1-byte Transaction ID */ 4648 }; 4649 4650 /* Find the PDU type */ 4651 pdut = tvb_get_guint8 (tvb, offset); 4652 4653 /* Develop the string to put in the Info column */ 4654 col_append_fstr(pinfo->cinfo, COL_INFO, "WSP %s (0x%02x)", 4655 val_to_str_ext (pdut, &wsp_vals_pdu_type_ext, "Unknown PDU type (0x%02x)"), 4656 pdut); 4657 4658 proto_ti = proto_tree_add_item(tree, proto_wsp, tvb, 0, -1, ENC_NA); 4659 wsp_tree = proto_item_add_subtree(proto_ti, ett_wsp); 4660 proto_item_append_text(proto_ti, ", Method: %s (0x%02x)", 4661 val_to_str_ext (pdut, &wsp_vals_pdu_type_ext, "Unknown (0x%02x)"), 4662 pdut); 4663 4664 /* Add common items: only TID and PDU Type */ 4665 4666 /* If this is connectionless, then the TID Field is always first */ 4667 if (is_connectionless) 4668 { 4669 proto_tree_add_item (wsp_tree, hf_wsp_header_tid, 4670 tvb, 0, 1, ENC_LITTLE_ENDIAN); 4671 } 4672 proto_tree_add_item( wsp_tree, hf_wsp_header_pdu_type, 4673 tvb, offset, 1, ENC_LITTLE_ENDIAN); 4674 offset++; 4675 4676 /* Map extended methods to the main method now the Column info has been 4677 * written; this way we can dissect the extended method PDUs. */ 4678 if ((pdut >= 0x50) && (pdut <= 0x5F)) /* Extended GET --> GET */ 4679 pdut = WSP_PDU_GET; 4680 else if ((pdut >= 0x70) && (pdut <= 0x7F)) /* Extended POST --> POST */ 4681 pdut = WSP_PDU_POST; 4682 4683 switch (pdut) 4684 { 4685 case WSP_PDU_CONNECT: 4686 case WSP_PDU_CONNECTREPLY: 4687 case WSP_PDU_RESUME: 4688 if (pdut == WSP_PDU_CONNECT) 4689 { 4690 proto_tree_add_item (wsp_tree, hf_wsp_version_major, 4691 tvb, offset, 1, ENC_LITTLE_ENDIAN); 4692 proto_tree_add_item (wsp_tree, hf_wsp_version_minor, 4693 tvb, offset, 1, ENC_LITTLE_ENDIAN); 4694 { 4695 guint8 ver = tvb_get_guint8(tvb, offset); 4696 proto_item_append_text(proto_ti, ", Version: %u.%u", 4697 ver >> 4, ver & 0x0F); 4698 } 4699 offset++; 4700 } else { 4701 count = 0; /* Initialise count */ 4702 value = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 4703 proto_tree_add_uint (wsp_tree, 4704 hf_wsp_server_session_id, 4705 tvb, offset, count, value); 4706 proto_item_append_text(proto_ti, ", Session ID: %u", value); 4707 offset += count; 4708 } 4709 count = 0; /* Initialise count */ 4710 capabilityLength = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 4711 ti = proto_tree_add_uint (wsp_tree, hf_capabilities_length, 4712 tvb, offset, count, capabilityLength); 4713 offset += count; 4714 if (capabilityLength > tvb_reported_length(tvb)) 4715 { 4716 expert_add_info(pinfo, ti, &ei_wsp_capability_length_invalid); 4717 break; 4718 } 4719 4720 if (pdut != WSP_PDU_RESUME) 4721 { 4722 count = 0; /* Initialise count */ 4723 headerLength = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 4724 proto_tree_add_uint (wsp_tree, hf_wsp_header_length, 4725 tvb, offset, count, headerLength); 4726 offset += count; 4727 4728 } else { 4729 /* Resume computes the headerlength 4730 * by remaining bytes */ 4731 headerStart = offset + capabilityLength; 4732 headerLength = tvb_reported_length_remaining (tvb, 4733 headerStart); 4734 } 4735 if (capabilityLength > 0) 4736 { 4737 tmp_tvb = tvb_new_subset_length (tvb, offset, 4738 capabilityLength); 4739 add_capabilities (wsp_tree, pinfo, tmp_tvb, pdut); 4740 offset += capabilityLength; 4741 } 4742 4743 if (headerLength > 0) 4744 { 4745 tmp_tvb = tvb_new_subset_length (tvb, offset, 4746 headerLength); 4747 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo); 4748 } 4749 4750 break; 4751 4752 case WSP_PDU_REDIRECT: 4753 dissect_redirect(tvb, offset, pinfo, wsp_tree, dissector_handle); 4754 break; 4755 4756 case WSP_PDU_DISCONNECT: 4757 case WSP_PDU_SUSPEND: 4758 count = 0; /* Initialise count */ 4759 value = tvb_get_guintvar (tvb, offset, &count, pinfo, 4760 &ei_wsp_oversized_uintvar); 4761 proto_tree_add_uint (wsp_tree, hf_wsp_server_session_id, 4762 tvb, offset, count, value); 4763 proto_item_append_text(proto_ti, ", Session ID: %u", value); 4764 break; 4765 4766 case WSP_PDU_GET: 4767 case WSP_PDU_OPTIONS: 4768 case WSP_PDU_HEAD: 4769 case WSP_PDU_DELETE: 4770 case WSP_PDU_TRACE: 4771 count = 0; /* Initialise count */ 4772 /* Length of URI and size of URILen field */ 4773 value = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 4774 nextOffset = offset + count; 4775 add_uri (wsp_tree, pinfo, tvb, offset, nextOffset, proto_ti); 4776 offset += value + count; /* VERIFY */ 4777 tmp_tvb = tvb_new_subset_remaining (tvb, offset); 4778 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo); 4779 break; 4780 4781 case WSP_PDU_POST: 4782 case WSP_PDU_PUT: 4783 uriStart = offset; 4784 count = 0; /* Initialise count */ 4785 uriLength = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 4786 headerStart = uriStart+count; 4787 count = 0; /* Initialise count */ 4788 headersLength = tvb_get_guintvar (tvb, headerStart, &count, pinfo, &ei_wsp_oversized_uintvar); 4789 offset = headerStart + count; 4790 4791 add_uri (wsp_tree, pinfo, tvb, uriStart, offset, proto_ti); 4792 offset += uriLength; 4793 4794 proto_tree_add_uint (wsp_tree, hf_wsp_header_length, 4795 tvb, headerStart, count, headersLength); 4796 4797 /* Stop processing POST PDU if length of headers is zero; 4798 * this should not happen as we expect at least Content-Type. */ 4799 if (headersLength == 0) 4800 break; 4801 4802 contentTypeStart = offset; 4803 nextOffset = add_content_type (wsp_tree, pinfo, 4804 tvb, offset, &contentType, &contentTypeStr); 4805 4806 /* Add content type to protocol summary line */ 4807 if (contentTypeStr) { 4808 proto_item_append_text(proto_ti, ", Content-Type: %s", 4809 contentTypeStr); 4810 } else { 4811 proto_item_append_text(proto_ti, ", Content-Type: 0x%X", 4812 contentType); 4813 } 4814 4815 /* Add headers subtree that will hold the headers fields */ 4816 /* Runs from nextOffset for 4817 * headersLength - (length of content-type field) */ 4818 headerLength = headersLength - (nextOffset - contentTypeStart); 4819 if (headerLength > 0) 4820 { 4821 tmp_tvb = tvb_new_subset_length (tvb, nextOffset, 4822 headerLength); 4823 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo); 4824 } 4825 /* XXX - offset is no longer used after this point */ 4826 /* offset = nextOffset+headerLength; */ 4827 4828 /* WSP_PDU_POST data - First check whether a subdissector exists 4829 * for the content type */ 4830 if (tvb_reported_length_remaining(tvb, 4831 headerStart + count + uriLength + headersLength) > 0) 4832 { 4833 tmp_tvb = tvb_new_subset_remaining (tvb, 4834 headerStart + count + uriLength + headersLength); 4835 /* 4836 * Try finding a dissector for the content 4837 * first, then fallback. 4838 */ 4839 found_match = 0; 4840 if (contentTypeStr) { 4841 /* 4842 * Content type is a string. 4843 */ 4844 found_match = dissector_try_string(media_type_table, 4845 contentTypeStr, tmp_tvb, pinfo, tree, NULL); 4846 } 4847 if (! found_match) { 4848 if (! dissector_try_heuristic(heur_subdissector_list, 4849 tmp_tvb, pinfo, tree, &hdtbl_entry, NULL)) { 4850 4851 pinfo->match_string = contentTypeStr; 4852 call_dissector_with_data(media_handle, tmp_tvb, pinfo, tree, NULL /* TODO: parameters */); 4853 #if 0 4854 add_post_data (wsp_tree, tmp_tvb, 4855 contentType, contentTypeStr, pinfo); 4856 #endif 4857 } 4858 } 4859 } 4860 break; 4861 4862 case WSP_PDU_REPLY: 4863 count = 0; /* Initialise count */ 4864 headersLength = tvb_get_guintvar (tvb, offset+1, &count, pinfo, &ei_wsp_oversized_uintvar); 4865 headerStart = offset + count + 1; 4866 { 4867 guint8 reply_status = tvb_get_guint8(tvb, offset); 4868 const char *reply_status_str; 4869 4870 reply_status_str = val_to_str_ext_const (reply_status, &wsp_vals_status_ext, "(Unknown response status)"); 4871 proto_tree_add_item (wsp_tree, hf_wsp_header_status, 4872 tvb, offset, 1, ENC_LITTLE_ENDIAN); 4873 proto_item_append_text(proto_ti, ", Status: %s (0x%02x)", 4874 reply_status_str, reply_status); 4875 4876 stat_info->status_code = (gint) reply_status; 4877 /* Append status code to INFO column */ 4878 col_append_fstr(pinfo->cinfo, COL_INFO, 4879 ": %s (0x%02x)", 4880 reply_status_str, reply_status); 4881 } 4882 nextOffset = offset + 1 + count; 4883 proto_tree_add_uint (wsp_tree, hf_wsp_header_length, 4884 tvb, offset + 1, count, headersLength); 4885 4886 if (headersLength == 0) 4887 break; 4888 4889 contentTypeStart = nextOffset; 4890 nextOffset = add_content_type (wsp_tree, pinfo, tvb, 4891 nextOffset, &contentType, &contentTypeStr); 4892 4893 /* Add content type to protocol summary line */ 4894 if (contentTypeStr) { 4895 proto_item_append_text(proto_ti, ", Content-Type: %s", 4896 contentTypeStr); 4897 } else { 4898 proto_item_append_text(proto_ti, ", Content-Type: 0x%X", 4899 contentType); 4900 } 4901 4902 /* Add headers subtree that will hold the headers fields */ 4903 /* Runs from nextOffset for 4904 * headersLength - (length of Content-Type field) */ 4905 headerLength = headersLength - (nextOffset - contentTypeStart); 4906 if (headerLength > 0) 4907 { 4908 tmp_tvb = tvb_new_subset_length (tvb, nextOffset, 4909 headerLength); 4910 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo); 4911 } 4912 /* XXX - offset is no longer used after this point */ 4913 /* offset += count+headersLength+1;*/ 4914 4915 /* WSP_PDU_REPLY data - First check whether a subdissector exists 4916 * for the content type */ 4917 if (tvb_reported_length_remaining(tvb, headerStart + headersLength) 4918 > 0) 4919 { 4920 tmp_tvb = tvb_new_subset_remaining (tvb, headerStart + headersLength); 4921 /* 4922 * Try finding a dissector for the content 4923 * first, then fallback. 4924 */ 4925 found_match = 0; 4926 if (contentTypeStr) { 4927 /* 4928 * Content type is a string. 4929 */ 4930 found_match = dissector_try_string(media_type_table, 4931 contentTypeStr, tmp_tvb, pinfo, tree, NULL); 4932 } 4933 if (! found_match) { 4934 if (! dissector_try_heuristic(heur_subdissector_list, 4935 tmp_tvb, pinfo, tree, &hdtbl_entry, NULL)) { 4936 4937 pinfo->match_string = contentTypeStr; 4938 call_dissector_with_data(media_handle, tmp_tvb, pinfo, tree, NULL /* TODO: parameters */); 4939 #if 0 4940 proto_tree_add_item (wsp_tree, hf_wsp_reply_data, 4941 tmp_tvb, 0, -1, ENC_NA); 4942 #endif 4943 } 4944 } 4945 } 4946 break; 4947 4948 case WSP_PDU_PUSH: 4949 case WSP_PDU_CONFIRMEDPUSH: 4950 count = 0; /* Initialise count */ 4951 headersLength = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 4952 headerStart = offset + count; 4953 4954 proto_tree_add_uint (wsp_tree, hf_wsp_header_length, 4955 tvb, offset, count, headersLength); 4956 4957 if (headersLength == 0) 4958 break; 4959 4960 offset += count; 4961 contentTypeStart = offset; 4962 nextOffset = add_content_type (wsp_tree, pinfo, 4963 tvb, offset, &contentType, &contentTypeStr); 4964 4965 /* Add content type to protocol summary line */ 4966 if (contentTypeStr) { 4967 proto_item_append_text(proto_ti, ", Content-Type: %s", 4968 contentTypeStr); 4969 } else { 4970 proto_item_append_text(proto_ti, ", Content-Type: 0x%X", 4971 contentType); 4972 } 4973 4974 /* Add headers subtree that will hold the headers fields */ 4975 /* Runs from nextOffset for 4976 * headersLength-(length of Content-Type field) */ 4977 headerLength = headersLength-(nextOffset-contentTypeStart); 4978 if (headerLength > 0) 4979 { 4980 tmp_tvb = tvb_new_subset_length (tvb, nextOffset, 4981 headerLength); 4982 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo); 4983 } 4984 /* XXX - offset is no longer used after this point */ 4985 /*offset += headersLength;*/ 4986 4987 /* WSP_PDU_PUSH data - First check whether a subdissector exists 4988 * for the content type */ 4989 if (tvb_reported_length_remaining(tvb, headerStart + headersLength) 4990 > 0) 4991 { 4992 tmp_tvb = tvb_new_subset_remaining (tvb, headerStart + headersLength); 4993 /* 4994 * Try finding a dissector for the content 4995 * first, then fallback. 4996 */ 4997 found_match = 0; 4998 if (contentTypeStr) { 4999 /* 5000 * Content type is a string. 5001 */ 5002 /* 5003 if (g_ascii_strcasecmp(contentTypeStr, "application/vnd.wap.sia") == 0) { 5004 dissect_sir(tree, tmp_tvb); 5005 } else 5006 */ 5007 found_match = dissector_try_string(media_type_table, 5008 contentTypeStr, tmp_tvb, pinfo, tree, NULL); 5009 } 5010 if (! found_match){ 5011 /* 5012 * Try to dissect x-wap-application lwm2m.dm data as CoAP 5013 * see docs: (page 141) 5014 * http://www.openmobilealliance.org/release/LightweightM2M/V1_0_2-20180209-A/OMA-TS-LightweightM2M-V1_0_2-20180209-A.pdf 5015 * header bytes should be: 0xAF, 0x9A 5016 */ 5017 if (tvb_get_guint8(tvb, headerStart + headerLength - 1) == 0xAF && /* x-wap app id */ 5018 tvb_get_guint8(tvb, headerStart + headerLength) == 0x9A) { /* x-wap app lwm2m.dm */ 5019 5020 call_dissector(coap_handle, tmp_tvb, pinfo, tree); 5021 } else if (! dissector_try_heuristic(heur_subdissector_list, 5022 tmp_tvb, pinfo, tree, &hdtbl_entry, NULL)) { 5023 5024 pinfo->match_string = contentTypeStr; 5025 call_dissector_with_data(media_handle, tmp_tvb, pinfo, tree, NULL /* TODO: parameters */); 5026 #if 0 5027 proto_tree_add_item (wsp_tree, hf_wsp_push_data, 5028 tmp_tvb, 0, -1, ENC_NA); 5029 #endif 5030 } 5031 } 5032 } 5033 break; 5034 5035 } 5036 stat_info->pdut = pdut; 5037 tap_queue_packet (wsp_tap, pinfo, stat_info); 5038 } 5039 5040 5041 /* 5042 * Called directly from UDP. 5043 * Put "WSP" into the "Protocol" column. 5044 */ 5045 static int 5046 dissect_wsp_fromudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) 5047 { 5048 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSP"); 5049 col_clear(pinfo->cinfo, COL_INFO); 5050 5051 dissect_wsp_common(tvb, pinfo, tree, wsp_fromudp_handle, TRUE); 5052 return tvb_captured_length(tvb); 5053 } 5054 5055 5056 /* 5057 * Called from a higher-level WAP dissector, in connection-oriented mode. 5058 * Leave the "Protocol" column alone - the dissector calling us should 5059 * have set it. 5060 */ 5061 static int 5062 dissect_wsp_fromwap_co(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) 5063 { 5064 /* 5065 * XXX - what about WTLS->WTP->WSP? 5066 */ 5067 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, FALSE); 5068 return tvb_captured_length(tvb); 5069 } 5070 5071 5072 /* 5073 * Called from a higher-level WAP dissector, in connectionless mode. 5074 * Leave the "Protocol" column alone - the dissector calling us should 5075 * have set it. 5076 */ 5077 static int 5078 dissect_wsp_fromwap_cl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) 5079 { 5080 /* 5081 * XXX - what about WTLS->WSP? 5082 */ 5083 col_clear(pinfo->cinfo, COL_INFO); 5084 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, TRUE); 5085 return tvb_captured_length(tvb); 5086 } 5087 5088 5089 static void 5090 add_uri (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, 5091 guint URILenOffset, guint URIOffset, proto_item *proto_ti) 5092 { 5093 guint count = 0; 5094 guint uriLen = tvb_get_guintvar (tvb, URILenOffset, &count, pinfo, &ei_wsp_oversized_uintvar); 5095 gchar *str; 5096 5097 proto_tree_add_uint (tree, hf_wsp_header_uri_len, 5098 tvb, URILenOffset, count, uriLen); 5099 5100 proto_tree_add_item (tree, hf_wsp_header_uri, 5101 tvb, URIOffset, uriLen, ENC_ASCII|ENC_NA); 5102 5103 str = tvb_format_text (pinfo->pool, tvb, URIOffset, uriLen); 5104 /* XXX - tvb_format_text(pinfo->pool, ) returns a pointer to a static text string 5105 * so please DO NOT attempt at g_free()ing it! 5106 */ 5107 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", str); 5108 5109 if (proto_ti) 5110 proto_item_append_text(proto_ti, ", URI: %s", str); 5111 } 5112 5113 5114 /* 5115 * CO-WSP capability negotiation 5116 */ 5117 5118 enum { 5119 WSP_CAPA_CLIENT_SDU_SIZE = 0x00, 5120 WSP_CAPA_SERVER_SDU_SIZE, 5121 WSP_CAPA_PROTOCOL_OPTIONS, 5122 WSP_CAPA_METHOD_MOR, 5123 WSP_CAPA_PUSH_MOR, 5124 WSP_CAPA_EXTENDED_METHODS, 5125 WSP_CAPA_HEADER_CODE_PAGES, 5126 WSP_CAPA_ALIASES, 5127 WSP_CAPA_CLIENT_MESSAGE_SIZE, 5128 WSP_CAPA_SERVER_MESSAGE_SIZE 5129 }; 5130 5131 static const value_string wsp_capability_vals [] = { 5132 { WSP_CAPA_CLIENT_SDU_SIZE, "Client SDU Size" }, 5133 { WSP_CAPA_SERVER_SDU_SIZE, "Server SDU Size" }, 5134 { WSP_CAPA_PROTOCOL_OPTIONS, "Protocol Options" }, 5135 { WSP_CAPA_METHOD_MOR, "Method MOR" }, 5136 { WSP_CAPA_PUSH_MOR, "Push MOR" }, 5137 { WSP_CAPA_EXTENDED_METHODS, "Extended Methods" }, 5138 { WSP_CAPA_HEADER_CODE_PAGES, "Header Code Pages" }, 5139 { WSP_CAPA_ALIASES, "Aliases" }, 5140 { WSP_CAPA_CLIENT_MESSAGE_SIZE, "Client Message Size" }, 5141 { WSP_CAPA_SERVER_MESSAGE_SIZE, "Server Message Size" }, 5142 { 0, NULL } 5143 }; 5144 5145 static void 5146 add_capabilities (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint8 pdu_type) 5147 { 5148 proto_tree *wsp_capabilities, *cap_subtree, *cap_subtree2; 5149 proto_item *ti, *cap_item, *cap_item2; 5150 5151 char *capaName, *str; 5152 guint32 offset = 0; 5153 guint32 len = 0; 5154 guint32 capaStart = 0; /* Start offset of the capability */ 5155 guint32 capaLen = 0; /* Length of the entire capability */ 5156 guint32 capaValueLen = 0; /* Length of the capability value & type */ 5157 guint32 tvb_len = tvb_reported_length(tvb); 5158 gboolean ok = FALSE; 5159 guint8 peek; 5160 guint32 value; 5161 5162 if (tvb_len == 0) { 5163 return; 5164 } 5165 5166 ti = proto_tree_add_item(tree, hf_capabilities_section, 5167 tvb, 0, tvb_len, ENC_NA); 5168 wsp_capabilities = proto_item_add_subtree(ti, ett_capabilities); 5169 5170 while (offset < tvb_len) { 5171 /* 5172 * WSP capabilities consist of: 5173 * - a guint32 length field, 5174 * - a capability identifier as Token-text or Short-integer, 5175 * - a capability-specific sequence of <length> octets. 5176 */ 5177 capaStart = offset; 5178 /* 5179 * Now Offset points to the 1st byte of a capability field. 5180 * Get the length of the capability field 5181 */ 5182 capaValueLen = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 5183 if (len == 0) 5184 return; 5185 capaLen = capaValueLen + len; 5186 5187 cap_subtree = proto_tree_add_subtree(wsp_capabilities, tvb, offset, capaLen, ett_capabilities_entry, &cap_item, "Capability"); 5188 if (capaValueLen > tvb_len) 5189 return; 5190 offset += len; 5191 /* 5192 * Now offset points to the 1st byte of the capability type. 5193 * Get the capability identifier. 5194 */ 5195 peek = tvb_get_guint8(tvb, offset); 5196 if (is_token_text(peek)) { /* Literal capability name */ 5197 /* 1. Get the string from the tvb */ 5198 capaName = (gchar *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, capaStart, (gint *)&len, ENC_ASCII); 5199 5200 /* 2. Look up the string capability name */ 5201 if (g_ascii_strcasecmp(capaName, "client-sdu-size") == 0) { 5202 peek = WSP_CAPA_CLIENT_SDU_SIZE; 5203 } else if (g_ascii_strcasecmp(capaName, "server-sdu-size") == 0) { 5204 peek = WSP_CAPA_SERVER_SDU_SIZE; 5205 } else if (g_ascii_strcasecmp(capaName, "protocol options") == 0) { 5206 peek = WSP_CAPA_PROTOCOL_OPTIONS; 5207 } else if (g_ascii_strcasecmp(capaName, "method-mor") == 0) { 5208 peek = WSP_CAPA_METHOD_MOR; 5209 } else if (g_ascii_strcasecmp(capaName, "push-mor") == 0) { 5210 peek = WSP_CAPA_PUSH_MOR; 5211 } else if (g_ascii_strcasecmp(capaName, "extended methods") == 0) { 5212 peek = WSP_CAPA_EXTENDED_METHODS; 5213 } else if (g_ascii_strcasecmp(capaName, "header code pages") == 0) { 5214 peek = WSP_CAPA_HEADER_CODE_PAGES; 5215 } else if (g_ascii_strcasecmp(capaName, "aliases") == 0) { 5216 peek = WSP_CAPA_ALIASES; 5217 } else if (g_ascii_strcasecmp(capaName, "client-message-size") == 0) { 5218 peek = WSP_CAPA_CLIENT_MESSAGE_SIZE; 5219 } else if (g_ascii_strcasecmp(capaName, "server-message-size") == 0) { 5220 peek = WSP_CAPA_SERVER_MESSAGE_SIZE; 5221 } else { 5222 expert_add_info_format(pinfo, cap_item, &ei_wsp_capability_invalid, 5223 "Unknown or invalid textual capability: %s", capaName); 5224 /* Skip this capability */ 5225 offset = capaStart + capaLen; 5226 continue; 5227 } 5228 offset += len; 5229 /* Now offset points to the 1st value byte of the capability. */ 5230 } else if (peek < 0x80) { 5231 expert_add_info_format(pinfo, cap_item, &ei_wsp_capability_invalid, 5232 "Invalid well-known capability: 0x%02X", peek); 5233 /* Skip further capability parsing */ 5234 return; 5235 } 5236 if (peek & 0x80) { /* Well-known capability */ 5237 peek &= 0x7F; 5238 len = 1; 5239 offset++; 5240 /* Now offset points to the 1st value byte of the capability. */ 5241 } 5242 5243 proto_item_append_text(cap_item, ": %s", val_to_str_const(peek, wsp_capability_vals, "Invalid capability")); 5244 /* Now the capability type is known */ 5245 switch (peek) { 5246 case WSP_CAPA_CLIENT_SDU_SIZE: 5247 value = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 5248 proto_tree_add_uint(cap_subtree, hf_capa_client_sdu_size, 5249 tvb, offset, len, value); 5250 break; 5251 case WSP_CAPA_SERVER_SDU_SIZE: 5252 value = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 5253 proto_tree_add_uint(cap_subtree, hf_capa_server_sdu_size, 5254 tvb, offset, len, value); 5255 break; 5256 case WSP_CAPA_PROTOCOL_OPTIONS: 5257 /* 5258 * The bits are stored in one or more octets, not an 5259 * uintvar-integer! Note that capability name and value 5260 * have length capaValueLength, and that the capability 5261 * name has length = len. Hence the remaining length is 5262 * given by capaValueLen - len. 5263 */ 5264 if (capaValueLen - len == 1) { 5265 static int * const capabilities[] = { 5266 &hf_capa_protocol_option_confirmed_push, 5267 &hf_capa_protocol_option_push, 5268 &hf_capa_protocol_option_session_resume, 5269 &hf_capa_protocol_option_ack_headers, 5270 &hf_capa_protocol_option_large_data_transfer, 5271 NULL 5272 }; 5273 5274 proto_tree_add_bitmask_with_flags(cap_subtree, tvb, offset, hf_capa_protocol_options, 5275 ett_proto_option_capability, capabilities, ENC_NA, BMT_NO_FALSE); 5276 } 5277 else 5278 { 5279 /* 5280 * The WSP spec foresees that this bit field can be 5281 * extended in the future. This does not make sense yet. 5282 */ 5283 proto_item_append_text(cap_item, 5284 " <warning: bit field too large>"); 5285 offset = capaStart + capaLen; 5286 continue; 5287 } 5288 break; 5289 case WSP_CAPA_METHOD_MOR: 5290 proto_tree_add_item(cap_subtree, hf_capa_method_mor, tvb, offset, len, ENC_NA); 5291 break; 5292 case WSP_CAPA_PUSH_MOR: 5293 proto_tree_add_item(cap_subtree, hf_capa_push_mor, tvb, offset, len, ENC_NA); 5294 break; 5295 case WSP_CAPA_EXTENDED_METHODS: 5296 /* Extended Methods capability format: 5297 * Connect PDU: collection of { Method (octet), Method-name (Token-text) } 5298 * ConnectReply PDU: collection of accepted { Method (octet) } 5299 */ 5300 cap_subtree2 = proto_tree_add_subtree(cap_subtree, tvb, capaStart, capaLen, ett_capabilities_extended_methods, &cap_item2, "Extended Methods"); 5301 if (pdu_type == WSP_PDU_CONNECT) { 5302 while (offset < capaStart + capaLen) { 5303 ti = proto_tree_add_item(cap_subtree2, hf_capa_extended_method, tvb, offset, 1, ENC_NA); 5304 offset++; 5305 5306 get_text_string(str, tvb, offset, len, ok); 5307 if (! ok) { 5308 expert_add_info(pinfo, ti, &ei_wsp_capability_encoding_invalid); 5309 return; 5310 } 5311 proto_item_append_text(ti, " = %s", str); 5312 proto_item_set_len(ti, len+1); 5313 offset += len; 5314 } 5315 } else { 5316 while (offset < capaStart + capaLen) { 5317 proto_tree_add_item(cap_subtree2, hf_capa_extended_method, tvb, offset, 1, ENC_NA); 5318 offset++; 5319 } 5320 } 5321 break; 5322 case WSP_CAPA_HEADER_CODE_PAGES: 5323 /* Header Code Pages capability format: 5324 * Connect PDU: collection of { Page-id (octet), Page-name (Token-text) } 5325 * ConnectReply PDU: collection of accepted { Page-id (octet) } 5326 */ 5327 cap_subtree2 = proto_tree_add_subtree(cap_subtree, tvb, capaStart, capaLen, ett_capabilities_header_code_pages, &cap_item2, "Header Code Pages"); 5328 if (pdu_type == WSP_PDU_CONNECT) { 5329 while (offset < capaStart + capaLen) { 5330 ti = proto_tree_add_item(cap_subtree2, hf_capa_header_code_page, tvb, offset, 1, ENC_NA); 5331 offset++; 5332 5333 get_text_string(str, tvb, offset, len, ok); 5334 if (! ok) { 5335 expert_add_info(pinfo, ti, &ei_wsp_capability_encoding_invalid); 5336 return; 5337 } 5338 proto_item_append_text(ti, " = %s", str); 5339 proto_item_set_len(ti, len+1); 5340 offset += len; 5341 } 5342 } else { 5343 while (offset < capaStart + capaLen) { 5344 proto_tree_add_item(cap_subtree2, hf_capa_header_code_page, tvb, offset, 1, ENC_NA); 5345 offset++; 5346 } 5347 } 5348 break; 5349 case WSP_CAPA_ALIASES: 5350 /* TODO - same format as redirect addresses */ 5351 proto_tree_add_item(cap_subtree, hf_capa_aliases, 5352 tvb, capaStart, capaLen, ENC_NA); 5353 break; 5354 case WSP_CAPA_CLIENT_MESSAGE_SIZE: 5355 value = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 5356 proto_tree_add_uint(cap_subtree, hf_capa_client_message_size, 5357 tvb, offset, len, value); 5358 break; 5359 case WSP_CAPA_SERVER_MESSAGE_SIZE: 5360 value = tvb_get_guintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar); 5361 proto_tree_add_uint(cap_subtree, hf_capa_server_message_size, 5362 tvb, offset, len, value); 5363 break; 5364 default: 5365 expert_add_info_format(pinfo, cap_item, &ei_wsp_capability_invalid, 5366 "Unknown well-known capability: 0x%02X", peek); 5367 break; 5368 } 5369 offset = capaStart + capaLen; 5370 } 5371 } 5372 5373 void 5374 add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType, 5375 const char *contentTypeStr, packet_info *pinfo) 5376 { 5377 guint offset = 0; 5378 guint variableStart = 0; 5379 guint variableEnd = 0; 5380 guint valueStart = 0; 5381 guint8 peek = 0; 5382 proto_item *ti; 5383 proto_tree *sub_tree; 5384 5385 /* VERIFY ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,-1,ENC_NA); */ 5386 ti = proto_tree_add_item (tree, hf_wsp_post_data, tvb, offset, -1, ENC_NA); 5387 sub_tree = proto_item_add_subtree(ti, ett_post); 5388 5389 if ( (contentTypeStr == NULL && contentType == 0x12) 5390 || (contentTypeStr && (g_ascii_strcasecmp(contentTypeStr, 5391 "application/x-www-form-urlencoded") == 0)) ) 5392 { 5393 /* 5394 * URL Encoded data. 5395 * Iterate through post data. 5396 */ 5397 for (offset = 0; offset < tvb_reported_length (tvb); offset++) 5398 { 5399 peek = tvb_get_guint8 (tvb, offset); 5400 if (peek == '=') 5401 { 5402 variableEnd = offset; 5403 valueStart = offset+1; 5404 } 5405 else if (peek == '&') 5406 { 5407 if (variableEnd > 0) 5408 { 5409 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset); 5410 } 5411 variableStart = offset+1; 5412 variableEnd = 0; 5413 valueStart = 0; 5414 } 5415 } 5416 5417 /* See if there's outstanding data */ 5418 if (variableEnd > 0) 5419 { 5420 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset); 5421 } 5422 } 5423 else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x24) || 5424 (contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33)) 5425 { 5426 /* add_multipart_data takes also care of subdissection */ 5427 add_multipart_data(sub_tree, tvb, pinfo); 5428 } 5429 } 5430 5431 static void 5432 add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint variableEnd, guint valueStart, guint valueEnd) 5433 { 5434 int variableLength = variableEnd-variableStart; 5435 int valueLength = 0; 5436 char *variableBuffer; 5437 char *valueBuffer; 5438 5439 variableBuffer = tvb_get_string_enc(wmem_packet_scope(), tvb, variableStart, variableLength, ENC_ASCII); 5440 5441 if (valueEnd < valueStart) 5442 { 5443 valueBuffer = (char *)wmem_alloc(wmem_packet_scope(), 1); 5444 valueBuffer[0] = 0; 5445 valueEnd = valueStart; 5446 } 5447 else 5448 { 5449 valueLength = valueEnd-valueStart; 5450 valueBuffer = tvb_get_string_enc(wmem_packet_scope(), tvb, valueStart, valueLength, ENC_ASCII); 5451 } 5452 5453 /* Check for variables with no value */ 5454 if (valueStart >= tvb_reported_length (tvb)) 5455 { 5456 valueStart = tvb_reported_length (tvb); 5457 valueEnd = valueStart; 5458 } 5459 valueLength = valueEnd-valueStart; 5460 5461 proto_tree_add_string_format(tree, hf_wsp_variable_value, tvb, variableStart, valueLength, valueBuffer, "%s: %s", variableBuffer, valueBuffer); 5462 5463 } 5464 5465 static void 5466 add_multipart_data (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo) 5467 { 5468 int offset = 0; 5469 guint nextOffset; 5470 guint nEntries = 0; 5471 guint count; 5472 guint HeadersLen; 5473 guint DataLen; 5474 guint contentType = 0; 5475 const char *contentTypeStr; 5476 tvbuff_t *tmp_tvb; 5477 int partnr = 1; 5478 int part_start; 5479 int found_match = 0; 5480 5481 proto_item *sub_tree = NULL; 5482 proto_item *ti = NULL; 5483 proto_tree *mpart_tree = NULL; 5484 5485 heur_dtbl_entry_t *hdtbl_entry; 5486 5487 nEntries = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 5488 offset += count; 5489 if (nEntries) 5490 { 5491 sub_tree = proto_tree_add_subtree(tree, tvb, offset - count, 0, 5492 ett_mpartlist, NULL, "Multipart body"); 5493 } 5494 while (nEntries--) 5495 { 5496 part_start = offset; 5497 HeadersLen = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 5498 offset += count; 5499 DataLen = tvb_get_guintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar); 5500 offset += count; 5501 5502 ti = proto_tree_add_uint(sub_tree, hf_wsp_mpart, tvb, part_start, 5503 HeadersLen + DataLen + (offset - part_start), partnr); 5504 mpart_tree = proto_item_add_subtree(ti, ett_multiparts); 5505 5506 nextOffset = add_content_type (mpart_tree, pinfo, tvb, offset, 5507 &contentType, &contentTypeStr); 5508 5509 /* Add content type to protocol summary line */ 5510 if (contentTypeStr) { 5511 proto_item_append_text(ti, ", content-type: %s", contentTypeStr); 5512 } else { 5513 proto_item_append_text(ti, ", content-type: 0x%X", contentType); 5514 } 5515 5516 HeadersLen -= (nextOffset - offset); 5517 if (HeadersLen > 0) 5518 { 5519 tmp_tvb = tvb_new_subset_length (tvb, nextOffset, HeadersLen); 5520 add_headers (mpart_tree, tmp_tvb, hf_wsp_headers_section, pinfo); 5521 } 5522 offset = nextOffset + HeadersLen; 5523 /* 5524 * Try the dissectors of the multipart content. 5525 * 5526 * TODO - handle nested multipart documents. 5527 */ 5528 tmp_tvb = tvb_new_subset_length(tvb, offset, DataLen); 5529 /* 5530 * Try finding a dissector for the content 5531 * first, then fallback. 5532 */ 5533 found_match = 0; 5534 if (contentTypeStr) { 5535 /* 5536 * Content type is a string. 5537 */ 5538 found_match = dissector_try_string(media_type_table, 5539 contentTypeStr, tmp_tvb, pinfo, mpart_tree, NULL); 5540 } 5541 if (! found_match) { 5542 if (! dissector_try_heuristic(heur_subdissector_list, 5543 tmp_tvb, pinfo, mpart_tree, &hdtbl_entry, NULL)) { 5544 5545 pinfo->match_string = contentTypeStr; 5546 call_dissector_with_data(media_handle, tmp_tvb, pinfo, mpart_tree, NULL /* TODO: parameters */); 5547 #if 0 5548 proto_tree_add_item (mpart_tree, hf_wsp_multipart_data, 5549 tvb, offset, DataLen, ENC_NA); 5550 #endif 5551 } 5552 } 5553 5554 offset += DataLen; 5555 partnr++; 5556 } 5557 } 5558 5559 /* TAP STAT INFO */ 5560 typedef enum 5561 { 5562 MESSAGE_TYPE_COLUMN = 0, 5563 PACKET_COLUMN 5564 } wsp_stat_columns; 5565 5566 static stat_tap_table_item wsp_stat_fields[] = { 5567 {TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Type / Code", "%-25s"}, 5568 {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Packets", "%d"} 5569 }; 5570 5571 static int unknown_pt_idx; 5572 static int unknown_sc_idx; 5573 5574 static void wsp_stat_init(stat_tap_table_ui* new_stat) 5575 { 5576 const char *pt_table_name = "PDU Types"; 5577 const char *sc_table_name = "Status Codes"; 5578 int num_fields = sizeof(wsp_stat_fields)/sizeof(stat_tap_table_item); 5579 stat_tap_table *pt_table; 5580 stat_tap_table_item_type pt_items[sizeof(wsp_stat_fields)/sizeof(stat_tap_table_item)]; 5581 stat_tap_table *sc_table; 5582 stat_tap_table_item_type sc_items[sizeof(wsp_stat_fields)/sizeof(stat_tap_table_item)]; 5583 int table_idx; 5584 5585 pt_table = stat_tap_find_table(new_stat, pt_table_name); 5586 if (pt_table) { 5587 if (new_stat->stat_tap_reset_table_cb) { 5588 new_stat->stat_tap_reset_table_cb(pt_table); 5589 } 5590 } 5591 else { 5592 pt_table = stat_tap_init_table(pt_table_name, num_fields, 0, NULL); 5593 stat_tap_add_table(new_stat, pt_table); 5594 5595 /* Add a row for each PDU type */ 5596 table_idx = 0; 5597 memset(pt_items, 0, sizeof(pt_items)); 5598 pt_items[MESSAGE_TYPE_COLUMN].type = TABLE_ITEM_STRING; 5599 pt_items[PACKET_COLUMN].type = TABLE_ITEM_UINT; 5600 while (wsp_vals_pdu_type[table_idx].strptr) 5601 { 5602 pt_items[MESSAGE_TYPE_COLUMN].value.string_value = g_strdup(wsp_vals_pdu_type[table_idx].strptr); 5603 pt_items[MESSAGE_TYPE_COLUMN].user_data.uint_value = wsp_vals_pdu_type[table_idx].value; 5604 5605 stat_tap_init_table_row(pt_table, table_idx, num_fields, pt_items); 5606 table_idx++; 5607 } 5608 pt_items[MESSAGE_TYPE_COLUMN].value.string_value = g_strdup("Unknown PDU type"); 5609 pt_items[MESSAGE_TYPE_COLUMN].user_data.uint_value = 0; 5610 stat_tap_init_table_row(pt_table, table_idx, num_fields, pt_items); 5611 unknown_pt_idx = table_idx; 5612 } 5613 5614 sc_table = stat_tap_find_table(new_stat, sc_table_name); 5615 if (sc_table) { 5616 if (new_stat->stat_tap_reset_table_cb) { 5617 new_stat->stat_tap_reset_table_cb(sc_table); 5618 } 5619 } 5620 else { 5621 sc_table = stat_tap_init_table(sc_table_name, num_fields, 0, NULL); 5622 stat_tap_add_table(new_stat, sc_table); 5623 5624 /* Add a row for each status code */ 5625 table_idx = 0; 5626 memset(sc_items, 0, sizeof(sc_items)); 5627 sc_items[MESSAGE_TYPE_COLUMN].type = TABLE_ITEM_STRING; 5628 sc_items[PACKET_COLUMN].type = TABLE_ITEM_UINT; 5629 while (wsp_vals_status[table_idx].strptr) 5630 { 5631 sc_items[MESSAGE_TYPE_COLUMN].value.string_value = g_strdup(wsp_vals_status[table_idx].strptr); 5632 sc_items[MESSAGE_TYPE_COLUMN].user_data.uint_value = wsp_vals_status[table_idx].value; 5633 5634 stat_tap_init_table_row(sc_table, table_idx, num_fields, sc_items); 5635 table_idx++; 5636 } 5637 sc_items[MESSAGE_TYPE_COLUMN].value.string_value = g_strdup("Unknown status code"); 5638 sc_items[MESSAGE_TYPE_COLUMN].user_data.uint_value = 0; 5639 stat_tap_init_table_row(sc_table, table_idx, num_fields, sc_items); 5640 unknown_sc_idx = table_idx; 5641 } 5642 } 5643 5644 static tap_packet_status 5645 wsp_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *wiv_ptr) 5646 { 5647 stat_data_t* stat_data = (stat_data_t*)tapdata; 5648 const wsp_info_value_t *value = (const wsp_info_value_t *)wiv_ptr; 5649 stat_tap_table *pt_table, *sc_table; 5650 guint element; 5651 stat_tap_table_item_type* item_data; 5652 gboolean found; 5653 5654 pt_table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 0); 5655 sc_table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 1); 5656 5657 found = FALSE; 5658 for (element = 0; element < pt_table->num_elements; element++) { 5659 item_data = stat_tap_get_field_data(pt_table, element, MESSAGE_TYPE_COLUMN); 5660 if (value->pdut == item_data->user_data.uint_value) { 5661 found = TRUE; 5662 break; 5663 } 5664 } 5665 if (!found) { 5666 element = unknown_pt_idx; 5667 } 5668 item_data = stat_tap_get_field_data(pt_table, element, PACKET_COLUMN); 5669 item_data->value.uint_value++; 5670 stat_tap_set_field_data(pt_table, element, PACKET_COLUMN, item_data); 5671 5672 if (value->status_code != 0) { 5673 found = FALSE; 5674 for (element = 0; element < sc_table->num_elements; element++) { 5675 item_data = stat_tap_get_field_data(sc_table, element, MESSAGE_TYPE_COLUMN); 5676 if (value->status_code == (int) item_data->user_data.uint_value) { 5677 found = TRUE; 5678 break; 5679 } 5680 } 5681 if (!found) { 5682 element = unknown_sc_idx; 5683 } 5684 item_data = stat_tap_get_field_data(sc_table, element, PACKET_COLUMN); 5685 item_data->value.uint_value++; 5686 stat_tap_set_field_data(sc_table, element, PACKET_COLUMN, item_data); 5687 } 5688 5689 return found? TAP_PACKET_REDRAW : TAP_PACKET_DONT_REDRAW; 5690 } 5691 5692 static void 5693 wsp_stat_reset(stat_tap_table* table) 5694 { 5695 guint element; 5696 stat_tap_table_item_type* item_data; 5697 5698 for (element = 0; element < table->num_elements; element++) 5699 { 5700 item_data = stat_tap_get_field_data(table, element, PACKET_COLUMN); 5701 item_data->value.uint_value = 0; 5702 stat_tap_set_field_data(table, element, PACKET_COLUMN, item_data); 5703 } 5704 } 5705 5706 static void 5707 wsp_stat_free_table_item(stat_tap_table* table _U_, guint row _U_, guint column, stat_tap_table_item_type* field_data) 5708 { 5709 if (column != MESSAGE_TYPE_COLUMN) return; 5710 g_free((char*)field_data->value.string_value); 5711 field_data->value.string_value = NULL; 5712 } 5713 5714 /* Register the protocol with Wireshark */ 5715 void 5716 proto_register_wsp(void) 5717 { 5718 5719 /* Setup list of header fields */ 5720 static hf_register_info hf[] = { 5721 { &hf_wsp_header_tid, 5722 { "Transaction ID", 5723 "wsp.TID", 5724 FT_UINT8, BASE_HEX, NULL, 0x00, 5725 "WSP Transaction ID (for connectionless WSP)", HFILL 5726 } 5727 }, 5728 { &hf_wsp_header_pdu_type, 5729 { "PDU Type", 5730 "wsp.pdu_type", 5731 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &wsp_vals_pdu_type_ext, 0x00, 5732 NULL, HFILL 5733 } 5734 }, 5735 { &hf_wsp_version_major, 5736 { "Version (Major)", 5737 "wsp.version.major", 5738 FT_UINT8, BASE_DEC, NULL, 0xF0, 5739 NULL, HFILL 5740 } 5741 }, 5742 { &hf_wsp_version_minor, 5743 { "Version (Minor)", 5744 "wsp.version.minor", 5745 FT_UINT8, BASE_DEC, NULL, 0x0F, 5746 NULL, HFILL 5747 } 5748 }, 5749 { &hf_capabilities_length, 5750 { "Capabilities Length", 5751 "wsp.capabilities.length", 5752 FT_UINT32, BASE_DEC, NULL, 0x00, 5753 "Length of Capabilities field (bytes)", HFILL 5754 } 5755 }, 5756 { &hf_wsp_header_length, 5757 { "Headers Length", 5758 "wsp.headers_length", 5759 FT_UINT32, BASE_DEC, NULL, 0x00, 5760 "Length of Headers field (bytes)", HFILL 5761 } 5762 }, 5763 { &hf_capabilities_section, 5764 { "Capabilities", 5765 "wsp.capabilities", 5766 FT_NONE, BASE_NONE, NULL, 0x00, 5767 NULL, HFILL 5768 } 5769 }, 5770 { &hf_wsp_headers_section, 5771 { "Headers", 5772 "wsp.headers", 5773 FT_NONE, BASE_NONE, NULL, 0x00, 5774 NULL, HFILL 5775 } 5776 }, 5777 { &hf_wsp_header_uri_len, 5778 { "URI Length", 5779 "wsp.uri_length", 5780 FT_UINT32, BASE_DEC, NULL, 0x00, 5781 "Length of URI field", HFILL 5782 } 5783 }, 5784 { &hf_wsp_header_uri, 5785 { "URI", 5786 "wsp.uri", 5787 FT_STRING, BASE_NONE, NULL, 0x00, 5788 NULL, HFILL 5789 } 5790 }, 5791 { &hf_wsp_server_session_id, 5792 { "Server Session ID", 5793 "wsp.server.session_id", 5794 FT_UINT32, BASE_DEC, NULL, 0x00, 5795 NULL, HFILL 5796 } 5797 }, 5798 { &hf_wsp_header_status, 5799 { "Status", 5800 "wsp.reply.status", 5801 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &wsp_vals_status_ext, 0x00, 5802 "Reply Status", HFILL 5803 } 5804 }, 5805 { &hf_wsp_parameter_untype_quote_text, 5806 { "Untyped quoted text", 5807 "wsp.untype.quote_text", 5808 FT_STRING, BASE_NONE, NULL, 0x00, 5809 NULL, HFILL 5810 } 5811 }, 5812 { &hf_wsp_parameter_untype_text, 5813 { "Untyped text", 5814 "wsp.untype.text", 5815 FT_STRING, BASE_NONE, NULL, 0x00, 5816 NULL, HFILL 5817 } 5818 }, 5819 { &hf_wsp_parameter_untype_int, 5820 { "Untyped integer", 5821 "wsp.untype.int", 5822 FT_UINT32, BASE_DEC, NULL, 0x00, 5823 NULL, HFILL 5824 } 5825 }, 5826 { &hf_wsp_parameter_type, 5827 { "Parameter Type", 5828 "wsp.parameter.type", 5829 FT_UINT32, BASE_DEC|BASE_EXT_STRING, ¶meter_type_vals_ext, 0x00, 5830 NULL, HFILL 5831 } 5832 }, 5833 { &hf_wsp_parameter_int_type, 5834 { "Integer Type", 5835 "wsp.parameter.int_type", 5836 FT_UINT32, BASE_DEC, NULL, 0x00, 5837 "Type parameter", HFILL 5838 } 5839 }, 5840 { &hf_wsp_parameter_name, 5841 { "Name", 5842 "wsp.parameter.name", 5843 FT_STRING, BASE_NONE, NULL, 0x00, 5844 "Name parameter", HFILL 5845 } 5846 }, 5847 { &hf_wsp_parameter_filename, 5848 { "Filename", 5849 "wsp.parameter.filename", 5850 FT_STRING, BASE_NONE, NULL, 0x00, 5851 "Filename parameter", HFILL 5852 } 5853 }, 5854 { &hf_wsp_parameter_start, 5855 { "Start", 5856 "wsp.parameter.start", 5857 FT_STRING, BASE_NONE, NULL, 0x00, 5858 "Start parameter", HFILL 5859 } 5860 }, 5861 { &hf_wsp_parameter_start_info, 5862 { "Start-info", 5863 "wsp.parameter.start_info", 5864 FT_STRING, BASE_NONE, NULL, 0x00, 5865 "Start-info parameter", HFILL 5866 } 5867 }, 5868 { &hf_wsp_parameter_comment, 5869 { "Comment", 5870 "wsp.parameter.comment", 5871 FT_STRING, BASE_NONE, NULL, 0x00, 5872 "Comment parameter", HFILL 5873 } 5874 }, 5875 { &hf_wsp_parameter_domain, 5876 { "Domain", 5877 "wsp.parameter.domain", 5878 FT_STRING, BASE_NONE, NULL, 0x00, 5879 "Domain parameter", HFILL 5880 } 5881 }, 5882 { &hf_wsp_parameter_path, 5883 { "Path", 5884 "wsp.parameter.path", 5885 FT_STRING, BASE_NONE, NULL, 0x00, 5886 "Path parameter", HFILL 5887 } 5888 }, 5889 { &hf_wsp_parameter_sec, 5890 { "SEC", 5891 "wsp.parameter.sec", 5892 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_wsp_parameter_sec_ext, 0x00, 5893 "SEC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL 5894 } 5895 }, 5896 { &hf_wsp_parameter_mac, 5897 { "MAC", 5898 "wsp.parameter.mac", 5899 FT_STRING, BASE_NONE, NULL, 0x00, 5900 "MAC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL 5901 } 5902 }, 5903 { &hf_wsp_parameter_upart_type, 5904 { "Type", 5905 "wsp.parameter.upart.type", 5906 FT_STRING, BASE_NONE, NULL, 0x00, 5907 "Multipart type parameter", HFILL 5908 } 5909 }, 5910 { &hf_wsp_parameter_level, 5911 { "Level", 5912 "wsp.parameter.level", 5913 FT_STRING, BASE_NONE, NULL, 0x00, 5914 "Level parameter", HFILL 5915 } 5916 }, 5917 { &hf_wsp_parameter_size, 5918 { "Size", 5919 "wsp.parameter.size", 5920 FT_UINT32, BASE_DEC, NULL, 0x00, 5921 "Size parameter", HFILL 5922 } 5923 }, 5924 #if 0 5925 { &hf_wsp_reply_data, 5926 { "Data", 5927 "wsp.reply.data", 5928 FT_NONE, BASE_NONE, NULL, 0x00, 5929 NULL, HFILL 5930 } 5931 }, 5932 #endif 5933 { &hf_wsp_header_shift_code, 5934 { "Switching to WSP header code-page", 5935 "wsp.code_page", 5936 FT_UINT8, BASE_DEC, NULL, 0x00, 5937 "Header code-page shift code", HFILL 5938 } 5939 }, 5940 /* 5941 * CO-WSP capability negotiation 5942 */ 5943 { &hf_capa_client_sdu_size, 5944 { "Client SDU Size", 5945 "wsp.capability.client_sdu_size", 5946 FT_UINT8, BASE_DEC, NULL, 0x00, 5947 "Client Service Data Unit size (bytes)", HFILL 5948 } 5949 }, 5950 { &hf_capa_server_sdu_size, 5951 { "Server SDU Size", 5952 "wsp.capability.server_sdu_size", 5953 FT_UINT8, BASE_DEC, NULL, 0x00, 5954 "Server Service Data Unit size (bytes)", HFILL 5955 } 5956 }, 5957 { &hf_capa_protocol_options, 5958 { "Protocol Options", 5959 "wsp.capability.protocol_opt", 5960 FT_UINT8, BASE_HEX, NULL, 0x00, 5961 NULL, HFILL 5962 } 5963 }, 5964 { &hf_capa_protocol_option_confirmed_push, 5965 { "Confirmed Push facility", 5966 "wsp.capability.protocol_option.confirmed_push", 5967 FT_BOOLEAN, 8, NULL, 0x80, 5968 "If set, this CO-WSP session supports the Confirmed Push facility", HFILL 5969 } 5970 }, 5971 { &hf_capa_protocol_option_push, 5972 { "Push facility", 5973 "wsp.capability.protocol_option.push", 5974 FT_BOOLEAN, 8, NULL, 0x40, 5975 "If set, this CO-WSP session supports the Push facility", HFILL 5976 } 5977 }, 5978 { &hf_capa_protocol_option_session_resume, 5979 { "Session Resume facility", 5980 "wsp.capability.protocol_option.session_resume", 5981 FT_BOOLEAN, 8, NULL, 0x20, 5982 "If set, this CO-WSP session supports the Session Resume facility", HFILL 5983 } 5984 }, 5985 { &hf_capa_protocol_option_ack_headers, 5986 { "Acknowledgement headers", 5987 "wsp.capability.protocol_option.ack_headers", 5988 FT_BOOLEAN, 8, NULL, 0x10, 5989 "If set, this CO-WSP session supports Acknowledgement headers", HFILL 5990 } 5991 }, 5992 { &hf_capa_protocol_option_large_data_transfer, 5993 { "Large data transfer", 5994 "wsp.capability.protocol_option.large_data_transfer", 5995 FT_BOOLEAN, 8, NULL, 0x08, 5996 "If set, this CO-WSP session supports Large data transfer", HFILL 5997 } 5998 }, 5999 { &hf_capa_method_mor, 6000 { "Method MOR", 6001 "wsp.capability.method_mor", 6002 FT_UINT8, BASE_DEC, NULL, 0x00, 6003 NULL, HFILL 6004 } 6005 }, 6006 { &hf_capa_push_mor, 6007 { "Push MOR", 6008 "wsp.capability.push_mor", 6009 FT_UINT8, BASE_DEC, NULL, 0x00, 6010 NULL, HFILL 6011 } 6012 }, 6013 { &hf_capa_extended_method, 6014 { "Extended Method", 6015 "wsp.capability.extended_method", 6016 FT_UINT8, BASE_HEX, NULL, 0x00, 6017 NULL, HFILL 6018 } 6019 }, 6020 { &hf_capa_header_code_page, 6021 { "Header Code Page", 6022 "wsp.capability.code_page", 6023 FT_UINT8, BASE_HEX, NULL, 0x00, 6024 NULL, HFILL 6025 } 6026 }, 6027 { &hf_capa_aliases, 6028 { "Aliases", 6029 "wsp.capability.aliases", 6030 FT_BYTES, BASE_NONE, NULL, 0x00, 6031 NULL, HFILL 6032 } 6033 }, 6034 { &hf_capa_client_message_size, 6035 { "Client Message Size", 6036 "wsp.capability.client_message_size", 6037 FT_UINT8, BASE_DEC, NULL, 0x00, 6038 "Client Message size (bytes)", HFILL 6039 } 6040 }, 6041 { &hf_capa_server_message_size, 6042 { "Server Message Size", 6043 "wsp.capability.server_message_size", 6044 FT_UINT8, BASE_DEC, NULL, 0x00, 6045 "Server Message size (bytes)", HFILL 6046 } 6047 }, 6048 { &hf_wsp_post_data, 6049 { "Data (Post)", 6050 "wsp.post.data", 6051 FT_NONE, BASE_NONE, NULL, 0x00, 6052 "Post Data", HFILL 6053 } 6054 }, 6055 #if 0 6056 { &hf_wsp_push_data, 6057 { "Push Data", 6058 "wsp.push.data", 6059 FT_NONE, BASE_NONE, NULL, 0x00, 6060 NULL, HFILL 6061 } 6062 }, 6063 { &hf_wsp_multipart_data, 6064 { "Data in this part", 6065 "wsp.multipart.data", 6066 FT_NONE, BASE_NONE, NULL, 0x00, 6067 "The data of 1 MIME-multipart part.", HFILL 6068 } 6069 }, 6070 #endif 6071 { &hf_wsp_mpart, 6072 { "Part", 6073 "wsp.multipart", 6074 FT_UINT32, BASE_DEC, NULL, 0x00, 6075 "MIME part of multipart data.", HFILL 6076 } 6077 }, 6078 { &hf_wsp_header_text_value, 6079 { "Header textual value", 6080 "wsp.header_text_value", 6081 FT_STRING, BASE_NONE, NULL, 0x00, 6082 NULL, HFILL 6083 } 6084 }, 6085 { &hf_wsp_variable_value, 6086 { "Variable value", 6087 "wsp.variable_value", 6088 FT_STRING, BASE_NONE, NULL, 0x00, 6089 NULL, HFILL 6090 } 6091 }, 6092 { &hf_wsp_default_int, 6093 { "Default integer", 6094 "wsp.default_int", 6095 FT_UINT32, BASE_DEC, NULL, 0x00, 6096 NULL, HFILL 6097 } 6098 }, 6099 { &hf_wsp_default_string, 6100 { "Default string value", 6101 "wsp.default_string", 6102 FT_STRING, BASE_NONE, NULL, 0x00, 6103 NULL, HFILL 6104 } 6105 }, 6106 { &hf_wsp_default_val_len, 6107 { "Default value len", 6108 "wsp.default_val_len", 6109 FT_UINT32, BASE_DEC, NULL, 0x00, 6110 NULL, HFILL 6111 } 6112 }, 6113 { &hf_wsp_redirect_flags, 6114 { "Flags", 6115 "wsp.redirect.flags", 6116 FT_UINT8, BASE_HEX, NULL, 0x00, 6117 "Redirect Flags", HFILL 6118 } 6119 }, 6120 { &hf_wsp_redirect_permanent, 6121 { "Permanent Redirect", 6122 "wsp.redirect.flags.permanent", 6123 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PERMANENT_REDIRECT, 6124 NULL, HFILL 6125 } 6126 }, 6127 { &hf_wsp_redirect_reuse_security_session, 6128 { "Reuse Security Session", 6129 "wsp.redirect.flags.reuse_security_session", 6130 FT_BOOLEAN, 8, TFS(&tfs_yes_no), REUSE_SECURITY_SESSION, 6131 "If set, the existing Security Session may be reused", HFILL 6132 } 6133 }, 6134 { &hf_redirect_addresses, 6135 { "Redirect Addresses", 6136 "wsp.redirect.addresses", 6137 FT_NONE, BASE_NONE, NULL, 0x00, 6138 "List of Redirect Addresses", HFILL 6139 } 6140 }, 6141 6142 /* 6143 * Addresses 6144 */ 6145 { &hf_address_entry, 6146 { "Address Record", 6147 "wsp.address", 6148 FT_UINT32, BASE_DEC, NULL, 0x00, 6149 NULL, HFILL 6150 } 6151 }, 6152 { &hf_address_flags_length, 6153 { "Flags/Length", 6154 "wsp.address.flags", 6155 FT_UINT8, BASE_HEX, NULL, 0x00, 6156 "Address Flags/Length", HFILL 6157 } 6158 }, 6159 { &hf_address_flags_length_bearer_type_included, 6160 { "Bearer Type Included", 6161 "wsp.address.flags.bearer_type_included", 6162 FT_BOOLEAN, 8, TFS(&tfs_yes_no), BEARER_TYPE_INCLUDED, 6163 "Address bearer type included", HFILL 6164 } 6165 }, 6166 { &hf_address_flags_length_port_number_included, 6167 { "Port Number Included", 6168 "wsp.address.flags.port_number_included", 6169 FT_BOOLEAN, 8, TFS(&tfs_yes_no), PORT_NUMBER_INCLUDED, 6170 "Address port number included", HFILL 6171 } 6172 }, 6173 { &hf_address_flags_length_address_len, 6174 { "Address Length", 6175 "wsp.address.flags.length", 6176 FT_UINT8, BASE_DEC, NULL, ADDRESS_LEN, 6177 NULL, HFILL 6178 } 6179 }, 6180 { &hf_address_bearer_type, 6181 { "Bearer Type", 6182 "wsp.address.bearer_type", 6183 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_bearer_types_ext, 0x0, 6184 NULL, HFILL 6185 } 6186 }, 6187 { &hf_address_port_num, 6188 { "Port Number", 6189 "wsp.address.port", 6190 FT_UINT16, BASE_DEC, NULL, 0x0, 6191 NULL, HFILL 6192 } 6193 }, 6194 { &hf_address_ipv4_addr, 6195 { "IPv4 Address", 6196 "wsp.address.ipv4", 6197 FT_IPv4, BASE_NONE, NULL, 0x0, 6198 "Address (IPv4)", HFILL 6199 } 6200 }, 6201 { &hf_address_ipv6_addr, 6202 { "IPv6 Address", 6203 "wsp.address.ipv6", 6204 FT_IPv6, BASE_NONE, NULL, 0x0, 6205 "Address (IPv6)", HFILL 6206 } 6207 }, 6208 { &hf_address_addr, 6209 { "Address", 6210 "wsp.address.unknown", 6211 FT_BYTES, BASE_NONE, NULL, 0x0, 6212 "Address (unknown)", HFILL 6213 } 6214 }, 6215 6216 6217 /* 6218 * New WSP header fields 6219 */ 6220 6221 6222 /* WSP header name */ 6223 { &hf_hdr_name_value, 6224 { "Header name", 6225 "wsp.header.name_value", 6226 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &vals_field_names_ext, 0x7F, 6227 "Name of the WSP header as numeric value", HFILL 6228 } 6229 }, 6230 { &hf_hdr_name_string, 6231 { "Header name", 6232 "wsp.header.name_string", 6233 FT_STRING, BASE_NONE, NULL, 0x0, 6234 "Name of the WSP header as string", HFILL 6235 } 6236 }, 6237 /* WSP headers start here */ 6238 { &hf_hdr_accept, 6239 { "Accept", 6240 "wsp.header.accept", 6241 FT_STRING, BASE_NONE, NULL, 0x00, 6242 "WSP header Accept", HFILL 6243 } 6244 }, 6245 { &hf_hdr_accept_charset, 6246 { "Accept-Charset", 6247 "wsp.header.accept_charset", 6248 FT_STRING, BASE_NONE, NULL, 0x00, 6249 "WSP header Accept-Charset", HFILL 6250 } 6251 }, 6252 { &hf_hdr_accept_encoding, 6253 { "Accept-Encoding", 6254 "wsp.header.accept_encoding", 6255 FT_STRING, BASE_NONE, NULL, 0x00, 6256 "WSP header Accept-Encoding", HFILL 6257 } 6258 }, 6259 { &hf_hdr_accept_language, 6260 { "Accept-Language", 6261 "wsp.header.accept_language", 6262 FT_STRING, BASE_NONE, NULL, 0x00, 6263 "WSP header Accept-Language", HFILL 6264 } 6265 }, 6266 { &hf_hdr_accept_ranges, 6267 { "Accept-Ranges", 6268 "wsp.header.accept_ranges", 6269 FT_STRING, BASE_NONE, NULL, 0x00, 6270 "WSP header Accept-Ranges", HFILL 6271 } 6272 }, 6273 { &hf_hdr_age, 6274 { "Age", 6275 "wsp.header.age", 6276 FT_STRING, BASE_NONE, NULL, 0x00, 6277 "WSP header Age", HFILL 6278 } 6279 }, 6280 { &hf_hdr_allow, 6281 { "Allow", 6282 "wsp.header.allow", 6283 FT_STRING, BASE_NONE, NULL, 0x00, 6284 "WSP header Allow", HFILL 6285 } 6286 }, 6287 { &hf_hdr_authorization, 6288 { "Authorization", 6289 "wsp.header.authorization", 6290 FT_STRING, BASE_NONE, NULL, 0x00, 6291 "WSP header Authorization", HFILL 6292 } 6293 }, 6294 { &hf_hdr_authorization_scheme, 6295 { "Authorization Scheme", 6296 "wsp.header.authorization.scheme", 6297 FT_STRING, BASE_NONE, NULL, 0x00, 6298 "WSP header Authorization: used scheme", HFILL 6299 } 6300 }, 6301 { &hf_hdr_authorization_user_id, 6302 { "User-id", 6303 "wsp.header.authorization.user_id", 6304 FT_STRING, BASE_NONE, NULL, 0x00, 6305 "WSP header Authorization: user ID for basic authorization", HFILL 6306 } 6307 }, 6308 { &hf_hdr_authorization_password, 6309 { "Password", 6310 "wsp.header.authorization.password", 6311 FT_STRING, BASE_NONE, NULL, 0x00, 6312 "WSP header Authorization: password for basic authorization", HFILL 6313 } 6314 }, 6315 { &hf_hdr_cache_control, 6316 { "Cache-Control", 6317 "wsp.header.cache_control", 6318 FT_STRING, BASE_NONE, NULL, 0x00, 6319 "WSP header Cache-Control", HFILL 6320 } 6321 }, 6322 { &hf_hdr_connection, 6323 { "Connection", 6324 "wsp.header.connection", 6325 FT_STRING, BASE_NONE, NULL, 0x00, 6326 "WSP header Connection", HFILL 6327 } 6328 }, 6329 { &hf_hdr_content_base, 6330 { "Content-Base", 6331 "wsp.header.content_base", 6332 FT_STRING, BASE_NONE, NULL, 0x00, 6333 "WSP header Content-Base", HFILL 6334 } 6335 }, 6336 { &hf_hdr_content_encoding, 6337 { "Content-Encoding", 6338 "wsp.header.content_encoding", 6339 FT_STRING, BASE_NONE, NULL, 0x00, 6340 "WSP header Content-Encoding", HFILL 6341 } 6342 }, 6343 { &hf_hdr_content_language, 6344 { "Content-Language", 6345 "wsp.header.content_language", 6346 FT_STRING, BASE_NONE, NULL, 0x00, 6347 "WSP header Content-Language", HFILL 6348 } 6349 }, 6350 { &hf_hdr_content_length, 6351 { "Content-Length", 6352 "wsp.header.content_length", 6353 FT_STRING, BASE_NONE, NULL, 0x00, 6354 "WSP header Content-Length", HFILL 6355 } 6356 }, 6357 { &hf_hdr_content_location, 6358 { "Content-Location", 6359 "wsp.header.content_location", 6360 FT_STRING, BASE_NONE, NULL, 0x00, 6361 "WSP header Content-Location", HFILL 6362 } 6363 }, 6364 { &hf_hdr_content_md5, 6365 { "Content-Md5", 6366 "wsp.header.content_md5", 6367 FT_BYTES, BASE_NONE, NULL, 0x00, 6368 "WSP header Content-Md5", HFILL 6369 } 6370 }, 6371 { &hf_hdr_content_range, 6372 { "Content-Range", 6373 "wsp.header.content_range", 6374 FT_STRING, BASE_NONE, NULL, 0x00, 6375 "WSP header Content-Range", HFILL 6376 } 6377 }, 6378 { &hf_hdr_content_range_first_byte_pos, 6379 { "First-byte-position", 6380 "wsp.header.content_range.first_byte_pos", 6381 FT_UINT32, BASE_DEC, NULL, 0x00, 6382 "WSP header Content-Range: position of first byte", HFILL 6383 } 6384 }, 6385 { &hf_hdr_content_range_entity_length, 6386 { "Entity-length", 6387 "wsp.header.content_range.entity_length", 6388 FT_UINT32, BASE_DEC, NULL, 0x00, 6389 "WSP header Content-Range: length of the entity", HFILL 6390 } 6391 }, 6392 { &hf_hdr_content_type, 6393 { "Content-Type", 6394 "wsp.header.content_type", 6395 FT_STRING, BASE_NONE, NULL, 0x00, 6396 "WSP header Content-Type", HFILL 6397 } 6398 }, 6399 { &hf_hdr_date, 6400 { "Date", 6401 "wsp.header.date", 6402 FT_STRING, BASE_NONE, NULL, 0x00, 6403 "WSP header Date", HFILL 6404 } 6405 }, 6406 { &hf_hdr_etag, 6407 { "ETag", 6408 "wsp.header.etag", 6409 FT_STRING, BASE_NONE, NULL, 0x00, 6410 "WSP header ETag", HFILL 6411 } 6412 }, 6413 { &hf_hdr_expires, 6414 { "Expires", 6415 "wsp.header.expires", 6416 FT_STRING, BASE_NONE, NULL, 0x00, 6417 "WSP header Expires", HFILL 6418 } 6419 }, 6420 { &hf_hdr_from, 6421 { "From", 6422 "wsp.header.from", 6423 FT_STRING, BASE_NONE, NULL, 0x00, 6424 "WSP header From", HFILL 6425 } 6426 }, 6427 { &hf_hdr_host, 6428 { "Host", 6429 "wsp.header.host", 6430 FT_STRING, BASE_NONE, NULL, 0x00, 6431 "WSP header Host", HFILL 6432 } 6433 }, 6434 { &hf_hdr_if_modified_since, 6435 { "If-Modified-Since", 6436 "wsp.header.if_modified_since", 6437 FT_STRING, BASE_NONE, NULL, 0x00, 6438 "WSP header If-Modified-Since", HFILL 6439 } 6440 }, 6441 { &hf_hdr_if_match, 6442 { "If-Match", 6443 "wsp.header.if_match", 6444 FT_STRING, BASE_NONE, NULL, 0x00, 6445 "WSP header If-Match", HFILL 6446 } 6447 }, 6448 { &hf_hdr_if_none_match, 6449 { "If-None-Match", 6450 "wsp.header.if_none_match", 6451 FT_STRING, BASE_NONE, NULL, 0x00, 6452 "WSP header If-None-Match", HFILL 6453 } 6454 }, 6455 { &hf_hdr_if_range, 6456 { "If-Range", 6457 "wsp.header.if_range", 6458 FT_STRING, BASE_NONE, NULL, 0x00, 6459 "WSP header If-Range", HFILL 6460 } 6461 }, 6462 { &hf_hdr_if_unmodified_since, 6463 { "If-Unmodified-Since", 6464 "wsp.header.if_unmodified_since", 6465 FT_STRING, BASE_NONE, NULL, 0x00, 6466 "WSP header If-Unmodified-Since", HFILL 6467 } 6468 }, 6469 { &hf_hdr_last_modified, 6470 { "Last-Modified", 6471 "wsp.header.last_modified", 6472 FT_STRING, BASE_NONE, NULL, 0x00, 6473 "WSP header Last-Modified", HFILL 6474 } 6475 }, 6476 { &hf_hdr_location, 6477 { "Location", 6478 "wsp.header.location", 6479 FT_STRING, BASE_NONE, NULL, 0x00, 6480 "WSP header Location", HFILL 6481 } 6482 }, 6483 { &hf_hdr_max_forwards, 6484 { "Max-Forwards", 6485 "wsp.header.max_forwards", 6486 FT_STRING, BASE_NONE, NULL, 0x00, 6487 "WSP header Max-Forwards", HFILL 6488 } 6489 }, 6490 { &hf_hdr_pragma, 6491 { "Pragma", 6492 "wsp.header.pragma", 6493 FT_STRING, BASE_NONE, NULL, 0x00, 6494 "WSP header Pragma", HFILL 6495 } 6496 }, 6497 { &hf_hdr_proxy_authenticate, 6498 { "Proxy-Authenticate", 6499 "wsp.header.proxy_authenticate", 6500 FT_STRING, BASE_NONE, NULL, 0x00, 6501 "WSP header Proxy-Authenticate", HFILL 6502 } 6503 }, 6504 { &hf_hdr_proxy_authenticate_scheme, 6505 { "Authentication Scheme", 6506 "wsp.header.proxy_authenticate.scheme", 6507 FT_STRING, BASE_NONE, NULL, 0x00, 6508 "WSP header Proxy-Authenticate: used scheme", HFILL 6509 } 6510 }, 6511 { &hf_hdr_proxy_authenticate_realm, 6512 { "Authentication Realm", 6513 "wsp.header.proxy_authenticate.realm", 6514 FT_STRING, BASE_NONE, NULL, 0x00, 6515 "WSP header Proxy-Authenticate: used realm", HFILL 6516 } 6517 }, 6518 { &hf_hdr_proxy_authorization, 6519 { "Proxy-Authorization", 6520 "wsp.header.proxy_authorization", 6521 FT_STRING, BASE_NONE, NULL, 0x00, 6522 "WSP header Proxy-Authorization", HFILL 6523 } 6524 }, 6525 { &hf_hdr_proxy_authorization_scheme, 6526 { "Authorization Scheme", 6527 "wsp.header.proxy_authorization.scheme", 6528 FT_STRING, BASE_NONE, NULL, 0x00, 6529 "WSP header Proxy-Authorization: used scheme", HFILL 6530 } 6531 }, 6532 { &hf_hdr_proxy_authorization_user_id, 6533 { "User-id", 6534 "wsp.header.proxy_authorization.user_id", 6535 FT_STRING, BASE_NONE, NULL, 0x00, 6536 "WSP header Proxy-Authorization: user ID for basic authorization", HFILL 6537 } 6538 }, 6539 { &hf_hdr_proxy_authorization_password, 6540 { "Password", 6541 "wsp.header.proxy_authorization.password", 6542 FT_STRING, BASE_NONE, NULL, 0x00, 6543 "WSP header Proxy-Authorization: password for basic authorization", HFILL 6544 } 6545 }, 6546 { &hf_hdr_public, 6547 { "Public", 6548 "wsp.header.public", 6549 FT_STRING, BASE_NONE, NULL, 0x00, 6550 "WSP header Public", HFILL 6551 } 6552 }, 6553 { &hf_hdr_range, 6554 { "Range", 6555 "wsp.header.range", 6556 FT_STRING, BASE_NONE, NULL, 0x00, 6557 "WSP header Range", HFILL 6558 } 6559 }, 6560 { &hf_hdr_range_first_byte_pos, 6561 { "First-byte-position", 6562 "wsp.header.range.first_byte_pos", 6563 FT_UINT32, BASE_DEC, NULL, 0x00, 6564 "WSP header Range: position of first byte", HFILL 6565 } 6566 }, 6567 { &hf_hdr_range_last_byte_pos, 6568 { "Last-byte-position", 6569 "wsp.header.range.last_byte_pos", 6570 FT_UINT32, BASE_DEC, NULL, 0x00, 6571 "WSP header Range: position of last byte", HFILL 6572 } 6573 }, 6574 { &hf_hdr_range_suffix_length, 6575 { "Suffix-length", 6576 "wsp.header.range.suffix_length", 6577 FT_UINT32, BASE_DEC, NULL, 0x00, 6578 "WSP header Range: length of the suffix", HFILL 6579 } 6580 }, 6581 { &hf_hdr_referer, 6582 { "Referer", 6583 "wsp.header.referer", 6584 FT_STRING, BASE_NONE, NULL, 0x00, 6585 "WSP header Referer", HFILL 6586 } 6587 }, 6588 { &hf_hdr_retry_after, 6589 { "Retry-After", 6590 "wsp.header.retry_after", 6591 FT_STRING, BASE_NONE, NULL, 0x00, 6592 "WSP header Retry-After", HFILL 6593 } 6594 }, 6595 { &hf_hdr_server, 6596 { "Server", 6597 "wsp.header.server", 6598 FT_STRING, BASE_NONE, NULL, 0x00, 6599 "WSP header Server", HFILL 6600 } 6601 }, 6602 { &hf_hdr_transfer_encoding, 6603 { "Transfer-Encoding", 6604 "wsp.header.transfer_encoding", 6605 FT_STRING, BASE_NONE, NULL, 0x00, 6606 "WSP header Transfer-Encoding", HFILL 6607 } 6608 }, 6609 { &hf_hdr_upgrade, 6610 { "Upgrade", 6611 "wsp.header.upgrade", 6612 FT_STRING, BASE_NONE, NULL, 0x00, 6613 "WSP header Upgrade", HFILL 6614 } 6615 }, 6616 { &hf_hdr_user_agent, 6617 { "User-Agent", 6618 "wsp.header.user_agent", 6619 FT_STRING, BASE_NONE, NULL, 0x00, 6620 "WSP header User-Agent", HFILL 6621 } 6622 }, 6623 { &hf_hdr_vary, 6624 { "Vary", 6625 "wsp.header.vary", 6626 FT_STRING, BASE_NONE, NULL, 0x00, 6627 "WSP header Vary", HFILL 6628 } 6629 }, 6630 { &hf_hdr_via, 6631 { "Via", 6632 "wsp.header.via", 6633 FT_STRING, BASE_NONE, NULL, 0x00, 6634 "WSP header Via", HFILL 6635 } 6636 }, 6637 { &hf_hdr_warning, 6638 { "Warning", 6639 "wsp.header.warning", 6640 FT_STRING, BASE_NONE, NULL, 0x00, 6641 "WSP header Warning", HFILL 6642 } 6643 }, 6644 { &hf_hdr_warning_code, 6645 { "Warning code", 6646 "wsp.header.warning.code", 6647 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_wsp_warning_code_ext, 0x00, 6648 "WSP header Warning code", HFILL 6649 } 6650 }, 6651 { &hf_hdr_warning_agent, 6652 { "Warning agent", 6653 "wsp.header.warning.agent", 6654 FT_STRING, BASE_NONE, NULL, 0x00, 6655 "WSP header Warning agent", HFILL 6656 } 6657 }, 6658 { &hf_hdr_warning_text, 6659 { "Warning text", 6660 "wsp.header.warning.text", 6661 FT_STRING, BASE_NONE, NULL, 0x00, 6662 "WSP header Warning text", HFILL 6663 } 6664 }, 6665 { &hf_hdr_www_authenticate, 6666 { "Www-Authenticate", 6667 "wsp.header.www_authenticate", 6668 FT_STRING, BASE_NONE, NULL, 0x00, 6669 "WSP header Www-Authenticate", HFILL 6670 } 6671 }, 6672 { &hf_hdr_www_authenticate_scheme, 6673 { "Authentication Scheme", 6674 "wsp.header.www_authenticate.scheme", 6675 FT_STRING, BASE_NONE, NULL, 0x00, 6676 "WSP header WWW-Authenticate: used scheme", HFILL 6677 } 6678 }, 6679 { &hf_hdr_www_authenticate_realm, 6680 { "Authentication Realm", 6681 "wsp.header.www_authenticate.realm", 6682 FT_STRING, BASE_NONE, NULL, 0x00, 6683 "WSP header WWW-Authenticate: used realm", HFILL 6684 } 6685 }, 6686 { &hf_hdr_content_disposition, 6687 { "Content-Disposition", 6688 "wsp.header.content_disposition", 6689 FT_STRING, BASE_NONE, NULL, 0x00, 6690 "WSP header Content-Disposition", HFILL 6691 } 6692 }, 6693 { &hf_hdr_application_id, 6694 { "Application-Id", 6695 "wsp.header.application_id", 6696 FT_STRING, BASE_NONE, NULL, 0x00, 6697 "WSP header Application-Id", HFILL 6698 } 6699 }, 6700 { &hf_hdr_content_uri, 6701 { "Content-Uri", 6702 "wsp.header.content_uri", 6703 FT_STRING, BASE_NONE, NULL, 0x00, 6704 "WSP header Content-Uri", HFILL 6705 } 6706 }, 6707 { &hf_hdr_initiator_uri, 6708 { "Initiator-Uri", 6709 "wsp.header.initiator_uri", 6710 FT_STRING, BASE_NONE, NULL, 0x00, 6711 "WSP header Initiator-Uri", HFILL 6712 } 6713 }, 6714 { &hf_hdr_bearer_indication, 6715 { "Bearer-Indication", 6716 "wsp.header.bearer_indication", 6717 FT_STRING, BASE_NONE, NULL, 0x00, 6718 "WSP header Bearer-Indication", HFILL 6719 } 6720 }, 6721 { &hf_hdr_push_flag, 6722 { "Push-Flag", 6723 "wsp.header.push_flag", 6724 FT_STRING, BASE_NONE, NULL, 0x00, 6725 "WSP header Push-Flag", HFILL 6726 } 6727 }, 6728 { &hf_hdr_push_flag_auth, 6729 { "Initiator URI is authenticated", 6730 "wsp.header.push_flag.authenticated", 6731 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x01, 6732 "The X-Wap-Initiator-URI has been authenticated.", HFILL 6733 } 6734 }, 6735 { &hf_hdr_push_flag_trust, 6736 { "Content is trusted", 6737 "wsp.header.push_flag.trusted", 6738 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x02, 6739 "The push content is trusted.", HFILL 6740 } 6741 }, 6742 { &hf_hdr_push_flag_last, 6743 { "Last push message", 6744 "wsp.header.push_flag.last", 6745 FT_UINT8, BASE_DEC, VALS(vals_false_true), 0x04, 6746 "Indicates whether this is the last push message.", HFILL 6747 } 6748 }, 6749 { &hf_hdr_profile, 6750 { "Profile", 6751 "wsp.header.profile", 6752 FT_STRING, BASE_NONE, NULL, 0x00, 6753 "WSP header Profile", HFILL 6754 } 6755 }, 6756 { &hf_hdr_profile_diff, 6757 { "Profile-Diff", 6758 "wsp.header.profile_diff", 6759 FT_STRING, BASE_NONE, NULL, 0x00, 6760 "WSP header Profile-Diff", HFILL 6761 } 6762 }, 6763 { &hf_hdr_profile_warning, 6764 { "Profile-Warning", 6765 "wsp.header.profile_warning", 6766 FT_STRING, BASE_NONE, NULL, 0x00, 6767 "WSP header Profile-Warning", HFILL 6768 } 6769 }, 6770 { &hf_hdr_expect, 6771 { "Expect", 6772 "wsp.header.expect", 6773 FT_STRING, BASE_NONE, NULL, 0x00, 6774 "WSP header Expect", HFILL 6775 } 6776 }, 6777 { &hf_hdr_te, 6778 { "Te", 6779 "wsp.header.te", 6780 FT_STRING, BASE_NONE, NULL, 0x00, 6781 "WSP header Te", HFILL 6782 } 6783 }, 6784 { &hf_hdr_trailer, 6785 { "Trailer", 6786 "wsp.header.trailer", 6787 FT_STRING, BASE_NONE, NULL, 0x00, 6788 "WSP header Trailer", HFILL 6789 } 6790 }, 6791 { &hf_hdr_x_wap_tod, 6792 { "X-Wap-Tod", 6793 "wsp.header.x_wap_tod", 6794 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00, 6795 "WSP header X-Wap-Tod", HFILL 6796 } 6797 }, 6798 { &hf_hdr_content_id, 6799 { "Content-Id", 6800 "wsp.header.content_id", 6801 FT_STRING, BASE_NONE, NULL, 0x00, 6802 "WSP header Content-Id", HFILL 6803 } 6804 }, 6805 { &hf_hdr_set_cookie, 6806 { "Set-Cookie", 6807 "wsp.header.set_cookie", 6808 FT_STRING, BASE_NONE, NULL, 0x00, 6809 "WSP header Set-Cookie", HFILL 6810 } 6811 }, 6812 { &hf_hdr_cookie, 6813 { "Cookie", 6814 "wsp.header.cookie", 6815 FT_STRING, BASE_NONE, NULL, 0x00, 6816 "WSP header Cookie", HFILL 6817 } 6818 }, 6819 { &hf_hdr_encoding_version, 6820 { "Encoding-Version", 6821 "wsp.header.encoding_version", 6822 FT_STRING, BASE_NONE, NULL, 0x00, 6823 "WSP header Encoding-Version", HFILL 6824 } 6825 }, 6826 { &hf_hdr_x_wap_security, 6827 { "X-Wap-Security", 6828 "wsp.header.x_wap_security", 6829 FT_STRING, BASE_NONE, NULL, 0x00, 6830 "WSP header X-Wap-Security", HFILL 6831 } 6832 }, 6833 { &hf_hdr_x_wap_application_id, 6834 { "X-Wap-Application-Id", 6835 "wsp.header.x_wap_application_id", 6836 FT_STRING, BASE_NONE, NULL, 0x00, 6837 "WSP header X-Wap-Application-Id", HFILL 6838 } 6839 }, 6840 { &hf_hdr_accept_application, 6841 { "Accept-Application", 6842 "wsp.header.accept_application", 6843 FT_STRING, BASE_NONE, NULL, 0x00, 6844 "WSP header Accept-Application", HFILL 6845 } 6846 }, 6847 6848 6849 /* 6850 * Openwave headers 6851 * Header Code Page: x-up-1 6852 */ 6853 { &hf_hdr_openwave_default_int, 6854 { "Default integer", 6855 "wsp.default_int", 6856 FT_UINT32, BASE_DEC, NULL, 0x00, 6857 NULL, HFILL 6858 } 6859 }, 6860 { &hf_hdr_openwave_default_string, 6861 { "Default string value", 6862 "wsp.default_string", 6863 FT_STRING, BASE_NONE, NULL, 0x00, 6864 NULL, HFILL 6865 } 6866 }, 6867 { &hf_hdr_openwave_default_val_len, 6868 { "Default value len", 6869 "wsp.default_val_len", 6870 FT_UINT32, BASE_DEC, NULL, 0x00, 6871 NULL, HFILL 6872 } 6873 }, 6874 { &hf_hdr_openwave_name_value, 6875 { "Header name", 6876 "wsp.header.name_value", 6877 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &vals_openwave_field_names_ext, 0x7F, 6878 "WSP Openwave header as numeric value", HFILL 6879 } 6880 }, 6881 6882 /* Textual headers */ 6883 { &hf_hdr_openwave_x_up_proxy_operator_domain, 6884 { "x-up-proxy-operator-domain", 6885 "wsp.header.x_up_1.x_up_proxy_operator_domain", 6886 FT_STRING, BASE_NONE, NULL, 0x00, 6887 "WSP Openwave header x-up-proxy-operator-domain", HFILL 6888 } 6889 }, 6890 { &hf_hdr_openwave_x_up_proxy_home_page, 6891 { "x-up-proxy-home-page", 6892 "wsp.header.x_up_1.x_up_proxy_home_page", 6893 FT_STRING, BASE_NONE, NULL, 0x00, 6894 "WSP Openwave header x-up-proxy-home-page", HFILL 6895 } 6896 }, 6897 { &hf_hdr_openwave_x_up_proxy_uplink_version, 6898 { "x-up-proxy-uplink-version", 6899 "wsp.header.x_up_1.x_up_proxy_uplink_version", 6900 FT_STRING, BASE_NONE, NULL, 0x00, 6901 "WSP Openwave header x-up-proxy-uplink-version", HFILL 6902 } 6903 }, 6904 { &hf_hdr_openwave_x_up_proxy_ba_realm, 6905 { "x-up-proxy-ba-realm", 6906 "wsp.header.x_up_1.x_up_proxy_ba_realm", 6907 FT_STRING, BASE_NONE, NULL, 0x00, 6908 "WSP Openwave header x-up-proxy-ba-realm", HFILL 6909 } 6910 }, 6911 { &hf_hdr_openwave_x_up_proxy_request_uri, 6912 { "x-up-proxy-request-uri", 6913 "wsp.header.x_up_1.x_up_proxy_request_uri", 6914 FT_STRING, BASE_NONE, NULL, 0x00, 6915 "WSP Openwave header x-up-proxy-request-uri", HFILL 6916 } 6917 }, 6918 { &hf_hdr_openwave_x_up_proxy_bookmark, 6919 { "x-up-proxy-bookmark", 6920 "wsp.header.x_up_1.x_up_proxy_bookmark", 6921 FT_STRING, BASE_NONE, NULL, 0x00, 6922 "WSP Openwave header x-up-proxy-bookmark", HFILL 6923 } 6924 }, 6925 /* Integer-value headers */ 6926 { &hf_hdr_openwave_x_up_proxy_push_seq, 6927 { "x-up-proxy-push-seq", 6928 "wsp.header.x_up_1.x_up_proxy_push_seq", 6929 FT_STRING, BASE_NONE, NULL, 0x00, 6930 "WSP Openwave header x-up-proxy-push-seq", HFILL 6931 } 6932 }, 6933 { &hf_hdr_openwave_x_up_proxy_notify, 6934 { "x-up-proxy-notify", 6935 "wsp.header.x_up_1.x_up_proxy_notify", 6936 FT_STRING, BASE_NONE, NULL, 0x00, 6937 "WSP Openwave header x-up-proxy-notify", HFILL 6938 } 6939 }, 6940 { &hf_hdr_openwave_x_up_proxy_net_ask, 6941 { "x-up-proxy-net-ask", 6942 "wsp.header.x_up_1.x_up_proxy_net_ask", 6943 FT_STRING, BASE_NONE, NULL, 0x00, 6944 "WSP Openwave header x-up-proxy-net-ask", HFILL 6945 } 6946 }, 6947 { &hf_hdr_openwave_x_up_proxy_tod, 6948 { "x-up-proxy-tod", 6949 "wsp.header.x_up_1.x_up_proxy_tod", 6950 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00, 6951 "WSP Openwave header x-up-proxy-tod", HFILL 6952 } 6953 }, 6954 { &hf_hdr_openwave_x_up_proxy_ba_enable, 6955 { "x-up-proxy-ba-enable", 6956 "wsp.header.x_up_1.x_up_proxy_ba_enable", 6957 FT_STRING, BASE_NONE, NULL, 0x00, 6958 "WSP Openwave header x-up-proxy-ba-enable", HFILL 6959 } 6960 }, 6961 { &hf_hdr_openwave_x_up_proxy_redirect_enable, 6962 { "x-up-proxy-redirect-enable", 6963 "wsp.header.x_up_1.x_up_proxy_redirect_enable", 6964 FT_STRING, BASE_NONE, NULL, 0x00, 6965 "WSP Openwave header x-up-proxy-redirect-enable", HFILL 6966 } 6967 }, 6968 { &hf_hdr_openwave_x_up_proxy_redirect_status, 6969 { "x-up-proxy-redirect-status", 6970 "wsp.header.x_up_1.x_up_proxy_redirect_status", 6971 FT_STRING, BASE_NONE, NULL, 0x00, 6972 "WSP Openwave header x-up-proxy-redirect-status", HFILL 6973 } 6974 }, 6975 { &hf_hdr_openwave_x_up_proxy_linger, 6976 { "x-up-proxy-linger", 6977 "wsp.header.x_up_1.x_up_proxy_linger", 6978 FT_STRING, BASE_NONE, NULL, 0x00, 6979 "WSP Openwave header x-up-proxy-linger", HFILL 6980 } 6981 }, 6982 { &hf_hdr_openwave_x_up_proxy_enable_trust, 6983 { "x-up-proxy-enable-trust", 6984 "wsp.header.x_up_1.x_up_proxy_enable_trust", 6985 FT_STRING, BASE_NONE, NULL, 0x00, 6986 "WSP Openwave header x-up-proxy-enable-trust", HFILL 6987 } 6988 }, 6989 { &hf_hdr_openwave_x_up_proxy_trust, 6990 { "x-up-proxy-trust", 6991 "wsp.header.x_up_1.x_up_proxy_trust", 6992 FT_STRING, BASE_NONE, NULL, 0x00, 6993 "WSP Openwave header x-up-proxy-trust", HFILL 6994 } 6995 }, 6996 { &hf_hdr_openwave_x_up_devcap_has_color, 6997 { "x-up-devcap-has-color", 6998 "wsp.header.x_up_1.x_up_devcap_has_color", 6999 FT_STRING, BASE_NONE, NULL, 0x00, 7000 "WSP Openwave header x-up-devcap-has-color", HFILL 7001 } 7002 }, 7003 { &hf_hdr_openwave_x_up_devcap_num_softkeys, 7004 { "x-up-devcap-num-softkeys", 7005 "wsp.header.x_up_1.x_up_devcap_num_softkeys", 7006 FT_STRING, BASE_NONE, NULL, 0x00, 7007 "WSP Openwave header x-up-devcap-num-softkeys", HFILL 7008 } 7009 }, 7010 { &hf_hdr_openwave_x_up_devcap_softkey_size, 7011 { "x-up-devcap-softkey-size", 7012 "wsp.header.x_up_1.x_up_devcap_softkey_size", 7013 FT_STRING, BASE_NONE, NULL, 0x00, 7014 "WSP Openwave header x-up-devcap-softkey-size", HFILL 7015 } 7016 }, 7017 { &hf_hdr_openwave_x_up_devcap_screen_chars, 7018 { "x-up-devcap-screen-chars", 7019 "wsp.header.x_up_1.x_up_devcap_screen_chars", 7020 FT_STRING, BASE_NONE, NULL, 0x00, 7021 "WSP Openwave header x-up-devcap-screen-chars", HFILL 7022 } 7023 }, 7024 { &hf_hdr_openwave_x_up_devcap_screen_pixels, 7025 { "x-up-devcap-screen-pixels", 7026 "wsp.header.x_up_1.x_up_devcap_screen_pixels", 7027 FT_STRING, BASE_NONE, NULL, 0x00, 7028 "WSP Openwave header x-up-devcap-screen-pixels", HFILL 7029 } 7030 }, 7031 { &hf_hdr_openwave_x_up_devcap_em_size, 7032 { "x-up-devcap-em-size", 7033 "wsp.header.x_up_1.x_up_devcap_em_size", 7034 FT_STRING, BASE_NONE, NULL, 0x00, 7035 "WSP Openwave header x-up-devcap-em-size", HFILL 7036 } 7037 }, 7038 { &hf_hdr_openwave_x_up_devcap_screen_depth, 7039 { "x-up-devcap-screen-depth", 7040 "wsp.header.x_up_1.x_up_devcap_screen_depth", 7041 FT_STRING, BASE_NONE, NULL, 0x00, 7042 "WSP Openwave header x-up-devcap-screen-depth", HFILL 7043 } 7044 }, 7045 { &hf_hdr_openwave_x_up_devcap_immed_alert, 7046 { "x-up-devcap-immed-alert", 7047 "wsp.header.x_up_1.x_up_devcap_immed_alert", 7048 FT_STRING, BASE_NONE, NULL, 0x00, 7049 "WSP Openwave header x-up-devcap-immed-alert", HFILL 7050 } 7051 }, 7052 { &hf_hdr_openwave_x_up_devcap_gui, 7053 { "x-up-devcap-gui", 7054 "wsp.header.x_up_1.x_up_devcap_gui", 7055 FT_STRING, BASE_NONE, NULL, 0x00, 7056 "WSP Openwave header x-up-devcap-gui", HFILL 7057 } 7058 }, 7059 { &hf_hdr_openwave_x_up_proxy_trans_charset, 7060 { "x-up-proxy-trans-charset", 7061 "wsp.header.x_up_1.x_up_proxy_trans_charset", 7062 FT_STRING, BASE_NONE, NULL, 0x00, 7063 "WSP Openwave header x-up-proxy-trans-charset", HFILL 7064 } 7065 }, 7066 { &hf_hdr_openwave_x_up_proxy_push_accept, 7067 { "x-up-proxy-push-accept", 7068 "wsp.header.x_up_1.x_up_proxy_push_accept", 7069 FT_STRING, BASE_NONE, NULL, 0x00, 7070 "WSP Openwave header x-up-proxy-push-accept", HFILL 7071 } 7072 }, 7073 7074 #if 0 7075 /* Not used for now */ 7076 { &hf_hdr_openwave_x_up_proxy_client_id, 7077 { "x-up-proxy-client-id", 7078 "wsp.header.x_up_1.x_up_proxy_client_id", 7079 FT_STRING, BASE_NONE, NULL, 0x00, 7080 "WSP Openwave header x-up-proxy-client-id", HFILL 7081 } 7082 }, 7083 #endif 7084 7085 /* 7086 * Header value parameters 7087 */ 7088 7089 { &hf_parameter_q, 7090 { "Q", 7091 "wsp.parameter.q", 7092 FT_STRING, BASE_NONE, NULL, 0x00, 7093 "Q parameter", HFILL 7094 } 7095 }, 7096 { &hf_parameter_charset, 7097 { "Charset", 7098 "wsp.parameter.charset", 7099 FT_STRING, BASE_NONE, NULL, 0x00, 7100 "Charset parameter", HFILL 7101 } 7102 } 7103 }; 7104 7105 /* Setup protocol subtree array */ 7106 static gint *ett[] = { 7107 &ett_wsp, 7108 &ett_header, /* Header field subtree */ 7109 &ett_headers, /* Subtree for WSP headers */ 7110 &ett_content_type_header, 7111 &ett_wsp_parameter_type, 7112 &ett_capabilities, /* CO-WSP Session Capabilities */ 7113 &ett_capabilities_entry, 7114 &ett_proto_option_capability, /* CO-WSP Session single Capability */ 7115 &ett_capabilities_extended_methods, 7116 &ett_capabilities_header_code_pages, 7117 &ett_post, 7118 &ett_redirect_flags, 7119 &ett_address_flags, 7120 &ett_multiparts, 7121 &ett_mpartlist, 7122 &ett_addresses, /* Addresses */ 7123 &ett_address, /* Single address */ 7124 &ett_default, 7125 &ett_add_content_type, 7126 &ett_accept_x_q_header, 7127 &ett_push_flag, 7128 &ett_profile_diff_wbxml, 7129 &ett_allow, 7130 &ett_public, 7131 &ett_vary, 7132 &ett_x_wap_security, 7133 &ett_connection, 7134 &ett_transfer_encoding, 7135 &ett_accept_ranges, 7136 &ett_content_encoding, 7137 &ett_accept_encoding, 7138 &ett_content_disposition, 7139 &ett_text_header, 7140 &ett_content_id, 7141 &ett_text_or_date_value, 7142 &ett_date_value, 7143 &ett_tod_value, 7144 &ett_age, 7145 &ett_integer_lookup, 7146 &ett_challenge, 7147 &ett_credentials_value, 7148 &ett_content_md5, 7149 &ett_pragma, 7150 &ett_integer_value, 7151 &ett_integer_lookup_value, 7152 &ett_cache_control, 7153 &ett_warning, 7154 &ett_profile_warning, 7155 &ett_encoding_version, 7156 &ett_content_range, 7157 &ett_range, 7158 &ett_te_value, 7159 &ett_openwave_default, 7160 }; 7161 7162 static ei_register_info ei[] = { 7163 { &ei_wsp_capability_invalid, { "wsp.capability.invalid", PI_PROTOCOL, PI_WARN, "Invalid capability", EXPFILL }}, 7164 { &ei_wsp_capability_length_invalid, { "wsp.capabilities.length.invalid", PI_PROTOCOL, PI_WARN, "Invalid capability length", EXPFILL }}, 7165 { &ei_wsp_capability_encoding_invalid, { "wsp.capability_encoding.invalid", PI_PROTOCOL, PI_WARN, "Invalid capability encoding", EXPFILL }}, 7166 { &ei_wsp_text_field_invalid, { "wsp.text_field_invalid", PI_PROTOCOL, PI_WARN, "Text field invalid", EXPFILL }}, 7167 { &ei_wsp_invalid_parameter_value, { "wsp.invalid_parameter_value", PI_PROTOCOL, PI_WARN, "Invalid parameter value", EXPFILL }}, 7168 { &ei_wsp_header_invalid_value, { "wsp.header_invalid_value", PI_PROTOCOL, PI_WARN, "Invalid header value", EXPFILL }}, 7169 { &ei_hdr_x_wap_tod, { "wsp.header.x_wap_tod.not_text", PI_PROTOCOL, PI_WARN, "Should be encoded as a textual value", EXPFILL }}, 7170 { &ei_wsp_undecoded_parameter, { "wsp.undecoded_parameter", PI_UNDECODED, PI_WARN, "Invalid parameter value", EXPFILL }}, 7171 { &ei_wsp_trailing_quote, { "wsp.trailing_quote", PI_PROTOCOL, PI_WARN, "Quoted-string value has been encoded with a trailing quote", EXPFILL }}, 7172 { &ei_wsp_header_invalid, { "wsp.header_invalid", PI_MALFORMED, PI_ERROR, "Malformed header", EXPFILL }}, 7173 { &ei_wsp_oversized_uintvar, { "wsp.oversized_uintvar", PI_MALFORMED, PI_ERROR, "Uintvar is oversized", EXPFILL }} 7174 }; 7175 7176 expert_module_t* expert_wsp; 7177 7178 /* Register the protocol name and description */ 7179 proto_wsp = proto_register_protocol( "Wireless Session Protocol", "WSP", "wsp"); 7180 wsp_tap = register_tap("wsp"); 7181 7182 /* Init the hash table */ 7183 /* wsp_sessions = g_hash_table_new( 7184 (GHashFunc) wsp_session_hash, 7185 (GEqualFunc)wsp_session_equal);*/ 7186 7187 /* Required function calls to register the header fields and subtrees used */ 7188 proto_register_field_array(proto_wsp, hf, array_length(hf)); 7189 proto_register_subtree_array(ett, array_length(ett)); 7190 expert_wsp = expert_register_protocol(proto_wsp); 7191 expert_register_field_array(expert_wsp, ei, array_length(ei)); 7192 7193 register_dissector("wsp-co", dissect_wsp_fromwap_co, proto_wsp); 7194 register_dissector("wsp-cl", dissect_wsp_fromwap_cl, proto_wsp); 7195 heur_subdissector_list = register_heur_dissector_list("wsp", proto_wsp); 7196 7197 wsp_fromudp_handle = create_dissector_handle(dissect_wsp_fromudp, 7198 proto_wsp); 7199 } 7200 7201 void 7202 proto_reg_handoff_wsp(void) 7203 { 7204 /* 7205 * Get a handle for the WTP-over-UDP and the generic media dissectors. 7206 */ 7207 wtp_fromudp_handle = find_dissector_add_dependency("wtp-udp", proto_wsp); 7208 media_handle = find_dissector_add_dependency("media", proto_wsp); 7209 coap_handle = find_dissector_add_dependency("coap", proto_wsp); 7210 wbxml_uaprof_handle = find_dissector_add_dependency("wbxml-uaprof", proto_wsp); 7211 7212 /* Only connection-less WSP has no previous handler */ 7213 dissector_add_uint_range_with_preference("udp.port", UDP_PORT_WSP_RANGE, wsp_fromudp_handle); 7214 7215 /* GSM SMS UD dissector can also carry WSP */ 7216 dissector_add_uint("gsm_sms_ud.udh.port", UDP_PORT_WSP, wsp_fromudp_handle); 7217 dissector_add_uint("gsm_sms_ud.udh.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle); 7218 7219 /* GSM SMS dissector can also carry WSP */ 7220 dissector_add_uint("gsm_sms.udh.port", UDP_PORT_WSP, wsp_fromudp_handle); 7221 dissector_add_uint("gsm_sms.udh.port", UDP_PORT_WSP_PUSH, wsp_fromudp_handle); 7222 7223 /* As the media types for WSP and HTTP are the same, the WSP dissector 7224 * uses the same string dissector table as the HTTP protocol. */ 7225 media_type_table = find_dissector_table("media_type"); 7226 7227 /* This dissector is also called from the WTP and WTLS dissectors */ 7228 } 7229 7230 /* 7231 * Session Initiation Request 7232 */ 7233 7234 /* Register the protocol with Wireshark */ 7235 void 7236 proto_register_sir(void) 7237 { 7238 /* Setup list of header fields */ 7239 static hf_register_info hf[] = { 7240 { &hf_sir_section, 7241 { "Session Initiation Request", 7242 "wap.sir", 7243 FT_NONE, BASE_NONE, NULL, 0x00, 7244 "Session Initiation Request content", HFILL 7245 } 7246 }, 7247 { &hf_sir_version, 7248 { "Version", 7249 "wap.sir.version", 7250 FT_UINT8, BASE_DEC, NULL, 0x00, 7251 "Version of the Session Initiation Request document", HFILL 7252 } 7253 }, 7254 { &hf_sir_app_id_list_len, 7255 { "Application-ID List Length", 7256 "wap.sir.app_id_list.length", 7257 FT_UINT32, BASE_DEC, NULL, 0x00, 7258 "Length of the Application-ID list (bytes)", HFILL 7259 } 7260 }, 7261 { &hf_sir_app_id_list, 7262 { "Application-ID List", 7263 "wap.sir.app_id_list", 7264 FT_NONE, BASE_NONE, NULL, 0x00, 7265 NULL, HFILL 7266 } 7267 }, 7268 { &hf_sir_wsp_contact_points_len, 7269 { "WSP Contact Points Length", 7270 "wap.sir.wsp_contact_points.length", 7271 FT_UINT32, BASE_DEC, NULL, 0x00, 7272 "Length of the WSP Contact Points list (bytes)", HFILL 7273 } 7274 }, 7275 { &hf_sir_wsp_contact_points, 7276 { "WSP Contact Points", 7277 "wap.sir.wsp_contact_points", 7278 FT_NONE, BASE_NONE, NULL, 0x00, 7279 "WSP Contact Points list", HFILL 7280 } 7281 }, 7282 { &hf_sir_contact_points_len, 7283 { "Non-WSP Contact Points Length", 7284 "wap.sir.contact_points.length", 7285 FT_UINT32, BASE_DEC, NULL, 0x00, 7286 "Length of the Non-WSP Contact Points list (bytes)", HFILL 7287 } 7288 }, 7289 { &hf_sir_contact_points, 7290 { "Non-WSP Contact Points", 7291 "wap.sir.contact_points", 7292 FT_NONE, BASE_NONE, NULL, 0x00, 7293 "Non-WSP Contact Points list", HFILL 7294 } 7295 }, 7296 { &hf_sir_protocol_options_len, 7297 { "Protocol Options List Entries", 7298 "wap.sir.protocol_options.length", 7299 FT_UINT32, BASE_DEC, NULL, 0x00, 7300 "Number of entries in the Protocol Options list", HFILL 7301 } 7302 }, 7303 { &hf_sir_protocol_options, 7304 { "Protocol Options", 7305 "wap.sir.protocol_options", 7306 FT_UINT16, BASE_DEC, VALS(vals_sir_protocol_options), 0x00, 7307 "Protocol Options list", HFILL 7308 } 7309 }, 7310 { &hf_sir_prov_url_len, 7311 { "X-Wap-ProvURL Length", 7312 "wap.sir.prov_url.length", 7313 FT_UINT32, BASE_DEC, NULL, 0x00, 7314 "Length of the X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL 7315 } 7316 }, 7317 { &hf_sir_prov_url, 7318 { "X-Wap-ProvURL", 7319 "wap.sir.prov_url", 7320 FT_STRING, BASE_NONE, NULL, 0x00, 7321 "X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL 7322 } 7323 }, 7324 { &hf_sir_cpi_tag_len, 7325 { "CPITag List Entries", 7326 "wap.sir.cpi_tag.length", 7327 FT_UINT32, BASE_DEC, NULL, 0x00, 7328 "Number of entries in the CPITag list", HFILL 7329 } 7330 }, 7331 { &hf_sir_cpi_tag, 7332 { "CPITag", 7333 "wap.sir.cpi_tag", 7334 FT_BYTES, BASE_NONE, NULL, 0x00, 7335 "CPITag (OTA-HTTP)", HFILL 7336 } 7337 } 7338 }; 7339 7340 /* Setup protocol subtree array */ 7341 static gint *ett[] = { 7342 &ett_sir /* Session Initiation Request */ 7343 }; 7344 7345 static tap_param wsp_stat_params[] = { 7346 { PARAM_FILTER, "filter", "Filter", NULL, TRUE } 7347 }; 7348 7349 static stat_tap_table_ui wsp_stat_table = { 7350 REGISTER_STAT_GROUP_TELEPHONY, 7351 "WAP-WSP Packet Counter", 7352 "wsp", 7353 "wsp,stat", 7354 wsp_stat_init, 7355 wsp_stat_packet, 7356 wsp_stat_reset, 7357 wsp_stat_free_table_item, 7358 NULL, 7359 sizeof(wsp_stat_fields)/sizeof(stat_tap_table_item), wsp_stat_fields, 7360 sizeof(wsp_stat_params)/sizeof(tap_param), wsp_stat_params, 7361 NULL, 7362 0 7363 }; 7364 7365 7366 /* Register the dissector */ 7367 proto_sir = proto_register_protocol( 7368 "WAP Session Initiation Request", /* protocol name for use by wireshark */ 7369 "WAP SIR", /* short version of name */ 7370 "wap-sir" /* Abbreviated protocol name, 7371 should Match IANA: 7372 < URL:http://www.iana.org/assignments/port-numbers/ > 7373 */ 7374 ); 7375 7376 /* Register header fields and protocol subtrees */ 7377 proto_register_field_array(proto_sir, hf, array_length(hf)); 7378 proto_register_subtree_array(ett, array_length(ett)); 7379 7380 register_stat_tap_table_ui(&wsp_stat_table); 7381 7382 } 7383 7384 void 7385 proto_reg_handoff_sir(void) 7386 { 7387 dissector_handle_t sir_handle; 7388 7389 sir_handle = create_dissector_handle(dissect_sir, proto_sir); 7390 7391 /* Add dissector bindings for SIR dissection */ 7392 dissector_add_string("media_type", "application/vnd.wap.sia", sir_handle); 7393 } 7394 7395 7396 7397 /* 7398 * Editor modelines 7399 * 7400 * Local Variables: 7401 * c-basic-offset: 4 7402 * tab-width: 8 7403 * indent-tabs-mode: nil 7404 * End: 7405 * 7406 * ex: set shiftwidth=4 tabstop=8 expandtab: 7407 * :indentSize=4:tabSize=8:noTabs=true: 7408 */ 7409