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; + } }