-// private static class PatternComparisonTask implements Runnable {
-//
-// private final Conversation mConversation;
-// private final FlowPattern mFlowPattern;
-//
-// private PatternComparisonTask(Conversation conversation, FlowPattern pattern) {
-// this.mConversation = conversation;
-// this.mFlowPattern = pattern;
-// }
-//
-// @Override
-// public void run() {
-// if(isCompleteMatch()) {
-// PcapPacket firstPacketInFlow = mConversation.getPackets().get(0);
-// System.out.println(
-// String.format("[ find ] Detected a complete match of pattern '%s' at %s!",
-// mFlowPattern.getPatternId(), firstPacketInFlow.getTimestamp().toString()));
-// }
-// }
-//
-// /**
-// * Compares the order of packet lengths present in {@link #mConversation} with those found in
-// * {@link #mFlowPattern}.
-// * @return {@code true} if the packet lengths matches pairwise for all indices, {@code false} otherwise.
-// */
-// private boolean isCompleteMatch() {
-// List<PcapPacket> convPackets = mConversation.getPackets();
-// if (convPackets.size() != mFlowPattern.getLength()) {
-// return false;
-// }
-// for (int i = 0; i < convPackets.size(); i++) {
-// TcpPacket tcpPacket = convPackets.get(i).get(TcpPacket.class);
-// if (tcpPacket.getPayload().length() != mFlowPattern.getPacketOrder().get(i)) {
-// return false;
-// }
-// }
-// return true;
-// }
-//
-// }
+ /**
+ * Find patterns based on the FlowPattern object (run by a thread)
+ */
+ private void findSignatureBasedOnTimestamp() {
+ try {
+ PcapPacket packet;
+// TODO: The new comparison method is pending
+// TODO: For now, just compare using one hostname and one list per FlowPattern
+ while ((packet = mPcap.getNextPacketEx()) != null) {
+ // Let DnsMap handle DNS packets.
+ if (packet.get(DnsPacket.class) != null) {
+ // Check if this is a valid DNS packet
+ mDnsMap.validateAndAddNewEntry(packet);
+ continue;
+ }
+ // For now, we only work support pattern search in TCP over IPv4.
+ final IpV4Packet ipPacket = packet.get(IpV4Packet.class);
+ final TcpPacket tcpPacket = packet.get(TcpPacket.class);
+ if (ipPacket == null || tcpPacket == null) {
+ continue;
+ }
+
+ String srcAddress = ipPacket.getHeader().getSrcAddr().getHostAddress();
+ String dstAddress = ipPacket.getHeader().getDstAddr().getHostAddress();
+ int srcPort = tcpPacket.getHeader().getSrcPort().valueAsInt();
+ int dstPort = tcpPacket.getHeader().getDstPort().valueAsInt();
+ //System.out.println("Timestamp packet: " + packet.getTimestamp());
+ // Is this packet related to the pattern; i.e. is it going to (or coming from) the cloud server?
+ boolean fromServer = mDnsMap.isRelatedToCloudServer(srcAddress, mPattern.getHostname());
+ boolean fromClient = mDnsMap.isRelatedToCloudServer(dstAddress, mPattern.getHostname());
+ if (!fromServer && !fromClient) {
+ // Packet not related to pattern, skip it.
+ continue;
+ }
+ // Record the conversation pairs
+ if (tcpPacket.getPayload() != null && checkTimeStamp(packet)) {
+ //if (tcpPacket.getPayload() != null) {
+ mConvPair.writeConversationPair(packet, fromClient, fromServer);
+ }
+ }
+ } catch (EOFException eofe) {
+ triggerListCounter = 0;
+ mConvPair.close();
+ System.out.println("[ findFlowPattern ] ConversationPair writer closed!");
+ System.out.println("[ findFlowPattern ] Frequencies of data points:");
+ mConvPair.printListFrequency();
+ } catch (UnknownHostException |
+ PcapNativeException |
+ NotOpenException |
+ TimeoutException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ private boolean checkTimeStamp(PcapPacket packet) {
+
+ // Extract time from the packet's timestamp
+ String timeStamp = packet.getTimestamp().toString();
+ String timeString = timeStamp.substring(timeStamp.indexOf("T") + 1, timeStamp.indexOf("."));
+ // Timestamps are in CET (ahead of PST) so it should be deducted by TIME_OFFSET
+ long time = timeToMillis(timeString, true) - TIME_OFFSET;
+ //long time = timeToMillis(timeString, true);
+
+ //System.out.println("Gets here: " + time + " trigger time: " + mTriggerTimes.get(triggerListCounter));
+
+ // We accept packets that are at most 3 seconds away from the trigger time
+ if ((mTriggerTimes.get(triggerListCounter) <= time) &&
+ (time <= mTriggerTimes.get(triggerListCounter) + 3000)) {
+ //System.out.println("Gets here 1: " + timeString + " index: " + triggerListCounter);
+ return true;
+ } else {
+ // Handle the case that the timestamp is > 3000, but < next timestamp
+ // in the list. We ignore these packets.
+ if (time < mTriggerTimes.get(triggerListCounter)) {
+ // Timestamp is smaller than trigger, ignore!
+ //System.out.println("Gets here 2: " + timeString + " index: " + triggerListCounter);
+ return false;
+ } else { // Timestamp is greater than trigger, increment!
+ triggerListCounter = triggerListCounter + 1;
+ //System.out.println("Gets here 3: " + timeString + " index: " + triggerListCounter);
+ //return false;
+ return checkTimeStamp(packet);
+ }
+ }
+
+ //System.out.println("Timestamp: " + timeToMillis(time, true));
+ //String time2 = "21:38:08";
+ //System.out.println("Timestamp: " + timeToMillis(time2, true));
+ }
+
+ /**
+ * A private function that returns time in milliseconds.
+ * @param time The time in the form of String.
+ * @param is24Hr If true, then this is in 24-hour format.
+ */
+ private long timeToMillis(String time, boolean is24Hr) {
+
+ String format = null;
+ if (is24Hr) {
+ format = "hh:mm:ss";
+ } else { // 12 Hr format
+ format = "hh:mm:ss aa";
+ }
+ DateFormat sdf = new SimpleDateFormat(format);
+ Date date = null;
+ try {
+ date = sdf.parse(time);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ if (date == null)
+ return 0;
+ return date.getTime();
+ }