第3章 显示过滤器基础:语法、表达式与快速使用
抓包只是第一步,真正折磨人的是——你面对几千个包,根本不知道看哪个。我见过不少新手,打开Wireshark看到满屏的包就慌了,然后一个个翻,翻到崩溃。
显示过滤器就是用来解决这个问题的。它不删包,只是帮你把不关心的藏起来。说白了,就是给数据包做“筛选”,只留下你想要的。
核心认知:捕获过滤器是“抓之前过滤”,显示过滤器是“抓之后过滤”。前者影响性能,后者不影响。日常排查我几乎只用显示过滤器。
3.1 显示过滤器的基本结构
显示过滤器的语法其实很简单,就三部分:协议.字段 运算符 值。比如:
ip.addr == 192.168.1.1
tcp.port == 80
http.request.method == "GET"
我刚开始学的时候,总记不住字段名。后来发现一个窍门:在Wireshark里点开一个包,展开协议树,右键你想过滤的字段,选择“作为过滤器应用”或“准备过滤器”,系统会自动生成表达式。你想想看,这比死记硬背强多了。
| 组件 | 说明 | 示例 |
|---|---|---|
| 协议 | 协议名称,小写 | ip, tcp, udp, http, dns |
| 字段 | 协议下的具体属性 | addr, port, request.method |
| 运算符 | 比较或逻辑操作 | ==, !=, >, &&, || |
| 值 | 要匹配的内容 | IP地址、端口号、字符串 |
小技巧:在Wireshark的过滤栏输入时,系统会自动补全字段名。如果你不确定某个字段是否存在,输入协议名加个点,下拉列表就出来了。
3.2 常用运算符与表达式
运算符这块,我把它分成两类:比较运算符和逻辑运算符。先看比较的:
| 运算符 | 含义 | 示例 |
|---|---|---|
| == | 等于 | ip.src == 10.0.0.1 |
| != | 不等于 | ip.src != 10.0.0.1 |
| > | 大于 | tcp.window_size > 65535 |
| < | 小于 | frame.len < 100 |
| contains | 包含子串 | http.user_agent contains "Chrome" |
| matches | 正则匹配 | http.host matches "\.com$" |
逻辑运算符更常用,因为实际场景很少只用一个条件:
# 与运算(同时满足)
ip.src == 192.168.1.1 && tcp.port == 80
# 或运算(满足其一)
tcp.port == 80 || tcp.port == 443
# 非运算(排除)
!arp
# 括号分组(控制优先级)
(ip.src == 192.168.1.1 || ip.src == 192.168.1.2) && tcp.port == 443
我曾经遇到过一个场景:客户说网络慢,我抓了包想看看是不是有重传。直接用 tcp.analysis.retransmission 这个字段,一秒定位到问题。嗯,这个字段是Wireshark自己算出来的,不是协议自带的,但特别好用。
注意:contains 和 matches 对大小写敏感。如果你不确定大小写,可以用 lower() 函数转换,比如 lower(http.user_agent) contains "chrome"。
3.3 快速使用技巧
说实话,我很少手敲完整的过滤表达式。Wireshark给了好几个偷懒的方法:
- 右键过滤:在包列表里右键某个字段,直接选“作为过滤器应用”或“准备过滤器”。
- 过滤表达式按钮:过滤栏旁边的“表达式...”按钮,打开后可以按协议树浏览所有字段。
- 颜色规则:用显示过滤器给特定流量上色,比如把所有HTTP流量标成绿色。
- 保存过滤器:常用的过滤条件可以保存,下次直接点一下就用。
我个人习惯把常用的几个过滤器保存下来:比如只看HTTP、只看DNS、只看某个IP的流量。这样每次排查不用重新写。
3.4 实战:常见场景的过滤表达式
下面这些是我工作中经常用的,你直接复制就能用:
| 场景 | 过滤表达式 |
|---|---|
| 只看某个IP的流量 | ip.addr == 10.0.0.1 |
| 只看两个IP之间的通信 | ip.addr == 10.0.0.1 && ip.addr == 10.0.0.2 |
| 只看HTTP GET请求 | http.request.method == "GET" |
| 只看DNS查询 | dns.flags.response == 0 |
| 只看TCP重传 | tcp.analysis.retransmission |
| 排除广播和多播 | !eth.dst[0] & 1 |
| 只看特定端口的UDP流量 | udp.port == 53 |
| 只看HTTP响应状态码为404的 | http.response.code == 404 |
避坑指南:我曾经用 ip.src == 10.0.0.1 && ip.dst == 10.0.0.2 想只看A到B的流量,结果发现包没少多少。为什么?因为B回A的包也被过滤掉了。正确做法是用 ip.addr 代替 ip.src 和 ip.dst,它匹配任意方向的地址。
3.5 显示过滤器知识体系
下面这张图帮你理清本章的核心脉络:
3.6 常见问题与避坑
最后分享几个我踩过的坑:
- 字段名记不住?别硬记。在包详情里找到字段,右键就有。用得多了自然就记住了。
- 过滤没生效?检查一下是不是输入法问题。Wireshark的过滤栏只认英文标点,中文引号、括号都会导致语法错误。
- 过滤结果为空?先确认你抓到的包里确实有符合条件的流量。我经常犯的错是:抓的是eth0,但流量走的是eth1。
- 性能问题:如果过滤条件特别复杂(比如嵌套多层括号、大量正则),Wireshark可能会卡。这时候建议先缩小捕获范围,或者分步过滤。
终极技巧:在过滤栏输入 tcp.analysis.flags 可以看到所有TCP异常(重传、乱序、重复ACK等)。这是我排查网络问题时最常用的一个过滤器,没有之一。