c - 原始套接字监听器

标签 c linux sockets network-programming

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

最佳答案

您是对的,您唯一需要做的就是调用 socket(),然后调用 recvfrom()。不过请注意,使用 SOCK_RAW 收听有一些限制。

If you're not using raw sockets on a "send-and-forget" basis, you will be interested in reading the reply packet(s) for your raw packet(s). The decision logic for whether a packet will be delivered to a raw socket can be enumarated as such:

  1. TCP and UDP packets are never delivered to raw sockets, they are always handled by the kernel protocol stack.

  2. Copies of ICMP packets are delivered to a matching raw socket. For some of the ICMP types (ICMP echo request, ICMP timestamp request, mask request) the kernel, at the same time, may wish to do some processing and generate replies.

  3. All IGMP packets are delivered to raw sockets: e.g. OSPF packets.

  4. All other packets destined for protocols that are not processed by a kernel subsystem are delivered to raw sockets.

The fact that you're dealing with a protocol for which reply packets are delivered to your raw socket does not necessarily mean that you'll get the reply packet. For this you may also need to consider:

  1. setting the protocol accordingly while creating your socket via socket(2)system call. For instance, if you're sending an ICMP echo-request packet, and want to receive ICMP echo-reply, you can set the protocol argument (3rd argument) to IPPROTO_ICMP).

  2. setting the protocol argument in socket(2) to 0, so any protocol number in the received packet header will match.

  3. defining a local address for your socket (via e.g. bind(2)), so if the destination address matches the socket's local address, it'll be delivered to your application also.

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

关于c - 原始套接字监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13082023/

相关文章:

c - C中递归的二维数组

java - 查找包含可变数量元素的可变数量数组的排列的有效方法

linux - 保存在变量中时,字符串中的制表符消失

regex - 重命名文件夹及其子文件夹的文件

python - (Python) 尝试一次扫描一个 IP 地址的端口范围时出现错误

c - 一个可以玩两手五张牌的函数?

c - 如何使 getch() 函数采用双字符而不是一个?

linux - Ocaml brew 中的 Utop 抛出错误

c# - TCP Socket Server - 一种检测传入数据的方法

java - 如何使用java套接字通过两个不同的wifi连接两台电脑?