winPcap学习笔记2_获取已安装设备的高级信息(转)

在第1课中, (获取设备列表) 我们展示了如何获取适配器的基本信息 (如设备的名称和描述)。 事实上,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()函数来实现打印。

 

代码
/*
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
* nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

#include
"pcap.h"

#ifndef WIN32
#include
<sys/socket.h>
#include
<netinet/in.h>
#else
#include
<winsock.h>
#endif


// 函数原型
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 *)&in;
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;
}

 原作者:The WinPcap Team  主页: http://www.winpcap.org

posted @ 2010-07-18 00:18  董雨  阅读(282)  评论(0编辑  收藏  举报