CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  网络编程

winpcap保存数据的问题

楼主chinajuanbob(chinajuanbob)2006-03-03 00:45:16 在 VC/MFC / 网络编程 提问

程序的子线程里调用winpcap函数。  
  我想问问怎么保存这许多的数据比较好?才接触winpcap,最好能给个具体的例子  
  谢啦~ 问题点数:40、回复次数:3Top

1 楼oyljerry(【勇敢的心】→ ㊣提拉米苏√㊣)回复于 2006-03-03 10:27:14 得分 0

可以保存到文本文档等Top

2 楼findheart(findheart)回复于 2006-03-06 15:41:04 得分 0

转贴  
  ————————————————————————  
  循序渐进学习使用WINPCAP(七)  
   
  通过以前的学习我门已经熟悉了从网卡上捕获数据包,现在我门将学习如何处理数据包。WINPCAP为我们提供了很多API来将流经网络的数据包保存到一个堆文件并读取堆的内容。这一节将讲述如何使用所有的这些API。  
  这种文件的格式很简单,但包含了所捕获的数据报的二进制内容,这种文件格式也是很多网络工具的标准如WinDump,   Ethereal   还有   Snort等.  
   
   
  关于如何将数据包保存到文件:  
   
  首先我们看看如何以LIBPCAP的格式写数据包。  
  下面的例子演示了如何从指定的接口上捕获数据包并将它们存储到一个指定的文件。  
   
   
  #include   "pcap.h"  
   
  /*   定义处理数据的函数原形   */  
  void   packet_handler(u_char   *param,   const   struct   pcap_pkthdr   *header,   const   u_char   *pkt_data);  
   
  main(int   argc,   char   **argv)  
  {  
  pcap_if_t   *alldevs;  
  pcap_if_t   *d;  
  int   inum;  
  int   i=0;  
  pcap_t   *adhandle;//定义文件句柄  
  char   errbuf[PCAP_ERRBUF_SIZE];  
  pcap_dumper_t   *dumpfile;  
   
   
   
  /*   检查命令行参数   是否带有文件名*/  
  if(argc   !=   2){  
   
      printf("usage:   %s   filename",   argv[0]);  
      return   -1;  
   
  }  
   
  /*   获得驱动列表   */  
  if   (pcap_findalldevs(&alldevs,   errbuf)   ==   -1)  
  {  
      fprintf(stderr,"Error   in   pcap_findalldevs:   %s\n",   errbuf);  
      exit(1);  
  }  
   
  /*   打印   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;  
  }  
       
  /*   跳转到指定的网卡   */  
  for(d=alldevs,   i=0;   i<   inum-1   ;d=d->next,   i++);  
   
  /*   Open   the   adapter   */  
  if   (   (adhandle   =   pcap_open_live(d->name,   //   name   of   the   device  
                          65536,       //   portion   of   the   packet   to   capture.    
                                  //   65536   grants   that   the   whole   packet   will   be   captured   on   all   the   MACs.  
                          1,           //   promiscuous   mode  
                          1000,       //   read   timeout  
                          errbuf       //   error   buffer  
                          )   )   ==   NULL)  
  {  
      fprintf(stderr,"\nUnable   to   open   the   adapter.   %s   is   not   supported   by   WinPcap\n");  
      /*   Free   the   device   list   */  
      pcap_freealldevs(alldevs);  
      return   -1;  
  }  
   
  /*   打开文件   */  
  dumpfile   =   pcap_dump_open(adhandle,   argv[1]);  
  if(dumpfile==NULL){  
      fprintf(stderr,"\nError   opening   output   file\n");  
      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);  
   
  /*   循环捕获数据并调用packet_handler函数把数据存储到堆文件   */  
  pcap_loop(adhandle,   0,   packet_handler,   (unsigned   char   *)dumpfile);  
   
  return   0;  
  }  
   
  /*   Callback   function   invoked   by   libpcap   for   every   incoming   packet   */  
   
  void   packet_handler(u_char   *dumpfile,   const   struct   pcap_pkthdr   *header,   const   u_char   *pkt_data)  
  {  
  /*   此函数功能将数据报存储到堆文件   */  
  pcap_dump(dumpfile,   header,   pkt_data);  
  }  
   
  正如你看到的那样该程序的结构非常类似与以前的例子,区别是:  
  一旦打开网卡就调用pcap_dump_open()来打开一个文件,该调用将文件和某个网卡相关联。  
  packet_handler()内部通过调用pcap_dump()来将捕获的数据报存储到文件。pcap_dump()的参数和   packet_handler()一样,所以用起来比较方便。  
   
  从文件读数据包:  
   
  下面我们来看如何从文件读取数据内容。下面的代码打开了   一个堆文件并打印了其中的每个包内容。  
  pcap_open_offline()用来打开一个堆文件,之后用pcap_loop()来循环从文件中读取数据。你能发现读取脱机的数据几乎和实时的从网卡上读取一摸一样。  
   
   
   
  #include   <stdio.h>  
  #include   <pcap.h>  
   
  #define   LINE_LEN   16  
   
  void   dispatcher_handler(u_char   *,   const   struct   pcap_pkthdr   *,   const   u_char   *);  
   
  main(int   argc,   char   **argv)   {  
   
  pcap_t   *fp;  
  char   errbuf[PCAP_ERRBUF_SIZE];  
   
   
  if(argc   !=   2){  
   
      printf("usage:   %s   filename",   argv[0]);  
      return   -1;  
   
  }  
   
  /*   打开一个存储有数据的堆文件   */  
  if   (   (fp   =   pcap_open_offline(argv[1],   errbuf)   )   ==   NULL)  
  {  
      fprintf(stderr,"\nError   opening   dump   file\n");  
      return   -1;  
  }  
   
  //   读取数据直到遇到   EOF标志。    
  pcap_loop(fp,   0,   dispatcher_handler,   NULL);  
   
  return   0;  
  }  
   
   
   
  void   dispatcher_handler(u_char   *temp1,    
                      const   struct   pcap_pkthdr   *header,   const   u_char   *pkt_data)  
  {  
  u_int   i=0;  
   
  /*   print   pkt   timestamp   and   pkt   len   */  
  printf("%ld:%ld   (%ld)\n",   header->ts.tv_sec,   header->ts.tv_usec,   header->len);            
   
  /*   Print   the   packet   */  
  for   (i=1;   (i   <   header->caplen   +   1   )   ;   i++)  
  {  
      printf("%.2x   ",   pkt_data[i-1]);  
      if   (   (i   %   LINE_LEN)   ==   0)   printf("\n");  
  }  
   
  printf("\n\n");        
   
  }  
   
   
  下面的代码具有一样的作用,只不过是用pcap_next_ex()来代替pcap_loop()循环读取数据而已。  
   
   
   
   
  #include   <stdio.h>  
  #include   <pcap.h>  
   
  #define   LINE_LEN   16  
   
  main(int   argc,   char   **argv)   {  
   
  pcap_t   *fp;  
  char   errbuf[PCAP_ERRBUF_SIZE];  
  struct   pcap_pkthdr   *header;  
  u_char   *pkt_data;  
  u_int   i=0;  
  int   res;  
   
  if(argc   !=   2){  
   
      printf("usage:   %s   filename",   argv[0]);  
      return   -1;  
   
  }  
   
  /*   Open   a   capture   file   */  
  if   (   (fp   =   pcap_open_offline(argv[1],   errbuf)   )   ==   NULL)  
  {  
      fprintf(stderr,"\nError   opening   dump   file\n");  
      return   -1;  
  }  
   
  /*   Retrieve   the   packets   from   the   file   */  
  while((res   =   pcap_next_ex(   fp,   &header,   &pkt_data))   >=   0){  
      /*   print   pkt   timestamp   and   pkt   len   */  
      printf("%ld:%ld   (%ld)\n",   header->ts.tv_sec,   header->ts.tv_usec,   header->len);            
       
      /*   Print   the   packet   */  
      for   (i=1;   (i   <   header->caplen   +   1   )   ;   i++)  
      {  
          printf("%.2x   ",   pkt_data[i-1]);  
          if   (   (i   %   LINE_LEN)   ==   0)   printf("\n");  
      }  
       
      printf("\n\n");        
  }  
   
   
  if(res   ==   -1){  
      printf("Error   reading   the   packets:   %s\n",   pcap_geterr(fp));  
  }  
   
  return   0;  
  }  
   
   
   
  用pcap_live_dump将数据写到文件:  
  WinPcap   的最新版本提供了一个进一步的方法来将数据包存储到磁盘,就是使用pcap_live_dump()函数。他需要三个参数:一个文件名,和一个该文件允许的最大长度还有一个参数是该文件所允许的最大包的数量。对这些参数来说   0   意味着没有最大限制。注:我们可以在调用pcap_live_dump()前设置一个过滤器来定义哪些数据报需要存储。  
   
  pcap_live_dump()   是非阻塞的,所以他会立刻返回:数据的存储过程将会异步的进行,直到文件到达了指定的最大长度或最大数据报的数目为止。  
  应用程序能够用pcap_live_dump_ended()来等检查是否数据存储完毕,如果你指定的最大长度参数和数据报数量为0,那么该操作将永远阻塞。  
   
  pcap_live_dump()   和   pcap_dump()的不同从设置的最大极限来说就是性能的问题。pcap_live_dump()采用WinPcap   NPF驱动来从内核级的层次上向文件中写数据,从而使内存拷贝最小化。  
  显然,这些特点当前在其他的操作系统下是不能够实现的,pcap_live_dump()是WinPcap所特有的,而且只能够应用于Win32环境.  
   
  Top

3 楼arthurkingios(吾将上下而求索)回复于 2006-03-13 22:29:46 得分 0

碰巧最近也做过一个类似于Ethereal的网络数据包嗅探器。  
   
  在用子进程进行抓包时,我的做法是用一块new出来的内存进行临时存储。  
   
  在用户对截获的数据包进行筛选(比如按照协议类型、目标地址等)后再保存为文件,这样应该灵活性更好吧。Top

相关问题

  • 数据保存
  • ADOQuery数据保存
  • 数据保存不成功
  • 数据保存问题
  • MSHFlexGrid数据的保存
  • 保存数据的问题
  • to Latitude:数据保存问题
  • 数据保存的问题
  • TTreeView 怎样保存数据?
  • datagrid数据的保存

关键词

  • 文件
  • 数据
  • 函数
  • live
  • pcap
  • 数据包
  • winpcap
  • errbuf
  • pkt
  • dump

得分解答快速导航

  • 帖主:chinajuanbob

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo