4、Wireshark高级过滤:显示过滤器的语法、常用过滤表达式
说到Wireshark的显示过滤器,我刚开始学的时候也觉得有点头大。但用久了你会发现,这玩意儿其实就是个「筛子」——把你不关心的流量统统过滤掉,只留下你想看的那部分。我个人习惯是抓包时先全量抓,然后用显示过滤器慢慢缩小范围,这样不会漏掉关键信息。
4.1 显示过滤器的基本语法
显示过滤器的语法,说白了就是「字段 运算符 值」这样的结构。举个例子:
ip.addr == 192.168.1.1
tcp.port == 80
http.request.method == "GET"
这里有几个要点:
- 字段名:比如
ip.addr、tcp.port,大小写不敏感 - 运算符:
==(等于)、!=(不等于)、>(大于)、<(小于) - 值:IP地址、端口号、字符串等,字符串需要用双引号
小技巧:我个人习惯用
== 而不是 eq,因为更直观。但Wireshark也支持 eq、ne、gt 等英文写法,看个人喜好。
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 实战案例:定位慢接口
最后分享一个我实际用过的案例。有一次客户反馈某个接口响应慢,我这样操作:
- 先抓全量包
- 用
http.time > 2找到响应时间超过2秒的HTTP请求 - 发现都是针对
/api/order/list的请求 - 再用
http.request.uri contains "/api/order/list"过滤出所有相关请求 - 分析发现是数据库查询慢导致的
整个过程不到5分钟。如果没有显示过滤器,你可能得盯着屏幕看半小时。
注意:
contains 是字符串包含匹配,matches 支持正则表达式。比如 http.request.uri matches "/api/v[0-9]/" 可以匹配所有版本号的API。但正则表达式性能较差,能不用尽量不用。
好了,显示过滤器就讲这么多。记住一个原则:先粗后细,逐步缩小。别想着一步到位写出完美的过滤表达式,先排除干扰项,再加条件,这样效率最高。