You are here and that’s great! Let’s learn to dump ‘em packets ;)
Here are some small
tcpdump tricks that I thought could be helpful to others as well.
It should work on MacOS, Linux, and any number of *BSDs. The
$ denotes the shell prompt.
The last time I checked Windows (Linux subsystem), it did not support
your Microsoft rep to get it on Linux subsystem! :)
To keep simple things simple, i’ll begin with the format of
$ tcpdump [options] [expression]
Options are things like e.g.
-i any -nn -A -v.
Expressions are things like e.g.
dst port 9999 and should be single quoted e.g.
If the interface option is left unspecified (
-i), then based on the implementation,
tcpdump will choose the default interface available. On Linux and FreeBSD this is usually
the first available network interface such as
re0. On macOS, this is a pseudo
PKTAP which captures on all available interfaces.
To trace packets on network interface
eth0 and not perform any DNS name resolution
-n and give super brief info of the packet traces
$ tcpdump -i eth0 -nq
I recommend using the
-n option for packet tracing because the packet dumps are much cleaner
as there would be no name resolution and thus no DNS traffic to pollute the capture.
To filter on host www.example.com on all network interface.
$ tcpdump -n 'host www.example.com'
The name resolution for
www.example.com happens once when the
tcpdump starts. If your
DNS resource record has a short TTL and the answer value changes often whilst debugging,
its important to keep this in mind.
To specify expression to filter on destination host
126.96.36.199 matching all protocols.
$ tcpdump -n 'dst host 188.8.131.52'
One of the important thing to consider is positioning of options.
tcpdump implementations, the network interface and the other options come
before the expression. For e.g.,
# FreeBSD $ tcpdump 'dst host 184.108.40.206' -i em0 -nq tcpdump: syntax error $ tcpdump -i em0 -nq 'dst host 220.127.116.11' tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on em0, link-type EN10MB (Ethernet), capture size 65535 bytes #MacOS $ tcpdump 'dst host 18.104.22.168' -i en0 -nq 12:48:31.736991 IP 172.16.10.5 > 22.214.171.124: ICMP echo request, id 59336, seq 0, length 64 [...]
tcpdump implementations support listening on all interfaces via
-i any. The default
tcpdump implementations on macOS and Linux support this feature
#FreeBSD $ tcpdump -n -i any 'dst host 126.96.36.199' tcpdump: any: No such device exists (BIOCSETIF failed: Device not configured) #MacOS $ tcpdump -i any -n 'dst host 188.8.131.52' -nq (macOS) tcpdump: data link type PKTAP tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
To filter on source port 9999, protocol
tcp on network interface
$ tcpdump -n -i eth0 'tcp and src port 9999'
To filter on destination port 9999, protocol udp on netif
$ tcpdump -n -i eth0 'udp and dst port 9999'
tcp traffic on port 8080 using
-A which prints the packets’ content in ASCII
$ tcpdump -n -i eth0 -A 'tcp and dst port 8080'
To write out
icmp packet traces to a
pcap formatted file (it can get quite large)
$ tcpdump -w /tmp/icmp-trace.pcap -n -i eth0 icmp
To read in
pcap packet traces (alternatively,
wireshark is great too :)
$ tcpdump -r /tmp/icmp-trace.pcap
tcpdump expressions can be viewed as a BPF instructions using the
$ tcpdump -d 'dst host 184.108.40.206' (000) ldh  (001) jeq #0x800 jt 2 jf 4 (002) ld  (003) jeq #0x8080404 jt 8 jf 9 (004) jeq #0x806 jt 6 jf 5 (005) jeq #0x8035 jt 6 jf 9 (006) ld  (007) jeq #0x8080404 jt 8 jf 9 (008) ret #65535 (009) ret #0
Each line is a BPF instruction that can be executed within a BPF VM.
To trace all udp packets in a destination port range 50000-65535 (inclusive)
$ tcpdump -n -i eth0 'udp and dst portrange 50000-65535'
To trace all udp packets not going to host
220.127.116.11 on network interface
$ tcpdump -n -i eth0 'udp and not dst host (18.104.22.168 or 22.214.171.124)'
To trace all IPv6 packets on network interface
$ tcpdump -n -i eth0 ip6
To trace all IPv4 packets on network interface
eth0 for network
$ tcpdump -n -i eth0 'net 126.96.36.199/8'
To print all
tcp packets with just
SYN flag set
$ tcpdump -n -i eth0 'tcp[tcpflags] & tcp-syn == 2'
To print the first hundred
tcp packets to destination port 80 on
$ tcpdump -n -i eth0 -c 100 'tcp and dst port 80'
Capture packets indefinitely and rotate every 10 seconds
$ tcpdump -i eth0 -G 10 -w dump-%S.pcap 'dst port 80'
tcpdump man page is a gold mine. I have spent a long time reading it and every single time I find something new in it.
Following are some of the handy ones:
To print the start and end packets (the SYN and FIN packets) of each TCP conversation that involves a non-local host.
$ tcpdump -n -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net 127.0.0.1'
To print all IPv4 HTTP packets to and from port 80, i.e. print only packets that contain data, not, for example, SYN and FIN packets and ACK-only packets.
$ tcpdump -n -i eth0 'tcp port 80 and (((ip[2:2] - ((ip&0xf)<<2)) - ((tcp&0xf0)>>2)) != 0)'
To print IP packets longer than 576 bytes sent through gateway snup:
$ tcpdump -n -i eth0 'gateway snup and ip[2:2] > 576'
To print IP broadcast or multi-cast packets that were not sent via Ethernet broadcast or multicast:
$ tcpdump -n -i eth0 'ether & 1 = 0 and ip >= 224'
To print all ICMP packets that are not an ICMP echo request/reply (e.g. not ping packets):
$ tcpdump -n -i eth0 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply'