WINPCAP编程环境设置
- 格式:doc
- 大小:81.00 KB
- 文档页数:11
使用Winpcap示例程序的时候解疑使用Winpcap示例程序的时候,会出现很多错误(转)WINPCAP编程环境设置2008-05-19 12:41一、WINPCAP编程环境设置在正式WinPcap编程之前,要配置运行环境。
1、运行环境设置Win32 平台下WinPcap应用程序需要以下四个动态链接库才能正常运行:wpcap.dll Packet.dll WanPacket.dll pthreadVC.dll 这四个动态链接库在WinPcap驱动程序里。
如果没有这个驱动程序,需要到WinPcap官方网站上下载,下载地址为: 如果应用程序出现一下提示,那就是没有安装驱动程序的原因了。
也可以不安装WinPcap驱动程序。
但是需要把上面提到的四个动态链接库文件拷贝到系统分区/WINDOWS/system32目录下。
(似乎有些问题)2、配置编程环境。
1> 从上下载WINPCAP SDK -WpdPack,WinPcap SDk里面包含库文件,头文件,文档文件和一些例子。
解压到一个指定的目录。
解压缩后把Include目录添加到IDE的包含文件中(VC6.0 T ools->Option->Directory; VS 2003/2005 工具->选项->项目和解决方案/项目->VC++目录); lib目录添加为新的库文件目录(VC6.0Tools->Option->Directory; VS 2003/2005 工具->选项->项目和解决方案/项目->VC++目录)如下图所示。
2> 如果一个源文件使用了WinPcap提供的库函数,那么就需要在该文件开始的位置添加pcap.h包含文件(或者在引用的文件中),即#include “pcap.h”也许会出现下面的错误:fatal error C1083: 无法打开包括文件:“pcap.h”: No such file or directory这个错误表明找不到pcap.h文件,这个头文件在驱动程序安装完成后也是没有的,它是开发包里面的一个头文件,所以,如果要运行程序还需要到官方网站上去下载WinPcap SDK,并按步骤1添加到项目中。
Winpcap 程序员手册Packet.dll API :程序员手册1.介绍PACKET.DLL 是一个动态连接库。
它提供了一套面向用户的包捕捉驱动程序接口。
这套动态连接库实现了一系列的函数,使得用户与驱动器的通信变得更为简便。
这避免了在用户程序中使用系统调用或控制输入/输出设备驱动模式(IOCTLs)。
而且,这套动态连接库还提供了网络适配器控制函数,对网络上捕获的数据包进行读取/写入函数,在驱动器中设置缓冲区和过滤器函数等等。
目前,有两个版本的PACKET.DLL:第一个适用于Windows95/98,第二个版本适用于WindowsNT/2000。
这两个版本都提供了相同的应用程序接口,这使得编写独立于系统的包捕获应用程序变得更为容易。
通过调用PACKET.DLL API,同一个应用程序可不做任何修改就在Windows95/98/NT/2000环境下运行。
本手册讲述了如何使用PACKET.DLL,并详细讲解这套动态连接库提供的函数和数据结构。
2.PACKET.DLL 与wpcap的比较如果你要编写一个没有特别/底层要求的包捕获应用程序,推荐使用wpcap.dll的函数,这是包捕获库(libpcap)的一个扩展集,而不是本章节中讨论的API。
在wpcap.dll中也使用PACKET.DLL的函数。
但wpcap.dll提供了一个更强大、更直接、更简洁的编程环境。
通过使用wpcap.dll,诸如捕获包、创建一个包过滤器或者在文件中保存dump 这些操作会被准确地执行并使程序变得直观。
Libpcap能够为一个标准的网络监听或嗅探程序提供所有需要的函数。
而且,利用libpcap编写的程序也能在UNIX平台上进行编译,这是因为这个库的Win32版本和UNIX版本有很好的兼容性。
然而,PACKET.DLL API 有一些libpcap没有提供的可能的操作。
Libpcap相对简单,它提供了一套系统无关的捕获包的API。
Winpcap开发环境搭建1、安装WinPcap_4_1_3.exe2、安装WinPcap开发包WpdPack_4_1_2.zip3. 开发环境●VC61)Tools->Options->Directories, 分别添加Include files和Libraries files目录2)pcap-stdinc.h#define _W644)Project->Settings->C/C++->Preprocessor definitions:WPCAP, HAVE_REMOTE5)Project->Settings->Link->Object/library modules:wpcap.lib Packet.lib或者在源代码文件中增加:#pragma comment(lib, "wpcap.lib")#pragma comment(lib, "Packet.lib")●VS20101) 执行菜单栏“视图——其他窗口——属性管理器”,可以看到“属性管理器”显示在工作区左侧。
如下图所示:2) 双击Debug | Win32下的“er“,或者右键单击->Properties。
在弹出的配置框中配置。
这个设置是全局的,对所有工程有效。
VC++ Directiories -> Include Directories和Library Directories中添加路径。
假如将wpdpack放到c盘。
则:Include Directories:c:\wpdpack\Include;Library Directories:c:\wpdpack\Lib;3)C/C++->Preprocessor(预处理器)->Preprocessor Definitions(预处理定义):添加WPCAP;HAVE_REMOTE;4) 链接器->输入->附加依赖项:添加wpcap.lib; Packet.lib;或者在源代码文件中增加:#pragma comment(lib, "wpcap.lib")#pragma comment(lib, "Packet.lib")。
Winpcap 环境部署注意:在VC6.0下进行winpcap程序和开发组件式不要用官网的最新版本而用低版本的,其中4_0_2是可以的。
Winpcap是一个强大的网络开发库,可以实现许多功能:获取可用的网络适配器;获取指定适配器信息(比如名称和描述信息);捕获指定网卡的数据封包;发送数据封包;过滤捕获的包以获取特定包等。
首先到/install/default.htm下载安装winpcap 驱动和DLL组件。
注意下图被红线圈起来的地方,即使下载地址,点击进入然后到/devel.htm.下载winpcap开发包,解压到指定目录,这里我解压到C:\WpdPack_4_0_2\WpdPack,可以看到里面包含了:Lib,Include,文档和示例程序。
把安装包和开发包下载下来后,执行安装包,这样你的机子就能运行winpcap程序了,解压开发包里面有具体解决方法:这里的include和lib文件夹里的东西因为vc6.0里没有,所以编译一些程序时我们要手动添加。
如果出现fatal error C1083: Cannot open include file: 'pcap.h': No such file or directory这个问题,就需要添加了。
下面是具体添加步骤:第一步:点菜单栏上的“工具”,再点击下拉菜单中的“选项”弹出“选项”对话框点“目录”在“目录【S】”的下面选择include files然后按底下的添加符号,把你写的winpcap开发包解压到的具体路径添加进去,如上图我的路径是C\:WpdPack 4 1 beta4\WpdPack\include把这个添加进去就行了然后选择“目录”下的下拉菜单中的library files把winpcap开发包里的lib文件路径添进去,我的是C:\WpdPack_4_1_beta4\WpdPack\Lib。
第二步菜单栏里的工程——设置,弹出project settinggs对话框,点击连接然后在“对象/库模块”下加入wpcap.lib Packet.lib 注意这个地方每个之间用空格隔开。
一、VC的安装在毕业设计中,我使用C++语言作为我的程序设计语言,而之所以选择它是因为:1、 ANSI 规范了C++的标准,使之具有高度的可移植性。
2、 C++程序能够运行得很快,可直接操作系统资源,而且能保持机器层次的实现细节。
3、 C++不要求图形环境,对系统要求相对较低。
4、易于解决与旧工程的接口以及在数据库,存储和性能方面的技术限制。
5、 C++ 既能够实现以前的结构化程序设计,方便初学者入门,又能够担当现在流行的面向对象的程序设计。
6、使用C++来开发软件可以大大减少重复的工作,使得设计程序更加轻松。
如下是安装《Turbo C/C++ for Windows 集成实验与学习环境》软件的步骤:1.双击安装包;2.单击“下一步”,继续安装;3.选择安装路径,并单击“下一步”继续安装;4.选择安装软件的目标文件夹,单击“下一步”继续安装;5.创建桌面快捷方式,并单击“下一步”继续安装;6.确定安装,单击“安装”;7.等待安装;8.单击“完成”,完成安装;9.双击桌面图标,进入编译环境;10.选择“VC6.0”,进入”Microsoft Visual C++”;11.编译一个标准输出字符串的小程序:完成后先点Build菜单,再点Compile OK.cpp(编译)。
所谓编译,就是使用编译器软件将我们比较容易掌握的高级语言翻译成计算机可以识别的低级语言。
如果没有经过编译,高级语言的程序代码是无法被执行的。
编译完成后,还要再点Build菜单,点Build工程名。
EXE(本例是“BuildOK.exe)。
我们通常把这个过程称为连接(Linking),其作用是将多个源文件的程序模块都整合起来。
当一个程序规模比较大的时候,连接也成为保证程序能正常运行的关键步骤之一。
最后再点Build菜单里的Execute 工程名.EXE(执行,本例是“Execute OK.Exe”),就能运行程序并查看结果了。
结果如下:由此,我们可以知道,编译软件安装成功了。
实验四编写协议解析器程序一、实验要求及目的使用libpcap/winpcap 进行网络抓包,并解析网络数据包的各层首部字段。
通过编写程序,捕获一段时间内以本机为源地址或者目的地址的IP 数据包,统计IP 数据包的信息,解析首部字段,匡助加深对IP 协议的工作原理和工作过程的认识以及掌握winpcap 抓包原理。
二、实验运行环境本实验是是用winpcap 进行网络抓包,基于windows 系统,下载WpdPack 4.1.2 安装包,在Visio stdio 2022 上配置winpcap 抓包环境,再编写C++代码实现网络抓包。
三、实验原理TCP/IP 协议族的分层结构包括应用层,传输层,互联网络层和主机- 网络层,其结构如图1 所示:应用层Telnet、TFP、SMTP DNS、TFTP、SNMP传输层TCP UDP互联网络层IP主机- 网络层Ethernet,Token Ring,X.25,SLIP,PPP图1 TCP/IP 协议族的分层结构其中IP 协议是保证以太网正常运行的最重要的协议之一,只要用于负责IP 寻址,路由选择和IP 数据报的分割与组装。
IP 协议是直接位于数据链路层之上,负责将源主机的报文分组发送到目的主机。
IP 协议是一种不可靠,无连接的数据报传送服务协议,它提供的是一种“竭力而为”的服务。
为了向传输层屏蔽的通信子网的差异,IP 协议制订了统一的IP 数据报格式。
IP 数据报的长度是可变的,它分为报头和数据两个部份。
基本的IP 报头是20B.选项字段的长度范围是0—40B,所以IP 数据报报头的长度是范围是20-60B。
IPV4 IP 数据报的结构如图2 所示:图2 IP 数据包格式IP 首部封装具体解释如下:(1)版本占 4 位,是指IP 协议的版本。
通信双方使用的IP 协议版本必须一致。
目前广泛使用的IP 协议版本号为4 (即IPv4 )(2)首部长度占 4 位,可表示的最大十进制数值是15。
因为项目需要,而且以前从没用过Winpcap,所以不得不从头学起。
以前虽然看过winsocket,但是,Winpcap的第一个程序,我花了很长时间才编译通过。
对于初学者来说,不太好做的可能是编译程序之前应该做什么事。
我就大体说一下我的过程。
首先先大体介绍下Winpcap。
winpcap(windows packet capture)windows平台下一个免费,公共的网络访问系统。
开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。
它提供了以下的各项功能:1> 捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包;2> 在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;3> 在网络上发送原始的数据包;4> 收集网络通信过程中的统计信息。
具体介绍参见/view/696423.htm这里有Winpcap的详细介绍。
下面说一下你在编译Winpcap之前要做的事情。
1 下载Winpcap安装包,地址/install/default.htm。
2 然后到/devel.htm下载WinPcap developer's pack包,解压,里面有配置好的例子和include library。
3 在VC6.0菜单中,点Tolls->Options->Directories中的include files 和library files中添加包里面的include和library。
然后我们就来编写一个最简单的Winpcap程序——获取已连接的网络适配器列表。
首先新建一个工程,选择Win32 Console Application,工程名我们设为winpcap.然后这这个工程中新建一个C++源文件,名字winpcap。
在里面填写如下代码:#include <pcap.h>main( )pcap_if_t *alldevs;pcap_if_t *d;int i=0;char errbuf[PCAP_ERRBUF_SIZE];if (pcap_findalldevs(&alldevs, errbuf) == -1){fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); exit(1);}for(d= alldevs; d != NULL; d= d->next){printf("%d. %s", ++i, d->name);if (d->description)printf(" (%s)\n", d->description);elseprintf(" (No description available)\n");}if (i == 0){printf("\nNo interfaces found! Make sure WinPcap is installed.\n");return -1;}pcap_freealldevs(alldevs);return 0;}运行之前我们要手动给它添加一个动态链接库wpcap.lib,方法是在菜单Project中点Settings,然后在选项中选Link,在library modules 后面填上wpcap.lib,注意和前面的要有空格隔开。
然后编译,链接。
运行结果如下正是我电脑的网卡信息,其中第一个现在我还没弄明白是什么,第二是我的无线网卡,第三是我现在正在用它上网的Realtek以太网卡。
关于这个程序的一些函数和变量的解释,大家可以看看Winpcap documentation,里面介绍的很详细,这里就不分析了。
PS:细心的人会发现,这里用来获取网络适配器信息的函数为pcap_findalldevs(),和Winpcap documentation里面的例子不同,它那里用的函数是pcap_findalldevs_ex(),这个函数的参数有四个,这两个函数的定义及参数问题,在帮助文档上都很详细,这里也不说了。
要是用这个函数的话,编译时会有错误,说pcap_findalldevs_ex()未定义,为什么呢?因为我们这里头文件只包含了winpcap.h,在这个头文件里,你会发现并没有pcap_findalldevs_ex()这个函数的定义,而只有pcap_findalldevs()的定义。
那么怎么办呢?两个方法,一,在#include <pcap.h>前面加上一个预处理程序定义#defineHAVE_REMOTE。
二,直接加上#include <remote_ext.h>,因为在这个文件里有pcap_findalldevs_ex()的函数定义。
其实第一种方法也就变相的调用remote_ext.h这个文件,其过程大家可以在pcap.h中找到。
PS2:为什么前面已经设置了路径了,函数编译的时候为什么还的手动添加动态链接库?因为这个路径只是告诉它在哪里找,也就是说,只是个路径提示。
就像include <pcap.h>一样,它也是在Directories设置的include文件中的,但是我们在程序的开头还的包括这个头文件,这个道理是一样的。
ps3: 发现上面的运行结果的图给贴错了,这个图是我禁用无线网络后运行的,所以没有打印出无线网卡的信息,只是有两个,第一个根据老师的介绍是计算机的拨号和VPN(虚拟专用网)的网络接口(俗称的“猫”),第二个是以太网卡。
1.在VC 6.0中[工具]->[选择]->[目录]分别把解压包里的inlude和library加进去。
2.在VC 6.0中[工程]->[Link]中加wpcap.lib Packet.lib或在源文件中加入#pragma comment(lib, "wpcap.lib")#pragma comment(lib, "Packet.lib")。
3.若要在程序中使用套接字,还须加#pragma comment(lib, "wsock32.lib")。
二列举网卡及对应的网络地址和子网掩码#include "pcap.h"#pragma comment(lib, "wpcap.lib")#pragma comment(lib, "Packet.lib")#pragma comment(lib, "wsock32.lib")void main()...{pcap_if_t *alldevs; //网络接口结点指针pcap_if_t *d;struct in_addr net_ip_address;//网络地址u_int32_t net_ip;//某种格式的网络地址char *net_ip_string;//可输出格式的网络地址struct in_addr net_mask_address;//子网掩码u_int32_t net_mask;//某种格式的子网掩码char *net_mask_string;//可输出格式的子网掩码int i=0;char errbuf[PCAP_ERRBUF_SIZE];/**//* 取得列表*/if (pcap_findalldevs(&alldevs, errbuf) == -1)...{fprintf(stderr,"Error in pcap_findalldevs: %s ", errbuf);exit(1);}/**//* 输出列表*/for(d=alldevs;d;d=d->next)...{printf("%s ",d->name);//网卡名字pcap_lookupnet(d->name,&net_ip,&net_mask,errbuf);//获取网络地址和子网掩码net_ip_address.s_addr = net_ip;net_ip_string = inet_ntoa(net_ip_address); //格式转化printf("网络地址:%s ", net_ip_string);net_mask_address.s_addr = net_mask;net_mask_string = inet_ntoa(net_mask_address); //格式转化printf("网络掩码:%s ", net_mask_string);}pcap_freealldevs(alldevs); //释放接口结点链表}运行结果如图:注:网络地址不是IP地址,故是10.10.138.0三捕获一个网络数据包#include <pcap.h>#pragma comment(lib, "wpcap.lib")#pragma comment(lib, "Packet.lib")#pragma comment(lib, "wsock32.lib")/**//*-----------------------------------------------------------------------------------------------------------------------WinPcap头文件;以下是以太网协议格式-----------------------------------------------------------------------------------------------------------------------*/struct ether_header...{u_int8_t ether_dhost[6];/**//* 以太网目的地址*/u_int8_t ether_shost[6];/**//* 源以太网地址*/u_int16_t ether_type;/**//* 以太网类型*/};void main()...{pcap_if_t *alldevs;char error_content[PCAP_ERRBUF_SIZE];/**//* 存储错误信息*/pcap_t *pcap_handle;/**//* winpcap句柄*/const u_char *packet_content;/**//* 数据包内容*/u_char *mac_string;/**//* 以太网地址*/u_short ethernet_type;/**//* 以太网类型*/bpf_u_int32 net_mask;/**//* 掩码地址*/bpf_u_int32 net_ip;/**//* 网络地址*/char *net_interface;/**//* 网络接口*/struct pcap_pkthdr protocol_header;/**//* 数据包头部信息*/struct ether_header *ethernet_protocol;/**//* 以太网协议变量*/struct bpf_program bpf_filter;/**//* BPF过滤规则*/char bpf_filter_string[] = "ip";/**//* 过滤规则字符串*/// net_interface = pcap_lookupdev(error_content); //因为第一个是moden的网卡,所以不用这个if (pcap_findalldevs(&alldevs,error_content) == -1)...{fprintf(stderr,"Error in pcap_findalldevs: %s ",error_content);exit(1);}net_interface=alldevs->next->name;//得到第二个网卡(以太网卡)的名字/**//* 获得网络接口*/pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);/**//* 获得网络地址和网络掩码*/pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);/**//* 打开网路接口*/pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);/**//* 编译过滤规则*/pcap_setfilter(pcap_handle, &bpf_filter);/**//* 设置过滤规则*/if (pcap_datalink(pcap_handle) != DLT_EN10MB)return ;packet_content = pcap_next(pcap_handle, &protocol_header);/**//* 捕获一个数据包,数据包内容返回给packet_content */printf("--------------------*****----------------------- ");printf("捕获到一个网络数据包");printf("捕获时间: ");printf("%s", ctime((const time_t*) &protocol__sec));printf("数据包长度: ");printf("%d ", protocol_header.len);ethernet_protocol = (struct ether_header*)packet_content;/**//* 获得数据包内容*/printf("以太网类型: ");ethernet_type = ntohs(ethernet_protocol->ether_type);/**//* 获得以太网类型*/printf("%04x ", ethernet_type);switch (ethernet_type)...{case 0x0800:printf("上层协议是IP协议");break;case 0x0806:printf("上层协议是ARP协议");break;case 0x8035:printf("上层协议是RARP协议");break;default:break;}printf("源以太网地址: ");mac_string = ethernet_protocol->ether_shost;printf("%02x:%02x:%02x:%02x:%02x:%02x ", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));/**//* 获得源以太网地址*/printf("目的以太网地址: ");mac_string = ethernet_protocol->ether_dhost;printf("%02x:%02x:%02x:%02x:%02x:%02x ", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));/**//* 获得目的以太网地址*/printf("--------------------*****----------------------- ");pcap_close(pcap_handle);/**//* 关闭winpcap操作*/}运行结果(随便打开一个网页)如图:注:因为第一个网卡是moden的网卡,所以要用pcap_findalldevs(&alldevs,error_content);net_interface=alldevs->next->name;若使用pcap_findalldevs_ex(),应#include <remote-ext.h>它是pcap_findalldevs()的一个超集, 他不仅可以获取本地的设备列表,还可以获取远程计算机的设备列表四捕获多个网络数据包#include <pcap.h>#pragma comment(lib, "wpcap.lib")#pragma comment(lib, "Packet.lib")/**//* 回调处理函数的原型*/void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);main()...{pcap_if_t *alldevs;//接口结点指针pcap_if_t *d;int inum;int i=0;pcap_t *adhandle;char errbuf[PCAP_ERRBUF_SIZE];/**//* 取得所有网卡列表*/if(pcap_findalldevs(&alldevs, errbuf) == -1)...{fprintf(stderr,"Error in pcap_findalldevs: %s ", errbuf);exit(1);}/**//* 输入列表*/for(d=alldevs; d; d=d->next)...{printf("%d. %s", ++i, d->name);if (d->description)printf(" (%s) ", d->description);elseprintf(" (No description available) ");}if(i==0)//如果网卡数等于0,则输出"找不到网卡"...{printf(" No interfaces found! Make sure WinPcap is installed. ");return -1;}/**//* 选择欲抓包网卡号*/printf("Enter the interface number (1-%d):",i);scanf("%d", &inum);if(inum < 1 || inum > i)...{printf(" Interface number out of range. ");/**//* Free the device list */pcap_freealldevs(alldevs);return -1;}for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);//进行网卡选择/**//* 打开一个网卡进行抓包*/if ((adhandle= pcap_open_live(d->name, // 网卡名字65536, // 要捕获的数据包字节数1, // 混杂模式为非0,非混杂为01000, // read timeouterrbuf // error buffer)) == NULL)...{fprintf(stderr," Unable to open the adapter. %s is not supported by WinPcap ", d->name); pcap_freealldevs(alldevs);return -1;}printf(" listening on %s... ", d->description);/**//* 释放网络接口列表结点链表空间*/pcap_freealldevs(alldevs);/**//* 开始循环抓包,每抓一个包就用第三个参数所指的处理函数来处理*/pcap_loop(adhandle, 0, packet_handler, NULL);pcap_close(adhandle);return 0;}/**//* 回调处理函数*/void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) ...{struct tm *ltime;//在pcap.h已包含了<time.h>char timestr[16];//接收转换后的时间time_t local_tv_sec;/**//* 获得时间*/local_tv_sec = header->_sec;//日历日间,相当于local_tv_sec = time(NULL);ltime=localtime(&local_tv_sec);//日历时间转化为本地时间strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);//时间显示格式printf("%s,%.6d len:%d ", timestr, header->_usec, header->len);}运行结果:本文来自CSDN博客,转载请标明出处:/xklxlmw/archive/2007/05/09/1602319.aspx。