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
wkh_default(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_content_type_header(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name)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
wkh_accept(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_content_type(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
add_content_type(proto_tree * tree,packet_info * pinfo,tvbuff_t * tvb,guint32 val_start,guint32 * well_known_content,const char ** textual_content)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
wkh_accept_x_q_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name,value_string_ext * valueStringExtAddr,const char * value_format)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
wkh_push_flag(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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 */
wkh_profile_diff_wbxml(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_allow(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_public(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_vary(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_x_wap_security(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_connection(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_transfer_encoding(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_accept_ranges(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_content_encoding(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_accept_encoding(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_content_disposition(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_text_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name)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
wkh_content_id(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_text_or_date_value_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name)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
wkh_date_value_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name)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
wkh_tod_value_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name)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
wkh_age(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_integer_lookup_or_text_value_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name,value_string_ext * valueStringExtAddr,const char * value_format)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
wkh_challenge_value_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,int hf_scheme,int hf_realm,const char * name)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
wkh_credentials_value_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,int hf_scheme,int hf_userid,int hf_password,const char * name)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
wkh_content_md5(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_pragma(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
wkh_integer_value_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name)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
wkh_integer_lookup_value_header_func(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo,int hf,const char * name,value_string_ext * valueStringExtAddr,const char * value_name)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
wkh_cache_control(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_warning(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_profile_warning(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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 */
wkh_encoding_version(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_content_range(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_range(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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 */
wkh_te(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_openwave_default(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo _U_)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
wkh_openwave_x_up_proxy_push_accept(proto_tree * tree,tvbuff_t * tvb,guint32 hdr_start,packet_info * pinfo)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
parameter_text(proto_tree * tree,tvbuff_t * tvb,int * offset,proto_item * ti,int hf)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
parameter_text_value(proto_tree * tree,packet_info * pinfo,tvbuff_t * tvb,int * offset,proto_item * ti,int hf)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
parameter(proto_tree * tree,packet_info * pinfo,proto_item * ti,tvbuff_t * tvb,int start,int len)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
parameter_value_q(proto_tree * tree,packet_info * pinfo,proto_item * ti,tvbuff_t * tvb,int start)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
dissect_redirect(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dissector_handle_t dissector_handle)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
add_addresses(proto_tree * tree,tvbuff_t * tvb,int hf)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
add_headers(proto_tree * tree,tvbuff_t * tvb,int hf,packet_info * pinfo)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
dissect_sir(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)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
dissect_wsp_common(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,dissector_handle_t dissector_handle,gboolean is_connectionless)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
dissect_wsp_fromudp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)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
dissect_wsp_fromwap_co(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)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
dissect_wsp_fromwap_cl(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)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
add_uri(proto_tree * tree,packet_info * pinfo,tvbuff_t * tvb,guint URILenOffset,guint URIOffset,proto_item * proto_ti)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
add_capabilities(proto_tree * tree,packet_info * pinfo,tvbuff_t * tvb,guint8 pdu_type)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
add_post_data(proto_tree * tree,tvbuff_t * tvb,guint contentType,const char * contentTypeStr,packet_info * pinfo)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
add_post_variable(proto_tree * tree,tvbuff_t * tvb,guint variableStart,guint variableEnd,guint valueStart,guint valueEnd)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
add_multipart_data(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo)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
wsp_stat_init(stat_tap_table_ui * new_stat)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
wsp_stat_packet(void * tapdata,packet_info * pinfo _U_,epan_dissect_t * edt _U_,const void * wiv_ptr)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
wsp_stat_reset(stat_tap_table * table)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
wsp_stat_free_table_item(stat_tap_table * table _U_,guint row _U_,guint column,stat_tap_table_item_type * field_data)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
proto_register_wsp(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
proto_reg_handoff_wsp(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
proto_register_sir(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
proto_reg_handoff_sir(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