tcpdumpでping要求をみる

# はじめに
`tcpdump`に触る機会があったので、色々と見てみようかと思いここにまとめておきます…

# 環境

[前の記事](https://qiita.com/hashito/items/454abe1f474766b06e78)で作成したdocker環境を流用して、2つのPC間の通信を見てみたいと思います。

*実際には片方のコンテナにアタッチして仮想ネットワーク内の通信を除く感じでやっていきます。*

# インストール
下記のコマンドで簡単に入ります…
＊`MAC`とかは標準で入っているみたいですね。

```sh
apt install tcpdump
```

## コマンド
`tcpdump`のコマンドは結構単純でネットワーク上のTCPプロトコルをみること、ファイルに書き込むことしか出来ない様子。

```
tcpdump -i eth0
```
*この場合はインターフェイスを`eth0`に規定しています


# 試してみる
## ping
片方のコンテナにアタッチして、中から`ping`要求を出してみます。

```sh:コンテナA
ifconfig
#eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
#        inet 172.19.0.2  netmask 255.255.0.0  broadcast 172.19.255.255
#        ether 02:42:ac:13:00:02  txqueuelen 0  (Ethernet)
#        RX packets 410  bytes 528949 (528.9 KB)
#        RX errors 0  dropped 0  overruns 0  frame 0
#        TX packets 241  bytes 14126 (14.1 KB)
#        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
#
#lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
#        inet 127.0.0.1  netmask 255.0.0.0
#        loop  txqueuelen 1  (Local Loopback)
#        RX packets 12  bytes 1126 (1.1 KB)
#        RX errors 0  dropped 0  overruns 0  frame 0
#        TX packets 12  bytes 1126 (1.1 KB)
#        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
tcpdump -i eth0
#....
```

```sh:コンテナB
ping 172.19.0.2 -c 1
#64 bytes from 172.19.0.2: icmp_seq=1 ttl=64 time=0.181 ms
```

```sh:コンテナA
#00:59:06.976543 IP 666c78f910c9.pinet > 7bfa751bb19e: ICMP echo request, id 12, seq 1, length 64
#00:59:06.976594 IP 7bfa751bb19e > 666c78f910c9.pinet: ICMP echo reply, id 12, seq 1, length 64
```

**うん…分からない…**

### 内容を読み解く

1行目のメッセージを見てみましょう。

```sh
00:59:06.976543      # 時間
IP                   # IP or IPv6
666c78f910c9.pinet > # 送り元？
7bfa751bb19e:        # 送り先？
ICMP                 # pingはicmpってプロトコル使っていると聞いたことが…
echo                 # ここからデータかな？
request,             # コマンド内容？
id 12,               # id...
seq 1,               # シーケンス1
length 64            # データ長?
```

[tcpdumpの使い方](https://qiita.com/drafts/124d48d0b7e652b977bb/edit)
を参考にさせていただくと、どうやらコマンドでもう少し見やすく出来るっぽい…

記事を参考に下記の2つのオプションを付与してみます。

```
-nn アドレスやポート番号を名前に変換しないで表示します。
```

```sh:コンテナA
06:35:15.821137 IP 172.19.0.3 > 172.19.0.2: ICMP echo request, id 12, seq 1, length 64
06:35:15.821207 IP 172.19.0.2 > 172.19.0.3: ICMP echo reply, id 12, seq 1, length 64
```

これで、何となくですが下記のような通信が見えてきました。

1. `172.19.0.3`(コンテナB)が`172.19.0.2`(コンテナA)に`ICMP`の`echo request`コマンドを発行
2. `172.19.0.2`(コンテナA)が`172.19.0.3`(コンテナB)に`ICMP`の`echo reply`コマンドを発行

[Internet Control Message Protocol(Wikipedia)](https://ja.wikipedia.org/wiki/Internet_Control_Message_Protocol#%E9%80%9A%E7%9F%A5%E3%81%AE%E7%A8%AE%E9%A1%9E)によるとICMPに規定されている通信の種類がいくつかあり、`0 - Echo Reply Message`と`8 - Echo Message`の二種類を利用して通信しているっぽい…


# その他
これを試しているときに、別のコマンドが入ったので少し調べてみました。

## arp
有名なARPってやつですね…

```sh:コンテナA
08:46:03.348573 ARP, Request who-has 172.19.0.3 tell 172.19.0.2, length 28
08:46:03.348599 ARP, Reply 172.19.0.3 is-at 02:42:ac:13:00:03, length 28
```

1. `arp`で`172.19.0.3`の`MAC Addres`を`172.19.0.2`が聞く
2. `arp`で`172.19.0.3`の`MAC Addres`で`02:42:ac:13:00:03`であることが解答される

という感じっぽいです。

## Router Advertisement

こちらは、IPv6でアドレスを自動決定するときに利用するプロトコルらしいです…
IPv6ではDHCPとは違う仕組みでアドレスを決定するようですね。

```sh
08:46:35.515383 IP6 fe80::a477:c6ff:fe0c:1892 > ff02::2: ICMP6, router solicitation, length 16
```