wiresharktcpdumpvxlan

How can I capture Gre or Vxlan inner network traffic?


I want to capture some network traffic with the filter like "src x.x.x.x and dst x.x.x.x".

Ususally it works, but it doesn't work when the network traffic is encapsulated by protocls like Gre or Vxlan.

For example, the Gre encapsulate a message like this:

Ethernet II, Src: VMware_91:f6:ad (00:0c:29:91:f6:ad), Dst: VMware_dc:c7:71 (00:0c:29:dc:c7:71)
Internet Protocol Version 4, Src: 10.75.2.161, Dst: 10.75.2.140
Generic Routing Encapsulation (Transparent Ethernet bridging)
Ethernet II, Src: Micro-St_e3:51:57 (4c:cc:6a:e3:51:57), Dst: VMware_91:f6:ad (00:0c:29:91:f6:ad)
Internet Protocol Version 4, Src: 10.75.2.11, Dst: 10.75.2.160

So what should I do to capture those inner traffic?

I use "src 10.75.2.160" to capture but it tcpdump captured nothing.

tcpdump -i eth0 "src 10.75.2.11"

It doesn't work.

I use "ip[54:4]" to capture, it works, but my leader tell me it's not accurate.

So what else can I try?


Solution

  • I don't know how accurate your leader wants the filter, but if we can make a few assumptions about the outer IP and GRE headers, then the filter isn't too complicated. So here are the 2 assumptions:

    With those assumptions out of the way, here's a filter that would be the equivalent of "src 10.75.2.11" but for the inner source IP address of a IP/GRE/IP packet:

    (ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b0x0b)
    

    Explanation:

    To verify the resulting BPF code, you can run tcpdump with the -d option to check that the filter meets your expectations, for example:

    tcpdump -i eth0 "(ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b020b)"
    

    You should see output of the following form:

    (000) ldh      [12]
    (001) jeq      #0x800           jt 2    jf 9
    (002) ldb      [23]
    (003) jeq      #0x2f            jt 4    jf 9
    (004) ldh      [36]
    (005) jeq      #0x800           jt 6    jf 9
    (006) ld       [50]
    (007) jeq      #0xa4b020b       jt 8    jf 9
    (008) ret      #262144
    (009) ret      #0
    

    If you're not familiar with BPF code, then I would suggest further reading elsewhere, as providing a BPF tutorial here is beyond the scope of this answer.

    Finally, if you need to filter for the source IP address whether it's in the outer IP header or the inner IP header, then you can basically just combine the 2 filters, i.e.:

    "(ip src 10.75.2.11) || ((ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b020b))"