第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给了好几个偷懒的方法:

  1. 右键过滤:在包列表里右键某个字段,直接选“作为过滤器应用”或“准备过滤器”。
  2. 过滤表达式按钮:过滤栏旁边的“表达式...”按钮,打开后可以按协议树浏览所有字段。
  3. 颜色规则:用显示过滤器给特定流量上色,比如把所有HTTP流量标成绿色。
  4. 保存过滤器:常用的过滤条件可以保存,下次直接点一下就用。

我个人习惯把常用的几个过滤器保存下来:比如只看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等)。这是我排查网络问题时最常用的一个过滤器,没有之一。