这是 linux c 编程原始套接字的一个快速问题。如果我只想用原始套接字监听任何接口,我必须实际绑定到 IP 地址或接口来监听流量吗?据我了解,我觉得我应该能够调用 sock(); 然后开始 recvfrom() 流量。也许我错了,但我见过一些不使用它的程序。
2 回答
你是对的,你唯一需要做的就是打电话socket()
,然后recvfrom()
。不过请注意,使用SOCK_RAW
.
如果您没有在“发送后忘记”的基础上使用原始套接字,您将对读取原始数据包的回复数据包感兴趣。是否将数据包传递到原始套接字的决策逻辑可以枚举如下:
TCP 和 UDP 数据包永远不会传递到原始套接字,它们总是由内核协议栈处理。
ICMP 数据包的副本被传递到匹配的原始套接字。对于某些 ICMP 类型(ICMP 回显请求、ICMP 时间戳请求、掩码请求),内核可能希望同时进行一些处理并生成回复。
所有 IGMP 数据包都被传递到原始套接字:例如 OSPF 数据包。
所有其他发往未由内核子系统处理的协议的数据包都被传递到原始套接字。
您正在处理将回复数据包传递到原始套接字的协议这一事实并不一定意味着您将获得回复数据包。为此,您可能还需要考虑:
在通过 socket(2) 系统调用创建套接字时相应地设置协议。例如,如果您正在发送 ICMP echo-request 数据包,并且想要接收 ICMP echo-reply,则可以将协议参数(第三个参数)设置为 IPPROTO_ICMP)。
将 socket(2) 中的协议参数设置为 0,因此接收到的数据包头中的任何协议号都将匹配。
为你的套接字定义一个本地地址(例如通过bind(2)),所以如果目标地址与套接字的本地地址匹配,它也会被传送到你的应用程序。
有关更多详细信息,您可以阅读例如this。
如果您打算捕获接口上的流量,则可以使用 libpcap。