4、Wireshark高级过滤:显示过滤器的语法、常用过滤表达式

说到Wireshark的显示过滤器,我刚开始学的时候也觉得有点头大。但用久了你会发现,这玩意儿其实就是个「筛子」——把你不关心的流量统统过滤掉,只留下你想看的那部分。我个人习惯是抓包时先全量抓,然后用显示过滤器慢慢缩小范围,这样不会漏掉关键信息。

4.1 显示过滤器的基本语法

显示过滤器的语法,说白了就是「字段 运算符 值」这样的结构。举个例子:

ip.addr == 192.168.1.1
tcp.port == 80
http.request.method == "GET"

这里有几个要点:

  • 字段名:比如 ip.addrtcp.port,大小写不敏感
  • 运算符==(等于)、!=(不等于)、>(大于)、<(小于)
  • :IP地址、端口号、字符串等,字符串需要用双引号
小技巧:我个人习惯用 == 而不是 eq,因为更直观。但Wireshark也支持 eqnegt 等英文写法,看个人喜好。

4.2 常用过滤表达式

我在项目中遇到过很多次,刚入门的同事总是记不住几个最常用的表达式。这里我列几个你一定会用到的:

4.2.1 ip.addr —— 按IP地址过滤

这个最常用,也最容易踩坑。注意 ip.addr 同时匹配源IP和目标IP:

ip.addr == 192.168.1.1        # 匹配所有包含该IP的包
ip.src == 192.168.1.1         # 只匹配源IP
ip.dst == 192.168.1.1         # 只匹配目标IP
避坑指南:我曾经犯过一个低级错误——用 ip.addr == 192.168.1.1 and ip.addr == 10.0.0.1 想找两个IP之间的通信。结果发现根本不对!因为 ip.addr 会匹配任意一个IP,正确写法应该是 (ip.src == 192.168.1.1 and ip.dst == 10.0.0.1) or (ip.src == 10.0.0.1 and ip.dst == 192.168.1.1)

4.2.2 tcp.port —— 按端口过滤

同样,tcp.port 同时匹配源端口和目标端口:

tcp.port == 80                # 匹配所有80端口的TCP包
tcp.srcport == 443            # 只匹配源端口443
tcp.dstport == 22             # 只匹配目标端口22

嗯,这里要注意:UDP的端口过滤用 udp.port,别搞混了。

4.2.3 http —— HTTP协议过滤

HTTP过滤是我排查Web问题时最常用的:

http                         # 显示所有HTTP包
http.request                 # 只显示HTTP请求
http.response                # 只显示HTTP响应
http.request.method == "POST"  # 只显示POST请求
http.response.code == 404    # 只显示404响应
实战经验:有一次线上接口突然变慢,我用 http.time > 1 一秒就找到了那些响应时间超过1秒的请求。你想想看,如果没有这个过滤器,你得在几千个包里一个个翻,多痛苦。

4.3 过滤表达式组合与取反

单个表达式往往不够用,我们需要组合它们。Wireshark支持逻辑运算符:

运算符 含义 示例
and&& ip.addr == 10.0.0.1 and tcp.port == 80
or|| tcp.port == 80 or tcp.port == 443
not! 取反 not arp!arp

组合使用时,我建议用括号明确优先级,避免歧义:

(ip.src == 192.168.1.1 and tcp.dstport == 80) or (ip.src == 10.0.0.1 and tcp.dstport == 443)
!icmp and !arp               # 排除ICMP和ARP包
http and !http.request       # 显示HTTP响应但不显示请求
我的习惯:排查问题时,我通常会先排除掉广播包和ARP包——!arp and !icmp,因为这些包会干扰视线。然后再加上具体条件,一步步缩小范围。

4.4 实战案例:定位慢接口

最后分享一个我实际用过的案例。有一次客户反馈某个接口响应慢,我这样操作:

  1. 先抓全量包
  2. http.time > 2 找到响应时间超过2秒的HTTP请求
  3. 发现都是针对 /api/order/list 的请求
  4. 再用 http.request.uri contains "/api/order/list" 过滤出所有相关请求
  5. 分析发现是数据库查询慢导致的

整个过程不到5分钟。如果没有显示过滤器,你可能得盯着屏幕看半小时。

注意contains 是字符串包含匹配,matches 支持正则表达式。比如 http.request.uri matches "/api/v[0-9]/" 可以匹配所有版本号的API。但正则表达式性能较差,能不用尽量不用。

好了,显示过滤器就讲这么多。记住一个原则:先粗后细,逐步缩小。别想着一步到位写出完美的过滤表达式,先排除干扰项,再加条件,这样效率最高。