java 网络抓包



网络抓包工具的首选是Sniffer。但分析数据时有局限性。比如我要同时监听所有的网卡。筛选发送到某个地址的数据生成绘图等等。

参考了 http://javafound.iteye.com/blog/165723 ,javafound 大神基于jpcap的网络实时监控程序。我想做数据分析,就在程序上改了一下去除了图形生成,改成了数据入库以便对数据进行分析。


主类:Tcpdump.java

 

package com.fitweber.socket;

import java.util.Map;



import jpcap.JpcapCaptor;

import jpcap.NetworkInterface;





/**

 * 1.使用jpcap抓取网络流量的主类,

 * 2.这个类要根据网卡个数,启动线程分别抓取各个网卡上的流量入表中

 * 3.生成图表的对象从流量表中取出数据

 * 4.这个类设计为单实例,在第一次调用时启动抓数据线程;

 * 5.目前没有设计停止抓取机制....

 * @author www.NetJava.cn modify by wheatmark

 */

public class Tcpdump {

	

	private Tcpdump(){}

	/**存入某个地址名字和流量统计值*/

	private   Map<String, Integer> nameTrafficMap=new java.util.HashMap();

	//单实例

	private static Tcpdump tcpdump=null;

	

   public static void main(String args[]){

	   //启动统计线程

	   Tcpdump.ins();

   }

  

	

   /**

    * 单实例调用:其它对象调用这个类的方法时,必须通过这个方法

    * 这样,保证了流量统计线程的启动,且只启动了一次

    * */

   public synchronized static Tcpdump ins(){

	   if(null==tcpdump){

		   tcpdump=new Tcpdump();

		   tcpdump.init();

	   }

	   return tcpdump;

	    

   }

   

   /**生成报表的Servlet调用用于生成图表中数据*/

	public   Map<String, Integer> getNameTrafficMap(){

		return nameTrafficMap;

	}

	

	/**

	 * 根据网卡个数,启动统计线程

	 * 注意:本地地址,即127.0.0.1上的不统计

	 */

	private   void init()  {

		try{

			//获取本机上的网络接口对象

			final	NetworkInterface[] devices = JpcapCaptor.getDeviceList();

			/*

			 * 	/172.16.175.242

			 */

			

			

		for(int i=0;i<devices.length;i++){

			NetworkInterface nc=devices[i];

			//大与零则为有效网卡,不抓本机地址.

			 if(nc.addresses.length>0){

				//一个网卡可能有多个地址,只取第一个地址

				 String addr=nc.addresses[0].address.toString();

				 // 创建某个卡口上的抓取对象,

				 JpcapCaptor jpcap = JpcapCaptor.openDevice(nc, 2000, true, 100);

				 //创建对应的抓取线程并启动

				 LoopPacketThread lt=new LoopPacketThread(jpcap,addr,nc);

				 lt.start();

				 System.out.println( addr+"上的采集线程己启动************");

			 }

		  }

		}catch(Exception ef){

			ef.printStackTrace();

			System.out.println("start caputerThread error ! ! ! !"+ef);

		}



	}

	

	/**IP和抓到包的长度放入hash表中,用表中长度加入放入的长度*/

	/**

	void putNetValue(String name,int value){

		if(nameTrafficMap.containsKey(name)){

		  value=nameTrafficMap.get(name)+value;

		  nameTrafficMap.put(name, value);

		}else{

			nameTrafficMap.put(name, value);

		}

	}

	**/

}

	

//   /**测试再加上一个内存监视线程*/

//class CheckMemory extends Thread{

//	

//	public void run(){

//		while(true){

//			try{

//				//计算内存占用量

//			long freeM=	java.lang.Runtime.getRuntime().freeMemory();

//			Long result=java.lang.Runtime.getRuntime().totalMemory()-freeM;

//			String rs=""+result/1000;

//			int is=Integer.parseInt(rs);

//			

//			Tcpdump.ins().putNetValue("这是内存占用", is);

//			 

//				Thread.sleep(1000);

//			}catch(Exception ef){

//				

//			}

//		}

//	}

//	

//}

 


 

数据抓取:DumpPacket.java

 

package com.fitweber.socket;



import java.sql.Timestamp;

import java.text.SimpleDateFormat;

import java.util.Date;



import jpcap.NetworkInterface;

import jpcap.PacketReceiver;

import jpcap.packet.ARPPacket;

import jpcap.packet.EthernetPacket;

import jpcap.packet.IPPacket;

import jpcap.packet.Packet;

import jpcap.packet.TCPPacket;

import jpcap.packet.UDPPacket;



import com.fitweber.pojo.WebPacket;

import com.fitweber.util.DataLoger;



/**

 * 抓包监听器,实现PacketReceiver中的方法,当数据包到达时计数.

 * @author www.NetJava.cn

 */

class DumpPacket  implements PacketReceiver {

	  private String ipAdd;

	  private DataLoger dataLoger;

	  private NetworkInterface nc;

	  private String addresses;

	  

	  DumpPacket(String ipAdd,NetworkInterface nc){

		  this.ipAdd=ipAdd;

		  this.nc = nc;

		  this.addresses = nc.addresses[0].address.toString();

		  this.dataLoger = new DataLoger();

	  }

	  

	  //实现包统计

	public void receivePacket(Packet packet) {

		

		WebPacket webPacket = new WebPacket();

		

		webPacket.setAddresses(this.addresses);//监听网卡地址

		

		EthernetPacket ethernetPacket = (EthernetPacket) packet.datalink;

		webPacket.setSource_mac(ethernetPacket.getSourceAddress());//请求硬件地址

		webPacket.setDest_mac(ethernetPacket.getDestinationAddress());//目标硬件地址

		

		if("class jpcap.packet.ARPPacket".equals(packet.getClass().toString())){

			ARPPacket arppacket = (ARPPacket) packet;

			

			webPacket.setCaplen(arppacket.len);//网络包长度

			

			webPacket.setHeader_data(arppacket.header);//报文头部信息

			webPacket.setPacket_data(arppacket.data);//报文数据

			webPacket.setReceive_date(new Timestamp(arppacket.sec*1000+arppacket.usec/1000));//收报时间

		}else{

			

			IPPacket ippacket = (IPPacket) packet;

			webPacket.setSource_ip(ippacket.src_ip.getHostAddress());//请求IP地址

			webPacket.setDest_ip(ippacket.dst_ip.getHostAddress());//目标IP地址

			

			webPacket.setProtocol(ippacket.protocol);//网络协议

			webPacket.setPriority(ippacket.priority);//优先级

			

			webPacket.setVersion(ippacket.version);//版本

			webPacket.setHop_limit(ippacket.hop_limit);//生存时间

			webPacket.setIdent(ippacket.ident);//分组标识

			webPacket.setCaplen(ippacket.len);//网络包长度

			webPacket.setDatalen(ippacket.length);//数据包长度

			

			webPacket.setHeader_data(ippacket.header);//报文头部信息

			webPacket.setPacket_data(ippacket.data);//报文数据

			

			webPacket.setReceive_date(new Timestamp(ippacket.sec*1000+ippacket.usec/1000));//收报时间

			

			//System.out.println("服务类型(TOS) (v4/v6):"+ippacket.rsv_tos);

			//System.out.println(ippacket);

			

			if(ippacket.protocol == 6){

				TCPPacket tcppacket =(TCPPacket) ippacket;

				webPacket.setSrc_port(tcppacket.src_port);//源端口

				webPacket.setDst_port(tcppacket.dst_port);//目标端口

			}

			

			if(ippacket.protocol == 17){

				UDPPacket udppacket =(UDPPacket) ippacket;

				webPacket.setSrc_port(udppacket.src_port);//源端口

				webPacket.setDst_port(udppacket.dst_port);//目标端口

			}

		}

		

		this.dataLoger.saveLog(webPacket);

		

	}

	

	/**

	 *日志时间信息

	 * @return:日志内容时间

	 */

	private static String currentTime(){

		Date d = new Date();

		SimpleDateFormat kk=new SimpleDateFormat("mm:ss");

		String strTime=kk.format(d); 

		return strTime;

		

	}

}


数据入库:DataLoger.java

 

 

package com.fitweber.util;



import java.io.IOException;

import java.io.InputStream;

import java.util.ArrayList;



import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;



import com.fitweber.dao.WebPacketDao;

import com.fitweber.pojo.WebPacket;



public class DataLoger {

	final private  int LOGTIME = 50;

	private ArrayList<WebPacket> webPacketArray = new ArrayList<WebPacket>();

	private WebPacketDao webPacketDao; 

	

	public DataLoger(){

		String resource = "META-INF/conf/mybatis-config.xml";

		InputStream inputStream;

		try {

			inputStream = Resources.getResourceAsStream(resource);

			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

			SqlSession session = sqlSessionFactory.openSession();

			this.webPacketDao = session.getMapper(WebPacketDao.class);

		} catch (IOException e) {

			e.printStackTrace();

		}

	}

	

	public  void saveLog(WebPacket webPacket) {

		if(webPacketArray.size()<LOGTIME){

			webPacketArray.add(webPacket);

		}else{

			//保存数据

			webPacketDao.insertWebPacket(webPacketArray);

			webPacketArray.clear();

			webPacketArray.add(webPacket);

		}

	

	}

	

}


 

这里汇总一下java 网络监听的知识点。把相关的资料传到 http://download.csdn.net/detail/super2007/5553057 。javafound 大神的项目包也传上去了。以后备用。





 

你可能感兴趣的:(java)