tcpdump network
wireshark is 300MB. this is one command.
The tcpdump man page is 1,100 lines long. You need about six filters and you’ll debug network problems faster than anyone with a GUI.
You had a network problem. Something wasn’t connecting. Something was timing out. Something was “just not working.” So you installed Wireshark. 300MB of GUI. You opened it. You selected an interface from a dropdown that listed eighteen options, half of which you didn’t recognize. You clicked “Start Capture.” Your screen filled with thousands of packets per second in a color-coded table. You stared at it. You scrolled. You saw a lot of green and some red. You had no idea what you were looking at. You right-clicked things. You tried “Follow TCP Stream.” More text. More confusion. You closed Wireshark and went back to Googling the error message.
tcpdump does the same thing in one command. It shows you exactly the traffic you care about — and nothing else — because you tell it what to filter before it starts capturing. No 300MB install. No interface dropdown. No color-coded confusion.
Unless you’re running Windows then wtf none of this applies to you. But hey, come to the dark side, go install WSL2 and you can follow along. We’ll wait. Impatiently.
If you’re lazy like me (all sysadmins are!) then click here for the tcpdump cheat sheet.
Capture everything (don’t actually do this)
sudo tcpdump
This captures every packet on the default interface and scrolls your terminal into oblivion. It’s useful for about three seconds to confirm “yes, traffic exists.” Then you stop it with Ctrl+c and add filters like a grown-up.
You need sudo because capturing packets requires root privileges. This is by design — you shouldn’t be reading other people’s packets without knowing what you’re doing.
Pick an interface
sudo tcpdump -i eth0
-i selects the network interface. If you don’t know which one to use:
sudo tcpdump -D
Lists all available interfaces. Pick the one that matters. Usually eth0 or ens33 for wired, wlan0 for wireless, any for everything.
sudo tcpdump -i any
Capture on all interfaces at once. Useful when you’re not sure where the traffic is flowing.
Filter by host
sudo tcpdump host 192.168.1.50
Only traffic to or from that IP. The noise drops from thousands of packets per second to the dozen you actually care about.
sudo tcpdump src 192.168.1.50
sudo tcpdump dst 10.0.0.1
src for traffic coming from an IP. dst for traffic going to an IP. When you need to be specific about the direction.
Filter by port
sudo tcpdump port 443
All HTTPS traffic. For when you want to see what’s talking to a web server.
sudo tcpdump port 53
All DNS queries. This is how you find out what your system is resolving and where it’s sending those queries. Surprisingly useful for debugging “why can’t I reach this hostname” problems.
sudo tcpdump src port 22
Traffic originating from port 22 — outbound SSH responses.
Filter by protocol
sudo tcpdump tcp
sudo tcpdump udp
sudo tcpdump icmp
Only TCP, UDP, or ICMP traffic. When you know what protocol you’re troubleshooting and don’t want to wade through everything else.
Combine filters
tcpdump uses and, or, and not to combine filters. This is where it gets powerful.
sudo tcpdump host 10.0.0.5 and port 80
HTTP traffic to/from a specific host.
sudo tcpdump src 192.168.1.0/24 and dst port 443
HTTPS traffic from your entire local subnet. The /24 is CIDR notation — it matches 192.168.1.0 through 192.168.1.255.
sudo tcpdump not port 22
Everything except SSH. Critical when you’re SSH’d into a remote server and don’t want to capture your own session — because that’s a feedback loop of packets that will fill your screen with noise.
sudo tcpdump 'host 10.0.0.5 and (port 80 or port 443)'
HTTP or HTTPS to/from a host. The quotes and parentheses prevent your shell from misinterpreting the expression.
Make the output readable
Show IP addresses as numbers (don’t resolve DNS)
sudo tcpdump -n host 10.0.0.5
-n skips DNS resolution. Without it, tcpdump tries to look up every IP address, which slows things down and clutters the output with hostnames you might not recognize. Always use -n.
Show more detail
sudo tcpdump -v host 10.0.0.5
sudo tcpdump -vv host 10.0.0.5
-v for verbose, -vv for more verbose. Shows TTL, packet length, TCP flags, and other header details. Use when the basic output doesn’t tell you enough.
Show packet contents (ASCII)
sudo tcpdump -A port 80
Prints the packet payload in ASCII. For unencrypted traffic (HTTP, not HTTPS), you can literally read the requests and responses. You’ll see headers, cookies, HTML — everything. On HTTPS (port 443), you’ll see encrypted garbage, which is the point.
Show packet contents (hex and ASCII)
sudo tcpdump -XX port 80
Hex dump with ASCII side-by-side. For when you need to see the raw bytes. Debugging protocol issues, inspecting headers, or impressing people who walk by your screen.
Save captures to a file
sudo tcpdump -w capture.pcap host 10.0.0.5
-w writes raw packets to a .pcap file. This is the standard format — Wireshark, tshark, and every other tool can read it.
Capture on the server. Download the file. Open it in Wireshark on your laptop. Best of both worlds — tcpdump for the fast capture, Wireshark for the deep analysis.
Limit the capture
sudo tcpdump -c 100 -w capture.pcap host 10.0.0.5
-c 100 stops after 100 packets. Without this, tcpdump runs forever until you Ctrl+c. Useful when you just need a sample, not a firehose.
Read a capture file
tcpdump -r capture.pcap
No sudo needed — you’re reading a file, not capturing live traffic. Apply the same filters you’d use live:
tcpdump -r capture.pcap port 443 and host 10.0.0.5
Timestamps
sudo tcpdump -tttt -n port 80
-tttt shows the full date and time in human-readable format. Default timestamps are relative and confusing. This gives you 2026-03-15 14:32:07.123456 — useful for correlating with log files.
The flags that actually matter
| Flag / Filter | What it does |
|---|---|
-i IFACE |
Capture on a specific interface (or any). |
-n |
Don’t resolve hostnames. Always use this. |
-v / -vv |
Verbose output with more packet detail. |
-A |
Show packet ASCII payload. |
-XX |
Show hex + ASCII dump. |
-w FILE |
Write packets to a pcap file. |
-r FILE |
Read packets from a pcap file. |
-c N |
Stop after N packets. |
-tttt |
Full timestamp with date. |
host IP |
Filter by host (source or destination). |
src / dst |
Filter by direction. |
port N |
Filter by port number. |
tcp / udp / icmp |
Filter by protocol. |
and / or / not |
Combine filters. |
“But Wireshark—”
Yes. Wireshark. Let’s talk about Wireshark.
“Wireshark has a GUI.” Wireshark has a 300MB GUI that requires a display server, a window manager, and a desktop environment. Your production server doesn’t have any of those things. And if it does, you have bigger problems than packet capture.
“Wireshark can decode protocols.” So can tcpdump with -v. For the 90% of debugging that’s “is traffic reaching the server,” “what port is it on,” and “are the packets getting through,” tcpdump is faster and lighter. For deep protocol analysis on a pcap file? Sure, use Wireshark on your laptop. But capture with tcpdump first.
“Wireshark shows traffic in real time with colors.” The colors are display filters applied after capture. tcpdump’s text filters are applied during capture, which means you only see what you asked for. Less visual, more precise. You don’t need a red row to tell you a connection was reset — tcpdump -v shows you the RST flag in the text.
“I don’t know the filter syntax.” You know it now. host, port, src, dst, and, or, not. That covers 95% of everything. Wireshark’s display filter syntax is arguably harder — tcp.flags.syn == 1 && ip.dst == 10.0.0.5 vs tcpdump’s dst 10.0.0.5 and tcp[tcpflags] & tcp-syn != 0. Both require learning. One doesn’t require a 300MB install.
“I use tcpdump to capture and Wireshark to analyze.” Now you get it. That’s the right workflow. tcpdump captures on the server where the problem is. Wireshark analyzes on your machine where you have a screen. They’re not competitors — they’re a team.
tcpdump cheat sheet
You made it. Or you skipped straight here. Either way, no judgment. Copy and paste these. Pin them. Tattoo them on your forearm. Whatever works.
| What you’re doing | Command |
|---|---|
| List interfaces | sudo tcpdump -D |
| Capture on an interface | sudo tcpdump -i eth0 -n |
| Filter by host | sudo tcpdump -n host 10.0.0.5 |
| Filter by port | sudo tcpdump -n port 443 |
| Filter by protocol | sudo tcpdump -n tcp |
| Combine filters | sudo tcpdump -n 'host 10.0.0.5 and port 80' |
| Exclude your SSH session | sudo tcpdump -n not port 22 |
| Show packet ASCII payload | sudo tcpdump -n -A port 80 |
| Verbose with timestamps | sudo tcpdump -n -vv -tttt port 443 |
| Save to pcap file | sudo tcpdump -n -w capture.pcap host 10.0.0.5 |
| Stop after 100 packets | sudo tcpdump -n -c 100 -w capture.pcap |
| Read a pcap file | tcpdump -n -r capture.pcap |
| Filter a pcap file | tcpdump -n -r capture.pcap port 443 |
The one flag:
-n— always use it. Without it, tcpdump resolves every IP to a hostname, which is slow, noisy, and never helpful when you’re debugging.