-
Notifications
You must be signed in to change notification settings - Fork 34
ParsePCAPFiles
SeparateWings edited this page Jul 8, 2023
·
2 revisions
I am going to show a small example how to parse PCAP files produced by Wireshark. The Format description I have found in the Wireshark wiki.
I have written a small class which takes a link to a PCAP file defined as the first command line argument and prints its inside content to console. The PCAP file can be saved in different byte orders so that I am made to check that outside of the parsing process and make selection of the right parsers based on the magic number byte order.
package com.igormaznitsa.parsepcap;
import com.igormaznitsa.jbbp.JBBPParser;
import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
import com.igormaznitsa.jbbp.io.JBBPByteOrder;
import com.igormaznitsa.jbbp.mapper.Bin;
import com.igormaznitsa.jbbp.utils.JBBPUtils;
import java.io.FileInputStream;
public class PCAPParser {
private static final JBBPParser PCAP_HEADER_LITTLE_ENDIAN = JBBPParser.prepare(
"<short version_major;"
+ "<short version_minor;"
+ "<int thiszone;"
+ "<int sigfigs;"
+ "<int snaplen;"
+ "<int network;"
);
private static final JBBPParser PCAP_HEADER_BIG_ENDIAN = JBBPParser.prepare(
"short version_major;"
+ "short version_minor;"
+ "int thiszone;"
+ "int sigfigs;"
+ "int snaplen;"
+ "int network;"
);
private static final JBBPParser PCAP_PACKET_LITTLE_ENDIAN = JBBPParser.prepare(
"<int ts_sec;"
+ "<int ts_usec;"
+ "<int incl_len;"
+ "<int orig_len;"
+ "byte [incl_len] data;"
);
private static final JBBPParser PCAP_PACKET_BIG_ENDIAN = JBBPParser.prepare(
"int ts_sec;"
+ "int ts_usec;"
+ "int incl_len;"
+ "int orig_len;"
+ "byte [incl_len] data;"
);
public static void main(final String ... args) throws Exception {
@Bin class PcapHeader {
short version_major;
short version_minor;
int thiszone;
int sigfigs;
int snaplen;
int network;
@Override
public String toString() {
return "Version "+version_major+'.'+version_minor+
"\nGMT to local correction: "+thiszone+
"\nAccuracy of timestamps: "+sigfigs+
"\nMax length of captured packets, in octets: "+snaplen+
"\nData link type: "+network;
}
}
@Bin class PcapPacket {
int ts_sec;
int ts_usec;
int incl_len;
int orig_len;
byte [] data;
@Override
public String toString() {
return "Timestamp (s): "+Long.toString((long)ts_sec & 0xFFFFFFFFL)+", "+
"Timestamp (us): " + Long.toString((long) ts_usec & 0xFFFFFFFFL) + ", " +
"Length : " + incl_len + ", " +
"Orig.Length : " + orig_len + ", "+JBBPUtils.array2hex(data);
}
}
JBBPBitInputStream inStream = null;
try{
inStream = new JBBPBitInputStream(new FileInputStream(args[0]));
final int magic = inStream.readInt(JBBPByteOrder.BIG_ENDIAN);
final JBBPParser headerParser;
final JBBPParser packetParser;
switch(magic){
case 0xA1B2C3D4:{
// BIG ENDIAN ORDER
headerParser = PCAP_HEADER_BIG_ENDIAN;
packetParser = PCAP_PACKET_BIG_ENDIAN;
}break;
case 0xD4C3B2A1:{
// LITTLE ENDIAN ORDER
headerParser = PCAP_HEADER_LITTLE_ENDIAN;
packetParser = PCAP_PACKET_LITTLE_ENDIAN;
}break;
default: throw new Exception("It is not a PCAP file");
}
final PcapHeader header = headerParser.parse(inStream).mapTo(PcapHeader.class);
System.out.println("PCAP File\n----------------------\n"+header+"\n----------------------");
int packetCounter = 0;
while(inStream.hasAvailableData()){
final PcapPacket packet = packetParser.parse(inStream).mapTo(PcapPacket.class);
System.out.println(packet);
packetCounter ++;
}
System.out.println("-------------------\nParsed "+packetCounter+" packet(s)");
}finally{
JBBPUtils.closeQuietly(inStream);
}
}
}