import edu.uci.iotproject.detection.ClusterMatcherObserver;
import edu.uci.iotproject.detection.SignatureDetectorObserver;
import edu.uci.iotproject.io.PcapHandleReader;
+import edu.uci.iotproject.io.PrintWriterUtils;
import edu.uci.iotproject.trafficreassembly.layer2.Layer2FlowReassembler;
import edu.uci.iotproject.util.PrintUtils;
import org.jgrapht.GraphPath;
import org.jgrapht.graph.SimpleDirectedWeightedGraph;
import org.pcap4j.core.*;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
import java.time.Duration;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
import java.util.*;
/**
- * TODO add class documentation.
+ * Performs layer 2 signature detection.
*
- * @author Janus Varmarken
+ * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
+ * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
*/
public class Layer2SignatureDetector implements PacketListener, ClusterMatcherObserver {
- // Main method only intended for easier debugging.
- public static void main(String[] args) throws PcapNativeException, NotOpenException {
- String onSignatureFile = "/Users/varmarken/temp/UCI IoT Project/layer2/kwikset-doorlock-onSignature-phone-side.sig";
- String offSignatureFile = "/Users/varmarken/temp/UCI IoT Project/layer2/kwikset-doorlock-offSignature-phone-side.sig";
+ /**
+ * If set to {@code true}, output written to the results file is also dumped to standard out.
+ */
+ private static boolean DUPLICATE_OUTPUT_TO_STD_OUT = true;
+
+ public static void main(String[] args) throws PcapNativeException, NotOpenException, IOException {
+ if (args.length < 4) {
+ String errMsg = String.format("Usage: %s inputPcapFile onSignatureFile offSignatureFile resultsFile [stdOut]" +
+ "\n - inputPcapFile: the target of the detection" +
+ "\n - onSignatureFile: the file that contains the ON signature to search for" +
+ "\n - offSignatureFile: the file that contains the OFF signature to search for" +
+ "\n - resultsFile: where to write the results of the detection" +
+ "\n - stdOut: optional true/false literal indicating if output should also be printed to std out; default is true",
+ Layer2SignatureDetector.class.getSimpleName());
+ System.out.println(errMsg);
+ return;
+ }
+ final String pcapFile = args[0];
+ final String onSignatureFile = args[1];
+ final String offSignatureFile = args[2];
+ final String resultsFile = args[3];
+ if (args.length == 5) {
+ DUPLICATE_OUTPUT_TO_STD_OUT = Boolean.parseBoolean(args[4]);
+ }
+
+ // Prepare file outputter.
+ File outputFile = new File(resultsFile);
+ outputFile.getParentFile().mkdirs();
+ final PrintWriter resultsWriter = new PrintWriter(new FileWriter(outputFile));
+ // Include metadata as comments at the top
+ PrintWriterUtils.println("# Detection results for:", resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
+ PrintWriterUtils.println("# - inputPcapFile: " + pcapFile, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
+ PrintWriterUtils.println("# - onSignatureFile: " + onSignatureFile, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
+ PrintWriterUtils.println("# - offSignatureFile: " + offSignatureFile, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
+ resultsWriter.flush();
// Create signature detectors and add observers that output their detected events.
Layer2SignatureDetector onDetector = new Layer2SignatureDetector(PrintUtils.deserializeSignatureFromFile(onSignatureFile));
Layer2SignatureDetector offDetector = new Layer2SignatureDetector(PrintUtils.deserializeSignatureFromFile(offSignatureFile));
- DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMM dd, uuuu h:mm:ss a").
- withZone(ZoneId.systemDefault()).withLocale(Locale.US);
onDetector.addObserver((signature, match) -> {
- System.out.println(new UserAction(UserAction.Type.TOGGLE_ON, match.get(0).get(0).getTimestamp()));
-// System.out.println("ON event detected at " + match.get(0).get(0).getTimestamp());
-// System.out.println(dateFormatter.format(match.get(0).get(0).getTimestamp()));
+ UserAction event = new UserAction(UserAction.Type.TOGGLE_ON, match.get(0).get(0).getTimestamp());
+ PrintWriterUtils.println(event, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
});
offDetector.addObserver((signature, match) -> {
- System.out.println(new UserAction(UserAction.Type.TOGGLE_OFF, match.get(0).get(0).getTimestamp()));
-// System.out.println("OFF event detected at " + match.get(0).get(0).getTimestamp());
-// System.out.println(dateFormatter.format(match.get(0).get(0).getTimestamp()));
+ UserAction event = new UserAction(UserAction.Type.TOGGLE_OFF, match.get(0).get(0).getTimestamp());
+ PrintWriterUtils.println(event, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
});
// Load the PCAP file
- String pcapFile = "/Users/varmarken/temp/UCI IoT Project/layer2/kwikset-doorlock.wlan1.local.pcap";
PcapHandle handle;
try {
handle = Pcaps.openOffline(pcapFile, PcapHandle.TimestampPrecision.NANO);
PcapHandleReader reader = new PcapHandleReader(handle, p -> true, onDetector, offDetector);
// Parse the file
reader.readFromHandle();
- }
+ // Flush output to results file and close it.
+ resultsWriter.flush();
+ resultsWriter.close();
+ }
/**
* The signature that this {@link Layer2SignatureDetector} is searching for.