--- /dev/null
+// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
+package edu.uci.iotproject;
+
+import io.kaitai.struct.ByteBufferKaitaiStream;
+import io.kaitai.struct.KaitaiStruct;
+import io.kaitai.struct.KaitaiStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.nio.charset.Charset;
+
+import java.nio.BufferUnderflowException;
+
+
+/**
+ * (No support for Auth-Name + Add-Name for simplicity)
+ */
+public class DnsPacket extends KaitaiStruct {
+ public static DnsPacket fromFile(String fileName) throws IOException {
+ return new DnsPacket(new ByteBufferKaitaiStream(fileName));
+ }
+
+ public enum ClassType {
+ IN_CLASS(1),
+ CS(2),
+ CH(3),
+ HS(4);
+
+ private final long id;
+ ClassType(long id) { this.id = id; }
+ public long id() { return id; }
+ private static final Map<Long, ClassType> byId = new HashMap<Long, ClassType>(4);
+ static {
+ for (ClassType e : ClassType.values())
+ byId.put(e.id(), e);
+ }
+ public static ClassType byId(long id) { return byId.get(id); }
+ }
+
+ public enum TypeType {
+ A(1),
+ NS(2),
+ MD(3),
+ MF(4),
+ CNAME(5),
+ SOE(6),
+ MB(7),
+ MG(8),
+ MR(9),
+ NULL(10),
+ WKS(11),
+ PTR(12),
+ HINFO(13),
+ MINFO(14),
+ MX(15),
+ TXT(16);
+
+ private final long id;
+ TypeType(long id) { this.id = id; }
+ public long id() { return id; }
+ private static final Map<Long, TypeType> byId = new HashMap<Long, TypeType>(16);
+ static {
+ for (TypeType e : TypeType.values())
+ byId.put(e.id(), e);
+ }
+ public static TypeType byId(long id) { return byId.get(id); }
+ }
+
+ public DnsPacket(KaitaiStream _io) {
+ this(_io, null, null);
+ }
+
+ public DnsPacket(KaitaiStream _io, KaitaiStruct _parent) {
+ this(_io, _parent, null);
+ }
+
+ public DnsPacket(KaitaiStream _io, KaitaiStruct _parent, DnsPacket _root) {
+ super(_io);
+ this._parent = _parent;
+ this._root = _root == null ? this : _root;
+ _read();
+ }
+ private void _read() {
+ this.transactionId = this._io.readU2be();
+ this.flags = new PacketFlags(this._io, this, _root);
+ this.qdcount = this._io.readU2be();
+ this.ancount = this._io.readU2be();
+ this.nscount = this._io.readU2be();
+ this.arcount = this._io.readU2be();
+ queries = new ArrayList<Query>((int) (qdcount()));
+ for (int i = 0; i < qdcount(); i++) {
+ this.queries.add(new Query(this._io, this, _root));
+ }
+ answers = new ArrayList<Answer>((int) (ancount()));
+ for (int i = 0; i < ancount(); i++) {
+ this.answers.add(new Answer(this._io, this, _root));
+ }
+ }
+ public static class PointerStruct extends KaitaiStruct {
+ public static PointerStruct fromFile(String fileName) throws IOException {
+ return new PointerStruct(new ByteBufferKaitaiStream(fileName));
+ }
+
+ public PointerStruct(KaitaiStream _io) {
+ this(_io, null, null);
+ }
+
+ public PointerStruct(KaitaiStream _io, DnsPacket.Label _parent) {
+ this(_io, _parent, null);
+ }
+
+ public PointerStruct(KaitaiStream _io, DnsPacket.Label _parent, DnsPacket _root) {
+ super(_io);
+ this._parent = _parent;
+ this._root = _root;
+ _read();
+ }
+ private void _read() {
+ this.value = this._io.readU1();
+ }
+ private DomainName contents;
+ public DomainName contents() {
+ if (this.contents != null)
+ return this.contents;
+ KaitaiStream io = _root._io();
+ long _pos = io.pos();
+ io.seek(value());
+ this.contents = new DomainName(io, this, _root);
+ io.seek(_pos);
+ return this.contents;
+ }
+ private int value;
+ private DnsPacket _root;
+ private DnsPacket.Label _parent;
+
+ /**
+ * Read one byte, then offset to that position, read one domain-name and return
+ */
+ public int value() { return value; }
+ public DnsPacket _root() { return _root; }
+ public DnsPacket.Label _parent() { return _parent; }
+ }
+ public static class Label extends KaitaiStruct {
+ public static Label fromFile(String fileName) throws IOException {
+ return new Label(new ByteBufferKaitaiStream(fileName));
+ }
+
+ public Label(KaitaiStream _io) {
+ this(_io, null, null);
+ }
+
+ public Label(KaitaiStream _io, DnsPacket.DomainName _parent) {
+ this(_io, _parent, null);
+ }
+
+ public Label(KaitaiStream _io, DnsPacket.DomainName _parent, DnsPacket _root) {
+ super(_io);
+ this._parent = _parent;
+ this._root = _root;
+ _read();
+ }
+ private void _read() {
+ this.length = this._io.readU1();
+ if (isPointer()) {
+ this.pointer = new PointerStruct(this._io, this, _root);
+ }
+ // TODO: This part causes BufferUnderflowException
+ if (!(isPointer())) {
+ try {
+ this.name = new String(this._io.readBytes(length()), Charset.forName("ASCII"));
+ } catch (BufferUnderflowException ex) {
+ //ex.printStackTrace();
+ this.name = null;
+ }
+ }
+ }
+ private Boolean isPointer;
+ public Boolean isPointer() {
+ if (this.isPointer != null)
+ return this.isPointer;
+ boolean _tmp = (boolean) (length() == 192);
+ this.isPointer = _tmp;
+ return this.isPointer;
+ }
+ private int length;
+ private PointerStruct pointer;
+ private String name;
+ private DnsPacket _root;
+ private DnsPacket.DomainName _parent;
+
+ /**
+ * RFC1035 4.1.4: If the first two bits are raised it's a pointer-offset to a previously defined name
+ */
+ public int length() { return length; }
+ public PointerStruct pointer() { return pointer; }
+
+ /**
+ * Otherwise its a string the length of the length value
+ */
+ public String name() { return name; }
+ public DnsPacket _root() { return _root; }
+ public DnsPacket.DomainName _parent() { return _parent; }
+ }
+ public static class Query extends KaitaiStruct {
+ public static Query fromFile(String fileName) throws IOException {
+ return new Query(new ByteBufferKaitaiStream(fileName));
+ }
+
+ public Query(KaitaiStream _io) {
+ this(_io, null, null);
+ }
+
+ public Query(KaitaiStream _io, DnsPacket _parent) {
+ this(_io, _parent, null);
+ }
+
+ public Query(KaitaiStream _io, DnsPacket _parent, DnsPacket _root) {
+ super(_io);
+ this._parent = _parent;
+ this._root = _root;
+ _read();
+ }
+ private void _read() {
+ this.name = new DomainName(this._io, this, _root);
+ this.type = DnsPacket.TypeType.byId(this._io.readU2be());
+ this.queryClass = DnsPacket.ClassType.byId(this._io.readU2be());
+ }
+ private DomainName name;
+ private TypeType type;
+ private ClassType queryClass;
+ private DnsPacket _root;
+ private DnsPacket _parent;
+ public DomainName name() { return name; }
+ public TypeType type() { return type; }
+ public ClassType queryClass() { return queryClass; }
+ public DnsPacket _root() { return _root; }
+ public DnsPacket _parent() { return _parent; }
+ }
+ public static class DomainName extends KaitaiStruct {
+ public static DomainName fromFile(String fileName) throws IOException {
+ return new DomainName(new ByteBufferKaitaiStream(fileName));
+ }
+
+ public DomainName(KaitaiStream _io) {
+ this(_io, null, null);
+ }
+
+ public DomainName(KaitaiStream _io, KaitaiStruct _parent) {
+ this(_io, _parent, null);
+ }
+
+ public DomainName(KaitaiStream _io, KaitaiStruct _parent, DnsPacket _root) {
+ super(_io);
+ this._parent = _parent;
+ this._root = _root;
+ _read();
+ }
+ private void _read() {
+ this.name = new ArrayList<Label>();
+ {
+ Label _it;
+ int i = 0;
+ do {
+ _it = new Label(this._io, this, _root);
+ this.name.add(_it);
+ i++;
+ } while (!( ((_it.length() == 0) || (_it.length() == 192)) ));
+ }
+ }
+ private ArrayList<Label> name;
+ private DnsPacket _root;
+ private KaitaiStruct _parent;
+
+ /**
+ * Repeat until the length is 0 or it is a pointer (bit-hack to get around lack of OR operator)
+ */
+ public ArrayList<Label> name() { return name; }
+ public DnsPacket _root() { return _root; }
+ public KaitaiStruct _parent() { return _parent; }
+ }
+ public static class Address extends KaitaiStruct {
+ public static Address fromFile(String fileName) throws IOException {
+ return new Address(new ByteBufferKaitaiStream(fileName));
+ }
+
+ public Address(KaitaiStream _io) {
+ this(_io, null, null);
+ }
+
+ public Address(KaitaiStream _io, DnsPacket.Answer _parent) {
+ this(_io, _parent, null);
+ }
+
+ public Address(KaitaiStream _io, DnsPacket.Answer _parent, DnsPacket _root) {
+ super(_io);
+ this._parent = _parent;
+ this._root = _root;
+ _read();
+ }
+ private void _read() {
+ ip = new ArrayList<Integer>((int) (4));
+ for (int i = 0; i < 4; i++) {
+ this.ip.add(this._io.readU1());
+ }
+ }
+ private ArrayList<Integer> ip;
+ private DnsPacket _root;
+ private DnsPacket.Answer _parent;
+ public ArrayList<Integer> ip() { return ip; }
+ public DnsPacket _root() { return _root; }
+ public DnsPacket.Answer _parent() { return _parent; }
+ }
+ public static class Answer extends KaitaiStruct {
+ public static Answer fromFile(String fileName) throws IOException {
+ return new Answer(new ByteBufferKaitaiStream(fileName));
+ }
+
+ public Answer(KaitaiStream _io) {
+ this(_io, null, null);
+ }
+
+ public Answer(KaitaiStream _io, DnsPacket _parent) {
+ this(_io, _parent, null);
+ }
+
+ public Answer(KaitaiStream _io, DnsPacket _parent, DnsPacket _root) {
+ super(_io);
+ this._parent = _parent;
+ this._root = _root;
+ _read();
+ }
+ private void _read() {
+ this.name = new DomainName(this._io, this, _root);
+ this.type = DnsPacket.TypeType.byId(this._io.readU2be());
+ this.answerClass = DnsPacket.ClassType.byId(this._io.readU2be());
+ this.ttl = this._io.readS4be();
+ this.rdlength = this._io.readU2be();
+ if (type() == DnsPacket.TypeType.PTR) {
+ this.ptrdname = new DomainName(this._io, this, _root);
+ }
+ if (type() == DnsPacket.TypeType.A) {
+ this.address = new Address(this._io, this, _root);
+ }
+ }
+ private DomainName name;
+ private TypeType type;
+ private ClassType answerClass;
+ private int ttl;
+ private int rdlength;
+ private DomainName ptrdname;
+ private Address address;
+ private DnsPacket _root;
+ private DnsPacket _parent;
+ public DomainName name() { return name; }
+ public TypeType type() { return type; }
+ public ClassType answerClass() { return answerClass; }
+
+ /**
+ * Time to live (in seconds)
+ */
+ public int ttl() { return ttl; }
+
+ /**
+ * Length in octets of the following payload
+ */
+ public int rdlength() { return rdlength; }
+ public DomainName ptrdname() { return ptrdname; }
+ public Address address() { return address; }
+ public DnsPacket _root() { return _root; }
+ public DnsPacket _parent() { return _parent; }
+ }
+ public static class PacketFlags extends KaitaiStruct {
+ public static PacketFlags fromFile(String fileName) throws IOException {
+ return new PacketFlags(new ByteBufferKaitaiStream(fileName));
+ }
+
+ public PacketFlags(KaitaiStream _io) {
+ this(_io, null, null);
+ }
+
+ public PacketFlags(KaitaiStream _io, DnsPacket _parent) {
+ this(_io, _parent, null);
+ }
+
+ public PacketFlags(KaitaiStream _io, DnsPacket _parent, DnsPacket _root) {
+ super(_io);
+ this._parent = _parent;
+ this._root = _root;
+ _read();
+ }
+ private void _read() {
+ this.flag = this._io.readU2be();
+ }
+ private Integer qr;
+ public Integer qr() {
+ if (this.qr != null)
+ return this.qr;
+ int _tmp = (int) (((flag() & 32768) >> 15));
+ this.qr = _tmp;
+ return this.qr;
+ }
+ private Integer ra;
+ public Integer ra() {
+ if (this.ra != null)
+ return this.ra;
+ int _tmp = (int) (((flag() & 128) >> 7));
+ this.ra = _tmp;
+ return this.ra;
+ }
+ private Integer tc;
+ public Integer tc() {
+ if (this.tc != null)
+ return this.tc;
+ int _tmp = (int) (((flag() & 512) >> 9));
+ this.tc = _tmp;
+ return this.tc;
+ }
+ private Integer rcode;
+ public Integer rcode() {
+ if (this.rcode != null)
+ return this.rcode;
+ int _tmp = (int) (((flag() & 15) >> 0));
+ this.rcode = _tmp;
+ return this.rcode;
+ }
+ private Integer opcode;
+ public Integer opcode() {
+ if (this.opcode != null)
+ return this.opcode;
+ int _tmp = (int) (((flag() & 30720) >> 11));
+ this.opcode = _tmp;
+ return this.opcode;
+ }
+ private Integer aa;
+ public Integer aa() {
+ if (this.aa != null)
+ return this.aa;
+ int _tmp = (int) (((flag() & 1024) >> 10));
+ this.aa = _tmp;
+ return this.aa;
+ }
+ private Integer z;
+ public Integer z() {
+ if (this.z != null)
+ return this.z;
+ int _tmp = (int) (((flag() & 64) >> 6));
+ this.z = _tmp;
+ return this.z;
+ }
+ private Integer rd;
+ public Integer rd() {
+ if (this.rd != null)
+ return this.rd;
+ int _tmp = (int) (((flag() & 256) >> 8));
+ this.rd = _tmp;
+ return this.rd;
+ }
+ private Integer cd;
+ public Integer cd() {
+ if (this.cd != null)
+ return this.cd;
+ int _tmp = (int) (((flag() & 16) >> 4));
+ this.cd = _tmp;
+ return this.cd;
+ }
+ private Integer ad;
+ public Integer ad() {
+ if (this.ad != null)
+ return this.ad;
+ int _tmp = (int) (((flag() & 32) >> 5));
+ this.ad = _tmp;
+ return this.ad;
+ }
+ private int flag;
+ private DnsPacket _root;
+ private DnsPacket _parent;
+ public int flag() { return flag; }
+ public DnsPacket _root() { return _root; }
+ public DnsPacket _parent() { return _parent; }
+ }
+ private int transactionId;
+ private PacketFlags flags;
+ private int qdcount;
+ private int ancount;
+ private int nscount;
+ private int arcount;
+ private ArrayList<Query> queries;
+ private ArrayList<Answer> answers;
+ private DnsPacket _root;
+ private KaitaiStruct _parent;
+
+ /**
+ * ID to keep track of request/responces
+ */
+ public int transactionId() { return transactionId; }
+ public PacketFlags flags() { return flags; }
+
+ /**
+ * How many questions are there
+ */
+ public int qdcount() { return qdcount; }
+
+ /**
+ * Number of resource records answering the question
+ */
+ public int ancount() { return ancount; }
+
+ /**
+ * Number of resource records pointing toward an authority
+ */
+ public int nscount() { return nscount; }
+
+ /**
+ * Number of resource records holding additional information
+ */
+ public int arcount() { return arcount; }
+ public ArrayList<Query> queries() { return queries; }
+ public ArrayList<Answer> answers() { return answers; }
+ public DnsPacket _root() { return _root; }
+ public KaitaiStruct _parent() { return _parent; }
+}
package edu.uci.iotproject;
+import io.kaitai.struct.ByteBufferKaitaiStream;
+import io.kaitai.struct.KaitaiStruct;
+import io.kaitai.struct.KaitaiStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.HashMap;
import java.util.Map;
/**
- * Entry point of the application.
+ * This is a system that reads PCAP files to compare
+ * patterns of DNS hostnames, packet sequences, and packet
+ * lengths with training data to determine certain events
+ * or actions for smart home devices.
*
* @author Janus Varmarken
+ * @author Rahmadi Trimananda (rtrimana@uci.edu)
+ * @version 0.1
*/
public class Main {
- private static int counter = 0;
- public static void main(String[] args) throws Exception {
+
+ /**
+ * Private class properties
+ */
+ private Pcap pcap;
+ private List<Pcap.Packet> listPacket;
+ private Map<String, List<byte[]>> mapHostnamesToIPAddresses;
+
+ /**
+ * Private class constants
+ */
+ private static final int DNS_PORT = 53;
+
+ /**
+ * Constructor
+ *
+ * @param file name of the analyzed PCAP file
+ */
+ public Main(String file) throws IOException {
+
+ pcap = Pcap.fromFile(file);
+ listPacket = pcap.packets();
+ mapHostnamesToIPAddresses = new HashMap<String, List<byte[]>>();
+ }
+
+
+ /**
+ * Private method that maps DNS hostnames to their
+ * respected IP addresses. This method iterates
+ * through the List<Pcap.Packet>, gets DNS packets,
+ * and gets the IP addresses associated with them.
+ */
+ private void mapHostnamesToIPAddresses() {
+
+ int counter = 1;
+ for(Pcap.Packet packet : listPacket) {
+ System.out.print("# " + counter++);
+ // Check the packet type
+ if (packet._root().hdr().network() == Pcap.Linktype.ETHERNET) {
+ EthernetFrame ethFrame = (EthernetFrame) packet.body();
+ if (ethFrame.etherType() == EthernetFrame.EtherTypeEnum.IPV4) {
+ Ipv4Packet ip4Packet = (Ipv4Packet) ethFrame.body();
+
+ System.out.print(" - Protocol: " + ip4Packet.protocol());
+
+ if (ip4Packet.protocol() == Ipv4Packet.ProtocolEnum.UDP) {
+ // DNS is UDP port 53
+ UdpDatagram udpData = (UdpDatagram) ip4Packet.body();
+ System.out.print(" - Source Port: " + udpData.srcPort());
+ System.out.print(" - Dest Port: " + udpData.dstPort());
+
+ // Source port 53 means this is DNS response
+ if (udpData.srcPort() == DNS_PORT) {
+ KaitaiStream dnsStream = new ByteBufferKaitaiStream(udpData.body());
+ DnsPacket dnsPacket = new DnsPacket(dnsStream);
+ ArrayList<DnsPacket.Answer> answers = dnsPacket.answers();
+ System.out.print(" - this DNS packet has " + answers.size() + " answers.");
+ }
+ }
+ }
+ }
+ System.out.println();
+ }
+ }
+
+ /*private String cloudIPAddress(String hostName) {
+ if (hostName.equals("events.tplinkra.com"))
+ return "205.251.203.26";
+ else
+ return null;
+ }*/
+
+ // TODO move to separate class
+ // Add parameter that is the trace to be analyzed (most like the pcap library's representation of a flow)
+ public String findPattern(Map<String, List<Integer>> hostnameToPacketLengths, String smartPlugIp) {
+
+ // No difference, output "Complete match"
+ // If difference, output <Packet no, deviation from expected> for each packet
+ return null;
+ }
+
+ public static void main(String[] args) {
System.out.println("it works");
//String file = "/scratch/traffic_measurements/Switches-Feb2018/wemo/wlan1/wlan1.setup.pcap";
String file = "/home/rtrimana/pcap_processing/smart_home_traffic/Code/Projects/SmartPlugDetector/pcap/wlan1.local.dns.pcap";
try {
- Pcap data = Pcap.fromFile(file);
- //data.hdr();
+ Main main = new Main(file);
+ main.mapHostnamesToIPAddresses();
+
+ /*Pcap data = Pcap.fromFile(file);
List<Pcap.Packet> listPacket = data.packets();
System.out.println("Number of packets: " + listPacket.size());
System.out.println("===================");
for(Pcap.Packet packet : listPacket) {
- System.out.print("#" + counter++ + "\n");
if (packet._root().hdr().network() == Pcap.Linktype.ETHERNET) {
EthernetFrame eFrame = (EthernetFrame) packet.body();
if (eFrame.etherType() == EthernetFrame.EtherTypeEnum.IPV4) {
}
}
}
- }
+ }*/
} catch (Exception e) {
e.printStackTrace();
}
}
-
- private String cloudIPAddress(String hostName) {
- if (hostName.equals("events.tplinkra.com"))
- return "205.251.203.26";
- else
- return null;
- }
-
- // TODO move to separate class
- // Add parameter that is the trace to be analyzed (most like the pcap library's representation of a flow)
- public String findPattern(Map<String, List<Integer>> hostnameToPacketLengths, String smartPlugIp) {
-
- // No difference, output "Complete match"
- // If difference, output <Packet no, deviation from expected> for each packet
- return null;
- }
}