【问题标题】:How does the AF_PACKET socket work in Linux?AF_PACKET 套接字在 Linux 中是如何工作的?
【发布时间】:2020-11-02 02:56:57
【问题描述】:

我正在尝试为 Linux 编写一个 C 嗅探器,并了解嗅探时内核中发生的操作。

我无法找到以下问题的答案: 如果我按以下方式初始化我的套接字:

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

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

【问题讨论】:

  • man packet: "当协议设置为 htons(ETH_P_ALL) 时,所有协议都会被接收。该协议类型的所有传入数据包将在传递给协议之前传递给数据包套接字在内核中实现。”

标签: c linux sockets linux-kernel


【解决方案1】:

内核中发生了什么?

内核只是简单地复制数据包从物理层接收到数据包(对于传入的数据包)或在将它们发送出去之前到物理层(对于传出数据包)。每个数据包的一个副本被发送到您的套接字(如果您使用ETH_PH_ALL,那么您正在侦听所有接口,但您也可以bind(2) 到特定接口)。将副本发送到您的套接字后,另一个副本将继续像往常一样进行处理(例如识别和解码协议、检查防火墙规则等)。

我如何查看所有传入和传出的数据包,而不是“劫持”它们?

为了使hijacking 发生,您需要写入 数据到注入新数据包的套接字(根据您要劫持的协议精确制作)。如果你只读取传入的数据包,你只是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) 时,则接收所有协议。 该协议类型的所有传入数据包将在传递到内核中实现的协议之前传递到数据包套接字。

【讨论】:

    猜你喜欢
    • 2010-11-22
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2021-07-02
    • 2018-11-14
    • 1970-01-01
    • 2014-07-04
    相关资源
    最近更新 更多