import org.pcap4j.core.PcapPacket;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
*/
protected final List<List<PcapPacket>> mCluster;
+ /**
+ * Observers registered for callbacks from this {@link AbstractClusterMatcher}.
+ */
+ protected final List<ClusterMatcherObserver> mObservers;
+
protected AbstractClusterMatcher(List<List<PcapPacket>> cluster) {
// ===================== PRECONDITION SECTION =====================
cluster = Objects.requireNonNull(cluster, "cluster cannot be null");
// ================================================================
// Let the subclass prune the provided cluster
mCluster = pruneCluster(cluster);
+ mObservers = new ArrayList<>();
+ }
+
+ /**
+ * Register for callbacks from this cluster matcher.
+ * @param observer The target of the callbacks.
+ */
+ public final void addObserver(ClusterMatcherObserver observer) {
+ mObservers.add(observer);
+ }
+
+ /**
+ * Deregister for callbacks from this cluster matcher.
+ * @param observer The callback target that is to be deregistered.
+ */
+ public final void removeObserver(ClusterMatcherObserver observer) {
+ mObservers.remove(observer);
}
/**
--- /dev/null
+package edu.uci.iotproject.detection;
+
+import org.pcap4j.core.PcapPacket;
+
+import java.util.List;
+
+/**
+ * Interface used by client code to register for receiving a notification whenever an {@link AbstractClusterMatcher}
+ * detects traffic that matches an element of its associated cluster.
+ *
+ * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
+ * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
+ */
+public interface ClusterMatcherObserver {
+
+ /**
+ * Callback that is invoked by an {@link AbstractClusterMatcher} whenever it detects traffic that matches an element
+ * of its associated cluster.
+ *
+ * @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}.
+ */
+ void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match);
+
+}
package edu.uci.iotproject.detection.layer3;
import edu.uci.iotproject.detection.AbstractClusterMatcher;
+import edu.uci.iotproject.detection.ClusterMatcherObserver;
import edu.uci.iotproject.trafficreassembly.layer3.Conversation;
import edu.uci.iotproject.trafficreassembly.layer3.TcpReassembler;
import edu.uci.iotproject.analysis.TcpConversationUtils;
*/
private final String mRouterWanIp;
- private final ClusterMatchObserver[] mObservers;
-
/**
* Create a {@link Layer3ClusterMatcher}.
* @param cluster The cluster that traffic is matched against.
* {@code cluster}, i.e., when the examined traffic is classified as pertaining to
* {@code cluster}.
*/
- public Layer3ClusterMatcher(List<List<PcapPacket>> cluster, String routerWanIp, ClusterMatchObserver... detectionObservers) {
+ public Layer3ClusterMatcher(List<List<PcapPacket>> cluster, String routerWanIp,
+ ClusterMatcherObserver... detectionObservers) {
super(cluster);
- // ===================== PRECONDITION SECTION =====================
- mObservers = Objects.requireNonNull(detectionObservers, "detectionObservers cannot be null");
- if (mObservers.length == 0) {
- throw new IllegalArgumentException("no detectionObservers provided");
+ Objects.requireNonNull(detectionObservers, "detectionObservers cannot be null");
+ for (ClusterMatcherObserver obs : detectionObservers) {
+ addObserver(obs);
}
// Build the cluster members' direction sequence.
// Note: assumes that the provided cluster was captured within the local network (routerWanIp is set to null).
"pattern"
);
}
- // ================================================================
mRouterWanIp = routerWanIp;
}
isPresent()) {
List<PcapPacket> matchSeq = match.get();
// Notify observers about the match.
- Arrays.stream(mObservers).forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
+ 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.
return directions;
}
- /**
- * Interface used by client code to register for receiving a notification whenever the {@link Layer3ClusterMatcher}
- * detects traffic that is similar to the traffic that makes up the cluster returned by
- * {@link Layer3ClusterMatcher#getCluster()}.
- */
- interface ClusterMatchObserver {
- /**
- * Callback that is invoked whenever a sequence that is similar to a sequence associated with the cluster (i.e.,
- * a sequence is a member of the cluster) is detected in the traffic that the associated {@link Layer3ClusterMatcher}
- * observes.
- * @param clusterMatcher The {@link Layer3ClusterMatcher} that detected a match (classified traffic as pertaining to
- * its associated cluster).
- * @param match The traffic that was deemed to match the cluster associated with {@code clusterMatcher}.
- */
- void onMatch(Layer3ClusterMatcher clusterMatcher, List<PcapPacket> match);
- }
-
}
import edu.uci.iotproject.analysis.TriggerTrafficExtractor;
import edu.uci.iotproject.analysis.UserAction;
+import edu.uci.iotproject.detection.AbstractClusterMatcher;
+import edu.uci.iotproject.detection.ClusterMatcherObserver;
import edu.uci.iotproject.io.PcapHandleReader;
import edu.uci.iotproject.util.PrintUtils;
import org.jgrapht.GraphPath;
* @author Janus Varmarken {@literal <jvarmark@uci.edu>}
* @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
*/
-public class SignatureDetector implements PacketListener, Layer3ClusterMatcher.ClusterMatchObserver {
+public class SignatureDetector implements PacketListener, ClusterMatcherObserver {
// Test client
public static void main(String[] args) throws PcapNativeException, NotOpenException {
}
@Override
- public void onMatch(Layer3ClusterMatcher clusterMatcher, List<PcapPacket> match) {
+ public void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match) {
// Add the match at the corresponding index
pendingMatches[mClusterMatcherIds.get(clusterMatcher)].add(match);
checkSignatureMatch();