Macの無線NICでハマった話

## 経緯
先日、友人とともに少人数で使用するネットワークを構築しました。
その際にMacBookの無線NICで、デフォルトゲートウェイより外側の機器と通信が行えないというトラブルがありました。
あまり情報がなかったので参考として載せておきます。

## 環境
トポ図（実際の環境よりも省略しています）
![topology.png](https://qiita-image-store.s3.amazonaws.com/0/223892/e0416ff1-6468-1f87-6de3-b454caff69f3.png)
サーバセグメントにアクセスするために、上記のようなクライアントのセグメントを作成しました。

- クライントは、スイッチから有線もしくはAPから無線でネットワークに参加
- クライアントはルータで動作しているDHCPサーバから自身のIPアドレスとデフォルゲートウェイのIPアドレスを取得

クライアントはMacBookシリーズとWindowsのノートパソコンがあります。

### ネットワーク機器

- ルータ : 891FJ, IOS 15.4(3)M1
- AP : Aironet 1702i, IOS 15.3(3)JD4
- スイッチ : Catalyst 2960L, IOS 15.2(6)E

### クライアント
- MacBook Retina, 12-inch, Early 2015, MacOS Mojave(ver10.14) 
- MacBook Pro Retina, 13-inch, Late 2013, MacOS High Sierra(ver10.13.6) 
- ThinkPad T460s, Windows 10(ver1803) 


※トラブル解決後に以下のデバイスでもテストしましたので掲載します。

- iPhone 7, iOS 12.0.1
- Nexus 5, Android 6.0.1

## トラブル
クライアントからサーバへ通信のテストを行った際に、Macの無線のみサーバと通信を行うことができませんでした。
`ping`での疎通確認の結果は以下の通りです。

| 端末 | 接続方法 | サーバとの疎通 |
| --- | --- | --- |
| Thinkpad | 有線 | ◯ |
| 〃 | 無線 | ◯ |
| MacBookシリーズ | 有線 | ◯ |
| 〃 | 無線 | × |
| iPhone | 無線 | × |
| Nexus | 無線 | ○ |

有線NICは今回使用したMacBookシリーズには内蔵されていないので、外付けのものを使用しました。
通信が失敗した際の出力は以下のようになります。

```terminal:無線接続時疎通テスト１
~ ❯❯❯ ping 192.168.1.35 -c 5                                                                                                                                                                                                                                                                     ⏎
PING 192.168.1.35 (192.168.1.35): 56 data bytes
ping: sendto: No route to host
ping: sendto: No route to host
Request timeout for icmp_seq 0
ping: sendto: No route to host
Request timeout for icmp_seq 1
ping: sendto: No route to host
Request timeout for icmp_seq 2
ping: sendto: No route to host
Request timeout for icmp_seq 3

--- 192.168.1.35 ping statistics ---
5 packets transmitted, 0 packets received, 100.0% packet loss
```
なぜ`No route to host`なんだ...。

※省略していますが、サーバと疎通が行えなかった2つの条件においてデフォルトゲートウェイへの`ping`は行えました。

## いろいろ調べてみる
宛先までの経路情報がないとのことなので、Macのルーティングテーブルを確認してみます。

```terminal:無線接続時経路情報１
~ ❯❯❯ netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            192.168.0.254      UGScI           6        0     en0
127                127.0.0.1          UCS             0        0     lo0
~~ 省略 ~~
```

デフォルトゲートウェイの情報は存在しているので問題はないように見えます。
有線接続時のルーティングテーブルと比較してみることにしました。

```terminal:有線接続時経路情報
~ ❯❯❯ netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            192.168.0.254      UGSc           67        0     en4
127                127.0.0.1          UCS             0        0     lo0
~~ 省略 ~~
```

2つを見比べるとデフォルトゲートウェイのフラグが異なっています。無線接続時には`I`のフラグが付与されていました。
`man netstat`で`I`フラグの説明を見てみます。
>I　　　RTF_IFSCOPE　　　Route is associated with an interface scope
> A route which is marked with the RTF_IFSCOPE flag is instantiated for the corresponding interface.


`Interface Scope`という意味は調べてもわかりませんでした（ごめんなさい）。インターフェースを指定すれば参照するが、そうでない場合は参照しないということでしょうか。`Global Scope`などのスコープとは別の意味？
試しに`ping`でインターフェースを指定してみると通信が行えました。

```terminal:無線接続時疎通テスト(インターフェース指定)
~ ❯❯❯ ping 192.168.1.35 -c 5 -b en0                                                                                                                                                                                                                                                              ⏎
PING 192.168.1.35 (192.168.1.35): 56 data bytes
64 bytes from 192.168.1.35: icmp_seq=0 ttl=62 time=3.540 ms
64 bytes from 192.168.1.35: icmp_seq=1 ttl=62 time=3.520 ms
64 bytes from 192.168.1.35: icmp_seq=2 ttl=62 time=3.757 ms
64 bytes from 192.168.1.35: icmp_seq=3 ttl=62 time=3.703 ms
64 bytes from 192.168.1.35: icmp_seq=4 ttl=62 time=3.476 ms

```
これだけでもかなり嬉しかったのですが、根本的な解決にはなっていないので更に情報を探します。

## 解決策
情報を探していると以下のようなページを発見しました。
https://forum.turris.cz/t/solved-guest-network-for-airport-extreme-vlan-1003/1708/13

もしかしたらDNSサーバの情報がないとMacOSが不完全な経路情報とみなして`I`フラグをつけるのかもしれない...？
実は、今回構築したネットワークではIPアドレスでのアクセスを前提としていたのでDNSサーバの情報はDHCPで配布していませんでした。
しかし有線接続時は疎通ができているので、DHCPサーバの情報には問題ないでしょうという気持ち。
打つ手もないので試しにDNSサーバの情報を配布しました。
すると...

```terminal:無線接続時経路情報２
~ ❯❯❯ cat /etc/resolv.conf | grep -v '#'                                                                                                                                                                                                                                                         ⏎
nameserver 192.168.0.254
~ ❯❯❯ netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            192.168.0.254      UGSc          193        0     en0
127                127.0.0.1          UCS             0        0     lo0
~~ 省略 ~~
```
`I`フラグが消えた！？
ということは...

```terminal:無線接続時疎通テスト２
~ ❯❯❯ ping 192.168.1.35 -c 5
PING 172.31.20.35 (172.31.20.35): 56 data bytes
64 bytes from 192.168.1.35: icmp_seq=0 ttl=62 time=3.851 ms
64 bytes from 192.168.1.35: icmp_seq=1 ttl=62 time=2.130 ms
64 bytes from 192.168.1.35: icmp_seq=2 ttl=62 time=1.989 ms
64 bytes from 192.168.1.35: icmp_seq=3 ttl=62 time=3.527 ms
64 bytes from 192.168.1.35: icmp_seq=4 ttl=62 time=3.758 ms

--- 172.31.20.35 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.989/3.051/3.851/0.818 ms
```
おお、通信できた！！
しかし有線では通信できたのになぜ無線ではだめだったんだろう。



## まとめ
### Macが無線で参加するネットワークにおいて、DHCPサーバを使用する時はDNSサーバの情報を配布しましょう。

理由はどうあれDNSサーバの情報が存在しないことが原因だったみたいなので。
こんな仕様があったとは...。
iPhoneも同様の結果になったのでApple製品の仕様なのかもしれません。
解決はしたけど有線接続時に通信が行えることに疑問が残る(´・ω・｀)