WinPcap教程(2):获取设备高级信息

WinPcap教程(1):获取网卡列表演示了如何获得网卡的基本信息(如设备名称和描述信息)。实际上,WinPcap还可以提供更多其他高级信息。特别地,pcap_findalldevs_ex()返回的pcap_if结构包含了一个pcap_addr结构列表,包括:

-          网卡的地址列表

-          网络掩码列表(其中每项和地址列表中的一项对应)

-          广播地址列表(其中每项和地址列表中的一项对应)

-          目的地地址列表(其中每项和地址列表中的一项对应)

 

更进一步,pcap_findalldevs_ex()也可以返回远程网卡相关信息以及指定的本地目录中的pcap文件列表。

 

下面的示例代码提供了一个打印pcap_if结构完整内容的函数ifprint()。它被pcap_findalldevs_ex()所返回的每一项(译注:即pcap_if结构)调用。

/*

 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)

 * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)

 * All rights reserved.

 *

 * Redistribution and use in source and binary forms, with or without

 * modification, are permitted provided that the following conditions

 * are met:

 *

 * 1. Redistributions of source code must retain the above copyright

 * notice, this list of conditions and the following disclaimer.

 * 2. Redistributions in binary form must reproduce the above copyright

 * notice, this list of conditions and the following disclaimer in the

 * documentation and/or other materials provided with the distribution.

 * 3. Neither the name of the Politecnico di Torino, CACE Technologies

 * nor the names of its contributors may be used to endorse or promote

 * products derived from this software without specific prior written

 * permission.

 *

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT

 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 *

 */

 

#include <stdio.h>

 

#include "pcap.h"

 

#ifndef WIN32

    #include <sys/socket.h>

    #include <netinet/in.h>

#else

    #include <winsock.h>

#endif

 

 

// Function prototypes

void ifprint(pcap_if_t *d);

char *iptos(u_long in);

char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);

 

 

int main()

{

  pcap_if_t *alldevs;

  pcap_if_t *d;

  char errbuf[PCAP_ERRBUF_SIZE+1];

  char source[PCAP_ERRBUF_SIZE+1];

 

  printf("Enter the device you want to list:/n"

            "rpcap://              ==> lists interfaces in the local machine/n"

            "rpcap://hostname:port ==> lists interfaces in a remote machine/n"

            "                          (rpcapd daemon must be up and running/n"

            "                           and it must accept 'null' authentication)/n"

            "file://foldername     ==> lists all pcap files in the give folder/n/n"

            "Enter your choice: ");

 

  fgets(source, PCAP_ERRBUF_SIZE, stdin);

  source[PCAP_ERRBUF_SIZE] = '/0';

 

  /* Retrieve the interfaces list */

  if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)

  {

    fprintf(stderr,"Error in pcap_findalldevs: %s/n",errbuf);

    exit(1);

  }

 

  /* Scan the list printing every entry */

  for(d=alldevs;d;d=d->next)

  {

    ifprint(d);

  }

 

  pcap_freealldevs(alldevs);

 

  return 1;

}

 

 

 

/* Print all the available information on the given interface */

void ifprint(pcap_if_t *d)

{

  pcap_addr_t *a;

  char ip6str[128];

 

  /* Name */

  printf("%s/n",d->name);

 

  /* Description */

  if (d->description)

    printf("/tDescription: %s/n",d->description);

 

  /* Loopback Address*/

  printf("/tLoopback: %s/n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");

 

  /* IP addresses */

  for(a=d->addresses;a;a=a->next) {

    printf("/tAddress Family: #%d/n",a->addr->sa_family);

 

    switch(a->addr->sa_family)

    {

      case AF_INET:

        printf("/tAddress Family Name: AF_INET/n");

        if (a->addr)

          printf("/tAddress: %s/n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));

        if (a->netmask)

          printf("/tNetmask: %s/n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));

        if (a->broadaddr)

          printf("/tBroadcast Address: %s/n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));

        if (a->dstaddr)

          printf("/tDestination Address: %s/n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));

        break;

 

      case AF_INET6:

        printf("/tAddress Family Name: AF_INET6/n");

        if (a->addr)

          printf("/tAddress: %s/n", ip6tos(a->addr, ip6str, sizeof(ip6str)));

       break;

 

      default:

        printf("/tAddress Family Name: Unknown/n");

        break;

    }

  }

  printf("/n");

}

 

 

 

/* From tcptraceroute, convert a numeric IP address to a string */

#define IPTOSBUFFERS    12

char *iptos(u_long in)

{

    static char output[IPTOSBUFFERS][3*4+3+1];

    static short which;

    u_char *p;

 

    p = (u_char *)&in;

    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);

    _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]),"%d.%d.%d.%d", p[0], p[1], p[2], p[3]);

    return output[which];

}

 

char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)

{

    socklen_t sockaddrlen;

 

    #ifdef WIN32

    sockaddrlen = sizeof(struct sockaddr_in6);

    #else

    sockaddrlen = sizeof(struct sockaddr_storage);

    #endif

 

 

    if(getnameinfo(sockaddr,

        sockaddrlen,

        address,

        addrlen,

        NULL,

        0,

        NI_NUMERICHOST) != 0) address = NULL;

 

    return address;

}

 

此文章来自于【http://blog.csdn.net/pathuang68/article/details/4291667

你可能感兴趣的:(WinPcap教程(2):获取设备高级信息)