我想创建一个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头。例如,如果我尝试打开到127.0.0.1:4999
的TCP连接,则C#应用程序会捕获3个数据包。我也可以通过这个套接字发送数据包,它可以正常工作。
然后,C#应用程序将这些数据包传输到Linux机器上运行的C ++应用程序。在那里,我更改了发送端口(这是简单的部分,只需将其写入TCP标头)然后我想简单地发送它并为我完成其他所有操作,就像它在C#中工作一样。显然,我还希望从原始linux套接字接收数据包,因此我可以将它们传回C#应用程序并进行一些通信。
我已经实现了除了原始linux套接字之外的所有内容。 这是我的问题:如何在C / C ++ for linux中编写上述C#代码?根据{{3}},如果我只做socket(AF_INET, SOCK_RAW, IPPROTO_RAW)
,我将不会获得TCP或UDP数据包,对吗?
编辑:顺便说一句,我在Windows上运行C#代码,但这不是我的问题。
答案 0 :(得分: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包装器,所以你也可以使用带有C#的winpcap。