-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 <jvarmark@uci.edu>}
- * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
- */
-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<Set<Integer>> mValidPktLengths;
-
-
-
- // Maintain one state machine for each layer...?
- private final StateMachine[] seqMatchers;
-
- public L2ClusterMatcher(List<List<PcapPacket>> cluster) {
- super(cluster);
-
- mValidPktLengths = new ArrayList<>();
- for (int i = 0; i < mCluster.get(0).size(); i++) {
- mValidPktLengths.add(new HashSet<>());
- }
- for (List<PcapPacket> 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<List<PcapPacket>> pruneCluster(List<List<PcapPacket>> 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<PcapPacket> flowPkts = flow.getPackets();
-
- for (List<PcapPacket> signatureSequence : mCluster) {
-
- }
- }
- }
-
-/*
- private Optional<List<PcapPacket>> findSubsequenceInSequence(List<PcapPacket> subsequence,
- List<PcapPacket> 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<PcapPacket> 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;
- }
-}