网络网络层之(3)IPv6协议
Author: Once Day Date: 2024年4月2日
一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦...
漫漫长路,有人对你微笑过嘛...
全系列文档可参考专栏:通信网络技术_Once-Day的博客-CSDN博客。
参考文章:
- 《TCP/IP详解卷一》
- IEEE RA Guidelines for Use of EUI, OUI, and CID
- IPv6本地链路地址生成方式_ipv6_addr_gen_mode-CSDN博客
- RFC 2373: IP Version 6 Addressing Architecture (rfc-editor.org)
- RFC 2464: Transmission of IPv6 Packets over Ethernet Networks (rfc-editor.org)
- RFC 4291: IP Version 6 Addressing Architecture (rfc-editor.org)
文章目录
- 网络网络层之(3)IPv6协议
-
-
-
- [1. 概述](#1. 概述)
-
- [1.1 基础信息](#1.1 基础信息)
- [1.2 IPv6地址简化表示方法](#1.2 IPv6地址简化表示方法)
- [2. IPv6地址](#2. IPv6地址)
-
- [2.1 IPv6地址构成](#2.1 IPv6地址构成)
- [2.2 IPv6本地链路地址](#2.2 IPv6本地链路地址)
- [3. IPv4和IPv6地址转换](#3. IPv4和IPv6地址转换)
-
- [3.1 单播地址转换](#3.1 单播地址转换)
- [4. IPv6组播地址](#4. IPv6组播地址)
-
- [4.1 组播地址格式](#4.1 组播地址格式)
- [4.1 特殊组播地址](#4.1 特殊组播地址)
-
-
1. 概述
1.1 基础信息
IPv6地址是互联网协议第六版(Internet Protocol Version 6)的一部分,它是为了解决IPv4地址耗尽问题而设计的新一代互联网地址协议。
IPv6地址使用128位地址长度,相较于IPv4的32位,大幅增加了地址空间,可以为地球上几乎每一粒沙子分配一个唯一的网络地址。
它通常使用十六进制表示,并且通过冒号(:)分隔成8组,每组4个十六进制数。例如,一个IPv6地址可能看起来像这样:2001:0db8:85a3:0000:0000:8a2e:0370:7334
。
IPv6很多地方规则与IPv4一致,因此本文不再描述那些与IPv4一样的内容,而是谈谈IPv6比较独特的地方。
1.2 IPv6地址简化表示方法
IPv6地址由于其128位的长度,以标准方式表示时非常长,因此在实际使用中,人们通常会采用简化表示法来减少地址的复杂性。IPv6地址简化的基本规则包括以下方面[RFC4291]:
-
省略前导零:在IPv6地址的每个16位字段中,可以省略字段起始部分的所有零。例如,"0042"可以简化为"42","0A00"可以简化为"A00"。
-
双冒号缩写:在IPv6地址中,一连串的零可以被替换为"::"(双冒号)。这个简化规则只能使用一次,因为多次使用会造成地址不明确。例如,
2001:0db8:0000:0000:0000:0000:1428:57ab
可以被简化为2001:0db8::1428:57ab
。如果地址中有多个零段,通常会将最长的连续零段替换为"::"以进行最大程度的简化。 -
在IPv6格式中嵌入IPv4地址可以采用混合符号形式,紧接着IPv4部分的地址块的值为ffff,地址其与部分使用点分四组格式。如
::ffff:10.0.0.1
表示由IPv4地址(10.0.0.1
)映射的IPv6地址。 -
IPv6地址的低32位通常采用点分四组表示法,例如
::0102:f001
可以表示为::1.2.240.1
,称为IPv4兼容的IPv6地址。
例如,完整的IPv6地址2001:0db8:0000:0000:0000:0000:0000:0001
可以被简化为2001:0db8::1
。
需要注意的是,"::"不能用于省略单个零段,因为这会导致地址的歧义。
RFC5952\]制定了一些规则,以缩小选择范围,减少不必要的混淆。
1. 前导的零必须被压缩,例如`2001::0001`变成`2001::1`。
2. `::`用于影响最大的地方,以压缩最多的零,如果多个块中包含等长度的零,顺序靠前的块将被替换为`::`。
3. a到f的十六进制数字应该使用小写表示。
在URL等场景下,IPv6的冒号会和端口号冲突,因此需要使用括号包围IPv6地址,如下表示:
```yacas
https://[2001:6666]:443
```
##### 2. IPv6地址
###### 2.1 IPv6地址构成
IPv6地址比IPv4长了四倍,因此能表示的地址数目范围非常大,也没有像IPv4一样分为A/B/C/D类地址。
IPv6吸取了IPv4子网划分的优点,直接一步到位,使用CIDR表示,通过前缀表示法,来划分许多特殊地址范围,如`fe80::/10`范围内的地址全都是本地链路地址,不能用于公共互联网。
IPv6也没有广播地址,因此不用像IPv4一样去区分子网号和主机号,直接根据地址范围划分作用。
常见IPv6地址范围划分如下:
| 前缀 | 描述 |
|-----------------|------------------------------------------------------------------------------|
| `::/0` | 默认路由条目,不用于寻址。 |
| `::/128` | **未指定地址** (Unspecified Address),可用于源IP地址。 |
| `::1/128` | **环回地址** (Loopback Address),类似于IPv4中的127.0.0.1。 |
| `fc00::/7` | **唯一本地地址** (Unique Local Address, ULA),不用于公共互联网。 |
| `fe80::/10` | **链路本地地址** (Link-Local Address),只在单个链路上有效,不会被路由器转发到其他链路。 |
| `ff00::/8` | **多(组)播地址** (Multicast Address),仅作为目的IP地址使用。 |
| `::ffff:0:0/96` | **IPv4映射地址** (IPv4-mapped IPv6 Address),只用于内部主机。 |
| `64:ff9b::/96` | **IPv4-IPv6转换地址** (IPv4-IPv6 Translation Address),用于自动IPv4/IPv6转换机制(如NAT64)。 |
通常一个网络接口上会有多个IPv6地址(本地链路地址+全球单播地址+组播地址等等),而IPv4一般只有一个地址。
###### 2.2 IPv6本地链路地址
链路本地IPv6地址使用接口标识符(IID)作为组成之一,通常直接由接口的链路层MAC地址形成,如下:

在IEEE标准中,EUI表示扩展唯一标识符,分成EUI-64和EUI-48版本。以太网中常用的是EUI-48的短格式版本,两者区别是其长度不一样。
EUI-48也就是常说的MAC地址,其第一个字节最低倒数第二位(U/G)表示该MAC地址是全局MAC地址还是本地MAC地址。
EUI-48通过在第三个字节和第四个字节中插入两个字节(0xFFFE)可以转化成EUI-64地址,再取反(U/G)位,便可以用于链路本地IPv6地址的接口标识符组成。**反转目的是将原来的全局MAC地址变成本地MAC地址,正好对应链路本地IPv6地址含义**。
例如,接口MAC地址是`00:11:22:33:44:55`,那么其IPv6链路本地地址是`fe80::0211:22ff:fe33:4455`。
下面是Linux设备上的IPv6链路本地地址实例:
```yacas
ubuntu->~:$ ifconfig eth0
eth0: flags=4163