(获取设备列表) 我们展示了如何获取适配器的基本信息 (如设备的名称和描述)。 事实上,WinPcap提供了其他更高级的信息。 特别需要指出的是, 由 pcap_findalldevs_ex() 返回的每一个 pcap_if 结构体,都包含一个 pcap_addr 结构体,这个结构体由如下元素组成:
- 一个地址列表
- 一个掩码列表 (each of which corresponds to an entry in the addresses list).
- 一个广播地址列表 (each of which corresponds to an entry in the addresses list).
- 一个目的地址列表 (each of which corresponds to an entry in the addresses list).
另外,函数 pcap_findalldevs_ex() 还能返回远程适配器信息和一个位于所给的本地文件夹的pcap文件列表。
下面的范例使用了ifprint()函数来打印出 pcap_if 结构体中所有的内容。程序对每一个由 pcap_findalldevs_ex() 函数返回的pcap_if,都调用ifprint()函数来实现打印。
- #include "pcap.h"
- #ifndef WIN32
- #include <sys/socket.h>
- #include <netinet/in.h>
- #else
- #include <winsock.h>
- #include <wspiapi.h>//getnameinfo
- #endif
- #pragma comment(lib,"ws2_32.lib")
- #pragma comment(lib,"wpcap.lib")
- // 函数原型
- void ifprint(pcap_if_t *d);
- char *iptos(u_long in);
- char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);
- int main()//samp2()
- {
- 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);
- fgets(source, PCAP_ERRBUF_SIZE, stdin);
- 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;
- }