逻辑组合在做什么
BPF 表达式用 and 与 &&、or 与 ||、not 与 ! 把多个条件连起来,也可以用括号分组。优先级上 and 高于 or,所以 a or b and c 会按 a or (b and c) 解析,这一点与直觉不符,组合条件时必须显式加括号。另一个高频问题是引号:括号与竖线在 shell 里有特殊含义,整个表达式要用单引号包住,否则会被 shell 提前拆解成完全不同的命令。
基本信息
| 与 | and 或 &&,两个条件都成立 |
|---|---|
| 或 | or 或 ||,任一条件成立 |
| 非 | not 或 !,条件取反 |
| 分组 | 用小括号,必须写在引号内 |
| 优先级 | not 高于 and,and 高于 or |
| 引用要求 | 含括号或竖线的表达式整体用单引号包住 |
典型使用场景
- 组合主机与端口:只看某台客户端访问某个服务
- 一次覆盖多个端口:port 80 or port 443,减少重复抓包
- 排除干扰协议:not (arp or icmp) 让输出只剩业务流量
- 描述两台设备之间的通话:host A and host B
- 排除某个来源:host 10.0.0.9 and not host 10.0.0.5
- 交叉条件排查:某网段发往某网段且特定端口
常用示例
常用示例
tcpdump -i eth0 -nn 'host 10.0.0.9 and (port 80 or port 443)' # 主机加多端口
tcpdump -i eth0 -nn 'tcp and not port 22' # 排除管理端口
tcpdump -i eth0 -nn 'not (arp or icmp)' # 排除两类协议
tcpdump -i eth0 -nn 'host 10.0.0.9 and host 10.0.0.10' # 两点之间
tcpdump -i eth0 -nn '(dst port 443 or dst port 8443) and host 10.0.0.9' # 双向条件
tcpdump -i eth0 -nn 'net 10.10.0.0/16 and not net 10.10.1.0/24' # 网段减去子段优先级与写法
| 写法 | 解析结果 | 说明 |
|---|---|---|
| a or b and c | a or (b and c) | and 优先,容易与预期不符 |
| (a or b) and c | 先求或再求与 | 用括号明确意图,读起来也清楚 |
| not a and b | (not a) and b | not 优先级最高 |
| not (a or b) | 两项都不成立 | 排除法最常用的形式 |
| a and not b | 满足 a 同时不满足 b | 排除特定来源的标准写法 |
| a or b or c | 任一成立 | 多端口、多主机并列时的写法 |
括号与竖线必须用单引号保护。不写引号时 shell 会把括号当成子命令、把竖线当成管道,命令会以完全不同的方式执行,甚至出现莫名其妙的语法错误。
排除法很适合缩小视野:先抓全量看清有哪些流量,再用 not 去掉已知噪音。代价是要确认排除项不会误伤目标流量,尤其是协议级别的排除。
判读要点
- 条件越多越要先验证命中量级,从小样本开始逐步加条件
- 排除条件写错时结果为空,容易误判成没有流量,建议先去掉排除项对比一次
- 同一原语重复出现可以合并,例如 port 80 or port 443 比写两次更短
- 括号写完要检查是否成对,缺一个右括号通常表现为整条命令报错