根据上一篇文章的内容,可以建立如下数据结构
/**
* 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 数据包头
* @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 数据报头
* @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 包头: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 包头:由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 结构
* @author johnnie
*
*/
public class PcapStruct {
private PcapFileHeader fileHeader;
private List dataHeaders;
public PcapFileHeader getFileHeader() {
return fileHeader;
}
public void setFileHeader(PcapFileHeader fileHeader) {
this.fileHeader = fileHeader;
}
public List getDataHeaders() {
return dataHeaders;
}
public void setDataHeaders(List dataHeaders) {
this.dataHeaders = dataHeaders;
}
public PcapStruct() {}
}
前往 bascker/javaworld 获取更多 Java 知识