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.
“请注意,expression 中遇到的第一个 vlan 关键字会改变 expression 其余部分的解码偏移量> 假设数据包是 VLAN 数据包。”在这里很重要。
这意味着vlan 和其他过滤器的顺序很重要。
所以:
如果我通过(protocol_filter 和 vlan_filter),我看不到任何数据包
这是因为“protocol_filter”是基于数据包不是 VLAN数据包的假设进行评估的;通过该过滤器的任何内容都不是 VLAN 数据包,因此“vlan_filter”失败。
但是如果我把 exp 换成(vlan_filter 和 protocol_filter),那么包过滤就可以了
这是因为“vlan_filter”检查 VLAN 数据包并且改变了所有后续测试的完成方式,因此他们假设数据包是一个 VLAN 数据包; “protocol_filter”的评估基于数据包是一个 VLAN 数据包的假设。
如果我包含带有“not”协议的 vlan,我会收到应用了协议过滤器的数据包:例如:(((vlan 20)) and (not (udp port 3800)) and ((not (tcp)) and (not (udp port 53)) and (not (icmp)) and (not (ip6)) and (not (udp port 5353))))
该过滤器将仅匹配 VLAN 数据包,如果数据包用于 VLAN 20,那么它将在假设数据包是 VLAN 数据包的情况下执行所有其他检查 - 例如,如果您正在捕获带有以太网标头的数据包,并且您正在检查 IPv4 或 IPv6,其他检查将查看以太网类型的偏移量为 16,而不是 12。
如果我没有在协议中包含 vlan,当 bpf 为:(not (udp port 3800)) and ((not (tcp)) and (not (udp port 53) ) and (not (icmp)) and (not (ip6)) and (not (udp port 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 的检查不匹配。因此,“不”过滤器做匹配。
这里的错误是 UDP 数据包进出 3800 端口 是 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 port 5353)))) 获取所有数据包,包括ip6、tcp等
这是另一个 libpcap 错误 - 正如以太网上的“vlan”会导致所有后续测试在 VLAN 标头之后查看以太网类型字段,“非 vlan”也是如此。但是“not vlan”是错误的,因为如果匹配,数据包不是 VLAN数据包,所以没有没有VLAN头!
(((not vlan)) and (not (udp port 3800)) and (((tcp)) or ((udp port 53)) or ((icmp)) or ((ip6)) or ((udp端口 5353)))) 甚至没有收到单个数据包
同样的问题。
libpcap/WinPcap 的错误可能容易修复,但有时间我会看看它们。