比较运算符在做什么
显示过滤器有一整套比较与逻辑运算符:等于可以写 == 或 eq,不等于写 != 或 ne,大小比较用 > gt、< lt、>= ge、<= le,字符串包含用 contains,正则匹配用 matches,集合判断用 in。逻辑连接用 and 与 &&、or 与 ||、not 与 !。真正的难点不在符号本身,而在字段类型:数值字段直接写数字,字符串字段要加双引号,字节序列用十六进制冒号分隔。类型写错时要么报语法错误,要么永远匹配不到。
基本信息
| 等于 | == 与 eq |
|---|---|
| 不等于 | != 与 ne |
| 大小比较 | > gt、< lt、>= ge、<= le |
| 逻辑 | and 与 &&、or 与 ||、not 与 ! |
| 字符串 | 必须加双引号,如 http.host == "api.example.com" |
| 集合与模糊 | in {a, b}、contains 子串、matches 正则 |
运算符速查
| 运算符 | 等价值 | 使用说明 | 示例 |
|---|---|---|---|
| == | eq | 数值或字符串精确相等 | tcp.port == 443 |
| != | ne | 不等于,常用于排除标志位 | tcp.flags.syn != 0 |
| >= 与 > | ge 与 gt | 数值区间判断 | http.response.code >= 500 |
| contains | 无 | 字符串或字节序列包含 | http.host contains "internal" |
| matches | 无 | PCRE 风格正则匹配 | http.user_agent matches "(?i)curl" |
| in | 无 | 集合成员判断 | tcp.port in {80, 443, 8080} |
| && | and | 两个条件同时成立 | tcp.port == 443 && ip.src == A |
| ! | not | 取反,记得连括号一起写 | !(arp || icmp) |
典型使用场景
- 筛服务端错误区间:http.response.code >= 500 一次看全部 5xx
- 一次看多个服务端口:tcp.port in {80, 443, 8080}
- 按客户端标识检索:http.user_agent matches "(?i)curl|python"
- 排除纯确认包:tcp.len != 0 让视图只保留带数据的报文
- 多条件叠加收窄:ip.addr == A && tcp.port == 443 && tcp.flags.syn == 1
常用示例
常用示例
tcp.port == 8080 # 端口等于
tcp.len > 0 # 只保留带载荷的报文
http.response.code >= 500 # 服务端错误区间
tcp.flags.syn == 1 && tcp.flags.ack == 0 # 纯 SYN
!(arp || icmp) # 排除两类协议
tcp.port in {80, 443, 8080} # 端口集合
http.host == "api.example.com" # 字符串精确匹配字符串比较必须带引号,数值不要加引号。类型写错时 Wireshark 会在状态栏提示类型不匹配,不会静默给错结果,遇到异常先看提示信息。
否定要连括号一起写。只写 !tcp.port == 443 时表达式会按对字段本身取反的语义解析,结果往往为空集,排障时容易误判成没有流量。
组合写法
组合写法
ip.addr == 10.0.0.9 && tcp.port == 443 && tcp.flags.syn == 1 # 建连请求
http.response.code >= 400 && http.response.code < 500 # 只筛 4xx
tcp.analysis.flags && !tcp.analysis.window_update # 异常里去掉窗口更新
frame.time_relative > 60 && frame.time_relative < 90 # 只切一分钟时间窗书写建议
- 一个表达式只回答一个问题,条件堆太多时拆成两步更容易定位
- 区间判断用两个比较运算符拼,显示过滤器没有 between 这类语法
- 字符串比较先确认字段名,字段不存在时表达式合法但结果为空
- 表达式存成过滤器按钮后要写清楚用途,团队共用时避免误用
字段类型与写法
| 字段类型 | 书写要求 | 示例与说明 |
|---|---|---|
| 无符号整数 | 直接写十进制数字,不加引号 | tcp.port、tcp.len、http.response.code 都属于这一类 |
| 地址类型 | 写点分十进制地址或带前缀长度的网段 | ip.addr == 10.0.0.0/24 用 == 加前缀,不用 contains |
| 字符串类型 | 必须加双引号 | http.host、http.request.uri、dns.qry.name 等字段 |
| 布尔字段 | 用 0 与 1 比较 | tcp.flags.syn == 1 这类字段只有两种取值 |
| 时间字段 | 写秒数小数 | frame.time_delta > 0.5 用于筛查间隔偏大的报文 |
| 字节序列 | 用十六进制冒号分隔写法 | tcp.payload contains 47:45:54 匹配固定字节 |
拿不准字段类型时,选中一个报文展开协议树,把鼠标停在字段上会显示字段名与类型;用右键菜单生成表达式还能顺带确认字段路径是否拼对。
空结果的排查顺序
- 先去掉最内层的条件看是否有结果,逐个条件回加,定位到是哪一条把结果筛空了
- 再确认字段在该协议里是否真的存在,例如 HTTP 字段在 HTTPS 流量里必然为空
- 然后看类型是否写错,字符串字段写数字、数值字段加引号都会导致匹配不到
- 最后确认否定条件是否少了括号,这是空结果最常见也最隐蔽的原因