Windows網(wǎng)絡編程實用教程:第9章 基于WinPcap技術(shù)的網(wǎng)絡數(shù)據(jù)包捕獲、過濾和分析技術(shù)_第1頁
Windows網(wǎng)絡編程實用教程:第9章 基于WinPcap技術(shù)的網(wǎng)絡數(shù)據(jù)包捕獲、過濾和分析技術(shù)_第2頁
Windows網(wǎng)絡編程實用教程:第9章 基于WinPcap技術(shù)的網(wǎng)絡數(shù)據(jù)包捕獲、過濾和分析技術(shù)_第3頁
Windows網(wǎng)絡編程實用教程:第9章 基于WinPcap技術(shù)的網(wǎng)絡數(shù)據(jù)包捕獲、過濾和分析技術(shù)_第4頁
Windows網(wǎng)絡編程實用教程:第9章 基于WinPcap技術(shù)的網(wǎng)絡數(shù)據(jù)包捕獲、過濾和分析技術(shù)_第5頁
已閱讀5頁,還剩71頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

1、第9章 基于WinPcap技術(shù)的網(wǎng)絡數(shù)據(jù)包捕獲、過濾和分析技術(shù)課程描述本章介紹基于WinPcap技術(shù)的網(wǎng)絡數(shù)據(jù)包捕獲、過濾和分析技術(shù)。如果在網(wǎng)絡出口位置對網(wǎng)絡中的數(shù)據(jù)包進行捕獲和分析,就可以統(tǒng)計出哪個IP地址的流量最大、這些流量都是基于哪些協(xié)議和應用的、產(chǎn)生這些流量的時間等,有了這些“鐵證”,對違規(guī)行為進行管理也就變得簡單多了。本章知識點9.1 WinPcap技術(shù)基礎9.2 下載和安裝WinPcap開發(fā)包9.3 在Visual C+中使用WinPcap技術(shù)9.1 WinPcap技術(shù)基礎9.1.1 WinPcap的體系結(jié)構(gòu)9.1.2 NIC驅(qū)動器和NDIS9.1.3 網(wǎng)絡組包過濾(NPF)模塊9

2、.1.4 捕獲數(shù)據(jù)包的原理和步驟9.1.1 WinPcap的體系結(jié)構(gòu)WinPcap是Windows Packet Capture的縮寫,即Windows平臺下的網(wǎng)絡數(shù)據(jù)包捕獲庫。它可以獨立于TCP/IP協(xié)議發(fā)送和接收原始數(shù)據(jù)包,其主要功能如下:繞開網(wǎng)絡協(xié)議棧捕獲網(wǎng)絡數(shù)據(jù)包,支持遠程數(shù)據(jù)包捕獲功能。在數(shù)據(jù)包發(fā)送到應用程序之前,按照指定的規(guī)則實現(xiàn)核心層數(shù)據(jù)包過濾。在網(wǎng)絡上發(fā)送原始數(shù)據(jù)包。收集網(wǎng)絡通信過程中的統(tǒng)計信息。WinPcap體系結(jié)構(gòu) WinPcap的體系結(jié)構(gòu)包含3個層次WinPcap的體系結(jié)構(gòu)包含3個層次,即網(wǎng)絡、核心層和用戶層。網(wǎng)絡:代表網(wǎng)絡中數(shù)據(jù)包。核心層:其中包含NPF模塊和NIC驅(qū)動

3、器。NPF(Netgroup Packet Filter,網(wǎng)絡組包過濾)是WinPcap的核心部分,它用于處理網(wǎng)絡上傳輸?shù)臄?shù)據(jù)包,并對用戶級提供捕獲、發(fā)送和分析數(shù)據(jù)包的能力;NIC(Network Interface Card,網(wǎng)絡適配器)驅(qū)動器直接管理網(wǎng)絡接口卡,NIC驅(qū)動器接口可以直接從硬件控制處理中斷、重設NIC、暫停NIC等;NDIS(Network Driver Interface Specification,網(wǎng)絡驅(qū)動接口規(guī)范)是定義網(wǎng)絡適配器和協(xié)議驅(qū)動(TCP/IP實現(xiàn)的)之間的通信的標準。用戶層:其中包含用戶代碼以及wpcap.dll和packet.dll兩個動態(tài)鏈接庫。以簡潔方

4、式來描述WinPcap體系結(jié)構(gòu)9.1.2 NIC驅(qū)動器和NDIS網(wǎng)絡接口卡和NIC驅(qū)動器中間層驅(qū)動器傳輸驅(qū)動器或者協(xié)議驅(qū)動器1網(wǎng)絡接口卡和NIC驅(qū)動器NIC驅(qū)動器可以直接管理網(wǎng)絡接口卡。它的下端接口與硬件關(guān)聯(lián),而其上端接口允許高層向網(wǎng)絡中發(fā)送數(shù)據(jù)包、處理中斷、重置網(wǎng)絡適配器、中止網(wǎng)絡適配器以及查詢和設置驅(qū)動器的操作屬性。NIC驅(qū)動器可以是微端口,也可以是傳統(tǒng)的完全NIC驅(qū)動器。微端口僅實現(xiàn)硬件指定的、用于管理網(wǎng)絡適配器的必要操作,包括在網(wǎng)絡適配器上發(fā)送和接收數(shù)據(jù)。大多數(shù)最低層NIC驅(qū)動器的操作(例如同步操作)都是由NDIS操作的。微端口不會直接調(diào)用操作系統(tǒng)例程,NDIS是微端口訪問操作系統(tǒng)的接

5、口。微端口將數(shù)據(jù)包傳送到NDIS,而NDIS確保這些數(shù)據(jù)包會傳送給正確的網(wǎng)絡協(xié)議。完全NIC驅(qū)動器用于執(zhí)行硬件指定的操作以及所有由NDIS完成的同步和隊列操作。2中間層驅(qū)動器中間層驅(qū)動器接口位于高層驅(qū)動器(例如協(xié)議驅(qū)動器)和一個微端口之間。對于高層驅(qū)動器而言,中間層驅(qū)動器就像微端口一樣;而在微端口看來,中間層驅(qū)動器就像是協(xié)議驅(qū)動器。一個中間層協(xié)議可以在另一個中間層驅(qū)動器之上,盡管這種分層方法可能給系統(tǒng)性能帶來副作用。開發(fā)中間層驅(qū)動器的主要原因是實現(xiàn)已有傳統(tǒng)協(xié)議驅(qū)動器和微端口之間的介質(zhì)轉(zhuǎn)換,這樣就可以管理協(xié)議驅(qū)動器不知道的新介質(zhì)類型的網(wǎng)絡適配器。例如,中間層驅(qū)動器可以將LAN協(xié)議轉(zhuǎn)換為ATM協(xié)議

6、。中間層驅(qū)動器無法與用戶模式應用程序進行通信,而只能與其他NDIS驅(qū)動器通信。3傳輸驅(qū)動器或者協(xié)議驅(qū)動器協(xié)議驅(qū)動器用于實現(xiàn)網(wǎng)絡協(xié)議棧,例如IPX/SPX或者TCP/IP,它可以為網(wǎng)絡適配器提供服務。協(xié)議驅(qū)動器為其上層的應用程序?qū)拥目蛻舳颂峁┓?,并且與其下層的NIC驅(qū)動器或者中間NDIS驅(qū)動器相連。NPF是協(xié)議驅(qū)動器的一種實現(xiàn)。從性能的角度來看,這并不是最佳的選擇。但它允許獨立于MAC層完全訪問裸流量。9.1.3 網(wǎng)絡組包過濾(NPF)模塊1數(shù)據(jù)包的捕獲和過濾捕獲數(shù)據(jù)庫是WinPcap的核心技術(shù)。在捕獲時,驅(qū)動器使用網(wǎng)絡接口嗅探數(shù)據(jù)包,并把它們完整地傳送到用戶層應用程序??梢钥吹剑东@數(shù)據(jù)包時

7、使用了兩個組件,即過濾器和核心緩沖區(qū)。2監(jiān)測和統(tǒng)計NPF中包含一個可編程的監(jiān)測模塊,它可以對網(wǎng)絡流量進行簡單的統(tǒng)計和計算。不需要把數(shù)據(jù)包復制到用戶層應用程序,只要簡單地接收和顯示從監(jiān)測引擎獲得的結(jié)果即可收集到統(tǒng)計信息。不需要捕獲數(shù)據(jù)包,也就避免了捕獲過程中可能耗費的CPU和內(nèi)存資源。監(jiān)測引擎由一個帶有計數(shù)器的分類器構(gòu)成。NPF中的一個過濾引擎對數(shù)據(jù)包進行分類,沒有被過濾掉的數(shù)據(jù)會進入計數(shù)器。計數(shù)器擁有一些變量,用于保存接收到的數(shù)據(jù)和過濾器接收的字節(jié)數(shù)。每當有新的數(shù)據(jù)包進入時,這些變量的值都會被更新。監(jiān)測引擎會定期將這些變量的值傳遞給用戶層應用程序,傳遞的時間可以由用戶自行配置。3轉(zhuǎn)儲到磁盤4數(shù)

8、據(jù)包發(fā)送NPF允許將一個原始數(shù)據(jù)包發(fā)送的網(wǎng)絡上。要實現(xiàn)此功能,需要用戶層的應用程序在NPF設備文件上執(zhí)行一個WriteFile()的系統(tǒng)調(diào)用。數(shù)據(jù)被發(fā)送到網(wǎng)絡上時并不會進行任何協(xié)議的封裝,因此應用程序必須親自為每個要發(fā)送的數(shù)據(jù)包填寫好包頭的數(shù)據(jù)。9.1.4 捕獲數(shù)據(jù)包的原理和步驟以太網(wǎng)(Ethernet)具有共享介質(zhì)的特征,信息是以明文的形式在網(wǎng)絡上傳輸?shù)?。當網(wǎng)絡適配器設置為監(jiān)聽模式(混雜模式,Promiscuous)時,由于采用以太網(wǎng)廣播信道爭用的方式,使得監(jiān)聽系統(tǒng)與正常通信的網(wǎng)絡能夠并聯(lián)連接,并可以捕獲任何一個在同一沖突域上傳輸?shù)臄?shù)據(jù)包。1網(wǎng)絡的工作模式(1)廣播模式(Broad Cast

9、 Model):MAC地址是0Xffffff的幀為廣播幀,工作在廣播模式的網(wǎng)卡接收廣播幀。(2)多播傳送(Multicast Model):多播傳送地址作為目標MAC地址的幀可以被組內(nèi)的其它主機同時接收,而組外主機卻接收不到。但是,如果將網(wǎng)卡設置為多播傳送模式,它可以接收所有的多播傳送幀,而不論它是不是組內(nèi)成員。(3)直接模式(Direct Model):工作在直接模式下的網(wǎng)卡只接收目標地址是自己MAC地址的幀。(4)混雜模式(Promiscuous Model):工作在混雜模式下的網(wǎng)卡接收所有流過網(wǎng)卡的幀,數(shù)據(jù)包捕獲程序就是在這種模式下運行的。網(wǎng)卡的缺省工作模式包含廣播模式和直接模式,即它只

10、接收廣播幀和發(fā)給自己的幀。如果采用混雜模式,一個站點的網(wǎng)卡將接受同一網(wǎng)絡內(nèi)所有站點所發(fā)送的數(shù)據(jù)包,這樣就可以達到對于網(wǎng)絡信息監(jiān)視捕獲的目的。2捕獲和過濾網(wǎng)絡數(shù)據(jù)包的步驟(1)打開網(wǎng)卡,并設為混雜模式(2)回調(diào)函數(shù)Network Tap在得到監(jiān)聽命令后,從網(wǎng)絡設備驅(qū)動程序處收集數(shù)據(jù)包,把監(jiān)聽到的數(shù)據(jù)包傳送給過濾程序。(3)當數(shù)據(jù)包過濾器監(jiān)聽到有數(shù)據(jù)包到達時,NDIS中間驅(qū)動程序首先調(diào)用分組驅(qū)動程序,該程序?qū)?shù)據(jù)傳遞給每一個參與進程的分組過濾程序。(4)然后由數(shù)據(jù)包過濾程序決定哪些數(shù)據(jù)包應該丟棄,哪些數(shù)據(jù)包應該接收,是否需要將接收到的數(shù)據(jù)拷貝到相應的應用程序。(5)通過分組過濾器后,將未過濾掉的數(shù)

11、據(jù)包提交給核心緩沖區(qū)。然后等待系統(tǒng)緩沖區(qū)滿后,再將數(shù)據(jù)包拷貝到用戶緩沖區(qū)。監(jiān)聽程序可以直接從用戶緩沖區(qū)中讀取捕獲的數(shù)據(jù)包。(6)關(guān)閉網(wǎng)卡。9.2 下載和安裝WinPcap開發(fā)包9.2.1 下載WinPcap9.2.2 安裝WinPcap9.2.3 源代碼的目錄結(jié)構(gòu)9.2.1 下載WinPcap/下載WinPcap的頁面下載WinPcap開發(fā)包單擊窗口左側(cè)欄目條中的“Development”超鏈接,打開下載開發(fā)資源頁面。單擊“Download WinPcap 4.1.1 Developers Pack”超鏈接,即可下載WinPcap 4.1.1的開發(fā)包,文件名為WpdPack_4_1_1.zip

12、。開發(fā)包中包含開發(fā)WinPcap應用程序時需要引用的頭文件(.h文件)和庫文件(.lib文件),它不需要安裝,只要將其解壓縮后即可使用。9.2.2 安裝WinPcap雙擊WinPcap_4_1_1.exe,打開WinPcap安裝向?qū)?。單擊“Next”按鈕,打開歡迎窗口。安裝WinPcap單擊“Next”按鈕,打開許可協(xié)議窗口。單擊“I Agree”按鈕,打開安裝選項對話框。如果在當前計算機上始終運行WinPcap應用程序,則選擇“Automatically the WinPcap driver at boot time”復選框。然后單擊“Install”按鈕,開始安裝WinPcap。 9.2.

13、3 源代碼的目錄結(jié)構(gòu)解壓縮WpdPack_4_1_1.zip,可以看到其中包含如下幾個子目錄:docs,保存詳細的用戶使用手冊。Examples-pcap,采用libpcap庫接口的示例程序。Examples-remote,采用wpcap庫接口的示例程序。Include,保存在WinPcap庫上開發(fā)所需的頭文件。Lib,保存在WinPcap庫上開發(fā)所需的庫文件。9.3 在Visual C+中使用WinPcap技術(shù)9.3.1 環(huán)境配置9.3.2 獲取與網(wǎng)絡適配器綁定的設備列表9.3.3 獲取網(wǎng)絡適配器的高級屬性信息9.3.4 打開網(wǎng)絡適配器并實現(xiàn)抓包功能9.3.5 不使用事件處理器進行抓包9.3

14、.6 過濾數(shù)據(jù)包9.3.7 分析數(shù)據(jù)包9.3.1 環(huán)境配置在開發(fā)WinPcap應用程序之前,首先應該準備好開發(fā)環(huán)境。參照9.2小節(jié)中介紹的方法下載并安裝WinPcap,解壓縮WinPcap開發(fā)包。建議將WpdPack_4_1_1.zip中包含的Include和Lib兩個目錄復制到應用程序的解決方案目錄下。創(chuàng)建一個MFC應用程序項目,打開項目屬性對話框,在左側(cè)的項目列表中選擇“配置屬性”/“C/C+”/“常規(guī)”,在右側(cè)的“附加包含目錄”欄中輸入“.Include”(這里假定將WpdPack_4_1_1.zip中包含的Include目錄復制到解決方案目錄下,即項目目錄的上級目錄。這樣做的好處是可以

15、讓多個項目共享頭文件)。設置項目的附加包含目錄設置項目的附加庫目錄然后在項目屬性對話框左側(cè)的項目列表中選擇“配置屬性”/“鏈接器”/“常規(guī)”,在右側(cè)的“附加庫目錄”欄中輸入“.Lib”(這里假定將WpdPack_4_1_1.zip中包含的Lib目錄復制到解決方案目錄下,即項目目錄的上級目錄。這樣做的好處是可以讓多個項目共享庫文件).設置項目中引用的庫文件再選擇“配置屬性”/“鏈接器”/“輸入”,在右側(cè)的“附加庫目錄”欄中輸入“Packet.lib wpcap.lib ws2_32.lib”,通常在WinPcap應用程序中會引用這3個庫文件。9.3.2 獲取與網(wǎng)絡適配器綁定的設備列表1pcap_

16、findalldevs_ex()函數(shù)2pcap_rmtauth結(jié)構(gòu)體3pcap_if_t結(jié)構(gòu)體4pcap_freealldevs()函數(shù)5示例程序1pcap_findalldevs_ex()函數(shù)在WinPcap中,可以調(diào)用pcap_findalldevs_ex()函數(shù)來獲取與網(wǎng)絡適配器綁定的設備列表,函數(shù)原型如下:int pcap_findalldevs_ex(char* source, struct pcap_rmtauth* auth, pcap_if_t* alldevsp, char* errbuf);參數(shù)說明如下:source,指定源的位置。pcap_findalldevs_ex()

17、函數(shù)會在指定的源上尋找網(wǎng)絡適配器。源可以是本地計算機、遠程計算機或pcap文件。如果源是本地計算機,則該參數(shù)使用“rpcap:/”;如果源是遠程計算機,則該參數(shù)使用被指定為“rpcap:/host:port”的格式;如果源是pcap文件,則該參數(shù)可以被指定為“file:/c:/myfolder/”的格式。auth,指向pcap_rmtauth結(jié)構(gòu)體的指針,其中保存到遠程主機的RPCAP連接所需要的認證信息。alldevsp,指向pcap_if_t結(jié)構(gòu)體的指針。在調(diào)用函數(shù)時,函數(shù)將為其分配內(nèi)存空間;當函數(shù)返回時,該指針指向獲取到的網(wǎng)絡設備鏈表中的第1個元素。errbuf,指向一個用戶分配的緩沖區(qū)

18、,其大小為PCAP_ERRBUF_SIZE,該緩沖區(qū)中包含調(diào)用函數(shù)時可能產(chǎn)生的錯誤信息。返回值如果函數(shù)執(zhí)行成功,則返回0;否則返回-1。函數(shù)調(diào)用出現(xiàn)錯誤時,可以從errbuf緩沖區(qū)中獲取到錯誤的具體情況。錯誤的原因可以是以下幾種情況:在本地或遠程主機上沒有安裝libpcap或WinPcap。用戶沒有足夠的權(quán)限獲取網(wǎng)絡設備列表。出現(xiàn)網(wǎng)絡問題。RPCAP版本協(xié)商失敗。其他問題,比如沒有足夠的內(nèi)存等。2pcap_rmtauth結(jié)構(gòu)體pcap_rmtauth結(jié)構(gòu)體用于保存遠程主機上的用戶認證信息,定義代碼如下:struct pcap_rmtauth int type; char *username;

19、char *password;結(jié)構(gòu)體中包含的字段說明如下:type,身份認證的類型。username,遠程主機上用戶認證時使用的用戶名。password,遠程主機上用戶認證時使用的密碼。3pcap_if_t結(jié)構(gòu)體pcap_if_t結(jié)構(gòu)體用于保存獲取到的網(wǎng)絡設備信息,它等同于pcap_if結(jié)構(gòu)體。typedef struct pcap_if pcap_if_t; pcap_if結(jié)構(gòu)體的定義代碼如下:struct pcap_if struct pcap_if *next; char *name; char *description; struct pcap_addr *addresses; u_i

20、nt flags; ;結(jié)構(gòu)體pcap_if中包含的字段next,如果不為NULL,則指向鏈表中的下一個元素;否則當前元素為鏈表中的最后一個元素。name,網(wǎng)絡設備的名稱。description,網(wǎng)絡設備的描述信息。addresses,接口上定義的地址列表中的第1個元素。flags,PCAP_IF_接口標識。目前該標識只可能是PCAP_IF_LOOPBACK,這會設置該接口為回環(huán)接口。4pcap_freealldevs()函數(shù)pcap_freealldevs()函數(shù)用于釋放獲取到的網(wǎng)絡設備鏈表,函數(shù)原型如下:pcap_freealldevs(pcap_if_t* alldevsp);參數(shù)alld

21、evsp表示要釋放的結(jié)構(gòu)列表。5示例程序【例9.1】通過一個Win32控制臺應用程序演示獲取與網(wǎng)絡適配器綁定的設備列表信息。項目名稱為FindAllDevs,首先參照9.3.1小節(jié)配置項目屬性。下面介紹程序中的代碼。程序中使用的包含文件如下:#include stdafx.h#include pcap.h#include remote-ext.h WinPcap應用程序中通常都要包含pcap.h,而pcap_findalldevs_ex()函數(shù)的原型在remote-ext.h中聲明。主函數(shù)_tmain()int _tmain(int argc, _TCHAR* argv) pcap_if_t

22、*alldevs; pcap_if_t *d; int i=0; char errbufPCAP_ERRBUF_SIZE; /* 獲取本地機器設備列表*/ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs_ex: %sn, errbuf); exit(1); 主函數(shù)_tmain() /* 打印列表*/ for(d= alldevs; d != NULL; d= d-n

23、ext) printf(n%d. %sn, +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (No description available)n); if (i = 0) printf(nNo interfaces found! Make sure WinPcap is installed.n); return 1; /* 不再需要設備列表了,釋放它*/ pcap_freealldevs(alldevs);system(pause);return 0;程序的運行結(jié)果9.3.3 獲取網(wǎng)絡適配

24、器的高級屬性信息【例9.2】通過一個Win32控制臺應用程序演示獲取與網(wǎng)絡適配器綁定的設備列表上的高級屬性信息。1包含文件2iptos()函數(shù)3ip6tos()函數(shù)4ifprint()函數(shù)5主函數(shù)1包含文件#include stdafx.h#include pcap.h#include remote-ext.hWinPcap應用程序中通常都要包含pcap.h,而pcap_findalldevs_ex()函數(shù)的原型在remote-ext.h中聲明。2iptos()函數(shù)#define IPTOSBUFFERS12char *iptos(u_long in)static char outputIPT

25、OSBUFFERS3*4+3+1;static short which;u_char *p;p = (u_char *)∈which = (which + 1 = IPTOSBUFFERS ? 0 : which + 1);sprintf(outputwhich, %d.%d.%d.%d, p0, p1, p2, p3);return outputwhich;3ip6tos()函數(shù)char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)socklen_t sockaddrlen;#ifdef WIN32sock

26、addrlen = sizeof(struct sockaddr_in6);#elsesockaddrlen = sizeof(struct sockaddr_storage);#endifif(getnameinfo(sockaddr, sockaddrlen, address, addrlen, NULL, 0, NI_NUMERICHOST) != 0) address = NULL;return address;4ifprint()函數(shù)ifprint()函數(shù)用于打印指定的網(wǎng)絡接口,代碼如下:void ifprint(pcap_if_t *d) pcap_addr_t *a; char

27、ip6str128; / 打印名稱 printf(%sn,d-name); / 打印描述信息 if (d-description) printf(tDescription: %sn,d-description); / 打印環(huán)回信息 printf(tLoopback: %sn,(d-flags & PCAP_IF_LOOPBACK)?yes:no); / 打印地址信息4ifprint()函數(shù) / 分配內(nèi)存空間 pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(sizeof (MIB_IPADDRTABLE); / 第次調(diào)用GetIpAddrTable()函數(shù),獲

28、取數(shù)據(jù)的大小到dwSize if (pIPAddrTable) if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) = ERROR_INSUFFICIENT_BUFFER) FREE(pIPAddrTable); pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(dwSize); if (pIPAddrTable = NULL) printf(GetIpAddrTable()函數(shù)內(nèi)存分配失敗n); exit(1); 4ifprint()函數(shù) for(a=d-addresses;a;a=a-next) printf(tAdd

29、ress Family: #%dn,a-addr-sa_family); switch(a-addr-sa_family) case AF_INET: printf(tAddress Family Name: AF_INETn); if (a-addr) printf(tAddress: %sn,iptos(struct sockaddr_in *)a-addr)-sin_addr.s_addr); if (a-netmask) printf(tNetmask: %sn,iptos(struct sockaddr_in *)a-netmask)-sin_addr.s_addr); if (a-

30、broadaddr) printf(tBroadcast Address: %sn,iptos(struct sockaddr_in *)a-broadaddr)-sin_addr.s_addr); if (a-dstaddr) printf(tDestination Address: %sn,iptos(struct sockaddr_in *)a-dstaddr)-sin_addr.s_addr); break; case AF_INET6:/ IPv6 printf(tAddress Family Name: AF_INET6n);#ifndef _MINGW32_ /* Cygnus

31、doesnt have IPv6 */ if (a-addr) printf(tAddress: %sn, ip6tos(a-addr, ip6str, sizeof(ip6str);#endif break; default: printf(tAddress Family Name: Unknownn); break; printf(n);5主函數(shù) int _tmain(int argc, _TCHAR* argv)pcap_if_t *alldevs;/ 獲取的所有網(wǎng)絡設備鏈表pcap_if_t *d;/ 指向一個網(wǎng)絡設備char errbufPCAP_ERRBUF_SIZE+1;/ 錯誤

32、緩沖區(qū)/ 獲取網(wǎng)絡設備列表if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1)fprintf(stderr,Error in pcap_findalldevs: %sn, errbuf);exit(1);/ 打印每個網(wǎng)絡設備的信息for(d=alldevs;d;d=d-next)ifprint(d);/ 釋放網(wǎng)絡設備鏈表pcap_freealldevs(alldevs);system(pause);return 0;程序的運行結(jié)果9.3.4 打開網(wǎng)絡適配器并實現(xiàn)抓包功能1pcap_open()函數(shù)2pc

33、ap_loop()函數(shù)3示例程序1pcap_open()函數(shù)在WinPcap中,可以調(diào)用pcap_open()函數(shù)打開與網(wǎng)絡適配器綁定的設備,用于捕獲和發(fā)送數(shù)據(jù),函數(shù)原型如下:pcap_t* pcap_open(const char* source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth* auth, char* errbuf);參數(shù)說明source,指定要打開的源設備名稱。調(diào)用pcap_findalldevs_ex()函數(shù)返回的適配器可以直接使用pcap_open()函數(shù)打開。snaplen,指定必須保留的

34、數(shù)據(jù)包長度。對于過濾器收到的每個數(shù)據(jù)包,只有前面的snaplen個字節(jié)會被存儲到緩沖區(qū)中,并且被傳送到用戶應用程序。例如,snaplen等于100,則每個包中只有前面100個字節(jié)會被存儲。這樣可以減少應用程序間復制數(shù)據(jù)的量,從而提高捕獲數(shù)據(jù)的效率。flags,保存幾個捕獲數(shù)據(jù)包所需要的標識。可以使用該參數(shù)來指示網(wǎng)絡適配器是否被設置成混雜模式。一般情況下,適配器只接收發(fā)給自己的數(shù)據(jù)包,而其他主機之間通信的數(shù)據(jù)包將會被丟棄。如果設置為混雜模式,則WinPcap會捕獲所有的數(shù)據(jù)包。read_timeout,讀取超時時間,單位為毫秒。在捕獲一個數(shù)據(jù)包后,讀操作并不必立即返回,而是等待一段時間以允許捕獲

35、更多的數(shù)據(jù)包。如果平臺不支持讀取操作,則忽略該參數(shù)的值。auth,指向一個pcap_rmtauth結(jié)構(gòu)體的指針,保存遠程計算機上用戶所需的認證信息。如果不是遠程捕獲,則該參數(shù)被設置為NULL。errbuf,指向一個用戶分配的緩沖區(qū),其大小為PCAP_ERRBUF_SIZE,該緩沖區(qū)中包含錯誤信息。2pcap_loop()函數(shù)pcap_loop()函數(shù)用于采集一組數(shù)據(jù)包,函數(shù)原型如下:int pcap_loop(pcap_t* p, int cnt, pcap_handler callback, u_char* user;參數(shù)說明如下:pcap_t,指定一個打開的WinPcap會話,并在該會話中

36、采集數(shù)據(jù)包。cnt,要采集的數(shù)據(jù)包數(shù)量。callback,采集數(shù)據(jù)包后調(diào)用的處理函數(shù)。user,傳遞給回調(diào)函數(shù)callback的參數(shù)。如果成功采集到cnt個數(shù)據(jù)包,則函數(shù)返回0;如果出現(xiàn)錯誤,則返回-1;如果用戶在未處理任何數(shù)據(jù)包之前調(diào)用pcap_breakloop()函數(shù),則pcap_loop()函數(shù)被終止,并返回-2。回調(diào)函數(shù)callback的原型void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);參數(shù)說明如下:param,在pcap_loop()函數(shù)中指定

37、的參數(shù)user。header,指向pcap_pkthdr結(jié)構(gòu)體的指針,表示接收到的數(shù)據(jù)包頭。pkt_data,接收到的數(shù)據(jù)包內(nèi)容。結(jié)構(gòu)體pcap_pkthdr的定義代碼如下:struct pcap_pkthdr struct timeval ts;/* 收到數(shù)據(jù)包的時間戳 */bpf_u_int32 caplen;/* 實際捕獲的數(shù)據(jù)包長度 */bpf_u_int32 len;/* 發(fā)送端發(fā)出的數(shù)據(jù)包長度 */;3示例程序【例9.3】通過一個Win32控制臺應用程序演示打開網(wǎng)絡適配器并通過事件處理器來捕獲數(shù)據(jù)包的方法。程序的運行過程如下:調(diào)用pcap_findalldevs_ex()函數(shù)獲取并

38、打印本機的網(wǎng)絡設備列表。要求用戶選擇用于捕獲數(shù)據(jù)包的網(wǎng)絡設備。使用for語句跳轉(zhuǎn)到選中的網(wǎng)絡設備,以便在后面的程序中打開該設備,并在該設備上捕獲數(shù)據(jù)。調(diào)用pcap_open()函數(shù)打開選擇的網(wǎng)絡設備。調(diào)用pcap_freealldevs()釋放網(wǎng)絡設備列表。調(diào)用pcap_loop()函數(shù)開始捕獲數(shù)據(jù)。當數(shù)據(jù)包到達時,WinPcap會自動調(diào)用回調(diào)packet_handler()對數(shù)據(jù)包進行處理。程序的運行結(jié)果9.3.5 不使用事件處理器進行抓包調(diào)用pcap_next_ex()函數(shù)可以直接獲得一個數(shù)據(jù)包,函數(shù)原型如下:int pcap_next_ex(pcap_t *p, struct pcap_

39、pkthdr* pkt_header, const u_char* pkt_data);參數(shù)說明如下:p,指定一個打開的WinPcap會話,并在該會話中采集數(shù)據(jù)包。調(diào)用pcap_open()函數(shù)打開與網(wǎng)絡適配器綁定的設備,可以返回WinPcap會話句柄pcap_t。pkt_header,指向pcap_pkthdr結(jié)構(gòu)體的指針,表示接收到的數(shù)據(jù)包頭。pkt_data,接收到的數(shù)據(jù)包內(nèi)容。如果成功讀取數(shù)據(jù)包,則函數(shù)返回1;如果在pcap_open_live()函數(shù)中設置的超時時間已過,則返回0;如果發(fā)生錯誤,則返回-1;如果從離線捕獲的數(shù)據(jù)中讀取時到達緩沖區(qū)的結(jié)尾,則返回-2?!纠?.4】程序的運

40、行過程如下:調(diào)用pcap_findalldevs_ex()函數(shù)獲取并打印本機的網(wǎng)絡設備列表。要求用戶選擇用于捕獲數(shù)據(jù)包的網(wǎng)絡設備。使用for語句跳轉(zhuǎn)到選中的網(wǎng)絡設備,以便在后面的程序中打開該設備,并在該設備上捕獲數(shù)據(jù)。調(diào)用pcap_open()函數(shù)打開選擇的網(wǎng)絡設備。調(diào)用pcap_freealldevs()釋放網(wǎng)絡設備列表。調(diào)用pcap_next_ex ()函數(shù)開始捕獲數(shù)據(jù),并打印收到數(shù)據(jù)包的時間和數(shù)據(jù)包的長度。程序的運行結(jié)果9.3.6 過濾數(shù)據(jù)包1pcap_compile()函數(shù)2pcap_setfilter()函數(shù)1pcap_compile()函數(shù)pcap_compile()函數(shù)將一個高層

41、的布爾過濾表達式編譯成一個能夠被過濾引擎所解釋的低層字節(jié)碼,函數(shù)原型如下:int pcap_compile(pcap_t*p, struct bpf_program* fp, char*str, intoptimize, bpf_u_int32netmask);參數(shù)說明p,指定一個打開的WinPcap會話,并在該會話中采集數(shù)據(jù)包。調(diào)用pcap_open()函數(shù)打開與網(wǎng)絡適配器綁定的設備,可以返回WinPcap會話句柄pcap_t。fp,指向bpf_program結(jié)構(gòu)體的指針,在調(diào)用pcap_compile()函數(shù)時被賦值,可以為pcap_setfilter()傳遞過濾信息。str,指定要保留的

42、數(shù)據(jù)包協(xié)議的字符串,例如,設置該參數(shù)為ip and tcp表示保留IP數(shù)據(jù)包和TCP數(shù)據(jù)包。optimize,用于控制結(jié)果代碼的優(yōu)化。netmask,指定本地網(wǎng)絡的子網(wǎng)掩碼。如果發(fā)生錯誤,則返回-1;否則返回0。2pcap_setfilter()函數(shù)pcap_setfilter()函數(shù)將一個過濾器與內(nèi)核捕獲會話向關(guān)聯(lián)。當pcap_setfilter()被調(diào)用時,這個過濾器將被應用到來自網(wǎng)絡的所有數(shù)據(jù)包,并且所有符合要求的數(shù)據(jù)包(即那些經(jīng)過過濾器以后,布爾表達式為真的包)將會立即復制給應用程序。函數(shù)原型如下:int pcap_setfilter(pcap_t *p, struct bpf_program *fp)參數(shù)說明如下:p,指定一個打開的WinPcap會話,并在該會話中采集數(shù)據(jù)包。調(diào)用pcap_open()函數(shù)打開與網(wǎng)絡適配器綁定的設備,可以返回WinPcap會話句柄pcap_t。fp,指向bpf_program結(jié)構(gòu)體的指針,通常取自pcap_compile()函數(shù)調(diào)用,可以為pcap_setfilter()傳遞過濾信息。如果發(fā)生

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論