使用java jpcap实现网络嗅探器

参考 https://blog.csdn.net/qq_34838643/article/details/78891127

标题
使用java进行实现网络嗅探器。

实验环境
Win10+Eclipse+JDK1.8+Winpcap+Jpcap

Jpcap
Jpcap实际上并非一个真正去实现对数据链路层的控制,而是一个中间件,JPCAP调用wincap/libpcap,而给JAVA语言提供一个公共的接口,从而实现了平台无关性。Java的.net包中,给出了传输层协议 TCP和UDP有关的API,用户只能操作传输层数据,要想直接操作网络层{比如自己写传输层数据报(自己写传输层包头),或者自己写好IP数据包向网络中发}则是无能为力的。 而JPCAP扩展包弥补了这一点,使我们可以支持从网卡中接收IP数据包,或者向网卡中发送IP数据包。

框架设计
MVC

详情请见:https://blog.csdn.net/qq_37865996/article/details/84311020

Jpcap的安装和使用
下载:https://download.csdn.net/download/qq_37865996/10797446

解压后,在已配置好java的环境和IDE后,将压缩包中的jpcap.dll粘贴到jre的bin文件夹中去。

将jpcap.jar作为库文件

Winpcap
在windows中进行抓包这是必不可少的。

https://www.winpcap.org/archive/

功能设置
1.作为Sniffer,即实现嗅探功能,抓包并分析;

2.选定网卡;

3.侦听所有进出本主机的数据包,解析显示数据包( ICMP 、 IP 、 TCP 、 UDP 等)各个字段及数据内容

4.指定功能:

侦听来源于指定 IP 地址的数据包,侦听指定目的 IP 地址的数据包 ;

获取数据包的详细信息,首部的各字段,包括源IP,目的IP,源端口,目的端口,源MAC,目的MAC等,将数据内容通过gbk方式解码;

侦听指定协议的数据包;

侦听含有指定数据的数据报包 ;

保存选中的包到本地。

使用流程
(1)启动程序,展示用户界面
(2)获取当前网卡列表,用户指定要操作的网卡
(3)获取当前过滤规则,可通过协议,源IP,目的IP,关键字进行过滤,也可为空
(4)展示数据包基本信息
(5)根据用户点击的内容,对该包进行解析,显示详细内容

代码
cControl

NetworkCard.java网卡类

package cControl;
import jpcap.*;
 
public class NetworkCard {
    
    
	String[] devices;
	public static NetworkInterface[] getDevices() {
    
    
	    NetworkInterface[] devices = JpcapCaptor.getDeviceList();
		return devices;
	}
}
PacketAnanlyze.java分析类

package cControl;
 
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import jpcap.packet.*;
 
 
public class PacketAnalyze {
    
    
	static Packet packet;
	static HashMap<String,String> att,att1;
	public PacketAnalyze(Packet packet){
    
    
		this.packet = packet;	
	}
	public static HashMap<String,String> packetClass(){
    
    
		att1 = new HashMap<String,String>();
		if(packet.getClass().equals(ICMPPacket.class)){
    
    
			att1 = ICMPanalyze();
		}else if(packet.getClass().equals(TCPPacket.class)){
    
    
			att1 = TCPanalyze();
		}else if(packet.getClass().equals(UDPPacket.class)){
    
    
			att1 = UDPanalyze();
		}
		return att;
	}
	public static HashMap<String,String> IPanalyze(){
    
    
		att = new HashMap<String,String>();
		if(packet instanceof IPPacket){
    
    
			IPPacket ippacket = (IPPacket) packet;
			att.put("协议", new String("IP"));
			att.put("源IP", ippacket.src_ip.toString().substring(1, ippacket.src_ip.toString().length()));
			att.put("目的IP", ippacket.dst_ip.toString().substring(1, ippacket.dst_ip.toString().length()));
			att.put("TTL", String.valueOf(ippacket.hop_limit));
			att.put("头长度", String.valueOf(ippacket.header.length));
			att.put("是否有其他切片", String.valueOf(ippacket.more_frag));
		}
		return att;
	}
	public static HashMap<String,String> ICMPanalyze(){
    
    
		att = new HashMap<String,String>();
		ICMPPacket icmppacket = (ICMPPacket) packet;
		att.put("协议", new String("ICMP"));
		att.put("源IP", icmppacket.src_ip.toString().substring(1, icmppacket.src_ip.toString().length()));
		att.put("目的IP", icmppacket.dst_ip.toString().substring(1, icmppacket.dst_ip.toString().length()));
		return att;
	}
	public static HashMap<String,String> TCPanalyze(){
    
    
		att = new HashMap<String,String>();
		TCPPacket tcppacket = (TCPPacket) packet;
		EthernetPacket ethernetPacket=(EthernetPacket)packet.datalink;
		att.put("协议", new String("TCP"));
		att.put("源IP", tcppacket.src_ip.toString().substring(1, tcppacket.src_ip.toString().length()));
		att.put("源端口", String.valueOf(tcppacket.src_port));
		att.put("目的IP", tcppacket.dst_ip.toString().substring(1, tcppacket.dst_ip.toString().length()));
		att.put("目的端口", String.valueOf(tcppacket.dst_port));
		att.put("源MAC", ethernetPacket.getSourceAddress());
		att.put("目的MAC", ethernetPacket.getDestinationAddress());
		try {
    
    
			att.put("数据", new String(tcppacket.data,"gbk"));
		} catch (UnsupportedEncodingException e) {
    
    
			e.printStackTrace();
		}
		return att;
	}
	public static HashMap<String,String> UDPanalyze(){
    
    
		att = new HashMap<String,String>();
		UDPPacket udpppacket = (UDPPacket) packet;
		EthernetPacket ethernetPacket=(EthernetPacket)packet.datalink;
		att.put("协议", new String("UDP"));
		att.put("源IP", udpppacket.src_ip.toString().substring(1, udpppacket.src_ip.toString().length()));
		att.put("源端口", String.valueOf(udpppacket.src_port));
		att.put("目的IP", udpppacket.dst_ip.toString().substring(1, udpppacket.dst_ip.toString().length()));
		att.put("目的端口", String.valueOf(udpppacket.dst_port));
		att.put("源MAC", ethernetPacket.getSourceAddress());
		att.put("目的MAC", ethernetPacket.getDestinationAddress());
		try {
    
    
			att.put("数据", new String(udpppacket.data,"gbk"));
		} catch (UnsupportedEncodingException e) {
    
    
			e.printStackTrace();
		}
	
		return att;
	}
}

PacketCaputure.java抓包类


package cControl;
 
import java.io.IOException;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import jpcap.*;
import jpcap.packet.*;
 
/*抓包*/
public class PacketCapture implements Runnable {
    
    
 
	NetworkInterface device;
	static DefaultTableModel tablemodel;
	static String FilterMess = "";
	static ArrayList<Packet> packetlist = new ArrayList<Packet>();
	public PacketCapture() {
    
    
	}
	public void setDevice(NetworkInterface device){
    
    
		this.device = device;
	}
	public void setTable(DefaultTableModel tablemodel){
    
    
		this.tablemodel = tablemodel;
	}
	public void setFilter(String FilterMess){
    
    
		this.FilterMess = FilterMess;
	}
	public void clearpackets(){
    
    
		packetlist.clear();
	}
	@Override
	public void run() {
    
    
		// TODO Auto-generated method stub
		Packet packet;
		try {
    
    
			JpcapCaptor captor = JpcapCaptor.openDevice(device, 65535,true, 20);
			//System.out.println(device.name);
			while(true){
    
    
				long startTime = System.currentTimeMillis();
				while (startTime + 600 >= System.currentTimeMillis()) {
    
    
					//captor.setFilter(FilterMess, true);
					packet = captor.getPacket();
					// 设置过滤器
					if(packet!=null&&TestFilter(packet)){
    
    
						//System.out.println(packet);
						packetlist.add(packet);
						showTable(packet);
					}
				}
				Thread.sleep(2000);
			}
		} catch (IOException e) {
    
    
			e.printStackTrace();
		} catch (InterruptedException e) {
    
    
			e.printStackTrace();
		}	
	}
	//将抓到包的信息添加到列表
	public static void showTable(Packet packet){
    
    
		String[] rowData = getObj(packet);
		tablemodel.addRow(rowData);
	}
	//其他类通过此方法获取Packet的列表
	public static ArrayList<Packet> getpacketlist(){
    
    
		return packetlist;
	}
	//设置过滤规则
	public static boolean TestFilter(Packet packet){
    
    
		if(FilterMess.contains("sip")){
    
    
			String sip = FilterMess.substring(4, FilterMess.length());
			if(new PacketAnalyze(packet).packetClass().get("源IP").equals(sip)){
    
    
				return true;
			}
		}else if(FilterMess.contains("dip")){
    
    
			String dip = FilterMess.substring(4, FilterMess.length());
			if(new PacketAnalyze(packet).packetClass().get("目的IP").equals(dip)){
    
    
				return true;
			}
		}else if(FilterMess.contains("ICMP")){
    
    
			if(new PacketAnalyze(packet).packetClass().get("协议").equals("ICMP")){
    
    
				return true;
			}
		}
		else if(FilterMess.contains("UDP")){
    
    
			if(new PacketAnalyze(packet).packetClass().get("协议").equals("UDP")){
    
    
				return true;
			}
		}else if(FilterMess.contains("TCP")){
    
    
			if(new PacketAnalyze(packet).packetClass().get("协议").equals("TCP")){
    
    
				return true;
			}
		}else if(FilterMess.contains("keyword")){
    
    
			String keyword = FilterMess.substring(8, FilterMess.length());
			if(new PacketAnalyze(packet).packetClass().get("数据").contains(keyword)){
    
    
				return true;
			}
		}else if(FilterMess.equals("")){
    
    
			return true;
		}
		return false;
	}
	//将抓的包的基本信息显示在列表上,返回信息的String[]形式
	public static String[] getObj(Packet packet){
    
    
		String[] data = new String[6];
		if (packet != null&&new PacketAnalyze(packet).packetClass().size()>=3) {
    
    
			Date d = new Date();
			DateFormat df = new SimpleDateFormat("HH:mm:ss");
			data[0]=df.format(d);
			data[1]=new PacketAnalyze(packet).packetClass().get("源IP");
			data[2]=new PacketAnalyze(packet).packetClass().get("目的IP");
			data[3]=new PacketAnalyze(packet).packetClass().get("协议");
			data[4]=String.valueOf(packet.len);
		}
		return data;
	}
}


Main.java

```java
package main;
 
import javax.swing.JMenuItem;
 
import jpcap.NetworkInterface;
import cControl.NetworkCard;
import show.MyInterface;
 
public class Main {
    
    
 
	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		new MyInterface();
	}
 
}
view

MyInterface.java界面类

package show;
 
import java.awt.*;
import java.awt.event.*;
import java.io.FileOutputStream;
import java.util.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import jpcap.NetworkInterface;
import jpcap.packet.Packet;
import cControl.PacketCapture;
import cControl.NetworkCard;
import cControl.PacketAnalyze;
 
public class MyInterface extends JFrame{
    
    
	JMenuBar menubar;   //菜单条
	JMenu menuFile1,menuFile2; //菜单
	JMenuItem[] item;   //菜单项
	JMenuItem pro1,pro2,pro3;
	JTextField searchText;
	JButton sipButton,dipButton,searchButton;
	JPanel panel;  
	JScrollPane scrollPane;  
	JTable table;  
	final String[] head = new String[] {
    
    
		"时间","源IP", "目的IP", "协议", "长度"
	};
	NetworkInterface[] devices;
	Object[][] datalist = {
    
    };
	DefaultTableModel tableModel;
	PacketCapture allpackets;
	public MyInterface(){
    
    
		allpackets = new PacketCapture();
		this.setTitle("MySniffer");
		this.setBounds(650, 150, 1200, 1000);
		menubar = new JMenuBar();
		//根据网卡进行过滤
		menuFile1 = new JMenu(" 网卡  ");
		NetworkInterface[] devices = new NetworkCard().getDevices();
		item = new JMenuItem[devices.length];
		for (int i = 0; i < devices.length; i++) {
    
    
			item[i] = new JMenuItem(i + ": " + devices[i].name + "("
					+ devices[i].description  + ")");
			menuFile1.add(item[i]);
			item[i].addActionListener(
					new CardActionListener(devices[i]));
		}
		//根据协议进行过滤
		menuFile2 = new JMenu("  协议    ");
		pro1 = new JMenuItem("ICMP");
		pro2 = new JMenuItem("TCP");
		pro3 = new JMenuItem("UDP");
		pro1.addActionListener(  
				new ActionListener(){
    
      
					public void actionPerformed(ActionEvent e3) {
    
      
						allpackets.setFilter("ICMP");
						allpackets.clearpackets();
						while(tableModel.getRowCount()>0){
    
    
							tableModel.removeRow(tableModel.getRowCount()-1);
						}
					}  
				}); 
		pro2.addActionListener(  
				new ActionListener(){
    
      
					public void actionPerformed(ActionEvent e3) {
    
      
						allpackets.setFilter("TCP");
						allpackets.clearpackets();
						while(tableModel.getRowCount()>0){
    
    
							tableModel.removeRow(tableModel.getRowCount()-1);
						}
					}  
				});
		pro3.addActionListener(  
				new ActionListener(){
    
      
					public void actionPerformed(ActionEvent e3) {
    
      
						allpackets.setFilter("UDP");
						allpackets.clearpackets();
						while(tableModel.getRowCount()>0){
    
    
							tableModel.removeRow(tableModel.getRowCount()-1);
						}
					}  
				}); 
		menuFile2.add(pro1);
		menuFile2.add(pro2);
		menuFile2.add(pro3);
		//根据源IP进行过滤
		sipButton = new JButton(" 源IP ");
		sipButton.addActionListener(  
				new ActionListener(){
    
      
					public void actionPerformed(ActionEvent e) {
    
      
						String fsip = JOptionPane.showInputDialog("请输入源IP,以筛选数据包:");  
						allpackets.setFilter("sip "+fsip);
						allpackets.clearpackets();
						while(tableModel.getRowCount()>0){
    
    
							tableModel.removeRow(tableModel.getRowCount()-1);
						}
					}  
				});
		//根据目的IP进行过滤
		dipButton = new JButton(" 目的IP ");
		dipButton.addActionListener(  
				new ActionListener(){
    
      
					public void actionPerformed(ActionEvent e) {
    
      
						String fdip = JOptionPane.showInputDialog("请输入目的IP,以筛选数据包:");  
						allpackets.setFilter("dip "+fdip);
						allpackets.clearpackets();
						while(tableModel.getRowCount()>0){
    
    
							tableModel.removeRow(tableModel.getRowCount()-1);
						}
					}  
				});
		//根据关键字进行过滤
		searchButton = new JButton(" 查找  ");
		searchButton.addActionListener(  
				new ActionListener(){
    
      
					public void actionPerformed(ActionEvent e) {
    
      
						String fkeyword = JOptionPane.showInputDialog("请输入数据关键字,以筛选数据包:");    
						allpackets.setFilter("keyword "+fkeyword);
						allpackets.clearpackets();
						while(tableModel.getRowCount()>0){
    
    
							tableModel.removeRow(tableModel.getRowCount()-1);
						}
					}  
				});
		//将菜单添加到菜单条上
		menubar.add(menuFile1);  
		menubar.add(menuFile2);
		menubar.add(sipButton);
		menubar.add(dipButton);
		menubar.add(searchButton);
		setJMenuBar(menubar);
 
		tableModel = new DefaultTableModel(datalist, head);
		table = new JTable(tableModel){
    
    
			public boolean isCellEditable(int row, int column){
    
    
				return false;
			}
		};
		allpackets.setTable(tableModel);	
		table.setPreferredScrollableViewportSize(new Dimension(500, 60));// 设置表格的大小 
		table.setRowHeight(30);// 设置每行的高度为20  
		table.setRowMargin(5);// 设置相邻两行单元格的距离  
		table.setRowSelectionAllowed(true);// 设置可否被选择.默认为false  
		table.setSelectionBackground(Color.cyan);// 设置所选择行的背景色  
		table.setSelectionForeground(Color.red);// 设置所选择行的前景色  
		table.setShowGrid(true);// 是否显示网格线   
		table.doLayout();   
		scrollPane = new JScrollPane(table); 
		panel = new JPanel(new GridLayout(0, 1));  
		panel.setPreferredSize(new Dimension(600, 300));  
		panel.setBackground(Color.black);  
		panel.add(scrollPane);  
		setContentPane(panel);  
		pack();  
		table.addMouseListener(new MouseAdapter(){
    
    
			public void mouseClicked(MouseEvent ev){
    
    
				if(ev.getClickCount() == 2){
    
    
					int row = table.getSelectedRow();
					JFrame frame = new JFrame("详细信息");
					JPanel panel = new JPanel();
					final JTextArea info = new JTextArea(23, 42);
					info.setEditable(false);
					info.setLineWrap(true);
					info.setWrapStyleWord(true);
					frame.add(panel);
					panel.add(new JScrollPane(info));
					JButton save = new JButton("保存到本地");
					save.addActionListener(  
							new ActionListener(){
    
      
								public void actionPerformed(ActionEvent e3) {
    
      
									String text = info.getText();
									int name = (int)System.currentTimeMillis();
									try {
    
      
										FileOutputStream fos = new FileOutputStream("d://"+name+".txt");   
										fos.write(text.getBytes());  
										fos.close();  
									} catch (Exception e) {
    
       
										e.printStackTrace();  
									} 
								}  
							}); 
					panel.add(save);
					frame.setBounds(150, 150, 500, 500);
					frame.setVisible(true);
					frame.setResizable(false);
					ArrayList<Packet> packetlist = allpackets.getpacketlist();
					Map<String,String> hm1 = new HashMap<String,String>();
					Map<String,String> hm2 = new HashMap<String,String>();
					Packet packet = packetlist.get(row);
					info.append("------------------------------------------------------------------------------\n");
					info.append("-------------------------------IP头信息:-------------------------------\n");
					info.append("------------------------------------------------------------------------------\n");
					hm1 = new PacketAnalyze(packet).IPanalyze();
					for(Map.Entry<String,String> me1 : hm1.entrySet())
					{
    
    
						info.append(me1.getKey()+" : "+me1.getValue()+"\n");
					}
					hm2 = new PacketAnalyze(packet).packetClass();
					info.append("------------------------------------------------------------------------------\n");
					info.append("-----------------------------"+hm2.get("协议")+"头信息:-----------------------------\n");
					info.append("------------------------------------------------------------------------------\n");
					for(Map.Entry<String,String> me : hm2.entrySet())
					{
    
    
						info.append(me.getKey()+" : "+me.getValue()+"\n");
					}
				}
			}
		});
 
		setResizable(false);
		setVisible(true);
		addWindowListener(new WindowAdapter() {
    
      
			public void windowClosing(WindowEvent e) {
    
      
				System.exit(0);
			}  
 
		});   
	}
 
	private class CardActionListener implements ActionListener{
    
    
 
		NetworkInterface device;
		CardActionListener(NetworkInterface device){
    
    
			this.device = device;
		}
		public void actionPerformed(ActionEvent e) {
    
    
			allpackets.setDevice(device);
			allpackets.setFilter("");
			new Thread(allpackets).start();   //开启抓包线程
		}     
	}  
}

猜你喜欢

转载自blog.csdn.net/qq_44428824/article/details/113741789