forked from osmocom/wireshark
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:
parent
3d75f7a2a6
commit
7b593acb18
|
@ -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[] =
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue