8.3 IPv6 包格式
IPv6的包格式中包含大量层次化IPv6地址和头部,从而可以让路由器能够有效地处理数据包。IPv6的地址空间非常大,足以满足Internet的飞速增长要求并能提供更多的分级层次。
IPv6删除了部分IPv4头部字段,删除了选项(Options)字段,要求所有路由器都必须处理选项内容,从而提高了数据包的处理效率。IPv6仍然有网络选项,但是在大多数情况下,仅需要目的节点处理选项内容。IPv6将选项处理移到了扩展报头部,从而只有那些需要该信息的节点才会去处理这些选项。
本节将详细介绍IPv6地址的类型、用法、结构及IPv6的头部等内容。
8.3.1 IPv6 地址
20世纪70年代首次出现IP的时候,Internet世界与现在有着天壤之别,当时的Internet完全用于研究和教育目的,32bit的地址空间看起来绰绰有余(至少在IP的生命期内是如此)。,但Internet获得了令人无法想象的成功,IP被嵌入了绝大多数商业和家庭的运行之中,IP网络也成为许多极其成功的组织机构日常运行的一部分,随着组织机构的不断扩大以及希望连接到Internet上的站点数越来越多,人们越来越关心可扩展的IP网解决方案。由于大量的设备需要使用(或在不远的将来即将使用)IP地址来接入互联网络,即使NAT和CIDR等技术在一定程度上延长了IP地址的耗尽时间,但这一切还远远不够,包括移动电话、PDA、电子邮件设备、家用照明系统、汽车、公共仪表等在内的设备都将需要IP地址,IP的异常成功以远远超出了当初的设计意图。
IPv6地址解决了上述问题,不但增大了地址空间,定义了更多的地址层级,而且定义了地址分配的管制规则,以维护分层汇聚能力。
1. 地址空间
目前被广泛使用的地址空间到底应该多大才合适?地址空间应该是固定的还是可变的?地址空间过小会限制其扩展能力,但地址空间过大也会形成巨大的包头,使得路由器(和人们)难以管理这些地址。而可变长地址则会提高软件的复杂性、降低包处理速度。IPng(the next generation of IP,下一代IP)的一种建议就是使用NSAP(Network Service Access Point,网络服务接入点)地址,其地址长度在1〜20个8位组之间可变;另一种建议就是使用64bit的定长地址空间。虽然64bit地址空间看起来足以满足IP节点的编址需求,但需要增加更多的地址来解决因Internet规模急剧扩大而带来的额外复杂性,因而从将来的网络扩展和地址分配的层次化要求等角度考虑,最终选择128bit的地址空间。
理论上,128bit地址空间可以为340 282 366 920 938 463 463 374 607 431 768 211 456个节点分配地址,如果全球人口按100亿计算,那么每个人可以分得的IP地址数将达到约 3.4×1027个.即便考虑到将来的快速发展,需要完全连接到Internet上的远程工作者,加上 Internet移动电话、IP手表、带有路由设备和公共仪表的家庭网络以及网络化汽车,都无法用完这么多的IP地址。
IPv6的地址长128bit,以用冒号“:”分隔的8个16bit片段来书写,每个片段以4个十六进制数字来表示。下面给出了两个IPv6地址示例。
• FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
• 1080:0000:0000:0000:0008:0800:200C:417A
这些地址都非常巨大,能够为大量节点提供编址能力。它们具备良好的层次化灵活性,但写起来很不方便,更别提记住这些地址了,因而提供了某些方法来压缩这些地址,以方便人们来处理这些地址。
任一个IPv6地址中都包含了很多的0,因而对任一个16bit字段来说,都可以删除其前导数字0,只要在每个字段中保留至少一个数字即可,但也有例外。上例中的第一个地址的所有16bit字段中都没有前导数字0,因而无法被压缩,而第二个地址则可以压缩为如下所示。
1080:0:0:0:8:800:200c:417A
还可以进一步压缩多个连续的0字段,这是每个字段都必须至少有一个数字的规则的例外情况。可以用两个冒号(::)来代替多个连续的0字段,表8-1列举了一些地址压缩实例。
前导或尾部0字段都可以被压缩。请注意,::只能代替一组连续的0字段,多个::则会给地址带来混乱。例如,1080::3245::200c:417A就是一个错误的地址写法,因为它没法提供两个8位组Ox3245正确位置的足够信息。
也可以用IPv6和IPv4混合的方式来表示IPv6地址,该表达方式包括多个以冒号分隔的 IPv6十六进制字段和一个以点号分隔的十进制IPv4地址,如下所示:
X:X:X:X:X:X:d.d.d.d
其中,X表示IPv6地址的十六进制数字,d.d.d.d以点分十进制记法表示了该地址的最后 32bit数字。表8-2给出了这种混合模式的地址格式示例。
这种混合的IPv6/ IPv4地址表达方式为IPv6和IPv4节点在同一个网络中的共存提供了方法。8.5节将详细讨论迁移和共存方法。
3. 地址前缀的文本表示方法
IPv6地址前缀的表示方法与IPv4 CIDR表示法相似,IPv6前缀的表示方法如下。
其中,IPv6-address是任何有效地址,prefix-length是组成前缀的连续bit数。
以下前缀都是56bit前缀200F00000000AB的合法文本表达形式。
• 200F::AB00:0:0:0:0/56
• 200F:0:0:AB00::/56
需要记住的是,对IPv6主机来说,每个地址表达式中最多只能出现一次::。
而下面则是56bit前缀200F00000000AB的无效文本表达形式。
• 200F:0:0:AB/56
• 200F::AB00/56
• 200F::AB/56
由于第一个表达式丢弃了某个16bit字段中的尾部0,导致地址的长度无效,”/”左前方的IPv6地址应该是完整长度或压缩后的IPv6地址,因而该表达式无效。第二个和第三个表达式虽然都是有效的IPv6地址,但它们无法扩展为正确的IPv6地址,它们所代表的不是 200F:0000:0000:AB00:0000:0000:0000:0000,而分别是200F:0000:0000:0000:0000:0000:0000: AB00和200F:0000:0000:0000:0000:0000:0000:00AB。
4. 地址类型分配
在前面的CIDR中曾经介绍过,IPv4地址的类型由地址中的高阶bit来定义,分为A、B、 C、D和E类地址。地址类型标识了固定长度的网络地址和主机地址,地址所有者可以自由使用该地址,这也是IPv4地址中惟一定义的地址结构。而IPv6则定义了更多的地址结构,有关详细内容将在8.3.2小节中进行介绍。IPv6地址的类型由地址的高阶bit来定义,由这些 bit组成的变长字段被称为FP(Format Prefix,格式前缀)。表8-3列出了这些前缀的初始分配情况。
目前,部分IPv6地址空间已被分配给可聚合全局可路由地址、本地应用地址和多播地址,已分配的地址空间约占15%左右。
某些地址空间被保留,目的是保留给将来NSAP和IPX路由实现使用,某些被保留的地址空间(特别是0x00)被用作专用地址,如环回地址和未指定地址(如下一小节所述)。
大部分IPv6地址空间仍未被分配,可以留给现有应用或其他新应用将来的扩展使用。
可聚合全局单播地址与全局可路由IPv4地址类似,它们被成块地分配给Internet服务提供商和交换中心,再由他们分配给商业用户和终端用户。该类型的IPv6地址定义了多级层次和聚合机制,虽然这部分地址是目前已分配的最大地址空间,但也仅占IPv6地址空间的1/8。
从表8-3可以看出多播地址均以0xEF为起始,其余地址均为单播地址。表8-4提供了IP地址类型的快速识别参考。
8.3.2 地址结构
IPv6的地址结构用于指派和分配,与IPv4一样,其包转发操作也是基于最长匹配前缀。单播地址可以是可聚合全局地址,也可以是链路本地地址、站点本地地址或专用格式地址。可以为 IPv6接口指派多个地址——单播、任播或多播地址。下面将逐一说明IPv6的地址结构类型。
1. 可聚合全局地址格式
可聚合全局地址用于连接公共Internet以及其他任何需要全局惟一和可路由功能的场合,该地址结构支持目前的基于提供商的聚合(provider-based aggregation)以及新的基于交换中心的聚合(exchange-based aggregation)。基于交换中心的聚合是将地址空间分配给交换中心,之后再细分地址空间并分配给其客户。这里所说的交换中心(exchange)就是第2章所说的NAP的另一个名称,是一台互联ISP和顶级服务提供商的二层交换机。可能需要在交换中心使用路由仲裁服务器来收集路由信息并在服务提供商之间提供一个对等点。不过基于交换中心的聚合有待进一步完善。通过这些聚合点,按照已定义的可聚合全局地址的格式就可以实现扩展Internet所需的层次化要求。有关层次化问题将在下一小节详细描述。
(1)层次化。
聚合地址按照公共(public)、站点(site)和接口(interface)3个层次进行组织。其中,公共拓扑包括服务提供商(提供公共Internet转接服务)和交换中心,由最顶级公共拓扑组成所谓的默认自由区(default-free zone)——Internet路由器的路由表中无默认路由表项,这些站点知道如何去往其他网络前缀。站点拓扑指的是不提供公共转接服务的本地站点或组织机构(虽然也可能提供某些更小规模的私有转接服务),而接口拓扑则用于标识网络上的接口。图8-2解释了可聚合地址的Internet寻址分层结构。
图8-2 Internet寻址分层结构
ISP1、ISP2、ISP3和ISP4表示公共空间,它们之间不但有直连链路,而且通过交换中心进行互联,而更小的ISP(P1和P2)及终端用户站点(S1〜S5)则构成站点空间。前面已定义的地址类型(将在后面详细讨论)即可反映上述Internet分层结构。
(2)地址格式。
图8-3显示了可聚合全局单播地址的格式。
图8-3 可聚合全局单播地址的格式
从图中可以看出,公共级字段包括FP、TLA、RES和NLA,SLA是站点级字段,而接口ID则是接口级字段。该类地址的网络部分占据前64位,后64位为地址的节点部分。可聚合全局单播地址的各字段定义如下。
• FP:格式前缀(001)。
• TLAID:顶级聚合标识符。
• RES:保留给将来使用。
• SLA ID:站点级聚合标识符。
• 接口 ID:接口标识符。
格式前缀FP是二进制数001,用于标识可聚合全局单播地址,如图8-3所示,FP、TLA、 RES和NLA等字段构成公共拓扑,SLA ID构成站点拓扑,而接口ID是接口标识符。还可以对公共拓扑和站点拓扑做进一步的细分以创建更多的层次结构。FP、TLA、RES、NLA和 SLA等字段属于该类地址的网络部分,而接口ID是该类地址的节点部分。下面将详细讨论图8-3中所示的各字段信息。
①TLA ID。
TLA ID(Top-Level Aggregation Identifiers,顶级聚合标识符)是路由分层架构中的顶级字段。对默认自由区中的路由器来说,每个TLA ID都必须有一个路由表项,而且还可能有描述其自身拓扑的路由表项。TLA ID字段长13bit,如果需要多个TLA,那么还需要分配其他的FP,或者将TLA字段扩展到右侧的保留字段。
就像IANA(Internet Assigned Numbers Authority, Internet编号分配机构)给不同区域IP注册机构分配的地址区间一样,IPv6 TLA ID也会被分配给全球的区域IP注册机构,再由区域IP注册机构将TLA ID分配给大型ISP。通常来说,这些收到TLAID的大型ISP都是转接服务提供商和交换中心。
IANA初始分配的TLA是0x0001,然后将细分后的sub-TLA(子SLA)块分配给RIR,接着再由RIR将所分配到的sub-TLA块中的SLA分配给提供IPv6服务的组织机构——TLA注册机构。TLA 0x0001包括13个sub-TLA bit,紧接着是6个sub-TLA保留bit、13个NLA bit、16个SLA bit和64个接口ID bit。每个sub-TLA最初最多有13 bit NLA ID分配给NLA注册机构,组织机构完全分配完其NLA空间之后就可以申请新的地址空间。虽然每个 sub-TLA都会被保留给每个组织机构,但每次只为每个组织机构分配一个sub-TLA,如果某个组织机构需要多个sub-TLA,那么就需要提供足够的工程资料或配置计划以证明该要求的合理性。此外,还可以利用6个保留bit在一个sub-TLA中分配更多的地址空间。
例如,如果分配给ARIN的是2001:0400::/23,那么ARIN就可以分配2001:0400::/29〜 2001:05FF::/29之间的sub-TLA。但为了鼓励慢启动(slow-start)编址方案,通常RIR分配的都是带有35bit前缀的地址,如2001:0408::/35。实际上,sub-TLA是29bit加上6bit保留NLA空间。分配给VBNS的是2001:0408::/35, VBNS可以采用任何分配方法将13bitNLA空间分配给其用户,可以将2001:0408:0010::/40分配给一个小型ISP用户,之后该小型ISP可以将 2001:0408:0010::/48〜2001:0408:001F::/48分配给其用户。
②RES。
除了在前面所说的TLA 0x0001应用场合之外,暂时还未使用RES(resvered,保留)字段,该字段的所有bit都会被设置为0,将来使用时可以扩展TLA ID和NLA ID。
③ NLA ID。
获得TLA ID的组织机构可以利用NLA ID(Next-Level Aggregation Identifier,次级聚合标识符)来创建分层寻址结构并标识各个站点,从NLA空间接收到地址分配的组织机构被称为NLA注册机构。NLA IS有些类似于分配给顶级ISP的IPv4 CIDR地址块,之后会由该 ISP向其用户分配带有更长前缀的地址。
组织机构在向其用户分配地址空间时,如果该组织机构被分配了一个TLA,那么将有24bit NLA可用;如果该组织机构被分配的是一个sub-TLA,那么将有13bit NLA可用。其用户可以是ISP(NLA注册机构),也可以是终端用户。TLA注册机构可以使用高位NLA bit来创建地址层次结构,并将低位NLA bit分配给NLA注册机构,NLA注册机构将被分配足够的地址空间并为其自己的用户提供相应的地址。NLA注册机构可以分配的最小地址空间是 48bit前缀(/48),此时该用户的子网编址方案应至少可以使用16bit SLA。虽然一个站点可以申请多个/48地址,但是用户必须提供其当前的地址部署统计情况以及工程资料或配置计划以证明其要求的合理性。
④SLA ID。
每个站点可以根据自己的需要在SLA ID(Site-Level Aggregation Identifier,站点级聚合标识符)内创建任意等级的分层地址结构,可以是无任何细分的平面编址方案,也可以将SLA ID进一步细分为多个子网,从而创建SLA ID地址的分层结构。
⑤接口ID。
接口 ID的作用是标识指定链路上的接口,对每条链路来说都是惟一的。所有高位bit在 001〜111之间的地址(不包括多播)都必须有EUI-64格式的接口ID,目前只有专用格式地址、NSAP分配的地址空间以及IPX分配的地址空间不在该范围之内。
EUI-64格式可以从接口MAC地址(如果有)衍生得到,只要在公司ID和节点ID之间插入FFFE,并将全体/本地bit设置为1以表示全局值,即可得到EUI-64格式(如图8-4所示)。
图8-4 MAC地址到EUI-64的转换
如图8-4所示,通过在MAC地址的公司ID之后插入FFFE,并将全体/本地bit设置为1之后,即可将MAC地址0000:0C0A:2C51转换为EUI-64地址0200:0CFF:FE0A:2C51。
2. 专用格式地址
某些地址使用专用格式,这些地址是从保留的FP 0x00中分配的,未指定地址(unspecified address)、环回地址(loopback address)和内嵌IPv4地址(embedded IPv4 address)都是专用格式地址。
(1)未指定地址。
未指定地址由全0组成,即0:0:0:0:0:0:0:0。永远不能将未指定地址分配给任何节点,实际上,未指定地址表示的是无地址。未指定地址的一种应用场合就是在初始化主机的源地址字段中,此时的主机还没有被分配任何有效地址。在任何情况下,都不能将未指定地址用作 IPv6包或IPv6路由头(routing header)的目的地址。
(2)环回地址。
环回地址是0: 0:0:0:0:0:0:1。该地址与IPv4的环回地址127.0.0.1类似,节点可以使用该地址向其自己发送IP包,不能将环回地址分配给物理接口,所有去往环回地址的流量都不会离开该流量发送节点。
(3)与IPv4兼容的IPv6地址。
从IPv4向IPv6迁移的一种转换机制是自动隧道技术,IPv6包会被自动封装到IPv4包中并经IPv4网络进行传送。该机制要求使用专用格式的IPv6地址,使用该技术的节点都运行在双栈模式(同时运行IPv4和IPv6协议栈)下,给支持自动隧道技术的IPv6/IPv4节点分配的IPv6地址,必须将IPv4地址内嵌在该IPv6地址的低32位中,其他bit均为0。这种类型的地址就被称为与IPv4兼容的IPv6地址(IPv4-compatible IPv6 addresses),其格式如下。
::d.d.d.d
其中,d.d.d.d是以点分十进制方式表示的IPv4地址。有关与IPv4兼容的IPv6地址以及自动隧道技术将在8.5节中做进一步论述。
3.本地使用地址
IPv6地址中有两类地址是本地有效的:链路本地地址仅对某个链路上的节点有效,站点本地地址仅对某个站点内的节点有效。这些地址都不是全球惟一的,它们只是在其作用域内具有惟一性。
(1)链路本地地址。
链路本地地址用于单条链路上的节点,自动配置(autoconfiguration)、邻居发现、无路由器链路上的节点以及路由协议都使用链路本地地址。路由器不能将源地址或目的地址是链路本地地址的数据包转发到该链路之外,因而对任何协议来说,如果希望将数据包发送给某链路上的设备,同时又希望该数据包不被路由到该链路之外,那么就可以在IP头中使用链路本地地址。链路本地地址的FP为1111111010,后面是54个0和接口ID,该类地址无TLA、 NLA或SLA信息,因而不存在任何分层结构信息,图8-5给出了链路本地地址的格式。
图8-5 链路本地地址格式
每个节点都会给每个有效IPv6接口分配一个链路本地地址,既可以利用自动配置机制来自动配置这些地址,也可以采取手工方式配置这些地址。
下面是一些链路本地地址的示例。
FE80::5ABC:01FF:FE01:1111
FE80::0060:08FF:FEB1:7EA2
FE80::200:CFF:FE0A:2C51
(2)站点本地地址。
一个站点就是一个组织机构或一个组织机构的一部分,它既可以是一个确定的拓扑位置,也可以是以某种方式互连起来的多个拓扑位置。对配置了站点本地地址的网络来说,无法从该站点之外的任何位置访问该站点,该站点的边缘路由器必须能将站点本地流量限制在本站点范围之内并负责控制路由的传播。除了站点本地FP以及接口ID之外,站点本地地址还有一个子网标识字段。但是需要注意,该类地址也没有TLA或NLA ID。这类地址仅被设计用于单个站点之内,因而不需要全局前缀,这类地址的使用方式类似于私有IPv4地址,都不是全球惟一的地址。建议在路由器接口上使用站点本地地址,而不是全局可聚合地址。
站点本地地址的FP为1111111011,后面是38个0和一个16bit子网字段以及一个64bit接口ID(如图8-6所示)。
图8-6站点本地地址格式
可以利用子网字段在站点内创建多个网络并创建本地范围内的分层结构,可以利用这种层次化能力在本地范围内实现地址聚合。请注意,不能将站点本地地址传播到站点边界之外。
下面是一些站点本地地址的示例。
FEC0::1:5ABC:1FF:FE01:1111
FEC0::CAB:60:8FF:FEB1:7EA2
(3)任播地址。
任播路由是一种对多个接口(通常是在不同的节点上)用同一个IP地址进行编址的机制,去往该地址的流量会被路由到最近的节点。有关任播的内容将在8. 4. 5小节做进一步讨论。任播地址的格式与单播地址的格式完全一样,并没有为任播地址定义特殊的FP。
任播地址是从单播地址空间分配的,事实上任播地址取自接口ID字段,目前已经预定义了Subnet-Router(子网路由器)任播地址,所有连接到某链路的路由器接口都要被分配该地址。该地址实质上就是接口标识符为全0的单播地址,图8-7给出了Subnet-Router任播地址的格式。
图8-7 Subnet-Router任播地址
Subnet-Router任播地址的一个例子就是以单播地址FEC0:0:0:A:200:CFF:FE0A:2C51在路由器接口上分配的FEC0:0:0:A::。
最高的128个接口ID被保留给已分配的子网任播地址,保留的子网任播地址是每个IPv6子网上可用的任播地址(而不管该地址前缀的类型或格式)。图8-8给出了保留的任播地址的结构。
如图8-8所示,保留的任播地址空间完全取自接口ID字段,每个IPv6子网都可以使用保留的任播地址,最高的128个接口ID被保留给任播地址使用,该类地址的最后7bit用于标识特殊的任播地址。
在写作本书的时候,惟一指定的任播地址就是移动IPv6家乡代理(mobile IPv6 home-agent),其任播标识符为二进制1111110。也就是说,每个IPv6子网中与EUI-64接口 ID FDFF: FFFF: FFFF: FFFE相关联的地址都被保留为移动IPv6家乡代理任播地址,前缀为FEC0:0:0:A::/64的移动IPv6家乡代理使用的任播地址为FEC0:0:0:A:FDFF:FFFF:FFFF:FFFE。
图8-8 任播地址结构
其余的任播地址(十六进制值0〜7D和7F)被保留给将来使用。
由于无法从格式上区分任播地址与单播地址,因而必须在接口上显式配置其地址为任播地址。
(4)多播地址。
多播地址用于表示接口组,每个接口组都可以包含多个多播地址。由于多播地址总是以 0xFF开头,因而很容易与单播地址进行区分。在IPv6的网络层中没有广播机制,由于广播会给那些对广播包不感兴趣的节点带来大量的额外开销,接收到广播包的IP接口都必须进行处理以确定其是否是所期望的接收者,但大多数时候,这些节点都不是期望的接收者。每个 IPv6都知道其所属的多播组,这样一来,只有那些属于该多播组的接口才会去处理这些多播包。因而,IPv6不使用广播,而使用多播。
IPv6多播地址既可以由官方编址机构进行分配(周知地址),也可以采取临时分配方式(即本地分配用于非全局作用域),初始的IPv6多播地址分配基于已分配的IPv4多播地址,所有的相关IPv4多播地址都被转换为IPv6多播地址。读者可以参考RFC 2375以获取当前已分配的IPv6多播地址完整列表,随后的表8-6中列出了一些多播地址实例。
IPv6多播地址也被限定了作用域,该类地址有一个用于标识作用域(节点本地、链路本地、站点本地、组织机构本地或全局范围)的字段。在特定作用域内定义的临时地址(transient address)仅对该作用域内的节点有意义,同样的地址可以在不同的作用域内或不同的网络内重复定义,并且可以拥有完全不同的含义。
图8-9给出了多播地址的格式。
图8-9 多播地址格式
最前面的8位组11111111标识了该地址为多播地址。
• figs(标记):该字段有4bit,其中前3bit暂时保留并被设置为0,最后lbit表示该多播地址是由Internet编号机构永久分配的地址或不是永久分配的地址(即“临时”地址),值为0时表示该多播地址为周知地址,即是由全球Internet编号机构分配的地址。
• scop(作用域):该字段有4bit,用于限定多播地址的作用域,表8-5列出了各种作用域值。
无论是周知地址还是临时地址,都可能存在上述作用域值,给定作用域内的临时地址仅对该作用域有效,在其他作用域内则毫无意义。
• 组ID(Group ID):用于标识给定作用域内的多播组——周知多播组或临时多播组。表8-6列出了一些常用多播组以及分配给它们的地址及作用域。
在接口初始化以及多播协议和多播应用初始化后,节点就会立即加入多播组。节点加入 FF01: : 1和FF02: : 1的所有节点(all-nodes)多播地址,从地址的格式可以看出,该地址属于周知地址,且分别是节点本地作用域和链路本地作用域地址。路由器则加入FF01: : 2、FF02: : 2,和FF05: : 2的所有路由器(all-routers)多播地址,这些地址也都是周知地址,且分别属于节点本地作用域、链路本地作用域和站点本地作用域地址。
从表8-6可以看出,能够运行于多个作用域之内的多播组拥有多个IPv6地址,这与周知 IPv4多播地址不同,它们没有被定界。第5章中曾经讨论过两种多播定界机制,TTL定界需要网络管理员在多播边界上设置TTL阈值,当多播包到达边界时,如果该多播包中的TTL值低于预设的阈值,那么将丢弃该多播包。这种方法的一个缺点就是缺乏灵活性,某个接口的TTL阈值会被应用于离开该接口的所有多播包,另一个缺点就是在大型网络中很难预测正确的TTL阈值。另一种IPv4多播定界方法就是管理性定界,即定义一个私有多播地址区间,以便在企业内部定义多播作用域,包括的地址区间是239. 0. 0. 0〜239. 255. 255. 255,建议定界区间是239. 255. 0. 0/16(用于本地或站点作用域)和239. 192. 0. 0/14(用于组织机构作用域)。这些仅仅是建议定界区间,企业可以根据需要自行使用这些地址。虽然管理性定界可能能够很好地工作于组织机构内部,但无法在全局作用域内使用,因为这些地址都是私有地址。
所有的IPv6多播地址都内嵌了多播定界机制,目前已经定义了5级作用域,对IPv4的 TTL定界来说,只要将所有链路本地多播包中的TTL值设置为1,即可得到链路本地作用域。其余的IPv6作用域可以为不同的多播定界策略提供工具,使用IPv6的多播应用可以被包含在链路、站点或组织机构内。多播地址中为将来的作用域保留了相应的地址。被限定作用域的周知多播地址可以在确保相同地址不被用于不同多播组的同时实现多播作用域定界功能。对两家公司来说,为两种不同的多播应用使用相同的多播地址毫无问题,但是当这两家公司今后要融合时就会出现地址冲突现象。
一种特殊的多播地址是“请求节点(solicited-node)”多播地址,各种IPv6功能都使用请求节点多播地址来与 IPv6节点进行通信,有关使用该地址的功能将在8. 4节中进行详细描述。除了链路本地地址之外,还为分配给接口的每个单播和任播地址创建并分配了请求节点多播地址。利用接口ID的最后24个bit并将其附加到前缀 FF02: 0: 0: 0: 0: 1: FF00: : /104之后,即可创建请求节点多播地址。图8-10解释了请求节点多播地址的构造过程。
图8-10 请求节点多播地址的构造过程
MAC地址为0000. 0C0A. 2C51的接口构成EUI-64接口ID: : 200: CFF: FE0A: 2C51,该接口 ID又创建了链路本地地址FE80: : 200: CFF: FE0A: 2C51。子网0上的站点本地前缀FEC0: : /64创建了站点本地地址FEC0: : 200: CFF: FE0A: 2C51,由于该接口上已经有了一个站点本地地址,因而可以构造一个请求节点多播地址,该请求节点多播地址从接口ID中取最后24bit(0A:2C51),并将其附加到请求节点前缀,即可构造出请求节点多播地址FF02::1:FF0A:2C51。
每个接口都可以拥有多个前缀以及多个与其相关的IPv6地址,对所有地址来说,其接口 ID很可能都是一样的,因而通过接口ID的最后24bit来创建请求节点多播地址可以最小化该节点必须加入的多播地址数。
4.节点所需要的地址
要求节点能够识别多种地址,为了保持正常工作,IPv6要求节点必须维护这些地址。有关每种地址的使用将结合特定的IPv6功能做进一步讨论。
要求主机能够识别以下地址。
• 每个接口的链路本地地址;
• 所有已分配的单播地址;
• 所有节点(all-nodes)多播地址;
• 关于每个已分配的单播地址和任播地址的请求节点多播地址;
• 该主机所属的其他多播组的多播地址。
除了上述地址之外,路由器还需要能够识别以下地址。
• 该路由器每个路由接口的子网路由器任播地址;
• 配置在该路由器上的其他任播地址;
• 所有路由器(all-routers)多播地址;
• 该路由器所属的其他多播组的多播地址。
表8-7总结了各种类型的地址情况。
8.3.3 IPv6 头部
IPv6的设计目标之一就是改善IPv4的头部,IPv6的头部更简洁、更灵活,而且在使用可选项时也更有效。IPv6头部删除了IPv4头部中的部分字段,并对其他字段进行了重新命名,其地址长度是IPv4的4倍,但其头部仅是IPv4头部的2倍。此外,IPv6头部可选项的编码方式做了更改,使得包处理更加有效,并且在大小和选项的增加上更为灵活。
1.头部格式
IPv6头部很简单,一共有8个字段,包括源地址和目的地址字段。图8-11给出了IPv6头部格式。
IPv6头部格式中的各字段信息定义如下。
• 版本(Version):指示IP版本号(此处为6)。
• 净荷长度(Payload Length):除去头部之外的IP包长度(以8位组为单位),扩展报头(将在后面讨论)属于净荷的一部分,因而也包含在该长度之内。
• 下一报头(Next Header):标识紧随IPv6基本头部之后的报头类型的值,下一个报头既可以是上层报头(如ICMPv、TCP或UDP),也可能是一个IPv6扩展报头。
• 跳数限制(Hop limit):被数据包所经过的每个节点所递减,跳数限制字段值为0时该数据包就要被丢弃。某些IPv6功能(如路由器宣告、邻居宣告和请求以及IPv6重定向)都只用于单条链路的两端设备,IPv6用于验证某数据包没有被发送到链路之外的节点(可能是某种恶意地对流量进行重定向)的技术要求将该字段设置为255(是跳数限制字段的最大值)。这是因为数据包穿越了路由器并由该链路外的节点发送而来,那么接收到的该数据包的跳数限制字段值必将小于255,这样一来,接收到该数据包的IPv6节点就知道该数据包无效并予以丢弃。
图8-11 IPv6头部格式
• 源地址/目的地址(Source Address/Destination Address):该字段的长度均为128bit,其内容分别是128bit的IPv6源地址和目的地址。
流量类别和流标签字段将在8.4.7节进行描述。
图8-12列出了IPv4头部以作对比。可以看出,只有那些需要由路径中的每个IP节点处理的IPv4头部字段被保留在了IPv6头部中,由于其余字段所包含的信息对给定IP包来说可能相关也可能不相关,因而都被移至IPv6头部中的扩展报头。
图8-12 IPv4头部格式
2.扩展报头
IPv6基本头部中不含可选的网络层信息,这些可选信息被放置在IPv6基本头部与上层协议报头之间的独立报头中。在数据包的传送路径上,并不是每个节点都会处理扩展报头(但是有一个例外),只有IPv6基本头部中目的地址字段所标识的节点(或者多播目的地的节点)才处理这些扩展报头。由于不再需要每台IP路由器都处理那些可能仅针对目的节点的头部信息,因而可以大大提高选项的处理效率。不过逐跳选项头是一个例外,因为逐跳选项头中包含了分发路径上每台路由器都需要的信息。
(1)扩展报头次序。
通过检查前一个头部中的相关信息,节点就可以确定其是否要检查并处理扩展报头,因而在处理扩展报头时,需要按照它们在数据包中的出现次序依次处理。如果所有的扩展报头都出现在某个数据包中,那么它们的次序将如表8-8所示,该表显示了标识该扩展报头的 Next-Header值。表8-8中的扩展报头应该按照表中的顺序进行排列,但实际中也可能不完全如此(逐跳选项头除外,其必须紧随IPv6基本头部之后),无论接收顺序如何,节点都需要处理这些扩展报头。
需要注意的是,表8-8中出现了两次目的选项头,但这两个位置的目的选项头的含义是不同的。如果目的选项头出现在路由头之前,那么IPv6头部中目的地址字段中的第一个目的地以及路由头中列出的所有地址都要检查该头部;如果目的选项头出现在路由头之后或者没有路由头,那么只有该数据包的最后目的地才处理该目的选项头。图8-13解释了扩展报头的使用方式。
每个头部中的Next-Header值的作用是标识紧接在IPv6基本头部之后的报头的类型。在读取了IPv6基本头部之后,如果该处理节点不是最终的目的地,而且下一个报头也不是逐跳报头,那么将转发该数据包;如果该节点是最终的目的地,那么将按照所接收顺序逐一处理每个报头。
(2)选项
目前已定义的两个扩展报头(逐跳选项头和目的选项头)包含一个或多个TLV(Type- Length-Value,类型—长度—值)选项。这些选项包括一个指示数据在传送过程中是否可变的标记,这对认证头来说是有意义的,如果该数据可变,那么认证头在计算认证信息时必须将该字段视为全0。目前仅定义了Padl和PadN两个选项,这两个选项都被用来填充头部,以便让整个头部的长度成为8个8位组的整数倍。
(3)逐跳选项头。
在数据包向目的地分发的路径上,所有的路由器都必须处理逐跳选项头。逐跳选项头必须紧随IPv6基本头部之后,这就使得分发路径上的路由器只要处理该报头即可,而无需处理其他扩展报头。
图8-13 扩展报头的使用
(4)路由头。
列在路由头中的地址的作用是标识数据包在分发到目的地的路由中所必须经过的节点。IPv6基本头部中包含的是路由中的第一个节点,而路由头中包含的则是剩余节点的列表(包括最后一个节点)。
路由头中包含Next-Header(下一报头)、Length(长度)Type(类型)、Segments Left(剩余段)和Address(地址)等字段。其中,类型字段包含一个已定义值type 0,剩余段字段是已被明确列出、在到达目的地之前还要经过的节点的数量。
由IPv6头部中目的地址字段所标识的节点来处理路由头。该节点将检查路由头,如果发现所列节点还没有被访问,那么该处理节点将通过对比路由头所列全部节点数与剩余段的数量来标识下一个要访问的节点,下一个节点的地址将被放置在目的地址字段,并将剩余段字段值减1,然后再转发该数据包。
(5)分段头。
当IPv6源节点希望发送的数据包大于去往目的地所经路径的MTU时,就需要使用分段头。如果路径上所有链路的MTU均小于该数据包,那么就需要由源节点负责对该数据包进行分段。但路由器本身并不对IPv6包进行分段,而是由源节点将数据包分段后通过多个数据包进行发送,并在目的地重组这些分段数据包。源节点可以利用MTU路径发现进程来确定去往目的地的路径上的最小MTU,确定了最小MTU之后,源节点就知道了该路径所能传送的最大包尺寸。如果源节点没有运行MTU路径发现进程,那么将假设其所能使用的最大MTU是IPv6最小MTU(即1280字节),有关该进程的详细信息将在8. 4. 5节的“MTU路径发现”中进行介绍。数据包的所有分段都会被标记上一个由源节点生成的标识值。
(6)目的选项头。
对目的选项头所包含的选项来说,IPv6包的目的地都必须加以检查。如果目的选项头紧靠在路由头之前,那么路由头中所包含的每个节点都必须处理目的选项头中的选项;如果目的选项头紧靠在上层协议报头之前,那么只有最终目的地才处理目的选项头中的选项。
IPv6中增加了AH(Authentication Header,认证头),其目的是为IPv6包提供完整性检查和身份验证。在IP包向目的地传送过程中,所有不发生变化的字段都会被用来计算认证信息,对那些发生变化的字段或选项(如跳数限制字段)来说,在计算认证信息时都要被视为0。
(8)封装安全净荷头。
ESP(Encapsulating Security Payload,封装安全净荷)可以提供完整性和机密性机制,可以结合使用AH和ESP来提供认证机制。ESP对数据进行加密并将加密后的数据放置在ESP头部中的数据(Data)部分。加密模式分为隧道模式(Tunnel mode)和传送模式(Transport mode)两种。在隧道模式下,ESP头会对整个IPv6包进行加密,并将加密后的数据放置在加密字段中,之后将ESP头放在一个新的未加密的IPv6包中。在传送模式下,ESP仅加密传送层报文段(TCP、UDP、ICMP),并将加密后的数据放置在加密字段中,之后再放入原始数据包中(位于传送层协议报头之前)。
有关安全机制的问题已超出了本书的讨论范围,更多IPv6的安全信息请参考RFC 2401、 RFC 2402和RFC 2403。