Filter tcpdump by IP: Hosts, Direction, Subnets, and Ports
When a packet capture is full of traffic you don't care about, narrow it with a **capture filter**. For an IP address, the key distinction is whether you want traffic in both directions, only packets from the address, or only packets going to it.
sudo tcpdump -nn -i eth0 'host 192.0.2.25'
This captures packets where `192.0.2.25` is either the source or destination. Replace the example address and interface with the ones relevant to your system.
## Start with the right interface
An IP filter only sees packets that reach the interface you selected. On Linux, list available capture interfaces with:
tcpdump -D
Then select the interface carrying the traffic with `-i`. If you're unsure which device to inspect, this guide to listing network interfaces on Linux explains how to identify them.
The options and the filter have separate jobs:
* `-i eth0` selects the interface.
* `-nn` keeps addresses and ports numeric instead of resolving names.
* `'host 192.0.2.25'` is the capture filter.
On many Linux systems, packet capture requires elevated privileges, which is why examples use `sudo`.
## Choose whether to match either direction or one side
Use `host` to match an address appearing as either endpoint. Add `src` or `dst` to restrict which side of the packet must contain it:
# Packets to or from the address
sudo tcpdump -nn -i eth0 'host 192.0.2.25'
# Packets sent by the address
sudo tcpdump -nn -i eth0 'src host 192.0.2.25'
# Packets sent to the address
sudo tcpdump -nn -i eth0 'dst host 192.0.2.25'
Direction is relative to the packet being observed. If you capture only `dst host 192.0.2.25`, a reply sent _from_ that address won't match. Start with `host` when you want to see both sides of a conversation; narrow to `src` or `dst` once you know which direction matters.
## Match a subnet instead of a single host
To capture traffic involving any address in a network, use `net` with CIDR notation:
sudo tcpdump -nn -i eth0 'net 192.0.2.0/24'
This matches packets whose source or destination belongs to `192.0.2.0/24`. Add a direction qualifier if you only want one side:
sudo tcpdump -nn -i eth0 'src net 192.0.2.0/24'
sudo tcpdump -nn -i eth0 'dst net 192.0.2.0/24'
Use a network address with the appropriate prefix length. For example, `192.0.2.0/24` represents addresses from `192.0.2.0` through `192.0.2.255`.
## Combine an IP filter with a port
Capture filters can combine conditions. Use `and` when both conditions must match, and quote the whole expression so your shell passes it to tcpdump as one argument:
sudo tcpdump -nn -i eth0 'host 192.0.2.25 and tcp port 443'
This matches TCP traffic involving the address when either TCP port is 443. To require traffic to be headed to the host, add a direction qualifier:
sudo tcpdump -nn -i eth0 'dst host 192.0.2.25 and tcp port 443'
You can also match either of two hosts. Parentheses make the intended grouping clear when combining `or` with `and`:
sudo tcpdump -nn -i eth0 '(host 192.0.2.25 or host 198.51.100.10) and tcp port 443'
Without clear grouping, a compound filter can match more traffic than intended. When a complicated expression behaves unexpectedly, simplify it or add parentheses to show which conditions belong together.
## IPv4 and IPv6
`host` can match an IPv4 or IPv6 address. Use `ip` or `ip6` when you want to explicitly restrict the expression to one address family:
sudo tcpdump -nn -i eth0 'ip and host 192.0.2.25'
sudo tcpdump -nn -i eth0 'ip6 and host 2001:db8::25'
An IPv4 filter won't match an IPv6 connection to the same service, or vice versa. If tcpdump rejects an expression, the supported filter syntax can depend on the local tcpdump/libpcap environment; check the local `pcap-filter` manual.
## If the capture shows nothing
Before broadening a filter, check the assumptions behind it:
1. **Interface:** Is the traffic visible on the interface selected with `-i`? Use `tcpdump -D` to see the available capture interfaces.
2. **Direction:** Did you use `src` or `dst` when you meant to capture both directions? Try `host ADDRESS` as a first check.
3. **Address and family:** Verify the address you expect to see, and whether the connection uses IPv4 or IPv6.
4. **Extra conditions:** Temporarily remove port or protocol requirements to see whether the IP match works on its own.
5. **Quoting and grouping:** Quote the entire expression and use parentheses around mixed `and`/`or` logic.
6. **Permissions:** Use elevated privileges when required by your system.
The examples here focus on Linux and Unix-like tcpdump environments. For a Windows packet-capture workflow, see options including WinDump and Pktmon.
The useful starting points are `host ADDRESS` for either direction, `src host ADDRESS` or `dst host ADDRESS` for one direction, and `net CIDR` for a subnet. Add port and protocol conditions only after confirming you're looking at the right interface and address family.
I originally published a more detailed version of this guide on the SSHFlow blog.
I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.