获取本地适配器信息

      第一次听说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协议所定义的格式,这里就不深究了。

获取本地适配器信息

你可能感兴趣的:(适配器)