学新通技术网

IPv6与IPv4对比学习

juejin 21 1
IPv6与IPv4对比学习

前言

本文没有直接罗列IPv6的各种特性,而是通过对比的方式来介绍该协议。在学习知识的过程中,了解相关的历史背景有助于我们更好的掌握该知识点,某种程度上来说,IPv4就是IPv6产生的历史背景,因此,笔者认为通过熟悉的IPv4来学习不那么熟悉的IPv6是一种不错的学习方式。

可以将本文看作相关知识点的概述和索引,文章首先介绍了IPv4和IPv6的地址表示和数据报区别,然后详细介绍了编址方法的演进,最后介绍了各类地址的分配方式以及与IPv4和IPv6相关的协议。

地址表示

IPv4地址

  • 使用32位正整数表示,需要4字节存储,可以提供约2^32≈4.3x10^9个地址;
  • 表示方法:为了方便记忆采用了点分十进制的标记方式,如114.114.114.114就是一个IPv4地址。

IPv6地址

  • 采用128位正整数表示,需要16字节存储,可以提供约2^128≈3.4x10^38个地址;
  • 表示方法:如果采用与IPv4相同的标记方式,则地址会很长,因此点分十进制不再适用。于是人们采用了冒号十六进制法来表示IPv6地址,它将每个16位的值用十六进制表示,各值之间用冒号分隔,如2001:0DB8:0000:0023:0008:0800:200C:417A就是一个IPv6地址;
  • 简化方式1:在这一表示方法中,允许将每个16进制值的前导0省略,即上面的地址可以表示为2001:DB8:0:23:8:800:200C:417A;
  • 简化方式2:某些情况下,一个IPv6地址可能包含很长的一段0,可以把一段连续的0压缩为::,如FF01:0:0:0:0:0:0:1101可以表示为FF01::1101。但为了保持地址解析的一致性,零压缩在一个地址中只能使用一次,如FF01:0:0:0:8:0:0:1101可以表示为FF01::8:0:0:1101或FF01:0:0:0:8::1101,不能表示为FF01::8::1101。

数据报格式

IPv4和IPv6数据报结构如下图所示,其中左侧为IPv4首部和数据报,右侧为IPv6首部和数据报。

流程图.jpg

图1 IPv4与IPv6数据报结构图

IPv4

IPv4首部字段如表1所示:

字段名 长度 说明
版本 4 bit IP协议的版本号,在IPv4中始终为4。
首部长度 4 bit 首部长度,单位为4字节。假如首部的长度为20字节,则首部长度字段应为0101=5,即5*4=20字节,因此这也导致了首部长度必须为4字节的整数倍,当首部长度不是4字节的整数倍时,需要用最后的填充字段来填充。
区分服务 8 bit 用于保证QoS,最初被定义为服务类型字段,实际上并未使用,1998年被IETF重定义为区分服务。只有在使用区分服务时,这个字段才起作用,一般的情况下该字段不被使用,这里给出一个使用该字段的例子:VoIP。
总长度 16 bit 表示首部和数据部分长度之和,单位为字节。因此IPv4数据报最长为65535字节。
标识 16 bit 用于标识属于相同数据报的分片,当数据报大小超过MTU需要分片时,所有数据报片就会被赋予一个相同的标识。
标志 3 bit 只有其中2位被使用,分别为MF和DF。其中: MF为1表示仍有其他分片,MF为0则表示当前分片为最后一个分片; DF为1表示不能分片,DF为0则表示可以分片。
片偏移 13 bit 较长的分组在分片后,某个分片在原分组的相对位置,单位为8字节。
生存时间 8 bit 用于表示数据报在网络中的跳数限制。每经过一个路由器,路由器就会将TTL减1,当生存时间为0时,该数据报会被丢弃.
协议 8 bit 指出此数据报携带的数据使用的是何种协议。
首部校验和 16 bit 用于校验首部。
源地址 32 bit 发送端地址。
目的地址 32 bit 接收端地址。
可选字段 可变 很少被使用,用于支持排错,测量和安全等措施。长度可变,从1到40个字节不等。

表1 IPv4首部字段

IPv6

2017年7月发布的IPv6协议文档:RFC 8200: Internet Protocol, Version 6 (IPv6) Specification,目前已成为互联网正式标准,IPv6的首部字段如下表所示:

字段名 长度 说明
版本 4 bit IP协议的版本号,在IPv6中始终为6。
通信量类 8 bit 类似于IPv4的区分服务字段,详细了解可参考RFC 2474RFC 3168
流标签 20 bit 使用源地址, 目的地址和流标签构成的三元组唯一确定一个流, 因而属于同一个流的数据报都拥有相同的流标签,运营商可以为特定流保证指明的服务质量。详细了解可参考RFC 6437
有效载荷长度 16 bit 有效载荷的大小,单位为字节。
下一个首部 8 bit 当没有扩展首部时,该字段与IPv4首部中的协议字段相同; 当出现扩展首部时,该字段则用于标识第一个扩展首部的类型; 其应用如图2所示。
跳数限制 8 bit 与IPv4首部中的生存时间相同,由发送端赋值,每经过一个路由器便减1,当值为0时,如果是中间路由器则将该数据报直接丢弃,如果是接收端则正常接收。
源地址 128 bit 发送端地址。
目的地址 128 bit 接收端地址。

表2 IPv6首部字段

有效载荷内容如下表所示:

字段名 说明
扩展首部 在IPv6中,可选的网络层信息被编码在单独的扩展首部中,这些扩展首部可以放置在数据报中首部和上层协议首部之间。扩展首部可以有0个或多个,根据不同的需要可以装载不同的首部,比如要实现IPv4中的分片功能,只需要增加一个分片扩展首部即可,图2为RFC 8200给出的扩展首部应用示例。
数据 IPv6数据报中的数据部分。

表3 有效载荷内容

流程图 (1).jpg

图2 扩展首部示意图

区别

相比IPv4,IPv6首部:

  • 去掉了“首部长度”,这是因为IPv6的首部变成了固定的40字节,无需再保存首部长度;
  • 去掉了“标识”、“标志”、“片偏移字段”,分片的职责被移交给了“下一个首部”和“扩展首部”,同时IPv6不再允许在中间路由器进行分片与重组,仅允许在源与目标主机执行此操作;
  • 去掉了“首部校验和”,这是由于数据链路层和传输层均有校验机制。取消该字段能够加快路由器对数据报的处理速度;
  • 去掉了“可选”字段,这一职责同样被移交给“下一个首部”和“扩展首部”完成,增加了路由器的处理速度;
  • 将“总长度”调整为了“有效载荷长度”,该字段在调整后仅表示有效载荷的长度;
  • 将“生存时间”调整为了“跳数限制”,命名与作用更加一致;
  • 将“协议”调整为了下一个首部;
  • 将“源地址”与“目的地址”的长度由32位增加到了128位;
  • 对“区分服务”的调整以及增加了“流标号”字段,笔者对这两个字段了解有限,这里不做介绍。

IPv6的有效载荷:

  • 增加了“扩展首部”,首部和扩展首部构成了一个“链表”,其扩展性更好,同时去掉了“选项”字段,并将该职责改为由扩展首部完成,这一变化大大增加了中间路由器的处理速度。

示例

以下为笔者使用tcpdump抓取的两个IPv6数据报。

数据报1

➜  ~ sudo tcpdump -nnnvvx -i en0 ip6tcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes20:44:31.278891 IP6 (class 0xc0, hlim 255, next-header ICMPv6 (58) payload length: 64) fe80::7ec3:85ff:fecc:79f1 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 64        hop limit 64, Flags [managed, other stateful], pref medium, router lifetime 1800s, reachable time 0ms, retrans timer 0ms          source link-address option (1), length 8 (1): 7c:c3:85:cc:79:f1            0x0000:  7cc3 85cc 79f1          mtu option (5), length 8 (1):  1500            0x0000:  0000 0000 05dc          prefix info option (3), length 32 (4): fdbd:ff1:ce00:1e2::/64, Flags [onlink, auto], valid time 2592000s, pref. time 604800s            0x0000:  40c0 0027 8d00 0009 3a80 0000 0000 fdbd            0x0010:  0ff1 ce00 01e2 0000 0000 0000 0000        0x0000:  6c00 0000 0040 3aff fe80 0000 0000 0000        0x0010:  7ec3 85ff fecc 79f1 ff02 0000 0000 0000        0x0020:  0000 0000 0000 0001 8600 4550 40c0 0708        0x0030:  0000 0000 0000 0000 0101 7cc3 85cc 79f1        0x0040:  0501 0000 0000 05dc 0304 40c0 0027 8d00        0x0050:  0009 3a80 0000 0000 fdbd 0ff1 ce00 01e2        0x0060:  0000 0000 0000 0000

黄色部分为二进制形式的IPv6首部,红色部分为tcpdump输出的对上述二进制数据的解释。

该数据报首部“版本”字段为6(0x6),“通信量类”字段为192(0xc0),“流标号”字段为0x00000,“有效载荷长度”字段为64(0x0040),“下一个首部”字段为58(0x3a),58表示其上层协议为ICMPv6,“跳数限制”字段为255(0xff),“源地址”为fe80::7ec3:85ff:fecc:79f1,“目的地址”为ff02::1。

数据报2

➜  ~ sudo tcpdump -nnnvvx -i en0 ip6tcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes20:44:36.367298 IP6 (flowlabel 0x10600, hlim 64, next-header TCP (6) payload length: 20) fdbd:ff1:ce00:1e2:18ff:2705:9ad:1a0e.54543 > 2606:50c0:8003::153.443: Flags [.], cksum 0xd482 (correct), seq 3464437871, ack 906010154, win 2048, length 0        0x0000:  6001 0600 0014 0640 fdbd 0ff1 ce00 01e2        0x0010:  18ff 2705 09ad 1a0e 2606 50c0 8003 0000        0x0020:  0000 0000 0000 0153 d50f 01bb ce7f 206f        0x0030:  3600 9e2a 5010 0800 d482 0000

该数据报首部“版本”字段为6(0x6),“通信量类”字段为0(0x00),“流标号”字段为0x10600,“有效载荷长度”字段为20(0x0014),“下一个首部”字段为6(0x06),6表示其上层协议为TCP,“跳数限制”字段为64(0x40),“源地址”为fdbd:ff1:ce00:1e2:18ff:2705:9ad:1a0e,“目的地址”为2606:50c0:8003::153。

编址方法

在介绍具体的编址方法之前,我们需要明确的一点是:无论IPv4还是IPv6,其地址都会被划分为多级地址,每一级地址的提出、修改以及删除都是为了解决当时存在的问题,而编址方法的演进,其本质就是多级地址划分方法的演进。请各位读者在阅读本小节时,注意关注每种编址方法中每一级地址的作用,这会对我们理解相关编址方法很有帮助。下面为大家介绍IPv4和IPv6的编址方法。

首先是IPv4,对IPv4地址的编址总共经过了三个历史阶段,按照时间顺序分别为:分类地址、划分子网以及无分类编址(CIDR)。

IPv4分类编址

分类的IPv4地址是最基本的编址方法,于1981年在RFC 791: Internet Protocol中被提出。在这种编址方法下,每个IPv4地址都被划分为了两部分,分别为网络号和主机号,即:

32位IPv4地址::={<n位网络号>,<32-n位主机号>}

网络号用于标识主机所连接的网络,而主机号则用于标识该主机。该方法使用网络号中包含的特定前缀位来确定网络号以及网络规模,进而将IPv4地址空间划分为具有若干个固定数目地址的地址块,其具体类别如下表所示:

类别 前缀位 网络地址位数 剩余的位数 网络数 每个网络的主机数
A类地址 0 8 24 128 16,777,214
B类地址 10 16 16 16,384 65,534
C类地址 110 24 8 2,097,152 254
D类地址(多播) 1110 未定义 未定义 未定义 未定义
E类地址(保留) 1111 未定义 未定义 未定义 未定义

表4 分类编址方法中的地址类别

其中,A类、B类、C类地址为单播地址,D类为多播地址,E类为保留地址,对于A、B、C类网络,上文中的n分别等于8、16、24,举一个例子:114.251.196.8中114化为二进制为01110010,前缀位为0,则该地址为A类地址。

另外,我们可以看到,表中展示的每个网络的主机数似乎都比该网络拥有的最大地址数少2,比如C类网络最多包含256个地址,每个网络的主机数应该是256,而表中却是254个,这是为什么呢?这是因为在IP地址中,主机号全0代表本网络,主机号全1代表本网络的广播地址,因此在计算某个网络的主机数时,需要将这两个地址排除,这一规则在后文其他IPv4编址方法中同样适用。

最后,需要说明的是,根据RFC 1812: Requirements for IP Version 4 Routers,由于无分类编址的出现,A、B、C类地址的划分已成为历史,目前我们说的A、B、C类地址,仅表示一类前缀长度分别为/8、/16、/24的地址块。

IPv4划分子网

在某个机构申请IP地址时,实际上是获得了具有相同网络号的一块地址,有的机构对地址数目的需求量大,有的需求量小,分类编址方法在当时被认为能够更好的满足不同类型用户的需求。但在实际应用中发现分类编址方法具有以下问题:

  • A类和B类网络即将耗尽,C类网络又太小,无法满足大多数组织的需要,拥有A类或B类网络的组织可以将自己的一部分地址块与其他组织共享。
  • 两级IP地址不够灵活,出于安全性和管理方便的考虑,有必要将自己的大网络划分为若干个子网;

为解决上述问题,1985年RFC 950: Internet Standard Subnetting Procedure提出:在IPv4地址中增加一个子网号字段,使分类编址方法中的两级地址变为了三级地址,即在分类编址方法的基础上从主机号中借用m位作为子网号,则地址结构就变为:

32位IPv4地址::={<n位网络号>,<m位子网号>,<32-m-n位主机号>}

这样一个网络就可以被分为若干个较小的子网,并且每个子网都有自己的子网地址,此做法被称为划分子网。

图3 划分子网

图4 划分子网路由转发原理

划分子网的实现采用子网掩码,子网掩码是一个32位的数,它的左边a位全为1,右边32-a位全为0,在提取某个地址所属子网的地址时,路由器使用子网掩码和该地址做与运算,便可得知该地址属于哪个网络,未划分子网时,A、B、C类的网络默认的子网掩码是255.0.0.0、255.255.0.0、255.255.255.0。划分子网的应用如图3所示,A类网络114.0.0.0被划分为了4个子网:

  • 子网1:114.0.0.0,子网掩码为255.192.0.0;
  • 子网2:114.64.0.0,子网掩码为255.192.0.0;
  • 子网3:114.128.0.0,子网掩码为255.192.0.0;
  • 子网4:114.192.0.0,子网掩码为255.192.0.0。

由于我们要将整个网络平均划分为4个子网,需要2位才能表示,因此a=8+2,每个网络的子网掩码均为255.192.0.0。每个子网内的主机通过交换机连接,子网掩码的应用如图4所示,当目的地址为114.66.3.3的数据报到达该网络时,路由器将目的地址与每个子网的子网掩码做与运算(在本例中由于四个子网掩码的子网掩码均为255.192.0.0,篇幅限制笔者只做了一次运算),图4运算后得到114.64.0.0,该地址与子网2的地址匹配,因此将该数据报转发到子网2对应的端口。在本例中,1. 114.66.3.3为A类地址,网络号共8位,为114;2. 网络被划分为4个子网,因此子网号共2位,为1(01)。另外,从114.0.0.0外部看,这就是一个普通的A类网络,外部无需关心该网络被划分为多少个子网,但在这个网络内,可以看到该网络被划分为了四个子网络。

IPv4无分类编址

1992年互联网面临着三个必须尽快解决的问题:

  • 分类编址方法提供的地址块分布不够平衡,B类地址块太大,C类地址块太小,人们需要的是中等大小的地址;
  • 互联网主干网的路由表规模急剧增长;
  • 未来IPv4地址将全部耗尽;

IETF认为第三个问题是比较长远问题,因此专门成立IPv6工作组来解决这个问题。而前两个问题被预计在1994年变得非常严重,因此IETF在RFC 1519: Classless Inter-Domain Routing (CIDR): an Address Assignment and Aggregation Strategy中提出采用无分类编址CIDR来解决前两个问题,CIDR也是目前被广泛应用的编址方式。

CDIR消除了传统A、B、C类地址以及划分子网的概念,不再沿用划分子网时的三级地址,而是重新使用两级地址,地址被划分为两部分,前半部分是网络前缀,用来指明网络,后半部分是主机号,用来指明主机,其记法是:

32位IPv4地址::={<n位网络前缀>,<32-n位主机号>}

与分类编址方法不同的是,这里的n,不再是分类编址方法中固定的8、16、24,而是取决于地址块的大小,n可以是1、2、3、...、32。为此,CIDR采用斜线记法,即在IP地址后加上“/”以及网络前缀位数,来标识网络前缀所占位数。只要看到CIDR地址块中的任何一个地址,就能知道这个地址块的起始地址,以及地址块中的地址数,如128.14.35.7/20是某个CIDR地址块中的地址,其中的“/20”表示网络前缀占20位,网络地址为128.14.32.0,该地址块最小可用地址为128.14.32.1,最大可用地址为128.14.47.254,共包含4094个可用地址。

有了CIDR后,地址块是如何分配的呢?分配地址的责任被交给了互联网名称与数字地址分配机构(ICANN),它将大块的地址块分配给五个地区互联网注册管理机构(RIR)。然后,RIR将小一些的地址块分配给互联网服务提供商(ISP),再由互联网服务提供商将地址分配给其他组织和个人用户,其中的地址块采用CIDR表示。

单位 地址块 地址数
大学 206.0.68.0/22 1022
计算机系 206.0.68.0/23 510
电子系 206.0.70.0/24 254
数学系 206.0.71.0/25 126
生物系 206.0.71.128/25 126
计算机系子网1 206.0.68.0/25 126
计算机系子网2 206.0.68.128/25 126
计算机系子网3 206.0.69.0/25 126
计算机系子网4 206.0.69.128/25 126

表5 CIDR子网的划分

通过CIDR,子网的划分更加灵活,能够根据需要更加有效的分配地址块,比如ISP分配给一个大学地址块206.0.68.0/22,它可以自由地向本校各系分配,而各系还可以根据情况再对分配到的地址块进行划分,如表5所示。

由于一个CIDR地址块中有很多地址,所以路由表中就利用CIDR地址块来查找目的网络。这种地址的聚合被称为路由聚合,也被称为构成超网。它使得路由表中的一个项目可以表示原来传统分类编址的很多个路由(例如上千个),进而解决了互联网主干网的路由表规模急剧增长的问题。

地址块 说明
0.0.0.0/32 本网络的本主机
255.255.255.255/32 本网络的广播地址
127.0.0.0/8 环回地址
10.0.0.0/8 私有的三块地址
172.16.0.0/12  
192.168.0.0/16  
169.254.0.0/16 链路本地地址

表6 一些不在公网上转发的地址

最后,表6给出了一些保留用作特殊用途、不在公网上转发的地址。

IPv6编址方法

在介绍IPv6编址方法前,先为各位介绍前缀标记,后续的地址分类都是以前缀标记为基础的。IPv6地址前缀的表示方式采用类似于IPv4 CIDR的方法,同样使用斜线记法,即:

128位IPv6地址/n位前缀位数

n为1、2、3、...、128。如:2001:DB8:AAAA:1111::/64表示该地址最左侧连续64比特为前缀部分,剩余其他64比特被称为该地址的接口ID。

image.png

图5 IPv6地址类型

IPv6地址有三类,分别为单播地址、任播地址和多播地址,图5给出了这三种地址类型的信息,由于任播地址目前还处于试验阶段,本文不做介绍。下面介绍其他两种类型的地址。

单播地址

单播地址能够唯一标识IPv6设备上的接口,单播地址包含环回地址、未指定地址、全局单播地址、链路本地地址、唯一本地地址和内嵌IPv4的地址。

环回地址

IPv6的环回地址为::1/128,等价于IPv4中的127.0.0.1;

未指定地址

全0地址,即::/128,不能分配给接口、不能用作目的地址,只能被用作源地址以表示接口无地址,路由器不会转发源地址为::/128的数据包;

全局单播地址

流程图 (2).jpg

图6 全局单播地址结构

全局单播地址是IPv6互联网上可路由的地址,等价于IPv4的公网地址,地址为2000::/3,图6给出了通用的全局单播地址结构,一般来说,全局路由前缀为48位,子网ID为16位,接口ID为64位。

以下为笔者本机ping6 Google和Facebook后得到的IPv6地址:

# Googleping6 google.comPING6(56=40+8+8 bytes) fdbd:ff1:ce00:1e2:18ff:2705:9ad:1a0e --> 2404:6800:4003:c0f::6416 bytes from 2404:6800:4003:c0f::64, icmp_seq=0 hlim=97 time=87.998 ms...# Facebookping6 facebook.comPING6(56=40+8+8 bytes) fdbd:ff1:ce00:1e2:18ff:2705:9ad:1a0e --> 2a03:2880:f15c:83:face:b00c:0:25de16 bytes from 2a03:2880:f15c:83:face:b00c:0:25de, icmp_seq=0 hlim=39 time=84.109 ms...

图7描述了全局路由前缀和子网ID的分配方式,解释了IPv6地址块是如何分配给RIR和ISP的,其中前32位由RIR分配(如亚太互联网络信息中心),32到48位由ISP分配(如中国移动、中国联通),子网ID由站点分配(如Google、Facebook)。

流程图 (3).jpg

图7 全局路由前缀大小

以Facebook的IPv6地址2a03:2880:f15c:83:face:b00c:0:25de为例,其中RIR分配的网络前缀可能为2a03:2880::/32,ISP分配的网络前缀可能为2a03:2880:f15c::/48,FaceBook自身分配的网络前缀可能为2a03:2880:f15c:83::/64。

链路本地地址

流程图 (4).jpg

图8 全局单播地址结构

链路本地地址允许节点未配置全局单播地址的前提下通信,只在同一链路的节点之间有效,在IPv6启动后就自动生成,其地址为FE80::/10,图8为链路本地单播地址的结构。

唯一本地地址

流程图 (5).jpg

图9 唯一本地地址结构

唯一本地地址类似于IPv4的私有地址,也被称为本地IPv6地址,这类地址不在全球互联网上进行路由,通常应用于范围有限的区域。其地址为FC00::/7,图9为唯一本地地址的结构,其中L位为1,为0时未定义。

内嵌 IPv4 的地址

最后一种单播地址就是内嵌IPv4的地址,该地址用于帮助从IPv4迁移到IPv6,内嵌IPv6地址在低阶32位中承载IPv4地址,RFC 4291: IP Version 6 Addressing Architecture中定义了两种内嵌IPv4的地址,分别为兼容IPv4的IPv6地址和映射IPv4的IPv6地址。

流程图 (6).jpg

图10 兼容IPv4的IPv6地址

兼容IPv4的IPv6地址的地址结构如图10所示,其中的IPv4地址必须是全局唯一的IPv4单播地址。此类地址已被弃用,当前的IPv6过渡机制都不再使用该地址。

流程图 (7).jpg

图11 映射IPv4的IPv6地址

映射IPv4的IPv6地址与兼容IPv4的IPv6地址几乎完全相同,唯一的区别是32位IPv4地址前的16位全为1,图11显示了此类地址的结构,此处的IPv4地址不需要具有全局唯一性。

多播地址

流程图 (8).jpg

图12 多播地址的结构

多播是一种将单个数据包同时发送给多个目的端(一对多)的技术,IPv6没有广播,只有多播。IPv6预先定义了一组多播地址,多播地址为FF00::/8,图12为多播地址的结构。需要注意的是,多播数据包必须有一个单播源地址,多播地址不能用作源地址。

image.png

图13 范围字段可能的取值

图14 对于范围的解释

其中,标志字段用于表示多播地址的类型,其取值为0(0000)或1(0001),为0表示这类多播地址是由IANA分配的周知多播地址,为1则表示这类多播地址是“暂时”或“动态”分配的多播地址。范围则用于表示多播地址的作用范围,其可能的取值及其相应含义如图13所示,对于范围的解释如图14所示。

RFC 2375: IPv6 Multicast Address Assignments定义了最初分配的IPv6多播地址,这些地址都拥有永久分配的全局ID,已分配的多播地址如表7所示。

/8前缀FF 标记0 范围 多播地址 描述
接口本地范围        
FF 0 1 FF01::1 全部节点
FF 0 1 FF01::2 全部路由器
链路本地范围        
FF 0 2 FF02::1 全部节点
FF 0 2 FF02::2 全部路由器
FF 0 2 FF02::5 OSPF路由器
FF 0 2 FF02::6 OSPF指派路由器
FF 0 2 FF02::9 RIP路由器
FF 0 2 FF02::A EIGRP路由器
FF 0 2 FF02::1:2 全部DHCP代理
站点本地范围        
FF 0 5 FF05::2 全部路由器
FF 0 5 FF05::1:3 全部DHCP服务器

表7 已分配的多播地址

除了已分配的多播地址外,还有一种请求节点多播地址,这类地址用于实现更高效的广播,主要利用请求节点多播前缀FF02:0:0:0:0:1:FF00::/104和设备单播地址的特定映射自动创建而成,其创建过程如图15所示。

流程图 (9).jpg

图15 请求节点多播地址创建过程

地址分配

IPv4地址分配

在IPv4中,地址的分配主要有两种方式:手动配置、动态主机设置协议DHCP。

人工进行协议配置很不方便,且容易出错,因此,应该采用自动配置的方式。互联网目前广泛使用的是DHCP,它提供了一种机制,被称为即插即用联网,这种机制允许一台计算机加入新的网络和获取IP地址而不用手工参与,但DHCP运行的细节超出了本文的写作范围,本文不会介绍,详细了解可以参考RFC 2131: Dynamic Host Configuration Protocol

IPv6地址分配

在介绍IPv6的地址分配方法之前,首先向各位读者介绍EUI-64技术。

EUI-64使用接口的以太网MAC地址来自动生成IPv6地址中的64位接口ID。以太网MAC地址长度为48位,前24位为组织机构唯一ID(由IEEE唯一分配),后24位为设备ID(公司自己编制)。而EUI-64生成接口ID的方法就是在组织机构唯一ID和设备ID之间插入固定值0xFFFE,并对组织机构唯一ID的第七位取反,即可得到生成的接口ID。例如,对于MAC地址00-50-3E-12-34-56,使用EUI-64技术生成的接口ID为02-50-3E-FF-FE-12-34-56。

全局单播地址

image.png

图16 全局单播地址的配置方式

全局单播地址的配置方式如图16所示。

手工配置分为静态配置方式和EUI-64方式。其中,静态配置类似于配置静态IPv4地址,需要在网络接口上配置IPv6地址与前缀长度。EUI-64方式允许指定前缀与前缀长度,以动态方式创建接口ID。

全局单播地址还可以采用动态方式分配,无需任何手工配置。动态配置的方式有两种:无状态自动配置(SLAAC)和DHCPv6。利用SLAAC配置时,前缀和前缀长度是通过路由器宣告消息来确定的,接口ID则是通过EUI-64创建或随机生成的。DHCPv6类似于IPv4的DHCP,设备通过DHCPv6服务器的相关服务自动获取地址信息。SLAAC在后文会被介绍。

链路本地单播地址

链路本地地址的配置方式有:静态方式、EUI-64生成和随机生成。其中第一种不必多说,第二种和第三种则分别使用EUI-64和随机生成的方式来创建接口ID,而前缀和前缀长度通常是FE80::/64,之后将接口ID和该前缀进行拼接,就得到了想要的链路本地单播地址。

链路本地地址为IPv6提供了一个独一无二的优势,网络设备可以自行创建自己的链路本地地址,而无需DHCPv6和路由器宣告消息,这就解决了IPv4中的“先有鸡还是先有蛋”的问题,即一方面希望向服务器申请IP地址,另一方面为了能够与该服务器通信,又必须要首先有一个IP地址。后文会介绍链路本地单播地址的生成过程。

唯一本地单播地址

虽然唯一本地地址只作用于有限的范围内,但唯一本地地址有很大可能是全局唯一的,这是由于RFC 4193: Unique Local IPv6 Unicast Addresses中定义了使用伪随机算法来生成本地分配的全局ID,本文不会介绍该算法,感兴趣的读者可以自行进入该文档查看。

一些协议

本章主要介绍IPv4对应的地址解析协议APR、网际控制报文协议ICMP,以及IPv6的ICMPv6、SLAAC。

ARP

在实际应用中,我们经常会遇到这样的问题:已知一个设备的IPv4地址,但不知道其对应的MAC地址。ARP就是用来解决这个问题的。ARP解决这个问题的方式,就是在主机ARP高速缓存中存放一个从IP地址到MAC地址的映射表,并且动态更新这个映射表。

当主机1需要根据IPv4地址查询局域网中主机2的MAC地址时,主机1首先到高速缓存中查看有无相应的IP地址,如果有,则取出该地址,并将其写入MAC帧。如果没有,则主机1会自动运行ARP,按照如下步骤找出主机2的硬件地址:

  1. ARP进程在本局域网上广播发送ARP请求分组,分组的内容是:Request who-has 主机2的IPv4地址 tell 主机1的IPv4地址;
  2. 局域网中所有主机上运行的ARP进程都会收到该ARP请求分组;
  3. 主机2的IP地址与ARP请求分组中查询的IPv4地址一致,则收下这个ARP请求分组,并向主机1发送ARP响应分组,响应分组的内容是:Reply 主机2的IPv4地址 is-at 主机2的MAC地址。局域网内其余所有主机的IPv4地址都与请求分组中的IPv4地址不一致,因此忽略了这个ARP请求分组;
  4. 主机1收到主机2的ARP响应分组后,就在其ARP高速缓存中写入主机2的IP地址到硬件地址的映射。

以下为笔者使用tcpdump抓取的ARP请求分组和ARP响应分组,其中红色部分为ARP请求分组,黄色部分为ARP响应分组。

➜  ~ sudo tcpdump -vnne -i en0 arptcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes11:36:09.962585 bc:d0:74:56:b9:25 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Ethernet (len 6), IPv4 (len 4), Request who-has 10.1.188.1 tell 10.1.189.183, length 2811:36:09.965303 7c:c3:85:cc:79:f1 > bc:d0:74:56:b9:25, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Reply 10.1.188.1 is-at 7c:c3:85:cc:79:f1, length 46

ICMP

ICMP是互联网标准协议,在IPv4网络中,它允许主机或路由器之间报告差错情况和提供异常情况的报告。

流程图 (10).jpg

图17 ICMP报文格式

ICMP报文格式如图17所示,它由一个8字节的首部和可变长的数据部分组成。同时尽管它是一个网络层协议,但它并不是直接传递给数据链路层,而是需要将其封装到IPv4数据报的数据部分,之后再传递给数据链路层。

ICMP报文种类 类型的值 说明
差错报告报文 3 终点不可达:当路由器或主机不能交付数据报时,就向源点发送该报文。
11 超时:有两种情况会发送此类报文,第一种是路由器收到TTL为0的报文,第二种是规定时间内没收到数据报的所有分片。  
12 参数问题:当路由器或主机收到的数据报首部有的字段不正确时,丢弃数据报并向源点发送该报文。  
5 改变路由:路由器把改变路由报文发送给主机,让主机下次将数据报发送给另外的路由器。  
询问报文 8或0 回送请求或回答:被用来测试目的站是否可达以及了解其有关状态。
13或14 时间戳请求或回答:用于时钟同步和时间测量。  

表8 常用的ICMP报文类型

ICMP有两种报文,分别为ICMP差错报告报文和ICMP询问报文,每种报文的用途如表8所示。 其中,我们常用的ping命令,就是使用回送请求或回答报文实现的。以下为笔者使用tcpdump抓取的回送请求和回送应答报文,其中红色部分为回送请求报文,黄色部分为回送应答报文。

sudo tcpdump -vnn -i en0 icmptcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes11:53:47.922969 IP (tos 0x0, ttl 64, id 35399, offset 0, flags [none], proto ICMP (1), length 84)    10.1.189.183 > 10.1.188.1: ICMP echo request, id 51387, seq 0, length 6411:53:47.925198 IP (tos 0x0, ttl 254, id 35399, offset 0, flags [none], proto ICMP (1), length 84)    10.1.188.1 > 10.1.189.183: ICMP echo reply, id 51387, seq 0, length 64

ICMPv6

与IPv4一样,IPv6也需要报告差错和异常情况,因此,在IPv6中有了新版本的ICMPv6。ICMPv6报文的格式与ICMP相同,但相比于ICMP,ICMPv6复杂的多,它除了实现与ICMP相同的功能外,还实现了很多新特性。在版本6的网络层,ARP协议、ICMP协议和IGMP协议(本文不讨论)都被合并到了ICMPv6中,如图18所示。

流程图 (11).jpg

图18 网络层

本节主要讨论新增的邻居发现协议使用的ICMPv6消息,邻居发现协议定义在RFC 4861: Neighbor Discovery for IP version 6 (IPv6)中,它是IPv6中MAC地址解析、重复地址检测(DAD)和邻居不可达性检测(NUD)的基础,邻居发现在IPv6地址的自动配置机制中扮演了重要的角色。

邻居发现协议用到了5种ICMPv6消息,分别为路由器请求(RS)消息、路由器宣告(RA)消息、邻居请求(NS)消息、邻居宣告(NA)消息以及重定向消息。这些消息的作用如下:

  • RS消息:当主机需要SLAAC所需的前缀、前缀长度、默认网关以及其他信息时,就会发送RS消息,通常发生在主机刚加电并被配置为自动获取其IP地址的情况下;
  • RA:RA消息由路由器周期性的发送,它也可以作为RS消息的响应消息,其作用是为主机提供编址及其他配置信息(比如单播地址的前缀和前缀长度);
  • NS消息:类似于 IPv4 中的ARP请求消息,作用是请求目标设备的二层地址(通常是以太网 MAC 地址),同时也向目标设备提供了自己的链路层地址;
  • NA消息:类似于IPv4中的ARP应答消息,是邻居请求消息的响应消息,作用是提供与 IPv6地址相对应的二层地址(通常是以太网 MAC 地址);
  • 重定向消息:作用是通知设备有更优的下一跳路由器,其工作方式与IPv4中的重定向消息相同。

主机还需要为每个接口维护两张缓存表,分别为邻居缓存表和目的地缓存表,邻居缓存表类似于IPv4中的ARP缓存表,它负责维护最近流量所送往邻居的信息列表。而目的地缓存表维护的是流量最近被发送的目的地列表,包括其他链路或其他网络上的目的地。

下面通过介绍地址解析、DAD的执行过程来介绍上述消息是如何使用的。

地址解析

类似IPv4中的ARP协议,地址解析过程如图19中的①②③④所示,假设PC1正在ping PC2

图19 地址解析过程

其中每一步的细节如下:

  1. PC1发现需要将IPv6数据报封装到以太网帧中。PC1已知PC2的IPv6地址,检查其邻居缓存表以获得相应的MAC地址,发现邻居缓存表中没有关于2001:DB8:AAAA:1::200的表项;
  2. PC1此时向请求节点多播地址FF02::1:FF00:200发送一条NS消息,NS请求消息中的目标地址是PC2的IPv6地址,其在IPv6首部中的地址是请求节点多播地址。其中,RFC 2464: Transmission of IPv6 Packets over Ethernet Networks规定使用以太网多播地址33-33-xx-xx-xx-xx来完成与IPv4中ARP请求分组中FF-FF-FF-FF-FF-FF相同的功能,最后4字节与IPv6数据报目的地址的最后四字节相同;
  3. PC2收到NS消息之后,向PC1以单播的方式响应NA消息,在消息中提供了其链路层MAC地址。PC2将PC1的IPv6地址加入到自己的邻居缓存表中;
  4. PC1收到邻居宣告消息,则以2001:DB8:AAAA:1::200和00-1B-24-04-A2-1E来更新其邻居缓存表。

重复地址检测(DAD)

图20 DAD过程

用于检测生成的单播地址是否重复,既可以检测全局单播地址也可以检测链路本地单播地址。DAD过程如图20中的①②③所示,假设我们需要检测生成的链路本地单播地址是否重复,共分为三步:

  1. PC1采用EUI-64或随机生成的方式创建链路本地单播地址FE80::50A5:8A35:1234:5678,在使用该地址前,需要先进行DAD检测以确保该地址在链路上的唯一性;
  2. PC1发送NS消息以确定链路上是否有其他设备正在使用该链路本地地址,其中,NS请求消息中的目标地址是刚刚创建的链路本地单播地址,IP首部的源IPv6地址为未指定地址,目的IP地址为请求节点多播地址,数据链路层目的地址为以太网多播地址,与地址解析中的第二步相同。在DAD完成前,该地址处于试验状态;
  3. PC1设置一个定时器,在一定时间内,如果链路内的其他设备有相同的链路本地单播地址,则会收到NA消息,该地址不可用。如果未收到NA消息,就代表该地址未被使用,该地址就会从试验状态迁移到已分配状态。

无状态地址自动配置(SLAAC)

SLAAC是一种允许主机通过组合本地可用信息与路由器宣告的信息生成自己单播地址的机制。自动配置进程包括通过SLAAC生成链路本地地址和全局单播地址,图21解释了SLAAC过程,共包含四个部分,用到了很多上文提到的技术和消息。

图21 SLAAC过程

其中的只有第三步是上文中没有介绍的,这一步PC1可以从路由器周期性发送的RA消息中获取全局单播地址信息和配置信息,如果PC1没有收到RA消息,那么PC1就会向路由器发送RS消息,RS消息的源IPv6地址是上一步创建的PC1链路本地地址,目的IPv6地址是全部路由器多播地址,RA消息的源IPv6地址是路由器的链路本地地址,目的IP地址是全部节点多播地址。

参考资料

本文出至:学新通技术网

标签:

上一篇:

下一篇: