When something goes wrong on a network — a connection times out, an application can’t reach a server, a firewall silently drops traffic — the most reliable way to find out exactly what’s happening is to look at the actual packets traveling across the wire. tcpdump is the classic, universally available Linux command-line tool for capturing and analyzing network traffic in real time. This article explains, from first principles, how packet sniffing works, how to use tcpdump effectively, and how to interpret its output.
What Is Packet Sniffing?
Every piece of data sent over a network — a web page request, an SSH session, a DNS query — is broken into small units called packets. Packet sniffing is the process of intercepting and inspecting these packets as they pass through a network interface, without necessarily being the intended recipient.
flowchart LR
A[Application] --> B[Network Stack]
B --> C[Network Interface Card]
C -.->|Promiscuous Mode| D[tcpdump captures a copy]
C --> E[Physical Network]tcpdump works by putting a network interface into a special listening mode and using the kernel’s packet capture facility (libpcap) to receive a copy of every packet passing through that interface — matching, if desired, a specific filter.
Installing tcpdump
sudo apt install tcpdump # Debian/Ubuntu
sudo dnf install tcpdump # RHEL/Fedora
Basic Usage
sudo tcpdump -i eth0
-i eth0specifies which interface to listen on- Without a filter, this captures all traffic on that interface, which can be overwhelming
Press Ctrl+C to stop capturing.
Understanding tcpdump Output
A typical line of output looks like this:
14:32:01.123456 IP 192.168.1.10.54321 > 93.184.216.34.443: Flags [S], seq 123456789, win 64240, length 0
| Field | Meaning |
|---|---|
14:32:01.123456 | Timestamp |
IP | Protocol (IPv4) |
192.168.1.10.54321 | Source IP and port |
93.184.216.34.443 | Destination IP and port |
Flags [S] | TCP flag — S = SYN (connection start) |
seq 123456789 | Sequence number |
win 64240 | TCP window size |
length 0 | Payload length (0 for a bare SYN packet) |
Common TCP Flags in Output
| Flag | Meaning |
|---|---|
S | SYN — initiating a connection |
S. (SYN-ACK) | Acknowledging a SYN, server accepting connection |
. (ACK) | Acknowledgment of received data |
P | PSH — push data to the application immediately |
F | FIN — graceful connection close |
R | RST — connection reset (abrupt close/rejection) |
Filtering Traffic
Capturing everything is rarely useful. tcpdump supports Berkeley Packet Filter (BPF) syntax to narrow down exactly what you want to see.
Filter by Host
sudo tcpdump -i eth0 host 192.168.1.10
Filter by Port
sudo tcpdump -i eth0 port 443
Filter by Protocol
sudo tcpdump -i eth0 icmp
sudo tcpdump -i eth0 tcp
sudo tcpdump -i eth0 udp
Combining Filters
sudo tcpdump -i eth0 'host 192.168.1.10 and port 443'
sudo tcpdump -i eth0 'src 192.168.1.10 and dst port 22'
Filtering Only SYN Packets (New Connection Attempts)
sudo tcpdump -i eth0 'tcp[tcpflags] == tcp-syn'
Saving Captures to a File for Later Analysis
sudo tcpdump -i eth0 -w capture.pcap
Later, read it back:
tcpdump -r capture.pcap
.pcap files can also be opened in Wireshark for detailed graphical analysis — tcpdump and Wireshark share the same underlying capture format, so they’re highly complementary tools.
Increasing Verbosity and Seeing Packet Contents
sudo tcpdump -i eth0 -v # verbose
sudo tcpdump -i eth0 -vv # more verbose
sudo tcpdump -i eth0 -A # show packet contents as ASCII
sudo tcpdump -i eth0 -X # show packet contents in hex AND ASCII
Example: viewing unencrypted HTTP traffic content (useful for debugging, only ever on traffic you’re authorized to inspect):
sudo tcpdump -i eth0 -A port 80
A Practical Example: Diagnosing a Connection Timeout
A web application server can’t reach a database on port 5432. Let’s investigate:
Step 1: Start capturing on the app server while reproducing the issue
sudo tcpdump -i eth0 -n host 10.0.0.5 and port 5432
Step 2: Trigger the connection attempt from the application
Step 3: Observe the output
If you see repeated SYN packets with no SYN-ACK response:
14:00:01 IP 10.0.0.10.51234 > 10.0.0.5.5432: Flags [S]
14:00:04 IP 10.0.0.10.51234 > 10.0.0.5.5432: Flags [S]
14:00:10 IP 10.0.0.10.51234 > 10.0.0.5.5432: Flags [S]
This pattern (repeated SYNs, no response at all) typically indicates a firewall silently dropping the traffic somewhere between the two hosts — rather than the database actively refusing the connection (which would show a RST response instead).
Real-World Example: Confirming DNS Queries Are Leaving the Server
sudo tcpdump -i eth0 -n port 53
Watching this while running dig example.com on another terminal confirms whether DNS queries are actually leaving the interface, and whether responses come back — useful when debugging “works sometimes” DNS issues.
Comparison: tcpdump vs. Wireshark
| Feature | tcpdump | Wireshark |
|---|---|---|
| Interface | Command-line | Graphical |
| Best for | Servers, remote sessions, scripting | Deep protocol analysis, visual inspection |
| Resource usage | Very light | Heavier |
| Use case | Quick diagnostics, headless servers | Detailed packet dissection, teaching, forensics |
| File format | .pcap (readable by both) | .pcap/.pcapng |
Best Practices
- Always use the narrowest filter possible. Capturing all traffic on a busy server can be overwhelming and can itself impact performance.
- Use
-nto disable DNS resolution during capture (sudo tcpdump -n ...), which both speeds up capture and avoids generating extra DNS traffic that could pollute your own analysis. - Save captures to files for later analysis with
-w, especially for intermittent issues you can’t watch live. - Never capture and store traffic containing sensitive data (like unencrypted credentials) longer than necessary, and always ensure you have authorization to monitor the traffic in question.
- Combine with
grep,awk, or scripting for automated analysis of large capture files. - Rotate capture files for long-running captures to avoid filling up disk space:
-w capture-%Y%m%d.pcap -G 3600.
Troubleshooting
Problem: tcpdump: eth0: You don't have permission to capture on that device
Packet capture requires elevated privileges. Run with sudo, or grant the cap_net_raw capability to the binary for non-root use:
sudo setcap cap_net_raw,cap_net_admin=eip $(which tcpdump)
Problem: No packets are captured at all
Confirm you’re listening on the correct interface:
ip link show
sudo tcpdump -D # lists all available interfaces
Problem: Too much traffic, hard to find what you need
Tighten your filter, and use -c to limit the number of packets captured:
sudo tcpdump -i eth0 -c 20 port 443
Problem: Traffic appears encrypted/unreadable (as expected for HTTPS)
This is normal and expected for HTTPS/TLS traffic — tcpdump shows you headers and metadata (source, destination, timing) but not encrypted payload content. For content inspection, you’d need access to TLS keys or a controlled decryption setup, which is a much more advanced and sensitive topic.
Problem: Capture file grows too large
Limit capture size and enable rotation:
sudo tcpdump -i eth0 -w capture.pcap -C 100 -W 5
This rotates through 5 files of 100 MB each.
Conclusion
tcpdump is one of the most powerful and universally available diagnostic tools in a Linux administrator’s toolkit — capable of revealing exactly what’s happening at the network level when higher-level symptoms (timeouts, failed connections, slow responses) don’t tell the full story. By mastering filters, understanding TCP flag output, and knowing when to save captures for deeper analysis in Wireshark, you gain the ability to diagnose network problems with precision instead of guesswork.
