Coverage Report

Created: 2026-11-12 07:01

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