ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

15:libpcap——全世界抓包工具共同的老父亲

15:libpcap——全世界抓包工具共同的老父亲 大家好我是毛衣哥。tcpdump 和 Wireshark 是两拨人写的但它们底层居然用同一个库。这个库就是 libpcap——全世界抓包工具的老父亲。tcpdump 和 Wireshark 是完全不同的两个项目由完全不同的人开发。但它们的抓包语法——比如tcp port 80——完全一样。答案在 libpcap 里。几乎所有你叫得上名字的抓包工具底层都依赖同一个 C 库libpcap。libpcap 的历史1994 年Steven McCanne对就是 BPF 论文的那个 McCanne和 Van Jacobson 在 BPF 的基础上开发了一个用户态库叫libpcap。它的目标“让所有抓包工具不需要重复实现跟 BPF 交互的底层细节。”在 libpcap 出现之前每个抓包程序都要自己写代码跟 BPF 设备打交道——打开/dev/bpf*设置 ioctl编译过滤表达式读取数据包。全是重复代码。libpcap 把这些重复操作封装成一组 API。从此你只需要几行代码就能写一个抓包程序。三个核心函数libpcap 的完整使用流程可以被归纳为三步第一步pcap_open_live()——打开网络设备pcap_t*handlepcap_open_live(en0,65535,1,1000,errbuf);en0网络接口名65535snaplen每个包最多抓取多少字节1promisc1 开启混杂模式1000to_ms超时时间毫秒背后做了什么Linux 上创建AF_PACKETsocketmacOS 上打开/dev/bpf0设置混杂模式 ioctl分配缓冲区。第二步pcap_compile()pcap_setfilter()——编译并加载 BPF 过滤器structbpf_programfcode;pcap_compile(handle,fcode,tcp port 80,1,0);pcap_setfilter(handle,fcode);pcap_compile()把人类可读的表达式编译成 BPF 字节码pcap_setfilter()通过系统调用把这个字节码送入内核。第三步pcap_loop()——循环读取数据包pcap_loop(handle,-1,callback,NULL);进入一个无限循环从 BPF 环形缓冲区读取一批数据包对每个包调用callback()函数。pcap 文件格式——通用语言libpcap 定义了 pcap 文件的二进制格式。任何遵守这个格式的工具都可以互相读取Global Header24 字节 Magic Number0xa1b2c3d4 大端序标记 Version Major / Minor Snaplen / Link Type Packet Header16 字节← 每个包一个 Timestamp秒 微秒 Captured Len / Original Len Packet DataN 字节这个格式为什么重要它是跨平台、跨工具的。Linux 上 tcpdump 抓的包可以用 macOS 上的 Wireshark 打开。libpcap 的跨平台差异平台底层机制特点LinuxAF_PACKET socket PACKET_MMAP支持零拷贝性能最好macOS/BSD/dev/bpf* 设备BPF 设备有限通常只有 4-8 个WindowsNPcap / WinPcap需要额外安装驱动性能弱于前两者macOS 的 BPF 设备陷阱/dev/bpf0到/dev/bpf7一共 8 个每个同一时间只能被一个程序使用。同时开两个 tcpdump 可能会报 “Device busy”。下期预告tcpdump 的十八般武艺——-X、-A、-e、-G、-C、-W——这些参数背后都对应着什么样的内核级操作DumpAny 怎么做libpcap 是 tcpdump/Wireshark 的底层DumpAny 不走这条路——我们做应用层代理而不是网络层抓包。但 DumpAny 的架构设计借鉴了 libpcap 的分层思想协议解析器parser和数据展示view是分离的。这意味着添加一个新协议时只需要写解析器展示和存储层完全复用。tcpdumplibpcapWiresharknmapSnortBPF / eBPF环形缓冲区内核网卡驱动┌──────────────────────────────┐ │ Global Header (24 bytes) │ │ Magic Number: 0xa1b2c3d4 │ │ Version: 2.4 │ │ Snaplen: 262144 │ │ Link Type: 1 (Ethernet) │ ├──────────────────────────────┤ │ Packet Header #1 (16 bytes) │ ← 每个包一个 │ Timestamp: 1689123456.123456│ │ Captured Len: 1420 │ │ Original Len: 1500 │ ├──────────────────────────────┤ │ Packet Data #1 (N bytes) │ ├──────────────────────────────┤ │ Packet Header #2 (16 bytes) │ │ Packet Data #2 (N bytes) │ └──────────────────────────────┘ 聊几句libpcap 是谁、哪年开发的—— Steven McCanne 和 Van Jacobson1994 年。pcap 文件格式的 Magic Number—— 0xa1b2c3d4在 24 字节 Global Header 里。libpcap 三个核心函数—— pcap_open_live 开设备、pcap_compile/pcap_setfilter 编译加载过滤器、pcap_loop 循环读包回调。macOS 的 BPF 设备有什么坑—— /dev/bpf0~bpf7 只有 8 个每个同时只能一个程序用开两个 tcpdump 可能报 Device busy。libpcap 这层 DumpAny 也封装好了你直接用就行不用自己调。官网 dumpany.cn开源免费。
返回列表