摘 要: 提出一種針對高速光網(wǎng)絡環(huán)境的數(shù)據(jù)包捕獲平臺的設計方案,。采用軟硬件結(jié)合" title="軟硬件結(jié)合">軟硬件結(jié)合的設計思想,由系統(tǒng)硬件完成數(shù)據(jù)包的解析和過濾,,軟件根據(jù)硬件解析結(jié)果將數(shù)據(jù)直接向應用進程分發(fā),。驅(qū)動部分借鑒了零拷貝和循環(huán)緩沖區(qū)技術,并進行了中斷優(yōu)化以降低數(shù)據(jù)采集的CPU占用率,。
關鍵詞: 軟硬件結(jié)合 規(guī)則? 包捕獲? 64位PCI? OC48接口
?
隨著網(wǎng)絡的普及,安全問題正威脅著每個網(wǎng)絡用戶,。因此對計算機的網(wǎng)絡監(jiān)控十分必要,而其中對網(wǎng)絡數(shù)據(jù)包的捕獲和分析尤為重要。隨著網(wǎng)絡帶寬不斷增加,監(jiān)控高速網(wǎng)絡數(shù)據(jù)流的需求越來越明顯,各種數(shù)據(jù)包捕獲技術在大規(guī)模寬帶網(wǎng)絡的入侵檢測系統(tǒng)[1],、大流量網(wǎng)絡數(shù)據(jù)情況下的網(wǎng)絡協(xié)議分析,、寬帶網(wǎng)絡防火墻和高性能路由器等領域中,都具有廣泛的應用前景。
1 傳統(tǒng)方案
傳統(tǒng)的數(shù)據(jù)包捕獲方案一般是基于普通的網(wǎng)卡,通過應用程序和支持庫把網(wǎng)卡設置成混雜模式[2],從而繞開網(wǎng)卡通常的工作程序,使之能夠接受目標地址而不是自己MAC地址的數(shù)據(jù)包,再經(jīng)過過濾,、解析實現(xiàn)監(jiān)控,。
目前實現(xiàn)包捕獲功能的軟件有很多。支持Linux操作系統(tǒng)的Libpcap[3]庫就是基于BPF模型一個典型數(shù)據(jù)包捕獲平臺,。Libpcap 實質(zhì)上是一個系統(tǒng)獨立的 API 函數(shù)接口,用于用戶層次的數(shù)據(jù)包截獲工作,。它為底層網(wǎng)絡監(jiān)控編程提供了易于移植的應用框架。利用Libpcap庫開發(fā)的網(wǎng)絡監(jiān)控的工具如Tcpdump[3]等,大多有效地利用了庫中的接口實現(xiàn)了按需捕獲功能,。但是總體上來看,這些工具由于設計上的限制,即使工作在非常強大的硬件平臺上,在面對現(xiàn)代高速網(wǎng)絡時也越來越難以應付,特別是在快于千兆的光網(wǎng)絡環(huán)境中,常常因為來不及處理導致丟包相當嚴重,。
2 改進方案概述
這是一種采用軟硬件結(jié)合的高速數(shù)據(jù)包捕獲實現(xiàn)方案。為了能適用于高速光網(wǎng)絡環(huán)境,硬件部分完成了對實時性要求高的數(shù)據(jù)包的預處理工作,軟件部分在后期能夠?qū)?shù)據(jù)包進行再次的深度處理,。整個系統(tǒng)硬件的關鍵在包解析處理模塊" title="處理模塊">處理模塊和規(guī)則管理模塊,。包解析處理模塊實現(xiàn)了數(shù)據(jù)包的預處理;規(guī)則管理模塊則用于規(guī)則存儲和查找,包解析處理模塊對數(shù)據(jù)包的過濾有賴于查找的結(jié)果?;谟布渲玫撵`活性,可以在前期就將未匹配成功,、校驗出錯、太短或太長等不符合要求的數(shù)據(jù)包丟棄,后期處理階段可以專注于對有處理需求的數(shù)據(jù)包進行解析,極大地提高了整個系統(tǒng)的性能,。另外,由于目前大部分寬帶IP網(wǎng)的地市級出口基本上都是由2.5Gbps POS(Packet Over SONET)鏈路組成,每個設備采用了兩路2.5Gbps OC48 POS接口作為數(shù)據(jù)輸入;而輸出端采用了64 bit 66MHz的PCI總線設計,從而在主機一側(cè)保證帶寬,。為了適應更高的采樣需求,驅(qū)動在設計上支持多設備協(xié)同工作。
系統(tǒng)軟件部分基于Linux操作系統(tǒng)平臺,由驅(qū)動程序和自定義的庫函數(shù)組成,。驅(qū)動程序?qū)崿F(xiàn)了系統(tǒng)各芯片的初始化,響應上層對規(guī)則和硬件配置的要求和維護數(shù)據(jù)緩沖區(qū)等功能,。庫函數(shù)介于應用程序與驅(qū)動程序之間,起到一個橋梁中介作用,主要向上層提供類似Libpcap的API,從而把復雜的處理函數(shù)封裝起來,給用戶一個簡潔通用的接口。
考慮到傳統(tǒng)方案主要在網(wǎng)卡中斷,、內(nèi)存操作,、用戶態(tài)和內(nèi)核態(tài)間的拷貝等方面存在瓶頸,軟件中做了幾項改進:(1)改進了中斷方式,以數(shù)據(jù)塊" title="數(shù)據(jù)塊">數(shù)據(jù)塊而不是以單個數(shù)據(jù)包觸發(fā)中斷,減少了中斷的頻率;(2)借鑒零拷貝的思想,避免了不必要的內(nèi)存拷貝;(3)利用循環(huán)緩沖區(qū)(ring buffer)存儲用戶數(shù)據(jù), 提高了內(nèi)存利用率,。
3 系統(tǒng)設計及實現(xiàn)
3.1 系統(tǒng)硬件實現(xiàn)
系統(tǒng)利用硬件代替Linux內(nèi)核實現(xiàn)了數(shù)據(jù)包的差錯校驗和協(xié)議棧的初步解析。一定格式的過濾規(guī)則按照優(yōu)先級存儲于規(guī)則管理模塊中,規(guī)則管理模塊將包解析模塊從數(shù)據(jù)包的一些控制字段中抽取出關鍵字同預設的所有規(guī)則進行比較,選出優(yōu)先級最高的匹配規(guī)則,匹配的結(jié)果反饋給包處理模塊,而沒有匹配到任何規(guī)則的數(shù)據(jù)包會被丟棄,。符合要求的數(shù)據(jù)包被加上一個叫做internal head的自定義頭部,。這個自定義頭部包含了這個數(shù)據(jù)包的長度、協(xié)議類型,、時間戳和cookie等信息,這里cookie字段是數(shù)據(jù)包分發(fā)的依據(jù),。此后驅(qū)動程序惟一需要解析的包頭只有自定義頭部,從而降低了軟件處理部分的復雜度。
經(jīng)過過濾后,符合要求的數(shù)據(jù)包會被暫存在硬件外部高速存儲器中,同時包處理模塊以中斷的方式通知驅(qū)動新數(shù)據(jù)的到來,。為避免頻繁中斷帶來的額外的系統(tǒng)開銷,在設計上采用了以數(shù)據(jù)塊而不是以數(shù)據(jù)包的方式來觸發(fā)中斷:暫存在硬件外部高速存儲器中的數(shù)據(jù)達到規(guī)定大小時觸發(fā)中斷, 數(shù)據(jù)借助這次中斷通過DMA方式送往主機側(cè),。當然,為防止收取不到規(guī)定大小的數(shù)據(jù)塊而造成的死鎖,也就是如果收取的數(shù)據(jù)在一定時間仍沒有辦法達到這個大小,則采用超時機制強行發(fā)出中斷請求,送出剩余的數(shù)據(jù)。
系統(tǒng)硬件數(shù)據(jù)處理的整個過程如圖1所示,。
3.2 系統(tǒng)軟件實現(xiàn)
本系統(tǒng)在Linux操作系統(tǒng)中被注冊為一個字符設備并共用一個設備號,。為了提供對多設備的支持,這里設計了一個全局的私有結(jié)構(gòu)來區(qū)分它們,每個結(jié)構(gòu)被用一個單向鏈表管理起來:每當驅(qū)動程序找到一個新設備,就給它分配一個新的結(jié)構(gòu)并掛在鏈表上。另外這個結(jié)構(gòu)的另一個用途是作為中斷處理" title="中斷處理">中斷處理函數(shù)的dev_id參數(shù),在中斷來時中斷處理函數(shù)能夠以此區(qū)分不同的設備,。
從驅(qū)動程序代理用戶進程設置過濾規(guī)則到硬件觸發(fā)中斷通知驅(qū)動程序收取數(shù)據(jù)包,驅(qū)動程序代表整個系統(tǒng)進行一些必要的工作,。
整個系統(tǒng)的軟件結(jié)構(gòu)如圖2所示。
3.2.1 用戶規(guī)則設置
每個用戶進程在創(chuàng)建初期會在內(nèi)核中獲取一塊或多塊連續(xù)內(nèi)存塊用來存儲自己所需的數(shù)據(jù),??紤]到用戶進程可能在數(shù)量上會很多,系統(tǒng)初始化時就已經(jīng)申請好一定數(shù)量固定大小的內(nèi)存塊,并打上id標記等待進程來申請。為了提高內(nèi)存的利用率,這里利用了循環(huán)緩沖區(qū)結(jié)構(gòu)來管理每個內(nèi)存塊,。循環(huán)緩沖區(qū)可以讓驅(qū)動程序?qū)P倪M行數(shù)據(jù)接收而不用考慮讀進程,同時內(nèi)存也不會被浪費,。為避免頻繁的數(shù)據(jù)拷貝,借鑒了零拷貝[4](zero-copy)的思想。零拷貝基本思想是:數(shù)據(jù)包從網(wǎng)絡設備到用戶程序空間傳遞的過程中,減少數(shù)據(jù)拷貝次數(shù),減少系統(tǒng)調(diào)用,在一定程度上實現(xiàn)CPU的零參與,。實現(xiàn)零拷貝采用的最主要技術是DMA數(shù)據(jù)傳輸技術和內(nèi)存區(qū)域映射技術,。傳統(tǒng)的網(wǎng)絡數(shù)據(jù)包過濾處理,需要進行多次數(shù)據(jù)拷貝,整個過程需要用戶進程向系統(tǒng)發(fā)出的系統(tǒng)調(diào)用,其中涉及到操作系統(tǒng)大量的上下文切換和CPU的始終參與。零拷貝技術首先利用DMA技術將網(wǎng)絡數(shù)據(jù)包通過DMA通道直接推入系統(tǒng)內(nèi)核中一個公共緩沖區(qū),其過程可與主機并行操作,然后由公共緩沖區(qū)分發(fā)給相應用戶緩沖區(qū),。由于位于內(nèi)核空間的用戶緩沖區(qū)是受保護的,應用進程在用戶態(tài)無法直接訪問,。排除低效率的系統(tǒng)調(diào)用方法,這里采用了Linux的一種高效的內(nèi)存映射機制mmap將內(nèi)核空間映射到虛地址空間,用戶通過這個空間內(nèi)的虛地址就能訪問到相應的用戶緩沖區(qū)了。
創(chuàng)建用戶進程的同時,過濾規(guī)則也按一定語法被設置,。規(guī)則通過庫函數(shù)和系統(tǒng)調(diào)用被按一定優(yōu)先級(這里稱規(guī)則索引)存儲于規(guī)則管理模塊中,此時該規(guī)則開始生效,。為了方便驅(qū)動管理規(guī)則,同樣的規(guī)則以鏈表的方式保存于系統(tǒng)內(nèi)存中。軟件中的規(guī)則是硬件中的規(guī)則的抽象,兩者每時每刻都保持著同步,。
用戶的緩沖區(qū)和用戶設置的規(guī)則被前文所述的內(nèi)存塊id標記聯(lián)系起來,。這個標記的值會賦予以規(guī)則索引為下標的數(shù)組從而完成關聯(lián)。
一個進程添加新規(guī)則的過程如圖3所示,。虛線箭頭表示控制流,。用戶進程發(fā)出系統(tǒng)調(diào)用在內(nèi)存中創(chuàng)建新規(guī)則及其規(guī)則索引,驅(qū)動程序代替它查詢用戶緩沖區(qū)得到一個空閑內(nèi)存塊的id標記號,然后這個id號關聯(lián)到新規(guī)則,也從而使用戶緩沖區(qū)的內(nèi)存塊、規(guī)則和用戶進程三者對應起來,最后規(guī)則被添加進入硬件,。值得注意的是,如果驅(qū)動程序發(fā)現(xiàn)內(nèi)存中已存在同樣的規(guī)則,它僅會把這個進程申請到的id號放在舊規(guī)則索引的數(shù)組最后,。
在做好其他相應的設置以后,應用進程會到自己的用戶緩沖區(qū)中查看是否有新的數(shù)據(jù)到來,。這里沒有采用常用的輪詢方法來檢查緩沖區(qū)。雖然輪詢不需要硬件特別的支持,但隨之帶來的問題也是明顯的,。頻率過高的輪詢會大量地消耗CPU的時鐘周期;時間間隔過大則會帶來數(shù)據(jù)包時間戳不準確,錯過收取數(shù)據(jù)的時機導致丟包等問題,。取而代之采用了一種中斷驅(qū)動的方法:用戶進程察看自己的緩沖區(qū)內(nèi)有沒有新數(shù)據(jù)的到來,如沒有則把自己掛到等待隊列開始睡眠;中斷來時,中斷處理函數(shù)收取數(shù)據(jù)包并發(fā)信號喚醒睡眠進程做讀操作,。
3.2.2 中斷處理過程
中斷的處理流程如圖4所示,。中斷來時,中斷處理函數(shù)首先根據(jù)內(nèi)核傳入的私有結(jié)構(gòu)dev_id[5]判斷到底是哪個設備產(chǎn)生中斷,然后檢查相應設備的中斷狀態(tài)寄存器,根據(jù)寄存器判斷中斷發(fā)生的不同原因決定是否進行DMA操作。DMA操作會在無需操作系統(tǒng)干預的情況下把數(shù)據(jù)塊從硬件外部高速存儲器搬到內(nèi)核公共緩沖區(qū),。公共緩沖區(qū)數(shù)據(jù)包自定義包頭經(jīng)過解析后得到cookie值,它對應著前文所述的規(guī)則索引,。驅(qū)動程序會根據(jù)規(guī)則索引把數(shù)據(jù)從公共緩沖區(qū)分發(fā)到相應進程的用戶緩沖區(qū)并喚醒等待隊列上的進程做讀取包和深度解析的工作。
在中斷處理過程中對于非搶占的Linux內(nèi)核涉及系統(tǒng)同步的問題,。為保護共享數(shù)據(jù)可能被非同步操作,整個中斷處理過程通過關中斷的方式來保護,。但對于擁有對稱多處理器(SMP)或加入搶占機制的系統(tǒng),需要做一些額外的處理:為了不影響其他處理器上的中斷處理,避免使用全局關中斷函數(shù),只禁用當前處理器的中斷,并利用不會睡眠的鎖如自旋鎖對所有可能引發(fā)同步問題的臨界區(qū)進行保護。在多設備的環(huán)境下,系統(tǒng)中的每個設備DMA操作前都必須擁有自己的鎖;為了避免數(shù)據(jù)混亂,每個設備都擁有各自的公共緩沖區(qū),而且從各自的公共緩沖區(qū)向用戶緩沖區(qū)寫數(shù)據(jù)前必須獲得一個全局鎖,從而實現(xiàn)寫操作的串行化,。
4 性能測試
實驗使用SmartBits測試儀模擬真實的網(wǎng)絡環(huán)境對本系統(tǒng)進行了測試,。測試硬件平臺為Intel P4 2.4GHz的處理器,1GB內(nèi)存,64位PCI總線;軟件平臺為Fedra core3。測試結(jié)果" title="測試結(jié)果">測試結(jié)果顯示傳統(tǒng)的Libpcap在400Mbps左右就已經(jīng)出現(xiàn)嚴重的丟包現(xiàn)象,而且受包長影響很大,。而本系統(tǒng)在單設備雙輸入的情況下,當包速率超過1 800Mbps才出現(xiàn)丟包現(xiàn)象,并基本不受包長變化影響,。另外測試結(jié)果表明本系統(tǒng)在Linux操作系統(tǒng)平臺下有較低的系統(tǒng)占用,如圖5所示本系統(tǒng)在不同包長的情況下處理器占用率均比Intel 光網(wǎng)卡 PRO/1000F要低得多。
本文在參考傳統(tǒng)網(wǎng)絡數(shù)據(jù)包捕獲方法的同時,針對傳統(tǒng)方法的一些弱點,提出一種軟硬件結(jié)合的包捕獲方案,。該方案由硬件完成數(shù)據(jù)包過濾的任務,并對軟件部分作了優(yōu)化,測試結(jié)果表明,該方案能滿足大多數(shù)高速網(wǎng)絡數(shù)據(jù)包捕獲任務的需要,具有廣泛的應用前景,。
參考文獻
1 White G B,Pooch U W.Cooperating security managers:Distributed intrusion detection systems.Computers & Security,,1996,;15(5):441~450
2 唐正軍,劉代志.網(wǎng)絡嗅探器Sniffer軟件源代碼淺3:采用Labpcap庫的通用設計.計算機工程,,2002,;28(2)
3 Jacobson V,Leres C,,McCanne S.The tcpdump manual page. Lawrence Berkeley Laboratory,,Berkeley,CA,,1997
4 Kurmann C,,Rauch F,Stricker T.Speculative defragmentation-leading gigabit ethernet to true Zero-Copy communication. Cluster Computing,,2001,;4(1):7~18
5 Rubini A,Corbet J著,,魏永明,,駱 剛,,姜 君譯.Linux設備驅(qū)動程序(第二版).北京:中國電力出版社,2004:275~276