5

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

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

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

感谢您的时间。

--

4

2 回答 2

3

raw(7)的手册页说:

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

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

于 2011-02-14T01:47:22.757 回答
2

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

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

于 2011-02-14T03:03:00.710 回答