精华内容
下载资源
问答
  • 主要介绍了java抓包后对pcap文件解析示例,需要的朋友可以参考下
  • I am working on converting PCAP file taken from wireshark using JAVA without using native or ready libraries.i converted the bytes to string directly just for checking the meaningful parts of it.then ...

    I am working on converting PCAP file taken from wireshark using JAVA without using native or ready libraries.

    i converted the bytes to string directly just for checking the meaningful parts of it.

    then i tried to convert it from hexadecimal to string. It was not meaningful.

    there is java library jNetPcap which is wrapping all the libpcap library native calls which is written in c.

    The following picture is captured the wireless network. so the pcap contains the same information: Source ip, destination ip, protocol, length and info

    6a53aa1cf01c821b63d62ca416fa5762.png

    I am trying to get the same result form the pcap file which contains the data in hexadecimal or binary:

    d4c3 b2a1 0200 0400 0000 0000 0000 0000

    0000 0400 0100 0000 2fd4 b355 2af8 0600

    3600 0000 3600 0000 0100 5e00 0016 f409

    d8ed d951 0800 46c0 0028 0000 4000 0102

    4049 c0a8 0308 e000 0016 9404 0000 2200

    fa02 0000 0001 0300 0000 e000 00fb 2fd4

    at the end i want to get to the output to be like something like this:

    764a8722fb59fa7b747457cc12eae877.png

    Any clue or suggestions where to get the packets and file format can help me alot. there maybe somebody else who already came along with this problem ?

    Thank you

    解决方案

    The asker mentioned that jNetPcap is not ideal because it wraps a native library.

    In the time since the accepted answer, a pure Java library has emerged: https://github.com/aboutsip/pkts

    展开全文
  • Java 解析Pcap文件(1)

    2021-03-11 10:38:53
    Java 解析Pcap文件(1) @author:Jingdai @date:2021.03.11 由于毕业实验是关于TLS流量分析的,所以最近学习了一下Pcap文件的解析,现记录一下。 Pcap文件结构 如果所示,Pcap文件由一个Global Header后面接着...

    Java 解析Pcap文件(1)

    @author:Jingdai
    @date:2021.03.11

    由于毕业实验是关于TLS流量分析的,所以最近学习了一下Pcap文件的解析,现记录一下。

    Pcap文件结构

    在这里插入图片描述

    如果所示,Pcap文件由一个Global Header后面接着若干组Packet Header 和 Packet Data 组成。

    先看一下 Global Header 的结构,它由 24B 组成,字段按照Pcap文件的顺序列出。

    • magic,占4B,如果它的值是0xa1b2c3d4,代表 Pcap 文件是大端模式存储的;如果它的值是 0xd4c3b2a1,代表 Pcap 文件是小端模式存储的。这里注意这里的大端小端仅仅是指 Pcap 文件的 Global Header 和 Packet Header,而无关Packet Data 里的内容。Packet Data里面就是利用抓包工具如wireshark捕获的数据包,他们都是符合网络字节序的,而网络字节序就是大端模式。如果对大端模式和小端模式不熟悉的童靴可以先去看一下,在回来学习,因为不知道这个解析包一定会有问题。
    • major,占2B,文件的主版本号,一般为0x0200。
    • minor,占2B,文件的次要版本号,一般为0x0400。
    • thisZone,占4B,当地标准时间,如果是GMT则全为0。
    • sigFigs,占4B,时间戳精度,一般全0。
    • snapLen,占4B,最长存储长度。
    • linkType,占4B,链路类型,以太网则为1,一般为1。

    下面看一下 Packet Header 的结构,它由 16 B组成。字段按文件顺序列出。

    • timestamp,占4B,时间戳高位,精确到seconds,这是Unix时间戳。捕获数据包的时间一般是根据这个值。
    • timestamp,占4B,时间戳低位,能够精确到microseconds。
    • capLen,占4B,当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
    • len,占4B,离线数据长度,网路中实际数据帧的长度,一般不大于capLen,多数情况下和capLen值一样。如果文件中保存不是完整的数据包,那么这个值可能要比前面的数据包长度的值大。

    Pcap 文件解析

    看完上面Pcap文件结构,可以据此将 Pcap 中一个个的 Packet Data 解析出来。先看 Global Header,要用到的就是 magic 和 linkType 字段(如果其他字段要用到稍微改一点就行)。据此构建出 Global Header 类,代码如下。

    package com.jingdai.pcapanalyzer.entity.format;
    
    /**
     * GlobalHeader 文件头结构
     */
    public class GlobalHeader {
    
    	public static final int LINK_TYPE_ETHERNET = 1;
    
    	private int magic;
    	private int linkType;
    	
    	public int getMagic() {
    		return magic;
    	}
    
    	public void setMagic(int magic) {
    		this.magic = magic;
    	}
    
        public int getLinkType() {
            return linkType;
        }
    
        public void setLinkType(int linkType) {
            this.linkType = linkType;
        }
    
    	public GlobalHeader() {}
    
    	@Override
    	public String toString() {
    		return "GlobalHeader{" +
    				"magic=" + magic +
    				", linkType=" + linkType +
    				'}';
    	}
    }
    

    接下来看 Packet Header,这次前面两个是时间,后面两个是长度,都会用到,同样创建一个Packet Header类。代码如下。

    package com.jingdai.pcapanalyzer.entity.format;
    
    /**
     * Pcap 数据包头
     */
    public class PacketHeader {
    	
    	/**
    	 * 时间戳 高位(秒):记录数据包抓获的时间
    	 * 记录方式是从格林尼治时间的1970年1月1日 00:00:00 到抓包时经过的秒数(4个字节)
    	 */
    	private int timeS;	
    	/**
    	 * 时间戳 低位(微秒):抓取数据包时的微秒值(4个字节)
    	 */
    	private int timeMs;						
    	/**
    	 * 数据包长度:标识所抓获的数据包保存在 pcap 文件中的实际长度,以字节为单位(4个字节)
    	 */
    	private int capLen;
    	/**
    	 * 数据包实际长度: 所抓获的数据包的真实长度(4个字节)
    	 */
    	private int len;
    
        @Override
        public String toString() {
            return "PacketHeader{" +
                    "timeS=" + timeS +
                    ", timeMs=" + timeMs +
                    ", capLen=" + capLen +
                    ", len=" + len +
                    '}';
        }
    
        public int getTimeMs() {
            return timeMs;
        }
    
        public void setTimeMs(int timeMs) {
            this.timeMs = timeMs;
        }
    
        public int getCapLen() {
            return capLen;
        }
    
        public void setCapLen(int capLen) {
            this.capLen = capLen;
        }
    
        public int getLen() {
            return len;
        }
    
        public void setLen(int len) {
            this.len = len;
        }
    
        public int getTimeS() {
    
            return timeS;
        }
    
        public void setTimeS(int timeS) {
            this.timeS = timeS;
        }
    
        public PacketHeader() {}
    	
    }
    

    接下来就可以进行解析了,首先从Pcap文件中读取 24B,这 24B 就是Global Header的数据。解析部分如下。

        /**
         *  解析Global Header
         */
        private GlobalHeader parseGlobalHeader(byte[] globalHeaderBuffer) {
            GlobalHeader globalHeader = new GlobalHeader();
    
            byte[] magicBuffer = Arrays.copyOfRange(globalHeaderBuffer, 0, 4);
            byte[] linkTypeBuffer = Arrays.copyOfRange(globalHeaderBuffer, 20, 24);
    
            int magic = DataUtils.byteArray2Int(magicBuffer, 4);
    
            DataUtils.reverseByteArray(linkTypeBuffer);
            int linkType = DataUtils.byteArray2Int(linkTypeBuffer, 4);
            globalHeader.setMagic(magic);
            globalHeader.setLinkType(linkType);
    
            return globalHeader;
        }
    

    如前所述,这里代码仅仅解析了 magiclinkType 字段,如果需要其他字段方法也是一样。还有就是本机测试magic 字段的值是 0xd4c3b2a1,即小端模式,所以后面 Global Header 和 Packet Header 的字段读取都需要是小端模式读取,在这里就是需要将 buffer 逆序后再存储值。

    利用同样的方式,再读取 16B,这16B就是 Packet Header 的数据,代码如下。

        /**
         *  解析Packet Header
         */
        private PacketHeader parsePacketHeader(byte[] dataHeaderBuffer){
    
            byte[] timeSBuffer = Arrays.copyOfRange(dataHeaderBuffer, 0, 4);
            byte[] timeMsBuffer = Arrays.copyOfRange(dataHeaderBuffer, 4, 8);
            byte[] capLenBuffer = Arrays.copyOfRange(dataHeaderBuffer, 8, 12);
            byte[] lenBuffer = Arrays.copyOfRange(dataHeaderBuffer, 12, 16);
    
            PacketHeader packetHeader = new PacketHeader();
    
            DataUtils.reverseByteArray(timeSBuffer);
            DataUtils.reverseByteArray(timeMsBuffer);
            DataUtils.reverseByteArray(capLenBuffer);
            DataUtils.reverseByteArray(lenBuffer);
    
            int timeS = DataUtils.byteArray2Int(timeSBuffer, 4);
            int timeMs = DataUtils.byteArray2Int(timeMsBuffer, 4);
            int capLen = DataUtils.byteArray2Int(capLenBuffer, 4);
            int len = DataUtils.byteArray2Int(lenBuffer, 4);
    
            packetHeader.setTimeS(timeS);
            packetHeader.setTimeMs(timeMs);
            packetHeader.setCapLen(capLen);
            packetHeader.setLen(len);
    
            return packetHeader;
        }
    

    之后就可以根据上面 packetHeader 的 capLen 的值读取 capLen 字节数的数据,这就是真正的 Packet Data 的数据即数据链路层的帧。之后再继续读取16B的 Packet Header,根据 packetHeader 的 capLen 读取对应字节数的数据,循环往复直至读取完毕。

    未完待续,解析数据链路层、IP层和传输层的数据。

    展开全文
  • JavaPcap文件解析(三:解析文件)

    千次阅读 2016-01-11 10:58:05
    数据结构已经定义好了,那么现在就开始正式解析Pcap文件了。 注:以下仅贴出核心代码,项目全部代码会在文章结尾处给出下载链接 解析Pcap文件 1 读取整个Pcap文件到内存 FileInputStream fis = null; try ...

    前言

    数据结构已经定义好了,那么现在就开始正式解析Pcap文件了。
    注:以下仅贴出核心代码,项目全部代码会在文章结尾处给出下载链接

    解析Pcap文件

    1 读取整个Pcap文件到内存

    FileInputStream fis = null;
        try {
            fis = new FileInputStream(pcap);
            int m = fis.read(file_header);
            //....
        } catch // .....
    

    2 读取文件头

    /**
         * 读取 pcap 文件头
         */
        public PcapFileHeader parseFileHeader(byte[] file_header) throws IOException {
            PcapFileHeader fileHeader = new PcapFileHeader();
            byte[] buff_4 = new byte[4];    // 4 字节的数组
            byte[] buff_2 = new byte[2];    // 2 字节的数组
    
            int offset = 0;
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = file_header[i + offset];
            }
            offset += 4;
            int magic = DataUtils.byteArrayToInt(buff_4);
            fileHeader.setMagic(magic);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = file_header[i + offset];
            }
            offset += 2;
            short magorVersion = DataUtils.byteArrayToShort(buff_2);
            fileHeader.setMagorVersion(magorVersion);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = file_header[i + offset];
            }
            offset += 2;
            short minorVersion = DataUtils.byteArrayToShort(buff_2);
            fileHeader.setMinorVersion(minorVersion);
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = file_header[i + offset];
            }
            offset += 4;
            int timezone = DataUtils.byteArrayToInt(buff_4);
            fileHeader.setTimezone(timezone);
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = file_header[i + offset];
            }
            offset += 4;
            int sigflags = DataUtils.byteArrayToInt(buff_4);
            fileHeader.setSigflags(sigflags);
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = file_header[i + offset];
            }
            offset += 4;
            int snaplen = DataUtils.byteArrayToInt(buff_4);
            fileHeader.setSnaplen(snaplen);
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = file_header[i + offset];
            }
            offset += 4;
            int linktype = DataUtils.byteArrayToInt(buff_4);
            fileHeader.setLinktype(linktype);
    
    //      LogUtils.printObjInfo(fileHeader);
    
            return fileHeader;
        }
    

    3 读取数据头

    /**
         * 读取数据包头
         */
        public PcapDataHeader parseDataHeader(byte[] data_header){
            byte[] buff_4 = new byte[4];
            PcapDataHeader dataHeader = new PcapDataHeader();
            int offset = 0;
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = data_header[i + offset];
            }
            offset += 4;
            int timeS = DataUtils.byteArrayToInt(buff_4);
            dataHeader.setTimeS(timeS);
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = data_header[i + offset];
            }
            offset += 4;
            int timeMs = DataUtils.byteArrayToInt(buff_4);
            dataHeader.setTimeMs(timeMs);
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = data_header[i + offset];
            }
            offset += 4;
            // 得先逆序在转为 int
            DataUtils.reverseByteArray(buff_4);
            int caplen = DataUtils.byteArrayToInt(buff_4);
            dataHeader.setCaplen(caplen);
    //      LogUtils.printObj("数据包实际长度", dataHeader.getCaplen());
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = data_header[i + offset];
            }
            offset += 4;
            //      int len = DataUtils.byteArrayToInt(buff_4);
            DataUtils.reverseByteArray(buff_4);
            int len = DataUtils.byteArrayToInt(buff_4);
            dataHeader.setLen(len);
    
    //      LogUtils.printObjInfo(dataHeader);
    
            return dataHeader;
        }
    

    读取数据头后,我们将整个数据存入 content 字节数组中,方便以后的解析

    private byte[] content;
    content = new byte[dataHeader.getCaplen()];
    

    4 读取数据帧

    数据帧数据对我们没啥用,不做过多解析

    /**
         * 读取 Pcap 数据帧
         * @param fis
         */
        public void readPcapDataFrame(byte[] content) {
            PcapDataFrame dataFrame = new PcapDataFrame();
            int offset = 12;
            byte[] buff_2 = new byte[2];
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
            }
            short frameType = DataUtils.byteArrayToShort(buff_2);
            dataFrame.setFrameType(frameType);
    
    //      LogUtils.printObjInfo(dataFrame);
        }
    

    5 读取IP头

    private IPHeader readIPHeader(byte[] content) {
            int offset = 14;
            IPHeader ip = new IPHeader();
    
            byte[] buff_2 = new byte[2];
            byte[] buff_4 = new byte[4];
    
            byte varHLen = content[offset ++];              // offset = 15
    //      LogUtils.printByteToBinaryStr("varHLen", varHLen);
            if (varHLen == 0) {
                return null;
            }
    
            ip.setVarHLen(varHLen);
    
            byte tos = content[offset ++];                  // offset = 16
            ip.setTos(tos);
    
            for (int i = 0; i < 2; i ++) {      
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 18
            short totalLen = DataUtils.byteArrayToShort(buff_2);
            ip.setTotalLen(totalLen);
    
            for (int i = 0; i < 2; i ++) {          
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 20
            short id = DataUtils.byteArrayToShort(buff_2);
            ip.setId(id);
    
            for (int i = 0; i < 2; i ++) {                  
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 22
            short flagSegment = DataUtils.byteArrayToShort(buff_2);
            ip.setFlagSegment(flagSegment);
    
            byte ttl = content[offset ++];                  // offset = 23
            ip.setTtl(ttl);
    
            byte protocol = content[offset ++];             // offset = 24
            ip.setProtocol(protocol);
    
            for (int i = 0; i < 2; i ++) {                  
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 26
            short checkSum = DataUtils.byteArrayToShort(buff_2);
            ip.setCheckSum(checkSum);
    
            for (int i = 0; i < 4; i ++) {                  
                buff_4[i] = content[i + offset];
            }
            offset += 4;                                    // offset = 30
            int srcIP = DataUtils.byteArrayToInt(buff_4);
            ip.setSrcIP(srcIP);
    
            // 拼接出 SourceIP
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < 4; i++) {
                builder.append((int) (buff_4[i] & 0xff));
                builder.append(".");
            }
            builder.deleteCharAt(builder.length() - 1);
            String sourceIP = builder.toString();
            protocolData.setSrcIP(sourceIP);
    
            for (int i = 0; i < 4; i ++) {      
                buff_4[i] = content[i + offset];
            }
            offset += 4;                                    // offset = 34
            int dstIP = DataUtils.byteArrayToInt(buff_4);
            ip.setDstIP(dstIP);
    
            // 拼接出 DestinationIP
            builder = new StringBuilder();
            for (int i = 0; i < 4; i++) {
                builder.append((int) (buff_4[i] & 0xff));
                builder.append(".");
            }
            builder.deleteCharAt(builder.length() - 1);
            String destinationIP = builder.toString();
            protocolData.setDesIP(destinationIP);
    
    //      LogUtils.printObjInfo(ip);
    
            return ip;
        }
    

    6 读取TCP头

    private TCPHeader readTCPHeader(byte[] content2, int offset) {
            byte[] buff_2 = new byte[2];
            byte[] buff_4 = new byte[4];
    
            TCPHeader tcp = new TCPHeader();
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
    //          LogUtils.printByteToBinaryStr("TCP: buff_2[" + i + "]", buff_2[i]);
            }
            offset += 2;                                    // offset = 36
            short srcPort = DataUtils.byteArrayToShort(buff_2);
            tcp.setSrcPort(srcPort);
    
            String sourcePort = validateData(srcPort);
            protocolData.setSrcPort(sourcePort);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 38
            short dstPort = DataUtils.byteArrayToShort(buff_2);
            tcp.setDstPort(dstPort);
    
            String desPort = validateData(dstPort);
            protocolData.setDesPort(desPort);
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = content[i + offset];
            }
            offset += 4;                                    // offset = 42
            int seqNum = DataUtils.byteArrayToInt(buff_4);
            tcp.setSeqNum(seqNum);
    
            for (int i = 0; i < 4; i ++) {
                buff_4[i] = content[i + offset];
            }
            offset += 4;                                    // offset = 46
            int ackNum = DataUtils.byteArrayToInt(buff_4);
            tcp.setAckNum(ackNum);
    
            byte headerLen = content[offset ++];            // offset = 47
            tcp.setHeaderLen(headerLen);
    
            byte flags = content[offset ++];                // offset = 48
            tcp.setFlags(flags);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 50
            short window = DataUtils.byteArrayToShort(buff_2);
            tcp.setWindow(window);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 52
            short checkSum = DataUtils.byteArrayToShort(buff_2);
            tcp.setCheckSum(checkSum);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 54
            short urgentPointer = DataUtils.byteArrayToShort(buff_2);
            tcp.setUrgentPointer(urgentPointer);
    
    //      LogUtils.printObj("tcp.offset", offset);
            data_offset = offset;
    //      LogUtils.printObjInfo(tcp);
    
            return tcp;
        }
    

    7 读取UDP头

    private UDPHeader readUDPHeader(byte[] content, int offset) {
            byte[] buff_2 = new byte[2];
    
            UDPHeader udp = new UDPHeader();
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
    //          LogUtils.printByteToBinaryStr("UDP: buff_2[" + i + "]", buff_2[i]);
            }
            offset += 2;                                    // offset = 36
            short srcPort = DataUtils.byteArrayToShort(buff_2);
            udp.setSrcPort(srcPort);
    
            String sourcePort = validateData(srcPort);
            protocolData.setSrcPort(sourcePort);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 38
            short dstPort = DataUtils.byteArrayToShort(buff_2);
            udp.setDstPort(dstPort);
    
            String desPort = validateData(dstPort);
            protocolData.setDesPort(desPort);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 40
            short length = DataUtils.byteArrayToShort(buff_2);
            udp.setLength(length);
    
            for (int i = 0; i < 2; i ++) {
                buff_2[i] = content[i + offset];
            }
            offset += 2;                                    // offset = 42
            short checkSum = DataUtils.byteArrayToShort(buff_2);
            udp.setCheckSum(checkSum);
    
    //      LogUtils.printObj("udp.offset", offset );
    //      LogUtils.printObjInfo(udp);
            data_offset = offset;
    
            return udp;
        }
    

    创建文件

    解析完毕后,就得将数据写入文件了

    /**
         * 创建文件
         * @param protocolData
         */
        public void createFiles(ProtocolData protocolData) {
            String protocol = "TCP";
            String suffix = ".pcap";
            if (protocolData.getProtocolType() == ProtocolType.UDP) {
                protocol = "UDP";
            }  else if (protocolData.getProtocolType() == ProtocolType.OTHER) {
                return;
            }
            String filename = protocol + "[" + protocolData.getSrcIP() + "]"
                                       + "[" + protocolData.getSrcPort() + "]"
                                       + "[" + protocolData.getDesIP() + "]"
                                       + "[" + protocolData.getDesPort() + "]";
    
            String reverseFilename = protocol + "[" + protocolData.getDesIP() + "]"
                                              + "[" + protocolData.getDesPort() + "]"
                                              + "[" + protocolData.getSrcIP() + "]"
                                              + "[" + protocolData.getSrcPort() + "]";
            boolean isReverse = false;
    
            boolean append = false;
            // 判断是否已经包含该五元组
            if (filenames.contains(filename)) {
                append = true;
    //          LogUtils.printObj(filename + "已存在...");
            } else {
                append = false;
    //          LogUtils.printObj(filename + "不存在...");
    
                // 将源IP、源Port和目的IP、目的Port 调换顺序,查看该文件是否存在,若存在,则追加
                if (filenames.contains(reverseFilename)) {
                    append = true;
                    isReverse = true;
                    filename = reverseFilename;
    //              LogUtils.printObj("rf: " + reverseFilename + "已存在...");
                } else {
                    filenames.add(filename);
                }
    
            }
    
            filename = DataUtils.validateFilename(filename);
            String pathname = savePath + "\\" + protocol + "\\" + filename + suffix;
    
            /*
             * 数据负载信息
             */
            int data_size = content.length - data_offset;
    //      LogUtils.printObj("数据负载长", data_size);
            data_content = new byte[data_size];
            for (int i = 0; i < data_size; i ++) {
                data_content[i] = content[i + data_offset];
            }
            String pathname_data = savePath + "\\" + protocol + "\\数据负载提取结果\\" + filename + ".pcap.txt";
    
            try {
                File file = new File(pathname);
                FileOutputStream fos = new FileOutputStream(file, append);
    
                File data_file = new File(pathname_data);
                FileOutputStream fos_data = new FileOutputStream(data_file, append);
    
                if (!append) {  // 若 append 为 true,表明文件已经存在,追加
                    // 1. 写入文件头
                    fos.write(file_header);
    
                    String[] data = new String[2];
                    data[0] = filename;
                    data[1] = pathname;
                    datas.add(data);
                    super.setChanged();                             // 通知观察者
                    super.notifyObservers(datas);                   // 传递数据给观察者
    
                    // 不存在,则说明该记录尚未添加
                    String logPath = savePath + "\\" + protocol + "\\" + protocol + ".txt";
                    FileUtils.writeLineToFile(filename, new File(logPath), true);
                }
    
                // 2. 写入 Pcap 数据头
    //          LogUtils.printObj("data_header.length", data_header.length);
                fos.write(data_header);
                // 3. 写入数据
    //          LogUtils.printObj("content.length", content.length);
                fos.write(content);
    
                // 写入数据负载信息
                fos_data.write(data_content);
    
                // 4. 关闭流
                FileUtils.closeStream(null, fos);
                FileUtils.closeStream(null, fos_data);
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } 
    
        }
    

    项目代码下载PcapAnalyzer

    前往 bascker/javaworld 获取更多 Java 知识

    展开全文
  • Java 解析Pcap文件(2)

    2021-03-11 11:19:50
    Java 解析Pcap文件(2) @author:Jingdai @date:2021.03.11 前面介绍了Pcap文件的结构并对Pcap文件的 Global Header 和 Packet Header进行了解析,接下来就是对Packet Data 即数据链路层的帧进行解析了。 数据链...

    Java 解析Pcap文件(2)

    @author:Jingdai
    @date:2021.03.11

    前面介绍了Pcap文件的结构并对Pcap文件的 Global Header 和 Packet Header进行了解析,接下来就是对Packet Data 即数据链路层的帧进行解析了。

    数据链路层解析

    Pcap包的Packet Data就是数据链路层的帧,可以根据前面的Packet Header 中的 capLen 字段知道对应的Packet Data 数据的字节数,从而进行读取。这里仅仅以以太网的帧为例进行解析,我们一般用 Wireshark 抓取的包大部分也是以太网的帧。如下图是以太网的帧结构。

    在这里插入图片描述

    需要注意的是,这里的 Packet Data 的以太网帧没有前同步码和FCS,原因可以参考这篇博客,所以以太网的帧首部就固定为14个字节,6字节的目的MAC地址,6字节的源MAC地址和2字节的协议类型,如果协议类型字段值为0x0800时,代表上层协议是IP。

    这里我不解析源MAC地址和目的MAC地址,因为对我的实验没有用,这里我只需要上层协议的类型。

    然后据此建立类 FrameHeader,代码如下。

    package com.jingdai.pcapanalyzer.entity.format;
    
    /**
     * 帧头(Ethernet Header)
     */
    
    public class FrameHeader {
    
        public static final int PROTOCOL_IP = 2048;
    
        private int protocol;
    
        public int getProtocol() {
            return protocol;
        }
    
        public void setProtocol(int protocol) {
            this.protocol = protocol;
        }
    
        public FrameHeader() {}
    }
    

    同时解析的代码如下。

        public FrameHeader parseFrameHeader(byte[] frameHeaderBuffer) {
            FrameHeader frameHeader = new FrameHeader();
            // 目的MAC地址、源MAC地址没用,越过
            byte[] protocolBuffer = Arrays.copyOfRange(frameHeaderBuffer, 12, 14);
    
            int protocol = DataUtils.byteArray2Int(protocolBuffer, 2);
            frameHeader.setProtocol(protocol);
            return frameHeader;
        }
    

    后面解析IP数据包和TCP段的类和解析代码类似,就不放代码了,最后我会把项目的全部代码的链接放出来供大家参考。

    IP包解析

    在 Packet Data 数据中去掉上节解析的帧头,剩下的就是IP数据包,即IP包就是以太网帧的数据部分。下图是IP包的结构。

    在这里插入图片描述

    由图知道IP包的首部长度不是固定的,可以从IP包的第一个字节的一半得出IP首部的长度,注意单位是4字节,然后根据这个长度截取相应的长度对IP首部进行解析。

    TCP数据段解析

    去掉IP首部后,如果IP包上层协议是TCP,就紧接着对TCP数据段进行解析(UDP更加简单,稍微改一点代码就可以),下图是TCP数据段的结构。

    在这里插入图片描述

    如图可见TCP数据段的首部长度也不是固定的,图中的数据偏移就相当于首部的长度,注意单位是4字节,然后根据此值截取相应的长度对TCP的首部进行解析。

    项目地址

    参考

    • 谢希仁 计算机网络(第7版)
    展开全文
  • JavaPcap文件解析(一:Pcap格式分析)

    万次阅读 2016-01-11 10:54:55
    1. 对Pcap文件进行解析,并从中提取TCP和UDP会话 2. 从TCP会话中提取出其数据负载信息 软件最终结果 [主界面] [File 菜单] [Help 的 About 菜单项,版权声明] [选择Pcap文件] [选择输出目录] ...
  • java解析Pcap文件获取五元组(可运行)
  • 数据结构 根据上一篇文章的内容,可以建立如下数据...Pcap 文件头 /** * Pcap 文件头结构 * @author johnnie * */ public class PcapFileHeader { private int magic; // 标识位,这个标识位的值是16进制的...
  • 数据结构已经定义好了,那么现在就开始正式解析Pcap文件了。  注:以下仅贴出核心代码,项目全部代码会在文章结尾处给出下载链接 解析Pcap文件 1 读取整个Pcap文件到内存 FileInputStream fis = null; ...
  • 原文地址:... 对Pcap文件进行解析,并从中提取TCP和UDP会话 2. 从TCP会话中提取出其数据负载信息软件最终结果[主界面] [File 菜单] [Help 的 About 菜单项,版权声明] [选择Pcap文件] [选择输出目...
  • 1. 对Pcap文件进行解析,并从中提取TCP和UDP会话  2. 从TCP会话中提取出其数据负载信息 软件最终结果 [主界面]    [File 菜单]    [Help 的 About 菜单项,版权声明]    [选择Pcap文件]    ...
  • 本文基本翻译自https://wiki.wireshark.org/Development/LibpcapFileFormat,主要分析pcap文件的格式。
  • pcap文件格式

    2019-10-06 19:24:29
    好吧 早就想写一个博客了,希望可以像大佬一样,不过一直没有行动。既然已经读研了,什么都玩过了,虽然也没有很想好好学习,但是以后还是要吃饭的呀。就当记录学习心得,也当做笔记吧,...Pcap文件格式实际上是...
  • 原文链接:https://blog.csdn.net/GuLu_GuLu_jp/article/details/50495200数据结构根据上一篇文章的内容,可以建立如下数据结构... * Pcap 文件头结构 * @author johnnie * */ public class PcapFileHeader { ...
  • pcap文件解析,并按照五元组分包,全部用java语言实现。
  • 数据结构 根据上一篇文章的内容,可以建立如下数据结构 ...Pcap 文件头 /** * Pcap 文件头结构 * @author johnnie * */ public class PcapFileHeader { private int magic; // 标识位,这个标识位的值是16进
  • pcap文件中还原文件

    千次阅读 2017-06-06 11:32:54
    直接从wireshark中显示raw,然后只显示一端向另一端发的数据,然后保存为某文件,然后用hex编辑器(比如010 Editor,或者Windows上的winhex)打开,去除掉无关的内容,然后保存。 保存之后,由于流量中显示该文件是...
  • 用于从PCAP文件生成流特征的解析器 基于ISCXFlowMeter项目。 特征 无双向 超时输入(以秒为单位) 来自捕获的报头的在线数据包的长度,以获取数据包的实际大小(解决了由于已从捕获的数据包中删除了有效负载而从...
  • cd src/velodyne/velodyne_driver/src/lib vi input.cc
  • pcap文件切割 1.在文件夹创建一个新的文件test.pcap 2.在pcap文件夹,在文件路径cmd打开窗口, 3.使用命令行 editcap -i input.pcap output.pcap e.g: editcap -i 1200 input.pcap output.pcap 1200秒切割 editcap ...
  • 通过匿名化任何个人身份数据,这将允许存储pcap文件。 该代码将:- 读取所有数据包 在UDP或TCP数据包中找到任何SIP数据包 解析所有SIP标头,使原始MSISDN匿名 存储更新的SIP数据包 非SIP数据包通过未更改的方式...
  • 优雅地将多个pcap文件合并在一起。 安装 从下载预编译的二进制文件 或者...使用go get : go get -u github.com/assafmo/joincap 或使用Ubuntu PPA: curl -SsL https://assafmo.github.io/ppa/ubuntu/KEY.gpg | ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,508
精华内容 603
关键字:

pcap文件java

java 订阅