The most surprising thing about tcpdump is that it fundamentally operates at the packet level, and filtering bidirectional traffic between two hosts isn’t about "seeing both sides" as much as it is about intelligently selecting which packets represent that bidirectional conversation.
Let’s see it in action. Imagine we have hostA at 192.168.1.10 and hostB at 192.168.1.20. We want to capture all traffic flowing between them.
First, a basic capture on hostA interface eth0:
sudo tcpdump -i eth0 -w capture.pcap
This will capture everything on eth0. Now, let’s filter for traffic to hostB:
sudo tcpdump -i eth0 host 192.168.1.20 -w capture_to_b.pcap
And for traffic from hostB (which will also be to hostA on this interface):
sudo tcpdump -i eth0 src host 192.168.1.20 -w capture_from_b.pcap
To get both directions on hostA, we combine these:
sudo tcpdump -i eth0 'host 192.168.1.20' -w capture_bidirectional_a.pcap
The host 192.168.1.20 filter is shorthand for (src host 192.168.1.20) or (dst host 192.168.1.20). This is key: on a single host’s interface, a packet is either coming from or going to another host. So, filtering for host X on hostA’s interface captures all packets where hostA is either the source or the destination relative to hostX.
However, if you are running tcpdump on a switch or a device that sees traffic passing through and not originating or terminating there, you need to be more explicit. Let’s say you’re on a router interface eth1 that connects to hostA, and eth2 connects to hostB.
To see traffic from hostA to hostB:
sudo tcpdump -i eth1 'dst host 192.168.1.20' -w a_to_b_via_router.pcap
And to see traffic from hostB to hostA:
sudo tcpdump -i eth2 'dst host 192.168.1.10' -w b_to_a_via_router.pcap
To get a single capture file representing the bidirectional flow as seen by the router, you’d typically capture on both interfaces and then merge, or run two separate captures and analyze them side-by-side. A more advanced technique is to use a capture device that can mirror traffic from both sides onto a single interface, or to use network taps.
But if you’re on one of the hosts, say hostA, and want to capture all traffic between hostA and hostB, the simple host 192.168.1.20 filter is all you need.
The mental model here is understanding network interfaces and packet direction. On hostA, eth0 receives packets. If a packet’s source IP is 192.168.1.20, it’s coming from hostB. If its destination IP is 192.168.1.20, it’s going to hostB. The host filter in tcpdump is a logical OR of these two conditions.
The -w flag writes to a file, which is essential for later analysis with tools like Wireshark. The -i flag specifies the interface. Without -i, tcpdump will often pick a default, but it’s best practice to be explicit.
Consider the case of a firewall or NAT device. If hostA is behind a NAT gateway and hostB is external, hostA’s IP might change as seen by hostB. In such scenarios, capturing on hostA will show its internal IP, while capturing on the gateway will show the external IP. Filtering for the internal IP on hostA will capture its outbound packets (destined for hostB’s public IP, but tcpdump on hostA only sees the final destination IP) and its inbound packets (source hostB’s public IP, but tcpdump on hostA only sees the source IP hostB used). The crucial point is that tcpdump on hostA sees the IPs as they appear on that host’s network stack.
When you use tcpdump on one host (say hostA) and filter for host B, you are capturing packets where hostA is either the source or the destination. This effectively shows you all the packets that hostA is sending to hostB and all the packets that hostA is receiving from hostB. The trick is that on hostA’s interface, the packets originating from hostB will have hostB as the source IP, and the packets destined for hostB will have hostB as the destination IP. The host keyword in tcpdump is a convenient shorthand for src host B or dst host B.
The next common problem is understanding how to filter by port numbers in conjunction with hosts, for example, to isolate a specific application’s communication.