Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android subnet scan

In my application I need to scan the local subnet (192.168.1.*) to collect the list of MAC addresses of all connected devices.

I currently use the following strategy:

  1. start simultaneously 255 ping commands with Runtime.exec("ping -c 1 <addr>")
  2. use waitFor() on each of the returned process to collect the exit code
  3. close input streams of processes and destroy them
  4. read the /proc/net/arp file and parse the MAC addresses

In most cases, this works very well and provides a fast scan.

But on some devices (such as android 1.5, and sometimes on >=4.0), the execution gets stuck at process creation (after a few ones have been successfully started) and there's no way to kill the running thread.

Do you see anything I could try to solve this issue? Or any other strategy that would not take too long?

like image 249
sdabet Avatar asked Feb 21 '23 18:02

sdabet


1 Answers

This can be solved by using a pool of thread running the INetAddress.isReachable() method (instead of running the ping command in native processes).

private static final int NB_THREADS = 10;

public void doScan() {
    Log.i(LOG_TAG, "Start scanning");

    ExecutorService executor = Executors.newFixedThreadPool(NB_THREADS);
    for(int dest=0; dest<255; dest++) {
        String host = "192.168.1." + dest;
        executor.execute(pingRunnable(host));
    }

    Log.i(LOG_TAG, "Waiting for executor to terminate...");
    executor.shutdown();
    try { executor.awaitTermination(60*1000, TimeUnit.MILLISECONDS); } catch (InterruptedException ignored) { }

    Log.i(LOG_TAG, "Scan finished");
}

private Runnable pingRunnable(final String host) {
    return new Runnable() {
        public void run() {
            Log.d(LOG_TAG, "Pinging " + host + "...");
            try {
                InetAddress inet = InetAddress.getByName(host);
                boolean reachable = inet.isReachable(1000);
                Log.d(LOG_TAG, "=> Result: " + (reachable ? "reachable" : "not reachable"));
            } catch (UnknownHostException e) {
                Log.e(LOG_TAG, "Not found", e);
            } catch (IOException e) {
                Log.e(LOG_TAG, "IO Error", e);
            }
        }
    };
}
like image 188
sdabet Avatar answered Mar 06 '23 16:03

sdabet