王晨俊美:WinPcap基础知识(第二课:获得已安装设备的高级信息)

来源:百度文库 编辑:中财网 时间:2024/04/29 01:50:06
第一课 (Obtaining the device list ) 展示了如何获得有用适配器的基本信息(如设备名称和描述)。事实上,WinPcap也提供另外的高级信息。特别的,每个pcap_findalldevs() 返回的 pcap_if 结构也包含了一个pcap_addr结构的列表: 该接口的地址列表a list of addresses for that interface.
网络掩码的列表a list of netmasks (each of which corresponds to an entry in the addresses list).
广播地址的列表a list of broadcast addresses (each of which corresponds to an entry in the addresses list).
目标地址的列表a list of destination addresses (each of which corresponds to an entry in the addresses list).
如下的例子提供一个ifpriont()函数,来打印pcap_if结构的完整内容。它被pcap_findalldevs()返回的每个条目调用。   
#include   
 
#ifndef WIN32  
    #include   
    #include   
#else  
    #include   
#endif  
 
#pragma comment(lib,"ws2_32.lib")  
 
 
// 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 *)∈  
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);  
    sprintf(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;  

/*
 * Copyright (c) 1999 - 2003
 * NetGroup, Politecnico di Torino (Italy)
 * 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 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 #ifndef WIN32
    #include
    #include
#else
    #include
#endif#pragma comment(lib,"ws2_32.lib")
// 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 *)∈
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
    sprintf(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;

 
 说明:该成员用到getnameinfo()和里面的NI_NUMERICHOST 宏,这些在"WS2tcpip.h" 头文件里面有定义,所以要包含这个头文件(官方网站上面下载的文档里面的pack里面是没有包含这个头文件的,那样编译会出错(vs6)。但是在vs7里面编译没有任何问题。估计是在其它文件里面已经把该头文件包含进去了。 此程序的缺点很明显:显示本机没有问题,但是显示远程主机就一般都不行,它要求双方都要装winpcap包并且对方在后台要运行rpcap,并且接收参数NULL授权参数。笔者试了一下,几乎不能获得远程主机的接口列表。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qsycn/archive/2009/08/18/4458008.aspx