完全自動な在室状況確認システム

この記事は[DeNA 24 新卒 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/dena-24-newgrad)の５日目の記事です．
同期の皆さんが素晴らしい記事を書いてくださっているので，ぜひチェックしてみてください！

# はじめに

研究室内で，どの部屋に誰がいるのか，いつでもどこからでも確認できるようにしたい．でも，入退室のたびに，自分の在室状況を変更するような手間は絶対に許容できない．
このモチベーションに従って，完全自動な在室状況確認システムを構築しました．

この記事では，システムのうち，在室状況（どの部屋に，誰がいるのか）を完全自動で更新する方法に焦点を当てて，知見を共有します．

基本的なアイデア
- [前提条件] 対象の部屋でLAN(Wi-Fiなど)を利用しており，ユーザーが自身の端末（スマホやPCなど）をそのLANに接続している．
- LANに接続された端末の一覧を取得できれば，端末の持ち主であるメンバーの在室状況を取得できそう！

実現方法
- LANに接続された端末の一覧を取得．
→ [ARPを利用した接続中端末の取得](#arpを利用した接続中端末の取得)
- 端末の持ち主の特定．
→ [端末と名簿の突合](#端末と名簿の突合)

# ARPを利用した接続中端末の取得
MACアドレスとは，パソコンやスマートフォンなどのネットワーク機器に対して，（原則として）一意に割り当てられる識別子のことです．
つまり，LANに接続されている端末の一覧を取得するためには，MACアドレスの一覧を取得できれば良いことになります．

[arp-scanコマンド](https://github.com/royhills/arp-scan)を利用すると，接続されている機器のMACアドレスのリストを簡単に取得することができます．

```
$ sudo arp-scan -l
Interface: en0, type: EN10MB, MAC: 00:11:22:33:44:55, IPv4: 192.168.1.100
Starting arp-scan 1.9.8 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.1.1	00:11:aa:bb:cc:dd	ExampleCorp Inc.
192.168.1.2	11:22:aa:bb:cc:dd	ExampleNet Co.
192.168.1.10	22:33:aa:bb:cc:dd	ExamplePrinters Ltd.
192.168.1.20	33:44:aa:bb:cc:dd	ExampleTech Inc.
192.168.1.105	44:55:aa:bb:cc:dd	ExampleDevices LLC.
192.168.1.150	55:66:aa:bb:cc:dd	ExampleMobile Inc.
192.168.1.160	66:77:aa:bb:cc:dd	(Unknown: locally administered)

500 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.8: 256 hosts scanned in 2.000 seconds (128.00 hosts/sec). 7 responded
```

以下のコマンドを実行すると，MACアドレスのみを抽出することができます．
```
$ sudo arp-scan -l | grep '^192' | awk '{ print $2 }'
00:11:aa:bb:cc:dd
11:22:aa:bb:cc:dd
22:33:aa:bb:cc:dd
33:44:aa:bb:cc:dd
44:55:aa:bb:cc:dd
55:66:aa:bb:cc:dd
66:77:aa:bb:cc:dd
```

## ARP
> Address Resolution Protocol (アドレス解決プロトコル、略称：ARP、アープ)は、与えられたインターネット層アドレス（一般的にはIPv4アドレス）に対応するリンク層アドレス（MACアドレスなど）を発見するために使用される通信プロトコルである。
> https://ja.wikipedia.org/wiki/Address_Resolution_Protocol

ARPとは上記のような通信プロトコルです．

> arp-scan is a network scanning tool that uses the ARP protocol to discover and fingerprint IPv4 hosts on the local network. It is available for Linux, BSD, macOS and Solaris under the GPLv3 licence.
> （和訳）[arp-scanコマンド](https://github.com/royhills/arp-scan)は，このARP(Address Resolution Protocol)を利用して，ローカルネットワーク上のIPv4ホストを発見し，識別するネットワークスキャニングツールです．GPLv3ライセンスの下で，Linux，BSD，macOS，Solarisで利用できます．
> https://github.com/royhills/arp-scan

このように，`arp-scan`コマンドは，ARP上で実行されるツールです．
したがって，`arp-scan`を利用せずに，ARPリクエストを直接実行することもできるということを補足しておきます．

# 端末と名簿の突合

端末（MACアドレス）と人物の対応表を事前に作成しておきます．
この対応表と，接続中のMACアドレスのリストを突合することで，在室状況を得ることができます．

```mermaid
graph LR
    subgraph 接続中のMACアドレス
        A["00:11:aa:bb:cc:dd"]
        B["11:22:aa:bb:cc:dd"]
        C["22:33:aa:bb:cc:dd"]
        D["44:55:aa:bb:cc:dd"]
    end

    subgraph 名簿
        C1["22:33:aa:bb:cc:dd→シンジ"]
        G1["33:44:aa:bb:cc:dd→レイ"] 
        D1["44:55:aa:bb:cc:dd→アスカ"]
        G2["33:44:aa:bb:cc:dd→マリ"]
    end

    subgraph ステータス
        Present[在室]
        Absent[不在]
    end

    C --> C1
    D --> D1
    C1 --> Present
    D1 --> Present
    G1 --> Absent
    G2 --> Absent
```

## プライベートWi-Fiアドレス

システムを構築する際，プライベートWi-Fiアドレスに注意する必要があります．

> iOS 14、iPadOS 14、watchOS 7 以降では、プライバシー対策を強化するため、Wi-Fi ネットワークごとに違う MAC アドレスを使い分けます。この一意の MAC アドレスは、デバイスがそのネットワークに限って使うプライベートな Wi-Fi アドレスとなります。
[iPhone、iPad、iPod touch、Apple Watch でプライベート Wi-Fi アドレスを使う](https://support.apple.com/ja-jp/102509)

このように，ネットワークごとに異なるMACアドレスが付与される場合があります．

そのため，複数のネットワークにまたがって在室状況を管理する場合は，同じ端末に対して複数のMACアドレスを紐付けられるようにする必要があります．

# 実際に作ったもの

ブラウザから，誰がどの部屋にいるのかを確認することができます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478527/bab64e1e-4696-88db-272f-487479a267a2.png)

MACアドレスの登録も可能です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478527/8097e5fa-9669-7f85-2f8e-a1d3739f9da9.png)

# 注意点
- `arp-scan`はネットワークに負荷をかける可能性があります．在室状況を更新する頻度には気をつけましょう．
- 他人の在室状況を取得する場合は，しっかりと同意を取りましょう．
- 在室状況はセンシティブな情報なので，インターネットに公開する場合は注意しましょう（メンバーしか見れないようにするなど）．

# まとめ

- ARPを利用してネットワークに接続されたMACアドレスを取得できる．
- MACアドレスと名簿を突合すれば，在室状況を構築できる．

# おわりに

在室状況確認システムとしては，今回の方法以外にも様々な方法が考えられるので，目的と状況に応じて最適なものを選択できると良いですね．
例：
- 名前とステータス（在室，帰宅，会議中など）を書いた表を用意して，自身のステータスに対応する場所に磁石を貼る．
- 打刻システムを利用し，アプリケーション上で入室時と退室時にボタンを押す．
- 部屋にNFCカードリーダーを設置し，入室時と退室時にカードをタッチする．

明日以降も [DeNA 24 新卒 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/dena-24-newgrad) は続きます．
引き続き，お楽しみに！

最後までお付き合いいただきありがとうございました！

# 関連記事
[在室管理を自動化する](https://qiita.com/taigak/items/db64baa0701457adedb0)
[Wifi打刻の話](https://qiita.com/utisam/items/7ba65bd84c911faaad79)

# 参考
[TCP/IPの絵本 ネットワークが面白くなる9つの扉](https://www.amazon.co.jp/TCP-IP%E3%81%AE%E7%B5%B5%E6%9C%AC-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%8C%E9%9D%A2%E7%99%BD%E3%81%8F%E3%81%AA%E3%82%8B9%E3%81%A4%E3%81%AE%E6%89%89-%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%82%A2%E3%83%B3%E3%82%AF-ebook/dp/B00O22XG80/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=34EZ6N41FGOYB&keywords=TCP%2FIP%E3%81%AE%E7%B5%B5%E6%9C%AC&qid=1701757122&s=books&sprefix=tcp%2Fip%E3%81%AE%E7%B5%B5%E6%9C%AC+%2Cstripbooks%2C199&sr=1-2)
[TCP/IPネットワーク管理](https://www.amazon.co.jp/TCP-IP%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E7%AE%A1%E7%90%86-%E3%82%AF%E3%83%AC%E3%82%A4%E3%82%B0-%E3%83%8F%E3%83%B3%E3%83%88/dp/4873111293/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1HIMKZHBVAMFN&keywords=TCP%2FIP+%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E7%AE%A1%E7%90%86&qid=1701757154&s=books&sprefix=tcp%2Fip+%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E7%AE%A1%E7%90%86%2Cstripbooks%2C160&sr=1-1)
https://github.com/royhills/arp-scan
https://ja.wikipedia.org/wiki/Address_Resolution_Protocol