From 751c8761c7069d2ddb23866483c88cfd6fa47b28 Mon Sep 17 00:00:00 2001 From: Janus Varmarken Date: Fri, 3 Aug 2018 16:31:52 -0700 Subject: [PATCH] Added grouping of conversations by sequence identifeir --- .../main/java/edu/uci/iotproject/Main.java | 33 ++++++--------- .../analysis/TcpConversationUtils.java | 42 +++++++++++++++++++ 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java index f3885a7..3dedc2c 100644 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java @@ -126,32 +126,25 @@ public class Main { - - // ons - Map> ons = new HashMap<>(); - Map> offs = new HashMap<>(); - + // Contains all ON events: hostname -> sequence identifier -> list of conversations with that sequence + Map>> ons = new HashMap<>(); + // Contains all OFF events: hostname -> sequence identifier -> list of conversations with that sequence + Map>> offs = new HashMap<>(); userActionsToConvsByHostname.forEach((ua, hostnameToConvs) -> { - Map> outer = ua.getType() == Type.TOGGLE_ON ? ons : offs; + Map>> outer = ua.getType() == Type.TOGGLE_ON ? ons : offs; hostnameToConvs.forEach((host, convs) -> { - Map sequenceCounts = TcpConversationUtils.countPacketSequenceFrequencies(convs); - outer.merge(host, sequenceCounts, (existingMap, newMap) -> { - newMap.forEach((sequence, count) -> existingMap.merge(sequence, count, (i1, i2) -> i1+i2)); - return existingMap; + Map> seqsToConvs = TcpConversationUtils. + groupConversationsByPacketSequence(convs); + outer.merge(host, seqsToConvs, (oldMap, newMap) -> { + newMap.forEach((sequence, cs) -> oldMap.merge(sequence, cs, (list1, list2) -> { + list1.addAll(list2); + return list1; + })); + return oldMap; }); }); }); - -// for (Map.Entry newMapEntry : newMap.entrySet()) { -// if (existingMap.get(newMapEntry.getKey()) != null) { -// existingMap.put(newMapEntry.getKey(), existingMap.get(newMapEntry.getKey()) + newMapEntry.getValue()); -// } else { -// existingMap.put(newMapEntry.getKey(), newMapEntry.getValue()); -// } -// } -// return existingMap; - System.out.println(""); // ------------------------------------------------------------------------------------------------------------- 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 427d890..9c9af70 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 @@ -132,6 +132,48 @@ public class TcpConversationUtils { return result; } + /** + * Given a {@link Collection} of {@link Conversation}s, builds a {@link Map} from {@link String} to {@link List} + * of {@link Conversation}s such that each key is the concatenation of the packet lengths of all payload packets + * (i.e., the set of packets returned by {@link Conversation#getPackets()}) separated by a delimiter of any + * {@link Conversation} pointed to by that key. In other words, what the {@link Conversation}s {@code cs} pointed to + * by the key {@code s} have in common is that they all contain exactly the same number of payload packets and + * these payload packets are identical across all {@code Conversation}s in {@code convs} in terms of packet + * length and packet order. For example, if the key is "152 440 550", this means that every individual + * {@code Conversation} in the list of {@code Conversation}s pointed to by that key contain exactly three payload + * packet of lengths 152, 440, and 550, and these three packets are ordered the in the order prescribed by the key. + * + * @param conversations The collection of {@code Conversation}s to group by packet sequence. + * @return a {@link Map} from {@link String} to {@link List} of {@link Conversation}s such that each key is the + * concatenation of the packet lengths of all payload packets (i.e., the set of packets returned by + * {@link Conversation#getPackets()}) separated by a delimiter of any {@link Conversation} pointed to + * by that key. + */ + public static Map> groupConversationsByPacketSequence(Collection conversations) { + Map> result = new HashMap<>(); + for (Conversation conv : conversations) { + if (conv.getPackets().size() == 0) { + // Skip conversations with no payload packets. + continue; + } + StringBuilder sb = new StringBuilder(); + for (PcapPacket pp : conv.getPackets()) { + if (sb.length() != 0) { + // only add a space if there's preceding content + sb.append(" "); + } + sb.append(pp.length()); + } + List oneItemList = new ArrayList<>(); + oneItemList.add(conv); + result.merge(sb.toString(), oneItemList, (oldList, newList) -> { + oldList.addAll(newList); + return oldList; + }); + } + return result; + } + /** * Given a {@link Conversation}, counts the frequencies of each unique packet length seen as part of the * {@code Conversation}. -- 2.34.1