Network学习7_Java之Pcap文件解析(二:建立数据结构)

来源:互联网 发布:clasence 软件 编辑:程序博客网 时间:2024/05/29 10:07

数据结构

根据上一篇文章的内容,可以建立如下数据结构

Pcap 文件头

/**     * Pcap 文件头结构     * @author johnnie     *     */    public class PcapFileHeader {        private int magic;                  // 标识位,这个标识位的值是16进制的 0xa1b2c3d4(4个字节)        private short magorVersion;     // 主版本号(2个字节)        private short minorVersion;     // 副版本号(2个字节)        private int timezone;               // 区域时间(4个字节)        private int sigflags;               // 精确时间戳(4个字节)        private int snaplen;                // 数据包最大长度(4个字节)        private int linktype;               // 链路层类型(4个字节)        public int getMagic() {            return magic;        }        public void setMagic(int magic) {            this.magic = magic;        }        public short getMagorVersion() {            return magorVersion;        }        public void setMagorVersion(short magorVersion) {            this.magorVersion = magorVersion;        }        public short getMinorVersion() {            return minorVersion;        }        public void setMinorVersion(short minorVersion) {            this.minorVersion = minorVersion;        }        public int getTimezone() {            return timezone;        }        public void setTimezone(int timezone) {            this.timezone = timezone;        }        public int getSigflags() {            return sigflags;        }        public void setSigflags(int sigflags) {            this.sigflags = sigflags;        }        public int getSnaplen() {            return snaplen;        }        public void setSnaplen(int snaplen) {            this.snaplen = snaplen;        }        public int getLinktype() {            return linktype;        }        public void setLinktype(int linktype) {            this.linktype = linktype;        }        public PcapFileHeader() {}        public PcapFileHeader(int magic, short magorVersion, short minorVersion,                int timezone, int sigflags, int snaplen, int linktype) {            this.magic = magic;            this.magorVersion = magorVersion;            this.minorVersion = minorVersion;            this.timezone = timezone;            this.sigflags = sigflags;            this.snaplen = snaplen;            this.linktype = linktype;        }        @Override        public String toString() {            return "PcapFileHeader [magic=" + DataUtils.intToHexString(magic)                    + ", magorVersion=" + DataUtils.shortToHexString(magorVersion)                    + ", minorVersion=" + DataUtils.shortToHexString(minorVersion)                    + ", timezone=" + DataUtils.intToHexString(timezone)                    + ", sigflags=" +  DataUtils.intToHexString(sigflags)                    + ", snaplen=" +  DataUtils.intToHexString(snaplen)                    + ", linktype=" +  DataUtils.intToHexString(linktype)                    + "]";        }    }   

Pcap 数据头

/** * Pcap 数据包头 * @author johnnie * */public class PcapDataHeader {    /**     * 时间戳(秒):记录数据包抓获的时间     * 记录方式是从格林尼治时间的1970年1月1日 00:00:00 到抓包时经过的秒数(4个字节)     */    private int timeS;      /**     * 时间戳(微秒):抓取数据包时的微秒值(4个字节)     */    private int timeMs;                         /**     * 数据包长度:标识所抓获的数据包保存在 pcap 文件中的实际长度,以字节为单位(4个字节)     */    private int caplen;    /**     * 数据包实际长度: 所抓获的数据包的真实长度(4个字节)     * 如果文件中保存不是完整的数据包,那么这个值可能要比前面的数据包长度的值大。     */    private int len;                            public int getTimeS() {        return timeS;    }    public void setTimeS(int timeS) {        this.timeS = timeS;    }    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 PcapDataHeader() {}    @Override    public String toString() {        return "PcapDataHeader [timeS=" +  DataUtils.intToHexString(timeS)                + ", timeMs=" +  DataUtils.intToHexString(timeMs)                + ", caplen=" +  caplen                + ", len=" +  len                + "]";    }}

以太网数据帧

/** * Pcap 捕获的数据帧头:以太网帧,14 个字节,可以不做处理,直接跳过 * @author johnnie * */public class PcapDataFrame {    /**     * 目的 MAC 地址:6 byte     */    private byte[] desMac;    /**     * 源 MAC 地址:6 byte     */    private byte[] srcMac;    /**     * 数据帧类型:2 字节     */    private short frameType;    public byte[] getDesMac() {        return desMac;    }    public void setDesMac(byte[] desMac) {        this.desMac = desMac;    }    public byte[] getSrcMac() {        return srcMac;    }    public void setSrcMac(byte[] srcMac) {        this.srcMac = srcMac;    }    public short getFrameType() {        return frameType;    }    public void setFrameType(short frameType) {        this.frameType = frameType;    }    public PcapDataFrame() {}    /**     * 按照 Wireshark 的格式显示信息     */    @Override    public String toString() {        // frameType 以 十六进制显示        return "PcapDataFrame [frameType=" + DataUtils.shortToHexString(frameType) + "]";    }}

IP 头

/** * IP 数据报头 * @author johnnie * */public class IPHeader {    /**     * 协议版本号(4 bit)及包头长度(4bit) =(1 字节)     * 版本号(Version):一般的值为0100(IPv4),0110(IPv6)     * IP包头最小长度为20字节     */    private byte varHLen;    /**     * Type of  Service:服务类型,(1 字节)     */    private byte tos;    /**     * 总长度(2 字节)     */    private short totalLen;    /**     * 标识(2 字节)     */    private short id;    /**     * 标志与偏移量(2 字节)     */    private short flagSegment;    /**     * Time to Live:生存周期(1 字节)     */    private byte ttl;    /**     * 协议类型(1 字节)     */    private byte protocol;    /**     * 头部校验和(2 字节)     */    private short checkSum;    /**     * 源 IP(4 字节)     */    private int srcIP;    /**     * 目的 IP(4 字节)     */    private int dstIP;    public byte getVarHLen() {        return varHLen;    }    public void setVarHLen(byte varHLen) {        this.varHLen = varHLen;    }    public byte getTos() {        return tos;    }    public void setTos(byte tos) {        this.tos = tos;    }    public short getTotalLen() {        return totalLen;    }    public void setTotalLen(short totalLen) {        this.totalLen = totalLen;    }    public short getId() {        return id;    }    public void setId(short id) {        this.id = id;    }    public short getFlagSegment() {        return flagSegment;    }    public void setFlagSegment(short flagSegment) {        this.flagSegment = flagSegment;    }    public byte getTtl() {        return ttl;    }    public void setTtl(byte ttl) {        this.ttl = ttl;    }    public byte getProtocol() {        return protocol;    }    public void setProtocol(byte protocol) {        this.protocol = protocol;    }    public short getCheckSum() {        return checkSum;    }    public void setCheckSum(short checkSum) {        this.checkSum = checkSum;    }    public int getSrcIP() {        return srcIP;    }    public void setSrcIP(int srcIP) {        this.srcIP = srcIP;    }    public int getDstIP() {        return dstIP;    }    public void setDstIP(int dstIP) {        this.dstIP = dstIP;    }    public IPHeader() { }    @Override    public String toString() {        return "IPHeader [varHLen=" + DataUtils.byteToHexString(varHLen)                + ", tos=" + DataUtils.byteToHexString(tos)                + ", totalLen=" + totalLen                + ", id=" + DataUtils.shortToHexString(id)                + ", flagSegment=" + DataUtils.shortToHexString(flagSegment)                + ", ttl=" + ttl                + ", protocol=" + protocol                + ", checkSum=" + DataUtils.shortToHexString(checkSum)                + ", srcIP=" + DataUtils.intToHexString(srcIP)                + ", dstIP=" + DataUtils.intToHexString(dstIP)                + "]";    }}

TCP 头

/** * TCP 包头:20 字节 * @author johnnie * */public class TCPHeader {    /**     * 源端口(2 字节)     */    private short srcPort;    /**     * 目的端口(2 字节)     */    private short dstPort;    /**     * Sequence Number:发送数据包中的第一个字节的序列号(4 字节)     */    private int seqNum;    /**     * 确认序列号(4 字节)     */    private int ackNum;    /**     * 数据报头的长度(4 bit) + 保留(4 bit) = 1 byte     */    private byte headerLen;    /**     * 标识TCP不同的控制消息(1 字节)     */    private byte flags;    /**     * 接收缓冲区的空闲空间,用来告诉TCP连接对端自己能够接收的最大数据长度(2 字节)     */    private short window;    /**     * 校验和(2 字节)     */    private short checkSum;    /**     * 紧急指针(2 字节)     */    private short urgentPointer;    public short getSrcPort() {        return srcPort;    }    public void setSrcPort(short srcPort) {        this.srcPort = srcPort;    }    public short getDstPort() {        return dstPort;    }    public void setDstPort(short dstPort) {        this.dstPort = dstPort;    }    public int getSeqNum() {        return seqNum;    }    public void setSeqNum(int seqNum) {        this.seqNum = seqNum;    }    public int getAckNum() {        return ackNum;    }    public void setAckNum(int ackNum) {        this.ackNum = ackNum;    }    public byte getHeaderLen() {        return headerLen;    }    public void setHeaderLen(byte headerLen) {        this.headerLen = headerLen;    }    public byte getFlags() {        return flags;    }    public void setFlags(byte flags) {        this.flags = flags;    }    public short getWindow() {        return window;    }    public void setWindow(short window) {        this.window = window;    }    public short getCheckSum() {        return checkSum;    }    public void setCheckSum(short checkSum) {        this.checkSum = checkSum;    }    public short getUrgentPointer() {        return urgentPointer;    }    public void setUrgentPointer(short urgentPointer) {        this.urgentPointer = urgentPointer;    }    public TCPHeader() {}    @Override    public String toString() {        return "TCPHeader [srcPort=" + srcPort                + ", dstPort=" + dstPort                + ", seqNum=" + seqNum                + ", ackNum=" + ackNum                + ", headerLen=" + headerLen                + ", flags=" + DataUtils.byteToHexString(flags)                + ", window=" + window                + ", checkSum=" + DataUtils.shortToHexString(checkSum)                + ", urgentPointer=" + urgentPointer                + "]";    }}


UDP 头

/** * UDP 包头:由4个域组成,每个域各占用2个字节 * @author johnnie * */public class UDPHeader {    private short srcPort;          // 源端口    private short dstPort;          // 目的端口    private short length;           // 数据包长    private short checkSum;     // 校验和    public short getSrcPort() {        return srcPort;    }    public void setSrcPort(short srcPort) {        this.srcPort = srcPort;    }    public short getDstPort() {        return dstPort;    }    public void setDstPort(short dstPort) {        this.dstPort = dstPort;    }    public short getLength() {        return length;    }    public void setLength(short length) {        this.length = length;    }    public short getCheckSum() {        return checkSum;    }    public void setCheckSum(short checkSum) {        this.checkSum = checkSum;    }    public UDPHeader() {}    @Override    public String toString() {        // TODO Auto-generated method stub        return "UDPHeader [srcPort=" + srcPort                + ", dstPort=" + dstPort                + ", length=" + length                + ", checkSum=" + DataUtils.shortToHexString(checkSum)                + "]";    }}

协议类型

/** * 协议类型 * @author johnnie * */public enum ProtocolType {    OTHER("0"),                 // 其他协议号:默认为0    TCP("6"),                   // TCP 协议号:6    UDP("17");                  // UDP 协议号:17    private String type;    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }    private ProtocolType(String type) {        this.type = type;    }}

协议五元组

/** * 协议数据,五元组 * @author johnnie * */public class ProtocolData {    String srcIP;                                       // 源 IP    String desIP;                                       // 目的 IP    String srcPort;                                     // 源端口    String desPort;                                     // 目的端口    ProtocolType protocolType = ProtocolType.OTHER;     // 协议类型    public String getSrcIP() {        return srcIP;    }    public void setSrcIP(String srcIP) {        this.srcIP = srcIP;    }    public String getDesIP() {        return desIP;    }    public void setDesIP(String desIP) {        this.desIP = desIP;    }    public String getSrcPort() {        return srcPort;    }    public void setSrcPort(String srcPort) {        this.srcPort = srcPort;    }    public String getDesPort() {        return desPort;    }    public void setDesPort(String desPort) {        this.desPort = desPort;    }    public ProtocolType getProtocolType() {        return protocolType;    }    public void setProtocolType(ProtocolType protocolType) {        this.protocolType = protocolType;    }    public ProtocolData() {        // TODO Auto-generated constructor stub    }    public ProtocolData(String srcIP, String desIP, String srcPort,            String desPort, ProtocolType protocolType) {        this.srcIP = srcIP;        this.desIP = desIP;        this.srcPort = srcPort;        this.desPort = desPort;        this.protocolType = protocolType;    }    @Override    public String toString() {        return "ProtocolData [srcIP=" + srcIP                + ", desIP=" + desIP                + ", srcPort=" + srcPort                + ", desPort=" + desPort                + ", protocolType=" + protocolType                + "]";    }}

Pcap结构

/** * Pcap 结构 * @author johnnie * */public class PcapStruct {    private PcapFileHeader fileHeader;    private List<PcapDataHeader> dataHeaders;    public PcapFileHeader getFileHeader() {        return fileHeader;    }    public void setFileHeader(PcapFileHeader fileHeader) {        this.fileHeader = fileHeader;    }    public List<PcapDataHeader> getDataHeaders() {        return dataHeaders;    }    public void setDataHeaders(List<PcapDataHeader> dataHeaders) {        this.dataHeaders = dataHeaders;    }    public PcapStruct() {}}

0 0