summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Meier <wmeier@newsguy.com>2011-12-29 20:23:18 +0000
committerBill Meier <wmeier@newsguy.com>2011-12-29 20:23:18 +0000
commitab5ead6bb0c3b7d76c9936f5f9b2c0889fe6ebc1 (patch)
tree931a7e3c736787f65519262997523c9c380ecf14
parent96151f1910ee8c50cdc7a7373362d469ccc7a53a (diff)
downloadwireshark-ab5ead6bb0c3b7d76c9936f5f9b2c0889fe6ebc1.tar.gz
Do whitespace cleanup; Reformat long lines;
Move proto_register...() to be near the end of the file. svn path=/trunk/; revision=40327
-rw-r--r--epan/dissectors/packet-dtls.c605
1 files changed, 315 insertions, 290 deletions
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c
index 093070211d..caf9895c29 100644
--- a/epan/dissectors/packet-dtls.c
+++ b/epan/dissectors/packet-dtls.c
@@ -28,11 +28,13 @@
* See RFC 4347 for details about DTLS specs.
*
* Notes :
- * This dissector is based on TLS one (packet-ssl.c) because of the proximity of DTLS and TLS, decryption works like him with RSA key exchange.
- * It uses the sames things (file, libraries) that SSL one (gnutls, packet-ssl-utils.h) to make it easily maintenable.
+ * This dissector is based on the TLS dissector (packet-ssl.c); Because of the similarity
+ * of DTLS and TLS, decryption works like TLS with RSA key exchange.
+ * This dissector uses the sames things (file, libraries) as the SSL dissector (gnutls, packet-ssl-utils.h)
+ * to make it easily maintainable.
*
- * It was developped to dissect and decrypt OpenSSL v 0.9.8f DTLS implementation.
- * It is limited to this implementation while there is no complete implementation.
+ * It was developed to dissect and decrypt the OpenSSL v 0.9.8f DTLS implementation.
+ * It is limited to this implementation; there is no complete implementation.
*
* Implemented :
* - DTLS dissection
@@ -93,68 +95,68 @@ static proto_tree *top_tree;
*********************************************************************/
/* Initialize the protocol and registered fields */
-static gint dtls_tap = -1;
-static gint proto_dtls = -1;
-static gint hf_dtls_record = -1;
-static gint hf_dtls_record_content_type = -1;
-static gint hf_dtls_record_version = -1;
-static gint hf_dtls_record_epoch = -1;
-static gint hf_dtls_record_sequence_number = -1;
-static gint hf_dtls_record_length = -1;
-static gint hf_dtls_record_appdata = -1;
-static gint hf_dtls_change_cipher_spec = -1;
-static gint hf_dtls_alert_message = -1;
-static gint hf_dtls_alert_message_level = -1;
-static gint hf_dtls_alert_message_description = -1;
-static gint hf_dtls_handshake_protocol = -1;
-static gint hf_dtls_handshake_type = -1;
-static gint hf_dtls_handshake_length = -1;
-static gint hf_dtls_handshake_message_seq = -1;
-static gint hf_dtls_handshake_fragment_offset = -1;
-static gint hf_dtls_handshake_fragment_length = -1;
-static gint hf_dtls_handshake_client_version = -1;
-static gint hf_dtls_handshake_server_version = -1;
-static gint hf_dtls_handshake_random_time = -1;
-static gint hf_dtls_handshake_random_bytes = -1;
-static gint hf_dtls_handshake_cookie_len = -1;
-static gint hf_dtls_handshake_cookie = -1;
+static gint dtls_tap = -1;
+static gint proto_dtls = -1;
+static gint hf_dtls_record = -1;
+static gint hf_dtls_record_content_type = -1;
+static gint hf_dtls_record_version = -1;
+static gint hf_dtls_record_epoch = -1;
+static gint hf_dtls_record_sequence_number = -1;
+static gint hf_dtls_record_length = -1;
+static gint hf_dtls_record_appdata = -1;
+static gint hf_dtls_change_cipher_spec = -1;
+static gint hf_dtls_alert_message = -1;
+static gint hf_dtls_alert_message_level = -1;
+static gint hf_dtls_alert_message_description = -1;
+static gint hf_dtls_handshake_protocol = -1;
+static gint hf_dtls_handshake_type = -1;
+static gint hf_dtls_handshake_length = -1;
+static gint hf_dtls_handshake_message_seq = -1;
+static gint hf_dtls_handshake_fragment_offset = -1;
+static gint hf_dtls_handshake_fragment_length = -1;
+static gint hf_dtls_handshake_client_version = -1;
+static gint hf_dtls_handshake_server_version = -1;
+static gint hf_dtls_handshake_random_time = -1;
+static gint hf_dtls_handshake_random_bytes = -1;
+static gint hf_dtls_handshake_cookie_len = -1;
+static gint hf_dtls_handshake_cookie = -1;
static gint hf_dtls_handshake_cipher_suites_len = -1;
-static gint hf_dtls_handshake_cipher_suites = -1;
-static gint hf_dtls_handshake_cipher_suite = -1;
-static gint hf_dtls_handshake_session_id = -1;
-static gint hf_dtls_handshake_comp_methods_len = -1;
-static gint hf_dtls_handshake_comp_methods = -1;
-static gint hf_dtls_handshake_comp_method = -1;
-static gint hf_dtls_handshake_extensions_len = -1;
-static gint hf_dtls_handshake_extension_type = -1;
-static gint hf_dtls_handshake_extension_len = -1;
-static gint hf_dtls_handshake_extension_data = -1;
-static gint hf_dtls_handshake_certificates_len = -1;
-static gint hf_dtls_handshake_certificates = -1;
-static gint hf_dtls_handshake_certificate = -1;
-static gint hf_dtls_handshake_certificate_len = -1;
-static gint hf_dtls_handshake_cert_types_count = -1;
-static gint hf_dtls_handshake_cert_types = -1;
-static gint hf_dtls_handshake_cert_type = -1;
-static gint hf_dtls_handshake_finished = -1;
-static gint hf_dtls_handshake_md5_hash = -1;
-static gint hf_dtls_handshake_sha_hash = -1;
-static gint hf_dtls_handshake_session_id_len = -1;
-static gint hf_dtls_handshake_dnames_len = -1;
-static gint hf_dtls_handshake_dnames = -1;
-static gint hf_dtls_handshake_dname_len = -1;
-static gint hf_dtls_handshake_dname = -1;
-
-static gint hf_dtls_fragments = -1;
-static gint hf_dtls_fragment = -1;
-static gint hf_dtls_fragment_overlap = -1;
-static gint hf_dtls_fragment_overlap_conflicts = -1;
-static gint hf_dtls_fragment_multiple_tails = -1;
-static gint hf_dtls_fragment_too_long_fragment = -1;
-static gint hf_dtls_fragment_error = -1;
-static gint hf_dtls_fragment_count = -1;
-static gint hf_dtls_reassembled_in = -1;
-static gint hf_dtls_reassembled_length = -1;
+static gint hf_dtls_handshake_cipher_suites = -1;
+static gint hf_dtls_handshake_cipher_suite = -1;
+static gint hf_dtls_handshake_session_id = -1;
+static gint hf_dtls_handshake_comp_methods_len = -1;
+static gint hf_dtls_handshake_comp_methods = -1;
+static gint hf_dtls_handshake_comp_method = -1;
+static gint hf_dtls_handshake_extensions_len = -1;
+static gint hf_dtls_handshake_extension_type = -1;
+static gint hf_dtls_handshake_extension_len = -1;
+static gint hf_dtls_handshake_extension_data = -1;
+static gint hf_dtls_handshake_certificates_len = -1;
+static gint hf_dtls_handshake_certificates = -1;
+static gint hf_dtls_handshake_certificate = -1;
+static gint hf_dtls_handshake_certificate_len = -1;
+static gint hf_dtls_handshake_cert_types_count = -1;
+static gint hf_dtls_handshake_cert_types = -1;
+static gint hf_dtls_handshake_cert_type = -1;
+static gint hf_dtls_handshake_finished = -1;
+static gint hf_dtls_handshake_md5_hash = -1;
+static gint hf_dtls_handshake_sha_hash = -1;
+static gint hf_dtls_handshake_session_id_len = -1;
+static gint hf_dtls_handshake_dnames_len = -1;
+static gint hf_dtls_handshake_dnames = -1;
+static gint hf_dtls_handshake_dname_len = -1;
+static gint hf_dtls_handshake_dname = -1;
+
+static gint hf_dtls_fragments = -1;
+static gint hf_dtls_fragment = -1;
+static gint hf_dtls_fragment_overlap = -1;
+static gint hf_dtls_fragment_overlap_conflicts = -1;
+static gint hf_dtls_fragment_multiple_tails = -1;
+static gint hf_dtls_fragment_too_long_fragment = -1;
+static gint hf_dtls_fragment_error = -1;
+static gint hf_dtls_fragment_count = -1;
+static gint hf_dtls_reassembled_in = -1;
+static gint hf_dtls_reassembled_length = -1;
/* Initialize the subtree pointers */
static gint ett_dtls = -1;
@@ -171,19 +173,19 @@ static gint ett_dtls_dnames = -1;
static gint ett_dtls_fragment = -1;
static gint ett_dtls_fragments = -1;
-static GHashTable *dtls_session_hash = NULL;
-static GHashTable *dtls_key_hash = NULL;
-static GHashTable *dtls_fragment_table = NULL;
-static GTree* dtls_associations = NULL;
-static dissector_handle_t dtls_handle = NULL;
-static StringInfo dtls_compressed_data = {NULL, 0};
-static StringInfo dtls_decrypted_data = {NULL, 0};
-static gint dtls_decrypted_data_avail = 0;
-
-static uat_t *dtlsdecrypt_uat = NULL;
-static gchar* dtls_keys_list = NULL;
+static GHashTable *dtls_session_hash = NULL;
+static GHashTable *dtls_key_hash = NULL;
+static GHashTable *dtls_fragment_table = NULL;
+static GTree* dtls_associations = NULL;
+static dissector_handle_t dtls_handle = NULL;
+static StringInfo dtls_compressed_data = {NULL, 0};
+static StringInfo dtls_decrypted_data = {NULL, 0};
+static gint dtls_decrypted_data_avail = 0;
+
+static uat_t *dtlsdecrypt_uat = NULL;
+static gchar *dtls_keys_list = NULL;
#ifdef HAVE_LIBGNUTLS
-static gchar* dtls_debug_file_name = NULL;
+static gchar *dtls_debug_file_name = NULL;
#endif
static heur_dissector_list_t heur_subdissector_list;
@@ -214,7 +216,7 @@ static void
dtls_init(void)
{
module_t *dtls_module = prefs_find_module("dtls");
- pref_t *keys_list_pref;
+ pref_t *keys_list_pref;
ssl_common_init(&dtls_session_hash, &dtls_decrypted_data, &dtls_compressed_data);
fragment_table_init (&dtls_fragment_table);
@@ -232,11 +234,11 @@ dtls_init(void)
static void
dtls_parse(void)
{
- ep_stack_t tmp_stack;
- SslAssociation *tmp_assoc;
- guint i;
- gchar **old_keys, **parts, *err;
- GString *uat_entry = g_string_new("");
+ ep_stack_t tmp_stack;
+ SslAssociation *tmp_assoc;
+ guint i;
+ gchar **old_keys, **parts, *err;
+ GString *uat_entry = g_string_new("");
if (dtls_key_hash)
{
@@ -257,12 +259,12 @@ dtls_parse(void)
for (i = 0; old_keys[i] != NULL; i++) {
parts = g_strsplit(old_keys[i], ",", 4);
if (parts[0] && parts[1] && parts[2] && parts[3]) {
- g_string_printf(uat_entry, "\"%s\",\"%s\",\"%s\",\"%s\",\"\"",
- parts[0], parts[1], parts[2], parts[3]);
- if (!uat_load_str(dtlsdecrypt_uat, uat_entry->str, &err)) {
- ssl_debug_printf("dtls_parse: Can't load UAT string %s: %s\n",
+ g_string_printf(uat_entry, "\"%s\",\"%s\",\"%s\",\"%s\",\"\"",
+ parts[0], parts[1], parts[2], parts[3]);
+ if (!uat_load_str(dtlsdecrypt_uat, uat_entry->str, &err)) {
+ ssl_debug_printf("dtls_parse: Can't load UAT string %s: %s\n",
uat_entry->str, err);
- }
+ }
}
g_strfreev(parts);
}
@@ -278,11 +280,11 @@ dtls_parse(void)
if (ndtlsdecrypt > 0)
{
- for (i = 0; i < ndtlsdecrypt; i++)
- {
- ssldecrypt_assoc_t *d = &(dtlskeylist_uats[i]);
- ssl_parse_key_list(d, dtls_key_hash, dtls_associations, dtls_handle, FALSE);
- }
+ for (i = 0; i < ndtlsdecrypt; i++)
+ {
+ ssldecrypt_assoc_t *d = &(dtlskeylist_uats[i]);
+ ssl_parse_key_list(d, dtls_key_hash, dtls_associations, dtls_handle, FALSE);
+ }
}
dissector_add_handle("sctp.port", dtls_handle);
@@ -369,20 +371,21 @@ static void
dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- conversation_t *conversation;
- void *conv_data;
- proto_item *ti;
- proto_tree *dtls_tree;
- guint32 offset;
- gboolean first_record_in_frame;
- SslDecryptSession* ssl_session;
- guint* conv_version;
- ti = NULL;
- dtls_tree = NULL;
- offset = 0;
+ conversation_t *conversation;
+ void *conv_data;
+ proto_item *ti;
+ proto_tree *dtls_tree;
+ guint32 offset;
+ gboolean first_record_in_frame;
+ SslDecryptSession *ssl_session;
+ guint* conv_version;
+
+ ti = NULL;
+ dtls_tree = NULL;
+ offset = 0;
first_record_in_frame = TRUE;
- ssl_session = NULL;
- top_tree=tree;
+ ssl_session = NULL;
+ top_tree = tree;
/* Track the version using conversations allows
* us to more frequently set the protocol column properly
@@ -395,7 +398,7 @@ dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* in addition to conv_version
*/
conversation = find_or_create_conversation(pinfo);
- conv_data = conversation_get_proto_data(conversation, proto_dtls);
+ conv_data = conversation_get_proto_data(conversation, proto_dtls);
/* manage dtls decryption data */
/*get a valid ssl session pointer*/
@@ -505,13 +508,69 @@ dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tap_queue_packet(dtls_tap, pinfo, NULL);
}
+static gboolean
+dissect_dtls_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ /* Stronger confirmation of DTLS packet is provided by verifying the
+ * payload length against the remainder of the UDP packet size. */
+ guint length = tvb_length(tvb);
+ guint offset = 0;
+
+ if (tvb_reported_length(tvb) == length) {
+ while (offset + 13 <= length && looks_like_dtls(tvb, offset)) {
+ /* Advance offset to the end of the current DTLS record */
+ offset += tvb_get_ntohs(tvb, offset + 11) + 13;
+ if (offset == length) {
+ dissect_dtls(tvb, pinfo, tree);
+ return TRUE;
+ }
+ }
+
+ if (pinfo->fragmented && offset >= 13) {
+ dissect_dtls(tvb, pinfo, tree);
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /* We've got a truncated packet - do our best with what we've got. */
+ while (tvb_length_remaining(tvb, offset) >= 3) {
+ if (!looks_like_dtls(tvb, offset))
+ return FALSE;
+
+ offset += 3;
+ if (tvb_length_remaining(tvb, offset) >= 10 ) {
+ offset += tvb_get_ntohs(tvb, offset + 8) + 10;
+ } else {
+ /* Dissect what we've got, which might be as little as 3 bytes. */
+ dissect_dtls(tvb, pinfo, tree);
+ return TRUE;
+ }
+ if (offset == length) {
+ /* Can this ever happen? Well, just in case ... */
+ dissect_dtls(tvb, pinfo, tree);
+ return TRUE;
+ }
+ }
+
+ /* One last check to see if the current offset is at least less than the
+ * original number of bytes present before truncation or we're dealing with
+ * a packet fragment that's also been truncated. */
+ if ((length >= 3) && (offset <= tvb_reported_length(tvb) || pinfo->fragmented)) {
+ dissect_dtls(tvb, pinfo, tree);
+ return TRUE;
+ }
+ return FALSE;
+}
+
static gint
decrypt_dtls_record(tvbuff_t *tvb, packet_info *pinfo, guint32 offset,
guint32 record_length, guint8 content_type, SslDecryptSession* ssl,
gboolean save_plaintext)
{
- gint ret;
- SslDecoder* decoder;
+ gint ret;
+ SslDecoder *decoder;
+
ret = 0;
/* if we can decrypt and decryption have success
@@ -548,8 +607,8 @@ decrypt_dtls_record(tvbuff_t *tvb, packet_info *pinfo, guint32 offset,
* is successful*/
dtls_decrypted_data_avail = dtls_decrypted_data.data_len;
if (ssl->state & SSL_HAVE_SESSION_KEY) {
- if (ssl_decrypt_record(ssl, decoder, content_type, tvb_get_ptr(tvb, offset, record_length),
- record_length, &dtls_compressed_data, &dtls_decrypted_data, &dtls_decrypted_data_avail) == 0)
+ if (ssl_decrypt_record(ssl, decoder, content_type, tvb_get_ptr(tvb, offset, record_length), record_length,
+ &dtls_compressed_data, &dtls_decrypted_data, &dtls_decrypted_data_avail) == 0)
ret = 1;
}
else if (ssl->cipher == 0x0001 || ssl->cipher == 0x0002) {
@@ -560,7 +619,8 @@ decrypt_dtls_record(tvbuff_t *tvb, packet_info *pinfo, guint32 offset,
}
if (ret && save_plaintext) {
- ssl_add_data_info(proto_dtls, pinfo, dtls_decrypted_data.data, dtls_decrypted_data_avail, tvb_raw_offset(tvb)+offset, 0);
+ ssl_add_data_info(proto_dtls, pinfo, dtls_decrypted_data.data, dtls_decrypted_data_avail,
+ tvb_raw_offset(tvb)+offset, 0);
}
return ret;
@@ -596,37 +656,39 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
* struct {
* ContentType type;
* ProtocolVersion version;
- * uint16 epoch; // New field
- * uint48 sequence_number; // New field
+ * uint16 epoch; // New field
+ * uint48 sequence_number; // New field
* uint16 length;
* opaque fragment[TLSPlaintext.length];
* } DTLSPlaintext;
*/
- guint32 record_length;
- guint16 version;
- guint16 epoch;
- gdouble sequence_number;
- gint64 sequence_number_temp;
- guint8 content_type;
- guint8 next_byte;
- proto_tree *ti;
- proto_tree *dtls_record_tree;
- SslAssociation* association;
- SslDataInfo *appl_data;
- ti = NULL;
+
+ guint32 record_length;
+ guint16 version;
+ guint16 epoch;
+ gdouble sequence_number;
+ gint64 sequence_number_temp;
+ guint8 content_type;
+ guint8 next_byte;
+ proto_tree *ti;
+ proto_tree *dtls_record_tree;
+ SslAssociation *association;
+ SslDataInfo *appl_data;
+
+ ti = NULL;
dtls_record_tree = NULL;
/*
* Get the record layer fields of interest
*/
- content_type = tvb_get_guint8(tvb, offset);
- version = tvb_get_ntohs(tvb, offset + 1);
- epoch = tvb_get_ntohs(tvb, offset + 3);
- sequence_number = tvb_get_ntohl(tvb, offset + 7);
- sequence_number_temp=tvb_get_ntohs(tvb, offset + 5);
- sequence_number_temp=sequence_number_temp<<32;
- sequence_number+=sequence_number_temp;
- record_length = tvb_get_ntohs(tvb, offset + 11);
+ content_type = tvb_get_guint8(tvb, offset);
+ version = tvb_get_ntohs(tvb, offset + 1);
+ epoch = tvb_get_ntohs(tvb, offset + 3);
+ sequence_number = tvb_get_ntohl(tvb, offset + 7);
+ sequence_number_temp = tvb_get_ntohs(tvb, offset + 5);
+ sequence_number_temp = sequence_number_temp<<32;
+ sequence_number += sequence_number_temp;
+ record_length = tvb_get_ntohs(tvb, offset + 11);
if(ssl){
if(ssl_packet_from_server(ssl, dtls_associations, pinfo)){
@@ -814,7 +876,7 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
* ssl session pointer is NULL at that time, so we can't access
* info cached there*/
association = ssl_association_find(dtls_associations, pinfo->srcport, pinfo->ptype == PT_TCP);
- association = association ? association: ssl_association_find(dtls_associations, pinfo->destport, pinfo->ptype == PT_TCP);
+ association = association ? association : ssl_association_find(dtls_associations, pinfo->destport, pinfo->ptype == PT_TCP);
proto_item_set_text(dtls_record_tree,
"%s Record Layer: %s Protocol: %s",
@@ -827,13 +889,16 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
if (appl_data && (appl_data->plain_data.data_len > 0))
{
tvbuff_t *next_tvb;
- gboolean dissected;
+ gboolean dissected;
/* try to dissect decrypted data*/
ssl_debug_printf("dissect_dtls_record decrypted len %d\n",
appl_data->plain_data.data_len);
/* create a new TVB structure for desegmented data */
- next_tvb = tvb_new_child_real_data(tvb, appl_data->plain_data.data, appl_data->plain_data.data_len, appl_data->plain_data.data_len);
+ next_tvb = tvb_new_child_real_data(tvb,
+ appl_data->plain_data.data,
+ appl_data->plain_data.data_len,
+ appl_data->plain_data.data_len);
add_new_data_source(pinfo, next_tvb, "Decrypted DTLS data");
@@ -900,11 +965,13 @@ dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo,
* AlertDescription description;
* } Alert;
*/
- proto_tree *ti;
- proto_tree *ssl_alert_tree;
+
+ proto_tree *ti;
+ proto_tree *ssl_alert_tree;
const gchar *level;
const gchar *desc;
- guint8 byte;
+ guint8 byte;
+
ssl_alert_tree = NULL;
if (tree)
@@ -919,11 +986,11 @@ dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo,
*/
/* first lookup the names for the alert level and description */
- byte = tvb_get_guint8(tvb, offset); /* grab the level byte */
+ byte = tvb_get_guint8(tvb, offset); /* grab the level byte */
level = match_strval(byte, ssl_31_alert_level);
- byte = tvb_get_guint8(tvb, offset+1); /* grab the desc byte */
- desc = match_strval(byte, ssl_31_alert_description);
+ byte = tvb_get_guint8(tvb, offset+1); /* grab the desc byte */
+ desc = match_strval(byte, ssl_31_alert_description);
/* now set the text in the record layer line */
if (level && desc)
@@ -975,8 +1042,8 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
* HandshakeType msg_type;
* uint24 length;
* uint16 message_seq; //new field
- * uint24 fragment_offset; //new field
- * uint24 fragment_length; //new field
+ * uint24 fragment_offset; //new field
+ * uint24 fragment_length; //new field
* select (HandshakeType) {
* case hello_request: HelloRequest;
* case client_hello: ClientHello;
@@ -992,19 +1059,21 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
* } body;
* } Handshake;
*/
- proto_tree *ti;
- proto_tree *ssl_hand_tree;
+
+ proto_tree *ti;
+ proto_tree *ssl_hand_tree;
const gchar *msg_type_str;
- guint8 msg_type;
- guint32 length;
- guint16 message_seq;
- guint32 fragment_offset;
- guint32 fragment_length;
- gboolean first_iteration;
- ti = NULL;
- ssl_hand_tree = NULL;
- msg_type_str = NULL;
- first_iteration = TRUE;
+ guint8 msg_type;
+ guint32 length;
+ guint16 message_seq;
+ guint32 fragment_offset;
+ guint32 fragment_length;
+ gboolean first_iteration;
+
+ ti = NULL;
+ ssl_hand_tree = NULL;
+ msg_type_str = NULL;
+ first_iteration = TRUE;
/* just as there can be multiple records per packet, there
* can be multiple messages per record as long as they have
@@ -1019,17 +1088,17 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
first_iteration = FALSE) /* set up for next pass, if any */
{
fragment_data *frag_msg = NULL;
- tvbuff_t *new_tvb = NULL;
- const gchar *frag_str = NULL;
- gboolean fragmented;
-
- msg_type = tvb_get_guint8(tvb, offset);
- msg_type_str = match_strval(msg_type, ssl_31_handshake_type);
- length = tvb_get_ntoh24(tvb, offset + 1);
- message_seq = tvb_get_ntohs(tvb,offset + 4);
+ tvbuff_t *new_tvb = NULL;
+ const gchar *frag_str = NULL;
+ gboolean fragmented;
+
+ msg_type = tvb_get_guint8(tvb, offset);
+ msg_type_str = match_strval(msg_type, ssl_31_handshake_type);
+ length = tvb_get_ntoh24(tvb, offset + 1);
+ message_seq = tvb_get_ntohs(tvb,offset + 4);
fragment_offset = tvb_get_ntoh24(tvb, offset + 6);
fragment_length = tvb_get_ntoh24(tvb, offset + 9);
- fragmented = fragment_length != length;
+ fragmented = fragment_length != length;
if (!msg_type_str && !first_iteration)
{
@@ -1299,7 +1368,8 @@ dissect_dtls_hnd_hello_common(tvbuff_t *tvb, proto_tree *tree,
{
/* show the client's random challenge */
nstime_t gmt_unix_time;
- guint8 session_id_length;
+ guint8 session_id_length;
+
session_id_length = 0;
if (ssl)
{
@@ -1337,7 +1407,7 @@ dissect_dtls_hnd_hello_common(tvbuff_t *tvb, proto_tree *tree,
if (tree)
{
/* show the time */
- gmt_unix_time.secs = tvb_get_ntohl(tvb, offset);
+ gmt_unix_time.secs = tvb_get_ntohl(tvb, offset);
gmt_unix_time.nsecs = 0;
proto_tree_add_time(tree, hf_dtls_handshake_random_time,
tvb, offset, 4, &gmt_unix_time);
@@ -1372,9 +1442,9 @@ static gint
dissect_dtls_hnd_hello_ext(tvbuff_t *tvb,
proto_tree *tree, guint32 offset, guint32 left)
{
- guint16 extension_length;
- guint16 ext_type;
- guint16 ext_len;
+ guint16 extension_length;
+ guint16 ext_type;
+ guint16 ext_len;
proto_item *pi;
proto_tree *ext_tree;
@@ -1385,12 +1455,12 @@ dissect_dtls_hnd_hello_ext(tvbuff_t *tvb,
proto_tree_add_uint(tree, hf_dtls_handshake_extensions_len,
tvb, offset, 2, extension_length);
offset += 2;
- left -= 2;
+ left -= 2;
while (left >= 4)
{
ext_type = tvb_get_ntohs(tvb, offset);
- ext_len = tvb_get_ntohs(tvb, offset + 2);
+ ext_len = tvb_get_ntohs(tvb, offset + 2);
pi = proto_tree_add_text(tree, tvb, offset, 4 + ext_len,
"Extension: %s",
@@ -1412,9 +1482,9 @@ dissect_dtls_hnd_hello_ext(tvbuff_t *tvb,
proto_tree_add_bytes_format(ext_tree, hf_dtls_handshake_extension_data,
tvb, offset, ext_len, NULL,
"Data (%u byte%s)", ext_len,
- plurality(ext_len, "", "s"));
+ plurality(ext_len, "", "s"));
offset += ext_len;
- left -= 2 + 2 + ext_len;
+ left -= 2 + 2 + ext_len;
}
return offset;
@@ -1436,16 +1506,18 @@ dissect_dtls_hnd_cli_hello(tvbuff_t *tvb,
* } ClientHello;
*
*/
+
proto_tree *ti;
proto_tree *cs_tree;
- guint16 cipher_suite_length;
- guint8 compression_methods_length;
- guint8 compression_method;
- guint16 start_offset = offset;
- guint8 cookie_length;
- cipher_suite_length = 0;
+ guint16 cipher_suite_length;
+ guint8 compression_methods_length;
+ guint8 compression_method;
+ guint16 start_offset = offset;
+ guint8 cookie_length;
+
+ cipher_suite_length = 0;
compression_methods_length = 0;
- cookie_length = 0;
+ cookie_length = 0;
if (tree || ssl)
{
@@ -1565,7 +1637,7 @@ dissect_dtls_hnd_cli_hello(tvbuff_t *tvb,
static void
dissect_dtls_hnd_hello_verify_request(tvbuff_t *tvb, proto_tree *tree,
- guint32 offset, SslDecryptSession* ssl)
+ guint32 offset, SslDecryptSession* ssl)
{
/*
* struct {
@@ -1575,6 +1647,7 @@ dissect_dtls_hnd_hello_verify_request(tvbuff_t *tvb, proto_tree *tree,
*/
guint8 cookie_length;
+
cookie_length = 0;
if (tree || ssl)
@@ -1621,7 +1694,9 @@ dissect_dtls_hnd_srv_hello(tvbuff_t *tvb,
* Extension server_hello_extension_list<0..2^16-1>;
* } ServerHello;
*/
+
guint16 start_offset;
+
start_offset = offset;
if (tree || ssl)
@@ -1701,10 +1776,12 @@ dissect_dtls_hnd_cert(tvbuff_t *tvb,
* ASN.1Cert certificate_list<1..2^24-1>;
* } Certificate;
*/
- guint32 certificate_list_length;
+
+ guint32 certificate_list_length;
proto_tree *ti;
proto_tree *subtree;
- asn1_ctx_t asn1_ctx;
+ asn1_ctx_t asn1_ctx;
+
asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
if (tree)
@@ -1769,12 +1846,14 @@ dissect_dtls_hnd_cert_req(tvbuff_t *tvb,
* } CertificateRequest;
*
*/
+
proto_tree *ti;
proto_tree *subtree;
guint8 cert_types_count;
- gint dnames_length;
+ gint dnames_length;
+
cert_types_count = 0;
- dnames_length = 0;
+ dnames_length = 0;
if (tree)
{
@@ -1950,7 +2029,7 @@ looks_like_dtls(tvbuff_t *tvb, guint32 offset)
/* have to have a valid content type followed by a valid
* protocol version
*/
- guint8 byte;
+ guint8 byte;
guint16 version;
/* see if the first byte is a valid content type */
@@ -1976,13 +2055,13 @@ looks_like_dtls(tvbuff_t *tvb, guint32 offset)
static void
dtlsdecrypt_free_cb(void* r)
{
- ssldecrypt_assoc_t* h = r;
+ ssldecrypt_assoc_t* h = r;
- g_free(h->ipaddr);
- g_free(h->port);
- g_free(h->protocol);
- g_free(h->keyfile);
- g_free(h->password);
+ g_free(h->ipaddr);
+ g_free(h->port);
+ g_free(h->protocol);
+ g_free(h->keyfile);
+ g_free(h->password);
}
#endif
@@ -1990,7 +2069,7 @@ dtlsdecrypt_free_cb(void* r)
static void
dtlsdecrypt_update_cb(void* r _U_, const char** err _U_)
{
- return;
+ return;
}
#endif
@@ -1998,16 +2077,16 @@ dtlsdecrypt_update_cb(void* r _U_, const char** err _U_)
static void *
dtlsdecrypt_copy_cb(void* dest, const void* orig, size_t len _U_)
{
- const ssldecrypt_assoc_t* o = orig;
- ssldecrypt_assoc_t* d = dest;
+ const ssldecrypt_assoc_t* o = orig;
+ ssldecrypt_assoc_t* d = dest;
- d->ipaddr = g_strdup(o->ipaddr);
- d->port = g_strdup(o->port);
- d->protocol = g_strdup(o->protocol);
- d->keyfile = g_strdup(o->keyfile);
- d->password = g_strdup(o->password);
+ d->ipaddr = g_strdup(o->ipaddr);
+ d->port = g_strdup(o->port);
+ d->protocol = g_strdup(o->protocol);
+ d->keyfile = g_strdup(o->keyfile);
+ d->password = g_strdup(o->password);
- return d;
+ return d;
}
UAT_CSTRING_CB_DEF(sslkeylist_uats,ipaddr,ssldecrypt_assoc_t)
@@ -2346,43 +2425,43 @@ proto_register_dtls(void)
{
module_t *dtls_module = prefs_register_protocol(proto_dtls, dtls_parse);
- static uat_field_t dtlskeylist_uats_flds[] = {
- UAT_FLD_CSTRING_OTHER(sslkeylist_uats, ipaddr, "IP address", ssldecrypt_uat_fld_ip_chk_cb, "IPv4 or IPv6 address"),
- UAT_FLD_CSTRING_OTHER(sslkeylist_uats, port, "Port", ssldecrypt_uat_fld_port_chk_cb, "Port Number"),
- UAT_FLD_CSTRING_OTHER(sslkeylist_uats, protocol, "Protocol", ssldecrypt_uat_fld_protocol_chk_cb, "Protocol"),
- UAT_FLD_FILENAME_OTHER(sslkeylist_uats, keyfile, "Key File", ssldecrypt_uat_fld_fileopen_chk_cb, "Path to the keyfile."),
- UAT_FLD_CSTRING_OTHER(sslkeylist_uats, password," Password (p12 file)", ssldecrypt_uat_fld_password_chk_cb, "Password"),
- UAT_END_FIELDS
- };
-
- dtlsdecrypt_uat = uat_new("DTLS RSA Keylist",
- sizeof(ssldecrypt_assoc_t),
- "dtlsdecrypttablefile", /* filename */
- TRUE, /* from_profile */
- (void*) &dtlskeylist_uats, /* data_ptr */
- &ndtlsdecrypt, /* numitems_ptr */
- UAT_CAT_FFMT, /* category */
- "ChK12ProtocolsSection", /* TODO, need revision - help */
- dtlsdecrypt_copy_cb,
- NULL, /* dtlsdecrypt_update_cb? */
- dtlsdecrypt_free_cb,
- dtls_parse,
- dtlskeylist_uats_flds);
-
- prefs_register_uat_preference(dtls_module, "cfg",
- "RSA keys list",
- "A table of RSA keys for DTLS decryption",
- dtlsdecrypt_uat);
-
- prefs_register_string_preference(dtls_module, "debug_file", "DTLS debug file",
+ static uat_field_t dtlskeylist_uats_flds[] = {
+ UAT_FLD_CSTRING_OTHER(sslkeylist_uats, ipaddr, "IP address", ssldecrypt_uat_fld_ip_chk_cb, "IPv4 or IPv6 address"),
+ UAT_FLD_CSTRING_OTHER(sslkeylist_uats, port, "Port", ssldecrypt_uat_fld_port_chk_cb, "Port Number"),
+ UAT_FLD_CSTRING_OTHER(sslkeylist_uats, protocol, "Protocol", ssldecrypt_uat_fld_protocol_chk_cb, "Protocol"),
+ UAT_FLD_FILENAME_OTHER(sslkeylist_uats, keyfile, "Key File", ssldecrypt_uat_fld_fileopen_chk_cb, "Path to the keyfile."),
+ UAT_FLD_CSTRING_OTHER(sslkeylist_uats, password," Password (p12 file)", ssldecrypt_uat_fld_password_chk_cb, "Password"),
+ UAT_END_FIELDS
+ };
+
+ dtlsdecrypt_uat = uat_new("DTLS RSA Keylist",
+ sizeof(ssldecrypt_assoc_t),
+ "dtlsdecrypttablefile", /* filename */
+ TRUE, /* from_profile */
+ (void*) &dtlskeylist_uats, /* data_ptr */
+ &ndtlsdecrypt, /* numitems_ptr */
+ UAT_CAT_FFMT, /* category */
+ "ChK12ProtocolsSection", /* TODO, need revision - help */
+ dtlsdecrypt_copy_cb,
+ NULL, /* dtlsdecrypt_update_cb? */
+ dtlsdecrypt_free_cb,
+ dtls_parse,
+ dtlskeylist_uats_flds);
+
+ prefs_register_uat_preference(dtls_module, "cfg",
+ "RSA keys list",
+ "A table of RSA keys for DTLS decryption",
+ dtlsdecrypt_uat);
+
+ prefs_register_string_preference(dtls_module, "debug_file", "DTLS debug file",
"redirect dtls debug to file name; leave empty to disable debug, "
"use \"" SSL_DEBUG_USE_STDERR "\" to redirect output to stderr\n",
(const gchar **)&dtls_debug_file_name);
- prefs_register_string_preference(dtls_module, "keys_list", "RSA keys list (deprecated)",
- "Semicolon-separated list of private RSA keys used for DTLS decryption. "
- "Used by versions of Wireshark prior to 1.6",
- (const gchar **)&dtls_keys_list);
+ prefs_register_string_preference(dtls_module, "keys_list", "RSA keys list (deprecated)",
+ "Semicolon-separated list of private RSA keys used for DTLS decryption. "
+ "Used by versions of Wireshark prior to 1.6",
+ (const gchar **)&dtls_keys_list);
}
#endif
@@ -2401,60 +2480,6 @@ proto_register_dtls(void)
register_heur_dissector_list("dtls", &heur_subdissector_list);
}
-static gboolean
-dissect_dtls_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- /* Stronger confirmation of DTLS packet is provided by verifying the
- * payload length against the remainder of the UDP packet size. */
- guint length = tvb_length(tvb);
- guint offset = 0;
-
- if (tvb_reported_length(tvb) == length) {
- while (offset + 13 <= length && looks_like_dtls(tvb, offset)) {
- /* Advance offset to the end of the current DTLS record */
- offset += tvb_get_ntohs(tvb, offset + 11) + 13;
- if (offset == length) {
- dissect_dtls(tvb, pinfo, tree);
- return TRUE;
- }
- }
-
- if (pinfo->fragmented && offset >= 13) {
- dissect_dtls(tvb, pinfo, tree);
- return TRUE;
- }
- return FALSE;
- }
-
- /* We've got a truncated packet - do our best with what we've got. */
- while (tvb_length_remaining(tvb, offset) >= 3) {
- if (!looks_like_dtls(tvb, offset))
- return FALSE;
-
- offset += 3;
- if (tvb_length_remaining(tvb, offset) >= 10 ) {
- offset += tvb_get_ntohs(tvb, offset + 8) + 10;
- } else {
- /* Dissect what we've got, which might be as little as 3 bytes. */
- dissect_dtls(tvb, pinfo, tree);
- return TRUE;
- }
- if (offset == length) {
- /* Can this ever happen? Well, just in case ... */
- dissect_dtls(tvb, pinfo, tree);
- return TRUE;
- }
- }
-
- /* One last check to see if the current offset is at least less than the
- * original number of bytes present before truncation or we're dealing with
- * a packet fragment that's also been truncated. */
- if ((length >= 3) && (offset <= tvb_reported_length(tvb) || pinfo->fragmented)) {
- dissect_dtls(tvb, pinfo, tree);
- return TRUE;
- }
- return FALSE;
-}
/* If this dissector uses sub-dissector registration add a registration
* routine. This format is required because a script is used to find