Chinaunix首页 | 论坛 | 博客
  • 博客访问: 618535
  • 博文数量: 178
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 2162
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-12 20:06
文章分类

全部博文(178)

文章存档

2011年(1)

2010年(94)

2009年(86)

我的朋友

分类:

2009-12-09 10:55:42

关于winpcap的一些认识
   Bill yuan
   2004-9-29
  一.Winpcap简介
   Winpcap是UNIX下的libpcap移植到windows下的产物,他是一个free and open source的项目。Winpcap工作于驱动(Driver)层,所以能以很高的效率进行网络操作。
   Winpcap提供了以下强大的功能:
  1.捕获原始的数据包
  2.设置filter,只捕获自己敢兴趣的数据包
  3.方便的把捕获的数据包输出到文件和从文件输入
  4.发送原始的数据包
  5.统计网络流量
  6.…..(其它还有很多,我不知道了)
  二.Winpcap的安装使用方法
   1.到下载winpcap的安装包,程序员开发包。
   2.执行安装包,这样你的机子就能运行winpcap程序了
   3.解压开发包,在VC的option的include和lib中加入winpcap的
  include和lib
  4. 在你的程序中加入#include , #include .然后在工程的setting中加入预定义宏:WPCAP,HAVE_REMOTE.导入wpcap.lib库
   5.就可以编写wpcap程序了
  三.Winpcap的一些基本的功能的实现
   一)捕获数据包
   1. 枚举所有的可用的设备[pcap_findalldevs_ex](可选)
   2. 通过名字打开一个设备[pcap_open()]
  在这里可以打开一个文件,只是在打开这个文件之前需要通过创建相应的name string
  3. 设置Filter[, ] (可选)
  4. 捕获数据
  有几种捕获数据的方法(捕获数据的数据都是最原始的数据包,即包含数据链路层的数据头)
  a. 是以回调的方式[ , ].
  这两种方法基本相同,底层收集数据包,当满足一定的条件(timeout 或者缓冲区满),就会调用回调函数,把收集到的原始数据包s,交给用户。他们返回的数据缓冲区包含多个包
  b. 的方式
  每当一个包到到达以后,pcap_next_ex就会返回,返回的数据缓冲区里只包涵一个包。
   二)发送包
   Winpcap中有发送单个包和发送多个包的方法。这里只说说发送单个包
  1. 通过名字打开一个设备[pcap_open]
  2. 自己构造一个原始数据包(这个数据包会不经过任何处理就发送出去,所以必须把包中的各个字段设置好。另外这个数据包是包含数据链路层报头的)
  3. 使用发送数据包
  三)统计网络流量
  1. 通过名字打开一个设备[pcap_open]
   通过 read_timeout来设置统计的时间间隔
  2. 设置filter[, ] (可选)
  3. 设置设备的为统计模式[ pcap_setmode(MODE_STAT);]
  4. 开始统计,pcap_loop/pcap_dispatch()
  5.在回调函数中的参数中就包含了统计信息,如下图:
  
  

  
  
  四. 总结
  这些东西都是我在学习winpcap的过程中的一些经验和总结。由于我学习winpcap的时间很匆忙,只是按照step by step guide来学习的,所以我对于winpcap的理解也就只能局限与此,希望能在以后有机会深入学习
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //下面是一个应用winpcap写的一个网络流量统计的例子,
  // nettraffic.cpp : Defines the entry point for the console application.
  //
  #include "stdafx.h"
  #include
  #include
  #include
  #include
  using namespace std;
  //------------------------------------------------------------------------
  //------------------------------------------------------------------------
  void dispatcher_handler(u_char* user_data, const struct pcap_pkthdr * pkthdr, const u_char *pktdata);
  //------------------------------------------------------------------------
  int main(int argc, char* argv[])
  {
   int i;
   pcap_if_t* alldevs;
   pcap_if_t* dev;
   char errorbuf[PCAP_ERRBUF_SIZE];
   int choice;
   pcap_t* stathandle;
   WSADATA wsadata;
   struct timeval timestamp;
  
   if( WSAStartup( MAKEWORD(2,2), &wsadata) != 0 )
   {
   cerr<<"WSAStartup failed [ "<   return (-1);
   }
  
   //enum all device
   if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &alldevs, errorbuf ) == -1 )
   {
   WSACleanup();
   cerr<<"pcap_findalldevs_ex failed! ("<   return (-1);
   }
  
   for( i=0,dev = alldevs; dev != NULL; dev = dev->next )
   {
   cout<<++i<<'\t'<name<   }
  
   if( i== 0 )
   {
   WSACleanup();
   cerr<<"no device found!"<   return (-2);
   }
  
   //let user choice
   while( 1)
   {
   cout<<"please choice a device:";
   cin>>choice;
   if( choice >= 1 && choice <=i )
  
  break;
  
   cerr<<"input error, you shall choice a device from upon list"<   }
  
   //move to the choice device
   for( i=0, dev = alldevs; inext );
   if( (stathandle = pcap_open( dev->name,
   100,
   PCAP_OPENFLAG_PROMISCUOUS,
   500,
   NULL, errorbuf ) ) == NULL )
   {
   cerr<<"open device failed! [device:"<name<<"] "
   <  
   pcap_freealldevs( alldevs );
   WSACleanup();
   return (-3);
   }
  
   cout<<"is Stat "<name<<" ..."<   pcap_freealldevs( alldevs );
  
   pcap_setmode( stathandle, MODE_STAT );
   timestamp.tv_sec = 0;
   timestamp.tv_usec = 0;
   pcap_loop( stathandle, 0, dispatcher_handler,(unsigned char*)×tamp );
   pcap_close( stathandle );
   return 0;
  }
  //------------------------------------------------------------------------
  void dispatcher_handler(u_char* user_data, const struct pcap_pkthdr * pkthdr, const u_char *pktdata)
  {
   static struct timeval tstamp = *( (struct timeval*)user_data );
   LARGE_INTEGER Bps,Pps;
   unsigned long 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;
   struct tm* 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;
  }
阅读(1059) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~