The content of this file is licensed under the Creative Commons
Attribution-Noncommercial-Share Alike 3.0 License.
. '||''|. '||
... .. .||. ... ... || || ... .. .... .... || ..
||' '' || ||' || ||'''|. ||' '' .|...|| '' .|| || .'
|| || || | || || || || .|' || ||'|.
.||. '|.' ||...' .||...|' .||. '|...' '|..'|' .||. ||.
||
'''' v1.2
Copyright (c) 2007 Dallachiesa Michele <micheleDOTdallachiesaATposteDOTit>
======{ Description }==========================================================
rtpbreak detects, reconstructs and analyzes any RTP [rfc1889] session through
heuristics over the UDP network traffic. It works well with SIP, H.323, SCCP
and any other signaling protocol. In particular, it doesn't require the
presence of RTCP packets (voipong needs them) that aren't always transmitted
from the recent VoIP clients. For updates, see "Links" section.
This application is released under licence GPL version 2.
For updates, see section "Links".
======{ How it works }=========================================================
The RTP sessions are composed by an ordered sequence of RTP packets. Those
packets transport the Real Time data using the UDP transport protocol. The RTP
packets must respect some well defined rules in order to be considered valid,
this characteristic allows to define a pattern on the single packet that is
used to discriminate the captured network traffic from packets that can be
RTP and those that securely are not. The fixed RTP header has this format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The following checks are performed:
1. Destination UDP port
The destination UDP port must be even, as specified in [rfc1889]. Beyond
this, it must be greater than 1024. This because in the transport
protocols UDP and TCP the ports <= 1024 are considered privileged and
they can't be used by user applications, like VoIP clients.
2. Minimal packet size
The UDP payload size must be greater than 12 bytes, this is the size of
the fixed header always present in the RTP packets.
3. RTP version
The RTP protocol version always used is 2, so the value of the V field
in the fixed RTP header must be equal to 2.
4. Padding bit
RTP allows to append some bytes as a packet trailer, that must be ignored.
The number of those bytes is specified exactly in the last packet byte. The
P field in the fixed RTP header indicates if this functionality is active.
If it's active, the RTP payload size is adjusted, checking that it's greater
than 0.
5. CSRC list
RTP allows the RTP Mixer to insert a list of contributing sources. This
list, if present, follows immediately the fixed RTP header and it's
composed by addresses (of 32 bits), their number is indicated
by the CC field in the fixed RTP header. If it's present, the RTP payload
size is adjusted, checking that it's greater than 0.
6. Extension bit
RTP allows to extend the fixed RTP header. If it's present, this extension
follows the fixed RTP header and the optional CSRC list. His format
follows:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The length field indicates the extension size, header of the extension
excluded. His presence is indicated by the X field value. If it's active,
the RTP payload size is adjusted, checking that it's greater than 0.
The UDP packets that have passed those controls are considered like
"maybe RTP" packets. Note that the IP and UDP packet checksum isn't
checked because quite often they're erroneously computed by VoIP clients.
The UDP packets that pass those controls are compared with the
already detected RTP sessions (this is called pattern over multiple packets).
The comparison is done considering the following informations:
1. SSRC
The value of the SSRC field in the fixed RTP header indicates the
unique identifier of the Sender of the session. His value is constant
in all RTP packets of the same session.
2. IP addresses and UDP ports
The IP addresses and the UDP ports of the Sender and Receiver are constant
in all RTP packets of the same session.
3. Sequence number
The seq field in the fixed RTP header indicates the packet sequence number,
a value that isn't necessarily initialized to 1 but that it's strictly
increasing in RTP packets of the same session. It's considered a window of
acceptable values for each session, that changes dynamically in the time.
This allows to consider the eventuality that some RTP packets are lost.
4. Timestamp
The ts field in the fixed RTP header indicates the sampling timestamp
of the first byte of the RTP payload, a value strictly increasing in
RTP packets of the same session. Also in this case it's considered a window
of acceptable values for each session, that changes dynamically in the time.
This allows to consider the eventuality that some RTP packets are lost.
If it's identified a possible session, the UDP packet is inserted in
his buffer. If this doesn't happen, a new one is created. When to a session
are assigned a minimal set of UDP packets, this is considered valid
and any UDP packet in his buffer is considered definitely RTP. This must
happen before a timeout, after that the session is considered a false
positive and destroyed.
======{ The Parameters }=======================================================
The accepted parameters by command line are the following:
INPUT
-r <str> Read packets from file (pcap format) <str>
-i <str> Read packets from network interface <str>
-L <int> Force datalink header length == <int>
This is useful in some particular situations, where the interface type
is not correctly recognized by the pcap library.
OUTPUT
-x <str> Set output directory to <str> (def: '.')
Allows to specify the output directory. The files are organized as follows:
- rtp.x.txt : logfile of the rtpbreak process, execution number <x>
- rtp.x.y.pcap : packets of the rtp session number <y>, reconstructed by the
rtpbreak process, execution number <x>
- rtp.x.y.raw : transported data of the rtp session number <y>, reconstructed
by the rtpbreak process, execution number <x>
- rtp.x.y.txt : logfile of the rtp session number <y>, reconstructed
by the rtpbreak process, execution number <x>
-g Fill gaps (lost packets) in .raw files
If some packets are lost, with this option the gaps in the .raw file
are filled with the last received packet. In this way, in a second
moment there won't be synchronization problems mixing multiple RTP streams.
-n Dump noise to 'rtp.x.noise.pcap'
It allows to save in .pcap format the packets that have passed the
single packet pattern but not the multiple packets pattern. This is useful
for debugging and traffic analysis.
-f Disable stdout logging
-F Enable syslog logging
-v Be verbose
SELECT
-m Sniff in promiscuous mode
-p <str> Add pcap filter <str>
The incoming packets are filtered also considering the pcap filter <str>.
-e Expect even destination UDP port
The RTP packets must have an even destination UDP port. This should be
always true, anyway some VoIP networks (like Yahoo) don't respect this
rule.
-u Expect unprivileged source/destination UDP ports (>1024)
The RTP packets must have an UDP port >1024.
-y <int> Expect RTP payload type == <int>
The RTP packets must have exactly this payload type. For example, if we
are interested in a G.711 ulaw RTP stream we can add the option -y 0,
value obtained by the -k option.
-l <int> Expect RTP payload length == <int>
The RTP payload length must be exactly <int> (that is constant in all
packets of the same RTP session).
-t <float> Set packet timeout to <float> seconds (def: 2.00)
When to a session aren't assigned RTP packets for <float> seconds,
it's considered terminated.
-T <float> Set pattern timeout to <float> seconds (def: 0.25)
The pattern over multiple packets must be verified in <float> seconds
from the session creation time.
-P <int> Set pattern packets count to <int> (def: 5)
An RTP session is considered as so if are assigned to herself <int>
packets before a predefined timeout, specified by the -T option. If
this condition isn't verified, the session is considered a false positive
and destroyed.
EXECUTION
-U <str> Run as user <str>
-G <str> Run as group <str>
If the group is not specified, the user group will be forced.
-D Run in background (option -f implicit)
MISC
-k List known RTP payload types
It dumps a list of known RTP payload types. Note that, because of the
unuseful functionality called "Dynamic RTP Payload", those values
shouldn't be considered too much. The rtp_payload_type <-> codec association
is in fact concorded through the Signaling messages (SIP,H.323,...),
assigning new values also for those codecs that have already a standard
and predefined value.
======{ Problems and solutions }================================================
In this section are presented some particular situations, with
relative solutions.
Problem: an improbable high number of RTP sessions is recognized and
a lot of noise packets are detected.
Cause: probably there's some type of silence suppression.
Solution: dilate the timeouts: ./rtpbreak -i eth0 -n -t100 -T100
Problem: an RTP session is not recognized and some noise packets are
detected.
Cause: probably the conversation has been immediately terminated.
Solution: reduce the number of required packets for the pattern:
./rtpbreak -i eth0 -n -P2
Problem: the expected RTP sessions are not recognized.
Possible cause: the VoIP client is broken, the network interface is not in
promisc mode, the conversation is very disturbed, the conversation
was immediately terminated.
Solution: dilate the timouts and reduce the numer of required packets for
the pattern: ./rtpbreak -i eth0 -m -n -P2 -t100 -T100
======{ Example }===============================================================
In this example we 1. sniff (with tcpdump), 2. reconstruct (with rtpbreak) and
3. decode (with sox) a conversation between two VoIP Wireless phones.
1. We sniff the network traffic:
----log begin----
xenion@gollum:~/dev/rtpbreak-1.2$ sudo tcpdump -s 0 -i eth2 -w zyxel_zyxel.pcap
....
xenion@gollum:~/dev/rtpbreak-1.2$ du -h zyxel_zyxel.pcap
3.4M zyxel_zyxel.pcap
xenion@gollum:~/dev/rtpbreak-1.2$
----log end----
2. We reconstruct the RTP sessions:
----log begin----
xenion@gollum:~/dev/rtpbreak-1.2$ ./rtpbreak -r zyxel_zyxel.pcap
+ rtpbreak v1.2 running here!
+ pid: 3647, date/time: 14/08/2007#10:39:24
+ Configuration
+ INPUT
Packet source: rxfile 'zyxel_zyxel.pcap'
Force datalink header length: disabled
+ OUTPUT
Output directory: '.'
Fill gaps: disabled
Dump noise: disabled
Logfile: './rtp.0.txt'
stdout logging: enabled
Syslog logging: disabled
Be verbose: disabled
+ SELECT
Sniff in promiscuous mode: disabled
Add pcap filter: disabled
Expecting even destination UDP port: disabled
Expecting unprivileged source/destination UDP ports: disabled
Expecting RTP payload type: any
Expecting RTP payload length: any
Packet timeout: 2.00 seconds
Pattern timeout: 0.25 seconds
Pattern packets: 5
+ EXECUTION
Running as user/group: xenion/xenion
Running daemonized: disabled
* You can dump stats sending me a SIGUSR2 signal
* Reading packets...
! [rtp0] detected: pt=0(g711U) 192.168.0.30:2072 => 192.168.0.20:2074
! [rtp1] detected: pt=0(g711U) 192.168.0.20:2074 => 192.168.0.30:2072
* [rtp1] maybe found reverse RTP stream: [rtp0]
* eof reached.
--
Caught SIGTERM signal (15), cleaning up...
--
* [rtp1] close: pkts buffer:0 flushed:2800 lost:115 (3.95%), length:1m27s
* [rtp0] close: pkts buffer:0 flushed:2819 lost:106 (3.62%), length:1m28s
+ Status
Alive RTP Sessions: 0
Closed RTP Sessions: 2
Detected RTP Sessions: 2
Flushed RTP packets: 5619
Lost RTP packets: 221 (3.78%)
Noise (false positive, maybe RTCP,NBNS,DNS) packets: 0
+ No active RTP streams
xenion@gollum:~/dev/rtpbreak-1.2$
----log end----
In output we have 7 files:
----log begin----
xenion@gollum:~/dev/rtpbreak-1.2$ ls rtp.*.*
rtp.0.0.pcap rtp.0.0.txt rtp.0.1.raw rtp.0.txt
rtp.0.0.raw rtp.0.1.pcap rtp.0.1.txt
xenion@gollum:~/dev/rtpbreak-1.2$
----log end----
The details:
----log begin----
xenion@gollum:~/dev/rtpbreak-1.2$ cat rtp.0.0.txt
Sniffer: rtpbreak v1.2
Logfile: rtp.0.txt
RTP stream files: rtp.0.0.*
Packet source: rxfile 'zyxel_zyxel.pcap'
Execution date/time: 14/08/2007#10:39:24
First seen packet: 15/03/2007#14:14:48
Stream peers: 192.168.0.30:2072 => 192.168.0.20:2074
RTP payload type: 0 (ITU-T G.711 PCMU)
Last seen packet: 15/03/2007#14:16:16
Length: 1m28s
Flushed packets: 2819
Lost packets: 106 (3.62%)
RTP payload length: 240 bytes (fixed)
xenion@gollum:~/dev/rtpbreak-1.2$ cat rtp.0.1.txt
Sniffer: rtpbreak v1.2
Logfile: rtp.0.txt
RTP stream files: rtp.0.1.*
Packet source: rxfile 'zyxel_zyxel.pcap'
Execution date/time: 14/08/2007#10:39:24
First seen packet: 15/03/2007#14:14:49
Stream peers: 192.168.0.20:2074 => 192.168.0.30:2072
RTP payload type: 0 (ITU-T G.711 PCMU)
Maybe reverse RTP stream: 0
Last seen packet: 15/03/2007#14:16:16
Length: 1m27s
Flushed packets: 2800
Lost packets: 115 (3.95%)
RTP payload length: 240 bytes (fixed)
xenion@gollum:~/dev/rtpbreak-1.2$
----log end----
We have 2 RTP audio streams encoded with G.711 u-law, the conversation
length is 1m27s and ~ 3.7% of the RTP packets were lost.
We decode now the .raw file and then we mix the two channels with sox:
----log begin----
xenion@gollum:~/dev/rtpbreak-1.2$ sox -r8000 -c1 -t ul rtp.0.0.raw -t wav s0.wav
xenion@gollum:~/dev/rtpbreak-1.2$ sox -r8000 -c1 -t ul rtp.0.1.raw -t wav s1.wav
xenion@gollum:~/dev/rtpbreak-1.2$ sox -m s0.wav s1.wav call01.wav
xenion@gollum:~/dev/rtpbreak-1.2$
----log end----
Now we've our call01.wav, ready for listening :)
======{ Dependencies and compilation }=========================================
Required libs: libpcap (>=0.7) and libnet (>=1.1).
In debian, you need the following packages:
libnet1
libnet1-dev
libpcap0.8
libpcap0.8-dev
To compile: make
======{ Links }================================================================
Antifork: http://www.antifork.org/
my stuff: http://xenion.antifork.org/
rtpbreak: http://xenion.antifork.org/rtpbreak/
======{ Eof }==================================================================