Pcap Deconstruction

Which bytes mean what
4 min |  Ross Jacobs |  July 7, 2019

Table of Contents


You may be familiar with protocol diagrams with 32-bit/4 byte widths like RFC793’s TCP header. The diagrams below have a 128-bit/16 byte width to match typical hexdump output.

Pcap Internals

                            PCAP HEADER (24B)

      0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    ┣━━━━━━━━━━━━━━━╋━━━━━━━┳━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
    ┃  Magic Number ┃ MajVer┃ MinVer┃    ThisZone   ┃    Sigfigs    ┃
    ┣━━━━━━━━━━━━━━━╋━━━━━━━┻━━━━━━━╋━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛
    ┃    Snaplen    ┃ Data Link Type┃
    ┗━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛



                           PACKET HEADER (16B)

      0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    ┣━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
    ┃ Timestamp Sec ┃ Timestamp μSec┃ Saved Pkt Len ┃ Real Pkt Len  ┃
    ┗━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛



                         N-PACKET PCAP STRUCTURE

                           ╔═════════════════╗
                           ║       PCAP      ║
                           ║      HEADER     ║
                           ╚═════════════════╝

                           ║ PACKET HEADER 1 ║
                           ╠═════════════════╣
                           ║      PACKET     ║
                           ║        #1       ║
                           ╠═════════════════╣
                           ║ PACKET HEADER 2 ║
                           ╠═════════════════╣
                           ║      PACKET     ║
                           ║        #2       ║
                           ╠═════════════════╣
                           ║                 ║

                                   ● ● ●

                           ║                 ║
                           ╠═════════════════╣
                           ║ PACKET HEADER N ║
                           ╠═════════════════╣
                           ║      PACKET     ║
                           ║        #N       ║
                           ╚═════════════════╝

This is a brief overview of pcap fields, but more in-depth articles exist.

Example: Deconstruction of 2 ARP capture

In the ARP example packet, padding is required to increase the payload to a minimum of 64 bytes
(See RFC 1042, section “For IEEE 802.3”).

                     ARP EXAMPLE PACKET (64B)

  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━   ╔═══════╗
     Destination MAC            Source MAC        Type  ║  4 -> ║
╔═══════════════════════╦═══════════════════════╦═══════╩- - - -╣
║ <- ARP Control fields        Sender MAC          Sender IP    ║
╠ - - - - - - - - - - - ╬ - - - - - - -╦════════╩═══════════════╝
║      Target MAC           Target IP  ║     PADDING            ╻
╚═══════════════════════╩══════════════╝        ┏━━━━━━━━━━━━━━━┫
╻                                               ┃ FCS (Stripped)┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛

This example goes over how to parse a pcap into its contituent parts (pcap header, packet headers and packets). This is what Wireshark and tools like it do to read a pcap. More in-depth dissections written by others are linked to below.

This example parses this two-packet ARP capture:

00000000: d4c3b2a1 02000400 00000000 00000000
00000010: ffff0000 01000000 21a96241 90330400
00000020: 3c000000 3c000000 ffffffff ffff0007
00000030: 0daff454 08060001 08000604 00010007
00000040: 0daff454 18a6ac01 00000000 000018a6
00000050: ad9f0601 04000000 00020100 03020000
00000060: 05010301 21a96241 b2b40500 3c000000
00000070: 3c000000 ffffffff ffff0007 0daff454
00000080: 08060001 08000604 00010007 0daff454
00000090: 18a6ac01 00000000 000018a6 ac8d0100
000000a0: 00100001 00000000 00002043 4b414141
  1. Take 24 bytes as pcap header.

    00000000: d4c3b2a1 02000400 00000000 00000000
    00000010: ffff0000 01000000
    
  2. Take 16 bytes as packet header

    00000010:                   21a96241 90330400
    00000020: 3c000000 3c000000
    
  3. Real packet length (last 4 bytes) => 0x3c => 60. So take 60 bytes for the ARP packet.

    00000020:                   ffffffff ffff0007
    00000030: 0daff454 08060001 08000604 00010007
    00000040: 0daff454 18a6ac01 00000000 000018a6
    00000050: ad9f0601 04000000 00020100 03020000
    00000060: 05010301
    
  4. Take 16 bytes as packet header.

    00000060:          21a96241 b2b40500 3c000000
    00000070: 3c000000
    
  5. Real packet length (last 4 bytes) = 0x3c => 60. So take 60 bytes for the ARP packet.

    00000060:          ffffffff ffff0007 0daff454
    00000080: 08060001 08000604 00010007 0daff454
    00000090: 18a6ac01 00000000 000018a6 ac8d0100
    000000a0: 00100001 00000000 00002043 4b414141
    
  6. We’ve reached the end of the file, and there are no more bytes to parse.

Discussion: Cut short in the middle of a packet

If we had reached the end of the file before the 60 bytes of packet length had been parsed, tshark would mark this capture as “damaged”. If you’ve even seen tshark complain that “the capture file appears to have been cut short in the middle of a packet”, this is what it’s talking about.

It’s easy to generate a pcap and its damaged twin by dropping the last byte of a capture:

bash$ tshark -c 1 -w - | tee orig.pcap | head --bytes=-1 > damaged.pcap

In this example, we create an orig.pcap that has the original data, and a damaged.pcap that lacks one byte. If we diff the files, we can see that the damaged pcap is indeed missing the last byte.

bash$ diff <(xxd orig.pcap) <(xxd damaged.pcap)
32c32
< 000001f0: 0000 0000 0000 0000 6c00 0000            ........l...
---
> 000001f0: 0000 0000 0000 0000 6c00 00              ........l..

And when reading the damaged.pcap, we will get the expected error:

bash$ tshark -r damaged.pcap
1 0.000000000    10.0.2.15 → 8.8.8.8      ICMP 98 Echo (ping) request  id=0x1d5b, seq=33560/6275, ttl=64

tshark: The file "damaged.pcap" appears to have been cut short in the middle of a packet.

Both of these will equivalently fix in place:

bash$ tshark -r $capture -w $capture
bash$ editcap $capture $capture

tshark and editcap will read the file and fix any packet lengths that are incorrect. For seriously damaged pcaps, pcapfix will try to salvage it by looking for packets byte-by-byte.

Further Reading

This chapter also contains a brief article on the pcap format.