解析包含未知扩展的IPv6扩展头

114

我正在编写一个非常简单的网络过滤器,需要解析IPv6头以匹配ICMPv6类型、TCP/UDP端口号等信息。

于是我深入研究了IPv6数据包格式,但我发现困难重重……我不得不反复阅读,以确保我正确理解它。 我的理解是,你必须从40字节的固定头开始,并查看其下一标头字段。然后你还要查看下一个标头中的下一个标头字段,以此类推,就像一个链接列表,直到到达结尾。如果有有效负载,则会跟随其后。

问题在于,固定头和扩展标头中都没有长度字段。所以,您必须拥有一个扩展标头类型及其大小的表格,以便您可以追踪此链接列表到最后。

这使我感到奇怪,甚至可能是一个毫无逻辑的设计。如果我遇到一个无法识别的扩展标头类型,该怎么办?我不知道它的长度。我想我必须将数据包丢弃并阻止它通过,因为在网络过滤器中允许该数据包通过将允许攻击者通过包含虚假的标头类型来规避网络过滤器。但这意味着,如果该协议被扩展,那么所有已编写的每个IPv6头解析软件必须同时更新,以使用新的扩展。

那么,如果我不知道正在使用哪些扩展,如何解析IPv6标头?如果我不知道长度,如何跳过未知扩展的标头?


10
根据这个问题,看起来我并不傻,而且我理解得没错:在现实世界中,向IPv6添加新的扩展头是不可能的。 - AdamIerymenko
10
是的,看起来计算头部长度需要进行链表遍历:http://stackoverflow.com/questions/14762193/get-exact-size-of-ipv6-header-including-the-extenstion-headers?rq=1别误会,IPv6很棒也非常必要。但这个计算仍然显得有些愚蠢。 - AdamIerymenko
3
规范文件(在上面的评论中提供链接)指出路由器不应查看报头信息,因此不应关注您添加了哪些报头。只有目标节点应查看这些报头。 - Anders E. Andersen
3
注意:单词 "hair-brained" 拼写相当令人困惑,应该使用 "hare-brained" 更为合适(来源:tfd)。 - pzkpfw
3
只要有一个正确的拼写,那就是“hare-brained”。 - Alan B
显示剩余2条评论
4个回答

97
如果我遇到一个无法识别的扩展头类型怎么办?
来自RFC 2460
如果由于处理标头而要求节点继续到下一个标头,但当前标头中的Next Header值未被节点识别,则应丢弃数据包并向数据包源发送ICMP参数问题消息,其中ICMP代码值为1(“遇到无法识别的Next Header类型”),ICMP指针字段包含原始数据包中无法识别的值的偏移量。如果节点在除IPv6标头以外的任何标头中遇到Next Header值为零,则应采取相同的操作。

15
好的。我以为我要疯了。所以是的,它确实是一个完全不可扩展的设计......至少没有带内信令和其他技巧。在应用层协议中,这种情况可以原谅,因为您控制两端并且只需要考虑您的应用程序的新版本,但是对于旨在持续数百年的东西来说就不行了。 - AdamIerymenko
8
有能力忽略未知报头会导致更加复杂的问题。(如果中间代理修改了TCP报头,而不知道封装的ESP报头呢?)在这种情况下,简单胜过“可扩展性”! - jman
4
IPv6几乎有足够的地址,可以为地球上每一个原子分配一个地址。没有任何数量的连接到互联网的烤面包机会耗尽这个地址空间。 - Tyler McHenry
8
@Max 我不会说我们绝对不需要IPv7,但是有了IPv6,我们已经有足够的地址空间,可以给地球大气层内每一个立方毫米(距离地面130,000公里)分配一个独特的地址……超过10万倍。所以我的意思是,一旦我们开始殖民其他星系,我们可能需要担心一些问题,但在那之前,我们应该很好。 - cincodenada
4
除了一个例外,IPv6扩展头在整个数据包传输路径上都不会被任何节点检查或处理,直到该数据包到达IPv6头中目的地址字段所标识的节点(或多播情况下的一组节点)为止。 - Tobu
显示剩余8条评论

34
如果你遇到无法解析的内容,就要根据已经解析的内容做出决策或执行操作。
这个设计是因为在IPv6中,每个扩展头“包裹”着整个数据包。如果您看到了路由头,然后是您从未听说过的某个头部,再然后是有效载荷,则您无法解析有效载荷。有效载荷的含义原则上取决于您不知道如何解释的头部。
路由器可以路由此类数据包,因为它们只需要路由头部。深度数据包检查设备和其他类似设备需要了解很多信息,但那也是他们的命运。
经过编辑添加:此设计意味着中间盒只能更改其所知道的内容。如果中间盒看到一个它不知道的头部,那么它只有两个选择:拒绝或传递。在IPv4中,它还可以删除未知的扩展头并传递其他内容。我认为这种特性使设计更具可扩展性,而不是相反。

29

在现实世界中,向IPv6添加新的扩展头是不可能的。

不正确,因为:

  1. 只有目标主机可以基于未识别的扩展头拒绝请求(除了你所链接的问题中提到的一个例外情况

  2. 如果你的新扩展头是可选的(最好是这样),你将会收到一个关于ICMP错误的通知,并可以在没有该项的情况下再试一次。


1
你确定这个 ICMP 数据包能够穿过 NAT 到达实际的发送者吗? - Dexter
5
@Dexter:ipv6会取代NAT...希望如此。 - Janus Troelsen
2
@Dexter:这些ICMP数据包需要到达出于多种原因。例如,如果管道的MTU缩小了(可能是因为PPPoE或VPN发生了数据包封装),并且要发送的数据包太大,则会返回一个ICMP数据包,说明数据包太大。 - Bill Lynch
4
@JanusTroelsen 并非所有人都与你有同样的希望。 - Dexter

4
更新 RFC 6564涵盖了这种情况。它准确地阐述了您所描述的场景,并提出了任何新扩展标头(如果有的话)的格式,这样像您这样的中间盒就能在至少一些时间内使用。请记住,它的目的不是通过创建新的扩展标头来扩展IPv6,而是通过添加新的目标选项来实现。对于处理未知目标选项,这应该是微不足道的,或者至少更容易些。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接