rohc team mailing list archive
-
rohc team
-
Mailing list archive
-
Message #01450
Enhance RTP detector from single packet to deep inspection of N packets
Hello!
The following RTP detector:
http://bazaar.launchpad.net/~didier-barvaux/rohc/main/view/head:/app/sniffer/sniffer.c#L1722
which try to decide if RTP by single packet can be enhanced to do deep packet inspection, by verifying that SSRC is stable for certain thershold period.
#NOTE: as Rtp_Arr[] is internal to the detector it access it directly instead via rtp_private.
The new source:
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define RTP_APPROVE_THOLD (5)
#define MAX_RTP_CID (8)
typedef struct rtp_entry
{
uint8_t Cnt2Rtp; // if free == 0, count (RTP_APPROVE_THOLD)5,4,3,2,1(RTP Approved)
uint8_t TBD; // PT?
uint16_t TBD16; // ...?
uint32_t LastPktTm; // Last-Packet-TimeStamp, in sec
uint32_t srcIp; // Source-IP, Kept in BigEndian
uint32_t SSRC; // SSRC, Kept in BigEndian
} rtp_ent_t;
rtp_ent_t Rtp_Arr[ MAX_RTP_CID ];
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
* @brief The detection callback which do detect RTP stream
*
* @param ip The inner ip packet
* @param udp The udp header of the packet
* @param payload The payload of the packet
* @param payload_size The size of the payload (in bytes) == udp.udp_length-8(=udp_header_size)
* @return 1 if the packet is an RTP packet, 0 otherwise
*/
static bool rtp_detect_cb(const unsigned char *const ip,
const unsigned char *const udp,
const unsigned char *const payload,
const unsigned int payload_size,
void *const rtp_private)
{
const uint16_t max_well_known_port = 1024;
const uint16_t sip_port = 5060;
uint32_t ssrc, src_ip;
uint16_t udp_sport;
uint16_t udp_dport;
//uint16_t udp_len; //==payload_size+8
uint8_t rtp_pt;
uint32_t ts_now;
int jj, freeNdx;
bool is_rtp = false;
//assert(ip != NULL);
//assert(udp != NULL);
//assert(payload != NULL);
//assert(rtp_private == NULL);
if( !ip || !udp || !payload)
{
//cprintf("%srtp_detector_cb called with NULL ptr%s\n", ATR_RED, ATR_OFF);
goto not_rtp;
}
bins.Detect++;
/* retrieve UDP source and destination ports and UDP length */
udp_sport = htons(*(uint16_t *)&udp[0]); //memcpy(&udp_sport, udp, sizeof(uint16_t));
udp_dport = htons(*(uint16_t *)&udp[2]); //memcpy(&udp_dport, udp + 2, sizeof(uint16_t));
//udp_len = htons(*(uint16_t *)&udp[4]); //memcpy(&udp_len, udp + 4, sizeof(uint16_t));//NO-NEED==payload_size+8
/* RTP streams do not use well known ports */
if((udp_sport <= max_well_known_port) ||
(udp_dport <= max_well_known_port))
{
goto not_rtp;
}
/* SIP (UDP/5060) is not RTP */
if((udp_sport == sip_port) && (udp_dport == sip_port))
{
goto not_rtp;
}
/* the UDP destination port of RTP packet is even (the RTCP destination
* port are RTP destination port + 1, so it is odd) */
if(((udp_sport % 2) != 0) || ((udp_dport % 2) != 0))
{
goto not_rtp;
}
/* UDP Length shall not be too large */
if(payload_size > 192)
{
goto not_rtp;
}
/* UDP payload shall at least contain the smallest RTP header */
if(payload_size < 12)
{
goto not_rtp;
}
/* RTP Version bits shall be 2, eXtension-bit4 should be 0 */
if((payload[0] & 0xd0) != 0x80)
{
goto not_rtp;
}//..is Ver==2 & X==0?
#define DEEP_PKT_INSPECT // Make sure it is RTP session by RTP_APPROVE_THOLD packets inspection
/* RTP payload type shall be:
* G.711/PCMU (0), GSM (0x03), ITU-T G.723 (0x04),
* ITU-T G.729 (0x12), dynamic RTP type 97 (0x61),
* telephony-event (0x65), Speex (0x72),
* or dynamic RTP type 125 (0x7d) */
rtp_pt = payload[1] & 0x7f;
#ifndef DEEP_PKT_INSPECT
if ((rtp_pt != 0x00) &&
(rtp_pt != 0x03) && (rtp_pt != 0x04) && (rtp_pt != 0x12) &&
(rtp_pt != 0x61) && (rtp_pt != 0x65) && (rtp_pt != 0x72) &&
(rtp_pt != 0x7d))
{
goto not_rtp;
}
#endif /*!DEEP_PKT_INSPECT*/
/* we think that the UDP packet is a RTP packet */
#ifdef DEEP_PKT_INSPECT
ssrc = *((uint32_t *)&payload[ 8 ]); // Let's keep it in Big Endian format
src_ip = *((uint32_t *)&ip[ 12 ]); // Let's keep it in Big Endian format
freeNdx = -1;
ts_now = time(0); // ts_now = tp_now >> 20; //Note: tp_now is time in usec since application start, means >> 20 => 1.048576sec
for (jj = 0; jj < MAX_RTP_CID; jj++)
{
register uint32_t DiffTm; // Delta T in seconds
DiffTm = ts_now - Rtp_Arr[ jj ].LastPktTm;
if (DiffTm >> 4) // Is Delta-T > 16sec
Rtp_Arr[ jj ].Cnt2Rtp = 0; // Mark free
if ((freeNdx < 0) && (Rtp_Arr[ jj ].Cnt2Rtp == 0))
freeNdx = jj; // Record tentative entry, if non-existing entry
if ((Rtp_Arr[ jj ].SSRC == ssrc) && (Rtp_Arr[ jj ].srcIp == src_ip))
{
if (Rtp_Arr[ jj ].Cnt2Rtp > 1)
Rtp_Arr[ jj ].Cnt2Rtp--;
Rtp_Arr[ jj ].LastPktTm = ts_now;
if (Rtp_Arr[ jj ].Cnt2Rtp == 1)
{
bins.isRtp++;
is_rtp = true;
}
break; // Found => stop search
}//..this rtp-session entry found
}//..search for rtp-session entry
if ((jj == MAX_RTP_CID) &&(freeNdx >= 0))
{
printf("rtp_detector_cb Set rtp entry:%d w/ Ip:0x%x-%x pt:x%x\n", freeNdx, src_ip, ssrc, rtp_pt);
Rtp_Arr[ freeNdx ].Cnt2Rtp = RTP_APPROVE_THOLD;
Rtp_Arr[ freeNdx ].LastPktTm = ts_now;
Rtp_Arr[ freeNdx ].srcIp = src_ip;
Rtp_Arr[ freeNdx ].SSRC = ssrc;
}//..rtp-session entry not-found => assign "free" entry
#else /*DEEP_PKT_INSPECT?*/
bins.isRtp++;
is_rtp = true;
#endif /*!DEEP_PKT_INSPECT*/
not_rtp:
return is_rtp;
}//..rtp_detect_cb()
Gil Beniamini
Gilat Satellite Networks - R&D
gilb@xxxxxxxxx<mailto:gilb@xxxxxxxxx>
Phone: (972)-3-9252427 Fax:(972)-3-9293040
IMPORTANT - This email and any attachments
is intended for the above named addressee(s), and may contain information which
is confidential or privileged. If you are not the intended recipient, please
inform the sender immediately and delete this email: you should not copy or use
this e-mail for any purpose nor disclose its contents to any person.