4. 显示过滤器进阶:基于协议、IP、端口的组合过滤

上一章我们聊了基础过滤,说白了就是单个条件查问题。但实际抓包时,你很少只关心一种因素。比如端口占用了,你得同时看IP对不对、协议是不是TCP、端口是不是那个冲突的端口。这时候就需要组合过滤了。

我个人习惯,遇到复杂问题从来不用单一过滤器。为什么?因为网络流量太杂了。你只过滤一个条件,结果里可能混进来一堆不相干的数据包,反而干扰判断。组合过滤就像给数据包做“安检”,多个条件一起上,精准定位。

4.1 逻辑运算符:and、or、not

Wireshark的显示过滤器支持三种逻辑运算:and(与)、or(或)、not(非)。它们的作用很简单:

运算符 含义 示例 说明
and 同时满足 ip.src==192.168.1.1 and tcp.port==80 源IP为192.168.1.1且端口为80
or 满足其一 tcp.port==80 or tcp.port==443 端口为80或443
not 排除条件 not arp 排除ARP协议

嗯,这里要注意:and 的优先级高于 or。如果你混用,最好加括号明确顺序。比如:(tcp.port==80 or tcp.port==443) and ip.src==192.168.1.1。不加括号的话,Wireshark会先算and,结果可能不是你想要的。

小技巧: 我习惯在复杂过滤表达式里,把每个条件用括号包起来。虽然Wireshark不强制,但这样可读性高,改起来也方便。比如:(ip.src==192.168.1.1) and (tcp.port==80)。

4.2 实战组合:协议 + IP + 端口

端口占用排查时,最常用的组合就是“协议 + IP + 端口”。举个例子:

假设你发现服务器192.168.1.100的8080端口被占用了,你想看看是谁在连它。过滤器可以这样写:

ip.addr==192.168.1.100 and tcp.port==8080

这个过滤器会显示所有涉及192.168.1.100且端口为8080的TCP包。但注意,ip.addr 同时匹配源IP和目标IP。如果你只想看某个方向的流量,可以用 ip.src 或 ip.dst。

我在项目中遇到过一个问题:客户说服务器端口被占用了,但抓包一看,全是广播包和ARP请求。后来我加了 not arp 和 not icmp,瞬间清净了。过滤器长这样:

ip.addr==192.168.1.100 and tcp.port==8080 and not arp and not icmp
核心思路: 组合过滤的本质是“缩小范围”。每加一个条件,就排除一批无关数据包。最终留下的,就是你要分析的那一小撮。

4.3 避坑指南:常见的组合过滤错误

我曾经在排查一个数据库连接问题时,写了这么个过滤器:

tcp.port==3306 or tcp.port==3307 and ip.src==192.168.1.50

结果出来的数据包乱七八糟。后来才发现,Wireshark先算了 tcp.port==3307 and ip.src==192.168.1.50,然后和 tcp.port==3306 做or运算。也就是说,所有3306端口的包都出来了,不管IP是谁。

正确的写法应该是:

(tcp.port==3306 or tcp.port==3307) and ip.src==192.168.1.50

另一个常见错误是混淆 ip.addr 和 ip.src/ip.dst。比如你想看从192.168.1.1发往80端口的包,写成:

ip.addr==192.168.1.1 and tcp.dstport==80

这会把192.168.1.1作为目标IP的包也包含进来。正确做法:

ip.src==192.168.1.1 and tcp.dstport==80
注意: ip.addr 是“IP地址字段包含”,不是“等于”。它匹配源IP和目标IP。如果你只想匹配一个方向,用 ip.src 或 ip.dst。

4.4 组合过滤的进阶用法

除了基本的and/or/not,你还可以用括号嵌套更复杂的逻辑。比如:

(ip.src==192.168.1.0/24 and tcp.port==80) or (ip.dst==10.0.0.1 and udp.port==53)

这个过滤器会显示:来自192.168.1.0/24网段且目标端口为80的TCP包,或者发往10.0.0.1且端口为53的UDP包。你想想看,这种组合在排查跨网段问题时特别有用。

我个人习惯在排查端口冲突时,先用一个宽泛的过滤器看全局,比如:

tcp.port==8080

然后根据结果逐步加条件。比如发现某个IP的流量异常,就加上 and ip.addr==x.x.x.x。这样一步步缩小范围,比一次性写一个超长过滤器要靠谱。

4.5 知识体系:组合过滤的核心逻辑

下面这张图总结了组合过滤的核心逻辑,你可以把它当作一个决策树来用:

组合过滤核心逻辑图 组合过滤决策树 原始数据包 协议过滤 IP地址过滤 端口过滤 精准定位的目标数据包 组合方式 and:同时满足 or:满足其一 not:排除条件 过滤顺序 协议 → IP → 端口 逐步缩小范围

从图上可以看出,组合过滤是一个“层层递进”的过程。先过滤协议,再过滤IP,最后过滤端口。每一步都在缩小数据包的范围,最终得到你真正关心的那部分。

4.6 实战案例:用组合过滤定位端口冲突

最后,我分享一个真实案例。有一次,客户反馈应用连不上数据库,报错“端口被占用”。我抓包后,先用基础过滤器看了下:

tcp.port==3306

结果发现大量来自不同IP的SYN包。但问题是我需要确认到底是哪个IP在“占用”端口。于是我加了IP过滤:

tcp.port==3306 and ip.src==192.168.1.100

嗯,还是很多。我又加了状态过滤:

tcp.port==3306 and ip.src==192.168.1.100 and tcp.flags.syn==1 and tcp.flags.ack==0

这下只显示SYN包了。但问题还没完——我发现同一个源IP发起了大量SYN,但服务器没回SYN-ACK。这说明端口确实被占用了,但占用者不是这个IP。后来我改用 not 排除这个IP:

tcp.port==3306 and not ip.src==192.168.1.100

终于找到了真正的“元凶”——一个异常进程在疯狂重连。你看,组合过滤用好了,排查效率能翻好几倍。

我的建议: 刚开始用组合过滤时,别追求一步到位。先写一个简单的,然后逐步加条件。每加一个条件,看看结果变化,这样你能更清楚每个条件的作用。