[Java] Load the packet capture obtained by tcpdump in Java

1 minute read

I want to read the result of packet capture with tcpdump, but I want to read it with some program instead of checking it with Wireshark. I could read it using a Java library called pkts, so make a note of what I did.

Command that captured

Since I want to get a list of domains to communicate from the first SYN packet of the TCP handshake and DNS response, I set a filter as follows.

# Extract packets that meet any of the following conditions
#-SYN flag is set and ACK flag is not set
#-Source port is 53 (DNS)
sudo tcpdump -s 0 -i en0 -nn -w tcpdump.pcap \('(tcp[tcpflags] & tcp-syn)' != 0 and'(tcp[tcpflags] & tcp-ack) ==0'\) or src port 53

How to read in Java

I used a Java library called pkts. The following is a part of a simple implementation example.

final Pcap pcap = Pcap.openStream("tcpdump.pcap");
pcap.loop(new PacketHandler() {
  public boolean nextPacket(Packet packet) throws IOException {
    if (packet.hasProtocol(Protocol.UDP)) {

In the case of IPv4 or UDP, the information of the header part can be acquired by acquiring the packet.

if (packet.hasProtocol(Protocol.IPv4)) (
  IPv4Packet ipv4Packet = (IPv4Packet) packet.getPacket(Protocol.IPv4);
  String srcIP = ipv4Packet.getSourceIP();
  String dstIP = ipv4Packet.getDestinationIP();

If you want to read the contents of Payload, you can get it as a byte array by the following method.

UDPPacket udpPacket = (UDPPacket) packet.getPacket(Protocol.UDP);
Buffer buffer = udpPacket.getPayload();
byte[] bytes = buffer.getArray();

The part that is parsed as a DNS packet must be written by yourself, referring to the DNS packet format. In the case of DNS, the domain part and the number of responses are variable, so it is a little troublesome. A very crude implementation aimed only at reading in characters without worrying about the format is here.

  • https://www.javahelps.com/2017/08/parse-pcap-files-in-java.html