Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-wsp.c
blobb818071749ed590b8d72b12741c9d3b508d2934a
1 /* packet-wsp.c
3 * Routines to dissect WSP component of WAP traffic.
5 * Refer to the AUTHORS file or the AUTHORS section in the man page
6 * for contacting the author(s) of this file.
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * WAP dissector based on original work by Ben Fowler
13 * Updated by Neil Hunter.
15 * WTLS support by Alexandre P. Ferreira (Splice IP).
17 * Openwave header support by Dermot Bradley (Openwave).
19 * Code optimizations, header value dissection simplification with parse error
20 * notification and macros, extra missing headers, WBXML registration,
21 * summary line of WSP PDUs,
22 * Session Initiation Request dissection
23 * by Olivier Biot.
25 * SPDX-License-Identifier: GPL-2.0-or-later
28 #include "config.h"
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 #include <epan/tfs.h>
37 #include <wsutil/str_util.h>
38 #include <wsutil/array.h>
40 #include "packet-wap.h"
41 #include "packet-wsp.h"
43 /* Statistics (see doc/README.tapping) */
44 #include <epan/stat_tap_ui.h>
45 #include <epan/tap.h>
47 void proto_register_wsp(void);
48 void proto_reg_handoff_wsp(void);
49 void proto_register_sir(void);
50 void proto_reg_handoff_sir(void);
52 static int wsp_tap;
55 /* File scoped variables for the protocol and registered fields */
56 static int proto_wsp;
57 static int proto_sir;
60 * Initialize the header field pointers
63 /* WSP header fields and their subfields if available */
64 static int hf_hdr_name_value;
65 static int hf_hdr_name_string;
66 static int hf_hdr_accept;
67 static int hf_hdr_accept_charset;
68 static int hf_hdr_accept_encoding;
69 static int hf_hdr_accept_language;
70 static int hf_hdr_accept_ranges;
71 static int hf_hdr_age;
72 static int hf_hdr_allow;
73 static int hf_hdr_authorization;
74 static int hf_hdr_authorization_scheme; /* Subfield */
75 static int hf_hdr_authorization_user_id; /* Subfield */
76 static int hf_hdr_authorization_password; /* Subfield */
77 static int hf_hdr_cache_control;
78 static int hf_hdr_connection;
79 static int hf_hdr_content_base;
80 static int hf_hdr_content_encoding;
81 static int hf_hdr_content_language;
82 static int hf_hdr_content_length;
83 static int hf_hdr_content_location;
84 static int hf_hdr_content_md5;
85 static int hf_hdr_content_range;
86 static int hf_hdr_content_range_first_byte_pos; /* Subfield */
87 static int hf_hdr_content_range_entity_length; /* Subfield */
88 static int hf_hdr_content_type;
89 static int hf_hdr_date;
90 static int hf_hdr_etag;
91 static int hf_hdr_expires;
92 static int hf_hdr_from;
93 static int hf_hdr_host;
94 static int hf_hdr_if_modified_since;
95 static int hf_hdr_if_match;
96 static int hf_hdr_if_none_match;
97 static int hf_hdr_if_range;
98 static int hf_hdr_if_unmodified_since;
99 static int hf_hdr_last_modified;
100 static int hf_hdr_location;
101 static int hf_hdr_max_forwards;
102 static int hf_hdr_pragma;
103 static int hf_hdr_proxy_authenticate;
104 static int hf_hdr_proxy_authenticate_scheme; /* Subfield */
105 static int hf_hdr_proxy_authenticate_realm; /* Subfield */
106 static int hf_hdr_proxy_authorization;
107 static int hf_hdr_proxy_authorization_scheme; /* Subfield */
108 static int hf_hdr_proxy_authorization_user_id; /* Subfield */
109 static int hf_hdr_proxy_authorization_password; /* Subfield */
110 static int hf_hdr_public;
111 static int hf_hdr_range;
112 static int hf_hdr_range_first_byte_pos; /* Subfield */
113 static int hf_hdr_range_last_byte_pos; /* Subfield */
114 static int hf_hdr_range_suffix_length; /* Subfield */
115 static int hf_hdr_referer;
116 static int hf_hdr_retry_after;
117 static int hf_hdr_server;
118 static int hf_hdr_transfer_encoding;
119 static int hf_hdr_upgrade;
120 static int hf_hdr_user_agent;
121 static int hf_hdr_vary;
122 static int hf_hdr_via;
123 static int hf_hdr_warning;
124 static int hf_hdr_warning_code; /* Subfield */
125 static int hf_hdr_warning_agent; /* Subfield */
126 static int hf_hdr_warning_text; /* Subfield */
127 static int hf_hdr_www_authenticate;
128 static int hf_hdr_www_authenticate_scheme; /* Subfield */
129 static int hf_hdr_www_authenticate_realm; /* Subfield */
130 static int hf_hdr_content_disposition;
131 static int hf_hdr_application_id;
132 static int hf_hdr_content_uri;
133 static int hf_hdr_initiator_uri;
134 static int hf_hdr_bearer_indication;
135 static int hf_hdr_push_flag;
136 static int hf_hdr_push_flag_auth; /* Subfield */
137 static int hf_hdr_push_flag_trust; /* Subfield */
138 static int hf_hdr_push_flag_last; /* Subfield */
139 static int hf_hdr_profile;
140 static int hf_hdr_profile_diff;
141 static int hf_hdr_profile_warning;
142 static int hf_hdr_expect;
143 static int hf_hdr_te;
144 static int hf_hdr_trailer;
145 static int hf_hdr_x_wap_tod;
146 static int hf_hdr_content_id;
147 static int hf_hdr_set_cookie;
148 static int hf_hdr_cookie;
149 static int hf_hdr_encoding_version;
150 static int hf_hdr_x_wap_security;
151 static int hf_hdr_x_wap_application_id;
152 static int hf_hdr_accept_application;
155 /* Openwave headers */
156 static int hf_hdr_openwave_default_int;
157 static int hf_hdr_openwave_default_string;
158 static int hf_hdr_openwave_default_val_len;
159 static int hf_hdr_openwave_name_value;
160 static int hf_hdr_openwave_x_up_proxy_operator_domain;
161 static int hf_hdr_openwave_x_up_proxy_home_page;
162 static int hf_hdr_openwave_x_up_proxy_uplink_version;
163 static int hf_hdr_openwave_x_up_proxy_ba_realm;
164 static int hf_hdr_openwave_x_up_proxy_request_uri;
165 #if 0
166 static int hf_hdr_openwave_x_up_proxy_client_id;
167 #endif
168 static int hf_hdr_openwave_x_up_proxy_bookmark;
169 static int hf_hdr_openwave_x_up_proxy_push_seq;
170 static int hf_hdr_openwave_x_up_proxy_notify;
171 static int hf_hdr_openwave_x_up_proxy_net_ask;
172 static int hf_hdr_openwave_x_up_proxy_tod;
173 static int hf_hdr_openwave_x_up_proxy_ba_enable;
174 static int hf_hdr_openwave_x_up_proxy_redirect_enable;
175 static int hf_hdr_openwave_x_up_proxy_redirect_status;
176 static int hf_hdr_openwave_x_up_proxy_linger;
177 static int hf_hdr_openwave_x_up_proxy_enable_trust;
178 static int hf_hdr_openwave_x_up_proxy_trust;
179 static int hf_hdr_openwave_x_up_devcap_has_color;
180 static int hf_hdr_openwave_x_up_devcap_num_softkeys;
181 static int hf_hdr_openwave_x_up_devcap_softkey_size;
182 static int hf_hdr_openwave_x_up_devcap_screen_chars;
183 static int hf_hdr_openwave_x_up_devcap_screen_pixels;
184 static int hf_hdr_openwave_x_up_devcap_em_size;
185 static int hf_hdr_openwave_x_up_devcap_screen_depth;
186 static int hf_hdr_openwave_x_up_devcap_immed_alert;
187 static int hf_hdr_openwave_x_up_devcap_gui;
188 static int hf_hdr_openwave_x_up_proxy_trans_charset;
189 static int hf_hdr_openwave_x_up_proxy_push_accept;
192 /* WSP parameter fields */
193 static int hf_parameter_q;
194 static int hf_parameter_charset;
196 /* Old header fields */
198 static int hf_wsp_header_tid;
199 static int hf_wsp_header_pdu_type;
200 static int hf_wsp_version_major;
201 static int hf_wsp_version_minor;
202 /* Session capabilities (CO-WSP) */
203 static int hf_capabilities_length;
204 static int hf_capabilities_section;
205 static int hf_capa_client_sdu_size;
206 static int hf_capa_server_sdu_size;
207 static int hf_capa_protocol_options;
208 static int hf_capa_protocol_option_confirmed_push; /* Subfield */
209 static int hf_capa_protocol_option_push; /* Subfield */
210 static int hf_capa_protocol_option_session_resume; /* Subfield */
211 static int hf_capa_protocol_option_ack_headers; /* Subfield */
212 static int hf_capa_protocol_option_large_data_transfer; /* Subfield */
213 static int hf_capa_method_mor;
214 static int hf_capa_push_mor;
215 static int hf_capa_extended_method;
216 static int hf_capa_header_code_page;
217 static int hf_capa_aliases;
218 static int hf_capa_client_message_size;
219 static int hf_capa_server_message_size;
221 static int hf_wsp_header_uri_len;
222 static int hf_wsp_header_uri;
223 static int hf_wsp_server_session_id;
224 static int hf_wsp_header_status;
225 static int hf_wsp_header_length;
226 static int hf_wsp_headers_section;
227 static int hf_wsp_parameter_untype_quote_text;
228 static int hf_wsp_parameter_untype_text;
229 static int hf_wsp_parameter_untype_int;
230 static int hf_wsp_parameter_type;
231 static int hf_wsp_parameter_int_type;
232 static int hf_wsp_parameter_name;
233 static int hf_wsp_parameter_filename;
234 static int hf_wsp_parameter_start;
235 static int hf_wsp_parameter_start_info;
236 static int hf_wsp_parameter_comment;
237 static int hf_wsp_parameter_domain;
238 static int hf_wsp_parameter_path;
239 static int hf_wsp_parameter_sec;
240 static int hf_wsp_parameter_mac;
241 static int hf_wsp_parameter_upart_type;
242 static int hf_wsp_parameter_level;
243 static int hf_wsp_parameter_size;
244 #if 0
245 static int hf_wsp_reply_data;
246 #endif
247 static int hf_wsp_post_data;
248 #if 0
249 static int hf_wsp_push_data;
250 static int hf_wsp_multipart_data;
251 #endif
252 static int hf_wsp_mpart;
253 static int hf_wsp_header_text_value;
254 static int hf_wsp_variable_value;
255 static int hf_wsp_default_int;
256 static int hf_wsp_default_string;
257 static int hf_wsp_default_val_len;
259 /* Header code page shift sequence */
260 static int hf_wsp_header_shift_code;
262 /* WSP Redirect fields */
263 static int hf_wsp_redirect_flags;
264 static int hf_wsp_redirect_permanent;
265 static int hf_wsp_redirect_reuse_security_session;
266 static int hf_redirect_addresses;
268 /* Address fields */
269 static int hf_address_entry;
270 static int hf_address_flags_length;
271 static int hf_address_flags_length_bearer_type_included; /* Subfield */
272 static int hf_address_flags_length_port_number_included; /* Subfield */
273 static int hf_address_flags_length_address_len; /* Subfield */
274 static int hf_address_bearer_type;
275 static int hf_address_port_num;
276 static int hf_address_ipv4_addr;
277 static int hf_address_ipv6_addr;
278 static int hf_address_addr;
280 /* Session Initiation Request fields */
281 static int hf_sir_section;
282 static int hf_sir_version;
283 static int hf_sir_app_id_list_len;
284 static int hf_sir_app_id_list;
285 static int hf_sir_wsp_contact_points_len;
286 static int hf_sir_wsp_contact_points;
287 static int hf_sir_contact_points_len;
288 static int hf_sir_contact_points;
289 static int hf_sir_protocol_options_len;
290 static int hf_sir_protocol_options;
291 static int hf_sir_prov_url_len;
292 static int hf_sir_prov_url;
293 static int hf_sir_cpi_tag_len;
294 static int hf_sir_cpi_tag;
297 * Initialize the subtree pointers
300 /* WSP tree */
301 static int ett_wsp;
302 /* WSP headers tree */
303 static int ett_header;
304 /* WSP header subtree */
305 static int ett_headers;
306 static int ett_wsp_parameter_type;
307 static int ett_content_type_header;
308 /* CO-WSP session capabilities */
309 static int ett_capabilities;
310 static int ett_capabilities_entry;
311 static int ett_proto_option_capability;
312 static int ett_capabilities_header_code_pages;
313 static int ett_capabilities_extended_methods;
314 static int ett_post;
315 static int ett_redirect_flags;
316 static int ett_address_flags;
317 static int ett_multiparts;
318 static int ett_mpartlist;
319 /* Session Initiation Request tree */
320 static int ett_sir;
321 static int ett_addresses;
322 static int ett_address;
324 static int ett_default;
325 static int ett_add_content_type;
326 static int ett_accept_x_q_header;
327 static int ett_push_flag;
328 static int ett_profile_diff_wbxml;
329 static int ett_allow;
330 static int ett_public;
331 static int ett_vary;
332 static int ett_x_wap_security;
333 static int ett_connection;
334 static int ett_transfer_encoding;
335 static int ett_accept_ranges;
336 static int ett_content_encoding;
337 static int ett_accept_encoding;
338 static int ett_content_disposition;
339 static int ett_text_header;
340 static int ett_content_id;
341 static int ett_text_or_date_value;
342 static int ett_date_value;
343 static int ett_tod_value;
344 static int ett_age;
345 static int ett_integer_lookup;
346 static int ett_challenge;
347 static int ett_credentials_value;
348 static int ett_content_md5;
349 static int ett_pragma;
350 static int ett_integer_value;
351 static int ett_integer_lookup_value;
352 static int ett_cache_control;
353 static int ett_warning;
354 static int ett_profile_warning;
355 static int ett_encoding_version;
356 static int ett_content_range;
357 static int ett_range;
358 static int ett_te_value;
359 static int ett_openwave_default;
361 static expert_field ei_wsp_capability_invalid;
362 static expert_field ei_wsp_capability_length_invalid;
363 static expert_field ei_wsp_capability_encoding_invalid;
364 static expert_field ei_wsp_text_field_invalid;
365 static expert_field ei_wsp_header_invalid_value;
366 static expert_field ei_wsp_invalid_parameter_value;
367 static expert_field ei_wsp_undecoded_parameter;
368 static expert_field ei_hdr_x_wap_tod;
369 static expert_field ei_wsp_trailing_quote;
370 static expert_field ei_wsp_header_invalid;
371 static expert_field ei_wsp_oversized_uintvar;
374 /* Handle for WSP-over-UDP dissector */
375 static dissector_handle_t wsp_fromudp_handle;
377 /* Handle for WTP-over-UDP dissector */
378 static dissector_handle_t wtp_fromudp_handle;
380 /* Handle for coap dissector */
381 static dissector_handle_t coap_handle;
383 /* Handle for generic media dissector */
384 static dissector_handle_t media_handle;
386 /* Handle for WBXML-encoded UAPROF dissector */
387 static dissector_handle_t wbxml_uaprof_handle;
389 /* Handle for Session Initiation Request dissector */
390 static dissector_handle_t sir_handle;
393 static const value_string wsp_vals_pdu_type[] = {
394 { 0x00, "Reserved" },
395 { 0x01, "Connect" },
396 { 0x02, "ConnectReply" },
397 { 0x03, "Redirect" },
398 { 0x04, "Reply" },
399 { 0x05, "Disconnect" },
400 { 0x06, "Push" },
401 { 0x07, "ConfirmedPush" },
402 { 0x08, "Suspend" },
403 { 0x09, "Resume" },
405 /* 0x10 - 0x3F Unassigned */
407 { 0x40, "Get" },
408 { 0x41, "Options" },
409 { 0x42, "Head" },
410 { 0x43, "Delete" },
411 { 0x44, "Trace" },
413 /* 0x45 - 0x4F Unassigned (Get PDU) */
414 /* 0x50 - 0x5F Extended method (Get PDU) */
415 { 0x50, "Extended Get Method 0"},
416 { 0x51, "Extended Get Method 1"},
417 { 0x52, "Extended Get Method 2"},
418 { 0x53, "Extended Get Method 3"},
419 { 0x54, "Extended Get Method 4"},
420 { 0x55, "Extended Get Method 5"},
421 { 0x56, "Extended Get Method 6"},
422 { 0x57, "Extended Get Method 7"},
423 { 0x58, "Extended Get Method 8"},
424 { 0x59, "Extended Get Method 9"},
425 { 0x5A, "Extended Get Method 10"},
426 { 0x5B, "Extended Get Method 11"},
427 { 0x5C, "Extended Get Method 12"},
428 { 0x5D, "Extended Get Method 13"},
429 { 0x5E, "Extended Get Method 14"},
430 { 0x5F, "Extended Get Method 15"},
432 { 0x60, "Post" },
433 { 0x61, "Put" },
435 /* 0x62 - 0x6F Unassigned (Post PDU) */
436 /* 0x70 - 0x7F Extended method (Post PDU) */
437 { 0x70, "Extended Post Method 0"},
438 { 0x71, "Extended Post Method 1"},
439 { 0x72, "Extended Post Method 2"},
440 { 0x73, "Extended Post Method 3"},
441 { 0x74, "Extended Post Method 4"},
442 { 0x75, "Extended Post Method 5"},
443 { 0x76, "Extended Post Method 6"},
444 { 0x77, "Extended Post Method 7"},
445 { 0x78, "Extended Post Method 8"},
446 { 0x79, "Extended Post Method 9"},
447 { 0x7A, "Extended Post Method 10"},
448 { 0x7B, "Extended Post Method 11"},
449 { 0x7C, "Extended Post Method 12"},
450 { 0x7D, "Extended Post Method 13"},
451 { 0x7E, "Extended Post Method 14"},
452 { 0x7F, "Extended Post Method 15"},
454 /* 0x80 - 0xFF Reserved */
456 { 0x00, NULL }
459 value_string_ext wsp_vals_pdu_type_ext = VALUE_STRING_EXT_INIT(wsp_vals_pdu_type);
461 /* The WSP status codes are inherited from the HTTP status codes */
462 static const value_string wsp_vals_status[] = {
463 /* 0x00 - 0x0F Reserved */
465 { 0x10, "100 Continue" },
466 { 0x11, "101 Switching Protocols" },
468 { 0x20, "200 OK" },
469 { 0x21, "201 Created" },
470 { 0x22, "202 Accepted" },
471 { 0x23, "203 Non-Authoritative Information" },
472 { 0x24, "204 No Content" },
473 { 0x25, "205 Reset Content" },
474 { 0x26, "206 Partial Content" },
476 { 0x30, "300 Multiple Choices" },
477 { 0x31, "301 Moved Permanently" },
478 { 0x32, "302 Moved Temporarily" },
479 { 0x33, "303 See Other" },
480 { 0x34, "304 Not Modified" },
481 { 0x35, "305 Use Proxy" },
482 { 0x37, "307 Temporary Redirect" },
484 { 0x40, "400 Bad Request" },
485 { 0x41, "401 Unauthorised" },
486 { 0x42, "402 Payment Required" },
487 { 0x43, "403 Forbidden" },
488 { 0x44, "404 Not Found" },
489 { 0x45, "405 Method Not Allowed" },
490 { 0x46, "406 Not Acceptable" },
491 { 0x47, "407 Proxy Authentication Required" },
492 { 0x48, "408 Request Timeout" },
493 { 0x49, "409 Conflict" },
494 { 0x4A, "410 Gone" },
495 { 0x4B, "411 Length Required" },
496 { 0x4C, "412 Precondition Failed" },
497 { 0x4D, "413 Request Entity Too Large" },
498 { 0x4E, "414 Request-URI Too Large" },
499 { 0x4F, "415 Unsupported Media Type" },
500 { 0x50, "416 Requested Range Not Satisfiable" },
501 { 0x51, "417 Expectation Failed" },
503 { 0x60, "500 Internal Server Error" },
504 { 0x61, "501 Not Implemented" },
505 { 0x62, "502 Bad Gateway" },
506 { 0x63, "503 Service Unavailable" },
507 { 0x64, "504 Gateway Timeout" },
508 { 0x65, "505 WSP/HTTP Version Not Supported" },
510 { 0x00, NULL }
512 value_string_ext wsp_vals_status_ext = VALUE_STRING_EXT_INIT(wsp_vals_status);
514 static const value_string vals_wsp_reason_codes[] = {
515 { 0xE0, "Protocol Error (Illegal PDU)" },
516 { 0xE1, "Session disconnected" },
517 { 0xE2, "Session suspended" },
518 { 0xE3, "Session resumed" },
519 { 0xE4, "Peer congested" },
520 { 0xE5, "Session connect failed" },
521 { 0xE6, "Maximum receive unit size exceeded" },
522 { 0xE7, "Maximum outstanding requests exceeded" },
523 { 0xE8, "Peer request" },
524 { 0xE9, "Network error" },
525 { 0xEA, "User request" },
526 { 0xEB, "No specific cause, no retries" },
527 { 0xEC, "Push message cannot be delivered" },
528 { 0xED, "Push message discarded" },
529 { 0xEE, "Content type cannot be processed" },
531 { 0x00, NULL }
533 value_string_ext vals_wsp_reason_codes_ext = VALUE_STRING_EXT_INIT(vals_wsp_reason_codes);
536 * Field names.
538 #define FN_ACCEPT 0x00
539 #define FN_ACCEPT_CHARSET_DEP 0x01 /* encoding version 1.1, deprecated */
540 #define FN_ACCEPT_ENCODING_DEP 0x02 /* encoding version 1.1, deprecated */
541 #define FN_ACCEPT_LANGUAGE 0x03
542 #define FN_ACCEPT_RANGES 0x04
543 #define FN_AGE 0x05
544 #define FN_ALLOW 0x06
545 #define FN_AUTHORIZATION 0x07
546 #define FN_CACHE_CONTROL_DEP 0x08 /* encoding version 1.1, deprecated */
547 #define FN_CONNECTION 0x09
548 #define FN_CONTENT_BASE 0x0A
549 #define FN_CONTENT_ENCODING 0x0B
550 #define FN_CONTENT_LANGUAGE 0x0C
551 #define FN_CONTENT_LENGTH 0x0D
552 #define FN_CONTENT_LOCATION 0x0E
553 #define FN_CONTENT_MD5 0x0F
554 #define FN_CONTENT_RANGE_DEP 0x10 /* encoding version 1.1, deprecated */
555 #define FN_CONTENT_TYPE 0x11
556 #define FN_DATE 0x12
557 #define FN_ETAG 0x13
558 #define FN_EXPIRES 0x14
559 #define FN_FROM 0x15
560 #define FN_HOST 0x16
561 #define FN_IF_MODIFIED_SINCE 0x17
562 #define FN_IF_MATCH 0x18
563 #define FN_IF_NONE_MATCH 0x19
564 #define FN_IF_RANGE 0x1A
565 #define FN_IF_UNMODIFIED_SINCE 0x1B
566 #define FN_LOCATION 0x1C
567 #define FN_LAST_MODIFIED 0x1D
568 #define FN_MAX_FORWARDS 0x1E
569 #define FN_PRAGMA 0x1F
570 #define FN_PROXY_AUTHENTICATE 0x20
571 #define FN_PROXY_AUTHORIZATION 0x21
572 #define FN_PUBLIC 0x22
573 #define FN_RANGE 0x23
574 #define FN_REFERER 0x24
575 #define FN_RETRY_AFTER 0x25
576 #define FN_SERVER 0x26
577 #define FN_TRANSFER_ENCODING 0x27
578 #define FN_UPGRADE 0x28
579 #define FN_USER_AGENT 0x29
580 #define FN_VARY 0x2A
581 #define FN_VIA 0x2B
582 #define FN_WARNING 0x2C
583 #define FN_WWW_AUTHENTICATE 0x2D
584 #define FN_CONTENT_DISPOSITION 0x2E
585 #define FN_X_WAP_APPLICATION_ID 0x2F
586 #define FN_X_WAP_CONTENT_URI 0x30
587 #define FN_X_WAP_INITIATOR_URI 0x31
588 #define FN_ACCEPT_APPLICATION 0x32
589 #define FN_BEARER_INDICATION 0x33
590 #define FN_PUSH_FLAG 0x34
591 #define FN_PROFILE 0x35
592 #define FN_PROFILE_DIFF 0x36
593 #define FN_PROFILE_WARNING 0x37
594 #define FN_EXPECT 0x38
595 #define FN_TE 0x39
596 #define FN_TRAILER 0x3A
597 #define FN_ACCEPT_CHARSET 0x3B /* encoding version 1.3 */
598 #define FN_ACCEPT_ENCODING 0x3C /* encoding version 1.3 */
599 #define FN_CACHE_CONTROL 0x3D /* encoding version 1.3 */
600 #define FN_CONTENT_RANGE 0x3E /* encoding version 1.3 */
601 #define FN_X_WAP_TOD 0x3F
602 #define FN_CONTENT_ID 0x40
603 #define FN_SET_COOKIE 0x41
604 #define FN_COOKIE 0x42
605 #define FN_ENCODING_VERSION 0x43
606 #define FN_PROFILE_WARNING14 0x44 /* encoding version 1.4 */
607 #define FN_CONTENT_DISPOSITION14 0x45 /* encoding version 1.4 */
608 #define FN_X_WAP_SECURITY 0x46
609 #define FN_CACHE_CONTROL14 0x47 /* encoding version 1.4 */
610 #define FN_EXPECT15 0x48 /* encoding version 1.5 */
611 #define FN_X_WAP_LOC_INVOCATION 0x49
612 #define FN_X_WAP_LOC_DELIVERY 0x4A
616 * Openwave field names.
618 #define FN_OPENWAVE_PROXY_PUSH_ADDR 0x00
619 #define FN_OPENWAVE_PROXY_PUSH_ACCEPT 0x01
620 #define FN_OPENWAVE_PROXY_PUSH_SEQ 0x02
621 #define FN_OPENWAVE_PROXY_NOTIFY 0x03
622 #define FN_OPENWAVE_PROXY_OPERATOR_DOMAIN 0x04
623 #define FN_OPENWAVE_PROXY_HOME_PAGE 0x05
624 #define FN_OPENWAVE_DEVCAP_HAS_COLOR 0x06
625 #define FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS 0x07
626 #define FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE 0x08
627 #define FN_OPENWAVE_DEVCAP_SCREEN_CHARS 0x09
628 #define FN_OPENWAVE_DEVCAP_SCREEN_PIXELS 0x0A
629 #define FN_OPENWAVE_DEVCAP_EM_SIZE 0x0B
630 #define FN_OPENWAVE_DEVCAP_SCREEN_DEPTH 0x0C
631 #define FN_OPENWAVE_DEVCAP_IMMED_ALERT 0x0D
632 #define FN_OPENWAVE_PROXY_NET_ASK 0x0E
633 #define FN_OPENWAVE_PROXY_UPLINK_VERSION 0x0F
634 #define FN_OPENWAVE_PROXY_TOD 0x10
635 #define FN_OPENWAVE_PROXY_BA_ENABLE 0x11
636 #define FN_OPENWAVE_PROXY_BA_REALM 0x12
637 #define FN_OPENWAVE_PROXY_REDIRECT_ENABLE 0x13
638 #define FN_OPENWAVE_PROXY_REQUEST_URI 0x14
639 #define FN_OPENWAVE_PROXY_REDIRECT_STATUS 0x15
640 #define FN_OPENWAVE_PROXY_TRANS_CHARSET 0x16
641 #define FN_OPENWAVE_PROXY_LINGER 0x17
642 #define FN_OPENWAVE_PROXY_CLIENT_ID 0x18
643 #define FN_OPENWAVE_PROXY_ENABLE_TRUST 0x19
644 #define FN_OPENWAVE_PROXY_TRUST_OLD 0x1A
645 #define FN_OPENWAVE_PROXY_TRUST 0x20
646 #define FN_OPENWAVE_PROXY_BOOKMARK 0x21
647 #define FN_OPENWAVE_DEVCAP_GUI 0x22
649 static const value_string vals_openwave_field_names[] = {
650 { FN_OPENWAVE_PROXY_PUSH_ADDR, "x-up-proxy-push-addr" },
651 { FN_OPENWAVE_PROXY_PUSH_ACCEPT, "x-up-proxy-push-accept" },
652 { FN_OPENWAVE_PROXY_PUSH_SEQ, "x-up-proxy-seq" },
653 { FN_OPENWAVE_PROXY_NOTIFY, "x-up-proxy-notify" },
654 { FN_OPENWAVE_PROXY_OPERATOR_DOMAIN, "x-up-proxy-operator-domain" },
655 { FN_OPENWAVE_PROXY_HOME_PAGE, "x-up-proxy-home-page" },
656 { FN_OPENWAVE_DEVCAP_HAS_COLOR, "x-up-devcap-has-color" },
657 { FN_OPENWAVE_DEVCAP_NUM_SOFTKEYS, "x-up-devcap-num-softkeys" },
658 { FN_OPENWAVE_DEVCAP_SOFTKEY_SIZE, "x-up-devcap-softkey-size" },
659 { FN_OPENWAVE_DEVCAP_SCREEN_CHARS, "x-up-devcap-screen-chars" },
660 { FN_OPENWAVE_DEVCAP_SCREEN_PIXELS, "x-up-devcap-screen-pixels" },
661 { FN_OPENWAVE_DEVCAP_EM_SIZE, "x-up-devcap-em-size" },
662 { FN_OPENWAVE_DEVCAP_SCREEN_DEPTH, "x-up-devcap-screen-depth" },
663 { FN_OPENWAVE_DEVCAP_IMMED_ALERT, "x-up-devcap-immed-alert" },
664 { FN_OPENWAVE_PROXY_NET_ASK, "x-up-proxy-net-ask" },
665 { FN_OPENWAVE_PROXY_UPLINK_VERSION, "x-up-proxy-uplink-version" },
666 { FN_OPENWAVE_PROXY_TOD, "x-up-proxy-tod" },
667 { FN_OPENWAVE_PROXY_BA_ENABLE, "x-up-proxy-ba-enable" },
668 { FN_OPENWAVE_PROXY_BA_REALM, "x-up-proxy-ba-realm" },
669 { FN_OPENWAVE_PROXY_REDIRECT_ENABLE, "x-up-proxy-redirect-enable" },
670 { FN_OPENWAVE_PROXY_REQUEST_URI, "x-up-proxy-request-uri" },
671 { FN_OPENWAVE_PROXY_REDIRECT_STATUS, "x-up-proxy-redirect-status" },
672 { FN_OPENWAVE_PROXY_TRANS_CHARSET, "x-up-proxy-trans-charset" },
673 { FN_OPENWAVE_PROXY_LINGER, "x-up-proxy-linger" },
674 { FN_OPENWAVE_PROXY_CLIENT_ID, "x-up-proxy-client-id" },
675 { FN_OPENWAVE_PROXY_ENABLE_TRUST, "x-up-proxy-enable-trust" },
676 { FN_OPENWAVE_PROXY_TRUST_OLD, "x-up-proxy-trust-old" },
677 { FN_OPENWAVE_PROXY_TRUST, "x-up-proxy-trust" },
678 { FN_OPENWAVE_PROXY_BOOKMARK, "x-up-proxy-bookmark" },
679 { FN_OPENWAVE_DEVCAP_GUI, "x-up-devcap-gui" },
680 { 0, NULL }
682 static value_string_ext vals_openwave_field_names_ext = VALUE_STRING_EXT_INIT(vals_openwave_field_names);
684 static const value_string vals_field_names[] = {
685 { FN_ACCEPT, "Accept" },
686 { FN_ACCEPT_CHARSET_DEP, "Accept-Charset (encoding 1.1)" },
687 { FN_ACCEPT_ENCODING_DEP, "Accept-Encoding (encoding 1.1)" },
688 { FN_ACCEPT_LANGUAGE, "Accept-Language" },
689 { FN_ACCEPT_RANGES, "Accept-Ranges" },
690 { FN_AGE, "Age" },
691 { FN_ALLOW, "Allow" },
692 { FN_AUTHORIZATION, "Authorization" },
693 { FN_CACHE_CONTROL_DEP, "Cache-Control (encoding 1.1)" },
694 { FN_CONNECTION, "Connection" },
695 { FN_CONTENT_BASE, "Content-Base" },
696 { FN_CONTENT_ENCODING, "Content-Encoding" },
697 { FN_CONTENT_LANGUAGE, "Content-Language" },
698 { FN_CONTENT_LENGTH, "Content-Length" },
699 { FN_CONTENT_LOCATION, "Content-Location" },
700 { FN_CONTENT_MD5, "Content-MD5" },
701 { FN_CONTENT_RANGE_DEP, "Content-Range (encoding 1.1)" },
702 { FN_CONTENT_TYPE, "Content-Type" },
703 { FN_DATE, "Date" },
704 { FN_ETAG, "ETag" },
705 { FN_EXPIRES, "Expires" },
706 { FN_FROM, "From" },
707 { FN_HOST, "Host" },
708 { FN_IF_MODIFIED_SINCE, "If-Modified-Since" },
709 { FN_IF_MATCH, "If-Match" },
710 { FN_IF_NONE_MATCH, "If-None-Match" },
711 { FN_IF_RANGE, "If-Range" },
712 { FN_IF_UNMODIFIED_SINCE, "If-Unmodified-Since" },
713 { FN_LOCATION, "Location" },
714 { FN_LAST_MODIFIED, "Last-Modified" },
715 { FN_MAX_FORWARDS, "Max-Forwards" },
716 { FN_PRAGMA, "Pragma" },
717 { FN_PROXY_AUTHENTICATE, "Proxy-Authenticate" },
718 { FN_PROXY_AUTHORIZATION, "Proxy-Authorization" },
719 { FN_PUBLIC, "Public" },
720 { FN_RANGE, "Range" },
721 { FN_REFERER, "Referer" },
722 { FN_RETRY_AFTER, "Retry-After" },
723 { FN_SERVER, "Server" },
724 { FN_TRANSFER_ENCODING, "Transfer-Encoding" },
725 { FN_UPGRADE, "Upgrade" },
726 { FN_USER_AGENT, "User-Agent" },
727 { FN_VARY, "Vary" },
728 { FN_VIA, "Via" },
729 { FN_WARNING, "Warning" },
730 { FN_WWW_AUTHENTICATE, "WWW-Authenticate" },
731 { FN_CONTENT_DISPOSITION, "Content-Disposition" },
732 { FN_X_WAP_APPLICATION_ID, "X-Wap-Application-ID" },
733 { FN_X_WAP_CONTENT_URI, "X-Wap-Content-URI" },
734 { FN_X_WAP_INITIATOR_URI, "X-Wap-Initiator-URI" },
735 { FN_ACCEPT_APPLICATION, "Accept-Application" },
736 { FN_BEARER_INDICATION, "Bearer-Indication" },
737 { FN_PUSH_FLAG, "Push-Flag" },
738 { FN_PROFILE, "Profile" },
739 { FN_PROFILE_DIFF, "Profile-Diff" },
740 { FN_PROFILE_WARNING, "Profile-Warning" },
741 { FN_EXPECT, "Expect" },
742 { FN_TE, "TE" },
743 { FN_TRAILER, "Trailer" },
744 { FN_ACCEPT_CHARSET, "Accept-Charset" },
745 { FN_ACCEPT_ENCODING, "Accept-Encoding" },
746 { FN_CACHE_CONTROL, "Cache-Control" },
747 { FN_CONTENT_RANGE, "Content-Range" },
748 { FN_X_WAP_TOD, "X-Wap-Tod" },
749 { FN_CONTENT_ID, "Content-ID" },
750 { FN_SET_COOKIE, "Set-Cookie" },
751 { FN_COOKIE, "Cookie" },
752 { FN_ENCODING_VERSION, "Encoding-Version" },
753 { FN_PROFILE_WARNING14, "Profile-Warning (encoding 1.4)" },
754 { FN_CONTENT_DISPOSITION14,"Content-Disposition (encoding 1.4)" },
755 { FN_X_WAP_SECURITY, "X-WAP-Security" },
756 { FN_CACHE_CONTROL14, "Cache-Control (encoding 1.4)" },
757 /* encoding-version 1.5 */
758 { FN_EXPECT15, "Expect (encoding 1.5)" },
759 { FN_X_WAP_LOC_INVOCATION, "X-Wap-Loc-Invocation" },
760 { FN_X_WAP_LOC_DELIVERY, "X-Wap-Loc-Delivery" },
761 { 0, NULL }
763 static value_string_ext vals_field_names_ext = VALUE_STRING_EXT_INIT(vals_field_names);
766 * Bearer types (from the WDP specification).
768 #define BT_IPv4 0x00
769 #define BT_IPv6 0x01
770 #define BT_GSM_USSD 0x02
771 #define BT_GSM_SMS 0x03
772 #define BT_ANSI_136_GUTS 0x04
773 #define BT_IS_95_SMS 0x05
774 #define BT_IS_95_CSD 0x06
775 #define BT_IS_95_PACKET_DATA 0x07
776 #define BT_ANSI_136_CSD 0x08
777 #define BT_ANSI_136_PACKET_DATA 0x09
778 #define BT_GSM_CSD 0x0A
779 #define BT_GSM_GPRS 0x0B
780 #define BT_GSM_USSD_IPv4 0x0C
781 #define BT_AMPS_CDPD 0x0D
782 #define BT_PDC_CSD 0x0E
783 #define BT_PDC_PACKET_DATA 0x0F
784 #define BT_IDEN_SMS 0x10
785 #define BT_IDEN_CSD 0x11
786 #define BT_IDEN_PACKET_DATA 0x12
787 #define BT_PAGING_FLEX 0x13
788 #define BT_PHS_SMS 0x14
789 #define BT_PHS_CSD 0x15
790 #define BT_GSM_USSD_GSM_SC 0x16
791 #define BT_TETRA_SDS_ITSI 0x17
792 #define BT_TETRA_SDS_MSISDN 0x18
793 #define BT_TETRA_PACKET_DATA 0x19
794 #define BT_PAGING_REFLEX 0x1A
795 #define BT_GSM_USSD_MSISDN 0x1B
796 #define BT_MOBITEX_MPAK 0x1C
797 #define BT_ANSI_136_GHOST 0x1D
799 static const value_string vals_bearer_types[] = {
800 { BT_IPv4, "IPv4" },
801 { BT_IPv6, "IPv6" },
802 { BT_GSM_USSD, "GSM USSD" },
803 { BT_GSM_SMS, "GSM SMS" },
804 { BT_ANSI_136_GUTS, "ANSI-136 GUTS/R-Data" },
805 { BT_IS_95_SMS, "IS-95 CDMA SMS" },
806 { BT_IS_95_CSD, "IS-95 CDMA CSD" },
807 { BT_IS_95_PACKET_DATA, "IS-95 CDMA Packet data" },
808 { BT_ANSI_136_CSD, "ANSI-136 CSD" },
809 { BT_ANSI_136_PACKET_DATA, "ANSI-136 Packet data" },
810 { BT_GSM_CSD, "GSM CSD" },
811 { BT_GSM_GPRS, "GSM GPRS" },
812 { BT_GSM_USSD_IPv4, "GSM USSD (IPv4 addresses)" },
813 { BT_AMPS_CDPD, "AMPS CDPD" },
814 { BT_PDC_CSD, "PDC CSD" },
815 { BT_PDC_PACKET_DATA, "PDC Packet data" },
816 { BT_IDEN_SMS, "IDEN SMS" },
817 { BT_IDEN_CSD, "IDEN CSD" },
818 { BT_IDEN_PACKET_DATA, "IDEN Packet data" },
819 { BT_PAGING_FLEX, "Paging network FLEX(TM)" },
820 { BT_PHS_SMS, "PHS SMS" },
821 { BT_PHS_CSD, "PHS CSD" },
822 { BT_GSM_USSD_GSM_SC, "GSM USSD (GSM Service Code addresses)" },
823 { BT_TETRA_SDS_ITSI, "TETRA SDS (ITSI addresses)" },
824 { BT_TETRA_SDS_MSISDN, "TETRA SDS (MSISDN addresses)" },
825 { BT_TETRA_PACKET_DATA, "TETRA Packet data" },
826 { BT_PAGING_REFLEX, "Paging network ReFLEX(TM)" },
827 { BT_GSM_USSD_MSISDN, "GSM USSD (MSISDN addresses)" },
828 { BT_MOBITEX_MPAK, "Mobitex MPAK" },
829 { BT_ANSI_136_GHOST, "ANSI-136 GHOST/R-Data" },
830 { 0, NULL }
832 static value_string_ext vals_bearer_types_ext = VALUE_STRING_EXT_INIT(vals_bearer_types);
834 static const value_string vals_content_types[] = {
835 /* Well-known media types */
836 /* XXX: hack: "..." "..." used to define several strings so that checkAPIs & etc won't see a 'start of comment' */
837 { 0x00, "*" "/" "*" },
838 { 0x01, "text/" "*" },
839 { 0x02, "text/html" },
840 { 0x03, "text/plain" },
841 { 0x04, "text/x-hdml" },
842 { 0x05, "text/x-ttml" },
843 { 0x06, "text/x-vCalendar" },
844 { 0x07, "text/x-vCard" },
845 { 0x08, "text/vnd.wap.wml" },
846 { 0x09, "text/vnd.wap.wmlscript" },
847 { 0x0A, "text/vnd.wap.channel" },
848 { 0x0B, "multipart/" "*" },
849 { 0x0C, "multipart/mixed" },
850 { 0x0D, "multipart/form-data" },
851 { 0x0E, "multipart/byteranges" },
852 { 0x0F, "multipart/alternative" },
853 { 0x10, "application/" "*" },
854 { 0x11, "application/java-vm" },
855 { 0x12, "application/x-www-form-urlencoded" },
856 { 0x13, "application/x-hdmlc" },
857 { 0x14, "application/vnd.wap.wmlc" },
858 { 0x15, "application/vnd.wap.wmlscriptc" },
859 { 0x16, "application/vnd.wap.channelc" },
860 { 0x17, "application/vnd.wap.uaprof" },
861 { 0x18, "application/vnd.wap.wtls-ca-certificate" },
862 { 0x19, "application/vnd.wap.wtls-user-certificate" },
863 { 0x1A, "application/x-x509-ca-cert" },
864 { 0x1B, "application/x-x509-user-cert" },
865 { 0x1C, "image/" "*" },
866 { 0x1D, "image/gif" },
867 { 0x1E, "image/jpeg" },
868 { 0x1F, "image/tiff" },
869 { 0x20, "image/png" },
870 { 0x21, "image/vnd.wap.wbmp" },
871 { 0x22, "application/vnd.wap.multipart.*" },
872 { 0x23, "application/vnd.wap.multipart.mixed" },
873 { 0x24, "application/vnd.wap.multipart.form-data" },
874 { 0x25, "application/vnd.wap.multipart.byteranges" },
875 { 0x26, "application/vnd.wap.multipart.alternative" },
876 { 0x27, "application/xml" },
877 { 0x28, "text/xml" },
878 { 0x29, "application/vnd.wap.wbxml" },
879 { 0x2A, "application/x-x968-cross-cert" },
880 { 0x2B, "application/x-x968-ca-cert" },
881 { 0x2C, "application/x-x968-user-cert" },
882 { 0x2D, "text/vnd.wap.si" },
883 { 0x2E, "application/vnd.wap.sic" },
884 { 0x2F, "text/vnd.wap.sl" },
885 { 0x30, "application/vnd.wap.slc" },
886 { 0x31, "text/vnd.wap.co" },
887 { 0x32, "application/vnd.wap.coc" },
888 { 0x33, "application/vnd.wap.multipart.related" },
889 { 0x34, "application/vnd.wap.sia" },
890 { 0x35, "text/vnd.wap.connectivity-xml" },
891 { 0x36, "application/vnd.wap.connectivity-wbxml" },
892 { 0x37, "application/pkcs7-mime" },
893 { 0x38, "application/vnd.wap.hashed-certificate" },
894 { 0x39, "application/vnd.wap.signed-certificate" },
895 { 0x3A, "application/vnd.wap.cert-response" },
896 { 0x3B, "application/xhtml+xml" },
897 { 0x3C, "application/wml+xml" },
898 { 0x3D, "text/css" },
899 { 0x3E, "application/vnd.wap.mms-message" },
900 { 0x3F, "application/vnd.wap.rollover-certificate" },
901 { 0x40, "application/vnd.wap.locc+wbxml"},
902 { 0x41, "application/vnd.wap.loc+xml"},
903 { 0x42, "application/vnd.syncml.dm+wbxml"},
904 { 0x43, "application/vnd.syncml.dm+xml"},
905 { 0x44, "application/vnd.syncml.notification"},
906 { 0x45, "application/vnd.wap.xhtml+xml"},
907 { 0x46, "application/vnd.wv.csp.cir"},
908 { 0x47, "application/vnd.oma.dd+xml"},
909 { 0x48, "application/vnd.oma.drm.message"},
910 { 0x49, "application/vnd.oma.drm.content"},
911 { 0x4A, "application/vnd.oma.drm.rights+xml"},
912 { 0x4B, "application/vnd.oma.drm.rights+wbxml"},
913 { 0x4C, "application/vnd.wv.csp+xml"},
914 { 0x4D, "application/vnd.wv.csp+wbxml"},
915 { 0x5A, "application/octet-stream"},
916 /* The following media types are registered by 3rd parties */
917 { 0x0201, "application/vnd.uplanet.cachop-wbxml" },
918 { 0x0202, "application/vnd.uplanet.signal" },
919 { 0x0203, "application/vnd.uplanet.alert-wbxml" },
920 { 0x0204, "application/vnd.uplanet.list-wbxml" },
921 { 0x0205, "application/vnd.uplanet.listcmd-wbxml" },
922 { 0x0206, "application/vnd.uplanet.channel-wbxml" },
923 { 0x0207, "application/vnd.uplanet.provisioning-status-uri" },
924 { 0x0208, "x-wap.multipart/vnd.uplanet.header-set" },
925 { 0x0209, "application/vnd.uplanet.bearer-choice-wbxml" },
926 { 0x020A, "application/vnd.phonecom.mmc-wbxml" },
927 { 0x020B, "application/vnd.nokia.syncset+wbxml" },
928 { 0x020C, "image/x-up-wpng"},
929 { 0x0300, "application/iota.mmc-wbxml"},
930 { 0x0301, "application/iota.mmc-xml"},
931 { 0x00, NULL }
933 static value_string_ext vals_content_types_ext = VALUE_STRING_EXT_INIT(vals_content_types);
935 static const value_string vals_languages[] = {
936 { 0x00, "*" },
937 { 0x01, "Afar (aa)" },
938 { 0x02, "Abkhazian (ab)" },
939 { 0x03, "Afrikaans (af)" },
940 { 0x04, "Amharic (am)" },
941 { 0x05, "Arabic (ar)" },
942 { 0x06, "Assamese (as)" },
943 { 0x07, "Aymara (ay)" },
944 { 0x08, "Azerbaijani (az)" },
945 { 0x09, "Bashkir (ba)" },
946 { 0x0A, "Byelorussian (be)" },
947 { 0x0B, "Bulgarian (bg)" },
948 { 0x0C, "Bihari (bh)" },
949 { 0x0D, "Bislama (bi)" },
950 { 0x0E, "Bengali; Bangla (bn)" },
951 { 0x0F, "Tibetan (bo)" },
952 { 0x10, "Breton (br)" },
953 { 0x11, "Catalan (ca)" },
954 { 0x12, "Corsican (co)" },
955 { 0x13, "Czech (cs)" },
956 { 0x14, "Welsh (cy)" },
957 { 0x15, "Danish (da)" },
958 { 0x16, "German (de)" },
959 { 0x17, "Bhutani (dz)" },
960 { 0x18, "Greek (el)" },
961 { 0x19, "English (en)" },
962 { 0x1A, "Esperanto (eo)" },
963 { 0x1B, "Spanish (es)" },
964 { 0x1C, "Estonian (et)" },
965 { 0x1D, "Basque (eu)" },
966 { 0x1E, "Persian (fa)" },
967 { 0x1F, "Finnish (fi)" },
968 { 0x20, "Fiji (fj)" },
969 { 0x21, "Urdu (ur)" },
970 { 0x22, "French (fr)" },
971 { 0x23, "Uzbek (uz)" },
972 { 0x24, "Irish (ga)" },
973 { 0x25, "Scots Gaelic (gd)" },
974 { 0x26, "Galician (gl)" },
975 { 0x27, "Guarani (gn)" },
976 { 0x28, "Gujarati (gu)" },
977 { 0x29, "Hausa (ha)" },
978 { 0x2A, "Hebrew (formerly iw) (he)" },
979 { 0x2B, "Hindi (hi)" },
980 { 0x2C, "Croatian (hr)" },
981 { 0x2D, "Hungarian (hu)" },
982 { 0x2E, "Armenian (hy)" },
983 { 0x2F, "Vietnamese (vi)" },
984 { 0x30, "Indonesian (formerly in) (id)" },
985 { 0x31, "Wolof (wo)" },
986 { 0x32, "Xhosa (xh)" },
987 { 0x33, "Icelandic (is)" },
988 { 0x34, "Italian (it)" },
989 { 0x35, "Yoruba (yo)" },
990 { 0x36, "Japanese (ja)" },
991 { 0x37, "Javanese (jw)" },
992 { 0x38, "Georgian (ka)" },
993 { 0x39, "Kazakh (kk)" },
994 { 0x3A, "Zhuang (za)" },
995 { 0x3B, "Cambodian (km)" },
996 { 0x3C, "Kannada (kn)" },
997 { 0x3D, "Korean (ko)" },
998 { 0x3E, "Kashmiri (ks)" },
999 { 0x3F, "Kurdish (ku)" },
1000 { 0x40, "Kirghiz (ky)" },
1001 { 0x41, "Chinese (zh)" },
1002 { 0x42, "Lingala (ln)" },
1003 { 0x43, "Laothian (lo)" },
1004 { 0x44, "Lithuanian (lt)" },
1005 { 0x45, "Latvian, Lettish (lv)" },
1006 { 0x46, "Malagasy (mg)" },
1007 { 0x47, "Maori (mi)" },
1008 { 0x48, "Macedonian (mk)" },
1009 { 0x49, "Malayalam (ml)" },
1010 { 0x4A, "Mongolian (mn)" },
1011 { 0x4B, "Moldavian (mo)" },
1012 { 0x4C, "Marathi (mr)" },
1013 { 0x4D, "Malay (ms)" },
1014 { 0x4E, "Maltese (mt)" },
1015 { 0x4F, "Burmese (my)" },
1016 { 0x50, "Ukrainian (uk)" },
1017 { 0x51, "Nepali (ne)" },
1018 { 0x52, "Dutch (nl)" },
1019 { 0x53, "Norwegian (no)" },
1020 { 0x54, "Occitan (oc)" },
1021 { 0x55, "(Afan) Oromo (om)" },
1022 { 0x56, "Oriya (or)" },
1023 { 0x57, "Punjabi (pa)" },
1024 { 0x58, "Polish (po)" },
1025 { 0x59, "Pashto, Pushto (ps)" },
1026 { 0x5A, "Portuguese (pt)" },
1027 { 0x5B, "Quechua (qu)" },
1028 { 0x5C, "Zulu (zu)" },
1029 { 0x5D, "Kirundi (rn)" },
1030 { 0x5E, "Romanian (ro)" },
1031 { 0x5F, "Russian (ru)" },
1032 { 0x60, "Kinyarwanda (rw)" },
1033 { 0x61, "Sanskrit (sa)" },
1034 { 0x62, "Sindhi (sd)" },
1035 { 0x63, "Sangho (sg)" },
1036 { 0x64, "Serbo-Croatian (sh)" },
1037 { 0x65, "Sinhalese (si)" },
1038 { 0x66, "Slovak (sk)" },
1039 { 0x67, "Slovenian (sl)" },
1040 { 0x68, "Samoan (sm)" },
1041 { 0x69, "Shona (sn)" },
1042 { 0x6A, "Somali (so)" },
1043 { 0x6B, "Albanian (sq)" },
1044 { 0x6C, "Serbian (sr)" },
1045 { 0x6D, "Siswati (ss)" },
1046 { 0x6E, "Sesotho (st)" },
1047 { 0x6F, "Sundanese (su)" },
1048 { 0x70, "Swedish (sv)" },
1049 { 0x71, "Swahili (sw)" },
1050 { 0x72, "Tamil (ta)" },
1051 { 0x73, "Telugu (te)" },
1052 { 0x74, "Tajik (tg)" },
1053 { 0x75, "Thai (th)" },
1054 { 0x76, "Tigrinya (ti)" },
1055 { 0x77, "Turkmen (tk)" },
1056 { 0x78, "Tagalog (tl)" },
1057 { 0x79, "Setswana (tn)" },
1058 { 0x7A, "Tonga (to)" },
1059 { 0x7B, "Turkish (tr)" },
1060 { 0x7C, "Tsonga (ts)" },
1061 { 0x7D, "Tatar (tt)" },
1062 { 0x7E, "Twi (tw)" },
1063 { 0x7F, "Uighur (ug)" },
1064 { 0x81, "Nauru (na)" },
1065 { 0x82, "Faeroese (fo)" },
1066 { 0x83, "Frisian (fy)" },
1067 { 0x84, "Interlingua (ia)" },
1068 { 0x85, "Volapuk (vo)" },
1069 { 0x86, "Interlingue (ie)" },
1070 { 0x87, "Inupiak (ik)" },
1071 { 0x88, "Yiddish (formerly ji) (yi)" },
1072 { 0x89, "Inuktitut (iu)" },
1073 { 0x8A, "Greenlandic (kl)" },
1074 { 0x8B, "Latin (la)" },
1075 { 0x8C, "Rhaeto-Romance (rm)" },
1076 { 0x00, NULL }
1078 static value_string_ext vals_languages_ext = VALUE_STRING_EXT_INIT(vals_languages);
1081 #define CACHE_CONTROL_NO_CACHE 0x00
1082 #define CACHE_CONTROL_NO_STORE 0x01
1083 #define CACHE_CONTROL_MAX_AGE 0x02
1084 #define CACHE_CONTROL_MAX_STALE 0x03
1085 #define CACHE_CONTROL_MIN_FRESH 0x04
1086 #define CACHE_CONTROL_ONLY_IF_CACHED 0x05
1087 #define CACHE_CONTROL_PUBLIC 0x06
1088 #define CACHE_CONTROL_PRIVATE 0x07
1089 #define CACHE_CONTROL_NO_TRANSFORM 0x08
1090 #define CACHE_CONTROL_MUST_REVALIDATE 0x09
1091 #define CACHE_CONTROL_PROXY_REVALIDATE 0x0A
1092 #define CACHE_CONTROL_S_MAXAGE 0x0B
1094 static const value_string vals_cache_control[] = {
1095 { CACHE_CONTROL_NO_CACHE, "no-cache" },
1096 { CACHE_CONTROL_NO_STORE, "no-store" },
1097 { CACHE_CONTROL_MAX_AGE, "max-age" },
1098 { CACHE_CONTROL_MAX_STALE, "max-stale" },
1099 { CACHE_CONTROL_MIN_FRESH, "min-fresh" },
1100 { CACHE_CONTROL_ONLY_IF_CACHED, "only-if-cached" },
1101 { CACHE_CONTROL_PUBLIC, "public" },
1102 { CACHE_CONTROL_PRIVATE, "private" },
1103 { CACHE_CONTROL_NO_TRANSFORM, "no-transform" },
1104 { CACHE_CONTROL_MUST_REVALIDATE, "must-revalidate" },
1105 { CACHE_CONTROL_PROXY_REVALIDATE, "proxy-revalidate" },
1106 { CACHE_CONTROL_S_MAXAGE, "s-max-age" },
1108 { 0x00, NULL }
1110 static value_string_ext vals_cache_control_ext = VALUE_STRING_EXT_INIT(vals_cache_control);
1112 static const value_string vals_wap_application_ids[] = {
1113 /* Well-known WAP applications */
1114 { 0x0000, "x-wap-application:*"},
1115 { 0x0001, "x-wap-application:push.sia"},
1116 { 0x0002, "x-wap-application:wml.ua"},
1117 { 0x0003, "x-wap-application:wta.ua"},
1118 { 0x0004, "x-wap-application:mms.ua"},
1119 { 0x0005, "x-wap-application:push.syncml"},
1120 { 0x0006, "x-wap-application:loc.ua"},
1121 { 0x0007, "x-wap-application:syncml.dm"},
1122 { 0x0008, "x-wap-application:drm.ua"},
1123 { 0x0009, "x-wap-application:emn.ua"},
1124 { 0x000A, "x-wap-application:wv.ua"},
1125 { 0x001A, "x-wap-application:lwm2m.dm"},
1126 /* Registered by 3rd parties */
1127 { 0x8000, "x-wap-microsoft:localcontent.ua"},
1128 { 0x8001, "x-wap-microsoft:IMclient.ua"},
1129 { 0x8002, "x-wap-docomo:imode.mail.ua"},
1130 { 0x8003, "x-wap-docomo:imode.mr.ua"},
1131 { 0x8004, "x-wap-docomo:imode.mf.ua"},
1132 { 0x8005, "x-motorola:location.ua"},
1133 { 0x8006, "x-motorola:now.ua"},
1134 { 0x8007, "x-motorola:otaprov.ua"},
1135 { 0x8008, "x-motorola:browser.ua"},
1136 { 0x8009, "x-motorola:splash.ua"},
1137 /* 0x800A: unassigned */
1138 { 0x800B, "x-wap-nai:mvsw.command"},
1139 /* 0x800C -- 0x800F: unassigned */
1140 { 0x8010, "x-wap-openwave:iota.ua"},
1141 /* 0x8011 -- 0x8FFF: unassigned */
1142 { 0x9000, "x-wap-docomo:imode.mail2.ua"},
1143 { 0x9001, "x-oma-nec:otaprov.ua"},
1144 { 0x9002, "x-oma-nokia:call.ua"},
1145 { 0x9003, "x-oma-coremobility:sqa.ua"},
1147 { 0x00, NULL }
1149 static value_string_ext vals_wap_application_ids_ext = VALUE_STRING_EXT_INIT(vals_wap_application_ids);
1152 /* Parameters and well-known encodings */
1153 static const value_string vals_wsp_parameter_sec[] = {
1154 { 0x00, "NETWPIN" },
1155 { 0x01, "USERPIN" },
1156 { 0x02, "USERNETWPIN" },
1157 { 0x03, "USERPINMAC" },
1159 { 0x00, NULL }
1161 static value_string_ext vals_wsp_parameter_sec_ext = VALUE_STRING_EXT_INIT(vals_wsp_parameter_sec);
1163 /* Warning codes and mappings */
1164 static const value_string vals_wsp_warning_code[] = {
1165 { 10, "110 Response is stale" },
1166 { 11, "111 Revalidation failed" },
1167 { 12, "112 Disconnected operation" },
1168 { 13, "113 Heuristic expiration" },
1169 { 14, "214 Transformation applied" },
1170 { 99, "199/299 Miscellaneous warning" },
1172 { 0, NULL }
1174 static value_string_ext vals_wsp_warning_code_ext = VALUE_STRING_EXT_INIT(vals_wsp_warning_code);
1176 static const value_string vals_wsp_warning_code_short[] = {
1177 { 10, "110" },
1178 { 11, "111" },
1179 { 12, "112" },
1180 { 13, "113" },
1181 { 14, "214" },
1182 { 99, "199/299" },
1184 { 0, NULL }
1186 static value_string_ext vals_wsp_warning_code_short_ext = VALUE_STRING_EXT_INIT(vals_wsp_warning_code_short);
1188 /* Profile-Warning codes - see http://www.w3.org/TR/NOTE-CCPPexchange */
1189 static const value_string vals_wsp_profile_warning_code[] = {
1190 { 0x10, "100 OK" },
1191 { 0x11, "101 Used stale profile" },
1192 { 0x12, "102 Not used profile" },
1193 { 0x20, "200 Not applied" },
1194 { 0x21, "101 Content selection applied" },
1195 { 0x22, "202 Content generation applied" },
1196 { 0x23, "203 Transformation applied" },
1198 { 0x00, NULL }
1200 static value_string_ext vals_wsp_profile_warning_code_ext = VALUE_STRING_EXT_INIT(vals_wsp_profile_warning_code);
1202 /* Well-known TE values */
1203 static const value_string vals_well_known_te[] = {
1204 { 0x82, "chunked" },
1205 { 0x83, "identity" },
1206 { 0x84, "gzip" },
1207 { 0x85, "compress" },
1208 { 0x86, "deflate" },
1210 { 0x00, NULL }
1212 static value_string_ext vals_well_known_te_ext = VALUE_STRING_EXT_INIT(vals_well_known_te);
1216 * Redirect flags.
1218 #define PERMANENT_REDIRECT 0x80
1219 #define REUSE_SECURITY_SESSION 0x40
1222 * Redirect address flags and length.
1224 #define BEARER_TYPE_INCLUDED 0x80
1225 #define PORT_NUMBER_INCLUDED 0x40
1226 #define ADDRESS_LEN 0x3f
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 */
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 */
1246 WSP_PDU_POST = 0x60,
1247 WSP_PDU_PUT = 0x61 /* No sample data */
1251 /* Dissector tables for handoff */
1252 static dissector_table_t media_type_table;
1253 static heur_dissector_list_t heur_subdissector_list;
1255 static void add_uri (proto_tree *, packet_info *, tvbuff_t *, unsigned, unsigned, proto_item *);
1257 static void add_post_variable (proto_tree *, tvbuff_t *, unsigned, unsigned, unsigned, unsigned);
1258 static void add_multipart_data (proto_tree *, tvbuff_t *, packet_info *pinfo);
1260 static void add_capabilities (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, uint8_t pdu_type);
1264 * Dissect the WSP header part.
1265 * This function calls wkh_XXX functions that dissect well-known headers.
1267 static void add_headers (proto_tree *tree, tvbuff_t *tvb, int hf, packet_info *pinfo);
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.
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)
1285 #define get_uintvar_integer(val,tvb,start,len,ok) \
1286 val = tvb_get_uintvar(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_uint8(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_uint8(tvb,start); \
1294 ok = true; /* Valid lengths for us are 1-4 */ \
1295 if (len==1) { val = tvb_get_uint8(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_uint8(tvb,start); \
1303 ok = true; \
1304 if (len & 0x80) { val = len & 0x7F; len = 0; } \
1305 else if (len==1) { val = tvb_get_uint8(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)
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_uint8(tvb,start))) { \
1320 str = (char *)tvb_get_stringz_enc(wmem_packet_scope(), tvb,start,(int *)&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)
1334 #define get_version_value(val,str,tvb,start,len,ok) \
1335 val = tvb_get_uint8(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); }
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);
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.
1353 * Define a wkh_XXX() function as follows:
1355 * static uint32_t
1356 * wkh_XXX (proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
1358 * wkh_0_Declarations;
1359 * << add other required declarations here >>
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 >>
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). >>
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.
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.
1387 #define wkh_0a_Declarations /* Declarations for Parsing */ \
1388 bool 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 uint32_t val_start = hdr_start + 1; \
1392 uint8_t val_id = tvb_get_uint8 (tvb, val_start); \
1393 uint32_t offset = val_start; /* Offset to one past this header */ \
1394 uint32_t val_len; /* length for value with length field */ \
1395 uint32_t val_len_len /* length of length field */
1397 #define wkh_0_Declarations \
1398 wkh_0a_Declarations; \
1399 const char *val_str = NULL
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 \
1409 * BEGIN */
1411 #define wkh_2_TextualValue /* Parse Textual Value */ \
1412 /* END */ \
1413 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \
1414 val_str = (char *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (int *)&val_len, ENC_ASCII); \
1415 offset = val_start + val_len; \
1416 /* Textual value processing starts HERE \
1418 * BEGIN */
1420 #define wkh_2_TextualValueInv /* Parse Textual Value */ \
1421 /* END */ \
1422 } else if ((val_id == 0) || (val_id >= 0x20)) { /* Textual value */ \
1423 /*val_str = (char *)*/tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (int *)&val_len, ENC_ASCII); \
1424 offset = val_start + val_len; \
1425 /* Textual value processing starts HERE \
1427 * BEGIN */
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 = uintvar */ \
1433 val_len = tvb_get_uintvar(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_uint8(tvb, offset); \
1437 val_len_len = 1; \
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 */
1449 #define wkh_4_End() /* End of value parsing */ \
1450 /* END */ \
1452 /* Check for errors */ \
1453 if (! ok) { \
1454 expert_add_info(pinfo, header_item, &ei_wsp_header_invalid_value); \
1456 return offset;
1460 * This yields the following default header value parser function body
1462 static uint32_t
1463 wkh_default(proto_tree *tree, tvbuff_t *tvb,
1464 uint32_t hdr_start, packet_info *pinfo _U_)
1466 wkh_0_Declarations;
1467 uint8_t hdr_id = tvb_get_uint8 (tvb, hdr_start) & 0x7F;
1469 ok = true; /* Bypass error checking as we don't parse the values! */
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>"));
1487 wkh_4_End(); /* The default parser has no associated hf_index;
1488 additionally the error code is always bypassed */
1492 /* Content-type processing uses the following common core: */
1493 static uint32_t
1494 wkh_content_type_header(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo, int hf, const char* name)
1496 wkh_0_Declarations;
1497 uint32_t off, val = 0, len;
1498 uint8_t peek;
1499 proto_item *ti = NULL;
1500 proto_tree *parameter_tree = NULL;
1501 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Content type: %s", name);
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);
1520 ok = true;
1521 wkh_3_ValueWithLength;
1522 off = val_start + val_len_len;
1523 peek = tvb_get_uint8(tvb, off);
1524 if (is_text_string(peek)) {
1525 val_str = (char *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, off, (int*)&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)"));
1536 off += len;
1537 } else {
1538 ok = false;
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);
1548 wkh_4_End();
1553 * Accept-value =
1554 * Short-integer
1555 * | Extension-media
1556 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
1558 static uint32_t
1559 wkh_accept(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
1561 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_accept, "Accept");
1566 * Content-type-value =
1567 * Short-integer
1568 * | Extension-media
1569 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
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.
1575 static uint32_t
1576 wkh_content_type(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
1578 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_content_type, "Content-Type");
1583 * Content-type-value =
1584 * Short-integer
1585 * | Extension-media
1586 * | ( Value-length ( Extension-media | Integer-value ) *( Parameter ) )
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).
1592 uint32_t
1593 add_content_type(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, uint32_t val_start,
1594 uint32_t *well_known_content, const char **textual_content)
1596 /* Replace wkh_0_Declarations with slightly modified declarations
1597 * so we can still make use of the wkh_[1-4]_XXX macros! */
1598 uint32_t hdr_start = val_start; /* No header name, only value! */
1599 uint8_t val_id = tvb_get_uint8 (tvb, val_start);
1600 uint32_t offset = val_start; /* Offset to one past this header */
1601 uint32_t val_len; /* length for value with length field */
1602 uint32_t val_len_len; /* length of length field */
1603 char *val_str = NULL;
1604 uint32_t off, val = 0, len;
1605 uint8_t peek;
1606 bool ok = false;
1607 proto_item *ti = NULL;
1608 proto_tree *parameter_tree = NULL;
1609 proto_tree *header_tree;
1610 proto_item *header_item;
1612 *textual_content = NULL;
1613 *well_known_content = 0;
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;
1639 ok = true;
1640 wkh_3_ValueWithLength;
1641 off = val_start + val_len_len;
1642 peek = tvb_get_uint8(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);
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;
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);
1673 wkh_4_End();
1678 * Template for accept_X headers with optional Q parameter value
1680 #define wkh_accept_x_q_header(underscored,Text,valueStringExtAddr,valueName) \
1681 static uint32_t \
1682 wkh_ ## underscored (proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
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>"); \
1689 static uint32_t
1690 wkh_accept_x_q_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t 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);
1694 static uint32_t
1695 wkh_accept_x_q_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo,
1696 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format)
1698 wkh_0_Declarations;
1699 uint32_t off, val = 0, len;
1700 uint8_t peek;
1701 proto_item *ti = NULL;
1702 proto_tree *parameter_tree = NULL;
1703 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Accept X: %s", name);
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_uint8(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);
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));
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);
1739 wkh_4_End();
1743 * Accept-charset-value =
1744 * Short-integer
1745 * | Extension-media
1746 * | ( Value-length ( Token-text | Integer-value ) [ Q-value ] )
1748 wkh_accept_x_q_header(accept_charset, "Accept-Charset",
1749 &mibenum_vals_character_sets_ext, "character set")
1751 * Accept-language-value =
1752 * Short-integer
1753 * | Extension-media
1754 * | ( Value-length ( Text-string | Integer-value ) [ Q-value ] )
1756 wkh_accept_x_q_header(accept_language, "Accept-Language",
1757 &vals_languages_ext, "language")
1761 * Push-flag-value = Short-integer
1763 static uint32_t
1764 wkh_push_flag(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
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(), "");
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;
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_boolean(subtree, hf_hdr_push_flag_auth,
1787 tvb, val_start, 1, val_id);
1788 proto_tree_add_boolean(subtree, hf_hdr_push_flag_trust,
1789 tvb, val_start, 1, val_id);
1790 proto_tree_add_boolean(subtree, hf_hdr_push_flag_last,
1791 tvb, val_start, 1, val_id);
1793 wkh_2_TextualValueInv;
1794 /* Invalid */
1795 wkh_3_ValueWithLength;
1796 /* Invalid */
1797 wkh_4_End();
1802 * Profile-Diff (with WBXML): Profile-diff-value =
1803 * Value-length <WBXML-Content>
1805 static uint32_t wkh_profile_diff_wbxml (proto_tree *tree, tvbuff_t *tvb,
1806 uint32_t hdr_start, packet_info *pinfo)
1808 wkh_0a_Declarations;
1809 tvbuff_t *tmp_tvb;
1810 proto_item *ti = NULL;
1811 proto_tree *subtree;
1813 ok = true; /* Bypass error checking as we don't parse the values! */
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();
1831 * Allow-value =
1832 * Short-integer
1833 1 */
1834 static uint32_t
1835 wkh_allow(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
1837 wkh_0a_Declarations;
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;
1848 wkh_2_TextualValueInv;
1849 /* Invalid */
1850 wkh_3_ValueWithLength;
1851 /* Invalid */
1852 wkh_4_End();
1857 * Public-value =
1858 * Token-text | Short-integer
1859 2 */
1860 static uint32_t
1861 wkh_public(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
1863 wkh_0_Declarations;
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;
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();
1885 * Vary-value =
1886 * Token-text | Short-integer
1888 static uint32_t
1889 wkh_vary(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
1891 wkh_0_Declarations;
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();
1911 * X-wap-security-value = 0x80
1913 static uint32_t
1914 wkh_x_wap_security(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
1916 wkh_0a_Declarations;
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;
1924 wkh_2_TextualValueInv;
1925 /* Invalid */
1926 wkh_3_ValueWithLength;
1927 /* Invalid */
1928 wkh_4_End();
1933 * Connection-value = 0x80 | Token-text
1934 5 */
1935 static uint32_t
1936 wkh_connection(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
1938 wkh_0_Declarations;
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;
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();
1957 * Transfer-encoding-value = 0x80 | Token-text
1959 static uint32_t
1960 wkh_transfer_encoding(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
1962 wkh_0_Declarations;
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;
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();
1981 * Accept-range-value = 0x80 | 0x81 | Token-text
1983 static uint32_t
1984 wkh_accept_ranges(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
1986 wkh_0_Declarations;
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;
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();
2012 * Content-encoding-value = 0x80 | 0x81 | 0x82 | Token-text
2014 static uint32_t
2015 wkh_content_encoding(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
2017 wkh_0_Declarations;
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;
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();
2048 * Accept-encoding-value =
2049 * Short-integer
2050 * | Token-text
2051 * | ( Value-length ( Short-integer | Text-string ) [ Q-value ] )
2053 static uint32_t
2054 wkh_accept_encoding(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
2056 wkh_0_Declarations;
2057 uint32_t len, off;
2058 uint8_t peek;
2059 char *str;
2060 proto_item *ti = NULL;
2061 proto_tree *parameter_tree = NULL;
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;
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_uint8(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;
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);
2123 off += len;
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);
2132 wkh_4_End();
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 )
2145 static uint32_t
2146 wkh_content_disposition(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
2148 wkh_0a_Declarations;
2149 uint32_t len, off;
2150 uint8_t peek;
2151 char *str;
2152 proto_item *ti = NULL;
2153 proto_tree *parameter_tree = NULL;
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_uint8(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;
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);
2187 off += len;
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);
2196 wkh_4_End();
2201 * Common code for headers with only a textual value
2202 * is written in the macro below:
2204 #define wkh_text_header(underscored,Text) \
2205 static uint32_t \
2206 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_) \
2208 return wkh_text_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2211 static uint32_t
2212 wkh_text_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo, int hf, const char* name)
2214 wkh_0_Declarations;
2215 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Header: %s", name);
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();
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")
2247 * Same for quoted-string value
2249 static uint32_t
2250 wkh_content_id(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
2252 wkh_0_Declarations;
2253 char *str;
2254 proto_item *ti = NULL;
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);
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);
2275 ok = true;
2276 wkh_3_ValueWithLength;
2277 /* Invalid */
2278 wkh_4_End();
2283 * Common code for headers with only a textual or a date value
2284 * is written in the macro below:
2286 #define wkh_text_or_date_value_header(underscored,Text) \
2287 static uint32_t \
2288 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
2290 return wkh_text_or_date_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2293 static uint32_t
2294 wkh_text_or_date_value_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo, int hf, const char* name)
2296 wkh_0_Declarations;
2297 uint32_t val = 0, off = val_start, len;
2298 char *str; /* may not be freed! */
2299 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Text or Date: %s", name);
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);
2316 wkh_4_End();
2319 /* If-Range */
2320 wkh_text_or_date_value_header(if_range,"If-Range")
2324 * Common code for headers with only a date value
2325 * is written in the macro below:
2327 #define wkh_date_value_header(underscored,Text) \
2328 static uint32_t \
2329 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
2331 return wkh_date_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2334 static uint32_t
2335 wkh_date_value_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo, int hf, const char* name)
2337 wkh_0a_Declarations;
2338 uint32_t val = 0, off = val_start, len;
2339 char *str; /* may not be freed! */
2340 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Date: %s", name);
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 */
2357 wkh_4_End();
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")
2368 /* Date-value with special interpretation of zero value */
2369 #define wkh_tod_value_header(underscored,Text) \
2370 static uint32_t \
2371 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
2373 return wkh_tod_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2376 static uint32_t
2377 wkh_tod_value_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo, int hf, const char* name)
2379 wkh_0a_Declarations;
2380 uint32_t val = 0, off = val_start, len;
2381 proto_item *ti = NULL;
2382 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Time of Day: %s", name);
2383 nstime_t t;
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;
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);
2417 wkh_4_End();
2420 wkh_tod_value_header(x_wap_tod, "X-Wap-Tod")
2424 * Age-value: Delta-seconds-value
2426 static uint32_t
2427 wkh_age(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
2429 wkh_0_Declarations;
2430 uint32_t val = 0, off = val_start, len;
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);
2449 wkh_4_End();
2454 * Template for Integer lookup or text value headers:
2456 #define wkh_integer_lookup_or_text_value(underscored,Text,valueStringExtAddr,valueName) \
2457 static uint32_t \
2458 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
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>"); \
2465 static uint32_t
2466 wkh_integer_lookup_or_text_value_func(proto_tree *tree, tvbuff_t *tvb, uint32_t 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);
2470 static uint32_t
2471 wkh_integer_lookup_or_text_value_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo,
2472 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_format)
2474 wkh_0_Declarations;
2475 uint32_t off = val_start, len;
2476 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer lookup: %s", name);
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_uint8(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));
2497 wkh_4_End();
2501 * Wap-application-value: Uri-value | Integer-value
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")
2516 * Challenge
2520 * Common code for headers with only a challenge value
2521 * is written in the macro below:
2523 #define wkh_challenge_value_header(underscored,Text) \
2524 static uint32_t \
2525 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
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); \
2532 static uint32_t
2533 wkh_challenge_value_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo,
2534 int hf, int hf_scheme, int hf_realm, const char* name)
2536 wkh_0a_Declarations;
2537 uint8_t peek;
2538 uint32_t off, len;
2539 proto_tree *subtree;
2540 char *str;
2541 proto_item *ti = NULL;
2542 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Challenge: %s", name);
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_uint8(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;*/
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);
2591 wkh_4_End();
2594 /* Challenge-value only headers: */
2595 wkh_challenge_value_header(www_authenticate, "WWW-Authenticate")
2596 wkh_challenge_value_header(proxy_authenticate, "Proxy-Authenticate")
2600 * Credentials
2604 * Common code for headers with only a credentials value
2605 * is written in the macro below:
2607 #define wkh_credentials_value_header(underscored,Text) \
2608 static uint32_t \
2609 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
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); \
2616 static uint32_t
2617 wkh_credentials_value_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo,
2618 int hf, int hf_scheme, int hf_userid, int hf_password, const char* name)
2620 wkh_0a_Declarations;
2621 uint8_t peek;
2622 uint32_t off, len;
2623 proto_tree *subtree;
2624 char *str;
2625 proto_item *ti = NULL;
2626 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Credentials: %s", name);
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_uint8(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;*/
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);
2675 wkh_4_End();
2678 /* Credentials-value only headers: */
2679 wkh_credentials_value_header(authorization, "Authorization")
2680 wkh_credentials_value_header(proxy_authorization, "Proxy-Authorization")
2684 * Content-md5-value = 16*16 OCTET
2686 static uint32_t
2687 wkh_content_md5 (proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
2689 wkh_0a_Declarations;
2690 uint32_t off;
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;
2703 wkh_4_End();
2708 * Pragma-value = 0x80 | Length Parameter
2710 static uint32_t
2711 wkh_pragma(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
2713 wkh_0a_Declarations;
2714 uint32_t off;
2715 proto_item *ti = NULL;
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;
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();
2739 * Integer-value
2741 #define wkh_integer_value_header(underscored,Text) \
2742 static uint32_t \
2743 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
2745 return wkh_integer_value_header_func(tree, tvb, hdr_start, pinfo, hf_hdr_ ## underscored, Text); \
2748 static uint32_t
2749 wkh_integer_value_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo, int hf, const char* name)
2751 wkh_0a_Declarations;
2752 uint32_t val = 0, off = val_start, len;
2753 char *str; /* may not be freed! */
2754 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer-value: %s", name);
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);
2772 wkh_4_End();
2775 wkh_integer_value_header(content_length, "Content-Length")
2776 wkh_integer_value_header(max_forwards, "Max-Forwards")
2779 #define wkh_integer_lookup_value_header(underscored,Text,valueStringExtAddr,valueName) \
2780 static uint32_t \
2781 wkh_ ## underscored(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo) \
2783 return wkh_integer_lookup_value_header_func(tree, tvb, hdr_start, pinfo, \
2784 hf_hdr_ ## underscored, Text,valueStringExtAddr, valueName); \
2787 static uint32_t
2788 wkh_integer_lookup_value_header_func(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo,
2789 int hf, const char* name, value_string_ext *valueStringExtAddr, const char* value_name)
2791 wkh_0_Declarations;
2792 uint32_t off = val_start, len;
2793 char* header_name = wmem_strdup_printf(wmem_packet_scope(), "Integer lookup: %s", name);
2794 char* value_name_str = wmem_strdup_printf(wmem_packet_scope(), "<Unknown %s>", value_name);
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);
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_uint8(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);
2826 wkh_4_End();
2829 wkh_integer_lookup_value_header(bearer_indication, "Bearer-Indication",
2830 &vals_bearer_types_ext, "bearer type")
2834 * Cache-control-value
2836 static uint32_t
2837 wkh_cache_control(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
2839 wkh_0_Declarations;
2840 uint32_t off, len, val = 0;
2841 uint8_t peek, cache_control_directive;
2842 proto_item *ti = NULL;
2843 wmem_strbuf_t *cache_str;
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;
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
2865 off = val_start + val_len_len;
2866 cache_control_directive = tvb_get_uint8(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_uint8(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;
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;
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"));
2907 break;
2909 default:
2910 /* ok = false */
2911 break;
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);
2931 } else { /* Token-text | 0x00 */
2932 /* TODO - check that we have Token-text or 0x00 */
2933 proto_item_append_text(ti, "%s", val_str);
2939 wkh_4_End();
2944 * Warning-value =
2945 * Short-integer
2946 * | ( Value-length Short-integer Text-string Text-string )
2948 static uint32_t
2949 wkh_warning(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
2951 wkh_0_Declarations;
2952 uint32_t off, len, val;
2953 uint8_t warn_code;
2954 char *str;
2955 proto_item *ti = NULL;
2956 proto_tree *subtree;
2958 /* TODO - subtree with values */
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;
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_uint8(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;*/
3005 wkh_4_End();
3010 * Profile-warning-value =
3011 * Short-integer
3012 * | ( Value-length Short-integer Text-string *( Date-value ) )
3014 static uint32_t
3015 wkh_profile_warning(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
3017 wkh_0_Declarations;
3018 uint32_t off, len, val = 0;
3019 uint8_t warn_code;
3020 proto_item *ti = NULL;
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;
3030 wkh_2_TextualValueInv;
3031 /* Invalid */
3032 wkh_3_ValueWithLength;
3033 off = val_start + val_len_len;
3034 warn_code = tvb_get_uint8(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 ws_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));
3058 wkh_4_End();
3062 /* Encoding-version-value =
3063 * Short-integer
3064 * | Text-string
3065 * | Length Short-integer [ Short-integer | text-string ]
3067 static uint32_t wkh_encoding_version (proto_tree *tree, tvbuff_t *tvb,
3068 uint32_t hdr_start, packet_info *pinfo _U_)
3070 wkh_0_Declarations;
3071 proto_item *ti = NULL;
3072 uint32_t off, val, len;
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_uint8(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);
3101 wkh_4_End();
3105 /* Content-range-value =
3106 * Length Uintvar-integer ( 0x80 | Uintvar-integer )
3108 static uint32_t
3109 wkh_content_range(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
3111 wkh_0_Declarations;
3112 uint32_t off, val, len;
3113 proto_item *ti = NULL;
3114 proto_tree *subtree = NULL;
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_uint8(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);
3146 wkh_4_End();
3150 /* Range-value =
3151 * Length
3152 * 0x80 Uintvar-integer [ Uintvar-integer ]
3153 * | 0x81 Uintvar-integer
3155 static uint32_t
3156 wkh_range(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
3158 wkh_0a_Declarations;
3159 uint32_t off, val, len;
3160 proto_item *ti = NULL;
3161 proto_tree *subtree = NULL;
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_uint8(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);
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);
3205 wkh_4_End();
3209 /* TE-value =
3210 * 0x81
3211 * | Value-length (0x82--0x86 | Token-text) [ Q-token Q-value ]
3213 static uint32_t wkh_te (proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
3215 wkh_0_Declarations;
3216 uint32_t off, val, len;
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;
3224 wkh_2_TextualValueInv;
3225 /* Invalid */
3226 wkh_3_ValueWithLength;
3227 off = val_start + val_len_len;
3228 val = tvb_get_uint8(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;
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;
3245 if ((ok) && (off < offset)) { /* Q-token Q-value */
3246 /* TODO */
3249 wkh_4_End();
3253 /****************************************************************************
3254 * O p e n w a v e h e a d e r s
3255 ****************************************************************************/
3258 /* Dissect the Openwave header value (generic) */
3259 static uint32_t
3260 wkh_openwave_default(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo _U_)
3262 wkh_0_Declarations;
3263 uint8_t hdr_id = tvb_get_uint8(tvb, hdr_start) & 0x7F;
3265 ok = true; /* Bypass error checking as we don't parse the values! */
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>"));
3283 wkh_4_End(); /* See wkh_default for explanation */
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")
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")
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")
3340 /* Openwave Time-Of-Day value header */
3341 wkh_tod_value_header(openwave_x_up_proxy_tod,
3342 "x-up-proxy-tod")
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")
3349 /* Openwave content type header */
3350 static uint32_t
3351 wkh_openwave_x_up_proxy_push_accept(proto_tree *tree, tvbuff_t *tvb, uint32_t hdr_start, packet_info *pinfo)
3353 return wkh_content_type_header(tree, tvb, hdr_start, pinfo, hf_hdr_openwave_x_up_proxy_push_accept, "x-up-proxy-push-accept");
3357 static bool parameter_text(proto_tree *tree, tvbuff_t *tvb, int *offset, proto_item *ti, int hf)
3359 char *val_str;
3360 bool ok;
3361 uint32_t val_len;
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;
3370 return ok;
3373 static bool parameter_text_value(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int *offset, proto_item *ti, int hf)
3375 char *val_str, *str;
3376 bool ok;
3377 uint32_t val_len;
3378 proto_item* ti2;
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);
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);
3398 proto_item_append_text(ti, "; %s=%s", proto_registrar_get_name(hf), val_str);
3399 (*offset) += val_len;
3402 return ok;
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)" },
3436 { 0x00, NULL }
3439 static value_string_ext parameter_type_vals_ext = VALUE_STRING_EXT_INIT(parameter_type_vals);
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 )
3450 * Returns: next offset
3452 * TODO - Verify byte highlighting in case of invalid parameter values
3454 static int
3455 parameter (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start, int len)
3457 int offset = start;
3458 uint8_t peek = tvb_get_uint8 (tvb,start);
3459 uint32_t val = 0, type = 0, type_len, val_len;
3460 const char *str = NULL;
3461 const char *val_str = NULL;
3462 bool ok;
3463 proto_item* ti2;
3465 if (is_token_text (peek)) {
3467 * Untyped parameter
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);
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);
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 */
3511 return offset;
3514 * Else: Typed parameter
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 */
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);
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 */
3541 break;
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 */
3555 break;
3557 case 0x05: /* WSP 1.1 encoding - Name: Text-string */
3558 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_name))
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 */
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))
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 */
3572 break;
3574 case 0x06: /* WSP 1.1 encoding - Filename: Text-string */
3575 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_filename))
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 */
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))
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 */
3589 break;
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>
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 */
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 */
3617 break;
3619 case 0x0A: /* WSP 1.2 encoding - Start: Text-string */
3620 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_start))
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 */
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))
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 */
3634 break;
3636 case 0x0B: /* WSP 1.2 encoding - Start-info: Text-string */
3637 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_start_info))
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 */
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))
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 */
3651 break;
3653 case 0x0C: /* WSP 1.3 encoding - Comment: Text-string */
3654 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_comment))
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 */
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))
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 */
3668 break;
3670 case 0x0D: /* WSP 1.3 encoding - Domain: Text-string */
3671 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_domain))
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 */
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))
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 */
3685 break;
3687 case 0x0F: /* WSP 1.3 encoding - Path: Text-string */
3688 if (!parameter_text(tree, tvb, &offset, ti, hf_wsp_parameter_path))
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 */
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))
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 */
3702 break;
3704 case 0x11: /* WSP 1.4 encoding - SEC: Short-integer (OCTET) */
3705 peek = tvb_get_uint8 (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 */
3717 break;
3719 case 0x12: /* WSP 1.4 encoding - MAC: Text-value */
3720 if (!parameter_text_value(tree, pinfo, tvb, &offset, ti, hf_wsp_parameter_mac))
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 */
3726 break;
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 */
3740 break;
3742 case 0x00: /* WSP 1.1 encoding - Q: Q-value */
3743 offset = parameter_value_q(tree, pinfo, ti, tvb, offset);
3744 break;
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 */
3758 break;
3761 * TODO
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;
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;
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;
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;
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;
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;
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;
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;
3812 return offset;
3817 * Dissects the Q-value parameter value.
3819 * Returns: next offset
3821 static int
3822 parameter_value_q (proto_tree *tree, packet_info *pinfo, proto_item *ti, tvbuff_t *tvb, int start)
3824 int offset = start;
3825 uint32_t val = 0, val_len;
3826 char *str = NULL;
3827 uint8_t ok;
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);
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;
3845 return offset;
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
3855 /* Code to actually dissect the packets */
3858 * WSP redirect
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.
3865 static void
3866 dissect_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo,
3867 proto_tree *tree, dissector_handle_t dissector_handle)
3869 proto_item *ti;
3870 proto_tree *addresses_tree;
3871 proto_tree *addr_tree = NULL;
3872 uint8_t bearer_type;
3873 uint8_t address_flags_len;
3874 int address_len;
3875 uint16_t port_num;
3876 uint32_t address_ipv4;
3877 ws_in6_addr address_ipv6;
3878 address redir_address;
3879 conversation_t *conv;
3880 uint32_t idx = 0; /* Address index */
3881 uint32_t 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
3890 * Redirect flags.
3892 proto_tree_add_bitmask(tree, tvb, offset, hf_wsp_redirect_flags, ett_redirect_flags, flags, ENC_NA);
3893 offset++;
3896 * Redirect addresses.
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);
3901 while (tvb_reported_length_remaining (tvb, offset) > 0) {
3902 idx++;
3904 * Read a single address at a time.
3906 address_flags_len = tvb_get_uint8 (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)
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);
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_uint8 (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 */
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 {
3934 * Redirecting to the same server port number as was
3935 * being used, i.e. the source port number of this
3936 * redirect.
3938 port_num = pinfo->srcport;
3940 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
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.)
3947 goto unknown_address_type;
3951 * We know the bearer type, so we know the address type.
3953 switch (bearer_type) {
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:
3971 * IPv4.
3973 if (address_len != 4) {
3975 * Say what?
3977 goto unknown_address_type;
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);
3984 * Create a conversation so that the
3985 * redirected session will be dissected
3986 * as WAP.
3988 redir_address.type = AT_IPv4;
3989 redir_address.len = 4;
3990 redir_address.data = (const uint8_t *)&address_ipv4;
3991 /* Find a conversation based on redir_address and pinfo->dst */
3992 conv = find_conversation(pinfo->num, &redir_address, &pinfo->dst,
3993 CONVERSATION_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, CONVERSATION_UDP, port_num, 0, NO_PORT2);
3998 /* Apply WSP dissection to the conversation */
3999 conversation_set_dissector(conv, dissector_handle);
4000 break;
4002 case BT_IPv6:
4004 * IPv6.
4006 if (address_len != 16) {
4008 * Say what?
4010 goto unknown_address_type;
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);
4017 * Create a conversation so that the
4018 * redirected session will be dissected
4019 * as WAP.
4021 redir_address.type = AT_IPv6;
4022 redir_address.len = 16;
4023 redir_address.data = (const uint8_t *)&address_ipv6;
4024 /* Find a conversation based on redir_address and pinfo->dst */
4025 conv = find_conversation(pinfo->num, &redir_address, &pinfo->dst,
4026 CONVERSATION_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, CONVERSATION_UDP, port_num, 0, NO_PORT2);
4031 /* Apply WSP dissection to the conversation */
4032 conversation_set_dissector(conv, dissector_handle);
4033 break;
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);
4041 break;
4043 offset += address_len;
4044 } /* while */
4047 /* Add addresses to the protocol tree.
4048 * This is a display-only function, so return if tree is NULL
4050 static void
4051 add_addresses(proto_tree *tree, tvbuff_t *tvb, int hf)
4053 proto_item *ti;
4054 proto_tree *addresses_tree;
4055 proto_tree *addr_tree;
4056 uint8_t bearer_type;
4057 uint8_t address_flags_len;
4058 int address_len;
4059 uint32_t tvb_len = tvb_reported_length(tvb);
4060 uint32_t offset = 0;
4061 uint32_t idx = 0; /* Address index */
4062 uint32_t address_record_len; /* Length of the entire address record */
4064 /* Skip needless processing */
4065 if (! tree)
4066 return;
4067 if (offset >= tvb_len)
4068 return;
4071 * Addresses.
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);
4077 while (offset < tvb_len) {
4078 idx++;
4080 * Read a single address at a time.
4082 address_flags_len = tvb_get_uint8 (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)
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);
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_uint8 (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 */
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;
4108 if (!(address_flags_len & BEARER_TYPE_INCLUDED)) {
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.)
4115 goto unknown_address_type;
4119 * We know the bearer type, so we know the address type.
4121 switch (bearer_type) {
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:
4139 * IPv4.
4141 if (address_len != 4) {
4143 * Say what?
4145 goto unknown_address_type;
4147 proto_tree_add_item (addr_tree, hf_address_ipv4_addr,
4148 tvb, offset, 4, ENC_NA);
4149 break;
4151 case BT_IPv6:
4153 * IPv6.
4155 if (address_len != 16) {
4157 * Say what?
4159 goto unknown_address_type;
4161 proto_tree_add_item (addr_tree, hf_address_ipv6_addr,
4162 tvb, offset, 16, ENC_NA);
4163 break;
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);
4171 break;
4173 offset += address_len;
4174 } /* while */
4177 /* Define a pointer to function data type for the well-known header
4178 * lookup table below */
4179 typedef uint32_t (*hdr_parse_func_ptr) (proto_tree *, tvbuff_t *, uint32_t, packet_info *);
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,
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
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 uintvar>
4355 * Followed with: <uintvar 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)>
4360 static void
4361 add_headers (proto_tree *tree, tvbuff_t *tvb, int hf, packet_info *pinfo)
4363 uint8_t hdr_id, val_id, codepage = 1;
4364 int32_t tvb_len = tvb_reported_length(tvb);
4365 int32_t offset = 0;
4366 int32_t save_offset;
4367 int32_t hdr_len, hdr_start;
4368 int32_t val_len, val_start;
4369 char *hdr_str, *val_str;
4370 proto_tree *wsp_headers;
4371 proto_item *ti, *hidden_item;
4372 uint8_t ok;
4373 uint32_t val = 0;
4375 if (offset >= tvb_len)
4376 return; /* No headers! */
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);
4383 while (offset < tvb_len) {
4384 hdr_start = offset;
4385 hdr_id = tvb_get_uint8(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;
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;
4410 } else if (hdr_id == 0x7F) { /* HCP shift sequence */
4411 codepage = tvb_get_uint8(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 = (char *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, hdr_start, (int *)&hdr_len, ENC_ASCII);
4418 val_start = hdr_start + hdr_len;
4419 val_id = tvb_get_uint8(tvb, val_start);
4420 /* Call header value dissector for given header */
4421 if (val_id >= 0x20 && val_id <=0x7E) { /* OK! */
4422 val_str = (char *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, val_start, (int *)&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);
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");
4451 } else {
4452 /* Otherwise, non-textual values are invalid; parse them
4453 * enough to get the value length. */
4454 uint32_t val_len_len; /* length of length field */
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_uintvar(tvb, val_start + 1, &val_len_len, pinfo, &ei_wsp_oversized_uintvar);
4463 val_len += val_len_len; /* count the length itself */
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);
4469 offset = val_start + val_len;
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");
4483 offset = tvb_len;
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 */
4494 { 0x00, NULL }
4498 /* Dissect a Session Initiation Request.
4500 * Arguably this should be a separate dissector, but SIR does not make sense
4501 * outside of WSP anyway.
4503 static int
4504 dissect_sir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4506 uint8_t version;
4507 uint32_t val_len;
4508 uint32_t val_len_save;
4509 uint32_t len;
4510 uint32_t offset = 0;
4511 uint32_t i;
4512 tvbuff_t *tmp_tvb;
4513 proto_tree *subtree;
4514 proto_item *ti;
4516 /* Append status code to INFO column */
4517 col_append_str(pinfo->cinfo, COL_INFO, ": WAP Session Initiation Request");
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);
4523 /* Version */
4524 version = tvb_get_uint8(tvb, 0);
4525 proto_tree_add_uint(subtree, hf_sir_version,
4526 tvb, 0, 1, version);
4528 /* Length of Application-Id headers list */
4529 val_len = tvb_get_uintvar(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;
4538 /* Length of WSP contact points list */
4539 val_len = tvb_get_uintvar(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);
4547 /* End of version 0 SIR content */
4548 if (version == 0)
4549 return offset;
4551 offset += val_len;
4553 /* Length of non-WSP contact points list */
4554 val_len = tvb_get_uintvar(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);
4562 offset += val_len;
4564 /* Number of entries in the Protocol Options list */
4565 val_len = tvb_get_uintvar(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 uintvar */
4572 val_len_save = val_len;
4573 for (i = 0; i < val_len_save; i++) {
4574 val_len = tvb_get_uintvar(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;
4580 /* Length of ProvURL */
4581 val_len = tvb_get_uintvar(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);
4588 offset += val_len;
4590 /* Number of entries in the CPITag list */
4591 val_len = tvb_get_uintvar(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;
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;
4605 return tvb_captured_length(tvb);
4608 static void
4609 dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4610 dissector_handle_t dissector_handle, bool is_connectionless)
4612 int offset = 0;
4614 uint8_t pdut;
4615 unsigned count = 0;
4616 unsigned value = 0;
4617 unsigned uriLength = 0;
4618 unsigned uriStart = 0;
4619 unsigned capabilityLength = 0;
4620 unsigned headersLength = 0;
4621 unsigned headerLength = 0;
4622 unsigned headerStart = 0;
4623 unsigned nextOffset = 0;
4624 unsigned contentTypeStart = 0;
4625 unsigned 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;
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;
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;
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. */
4644 /* Connection-less mode has a TID first */
4645 if (is_connectionless)
4647 offset++; /* Skip the 1-byte Transaction ID */
4650 /* Find the PDU type */
4651 pdut = tvb_get_uint8 (tvb, offset);
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);
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);
4664 /* Add common items: only TID and PDU Type */
4666 /* If this is connectionless, then the TID Field is always first */
4667 if (is_connectionless)
4669 proto_tree_add_item (wsp_tree, hf_wsp_header_tid,
4670 tvb, 0, 1, ENC_LITTLE_ENDIAN);
4672 proto_tree_add_item( wsp_tree, hf_wsp_header_pdu_type,
4673 tvb, offset, 1, ENC_LITTLE_ENDIAN);
4674 offset++;
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;
4683 switch (pdut)
4685 case WSP_PDU_CONNECT:
4686 case WSP_PDU_CONNECTREPLY:
4687 case WSP_PDU_RESUME:
4688 if (pdut == WSP_PDU_CONNECT)
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);
4695 uint8_t ver = tvb_get_uint8(tvb, offset);
4696 proto_item_append_text(proto_ti, ", Version: %u.%u",
4697 ver >> 4, ver & 0x0F);
4699 offset++;
4700 } else {
4701 count = 0; /* Initialise count */
4702 value = tvb_get_uintvar (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;
4709 count = 0; /* Initialise count */
4710 capabilityLength = tvb_get_uintvar (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))
4716 expert_add_info(pinfo, ti, &ei_wsp_capability_length_invalid);
4717 break;
4720 if (pdut != WSP_PDU_RESUME)
4722 count = 0; /* Initialise count */
4723 headerLength = tvb_get_uintvar (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;
4728 } else {
4729 /* Resume computes the headerlength
4730 * by remaining bytes */
4731 headerStart = offset + capabilityLength;
4732 headerLength = tvb_reported_length_remaining (tvb,
4733 headerStart);
4735 if (capabilityLength > 0)
4737 tmp_tvb = tvb_new_subset_length (tvb, offset,
4738 capabilityLength);
4739 add_capabilities (wsp_tree, pinfo, tmp_tvb, pdut);
4740 offset += capabilityLength;
4743 if (headerLength > 0)
4745 tmp_tvb = tvb_new_subset_length (tvb, offset,
4746 headerLength);
4747 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4750 break;
4752 case WSP_PDU_REDIRECT:
4753 dissect_redirect(tvb, offset, pinfo, wsp_tree, dissector_handle);
4754 break;
4756 case WSP_PDU_DISCONNECT:
4757 case WSP_PDU_SUSPEND:
4758 count = 0; /* Initialise count */
4759 value = tvb_get_uintvar (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;
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_uintvar (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;
4781 case WSP_PDU_POST:
4782 case WSP_PDU_PUT:
4783 uriStart = offset;
4784 count = 0; /* Initialise count */
4785 uriLength = tvb_get_uintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4786 headerStart = uriStart+count;
4787 count = 0; /* Initialise count */
4788 headersLength = tvb_get_uintvar (tvb, headerStart, &count, pinfo, &ei_wsp_oversized_uintvar);
4789 offset = headerStart + count;
4791 add_uri (wsp_tree, pinfo, tvb, uriStart, offset, proto_ti);
4792 offset += uriLength;
4794 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4795 tvb, headerStart, count, headersLength);
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;
4802 contentTypeStart = offset;
4803 nextOffset = add_content_type (wsp_tree, pinfo,
4804 tvb, offset, &contentType, &contentTypeStr);
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);
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)
4821 tmp_tvb = tvb_new_subset_length (tvb, nextOffset,
4822 headerLength);
4823 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4825 /* XXX - offset is no longer used after this point */
4826 /* offset = nextOffset+headerLength; */
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)
4833 tmp_tvb = tvb_new_subset_remaining (tvb,
4834 headerStart + count + uriLength + headersLength);
4836 * Try finding a dissector for the content
4837 * first, then fallback.
4839 found_match = 0;
4840 if (contentTypeStr) {
4842 * Content type is a string.
4844 found_match = dissector_try_string_with_data(media_type_table,
4845 contentTypeStr, tmp_tvb, pinfo, tree, true, NULL);
4847 if (! found_match) {
4848 if (! dissector_try_heuristic(heur_subdissector_list,
4849 tmp_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
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
4860 break;
4862 case WSP_PDU_REPLY:
4863 count = 0; /* Initialise count */
4864 headersLength = tvb_get_uintvar (tvb, offset+1, &count, pinfo, &ei_wsp_oversized_uintvar);
4865 headerStart = offset + count + 1;
4867 uint8_t reply_status = tvb_get_uint8(tvb, offset);
4868 const char *reply_status_str;
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);
4876 stat_info->status_code = (int) 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);
4882 nextOffset = offset + 1 + count;
4883 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4884 tvb, offset + 1, count, headersLength);
4886 if (headersLength == 0)
4887 break;
4889 contentTypeStart = nextOffset;
4890 nextOffset = add_content_type (wsp_tree, pinfo, tvb,
4891 nextOffset, &contentType, &contentTypeStr);
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);
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)
4908 tmp_tvb = tvb_new_subset_length (tvb, nextOffset,
4909 headerLength);
4910 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4912 /* XXX - offset is no longer used after this point */
4913 /* offset += count+headersLength+1;*/
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)
4920 tmp_tvb = tvb_new_subset_remaining (tvb, headerStart + headersLength);
4922 * Try finding a dissector for the content
4923 * first, then fallback.
4925 found_match = 0;
4926 if (contentTypeStr) {
4928 * Content type is a string.
4930 found_match = dissector_try_string_with_data(media_type_table,
4931 contentTypeStr, tmp_tvb, pinfo, tree, true, NULL);
4933 if (! found_match) {
4934 if (! dissector_try_heuristic(heur_subdissector_list,
4935 tmp_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
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
4946 break;
4948 case WSP_PDU_PUSH:
4949 case WSP_PDU_CONFIRMEDPUSH:
4950 count = 0; /* Initialise count */
4951 headersLength = tvb_get_uintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
4952 headerStart = offset + count;
4954 proto_tree_add_uint (wsp_tree, hf_wsp_header_length,
4955 tvb, offset, count, headersLength);
4957 if (headersLength == 0)
4958 break;
4960 offset += count;
4961 contentTypeStart = offset;
4962 nextOffset = add_content_type (wsp_tree, pinfo,
4963 tvb, offset, &contentType, &contentTypeStr);
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);
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)
4980 tmp_tvb = tvb_new_subset_length (tvb, nextOffset,
4981 headerLength);
4982 add_headers (wsp_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
4984 /* XXX - offset is no longer used after this point */
4985 /*offset += headersLength;*/
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)
4992 tmp_tvb = tvb_new_subset_remaining (tvb, headerStart + headersLength);
4994 * Try finding a dissector for the content
4995 * first, then fallback.
4997 found_match = 0;
4998 if (contentTypeStr) {
5000 * Content type is a string.
5003 if (g_ascii_strcasecmp(contentTypeStr, "application/vnd.wap.sia") == 0) {
5004 dissect_sir(tree, tmp_tvb);
5005 } else
5007 found_match = dissector_try_string_with_data(media_type_table,
5008 contentTypeStr, tmp_tvb, pinfo, tree, true, NULL);
5010 if (! found_match){
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
5017 if (tvb_get_uint8(tvb, headerStart + headerLength - 1) == 0xAF && /* x-wap app id */
5018 tvb_get_uint8(tvb, headerStart + headerLength) == 0x9A) { /* x-wap app lwm2m.dm */
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)) {
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
5033 break;
5036 stat_info->pdut = pdut;
5037 tap_queue_packet (wsp_tap, pinfo, stat_info);
5042 * Called directly from UDP.
5043 * Put "WSP" into the "Protocol" column.
5045 static int
5046 dissect_wsp_fromudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5048 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSP");
5049 col_clear(pinfo->cinfo, COL_INFO);
5051 dissect_wsp_common(tvb, pinfo, tree, wsp_fromudp_handle, true);
5052 return tvb_captured_length(tvb);
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.
5061 static int
5062 dissect_wsp_fromwap_co(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5065 * XXX - what about WTLS->WTP->WSP?
5067 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, false);
5068 return tvb_captured_length(tvb);
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.
5077 static int
5078 dissect_wsp_fromwap_cl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5081 * XXX - what about WTLS->WSP?
5083 col_clear(pinfo->cinfo, COL_INFO);
5084 dissect_wsp_common(tvb, pinfo, tree, wtp_fromudp_handle, true);
5085 return tvb_captured_length(tvb);
5089 static void
5090 add_uri (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
5091 unsigned URILenOffset, unsigned URIOffset, proto_item *proto_ti)
5093 unsigned count = 0;
5094 unsigned uriLen = tvb_get_uintvar (tvb, URILenOffset, &count, pinfo, &ei_wsp_oversized_uintvar);
5095 char *str;
5097 proto_tree_add_uint (tree, hf_wsp_header_uri_len,
5098 tvb, URILenOffset, count, uriLen);
5100 proto_tree_add_item (tree, hf_wsp_header_uri,
5101 tvb, URIOffset, uriLen, ENC_ASCII);
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!
5107 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", str);
5109 if (proto_ti)
5110 proto_item_append_text(proto_ti, ", URI: %s", str);
5115 * CO-WSP capability negotiation
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
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 }
5145 static void
5146 add_capabilities (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, uint8_t pdu_type)
5148 proto_tree *wsp_capabilities, *cap_subtree, *cap_subtree2;
5149 proto_item *ti, *cap_item, *cap_item2;
5151 char *capaName, *str;
5152 uint32_t offset = 0;
5153 uint32_t len = 0;
5154 uint32_t capaStart = 0; /* Start offset of the capability */
5155 uint32_t capaLen = 0; /* Length of the entire capability */
5156 uint32_t capaValueLen = 0; /* Length of the capability value & type */
5157 uint32_t tvb_len = tvb_reported_length(tvb);
5158 bool ok = false;
5159 uint8_t peek;
5160 uint32_t value;
5162 if (tvb_len == 0) {
5163 return;
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);
5170 while (offset < tvb_len) {
5172 * WSP capabilities consist of:
5173 * - a uint32_t length field,
5174 * - a capability identifier as Token-text or Short-integer,
5175 * - a capability-specific sequence of <length> octets.
5177 capaStart = offset;
5179 * Now Offset points to the 1st byte of a capability field.
5180 * Get the length of the capability field
5182 capaValueLen = tvb_get_uintvar(tvb, offset, &len, pinfo, &ei_wsp_oversized_uintvar);
5183 if (len == 0)
5184 return;
5185 capaLen = capaValueLen + len;
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;
5192 * Now offset points to the 1st byte of the capability type.
5193 * Get the capability identifier.
5195 peek = tvb_get_uint8(tvb, offset);
5196 if (is_token_text(peek)) { /* Literal capability name */
5197 /* 1. Get the string from the tvb */
5198 capaName = (char *)tvb_get_stringz_enc(wmem_packet_scope(), tvb, capaStart, (int *)&len, ENC_ASCII);
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;
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;
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. */
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_uintvar(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_uintvar(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:
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.
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
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);
5277 else
5280 * The WSP spec foresees that this bit field can be
5281 * extended in the future. This does not make sense yet.
5283 proto_item_append_text(cap_item,
5284 " <warning: bit field too large>");
5285 offset = capaStart + capaLen;
5286 continue;
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) }
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++;
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;
5311 proto_item_append_text(ti, " = %s", str);
5312 proto_item_set_len(ti, len+1);
5313 offset += len;
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++;
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) }
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++;
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;
5338 proto_item_append_text(ti, " = %s", str);
5339 proto_item_set_len(ti, len+1);
5340 offset += len;
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++;
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_uintvar(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_uintvar(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;
5369 offset = capaStart + capaLen;
5373 void
5374 add_post_data (proto_tree *tree, tvbuff_t *tvb, unsigned contentType,
5375 const char *contentTypeStr, packet_info *pinfo)
5377 unsigned offset = 0;
5378 unsigned variableStart = 0;
5379 unsigned variableEnd = 0;
5380 unsigned valueStart = 0;
5381 uint8_t peek = 0;
5382 proto_item *ti;
5383 proto_tree *sub_tree;
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);
5389 if ( (contentTypeStr == NULL && contentType == 0x12)
5390 || (contentTypeStr && (g_ascii_strcasecmp(contentTypeStr,
5391 "application/x-www-form-urlencoded") == 0)) )
5394 * URL Encoded data.
5395 * Iterate through post data.
5397 for (offset = 0; offset < tvb_reported_length (tvb); offset++)
5399 peek = tvb_get_uint8 (tvb, offset);
5400 if (peek == '=')
5402 variableEnd = offset;
5403 valueStart = offset+1;
5405 else if (peek == '&')
5407 if (variableEnd > 0)
5409 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5411 variableStart = offset+1;
5412 variableEnd = 0;
5413 valueStart = 0;
5417 /* See if there's outstanding data */
5418 if (variableEnd > 0)
5420 add_post_variable (sub_tree, tvb, variableStart, variableEnd, valueStart, offset);
5423 else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x24) ||
5424 (contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33))
5426 /* add_multipart_data takes also care of subdissection */
5427 add_multipart_data(sub_tree, tvb, pinfo);
5431 static void
5432 add_post_variable (proto_tree *tree, tvbuff_t *tvb, unsigned variableStart, unsigned variableEnd, unsigned valueStart, unsigned valueEnd)
5434 int variableLength = variableEnd-variableStart;
5435 int valueLength = 0;
5436 char *variableBuffer;
5437 char *valueBuffer;
5439 variableBuffer = tvb_get_string_enc(wmem_packet_scope(), tvb, variableStart, variableLength, ENC_ASCII);
5441 if (valueEnd < valueStart)
5443 valueBuffer = (char *)wmem_alloc(wmem_packet_scope(), 1);
5444 valueBuffer[0] = 0;
5445 valueEnd = valueStart;
5447 else
5449 valueLength = valueEnd-valueStart;
5450 valueBuffer = tvb_get_string_enc(wmem_packet_scope(), tvb, valueStart, valueLength, ENC_ASCII);
5453 /* Check for variables with no value */
5454 if (valueStart >= tvb_reported_length (tvb))
5456 valueStart = tvb_reported_length (tvb);
5457 valueEnd = valueStart;
5459 valueLength = valueEnd-valueStart;
5461 proto_tree_add_string_format(tree, hf_wsp_variable_value, tvb, variableStart, valueLength, valueBuffer, "%s: %s", variableBuffer, valueBuffer);
5465 static void
5466 add_multipart_data (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo)
5468 int offset = 0;
5469 unsigned nextOffset;
5470 unsigned nEntries = 0;
5471 unsigned count;
5472 unsigned HeadersLen;
5473 unsigned DataLen;
5474 unsigned contentType = 0;
5475 const char *contentTypeStr;
5476 tvbuff_t *tmp_tvb;
5477 int partnr = 1;
5478 int part_start;
5479 int found_match = 0;
5481 proto_item *sub_tree = NULL;
5482 proto_item *ti = NULL;
5483 proto_tree *mpart_tree = NULL;
5485 heur_dtbl_entry_t *hdtbl_entry;
5487 nEntries = tvb_get_uintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
5488 offset += count;
5489 if (nEntries)
5491 sub_tree = proto_tree_add_subtree(tree, tvb, offset - count, 0,
5492 ett_mpartlist, NULL, "Multipart body");
5494 while (nEntries--)
5496 part_start = offset;
5497 HeadersLen = tvb_get_uintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
5498 offset += count;
5499 DataLen = tvb_get_uintvar (tvb, offset, &count, pinfo, &ei_wsp_oversized_uintvar);
5500 offset += count;
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);
5506 nextOffset = add_content_type (mpart_tree, pinfo, tvb, offset,
5507 &contentType, &contentTypeStr);
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);
5516 HeadersLen -= (nextOffset - offset);
5517 if (HeadersLen > 0)
5519 tmp_tvb = tvb_new_subset_length (tvb, nextOffset, HeadersLen);
5520 add_headers (mpart_tree, tmp_tvb, hf_wsp_headers_section, pinfo);
5522 offset = nextOffset + HeadersLen;
5524 * Try the dissectors of the multipart content.
5526 * TODO - handle nested multipart documents.
5528 tmp_tvb = tvb_new_subset_length(tvb, offset, DataLen);
5530 * Try finding a dissector for the content
5531 * first, then fallback.
5533 found_match = 0;
5534 if (contentTypeStr) {
5536 * Content type is a string.
5538 found_match = dissector_try_string_with_data(media_type_table,
5539 contentTypeStr, tmp_tvb, pinfo, mpart_tree, true, NULL);
5541 if (! found_match) {
5542 if (! dissector_try_heuristic(heur_subdissector_list,
5543 tmp_tvb, pinfo, mpart_tree, &hdtbl_entry, NULL)) {
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
5554 offset += DataLen;
5555 partnr++;
5559 /* TAP STAT INFO */
5560 typedef enum
5562 MESSAGE_TYPE_COLUMN = 0,
5563 PACKET_COLUMN
5564 } wsp_stat_columns;
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"}
5571 static int unknown_pt_idx;
5572 static int unknown_sc_idx;
5574 static void wsp_stat_init(stat_tap_table_ui* new_stat)
5576 const char *pt_table_name = "PDU Types";
5577 const char *sc_table_name = "Status Codes";
5578 int num_fields = array_length(wsp_stat_fields);
5579 stat_tap_table *pt_table;
5580 stat_tap_table_item_type pt_items[array_length(wsp_stat_fields)];
5581 stat_tap_table *sc_table;
5582 stat_tap_table_item_type sc_items[array_length(wsp_stat_fields)];
5583 int table_idx;
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);
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);
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)
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;
5605 stat_tap_init_table_row(pt_table, table_idx, num_fields, pt_items);
5606 table_idx++;
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;
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);
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);
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)
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;
5634 stat_tap_init_table_row(sc_table, table_idx, num_fields, sc_items);
5635 table_idx++;
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;
5644 static tap_packet_status
5645 wsp_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *wiv_ptr, tap_flags_t flags _U_)
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 unsigned element;
5651 stat_tap_table_item_type* item_data;
5652 bool found;
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);
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;
5665 if (!found) {
5666 element = unknown_pt_idx;
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);
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;
5681 if (!found) {
5682 element = unknown_sc_idx;
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);
5689 return found? TAP_PACKET_REDRAW : TAP_PACKET_DONT_REDRAW;
5692 static void
5693 wsp_stat_reset(stat_tap_table* table)
5695 unsigned element;
5696 stat_tap_table_item_type* item_data;
5698 for (element = 0; element < table->num_elements; element++)
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);
5706 static void
5707 wsp_stat_free_table_item(stat_tap_table* table _U_, unsigned row _U_, unsigned column, stat_tap_table_item_type* field_data)
5709 if (column != MESSAGE_TYPE_COLUMN) return;
5710 g_free((char*)field_data->value.string_value);
5711 field_data->value.string_value = NULL;
5714 /* Register the protocol with Wireshark */
5715 void
5716 proto_register_wsp(void)
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, 0x0,
5725 "WSP Transaction ID (for connectionless WSP)", HFILL
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
5735 { &hf_wsp_version_major,
5736 { "Version (Major)",
5737 "wsp.version.major",
5738 FT_UINT8, BASE_DEC, NULL, 0xF0,
5739 NULL, HFILL
5742 { &hf_wsp_version_minor,
5743 { "Version (Minor)",
5744 "wsp.version.minor",
5745 FT_UINT8, BASE_DEC, NULL, 0x0F,
5746 NULL, HFILL
5749 { &hf_capabilities_length,
5750 { "Capabilities Length",
5751 "wsp.capabilities.length",
5752 FT_UINT32, BASE_DEC, NULL, 0x0,
5753 "Length of Capabilities field (bytes)", HFILL
5756 { &hf_wsp_header_length,
5757 { "Headers Length",
5758 "wsp.headers_length",
5759 FT_UINT32, BASE_DEC, NULL, 0x0,
5760 "Length of Headers field (bytes)", HFILL
5763 { &hf_capabilities_section,
5764 { "Capabilities",
5765 "wsp.capabilities",
5766 FT_NONE, BASE_NONE, NULL, 0x0,
5767 NULL, HFILL
5770 { &hf_wsp_headers_section,
5771 { "Headers",
5772 "wsp.headers",
5773 FT_NONE, BASE_NONE, NULL, 0x0,
5774 NULL, HFILL
5777 { &hf_wsp_header_uri_len,
5778 { "URI Length",
5779 "wsp.uri_length",
5780 FT_UINT32, BASE_DEC, NULL, 0x0,
5781 "Length of URI field", HFILL
5784 { &hf_wsp_header_uri,
5785 { "URI",
5786 "wsp.uri",
5787 FT_STRING, BASE_NONE, NULL, 0x0,
5788 NULL, HFILL
5791 { &hf_wsp_server_session_id,
5792 { "Server Session ID",
5793 "wsp.server.session_id",
5794 FT_UINT32, BASE_DEC, NULL, 0x0,
5795 NULL, HFILL
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
5805 { &hf_wsp_parameter_untype_quote_text,
5806 { "Untyped quoted text",
5807 "wsp.untype.quote_text",
5808 FT_STRING, BASE_NONE, NULL, 0x0,
5809 NULL, HFILL
5812 { &hf_wsp_parameter_untype_text,
5813 { "Untyped text",
5814 "wsp.untype.text",
5815 FT_STRING, BASE_NONE, NULL, 0x0,
5816 NULL, HFILL
5819 { &hf_wsp_parameter_untype_int,
5820 { "Untyped integer",
5821 "wsp.untype.int",
5822 FT_UINT32, BASE_DEC, NULL, 0x0,
5823 NULL, HFILL
5826 { &hf_wsp_parameter_type,
5827 { "Parameter Type",
5828 "wsp.parameter.type",
5829 FT_UINT32, BASE_DEC|BASE_EXT_STRING, &parameter_type_vals_ext, 0x00,
5830 NULL, HFILL
5833 { &hf_wsp_parameter_int_type,
5834 { "Integer Type",
5835 "wsp.parameter.int_type",
5836 FT_UINT32, BASE_DEC, NULL, 0x0,
5837 "Type parameter", HFILL
5840 { &hf_wsp_parameter_name,
5841 { "Name",
5842 "wsp.parameter.name",
5843 FT_STRING, BASE_NONE, NULL, 0x0,
5844 "Name parameter", HFILL
5847 { &hf_wsp_parameter_filename,
5848 { "Filename",
5849 "wsp.parameter.filename",
5850 FT_STRING, BASE_NONE, NULL, 0x0,
5851 "Filename parameter", HFILL
5854 { &hf_wsp_parameter_start,
5855 { "Start",
5856 "wsp.parameter.start",
5857 FT_STRING, BASE_NONE, NULL, 0x0,
5858 "Start parameter", HFILL
5861 { &hf_wsp_parameter_start_info,
5862 { "Start-info",
5863 "wsp.parameter.start_info",
5864 FT_STRING, BASE_NONE, NULL, 0x0,
5865 "Start-info parameter", HFILL
5868 { &hf_wsp_parameter_comment,
5869 { "Comment",
5870 "wsp.parameter.comment",
5871 FT_STRING, BASE_NONE, NULL, 0x0,
5872 "Comment parameter", HFILL
5875 { &hf_wsp_parameter_domain,
5876 { "Domain",
5877 "wsp.parameter.domain",
5878 FT_STRING, BASE_NONE, NULL, 0x0,
5879 "Domain parameter", HFILL
5882 { &hf_wsp_parameter_path,
5883 { "Path",
5884 "wsp.parameter.path",
5885 FT_STRING, BASE_NONE, NULL, 0x0,
5886 "Path parameter", HFILL
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
5896 { &hf_wsp_parameter_mac,
5897 { "MAC",
5898 "wsp.parameter.mac",
5899 FT_STRING, BASE_NONE, NULL, 0x0,
5900 "MAC parameter (Content-Type: application/vnd.wap.connectivity-wbxml)", HFILL
5903 { &hf_wsp_parameter_upart_type,
5904 { "Type",
5905 "wsp.parameter.upart.type",
5906 FT_STRING, BASE_NONE, NULL, 0x0,
5907 "Multipart type parameter", HFILL
5910 { &hf_wsp_parameter_level,
5911 { "Level",
5912 "wsp.parameter.level",
5913 FT_STRING, BASE_NONE, NULL, 0x0,
5914 "Level parameter", HFILL
5917 { &hf_wsp_parameter_size,
5918 { "Size",
5919 "wsp.parameter.size",
5920 FT_UINT32, BASE_DEC, NULL, 0x0,
5921 "Size parameter", HFILL
5924 #if 0
5925 { &hf_wsp_reply_data,
5926 { "Data",
5927 "wsp.reply.data",
5928 FT_NONE, BASE_NONE, NULL, 0x0,
5929 NULL, HFILL
5932 #endif
5933 { &hf_wsp_header_shift_code,
5934 { "Switching to WSP header code-page",
5935 "wsp.code_page",
5936 FT_UINT16, BASE_DEC, NULL, 0x0,
5937 "Header code-page shift code", HFILL
5941 * CO-WSP capability negotiation
5943 { &hf_capa_client_sdu_size,
5944 { "Client SDU Size",
5945 "wsp.capability.client_sdu_size",
5946 FT_UINT8, BASE_DEC, NULL, 0x0,
5947 "Client Service Data Unit size (bytes)", HFILL
5950 { &hf_capa_server_sdu_size,
5951 { "Server SDU Size",
5952 "wsp.capability.server_sdu_size",
5953 FT_UINT8, BASE_DEC, NULL, 0x0,
5954 "Server Service Data Unit size (bytes)", HFILL
5957 { &hf_capa_protocol_options,
5958 { "Protocol Options",
5959 "wsp.capability.protocol_opt",
5960 FT_UINT8, BASE_HEX, NULL, 0x0,
5961 NULL, HFILL
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
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
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
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
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
5999 { &hf_capa_method_mor,
6000 { "Method MOR",
6001 "wsp.capability.method_mor",
6002 FT_UINT8, BASE_DEC, NULL, 0x0,
6003 NULL, HFILL
6006 { &hf_capa_push_mor,
6007 { "Push MOR",
6008 "wsp.capability.push_mor",
6009 FT_UINT8, BASE_DEC, NULL, 0x0,
6010 NULL, HFILL
6013 { &hf_capa_extended_method,
6014 { "Extended Method",
6015 "wsp.capability.extended_method",
6016 FT_UINT8, BASE_HEX, NULL, 0x0,
6017 NULL, HFILL
6020 { &hf_capa_header_code_page,
6021 { "Header Code Page",
6022 "wsp.capability.code_page",
6023 FT_UINT8, BASE_HEX, NULL, 0x0,
6024 NULL, HFILL
6027 { &hf_capa_aliases,
6028 { "Aliases",
6029 "wsp.capability.aliases",
6030 FT_BYTES, BASE_NONE, NULL, 0x0,
6031 NULL, HFILL
6034 { &hf_capa_client_message_size,
6035 { "Client Message Size",
6036 "wsp.capability.client_message_size",
6037 FT_UINT8, BASE_DEC, NULL, 0x0,
6038 "Client Message size (bytes)", HFILL
6041 { &hf_capa_server_message_size,
6042 { "Server Message Size",
6043 "wsp.capability.server_message_size",
6044 FT_UINT8, BASE_DEC, NULL, 0x0,
6045 "Server Message size (bytes)", HFILL
6048 { &hf_wsp_post_data,
6049 { "Data (Post)",
6050 "wsp.post.data",
6051 FT_NONE, BASE_NONE, NULL, 0x0,
6052 "Post Data", HFILL
6055 #if 0
6056 { &hf_wsp_push_data,
6057 { "Push Data",
6058 "wsp.push.data",
6059 FT_NONE, BASE_NONE, NULL, 0x0,
6060 NULL, HFILL
6063 { &hf_wsp_multipart_data,
6064 { "Data in this part",
6065 "wsp.multipart.data",
6066 FT_NONE, BASE_NONE, NULL, 0x0,
6067 "The data of 1 MIME-multipart part.", HFILL
6070 #endif
6071 { &hf_wsp_mpart,
6072 { "Part",
6073 "wsp.multipart",
6074 FT_UINT32, BASE_DEC, NULL, 0x0,
6075 "MIME part of multipart data.", HFILL
6078 { &hf_wsp_header_text_value,
6079 { "Header textual value",
6080 "wsp.header_text_value",
6081 FT_STRING, BASE_NONE, NULL, 0x0,
6082 NULL, HFILL
6085 { &hf_wsp_variable_value,
6086 { "Variable value",
6087 "wsp.variable_value",
6088 FT_STRING, BASE_NONE, NULL, 0x0,
6089 NULL, HFILL
6092 { &hf_wsp_default_int,
6093 { "Default integer",
6094 "wsp.default_int",
6095 FT_UINT32, BASE_DEC, NULL, 0x0,
6096 NULL, HFILL
6099 { &hf_wsp_default_string,
6100 { "Default string value",
6101 "wsp.default_string",
6102 FT_STRING, BASE_NONE, NULL, 0x0,
6103 NULL, HFILL
6106 { &hf_wsp_default_val_len,
6107 { "Default value len",
6108 "wsp.default_val_len",
6109 FT_UINT32, BASE_DEC, NULL, 0x0,
6110 NULL, HFILL
6113 { &hf_wsp_redirect_flags,
6114 { "Flags",
6115 "wsp.redirect.flags",
6116 FT_UINT8, BASE_HEX, NULL, 0x0,
6117 "Redirect Flags", HFILL
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
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
6134 { &hf_redirect_addresses,
6135 { "Redirect Addresses",
6136 "wsp.redirect.addresses",
6137 FT_NONE, BASE_NONE, NULL, 0x0,
6138 "List of Redirect Addresses", HFILL
6143 * Addresses
6145 { &hf_address_entry,
6146 { "Address Record",
6147 "wsp.address",
6148 FT_UINT32, BASE_DEC, NULL, 0x0,
6149 NULL, HFILL
6152 { &hf_address_flags_length,
6153 { "Flags/Length",
6154 "wsp.address.flags",
6155 FT_UINT8, BASE_HEX, NULL, 0x0,
6156 "Address Flags/Length", HFILL
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
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
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
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
6187 { &hf_address_port_num,
6188 { "Port Number",
6189 "wsp.address.port",
6190 FT_UINT16, BASE_DEC, NULL, 0x0,
6191 NULL, HFILL
6194 { &hf_address_ipv4_addr,
6195 { "IPv4 Address",
6196 "wsp.address.ipv4",
6197 FT_IPv4, BASE_NONE, NULL, 0x0,
6198 "Address (IPv4)", HFILL
6201 { &hf_address_ipv6_addr,
6202 { "IPv6 Address",
6203 "wsp.address.ipv6",
6204 FT_IPv6, BASE_NONE, NULL, 0x0,
6205 "Address (IPv6)", HFILL
6208 { &hf_address_addr,
6209 { "Address",
6210 "wsp.address.unknown",
6211 FT_BYTES, BASE_NONE, NULL, 0x0,
6212 "Address (unknown)", HFILL
6218 * New WSP header fields
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
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
6237 /* WSP headers start here */
6238 { &hf_hdr_accept,
6239 { "Accept",
6240 "wsp.header.accept",
6241 FT_STRING, BASE_NONE, NULL, 0x0,
6242 "WSP header Accept", HFILL
6245 { &hf_hdr_accept_charset,
6246 { "Accept-Charset",
6247 "wsp.header.accept_charset",
6248 FT_STRING, BASE_NONE, NULL, 0x0,
6249 "WSP header Accept-Charset", HFILL
6252 { &hf_hdr_accept_encoding,
6253 { "Accept-Encoding",
6254 "wsp.header.accept_encoding",
6255 FT_STRING, BASE_NONE, NULL, 0x0,
6256 "WSP header Accept-Encoding", HFILL
6259 { &hf_hdr_accept_language,
6260 { "Accept-Language",
6261 "wsp.header.accept_language",
6262 FT_STRING, BASE_NONE, NULL, 0x0,
6263 "WSP header Accept-Language", HFILL
6266 { &hf_hdr_accept_ranges,
6267 { "Accept-Ranges",
6268 "wsp.header.accept_ranges",
6269 FT_STRING, BASE_NONE, NULL, 0x0,
6270 "WSP header Accept-Ranges", HFILL
6273 { &hf_hdr_age,
6274 { "Age",
6275 "wsp.header.age",
6276 FT_STRING, BASE_NONE, NULL, 0x0,
6277 "WSP header Age", HFILL
6280 { &hf_hdr_allow,
6281 { "Allow",
6282 "wsp.header.allow",
6283 FT_STRING, BASE_NONE, NULL, 0x0,
6284 "WSP header Allow", HFILL
6287 { &hf_hdr_authorization,
6288 { "Authorization",
6289 "wsp.header.authorization",
6290 FT_STRING, BASE_NONE, NULL, 0x0,
6291 "WSP header Authorization", HFILL
6294 { &hf_hdr_authorization_scheme,
6295 { "Authorization Scheme",
6296 "wsp.header.authorization.scheme",
6297 FT_STRING, BASE_NONE, NULL, 0x0,
6298 "WSP header Authorization: used scheme", HFILL
6301 { &hf_hdr_authorization_user_id,
6302 { "User-id",
6303 "wsp.header.authorization.user_id",
6304 FT_STRING, BASE_NONE, NULL, 0x0,
6305 "WSP header Authorization: user ID for basic authorization", HFILL
6308 { &hf_hdr_authorization_password,
6309 { "Password",
6310 "wsp.header.authorization.password",
6311 FT_STRING, BASE_NONE, NULL, 0x0,
6312 "WSP header Authorization: password for basic authorization", HFILL
6315 { &hf_hdr_cache_control,
6316 { "Cache-Control",
6317 "wsp.header.cache_control",
6318 FT_STRING, BASE_NONE, NULL, 0x0,
6319 "WSP header Cache-Control", HFILL
6322 { &hf_hdr_connection,
6323 { "Connection",
6324 "wsp.header.connection",
6325 FT_STRING, BASE_NONE, NULL, 0x0,
6326 "WSP header Connection", HFILL
6329 { &hf_hdr_content_base,
6330 { "Content-Base",
6331 "wsp.header.content_base",
6332 FT_STRING, BASE_NONE, NULL, 0x0,
6333 "WSP header Content-Base", HFILL
6336 { &hf_hdr_content_encoding,
6337 { "Content-Encoding",
6338 "wsp.header.content_encoding",
6339 FT_STRING, BASE_NONE, NULL, 0x0,
6340 "WSP header Content-Encoding", HFILL
6343 { &hf_hdr_content_language,
6344 { "Content-Language",
6345 "wsp.header.content_language",
6346 FT_STRING, BASE_NONE, NULL, 0x0,
6347 "WSP header Content-Language", HFILL
6350 { &hf_hdr_content_length,
6351 { "Content-Length",
6352 "wsp.header.content_length",
6353 FT_STRING, BASE_NONE, NULL, 0x0,
6354 "WSP header Content-Length", HFILL
6357 { &hf_hdr_content_location,
6358 { "Content-Location",
6359 "wsp.header.content_location",
6360 FT_STRING, BASE_NONE, NULL, 0x0,
6361 "WSP header Content-Location", HFILL
6364 { &hf_hdr_content_md5,
6365 { "Content-Md5",
6366 "wsp.header.content_md5",
6367 FT_BYTES, BASE_NONE, NULL, 0x0,
6368 "WSP header Content-Md5", HFILL
6371 { &hf_hdr_content_range,
6372 { "Content-Range",
6373 "wsp.header.content_range",
6374 FT_STRING, BASE_NONE, NULL, 0x0,
6375 "WSP header Content-Range", HFILL
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, 0x0,
6382 "WSP header Content-Range: position of first byte", HFILL
6385 { &hf_hdr_content_range_entity_length,
6386 { "Entity-length",
6387 "wsp.header.content_range.entity_length",
6388 FT_UINT32, BASE_DEC, NULL, 0x0,
6389 "WSP header Content-Range: length of the entity", HFILL
6392 { &hf_hdr_content_type,
6393 { "Content-Type",
6394 "wsp.header.content_type",
6395 FT_STRING, BASE_NONE, NULL, 0x0,
6396 "WSP header Content-Type", HFILL
6399 { &hf_hdr_date,
6400 { "Date",
6401 "wsp.header.date",
6402 FT_STRING, BASE_NONE, NULL, 0x0,
6403 "WSP header Date", HFILL
6406 { &hf_hdr_etag,
6407 { "ETag",
6408 "wsp.header.etag",
6409 FT_STRING, BASE_NONE, NULL, 0x0,
6410 "WSP header ETag", HFILL
6413 { &hf_hdr_expires,
6414 { "Expires",
6415 "wsp.header.expires",
6416 FT_STRING, BASE_NONE, NULL, 0x0,
6417 "WSP header Expires", HFILL
6420 { &hf_hdr_from,
6421 { "From",
6422 "wsp.header.from",
6423 FT_STRING, BASE_NONE, NULL, 0x0,
6424 "WSP header From", HFILL
6427 { &hf_hdr_host,
6428 { "Host",
6429 "wsp.header.host",
6430 FT_STRING, BASE_NONE, NULL, 0x0,
6431 "WSP header Host", HFILL
6434 { &hf_hdr_if_modified_since,
6435 { "If-Modified-Since",
6436 "wsp.header.if_modified_since",
6437 FT_STRING, BASE_NONE, NULL, 0x0,
6438 "WSP header If-Modified-Since", HFILL
6441 { &hf_hdr_if_match,
6442 { "If-Match",
6443 "wsp.header.if_match",
6444 FT_STRING, BASE_NONE, NULL, 0x0,
6445 "WSP header If-Match", HFILL
6448 { &hf_hdr_if_none_match,
6449 { "If-None-Match",
6450 "wsp.header.if_none_match",
6451 FT_STRING, BASE_NONE, NULL, 0x0,
6452 "WSP header If-None-Match", HFILL
6455 { &hf_hdr_if_range,
6456 { "If-Range",
6457 "wsp.header.if_range",
6458 FT_STRING, BASE_NONE, NULL, 0x0,
6459 "WSP header If-Range", HFILL
6462 { &hf_hdr_if_unmodified_since,
6463 { "If-Unmodified-Since",
6464 "wsp.header.if_unmodified_since",
6465 FT_STRING, BASE_NONE, NULL, 0x0,
6466 "WSP header If-Unmodified-Since", HFILL
6469 { &hf_hdr_last_modified,
6470 { "Last-Modified",
6471 "wsp.header.last_modified",
6472 FT_STRING, BASE_NONE, NULL, 0x0,
6473 "WSP header Last-Modified", HFILL
6476 { &hf_hdr_location,
6477 { "Location",
6478 "wsp.header.location",
6479 FT_STRING, BASE_NONE, NULL, 0x0,
6480 "WSP header Location", HFILL
6483 { &hf_hdr_max_forwards,
6484 { "Max-Forwards",
6485 "wsp.header.max_forwards",
6486 FT_STRING, BASE_NONE, NULL, 0x0,
6487 "WSP header Max-Forwards", HFILL
6490 { &hf_hdr_pragma,
6491 { "Pragma",
6492 "wsp.header.pragma",
6493 FT_STRING, BASE_NONE, NULL, 0x0,
6494 "WSP header Pragma", HFILL
6497 { &hf_hdr_proxy_authenticate,
6498 { "Proxy-Authenticate",
6499 "wsp.header.proxy_authenticate",
6500 FT_STRING, BASE_NONE, NULL, 0x0,
6501 "WSP header Proxy-Authenticate", HFILL
6504 { &hf_hdr_proxy_authenticate_scheme,
6505 { "Authentication Scheme",
6506 "wsp.header.proxy_authenticate.scheme",
6507 FT_STRING, BASE_NONE, NULL, 0x0,
6508 "WSP header Proxy-Authenticate: used scheme", HFILL
6511 { &hf_hdr_proxy_authenticate_realm,
6512 { "Authentication Realm",
6513 "wsp.header.proxy_authenticate.realm",
6514 FT_STRING, BASE_NONE, NULL, 0x0,
6515 "WSP header Proxy-Authenticate: used realm", HFILL
6518 { &hf_hdr_proxy_authorization,
6519 { "Proxy-Authorization",
6520 "wsp.header.proxy_authorization",
6521 FT_STRING, BASE_NONE, NULL, 0x0,
6522 "WSP header Proxy-Authorization", HFILL
6525 { &hf_hdr_proxy_authorization_scheme,
6526 { "Authorization Scheme",
6527 "wsp.header.proxy_authorization.scheme",
6528 FT_STRING, BASE_NONE, NULL, 0x0,
6529 "WSP header Proxy-Authorization: used scheme", HFILL
6532 { &hf_hdr_proxy_authorization_user_id,
6533 { "User-id",
6534 "wsp.header.proxy_authorization.user_id",
6535 FT_STRING, BASE_NONE, NULL, 0x0,
6536 "WSP header Proxy-Authorization: user ID for basic authorization", HFILL
6539 { &hf_hdr_proxy_authorization_password,
6540 { "Password",
6541 "wsp.header.proxy_authorization.password",
6542 FT_STRING, BASE_NONE, NULL, 0x0,
6543 "WSP header Proxy-Authorization: password for basic authorization", HFILL
6546 { &hf_hdr_public,
6547 { "Public",
6548 "wsp.header.public",
6549 FT_STRING, BASE_NONE, NULL, 0x0,
6550 "WSP header Public", HFILL
6553 { &hf_hdr_range,
6554 { "Range",
6555 "wsp.header.range",
6556 FT_STRING, BASE_NONE, NULL, 0x0,
6557 "WSP header Range", HFILL
6560 { &hf_hdr_range_first_byte_pos,
6561 { "First-byte-position",
6562 "wsp.header.range.first_byte_pos",
6563 FT_UINT32, BASE_DEC, NULL, 0x0,
6564 "WSP header Range: position of first byte", HFILL
6567 { &hf_hdr_range_last_byte_pos,
6568 { "Last-byte-position",
6569 "wsp.header.range.last_byte_pos",
6570 FT_UINT32, BASE_DEC, NULL, 0x0,
6571 "WSP header Range: position of last byte", HFILL
6574 { &hf_hdr_range_suffix_length,
6575 { "Suffix-length",
6576 "wsp.header.range.suffix_length",
6577 FT_UINT32, BASE_DEC, NULL, 0x0,
6578 "WSP header Range: length of the suffix", HFILL
6581 { &hf_hdr_referer,
6582 { "Referer",
6583 "wsp.header.referer",
6584 FT_STRING, BASE_NONE, NULL, 0x0,
6585 "WSP header Referer", HFILL
6588 { &hf_hdr_retry_after,
6589 { "Retry-After",
6590 "wsp.header.retry_after",
6591 FT_STRING, BASE_NONE, NULL, 0x0,
6592 "WSP header Retry-After", HFILL
6595 { &hf_hdr_server,
6596 { "Server",
6597 "wsp.header.server",
6598 FT_STRING, BASE_NONE, NULL, 0x0,
6599 "WSP header Server", HFILL
6602 { &hf_hdr_transfer_encoding,
6603 { "Transfer-Encoding",
6604 "wsp.header.transfer_encoding",
6605 FT_STRING, BASE_NONE, NULL, 0x0,
6606 "WSP header Transfer-Encoding", HFILL
6609 { &hf_hdr_upgrade,
6610 { "Upgrade",
6611 "wsp.header.upgrade",
6612 FT_STRING, BASE_NONE, NULL, 0x0,
6613 "WSP header Upgrade", HFILL
6616 { &hf_hdr_user_agent,
6617 { "User-Agent",
6618 "wsp.header.user_agent",
6619 FT_STRING, BASE_NONE, NULL, 0x0,
6620 "WSP header User-Agent", HFILL
6623 { &hf_hdr_vary,
6624 { "Vary",
6625 "wsp.header.vary",
6626 FT_STRING, BASE_NONE, NULL, 0x0,
6627 "WSP header Vary", HFILL
6630 { &hf_hdr_via,
6631 { "Via",
6632 "wsp.header.via",
6633 FT_STRING, BASE_NONE, NULL, 0x0,
6634 "WSP header Via", HFILL
6637 { &hf_hdr_warning,
6638 { "Warning",
6639 "wsp.header.warning",
6640 FT_STRING, BASE_NONE, NULL, 0x0,
6641 "WSP header Warning", HFILL
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
6651 { &hf_hdr_warning_agent,
6652 { "Warning agent",
6653 "wsp.header.warning.agent",
6654 FT_STRING, BASE_NONE, NULL, 0x0,
6655 "WSP header Warning agent", HFILL
6658 { &hf_hdr_warning_text,
6659 { "Warning text",
6660 "wsp.header.warning.text",
6661 FT_STRING, BASE_NONE, NULL, 0x0,
6662 "WSP header Warning text", HFILL
6665 { &hf_hdr_www_authenticate,
6666 { "Www-Authenticate",
6667 "wsp.header.www_authenticate",
6668 FT_STRING, BASE_NONE, NULL, 0x0,
6669 "WSP header Www-Authenticate", HFILL
6672 { &hf_hdr_www_authenticate_scheme,
6673 { "Authentication Scheme",
6674 "wsp.header.www_authenticate.scheme",
6675 FT_STRING, BASE_NONE, NULL, 0x0,
6676 "WSP header WWW-Authenticate: used scheme", HFILL
6679 { &hf_hdr_www_authenticate_realm,
6680 { "Authentication Realm",
6681 "wsp.header.www_authenticate.realm",
6682 FT_STRING, BASE_NONE, NULL, 0x0,
6683 "WSP header WWW-Authenticate: used realm", HFILL
6686 { &hf_hdr_content_disposition,
6687 { "Content-Disposition",
6688 "wsp.header.content_disposition",
6689 FT_STRING, BASE_NONE, NULL, 0x0,
6690 "WSP header Content-Disposition", HFILL
6693 { &hf_hdr_application_id,
6694 { "Application-Id",
6695 "wsp.header.application_id",
6696 FT_STRING, BASE_NONE, NULL, 0x0,
6697 "WSP header Application-Id", HFILL
6700 { &hf_hdr_content_uri,
6701 { "Content-Uri",
6702 "wsp.header.content_uri",
6703 FT_STRING, BASE_NONE, NULL, 0x0,
6704 "WSP header Content-Uri", HFILL
6707 { &hf_hdr_initiator_uri,
6708 { "Initiator-Uri",
6709 "wsp.header.initiator_uri",
6710 FT_STRING, BASE_NONE, NULL, 0x0,
6711 "WSP header Initiator-Uri", HFILL
6714 { &hf_hdr_bearer_indication,
6715 { "Bearer-Indication",
6716 "wsp.header.bearer_indication",
6717 FT_STRING, BASE_NONE, NULL, 0x0,
6718 "WSP header Bearer-Indication", HFILL
6721 { &hf_hdr_push_flag,
6722 { "Push-Flag",
6723 "wsp.header.push_flag",
6724 FT_STRING, BASE_NONE, NULL, 0x0,
6725 "WSP header Push-Flag", HFILL
6728 { &hf_hdr_push_flag_auth,
6729 { "Initiator URI is authenticated",
6730 "wsp.header.push_flag.authenticated",
6731 FT_BOOLEAN, 8, NULL, 0x01,
6732 "The X-Wap-Initiator-URI has been authenticated.", HFILL
6735 { &hf_hdr_push_flag_trust,
6736 { "Content is trusted",
6737 "wsp.header.push_flag.trusted",
6738 FT_BOOLEAN, 8, NULL, 0x02,
6739 "The push content is trusted.", HFILL
6742 { &hf_hdr_push_flag_last,
6743 { "Last push message",
6744 "wsp.header.push_flag.last",
6745 FT_BOOLEAN, 8, NULL, 0x04,
6746 "Indicates whether this is the last push message.", HFILL
6749 { &hf_hdr_profile,
6750 { "Profile",
6751 "wsp.header.profile",
6752 FT_STRING, BASE_NONE, NULL, 0x0,
6753 "WSP header Profile", HFILL
6756 { &hf_hdr_profile_diff,
6757 { "Profile-Diff",
6758 "wsp.header.profile_diff",
6759 FT_STRING, BASE_NONE, NULL, 0x0,
6760 "WSP header Profile-Diff", HFILL
6763 { &hf_hdr_profile_warning,
6764 { "Profile-Warning",
6765 "wsp.header.profile_warning",
6766 FT_STRING, BASE_NONE, NULL, 0x0,
6767 "WSP header Profile-Warning", HFILL
6770 { &hf_hdr_expect,
6771 { "Expect",
6772 "wsp.header.expect",
6773 FT_STRING, BASE_NONE, NULL, 0x0,
6774 "WSP header Expect", HFILL
6777 { &hf_hdr_te,
6778 { "Te",
6779 "wsp.header.te",
6780 FT_STRING, BASE_NONE, NULL, 0x0,
6781 "WSP header Te", HFILL
6784 { &hf_hdr_trailer,
6785 { "Trailer",
6786 "wsp.header.trailer",
6787 FT_STRING, BASE_NONE, NULL, 0x0,
6788 "WSP header Trailer", HFILL
6791 { &hf_hdr_x_wap_tod,
6792 { "X-Wap-Tod",
6793 "wsp.header.x_wap_tod",
6794 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
6795 "WSP header X-Wap-Tod", HFILL
6798 { &hf_hdr_content_id,
6799 { "Content-Id",
6800 "wsp.header.content_id",
6801 FT_STRING, BASE_NONE, NULL, 0x0,
6802 "WSP header Content-Id", HFILL
6805 { &hf_hdr_set_cookie,
6806 { "Set-Cookie",
6807 "wsp.header.set_cookie",
6808 FT_STRING, BASE_NONE, NULL, 0x0,
6809 "WSP header Set-Cookie", HFILL
6812 { &hf_hdr_cookie,
6813 { "Cookie",
6814 "wsp.header.cookie",
6815 FT_STRING, BASE_NONE, NULL, 0x0,
6816 "WSP header Cookie", HFILL
6819 { &hf_hdr_encoding_version,
6820 { "Encoding-Version",
6821 "wsp.header.encoding_version",
6822 FT_STRING, BASE_NONE, NULL, 0x0,
6823 "WSP header Encoding-Version", HFILL
6826 { &hf_hdr_x_wap_security,
6827 { "X-Wap-Security",
6828 "wsp.header.x_wap_security",
6829 FT_STRING, BASE_NONE, NULL, 0x0,
6830 "WSP header X-Wap-Security", HFILL
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, 0x0,
6837 "WSP header X-Wap-Application-Id", HFILL
6840 { &hf_hdr_accept_application,
6841 { "Accept-Application",
6842 "wsp.header.accept_application",
6843 FT_STRING, BASE_NONE, NULL, 0x0,
6844 "WSP header Accept-Application", HFILL
6850 * Openwave headers
6851 * Header Code Page: x-up-1
6853 { &hf_hdr_openwave_default_int,
6854 { "Default integer",
6855 "wsp.default_int",
6856 FT_UINT32, BASE_DEC, NULL, 0x0,
6857 NULL, HFILL
6860 { &hf_hdr_openwave_default_string,
6861 { "Default string value",
6862 "wsp.default_string",
6863 FT_STRING, BASE_NONE, NULL, 0x0,
6864 NULL, HFILL
6867 { &hf_hdr_openwave_default_val_len,
6868 { "Default value len",
6869 "wsp.default_val_len",
6870 FT_UINT32, BASE_DEC, NULL, 0x0,
6871 NULL, HFILL
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
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, 0x0,
6887 "WSP Openwave header x-up-proxy-operator-domain", HFILL
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, 0x0,
6894 "WSP Openwave header x-up-proxy-home-page", HFILL
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, 0x0,
6901 "WSP Openwave header x-up-proxy-uplink-version", HFILL
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, 0x0,
6908 "WSP Openwave header x-up-proxy-ba-realm", HFILL
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, 0x0,
6915 "WSP Openwave header x-up-proxy-request-uri", HFILL
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, 0x0,
6922 "WSP Openwave header x-up-proxy-bookmark", HFILL
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, 0x0,
6930 "WSP Openwave header x-up-proxy-push-seq", HFILL
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, 0x0,
6937 "WSP Openwave header x-up-proxy-notify", HFILL
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, 0x0,
6944 "WSP Openwave header x-up-proxy-net-ask", HFILL
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, 0x0,
6951 "WSP Openwave header x-up-proxy-tod", HFILL
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, 0x0,
6958 "WSP Openwave header x-up-proxy-ba-enable", HFILL
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, 0x0,
6965 "WSP Openwave header x-up-proxy-redirect-enable", HFILL
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, 0x0,
6972 "WSP Openwave header x-up-proxy-redirect-status", HFILL
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, 0x0,
6979 "WSP Openwave header x-up-proxy-linger", HFILL
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, 0x0,
6986 "WSP Openwave header x-up-proxy-enable-trust", HFILL
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, 0x0,
6993 "WSP Openwave header x-up-proxy-trust", HFILL
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, 0x0,
7000 "WSP Openwave header x-up-devcap-has-color", HFILL
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, 0x0,
7007 "WSP Openwave header x-up-devcap-num-softkeys", HFILL
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, 0x0,
7014 "WSP Openwave header x-up-devcap-softkey-size", HFILL
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, 0x0,
7021 "WSP Openwave header x-up-devcap-screen-chars", HFILL
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, 0x0,
7028 "WSP Openwave header x-up-devcap-screen-pixels", HFILL
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, 0x0,
7035 "WSP Openwave header x-up-devcap-em-size", HFILL
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, 0x0,
7042 "WSP Openwave header x-up-devcap-screen-depth", HFILL
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, 0x0,
7049 "WSP Openwave header x-up-devcap-immed-alert", HFILL
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, 0x0,
7056 "WSP Openwave header x-up-devcap-gui", HFILL
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, 0x0,
7063 "WSP Openwave header x-up-proxy-trans-charset", HFILL
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, 0x0,
7070 "WSP Openwave header x-up-proxy-push-accept", HFILL
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, 0x0,
7080 "WSP Openwave header x-up-proxy-client-id", HFILL
7083 #endif
7086 * Header value parameters
7089 { &hf_parameter_q,
7090 { "Q",
7091 "wsp.parameter.q",
7092 FT_STRING, BASE_NONE, NULL, 0x0,
7093 "Q parameter", HFILL
7096 { &hf_parameter_charset,
7097 { "Charset",
7098 "wsp.parameter.charset",
7099 FT_STRING, BASE_NONE, NULL, 0x0,
7100 "Charset parameter", HFILL
7105 /* Setup protocol subtree array */
7106 static int *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,
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, "Undecoded 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 }}
7176 expert_module_t* expert_wsp;
7178 /* Register the protocol name and description */
7179 proto_wsp = proto_register_protocol( "Wireless Session Protocol", "WSP", "wsp");
7180 wsp_tap = register_tap("wsp");
7182 /* Init the hash table */
7183 /* wsp_sessions = g_hash_table_new(
7184 (GHashFunc) wsp_session_hash,
7185 (GEqualFunc)wsp_session_equal);*/
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));
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_with_description("wsp", "WSP payload fallback", proto_wsp);
7197 wsp_fromudp_handle = register_dissector("wsp.udp", dissect_wsp_fromudp,
7198 proto_wsp);
7201 void
7202 proto_reg_handoff_wsp(void)
7205 * Get a handle for the WTP-over-UDP and the generic media dissectors.
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);
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);
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);
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);
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");
7227 /* This dissector is also called from the WTP and WTLS dissectors */
7231 * Session Initiation Request
7234 /* Register the protocol with Wireshark */
7235 void
7236 proto_register_sir(void)
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, 0x0,
7244 "Session Initiation Request content", HFILL
7247 { &hf_sir_version,
7248 { "Version",
7249 "wap.sir.version",
7250 FT_UINT8, BASE_DEC, NULL, 0x0,
7251 "Version of the Session Initiation Request document", HFILL
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, 0x0,
7258 "Length of the Application-ID list (bytes)", HFILL
7261 { &hf_sir_app_id_list,
7262 { "Application-ID List",
7263 "wap.sir.app_id_list",
7264 FT_NONE, BASE_NONE, NULL, 0x0,
7265 NULL, HFILL
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, 0x0,
7272 "Length of the WSP Contact Points list (bytes)", HFILL
7275 { &hf_sir_wsp_contact_points,
7276 { "WSP Contact Points",
7277 "wap.sir.wsp_contact_points",
7278 FT_NONE, BASE_NONE, NULL, 0x0,
7279 "WSP Contact Points list", HFILL
7282 { &hf_sir_contact_points_len,
7283 { "Non-WSP Contact Points Length",
7284 "wap.sir.contact_points.length",
7285 FT_UINT32, BASE_DEC, NULL, 0x0,
7286 "Length of the Non-WSP Contact Points list (bytes)", HFILL
7289 { &hf_sir_contact_points,
7290 { "Non-WSP Contact Points",
7291 "wap.sir.contact_points",
7292 FT_NONE, BASE_NONE, NULL, 0x0,
7293 "Non-WSP Contact Points list", HFILL
7296 { &hf_sir_protocol_options_len,
7297 { "Protocol Options List Entries",
7298 "wap.sir.protocol_options.length",
7299 FT_UINT32, BASE_DEC, NULL, 0x0,
7300 "Number of entries in the Protocol Options list", HFILL
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
7310 { &hf_sir_prov_url_len,
7311 { "X-Wap-ProvURL Length",
7312 "wap.sir.prov_url.length",
7313 FT_UINT32, BASE_DEC, NULL, 0x0,
7314 "Length of the X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL
7317 { &hf_sir_prov_url,
7318 { "X-Wap-ProvURL",
7319 "wap.sir.prov_url",
7320 FT_STRING, BASE_NONE, NULL, 0x0,
7321 "X-Wap-ProvURL (Identifies the WAP Client Provisioning Context)", HFILL
7324 { &hf_sir_cpi_tag_len,
7325 { "CPITag List Entries",
7326 "wap.sir.cpi_tag.length",
7327 FT_UINT32, BASE_DEC, NULL, 0x0,
7328 "Number of entries in the CPITag list", HFILL
7331 { &hf_sir_cpi_tag,
7332 { "CPITag",
7333 "wap.sir.cpi_tag",
7334 FT_BYTES, BASE_NONE, NULL, 0x0,
7335 "CPITag (OTA-HTTP)", HFILL
7340 /* Setup protocol subtree array */
7341 static int *ett[] = {
7342 &ett_sir /* Session Initiation Request */
7345 static tap_param wsp_stat_params[] = {
7346 { PARAM_FILTER, "filter", "Filter", NULL, true }
7349 static stat_tap_table_ui wsp_stat_table = {
7350 REGISTER_TELEPHONY_GROUP_UNSORTED,
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 array_length(wsp_stat_fields), wsp_stat_fields,
7360 array_length(wsp_stat_params), wsp_stat_params,
7361 NULL,
7366 /* Register the dissector */
7367 /* Abbreviated protocol name should Match IANA: https://www.iana.org/assignments/port-numbers/ */
7368 proto_sir = proto_register_protocol("WAP Session Initiation Request", "WAP SIR", "wap-sir");
7370 /* Register header fields and protocol subtrees */
7371 proto_register_field_array(proto_sir, hf, array_length(hf));
7372 proto_register_subtree_array(ett, array_length(ett));
7374 sir_handle = register_dissector("wap-sir", dissect_sir, proto_sir);
7376 register_stat_tap_table_ui(&wsp_stat_table);
7379 void
7380 proto_reg_handoff_sir(void)
7382 /* Add dissector bindings for SIR dissection */
7383 dissector_add_string("media_type", "application/vnd.wap.sia", sir_handle);
7389 * Editor modelines
7391 * Local Variables:
7392 * c-basic-offset: 4
7393 * tab-width: 8
7394 * indent-tabs-mode: nil
7395 * End:
7397 * ex: set shiftwidth=4 tabstop=8 expandtab:
7398 * :indentSize=4:tabSize=8:noTabs=true: