在vs2008MFC下开发基于winpcap的网络嗅探器(IP-TCP-UDP)_第1页
在vs2008MFC下开发基于winpcap的网络嗅探器(IP-TCP-UDP)_第2页
在vs2008MFC下开发基于winpcap的网络嗅探器(IP-TCP-UDP)_第3页
在vs2008MFC下开发基于winpcap的网络嗅探器(IP-TCP-UDP)_第4页
在vs2008MFC下开发基于winpcap的网络嗅探器(IP-TCP-UDP)_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上精选优质文档-倾情为你奉上专心-专注-专业专心-专注-专业精选优质文档-倾情为你奉上专心-专注-专业课程设计设计报告题 目: 基于Winpcap的网络嗅探器的实现 学 号: 姓 名: 学 院: 专业班级: 指导教师: 设计时间: 指导老师评语: 评定成绩: 签名: 日期:目 录 TOC o 1-3 h z u 1 概述1.1 课程设计的目的目的:设计一个GUI程序,实现IP、TCP、UDP数据包的捕获和解析。通过编程了解各类数据报的结构,掌握网络编程的基本原理和方法。1.2 设计任务与要求本课程设计的基本内容是捕获IP,TCP,UDP数据包,通过解析数据包,理解和掌握

2、各类数据包的结构(1)设计一个GUI程序,完成局域网数据包的捕获和IP、TCP、UDP数据包的解析;(2)捕获几个网络数据报,给出实例并分析各数据包各字段的含义;(3)说明基于Winpcap编程的基本原理、程序的总体框架,绘制每个函数的详细设计流程图。1.3 开发环境标准PC机,Windows操作系统,vs2008集成开发环境,Winpcap函数库。2系统设计的基本概念与原理2.1 IP协议基本知识 IP协议介绍IP是英文Internet Protocol(网络互连的协议)的缩写,中文简称为“网协”,也就是为计算机网络相互连接进行通信而设计的协议。在因特网中,它是能使连接到网上的所有计算机网络

3、实现相互通信的一套规则,规定了计算机在因特网上进行通信时应当遵守的规则。任何厂家生产的计算机系统,只要遵守 IP协议就可以与因特网互连互通。IP协议的网络互连实现各个厂家生产的网络系统和设备,如以太网、分组交换网等,它们相互之间不能互通,不能互通的主要原因是因为它们所传送数据的基本单元(技术上称之为“帧”)的格式不同。IP协议实际上是一套由软件程序组成的协议软件,它把各种不同“帧”统一转换成“IP数据包”格式,这种转换是因特网的一个最重要的特点,使所有各种计算机都能在因特网上实现互通,即具有“开放性”的特点。IP数据报TCP/IP协议定义了一个在因特网上传输的包,称为IP数据报(IP Data

4、gram)。这是一个与硬件无关的虚拟包, 由首部和数据两部分组成,其格式如图2.1所示:数据报的数据区数据报首部数据报的数据区数据报首部 图2.1 IP数据报一般格式IP数据报的详细格式如图2.2所示: 0 3 7 15 31版本首部长度服务类型总长度 标识标志片偏移生存时间协议头校验和源IP地址目的IP地址选项填充域数据部分 图2.2 IP数据报的详细格式IP数据报固定部分各字段含义:(1)版本占4位,指IP协议的版本。通信双方使用的IP协议版本必须一致。目前广泛使用的IP协议版本号为4(即IPv4)。关于IPv6,目前还处于草案阶段。 (2)首部长度占4位,可表示的最大十进制数值是15。请

5、注意,这个字段所表示数的单位是32位字长(1个32位字长是4字节),因此,当IP的首部长度为1111时(即十进制的15),首部长度就达到60字节。当IP分组的首部长度不是4字节的整数倍时,必须利用最后的填充字段加以填充。因此数据部分永远在4字节的整数倍开始,这样在实现IP协议时较为方便。首部长度限制为60字节的缺点是有时可能不够用。但这样做是希望用户尽量减少开销。最常用的首部长度就是20字节(即首部长度为0101),这时不使用任何选项。 (3)区分服务占8位,用来获得更好的服务。这个字段在旧标准中叫做服务类型,但实际上一直没有被使用过。1998年IETF把这个字段改名为区分服务DS(Diffe

6、rentiated Services)。只有在使用区分服务时,这个字段才起作用。 (4)总长度总长度指首部和数据之和的长度,单位为字节。总长度字段为16位,因此数据报的最大长度为216-1=65535字节。 在IP层下面的每一种数据链路层都有自己的帧格式,其中包括帧格式中的数据字段的最大长度,这称为最大传送单元MTU(Maximum Transfer Unit)。当一个数据报封装成链路层的帧时,此数据报的总长度(即首部加上数据部分)一定不能超过下面的数据链路层的MTU值。 (5)标识(identification)占16位。IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将

7、此值赋给标识字段。但这个“标识”并不是序号,因为IP是无连接服务,数据报不存在按序接收的问题。当数据报由于长度超过网络的MTU而必须分片时,这个标识字段的值就被复制到所有的数据报的标识字段中。相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报。 (6)标志(flag)占3位,但目前只有2位有意义。 标志字段中的最低位记为MF(More Fragment)。MF=1即表示后面“还有分片”的数据报。MF=0表示这已是若干数据报片中的最后一个。 标志字段中间的一位记为DF(Dont Fragment),意思是“不能分片”。只有当DF=0时才允许分片。 (7)片偏移占13位。片偏移

8、指出:较长的分组在分片后,某片在原分组中的相对位置。也就是说,相对用户数据字段的起点,该片从何处开始。片偏移以8个字节为偏移单位。这就是说,每个分片的长度一定是8字节(64位)的整数倍。 (8)生存时间占8位,生存时间字段常用的的英文缩写是TTL(Time To Live),表明是数据报在网络中的寿命。由发出数据报的源点设置这个字段。其目的是防止无法交付的数据报无限制地在因特网中兜圈子,因而白白消耗网络资源。最初的设计是以秒作为TTL的单位。每经过一个路由器时,就把TTL减去数据报在路由器消耗掉的一段时间。若数据报在路由器消耗的时间小于1秒,就把TTL值减1。当TTL值为0时,就丢弃这个数据报

9、。 (9)协议占8位,协议字段指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个处理过程。 (10)首部检验和占16位。这个字段只检验数据报的首部,但不包括数据部分。这是因为数据报每经过一个路由器,路由器都要重新计算一下首部检验和(一些字段,如生存时间、标志、片偏移等都可能发生变化)。不检验数据部分可减少计算的工作量。 (11)源地址占32位。 (12)目的地址占32位。IP数据报可选部分字段含义:IP首部的可变部分就是一个可选字段。选项字段用来支持排错、测量以及安全等措施,内容很丰富。此字段的长度可变,从1个字节到40个字节不等,取决于所选择的项目。某些选

10、项项目只需要1个字节,它只包括1个字节的选项代码。但还有些选项需要多个字节,这些选项一个个拼接起来,中间不需要有分隔符,最后用全0的填充字段补齐成为4字节的整数倍。2.2 TCP协议基本知识(1)TCP协议介绍TCP:Transmission Control Protocol (传输控制协议)TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层通信协议。在OSI/RM模型中,它完成第四层传输层所指定的功能,UDP是同一层内另一个重要的传输协议。(2)TCP协议的作用在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的运输层。 应用

11、层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分割成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个字节一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。首先,TCP建立连接之后,通信

12、双方都同时可以进行数据的传输,其次,他是全双工的;在保证可靠性上,采用超时重传和稍待确认机制。在流量控制上,采用滑动窗口协议,协议中规定,对于窗口内未经确认的分组需要重传。在拥塞控制上,采用慢启动算法。(3) TCP报文段格式两台机器上的TCP软件之间传送的数据单元称为报文段。两台机器通过报文段的交互来建立连接、传送数据、发送确认、通告窗口大小及关闭连接。每个报文段分为两个部分:首部和数据。TCP报文格式如图2.3:0 4 10 16 24 31源端口目的端口序号确认序号首部长度保留代码比特窗口校验和紧急指针选项填充数据 图2.3 TCP报文段详细格式TCP报文字段说明:源端口号(16位),标

13、识主机上发起传送的应用程序;目的端口(16位)标识主机上传送要到达的应用程序。序号:占32比特。用来标识从TCP源端向TCP目标端发送的数据字节流,它表示在这个报文段中的第一个数据字节。 确认序号:占32比特。只有ACK标志为1时,确认号字段才有效。它包含目标端所期望收到源端的下一个数据字节。 首部长度:占4比特。给出头部占32比特的数目。没有任何选项字段的TCP头部长度为20字节;最多可以有60字节的TCP头部。预留:由跟在数据偏移字段后的6位构成,预留位通常为0.代码比特(U、A、P、R、S、F):占6比特。各比特的含义如下: URG:紧急指针(urgent pointer)有效。 ACK

14、:确认序号有效。 PSH:接收方应该尽快将这个报文段交给应用层。 RST:重建连接。 SYN:发起一个连接。 FIN:释放一个连接。 窗口大小:占16比特。此字段用来进行流量控制。单位为字节数,这个值是本机期望一次接收的字节数。 TCP校验和:占16比特。对整个TCP报文段,即TCP头部和TCP数据进行校验和计算,并由目标端进行验证。 紧急指针:占16比特。它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。 选项、填充:占32比特。可能包括窗口扩大因子、时间戳等选项。2.3 UDP协议基本知识(1) UDP协议介绍UDP协议的全称是用户数据报协议,在网络中它与TCP协议一样用

15、于处理数据包。在OSI模型中,在第四层传输层,处于IP协议的上一层。UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。 UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天,UDP仍然不失为一项非常实用和可行的网络传输层协议。(2) UDP报文格式UDP报文段首部只有8个字节;详细格式见图2.40 1 3 5 7源端口目的端口长度校验和数据 图2.4

16、UDP报文详细格式2.4 winpcap基本知识(1) winpcap简介(1) Winpcap简介大多数Unix操作系统提供了一套允许应用程序直接与网络相互联系的系统调用。这些指令对于那些需要通过网络捕获连续的包数据而不用内核进行过多的干预的包捕获应用程序非常有用。在Windows环境下,WinPcap就是这样一类工具。WinPcap是一个在Windows操作系统下的免费、公开的用于直接访问网络的开发工具包(编程API)。大多数Windows网络应用程序都是通过Winsock API(Windows套接口)这类高级编程接口访问网络的。这种方法允许在网络上进行简单的数据传送,因为操作系统的TC

17、P/IP协议栈实现软件会处理底层细节(协议操作、流程重组等等),并提供一个类似于读写文件的函数接口。然而,有时候“简便方法”并不能满足实际需要。有些程序希望绕过TCP/IP协议栈,直接处理底层网络中的通信数据,它们需要对网络进行底层进行直接访问,即在没有类似协议栈(TCP/IP协议栈)的实体介入条件下对网络进行原始访问。基于Winsock API编程,应用程序是通过调用操作系统提供的编程接口访问TCP/IP协议栈实现网络通信的。基于WinPcap编程,网络程序实际上是绕开操作系统的TCP/IP协议栈直接通过底层网络发送数据,因此,网络程序可以实现一些更低级、更灵活的功能。 (2) Winpca

18、p的目的和用途开发WinPcap的目的是为Win32应用程序提供一种直接访问底层网络的能力。通过WinPcap,网络应用程序可以实现如下功能:捕获原始数据包,包括发送到本主机以及在共享网络上的数据包。数据过滤。在将数据包发送给应用程序之前按照用户的规定对捕获的数据包进行过滤。发送原始数据包。向网络发送原始数据包。数据包统计。对网络通信进行统计。上述功能都通过一个设备驱动(这个驱动程序安装在Win32内核的网络部分)和一组动态连接库(DLL)获得。所有这些功能部件都通过一个强大的编程接口来实现,应用程序能易于开发并且能移植到各种操作系统中。(3) 基于Winpcap可开发的网络应用程序基于Win

19、Pcap可以开发很多网络应用程序,典型的包括: 网络和协议分析软件 网络监听软件 网络通信量记录软件 网络数据生成软件 用户机网桥和路由器 网络入侵探测系统 网络扫描软件 网络安全工具Winpcap的局限性:WinPcap可以独立于主机的协议(如TCP/IP协议)进行接收和发送数据包。这意味着WinPcap不能阻塞、过滤或处理本机上其它程序产生的数据。它仅仅能嗅探在网线上传输的数据包。因此,WinPcap不能在traffic shapers、QoS schedulers和个人防火墙这类应用程序中使用。Winpcap的开发和运行环境:目前,winpcap主要的开发和运行环境是windows NT

20、/2000/XP。由于winpcap的用户中只有很小一部分使用windows 95/98/Me,并且微软也已经放弃了对win9x的开发和支持。实际上,winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。 Winpcap的组成与结构:WinPcap由一个数据包监听设备驱动程序(NPF)、一个底层的动态连接库(packet.dll)和一个高层的不依赖于操作系统的静态库(wpcap.dll)共三个部分构成,如图2.5所示。这里,NPF在操作系统的内核级,packet.dll、wpcap.dll在用户

21、级。图2.5 WinPcap的组成和结构图2.5 WinPcap的组成和结构应用程序wpcap.dllpacket.dllNPFDevice Driver用户层核心层网络层数据包1)数据包监听设备驱动程序技术实现上,为了实现抓包,系统必须绕过操作系统的协议栈来访问在网络上传输的原始数据包(raw packet)。这就要求WinPcap的一部分运行在操作系统核心内部,直接与网络接口驱动交互。由于这个部分是系统依赖(system dependent)的,在Winpcap的解决方案中它被视为是一个设备驱动,称作NPF(Netgroup Packet Filter)。Winpcap开发小组针对Wind

22、ows95,Windows98,WindowsME,Windows NT 4,Windows2000和WindowsXP提供了不同版本的驱动(在Windows95/98/ME中是VXD文件,在WindowsNT/2000中是SYS文件)。这些驱动不仅提供了基本的特性(例如抓包、发送原始数据包注入数据包),还有更高级的特性(例如可编程的过滤器系统和监视引擎)。前者可以被用来约束一个抓包会话只针对网络通信中的一个子集(例如,只捕获特殊主机产生的ftp通信数据包),后者提供了一个强大而简单的统计网络通信量的机制(例如,获得网络负载或两个主机间的数据交换量)。2)底层的动态连接库(packet.dll

23、)和高层静态库(wpcap.dll)为了方便编程,WinPcap必须提供一个编程接口(API),这就是WinPcap的底层的动态连接库(packet.dll)和高层静态库(wpcap.dll)。这里,packet.dll提供了一个底层API,伴随着一个独立于Microsoft操作系统的编程接口,这些API可以直接用来访问驱动的函数;wpcap.dll导出了一组更强大的与libpcap一致的高层抓包函数库(capture primitives),这些函数使得数据包的捕获以一种与网络硬件和操作系统无关的方式进行。底层动态链接库运行在用户层,它将应用程序和数据包监听设备驱动程序隔离开来,使得应用程序

24、可以不加修改地在不同的WINDOWS系统上运行。高级的静态链接库和应用程序编译在一起,它使用低级动态链接库提供的服务,向应用程序提供完善的监听接口。Winpcap的技术细节:1)NPF驱动网络数据包过滤器(Netgroup Packet Filter,简称NPF)是Winpcap的核心部分,它是Winpcap完成困难工作的核心组件。NPF负责处理网络上传输的数据包,并向上层提供各种服务,包括数据包的捕获(capture)、发送(injection)和分析性能(analysis capabilities)。2)NPF和NDISNDIS(Network Driver Interface Speci

25、fication)是Windows环境下的一个定义网络适配器(或者说成是管理网络适配器的驱动程序)与协议驱动(例如TCP/IP的实现)之间通信的规范,如图2.2。基于NDIS,顶层应用(例如TCP/IP协议)可以发送和接收网络(LAN或WAN)上的数据包而不必关心特定的适配器硬件或特定的Win32操作系统版本。网卡硬件网卡驱动程序网卡硬件网卡驱动程序NDISTCP/IP协议栈实现图2.2 NDIS的作用和地位 网络接口卡或NIC驱动(Network interface card or NIC drivers)。NIC驱动直接管理着网络接口卡(NIC)。NIC驱动接下边与硬件连接,从上边表现为一

26、个接口,该接口允许高层发送数据包到网络上,处理中断,重置NIC,停止NIC,查询和设置驱动的运行特征。NIC驱动可以是小端口(miniport)或完全的NIC驱动(full NIC driver)。Miniport驱动仅仅实现了管理NIC的必要操作,包括在NIC上发送和接收数据。对于所有最底层的NIC驱动的操作由NDIS提供,例如同步(synchronization)。小端口(miniport)不直接调用操作系统函数,它们对于操作系统的接口是NDIS。完全NIC驱动(Full NIC driver)完成硬件细节的操作和所有由NDIS完成的同步和查询操作。例如,完全NIC驱动维持接收到的数据的绑

27、定信息。 中间层驱动(Intermediate drivers)中间层驱动位于高层驱动(例如协议驱动)和小端口之间。对于高层驱动,中间层驱动看起来像是小端口;对于小端口,中间层驱动看起来像协议驱动。一个中间层协议驱动可以位于另一个中间层驱动之上,尽管这种分层可能对系统性能带来负面影响。 传输驱动或协议驱动(Transport drivers or protocol drivers)协议驱动实现了网络协议栈。在协议驱动的上面,它为应用层客户程序服务;在它的下面,它与一个或多个NIC驱动或中间层NDIS驱动连接。3)NPF在Windows系统中的位置如图2.6,NPF是一个协议驱动。从性能方面来看

28、,这不是最好的选择,但是它合理地独立于MAC层并且有权使用原始通信(raw traffic)。可以看出,NPF在NDIS之上,它与TCP/IP协议栈的实现在同一层次。因此,应用程序不通过Winsock也可以实现数据的发送和接受。图2.6 图2.6 NPF在Windows系统中的位置基于Winsock的应用程序NPFTCP/IP协议实现NIC Driver(NDIS3.0或更高)核心层网络层数据包基于Wincap的应用程序2.5 winpcap基本原理抓包是WinPcap的基本功能,也是NPF最重要的操作。在抓包的时候,驱动(例如NIC Driver)使用一个网络接口监视着数据包,并将这些数据包

29、完整无缺地投递给用户级应用程序。如图2.7,WinPcap的NPF抓包主要依靠两个组件。1)数据包过滤器(filter)。数据包过滤器决定是否接收进来的数据包并把数据包拷贝给监听程序。数据包过滤器是一个有布尔输出的函数。如果函数值是true,抓包驱动拷贝数据包给应用程序;如果是false,数据包将被丢弃。NPF数据包过滤器更复杂一些,因为它不仅决定数据包是否应该被保存,而且还决定要保存的字节数。应用程序采用用户自定义的过滤器并使用wpcap.dll将它们编译进BPF程序。然后,应用程序使用BIOCSETF IOCTL写入核心态的过滤器。这样,对于每一个到来的数据包该程序都将被执行,而满足条件的

30、数据包将被接收。与传统解决方案不同,NPF不解释(interpret)过滤器,而是执行(execute)它。由于性能的原因,在使用过滤器前,NPF提供一个JIT编译器将它转化成本地的80 x86函数。当一个数据包被捕获,NPF调用这个本地函数而不是调用过滤器解释器,这使得处理过程相当快。 2)循环缓冲区(Buffer)。NPF的循环缓冲区用来保存数据包以免丢失(如果一个包符合过滤器的要求,就被复制到循环缓冲区)。一个保存在缓冲区中的数据包有一个头,它包含了一些主要的信息,例如时间戳和数据包的大小,注意:它不是协议头。另外,循环缓冲区以队列插入的方式来保存数据包,提高数据的存储效率。程序员可以以

31、组的方式将数据包从NPF缓冲区拷贝到应用程序,这样就提高了性能,因为它降低了读的次数。如果一个数据包到来的时候缓冲区已经满了,那么该数据包将被丢弃,这时就发生了丢包现象。3)Network Tap是一个用于探听网络中所有数据流的函数。4)数据统计如图2.7,为了提高数据处理的速度,WinPcap将统计和监听功能移到内核中,这样避免了将任何数据都传递给用户。WinPcap通过使用从NPF中得到的过滤器来执行一个内核级的可编统计模块,这使其变成一个强大的分级引擎,而不只是个简单的包过滤器。应用程序可以构造这个模块来监听网络活动的任意方面(例如:网络负荷、两台主机间的流量、每秒web请求的次数等等)

32、,并在预定的时间间隔内接收内核传来的数据。图2.7 图2.7 Wincap的内部结构和原理基于Winpcap的监控程序packet.dllwpcap.dllNIC Driver(NDIS3.0或更高)核心层网络层数据包基于Winpcap的应用程序1Filter1Filter2Filter3Buffer1Buffer2统计引擎Network TapTCP/IP协议栈其他协议栈实现User- Buffer1User- Buffer2基于Winpcap的应用程序2NPF调用packet.dllAPI的程序直接访问NPF的程序用户层(4) 基于Winpcap的网络编程编程API接口的选择如前所述,Wi

33、nPcap由三部分模块组成NPF、packet.dll和wpcap.dll。编程方面,我们主要使用packet.dll和wpcap.dll提供的编程接口。基于packet.dll编写的程序可以不经过重新编译就在各种Win32平台下实现捕获数据包。另外,packet.dll还包含了其他一些函数,它可以进行一些底层的操作,如获取网络适配器名或动态的加载驱动程序。通过packet.dll还可以取得一些系统信息,如主机的MAC地址、一些硬件计数,例如以太网上冲突次数等。packet.dll和NPF都严重依赖于操作系统,并且由于Windows95/98和WindowsNT/2000之间OS结构的不同而在

34、不同版本的操作系统上有所不同。为了提高应用程序的可移植性,WinPcap提供了基于wpcap.dll的编程方式。这里,wpcap.dll不依赖于操作系统,它包含了一些其它高层的函数,比如:过滤器生成器、用户定义的缓冲区和高层特性(数据统计和构造数据包)。wpcap.dll能自动调用packet.dll。一个“高层”调用会被译成几个NPF系统调用。程序员一般使用wpcap.dll,只有在为数不多的程序中才直接使用packet.dll。2.6 MFC编程框架MFC (Microsoft Foundation Class Library)中的各种类结合起来构成了一个应用程序框架,它的目的就是让程序员

35、在此基础上来建立Windows下的应用程序,这是一种相对SDK来说更为简单的方法。因为总体上,MFC框架定义了应用程序的轮廓,并提供了用户接口的标准实现方法,程序员所要做的就是通过预定义的接口把具体应用程序特有的东西填入这个轮廓。Microsoft Visual C+提供了相应的工具来完成这个工作:AppWizard可以用来生成初步的框架文件(代码和资源等);资源编辑器用于帮助直观地设计用户接口;ClassWizard用来协助添加代码到框架文件;最后,编译,则通过类库实现了应用程序特定的逻辑。MFC类的封装构成MFC框架的是MFC类库。MFC类库是C+类库。这些类或者封装了Win32应用程序编

36、程接口,或者封装了应用程序的概念,或者封装了OLE特性,或者封装了ODBC和DAO数据访问的功能,等等,分述如下。对Win32应用程序编程接口的封装用一个C+ Object来包装一个Windows Object。例如:class CWnd是一个C+ window object,它把Windows window(HWND)和Windows window有关的API函数封装在C+ window object的成员函数内,后者的成员变量m_hWnd就是前者的窗口句柄。对应用程序概念的封装使用SDK编写Windows应用程序时,总要定义窗口过程,登记Windows Class,创建窗口,等等。MFC把

37、许多类似的处理封装起来,替程序员完成这些工作。另外,MFC提出了以文档-视图为中心的编程模式,MFC类库封装了对它的支持。文档是用户操作的数据对象,视图是数据操作的窗口,用户通过它处理、查看数据。对COM/OLE特性的封装OLE建立在COM模型之上,由于支持OLE的应用程序必须实现一系列的接口(Interface),因而相当繁琐。MFC的OLE类封装了OLE API大量的复杂工作,这些类提供了实现OLE的更高级接口。对ODBC功能的封装以少量的能提供与ODBC之间更高级接口的C+类,封装了ODBC API的大量的复杂的工作,提供了一种数据库编程模式。MFC类的继承首先,MFC抽象出众多类的共同

38、特性,设计出一些基类作为实现其他类的基础。这些类中,最重要的类是CObject和CCmdTarget。CObject是MFC的根类,绝大多数MFC类是其派生的,包括CCmdTarget。CObject 实现了一些重要的特性,包括动态类信息、动态创建、对象序列化、对程序调试的支持,等等。所有从CObject派生的类都将具备或者可以具备CObject所拥有的特性。CCmdTarget通过封装一些属性和方法,提供了消息处理的架构。 MFC中,任何可以处理消息的类都从CCmdTarget派生。针对每种不同的对象,MFC都设计了一组类对这些对象进行封装,每一组类都有一个基类,从基类派生出众多更具体的类。

39、这些对象包括以下种类:窗口对象,基类是CWnd;应用程序对象,基类是CwinThread;文档对象,基类是Cdocument,等等。程序员将结合自己的实际,从适当的MFC类中派生出自己的类,实现特定的功能,达到自己的编程目的。虚拟函数和动态约束MFC以“C+”为基础,自然支持虚拟函数和动态约束。但是作为一个编程框架,有一个问题必须解决:如果仅仅通过虚拟函数来支持动态约束,必然导致虚拟函数表过于臃肿,消耗内存,效率低下。例如,CWnd封装 Windows窗口对象时,每一条Windows消息对应一个成员函数,这些成员函数为派生类所继承。如果这些函数都设计成虚拟函数,由于数量太多,实现起来不现实。于

40、是,MFC建立了消息映射机制,以一种富有效率、便于使用的手段解决消息处理函数的动态约束问题。这样,通过虚拟函数和消息映射,MFC类提供了丰富的编程接口。程序员继承基类的同时,把自己实现的虚拟函数和消息处理函数嵌入MFC的编程框架。MFC编程框架将在适当的时候、适当的地方来调用程序的代码。本书将充分的展示MFC调用虚拟函数和消息处理函数的内幕,让读者对MFC的编程接口有清晰的理解。MFC的宏观框架体系如前所述,MFC实现了对应用程序概念的封装,把类、类的继承、动态约束、类的关系和相互作用等封装起来。这样封装的结果对程序员来说,是一套开发模板(或者说模式)。针对不同的应用和目的,程序员采用不同的模

41、板。例如,SDI应用程序的模板,MDI应用程序的模板,规则DLL应用程序的模板,扩展DLL应用程序的模板,OLE/ACTIVEX应用程序的模板,等等。这些模板都采用了以文档-视为中心的思想,每一个模板都包含一组特定的类。典型的MDI应用程序的构成将在下一节具体讨论。为了支持对应用程序概念的封装,MFC内部必须作大量的工作。例如,为了实现消息映射机制,MFC编程框架必须要保证首先得到消息,然后按既定的方法进行处理。又如,为了实现对DLL编程的支持和多线程编程的支持,MFC内部使用了特别的处理方法,使用模块状态、线程状态等来管理一些重要信息。虽然,这些内部处理对程序员来说是透明的,但是,懂得和理解

42、MFC内部机制有助于写出功能灵活而强大的程序。总之,MFC封装了Win32 API,OLE API,ODBC API等底层函数的功能,并提供更高一层的接口,简化了Windows编程。同时,MFC支持对底层API的直接调用。MFC提供了一个Windows应用程序开发模式,对程序的控制主要是由MFC框架完成的,而且MFC也完成了大部分的功能,预定义或实现了许多事件和消息处理,等等。框架或者由其本身处理事件,不依赖程序员的代码;或者调用程序员的代码来处理应用程序特定的事件。MFC是C+类库,程序员就是通过使用、继承和扩展适当的类来实现特定的目的。例如,继承时,应用程序特定的事件由程序员的派生类来处理

43、,不感兴趣的由基类处理。实现这种功能的基础是C+对继承的支持,对虚拟函数的支持,以及MFC实现的消息映射机制。3 基于Winpcap的单文档网络嗅探器的设计与分析3.1 系统设计实现的基本原理与过程3.1.1 基于winpcap捕获数据的机理运用以太网数据捕获的原理使得信息捕获系统能够拦截到我们所要的信息,这是捕获数据包的物理基础。在网络数据包的捕获过程中,首先,数据包捕获系统必须绕过操作系统的协议栈来访问在网络上传输的原始数据包,这就要求一部分程序要运行在操作系统核心内部,直接与网络接口驱动交互。这个部分是系统依赖的,在WinPcap 的解决方案里它是由内核级的数据包监听设备驱动程序NPF

44、实现的。WinPcap 开发小组针对不同版本的Windows 操作系统提供了不同的驱动。这些驱动不仅提供了基本的特性,例如抓包和injection;还有更高级的特性,例如可编程的过滤器系统和监视引擎等。其次,数据包捕获系统必须有用户级的程序接口,通过这些接口,用户程序可以利用内核驱动提供的高级特性。在WinPcap 的解决方案中是由两个不同的库:Packet.dll 和Wpcap.dll 库来实现的。WinPcap 的优势在于提供了一套标准的抓包接口与libpcap 兼容,可使得原来许多UNIX 平台下的网络分析工具快速移植过来便于开发各种网络分析工具,充分考虑了各种性能和效率的优化,包括对于

45、NPF 内核层次上的过滤器支持, 支持内核态的统计模式, 提供了发送数据包的能力。前者提供了一个底层API, 伴随着一个独立于Windows 操作系统的编程接口,这些API 可以直接用来访问驱动的函数;后者导出了一组更强大的与libpcap 一致的高层抓包函数库(capture primitives)。这些函数使得WinPcap 在数据包的捕获过程中可以以一种与网络硬件和操作系统无关的方式进行。3.1.2 基于winpcap数据包捕获的过程在利用WinPcap 捕获分析网络数据时, 主要是调用Packet.dll 和Wpcap.dll 中提供的API 函数进行操作。以下是基于WinPcap 的

46、网络数据包捕获流程及相应的WinPcap 库函数。 获取网络适配器信息利用WinPcap 捕获数据包的第一步是要获得本地的网络适配器(网卡)列表。WinPcap 提供Pcap_findalldevs()和Pcap_findalldev_ex()这两个函数来实现些功能,这两个API 函数都返回一个pcap_if 结构列表,列表的每项内容都含有全面的网卡信息, 尤其是字段名字和含有名字的描述以及有关驱动器的易读信息。 设置并编译过滤器WinPcap 使用的过滤规则兼容Tcpdump 的过滤规则, 它提供一种高效的方法来捕获网络数据包的某些数据, 且常和系统的捕获机制相集成。函数Pcap_compi

47、le()和Pcap_setfilter()用来实现过滤数据的功能。Pcap_compile()来编译一个过滤设备,它通过一个高层的boolean 型变量和字串产生一系列的能够被底层驱动所解释的二进制编码。boolean 表示语法能够在这个文件的过滤表示语法中找到。pcap_setfilter()用来联系一个在内核驱动上过滤的过滤器,这时所有网络数据包都将流经过滤器,并拷贝到应用程序中。 打开网络设备使用函数Pcap_open()或者Pcap_open_line()。函数有三个参数snaplen、promisc、to_ms。snaplen 用于指定要捕获数据包的长度,最大为65535,如果设定一

48、个值,则捕获到大于这个设定值的数据时,后面的数据会被截断掉。Promisc 表示是否把网卡设置为混杂模式,如果是1 表示设为混杂模式,在通常情况下网卡只接受发往它的数据包而忽略发往其他主机的数据包。但网卡处于混杂模式时它将接收所有的流经它的数据包,这就意味着在共享介质的情况下我们可以捕获到其它主机的数据包;大部分的数据包捕获程序都将混杂模式设为默认。to_ms 参数指定读数据的超时控制,超时以毫秒计算,当在超时时间内网卡上没有数据到来时对网卡的读操作将返回。 捕获数据包一旦网卡被打开,就可以调用Pcap_next(),Pacp_next_ex()或Pcap_loop()进行数据包的捕获。Pca

49、p_next()和Pacp_next_ex()表示捕获一个可用数据包就返回;而Pcap_loop()表示捕获多个数据包,可以循环捕获数据包,直到出现错误为止。这三个函数都有返回一个指向Pcap_pkthdr 结构的指针,Pcap_next()与Pcap_next_ex()的功能相似,不过后者只在win32 环境下运行。读取离线数据包 pcap_dump_open()被用来打开一个savefile以供写入数据包。pcap_open_offlin()被用来打开savefile,并用pcap_next()来逐条读取数据包。3.2 系统功能设计本系统的基本功能为实现网络数据包的捕获,并将其数据内容解析

50、显示;网络数据包捕获功能主要负责从网络中捕获和过滤数据,这可以通过调用Winpcap提供的丰富的API函数来实现;数据解析及显示部分主要负责界面数据转化、解析、处理、格式化、协议分析等,这一部分主要通过MFC来设计一个单文档图形用户界面GUI,解析结果将通过MFC的类库显示到GUI中。3.3 系统架构设计网络嗅探器的整体设计由三个模块组成,自底向上分别是嗅探器设置模块,数据包捕获模块,解析和显示模块;嗅探器设置模块主要调用Winpcap提供的API,分为获取网络设备信息,设置并编译过滤器,打开网络设备 三个步骤;数据包捕获模块创建了新的线程,利用了Winpcap的非回调函数pcap_next_

51、ex()函数从Winpcap底层驱动的数据缓冲区中读取数据包。并将数据包存储在系统临时文件中,以便之后的分析。用pcap_open_offline()函数从离线文件中读取包。读取到的任意一个符合捕获条件数据包,将其内容解析,并显示本数据包;捕获完成后,进入解析和显示模块。网络嗅探器总体结构如图3.1解析和显示模块解析和显示模块网络数据包捕获网络数据包捕获嗅探器设置模块嗅探器设置模块以太网网络适配器以太网网络适配器 图3.1 网络嗅探器总体结构3.4 子系统与模块设计3.4.1 网络嗅探器设置模块该部分分为三个子过程:1)获取已连接的网络设备列表,WinPcap提供了 函数,这个函数返回一个 结

52、构的链表, 每个这样的结构都包含了一个适配器的详细信息。2)打开网络设备,Winpcap提供了pcap_open()函数,该函数第一参数制定要捕获数据包的哪些部分,第二参数用来制定适配器是否为混杂模式,第三参数为读取数据的超时时间,当适配器被打开后,就可以进行捕获工作了;3)设置过滤器,Winpcap中用来过滤数据包的函数是 和 。 它将一个高层的布尔过滤表达式编译成一个能够被过滤引擎所解释的低层的字节码。 将一个过滤器与内核捕获会话相关联。当 被调用时,这个过滤器将被应用到来自网络的所有数据包,并且,所有的符合要求的数据包 (即那些经过过滤器以后,布尔表达式为真的包) ,将会立即复制给应用程

53、序。3.4.2 网络数据包的捕获模块该部分创建了一个用于捕获数据包的线程,在该线程中调用Winpcap提供的pcap_next_ex()函数从底层驱动数据缓冲区中读取数据包,该函数接受已打开的网络设备句柄,返回捕获数据包的实体。并用pcap_dump()函数将每一个数据包写入临时文件中。3.4.3 解析和显示模块该部分在接收到用户发出的捕获完成消息后,将数据包从离线文件中逐条取出并进行解析和显示。将解析完毕数据包中的各项内容填入已经预先声明的协议的数据结构中,包括(序号,捕获时间,以太帧长度,传输层协议,源IP地址,目的IP地址,源MAC地址,目的MAC地址),然后将数据结构添加到列表视图中。

54、4 系统详细设计与实现4.1 数据结构的设计以太帧协议首部/* 以太网首部 */typedef struct eth_headeru_char destMac6; /源MAC地址u_char sourceMac6;/目的MAC地址u_char ethType2; /类型eth_header;IP协议首部/* IPv4 首部 */typedef struct ip_header u_char ver_ihl; / 版本 (4 bits) + 首部长度 (4 bits) u_char tos; / 服务类型(Type of service) u_short tlen; / 总长(Total len

55、gth) u_short identification; / 标识(Identification) u_short flags_fo; / 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits) u_char ttl; / 存活时间(Time to live) u_char proto; / 协议(Protocol) u_short crc; / 首部校验和(Header checksum) ip_address saddr; / 源地址(Source address) ip_address daddr; / 目的地址(Destination

56、 address) u_int op_pad; / 选项与填充(Option + Padding)ip_header;TCP协议首部/* TCP首部 */typedef struct tcp_header u_short sport; /* 源端口 */ u_short dport; /* 目的端口 */ u_int seq; /* 序号 */ u_int ack; /* 确认号 */ u_short off_res; /* 数据偏移+保留+URG+ACK+PSH+RST+SYN+FIN */#define TH_FIN 0 x01 /* FIN:释放一个连接*/#define TH_SYN

57、0 x02 /* SYN:发起一个连接*/#define TH_RST 0 x04 /* RST:重建连接*/#define TH_PSH 0 x08 /* PSH:接收方应该尽快将这个报文段交给应用层*/#define TH_ACK 0 x10 /* ACK:确认序号有效。 */#define TH_URG 0 x20 /* URG:紧急指针(urgent pointer)有效*/ u_short window; /* 窗口 */ u_short checksum; /* 校验和 */ u_short urp; /* 紧急指针 */tcp_header;UDP协议首部/* UDP 首部*/t

58、ypedef struct udp_header u_short sport; / 源端口(Source port) u_short dport; / 目的端口(Destination port) u_short len; / UDP数据包长度(Datagram length) u_short crc; / 校验和(Checksum)udp_header;IP地址typedef struct ip_address u_char byte1; u_char byte2; u_char byte3; u_char byte4;ip_address;4.2 全局变量与函数的声明pcap_t* adh

59、andle; BOOL isStart = FALSE;/是否启动了捕获程序int m_filter(0); /定义的过滤器int m_pacNum(0); /捕包总数const char *m_filepath;/存储文件路径BOOL m_cinpromiscuousmode(false); /是否为混杂模式UINT Cappacketlivethread(LPVOID pParam); /捕获数据包线程pcap_dumper_t *dumpfile;/open_dump指针4.3 嗅探器界面设计在CMainFrame类里面重载OnCreateClient函数,添加如下的代码:m_split

60、ter.CreateStatic(this,2,1);m_splitter.CreateView(0,0,RUNTIME_CLASS(CSetupdlgView),CSize(400,400),pContext);m_splitter.CreateView(1,0,RUNTIME_CLASS(CViewDown),CSize(200,200),pContext); m_splitter是一个声明的CSplitterWnd变量,来将主窗口切分为两部分。视图的上面部分是从CListView派生的,用来显示捕获到的数据包的信息,下面部分嵌入了一个从CFormView继承的Dialog,用来响应用户单

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论