摘 要: Winpcap有一系列創(chuàng)新(如數(shù)據(jù)包監(jiān)視和數(shù)據(jù)包注入)的特點(diǎn),這在以前的操作系統(tǒng)中是見(jiàn)不到的。介紹了Winpcap的系統(tǒng)結(jié)構(gòu)及其功能。
關(guān)鍵詞: Winpcap;數(shù)據(jù)包監(jiān)測(cè);數(shù)據(jù)包注入
網(wǎng)絡(luò)分析軟件通常依賴底層調(diào)用抓取數(shù)據(jù)包,進(jìn)行數(shù)據(jù)包監(jiān)視或流量分析等。大多數(shù)的Unix系統(tǒng)都提供這些功能(至少是數(shù)據(jù)包抓?。鳺indows提供的這些功能卻不令人滿意。Windows提供了一些與各種內(nèi)核組件相關(guān)的API,但這些API存在嚴(yán)重的缺陷,如并不是所有的Netmon API都可用,而且其擴(kuò)展存在很多限制。IP過(guò)濾驅(qū)動(dòng)程序(IP filter driver)只存在Windows 2000及以上系統(tǒng)中,而且它只支持IP協(xié)議,雖然它能夠控制和丟棄數(shù)據(jù)包但卻不能監(jiān)測(cè)和構(gòu)造數(shù)據(jù)包。PCAUSA提供了一個(gè)商業(yè)產(chǎn)品,該產(chǎn)品含有數(shù)據(jù)包捕獲和BPF兼容的過(guò)濾器,然而它的用戶接口處于底層且沒(méi)有提供過(guò)濾器構(gòu)造這樣的抽象方法。隨著原本在Unix系統(tǒng)上的應(yīng)用不斷轉(zhuǎn)向Windows系統(tǒng),這些特性的缺失成了不可忽視的問(wèn)題。
本文主要介紹一個(gè)強(qiáng)大可擴(kuò)展的Win32平臺(tái)的網(wǎng)絡(luò)監(jiān)聽(tīng)框架系統(tǒng)Winpcap的結(jié)構(gòu)及其功能。該體系結(jié)構(gòu)填補(bǔ)了Unix和Windows間網(wǎng)絡(luò)監(jiān)聽(tīng)能力的間隔,使得Unix應(yīng)用到Windows的移植更簡(jiǎn)單,而且Winpcap把性能放在最首位,使其能滿足更苛刻的需求。
1 Winpcap的體系結(jié)構(gòu)
Winpcap的基本結(jié)構(gòu)如圖1所示,由1個(gè)過(guò)濾引擎、2個(gè)緩沖區(qū)(內(nèi)核層與用戶層)以及一系列供開(kāi)發(fā)人員使用的組件庫(kù)組成。盡管Libpcap具有穩(wěn)固的結(jié)構(gòu)并且功能強(qiáng)大,但Winpcap在結(jié)構(gòu)和數(shù)據(jù)捕獲上仍然有自己獨(dú)到的地方,而且甚至可以認(rèn)為是對(duì)Libpcap的創(chuàng)新。
Winpcap的過(guò)濾可從用戶層開(kāi)始(與Libpcap兼容),開(kāi)發(fā)人員可以自定義包過(guò)濾條件(如picks up all udp packets);Winpcap會(huì)把它們編譯成一些虛擬指令(如if the packet is ip and the protocol type field is equal to 17,then return true),同時(shí)把這些虛擬指令發(fā)送到過(guò)濾引擎,并且激活這些功能。要實(shí)現(xiàn)這些目的,內(nèi)核模塊必須能夠執(zhí)行指令,因此需要一個(gè)“虛擬BPF”用來(lái)在每個(gè)接收的數(shù)據(jù)包執(zhí)行這些虛擬代碼。其中內(nèi)核層的過(guò)濾引擎是獲得高性能的關(guān)鍵。
NPF與BPF在體系上最大的不同是對(duì)循環(huán)緩沖區(qū)的使用選擇[1]。Winpcap每次復(fù)制一部分?jǐn)?shù)據(jù)包,Winpcap的緩沖區(qū)不再是固定大?。↙ibpcap的內(nèi)核緩沖區(qū)與用戶緩沖區(qū)都是32 KB),而且在將數(shù)據(jù)包從內(nèi)核緩沖區(qū)復(fù)制到用戶緩沖區(qū)的過(guò)程中對(duì)數(shù)據(jù)包進(jìn)行更新,而不是復(fù)制完后更新。在復(fù)制過(guò)程中,將已經(jīng)傳送的數(shù)據(jù)包所占用的空間立即釋放,因?yàn)楸M管Winpcap工作在較高的優(yōu)先級(jí)并且可能一直壟斷CPU,但內(nèi)核層的捕獲程序可能會(huì)中斷復(fù)制過(guò)程。只要交換緩沖區(qū)允許占用一般的內(nèi)存,Winpcap的緩沖區(qū)就可以存放大量的數(shù)據(jù)包。
內(nèi)核緩沖區(qū)僅通過(guò)一個(gè)read函數(shù)就可以完全復(fù)制,這可以減少大量的系統(tǒng)調(diào)用并且避免程序在內(nèi)核層與用戶層之間頻繁切換。因?yàn)榄h(huán)境的切換之前必須保存任務(wù)狀態(tài)(CPU描述符與任務(wù)狀態(tài)大約有幾百個(gè)字節(jié)),頻繁切換會(huì)導(dǎo)致CPU使用率下降。
Winpcap的內(nèi)核緩沖區(qū)比BPF的要大(為1 MB),因?yàn)檩^小的內(nèi)核緩存也會(huì)帶來(lái)一些問(wèn)題,特別是當(dāng)程序無(wú)法與捕獲數(shù)據(jù)包的驅(qū)動(dòng)程序的速度保持一致情況下,這種情況在將數(shù)據(jù)發(fā)往硬盤(pán)或網(wǎng)絡(luò)數(shù)據(jù)量激增的情況下很常見(jiàn)。相反,用戶緩沖區(qū)需要小一些,通常情況下為256 KB。內(nèi)核緩沖區(qū)與用戶緩沖區(qū)都可以在運(yùn)行時(shí)調(diào)整。
用戶緩沖區(qū)的大小至關(guān)重要,因?yàn)樗鼪Q定了僅通過(guò)一個(gè)調(diào)用最多可以從內(nèi)核讀多少數(shù)據(jù),同時(shí),一次從內(nèi)核中至少應(yīng)該讀多少數(shù)據(jù)也很重要。如果給出一個(gè)較大的值,則內(nèi)核可以在數(shù)據(jù)送往用戶緩沖區(qū)之前等待足夠多的數(shù)據(jù)包到達(dá),這可以減少一些系統(tǒng)調(diào)用。如果給出一個(gè)較小的值,則意味著內(nèi)核可以將數(shù)據(jù)包盡快送往用戶緩存。這對(duì)那些實(shí)時(shí)性要求比較高的應(yīng)用來(lái)說(shuō)很重要,一個(gè)好的捕獲引擎會(huì)在兩者之間做出好的平衡。NPF是可配置的,讓用戶選擇程序具有好的執(zhí)行效率或快速的反應(yīng)。而Winpcap提供了一組函數(shù)可以設(shè)置數(shù)據(jù)包讀延時(shí)和數(shù)據(jù)包拷貝的最小值。當(dāng)讀延時(shí)或內(nèi)核緩沖區(qū)獲得的數(shù)據(jù)包數(shù)據(jù)量滿足了最小值,數(shù)據(jù)都會(huì)被送往用戶緩沖區(qū)。延時(shí)默認(rèn)設(shè)置為1 s,最小數(shù)據(jù)量設(shè)置為16 KB,這種功能被稱之為“延遲寫(xiě)入”。
1.1 統(tǒng)計(jì)模式
包捕獲與網(wǎng)絡(luò)分析會(huì)過(guò)多占用CPU,因?yàn)橛写罅康臄?shù)據(jù)需要處理和拷貝。提高執(zhí)行速度最常用的方法是提高過(guò)濾引擎的速度與一次拷貝結(jié)構(gòu),這種方法是通過(guò)將內(nèi)核緩沖區(qū)映射到程序內(nèi)存來(lái)實(shí)現(xiàn)。一次拷貝的操作會(huì)減少數(shù)據(jù)的拷貝,但并不會(huì)減少內(nèi)核層與用戶層之間的系統(tǒng)調(diào)用。如果用戶一次讀一個(gè)數(shù)據(jù)包,環(huán)境切換的代價(jià)會(huì)抵消一次拷貝所帶來(lái)的好處。
一種新的方法是監(jiān)視時(shí)并不將數(shù)據(jù)包送往用戶層,而是Winpcap將監(jiān)視的功能放在內(nèi)核層,這樣就可以避免數(shù)據(jù)送往用戶層。Winpcap提供了一種嵌入在NPF過(guò)濾引擎中的可編程的統(tǒng)計(jì)模式,可以使過(guò)濾器成為強(qiáng)大的分類器而不僅僅是過(guò)濾器。應(yīng)用程序可以使用這個(gè)模塊監(jiān)視任意的網(wǎng)絡(luò)行為(如網(wǎng)絡(luò)下載、兩臺(tái)主機(jī)間的網(wǎng)絡(luò)流量、每秒鐘的網(wǎng)頁(yè)訪問(wèn)數(shù)量),并且可以在預(yù)先設(shè)定的時(shí)間間隔獲得這些結(jié)果。
統(tǒng)計(jì)模式避免了數(shù)據(jù)拷貝,并且實(shí)行0拷貝模式(統(tǒng)計(jì)行為在數(shù)據(jù)包到達(dá)網(wǎng)卡驅(qū)動(dòng)的存儲(chǔ)區(qū)時(shí)執(zhí)行,之后數(shù)據(jù)包被丟棄),所以不需要緩沖區(qū)。統(tǒng)計(jì)模式是監(jiān)視網(wǎng)絡(luò)的一種極為有效的方法,且能在高速網(wǎng)絡(luò)中表現(xiàn)出良好的性能。
Winpcap為開(kāi)發(fā)人員提供了一組高層調(diào)用可以很容易地使用統(tǒng)計(jì)模式,對(duì)那些習(xí)慣了Libpcap的開(kāi)發(fā)人員來(lái)說(shuō)很容易掌握。
1.2 數(shù)據(jù)包注入
BPF與NPF都提供了直接發(fā)送原始包的功能,可以將數(shù)據(jù)包直接發(fā)送到網(wǎng)絡(luò)中。但是Libpcap并沒(méi)有使用這些調(diào)用,而B(niǎo)PF也并不是用于此目的。大多數(shù)Unix系統(tǒng)都提供了直接發(fā)送原始包的功能,而Windows只有2000才提供了此功能,且功能受限。因此,Winpcap是Win32平臺(tái)上第一標(biāo)準(zhǔn)的而且可靠的發(fā)送原始包的類庫(kù)。NPF提供了許多新的函數(shù)可以發(fā)送多個(gè)數(shù)據(jù)包而只在內(nèi)核層與用戶層之間切換一次。
Winpcap雖然提供了很多函數(shù)可以去開(kāi)發(fā)這些新的功能(但并沒(méi)有直接提供這些功能),它需要開(kāi)發(fā)人員手工構(gòu)造數(shù)據(jù)包或利用已有的工具。而用戶可以使用Libnet Packet Assembly Library(即在Winpcap上加了一層功能),就可以構(gòu)造數(shù)據(jù)包并發(fā)送到網(wǎng)絡(luò)中。
2 性能分析
主要是對(duì)Winpcap的性能進(jìn)行測(cè)試,用Winpcap在Windows98與Windows2000下的表現(xiàn)與Libpcap/BPF在FreeBSD下的表現(xiàn)進(jìn)行比較。
圖2為兩臺(tái)主機(jī)直接相連,以排除外部數(shù)據(jù)包的干擾,使實(shí)驗(yàn)結(jié)果更精確。一臺(tái)主機(jī)是Windows2000操作系統(tǒng),使用基于Winpcap的工具產(chǎn)生大量的數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)中,并保證高速率。數(shù)據(jù)包的大小選擇,是以保證每秒所產(chǎn)生的數(shù)據(jù)包都能夠達(dá)到一個(gè)極限值。
操作系統(tǒng)安裝在同一臺(tái)主機(jī)上的不同硬盤(pán)分區(qū)上,以避免由于硬件原因帶來(lái)的差異。數(shù)據(jù)包被發(fā)送到不同的主機(jī)上,這樣可以使兩臺(tái)主機(jī)之間不用進(jìn)行交互。接收端的主機(jī)網(wǎng)卡設(shè)置為混雜模式,根據(jù)測(cè)試主題的不同而用不同的工具捕獲數(shù)據(jù)包。根據(jù)測(cè)試需要,數(shù)據(jù)包收到后或丟棄、或傳送給應(yīng)用程序、或存儲(chǔ)在硬盤(pán)中。
FreeBSD的CPU負(fù)載可以在TOP PROGRAM查看,Windows2000可以通過(guò)任務(wù)管理器查看,Windows98則可以用CPUMETER查看(可以從網(wǎng)上獲得)。
被測(cè)試的軟件都是最新的發(fā)行版,Winpcap的內(nèi)核緩沖區(qū)為1 MB,Libpcap的緩沖區(qū)被設(shè)置為2個(gè)512 KB大小的空間(默認(rèn)為32 KB)。
這些實(shí)驗(yàn)將努力避免其他軟件對(duì)實(shí)驗(yàn)結(jié)果的影響,但是結(jié)果并不能準(zhǔn)確地表現(xiàn)出單獨(dú)組件的性能,因?yàn)椴煌慕M件不交互基本上是不可能的。
2.1 發(fā)送實(shí)驗(yàn)
發(fā)送實(shí)驗(yàn)是測(cè)試發(fā)送性能,只在Windows2000下進(jìn)行(95/98沒(méi)有對(duì)這個(gè)功能做優(yōu)化)。圖3顯示了當(dāng)每個(gè)包都為88 B的情況下達(dá)到每秒發(fā)送的最大值(原認(rèn)為在每個(gè)包為64 B的情況下會(huì)達(dá)到最大值),這出乎意料。因?yàn)闇y(cè)試并不依賴NPF,CPU的負(fù)載始終沒(méi)有達(dá)到100%,這也說(shuō)明了NPF并不是瓶頸所在。當(dāng)數(shù)據(jù)包為400 B時(shí)網(wǎng)絡(luò)達(dá)到全速。
經(jīng)實(shí)驗(yàn)發(fā)現(xiàn)發(fā)送能力更多依賴于網(wǎng)卡,當(dāng)更換網(wǎng)卡、并在相同情況下進(jìn)行測(cè)試時(shí),發(fā)送速度只能達(dá)到每秒30 000個(gè)包。
2.2 接收與過(guò)濾實(shí)驗(yàn)
接收與過(guò)濾能力實(shí)驗(yàn)測(cè)試:數(shù)據(jù)包被網(wǎng)絡(luò)接口接收并被過(guò)濾器檢查,如果所有的包都不會(huì)滿足過(guò)濾條件,它們將在檢查后被丟棄(不會(huì)被拷貝)。
測(cè)試在兩種情況下進(jìn)行:第一種使用3條BPF虛擬指令;第二種使用13條復(fù)雜的BPF虛擬指令。
圖4為網(wǎng)絡(luò)分離和過(guò)濾性能,幾乎所有的包都被接受并沒(méi)有被過(guò)濾器檢查。Windows98的CPU負(fù)載明顯高于Windows2000(但是也在可以接受的范圍內(nèi))FreeBSD表現(xiàn)很差,只捕獲大約一半的數(shù)據(jù)包,而且CPU負(fù)載始終較高。
2.3 向應(yīng)用程序傳送數(shù)據(jù)包的測(cè)試
測(cè)試應(yīng)用程序從Winpcap接收數(shù)據(jù)包的能力(收到后直接丟棄,并不做進(jìn)一步的處理),檢驗(yàn)整個(gè)Winpcap體系的功能,包括數(shù)據(jù)從網(wǎng)卡復(fù)制到內(nèi)核緩沖區(qū)再到用戶緩沖區(qū),而且將不使用過(guò)濾功能。圖5為測(cè)試結(jié)果,Winpcap幾乎可以將所有從網(wǎng)絡(luò)接口獲得的數(shù)據(jù)全部送至應(yīng)用程序,沒(méi)有數(shù)據(jù)包在內(nèi)核緩沖區(qū)被丟棄。而FreeBSD并不能做到這些,特別是在高數(shù)據(jù)率的情況下,大部分的數(shù)據(jù)包在沒(méi)有到達(dá)過(guò)濾器之前已被丟棄。
無(wú)論在Windows2000還是FreeBSD中,CPU的負(fù)載都隨著數(shù)據(jù)包容量的增大而降低,Windows98因?yàn)闆](méi)有延遲寫(xiě)入的能力而表現(xiàn)一般。
2.4 程序性能實(shí)驗(yàn)
實(shí)驗(yàn)將使用基于Winpcap的工具將獲得的數(shù)據(jù)包轉(zhuǎn)存在文件中,結(jié)果如圖6所示。程序?qū)⒚總€(gè)數(shù)據(jù)包的68 B的內(nèi)容存到文件中。所有的系統(tǒng)在高數(shù)據(jù)率的情況下都會(huì)丟失一些數(shù)據(jù)包:一部分是因?yàn)殂∈谻PU時(shí)間(當(dāng)一個(gè)數(shù)據(jù)包到達(dá)時(shí),程序卻還在處理前面的包);另一部分則因?yàn)閮?nèi)核緩沖區(qū)沒(méi)有足夠的空間去存放數(shù)據(jù)包。圖7為整個(gè)數(shù)據(jù)包被寫(xiě)入文件時(shí)的結(jié)果。
2.5 監(jiān)視實(shí)驗(yàn)
監(jiān)視實(shí)驗(yàn)在AD-HOC網(wǎng)絡(luò)上進(jìn)行。實(shí)驗(yàn)結(jié)果表明CPU負(fù)載一直維持在較低的水平,而且結(jié)果與圖4相類似。圖5顯示了在用戶層監(jiān)視的代價(jià)遠(yuǎn)高于內(nèi)核層,這些多余的代價(jià)會(huì)給用戶層監(jiān)視的性能帶來(lái)折扣。另外,用戶層的監(jiān)視需要大容量的緩沖區(qū)。
3 Winpcap的改進(jìn)意見(jiàn)
根據(jù)實(shí)驗(yàn)結(jié)果與體系結(jié)構(gòu)的特點(diǎn),采取了如下相應(yīng)的改進(jìn)措施:
3.1 過(guò)濾引擎改進(jìn)
因?yàn)椴捎脛?dòng)態(tài)代碼生成技術(shù)對(duì)BPF進(jìn)行改進(jìn),使BPF性能取得明顯效果,因此對(duì)NPF也進(jìn)行了類似的改進(jìn),采用JIT(Just In Time)技術(shù),將過(guò)濾代碼翻譯成X86的二進(jìn)制代碼,這項(xiàng)改進(jìn)使整體的捕獲性能提高了約8%。
3.2 內(nèi)存拷貝
因數(shù)據(jù)包從網(wǎng)卡到程序需要進(jìn)行兩次拷貝過(guò)程,而第一次拷貝(從網(wǎng)卡到內(nèi)核緩沖區(qū))的代價(jià)明顯高于第二次拷貝,一個(gè)重要的原因是NdisTransferData()函數(shù)進(jìn)行了額外的操作。但是同時(shí),在研究過(guò)程中也注意到一些網(wǎng)絡(luò)控制器(尤其是一些大型的網(wǎng)絡(luò)適配器)是在通知網(wǎng)卡驅(qū)動(dòng)之前將數(shù)據(jù)包拷貝到內(nèi)存中的,因此NPF驅(qū)動(dòng)可以在同一內(nèi)存區(qū)接收數(shù)據(jù)包。在這種情況下,可以使用C標(biāo)準(zhǔn)庫(kù)的函數(shù)來(lái)實(shí)現(xiàn)這個(gè)功能。
3.3 時(shí)間戳
用于產(chǎn)生微妙級(jí)精確度時(shí)間戳的KeQueryPerformanceCounter函數(shù)可以被Inter處理器中集成的TSC(Time Stamp Counter)取代,TSC的精度與CPU頻率相同。X86的指令集提供了一條指令來(lái)取得時(shí)間戳(rdtsc),這項(xiàng)改進(jìn)可以使整體性能提升27%左右。但是標(biāo)準(zhǔn)的NPF發(fā)現(xiàn)版并沒(méi)有使用這項(xiàng)改進(jìn),因?yàn)檫@項(xiàng)指令需要硬件支持(只在Inter處理器或與Inter處理器兼容的處理器上才能運(yùn)行)[2]。
3.4 Tap函數(shù)優(yōu)化
Tap函數(shù)中同樣用到了NdisTransferData()函數(shù),而該函數(shù)運(yùn)行時(shí)要求分配一塊存儲(chǔ)區(qū)去使某個(gè)數(shù)據(jù)結(jié)構(gòu)可以用來(lái)存放要傳送的數(shù)據(jù)包,這個(gè)操作在數(shù)據(jù)包傳送完畢時(shí)可能會(huì)導(dǎo)致回調(diào)函數(shù)的調(diào)用中斷。同樣也可以用C標(biāo)準(zhǔn)庫(kù)的函數(shù)替代它。這項(xiàng)改進(jìn)可以使整體性能提升5%左右。
3.5 硬件優(yōu)化
由于很多開(kāi)銷是在捕獲過(guò)程之外產(chǎn)生的,這就存在硬件優(yōu)化的可能性,如NEW ZEALAND BASED公司推出有專用于網(wǎng)絡(luò)捕獲的芯片。該芯片避免了過(guò)多地與操作系統(tǒng)的交互,它可以產(chǎn)生時(shí)間戳,而且直接將數(shù)據(jù)包傳送到系統(tǒng)內(nèi)存,用硬件來(lái)管理緩沖區(qū)。這樣應(yīng)用程序可以直接取得數(shù)據(jù)而不需要同其他層次打交道。因此,硬件的優(yōu)化可以使基于軟件的捕獲程序性能得到較大的提升。
本文主要針對(duì)Winpcap的體系結(jié)構(gòu)及其性能進(jìn)行研究,并對(duì)可能的優(yōu)化措施進(jìn)行探討。文中的實(shí)驗(yàn)主要是對(duì)Winpcap的各個(gè)部分的性能進(jìn)行測(cè)試,與一般的看法不同,過(guò)濾和緩沖區(qū)并不是影響整體性能的最重要的部分。對(duì)這兩部分的優(yōu)化,引起了很多的關(guān)注,但是針對(duì)它們的改進(jìn)相對(duì)整體的性能提升并沒(méi)有明顯的幫助,特別是在數(shù)據(jù)包比較小的情況下。經(jīng)一系列實(shí)驗(yàn)說(shuō)明,真正的瓶頸在那些隱藏的地方,如設(shè)備驅(qū)動(dòng)程序、應(yīng)用程序與操作系統(tǒng)的交互、操作系統(tǒng)與硬件之間的交互。
數(shù)據(jù)捕獲是由很多組件配合完成的工作。所以,在對(duì)其性能進(jìn)行優(yōu)化這個(gè)問(wèn)題上,要從全局考慮,而不應(yīng)該僅僅局限在某個(gè)組件。實(shí)驗(yàn)說(shuō)明了一些大量?jī)?yōu)化操作都集中在沒(méi)什么提升潛力的地方(如過(guò)濾引擎和緩沖區(qū)優(yōu)化),而真正值得關(guān)注的地方卻并沒(méi)有引起足夠的重視。同時(shí),即使所有涉及到的技術(shù)都很成熟,但性能提升還是有很大的空間,希望本文能給同行提供一些新的視角。
參考文獻(xiàn)
[1] DEGIOANNI L, BALDI M, RISSO F, et al. Profiling and optimization of software-based network-analysis applications proceedings[C]. The 15th IEEE Symposium on Computer Architecture and High Performance Computing (SBAC-PAD 2003) Sao Paulo, Brazil, November 2003:3-5.