📡 tcpdump Quick Reference

tcpdump cheat sheet / survival guide

Video: tcpdump Cheat Sheet (sysadmin video)
Prefer to watch? This video runs the guide's main commands on a real Ubuntu 24.04 machine, with on-screen captions and no voiceover. Click to play, or watch it on YouTube. It is part of the Networking and Firewalls playlist.
tcpdump [options] [filter expression]
sudo tcpdump -i eth0 port 80

tcpdump captures and prints network packets as they cross an interface. It is the
fastest way to answer "is the traffic actually arriving?" on a server with no GUI.
It needs root (sudo). Only capture traffic on networks you are authorized to monitor.
Captured packets can contain passwords and personal data. Handle files with care.

Choose the interface

sudo tcpdump -D                          # list interfaces
sudo tcpdump -i eth0                     # one interface
sudo tcpdump -i any                      # all interfaces (Linux)
sudo tcpdump -i lo                       # loopback (local traffic)

Common options

-i IFACE    Interface to listen on          -n    Do not resolve hostnames
-nn         Also do not resolve port names  -c N  Stop after N packets
-v / -vv    More detail                     -q    Quieter, shorter lines
-X          Show packet contents in hex and ASCII      -XX   also the link header
-A          Show contents as ASCII (good for HTTP)     -e    Show MAC addresses
-s 0        Capture whole packets (default snaplen varies by version)
-t          No timestamps          -tttt   Human-readable date and time
-l          Line-buffered output (for piping)          -p    Do not use promiscuous mode
-w FILE     Write raw packets to a file                -r FILE   Read a saved file
-C SIZE     Start a new file every SIZE million bytes  -G SECS   Rotate files by time
-W N        Keep only N files (with -C)                -Z USER   Drop privileges after opening
-Q in|out   Only inbound or outbound packets (Linux)   -S    Absolute TCP sequence numbers
Good default while investigating: sudo tcpdump -nn -i eth0

Filter by host, network and port

host 192.168.1.10                        # to or from this host
src host 192.168.1.10                    # from
dst host 192.168.1.10                    # to
net 192.168.1.0/24                       # a network
src net 10.0.0.0/8
port 443                                 # a port (TCP or UDP)
src port 22       dst port 53
portrange 8000-9000
ether host aa:bb:cc:dd:ee:ff             # by MAC address
Examples:
sudo tcpdump -nn -i eth0 host 8.8.8.8
sudo tcpdump -nn -i eth0 net 10.0.0.0/8 and port 22

Filter by protocol

tcp    udp    icmp    icmp6    arp    ip    ip6
sudo tcpdump -nn icmp                    # pings
sudo tcpdump -nn arp                     # who-has / is-at requests
sudo tcpdump -nn udp port 53             # DNS
sudo tcpdump -nn 'tcp port 80 or tcp port 443'
sudo tcpdump -nn vlan                    # VLAN-tagged frames

Combine filters

and  (or &&)     or  (or ||)     not  (or !)     Use parentheses, and quote them
sudo tcpdump -nn 'host 10.0.0.5 and (port 80 or port 443)'
sudo tcpdump -nn 'src 10.0.0.5 and not port 22'
sudo tcpdump -nn 'not arp and not icmp'
sudo tcpdump -nn 'tcp and dst port 3306 and net 10.0.0.0/24'
Always quote filters that contain ( ) ! so the shell leaves them alone.

TCP flags

tcp[tcpflags] & (tcp-syn) != 0           # any SYN
tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn    # SYN only: new connection attempts
tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)   # SYN-ACK
tcp[tcpflags] & (tcp-rst) != 0           # resets: refused or aborted connections
tcp[tcpflags] & (tcp-fin) != 0           # connection closes
sudo tcpdump -nn 'tcp[tcpflags] == tcp-syn'
Flags in the output: [S] SYN  [S.] SYN-ACK  [.] ACK  [P.] push  [F.] FIN  [R] reset

Packet size and content

less 128     greater 1000                # by packet length
sudo tcpdump -nn 'greater 1400'          # large packets (MTU issues)
sudo tcpdump -nn 'ip[8] < 5'             # low TTL
sudo tcpdump -nn -A 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'   # HTTP with data

Save and read captures

sudo tcpdump -nn -i eth0 -w capture.pcap          # save (Ctrl+C to stop)
sudo tcpdump -nn -i eth0 -c 1000 -w cap.pcap      # stop after 1000 packets
sudo tcpdump -nn -i eth0 -w cap-%F-%H%M.pcap -G 3600 -W 24   # hourly files, keep 24
sudo tcpdump -nn -i eth0 -C 100 -W 10 -w ring.pcap           # 100MB ring buffer of 10 files
tcpdump -nn -r capture.pcap                       # read it back
tcpdump -nn -r capture.pcap host 10.0.0.5         # filter while reading
tcpdump -nn -r capture.pcap -A | less
Open the .pcap in Wireshark for a deep look (wireshark capture.pcap or tshark -r capture.pcap).
Writing to a file is far faster than printing to the screen. Use -w on busy links.

Reading the output

14:03:22.481 IP 10.0.0.5.51422 > 93.184.216.34.443: Flags [S], seq 3841, win 64240, length 0
time        proto source.port   > destination.port: flags, sequence, window, payload length
Source and destination are host.port. Flags [S] means the client is starting a connection.
A healthy connection: [S] then [S.] then [.]. Many [S] with no [S.] means the server is not answering.

Practical one-liners

# Is any traffic reaching this port at all?
sudo tcpdump -nn -i any port 8080 -c 10

# Watch DNS queries
sudo tcpdump -nn -i any udp port 53

# See HTTP requests in plain text (unencrypted HTTP only)
sudo tcpdump -nn -A -s 0 'tcp port 80'

# Are pings arriving? (troubleshoot firewalls)
sudo tcpdump -nn -i eth0 icmp

# See who is connecting to SSH
sudo tcpdump -nn -i eth0 'tcp dst port 22 and tcp[tcpflags] & tcp-syn != 0'

# Show DHCP exchanges
sudo tcpdump -nn -i eth0 -vv 'port 67 or port 68'

# Watch ARP on the LAN
sudo tcpdump -nn -i eth0 arp

# Top talkers (source IPs) from a live sample
sudo tcpdump -nn -i eth0 -c 1000 | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head

# Capture everything except your own SSH session
sudo tcpdump -nn -i eth0 'not port 22'

# Capture from a remote machine and view it locally in Wireshark
ssh user@server 'sudo tcpdump -nn -U -s 0 -i eth0 -w - not port 22' | wireshark -k -i -

# Look for connection resets
sudo tcpdump -nn -i eth0 'tcp[tcpflags] & tcp-rst != 0'

# Count packets per second
sudo tcpdump -nn -i eth0 -tt | awk '{print int($1)}' | uniq -c

Permissions and safety

sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/tcpdump    # allow non-root capture (use carefully)
Capture files can hold credentials and private data. Store them securely and delete them
when finished. Avoid capturing on shared or production networks without permission.

Common problems

"You don't have permission to capture"   Use sudo, or grant capabilities
"No such device exists"                  Wrong interface name: sudo tcpdump -D or ip -br link
Nothing shows up                         Wrong interface, wrong filter, or the traffic never arrives
Output is a wall of text                 Add -nn, a filter, and -c to limit it
"packets dropped by kernel"              Too much traffic: write with -w, use a tighter filter, raise -B
Cannot read HTTPS payload                It is encrypted. tcpdump shows the packets, not the content
Only see your own SSH traffic            Add "not port 22" to hide it
Hostnames slow it down                   Use -n or -nn so it does not do DNS lookups

Tips

    Always use -nn while troubleshooting. DNS lookups slow the output and can create their own traffic.

    Filter as tightly as you can. Capturing everything on a busy link loses packets.

    Use -w to save a capture and analyze it later in Wireshark. Do not squint at a scrolling terminal.

    Watching the TCP handshake ([S], [S.], [.]) tells you quickly whether a service is reachable, blocked, or silent.

    Use -i any to find which interface traffic uses, then switch to the specific one.

    Exclude your own SSH session (not port 22) so your capture does not record itself.

    Encrypted traffic (HTTPS, SSH) shows only headers and sizes. That is still enough to prove a connection exists.

    Only capture traffic you are authorized to monitor, and protect the files you create.