以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 安全理论 』  (http://bbs.xml.org.cn/list.asp?boardid=65)
----  [原创]Winpcap学习第三天  (http://bbs.xml.org.cn/dispbbs.asp?boardid=65&rootid=&id=33470)


--  作者:binaryluo
--  发布时间:6/1/2006 9:30:00 AM

--  [原创]Winpcap学习第三天
今天的试验程序与前天的功能是一样的,只是在捕获数据包的时候前天的程序用的是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。不幸的是,没有办法检测是否发生错误。


--  作者:waxic
--  发布时间:6/12/2006 11:18:00 AM

--  
pcap_next_ex(adhandle, &header, &pkt_data))
这里编译不过去啊?????
--  作者:binaryluo
--  发布时间:6/12/2006 12:30:00 PM

--  
以下是引用waxic在2006-6-12 11:18:00的发言:
pcap_next_ex(adhandle, &header, &pkt_data))
这里编译不过去啊?????

报什么错误?


--  作者:picop
--  发布时间:12/21/2006 8:00:00 AM

--  
显示的错误是这样的:

--------------------Configuration: wincapd3 - Win32 Debug--------------------
Compiling...
wincapd3.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\winpcapday3\wincapd3.cpp(82) : error C2664: 'pcap_next_ex' : cannot convert parameter 3 from 'unsigned char ** ' to 'const unsigned char ** '
        Conversion loses qualifiers
C:\Program Files\Microsoft Visual Studio\MyProjects\winpcapday3\wincapd3.cpp(82) : fatal error C1903: unable to recover from previous error(s); stopping compilation
Error executing cl.exe.

localdev.obj - 2 error(s), 0 warning(s)


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
78.125ms