關於C#的RawSocket編程的問題

來源:互聯網
上載者:User

Q:你好!

看過了你在csdn上發表的《用C#下的Raw Socket編程實現網路封包監視》,覺得高度興趣,而且對我的協助很大。不過在調試的過程中遇到一些問題,特此向你請教一下。謝謝!

首先

socket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.HeaderIncluded, 1);

     byte []IN = new byte[4]{1, 0, 0, 0};

     byte []OUT = new byte[4];

     //低層級操作模式,接受所有的資料包,這一步是關鍵必須把socket設成raw和IPLevel才可用SIO_RCVALL

     int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);

     ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];//把4個8位位元組合成一個32位整數

     if(ret_code != 0) ret_value = false;

應改是用來設定socket的工作方式的,我想知道的是你所是值得常量SIO_RCVALL = 0x98000001是如何得到的(我是指後面的十六進位數十怎麼得到的),有沒有相關的文檔推薦一下。我看過一些,不過沒有眉目。這些數字應該是什麼所謂的操作控制碼,但我找不到更詳細的資料,希望能指點一下。另外,在第二行中那個IN數組為什麼要那麼設定,這點我還不太明白。

第二

e.HeaderLength=(uint)(head->ip_verlen & 0x0F) << 2;

 

在這句話中,你是想要得到資料包的IP頭長,從IP的結構來看,似乎是不應該移位(即左移兩位)的,因為屏蔽掉前前四位之後,所剩的四位正好為頭長,不知這個地方是否有問題。

第三

     這段代碼是由原始通訊端作封包監視,但不知能否實現資料包的攔截。因為如果可以的話就可以實現放火牆的功能了。

 

不好意思!

第一次給你發信就問了這麼一大堆,耽誤了你的時間!

再次表示感謝!

 

等待你的回信:)

A:

第一.
在winsock2.h中定義了以下宏:
#define IOC_VOID        0x20000000      /* no parameters */
#define IOC_OUT         0x40000000      /* copy out parameters */
#define IOC_IN          0x80000000      /* copy in parameters */

#define IOC_UNIX                      0x00000000
#define IOC_WS2                       0x08000000
#define IOC_PROTOCOL                  0x10000000
#define IOC_VENDOR                    0x18000000

#define _WSAIO(x,y)                   (IOC_VOID|(x)|(y))
#define _WSAIOR(x,y)                  (IOC_OUT|(x)|(y))
#define _WSAIOW(x,y)                  (IOC_IN|(x)|(y))
#define _WSAIORW(x,y)                 (IOC_INOUT|(x)|(y))

裡面沒有SIO_RCVALL的定義,但是你可以查看msdn中的ms-help://MS.MSDNQTR.2003FEB.2052/winsock/winsock/wsaioctl_2.htm看WSAIoctl函數中的SIO_RCVALL 的說明,你可以知道它是這樣定義的:
#define SIO_RCVALL   _WSAIOW(IOC_VENDOR,1)
即:
0x80000000|0x18000000|0x00000001
其中IOC_VENDOR 實際上是IOC_WS2|IOC_PROTOCOL ,因為要receive all IP packets on the network on win32 platform.

至於用四位元組數組來接收資料流,是因為網路資料流串列的在網線傳輸,需要接收到32位(二進位)後才能對該串列流進行解析,這是一種串列通訊協定,當接收到32位後,網卡會把這32位(二進位)傳給一個四位元組數組。因為要和IOControl的傳回值保持一致,返回的是32位的int32,所以要把out〔〕數組整合成int。至於byte []IN = new byte[4]{1, 0, 0, 0};這樣定義是,因為這樣整合成的整形數是(十六進位) 00 00 00 01 ,即1,輸入32位元的值為一,是因為要把socket設定成非阻塞狀態(which is nonzero if nonblocking mode is to be enabled and zero if it is to be disabled. )。而out得到的是一次接收操作中得到的位元組數 (returns the total amount of data that can be read in a single receive operation; )。

第二:

資料包包頭長的值為4位二進位,範圍0-15,如果不移位的話包頭長度不會超過15位元組,怎麼會?正如上面所說。每32位二進位是一個網路串列通訊的資料單元,描述包頭長的四位記錄的是資料單元數,不是位元組數,所以要乘與四(32bit資料單元長度/8bit位元組長度),即左移二位。

第三:

基於.net的raw socket是基於winsock2來實現的,它實現在七層模型的應用程式層,而應用程式層的封包攔截向來很弱,一般在應用程式層實現可用spi(服務提供者),其實這需要系統調用。我試過,在.net下效果不是太好,資料包要麼全部都攔住了,要麼全部允許存取,系統反應很慢,穩定性很弱,呵呵,這是.net的隱痛。一種比較流行的做法是寫網路層的ndis驅動程式,ndis hook driver和ndis中介層驅動都可以,其中ndis中介層驅動功能強大,不光可以進行封包攔截,還可以實現對網路資料流的加密,強烈建議使用!

至於在.net下做防火牆,可用managed C++做來DeviceIoControl,可以查看我的文章:
http://www.csdn.net/develop/read_article.asp?id=21480

獲得RawSocket的C#原始碼請訪問:http://www.mscenter.edu.cn/blog/seafrog/archive/2005/05/30/2866.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.