| « | November 2025 | » |  | 日 | 一 | 二 | 三 | 四 | 五 | 六 |   |  |  |  |  |  | 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |  |  |  |  |  |  |  |  
  |    登录 |  
| 
 |    联系我 email: binaryluo(at)gmail.com
  
 
 
 
 
| 
 Blog信息  |  
| 
   
blog名称:二进制-虚心使人进步,骄傲使人落后。 日志总数:42 评论数量:370 留言数量:88 访问次数:643488 建立时间:2005年2月19日   |   
 
  
 
  |    | 
 
| 
  [网络编程技术]【原创】Winpcap学习:第三天(20060128) 原创空间,  随笔,  读书笔记,  心得体会,  软件技术,  电脑与网络 
binaryluo 发表于 2006/1/28 16:09:20   |  
| 
 
    今天的试验程序与前天的功能是一样的,只是在捕获数据包的时候前天的程序用的是pcap_loop(),今天的代码用的是pcap_next_ex()。基于pcap_loop()抓包机制的回调很方便而且在某些情况下是一个不错的选择。但是,处理回调有些时候不适用——它使得程序更复杂,尤其是在应用程序与多线程或C++类有关的情况下。而pcap_next_ex()有的时候用起来更加方便。
    试验代码3:
#include <pcap.h>#include <remote-ext.h>
int 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 on the local machine */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &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; }
 /* Select an adapter */ 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 adpater */ for (d = alldevs, i = 0; i < inum - 1; d = d->next, ++ i);
 /* Open the device */ if ((adhandle = pcap_open(d->name, /* name of the device */         65536, /* portion of the packet to capture */         /* 65536 guarantees that the whole packet will be captured on all the link layers */         PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */         1000,  /* read timeout */         NULL,  /* authentication on the remote machine */         errbuf /* error buffer */ )) == NULL) {   fprintf(stderr, "\nUnable to open the adapter. %s is not supported by Winpcap\n", d->name);
   /* Free the devices 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);
 /* Retrieve the packets */ 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 1;}
函数1:
pcap_next_ex(pcap_t*                       p,
                      struct pcap_pkthdr**   pkt_header,
                      const u_char*             pkt_data
)
    从一个网络接口或离线捕获方式(例如读文件)读取一个数据包。该函数被用来重新获得下一个可用的数据包,没有使用libpcap提供的传统的回调方法。pcap_next_ex用指向头和下一个被捕获的数据包的指针为pkt_header和pkt_data参数赋值。
返回值有下列几种情况:
1,数据包被正确读取
0,pcap_open_live()设置的超时时间到。在这种情况下pkt_header和pkt_data不指向有效数据包
-1,发生错误
-2,离线捕获的时候读取到EOF
    我们通常使用pcap_next_ex()而不是pcap_next(),因为pcap_next()有些缺点。首先,pcap_next()效率低,因为它隐藏了回调方法但是还是依赖于pcap_dispatch;第二,它不能检测EOF,所以当从一个文件获取数据包时它不是很有用。
 
函数2:
u_char* pcap_next(pcap_t*                      p,
struct pcap_pkthdr*     h
)
    返回下一个可用的数据包并且返回一个u_char指向该数据包数据部分的指针。如果发生错误或者活动的抓包没有读取到数据包(例如:数据包不能通过包过滤器而被丢弃,或者在支持读超时(read timeout)的平台上在任何数据包到来之前就超时终止,又或者是抓包设备的文件描述符在非阻塞(non-blocking)模式下并且没有数据包可以被读取),或者文件已被读完时返回NULL。不幸的是,没有办法检测是否发生错误。  
 |   
  
| 
 回复:Winpcap学习:第三天(20060128) 原创空间,  随笔,  读书笔记,  心得体会,  软件技术,  电脑与网络 
binaryluo发表评论于2006/2/28 23:23:21   |  
| 
 以下引用feiyu_lili(游客)在2006-2-27 9:50:00的评论:不好意思,假日休息去了~~嘿嘿
中文意思
c:\Documents and Settings\cheli\My Documents\Visual Studio Projects\disan\disan\disan.cpp(86): error C2664: 'pcap_next_ex' : 3第三个引数 'u_char **__w64  ' 里来的 'const u_char ** ' 类型不能转换。
 c:\Documents and Settings\cheli\My Documents\Visual Studio Projects\disan\disan\disan.cpp(86): fatal error C1903: 前面的错误没有修复。编译终止。
我用的是Microsoft Visual Studio .NET 2003可能是那个数据类型没有被定义过,也就是Winpcap的库没有被包含进去。  
 |   
  
| 
 回复:Winpcap学习:第三天(20060128) 原创空间,  随笔,  读书笔记,  心得体会,  软件技术,  电脑与网络 
feiyu_lili发表评论于2006/2/27 11:12:08   |  
| 
 我想知道第86行里面while ((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0)的第3个参数&pkt_data的值是哪个函数的什么参数传给他的?  
 |   
  
  
| 
 回复:Winpcap学习:第三天(20060128) 原创空间,  随笔,  读书笔记,  心得体会,  软件技术,  电脑与网络 
feiyu_lili(游客)发表评论于2006/2/27 9:50:00   |  
| 
 不好意思,假日休息去了~~嘿嘿
中文意思
c:\Documents and Settings\cheli\My Documents\Visual Studio Projects\disan\disan\disan.cpp(86): error C2664: 'pcap_next_ex' : 3第三个引数 'u_char **__w64  ' 里来的 'const u_char ** ' 类型不能转换。
 c:\Documents and Settings\cheli\My Documents\Visual Studio Projects\disan\disan\disan.cpp(86): fatal error C1903: 前面的错误没有修复。编译终止。
我用的是Microsoft Visual Studio .NET 2003  
 |   
  
| 
 回复:Winpcap学习:第三天(20060128) 原创空间,  随笔,  读书笔记,  心得体会,  软件技术,  电脑与网络 
binaryluo发表评论于2006/2/24 22:22:43   |  
| 
 以下引用feiyu_lili(游客)在2006-2-24 17:35:34的评论:c:\Documents
and Settings\cheli\My Documents\Visual Studio
Projects\disan\disan\disan.cpp(86): error C2664: 'pcap_next_ex' : 3
番目の引数を 'u_char **__w64  ' から 'const u_char ** ' に変換できません。
c:\Documents and Settings\cheli\My Documents\Visual Studio
Projects\disan\disan\disan.cpp(86): fatal error C1903:
直前のエラーを修復できません。コンパイルを中止します。不好意思是日语!这段代码我已经在VC++6.0下编译通过了。是不是你的什么设置不对啊?也看不懂错误提示是什么。  
 |   
  
| 
 你这段代码问题的呢! 原创空间,  随笔,  读书笔记,  心得体会,  软件技术,  电脑与网络 
feiyu_lili(游客)发表评论于2006/2/24 17:35:34   |  
| 
 c:\Documents and Settings\cheli\My Documents\Visual Studio Projects\disan\disan\disan.cpp(86): error C2664: 'pcap_next_ex' : 3 番目の引数を 'u_char **__w64  ' から 'const u_char ** ' に変換できません。
c:\Documents and Settings\cheli\My Documents\Visual Studio Projects\disan\disan\disan.cpp(86): fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します。不好意思是日语!  
 |   
 
  
  |