WinPcap-中文技術(shù)文檔_第1頁
WinPcap-中文技術(shù)文檔_第2頁
WinPcap-中文技術(shù)文檔_第3頁
WinPcap-中文技術(shù)文檔_第4頁
WinPcap-中文技術(shù)文檔_第5頁
已閱讀5頁,還剩195頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

WinPcap中文技術(shù)文檔4.0.1作者:TheWinPcapTeam作者主頁:模塊WinPcap用戶指南定義輸出函數(shù)過濾串表達(dá)式的語法使用WinPcap編程WinPcap教程:循序漸進(jìn)教您使用WinPcap獲取設(shè)備列表獲取已安裝設(shè)備的高級信息打開適配器并捕獲數(shù)據(jù)包不用回調(diào)方法捕獲數(shù)據(jù)包過濾數(shù)據(jù)包分析數(shù)據(jù)包處理脫機(jī)堆文件發(fā)送數(shù)據(jù)包收集并統(tǒng)計(jì)網(wǎng)絡(luò)流量WinPcap核心資料NPF驅(qū)動(dòng)核心指南NPF結(jié)構(gòu)與定義NPF函數(shù)Packet.dll--數(shù)據(jù)包驅(qū)動(dòng)API如何編譯WinPcap遠(yuǎn)程捕獲輸出結(jié)構(gòu)與定義外部函數(shù).對于提供遠(yuǎn)程捕獲的函數(shù)引用,請參閱WinPcap輸出函數(shù)章節(jié)的"Windows-specificExtensions".核心數(shù)據(jù)結(jié)構(gòu)與定義介紹本手冊提供了WinPcap編程接口的描述及其源代碼。它與詳盡的WinPcap核心資料一起,為編程人員提供了詳細(xì)的函數(shù)與結(jié)構(gòu)的描述,同時(shí)也提供了若干教程和程序范例。

您可以點(diǎn)擊頁面頂部的導(dǎo)航鏈接,或者使用頁面左邊的樹形控件,來跳轉(zhuǎn)到您感興趣的內(nèi)容。本文檔使用theDoxygendocumentationsystem創(chuàng)建,您可以登錄閱覽相關(guān)內(nèi)容。什么是WinPcapWinPcap是一個(gè)基于Win32平臺(tái)的,用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包并進(jìn)行分析的開源庫.大多數(shù)網(wǎng)絡(luò)應(yīng)用程序通過被廣泛使用的操作系統(tǒng)元件來訪問網(wǎng)絡(luò),比如sockets。

這是一種簡單的實(shí)現(xiàn)方式,因?yàn)椴僮飨到y(tǒng)已經(jīng)妥善處理了底層具體實(shí)現(xiàn)細(xì)節(jié)(比如協(xié)議處理,封裝數(shù)據(jù)包等等),并且提供了一個(gè)與讀寫文件類似的,令人熟悉的接口。然而,有些時(shí)候,這種“簡單的方式”并不能滿足任務(wù)的需求,因?yàn)橛行?yīng)用程序需要直接訪問網(wǎng)絡(luò)中的數(shù)據(jù)包。也就是說,那些應(yīng)用程序需要訪問原始數(shù)據(jù)包,即沒有被操作系統(tǒng)利用網(wǎng)絡(luò)協(xié)議處理過的數(shù)據(jù)包。WinPcap產(chǎn)生的目的,就是為Win32應(yīng)用程序提供這種訪問方式;WinPcap提供了以下功能捕獲原始數(shù)據(jù)包,無論它是發(fā)往某臺(tái)機(jī)器的,還是在其他設(shè)備(共享媒介)上進(jìn)行交換的在數(shù)據(jù)包發(fā)送給某應(yīng)用程序前,根據(jù)用戶指定的規(guī)則過濾數(shù)據(jù)包將原始數(shù)據(jù)包通過網(wǎng)絡(luò)發(fā)送出去收集并統(tǒng)計(jì)網(wǎng)絡(luò)流量信息以上這些功能需要借助安裝在Win32內(nèi)核中的網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序才能實(shí)現(xiàn),再加上幾個(gè)動(dòng)態(tài)鏈接庫DLL。所有這些功能都能通過一個(gè)強(qiáng)大的編程接口來表現(xiàn)出來,易于開發(fā),并能在不同的操作系統(tǒng)上使用。這本手冊的主要目標(biāo)是在一些程序范例的幫助下,敘述這些編程接口的使用。

如果您現(xiàn)在就想開始摸索這些功能,您可以直接進(jìn)入WinPcap用戶手冊.哪些程序在使用WinPcapWinPcap可以被用來制作許多類型的網(wǎng)絡(luò)工具,比如具有分析,解決紛爭,安全和監(jiān)視功能的工具。特別地,一些基于WinPcap的典型應(yīng)用有:網(wǎng)絡(luò)與協(xié)議分析器(networkandprotocolanalyzers)網(wǎng)絡(luò)監(jiān)視器(networkmonitors)網(wǎng)絡(luò)流量記錄器(trafficloggers)網(wǎng)絡(luò)流量發(fā)生器(trafficgenerators)用戶級網(wǎng)橋及路由(user-levelbridgesandrouters)網(wǎng)絡(luò)入侵檢測系統(tǒng)(networkintrusiondetectionsystems(NIDS))網(wǎng)絡(luò)掃描器(networkscanners)安全工具(securitytools)什么是WinPcap做不到的WinPcap能獨(dú)立地通過主機(jī)協(xié)議發(fā)送和接受數(shù)據(jù),如同TCP-IP。這就意味著WinPcap不能阻止、過濾或操縱同一機(jī)器上的其他應(yīng)用程序的通訊:它僅僅能簡單地"監(jiān)視"在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)包。所以,它不能提供類似網(wǎng)絡(luò)流量控制、服務(wù)質(zhì)量調(diào)度和個(gè)人防火墻之類的支持。本手冊的目標(biāo)本手冊的目的是提供一個(gè)全面而簡單的方法來讓您瀏覽WinPcap的設(shè)計(jì)文檔。你會(huì)找到兩個(gè)主要部分:WinPcap用戶指南和WinPcap核心資料.第一部分內(nèi)容主要適合那些需要利用WinPcap開發(fā)應(yīng)用程序的編程人員:它包含了WinPcapAPI的所有函數(shù)和數(shù)據(jù)結(jié)構(gòu)的信息,說明部分解釋了如何編寫一個(gè)數(shù)據(jù)包過濾器,而另一個(gè)頁面則解釋了如何將它包含到應(yīng)用程序中。一個(gè)教程也提供了若干個(gè)程序范例,您可以使用它來循序漸進(jìn)地學(xué)習(xí)WinPcapAPI的基本使用方法,不過有時(shí)候,它也會(huì)提供一些高級應(yīng)用的代碼片斷。第二部分內(nèi)容主要為WinPcap的開發(fā)、維護(hù)人員,以及那些希望了解系統(tǒng)工作原理的人士而準(zhǔn)備。它描述了WinPcap的主要設(shè)計(jì)方法,并解釋了它是如何工作的。另外,它闡述了完整的設(shè)備驅(qū)動(dòng)的數(shù)據(jù)結(jié)構(gòu)及源代碼,packet.dll的接口以及底層的WinPcap的API。如果您想了解WinPcap內(nèi)部發(fā)生了什么,或者您想去擴(kuò)展它,那么請您閱讀此部分內(nèi)容。附加文檔最新最及時(shí)的文檔,請?jiān)L問

/docs/特別地,如果您對WinPcap的系統(tǒng)結(jié)構(gòu)和核心內(nèi)容感興趣,我們建議您閱讀下列內(nèi)容FulvioRisso,LorisDegioanni,AnArchitectureforHighPerformanceNetworkAnalysis,Proceedingsofthe6thIEEESymposiumonComputersandCommunications(ISCC2001),Hammamet,Tunisia,July2001LorisDegioanni,MarioBaldi,FulvioRissoandGianlucaVarenni,ProfilingandOptimizationofSoftware-BasedNetwork-AnalysisApplications,Proceedingsofthe15thIEEESymposiumonComputerArchitectureandHighPerformanceComputing(SBAC-PAD2003),SaoPaulo,Brasil,November2003LorisDegioanni,DevelopmentofanArchitectureforPacketCaptureandNetworkTrafficAnalysis,GraduationThesis,PolitecnicoDiTorino(Turin,Italy,Mar.2000)術(shù)語為了文獻(xiàn)的一致性,我們會(huì)使用術(shù)語數(shù)據(jù)包(packet),盡管用術(shù)語幀(frame)會(huì)更加準(zhǔn)確,因?yàn)椴东@過程是在數(shù)據(jù)鏈路層完成的,并且數(shù)據(jù)鏈路首部也包含在被捕獲的數(shù)據(jù)中。本文檔中使用的術(shù)語Win9x表示與Windows95同一體系的微軟操作系統(tǒng),如Windows98和WindowsME。術(shù)語WinNTx表示基于NT內(nèi)核的操作系統(tǒng),從WindowsNT4開始,包含了Windows2000,WindowsXP,WindowsServer2003等附注我們主要會(huì)致力于開發(fā)基于WindowsNT/2000/XP/2003版本的WinPcap及其相關(guān)文檔。這一選擇是基于這樣一個(gè)事實(shí),大多數(shù)WinPcap用戶都工作在NTx系統(tǒng)上,而且9x技術(shù)已經(jīng)被微軟放棄。此外,我們假定,使用PC機(jī)來完成類似網(wǎng)絡(luò)分析這樣高級任務(wù)的用戶,都會(huì)安裝高級的操作系統(tǒng)。鑒于這個(gè)原因,本文檔將參考WinNTx的驅(qū)動(dòng)和API。Win9x版本在概念上很類似,不過有時(shí)在執(zhí)行上有些不同。在有些場合,Win9x版本的API缺少一些高級功能。這本手冊會(huì)給出一個(gè)完整的API描述,并會(huì)指出那些只有WinNTx才得到支持的函數(shù)。

LastModified:Sunday,July23,2007

WinPcap教程:循序漸進(jìn)教您使用WinPcap本節(jié)將向您展示如何使用WinPcapAPI的一些特性。這部分教程細(xì)化成若干節(jié)課,以循序漸進(jìn)的方式介紹給讀者,讓讀者從最基本的部分(獲得設(shè)備列表)到最復(fù)雜的部分(控制發(fā)送隊(duì)列并收集和統(tǒng)計(jì)網(wǎng)絡(luò)流量)來了解如何使用WinPcap進(jìn)行程序開發(fā)。有時(shí),我們會(huì)給出一些簡單使用的代碼片斷,但同時(shí),我們提供完整程序的鏈接:所有的源代碼包含一些指向手冊其他地方的鏈接,這可以讓您很方便地通過點(diǎn)擊鼠標(biāo)來跳轉(zhuǎn)到您想查看的函數(shù)和數(shù)據(jù)結(jié)構(gòu)的內(nèi)容中去。范例程序都是用純C語言編寫,所以,掌握基本的C語言編程知識(shí)是必須的,而且,這是一部關(guān)于處理原始網(wǎng)絡(luò)數(shù)據(jù)包的教程,因?yàn)?,我們希望讀者擁有良好的網(wǎng)絡(luò)及網(wǎng)絡(luò)協(xié)議的知識(shí)。獲取設(shè)備列表通常,編寫基于WinPcap應(yīng)用程序的第一件事情,就是獲得已連接的網(wǎng)絡(luò)適配器列表。libpcap和WinPcap都提供了pcap_findalldevs_ex()函數(shù)來實(shí)現(xiàn)這個(gè)功能:這個(gè)函數(shù)返回一個(gè)pcap_if結(jié)構(gòu)的鏈表,每個(gè)這樣的結(jié)構(gòu)都包含了一個(gè)適配器的詳細(xì)信息。值得注意的是,數(shù)據(jù)域name和description表示一個(gè)適配器名稱和一個(gè)可以讓人們理解的描述。下列代碼能獲取適配器列表,并在屏幕上顯示出來,如果沒有找到適配器,將打印錯(cuò)誤信息。#include"pcap.h"main(){pcap_if_t*alldevs;pcap_if_t*d;inti=0;charerrbuf[PCAP_ERRBUF_SIZE];/*獲取本地機(jī)器設(shè)備列表*/if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL/*authisnotneeded*/,&alldevs,errbuf)==-1){fprintf(stderr,"Errorinpcap_findalldevs_ex:%s\n",errbuf);exit(1);}/*打印列表*/for(d=alldevs;d!=NULL;d=d->next){printf("%d.%s",++i,d->name);if(d->description)printf("(%s)\n",d->description);elseprintf("(Nodescriptionavailable)\n");}if(i==0){printf("\nNointerfacesfound!MakesureWinPcapisinstalled.\n");return;}/*不再需要設(shè)備列表了,釋放它*/pcap_freealldevs(alldevs);}有關(guān)這段代碼的一些說明首先,pcap_findalldevs_ex(),和其他libpcap函數(shù)一樣,有一個(gè)errbuf參數(shù)。一旦發(fā)生錯(cuò)誤,這個(gè)參數(shù)將會(huì)被libpcap寫入字符串類型的錯(cuò)誤信息。第二要記住,不是所有的操作系統(tǒng)都支持libpcap提供的網(wǎng)絡(luò)程序接口,因此,如果我們想編寫一個(gè)可移植的應(yīng)用程序,我們就必須考慮在什么情況下,description是null。本程序中,我們遇到這種情況時(shí),會(huì)打印提示語句"Nodescriptionavailable"。最后要記住,當(dāng)我們完成了設(shè)備列表的使用,我們要調(diào)用pcap_freealldevs()函數(shù)將其占用的內(nèi)存資源釋放。讓我們編譯并運(yùn)行我們的第一個(gè)示例程序吧!為了能在Unix或Cygwin平臺(tái)上編譯這段程序,需要簡單輸入:gcc-otestprogtestprog.c-lpcap在Windows平臺(tái)上,您需要?jiǎng)?chuàng)建一個(gè)工程,并按照使用WinPcap編程里的步驟做。然而,我們建議您使用WinPcapdeveloper'spack(詳情請?jiān)L問WinPcap網(wǎng)站,),因?yàn)樗峁┝撕芏嘁呀?jīng)配置好的范例,包括本教程中的所有示例代碼,以及在編譯運(yùn)行時(shí)需要的包含文件(include)和庫(libraries)jiash假設(shè)我們已經(jīng)完成了對程序的編譯,那讓我們來運(yùn)行它吧。在某臺(tái)WinXP的電腦上,我們得到的結(jié)果是:1.\Device\NPF_{4E273621-5161-46C8-895A-48D0E52A0B83}(RealtekRTL8029(AS)EthernetAdapter)2.\Device\NPF_{5D24AE04-C486-4A96-83FB-8B5EC6C7F430}(3ComEtherLinkPCI)正如您看到的,Windows平臺(tái)下的網(wǎng)絡(luò)適配器的名字讀起來相當(dāng)容易,可見,解釋性的描述是多么有幫助阿!獲取已安裝設(shè)備的高級信息在第1講中,(獲取設(shè)備列表)我們展示了如何獲取適配器的基本信息(如設(shè)備的名稱和描述)。事實(shí)上,WinPcap提供了其他更高級的信息。特別需要指出的是,由pcap_findalldevs_ex()返回的每一個(gè)pcap_if結(jié)構(gòu)體,都包含一個(gè)pcap_addr結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體由如下元素組成:一個(gè)地址列表一個(gè)掩碼列表(eachofwhichcorrespondstoanentryintheaddresseslist).一個(gè)廣播地址列表(eachofwhichcorrespondstoanentryintheaddresseslist).一個(gè)目的地址列表(eachofwhichcorrespondstoanentryintheaddresseslist).另外,函數(shù)pcap_findalldevs_ex()還能返回遠(yuǎn)程適配器信息和一個(gè)位于所給的本地文件夾的pcap文件列表。下面的范例使用了ifprint()函數(shù)來打印出pcap_if結(jié)構(gòu)體中所有的內(nèi)容。程序?qū)γ恳粋€(gè)由pcap_findalldevs_ex()函數(shù)返回的pcap_if,都調(diào)用ifprint()函數(shù)來實(shí)現(xiàn)打印。/**Copyright(c)1999-2005NetGroup,PolitecnicodiTorino(Italy)*Copyright(c)2005-2006CACETechnologies,Davis(California)*Allrightsreserved.**Redistributionanduseinsourceandbinaryforms,withorwithout*modification,arepermittedprovidedthatthefollowingconditions*aremet:**1.Redistributionsofsourcecodemustretaintheabovecopyright*notice,thislistofconditionsandthefollowingdisclaimer.*2.Redistributionsinbinaryformmustreproducetheabovecopyright*notice,thislistofconditionsandthefollowingdisclaimerinthe*documentationand/orothermaterialsprovidedwiththedistribution.*3.NeitherthenameofthePolitecnicodiTorino,CACETechnologies*northenamesofitscontributorsmaybeusedtoendorseorpromote*productsderivedfromthissoftwarewithoutspecificpriorwritten*permission.**THISSOFTWAREISPROVIDEDBYTHECOPYRIGHTHOLDERSANDCONTRIBUTORS*"ASIS"ANDANYEXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOT*LIMITEDTO,THEIMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFOR*APARTICULARPURPOSEAREDISCLAIMED.INNOEVENTSHALLTHECOPYRIGHT*OWNERORCONTRIBUTORSBELIABLEFORANYDIRECT,INDIRECT,INCIDENTAL,*SPECIAL,EXEMPLARY,ORCONSEQUENTIALDAMAGES(INCLUDING,BUTNOT*LIMITEDTO,PROCUREMENTOFSUBSTITUTEGOODSORSERVICES;LOSSOFUSE,*DATA,ORPROFITS;ORBUSINESSINTERRUPTION)HOWEVERCAUSEDANDONANY*THEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,ORTORT*(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUTOFTHEUSE*OFTHISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGE.**/#include"pcap.h"#ifndefWIN32#include<sys/socket.h>#include<netinet/in.h>#else#include<winsock.h>#endif//函數(shù)原型voidifprint(pcap_if_t*d);char*iptos(u_longin);char*ip6tos(structsockaddr*sockaddr,char*address,intaddrlen);intmain(){pcap_if_t*alldevs;pcap_if_t*d;charerrbuf[PCAP_ERRBUF_SIZE+1];charsource[PCAP_ERRBUF_SIZE+1];printf("Enterthedeviceyouwanttolist:\n""rpcap://==>listsinterfacesinthelocalmachine\n""rpcap://hostname:port==>listsinterfacesinaremotemachine\n""(rpcapddaemonmustbeupandrunning\n""anditmustaccept'null'authentication)\n""file://foldername==>listsallpcapfilesinthegivefolder\n\n""Enteryourchoice:");fgets(source,PCAP_ERRBUF_SIZE,stdin);source[PCAP_ERRBUF_SIZE]='\0';/*獲得接口列表*/if(pcap_findalldevs_ex(source,NULL,&alldevs,errbuf)==-1){fprintf(stderr,"Errorinpcap_findalldevs:%s\n",errbuf);exit(1);}/*掃描列表并打印每一項(xiàng)*/for(d=alldevs;d;d=d->next){ifprint(d);}pcap_freealldevs(alldevs);return1;}/*打印所有可用信息*/voidifprint(pcap_if_t*d){pcap_addr_t*a;charip6str[128];/*設(shè)備名(Name)*/printf("%s\n",d->name);/*設(shè)備描述(Description)*/if(d->description)printf("\tDescription:%s\n",d->description);/*LoopbackAddress*/printf("\tLoopback:%s\n",(d->flags&PCAP_IF_LOOPBACK)?"yes":"no");/*IPaddresses*/for(a=d->addresses;a;a=a->next){printf("\tAddressFamily:#%d\n",a->addr->sa_family);switch(a->addr->sa_family){caseAF_INET:printf("\tAddressFamilyName:AF_INET\n");if(a->addr)printf("\tAddress:%s\n",iptos(((structsockaddr_in*)a->addr)->sin_addr.s_addr));if(a->netmask)printf("\tNetmask:%s\n",iptos(((structsockaddr_in*)a->netmask)->sin_addr.s_addr));if(a->broadaddr)printf("\tBroadcastAddress:%s\n",iptos(((structsockaddr_in*)a->broadaddr)->sin_addr.s_addr));if(a->dstaddr)printf("\tDestinationAddress:%s\n",iptos(((structsockaddr_in*)a->dstaddr)->sin_addr.s_addr));break;caseAF_INET6:printf("\tAddressFamilyName:AF_INET6\n");if(a->addr)printf("\tAddress:%s\n",ip6tos(a->addr,ip6str,sizeof(ip6str)));break;default:printf("\tAddressFamilyName:Unknown\n");break;}}printf("\n");}/*將數(shù)字類型的IP地址轉(zhuǎn)換成字符串類型的*/#defineIPTOSBUFFERS12char*iptos(u_longin){staticcharoutput[IPTOSBUFFERS][3*4+3+1];staticshortwhich;u_char*p;p=(u_char*)∈which=(which+1==IPTOSBUFFERS?0:which+1);sprintf(output[which],"%d.%d.%d.%d",p[0],p[1],p[2],p[3]);returnoutput[which];}char*ip6tos(structsockaddr*sockaddr,char*address,intaddrlen){socklen_tsockaddrlen;#ifdefWIN32sockaddrlen=sizeof(structsockaddr_in6);#elsesockaddrlen=sizeof(structsockaddr_storage);#endifif(getnameinfo(sockaddr,sockaddrlen,address,addrlen,NULL,0,NI_NUMERICHOST)!=0)address=NULL;returnaddress;}打開適配器并捕獲數(shù)據(jù)包現(xiàn)在,我們已經(jīng)知道如何獲取適配器的信息了,那我們就開始一項(xiàng)更具意義的工作,打開適配器并捕獲數(shù)據(jù)包。在這講中,我們會(huì)編寫一個(gè)程序,將每一個(gè)通過適配器的數(shù)據(jù)包打印出來。打開設(shè)備的函數(shù)是pcap_open()。下面是參數(shù)snaplen,flags和to_ms的解釋說明snaplen制定要捕獲數(shù)據(jù)包中的哪些部分。在一些操作系統(tǒng)中(比如xBSD和Win32),驅(qū)動(dòng)可以被配置成只捕獲數(shù)據(jù)包的初始化部分:這樣可以減少應(yīng)用程序間復(fù)制數(shù)據(jù)的量,從而提高捕獲效率。本例中,我們將值定為65535,它比我們能遇到的最大的MTU還要大。因此,我們確信我們總能收到完整的數(shù)據(jù)包。flags:最最重要的flag是用來指示適配器是否要被設(shè)置成混雜模式。一般情況下,適配器只接收發(fā)給它自己的數(shù)據(jù)包,而那些在其他機(jī)器之間通訊的數(shù)據(jù)包,將會(huì)被丟棄。相反,如果適配器是混雜模式,那么不管這個(gè)數(shù)據(jù)包是不是發(fā)給我的,我都會(huì)去捕獲。也就是說,我會(huì)去捕獲所有的數(shù)據(jù)包。這意味著在一個(gè)共享媒介(比如總線型以太網(wǎng)),WinPcap能捕獲其他主機(jī)的所有的數(shù)據(jù)包。大多數(shù)用于數(shù)據(jù)捕獲的應(yīng)用程序都會(huì)將適配器設(shè)置成混雜模式,所以,我們也會(huì)在下面的范例中,使用混雜模式。to_ms指定讀取數(shù)據(jù)的超時(shí)時(shí)間,以毫秒計(jì)(1s=1000ms)。在適配器上進(jìn)行讀取操作(比如用pcap_dispatch()或pcap_next_ex())都會(huì)在to_ms毫秒時(shí)間內(nèi)響應(yīng),即使在網(wǎng)絡(luò)上沒有可用的數(shù)據(jù)包。在統(tǒng)計(jì)模式下,to_ms還可以用來定義統(tǒng)計(jì)的時(shí)間間隔。將to_ms設(shè)置為0意味著沒有超時(shí),那么如果沒有數(shù)據(jù)包到達(dá)的話,讀操作將永遠(yuǎn)不會(huì)返回。如果設(shè)置成-1,則情況恰好相反,無論有沒有數(shù)據(jù)包到達(dá),讀操作都會(huì)立即返回。#include"pcap.h"/*packethandler函數(shù)原型*/voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data);main(){pcap_if_t*alldevs;pcap_if_t*d;intinum;inti=0;pcap_t*adhandle;charerrbuf[PCAP_ERRBUF_SIZE];/*獲取本機(jī)設(shè)備列表*/if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1){fprintf(stderr,"Errorinpcap_findalldevs:%s\n",errbuf);exit(1);}/*打印列表*/for(d=alldevs;d;d=d->next){printf("%d.%s",++i,d->name);if(d->description)printf("(%s)\n",d->description);elseprintf("(Nodescriptionavailable)\n");}if(i==0){printf("\nNointerfacesfound!MakesureWinPcapisinstalled.\n");return-1;}printf("Entertheinterfacenumber(1-%d):",i);scanf("%d",&inum);if(inum<1||inum>i){printf("\nInterfacenumberoutofrange.\n");/*釋放設(shè)備列表*/pcap_freealldevs(alldevs);return-1;}/*跳轉(zhuǎn)到選中的適配器*/for(d=alldevs,i=0;i<inum-1;d=d->next,i++);/*打開設(shè)備*/if((adhandle=pcap_open( d->name,//設(shè)備名65536,//65535保證能//捕獲到不同數(shù)據(jù)鏈路層上的 //每個(gè)數(shù)據(jù)包的全部內(nèi)容 PCAP_OPENFLAG_PROMISCUOUS,//混雜模式1000,//讀取超時(shí)時(shí)間NULL,//遠(yuǎn)程機(jī)器驗(yàn)證errbuf//錯(cuò)誤緩沖池))==NULL){fprintf(stderr,"\nUnabletoopentheadapter.%sisnotsupportedbyWinPcap\n",d->name);/*釋放設(shè)備列表*/pcap_freealldevs(alldevs);return-1;}printf("\nlisteningon%s...\n",d->description);/*釋放設(shè)備列表*/pcap_freealldevs(alldevs);/*開始捕獲*/pcap_loop(adhandle,0,packet_handler,NULL);return0;}/*每次捕獲到數(shù)據(jù)包時(shí),libpcap都會(huì)自動(dòng)調(diào)用這個(gè)回調(diào)函數(shù)*/voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data){structtm*ltime;chartimestr[16];time_tlocal_tv_sec;/*將時(shí)間戳轉(zhuǎn)換成可識(shí)別的格式*/local_tv_sec=header->ts.tv_sec;ltime=localtime(&local_tv_sec);strftime(timestr,sizeoftimestr,"%H:%M:%S",ltime);printf("%s,%.6dlen:%d\n",timestr,header->ts.tv_usec,header->len);}當(dāng)適配器被打開,捕獲工作就可以用pcap_dispatch()或pcap_loop()進(jìn)行。這兩個(gè)函數(shù)非常的相似,區(qū)別就是pcap_dispatch()當(dāng)超時(shí)時(shí)間到了(timeoutexpires)就返回(盡管不能保證),而pcap_loop()不會(huì)因此而返回,只有當(dāng)cnt數(shù)據(jù)包被捕獲,所以,pcap_loop()會(huì)在一小段時(shí)間內(nèi),阻塞網(wǎng)絡(luò)的利用。pcap_loop()對于我們這個(gè)簡單的范例來說,可以滿足需求,不過,pcap_dispatch()函數(shù)一般用于比較復(fù)雜的程序中。這兩個(gè)函數(shù)都有一個(gè)回調(diào)參數(shù),packet_handler指向一個(gè)可以接收數(shù)據(jù)包的函數(shù)。這個(gè)函數(shù)會(huì)在收到每個(gè)新的數(shù)據(jù)包并收到一個(gè)通用狀態(tài)時(shí)被libpcap所調(diào)用(與函數(shù)pcap_loop()和pcap_dispatch()中的user參數(shù)相似),數(shù)據(jù)包的首部一般有一些諸如時(shí)間戳,數(shù)據(jù)包長度的信息,還有包含了協(xié)議首部的實(shí)際數(shù)據(jù)。注意:冗余校驗(yàn)碼CRC不再支持,因?yàn)閹竭_(dá)適配器,并經(jīng)過校驗(yàn)確認(rèn)以后,適配器就會(huì)將CRC刪除,與此同時(shí),大部分適配器會(huì)直接丟棄CRC錯(cuò)誤的數(shù)據(jù)包,所以,WinPcap沒法捕獲到它們。上面的程序?qū)⒚恳粋€(gè)數(shù)據(jù)包的時(shí)間戳和長度從pcap_pkthdr的首部解析出來,并打印在屏幕上。請注意,使用pcap_loop()函數(shù)可能會(huì)遇到障礙,主要因?yàn)樗苯佑蓴?shù)據(jù)包捕獲驅(qū)動(dòng)所調(diào)用。因此,用戶程序是不能直接控制它的。另一個(gè)實(shí)現(xiàn)方法(也是提高可讀性的方法),是使用pcap_next_ex()函數(shù)。有關(guān)這個(gè)函數(shù)的使用,我們將在下一講為您展示。(不用回調(diào)方法捕獲數(shù)據(jù)包).不用回調(diào)方法捕獲數(shù)據(jù)包本講的范例程序所實(shí)現(xiàn)的功能和效果和上一講的非常相似(打開適配器并捕獲數(shù)據(jù)包),但本講將用pcap_next_ex()函數(shù)代替上一講的pcap_loop()函數(shù)。pcap_loop()函數(shù)是基于回調(diào)的原理來進(jìn)行數(shù)據(jù)捕獲,這是一種精妙的方法,并且在某些場合中,它是一種很好的選擇。然而,處理回調(diào)有時(shí)候并不實(shí)用--它會(huì)增加程序的復(fù)雜度,特別是在擁有多線程的C++程序中??梢酝ㄟ^直接調(diào)用pcap_next_ex()函數(shù)來獲得一個(gè)數(shù)據(jù)包--只有當(dāng)編程人員使用了pcap_next_ex()函數(shù)才能收到數(shù)據(jù)包。這個(gè)函數(shù)的參數(shù)和捕獲回調(diào)函數(shù)的參數(shù)是一樣的--它包含一個(gè)網(wǎng)絡(luò)適配器的描述符和兩個(gè)可以初始化和返回給用戶的指針(一個(gè)指向pcap_pkthdr結(jié)構(gòu)體,另一個(gè)指向數(shù)據(jù)報(bào)數(shù)據(jù)的緩沖)。在下面的程序中,我們會(huì)再次用到上一講中的有關(guān)回調(diào)方面的代碼,只是我們將它放入了main()函數(shù),之后調(diào)用pcap_next_ex()函數(shù)。#include"pcap.h"main(){pcap_if_t*alldevs;pcap_if_t*d;intinum;inti=0;pcap_t*adhandle;intres;charerrbuf[PCAP_ERRBUF_SIZE];structtm*ltime;chartimestr[16];structpcap_pkthdr*header;constu_char*pkt_data;time_tlocal_tv_sec;/*獲取本機(jī)設(shè)備列表*/if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1){fprintf(stderr,"Errorinpcap_findalldevs:%s\n",errbuf);exit(1);}/*打印列表*/for(d=alldevs;d;d=d->next){printf("%d.%s",++i,d->name);if(d->description)printf("(%s)\n",d->description);elseprintf("(Nodescriptionavailable)\n");}if(i==0){printf("\nNointerfacesfound!MakesureWinPcapisinstalled.\n");return-1;}printf("Entertheinterfacenumber(1-%d):",i);scanf("%d",&inum);if(inum<1||inum>i){printf("\nInterfacenumberoutofrange.\n");/*釋放設(shè)備列表*/pcap_freealldevs(alldevs);return-1;}/*跳轉(zhuǎn)到已選中的適配器*/for(d=alldevs,i=0;i<inum-1;d=d->next,i++);/*打開設(shè)備*/if((adhandle=\l"g2b64c7b6490090d1d3

溫馨提示

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

最新文檔

評論

0/150

提交評論