blackdronzer
blackdronzer

Reputation: 39

inspect inner geneve packet using tcpdump

I want to put filters on inner packets encapsulated by geneve.

If I put a filter like

tcpdump -vnn udp -i eth0

It filters all geneve packets as the header above geneve is udp.

How to filter the packets which are inside geneve which has proto field set to udp?

Upvotes: 1

Views: 2782

Answers (1)

Christopher Maynard
Christopher Maynard

Reputation: 6294

I managed to find a sample capture file online that contains Geneve traffic. It's the geneve.pcap file available at Cloudshark.

I download this file and modified one of the packets so the inner encapsulated protocol was UDP instead of ICMP. I was then able to come up with a capture filter to isolate that packet while testing with tcpdump. Here's the command with capture filter that I used to test this:

tcpdump -r geneve_udp.pcap "(udp port 6081) and (udp[10:2] = 0x6558) and (udp[(8 + (4 * (2 + (udp[8:1] & 0x3f))) + 12):2] = 0x0800) and (udp[8 + (4 * (2 + (udp[8:1] & 0x3f))) + 14 + 9:1] = 17)"

Explanation of the capture filter:

  • udp port 6081: This part just filters for Geneve packets, as identified by the UDP port number.
  • udp[10:2] = 0x6558: This part filters for Geneve packets with a Protocol Type of "Transparent Ethernet bridging".
  • udp[(8 + (4 * (2 + (udp[8:1] & 0x3f))) + 12):2] = 0x0800: This somewhat complicated part filters for encapsulated Ethernet frames having an Ethertype of 0x0800 (IPv4). It does this by:
    • Skipping the 8 bytes of the UDP header itself.
    • Skipping the Geneve Header, which is 8 bytes plus 4 times the Opt Len, which we must isolate from the byte because this field is only contained within the lower 6 bits.
    • Skipping to the Ethertype field of the encapsulated Ethernet header.
    • And finally comparing the 2-byte value found there to the IPv4-assigned Ethertype of 0x0800.
  • udp[8 + (4 * (2 + (udp[8:1] & 0x3f))) + 14 + 9:1] = 17: This somewhat complicated part filters for encapsulated IPv4 headers having a Protocol field as 17 (UDP). It does this by:
    • Skipping the 8 bytes of the UDP header itself.
    • Skipping the Geneve Header, which is 8 bytes plus 4 times the Opt Len, which we must isolate from the byte because this field is only contained within the lower 6 bits.
    • Skipping the 14 bytes of the encapsulated Ethernet header.
    • Skipping the 1st 9 bytes of the encapsulated IP header to get to the proper offset of the IPv4 Protocol field.
    • And finally comparing the value of that field with the UDP-assigned protocol value of 17.

If the Geneve protocol encapsulates UDP within IPv6 instead of IPv4, then you'll have to modify the capture filter accordingly.

NOTE: I'm not sure if I should just delete my original answer or not? For now, I'll just leave it below ...


I'm not familiar with this Geneve protocol, nor do I have any capture files to test with, but you should be able to use the slice operator (i.e., []) if you know the offset to the field containing the desired value indicating that the inner protocol is UDP.

For illustrative purposes, I'll assume that if the Protocol Type field of the Geneve Header contains the value 17, then this indicates an encapsulated UDP packet. Assuming this is correct, then a filters such as follows may help:

"udp[10:2] = 17" 

This filter compares the 2 bytes at offset 10 of the UDP data to the value of 17, which as I understand it, is the location of the Protocol Type field of the Geneve Header. You'll obviously need to adjust the offset if this assumption or my understanding of the protocol isn't correct.

Refer to the pcap-filter man page for more help on the capture filter syntax.

Upvotes: 2

Related Questions