RFCから学ぶIPv6

# はじめに
インターネットではいろいろな個人の知識がブログなどで手軽に共有できます。
我々がお世話になっているQiitaもその一つですね。
とはいえエンジニアとしてはRFCなどの技術仕様が記載された文書も読まなければならない時もあります。
以前IPv6を勉強しようとRFCを読んでいたので、その内容とRFCのリンク(できれば日本語に翻訳されたもの)を添えてみようかと思います。
IPv6を勉強しようと思い書籍やブログを読んだことはあるけど実はRFCって読んだことないな、という方がリンクをポチポチすると楽しめるかもしれません。
RFCについては以下のリンクを参考にしていただければと思います。
- [JPNIC - RFCってなに?](https://www.nic.ad.jp/ja/rfc-jp/WhatisRFC.html)
- [JPNIC - RFCの分類](https://www.nic.ad.jp/ja/rfc-jp/RFC-Category.html)

ちなみに有名かと思いますがIPv6を勉強しようという方には小川晃通さんが執筆した「プロフェッショナルIPv6」という書籍がオススメです。


# IPv6概要
[RFC 8200 - Internet Protocol, Version 6 (IPv6) Specification - 1.Introduction](https://tex2e.github.io/rfc-translater/html/rfc8200.html#1--Introduction)

IPv6はTCP/IP Protocol Suiteにおけるインターネット層のプロトコルで、IPv4([RFC791 - INTERNET PROTOCOL](https://datatracker.ietf.org/doc/html/rfc791))の後継として設計されたインターネットプロトコルの新しいバージョンです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223892/e79d8cd7-cd3e-4622-c89f-308faa89ab9a.png" width="500">


IPv4からの主な変更点は以下となっています。

- アドレッシング機能の拡張
- ヘッダーフォーマットの簡略化
- 拡張機能とオプションのサポート向上
- フローのラベル付け機能
- 認証とプライバシー機能

パケットを目的地まで届けるという役割はIPv4もIPv6も同じです。
IPv4とアドレス構成が異なるので、IP情報を扱うプロトコルはIPv6の登場に合わせて拡張が行われています。
例：RIPng, OSPFv3, RADIUSなど

# ヘッダフォーマット
[RFC 8200 Internet Protocol, Version 6 (IPv6) Specification - 3. IPv6 Header Format](https://tex2e.github.io/rfc-translater/html/rfc8200.html#3--IPv6-Header-Format)　
### IPv6ヘッダフォーマットとIPv4との比較
IPv6のヘッダフィールドは以下のようになっています。
比較としてIPv4のヘッダも並べておきます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223892/bb979ae6-563b-9870-bc58-a4bbd05ac67b.png" width="900">
IPv6ではIPv4に比べ、フィールドが簡素化され固定長となっており、機器の処理コストを削減しています。

### 各ヘッダフィールド
- Version(4bit)
    - IPのバージョン情報です。
    - IPv6の場合は`6`となります。

- Traffic Class(8bit)
    - 上位6bitのDifferentiated Services Codepoint(DSCP)と下位2bitのExplicit Congestion Notification(ECN)から構成されています。
        - 参考:[RFC 2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers ](https://tex2e.github.io/rfc-translater/html/rfc2474.html)
        - 参考:[RFC 3168 - The Addition of Explicit Congestion Notification (ECN) to IP](https://tex2e.github.io/rfc-translater/html/rfc3168.html)
    - このフィールドはネットワーク内でのトラフィック管理に使用されます。
    - IPv4のToSフィールドに相当します。

- Flow Label(20bit)
    - IPv6のフロー識別に使用されるラベルです。
        - 参考:[RFC 6437 IPv6 Flow Label Specification](https://tex2e.github.io/rfc-translater/html/rfc6437.html)
    - IPv4の場合は5つのフィールド(送信元/宛先アドレス、プロトコルタイプ、送信元/宛先ポート)の情報を使用する場合が多く、フラグメンテーションや暗号化などにより使用できないフィールドがあります。
    - IPv6の場合は3つのフィールド(送信元/宛先アドレス、Flow Label)でフローを識別できます。
    - IPv4と同様の方法でも識別は可能です。

- Payload Length(16bit)
    - IPv6パケットのペイロードの長さを示します。
    - 後述する拡張ヘッダもペイロードの長さにカウントされます。

- Next Header(8bit)
    - IPv6ヘッダの直後に続くヘッダタイプを示します。
    - IPv4のProtocolフィールドと同じ値を使用します。
        - 例：ICMP=1,TCP=6,UDP=17
    - この番号はIANAにて割り振られています。
        - IANA - [Protocol Numbers](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)

- Hop Limit(8bit)
    - パケットを転送するノードごとに1ずつ減少する値です。
    - 受信時に0であった、もしくは0にデクリメントされた場合はパケットは破棄されます。
    - IPv4におけるTTLフィールドに相当します。

- Source Address(128bit)
    - パケットの発信者の128ビットアドレスです。

- Destination Address(128bit)
    - パケットの宛先の128ビットアドレスです。



# 拡張ヘッダ
[RFC 8200 Internet Protocol, Version 6 (IPv6) Specification - 4 .IPv6 Extension Headers](https://tex2e.github.io/rfc-translater/html/rfc8200.html#4--IPv6-Extension-Headers)

IPv4のヘッダフィールドにあったオプションフィールドはIPv6では廃止されました。
その代わり、オプションのインターネット層情報は、上位層ヘッダとの間に配置できる個別の拡張ヘッダとして用意されており、Next Headerの値によって識別されます。
IPv6ヘッダは固定長化されていますが、拡張ヘッダを導入することによって容易に追加機能を持たせることができます。
上位層のプロトコルと同様にプロトコル番号が割り振られており、[Protocol Numbers](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)のIPv6 Extension Header列に`Y`の記載があるものがIPv6拡張ヘッダとなります。
拡張ヘッダは複数使用することができ、それぞれのヘッダにNext Headerフィールドが用意されています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223892/b103b8fa-b747-8783-f974-df45b4a4ecef.png" width="600">

代表例は以下となります。
- ホップバイホップオプションヘッダ[[RFC8200 - 4.3](https://tex2e.github.io/rfc-translater/html/rfc8200.html#4-3--Hop-by-Hop-Options-Header)]
- ルーティングヘッダ[[RFC8200 - 4.4](https://tex2e.github.io/rfc-translater/html/rfc8200.html#4-4--Routing-Header)]
- フラグメントヘッダ[[RFC8200 - 4.5](https://tex2e.github.io/rfc-translater/html/rfc8200.html#4-5--Fragment-Header)]
- 宛先オプションヘッダ[[RFC8200 - 4.6](https://tex2e.github.io/rfc-translater/html/rfc8200.html#4-6--Destination-Options-Header)]
- 認証ヘッダ[[RFC 4302](https://tex2e.github.io/rfc-translater/html/rfc4302.html)]
- カプセル化セキュリティペイロードヘッダ[[RFC 4303](https://tex2e.github.io/rfc-translater/html/rfc4303.html)]

主な変更点に挙げられていた「認証とプライバシー機能」は認証ヘッダやカプセル化セキュリティペイロードヘッダのことです。


# アドレッシング
[RFC 4291 - IP Version 6 Addressing Architecture - 2. IPv6 Addressing](https://tex2e.github.io/rfc-translater/html/rfc4291.html#2--IPv6-Addressing)

IPv6では128 ビットの長さでアドレスを表現します。
$2^{128}$ 個のアドレス＝約$3.4 \times 10^{38}$個のアドレスが存在します。
すべてのインターフェースには、少なくとも1つのリンクローカルユニキャストアドレスが必要です(後述)。
インターフェースは、任意のタイプまたはスコープの複数のIPv6アドレスを持つことができます。

IPv6アドレスには次の3つのタイプがあります。
　■ユニキャストアドレス
　■エニーキャストアドレス
　■マルチキャストアドレス

## 表記方法
■[RFC 4291 IP Version 6 Addressing Architecture  - 2.2.Text Representation of Addresses](https://tex2e.github.io/rfc-translater/html/rfc4291.html#2-2--Text-Representation-of-Addresses)
- 16進数で表記し`:`(コロン) によって2オクテットごとに分割します。
- 連続するブロックでのゼロは `::`(ダブルコロン) により省略して表記されます。
    - 1アドレス内で使用できるのは1回のみ

■[RFC 4291 IP Version 6 Addressing Architecture  - 2.3. Text Representation of Address Prefixes](https://tex2e.github.io/rfc-translater/html/rfc4291.html#2-3--Text-Representation-of-Address-Prefixes)
- IPv6アドレスプレフィックスは、次の表記で表されます。
- `ipv6-address` / `prefix-length`
- `prefix-length`はアドレスの左端の連続するビットの何個がプレフィックスを構成するかを指定する10進数値です。


■[RFC 5952 A Recommendation for IPv6 Address Text Representation - 4.A Recommendation for IPv6 Text Representation](https://tex2e.github.io/rfc-translater/html/rfc5952.html)
こちらは人間が読むために推奨される表記方法です。

- 各ブロックの先頭の0は省略して表記します。
- アルファベットは小文字で表記します。
- ダブルコロンは1アドレスにつき1回のみ使用でき、省略可能なブロックが複数ある場合は一番長いブロックを省略します。
- 1ブロックの省略に `::`(ダブルコロン)は使用できません。
- 省略可能なブロックの長さが同じ場合は上位ビットのブロックを省略します。

### 表記例
　`2001:db8:f10a:41:ff72:8a8e:ee13:9/64`
　`2001:db8::88e:0:1/64`

## ユニキャストアドレス
[RFC 4291 IP Version 6 Addressing Architecture - 2.5.Unicast Addresses](https://tex2e.github.io/rfc-translater/html/rfc4291.html#2-5--Unicast-Addresses)

単一のインターフェースを識別するアドレスタイプ(one-to-one 配送)となります。
リンクを識別する __Subnet Prefix__ と、リンク上のインターフェースを識別する __Interface ID__ の情報があります。
ユニキャストアドレスの形式を以下に示します。

| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;128 - n bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |
| :---: | :---: |
| Subnet Prefix | Interface ID |

よく利用されるユニキャストIPv6アドレスはSubnet Prefixが64bit、Interface IDが64bitとなっています。

RFC 4291でアドレス形式のフィールドを表す際にPrefixとIDという単語が出てきますが意味はほとんど同じです。
IDはアドレスのフィールドを意味し、Prefixはアドレスの左端から当該のフィールドまでという意味ですが左端のフィールドにしかPrefixという名称は使用されていないので。
表記方法で記載したprefix-lengthはSubnet Prefixの長さを示しているわけですね。


### アドレススコープ
#### リンクローカル
`fe80::/10`の範囲のアドレスを使用します。
同一のリンク内(ルータを超えない範囲)でのみ有効なユニキャストアドレスで、近隣のノードに対する通信に用いられます。
ルータは、このアドレスが発信元となったパケットを、他のリンクへルーティングしません。
IPv6が有効な機器は自動で生成します。
リンクローカルユニキャストアドレスの形式を以下に示します。


| 10bit | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;54bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;64bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |
| :---: | :---: | :---: |
| 1111111010 | 0 | Interface ID |

　　
#### サイトローカル

※現在サイトローカルの使用は __非推奨__ となっており、代わりにユニークローカル([RFC 4193 - Unique Local IPv6 Unicast Addresses ](https://tex2e.github.io/rfc-translater/html/rfc4193.html))が存在します。

`fec0::/10`の範囲のアドレスを使用します。
組織内のネットワーク通信に使用されるローカルなユニキャストアドレスとなります。
IPv4における、プライベートIPアドレスに相当します。
サイトローカルユニキャストアドレスの形式を以下に示します。

| 10bit | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;54bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;64bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|
| :---: | :---: | :---: |
| 1111111011 | Subnet ID | Interface ID |

　　
#### グローバル
用途の決まっているプレフィックスに該当しない（組織内、インターネットなどスコープの制限がない）ユニキャストアドレスとなります。
グローバルユニキャストアドレスの形式を以下に示します。
現時点では`2000::/3`の範囲がIANAによってインターネットに割り当てられているので、先頭は3bitは`001`から始まるかと思います
IANA - [IPv6 Global Unicast Address Assignments](https://www.iana.org/assignments/ipv6-unicast-address-assignments/ipv6-unicast-address-assignments.xhtml)
参考: [RFC 3587 - IPv6 Global Unicast Address Format](https://tex2e.github.io/rfc-translater/html/rfc3587.html)

| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | m bit | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;128 - n - m bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |
| :---: | :---: | :---: |
| Grobal Routing Prefix | Subnet ID | Interface ID |

- Global Routing Prefix: 各RIR(Regional Internet Registry: APNIC, etc...), NIR(National Internet Registry: JPNIC, etc...), ISPが階層的に構造化されるように設計する領域です。
- Subnet ID: サイト管理者が階層的に構造化されるように設計する領域です。



### 特殊なアドレス
#### Unspecified Address
`::(0:0:0:0:0:0:0:0)`で示されるアドレスとなります。
このアドレスはノードに割り当ててはいけません。
ホストが自身のアドレスを学習する前に送信するIPv6パケットのソースアドレスフィールドなどで使用されます。

#### Loopback Address
`::1(0:0:0:0:0:0:0:1)`で示されるアドレスとなります。
ノードはこのアドレスを使用してIPv6パケットを自分自身に送信できます。
リンクローカルスコープを持つものとして扱われ、外部と通信を行わない仮想インターフェイス（通常は「ループバックインターフェイス」と呼ばれます）のリンクローカルユニキャストアドレスと考えることができます。
物理インターフェースに割り当ててはいけません。

#### IPv6 Addresses with Embedded IPv4 Addresses
アドレスの下位32bitがIPv4アドレスとなっている以下2つのアドレスがあります。
- IPv4-Compatible IPv6 Address
    - 廃止済みなので説明省略。
- IPv4-Mapped IPv6 Address
    - IPv4ノードのアドレスをIPv6アドレスとして表すために使用されます。
    - アプリケーションのIPv6移行をサポートするために定義されています。
        - 背景は[RFC 4038 - Application Aspects of IPv6 Transition ](https://tex2e.github.io/rfc-translater/html/rfc4038.html)に記載されています。
    - 形式を以下に示します。

| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;80bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;&nbsp;16bit&nbsp;&nbsp;&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;32bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |
| :---: | :---: | :---: |
| 0 | FFFF | IPv4 Address |

表記例: `::FFFF:192.0.2.1`


### IPv6アドレスの設定
ノードにおけるIPv6アドレスの設定方法には以下3種類があります。
- Stateless Address Autoconfiguration
    - Prefix情報をルータのRAメッセージ(後述)から受け取り、Interface IDと組み合わせてアドレスを構成する方法です。
        - 参考：[RFC 4862 - IPv6 Stateless Address Autoconfiguration](https://tex2e.github.io/rfc-translater/html/rfc4862.html) - 5.5. Creation of Global Addresses
    - Interface IDはModified EUI-64 formatによる構成や一時アドレス([RFC 8981 Temporary Address Extensions for Stateless Address Autoconfiguration in IPv6](https://tex2e.github.io/rfc-translater/html/rfc8981.html))が用いられます。

- DHCPv6
    - DHCPv6サーバのアドレスプールから割り当てを行うものです。
        - 参考：[RFC 8415 - Dynamic Host Configuration Protocol for IPv6 (DHCPv6)](https://tex2e.github.io/rfc-translater/html/rfc8415.html)
    - ちなみにDHCPv6は、デフォルトルータの情報をRAメッセージ(後述)から受け取るのでDHCPv6ではデフォルトルータの広報機能がないなど、IPv4とは使い勝手が違います。
- 手動設定

## エニーキャストアドレス
[RFC 4291 IP Version 6 Addressing Architecture - 2.6.Anycast Addresses](https://tex2e.github.io/rfc-translater/html/rfc4291.html#2-6--Anycast-Addresses)
複数のノードのインターフェースに割り当てられた同一のアドレス(one-to-one-of-many配送)となります。
送信元からエニーキャストアドレスに送信した場合はエニーキャストアドレスを持つ最も近いノードへパケットが転送されます。
エニーキャスト専用のアドレス範囲はなく、ユニキャストアドレスの範囲を利用します。
※エニーキャストアドレスとして使用することは明示的にしなければなりません。

## マルチキャストアドレス
[RFC 4291 IP Version 6 Addressing Architecture - 2.7.Multicast Addresses](https://tex2e.github.io/rfc-translater/html/rfc4291.html#2-7--Multicast-Addresses)
インターフェースグループのアドレス(one-to-many配送)となります。
`ff00::/8`のアドレス範囲を使用します。
IPv4にあったブロードキャストは廃止され、IPv6ではマルチキャストに置き換えられています。
マルチキャストアドレスの形式を以下に示します。


| 8bit | 4bit | 4bit | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;112bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|
| :---: | :---: | :---: | :---: |
| 11111111 | Flags | Scop | Group ID |



■Flags
Flagsは4bit(4つのFlag)があり、形式は以下のようになっています。
| `0` | R | P | T |
| :---: | :---: | :---: | :---: |

- `0`: 最上位のFlagは`0`です。
- R: RP(Rendezvous Point、ランデブーポイント)のアドレスを埋め込んだマルチキャストアドレスであることを示します。
    - [RFC 3956  - Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast Address](https://tex2e.github.io/rfc-translater/html/rfc3306.html) - 2. Unicast-Prefix-based Address Formatに記載
- P: Network Prefixに基づいて割り当てられたアドレスであることを示します。
    - [RFC 3306 - Unicast-Prefix-based IPv6 Multicast Addresses](https://tex2e.github.io/rfc-translater/html/rfc3306.html)　- 4. Multicast Address Formatに記載
- T: 一時的に割り当てられたアドレスであることを示します。0である場合はIANAによって永続的に割り当てられたアドレスです。

■Scop
Scopが示す値は以下の表の通りです。
| HEX | Scop |
| --- | --- |
| 0 | 予約済み |
| 1 | インターフェースローカルスコープ |
| 2 | リンクローカルスコープ |
| 3 | 予約済み |
| 4 | 管理者ローカルスコープ |
| 5 | サイトローカルスコープ |
| 6 | 未割り当て |
| 7 | 未割り当て |
| 8 | 組織ローカルスコープ |
| 9 | 未割り当て |
| a | 未割り当て |
| b | 未割り当て |
| c | 未割り当て |
| d | 未割り当て |
| e | グローバルスコープ |
| f | 予約済み |




各スコープにおける予約されたマルチキャストアドレスの割り当てはIANAにて確認することができます。
[IANA - IPv6 Multicast Address Space Registry](https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml)
主な予約済みマルチキャストアドレスの用途は以下となります。
| マルチキャストアドレス | スコープ | 用途 |
| ---- | ---- | ---- |
|  ff02::1 | リンクローカル |　全てのノード宛 |
|  ff02::2 | リンクローカル |　全てのルータ宛 |
|  ff02::5 | リンクローカル |　OSPFv3ルータ宛 |
|  ff02::6 | リンクローカル |　OPPFv3 DR/BDR宛 |
|  ff02::9 | リンクローカル |　RIPngルータ宛 |


# ネイバーディスカバリ
[RFC 4861 - Neighbor Discovery for IP version 6 (IPv6) ](https://tex2e.github.io/rfc-translater/html/rfc4861.html)

- 同一リンク上のIPv6ノードは以下の目的でネイバーディスカバリを実施します。
    - ルータを検索するため。
    - 互いのリンクレイヤアドレスを特定するため（IPv4で使用されていたARPに相当）。
    - 到達可能性情報を維持するため。
- ルータの検索を行うと同時に、IPv6アドレスのオートコンフィグレーションを実行することができます。
- ネイバーディスカバリは __ICMPv6__ メッセージを使用します。
    - ルータ要請: Router Solicitation(ICMPv6 メッセージタイプ 133)
    - ルータ広告: Router Advertisement(ICMPv6 メッセージタイプ 134)
    - ネイバー要請: Neighbor Solicitation(ICMPv6 メッセージタイプ 135)
    - ネイバー広告: Neighbor Advertisement(ICMPv6 メッセージタイプ 136)
    - リダイレクト: Redirect (ICMPv6 メッセージタイプ 137)

以降に出てくるICMPv6のChecksumフィールドは、ICMPv6メッセージタイプフィールドから開始して全体のICMPv6メッセージの1の補数和の16ビットの1の補数となります。
参考: [RFC 4443 - Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification](https://tex2e.github.io/rfc-translater/html/rfc4443.html) - 2.3. Message Checksum Calculation

## Router Solicitation(RS)メッセージ
- ホストがリンク上にルータが存在するか確認するために送信します。
- 送信先はAll Routers Address`ff02::2`を使用します。
- 送信元 IP アドレスにはリンクローカルアドレスかUnspecified Address`::`を使用します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223892/fce8a7e7-75d4-75b9-eb5e-d896273853ee.png" width="900">

■ICMPv6メッセージフィールド
- Type: 133
- Code: 0
- Reserved: 0で初期化される予約済みの領域です。
- Options: このフィールドを使用して将来のバージョンで拡張を行うことができます。Source link-layer address(送信者のリンク層のアドレス)を挿入可能です。

## Router Advertisement(RA)メッセージ
- ルータ（ゲートウェイ）の存在をノードに通知します。
    - ルータは定期的もしくはRSメッセージに応答して送信します。
- ルータはアドレスの自動設定を実行する方法(SLAAC or DHCPv6)をホストに通知できます。
- SLAACの場合、ノードはRAメッセージを用いてアドレスの自動設定を行います。
- 送信元 IPv6 アドレスにはリンクローカルアドレス、送信先にノードのユニキャストアドレスもしくはALL Nodes Address`ff02::1`を使用します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223892/bded7533-62ac-bbe8-000b-1b52a8a35d54.png" width="900">


■ICMPv6フィールド
- Type: 134
- Code: 0
- Cur Hop Limit: ルータがIPv6パケットで使用できるホップの最大数を示します。送信されるIPv6パケットのHop Limitフィールドに最初にセットされる値となります。
- Mフラグ(Managed address configuration): `0`の場合はSLAACによるアドレス設定、`1`の場合はDHCPv6によるアドレス設定であることをノードに示します。
- Oフラグ(Other configuration): `1`の場合はDHCPv6からアドレス以外の情報を取得できることをノードに示します。Mフラグが`1`である場合はOフラグは冗長な情報となります。
- Reserved: 0で初期化される予約済みの領域となります。
- Router Lifetime: デフォルトルータの有効期限。
- Reachable Time: ネイバーが到達可能であると仮定する時間を示します。Neighbor Unreachability Detectionに使用される値となり、0は指定されないことを意味します。
- Retrans Timer: Neighbor Solicitationメッセージの再送信までの時間を示します。到達可能性検出に使用される値となり、0は指定されないことを意味します。
- Options: このフィールドを使用して将来のバージョンで拡張を行うことができます。ルータのリンクレイヤアドレス、MTU、Prefix、DNSサーバ([RFC8106](https://tex2e.github.io/rfc-translater/html/rfc8106.html))などを挿入可能です。


## Neighbor Solicitation(NS)メッセージ
- IPv6 ノードのリンクレイヤアドレスを解決するために使用されます(IPv4のARP requestに相当)。
    - 送信先アドレスは、アドレス解決にはAll Nodes Address`ff02::1`を、ノード到達可能性にはユニキャストアドレスを使用します。
    - 送信元アドレスには送信ノードのリンクローカルユニキャストアドレスを使用します。
- Duplicate Address Detection （重複アドレス検出）にも使用されます。
    - 送信元アドレスにはUnspecified Address `::`を使用します。
    - 送信先アドレスには要請ノードマルチキャストアドレスを使用します。
        - 要請ノードマルチキャストアドレス: `FF02:0:0:0:0:1:FF00::/104`のレンジのうち下位24bitを検出するアドレスの下位24bitと同様の値にしたもの

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223892/017fb367-a766-ccbf-13bf-4f8d263e1cad.png" width="900">



■ICMPv6フィールド
- Type: 135
- Code: 0
- Reserved: 0で初期化される予約済みの領域となります。
- Target Address: アドレス解決を行う対象IPv6アドレスを示します。
- Options: 送信元ノードのリンクレイヤアドレスを挿入可能です。


## Neighbor Advertisement(NA)メッセージ
- ノードのリンクレイヤアドレスを通知します(IPv4のAPR repryに相当)。
- 送信元アドレスには送信ノードのユニキャストアドレスを使用します。
- 送信先アドレスにはNSメッセージの送信元アドレス（ Unspecified Address`::`の場合はAll Nodes Address`ff02::1`）を使用します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223892/740d64e1-9b40-01f6-e018-91113305a117.png" width="900">



■ICMPv6フィールド
- Type: 136
- Code: 0
- R: ルータフラグ。1である場合、送信者がルータであることを示します。
- S: Solicitedフラグ。1である場合、NSに対する応答であることを示しましす。
- O: オーバーライドフラグ。1である場合、既存のキャッシュされたリンクレイヤアドレスを上書きして更新することを示します。
- Reserved: 0で初期化される予約済みの領域となります。
- Target Address: アドレス解決を行う対象IPv6アドレスを示します。
- Options: このフィールドを使用して将来のバージョンで拡張を行うことができます。Target Address を持つInterfaceのリンクレイヤアドレスを挿入可能です。

## Redirect
- より良いルータへのリルートを指示するのに使用されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223892/9fb6b029-2789-50e1-24bd-fe192a231140.png" width="900">



■ICMPv6フィールド
- Type: 137
- Code: 0
- Reserved: 0で初期化される予約済みの領域となります。
- Target Address: より良い最初のホップであるルータのIPアドレスを示します。
- Destination Address: リダイレクトされたパケットの宛先のIPアドレスを示します。
- Options: このフィールドを使用して将来のバージョンで拡張を行うことができます。Target Addressを持つインターフェースのリンクレイヤアドレスを挿入可能です。


# 最後に
実はIPv6を勉強しようと思っても何種類ものRFCを読み漁る必要があります。
個人的に一番大変なのはRFCを見つけることでした。
（散らばっている情報をまとめてくれているブログや書籍は偉大。）
基本的にこういった文書は日本語じゃないので敬遠されがちですが、プロトコルの仕様を調べる時にはRFCなどの文書を確認する癖はつけたいですね。