【问题标题】:raw socket listener原始套接字侦听器
【发布时间】:2012-10-16 10:18:45
【问题描述】:

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

【问题讨论】:

    标签: c linux sockets network-programming


    【解决方案1】:

    如果您要捕获接口上的流量,可以使用 libpcap。

    【讨论】:

    • 感谢您的建议,我可能会使用 libpcap 而不是 bpf,因为它似乎更容易分析数据包。我今天学到了一些东西!
    【解决方案2】:

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

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

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

    2. ICMP 数据包的副本被传递到匹配的原始套接字。对于某些 ICMP 类型(ICMP 回显请求、ICMP 时间戳请求、 mask request) 内核,同时,不妨做一些 处理并生成回复。

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

    4. 所有其他发往未被内核子系统处理的协议的数据包都被传递到原始套接字。

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

    1. 在通过 socket(2) 系统调用创建套接字时相应地设置协议。例如,如果您要发送 ICMP echo-r​​equest 包,想要接收 ICMP echo-r​​eply,可以设置 IPPROTO_ICMP 的协议参数(第三个参数)。

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

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

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

    【讨论】:

    • 100 万谢谢!:) 我找不到任何关于在原始套接字上接收数据包的好信息,但再次感谢您启发我。现在我知道如果我想进入原始套接字,我应该使用 bpf。
    • 很好的答案。最终链接目前不可用(也许只是暂时的?)但在web.archive.org/web/20190716060924/http://www.enderunix.org/…
    猜你喜欢
    • 2015-01-20
    • 2011-04-30
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    相关资源
    最近更新 更多