From 6647790f717c4e02d11d6f1bfbe847a83dd1f32f Mon Sep 17 00:00:00 2001 From: rtrimana Date: Fri, 18 Jan 2019 17:57:36 -0800 Subject: [PATCH 1/1] Adding sensitivity experiment. --- .../main/java/edu/uci/iotproject/Main.java | 618 +++++++++++++----- .../analysis/TcpConversationUtils.java | 8 +- .../detection/layer3/SignatureDetector.java | 12 +- .../uci/iotproject/util/PcapPacketUtils.java | 25 +- 4 files changed, 475 insertions(+), 188 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 0e5f420..12c3a2a 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 @@ -15,6 +15,7 @@ import org.pcap4j.packet.namednumber.DataLinkType; import java.io.EOFException; import java.net.UnknownHostException; +import java.time.Duration; import java.time.Instant; import java.util.*; import java.util.concurrent.TimeoutException; @@ -181,7 +182,7 @@ public class Main { // final String inputPcapFile = path + "/experimental_result/standalone/hue-bulb/wlan1/hue-bulb.wlan1.local.pcap"; // final String outputPcapFile = path + "/experimental_result/standalone/hue-bulb/wlan1/hue-bulb-processed.pcap"; // final String triggerTimesFile = path + "/experimental_result/standalone/hue-bulb/timestamps/hue-bulb-nov-19-2018.timestamps"; -// final String deviceIp = "192.168.1.100"; // .246 == phone; .100 == Hue hub +//// final String deviceIp = "192.168.1.100"; // .246 == phone; .100 == Hue hub // final String deviceIp = "192.168.1.246"; // .246 == phone; .100 == Hue hub // 9) Lifx Bulb August 8 experiment @@ -212,13 +213,13 @@ public class Main { // final String triggerTimesFile = path + "/2018-08/arlo-camera/arlo-camera-aug-10-2018.timestamps"; // final String deviceIp = "192.168.1.246"; // .246 == phone; .140 == camera // TODO: EXPERIMENT - November 13, 2018 - final String inputPcapFile = path + "/experimental_result/standalone/arlo-camera/wlan1/arlo-camera.wlan1.local.pcap"; - final String outputPcapFile = path + "/experimental_result/standalone/arlo-camera/wlan1/arlo-camera-processed.pcap"; -// final String inputPcapFile = path + "/experimental_result/standalone/arlo-camera/eth0/arlo-camera.eth1.local.pcap"; -// final String outputPcapFile = path + "/experimental_result/standalone/arlo-camera/eth0/arlo-camera-processed.pcap"; - final String triggerTimesFile = path + "/experimental_result/standalone/arlo-camera/timestamps/arlo-camera-nov-13-2018.timestamps"; -// final String deviceIp = "192.168.1.140"; // .246 == phone; .140 == camera - final String deviceIp = "192.168.1.246"; // .246 == phone; .140 == camera +// final String inputPcapFile = path + "/experimental_result/standalone/arlo-camera/wlan1/arlo-camera.wlan1.local.pcap"; +// final String outputPcapFile = path + "/experimental_result/standalone/arlo-camera/wlan1/arlo-camera-processed.pcap"; +//// final String inputPcapFile = path + "/experimental_result/standalone/arlo-camera/eth0/arlo-camera.eth1.local.pcap"; +//// final String outputPcapFile = path + "/experimental_result/standalone/arlo-camera/eth0/arlo-camera-processed.pcap"; +// final String triggerTimesFile = path + "/experimental_result/standalone/arlo-camera/timestamps/arlo-camera-nov-13-2018.timestamps"; +//// final String deviceIp = "192.168.1.140"; // .246 == phone; .140 == camera +// final String deviceIp = "192.168.1.246"; // .246 == phone; .140 == camera // 12) Blossom sprinkler August 13 experiment // final String inputPcapFile = path + "/2018-08/blossom/blossom.wlan1.local.pcap"; @@ -236,6 +237,7 @@ public class Main { // final String triggerTimesFile = path + "/experimental_result/standalone/blossom-sprinkler/timestamps/blossom-sprinkler-standalone-jan-14-2019.timestamps"; //// final String triggerTimesFile = path + "/experimental_result/standalone/blossom-sprinkler/timestamps/blossom-sprinkler-standalone-jan-11-2019.timestamps"; // final String deviceIp = "192.168.1.246"; // .246 == phone; .229 == sprinkler +//// final String deviceIp = "192.168.1.229"; // .246 == phone; .229 == sprinkler // // 13) DLink siren August 14 experiment // final String inputPcapFile = path + "/2018-08/dlink-siren/dlink-siren.wlan1.local.pcap"; @@ -249,15 +251,15 @@ public class Main { // final String inputPcapFile = path + "/experimental_result/standalone/dlink-siren/wlan1/dlink-siren.wlan1.local.pcap"; // final String outputPcapFile = path + "/experimental_result/standalone/dlink-siren/wlan1/dlink-siren-processed.pcap"; // final String triggerTimesFile = path + "/experimental_result/standalone/dlink-siren/timestamps/dlink-siren-nov-9-2018.timestamps"; -// final String deviceIp = "192.168.1.183"; // .246 == phone; .183 == siren -//// final String deviceIp = "192.168.1.246"; // .246 == phone; .183 == siren +//// final String deviceIp = "192.168.1.183"; // .246 == phone; .183 == siren +// final String deviceIp = "192.168.1.246"; // .246 == phone; .183 == siren // 14) Nest thermostat August 15 experiment // final String inputPcapFile = path + "/2018-08/nest/nest.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-08/nest/nest-processed.pcap"; // final String triggerTimesFile = path + "/2018-08/nest/nest-aug-15-2018.timestamps"; // final String deviceIp = "192.168.1.246"; // .246 == phone; .127 == Nest thermostat - // TODO: EXPERIMENT - November 14, 2018 +// // TODO: EXPERIMENT - November 14, 2018 // final String inputPcapFile = path + "/experimental_result/standalone/nest-thermostat/wlan1/nest-thermostat.wlan1.local.pcap"; // final String outputPcapFile = path + "/experimental_result/standalone/nest-thermostat/wlan1/nest-thermostat-processed.pcap"; //// final String inputPcapFile = path + "/experimental_result/standalone/nest-thermostat/eth0/nest-thermostat.eth1.local.pcap"; @@ -293,56 +295,250 @@ public class Main { // final String triggerTimesFile = path + "/2018-08/noise/kwikset-doorlock-noise-sept-27-2018.timestamps"; // final String deviceIp = "192.168.1.142"; // .142 == SmartThings Hub; + // TODO: The below part is just for 15-second time sensitivity experiment + // TODO: The below part is just for 15-second time sensitivity experiment + // TODO: The below part is just for 15-second time sensitivity experiment + // D-Link plug +// final String triggerTimesFile = path + "/experimental_result/standalone/dlink-plug/timestamps/dlink-plug-nov-7-2018.timestamps"; +//// final String onSignatureFile = path + "/experimental_result/standalone/dlink-plug/signatures/dlink-plug-onSignature-phone-side.sig"; +//// final String offSignatureFile = path + "/experimental_result/standalone/dlink-plug/signatures/dlink-plug-offSignature-phone-side.sig"; +// final String onSignatureFile = path + "/experimental_result/standalone/dlink-plug/signatures/dlink-plug-onSignature-device-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/dlink-plug/signatures/dlink-plug-offSignature-device-side.sig"; + // TP-Link plug +// final String triggerTimesFile = path + "/experimental_result/standalone/tplink-plug/timestamps/tplink-plug-nov-8-2018.timestamps"; +//// final String onSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-onSignature-phone-side.sig"; +//// final String offSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-offSignature-phone-side.sig"; +// final String onSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-onSignature-device-side-outbound.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/tplink-plug/signatures/tplink-plug-offSignature-device-side-outbound.sig"; + // D-Link siren +// final String triggerTimesFile = path + "/experimental_result/standalone/dlink-siren/timestamps/dlink-siren-nov-9-2018.timestamps"; +// final String onSignatureFile = path + "/experimental_result/standalone/dlink-siren/signatures/dlink-siren-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/dlink-siren/signatures/dlink-siren-offSignature-phone-side.sig"; + // Kwikset door lock +// final String triggerTimesFile = path + "/experimental_result/standalone/kwikset-doorlock/timestamps/kwikset-doorlock-nov-10-2018.timestamps"; +// final String onSignatureFile = path + "/experimental_result/standalone/kwikset-doorlock/signatures/kwikset-doorlock-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/kwikset-doorlock/signatures/kwikset-doorlock-offSignature-phone-side.sig"; + // SmartThings plug +// final String triggerTimesFile = path + "/experimental_result/standalone/st-plug/timestamps/st-plug-nov-12-2018.timestamps"; +// final String onSignatureFile = path + "/experimental_result/standalone/st-plug/signatures/st-plug-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/st-plug/signatures/st-plug-offSignature-phone-side.sig"; + // Arlo Q +// final String triggerTimesFile = path + "/experimental_result/standalone/arlo-camera/timestamps/arlo-camera-nov-13-2018.timestamps"; +// final String onSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/arlo-camera/signatures/arlo-camera-offSignature-phone-side.sig"; + // Nest thermostat +// final String triggerTimesFile = path + "/experimental_result/standalone/nest-thermostat/timestamps/nest-thermostat-nov-15-2018.timestamps"; +// final String onSignatureFile = path + "/experimental_result/standalone/nest-thermostat/signatures/nest-thermostat-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/nest-thermostat/signatures/nest-thermostat-offSignature-phone-side.sig"; + // Blossom sprinkler +// final String triggerTimesFile = path + "/experimental_result/standalone/blossom-sprinkler/timestamps/blossom-sprinkler-standalone-jan-14-2019.timestamps"; +// final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-device-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-device-side.sig"; +// final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-phone-side.sig"; + // TP-Link bulb +// final String triggerTimesFile = path + "/experimental_result/standalone/tplink-bulb/timestamps/tplink-bulb-nov-16-2018.timestamps"; +// final String onSignatureFile = path + "/experimental_result/standalone/tplink-bulb/signatures/tplink-bulb-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/tplink-bulb/signatures/tplink-bulb-offSignature-phone-side.sig"; + // Philips hue +// final String triggerTimesFile = path + "/2018-08/hue-bulb/hue-bulb-aug-7-2018.timestamps"; +// final String onSignatureFile = path + "/training/hue-bulb/signatures/hue-bulb-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/training/hue-bulb/signatures/hue-bulb-offSignature-phone-side.sig"; + // WeMo plug +// final String triggerTimesFile = path + "/experimental_result/standalone/wemo-plug/timestamps/wemo-plug-nov-20-2018.timestamps"; +// final String onSignatureFile = path + "/experimental_result/standalone/wemo-plug/signatures/wemo-plug-onSignature-phone-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/wemo-plug/signatures/wemo-plug-offSignature-phone-side.sig"; + // WeMo Insight plug + final String triggerTimesFile = path + "/experimental_result/standalone/wemo-insight-plug/timestamps/wemo-insight-plug-nov-21-2018.timestamps"; + final String onSignatureFile = path + "/experimental_result/standalone/wemo-insight-plug/signatures/wemo-insight-plug-onSignature-phone-side.sig"; + final String offSignatureFile = path + "/experimental_result/standalone/wemo-insight-plug/signatures/wemo-insight-plug-offSignature-phone-side.sig"; + + TriggerTimesFileReader ttfr = new TriggerTimesFileReader(); List triggerTimes = ttfr.readTriggerTimes(triggerTimesFile, false); - // Tag each trigger with "ON" or "OFF", assuming that the first trigger is an "ON" and that they alternate. - List userActions = new ArrayList<>(); - for (int i = 0; i < triggerTimes.size(); i++) { - userActions.add(new UserAction(i % 2 == 0 ? Type.TOGGLE_ON : Type.TOGGLE_OFF, triggerTimes.get(i))); + + System.out.println("ON signature file in use is " + onSignatureFile); + System.out.println("OFF signature file in use is " + offSignatureFile); + + List>> onSignature = PrintUtils.deserializeSignatureFromFile(onSignatureFile); + List>> offSignature = PrintUtils.deserializeSignatureFromFile(offSignatureFile); + + List signatureTimestamps = new ArrayList<>(); + // Load ON signature last packet's timestamp + // Get the last only + List> lastListOn = onSignature.get(onSignature.size()-1); + for (List list : lastListOn) { + // Get timestamp Instant from the last packet + int lastPacketIndex = list.size()-1; + signatureTimestamps.add(list.get(lastPacketIndex).getTimestamp()); + } + // Load OFF signature last packet's timestamp + // Get the last only + List> lastListOff = offSignature.get(offSignature.size()-1); + for (List list : lastListOff) { + // Get timestamp Instant from the last packet + int lastPacketIndex = list.size()-1; + signatureTimestamps.add(list.get(lastPacketIndex).getTimestamp()); + } + // Sort the timestamps + signatureTimestamps.sort((p1, p2) -> { + return p1.compareTo(p2); + }); + + Iterator iterTrig = triggerTimes.iterator(); + Iterator iterSign = signatureTimestamps.iterator(); + System.out.println("Trigger to Last Packet:"); + while (iterTrig.hasNext() && iterSign.hasNext()) { + Instant trigInst = (Instant) iterTrig.next(); + Instant signInst = (Instant) iterSign.next(); + Duration dur = Duration.between(trigInst, signInst); + long duration = dur.toMillis(); + // Check duration --- should be below 15 seconds + if (duration >= 0 && duration <= 15000) { + System.out.println(dur.toMillis()); + } else if (duration > 15000) { + while (duration > 15000) { // that means we have to move to the next trigger + trigInst = (Instant) iterTrig.next(); + dur = Duration.between(trigInst, signInst); + duration = dur.toMillis(); + } + System.out.println(dur.toMillis()); + } else { // below 0 / negative --- that means we have to move to the next signature + while (duration < 0) { // that means we have to move to the next trigger + signInst = (Instant) iterSign.next(); + dur = Duration.between(trigInst, signInst); + duration = dur.toMillis(); + } + System.out.println(dur.toMillis()); + } + } + + + // ========================================================================== + List firstSignatureTimestamps = new ArrayList<>(); + List lastSignatureTimestamps = new ArrayList<>(); + List> firstListOnSign = onSignature.get(0); + List> lastListOnSign = onSignature.get(onSignature.size()-1); + // Load ON signature first and last packet's timestamps + for (List list : firstListOnSign) { + // Get timestamp Instant from the last packet + firstSignatureTimestamps.add(list.get(0).getTimestamp()); + } + for (List list : lastListOnSign) { + // Get timestamp Instant from the last packet + int lastPacketIndex = list.size()-1; + lastSignatureTimestamps.add(list.get(lastPacketIndex).getTimestamp()); + } + + List> firstListOffSign = offSignature.get(0); + List> lastListOffSign = offSignature.get(offSignature.size()-1); + // Load OFF signature first and last packet's timestamps + for (List list : firstListOffSign) { + // Get timestamp Instant from the last packet + firstSignatureTimestamps.add(list.get(0).getTimestamp()); } - TriggerTrafficExtractor tte = new TriggerTrafficExtractor(inputPcapFile, triggerTimes, deviceIp); - final PcapDumper outputter = Pcaps.openDead(DataLinkType.EN10MB, 65536).dumpOpen(outputPcapFile); - DnsMap dnsMap = new DnsMap(); - TcpReassembler tcpReassembler = new TcpReassembler(); - TrafficLabeler trafficLabeler = new TrafficLabeler(userActions); - tte.performExtraction(pkt -> { - try { - outputter.dump(pkt); - } catch (NotOpenException e) { - e.printStackTrace(); + for (List list : lastListOffSign) { + // Get timestamp Instant from the last packet + int lastPacketIndex = list.size()-1; + lastSignatureTimestamps.add(list.get(lastPacketIndex).getTimestamp()); + } + // Sort the timestamps + firstSignatureTimestamps.sort((p1, p2) -> { + return p1.compareTo(p2); + }); + // Sort the timestamps + lastSignatureTimestamps.sort((p1, p2) -> { + return p1.compareTo(p2); + }); + + Iterator iterFirst = firstSignatureTimestamps.iterator(); + Iterator iterLast = lastSignatureTimestamps.iterator(); + System.out.println("First to Last Packet:"); + while (iterFirst.hasNext() && iterLast.hasNext()) { + Instant firstInst = (Instant) iterFirst.next(); + Instant lastInst = (Instant) iterLast.next(); + Duration dur = Duration.between(firstInst, lastInst); + long duration = dur.toMillis(); + // Check duration --- should be below 15 seconds + if (duration >= 0 && duration <= 15000) { + System.out.println(dur.toMillis()); + } else if (duration > 15000) { + while (duration > 15000) { // that means we have to move to the next trigger + firstInst = (Instant) iterFirst.next(); + dur = Duration.between(firstInst, lastInst); + duration = dur.toMillis(); + } + System.out.println(dur.toMillis()); + } else { // below 0 / negative --- that means we have to move to the next signature + while (duration < 0) { // that means we have to move to the next trigger + lastInst = (Instant) iterLast.next(); + dur = Duration.between(firstInst, lastInst); + duration = dur.toMillis(); + } + System.out.println(dur.toMillis()); + } + if (duration > 8000) { + break; } - }, dnsMap, tcpReassembler, trafficLabeler); - outputter.flush(); - outputter.close(); - - if (tte.getPacketsIncludedCount() != trafficLabeler.getTotalPacketCount()) { - // Sanity/debug check - throw new AssertionError(String.format("mismatch between packet count in %s and %s", - TriggerTrafficExtractor.class.getSimpleName(), TrafficLabeler.class.getSimpleName())); } - // Extract all conversations present in the filtered trace. - List allConversations = tcpReassembler.getTcpConversations(); - // Group conversations by hostname. - Map> convsByHostname = TcpConversationUtils.groupConversationsByHostname(allConversations, dnsMap); - System.out.println("Grouped conversations by hostname."); - // For each hostname, count the frequencies of packet lengths exchanged with that hostname. - final Map> pktLenFreqsByHostname = new HashMap<>(); - convsByHostname.forEach((host, convs) -> pktLenFreqsByHostname.put(host, TcpConversationUtils.countPacketLengthFrequencies(convs))); - System.out.println("Counted frequencies of packet lengths exchanged with each hostname."); - // For each hostname, count the frequencies of packet sequences (i.e., count how many conversations exchange a - // sequence of packets of some specific lengths). - final Map> pktSeqFreqsByHostname = new HashMap<>(); - convsByHostname.forEach((host, convs) -> pktSeqFreqsByHostname.put(host, TcpConversationUtils.countPacketSequenceFrequencies(convs))); - System.out.println("Counted frequencies of packet sequences exchanged with each hostname."); - // For each hostname, count frequencies of packet pairs exchanged with that hostname across all conversations - final Map> pktPairFreqsByHostname = - TcpConversationUtils.countPacketPairFrequenciesByHostname(allConversations, dnsMap); - System.out.println("Counted frequencies of packet pairs per hostname"); - // For each user action, reassemble the set of TCP connections occurring shortly after - final Map> userActionToConversations = trafficLabeler.getLabeledReassembledTcpTraffic(); - final Map>> userActionsToConvsByHostname = trafficLabeler.getLabeledReassembledTcpTraffic(dnsMap); - System.out.println("Reassembled TCP conversations occurring shortly after each user event"); + // TODO: The above part is just for 15-second time sensitivity experiment + // TODO: The above part is just for 15-second time sensitivity experiment + // TODO: The above part is just for 15-second time sensitivity experiment + + + + +// TriggerTimesFileReader ttfr = new TriggerTimesFileReader(); +// List triggerTimes = ttfr.readTriggerTimes(triggerTimesFile, false); +// // Tag each trigger with "ON" or "OFF", assuming that the first trigger is an "ON" and that they alternate. +// List userActions = new ArrayList<>(); +// for (int i = 0; i < triggerTimes.size(); i++) { +// userActions.add(new UserAction(i % 2 == 0 ? Type.TOGGLE_ON : Type.TOGGLE_OFF, triggerTimes.get(i))); +// } +// TriggerTrafficExtractor tte = new TriggerTrafficExtractor(inputPcapFile, triggerTimes, deviceIp); +// final PcapDumper outputter = Pcaps.openDead(DataLinkType.EN10MB, 65536).dumpOpen(outputPcapFile); +// DnsMap dnsMap = new DnsMap(); +// TcpReassembler tcpReassembler = new TcpReassembler(); +// TrafficLabeler trafficLabeler = new TrafficLabeler(userActions); +// tte.performExtraction(pkt -> { +// try { +// outputter.dump(pkt); +// } catch (NotOpenException e) { +// e.printStackTrace(); +// } +// }, dnsMap, tcpReassembler, trafficLabeler); +// outputter.flush(); +// outputter.close(); +// +// if (tte.getPacketsIncludedCount() != trafficLabeler.getTotalPacketCount()) { +// // Sanity/debug check +// throw new AssertionError(String.format("mismatch between packet count in %s and %s", +// TriggerTrafficExtractor.class.getSimpleName(), TrafficLabeler.class.getSimpleName())); +// } +// +// // Extract all conversations present in the filtered trace. +// List allConversations = tcpReassembler.getTcpConversations(); +// // Group conversations by hostname. +// Map> convsByHostname = TcpConversationUtils.groupConversationsByHostname(allConversations, dnsMap); +// System.out.println("Grouped conversations by hostname."); +// // For each hostname, count the frequencies of packet lengths exchanged with that hostname. +// final Map> pktLenFreqsByHostname = new HashMap<>(); +// convsByHostname.forEach((host, convs) -> pktLenFreqsByHostname.put(host, TcpConversationUtils.countPacketLengthFrequencies(convs))); +// System.out.println("Counted frequencies of packet lengths exchanged with each hostname."); +// // For each hostname, count the frequencies of packet sequences (i.e., count how many conversations exchange a +// // sequence of packets of some specific lengths). +// final Map> pktSeqFreqsByHostname = new HashMap<>(); +// convsByHostname.forEach((host, convs) -> pktSeqFreqsByHostname.put(host, TcpConversationUtils.countPacketSequenceFrequencies(convs))); +// System.out.println("Counted frequencies of packet sequences exchanged with each hostname."); +// // For each hostname, count frequencies of packet pairs exchanged with that hostname across all conversations +// final Map> pktPairFreqsByHostname = +// TcpConversationUtils.countPacketPairFrequenciesByHostname(allConversations, dnsMap); +// System.out.println("Counted frequencies of packet pairs per hostname"); +// // For each user action, reassemble the set of TCP connections occurring shortly after +// final Map> userActionToConversations = trafficLabeler.getLabeledReassembledTcpTraffic(); +// final Map>> userActionsToConvsByHostname = trafficLabeler.getLabeledReassembledTcpTraffic(dnsMap); +// System.out.println("Reassembled TCP conversations occurring shortly after each user event"); @@ -445,123 +641,205 @@ 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()); - //Collections.sort(onConversations, (c1, c2) -> c1.getPackets().) - - 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, 45); - //DBSCANClusterer onClusterer = new DBSCANClusterer<>(3, 45); - //DBSCANClusterer onClusterer = new DBSCANClusterer<>(10.0, 10); - List> onClusters = onClusterer.cluster(onPairs); - // Perform clustering on conversation logged as part of all OFF events. - DBSCANClusterer offClusterer = new DBSCANClusterer<>(10.0, 45); - //DBSCANClusterer offClusterer = new DBSCANClusterer<>(3, 45); - //DBSCANClusterer offClusterer = new DBSCANClusterer<>(10.0, 10); - List> offClusters = offClusterer.cluster(offPairs); - // Sort the conversations as reference - List sortedAllConversation = TcpConversationUtils.sortConversationList(allConversations); - // Output clusters - System.out.println("========================================"); - System.out.println(" Clustering results for ON "); - System.out.println(" Number of clusters: " + onClusters.size()); - int count = 0; - List>> ppListOfListReadOn = new ArrayList<>(); - List>> ppListOfListListOn = new ArrayList<>(); - for (Cluster c : onClusters) { - System.out.println(String.format("<<< Cluster #%02d (%03d points) >>>", ++count, c.getPoints().size())); - System.out.print(PrintUtils.toSummaryString(c)); - if(c.getPoints().size() > 45 && c.getPoints().size() < 55) { - //if(c.getPoints().size() > 25) { - // Print to file - List> ppListOfList = PcapPacketUtils.clusterToListOfPcapPackets(c); - ppListOfListListOn.add(ppListOfList); - } - } - // TODO: Merging test - ppListOfListListOn = PcapPacketUtils.mergeSignatures(ppListOfListListOn, sortedAllConversation); - // TODO: Need to remove sequence 550 567 for Blossom phone side since it is not a good signature (overlap)! -// PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 1); - // TODO: Need to remove sequence 69 296 for Blossom device side since it is not a good signature (overlap)! -// PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 2); - // TODO: Need to remove sequence number 2 for ST plug since it is not a good signature! - //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 2); - // TODO: Need to remove sequence number 0 for Arlo Camera since it is not a good signature! - //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 0); - // TODO: Need to remove sequence number 0 for TP-Link plug since it is not a good signature! - // TODO: This sequence actually belongs to the local communication between the plug and the phone - //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 0); - ppListOfListListOn = PcapPacketUtils.sortSignatures(ppListOfListListOn); - PcapPacketUtils.printSignatures(ppListOfListListOn); - //count = 0; - /*for (List> ll : ppListOfListListOn) { - PrintUtils.serializeClustersIntoFile("./onSignature" + ++count + ".sig", ll); - ppListOfListReadOn.add(PrintUtils.deserializeClustersFromFile("./onSignature" + count + ".sig")); - }*/ - PrintUtils.serializeSignatureIntoFile("./onSignature.sig", ppListOfListListOn); - ppListOfListReadOn = PrintUtils.deserializeSignatureFromFile("./onSignature.sig"); - - System.out.println("========================================"); - System.out.println(" Clustering results for OFF "); - System.out.println(" Number of clusters: " + offClusters.size()); - count = 0; - List>> ppListOfListReadOff = new ArrayList<>(); - List>> ppListOfListListOff = new ArrayList<>(); - for (Cluster c : offClusters) { - System.out.println(String.format("<<< Cluster #%03d (%06d points) >>>", ++count, c.getPoints().size())); - System.out.print(PrintUtils.toSummaryString(c)); - if(c.getPoints().size() > 45 && c.getPoints().size() < 55) { - //if(c.getPoints().size() > 25) { - // Print to file - List> ppListOfList = PcapPacketUtils.clusterToListOfPcapPackets(c); - ppListOfListListOff.add(ppListOfList); - } - } - // TODO: Merging test - ppListOfListListOff = PcapPacketUtils.mergeSignatures(ppListOfListListOff, sortedAllConversation); - // TODO: Need to remove sequence 69 296 for Blossom device side since it is not a good signature (overlap)! -// PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 3); - // TODO: Need to remove sequence number 1 for Nest Thermostat since it is not a good signature! - //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 1); - // TODO: Need to remove sequence number 0 for Arlo Camera since it is not a good signature! - PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 1); - // TODO: Need to remove sequence number 2 for ST plug since it is not a good signature! - //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 2); - // TODO: Need to remove sequence number 0 for TP-Link plug since it is not a good signature! - // TODO: This sequence actually belongs to the local communication between the plug and the phone - //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 0); - ppListOfListListOff = PcapPacketUtils.sortSignatures(ppListOfListListOff); - PcapPacketUtils.printSignatures(ppListOfListListOff); - //count = 0; - /*for (List> ll : ppListOfListListOff) { - PrintUtils.serializeClustersIntoFile("./offSignature" + ++count + ".sig", ll); - ppListOfListReadOff.add(PrintUtils.deserializeClustersFromFile("./offSignature" + count + ".sig")); - }*/ - PrintUtils.serializeSignatureIntoFile("./offSignature.sig", ppListOfListListOff); - ppListOfListReadOff = PrintUtils.deserializeSignatureFromFile("./offSignature.sig"); - System.out.println("========================================"); +// 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()); +// //Collections.sort(onConversations, (c1, c2) -> c1.getPackets().) +// +// 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, 45); +// DBSCANClusterer onClusterer = new DBSCANClusterer<>(2, 2); +// //DBSCANClusterer onClusterer = new DBSCANClusterer<>(10.0, 10); +// List> onClusters = onClusterer.cluster(onPairs); +// // Perform clustering on conversation logged as part of all OFF events. +//// DBSCANClusterer offClusterer = new DBSCANClusterer<>(10.0, 45); +// DBSCANClusterer offClusterer = new DBSCANClusterer<>(2, 2); +// //DBSCANClusterer offClusterer = new DBSCANClusterer<>(10.0, 10); +// List> offClusters = offClusterer.cluster(offPairs); +// // Sort the conversations as reference +// List sortedAllConversation = TcpConversationUtils.sortConversationList(allConversations); +// // Output clusters +// System.out.println("========================================"); +// System.out.println(" Clustering results for ON "); +// System.out.println(" Number of clusters: " + onClusters.size()); +// int count = 0; +// List>> ppListOfListReadOn = new ArrayList<>(); +// List>> ppListOfListListOn = new ArrayList<>(); +// for (Cluster c : onClusters) { +// System.out.println(String.format("<<< Cluster #%02d (%03d points) >>>", ++count, c.getPoints().size())); +// System.out.print(PrintUtils.toSummaryString(c)); +// if(c.getPoints().size() > 45 && c.getPoints().size() < 55) { +// //if(c.getPoints().size() > 25) { +// // Print to file +// List> ppListOfList = PcapPacketUtils.clusterToListOfPcapPackets(c); +// ppListOfListListOn.add(ppListOfList); +// } +// } +// // TODO: Merging test +// ppListOfListListOn = PcapPacketUtils.mergeSignatures(ppListOfListListOn, sortedAllConversation); +// // TODO: Need to remove sequence 550 567 for Blossom phone side since it is not a good signature (overlap)! +//// PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 1); +// // TODO: Need to remove sequence 69 296 for Blossom device side since it is not a good signature (overlap)! +//// PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 2); +// // TODO: Need to remove sequence number 2 for ST plug since it is not a good signature! +// //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 2); +// // TODO: Need to remove sequence number 0 for Arlo Camera since it is not a good signature! +// //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 0); +// // TODO: Need to remove sequence number 0 for TP-Link plug since it is not a good signature! +// // TODO: This sequence actually belongs to the local communication between the plug and the phone +// //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, 0); +// ppListOfListListOn = PcapPacketUtils.sortSignatures(ppListOfListListOn); +// PcapPacketUtils.printSignatures(ppListOfListListOn); +// //count = 0; +// /*for (List> ll : ppListOfListListOn) { +// PrintUtils.serializeClustersIntoFile("./onSignature" + ++count + ".sig", ll); +// ppListOfListReadOn.add(PrintUtils.deserializeClustersFromFile("./onSignature" + count + ".sig")); +// }*/ +// PrintUtils.serializeSignatureIntoFile("./onSignature.sig", ppListOfListListOn); +// ppListOfListReadOn = PrintUtils.deserializeSignatureFromFile("./onSignature.sig"); +// +// System.out.println("========================================"); +// System.out.println(" Clustering results for OFF "); +// System.out.println(" Number of clusters: " + offClusters.size()); +// count = 0; +// List>> ppListOfListReadOff = new ArrayList<>(); +// List>> ppListOfListListOff = new ArrayList<>(); +// for (Cluster c : offClusters) { +// System.out.println(String.format("<<< Cluster #%03d (%06d points) >>>", ++count, c.getPoints().size())); +// System.out.print(PrintUtils.toSummaryString(c)); +// if(c.getPoints().size() > 45 && c.getPoints().size() < 55) { +// //if(c.getPoints().size() > 25) { +// // Print to file +// List> ppListOfList = PcapPacketUtils.clusterToListOfPcapPackets(c); +// ppListOfListListOff.add(ppListOfList); +// } +// } +// // TODO: Merging test +// ppListOfListListOff = PcapPacketUtils.mergeSignatures(ppListOfListListOff, sortedAllConversation); +// // TODO: Need to remove sequence 69 296 for Blossom device side since it is not a good signature (overlap)! +//// PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 3); +// // TODO: Need to remove sequence number 1 for Nest Thermostat since it is not a good signature! +// //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 1); +// // TODO: Need to remove sequence number 0 for Arlo Camera since it is not a good signature! +//// PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 1); +// // TODO: Need to remove sequence number 2 for ST plug since it is not a good signature! +// //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 2); +// // TODO: Need to remove sequence number 0 for TP-Link plug since it is not a good signature! +// // TODO: This sequence actually belongs to the local communication between the plug and the phone +// //PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, 0); +// ppListOfListListOff = PcapPacketUtils.sortSignatures(ppListOfListListOff); +// PcapPacketUtils.printSignatures(ppListOfListListOff); +// //count = 0; +// /*for (List> ll : ppListOfListListOff) { +// PrintUtils.serializeClustersIntoFile("./offSignature" + ++count + ".sig", ll); +// ppListOfListReadOff.add(PrintUtils.deserializeClustersFromFile("./offSignature" + count + ".sig")); +// }*/ +// PrintUtils.serializeSignatureIntoFile("./offSignature.sig", ppListOfListListOff); +// ppListOfListReadOff = PrintUtils.deserializeSignatureFromFile("./offSignature.sig"); +// System.out.println("========================================"); // ============================================================================================================ + // TODO: This part is just for DBSCAN sensitivity experiment + // TODO: This part is just for DBSCAN sensitivity experiment + // TODO: This part is just for DBSCAN sensitivity experiment + // TODO: This part is just for DBSCAN sensitivity experiment + // TODO: This part is just for DBSCAN sensitivity experiment +// 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()); +// //Collections.sort(onConversations, (c1, c2) -> c1.getPackets().) +// +// 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)); +// +// double eps = 10; // loop from eps 1-10 +// int minPts = 50; // loop from minPts 30-50 +// for(int epsCount = 1; epsCount <= eps; epsCount++) { +// for(int minPtsCount = 30; minPtsCount <= minPts; minPtsCount++) { +// System.out.println("Eps: " + epsCount + " --- minPts: " + minPtsCount); +// DBSCANClusterer onClusterer = new DBSCANClusterer<>(epsCount, minPtsCount); +// DBSCANClusterer offClusterer = new DBSCANClusterer<>(epsCount, minPtsCount); +// List> onClusters = onClusterer.cluster(onPairs); +// List> offClusters = offClusterer.cluster(offPairs); +// // Sort the conversations as reference +// List sortedAllConversation = TcpConversationUtils.sortConversationList(allConversations); +// // Output clusters +// System.out.println("========================================"); +// System.out.println(" Clustering results for ON "); +// System.out.println(" Number of clusters: " + onClusters.size()); +// int count = 0; +// List>> ppListOfListListOn = new ArrayList<>(); +// for (Cluster c : onClusters) { +// System.out.println(String.format("<<< Cluster #%02d (%03d points) >>>", ++count, c.getPoints().size())); +// System.out.print(PrintUtils.toSummaryString(c)); +// if (c.getPoints().size() > 45 && c.getPoints().size() < 55) { +//// if(c.getPoints().size() > 25) { +// // Print to file +// List> ppListOfList = PcapPacketUtils.clusterToListOfPcapPackets(c); +// ppListOfListListOn.add(ppListOfList); +// } +// } +// PcapPacketUtils.printSignatures(ppListOfListListOn); +// +// System.out.println("========================================"); +// System.out.println(" Clustering results for OFF "); +// System.out.println(" Number of clusters: " + offClusters.size()); +// count = 0; +// List>> ppListOfListListOff = new ArrayList<>(); +// for (Cluster c : offClusters) { +// System.out.println(String.format("<<< Cluster #%03d (%06d points) >>>", ++count, c.getPoints().size())); +//// System.out.print(PrintUtils.toSummaryString(c)); +// if (c.getPoints().size() > 45 && c.getPoints().size() < 55) { +// //if(c.getPoints().size() > 25) { +// // Print to file +// List> ppListOfList = PcapPacketUtils.clusterToListOfPcapPackets(c); +// ppListOfListListOff.add(ppListOfList); +// } +// } +// PcapPacketUtils.printSignatures(ppListOfListListOff); +// System.out.println(); +// System.out.println(); +// System.out.println(); +// // ============================================================================================================ +// } +// } + // // ================================================================================================ // // <<< Some work-in-progress/explorative code that extracts a "representative" sequence >>> 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 f1c264b..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 @@ -71,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()) { diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/layer3/SignatureDetector.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/layer3/SignatureDetector.java index 4c81bb6..ce745e5 100644 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/layer3/SignatureDetector.java +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/layer3/SignatureDetector.java @@ -112,7 +112,7 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver // final String inputPcapFile = path + "/UNSW/16-10-01.pcap"; // final String inputPcapFile = path + "/UNSW/16-10-06.pcap"; // Negative test: dataset from UNB - final String inputPcapFile = path + "/evaluation/negative-datasets/UNB/Monday-WorkingHours_one-local-endpoint-001.pcap"; +// final String inputPcapFile = path + "/evaluation/negative-datasets/UNB/Monday-WorkingHours_one-local-endpoint-001.pcap"; // TODO: The following are tests for signatures against training data @@ -218,15 +218,15 @@ public class SignatureDetector implements PacketListener, ClusterMatcherObserver // TODO: EXPERIMENT - January 9, 2018 // Blossom Sprinkler experiment -// final String inputPcapFile = path + "/experimental_result/standalone/blossom-sprinkler/wlan1/blossom-sprinkler.wlan1.local.pcap"; + final String inputPcapFile = path + "/experimental_result/standalone/blossom-sprinkler/wlan1/blossom-sprinkler.wlan1.local.pcap"; // final String inputPcapFile = path + "/experimental_result/smarthome/blossom-sprinkler/eth0/blossom-sprinkler.eth0.detection.pcap"; // final String inputPcapFile = path + "/experimental_result/smarthome/blossom-sprinkler/wlan1/blossom-sprinkler.wlan1.detection.pcap"; // Blossom Sprinkler DEVICE signatures - final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-device-side.sig"; - final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-device-side.sig"; +// final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-device-side.sig"; +// final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-device-side.sig"; // Blossom Sprinkler PHONE signatures -// final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-phone-side.sig"; -// final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-phone-side.sig"; + final String onSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-onSignature-phone-side.sig"; + final String offSignatureFile = path + "/experimental_result/standalone/blossom-sprinkler/signatures/blossom-sprinkler-offSignature-phone-side.sig"; // LiFX Bulb experiment // final String inputPcapFile = path + "/training/lifx-bulb/wlan1/lifx-bulb.wlan1.local.pcap"; diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/util/PcapPacketUtils.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/util/PcapPacketUtils.java index bde5ec5..067af93 100644 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/util/PcapPacketUtils.java +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/util/PcapPacketUtils.java @@ -28,6 +28,11 @@ public final class PcapPacketUtils { */ private static final int SIGNATURE_MERGE_THRESHOLD = 5; + /** + * This is an overlap counter (we consider overlaps between signatures if it happens more than once) + */ + private static int mOverlapCounter = 0; + /** * Gets the source address of the Ethernet part of {@code packet}. @@ -113,7 +118,7 @@ public final class PcapPacketUtils { * @param port The port to look for in the tcp.port field of {@code packet}. * @return {@code true} if the given ip+port match the corresponding fields in {@code packet}. */ - public static boolean isSource(PcapPacket packet, String ip, int port) { + public static boolean isSource(PcapPacket packet, String ip, int port) { IpV4Packet ipPacket = Objects.requireNonNull(packet.get(IpV4Packet.class)); // For now we only support TCP flows. TcpPacket tcpPacket = Objects.requireNonNull(packet.get(TcpPacket.class)); @@ -174,7 +179,7 @@ public final class PcapPacketUtils { } /** - * Checks if {@code packet} wraps a TCP packet that has the ACK flag set. + * Checks if {@code packet} wraps a TCP packet th at has the ACK flag set. * @param packet A {@link PcapPacket} that is suspected to contain a {@link TcpPacket} for which the ACK flag is set. * @return {@code true} iff {@code packet} contains a {@code TcpPacket} for which the ACK flag is set, * {@code false} otherwise. @@ -204,7 +209,7 @@ public final class PcapPacketUtils { ppListOfList.add(ppList); } // Sort the list of lists based on the first packet's timestamp! - Collections.sort(ppListOfList, (p1, p2) -> p1.get(0).getTimestamp().compareTo(p2.get(0).getTimestamp())); + Collections.sort(ppListOfList, (p1, p2) -> p1. get(0).getTimestamp().compareTo(p2.get(0).getTimestamp())); return ppListOfList; } @@ -397,10 +402,14 @@ public final class PcapPacketUtils { // Check the signs of compare and compareLast if ((compare <= 0 && compareLast > 0) || (compareLast <= 0 && compare > 0)) { - throw new Error("OVERLAP WARNING: " + "" + - "One sequence is in the other. Please remove one of the sequences: " + - sequence1.get(0).length() + "... OR " + - sequence2.get(0).length() + "..."); + mOverlapCounter++; + // TODO: Probably not the best approach but we consider overlap if it happens more than once + if (mOverlapCounter > 1) { + throw new Error("OVERLAP WARNING: " + "" + + "One sequence is in the other. Please remove one of the sequences: " + + sequence1.get(0).length() + "... OR " + + sequence2.get(0).length() + "..."); + } } } @@ -439,7 +448,7 @@ public final class PcapPacketUtils { int sequenceCounter = 0; for(List> listListPcapPacket : signatures) { // Iterate over every member of a cluster/sequence - System.out.print("====== SEQUENCE " + sequenceCounter++); + System.out.print("====== SEQUENCE " + ++sequenceCounter); System.out.println(" - " + listListPcapPacket.size() + " MEMBERS ======"); for(List listPcapPacket : listListPcapPacket) { // Print out packet lengths in a sequence -- 2.34.1