2013-09-26 100 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部分的幫助。 –

相關問題