使用jnetpcap捕获数据包进行流量检测

jnetpcap是用java对libpcap的一个封装,它可以用来监听网卡,捕获数据包


CaptureCore.java

package nssa.nm.capture;
 
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;
 
public class CaptureCore {
     
    public static List<PcapIf> getDevs() {//获取机器上的网卡列表
        List<PcapIf> devs = new ArrayList<PcapIf>();
        StringBuilder errsb = new StringBuilder();
        int r = Pcap.findAllDevs(devs, errsb);
        if (r == Pcap.NOT_OK || devs.isEmpty()) {
            JOptionPane.showMessageDialog(null,errsb.toString(),"错误",JOptionPane.ERROR_MESSAGE);
            return null;
        } else {
            return devs;
        }
    }
     
    public static void startCaptureAt(int num) {//选择一个网卡开启抓包
        List<PcapIf> devs = new ArrayList<PcapIf>();
        StringBuilder errsb = new StringBuilder();
        int r = Pcap.findAllDevs(devs, errsb);
        if (r == Pcap.NOT_OK || devs.isEmpty()) {
            JOptionPane.showMessageDialog(null,errsb.toString(),"错误",JOptionPane.ERROR_MESSAGE);
            return;
        }
        PcapIf device = devs.get(num);
        int snaplen = Pcap.DEFAULT_SNAPLEN;//长度65536
        int flags = Pcap.MODE_PROMISCUOUS;//混杂模式
        int timeout = 10 * 1000;
        //StringBuilder errsb = null;
        Pcap pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errsb);
        if (pcap == null) {
            JOptionPane.showMessageDialog(null,errsb.toString(),"错误",JOptionPane.ERROR_MESSAGE);
            return;
        }
        PacketMatch packetMatch = PacketMatch.getInstance();
        packetMatch.loadRules();
        MyPcapPacketHandler<Object> myhandler = new MyPcapPacketHandler<Object>();
        pcap.loop(0, myhandler, "jnetpcap");
        pcap.close();
    }

MyPcapPacketHandler.java

package nssa.nm.capture;
 
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
 
public class MyPcapPacketHandler<Object> implements PcapPacketHandler<Object>  {//抓到包后送去检测
     
    @Override
    public void nextPacket(PcapPacket packet, Object obj) {
        PacketMatch packetMatch = PacketMatch.getInstance();
        packetMatch.handlePacket(packet);
    }
}


PacketMatch.java

package nssa.nm.capture;
 
import java.util.ArrayList;
import java.util.List;
import org.jnetpcap.nio.JBuffer;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.protocol.network.Icmp;
import org.jnetpcap.protocol.network.Ip4;
import org.jnetpcap.protocol.tcpip.Tcp;
import org.jnetpcap.protocol.tcpip.Udp;
import nssa.nm.message.MessageCenter;
import nssa.nm.message.NMMessage;
import nssa.nm.vo.Rule;
 
public class PacketMatch {
     
    private static PacketMatch pm;
    private Ip4 ip = new Ip4();
    private Icmp icmp = new Icmp();
    private Tcp tcp = new Tcp();
    private Udp udp = new Udp();
     
    private List<Rule> icmpRules;
    private List<Rule> tcpRules;
    private List<Rule> udpRules;
     
    private NMMessage message;
     
    public static PacketMatch getInstance() {
        if (pm == null) {
            pm = new PacketMatch();
        }
        return pm;
    }
     
    public void loadRules() {//加载规则
        /*RuleDao dao = new RuleDao();
        try {
            icmpRules = dao.list("icmp");
            tcpRules = dao.list("tcp");
            udpRules = dao.list("udp");
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null,e.toString(),"错误",JOptionPane.ERROR_MESSAGE);
        }*/
        icmpRules = new ArrayList<Rule>();
        tcpRules = new ArrayList<Rule>();
        udpRules = new ArrayList<Rule>();
    }
     
    public void handlePacket(PcapPacket packet) {//根据包头选择不同的规则
        message = new NMMessage();
        if (packet.hasHeader(ip)) {
            handleIp(packet);
        }
        if (packet.hasHeader(icmp)) {
            handleIcmp(packet);
        }
        if (packet.hasHeader(tcp)) {
            handleTcp(packet);
        }
        if (packet.hasHeader(udp)) {
            handleUdp(packet);
        }
    }
     
    private void handleIp(PcapPacket packet) {
        packet.getHeader(ip);
        byte[] sIP = new byte[4], 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);
        message.setSip(srcIP);
        message.setDip(dstIP);
    }
     
    private void handleIcmp(PcapPacket packet) {
        packet.getHeader(icmp);
         
        byte[] buff = new byte[packet.getTotalSize()];
        packet.transferStateAndDataTo(buff);
        JBuffer jb = new JBuffer(buff);
        String content = jb.toHexdump();
        //for(int i = 0; i < icmpRules.size(); i++) {
            //if(content.contains(icmpRules.get(i).getContent())) {
                //message.setMsg(icmpRules.get(i).getMsg());
                message.setPacket(content);
                sendMessage();
            //}
        //}
    }
     
    private void handleTcp(PcapPacket packet) {
        packet.getHeader(tcp);
        String srcPort = String.valueOf(tcp.source());
        String dstPort = String.valueOf(tcp.destination());
        message.setSport(srcPort);
        message.setDport(dstPort);
         
        byte[] buff = new byte[packet.getTotalSize()];
        packet.transferStateAndDataTo(buff);
        JBuffer jb = new JBuffer(buff);
        String content = jb.toHexdump();
        //for(int i = 0; i < tcpRules.size(); i++) {
            //if(content.contains(tcpRules.get(i).getContent())) {
                //message.setMsg(tcpRules.get(i).getMsg());
                message.setPacket(content);
                sendMessage();
            //}
        //}
    }
     
    private void handleUdp(PcapPacket packet) {
        packet.getHeader(udp);
        String srcPort = String.valueOf(udp.source());
        String dstPort = String.valueOf(udp.destination());
        message.setSport(srcPort);
        message.setDport(dstPort);
         
        byte[] buff = new byte[packet.getTotalSize()];
        packet.transferStateAndDataTo(buff);
        JBuffer jb = new JBuffer(buff);
        String content = jb.toHexdump();
        //for(int i = 0; i < udpRules.size(); i++) {
            //if(content.contains(udpRules.get(i).getContent())) {
                //message.setMsg(udpRules.get(i).getMsg());
                message.setPacket(content);
                sendMessage();
            //}
        //}
    }
     
    private void sendMessage() {
        MessageCenter.sendMessage(message);
    }
     
}



原文地址:https://www.cnblogs.com/hanfeihan1992/p/4504073.html