简介
介绍IPv6的基本知识
包头
格式
IPv6的包头比IPv4更有效率,数据字段更少,去掉了包头校验和,更简单的报头提高了路由器的处理效率。新的扩展包头替代了IPv4的选项字段,并且提供了更多的灵活性。

IPv4的ToS字段替换成IPv6的Traffic Class字段IPv4的TTL字段替换成IPv6的Hop Limit字段
如下为IPv6的报头示例

IPv6中有个Next Header字段,指向下一个包头

其实这个拓展包头可以一直有个Next Header字段,就跟链表一样

拓展包头是有一定顺序(RFC2460)

| 报头类型 | Next Header 字段值 | 描述 |
|---|---|---|
| 逐跳选项报头 | 0 | 该选项主要用于为在传送路径上的每跳转发指定发送参数,传送路径上的每台中间节点都要读取并处理该字段,应用场景:用于巨型载荷用于路由器提示用于资源预留。所有路由器都要对其处理 |
| 目的选项报头 | 60 | 目的选项报头携带了一些只有目的节点才会处理的信息。目前,目的选项报头主要应用于移动 IPv6 。 |
| 路由报头 | 43 | 路由报头和 IPv4 的 Loose Source and Record Route 选项类似,该报头能够被 IPv6 源节点用来强制数据包经过特定的路由器。 |
| 分段报头 | 44 | 同 IPv4 一样,IPv6 报文发送也受到 MTU 的限制。当报文长度超过 MTU 时就需要将报文分段发送,而在 IPv6 中,分段发送使用的是分段报头。 |
| 认证报头 | 51(AH) | 该报头由 IPSec 使用,提供认证、数据完整性以及重放保护。它还对 IPv6 基本报头中的一些字段进行保护。 |
| 封装安全净载报头 | 50(ESP) | 该报头由 IPSec 使用,提供认证、数据完整性以及重放保护和 IPv6 数据报的保密,类似于认证报头。 |
| 上层包头 | … | 注意,三层以上的协议dhcp或者是dns均为负载部分,跟包头无关。58(ICMP),6(TCP),17(UDP) |
IPv6包头的改进
-
取消了
IP的校验第二层和第四层的检验已经足够健壮了,因此
IPv6直接取消了IP的三层校验 -
取消中间节点的分片功能
分片重组功能由源目两端自己进行,通过
PMTU机制发现路径MTU -
定义最长的
IPv6报头有利于硬件的快速处理,如此一来中间节点可以避免处理而节省大量的资源
-
安全选项的支持
IPv6提供了IPSec的完美支持,如此上层协议可以省去许多安全选项,如OSPFv3就取消了认证 -
增加流标签
提高
QoS效率
IPv6编址
地址简写方式
-
每组
16bits的单元中多个前导0可以省略成一个02001:00a8:0207:0000:0000:0000:0000:8207 2001:00a8:0207:0:0:0:0:8207 -
一个或多个连续的
16比特字段为0时,可用::表示,但整个缩写中只允许有一个::2001:00a8:0207:0:0:0:0:8207 2001:00a8:0207::8207
其他的简写示例
0000:0000:0000:0000:0000:0000:0000:0001
::1
2001:0410:0000:0000:FB00:1400:5000:45FF
2001:0410::f800:1400:5000:45ff
2001:0410:0000:1234:FB00:1400:5000:45FF
2001:0410::1234:FB00:1400:5000:45FF
3ffe:0000:0000:0000:1010:2a2a:0000:0001
3ffe::1010:2a2a:0:1
IPv6地址空间

按照地址大小顺序大概如下

单播地址
- aggregatable global unicast address可聚合全球单播地址
- site-local address 本地站点地址
- unique local address 唯一本地地址
- linklocal address 链路本地地址
- tentative address 临时地址
aggregatable global unicast address可聚合全球单播地址
-
相当于
IPv4全局单播地址 -
由48位的全局路由选择前缀+16位的子网ID+64位的接口ID组成。如
2001:BCFF:FEA6::/48表示一个IPv6路由前缀,2001:BCFF:FEA6:6C01::/64表示一个IPv6子网前缀
-
范围如下所示,占全球
IPv6总地址空间的八分之一。这个范围的大小为2*2^128,而总的空间为16 * 2 ^128。2000:0000:0000:0000:0000:0000:0000:0000 ~3FFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF -
其中部分地址另有用途
2001::/16,用于Teredo隧道,由IANA按地域和ISP进行分配2002::/16,6 to 4地址,用于6 to 4自动构造隧道技术的地址

想要查看自己电脑或者手机是否支持IPv6,可以登录这个网站查看
https://test-ipv6.com/index.html.zh_CN
这是我的电脑测试结果

手机连家里wifi的结果

手机流量测试结果

site-local address 本地站点地址
- 目前已弃用
- 类似于
IPv4私有地址 - 使用站点本地地址意味着需要
NAT,地址不是端到端的 - 地址开头为
FEC0::/10,紧接着是连续的38bits的0,前48bits总是固定的 - 在接口
ID和48bits特定前缀之间有16bits子网ID字段,供机构在内部构建子网 - 永远不会用于与全球
ipv6因特网通信,一般用于内网通信 - 被下面要讲的
unique local address唯一本地地址替代
虽然说是弃用,但是看我qemu模拟的arm64,有这种地址,scopeid 0x40<site>

unique local address 唯一本地地址
-
ULA是IPv6的私有地址,该地址在IPv6公网不会被路由,同网段可通信 -
用于取代前面的site-local address
-
地址块为
FC00/7,被划分位两个/8的块-
其中
FC00::/8未定义 -
FD00::/8定义如下
-
linklocal address 链路本地地址
Linux

Windows

-
有效范围为本地链路。不同链路的链路本地地址是可以重复的。
-
首先是怎么理解这个本地链路,个人对这个本地链路理解是只要是同个网络,也就是路由器的一个接口范围内,都是本地链路。比如下面这个示意图,A跟B都可以用这个
linklocal地址来通信。(亲测过)
-
其次是怎么理解不同链路的链路本地地址为什么可以重复。这就是因为
linklocal地址的接口ID了,这个接口ID跟MAC地址有一定的转换关系,至少在自己本地交换机链路上,可以确认是唯一的。
-
-
地址形式是以
FE80::/10为前缀(注意不是网络前缀,网络前缀固定是64),11-64位为0加 一个64位接口标识
-
接口ID
-
接口ID为64bits,用于标识链路上的接口,在每条链路上接口ID必须唯一
-
接口ID的作用
- 可用于构成
LinkLocal地址 - 可在无状态配置环境中用于构成
IPv6地址(这部分就是后面要讲的RA消息相关了)
- 可用于构成
-
接口ID的生成
-
自动生成随机接口ID(比如Windows)
-
手工配置接口ID(比如Linux)
放个图片
-
根据IEEE的EUI-64规范将48比特的MAC地址转化为64比特的接口ID
总结就是把MAC地址劈开,中间插入FFFE,设置UL位也即第七个bit

比如Linux的这个
linklocal地址
-
-
关于这个UL位,第七个bit是怎么取,貌似众说纷纭?有的说直接取1,有的说直接取0,有的说是取反。而我直接看内核的代码是取反的操作。
net/ipv6/addrconf.c中结构体ipv6_devconf指定了ipv6地址的生成格式为eui64

具体eui64的生成代码在函数addrconf_ifid_eui48
addrconf_addr_gen
ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
case IN6_ADDR_GEN_MODE_EUI64:
ipv6_generate_eui64(addr.s6_addr + 8, idev->dev)
addrconf_ifid_eui48(eui, dev);
addrconf_addr_eui48_base
memcpy(eui, addr, 3);
eui[3] = 0xFF;
eui[4] = 0xFE;
memcpy(eui + 5, addr + 3, 3);
if (dev->dev_id) {
eui[3] = (dev->dev_id >> 8) & 0xFF;
eui[4] = dev->dev_id & 0xFF;
} else {
eui[0] ^= 2;
}
addrconf_add_linklocal(idev, &addr, 0)
ipv6_add_addr
其中的dev_id是unsigned short类型,用于共享网络,不过这个变量的赋值我目前是搞不清楚的

不过从我的WSL来看,是符合这段代码的逻辑
cat /sys/class/net/eth0/dev_id

tentative address临时地址
地址::称为未指定地址,不能分配给任何节点。在节点获得有效的IPv6地址之前,可在发送的IPv6报文的源地址字段填入该地址,但不能作为IPv6报文中的目的地址。

组播地址
-
地址范围是
FF00::/8 -
地址格式

- 几个常见的组播地址(flags为
0000,scope为2),也即本地链路范围有效- FF02::1:表示链路上的所有节点
- FF02::2:表示链路上的所有路由器
- FF02::9:表示链路上的所有RIP路由器
- FF02::5:表示链路上的所有OSPF路由器
- FF02::6:表示链路上的所有OSPF DR路由器
-
组播
MAC地址的映射
-
被请求节点组播地址
Solicited-node-
主要用于重复地址检测(DAD)和替代
ipv4中的ARP -
由前缀FF02::1:FF00:0/l04和
ipv6单播地址的最后24位组成 ,一个ipv6的单播地址对应一个Solicited-node地址,对应关系如下
-
Solicited-node地址受限范围为本地链路范围
-
Well-Known Multicast IPv6 Address

任意播地址
任意播地址,标识多个接口,目的为任意播地址的报文会被送到最近的一个被标识接口,最近节点是由路由协议来定义的。任意播地址用单播地址的形势。
不是很理解这个任意播地址,等后续更新再补充。
根据网上查到的资料一跟资料二,我理解这个任意播地址是路由器才会有的?而且多用于移动IPv6?
比如我下面的wsl,tap0网卡开了转发选项,而且运行了radvd服务(让自己看起来是个路由器?)

特殊地址
未指定地址
::/128,即 0:0:0:0:0:0:0:0。只能作为尚未获得正式地址的host的源地址,不能作为目的地址,不能分配给真实的网络接口
环回地址
::1/128,相当于 IPv4 中的回环地址lo 127.0.0.1
ORCHID
原型是Overlay Routable Cryptographic Hash Identifiers,地址范围是2001:10::/28,这些是不可送达的 IPv6 地址,用于加密散列识别