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