Network 版 (精华区)

发信人: PaulD (但屈指西风几时来,又不道流年暗中偷换), 信区: Network
标  题: Internet 协议第六版 (IPv6) 规范(四) 
发信站: 哈工大紫丁香 (2003年07月31日11:17:56 星期四), 站内信件

4.IPv6扩展首部
在IPv6里,可选的网络层信息在一个独立的首部编码,放在包中IPv6首部与上层协议首部
之间。有这样几个为数不多的扩展首部,每个首部由不同的"下一个首部"的值来标识。一
个IPv6首部可以携带零个,一个或者更多的扩展首部,每个扩展首部由前一个首部中的"下
一个首部"字段标识。如下例所示:
http://www.longen.org/E-K/detaile~k/IPv6-2.gif 
除了一个特例,扩展首部不在包的传送路径中的任何节点检测和处理,直到这个包到达目
的地址字段标识的那个节点(或者在组播的情况下,一组节点中的每一个)。在这里,对IP
v6 首部的"下一个首部"字段的常规处理将是调用处理模块来处理第一个扩展首部,或者,
如果不存在扩展首部,就处理上层首部。每个扩展首部的内容和语义决定是否处理下一个
首部。因此,扩展首部必须严格按照它们在包中出现的次序来处理;这样,接收者就不能
搜索整个包来寻找某个特定类型的首部,并且在处理所有前面的首部之前处理它。
上文所述的特例是指 Hop-by-Hop 选项首部。它携带了包的传送路径中的每个节点都必须
检测和处理的信息,包括源节点和目的节点。Hop-by-Hop 选项首部如果存在,就必须紧跟
在IPv6首部后面. IPv6首部中"下一个首部"字段的值为零表示存在这个首部。如果一个首
部的处理结果要求节点处理下一个首部,但是节点无法识别这个首部的"下一个首部"字段
值,那么节点就应该抛弃这个包,并且给包的源节点发送一个ICMP "参数存在问题"的报文
,ICMP 编码值为 1 ("遇到无法识别的'下一个首部'类型")。ICMP 指针字段包含那个无法
识别的值在原包中的偏移量。如果节点遇到IPv6首部以外的其他首部中的"下一个首部"字
段的值为零的情况,应做相同的处理。
为了后面的首部保持8个八位组对齐,每个扩展首部都是8个八位组的整数倍长。每个扩展
首部的多八位组字段都以它们的自然边界对齐。也就是说,宽度为 n 个八位组的字段放在
距首部开始位置处 n 个八位组的整数倍的位置上,其中 n = 1,2, 4,或者 8。一个完整
的IPv6实现应包含以下扩展首部的处理程序:
Hop-by-Hop 选项首部 
路由首部 (类型 0) 
分片首部 
目的地址首部 
认证首部 
封装安全有效数据首部 (ESP 首部) 
4.1 扩展首部的顺序
当在同一个包中使用多于一个扩展首部时,建议以如下顺序排列这些首部:
IPv6首部
 http://www.longen.org/E-K/detaile~k/IPv6-3.gif
Hop-by-Hop 选项首部
 
目的地址选项首部 (注 1)
 
路由首部
 
分片首部
 
认证首部 (注 2)
 
封装安全有效数据首部 (注 2)
 
目的地址选项首部 (注 3)
 
上层协议首部
 
注 1: 由IPv6目的地址字段及路由首部列出的后续地址中第一个出现的目的地址处理的选
项。
注 2: 关于认证首部和封装安全有效数据首部的相关顺序的附加建议参见其它文献。
注 3: 只由包的最终目的地址处理的选项。
除了目的地址选项首部最多出现两次 (一次在路由首部前,一次在上层协议首部前)以外,
每个扩展首部应当只出现一次。如果上层协议首部是另一个IPv6首部 (在使用通道技术或
封装在IPv6中的情况下),它后面可以有自己的扩展首部. 这些扩展首部以同样的建议顺序
独立排列。如果定义了其他的扩展首部,与上面列出的扩展首部相关的次序限制必须加以
说明。除了 Hop-by-Hop 选项首部必须紧跟在IPv6首部后面以外,IPv6节点必须接受并且尽
量处理任意顺序的,以及在同一个包内出现任意多次的扩展首部。尽管如此,建议IPv6包
的源节点遵守上面的建议顺序,除非后续的协议规范修改这一顺序。
4.2 选项
当前已定义的扩展首部中的两个:Hop-by-Hop 选项首部和目的地址选项首部,携带不定数
量的,以类型-长度-值(TLV)格式进行编码的选项,其格式如下:
http://www.longen.org/E-K/detaile~k/IPv6-3.gif
选项类型
 8 位标识符,标识选项的类型。
 
选项数据长度
 8 位无符号整数。以八位组为单位的选项数据字段的长度。
 
选项数据
 可变长度字段。依选项类型而不同的数据。
 
首部中的选项必须严格按照它们在首部中出现的次序来处理;这样,接收方就不能搜索整
个首部来寻找某个特定类型的选项,并且在处理所有前面的选项之前处理它。选项类型标
识符以如下规则编码: 其最高两位指定了当IPv6节点无法识别这一选项类型时所必须的反
应:
00
 跳过这一选项,继续处理首部。
 
01
 抛弃这个包
 
10
 抛弃这个包,并且不管包的目的地址是不是组播地址,都给包的源地址发送一个 ICMP "
参数存在问题",编码 2 的报文,指针指向无法识别的选项类型。
 
11
 抛弃这个包,并且只有当包的目的地址不是组播地址时,才给包的源地址发送一个 ICMP
 "参数存在问题",编码 2 的报文,指针指向无法识别的选项类型。
 
选项类型标识符的第三位指明了选项数据是否可以改变到最终目的地址的选路。若存在认
证首部,在包计算或校验认证值时,可改变选路的选项的整个数据字段都必须当作全零的
八位组来处理。
0 - 选项数据不会改变选路
1 - 选项数据可能改变选路
上述的前三位应作为选项类型的一部分,而不能独立于选项类型之外。这就是说,某一特定
的选项是由全部 8 位的选项类型标识符标识的,而并不只是选项类型中的后面 5 位。Ho
p-by-Hop 选项首部和目的地址选项首部使用相同的选项类型编码空间。尽管如此,某一特
定类型的选项的规范可以限制其只用于两者之一。有些选项可能具有明确的对齐要求,以
保证选项数据字段中的多八位组值能够落在其自然边界上。选项的对齐要求用符号 xn+y 
来说明,表示选项类型必须出现在从首部开始位置处 x 个八位组的整数倍加上 y 个八位
组的位置上。例如: 2n表示从首部开始处 2 个八位组的整数倍的偏移量。8n+2 表示从首
部开始处 8 个八位组的整数倍加上 2 个八位组的偏移量。有两种填充选项,用来在需要
时对齐后续的选项,以及把整个首部填充成 8 个八位组的整数倍长。所有的IPv6实现都必
须能够识别这些填充选项。
填充1 选项 (对齐要求: 无)
http://www.longen.org/E-K/detaile~k/IPv6-4.gif
填充1 选项是一种特殊情况 -- 它没有长度字段和数值字段。填充1 选项用于在首部的选
项区填充一个八位组。如果需要填充多于一个的八位组,那么就应该使用下面要介绍的填
充N 选项,而不是多个填充1 选项。
填充N 选项 (对齐要求: 无)
http://www.longen.org/E-K/detaile~k/IPv6-5.gif
填充N 选项用于在首部的选项区填充两个或两个以上的八位组。对于 N 个八位组的填充,
选项数据长度字段应包含值 N-2,选项数据由 N-2 个零值八位组组成。
4.3 Hop-by-Hop 选项首部
Hop-by-Hop 选项首部用于传送必须由包的传送路径中的每个节点检测的可选信息。Hop-b
y-Hop 选项首部由IPv6首部中"下一个首部"字段值为 0 来标识,并且具有如下的格式:
下一个首部
http://www.longen.org/E-K/detaile~k/IPv6-6.gif
 8 位选择器。标识紧跟在Hop-by-Hop 选项首部后面的首部的类型。使用与 IPv4 协议字
段 相同的数值。
 
首部扩展长度
 8 位无符号整数。以 8 个八位组为单位的 Hop-by-Hop选项首部的长度,不包括开始的 
8 个八位组。
 
选项
 可变长度字段,其长度须使整个 Hop-by-Hop 选项首部的长度为 8 个八位组的整数倍。
包含一个或多个 TLV 编码的选项,如第 4.2 章中所述。
 
在本文中定义的仅有的 Hop-by-Hop 选项是填充1 及填充N 选项。
4.4 路由首部
路由首部用于IPv6源节点列出到包的目的节点的路径中所应"访问"的一个或多个中间节点
。这一功能十分类似于 IPv4 的松散源地址和路由记录选项。前面的首部中"下一个首部"
字段中的值为 43 表示下一个首部为路由首部。路由首部具有如下的格式:
下一个首部
http://www.longen.org/E-K/detaile~k/IPv6-7.gif
 8 位选择器。标识紧跟在路由首部后面的首部的类型。使用与 IPv4 协议字段相同的数值

 
首部扩展长度
 8 位无符号整数。以 8 个八位组为单位的路由首部的长度,不包括开始的 8 个八位组。

 
路由类型
 8 位的某种特定路由首部变量的标识符。
 
分段剩余
 8 位无符号整数。剩余的路由分段的数量。也就是在到达最终的目的节点之前仍然应当访
问的,明确列出的中间节点的数量。
 
特定类型的数据
 可变长度字段。其格式由路由类型决定,其长度须使整个路由首部的长度为 8 个八位组
的整数倍。
 
如果节点在处理收到的包的过程中遇到了含有无法识别的路由类型值的路由首部,节点应根
据分段剩余字段中的值进行处理,如下所述:如果分段剩余值是零,节点必须忽略路由首部
,继续处理包中的下一个首部,其类型由路由首部中的"下一个首部"字段中的值来标识。
如果分段剩余值非零,节点必须抛弃这个包,并且给包的源地址发送一个 ICMP"参数存在
问题",编码 0 的报文,指针指向无法识别的路由类型。如果中间节点在处理路由首部之
后,确定应将包传送到一个链路 MTU 小于此包的大小的链路中去,那么中间节点必须抛弃
此包,并且给包的源地址发送一个 ICMP"包太大"的报文。
类型 0 的路由首部具有如下格式:
http://www.longen.org/E-K/detaile~k/IPv6-8.gif

下一个首部
 8 位选择器。标识紧跟在路由首部后面的首部的类型。使用与 IPv4 协议字段相同的数值

 
首部扩展长度
 8 位无符号整数。以 8 个八位组为单位的路由首部的长度,不包括开始的 8 个八位组。
对于类型 0 的路由首部,首部扩展长度等于首部中地址数量的两倍。
 
路由类型
 0
 
分段剩余
 8 位无符号整数。剩余的路由分段的数量。也就是在到达最终的目的节点之前仍然应当访
问的,明确列出的中间节点的数量。
 
保留
 32 位保留字段。传输时初始化为零;接收时忽略。
 
地址[1..n]
 128 位地址向量,从 1 到 n 编号。
 
不允许组播地址出现在类型 0 的路由首部中,也不允许出现在携带类型 0 路由首部的包
中的IPv6目的地址字段中。直到包到达IPv6首部中的目的地址字段所标识的那个节点才对
路由首部进行检测和处理。在这个节点调用路由首部处理模块,并且对于路由类型 0,执
行下面的算法:
 
          if 分段剩余 = 0 {
             继续处理包中的下一个首部,其类型由路由首部中"下一个首部"字段所标识

          }
          else if 首部扩展长度为奇数 {
                给源地址发送一个 ICMP "参数存在问题",编码 0 的报文,指针指向首
部扩展长度字段,并且抛弃此包
          }
          else {
             计算出n,也就是路由首部中的地址数量。方法是首部扩展长度除以 2
             if 分段剩余比 n 大 {
                给源地址发送一个 ICMP "参数存在问题",编码 0 的报文,指针指向分
段剩余字段,并且抛弃此包
             }
             else {
                分段剩余减一;
                计算 i,也就是地址向量(地址列表)中要"访问"的下一个地址,方法是
 n 减分段剩余
                if 地址[i] 或者IPv6目的地址是组播地址 {
                   抛弃此包
                }
                else {
                   交换IPv6目的地址和地址[i]
                   ifIPv6跳数限制小于等于 1 {
                      给源地址发送一个 ICMP "超时 - 传输超过跳数限制" 的报文,
并且抛弃此包
                   }
                   else {
                   跳数限制减一;
                   向IPv6模块重新提交此包,传给新的目的节点
                   }
                }
             }
          }
作为上述算法的一个例子,考虑这样一种情况: 源节点 S 给目的节点 D 发送一个包,用
路由首部来使这个包经过中间节点 I1,I2 和 I3。在传送路径的每段中, IPv6首部中的相
关字段值以及路由首部字段值应为如下所述:
当包从 S 传到 I1:
 
源地址 = S
目的地址 = I1
 首部扩展长度 = 6
 
分段剩余 = 3
 
地址[1] = I2
 
地址[2] = I3
 
地址[3] = D
 
当包从 I1 传到 I2:
 
源地址 = S
目的地址 = I2
 首部扩展长度 = 6
 
分段剩余 = 2
 
地址[1] = I1
 
地址[2] = I3
 
地址[3] = D
 
当包从 I2 传到 I3:
 
源地址 = S
目的地址 = I3
 首部扩展长度 = 6
 
分段剩余 = 1
 
地址[1] = I1
 
地址[2] = I2
 
地址[3] = D
 
当包从 I3 传到 D:
 
源地址 = S
目的地址 = D
 首部扩展长度 = 6
 
分段剩余 = 0
 
地址[1] = I1
 
地址[2] = I2
 
地址[3] = I3
 
4.5 分片首部
IPv6源节点使用分片首部来发送大于去往目的节点的路径 MTU 的包。(注意: 不同于 IPv
4 的是,在IPv6里,只有包的源节点才能进行分片,传输路径中的路由器不能进行分片 ?
参见第 5 章) 前面的首部中"下一个首部"字段中的值为 44 表示下一个首部为分片首部。
分片首部具有如下格式:
http://www.longen.org/E-K/detaile~k/IPv6-14.gif
下一个首部
 8 位选择器。标识原包(后面有定义)中可分片部分的初始首部的类型。使用与 IPv4 协议
字段相同的数值。
 
保留
 8 位保留字段。传输时初始化为零;接收时忽略。
 
分片偏移量
 13 位无符号整数。以 8 个八位组为单位的,首部后面的数据相对于原包中可分片部分的
开始位置处的偏移量。
 
Res (保留)
 2 位保留字段。传输时初始化为零;接收时忽略。
 
M 标志位
 1 = 还有分片;0 = 最后一个分片。
 
标识
 32 位。参见下面的说明。
 
要发送大于去往目的节点的路径 MTU 的包,源节点可以将包分成若干分片,每个分片单独
发送,并且在接收者处进行重组。源节点应为每个要分片的包规定一个标识值。这个标识
值必须不同于近期之内,同一对源节点和目的节点之间其他的分片包的标识值。如果存在
路由首部,那么目的节点是指最终目的节点。"近期之内" 是指包可能的最大生存期。其中
包括从源节点到目的节点的传输时间,以及等待与同一包的其他分片重组所花费的时间。
尽管如此,源节点并没有必要知道包的最大生存期。它只需将标识字段值作为一个简单的
32 位循环计数器,每次将包分片时计数器增加一个增量即可。具体的实现可以自己选择是
维护一个计数器还是多个计数器,还可以选择是为每个节点可能的源地址维护一个计数器
,还是为每个活动的 (源地址,目的地址) 对维护一个计数器。最初的,未分片的大数据
包称为"原包"。原包可以看作是由两部分组成的,如下所示:
原包:
http://www.longen.org/E-K/detaile~k/IPv6-10.gif
不可分片部分包括IPv6首部,以及那些必须由路由中的节点处理的扩展首部。也就是以下
三种情况: 所有路由首部以前(含路由首部)的首部(如果存在的话),或者是 Hop-by-Hop 选
项首部(如果存在的话),或者没有扩展首部。包中其余的部分为可分片部分,也就是只需
由包的最终目的节点处理的扩展首部,以及上层协议首部和数据。原包中可分片部分被划
分成若干分片,除去最后("最右")一个分片,每个分片都为8 个八位组的整数倍长。这些
分片由相互独立的"分片包"来传送,如下例所示:
原包:
http://www.longen.org/E-K/detaile~k/IPv6-11.gif
分片包:
http://www.longen.org/E-K/detaile~k/IPv6-12.gif
每个分片包由下述几部分构成:
(1) 原包中的不可分片部分。其中原来IPv6首部中有效数据长度值只应包含本分片包的长
度 (不包含IPv6首部自身的长度)。不可分片部分中最后一个首部的"下一个首部"字段值改
为 44。
(2) 分片首部。其中包括:其"下一个首部"值标识原包中可分片部分的第一个首部。其分片
偏移量字段 包含以 8 个八位组为单位的,本分片相对于原包中可分片部分开始位置处的
偏移量。第一个("最左")分片的分片偏移量为 0。其 M 标志位为 0 表示这是最后("最右
")一个分片,否则 M 标志位为 1。其标识值依原包产生。
(3) 分片自身
分片的长度应使分片包的大小适于去往目的节点的路径 MTU。在目的节点,分片包重组为
原来未分片的形式,如下例所示:
重组的原包:
http://www.longen.org/E-K/detaile~k/IPv6-14.gif
重组应遵循如下原则:
原包只能由具有相同源地址,目的地址和分片标识的分片包重组。重组后的包中的不可分
片部分由第一个分片包(也就是分片偏移量为 0 的那个包)中分片首部前面所有的首部(不
含分片首部)组成,并作如下两处修改:从第一个分片的分片首部中的"下一个首部"字段得
到不可分片部分最后一个首部中的"下一个首部"字段值。由不可分片部分的长度及最后一
个分片的长度和偏移量计算出重组包的有效数据长度。计算重组包的有效数据长度的公式
为:
PL.orig = PL.first - FL.first - 8 + (8 * FO.last) + FL.last
PL.orig = 重组包的有效数据长度字段。
PL.first = 第一个分片包的有效数据长度字段。
FL.first = 第一个分片包中分片首部后面的分片长度。
FO.last = 最后一个分片包中分片首部的分片偏移量字段。
FL.last = 最后一个分片包中分片首部后面的分片长度。
重组包的可分片部分由各分片包中分片首部后面的分片组成。各分片的长度可由分片包的
有效数据长度减去此包中IPv6首部与分片之间所有首部的长度计算得到。各分片在可分片
部分中的相对位置由其分片偏移量值计算得到。最终重组后的包不含分片首部。包的重组
过程可能出现下列错误情形:
如果收到包的第一个(到达的)分片之后 60 秒内没有收到全部分片以完成重组,那么必须终
止这次重组,抛弃所有已收到的包。如果收到了第一个分片 (也就是分片偏移量为零的那
个分片),应给分片的源节点发送一个 ICMP "超时 -- 分片重组超时"报文。 
如果由分片包的有效数据长度字段得到的分片长度不是 8 个八位组的整数倍,而且分片的
 M 标志位被置为 1,那么必须抛弃这个分片,并且给分片的源节点发送一个 ICMP "参数
存在问题",编码 0 的报文,指针指向分片包的有效数据长度字段。 
如果分片的长度和偏移量使得重组后的包的有效数据长度超过了 65,535 个八位组,那么
必须抛弃这个分片,并且向分片的源节点发送一个 ICMP "参数存在问题",编码 0 的报文
,指针指向分片包的分片偏移量字段。 
不希望出现下述情形,但不将它们视为错误:
同一个原包的不同分片中,分片首部前面的首部在数量和内容上都可能不同。 
当每个分片包到达时,无论分片首部前面的首部是什么,都应在进入分片重组队列之前进
行处理。只有分片偏移量为零的那个包中的首部才保留在重组后的包中。 
同一个原包的不同分片中,分片首部中"下一个首部"值可能不同。只有分片偏移量为零的
那个包中的值才可用于重组。 
4.6 目的地址选项首部
目的地址选项首部用于携带只需由包的目的节点检测的可选信息。前面的首部中"下一个首
部"字段中的值为 60 表示下一个首部为目的地址选项首部。目的地址选项首部具有如下格
式:
http://www.longen.org/E-K/detaile~k/IPv6-15.gif
下一个首部
 8 位选择器。标识紧跟在目的地址选项首部后面的首部的类型。使用与 IPv4 协议字段相
同的数值。
 
首部扩展长度
 8 位无符号整数。以 8 个八位组为单位的目的地址选项首部的长度,不包括开始的 8 个
八位组。
 
选项
 可变长度字段,其长度须使整个目的地址选项首部的长度为 8 个八位组的整数倍。包含
一个或多个 TLV 编码的选项,如第 4.2 章中所述。
 
在本文中定义的仅有的目的地址选项是填充1 及填充N 选项,如第 4.2 章中所述。需要注
意的是,有两种途径来编码目的地址的可选信息: 或者作为目的地址选项首部中的一个选
项,或者作为一个独立的扩展首部。分片首部和认证首部就是后者的典型例子。使用哪种
方法取决于目的节点无法识别这一可选信息时,希望采取的措施:
o 如果希望节点抛弃这个包,并且当包的目的地址不是组播地址时,给包的源地址发送一
个 ICMP "类型无法识别"报文,可以将这一信息编码成独立的扩展首部或者目的地址选项
首部中的一个选项,其选项类型的最高两位为 11。最终的选择可以根据其他的因素而定,
比如哪一个可以使用更少的八位组,哪一个能生成更好的对齐或者具有更高的处理效率。
o 如果希望采取其他的措施,那么这一信息必须作为目的地址选项首部的一个选项进行编
码。其选项类型的最高两位为 00,01 或 10,指定所需采取的措施。
4.7 "无下一个首部"
IPv6首部或者扩展首部中"下一个首部"的值为 59 表示这个首部后面没有其他的首部了。
如果IPv6首部中的有效数据字段表明最后一个首部 ("下一个首部"字段为 59 的那个首部
) 后面还有其他的八位组,那么这些八位组将被忽略,并且在传输过程中保持不变。


--
The secret of happy living is not to do what you like, 
              but to like what you do. 

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.230.170]
※ 修改:·PaulD 於 07月31日11:37:05 修改本文·[FROM: 202.118.230.170]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:213.213毫秒