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>
======{ Descrizione }==========================================================
rtpbreak riconosce, ricostruisce ed analizza qualsiasi sessione RTP [rfc1889]
mediante euristiche sul traffico di rete UDP. Funziona bene con SIP, H.323,
SCCP e qualsiasi altro protocollo di segnalazione. In particolare, non richiede
la presenza dei pacchetti di controllo RTCP (voipong li richiede) che non
sempre vengono trasmessi dagli attuali client VoIP.
Questa applicazione e' rilasciata sotto licenza GPL versione 2.
Per aggiornamenti, vedi la sezione "Links".
======{ Funzionamento }========================================================
Le sessioni RTP sono costituite da una sequenza ordinata di pacchetti
RTP. Questi trasportano le informazioni Real Time utilizzando il protocollo di
trasporto UDP. I pacchetti RTP devono rispettare alcune regole ben definite
per essere considerati validi, questa caratteristica permette di definire
un pattern sul singolo pacchetto che viene utilizzato al fine di poter
discriminare il traffico di rete catturato fra pacchetti che potrebbero
essere di tipo RTP e pacchetti che sicuramente non lo sono. L'header fisso
RTP ha il seguente formato:
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 |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
I controlli che vengono effettuati sono i seguenti:
1. Porta UDP di destinazione
La porta UDP di destinazione deve essere pari, come indicato in
[rfc1889]. Inoltre deve essere maggiore di 1024, questo perche' nei
protocolli di trasporto UDP e TCP le porte inferiori oppure uguali a 1024
sono considerate privilegiate e non utilizzabili dalle applicazioni utente,
come ad esempio i client VoIP.
2. Dimensione minima del pacchetto
La dimensione del payload del pacchetto UDP deve essere superiore a 12 byte,
dimensione dell'header fisso sempre presente nei pacchetti RTP.
3. versione RTP
La versione del protocollo RTP attualmente in uso e' la 2. Viene quindi
verificato che il campo V dell'header fisso RTP abbia come valore 2.
4. Padding bit
RTP consente di inserire alcuni byte di riempimento alla fine del pacchetto,
che devono essere ignorati. Il numero di byte di riempimento e' indicato
esattamente nell'ultimo byte del pacchetto. Il campo P dell'header fisso
RTP indica quando questa funzionalita' e' attiva. Se attiva, la dimensione
del payload RTP viene aggiustata di conseguenza, controllando nuovamente
che sia superiore a 0.
5. lista CSRC
RTP consente ai Mixer RTP di inserire una lista di sorgenti che hanno
contribuito a creare i dati trasportati. Questa lista, se presente, segue
immediatamente l'header fisso RTP e si compone di indirizzi di 32 bit
ciascuno, il loro numero e' indicato dal valore del campo CC dell'header
fisso RTP. Se presenti, la dimensione del payload RTP viene aggiustata di
conseguenza, controllando nuovamente che sia superiore a 0.
6. Extension bit
RTP consente di estendere l'header fisso RTP. Se presente, questa estensione
segue l'header fisso RTP e la lista opzionale CSRC. Il suo formato e'
il seguente:
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 |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Il campo length indica la dimensione dell'estensione, header dell'estensione
escluso. La sua presenza e' indicata dal valore del campo X. Se attivo,
la dimensione del payload RTP viene aggiustata di conseguenza, controllando
nuovamente che sia superiore a 0.
I pacchetti UDP che superano questi controlli sono considerati dei
possibili pacchetti RTP. Si noti che il checksum dei pacchetti IP ed UDP
non viene controllato perche' molto spesso vengono erroneamente calcolati
dai client VoIP, come verificato durante i test di laboratorio. I pacchetti
UDP che superano questi controlli vengono confrontati con le sessioni RTP
precedentemente riconosciute (pattern su pacchetti multipli). Il confronto
avviene considerando le seguenti informazioni:
1. SSRC
Il valore del campo SSRC dell'header fisso RTP indica l'identificativo
univoco del Sender della sessione. Il suo valore e' costante in tutti i
pacchetti RTP appartenenti alla sessione.
2. indirizzi IP e porte UDP
Gli indirizzi IP e le porte UDP di Sender e Receiver sono costanti in
tutti i pacchetti RTP appartenenti alla sessione.
3. Sequence number
Il campo seq nell'header fisso RTP indica il sequence number del pacchetto,
un valore che non necessariamente viene inizializzato a 1 ma che e'
strettamente crescente nei pacchetti appartenenti alla sessione. Viene
considerata una finestra di valori accettabili per ciascuna sessione, che
varia dinamicamente nel tempo. Questo permette di considerare l'eventualita'
che dei pacchetti RTP vengano perduti.
4. Timestamp
Il campo ts dell'header fisso RTP indica il timestamp del campionamento
riferito al primo byte del payload RTP, un valore strettamente crescente
nei pacchetti appartenenti alla sessione. Viene anche in questo caso
considerata una finestra di valori accettabili per ciascuna sessione, che
varia dinamicamente nel tempo. Questo permette di considerare l'eventualita'
che dei pacchetti RTP vengano perduti.
Se viene identificata una sessione corrispondente, il pacchetto UDP viene
inserito nel buffer dei pacchetti appartenenti a quella sessione. Se non
viene identificata alcuna sessione corrispondente, viene creata una nuova
sessione. Quando ad una sessione vengono riconosciuti un numero minimo
predefinito di pacchetti UDP, questa viene considerata valida e qualsiasi
pacchetto UDP nel buffer associato a tale sessione viene considerato
definitivamente RTP. Questo deve verificarsi entro un certo tempo, oltre il
quale la sessione viene considerata un falso positivo e quindi distrutta.
======{ I Parametri }==========================================================
I parametri accettati da linea di comando sono i seguenti:
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>
E' utile in alcune situazioni particolari, dove il tipo di interfaccia non e'
correttamente riconosciuto dalla libreria pcap.
OUTPUT
-x <str> Set output directory to <str> (def: '.')
Permette di specificare la directory di output. I file sono cosi' organizzati:
- rtp.x.txt : file di log del processo rtpbreak, esecuzione numero <x>
- rtp.x.y.pcap : pacchetti della sessione rtp numero <y> ricostruita
dal processo rtpbreak, esecuzione numero <x>
- rtp.x.y.raw : dati trasportati dalla sessione rtp numero <y>
ricostruita dal processo rtpbreak, esecuzione numero <x>
- rtp.x.y.txt : file di log della sessione rtp numero <y> ricostruita
dal processo rtpbreak, esecuzione numero <x>
-g Fill gaps (lost packets) in .raw files
Se vengono persi dei pacchetti, i salti nel file .raw vengono riempiti con il
pacchetto precedente. Cosi' facendo, in un secondo momento non si hanno
problemi di desincronizzazione di piu' flussi rtp durante il mixing.
-n Dump noise to 'rtp.x.noise.pcap'
Permette di salvare in formato pcap i pacchetti che hanno superato il controllo
del pattern su pacchetto singolo ma non quello su pacchetti multipli. Utile per
debugging e analisi del traffico.
-f Disable stdout logging
-F Enable syslog logging
-v Be verbose
SELECT
-m Sniff in promiscuous mode
-p <str> Add pcap filter <str>
I pacchetti in ingresso vengono filtrati considerando anche il
filtro pcap <str>.
-e Expect even destination UDP port
Impone che i pacchetti RTP abbiano la porta UDP pari. Anche se dovrebbe essere
sempre cosi', alcune reti VoIP (come Yahoo Messenger) non rispettano questo
vincolo.
-u Expect unprivileged source/destination UDP ports (>1024)
Impone che i pacchetti RTP abbiano la porta UDP > di 1024.
-y <int> Expect RTP payload type == <int>
Impone un particolare tipo di payload. Ad esempio, se si e' interessati
ad un flusso audio G.711 ulaw possiamo aggiungere l'opzione -y 0, valore
ottenuto dall'output dell'opzione -k.
-l <int> Expect RTP payload length == <int>
Impone una particolare dimensione del payload RTP (che e' costante in tutti
i pacchetti dello stesso flusso).
-t <float> Set packet timeout to <float> seconds (def: 2.00)
Quando ad una sessione non vengono riconosciuti pacchetti RTP per <float>
secondi, questa viene considerata terminata.
-T <float> Set pattern timeout to <float> seconds (def: 0.25)
Il pattern su pacchetti multipli deve essere verificato entro <float> secondi,
altrimenti la sessione viene considerata un falso positivo e distrutta.
-P <int> Set pattern packets count to <int> (def: 5)
Una sessione RTP viene considerata tale se le vengono riconosciuti <int>
pacchetti entro un certo tempo, specificato dall'opzione -T. Se questa
condizione non si verifica, la sessione viene considerata un falso positivo
e quindi distrutta.
EXECUTION
-U <str> Run as user <str>
-G <str> Run as group <str>
Se il gruppo non viene specificato, viene forzato il gruppo dell'utente.
-D Run in background (option -f implicit)
MISC
-k List known RTP payload types
Mostra la lista di tipi di payload RTP conosciuti. Si noti che, a causa
dell'inutile funzionalita' chiamata "Dynamic RTP Payload", non si dovrebbe
fare troppo affidamento su questi valori. L'associazione rtp_payload_type <->
codec viene infatti concordata nei messaggi di Signaling (SIP,H.323,...),
assegnando nuovi valori anche per i codec che ne avrebbero gia' uno standard.
======{ Problemi e soluzioni }=================================================
Vengono di seguito presentate alcune situazioni particolari, con relative
soluzioni.
Problema: vengono riconosciute un numero esagerato di sessioni RTP e
vengono rilevati molti pacchetti di rumore.
Motivo: probabilmente c'e' soppressione dei silenzi.
Soluzione: dilatare i timeout: ./rtpbreak -i eth0 -n -t100 -T100
Problema: non viene riconosciuta una sessione RTP e vengono rilevati
alcuni pacchetti di rumore.
Motivo: probabilmente la conversazione e' stata terminata subito.
Soluzione: ridurre il numero di pacchetti richiesti per il pattern:
./rtpbreak -i eth0 -n -P2
Problema: non vengono riconosciute le sessioni aspettate.
Possibili motivi: il client VoIP ha un comportamento anomalo, l'interfaccia di
rete non e' in modalita' promiscua, la conversazione e' molto disturbata,
la conversazione e' stata interrotta rapidamente.
Soluzione: dilatare i timeout e ridurre il numero di pacchetti richiesti per
il pattern: ./rtpbreak -i eth0 -m -n -P2 -t100 -T100
======{ Esempio di utilizzo }==================================================
In questo esempio viene 1. sniffata (con tcpdump), 2. ricostruita (con
rtpbreak) e 3. decodificata (con sox) una conversazione fra due telefoni
VoIP Wireless.
1. sniffiamo il traffico di rete:
----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. ricostruiamo le sessioni RTP:
----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 abbiamo quindi 7 file:
----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----
Vediamo i dettagli di ciascun flusso rtp:
----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----
Abbiamo 2 flussi RTP audio codificati in G.711 u-law, la conversazione e'
durata 1m27s e sono stati persi circa il 3.7% dei pacchetti RTP. Decodifichiamo
i due file .raw e mixiamo i due canali con 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----
Adesso abbiamo il nostro call01.wav, pronto per essere ascoltato :)
======{ Dipendenze e compilazione }============================================
Sono richieste le librerie libpcap (>=0.7) e libnet (>=1.1).
In debian, sono richiesti i seguenti pacchetti:
libnet1
libnet1-dev
libpcap0.8
libpcap0.8-dev
Per compilare: make
======{ Links }================================================================
Antifork: http://www.antifork.org/
my stuff: http://xenion.antifork.org/
rtpbreak: http://xenion.antifork.org/rtpbreak/
======{ Eof }==================================================================