Skip to content

tcpdump and tshark: Packet Capture in CLI

When debugging network issues in Linux infrastructure, ping and curl are not enough. Sometimes you need to see what is actually traveling over the wire. tcpdump is the standard tool for capturing packets from the CLI. tshark is its sibling from the Wireshark suite, convenient for scripting.

Quick Start with tcpdump

Check that packets are reaching the host:

tcpdump -i eth0 host 10.0.0.5

The utility puts the interface into promiscuous mode and prints one line per packet passing through. By default it works with the first interface it finds, but specifying explicitly is better.

For a quick test without DNS resolution (to avoid timeout when there is no network):

tcpdump -i eth0 -nn host 10.0.0.5

-nn prevents resolving both hostnames and ports.

Key Flags

FlagPurpose
-i ifaceInterface
-c NCapture N packets and exit
-nDo not resolve hostnames
-nnDo not resolve hostnames and ports
-v, -vv, -vvvIncrease output verbosity
-w fileWrite raw dump to file (pcap)
-r fileRead dump from file
-XShow hex + ASCII packet body
-s NTruncate each packet to N bytes (0 = full)
-CRotate output file when it reaches N MB

The -v flags are useful for debugging: the first level shows TTL and ID, the second shows flags and window size, the third adds ACK and displays the full IP header.

# Capture 100 packets on port 443, verbosity -vv
tcpdump -i eth0 -nn -c 100 -vv port 443

BPF Filters

tcpdump uses Berkeley Packet Filter. The syntax reads left to right.

# TCP only on port 80 or 443
tcpdump -i eth0 -nn tcp port 80 or port 443

# Host as source OR destination
tcpdump -i eth0 -nn host 192.168.1.10

# Do not show SSH (cut the noise)
tcpdump -i eth0 -nn not port 22

# TCP packets with SYN flag (connection start)
tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-syn'

# Packets larger than 1000 bytes
tcpdump -i eth0 -nn 'ip[2:2] > 1000'

# ICMP ping (type 8 code 0)
tcpdump -i eth0 -nn 'icmp[icmptype] == 8'

Filters combine with and, or, not. Quotes are needed when the expression contains spaces or special characters.

Warning

Do not run tcpdump -i any in production without restricting by host or port. You will get a flood of traffic and waste disk space for no reason.

Writing to File and Reading

Capturing to a file is mandatory practice. A live sniffer dumps data dozens of lines per second; analyzing in the terminal is impossible.

# Write 10,000 packets to a file
tcpdump -i eth0 -nn -w /tmp/capture.pcap -c 10000

# Read from file (interactive)
tcpdump -r /tmp/capture.pcap

# Read with a filter
tcpdump -r /tmp/capture.pcap -nn 'tcp port 443'

The pcap format is binary. The -C option limits file size:

tcpdump -i eth0 -nn -w /tmp/capture -C 10 -W 5

This creates files /tmp/capture-0, /tmp/capture-1 … up to 5 files, each up to 10 MB. -W sets the number of files.

tshark as a tty-free Alternative

tshark is the command-line part of Wireshark. It produces structured output convenient for parsing in scripts:

# Installation
apt install tshark   # Debian/Ubuntu
yum install wireshark-cli   # RHEL/CentOS

# Capture with field output
tshark -i eth0 -f 'host 10.0.0.5' -c 100 -T fields -e ip.src -e ip.dst -e tcp.port

-T fields -e extracts specific fields from each packet:

# HTTP requests: method and host
tshark -i eth0 'tcp port 80' -Y http.request -T fields -e http.host -e http.request.method -e http.request.uri

Reading pcap files with tshark is more convenient than with tcpdump:

# Show protocol hierarchy statistics
tshark -r /tmp/capture.pcap -z io,phs -q

tshark does not support -C rotation like tcpdump, but it handles live filters better (full Wireshark dissector engine).

Reading Dumps in Wireshark

A pcap created by tcpdump opens in Wireshark without conversion:

# Transfer file to local machine
scp user@server:/tmp/capture.pcap /tmp/

# Or start a web server on the remote host
python3 -m http.server 8080 --directory /tmp

In Wireshark Apply as display filter you enter the same BPF syntax: tcp.port == 443 && ip.src == 10.0.0.1.

Tip

If the file is large (>100 MB), do not open it entirely. Use tcpdump -r with a pre-filter to extract the needed slice: tcpdump -r big.pcap -nn 'host 10.0.0.5' -w small.pcap.

Common Mistakes

  • Forgot -c — the process hangs, capturing traffic indefinitely. Add the limit immediately.
  • No permissions — you need root or sudo tcpdump. In modern distributions you can grant capabilities: setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump.
  • -w does not work with -l (line-buffering) simultaneously. If you need progress — write to file and read in parallel via tail -f.
  • File was written but reads empty — possibly there was no traffic matching the filter. Check tcpdump -i eth0 -nn without a filter.