【问题标题】:How to bind a Raw Socket to a specific port?如何将原始套接字绑定到特定端口?
【发布时间】:2011-02-14 01:00:36
【问题描述】:

我目前正在从事一项编程任务。任务是实现客户端、网络仿真器和服务器。客户端将数据包传递给网络模拟器,而网络模拟器则传递给服务器。反之亦然。分配的先决条件是我只能使用原始套接字。因此,我将创建自己的 IP 和 UDP 标头。我已经用wireshark测试了我的数据包。它们都是正确的并且格式正确(它可以正确读取它们)。

另一个要求是模拟器、客户端和服务器都必须绑定特定的端口。现在,我不明白如何将原始套接字绑定到特定端口。我所有的原始套接字都在它们绑定的主机地址上接收所有流量。根据手册页和互联网上的其他任何地方,包括 Richard Stevens 的“Unix Network Programming”,它们应该是这样工作的。我的老师没有回复我的任何电子邮件,我可能要到周二才能问他。我看到了两个选项。首先,我可以使用 libpcap 从特定设备中过滤,然后输出到我的原始套接字。我觉得这超出了我们的任务范围。或者我可以在从套接字接收到它们后过滤它们。这显然有很多开销,因为所有数据包都通过内核复制/移动。至少,这是我的理解(如果我错了,请随时纠正我)。

所以我的问题是: 他们是一个选项还是我可以为此设置的东西?原始套接字将在哪里绑定到端口?我错过了什么明显的东西吗?

感谢您的宝贵时间。

--

【问题讨论】:

    标签: c network-programming raw-sockets


    【解决方案1】:

    man page for raw(7) 说:

    可以使用 bind(2) 调用将原始套接字绑定到特定的本地地址。如果没有绑定指定IP协议的所有数据包都会被接收。此外,可以使用 SO_BINDTODEVICE 将 RAW 套接字绑定到特定的网络设备;见套接字(7)。

    编辑:您不能将原始套接字绑定到特定端口,因为“端口”是 TCP 和 UDP 中的概念,而不是 IP。查看这三个协议的标头图,应该会很明显:​​您在较低级别工作,端口的概念是未知的。

    【讨论】:

    • 所以,为了确保我正确解释了这一点,我无法绑定到特定端口?如果是这种情况,您将如何实现“过滤器”? Libpcap 到特定设备并过滤端口,或者因为这仅用于分配,所以在套接字接收它们后将它们过滤掉?或者您是否有更好的实施方式?顺便感谢您的回复和时间。
    • 查看我的回答中的编辑。我认为你在正确的轨道上。
    • “端口”是传输协议的结构。从网络级别 (IP) 来看,数据包被寻址到地址。实现“端口”语义是更高级别的传输协议的工作。我想你必须自己解码接收到的数据包,以确定它被寻址到哪个“端口”并相应地过滤。
    • 还有圣诞老人,感谢您的帮助。我将继续在程序中通过端口字段的比较来执行此操作。我还有另一个问题。我是董事会的新手,我想知道我是否将这个问题标记为已回答或什么?
    【解决方案2】:

    我认为您应该过滤软件中的数据包。听起来这个练习是通过在用户空间中重新创建一个简化的部分来了解 IP 堆栈的不同组件的作用。通常在内核中,IP 代码会处理所有数据包、验证 IP 标头、重组片段并检查协议字段。如果协议字段为 17 (udp),则将其传递给 UDP 代码(每个 UDP 数据包)。然后由 UDP 代码验证 UDP 标头并根据目标端口确定是否有任何应用程序对它们感兴趣。

    我想您的项目或多或少会模仿这个过程。显然,没有一个比在内核中执行效率更高,但由于任务是在用户空间中编写(部分)IP 堆栈,我猜效率不是练习的重点。

    【讨论】:

      猜你喜欢
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多