Winpcap捕获网络数据包的一般步骤

21 views
Skip to first unread message

paska

unread,
Mar 11, 2008, 3:41:56 AM3/11/08
to 姚博士的论坛-教学
Winpcap捕获网络数据包的一般步骤

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

2、打开指定的网卡。
打开网卡的功能是通过pcap_open_live(char * device, int snaplen,int promisc,
int to_ms, char * errbuf)来实现的。参数device:网卡的描述符指针;snaplen:规定捕获的每个数据包的最大字节
数,当值为65535时为捕获所有数据包;promisc:1为混杂模式,0为非混杂模式;to_ms:指定读数据的超时控制,超时以毫秒计算.

3、数据包的过滤(可选)。
通常我们只对特定网络通信感兴趣。比如我们只打算监听Telnet服务(port 23),可以通过pcap_compile()和
pcap_setfilter()来设置数据流过滤规则(filter)。如果想捕获网络中的所有数据,可省略此步骤。

4、捕获并处理数据包。
pcap_loop(pcap_t * p, int cnt, pcap_handler callback,u_char * user)是
一个循环捕获数据包的函数。参数pcap_t * p:pcap_findalldevs返回的数据包捕获的指针;int cnt:规定了捕获多少数据
包结束,0为无穷大;pcap_handler callback:指向一个函数,这个函数就是对捕获到的数据包进行处理,因此是应用程序中最主要的一
步;u_char *user:该指针用于传递给callback。

5、释放网络接口。
使用完网卡之后,调用pcap_freealldevs()函数释放网卡。


下面以一个简单的例子,说明winpcap捕获数据包的一般步骤。

#include "pcap.h"
#include "stdio.h"
/* 数据包处理函数声明 */
pcap_t *adhandle;
void packet_handler(u_char *param, const struct pcap_pkthdr *header,
const u_char *pkt_data);

main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;

char errbuf[PCAP_ERRBUF_SIZE];

/* 获取网卡列表 */
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 interfaces found! Make sure WinPcap is installed.\n");
return -1;
}

printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);

if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* 释放网卡列表 */
pcap_freealldevs(alldevs);
return -1;
}

/* 转到选择的网卡 */
for(d=alldevs, i=0; i< inum-1;d=d->next, i++);

/* 打开网卡 */
if( (adhandle= pcap_open_live(d->name, //设备名
65535, // 捕捉完整的数据包
1, // 混在模式
1000, // 读入超时
errbuf // 错误缓冲
) ) == NULL)
{
/* Y- 打开失败*/
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by
WinPcap\n");
/* 释放列表 */
pcap_freealldevs(alldevs);
return -1;
}

printf("\nlistening on %s...\n", d->description);

/* 我们已经不需要网卡列表了, 释放它 */
pcap_freealldevs(alldevs);

/* 开始捕获数据包 */
pcap_loop(adhandle, 0, packet_handler, NULL);

return 0;
}


/* 处理数据包的回调函数*/
void packet_handler(u_char *param, const struct pcap_pkthdr *header,
const u_char *pkt_data)
{
printf("I get a packet!\n"); //对数据包的处理,这里只是简单的显示。
}

Reply all
Reply to author
Forward
0 new messages