1

I was able to create a wav file from a wireshark capture. Here is how I do it.

1. I use tcpdump to capture all the packets and filter for RTP packets. Each RTP packet has a "Synchornization source identifier" and that how you can filter by an audio stream:

enter image description here

That picture shows an Opus codec but if on my phone call I was using ulaw then it would show RTP.

2. Then I save that capture as another pcap file.

3. Then if I use a program to iterate through every packet and remove the first 12 bytes of the payload and append those bytes to a file I end up with a file that I can listen too on audacity by selecting the correct format. Actually I can convert that audio.ulaw file to wav with this command:

# apt-get install ffmpeg -y
ffmpeg -f mulaw -ar 8000 -i audio.ulaw -acodec pcm_s16le -ar 8000 -ac 1 output.wav

Now I am curios how can I build a playable file and do the same thing I did using the ulaw codec but with Opus. I know that the sdp packet contains all the information. How can I build an opus file based on that capture. I know the capture is correct because Wireshark is able to play that opus stream if I go to Telephone -> VOIP Calls -> Play Streams:

enter image description here

This is how I constructed the ulaw file that worked and its the same idea with opus. Its a c# program that reads data from each packet. It checks that the sequence is correct and for now that I am testing I harcoded the values:

using SharpPcap;
using SharpPcap.LibPcap;

var inputFilePath = @"C:\temp.pcap"; var outputFilePath = @"C:\raw.opus";

// Open the pcap file using var reader = new CaptureFileReaderDevice(inputFilePath); reader.Open();

using var outputFileStream = new FileStream(outputFilePath, FileMode.Create);

var lastLength = 0;

var i = 0;

// harcoded because of wireshark capture told me var lastSequence = 20585;

// Read packets while (reader.GetNextPacket(out var packet) == GetPacketStatus.PacketRead) { i++;

var data = packet.Data;

// ignore small packets
if (data.Length < 54)
{
    continue;
}

// get the id of packet. In reality this is 4 bytes long but since my capture is already a filter this works for now
if (packet.Data[0x35] != 0x3c)
{
    continue;
}

// convert sequence using little endian to a unsigned int
// this sequence has to increment
byte a = packet.Data[0x2c];
byte b = packet.Data[0x2d];

// little indean
var s = BitConverter.ToUInt16(new byte[] { b, a });
if (s == lastSequence)
{
    // good
    lastSequence++;
}
else
{
    Console.WriteLine("errrr");
    throw new NotImplementedException();
}


var audio = packet.Data[54..];

outputFileStream.Write(audio);    

}

// Cleanup outputFileStream.Close(); reader.Close();

Tono Nam
  • 889

0 Answers0