当前位置: 网站首页>>协议分析>>Winpcap>>

循序渐进学习使用WINPCAP(四)

时间:2006-10-16 来源:binaryluo的博客 作者:binaryluo 点击:
这一节中是用pcap_next_ex()来代替pcap_loop()来捕获数据包 这节的例子很象先前的一章(获得网卡的高级信息)但是这一节中是用pcap_next_ex()来代替pcap_loop()来捕 获数据包。基于回调包捕获机制的pcap_loop()在某些情况下是不错的选择。但是在一些情况下处理回调并不
  

这一节中是用pcap_next_ex()来代替pcap_loop()来捕获数据包

这节的例子很象先前的一章(获得网卡的高级信息)但是这一节中是用pcap_next_ex()来代替pcap_loop()来捕

获数据包。基于回调包捕获机制的pcap_loop()在某些情况下是不错的选择。但是在一些情况下处理回调并不特

别好:这会使程序变的复杂并且在象多线程或C++类这些情况下它看起来到象一块绊脚石。

在这些情况下pcap_next_ex()允许直接调用来接收包,它的参数和pcap_loop()相同:有一个网卡描述副,和两

个指针,这两个指针会被初始化并返回给用户,一个是pcap_pkthdr结构,另一个是接收数据的缓冲区。

下面的程序我门将循环调用前一节的例子中的回掉部分,只是把它移到了main里面了。



#include "pcap.h"


main()
{
  pcap_if_t *alldevs;
  pcap_if_t *d;
  int inum;
  int i=0;
  pcap_t *adhandle;
  int res;
  char errbuf[PCAP_ERRBUF_SIZE];
  struct tm *ltime;
  char timestr[16];
  struct pcap_pkthdr *header;
  u_char *pkt_data;
  
  
  /* Retrieve the device list */
  if (pcap_findalldevs(&alldevs, errbuf) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
    exit(1);
  }
  
  /* Print the 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;
  }
  
  /* Jump to the selected adapter */
  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;
  }
  
  printf("\nlistening on %s...\n", d->description);
  
  /* At this point, we don’t need any more the device list. Free it */
  pcap_freealldevs(alldevs);
  
  /* 此处循环调用 pcap_next_ex来接受数据报*/
  while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){
    
    if(res == 0)
        /* Timeout elapsed */
        continue;
    
    /* convert the timestamp to readable format */
    ltime=localtime(&header->ts.tv_sec);
    strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
    
    printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
  }
  
  if(res == -1){
    printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
    return -1;
  }
  
  return 0;
}


注:pcap_next_ex()只在Win32环境下才行因为它不是原始libpcap API中的一部分,这就意味着依赖于这个函

数的代码不会在UNIX下工作。那么为什么我们用pcap_next_ex()而不用pcap_next()?因为pcap_next()有许多

限制在很多情况下并不鼓励用它。首先它的效率很低因为它隐藏了回掉方法并且还依赖于pcap_dispatch()这个

函数。再次它不能够识别文件结束标志EOF所以对来自文件的数据流它几乎无能为力。
注意当pcap_next_ex()在成功,超时,出错和文件结束的情况下会返回不同的值。


 

------分隔线----------------------------
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
最新评论 查看所有评论
发表评论 查看所有评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
推荐内容
  • 如何编译WinPcap

    编译驱动 编译NPF时,有两个主要的路径:Windows NTx和Windows 9x。注意,因为NPF驱动...

  • winpcap 驱动简介

    winpcap(windowspacketcapture)是windows平台下一个免费,公共的网络访问系统。开发wi...

  • 命令行下装WinPcap

    WinPcap是个很常用的工具,但必须在窗口界面下安装。在网上也可以找到不用GUI的版本(...

  • WinPcap 教程

    原文出处:http://winpcap.polito.it/docs/man/html/index.html 作者: LorisDegioanni...