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版)