基于jnetpcap开发的抓包程序

        此次的设计模式课程设计让我很是感觉到有些失败,原因是1:在开始定题是是研究yazd论坛,在参考了彭晨阳《java使用系统开发指南》一书,在第三章的Jlive论坛便是基于yazd论坛的升级版(相关可以参考解道论坛)。在和同伴一起调通admin部分后,后来自己花费1天多想弄通控制权限部分(因为他的进入yazd论坛普通用户需要注册还要激活,我们搞不同他的激活方式,便导致后期不能继续研究),想一想这也是我自己本身能力不足的一方面。虽然之前和老师一起做过相关的web项目,但是还是没有深入研究。

        后来,小伙伴转到研究spring框架,我也不得不另择道路。想了想,还是重构一下自己原先的代码吧。所以选了《计算机网络课程设计》----局域网抓包的程序。在重构过程中我也感觉到自己写的代码是多么惨目忍睹。打开自己原来写的东西,才发现当时写的代码是多么不可理喻,类与类之间耦合度太强,两个类之间互相需要调用造成一种死锁局面(因为A类需要new时需要调用B类的一个方法,而B类new时有需要调用A类的方法);另外程序出现的问题就是面向实现而编程的,违背了面向对象的设计优点:面向接口编程。还记得前些日子,教授说的“软件的理解“,自己学了三年可以说尚未真正悟出他所说的。

        总之自己还得继续努力!!!

        下面就将自己这两天写的一些关于jentpcap分享给大家:

        <1>架构模式:MVC

        

<2>工厂模式:通过反射生产对象,这个做法主要是参考和老师一起做的项目,通过读取可配置文件然后生产对象

        

package com.jnetpcap.util;

import java.util.Properties;

public class MyFactory {
    
    public static Properties prop = new Properties();
    /**2017/12/14
     *通过反射获取对象,这里返回的是Object类型对象,然后强制转换便可以生产相应对象
     */
    public static Object getObject(String name) {
        try {
            String className = prop.getProperty(name);
            Object obj = Class.forName(className).newInstance();
            return obj;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (InstantiationException e) {
            e.printStackTrace();
            return null;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
}

<2>单例模式:程序中使用单例模式主要确保抓包的类只有一个实例,自己感觉写个单例有点多余,因为吸收了一些之前java课程设计中达内人员过来讲的IOC(依赖注入)模式就是new出一个对象,然后通过set方法注入对象。

package com.jnetpcap.service;

import java.awt.Frame;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;

import com.jnetpcap.entity.PacketMessage;
import com.jnetpcap.table.Buffer;
import com.jnetpcap.table.TableModel;
/*
*@author:软件工程:严治政
*@time=2017年9月14日
*/
public class CaptureSingleton implements Runnable{
	
	List<PacketMessage> packetMessage ;
	private final List<PcapIf> devs = new ArrayList<PcapIf>();
	private final StringBuilder err = new StringBuilder();
	private PcapIf device;
	int num;
	private volatile static CaptureSingleton instance ;
	private MyPcapPacketHandler<Object> myhandler = new MyPcapPacketHandler<Object>();

	public MyPcapPacketHandler<Object> getHander() {
		return myhandler;
	}
	
	private CaptureSingleton() {
		
	}
	
	public static CaptureSingleton getInstance() {
		if (instance == null) {
			synchronized(CaptureSingleton.class) {
				if(instance == null)
					instance = new CaptureSingleton();
			}
		}
		return instance;
	}
	
//	获取机器上网卡列表
 	public List<PcapIf> getDevs() {
		int r = Pcap.findAllDevs(devs, err);
		if (r == Pcap.NOT_OK || devs.isEmpty()) {
			JOptionPane.showMessageDialog(null, err.toString(),"error error error!"
					,JOptionPane.ERROR_MESSAGE);
			return null;
		}else {
			return devs;
		}
	}

	//选择一个网卡开始抓包
	public  void startCaptureAt(int num) {
		this.device = devs.get(num);
		start(device);
	}
	
	public  void start(PcapIf device) {
		int snaplen = Pcap.DEFAULT_JPACKET_BUFFER_SIZE;
		int flags = Pcap.MODE_PROMISCUOUS;
		int timeout = 10*1000;
		StringBuilder err =  new StringBuilder();
		Pcap pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, err);
		if (pcap == null) {
			JOptionPane.showMessageDialog(null, err.toString(),"error error error!",JOptionPane.ERROR_MESSAGE);
			return ;
		}
		int cnt = 1;
		//包匹配
		pcap.loop(cnt,myhandler,"jnetpcap rock!");
		pcap.close();
	}

	public void setNum(int num) {
		this.num = num;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub	
		while(true) {
			/**
			 * 这个位置主要是我一开始在测试类中启动的是单列模式,而具体选择网卡是用num确定
			 * 一开始new出来这个类默认值是0号网卡,但是这个num我需要通过界面选择传过来
			 * 所以便直接给定网卡号码,后期需要在考虑考虑
			 */
				System.out.println(num+"号网卡工作");
				startCaptureAt(3);	
		}
		
	}
}

<3>策略模式:策略模式主要是完成一项任务,可以有多种方法,每一种方式成为一个策略

    

package com.jnetpcap.util;

import org.jnetpcap.packet.PcapPacket;

import com.jnetpcap.entity.Packet;
import com.jnetpcap.entity.PacketMessage;

/**
 * 
 * @author       
 * @编辑时间:2018年3月11日
 * @功能说明:策略模式接口
 * @version:
 */
public interface IHanderStrategy {
	public PacketMessage hander(PcapPacket p);
}

处理ip数据包

package com.jnetpcap.util;

import java.util.Date;

import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.protocol.network.Ip4;

import com.jnetpcap.entity.Packet;
import com.jnetpcap.entity.PacketMessage;

public class IPStrategy implements IHanderStrategy{

	@Override
	public PacketMessage hander(PcapPacket packet) {
		Ip4 ip = new Ip4();
		PacketMessage pm = new PacketMessage();
		packet.getHeader(ip);
		byte[] sIp = new byte[4];
		byte[] dIp = new byte[4];
		sIp = ip.source();
		dIp = ip.destination();
		
		String srcIp = org.jnetpcap.packet.format.FormatUtils.ip(sIp);  
		String dstIp = org.jnetpcap.packet.format.FormatUtils.ip(dIp);  
		pm.setsIp(srcIp);
		pm.setdIp(dstIp);
		pm.setCaplen(packet.getCaptureHeader().caplen());
		pm.setTime(new Date(packet.getCaptureHeader().timestampInMillis()));
		return pm; 
	}

}

处理Ethernet数据包

package com.jnetpcap.util;

import java.util.Date;

import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.protocol.lan.Ethernet;

import com.jnetpcap.entity.PacketMessage;

public class EthStrategy implements IHanderStrategy{

	@Override
	public PacketMessage hander(PcapPacket p) {
		Ethernet eth = new Ethernet();
		PacketMessage pm = new PacketMessage();
		eth = p.getHeader(eth);
		byte[] dstMac = eth.destination();
		byte[] srcMac = eth.source();
		int type = eth.type();
		
		pm.setsMac(asString(srcMac));
		pm.setdMac(asString(dstMac));
		pm.setCaplen(p.getCaptureHeader().caplen());
		pm.setTime(new Date(p.getCaptureHeader().timestampInMillis()));
		return pm;
	}
	
	public String asString(byte[] mac) {
		final StringBuilder buf = new StringBuilder();
		for (byte b : mac) {
			if (buf.length() != 0) {
				buf.append(':');
			}
			if (b >= 0 && b < 16) {
				buf.append('0');
			}
			buf.append(Integer.toHexString((b < 0) ? b + 256 : b).toUpperCase());
		}
		return buf.toString();
	}

}
package com.jnetpcap.service;


import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.protocol.lan.Ethernet;
import org.jnetpcap.protocol.network.Ip4;

import com.jnetpcap.entity.PacketMessage;
import com.jnetpcap.util.EthStrategy;
import com.jnetpcap.util.IHanderStrategy;
import com.jnetpcap.util.IPStrategy;
/*
*@author:策略模式调用类
*@time=2017年9月14日
*/
public class PacketMatch {

	
	private IHanderStrategy strategy;
	

	public void setStrategy(IHanderStrategy strategy) {
		this.strategy = strategy;
	}
	
	public PacketMessage algorithm(PcapPacket packet) {
		return strategy.hander(packet);
		
	}
	
	//分析数据包  并返回一个packetMessage对象
	public PacketMessage handlePacket(PcapPacket packet) {
		PacketMessage pm = null;
		/**********************************************
		 * 通过注入具体的配对策略实现分析不同的数据报
		 **********************************************/
		if (packet.hasHeader(new Ip4() )) {
			this.setStrategy(new IPStrategy() );
			pm = this.algorithm(packet);
		}
		else if (packet.hasHeader(Ethernet.ID)) {
			this.setStrategy(new EthStrategy());
			pm = this.algorithm(packet);
		}	
		return pm;
	}

}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值