洪進(jìn)棟,焦鳳先,魏 榕
(1.西安電子科技大學(xué)電子工程學(xué)院,陜西西安 710126;2.西安電子科技大學(xué)通信工程學(xué)院,陜西西安 710126;3.西安電子科技大學(xué)微電子學(xué)院,陜西西安 710126)
隨著網(wǎng)絡(luò)技術(shù)的發(fā)展,各種網(wǎng)絡(luò)終端越來越多;使用NAT技術(shù)接入Internet的小型局域網(wǎng)在家庭、實(shí)驗(yàn)室等場合的應(yīng)用更加普及。然而,無論是Windows自帶的Internet共享(NAT)功能,還是傳統(tǒng)小型路由器,一般都不具備流量監(jiān)控、網(wǎng)絡(luò)監(jiān)管、數(shù)據(jù)過濾功能,無法滿足網(wǎng)絡(luò)安全的需求。
要在Windows自帶NAT的基礎(chǔ)上加入上述功能,由于該模塊工作于內(nèi)核模式下,需要通過加入Windows內(nèi)核模塊實(shí)現(xiàn),開發(fā)難度較高。為解決這一問題,本文提出了一種工作于Windows用戶模式的NAT路由器,并使用WinPcap實(shí)現(xiàn)了該方案。該路由預(yù)留了過濾層接口,能夠快速加入流量監(jiān)控、網(wǎng)絡(luò)監(jiān)管、數(shù)據(jù)過濾的功能。
NAT(Network Address Translation,網(wǎng)絡(luò)地址轉(zhuǎn)換)是一種將實(shí)現(xiàn)局域網(wǎng)內(nèi)每個(gè)節(jié)點(diǎn)的私有IP地址轉(zhuǎn)換成一個(gè)統(tǒng)一的公有IP地址和相應(yīng)的反向轉(zhuǎn)換的技術(shù),從而實(shí)現(xiàn)多個(gè)網(wǎng)絡(luò)終端共用一個(gè)公有IP地址接入互聯(lián)網(wǎng)。
NAT路由器的核心功能是在內(nèi)網(wǎng)發(fā)送網(wǎng)絡(luò)數(shù)據(jù)包時(shí),將內(nèi)部私有IP地址翻譯成外部合法公有IP地址;在接收到外網(wǎng)數(shù)據(jù)包時(shí),將外部IP地址翻譯回內(nèi)部對應(yīng)的私有IP地址。同時(shí),有部分?jǐn)?shù)據(jù)包僅在外部網(wǎng)絡(luò)進(jìn)行通信,或者在內(nèi)部網(wǎng)絡(luò)進(jìn)行通信,不需要在內(nèi)部和外部網(wǎng)絡(luò)之間相互轉(zhuǎn)發(fā),因而這部分?jǐn)?shù)據(jù)包不需要進(jìn)行地址轉(zhuǎn)換。
NAT的實(shí)現(xiàn)機(jī)制是將某一對私有IP地址、端口和公有IP地址的某個(gè)端口建立映射關(guān)系,并將這兩個(gè)端口的數(shù)據(jù)包經(jīng)過替換IP、端口等處理之后相互轉(zhuǎn)發(fā)。
NAT技術(shù)解決了IP地址緊缺的問題,實(shí)現(xiàn)公有和私有IP地址之間的映射,而且能使內(nèi)部和外部的網(wǎng)絡(luò)隔離,提供一定程度的網(wǎng)絡(luò)安全保障。因而,NAT技術(shù)在中小型局域網(wǎng)廣泛應(yīng)用,使得多個(gè)終端共用一個(gè)公有IP地址上網(wǎng)。
在典型的小型局域網(wǎng)中,NAT路由器通常分為2組端口,一組稱為WAN口,配置公有IP接入互聯(lián)網(wǎng);另一組端口稱為LAN口,配置私有IP接入局域網(wǎng)。NAT路由完成者2組端口之間的數(shù)據(jù)轉(zhuǎn)發(fā)工作。
WinPcap是一個(gè)用于捕獲、處理網(wǎng)絡(luò)數(shù)據(jù)包析的開源庫,應(yīng)用于 Windows平臺[1]。
在Windows平臺下,大多數(shù)網(wǎng)絡(luò)應(yīng)用程序通過諸如Sockets等操作系統(tǒng)元件來訪問網(wǎng)絡(luò)。該方法的優(yōu)點(diǎn)是簡單,且類似于文件讀寫,因?yàn)椴僮飨到y(tǒng)已經(jīng)妥善處理了底層具體實(shí)現(xiàn)細(xì)節(jié)。然而,實(shí)現(xiàn)NAT路由需要直接發(fā)送和接收網(wǎng)絡(luò)中的原始數(shù)據(jù)包,即沒有被操作系統(tǒng)利用網(wǎng)絡(luò)協(xié)議處理過的數(shù)據(jù)包[2]。本項(xiàng)目通過WinPcap來實(shí)現(xiàn)訪問網(wǎng)絡(luò)原始數(shù)據(jù)包。
圖1 WinPcap結(jié)構(gòu)圖
WinPcap就是一個(gè)能為Win32應(yīng)用程序提供訪問網(wǎng)絡(luò)原始數(shù)據(jù)包的開源庫,主要提供了以下功能:(1)捕獲原始數(shù)據(jù)包,包括發(fā)往本機(jī)和其他終端的數(shù)據(jù)包。(2)根據(jù)用戶指定的規(guī)則過濾數(shù)據(jù)包,然后再將剩余數(shù)據(jù)包發(fā)到給應(yīng)用程序。(3)使用網(wǎng)絡(luò)適配器將原始數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)中。(4)收集并統(tǒng)計(jì)網(wǎng)絡(luò)流量信息。
WinPcap借助安裝在Win32內(nèi)核中的網(wǎng)絡(luò)設(shè)備驅(qū)動程序,以及幾個(gè)動態(tài)鏈接庫dll實(shí)現(xiàn)了上述功能;并且,WinPcap將這些功能都規(guī)范成統(tǒng)一的編程接口,使得訪問網(wǎng)絡(luò)原始數(shù)據(jù)包變得較容易,并能在不同的Windows操作系統(tǒng)上使用[3]。
在以上原理的基礎(chǔ)上,就可用WinPcap實(shí)現(xiàn)NAT路由功能。本項(xiàng)目使用一臺配置兩個(gè)網(wǎng)卡的Windows平臺;其中一個(gè)網(wǎng)卡作為外網(wǎng)網(wǎng)卡,配置公有IP地址接入互聯(lián)網(wǎng),另一個(gè)網(wǎng)卡作為內(nèi)網(wǎng)網(wǎng)卡,配置私有IP接入局域網(wǎng);所開發(fā)的NAT路由軟件就是需要完成這個(gè)兩個(gè)網(wǎng)卡之間數(shù)據(jù)包的轉(zhuǎn)發(fā)以及對應(yīng)的NAT協(xié)議處理,如圖2所示。
圖2 基于WinPcap的NAT路由工作流程
數(shù)據(jù)包捕獲是指使用WinPcap從外網(wǎng)網(wǎng)卡和內(nèi)網(wǎng)網(wǎng)卡獲得網(wǎng)絡(luò)原始數(shù)據(jù)包,預(yù)處理則完成部分?jǐn)?shù)據(jù)包的篩選工作。
?陳國青等:《工商管理學(xué)科“十三五”發(fā)展戰(zhàn)略與優(yōu)先資助領(lǐng)域研究報(bào)告》,科學(xué)出版社2016年版,第101頁。
首先,獲得已連接的網(wǎng)絡(luò)適配器(即網(wǎng)卡)列表。WinPcap提供了pcap_findalldevs_ex()函數(shù)來實(shí)現(xiàn)此功能:這個(gè)函數(shù)返回一個(gè) pcap_if結(jié)構(gòu)的鏈表,每個(gè)pcap_if結(jié)構(gòu)都包含了一個(gè)適配器的詳細(xì)信息。pcap_if結(jié)構(gòu)數(shù)據(jù)域name和description表示一個(gè)適配器名稱和一個(gè)描述。獲取網(wǎng)絡(luò)適配器列表后,就可利用pcap_open()函數(shù)打開網(wǎng)絡(luò)適配器[2]。
然后,從列表中選擇外網(wǎng)網(wǎng)絡(luò)適配器和內(nèi)網(wǎng)網(wǎng)絡(luò)適配器,并使用pcap_open()函數(shù)打開它們。當(dāng)適配器被打開,捕獲工作就可以用pcap_loop()進(jìn)行。這個(gè)函數(shù)有一個(gè)回調(diào)參數(shù)packet_handler,指向一個(gè)可以處理所接收數(shù)據(jù)包的函數(shù)。這個(gè)函數(shù)會在收到每個(gè)新的數(shù)據(jù)包時(shí)被WinPcap所調(diào)用,并向該函數(shù)提供一個(gè)指向pcap_pkthdr和 pkt_data結(jié)構(gòu)指針。pcap_pkthdr結(jié)構(gòu)一般有一些諸如時(shí)間戳、數(shù)據(jù)包長度的信息;pkt_data結(jié)構(gòu)則包含了網(wǎng)絡(luò)中的實(shí)際數(shù)據(jù)。
在回調(diào)函數(shù)中,我們對捕獲的數(shù)據(jù)包進(jìn)行預(yù)處理:篩選了TCP、UDP、ARP數(shù)據(jù)包存放到緩沖池,對于其他協(xié)議的數(shù)據(jù)包,直接丟棄。需要注意,將從內(nèi)網(wǎng)網(wǎng)卡和外網(wǎng)網(wǎng)卡捕獲的數(shù)據(jù)包分別存儲到單獨(dú)的緩沖池。
為提高程序處理數(shù)據(jù)包的效率,利用Queue(隊(duì)列)這種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)一個(gè)緩沖池。
程序使用的緩沖池設(shè)計(jì)如下:緩沖池由2個(gè)工作Thread(線程)和一個(gè)Queue組成,一個(gè)線程負(fù)責(zé)把數(shù)據(jù)包放到Queue里面,而另一個(gè)Thread就依次取出這些數(shù)據(jù)包并進(jìn)行處理。
Queue的一個(gè)經(jīng)典實(shí)現(xiàn)是使用一個(gè)循環(huán)數(shù)組,如一個(gè)大小為size的數(shù)組,這個(gè)循環(huán)數(shù)組可以被想象成首尾相連的一個(gè)環(huán)。同時(shí),使用first指針指向Queue中最早存入的數(shù)據(jù)的位置,next指向下一個(gè)可以放新數(shù)據(jù)的位置[4]。
當(dāng)添加一個(gè)新數(shù)據(jù)到到Queue時(shí),該數(shù)據(jù)被存到next的位置,同時(shí)需要更新next:next=(next+1)%size;
當(dāng)first==next的時(shí)候,Queue為空;
當(dāng)(next+1)%size==first時(shí),Queue為滿。
注意,為了區(qū)分Queue為空和為滿的情況,實(shí)際上Queue里面最多能放size-1個(gè)數(shù)據(jù)。
在本項(xiàng)目中,Queue會同時(shí)被2個(gè)線程訪問,需要考慮在多線程的情況下Queue如何正常工作,因而,采取了以下措施:首先,Queue是線程安全,使用Windows API提供的互斥體Mutex來確保同時(shí)只有一個(gè)Thread在訪問Queue;其次,要防止Queue為空的取出數(shù)據(jù)操作,或者Queue為滿的時(shí)候的數(shù)據(jù)存入操作。在多線程訪問遇到這種情況時(shí),一般希望執(zhí)行操作的線程可以等待直到該操作可以進(jìn)行下去。通過wait和notify方法使Thread在上述兩種操作進(jìn)行時(shí)等待(block),直到訪問Queue另一個(gè)進(jìn)程存入或取出數(shù)據(jù)。
在本項(xiàng)目中,由接收網(wǎng)絡(luò)數(shù)據(jù)包的線程將網(wǎng)絡(luò)數(shù)據(jù)包放到Queue里,由處理數(shù)據(jù)包并轉(zhuǎn)發(fā)的線程負(fù)責(zé)取出數(shù)據(jù)包;并且,為兩個(gè)網(wǎng)絡(luò)適配器分別實(shí)例化了一個(gè)互相的獨(dú)立的Queue。
WinPcap接收到的網(wǎng)絡(luò)原始數(shù)據(jù)包只包含幀頭和載荷部分。NAT路由的核心工作是轉(zhuǎn)發(fā)IP層的TCP和UDP數(shù)據(jù)包[5]。因而,協(xié)議分析則是將接收到的類型為TCP和UDP數(shù)據(jù)包分解為對應(yīng)的9個(gè)部分并進(jìn)行分析,即目的MAC、源MAC、幀類型、目的IP、目的端口、源IP、源端口、IP校驗(yàn)和以及數(shù)據(jù)。
在對數(shù)據(jù)包記性協(xié)議分析后,可以針對特定的數(shù)據(jù)包進(jìn)行過濾,可完成流量統(tǒng)計(jì)、網(wǎng)絡(luò)行為控制等功能。在本項(xiàng)目中,預(yù)留了過濾層接口,用于進(jìn)一步擴(kuò)展功能。
對于數(shù)據(jù)包的NAT轉(zhuǎn)換處理,需要對內(nèi)網(wǎng)發(fā)送的數(shù)據(jù)包和外網(wǎng)接收的數(shù)據(jù)包做不同的處理;在數(shù)據(jù)處理之前,初始化化了一個(gè)空路由表,路由表單條記錄的格式為:內(nèi)網(wǎng)IP、端口、MAC地址、外網(wǎng)端口。
對于內(nèi)網(wǎng)發(fā)送的數(shù)據(jù)包,完成NAT轉(zhuǎn)換的數(shù)據(jù)處理如下:(1)根據(jù)數(shù)據(jù)包的源IP、端口,在路由表查找內(nèi)網(wǎng)IP、端口都相同的記錄,如果存在相應(yīng)的記錄,則獲取其外網(wǎng)端口;否則,選用一個(gè)未占用的外網(wǎng)端口,新建一條路由記錄;(2)將數(shù)據(jù)包的源端口替換成上一步獲取的端口,同時(shí)將源IP、源MAC替換成外網(wǎng)網(wǎng)卡的IP、MAC地址,目的MAC地址替換成外網(wǎng)下一跳的MAC地址。(3)重新計(jì)算IP校驗(yàn)和。
對于接收到的外網(wǎng)數(shù)據(jù)包,完成NAT轉(zhuǎn)換的數(shù)據(jù)處理過程如下:(1)根據(jù)數(shù)據(jù)包的目的端口,在路由表查找外網(wǎng)端口相同的記錄,如果存在,則獲取內(nèi)網(wǎng)IP、端口、MAC地址;否則,丟棄該數(shù)據(jù)包。(2)將數(shù)據(jù)包的目的IP、端口、目的MAC地址替換成上一步獲取到的內(nèi)網(wǎng)IP、端口、MAC地址,同時(shí)將源MAC替換成本機(jī)內(nèi)網(wǎng)網(wǎng)卡的MAC地址。(3)重新計(jì)算IP校驗(yàn)和。
數(shù)據(jù)包處理完成后,該數(shù)據(jù)包就可以被轉(zhuǎn)發(fā)了。
在一個(gè)網(wǎng)卡上捕獲的數(shù)據(jù)包,按照NAT協(xié)議,經(jīng)過內(nèi)外網(wǎng)地址轉(zhuǎn)換、端口轉(zhuǎn)換后,需要在另一個(gè)網(wǎng)卡上發(fā)送。WinPcap的Pcap_sendpacket()函數(shù)提供了一個(gè)簡單而又直接的方法來發(fā)送一個(gè)數(shù)據(jù)包;同時(shí),由于對于發(fā)送數(shù)據(jù)包,WinPcap內(nèi)部已經(jīng)有緩沖機(jī)制,本項(xiàng)目中不需要緩沖發(fā)送隊(duì)列。
測試環(huán)境:Windows Server 2003服務(wù)器一臺,服務(wù)器配置兩塊百兆網(wǎng)卡,其中一塊網(wǎng)卡接入Internet,另一塊網(wǎng)卡接交換機(jī)設(shè)備,與若干臺客戶機(jī)連接形成內(nèi)網(wǎng)。
Windows Server 2003服務(wù)器運(yùn)行上述NAT路由器,為內(nèi)網(wǎng)電腦提供Internet接入共享;手動為內(nèi)網(wǎng)設(shè)備分配私有IP。測試軟件采用通用路由測試軟件IxChariot測試。
測試結(jié)果:在功能測試方面,在內(nèi)網(wǎng)的客戶機(jī)均能通過服務(wù)器的網(wǎng)絡(luò)共享正常上網(wǎng),說明路由器功能正常。
同時(shí)測試本方案的NAT路由和Fast FW300R小型家用路由器,結(jié)果如表1所示。
表1 測試結(jié)果對比
在實(shí)際使用中,內(nèi)網(wǎng)訪問互聯(lián)網(wǎng)的速度最高可達(dá)65 Mbit·s-1,能滿足一般小型局域網(wǎng)的要求。
設(shè)計(jì)了一種工作于Windows用戶模式的NAT路由器,并使用WinPcap實(shí)現(xiàn)了這種方案;經(jīng)測試,該路由器功能正常,性能能夠達(dá)到中檔路由器的水平,預(yù)留的過濾層可以滿足功能擴(kuò)展的需求。
[1] 胡曉元,史浩山.WinPcap包截獲系統(tǒng)的分析及其應(yīng)用[J].軟件技術(shù)與數(shù)據(jù)庫,2005(2):96 -99.
[2] 于雷.WinPcap在網(wǎng)絡(luò)監(jiān)聽管理中的應(yīng)用研究[J].電腦知識與技術(shù),2012,8(7):59 -62.
[3] 李延會,岳彩祥,徐金艷,等.基于Winpcap的數(shù)據(jù)包捕獲和協(xié)議分析系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].中國科技信息,2009(10):89-92.
[4] 王麗珍.數(shù)據(jù)倉庫與數(shù)據(jù)挖掘原理及應(yīng)用[M].北京:科學(xué)出版社,2005.
[5] 李小玲,周金治.網(wǎng)絡(luò)地址轉(zhuǎn)換技術(shù)在計(jì)算機(jī)網(wǎng)絡(luò)上的應(yīng)用[J].山東科技大學(xué)學(xué)報(bào):自然科學(xué)版,2004(2):168 -172.