当前位置:   article > 正文

WinPcap编程_基于winpcap编程,实现一个手动发送tcp报文的小程序

基于winpcap编程,实现一个手动发送tcp报文的小程序

WinPcap编程

WinPcap是一个开源的、运行于Win32平台下的体系结构,它的主要功能是进行数据包捕获和网络分析。它允许应用程序通过协议栈捕获和传输网络数据包,也包括内核级别的数据包过滤、网络静态引擎和支持远程数据包捕获等有用的功能。

WinPcap由两部分组成:

1.         驱动程序: 扩展操作系统功能提供低层次的网络访问

2.         动态链接库:运行在Win32平台上的应用程序可以非常方便地访问网络低层次的数据。

Ethereal是大名鼎鼎的捕获数据包专业软件,它的运行是在WinPcap的支持之下的,如果没有安装WinPcapEthereal也无法正常捕获数据包。

在正式WinPcap编程之前,要配置运行环境。

Win32 平台下WinPcap应用程序需要以下四个动态链接库才能正常运行:

wpcap.dll

Packet.dll

WanPacket.dll

pthreadVC.dll

这四个动态链接库在WinPcap驱动程序里。

如果没有这个驱动程序,需要到WinPcap官方网站上下载,下载地址为:www.WinPcap.org

如果应用程序出现一下提示,那就是没有安装驱动程序的原因了。

 

被过滤广告

也可以不安装WinPcap驱动程序。但是需要把上面提到的四个动态链接库文件拷贝到系统分区/WINDOWS/system32目录下

或者

接下来配置编程环境。

如果一个源文件使用了WinPcap提供的库函数,那么就需要在该文件开始的位置添加pcap.h包含文件(或者在引用的文件中),即#include pcap.h

也许会出现下面的错误:

fatal error C1083: 无法打开包括文件:pcap.h: No such file or directory

这个错误表明找不到pcap.h文件

这个头文件在驱动程序安装完成后也是没有的,它是开发包里面的一个头文件

所以,如果要运行程序还需要到官方网站上去下载WinPcap SDKWpdPack

WinPcap SDk里面包含库文件,头文件,文档文件和一些例子。

解压缩后把Include目录添加到IDE的包含文件中(VC6.0 Tools->Option->Directory; VS 2003/2005 工具->选项->项目和解决方案/项目->VC++目录)

error LNK2019: 无法解析的外部符号_pcap_findalldevs_ex,该符号在函数XXX 中被引用

如果发生上面的错误就表明缺少库文件,需要添加wpcap.lib到工程中(VC6.0 Project->Settings->Link->Object/library modules; VS 2003/2005 项目->添加现有项->所有文件)

error C2065: PCAP_SRC_IF_STRING: 未声明的标识符

error C3861: pcap_findalldevs_ex: 找不到标识符

error C2065: PCAP_OPENFLAG_PROMISCUOUS: 未声明的标识符

error C3861: pcap_open: 找不到标识符

新的版本里WinPcap支持远程数据包获取,发生上面的错误很有可能是新的版本导致不兼容的问题,所以还应当添加一个头文件remote-ext.h ,即

#include "remote-ext.h"

如果还有问题,可以到WinPcaP官方网站上找FAQ

一般情况下应该没有问题了。接下来,开始动手做抓包分析吧。

 

 

Winpcap简介

一.Winpcap简介

 

WinpcapUNIX下的libpcap移植到windows下的产物,他是一个free and open source的项目。Winpcap工作于驱动(Driver)层,所以能以很高的效率进行网络操作。

 

Winpcap提供了以下强大的功能:

 

1.捕获原始的数据包

 

2.设置filter,只捕获自己敢兴趣的数据包

 

3.方便的把捕获的数据包输出到文件和从文件输入

 

4.发送原始的数据包

 

5.统计网络流量

 

6.…..(其它还有很多,我不知道了)

 

 

 

二.Winpcap的安装使用方法

 

1.到http://winpcap.polito.it下载winpcap的安装包,程序员开发包。

 

2.执行安装包,这样你的机子就能运行winpcap程序了

 

3.解压开发包,在VCoptionincludelib中加入winpcap

 

includelib

 

4. 在你的程序中加入#include <pcap.h>, #include <remote-ext.h>.然后在工程的setting中加入预定义宏:WPCAP,HAVE_REMOTE.导入wpcap.lib

 

5.就可以编写wpcap程序了

 

 

 

三.Winpcap的一些基本的功能的实现

 

一)捕获数据包

 

1. 枚举所有的可用的设备[pcap_findalldevs_ex](可选)

 

2. 通过名字打开一个设备[pcap_open()]

 

在这里可以打开一个文件,只是在打开这个文件之前需要通过pcap_createsrcstr创建相应的name string

 

3. 设置Filter[pcap_compile, pcap_setfilter] (可选)

 

4. 捕获数据

 

有几种捕获数据的方法(捕获数据的数据都是最原始的数据包,即包含数据链路层的数据头)

 

a.是以回调的方式[ pcap_loop,pcap_dispatch() ].

 

这两种方法基本相同,底层收集数据包,当满足一定的条件(timeout 或者缓冲区满),就会调用回调函数,把收集到的原始数据包s,交给用户。他们返回的数据缓冲区包含多个包

 

b. pcap_next_ex()的方式

 

每当一个包到到达以后,pcap_next_ex就会返回,返回的数据缓冲区里只包涵一个包。

 

 

 

二)发送包

 

Winpcap中有发送单个包和发送多个包的方法。这里只说说发送单个包

 

1.通过名字打开一个设备[pcap_open]

 

2.自己构造一个原始数据包(这个数据包会不经过任何处理就发送出去,所以必须把包中的各个字段设置好。另外这个数据包是包含数据链路层报头的)

 

3.使用pcap_sendpacket()发送数据包

 

 

 

三)统计网络流量

 

1. 通过名字打开一个设备[pcap_open]

 

通过 read_timeout来设置统计的时间间隔

 

2. 设置filter[pcap_compile, pcap_setfilter] (可选)

 

3. 设置设备的为统计模式[ pcap_setmode(MODE_STAT);]

 

4. 开始统计,pcap_loop/pcap_dispatch()

 

5.在回调函数中的参数中就包含了统计信息,如下图:

 

  winpcap的一些认识

一.Winpcap简介

 

      WinpcapUNIX下的libpcap移植到windows下的产物,他是一个freeandopensource的项目。Winpcap工作于驱动(Driver)层,所以能以很高的效率进行网络操作。

 

      Winpcap提供了以下强大的功能:

 

1.捕获原始的数据包

 

2.设置filter,只捕获自己敢兴趣的数据包

 

3.方便的把捕获的数据包输出到文件和从文件输入

 

4.发送原始的数据包

 

5.统计网络流量

 

6.…..(其它还有很多,我不知道了)

 

 

 

二.Winpcap的安装使用方法

 

      1.到http://winpcap.polito.it下载winpcap的安装包,程序员开发包。

 

    2.执行安装包,这样你的机子就能运行winpcap程序了

 

    3.解压开发包,在VCoptionincludelib中加入winpcap

 

includelib

 

4.在你的程序中加入#include<pcap.h>,#include<remote-ext.h>.然后在工程的setting中加入预定义宏:WPCAP,HAVE_REMOTE.导入wpcap.lib

 

    5.就可以编写wpcap程序了

 

三.Winpcap的一些基本的功能的实现

 

    一)捕获数据包

             1.   枚举所有的可用的设备[pcap_findalldevs_ex](可选)

             2.   通过名字打开一个设备[pcap_open()]

在这里可以打开一个文件,只是在打开这个文件之前需要通过pcap_createsrcstr创建相应的namestring

3.       设置Filter[pcap_compile,pcap_setfilter](可选)

4.       捕获数据

有几种捕获数据的方法(捕获数据的数据都是最原始的数据包,即包含数据链路层的数据头)

 

a.是以回调的方式[pcap_loop,pcap_dispatch()].

这两种方法基本相同,底层收集数据包,当满足一定的条件(timeout或者缓冲区满),就会调用回调函数,把收集到的原始数据包s,交给用户。他们返回的数据缓冲区包含多个包

 

b.    pcap_next_ex()的方式

每当一个包到到达以后,pcap_next_ex就会返回,返回的数据缓冲区里只包涵一个包。

 

      二)发送包

             Winpcap中有发送单个包和发送多个包的方法。这里只说说发送单个包

 

1.通过名字打开一个设备[pcap_open]

 

2.自己构造一个原始数据包(这个数据包会不经过任何处理就发送出去,所以必须把包中的各个字段设置好。另外这个数据包是包含数据链路层报头的)

 

3.使用pcap_sendpacket()发送数据包

 

三)统计网络流量

 

1.通过名字打开一个设备[pcap_open]

    通过 read_timeout来设置统计的时间间隔

 

2.设置filter[pcap_compile,pcap_setfilter](可选)

3. 设置设备的为统计模式[pcap_setmode(MODE_STAT);]

4. 开始统计,pcap_loop/pcap_dispatch()

5.在回调函数中的参数中就包含了统计信息,如下图:

 

.总结

 

这些东西都是我在学习winpcap的过程中的一些经验和总结。由于我学习winpcap的时间很匆忙,只是按照stepbystepguide来学习的,所以我对于winpcap的理解也就只能局限与此,希望能在以后有机会深入学习

 

 

 

/

//下面是一个应用winpcap写的一个网络流量统计的例子,

 

//nettraffic.cppefinestheentrypointfortheconsoleapplication.

//

#include"stdafx.h"

#include<pcap.h>

#include<remote-ext.h>

#include<iostream>

#include<winsock2.h>

 

usingnamespacestd;

//------------------------------------------------------------------------

//------------------------------------------------------------------------

Void dispatcher_handler(u_char*user_data,conststructpcap_pkthdr*pkthdr,constu_char*pktdata);

 

//------------------------------------------------------------------------

 

Int main(intargc,char*argv[])

{

      int                                      i;

      pcap_if_t*                         alldevs;

      pcap_if_t*                         dev;

      char                            errorbuf[PCAP_ERRBUF_SIZE];

      int                                      choice;

      pcap_t*                             stathandle;

      WSADATA                             wsadata;

      structtimeval              timestamp;

      if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)

      {

             cerr<<"WSAStartupfailed["<<WSAGetLastError()<<"]"<<endl;

             return(-1);

      }     

      //enumalldevice

      if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errorbuf)==-1)

      {

             WSACleanup();

             cerr<<"pcap_findalldevs_exfailed!("<<errorbuf<<""<<endl;

             return(-1);

      }

      for(i=0,dev=alldevs;dev!=NULL;dev=dev->next)

      {

             cout<<++i<<'\t'<<dev->name<<endl;

      }

      if(i==0)

      {

             WSACleanup();

             cerr<<"nodevicefound!"<<endl;

             return(-2);

      }

      //letuserchoice

      while(1)

      {

             cout<<"pleasechoiceadevice:";

             cin>>choice;

             if(choice>=1&& choice<=i)

                    break;

             cerr<<"inputerror,youshallchoiceadevicefromuponlist"<<endl;

      }

      //movetothechoicedevice

      for(i=0,dev=alldevs;i<choice-1;i++,dev=dev->next);

      if((stathandle=pcap_open(dev->name,100,                                                       PCAP_OPENFLAG_PROMISCUOUS,500, NULL,errorbuf))==NULL)

      {

             cerr<<"opendevicefailed![device:"<<dev->name<<"]"<<errorbuf<<endl;

             pcap_freealldevs(alldevs);

             WSACleanup();

             return(-3);

      }

      cout<<"isStat"<<dev->name<<"..."<<endl;

      pcap_freealldevs(alldevs);

      pcap_setmode(stathandle,MODE_STAT);

      timestamp.tv_sec=0;

      timestamp.tv_usec=0;

      pcap_loop(stathandle,0,dispatcher_handler,(unsignedchar*)&timestamp);

      pcap_close(stathandle);

      return0;

 

}

//------------------------------------------------------------------------

 

voiddispatcher_handler(u_char*user_data,conststructpcap_pkthdr*pkthdr,constu_char*pktdata)

{

      staticstructtimeval      tstamp=*((structtimeval*)user_data);

      LARGE_INTEGER                 Bps,Pps;

      unsignedlong              delay;

      char                            strtime[32];

      delay=(pkthdr->ts.tv_sec-tstamp.tv_sec)*1000000-tstamp.tv_usec+pkthdr->ts.tv_usec;

      Pps.QuadPart=((*(LONGLONG*)(pktdata))*1000000)/delay;

      Bps.QuadPart=((*(LONGLONG*)(pktdata+8))*1000000)/delay;

      structtm*ltime=localtime(&(pkthdr->ts.tv_sec));

      strftime(strtime,sizeof(strtime),"%H:%M:%S",ltime);     

      printf("%s:",strtime);

      printf("\tPps=%I64u\tBps=%I64u\r\n",Pps.QuadPart,Bps.QuadPart);

      tstamp=pkthdr->ts;

 

 

要将wpcap.lib拷贝到(VS安装目录)VC\lib目录下

 

 

首先要下载一个WinPcap4.0.1 ,将其安装至电脑。
Microsoft Visual C++ 创建一个使用 wpcap.dll 的应用程序,需要按一下步骤: 
 
在每一个使用了库的源程序中,将 pcap.h 头文件包含(include)进来。 
如果你在程序中使用了WinPcap中提供给Win32平台的特有的函数, 记得在预处理中加入WPCAP 的定义。 
如果你的程序使用了WinPcap的远程捕获功能,那么在预处理定义中加入HAVE_REMOTE。不要直接把remote-ext.h直接加入到你的源文件中去。 
设置VC++的链接器(Linker),把wpcap.lib库文件包含进来。wpcap.lib可以在WinPcap中找到。 
设置VC++的链接器(Linker),把ws2_32.lib库文件包含进来。这个文件分布于C的编译器,并且包含了Windows的一些socket函数。本教程中的一些范例程序,会需要它。 
记住以下几点:
 
要添加一个预处理定义,你需要打开Project菜单,选择Settings,然后选择C/C++选项卡,在General类下,你必须在Preprocessor Definitions下的文本框中添加定义。 
要在一个VC++6.0工程中,添加一,个新的库,你必须打开Project菜单,选择Settings,然后选择Link选项卡,然后把新库的名字添加到Object/Library modules下的文本框中 
要向VC++6.0中添加一个新的库所在的路径,你必须打开Tool菜单,选择Options,然后选择Directories选项卡,在Show directories下拉框中选择Library files,并且将新的路径添加到Directories中去 
要向VC++6.0中添加一个新的包含文件所在的路径,你必须打开Tool菜单,选择Options,然后选择Directories选项卡,在Show directories下拉框中选择Include files,并且将新的路径添加到Directories中去 。
 

 

 

 

  WINPCAP编程环境设置

一、WINPCAP编程环境设置

在正式WinPcap编程之前,要配置运行环境。

1、运行环境设置

Win32 平台下WinPcap应用程序需要以下四个动态链接库才能正常运行:wpcap.dll Packet.dll WanPacket.dll pthreadVC.dll

这四个动态链接库在WinPcap驱动程序里。

如果没有这个驱动程序,需要到WinPcap官方网站上下载,下载地址为:www.WinPcap.org

如果应用程序出现一下提示,那就是没有安装驱动程序的原因了。

也可以不安装WinPcap驱动程序。但是需要把上面提到的四个动态链接库文件拷贝到系统分区/WINDOWS/system32目录下。(似乎有些问题)

 

 

2、配置编程环境。

1> WWW.WINPCAP.ORG上下载WINPCAP SDK -WpdPackWinPcap SDk里面包含库文件,头文件,文档文件和一些例子。解压到一个指定的目录。解压缩后把Include目录添加到IDE的包含文件中(VC6.0 Tools->Option->Directory; VS 2003/2005 工具->选项->项目和解决方案/项目->VC++目录); lib目录添加为新的库文件目录(VC6.0 Tools->Option->Directory; VS 2003/2005 工具->选项->项目和解决方案/项目->VC++目录)如下图所示。

 

2> 如果一个源文件使用了WinPcap提供的库函数,那么就需要在该文件开始的位置添加pcap.h包含文件(或者在引用的文件中),即#include pcap.h

也许会出现下面的错误:

fatal error C1083: 无法打开包括文件:pcap.h: No such file or directory

这个错误表明找不到pcap.h文件,这个头文件在驱动程序安装完成后也是没有的,它是开发包里面的一个头文件,所以,如果要运行程序还需要到官方网站上去下载WinPcap SDK,并按步骤1添加到项目中。

 

3> 在程序中添加wpcap.lib。如果出现下面错误

error LNK2019: 无法解析的外部符号_pcap_findalldevs_ex,该符号在函数XXX 中被引用,如果发生上面的错误就表明缺少库文件,需要添加wpcap.lib到工程中(VC6.0 Project->Settings->Link->Object/library modules; VS 2003/2005 项目->添加现有项->所有文件)如下图所示:

 

4> 新的版本里WinPcap支持远程数据包获取,所以还应当添加一个头文件remote-ext.h ,即#include "remote-ext.h"(记住这条语句要放在#include pcap.h”之后,否则会出错!)

否则会发生下面的错误

error C2065: PCAP_SRC_IF_STRING: 未声明的标识符

error C3861: pcap_findalldevs_ex: 找不到标识符

error C2065: PCAP_OPENFLAG_PROMISCUOUS: 未声明的标识符

error C3861: pcap_open: 找不到标识符

 

5> 或者不用添加#include "remote-ext.h".VC.NET提供的IDE环境中,可以通过执行“项目”菜单中的的“属性”进入该项目的属性配置页,通过选择“配置属性”树中的“C/C++预处理哭”选项就增加’WPCAP’和’HAVE_REMOTE’两个标号。如下图所示:

 

6> 如果还有问题,可以到WinPcaP官方网站上找FAQ

 

二、WINPCAP编程入门

利用WINPCAP捕获数据包一般要经过以下几个步骤

1、获取网络接口列表

通常, 一个基于WinPcap的应用程序所要做的第一件事, 就是获得适合的网络接口的列表.pcap_findalldevs()(或者pcap_findalldevs_ex())函数就是干这活的: 这个函数返回一个pcap_if结构的列表, 每个元素都记录了一个接口的信息. 其中, namedescription以人类可以阅读的形式, 记录了设备的信息.

2、获取设备的高级信息

WinPcap 也可以为我们提供关于接口的更多信息. pcap_findalldevs() 函数返回的 pcap_if 结构也包含了一个 pcap_addr 结构的列表, 它记录了以下信息:

1. 接口的地址列表

2. 接口的掩码列表 (与地址列表一一对应)

3. 接口的广播地址列表 (与地址列表一一对应)

4. 目标地址列表 (与地址列表一一对应)

3、打开一个接口并捕捉流量

现在我们已经知道如何获取一个接口的有关信息了, 我们可以来点真家伙了 -- 打开一个接口并捕捉流量. 接下来我们会编译一个程序, 它将捕捉网络中所有的数据包并输出他们的一些相关信息。我们使用函数 pcap_open_live() 来打开一个捕捉设备. 这里, 我们需要解释一下 snaplen, promisc to_ms 参数.

函数原型: pcap_t * pcap_open_live (char *device, int snaplen, int promisc, int to_ms, char *ebuf)

"snaplen" 参数指定了要捕捉的数据包的部分. 在某些操作系统中 ( xBSD Win32), 驱动程序提供了只捕捉每个数据包其中一部分的可能性: 这样就降低了要处理的数据的量, 从而提高了捕捉程序的效率. 在例子中, 我们使用一个高出 MTU 最大值的值 (65536) 以确保可以捕捉到成个数据包.

"promisc" =1表明接口将会被设置为混杂模式. 一般情况下, 接口只处理目标地址为自己的数据; 到其他主机的数据包将会被忽略. 然而当一个接口处于混杂模式时, 它将会处理全部的流量: 也就是说, 在共享媒介, 例如非交换型以太网 (比如基于集线器的网络 ), WinPcap 可以捕捉到所有主机的数据包. 混在模式是多数捕捉程序的默认模式, 所以我们在例子中也采用这种模式.

"to_ms" 用以设置超时, 单位是毫秒. 一个从接口读取 ( Y- 捕捉) 的操作, (例如 pcap_dispatch() 或者 pcap_next_ex()), 如果没有捕捉到数据包, 那么在超过指定的时间以后就会返回. 进一步说, 如果接口处在静态模式中, to_ms 也定义了静态报告的间隔时间 (参阅 "Gathering Statistics on the network traffic " 以获取更多信息). 设置 to_ms 0, 则说明永远不会超时, 如果没有数据包到达, 那么捕捉操作将会永远不会返回, 而将其值设置为 -1 则会立刻返回.

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/eaglewood2005/archive/2009/09/19/4567674.aspx

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号