对于我的应用程序,我需要拦截某些 TCP/IP 数据包并通过自定义通信链路(不是以太网)将它们路由到不同的设备。我需要所有 TCP 控制数据包和完整标头。我已经弄清楚了如何使用原始套接字(使用 socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))获取它们。这很有效,并允许我附加过滤器以仅查看我感兴趣的 TCP 端口。
但是,Linux 也能看到这些数据包。默认情况下,当它收到一个数据包到它不知道的端口号时,它会发送一个 RST。这没什么用,因为我打算稍后自己发回一个响应。如果我使用 socket(PF_INET, SOCK_STREAM, 0) 和 listen() 在同一个端口上打开第二个“正常”套接字,Linux 就会向传入的 TCP 数据包发送 ACK。这两个选项都不是我想要的。我希望它能做到没有什么有了这些数据包,我就可以自己处理所有事情了。我该如何实现这一点?
答案1
iptables
您可以将这些数据包丢弃在 FILTER 表的 OUTPUT 链中。
协议
RFC 793 (TCP) 指定了 RST 发送行为
SEGMENT ARRIVES
If the state is CLOSED (i.e., TCB does not exist) then [...]:
An incoming segment not containing a RST causes a RST to be sent in response.
并且Linux显然正确地实现了它。
sysctl 接口
似乎该行为也无法通过 sysctl 接口进行调整(参见TCP(7))。无论如何,如果您还没有读过该手册页,那它绝对是一本值得一读的书。
内核代码
根据您实际想要实现的目标,直接改变内核代码可能是一种选择。