PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOn, sequenceToDelete);
}
ppListOfListListOn = PcapPacketUtils.sortSequences(ppListOfListListOn);
+ PrintWriterUtils.println("Concatenated and sorted ON signature sequences...", resultsWriter,
+ DUPLICATE_OUTPUT_TO_STD_OUT);
// Concatenate
ppListOfListListOff = PcapPacketUtils.concatSequences(ppListOfListListOff, sortedAllConversation);
PcapPacketUtils.removeSequenceFromSignature(ppListOfListListOff, sequenceToDelete);
}
ppListOfListListOff = PcapPacketUtils.sortSequences(ppListOfListListOff);
+ PrintWriterUtils.println("Concatenated and sorted OFF signature sequences...", resultsWriter,
+ DUPLICATE_OUTPUT_TO_STD_OUT);
+
// Write the signatures into the screen
PrintWriterUtils.println("========================================", resultsWriter,
DUPLICATE_OUTPUT_TO_STD_OUT);
PrintUtils.serializeIntoFile(onClusterAnalysisFile, corePointRangeSignatureOn);
PrintUtils.serializeIntoFile(offClusterAnalysisFile, corePointRangeSignatureOff);
- // =========================================== SIGNATURE DURATION ===========================================
+ // =========================================== SIGNATURE DURATIONS =============================================
List<Instant> firstSignatureTimestamps = new ArrayList<>();
List<Instant> lastSignatureTimestamps = new ArrayList<>();
if (!ppListOfListListOn.isEmpty()) {
}
}
- if (!ppListOfListListOn.isEmpty()) {
+ if (!ppListOfListListOff.isEmpty()) {
List<List<PcapPacket>> firstListOffSign = ppListOfListListOff.get(0);
List<List<PcapPacket>> lastListOffSign = ppListOfListListOff.get(ppListOfListListOff.size() - 1);
// Load OFF signature first and last packet's timestamps
* @param clusterMatcher The {@link AbstractClusterMatcher} that detected a match (i.e., classified traffic as
* pertaining to its associated cluster).
* @param match The traffic that was deemed to match the cluster associated with {@code clusterMatcher}.
+ * @param maxSkippedPackets Maximum number of skipped packets.
*/
- void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match);
+ void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match, int maxSkippedPackets);
}
*/
protected final boolean[] mPacketDirections;
+ /**
+ * Keep track of the numbers of skipped packets
+ */
+ protected int mSkippedPackets;
+ protected int mMaxSkippedPackets;
+
/**
* Create a {@code Layer2AbstractMatcher}.
* @param sequence The sequence of the signature.
mPacketDirections[i] = getPacketDirection(prevPkt, prevPktDirection, sequence.get(i));
}
}
+ mSkippedPackets = 0;
+ mMaxSkippedPackets = 0;
}
/**
return mMatchedPackets;
}
+ public int getMaxSkippedPackets() {
+ return mMaxSkippedPackets;
+ }
+
/**
* Utility for {@code getMatchedPackets().get(getMatchedPackets().size()-1)}.
* @return The last matched packet, or {@code null} if no packets have been matched yet.
if (matched) {
if (sm.getMatchedPacketsCount() == sm.getTargetSequencePacketCount()) {
// Sequence matcher has a match. Report it to observers.
- mObservers.forEach(o -> o.onMatch(this, sm.getMatchedPackets()));
+ mObservers.forEach(o -> o.onMatch(this, sm.getMatchedPackets(),
+ sm.getMaxSkippedPackets()));
// Remove the now terminated sequence matcher.
matchers[i][j] = null;
} else {
if (matched) {
if (sm.getMatchedPacketsCount() == sm.getTargetSequencePacketCount()) {
// Sequence matcher has a match. Report it to observers.
- mObservers.forEach(o -> o.onMatch(this, sm.getMatchedPackets()));
+ mObservers.forEach(o -> o.onMatch(this, sm.getMatchedPackets(),
+ sm.getMaxSkippedPackets()));
// Terminate sequence matcher since matching is complete.
listMatchers.remove(matcher);
}
private final List<PcapPacket> mUpperBound;
private final double mEps;
private int mInclusionTimeMillis;
+ private int mSkippedPackets;
/**
* Create a {@code Layer2RangeMatcher}.
mEps = eps;
mInclusionTimeMillis =
inclusionTimeMillis == 0 ? TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS : inclusionTimeMillis;
+ mSkippedPackets = 0;
}
/**
return false;
}
// If we made it here, it means that this packet has the expected length, direction, and obeys the timing
- // constraints, so we store it and advance.
+ // constraints, so we store it and advance.zzzz
mMatchedPackets.add(packet);
if (mMatchedPackets.size() == mLowerBound.size()) {
// TODO report (to observers?) that we are done?
private int mInclusionTimeMillis;
+
/**
* Create a {@code Layer2SequenceMatcher}.
* @param sequence The sequence to match against (search for).
mPacketDirections[getMatchedPacketsCount()-1], packet);
boolean expectedDirection = mPacketDirections[getMatchedPacketsCount()];
if (actualDirection != expectedDirection) {
+ mSkippedPackets++;
return false;
}
// Next apply timing constraints:
// 1: to be a match, the packet must have a later timestamp than any other packet currently matched
// 2: does adding the packet cause the max allowed time between first packet and last packet to be exceeded?
if (!packet.getTimestamp().isAfter(mMatchedPackets.get(getMatchedPacketsCount()-1).getTimestamp())) {
+ mSkippedPackets++;
return false;
}
// if (packet.getTimestamp().isAfter(mMatchedPackets.get(0).getTimestamp().
// plusMillis(TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS))) {
if (packet.getTimestamp().isAfter(mMatchedPackets.get(0).getTimestamp().
plusMillis(mInclusionTimeMillis))) {
+ mSkippedPackets++;
return false;
}
// If we made it here, it means that this packet has the expected length, direction, and obeys the timing
// constraints, so we store it and advance.
+ if (mMaxSkippedPackets < mSkippedPackets) {
+ mMaxSkippedPackets = mSkippedPackets;
+ mSkippedPackets = 0;
+ }
mMatchedPackets.add(packet);
if (mMatchedPackets.size() == mSequence.size()) {
// TODO report (to observers?) that we are done?
detectedEvents.stream().filter(ua -> ua.getType() == UserAction.Type.TOGGLE_ON).count();
String resultOff = "# Number of detected events of type " + UserAction.Type.TOGGLE_OFF + ": " +
detectedEvents.stream().filter(ua -> ua.getType() == UserAction.Type.TOGGLE_OFF).count();
+ String onMaxSkippedPackets = "# Number of skipped packets in ON signature " +
+ Integer.toString(onDetector.getMaxSkippedPackets());
+ String offMaxSkippedPackets = "# Number of skipped packets in OFF signature " +
+ Integer.toString(offDetector.getMaxSkippedPackets());
PrintWriterUtils.println(resultOn, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
PrintWriterUtils.println(resultOff, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
+ PrintWriterUtils.println(onMaxSkippedPackets, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
+ PrintWriterUtils.println(offMaxSkippedPackets, resultsWriter, DUPLICATE_OUTPUT_TO_STD_OUT);
// Flush output to results file and close it.
resultsWriter.flush();
private int mInclusionTimeMillis;
+ private int mMaxSkippedPackets;
+
public Layer2SignatureDetector(List<List<List<PcapPacket>>> searchedSignature, int signatureDuration, boolean isRangeBased, double eps) {
this(searchedSignature, null, signatureDuration, isRangeBased, eps);
}
mClusterMatchers.forEach(cm -> mFlowReassembler.addObserver(cm));
mInclusionTimeMillis =
inclusionTimeMillis == 0 ? TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS : inclusionTimeMillis;
+ mMaxSkippedPackets = 0;
+ }
+
+ public int getMaxSkippedPackets() {
+ return mMaxSkippedPackets;
}
@Override
}
@Override
- public void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match) {
+ public void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match, int maxSkippedPackets) {
+ // Update the number of skipped packets
+ if (mMaxSkippedPackets < maxSkippedPackets) {
+ mMaxSkippedPackets = maxSkippedPackets;
+ }
// TODO: a cluster matcher found a match
if (clusterMatcher instanceof Layer2ClusterMatcher) {
// Add the match at the corresponding index
isPresent()) {
List<PcapPacket> matchSeq = match.get();
// 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));
-// }
+ // Max number of skipped packets in layer 3 is 0 (no skipped packets)
+ mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq, 0));
/*
* Get the index in cPkts of the last packet in the sequence of packets that matches the searched
* signature sequence.
isPresent()) {
List<PcapPacket> matchSeq = match.get();
// 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));
-// }
+ // Max number of skipped packets in layer 3 is 0 (no skipped packets)
+ mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq, 0));
/*
* Get the index in cPkts of the last packet in the sequence of packets that matches the searched
* signature sequence.
}
@Override
- public void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match) {
+ public void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match, int maxSkippedPackets) {
// Add the match at the corresponding index
pendingMatches[mClusterMatcherIds.get(clusterMatcher)].add(match);
checkSignatureMatch();
if (Math.abs(timestamp1 - timestamp2) < TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS) {
// If these two are within INCLUSION_WINDOW_MILLIS window then compare!
compare = p1.get(count1).get(0).getTimestamp().compareTo(p2.get(count2).get(0).getTimestamp());
- overlapChecking(compare, comparePrev, p1.get(count1), p2.get(count2));
+ overlapChecking(compare, comparePrev, p1.get(count1), p2.get(count2),
+ signatures.indexOf(p1), signatures.indexOf(p2));
comparePrev = compare;
count1++;
count2++;
* @param comparePrev Previous comparison value between packet sequences p1 and p2
* @param sequence1 The packet sequence ({@link List} of {@link PcapPacket} objects).
* @param sequence2 The packet sequence ({@link List} of {@link PcapPacket} objects).
+ * @param indexSequence1 The index of packet sequence ({@link List} of {@link PcapPacket} objects).
+ * @param indexSequence2 The index of packet sequence ({@link List} of {@link PcapPacket} objects).
*/
- private static void overlapChecking(int compare, int comparePrev, List<PcapPacket> sequence1, List<PcapPacket> sequence2) {
+ private static void overlapChecking(int compare, int comparePrev,
+ List<PcapPacket> sequence1, List<PcapPacket> sequence2,
+ int indexSequence1, int indexSequence2) {
// Check if p1 occurs before p2 but both have same overlap
if (comparePrev != 0) { // First time since it is 0
// E.g., 111, 222, 333 in one occassion and 222, 333, 111 in the other.
throw new Error("OVERLAP WARNING: " + "" +
"Two sequences have some overlap. Please remove one of the sequences: " +
- sequence1.get(0).length() + "... OR " +
- sequence2.get(0).length() + "...");
+ sequence1.get(0).length() + " with index " + indexSequence1 + " OR " +
+ sequence2.get(0).length() + " with index " + indexSequence2);
}
}
// Check if p1 is longer than p2 and p2 occurs during the occurrence of p1