paska
unread,Mar 11, 2008, 3:41:56 AM3/11/08Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
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"); //对数据包的处理,这里只是简单的显示。
}