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%2FMain.java;h=0f837b29f41ad193b827bee13768a84c610bf43b;hp=6dbd63b90bc605b619b1006310bfe2888c9815b2;hb=f314a6e02dad77f006f7acea08d3304569fc5ea9;hpb=26462c63738130dd6f7ef8b406b308c8d87abe6f 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 6dbd63b..0f837b2 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 @@ -8,6 +8,8 @@ import edu.uci.iotproject.comparison.seqalignment.SequenceAlignment; import edu.uci.iotproject.comparison.seqalignment.SequenceExtraction; import edu.uci.iotproject.io.TriggerTimesFileReader; import edu.uci.iotproject.util.PrintUtils; +import org.apache.commons.math3.stat.clustering.Cluster; +import org.apache.commons.math3.stat.clustering.DBSCANClusterer; import org.pcap4j.core.*; import org.pcap4j.packet.namednumber.DataLinkType; @@ -18,6 +20,8 @@ import java.net.UnknownHostException; import java.time.Instant; import java.util.*; import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * This is a system that reads PCAP files to compare @@ -37,8 +41,8 @@ public class Main { // ------------ # Code for extracting traffic generated by a device within x seconds of a trigger # ------------ // Paths to input and output files (consider supplying these as arguments instead) and IP of the device for // which traffic is to be extracted: - String path = "/scratch/July-2018"; // Rahmadi -// String path = "/Users/varmarken/temp/UCI IoT Project/experiments"; // Janus +// String path = "/scratch/July-2018"; // Rahmadi + String path = "/Users/varmarken/temp/UCI IoT Project/experiments"; // Janus boolean verbose = true; final String onPairsPath = "/scratch/July-2018/on.txt"; final String offPairsPath = "/scratch/July-2018/off.txt"; @@ -92,6 +96,7 @@ public class Main { // final String outputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock-processed.pcap"; // final String triggerTimesFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock-aug-6-2018.timestamps"; // final String deviceIp = "192.168.1.246"; // .246 == phone; .142 == SmartThings Hub (note: use eth0 capture for this!) + // September 12, 2018 - includes both wlan1 and eth1 interfaces //final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3.wlan1.local.pcap"; // final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3.eth1.local.pcap"; @@ -99,7 +104,6 @@ public class Main { // final String triggerTimesFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock-sept-12-2018.timestamps"; // final String deviceIp = "192.168.1.142"; // .246 == phone; .142 == SmartThings Hub (note: use eth0 capture for this!) - // 8) Hue Bulb August 7 experiment // final String inputPcapFile = path + "/2018-08/hue-bulb/hue-bulb.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-08/hue-bulb/hue-bulb-processed.pcap"; @@ -131,10 +135,10 @@ public class Main { // final String deviceIp = "192.168.1.246"; // .246 == phone; .229 == sprinkler // // 13) DLink siren August 14 experiment -// final String inputPcapFile = path + "/2018-08/dlink-siren/dlink-siren.wlan1.local.pcap"; -// final String outputPcapFile = path + "/2018-08/dlink-siren/dlink-siren-processed.pcap"; -// final String triggerTimesFile = path + "/2018-08/dlink-siren/dlink-siren-aug-14-2018.timestamps"; -// final String deviceIp = "192.168.1.183"; // .246 == phone; .183 == siren + final String inputPcapFile = path + "/2018-08/dlink-siren/dlink-siren.wlan1.local.pcap"; + final String outputPcapFile = path + "/2018-08/dlink-siren/dlink-siren-processed.pcap"; + final String triggerTimesFile = path + "/2018-08/dlink-siren/dlink-siren-aug-14-2018.timestamps"; + final String deviceIp = "192.168.1.183"; // .246 == phone; .183 == siren // 14) Nest thermostat August 15 experiment // final String inputPcapFile = path + "/2018-08/nest/nest.wlan1.local.pcap"; @@ -154,10 +158,10 @@ public class Main { // final String deviceIp = "192.168.1.225"; // .246 == phone; .225 == Alexa // September 17 - final String inputPcapFile = path + "/2018-08/noise/noise.eth1.pcap"; - final String outputPcapFile = path + "/2018-08/noise/noise-processed.pcap"; - final String triggerTimesFile = path + "/2018-08/noise/noise-sept-17-2018.timestamps"; - final String deviceIp = "192.168.1.142"; // .142 == SmartThings Hub; .199 == dlink plug; .183 == siren +// final String inputPcapFile = path + "/2018-08/noise/noise.eth1.pcap"; +// final String outputPcapFile = path + "/2018-08/noise/noise-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/noise/noise-sept-17-2018.timestamps"; +// final String deviceIp = "192.168.1.142"; // .142 == SmartThings Hub; .199 == dlink plug; .183 == siren TriggerTimesFileReader ttfr = new TriggerTimesFileReader(); List triggerTimes = ttfr.readTriggerTimes(triggerTimesFile, false); @@ -212,6 +216,12 @@ public class Main { + /* + * NOTE: no need to generate these more complex on/off maps that also contain mappings from hostname and + * sequence identifiers as we do not care about hostnames and sequences during clustering. + * We can simply use the UserAction->List map to generate ON/OFF groupings of conversations. + */ + /* // 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 @@ -230,8 +240,60 @@ public class Main { }); }); }); + */ + + // ================================================ CLUSTERING ================================================ + // Note: no need to use the more convoluted on/off maps; can simply use the UserAction->List map + // when don't care about hostnames and sequences (see comment earlier). + List onConversations = userActionToConversations.entrySet().stream(). + filter(e -> e.getKey().getType() == Type.TOGGLE_ON). // drop all OFF events from stream + map(e -> e.getValue()). // no longer interested in the UserActions + flatMap(List::stream). // flatten List> to a List + collect(Collectors.toList()); + List offConversations = userActionToConversations.entrySet().stream(). + filter(e -> e.getKey().getType() == Type.TOGGLE_OFF). + map(e -> e.getValue()). + flatMap(List::stream). + collect(Collectors.toList()); + List onPairs = onConversations.stream(). + map(c -> c.isTls() ? TcpConversationUtils.extractTlsAppDataPacketPairs(c) : + TcpConversationUtils.extractPacketPairs(c)). + flatMap(List::stream). // flatten List> to List<> + collect(Collectors.toList()); + List offPairs = offConversations.stream(). + map(c -> c.isTls() ? TcpConversationUtils.extractTlsAppDataPacketPairs(c) : + TcpConversationUtils.extractPacketPairs(c)). + flatMap(List::stream). // flatten List> to List<> + collect(Collectors.toList()); + // Note: need to update the DnsMap of all PcapPacketPairs if we want to use the IP/hostname-sensitive distance. + Stream.concat(Stream.of(onPairs), Stream.of(offPairs)).flatMap(List::stream).forEach(p -> p.setDnsMap(dnsMap)); + // Perform clustering on conversation logged as part of all ON events. + DBSCANClusterer onClusterer = new DBSCANClusterer<>(10.0, 5); + List> onClusters = onClusterer.cluster(onPairs); + // Perform clustering on conversation logged as part of all OFF events. + DBSCANClusterer offClusterer = new DBSCANClusterer<>(10.0, 5); + List> offClusters = offClusterer.cluster(offPairs); + // Output clusters + System.out.println("========================================"); + System.out.println(" Clustering results for ON "); + System.out.println(" Number of clusters: " + onClusters.size()); + int count = 0; + for (Cluster c : onClusters) { + System.out.println(String.format("<<< Cluster #%02d (%03d points) >>>", ++count, c.getPoints().size())); + System.out.print(PrintUtils.toSummaryString(c)); + } + System.out.println("========================================"); + System.out.println(" Clustering results for OFF "); + System.out.println(" Number of clusters: " + offClusters.size()); + count = 0; + for (Cluster c : offClusters) { + System.out.println(String.format("<<< Cluster #%03d (%06d points) >>>", ++count, c.getPoints().size())); + System.out.print(PrintUtils.toSummaryString(c)); + } + System.out.println("========================================"); + // ============================================================================================================ - + /* System.out.println("==== ON ===="); // Print out all the pairs into a file for ON events File fileOnEvents = new File(onPairsPath); @@ -301,7 +363,7 @@ public class Main { } } pwOff.close(); - + */ // // ================================================================================================ // // <<< Some work-in-progress/explorative code that extracts a "representative" sequence >>>