aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorJaap Keuter <jaap.keuter@xs4all.nl>2007-08-21 07:23:34 +0000
committerJaap Keuter <jaap.keuter@xs4all.nl>2007-08-21 07:23:34 +0000
commit7b593acb18e8370a56a2d30010470eecff382713 (patch)
treebef3b83909fded855d75986e138f2eeeebd18367 /epan/dissectors
parent3d75f7a2a6e95ab607330906b6505d3ddb80befe (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
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-rtcp.c189
-rw-r--r--epan/dissectors/packet-rtcp.h10
-rw-r--r--epan/dissectors/packet-rtp.c101
-rw-r--r--epan/dissectors/packet-rtp.h54
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);