Commands / On the wire

On the wire

tcpdump

Also packet capture, sniffer, wireshark, pcap

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 75 from 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.

Run it on real machines

Learn it on real machines.

Every lab is a small network of real Linux machines in your browser. Start with a free account: Google or email, no card.

Start free