獲取本地適配器信息


      第一次聽說Winpcap是在做計算機網絡實驗的時候,那時候要用Ethereal捕獲數據包來做分析,而Ethereal需要用到Winpcap包,那時候對Winpcap的概念很粗淺,認為它就是用來捕獲數據包的。現在由於項目的原因要用到Winpcap編程,簡單來說就是調用Winpcap里面的庫函數來捕獲網絡封包之類的操作。因為沒有相關的書籍講解Winpcap編程,所以就直接參考的Winpcap技術文檔,官網上有下載,有英文版的也有中文版的,中文版的是支持到4.01版本。我下載的Winpcap庫是4.1.2的,但是由於看到有中文版的就省點事直接看中文版的了,當然同時也會參照英文版的文檔,可能有些翻譯並不是那么地到位。技術文檔里面有Winpcap教程,它從最簡單的部分(獲得設備列表)到最復雜的部分(控制發送隊列並收集和統計網絡信息)來展示如何使用Winpcap進行程序開發。由於我是初學者,所以就一步一步、按部就班地按照這個教程來學習。

      第一個實例程序是一個獲取設備列表的小程序(所有的示例程序都是用C語言來編寫的),下面是源代碼(我是在Windows下開發,使用的codeblocks IDE,相對於源碼有一些修改)

#include <stdio.h>
#include <stdlib.h>

#define HAVE_REMOTE
#include <pcap.h>

int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i = 0;
char errbuf[PCAP_ERRBUF_SIZE];

/* get local devices */
if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
exit(1);
}

/* print devices list */
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)
{
printf("\nNo interfaces found! Make sure Winpcap is installed.\n");
return -1;
}

pcap_freealldevs(alldevs);

return 0;
}

      細心的讀者可以發現,多了一條宏定義語句"#define HAVE_REMOTE",這句話到底是做什么用的呢?仍然是參考技術文檔,有一章“使用Winpcap編程”,在講到創建一個使用wpcap.dll的應用程序的時候有這么一句話:

      如果你的程序使用了WinPcap的遠程捕獲功能,那么在預處理定義中加入HAVE_REMOTE不要直接把remote-ext.h直接加入到你的源文件中去。  

      就是說它的作用相當於是包含了remote-ext.h這個頭文件,至於為何不直接把這個頭文件包含起來,這就不是這一章需要設計的話題了。

      繼續查看源碼我們發現有兩個結構體指針pcap_if_t*的聲明,轉到pcap_if_t的聲明處我們看到在"pcap.h"中有一句

typedef struct pcap_if pcap_if_t;

      pcap_if這個結構體是用來做什么的呢?查看文檔我們不難發現,它包含了一個適配器的詳細信息,其中的數據域name和description表示一個適配器名稱和一個可以讓人們理解的描述。而之所以定義結構體指針,因為其實定義的是pcap_if結構的鏈表。鏈表我們是再熟悉不過了!接下去分析,PCAP_ERRBUF_SIZE是宏定義的,值為256。然后我們看到了pcap_findalldevs_ex這么一個函數,函數的功能就是返回一個pcap_if結構的鏈表。函數的完整聲明如下所示:

int pcap_findalldevs_ex  ( char *  source,  
struct pcap_rmtauth * auth,
pcap_if_t ** alldevs,
char * errbuf
)

      第一個參數是一個字符指針,保存的是source的地址,事實上它決定了source的類型(file, remote/local interface),而PCAP_SRC_IF_STRING表示用戶希望從一個網絡接口卡打開捕獲(open a capture from a network interface)。

      第二個參數是一個pcap_rmtauth的結構體指針,它保存了RPCAP連接遠程用戶的驗證信息,因為是要獲取本地的設備列表,這個參數就沒有意義,置為NULL。

      第三個參數剛才已經說了,這個函數的功能就是返回一個pcap_if結構的鏈表,給的是鏈表的地址,所以在源碼中看到寫的是“&alldevs”。

      第四個參數是錯誤信息緩沖,就是說如果這個函數調用出錯則把錯誤信息保存到這個buff里面。

      pcap_findalldevs_ex函數的返回值為0,說明everything is fine,返回-1則表示出錯。

      接下來的代碼就沒什么好說的了。但注意最后有一個pcap_freealldevs的函數,它的功能顯而易見,就是釋放鏈表的空間咯!

      最后看一下在本機運行后的結果。顯示的是本機連接的設備信息,當然我們看到設備的名稱都是以rpcap://打頭的,其實就是源碼中用到的PCAP_SRC_IF_STRING,這應該是RPCAP協議所定義的格式,這里就不深究了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM