🎓 レベル:標準 | 重要度:B(重要) 📎 前提:IPアドレスの基礎(IPv4)
要点(BLUF)
- IPv6は128ビットで、枯渇したIPv4を置き換えます。16進4桁を8グループ、コロン区切りで書きます。
- 0の連続は
::で1回だけ省略でき、各グループ先頭の0も省けます。 - アドレスは用途別に**GUA(公開)/ULA(私設)/リンクローカル(同一リンク限定)**などに分かれ、SLAACで機器が自動生成できます。
表記と短縮ルール
2001:0db8:0000:0000:0000:0000:0000:0001 は次の2段階で短くします。
- 各グループの先頭の0を削る →
2001:db8:0:0:0:0:0:1 - 連続する0グループを
::で1回だけ置換 →2001:db8::1
import ipaddress
a = ipaddress.IPv6Address("2001:0db8:0000:0000:0000:0000:0000:0001")
print("compressed:", a.compressed)
print("exploded :", a.exploded)
実行結果:
compressed: 2001:db8::1
exploded : 2001:0db8:0000:0000:0000:0000:0000:0001
:: は1アドレスにつき1回だけ使えます(2回使うと0の個数が定まらないため)。
アドレスの構造とプレフィックス
一般的なユニキャストは、前半64ビットがネットワーク(プレフィックス)、後半64ビットがインターフェースIDです。IPv4の「ネットワーク部/ホスト部」に対応しますが、ホスト部が常に64ビットと広大なのが特徴です。
graph LR P["プレフィックス(前半64bit・/64)"] I["インターフェースID(後半64bit)"] P --- I
アドレス種別
| 種別 | 範囲(プレフィックス) | スコープ | 用途 |
|---|---|---|---|
| グローバルユニキャスト GUA | 2000::/3 | インターネット全体 | 公開アドレス(IPv4のグローバル相当) |
| ユニークローカル ULA | fc00::/7(実質 fd00::/8) | 組織内 | 私設(IPv4のプライベート相当) |
| リンクローカル | fe80::/10 | 同一リンク内のみ | 隣接通信・自動生成・必須 |
| マルチキャスト | ff00::/8 | 範囲指定 | 1対多(ブロードキャストは廃止) |
| ループバック | ::1 | 自分自身 | IPv4の127.0.0.1相当 |
IPv6にはブロードキャストがなく、その役割はマルチキャストが担います(例 ff02::1 は全ノード)。リンクローカル(fe80::)はすべてのIPv6インターフェースに必ず1つ付き、近隣探索(NDP、ARPの後継)に使われます。
import ipaddress
# 注: 2001:db8::/32 は文書用に予約された範囲で is_private=True になる。
# ここでは実在のグローバルアドレス(Cloudflare DNS)で判定を示す。
for s in ["2606:4700:4700::1111", "fd00:abcd::1", "fe80::1", "::1"]:
a = ipaddress.IPv6Address(s)
kind = ("loopback" if a.is_loopback else
"link-local" if a.is_link_local else
"private/ULA" if a.is_private else
"global")
print(f"{s:20} -> {kind}")
実行結果:
2606:4700:4700::1111 -> global
fd00:abcd::1 -> private/ULA
fe80::1 -> link-local
::1 -> loopback
EUI-64 とSLAAC:自動でアドレスを作る
SLAAC(ステートレスアドレス自動設定)では、ルータが広告する**/64プレフィックスに、機器が自分でインターフェースIDを足して完成させます。インターフェースIDの古典的な作り方がEUI-64**で、48ビットMACから生成します。
手順:(1) MACを前半24bitと後半24bitに割り、間に FFFE を挿入、(2) 先頭バイトの7番目のビット(U/Lビット)を反転。
# MAC 00:1a:2b:3c:4d:5e から EUI-64 インターフェースIDを作る
mac = "00:1a:2b:3c:4d:5e".split(":")
b = [int(x, 16) for x in mac]
b[0] ^= 0b00000010 # U/Lビットを反転
eui = b[0:3] + [0xFF, 0xFE] + b[3:6] # 中央に FFFE を挿入
iid = "".join(f"{x:02x}" for x in eui)
iid = ":".join(iid[i:i+4] for i in range(0, 16, 4))
print("interface-id:", iid)
print("full address: 2001:db8:0:0:" + iid)
実行結果:
interface-id: 021a:2bff:fe3c:4d5e
full address: 2001:db8:0:0:021a:2bff:fe3c:4d5e
先頭が 00 から 02 に変わったのがU/Lビット反転の結果で、中央に ff:fe が挿入されています。現在はプライバシー上ランダムなインターフェースID(RFC 4941)も広く使われますが、EUI-64の仕組みはCCNAで問われます。
なぜIPv6へ移行するのか(設計の直観)
IPv4の32ビットは約43億で、世界の機器数に対し決定的に足りません。NATで延命してきましたが、NATは端点間の対等な接続(P2P)を壊します。IPv6の128ビット(約3.4×10の38乗)は枯渇の心配がなく、NATなしで端末ごとに公開アドレスを持てる世界へ戻します。アドレス自動設定(SLAAC)でDHCPなしでも繋がる手軽さも設計の狙いです。
⚠️ よくある誤解
- 「
::は何回でも使える」ではない。1アドレスに1回だけ。複数あると0の数が復元できません。 - 「IPv6にブロードキャストがある」ではない。廃止され、マルチキャスト(
ff02::1等)が代替します。 - 「リンクローカルは設定しないと付かない」ではない。
fe80::/10は自動で必ず付与され、近隣探索の土台になります。
対応 lab
[[networking-study/labs/03-05_ipv6.py]]— 短縮/展開・種別判定・EUI-64生成
関連
- 前:
[[03-04_ARPとICMP]]/章ハブ:[[03-00_ネットワーク層とIP_目次]] - IPv4の枯渇とNAT:
[[07-01_NAT_PAT]]/次章:[[04-01_TCP]]