diff options
author | Anders Broman <anders.broman@ericsson.com> | 2012-01-26 17:52:13 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2012-01-26 17:52:13 +0000 |
commit | 63e69454827cbd2ddfc8d7ac5f771e6c5c17e6ee (patch) | |
tree | 5614fd1c94b473e5522f1be892ea17f6db67b769 /epan/dissectors/packet-sdp.c | |
parent | ab692eb7d4f775a6ef59c4ac9114c7151329b1e8 (diff) | |
download | wireshark-63e69454827cbd2ddfc8d7ac5f771e6c5c17e6ee.tar.gz |
Dissect the crypto attribute.
svn path=/trunk/; revision=40732
Diffstat (limited to 'epan/dissectors/packet-sdp.c')
-rw-r--r-- | epan/dissectors/packet-sdp.c | 739 |
1 files changed, 448 insertions, 291 deletions
diff --git a/epan/dissectors/packet-sdp.c b/epan/dissectors/packet-sdp.c index 4568248225..748ba7c410 100644 --- a/epan/dissectors/packet-sdp.c +++ b/epan/dissectors/packet-sdp.c @@ -179,6 +179,14 @@ static int hf_key_mgmt_att_value = -1; static int hf_key_mgmt_prtcl_id = -1; static int hf_key_mgmt_data = -1; +static int hf_sdp_crypto_tag = -1; +static int hf_sdp_crypto_crypto_suite = -1; +static int hf_sdp_crypto_master_key = -1; +static int hf_sdp_crypto_master_salt = -1; +static int hf_sdp_crypto_lifetime = -1; +static int hf_sdp_crypto_mki = -1; +static int hf_sdp_crypto_mki_length = -1; + /* trees */ static int ett_sdp = -1; static int ett_sdp_owner = -1; @@ -193,6 +201,7 @@ static int ett_sdp_media = -1; static int ett_sdp_media_attribute = -1; static int ett_sdp_fmtp = -1; static int ett_sdp_key_mgmt = -1; +static int ett_sdp_crypto_key_parameters = -1; #define SDP_MAX_RTP_CHANNELS 4 @@ -985,69 +994,69 @@ static void dissect_key_mgmt(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti){ - proto_tree *sdp_session_attribute_tree; - gint offset, next_offset, tokenlen; - guint8 *field_name; + proto_tree *sdp_session_attribute_tree; + gint offset, next_offset, tokenlen; + guint8 *field_name; - offset = 0; - next_offset = 0; - tokenlen = 0; + offset = 0; + next_offset = 0; + tokenlen = 0; - sdp_session_attribute_tree = proto_item_add_subtree(ti, - ett_sdp_session_attribute); + sdp_session_attribute_tree = proto_item_add_subtree(ti, + ett_sdp_session_attribute); - next_offset = tvb_find_guint8(tvb,offset,-1,':'); + next_offset = tvb_find_guint8(tvb,offset,-1,':'); - if(next_offset == -1) - return; + if(next_offset == -1) + return; - tokenlen = next_offset - offset; + tokenlen = next_offset - offset; - proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_field, - tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_field, + tvb, offset, tokenlen, ENC_ASCII|ENC_NA); - field_name = tvb_get_ephemeral_string(tvb, offset, tokenlen); + field_name = tvb_get_ephemeral_string(tvb, offset, tokenlen); - offset = next_offset + 1; + offset = next_offset + 1; - if (strcmp((char*)field_name, "ipbcp") == 0) { - offset = tvb_pbrk_guint8(tvb,offset,-1,(guint8 *)"0123456789", NULL); + if (strcmp((char*)field_name, "ipbcp") == 0) { + offset = tvb_pbrk_guint8(tvb,offset,-1,(guint8 *)"0123456789", NULL); - if (offset == -1) - return; + if (offset == -1) + return; - next_offset = tvb_find_guint8(tvb,offset,-1,' '); + next_offset = tvb_find_guint8(tvb,offset,-1,' '); - if (next_offset == -1) - return; + if (next_offset == -1) + return; - tokenlen = next_offset - offset; + tokenlen = next_offset - offset; - proto_tree_add_item(sdp_session_attribute_tree,hf_ipbcp_version,tvb,offset,tokenlen,ENC_ASCII|ENC_NA); + proto_tree_add_item(sdp_session_attribute_tree,hf_ipbcp_version,tvb,offset,tokenlen,ENC_ASCII|ENC_NA); - offset = tvb_pbrk_guint8(tvb,offset,-1,(guint8 *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL); + offset = tvb_pbrk_guint8(tvb,offset,-1,(guint8 *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL); - if (offset == -1) - return; + if (offset == -1) + return; - tokenlen = tvb_find_line_end(tvb,offset,-1, &next_offset, FALSE); + tokenlen = tvb_find_line_end(tvb,offset,-1, &next_offset, FALSE); - if (tokenlen == -1) - return; + if (tokenlen == -1) + return; - proto_tree_add_item(sdp_session_attribute_tree,hf_ipbcp_type,tvb,offset,tokenlen,ENC_ASCII|ENC_NA); - } else if (strcmp((char*)field_name, "key-mgmt") == 0) { - tvbuff_t *key_tvb; - proto_item *key_ti; + proto_tree_add_item(sdp_session_attribute_tree,hf_ipbcp_type,tvb,offset,tokenlen,ENC_ASCII|ENC_NA); + } else if (strcmp((char*)field_name, "key-mgmt") == 0) { + tvbuff_t *key_tvb; + proto_item *key_ti; - key_tvb = tvb_new_subset_remaining(tvb, offset); - key_ti = proto_tree_add_item(sdp_session_attribute_tree, hf_key_mgmt_att_value, key_tvb, 0, -1, ENC_ASCII|ENC_NA); + key_tvb = tvb_new_subset_remaining(tvb, offset); + key_ti = proto_tree_add_item(sdp_session_attribute_tree, hf_key_mgmt_att_value, key_tvb, 0, -1, ENC_ASCII|ENC_NA); - dissect_key_mgmt(key_tvb, pinfo, key_ti); - } else { - proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_value, - tvb, offset, -1, ENC_ASCII|ENC_NA); - } + dissect_key_mgmt(key_tvb, pinfo, key_ti); + } else { + proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_value, + tvb, offset, -1, ENC_ASCII|ENC_NA); + } } @@ -1470,7 +1479,8 @@ typedef struct { #define SDP_RTPMAP 1 #define SDP_FMTP 2 #define SDP_PATH 3 -#define SDP_H248_ITEM 4 +#define SDP_H248_ITEM 4 +#define SDP_CRYPTO 5 static const sdp_names_t sdp_media_attribute_names[] = { { "Unknown-name"}, /* 0 Pad so that the real headers start at index 1 */ @@ -1478,6 +1488,7 @@ static const sdp_names_t sdp_media_attribute_names[] = { { "fmtp"}, /* 2 */ { "path"}, /* 3 */ { "h248item"}, /* 4 */ + { "crypto"}, /* 5 */ }; static gint find_sdp_media_attribute_names(tvbuff_t *tvb, int offset, guint len) @@ -1494,281 +1505,398 @@ static gint find_sdp_media_attribute_names(tvbuff_t *tvb, int offset, guint len) } static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item * ti, int length, transport_info_t *transport_info){ - proto_tree *sdp_media_attribute_tree; - proto_item *fmtp_item, *media_format_item; - proto_tree *fmtp_tree; - gint offset, next_offset, tokenlen, n, colon_offset; - /*??guint8 *field_name;*/ - guint8 *payload_type; - guint8 *attribute_value; - gint *key; - guint8 pt; - gint sdp_media_attrbute_code; - const char *msrp_res = "msrp://"; - const char *h324ext_h223lcparm = "h324ext/h223lcparm"; - gboolean has_more_pars = TRUE; - tvbuff_t *h245_tvb; - encoding_name_and_rate_t *encoding_name_and_rate; - - offset = 0; - next_offset = 0; - tokenlen = 0; - - /* Create attribute tree */ - sdp_media_attribute_tree = proto_item_add_subtree(ti, - ett_sdp_media_attribute); - /* Find end of field */ - colon_offset = tvb_find_guint8(tvb,offset,-1,':'); - - if(colon_offset == -1) - return; + proto_tree *sdp_media_attribute_tree, *parameter_item; + proto_item *fmtp_item, *media_format_item, *parameter_tree; + proto_tree *fmtp_tree; + gint offset, next_offset, tokenlen, n, colon_offset; + /*??guint8 *field_name;*/ + guint8 *payload_type; + guint8 *attribute_value; + gint *key; + guint8 pt; + gint sdp_media_attrbute_code; + const char *msrp_res = "msrp://"; + const char *h324ext_h223lcparm = "h324ext/h223lcparm"; + gboolean has_more_pars = TRUE; + tvbuff_t *h245_tvb; + encoding_name_and_rate_t *encoding_name_and_rate; + guint8 master_key_length = 0, master_salt_length = 0; + + offset = 0; + next_offset = 0; + tokenlen = 0; + + /* Create attribute tree */ + sdp_media_attribute_tree = proto_item_add_subtree(ti, + ett_sdp_media_attribute); + /* Find end of field */ + colon_offset = tvb_find_guint8(tvb,offset,-1,':'); + + if(colon_offset == -1) + return; - /* Attribute field name is token before ':' */ - tokenlen = colon_offset - offset; - proto_tree_add_item(sdp_media_attribute_tree, - hf_media_attribute_field, - tvb, offset, tokenlen, ENC_ASCII|ENC_NA); - /*??field_name = tvb_get_ephemeral_string(tvb, offset, tokenlen);*/ - sdp_media_attrbute_code = find_sdp_media_attribute_names(tvb, offset, tokenlen); + /* Attribute field name is token before ':' */ + tokenlen = colon_offset - offset; + proto_tree_add_item(sdp_media_attribute_tree, + hf_media_attribute_field, + tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + /*??field_name = tvb_get_ephemeral_string(tvb, offset, tokenlen);*/ + sdp_media_attrbute_code = find_sdp_media_attribute_names(tvb, offset, tokenlen); - /* Skip colon */ - offset = colon_offset + 1; - /* skip leading wsp */ - offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset)); + /* Skip colon */ + offset = colon_offset + 1; + /* skip leading wsp */ + offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset)); - /* Value is the remainder of the line */ - attribute_value = tvb_get_ephemeral_string(tvb, offset, tvb_length_remaining(tvb, offset)); + /* Value is the remainder of the line */ + attribute_value = tvb_get_ephemeral_string(tvb, offset, tvb_length_remaining(tvb, offset)); - /*********************************************/ - /* Special parsing for some field name types */ + /*********************************************/ + /* Special parsing for some field name types */ - switch (sdp_media_attrbute_code){ - case SDP_RTPMAP: - /* decode the rtpmap to see if it is DynamicPayload to dissect them automatic */ - next_offset = tvb_find_guint8(tvb,offset,-1,' '); + switch (sdp_media_attrbute_code){ + case SDP_RTPMAP: + /* decode the rtpmap to see if it is DynamicPayload to dissect them automatic */ + next_offset = tvb_find_guint8(tvb,offset,-1,' '); - if(next_offset == -1) - return; + if(next_offset == -1) + return; - tokenlen = next_offset - offset; + tokenlen = next_offset - offset; - proto_tree_add_item(sdp_media_attribute_tree, hf_media_format, tvb, - offset, tokenlen, ENC_ASCII|ENC_NA); + proto_tree_add_item(sdp_media_attribute_tree, hf_media_format, tvb, + offset, tokenlen, ENC_ASCII|ENC_NA); - payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen); + payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen); - offset = next_offset + 1; + offset = next_offset + 1; - next_offset = tvb_find_guint8(tvb,offset,-1,'/'); + next_offset = tvb_find_guint8(tvb,offset,-1,'/'); - if(next_offset == -1){ - return; - } - - tokenlen = next_offset - offset; + if(next_offset == -1){ + return; + } - proto_tree_add_item(sdp_media_attribute_tree, hf_media_encoding_name, tvb, - offset, tokenlen, ENC_ASCII|ENC_NA); + tokenlen = next_offset - offset; - key=g_malloc( sizeof(gint) ); - *key=atol((char*)payload_type); - pt = atoi((char*)payload_type); - if (pt >= SDP_NO_OF_PT) { - return; /* Invalid */ - } - transport_info->encoding_name[pt] = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen); + proto_tree_add_item(sdp_media_attribute_tree, hf_media_encoding_name, tvb, + offset, tokenlen, ENC_ASCII|ENC_NA); - next_offset = next_offset + 1; - offset = next_offset; - while (length-1 >= next_offset){ - if(!isdigit(tvb_get_guint8(tvb, next_offset))) - break; - next_offset++; - } - tokenlen = next_offset - offset; - proto_tree_add_item(sdp_media_attribute_tree, hf_media_sample_rate, tvb, - offset, tokenlen, ENC_ASCII|ENC_NA); - transport_info->sample_rate[pt] = atoi(tvb_get_ephemeral_string(tvb, offset, tokenlen)); - /* As per RFC2327 it is possible to have multiple Media Descriptions ("m="). - For example: - - a=rtpmap:101 G726-32/8000 - m=audio 49170 RTP/AVP 0 97 - a=rtpmap:97 telephone-event/8000 - m=audio 49172 RTP/AVP 97 101 - a=rtpmap:97 G726-24/8000 - - The Media attributes ("a="s) after the "m=" only apply for that "m=". - If there is an "a=" before the first "m=", that attribute applies for - all the session (all the "m="s). - */ + key=g_malloc( sizeof(gint) ); + *key=atol((char*)payload_type); + pt = atoi((char*)payload_type); + if (pt >= SDP_NO_OF_PT) { + return; /* Invalid */ + } + transport_info->encoding_name[pt] = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen); + + next_offset = next_offset + 1; + offset = next_offset; + while (length-1 >= next_offset){ + if(!isdigit(tvb_get_guint8(tvb, next_offset))) + break; + next_offset++; + } + tokenlen = next_offset - offset; + proto_tree_add_item(sdp_media_attribute_tree, hf_media_sample_rate, tvb, + offset, tokenlen, ENC_ASCII|ENC_NA); + transport_info->sample_rate[pt] = atoi(tvb_get_ephemeral_string(tvb, offset, tokenlen)); + /* As per RFC2327 it is possible to have multiple Media Descriptions ("m="). + For example: + + a=rtpmap:101 G726-32/8000 + m=audio 49170 RTP/AVP 0 97 + a=rtpmap:97 telephone-event/8000 + m=audio 49172 RTP/AVP 97 101 + a=rtpmap:97 G726-24/8000 + + The Media attributes ("a="s) after the "m=" only apply for that "m=". + If there is an "a=" before the first "m=", that attribute applies for + all the session (all the "m="s). + */ + + /* so, if this "a=" appear before any "m=", we add it to all the dynamic + * hash tables + */ + if (transport_info->media_count == 0) { + for (n=0; n < SDP_MAX_RTP_CHANNELS; n++) { + encoding_name_and_rate = g_malloc( sizeof(encoding_name_and_rate_t)); + encoding_name_and_rate->encoding_name = g_strdup(transport_info->encoding_name[pt]); + encoding_name_and_rate->sample_rate = transport_info->sample_rate[pt]; + if (n==0){ + g_hash_table_insert(transport_info->media[n].rtp_dyn_payload, + key, encoding_name_and_rate); + } + else { /* we create a new key and encoding_name to assign to the other hash tables */ + gint *key2; + key2=g_malloc( sizeof(gint) ); + *key2=atol((char*)payload_type); + g_hash_table_insert(transport_info->media[n].rtp_dyn_payload, + key2, encoding_name_and_rate); + } + } + return; + /* if the "a=" is after an "m=", only apply to this "m=" */ + }else + /* in case there is an overflow in SDP_MAX_RTP_CHANNELS, we keep always the last "m=" */ + encoding_name_and_rate = g_malloc( sizeof(encoding_name_and_rate_t)); - /* so, if this "a=" appear before any "m=", we add it to all the dynamic - * hash tables - */ - if (transport_info->media_count == 0) { - for (n=0; n < SDP_MAX_RTP_CHANNELS; n++) { - encoding_name_and_rate = g_malloc( sizeof(encoding_name_and_rate_t)); encoding_name_and_rate->encoding_name = g_strdup(transport_info->encoding_name[pt]); encoding_name_and_rate->sample_rate = transport_info->sample_rate[pt]; - if (n==0){ - g_hash_table_insert(transport_info->media[n].rtp_dyn_payload, - key, encoding_name_and_rate); + if (transport_info->media_count == SDP_MAX_RTP_CHANNELS-1) + g_hash_table_insert(transport_info->media[ transport_info->media_count ].rtp_dyn_payload, + key, encoding_name_and_rate); + else + g_hash_table_insert(transport_info->media[ transport_info->media_count-1 ].rtp_dyn_payload, + key, encoding_name_and_rate); + break; + case SDP_FMTP: + if(sdp_media_attribute_tree){ + guint8 media_format; + /* Reading the Format parameter(fmtp) */ + /* Skip leading space, if any */ + offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset)); + /* Media format extends to the next space */ + next_offset = tvb_find_guint8(tvb,offset,-1,' '); + + if(next_offset == -1) + return; + + tokenlen = next_offset - offset; + + + media_format_item = proto_tree_add_item(sdp_media_attribute_tree, + hf_media_format, tvb, offset, + tokenlen, ENC_ASCII|ENC_NA); + media_format = atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen)); + if (media_format >= SDP_NO_OF_PT) { + return; /* Invalid */ + } + + /* Append encoding name to format if known */ + proto_item_append_text(media_format_item, " [%s]", + transport_info->encoding_name[media_format]); + + /*??payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen);*/ + /* Move offset past the payload type */ + offset = next_offset + 1; + + while(has_more_pars==TRUE){ + next_offset = tvb_find_guint8(tvb,offset,-1,';'); + offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset)); + + if(next_offset == -1){ + has_more_pars = FALSE; + next_offset= tvb_length(tvb); + } + + /* There are at least 2 - add the first parameter */ + tokenlen = next_offset - offset; + fmtp_item = proto_tree_add_item(sdp_media_attribute_tree, + hf_media_format_specific_parameter, tvb, + offset, tokenlen, ENC_ASCII|ENC_NA); + + fmtp_tree = proto_item_add_subtree(fmtp_item, ett_sdp_fmtp); + + decode_sdp_fmtp(fmtp_tree, tvb, pinfo, offset, tokenlen, + transport_info->encoding_name[media_format]); + + /* Move offset past "; " and onto firts char */ + offset = next_offset + 1; + } } - else { /* we create a new key and encoding_name to assign to the other hash tables */ - gint *key2; - key2=g_malloc( sizeof(gint) ); - *key2=atol((char*)payload_type); - g_hash_table_insert(transport_info->media[n].rtp_dyn_payload, - key2, encoding_name_and_rate); + break; + case SDP_PATH: + /* msrp attributes that contain address needed for conversation */ + /* RFC 4975 + * path = path-label ":" path-list + * path-label = "path" + * path-list= MSRP-URI *(SP MSRP-URI) + * MSRP-URI = msrp-scheme "://" authority + * ["/" session-id] ";" transport *( ";" URI-parameter) + * ; authority as defined in RFC3986 + * + * msrp-scheme = "msrp" / "msrps" + * RFC 3986 + * The authority component is preceded by a double slash ("//") and is terminated by + * the next slash ("/"), question mark ("?"), or number sign ("#") character, or by + * the end of the URI. + */ + + /* Check for "msrp://" */ + if (strncmp((char*)attribute_value, msrp_res, strlen(msrp_res)) == 0){ + int address_offset, port_offset, port_end_offset; + + /* Address starts here */ + address_offset = offset + (int)strlen(msrp_res); + + /* Port is after next ':' */ + port_offset = tvb_find_guint8(tvb, address_offset, -1, ':'); + /* Check if port is present if not skipp */ + if(port_offset!= -1){ + /* Port ends with '/' */ + port_end_offset = tvb_find_guint8(tvb, port_offset, -1, '/'); + + /* Attempt to convert address */ + if (inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, address_offset, port_offset-address_offset), &msrp_ipaddr) > 0) { + /* Get port number */ + msrp_port_number = atoi((char*)tvb_get_ephemeral_string(tvb, port_offset+1, port_end_offset-port_offset-1)); + /* Set flag so this info can be used */ + msrp_transport_address_set = TRUE; + } + } } - } - return; - /* if the "a=" is after an "m=", only apply to this "m=" */ - }else - /* in case there is an overflow in SDP_MAX_RTP_CHANNELS, we keep always the last "m=" */ - encoding_name_and_rate = g_malloc( sizeof(encoding_name_and_rate_t)); - - encoding_name_and_rate->encoding_name = g_strdup(transport_info->encoding_name[pt]); - encoding_name_and_rate->sample_rate = transport_info->sample_rate[pt]; - if (transport_info->media_count == SDP_MAX_RTP_CHANNELS-1) - g_hash_table_insert(transport_info->media[ transport_info->media_count ].rtp_dyn_payload, - key, encoding_name_and_rate); - else - g_hash_table_insert(transport_info->media[ transport_info->media_count-1 ].rtp_dyn_payload, - key, encoding_name_and_rate); - break; - case SDP_FMTP: - if(sdp_media_attribute_tree){ - guint8 media_format; - /* Reading the Format parameter(fmtp) */ - /* Skip leading space, if any */ - offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset)); - /* Media format extends to the next space */ - next_offset = tvb_find_guint8(tvb,offset,-1,' '); - - if(next_offset == -1) - return; - - tokenlen = next_offset - offset; - - - media_format_item = proto_tree_add_item(sdp_media_attribute_tree, - hf_media_format, tvb, offset, - tokenlen, ENC_ASCII|ENC_NA); - media_format = atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen)); - if (media_format >= SDP_NO_OF_PT) { - return; /* Invalid */ - } - - /* Append encoding name to format if known */ - proto_item_append_text(media_format_item, " [%s]", - transport_info->encoding_name[media_format]); - - /*??payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen);*/ - /* Move offset past the payload type */ - offset = next_offset + 1; - - while(has_more_pars==TRUE){ - next_offset = tvb_find_guint8(tvb,offset,-1,';'); - offset = tvb_skip_wsp(tvb,offset,tvb_length_remaining(tvb,offset)); - - if(next_offset == -1){ - has_more_pars = FALSE; - next_offset= tvb_length(tvb); - }else{ - + break; + case SDP_H248_ITEM: + /* Decode h248 item ITU-T Rec. H.248.12 (2001)/Amd.1 (11/2002)*/ + if (strncmp((char*)attribute_value, h324ext_h223lcparm, strlen(msrp_res)) == 0){ + /* A.5.1.3 H.223 Logical channel parameters + * This property indicates the H.245 + * H223LogicalChannelsParameters structure encoded by applying the PER specified in + * ITU-T Rec. X.691. Value encoded as per A.5.1.2. For text encoding the mechanism defined + * in ITU-T Rec. H.248.15 is used. + */ + gint len; + asn1_ctx_t actx; + + len = (gint)strlen(attribute_value); + h245_tvb = ascii_bytes_to_tvb(tvb, pinfo, len, attribute_value); + /* arbitrary maximum length */ + /* should go through a handle, however, the two h245 entry + points are different, one is over tpkt and the other is raw + */ + if (h245_tvb){ + asn1_ctx_init(&actx, ASN1_ENC_PER, TRUE, pinfo); + dissect_h245_H223LogicalChannelParameters(h245_tvb, 0, &actx, sdp_media_attribute_tree, hf_SDPh223LogicalChannelParameters); + } } - - /* There are at least 2 - add the first parameter */ + break; + case SDP_CRYPTO: + /* http://tools.ietf.org/html/rfc4568 + * 9.1. Generic "Crypto" Attribute Grammar + * + * The ABNF grammar for the crypto attribute is defined below: + * + * "a=crypto:" tag 1*WSP crypto-suite 1*WSP key-params + * *(1*WSP session-param) + * + * tag = 1*9DIGIT + * crypto-suite = 1*(ALPHA / DIGIT / "_") + * + * key-params = key-param *(";" key-param) + * key-param = key-method ":" key-info + * key-method = "inline" / key-method-ext + * key-method-ext = 1*(ALPHA / DIGIT / "_") + * key-info = 1*(%x21-3A / %x3C-7E) ; visible (printing) chars + * ; except semi-colon + * session-param = 1*(VCHAR) ; visible (printing) characters + * + * where WSP, ALPHA, DIGIT, and VCHAR are defined in [RFC4234]. + * + */ + + /* We are at the first colon */ + /* tag */ + next_offset = tvb_find_guint8(tvb,offset,-1,' '); tokenlen = next_offset - offset; - fmtp_item = proto_tree_add_item(sdp_media_attribute_tree, - hf_media_format_specific_parameter, tvb, - offset, tokenlen, ENC_ASCII|ENC_NA); - - fmtp_tree = proto_item_add_subtree(fmtp_item, ett_sdp_fmtp); - - decode_sdp_fmtp(fmtp_tree, tvb, pinfo, offset, tokenlen, - transport_info->encoding_name[media_format]); - - /* Move offset past "; " and onto firts char */ - offset = next_offset + 1; - } - } - break; - case SDP_PATH: - /* msrp attributes that contain address needed for conversation */ - /* RFC 4975 - * path = path-label ":" path-list - * path-label = "path" - * path-list= MSRP-URI *(SP MSRP-URI) - * MSRP-URI = msrp-scheme "://" authority - * ["/" session-id] ";" transport *( ";" URI-parameter) - * ; authority as defined in RFC3986 - * - * msrp-scheme = "msrp" / "msrps" - * RFC 3986 - * The authority component is preceded by a double slash ("//") and is terminated by - * the next slash ("/"), question mark ("?"), or number sign ("#") character, or by - * the end of the URI. - */ + proto_tree_add_uint(sdp_media_attribute_tree, hf_sdp_crypto_tag, tvb, offset, tokenlen, + atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen))); + offset=next_offset+1; - /* Check for "msrp://" */ - if (strncmp((char*)attribute_value, msrp_res, strlen(msrp_res)) == 0){ - int address_offset, port_offset, port_end_offset; - - /* Address starts here */ - address_offset = offset + (int)strlen(msrp_res); - - /* Port is after next ':' */ - port_offset = tvb_find_guint8(tvb, address_offset, -1, ':'); - /* Check if port is present if not skipp */ - if(port_offset!= -1){ - /* Port ends with '/' */ - port_end_offset = tvb_find_guint8(tvb, port_offset, -1, '/'); - - /* Attempt to convert address */ - if (inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, address_offset, port_offset-address_offset), &msrp_ipaddr) > 0) { - /* Get port number */ - msrp_port_number = atoi((char*)tvb_get_ephemeral_string(tvb, port_offset+1, port_end_offset-port_offset-1)); - /* Set flag so this info can be used */ - msrp_transport_address_set = TRUE; + /* crypto-suite */ + next_offset = tvb_find_guint8(tvb,offset,-1,' '); + tokenlen = next_offset - offset; + proto_tree_add_item(sdp_media_attribute_tree, hf_sdp_crypto_crypto_suite, tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + if(tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_80",tokenlen) == 0){ + master_key_length = 16; /* 128 bits = 16 octets */ + master_salt_length = 14; /* 112 bits = 14 octets */ + }else if(tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_32",tokenlen) == 0){ + master_key_length = 16; /* 128 bits = 16 octets */ + master_salt_length = 14; /* 112 bits = 14 octets */ + }else if(tvb_strncaseeql(tvb, offset, "F8_128_HMAC_SHA1_80",tokenlen) == 0){ + master_key_length = 16; /* 128 bits = 16 octets */ + master_salt_length = 14; /* 112 bits = 14 octets */ + } + offset=next_offset+1; + + /* key-params */ + while(has_more_pars==TRUE){ + int param_end_offset; + tvbuff_t *key_salt_tvb; + gchar *data_p = NULL; + + param_end_offset = tvb_find_guint8(tvb,offset,-1,';'); + if(param_end_offset == -1){ + has_more_pars = FALSE; + param_end_offset= tvb_length(tvb); + } + parameter_item = proto_tree_add_text(sdp_media_attribute_tree, tvb, offset, param_end_offset-offset, "Key parameters"); + parameter_tree = proto_item_add_subtree(parameter_item, ett_sdp_crypto_key_parameters); + + /* key-method or key-method-ext */ + next_offset = tvb_find_guint8(tvb,offset,-1,':'); + if(tvb_strncaseeql(tvb, offset, "inline", next_offset-offset) == 0){ + /* XXX only for SRTP? */ + /* srtp-key-info = key-salt ["|" lifetime] ["|" mki] */ + offset = next_offset +1; + next_offset = tvb_find_guint8(tvb,offset,-1,'|'); + if(next_offset == -1){ + tokenlen = param_end_offset - offset; + }else{ + tokenlen = next_offset - offset; + } + data_p = tvb_get_ephemeral_string(tvb, offset, tokenlen); + key_salt_tvb = base64_to_tvb(tvb, data_p); + add_new_data_source(pinfo, key_salt_tvb, "Key_Salt_tvb"); + if(master_key_length !=0){ + proto_tree_add_text(parameter_tree, tvb, offset, tokenlen, "Key and Salt"); + proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_key, key_salt_tvb, 0, master_key_length, ENC_ASCII|ENC_NA); + proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_salt, key_salt_tvb, master_key_length, master_salt_length, ENC_ASCII|ENC_NA); + }else{ + proto_tree_add_text(parameter_tree, key_salt_tvb, 0, -1, "Key and Salt"); + } + /* ["|" lifetime] ["|" mki] are optional */ + if(next_offset != -1){ + + offset = next_offset + 1; + next_offset = tvb_find_guint8(tvb,offset,-1,'|'); + if(next_offset != -1){ + /*lifetime = ["2^"] 1*(DIGIT) ; see section 6.1 for "2^" */ + tokenlen = next_offset - offset; + proto_tree_add_item(parameter_tree, hf_sdp_crypto_lifetime, tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + offset = next_offset + 1; + } + /* mki = mki-value ":" mki-length + * + * mki-value = 1*DIGIT + */ + next_offset = tvb_find_guint8(tvb,offset,-1,':'); + tokenlen = next_offset - offset; + proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki, tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + offset = next_offset + 1; + + /* mki-length = 1*3DIGIT ; range 1..128. */ + next_offset = param_end_offset; + tokenlen = next_offset - offset; + proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki_length, tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + } + offset = param_end_offset; + }else{ + tokenlen = param_end_offset - next_offset+1; + proto_tree_add_text(parameter_tree, tvb, next_offset+1, tokenlen, "%s",tvb_get_ephemeral_string(tvb, next_offset+1, tokenlen)); + offset = param_end_offset; + } } - } - } - break; - case SDP_H248_ITEM: - /* Decode h248 item ITU-T Rec. H.248.12 (2001)/Amd.1 (11/2002)*/ - if (strncmp((char*)attribute_value, h324ext_h223lcparm, strlen(msrp_res)) == 0){ - /* A.5.1.3 H.223 Logical channel parameters - * This property indicates the H.245 - * H223LogicalChannelsParameters structure encoded by applying the PER specified in - * ITU-T Rec. X.691. Value encoded as per A.5.1.2. For text encoding the mechanism defined - * in ITU-T Rec. H.248.15 is used. - */ - gint len; - asn1_ctx_t actx; - - len = (gint)strlen(attribute_value); - h245_tvb = ascii_bytes_to_tvb(tvb, pinfo, len, attribute_value); - /* arbitrary maximum length */ - /* should go through a handle, however, the two h245 entry - points are different, one is over tpkt and the other is raw - */ - if (h245_tvb){ - asn1_ctx_init(&actx, ASN1_ENC_PER, TRUE, pinfo); - dissect_h245_H223LogicalChannelParameters(h245_tvb, 0, &actx, sdp_media_attribute_tree, hf_SDPh223LogicalChannelParameters); - } + + break; + default: + /* No special treatment for values of this attribute type, just add as one item. */ + proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value, + tvb, offset, -1, ENC_ASCII|ENC_NA); + break; } - break; - default: - /* No special treatment for values of this attribute type, just add as one item. */ - proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value, - tvb, offset, -1, ENC_ASCII|ENC_NA); - break; - } } void @@ -2027,6 +2155,34 @@ proto_register_sdp(void) { "Key Management Data", "sdp.key_mgmt.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { &hf_sdp_crypto_tag, + { "tag", + "sdp.crypto.tag", FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_sdp_crypto_crypto_suite, + { "Crypto suite", + "sdp.crypto.crypto_suite", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_sdp_crypto_master_key, + { "Master Key", + "sdp.crypto.master_key", FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_sdp_crypto_master_salt, + { "Mater salt", + "sdp.crypto.master_salt", FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_sdp_crypto_lifetime, + { "Lifetime", + "sdp.crypto.lifetime", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_sdp_crypto_mki, + { "mki-value", + "sdp.crypto.mki-valu", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_sdp_crypto_mki_length, + { "mki_length", + "sdp.crypto.mki_length", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, }; static gint *ett[] = { &ett_sdp, @@ -2042,6 +2198,7 @@ proto_register_sdp(void) &ett_sdp_media_attribute, &ett_sdp_fmtp, &ett_sdp_key_mgmt, + &ett_sdp_crypto_key_parameters, }; module_t *sdp_module; |