It is not possible to a distinguish RTP packet reliably without additional analysis of signaling.
Different ways are used to understand if some packet is RTP or not.
I've made investigation of the X company's IP sniffer module and the JNetPcap library.
You can find here methods used in these software. All these methods don't give a 100% exact decision.
You can find RTP header description in
specification of RTP protocol.
X company's IP sniffer module
Analysis is done inside method
IsValid() of
RtpPacket class.
A decision is taken on base check of the three parameters: RTP version, payload type and header length.
- The payload type is checked if it belongs to a valid range of values from 34 (H263) to 96 (DynMin).
- The header length check is a little more complex.
IPP calculates the RTP header length on base value the CSRC count (field CC) and padding (field P). During this step IPP supposes that a current packet is a RTP packet.
Then it calculates the data length as a difference between the total packet length and the calculated header length - DataLen = TotalPacketLen - HeaderLen.
After that it compares calculated data length with total packet length.
If data length is bigger than total length then it is not RTP.
- RTP version must be 2.
Source code:
bool RtpPacket::IsValid()
{
//check for correct version
if (version != 2) return false;
//check for a known payload type
if (payloadType > rtpPayloadH263 && payloadType < rtpPayloadDynMin) return false;
if (dataLen >= totalLength) return false;
return true;
}
JNetPcap
Analysis is done inside function
validate_rtp() of
packet_protocol.cpp file (line 143 for version 1.3.b3).
The decision is taken by using more parameters. However I am not sure that probability of the recognition is higher. Let's consider the algorithm.
- It checks the RTP version. The version must be 2 also.
- The CSRC count check is empty. The JNetPcap check only low boundary. It must be greater than 15. But CSRC count is 4 bits field and it can't be more 15.
- The payload check is much simpler. It also checks only low boundary. It must be greater than 25.
- Sequence number is checked for zero.
- SSRC is checked for zero.
- Timestamp is checked for zero.
- All other fields if any are also checked for zero.
- If a packet has extension then extension length is also checked for out of bounds.
JNetPcap source code:
int validate_rtp(scan_t *scan) {
if ((scan->buf_len - scan->offset) < sizeof (rtp_t)) { |
register rtp_t *rtp = (rtp_t *)(scan->buf + scan->offset); |
TRACE("INVALID header flad"); |
uint32_t *c = (uint32_t *)(rtp + 1); |
for (int i = 0; i < rtp- >rtp_cc; i ++) { |
TRACE("CSRC[%d]=0x%x", i, BIG_ENDIAN32(c[i])); |
if (BIG_ENDIAN32(c[i]) == 0) { |
TRACE("INVALID CSRC entry is 0"); |
* Check for any duplicates CSRC ids within the table. Normally there |
* can't be any duplicates. |
for (int j = i + 1; j < rtp- >rtp_cc; j ++) { |
if (BIG_ENDIAN32(c[i]) == BIG_ENDIAN32(c[j])) { |
TRACE("INVALID duplicates CSRC entries"); |
rtpx_t * rtpx = (rtpx_t *)( |
register int xlen = BIG_ENDIAN16(rtpx->rtpx_len) * 4; |
if ((!SCAN_IS_FRAGMENT(scan) && |
(scan->offset + xlen > scan->wire_len)) || |
TRACE("INVALID rtpx_len > %d bytes (wire_len) in extension header", |
}
No comments:
Post a Comment