WEB开发网
开发学院操作系统windows 2008 深度剖析WinPcap之(七)——获得与释放网络适配器设... 阅读

深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(1)

 2009-09-11 00:00:00 来源:WEB开发网   
核心提示: 首先, pcap_findalldevs_ex函数和其他libpcap函数一样,深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(1)(6),有一个 errbuf 参数,一旦发生错误,"getifaddrs()",等)找到的设备,这个参数将会被libpcap写入

首先, 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平台下的网络适配器的名称读起来相当容易,可见,解释性的描述是很有帮助的。

1.3    wpcap.dll中相应函数接口的实现

1.3.1        pcap_findalldevs函数

wpcap\libpcap\fad-win32.c(219): 218-327

参数alldevsp返回所找到的适配器列表,参数errbuf返回错误信息。

 
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
    pcap_if_t *devlist = NULL;
    int ret = 0;
    const char *desc;
    char *AdaptersName;
    ULONG NameLength;
    char *name;
// PacketGetAdapterNames 是packet.dll中提供的函数,获取一个可用网络适配器的列表与它们的描述
//NameLength返回存储适配器列表所需的字节数
    if (!PacketGetAdapterNames(NULL, &NameLength))
{
        //获取字节数失败,处理错误,程序退出

    }
 
    if (NameLength > 0)
        AdaptersName = (char*) malloc(NameLength);//分配存储适配器列表所需内存
    else
    {
        *alldevsp = NULL;
        return 0;
    }
    if (AdaptersName == NULL)
    {
        snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
        return (-1);
    }         
 
    if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {//获取可用网络适配器列表
        snprintf(errbuf, PCAP_ERRBUF_SIZE,
            "PacketGetAdapterNames: %s",
            pcap_win32strerror());
        free(AdaptersName);
        return (-1);
    }
  
    /* "PacketGetAdapterNames()"返回一个以空字符结尾的ASCII字符串,该字符串存储接口名列表,以一个空字符结尾,其后为一个以空字符结尾的ASCII字符串,该字符串存储接口描述列表,以一个空字符结尾。   这意味着在第一个列表的末尾有两个ASCII空字符。*/
 
     /*查找第一个列表的末尾,那是第二个列表的开始*/
    desc = &AdaptersName[0];
    while (*desc != '\0' || *(desc + 1) != '\0') //查找第一个两个紧连着的空字符(‘\0\0’)
        desc++;
  
    /* 找到了 - "desc"指向接口名列表末尾的两个空字符的第一个。因此描述列表的第一个字节在后面两个字节的位置。*/
    desc += 2;
  
    /*循环遍历第一个列表中的所有元素*/
    name = &AdaptersName[0];
    while (*name != '\0') {
        /*为每个接口在devlist链表中添加一个节点*/
        if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) {
            /*操作失败*/
            ret = -1;
            break;
        }
        name += strlen(name) + 1;
        desc += strlen(desc) + 1;
    }
 
 
    if (ret != -1) {
        /*至此,没有任何错误,做任何特定平台的操作添加设备*/
 
/* pcap_platform_finddevs是 pcap_findalldevs()的内部接口
pcap_platform_finddevs()是一个依赖平台的例程,添加没有被“标准”机制"(SIOCGIFCONF,"getifaddrs()",等)找到的设备。
    */
        if (pcap_platform_finddevs(&devlist, errbuf) < 0)
            ret = -1;
    }
  
    if (ret == -1) {
//发生错误,释放所构建的列表devlist   
        if (devlist != NULL) {
            pcap_freealldevs(devlist);
            devlist = NULL;
        }
    }
  
    *alldevsp = devlist; //返回最终的适配器列表
    free(AdaptersName);  //释放存储适配器列表所的内存
    return (ret);
}

上一页  1 2 3 4 5 6 7 8  下一页

Tags:深度 剖析 WinPcap

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接