JAVA+网络数据包的抓取与分析实验

一、实验目的

  1. 熟悉TC
  2. P/IP数据包的结构。
  3. 掌握Wireshark的使用方法。
  4. 能够利用JNet Pcap编程实现数据包的抓取与分析。

二、实验准备

1、通过抓包,可以进行网络故障分析、流量监控、隐私盗取等操作,相关的抓包工具有很多,主要有Fiddler、Wireshark、Charles等。

2、本实验需要提前安装Wireshark、配置java环境、下载并导入JNetPcap.jar包。Windows系统下需要安装WinPcap, Linux下需要安装Libcap。 WinPcap官网:WinPcap - Home

3、在数据包监听与分析方面,Java常用的类库有JPcap和JNetPcap等。由于JPcap已经好久不更新了,本实验使用JNetPcap,其抓包的过程可以概括为获取设备网卡列表、打开选中的网卡、设置过滤器、开始监听、数据包分析与展示这五个步骤。

三、实验内容

1、使用WireShark进行抓包分析

(1)打开Wireshark,选择要监控的网卡,右键后点击"start  capture"按钮开始抓包。然后,打开浏览器输入任意http网址,例如:百度一下,你就知道,接着,回到Wireshark界面,点击左上角的停止按键。查看此时Wireshark的抓包信息。

(2)在Wireshark的filter中输入过滤语句http.request.method==POST,即只抓取http协议中post请求的包。然后登录学校教务网站,就可以抓到表单提交的post请求包。分析包的结构,查找用户名和密码信息。

2.分析、调试下面的代码,体会利用JNetPacp进行抓包和分析的过程

JNetPcap抓包类:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import org.jnetpcap.Pcap;
import org.jnetpcap.PcapBpfProgram;
import org.jnetpcap.PcapIf;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
import org.jnetpcap.packet.format.FormatUtils;
import org.jnetpcap.protocol.network.Arp;
import org.jnetpcap.protocol.network.Icmp;
import org.jnetpcap.protocol.network.Ip4;
import org.jnetpcap.protocol.tcpip.Http;
import org.jnetpcap.protocol.tcpip.Tcp;
import org.jnetpcap.protocol.tcpip.Udp;
public class capture {
	private static Ip4 ip = new Ip4();
	private static Udp udp=new Udp();
	private static Tcp tcp=new Tcp();
	private static Icmp icmp=new Icmp();
	private static Arp arp=new Arp();
	private static Http http=new Http();
	//获得网卡设备列表  
	public static ArrayList<PcapIf> getDevices()
	{	//用于存储搜索到的网卡
		ArrayList<PcapIf> alldevs = new ArrayList<PcapIf>();
	    //错误信息
	    StringBuilder errbuf = new StringBuilder();
	    //Pcap.findAllDevs(alldevs, errbuf)取得设备列表
	    int r = Pcap.findAllDevs(alldevs, errbuf);
	    if (r == Pcap.NOT_OK || alldevs.isEmpty()) { 
	    	// 如果获取失败,或者获取到列表为空,则输出错误信息退出
	    	System.err.printf("Can't read list of devices, error is %s", errbuf.toString());  
			return null;   
    	}
	    return alldevs;
	}
	//打开设备并进行抓包分析
	public static String[] openDevice(ArrayList<PcapIf> alldevs,int choose,String expression)
	{ StringBuilder errbuf = new StringBuilder();
	  int snaplen = Pcap.DEFAULT_SNAPLEN; // 默认长度为65535
      int flags = Pcap.MODE_PROMISCUOUS;  // 混杂模式
      int timeout = 10 * 1000;             // 10 seconds in millis
      Pcap pcap = Pcap.openLive(alldevs.get(choose).getName(), snaplen, flags, timeout, errbuf);
        if (pcap == null) {JOptionPane.showMessageDialog(null,errbuf.toString(),"错误",JOptionPane.ERROR_MESSAGE);
            return null;
        }
//        System.out.print(alldevs.get(choose).getName()); 
        //如果过滤器不为none,设置相应过滤器
        if (expression!="none")
        {PcapBpfProgram filter = new PcapBpfProgram();
        	int res = pcap.compile(filter, expression, 1, 0);
        	pcap.setFilter(filter);
        }
        //存储分析结果
        String[] data= new String[8];
        PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {  
            public void nextPacket(PcapPacket packet, String user) {
            	int no=(int) (packet.getFrameNumber());
            	//编号
            	data[0]= String.valueOf(no);
            	//长度
            	data[5]=String.valueOf(packet.getCaptureHeader().caplen());
            	//封包具体信息
            	data[7]=String.valueOf(packet);
            	//tcp
            	if (packet.hasHeader(tcp))
            	{   packet.getHeader(tcp);
            		data[4]="tcp";
            	Stringstod=String.valueOf(tcp.source())+"->"+String.valueOf(tcp.destination());
            		String seq="Seq="+String.valueOf(tcp.seq());
            		String ack="Ack="+String.valueOf(tcp.ack());
            		String win="Win="+String.valueOf(tcp.window());
            		String len="Len="+String.valueOf(tcp.getLength());
            		String syn="SYN="+String.valueOf(tcp.flags_SYN());
            		String fin="FIN="+String.valueOf(tcp.flags_FIN());
            		data[6]=stod+" "+seq+" "+ack+" "+win+" "+len+" "+syn+" "+fin;
            		formMain.tcpnum++;
            	}
            	//udp
            	if (packet.hasHeader(udp))
            	{   packet.getHeader(udp);
            		data[4]="udp";
           String stod=String.valueOf(udp.source())+" -> "+String.valueOf(udp.destination());
            		String len="Len="+String.valueOf(udp.length());
            		data[6]=stod+" "+len;
            		formMain.udpnum++;
            	}
            	//icmp
            	if (packet.hasHeader(icmp))
            	{  packet.getHeader(icmp);
            		data[4]="icmp";
            		formMain.icmpnum++;
            	}
            	//arp
            	if (packet.hasHeader(arp))
            	{   packet.getHeader(arp);
            		String hardwareType=arp.hardwareTypeDescription();
            		data[4]="arp";
            		data[6]="hardwareTypeDescription:"+hardwareType;
            		formMain.arpnum++;
            	}
            	//http
            	if (packet.hasHeader(http))
            	{   packet.getHeader(http);
            		data[4]="http";
            		formMain.httpnum++;
            	}
            	//ip
            	if (packet.hasHeader(ip)) { 
if (formMain.IPhashMap.containsKey(FormatUtils.ip(ip.source())+"->" +FormatUtils.ip(ip.destination())))
        			{
        				int num=formMain.IPhashMap.get(FormatUtils.ip(ip.source())+" -> "+FormatUtils.ip(ip.destination()));
        				num++;
        				formMain.IPhashMap.put(FormatUtils.ip(ip.source())+" -> "+FormatUtils.ip(ip.destination()),num);
        			}
        			else
        				formMain.IPhashMap.put(FormatUtils.ip(ip.source())+" -> "+FormatUtils.ip(ip.destination()),1);
            		packet.getHeader(ip);
            		data[2]=FormatUtils.ip(ip.source());
            		data[3]=FormatUtils.ip(ip.destination());
            		formMain.ipnum++;
            	}
            }
	};
            
        pcap.loop(1, jpacketHandler, "jNetPcap");
        pcap.close();
        return data;
	}
}

界面类:

public void actionPerformed(ActionEvent arg0) { import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;
import org.jnetpcap.PcapIf;
import jpcap.NetworkInterface;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JScrollBar;
public class formMain extends JFrame {
	private JPanel contentPane;
	private JTable table = new JTable();
	private JTextArea textArea = new JTextArea();
	//记录当前选中设备号
	private int chooseFlag=0;
	DefaultTableModel model=(DefaultTableModel)table.getModel();
	//记录运行时间
	public int minute;
	private JTextField textField;
	private JComboBox comboBox = new JComboBox();
	private ArrayList<String> datas=new ArrayList<String>();
	
	//数量统计
	public static int tcpnum=0;
	public static int udpnum=0;
	public static int icmpnum=0;
	public static int ipnum=0;
	public static int httpnum=0;
	public static int arpnum=0;
	public static HashMap<String, Integer> IPhashMap=new HashMap<>();

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					formMain frame = new formMain();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public formMain() {
		setTitle("\u6293\u5305");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(450, 100, 800, 979);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		JLabel label_tcp = new JLabel("0");
		label_tcp.setBounds(166, 773, 72, 18);
		contentPane.add(label_tcp);
		
		JLabel label_udp = new JLabel("0");
		label_udp.setBounds(167, 820, 72, 18);
		contentPane.add(label_udp);
		JLabel label_icmp = new JLabel("0");
		label_icmp.setBounds(166, 865, 72, 18);
		contentPane.add(label_icmp);
		JLabel label_ip = new JLabel("0");
		label_ip.setBounds(449, 773, 72, 18);
		contentPane.add(label_ip);
		JLabel label_arp = new JLabel("0");
		label_arp.setBounds(449, 820, 72, 18);
		contentPane.add(label_arp);
		JLabel label_http = new JLabel("0");
		label_http.setBounds(449, 865, 72, 18);
		contentPane.add(label_http);
		
		//label
		JLabel lblS = new JLabel("请选择设备:");
		lblS.setBounds(106, 32, 115, 18);
		lblS.setFont(new Font("黑体", Font.PLAIN, 18));
		contentPane.add(lblS);
		
		//下拉框
		JComboBox<String> comboDevices = new JComboBox<String>();
		comboDevices.setBounds(221, 30, 454, 24);
		comboDevices.setFont(new Font("黑体", Font.PLAIN, 16));
		contentPane.add(comboDevices);
		//添加设备
		ArrayList<PcapIf> dlist=capture.getDevices();
		for (int i=0;i<dlist.size();i++)
		{
			comboDevices.addItem(dlist.get(i).getName());
		}
		
		//执行时间
		textField = new JTextField();
		textField.setBounds(314, 110, 100, 30);
		textField.setText("0");
		String time=textField.getText();
		minute=Integer.valueOf(time);
		textField.setFont(new Font("黑体", Font.PLAIN, 18));
		contentPane.add(textField);
		textField.setColumns(10);
		
		//开始按钮
		JButton btnStart = new JButton("Start");
		btnStart.setBounds(496, 111, 113, 27);
		btnStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				//确定所选设备号
				for (int i=0;i<dlist.size();i++)
				{
					if(dlist.get(i).getName()==comboDevices.getSelectedItem())
						chooseFlag=i;
				}
				
				int count=1;
				//获得执行时间
				String time=textField.getText();
				minute=Integer.valueOf(time);
				long startTime = System.currentTimeMillis();
				System.out.print("time:"+time);
		        long nowTime = System.currentTimeMillis();
		        
		        while (startTime + minute * 60 * 1000 >= nowTime) {
		        	nowTime = System.currentTimeMillis();
		        	System.out.println(nowTime);
		        	String expression=(String) comboBox.getSelectedItem();
					String data[]=capture.openDevice(dlist,chooseFlag,expression);
					data[0]=String.valueOf(count);
					SimpleDateFormat sdff=new SimpleDateFormat("HH:mm:ss");
					data[1]=sdff.format(nowTime);
					//将获得的数据加入表格中
					model.addRow(data);
					datas.add(data[7]);
					count++;
					table.validate();

					label_tcp.setText(String.valueOf(tcpnum));
					label_udp.setText(String.valueOf(udpnum));
					label_icmp.setText(String.valueOf(icmpnum));
					label_ip.setText(String.valueOf(ipnum));
					label_http.setText(String.valueOf(httpnum));
					label_arp.setText(String.valueOf(arpnum));
				}
			}
		});
		btnStart.setFont(new Font("黑体", Font.PLAIN, 18));
		contentPane.add(btnStart);
		//表格
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(27, 150, 720, 280);
		contentPane.add(scrollPane);
		
	    String[] titles = { "No.", "Time","Source","Destination","Protocal","Length","Info" };
		model.setColumnIdentifiers(titles);
		scrollPane.setViewportView(table);
		table.setFont(new Font("黑体", Font.PLAIN, 15));
		table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				int index = table.getSelectedRow();
				textArea.setText(datas.get(index));
			}
		});
		
JLabel label = new JLabel("\u6267\u884C\u65F6\u957F\uFF1A\uFF08\u5206\u949F\uFF09");
		label.setBounds(167, 118, 162, 18);
		label.setFont(new Font("黑体", Font.PLAIN, 15));
		contentPane.add(label);
		JScrollPane scrollPane_1 = new JScrollPane();
		scrollPane_1.setBounds(27, 443, 720, 300);
		contentPane.add(scrollPane_1);
		scrollPane_1.setViewportView(textArea);
scrollPane_1.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		textArea.setBounds(27, 443, 720, 300);
		JLabel label_1 = new JLabel("\u8FC7\u6EE4\u5668\u9009\u62E9\uFF1A");
		label_1.setFont(new Font("黑体", Font.PLAIN, 15));
		label_1.setBounds(167, 79, 132, 18);
		contentPane.add(label_1);
		//过滤器下拉框
		comboBox.setBounds(262, 76, 347, 24);
		contentPane.add(comboBox);
		comboBox.addItem("none");
		comboBox.addItem("ip");
		comboBox.addItem("tcp");
		comboBox.addItem("udp");
		comboBox.addItem("arp");
		comboBox.addItem("icmp");
		comboBox.addItem("http");
		JLabel label_2 = new JLabel("\u7EDF\u8BA1\uFF1A");
		label_2.setFont(new Font("黑体", Font.PLAIN, 17));
		label_2.setBounds(27, 772, 72, 18);
		contentPane.add(label_2);
		JLabel lblTcp = new JLabel("TCP\u5305\uFF1A");
		lblTcp.setBounds(96, 773, 72, 18);
		contentPane.add(lblTcp);
		JLabel lblUdp = new JLabel("UDP\u5305\uFF1A");
		lblUdp.setBounds(96, 820, 72, 18);
		contentPane.add(lblUdp);
		JLabel lblIcmp = new JLabel("ICMP\u5305\uFF1A");
		lblIcmp.setBounds(96, 865, 72, 18);
		contentPane.add(lblIcmp);
		JLabel lblIp = new JLabel("IP\u5305\uFF1A");
		lblIp.setBounds(378, 773, 72, 18);
		contentPane.add(lblIp);
		JLabel lblArp = new JLabel("ARP\u5305\uFF1A");
		lblArp.setBounds(376, 823, 72, 18);
		contentPane.add(lblArp);
		JLabel lblHttp = new JLabel("HTTP\u5305\uFF1A");
		lblHttp.setBounds(374, 866, 72, 18);
		contentPane.add(lblHttp);
		JButton btnDetails = new JButton("Details");
		btnDetails.addActionListener(new ActionListener() {

				if (comboBox.getSelectedItem()=="none")
				{
				DefaultPieDataset dpd=new DefaultPieDataset(); //建立一个默认的饼图
					//添加数据
					dpd.setValue("tcp",tcpnum);
					dpd.setValue("udp",udpnum);
					dpd.setValue("ip", ipnum);
					dpd.setValue("icmp",icmpnum);
					dpd.setValue("arp",arpnum);
					dpd.setValue("http",httpnum);
					
		JFreeChart chart=ChartFactory.createPieChart("数据包统计分析",dpd,true,true,false);
					ChartFrame chartFrame=new ChartFrame("数据包统计分析",chart);
					chartFrame.pack(); //以合适的大小展现图形
					chartFrame.setVisible(true);//图形是否可见
				}
				else
				{
				DefaultPieDataset dpd=new DefaultPieDataset(); //建立一个默认的饼图
					//添加数据
					Set set=IPhashMap.entrySet();
			        Iterator it=set.iterator();
			        while(it.hasNext()){
			        	Map.Entry me=(Map.Entry)it.next();
			        	dpd.setValue(String.valueOf(me.getKey()), (int)me.getValue());
			        }
		JFreeChart chart=ChartFactory.createPieChart("数据包统计分析",dpd,true,true,false);
					ChartFrame chartFrame=new ChartFrame("数据包统计分析",chart);
					chartFrame.pack(); //以合适的大小展现图形
					chartFrame.setVisible(true);//图形是否可见
				}
			}
		});
		btnDetails.setFont(new Font("宋体", Font.BOLD, 15));
		btnDetails.setBounds(634, 816, 113, 27);
		contentPane.add(btnDetails);
		
	}
}

  • 2
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现网络数据包的捕获与分析需要使用到Java网络编程库和数据包处理库,以下是一个简单的示例程序: ```java import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; import org.jnetpcap.Pcap; import org.jnetpcap.PcapIf; import org.jnetpcap.packet.PcapPacket; import org.jnetpcap.protocol.network.Ip4; import org.jnetpcap.protocol.tcpip.Tcp; public class PacketCapture { public static void main(String[] args) { StringBuilder errbuf = new StringBuilder(); Pcap pcap = Pcap.openLive("eth0", 65536, Pcap.MODE_PROMISCUOUS, 1000, errbuf); if (pcap == null) { System.err.println("Failed to open device: " + errbuf); return; } Ip4 ip = new Ip4(); Tcp tcp = new Tcp(); PcapPacket packet = new PcapPacket(ByteBuffer.allocate(65536).order(ByteOrder.BIG_ENDIAN)); while (pcap.nextEx(packet) == Pcap.NEXT_EX_OK) { if (packet.hasHeader(ip) && packet.hasHeader(tcp)) { try { InetAddress srcAddr = InetAddress.getByAddress(ip.source()); InetAddress dstAddr = InetAddress.getByAddress(ip.destination()); int srcPort = tcp.source(); int dstPort = tcp.destination(); System.out.println("Source IP address: " + srcAddr.getHostAddress()); System.out.println("Destination IP address: " + dstAddr.getHostAddress()); System.out.println("Source port: " + srcPort); System.out.println("Destination port: " + dstPort); } catch (UnknownHostException e) { e.printStackTrace(); } } } pcap.close(); } } ``` 这个程序使用了jNetPcap库来捕获网络数据包,并使用了Ip4和Tcp协议类来解析IPTCP头部。在while循环中,我们可以通过IPTCP头部的字段来获取源IP地址、目的IP地址、源端口和目的端口等信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值