现在我们已经知道了怎样去获取一个适配器并使用它,让我们开始真正的工作-----开始抓取网络数据包吧。在这一课中我们将写一个程序,这个程序将在我们选择的适配器上监听,并抓取通过这个适配器上的每一个数据包,打印其中的一些信息。
 我们主要使用的函数是pcap_open(),这个函数的功能是打开一个抓取设备。在这里有必要对其中的几个参数snaplen, flags and to_ms作一下说明。
 snaplen指定了我们所要抓取的包的长度(译者:也就是我们想抓多长就设置多长)。在一些操作系统(如xBSD和Win32)中,底层驱动可以通过配置只抓取数据包的开始部分:这样就减少了拷贝给应用程序的数据量,因此可以提高抓取效率。在这个例子里我们使用65536这个比我们所能遇到的最大的MTU还大的数字。这样我们就能确保我们的程序可以抓到整个数据包。
 flags:最重要的标志是一个指示适配器是否工作在混杂模式下的。在正常状况下,一个适配器仅仅抓取网络中目的地是它自己的数据包;因此其他主机交换的数据包都被忽略。相反,当适配器处在混杂模式下的时候它就会抓取所有的数据包而不管是不是发给它的。这就意味着在共享媒体(如非交换的以太网)上,WinPcap将能够抓取其他主机的数据包。混杂模式是大部分抓取程序的默认模式,所以在下面的例子中我们就开启它。
 to_ms以豪秒为单位指定了读取操作的超时界限。在适配器上一个读取操作(比如,pcap_dispatch() 或者 pcap_next_ex())将总是在to_ms豪秒后返回,即使网络中没有数据包可供抓取。如果适配器工作在统计模式(如果对此不了解,请看课程9),to_ms还定义了统计报告之间的间隔。把tm_ms设置为0意味着没有时间限制,如果没有数据包到达适配器,读取操作将永远不会返回。反过来,把tm_ms设置为-1将使读取操作总是立即返回。

#define HAVE_REMOTE #include <pcap.h> #pragma comment(lib,"wpcap.lib") /* 数据包处理程序,回调函数 */ 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; pcap_t *adhandle; char errbuf[PCAP_ERRBUF_SIZE]; /* Retrieve the device list on the local machine */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &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 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"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } /* Jump to the selected adapter */ for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); /* Open the device */ if ( (adhandle= pcap_open(d->name, // name of the device 65536, // portion of the packet to capture // 65536 guarantees that the whole packet will be captured on all the link layers PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode 1000, // read timeout NULL, // authentication on the remote machine errbuf // error buffer ) ) == NULL) { fprintf(stderr,"/nUnable to open the adapter. %s is not supported by WinPcap/n", d->name); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } printf("/nlistening on %s.../n", d->description); /* At this point, we don't need any more the device list. Free it */ pcap_freealldevs(alldevs); /* start the capture */ pcap_loop(adhandle, 0, packet_handler, NULL); return 0; } /* Callback function invoked by libpcap for every incoming packet */ void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { struct tm *ltime; char timestr[16]; /* convert the timestamp to readable format */ ltime=localtime(&header->ts.tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); printf("%s,%.6d len:%d/n", timestr, header->ts.tv_usec, header->len); }

程序运行说明:程序会打印出在上面时候接收到多大的数据包,注意到pcap_open()函数里面的3个重要参数:snaplen设置为65536保证每次都把整个包抓获;flags设置为混杂模式以便抓获所有的数据包。关于第三个参数to_ms,我运行的环境是WindowsXP,设置这个值对程序指向结果没有影响。

疑问:会不会是to_ms参数不被Wins平台支持?

一旦打开了适配器,就由pcap_dispatch() 或者pcap_loop()开始抓取。这两个函数都非常慢,所不同的是pcap_ dispatch()一旦超时就可以返回(尽管不能保证)而pcap_loop() 会一直等到cnt包被抓到才会返回,所以这个函数在没有数据包的网络中会阻塞任意的时间。在这个例子中pcap_loop()就足够了,而pcap_dispatch() 则可以在一个更复杂的程序中使用。
 这两个函数都有一个回调函数作为参数,packet_handler,这个参数指定的函数将收到数据包。这个函数在每一个新的数据包从网络中到达时都会被libpcap调用,并且会收到一个反映pcap_loop() 和 pcap_dispatch()函数的生成状态,和一个结构体header。这个header中带有一些数据包中的信息,比如时间戳和长度、包括所有协议头的实际数据包。注意结构体中是没有CRC的,因为在数据确认后已经被适配器去掉了。也要注意大部分适配器丢弃了CRC错误的数据包,因此Winpcap不能抓取这些包。
 上面的例子从pcap_pkthdr中提取每个数据包的时间戳和长度并显示它们。
 请注意使用pcap_loop()可能有一个缺点,就是使用这个函数时包处理函数要被包抓取驱动程序来调用;因此应用程序不能直接控制它。另一种方法(并且更容易理解)是使用函数pcap_next_ex(),这个函数我们将在下一个例子中使用。

转自:http://wotseb.bokee.com/1419050.html

WinPcap基础知识(第三课:打开一个适配器捕捉数据包)相关推荐

  1. Linux常用基础知识必备三之常用指令及操作

    Linux常用基础知识必备三之常用指令及操作 1.vi和vim vi如何使用 vi几种模式下的操作指令 命令模式进入编辑模式 命令模式下的快捷键 底行模式(指按了esc键之后输入按键:后出现) 字符串 ...

  2. 概率论基础知识(三) 参数估计

    概率论基础知识(三) 参数估计 1.矩 矩是用来描述随机变量的某些特征的数字,即求平均值,用大写字母E表示. 矩是更具有一般意义的数字特征. 设有随机变量X,若 E ( ∣ X ∣ k ) < ...

  3. 【STM32】基础知识 第十课 CubeMx

    [STM32]基础知识 第十课 CubeMx STM32 CubeMX 简介 安装 JAVA CubeMX 安装 新建 STM32 CubeMX 工程步骤 新建工程 时钟模块配置 GPIO 配置 生成 ...

  4. Python复习系列:Python基础知识(三)

    Python基础知识(三) Python基础知识(三) (一)循环结构和选择结构 1. 条件表达式 2. 选择结构 2.1 单分支选择结构 2.2 双分支选择结构 2.3 多分支选择结构 2.4 选择 ...

  5. 计算机基础知识讲课稿,《计算机基础知识》说课稿

    <计算机基础知识>说课稿 郭珊 尊敬的各位评委,亲爱的同学们: 大家好! 今天我说课的题目是<计算机硬件系统> ,下面我将从以下六个方面来展开 进行. 首先是教材分析 一.教材 ...

  6. CV:传统视觉知识—机器视觉系统的基础知识(机器视觉三要素+典型的工业机器视觉系统五大组件)

    CV:传统视觉知识-机器视觉系统的基础知识(机器视觉三要素+典型的工业机器视觉系统五大组件) 目录 机器视觉三要素 1.what-测量.判断 2.why-灵活性.自动化

  7. 计算机基础知识第三章答案,2011年河北省职称计算机模拟习题(基础知识第三章+标准答案)...

    2011年河北省职称计算机模拟习题(基础知识第三章+标准答案) 基础知识第三章 下列关于控制面板不正确的叙述是________. A.控制面板是一组系统管理程序 B.可以安装或删除系统的软件.硬件 C ...

  8. 计算机一切存储转化都是二进制,计算机基础知识讲稿三.doc

    计算机基础知识讲稿(三) --信息在计算机中的表示(续) 计算机内部,一切信息的存储.处理等都是采用二进制数的形式,但二进制的书写比较长,通常使用八进制及十六进制表示: 一 认识八进制数和十六进制数 ...

  9. Xshell通过SSH连接阿里云报错“服务器发送了一个意外的数据包” xshell连接ubuntu

    在阿里云的ubuntu系统用xshell连接发现报错无法连接,百度了一圈好多方法不行,这里给出我最后解决的方法. xshell报错提示:服务器发送了一个意外的数据包.received: 3,expec ...

最新文章

  1. 新病毒仿熊猫烧香 利用 Vista系统漏洞疯狂传播
  2. uva1347Tour
  3. Codeforces Round #647 (Div. 2) - Thanks, Algo Muse!(AB)
  4. JsonConfig处理日期时间
  5. javascript多重继承
  6. CSDN邀请您成为技术中心特约作者
  7. pmp备考资料这些都是必备的
  8. SQL Server 2012安装过程中出现 NetFx3错误
  9. 如何解决VS2017打开安装包运行报错问题
  10. 零基础怎么学计算机编程!看完的你,应该会恍然大悟!
  11. OpenCV各个版本的下载地址
  12. Kafka 集群搭建
  13. 组播源发现协议-MSDP
  14. Visual Studio Ultimate 2013(VS2013旗舰版 下载地址及哈希校验)
  15. Contrastive Loss
  16. Elasticsearch:Apache spark 大数据集成
  17. 作为一直火爆市场的二级分销,你知道哪些
  18. BZOJ[1135][POI2009]Lyz 线段树
  19. 【学会轮播图这一篇文章就足够啦】JS 网页轮播图详解 自动播放+手动播放
  20. php上传文件失败的原因,PHP图片文件上传失败的原因

热门文章

  1. 顺德区小学计算机课本,佛山市顺德区2011版信息技术学科教学计划(三年级下册).doc...
  2. wkhtmltopdf生成pdf时echarts图表不显示的问题
  3. ML拍照购物功能集成教程分享
  4. 罗马仕php30和plp30,华为p30和p30pro有什么区别
  5. 多媒体:图片PNG、IconFont、SVG图标资源优化详解
  6. Linux下WPS自主设置快捷键,WPS文字技巧—如何给特殊符号自定义快捷键
  7. linux设置mysql root密码_Linux 上安装 Mysql 设置root密码问题
  8. CentOS6升级到CentOS6CR
  9. VC++ 获取CPU的型号、主频和核数(附源码)
  10. IReport 导出PDF中的 平方(m²) 与 立方(m³) 特殊字符再Adobe Acrobat DC显示不全问题