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 was able to load it using a Java library called pkts, so make a note of what I did.
I want to get a list of communication destination domains from the first SYN packet and DNS response of the TCP handshake, so I set the filter as follows
#Extract packets that meet any of the following conditions
# -The SYN flag is set and the 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
I used a Java library called pkts. Some of the simple implementation examples are as follows.
final Pcap pcap = Pcap.openStream("tcpdump.pcap");
pcap.loop(new PacketHandler() {
@Override
public boolean nextPacket(Packet packet) throws IOException {
if (packet.hasProtocol(Protocol.UDP)) {
System.out.println(packet.getPacket(Protocol.UDP).getPayload());
}
}
}
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 to be parsed as a DNS packet needs to be written by yourself with reference to the DNS packet format. In the case of DNS, it is a little troublesome because the domain part and the number of responses are variable. Here is a very crude implementation that aims to read only in characters without worrying about the format.
Recommended Posts