RFC4944:在 IEEE 802.15.4 网络上传输 IPv6 报文

目录

摘要

  本文描述了在 IEEE 802.15.4 网络上传输 IPv6 报文的帧格式,和生成 IPv6 链路地址和无状态自动配置地址的方法。另外,还描述了一个简单的、使用共享上下文的报头压缩方法和在 IEEE 802.15.4 mesh 网络中传输报文的方法。

1 简介

  IEEE 802.15.4 标准 [ieee802.15.4] 主要用于低功耗个人局域网。本文定义了在 IEEE 802.15.4 网络上传输的 IPv6 报文的帧格式、IPv6 链路地址和无状态自动配置地址等信息。由于 IPv6 的报文长度比 IEEE 802.15.4 最大帧长还要大得多,所以定义了一个适配层。为了能够在实际的 IEEE 802.15.4 网络上传输 IPv6,还定义了头部压缩机制。完整的 mesh 路由定义(使用特定的协议,与邻居发现交互等)不在本文的讨论范围内。

1.1 符号说明

  本文使用的关键词“MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“MAY”和“OPTIONAL”请参考 [RFC2119]。

1.2 术语使用

AES - Advanced Encryption Scheme

  高级加密标准

CSMA/CA - Carrier Sense Multiple Access / Collision Avoidance

  载波侦听多路访问/冲突避免

FFD - Full Function Device

  全功能设备

GTS - Guaranteed Time Service

  保护时间服务

MTU - Maximum Transmission Unit

  最大传输单元

MAC - Media Access Control

  介质访问控制

PAN - Personal Area Network

  个人局域网

RFD - Reduced Function Device

  简化功能设备   

2 IP 的 IEEE 802.15.4 模式

  IEEE 802.15.4 定义了四种类型的帧:信标帧,MAC 命令帧,确认帧和数据帧。IPv6 报文必须放在数据帧里。数据帧要求进行确认是可选的。为了符合 [RFC3819],帮助链路恢复,建议在传输 IPv6 报文时设置该帧为需要确认。

  IEEE 802.15.4 网络有两种模式:非信标使能模式和信标使能模式 [ieee802.15.4]。 信标使能模式是一个可选模式,该网络中的设备通过协调器的信标进行同步。IEEE 802.15.4 允许使用超帧,在超帧内可以使用免竞争的 GTS。本文不要求 IEEE 网络必须运行在信标使能模式下。在非信标模式网络中,传输数据帧(包括运载 IPv6 报文的数据帧)时是通过基于竞争的非时隙版 CSMA/CA 来访问信道的。

  在非信标模式网络中,信标不是用来同步的,但是依然可用于链路层的设备发现,即用于设备与网络的关联和解关联。本文建议配置信标以实现这些功能。同时,为了有助于检测网络附加,还建议将在 IPv6 层支持这些事件,这也是 IETF 正在研究的问题。

  IEEE 802.15.4 允许在帧中省略源地址或/和目标地址,但是本文定义的机制要求在帧头中必须包含源地址和目的地址,以及可以包含 PAN ID 和目的 PAN ID 字段。   

3 编址模式

  IEEE 802.15.4 定义了两种编址模式:64 位扩展地址模式和(在设备与网络关联后) 16 位地址模式(这个地址在 PAN 网络中是唯一的)。本文既支持 64 位扩展地址,又支持 16 位短地址。本文对 16 位短地址的格式增加了一些限制(除了 IEEE 802.15.4 要求的之外),具体描述见第 12 章。短地址实质上是瞬态的,需要注意的是:由于短地址是由 PAN 协调器在进行关联操作时分配的,所以它们只在此次关联的生命周期内是有效的、唯一的。当关联周期到期,或者 PAN 协调器发生灾难时,短地址的生命周期就结束了。由于集中分配和 PAN 协调器的单点故障而产生的可伸缩问题,开发者在使用短地址部署网络时必须仔细权衡网络的增长(并实行必要的机制)。当然, IEEE 64 位扩展地址就不会有这样的缺点,但仍然会有一些可伸缩问题,比如路由、设备发现、配置等。

  本文假定一个 PAN 映射到一个特定的 IPv6 连接。这符合共享网络支持链路层子网广播的建议 [RFC3819]。严格来说,在 IPv6 里存在多播而不存在广播。而 IEEE 802.15.4 不支持多播,所以 IPv6 层多播报文必须放在 IEEE 802.15.4 网络的链路层广播帧里。这是强制要求的,因为广播帧只被特定链路的 PAN 里的设备所接收。安装 [ieee802.15.4] 第 7.5.6.2 的要求,必须要实现如下两点:

  1. 帧里包含一个目的 PAN 标识符,它必须与链路层的 PAN ID 相匹配。
  2. 帧里包含一个目的短地址,它必须与广播地址(0xffff)相匹配。

  另外,第 9 章的 IPv6 多播地址映射的支持必须只用在一个 mesh 配置里。本文对这个功能不做更具体的描述。

  通常,主机从路由器广告里学习 IPv6 前缀 [RFC4861]。

4 最大传输单元 MTU

  在 IEEE 802.15.4 上的 IPv6 报文最大传输单元是 1280 字节。然而, 一个 IEEE 802.15.4 帧里 容不下一个完整的 IPv6 报文。802.15.4 协议数据单元的大小取决于报文头的大小 [ieee802.15.4]。由于一个物理层的最大帧长是 127 字节(aMaxPHYPacketSize)且一个最大帧头长度是 25 字节(aMaxFrameOverhead),所以 MAC 层的最大帧长是 102 字节。链路安全协议还需要增加报头长度,最大的情况(对于 AES-CCM-128 来说是 21 字节, AES-CCM-32和 AES-CCM-64 分别是 9 和 13 字节),只剩下 81 字节可用。这明显远不够 IPv6 报文的最小长度 1280 字节,为了和第 5 章的 IPv6 规范 [RFC2460] 一致, IP 层下必须提供一个分片和重组的适配层。 适配层在第 5 节定义。

  另外,由于 IPv6 报头长度是 40 字节,这就只剩下 41 字节给上层协议,如 UDP。 UDP 使用8 字节的报头,那应用数据就只剩下 33 字节了。并且,如上面提到的,还需要一个分片和重组的适配层,这将消耗更多的报头字节。

  上述问题引起了如下两点:

  1. 适配层必须满足 IPv6 对于最小 MTU 的要求。然而(a)多数 IEEE 802.15.4 应用并不会使用这么大的报文,(b)小量的应用数据和使用合理的报头压缩可以产生适合于一个 IEEE 802.15.4 帧的报文。 使用适配层的理由不仅是为了满足 IPv6 报文,极有可能一些应用交换(如配置或服务)产生的报文也需要少量的分片。
  2. 即使上述计算显示的是最坏情况的场景,它的确显示出了事实上报文压缩几乎是不可避免的。我们希望多数(如果不是全部) IEEE 802.15.4 使用 IP 的应用会用到报头压缩,这在它 10 章定义。

5 LoWPAN 适配层和帧格式

  本章所说的封装格式(在后面也叫做“LoWPAN 封装”)是 IEEE 802.15.4 协议数据单元(PDU)的负载。这个封装头的后面是 LoWPAN 的负载(比如 IPv6 报文)。

  所有通过 IEEE 802.15.4 传输的 LoWPAN 封装报文的前缀都来自于封装头部栈。封装头部栈中的每个头部都由头部类型和紧跟在头部类型后的零个或多个头部字段组成。对于 IPv6 的报文头部,其栈依次包含地址、逐跳选项、路由、分片、目的选项和负载 [RFC2460];对于 LoWPAN 的报文头部,类似的序列是 mesh (L2)地址、逐跳选项(包括 L2 广播/多播)、分配和负载。以下的例子展示了在 LoWPAN 网络中可能用到的典型的报头栈结构。

  一个 LoWPAN 封装的 IPv6 报文:

  1. +---------------+-------------+---------+
  2. | IPv6 Dispatch | IPv6 Header | Payload |
  3. +---------------+-------------+---------+

  一个 LoWPAN 封装的 LOWPAN_HC1 压缩 IPv6 报文

  1. +--------------+------------+---------+
  2. | HC1 Dispatch | HC1 Header | Payload |
  3. +--------------+------------+---------+

  一个 LoWPAN 封装的采用 LOWPAN_HC1 压缩的、需要 mesh 寻址的 IPv6 报文:

  1. +-----------+-------------+--------------+------------+---------+
  2. | Mesh Type | Mesh Header | HC1 Dispatch | HC1 Header | Payload |
  3. +-----------+-------------+--------------+------------+---------+

  一个 LoWPAN 封装的采用 LOWPAN_HC1 压缩的、需要分片的 IPv6 报文:

  1. +-----------+-------------+--------------+------------+---------+
  2. | Frag Type | Frag Header | HC1 Dispatch | HC1 Header | Payload |
  3. +-----------+-------------+--------------+------------+---------+

  一个 LoWPAN 封装的采用 LOWPAN_HC1 压缩的、需要 mesh 寻址的、需要分片的 IPv6 报文:

  1. +-------+-------+-------+-------+---------+---------+---------+
  2. | M Typ | M Hdr | F Typ | F Hdr | HC1 Dsp | HC1 Hdr | Payload |
  3. +-------+-------+-------+-------+---------+---------+---------+

  一个 LoWPAN 封装的采用 LOWPAN_HC1 压缩的、需要 mesh 寻址的、需要广播头以支持 mesh 广播/多播的 IPv6 报文:

  1. +-------+-------+-------+-------+---------+---------+---------+
  2. | M Typ | M Hdr | B Dsp | B Hdr | HC1 Dsp | HC1 Hdr | Payload |
  3. +-------+-------+-------+-------+---------+---------+---------+

  当一个报文里出现多个报头时它们必须以以下的顺序出现:

  • mesh 寻址头
  • 广播头
  • 分片头

  如上面所给出的例子中那样,所以的协议头(比如 IPv6、压缩的 IPv6 头等)都应该在一个有效的 LoWPAN 封装报头后面。这可以统一软件对报文的处理而不管传输方式是什么。

  LoWPAN 报头的定义,除了 mesh 寻址和分片外,还包括分派值、分派值之后的头部字段以及与其它报头相关的顺序限制。尽管封装头部栈结构提供了对 LoWPAN 适配层进行修改的需求,但是它不打算提供通用目标的可扩展性。为了体现清晰性、简洁性和正交性,本文档使用报头栈指定了一系列头部的集合。

5.1 分派类型和报头

分派类型定义为第 1 位为 0 第 2 位为 1。分派类型和报头如下图所示:

  1. 1 2 3
  2. 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
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. |0 1| Dispatch | type-specific header
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • 分派(Dispatch) - 一个 6 位选择器。确定报头类型,后面是分派报头。
  • 类型相关的头(type-specific header) - 一个由分派报头确定的报头
    图 1. 分派类型和头部

分派值可以看作一个非正式的命名空间,我们只需要少量的符号就可以表示当前 LoWPAN 的功能。尽管将附件功能编码到分派类型中可以节省空间,但这种方法可能对未来扩展功能有所限制。

  1. Pattern Header Type
  2. +-----------+------------------------------------------------+
  3. | 00 xxxxxx | NALP - Not a LoWPAN frame |
  4. | 01 000001 | IPv6 - Uncompressed IPv6 Addresses |
  5. | 01 000010 | LOWPAN_HC1 - LOWPAN_HC1 compressed IPv6 |
  6. | 01 000011 | reserved - Reserved for future use |
  7. | ... | reserved - Reserved for future use |
  8. | 01 001111 | reserved - Reserved for future use |
  9. | 01 010000 | LOWPAN_BC0 - LOWPAN_BC0 broadcast |
  10. | 01 010001 | reserved - Reserved for future use |
  11. | ... | reserved - Reserved for future use |
  12. | 01 111110 | reserved - Reserved for future use |
  13. | 01 111111 | ESC - Additional Dispatch byte follows |
  14. | 10 xxxxxx | MESH - Mesh Header |
  15. | 11 000xxx | FRAG1 - Fragmentation Header (first) |
  16. | 11 001000 | reserved - Reserved for future use |
  17. | ... | reserved - Reserved for future use |
  18. | 11 011111 | reserved - Reserved for future use |
  19. | 11 100xxx | FRAGN - Fragmentation Header (subsequent) |
  20. | 11 101000 | reserved - Reserved for future use |
  21. | ... | reserved - Reserved for future use |
  22. | 11 111111 | reserved - Reserved for future use |
  23. +------------+-----------------------------------------------+
  24. 2. 分派值位模式
  • NALP:指明接下来的比特位不是 LoWPAN 封装的一部分,所有的 LoWPAN 节点应该丢弃收到的分派值为 00xxxxxx 的报文。其它想要与 LoWPAN 节点兼容的非 LoWPAN 协议应该使 802.15.4 头部后面的第一个字节与这种模式相匹配。
  • IPv6:指明接下来的头是无压缩的 IPv6 报头 [RFC2460]。
  • LOWPAN_HC1:指明接下来的报头是一个 LOWPAN_HC1 压缩的 IPv6 报头。这个报头格式定义如图 9 所示。
  • LOWPAN_BC0: 指明接下来的报头是一个 LOWPAN_BC0 报头,它支持 mesh 广播/多播,在 11.1 节进行描述。
  • ESC:指明接下来的报头是一个用于分派值的单独的 8 位字段。它允许支持分派值大于 127。

5.2 Mesh 寻址类型和报头

  前两位为10表示 Mesh 类型。 Mesh 类型和报头如下图所示:

  1. 1 2 3
  2. 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
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. |1 0|V|F|HopsLft| originator address, final address
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. 3. Mesh 编址类型和头部

  各字段定义如下:

  • V:如果源地址(最初始节点的地址)是一个 IEEE 扩展 64 位地址( EUI-64),这位就是 0;如果是16 位短地址,这位就为 1。
  • F:如果最终目标地址是一个 IEEE 扩展 64 位地址( EUI-64),这位就是 0;如果是 16 位短地址,这位就为 1。
  • 剩余跳数(Hops Left):该字段占 4 位。转发节点将报文转发给下一跳之前将该字段减 1。如果值减至 0,报文将不会被转发。值 0xF 是保留的,表示接下来的一个字节是一个 8 位剩余跳数字段,这允许源节点指定一个大于 14 的跳数限制。
  • 原始地址(Originator Address):原始节点的链路层地址。
  • 最终目的地址(Final Destination Address):最终目的节点的链路层地址。

  注意到‘ V’和‘ F’位允许 16 位和 64 位地址的混合。这至少对于允许 mesh 层“广播”是有用的,因为 802.15.4 广播地址定义的是 16 位短地址。

  关于在 mesh 网络中传输帧的内容将会在第 11 节进行具体的讨论。   

5.3 分片类型和报头

  如果一个完整的负载(如 IPv6)数据报装在一个单独的 802.15.4 帧里,它就是不分片的,那么 LoWPAN 封装就不必包含一个分片报头。如果数据报无法封装在一个单独的 IEEE 802.15.4 帧内,它应该在链路层进行分片。因为碎片偏移量只能表示为 8 字节的倍数,所以除了最后一片外的所有分片大小都必须为 8 字节的整数倍。。第一个链路分片应该包含第一个分片报头,其定义如下图所示:

  1. 1 2 3
  2. 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
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. |1 1 0 0 0| datagram_size | datagram_tag |
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. 4. 第一个分片

  第二个和以后的链路分片(直到包含最后一个)应该包含的分片报头,如下图所示:

  1. 1 2 3
  2. 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
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. |1 1 1 0 0| datagram_size | datagram_tag |
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. |datagram_offset|
  7. +-+-+-+-+-+-+-+-+
  8. 5. 后续的分片
  • 数据报大小(datagram_size):该字段占 11 字节,表示在链路分片之前(但在 IP 层分片之后)的整个 IP 报文的大小。对于一个 IP 报文来说,所有分片的 datagram_size 的值都应该是相同的。对于 IPv6,这个值应该是比报文里 IPv6 报头[RFC2460]的负载长度多 40 字节(无压缩的 IPv6 报头的长度)。注意,这个报文可能已经由参与通信的主机进行分片了,也就是说,这个字段需要设置最大长度是 1280 字节( IEEE 802.15.4 链路 MTU,如在本文所定义的那样)。

  注意:不是每个报文都需要这个字段。如第一个分片里含有这个字段,后面分片就可以省略该字段。然而,如果每个链路分片都包含这个字段,能简化当第二个分片(或更后面的分片)比第一个分片早达到时进行重组的过程。在这种情况下,接收端在收到任一个分片后就可以知道 datagram_size 的值,可以更早地知道需要设置多大的缓存空间。

  • 数据报标签:一个负载(比如 IPv6)数据报的所有链路分片的数据报标签的值是相同的。发送者应该对连续的分片数据报递增 datagram_tag 的值。当 datagram_tag 的值递增到大于 65535 时应该变为 0。这个字段占 16 位,它的初始值没有定义。

  • 数据报偏移(datagram_offset):这个字段只出现在第二个和之后的链路分片里,表示从负载数据报开始的以 8 字节为增量的分片偏移量。 数据报的第一个字节(例如 IPv6 报头的开始)的偏移量是 0;第一个链路分片的 datagram_offset 隐含值是 0。这个字段占 8 位。

  链路分片的接收者应该使用(1)发送者的 802.15.4 源地址(或 Originator Address 如果出现了 Mesh Addressing 字段),(2)目标的 802.15.4 地址(或 Final Destination Address 如果出现了Mesh Addressing 字段),(3)datagram_size 和(4)datagram_tag 来确定一个给定数据报的所有链路分片。

  在收到一个链路分片后,接收者开始构造大小为 datagram_size 的未分片的原始报文。它使用 datagram_offset 字段来确定每一个分片在原始报文中的位置。例如,它把数据载荷(除了封装报头)放在一个位置由 datagram_offset 确定的载荷数据报重组缓存里。重组缓存的大小应该由 datagram_size 来确定。

  如果收到与另一个分片重叠的链路分片,如上面所确定的,并且与重叠的分片的大小和datagram_offset 都不同,那么已经累积在重组缓存里的分片应该要丢弃。一个新的重组可能从最近接收到的链路分片开始。分片重叠是由封装报头的 datagram_offset 和 802.15.4 物理层协议数据单元( PPDU)报文头部的“帧长”组合来确定的。

  在检测到一个 IEEE 802.15.4 分裂事件时, 分片接收者必须丢弃所有部分重组的载荷数据报所有的链路分片,分片发送者必须丢弃部分发送的载荷(如 IPv6)数据报的未发送的链路分片。类似地,当一个节点接收到第一个给定 datagram_tag 的分片,它开始一个重组定时器。当定时时间到,如果整个报文没有重组完成,现有的分片必须丢弃,并且重组状态必须重设。重组超时的最大时间必须为 60 秒(这也是 IPv6 重组程序的最大超时[RFC2460])。

6 无状态地址自动配置

  本章定义如何获得 IPv6 接口标识符。

  IEEE 802.15.4 接口的接口标识符 [RFC4291] 可能是基于分配给 IEEE 802.15.4 设备的 EUI-64 标识符 [EUI64] 生成的。在这种情况下,先按照“以太网上的 IPv6 ”规范 [RFC2464] 生成一个 EUI-64,然后根据这个 EUI-64 构成一个接口标识符。

  所有的 802.15.4 设备都有一个 IEEE EUI-64 地址,同时也可能有一个 16 位短地址(第 3 章和第 12 章)。在这种情况下,一个“假的 48 位地址”的产生过程如下:

  首先,左 32 位由 16 位 0 和 16 位 PAN ID(可选,如果不知道 PAN ID, 就用 16 位 0)组成。这样产生的 32 位字段如下所示:

  • 16 位 PAN ID : 16 位 0

  然后,将这这生成的 32 位和 16 位短地址串接在一起,就产生了 48 位地址:

  • 如上所示的 32 位 : 16 位短地址

  由这 48 位则构成了类似于“以太网上的 IPv6”规范 [RFC2464] 中规定的接口标识符。不过,这样形成的接口标识符并不是全球唯一的,所以要将“全局/本地”(U/L)位置为 0。

  也可以使用由人工或者软件设置的 MAC 地址来构成接口标识符。在这种情形下,它的全局唯一性应该反映到“全局/本地”(U/L)位上。

  IEEE 802.15.4 接口上用于无状态自动配置[RFC4862]的 IPv6 地址前缀长度必须是 64 位。

7 IPv6 链路本地地址

  前缀 FE80::/64 与 IEEE 802.15.4 接口标识符共同构成 IPv6 链路本地地址[RFC4291],如下所示:

  1. 10 bits 54 bits 64 bits
  2. +----------+-----------------------+----------------------------+
  3. |1111111010| (zeros) | Interface Identifier |
  4. +----------+-----------------------+----------------------------+
  5. 6

8 单播地址映射

  除非特别说明,用于将 IPv6 非多播地址映射到 IEEE 802.15.4 链路层地址的地址解析程序(ARP)遵循 [RFC4861] 7.2 节的通用描述。

  当链路层是 IEEE 802.15.4,地址是 EUI-64 或 16 位短地址时,源/目标链路层地址选项分别有以下的形式:

  1. 0 1
  2. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. | Type | Length=2 |
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. | |
  7. +- IEEE 802.15.4 -+
  8. | EUI-64 |
  9. +- -+
  10. | |
  11. +- Address -+
  12. | |
  13. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  14. | |
  15. +- Padding -+
  16. | |
  17. +- (all zeros) -+
  18. | |
  19. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  20. 0 1
  21. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  22. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  23. | Type | Length=1 |
  24. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  25. | 16-bit short Address |
  26. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  27. | |
  28. +- Padding -+
  29. | (all zeros) |
  30. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  31. 7

  可选字段:

  • 类型(Type):

  1:源链路层地址。

  2:目的链路层地址。

  • 长度(Length):这是这个选项(包含 type 和 length 字段)的长度,单位是字节。如果使用 EUI-64 地址,这个字段的值为 2,如果使用 16 位短地址,这个字段的值为 1。
  • IEEE 802.15.4 地址:64 位的 IEEE 802.15.4 地址,或 16 位短地址(如第 9 章所描述的格式),使用正则位顺序。这是接口当年可响应的地址。缘于隐私或安全(如邻居发现)的考虑,这个地址可能与用于产生接口标识符的内建的地址不同。

9 多播地址映射

  这一节里的功能必须在一个 mesh 使能的 LoWPAN 里使用。一个有多播目标地址(DST)的 IPv6 报文,,将会传输到以下 802.15.4 的 16 位多播地址:

  1. 0 1
  2. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. |1 0 0|DST[15]* | DST[16] |
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. 8

  这里, DST[15]*表示 DST[15]的后 5 位,那就是, DST[15]里的 3-7 位。开始的 3 位序列“100”紧跟在 16 位短地址格式后面用于多播地址(节 12)。

  这允许在 6LoWPAN 网络中支持多播,但具体的多播方式不在本文的描述范围内。机制示例是:泛洪、受控泛洪、单播到 PAN 协调器等。这应该由不同的 mesh 路由机制来描述。   

10 报头压缩

  尽管存在很多已被发行和正在制定的头部压缩标准,但是我们可以将对运行在 IEEE 802.15.4 之上的 IPv6 进行头部压缩时面临的各种限制总结如下:

  • 现有标准都假设在任何两个设备之间存在很多流量。我们假设存在一个简单的、与上下文不太相关的报头压缩。这种压缩与流量无关,不使用与任何流量相关的任何上下文。当然,其压缩效果没有为每个流量构建独立上下文的效果好。
  • 由于报文尺寸极其有限,所以非常有必要对第 2 层和第 3 层进行压缩。这是传统压缩没有做的事(尽管现在有了 ROHC( RObust 报头压缩)工作组而正在改变)。
  • 尽管 IEEE 802.15.4 设备应该部署在多跳网络中,但是在传统的点对点链路场景下,压缩者和解压缩者是直接与对方通信并独占链路的。在 IEEE 802.15.4 网络中,设备最好能(使用尽量少的初始化工作)通过它的任何邻居发送头部压缩过的报文。

  通过使用不同的分派值,报头压缩所需要的任何新报文格式都可以重用第 5 章中所定义的基本报文格式。

  报头压缩可能导致不能字节边界对齐。由于硬件通常不能传输小于一个字节的数据单元,所以必须使用填充位。填充的步骤:首先,将所有连续的压缩报头按位排序(本文只定义了 IPv6 和 UDP 报头压缩机制,但其它的可能在别处定义)。然后,用若干位 0 进行填以与字节边界对齐。这消除了所有由报头压缩产生的不对齐,所以后续字段(例如非压缩报头、数据载荷)就从正常的字节边界开始了。

10.1 IPv6 报头字段压缩

  由于加入到同一个 6LoWPAN 网络,所以设备间可以共享一些状态。这使得在压缩报头时可以不用明确创建任何内容状态。因此,6LoWPAN 报头压缩并不保留任何流量状态,反而依赖于与整个链路相关的信息。以下的 IPv6 报头值对于 6LoWPAN 网络是通用的,所以 HC1 报头从一开始用于高效压缩:

  • 版本是 IPv6;
  • IPv6 源和目标地址都是链路本地地址;
  • 源地址和目标地址的 IPv6 接口标识符(后 64 位)可以从第二层的源和目标地址(当然,这是只能由一个 802.15.4 MAC 地址来产生接口标识符)推断出;
  • 报文长度可以从第二层( IEEE 802.15.4 PPDU 里的“帧长”)或分片报头(如果有)的“ datagram_size”字段来获得;
  • 业务类型字段和流量标签字段都是 0;
  • 下一个报头是 UDP, ICMP 或 TCP;

  IPv6 头部字段中唯一一个不需要压缩的字段是跳数限制字段(8 位)。依赖于报文与这种通用情形的匹配程序,一些字段可能不需要压缩而直接内嵌传输(第 10.3.1 节)。通用 IPv6 头部(如上面提到的)可以被压缩到 2 字节(1 字节的 HC1 编码和 1 字节的跳数限制),而不是 40 字节。这样的报文可通过 LOWPAN_HC1 格式来进行压缩,即通过使用 LOWPAN_HC1 的分派值以及后面的 LOWPAN_HC1 报头里“ HC1 编码”字段(8 位)来编码不同的组合,如下图所示。这个报头前面可能是一个分片报头,再前面可能是一个 mesh 报头。

  1. 1 2 3
  2. 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
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. | HC1 encoding | Non-Compressed fields follow...
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. 9: LOWPAN_HC1 (通用压缩报头编码)

  如下面所示(比特 7),一个 HC2 编码后面可能是一个 HC1 字节。在这种情况下, HC2 编码字段后面是一个非压缩字段(节 10.3)。

  由“ HC1 编码”产生的地址字段解释如下所示:

  • PI:内嵌的前缀(第 10.3.1 节)。
  • PC:压缩的前缀( 假定是链路本地前缀)。
  • II:内嵌的接口标识符(第 10.3.1 节)。
  • IC:省略的接口标识符(从相应的链路层地址获得的)。如果在一个 mesh 路由中使用源或目标地址的接口标识符(第 11 章),相应的链路层地址是“Mesh Addressing”字段里的地址(第 5.2 节)。

  “HC1 编码”如下所示(比特 0 到比特 7):

  • IPv6 源地址(比特 0 和 1):
    • 00: PI, II
    • 01: PI, IC
    • 10: PC, II
    • 11: PC, IC
  • IPv6 目标地址(比特 2 和 3):
    • 00: PI, II
    • 01: PI, IC
    • 10: PC, II
    • 11: PC, IC
  • 交通等级和流量标签(比特 4):
    • 0:非压缩的;全 8 位的交通等级和 20 位的流量标签都会发送
    • 1:交通等级和流量标签都为 0
  • 下一报头(比特 5 和 6):
    • 00:非压缩的;全 8 位都会发送
    • 01: UDP
    • 10: ICMP
    • 11: TCP
  • HC2 编码(比特 7):
    • 0:没有更多的报头压缩位
    • 1: HC1 编码后面有更多 HC2 编码格式的报头压缩位。位 5 和 6 确定了 HC2 编码的用途(例如,UDP,ICMP 或 TCP 编码)。

10.2 UDP 报头字段编码

  LOWPAN_CH1 的比特 5 和比特 6 允许对 IPv6 头部(UDP,TCP 和 ICMP)中的下一个头部字段进行压缩。对这些协议的头部进行进一步压缩也是可能的,但是在本节主要解释 UDP 头部本身是如何进行压缩的。在本节中,LOWPAN_CH2 编码就是 HC_UDP 编码,且只在 HC1 中的比特 5 和比特 6 表示 IPv6 头部后的协议是 UDP 时才有效。HC_UDP 编码(图 10)允许压缩 UDP 头部中的如下字段:源端口、目的端口和长度。UDP 头部的检验和字段不能被压缩,因此它必须被完全传输。下面定义的机制可以让 UDP 的头部由原始的 8 字节压缩到 4 字节。

  在 UDP 头部中,唯一一个能出其它地方推断出的字段是长度字段。其它的字段必须被完全嵌入或者部分压缩的方式嵌入。

  1. 1 2 3
  2. 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
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. |HC_UDP encoding| Fields carried in-line follow...
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. 10: HC_UDP (UDP 通用头部压缩编码)

  UDP 的“HC_UDP”编码如下所示(从比特 0 到比特 7):

  • UDP 源端口(比特 0):
    • 0: 非压缩的,“内嵌”运载(第 10.3.2 节)。
    • 1: 压缩到 4 位。实际的 16 位源端口通过计算得到:P + short_port。P 的值是 61616( 0xF0B0)。 short_port 是一个“内嵌传输的 4 位值(第 10.3.2 节)。
  • UDP 目标端口(比特 1):
    • 0: 非压缩的,“内嵌”运载(第 10.3.2 节)。
    • 1: 压缩到 4 位。实际的 16 位目的端口通过计算得到:P + short_port。P 的值是 61616( 0xF0B0)。 short_port 是一个“内嵌传输的 4 位值(第 10.3.2 节)。
  • 长度(比特 2):
    • 0: 非压缩的,“内嵌”运载(第 10.3.2 节).
    • 1: 压缩的,长度从 IPv6 报头长度信息来计算而来。UDP 长度字段的值等于 IPv6 报头的载荷长度减去出现在 IPv6 报头和 UDP 报头之间的任何扩展报头的长度。
  • 保留(比特 3 到 7)

10.3 非压缩字段

10.3.1 非压缩的 IPv6 字段

本方法允许把 IPv6 报头进行不同程度的压缩。在压缩后,只需要传输非压缩字段,而不是完整的(标准的)IPv6 头部。随后的头部(原始 IPv6 报文中由“下一个头部”所指定)紧跟在 IPv6 非压缩字段后面。

IPv6 头部中的的非压缩部分由一个分派类型描述,该分派类型包括一个 IPv6 分派值。分派之之后是非压缩的头部。这个分派类型前面可能有附加的 LoWPAN 报头。

非压缩的 IPv6 字段里总是包括“跳数限制(8 比特)”。“跳数限制”必须出现在编码字段(比如图 9 中的“HC1 编码”)之后。其它非编码字段必须跟在“跳数限制”字段后面,这与前面(第 10.1 节)所说的“HC1 编码”的顺序一样:源地址前缀(64 比特)和/或接口标识符(64 比特),目的地址前缀(64 比特)和/或接口标识符(64 比特),通信类别(8 比特),流量标签(10 比特)和下一个头部(8 比特)。实际的下一个头部(例如 UDB,TCP,ICMP 等)跟在这些非压缩字段最后。

10.3.2 非压缩的和部分压缩的 UDP 字段

本方法允许把 UDP 报头进行不同程度的压缩。在压缩后,只需要传输非压缩或部分压缩的字段,而不是完整的(标准的)UDP 头部。

UDP 头部中的非压缩或部分压缩字段必须跟在 IPv6 头部和它所相关的内嵌字段之后。UDP 头部的内嵌字段出现的顺序必须与正常的 UDP 头部字段 [RFC0768] 的顺序一致:源端口号,目的端口号,长度,校验和。如果源或目的端口号是“short_port”的格式(如压缩 UDP 报头里指定的),那么这个内嵌的端口号只占 4 比特,而不是原来 16 比特。

11 链路层 Mesh 的帧传送

11.1 LoWPAN 广播

12 IANA 考虑

13 安全考虑

14 致谢

15 参考文献

15.1. Normative References

  • [RFC2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.
  • [RFC2434] Narten, T. and H. Alvestrand, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 2434, October 1998.
  • [RFC2460] Deering, S. and R. Hinden, “Internet Protocol, Version 6 (IPv6) Specification”, RFC 2460, December 1998.
  • [RFC2464] Crawford, M., “Transmission of IPv6 Packets over Ethernet Networks”, RFC 2464, December 1998.
  • [RFC4291] Hinden, R. and S. Deering, “IP Version 6 Addressing Architecture”, RFC 4291, February 2006.
  • [RFC4861] Narten, T., Nordmark, E., Simpson, W., and H. Soliman, “Neighbor Discovery for IP version 6 (IPv6)”, RFC 4861, September 2007.
  • [RFC4862] Thomson, S., Narten, T., and T. Jinmei, “IPv6 Stateless Address Autoconfiguration”, RFC 4862, September 2007.
  • [ieee802.15.4] IEEE Computer Society, “IEEE Std. 802.15.4-2003”, October 2003.

    15.2. Informative References

  • [EUI64] “GUIDELINES FOR 64-BIT GLOBAL IDENTIFIER (EUI-64) REGISTRATION AUTHORITY”, IEEE http://standards.ieee.org/regauth/oui/tutorials/EUI64.html.
  • [KW03] Karlof, Chris and Wagner, David, “Secure Routing in Sensor Networks: Attacks and Countermeasures”, Elsevier’s AdHoc Networks Journal, Special Issue on Sensor Network Applications and Protocols vol 1, issues 2-3, September 2003.
  • [RFC0768] Postel, J., “User Datagram Protocol”, STD 6, RFC 768, August 1980.
  • [RFC3756] Nikander, P., Kempf, J., and E. Nordmark, “IPv6 Neighbor Discovery (ND) Trust Models and Threats”, RFC 3756, May 2004.
  • [RFC3819] Karn, P., Bormann, C., Fairhurst, G., Grossman, D., Ludwig, R., Mahdavi, J., Montenegro, G., Touch, J., and L. Wood, “Advice for Internet Subnetwork Designers”, BCP 89, RFC 3819, July 2004.