1 package edu.uci.iotproject;
3 import org.pcap4j.packet.Packet;
4 import org.pcap4j.packet.DnsPacket;
5 import org.pcap4j.packet.DnsResourceRecord;
6 import org.pcap4j.packet.namednumber.DnsResourceRecordType;
8 import java.io.EOFException;
9 import java.net.Inet4Address;
10 import java.net.UnknownHostException;
11 import java.time.Instant;
13 import java.util.concurrent.TimeoutException;
16 * This is a class that does DNS mapping.
17 * Basically an IP address is mapped to its
18 * respective DNS hostnames.
20 * @author Rahmadi Trimananda (rtrimana@uci.edu)
25 /* Class properties */
26 private Map<String, Set<String>> ipToHostnameMap;
29 private static final Set<String> EMPTY_SET = Collections.unmodifiableSet(new HashSet<>());
35 ipToHostnameMap = new HashMap<String, Set<String>>();
40 * Gets a packet and determine if this is a DNS packet
42 * @param packet Packet object
43 * @return DnsPacket object or null
45 private DnsPacket getDnsPacket(Packet packet) {
47 DnsPacket dnsPacket = packet.get(DnsPacket.class);
53 * Checks DNS packet and build the map data structure that
54 * maps IP addresses to DNS hostnames
56 * @param packet Packet object
58 public void validateAndAddNewEntry(Packet packet) throws UnknownHostException {
60 // Make sure that this is a DNS packet
61 DnsPacket dnsPacket = getDnsPacket(packet);
62 if (dnsPacket != null) {
64 // We only care about DNS answers
65 if (dnsPacket.getHeader().getAnswers().size() != 0) {
67 String hostname = dnsPacket.getHeader().getQuestions().get(0).getQName().getName();
68 for(DnsResourceRecord answer : dnsPacket.getHeader().getAnswers()) {
69 // We only care about type A records
70 if (!answer.getDataType().equals(DnsResourceRecordType.A))
72 // Sanity check. For some reason the hostname appears to be the empty string in the answer .
73 // We hence have to assume that all answers correspond to a single question that holds the hostname as part of its object tree.
74 // Therefore, if there are more questions in one query-reply exchange, we are in trouble.
75 if (!answer.getName().getName().equals("") && !answer.getName().getName().equals(hostname))
76 throw new RuntimeException("[DNS parser] mismatch between hostname in question and hostname in answer");
77 // The IP in byte representation.
78 byte[] ipBytes = answer.getRData().getRawData();
79 // Convert to string representation.
80 String ip = Inet4Address.getByAddress(ipBytes).getHostAddress();
81 Set<String> hostnameSet = new HashSet<String>();
82 hostnameSet.add(hostname);
83 // Update or insert depending on presence of key:
84 // Concat the existing set and the new set if ip already present as key,
85 // otherwise add an entry for ip pointing to new set.
86 ipToHostnameMap.merge(ip, hostnameSet, (v1, v2) -> { v1.addAll(v2); return v1; });
94 * Checks DNS packet and build the map data structure that
95 * maps IP addresses to DNS hostnames
97 * @param address Address to check
98 * @param hostname Hostname to check
100 public boolean isRelatedToCloudServer(String address, String hostname) {
102 return ipToHostnameMap.getOrDefault(address, EMPTY_SET).contains(hostname);