Linux Sniffer如何支持多种协议
小樊
41
2025-12-25 03:21:19
Linux Sniffer支持多种协议的核心机制
- 通过网卡进入混杂模式,让网卡接收所有经过接口的帧,而非仅限发给本机的目的MAC。这样可覆盖同一二层网段内的更多流量。
- 使用PF_PACKET 套接字直接对接网卡驱动:选择SOCK_RAW可拿到包含以太网头的完整帧,选择SOCK_DGRAM则由内核处理/剥离链路层头,便于在上层解析。
- 在套接字上设置**BPF(Berkeley Packet Filter)**过滤表达式,内核在数据到达用户态前完成高效过滤,仅交付你关心的协议/端口/地址,从而以低开销支持多种协议同时监听。
- 解析时按协议栈自底向上:以太网头(EtherType)→ IPv4/IPv6 头 → TCP/UDP/ICMP 等传输层 → 应用层(如 DNS、HTTP 等)。其中 EtherType 如0x0800=IPv4、0x86DD=IPv6,IPv4 头中的protocol字段标识上层协议(如6=TCP、17=UDP、1=ICMP)。
- 权限与安全:PF_PACKET 属于特权操作,通常需要root或具备相应能力(CAP_NET_RAW)才能创建与抓包。
从零实现支持多协议的嗅探器要点
- 打开套接字:socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) 可接收所有以太网帧;或指定 ETH_P_IP/ETH_P_IPV6 仅收对应三层流量。
- 混杂模式:用 ioctl(SIOCGIFFLAGS/ SIOCSIFFLAGS) 获取并设置 IFF_PROMISC 标志,使网卡进入混杂。
- BPF 过滤:使用 setsockopt(SO_ATTACH_FILTER) 附加编译后的 BPF 程序,在内核态先筛掉无关流量,显著降低用户态解析压力。
- 接收与解析:recvfrom 获取帧后,按偏移解析以太网头→IP 头→传输层头;依据 IP 头的 protocol 分发到 TCP/UDP/ICMP 等解析器,再按端口或特征识别更高层协议。
- 权限控制:以最小权限运行(如仅授予 CAP_NET_RAW),谨慎处理原始内存与不可信输入。
使用 libpcap 的方案与多协议支持
- 采用libpcap(tcpdump、Wireshark 等均基于它)可快速获得跨协议解析与成熟过滤能力。
- 典型流程:pcap_open_live 打开接口→pcap_compile/pcap_setfilter 设置 BPF→pcap_loop/pcap_next 循环捕获→在回调中按DLT/链路层类型与IP 协议号分发到各协议解析器。
- 优势:自动适配以太网、802.11、PPP等链路层,内置TCP/UDP/ICMP/DNS/HTTP等解析与显示,BPF 语法统一,开发效率高、可移植性好。
常见协议的支持范围与可见性
- 二层与三层:可解析以太网、802.11(链路层)、ARP/RARP(链路/三层辅助)、IPv4/IPv6。
- 传输层:TCP/UDP/ICMP/IGMP 等,依据 IPv4 头的protocol字段或 IPv6 的Next Header识别。
- 应用层:取决于是否解析到负载与端口/特征,如DNS(UDP/TCP 53)、HTTP(TCP 80)、FTP(TCP 21/20)、SMTP/POP3/IMAP(明文)、以及ICMP(ping/traceroute)。
- 加密流量:如 HTTPS/TLS 可捕获到连接元数据(五元组、握手与记录层帧头),但应用层内容默认不可解密;如需内容级分析需配合会话密钥或中间人条件。
- 交换网络可见性:在普通交换网络中,默认只能看到本机或广播/多播流量;要覆盖更多主机,需端口镜像或在受控前提下使用ARP 欺骗等手段。
最小示例与命令参考
- 命令行快速抓取多协议(libpcap):
- 抓取所有接口上的 HTTP 与 DNS:
- tcpdump -i any -nn -s 0 -w capture.pcap ‘tcp port 80 or udp port 53’
- 读取并分析文件:
- tcpdump -r capture.pcap -nn -vv
- C 语言最小嗅探框架(PF_PACKET + BPF 思路):
- 创建套接字:socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
- 开启混杂:ioctl(SIOCSIFFLAGS) 设置 IFF_PROMISC
- 编译并附加 BPF:使用 pcap_compile/pcap_setfilter 或手工构造 bpf_insn 并 setsockopt(SO_ATTACH_FILTER)
- 循环 recvfrom,按 EtherType→IP 头→protocol 分发解析器(TCP/UDP/ICMP 等)
- 注意:需root/CAP_NET_RAW,并做好长度与指针边界检查。