AF_PACKET套接字在Linux中如何工作?

xyhw6mcr  于 2023-03-22  发布在  Linux
关注(0)|答案(1)|浏览(226)

我正在尝试为Linux编写一个C嗅探器,并了解嗅探时内核中发生的操作。
我很难找到以下问题的答案:如果我用下面的方法初始化我的socket:

sock_raw = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL));

在内核中发生了什么?我怎么能看到所有传入和传出的数据包,而不是“劫持”它们?因为我所理解的是,当内核接收到一个数据包时,它会将其发送到相关的协议处理函数。因此我不明白-内核是否克隆了数据包,并将其发送到我打开的套接字之外?

vktxenjb

vktxenjb1#

内核中发生了什么?
内核只是简单地复制数据包 * 一旦它从物理层收到它们 *(对于传入的数据包)或 * 就在将它们发送出去 * 到物理层之前每个包的一个副本被发送到你的套接字(如果你使用ETH_PH_ALL,那么你监听所有的接口,但是你也可以bind(2)监听某个特定的接口)。然后,另一个副本继续像正常情况那样被处理(例如,识别和解码协议、检查防火墙规则等)。
我如何看到所有传入和传出的数据包,但不“劫持”它们?
为了让hijacking发生,你需要向socket * 写 * 数据,注入新的数据包(根据你想要劫持的协议精确地制作)。如果你只 * 读 * 传入的数据包,你只是sniffing,没有劫持任何东西。
内核是否会克隆数据包并将其发送到我打开的套接字之外?
是的,基本上就是这样。This image可以帮助你可视化它(点击放大):

man 7 packet也描述了这一点:
包套接字用于在设备驱动(OSI第2层)层接收或发送原始包。它们允许用户在物理层之上的用户空间实现协议模块。
socket_typeSOCK_RAW(用于包含链路级报头的原始数据包)或SOCK_DGRAM(用于删除了链路级报头的熟数据包)。链路级报头信息以sockaddr_ll结构中的通用格式提供。protocol是IEEE 802.3协议编号(按网络字节顺序)。有关允许的协议列表,请参阅<linux/if_ether.h>包含文件。当protocol设置为htons(ETH_P_ALL)时,将接收所有协议。该协议类型的所有传入数据包将在传递到内核中实现的协议之前传递到数据包套接字。

相关问题