X-Git-Url: http://plrg.eecs.uci.edu/git/?p=pingpong.git;a=blobdiff_plain;f=Code%2FProjects%2FSmartPlugDetector%2Fsrc%2Fmain%2Fjava%2Fedu%2Fuci%2Fiotproject%2Fanalysis%2FTcpConversationUtils.java;h=a4217ccbb821421e86c4a75789c96fe93eaeb056;hp=0db25e32737718a1d863f960040fe267ff2cd20a;hb=6647790f717c4e02d11d6f1bfbe847a83dd1f32f;hpb=f2d68ea45966e9905b3d0eb5c6958dd730f6c4f1
diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TcpConversationUtils.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TcpConversationUtils.java
index 0db25e3..a4217cc 100644
--- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TcpConversationUtils.java
+++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/TcpConversationUtils.java
@@ -1,6 +1,6 @@
package edu.uci.iotproject.analysis;
-import edu.uci.iotproject.Conversation;
+import edu.uci.iotproject.trafficreassembly.layer3.Conversation;
import edu.uci.iotproject.DnsMap;
import edu.uci.iotproject.util.PcapPacketUtils;
import org.pcap4j.core.PcapPacket;
@@ -21,6 +21,15 @@ import static edu.uci.iotproject.util.PcapPacketUtils.*;
*/
public class TcpConversationUtils {
+ /**
+ * Identifies the adjacency type of the signature for merging.
+ */
+ public enum SignaturePosition {
+ NOT_ADJACENT,
+ LEFT_ADJACENT,
+ RIGHT_ADJACENT
+ }
+
/**
*
* Given a {@link Conversation}, extract its set of "packet pairs", i.e., pairs of request-reply packets.
@@ -62,10 +71,10 @@ public class TcpConversationUtils {
// Helper method for implementing the public API of similarly named methods.
private static List extractPacketPairs(List packets) {
List pairs = new ArrayList<>();
- for(PcapPacket pp : packets) {
- System.out.print(pp.length() + " ");
- }
- System.out.println();
+// for(PcapPacket pp : packets) {
+// System.out.print(pp.length() + " ");
+// }
+// System.out.println();
int i = 0;
while (i < packets.size()) {
@@ -316,6 +325,22 @@ public class TcpConversationUtils {
return s.collect(Collectors.joining(" "));
}
+ /**
+ * Set of port numbers that we consider TLS traffic.
+ * Note: purposefully initialized as a {@link HashSet} to get O(1) {@code contains()} call.
+ */
+ private static final Set TLS_PORTS = Stream.of(443, 8443, 41143).
+ collect(Collectors.toCollection(HashSet::new));
+
+ /**
+ * Check if a given port number is considered a TLS port.
+ * @param port The port number to check.
+ * @return {@code true} if the port number is considered a TLS port, {@code false} otherwise.
+ */
+ public static boolean isTlsPort(int port) {
+ return TLS_PORTS.contains(port);
+ }
+
/**
* Appends a space to {@code sb} iff {@code sb} already contains some content.
* @param sb A {@link StringBuilder} that should have a space appended iff it is not empty.
@@ -325,4 +350,115 @@ public class TcpConversationUtils {
sb.append(" ");
}
}
+
+ /**
+ * Given a list of {@link Conversation} objects, sort them by timestamps.
+ * @param conversations The list of {@link Conversation} objects to be sorted.
+ * @return A sorted list of {@code Conversation} based on timestamps of the first
+ * packet in the {@code Conversation}.
+ */
+ public static List sortConversationList(List conversations) {
+ // Get rid of Conversation objects with no packets.
+ conversations.removeIf(x -> x.getPackets().size() == 0);
+ // Sort the list based on the first packet's timestamp!
+ Collections.sort(conversations, (c1, c2) ->
+ c1.getPackets().get(0).getTimestamp().compareTo(c2.getPackets().get(0).getTimestamp()));
+ return conversations;
+ }
+
+ /**
+ * Given a {@code List} of {@link Conversation} objects, find one that has the given {@code List}
+ * of {@code PcapPacket}.
+ * @param conversations The {@code List} of {@link Conversation} objects as reference.
+ * @param ppList The {@code List} of {@code PcapPacket} objects to search in the {@code List} of {@link Conversation}.
+ * @return A {@code Conversation} that contains the given {@code List} of {@code PcapPacket}.
+ */
+ public static Conversation returnConversation(List ppList, List conversations) {
+ // TODO: This part of comparison takes into account that the list of conversations is not sorted
+ // TODO: We could optimize this to have a better performance by requiring a sorted-by-timestamp list
+ // TODO: as a parameter
+ // Find a Conversation that ppList is part of
+ for (Conversation c : conversations) {
+ // Figure out if c is the Conversation that ppList is in
+ if (isPartOfConversation(ppList, c)) {
+ return c;
+ }
+ }
+ // Return null if not found
+ return null;
+ }
+
+ /**
+ * Given a {@link Conversation} objects, check if {@code List} of {@code PcapPacket} is part of it and return the
+ * adjacency label based on {@code SignaturePosition}.
+ * @param conversation The {@link Conversation} object as reference.
+ * @param ppListFirst The first {@code List} of {@code PcapPacket} objects in the {@link Conversation}.
+ * @param ppListSecond The second {@code List} of {@code PcapPacket} objects in the {@link Conversation} whose
+ * position will be observed in the {@link Conversation} with respect to ppListFirst.
+ * @return A {@code SignaturePosition} that represents the position of the signature against another signature
+ * in a {@link Conversation}.
+ */
+ public static SignaturePosition isPartOfConversationAndAdjacent(List ppListFirst,
+ List ppListSecond,
+ Conversation conversation) {
+ // Take the first element in ppList and compare it
+ // The following elements in ppList are guaranteed to be in the same Conversation
+ // TODO: This part of comparison takes into account that the list of conversations is not sorted
+ // TODO: We could optimize this to have a better performance by requiring a sorted-by-timestamp list
+ // TODO: as a parameter
+ if (isPartOfConversation(ppListSecond, conversation)) {
+ // Compare the first element of ppListSecond with the last element of ppListFirst to know
+ // whether ppListSecond is RIGHT_ADJACENT relative to ppListFirst.
+ PcapPacket lastElOfFirstList = ppListFirst.get(ppListFirst.size() - 1);
+ PcapPacket firstElOfSecondList = ppListSecond.get(0);
+ // If the positions of the two are in order, then they are adjacent.
+ int indexOfLastElOfFirstList = returnIndexInConversation(lastElOfFirstList, conversation);
+ int indexOfFirstElOfSecondList = returnIndexInConversation(firstElOfSecondList, conversation);
+ if(indexOfLastElOfFirstList + 1 == indexOfFirstElOfSecondList) {
+ return SignaturePosition.RIGHT_ADJACENT;
+ }
+ // NOT RIGHT_ADJACENT, so check for LEFT_ADJACENT.
+ // Compare the first element of ppListRight with the last element of ppListSecond to know
+ // whether ppListSecond is LEFT_ADJACENT relative to ppListFirst.
+ PcapPacket firstElOfFirstList = ppListFirst.get(0);
+ PcapPacket lastElOfSecondList = ppListSecond.get(ppListSecond.size() - 1);
+ // If the positions of the two are in order, then they are adjacent.
+ int indexOfFirstElOfFirstList = returnIndexInConversation(firstElOfFirstList, conversation);
+ int indexOfLastElOfSecondList = returnIndexInConversation(lastElOfSecondList, conversation);
+ if(indexOfLastElOfSecondList + 1 == indexOfFirstElOfFirstList) {
+ return SignaturePosition.LEFT_ADJACENT;
+ }
+ }
+ // Return NOT_ADJACENT if not found.
+ return SignaturePosition.NOT_ADJACENT;
+ }
+
+ /**
+ * Given a {@link Conversation} objects, check if {@code List} of {@code PcapPacket} is part of it.
+ * @param conversation The {@link Conversation} object as reference.
+ * @param ppList The {@code List} of {@code PcapPacket} objects to search in the {@link Conversation}.
+ * @return A {@code Boolean} value that represents the presence of the {@code List} of {@code PcapPacket} in
+ * the {@link Conversation}.
+ */
+ private static boolean isPartOfConversation(List ppList, Conversation conversation) {
+ // Find the first element of ppList in conversation.
+ if (conversation.getPackets().contains(ppList.get(0)))
+ return true;
+ // Return false if not found.
+ return false;
+ }
+
+ /**
+ * Given a {@link Conversation} objects, check the index of a {@code PcapPacket} in it.
+ * @param conversation The {@link Conversation} object as reference.
+ * @param pp The {@code PcapPacket} object to search in the {@link Conversation}.
+ * @return An {@code Integer} value that gives the index of the {@code PcapPacket} in the {@link Conversation}.
+ */
+ private static int returnIndexInConversation(PcapPacket pp, Conversation conversation) {
+ // Find pp in conversation.
+ if (conversation.getPackets().contains(pp))
+ return conversation.getPackets().indexOf(pp);
+ // Return -1 if not found.
+ return -1;
+ }
}