
// NetstatTest.java
// Andrew Davison, ad@coe.psu.ac.th, Nov. 2022

/* Print out 'Established' HTTP connections, updating the
   results every PERIOD secs by using 'netstat -f' on Windows.

   This uses a call to zt-exec's ProcessExecutor that 
   collects output line-by-line while the process is running
   (see https://github.com/zeroturnaround/zt-exec)

   Netstat info:
    * netstat /?
    * https://www.lifewire.com/netstat-command-2618098
    * https://www.tutorialspoint.com/unix_commands/netstat.htm
    * https://www.tecmint.com/20-netstat-commands-for-linux-network-management/

    Usage:
      > compile NetstatTest.java
      > run NetstatTest
*/

import java.io.*;
import java.util.*;
import java.util.concurrent.*;

import org.zeroturnaround.exec.*;
import org.zeroturnaround.exec.stream.*;


public class NetstatTest
{
  private static final int PERIOD = 5;  // seconds

  private static ArrayList<String> addrs = new ArrayList<>();


  public static void main(String[] args)
  {
    prepareHook();   // to handle termination with ctrl-c

    String[] cmd = {"netstat", "-f", ""+PERIOD };
    try {
      new ProcessExecutor().command(cmd).
         redirectOutput(new LogOutputStream() {
            protected void processLine(String line) 
            {
              if (line.contains("ESTABLISHED") &&
                  line.contains("http")) {
                // System.out.println(line);
                String[] fields = line.trim().split("\\s+");
                if (fields.length == 4) {   
                  // the fields are: Proto,Local,Foreign,State
                  String foreignAddr = fields[2];
                  if (!addrs.contains(foreignAddr)) {  // store new one
                    System.out.println(foreignAddr);
                    addrs.add(foreignAddr);
                  }
                }
              }
            }
           }).execute();
    }
    catch(Exception e)
    { System.out.println(e.getMessage()); }

  } // end of main()


  private static void prepareHook()
  // report address number on ctrl-c shutdown
  {
    Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() 
      {
        try {
          Thread.sleep(200);
          System.out.println("No. of addresses collected: " + 
                                              addrs.size());
        } 
        catch (InterruptedException e) { }
      }
    });
  }  // end of prepareHook()

}  // end of NetstatTest class