Few more tests in Main.java
[pingpong.git] / Code / Projects / SmartPlugDetector / src / main / java / edu / uci / iotproject / analysis / TcpConversationUtils.java
index ff7b4ad73326f80ea494ce176db44a58c4d439e7..9c9af7072fa35f5e7b51d3ad9621e98e90140027 100644 (file)
@@ -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 <em>concatenation of the packet lengths of all payload packets
+     * (i.e., the set of packets returned by {@link Conversation#getPackets()}) separated by a delimiter</em> 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 <em>and
+     * </em> 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
+     *         <em>concatenation of the packet lengths of all payload packets (i.e., the set of packets returned by
+     *         {@link Conversation#getPackets()}) separated by a delimiter</em> of any {@link Conversation} pointed to
+     *         by that key.
+     */
+    public static Map<String, List<Conversation>> groupConversationsByPacketSequence(Collection<Conversation> conversations) {
+        Map<String, List<Conversation>> 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<Conversation> 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}.
@@ -173,4 +215,17 @@ public class TcpConversationUtils {
         return result;
     }
 
+    public static Map<String, Map<String, Integer>> countPacketPairFrequenciesByHostname(Collection<Conversation> tcpConversations, DnsMap ipHostnameMappings) {
+        Map<String, List<Conversation>> convsByHostname = groupConversationsByHostname(tcpConversations, ipHostnameMappings);
+        HashMap<String, Map<String, Integer>> result = new HashMap<>();
+        for (Map.Entry<String, List<Conversation>> entry : convsByHostname.entrySet()) {
+            // Merge all packet pairs exchanged during the course of all conversations with hostname into one list
+            List<PcapPacketPair> allPairsExchangedWithHostname = new ArrayList<>();
+            entry.getValue().forEach(conversation -> allPairsExchangedWithHostname.addAll(extractPacketPairs(conversation)));
+            // Then count the frequencies of packet pairs exchanged with the hostname, irrespective of individual
+            // conversations
+            result.put(entry.getKey(), countPacketPairFrequencies(allPairsExchangedWithHostname));
+        }
+        return result;
+    }
 }