WinPcap教程1——据说为珊瑚虫所译

一些需要知道的细节描述(前言):
这一部分展示了如何使用WINPCAP-API的不同的功能,它作为一个使用指南被划分为一系列的课时来带领读者循序渐进的体会PCAP的程序设计的

魅力:从简单的基本功能(如获取网卡的列表,数据包的捕获等)到统计和收集网络流量等高级功能。

在这里将提供一些简单但完整的代码作为参考:所有的这些原代码都有和它相关的详细信息的连接以便单击这些功能和数据结构时能够即使跳转到相关的文献。

这些例子是用C语言写的,所以在学习之前首先要有一定的C语言的基础,当然PCAP作为一个网络底层的驱动,要想学好它也必须具备一定的网络方面的知识。

 

(一)得到网络驱动列表

用PCAP写应用程序的第一件事往往就是要获得本地的网卡列表。PCAP提供了pcap_findalldevs()这个函数来实现此功能,这个API返回一个pcap_if结构的连表,连表的每项内容都含有全面的网卡信息:尤其是字段名字和含有名字的描述以及有关驱动器的易读信息。

得到网络驱动列表的程序如下:

#include "pcap.h"

main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];

/* 这个API用来获得网卡 的列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}

/* 显示列表的响应字段的内容 */
for(d=alldevs;d;d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else printf(" (No description available)\n");
}

if(i==0)
{
printf("\nNo inte***ces found! Make sure WinPcap is installed.\n");
return;
}

/* We don‘t need any more the device list. Free it */
pcap_freealldevs(alldevs);
}

 

有关这段程序的一些说明:
首先pcap_findalldevs()同其他的libpcap函数一样有一个errbuf参数,当有异常情况发生时,这个参数会被PCAP填充为某个特定的错误字串。

再次,UNIX也同样提供pcap_findalldevs()这个函数,但是请注意并非所有的系统都支持libpcap提供的网络程序接口。所以我门要想写出合适

的程序就必须考虑到这些情况(系统不能够返回一些字段的描述信息),在这种情况下我门应该给出类似"No description available"这样的

提示。

最后结束时别忘了用pcap_freealldevs()释放掉内存资源。

 


#include "pcap.h"

main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];

/* Retrieve the device list */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}

/* Print the list */
for(d=alldevs;d;d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else printf(" (No description available)\n");
}

if(i==0)
{
printf("\nNo inte***ces found! Make sure WinPcap is installed.\n");
return;
}

/* We don‘t need any more the device list. Free it */
pcap_freealldevs(alldevs);
}

(二)获得已安装网络驱动器的高级信息

在第一章中演示了如何获得已存在适配器的静态信息。实际上WinPcap同样也提供其他的高级信息,特别是 pcap_findalldevs()这个函数返回的每个 pcap_if结构体都同样包含一个pcap_addr结构的列表,他包含:
一个地址列表,一个掩码列表,一个广播地址列表和一个目的地址列表。
下面的例子通过一个ifprint()函数打印出了pcap_if结构的的所有字段信息,该程序对每一个pcap_findalldevs()所返回的pcap_if结构循环调用ifprint()来显示详细的字段信息。


#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);

int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
char errbuf[PCAP_ERRBUF_SIZE+1];

/* 获得网卡的列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
exit(1);
}

/* 循环调用ifprint() 来显示pcap_if结构的信息*/
for(d=alldevs;d;d=d->next)
{
ifprint(d);
}

return 1;
}

/* Print all the available information on the given inte***ce */
void ifprint(pcap_if_t *d)
{
pcap_addr_t *a;

/* 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);

/*关于 sockaddr_in 结构请参考其他的网络编程书*/
switch(a->addr->sa_family)
{
case AF_INET:
printf("\tAddress Family Name: AF_INET\n");//打印网络地址类型
if (a->addr)//打印IP地址
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;
default:
printf("\tAddress Family Name: Unknown\n");
break;
}
}
printf("\n");
}

/* 将一个unsigned long 型的IP转换为字符串类型的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.%*", *[0], *[1], p[2], p[3]);
return output[which];

 

此文章来自于【http://blog.163.com/szlear@126/blog/static/637030312005710015570/】

你可能感兴趣的:(WinPcap教程1——据说为珊瑚虫所译)