我正在尝试为 Linux 编写一个 C 嗅探器,并了解嗅探时内核中发生的操作。
我无法找到以下问题的答案: 如果我通过以下方式初始化套接字:
sock_raw = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL));
内核中发生了什么?我如何看到所有传入和传出的数据包,但不“劫持”它们?因为我到目前为止所理解的是,当内核收到数据包时,它将其发送到相关的协议处理函数。因此我无法理解 - 除了我打开的套接字之外,内核还会克隆数据包并发送它吗?
内核中发生了什么?
内核一旦从物理层接收到数据包(对于传入数据包)或在将它们发送到物理层(对于传出数据包)之前,就会简单地复制数据包。每个数据包的一份副本将发送到您的套接字。如果您使用 ETH_P_ALL
,那么您正在监听所有接口,但您也可以
bind(2)
监听特定接口。将副本发送到套接字后,另一个副本将像平常一样继续处理。例如,识别和解码协议、检查防火墙规则等
我如何看到所有传入和传出的数据包,而不是“劫持”它们?
,您需要将数据为了发生
劫持
写入到注入新数据包的套接字(根据您想要劫持的协议准确制作)。如果您只读取传入的数据包,那么您只是嗅探,而没有劫持任何东西。 除了我打开的套接字之外,内核是否克隆数据包并发送它?
可以帮助您直观地看到它(点击放大):是的,基本上就是这样。
这张图片
man 7 packet
数据包套接字用于在设备驱动程序(OSI 第 2 层)级别接收或发送原始数据包。它们允许用户在物理层之上的用户空间中实现协议模块。
是包含链路级标头的原始数据包的
socket_type
SOCK_RAW
,或者是删除了链路级标头的熟数据包的SOCK_DGRAM
。链路级标头信息以sockaddr_ll
结构中的通用格式提供。protocol
是网络字节顺序中的 IEEE 802.3 协议号。请参阅<linux/if_ether.h>
包含文件以获取允许的协议列表。当protocol
设置为htons(ETH_P_ALL)
时,则接收所有协议。该协议类型的所有传入数据包将先传递到数据包套接字,然后再传递到内核中实现的协议。