diff options
author | Jaap Keuter <jaap.keuter@xs4all.nl> | 2007-08-21 07:23:34 +0000 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2007-08-21 07:23:34 +0000 |
commit | 7b593acb18e8370a56a2d30010470eecff382713 (patch) | |
tree | bef3b83909fded855d75986e138f2eeeebd18367 | |
parent | 3d75f7a2a6e95ab607330906b6505d3ddb80befe (diff) |
From Neil Piercy:
This patch set provides a an API for out of band signalling protocols to
register flows as SRTP/SRTCP using extended versions of the existing
rt(c)p_add_address functions. At present the encrypted portions of the payloads
are simply skipped, and the auth tags etc added as fields.
svn path=/trunk/; revision=22562
-rw-r--r-- | epan/dissectors/packet-rtcp.c | 189 | ||||
-rw-r--r-- | epan/dissectors/packet-rtcp.h | 10 | ||||
-rw-r--r-- | epan/dissectors/packet-rtp.c | 101 | ||||
-rw-r--r-- | epan/dissectors/packet-rtp.h | 54 |
4 files changed, 311 insertions, 43 deletions
diff --git a/epan/dissectors/packet-rtcp.c b/epan/dissectors/packet-rtcp.c index da19a895de..06bedd9e0e 100644 --- a/epan/dissectors/packet-rtcp.c +++ b/epan/dissectors/packet-rtcp.c @@ -59,6 +59,7 @@ #include <string.h> #include "packet-rtcp.h" +#include "packet-rtp.h" #include "packet-ntp.h" #include <epan/conversation.h> @@ -113,7 +114,7 @@ static const value_string rtcp_packet_type_vals[] = { RTCP_RTPFB, "Generic RTP Feedback" }, { RTCP_PSFB, "Payload-specific" }, { RTCP_XR, "Extended report (RFC 3611)"}, - { 0, NULL }, + { 0, NULL } }; /* RTCP SDES types (Section A.11.2) */ @@ -140,7 +141,7 @@ static const value_string rtcp_sdes_type_vals[] = { RTCP_SDES_NOTE, "NOTE (note about source)" }, { RTCP_SDES_PRIV, "PRIV (private extensions)" }, { RTCP_SDES_H323_CADDR,"H323-CADDR (H.323 callable address)"}, - { 0, NULL }, + { 0, NULL } }; /* RTCP XR Blocks (Section 4, RTC 3611) */ @@ -228,7 +229,7 @@ static const value_string rtcp_app_poc1_floor_cnt_type_vals[] = { TBCP_DISCONNECT, "TBCP Disconnect"}, { TBCP_CONNECT, "TBCP Connect"}, { TBCP_BURST_TAKEN_EXPECT_REPLY, "TBCP Talk Burst Taken (ack expected)"}, - { 0, NULL }, + { 0, NULL } }; static const value_string rtcp_app_poc1_reason_code1_vals[] = @@ -238,7 +239,7 @@ static const value_string rtcp_app_poc1_reason_code1_vals[] = { 3, "Only one participant in the group"}, { 4, "Retry-after timer has not expired"}, { 5, "Listen only"}, - { 0, NULL }, + { 0, NULL } }; static const value_string rtcp_app_poc1_reason_code2_vals[] = @@ -247,7 +248,7 @@ static const value_string rtcp_app_poc1_reason_code2_vals[] = { 2, "Talk burst too long"}, { 3, "No permission to send a Talk Burst"}, { 4, "Talk burst pre-empted"}, - { 0, NULL }, + { 0, NULL } }; static const value_string rtcp_app_poc1_reason_code_ack_vals[] = @@ -255,7 +256,7 @@ static const value_string rtcp_app_poc1_reason_code_ack_vals[] = { 0, "Accepted"}, { 1, "Busy"}, { 2, "Not accepted"}, - { 0, NULL }, + { 0, NULL } }; static const value_string rtcp_app_poc1_conn_sess_type_vals[] = { @@ -264,7 +265,7 @@ static const value_string rtcp_app_poc1_conn_sess_type_vals[] = { 2, "Ad-hoc"}, { 3, "Pre-arranged"}, { 4, "Chat"}, - { 0, NULL }, + { 0, NULL } }; static const value_string rtcp_app_poc1_qsresp_priority_vals[] = @@ -273,14 +274,14 @@ static const value_string rtcp_app_poc1_qsresp_priority_vals[] = { 1, "Normal priority"}, { 2, "High priority"}, { 3, "Pre-emptive priority"}, - { 0, NULL }, + { 0, NULL } }; /* RFC 4585 */ static const value_string rtcp_rtpfb_fmt_vals[] = { { 1, "Generic negative acknowledgement"}, { 31, "Reserved for future extensions"}, - { 0, NULL }, + { 0, NULL } }; static const value_string rtcp_psfb_fmt_vals[] = @@ -290,7 +291,7 @@ static const value_string rtcp_psfb_fmt_vals[] = { 3, "Reference Picture Selection Indication"}, { 15, "Application Layer Feedback"}, { 31, "Reserved for future extensions"}, - { 0, NULL }, + { 0, NULL } }; /* RTCP header fields */ @@ -404,6 +405,10 @@ static int hf_rtcp_length_check = -1; static int hf_rtcp_rtpfb_fmt = -1; static int hf_rtcp_psfb_fmt = -1; static int hf_rtcp_fci = -1; +static int hf_srtcp_e = -1; +static int hf_srtcp_index = -1; +static int hf_srtcp_mki = -1; +static int hf_srtcp_auth_tag = -1; /* RTCP setup fields */ static int hf_rtcp_setup = -1; @@ -430,7 +435,7 @@ static gint ett_rtcp_roundtrip_delay = -1; static gint ett_xr_block = -1; static gint ett_xr_block_contents = -1; static gint ett_xr_ssrc = -1; -static gint ett_xr_loss_chunk = -1; +static gint ett_xr_loss_chunk = -1; static gint ett_poc1_conn_contents = -1; /* Protocol registration */ @@ -464,10 +469,11 @@ static void add_roundtrip_delay_info(tvbuff_t *tvb, packet_info *pinfo, /* Set up an RTCP conversation using the info given */ -void rtcp_add_address( packet_info *pinfo, +void srtcp_add_address( packet_info *pinfo, address *addr, int port, int other_port, - const gchar *setup_method, guint32 setup_frame_number) + const gchar *setup_method, guint32 setup_frame_number, + struct srtp_info *srtcp_info) { address null_addr; conversation_t* p_conv; @@ -530,6 +536,16 @@ void rtcp_add_address( packet_info *pinfo, strncpy(p_conv_data->setup_method, setup_method, MAX_RTCP_SETUP_METHOD_SIZE); p_conv_data->setup_method[MAX_RTCP_SETUP_METHOD_SIZE] = '\0'; p_conv_data->setup_frame_number = setup_frame_number; + p_conv_data->srtcp_info = srtcp_info; +} + +/* Set up an RTCP conversation using the info given */ +void rtcp_add_address( packet_info *pinfo, + address *addr, int port, + int other_port, + const gchar *setup_method, guint32 setup_frame_number) +{ + srtcp_add_address(pinfo, addr, port, other_port, setup_method, setup_frame_number, NULL); } static gboolean @@ -901,7 +917,7 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree /* Item len of 1 because its an FT_UINT_STRING... */ proto_tree_add_item(PoC1_tree, hf_rtcp_app_poc1_sip_uri, tvb, offset, 1, FALSE ); - offset++; + offset++; if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, " CNAME=\"%s\"", @@ -1910,7 +1926,7 @@ dissect_rtcp_sr( packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree if ( count != 0 ) offset = dissect_rtcp_rr( pinfo, tvb, offset, tree, count, packet_length-(offset-sr_offset) ); else - { + { /* If length remaining, assume profile-specific extension bytes */ if ((offset-sr_offset) < (int)packet_length) { @@ -2271,18 +2287,52 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) guint16 total_packet_length = 0; guint rtcp_subtype = 0; guint32 app_length = 0; + gboolean srtcp_encrypted = FALSE; + gboolean srtcp_now_encrypted = FALSE; + conversation_t *p_conv = NULL; + struct _rtcp_conversation_info *p_conv_data = NULL; + struct srtp_info *srtcp_info = NULL; + gboolean e_bit; + guint32 srtcp_offset = 0; + guint32 srtcp_index = 0; if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) { col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTCP" ); } + /* first see if this conversation is encrypted SRTP, and if so do not try to dissect the payload(s) */ + p_conv = find_conversation(pinfo->fd->num, &pinfo->net_src, &pinfo->net_dst, + pinfo->ptype, + pinfo->srcport, pinfo->destport, NO_ADDR_B); + if (p_conv) + { + p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp); + if (p_conv_data && p_conv_data->srtcp_info) + { + srtcp_info = p_conv_data->srtcp_info; + /* get the offset to the start of the SRTCP fields at the end of the packet */ + srtcp_offset = tvb_length_remaining(tvb,offset) - srtcp_info->auth_tag_len - srtcp_info->mki_len - 4; + /* It has been setup as SRTCP, but skip to the SRTCP E field at the end + to see if this particular packet is encrypted or not. The E bit is the MSB. */ + srtcp_index = tvb_get_ntohl(tvb,srtcp_offset); + e_bit = (srtcp_index & 0x80000000) ? TRUE : FALSE; + srtcp_index &= 0x7fffffff; + + if (srtcp_info->encryption_algorithm!=SRTP_ENC_ALG_NULL) { + /* just flag it for now - the first SR or RR header and SSRC are unencrypted */ + if (e_bit) + srtcp_encrypted = TRUE; + } + } + } + /* * Check if there are at least 4 bytes left in the frame, * the last 16 bits of those is the length of the current * RTCP message. The last compound message contains padding, * that enables us to break from the while loop. */ - while ( tvb_bytes_exist( tvb, offset, 4) ) { + while ( !srtcp_now_encrypted && tvb_bytes_exist( tvb, offset, 4) ) { /* * First retreive the packet_type */ @@ -2346,6 +2396,11 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) ); offset += 4; + if (srtcp_encrypted) { /* rest of the payload is encrypted - do not try to dissect */ + srtcp_now_encrypted = TRUE; + break; + } + if ( packet_type == RTCP_SR ) offset = dissect_rtcp_sr( pinfo, tvb, offset, rtcp_tree, elem_count, packet_length-8 ); else @@ -2403,10 +2458,10 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) case RTCP_NACK: offset = dissect_rtcp_nack( tvb, offset, rtcp_tree ); break; - case RTCP_RTPFB: - /* Transport layer FB message */ - /* Feedback message type (FMT): 5 bits */ - proto_tree_add_item( rtcp_tree, hf_rtcp_rtpfb_fmt, tvb, offset, 1, FALSE ); + case RTCP_RTPFB: + /* Transport layer FB message */ + /* Feedback message type (FMT): 5 bits */ + proto_tree_add_item( rtcp_tree, hf_rtcp_rtpfb_fmt, tvb, offset, 1, FALSE ); offset++; /* Packet type, 8 bits */ proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE ); @@ -2416,18 +2471,18 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) /* SSRC of packet sender, 32 bits */ proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) ); offset += 4; - /* SSRC of media source, 32 bits */ + /* SSRC of media source, 32 bits */ proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) ); offset += 4; - /* Feedback Control Information (FCI) */ - if (packet_length > 2) - proto_tree_add_item( rtcp_tree, hf_rtcp_fci, tvb, offset, 1, FALSE ); - break; + /* Feedback Control Information (FCI) */ + if (packet_length > 2) + proto_tree_add_item( rtcp_tree, hf_rtcp_fci, tvb, offset, 1, FALSE ); + break; - case RTCP_PSFB: - /* Payload-specific FB message */ - /* Feedback message type (FMT): 5 bits */ - proto_tree_add_item( rtcp_tree, hf_rtcp_psfb_fmt, tvb, offset, 1, FALSE ); + case RTCP_PSFB: + /* Payload-specific FB message */ + /* Feedback message type (FMT): 5 bits */ + proto_tree_add_item( rtcp_tree, hf_rtcp_psfb_fmt, tvb, offset, 1, FALSE ); offset++; /* Packet type, 8 bits */ proto_tree_add_item( rtcp_tree, hf_rtcp_pt, tvb, offset, 1, FALSE ); @@ -2437,13 +2492,13 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) /* SSRC of packet sender, 32 bits */ proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) ); offset += 4; - /* SSRC of media source, 32 bits */ + /* SSRC of media source, 32 bits */ proto_tree_add_uint( rtcp_tree, hf_rtcp_ssrc_sender, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) ); offset += 4; - /* Feedback Control Information (FCI) */ - if (packet_length > 2) - proto_tree_add_item( rtcp_tree, hf_rtcp_fci, tvb, offset, 1, FALSE ); - break; + /* Feedback Control Information (FCI) */ + if (packet_length > 2) + proto_tree_add_item( rtcp_tree, hf_rtcp_fci, tvb, offset, 1, FALSE ); + break; default: /* * To prevent endless loops in case of an unknown message type @@ -2468,8 +2523,24 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) proto_tree_add_item( rtcp_tree, hf_rtcp_padding_count, tvb, offset, 1, FALSE ); } + /* If the payload was encrypted, the main payload was not dissected */ + if (srtcp_encrypted == TRUE) { + proto_tree_add_text(rtcp_tree, tvb, offset, srtcp_offset-offset, "Encrypted RTCP Payload - not dissected"); + proto_tree_add_item(rtcp_tree, hf_srtcp_e, tvb, srtcp_offset, 4, FALSE); + proto_tree_add_uint(rtcp_tree, hf_srtcp_index, tvb, srtcp_offset, 4, srtcp_index); + srtcp_offset += 4; + if (srtcp_info->mki_len) { + proto_tree_add_item(rtcp_tree, hf_srtcp_mki, tvb, srtcp_offset, srtcp_info->mki_len, FALSE); + srtcp_offset += srtcp_info->mki_len; + } + + if (srtcp_info->auth_tag_len) { + proto_tree_add_item(rtcp_tree, hf_srtcp_auth_tag, tvb, srtcp_offset, srtcp_info->auth_tag_len, FALSE); + srtcp_offset += srtcp_info->auth_tag_len; + } + } /* offset should be total_packet_length by now... */ - if (offset == total_packet_length) + else if (offset == (int)total_packet_length) { ti = proto_tree_add_boolean_format_value(tree, hf_rtcp_length_check, tvb, 0, 0, TRUE, "OK - %u bytes", @@ -3938,6 +4009,54 @@ proto_register_rtcp(void) } }, + { + &hf_srtcp_e, + { + "SRTCP E flag", + "srtcp.e", + FT_BOOLEAN, + 32, + NULL, + 0x80000000, + "SRTCP Encryption Flag", HFILL + } + }, + { + &hf_srtcp_index, + { + "SRTCP Index", + "srtcp.index", + FT_UINT32, + BASE_DEC_HEX, + NULL, + 0x7fffffff, + "SRTCP Index", HFILL + } + }, + { + &hf_srtcp_mki, + { + "SRTCP MKI", + "srtcp.mki", + FT_BYTES, + BASE_NONE, + NULL, + 0, + "SRTCP Master Key Index", HFILL + } + }, + { + &hf_srtcp_auth_tag, + { + "SRTCP Auth Tag", + "srtcp.auth_tag", + FT_BYTES, + BASE_NONE, + NULL, + 0, + "SRTCP Authentication Tag", HFILL + } + }, }; static gint *ett[] = { diff --git a/epan/dissectors/packet-rtcp.h b/epan/dissectors/packet-rtcp.h index 646a21b565..89c9a13a5d 100644 --- a/epan/dissectors/packet-rtcp.h +++ b/epan/dissectors/packet-rtcp.h @@ -49,6 +49,9 @@ struct _rtcp_conversation_info guint32 calculated_delay_used_frame; gint calculated_delay_report_gap; gint32 calculated_delay; + + /* SRTCP context */ + struct srtp_info *srtcp_info; }; @@ -57,3 +60,10 @@ void rtcp_add_address(packet_info *pinfo, address *addr, int port, int other_port, const gchar *setup_method, guint32 setup_frame_number); + +/* Add an SRTP conversation with the given details */ +void srtcp_add_address(packet_info *pinfo, + address *addr, int port, + int other_port, + const gchar *setup_method, guint32 setup_frame_number, + struct srtp_info *srtcp_info); diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c index f13efa5464..5d9d7e136f 100644 --- a/epan/dissectors/packet-rtp.c +++ b/epan/dissectors/packet-rtp.c @@ -186,6 +186,10 @@ static gint ett_rtp_setup = -1; static gint ett_rtp_rfc2198 = -1; static gint ett_rtp_rfc2198_hdr = -1; +/* SRTP fields */ +static int hf_srtp_encrypted_payload = -1; +static int hf_srtp_mki = -1; +static int hf_srtp_auth_tag = -1; /* PacketCable CCC header fields */ static int proto_pkt_ccc = -1; @@ -335,6 +339,21 @@ const value_string rtp_payload_type_short_vals[] = { 0, NULL }, }; +static const value_string srtp_encryption_alg_vals[] = +{ + { SRTP_ENC_ALG_NULL, "Null Encryption" }, + { SRTP_ENC_ALG_AES_CM, "AES-128 Counter Mode" }, + { SRTP_ENC_ALG_AES_F8, "AES-128 F8 Mode" }, + { 0, NULL }, +}; + +static const value_string srtp_auth_alg_vals[] = +{ + { SRTP_AUTH_ALG_NONE, "No Authentication" }, + { SRTP_AUTH_ALG_HMAC_SHA1, "HMAC-SHA1" }, + { 0, NULL }, +}; + /* initialisation routine */ static void rtp_fragment_init(void) @@ -351,11 +370,12 @@ rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload) rtp_dyn_payload = NULL; } -/* Set up an RTP conversation */ -void rtp_add_address(packet_info *pinfo, +/* Set up an SRTP conversation */ +void srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port, - const gchar *setup_method, guint32 setup_frame_number, GHashTable *rtp_dyn_payload) + const gchar *setup_method, guint32 setup_frame_number, GHashTable *rtp_dyn_payload, + struct srtp_info *srtp_info) { address null_addr; conversation_t* p_conv; @@ -424,6 +444,16 @@ void rtp_add_address(packet_info *pinfo, p_conv_data->method[MAX_RTP_SETUP_METHOD_SIZE] = '\0'; p_conv_data->frame_number = setup_frame_number; p_conv_data->rtp_dyn_payload = rtp_dyn_payload; + p_conv_data->srtp_info = srtp_info; +} + +/* Set up an RTP conversation */ +void rtp_add_address(packet_info *pinfo, + address *addr, int port, + int other_port, + const gchar *setup_method, guint32 setup_frame_number, GHashTable *rtp_dyn_payload) +{ + srtp_add_address(pinfo, addr, port, other_port, setup_method, setup_frame_number, rtp_dyn_payload, NULL); } static gboolean @@ -491,10 +521,42 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree, { struct _rtp_conversation_info *p_conv_data = NULL; gboolean found_match = FALSE; + int payload_len; + struct srtp_info *srtp_info; + int offset=0; + + payload_len = tvb_length_remaining(newtvb, offset); + + /* first check if this is added as an SRTP stream - if so, don't try to dissector the payload data for now */ + p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp); + if (p_conv_data && p_conv_data->srtp_info) { + srtp_info = p_conv_data->srtp_info; + payload_len -= srtp_info->mki_len + srtp_info->auth_tag_len; + + if (p_conv_data->srtp_info->encryption_algorithm==SRTP_ENC_ALG_NULL) { + if (rtp_tree) + proto_tree_add_text(rtp_tree, newtvb, offset, payload_len, "SRTP Payload with NULL encryption"); + } + else { + if (rtp_tree) + proto_tree_add_item(rtp_tree, hf_srtp_encrypted_payload, newtvb, offset, payload_len, FALSE); + found_match = TRUE; /* use this flag to prevent dissection below */ + } + offset += payload_len; + + if (srtp_info->mki_len) { + proto_tree_add_item(rtp_tree, hf_srtp_mki, newtvb, offset, srtp_info->mki_len, FALSE); + offset += srtp_info->mki_len; + } + + if (srtp_info->auth_tag_len) { + proto_tree_add_item(rtp_tree, hf_srtp_auth_tag, newtvb, offset, srtp_info->auth_tag_len, FALSE); + offset += srtp_info->auth_tag_len; + } + } /* if the payload type is dynamic (96 to 127), we check if the conv is set and we look for the pt definition */ - if ( (payload_type >=96) && (payload_type <=127) ) { - p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp); + else if ( (payload_type >=96) && (payload_type <=127) ) { if (p_conv_data && p_conv_data->rtp_dyn_payload) { gchar *payload_type_str = NULL; payload_type_str = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &payload_type); @@ -516,7 +578,7 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree, } /* if we don't found, it is static OR could be set static from the preferences */ - if (!dissector_try_port(rtp_pt_dissector_table, payload_type, newtvb, pinfo, tree)) + if (!found_match && !dissector_try_port(rtp_pt_dissector_table, payload_type, newtvb, pinfo, tree)) proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, FALSE ); } @@ -845,6 +907,8 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) guint32 sync_src; guint32 csrc_item; struct _rtp_conversation_info *p_conv_data = NULL; + struct srtp_info *srtp_info = NULL; + unsigned int srtp_offset; /* Can tap up to 4 RTP packets within same packet */ static struct _rtp_info rtp_info_arr[4]; @@ -968,6 +1032,15 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTP" ); } + /* check if this is added as an SRTP stream - if so, don't try to dissector the payload data for now */ + p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp); + if (p_conv_data && p_conv_data->srtp_info) { + srtp_info = p_conv_data->srtp_info; + if (rtp_info->info_all_data_present) { + srtp_offset = rtp_info->info_data_len - srtp_info->mki_len - srtp_info->auth_tag_len; + } + } + /* if it is dynamic payload, let use the conv data to see if it is defined */ if ( (payload_type>95) && (payload_type<128) ) { if (p_conv_data && p_conv_data->rtp_dyn_payload){ @@ -1221,6 +1294,7 @@ static void get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info) p_conv_packet_data->frame_number = p_conv_data->frame_number; p_conv_packet_data->rtp_dyn_payload = p_conv_data->rtp_dyn_payload; p_conv_packet_data->rtp_conv_info = p_conv_data->rtp_conv_info; + p_conv_packet_data->srtp_info = p_conv_data->srtp_info; p_add_proto_data(pinfo->fd, proto_rtp, p_conv_packet_data); /* calculate extended sequence number */ @@ -1711,6 +1785,21 @@ proto_register_rtp(void) {"RTP fragment, reassembled in frame", "rtp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0, "This RTP packet is reassembled in this frame", HFILL } + }, + {&hf_srtp_encrypted_payload, + {"SRTP Encrypted Payload", "srtp.enc_payload", + FT_BYTES, BASE_NONE, NULL, 0x0, + "SRTP Encrypted Payload", HFILL } + }, + {&hf_srtp_mki, + {"SRTP MKI", "srtp.mki", + FT_BYTES, BASE_NONE, NULL, 0x0, + "SRTP Master Key Index", HFILL } + }, + {&hf_srtp_auth_tag, + {"SRTP Auth Tag", "srtp.auth_tag", + FT_BYTES, BASE_NONE, NULL, 0x0, + "SRTP Authentication Tag", HFILL } } }; diff --git a/epan/dissectors/packet-rtp.h b/epan/dissectors/packet-rtp.h index 865fbdb15f..c976767500 100644 --- a/epan/dissectors/packet-rtp.h +++ b/epan/dissectors/packet-rtp.h @@ -53,6 +53,46 @@ struct _rtp_info { */ }; +/* definitions for SRTP dissection */ + +/* Encryption algorithms */ +#define SRTP_ENC_ALG_NULL 0 /* non-encrypted SRTP payload - may still be authenticated */ +#define SRTP_ENC_ALG_AES_CM 1 /* SRTP default algorithm */ +#define SRTP_ENC_ALG_AES_F8 2 + +/* Authentication algorithms */ +#define SRTP_AUTH_ALG_NONE 0 /* no auth tag in SRTP/RTP payload */ +#define SRTP_AUTH_ALG_HMAC_SHA1 1 /* SRTP default algorithm */ + + +#if 0 /* these are only needed once the dissector include the crypto functions to decrypt and/or authenticate */ +struct srtp_key_info +{ + guint8 *master_key; /* pointer to an se_alloc'ed master key */ + guint8 *master_salt; /* pointer to an se_alloc'ed salt for this master key - NULL if no salt */ + guint8 key_generation_rate; /* encoded as the power of 2, 0..24, or 255 (=zero rate) */ + /* Either the MKI value is used (in which case from=to=0), or the <from,to> values are used (and MKI=0) */ + guint32 from_roc; /* 32 MSBs of a 48 bit value - frame from which this key is valid (roll-over counter part) */ + guint16 from_seq; /* 16 LSBs of a 48 bit value - frame from which this key is valid (sequence number part) */ + guint32 to_roc; /* 32 MSBs of a 48 bit value - frame to which this key is valid (roll-over counter part) */ + guint16 to_seq; /* 16 LSBs of a 48 bit value - frame to which this key is valid (sequence number part) */ + guint32 mki; /* the MKI value associated with this key */ +}; +#endif + +struct srtp_info +{ + guint encryption_algorithm; /* at present only NULL vs non-NULL matter */ + guint auth_algorithm; /* at present only NULL vs non-NULL matter */ + guint mki_len; /* number of octets used for the MKI in the RTP payload */ + guint auth_tag_len; /* number of octets used for the Auth Tag in the RTP payload */ +#if 0 /* these are only needed once the dissector include the crypto functions to decrypt and/or authenticate */ + struct srtp_key_info **master_keys; /* an array of pointers to master keys and their info, the array and each key struct being se_alloc'ed */ + void *enc_alg_info, /* algorithm-dependent info struct - may be void for default alg with default params */ + void *auth_alg_info /* algorithm-dependent info struct - void for default alg with default params */ +#endif +}; + /* Info to save in RTP conversation / packet-info */ #define MAX_RTP_SETUP_METHOD_SIZE 7 struct _rtp_conversation_info @@ -67,6 +107,7 @@ struct _rtp_conversation_info struct _rtp_private_conv_info *rtp_conv_info; /* conversation info private * to the rtp dissector */ + struct srtp_info *srtp_info; /* SRTP context */ }; /* Add an RTP conversation with the given details */ @@ -74,8 +115,17 @@ void rtp_add_address(packet_info *pinfo, address *addr, int port, int other_port, const gchar *setup_method, - guint32 setup_frame_number, - GHashTable *rtp_dyn_payload); + guint32 setup_frame_number, + GHashTable *rtp_dyn_payload); + +/* Add an SRTP conversation with the given details */ +void srtp_add_address(packet_info *pinfo, + address *addr, int port, + int other_port, + const gchar *setup_method, + guint32 setup_frame_number, + GHashTable *rtp_dyn_payload, + struct srtp_info *srtp_info); /* Free and destroy the dyn_payload hash table */ void rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload); |