第四章 显示过滤器进阶:高级过滤技巧、函数与用户自定义过滤器
显示过滤器,说白了就是你跟Wireshark对话的语言。基础语法能让你抓到包,但想真正用好它,得学会高级玩法。我做了这么多年网络排障,发现很多人卡在“知道有这功能但不会用”的阶段。
今天咱们就把这块啃透。
4.1 逻辑运算符的深层用法
大部分人用 and、or、not 也就够了。但实际抓包时,条件往往更复杂。
核心原则:用括号明确优先级,别靠脑子记。
举个例子,你想看“来自192.168.1.1的HTTP流量,或者所有DNS查询”。很多人会写:
ip.src == 192.168.1.1 and http or dns
这其实是错的。Wireshark会解析成 (ip.src == 192.168.1.1 and http) or dns,结果把所有DNS包都捞出来了。正确写法是:
ip.src == 192.168.1.1 and (http or dns)
我在项目里见过好几次这种坑,排查了半天发现是过滤器逻辑搞反了。
4.2 比较运算符与切片操作
除了 ==、!=、>、<,Wireshark还支持一些冷门但好用的操作符。
| 运算符 | 含义 | 示例 |
|---|---|---|
contains |
包含子串 | http.host contains "baidu" |
matches |
正则匹配 | http.request.uri matches "\.php$" |
in |
成员判断 | ip.src in {10.0.0.0/8, 172.16.0.0/12} |
[] |
字节切片 | eth.src[0:3] == 00:1a:2b |
切片操作是我个人很爱用的。比如只看MAC地址前3字节(OUI)匹配某个厂商的包:
eth.addr[0:3] == 00:1a:2b
或者只看TCP负载的前4个字节:
tcp.payload[0:4] == 48:65:6c:6c
小技巧:切片语法是 [起始偏移:长度],偏移从0开始。不写长度就是取到末尾。
4.3 显示过滤器函数
Wireshark内置了一批函数,能帮你做更复杂的判断。我刚开始学的时候觉得这些函数可有可无,直到有一次要分析几千个TCP流……
4.3.1 upper() / lower()
字符串比较时忽略大小写:
upper(http.host) contains "GOOGLE"
4.3.2 len()
获取字段长度。比如只看UDP负载超过100字节的包:
len(udp.payload) > 100
4.3.3 count()
统计某个字段出现的次数。比如过滤出有超过3个TCP选项的包:
count(tcp.options) > 3
4.3.4 string()
把字段转成字符串,方便做正则匹配。比如:
string(frame.number) matches "^1[0-9]"
注意:string() 函数性能开销较大,在大流量抓包中慎用。我曾经在线上环境用这个函数,结果Wireshark卡了半分钟。
4.4 用户自定义显示过滤器
你有没有遇到过这种情况?一个复杂的过滤器,每次都要重新敲一遍。比如:
ip.src == 192.168.1.0/24 and tcp.port == 80 and not icmp
Wireshark允许你把这种常用过滤器保存成“按钮”,一键切换。
操作步骤:
- 点击显示过滤器栏右侧的 “+” 按钮(或右键 → 管理显示过滤器)
- 在弹出的对话框中,输入名称(比如“内网HTTP”)和过滤器表达式
- 点击保存
之后你就能在过滤器下拉菜单里直接选它了。我习惯把常用的排障场景都存成预设:
| 名称 | 过滤器表达式 | 用途 |
|---|---|---|
| 内网HTTP | ip.src == 192.168.0.0/16 and http |
只看内网HTTP请求 |
| TCP重传 | tcp.analysis.retransmission |
快速定位重传 |
| DNS异常 | dns.flags.rcode != 0 |
过滤DNS错误响应 |
| 大包 | frame.len > 1400 |
找出超过MTU的包 |
4.5 实战:用高级过滤器定位慢访问问题
咱们来走一个真实场景。用户反馈访问某个网站很慢,你抓了包,怎么快速定位?
我的做法是分三步:
- 先看TCP握手时间:
看SYN到SYN-ACK的延迟。tcp.flags.syn == 1 and ip.addr == 目标IP - 再看应用层响应时间:
过滤出HTTP响应时间超过1秒的请求。http.time > 1 - 最后看是否有重传:
tcp.analysis.retransmission and ip.addr == 目标IP
有一次我排查一个电商网站的慢访问,就是用这个组合拳,发现是某个CDN节点的TCP重传率高达15%。后来跟运营商一沟通,果然是路由问题。
4.6 知识体系总览
下面这张图把本章的核心逻辑串起来了。你想想看,从基础语法到函数,再到自定义过滤器,其实是一条线:表达能力越来越强,操作越来越快。
4.7 避坑指南
最后分享几个我踩过的坑:
- 别在显示过滤器里用
!=判断不存在的字段。比如http.host != "baidu.com",它会匹配所有没有http.host字段的包(比如TCP握手包),结果完全不是你想要的。正确做法是http.host and http.host != "baidu.com"。 - 正则表达式别写太复杂。Wireshark的正则引擎性能一般,一个复杂的正则能让界面卡死。我一般只用
contains解决80%的问题。 - 自定义过滤器命名要有规律。我见过有人存了20多个过滤器,名字叫“test1”、“test2”……过两天自己都忘了是干嘛的。建议按“场景_协议_用途”命名,比如
web_http_慢请求。
我的习惯:每做完一次排障,就把用到的过滤器存下来,加个备注。半年下来,你的过滤器库就是一本排障手册。
好了,显示过滤器进阶就聊到这儿。这些技巧你多用几次,慢慢就会变成肌肉记忆。下次遇到复杂场景,别急着翻包,先想想能不能用一行过滤器搞定。