您的位置:首页 > 理论基础 > 计算机网络

Java之JPcap网络抓包与分析程序(支持多种协议分析,对初学网络者认识网络有很好帮助)

2010-08-13 23:19 603 查看
此程序是利用JPcap包,抓取通过本地网卡的数据帧,并分析各字段的程序。

这是我的一个网络课程设计,具体介绍在下面的实习报告中详细讲述,并附有源代码

不知道怎么上传文件,所以直接粘贴过来了。

目录

第一章 设计目的、任务与要求
1.1设计的目的------------------------------------3
1.2设计的任务与要求------------------------------3

第二章 系统分析设计
2.1 系统分析--------------------------------------3
2.2 系统设计--------------------------------------8

第三章 系统实现
3.1 实现过程--------------------------------------10
3.2 采用技术--------------------------------------11
3.3 结果界面--------------------------------------11
3.4 结果分析--------------------------------------16

第四章 心得体会------------------------------------- 18

参考文献--------------------------------------------19

附录------------------------------------------------20

第一章 设计目的、任务与要求

1.1:设计的目的
《计算机网络原理》课程是计算机科学与技术专业的重要专业课程之一。随着计算机网络技术的迅速发展和在当今信息社会中的广泛应用,给《计算机网络》课程的教学提出了新的更高的要求。
计算机网络原理课程设计的目的与任务是为了使学生在课程学习的同时,通过在一个计算机网络环境中的实际操作,巩固《计算机网络原理》课堂教学所讲授网络的基本理论、基本概念和方法技术,对现代计算机网络的基本功能有一个初步的了解。为学生今后使用计算机网络的理论和方法,开发大型、复杂的集成系统,打下一个坚实的基础。

1.2:设计的任务与要求
本次实验的要求在网络环境,使用编程语言实现捕获网络中的IP数据包,解析数据包的内容,将结果显示在标准输出上,并同时写入日志文件。
程序的具体要求如下:
①:在标准输出和日志文件中写入捕获的IP包的版本、头长度、服务类型、数据包总长度、数据包标识、分段标志、分段偏移值、生存时间、上层协议类型、头校验和、源IP地址和目的IP地址等内容。
②:可扩展分析其他协议包。

第二章 系统分析设计

2.1:系统分析
实现网络抓包的方法有很多,下面介绍四种:
①:原始套接字
套接字是网络应用编程接口。应用程序可以使用它进行网络通信而不需要知道底层发生的细节。有时需要自己生成一些定制的数据包或者功能并希望绕开Socket 提供的功能,原始套接字( Raw Socket) 满足了这样的要求。原始套接字能
够生成自己的数据报文, 包括报头和数据报本身的内容。通过原始套接字, 可以更加自如地控制Windows 下的多种协议, 而且能够对网络底层的传输机制进行控制。可以用原始套接字来发送和接收IP 层以上的原始数据包, 如ICMP, TCP, UDP, 而且能够对网络底层的传输机制进行控制。Raw Socket 的作用主要有三个方面: ( 1) 接收发向本机的ICMP, IGMP 协议包, 或者发送这些协议包; ( 2) 接收发向本机的IP 包; ( 3) 发送自定义的IP 包。
②:LibPca p
可以从http: / / ee. lbl. gov/ 找到并下载LibPcap, 它是一个广泛应用的系统抓包库。LibPcap 是一种与系统无关, 采用分组捕获机制的分组捕获函数库, 用于访问数据链路层, 它在不同的平台上采用统一的编程接口, 使用LibPcap 编写的程序可自由的跨平台使用。同时LibPcap 是一个独立于系统接口的用户级的抓包库, 它为底层网络监听提供了可移植框架。它的应用包括网络统计集合、安全监听、网络调试等。
③:WinPca p
可以从http: / /winPcap. polito. it / 找到WinPcap。WinPcap是LibPcap 的Windows 版本, 它是一个基于Win32 的捕获数据包和网络分析的体系结构, 它包括一个内核级的包过滤器, 一个底层的动态链接库( Packet. dll) , 一个高层并且与系统无关的库( WPcap. dll, 基于LibPcap0. 6. 2 版本) 。WinPcap 是集成于Windows95, 98, ME, NT, 2000 和XP 操作系统的设备驱动程序, 它可以从网卡捕获或者发送原始数据, 同时能够过滤并且存储数据包。开发WinPcap 这个项目的目的在于为Win32 应用程序提供访问网络底层的能力。它提供了以下四项功能:
( 1) 捕获原始数据报, 包括共享网络上各主机发送/ 接收的以及相互之间交换的数据报;
( 2) 在数据报发往应用程序之前, 按照自定义的规则将某些特殊的数据报过滤掉;
( 3) 在网络上发送原始的数据报;
( 4) 收集网络通信过程中的统计信息。
④:JP ca p
可以从http: / / netresearch. ics. uci. edu / kfujii / jpcap / doc /index. html 找到JPcap。JPcap 是一个能够捕获、发送网络数据包的Java 类库包。这个包用到了LibPcap 和原始套接字API。目前JPcap 在FreeBSD 3. x, Linux RedHat 6. 1, Solaris 和MicrosoftWindows 2000 /XP 系统上已经做过测试, 并且支持Ethernet, IPv4, IPv6, ARP/RARP, TCP, UDP, ICMPv4 协议。JPcap是一个Java 类集合, 它为网络数据包的捕获提供接口和系统支持。其最初版本是2000 年6 月发布的JPcap0. 01 版, 此后几经修改, 到2003 年4 月发布了最新的JPcap0.4 版。
由于本程序采用Java编程语言,所以使用第四种方法,即JPca p来实现抓包。

现在选定了抓包工具,我们还得分析一下所获包的结构,只有弄清楚结构,才能很好的分析捕获包。
我们知道,网络软件是由多个协议层次组成的,在每一层里面都有自己的数据封装,以便实现每个层的功能。OSI参考模型中定义了7层,从低到高分别是物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。TCP/IP参考模型中定义得比较少:互联网层(网络层)、传输层、应用层、主机至网络层(空白,可以理解为跟OSI模型一致)。而且我们知道,高层协议整个协议包是封装到低层协议的数据段中的,所以整体是一个嵌套的结构,如下图所示:



数据链路帧格式如下(以太帧):



网络层协议有IP、ICMP、ARP等:
IP分为IPv4和IPv6,这里介绍IPv4
IPv4协议格式如下:



ICMP用于控制,每一种控制有独特的格式,由于格式太多,这里不介绍,详情可参考RFC792 - Internet Control Message Protocol。
ARP协议格式如下:



传输层协议有TCP、UDP:
TCP协议格式如下:



UDP协议格式如下:



基于TCP的应用层协议主要有HTTP:
HTTP协议格式如下(具体数据会不同,这里供参考):
①:HTTP请求:
GET 请求:



POST请求:



②:HTTP响应:



基于UDP的应用层协议主要有DNS:
DNS协议格式如下:



以上这些协议是本程序所能分析出来的,由于网络协议有上千种,不可能都去分析,所以其他的协议在此忽略。
既然找到抓包工具,弄清协议格式,现在就开始系统设计吧。

2.2:系统设计
环境搭建:
设计少不了的一项工作就是环境搭建,以下是环境搭建的步骤:
①:jre安装(最好是最新版本——jre6)
②:Myeclipse或者Eclipse安装
③:下载并安装winpcap(可以下载最新版本)。
④:配置Jpcap路径:这一步也是最重要的一步。具体路径为,把Jpcap文件夹下lib文件夹里的Jpcap.dll复制到"C:/Program Files/Java/jre1.6.0_07/bin"文件夹里面(复制到你机器JRE文件夹放到bin文件夹里面就可以了,其中JRE的版本一定要与Eclipse配置的版本一致),再把Jpcap文件夹下lib文件夹里的Jpcap.jar复制到"C:/Program Files/Java/jre1.6.0_07/lib/ext"文件夹里面(复制到你机器JRE文件夹->lib->ext放到ext文件夹里面就可以了)。
⑤:配置Eclipse的JRE环境,(一定需要),选择Window->preferences->Java->Installed JREs,在Installed JREs选择框中选择相应的JRE版本,点Edit,



选择Add External JARs…,选择你的Jpcap.jar包("C:/Program Files/Java/jre1.6.0_07/lib/ext"文件夹里),在Finish就配置全部完成了。





在本程序中,采用图形化界面,根据用户的相关配置进行抓包,具体过程参考下面实现过程。

第三章 系统实现

3.1:实现过程
当环境搭建好后,一起都会显得很简单了,这里说一下原理,在安装winpcap时,其实就是利用第三方编写好的程序,他们已经实现了底层和网卡的交互,数据捕获,并把数据封装好,然后对上层用户提供API,现在我们就利用他们提供的API,即JPca p来处理他们封装好的数据。
所以在环境搭建中,必须安装winpcap和导入JPca p库函数。
下面是获取包的几个关键步骤:
①:获得网卡接口
通过调用JPca p库中JpcapCaptor的静态方法getDeviceList()得到网卡接口数组。
②:获得某个网卡接口的连接
通过调用JPca p库中JpcapCaptor的静态方法openDevice()得到某个网卡接口的连接实例。
③:调用实例的processPacket()开始抓包。
④:将抓获的包交给实例的receivePacket()方法进行分析处理。
以上就是整个抓包过程。
当然,在上面的那些方法中,都有一些特定的参数,上面没有给出,这些参数都是用于配置抓包的,程序采用图形化界面,所以这些参数可以在界面上根据用户的选择,然后传入相应方法中,最终获得用户所需的信息。
采用图形化界面,要解决的一个问题就是界面的刷新,通常是后台程序运行,产生结果,界面中要及时显现变化,即界面内容因后台结果而变。
在这个前台(界面)和后台都要兼顾的前提下,必须使用线程来解决这个问题,界面是根据后台而变的,所以可以为界面分配较高优先级,当界面显示内容不再变化,程序才会去执行较低优先级的后台抓包程序,而当抓包结果产生时,程序马上又能调用较高优先级的前台程序显示出来。
至此,前台和后台都能兼顾运行。
这里要说明的一点是,由于采用线程抓包,所以所抓获的包不是连续通过网卡的包,我们获得的,只是某些时刻的包。

3.2:采用技术
①:JPca p库函数运用
②:Swing组件运用
③:线程技术运用
④:托盘技术运用(托盘图标,用于图形化界面,没有抓包方面的知识)
⑤:文件操作技术运用(分析结果保存于文件和文件打开)

3.3:结果界面
①:开始界面(欢迎界面)



②:菜单选项
File菜单:

Capture菜单:


Tool菜单:

Help菜单:


③:网卡信息



④:配置抓包



⑤:开始抓包



⑥:保存文件(自定义后缀为 .sto)



⑦:打开以前保存的文件



点击打开后,会在界面上显示保存的结果

⑧:相关链接
Wireshake 链接(本程序就是参考此程序的)
注:要链接此程序,必须安装wireshake于本地机器上,目录为安装默认目录。



Check network card factory(网卡厂商查询)链接
注:通过此链接,可跳转到国外的一个查询网站,输入前3位16进制(即前24位二进制)网卡地址查询。



⑨:Help菜单
注:点击链接到JPCAP 的API,要想链接,必须把API的doc文档放于E:/目录下。



⑩:托盘
注:当点击窗口最小化时,在电脑右下角显示托盘图标,双击图标恢复界面



QQ图标左边第一个为本程序的托盘图标

3.4:结果分析
下面以一个以太帧的结果来分析产生结果
------包分析-------
Captured Length:805 byte
Length of this Packet:805 byte
Header:[B@dea768
Length of Header:54 byte
Data:[B@1c0cd80
Length of Data:751 byte
---Ethernet头部信息---
src_mac:0:e0:b0:f8:65:8e
dst_mac:d8:5d:4c:1d:52:7a
frametype:0x800
------------------
---IP版本: 4 ---
Type of service:0
Priprity:0
Packet Length:791
Identification:5730
Don't Frag? false
More Frag? false
Frag Offset:0
Time to Live:64
Protocol:6 (TCP = 6; UDP = 17)
Source address:/192.168.1.100
Destination address:/220.170.91.146
Options:null
------------------
---TCP---
Source Port:2434
Destination Port:80
Sequence Number:2037813051
Acknowledge Number:2047245128
URG:false
ACK:true
PSH:true
RST:false
SYN:false
FIN:false
Window Size:46537
Urgent Pointer:0
Option:null
------------------
---HTTP---
GET / HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; 360SE)
Host: www.163.com
Connection: Keep-Alive
Cookie: ALLYESSESSION1=4c201e0f6e31e; _ntes_nnid=d837938ce6aa32c1e7bd8b6b8ea9b518,0; _ntes_nuid=d837938ce6aa32c1e7bd8b6b8ea9b518; ntes_ucc=; NTES_UFC=5101000000000001101000000000000000000000000000000000000000000000; USERTRACK=220.168.117.183.1276908764822367; vjuids=96e8a39f.12205a57bb7.0.c45bac10feb66; vjlast=1245635247.1245635247.30; Province=0730; City=0731; ALLYESID4=00100622094821301258115; __ntes__test__cookies=1245637579343; NTES_adText=2; locOfCh=south; theCity=57679; movnum=1; kksp2009622channeleventcookies=1

这是一个比较完整的以太帧,从上到下为低层包含高层的嵌套结构,每个协议都用分割线隔开,最初是整个包(以太帧)的信息。然后就是帧头信息,帧头里面按照帧的格式显示,之后进入IP头部格式分析,各个字段也是按照IP格式给出,IP下面是TCP,TCP下面是HTTP等。
结果一目了然。

第四章 心得体会

在获得题目之初,我最初是想做网卡驱动的,因为我觉得假如能实现底层的驱动的话,能让我更好的掌握相关网络知识,而且对我以后的求职也会有所帮助,然而当我在网上找了相关资料一看的时候,所有的编程语言都是底层语言,比如C语言、汇编语言、C++之类,而我的C和汇编都仅仅是入门而已,C++更是没有学过,所以做不了网卡驱动了。剩下的网站编写,我自己也写过一些,觉得那个把相关网络知识都封装了,几乎不会网络知识的人也能完成。最终我选择了IP抓包课题,因为这个几乎贯穿了我们所学的知识。
开始我也不知道,做了之后我才发现,要实现简单的捕获包,通过相关配置之后,只要不到百行代码,然后我询问了其他也是做这个课题但是不是用Java的同学,他们也说好简单。
我知道他们的简单是什么意思,就是得到包而已。我觉得还是不简单的,因为重头戏在分析包的结构中,所以我开始构想,我能不能把常用的包都分析出来,而不仅仅是题目要求的IP分析,经过相关的查询之后,得到结论:可以。
要分析包,肯定的了解包的构造,不同层有不同层的构造,不同协议也有不同协议的构造,我得去查看各个常用协议的构造,教材已不再满足要求,因为好多都没有整体构造,仅仅是一些字段说明,所以得充分利用网络资源,而这其中,Request For Comments(RFC)是最有力的工具,这里面有各个协议的标准,整体构造,字段说明等,看了RFC之后,我终于知道看原版的好处了。
通过查看相关RFC之后,我归纳了上面给出的那些协议格式,那些协议也是我想要在程序里面分析的。
还有在一些博客里面,楼主都把自己的经验分享了,在本课程设计中,我觉得其中最重要的就是有人把环境配置的经验分享了,不然要我去摸索过程,我觉得会是很难的。
通过这次实验,我收获还是很多,虽然我也想要有他们做网站、做文件传输的收获,但是鱼和熊掌不可兼得,他们也没有我的收获啊,嘿嘿...
以下是所得:
首先,就是巩固了网络知识,对于这些常用协议,我现在真的是有自己的认识了。
其次,掌握了网络抓包的原理,以及基于Java的抓包程序的编写。
再者,加深Swing组件应用,掌握托盘技术,学会使用线程。
最后,也是最重要的一点体验,就是觉得网络真的是一个宝库,只要你知道你的问题,你都能在其中找到你要的答案。
其他的话,就是感谢老师先给我们上了理论知识,最后又提供课题让我们自己去深刻感受理论知识的运用。

参考文献
以下皆来自网络
[1] RFC826 - Ethernet Address Resolution Protocol (ARP)
[2] RFC792 - Internet Control Message Protocol (ICMP)
[3] RFC791 - Internet Protocol (IP)
[4] RFC793 - Transmission Control Protocol (TCP)
[5] RFC768 - User Datagram Protocol (UDP)
[6]RFC2616 - Hypertext Transfer Protocol -- HTTP/1.1 (HTTP)
以下是教材
[7]计算机网络(第四版),清华大学出版社,2004年8月出版

附录

源代码如下:

①:MainFrame类
package cn.com.wwc;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Container;
import java.awt.Frame;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import org.jvnet.substance.SubstanceLookAndFeel;

public class MainFrame extends JFrame implements ActionListener,WindowListener,Runnable{

private static final long serialVersionUID = 1L;
private JMenuBar mBar = new JMenuBar();
private JMenu M_file = new JMenu("File");
private JMenu M_capture = new JMenu("Capture");
private JMenu M_tool = new JMenu("Tool");
private JMenu M_help = new JMenu("Help");
private JMenuItem F_open = new JMenuItem("Open File");
private JMenuItem F_save = new JMenuItem("Save File");
private JMenuItem F_exit = new JMenuItem("Exit");
private JMenuItem C_show = new JMenuItem("Network Card information");
private JMenuItem C_Configure = new JMenuItem("Configure");
private JMenuItem C_start = new JMenuItem("Start");
private JMenuItem C_stop = new JMenuItem("Stop");
private JMenuItem T_wireshake = new JMenuItem("Wireshake");
private JMenuItem T_factory = new JMenuItem("Check network card factory");
private JMenuItem H_api = new JMenuItem("API for JPCAP");
private JMenuItem H_author = new JMenuItem("About Author");
public JPanel mainPanel1;
public JScrollPane mainPanel2;
public Container con;
public JTextArea area = new JTextArea();

public CatchPacket cPacket ;
Thread thread = new Thread(cPacket);

public Configure configure;
public static boolean isWorking = false;

private SystemTray sTray;
private TrayIcon tIcon;

// 布局页面
public void init(){

// file菜单
M_file.add(F_open);
M_file.add(F_save);
M_file.add(F_exit);
// capture菜单
M_capture.add(C_show);
M_capture.add(C_Configure);
M_capture.add(C_start);
M_capture.add(C_stop);
// tool菜单
M_tool.add(T_wireshake);
M_tool.add(T_factory);
// help菜单
M_help.add(H_api);
M_help.add(H_author);
// 组装菜单
mBar.add(M_file);
mBar.add(M_capture);
mBar.add(M_tool);
mBar.add(M_help);
setJMenuBar(mBar);

setLayout(null);

mainPanel1 = welPanel();
mainPanel2 = workPanel();
mainPanel1.setBounds(50, 10, 900,700);
mainPanel2.setBounds(50, 10, 900,700);
add(mainPanel1);
add(mainPanel2);
mainPanel1.setVisible(!isWorking);
mainPanel2.setVisible(isWorking);

setTitle("PacketCatcher-WWC(World-Wide-Catch)");
setSize(1000, 800);
setResizable(false);
setVisible(true);

F_open.addActionListener(this);
F_save.addActionListener(this);
F_exit.addActionListener(this);
C_show.addActionListener(this);
C_Configure.addActionListener(this);
C_start.addActionListener(this);
C_stop.addActionListener(this);
T_wireshake.addActionListener(this);
T_factory.addActionListener(this);
H_api.addActionListener(this);
H_author.addActionListener(this);
this.addWindowListener(this);
}

// 设置托盘
public void setTray(){
sTray = SystemTray.getSystemTray();
ImageIcon icon = new ImageIcon(".//.//.//images//tray.jpg");
PopupMenu menu = new PopupMenu();
MenuItem show = new MenuItem("显示窗体");
MenuItem exit = new MenuItem("退出窗体");
tIcon = new TrayIcon(icon.getImage(),"World-Wide-Catch",menu);
tIcon.addMouseListener(new MouseAdapter() {

public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {// 鼠标双击
sTray.remove(tIcon);
setVisible(true);
// 设置窗口全屏
//setExtendedState(JFrame.MAXIMIZED_BOTH);
}
}
});
}

// 初始化界面
public MainFrame() {
// 初始化一个CacthPacket对象,以后都是在操作此对象
cPacket = new CatchPacket();
con = this.getContentPane();
init();
setTray();
}

// 添加welcome界面
public JPanel welPanel(){
JPanel jPanel = new JPanel();
JLabel label = new JLabel();
ImageIcon icon = new ImageIcon(".//.//.//images//final.jpg");
label.setIcon(icon);
jPanel.add(label);
return jPanel;
}

// 运行时界面
public JScrollPane workPanel(){
area.setBackground(Color.yellow);
area.setText(CatchPacket.sb.toString());
area.setEditable(false);
JScrollPane sPane = new JScrollPane(area);
sPane.setSize(800,600);
sPane.setVisible(isWorking);
return sPane;
}

// 菜单栏listener
public void actionPerformed(ActionEvent e) {

if(e.getSource()==F_open){
if(isWorking==false){
isWorking = true;
}
JFileChooser chooser = new JFileChooser();
int returnType = chooser.showOpenDialog(null);
if(returnType==JFileChooser.APPROVE_OPTION){
File file = chooser.getSelectedFile();
String fileName = file.getAbsolutePath();
CatchPacket.sb.delete(0, CatchPacket.sb.length());
cPacket.openFile(fileName);
}

}else if(e.getSource()==F_save){
JFileChooser chooser = new JFileChooser();
int returnType = chooser.showSaveDialog(null);
if(returnType==JFileChooser.APPROVE_OPTION){
File file = chooser.getSelectedFile();
String fileName = file.getAbsolutePath();
cPacket.saveFile(fileName);
}

}else if(e.getSource()==F_exit){
int show = JOptionPane.showConfirmDialog(null, "是否关闭?", "确认关闭系统",
JOptionPane.YES_NO_OPTION);
if (show == JOptionPane.YES_OPTION) {
System.exit(0);
}else {
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}

}else if(e.getSource()==C_show){
isWorking = true;
cPacket.devices = cPacket.getDevices();
CatchPacket.sb.delete(0, CatchPacket.sb.length());
cPacket.desNetworkInterface();
area.setText(CatchPacket.sb.toString());

}else if(e.getSource()==C_Configure){
configure = new Configure();
configure.init(cPacket);

}else if(e.getSource()==C_start){
if(configure==null){
JOptionPane.showMessageDialog(null, "Configure first!","INFORMATION",JOptionPane.INFORMATION_MESSAGE);
}else{
isWorking = true;
cPacket.getCap(CatchPacket.chooseDevice, CatchPacket.chooseMode, "");
thread = new Thread(cPacket);
CatchPacket.sb.delete(0, CatchPacket.sb.length());
thread.start();
}
}
else if(e.getSource()==C_stop){
if(thread.isAlive()){
thread.stop();
}
}
else if(e.getSource()==T_wireshake){
String cmd ="rundll32 url.dll,FileProtocolHandler C://Program Files//Wireshark//wireshark.exe";
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e1) {
e1.printStackTrace();
}
}else if(e.getSource()==T_factory){
String cmd ="rundll32 url.dll,FileProtocolHandler http://standards.ieee.org/regauth/oui/index.shtml"; try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e1) {
e1.printStackTrace();
}
}else if(e.getSource()==H_api){
String cmd ="rundll32 url.dll,FileProtocolHandler E://doc//javadoc//index.html";
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e1) {
e1.printStackTrace();
}
}else if(e.getSource()==H_author){
//查看空间
String cmd ="rundll32 url.dll,FileProtocolHandler http://user.qzone.qq.com/627443660?ADUIN=627443660&ADSESSION=1277106345&ADTAG=CLIENT.QQ.2881_MyTip.0&ptlang=2052"; try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e1) {
e1.printStackTrace();
}
}

}

// 窗口listener
public void windowActivated(WindowEvent arg0) {}

public void windowClosed(WindowEvent arg0) {}

public void windowDeactivated(WindowEvent arg0) {}

public void windowDeiconified(WindowEvent arg0) {}

public void windowOpened(WindowEvent arg0) {}

public void windowClosing(WindowEvent e) {
int show = JOptionPane.showConfirmDialog(null, "是否关闭?", "确认关闭系统",
JOptionPane.YES_NO_OPTION);
if (show == JOptionPane.YES_OPTION) {
System.exit(0);
}else {
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
}

// 最小化
public void windowIconified(WindowEvent arg0) {
if (getState() == Frame.ICONIFIED) {
try {
sTray = SystemTray.getSystemTray();
sTray.add(tIcon);
} catch (AWTException e1) {
e1.printStackTrace();
}
setVisible(false);
}
}

public static void main(String[] args) {
try {
UIManager.setLookAndFeel(new SubstanceLookAndFeel());

}catch(Exception e){

}
MainFrame mFrame = new MainFrame();
Thread mThread = new Thread(mFrame);
mThread.setPriority(Thread.MAX_PRIORITY);
mThread.start();

}

public void run() {
while(true){
try {
Thread.sleep(800);
this.mainPanel1.setVisible(!isWorking);
this.mainPanel2.setVisible(isWorking);
area.setText(CatchPacket.sb.toString());
con.validate();
con.repaint();

} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

}

②:Configure类
package cn.com.wwc;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import jpcap.JpcapCaptor;
import jpcap.NetworkInterface;

public class Configure extends JFrame implements ActionListener{

private JLabel choose_Device = new JLabel("Choose a Network Interface:");
private JLabel choose_Mode = new JLabel("Choose Work Mode:");
private JLabel set_Filter = new JLabel("Set Filter:");
private JComboBox device_Box ;
private JComboBox mode_Box;
private JTextField filter_Field = new JTextField("Input here");
private JButton go = new JButton("Go");

public static NetworkInterface[] devices;
public String[] device_Names;
public String[] mode_Names = new String[]{"混杂模式","优化模式"};
public CatchPacket catchPacket;

public void init(CatchPacket cPacket){
this.catchPacket = cPacket;
devices = cPacket.getDevices();
device_Names = new String[devices.length];
for(int i=0;i<devices.length;i++){
device_Names[i] = devices[i].description+i;
}
device_Box = new JComboBox(device_Names);
device_Box.setSelectedIndex(device_Names.length-1);
mode_Box = new JComboBox(mode_Names);
mode_Box.setSelectedIndex(0);
//布局
setLayout(null);
choose_Device.setBounds(50, 20, 250, 20);
add(choose_Device);
device_Box.setBounds(300, 20, 250, 20);
add(device_Box);
choose_Mode.setBounds(50, 50, 250, 20);
add(choose_Mode);
mode_Box.setBounds(300, 50, 250, 20);
add(mode_Box);
set_Filter.setBounds(50, 80, 250, 20);
add(set_Filter);
filter_Field.setBounds(300, 80, 250, 20);
add(filter_Field);
go.setBounds(500, 110, 50, 20);
add(go);

setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Configure");
setSize(600, 180);
setResizable(false);
setVisible(true);

// device_Box.addItemListener(this);
// mode_Box.addItemListener(this);
// filter_Field.addActionListener(this);
go.addActionListener(this);
}

public void actionPerformed(ActionEvent e) {
String device_Item = (String)device_Box.getSelectedItem();
String mode_Item = (String)mode_Box.getSelectedItem();
Boolean is_Mix = true;
for(int i=0;i<devices.length;i++){
if(device_Item.endsWith(i+"")){
catchPacket.chooseDevice = devices[i];
break;
}
}
if(mode_Item.equals("混杂模式")){
is_Mix = true;
}else
is_Mix = false;
catchPacket.chooseMode = is_Mix;
catchPacket.inputFilter = filter_Field.getText();
this.setVisible(false);

/*if(e.getSource()==device_Box){
device_Box.getSelectedIndex();

}
if(e.getSource()==filter_Field){
String msg = filter_Field.getText();
msg = msg.trim();
if(msg!=null || !msg.equals("")||!msg.equals("Input here")){
catchPacket.inputFilter = msg;
sets[2] = true; //表示过滤器已设
this.setVisible(false);
}
}*/

}

public static void main(String[] args) {
// new Configure();
}

}

③:CatchPacket类
package cn.com.wwc;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedList;
import javax.swing.JOptionPane;
import jpcap.JpcapCaptor;
import jpcap.JpcapWriter;
import jpcap.NetworkInterface;
import jpcap.PacketReceiver;
import jpcap.packet.ARPPacket;
import jpcap.packet.DatalinkPacket;
import jpcap.packet.EthernetPacket;
import jpcap.packet.ICMPPacket;
import jpcap.packet.IPPacket;
import jpcap.packet.Packet;
import jpcap.packet.TCPPacket;
import jpcap.packet.UDPPacket;

public class CatchPacket implements PacketReceiver,Runnable {

public NetworkInterface[] devices;
public NetworkInterface device;
public JpcapCaptor jCaptor;
public JpcapWriter writer;
public LinkedList<Packet> packets = new LinkedList();

public static NetworkInterface chooseDevice;
public static boolean chooseMode;
public static String inputFilter;
public static StringBuffer sb = new StringBuffer();

// 获得网络接口list
public NetworkInterface[] getDevices() {
devices = JpcapCaptor.getDeviceList();
return devices;
}

// 获得网卡接口list描述
public void desNetworkInterface() {
sb.append("************************网卡信息****************************************/n");
sb.append("总共有 " + devices.length + " 个网络设备接口/n");
for (int i = 0; i < devices.length; i++) {
sb.append("/n设备接口" + (i + 1) + ":/n");
sb.append("网络接口名称:" + devices[i].name+"/n");
// 选中一个网卡接口进行监听
if (!(devices[i].name.contains("GenericDialupAdapter"))) {
device = devices[i];
}
sb.append("网络接口描述:" + devices[i].description+"/n");
sb.append("数据链路层名称:" + devices[i].datalink_name+"/n");
sb.append("数据链路层描述:" + devices[i].datalink_description+"/n");
sb.append("是否是LOOPBACK设备:" + devices[i].loopback+"/n");
sb.append("MAC地址:");
int flag = 0;
for (byte b : devices[i].mac_address) {
flag++;
if (flag < devices[i].mac_address.length) {
sb.append(Integer.toHexString(b & 0xff) + ":");
} else
sb.append(Integer.toHexString(b & 0xff)+"/n");
}
}
sb.append("**********************************************************************/n");
// System.out.println(sb);

}

// 获得某个网卡接口的连接
public void getCap(NetworkInterface nInterface, boolean mixMode,String filter){
try {
jCaptor = JpcapCaptor.openDevice(nInterface, 2048, mixMode, 5000);
} catch (IOException e) {
e.printStackTrace();
}

}

// 设置过滤器
public void setFilter(String filter){
try {
jCaptor.setFilter(filter, true);
} catch (IOException e) {
e.printStackTrace();
}
}

// 设置抓包模式开始抓包
public void beginCatch() {

jCaptor.processPacket(1, this);
}

// 结束抓包
public void endCatch() {
if (jCaptor != null) {
jCaptor.breakLoop();
}
}

// 保存捕获包于文件中
public void saveFile(String fileName) {
if(jCaptor == null){
JOptionPane.showMessageDialog(null, "No Packet yet!","NO-PACKETS",JOptionPane.INFORMATION_MESSAGE);
}else{
try {
writer = JpcapWriter.openDumpFile(jCaptor, fileName);
while (packets.size() != 0) {
writer.writePacket(packets.removeFirst());
}
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

// 打开存于文件中的包
public void openFile(String fileName) {
try {
jCaptor = JpcapCaptor.openFile(fileName);
while (true) {
Packet packet = jCaptor.getPacket();
if (packet == null || packet == Packet.EOF) {
break;
}
analysis(packet);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(jCaptor!=null){
jCaptor.close();
}
}
}

public void analysis(Packet packet) {
sb.append("------包分析-------/n");
sb.append("Captured Length:"+packet.caplen+" byte/n");
sb.append("Length of this Packet:"+packet.len+" byte/n");
sb.append("Header:"+packet.header+"/n");
sb.append("Length of Header:"+packet.header.length+" byte/n");
sb.append("Data:"+packet.data+"/n");
sb.append("Length of Data:"+packet.data.length+" byte/n");
sb.append("---Ethernet头部信息---/n");

DatalinkPacket dPacket = packet.datalink;
if(dPacket instanceof EthernetPacket){ //分析以太网帧
EthernetPacket ePacket = (EthernetPacket)dPacket;
sb.append("src_mac:");
int flag1 = 0;
for(byte b:ePacket.src_mac){
flag1++;
if(flag1<ePacket.src_mac.length){
sb.append(Integer.toHexString(b & 0xff)+":");
}else
sb.append(Integer.toHexString(b & 0xff)+"/n");
}
sb.append("dst_mac:");
int flag2 = 0;
for(byte b:ePacket.dst_mac){
flag2++;
if(flag2<ePacket.dst_mac.length){
sb.append(Integer.toHexString(b & 0xff)+":");
}else
sb.append(Integer.toHexString(b & 0xff)+"/n");
}
sb.append("frametype:"+Integer.toHexString(ePacket.frametype & 0xffff)+"/n");
sb.append("------------------/n");

}else{
sb.append(dPacket+"/n");
sb.append("------------------/n");
}

if(packet instanceof ARPPacket){ //分析ARP协议
sb.append("---ARP---/n");
ARPPacket aPacket = (ARPPacket)packet;
sb.append("硬件类型:"+aPacket.hardtype+"/n");
sb.append("协议类型:"+aPacket.prototype+"/n");
sb.append("硬件地址长度:"+aPacket.hlen+"/n");
sb.append("协议地址长度:"+aPacket.plen+"/n");
sb.append("Operation:"+aPacket.operation+"/n");
sb.append("发送者硬件地址:"+aPacket.sender_hardaddr+"/n");
sb.append("发送者协议地址:"+aPacket.sender_protoaddr+"/n");
sb.append("目标硬件地址:"+aPacket.target_hardaddr+"/n");
sb.append("目标协议地址:"+aPacket.target_protoaddr+"/n");
sb.append("------------------/n");
}

if(packet instanceof ICMPPacket){ //分析ICMP协议
sb.append("---ICMP---/n");
ICMPPacket iPacket = (ICMPPacket)packet;
sb.append("ICMP_TYPE:"+iPacket.type+"/n");
sb.append("由于ICMP格式种类繁多,故省去不分析/n");
sb.append("------------------/n");
}

if(packet instanceof IPPacket){ //分析IP
IPPacket iPacket = (IPPacket)packet;
sb.append("---IP版本: "+iPacket.version+" ---/n");
if(iPacket.version==4){ //分析IPv4协议
sb.append("Type of service:"+iPacket.rsv_tos+"/n");
sb.append("Priprity:"+iPacket.priority+"/n");
sb.append("Packet Length:"+iPacket.length+"/n");
sb.append("Identification:"+iPacket.ident+"/n");
sb.append("Don't Frag? "+iPacket.dont_frag+"/n");
sb.append("More Frag? "+iPacket.more_frag+"/n");
sb.append("Frag Offset:"+iPacket.offset+"/n");
sb.append("Time to Live:"+iPacket.hop_limit+"/n");
sb.append("Protocol:"+iPacket.protocol+" (TCP = 6; UDP = 17)/n");
sb.append("Source address:"+iPacket.src_ip.toString()+"/n");
sb.append("Destination address:"+iPacket.dst_ip.toString()+"/n");
sb.append("Options:"+iPacket.option+"/n");
sb.append("------------------/n");
}

if(iPacket instanceof UDPPacket){ //分析UDP协议
sb.append("---UDP---/n");
UDPPacket uPacket = (UDPPacket)iPacket;
sb.append("Source Port:"+uPacket.src_port+"/n");
sb.append("Destination Port:"+uPacket.dst_port+"/n");
sb.append("Length:"+uPacket.length+"/n");
sb.append("------------------/n");

if(uPacket.src_port==53||uPacket.dst_port==53){ //分析DNS协议
sb.append("---DNS---/n");
sb.append("此包已抓获,分析略.../n");
sb.append("------------------/n");
}
}

if(iPacket instanceof TCPPacket){ //分析TCP协议
sb.append("---TCP---/n");
TCPPacket tPacket = (TCPPacket)iPacket;
sb.append("Source Port:"+tPacket.src_port+"/n");
sb.append("Destination Port:"+tPacket.dst_port+"/n");
sb.append("Sequence Number:"+tPacket.sequence+"/n");
sb.append("Acknowledge Number:"+tPacket.ack_num+"/n");
sb.append("URG:"+tPacket.urg+"/n");
sb.append("ACK:"+tPacket.ack+"/n");
sb.append("PSH:"+tPacket.psh+"/n");
sb.append("RST:"+tPacket.rst+"/n");
sb.append("SYN:"+tPacket.syn+"/n");
sb.append("FIN:"+tPacket.fin+"/n");
sb.append("Window Size:"+tPacket.window+"/n");
sb.append("Urgent Pointer:"+tPacket.urgent_pointer+"/n");
sb.append("Option:"+tPacket.option+"/n");
sb.append("------------------/n");

if(tPacket.src_port==80 || tPacket.dst_port==80){ //分析HTTP协议
sb.append("---HTTP---/n");
byte[] data = tPacket.data;
if(data.length==0){
sb.append("此为不带数据的应答报文!/n");
}else{
if(tPacket.src_port==80){ //接受HTTP回应
String str = null;
try {
String str1 = new String(data,"UTF-8");
if(str1.contains("HTTP/1.1")){
str = str1;
}else{
String str2 = new String(data,"GB2312");
if(str2.contains("HTTP/1.1")){
str = str2;
}else{
String str3 = new String(data,"GBK");
if(str3.contains("HTTP/1.1")){
str = str3;
}else{
str = new String(data,"Unicode");
}
}
}
sb.append(str+"/n");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

if(tPacket.dst_port==80){
try{
String str = new String(data,"ASCII");
sb.append(str);
}catch (Exception e) {
// TODO: handle exception
}
}
}

}

}
sb.append("/n");
System.out.println(sb);

}

}

public void receivePacket(Packet packet) {
packets.add(packet);
analysis(packet);
}

public static void main(String[] args) {
CatchPacket cPacket = new CatchPacket();
cPacket.devices = cPacket.getDevices();
cPacket.desNetworkInterface();
cPacket.getCap(cPacket.device, true, "");
Thread thread = new Thread(cPacket);
sb.delete(0, sb.length());
thread.start();
}

public void run() {
while(true){
try {
Thread.sleep(5000);
beginCatch();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐