e8fc4f52727bf86f5af0351aa621bc4655e0d976
[pingpong.git] / Code / Projects / SmartPlugDetector / src / main / java / edu / uci / iotproject / analysis / PcapHandleReader.java
1 package edu.uci.iotproject.analysis;
2
3 import org.pcap4j.core.*;
4
5 import java.io.EOFException;
6 import java.util.concurrent.TimeoutException;
7
8 /**
9  * Reads packets from a {@link PcapHandle} (online or offline) and delivers those packets that pass the test exercised
10  * by the provided {@link PcapPacketFilter} onto the provided {@link PacketListener}s.
11  *
12  * @author Janus Varmarken
13  */
14 public class PcapHandleReader {
15
16     private final PcapPacketFilter mPacketFilter;
17     private final PcapHandle mHandle;
18     private final PacketListener[] mPacketListeners;
19
20     /**
21      * Create a {@code PcapHandleReader}.
22      * @param handle An <em>open</em> {@link PcapHandle} that packets will be read from.
23      * @param packetFilter A {@link PcapPacketFilter} that dictates which of the packets read from {@code handle} should
24      *                     be delivered to {@code packetListeners}. Note that while a value of {@code null} is not
25      *                     permitted here, the caller can instead simply provide an implementation that always returns
26      *                     {@code true} if they want to include all packets read from {@code handle}.
27      * @param packetListeners One or more {@link PacketListener}s to which those packets read from {@code handle} that
28      *                        pass through {@code packetFilter} are delivered.
29      */
30     public PcapHandleReader(PcapHandle handle, PcapPacketFilter packetFilter, PacketListener... packetListeners) {
31         mHandle = handle;
32         mPacketFilter = packetFilter;
33         mPacketListeners = packetListeners;
34     }
35
36
37     /**
38      * Start reading (and filtering) packets from the provided {@link PcapHandle}.
39      * @throws PcapNativeException if an error occurs in the pcap native library.
40      * @throws NotOpenException if the provided {@code PcapHandle} is not open.
41      * @throws TimeoutException if packets are being read from a live capture and the timeout expired.
42      */
43     public void readFromHandle() throws PcapNativeException, NotOpenException, TimeoutException {
44         try {
45             PcapPacket prevPacket = null;
46             PcapPacket packet;
47             while ((packet = mHandle.getNextPacketEx()) != null) {
48                 if (prevPacket != null && packet.getTimestamp().isBefore(prevPacket.getTimestamp())) {
49                     System.out.println("Out-of-order (in terms of timestamp) packet detected");
50                     /*
51                     // Fail early if assumption doesn't hold.
52                     mHandle.close();
53                     throw new AssertionError("Packets not in ascending temporal order");
54                     */
55                 }
56                 if (mPacketFilter.shouldIncludePacket(packet)) {
57                     // Packet accepted for inclusion; deliver it to observing client code.
58                     for (PacketListener consumer : mPacketListeners) {
59                         consumer.gotPacket(packet);
60                     }
61                 }
62                 prevPacket = packet;
63             }
64         } catch (EOFException eof) {
65             // Reached end of file. All good.
66             System.out.println(String.format("%s: finished reading pcap file", getClass().getSimpleName()));
67         }
68         mHandle.close();
69     }
70
71 }