Renaming root project name.
[pingpong.git] / Code / Projects / SmartPlugDetector / src / main / java / edu / uci / iotproject / io / LiveCapture.java
1 package edu.uci.iotproject.io;
2
3 import org.pcap4j.core.*;
4 import org.pcap4j.packet.namednumber.DataLinkType;
5 import org.pcap4j.util.NifSelector;
6
7 import java.io.IOException;
8 import java.util.Objects;
9
10 /**
11  * Utility methods for setting up a {@link PcapHandleReader} that reads live traffic from a network interface card.
12  *
13  * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
14  * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
15  */
16 public class LiveCapture {
17
18     // This main method is just for experimental purposes!
19     public static void main(String[] args) throws PcapNativeException, NotOpenException, InterruptedException {
20         // ================================================ EXAMPLE USE ================================================
21         final String outputPcapFile = System.getProperty("user.home") + "/temp/livecapture42.pcap";
22         final PcapDumper outputter = Pcaps.openDead(DataLinkType.EN10MB, 65536).dumpOpen(outputPcapFile);
23         // Prompt user to select what interface we should be listening to; dump packets to a file.
24         PcapHandleReader reader = fromCliNicSelection(
25                 p -> {
26                     try {
27                         outputter.dump(p);
28                     } catch (NotOpenException noe) {
29                         noe.printStackTrace();
30                     }
31                 }
32         );
33
34         // Read on separate thread so that we can get a chance to terminate the reader on this thread.
35         Thread readerThread = new Thread(() -> {
36             try {
37                 reader.readFromHandle();
38             } catch (PcapNativeException e) {
39                 e.printStackTrace();
40             } catch (NotOpenException e) {
41                 e.printStackTrace();
42             }
43         });
44         readerThread.start();
45
46         // Pause to let reader read some packets before we terminate it.
47         Thread.sleep(30_000);
48
49         // Shutdown reader.
50         reader.stopReading();
51         System.out.println("Waiting for " + reader.getClass().getSimpleName() + " to terminate...");
52         while (!reader.hasTerminated());
53         // remember to flush any buffered output
54         outputter.flush();
55         System.out.println(reader.getClass().getSimpleName() + " terminated.");
56         // =============================================================================================================
57     }
58
59     /**
60      * Prompts the user to pick a Network Interface Card (NIC) for which live traffic is to be captured, then creates a
61      * {@link PcapHandleReader} that is ready to start capturing live traffic from that NIC.
62      *
63      * @param listeners One or more {@link PacketListener}s to which packets read from the NIC will be delivered.
64      *
65      * @return A {@link PcapHandleReader} that is ready to start capturing live traffic from the selected NIC or
66      *         {@code null} if no NICs can be found.
67      *
68      * @throws PcapNativeException if an error occurs in the pcap native library.
69      */
70     public static PcapHandleReader fromCliNicSelection(PacketListener... listeners) throws PcapNativeException {
71         PcapNetworkInterface networkInterface = null;
72         try {
73             networkInterface = new NifSelector().selectNetworkInterface();
74         } catch (IOException ioe) {
75             System.err.println("No network interfaces found.");
76             ioe.printStackTrace();
77         }
78         return networkInterface != null ? fromNic(networkInterface, listeners) : null;
79     }
80
81     /**
82      * Creates a {@link PcapHandleReader} that is ready to start capturing live traffic from the provided Network
83      * Interface Card (NIC).
84      *
85      * @param networkInterface The target NIC.
86      * @param listeners One or more {@link PacketListener}s to which packets read from the NIC will be delivered.
87      *
88      * @return A {@link PcapHandleReader} that is ready to start capturing live traffic from the provided NIC.
89      *
90      * @throws PcapNativeException if an error occurs in the pcap native library.
91      */
92     public static PcapHandleReader fromNic(PcapNetworkInterface networkInterface, PacketListener... listeners)
93             throws PcapNativeException {
94         Objects.requireNonNull(networkInterface);
95         int snapshotLength = 65536; // in bytes
96         int readTimeout = 10000; // 0 is infinite on all systems but Solaris
97         PcapHandle handle = networkInterface.openLive(snapshotLength, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, readTimeout);
98         // Supply a filter that accepts all packets (p -> true) as we want to examine all traffic.
99         return new PcapHandleReader(handle, p -> true, listeners);
100     }
101
102 }