4. Control Message Attribute Value Pairs (控制消息属性值对)
为了在保证互操作性的同时最大化可扩展性,整个 L2TP 使用统一的方法来编码消息类型和消息体。这种编码在本文档的其余部分将被称为 AVP (Attribute-Value Pair,属性值对)。
4.1 AVP Format (AVP 格式)
每个 AVP 的编码如下:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|M|H| rsvd | Length | Vendor ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute Type | Attribute Value...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
[until Length is reached]... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
前六位是位掩码,描述 AVP 的一般属性。
本文档定义了两个位,其余位为将来扩展保留。保留位必须 (MUST) 设置为 0。接收到保留位设置为 1 的 AVP 必须 (MUST) 被视为无法识别的 AVP。
Mandatory (M) 位:控制实现接收到其无法识别的 AVP 时所需的行为。如果在与特定会话关联的消息中的无法识别的 AVP 上设置了 M 位,则与此消息关联的会话必须 (MUST) 被终止。如果在与整个隧道关联的消息中的无法识别的 AVP 上设置了 M 位,则整个隧道(及其内的所有会话)必须 (MUST) 被终止。如果未设置 M 位,则必须 (MUST) 忽略无法识别的 AVP。然后控制消息必须继续处理,就像该 AVP 不存在一样。
Hidden (H) 位:标识 AVP 的 Attribute Value 字段中数据的隐藏。此功能可用于避免以明文形式在 AVP 中传递敏感数据,例如用户密码。第 4.3 节描述了执行 AVP 隐藏的过程。
Length:编码此 AVP 中包含的八位字节数(包括整体长度和位掩码字段)。长度可以计算为 6 + Attribute Value 字段的长度(以八位字节为单位)。该字段本身为 10 位,允许单个 AVP 中最多 1023 个八位字节的数据。AVP 的最小长度为 6。如果长度为 6,则 Attribute Value 字段不存在。
Vendor ID:IANA 分配的"SMI Network Management Private Enterprise Codes" [RFC1700] 值。值 0 对应于 IETF 采用的属性值,用于本文档中定义的所有 AVP。任何希望实现自己的 L2TP 扩展的供应商都可以使用自己的 Vendor ID 以及私有 Attribute 值,保证它们不会与任何其他供应商的扩展或未来的 IETF 扩展冲突。请注意,为 Vendor ID 分配了 16 位,因此将此功能限制为前 65,535 个企业。
Attribute Type:一个 2 八位字节的值,在给定 Vendor ID 下定义的所有 AVP 中具有唯一的解释。
Attribute Value:这是由 Vendor ID 和 Attribute Type 指示的实际值。它紧跟在 Attribute Type 字段之后,并运行 Length 中指示的剩余八位字节(即 Length 减去 6 个八位字节的头部)。如果 Length 为 6,则此字段不存在。
4.2 Mandatory AVPs (强制性 AVP)
接收到设置了 M 位的未知 AVP 对于与其关联的会话或隧道是灾难性的。因此,M 位应该只为对会话或隧道的正常操作绝对关键的 AVP 定义。此外,在 LAC 或 LNS 接收到设置了 M 位的未知 AVP 并相应地关闭会话或隧道的情况下,发送强制性 AVP 的对等方完全有责任接受导致不可互操作情况的故障。在定义设置了 M 位的 AVP 之前,特别是供应商特定的 AVP,请确保这是预期的后果。
当存在使用 M 位的充分替代方案时,应该使用它。例如,不是简单地发送设置了 M 位的 AVP 来确定特定扩展是否存在,可以通过在请求消息中发送 AVP 并期望在回复消息中有相应的 AVP 来识别可用性。
使用新 AVP(本文档中未定义的那些)的 M 位必须 (MUST) 提供配置关闭相关功能的能力,使得 AVP 要么不发送,要么在未设置 M 位的情况下发送。
4.3 Hiding of AVP Attribute Values (隐藏 AVP 属性值)
每个 AVP 头部中的 H 位提供了一种机制,用于向接收对等方指示 AVP 的内容是隐藏的还是以明文形式存在的。此功能可用于隐藏敏感的控制消息数据,例如用户密码或用户 ID。
H 位只有 (MUST) 在 LAC 和 LNS 之间存在共享密钥时才能设置。共享密钥与用于隧道认证的密钥相同(参见第 5.1.1 节)。如果在给定控制消息的任何 AVP 中设置了 H 位,则消息中还必须 (MUST) 存在 Random Vector AVP,并且必须 (MUST) 在第一个 H 位为 1 的 AVP 之前。
隐藏 AVP 值分几个步骤完成。第一步是获取原始(明文)AVP 的长度和值字段,并将它们编码到隐藏 AVP 子格式中,如下所示:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length of Original Value | Original Attribute Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... | Padding ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Length of Original Attribute Value:这是要隐藏的原始属性值的长度(以八位字节为单位)。这对于确定属性值的原始长度是必要的,因为在添加额外的填充时会丢失该长度。
Original Attribute Value:要隐藏的属性值。
Padding:用于隐藏正在隐藏的属性值长度的随机附加八位字节。
为了掩盖被隐藏数据的大小,生成的子格式可以 (MAY) 如上所示进行填充。填充不会改变放置在 Length of Original Attribute Value 字段中的值,但会改变正在创建的结果 AVP 的长度。例如,如果要隐藏的属性值长度为 4 个八位字节,则未隐藏的 AVP 长度将为 10 个八位字节(6 + 属性值长度)。隐藏后,AVP 的长度将变为 6 + 属性值长度 + Length of Original Attribute Value 字段的大小 + 填充。因此,如果填充为 12 个八位字节,则 AVP 长度将为 6 + 4 + 2 + 12 = 24 个八位字节。
接下来,对以下内容的连接执行 MD5 哈希:
- AVP 的 2 个八位字节属性编号
- 共享密钥
- 任意长度的随机向量
此哈希中使用的随机向量的值在 Random Vector AVP 的值字段中传递。此 Random Vector AVP 必须由发送者在任何隐藏 AVP 之前放置在消息中。相同的随机向量可以用于同一消息中的多个隐藏 AVP。如果对后续 AVP 的隐藏使用不同的随机向量,则必须在应用它的第一个 AVP 之前在命令消息中放置新的 Random Vector AVP。
然后将 MD5 哈希值与隐藏 AVP 子格式的前 16 个八位字节(或更少)段进行异或 (XOR),并放置在隐藏 AVP 的 Attribute Value 字段中。如果隐藏 AVP 子格式少于 16 个八位字节,则子格式被转换,就像在 XOR 之前 Attribute Value 字段已被填充到 16 个八位字节一样,但只有子格式中实际存在的八位字节被修改,并且 AVP 的长度不会改变。
如果子格式长度超过 16 个八位字节,则对由共享密钥后跟第一次 XOR 的结果组成的八位字节流计算第二个单向 MD5 哈希。该哈希与子格式的第二个 16 个八位字节(或更少)段进行 XOR,并放置在隐藏 AVP 的 Value 字段的相应八位字节中。
如果需要,重复此操作,共享密钥与每个 XOR 结果一起使用以生成下一个哈希,以便对值的下一段进行 XOR。
隐藏方法改编自 RFC 2138 [RFC2138],该方法取自 Kaufman、Perlman 和 Speciner [KPS] 所著的"Network Security"一书中的"Mixing in the Plaintext"部分。该方法的详细说明如下:
称共享密钥为 S,随机向量为 RV,属性值为 AV。将值字段分解为 16 个八位字节的块 p1、p2 等,最后一个块在末尾用随机数据填充到 16 个八位字节的边界。称密文块为 c(1)、c(2) 等。我们还将定义中间值 b1、b2 等。
b1 = MD5(AV + S + RV) c(1) = p1 xor b1
b2 = MD5(S + c(1)) c(2) = p2 xor b2
. .
. .
. .
bi = MD5(S + c(i-1)) c(i) = pi xor bi
字符串将包含 c(1)+c(2)+...+c(i),其中 + 表示连接。
接收时,从要取消隐藏的 AVP 之前在消息中遇到的最后一个 Random Vector AVP 中获取随机向量。然后反转上述过程以产生原始值。
4.4 AVP Summary (AVP 摘要)
以下各节包含本文档中定义的所有 L2TP AVP 的列表。
AVP 名称后面是使用每个 AVP 的消息类型列表。每个 AVP 标题后面是 AVP 目的的简短描述、Attribute Value 格式的详细信息(包括图形),以及正确使用 AVP 所需的任何其他信息。
4.4.1 AVPs Applicable To All Control Messages (适用于所有控制消息的 AVP)
Message Type (所有消息)
Message Type AVP,Attribute Type 0,标识此处的控制消息并定义确定后续 AVP 确切含义的上下文。
此 AVP 的 Attribute Value 字段具有以下格式:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Message Type 是 2 个八位字节的无符号整数。
Message Type AVP 必须 (MUST) 是消息中的第一个 AVP,紧跟在控制消息头部(在第 3.1 节中定义)之后。有关已定义的控制消息类型及其标识符的列表,请参见第 3.2 节。
Message Type AVP 中的 Mandatory (M) 位具有特殊含义。它不是指示在无法识别 AVP 本身时是否应忽略 AVP,而是指示是否应忽略控制消息本身。因此,如果在 Message Type AVP 中设置了 M 位,并且实现不知道该 Message Type,则必须 (MUST) 清除隧道。如果未设置 M 位,则实现可以忽略未知的消息类型。对于本文档中定义的所有消息类型,M 位必须 (MUST) 设置为 1。此 AVP 不能被隐藏(H 位必须 (MUST) 为 0)。此 AVP 的长度为 8。
Random Vector (所有消息)
Random Vector AVP,Attribute Type 36,用于启用任意 AVP 的 Attribute Value 的隐藏。
此 AVP 的 Attribute Value 字段具有以下格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Random Octet String ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Random Octet String 可以是任意长度,尽管建议至少 16 个八位字节的随机向量。该字符串包含用于计算 MD5 哈希以检索或隐藏隐藏 AVP 的 Attribute Value 的随机向量(参见第 4.2 节)。
一个消息中可能出现多个 Random Vector AVP,在这种情况下,隐藏的 AVP 使用最接近它的 Random Vector AVP。此 AVP 必须 (MUST) 在第一个设置了 H 位的 AVP 之前。
此 AVP 的 M 位必须 (MUST) 设置为 1。此 AVP 不得 (MUST NOT) 被隐藏(H 位必须 (MUST) 为 0)。此 AVP 的长度为 6 加上 Random Octet String 的长度。
4.4.2 Result and Error Codes (结果和错误代码)
Result Code (CDN, StopCCN)
Result Code AVP,Attribute Type 1,指示终止控制通道或会话的原因。
此 AVP 的 Attribute Value 字段具有以下格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Result Code | Error Code (opt) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Error Message (opt) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Result Code 是 2 个八位字节的无符号整数。可选的 Error Code 是 2 个八位字节的无符号整数。可选的 Error Message 可以跟在 Error Code 字段之后。Error Code 和 Message 的存在由 AVP Length 字段指示。Error Message 包含任意字符串,提供与条件相关的进一步(人类可读)文本。所有错误消息中的人类可读文本必须 (MUST) 使用默认语言 [RFC2277] 以 UTF-8 字符集提供。
此 AVP 不得 (MUST NOT) 被隐藏(H 位必须 (MUST) 为 0)。此 AVP 的 M 位必须 (MUST) 设置为 1。如果没有 Error Code 或 Message,长度为 8;如果有 Error Code 但没有 Error Message,长度为 10;如果有 Error Code 和 Message,长度为 10 + Error Message 的长度。
StopCCN 消息的已定义 Result Code 值:
- 0 - 保留
- 1 - 清除控制连接的一般请求
- 2 - 一般错误——Error Code 指示问题
- 3 - 控制通道已存在
- 4 - 请求者无权建立控制通道
- 5 - 请求者的协议版本不受支持——Error Code 指示支持的最高版本
- 6 - 请求者正在关闭
- 7 - 有限状态机错误
CDN 消息的已定义 Result Code 值:
- 0 - 保留
- 1 - 由于载波丢失而断开呼叫
- 2 - 由于错误代码中指示的原因断开呼叫
- 3 - 由于管理原因断开呼叫
- 4 - 由于缺少适当的设施而呼叫失败(临时条件)
- 5 - 由于缺少适当的设施而呼叫失败(永久条件)
- 6 - 无效目的地
- 7 - 由于未检测到载波而呼叫失败
- 8 - 由于检测到忙音信号而呼叫失败
- 9 - 由于缺少拨号音而呼叫失败
- 10 - 呼叫未在 LAC 分配的时间内建立
- 11 - 呼叫已连接但未检测到适当的帧
一般错误代码:
下面定义的错误代码涉及不特定于任何特定 L2TP 请求的错误类型,而是协议或消息格式错误。如果 L2TP 回复在其 Result Code 中指示发生一般错误,则应检查 General Error 值以确定错误是什么。当前定义的 General Error 代码及其含义是:
- 0 - 无一般错误
- 1 - 此 LAC-LNS 对尚不存在控制连接
- 2 - 长度错误
- 3 - 其中一个字段值超出范围或保留字段非零
- 4 - 资源不足,现在无法处理此操作
- 5 - Session ID 在此上下文中无效
- 6 - LAC 中发生通用供应商特定错误
- 7 - 尝试另一个。如果 LAC 知道其他可能的 LNS 目的地,它应该尝试其中一个
- 8 - 由于接收到设置了 M 位的未知 AVP 而关闭会话或隧道(参见第 4.2 节)
当使用 General Error Code 6 时,应该 (SHOULD) 在 Error Message 字段中包含有关错误的其他信息。
4.4.3 Control Connection Management AVPs (控制连接管理 AVP)
本节定义了用于控制连接管理的其他AVP类型。