Network Debugging: tcpdump, wireshark, netstat, ss
What This Concept Is
When a network problem shows up, guessing is expensive. Four tools let you replace guesses with evidence:
tcpdump-- CLI packet capture. Shows the actual bytes going in and out of an interface, filtered by BPF expressions. Ubiquitous on Unix-like systems. Saves captures as.pcapfiles.- Wireshark -- GUI packet analyzer that reads
tcpdump's.pcapfiles (or captures its own). Extensive protocol dissectors: it decodes TCP, TLS, HTTP/1, HTTP/2, DNS, and hundreds more, one layer at a time. netstat-- shows sockets, their states, and per-protocol statistics. Older and slower; still useful cross-platform (including Windows).ss(Linux) -- modern replacement fornetstat. Much faster, richer filters, and can show TCP internal state likecwnd, retransmits, RTT, and pacing.
The workflow is usually: start with ss to see what sockets exist and what state they are in; use tcpdump to capture traffic; open the capture in Wireshark for protocol-level interpretation.
Why It Matters Here
Almost every non-trivial production networking bug -- stuck connections, sudden latency spikes, mysterious resets, TLS handshake failures -- is solved by picking the right layer and watching real bytes or real socket states. These tools are how senior engineers confirm or refute a hypothesis in minutes instead of hours.
Concrete Example
Capture the TCP handshake of a local connection:
sudo tcpdump -n -i lo -S "port 9000"
Typical output:
10:00:00.000001 IP 127.0.0.1.54321 > 127.0.0.1.9000: Flags [S], seq 1000, win 65535, length 0
10:00:00.000010 IP 127.0.0.1.9000 > 127.0.0.1.54321: Flags [S.], seq 4000, ack 1001, win 65535, length 0
10:00:00.000020 IP 127.0.0.1.54321 > 127.0.0.1.9000: Flags [.], ack 4001, win 65535, length 0
Three packets: SYN, SYN-ACK, ACK. Exactly the state machine from Concept 9.
List sockets and their states:
ss -tan state established '( sport = :9000 or dport = :9000 )'
See per-connection TCP internals:
ss -tin '( sport = :443 or dport = :443 )'
This shows cwnd, rtt, retrans, and more.
Common Confusion / Misconception
"tcpdump shows me everything." It shows what reaches the kernel on that interface with the BPF filter you gave. Hardware offload (TSO, GRO) can make packets look merged; VPN/encapsulation can hide inner protocols; and TLS obviously hides payload. Use -s 0 for full packets and be aware of layer-of-capture effects.
"Wireshark is just a prettier tcpdump." Wireshark adds dissectors: it reconstructs TCP streams, decodes HTTP across segments, decrypts TLS (with session keys), and knows the quirks of hundreds of protocols. It is qualitatively different.
How To Use It
The debugging loop:
- Form a hypothesis at a specific layer (e.g., "the server is sending RST after the first data segment").
- Use
ssto confirm the socket state you expect. - Use
tcpdumpwith a narrow filter (port + host) to capture the relevant window. - Open the
.pcapin Wireshark and follow the TCP stream. - Confirm or reject the hypothesis; repeat one layer higher or lower.
Check Yourself
- Why is
ss -tinmore useful thannetstat -antfor performance debugging? - What BPF filter captures just traffic to or from
10.0.24.53on port 443? - When would Wireshark's "Follow TCP Stream" feature mislead you?
- Why might
tcpdumpon the same host that runs the server miss packets that a mid-path capture would see? - How do you tell, from
ss -ti, whether a connection is limited by the receiver's window or by congestion control?
Useful Filter Recipes
- Only traffic for one host:
host 10.0.24.53. - Only one direction:
src host 10.0.24.53 and port 443. - Only SYN packets:
tcp[tcpflags] & tcp-syn != 0. - Only
RSTpackets:tcp[tcpflags] & tcp-rst != 0. - Full-packet capture to disk for later analysis:
sudo tcpdump -s 0 -w out.pcap "port 443".
Keep a short personal cheatsheet; good filters are the difference between a five-second confirmation and a half-hour scroll.
Mini Drill or Application
- Start the echo server from Concept 13 on port 9000.
- Capture one connection's full lifecycle to a file:
sudo tcpdump -i lo -w echo.pcap "port 9000". - From
nc localhost 9000, send two lines, Ctrl-D, stop the capture. - Open
echo.pcapin Wireshark. Identify: 3 handshake packets, data segments, 4 close packets. Note any ACKs the human eye would miss. - Run
ss -tin '( sport = :9000 )'while the server is idle and while it has a connection; compare.