首页 文章

如何区分扩展和上层头

提问于
浏览
2

我正在尝试解析通过原始套接字接收的IPv6数据包,并确定它是否是ICMPv6 . 我可以处理以太网和IPv6标头,但是有可选的扩展标头 . 如果IPv6标头的 Next Header 字段不是ICMPv6,我必须遍历可能在之前的任何扩展 .

迭代本身不是问题,因为每个扩展头都有其长度 . 但是,我找不到区分可能遵循的扩展标头和其他高级协议(如TCP和UDP)的好方法 . 我可以检查 Next Header 是否是已知的扩展标头之一(在这种情况下我可以迭代)或者如果 Next Header 是上层协议(在这种情况下我必须停止,将不会有任何ICMP ..) .

在这两种方法中,我都会检查 Next Header ,该列表将来可能会发生变化 . 是否't there a better way to tell when I' m在扩展 Headers 的末尾和上层 Headers (或什么都没有)?

2 回答

  • 3

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


    Update:

    关于你修改过的问题,不,没有标准的功能或算法来区分指定扩展 Headers 的 Headers 代码和那些指定协议 Headers 的 Headers ,除了简单地知道哪些是哪个 . 它们是从相同的代码空间分配的,没有特殊的内部结构 .

    但是,只有256个可能的值,因此知道哪个是可行的 . 但请注意:近一半的可用代码当前未分配,但将来可能会分配给扩展头类型或协议类型 . 除非代码用尽,否则您的软件需要识别 three 类别:

    • 扩展头,

    • 协议 Headers ,和

    • 未知 .

    另外,至于实现这样的测试,我建议创建和使用查找表,而不是构建复杂的条件表达式 . 这些方面的东西:

    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
    };
    

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

  • 2

    除了走链子之外别无其他事情,听起来就像你正在做的那样 . 正如您在评论中提到的那样,“查明下一个 Headers 是否也将是扩展名的标准方法”是它是否是其中一个值,这意味着它是IPv6扩展 Headers . 最初,除了逐跳扩展头(大多数网络管理员忽略,因为让终端设备指示路由是一种不好的做法),所有中间节点(路由器等)都应该ignore extension headers

    除了一个例外,任何节点都不会沿数据包的传递路径检查或处理扩展头,直到数据包到达在目标地址字段中标识的节点(或多播节点中的每个节点) . IPv6标头 . 在那里,IPv6报头的Next Header字段上的正常解复用调用模块来处理第一个扩展头,如果没有扩展头,则调用上层头 . 每个扩展标头的内容和语义决定是否继续下一个标头 . 因此,必须严格按照它们在数据包中出现的顺序处理扩展标头;例如,接收方不得扫描寻找特定类型扩展标头的数据包,并在处理所有前面的标头之前处理该标头 . 前一段中提到的例外是逐跳选项头,它包含必须由数据包的传递路径上的每个节点检查和处理的信息,包括源节点和目标节点 . Hop-by-Hop Options标头(如果存在)必须紧跟IPv6标头 . 其存在由IPv6报头的Next Header字段中的值零指示 . 如果作为处理标头的结果,则需要节点继续下一个标头而不是下一个标头值当前标头中的节点无法识别,它应该丢弃该数据包并向数据包源发送ICMP参数问题消息,ICMP代码值为1(遇到“无法识别的下一个 Headers 类型”)和ICMP指针字段包含原始数据包中无法识别的值的偏移量 . 如果节点在除IPv6标头之外的任何标头中遇到Next Header值为零,则应采取相同的操作 .

    不幸的是,现实开始了,而现在已不再如此 . 现在甚至可能中间节点将添加扩展标头,并且标头链可能最终碎片化 .

    RFC 6564, A Uniform Format for IPv6 Extension Headers尝试为IPv6扩展标头带来一些订单,但遗憾的是,它无法对先前定义的IPv6扩展标头执行任何操作 .

    RFC 7045, Transmission and Processing of IPv6 Extension Headers讨论了有关IPv6扩展标头的问题 .

相关问题