Intro
Tcpdump is the Swiss Army knife of packet capture. It’s lean, scriptable, and ships with almost every Unix-like system. That makes it ideal for automation, troubleshooting, or handing to a customer when you need a reproducible capture without walking them through a GUI.
Most people analyze captures in Wireshark, the premiere open-source packet analyzer. But tcpdump is often the better tool for collecting the data in the first place: it can be scripted, shared as a one-liner, and run with minimal instructions. That workflow — capture with tcpdump, analyze with Wireshark — is a staple in real-world troubleshooting.
Packet captures are rarely trivial: they’re big, messy, and not something you want to redo needlessly. The goal is to get it right the first time — a clean, useful trace containing the data you need that you can hand off to Wireshark or another analyst. This survival guide shows the commands you need to do just that.

Photo: Ave Maria / Jonas, via Wikimedia Commons, CC BY 2.0
Where to Capture?
Before worrying about command flags, it helps to think about point of view. Packet captures are always relative — what you see depends on where you’re listening from.
If you’re debugging a client/server exchange, you could capture on the client to confirm whether requests are leaving, or on the server to see if they arrive. Sometimes you need both perspectives: one to prove the client sent the packet, the other to prove the server received (or didn’t).
The network itself matters too. On a flat LAN or broadcast domain, a capture may show you traffic between many hosts. But on a switched or routed network, you’ll only see packets destined to or from the machine you’re capturing on. That’s why capturing on the endpoint itself is often the simplest, most reliable approach.
For complex problems, it’s common to gather multiple captures — one at the client, one at the server, maybe another at a key router or firewall. When you line them up by timestamp, you can follow the packet’s journey across the path and pinpoint where things break down.
Capturing With Purpose
Before you even start tcpdump, think about the flow: set up the capture, reproduce the issue, then stop and analyze. The most useful captures are the ones where you already know what you were testing and when.
When possible, note the time that certain events happen (“clicked Connect at 14:03:12”, “login failed around 14:05”). Even better, jot down exactly what you did while the capture was running. Those notes become anchors when you later scroll through packets in Wireshark.
It’s tempting to just run tcpdump for hours and fish around afterwards, but that usually leaves you with a mountain of noise. A focused capture is faster to analyze and less likely to miss the moment you care about. Sometimes you know the exact traffic you want (say, HTTPS to a specific host). Other times you don’t — and that’s fine. Even then, try to reproduce the problem cleanly and capture just long enough to get the exchange you’re after.
The key idea: minimum noise, maximum relevance. The cleaner your capture, the easier your analysis.
Gathering a Solid Capture
Now that you’ve thought about where to capture and how to focus your test, the next step is setting up tcpdump to record everything you need without losing detail. The essentials boil down to three things: interface, scope, and output. We’ll get deeper into interface choices in the next section — for now, let’s focus on how to record a solid trace.
Save to a File
For later analysis in Wireshark or another tool, always write to a .pcap
:
sudo tcpdump -i eth0 -s 0 -w capture.pcap
-s 0
→ capture the entire packet, not just the default snap length.-w
→ write raw packets to a file (not human-readable).- Use
Ctrl+C
to stop when you’ve got enough.
Quick Checks
Sometimes you only need a small slice:
sudo tcpdump -i eth0 -s 0 -c 500 -w sample.pcap
-c
stops after N packets.- Great for reproducible test runs.
Reading It Back
To verify or skim without Wireshark:
tcpdump -r capture.pcap
Pro Tips
- Always run with
sudo
(or root). - Watch disk space — captures grow quickly.
- Sync system clocks if possible (NTP helps line up multi-host captures).
- Time matters: make sure your system clock is accurate for useful logs.
Now that you know the essential flags for capturing, you need to point tcpdump at the right place to listen. Modern systems have multiple network interfaces, and choosing the wrong one means capturing nothing useful.
Choosing the Right Interface
Once you know where you want to capture, the next step is picking the right network interface. Modern systems almost always have more than one: a wired port, one or more wireless adapters, VPN tunnels, virtual interfaces created by containers, or diagnostic interfaces used for special cases like mobile devices. Tcpdump needs to know exactly which one to listen on.
List available interfaces with:
tcpdump -D
You’ll see numbered entries such as:
- Linux:
eth0
,ens33
,wlan0
,lo
(loopback),docker0
,tun0
(VPN),vethXYZ
(containers) - macOS:
en0
(Ethernet or Wi-Fi),en1
,lo0
(loopback),utunX
(VPN),bridge0
,rvi0
(iOS Remote Virtual Interface) - Windows (via WSL or WinDump):
Ethernet
,Wi-Fi
,Local Area Connection
, plus GUID-style names for virtual adapters
Which Ones Matter?
- Ethernet / Wi-Fi (
eth0
,ens33
,en0
,wlan0
) → Most common capture points for client or server traffic. - Loopback (
lo
,lo0
) → Useful if you’re testing services that talk to themselves onlocalhost
. - VPN (
tun0
,utunX
) → Captures encrypted tunnel traffic; sometimes useful for debugging, but you won’t see the inner payloads unless you capture on the endpoint before encryption. - Docker / Container Bridges (
docker0
,vethXYZ
,cniXYZ
) → Capture container-to-container traffic. Handy in Kubernetes/Docker debugging. - Mobile Debugging (
rvi0
for iOS,any
for Android) → Special cases we’ll cover in detail below. - Others (bridges, virtual adapters, hypervisor links) → Usually less relevant unless you’re debugging virtualization or complex network topologies.
The key point: capture on the interface where the traffic of interest actually flows. Choose wrong, and you’ll end up with an empty file or irrelevant chatter.
Capturing Mobile Traffic
One of tcpdump’s neat tricks is that you can capture traffic from mobile devices without exotic hardware taps. Both iOS and Android expose interfaces that tcpdump can hook into from your computer. In both cases you’ll need the device plugged in with a USB cable.
iOS (macOS host required)
On macOS, Apple provides a Remote Virtual Interface (RVI) that exposes iPhone or iPad network traffic over USB. The device must be unlocked and you’ll need to tap Trust this computer the first time you connect. Once enabled, the phone appears as a virtual interface (rvi0
) that you can capture from with tcpdump.
The only catch: you need the device’s UDID (Unique Device Identifier). You can get it a few ways:
-
System Profiler (built-in):
Plug in your device, then run:system_profiler SPUSBDataType | grep -w "Serial Number"
This prints the serial numbers of connected USB devices. For iPhones and iPads, that string is the UDID.
-
libimobiledevice (third-party tools):
If you have libimobiledevice installed, you can run:idevice_id -l
which lists all connected iOS devices by UDID.
Pro-Tip If you’re handing instructions to someone else, you can make it a one-liner:
rvictl -s $(system_profiler SPUSBDataType | awk '/Serial Number/{print $3; exit}')
That command automatically grabs the first iOS device’s UDID and passes it to rvictl
.
Once the RVI is active, check with:
rvictl -l
When finished, tear it down with:
rvictl -x <device-udid>
At that point, rvi0
behaves like any other interface. You can capture traffic from it just like you would on Ethernet or Wi-Fi:
sudo tcpdump -i rvi0 -s 0 -w iphone.pcap
This gives you a complete packet trace of the phone’s traffic — Wi-Fi, cellular, or both — without needing a special router or access point. It’s one of the most useful tricks for debugging mobile apps in the field.
Android (USB required)
Android doesn’t expose an RVI, but you can capture traffic via the Android Debug Bridge (adb). Your phone must be plugged in over USB with USB debugging enabled. On many devices this works out of the box, but some builds require a tcpdump binary installed on the phone and root privileges to run it.
- macOS:
brew install android-platform-tools
- Debian/Ubuntu:
sudo apt install android-tools-adb
- Fedora:
sudo dnf install android-tools
- Windows:
Download Android Platform Tools from Google.
With adb installed and your phone connected by USB (with USB debugging enabled), verify the device is detected:
adb devices
You may need to accept a prompt on the phone.
From there, you have two approaches:
-
Capture directly on the device:
adb shell tcpdump -i any -s 0 -w /sdcard/capture.pcap adb pull /sdcard/capture.pcap
This writes a
.pcap
file to the device and then pulls it back to your computer. -
Stream packets live to your desktop:
adb exec-out tcpdump -i any -s 0 -w - > android.pcap
This writes the capture directly to your computer, which is often simpler for real-time analysis in Wireshark.
Whichever method you use, the result is the same: a .pcap
file containing app traffic over Wi-Fi and cellular, ready to open in Wireshark.
Filtering for Relevance
Captures get big quickly. A focused filter saves disk space, cuts noise, and makes analysis much easier. Tcpdump uses the Berkeley Packet Filter (BPF) syntax, which is simple once you know a few basics.
In practice, you’ll usually want to capture full packets and write them to a file for later analysis in Wireshark. For example:
sudo tcpdump -i eth0 -s 0 -w capture.pcap 'tcp port 443 and host example.com'
-s 0
→ capture the entire packet-w capture.pcap
→ write to a file instead of printing to the screen- Filter expression in quotes → what traffic to capture
For the examples below, we’ll omit the -s 0 -w ...
parts to keep things short, but remember to include them when you’re running a real capture.
Common Filters
# Host-based
tcpdump host 192.168.1.50
tcpdump src host 10.0.0.5
tcpdump dst host example.com
# Port-based
tcpdump port 80
tcpdump tcp port 443
# Protocol
tcpdump icmp
tcpdump arp
tcpdump udp
Practical Filtering Recipes
# DNS traffic only
tcpdump -i eth0 port 53
# HTTP traffic to a specific host
tcpdump -i eth0 tcp port 80 and host example.com
# HTTPS traffic to a specific host
tcpdump -i eth0 tcp port 443 and host 203.0.113.42
# All web traffic (HTTP + HTTPS) from one client
tcpdump -i eth0 host 192.168.1.25 and \( port 80 or port 443 \)
# Capture traffic in a subnet
tcpdump net 192.168.1.0/24
# Capture all but one noisy host
tcpdump not host 192.168.1.10
# SSH traffic to or from a specific server
tcpdump tcp port 22 and host bastion.example.com
# ICMP (pings) except from a certain host
tcpdump icmp and not src host 10.0.0.5
# Multiple conditions: HTTPS to a subnet, but ignore one host
tcpdump tcp port 443 and net 10.0.0.0/24 and not host 10.0.0.50
Tips
- Use parentheses
()
when combining multiple expressions (escape them in shells with\(
\)
). - Add
-n
to prevent tcpdump from resolving hostnames (faster, less noise). - Increase detail with
-v
,-vv
, or-vvv
when reviewing packets live. - Filters in tcpdump (BPF) are not the same as Wireshark display filters — capture filters decide what packets are saved, while display filters decide what you see later.
Links & Stuff
Essential Documentation:
Further Reading:
- Tcpdump Zine by Julia Evans — a fun, visual guide that complements this article.
- Packet Life Cheat Sheets — quick reference sheets for tcpdump, Wireshark, and more.
Conclusion
Tcpdump isn’t flashy, but it’s indispensable. With just a few commands you can capture clean, useful packet traces that save hours of guesswork. Think about where to capture, plan your test, write to a file, and use filters to cut noise. Do it right once, and you won’t have to ask your customer to redo it.
This guide covered the essentials — enough to get you started, hand off captures, and debug issues with confidence. In a follow-up, we’ll dive into analysis and advanced tricks: tshark
, Wireshark filtering, ring buffer captures, and boot-time monitoring.
As always, if you found this post useful or if you have questions, I’d love to hear from you: feedback@adminjitsu.com
Happy packet hunting ✨