支持情况与原理
在 linux 上的嗅探器通常都支持自定义过滤器。底层通过内核的 BPF(Berkeley Packet Filter) 在网卡驱动之后尽早过滤,只有匹配过滤表达式的数据包才会被拷贝到用户态,从而显著降低 CPU 与内存开销。常见抓包工具(如 tcpdump)使用 libpcap 将人类可读的过滤表达式编译为 BPF 字节码并下发到内核执行,实现高性能的自定义过滤。
常用工具的自定义过滤示例
- tcpdump(BPF 语法,捕获过滤)
- 仅抓取源端口为 80 的 tcp 流量:sudo tcpdump -i eth0 ‘tcp src port 80’
- 抓取 192.168.1.0/24 网段到 10.0.0.10 的 icmp 流量:sudo tcpdump -i eth0 ‘icmp and src net 192.168.1.0/24 and dst host 10.0.0.10’
- 将结果写入文件并用 -r 回放分析:sudo tcpdump -i eth0 -w capture.pcap ‘port 53’;tcpdump -r capture.pcap
- Wireshark / tshark(显示过滤器)
- 捕获阶段通常全量抓取,分析阶段用显示过滤器聚焦,例如:ip.addr == 192.168.1.100 and dns
- 提示:显示过滤器语法与 BPF 不同,用于界面展示阶段的筛选。
开发自定义嗅探器的实现思路
- 使用 PF_PACKET + SOCK_RAW 打开网卡,配合 setsockopt(SO_ATTACH_FILTER) 附加 BPF 过滤程序,内核将按 BPF 规则预筛选报文,仅把命中数据送入用户态,避免应用层逐个丢弃的开销。
- 借助 libpcap 提供的 pcap_compile / pcap_setfilter 将表达式编译为 BPF 并应用到捕获句柄,简化过滤器开发;也可直接编写 BPF 汇编或使用 tcpdump 的 -d/-dd/-ddd 查看编译后的 BPF 指令用于调试。
使用过滤器的注意事项
- 需要 root/管理员权限 才能捕获网卡数据包(涉及网卡混杂模式与内核过滤下发)。
- 区分两类过滤:捕获过滤(如 BPF,尽早丢弃无关包,节省资源)与显示过滤(如 Wireshark 界面筛选,仅影响展示不影响捕获)。
- 在 CentOS/RHEL 等环境中,常以 tcpdump / Wireshark 作为嗅探与过滤工具;编写规则时注意接口名、地址族与协议关键字的正确使用。