我正在尝试解析通过原始套接字接收的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 回答
每个扩展头都有自己的
Next Header
字段作为其第一个八位字节,其含义与固定IPv6头的相应字段具有相同的含义(但不同的相对位置) . 您可以将这些与扩展标头的长度字段一起使用,以逐步执行扩展标头,直到找到传输层标头 . 维基百科covers this有些细节 .Update:
关于你修改过的问题,不,没有标准的功能或算法来区分指定扩展 Headers 的 Headers 代码和那些指定协议 Headers 的 Headers ,除了简单地知道哪些是哪个 . 它们是从相同的代码空间分配的,没有特殊的内部结构 .
但是,只有256个可能的值,因此知道哪个是可行的 . 但请注意:近一半的可用代码当前未分配,但将来可能会分配给扩展头类型或协议类型 . 除非代码用尽,否则您的软件需要识别 three 类别:
扩展头,
协议 Headers ,和
未知 .
另外,至于实现这样的测试,我建议创建和使用查找表,而不是构建复杂的条件表达式 . 这些方面的东西:
您可以使用它来回答几种问题,也非常有效 . 初始化器中的显式指示符并不是绝对必要的,但我认为它们是个好主意:它们将帮助您验证和维护表 .
除了走链子之外别无其他事情,听起来就像你正在做的那样 . 正如您在评论中提到的那样,“查明下一个 Headers 是否也将是扩展名的标准方法”是它是否是其中一个值,这意味着它是IPv6扩展 Headers . 最初,除了逐跳扩展头(大多数网络管理员忽略,因为让终端设备指示路由是一种不好的做法),所有中间节点(路由器等)都应该ignore extension headers:
不幸的是,现实开始了,而现在已不再如此 . 现在甚至可能中间节点将添加扩展标头,并且标头链可能最终碎片化 .
RFC 6564, A Uniform Format for IPv6 Extension Headers尝试为IPv6扩展标头带来一些订单,但遗憾的是,它无法对先前定义的IPv6扩展标头执行任何操作 .
RFC 7045, Transmission and Processing of IPv6 Extension Headers讨论了有关IPv6扩展标头的问题 .