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 的错误可能不容易修复,但我会在有时间的时候查看它们。