tcpdump Cheatsheet

Port and Protocol Filters

Use this tcpdump reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Ports

sudo tcpdump -i eth0 -nn port 443
sudo tcpdump -i eth0 -nn tcp port 443
sudo tcpdump -i eth0 -nn 'tcp dst port 443'
sudo tcpdump -i eth0 -nn 'tcp portrange 8000-8100'
sudo tcpdump -i eth0 -nn 'port 80 or port 443'
FilterMatches
port 53TCP and UDP and SCTP, source or destination
tcp port 53TCP only, either direction
src port 53Source port only
dst port 53Destination port only
portrange 8000-8100Any port in the inclusive range
tcp portrange 1-1024TCP well-known ports
port not 22Everything except port 22
port domainService name from /etc/services, resolves to 53

Bare port N is wider than people expect. It expands to a check on TCP, UDP and SCTP, across IPv4 and IPv6, plus a fragment test. Prefix the transport (tcp port, udp port) both for correctness and for speed.

Service names work but hurt readability, and /etc/services differs across distributions. Use numbers.

Transport protocols

sudo tcpdump -i eth0 -nn tcp
sudo tcpdump -i eth0 -nn udp
sudo tcpdump -i eth0 -nn icmp
sudo tcpdump -i eth0 -nn icmp6
sudo tcpdump -i eth0 -nn 'tcp or udp'
sudo tcpdump -i eth0 -nn 'not (tcp or udp or icmp)'
KeywordProtocol
tcpShorthand for ip proto \tcp or ip6 proto \tcp
udpUDP, both address families
icmpICMPv4 only
icmp6ICMPv6, including neighbor discovery
sctpSCTP
arp / rarpAddress resolution, layer 2
esp / ahIPsec
ip proto 47GRE by number
ip proto \greGRE by name, backslash required

\ before a protocol name is not optional. tcp, udp and icmp are reserved words in the filter grammar, so ip proto tcp is a syntax error while ip proto \tcp compiles. In a single-quoted shell string one backslash is enough.

Application protocols by port

pcap has no application-layer awareness, so "capture HTTP" means "capture the ports HTTP usually runs on".

ProtocolFilter
DNS'udp port 53 or tcp port 53'
DNS over TLStcp port 853
DHCPv4'udp port 67 or udp port 68'
HTTP'tcp port 80 or tcp port 8080'
HTTPS / TLStcp port 443
QUIC / HTTP-3udp port 443
SSHtcp port 22
SMTP'tcp port 25 or tcp port 587 or tcp port 465'
NTPudp port 123
SNMP'udp port 161 or udp port 162'
Syslogudp port 514
LDAP'tcp port 389 or tcp port 636'
Postgrestcp port 5432
MySQLtcp port 3306
Redistcp port 6379
MongoDBtcp port 27017
Kafkatcp port 9092
mDNSudp port 5353
SIP'port 5060 or port 5061'
RDPtcp port 3389
VXLANudp port 4789
WireGuardudp port 51820

A service on a non-standard port is invisible to a port filter. When you do not know the port, filter by host and read what comes back.

ICMP types by name

pcap defines symbolic names for ICMP types, which beats memorizing numbers.

# Pings out and replies back
sudo tcpdump -i eth0 -nn 'icmp[icmptype] == icmp-echo or
  icmp[icmptype] == icmp-echoreply'

# Only the errors, which is what you want for MTU and routing bugs
sudo tcpdump -i eth0 -nn -v 'icmp[icmptype] != icmp-echo and
  icmp[icmptype] != icmp-echoreply'
NameTypeMeaning
icmp-echo8Ping request
icmp-echoreply0Ping reply
icmp-unreach3Destination unreachable
icmp-sourcequench4Source quench, obsolete
icmp-redirect5Redirect
icmp-timxceed11TTL exceeded, what traceroute reads
icmp-paramprob12Parameter problem
icmp-tstamp13Timestamp request
icmp-tstampreply14Timestamp reply

Path-MTU black holes are ICMP type 3 code 4:

sudo tcpdump -i eth0 -nn -v 'icmp[icmptype] == icmp-unreach and
  icmp[icmpcode] == 4'

If that filter is silent while large transfers hang, something upstream is dropping the "fragmentation needed" message, which is the classic PMTUD failure.

Fragments break port filters

A port lives in the transport header, which only exists in the first fragment. Later fragments carry no ports, so tcp port 80 silently drops them.

# Only non-first fragments
sudo tcpdump -i eth0 -nn 'ip[6:2] & 0x1fff != 0'

# First fragments and unfragmented packets only
sudo tcpdump -i eth0 -nn 'ip[6:2] & 0x1fff = 0'

# Anything fragmented at all: MF bit set or a nonzero offset
sudo tcpdump -i eth0 -nn 'ip[6] & 0x20 != 0 or ip[6:2] & 0x1fff != 0'

ip[6:2] is the 16-bit flags-plus-fragment-offset field. 0x1fff masks off the three flag bits and leaves the 13-bit offset. ip[6] & 0x20 tests the More Fragments bit on its own.

Size filters

sudo tcpdump -i eth0 -nn greater 1400
sudo tcpdump -i eth0 -nn less 100
sudo tcpdump -i eth0 -nn 'len > 1400 and len < 1500'

greater, less and len all compare the whole frame length as it was on the wire, not the payload. To find TCP segments carrying data, tcp[13] & 8 != 0 (PSH set) is a rough proxy, and the exact test is the payload-length expression in the byte-offsets topic.