Adding pre-processing for training set---we take packet lengths directly from a train...
[pingpong.git] / Code / Projects / SmartPlugDetector / src / main / java / edu / uci / iotproject / FlowPattern.java
1 package edu.uci.iotproject;
2
3 import org.pcap4j.core.*;
4 import org.pcap4j.packet.*;
5 import org.pcap4j.packet.DnsPacket;
6 import org.pcap4j.packet.namednumber.DnsResourceRecordType;
7
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.Collections;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14
15 import java.io.EOFException;
16 import java.net.UnknownHostException;
17 import java.util.concurrent.TimeoutException;
18
19 /**
20  * TODO add class documentation.
21  *
22  * @author Janus Varmarken
23  */
24 public class FlowPattern {
25
26     static {
27         // TP-Link Local ON packet lengths (TCP payload only), extracted from ON event at Feb 13, 2018 13:38:04
28         // of the 5 switch data collection:
29         // 517 1448 1448 1448 855 191 51 490 1027 31
30
31         ArrayList<Integer> packetLengths = new ArrayList<>();
32         packetLengths.addAll(Arrays.asList(new Integer[] {517, 1448, 1448, 1448, 855, 191, 51, 490, 1027, 31}));
33         TP_LINK_LOCAL_ON = new FlowPattern("TP_LINK_LOCAL_ON", "events.tplinkra.com", packetLengths);
34     }
35
36     public static final FlowPattern TP_LINK_LOCAL_ON;
37
38     /**
39      * Class properties
40      */
41     private final String patternId;
42
43     /**
44      * The hostname that this {@code FlowPattern} is associated with.
45      */
46     private final String hostname;  // The hostname that this {@code FlowPattern} is associated with.
47
48     /**
49      * The order of packet lengths that defines this {@link FlowPattern}
50      * TODO: this is a simplified representation, we should also include information about direction of each packet.
51      */
52     private final List<Integer> flowPacketOrder;
53         
54     private final Map<String, List<Integer>> hostnameToPacketOrderMap;
55     private final PcapHandle pcap;
56     
57     /**
58      * Class constants
59      */
60      
61
62     /**
63      * Constructor #1
64      */
65     public FlowPattern(String patternId, String hostname, PcapHandle pcap) {
66         this.patternId = patternId;
67         this.hostname = hostname;
68         this.pcap = pcap;
69         this.hostnameToPacketOrderMap = null;
70         this.flowPacketOrder = new ArrayList<Integer>();
71         processPcap();
72     }
73
74     /**
75      * Process the PcapHandle to strip off unnecessary packets and just get the integer array of packet lengths
76      */
77     private void processPcap() {
78
79         PcapPacket packet;
80         try {
81             while ((packet = pcap.getNextPacketEx()) != null) {
82                 // For now, we only work support pattern search in TCP over IPv4.
83                 IpV4Packet ipPacket = packet.get(IpV4Packet.class);
84                 TcpPacket tcpPacket = packet.get(TcpPacket.class);
85                 if (ipPacket == null || tcpPacket == null)
86                     continue;
87                 if (tcpPacket.getPayload() == null) // We skip non-payload control packets as these are less predictable
88                     continue; 
89                 int packetLength = tcpPacket.getPayload().length();
90                 flowPacketOrder.add(packetLength);
91             }
92         } catch (EOFException eofe) {
93             System.out.println("[ FlowPattern ] Finished processing a training PCAP stream!");
94             System.out.println("[ FlowPattern ] Pattern for " + patternId + ": " + Arrays.toString(flowPacketOrder.toArray()));
95         } catch (PcapNativeException  |
96                  TimeoutException     |
97                  NotOpenException ex) {
98             ex.printStackTrace();
99         }
100     }
101
102     /**
103      * Constructor #2
104      *
105      * @param   patternId       Label for this pattern
106      * @param   hostname        Hostname associated with this pattern
107      * @param   flowPacketOrder List of packets in order
108      */
109     public FlowPattern(String patternId, String hostname, List<Integer> flowPacketOrder) {
110         this.patternId = patternId;
111         this.hostname = hostname;
112         this.hostnameToPacketOrderMap = null;
113         this.pcap = null;
114         this.flowPacketOrder = Collections.unmodifiableList(flowPacketOrder);
115     }
116     
117     /**
118      * Constructor #3
119      */
120     public FlowPattern(String patternId, String hostname, Map<String, List<Integer>> hostnameToPacketOrderMap) {
121         this.patternId = patternId;
122         this.hostname = hostname;
123         this.pcap = null;
124         this.flowPacketOrder = null;
125         this.hostnameToPacketOrderMap = Collections.unmodifiableMap(hostnameToPacketOrderMap);
126     }
127
128     public String getPatternId() {
129         return patternId;
130     }
131
132     public String getHostname() {
133         return hostname;
134     }
135
136     /**
137      * Get the the sequence of packet lengths that defines this {@code FlowPattern}.
138      * @return the sequence of packet lengths that defines this {@code FlowPattern}.
139      */
140     public List<Integer> getPacketOrder() {
141         return flowPacketOrder;
142     }
143     
144     /**
145      * Get the length of the List of {@code FlowPattern}.
146      * @return the length of the List of {@code FlowPattern}.
147      */
148     public int getLength() {
149         return flowPacketOrder.size();
150     }
151
152 }