设 为 首 页
加 入 收 藏
联 系 我 们
推荐栏目 | Sniffer | Ethereal | IPV6 | IPTV | MPLS | TCP/IP | SNMP | WLAN | 中文RFC文档 | 编码交流 |
   

您现在的位置: 首页>>协议分析>>协议分析技术>>Winpcap>>正文


循序渐进学习使用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()来循环从文件中读取数据。你能发现读取脱机的数据几乎和实时的从网卡上读取一摸一样。

本新闻共2页,当前在第1页  1  2  

 


版权所有 中国协议分析网 联系信箱:wayky#126.com(请把"#"改成"@")
Copyright (C) www.Cnpaf.Net 2004-2008  All Rights Reserved. [京ICP备05002225号]