Android Open Source - android_network_discovery Async Portscan






From Project

Back to project page android_network_discovery.

License

The source code is released under:

GNU General Public License

If you think the Android project android_network_discovery listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2009-2010 Aubort Jean-Baptiste (Rorist)
 * Licensed under GNU's GPL 2, see README
 *///from www  . j ava2 s.c  om

/**
 * Java NIO Documentation:
 * http://jfarcand.wordpress.com/2006/05/30/tricks-and-tips-with-nio-part-i-why-you-must-handle-op_write
 * http://jfarcand.wordpress.com/2006/07/06/tricks-and-tips-with-nio-part-ii-why-selectionkey-attach-is-evil/ 
 * http://jfarcand.wordpress.com/2006/07/07/tricks-and-tips-with-nio-part-iii-to-thread-or-not-to-thread/
 * http://jfarcand.wordpress.com/2006/07/19/httpweblogs-java-netblog20060719tricks-and-tips-nio-part-iv-meet-selectors/
 * http://jfarcand.wordpress.com/2006/09/21/tricks-and-tips-with-nio-part-v-ssl-and-nio-friend-or-foe
 * http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/
 */

package info.lamatricexiste.network;

import info.lamatricexiste.network.Utils.Prefs;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;

public class AsyncPortscan extends AsyncTask<Void, Object, Void> {

  private final String TAG = "AsyncPortscan";
  private static final int TIMEOUT_SELECT = 300;
  private static long TIMEOUT_CONNECT = 1000 * 1000000; // ns
  private static final long TIMEOUT_RW = 3 * 1000 * 1000000; // ns
  private static final String E_REFUSED = "Connection refused";
  private static final String E_TIMEOUT = "The operation timed out";
  // TODO: Probe system to send other stuff than strings
  private static final String[] PROBES = new String[] { "", "\r\n\r\n",
      "GET / HTTP/1.0\r\n\r\n" };
  private static final int MAX_READ = 8 * 1024;
  private static final int WRITE_PASS = PROBES.length;
  private static final long WRITE_COOLDOWN = 200 * 1000000; // ns

  private int rate;
  private boolean select = true;
  private Selector selector;

  protected String ipAddr = null;
  protected int port_start = 0;
  protected int port_end = 0;
  protected int nb_port = 0;
  private boolean getBanner = false;
  private ByteBuffer byteBuffer = ByteBuffer.allocate(MAX_READ);
  private Charset charset = Charset.forName("UTF-8");

  public final static int OPEN = 0;
  public final static int CLOSED = 1;
  public final static int FILTERED = -1;
  public final static int UNREACHABLE = -2;
  public final static int TIMEOUT = -3;

  protected AsyncPortscan(Activity activity, String host, int _rate) {
    ipAddr = host;
    rate = _rate;
    TIMEOUT_CONNECT = rate * 1000000; // ms to ns

    // Preferences
    WeakReference<Activity> mActivity = new WeakReference<Activity>(
        activity);
    final Activity d = mActivity.get();
    if (d != null) {
      SharedPreferences prefs = PreferenceManager
          .getDefaultSharedPreferences(d.getApplicationContext());
      getBanner = prefs
          .getBoolean(Prefs.KEY_BANNER, Prefs.DEFAULT_BANNER);
    }
  }

  @Override
  protected Void doInBackground(Void... params) {
    try {
      int step = 127;
      Log.i("AsyncPortScan","Executed");
      InetAddress ina = InetAddress.getByName(ipAddr);
      if (nb_port > step) {
        // FIXME: Selector leaks file descriptors (Dalvik bug)
        // http://code.google.com/p/android/issues/detail?id=4825
        for (int i = port_start; i <= port_end - step; i += step + 1) {
          if (select) {
            start(ina, i, i
                + ((i + step <= port_end - step) ? step
                    : port_end - i));
          }
        }
      } else {
        start(ina, port_start, port_end);
      }

    } catch (UnknownHostException e) {
      Log.e(TAG, e.getMessage());
      publishProgress(0, UNREACHABLE, null);
    }
    return null;
  }

  private void start(final InetAddress ina, final int PORT_START,
      final int PORT_END) {
    select = true;
    try {
      selector = Selector.open();
      for (int j = PORT_START; j <= PORT_END; j++) {
        connectSocket(ina, j);
      }
      while (select && selector.keys().size() > 0) {
        if (selector.select(TIMEOUT_SELECT) > 0) {
          synchronized (selector.selectedKeys()) {
            Iterator<SelectionKey> iterator = selector
                .selectedKeys().iterator();
            while (iterator.hasNext()) {
              SelectionKey key = (SelectionKey) iterator.next();
              try {
                if (!key.isValid()) {
                  continue;
                }
                // States
                final Data data = (Data) key.attachment();

                if (key.isConnectable()) {
                  if (((SocketChannel) key.channel())
                      .finishConnect()) {
                    if (getBanner) {
                      key.interestOps(SelectionKey.OP_READ
                          | SelectionKey.OP_WRITE);
                      data.state = OPEN;
                      data.start = System.nanoTime();
                      publishProgress(data.port, OPEN,
                          null);
                    } else {
                      finishKey(key, OPEN);
                    }
                  }

                } else if (key.isReadable()) {
                  try {
                    byteBuffer.clear();
                    final int numRead = ((SocketChannel) key
                        .channel()).read(byteBuffer);
                    if (numRead > 0) {
                      String banner = new String(
                          byteBuffer.array())
                          .substring(0, numRead)
                          .trim();
                      // Log.v(TAG, "read " + data.port +
                      // " data=" + banner);
                      finishKey(key, OPEN, banner);
                    } else {
                      key.interestOps(SelectionKey.OP_WRITE);
                    }
                  } catch (IOException e) {
                    Log.e(TAG, e.getMessage());
                  }
                } else if (key.isWritable()) {
                  key.interestOps(SelectionKey.OP_READ
                      | SelectionKey.OP_WRITE);
                  if (System.nanoTime() - data.start > WRITE_COOLDOWN) {
                    if (data.pass < WRITE_PASS) {
                      // Log.v(TAG, "write " + data.port);
                      // write something (blocking)
                      final ByteBuffer bytedata = charset
                          .encode(PROBES[data.pass]);
                      final SocketChannel sock = (SocketChannel) key
                          .channel();
                      while (bytedata.hasRemaining()) {
                        sock.write(bytedata);
                      }
                      bytedata.clear();
                      data.start = System.nanoTime();
                      data.pass++;
                    } else {
                      finishKey(key, OPEN);
                    }
                  }
                }

              } catch (ConnectException e) {
                if (e.getMessage().equals(E_REFUSED)) {
                  finishKey(key, CLOSED);
                } else if (e.getMessage().equals(E_TIMEOUT)) {
                  finishKey(key, FILTERED);
                } else {
                  Log.e(TAG, e.getMessage());
                  e.printStackTrace();
                  finishKey(key, FILTERED);
                }
              } catch (Exception e) {
                try {
                  Log.e(TAG, e.getMessage());
                } catch (java.lang.NullPointerException e1) {
                  e1.printStackTrace();
                } finally {
                  e.printStackTrace();
                  finishKey(key, FILTERED);
                }
              } finally {
                iterator.remove();
              }
            }
          }
        } else {
          // Remove old/non-connected keys
          final long now = System.nanoTime();
          final Iterator<SelectionKey> iterator = selector.keys()
              .iterator();
          while (iterator.hasNext()) {
            final SelectionKey key = (SelectionKey) iterator.next();
            final Data data = (Data) key.attachment();
            if (data.state == OPEN && now - data.start > TIMEOUT_RW) {
              Log.e(TAG, "TIMEOUT=" + data.port);
              finishKey(key, TIMEOUT);
            } else if (data.state != OPEN
                && now - data.start > TIMEOUT_CONNECT) {
              finishKey(key, TIMEOUT);
            }
          }
        }
      }
    } catch (IOException e) {
      Log.e(TAG, e.getMessage());
    } finally {
      closeSelector();
    }
  }

  private void connectSocket(InetAddress ina, int port) {
    // Create the socket
    try {
      SocketChannel socket = SocketChannel.open();
      socket.configureBlocking(false);
      socket.connect(new InetSocketAddress(ina, port));
      Data data = new Data();
      data.port = port;
      data.start = System.nanoTime();
      socket.register(selector, SelectionKey.OP_CONNECT, data);
    } catch (IOException e) {
      Log.e(TAG, e.getMessage());
    }
  }

  protected void onCancelled() {
    select = false;
  }

  private void closeSelector() {
    try {
      if (selector.isOpen()) {
        synchronized (selector.keys()) {
          Iterator<SelectionKey> iterator = selector.keys()
              .iterator();
          while (iterator.hasNext()) {
            finishKey((SelectionKey) iterator.next(), FILTERED);
          }
          selector.close();
        }
      }
    } catch (IOException e) {
      Log.e(TAG, e.getMessage());
    } catch (ClosedSelectorException e) {
      if (e.getMessage() != null) {
        Log.e(TAG, e.getMessage());
      }
    }
  }

  private void finishKey(SelectionKey key, int state) {
    finishKey(key, state, null);
  }

  private void finishKey(SelectionKey key, int state, String banner) {
    synchronized (key) {
      if (key == null || !key.isValid()) {
        return;
      }
      closeChannel(key.channel());
      Data data = (Data) key.attachment();
      publishProgress(data.port, state, banner);
      key.attach(null);
      key.cancel();
      key = null;
    }
  }

  private void closeChannel(SelectableChannel channel) {
    if (channel instanceof SocketChannel) {
      Socket socket = ((SocketChannel) channel).socket();
      try {
        if (!socket.isInputShutdown())
          socket.shutdownInput();
      } catch (IOException ex) {
      }
      try {
        if (!socket.isOutputShutdown())
          socket.shutdownOutput();
      } catch (IOException ex) {
      }
      try {
        socket.close();
      } catch (IOException ex) {
      }
    }
    try {
      channel.close();
    } catch (IOException ex) {
    }
  }

  // Port private object
  private static class Data {
    protected int state = FILTERED;
    protected int port;
    protected long start;
    protected int pass = 0;
  }
}




Java Source Code List

info.lamatricexiste.network.AbstractDiscovery.java
info.lamatricexiste.network.ActivityDiscovery.java
info.lamatricexiste.network.ActivityMain.java
info.lamatricexiste.network.ActivityNet.java
info.lamatricexiste.network.ActivityPortscan.java
info.lamatricexiste.network.AsyncPortscan.java
info.lamatricexiste.network.DatabaseHelper.java
info.lamatricexiste.network.DefaultDiscovery.java
info.lamatricexiste.network.DiscoverActivity.java
info.lamatricexiste.network.DnsDiscovery.java
info.lamatricexiste.network.NetworkChange.java
info.lamatricexiste.network.Network.Banner.java
info.lamatricexiste.network.Network.DownloadFile.java
info.lamatricexiste.network.Network.HardwareAddress.java
info.lamatricexiste.network.Network.HostBean.java
info.lamatricexiste.network.Network.NetInfo.java
info.lamatricexiste.network.Network.OsFingerprint.java
info.lamatricexiste.network.Network.Ping.java
info.lamatricexiste.network.Network.RateControl.java
info.lamatricexiste.network.Network.SendSmbNegotiate.java
info.lamatricexiste.network.Utils.DbUpdate.java
info.lamatricexiste.network.Utils.Db.java
info.lamatricexiste.network.Utils.Export.java
info.lamatricexiste.network.Utils.Help.java
info.lamatricexiste.network.Utils.Prefs.java
info.lamatricexiste.network.Utils.Save.java
info.lamatricexiste.network.Utils.UpdateNicDb.java
info.lamatricexiste.network.connectivity.java
info.lamatricexiste.network.portscan.java
info.lamatricexiste.network.wifiinfo.java