1 package edu.uci.iotproject;
3 import org.pcap4j.core.*;
4 import org.pcap4j.packet.*;
5 import org.pcap4j.packet.DnsPacket;
6 import org.pcap4j.packet.namednumber.DnsResourceRecordType;
8 import java.io.EOFException;
9 import java.net.InetAddress;
10 import java.net.UnknownHostException;
12 import java.util.concurrent.TimeoutException;
15 * TODO add class documentation.
16 * TODO: At this point, this class is still in transition to having multiple hostnames and lists of packets
18 * @author Janus Varmarken
20 public class FlowPattern {
25 private final String mPatternId;
26 private final String hostname; // The hostname that this {@code FlowPattern} is associated with.
29 * The order of packet lengths that defines this {@link FlowPattern}
30 * TODO: this is a simplified representation, we should also include information about direction of each packet.
32 private final List<Integer> flowPacketOrder;
33 private final Map<String, List<Integer>> mHostnameToPacketLengthsMap;
34 private final List<String> mHostnameList;
35 private final PcapHandle mPcap;
46 public FlowPattern(String mPatternId, String hostname, PcapHandle mPcap) {
47 this.mPatternId = mPatternId;
48 this.hostname = hostname;
49 this.mHostnameList = null;
51 this.mHostnameToPacketLengthsMap = null;
52 this.flowPacketOrder = new ArrayList<Integer>();
58 * Process the PcapHandle to strip off unnecessary packets and just get the integer array of packet lengths
60 private void processPcap() {
64 while ((packet = mPcap.getNextPacketEx()) != null) {
65 // For now, we only work support pattern search in TCP over IPv4.
66 IpV4Packet ipPacket = packet.get(IpV4Packet.class);
67 TcpPacket tcpPacket = packet.get(TcpPacket.class);
68 if (ipPacket == null || tcpPacket == null)
70 if (tcpPacket.getPayload() == null) // We skip non-payload control packets as these are less predictable
72 int packetLength = tcpPacket.getPayload().length();
73 flowPacketOrder.add(packetLength);
75 } catch (EOFException eofe) {
76 System.out.println("[ FlowPattern ] Finished processing a training PCAP stream!");
77 System.out.println("[ FlowPattern ] Pattern for " + mPatternId + ": " + Arrays.toString(flowPacketOrder.toArray()));
78 } catch (PcapNativeException |
80 NotOpenException ex) {
87 * Process the PcapHandle to strip off unnecessary packets.
88 * We then map list of hostnames to their respective arrays of packet lengths
90 private void processPcapToMap() {
95 Set<String> addressSet = new HashSet<>();
96 while ((packet = mPcap.getNextPacketEx()) != null) {
97 // For now, we only work support pattern search in TCP over IPv4.
98 IpV4Packet ipPacket = packet.get(IpV4Packet.class);
99 TcpPacket tcpPacket = packet.get(TcpPacket.class);
100 if (ipPacket == null || tcpPacket == null) {
103 if (tcpPacket.getPayload() == null) {
104 // We skip non-payload control packets as these are less predictable
107 // We assume that if it is not a local address then it is a cloud server address
108 InetAddress srcAddress = ipPacket.getHeader().getSrcAddr();
109 InetAddress dstAddress = ipPacket.getHeader().getDstAddr();
110 boolean fromServer = !srcAddress.isSiteLocalAddress();
111 boolean fromClient = !dstAddress.isSiteLocalAddress();
112 if (!fromServer && !fromClient) {
113 // Packet not related to pattern, skip it
116 // We relate and assume that this address is from our cloud server
117 String cloudAddress = null;
119 cloudAddress = dstAddress.getHostAddress();
120 } else { // fromServer
121 cloudAddress = srcAddress.getHostAddress();
123 //System.out.println("\nCloud address: " + cloudAddress);
124 if (!addressSet.contains(cloudAddress)) {
125 addressSet.add(cloudAddress);
129 String hostname = mHostnameList.get(hostIndex);
130 List<Integer> packetLengthsList = mHostnameToPacketLengthsMap.containsKey(hostname) ?
131 mHostnameToPacketLengthsMap.get(hostname) : new ArrayList<>();
132 int packetLength = tcpPacket.getPayload().length();
133 packetLengthsList.add(packetLength);
134 mHostnameToPacketLengthsMap.put(hostname, packetLengthsList);
137 } catch (EOFException eofe) {
138 System.out.println("[ FlowPattern ] Finished processing a training PCAP stream!");
139 System.out.println("[ FlowPattern ] Pattern for " + mPatternId + ": " + Arrays.toString(mHostnameToPacketLengthsMap.entrySet().toArray()));
140 } catch (PcapNativeException |
142 NotOpenException ex) {
143 ex.printStackTrace();
151 public FlowPattern(String mPatternId, List<String> mHostnameList, PcapHandle mPcap) {
152 this.mPatternId = mPatternId;
153 this.hostname = null;
154 this.mHostnameList = mHostnameList;
156 this.flowPacketOrder = null;
157 this.mHostnameToPacketLengthsMap = new HashMap<>();
162 public String getPatternId() {
167 public String getHostname() {
173 * Get the sequence of packet lengths that defines this {@code FlowPattern}.
174 * @return the sequence of packet lengths that defines this {@code FlowPattern}.
176 public List<Integer> getPacketOrder() {
177 return flowPacketOrder;
182 * Get the sequence of packet lengths based on input hostname.
183 * @return the sequence of packet lengths that defines this {@code FlowPattern}.
185 public List<Integer> getPacketOrder(String hostname) {
186 return mHostnameToPacketLengthsMap.get(hostname);
191 * Get the list of associated hostnames.
192 * @return the associated hostnames that define this {@code FlowPattern}.
194 public List<String> getHostnameList() {
195 return mHostnameList;
200 * Get the length of the List of {@code FlowPattern}.
201 * @return the length of the List of {@code FlowPattern}.
203 public int getLength() {
204 return flowPacketOrder.size();
209 * Get the length of the List of {@code FlowPattern}.
210 * @return the length of the List of {@code FlowPattern}.
212 public int getLength(String hostname) {
213 return mHostnameToPacketLengthsMap.get(hostname).size();