摘要:數據捕獲是網絡應用和網絡安全方面的一個核心內容,利用它可以捕獲所有經過網絡的數據包或者感興趣的特定數據包。可以利用多種方法來捕獲網絡數據包,在Windows環境中利用NDIS驅動方式來實現是最直接也是最有效率的一種方式,本文對捕獲原理和實現方法進行了研究。分析和比較了幾種不同的數據包捕獲方法,對NDIS中間層驅動的執行過程進行了詳細剖析,并對捕獲數據的內部存儲結構以及操作方法進行了闡述。
關鍵詞:網絡安全;數據捕獲;網絡驅動接口規范
中圖分類號:TP393文獻標識碼:A文章編號:1009-3044(2010)03-571-02
Research on Network Packet Capture Based on NDIS Driver
LIU Wen-tao
(Department of Computer and Information Engineering, Wuhan Polytechnic University, Wuhan 430023, China)
Abstract: The network packet capture is the key component of network application and network security system and it can capture all or special network packets on the network. Many methods can be used for network packet capture and the method based on NDIS in windows is a most efficient and convenient style. In this paper, the principle and the implement method of this capture are provided. Some network packet methods are discussed and compared. The execution progress of The NDIS intermediate driver is analyzed in detail and the internal data storage structure and operation methods are described.
Key words: network security; network packet capture; network driver interface specification
網絡安全是現在研究的重要方向之一,隨著網絡的飛速發展,安全問題日益嚴重,對網絡安全產品的需求更加迫切。在網絡安全軟件中,網絡數據包的捕獲是一個核心內容,在很多典型的網絡安全系統中都有涉及。例如網絡防火墻、網絡協議分析系統、入侵檢測系統等。如何高效率而方便的獲取網絡數據包是網絡安全研究中的一個重要內容。在實際的應用中,有很多種網絡數據包捕獲方法,總結起來有如下一些。
1) 使用一些通用的數據包捕獲組件。例如Libpcap和Winpcap。Libpcap[1]是一個通用的數據包捕獲組件,他在內部提供了強有力的數據包捕獲功能,使用了雙緩存的概念,使捕獲的性能得到明顯提高。另外在Libpcap中還提供了對數據包的過濾技術,用過濾規則實現對數據包的過濾,使用戶能夠只捕獲感興趣的數據包。最典型的應用就是Tcpdump,他是一個比較流行的協議分析軟件,基于Libpcap而開發的。Winpcap[2]是Libpcap在Windows平臺下的版本,很多函數都是兼容的。雖然使用這些開發包可以明顯縮短軟件開發周期,編程也更加容易,但他們也有自己的缺點。在使用這些開發包的時候,必須在計算機系統中安裝相應的運行環境,例如要運行基于Winpcap的程序,必須安裝Winpcap運行庫,否則會提示出錯。所以在軟件發布的時候,需要額外安裝運行庫。另外這些運行庫可能染上病毒,或者可能本身存在漏洞,這又添加了新的安全問題。
2) 使用套接字Socket。可以利用原始套接字Raw Socket技術,來捕獲經過網絡的數據包,由于套接字的標準特性,每個操作系統都普遍支持,所以基于他來設計更加具有通用性。但是基于原始套接字技術來捕獲數據包的功能有限,不夠靈活,很多應用都有局限性,并且性能受到一定的限制。
3) 使用驅動Driver捕獲,這是本文使用的技術。在Windows系統中,提供了驅動模塊,在驅動這一級別來捕獲數據包,更能靈活控制數據包的行為。可以利用他來被動捕獲,也可以進行主動攔截。本文對在Windows環境中利用網絡驅動接口規范NDIS技術來實現網路數據包捕獲的原理和開發過程進行了研究。
1 NDIS驅動
NDIS(Network Driver Interface Specification)[3]是Windows網絡協議驅動程序的接口規范,他具有很高的結構性和可擴展性。其目的是為網絡接口卡的驅動程序提供一個標準的應用程序接口,提供網絡通信的基本服務。很多具體的網絡協議可以在此接口上得以實現,無縫連接,并為用戶開發提供了方便。其支持的協議包括常見的TCP/IP協議族,以及其他的協議,例如AppleTalk、IPX和NetBIOS等。其中NetBIOS為網絡基本輸入/輸出系統,他制定了在應用程序和連接媒介之間提供通信接口的標準方法,可以適用于各種局域網,例如以太網(Ethernet),令牌環網(Token Ring),還可以適用于廣域網,例如TCP/IP、PPP以及X.25等。IPX(Internetwork Packet Exchange)是網間數據包交換協議,他是Novell網絡的核心協議,類似于TCP/IP協議族中的IP協議,主要用來控制局域網內或者局域網之間的網絡數據包的尋址和路由。鑒于此,可以發現NDIS為用戶開發協議驅動提供了方便的接口,使編程難度相對簡單,由于其屏蔽了底層的硬件的不同之處,為網絡驅動程序開發提供了便捷。
NDIS主要支持三種類型的網絡驅動:小端口驅動、中間驅動以及協議驅動。小端口驅動層主要是實現網絡設備的物理驅動程序,屬于底層的驅動。他負責管理網絡接口卡,例如通過網絡接口卡發送和接收數據,另外他還負責與上層驅動程序進行交互,包括中間層驅動和協議驅動。而協議驅動層主要是實現具體的一些協議族,例如TCP/IP、IPX等協議族,并為上層的應用程序提供TDI接口(Transportation Driver Interface)。它既為應用層的進程提供服務,也接收來自網卡和中間層驅動的數據。而中間層驅動位于這兩層之間,提供了很多對數據包進行處理的機會和方法。于是在中間層對數據包進行捕獲和攔截是理所當然的,并且可以獲得很多的靈活性,能深入靈活地控制數據包的行為。在這三個層次驅動之間,都由NDIS提供相應的接口以便他們之間信息的傳遞和溝通。小端口驅動利用NDIS接口來與網絡設備進行交互,網絡設備可能由不同的設備廠家提供,為了實現兼容性和可移植性,在Windows平臺中,提供了一個硬件抽象層HAL,由他來處理不同硬件之間的差異性,從而給上端的驅動程序提供一個統一的編程接口。這樣驅動程序的編寫者不需要了解各種硬件的特性,從而只需要掌握NDIS編程規范就可以編寫出各種不同應用的驅動程序,這對于驅動程序的開發是很有益處的。在NDIS中支持面向連接的小端口驅動,主要有介質有Ethernet、FDDI和Token Ring。也支持無連接的驅動,主要有ATM和ISDN。他們通過一系列的NdisXxx函數來操作,同時NDIS小端口驅動注冊一系列MiniportXxx函數,由函數NdisRegisterMiniport完成,而協議驅動層向NDIS注冊一系列ProtocolXxx函數,由NdisRegisteredProtocol函數完成[4]。其中參數MiniportCharacteristics是NDIS_MINIPORT_CHARACTERISTICS結構體類型,在這個結構中定義了對應的一系列MiniportXxx函數,例如MiniportTransferData、MiniportReturnPacket、MiniportSendPackets、MiniportSend等。而參數ProtocolCharacteristics是NDIS_PROTOCOL_CHARACTERISTICS結構體類型,在此結構體中指定了一系列ProtocolXxx函數,例如ProtocolOpenAdapterComplete、ProtocolCloseAdapterComplete、ProtocolReceive、ProtocolReceivePacket、ProtocolStatus、ProtocolReceiveComplete、ProtocolSendComplete、ProtocolTransferDataComplete 、ProtocolCoReceivePacket等。這些函數有些是強制性的,有些是非強制性的。其中參數NdisWrapperHandle是由函數NdisMInitializeWrapper獲得的,他向NDIS注冊小端口設備。
注冊完這些函數后,當有數據包到達時,NDIS調用合適的MiniportXxx函數接收數據包傳輸給小端口,然后小端口調用合適的NdisXxx函數把數據包轉移給網絡接口卡發送出去。當有數據包到達時,產生小端口處理中斷,NDIS調用恰當的MiniportXxx函數經過小端口把數據傳送到上層驅動。
2 數據捕獲實現
中間驅動是介于協議驅動和小端口之間,他可以捕獲所有的網絡數據包,因此具有很高的靈活性。在對應于網絡協議層體系中,他位于鏈路層和網絡層之間,對網絡層提供虛擬的小端口驅動,對鏈路層提供協議驅動。如圖1所示。
在中間層的下邊界,提供了協議驅動接口,用于與下層驅動交互,此時相對下層驅動而言中間層驅動類似于協議驅動。在中間層的上邊界,提供了小端口接口,用于與上層驅動交互,此時相對于上層驅動而言中間層驅動類似于小端口驅動。此時,他不是實際管理物理的網絡接口卡,而只是向上層提供可以綁定的虛擬適配器,類似于物理網絡接口卡。當發送數據包的時候,中間層驅動把這些數據包發送給下層的小端口,再由小端口進行處理。當有數據包到達時,中間層驅動把這些數據包傳遞給上層的協議驅動,此時的協議驅動就是綁定在虛擬適配器上的。
所以通過網卡發送和接收的所有數據包都可以經過中間層,因此在此處可以實現數據包的捕獲和攔截。中間層驅動的入口應為DriverEntry模式[5-6]。由此開始,完成如圖2所示的工作,在這個過程中,完成了MiniportXxx函數和ProtocolXxx函數的注冊,以及他們之間的映射關系。
由于在這里捕獲到達的數據包,所以只考慮數據包到達的情況。當有數據到達的時候,會調用函數NdisMIndicateReceivePacket實現數據包的接收,他通知NDIS一組可用的數據到達,并可以轉發到適用的協議驅動來進行處理。此時將觸發NDIS中間驅動層函數ProtocolReceivePacket的調用,由他來對接收的數據包進行處理。所以在這個函數中就可以對數據包進行捕獲,或者實行攔截,以及其他的一些動作。另外還可以觸發NDIS協議驅動層的函數ProtocolReceive來接收數據。 ProtocolReceive一次接收一個數據包,他是通過比較數據包和緩沖區的大小來監控數據包是否傳輸完畢,若數據沒有接收完,則調用NdisTransferData把剩余的數據傳輸給上層。ProtocolReceivePacket一次可以接收多個數據包,比ProtocolReceive的效率要高。接收到的數據存儲在由NDIS_PACKET數據結構指針指向的鏈表,由他描述每個網絡數據包。在NDIS_PACKET數據包描述符內有一個NDIS_PACKET_PRIVATE類型的成員Private,由他來詳細描述了數據包的信息。
實際的數據內容存儲在由數據結構NDIS_BUFFER描述的結點之中,組成一個鏈表來表示。其中成員Head指出了數據鏈表的首結點,成員Tail表示數據鏈表的終結點。在NDIS_PACKET_PRIVATE中NdisPacketOobOffset成員指出了帶外數據的位移,通過帶外數據位移和NDIS_PACKET描述符可以獲得帶外數據的存放地址,讀取帶外數據。帶外數據主要是指實際數據以外的信息,例如數據包的接收時間。帶外數據由NDIS_PACKET_OOB_DATA數據結構描述。對這些數據結構不需要直接進行操作,因為他們對開發人員來說是不透明的,可能在不同的版本其格式有差別。為安全起見,一般都是通過NDIS提供的操作函數來進行讀取。常用的操作函數有NdisQueryPacket、NdisQueryBufferSafe、NdisGetNextBuffer等。其中NdisQueryPacket用來讀取一個數據包描述符,返回第一個數據緩沖結點指針。NdisQueryBufferSafe用來獲得一個緩沖區結點的首地址和大小,這樣就可以把此緩沖區的數據取出,用函數NdisMoveMemory操作。函數NdisGetNextBuffer用來獲取下一個數據緩沖區結點,這樣通過與函數NdisQueryBufferSafe配合,用循環就可以獲取一個完整的數據包信息。捕獲到網絡數據之后,可以按照協議格式對此數據包進行分析,根據要求進一步開發出各種應用,例如網絡協議分析系統、入侵檢測系統等。
3 小結
數據包捕獲在很多場合都有應用,本文闡述了NDIS捕獲網絡數據包的原理和實現。利用NDIS驅動來實現對數據包的捕獲可以獲得很高的效率,并且具有可移植性、并行性、可靠性和異步性等特征,特別適用于Windows下的網絡安全程序。
參考文獻:
[1] Libpcap[EB/OL].http://www.tcpdump.org/.
[2] Winpcap[EB/OL].http://www.winpcap.org/.
[3] NDIS Developer's Reference[EB/OL].http://www.ndis.com/.
[4] Network Driver Reference[EB/OL].http://msdn.microsoft.com/.
[5] Microsoft Corporation. Windows 2000驅動程序開發大全,設計之南[M].馮博琴,譯.北京:機械工業出版社,2001.
[6] Art Baker,Jerry Lozano.Windows 2000設備驅動程序設計指南[M]. 施諾,譯.2版.北京:機械工業出版社,2001.