win1

通常,編寫基於WinPcap應用程序的第一件事情,就是獲得已連接的網絡適配器設備列表。同時在程序結束時確保釋放獲取的設備列表。 圖6-1函數調用關係圖 1.1 wpcap.dll導出的相應函數接口 wpcap.dll爲了獲得與釋放已連接的網絡適配器設備列表,提供了下列函數:文件/wpcap/libpcap/pcap/pcap.h中 struct pcap_if; struct pcap_addr; int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf);void pcap_freealldevs(pcap_if_t *alldevsp ) ; 文件wpcap/libpcap/remote-ext.h中int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); 1.1.1 pcap_if結構體函數pcap_findalldevs_ex或pcap_findalldevs分別返回一個 pcap_if_t類型的鏈表alldevs或alldevsp。每個pcap_if_t結構體都包含一個適配器的詳細信息。其中成員 name 和 description 分別表示一個適配器的名稱和一個更容易讓人理解的描述。該結構體的定義如下:typedef struct pcap_if pcap_if_t; struct pcap_if {/*如果不爲NULL,則指向鏈表的下一個元素。如果爲NULL,則爲鏈表的尾部*/struct pcap_if *next; /*給pcap_open_live函數傳遞的一個描述設備名稱的字符串指針*/char *name; /*如果不爲NULL,則指向描述設備的一個可讀字符串*/char *description; /*一個指向接口地址鏈表的第一個元素的指針*/struct pcap_addr *addresses; /**PCAP_IF_接口標誌。當前僅有的可能標誌爲PCAP_IF_LOOPBACK,*如果接口是迴環的則設置該標誌*/bpf_u_int32 flags; };其中結構體pcap_addr的定義在下面描述。結構體pcap_addr表示接口地址的信息,定義如下:typedef struct pcap_addr pcap_addr_t; struct pcap_addr { struct pcap_addr *next; /*指向下一個元素的指針*/ struct sockaddr *addr; /* IP地址 */ struct sockaddr *netmask; /* 網絡掩碼 */ struct sockaddr *broadaddr; /* 廣播地址 */ struct sockaddr *dstaddr; /* P2P目的地址*/};1.1.2 pcap_findalldevs_ex函數 通常,編寫基於WinPcap應用程序的第一件事情,就是獲得已連接的網絡適配器設備列表。WinPcap提供了pcap_findalldevs_ex函數來實現這個功能,該函數的的原型如下:int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);該函數創建一個能用pcap_open函數打開的網絡適配器設備列表。該函數是老函數pcap_findalldevs的一個擴展,pcap_findalldevs()是一個過時的函數,其只允許列出在本機上的網絡設備。反之pcap_findalldevs_ex也允許列出一個遠程機器上的網絡設備,此外還能列出一個給定文件夾中可用的pcap文件。因爲pcap_findalldevs_ex()依賴於標準的pcap_findalldevs()來獲得本地機器的地址,所以它是平臺無關的。萬一該函數必須列出遠程機器上的設備,它對那臺機器打開一個新的控制連接,重新獲得那個網絡接口並終止連接。然而,如果函數檢測到遠程計算機正處在“激活模式”下,連接不會終止並使用已存在的套結字。“source”是一個告訴函數在哪兒查找設備的參數,並且它使用與pcap_open函數同樣的語法。與pcap_findalldevs函數不同,該設備的名稱 (由alldevs->name 指定,其它的存在已連接的鏈表中)已經被考慮用在pcap_open函數中。相反,pcap_findalldevs函數的輸出必須採用pcap_createsrcstr()格式處理後,才能把源參數傳遞給pcap_open函數使用。參數source是一個字符型的緩衝區,根據新的WinPcap語法保存着“源的位置”。檢查該源以尋找適配器(本機的或遠程的)(如源可以爲本機的適配器“rpcap://”或遠程的適配器“rpcap://host:port”)或pcap文件(如源可以爲“file://c:/myfolder/”)。該字符串應該預先仔細考慮,爲了闡明所需的源是否爲本地/遠程適配器或文件。這些源的含義都在新的語法規定(Source Specification Syntax )中定義。參數auth是一個指向pcap_rmtauth結構體的指針。該指針保持着認證RPCAP連接到遠程主機所需的信息。該參數對本地主機請求沒什麼意義,此時可以設爲NULL。參數alldevs是一個“pcap_if_t”結構體類型的指針,在該函數中被正確的分配。該函數成功返回時,該指針被設置爲指向網絡設備鏈表的第一個元素,該鏈表的每個元素都是“pcap_if_t”類型。參數errbuf是一個指向用戶分配的緩衝區(大小爲PCAP_ERRBUF_SIZE)的指針,如果函數操作出現錯誤,該緩衝區將存儲該錯誤信息。函數成功則返回0,如果有錯誤則返回-1。“alldevs”變量返回設備列表,當函數正確返回時,“alldevs”不能爲NULL。也就是說,當系統沒有任何接口時,該函數也返回-1。“errbuf”變量返回錯誤信息,一個錯誤可能由下列原因導致:Ø WinPcap沒有安裝在本地/遠程主機上Ø 用戶沒有足夠的權限來列出這些設備/文件Ø 一個網絡故障Ø RPCAP版本協商失敗(the RPCAP version negotiation failed)Ø 其它錯誤(如沒足夠的內存或其它的問題)值得注意的是,通過調用pcap_findalldevs函數可能存在網絡設備不能被pcap_open函數打開的現象。比如可能沒有足夠的權限來打開它們並進行捕獲,如果是這樣,這些設備將不出現在設備列表中。該函數所獲取的設備列表必須採用pcap_freealldevs函數手工進行釋放。1.1.3 pcap_findalldevs函數函數pcap_findalldevs是一個過時的函數,其只允許列出本機上出現的網絡設備。函數原型如下:int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf);函數獲得已連接並能打開的所有網絡設備列表,該列表能夠被pcap_open_live函數打開。參數alldevsp指向列表的第一個元素,列表的每個元素都爲pcap_if_t類型。如果沒有已連接並能打開的網絡設備,該鏈表可能爲NULL。函數失敗返回-1,errbuf存儲合適的錯誤信息;成功返回0。值得注意的是,通過調用pcap_findalldevs函數可能存在網絡設備不能被pcap_open_live函數打開的現象。比如可能沒有足夠的權限來打開它們並進行捕獲,如果是這樣,這些設備將不出現在設備列表中。1.1.4 pcap_freealldevs函數由函數pcap_findalldevs_ex或pcap_findalldevs函數返回的網絡適配器設備鏈表,必須調用pcap_freealldevs函數釋放。該函數的原型如下:void pcap_freealldevs(pcap_if_t *alldevsp ) st1/:*{behavior:url(#ieooui) } 1.2 獲得與釋放網絡適配器列表的實例 下列代碼能獲取適配器列表,並在屏幕上顯示出來,如果沒有找到適配器,將打印錯誤信息。並在程序結束時釋放設備列表。#include "remote-ext.h"#include "pcap.h" main(){ pcap_if_t *alldevs; pcap_if_t *d; int i=0; char errbuf[PCAP_ERRBUF_SIZE]; //獲取本地機器設備列表if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL , &alldevs, errbuf) == -1){ //獲取設備列表失敗,程序返回 fprintf(stderr,"Error in pcap_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); else printf(" (No description available)/n"); } if (i == 0){ //沒找到設備接口,確認WinPcap已安裝,程序退出 printf("/nNo interfaces found! Make sure WinPcap is installed./n"); return; } //不再需要設備列表了,釋放它pcap_freealldevs(alldevs);}首先, pcap_findalldevs_ex函數和其他libpcap函數一樣,有一個 errbuf 參數。一旦發生錯誤,這個參數將會被libpcap寫入字符串類型的錯誤信息。 第二要記住,不是所有的操作系統都支持libpcap提供的網絡程序接口,因此,如果想編寫一個可移植的應用程序,就必須考慮在什麼情況下, description 是 null。在本程序中遇到這種情況時,會打印提示語句"No description available"。 最後要記住,當完成了設備列表的使用,要調用 pcap_freealldevs() 函數將其佔用的內存資源釋放。 在某臺WinXP的電腦上,運行該程序得到的結果是: 1. /Device/NPF_{4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter) 2. /Device/NPF_{5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI) 正如所看見的,Windows平臺下網絡適配器的名稱相當不易讀,可見,解釋性的描述是很有幫助的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章