11. 文本表示 (Textual Representation)
文本表示 (Textual Representation)
如前所述, 要明确指定 IPv6 非全局地址, 也应指定预期的作用域区域。作为指定作用域区域的通用符号, 实现应该支持以下格式:
<address>%<zone_id>
其中:
<address>是字面 IPv6 地址,<zone_id>是标识地址区域的字符串, 以及%是分隔符字符, 用于区分<address>和<zone_id>。
以下小节描述了格式的详细定义、具体示例和其他注释。
11.1. 非全局地址 (Non-Global Addresses)
该格式适用于除未指定地址外的所有非全局作用域单播和多播地址, 未指定地址没有作用域。该格式对全局地址没有意义, 不应用于全局地址。回环地址属于虚拟链路, 即连接到回环接口的链路。因此该格式也不应用于回环地址。本文档没有规定当 <address> 是未指定地址时格式的使用, 因为该地址没有作用域。然而, 本文档不禁止实现为实现相关目的对这些特殊地址使用该格式。
11.2. <zone_id> 部分
在文本表示中, <zone_id> 部分应该能够标识地址作用域的特定区域。虽然区域索引预期包含足够的信息来确定作用域并在如第 6 节所述的所有作用域之间是唯一的, <zone_id> 部分的格式不必包含作用域。这是因为 <address> 部分应指定适当的作用域。这也意味着 <zone_id> 部分不必在所有作用域之间是唯一的。
借助这种宽松的特性, 实现可以使用方便的表示作为 <zone_id>。例如, 为了表示链路索引 2, 实现可以简单地使用 "2" 作为 <zone_id>, 这比包含 "link" 作用域的其他表示更可读。
当实现解释格式时, 它应该从 <zone_id> 部分和 <address> 部分指定的作用域构造 "完整" 区域索引。(记住区域索引本身应该包含作用域, 如第 6 节所指定的。)
实现应该支持至少数值索引, 即非负十进制整数作为 <zone_id>。默认区域索引 (通常应为 0, 见第 6 节) 包含在整数中。当 <zone_id> 是默认时, 分隔符字符 "%" 和 <zone_id> 可以省略。类似地, 如果给定 IPv6 地址的文本表示没有区域索引, 它应该被解释为 <address>%<default ID>, 其中 <default ID> 是 <address> 具有的作用域的默认区域索引。
实现可以支持其他种类的非空字符串作为 <zone_id>。然而, 字符串不得与分隔符字符冲突。附加字符串的精确格式和语义是实现相关的。
这些字符串的一个可能的候选是接口名称, 因为接口唯一地消除任何作用域的歧义。特别是, 接口名称可以用作接口和链路的 "默认标识符", 因为默认情况下接口和这些作用域之间存在一一对应关系, 如第 6 节所述。
实现也可以将接口名称用作 <zone_id> 用于大于链路的作用域, 但此用法可能会导致一些混淆。例如, 当多个接口属于同一 (多播) 站点时, 用户会对应该使用哪个接口感到困惑。此外, 从地址到名称的映射函数在打印具有接口名称作为区域索引的地址时会遇到相同类型的问题。本文档没有规定这些情况应该如何处理, 并且将其留作实现相关。
不能假设索引在区域中的所有节点中是通用的 (见第 6 节)。因此, 格式必须仅在节点内使用, 并且除非解释格式的每个节点都同意语义, 否则不得在线路上发送。
11.3. 示例 (Examples)
以下地址
fe80::1234 (在节点的第 1 条链路上)
ff02::5678 (在节点的第 5 条链路上)
ff08::9abc (在节点的第 10 个组织)
会被表示如下:
fe80::1234%1
ff02::5678%5
ff08::9abc%10
(这里我们假设从区域索引到 <zone_id> 部分的自然转换, 其中任何作用域的第 N 个区域转换为 "N"。)
如果我们使用接口名称作为 <zone_id>, 这些地址也可以表示如下:
fe80::1234%ne0
ff02::5678%pvc1.3
ff08::9abc%interface10
其中接口 "ne0" 属于第 1 条链路, "pvc1.3" 属于第 5 条链路, 和 "interface10" 属于第 10 个组织。
11.4. 使用示例 (Usage Examples)
应该在端主机中使用的应用程序, 如 telnet、ftp 和 ssh, 可能不会明确支持地址作用域的概念, 特别是链路本地地址。然而, 专家用户 (例如, 网络管理员) 有时必须向这样的应用程序给予甚至链路本地地址。
这是一个具体的例子。考虑一个称为 "R1" 的多链路路由器, 它至少有两个点对点接口 (链路)。这些接口中的每一个都连接到另一个路由器, 分别为 "R2" 和 "R3"。还假设点对点接口仅具有链路本地地址。
现在假设 R2 上的路由系统挂起, 必须重新启动。在这种情况下, 我们可能无法使用 R2 的全局地址, 因为这是路由故障, 我们不能期望有足够的全局可达性的路由到 R2。
因此, 我们必须首先登录 R1, 然后尝试使用链路本地地址登录 R2。在这种情况下, 我们必须给例如 telnet 给出 R2 的链路本地地址。这里我们假设地址是 fe80::2。
注意我们不能仅仅输入
% telnet fe80::2
这里, 因为 R1 有多个链路, 因此 telnet 命令无法检测到它应该尝试使用哪个链路进行连接。相反, 我们应该输入带有链路索引的链路本地地址, 如下所示:
% telnet fe80::2%3
其中分隔符字符 % 之后的 "3" 对应于点对点链路的链路索引。
11.5. 相关 API (Related API)
推荐的基本 API 的扩展定义了在将节点名翻译为地址或反之亦然的库函数中应该如何处理非全局地址的格式 [11]。
11.6. 省略区域索引 (Omitting Zone Indices)
本文档中定义的格式不打算使非全局地址的原始格式无效; 即, 不带区域索引部分的格式。如第 6 节所述, 在某些具有默认区域索引概念的常见情况下, 可能不存在关于作用域区域的歧义。在这样的环境中, 实现可以省略 "%<zone_id>" 部分。因此, 它可以表现得好像根本不支持扩展格式。
11.7. 分隔符字符的组合 (Combinations of Delimiter Characters)
为 IPv6 地址定义了其他种类的分隔符字符。在本小节中, 我们描述它们应该如何与非全局地址的格式组合。
IPv6 寻址架构 [1] 还定义了 IPv6 前缀的语法。如果前缀的地址部分是非全局的, 其作用域区域应该明确, 地址部分应该是格式。例如, 第二条链路上的链路本地前缀 fe80::/64 可以表示如下:
fe80::%2/64
在这个组合中, 当我们考虑按名称-地址库函数解析格式时 [11], 重要的是在前缀长度之前放置区域索引部分。也就是说, 我们可以首先将地址与区域索引从前缀长度分开, 并仅将前者传递给库函数。
URL 中字面 IPv6 地址的首选格式也被定义 [12]。当用户键入其区域应该明确指定的 IPv6 非全局地址的首选格式时, 用户可以使用非全局地址的格式与首选格式组合。
然而, 输入的 URL 通常在线路上发送, 如果应用程序没有在发送前剥离 <zone_id> 部分, 它会导致混淆。注意应用程序不需要关心他们使用的是什么类型的地址, 更不用说解析或剥离地址的 <zone_id> 部分。
此外, 非全局地址的格式可能与 URI 语法 [13] 冲突, 因为语法将分隔符字符 (%) 定义为转义字符。此冲突将需要, 例如, 区域 1 的 <zone_id> 部分用分隔符表示为 '%251'。它也意味着我们不能简单地将其他来源中的非转义格式作为输入复制到 URI 解析器。此外, 如果 URI 解析器在将其传递给名称-地址库函数之前不转换转义格式, 转换将失败。所有这些问题会降低本节所述的文本表示的好处。
因此, 本文档不规定非全局地址的格式应该如何与字面 IPv6 地址的首选格式组合。在任何情况下, 建议在 URL 中使用 FQDN 而不是字面 IPv6 地址, 只要 FQDN 可用。