diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-01-30 05:54:19 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-01-30 05:54:19 +0000 |
commit | 6b69c22f889eb4e4a8f3a5eebd3bb3351abf81bf (patch) | |
tree | c6d0a5a7eaf088c4d30b5bd72f1c6f9f883829b6 /packet-wsp.c | |
parent | 59dda02da51568c82c9f7ff86d451296a8ee8b05 (diff) |
WTLS support and WSP fixes, from Alexandre P. Ferreira.
svn path=/trunk/; revision=2960
Diffstat (limited to 'packet-wsp.c')
-rw-r--r-- | packet-wsp.c | 1496 |
1 files changed, 1451 insertions, 45 deletions
diff --git a/packet-wsp.c b/packet-wsp.c index f8674bdcd5..9a71ecd038 100644 --- a/packet-wsp.c +++ b/packet-wsp.c @@ -3,7 +3,7 @@ * * Routines to dissect WSP component of WAP traffic. * - * $Id: packet-wsp.c,v 1.14 2001/01/28 04:26:53 guy Exp $ + * $Id: packet-wsp.c,v 1.15 2001/01/30 05:54:18 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -56,6 +56,7 @@ /* File scoped variables for the protocol and registered fields */ static int proto_wsp = HF_EMPTY; +static int proto_wtls = HF_EMPTY; /* These fields used by fixed part of header */ static int hf_wsp_header_tid = HF_EMPTY; @@ -80,6 +81,7 @@ static int hf_wsp_header_accept = HF_EMPTY; static int hf_wsp_header_accept_str = HF_EMPTY; static int hf_wsp_header_accept_charset = HF_EMPTY; static int hf_wsp_header_accept_language = HF_EMPTY; +static int hf_wsp_header_accept_language_str = HF_EMPTY; static int hf_wsp_header_accept_ranges = HF_EMPTY; static int hf_wsp_header_cache_control = HF_EMPTY; static int hf_wsp_header_content_length = HF_EMPTY; @@ -95,6 +97,72 @@ static int hf_wsp_header_user_agent = HF_EMPTY; static int hf_wsp_header_application_header = HF_EMPTY; static int hf_wsp_header_application_value = HF_EMPTY; static int hf_wsp_header_x_wap_tod = HF_EMPTY; +static int hf_wsp_header_transfer_encoding = HF_EMPTY; +static int hf_wsp_header_transfer_encoding_str = HF_EMPTY; +static int hf_wsp_header_via = HF_EMPTY; + +static int hf_wtls_record = HF_EMPTY; +static int hf_wtls_record_type = HF_EMPTY; +static int hf_wtls_record_length = HF_EMPTY; +static int hf_wtls_record_sequence = HF_EMPTY; +static int hf_wtls_record_ciphered = HF_EMPTY; +static int hf_wtls_hands = HF_EMPTY; +static int hf_wtls_hands_type = HF_EMPTY; +static int hf_wtls_hands_length = HF_EMPTY; +static int hf_wtls_hands_cli_hello = HF_EMPTY; +static int hf_wtls_hands_cli_hello_version = HF_EMPTY; +static int hf_wtls_hands_cli_hello_gmt = HF_EMPTY; +static int hf_wtls_hands_cli_hello_random = HF_EMPTY; +static int hf_wtls_hands_cli_hello_session = HF_EMPTY; +static int hf_wtls_hands_cli_hello_cli_key_id = HF_EMPTY; +static int hf_wtls_hands_cli_hello_trust_key_id = HF_EMPTY; +static int hf_wtls_hands_cli_hello_key_exchange =HF_EMPTY; +static int hf_wtls_hands_cli_hello_key_exchange_suite =HF_EMPTY; +static int hf_wtls_hands_cli_hello_key_parameter_index =HF_EMPTY; +static int hf_wtls_hands_cli_hello_key_parameter_set =HF_EMPTY; +static int hf_wtls_hands_cli_hello_key_identifier_type =HF_EMPTY; +static int hf_wtls_hands_cli_hello_cipher_suite =HF_EMPTY; +static int hf_wtls_hands_cli_hello_cipher_suite_item =HF_EMPTY; +static int hf_wtls_hands_cli_hello_cipher_bulk =HF_EMPTY; +static int hf_wtls_hands_cli_hello_cipher_mac =HF_EMPTY; +static int hf_wtls_hands_cli_hello_compression_methods =HF_EMPTY; +static int hf_wtls_hands_cli_hello_compression =HF_EMPTY; +static int hf_wtls_hands_cli_hello_sequence_mode =HF_EMPTY; +static int hf_wtls_hands_cli_hello_key_refresh =HF_EMPTY; +static int hf_wtls_hands_serv_hello = HF_EMPTY; +static int hf_wtls_hands_serv_hello_version = HF_EMPTY; +static int hf_wtls_hands_serv_hello_gmt = HF_EMPTY; +static int hf_wtls_hands_serv_hello_random = HF_EMPTY; +static int hf_wtls_hands_serv_hello_session = HF_EMPTY; +static int hf_wtls_hands_serv_hello_cli_key_id =HF_EMPTY; +static int hf_wtls_hands_serv_hello_cipher_suite_item =HF_EMPTY; +static int hf_wtls_hands_serv_hello_cipher_bulk =HF_EMPTY; +static int hf_wtls_hands_serv_hello_cipher_mac =HF_EMPTY; +static int hf_wtls_hands_serv_hello_compression =HF_EMPTY; +static int hf_wtls_hands_serv_hello_sequence_mode =HF_EMPTY; +static int hf_wtls_hands_serv_hello_key_refresh =HF_EMPTY; +static int hf_wtls_hands_certificates =HF_EMPTY; +static int hf_wtls_hands_certificate =HF_EMPTY; +static int hf_wtls_hands_certificate_type =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_version =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_signature_type =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_issuer_type =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_issuer_charset =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_issuer_name =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_valid_not_before =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_valid_not_after =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_subject_type =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_subject_charset =HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_subject_name = HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_public_key_type = HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_key_parameter_index = HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_key_parameter_set = HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_rsa_exponent = HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_rsa_modules = HF_EMPTY; +static int hf_wtls_hands_certificate_wtls_signature = HF_EMPTY; +static int hf_wtls_alert = HF_EMPTY; +static int hf_wtls_alert_level = HF_EMPTY; +static int hf_wtls_alert_description = HF_EMPTY; /* Initialize the subtree pointers */ static gint ett_wsp = ETT_EMPTY; @@ -102,6 +170,11 @@ static gint ett_header = ETT_EMPTY; static gint ett_headers = ETT_EMPTY; static gint ett_capabilities = ETT_EMPTY; static gint ett_content_type = ETT_EMPTY; +static gint ett_wtls_rec = ETT_EMPTY; +static gint ett_wtls_msg_type = ETT_EMPTY; +static gint ett_wtls_msg_type_item = ETT_EMPTY; +static gint ett_wtls_msg_type_item_sub = ETT_EMPTY; +static gint ett_wtls_msg_type_item_sub_sub = ETT_EMPTY; static const value_string vals_pdu_type[] = { { 0x00, "Reserved" }, @@ -260,7 +333,102 @@ static const value_string vals_character_sets[] = { }; static const value_string vals_languages[] = { - { 0x19, "English (en)" }, + { 0x01,"Afar(aa)" }, + { 0x02,"Abkhazian(ab)" }, + { 0x03,"Afrikaans(af)" }, + { 0x04,"Amharic(am)" }, + { 0x05,"Arabic(ar)" }, + { 0x06,"Assamese(as)" }, + { 0x07,"Aymara(ay)" }, + { 0x08,"Azerbaijani(az)" }, + { 0x09,"Bashkir(ba)" }, + { 0x0A,"Byelorussian(be)" }, + { 0x0B,"Bulgarian(bg)" }, + { 0x0C,"Bihari(bh)" }, + { 0x0D,"Bislama(bi)" }, + { 0x0E,"Bengali; Bangla(bn)" }, + { 0x0F,"Tibetan(bo)" }, + { 0x10,"Breton(br)" }, + { 0x11,"Catalan(ca)" }, + { 0x12,"Corsican(co)" }, + { 0x13,"Czech(cs)" }, + { 0x14,"Welsh(cy)" }, + { 0x15,"Danish(da)" }, + { 0x16,"German(de)" }, + { 0x17,"Bhutani(dz)" }, + { 0x18,"Greek(el)" }, + { 0x19,"English(en)" }, + { 0x1A,"Esperanto(eo)" }, + { 0x1B,"Spanish(es)" }, + { 0x1C,"Estonian(et)" }, + { 0x1D,"Basque(eu)" }, + { 0x1E,"Persian(fa)" }, + { 0x1F,"Finnish(fi)" }, + { 0x20,"Fiji(fj)" }, + { 0x22,"French(fr)" }, + { 0x24,"Irish(ga)" }, + { 0x25,"Scots Gaelic(gd)" }, + { 0x26,"Galician(gl)" }, + { 0x27,"Guarani(gn)" }, + { 0x28,"Gujarati(gu)" }, + { 0x29,"Hausa(ha)" }, + { 0x2A,"Hebrew (formerly iw)(he)" }, + { 0x2B,"Hindi(hi)" }, + { 0x2C,"Croatian(hr)" }, + { 0x2D,"Hungarian(hu)" }, + { 0x2E,"Armenian(hy)" }, + { 0x30,"Indonesian (formerly in)(id)" }, + { 0x47,"Maori(mi)" }, + { 0x48,"Macedonian(mk)" }, + { 0x49,"Malayalam(ml)" }, + { 0x4A,"Mongolian(mn)" }, + { 0x4B,"Moldavian(mo)" }, + { 0x4C,"Marathi(mr)" }, + { 0x4D,"Malay(ms)" }, + { 0x4E,"Maltese(mt)" }, + { 0x4F,"Burmese(my)" }, + { 0x51,"Nepali(ne)" }, + { 0x52,"Dutch(nl)" }, + { 0x53,"Norwegian(no)" }, + { 0x54,"Occitan(oc)" }, + { 0x55,"(Afan) Oromo(om)" }, + { 0x56,"Oriya(or)" }, + { 0x57,"Punjabi(pa)" }, + { 0x58,"Polish(po)" }, + { 0x59,"Pashto, Pushto(ps)" }, + { 0x5A,"Portuguese(pt)" }, + { 0x5B,"Quechua(qu)" }, + { 0x5D,"Kirundi(rn)" }, + { 0x5E,"Romanian(ro)" }, + { 0x5F,"Russian(ru)" }, + { 0x60,"Kinyarwanda(rw)" }, + { 0x61,"Sanskrit(sa)" }, + { 0x62,"Sindhi(sd)" }, + { 0x63,"Sangho(sg)" }, + { 0x64,"Serbo-Croatian(sh)" }, + { 0x65,"Sinhalese(si)" }, + { 0x66,"Slovak(sk)" }, + { 0x67,"Slovenian(sl)" }, + { 0x68,"Samoan(sm)" }, + { 0x69,"Shona(sn)" }, + { 0x6A,"Somali(so)" }, + { 0x6B,"Albanian(sq)" }, + { 0x6C,"Serbian(sr)" }, + { 0x6D,"Siswati(ss)" }, + { 0x6E,"Sesotho(st)" }, + { 0x6F,"Sundanese(su)" }, + { 0x70,"Swedish(sv)" }, + { 0x71,"Swahili(sw)" }, + { 0x72,"Tamil(ta)" }, + { 0x73,"Telugu(te)" }, + { 0x74,"Tajik(tg)" }, + { 0x75,"Thai(th)" }, + { 0x76,"Tigrinya(ti)" }, + { 0x81,"Nauru(na)" }, + { 0x82,"Faeroese(fo)" }, + { 0x83,"Frisian(fy)" }, + { 0x84,"Interlingua(ia)" }, + { 0x8C,"Rhaeto-Romance(rm)" }, { 0x00, NULL } }; @@ -285,6 +453,168 @@ static const value_string vals_cache_control[] = { { 0x00, NULL } }; +static const value_string vals_transfer_encoding[] = { + { 0x80, "Chunked" }, + { 0x00, NULL } +}; +static const value_string wtls_vals_record_type[] = { + { 0x01, "change_cipher_data" }, + { 0x02, "alert" }, + { 0x03, "handshake" }, + { 0x04, "application_data" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_cipher_bulk[] = { + { 0x00, "Null" }, + { 0x01, "RC5 CBC 40" }, + { 0x02, "RC5 CBC 56" }, + { 0x03, "RC5 CBC" }, + { 0x04, "DES CBC 40" }, + { 0x05, "DES CBC" }, + { 0x06, "3DES CBC cwEDE40" }, + { 0x07, "IDEA CBC 40" }, + { 0x08, "IDEA CBC 56" }, + { 0x09, "IDEA CBC" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_cipher_mac[] = { + { 0x00, "SHA 0" }, + { 0x01, "SHA 40 " }, + { 0x02, "SHA 80" }, + { 0x03, "SHA" }, + { 0x04, "SHA XOR 40" }, + { 0x05, "MD5 40" }, + { 0x06, "MD5 80" }, + { 0x07, "MD5" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_handshake_type[] = { + { 0, "Hello Request" }, + { 1, "Client Hello" }, + { 2, "Server Hello" }, + { 11, "Certificate" }, + { 12, "Server Key Exchange" }, + { 13, "Certificate Request" }, + { 14, "Server Hello Done" }, + { 15, "Certificate Verify" }, + { 16, "Client Key Exchange" }, + { 20, "Finished" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_key_exchange_suite[] = { + { 0, "NULL" }, + { 1, "Shared Secret" }, + { 2, "Diffie Hellman Anonymous" }, + { 3, "Diffie Hellman Anonymous 512" }, + { 4, "Diffie Hellman Anonymous 768" }, + { 5, "RSA Anonymous" }, + { 6, "RSA Anonymous 512" }, + { 7, "RSA Anonymous 768" }, + { 8, "RSA" }, + { 9, "RSA 512" }, + { 10, "RSA 768" }, + { 11, "EC Diffie Hellman Anonymous" }, + { 12, "EC Diffie Hellman Anonymous 113" }, + { 13, "EC Diffie Hellman Anonymous 131" }, + { 14, "EC Diffie Hellman ECDSA" }, + { 15, "EC Diffie Hellman Anonymous Uncomp" }, + { 16, "EC Diffie Hellman Anonymous Uncomp 113" }, + { 17, "EC Diffie Hellman Anonymous Uncomp 131" }, + { 18, "EC Diffie Hellman ECDSA Uncomp" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_identifier_type[] = { + { 0, "No identifier" }, + { 1, "Textual Name" }, + { 2, "Binary Name" }, + { 254, "SHA-1 Hash Publie Key" }, + { 255, "x509 Distinguished Name" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_certificate_type[] = { + { 1, "WTLS" }, + { 2, "X509" }, + { 3, "X968" }, + { 4, "Url" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_compression[] = { + { 0, "Null" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_sequence_mode[] = { + { 0, "Off" }, + { 1, "Implicit" }, + { 2, "Explicit" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_certificate_signature[] = { + { 0, "Anonymous" }, + { 1, "ECDSA_SHA" }, + { 2, "RSA_SHA" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_public_key_type[] = { + { 2, "RSA" }, + { 3, "ECDH" }, + { 4, "ECSA" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_alert_level[] = { + { 1, "Warning" }, + { 2, "Critical" }, + { 3, "Fatal" }, + { 0x00, NULL } +}; + +static const value_string wtls_vals_alert_description[] = { + { 0,"connection_close_notify"}, + { 1,"session_close_notify"}, + { 5,"no_connection"}, + { 10,"unexpected_message"}, + { 11,"time_required"}, + { 20,"bad_record_mac"}, + { 21,"decryption_failed"}, + { 22,"record_overflow"}, + { 30,"decompression_failure"}, + { 40,"handshake_failure"}, + { 42,"bad_certificate"}, + { 43,"unsupported_certificate"}, + { 44,"certificate_revoked"}, + { 45,"certificate_expired"}, + { 46,"certificate_unknown"}, + { 47,"illegal_parameter"}, + { 48,"unknown_ca"}, + { 49,"access_denied"}, + { 50,"decode_error"}, + { 51,"decrypt_error"}, + { 52,"unknown_key_id"}, + { 53,"disabled_key_id"}, + { 54,"key_exchange_disabled"}, + { 55,"session_not_ready"}, + { 56,"unknown_parameter_index"}, + { 57,"duplicate_finished_received"}, + { 60,"export_restriction"}, + { 70,"protocol_version"}, + { 71,"insufficient_security"}, + { 80,"internal_error"}, + { 90,"user_canceled"}, + { 100,"no_renegotiation"}, + { 0x00, NULL } +}; + + /* * Windows appears to define DELETE. */ @@ -314,6 +644,33 @@ enum { PUT = 0x61, /* No sample data */ }; +#define WTLS_RECORD_TYPE_LENGTH 0x80 +#define WTLS_RECORD_TYPE_SEQUENCE 0x40 +#define WTLS_RECORD_TYPE_CIPHER_CUR 0x20 +#define WTLS_RECORD_CONTENT_TYPE 0x0f + +#define WTLS_ALERT 0x02 +#define WTLS_PLAIN_HANDSHAKE 0x03 + +#define WTLS_HANDSHAKE_CLIENT_HELLO 1 +#define WTLS_HANDSHAKE_SERVER_HELLO 2 +#define WTLS_HANDSHAKE_CERTIFICATE 11 + +#define CERTIFICATE_WTLS 1 +#define CERTIFICATE_X509 2 +#define CERTIFICATE_X968 3 +#define CERTIFICATE_URL 4 + +#define IDENTIFIER_NULL 0 +#define IDENTIFIER_TEXT 1 +#define IDENTIFIER_BIN 2 +#define IDENTIFIER_SHA_1 254 +#define IDENTIFIER_X509 255 + +#define PUBLIC_KEY_RSA 2 +#define PUBLIC_KEY_ECDH 3 +#define PUBLIC_KEY_ECDSA 4 + static void add_uri (proto_tree *, tvbuff_t *, guint, guint); static void add_headers (proto_tree *, tvbuff_t *); static void add_header (proto_tree *, tvbuff_t *, tvbuff_t *); @@ -323,6 +680,7 @@ static guint add_parameter (proto_tree *, tvbuff_t *, guint); static guint add_parameter_charset (proto_tree *, tvbuff_t *, guint, guint); static void add_post_data (proto_tree *, tvbuff_t *, guint); static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint); +static void dissect_wtls_handshake (proto_tree *, tvbuff_t *, guint, guint); /* * Accessor to retrieve variable length int as used in WAP protocol. @@ -404,32 +762,16 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* proto_tree *wsp_header_fixed; */ proto_tree *wsp_capabilities; -/* This field shows up as the "Info" column in the display; you should make - it, if possible, summarize what's in the packet, so that a user looking - at the list of packets can tell what type of packet it is. */ - - /* Display protocol type depending on the port */ if (check_col(fdata, COL_PROTOCOL)) { - switch ( pinfo->match_port ) - { - case UDP_PORT_WSP: - col_set_str(fdata, COL_PROTOCOL, "WSP" ); - break; - case UDP_PORT_WTLS_WSP: - col_set_str(fdata, COL_PROTOCOL, "WTLS+WSP" ); - break; - } + col_set_str(fdata, COL_PROTOCOL, "WSP" ); } if (check_col(fdata, COL_INFO)) { col_clear(fdata, COL_INFO); }; /* Connection-less mode has a TID first */ - if ((pinfo->match_port == UDP_PORT_WSP) || (pinfo->match_port == UDP_PORT_WTLS_WSP)) - { - offset++; - }; + offset++; /* Find the PDU type */ pdut = tvb_get_guint8 (tvb, offset); @@ -455,10 +797,7 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* Add common items: only TID and PDU Type */ /* TID Field is always first (if it exists) */ - if ((pinfo->match_port == UDP_PORT_WSP) || (pinfo->match_port == UDP_PORT_WTLS_WSP)) - { - ti = proto_tree_add_item (wsp_tree, hf_wsp_header_tid,tvb,0,1,bo_little_endian); - } + ti = proto_tree_add_item (wsp_tree, hf_wsp_header_tid,tvb,0,1,bo_little_endian); ti = proto_tree_add_item( wsp_tree, /* tree */ @@ -602,6 +941,526 @@ dissect_wsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } } +/* Code to actually dissect the packets */ +static void +dissect_wtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + frame_data *fdata = pinfo->fd; + int offset = 0; + + char pdut; + char pdu_msg_type; + guint count = 0; + guint offset_wtls = 0; + +/* Set up structures we will need to add the protocol subtree and manage it */ + proto_item *ti; + proto_tree *wtls_tree; + proto_tree *wtls_rec_tree; + proto_tree *wtls_msg_type_tree; + + if (check_col(fdata, COL_PROTOCOL)) + { + col_set_str(fdata, COL_PROTOCOL, "WTLS+WSP" ); + } + + /* Develop the string to put in the Info column */ + if (check_col(fdata, COL_INFO)) { + col_set_str(fdata, COL_INFO, "WTLS" ); + }; + + /* In the interest of speed, if "tree" is NULL, don't do any work not + necessary to generate protocol tree items. */ + + if (tree) { + ti = proto_tree_add_item(tree, proto_wtls, tvb, offset_wtls, + tvb_length(tvb), bo_little_endian); + wtls_tree = proto_item_add_subtree(ti, ett_wsp); + + for (offset_wtls=0; offset_wtls < (tvb_length(tvb)-1);) { + pdut = tvb_get_guint8 (tvb, offset_wtls); + + offset = offset_wtls+1; + + if (pdut & WTLS_RECORD_TYPE_SEQUENCE) { + offset+=2; + } + if (pdut & WTLS_RECORD_TYPE_LENGTH) { + count = tvb_get_ntohs(tvb, offset); + offset+=2; + count += offset-offset_wtls; + } + else { + count = tvb_length (tvb)-offset_wtls; + } + ti = proto_tree_add_item(wtls_tree, hf_wtls_record, tvb, offset_wtls, + count, bo_little_endian); + wtls_rec_tree = proto_item_add_subtree(ti, ett_wtls_rec); + + offset = offset_wtls; + + ti = proto_tree_add_item (wtls_rec_tree, hf_wtls_record_type, + tvb,offset,1,bo_big_endian); + + offset++; + + offset_wtls += count; + + if (pdut & WTLS_RECORD_TYPE_SEQUENCE) { + ti = proto_tree_add_item (wtls_rec_tree, hf_wtls_record_sequence, + tvb,offset,2,bo_big_endian); + offset+=2; + } + if (pdut & WTLS_RECORD_TYPE_LENGTH) { + count = tvb_get_ntohs(tvb, offset); + ti = proto_tree_add_item (wtls_rec_tree, hf_wtls_record_length, + tvb,offset,2,bo_big_endian); + offset+=2; + } + else { + count = tvb_length (tvb)-offset; + } + + if (pdut & WTLS_RECORD_TYPE_CIPHER_CUR) { + ti = proto_tree_add_item (wtls_rec_tree, hf_wtls_record_ciphered, + tvb,offset,count,bo_big_endian); + continue; + } + + switch (pdut & WTLS_RECORD_CONTENT_TYPE) { + case WTLS_PLAIN_HANDSHAKE : + dissect_wtls_handshake(wtls_rec_tree,tvb,offset,count); + break; + case WTLS_ALERT : + ti = proto_tree_add_item(wtls_rec_tree, hf_wtls_alert, tvb, offset, + count, bo_little_endian); + wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type); + pdu_msg_type = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item (wtls_msg_type_tree, hf_wtls_alert_level, + tvb,offset,1,bo_big_endian); + offset+=1; + count = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item (wtls_msg_type_tree, hf_wtls_alert_description, + tvb,offset,1,bo_big_endian); + offset+=1; + default: + offset+=count; + break; + } + } + } +} + +static void +dissect_wtls_handshake(proto_tree *tree, tvbuff_t *tvb, guint offset, guint count) +{ + char pdu_msg_type; + struct timeval timeValue; + int client_size = 0; + guint value = 0; + int size = 0; + guint public_key = 0; + guint signature = 0; + + proto_item *ti; + proto_item *cli_key_item; + proto_tree *wtls_msg_type_tree; + proto_tree *wtls_msg_type_item_tree; + proto_tree *wtls_msg_type_item_sub_tree; + proto_tree *wtls_msg_type_item_sub_sub_tree; + + ti = proto_tree_add_item(tree, hf_wtls_hands, tvb, offset,count, bo_little_endian); + wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type); + + pdu_msg_type = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_type, + tvb,offset,1,bo_big_endian); + offset+=1; + count = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_length, + tvb,offset,2,bo_big_endian); + offset+=2; + switch(pdu_msg_type) { + case WTLS_HANDSHAKE_CLIENT_HELLO : + ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_cli_hello, tvb, offset, + count, bo_little_endian); + wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); + ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_version, + tvb,offset,1,bo_big_endian); + offset++; + timeValue.tv_sec = tvb_get_ntohl (tvb, offset); + ti = proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_gmt, tvb, + offset, 4, &timeValue); + offset+=4; + ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_random, + tvb,offset,12,bo_big_endian); + offset+=12; + count = tvb_get_guint8(tvb, offset); + ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session, + tvb,offset,count+1,bo_big_endian); + offset+=1+count; + count = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_cli_hello_cli_key_id, tvb, offset, + count+2, bo_little_endian); + wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); + offset+=2; + for (;count > 0;count-=client_size) { + cli_key_item = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1, + bo_little_endian); + client_size=1; + wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, + ett_wtls_msg_type_item_sub_sub); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_key_exchange_suite, + tvb,offset,1,bo_big_endian); + offset++; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_key_parameter_index, + tvb,offset,1,bo_big_endian); + offset++; + client_size++; + if (value == 0xff) { + size = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_key_parameter_set, + tvb,offset,size+2,bo_big_endian); + offset+=size+2; + client_size+=size+2; + } + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_key_identifier_type, + tvb,offset,1,bo_big_endian); + offset++; + client_size++; + proto_item_set_len(cli_key_item, client_size); + } + count = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_cli_hello_trust_key_id, tvb, offset, + count+2, bo_little_endian); + wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); + offset+=2; + for (;count > 0;count-=client_size) { + cli_key_item = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1, + bo_little_endian); + client_size=1; + wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, + ett_wtls_msg_type_item_sub_sub); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_key_exchange_suite, + tvb,offset,1,bo_big_endian); + offset++; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_key_parameter_index, + tvb,offset,1,bo_big_endian); + offset++; + client_size++; + if (value == 0xff) { + size = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_key_parameter_set, + tvb,offset,size+2,bo_big_endian); + offset+=size+2; + client_size+=size+2; + } + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_key_identifier_type, + tvb,offset,1,bo_big_endian); + offset++; + client_size++; + proto_item_set_len(cli_key_item, client_size); + } + count = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_cli_hello_cipher_suite, tvb, offset, + count+1, bo_little_endian); + wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); + offset+=1; + for (;count > 0;count-=client_size) { + cli_key_item = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_cli_hello_cipher_suite_item, tvb, offset,1, + bo_little_endian); + client_size=1; + wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, + ett_wtls_msg_type_item_sub_sub); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_cipher_bulk, + tvb,offset,1,bo_big_endian); + offset++; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, + hf_wtls_hands_cli_hello_cipher_mac, + tvb,offset,1,bo_big_endian); + offset++; + client_size++; + proto_item_set_len(cli_key_item, client_size); + } + count = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_cli_hello_compression_methods, tvb, offset, + count+1, bo_little_endian); + wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); + offset+=1; + for (;count > 0;count-=client_size) { + client_size=0; + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_cli_hello_compression, tvb, offset,1, + bo_little_endian); + offset++; + client_size++; + } + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_cli_hello_sequence_mode, tvb, offset, + 1, bo_little_endian); + offset++; + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_cli_hello_key_refresh, tvb, offset, + 1, bo_little_endian); + break; + case WTLS_HANDSHAKE_SERVER_HELLO : + ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_serv_hello, tvb, offset, + count, bo_little_endian); + wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); + ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_version, + tvb,offset,1,bo_big_endian); + offset++; + timeValue.tv_sec = tvb_get_ntohl (tvb, offset); + ti = proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_gmt, tvb, + offset, 4, &timeValue); + offset+=4; + ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_random, + tvb,offset,12,bo_big_endian); + offset+=12; + count = tvb_get_guint8(tvb, offset); + ti = proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session, + tvb,offset,count+1,bo_big_endian); + offset+=1+count; + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_serv_hello_cli_key_id, + tvb,offset,1,bo_big_endian); + offset++; + cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_serv_hello_cipher_suite_item, tvb, offset,2, + bo_little_endian); + wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item, + ett_wtls_msg_type_item_sub); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_serv_hello_cipher_bulk, + tvb,offset,1,bo_big_endian); + offset++; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_serv_hello_cipher_mac, + tvb,offset,1,bo_big_endian); + offset++; + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_serv_hello_compression, tvb, offset,1, + bo_little_endian); + offset++; + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_serv_hello_sequence_mode, tvb, offset, + 1, bo_little_endian); + offset++; + ti = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_serv_hello_key_refresh, tvb, offset, + 1, bo_little_endian); + offset++; + break; + case WTLS_HANDSHAKE_CERTIFICATE : + ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_certificates, + tvb, offset,count, bo_little_endian); + wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); + count = tvb_get_ntohs (tvb, offset); + offset+=2; + for (;count > 0;count-=client_size) { + cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree, + hf_wtls_hands_certificate, tvb, offset,1, + bo_little_endian); + client_size=0; + wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item, + ett_wtls_msg_type_item_sub); + proto_item_set_len(cli_key_item, client_size); + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_type, tvb, offset,1, + bo_little_endian); + offset++; + client_size++; + switch(value) { + case CERTIFICATE_WTLS: + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_version, + tvb, offset,1, + bo_little_endian); + offset++; + client_size++; + signature = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_signature_type, + tvb, offset,1, + bo_little_endian); + offset++; + client_size++; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_issuer_type, + tvb, offset,1, + bo_little_endian); + offset++; + client_size++; + switch (value) { + case IDENTIFIER_NULL : + break; + case IDENTIFIER_TEXT : + ti = proto_tree_add_item( + wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_issuer_charset, + tvb, offset,2, + bo_big_endian); + offset+=2; + client_size+=2; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item( + wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_issuer_name, + tvb, offset,1+value, + bo_big_endian); + offset+=1+value; + client_size+=1+value; + break; + case IDENTIFIER_BIN : + break; + case IDENTIFIER_SHA_1 : + break; + case IDENTIFIER_X509 : + break; + } + timeValue.tv_sec = tvb_get_ntohl (tvb, offset); + ti = proto_tree_add_time (wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_valid_not_before, + tvb, offset, 4, &timeValue); + offset+=4; + client_size+=4; + timeValue.tv_sec = tvb_get_ntohl (tvb, offset); + ti = proto_tree_add_time (wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_valid_not_after, + tvb, offset, 4, &timeValue); + offset+=4; + client_size+=4; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_subject_type, + tvb, offset,1, + bo_little_endian); + offset++; + client_size++; + switch (value) { + case IDENTIFIER_NULL : + break; + case IDENTIFIER_TEXT : + ti = proto_tree_add_item( + wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_subject_charset, + tvb, offset,2, + bo_big_endian); + offset+=2; + client_size+=2; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item( + wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_subject_name, + tvb, offset,1+value, + bo_big_endian); + offset+=1+value; + client_size+=1+value; + break; + case IDENTIFIER_BIN : + break; + case IDENTIFIER_SHA_1 : + break; + case IDENTIFIER_X509 : + break; + } + public_key = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_public_key_type, + tvb, offset,1, + bo_little_endian); + offset++; + client_size++; + value = tvb_get_guint8 (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_key_parameter_index, + tvb,offset,1,bo_big_endian); + offset++; + client_size++; + if (value == 0xff) { + size = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_key_parameter_set, + tvb,offset,size+2,bo_big_endian); + offset+=size+2; + client_size+=size+2; + } + switch (public_key) { + case PUBLIC_KEY_RSA : + value = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_rsa_exponent, + tvb,offset,value+2,bo_big_endian); + offset+=2+value; + client_size+=2+value; + value = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_rsa_modules, + tvb,offset,value+2,bo_big_endian); + offset+=2+value; + client_size+=2+value; + break; + case PUBLIC_KEY_ECDH : + break; + case PUBLIC_KEY_ECDSA : + break; + } + value = tvb_get_ntohs (tvb, offset); + ti = proto_tree_add_item(wtls_msg_type_item_sub_tree, + hf_wtls_hands_certificate_wtls_signature, + tvb,offset,2+value,bo_big_endian); + offset+=2+value; + client_size+=2+value; + break; + case CERTIFICATE_X509: + case CERTIFICATE_X968: + value = tvb_get_ntohs (tvb, offset); + offset+=2; + client_size+=2; + client_size += value; + offset += value; + break; + case CERTIFICATE_URL: + value = tvb_get_guint8 (tvb, offset); + offset++; + client_size++; + client_size += value; + offset += value; + break; + } + proto_item_set_len(cli_key_item, client_size); + } + break; + default: + offset+=count; + break; + } +} + static void add_uri (proto_tree *tree, tvbuff_t *tvb, guint URILenOffset, guint URIOffset) { @@ -703,7 +1562,6 @@ add_headers (proto_tree *tree, tvbuff_t *tvb) #ifdef DEBUG fprintf (stderr, "dissect_wsp: Looking for %d octets\n", peek); #endif - valueStart++; valueEnd = offset+1+peek; offset += (peek+1); } @@ -789,35 +1647,78 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff) if (peek < 31) { /* Peek contains the number of octets to follow */ + value = tvb_get_guint8 (value_buff, 1); + /* decode Charset */ + if (value & 0x80) { + proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, value & 0x7f); + } + else if (value < 31) { + switch (value) + { + case 1: + proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_guint8 (value_buff, 2) ); + break; + case 2: + proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_ntohs (value_buff, 2) ); + break; + case 3: + proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, + (tvb_get_ntohs (value_buff, 2) << 8) + tvb_get_guint8 (value_buff, 4)); + break; + case 4: + proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_ntohl (value_buff, 2) ); + break; + default: + fprintf (stderr, "dissect_wsp: accept-charset size %d NYI\n", peek); + } + } + else { + fprintf (stderr, "dissect_wsp: Accept-Charset value %d (0x%02X) NYI\n", peek, value); + } + } + else if (peek & 0x80) + { + proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, (peek & 0x7F) ); + } + else + { + fprintf (stderr, "dissect_wsp: Accept-Charset value %d (0x%02X) NYI\n", peek, peek); + } + break; + + case 0x03: /* Accept-Language */ + if (peek < 31) + { + /* Peek contains the number of octets to follow */ switch (peek) { case 1: - proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_guint8 (value_buff, 1) ); + proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, + headerLen, tvb_get_guint8 (value_buff, 1) ); break; case 2: - proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_ntohs (value_buff, 1) ); + proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, + headerLen, tvb_get_ntohs (value_buff, 1) ); break; case 4: - proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, tvb_get_ntohl (value_buff, 1) ); + proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, + headerLen, tvb_get_ntohl (value_buff, 1) ); break; default: - fprintf (stderr, "dissect_wsp: accept-charset size %d NYI\n", peek); + fprintf (stderr, "dissect_wsp: accept-language size %d NYI\n", peek); } } else if (peek & 0x80) { - proto_tree_add_uint (tree, hf_wsp_header_accept_charset, header_buff, offset, headerLen, (peek & 0x7F) ); + proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, headerLen, (peek & 0x7F) ); } else { - fprintf (stderr, "dissect_wsp: Accept-Charset value %d (0x%02X) NYI\n", peek, peek); + proto_tree_add_string (tree, hf_wsp_header_accept_language_str, header_buff, offset,headerLen, + tvb_get_ptr (value_buff, 0, valueLen)); } break; - case 0x03: /* Accept-Language */ - proto_tree_add_uint (tree, hf_wsp_header_accept_language, header_buff, offset, headerLen, (peek & 0x7F)); - break; - case 0x04: /* Accept-Ranges */ if ((peek == 128) || (peek == 129)) { @@ -898,6 +1799,29 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff) { proto_tree_add_uint (tree, hf_wsp_header_content_length, header_buff, offset, headerLen, (peek & 0x7F)); } + else if (peek < 31) { + switch (peek) + { + case 1: + proto_tree_add_uint (tree, hf_wsp_header_content_length, header_buff, offset, headerLen, + tvb_get_guint8 (value_buff, 1) ); + break; + case 2: + proto_tree_add_uint (tree, hf_wsp_header_content_length, header_buff, offset, headerLen, + tvb_get_ntohs (value_buff, 1) ); + break; + case 3: + proto_tree_add_uint (tree, hf_wsp_header_content_length, header_buff, offset, headerLen, + (tvb_get_ntohs (value_buff, 1) << 8) + tvb_get_guint8 (value_buff, 3) ); + break; + case 4: + proto_tree_add_uint (tree, hf_wsp_header_content_length, header_buff, offset, headerLen, + tvb_get_ntohl (value_buff, 1) ); + break; + default: + fprintf (stderr, "dissect_wsp: accept-charset size %d NYI\n", peek); + } + } else { fprintf (stderr, "dissect_wsp: Content-Length long-integer size NYI\n"); @@ -966,10 +1890,27 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff) ti = proto_tree_add_string (tree, hf_wsp_header_server,header_buff,offset,headerLen,tvb_get_ptr (value_buff, 0, valueLen)); break; + case 0x27: /* Transfer encoding */ + if (peek & 0x80) + { + proto_tree_add_uint (tree, hf_wsp_header_transfer_encoding, header_buff, offset, headerLen, peek); + } + else + { + proto_tree_add_string (tree, hf_wsp_header_transfer_encoding_str, header_buff, offset,headerLen,tvb_get_ptr (value_buff, 0, valueLen)); + } + break; + + case 0x29: /* User-Agent */ ti = proto_tree_add_string (tree, hf_wsp_header_user_agent,header_buff,offset,headerLen,tvb_get_ptr (value_buff, 0, valueLen)); break; + case 0x2B: /* Via */ + ti = proto_tree_add_string (tree, hf_wsp_header_via,header_buff,offset,headerLen,tvb_get_ptr (value_buff, 0, valueLen)); + break; + + default: ti = proto_tree_add_text (tree, header_buff, 0, headerLen, "Unsupported Header (0x%02X)", (tvb_get_guint8 (header_buff, 0) & 0x7F)); break; @@ -981,15 +1922,25 @@ add_header (proto_tree *tree, tvbuff_t *header_buff, tvbuff_t *value_buff) * by a 4-byte date value */ if (strncasecmp ("x-wap.tod", tvb_get_ptr (header_buff, 0, headerLen), 9) == 0) { - if (tvb_reported_length (value_buff) == 4) /* Probably a date value */ - { - timeValue.tv_sec = tvb_get_ntohl (value_buff, 0); - ti = proto_tree_add_time (tree, hf_wsp_header_x_wap_tod, header_buff, offset, headerLen, &timeValue); - } - else - { - ti = proto_tree_add_text (tree, header_buff, 0, headerLen, "%s: %s", tvb_get_ptr (header_buff, 0, headerLen), tvb_get_ptr (value_buff, 0, valueLen)); + switch( peek) { + case 1: + timeValue.tv_sec = tvb_get_guint8 (value_buff, 1); + break; + case 2: + timeValue.tv_sec = tvb_get_ntohs (value_buff, 1); + break; + case 3: + timeValue.tv_sec = (tvb_get_ntohs (value_buff, 1) << 8) + tvb_get_guint8 (value_buff, 3); + break; + case 4: + timeValue.tv_sec = tvb_get_ntohl (value_buff, 1); + break; + default: + timeValue.tv_sec = 0; + fprintf (stderr, "dissect_wsp: x-wap-top unkown\n"); + break; } + ti = proto_tree_add_time (tree, hf_wsp_header_x_wap_tod, header_buff, offset, headerLen, &timeValue); } else { @@ -1115,7 +2066,7 @@ add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType) guint8 peek = 0; proto_item *ti; - ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,END_OF_FRAME,bo_little_endian); + ti = proto_tree_add_item (tree, hf_wsp_post_data,tvb,offset,tvb_reported_length(tvb),bo_little_endian); if (contentType == 0x12) /* URL Encoded data */ { @@ -1337,6 +2288,13 @@ proto_register_wsp(void) "Accept-Language" } }, + { &hf_wsp_header_accept_language_str, + { "Accept-Language", + "wsp.header.accept-language.string", + FT_STRING, BASE_NONE, NULL, 0x00, + "Accept-Language" + } + }, { &hf_wsp_header_accept_ranges, { "Accept-Ranges", "wsp.header.accept-ranges", @@ -1452,6 +2410,440 @@ proto_register_wsp(void) "Post Data" } }, + { &hf_wtls_record, + { "Record", + "wsp.wtls.record", + FT_NONE, BASE_NONE, NULL, 0x00, + "Record" + } + }, + { &hf_wtls_record_type, + { "Record Type", + "wsp.wtls.rec_type", + FT_UINT8, BASE_DEC, VALS ( wtls_vals_record_type ), 0x0f, + "Record Type" + } + }, + { &hf_wtls_record_length, + { "Record Length", + "wsp.wtls.rec_length", + FT_UINT16, BASE_DEC, NULL, 0x00, + "Record Length" + } + }, + { &hf_wtls_record_sequence, + { "Record Sequence", + "wsp.wtls.rec_seq", + FT_UINT16, BASE_DEC, NULL, 0x00, + "Record Sequence" + } + }, + { &hf_wtls_record_ciphered, + { "Record Ciphered", + "wsp.wtls.rec_cipher", + FT_NONE, BASE_DEC, NULL, 0x00, + "Record Ciphered" + } + }, + { &hf_wtls_hands, + { "Handshake", + "wsp.wtls.handshake", + FT_NONE, BASE_DEC, NULL, 0x00, + "Handshake" + } + }, + { &hf_wtls_hands_type, + { "Type", + "wsp.wtls.handshake.type", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_handshake_type ), 0x00, + "Type" + } + }, + { &hf_wtls_hands_length, + { "Length", + "wsp.wtls.handshake.length", + FT_UINT16, BASE_DEC, NULL, 0x00, + "Length" + } + }, + { &hf_wtls_hands_cli_hello, + { "Client Hello", + "wsp.wtls.handshake.client_hello", + FT_NONE, BASE_NONE,NULL, 0x00, + "Client Hello" + } + }, + { &hf_wtls_hands_cli_hello_version, + { "Version", + "wsp.wtls.handshake.client_hello.version", + FT_UINT8, BASE_DEC, NULL, 0x00, + "Version" + } + }, + { &hf_wtls_hands_cli_hello_gmt, + { "Time GMT", + "wsp.wtls.handshake.client_hello.gmt", + FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, + "Time GMT" + } + }, + { &hf_wtls_hands_cli_hello_random, + { "Random", + "wsp.wtls.handshake.client_hello.random", + FT_NONE, BASE_DEC, NULL, 0x00, + "Random" + } + }, + { &hf_wtls_hands_cli_hello_session, + { "Session ID", + "wsp.wtls.handshake.client_hello.sessionid", + FT_NONE, BASE_DEC, NULL, 0x00, + "Session ID" + } + }, + { &hf_wtls_hands_cli_hello_cli_key_id, + { "Client Keys", + "wsp.wtls.handshake.client_hello.client_keys_id", + FT_NONE, BASE_DEC, NULL, 0x00, + "Client Keys" + } + }, + { &hf_wtls_hands_cli_hello_trust_key_id, + { "Trusted Keys", + "wsp.wtls.handshake.client_hello.trusted_keys_id", + FT_NONE, BASE_DEC, NULL, 0x00, + "Trusted Keys" + } + }, + { &hf_wtls_hands_cli_hello_key_exchange, + { "Key Exchange", + "wsp.wtls.handshake.client_hello.key.key_exchange", + FT_NONE, BASE_NONE, NULL, 0x00, + "Key Exchange" + } + }, + { &hf_wtls_hands_cli_hello_key_exchange_suite, + { "Suite", + "wsp.wtls.handshake.client_hello.key.key_exchange.suite", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_key_exchange_suite ), 0x00, + "Suite" + } + }, + { &hf_wtls_hands_cli_hello_key_parameter_index, + { "Parameter Index", + "wsp.wtls.handshake.client_hello.parameter_index", + FT_UINT8, BASE_DEC, NULL, 0x00, + "Parameter Index" + } + }, + { &hf_wtls_hands_cli_hello_key_parameter_set, + { "Parameter Set", + "wsp.wtls.handshake.client_hello.parameter", + FT_STRING, BASE_NONE, NULL, 0x00, + "Parameter Set" + } + }, + { &hf_wtls_hands_cli_hello_key_identifier_type, + { "Identifier Type", + "wsp.wtls.handshake.client_hello.ident_type", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_identifier_type ), 0x00, + "Identifier Type" + } + }, + { &hf_wtls_hands_cli_hello_cipher_suite, + { "Cipher Suites", + "wsp.wtls.handshake.client_hello.ciphers", + FT_NONE, BASE_DEC, NULL, 0x00, + "Cipher Suite" + } + }, + { &hf_wtls_hands_cli_hello_cipher_suite_item, + { "Cipher", + "wsp.wtls.handshake.client_hello.cipher", + FT_NONE, BASE_DEC, NULL, 0x00, + "Cipher" + } + }, + { &hf_wtls_hands_cli_hello_cipher_bulk, + { "Cipher Bulk", + "wsp.wtls.handshake.client_hello.cipher.bulk", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_cipher_bulk ), 0x00, + "Cipher Bulk" + } + }, + { &hf_wtls_hands_cli_hello_cipher_mac, + { "Cipher MAC", + "wsp.wtls.handshake.client_hello.cipher.mac", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_cipher_mac ), 0x00, + "Cipher MAC" + } + }, + { &hf_wtls_hands_cli_hello_compression_methods, + { "Compression Methods", + "wsp.wtls.handshake.client_hello.comp_methods", + FT_NONE, BASE_DEC, NULL, 0x00, + "Compression Methods" + } + }, + { &hf_wtls_hands_cli_hello_compression, + { "Compression", + "wsp.wtls.handshake.client_hello.compression", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_compression ), 0x00, + "Compression" + } + }, + { &hf_wtls_hands_cli_hello_sequence_mode, + { "Sequence Mode", + "wsp.wtls.handshake.client_hello.sequence_mode", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_sequence_mode ), 0x00, + "Sequence Mode" + } + }, + { &hf_wtls_hands_cli_hello_key_refresh, + { "Refresh", + "wsp.wtls.handshake.client_hello.refresh", + FT_UINT8, BASE_DEC,NULL, 0x00, + "Refresh" + } + }, + { &hf_wtls_hands_serv_hello, + { "Server Hello", + "wsp.wtls.handshake.server_hello", + FT_NONE, BASE_NONE,NULL, 0x00, + "Server Hello" + } + }, + { &hf_wtls_hands_serv_hello_version, + { "Version", + "wsp.wtls.handshake.server_hello.version", + FT_UINT8, BASE_DEC, NULL, 0x00, + "Version" + } + }, + { &hf_wtls_hands_serv_hello_gmt, + { "Time GMT", + "wsp.wtls.handshake.server_hello.gmt", + FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, + "Time GMT" + } + }, + { &hf_wtls_hands_serv_hello_random, + { "Random", + "wsp.wtls.handshake.server_hello.random", + FT_NONE, BASE_DEC, NULL, 0x00, + "Random" + } + }, + { &hf_wtls_hands_serv_hello_session, + { "Session ID", + "wsp.wtls.handshake.server_hello.sessionid", + FT_NONE, BASE_DEC, NULL, 0x00, + "Session ID" + } + }, + { &hf_wtls_hands_serv_hello_cli_key_id, + { "Client Key ID", + "wsp.wtls.handshake.server_hello.key", + FT_UINT8, BASE_HEX, NULL, 0x00, + "Client Key ID" + } + }, + { &hf_wtls_hands_serv_hello_cipher_suite_item, + { "Cipher", + "wsp.wtls.handshake.server_hello.cipher", + FT_NONE, BASE_DEC, NULL, 0x00, + "Cipher" + } + }, + { &hf_wtls_hands_serv_hello_cipher_bulk, + { "Cipher Bulk", + "wsp.wtls.handshake.server_hello.cipher.bulk", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_cipher_bulk ), 0x00, + "Cipher Bulk" + } + }, + { &hf_wtls_hands_serv_hello_cipher_mac, + { "Cipher MAC", + "wsp.wtls.handshake.server_hello.cipher.mac", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_cipher_mac ), 0x00, + "Cipher MAC" + } + }, + { &hf_wtls_hands_serv_hello_compression, + { "Compression", + "wsp.wtls.handshake.server_hello.compression", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_compression ), 0x00, + "Compression" + } + }, + { &hf_wtls_hands_serv_hello_sequence_mode, + { "Sequence Mode", + "wsp.wtls.handshake.server_hello.sequence_mode", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_sequence_mode ), 0x00, + "Sequence Mode" + } + }, + { &hf_wtls_hands_serv_hello_key_refresh, + { "Refresh", + "wsp.wtls.handshake.server_hello.refresh", + FT_UINT8, BASE_DEC,NULL, 0x00, + "Refresh" + } + }, + { &hf_wtls_hands_certificates, + { "Certificates", + "wsp.wtls.handshake.certificates", + FT_NONE, BASE_DEC, NULL, 0x00, + "Certificates" + } + }, + { &hf_wtls_hands_certificate, + { "Certificate", + "wsp.wtls.handshake.certificate", + FT_NONE, BASE_DEC, NULL, 0x00, + "Certificate" + } + }, + { &hf_wtls_hands_certificate_type, + { "Type", + "wsp.wtls.handshake.certificate.type", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_certificate_type ), 0x00, + "Type" + } + }, + { &hf_wtls_hands_certificate_wtls_version, + { "Version", + "wsp.wtls.handshake.certificate.version", + FT_UINT8, BASE_HEX, NULL, 0x00, + "Version" + } + }, + { &hf_wtls_hands_certificate_wtls_signature_type, + { "Signature Type", + "wsp.wtls.handshake.certificate.signature.type", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_certificate_signature ), 0x00, + "Signature Type" + } + }, + { &hf_wtls_hands_certificate_wtls_signature, + { "Signature", + "wsp.wtls.handshake.certificate.signature.signature", + FT_NONE, BASE_HEX, NULL, 0x00, + "Signature" + } + }, + { &hf_wtls_hands_certificate_wtls_issuer_type, + { "Issuer", + "wsp.wtls.handshake.certificate.issuer.type", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_identifier_type ), 0x00, + "Issuer" + } + }, + { &hf_wtls_hands_certificate_wtls_issuer_charset, + { "Charset", + "wsp.wtls.handshake.certificate.issuer.charset", + FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00, + "Charset" + } + }, + { &hf_wtls_hands_certificate_wtls_issuer_name, + { "Name", + "wsp.wtls.handshake.certificate.issuer.name", + FT_NONE, BASE_HEX, NULL, 0x00, + "Name" + } + }, + { &hf_wtls_hands_certificate_wtls_valid_not_before, + { "Valid not before", + "wsp.wtls.handshake.certificate.before", + FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, + "Valid not before" + } + }, + { &hf_wtls_hands_certificate_wtls_valid_not_after, + { "Valid not after", + "wsp.wtls.handshake.certificate.after", + FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, + "Valid not after" + } + }, + { &hf_wtls_hands_certificate_wtls_subject_type, + { "Subject", + "wsp.wtls.handshake.certificate.subject.type", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_identifier_type ), 0x00, + "Subject" + } + }, + { &hf_wtls_hands_certificate_wtls_subject_charset, + { "Charset", + "wsp.wtls.handshake.certificate.subject.charset", + FT_UINT16, BASE_HEX, VALS ( vals_character_sets ), 0x00, + "Charset" + } + }, + { &hf_wtls_hands_certificate_wtls_subject_name, + { "Name", + "wsp.wtls.handshake.certificate.subject.name", + FT_NONE, BASE_HEX, NULL, 0x00, + "Name" + } + }, + { &hf_wtls_hands_certificate_wtls_public_key_type, + { "Public Key Type", + "wsp.wtls.handshake.certificate.public.type", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_public_key_type ), 0x00, + "Public Key Type" + } + }, + { &hf_wtls_hands_certificate_wtls_key_parameter_index, + { "Parameter Index", + "wsp.wtls.handshake.certificate.parameter_index", + FT_UINT8, BASE_DEC, NULL, 0x00, + "Parameter Index" + } + }, + { &hf_wtls_hands_certificate_wtls_key_parameter_set, + { "Parameter Set", + "wsp.wtls.handshake.certificate.parameter", + FT_STRING, BASE_NONE, NULL, 0x00, + "Parameter Set" + } + }, + { &hf_wtls_hands_certificate_wtls_rsa_exponent, + { "RSA Exponent", + "wsp.wtls.handshake.certificate.rsa.exponent", + FT_NONE, BASE_HEX, NULL, 0x00, + "RSA Exponent" + } + }, + { &hf_wtls_hands_certificate_wtls_rsa_modules, + { "RSA Modulus", + "wsp.wtls.handshake.certificate.rsa.modulus", + FT_NONE, BASE_HEX, NULL, 0x00, + "RSA Modulus" + } + }, + { &hf_wtls_alert, + { "Alert", + "wsp.wtls.alert", + FT_NONE, BASE_HEX, NULL, 0x00, + "Alert" + } + }, + { &hf_wtls_alert_level, + { "Level", + "wsp.wtls.alert.level", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_alert_level ), 0x00, + "Level" + } + }, + { &hf_wtls_alert_description, + { "Description", + "wsp.wtls.alert.description", + FT_UINT8, BASE_HEX, VALS ( wtls_vals_alert_description ), 0x00, + "Description" + } + }, }; /* Setup protocol subtree array */ @@ -1461,6 +2853,11 @@ proto_register_wsp(void) &ett_headers, &ett_capabilities, &ett_content_type, + &ett_wtls_rec, + &ett_wtls_msg_type, + &ett_wtls_msg_type_item, + &ett_wtls_msg_type_item_sub, + &ett_wtls_msg_type_item_sub_sub, }; /* Register the protocol name and description */ @@ -1472,11 +2869,20 @@ proto_register_wsp(void) */ ); + proto_wtls = proto_register_protocol( + "Wireless Transport Layer Security", /* protocol name for use by ethereal */ + "WTLS", /* short version of name */ + "wap-wtls" /* Abbreviated protocol name, should Match IANA + < URL:http://www.isi.edu/in-notes/iana/assignments/port-numbers/ > + */ + ); + /* Required function calls to register the header fields and subtrees used */ proto_register_field_array(proto_wsp, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); register_dissector("wsp", dissect_wsp, proto_wsp); + register_dissector("wtls", dissect_wtls, proto_wtls); }; void @@ -1485,6 +2891,6 @@ proto_reg_handoff_wsp(void) /* Only connection-less WSP has no previous handler */ dissector_add("udp.port", UDP_PORT_WSP, dissect_wsp, proto_wsp); /* dissector_add("udp.port", UDP_PORT_WTP_WSP, dissect_wsp, proto_wsp); */ - /* dissector_add("udp.port", UDP_PORT_WTLS_WSP, dissect_wsp, proto_wsp); */ + dissector_add("udp.port", UDP_PORT_WTLS_WSP, dissect_wtls, proto_wtls); /* dissector_add("udp.port", UDP_PORT_WTLS_WTP_WSP, dissect_wsp, proto_wsp); */ } |