Skip to main content

tcpdump and Wireshark

ping, traceroute, and dig tell you whether things are reachable and how names resolve. When neither explains a problem, the next step is to look at the actual packets on the wire. tcpdump captures them from a terminal; Wireshark opens the same capture (or a saved file from tcpdump) with a GUI built for digging through it.

Filter syntax basics

tcpdump filters are written in BPF (Berkeley Packet Filter) syntax. The building blocks:

FilterMatches
host 10.0.0.5traffic to or from that IP
net 10.0.0.0/24traffic to or from that subnet
port 443traffic on that port, either direction
tcpTCP traffic only (also udp, icmp)
src host X / dst host Xdirection-qualified host match
and / or / notcombine filters, e.g. host 10.0.0.5 and port 443
$ sudo tcpdump -i eth0 host 10.0.0.5 and port 443
tcpdump: verbose output suppressed, use -v for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
10:22:01.114532 IP 10.0.0.7.51322 > 10.0.0.5.443: Flags [S], seq 3021456789, win 65535, length 0
10:22:01.115901 IP 10.0.0.5.443 > 10.0.0.7.51322: Flags [S.], seq 118273645, ack 3021456790, win 65160, length 0
10:22:01.116233 IP 10.0.0.7.51322 > 10.0.0.5.443: Flags [.], ack 118273646, win 2058, length 0
10:22:01.118877 IP 10.0.0.7.51322 > 10.0.0.5.443: Flags [P.], seq 1:518, ack 1, win 2058, length 517
10:22:01.119654 IP 10.0.0.5.443 > 10.0.0.7.51322: Flags [.], ack 518, win 65535, length 0

Flags [S], [S.], [.], [P.], [F.], [R] are TCP flags decoded by name: S = SYN, . = ACK, P = PSH, F = FIN, R = RST. That first three-line exchange above is a textbook TCP handshake: SYN, SYN-ACK, ACK.

Matching flags directly

You can also filter on the raw flags byte, which is byte offset 13 of the TCP header. tcp[13] is that byte; tcp[13]&2!=0 masks bit 2, the SYN bit, selecting only packets with SYN set (both plain SYNs and SYN-ACKs):

$ sudo tcpdump -i eth0 'tcp[13]&2!=0'

Other commonly used masks:

FilterSelects
tcp[13]&2!=0SYN set (connection attempts, including SYN-ACK)
tcp[13]&4!=0RST set (resets)
tcp[13]&1!=0FIN set (graceful close)
'tcp[13]=2'SYN set and nothing else (a fresh outbound SYN only)
info

The flags byte's bits, from the low bit up, are FIN(1) SYN(2) RST(4) PSH(8) ACK(16) URG(32). A SYN-ACK packet has both bit 2 and bit 16 set, so tcp[13]&2!=0 matches it too - use tcp[13]=2 if you want only the initial SYN.

Capturing to a file, opening in Wireshark

tcpdump on its own is fine for a quick filtered stream in a terminal, but for anything you need to scroll back through, reassemble, or hand to someone else, capture to a .pcap file and open it in Wireshark:

$ sudo tcpdump -i eth0 -w capture.pcap host 10.0.0.5

-w writes raw packets instead of printing a decoded summary (decoding as you capture can drop packets under load, so -w is also the safer choice for a busy link). Copy capture.pcap to a machine with Wireshark and open it there; every packet tcpdump would have summarized on one line is now a row you can click into, with every header field broken out.

tip

Same filter syntax works when reading back: tcpdump -r capture.pcap 'tcp[13]&4!=0' replays only the reset packets from a saved capture, without needing to recapture live.

Following a TCP stream

Wireshark's "Follow > TCP Stream" (right-click any packet in a connection) reassembles every payload byte from both directions of one TCP connection, in order, into a single readable view - this is how you read an actual HTTP request/response or a plaintext protocol exchange instead of piecing it together packet by packet. For TLS traffic the bytes are encrypted unless you have supplied a decryption key (e.g. via SSLKEYLOGFILE), so "Follow Stream" mostly shows the handshake, not the application data.

Spotting retransmissions and resets

Two patterns in a capture almost always mean trouble, and Wireshark flags both automatically (in the black/red-highlighted rows and the Info column):

  • Retransmissions - the same sequence number sent more than once means the original was never acknowledged in time. Wireshark labels these [TCP Retransmission]. A handful under real packet loss is normal; a connection that retransmits repeatedly and never progresses points at loss or a black hole somewhere on the path (a job for mtr, see ping, traceroute & mtr).
  • Resets - a Flags [R] packet tears the connection down immediately, with no graceful FIN exchange. A reset arriving right after a SYN usually means nothing is listening on that port; a reset mid-connection usually means one side crashed, hit a timeout, or a firewall/load balancer actively killed the connection.
10:22:03.410221 IP 10.0.0.7.51322 > 10.0.0.5.443: Flags [P.], seq 518:1035, ack 1, length 517
10:22:03.610455 IP 10.0.0.7.51322 > 10.0.0.5.443: Flags [P.], seq 518:1035, ack 1, length 517
[TCP Retransmission] - same seq 518:1035 sent again 200ms later, no ACK in between
Gotcha

A [TCP Retransmission] label in Wireshark can also appear spuriously when capturing on the sending host with TCP segmentation offload (TSO) enabled - the NIC does the actual segmentation in hardware after the capture point sees one large "packet." If retransmission counts look implausibly high only on the sender's own capture, capture on the receiver (or an in-path tap) instead.