tcpdump — quick reference
Most captures need sudo or root. Replace lo with your interface (tcpdump -D lists names).
Capture control
| When to use | Command |
|---|---|
| Stop after N packets | sudo tcpdump -c 5 -i lo |
| Print only packet count when reading a pcap | sudo tcpdump --count -r file.pcap |
| Set OS capture buffer size (KiB) | sudo tcpdump -B 4096 -i lo |
| Line-buffered stdout (see lines as they arrive) | sudo tcpdump -l -i lo |
| Packet-buffered stdout (flush after each packet) | sudo tcpdump -U -i lo |
| Capture in immediate mode | sudo tcpdump --immediate-mode -i lo |
| Do not put interface in promiscuous mode | sudo tcpdump -p -i lo |
| Do not verify IP/TCP/UDP checksums | sudo tcpdump -K -i lo |
| Drop privileges to an unprivileged user after opening capture | sudo tcpdump -Z user -i lo |
Run a command after a rotated savefile (with -G/-w) |
sudo tcpdump -z gzip -w out.pcap -G 60 -i lo |
| Skip BPF filter optimizer (debug odd filters) | sudo tcpdump -O -n -i lo |
| Validate TCP-MD5 digests with a shared secret | sudo tcpdump -M secret -n -i lo tcp |
Interface selection
| When to use | Command |
|---|---|
| List interfaces tcpdump can use | sudo tcpdump -D |
| Capture on one interface | sudo tcpdump -i lo |
| Capture on all interfaces (Linux) | sudo tcpdump -i any |
Capture by interface number from -D |
sudo tcpdump -i 4 |
| Wi-Fi monitor mode (where supported) | sudo tcpdump -I -i wlan0 |
| List link-layer types for an interface | sudo tcpdump -L -i lo |
| Force link-layer type | sudo tcpdump -y EN10MB -i lo |
| List supported timestamp types | sudo tcpdump -J -i lo |
| Set timestamp type | sudo tcpdump -j host -i lo |
| Microsecond timestamp precision | sudo tcpdump --micro -i lo |
| Nanosecond timestamp precision | sudo tcpdump --nano -i lo |
| Set timestamp precision explicitly | sudo tcpdump --time-stamp-precision=nano -i lo |
Match traffic direction (Linux any pseudo-interface) |
sudo tcpdump -Q in -i any |
Output format
| When to use | Command |
|---|---|
| Skip DNS/port name lookup (faster, clearer IPs) | sudo tcpdump -n -i lo |
| Skip DNS and port names | sudo tcpdump -nn -i lo |
| Print host names without domain suffix | sudo tcpdump -N -i lo |
| Less verbose one-line summary | sudo tcpdump -q -i lo |
| More decode detail | sudo tcpdump -v -i lo |
| Even more protocol detail | sudo tcpdump -vv -i lo |
| Maximum decode detail | sudo tcpdump -vvv -i lo |
| Print link-layer (MAC) headers | sudo tcpdump -e -i lo |
| Omit timestamp from lines | sudo tcpdump -t -i lo |
| Seconds since epoch timestamp | sudo tcpdump -tt -i lo |
| Delta seconds between packets | sudo tcpdump -ttt -i lo |
| Date + time on each line | sudo tcpdump -tttt -i lo |
| Print packet in hex | sudo tcpdump -x -i lo |
| Print hex including link header | sudo tcpdump -xx -i lo |
| Print hex and ASCII | sudo tcpdump -X -i lo |
| Print hex + ASCII including link header | sudo tcpdump -XX -i lo |
| Print packet in ASCII | sudo tcpdump -A -i lo |
| Unaligned packet output (legacy) | sudo tcpdump -u -i lo |
| Print absolute TCP sequence numbers | sudo tcpdump -S -i lo |
| Print BGP AS numbers in ASDOT notation | sudo tcpdump -b -i lo |
| Print foreign IPv4 addresses numerically | sudo tcpdump -f -i lo |
| Attempt 802.11s mesh header decode | sudo tcpdump -H -i lo |
| Print frame number while reading a file | sudo tcpdump --number -r file.pcap |
| Prefix each live line with a packet number | sudo tcpdump -# -n -i lo |
| Print generated filter code and exit | sudo tcpdump -d tcp |
| Compile filter without optimizer (debugging) | sudo tcpdump -O -d tcp |
| Print filter code as C fragment | sudo tcpdump -dd tcp |
| Print filter code as decimal opcodes | sudo tcpdump -ddd tcp |
Snap length and save files
| When to use | Command |
|---|---|
| Limit bytes captured per packet | sudo tcpdump -s 64 -i lo |
| Full snap length (default on recent tcpdump) | sudo tcpdump -s 0 -i lo |
| Write packets to a pcap file | sudo tcpdump -w /tmp/cap.pcap -i lo |
| Read packets from a pcap file | sudo tcpdump -r /tmp/cap.pcap |
| Read every pcap path listed in a file | sudo tcpdump -V /path/pcap-list.txt |
| Force packet type when reading a savefile | sudo tcpdump -T domain -r file.pcap |
| Rotate savefile when size exceeds N MB | sudo tcpdump -C 10 -w out.pcap -i lo |
| Rotate savefile every N seconds | sudo tcpdump -G 60 -w '%Y%m%d-%H%M%S.pcap' -i lo |
Stop after N savefiles with -C/-G |
sudo tcpdump -W 5 -C 10 -w out.pcap -i lo |
| Decrypt IPsec ESP (needs crypto build + secrets) | sudo tcpdump -E '[email protected] des-cbc:secret' -i eth0 |
| Read filter from a file | sudo tcpdump -F /path/filter.txt -i lo |
Print decoded lines while also writing with -w |
sudo tcpdump --print -w /tmp/cap.pcap -i lo |
| Print frame number on live capture | sudo tcpdump -# -n -i lo |
BPF filter expressions
Append expressions after options. Combine with and, or, not.
| When to use | Command |
|---|---|
| Only TCP traffic | sudo tcpdump -n -i lo tcp |
| Only UDP traffic | sudo tcpdump -n -i lo udp |
| ICMP (ping) traffic | sudo tcpdump -n -i lo icmp |
| Traffic involving one host | sudo tcpdump -n -i lo host 127.0.0.1 |
| Source or destination host | sudo tcpdump -n -i lo src 10.0.0.1sudo tcpdump -n -i lo dst 10.0.0.1 |
| Traffic on a port | sudo tcpdump -n -i lo port 443 |
| Source or destination port | sudo tcpdump -n -i lo src port 53sudo tcpdump -n -i lo dst port 53 |
| Network prefix | sudo tcpdump -n -i lo net 192.168.1.0/24 |
| VLAN traffic | sudo tcpdump -n -i eth0 vlan |
| ARP packets | sudo tcpdump -n -i lo arp |
Help and version
| When to use | Command |
|---|---|
| Show usage and version strings | tcpdump -h |
| Print version only | tcpdump --version |
tcpdump — command syntax
Synopsis from tcpdump --help on Ubuntu 25.04 (tcpdump 4.99.4):
tcpdump [-AbdDefhHIJKlLnNOpqStuUvxX#] [ -B size ] [ -c count ] [--count]
[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]
[ -i interface ] [ --immediate-mode ] [ -j tstamptype ]
[ -M secret ] [ --number ] [ --print ] [ -Q in|out|inout ]
[ -r file ] [ -s snaplen ] [ -T type ] [ --version ]
[ -V file ] [ -w file ] [ -W filecount ] [ -y datalinktype ]
[ --time-stamp-precision precision ] [ --micro ] [ --nano ]
[ -z postrotate-command ] [ -Z user ] [ expression ]Without -i, tcpdump picks the lowest-numbered non-loopback interface that is up. Capture files use pcap format; Wireshark and tcpdump -r read them.
tcpdump — command examples
Essential Capture five packets on loopback without DNS lookups
A safe first lab uses the lo interface — traffic stays on the host and you can limit packet count so the command exits on its own.
Run the command:
sudo tcpdump -c 5 -n -i loSample output:
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:16:08.206351 IP 127.0.0.1.33035 > 127.0.0.1.49520: Flags [P.], seq 1082399863:1082400244, ack 2802465881, win 124, options [nop,nop,TS val 2583620288 ecr 2805920306], length 381
14:16:08.206368 IP 127.0.0.1.49520 > 127.0.0.1.33035: Flags [.], ack 381, win 130, options [nop,nop,TS val 2805920518 ecr 2583620288], length 0
14:16:08.207956 IP 127.0.0.1.33035 > 127.0.0.1.49520: Flags [P.], seq 381:458, ack 1, win 124, options [nop,nop,TS val 2583620289 ecr 2805920518], length 77
14:16:08.208034 IP 127.0.0.1.49520 > 127.0.0.1.33035: Flags [.], ack 458, win 130, options [nop,nop,TS val 2805920519 ecr 2583620289], length 0
14:16:08.210642 IP 127.0.0.1.49520 > 127.0.0.1.33035: Flags [P.], seq 1:28, ack 458, win 130, options [nop,nop,TS val 2805920522 ecr 2583620289], length 27
5 packets captured
160 packets received by filter
0 packets dropped by kernelThe -n flag skips reverse DNS so you see 127.0.0.1 instead of localhost. The summary lines at the end (packets captured, dropped by kernel) tell you whether the filter or buffer lost traffic.
Essential Minimal loopback capture — three packets, no DNS
This is the smallest useful lab on Ubuntu: loopback only, fixed count, numeric addresses.
Run the command:
sudo tcpdump -i lo -c 3 -nSample output:
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:23:23.644394 IP 127.0.0.1.33035 > 127.0.0.1.49520: Flags [P.], seq 1082778692:1082778842, ack 2804314358, win 124, options [nop,nop,TS val 2584055726 ecr 2806355843], length 150
14:23:23.644478 IP 127.0.0.1.49520 > 127.0.0.1.33035: Flags [.], ack 150, win 130, options [nop,nop,TS val 2806355956 ecr 2584055726], length 0
14:23:23.648142 IP 127.0.0.1.49520 > 127.0.0.1.33035: Flags [P.], seq 1:28, ack 150, win 130, options [nop,nop,TS val 2806355959 ecr 2584055726], length 27
3 packets captured
20 packets received by filter
0 packets dropped by kernelTraffic on lo is always local — safe for practice. On a real NIC, -c keeps the capture from running forever.
Essential List capture interfaces with -D
Before capturing on a server, confirm interface names — they differ from ip link labels on some hosts.
Run the command:
sudo tcpdump -DSample output:
1.enp0s3 [Up, Running, Connected]
2.enp0s8 [Up, Running, Connected]
3.any (Pseudo-device that captures on all interfaces) [Up, Running]
4.lo [Up, Running, Loopback]
5.bluetooth-monitor (Bluetooth Linux Monitor) [Wireless]Use the name after the number (enp0s3, lo, any) with -i. On Linux, any captures on all interfaces at once.
Essential Filter ICMP echo (ping) on loopback
BPF filters go at the end of the command. Start tcpdump in one terminal, then generate traffic in another.
Run the capture:
sudo tcpdump -c 3 -n -i lo icmpIn another shell, generate ping traffic:
ping -c 2 127.0.0.1Sample output from the capture:
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:24:56.059515 IP 127.0.0.1 > 127.0.0.1: ICMP echo request, id 46919, seq 1, length 64
14:24:56.059528 IP 127.0.0.1 > 127.0.0.1: ICMP echo reply, id 46919, seq 1, length 64
14:24:57.114305 IP 127.0.0.1 > 127.0.0.1: ICMP echo request, id 46919, seq 2, length 64
3 packets capturedCombine host and protocol: host 10.0.0.5 and icmp. Use or and not for broader or inverted filters.
Common Write a pcap file and read it back
Save packets for later analysis in Wireshark or offline review with tcpdump -r.
Run the commands:
sudo tcpdump -c 5 -n -i lo -w /tmp/cap-test.pcap
sudo tcpdump -r /tmp/cap-test.pcap -n
sudo rm -f /tmp/cap-test.pcapSample output from the read step:
reading from file /tmp/cap-test.pcap, link-type EN10MB (Ethernet), snapshot length 262144
14:24:56.946326 IP 127.0.0.1.33035 > 127.0.0.1.49520: Flags [P.], seq 1082851512:1082851546, ack 2804784493, win 124, options [nop,nop,TS val 2584149027 ecr 2806449136], length 34
14:24:56.946388 IP 127.0.0.1.49520 > 127.0.0.1.33035: Flags [.], ack 34, win 130, options [nop,nop,TS val 2806449258 ecr 2584149027], length 0
...
5 packets capturedThe write step prints only counters unless you add --print. Remove test pcaps when finished.
Common Filter by host and TCP port
Narrow captures to one conversation — typical when debugging a web or database service.
Run the command (replace the IP and port with your target):
sudo tcpdump -n -i lo -c 3 'host 127.0.0.1 and tcp'Sample output:
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:16:09.360922 IP 127.0.0.1.49520 > 127.0.0.1.33035: Flags [P.], seq 2802467601:2802467930, ack 1082401919, win 130, options [nop,nop,TS val 2805921672 ecr 2583621407], length 329
14:16:09.375344 IP 127.0.0.1.33035 > 127.0.0.1.49520: Flags [P.], seq 1:23, ack 329, win 124, options [nop,nop,TS val 2583621457 ecr 2805921672], length 22
14:16:09.403876 IP 127.0.0.1.33035 > 127.0.0.1.49520: Flags [P.], seq 23:12142, ack 329, win 124, options [nop,nop,TS val 2583621485 ecr 2805921672], length 12119
3 packets capturedAdd port 443 or port 22 when you know the service port. Quote complex filters so the shell does not split on spaces.
Common Verbose protocol decode with -v
One-line mode hides IP header fields. Add -v (or -vv, -vvv) when you need checksums, TTL, and option details.
Run the command:
sudo tcpdump -c 1 -n -v -i loSample output:
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:25:47.129738 IP (tos 0x0, ttl 64, id 2057, offset 0, flags [DF], proto TCP (6), length 113)
127.0.0.1.33035 > 127.0.0.1.41690: Flags [P.], cksum 0xfe65 (incorrect -> 0x000e), seq 2443207211:2443207272, ack 4225976044, win 377, options [nop,nop,TS val 2118267756 ecr 2387211119], length 61
1 packet capturedcksum ... (incorrect -> ...) on loopback is normal — the stack may not compute NIC checksums for lo.
Common Capture fails without root or capabilities
Raw capture needs elevated privileges on Linux. Running as a normal user usually fails immediately.
Run the command as an unprivileged user:
su -s /bin/bash nobody -c 'tcpdump -c 1 -i lo 2>&1'Sample output:
tcpdump: lo: You don't have permission to perform this capture on that device
(socket: Operation not permitted)Use sudo tcpdump ... or grant cap_net_raw to the binary. For production, prefer -Z user to drop privileges after the socket opens.
Common Invalid BPF filter syntax
Typos in the filter expression make tcpdump exit before listening.
Run the command:
sudo tcpdump -n -i lo 'hostt 127.0.0.1'Sample output:
tcpdump: can't parse filter expression: syntax errorFix the keyword (host), check parentheses, and test with -d 'expression' first.
Advanced Inspect compiled BPF filter with -d
When a filter behaves unexpectedly, -d prints the bytecode tcpdump would use — without capturing packets.
Run the command:
sudo tcpdump -d 'tcp port 80'Sample output:
Warning: assuming Ethernet
(000) ldh [12]
(001) jeq #0x86dd jt 2 jf 8
(002) ldb [20]
(003) jeq #0x6 jt 4 jf 19Use -dd or -ddd for C or decimal opcode listings. Pair with -O if you suspect the optimizer changed semantics.
tcpdump — when to use / when not
| Use tcpdump when | Use something else when |
|---|---|
|
|
tcpdump vs Wireshark
Both use libpcap. tcpdump is a CLI capture and print tool — ideal on headless servers. Wireshark (and tshark) add deep dissectors, stream reassembly, and a GUI.
| tcpdump | Wireshark | |
|---|---|---|
| Interface | Terminal only | GUI or tshark CLI |
| Typical use | Live capture, quick filters, save pcap | Analysis, filters, exports, TLS decode with keys |
| On production servers | Common — small footprint | Often installed on admin workstations only |
| Output | Text lines or pcap via -w |
Opens pcaps; can capture live |
Workflow many admins use: tcpdump -w trace.pcap on the server, copy the file, open it in Wireshark on a laptop.
Related commands
Tools often used in the same network troubleshooting workflow.
| Command | One line |
|---|---|
| tcpdump | Packet capture and BPF filters (this page) |
| ss | Socket statistics without capturing payloads |
| traceroute | Path and hop latency to a remote host |
| ping | Generate ICMP traffic to test filters |
Browse the full index in our Linux commands reference.
tcpdump — interview corner
What is tcpdump used for?
tcpdump reads packets from a network interface (or from a saved pcap file) and prints a one-line summary per packet. It uses BPF (Berkeley Packet Filter) expressions — like host 10.0.0.1 and port 443 — so the kernel drops uninteresting traffic before userspace sees it.
Typical admin uses:
- Confirm a service is receiving connections on the expected port
- Spot retransmits or RSTs during an outage
- Save evidence to a pcap for Wireshark
Most Linux captures need root or sudo because opening a raw socket is privileged.
A strong answer is:
"tcpdump captures and prints live packets or reads pcaps, with BPF filters for host, port, and protocol. I use it on servers for quick traces and -w files for deeper Wireshark analysis."
Where do you put the filter in a tcpdump command?
Options (-i, -n, -c, -w, …) come first. The filter expression is usually last and unquoted or single-quoted:
sudo tcpdump -n -i eth0 -c 10 'tcp port 443 and host 203.0.113.5'Keywords include host, src, dst, port, net, tcp, udp, icmp, combined with and, or, not. Without a filter, tcpdump prints all traffic the interface delivers — often too noisy on busy links.
Test bytecode without capturing:
sudo tcpdump -d 'tcp port 80'A strong answer is:
"BPF filters go at the end after options. I quote complex expressions and use host, port, and protocol keywords with and/or/not. For debugging I disassemble with tcpdump -d."
Why does tcpdump usually require sudo?
Capturing from a live interface needs a raw packet socket. On Linux that is restricted to root or processes with CAP_NET_RAW / CAP_NET_ADMIN. Without it you see:
tcpdump: eth0: You don't have permission to perform this capture on that device-Z user drops to an unprivileged user after opening the capture — good for long-running captures. Reading an existing file with -r does not need special privileges if the file is readable.
A strong answer is:
"Live capture needs raw socket access, so root or sudo. I use sudo for ad-hoc work and -Z to drop privileges after start when a capture runs for a long time."
What does tcpdump -n do?
-n disables reverse DNS lookup on addresses. -nn also skips service name lookup for ports (so you see 443 instead of https).
Compare:
| Flag | Addresses | Ports |
|---|---|---|
| (none) | may resolve to hostnames | may show service names |
-n |
numeric IPs | may show service names |
-nn |
numeric IPs | numeric ports |
On busy captures, DNS lookups slow output and can mislead when PTR records are wrong. -N is different: it prints short hostnames without domain suffix when DNS is used.
A strong answer is:
"-n skips reverse DNS so output stays fast and shows IPs. -nn also numericizes ports. I almost always use -n or -nn on servers."
How do you save and read captures with tcpdump?
Write live traffic to pcap:
sudo tcpdump -w /var/tmp/trace.pcap -i eth0 -c 1000Read back without capturing:
tcpdump -r /var/tmp/trace.pcap -nAdd --print if you want lines on stdout while also writing -w. Rotate large captures with -C (size MB) or -G (seconds) and limit file count with -W.
A strong answer is:
"I capture with -w to a pcap, copy it off the host, and analyze with tcpdump -r or Wireshark. For long captures I use -C or -G rotation with -W."
When would you capture on lo instead of eth0?
lo is the loopback interface — traffic between local processes on the same host (for example 127.0.0.1:8080 to 127.0.0.1:5432). It is safe for learning and reproducing filters without exposing credentials on the wire.
eth0 (or enp0s3, any, etc.) carries traffic that leaves or enters the host — what you need for real client/server debugging.
Lab pattern:
sudo tcpdump -i lo -c 3 -nUse -D to list names on the machine before choosing -i.
A strong answer is:
"lo for local-only traffic and safe practice; real NIC or any for production debugging. I always tcpdump -D first because interface names vary by distro and cloud image."
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
You don't have permission to perform this capture |
Not root and no CAP_NET_RAW |
sudo tcpdump ... or grant capability to the binary |
can't parse filter expression |
Typo or unsupported BPF keyword | Fix syntax; test with tcpdump -d 'expression' |
| No packets printed | Filter too narrow or idle interface | Remove filter; generate traffic (ping, curl); confirm -i with tcpdump -D |
0 packets dropped by kernel but count is low |
-c limit reached quickly |
Raise -c or remove it for sustained capture |
Huge incomplete lines on -w only |
Normal — -w is binary pcap |
Read with tcpdump -r or Wireshark; add --print for live text |
tcpdump: eth0: No such device |
Wrong interface name | tcpdump -D or ip link |
| Reverse DNS pauses | Missing -n |
Add -n or -nn |
