📄 ip.java
字号:
package ip.class3.cie;
import jpcap.*;
import jpcap.packet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.InetAddress;
import java.sql.Timestamp;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.TitledBorder;
/**
* 创建一个执行接口PacketReceiver类的一个实例IP类
* 实现用表格或图表显示所抓包详细信息
* 实现将所有包的详细详细信息写进文件
*
* 作者:蒲德祥
*
*/
class IP implements PacketReceiver {
PacketPanel udpPanel,tcpPanel,icmpPanel,arpPanel;
JPanel mainPanel, statePanel,northPanel, imagePanel;
private JLabel label;//提示各种包个数
private JButton button, toDiagram;//表格与图表的切换
private JButton stopButton; //停止监控
private boolean isCatch;//使用表格与图表的标志
private boolean isToCatch;//是否监控IP
private int udpCount, tcpCount, icmpCount, arpCount, sunCount;//包个数
private int gCount, mCount, kCount, bCount;//流量统计
private String localAddress;
//文件读写缓冲区
private StringBuffer udpBuffer, tcpBuffer, icmpBuffer, arpBuffer;
//控制文件输入时间
private Timer writeToFile;
ImageCanvas imageCanvas;//图表画布
public IP(String address) {
localAddress = address;//获得本地IP
}
/**
* 抓包;分ARP,UDP,TCP,ICMP包
*/
public void receivePacket(Packet packet) {
if(isToCatch) {
try {
ARPPacket arp = (ARPPacket)packet;
String address = arp.toString().substring(12, arp.toString().length());
//捕获时间
String time = new Timestamp((packet.sec * 1000) +
(packet.usec / 1000)).toString();
//报文头长度
String leng = " "+(packet.len-packet.header.length);
//报文长度
String packetLength = " "+packet.len;
arpBuffer.append(address+" "+time+" "+leng+" "+packetLength+"\r\n");
//通过表格将包内容显示出来
if(isCatch) {
arpPanel.comTable.addRow(getTableCell(time, leng, address, packetLength));
}
arpCount ++;
bCount += packet.len;
}catch( Exception e ) {
}
try {
String address = ((ICMPPacket)packet).dst_ip.toString();
address = address.substring(1, address.length());
address = getAddress(address, localAddress);
String time = new Timestamp((packet.sec * 1000) +
(packet.usec / 1000)).toString();
//报文长度
String leng = ""+(packet.len-packet.header.length);
//包大小
String packetLength = ""+packet.len;
System.out.println(((ICMPPacket)packet).src_ip.toString());
//通过表格将包内容显示出来
if(isCatch) {
icmpPanel.comTable.addRow(getTableCell(time, leng, address, packetLength));
}
icmpBuffer.append(address+" "+time+" "+leng+" "+packetLength+"\r\n");
icmpCount ++;
bCount += packet.len;
}catch( Exception e ) {
}
try {
//IP 地址
String address = ((UDPPacket)packet).dst_ip.toString();
address = address.substring(1, address.length());
address = getAddress(address, localAddress);
//捕获时间
String time = new Timestamp((packet.sec * 1000) +
(packet.usec / 1000)).toString();
//报文头长度
String leng = " "+(packet.len-packet.header.length);
//报文长度
String packetLength = " "+packet.len;
//通过表格将包内容显示出来
if(isCatch) {
udpPanel.comTable.addRow(getTableCell(time, leng, address, packetLength));
}
udpBuffer.append(address+" "+time+" "+leng+" "+packetLength+"\r\n");
udpCount ++;
bCount += packet.len;
}catch( Exception e ){ }
try {
String address = ((TCPPacket)packet).dst_ip.toString();
address = address.substring(1, address.length());
address = getAddress(address, localAddress);
String time = new Timestamp((packet.sec * 1000) +
(packet.usec / 1000)).toString();
// //报文头长度
String leng = " "+(packet.len-packet.header.length);
//报文长度
String packetLength = " "+packet.len;
//通过表格将包内容显示出来
if(isCatch) {
tcpPanel.comTable.addRow(getTableCell(time, leng, address, packetLength));
}
tcpBuffer.append(address+" "+time+" "+leng+" "+packetLength+"\r\n");
tcpCount ++;
bCount += packet.len;
}catch( Exception e ) {
}
//计算流量大小K字节
kCount += bCount/1024;
bCount = bCount%1024;
//计算流量大小M字节
mCount += kCount/1024;
kCount = kCount%1024;
//计算流量大小G字节
gCount += mCount/1024;
mCount = mCount%1024;
//计算总包数
sunCount = arpCount+tcpCount+udpCount+icmpCount;
//如果在图表模式下显示图表
if(!isCatch) {
imageCanvas.setPackeg(udpCount,tcpCount, icmpCount, arpCount);
imageCanvas.repaint();
}
//显示抓包信息
label.setText("UDP包个数:"+udpCount+
" TCP包个数:"+tcpCount+
" ICMP包个数:"+icmpCount+
" ARP包个数:"+arpCount+
" 一共抓获"+sunCount+"个数据包 "+
" 流量:"+gCount+"G"+mCount+"M"+kCount+"K"+bCount+"B");
}
}
/**
* 判断本地地址、外地地址
* @param address
* @param localAddress
* @return
*/
public String getAddress(String address, String localAddress) {
String local = null;
if(address.compareTo(localAddress) == 0) {
local = "本";
}
else
local = "外";
return local+address;
}
/**
* 表格单元格设置
* @param time
* @param leng
* @param address
* @param packetLength
* @return
*/
public Vector getTableCell(String time, String leng,
String address, String packetLength) {
Vector vec = new Vector();
vec.addElement(time);
vec.addElement(leng);
vec.addElement(address);
vec.addElement(packetLength);
return vec;
}
/**
* 将包的内容写到文件里面
*/
public void writeToFile(String str, int whatPacket) {
File udpFile = new File("D:\\packeges/UDP.txt");
File tcpFile = new File("D:\\packeges/TCP.txt");
File icmpFile = new File("D:\\packeges/ICMP.txt");
File arpFile = new File("D:\\packeges/ARP.txt");
File file = null;
//根据包的内容写入不同的文件
switch(whatPacket) {
case 0:
file = udpFile;
break;
case 1:
file = tcpFile;
break;
case 2:
file = icmpFile;
break;
case 3:
file = arpFile;
break;
}
//写文件
try {
if(!file.exists()){
file.createNewFile();//不存在则创建
}
FileWriter fw = new FileWriter(file,true);
fw.append(str);
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 初始化整个系统
*/
public void init() {
isCatch = true;
isToCatch = true;
mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(2, 2));
//通过不同的参数列出不同名字表格
udpPanel = new PacketPanel("UDP packet");
tcpPanel = new PacketPanel("TCP packet");
icmpPanel = new PacketPanel("ICMP packet");
arpPanel = new PacketPanel("ARP packet");
//将不同的表格添加到主视图中
mainPanel.add(udpPanel);
mainPanel.add(tcpPanel);
mainPanel.add(icmpPanel);
mainPanel.add(arpPanel);
imageCanvas = new ImageCanvas();
toDiagram = new JButton("图表显示");
toDiagram.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
isCatch = false;
toDiagram.setEnabled(false);//模式设置
button.setEnabled(true);
mainPanel.removeAll();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(imageCanvas, BorderLayout.CENTER);
imageCanvas.repaint();
mainPanel.updateUI();
}
});
button = new JButton("表格显示");
button.setEnabled(false);//默认显示表格,按纽不可访问
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
isCatch = true;
button.setEnabled(false);//模式设置
toDiagram.setEnabled(true);
mainPanel.removeAll();
mainPanel.setLayout(new GridLayout(2, 2));
mainPanel.add(udpPanel);
mainPanel.add(tcpPanel);
mainPanel.add(icmpPanel);
mainPanel.add(arpPanel);
mainPanel.updateUI();
}
});
stopButton = new JButton("停止监控");
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(isToCatch) {
isToCatch = false;
stopButton.setText("开始监控");
}
else {
isToCatch = true;
stopButton.setText("停止监控");
}
}
});
northPanel = new JPanel();
northPanel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.black,1),
"",
TitledBorder.CENTER,
TitledBorder.TOP));
northPanel.setLayout(new FlowLayout());
northPanel.add(button);
northPanel.add(toDiagram);
northPanel.add(stopButton);
//初始化包个数
udpCount = 0;
tcpCount = 0;
icmpCount = 0;
arpCount = 0;
sunCount = 0;
//初始化流量
gCount = 0;
mCount = 0;
kCount = 0;
bCount = 0;
statePanel = new JPanel();
statePanel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.black,1),
"",
TitledBorder.CENTER,
TitledBorder.TOP));
label = new JLabel("UDP包个数:"+udpCount+
" TCP包个数:"+tcpCount+
" ICMP包个数:"+icmpCount+
" ARP包个数:"+arpCount+
" 一共抓获"+sunCount+"个数据包 "+
" 流量:"+gCount+"G"+mCount+"M"+kCount+"K"+bCount+"B");
label.setForeground(Color.red);
statePanel.add(label);
//初始化文件读写缓冲区
udpBuffer = new StringBuffer();
tcpBuffer = new StringBuffer();
icmpBuffer = new StringBuffer();
arpBuffer = new StringBuffer();
//每隔10秒向文件写入数据
writeToFile = new Timer(10000, null);
writeToFile.start();
writeToFile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//追加写入文件
writeToFile(udpBuffer.toString(), 0);
writeToFile(tcpBuffer.toString(), 1);
writeToFile(icmpBuffer.toString(), 2);
writeToFile(arpBuffer.toString(), 3);
//获得文件缓冲区存放数据的大小
int udp = udpBuffer.length();
int tcp = tcpBuffer.length();
int icmp = icmpBuffer.length();
int arp = arpBuffer.length();
//清空文件缓冲区
if(udp > 0)
udpBuffer.delete(0, udp-1);
if(tcp > 0)
tcpBuffer.delete(0, tcp-1);
if(icmp > 0)
icmpBuffer.delete(0, icmp-1);
if(arp > 0)
arpBuffer.delete(0, arp-1);
}
});
}
/**
* 主函数
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//返回一个网络设备列表
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
//打开连接设备实例1,提取每次数据包中前2000字节,设置网卡为混杂模式,最后指定超时时间为20
JpcapCaptor jpcap = JpcapCaptor.openDevice( devices[1], 2000, true, 20);
//指定捕获一个数据包,如果设为-1,则为无限循环地捕获,调用抽象方法void receive(Packet packet)
InetAddress addr = InetAddress.getLocalHost();
String bip=addr.getHostAddress().toString();//获得本机IP
IP ip = new IP(bip);
ip.init();
JFrame f = new JFrame("IP 包监控");
f.setSize(800, 600);
f.add(ip.mainPanel, BorderLayout.CENTER);
f.add(ip.northPanel, BorderLayout.NORTH);
f.add(ip.statePanel, BorderLayout.SOUTH);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jpcap.loopPacket(-1, ip);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -