如何区分扩展和 upper-layer header

How to differentiate between extension and upper-layer header

我正在尝试解析通过原始套接字接收的 IPv6 数据包并确定它是否是 ICMPv6。我可以处理 EthernetIPv6 header,但还有可选的扩展 headers。如果 IPv6 header 的 Next Header 字段不是 ICMPv6,我必须遍历可能在前面的任何扩展。

迭代本身不是问题,因为每个扩展 header 都有其长度。但是,我找不到区分可能遵循的扩展 header 和其他 upper-level 协议(例如 TCPUDP)的好方法。我可以检查 Next Header 是否是已知扩展 headers 之一(在这种情况下我可以迭代)或者 Next Header 是否是 upper-layer 协议(在这种情况下我必须停止,不会有任何 ICMP..)。

在这两种方法中,我都依赖一些 self-built 常量列表来检查 Next Header 并且该列表将来可能会更改。难道没有更好的方法来判断我何时处于扩展 headers 的末尾并且 upper-layer header (或什么都没有)跟随?

每个扩展 header 都有自己的 Next Header 字段作为其第一个八位字节,与固定 IPv6 header 的相应字段具有相同的含义(但相对位置不同) .您可以将这些与扩展 headers 的长度字段一起使用,逐步执行扩展 headers,直到找到传输层 header。维基百科 covers this 比较详细。


更新:

关于您修改后的问题,不,没有标准函数或算法来区分指定扩展 header 的 header 代码和指定协议 header 的代码,除了只是为了知道哪些是哪些。它们是从相同的代码 space 分配的,没有特殊的内部结构。

然而,只有 256 个可能的值,所以知道哪些是可行的。但是请注意:目前将近一半的可用代码尚未分配,但将来可能会分配给扩展 header 类型或协议类型。除非代码用完,否则您的软件将需要识别 三个 类别:

  • 分机 header,
  • 协议header,以及
  • 未知.

此外,对于实现这样的测试,我建议创建和使用查找 table 而不是构建复杂的条件表达式。沿着这些线的东西:

enum header_type { HDR_PROTOCOL, HDR_EXTENSION, HDR_UNKNOWN };

const enum header_type header_types[256] = {
    [0x00] = HDR_EXTENSION,  // IPv6 hop-by-hop option
    [0x01] = HDR_PROTOCOL,   // ICMP
    // ... both extension and protocol headers in this range ...
    [0x8e] = HDR_PROTOCOL,   // robust header compression
    [0x8f] = HDR_UNKNOWN,    // unassigned
    // ... more unassigned ...
    [0xfd] = HDR_UNKNOWN,    // for experimentation
    [0xfe] = HDR_UNKNOWN,    // for experimentation
    [0xff] = HDR_UNKNOWN,    // reserved
};

您可以用它来回答多种问题,而且非常有效。初始化器中的显式指示符并非绝对必要,但我认为它们是个好主意:它们将帮助您验证和维护 table.

除了走链条,真的没有什么可做的,听起来这就是你在做的事情。正如您在评论中所问,“ 确定下一个 header 是否也将是扩展名的标准方法 ” 是否是表示它的值之一是 IPv6 扩展 header。最初,除了 Hop-by-hop 扩展 header(大多数网络管理员忽略它,因为让 end-devices 指示路由是一种糟糕的做法),所有中间节点(路由器等)都被删除。 ) 应该 ignore extension headers:

With one exception, extension headers are not examined or processed by any node along a packet's delivery path, until the packet reaches the node (or each of the set of nodes, in the case of multicast) identified in the Destination Address field of the IPv6 header. There, normal demultiplexing on the Next Header field of the IPv6 header invokes the module to process the first extension header, or the upper-layer header if no extension header is present. The contents and semantics of each extension header determine whether or not to proceed to the next header. Therefore, extension headers must be processed strictly in the order they appear in the packet; a receiver must not, for example, scan through a packet looking for a particular kind of extension header and process that header prior to processing all preceding ones.

The exception referred to in the preceding paragraph is the Hop-by- Hop Options header, which carries information that must be examined and processed by every node along a packet's delivery path, including the source and destination nodes. The Hop-by-Hop Options header, when present, must immediately follow the IPv6 header. Its presence is indicated by the value zero in the Next Header field of the IPv6 header.

If, as a result of processing a header, a node is required to proceed to the next header but the Next Header value in the current header is unrecognized by the node, it should discard the packet and send an ICMP Parameter Problem message to the source of the packet, with an ICMP Code value of 1 ("unrecognized Next Header type encountered") and the ICMP Pointer field containing the offset of the unrecognized value within the original packet. The same action should be taken if a node encounters a Next Header value of zero in any header other than an IPv6 header.

不幸的是,现实已经不是这样了。现在甚至有可能中间节点将添加扩展 headers,并且 header 链最终可能会碎片化。

RFC 6564, A Uniform Format for IPv6 Extension Headers 试图为 IPv6 扩展 headers 带来一些秩序,但不幸的是,它对先前定义的 IPv6 扩展 headers 无能为力。

RFC 7045, Transmission and Processing of IPv6 Extension Headers 讨论有关 IPv6 扩展 headers 的问题。