package edu.uci.iotproject;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+
/**
* TODO add class documentation.
*
*/
public class FlowPattern {
+ static {
+ // TP-Link Local ON packet lengths (TCP payload only), extracted from ON event at Feb 13, 2018 13:38:04
+ // of the 5 switch data collection:
+ // 517 1448 1448 1448 855 191 51 490 1027 31
+
+ ArrayList<Integer> packetLengths = new ArrayList<>();
+ packetLengths.addAll(Arrays.asList(new Integer[] {517, 1448, 1448, 1448, 855, 191, 51, 490, 1027, 31}));
+ TP_LINK_LOCAL_ON = new FlowPattern("TP_LINK_LOCAL_ON", "events.tplinkra.com", packetLengths);
+ }
+
+ public static final FlowPattern TP_LINK_LOCAL_ON;
+
private final String patternId;
/**
/**
* The order of packet lengths that defines this {@link FlowPattern}
+ * TODO: this is a simplified representation, we should also include information about direction of each packet.
*/
private final List<Integer> flowPacketOrder;
this.flowPacketOrder = Collections.unmodifiableList(flowPacketOrder);
}
+ public String getPatternId() {
+ return patternId;
+ }
+
public String getHostname() {
return hostname;
}
Packet packet;
while ((packet = pcap.getNextPacketEx()) != null) {
-
// For now, we only work support pattern search in TCP over IPv4.
IpV4Packet ipPacket = packet.get(IpV4Packet.class);
TcpPacket tcpPacket = packet.get(TcpPacket.class);
// Packet not related to pattern, skip it.
continue;
}
+ if (tcpPacket.getPayload() == null) {
+ // We skip non-payload control packets as these are less predictable and should therefore not be
+ // part of a signature (e.g. receiver can choose not to ACK immediately)
+ continue;
+ }
+
// Identify conversations (connections/sessions) by the four-tuple (clientIp, clientPort, serverIp, serverPort).
// TODO: this is strictly not sufficient to differentiate one TCP session from another, but should suffice for now.
Conversation conversation = fromClient ? new Conversation(srcAddress, srcPort, dstAddress, dstPort) :
}
} catch (EOFException eofe) {
System.out.println("findFlowPattern: finished processing entire file");
+ find(pattern);
+ }
+ }
+
+ private void find(FlowPattern pattern) {
+ for (Conversation con : connections.keySet()) {
+ List<Packet> packets = connections.get(con);
+ if (packets.size() != pattern.getPacketOrder().size()) {
+ // Not a complete match if different number of packets.
+ continue;
+ }
+ boolean completeMatch = true;
+ for (int i = 0; i < packets.size(); i++) {
+ TcpPacket tcpPacket = packets.get(i).get(TcpPacket.class);
+ if (tcpPacket.getPayload().length() != pattern.getPacketOrder().get(i)) {
+ completeMatch = false;
+ break;
+ }
+ }
+ if (completeMatch) {
+ System.out.println(String.format("found a complete match for %s", pattern.getPatternId()));
+ }
}
}
handle = Pcaps.openOffline(fileName);
}
FlowPatternFinder fpf = new FlowPatternFinder(ipToHostnameMap);
- fpf.findFlowPattern(handle, new FlowPattern("TP_LINK_LOCAL_ON", "events.tplinkra.com", new ArrayList<>()));
+ fpf.findFlowPattern(handle, FlowPattern.TP_LINK_LOCAL_ON);
// ========================
}