首页/网络/抓包与流量分析速查/tcpdump 逻辑组合与括号

tcpdump 逻辑组合与括号

用 and(&&)、or(||)、not(!)组合条件;括号需要用引号包住整个表达式传给 shell,避免被 shell 解释。

逻辑组合在做什么

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 ca or (b and c)and 优先,容易与预期不符
(a or b) and c先求或再求与用括号明确意图,读起来也清楚
not a and b(not a) and bnot 优先级最高
not (a or b)两项都不成立排除法最常用的形式
a and not b满足 a 同时不满足 b排除特定来源的标准写法
a or b or c任一成立多端口、多主机并列时的写法
括号与竖线必须用单引号保护。不写引号时 shell 会把括号当成子命令、把竖线当成管道,命令会以完全不同的方式执行,甚至出现莫名其妙的语法错误。
排除法很适合缩小视野:先抓全量看清有哪些流量,再用 not 去掉已知噪音。代价是要确认排除项不会误伤目标流量,尤其是协议级别的排除。

判读要点

  • 条件越多越要先验证命中量级,从小样本开始逐步加条件
  • 排除条件写错时结果为空,容易误判成没有流量,建议先去掉排除项对比一次
  • 同一原语重复出现可以合并,例如 port 80 or port 443 比写两次更短
  • 括号写完要检查是否成对,缺一个右括号通常表现为整条命令报错

易错点

  • and 优先级高于 or,混写不加括号会得到与预期不同的结果
  • 表达式未用引号包住时,括号与竖线会被 shell 解释,命令行为完全改变
  • 排除条件误伤目标流量会得到空结果,容易被误读为链路没有流量
  • 括号不配对时整条命令报语法错误,先数左右括号再排查表达式内容
  • 条件堆得过多时难以定位是哪一条写错,建议逐条添加并观察命中变化

数据来源与参考

  • man 8 pcap-filter(逻辑运算符与优先级)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌