简介
介绍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
可以省略成一个0
2001: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
地址,用于加密散列识别