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

1 主要数据结构定义

(1)重要结构体

 1 struct pcap_if//网络接口列表的一个节点 一个网络接口就是一个结点 方便链表
 2 {
 3         struct pcap_if *next;//网络接口节点
 4         char *name;//网络接口名字
 5         struct pcap_addr *address;//网络接口地址
 6         bpf_u_int32 flags;//标记
 7         char *description;//描述信息
 8 }
 9 
10 typedefstruct pcap_ifpcap_if_t;
11 
12 typedef struct pcap_addr pcap_addrt//描述网络接口地址
13 {
14    struct pcap_addr *next;//下一个地址
15    struct sockaddr *addr;//接口地址
16    struct sockaddr *netmask;//子网掩码
17    struct sockaddr *broadaddr;//广播地址
18    struct sockaddr *dstaddr;//目标地址
19 }
View Code

(2)pcap_findalldevs_ex理解

1 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()’来获得本地机器的地址。pcap_findalldevs_ex()中的source决定的,sourse指定需要监控的网络适配器。他有特定的伪语法:

  •  file://folder/[列出指定文件夹中的所有文件]
  •  rpcap://[列出所有本地的适配器]
  • 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数字形式,端口号是字符形式]

(3)pcap_addr_t *a;理解

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

 1 typedef struct sockaddr_in {
 2 
 3 #if(_WIN32_WINNT < 0x0600)
 4     short   sin_family;
 5 #else //(_WIN32_WINNT < 0x0600)
 6     ADDRESS_FAMILY sin_family;
 7 #endif //(_WIN32_WINNT < 0x0600)
 8 
 9     USHORT sin_port;
10     IN_ADDR sin_addr;
11     CHAR sin_zero[8];
12 } SOCKADDR_IN, *PSOCKADDR_IN;
13 
14 struct pcap_addr {
15  struct pcap_addr *next;
16  struct sockaddr *addr;  /* address */
17  struct sockaddr *netmask; /* netmask for that address */
18  struct sockaddr *broadaddr; /* broadcast address for that address */
19  struct sockaddr *dstaddr; /* P2P destination address for that address */
20 };
21 
22 typedef struct in_addr {
23         union {
24                 struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
25                 struct { USHORT s_w1,s_w2; } S_un_w;
26                 ULONG S_addr;
27         } S_un;
28 #define s_addr  S_un.S_addr /* can be used for most tcp & ip code */
29 #define s_host  S_un.S_un_b.s_b2    // host on imp
30 #define s_net   S_un.S_un_b.s_b1    // network
31 #define s_imp   S_un.S_un_w.s_w2    // imp
32 #define s_impno S_un.S_un_b.s_b4    // imp #
33 #define s_lh    S_un.S_un_b.s_b3    // logical host
34 } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
35 
36 #endif

2 基本例子 获取已经安装设备的高级信息

#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:
"
 25         "rpcap://              ==> lists interfaces in the local machine
"
 26         "rpcap://hostname:port ==> lists interfaces in a remote machine
"
 27         "                          (rpcapd daemon must be up and running
"
 28         "                           and it must accept 'null' authentication)
"
 29         "file://foldername     ==> lists all pcap files in the give folder

"
 30         "Enter your choice: ");
 31 
 32     fgets(source, PCAP_ERRBUF_SIZE, stdin);
 33     source[PCAP_ERRBUF_SIZE] = '';
 34 
 35     /* 获得接口列表 */
 36     if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
 37     {
 38         fprintf(stderr, "Error in pcap_findalldevs: %s
", 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
", d->name);
 63 
 64     /* 设备描述(Description) */
 65     if (d->description)
 66         printf("	Description: %s
", d->description);
 67 
 68     /* Loopback Address*/
 69     printf("	Loopback: %s
", (d->flags & PCAP_IF_LOOPBACK) ? "yes" : "no");
 70 
 71     /* IP addresses */
 72     for (a = d->addresses; a; a = a->next) {
 73         printf("	Address Family: #%d
", a->addr->sa_family);
 74 
 75         switch (a->addr->sa_family)
 76         {
 77         case AF_INET:
 78             printf("	Address Family Name: AF_INET
");
 79             if (a->addr)
 80                 printf("	Address: %s
", iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
 81             if (a->netmask)
 82                 printf("	Netmask: %s
", iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
 83             if (a->broadaddr)
 84                 printf("	Broadcast Address: %s
", iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
 85             if (a->dstaddr)
 86                 printf("	Destination Address: %s
", iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
 87             break;
 88 
 89         case AF_INET6:
 90             printf("	Address Family Name: AF_INET6
");
 91             if (a->addr)
 92                 printf("	Address: %s
", ip6tos(a->addr, ip6str, sizeof(ip6str)));
 93             break;
 94 
 95         default:
 96             printf("	Address Family Name: Unknown
");
 97             break;
 98         }
 99     }
100     printf("
");
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 }
View Code
原文地址:https://www.cnblogs.com/lanjianhappy/p/6667162.html