如何拦截进入内核的IP数据包Linux

How to intercept IP packets going to the kernel Linux

我需要“手动”创建 TCP 会话,而不使用 connect() 函数。我曾尝试使用 RAW 套接字。但在这种情况下,我只获得传入 IP 数据包的副本。原始传入的数据包溜进了内核,它生成了一个破坏我的协议的 ACK 响应数据包。

接下来,变体 2,我可以编写一个虚拟 eth 接口驱动程序(内核模块)并使用 iptables 将传入流量路由到它。但是机器上有一个打过补丁的非原始(非vanila)内核。无法使用内核正常 linking 模块。

变体 3. 我也尝试过不为 NIC 接口分配 IP 地址。在这种情况下,内核中的网络 TCP/IP 层模块未激活,并且可以使用 PF_PACKET 套接字域在 link (以太网)层上生成和接收任意 IP 数据包输入 socket() 函数。但是此时,任何其他使用TCP/IP协议的应用程序都无法工作。

如何通过其他方式解决这个问题?

如果能够拦截从网络接口到内核的数据包就好了,也就是拦截SKBuf缓冲区。但是不知道怎么实现。

显然您正在尝试创建隧道。创建隧道的正确方法不是尝试劫持现有接口,而是使用内核模块或 TUN/TAP 创建一个新接口。然而,隧道通常用于接收在运行隧道软件的机器上生成的流量,或者至少通过它路由。这意味着您还必须设置内核以将流量路由到您的隧道。

您可以创建一个新界面作为 TUN/TAP interface。它就像一个虚拟以太网驱动程序,只是您不需要编写新的内核模块。它专为隧道设计(因此得名)。

TUN 和 TAP 的区别在于 TUN 接口是一个 IP 接口,它从内核的 IP 路由系统接收 IP 数据包,而 TAP 接口接收以太网数据包(可能包含 IP 数据包),因此它也可以是网桥的一部分(虚拟以太网交换机 - 只查看以太网报头,不查看 IP 报头)。

我认为对于您的场景,您会发现最简单的方法是创建一个 TAP 接口,然后在 TAP 接口和另一台主机所连接的接口之间创建一个网桥(虚拟以太网交换机)。两者都不需要 IP 地址 - 内核将愉快地传递 Ethernet-layer 流量,而无需尝试处理数据包中的 IP 信息。然后,您的隧道软件可以模拟主机 - 或连接到实际主机的隧道 - 或任何您希望它执行的操作。

或视觉形式:

如果您希望主机 能够与机器对话 运行 隧道软件 - 无需通过隧道软件 - 那么您可以选择在网桥上放置一个 IP 地址。