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
This commit is contained in:
Jaap Keuter 2007-08-21 07:23:34 +00:00
parent 3d75f7a2a6
commit 7b593acb18
4 changed files with 311 additions and 43 deletions

View File

@ -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[] =
{

View File

@ -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);

View File

@ -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 }
}
};

View File

@ -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);