摘要:網絡隔離器在隔離了可信網絡和不可信網絡的同時,允許信息在兩個網絡間安全傳輸。主要介紹使用USB實現網絡隔離器內部的數據交換。首先介紹了USB系統、USB通信模型和數據傳輸類型,然后介紹了Linux的USB子系統及主要數據結構,重點說明了使用libusb庫實現兩臺USB主機間的數據傳輸。
關鍵詞:網絡隔離;網閘;Linux;通用串行總線;libusb
中圖分類號:TP311.11文獻標志碼:A
文章編號:1001-3695(2007)08-0306-03
0引言
Linux操作系統結構清晰、功能強大,支持多用戶訪問和多任務編程,是一個穩定可靠、功能完善的操作系統。Linux源代碼開放,具有可訂制性和可裁減性,被廣泛應用于防火墻、安全網關、網絡隔離器等安全產品。在國家保密局發布的《計算機信息系統國際互聯網保密管理規定》中規定“涉及國家秘密的計算機信息系統,不得直接或間接地與國際互聯網或其他公共信息網絡相連接,必須進行物理隔離”。
物理隔離阻斷了內部網絡與Internet間的直接連接,是防范網絡攻擊的有效手段,但是同時也阻斷了必要的信息交換。基于網絡隔離的數據交換系統就是在保證兩個網絡安全隔離的基礎上實現信息的自動交換。本文基于國家2005信息安全專項“隔離專網之防病毒反入侵綜合管理與更新網關的產品產業化”。網絡隔離器主要由三部分組成:內網處理單元、外網處理單元和中間數據交換單元。在隔離器內部三個單元之間的通信必須在鏈路層上中止網絡連接[1]。USB具有低成本、支持即插即用、協議靈活、傳輸速率高的優點,本文將通過使用USB來實現網絡隔離器內部的安全數據交換。
1USB系統簡介
一個USB系統由USB主機、USB設備以及兩者之間的互連三個部分組成。USB主機和多個USB設備之間構成一個有層次性的星型結構。當一個USB設備連接到主機時,主機控制器會為這個設備分配一個惟一的地址(1~127),并且讀取該設備的描述符。
USB是一種被動的總線類型,所有USB主機與設備之間的通信都是由主機控制器發起的。USB的數據傳輸是在主機軟件與USB設備上指定端點之間進行的。主機和端點之間的連接稱為管道(pipe)。一個端點只支持一個方向的數據傳輸,或支持數據流入設備,或支持數據流出設備。0號端點是所有USB設備的缺省端點。當外設連接到USB,被供電并接收到總線復位信號后,USB系統軟件就可通過0號端點初始化并操作USB設備了。除0號缺省端點外,其他的端點只有設置后才能被使用。
圖1以分層結構顯示了USB的通信模型。其中最底層是USB接口層(USB interface layer),它提供了USB主機與設備之間的物理連接;中間層是USB設備層(USB device layer),它負責處理所有USB的數據傳輸,在主機端,除了對控制傳輸進行分析外,其余的直接送往上層;最上層是功能接口層,提供了不同類USB設備的驅動程序,在設備端對應的實體是設備中不同的接口。
USB協議中定義了四種數據傳輸類型,即控制傳輸、批量傳輸、中斷傳輸、等時傳輸。控制傳輸把特定的設備請求傳送給USB設備,用來配置設備、控制設備狀態等。它是一種可靠的、非周期性的傳輸。批量傳輸用于傳輸批量的、沒有周期和傳輸速率要求的數據。中斷傳輸通過對設備的查詢以確定設備是否有數據需要傳輸,主機控制器以指定的時間間隔向設備周期性地發送中斷請求。等時傳輸用于要求以恒定速率實時傳輸的數據流,但對所傳送數據是否正確并無要求,常用于音頻和視頻數據的傳送[2,3]。
2Linux中的USB子系統
Linux系統中將設備分為字符設備、塊設備和網絡設備三種類型。每個USB設備由一個USB模塊驅動。該USB模塊和USB子系統一同工作;但是在底層,每個USB設備仍然表現為一個字符設備、塊設備或網絡設備(USB以太網接口)。
2.1USB內核
Linux中的USB體系結構分為三層,如圖2所示,類似于規范中建議的結構。Linux內核中提供了一個稱為USB core的模塊,該模塊連接了上層USB設備驅動程序和下層主控制器驅動程序。Linux的USB內核主要由文件usb.h和usb.c組成。USB core模塊包含了所有USB設備驅動和USB主控制器驅動的通用程序,它通過定義一些數據結構、宏和功能函數抽象了所有的硬件設備,給出專門的API來支持上層設備驅動程序和下層主控制器驅動程序。另外,USB內核還具有維護設備的加載/卸載、負責設備的默認配置、連接設備與對應的驅動程序關聯等功能。
2.2主要數據結構
Linux的USB內核中定義了struct usb_bus、struct usb_device、struct urb、struct usb_driver等與設備驅動程序相關的核心數據結構。
1)struct usb_bus描述了USB的總線結構。從該數據結構中可以獲得USB系統的基本信息,如總線上的設備地址信息、子系統的根集線器、子系統中當前帶寬的使用情況、子系統中當前中斷傳輸和等時傳輸的數量。
struct usb_bus {
struct usb_device *root_hub; //根集線器
struct list_head bus_list;
//雙向指針,維護系統中所有的USB總線系統
int bandwidth_allocated; //帶寬使用情況
int bandwidth_int_reqs; //中斷傳輸數量
……
};
2)struct usb_device描述了一個USB設備的基本信息,包括設備分配的地址、設備描述符信息、配置描述符和其包含的接口描述符、端點描述符的指針等。該數據結構主要用于設備的初始化過程中。
struct usb_device {
int devnum; //為設備分配的地址
struct usb_bus *bus; //設備所屬USB系統
struct usb_device_descriptor descriptor; //設備描述符信息
struct usb_host_config *config; //配置描述符的指針
……
};
3)struct urb在Linux的USB子系統中,所有的數據傳輸都使用URB請求塊(USB request block)的數據結構實現。它包含了建立任何USB傳輸所需的所有信息,并貫穿于USB協議對數據處理的整個過程。其中:*dev指向某一個指定的USB設備;pipe指向與管道關聯的USB設備一端的設備端點;*transfer_buffer指向與管道關聯的USB主機一端的數據緩沖區[5]。
4)struct usb_driver主要用于在Linux內核中注冊一個USB設備驅動程序。包括設備驅動程序的名字、指向驅動程序所屬模塊的指針、兩個注冊的入口點:設備初始化函數指針*probe()和設備卸載函數指針*disconnect()等信息。
3主機間USB通信的實現
USB總線采用的是主/從工作模式(master to slave)。USB主機根據各設備的屬性周期性地訪問各個設備。USB設備被動地響應USB主機的訪問請求。對于兩個USB主機之間,由于是主/主的結構(master to master),直接使用USB連接線相連是無法實現雙方通信的。
為了實現主機間的USB通信,需要實現主—從—主的結構。本文通過使用嵌入Ali M5632控制芯片的數據傳輸線(hosttohost link),在兩個USB主機之間起到橋梁和中介的作用,實現主機間點到點的USB通信。M5632控制芯片提供了四種可配置端點,分別支持64 Byte FIFO控制傳輸、512 Byte乒乓緩沖器批量輸入/輸出傳輸、16 Byte乒乓緩沖器中斷傳輸。
在Linux主機上可以通過調用libusb庫實現用戶空間的應用程序與USB設備之間的通信。Libusb封裝了與內核的交互,通過向外界提供一組高層接口,方便用戶對USB設備的訪問[6]。以下將通過libusb提供的功能函數實現USB主機間的數據傳輸。
3.1設備初始化
在使用libusb之前需要首先進行初始化,通過調用usb_init(),libusb建立一些內部結構。在對指定USB設備操作之前,必須先在USB上找到該設備。USB設備描述符中的idVendor和idProduct域分別指定了廠商標志和產品標志,通過這兩個域可以指定一個USB設備。Ali M5632控制芯片的idVendor和idProduct分別是0x0402、0x5632。在獲取指定的USB設備后,可以通過usb_device結構體中的descriptor成員、*config成員獲得USB設備描述符、配置描述符、接口描述符和端點描述符的詳細信息。圖3給出了獲取指定USB設備時usb_bus、usb_device以及各種USB描述符等數據結構之間的協作關系圖。
下面給出了查找、獲取Ali M5632 USB數據傳輸線設備的簡要代碼:
#define VENDOR_ID 0x0402
#define PRODUCT_ID 0x5632
struct usb_device *find_device(){
……
struct usb_bus *busses=usb_get_busses();
for(bus=busses; bus; bus=bus>next){
for(device=bus>devices; device; device=device>next){
if(device>descriptor.idVendor==VENDOR_ID device>descriptor.idProduct==PRODUCT_ID){
return device;
}
}
}
return NULL;
}
3.2打開設備
在通過libusb使用USB設備之前,首先必須打開該設備。USB設備由許多不同的邏輯單元構成。通常一個USB設備有一個或多個配置,配置有一個或多個接口,接口又有零個或多個端點。在打開USB設備后,需要激活其中的一個配置并聲明配置中的一個接口。
Libusb庫中在對USB設備的某一接口進行任何操作之前,必須首先調用庫函數usb_claim_interface(usb_dev_handle *dev, int interface)對這一接口進行聲明。該API返回0表示對接口的聲明成功,返回值小于0表示聲明失敗。只有對一個接口成功地聲明后才可以激活該接口,并使用接口中的端點進行各種傳輸。
3.3控制傳輸的實現
USB支持四種數據傳輸類型,包括控制傳輸、批量傳輸、中斷傳輸和等時傳輸。其中控制傳輸用來對USB設備進行初始化和配置管理,所有的USB設備都要支持控制傳輸。在USB系統中,USB設備正常工作之前必須先進行配置,完成對設備上的端點配置管道、分配帶寬等工作。
在進行控制傳輸時,先要由主機向設備發一個總線建立(setup)信息,它描述了控制訪問的類型,設備對主機的請求發出響應。USB主機負責設置setup包內每個域的值,在libusb庫中提供了用于控制傳輸的API。庫函數usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout)中,參數dev表示指定USB設備的句柄,參數requesttype、request、value、index的值分別與協議規范中setup包中相應域bmRequestType、bRequest、wValue、wIndex的值相對應,參數*bytes、size表示數據緩沖區的地址和發送數據的長度。
在USB協議中規定每個setup包有八個字節。其中bmRequestType域占據一個字節,表明此請求的特性。其中:D7位表明傳輸的方向,D7=0表示從主機到設備,D7=1表示從設備到主機;D6..5位表明請求的種類,D6..5=00表示標準請求,D6..5=01表示類請求,D6..5=10表示廠商自定義請求;D4..0表示請求的接收者,一個請求可以被引導到設備上,也可以被引導到接口或一個端點上。
USB協議中定義了11個標準請求,這些請求主要用于配置設備、獲取設備信息等操作,如獲取設備描述符信息、指定設備地址等。在對Ali M5632控制芯片操作時,需要使用設備廠商提供的自定義請求對USB設備進行配置。
3.4批量傳輸的實現
當打開USB設備,對設備的接口進行了成功的聲明,并對設備進行了基本配置后,就可以方便地使用批量傳輸方式進行數據的傳輸。在libusb中提供了兩種批量傳輸的API,即批量傳輸讀usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)和批量傳輸寫usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)。在這兩個API中,ep表示用于批量傳輸的端點。由于單一端點只能實現數據的讀出或寫入,對于批量讀和批量寫需要分別指定端點。
3.5實驗結論
在Linux中,libusb庫的默認路徑是/usr/lib,在對源文件進行編譯時,需要添加對libusb庫的引用。為了驗證傳輸的有效性和穩定性,在USB主機A上讀入一個普通字符數據文件,通過批量傳輸發送給另一臺USB主機B,主機B接收到數據后寫入本地磁盤,經過對比源和目標文件發現兩個文件內容完全相同。實驗結論表明,所開發的程序可以成功地實現兩個USB主機之間的數據通信。
4結束語
在網絡隔離環境下,為有效阻斷網絡攻擊,隔離單元中的數據交換子系統必須在鏈路層切斷網絡連接。通過使用USB實現隔離單元內部的數據交換,可以有效地阻斷網絡連接,提升安全性。在今后的工作中,筆者還將作進一步改進,在保證隔離的前提下,進一步提高隔離單元內部數據交換的效率。
參考文獻:
[1]岳紅梅,石冬雪,徐詠梅,等. 基于嵌入式Linux的網絡隔離系統研究與實現[J].計算機工程與應用,2005,41(5):141143.
[2]Universal serial bus specification reversion 1.1[S].
[3]Universal serial bus specification reversion 2.0[S].
[4]MSCTCGFJ-04,信息技術網閘產品安全檢驗規范[S].
[5]梁正平,毋國慶,肖敬. Linux中USB設備驅動程序研究[J].計算機應用研究,2004,21(6):70-72.
[6]Libusb project[EB/OL].http://libusb.sourceforge.net/.
[7]鄧智群,劉福,慕德俊,等.網絡隔離體系結構研究[J].計算機應用研究,2005,22(5):219-221.
[8]巍騖,張煥強,方明貴.基于Linux的USB驅動程序實現[J].計算機應用,2002,22(8):1719.
[9]CORBET J,RUBINI A, KroahHartman G.Linux設備驅動程序[M].魏永明,耿岳,鐘書毅,譯.3版.北京:中國電力出版社,2005:324-358.
注:“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”