AF_PACKET 套接字在 Linux 中如何工作?
How does the AF_PACKET socket work in Linux?
我正在尝试为 Linux 编写一个 C 嗅探器,并在嗅探时了解内核中发生的操作。
我无法找到以下问题的答案:
如果我按以下方式初始化套接字:
sock_raw = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL));
内核中发生了什么?我如何看到所有传入和传出的数据包,而不是“劫持”它们?因为我所理解的是,当内核接收到一个数据包时,它会将它发送到相关的协议处理函数。因此我无法理解 - 除了我打开的套接字之外,内核是否克隆数据包并发送它?
What happens in the kernel?
内核在从物理层(对于传入数据包)接收到数据包 或发送数据包之前[=39] 简单地复制数据包 =] 到物理层(用于传出数据包)。每个数据包的一个副本被发送到您的套接字(如果您使用 ETH_PH_ALL
那么您正在监听所有接口,但您也可以 bind(2)
到一个特定的接口)。将一个副本发送到您的套接字后,另一个副本将像往常一样继续处理(例如识别和解码协议、检查防火墙规则等)。
How am I seeing all the incoming and outgoing packets, but not "hijacking" them?
为了hijacking to happen, you would need to write data to the socket injecting new packets (accurately crafted depending on the protocol you want to hijack). If you only read incoming packets, you are merely sniffing,没有劫持任何东西。
does the kernel clone the packet and sends it in addition to the socket I opened?
是的,基本上就是这样。 This image 可以帮助您想象它。
man 7 packet
也这样描述:
Packet sockets are used to receive or send raw packets at the device driver (OSI Layer 2) level. They allow the user to implement protocol modules in user space on top of the physical layer.
The socket_type
is either SOCK_RAW
for raw packets including the link-level header or SOCK_DGRAM
for cooked packets with the link-level header removed. The link-level header information is available in a common format in a sockaddr_ll
structure. protocol
is the IEEE 802.3 protocol number in network byte order. See the <linux/if_ether.h>
include file for a list of allowed protocols. When protocol
is set to htons(ETH_P_ALL)
, then all protocols are received. All incoming packets of that protocol type will be passed to the packet socket before they are passed to the protocols implemented in the kernel.
我正在尝试为 Linux 编写一个 C 嗅探器,并在嗅探时了解内核中发生的操作。
我无法找到以下问题的答案: 如果我按以下方式初始化套接字:
sock_raw = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL));
内核中发生了什么?我如何看到所有传入和传出的数据包,而不是“劫持”它们?因为我所理解的是,当内核接收到一个数据包时,它会将它发送到相关的协议处理函数。因此我无法理解 - 除了我打开的套接字之外,内核是否克隆数据包并发送它?
What happens in the kernel?
内核在从物理层(对于传入数据包)接收到数据包 或发送数据包之前[=39] 简单地复制数据包 =] 到物理层(用于传出数据包)。每个数据包的一个副本被发送到您的套接字(如果您使用 ETH_PH_ALL
那么您正在监听所有接口,但您也可以 bind(2)
到一个特定的接口)。将一个副本发送到您的套接字后,另一个副本将像往常一样继续处理(例如识别和解码协议、检查防火墙规则等)。
How am I seeing all the incoming and outgoing packets, but not "hijacking" them?
为了hijacking to happen, you would need to write data to the socket injecting new packets (accurately crafted depending on the protocol you want to hijack). If you only read incoming packets, you are merely sniffing,没有劫持任何东西。
does the kernel clone the packet and sends it in addition to the socket I opened?
是的,基本上就是这样。 This image 可以帮助您想象它。
man 7 packet
也这样描述:
Packet sockets are used to receive or send raw packets at the device driver (OSI Layer 2) level. They allow the user to implement protocol modules in user space on top of the physical layer.
The
socket_type
is eitherSOCK_RAW
for raw packets including the link-level header orSOCK_DGRAM
for cooked packets with the link-level header removed. The link-level header information is available in a common format in asockaddr_ll
structure.protocol
is the IEEE 802.3 protocol number in network byte order. See the<linux/if_ether.h>
include file for a list of allowed protocols. Whenprotocol
is set tohtons(ETH_P_ALL)
, then all protocols are received. All incoming packets of that protocol type will be passed to the packet socket before they are passed to the protocols implemented in the kernel.