javaandroidnsd

How to scan IP and Mac address of all Device Connected to wifi in android accurately?


Hi i am trying to find all devices connected to My WIFI Router from android and ,i need to device Mac address and local ip address of each device (Including iOT Devices) , right now , i am trying to find from ARP cache table . but sometime in the scan some devices are missing , it is not so accurate .

My Code :

 List<LocalDeviceInfo> devicesInfos = new ArrayList<>();


        BufferedReader bufferedReader = null;

        try {
            bufferedReader = new BufferedReader(new FileReader("/proc/net/arp"));

            String line;
            while ((line = bufferedReader.readLine()) != null) {
                String[] splitted = line.split(" +");
                if (splitted != null && splitted.length >= 4) {
                    String ip = splitted[0];
                    String mac = splitted[3];
                    if (mac.matches("..:..:..:..:..:..")) {
                        LocalDeviceInfo thisNode = new LocalDeviceInfo(ip, mac);
                        devicesInfos.add(thisNode);
                    }
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // Print Description
        for (LocalDeviceInfo devicesInfo :devicesInfos)
        {
            System.out.print("✅");
            System.out.println("IP : "+devicesInfo.getIp());
            System.out.println("Mac : "+devicesInfo.getMacAddress());
        }

How can i scan all devices (IP address and Mac address) in android accurately .



Solution

  • I found the solution of my problem , most of devices was not in the system arp table , so you need to Ping each of device at first time , once you ping that device its will be stored in System ARP Table Which is stored at (/proc/net/arp)

    Pinging All devices with ip: ( First you need to find your device's IP Address , than you can determine the subnet mask and you can start pining from (0-255)

    Code:

    public  void startPingService(Context context)
    {
      List<LocalDeviceInfo> deviceInfoList  = new ArrayList<LocalDeviceInfo>();
        try {
    
            WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            WifiInfo mWifiInfo = mWifiManager.getConnectionInfo();
            String subnet = getSubnetAddress(mWifiManager.getDhcpInfo().gateway);
    
    
            for (int i=1;i<255;i++){
    
                String host = subnet + "." + i;
    
                if (InetAddress.getByName(host).isReachable(timeout)){
    
                    String strMacAddress = getMacAddressFromIP(host);
    
                    Log.w("DeviceDiscovery", "Reachable Host: " + String.valueOf(host) +" and Mac : "+strMacAddress+" is reachable!");
    
                        LocalDeviceInfo localDeviceInfo = new LocalDeviceInfo(host,strMacAddress);
                        deviceInfoList.add(localDeviceInfo);
                 }
                else
                {
                    Log.e("DeviceDiscovery", "❌ Not Reachable Host: " + String.valueOf(host));
    
                }
            }
    
    
        }
        catch(Exception e){
            //System.out.println(e);
        }
    
    
    }
    
    
    private String getSubnetAddress(int address)
    {
        String ipString = String.format(
                "%d.%d.%d",
                (address & 0xff),
                (address >> 8 & 0xff),
                (address >> 16 & 0xff));
    
        return ipString;
    }
    

    Get Mac address from ARP cache Table

    public String getMacAddressFromIP(@NonNull String ipFinding)
    {
    
        Log.i("IPScanning","Scan was started!");
        List<LocalDeviceInfo> antarDevicesInfos = new ArrayList<>();
    
    
        BufferedReader bufferedReader = null;
    
        try {
            bufferedReader = new BufferedReader(new FileReader("/proc/net/arp"));
    
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                String[] splitted = line.split(" +");
                if (splitted != null && splitted.length >= 4) {
                    String ip = splitted[0];
                    String mac = splitted[3];
                    if (mac.matches("..:..:..:..:..:..")) {
    
                        if (ip.equalsIgnoreCase(ipFinding))
                        {
                            return mac;
                        }
                    }
                }
            }
    
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        return "00:00:00:00";
    }
    

    You need these permission too:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />