tcpdump Cheatsheet
Capture Files
Use this tcpdump reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Writing and reading
Capture to a file, analyze later. This is the normal workflow, because you cannot re-run a network event.
# Write raw packets, print nothing sudo tcpdump -i eth0 -nn -w capture.pcap 'tcp port 443' # Write and watch at the same time sudo tcpdump -i eth0 -nn -w capture.pcap -U -Q inout | \ tcpdump -nn -r - -c 20 # Read it back with a tighter filter tcpdump -nn -r capture.pcap 'host 10.0.0.5 and tcp[tcpflags] & tcp-rst != 0'
| Flag | Effect |
|---|---|
-w file | Write raw packets, - means stdout |
-r file | Read from a pcap, - means stdin, needs no root |
-V filelist | Read a file containing a list of pcap filenames |
-U | Flush after each packet, so a tail or pipe sees data live |
-Z user | Drop privileges before writing, so the file is not root-owned |
-F file | Read the filter expression from a file |
Two filters, two stages. -w applies the capture filter, and reading
with -r applies a fresh filter to what was already recorded. So capture
broadly and narrow on read, because you cannot recover what the capture
filter threw away.
Reading a pcap needs no privileges. Only capturing does. So hand developers the file rather than root on the box.
Ring buffers for long captures
The problem: an intermittent fault appears once a day and you cannot leave an unbounded capture running. Rotate.
| Flag | Meaning |
|---|---|
-C n | Start a new file once the current one exceeds n million bytes (10⁶, not MiB) |
-G n | Start a new file every n seconds |
-W n | With -C, cap the file count and overwrite oldest. With -G, stop after n files |
# Bounded disk: 20 files of 100 MB each, oldest overwritten, 2 GB ceiling sudo tcpdump -i eth0 -nn -s 96 -C 100 -W 20 -w /var/tmp/ring.pcap \ -Z tcpdump 'not (host 203.0.113.9 and port 22)' # One file per hour, named by time, keep 24 then exit sudo tcpdump -i eth0 -nn -G 3600 -W 24 \ -w '/var/tmp/cap-%Y%m%d-%H%M%S.pcap' -Z tcpdump # One file per hour, unbounded, rely on the timestamp for uniqueness sudo tcpdump -i eth0 -nn -G 3600 -w '/var/tmp/cap-%Y%m%d-%H.pcap'
Gotchas that bite in production:
- -C counts in 1,000,000 bytes, not 1,048,576. A -C 100 file is
100 MB, not 100 MiB.
- -G without a strftime pattern in -w overwrites the same file on
every rotation. Always include %Y%m%d-%H%M%S or similar when using -G.
- -W means two different things. With -C it is a true ring, oldest
overwritten forever. With -G it is a stop condition, tcpdump exits 0 at
the limit.
- -C and -G together make -W affect only the filename, per the man
page, so you do not get a bounded count that way.
- -C names the first file exactly as given, then appends 1, 2, 3. With
-W the numbers are zero-padded so they sort correctly.
- Cut -s when running long. -s 96 keeps headers and drops payload, which
is usually all you need for a connectivity fault and shrinks the ring by
an order of magnitude.
Splitting, merging, filtering files
These are Wireshark's command-line tools, installed alongside tshark.
| Command | Does |
|---|---|
capinfos f.pcap | Summary: packet count, duration, byte rate, file type |
editcap -c 10000 in.pcap out.pcap | Split into 10,000-packet chunks |
editcap -i 60 in.pcap out.pcap | Split into 60-second chunks |
editcap -A "<t>" -B "<t>" in out | Keep only a time window |
editcap -s 96 in.pcap out.pcap | Re-snaplen, strip payload |
editcap -d in.pcap out.pcap | Drop duplicate packets |
editcap -F pcap in.pcapng out.pcap | Convert pcapng to legacy pcap |
mergecap -w all.pcap a.pcap b.pcap | Merge, sorted by timestamp |
tcpslice | Extract a time range from pcap files |
# How big is this and what is in it capinfos -a -e -c -d capture.pcap # Chop a 4 GB capture into 100k-packet pieces Wireshark can open editcap -c 100000 huge.pcap piece.pcap # Keep one minute around the incident editcap -A "2026-09-15 14:20:00" -B "2026-09-15 14:21:00" \ huge.pcap window.pcap # Pull just one conversation out, using tcpdump as the filter tcpdump -r huge.pcap -w pair.pcap 'host 10.0.0.5 and host 10.0.0.9'
Opening a multi-gigabyte pcap in the Wireshark GUI will swap your machine
to death. Narrow it with tcpdump -r ... -w ... or editcap first, always.
pcap versus pcapng
| pcap | pcapng | |
|---|---|---|
| Interfaces per file | One | Many |
| Nanosecond timestamps | Only in a variant | Yes |
| Comments and metadata | No | Yes |
| Name resolution block | No | Yes |
| tcpdump default | Yes | No, except macOS pktap |
| Wireshark default | No | Yes |
tcpdump writes legacy pcap by default, tshark -w writes pcapng. Some
older tools reject pcapng, so convert with
editcap -F pcap in.pcapng out.pcap. On macOS a pktap pseudo-interface
forces pcapng, because it carries per-packet metadata that pcap has no room
for.
Timestamp precision
# Nanosecond timestamps, if the capture source supports them sudo tcpdump -i eth0 -nn --time-stamp-precision=nano -w ns.pcap # What precision does an existing file use capinfos capture.pcap | grep -i precision
Microseconds are the default and are enough for almost everything. Nanoseconds matter for latency work inside a data center, where a whole round trip can be under 50 µs and microsecond rounding hides the signal.