0

使用 libpcap pcap_compile 时出现一些奇怪的错误如果这些是已知问题,或者我正在犯一些 bpf 格式/排序错误,请告诉我

例如:

1)如果我通过(protocol_filter 和 vlan_filter),我看不到数据包:像((arp 或 udp 端口​​ 234)和 vlan 12)但是如果我将 exp 交换为(vlan_filter 和 protocol_filter),那么数据包过滤工作:像((vlan 12) 和 (arp 或 udp 端口​​ 234))

2)如果我包含带有“not”协议的vlan,我会得到应用了协议过滤器的数据包:例如:(((vlan 20))和(not(udp端口3800))和((not(tcp))和(not( udp 端口​​ 53)) 和 (not (icmp)) 和 (not (ip6)) 和 (not (udp port 5353))))

如果我没有在协议中包含 vlan,当 bpf 为:(not (udp port 3800)) and ((not (tcp)) and (not (udp port 53)) and (不是(icmp))和(不是(ip6))和(不是(udp端口5353))))

3)(((not vlan)) and (not (udp port 3800)) and ((not (tcp)) and (not (udp port 53)) and (not (icmp)) and (not (ip6)) and (not (udp port 5353)))) 获取所有数据包,包括 ip6、tcp 等

(((not vlan)) and (not (udp port 3800)) and (((tcp)) or ((udp port 53)) or ((icmp)) or ((ip6)) or ((udp port 5353) ))) 甚至没有得到单个数据包

4

1 回答 1

2

vlan很奇怪。

引用 pcap-filter 手册页:

   vlan [vlan_id]
          True if the packet is an IEEE 802.1Q VLAN packet.  If  [vlan_id]
          is specified, only true if the packet has the specified vlan_id.
          Note that the  first  vlan  keyword  encountered  in  expression
          changes  the decoding offsets for the remainder of expression on
          the assumption that the packet  is  a  VLAN  packet.   The  vlan
          [vlan_id]  expression  may  be used more than once, to filter on
          VLAN hierarchies.  Each use of that  expression  increments  the
          filter offsets by 4.

          For example:
               vlan 100 && vlan 200
          filters on VLAN 200 encapsulated within VLAN 100, and
               vlan && vlan 300 && ip
          filters  IPv4  protocols  encapsulated  in VLAN 300 encapsulated
          within any higher order VLAN.

“请注意,表达式中遇到的第一个vlan关键字会在假设数据包是 VLAN 数据包的情况下更改表达式其余部分的解码偏移量。” 在这里很重要。

这意味着过滤器和其他过滤器的顺序vlan很重要。

所以:

如果我通过(protocol_filter 和 vlan_filter),我看不到任何数据包

这是因为“protocol_filter”是基于数据包不是VLAN 数据包的假设进行评估的;通过该过滤器的任何内容都不是 VLAN 数据包,因此“vlan_filter”失败。

但是如果我将 exp 交换为(vlan_filter 和 protocol_filter),那么包过滤就可以了

这是因为“vlan_filter”会检查 VLAN 数据包改变所有后续测试的完成方式,因此它们会假定数据包VLAN 数据包;“protocol_filter”的评估基于数据包是VLAN 数据包的假设。

如果我包含带有“非”协议的 vlan,我会得到应用了协议过滤器的数据包:例如:(((vlan 20)) 和 (not (udp 端口​​ 3800)) 和 ((not (tcp)) 和 (not (udp 端口53))和(非(icmp))和(非(ip6))和(非(udp端口5353))))

该过滤器将仅匹配 VLAN 数据包,如果数据包用于 VLAN 20,它将在假设数据包是 VLAN 数据包的情况下执行所有其他检查 - 例如,如果您正在捕获带有以太网标头的数据包,并且您正在检查 IPv4 或 IPv6,其他检查将查看以太网类型的偏移量 16,而不是 12。

如果我没有在协议中包含 vlan,当 bpf 为:(not (udp port 3800)) and ((not (tcp)) and (not (udp port 53)) and (不是(icmp))和(不是(ip6))和(不是(udp端口5353))))

这有点令人困惑,可以说这是 libpcap 中的一个错误。

“udp 端口​​ 3800”首先检查“这是 IPv4 还是 IPv6”,这在以太网上是通过检查以太网类型/长度字段的值是否为 IPv6 的 0x0800 或 IPv6 的 0x86dd 来完成的。如果与 IPv4 匹配,它会检查 IPv4 协议字段以查看它是否是 UDP;如果它与 IPv6 匹配,它会检查 IPv6 下一个标头字段以查看它是否是 UDP。如果是 UDP,则检查源端口号和目标端口号,看是否有一个是 3800;如果是,则数据包匹配,否则不匹配。

“not (udp port 3800)” 执行相同的检查,除了如果任何测试不匹配,则数据包匹配,如果任何测试匹配,数据包匹配。

VLAN 数据包的以太网类型/长度字段中有 0x8100,因此 IPv4 和 IPv6 的检查不匹配。因此,“不”过滤器确实匹配。

此处的错误是,与端口 3800 之间的 UDP 数据包IPv4 或 IPv6 数据包;如果它在 VLAN 上,它只是不会碰巧在以太网上从数据包的开头偏移 12 处有 0x0800 或 0x86dd,它有 0x8100。

(((not vlan)) and (not (udp port 3800)) and ((not (tcp)) and (not (udp port 53)) and (not (icmp)) and (not (ip6)) and (not (udp 端口​​ 5353)))) 获取所有数据包,包括 ip6、tcp 等

这是另一个 libpcap 错误 - 就像以太网上的“vlan”一样,会导致所有后续测试查看VLAN 标头之后的以太网类型字段,“not vlan”也是如此。但是“not vlan”是错误的,因为如果匹配,则数据包不是VLAN 数据包,因此没有VLAN 标头!

(((not vlan)) and (not (udp port 3800)) and (((tcp)) or ((udp port 53)) or ((icmp)) or ((ip6)) or ((udp port 5353) ))) 甚至没有得到单个数据包

同样的问题。

libpcap/WinPcap 的错误可能不容易修复,但我会在有时间的时候查看它们。

于 2015-07-01T19:12:25.857 回答