From d4dfbf7b96d59119274182551139aade8e1db6ea Mon Sep 17 00:00:00 2001 From: Janus Varmarken Date: Sat, 12 Jan 2019 20:05:29 -0800 Subject: [PATCH] Cleanup of layer 2 sequence detection: get rid of some experimental classes --- .../java/edu/uci/iotproject/StateMachine.java | 126 ----------- .../detection/L2ClusterMatcher.java | 196 ------------------ 2 files changed, 322 deletions(-) delete mode 100644 Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/StateMachine.java delete mode 100644 Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/L2ClusterMatcher.java diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/StateMachine.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/StateMachine.java deleted file mode 100644 index dc9e51a..0000000 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/StateMachine.java +++ /dev/null @@ -1,126 +0,0 @@ -package edu.uci.iotproject; - -import org.jgrapht.Graphs; -import org.jgrapht.graph.DefaultEdge; -import org.jgrapht.graph.SimpleDirectedGraph; -import org.pcap4j.core.PcapPacket; - -import java.util.List; -import java.util.Optional; - -/** - * TODO add class documentation. - * - * @author Janus Varmarken - */ -public class StateMachine { - - - private final SimpleDirectedGraph mGraph = new SimpleDirectedGraph<>(DefaultEdge.class); - - - public StateMachine(List> subCluster) { - - for (List seqVariation : subCluster) { - - Vertex currVtx; - Vertex prevVtx = null; - - for (int i = 0; i < seqVariation.size(); i++) { - // Create new vertex corresponding to this packet of the sequence - PcapPacket currPkt = seqVariation.get(i); - currVtx = new Vertex(currPkt.getOriginalLength(), i); - - - - - - mGraph.addVertex(currVtx); - - - - if (prevVtx != null) { - // Link vertex representing previous packet of sequence to this vertex. - mGraph.addEdge(prevVtx, currVtx); - - } - - // Current vertex becomes previous vertex for next iteration. - prevVtx = currVtx; - } - } - - } - - - private Vertex mCurrentState; - -// @Override -// public void gotPacket(PcapPacket packet) { -// // Generate a vertex corresponding to the received packet. -// // We expect a packet at the layer that follows the current state's layer. -// Vertex pktVtx = new Vertex(packet.getOriginalLength(), mCurrentState.mLayer + 1); -// // Check if such a vertex is present as a successor of the current state -// Optional match = Graphs.successorListOf(mGraph, mCurrentState).stream(). -// filter(v -> v.equals(pktVtx)).findFirst(); -// // If yes, we move to that new state (new vertex). -// match.ifPresent(v -> mCurrentState = v); -// // TODO buffer the packets that got us here -// // TODO check if we've reached the final layer... -// -// } - - - /** - * Attempts to use {@code packet} to advance this state machine. - * @param packet - * @return {@code true} if this state machine could progress by consuming {@code packet}, {@code false} otherwise. - */ - public boolean attemptAdvance(PcapPacket packet) { - // Generate a vertex corresponding to the received packet. - // We expect a packet at the layer that follows the current state's layer. - Vertex pktVtx = new Vertex(packet.getOriginalLength(), mCurrentState.mLayer + 1); - // Check if such a vertex is present as a successor of the current state - Optional match = Graphs.successorListOf(mGraph, mCurrentState).stream(). - filter(v -> v.equals(pktVtx)).findFirst(); - if (match.isPresent()) { - // If yes, we move to that new state (new vertex). - mCurrentState = match.get(); - // TODO buffer the packet to keep track of what packets got us here (keep track of the match) - // TODO check if we've reached the final layer... - - return true; - } - return false; - } - - private static class Vertex { - - // TODO how to include direction of packets here... - - private final int mPktLength; - private final int mLayer; - - - private Vertex(int pktLength, int layer) { - mPktLength = pktLength; - mLayer = layer; - } - - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Vertex)) return false; - Vertex that = (Vertex) obj; - return that.mPktLength == this.mPktLength && that.mLayer == this.mLayer; - } - - @Override - public int hashCode() { -// return Integer.hashCode(mPktLength); - // Hack: use string's hashCode implementation. - return (Integer.toString(mPktLength) + " " + Integer.toString(mLayer)).hashCode(); - } - - } -} diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/L2ClusterMatcher.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/L2ClusterMatcher.java deleted file mode 100644 index b673e28..0000000 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/L2ClusterMatcher.java +++ /dev/null @@ -1,196 +0,0 @@ -package edu.uci.iotproject.detection; - -import edu.uci.iotproject.Layer2Flow; -import edu.uci.iotproject.L2FlowReassembler; -import edu.uci.iotproject.StateMachine; -import edu.uci.iotproject.util.PcapPacketUtils; -import org.pcap4j.core.PacketListener; -import org.pcap4j.core.PcapPacket; -import org.pcap4j.util.MacAddress; - -import java.util.*; - -/** - * Layer 2 cluster matcher. - * - * @author Janus Varmarken {@literal } - * @author Rahmadi Trimananda {@literal } - */ -public class L2ClusterMatcher extends AbstractClusterMatcher implements PacketListener { - - private final MacAddress mRouterMac = null; - private final MacAddress mPhoneMac = null; - private final MacAddress mDeviceMac = null; - - /** - * Reassembles traffic flows. - */ - private final L2FlowReassembler mFlowReassembler = new L2FlowReassembler(); - - /** - * Each inner set holds the possible packet lengths for the packet at the corresponding index in a sequemce, taken - * across all sequences in {@link #mCluster}. For example, if the cluster is comprised of the sequences [112, 115] - * and [112, 116], the set at index 0 will be {112}, and the set at index 1 will be {115, 116}. - */ - private final List> mValidPktLengths; - - - - // Maintain one state machine for each layer...? - private final StateMachine[] seqMatchers; - - public L2ClusterMatcher(List> cluster) { - super(cluster); - - mValidPktLengths = new ArrayList<>(); - for (int i = 0; i < mCluster.get(0).size(); i++) { - mValidPktLengths.add(new HashSet<>()); - } - for (List seqVariation : mCluster) { - for (int i = 0; i < seqVariation.size(); i++) { - mValidPktLengths.get(i).add(seqVariation.get(i).getOriginalLength()); - } - } - - seqMatchers = new StateMachine[mValidPktLengths.size()]; - } - - @Override - protected List> pruneCluster(List> cluster) { - return null; - } - - - @Override - public void gotPacket(PcapPacket packet) { - for (int i = 0; i < seqMatchers.length; i++) { - StateMachine sm = seqMatchers[i]; - if (sm.attemptAdvance(packet)) { - - } - - } - - - - - - - - for (int i = 0; i < mValidPktLengths.size(); i++) { - if (mValidPktLengths.get(i).contains(packet.getOriginalLength())) { - // This packet length is potentially of interest to state machines that currently expect the i'th packet - // of the searched sequence - - } - } - - - - - // Forward to flow reassembler - mFlowReassembler.gotPacket(packet); - - - - - } - - - public void performDetection() { - for (Layer2Flow flow : mFlowReassembler.getFlows()) { - List flowPkts = flow.getPackets(); - - for (List signatureSequence : mCluster) { - - } - } - } - -/* - private Optional> findSubsequenceInSequence(List subsequence, - List sequence, - boolean[] subsequenceDirections) { - if (sequence.size() < subsequence.size()) { - // If subsequence is longer, it cannot be contained in sequence. - return Optional.empty(); - } - // If packet directions have not been precomputed by calling code, we need to construct them. - if (subsequenceDirections == null) { - subsequenceDirections = getPacketDirections(subsequence); - } - - - - - - -// if (sequenceDirections == null) { -// sequenceDirections = getPacketDirections(sequence); -// } - - - boolean[] sequenceDirections; - - int subseqIdx = 0; - int seqIdx = 0; - while (seqIdx < sequence.size()) { - if (subseqIdx == 0) { - // Every time we (re-)start matching (i.e., when we consider the first element of subsequence), we must - // recompute the directions array for the subsequence.size() next elements of sequence so that we can - // perform index-wise comparisons of the individual elements of the two direction arrays. If we compute - // the directions array for the entire sequence in one go, we may end up with a reversed representation - // of the packet directions (i.e. one in which all boolean values in the array are flipped to be the - // opposite of what is the expected order) for a subsection of sequence that actually obeys the expected - // directions (as defined by the directions array corresponding to subsequence), depending on the packets - // that come earlier (as we always use 'true' for the first packet direction of a sequence). - int toIndex = Integer.min(seqIdx + subsequence.size(), sequence.size()); - sequenceDirections = getPacketDirections(sequence.subList(seqIdx, toIndex)); - } - - - PcapPacket subseqPkt = subsequence.get(subseqIdx); - PcapPacket seqPkt = sequence.get(seqIdx); - // We only have a match if packet lengths and directions match. - if (subseqPkt.getOriginalLength() == seqPkt.getOriginalLength() && - subsequenceDirections[subseqIdx] == sequenceDirections[subseqIdx]) { - if (subseqIdx > 0) { - - } - } - } - } - */ - - /** - * Returns a boolean array {@code b} such that each entry in {@code b} indicates the direction of the packet at the - * corresponding index in {@code pktSequence}. As there is no notion of client and server, we model the - * packet directions as simple binary values. The direction of the first packet in {@code pktSequence} (and all - * subsequent packets going in the same direction) is denoted using a value of {@code true}, and all packets going - * in the opposite direction are denoted using a value of {@code false}. - * - * @param pktSequence A sequence of packets exchanged between two hosts for which packet directions are to be - * extracted. - * @return The packet directions for {@code pktSequence}. - */ - private boolean[] getPacketDirections(List pktSequence) { - boolean[] directions = new boolean[pktSequence.size()]; - for (int i = 0; i < pktSequence.size(); i++) { - if (i == 0) { - // Special case for first packet: no previous packet to compare against. - directions[i] = true; - } else { - PcapPacket currPkt = pktSequence.get(i); - PcapPacket prevPkt = pktSequence.get(i-1); - if (PcapPacketUtils.getEthSrcAddr(currPkt).equals(PcapPacketUtils.getEthSrcAddr(prevPkt))) { - // Same direction as previous packet. - directions[i] = directions[i-1]; - } else { - // Opposite direction of previous packet. - directions[i] = !directions[i-1]; - } - } - } - return directions; - } -} -- 2.34.1