令和の今だからこそ地球🌏の裏側までパケットを届けるIPを理解する

# 📖 この記事を読むとわかること（所要時間15分）

- IPアドレスとMACアドレスの関係
- パケット（ネットワーク層）とフレーム（データリンク層）の本当の姿
- 物理ネットワークと論理ネットワークがどうやって対応しているか
- ARPすげー

# 😎 この記事の目的
**インターネットがなぜ使えるのか**不思議に思ったことはありませんか？
ほとんどの人がインターネットを日常に使っている令和の時代において、こんな今更な疑問を抱く人は少ないかもしれません。
「OSI参照モデルのような概念は知ってるぜ」という人もいれば、「使えりゃいいんだよ」という人もいると思います。

私自身は、漠然とこのような疑問を抱えたまま、**Pythonのような高級言語**ばかりを使い、ネットワークの本当の姿を見ずに生きてきました。
しかし、ここ最近、ネットワークを勉強する機運に恵まれ、遅ればせながら**「ネットワークでデータを送るとはどういうことか」について腹落ちした**ので共有したいと思います。


ネットワークを概念的に理解するために、**OSI参照モデル**に基づく説明がされることが多いです。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f39313636342f66343135386235302d653461312d353931632d343166392d3831643633313262666533392e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/60444bef-2c49-1201-4cc0-ddde2b4b8d74.png)
(**OSI参照モデルの図**、https://qiita.com/naoki_mochizuki/items/7ee0e01db61e1e7abd62 から引用)

（たくさん層があって大変だなー、となりますね）

OSI参照モデルでは、各レイヤーで「これだけは実装してね」という**機能とインターフェイスを事前に決めておく**ことで、自分のレイヤーだけに集中して、他のレイヤーの詳細な実装を気にしなくてもよくなります。簡単なインターフェイスのみでレイヤー間を繋げています。
技術の発展とともに各レイヤーの仕様は目まぐるしく変化していきます。このように**レイヤー間をゆる〜く繋げることで、仕様の変化が及ぼす影響範囲をそのレイヤーにとどめておく**ことができます。


ネットワークのデータのやり取りを腹落ちするためには、少なくとも次の二つの層の役割を知る必要があります。


- **データリンク層（MACアドレスで物理的に繋がる機器にフレームを届ける）**
- **ネットワーク層（IPアドレスで地球の裏側までパケットを届ける）**

ここさえ突破してしまえば、ブラウザでページ遷移した時にどういうことが起きているかを（ぼんやりと）想像できるようになるかと思います。
これらの層の上に乗っているトランスポート層(TCP,UDP)などは、IPで繋がっている前提で考えることができるため、かなり理解しやすくなります。

この記事では、この二つの層に注目して、実際に[Wireshark](https://www.wireshark.org/)で**パケット**(ネットワーク層)や**フレーム**(データリンク層)を確認しながら、OSI参照モデルのような**概念**と、**実際のPCやスマホがやり取りしているデータ**の橋渡しをすることを目標としています。


# 🦈 Wiresharkをインストールする
実際にあなたのPCで行われている通信の中身を簡単に確認できる**Wireshark**というソフトがオススメです。百聞は一見に如かず、とりあえずインストールしてみましょう。

[Wiresharkのダウンロードページ](https://www.wireshark.org/download.html)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/ae0974a4-46a1-e820-b015-a0a279494d77.png)
実際に起動すると、モニタリング対象のネットワークを選ぶことができます。
とりあえず適当に通信してそうなものをクリックしてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/0a3b4047-bb14-9548-94f6-af494e478ef8.png)
すると、次のようなキャプチャ画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/a38102f4-69e2-6833-83bd-016a8cfccd6b.png)

各部分の機能は次のようなものがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/77c5ea55-562a-383c-37ba-d2340be5d2ee.png)

Wiresharkを使える準備ができました！🎉

でもその前に、概念を説明したいと思います🤔


# 📗 まずは概念から

データリンク層の説明の前に**物理層**に少し触れておきます。
データリンク層の下にある物理層は、ケーブルや端子の規格を決めている層です。
規格は何であれ、**0と1のビット列を電気信号や光信号に変換して届ける**ことが物理層の一番の役割です。

この物理層のおかげで、さらに上の層では、どんな規格のケーブルが何mの長さで繋がっているか、有線か無線かといった、**物理的で複雑すぎる要因**を考えないで済むようになります。
地球の裏側のケーブルの規格を気にしなければいけないとなると、途方もなく大変な気がしますよね。
有線ケーブルだったり、Wifiといった無線のような様々な規格だったり、最近ニュースでも聞く5Gとかも物理層の話です。

## 🔗 データリンク層（イーサネット）
続いて、**データリンク層**について説明します。

データリンク層とはざっくりいうと、**物理的ネットワークに依存するややこしい部分を全部吸収してくれている層**です。これより上の層では、ネットワーク経路上にあるルータやスイッチ、PCがどのベンダーのどの製品かといったことを知らないでも通信が行えるようになります。
つまり、**データリンク層は物理層と論理層（IPアドレス）の橋渡しをするとっても重要な層**ということになります。
物理層は、規格は何であれ、0と1のビット列を電気信号や光信号を変換して届けてくれる層でした。これに対して、データリンク層は、**0と1のビット列をどこの機器に送るか**を決める層だといえます。


物理層で繋がったPCやルータ、スマホには、デバイス同士が識別できるように**MACアドレス**と呼ばれる48ビット（6オクテット≒6バイト）の識別IDがつけられています。このMACアドレスは、ベンダー識別ID(3オクテット)とそのベンダーの製品で機器ごとに一意になるようにつけられたID(3オクテット)でできており、**全世界で固有のものであることが保証**されています。つまり、同じLANには、必ず違うMACアドレスの機器が接続されていることになります。

🍎例えばApple製のPCのMACアドレスは、`8c:85:90:xx:xx:xx` のようになります。

広く使われているデータリンク層のプロトコルが**イーサネット(Ethernet)**です。物理層でつながったデバイス同士がどのように0と1のビット列を送受信するかを定めたプロトコルです。
イーサネットでは、**フレーム**というデータのかたまりでデータの通信を行います。
フレームは、以下の二つの部分からできています。

- **ヘッダー**(**送信元MACアドレス**,**送信先MACアドレス**の情報)
- **データ部分**(さらに上の層のデータ、つまり**パケット**)

### 👀 イーサネットのフレームを詳しくみてみる
フレームの最初には、8バイトのプリアンブルと呼ばれる「これからフレーム来ますよ」信号があります。
> 1010101010101010101010101010101010101010101010101010101010101011

間違い探しみたいですが、最後が`11`で終わってるのがポイントです。こんな大量に交互に0と1が送られてきたら、「単なるノイズではない電気信号や光信号が来そう」となりますね。
このプリアンブル信号の後には、先ほど説明したヘッダーが来ます。

> 送信元MACアドレス(6バイト) + 送信先MACアドレス(6バイト) + ネットワーク層のプロトコル(2バイト）

Wiresharkを使ってフレームを確認してみましょう。
プリアンブル信号は、共通してるのでWiresharkでは省略されています。


Wiresharkで、とあるTCPパケットをみてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/4de5f5dc-8132-e41a-3767-d14b7e0edf82.png)
ネットワーク層のプロトコルというのは、この場合IPv4です。他にはIPv6などがあります。

ヘッダーの次にあるデータ部には、**ネットワーク層のパケット(IPv4)**が丸ごと入っています。
このようにデータリンク層ではMACアドレスを目印にデータが送受信されていき、バケツリレーのように目的地に送られていきます。

バケツがフレームだとすると、間を取り持つ人に対応するのが**L2スイッチ**です。
###  📬 L2スイッチ
実のところ、基本的には他のデバイスのMACアドレスなんてわかりませんし、知る必要があるのは**同じデータリンクにいるデバイス**くらいです。世界中の異なるMACアドレスを保存するのは無理ですね😅

**同じデータリンクのデバイスは、L2スイッチと物理ポートで繋がっています**。このL2はレイヤー２、つまりデータリンク層のスイッチであるという意味です。
**L2スイッチ**は、**MACアドレステーブル**と呼ばれる**MACアドレスと物理ポートの対応表**を持っています。「このMACアドレスに送ってくれー」というフレームを受け取ると、対応表からMACアドレスを探し、見つかったらその物理ポートにデータを送信します。
もちろん、送信先のMACアドレスが対応表にない時もあります。その時はどうするかというと、シンプルに**「大声で叫ぶ」**のです（**ブロードキャスト**）。

「誰かこのMACアドレスじゃないかねー！？」

自分がそうであれば、「そうでーす」と返事します。

このようにして、L2スイッチのMACアドレス対応表が出来上がっていきます。
**L2スイッチは電気信号や光信号をとても早く、効率的に目的のMACアドレスへ送信する**ことができます。

## 😳 ＜ あれ？MACアドレスだけあればIPなんていらないんじゃね？
MACアドレスは、世界に一つの識別番号であり、世界中のL2スイッチが頑張りさえすれば、**別のデータリンクにもデータを送ってくれます**。
じゃあ、**なんでネットワーク層（IP）がいるの？**って話になりますよね。

[MACアドレスとIPアドレスの両者が必要な理由](http://www.rickynews.com/blog/2015/07/09/why-ip-address-and-mac-address-are-needed/)でも言及されているように、原理的にはMACアドレスでも通信はできるけど、**ネットワーク層を入れると便利だった**というのが真実かもしれません。

上のURLでも紹介されていますが、よくある例えとして、パケット通信と郵便配達の比較があります。

|MACアドレス|IPアドレス|
|:--------:|:-----:|
|個人の名前|住所|

MACアドレス（個人名）がわかっていたとしても、住所がわからないと、なかなか郵便配達は難しそうです。郵便局(L2スイッチ)が本気を出せば配達はできるかもしれませんが、毎回調べて送信するとなると途方もない努力が必要になりそうですね。
MACアドレスは世界に一つという優れた識別能力を持ち、**家に届いたらすごい速さで家族に届けてくれます**が、遠方に届けるとなるとなんらかの手がかりがあったほうが郵便局員(L2スイッチ)は助かるでしょう。

この手がかりがまさに**IPアドレス**です。

## 🚀 ネットワーク層
満を持して**IP(Internet Protocol)**の出番です。
ネットワーク層のプロトコルには、

- **IP**(IPv4, IPv6)
- **ICMP**
- **ARP**

があります。
どれも重要なんですが、今回の記事では**IP**と**ARP**が重要になります。

IPは、**パケット**と呼ばれるデータのやり取りをするプロトコルです。

### 👀 IPのパケットを詳しくみてみる
例によってWiresharkでIPv4のパケットをみてみましょう。先ほどお見せした**フレームのデータ部分がパケット**ということになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/4293b277-76f9-d832-34cf-70fe6a10cf12.png)
IPv4パケットのヘッダーには、**送信元IPアドレス**や**送信先IPアドレス**や、さらに上位層のプロトコル（TCP）についての情報が書かれています。

このIP、何がすごいのかというと、**ルーティングが超賢いんです**。

ネットワーク層において、イーサネットでのL2スイッチと似た役割を果たすのが、**ルータ**(L3スイッチ)です。

**ルータ**は、 どんなに離れた場所にあるホスト（例え地球の裏側🌎）であっても、両端の**IPアドレス**さえ与えれば、多くても１０個程度のルータ（のIPアドレス）を経由したネットワーク経路を見つけ出します。

機器に縛り付けられたMACアドレスと違い、**より抽象的で論理的なIPアドレスを扱うことで、異なるデータリンク間の優れたルーティングアルゴリズムを実装することができる**ようになりました。

## 😒 ＜ ふ〜ん、IPってすごそうだけど漠然としてるなぁ
その通り。

ネットワーク層とデータリンク層の繋がりって結局なんでしょうか？

IPで地球の裏側までパケットを送るといっても、実のところ、**一つ一つのデータリンク間の移動では必ずMACアドレスによって繋がっています**。

つまり、IPでパケットを運ぶとしても、フレームにするためには、必ず**送信元MACアドレスと送信先MACアドレスの両方**が必要になります。

IPの優れたルーティングアルゴリズムによって、送信先（ルータとかホスト）のIPアドレスはわかりました。

**でも、IPを知ってても、MACアドレスがわからない場合があるんじゃないの？**

答えは、**「YES」**です。
普通の家庭で使われるISPから割り当てられる動的IPアドレスは、接続するたびに変わることがあります。つまり、**同じPC（同じMACアドレス）であっても、IPアドレスが同じである保証は全くありません**。
**IPアドレスとMACアドレスをつなぐもの**、それがネットワーク層のプロトコルである**ARP**です。

# 💡 ARP ー IPアドレスからMACアドレスを調べる
この記事を書きたくなった動機が、このプロトコルに感動したからでした。
**ARP(Address Resolution Protocol)**とは、特定のIPアドレスに対応するMACアドレスを調べるためのプロトコルです。

ARPがやっていることは、案外単純です。
同じネットワーク（VLAN）内のIPアドレス全てにブロードキャストで、**「あなたのIPがこのIPと同じだったら、MACアドレスを教えて」**というパケット（**リクエスト**）を送ります。
仮に、リクエストに書かれたIPアドレスが自分のものと同じだったら、元々の送信元に**リプライ**を返します。

ルータは、ARPを定期的に送り、リアルタイムでIPアドレスとMACアドレスの対応を知るようにしています。

WiresharkでARPの中身をみてみましょう。上のフィルタに「arp」と指定することで、ARPのみを表示することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/d299f634-e478-1083-e4f1-276e928ac75b.png)


まずは、ARPリクエストです。ターゲットIPアドレスが設定されている一方で、**ターゲットMACアドレスは何も指定されていない**ことが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/4b549b4c-71b7-0f1c-6a2f-7c26cb17d671.png)

私のPCはARPリクエストを受け取りました。ターゲットIPアドレスが自分のものと同じなので、ARPリプライを送信元に対して返しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260547/9433fdc3-e1d4-970f-932b-ac1468f3b4e8.png)

このようにして、**同一ネットワークだとIPアドレスさえあれば、MACアドレスを知ることができます。**

パケットに送信元MACアドレスと送信先MACアドレスをつければ、データリンク層のフレームとして送信できるようになります。

ただし、ARPの弱点として、**ブロードキャストが必要になる**、という点があります。
巨大なVLAN（サブネットを大きく切った場合）であれば、ARPでネットワークがパンパンになる可能性すらあります。
ARPで得られたIPアドレスとMACアドレスの対応は、一時的にキャッシュされることで、この問題を解決しています。

# まとめ
IPアドレスとMACアドレスの関係についてまとめてみました。いかがだったでしょうか？

この記事を３行でまとめると次のようになります😚

**同一データリンク内のフレームの通信は両端のMACアドレスがわかれば可能です。
IPを使ったルーティングのおかげで、地球の裏側へのパケットを送るためのIPアドレスの経路がわかります。
各経路でIPのパケットをフレームにするには、送信先のMACアドレスが必要→ARP！**

不正確なところがあるかもしれませんので、ご指摘いただけると嬉しいです🤗
ありがとうございました！