ローカルネットに接続されている機器のIPアドレスを調べる方法

## ポイント
* pingのブロードキャストでは、すぐには調べられない
  * 回数を重ねても応答しない機器が多かった
* pingでアドレス指定でスキャンすると応答が得られやすい
  * IPアドレスを生成して網羅的にpingしてみる
* sleepしている機器からは応答が返らない場合がある

## IPアドレスを生成してping
ネットワークアドレスは`ipconfig /all`や`ip address`などで調べます。
一般的な家庭内のネットワークでは、ほとんどが下記のようなサブネットになっていると思います。
`サブネット マスク . . . . . . . . . .: 255.255.255.0`
この場合は、自分のIPアドレスの最後の数字を省いたものがネットワークアドレスのベースになります。
最後にピリオド(`.`)を付けた文字列を環境変数に設定しておきます。
以降の例では環境変数に設定する文字列を`123.234.56.`としています。
探索するアドレス範囲は、適切に設定してください。
例では、サブアドレス`1`がルーターなので、2から20までを探索しています。最大の254までだと時間がかかるので、調査範囲は自分のアドレス付近に限定しておくと時短になります。
### Windows コマンドシェル(cmd)
```batch
C:>set net=123.234.56.

C:>for /l %i in (2,1,20) do @ping -w 100 -n 1 %net%%i | findstr =32

C:>arp -a | findstr /c:"  %net%"
```

### Windows PowerShell
```powershell
PS > $net='123.234.56.'
PS > @(2..20) | %{ping -w 100 -n 1 -4 $net$_} | sls =32

PS > Get-NetNeighbor | sort {$_.IPAddress -As [Version]}| oss | sls -SimpleMatch $net | sls -NotMatch Unr
```

### WSL bash
```bash
$ net=123.234.56.
$ for i in {2..20}; do ping -W 1 -c 1 $net$i | grep ttl; done

$ arp.exe -a | grep -F "  $net"
```
## 試したこと
主にWSLのbashにて試しました。IPアドレスとMACアドレスはマスクした結果を示します。
### arpのキャッシュクリア
arpのキャッシュは一定時間でクリアされるようですが、調査を開始するときには明示的にクリアしておいた方が良いと思います。
* Windowsの管理者で下記コマンドを実行
  `arp -d *`
### ネットワークアドレスの設定
```bash
$ net=123.234.56.
```

### aprの実行(キャッシュクリア直後)
```bash
$ arp.exe -a | grep -F "  $net" | sed -E 's/([0-9a-f]{2}-){5}[0-9a-f]{2}/xx-xx-xx-xx-xx-xx/' | sed "s/$net/123.234.56./
"
  123.234.56.1           xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.255         xx-xx-xx-xx-xx-xx     static
```
### pingによるブロードキャスト(20回)後にarp実行
```bash
$ time (ping -c 20 ${net}255 | sed "s/$net/123.234.56./g")
PING 123.234.56.255 (123.234.56.255) 56(84) bytes of data.

--- 123.234.56.255 ping statistics ---
20 packets transmitted, 0 received, 100% packet loss, time 1004ms


real    0m11.058s
user    0m0.000s
sys     0m0.047s
$ arp.exe -a | grep -F "  $net" | sed -E 's/([0-9a-f]{2}-){5}[0-9a-f]{2}/xx-xx-xx-xx-xx-xx/' | sed "s/$net/123.234.56./
"
  123.234.56.1           xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.255         xx-xx-xx-xx-xx-xx     static
```
### pingによるブロードキャスト(100回)後にarp実行
```bash
$ time (ping -c 100 ${net}255 | sed "s/$net/123.234.56./g")
PING 123.234.56.255 (123.234.56.255) 56(84) bytes of data.

--- 123.234.56.255 ping statistics ---
100 packets transmitted, 0 received, 100% packet loss, time 99501ms


real    1m49.548s
user    0m0.016s
sys     0m0.047s
$ arp.exe -a | grep -F "  $net" | sed -E 's/([0-9a-f]{2}-){5}[0-9a-f]{2}/xx-xx-xx-xx-xx-xx/' | sed "s/$net/123.234.56./
  123.234.56.1           xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.10          xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.255         xx-xx-xx-xx-xx-xx     static
```
* 合計120回、2分半以上かかって、画面を消してスリープしているスマホ1台がやっと応答しました。
* **ブロードキャストで調べるのはイマイチ。**
### 各アドレス(2～20)に対してping
```bash
$ time (for i in {2..20}; do ping -W 1 -c 1 $net$i | grep ttl | sed "s/$net/123.234.56./"; done)
64 bytes from 123.234.56.4: icmp_seq=1 ttl=64 time=18.0 ms
64 bytes from 123.234.56.6: icmp_seq=1 ttl=128 time=0.404 ms
64 bytes from 123.234.56.8: icmp_seq=1 ttl=64 time=5.55 ms
64 bytes from 123.234.56.13: icmp_seq=1 ttl=64 time=122 ms
64 bytes from 123.234.56.15: icmp_seq=1 ttl=128 time=3.07 ms
64 bytes from 123.234.56.18: icmp_seq=1 ttl=64 time=119 ms
64 bytes from 123.234.56.19: icmp_seq=1 ttl=64 time=4.57 ms

real    0m44.905s
user    0m0.063s
sys     0m0.563s
```
* 約45秒で多くの機器から反応がありましたが、**通常Sleepしている機器は、1回(`-c 1`)では応答を返さない**傾向があるようです。
* 目的の機器が見つからなかった場合は、pingのパラメータを変更してみてください。

### 全アドレス(2～254)に対してping
```bash
$ time (for i in {2..254}; do ping -W 1 -c 1 $net$i | grep ttl | sed "s/$net/123.234.56./"; done)
64 bytes from 123.234.56.4: icmp_seq=1 ttl=64 time=18.0 ms
64 bytes from 123.234.56.6: icmp_seq=1 ttl=128 time=0.404 ms
64 bytes from 123.234.56.8: icmp_seq=1 ttl=64 time=5.55 ms
64 bytes from 123.234.56.13: icmp_seq=1 ttl=64 time=122 ms
64 bytes from 123.234.56.15: icmp_seq=1 ttl=128 time=3.07 ms
64 bytes from 123.234.56.18: icmp_seq=1 ttl=64 time=119 ms
64 bytes from 123.234.56.19: icmp_seq=1 ttl=64 time=4.57 ms

real    16m22.717s
user    0m0.422s
sys     0m6.922s
```
* 16分以上かかりましたが、応答する機器に変化はありませんでした。
* 自分で設置した機器を探す目的の場合は、全アドレスをスキャンせずに、当たりを付けて探索した方が良さそうです。

### これまでのIP利用履歴をチェック
通常Sleepしている端末を含めて調べる場合は、pingのスキャンを時間をおいて数回繰り返し、その後にarpで履歴をチェックします。
* 例：
```bash
$ arp.exe -a | grep -F "  $net" | sed -E 's/([0-9a-f]{2}-){5}[0-9a-f]{2}/xx-xx-xx-xx-xx-xx/' | sed "s/$net/123.234.56./"
  123.234.56.1           xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.2           xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.4           xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.8           xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.10          xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.12          xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.13          xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.15          xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.16          xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.18          xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.19          xx-xx-xx-xx-xx-xx     dynamic
  123.234.56.255         xx-xx-xx-xx-xx-xx     static
```

### 試行環境
* Windows Home 21H2, 22H2
* PowerShell 5.1
* WSL1 (Ubuntu 18.04, 20.04)

```
OS 名:                  Microsoft Windows 10 Home
OS バージョン:          10.0.19044 N/A ビルド 19044
PSVersion:              5.1.19041.1682

  NAME            STATE           VERSION
* Ubuntu-18.04    Running         1
```

## 注意事項
本来は、IPアドレスは機器の設定で調べるべきです。しかし、今回はDHCP環境でWi-Fiコンバータ経由でボードPCの有線ポートに接続したので、外部から調べる必要がありました。機器の中には、DHCPのリース期間を無視するものや、arpへの問い合わせに対して誤った情報を返すものがあるので、注意が必要です。`arp -a`で得られるのは、あくまでも参考情報です。過信は禁物。
* DHCPのリース期間中に調べ切らないと、調査途中でアドレスが変わってしまう可能性があります。(古いメモなどに注意)

## 補足 (2024/1/27)
pingしたって応答しない機器があるから無駄だと思っていませんか? ICMPの応答が返らなくても、ARPキャッシュ(テーブル)は更新されます。実際に試してみてください。

## 更新情報 (2023/8/22)
* pingの結果フィルタリングの文字列を`from`から`ttl`に変更
  (日本語環境対応)
* 動作確認環境を追加
  (Windows 10 22H2、Ubuntu 20.04)