WinPcap笔记2之获取已经安装设备的高级信息
Posted L的存在
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
(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:\\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 *)∈ 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之获取已经安装设备的高级信息的主要内容,如果未能解决你的问题,请参考以下文章