Date created: 07/29/13 16:44:17. Last modified: 09/09/13 10:55:06

Extracting RTP Payload from PCAP

Extraction is using rtpbreak;

Documentation is here

Download here (local mirror)

sudo apt-get install libnet1 libnet1-dev libpcap0.8 libpcap0.8-dev
wget /uploads/voice/rtpbreak-1.3.tgz
tar -xvzf rtpbreak-1.3.tgz
cd rtpbreak-1.3/
make

# If errors are displaid regarding missing pcap functions;
main.o: In function `loop':
main.c:(.text+0x453): undefined reference to `pcap_next'

# Change line 17 of src/Makefile from

$(CC) $(LIBS) main.o common.o net.o -o rtpbreak

# To...

$(CC) main.o common.o net.o -o rtpbreak $(LIBS)

# Then 'make clean' and 'make' again

Spit a pcap file in it various components (see rtpbreak documentation for further details)

# -g Fill the gaps of lost packets in raw dumps with the last sniffed packet, preventing desynchronization problems when decoding/mixing multiple RTP streams (with sox, ...) 
# -r  Read packets from file (pcap format)  
# -d  Set the output directory to  
rtpbreak -g -d output/ -r ./2013-07-26--09-04-28--test-capture.pcap

This produces many RTP streams, two of them form one call (each direction of audio).
rtp.0.0.raw and rtp.0.1.raw are one call for example

ls output/
rtp.0.0.pcap   rtp.0.12.pcap  rtp.0.15.pcap  rtp.0.18.pcap  rtp.0.20.pcap  rtp.0.23.pcap  rtp.0.26.pcap  rtp.0.2.pcap  rtp.0.5.pcap  rtp.0.8.pcap
rtp.0.0.raw    rtp.0.12.raw   rtp.0.15.raw   rtp.0.18.raw   rtp.0.20.raw   rtp.0.23.raw   rtp.0.26.raw   rtp.0.2.raw   rtp.0.5.raw   rtp.0.8.raw
rtp.0.0.txt    rtp.0.12.txt   rtp.0.15.txt   rtp.0.18.txt   rtp.0.20.txt   rtp.0.23.txt   rtp.0.26.txt   rtp.0.2.txt   rtp.0.5.txt   rtp.0.8.txt
rtp.0.10.pcap  rtp.0.13.pcap  rtp.0.16.pcap  rtp.0.19.pcap  rtp.0.21.pcap  rtp.0.24.pcap  rtp.0.27.pcap  rtp.0.3.pcap  rtp.0.6.pcap  rtp.0.9.pcap
rtp.0.10.raw   rtp.0.13.raw   rtp.0.16.raw   rtp.0.19.raw   rtp.0.21.raw   rtp.0.24.raw   rtp.0.27.raw   rtp.0.3.raw   rtp.0.6.raw   rtp.0.9.raw
rtp.0.10.txt   rtp.0.13.txt   rtp.0.16.txt   rtp.0.19.txt   rtp.0.21.txt   rtp.0.24.txt   rtp.0.27.txt   rtp.0.3.txt   rtp.0.6.txt   rtp.0.9.txt
rtp.0.11.pcap  rtp.0.14.pcap  rtp.0.17.pcap  rtp.0.1.pcap   rtp.0.22.pcap  rtp.0.25.pcap  rtp.0.28.pcap  rtp.0.4.pcap  rtp.0.7.pcap  rtp.0.txt
rtp.0.11.raw   rtp.0.14.raw   rtp.0.17.raw   rtp.0.1.raw    rtp.0.22.raw   rtp.0.25.raw   rtp.0.28.raw   rtp.0.4.raw   rtp.0.7.raw
rtp.0.11.txt   rtp.0.14.txt   rtp.0.17.txt   rtp.0.1.txt    rtp.0.22.txt   rtp.0.25.txt   rtp.0.28.txt   rtp.0.4.txt   rtp.0.7.txt

Use sox to convert the two payload streams into two mono wav files, and them mix them together into a single mono file.

sox -r8000 -c1 -t ul output/rtp.0.0.raw -t wav 0.wav
sox -r8000 -c1 -t ul output/rtp.0.1.raw -t wav 1.wav
sox -m 0.wav 1.wav call.wav

Now run through and conver all for a given PCAP file - rtp-extract.sh

#!/bin/bash 

pcapfile=$1
rtpfolder=`dirname $pcapfile`

rtpbreak -g -d $rtpfolder -r $pcapfile

streams=(`find $rtpfolder -type f -name *.raw | sort -t'.' -n -k3`)

for ((i=0; i<${#streams[*]}; i++))
do
    firstfilename=`basename ${streams[$i]} '.raw'`
    sox -r8000 -c1 -t ul ${streams[$i]} -t wav $rtpfolder/$firstfilename.wav
    j=$i
    let i=$i+1
    if [ "$i" -lt "${#streams[*]}" ];
    then
        secondfilename=`basename ${streams[$i]} '.raw'`
        sox -r8000 -c1 -t ul ${streams[$i]} -t wav $rtpfolder/$secondfilename.wav
        # Uncomment to join consecutive files together, could be wrong if a stream is missing
        #sox -m $rtpfolder/$firstfilename.wav $rtpfolder/$secondfilename.wav $rtpfolder/joint-$firstfilename-$i.wav
    fi

done