tcpdump filter that excludes private ip traffic

For a generic filter to exclude all traffic in my dump that is between private IP address, I came up with the following:

sudo tcpdump -n '
(not
    (
        (src net 172.16.0.0/20 or src net 10.0.0.0/8 or src net 192.168.0.0/16)
    and
        (dst net 172.16.0.0/20 or dst net 10.0.0.0/8 or dst net 192.168.0.0/16)
    )
) and 
(not
    (
        (dst net 172.16.0.0/20 or dst net 10.0.0.0/8 or dst net 192.168.0.0/16)
    and
        (src net 172.16.0.0/20 or src net 10.0.0.0/8 or src net 192.168.0.0/16)    
    )
)' -w test2.dump

Seems pretty excessive, but it also seems to work, is this filter a lot longer than it needs to be and there is better way to express this logic, or is there anything wrong with the filter?


I'm running the built-in tcpdump 4.0.0 and libpcap 1.0.0 on Mac OS X v10.6.2 and it seems I can get away with this:

'not (src net (10 or 172.16/12 or 192.168/16) and dst net (10 or 172.16/12 or 192.168/16))'

I ran a couple quick tests that seemed to do what you're asking: traffic that was both to and from any RFC 1918 private address subnet was omitted, but all traffic where one or both endpoints had a public address was included.

Note that you had an error in your original filter for the 172.16 network. You had moved the subnet mask 4 bits in the wrong direction. 172.16 is actually a /12, not a /20 as you had written. That is, 172.16.0.0 - 172.31.255.255 are all RFC 1918 private addresses, whereas your filter was only catching 172.16.0.0 - 172.16.15.255.


Isn't your second block

(not
   (
        (dst net 172.16.0.0/20 or dst net 10.0.0.0/8 or dst net 192.168.0.0/16)
    and
        (src net 172.16.0.0/20 or src net 10.0.0.0/8 or src net 192.168.0.0/16)    
    )
)

the same as your first block, only reversed? I'd say that and is a symmetric operation, so it won't make a difference? (Meaning that you could just as well remove the second block.)