1 package edu.uci.iotproject.detection.layer2;
3 import edu.uci.iotproject.analysis.TriggerTrafficExtractor;
4 import org.pcap4j.core.PcapPacket;
6 import java.util.ArrayList;
10 * Attempts to detect the presence of a specific packet sequence in the set of packets provided through multiple calls
11 * to {@link #matchPacket(PcapPacket)}, considering only layer 2 information.
13 * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
14 * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
16 public class Layer2SequenceMatcher {
19 * The sequence this {@link Layer2SequenceMatcher} is searching for.
21 private final List<PcapPacket> mSequence;
24 * Buffer of actual packets seen so far that match the searched sequence (i.e., constitutes a subsequence of the
27 private final List<PcapPacket> mMatchedPackets = new ArrayList<>();
30 * Create a {@code Layer2SequenceMatcher}.
31 * @param sequence The sequence to match against (search for).
33 public Layer2SequenceMatcher(List<PcapPacket> sequence) {
38 * Attempt to advance this {@code Layer2SequenceMatcher} by matching {@code packet} against the packet that this
39 * {@code Layer2SequenceMatcher} expects as the next packet of the sequence it is searching for.
41 * @return {@code true} if this {@code Layer2SequenceMatcher} could advance by adding {@code packet} to its set of
42 * matched packets, {@code false} otherwise.
44 public boolean matchPacket(PcapPacket packet) {
45 // The packet we want to match next.
46 PcapPacket expected = mSequence.get(mMatchedPackets.size());
47 // First verify if the received packet has the length we're looking for.
48 if (packet.getOriginalLength() == expected.getOriginalLength()) {
49 // Next apply timing constraints:
50 // - to be a match, the packet must have a later timestamp than any other packet currently matched
51 // - does adding the packet cause the max allowed time between first packet and last packet to be exceeded?
52 if (mMatchedPackets.size() > 0 &&
53 !packet.getTimestamp().isAfter(mMatchedPackets.get(mMatchedPackets.size()-1).getTimestamp())) {
56 if (mMatchedPackets.size() > 0 &&
57 packet.getTimestamp().
58 isAfter(mMatchedPackets.get(0).getTimestamp().
59 plusMillis(TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS))) {
63 // TODO (how to) check directions?
64 // This packet has a length matching next packet of searched sequence, so we store it and advance.
65 mMatchedPackets.add(packet);
66 if (mMatchedPackets.size() == mSequence.size()) {
67 // TODO report (to observers?) that we are done.
74 public int getMatchedPacketsCount() {
75 return mMatchedPackets.size();
78 public int getTargetSequencePacketCount() {
79 return mSequence.size();
82 public List<PcapPacket> getTargetSequence() {
86 public List<PcapPacket> getMatchedPackets() {
87 return mMatchedPackets;