获取已安装设备的高级信息
2012-03-10 11:41
441 查看
继续WinPcap编程的学习,上一节说到《获取本地适配器信息》,本节的实例程序功能跟上一节的程序功能类似,只是打印了适配器更详细的信息,来看一下源码(在windows下codeblocks下编译运行,即使用MingW编译器通过)
在编译本程序的时候碰到了很多问题,这里想总结一下解决的办法。之前在网上查找过很多博客,但是发现程序都是在VC下进行编译的,而我的codeblocks用的是MingW编译器进行编译的,之间会有很多区别,VC编译器如何解决我这里就不做介绍了,因为编写C程序还是比较习惯在codeblocks下,个人偏好。配置其实跟VC下的配置差不多,仍然是在Link Libraries下加入Packet.lib和wpcap.lib,这两个库文件是WinPcap提供的;另外,还要添加libws2_32.a这个库,这个库可以在MingW安装目录下的lib文件夹里面找到,VC下面是要添加ws2_32.lib这个库,大家千万不要搞混了,因为有看到很多博客上写的是配置codeblocks添加ws2_32.lib,当然如果是用VC的编译器就没问题,但如果用MingW编译器一般不会报错,但是会出现很多Warning,大家注意一下便是。截图给大家看一下,以下是本机codeblocks Link Libraries添加的情况:
另外,在Search directories的Compiler目录下加入WinPcap的include目录,也可以把MingW安装目录下的include目录添加进去,添不添加关系不大,但是WinPcap的include目录一定是要包含进去的。同样,截图给大家看一下本机配置情况:
再看一看源程序,跟上一个程序很类似。只是本程序提供了更高级的信息。我们知道由pcap_findalldevs_ex()返回的每一个pcap_if结构体,都包含一个pcap_addr结构体,这个结构体如下元素组成:
一个地址列表、一个掩码列表、一个广播地址列表、一个目的地址列表
另外,函数pcap_findalldevs_ex()还能返回远程适配器信息和一个位于所给的本地文件夹的pcap文件列表,跟函数第一个参数有关。
我们看到源码中声明了3个函数,ifprint、iptos和ip6tos。ifprint函数其实就是一个打印函数,打印设备名、设备描述、回环地址、IP地址信息;iptos函数和ip6tos函数功能类似,就是把IP地址转换成为char*类型,只是协议族不同,一个是ipv4,另一个是ipv6,而且iptos函数参数中IP地址是unsigned long类型,ip6tos函数参数中IP地址是sockaddr结构体指针类型。
程序功能很简单,但是有一点想说一下。我们看到源码中多了一行:
这行是搞什么东东呢?源码中也没用到这个WINVER是吧。我刚开始因为没有添加这一行折腾了很久,一直报getnameinfo这个函数未定义,但是查看getnameinfo函数的声明处又偏偏看到了:
找了很久没有找到答案,于是自己仔细分析了一下,因为这是一个条件编译,如果说没有找到声明,肯定是if判断不成功。于是乎我看了一下_WIN32_WINNT是在哪里声明的:
原来_WIN32_WINNT的前身是WINVER!!根据它的注释的意思,是要自己define WINVER或者包含windef.h这个头文件,但是查看windef.h这个头文件看到WINVER的值为0x0400,包含了这个头文件条件编译仍然是不能通过的,要大于或等于0x0501。那得了,我们之间#define WINVER 0x0501不就好了,事实上也是的,添加进去后编译就可以通过了,Congratulations!下面是程序运行后的截图:
输入rpcap://后回车,返回结果如下图所示:
//#define WPCAP //#include <winsock2.h> #define WINVER 0x0501 #define HAVE_REMOTE #include <pcap.h> //#include <winsock2.h> #include <ws2tcpip.h> //#define _WIN32_WINNT 0x0501 //typedef int socklen_t; // 函数原型 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'; /* 获得接口列表 */ if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf); exit(1); } /* 扫描列表并打印每一项 */ for(d=alldevs;d;d=d->next) { ifprint(d); } pcap_freealldevs(alldevs); return 1; } /* 打印所有可用信息 */ 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"); } /* 将数字类型的IP地址转换成字符串类型的 */ #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; }
在编译本程序的时候碰到了很多问题,这里想总结一下解决的办法。之前在网上查找过很多博客,但是发现程序都是在VC下进行编译的,而我的codeblocks用的是MingW编译器进行编译的,之间会有很多区别,VC编译器如何解决我这里就不做介绍了,因为编写C程序还是比较习惯在codeblocks下,个人偏好。配置其实跟VC下的配置差不多,仍然是在Link Libraries下加入Packet.lib和wpcap.lib,这两个库文件是WinPcap提供的;另外,还要添加libws2_32.a这个库,这个库可以在MingW安装目录下的lib文件夹里面找到,VC下面是要添加ws2_32.lib这个库,大家千万不要搞混了,因为有看到很多博客上写的是配置codeblocks添加ws2_32.lib,当然如果是用VC的编译器就没问题,但如果用MingW编译器一般不会报错,但是会出现很多Warning,大家注意一下便是。截图给大家看一下,以下是本机codeblocks Link Libraries添加的情况:
另外,在Search directories的Compiler目录下加入WinPcap的include目录,也可以把MingW安装目录下的include目录添加进去,添不添加关系不大,但是WinPcap的include目录一定是要包含进去的。同样,截图给大家看一下本机配置情况:
再看一看源程序,跟上一个程序很类似。只是本程序提供了更高级的信息。我们知道由pcap_findalldevs_ex()返回的每一个pcap_if结构体,都包含一个pcap_addr结构体,这个结构体如下元素组成:
一个地址列表、一个掩码列表、一个广播地址列表、一个目的地址列表
另外,函数pcap_findalldevs_ex()还能返回远程适配器信息和一个位于所给的本地文件夹的pcap文件列表,跟函数第一个参数有关。
我们看到源码中声明了3个函数,ifprint、iptos和ip6tos。ifprint函数其实就是一个打印函数,打印设备名、设备描述、回环地址、IP地址信息;iptos函数和ip6tos函数功能类似,就是把IP地址转换成为char*类型,只是协议族不同,一个是ipv4,另一个是ipv6,而且iptos函数参数中IP地址是unsigned long类型,ip6tos函数参数中IP地址是sockaddr结构体指针类型。
程序功能很简单,但是有一点想说一下。我们看到源码中多了一行:
#define WINVER 0x0501
这行是搞什么东东呢?源码中也没用到这个WINVER是吧。我刚开始因为没有添加这一行折腾了很久,一直报getnameinfo这个函数未定义,但是查看getnameinfo函数的声明处又偏偏看到了:
找了很久没有找到答案,于是自己仔细分析了一下,因为这是一个条件编译,如果说没有找到声明,肯定是if判断不成功。于是乎我看了一下_WIN32_WINNT是在哪里声明的:
原来_WIN32_WINNT的前身是WINVER!!根据它的注释的意思,是要自己define WINVER或者包含windef.h这个头文件,但是查看windef.h这个头文件看到WINVER的值为0x0400,包含了这个头文件条件编译仍然是不能通过的,要大于或等于0x0501。那得了,我们之间#define WINVER 0x0501不就好了,事实上也是的,添加进去后编译就可以通过了,Congratulations!下面是程序运行后的截图:
输入rpcap://后回车,返回结果如下图所示:
相关文章推荐
- WinPcap学习(三)获取已安装设备的高级信息
- winpcap编程学习笔记(2) 获取已安装设备的高级信息
- WinPcap编程【3】获取已安装设备的高级信息
- WinPcap编程入门(2)——获取安装设备的高级信息
- WinPcap之获取已安装设备的高级信息
- Winpcap网络编程六之Winpcap学习教程,获取已安装设备的高级信息
- WinPcap教程:(2)获取已安装设备的高级信息
- winPcap学习笔记2_获取已安装设备的高级信息(转)
- 获取已安装设备的高级信息
- winPcap_4_获取已安装设备的高级信息
- WinPcap之获取已安装设备的高级信息
- WinPcap编程【3】获取已安装设备的高级信息
- WinPcap基础知识(第二课:获得已安装设备的高级信息)
- WinPcap教程(2):获取设备高级信息
- 电脑安装了金山毒霸,手机连接电脑,输入adb devices 无法获取设备信息的解决方法
- WinPcap笔记(3):获取已安装设备的详细信息
- WinPcap教程(2):获取设备高级信息
- iOS设备安装App列表信息获取
- 获取android设备已安装应用信息
- 获取安装游戏应用设备信息(swift)