パケットはどのようにして目的地まで届けられるの？

## どのような仕組みでデータを目的地まで送り届けるのか？
TCP担当部分が通信相手とやり取りするとき、IP担当部分に依頼して、データをパケットにして送信してもらいますが、そのパケットはどのようにして通信相手に届くのでしょうか。

今回は、IP担当部分がどのようにしてパケットを相手に届けているかについてまとめてみます。

## これは何の記事か？

プログラミングしか学んでこなかったエンジニアが本を参考に、パケットが通信相手に届けられる仕組みについて大まかにまとめた記事です。

**対象読者**

- プログラミングしか学んでこなかった
- `IP`ってなんですか？？
- `ARP`って何ですか？？
- `ICMP`って何ですか？？
- `ルータ`や`ハブ`の役割がわからない

## この記事のゴール
パケットがどのようにして通信相手に届くかを大まかに説明できる。

## データがサーバに届く大まかな流れ
まずは全体像をイメージしやすいように、データを届ける際の大まかな流れからまとめます。

※ クライアントがWebサーバにリクエスト・メッセージを送信する例を前提にしています

![network-パケットを運ぶ仕組み.png](https://qiita-image-store.s3.amazonaws.com/0/186009/80b8b07f-602c-9b7a-a253-0c0f339b6b61.png)

クライアントでリクエスト・メッセージが作成され、TCPによってデータにTCPヘッダーがつけられた後、TCP担当部分はIP担当部分に依頼してデータを送信してもらいます。

依頼を受けたIP担当部分は渡されたデータに、宛先となるWebサーバのIPアドレスを記載したIPヘッダーをつけます。これで宛先が明示的になります。

![network-IPパケット.png](https://qiita-image-store.s3.amazonaws.com/0/186009/0ea0a314-42a9-693b-d62d-18668b56c8f6.png)

そして、Webサーバに届けるために経由するべき次のルータを経路表（ルーティング・テーブル）を使って探し出します。ルータを見つけたら、そのルータのMACアドレスを調べ、それをMACヘッダーに記載します。

![network-イーサネットのパケット.png](https://qiita-image-store.s3.amazonaws.com/0/186009/48d5c3fb-9e6e-a224-49e9-ebae8fb9d251.png)

作成されたパケットを送信すると、イーサネットの仕組みによって動くハブに届きます。ハブはMACヘッダーに書かれている情報をMACアドレス・テーブルと付き合わせて、次のルータにデータを届けます。

データを受け取ったルータは、IPヘッダーに書かれている情報を経路表（ルーティング・テーブル）と付き合わせて、経由すべき次のルータを特定します。

これが繰り返されることでWebサーバにデータが届くという仕組みになっています。

## 次のルータを特定する仕組み
クライアントやルータが、経由すべき次のルータを特定する仕組みについてまとめます。

上記の説明でも出てきましたが、IPヘッダーに記載されている宛先IPアドレスと経路表（ルーティング・テーブル）を付き合わせて、次のルータを特定しています。

経路表（ルーティング・テーブル）は `route print` コマンドで確認することができます。

```
C:¥> route print
========================================================================
Interface List
0x1 ........................... MS TCP Loopback interface
0x2 ...00 60 97 a5 4a e9 ...... 3Com 3C905TX-based Ethernet Adapter (Generic) - パケット スケジューラ ミニポート
========================================================================
========================================================================
Active Routes:
Network Destination          Netmask       Gateway     Interface  Metric
            0.0.0.0          0.0.0.0     10.10.1.1    10.10.1.16      25
          127.0.0.0        255.0.0.0     127.0.0.1     127.0.0.1      1
          10.10.1.0    255.255.255.0    10.10.1.16    10.10.1.16      25
         10.10.1.16  255.255.255.255     127.0.0.1     127.0.0.1      25
        10.10.1.255  255.255.255.255    10.10.1.16    10.10.1.16      25
        192.168.1.0    255.255.255.0     10.10.1.2    10.10.1.16      2
          224.0.0.0        240.0.0.0    10.10.1.16    10.10.1.16      25
    255.255.255.255  255.255.255.255    10.10.1.16    10.10.1.16      1
Default Gateway:           10.10.1.1
========================================================================
Persistent Routes:
  None
```

宛先IPアドレスが `192.168.1.21` だったとすると、経路表の6行目に記載されている箇所は該当することになります。 `192.168.1` という部分が一致するからです。

`Interface` はクライアントのLANアダプタなどのネットワーク用インターフェースを表していて、そのインターフェースからパケットを送信すれば、通信相手にデータを届けることができるということを意味しています。

`Getway` は次のルータのIPアドレスを表していて、そのIPアドレスを持つルータにパケットを渡せば、そのルータがサーバにパケットを中継してくれることを意味しています。

上記のような経路表がクライアントだけでなくルータやWebサーバにも登録されています。IPヘッダーに記載されている宛先IPアドレスと経路表を付き合わせることで、次のルータのIPアドレスがわかる仕組みになっています。

## ルータのMACアドレスを特定する仕組み
次のルータに向けて送信されたパケットは、イーサネットの仕組みに従って動いているハブによって、そのルータに運ばれます。

ハブはMACヘッダーに記載されている宛先MACアドレスとハブに登録されているMACアドレス・テーブルを付き合わせて、宛先のルータを判別しています。

では、MACヘッダーに記載された経由先ルータのMACアドレスはどのようにして特定されているのでしょうか。ここで登場するのが `ARP（Address Resolution Protocol）` という仕組みです。

![network-ARP.png](https://qiita-image-store.s3.amazonaws.com/0/186009/6bcda360-a02e-5c12-e423-210f65fa8387.png)

イーサネットに繋がっている全員にパケットを届けるブロードキャストを使って、「〇〇というIPアドレスを持っている人はいませんか？いたらMACアドレスを教えてください」という問い合わせを全員に対して行います。

すると該当者だけが「それは私です。私のMACアドレスはXXXです。」というように返答をすることで、次のルータのMACアドレスを特定することができるという仕組みになっています。

またパケットを送るたびにこれをやっていると、`ARP`のパケットが増えてしまうので、一度調べた結果は`ARPキャッシュ`というメモリー領域に保存して再利用しています。

## エラーを知らせる仕組み
Webサーバからプトロコル・スタックにパケットが返ってきたら、IP担当部分がまずIPヘッダー部分を調べます。

このとき、フォーマットに誤りがあったり、宛先IPアドレスがクライアントに割り振られたIPアドレスではなかったりしたときに、IP担当部分が`ICMP`というメッセージを使用して、通信相手にエラーを通知することになっています。

## まとめ
- プロトコル・スタックのIP担当部分は、TCP担当部分から渡された宛先IPアドレスをIPヘッダーに記載し、そのIPアドレスと経路表（ルーティング・テーブル）を付き合わせて、経由すべきルータを特定する。
- さらに`ARP`という仕組みを使って、経由先ルータのMACアドレスを特定し、それをMACヘッダーに記載する。
- ハブが、宛先MACアドレスとMACアドレス・テーブルを付き合わせて、経由先ルータまで送り届ける。
- 経由先ルータに届いたら、再度同じようにして次の経由先ルータを特定し、送信する。
- この繰り返しで、Webサーバまでデータが届く。

## 参考にした本
- [ネットワークはなぜつながるのか 第２版](https://www.amazon.co.jp/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8B%E3%81%AE%E3%81%8B-%E7%AC%AC%EF%BC%92%E7%89%88-%E6%88%B8%E6%A0%B9-%E5%8B%A4-ebook/dp/B077XSB8BS)

## 所感
ネットワーク層の仕組みはトランスポート層の仕組みと比べて、そこまで複雑ではないように感じたので、学びやすかったです。

普段使用しているルータが、Webサーバまでデータを届けてくれていることを知り、一気に親密さが増したような気がします。