package edu.uci.iotproject.detection.layer2;
+import edu.uci.iotproject.analysis.TriggerTrafficExtractor;
import edu.uci.iotproject.trafficreassembly.layer2.Layer2FlowReassembler;
import edu.uci.iotproject.trafficreassembly.layer2.Layer2Flow;
import edu.uci.iotproject.trafficreassembly.layer2.Layer2FlowReassemblerObserver;
*/
private final double mEps;
+ private int mInclusionTimeMillis;
+
/**
* Create a new {@link Layer2ClusterMatcher} that attempts to find occurrences of {@code cluster}'s members.
* @param cluster The sequence mutations that the new {@link Layer2ClusterMatcher} should search for.
*/
- public Layer2ClusterMatcher(List<List<PcapPacket>> cluster, boolean isRangeBased, double eps) {
+ public Layer2ClusterMatcher(List<List<PcapPacket>> cluster, int inclusionTimeMillis,
+ boolean isRangeBased, double eps) {
// Consider all flows if no flow filter specified.
- this(cluster, flow -> true, isRangeBased, eps);
+ this(cluster, flow -> true, inclusionTimeMillis, isRangeBased, eps);
}
/**
* namely when the {@link Layer2FlowReassembler} notifies the {@link Layer2ClusterMatcher} about
* the new flow. This functionality may for example come in handy when one only wants to search
* for matches in the subset of flows that involves a specific (range of) MAC(s).
+ * @param inclusionTimeMillis Packet inclusion limit for matching.
* @param isRangeBased The boolean that decides if it is range-based vs. strict matching.
* @param eps The epsilon value used in the DBSCAN algorithm.
*/
public Layer2ClusterMatcher(List<List<PcapPacket>> cluster, Function<Layer2Flow, Boolean> flowFilter,
- boolean isRangeBased, double eps) {
+ int inclusionTimeMillis, boolean isRangeBased, double eps) {
super(cluster, isRangeBased);
mFlowFilter = flowFilter;
mRangeBased = isRangeBased;
mEps = eps;
+ mInclusionTimeMillis =
+ inclusionTimeMillis == 0 ? TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS : inclusionTimeMillis;
}
@Override
Layer2SequenceMatcher[][] matchers = new Layer2SequenceMatcher[mCluster.size()][mCluster.get(0).size()];
// Prepare a "state 0" sequence matcher for each sequence variation in the cluster.
for (int i = 0; i < matchers.length; i++) {
- matchers[i][0] = new Layer2SequenceMatcher(mCluster.get(i));
+ matchers[i][0] = new Layer2SequenceMatcher(mCluster.get(i), mInclusionTimeMillis);
}
// Associate the new sequence matcher table with the new flow
mPerFlowSeqMatchers.put(flow, matchers);
// We always want to have a sequence matcher in state 0, regardless of if the one that advanced
// from state zero completed its matching or if it replaced a different one in state 1 or not.
if (sm.getMatchedPacketsCount() == 1) {
- matchers[i][j] = new Layer2SequenceMatcher(sm.getTargetSequence());
+ matchers[i][j] = new Layer2SequenceMatcher(sm.getTargetSequence(), mInclusionTimeMillis);
}
}
}
// around), so the length of the array is simply the sequence length.
Layer2RangeMatcher[] matcher = new Layer2RangeMatcher[mCluster.get(0).size()];
// Prepare a "state 0" sequence matcher.
- matcher[0] = new Layer2RangeMatcher(mCluster.get(0), mCluster.get(1), mEps);
+ matcher[0] = new Layer2RangeMatcher(mCluster.get(0), mCluster.get(1), mInclusionTimeMillis, mEps);
// Associate the new sequence matcher table with the new flow.
mPerFlowRangeMatcher.put(flow, matcher);
}
// We always want to have a sequence matcher in state 0, regardless of if the one that advanced
// from state zero completed its matching or if it replaced a different one in state 1 or not.
if (sm.getMatchedPacketsCount() == 1) {
- matcher[j] = new Layer2RangeMatcher(sm.getTargetLowerBound(), sm.getTargetUpperBound(), mEps);
+ matcher[j] = new Layer2RangeMatcher(sm.getTargetLowerBound(), sm.getTargetUpperBound(),
+ mInclusionTimeMillis, mEps);
}
}
}
private final List<PcapPacket> mLowerBound;
private final List<PcapPacket> mUpperBound;
private final double mEps;
+ private int mInclusionTimeMillis;
/**
* Create a {@code Layer2RangeMatcher}.
* @param upperBound The upper bound of the sequence to match against (search for).
* @param eps The epsilon value used in the DBSCAN algorithm.
*/
- public Layer2RangeMatcher(List<PcapPacket> lowerBound, List<PcapPacket> upperBound, double eps) {
+ public Layer2RangeMatcher(List<PcapPacket> lowerBound, List<PcapPacket> upperBound,
+ int inclusionTimeMillis, double eps) {
// TODO: Just use the lower bound since both lower and upper bounds' packets essentially have the same direction
// TODO: for the same position in the array. Both arrays also have the same length.
super(lowerBound);
mLowerBound = lowerBound;
mUpperBound = upperBound;
mEps = eps;
+ mInclusionTimeMillis =
+ inclusionTimeMillis == 0 ? TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS : inclusionTimeMillis;
}
/**
if (!packet.getTimestamp().isAfter(mMatchedPackets.get(getMatchedPacketsCount()-1).getTimestamp())) {
return false;
}
+// if (packet.getTimestamp().isAfter(mMatchedPackets.get(0).getTimestamp().
+// plusMillis(TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS))) {
if (packet.getTimestamp().isAfter(mMatchedPackets.get(0).getTimestamp().
- plusMillis(TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS))) {
+ plusMillis(mInclusionTimeMillis))) {
return false;
}
// If we made it here, it means that this packet has the expected length, direction, and obeys the timing
*/
private final List<PcapPacket> mSequence;
+ private int mInclusionTimeMillis;
+
/**
* Create a {@code Layer2SequenceMatcher}.
* @param sequence The sequence to match against (search for).
*/
- public Layer2SequenceMatcher(List<PcapPacket> sequence) {
+ public Layer2SequenceMatcher(List<PcapPacket> sequence, int inclusionTimeMillis) {
super(sequence);
mSequence = sequence;
// Compute packet directions for sequence.
mPacketDirections[i] = getPacketDirection(prevPkt, prevPktDirection, sequence.get(i));
}
}
+ mInclusionTimeMillis =
+ inclusionTimeMillis == 0 ? TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS : inclusionTimeMillis;
}
/**
if (!packet.getTimestamp().isAfter(mMatchedPackets.get(getMatchedPacketsCount()-1).getTimestamp())) {
return false;
}
+// if (packet.getTimestamp().isAfter(mMatchedPackets.get(0).getTimestamp().
+// plusMillis(TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS))) {
if (packet.getTimestamp().isAfter(mMatchedPackets.get(0).getTimestamp().
- plusMillis(TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS))) {
+ plusMillis(mInclusionTimeMillis))) {
return false;
}
// If we made it here, it means that this packet has the expected length, direction, and obeys the timing