2013-09-26 66 views
0

我想创建一个IP隧道。对于这一点,我在客户端上创建C#中的原始套接字并将其绑定到端口4999:在原始linux套接字上接收来自任何协议的数据包

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#代码?根据raw(7),如果我只是做socket(AF_INET, SOCK_RAW, IPPROTO_RAW),我不会得到TCP或UDP数据包,对不对?

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

+0

如果您使用的是C++,像Boost这样的库,Berkeley套接字将成为CIMHO的首选选项,其中包含更接近C#代码的Berkeley封装你发布了。 –

+0

@AllanElder看我的编辑。 –

回答

0

编号

在这种情况下,端口号不应该是TCP或UDP端口号。它应该是(我不确定)更高级别的协议标识符(例如,“端口号”为6意味着:TCP分组,而17意味着:UDP分组)。目前的Linux版本表示原始套接字的端口号必须为0。应用程序需要“根”权限。

的差异的Windows(相对于Linux的):

在Windows文件说,原始套接字所允许的ICMP和IGMP数据包(只)。

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

有一个winpcap的.NET包装器,所以你应该也可以在C#中使用winpcap。

+0

您正在谈论协议标识符。但我希望能够在不关心传输层的情况下传输IP数据包。 –

+0

@ main--:我编辑了我的答案。 –

+0

谢谢,但你误会我的问题。 Windows部分工作得很好,我只需要Linux部分的帮助。 –

相关问题