pcap4j 实现java 抓包及DNS解析

目前java实现解析pcap格式的三方库很多,如jnetpcapjpcappcap4j,但是jnetpcap和jpcap已经很久没有更新了,而且jnetpcap的跨平台表现不是很好,在Linux系统上在很多问题,我这边是获取不到网卡信息(root方式启动)。
综合考虑下来决定采用pcap4j,pcap4j 目前支持DNS、SNMP,以及传输层TCP、UDP,网络层的ARP、ICMP等协议,但是暂不支持Http协议解析,作者在issue中提到2.0版本会添加http支持。

环境准备

Mac/Linux/UNIX 需要安装libpcap,windows环境需要安装winpcap
Centos

yum install libpcap-devel

Ubuntu

apt-get install libpcap-dev

Mac

brew install libpcap

添加依赖

Gradle

compile 'org.pcap4j:pcap4j-core:1.+'
compile 'org.pcap4j:pcap4j-packetfactory-static:1.+'

Maven

<dependency>
  <groupId>org.pcap4j</groupId>
  <artifactId>pcap4j-core</artifactId>
  <version>[1.0, 2.0)</version>
</dependency>
<dependency>
  <groupId>org.pcap4j</groupId>
  <artifactId>pcap4j-packetfactory-static</artifactId>
  <version>[1.0, 2.0)</version>
</dependency>

代码实现

本部分不详细说明各个代码的实现逻辑,具体请查看代码注释吧。

获取抓包设备
可以根据设备名称、设备IP地址进行选择本地的网络设备,具体的代码如下:

  /**
     * 根据IP获取指定网卡设备
     * @param localHost 网卡IP
     * 
     * @return 指定的设备对象
     */
    public static PcapNetworkInterface getCaptureNetworkInterface(String localHost) {
        List<PcapNetworkInterface> allDevs;
        try {
            // 获取全部的网卡设备列表,Windows如果获取不到网卡信息,输入:net start npf  启动网卡服务
            allDevs = Pcaps.findAllDevs();

            for (PcapNetworkInterface networkInterface : allDevs) {
                List<PcapAddress> addresses = networkInterface.getAddresses();
                for (PcapAddress pcapAddress : addresses) {
                    // 获取网卡IP地址
                    String ip = pcapAddress.getAddress().getHostAddress();
                    if (ip != null && ip.contains(localHost)) {
                        // 返回指定的设备对象
                        return networkInterface;
                    }

                }
            }
        } catch (PcapNativeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

核心抓包代码

  /**
     *在线抓包以及保存至本地
     * 
     * @return
     * @throws InterruptedException
     */
    private boolean captureAndDumpLive() throws InterruptedException {
        //将回环地址替换成自己网卡地址( ipconfig 查看)
        PcapNetworkInterface nif = PcapNIfManager.getCaptureNetworkInterface("127.0.0.1");
        if (nif == null) {
            return false;
        }

        try {
            // 抓包
            pcapHandle = nif.openLive(SNAPLEN, PromiscuousMode.PROMISCUOUS, TIMEOUT);
            // 打开抓包数据写入文件
            dumper = pcapHandle.dumpOpen(DUMP_FILE);
            // 循环处理 -1 为持续抓包,直至中断退出,可以设定为正整数(抓包个数),
            pcapHandle.loop(-1, new CoreCaptureListener());
            //   也可以采用如下方式,进行循环抓包,
            /*
            while (true) {
                Packet packet = pcapHandle.getNextPacket();
                if (packet == null) {
                    continue;
                } else {
                    if (condition) {
                        break;
                    }
                }
            }*/

        } catch (PcapNativeException e) {
            e.printStackTrace();
            return false;
        } catch (NotOpenException e) {
            e.printStackTrace();
            return false;
        }
        return true;

    }

抓包处理

 class CoreCaptureListener implements PacketListener {

        /* (non-Javadoc)
         * @see org.pcap4j.core.PacketListener#gotPacket(org.pcap4j.packet.Packet)
         */
        @Override
        public void gotPacket(Packet packet) {
            // 解析DNS 数据信息
            if (packet.contains(DnsPacket.class)) {
                DnsHeader dnsHeader = packet.get(DnsPacket.class).getHeader();
                if (dnsHeader.isResponse()) {
                    dnsHeader.getAnswers().get(0).getName();
                } else {
                    dnsHeader.getQuestions();
                    // DNS 记录类型
                    dnsHeader.getQuestions().get(0).getQType();
                }
            }
            try {
                dumper.dump(packet);
            } catch (NotOpenException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

结语

只是简单介绍了下pcap4j的基本应用,详细的说明还请去github上查看或者查看在线doc
本文demo下载地址

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: Java可以利用第三方库Jpcap解析pcap文件的五元组信息。在使用Jpcap之前,需要先下载和安装Jpcap库。 首先,我们需要创建一个能够读取pcap文件的Capture对象。代码如下: `Capture capture = new Capture();` 然后,我们需要设置Capture对象的文件路径,指定pcap文件所在的位置。代码如下: `capture.openFile("filepath.pcap");` 接下来,我们可以通过循环遍历Capture对象的包,获取每个包的五元组信息。代码如下: ``` while(capture.getNextPacket() != null){ byte[] packet = capture.getPacket(); //解析五元组信息 //...代码 } ``` 在循环内部,我们可以利用Jpcap库提供的方法来解析包的五元组信息。五元组信息包括源IP地址、目标IP地址、源端口号、目标端口号和传输协议。具体解析方法如下: ``` Packet packet = new Packet(packet, Packet.PROTOCOL_IP); if (packet instanceof IPPacket) { IPPacket ipPacket = (IPPacket) packet; String sourceIP = ipPacket.getSourceAddress(); String destinationIP = ipPacket.getDestinationAddress(); int sourcePort = 0; int destinationPort = 0; if (packet instanceof TCPPacket) { TCPPacket tcpPacket = (TCPPacket) packet; sourcePort = tcpPacket.getSourcePort(); destinationPort = tcpPacket.getDestinationPort(); } else if (packet instanceof UDPPacket) { UDPPacket udpPacket = (UDPPacket) packet; sourcePort = udpPacket.getSourcePort(); destinationPort = udpPacket.getDestinationPort(); } String transportProtocol = ipPacket.protocolDescription; //打印五元组信息 System.out.println("源IP地址:" + sourceIP + ",目标IP地址:" + destinationIP + ",源端口号:" + sourcePort + ",目标端口号:" + destinationPort + ",传输协议:" + transportProtocol); } ``` 通过以上代码,我们可以获取pcap文件中每个包的五元组信息,并打印出来。 最后,记得在程序结束后关闭Capture对象,释放资源。代码如下: `capture.close();` 以上是Java解析pcap文件五元组信息的基本步骤和代码实现。通过利用Jpcap库,我们可以方便地获取pcap文件中的五元组信息,进行进一步的网络分析和处理。 ### 回答2: PCAP文件是一种常用的网络数据捕获文件格式,它可以用来存储网络数据包。在网络分析和安全领域中,解析PCAP文件的五元组信息非常重要。 五元组信息指的是TCP/IP协议栈中的五个重要参数,即源IP地址、目的IP地址、源端口号、目的端口号和协议类型。解析PCAP文件的五元组信息可以帮助我们分析网络通信的源和目的,识别网络中的主机和服务等。 对于Java程序来说,解析PCAP文件的五元组信息可以通过使用相关的库和API实现。以下是一个简单的示例代码,展示了如何使用开源库jpcap解析PCAP文件中的五元组信息: ```java import jpcap.*; import jpcap.packet.*; public class PCAPParser { public static void main(String[] args) throws Exception { // 打开PCAP文件 NetworkInterface[] devices = JpcapCaptor.getDeviceList(); JpcapCaptor captor = JpcapCaptor.openFile("filename.pcap"); // 逐个解析数据包 while (true) { Packet packet = captor.getPacket(); if (packet == null) break; // 获取五元组信息 if (packet instanceof IPPacket) { IPPacket ipPacket = (IPPacket) packet; String sourceIP = ipPacket.src_ip.getHostAddress(); String destinationIP = ipPacket.dst_ip.getHostAddress(); int sourcePort = 0; int destinationPort = 0; if (ipPacket instanceof TCPPacket) { TCPPacket tcpPacket = (TCPPacket) ipPacket; sourcePort = tcpPacket.src_port; destinationPort = tcpPacket.dst_port; } else if (ipPacket instanceof UDPPacket) { UDPPacket udpPacket = (UDPPacket) ipPacket; sourcePort = udpPacket.src_port; destinationPort = udpPacket.dst_port; } String protocol = ipPacket.protocolDescription; // 输出五元组信息 System.out.println("Source IP: " + sourceIP); System.out.println("Destination IP: " + destinationIP); System.out.println("Source Port: " + sourcePort); System.out.println("Destination Port: " + destinationPort); System.out.println("Protocol: " + protocol); System.out.println("--------------------------"); } } // 关闭PCAP文件 captor.close(); } } ``` 以上代码使用jpcap库读取并解析PCAP文件中的数据包。通过遍历数据包,我们使用IPPacket类获取源IP地址、目的IP地址和协议类型。之后,根据具体的协议类型,我们使用TCPPacket或UDPPacket类获取源端口号和目的端口号。 最后,输出五元组信息供进一步的分析和使用。这样,我们就可以使用Java解析PCAP文件中的五元组信息了。当然,解析PCAP文件还涉及到其他的一些操作,比如过滤、统计等,可以根据具体需求进行扩展和处理。 ### 回答3: Java解析pcap文件五元组信息的过程如下: pcap文件是一种网络数据包捕获文件格式,它记录了在计算机网络中传输的数据包的原始内容和元数据。五元组是识别网络数据流的关键信息,包括源IP地址、目标IP地址、源端口号、目标端口号和传输协议。 1. 打开pcap文件:使用Java的文件操作类库打开pcap文件,并读取其中的数据包内容和元数据。 2. 解析数据包:遍历pcap文件中的数据包,使用Java的网络协议解析库对每个数据包进行解析。这个过程中可以获取到数据包的源IP地址、目标IP地址、源端口号、目标端口号和传输协议。 3. 保存五元组信息:将每个数据包中解析得到的五元组信息存储在一个数据结构中,比如使用Java的列表或映射等。 4. 分析五元组信息:对保存的五元组信息进行分析,可以统计每个五元组出现的次数,找出频率最高的五元组,或者进行其他复杂的网络分析。 通过以上步骤,使用Java可以很方便地解析pcap文件中的五元组信息。这些信息对于网络安全研究、网络流量监控和网络性能优化等领域都非常重要。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值