码迷,mamicode.com
首页 > Windows程序 > 详细

WinPcap笔记2之获取已经安装设备的高级信息

时间:2017-04-05 09:44:19      阅读:313      评论:0      收藏:0      [点我收藏+]

标签:loopback   put   ace   win   语法   技术   端口   wan   new   

1 主要数据结构定义

  struct pcap_if//网络接口列表的一个节点 一个网络接口就是一个结点 方便链表
    {
        struct pcap_if *next;//网络接口节点
        char *name;//网络接口名字
        struct pcap_addr *address;//网络接口地址
        bpf_u_int32 flags;//标记
        char *description;//描述信息
    }

typedefstruct pcap_ifpcap_if_t

 typedef struct pcap_addr pcap_addrt//描述网络接口地址
  {
   struct pcap_addr *next;//下一个地址
   struct sockaddr *addr;//接口地址
   struct sockaddr *netmask;//子网掩码
   struct sockaddr *broadaddr;//广播地址
   struct sockaddr *dstaddr;//目标地址
  }

////错误放在errbuf中 查找可用的网络接口

 

int pcap_findalldevs_ex(char * source,  

 

struct pcap_rmtauth * auth,

 

pcap_if_t ** alldevs,

 

char * errbuf

 

)

 

    这个函数是’pcap_findalldevs()’的一个超集。’pcap_findalldevs()’比较老,他只允许列出本地机器上的设备。然而,’pcap_findalldevs_ex()’除了可以列出本地及其上的设备,还可以列出远程机器上的设备。此外,它还能列出所有可用的pcap文件到指定的文件夹。’pcap_findalldevs_ex()’是平台无关的,然而它以来于标准的’pcap_findalldevs()’来获得本地机器的地址。

几个非常重要的问题?这也是在运行编译测试和看代码中的疑问了?

1区别是远程还是本地是由pcap_findalldevs_ex()中的source决定的,sourse指定需要监控的网络适配器。他有特定的为语法

  (1)file://folder/[列出指定文件夹中的所有文件]

      (2)rpcap://[列出所有本地的适配器]

      (3)rpcap://host:port/[列出远程主机上的可用的设备]

    注意:port和host参数可以使数字形式也可以是字符形式

      host (字符):例如: host.foo.bar

  •   host (数字 IPv4): 例如: 10.11.12.13
  •   host (IPv6型的IPv4数字形式): 例如: [10.11.12.13]
  •   host (数字 IPv6): 例如: [1:2:3::4]
  •   port: 也可以是数字 (例如:‘80‘) 或字符 (例如: ‘http‘)

 

下面举一些实际例子:

 

  •  rpcap://host.foo.bar/devicename [全部都是字符形式的,没有端口号]
  •  rpcap://host.foo.bar:1234/devicename [全部都是字符形式的,有端口号]
  •  rpcap://10.11.12.13/devicename [IPv4 的数字形式,没有端口号]
  •  rpcap://10.11.12.13:1234/devicename [IPv4 的数字形式,有端口号]
  •  rpcap://[10.11.12.13]:1234/devicename [IPv6格式的IPv4数字形式 ,有端口号]
  •  rpcap://[1:2:3::4]/devicename [IPv6数字形式,没有端口号]
  •  rpcap://[1:2:3::4]:1234/devicename [IPv6数字形式,有端口号]
  •  rpcap://[1:2:3::4]:http/devicename [IPv6数字形式,端口号是字符形式]

 

另外,在Winpcap里,字符串"file://"和字符串"rpcap://"都被宏定义过:
  #define PCAP_SRC_FILE_STRING "file://"
  #define PCAP_SRC_IF_STRING "rpcap://"
所以也可以用宏名来代替它们。

pcap_addr_t *a;

iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));//这句话的相关由来就是下面三个结构体

 

typedef struct sockaddr_in {

 

#if(_WIN32_WINNT < 0x0600)
    short   sin_family;
#else //(_WIN32_WINNT < 0x0600)
    ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)

 

    USHORT sin_port;
    IN_ADDR sin_addr;
    CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;

 

struct pcap_addr {
 struct pcap_addr *next;
 struct sockaddr *addr;  /* address */
 struct sockaddr *netmask; /* netmask for that address */
 struct sockaddr *broadaddr; /* broadcast address for that address */
 struct sockaddr *dstaddr; /* P2P destination address for that address */
};

typedef struct in_addr {
        union {
                struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
                struct { USHORT s_w1,s_w2; } S_un_w;
                ULONG S_addr;
        } S_un;
#define s_addr  S_un.S_addr /* can be used for most tcp & ip code */
#define s_host  S_un.S_un_b.s_b2    // host on imp
#define s_net   S_un.S_un_b.s_b1    // network
#define s_imp   S_un.S_un_w.s_w2    // imp
#define s_impno S_un.S_un_b.s_b4    // imp #
#define s_lh    S_un.S_un_b.s_b3    // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;

#endif

  1 #include "pcap.h"
  2 
  3 #ifndef WIN32
  4 #include <sys/socket.h>
  5 #include <netinet/in.h>
  6 #else
  7 #include <winsock.h>
  8 #endif
  9 
 10 
 11 // 函数原型
 12 void ifprint(pcap_if_t *d);
 13 char *iptos(u_long in);
 14 char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);
 15 
 16 
 17 int main()
 18 {
 19     pcap_if_t *alldevs;
 20     pcap_if_t *d;
 21     char errbuf[PCAP_ERRBUF_SIZE + 1];
 22     char source[PCAP_ERRBUF_SIZE + 1];
 23 
 24     printf("Enter the device you want to list:\n"
 25         "rpcap://              ==> lists interfaces in the local machine\n"
 26         "rpcap://hostname:port ==> lists interfaces in a remote machine\n"
 27         "                          (rpcapd daemon must be up and running\n"
 28         "                           and it must accept ‘null‘ authentication)\n"
 29         "file://foldername     ==> lists all pcap files in the give folder\n\n"
 30         "Enter your choice: ");
 31 
 32     fgets(source, PCAP_ERRBUF_SIZE, stdin);//输入上面提示内容 需要的查看内容
 33     source[PCAP_ERRBUF_SIZE] = \0;
 34 
 35     /* 获得接口列表 */
 36     if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
 37     {
 38         fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
 39         exit(1);
 40     }
 41 
 42     /* 扫描列表并打印每一项 */
 43     for (d = alldevs; d; d = d->next)
 44     {
 45         ifprint(d);
 46     }
 47 
 48     pcap_freealldevs(alldevs);
 49 
 50     return 1;
 51 }
 52 
 53 
 54 
 55 /* 打印所有可用信息 */
 56 void ifprint(pcap_if_t *d)
 57 {
 58     pcap_addr_t *a;
 59     char ip6str[128];
 60 
 61     /* 设备名(Name) */
 62     printf("%s\n", d->name);
 63 
 64     /* 设备描述(Description) */
 65     if (d->description)
 66         printf("\tDescription: %s\n", d->description);
 67 
 68     /* Loopback Address*/
 69     printf("\tLoopback: %s\n", (d->flags & PCAP_IF_LOOPBACK) ? "yes" : "no");
 70 
 71     /* IP addresses */
 72     for (a = d->addresses; a; a = a->next) {
 73         printf("\tAddress Family: #%d\n", a->addr->sa_family);
 74 
 75         switch (a->addr->sa_family)
 76         {
 77         case AF_INET:
 78             printf("\tAddress Family Name: AF_INET\n");
 79             if (a->addr)
 80                 printf("\tAddress: %s\n", iptos(((struct sockaddr_in *)a->addr)->sin_addr.S_un.S_addr));
 81             if (a->netmask)
 82                 printf("\tNetmask: %s\n", iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
 83             if (a->broadaddr)
 84                 printf("\tBroadcast Address: %s\n", iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
 85             if (a->dstaddr)
 86                 printf("\tDestination Address: %s\n", iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
 87             break;
 88 
 89         case AF_INET6:
 90             printf("\tAddress Family Name: AF_INET6\n");
 91             if (a->addr)
 92                 printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
 93             break;
 94 
 95         default:
 96             printf("\tAddress Family Name: Unknown\n");
 97             break;
 98         }
 99     }
100     printf("\n");
101 
102     getchar();
103 }
104 
105 
106 
107 /* 将数字类型的IP地址转换成字符串类型的 */
108 #define IPTOSBUFFERS    12
109 char *iptos(u_long in)
110 {
111     static char output[IPTOSBUFFERS][3 * 4 + 3 + 1];//3*4个数组+3个点+一个空字符结束
112     static short which;
113     u_char *p;
114 
115     p = (u_char *)&in;
116     //如果转换IP的个数大于总Buffer数,就从0开始. 
117         which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
118     sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
119     return output[which];
120 }
121 
122 char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
123 {
124     socklen_t sockaddrlen;
125 
126 #ifdef WIN32
127     sockaddrlen = sizeof(struct sockaddr_in6);
128 #else
129     sockaddrlen = sizeof(struct sockaddr_storage);
130 #endif
131 
132 
133     if (getnameinfo(sockaddr,
134         sockaddrlen,
135         address,
136         addrlen,
137         NULL,
138         0,
139         NI_NUMERICHOST) != 0) address = NULL;
140 
141     return address;
142 }
View Code
  1 #include "pcap.h"
  2 
  3 #ifndef WIN32
  4 #include <sys/socket.h>
  5 #include <netinet/in.h>
  6 #else
  7 #include <winsock.h>
  8 #endif
  9 
 10 
 11 // 函数原型
 12 void ifprint(pcap_if_t *d);
 13 char *iptos(u_long in);
 14 char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);
 15 
 16 
 17 int main()
 18 {
 19     pcap_if_t *alldevs;
 20     pcap_if_t *d;
 21     char errbuf[PCAP_ERRBUF_SIZE + 1];
 22     char source[PCAP_ERRBUF_SIZE + 1];
 23 
 24     printf("Enter the device you want to list:\n"
 25         "rpcap://              ==> lists interfaces in the local machine\n"
 26         "rpcap://hostname:port ==> lists interfaces in a remote machine\n"
 27         "                          (rpcapd daemon must be up and running\n"
 28         "                           and it must accept ‘null‘ authentication)\n"
 29         "file://foldername     ==> lists all pcap files in the give folder\n\n"
 30         "Enter your choice: ");
 31 
 32     fgets(source, PCAP_ERRBUF_SIZE, stdin);
 33     source[PCAP_ERRBUF_SIZE] = \0;
 34 
 35     /* 获得接口列表 */
 36     if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
 37     {
 38         fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
 39         exit(1);
 40     }
 41 
 42     /* 扫描列表并打印每一项 */
 43     for (d = alldevs; d; d = d->next)
 44     {
 45         ifprint(d);
 46     }
 47 
 48     pcap_freealldevs(alldevs);
 49     getchar();
 50     return 1;
 51 }
 52 
 53 
 54 
 55 /* 打印所有可用信息 */
 56 void ifprint(pcap_if_t *d)
 57 {
 58     pcap_addr_t *a;
 59     char ip6str[128];
 60 
 61     /* 设备名(Name) */
 62     printf("%s\n", d->name);
 63 
 64     /* 设备描述(Description) */
 65     if (d->description)
 66         printf("\tDescription: %s\n", d->description);
 67 
 68     /* Loopback Address*/
 69     printf("\tLoopback: %s\n", (d->flags & PCAP_IF_LOOPBACK) ? "yes" : "no");
 70 
 71     /* IP addresses */
 72     for (a = d->addresses; a; a = a->next) {
 73         printf("\tAddress Family: #%d\n", a->addr->sa_family);
 74 
 75         switch (a->addr->sa_family)
 76         {
 77         case AF_INET:
 78             printf("\tAddress Family Name: AF_INET\n");
 79             if (a->addr)
 80                 printf("\tAddress: %s\n", iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
 81             if (a->netmask)
 82                 printf("\tNetmask: %s\n", iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
 83             if (a->broadaddr)
 84                 printf("\tBroadcast Address: %s\n", iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
 85             if (a->dstaddr)
 86                 printf("\tDestination Address: %s\n", iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
 87             break;
 88 
 89         case AF_INET6:
 90             printf("\tAddress Family Name: AF_INET6\n");
 91             if (a->addr)
 92                 printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
 93             break;
 94 
 95         default:
 96             printf("\tAddress Family Name: Unknown\n");
 97             break;
 98         }
 99     }
100     printf("\n");
101 }
102 
103 
104 
105 /* 将数字类型的IP地址转换成字符串类型的 */
106 #define IPTOSBUFFERS    12
107 char *iptos(u_long in)
108 {
109     static char output[IPTOSBUFFERS][3 * 4 + 3 + 1];//3*4个数组+3个点+一个空字符结束
110     static short which;
111     u_char *p;
112 
113     p = (u_char *)&in;
114     which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);//如果转换IP的个数大于总Buffer数,就从0开始. 
115     sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
116     return output[which];
117 }
118 
119 char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
120 {
121     socklen_t sockaddrlen;
122 
123 #ifdef WIN32
124     sockaddrlen = sizeof(struct sockaddr_in6);
125 #else
126     sockaddrlen = sizeof(struct sockaddr_storage);
127 #endif
128 
129 
130     if (getnameinfo(sockaddr,
131         sockaddrlen,
132         address,
133         addrlen,
134         NULL,
135         0,
136         NI_NUMERICHOST) != 0) address = NULL;
137 
138     return address;
139 }

 

 技术分享

WinPcap笔记2之获取已经安装设备的高级信息

标签:loopback   put   ace   win   语法   技术   端口   wan   new   

原文地址:http://www.cnblogs.com/lanjianhappy/p/6667162.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!