web-dev-qa-db-ja.com

Androidでwifiに接続されているすべてのデバイスのIPおよびMacアドレスを正確にスキャンする方法は?

こんにちは私はAndroidから私のWIFIルーターに接続されているすべてのデバイスを見つけようとしています、そして、私は各デバイス(iOTデバイスを含む)のMacアドレスとローカルIPアドレスをデバイスにする必要があります)、今、私はARPキャッシュテーブルから検索しようとしていますが、スキャン中に一部のデバイスが見つからない場合は、それほど正確ではありません。

マイコード:

 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());
        }

Android)ですべてのデバイス(IPアドレスとMacアドレス)を正確にスキャンするにはどうすればよいですか。


10
Dhiru

私は私の問題の解決策を見つけました、ほとんどのデバイスはシステムのarpテーブルにありませんでした。そのため、最初に各デバイスにpingを実行する必要があります。デバイスにpingを実行すると、デバイスは_(/proc/net/arp)_

Ipを使用してすべてのデバイスをpingします:(まず、デバイスのIPアドレスを見つける必要があります。サブネットマスクを特定し、(0-255)からピン接続を開始できます。

コード:

_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;
}
_

ARPキャッシュテーブルからMacアドレスを取得します

_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";
}
_

これらの許可も必要です:

_<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" />
_
10
Dhiru

実際には、デバイスのネットワークのブロードキャストアドレスにpingを送信するだけで、ICMP ECHO要求がネットワーク上のすべてのマシンに送信されます。個別にpingする必要はありません。一方、一部のデバイスは、「セキュリティ対策」として、このようなpingに応答しません。それはあなた次第です。

次に、他の回答のコードが行うことを実行します-解析/proc/net/arp ARPキャッシュが含まれています。 procfs内のその特別なファイルから、ネットワーク内のネットワークデバイスのMACアドレスがわかります。 (これを他の回答へのコメントとして追加する評判がまだないため、これを回答として投稿します)