How can I use complex filters by protocol in tcpdump?

I can filter by lots of protocols in wireshark and tshark, like this:

sudo tshark -i <My_Interface> -Y '(ip.addr == <My_IP> and isakmp)'

How can I add the protocol filter in a tcpdump command like this?

sudo tcpdump -i any -nn host <My_IP>


Solution 1:

You would use filters on the end. These are called Berklee Packet Filters or BPFs for short. In your example, you could do it this way:

tcpdump -nn -vvv -e -s 0 -X -c 100 -i eth0 host 1.2.3.4 and \(proto 17 and port 500\)

This would capture traffic to or from 1.2.3.4 with Layer-3 protocol 17 (UDP) and Layer-4 port 500. You can also use friendly names if they are present in /etc/protocols and /etc/services like this:

host 1.2.3.4 and \(proto udp and port isakmp\)

There are quite a lot more BPFs you can use to limit things like protocol versions to only capture IPv6 (ip6) or capture traffic that has the SYN flag set in a TCP packet (tcp[tcpflags] == tcp-syn).

If you need a live tool, I've created https://tcpdump101.com which will let you build your tcpdump syntax and BPF so you can just copy and paste it. Hopefully it will help you out.