1. SLL 介绍
SLL 是 libpcap 在 Linux 上使用的伪协议,用于从“any”设备(在所有接口上捕获数据包的伪设备),或者在本地链路层
头不可用或不能使用的设备上,捕获数据包。比如,Linux 的 PPP 代码在向 libpcap 提供 PPP 头时不可靠 - 通常,要么
不提供(意味着数据包类型不可用),要么在某些但非全部数据包中包含额外的随机数据(发生在某些 PPP-over-ISDN 接
口上)- 因此在 PPP 接口上使用 SLL 伪链路层。由于一台机器的所有接口并非必须具有相同的链路层类型,但是为使捕获
过滤器起作用,同一接口上的所有数据包必须具有相同类型的链路层头,所以在“any”上使用 SLL。
在 Linux 中,当从“any”设备或其它设备捕获数据包时,libpcap 不提供真正的“硬件协议”(比如 Ethernet)的链路层
头,而是为该伪协议提供虚假的链路层头。
“SLL”代表“sockaddr_ll”,在“cooked 模式”下,通过从 套接字(而不是通常用于捕 PF_PACKET/SOCK_DGRAM
获的 套接字)读取的方式,完成捕获。使用 而不是 意味着 PF_PACKET/SOCK_RAW SOCK_DGRAM SOCK_RAW
Linux 套接字代码不提供数据包的链路层头。这意味着链路层协议的数据包类型字段等信息不可用,因此当 libpcap 在套接
字上执行 recvfrom() 时,从提供的地址构造合成的链路层头。在 套接字中,该地址的类型是 PF_PACKET sockaddr_ll
,其中“ll”很可能代表“link layer”;该结构中的字段以 开头。请参阅 Linux 系统上的 packet(7) 手册页,获取更 sll_
多详细信息。
2. SLL 数据包结构
+---------------------------+
| Packet type |
| (2 Octets) |
+---------------------------+
| ARPHRD_ type |
| (2 Octets) |
+---------------------------+
| Link-layer address length |
| (2 Octets) |
+---------------------------+
| Link-layer address |
| (8 Octets) |
+---------------------------+
| Protocol type |
| (2 Octets) |
+---------------------------+
| Payload |
. .
. .
. .
2.1 描述
数据包类型字段以网络字节顺序(大端序)表示,它包含以下值之一:
0,如果数据包是由其他人专门发送给我们的;
1,如果数据包是由其他人广播的;
2,如果数据包是由其他人组播(但不是广播)的;
3,如果数据包是由其他人发送给其他人的;
4,如果数据包是由我们发送的。
类型字段以网络字节序表示;它包含表示链路层设备类型的 Linux 值。 ARPHRD_ ARPHRD_
链路层地址长度字段以网络字节序表示;它包含数据包发送者的链路层地址长度。该长度可能为 0。
链路层地址字段包含数据包发送者的链路层地址;该字段中有意义的字节数由链路层地址长度字段指定。如果超过 8 个字
节,那么只有前 8 个字节存在;如果少于 8 个字节,那么地址后面有填充字节,将字段填充至 8 个字节。
协议类型字段以网络字节序表示。
如果 类型为 (824),那么数据包数据,包括 头,是 ARPHRD_ ARPHRD_NETLINK LINKTYPE_LINUX_SLL
数据包,其中协议类型字段是 协议类型。 如果 类型是 LINKTYPE_NETLINK Netlink ARPHRD_ ARPHRD_IPGRE
(778),那么协议类型字段包含 GRE 协议类型。 如果 类型为 ARPHRD_ ARPHRD_IEEE80211_RADIOTAP
(803),那么协议类型字段将被忽略, 头之后的有效载荷以 Radiotap 链路层信息(紧跟着一个 LINKTYPE_LINUX_SLL
802.11 头)开头。 如果 类型为 (770),那么协议类型字段将被忽略, ARPHRD_ ARPHRD_FRAD
头之后的有效载荷是 Frame Relay LAPF 帧,以 ITU-T 建议 Q.922 LAPF 头开头(以地址字段开LINKTYPE_LINUX_SLL
始,并且帧的尾部没有 FCS)。
否则,协议类型字段包含数据包的以太网协议类型,或者以下之一:
,如果帧是没有 802.2 LLC 头的 Novell 802.3 帧; 0x0001
,在某些神秘情况下; 0x0003
,如果帧以 802.2 LLC 头开头; 0x0004
,如果帧是 CAN 总线帧; 0x000C
,如果帧是 CAN FD(CAN with Flexible Data-Rate)帧 0x000D
3. 参考文档
https://wiki.wireshark.org/SLL
https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html