- 网络安全
- 网络
- IDS
【免费下载链接】zeek
Zeek is a powerful network analysis framework that is much different from the typical IDS you may know.
本指南以 Zeek 仓库中 linux_sll2 包文档 为核心,系统讲解 Zeek 如何解析Linux cooked capture version 2(SLL2,DLT_LINUX_SLL2,DLT 值 276)链路层封装:从链路层到网络层(IPv4/IPv6/ARP)的派发机制、底层 C++ 解析器实现、默认脚本注册逻辑,以及如何用-r读取 SLL2 pcap 文件并验证 ARP、ICMP 事件输出。读完本文,你将掌握 SLL2 在 Zeek 中的完整处理链路,并能动手复现对应测试验证解析行为。
一、SLL2 是什么:Linux 下的另一种"虚拟以太网"封装
在 Linux 系统上抓包时,并非总能拿到标准的以太网帧。当数据包经由any 接口(-i any)或某些非以太网接口(如lo、tun、wlan等)进入抓包工具时,内核AF_PACKET套接字会为每个包前置一个Linux cooked capture头,用 SLL(旧版,DLT 113)或 SLL2(新版,DLT 276)来携带"如果这是以太网帧本该有的"协议类型(Ethertype)、接口索引、ARPHRD 硬件类型、源地址等信息。
SLL2 的头部布局(来自 LINKTYPE_LINUX_SLL2 规范)为:
| 字段 | 长度 | 说明 |
|---|---|---|
protocol_type | 2 字节 | Ethertype,网络字节序(如0x0800=IPv4、0x86DD=IPv6、0x0806=ARP、0x8035=RARP) |
reserved | 2 字节 | 保留,置 0 |
interface_index | 4 字节 | 抓包接口的 ifindex |
arphrd_type | 2 字节 | ARPHRD 硬件类型 |
packet_type | 1 字节 | 包方向/类型(如 PACKET_HOST) |
addr_len | 1 字节 | 链路层源地址长度(字节) |
addr | 8 字节 | 链路层源地址(按addr_len有效) |
与旧版 SLL 相比,SLL2 头固定为 20 字节(旧的 SLL 为 16 字节),并新增了接口索引与 ARPHRD 硬件类型字段。
Zeek 为这种封装提供了专门的解析器,命名空间为PacketAnalyzer::LINUXSLL2(见 main.zeek.rst)。
二、从 DLT 值到解析器:root 层的注册路由
Zeek 的base/packet-protocols/root脚本定义了各链路层 DLT 值与解析器的映射关系,其中:
DLT_LINUX_SLL2 = 276(见 root/main.zeek);- 在
zeek_init()中调用PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_ROOT, DLT_LINUX_SLL2, PacketAnalyzer::ANALYZER_LINUXSLL2),把 ROOT 解析器在 DLT 276 上的后继解析器注册为ANALYZER_LINUXSLL2。
也就是说,当一个包的链路层类型为 DLT_LINUX_SLL2 时,ROOT 层会把它派发给 LinuxSLL2 解析器继续处理。根层同时为DLT_EN10MB(1)→Ethernet、DLT_LINUX_SLL(113)→LINUXSLL、DLT_NFLOG(239)→NFLOG 等建立了类似路由,linux_sll2只是其中的一条分支。
三、C++ 解析器实现:LinuxSLL2Analyzer 的数据流
解析器核心实现在 src/packet_analysis/protocol/linux_sll2/LinuxSLL2.cc 与 LinuxSLL2.h。头部结构体SLL2Header用#pragma pack(push, 1)紧凑对齐以支持跨编译器(MSVC 忽略__attribute__((packed))),字段顺序与上文规范表一一对应。
AnalyzePacket()的处理流程:
- 长度校验:若
sizeof(SLL2Header)(20 字节)不小于包长,则上报truncated_Linux_SLL2_headerweird 并丢弃; - 读取 Ethertype:
ntohs(hdr->protocol_type)得到网络层协议号; - 填充链路层地址:
packet->l2_src指向头部addr字段(即 SLL2 头携带的源 MAC);由于 SLL2 头不含目的地址,packet->l2_dst被显式设置为Packet::L2_EMPTY_ADDR——源码注释特别说明,不设置l2_dst会在后续 ARP 等处理中引发崩溃; - 前向派发:
ForwardPacket(len - 20, data + 20, packet, protocol)把负载(去掉 SLL2 头)按 Ethertype 交给网络层解析器。
一个值得注意的设计取舍在 LinuxSLL2.cc:当前实现只假定看到的是 Ethertype,不区分不同的ARPHDR_type值,这与 SLL(LinuxSLL.cc 同源代码结构一致)的做法相同——这类实现细节都以 tcpdump 的 LINKTYPE_LINUX_SLL2 规范为参照。
3.1 插件注册
解析器通过标准插件机制加载,Plugin.cc 将组件"LinuxSLL2"注册进packet_analysis::Component,插件名Zeek::LinuxSLL2,描述为 "Linux cooked capture version 2 (SLL2) packet analyzer"。
四、脚本层派发规则:Ethertype → 网络层解析器
SLL2 本身是"准链路层",它需要把内部 Ethertype 再映射到网络层解析器。这一映射在脚本 scripts/base/packet-protocols/linux_sll2/main.zeek 中于zeek_init()(&priority=20)内注册:
| Ethertype | 值 | 派发目标 |
|---|---|---|
| IPv4 | 0x0800 | PacketAnalyzer::ANALYZER_IP |
| IPv6 | 0x86DD | PacketAnalyzer::ANALYZER_IP |
| ARP | 0x0806 | PacketAnalyzer::ANALYZER_ARP |
| RARP | 0x8035 | PacketAnalyzer::ANALYZER_ARP |
例如PacketAnalyzer::register_packet_analyzer(PacketAnalyzer::ANALYZER_LINUXSLL2, 0x0800, PacketAnalyzer::ANALYZER_IP)表示:当 LinuxSLL2 解析出的 Ethertype 为0x0800时,后续由 IP 解析器接手。这与linux_sll包的注册逻辑完全一致(对照 linux_sll/main.zeek),体现了新旧两版 cooked capture 处理的一致性。
该脚本由 base/packet-protocols/load.zeek 中的@load base/packet-protocols/linux_sll2自动加载,因此默认配置(init-default)下无需任何额外操作即可启用 SLL2 解析。
五、从文档到实战:读取 SLL2 pcap 并验证解析结果
仓库的 linuxsll2.zeek 测试 是验证整个解析链路的现成例子,测试步骤如下:
- 前置条件:测试要求构建产物中不定义
DONT_HAVE_LIBPCAP_DLT_LINUX_SLL2(即 libpcap 支持 SLL2 DLT 值),对应测试注释# @TEST-REQUIRES: ! grep -q "#define DONT_HAVE_LIBPCAP_DLT_LINUX_SLL2" $BUILD/zeek-config.h; - 运行:
zeek -b -C -r $TRACES/linux_dlt_sll2.pcap %INPUT,即关闭 banner(-b)、关闭校验和校验(-C)、离线读取 SLL2 封装 pcap,并加载测试脚本; - 断言:测试脚本订阅了
arp_request、icmp_echo_request、icmp_echo_reply事件并打印字段,btest-diff .stdout将输出与基线比对。
这说明:SLL2 链路中的 ARP 请求会携带 SLL2 头中的源 MAC(经packet->l2_src传入 ARP 解析器,参见 ARP.cc 中RequestReplyEvent(arp_request, packet->l2_src, packet->l2_dst, ah)的调用),而 ICMP 事件则证明 IPv4 分支(0x0800→ IP)解析正常。
自己动手复现时,只需一条命令即可验证默认解析行为:
zeek -C -r /path/to/linux_dlt_sll2.pcap然后观察conn.log中是否生成对应连接记录,或在脚本中订阅arp_request/icmp_echo_request等事件查看 SLL2 头中携带的 MAC 与 IP 映射是否正确。
六、SLL2 与 SLL、Ethernet 解析器对照
| 维度 | Ethernet | LINUX_SLL | LINUX_SLL2 |
|---|---|---|---|
| DLT 值 | 1 | 113 | 276 |
| 头部字节 | 14 | 16 | 20 |
| 源地址来源 | 帧内dst/src MAC | SLL 头addr字段 | SLL2 头addr字段 |
| 目的地址 | 帧内 | 无,置L2_EMPTY_ADDR | 无,置L2_EMPTY_ADDR |
| 派发依据 | 帧内 Ethertype | SLL 头 protocol_type | SLL2 头 protocol_type |
从源码看,Ethernet.cc 会同时设置l2_src与l2_dst;而 SLL/SLL2 由于头部不含目的 MAC,都通过Packet::L2_EMPTY_ADDR占位以避免下游崩溃。这也是为什么在-i any抓包环境下,Zeek 仍能正确填充arp_request等事件的 MAC 字段——源 MAC 来自 SLL2 头,目的 MAC 则不可用。
七、总结与延伸阅读
SLL2 解析器是 Zeek 在非以太网抓包环境下还原"虚拟链路层"的关键一环:ROOT 层按 DLT 值选路,LinuxSLL2Analyzer 在 C++ 侧解析 20 字节 SLL2 头并填充l2_src/l2_dst,脚本层再按 Ethertype 把 IPv4/IPv6/ARP/RARP 派发给网络层解析器。默认随base/packet-protocols/__load__.zeek自动加载,zeek -C -r xxx.pcap即可直接消费 SLL2 抓包。
进一步阅读建议:
- 解析器 C++ 源码:LinuxSLL2.cc、LinuxSLL2.h;
- 插件注册:Plugin.cc;
- DLT 路由:root/main.zeek;
- 测试用例:testing/btest/core/linuxsll2.zeek;
- 关联解析器:LinuxSLL(main.zeek)与 Ethernet(Ethernet.cc)。
- 网络安全
- 网络
- IDS
【免费下载链接】zeek
Zeek is a powerful network analysis framework that is much different from the typical IDS you may know.
相关推荐
Talos Linux 链路别名配置:LinkAliasConfig 文档深入解析与实战
Talos Linux 链路别名配置:LinkAliasConfig 文档深入解析与实战 LinkAliasConfig 是 Talos Linux 中一类独立
云原生操作系统容器编排Matter(CHIP)Linux 平台适配层源码解读:PlatformManager 到 PosixConfig 的完整实现剖析
Matter(CHIP)Linux 平台适配层源码解读:PlatformManager 到 PosixConfig 的完整实现剖析 本文是 Matter(原 P
物联网智能家居嵌入式通信Zeek Broker 通信框架完全指南:脚本层 API、配置选项与源码级剖析
Zeek Broker 通信框架完全指南:脚本层 API、配置选项与源码级剖析 导读 本文以 Zeek 官方脚本文档 doc/scripts/base/fram
网络安全网络IDS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考