浅谈IPv6地址

前言

2019年11月25日,全球五大区域互联网注册管理机构之一的欧洲网络协调中心(RIPE NCC)宣布 IPv4 地址已全部用完,该机构在其声明中写道:我们从可用池中仅剩的地址里分配了最后的 /22 IPv4。

IPv4地址空间已经消耗殆尽, 能够一直使用还在与NAT技术的发明。

随着IPv4地址空间的消耗, 近乎无限地址空间的IPv6"闪亮登场"。

IPv4与IPv6区别

两者在本质上以及数量上的区别:

          版本              长度                                                   地址数量
         IPv4             32 bit                                              4,294,967,296
         IPv6            128 bit               340,282,366,920,938,463,463,374,607,431,768,211,456

两者的报头对比如下

IPv4 Header:

IPv6 Header:

(图来自51CTO.com)

IPv6是在IPv4的基础上进行改进的, 增加了流标签域, 去除了一些冗余的字段, 使得报文头的处理更加简单高效。

  • IPv4

可用地址有限; (十进制数)

安全性差;

无法实现端到端的控制

  • IPv6

近乎无限的地址; (十六进制数)

内嵌AH和ESP;

可有效与QOS结合使用

IPv6地址分类

IPv6地址分为单播地址、任播地址、组播地址三种类型

地址范围 描述
2000::/3 全球单播地址
FEC0::/10 本地站点地址
FE80::/10 链路本地地址
FF00::/8 组播地址
::/0 缺省地址
::1/128 环回地址

本地站点地址以 FEC0 开头, 相当于IPv4里的192.168.*.*的192 (可以这么理解);

链路本地地址以 FE80 开头, 通信只能在局域网内进行, 不同的网段不能通信, 只能在同一局域网内使用, 这里是和IPv4不同的;

组播地址可以理解为网关, 作为整个网段的一个终端;

缺省地址相当于IPv4里的0.0.0.0;

环回地址相当于本地环回地址127.0.0.1

与IPv4不同的是, IPv6不存在广播地址, 增加了任播地址。

IPv6地址格式

IPv6地址长度为128比特(bit), 每16bit划分为一段, 每段由4个十六进制数表示, 并用冒号隔开;

IPv6地址包括网络前缀和接口标识两部分

有如下一个IPv6地址:

FEC0:0000:0000:0001:0000:0000:0000:0001/64

这种写法其实相当于IPv4里的192.168.1.1/24

IPv6网络前缀由公共拓扑&站点拓扑两大部分组成, 其中公共拓扑总共占48位, 站点拓扑占16位; 从运营商得到的是前48位固定, 即FEC0:0000:0000, 相当于192.168; 后16位子网用户自行划分, 即0001, 相当于192.168.1.* 或者 192.168.2.*; 剩下的就是主机位了, 一共可以有2^64个主机 (已经很多了)

前缀长度的作用类似与IPv4中的子网掩码, 用于区分的部分是接口标识。

接口标识与IPv4中的主机部分类似, 用于标志网络中的主机身份。

如何区分网络前缀和主机标识

将网络前缀与IPv6地址进行&运算即可

  • 举个栗子

在IPv4中,  192.168.1.0/24 与 192.168.2.0/24 是否能通信?

首先来看 192.168.1.0/24

网络前缀 (子网掩码) 中可知, 前24位都是1:

11111111 11111111 11111111 00000000

那么IPv4地址为 192.168.1.0:

11000000 10101000 00000001 00000000

两者进行&运算:

11111111 11111111 11111111 00000000
11000000 10101000 00000001 00000000
                                     &
---------------------------------------
11000000 10101000 00000001 00000000

得到的结果为:   11000000 10101000 00000001 00000000

在来看 192.168.2.0/24, 将网络前缀与IPv4地址进行&运算之后得到:

11111111 11111111 11111111 00000000
11000000 10101000 00000010 00000000
                                     &
---------------------------------------
11000000 10101000 00000010 00000000

得到的结果为:   11000000 10101000 00000010 00000000

两者不相等, 故192.168.1.0/24与192.168.2.0/24不在同一局域网内, 不能通信。

但是 192.168.1.0/16与192.168.2.0/16 就在同一局域网内, 感兴趣的读者可以自行尝试计算。

  • 在IPv6中

与IPv4同样的原理,  假设有:  FEC0:0000:0000:0001:0000:0000:0000:0001/64

网络前缀 (相当于子网掩码):

1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111

IPv6:

1111 1110 1100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001

IPv6地址压缩格式

IPv6地址很长, 所以产生了压缩省略的写法:

  • 每一组中的前导 '0' 都可以省略;
  • 地址中包含连续全为0的组, 可以用双冒号 '::' 来代替

值得注意的是,  形如fec0中的0不能省略, 举个很简单的例子, 010可以省略为10, 但不能记为01

还有一种情况

假设有IPv6:  

fec0:0:0:1:0:0:0:1

若省略记为:

fec0::1::1

那么就不知道两个 '::' 处那个是有两个0, 哪个是有三个0的了, 造成一种混淆模糊的写法。

只能记为:

fec0:0:0:1::1
或者
fec0::1:0:0:0:1

IPv6单播地址

全球单播地址带有固定前缀, 类似与IPv4中的公网地址。

IPv6链路本地单播地址

链路本地单播地址前缀为FE80::/10

IPv6组播地址

这里介绍下组播地址, (没有IPv4的广播了)

  • 所有组播地址都以FF开头;
  • IPv6为需要使用组播发送数据的协议预留了一些组播租
地址范围 描述
FF02::1 链路本地范围的所有节点 (终端设备)
FF02::2 链路本地范围的所有路由器 (网络设备)

IPv6任播地址

任播地址用来标识一组网络接口, 在给多个主机或者节点提供相同服务的时候, 会提供冗余和负载分担。

假设有任播地址 2001:0DB8::84C2, 有多个区域访问该地址, 那么任播地址就会根据客户端的距离来分别相同的服务器给其访问, 从而减少负载。

EUI-64规范

IPv6地址配置起来实在太麻烦了,  所以产生了EUI-64规范来自动配置IPv6地址。

EUI-64规范是生成后64位的主机位的, 它是根据48位以太网的MAC地址来生成对应的IPv6地址, 方法如下:

将FFFE插入MAC地址的前24位与后24位之间, 并将第7位的0改为1即可生成接口ID

举个例子:

假设有一台主机的MAC地址为: 

4c1f-cc4d-2cd5

将 fffe 插入MAC地址的前24位与后24位之间:

4c1f-ccfffe4d-2cd5

并将第7位的0改为1

  4   c    1    f    ...
0100 1100 0001 1111  ...

第7为的0改为1:

  4   e    1    f    ...
0100 1110 0001 1111  ...

最后生成的后64位主机位为:

4e1f:ccff:fe4d:2cd5

配合前64位固定的链路本地地址 fe80::, 组合得到:

fe80::4e1f:ccff:fe4d:2cd5

IPv6无状态地址DAD检查

在IPv4中, 为防止ip配置冲突, 采用了 ARP 缓存对应表来判断ip是否被使用。

在IPv6中,

  • 用DAD (Duplicate Address Detection) 来检测在本地链路范围内将要使用的IPv6地址是否唯一;
  • 目的地址(多播地址) = ff02::1ff00::/104 + 该接口本地链路地址的后24位。

假设主机A要使用目的地址:  2000::1

那么A就会向本地链路范围内发送数据包:

ICMP TYPE = 135                   // 代表发送一个请求
Source = ::                       // 代表未知源
Destination = ff02::1:ff00:1      // 目的地址 (多播地址) = ff02::1ff00::/104 + 该接口本地链路地址的后24位
Data = 2000::1                    // 要使用的目的地址
Query = is this address in use ?

假设有主机B整在使用 2000::1, 且收到了刚刚的数据包, 那么它会回复以下数据包:

ICMP TYPE = 136                   // 代表发送一个报文
Source = 2000::1                  // 代表主机B
Destination = ff02::1             // 链路本地范围的所有节点, 主机A在其中(终端设备)
Data = 2000::1                    // 正在使用的目的地址
Query = i am using this address

表示 2000::1 已经在使用了, 主机A配置失败;

反之, 一段时间内,若链路上没有谁回复,或者收到同样结构的NS报文,则认为该地址在链路上具有唯一性,配置生效。

猜你喜欢

转载自blog.csdn.net/angry_program/article/details/106030037