不用回调方法捕获数据包
2012-03-10 22:00
561 查看
这一次要分析的实例程序跟上一讲非常类似(“打开适配器并捕获数据包”),略微不同的一点是本次将pcap_loop()函数替换成了pcap_next_ex()函数。本节的重点也就是说一下这两个函数之间的差异。我们知道pcap_loop()函数是基于回调的原理来进行数据捕获的,如技术文档所说,这是一种精妙的方法,并且在某些场合下,它是一种很好的选择。但是在处理回调有时候会并不实用,它会增加程序的复杂度,特别是在多线程的C++程序中。而对于pcap_next_ex()函数而言,可以通过直接调用它来获得一个数据包,也只有在调用了这个函数才能收到数据包。pcap_next_ex()函数跟pcap_loop()的回调函数参数是相同的:
第一个参数是网络适配器的描述符;第二个参数是一个指向pcap_pkthdr结构体的指针;第三个参数是指向数据报数据的缓冲的指针。
来看一下实例程序的代码:
文档上在最后简单地比较了一下pcap_next_ex()函数和pcap_next()函数的区别,通过函数名我们知道pcap_next_ex()函数是在pcap_next()基础上扩展得到的。为什么会扩展?根据文档说明可以知道,pcap_next()函数有一些缺陷。比如它效率很低,尽管隐藏了回调的方式,但它仍然依赖于函数pcap_dispatch();另外,它不能检测到EOF这个状态,那么如果数据包是从文件中读取过来的,那么它就不那么好用了。显然,pcap_next_ex()函数在此基础上做出了一些改进。最后我们来看一下pcap_next_ex()函数的返回值,引用文档中的描述:
The return value can be:
1 if the packet has been read without problems (数据读取无误)
0 if the timeout set with pcap_open_live() has elapsed. In this case pkt_header and pkt_data don't point to a valid packet
(pcap_open_live()设置的超时时间超时,在这种情况下pkt_header和pkt_data指向一个非法的数据)
-1 if an error occurred (出错)
-2 if EOF was reached reading from an offline capture (读取到EOF,应该是文件)
int pcap_next_ex ( pcap_t * p, struct pcap_pkthdr ** pkt_header, const u_char ** pkt_data )
第一个参数是网络适配器的描述符;第二个参数是一个指向pcap_pkthdr结构体的指针;第三个参数是指向数据报数据的缓冲的指针。
来看一下实例程序的代码:
#define HAVE_REMOTE #include <pcap.h> int main() { pcap_if_t *alldevs; pcap_if_t *d; int inum; int i=0; pcap_t *adhandle; int res; char errbuf[PCAP_ERRBUF_SIZE]; struct tm *ltime; char timestr[16]; struct pcap_pkthdr *header; const u_char *pkt_data; time_t local_tv_sec; /* 获取本机设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &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(d->name, // 设备名 65536, // 要捕捉的数据包的部分 // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式 1000, // 读取超时时间 NULL, // 远程机器验证 errbuf // 错误缓冲池 ) ) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); /* 释放设列表 */ pcap_freealldevs(alldevs); return -1; } printf("\nlistening on %s...\n", d->description); /* 释放设备列表 */ pcap_freealldevs(alldevs); /* 获取数据包 */ while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0) { if(res == 0) /* 超时时间到 */ continue; /* 将时间戳转换成可识别的格式 */ local_tv_sec = header->ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); printf("%s,%.6ld len:%d\n", timestr, header->ts.tv_usec, header->len); } if(res == -1) { printf("Error reading the packets: %s\n", pcap_geterr(adhandle)); return -1; } return 0; }
文档上在最后简单地比较了一下pcap_next_ex()函数和pcap_next()函数的区别,通过函数名我们知道pcap_next_ex()函数是在pcap_next()基础上扩展得到的。为什么会扩展?根据文档说明可以知道,pcap_next()函数有一些缺陷。比如它效率很低,尽管隐藏了回调的方式,但它仍然依赖于函数pcap_dispatch();另外,它不能检测到EOF这个状态,那么如果数据包是从文件中读取过来的,那么它就不那么好用了。显然,pcap_next_ex()函数在此基础上做出了一些改进。最后我们来看一下pcap_next_ex()函数的返回值,引用文档中的描述:
The return value can be:
1 if the packet has been read without problems (数据读取无误)
0 if the timeout set with pcap_open_live() has elapsed. In this case pkt_header and pkt_data don't point to a valid packet
(pcap_open_live()设置的超时时间超时,在这种情况下pkt_header和pkt_data指向一个非法的数据)
-1 if an error occurred (出错)
-2 if EOF was reached reading from an offline capture (读取到EOF,应该是文件)
相关文章推荐
- WinPcap编程【5】不用回调方法捕获数据包
- Winpcap打开适配器并捕获数据包:不用回调方法捕获数据包
- Winpcap打开适配器并捕获数据包:不用回调方法捕获数据包
- WinPcap笔记(5):不用回调方法捕获数据包
- 不用回调方法捕获数据包
- WinPcap编程【5】不用回调方法捕获数据包
- winPcap编程之不用回调方法捕获数据包(五 转)
- 不用回调方法捕获数据包
- 不用回调方法捕获数据包
- winPcap_6_不用回调方法捕获数据包
- 不用回调方法捕获数据包
- winPcap学习笔记4_不用回调方法捕获数据包(转)
- WinPcap学习(五)不用回调方法捕获数据包
- [网络分析] 3 不用回调的方式捕获数据包
- WinPcap教程:(4)不用回调方式捕获数据包
- WinPcap编程入门(4)——不使用回调方法获取数据包
- 【笔记】wincap网络数据包的捕获——使用函数回调
- 【笔记】wincap网络数据包的捕获——不使用回调的方式
- 不用密码进入XP系统的方法