Export raw packet bytes in tshark, tcpdump, or similar?

ctitze picture ctitze · Dec 19, 2016 · Viewed 7.9k times · Source

Context:

I have a *.pcap file with many WLAN probe requests. My goal is to extract the WLAN management frame of each probe request as raw bytes (that is, no headers and no extra information - only the raw bytes like they were originally captured).

In Wireshark, I can simply right-click the management frame and select "Export Packet Bytes...": Wireshark Raw Packet Byte Extraction

If I select "RAW" as the file format, Wireshark gives me exactly what I want: A file containing nothing more than the selected bytes.

Problem:

I need to automate this task programatically. I came across tools like tshark, tcpdump, capedit, etc. However, none of these tools seem to allow me to extract the WLAN management frame and nothing more.

While I was able to get the desired bytes as ASCII on stdout using tcpdump, I wasn't able to save them to a file or into a variable. Additionally, I was only able to do it for a single probe request, not for all probe requests in the *.pcap file.

Current Approach:

As mentioned above, I was able to get the desired bytes as ASCII on stdout:

$ tcpdump -r capture.pcap -c 1 -x
reading from file capture.pcap, link-type IEEE802_11_RADIO (802.11 plus radiotap header)
11:24:52.933799 1.0 Mb/s 2457 MHz 11b -77dBm signal antenna 1 Probe Request () [1.0* 2.0* 5.5* 6.0 9.0 11.0* 12.0 18.0 Mbit]
    0x0000:  0000 0108 8284 8b0c 1296 1824 3204 3048
    0x0010:  606c 2d1a ac01 02ff ff00 0000 0000 0000
    0x0020:  0000 0000 0000 0000 0000 0000 0000

To extract the raw bytes, I can simply pipe this output into grep, sed, and xxd:

$ tcpdump -r capture.pcap -c 1 -x | grep "0x00" | sed  's/0x[[:xdigit:]]*:[[:space:]]*//g' | xxd -r -p > rawbytefile

Obviously, this is a rather hacky way of accomplishing what I want and there must be a better way. Nobody wants code that's highly dependent on the human-centric output of other people's programs.

Questions:

  1. How can I extract the WLAN management frame in a proper way? (On the command line/programatically - using Bash, Python, etc.)
  2. How can this be done for every probe request within the *.pcap-file? (Again, in a proper way - building another hacky loop by parsing ASCII output is not really what one should do...)

Answer

kaitoy picture kaitoy · Dec 20, 2016

You can achieve it using my Java library, Pcap4J.

Add pcap4j-core.jar and pcap4j-packetfactory-static.jar to your class path and execute code like below:

PcapHandle handle = Pcaps.openOffline("/path/to/your.pcap");
while (true) {
  try {
    Packet packet = handle.getNextPacketEx();
    Dot11ProbeRequestPacket probe = packet.get(Dot11ProbeRequestPacket.class);
    if (probe == null) { continue; }
    byte[] mgmtFrame = ByteArrays.getSubArray(
      probe.getRawData(),
      probe.getHeader().getFrameControl().isOrder() ? 28 : 24
    );
    System.out.println(ByteArrays.toHexString(mgmtFrame, ""));
  } catch (EOFException e) {
    break;
  } catch (PcapNativeException | TimeoutException | NotOpenException e) {
    e.printStackTrace();
  }
}
handle.close();