Index: epan/dissectors/packet-ssl-utils.c =================================================================== --- epan/dissectors/packet-ssl-utils.c (revision 33234) +++ epan/dissectors/packet-ssl-utils.c (working copy) @@ -819,7 +819,29 @@ { 0, NULL } }; +const value_string dtls_hello_extension_types[] = { + { 0, "server_name" }, + { 1, "max_fragment_length" }, + { 2, "client_certificate_url" }, + { 3, "trusted_ca_keys" }, + { 4, "truncated_hmac" }, + { 5, "status_request" }, + { 6, "user_mapping" }, /* RFC 4681 */ + { 7, "client_authz" }, + { 8, "server_authz" }, + { 9, "cert_type" }, /* RFC 5081 */ + { SSL_HND_HELLO_EXT_ELLIPTIC_CURVES, "elliptic_curves" }, /* RFC 4492 */ + { SSL_HND_HELLO_EXT_EC_POINT_FORMATS, "ec_point_formats" }, /* RFC 4492 */ + { 12, "srp" }, /* RFC 5054 */ + { 13, "signature_algorithms" }, /* RFC 5246 */ + { 14, "use_srtp" }, + { 35, "SessionTicket TLS" }, /* RFC 4507 */ + { 41, "Mobility" }, + { 65281, "renegotiation_info" }, + { 0, NULL } +}; + /* we keep this internal to packet-ssl-utils, as there should be no need to access it any other way. Index: epan/dissectors/packet-ssl-utils.h =================================================================== --- epan/dissectors/packet-ssl-utils.h (revision 33234) +++ epan/dissectors/packet-ssl-utils.h (working copy) @@ -172,6 +172,7 @@ extern const value_string pct_exch_type[]; extern const value_string pct_error_code[]; extern const value_string tls_hello_extension_types[]; +extern const value_string dtls_hello_extension_types[]; extern const value_string ssl_extension_curves[]; extern const value_string ssl_extension_ec_point_formats[]; Index: epan/dissectors/packet-dtls.c =================================================================== --- epan/dissectors/packet-dtls.c (revision 33234) +++ epan/dissectors/packet-dtls.c (working copy) @@ -75,6 +75,8 @@ #endif #include "packet-ssl-utils.h" +#define DTLS_HND_HELLO_EXT_MOBILITY 0x0029 + /* we need to remember the top tree so that subdissectors we call are created * at the root and not deep down inside the DTLS decode */ @@ -94,6 +96,7 @@ 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_mobility_connection_id = -1; static gint hf_dtls_record_length = -1; static gint hf_dtls_record_appdata = -1; static gint hf_dtls_change_cipher_spec = -1; @@ -123,6 +126,7 @@ 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_extension_mobility = -1; static gint hf_dtls_handshake_certificates_len = -1; static gint hf_dtls_handshake_certificates = -1; static gint hf_dtls_handshake_certificate = -1; @@ -297,6 +301,8 @@ guint32 offset, guint* conv_version); +static gboolean has_mobility_ext(tvbuff_t *tvb, guint32 offset); + /* * Support Functions * @@ -560,6 +566,8 @@ guint32 available_bytes; SslAssociation* association; SslDataInfo *appl_data; + gboolean has_connid_field; + has_connid_field = FALSE; ti = NULL; dtls_record_tree = NULL; available_bytes = tvb_length_remaining(tvb, offset); @@ -574,8 +582,13 @@ 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); + has_connid_field = has_mobility_ext(tvb, offset); + if (has_connid_field) + record_length = tvb_get_ntohs(tvb, offset + 15); + else + record_length = tvb_get_ntohs(tvb, offset + 11); + if(ssl){ if(ssl_packet_from_server(ssl, dtls_associations, pinfo)){ if (ssl->server) { @@ -639,6 +652,14 @@ offset += 6; + /* In case there is a connectionID field */ + if(has_connid_field) + { + proto_tree_add_uint(dtls_record_tree, hf_dtls_record_mobility_connection_id, tvb, + offset, 4, tvb_get_ntohl(tvb, offset)); + offset += 4; + } + /* add the length */ proto_tree_add_uint(dtls_record_tree, hf_dtls_record_length, tvb, offset, 2, record_length); @@ -648,7 +669,10 @@ else { /* if no GUI tree, then just skip over those fields */ - offset += 13; + if(has_connid_field) + offset += 17; + else + offset += 13; } @@ -1329,7 +1353,7 @@ pi = proto_tree_add_text(tree, tvb, offset, 4 + ext_len, "Extension: %s", val_to_str(ext_type, - tls_hello_extension_types, + dtls_hello_extension_types, "Unknown %u")); ext_tree = proto_item_add_subtree(pi, ett_dtls_extension); if (!ext_tree) @@ -1343,12 +1367,23 @@ tvb, offset, 2, ext_len); offset += 2; - proto_tree_add_bytes_format(ext_tree, hf_dtls_handshake_extension_data, - tvb, offset, ext_len, - tvb_get_ptr(tvb, offset, ext_len), - "Data (%u byte%s)", - ext_len, plurality(ext_len, "", "s")); - offset += ext_len; + switch (ext_type) + { + case DTLS_HND_HELLO_EXT_MOBILITY: + proto_tree_add_item(ext_tree, hf_dtls_handshake_extension_mobility, tvb, + offset, 4, 0); + offset += ext_len; + break; + default: + proto_tree_add_bytes_format(ext_tree, hf_dtls_handshake_extension_data, + tvb, offset, ext_len, + tvb_get_ptr(tvb, offset, ext_len), + "Data (%u byte%s)", + ext_len, plurality(ext_len, "", "s")); + offset += ext_len; + break; + } + left -= 2 + 2 + ext_len; } @@ -1947,6 +1982,11 @@ FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_dtls_record_mobility_connection_id, + { "Connection ID", "dtls.record.connection_id", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, { &hf_dtls_record_length, { "Length", "dtls.record.length", FT_UINT16, BASE_DEC, NULL, 0x0, @@ -2079,7 +2119,7 @@ }, { &hf_dtls_handshake_extension_type, { "Type", "dtls.handshake.extension.type", - FT_UINT16, BASE_HEX, VALS(tls_hello_extension_types), 0x0, + FT_UINT16, BASE_HEX, VALS(dtls_hello_extension_types), 0x0, "Hello extension type", HFILL } }, { &hf_dtls_handshake_extension_len, @@ -2092,6 +2132,11 @@ FT_BYTES, BASE_NONE, NULL, 0x0, "Hello Extension data", HFILL } }, + { &hf_dtls_handshake_extension_mobility, + { "ConnectionID", "dtls.handshake.extension.mobility", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Connection Identifier", HFILL } + }, { &hf_dtls_handshake_certificates_len, { "Certificates Length", "dtls.handshake.certificates_length", FT_UINT24, BASE_DEC, NULL, 0x0, @@ -2270,3 +2315,65 @@ /* add now dissector to default ports.*/ dtls_parse(); } + +static gboolean has_mobility_ext(tvbuff_t *tvb, guint32 offset) +{ + gboolean has_connid_field; + guint32 length; + guint32 remaining_len; + gboolean is_first_iteration; + gboolean equals_on_first; + gboolean is_second_iteration; + + has_connid_field = FALSE; + length = 0; + remaining_len = 0; + is_first_iteration = TRUE; + equals_on_first = FALSE; + is_second_iteration = FALSE; + + while (remaining_len >= 17 || is_first_iteration) + { + if (is_first_iteration) + { + length = tvb_get_ntohs(tvb, offset+11); + remaining_len = tvb_length_remaining(tvb, offset+13); + } + else + { + length = tvb_get_ntohs(tvb, offset+15); + remaining_len = tvb_length_remaining(tvb, offset+17); + } + + if (length == remaining_len) + { + if (is_first_iteration == TRUE) + equals_on_first = TRUE; + else if (is_second_iteration == TRUE && equals_on_first == TRUE) + return 0; + else + return 1; + } + else if (length > remaining_len) + { + if (is_first_iteration == FALSE) + return 0; + } + else + { + if (is_first_iteration == FALSE) + { + offset += 17; + offset += length; + } + } + + if (is_first_iteration) + is_second_iteration = TRUE; + else + is_second_iteration = FALSE; + + is_first_iteration = FALSE; + } + return has_connid_field; +}