专业游戏门户,分享手游网游单机游戏百科知识攻略!

嗨游网
嗨游网

winpcap编程软件使用教程

来源:小嗨整编  作者:小嗨  发布时间:2023-03-21 05:06
摘要:winpcap编程软件使用教程WinPcap原理我们在安装WinPcap的时候,除了安装相关的Dll文件到系统目录,最重要的是在系统的NDIS层安装了一个用于原始封包过滤的驱动程序。通过Dll提供的函数,使得运行于Ring3层的应用程序也能...

winpcap编程软件使用教程

winpcap编程软件使用教程

WinPcap 原理
我们在安装 WinPcap 的时候,除了安装相关的 Dll 文件到系统目录,最重要的是在系统的 NDIS 层安装了一个用于原始封包过滤的驱动程序。通过 Dll 提供的函数,使得运行于 Ring3 层的应用程序也能访问到底层的网络数据。至于这些过程具体是如何实现的,不是本教程关注的内容,有兴趣的读者可以自行百度,或者直接阅读 WinPcap 的源码!有任何心得体会欢迎与我交流:)
WinPcap 编程的一般方法
平心而论,使用 WinPcap 提供的 API 接口编程实现原始封包数据的获取、发送、转储等功能,还是比较简单的。以抓包为例,必须步骤依次是:获取网络驱动接口、打开网络驱动接口、开始抓包,通常我们不会需要捕获所有的数据包,因此抓包之前还需要设定合适的过滤规则,比如指定 IP 地址、TCP 或者 UDP 端口等等。下面将分别介绍这些步骤。
1、获取网络驱动接口
需要注意的是,我们这里说的是网络驱动接口,而不是物理网卡,也就是说实际上 WinPcap 是通过网卡驱动程序来实现与网卡的交互。这也就是为什么在很多机器上明明只有一个物理网卡,但 WinPcap 却能获取到两个或者更多的网卡驱动接口信息。那些软件虚拟的网卡多数是因为系统中安装了与 VPN 客户端类似的连接程序。下面是获取网络驱动接口信息的代码:

  1.                 pcap_if_t *alldevs, *pDev;

  2.                 char errbuf[PCAP_ERRBUF_SIZE+1];

  3.                 /* Retrieve the device list */

  4.                 if(pcap_findalldevs(&alldevs, errbuf) == -1)

  5.                 {

  6.                         //出错了返回自定义错误代码‘2’,通常用于定位故障;

  7.                         return 2;

  8.                 }

复制代码

函数 pcap_findalldevs 用于获取网络驱动接口的相关信息,并将他们存储在由 alldevs 指向的链表结构中。该链表结构的元素均由 pcap_if_t  结构定义,其中最重要的字段就是接口的名字,在以上代码中可以使用 pDev->name 访问,比如笔者机器上的物理网卡的 name 就是:

  1. \Device\NPF_{79D843D7-2AE1-4E2E-A54F-D46154627742}

复制代码

这个名字不是很友好,看起来应该就是系统注册表中对应的表项值。pDev->description 中是此接口的描述信息:

  1. Network adapter 'Realtek 10/100/1000 Ethernet NIC

复制代码

这个就友好多了吧。除了名字和描述,pDev->address 也很重要,主要保存了配置在该接口上的网络地址,通常就是 IP 地址和对应的掩码。需要注意的是,一个网络接口上通常可以配置多个地址,因此 address 字段指向的是一个地址链表。
2、选择合适的网络驱动接口(最佳路由匹配)
如果上一步仅获取到一个接口,那就直接用它好了,但是实际的情况是很多时候你都会获取到两个以及两个以上的接口。比如笔记本电脑通常会有有线和无线两种网卡,自然对应两个网络驱动接口。那么这种情况下如何选择合适的网卡呢?通常为了简化程序设计,可以直接将列出所有的接口信息,让用户手动选择!但是本教程采用最佳路由匹配的方法让程序自动选择合适的接口。
要使用最佳路由匹配,需要在我们的程序中包含 Iphlpapi.h 头文件,这是标准的 Windows API,因此可以使用如下代码:

  1. #include <Iphlpapi.h>

复制代码

所谓最佳路由,其实就是找网关,方法是调用函数 GetBestRoute 计算出到达某个公网地址“114.114.114.114”的下一跳地址,通常就是网卡上配置的网关地址。接着逐个计算网络驱动接口上的 IP 是否与下一跳地址在相同网段,如果确实在相同网段,那么则拥有该 IP 的接口就是我们要使用的接口。关于 IP 路由的基础知识,如果您不是很了解的话,可以参考本站教程:[图解] IP 路由基础。通过最佳路由选定网络接口(网卡)的代码如下:

  1.                 PMIB_IPFORWARDROW pBestRoute = new MIB_IPFORWARDROW;

  2.                 DWORD dwGateway,*pIPAddr,*pNetMask;

  3.                 CString str;

  4.                 if(GetBestRoute(inet_addr("114.114.114.114"),0,pBestRoute) == NO_ERROR)

  5.                 { 

  6.                         dwGateway = pBestRoute->dwForwardNextHop;

  7.                 }

  8.                 pcap_addr_t *a;

  9.                 for(pDev=alldevs;pDev;pDev=pDev->next)

  10.                 {

  11.                         for(a=pDev->addresses;a;a=a->next)

  12.                         {

  13.                                 if(a->addr->sa_family == AF_INET)

  14.                                 {

  15.                                         pIPAddr = (DWORD*)(&a->addr->sa_data[2]);

  16.                                         pNetMask = (DWORD*)(&a->netmask->sa_data[2]);

  17.                                         if((*pIPAddr & *pNetMask) == (dwGateway & *pNetMask))

  18.                                         {

  19.                                                 str.Format("%s",pDev->name);

  20.                                                 pcap_freealldevs(alldevs);

  21.                                                 delete pBestRoute;

  22.                                         }

  23.                                 }

  24.                         }

  25. }

复制代码

这段代码首先使用函数 GetBestRoute 获取到达指定地址“114.114.114.114”的最佳路由信息,并将其存储在由 pBestRoute 指向的 MIB_IPFORWARDROW 结构中,MIB_IPFORWARDROW 结构中的字段 dwForwardNextHop 就是我们所需要的下一跳地址,多数情况下这就是网关地址!然后接下来的循环体用来找出与下一跳地址在相同网段的接口 IP,外循环是遍历网络驱动接口,内循环是遍历当前接口上的 IP 地址。判断接口 IP 与下一跳地址是否在相同网段的方法是:“接口IP & 接口掩码” 等于 “下一跳(网关)地址 & 接口掩码”,如果找到了符合条件的 IP ,则将拥有这个 IP 地址的网络驱动接口的名字保存起来,然后使用函数 pcap_freealldevs 释放之前由 pcap_findalldevs 获取的接口列表 alldevs。
注意:此方法并不能适用于系统中存在逻辑连接的情况!什么是逻辑连接?很多计算机上网都是通过 PPPoE 宽带拨号上网的,拨号成功以后系统中将存在一条逻辑连接,它是建立在网络驱动接口之上的虚拟连接,而 pcap_findalldevs 函数无法获取到这些逻辑连接的信息。同时 WinXP 系统下没有很好的办法可以获取逻辑连接与网络驱动接口直接的堆叠关系,如果是 Win7 或者以上系统则可以通过 GetIfStackTable 函数来获取逻辑连接与物理连接之间的堆叠关系。
3、打开网络驱动接口
当选定了正确的网络驱动接口后,使用函数 pcap_open 来打开网络驱动接口,如果成功将返回一个对应网络驱动接口的句柄,并保存在 adhandle 中,以后如果需要对该网络驱动接口进行相关操作,那么都可以通过 adhandle 来实现。

  1. if((adhandle = pcap_open(pDev->name, 65536, 0, 250, NULL, errbuf)) == NULL)[indent]{

  2.         // 打开失败!

  3.         return 0;

  4. }

复制代码

仅打开接口,创建一个接口句柄还不能满足我们的要求,必须要能针对指定的封包流(只对游戏封包感兴趣)进行过滤,一来降低系统消耗,二来减少不必要的数据处理。因此我们还需要设定过滤规则,并将过滤规则与网络驱动接口绑定。相关代码如下:

  1. if(pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0)

  2. {

  3.         //过滤规则编译失败!

  4.         return 0;

  5. }

  6. if (pcap_setfilter(adhandle, &fcode)<0)[/indent]{

  7.         //设定过滤规则失败!

  8.         return 0;

  9. }

复制代码

代码中的 fcode 是由函数 pcap_compile 输出的过滤规则,根据 WinPcap 手册我们知道 fcode 中保存的是二进制的可执行代码,可以通过函数 pcap_setfilter 将这段代码与对应的网络驱动接口绑定起来,以实现对指定封包数据流的捕获。packet_filter  则是用用户指定的用于描述封包数据流的规则,也就是通常所说的过滤规则。fcode 和 packet_filter 可以通过如下代码定义:

  1.         char *packet_filter = "tcp port 4000";

  2.         struct bpf_program fcode;

复制代码

封包过滤规则详见 WinPcap 手册中的“Filtering expression syntax”小节。
4、开始抓包
在以上步骤都顺利完成后,终于可以开始捕获我们心仪已久网络封包数据了!在 WinPcap 中提供了三种获取封包的方式,分别是:pcap_loop、pcap_dispatch 和 pcap_next(pcap_next_ex),如何选择呢?
首先 pcap_next 不支持回调函数,大大降低灵活性,直接出局!pcap_loop 貌似没有 pcap_dispatch 灵活,介于 WinPcap 对 pcap_loop 与 pcap_dispatch 区别的介绍不够详细,我也不好妄自揣测。本文选择使用 pcap_dispatch 的原因是因为大名鼎鼎的 Wireshark 就是用的 pcap_dispatch ,有兴趣的朋友可以去读读 Wireshark 的源码(dumpcap.c)。开启抓包的代码如下:

  1. pcap_dispatch(adhandle, 1, packet_handler, (u_char*)pParam);

  2. void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)

  3. {//...处理封包的代码...}

复制代码

代码中的 packet_handler 是回调函数,每当 pcap_dispatch 获取到一个符合过滤规则的封包后,就会自动调用packet_handler  来对封包中的数据进行处理,回调函数有三个参数,第一个参数可以用来给回调函数传递参数,比如告诉回调函数应该如何处理数据;第二个参数是 WinPcap 自动生成的关于这个数据包的一些基本信息,比如获取此封包的时间,封包长度等等;第三个参数就是原始的封包数据了,包含了从数据链路层到应用层的完整封包数据。
到此,使用 WinPcap 进行抓包的主要步骤就介绍完了。如果读者觉得无法很好的理解这部分内容,建议先去学习下 WinPcap技术手册,并动手编译调试一下 WinPcap 源码包中 Example 目录下的实例,以加深理解。


本文地址:IT问答频道 https://www.eeeoo.cn/itwenda/935163.html,嗨游网一个专业手游免费下载攻略知识分享平台,本站部分内容来自网络分享,不对内容负责,如有涉及到您的权益,请联系我们删除,谢谢!


IT问答
小编:小嗨整编
相关文章相关阅读
  • 绝地求生科技开挂防封(绝地求生科技软件免费)

    绝地求生科技开挂防封(绝地求生科技软件免费)

    绝地求生科技开挂防封(绝地求生科技软件免费)随着绝地求生游戏的火热,越来越多的玩家加入到了这场竞技盛宴中。然而,游戏中外挂现象也日益严重,许多玩家因此遭受不公平对待。本文将为大家介绍如何使用绝地求生科技开挂防封。一、科技开挂的优势1.提高游...

  • 仿ios备忘录怎么下载(仿ios备忘录软件推荐)?

    仿ios备忘录怎么下载(仿ios备忘录软件推荐)?

    仿ios备忘录怎么下载(仿ios备忘录软件推荐)?在数字化生活的今天,备忘录成为了我们管理日常生活和工作的得力助手。iOS系统的备忘录以其简洁的设计和实用的功能受到许多用户的喜爱。然而,对于安卓用户来说,是否也能够享受到iOS备忘录的便捷呢...

  • 免费追剧app软件无广告(免费追剧app推荐)

    免费追剧app软件无广告(免费追剧app推荐)

    免费追剧app软件无广告(免费追剧app推荐)下面带来一款追剧app,每天自动更新全网视频,无广告、无病毒、极速播放,不卡顿,永久免费,叫蛋播星球。蛋播星球还囊括了小说、音乐以及短剧等多种功能,让你的娱乐生活更加多姿多彩。此外,支持离线下载...

  • 视频格式转换软件有哪些(视频格式转换软件免费版)?

    视频格式转换软件有哪些(视频格式转换软件免费版)?

    视频格式转换软件有哪些(视频格式转换软件免费版)?随着科技的不断发展,人们对视频拍摄和观看的需求日益增长,视频格式转换软件也应运而生。本文将为大家介绍几款免费视频格式转换软件,帮助你轻松应对不同视频格式的转换需求。一、AnyVideoCon...

  • 电脑锁屏软件哪个好用(电脑锁屏软件有哪些)?

    电脑锁屏软件哪个好用(电脑锁屏软件有哪些)?

    电脑锁屏软件哪个好用(电脑锁屏软件有哪些)?一款好用的电脑锁屏软件就能派上大用场。本文将为您盘点目前市面上较为流行的电脑锁屏软件,并分析它们的优缺点,帮助您选择最适合自己的软件。一、电脑锁屏软件有哪些?1.Windows自带锁屏功能2.Sc...

  • 硬盘修复软件哪个好用(免费硬盘恢复软件哪个好)?

    硬盘修复软件哪个好用(免费硬盘恢复软件哪个好)?

    硬盘修复软件哪个好用(免费硬盘恢复软件哪个好)?硬盘作为电脑的重要组成部分,存储着我们的重要文件和数据。然而,由于各种原因,如误删除、格式化、分区丢失等,硬盘数据可能会丢失。这时,一款好用的硬盘修复软件就显得至关重要。本文将为您推荐几款免费...

  • ai画图软件免费(ai画图软件哪个好)?

    ai画图软件免费(ai画图软件哪个好)?

    ai画图软件免费(ai画图软件哪个好)?随着人工智能技术的不断发展,AI画图软件已经成为了许多绘画爱好者、设计师和艺术创作者的得力助手。这些软件不仅能够轻松生成高质量的图像,还极大地降低了创作门槛。本文将为您介绍几款免费的AI画图软件,帮助...

  • 进销存管理软件哪款好用(永久免费进销存软件推荐)?

    进销存管理软件哪款好用(永久免费进销存软件推荐)?

    进销存管理软件哪款好用(永久免费进销存软件推荐)?在当今信息化时代,进销存管理软件已成为企业提高运营效率、降低成本的重要工具。尤其是永久免费的进销存软件,更是受到许多中小企业的青睐。本文将为您推荐几款永久免费的进销存管理软件,并分析它们的特...

  • 周排行
  • 月排行
  • 年排行

精彩推荐