您的位置:首页 > 理论基础 > 计算机网络

WinPcap教程:(3)打开适配器并捕获数据包

2017-05-17 15:54 295 查看
现在,我们已经知道如何获取适配器的信息了,那我们就开始一项更具意义的工作,打开适配器并捕获数据包。我们会编写一个程序,将每一个通过适配器的数据包打印出来。

1、打开设备

打开设备的函数是pcap_open()。下面是参数snaplen,flags和to_ms的解释说明。

snaplen制定要捕获数据包中的哪些部分。在一些操作系统中(比如xBSD和Win32),驱动可以被配置成只捕获数据包的初始化部分。这样可以减少应用程序间复制数据的量,从而提高捕获效率。我们将值定为  65535,它比我们能遇到的最大的MTU还要大。因此,我们确信我们总能收到完整的数据包。

flags是最最重要的。flag是用来指示适配器是否要被设置成混杂模式。一般情况下,适配器只接收发给它自己的数据包,而那些在其他机器之间通讯的数据包将会被丢弃。相反,如果适配器是混杂模式,那么不管这个数据包是不是发给我的,我都会去捕获。也就是说,我会去捕获所有的数据包。这意味着在一个共享媒介(比如总线型以太网),WinPcap能捕获其他主机的所有的数据包。大多数用于数据捕获的应用程序都会将适配器设置成混杂模式。

to_ms指定读取数据的超时时间,以毫秒计(1s=1000ms)。在适配器上进行读取操作(比如用pcap_dispatch()或pcap_next_ex())都会在to_ms毫秒时间内响应,即使在网络上没有可用的数据包。在统计模式下,to_ms还可以用来定义统计的时间间隔。将to_ms设置为0意味着没有超时,那么如果没有数据包到达的话,读操作将永远不会返回。如果设置成-1,则情况恰好相反,无论有没有数据包到达,读操作都会立即返回。

2、捕获数据包

当适配器被打开,捕获工作就可以用pcap_dispatch()或pcap_loop()进行。

这两个函数非常的相似,区别就是pcap_ dispatch()当超时时间到了(timeout expires)就返回(尽管不能保证),而pcap_loop()不会因此而返回,只有当cnt数据包被捕获。

所以,pcap_loop()会在一小段时间内,阻塞网络的利用。pcap_dispatch()函数一般用于比较复杂的程序中。

这两个函数都有一个回调参数,packet_handler指向一个可以接收数据包的函数。这个函数会在收到每个新的数据包并收到一个通用状态时被libpcap所调用(与函数pcap_loop()和pcap_dispatch()中的user参数相似),数据包的首部一般有一些诸如时间戳,数据包长度的信息,还有包含了协议首部的实际数据。

注意:冗余校验码CRC不再支持,因为帧到达适配器,并经过校验确认以后,适配器就会将  CRC  删除,与此同时,大部分适配器会直接丢弃CRC错误的数据包,所以,WinPcap  没法捕获到它们。

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_loop(adhandle,0,packet_handler,NULL);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  WinPcap 网络 抓包