0

我想创建一个 IP 隧道。为此,我在客户端的 C# 中创建了一个原始套接字并将其绑定到端口 4999:

Socket mysock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
mysock.Bind(new IPEndPoint(IPAddress.Loopback, 4999));
mysock.Connect(new IPEndPoint(IPAddress.Loopback, 4999));

现在我可以调用mysock.Receive(byte[]),我得到所有的 IP 数据包,包括 IP 标头。例如,如果我尝试打开与 的 TCP 连接127.0.0.1:4999,C# 应用程序会捕获 3 个数据包。我也可以通过这个套接字发送数据包,它会工作得很好。

然后 C# 应用程序将这些数据包传输到在 linux 机器上运行的 C++ 应用程序。在那里,我更改了发送端口(这很简单,只需将其写入 TCP 标头),然后我想简单地将其发送出去并为我完成所有其他工作,就像它在 C# 中工作一样。显然,我还想从原始 linux 套接字接收数据包,这样我就可以将它们传输回 C# 应用程序并进行一些通信。

我已经实现了除原始 linux socket 之外的所有内容那是我的问题:如何在 C/C++ for linux 中编写上述 C# 代码?根据raw(7),如果我这样做,我不会得到 TCP 或 UDP 数据包socket(AF_INET, SOCK_RAW, IPPROTO_RAW),对吧?

编辑:顺便说一句,我在 Windows 上运行 C# 代码,但这不是我的问题。

4

1 回答 1

0

不。

在这种情况下,端口号不应是 TCP 或 UDP 端口号。

它应该是(我不确定)更高级别的协议标识符(例如,“端口号”为 6 表示:TCP 数据包,而 17 表示:UDP 数据包)。当前的 Linux 版本说原始套接字的端口号必须为 0。应用程序需要“root”权限。

Windows中的差异(与 Linux 相比):

Windows 文档说(仅)允许 ICMP 和 IGMP 数据包使用原始套接字。

使用 winpcap 库应该允许程序获得对以太网卡的原始访问权限。但是,在这种情况下,您还会看到 14 字节的以太网报头(在 IP 报头之前),并且您将收到各种以太网数据包(在正常的 TCP/IP 网络中,这些数据包应该是 ARP、IPv4、IPv6 和 STP)和不仅是 IPv4 数据包。

winpcap 有一个 .NET 包装器,因此您也应该能够将 winpcap 与 C# 一起使用。

于 2013-09-26T19:55:35.243 回答