一尘不染

原始套接字监听器

linux

对于linux
c编程原始套接字,这是一个快速的问题。如果我只想使用原始套接字来监听任何接口,我是否真的必须绑定到ip地址或接口来监听流量?据我了解,我觉得我应该能够只调用sock();。然后启动recvfrom()流量。也许我错了,但是我看过一些不使用它的程序。


阅读 240

收藏
2020-06-07

共1个答案

一尘不染

没错,您唯一需要做的就是打电话给socket()then recvfrom()。不过请注意,使用收听存在一些限制SOCK_RAW

如果您不是在“发送后忘记”的基础上使用原始套接字,那么您将有兴趣阅读原始数据包的回复数据包。数据包是否将被传递到原始套接字的决策逻辑可以这样放大:

  1. TCP和UDP数据包永远不会传递到原始套接字,它们始终由内核协议栈处理。

2.
ICMP数据包的副本将传递到匹配的原始套接字。对于某些ICMP类型(ICMP回显请求,ICMP时间戳请求,掩码请求),内核可能希望同时进行一些处理并生成答复。

  1. 所有IGMP数据包都传递到原始套接字:例如OSPF数据包。

  2. 指定给协议的所有其他未由内核子系统处理的数据包都传递到原始套接字。

您正在处理将答复数据包传递到原始套接字的协议这一事实并不一定意味着您将获得答复数据包。为此,您可能还需要考虑:

1.
通过socket(2)system调用创建套接字时,相应地设置协议。例如,如果您要发送ICMP回显请求数据包,并且想要接收ICMP回显应答,则可以将协议参数(第3个参数)设置为IPPROTO_ICMP)。

  1. 将socket(2)中的协议参数设置为0,以便接收到的数据包头中的任何协议号都将匹配。

  2. 为套接字定义一个本地地址(例如通过bind(2)),因此,如果目标地址与套接字的本地地址匹配,它也将被传递到您的应用程序。

有关更多详细信息,您可以阅读例如this

2020-06-07