The most surprising thing about tcpdump’s verbose output is how much of the packet’s internal state it can reveal, often highlighting subtle protocol misbehaviors that a simple packet capture would miss entirely.

Let’s see tcpdump in action, not just capturing, but dissecting. Imagine we’re debugging a slow connection. We’ve got a client trying to talk to a server, and we suspect TCP issues.

First, the basics. A standard tcpdump might look like this:

sudo tcpdump -i eth0 host 192.168.1.100 and port 80 -w capture.pcap

This just grabs packets going to or from 192.168.1.100 on port 80 and saves them. Useful, but opaque.

Now, let’s add verbosity. The -v flag is our entry point.

sudo tcpdump -i eth0 -v host 192.168.1.100 and port 80 -w capture.pcap

Running this and then examining capture.pcap with tcpdump -r capture.pcap -v (or just running the command interactively) will show us more. We’ll start seeing things like TCP sequence and acknowledgment numbers, window sizes, and flags.

For example, a SYN packet might show up as:

10:30:01.123456 IP 192.168.1.100.54321 > 192.168.1.100.80: Flags [S], seq 123456789, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS val 12345678 ecr 0], length 0

Notice the seq (sequence number), win (window size), and the options like mss (Maximum Segment Size), wscale (window scaling), and TS (Timestamps). This is crucial.

To really understand what’s happening, we need to go deeper. -vv adds even more detail, particularly to IP and TCP headers.

sudo tcpdump -i eth0 -vv host 192.168.1.100 and port 80 -w capture.pcap

With -vv, you’ll see TTL (Time To Live), IP ID, and more detailed TCP options.

The ultimate verbosity for TCP/IP debugging is -vvv. This flag unpacks almost every field in the IP and TCP headers, making it invaluable for pinpointing low-level protocol issues.

sudo tcpdump -i eth0 -vvv host 192.168.1.100 and port 80 -w capture.pcap

When you examine a packet with -vvv, you might see something like:

10:30:01.123456 IP (tos 0x0, ttl 64, id 12345, offset 0, flags [DF], proto TCP (6), length 60) 192.168.1.100.54321 > 192.168.1.100.80: Flags [S], seq 123456789, ack 0, win 65535, options [mss 1460,nop,wscale 7,sackOK,TS value 12345678 ecr 0], length 0

Here, tos (Type of Service), ttl (Time To Live), id (IP ID), offset, flags [DF] (Don’t Fragment) are all visible. For TCP, seq, ack, win, and the detailed options become explicit.

The problem tcpdump -v (and its variants) solves is the opacity of network traffic. Without it, you’re guessing. With it, you can see the exact state of the TCP connection from both sides. For instance, if you see a client sending packets with a very small win value, even if it has a high wscale, it’s signaling congestion or a receiver buffer issue. Or if you see the TS (Timestamp) values not incrementing as expected, it could indicate clock skew or processing delays.

The real power comes from correlating these details across packets. You can observe the initial three-way handshake: SYN, SYN-ACK, ACK. With -vvv, you see the seq and ack numbers align perfectly. You can then watch the win values. If the server’s win is small, it limits how much data the client can send. If the client’s win is small, it means the client is telling the server to slow down.

Consider a scenario where packets are being dropped. A standard capture might show retransmissions. With -vvv, you can see the reason for the retransmission. If the ack numbers aren’t advancing from the sender’s perspective, it means the receiver isn’t acknowledging packets, potentially due to packet loss or being overwhelmed. You can even spot duplicate ACKs, which tcpdump will often flag, indicating a lost segment that the receiver did get some data after.

The options field is another goldmine. mss tells you the largest payload size allowed in a single TCP segment. wscale is critical for modern high-bandwidth networks; without it, TCP window sizes are severely limited. Seeing a wscale of 7 means the window can be up to 128 times larger than the base win value. If you see a wscale of 0, it’s a massive bottleneck on anything but a low-bandwidth link. sackOK indicates that Selective Acknowledgments are supported, allowing the receiver to specify exactly which segments it has received, rather than just the next expected one. TS values are used for Round Trip Time (RTT) measurement and can help detect network jitter or clock synchronization issues between the client and server.

A common, often overlooked, detail revealed by -vvv is the IP header’s ttl field. If the ttl is unexpectedly low, it might indicate the packet is traversing more routers than anticipated, or worse, that it’s looping somewhere. Seeing the DF (Don’t Fragment) flag is also important; if set and a router needs to fragment the packet, it will be dropped, and tcpdump with verbose output can help you see that this flag is set on packets that are too large for a hop.

The core of understanding TCP’s congestion control and flow control mechanisms lies in observing the interplay between the win field (flow control, dictated by receiver buffer availability) and the seq and ack numbers (sequence and acknowledgment for reliable delivery and congestion control signals). When the win is zero, the sender must stop sending data until it receives an ACK with a non-zero window. This is the explicit signal of receiver buffer exhaustion.

If you’re troubleshooting a connection that hangs during the TLS handshake, -vvv can show you the sequence numbers and flags of the Certificate, Client Key Exchange, and Change Cipher Spec messages. You might see retransmissions of these specific packets, or perhaps the server’s response packets have a win of 0, indicating it’s struggling to process the request.

The next common problem you’ll encounter after mastering tcpdump -v is understanding how to filter based on the content revealed by that verbosity, such as filtering for packets with a specific TCP option or a zero window.

Want structured learning?

Take the full Tcpdump course →