利用WinpCap写抓包工具

      这个程序原为我上学期网络课程设计的作品,利用了WinpCap提供的接口。

       WinpCap是一个公开的免费的抓包驱动加开发包,利用它,可以大大缩短我们的开发周期。

      首先,先枚举系统中的所有网卡:

/* 获取设备列表 */ 
 if (pcap_findalldevs(&alldevs, errbuf) == -1)
 {
  fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
  exit(1);
 }
 /* 数据列表 */ 
 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 ( (adhandle= pcap_open_live(d->name, //设备名 
  65536, // 捕捉完整的数据包 
  1 , // 混在模式 
  1, // 读入超时 
  errbuf // 错误缓冲 
  ) ) == NULL)
 {
  printf("Unable to open the adapter");
  pcap_freealldevs(alldevs);
  return; 
 }

打开设备之后,我们就可以利用adhandle句柄来正式抓包了,先新建一个回调函数,形如

void packet_handler(u_char* packets,const struct pcap_pkthdr *header,const u_char *data)
{

 }

然后调用pcap_loop(adhandle, 0, packet_handler, NULL);pcap_loop的最后一个参数和packet_handler的packets参数是对应的,用于在函数间传递数据。WinpCap每收到一个包就自动调用packet_handler函数,将包的内容作为data参数,我们对data作强制类型转化就可以得到数据包各部分的内容。

事实上,WinpCap开发包除了可以用回调函数抓包外,还可以用非回调的方法。在得到adhandle后不调用pcap_loop,而用下面的方法:

while(1)
 {
   res = pcap_next_ex(adhandle,&header,&data);
  if(res==0)
  {
   Sleep(100);
   continue;
  }

}

用pcap_next_ex读取数据包内容,至于if(res==0)这一段是为了防止没数据包到达时重复循环。

不多讲了全部源程序可看附件。附件中有两个抓包程序,一个是GUI的,一个是CUI的。CUI程序的运行结果如下:

 

附件下载:

WinpCap开发包 :

WinPcap_4_0_beta3.rar

CUI抓包源程序:

CapPack.rar

GUI抓包源程序(MFC):

MFCCapPack.rar
  • quote 1.tj646
  • 我下载了3个源码没看到有CUI版本的呀

    你的程序是不是在VS2003下面编写的呀.
    langouster 于 2007-04-08 20:06:42 回复
    第二个是CUI的,我把名字写错了。
    程序的确是在VS2003下编译的。
  • 2007-04-08 20:06:42 回复该留言
  • quote 2.你的这个程序有点小问题
  • 这个程序有点小问题!程序中的ListCtrl控件中的源IP和目的IP的显示是一样的。为什么?
    解决的方法是:应该在CapPackDlg.cpp中472行改为:ipaddr=IPHead->ip_destination_address;

    请多多指教哦!!小弟刚学MFC和WinPcap。
  • 2007-05-08 21:27:14 回复该留言
  • quote 3.langouster
  • 抱歉抱歉,能找出这样的错误,厉害厉害,谢谢!
    futurist007 于 2007-05-09 17:09:52 回复
    不用客气!还想向你请教呢!!
  • 2007-05-09 17:09:52 回复该留言
  • quote 4.futurist007
  • 我今天又测试了一下还有一些小问题,你可否解决一下? 如果解决了,能发给我一份吗?

    问题1:只能抓住本机发往局域网以外的IP(或者调过来),不能抓住本地局域网内任何机器的数据报(最多也只能抓住又路由发来的数据)?----这是关键问题????按道理用 WinPcap可以抓住的哦??

    问题2:设置过滤条件好像有点问题,设置好了好像不生效;不知为什么?

    希望您能够帮忙一下。 Thank you very much !!---一个想学好编程的人!!

    我的通信邮箱是 futurist007@126.com
    langouster 于 2007-05-10 20:20:13 回复
    兄弟看的真仔细,确实有这两个问题,关于第二个问题,你看下源程序就知道原因了,程序中其实没加一些过滤,当时做课程设计时间急啊.
    关于第一个问题,你也挻郁闷的,用的方法应该没问题,但就抓不到其它机子的TCP包(可能是网卡模式的问题).
    要不是现在忙于备考和更新我的IE卫士,我真的想有空改改我的程序.抱歉.
    要以后改好了定发给你.
    futurist007 于 2007-05-10 20:45:47 回复
    谢谢你提供解决方法的思想!
  • 2007-05-10 20:45:47 回复该留言
  • quote 5.谢谢啊
  • 很感谢你这个程序,我正好用上了。
    在你的程序里没有保存文件的代码,我自己编了一个,但总有问题,你能不能有时间写一下,谢谢! ^_^
  • 2007-05-24 22:03:17 回复该留言
  • quote 6.futurist007
  • 楼上的那位你到底有没有看代码的?程序中已经实现了保存文件的代码,你再仔细看一下吧!!
  • 2007-05-30 20:59:40 回复该留言
  • quote 7.futurist007
  • 在设置过滤条件时,我在初始化的时候m_ComboFilter.AddString("ip");选择后取得“ip”这个字符串,但在设置pcap_compile()的第三个参数时它要求是(char *),怎样才可以转换成功呢?还是有其他的办法? 请教你啦!!
    langouster 于 2007-06-01 14:35:53 回复
    已经记不得了 不过WinpCap只带的例子程序上有讲过滤的,建议你看看
  • 2007-06-01 14:35:53 回复该留言
  • quote 8.futurist007
  • 为什么WinPcap捕捉到的数据是乱码的?
    langouster 于 2007-06-09 22:11:21 回复
    要么程序手下抓包有问题,要么对包的分析有问题.
    其实大多数时候就应该是乱码,浏览网页时应该不是(HTTPS除外).
  • 2007-06-09 22:11:21 回复该留言
  • quote 10.kishy
  • 你好,MFC那个编译出现问题:
    LINK : fatal error LNK1181: cannot open input file "and.obj"
    请教下怎么回事啊?3X
    langouster2 于 2007-11-09 16:07:16 回复
    全部重新编译试试
  • 2007-11-09 16:07:16 回复该留言
  • quote 11.旭之明
  • 第二个GUI的下下来调试的过程中出现了很多问题 编译也通不过,错误解决不了,您能具体说一下把你给的包下下来后,怎么调试(包括路径的设置呀,等等 比较细节的问题,我的机子是VS2006)急需,谢谢拉
    langouster2 于 2008-05-15 14:27:41 回复
    要设置附加包含目录和附加库文件目录 我是用vs2003写的
  • 2008-05-15 09:04:39 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Copyright langouster. Some Rights Reserved.   苏ICP备06046736号   

本站点由 Z-Blog 2.0 bate Build 构建,基于 Glued Ideas Subtle 主题,由 zx.asd 移植并创新.