tcpdump Cheatsheet

Host and Network Filters

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

Single hosts

host is the default type qualifier, so host is often omitted, but write it anyway for readability.

# Either direction
sudo tcpdump -i eth0 -nn host 10.0.0.5

# One direction only
sudo tcpdump -i eth0 -nn src host 10.0.0.5
sudo tcpdump -i eth0 -nn dst host 10.0.0.5

# Force one address family
sudo tcpdump -i eth0 -nn ip host 10.0.0.5
sudo tcpdump -i eth0 -nn ip6 host 2001:db8::1
FilterMatches
host 10.0.0.5IPv4, IPv6, and ARP/RARP traffic for that address
ip host 10.0.0.5IPv4 only, no ARP
src host 10.0.0.5Only where it is the source
dst host 10.0.0.5Only where it is the destination
host example.comResolved once at compile time, may expand to several

A hostname in a filter is looked up when the filter compiles, not per packet, so it costs nothing at capture time. But if the name has four A records, the filter silently becomes a four-way or.

One host pair, both ways

The single most useful filter in practice. Two forms, and they mean different things.

# Any traffic touching both, in either direction
sudo tcpdump -i eth0 -nn 'host 10.0.0.5 and host 10.0.0.9'

# Strictly one direction of that pair
sudo tcpdump -i eth0 -nn 'src host 10.0.0.5 and dst host 10.0.0.9'

host A and host B reads as "A is one endpoint and B is the other", which is exactly the conversation view you want. Adding src/dst narrows it to half the conversation, which halves what you can diagnose.

Networks and subnets

sudo tcpdump -i eth0 -nn net 10.0.0.0/8
sudo tcpdump -i eth0 -nn 'src net 172.16.0.0 mask 255.240.0.0'
sudo tcpdump -i eth0 -nn dst net 192.168.1.0/24
sudo tcpdump -i eth0 -nn ip6 net 2001:db8::/32
FormMeaning
net 10.0.0.0/8CIDR, the form to use
net 10.0.0.0 mask 255.0.0.0Explicit netmask, equivalent
net 10.0.0Classful shorthand, expands to 10.0.0.0/24
net 10Classful shorthand, expands to 10.0.0.0/8

Avoid the classful shorthand. net 128.3 becoming a /16 while net 192.168.1 becomes a /24 is a real source of wrong captures. Write CIDR.

Excluding your own SSH session

The classic mistake. You SSH in, run tcpdump, and every packet tcpdump prints generates more SSH traffic, which tcpdump prints, forever.

# Blunt but usually fine
sudo tcpdump -i eth0 -nn not port 22

# Precise, keeps other SSH traffic visible
sudo tcpdump -i eth0 -nn 'not (host 203.0.113.9 and port 22)'

# Derive your client address from the environment
sudo tcpdump -i eth0 -nn \
  "not (host ${SSH_CLIENT%% *} and port ${SSH_CLIENT##* })"

$SSH_CLIENT is clientip clientport serverport, so ${SSH_CLIENT%% *} is the client address and ${SSH_CLIENT##* } is the local SSH port. Note the double quotes here, because the shell has to expand those.

Layer 2, MACs, broadcast, multicast

sudo tcpdump -i eth0 -nn -e ether host 00:11:22:33:44:55
sudo tcpdump -i eth0 -nn -e ether src 00:11:22:33:44:55
sudo tcpdump -i eth0 -nn -e ether broadcast
sudo tcpdump -i eth0 -nn arp or icmp6
FilterMatches
ether host <mac>Either MAC field
ether broadcastff:ff:ff:ff:ff:ff destination
ether multicastMulticast bit set in the destination MAC
ip broadcastIPv4 broadcast destination
ip multicast224.0.0.0/4 destination
ether proto \arpARP by EtherType, backslash is required
vlan 100802.1Q tag 100
mpls 1000MPLS label 1000

Add -e whenever you filter on MACs, otherwise the addresses you are matching on are not printed and you cannot check your own filter.

Finding a rogue DHCP server or an ARP conflict:

# Every ARP on the segment, with MACs
sudo tcpdump -i eth0 -nn -e arp

# DHCP offers, which reveal the server MAC and address
sudo tcpdump -i eth0 -nn -e -v 'udp port 67 or udp port 68'

VLAN tags shift every offset

vlan is positional, not a predicate. Once matched, it moves the decode point 4 bytes forward for everything after it.

# WORKS: vlan first, then the shifted offsets
sudo tcpdump -i eth0 -nn 'vlan 100 and tcp port 80'

# DOES NOT WORK as intended: tcp port 80 is checked untagged
sudo tcpdump -i eth0 -nn 'tcp port 80 and vlan 100'

# Tagged OR untagged, the portable form
sudo tcpdump -i eth0 -nn 'tcp port 80 or (vlan and tcp port 80)'

The same rule applies to mpls. Q-in-Q needs vlan twice: 'vlan and vlan and tcp port 80'.

If a filter that looks right returns nothing on a trunk port, a VLAN tag is almost always why. Run tcpdump -i eth0 -nn -e -c 20 with no filter and look for vlan 100, p 0 in the output.