WinPcap编程入门(1)——获取本地适配器信息

本文转载自:http://www.cnblogs.com/blacksword/  

    第一次听说Winpcap是在做计算机网络实验的时候,那时候要用Ethereal捕获数据包来做分析,而Ethereal需要用到Winpcap包,那时候对Winpcap的概念很粗浅,认为它就是用来捕获数据包的。现在由于项目的原因要用到Winpcap编程,简单来说就是调用Winpcap里面的库函数来捕获网络封包之类的操作。因为没有相关的书籍讲解Winpcap编程,所以就直接参考的Winpcap技术文档,官网上有下载,有英文版的也有中文版的,中文版的是支持到4.01版本。我下载的Winpcap库是4.1.2的,但是由于看到有中文版的就省点事直接看中文版的了,当然同时也会参照英文版的文档,可能有些翻译并不是那么地到位。技术文档里面有Winpcap教程,它从最简单的部分(获得设备列表)到最复杂的部分(控制发送队列并收集和统计网络信息)来展示如何使用Winpcap进行程序开发。由于我是初学者,所以就一步一步、按部就班地按照这个教程来学习。

    第一个实例程序是一个获取设备列表的小程序(所有的示例程序都是用C语言来编写的),下面是源代码(我是在Windows下开发,使用的codeblocks IDE,相对于源码有一些修改)

<span style="font-family:KaiTi_GB2312;font-size:18px;">#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;
}</span>

    细心的读者可以发现,多了一条宏定义语句"#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结构的链表。函数的完整声明如下所示:

<span style="font-family:KaiTi_GB2312;font-size:18px;">int pcap_findalldevs_ex  ( char *  source,  
  struct pcap_rmtauth *  auth,  
  pcap_if_t **  alldevs,  
  char *  errbuf   
 ) </span>

    第一个参数是一个字符指针,保存的是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协议所定义的格式,这里就不深究了。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值