On the wire
tcpdump
Prints the packets passing a network card, filtered by address, port or protocol: the ground truth.
Every other command tells you what a program believes; tcpdump shows what really crosses the card. Capture
on both ends (or on each card of a router) and compare: a packet that leaves one side and never arrives at the
other was lost between them. The filter at the end keeps it readable: host, net, port, icmp, arp,
combined with and, or, not. TCP flags read [S] SYN, [S.] SYN-ACK, [.] ACK, [P.] data,
[F.] FIN, [R] reset.
tcpdump command usage
tcpdump [-n|-nn] [-e] [-v] [-S] [-A|-X] [-tttt|-ttt] [-i CARD] [-c COUNT] [-l] [-s SNAPLEN] [-w FILE [-C MB] [-W FILES] [-G SECONDS]] [FILTER] tcpdump -r FILE [-n] [-A|-X] [FILTER] tcpdump -D
Options
-
-D - list the cards it can capture on
-
-i eth0 - capture on that card (any: every card)
-
-c 10 - stop after that many packets
-
--help - list every option by its letter, and stop
-
-n / -nn - don't resolve addresses / nor port names
-
host 10.0.2.10 - filter: only packets to or from that address (the filter goes after the options)
-
port 53 - filter: only packets to or from that port, on TCP or UDP
-
-e - print the Ethernet header: MAC addresses
-
arp - filter: only ARP
-
icmp - filter: only ICMP: pings and their errors
-
-A - print each packet's data as text
-
and / or / not - filter: join filter words, or turn one around; group them with ( ) and put the whole filter in single quotes
-
src host 10.0.1.12 - filter: only packets this address sends
-
dst host 10.0.1.12 - filter: only packets sent to this address
-
net 10.0.2.0/24 - filter: only packets to or from any address in this network
-
udp - filter: only UDP; udp port 53 is port 53 on UDP alone
-
tcp[tcpflags] & tcp-syn != 0 - filter (quoted): only TCP packets with that flag on (tcp-syn, tcp-ack, tcp-fin, tcp-rst, tcp-push); & (tcp-syn|tcp-ack) == tcp-syn keeps new connections only
-
-v - more detail: TTL, IP id, flags, lengths
-
tcp - filter: only TCP; tcp port 80 is port 80 on TCP alone
-
-S - print the real sequence numbers, not counted from the conversation's start
-
-X - print each packet in hex and as text, side by side
-
-tttt - start each line with the date and time
-
-ttt - start each line with the time since the packet before
-
-w file.pcap - save the packets to a file (for Wireshark, or -r) instead of printing them
-
-r file.pcap - read a saved capture instead of a card
-
-s 96 - keep only that many bytes of each packet, its start (snap length)
-
-C 100 - with -w, start a new file each time this many MB are written
-
-W 5 - keep at most that many files, writing over the oldest
-
-G 3600 - with -w, start a new file every that many seconds (name it with %H%M%S)
-
-l - print each line at once (for pipes)
tcpdump examples
-
tcpdump -ni eth0 host 10.0.2.10 - Prints every packet to or from 10.0.2.10 on eth0.
-
tcpdump -ni eth0 icmp - Prints only ICMP: pings, and errors such as unreachable or time exceeded.
-
tcpdump -eni eth0 arp - Prints ARP requests and replies with the MAC addresses of each frame.
-
tcpdump -nni eth0 'tcp port 80' - Prints web traffic on port 80, with numeric ports.
-
tcpdump -ni any -c 20 'udp port 53' - Prints the first 20 DNS packets on any card.
-
tcpdump -nni eth0 'tcp[tcpflags] & tcp-syn != 0' - Prints SYN packets: connection attempts, and the SYN-ACKs that answer them.
-
tcpdump -D - Lists the cards tcpdump can capture on, any included.
-
tcpdump -nni eth0 -ttt 'tcp port 8080' - Starts each line with the time since the one before: the same SYN sent again after 1 s, then 2 s, is a connection nothing answers.
-
tcpdump -ni eth0 net 10.0.2.0/24 - Prints packets to or from any address in 10.0.2.0/24.
-
tcpdump -ni eth0 'src 10.0.1.10 and dst port 443' - Prints only what 10.0.1.10 sends to HTTPS servers: and, or, not combine filters.
-
tcpdump -ni eth0 'host 10.0.2.10 and not port 22' - Prints a host's traffic but leaves out your own SSH session to it.
-
tcpdump -ni eth0 -w capture.pcap - Writes the packets to capture.pcap for Wireshark or a later read, printing nothing.
-
tcpdump -nr capture.pcap 'tcp port 80' - Reads a saved capture, with a filter like a live one.
-
tcpdump -ni eth0 -A 'tcp port 80' - Prints each packet's content as text: readable HTTP headers when the traffic is not encrypted.
-
tcpdump -ni eth0 -X -c 5 'udp port 53' - Prints five packets in hex and text side by side, to read a protocol byte by byte.
-
tcpdump -nvi eth0 icmp - Prints the IP header details too: TTL, ID, length and flags such as DF.
-
tcpdump -nni eth0 'tcp[tcpflags] & tcp-rst != 0' - Prints only resets: connections refused or torn down.
-
tcpdump -ni eth0 -w ring.pcap -C 100 -W 5 - Captures into five files of about 100 MB each, overwriting the oldest: runs for days without filling the disk.
-
tcpdump -ni eth0 -s 96 -w heads.pcap - Saves only each packet's first 96 bytes: the headers, enough to follow every packet, in a much smaller file.
-
tcpdump -ni any icmp - Captures on every card at once; each line names the card and In or Out: where a router sends what.
Reading the output
$ tcpdump -ni eth0 host 10.0.2.10 10:00:46.601811 IP 10.0.1.10.38412 > 10.0.2.10.80: Flags [S], seq 3789070994, win 64240, options [mss 1460,…], length 0 10:00:46.601919 IP 10.0.2.10.80 > 10.0.1.10.38412: Flags [S.], seq 3272071078, ack 3789070995, win 65160, …, length 0 10:00:46.601930 IP 10.0.1.10.38412 > 10.0.2.10.80: Flags [.], ack 1, win 502, length 0 10:00:46.601987 IP 10.0.1.10.38412 > 10.0.2.10.80: Flags [P.], seq 1:75, ack 1, win 502, length 74: HTTP: GET / HTTP/1.1 10:00:46.602234 IP 10.0.2.10.80 > 10.0.1.10.38412: Flags [P.], seq 1:210, ack 75, win 509, length 209: HTTP: HTTP/1.1 200 OK
10.0.1.10.38412 > 10.0.2.10.80: source address.port, then destination address.port.[S],[S.],[.]: the three-way handshake. Only[S]repeating: no answer.[S]then[R.]: refused.seq 1:75 … length 74: 74 bytes of data;ack 75from the other side confirms them.mss 1460: the largest segment each side accepts, announced in the SYN.
Pitfalls
- Without
-n, tcpdump looks up every address in DNS: slow, and it adds DNS packets of its own. - Capture on the right card: on a router, a packet shows on the card it enters by and the card it leaves by.
- Quote filters with brackets or
&so the shell leaves them alone.