使用tcpdump检查内部槽形数据包



我想在geneve封装的内部数据包上设置过滤器。

如果我放一个像这样的过滤器

tcpdump-vnn udp-i eth0

它过滤所有日内瓦数据包,因为日内瓦上面的头是udp。

如何过滤在proto字段设置为udp的geneve内的数据包?

我设法在网上找到了一个包含Geneve流量的示例捕获文件。这是Cloudshark上提供的geneve.pcap文件。

我下载了这个文件并修改了其中一个数据包,因此内部封装的协议是UDP而不是ICMP。然后,在使用tcpdump进行测试时,我能够想出一个捕获过滤器来隔离该数据包。这是我用来测试的带有捕获过滤器的命令:

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)"

捕获过滤器的说明:

  • udp port 6081:这部分只是过滤由UDP端口号标识的Geneve数据包
  • CCD_ 3:该部分过滤具有协议类型为"0"的Geneve分组;透明以太网桥接">
  • udp[(8 + (4 * (2 + (udp[8:1] & 0x3f))) + 12):2] = 0x0800:这个有点复杂的部分过滤以太网类型为0x0800(IPv4(的封装以太网帧。它通过以下方式实现:
    • 跳过UDP标头本身的8个字节
    • 跳过Geneve Header,它是8个字节加上Opt-Len的4倍,我们必须将其与字节隔离,因为此字段只包含在较低的6位中
    • 跳到封装的以太网标头的Ethertype字段
    • 最后将在那里找到的2字节值与IPv4分配的0x0800以太类型进行比较
  • udp[8 + (4 * (2 + (udp[8:1] & 0x3f))) + 14 + 9:1] = 17:这个有点复杂的部分过滤协议字段为17(UDP(的封装IPv4报头。它通过以下方式实现:
    • 跳过UDP标头本身的8个字节
    • 跳过Geneve Header,它是8个字节加上Opt-Len的4倍,我们必须将其与字节隔离,因为此字段只包含在较低的6位中
    • 正在跳过封装的以太网标头的14个字节
    • 跳过封装的IP标头的前9个字节,以获得IPv4协议字段的正确偏移量
    • 最后将该字段的值与UDP分配的协议值17进行比较

如果Geneve协议将UDP封装在IPv6而不是IPv4中,则必须相应地修改捕获筛选器。

注意:我不确定是否应该删除我的原始答案?现在,我就把它留在下面。。。


我不熟悉这个Geneve协议,也没有任何捕获文件可供测试,但如果您知道包含所需值的字段的偏移量,则应该能够使用切片运算符(即[](,该值指示内部协议为UDP。

为了便于说明,我假设Geneve Header的Protocol Type字段包含值17,则这表示封装的UDP数据包。假设这是正确的,那么下面这样的过滤器可能会有所帮助:

"udp[10:2] = 17" 

这个过滤器将UDP数据偏移量10处的2个字节与值17进行比较,据我所知,17是Geneve Header的Protocol Type字段的位置。如果这个假设或我对协议的理解不正确,你显然需要调整偏移量。

有关捕获筛选器语法的更多帮助,请参阅pcap筛选器手册页。

最新更新