From Neil Piercy:
authorjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 21 Aug 2007 07:23:34 +0000 (07:23 +0000)
committerjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 21 Aug 2007 07:23:34 +0000 (07:23 +0000)
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.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@22562 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-rtcp.c
epan/dissectors/packet-rtcp.h
epan/dissectors/packet-rtp.c
epan/dissectors/packet-rtp.h

index da19a895de0a7195b3a0d8d1047828fd481b1083..06bedd9e0ee52191bed68655134aa172b2ced524 100644 (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[] =
        {
index 646a21b5653374d9467767f18ef58d3a8e42a776..89c9a13a5d34ba3093fc3ec49322fcc3ae42a1e0 100644 (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);
index f13efa5464cb842d240e4bdc6321156d3ab2d8d3..5d9d7e136f1a3b537c998f9915da2a56db96f2c6 100644 (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 }
                }
 
        };
index 865fbdb15f69edc373b76c077769a96be9a1566b..c976767500c491c54e1d4b0d11e58aa1ad3fced5 100644 (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);