网络监听软件是提供给网络安全管理人员进行安全管理的工具,可以用来监视网络的状态、数据流动情况以及网络上传输的信息,以获取有用信息。作为黑客来说,通过网络监听可以获取其所需信息(比如密码等);对黑客活动和其他网络犯罪进行侦察、取证时,可以使用网络监听技术来获取必要的信息。因此,在目前研究和使用网络监听技术及相关工具,对于防护网络安全、打击网络犯罪具有重要的现实意义。
本局域网监听软件主要利用Winpcap和Jpcap等工具进行开发,使用Java语言在Eclipse 3.2环境下进行开发。软件主要实现了对网络上的数据进行监听,并分析出每一协议层的传输数据和协议层上主要字段的数据,然后将其显示出来,同时进行动态更新;另外,添加了一些附加功能(指定对象监听、饼状图显示、界面选择等)。经过测试与分析,说明了该软件运行稳定、可靠,具有一定的实际应用价值。
1 引言
1.1 课题背景
网络监听,在网络安全上一直是一个比较敏感的话题,作为一种发展比较成熟的技术,网络监听在协助网络管理员监测网络传输数据,排除网络故障等方面具有不可替代的作用,因而一直倍受网络管理员的青睐。然而,在另一方面网络监听也给以太网安全带来了极大的隐患,许多的网络入侵往往都伴随着以太网内网络监听行为,从而造成口令失窃,敏感数据被截获等等连锁性安全事件。
随着互联网技术的迅猛发展,网络给人们带来了很多便利,但是网络在给人们带来许多便利的同时,也给人们带来了最担忧的网络安全问题。保证网络及应用系统的安全也成了人们最为关心的问题。
网络监听技术就是提供给网络安全管理人员进行管理的工具,可以用来监视网络的状态、数据流动情况以及网络上传输的信息,以获取有用的信息。作为黑客来说,通过网络监听可以获取其所需的信息(比如密码等);对黑客活动和其他网络犯罪进行侦察、取证时,可以使用网络监听技术来获取必要的信息。因此,在目前研究和使用网络监听技术及相关工具,对于防护网络安全、打击网络犯罪具有重要的现实意义。
1.2 本课题研究的意义
我国的网络正在快速发展中,相应的问题也就显现出来,网络管理及相应的应用自然将越发重要,而监听技术正是网络管理和应用的基础,其意义当然重要,放眼当前相关工具,Linux 有snort tcpdump ,snift 等,window 有nexray, sniffer等无一不是国外软件,随着中国网络的发展,网络监听系统必将大有用武之地,因此监听技术的研究已是时事的要求。
中国入世,各种针对盗版的打击力度和对于正版软件的保护力度都将大大加强,windows的盗版软件随处可见的现象将会一去不返,面对这样的情况,大部分的公司只有两种选择:要么花大价钱向微软购买正版软件,要么是用开元操作系统Linux,特别是重要部门,如国家机关,政府部门,难道要把自己的办公系统操纵在国外大公司手里?北京的政府办公系统已经转用红旗Linux,而且Linux的界面也在不但的改进,更加友好,易操作,有理由相信Linux将在我国大有作为,这也是研究Linux下网络监听的原因。
1.3 本课题的研究方法
本毕业设计的目的主要是为了检查对以前所学知识(包括以前所学的一些关于网络技术、编程技术、网络与信息安全等知识)综合运用的能力,设计开发一个局域网监听软件。
在本系统的开发使用Eclipse 3.2开发工具,利用Java语言来编写一个具备数据包统计和分析功能的局域网监听软件。
由于核心Java API不能访问底层的网络数据,因此在使用Java编写网络监听程序时就必须借助一些工具。本设计借助Winpcap和Jpcap这两个工具来对网络底层进行访问,帮助实现网络监听程序。
1.4 本论文主要工作
本文主要介绍局域网监听软件设计与开发。在进行设计之前,必需了解一些必要的相关知识,所以本文先从基础知识开始介绍,然后一步一步地深入,最后开发出具有一定功能的网络监听软件。
本文的第二章对网络监听软件的设计有一个全面的需求分析,在写需求分析的时候,主要是对本软件的实现目标、运行环境和功能做一个具体的规划,其次对本软件的发展方向也做了一定的要求。
在第三章中,首先对网络监听的原理进行简单的介绍,了解到在网络中的数据是怎样的进行传输的、每一层的协议的作用等等。然后再就本次开发所必需的辅助工具(Winpcap和Jpcap)和它们在局域网监听软件中所起的作用,以及它们的使用方法做了一定的介绍。
具备了一定的基础知识后,在第四章中对局域网监听软件的设计做了一个整体的规划,对本次设计的进程有了一个初步的框架,然后再综合所学知识进行具体的设计。
在第五章中,开始介绍具体的设计步骤,首先将编写三个不同的包,每一个包完成的功能有所不同,但又互相联系,然后再编写主类和一些能将每个包,每个类联系起来的类,让其实现预期的效果,最终完成初步的设计。
第六章的主要工作是介绍如何测试所编写的程序是否能正常运行,确保所设计的程序能完成相关的功能,不断的对软件进行完善。测试完毕后,将所有代码进行封装打包,完成本次设计。
在本文的最后一章,主要介绍的是如何使用该软件,附带一些软件运行时的图片,对用户做一个具体的介绍。
2 需求分析
2.1 需求分析概述
需求分析是指理解用户需求,就软件功能与客户达成一致,估计软件风险和评估项目代价,最终形成开发计划的一个复杂过程。从广义上理解:需求分析包括需求的获取、分析、规格说明、变更、验证、管理的一系列需求工程。图1为需求分析的具体步骤。
需求分析之所以重要,就因为它具有决策性,方向性,策略性的作用,在软件开发的过程中具有举足轻重的地位。在一个大型软件系统的开发中,他的作用要远远大于程序设计。
2.2本软件的需求分析
2.2.1 本软件实现的目标
虽然计算机网络给人们带来了巨大的便利,但互联网是一个面向大众的开放系统,对信息的保密和系统的安全考虑得并不完备,存在着安全隐患,网络的安全形势日趋严峻。
因此,在Internet安全隐患中扮演重要角色之一的网络监听软件受到越来越大的关注,大多数的黑客为了探测内部网上的主机并取得控制权,甚至有些黑客为了控制整个网络,从而安装特洛伊木马和后门程序,并清除记录。他们经常使用的手段是安装网络监听软件。
在黑客和违法人员进行一些非法的操作(例如,盗取用户的密码和相关信息等)时,执法人员也可以利用同样的方法对其进行侦察和取证,并对其进行相关的处置,达到保护用户的重要资料和维护用户的个人利益,并保证网络的正常运行和预防一些违法操作。
本软件的设计就是为了达到基本的维护网络安全的作用,对网络上传输的数据进行捕获,然后从中得到有用的信息,以此来判断是否是恶意的信息,并对其进行过滤等相关操作,起到保护网络安全的作用。
2.2.2 本软件的运行环境要求
在编写本软件前,作者首先确定了所使用的语言——Java,并在开发工具Eclipse 3.2下进行开发,所以首先应该配置好Java的运行环境(安装j2sdk1.4.0或jre1.4.0以上版本),并在命令提示符检查是否正确配置好Java的运行环境(输入java或javac)。
由于Java API语言不能访问底层的网络数据,所以使用一些工具(如Winpcap和Jpcap)来帮助实现对底层网络数据的访问。在此,本软件必须首先安装Winpcap,然后在jre中配置好Jpcap的环境,值得注意的是,以上两个工具都是开元的,所以在很多地方可以查询到它们的使用方式。
2.2.3 本软件的功能要求
对于这个程序,开发人员希望它达到以下几个功能:
(1)能够截取本网段中传输的数据包;
(2)运用不同TCP/IP体系层次的协议解析类,将数据包逐步分解;
(3)将分析结果显示出来(协议字段、数据内容等);
(4)对截获的数据包的数量和大小进行统计(饼状图等);
(5)对指定的IP地址进行单独监听;
(6)可以进行界面选择。
2.2.4 本软件功能的扩充
完成了以上功能,只是初步达到了现有阶段的要求,在以后的操作中,可能会遇到许多更为复杂的问题,为此,在设计软件的同时,也应该根据系统的性能来分析将来很可能会提出来的要求,这样做的目的是在设计过程中对系统将来可能的扩充和修改预做准备,以便一旦需要时能比较容易地进行一些扩充和修改。
本软件虽然能够捕获到本网段的数据,并可以对捕获的数据进行简单的分析,还可以进行指定对象的监听和将结果显示出来等功能,但在实际的运用中,用户肯定会遇到更多的问题,以下是对本软件的扩充性能的一些初步预计:
(1)自动获取本机和网关的IP和MAC地址;
(2)监视所有主机的收发邮件记录收发邮件的Email地址、日期、主题等;
(3)对捕获到的数据进一步分析,得到非法数据;
(4)可以对局域网内的计算机进行一些简单的操作。
3 理论基础与相关工具介绍
3.1 网络监听原理介绍
Ethernet协议(以太网协议)的工作方式是将要发送的数据包发往连接在一起的所有主机。在包头中包括有应该接收数据包的主机的正确地址,因为只有与数据包中目标地址一致的那台主机才能接收到数据包,但是当主机工作在监听模式下,不管数据包中的目标物理地址是什么,主机都将可以接收到。
数据包并不能在协议栈的高层直接发送出去,要发送的数据包必须从TCP/IP协议的IP层交给网络接口,也就是所说的数据链路层。网络接口不会识别IP地址的。因此,在网络接口由IP层传输过来的带有IP地址的数据包将增加了一部分以太帧的帧头的信息。在帧头中,有两个域分别为只有网络接口才能识别的源主机和目的主机的物理地址,这是一个48位的地址,这个48位的地址是与IP地址相对应的,换句话说就是一个IP地址也会对应一个物理地址。
传输数据时,包含物理地址的帧从网络接口(网卡)发送到物理的线路上,如果局域网是由一条粗缆或细缆连接而成,则数字信号在电缆上传输,能够到达线路上的每一台主机。当使用集线器时,由集线器再发向连接在集线器上的每一条线路,数字信号也能到达连接在集线器上的每一台主机。当数字信号到达一台主机的网络接口时,正常情况下,网络接口读入数据帧,进行检查,如果数据帧中携带的物理地址是自己的或者是广播地址,则将数据帧交给上层协议软件,也就是IP层软件,否则就将这个帧丢弃。对于每一个到达网络接口的数据帧,都要进行这个过程。
当连接在同一条电缆或集线器上的主机被逻辑地分为几个子网的时候,那么要是有一台主机处于监听模式,它还将可以接收到发向与自己不在同一个子网(使用了不同的掩码、IP地址和网关)的主机的数据包,在同一个物理信道上传输的所有信息都可以被接收到。
以太网上的数据帧主要涉及TCP/IP协议,针对以下几个协议的分析:IP,ARP,RARP,IPX,其中重点在于IP和 ARP协议,这两个协议是多数网络协议的基础。
在本软件的监听过程中,将监听到的数据包利用工具和所编写的方法进行逐层分析,并解析出每一层、每一协议、每一字段的数据,从中得到自己想要的信息,最后将其显示出来,并进行动态的更新。
3.2 TCP/IP的层次结构
3.2.1 OSI 与 TCP/IP体系结构的比较
OSI(Open System Interconnect)是开放式系统互联,为了解决不同体系结构的网络的互联问题,国际标准化组织ISO于1981年制定了开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM)。OSI把网络通信的工作分为7层,它们由低到高分别是物理层(Physical Layer),数据链路层(Data Link Layer),网络层(Network Layer),传输层(Transport Layer),会话层(Session Layer),表示层(Presen tation Layer)和应用层(Application Layer)。每层完成一定的功能,每层都直接为其上层提供服务,并且所有层次都互相支持。
TCP/IP协议(Transmission Control Protocol/Internet Protocol)是传输控制/网际协议,这个协议是Internet国际互联网络的基础。TCP/IP通讯协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。这4层分别为:
(1)应用层:应用程序间沟通的层,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等;
(2)传输层:在此层中,它提供了节点间的数据传送服务,如传输控制协议(TCP)、用户数据报协议(UDP)等,TCP和UDP给数据包加入传输数据并把它传输到下一层中,这一层负责传送数据,并且确定数据已被送达并接收;
(3)互连网络层:负责提供基本的数据封包传送功能,让每一块数据包都能够到达目的主机(但不检查是否被正确接收),如网际协议(IP);
(4)网络接口层:对实际的网络媒体的管理,定义如何使用实际网络(如Ethernet、Serial Line等)来传送数据。
TCP/IP各层的描述如表1所示。
OSI模型与TCP/IP协议的区别如下:
(1)TCP/IP一开始就考虑到多种异构网的互联问题,并将网际协议IP作为TCP/IP的重要组成部分。但ISO和CCITT最初只考虑到全世界都使用一种统一的标准公用数据网将各种不同的系统互连在一起。后来,ISO认识到了网际协议IP的重要性,然而已经来不及了,只好在网络层中划分出一个子层来完成类似TCP/IP中的IP的作用;
(2)TCP/IP一开始就对面向连接服务和无连接服务并重,而OSI在开始只强调面向连接这一种服务。一直到很晚OSI才开始制定另一种无连接服务的有关标准;
(3)TCP/IP较早就有较好的网络管理功能,而OSI到后来才开始考虑这个问题。
OSI 与 TCP/IP体系结构的比较如图2所示。
在许多文献中,也常见到TCP/IP的四层协议的表示方法。例如,在讨论两个主机通过两个网络用路由器连在一起时,可以使用如图3所示的层次关系。图3中的逻辑链路控制和物理层都简化为网络接口层。实际上,现在插在主机中的网络接口板上的硬件和软件就是实现了数据链路层和物理层这两层的功能。应当注意的是,在网络互连中起重要作用的路由器则没有应用层和运输层,其数据链路层和物理层也是在网络接口板上实现的。
3.2.3 使用TCP/IP进行通信的示意图
在TCP/IP的应用层协议使用的是客户-服务器方式。客户(Client)和服务器(Server)都是指通信中所涉及的两个应用进程。客户-服务器方式所描述的是进程之间服务和被服务的关系。当A进程需要B进程的服务时就主动呼叫B进程,在这种情况下,A是客户而B是服务器。这里最重要的特征就是:客户是服务请求方,服务器是服务提供方。
客户与服务器的通信关系一旦建立,通信就可是双向的,客户和服务器都可以发送和接收信息,如图4所示。
3.3 Winpcap简介
Winpcap(windows packet capture)是Windows平台下一个免费,公共的网络访问系统。开发Winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。它提供了以下的各项功能:
(1)捕获原始数据报,包括在共享网络上各主机发送/接收的以及相互之间交换的数据报;
(2)在数据报发往应用程序之前,按照自定义的规则将某些特殊的数据报过滤掉;
(3)在网络上发送原始的数据报;
(4)收集网络通信过程中的统计信息。
Winpcap的主要功能在于独立于主机协议(如TCP/IP)而发送和接收原始数据报。也就是说,Winpcap不能阻塞、过滤或控制其他应用程序数据报的发收,它仅仅只是监听共享网络上传送的数据报。因此,它不能用于服务质量QoS调度程序或个人防火墙。目前,Winpcap开发的主要对象是Windows NT/2000/XP,这主要是因为在使用Winpcap的用户中只有一小部分使用Windows 95/98/Me,并且微软也已经放弃了对win9x的开发。其实Winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。
Winpcap提供给用户两个不同级别的编程接口:一个基于libpcap的wpcap.dll,另一个是较底层的packet.dll。对于一般的要与UNIX平台上libpcap兼容的开发来说,使用wpcap.dll是当然的选择。下面几个库是与lipcap相关的:libnet1.0.2——数据包的发送构造过程;libnids——实现了ids的一些框架;libicmp——icmp数据包处理。
操作系统拦截数据包的技术有很多,现在很多文章都是介绍编写IM DRIVER阿在NDIS中间层对MINIPORT(网卡驱动程序)和协议驱动程序之间的数据包进行拦截。这是微软提供的一种技术但编写该过滤程序拦截程序非常地复杂,安装也很麻烦。
现在简单的介绍基于NDIS包拦截技术。NDIS协议驱动程序是通过填写一张NDIS_PROTOCOL_CHARACTERISTICS的表,并调用NDIS API函数NdisRegisterProtocol进行注册。现在来关注一下NDIS_PROTOCOL_CHARACTERISTICS这张表,这张表中存有所有协议驱动程序与底层的派发函数的入口。如BindAdapterHandler,SendHandler, ReceiveHandler等,当网卡有数据包进入时,会通过表中ReceiveHandle或ReceivePacketHandler通知协议驱动程序有一个该协议的数据包进入,反之协议驱动程序是通过Send Handler或SendPacketsHandler函数向网卡驱动发送数据包到网络上去的。虽然在程序中是调用NdisSend或NdisSendPackets函数发送,但是通过查看NDIS.H的头文件里对这两个函数的定义就知道了,它们都是一个宏定义,实际还是通过这表中Send Handler或SendPacketsHandler发送的。现在要做的事情应该很清楚了,只要能够将每一个协议程序所填写的NDIS_PROTOCOL_CHARACTERISTICS表里的派发函数指向自己的函数,就能成功的对数据包进行拦截。
Winpcap也是用NDIS(Windows的通信协议程序(比如TCP/IP)和网络设备驱动器之间通信的规范)的,将自己注册为一个协议处理驱动。Winpcap的使用非常方便,但是它有一个致命的缺陷就是只适用于共享式以太网络,对于交换式网络下的数据则无能为力。经过测试,在使用交换机连接的局域网下,Winpcap只能监听到本网段内的数据,而对于来自其他网段的数据则无法监听,除非你把probe接到交换机之前或者接到交换机的console口上,不过那样的弊端是显而易见的,所以,Winpcap的应用还是有局限性的。
3.4 Jpcap简介
由于核心Java API不能直接访问网络底层,因此需要借助一种工具来为Java和网络底层提供一个桥梁。Jpcap就是一种提供在Windows或UNIX系统上进行网络底层访问的Java API。Jpcap不是一种纯粹的Java解决方案,它依赖本地库的使用。在Windows 或 UNIX上,用户必须有必要的第三方库,分别是WinPcap或libpcap。
Jpcap的工作原理是使用一个事件模型让你对数据包进行处理。首先必须创建一个执行接口jpcap.JpcapHandler的类:
public class JpcapTip implements JpcapHandler {
public void handlePacket(Packet packet){
System.out.println(packet);
}
}
为了捕获包,用户需要告诉Jpcap想用哪个网络设备来监听。API提供了jpcap.Jpcap. getDeviceList()方法以满足这一目的。这个方法返回一列字符串,用户可以像如下的方法使用它:
String[] devices = Jpcap.getDeviceList();
一旦用户有了一个设备名称的目录,用户必须选取一个用来监听:
String deviceName = devices[0];
选择一个设备之后,通过Jpcap.openDevice()方法打开它。openDevice()方法需要四个参数:即将打开的设备名,从设备上一次读取的最大字节数,说明是否将设备设为混杂模式(可以接受任意的包)的Boolean值和以后调用processPacket()方法要使用到的超时值。
Jpcapjpcap = Jpcap.openDevice(deviceName, 1028, false, 10000);
openDevice()方法将一个参数返回到用以捕获的Jpcap对象。既然有了Jpcap实例,可以调用processPacket()或loopPacket()开始监听了。这两种方式都带有两个参数:捕获的最大包数可以是−1(说明没有限制);执行JpcapHandler的一个类的实例。
如果调用processPacket(),那么Jpcap将一直捕获包,直到超过openDevice中规定的时限或达到了规定的最大包数;loopPacket()则将一直捕获包,直到达到最大包数,如果没有最大数限制,它将永远运行下去。就像下面这样调用:
jpcap.loopPacket(-1, new JpcapTip());
为了执行可用类,必须确保虚拟机可以找到Jpcap的本地库。在Windows上,如果jpcap.dll在库地址目录中,Java命令如下:
java -Djava.library.path=lib -cp lib\jpcap.jar;. JpcapTip
运用Jpcap将会使开发人员在利用Java开发网络程序的时候,不必过多关注与底层网络的接口复杂的连接细节,而注重在对Jpcap简单而强大接口的使用以及程序界面和功能。
4 设计思路
4.1 设计框架图
经过对Winpcap和Jpcap的了解,知道了如何截获数据包并进行处理,现在就要编写代码,将这些步骤嵌入到一个框架中,将数据包的处理结果显示出来,根据本软件所要实现的功能,本设计所需要实现的类结构如图5所示。
4.2 设计步骤
4.2.1 整体规划
现在对程序进行如下设计:
(1)使用Eclipse 3.2开发的基于J2SE Swing的图形用户界面程序;
(2)允许多个窗口同时运行,因此用向量来存储已创建的窗口。为了使各个窗口间的监听不相互干扰,因此为每一个监听过程都开辟一个新的线程,在线程中完成从截获数据包到分析数据包到最后将结果显示出来的全部过程。
(3)将所有截获的数据包用向量存储,当然定义了数量上限。预计监听结果的显示如下:使用JTable组件显示每条分析完后的数据包,并进行动态更的新;若选中表格中的某一条记录时,则在JTree组件中将它所具有的全部协议显示出来,父结点为协议名,子结点为协议字段名,叶子结点为字段取值,同时将数据包的内容转换为字符串显示在JTextArea组件中。
4.2.2 程序运行流程
(1)程序的开始
程序主类为JSniffer,整个程序由此类中的main()函数进入,进行初始化,出现主界面,即JDFrame类的实例,然后等待主界面中的事件响应。
(2)准备监听
当主界面中执行开始监听事件时,创建JDCaptor类实例,这个类实际上就是数据包截获器。JDCaptor类首先调用JDCaptureDialog类,这是一个选择设备对话框,在JDCaptureDialog中使用Jpcap.getDeviceList()和Jpcap.getDeviceDescription()获取设备,根据界面选择设备,然后使用openDevice函数打开设备,返回Jpcap对象给调用它的JDCaptor实体。
(3)截获数据包
JDCaptor类开启一条线程,用来进行截获数据包处理。在此线程中使用刚才得到的Jpcap对象的processPacket()函数截获数据包。
(4)分析数据包
使用Jpcap类的包处理接口JpcapHandler handlePacket()进行截获的数据包的初步处理,每截获一个数据包都放入数据包向量packets中,则packets中存放的就是一次监听过程中所监听到的所有数据包。然后将packets传递给analyzer包中的所有类,即每截获一个数据包,就用所有已经定义的协议进行分析。
(5)分析结果显示
使用JTable控件来显示截获的数据包进过分析后的信息,每分析完一条,显示一条,至于显示哪些信息,由菜单中的“协议查看”下面的选项来决定。当执行选择table中某一行的事件时,用tree控件来显示此数据包对应于各层的协议,并用textarea控件将此数据包的内容转换为字符串完整的显示。
(6)流量统计
使用向量来存储每一个协议的所有的数据包,每分析完一个数据包后,在它所包含的协议的向量中加一。然后绘制每一层协议的饼状图,饼状图动态更新。
(7)数据更新
使用Timer类的start(),setRepeats()来进行动态更新,并通过此类中的事件响应来进行更新时的操作,即提示表格更新。
(8)指定对象监听
指定对象监听就是使用JSourceDialog来得到指定监听的主机的IP地址,监听内容是源IP为指定IP的数据包,如果符合条件则处理,不符合则丢弃。这个过滤处理在分析数据包JpcapHandler handlePacket()中完成。
5 具体实现步骤
5.1使用Eclipse 3.2创建项目
5.1.1 创建项目
使用Eclipse 3.2创建JSniffer工程。单击“文件->新建->项目”,在弹出的“新建项目”对话框中选择Java项目,在项目名中填写项目名为“JSniffer”,如图6所示。
5.1.2 创建包
在项目“JSniffer”上单击右键,选择“新建->包”,在弹出的“新建Java包”对话框中填写包名为“analyzer”,在以后的编写过程中,还需创建“stat”、“ui”、“graph”包,在这就不依依介绍了,创建过程类同“analyzer”包的创建,如图7所示。
5.1.3 创建类
在包“analyzer”上单击右键,选择“新建->类”,在弹出的“新建Java类”对话框中填写类名称,如图8所示。
5.2 analyzer包的设计
5.2.1 analyzer包的作用
analyzer包的作用是根据不同协议的结构格式设计相应的数据包解析类,然后对于传送给解析类的数据包进行相应协议结构的解析,即分析出协议中各个字段的内容。
在本程序中预计对8个协议进行解析,为此需要定义8个解析类再加上一个用于返回截获数据包信息(如截获时间,大小等)的类。
协议与类的对应关系如表2所示。
表2 协议与类的对应关系
TCP/IP体系层次 | 协 议 名 | 数据包解析类名 |
主机网络层 | Ethernet Frame | EthernetAnalyzer |
互联层 | IPv4 | IPv4Analyer |
IPv6 | IPv6Analyzer | |
ARP | ARPAnalyzer | |
ICMP | ICMPAnalyzer | |
传输层 | TCP | TCPAnalyzer |
UDP | UDPAnalyzer | |
应用层 | HTTP | HTTPAnalyzer |
返回类 | 显示数据包被截获相关信息 | PacketAnalyzer |
5.2.2 analyzer包中各个类的作用与实现方式
在analyzer包中,针对不同的TCP/IP层次,编写不同的分析类,每一个类中都将每一协议的重要字段都进行定义,并将进行逐步分析,得到每一字段的数据值,下面将介绍在这个包中每个类的作用和编写思路:
(1)JDPacketAnalyzer.java
这是一个抽象类,其功能主要有两个,定义静态常量用来表示TCP/IP体系中的各层次,然后定义不同协议数据包分析类中的公用函数,定义每一个协议层,并定义一些方法,是所有分析类的父类。
(2)EthernetAnalyzer.java
Ethernet Frame是主机网络层(数据链路层),属于数据链路层(DATALINK_LAYER),在这一层中,定义了主机网络层类型(Frame Type)、源MAC地址(Source MAC)、目的MAC地址(Destination MAC),用于最底层数据包的解析类。
(3)IPv4Analyzer.java
此类的功能为解析IPv4协议数据包,为相应字段赋值。在类中定义一个字符串常量valueNames用来存储IPv4协议中所有的字段名;在解析之前首先要判断所接收的数据包是否属于IPv4协议,因此定义函数isAnalyzable,运用“instance of”语句判断接收的数据包是否与jpcap包中定义的IPPacket类相符合;定义函数analyze用于解析数据包,其原理也是用jpcap包中定义的IPPacket类对接收到的数据包进行强制转换,然后将IPPacket类中相应的成员赋给相应的字段,完成解析。
(4)IPv6Analyzer.java
IPv6将地址从IPv4的32bit增大到了128bit,首部长度固定为40字节,IPv6的一个新的机制是支持资源预分配,并且允许路由器将每一个数据报与一个给定的资源分配相联系。IPv6提出流(flow)的抽象慨念。所谓"流"就是互联网上从特定源点到特定终点(单播或多播)的一系列数据报(如实时音频或视频传输),而在这个"流"所经过的路径上的路由器都保证指明的服务质量,所有属于同一个流的数据报都具有同样的流标号。
此类同IPv4Analyzer.java类中的方法类似。
(5)ARPAnalyzer.java
此类用于对ARP(Address Resolution Protocol)地址解析协议和RARP(Reverse Address Resolution Protocol)逆地址解析协议层的数据进行分析,ARP是工作在IP层与数据链路层之间的一个桥梁,起的作用是查询给定的IP地址所对应的网卡物理地址(MAC地址)。
此类同IPv4Analyzer.java类中的方法类似。
(6)ICMPAnalyzer.java
ICMP(Internet Control Message Protocol)Internet控制报文协议,传递差错报文以及其他需要注意的信息,种类有两种:ICMP差错报告报文和ICMP询问报文,ICMP报文是在IP数据报内部被传输的,前4个字节是统一的:类型,代码,检验和;接着4个字节的内容与ICMP的类型有关;再后面是数据字段,其长度取决于ICMP的类型。ICMP报文的代码字段是为了进一步区分某种类型中的几种不同的情况;检验和用来检验整个ICMP报文。
此类用于对属于ICMP协议的数据进行逐步分析,并得到各字段的数据,使用的方法和其他解析类类似,在此不再重复,可参考相应源程序文件。
(7)TCPAnalyzer.java
TCP(Transmission Control Protocol)传输控制协议和UDP(User Datagram Protocol)用户数据报协议是属于运输层的,运输层的作用范围是提供进程之间的逻辑通信,能够向应用层提供运输服务,而网络层(IP协议)提供主机之间的逻辑通信。TCP协议是面向连接的,而UDP是无连接的。
TCP报文段分为首部和数据两部分,首部前20字节是固定的,后面有4N字节是根据需要而增加的,因此TCP首部的最小长度为20字节。具体字段作用可参考相应源文件。
端口(16bit)的作用:让应用层的各种应用程序都能将其数据通过端口向下交付给运输层,以及让运输层知道应当将其报文段中的数据向上通过端口交付给应用层相应的程序。
(8)UDPAnalyzer.java
UDP报文段分为数据字段和首部字段,首字段只有8个字节,由4个字段组成,每个字段2字节,各字段为:源端口(源端口号)、目的端口(目的端口号)、长度(UDP用户数据报的长度)、检验和(防止UDP用户数据报在传输中出错)。
(9)PacketAnalyzer.java
此类用于显示数据包被截获相关信息,比如捕获时间和捕获长度。
5.3 stat包的设计
5.3.1 stat包的作用
Stat的作用是完成对所截获的数据包按照不同的协议,不同的层次进行统计,并进行动态的更新,最后将其结果显示出来。
在数据包统计中,作者将所有截获的数据包按照所属协议的层次分别进行统计,则统计类的设计与层次的分类一致,如表3所示。
表3 统计类的设计与层次对照表
TCP/IP层次 | 数据包统计类名 |
互联层 | NetworkProtocolStat |
传输层 | TransportProtocolStat |
应用层 | ApplicationProtolStat |
与analyzer包类似,在stat包中,我首先编写一个抽象类JDStatisticTaker,用来定义一些不同层次数据包统计类所具有的公用函数,然后在每一个类中分别定义了四个不同的变量用来存储不同的数据:不同层中各协议数据包所占的数量比重(long[] numOfPs)、不同层数据包总数量(long totalPs)、不同层中各协议数据包所占的大小比重(long[] sizeOfPs)、不同层数据包的总大小(long totalSize);在构造函数中提取各个层协议数量,分配numOfPs和sizeOfPs两个数组的大小;定义函数analyze用于对一组数据包进行统计;定义函数addPacket用于对每接收到一个数据包进行累加统计。
5.3.2 stat包中各个类的作用与实现方式
(1)JDStatisticsTaker.java
此类是一个抽象类,用于定义一些不同层次数据包统计类所具有的公共函数,将所有截获的数据包按照所属协议的层次分别进行统计,则统计类的设计与层次的分类一致。
(2)NetworkProtocolStat.java
此类是网络层的数据包统计类,分配四个不同的变量用来存储网络层不同的协议数量,在该类中的构造函数用来提取网络层协议数量,分配数组大小;并用getName()方法来得到该协议层的名字;然后用analyze方法来分析数据包,并进行统计;最后使用addPacket方法来将所分析的到的数据包加入到不同的变量中,进行及时的更新操作。
(3)TransportProtocolStat.java
此类是传输层的数据包统计类,与网络层的统计方法类似,在此不再重复,可参考相应源程序文件。
(4)ApplicationProtocolStat.java
此类是传输层的数据包统计类,与网络层的统计方法类似,在此不再重复,可参考相应源程序文件。
5.4 ui包的设计
5.4.1 ui包的作用
向JSniffer工程中添加ui包,步骤与添加analyzer包和stat包一致。
Ui包中的所有类主要实现该程序的界面排版,将实现程序界面的所有的类封装在“ui”包中。该包中将程序主界面分为四个部分,分别用不同的组件去实现,它包括菜单栏,工具栏,以及显示结果的JPanel控件,设计监听程序界面如图9所示。
每一部分所使用的组件以及所属的类如表4所示。
表4 组件以及类对照表
序号 | 组 件 | 类 |
① | JFrame | JDFrame |
② | JPanel | JDTablePane |
③ | JTable | JDTable |
④ | JTree | JDTableTree |
⑤ | JTextArea | JDTableTextArea |
5.4.2 ui包中各个类的作用与实现方式
(1)JDFrame.java
JDFrame类是程序的主界面,它包括菜单栏,工具栏以及用于显示监听结果的JPanel控件,在JPanel中又分为三个部分,分别用组件JTable、JTree、JTextArea来实现,该类中最主要的功能在于添加对菜单和工具栏的事件响应,进行动态更新操作,设置程序在不同的运行状态时不同的组件状态,并用Java提供的方法将相应的图片镶嵌进程序,增强视觉效应。
(2)JDCaptureDialog.java
JDCaptureDialog类的作用是选择设备和设置设备模式,也是进行网络监听的关键一步。在单击“开始监听”菜单或者按钮后会弹出一个选择设备对话框,它是由JDCaptureDialog类来实现。JDCaptureDialog类利用Jpcap包的getDeviceList函数和getDeviceDescription函数来获取本机上可进行监听的所有的网络设备。在确定所选择的设备后,还可以通过设定如何截取数据包,是只截取数据包头还是截取整个数据包。单击确定后,通过调用Jpcap的openDevice函数来打开设备。
选择设备对话框如图10所示。
(3)JDTablePane.java
JDTablePane类主要功能是对JTable、JTree、JTextArea三个组件进行布局,这里用的是JSplitPane布局,即进行分割布局(JSplitPane 用于分隔两个<只能两个>Component);同时在JDTablePane类中还完成了协议查看菜单的设置和事件响应。对于监听结果的显示是由三个部分组成的,即JTable组件自动更新显示截获并解析后的每一条数据包,在选定某一条数据包后,JTree组件显示这个数据包具备的全部协议的协议头部,JTextArea组件显示这个数据包的内容。
(4)JDTable.java
JDTable类用来实现显示截获数据包解析后的结果,位于JDTablePane布局中的上方。该类主要功能是设置表格中显示的内容,由setTableView函数来实现;当有新数据包解析完后进行插入,由fireTableChanged函数来实现。同时在此类中定义了TableView类用来表示表格显示的结构;JDTableModel类是一种模式,在其中定义了对表格的一些常见操作,而JDTable便是JDTableModel模式下的表格。Jtable是JavaSwing中最复杂的组件之一,在本程序中作者还定义了JDTableRender、TableMap和TableSorter三个类用来辅助JDTable类的实现,因为这三个都编写成通用类,属于J2SESwing的界面编程技巧与网络监听没有太大关系,因此这里不再介绍,可查看源程序文件“JDDetailTree.java、JDTableRenderer.java、TableMap.java和TableSorter.java”。
显示截获数据包解析后的结果如图11所示:
(5)JDTableTree.java
JDTableTree类的功能是在选择某一个数据包后,将该数据包具有的所有协议内容组成一棵树,父结点是协议名,子结点是协议具有的字段名,叶子是字段取值。analyzePacket函数实现了将一个数据包分解然后构造树的过程。addNode和addNodes两个函数都是用于添加新的结点,树中显示的结果如图12所示。
(6)JDTableTextArea.java
JDTableTextArea类所实现的功能是在选择某一条数据包后,在其中显示此数据包的内容。关键在于将数据包内容转换为字符串显示,对于不可显示字符有一个特定符号代替,这个功能由showPacket函数实现。
TextArea中显示的结果如图13所示。
(7)JDStatFrame.java
为了更好地把统计结果显示出来,作者在主界面中添加了“数据包统计”菜单,单击菜单中相应的层次的菜单项,就会弹出该层次数据包统计结果的窗口。
JDStatFrame类就是其中一个实现统计结果显示的类,它是一个抽象类。为了对统计结果利用图表进行显示,可以绘制折线图、柱状图和饼图等。因此在JDStatFrame类中定义了实现统计结果窗口所需要的公用函数。
(8)JDCumlativeStatFrame.java
JDCumlativeStatFrame类实现了对结果饼图的绘制,它将弹出一个窗口,将统计结果显示在上面,利用自定义的PieGraph类对结果绘制饼状图,并且实现动态更新。作者将PieGraph类编写成一个通用类,与网络监听没有太大的关系,因此这里不介绍PieGraph类的实现,可查看源文件“PieGraph.java”。
统计显示结果如图14所示。
(9)JSourceDialog.java
JSourceDialog类的功能是在进行指定对象监听的时候,弹出对话框,接受用户输入要指定对象的IP地址,并对输入的地址进行正确性检验。使用DocumentListener 监听者的insertUpdate方法对输入的字符进行监视检查,确保输入的是0到9之间的数字;在单击确定按钮后再次检查,看看是否4个十进制数都在0到255之间。若正确则将此地址转换为字符串,然后再调用analyzer包中的分析类进行指定IP地址的分析。
输入指定IP地址的显示图所图15所示。
5.4.3 ui包中graph包的作用
此包中包含两个类(PieGraph.java和LineGraph.java),这两个类都是通用类,属于J2SESwing的界面编程技巧,与网络监听没有太大关系,在这只是调用JAVA中这个方法来显示饼状图和曲线图,因此这里不再介绍,可查看源程序文件。
5.5 外部类的设计
5.5.1 外部类在整个程序中的作用
到此,本设计已完成了分别用于分析,统计和界面的三个包“analyzer”、“stat”和“ui”的介绍。整个程序是一个名为JSniffer的工程,所以所有的代码都包含在“JSniffer”包中。最后还需要直接在“JSniffer”包添加几个类,包括主类JSniffer和实现截取数据包的类JDCaptor等,用于将各个部分结合起来,达到预期的实现效果。
5.5.2 外部各个类的作用与实现方式
(1)JDCaptor.java
JDCaptor类是整个程序的关键,它相当于一个数据包截获器。JDCaptor类将每次监听分配到一个监听线程,对数据包的截取将通过在线程中调用Jpcap类的processPacket函数来实现,截取完后将数据包交给JpcapHandler对象handler进行处理,包括指定对象监听的时候对数据包进行过滤和将数据包加入到向量中。JDCaptor类中的函数大部分都是对监听线程的操作,包括开启线程、停止线程、暂时停止线程和继续线程,并完成了对文件进行保存和打开的操作等等。
(2)JDPacketAnalyzerLoader.java
JDPacketAnalyzerLoader类是一个载入器。JDPacketAnalyzerLoader类将所有“analyzer”包中定义的所有的协议解析类存储到一个向量中,在截获一个数据包后,利用此向量对数据包进行解析。
(3)JDStatisticTakerLoader.java
JDStatisticTakerLoader类也是一个载入器,同JDPacketAnalyzerLoader类类似,JDStatisticTakerLoader类也类似,将“stat”包中定义的数据包统计类存储到一个向量中,利用此向量进行统计。
(4)JSniffer.java
JSniffer类是程序的主类,在此类中主函数通过调用函数openNewWindow启动主界面。openNewWindow函数创建一个截获器JDCaptor实例,然后作为参数传递给JDFrame类的构造函数,创建一个主界面。为了支持多个界面同时运行,在类中定义一个frame向量,每创建一个主界面就将其加入到向量中。当然JDCaptor实例和JDFrame实例是一一对应的,即每个JDFrame实例独立拥有一个JDCaptor实例。
6 测试与分析
6.1 测试的目的
软件测试是软件开发过程的重要组成部分,是用来确认一个程序的品质和性能是否符合开发之前所提出的一些要求,是为了发现错误而执行程序的过程。
本次软件测试的目的:
(1)确认软件的质量,其一方面是确认软件是否完成了开发人员期望的功能,另一方面是确认软件是否以正确的方式来完成这些功能的;
(2)提供信息,让开发人员知道该软件需要进行哪些地方的完善,比如提供给开发人员的反馈信息。
对软件测试的结果由以下几个方面来衡量的:
(1)该软件是否能在正确的时间用正确的方法把一个工作做正确;
(2)符合一些应用标准的要求,比如用户的操作习惯、界面的友好状况等等;
(3)软件是否达到了最开始所设定的要求和代码的规范程度。
6.2 测试的步骤
本软件的测试过程按4个步骤进行,即单元测试、集成测试、确认测试和系统测试。
(1)单元测试
单元测试是紧接在编码之后的,是集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。
单元测试任务包括:
① 模块接口测试;
② 模块局部数据结构测试;
③ 模块边界条件测试;
④ 模块中所有独立执行通路测试;
⑤ 模块的各条错误处理通路测试。
对analyzer和stat包进行测试时,作者首先进行一个总体的测试,在完全不考虑程序内部结构和特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格来运行,程序是否能适当地接收输入数据而产生正确的输出信息。
然后作者利用Eclipse 3.2中的Java调试功能,通过这种测试来检测软件内部动作是否按照要求正常进行,检验程序中的每条通路是否都有能按预定要求正确工作,而不顾它的功能。在测试程序的过程中设置不同断点,并将程序处于运行状态,当运行到断点时,Eclipse 3.2中将显示每一个变量的值和所使用的方法等等,以次可以判断程序是否是按照作者预期的要求在运行,若发生错误或没有按照要求运行,开发人员将对源代码进行一定的修改后再进行调试,所以在编写该软件时,修改和调试操作是交替进行的。
而在对ui包进行测试时,和其它包的调试操作有所不同,因为Eclipse 3.2的开发是基于J2SE Swing的图形用户界面的,所以在布局的设计上就显得更为简单,有一个直观的效果,可以在一种布局上添加不同的组件,以此来达到作者预期的效果。在这一部分的调试中,最重要的问题就是测试每一个监听事件的响应是否正确,因此必须对菜单和工具栏中的每一个按钮进行逐一的测试,通过测试其中一个事件响应时,反映出每一组件在相应的状态下是否处于正常的运行状态等。
(2)集成测试
集成测试是把已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。
在这一部分的测试中,作者主要是对外部的类进行测试,比如主类(JSniffer.java)、数据包截获器类(JDCaptor.java)等。在对主类进行测试中,主要就是看它是否将每一个类,每一个包联系起来,让该软件达到用户要求的功能,并且有一个友好的界面等。
(3)确认测试
确认测试则是要检查软件是否满足了所规定的各种需求,以及软件配置是否完全、正确。
在对该软件地确认测试中,作者只是简单地进行了一些操作,比如在Eclipse 3.2下运行程序,执行各种操作,检查是否满足规定的所有功能和性能,是否令用户满意。
(4)系统测试
系统测试把已经经过确认的软件纳入到实际的运行环境中,与其它系统成份组合在一起进行测试。
经过了以上一系列的测试后,已经对软件进行了大部分的测试操作,确保了软件运行效果的正确性。下面还需将软件进行打包,并将其纳入到实际的运行环境下进行测试,在此测试部分,作者首先将软件所需要的运行环境配置正确,然后启动软件,进行一系列的测试操作,确定软件的完整性、健壮性等。
6.3 测试分析
经过单元测试、集成测试、确认测试和系统测试后,已经确保了本软件在正确的环境下可以正常的运行,实现了数据包统计和分析功能的网络监听软件,它可以仅通过局域网中任意一台主机的安装,达到监控整个局域网的目的。具体功能描述如下:
(1)局域网中任意一台连网主机都可以安装,对安装的环境没有任何限制。一机安装,全网监控。
(2)当安装的主机有多个网卡时,可以选择监视其中的一个网卡。
(3)分析出本网络中所有IP地址所传输数据的字段、捕获时间、长度等。
(4)指定IP地址监听。
(5)可以使用饼状图将其结果显示出来。
(6)可以进行界面选择。
在编写的过程中也遇到一些困难和一些不足之处,例如:
(1)由于核心Java API不能访问底层的网络数据,因此在使用Java编写网络监听程序时就必须借助一些工具。如:Winpcap和Jpcap这两个工具来对网络底层进行访问,帮助实现网络监听程序。
(2)在选择设备时会发生一些溢出异常,如图16所示。
(3)不能自动获取本机和网关的IP和MAC地址、
(4)不能指定IP段来进行监听。
至此,已经设计出一个完整、健壮的局域网监听软件,在开发的过程中,我深深的体会到随着Internet及电子商务的日益普及,Internet的安全也越来越受到重视。在Internet安全隐患中扮演重要角色之一的网络监听软件受到越来越大的关注。网络管理员可以使用网络监视器检测和解决在本地计算机上可能遇到的网络问题。例如,作为一名网络管理员,当服务器计算机不能与其他计算机通讯时可以使用网络监视器诊断硬件和软件问题。网络监视器捕获的帧可以保存为文件,然后发给专业的网络分析人员或支持机构。另外,网络应用程序开发人员可以在开发时使用网络监视器监视和调试网络应用程序等等。
本软件还有许多不足之处,还需在以后的使用过程中不断发现问题,不断完善。
7 用户使用手册
7.1 系统配置要求
(1)程序名称:JSniffer(局域网监听软件)
(2)开发语言:Java
(4)使用工具:Winpcap, Jpcap, Eclipse 3.2
(3)运行平台:Windows
7.2 系统环境配置
(1)安装j2sdk1.4.0或jre1.4.0以上版本;
(2)安装Java虚拟机;
(3)想捕获Java程序中的网络包,那么你需要一些辅助工具,因为核心Java API不能访问底层的网络数据。但Jpcap只是一种提供在Windows系统上进行这种访问的Java API,而不是一种纯粹的Java解决方案,它依赖本地库的使用。在Windows上,你必须有必要的第三方库是Winpcap;
(4)安装配置Jpcap包;
Windows:
- Copy "lib\Jpcap.dll" into "[JRE directory]\bin" or "[JRE directory]\lib\ext\x86"
- Copy "lib\jpcap.jar" into "[JRE directory]\lib\ext"
- If you installed J2SE SDK, you also need to copy "lib\jpcap.jar" into "[SDK directory]\jre\lib\ext".
(5)安装WinPcap。
7.3 执行程序步骤
(1)执行程序
直接双击JSniffer.jar,即可打开程序。
(2)开始扫描、停止扫描、暂停扫描、继续扫描:
a.单击菜单栏里的“开始监听”按钮,然后在监听参数设置窗口中选择网络设备,再单击‘确定’按钮即可开始扫描。
b.单击工具栏里的“停止扫描” ,即可停止。单击“暂停”即可暂停扫描。单击“继续”即可继续此次扫描。
单击“开始监听”后选择网络设备的界面所图17所示。
扫描中的状态如图18所示。
(3)确定对象扫描和停止对象扫描
a.在工具栏里单击“对象扫描”按钮即可显示对话设置窗口,在对象设置窗口中填写要扫描对象的IP,即可对对象开始扫描。
b.按“停止对象扫描”按钮即可停止该次对象扫描开始全局扫描。
对象监听状态如图19所示。
(4)协议察看
可以在菜单栏里选择你想查看的网络协议的具体内容。
(5)数据包统计察看
可以通过菜单,选择你要看的数据包统计结果。
数据包统计结果如图20所示。
(6)数据包查看
要查看数据包只要在表中单击一行数据即可在下面显示其数据包中的内容,以供分析。
全局信息查看如图21所示。