Package net.azib.ipscan.fetchers

Source Code of net.azib.ipscan.fetchers.PortsFetcher

/**
* This file is a part of Angry IP Scanner source code,
* see http://www.angryip.org/ for more information.
* Licensed under GPLv2.
*/
package net.azib.ipscan.fetchers;

import net.azib.ipscan.config.ScannerConfig;
import net.azib.ipscan.core.PortIterator;
import net.azib.ipscan.core.ScanningResult.ResultType;
import net.azib.ipscan.core.ScanningSubject;
import net.azib.ipscan.core.values.NotScanned;
import net.azib.ipscan.core.values.NumericRangeList;
import net.azib.ipscan.gui.fetchers.PortsFetcherPrefs;
import net.azib.ipscan.util.SequenceIterator;
import net.azib.ipscan.util.ThreadResourceBinder;

import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

/**
* PortsFetcher scans TCP ports.
* Port list is obtained using the {@link net.azib.ipscan.core.PortIterator}.
*
* @author Anton Keks
*/
public class PortsFetcher extends AbstractFetcher {
 
  public static final String ID = "fetcher.ports";
 
  private static final String PARAMETER_OPEN_PORTS = "openPorts";
  private static final String PARAMETER_FILTERED_PORTS = "filteredPorts";
 
  private ScannerConfig config;
  private ThreadResourceBinder<Socket> sockets = new ThreadResourceBinder<Socket>();
 
  // initialize preferences for this scan
  private PortIterator portIteratorPrototype;
  protected boolean displayAsRanges = true// TODO: make configurable
 
  public PortsFetcher(ScannerConfig scannerConfig) {
    this.config = scannerConfig;
  }

  public String getId() {
    return ID;
  }

  @Override
  public String getFullName() {
    int numPorts = new PortIterator(config.portString).size();
    return getName() + " [" + numPorts + (config.useRequestedPorts ? "+" : "" ) + "]";
  }
 
  @Override
  public Class<? extends FetcherPrefs> getPreferencesClass() {
    return PortsFetcherPrefs.class;
  }

  /**
   * This method does the actual port scanning.
   * It then remembers the results for other extending fetchers to use, like FilteredPortsFetcher.
   * @param subject the address to scan
   * @return true if any ports were scanned, false otherwise
   */
  @SuppressWarnings("unchecked")
  protected boolean scanPorts(ScanningSubject subject) {
    SortedSet<Integer> openPorts = getOpenPorts(subject);
         
    if (openPorts == null) {
      // no results are available yet, let's proceed with the scanning
      openPorts = new TreeSet<Integer>();
      SortedSet<Integer> filteredPorts = new TreeSet<Integer>();
      subject.setParameter(PARAMETER_OPEN_PORTS, openPorts);
      subject.setParameter(PARAMETER_FILTERED_PORTS, filteredPorts);

      int portTimeout = subject.getAdaptedPortTimeout();
     
      // clone port iterator for performance instead of creating for every thread
      Iterator<Integer> portsIterator = portIteratorPrototype.copy();
      if (config.useRequestedPorts && subject.isAnyPortRequested()) {
        // add requested ports to the iteration
        portsIterator = new SequenceIterator<Integer>(portsIterator, subject.requestedPortsIterator());
      }
      if (!portsIterator.hasNext()) {
        // no ports are configured for scanning
        return false;
      }

      while (portsIterator.hasNext() && !Thread.currentThread().isInterrupted()) {
        // TODO: UDP ports?
        Socket socket = sockets.bind(new Socket());
        int port = portsIterator.next();
        try {     
          // set some optimization options
          socket.setReuseAddress(true);
          socket.setReceiveBufferSize(32);
          // now connect
          socket.connect(new InetSocketAddress(subject.getAddress(), port), portTimeout);
          // some more options
          socket.setSoLinger(true, 0);
          socket.setSendBufferSize(16);
          socket.setTcpNoDelay(true);
         
          if (socket.isConnected()) openPorts.add(port);
        }
        catch (SocketTimeoutException e) {
          filteredPorts.add(port);
        }
        catch (IOException e) {
          // connection refused
          assert e instanceof ConnectException : e;
        }
        finally {
          sockets.closeAndUnbind(socket);
        }
      }
    }
    return true;
  }

  @SuppressWarnings("unchecked")
  protected SortedSet<Integer> getFilteredPorts(ScanningSubject subject) {
    return (SortedSet<Integer>) subject.getParameter(PARAMETER_FILTERED_PORTS);
  }

  @SuppressWarnings("unchecked")
  protected SortedSet<Integer> getOpenPorts(ScanningSubject subject) {
    return (SortedSet<Integer>) subject.getParameter(PARAMETER_OPEN_PORTS);
  }
 
  /*
   * @see net.azib.ipscan.fetchers.Fetcher#scan(net.azib.ipscan.core.ScanningSubject)
   */
  public Object scan(ScanningSubject subject) {
    boolean portsScanned = scanPorts(subject);
    if (!portsScanned)
      return NotScanned.VALUE;
   
    SortedSet<Integer> openPorts = getOpenPorts(subject);
    boolean portsFound = openPorts.size() > 0;
    if (portsFound) {
      subject.setResultType(ResultType.WITH_PORTS);
    }
    return portsFound ? new NumericRangeList(openPorts, displayAsRanges) : null;
  }

  public void init() {
    // rebuild port iterator before each scan
    this.portIteratorPrototype = new PortIterator(config.portString);
  }

  @Override
  public void cleanup() {
    sockets.close();
  }
}
TOP

Related Classes of net.azib.ipscan.fetchers.PortsFetcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.