package edu.uci.iotproject.detection.layer3;
+import edu.uci.iotproject.analysis.TriggerTrafficExtractor;
import edu.uci.iotproject.detection.AbstractClusterMatcher;
import edu.uci.iotproject.detection.ClusterMatcherObserver;
import edu.uci.iotproject.trafficreassembly.layer3.Conversation;
*/
public class Layer3ClusterMatcher extends AbstractClusterMatcher implements PacketListener {
- // Test client
- public static void main(String[] args) throws PcapNativeException, NotOpenException {
-
-// String path = "/scratch/July-2018"; // Rahmadi
-// String path = "/Users/varmarken/temp/UCI IoT Project/experiments"; // Janus
-// final String inputPcapFile = path + "/2018-07/dlink/dlink.wlan1.local.pcap";
-// final String signatureFile = path + "/2018-07/dlink/offSignature1.sig";
-//
-// List<List<PcapPacket>> signature = PrintUtils.deserializeClustersFromFile(signatureFile);
-// Layer3ClusterMatcher clusterMatcher = new Layer3ClusterMatcher(signature, null,
-// (sig, match) -> System.out.println(
-// String.format("[ !!! SIGNATURE DETECTED AT %s !!! ]",
-// match.get(0).getTimestamp().atZone(ZoneId.of("America/Los_Angeles")))
-// )
-// );
-//
-// PcapHandle handle;
-// try {
-// handle = Pcaps.openOffline(inputPcapFile, PcapHandle.TimestampPrecision.NANO);
-// } catch (PcapNativeException pne) {
-// handle = Pcaps.openOffline(inputPcapFile);
-// }
-// PcapHandleReader reader = new PcapHandleReader(handle, p -> true, clusterMatcher);
-// reader.readFromHandle();
-// clusterMatcher.performDetection();
- }
-
/**
* The ordered directions of packets in the sequences that make up {@link #mCluster}.
*/
private final String mRouterWanIp;
/**
- * Range-based vs. strict matching.
+ * Epsilon value used by the DBSCAN algorithm; it is used again for range-based matching here.
*/
- private final boolean mRangeBased;
+ private final double mEps;
/**
- * Epsilon value used by the DBSCAN algorithm; it is used again for range-based matching here.
+ * The packet inclusion time for signature.
*/
- private final double mEps;
+ private int mInclusionTimeMillis;
/**
* Create a {@link Layer3ClusterMatcher}.
* @param cluster The cluster that traffic is matched against.
* @param routerWanIp The router's WAN IP if examining traffic captured at the ISP's point of view (used for
* determining the direction of packets).
+ * @param inclusionTimeMillis The packet inclusion time for signature.
* @param isRangeBased The boolean that decides if it is range-based vs. strict matching.
+ * @param eps The epsilon value used in the DBSCAN algorithm.
* @param detectionObservers Client code that wants to get notified whenever the {@link Layer3ClusterMatcher} detects that
* (a subset of) the examined traffic is similar to the traffic that makes up
* {@code cluster}, i.e., when the examined traffic is classified as pertaining to
* {@code cluster}.
*/
- public Layer3ClusterMatcher(List<List<PcapPacket>> cluster, String routerWanIp, boolean isRangeBased, double eps,
+ public Layer3ClusterMatcher(List<List<PcapPacket>> cluster, String routerWanIp, int inclusionTimeMillis,
+ boolean isRangeBased, double eps,
ClusterMatcherObserver... detectionObservers) {
super(cluster, isRangeBased);
Objects.requireNonNull(detectionObservers, "detectionObservers cannot be null");
* on in favor of performance. However, it is only run once (at instantiation), so the overhead may be warranted
* in order to ensure correctness, especially during the development/debugging phase.
*/
- mRangeBased = isRangeBased;
- if (!mRangeBased) { // Only when it is not range-based
+ if (!isRangeBased) { // Only when it is not range-based
if (mCluster.stream().
anyMatch(inner -> !Arrays.equals(mClusterMemberDirections, getPacketDirections(inner, null)))) {
throw new IllegalArgumentException(
}
mEps = eps;
mRouterWanIp = routerWanIp;
+ mInclusionTimeMillis =
+ inclusionTimeMillis == 0 ? TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS : inclusionTimeMillis;
}
@Override
while ((match = findSubsequenceInSequence(lowerBound, upperBound, cPkts, mClusterMemberDirections, null)).
isPresent()) {
List<PcapPacket> matchSeq = match.get();
- // Notify observers about the match.
- mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
+// // Notify observers about the match.
+// mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
+ if (!matchSeq.get(matchSeq.size()-1).getTimestamp().isAfter(matchSeq.get(0).getTimestamp().
+ plusMillis(mInclusionTimeMillis))) {
+ // Notify observers about the match.
+ mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
+ }
/*
* Get the index in cPkts of the last packet in the sequence of packets that matches the searched
* signature sequence.
while ((match = findSubsequenceInSequence(signatureSequence, cPkts, mClusterMemberDirections, null)).
isPresent()) {
List<PcapPacket> matchSeq = match.get();
- // Notify observers about the match.
- mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
+// // Notify observers about the match.
+// mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
+ if (!matchSeq.get(matchSeq.size()-1).getTimestamp().isAfter(matchSeq.get(0).getTimestamp().
+ plusMillis(mInclusionTimeMillis))) {
+ // Notify observers about the match.
+ mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
+ }
/*
* Get the index in cPkts of the last packet in the sequence of packets that matches the searched
* signature sequence.
// We only have a match if packet lengths and directions match.
// The packet lengths have to be in the range of [lowerBound - eps, upperBound+eps]
// TODO: Maybe we could do better here for the double to integer conversion?
- int epsLowerBound = lowBndPkt.length() - (int) mEps;
- int epsUpperBound = upBndPkt.length() + (int) mEps;
+// int epsLowerBound = lowBndPkt.length() - (int) mEps;
+// int epsUpperBound = upBndPkt.length() + (int) mEps;
+ // TODO: TEMPORARILY REMOVE EPS BOUNDS
+ int epsLowerBound = lowBndPkt.length();
+ int epsUpperBound = upBndPkt.length();
if (epsLowerBound <= seqPkt.getOriginalLength() &&
seqPkt.getOriginalLength() <= epsUpperBound &&
subsequenceDirections[subseqIdx] == sequenceDirections[seqIdx]) {