Tcpdump BPF 语法歧义

Tcpdump BPF syntax ambiguity

在 tcpdump/libpcap 语法中观察这些 BPF 过滤器行:

1: not host x or host y
2: not (host x or host y)
3: not (host x or y)
4: not host x or y
5: (not host x) or host y
6: (not host x) or y

我认为主机 z 符合以上所有条件(6 除外,因为它的语法无效)。 我的问题出在第 4 行。tcpdump 程序将其视为等同于第 5 行,但我认为这不直观,因此也不正确。 第 5 行和第 3 行一样明确。但是,第 4 行可能意味着这两种情况,具体取决于您如何看待事物。我的观点是,因为您无法从 "host" 关键字中单独看到 y,所以将第 4 行视为第 5 行是错误的。

这背后的解析逻辑是什么?谁能解释为什么 1 == 4 == 5 和为什么 2 != 4 和 3 != 4 ?

"I think that is not intuitive and therefore not correct."

也许吧。但往往直觉是仁者见仁智者见智,精确的规范总是比 "the parser does the intuitive thing" 更有用。 (我想除非你喜欢 Perl。但是你需要正确的直觉。)

话虽如此,我找不到 pcap 语法的精确规范,但 man pcap-filter 确实解释了如何在原语与布尔运算符的组合中消除表达式的歧义:

Negation has highest precedence. Alternation and concatenation have equal precedence and associate left to right.

许多原语由关键字和标识符组成,但关键字可以省略:

If an identifier is given without a keyword, the most recent keyword is assumed.

这对分组没有影响。插入省略的关键字而不更改解析。该示例清楚地说明了这一点:

For example,
not host vs and ace
is short for
not host vs and host ace
which should not be confused with
not ( host vs or ace )

描述中没有真正说清楚的是你的例子6是语法错误的原因,即解析是在括号内递归执行的,因此括号表达式内的关键字不会改变"the most recent keyword".