Linux and macOS

tcpdump to a PCAP file: write, rotate and fix the usual errors

Updated ยท Every command run or checked against its tool's documentation

Free uploads create public reports. Use only sanitized captures; choose private analysis for sensitive traffic.

By default tcpdump prints one summary line per packet to the terminal, and a scrolling screen is not evidence you can hand over. Writing tcpdump to a PCAP file takes one flag, -w, and gives you a file that Wireshark, tshark or A-Packets can read later. The flag is the easy part. Choosing the interface, keeping each file under an upload limit and making sense of the error tcpdump prints when it refuses are where captures go wrong, so this guide covers those too. The commands work the same on Linux and macOS unless a step says otherwise.

A-Packets HTTP Headers view of a web server capture: SQL injection strings in request URIs
A capture taken next to a web server, opened in A-Packets: the HTTP Headers view of a public DVWA lab capture shows SQL injection strings in the request URIs, exactly as the server received them.

Find the interface the traffic crosses

sudo tcpdump -D

-D lists the interfaces tcpdump can open, numbered, with flags such as Up, Running and Wireless. On a Linux server the one with the default route is usually eth0 or a name like ens160; ip route shows which. On a Mac, Wi-Fi is usually en0. Linux also offers -i any, which records every interface at once. The file then uses the Linux cooked format instead of Ethernet: tcpdump 4.99 reports it as LINUX_SLL2, A-Packets reads it, and each packet keeps one link-layer address, the sender's, instead of both MAC addresses. That loss matters only for layer-2 questions such as ARP spoofing, where you want a real Ethernet interface.

Write packets to a file, not the screen

sudo tcpdump -i eth0 -w capture.pcap

tcpdump answers with a line such as listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes and then stays quiet, because the packets go to the file. The snapshot length is the most it keeps of each packet, and on current versions that is the whole packet. Older releases cut packets short by default; on those, add -s 0. Stop with Ctrl+C. tcpdump then flushes its buffer, closes the file and prints three counters: packets captured, packets received by the filter and packets dropped by the kernel. Add -c 50000 to stop by itself after that many packets.

Keep only the traffic you need

sudo tcpdump -i eth0 -w web.pcap 'host 10.0.0.5 and port 443'
sudo tcpdump -i eth0 -w capture.pcap 'not port 22'

The expression at the end is a capture filter in BPF syntax, and anything it rejects is gone for good. The first command keeps one host's HTTPS traffic. The second keeps everything except SSH, which matters when you run tcpdump over an SSH session on the same interface: otherwise the file fills with the packets of your own terminal. When you are not sure what the question needs, capture wider and cut the file later; the guide on how to split a large PCAP shows the commands.

Rotate files under an upload limit

sudo tcpdump -i eth0 -C 20 -W 10 -w ring.pcap
sudo tcpdump -i eth0 -G 600 -w 'cap-%H%M%S.pcap'

-C 20 closes the file once it passes 20 million bytes and opens the next, so every part fits the 25 MB public upload limit. With -W 10 tcpdump keeps ten files named ring.pcap0 to ring.pcap9 and then overwrites the oldest, a ring buffer you can leave running until the fault comes back. Without -W the files are ring.pcap, ring.pcap1, ring.pcap2 and so on, until the disk fills. -G 600 starts a new file every ten minutes; the file name needs a time format, or each new file overwrites the last one.

Errors and what they mean

tcpdump saysWhat happened and the fix
eth0: You don't have permission to perform this capture on that deviceCapturing needs root or the capture capabilities. Run it with sudo.
nosuch0: No such device existsThe interface name is wrong or the interface is down. Check tcpdump -D.
r.pcap: Permission deniedDebian and Ubuntu builds switch to the user tcpdump once the capture starts. With -C every output file, and with -G every file after the first, is opened after that switch. Write into a folder that user can write to, or add -Z root.
N packets dropped by kernel, with N above zerotcpdump could not keep up. Narrow the filter, write to a local disk, or raise the buffer with -B 8192 (KiB).
pcap_loop: truncated dump file; tried to read 29826 captured bytes, only got 26711The file ends in the middle of a packet: tcpdump was killed with kill -9, the disk filled up, or the file was copied while still being written.

The messages above are what tcpdump 4.99.5 printed in our tests on Debian, with the file and interface names of those tests; macOS prints the same text for a wrong interface name. A truncated file is not lost: editcap capture.pcap repaired.pcap warns that the file was cut short and writes every complete packet to the new file, which then reads cleanly and uploads like any other.

tcpdump capture questions

Does tcpdump -w record whole packets?
On current versions, yes: tcpdump 4.99 keeps up to 262,144 bytes of each packet unless -s sets less. Older releases cut packets short by default, so add -s 0 there.
Can A-Packets read a capture taken with -i any?
Yes. tcpdump writes it in the Linux cooked format, which A-Packets reads like Ethernet. The file keeps one link-layer address per packet, the sender's, instead of both Ethernet addresses.
How do I stop tcpdump without damaging the file?
Press Ctrl+C or send it SIGTERM, so it writes what it has buffered and closes the file. kill -9 skips that step and usually leaves the last packet cut in half.