IPv6和ESP作为下一个标题

我想知道如何parsingIPv6头,并获得TCP头和它的有效载荷的偏移量。

我知道IPv6有固定的基地头。 我也知道在IPv6中有几个扩展头 – 其中包括:路由,片段,目标选项,ESP等等。

我得到的是指向缓冲区的以太网帧。 现在我可以findIPv6头部的开头,但是在有ESP头部的情况下,不能计算TCP头部的开始和它的有效载荷。 有一些描述ESP的rfc2406,但对我来说还不清楚。 我不能计算ESP头和它的数据的大小,所以我找不到TCP的偏移量。

我的问题是:如何在IPv6的情况下计算ESP扩展头的长度?

通常,每个扩展头以两个字节开始,指示下一个头的types和当前头的长度。

一般来说,你不能假设这是真的。 这取决于您正在parsing的扩展头的types,该types由前一个头中的下一个头字段指示。

与其他IPv6扩展标头相比,IPSec中的长度字段略有不同。

对于一个正常的IPv6扩展头,你可以从字节值到头的长度,首先加1,然后乘以8。

对于从字节值到报头长度的IPSec报头,首先加2,然后乘以4。

为什么它是这样devise的

数据包的接收者在处理数据包时需要validation数据包的长度字段。 IPv6要求所有扩展头的长度是8个字节的倍数,这样才能在64位CPU上高效地实现。

扩展头的最小长度为8个字节,尽pipe扩展头没有最大长度,但扩展头宣称延长到embedded的数据包的末尾是无效的。

使这些validation不正确将最有可能导致严重的安全问题。 例如,如果一个接收者盲目地接受一个声称是0字节长的扩展头,这将导致parsing假定下一个扩展头在完全相同的地址开始。 这可能导致一个无限循环,接收者一直在parsing相同的扩展头。 如果接收到这样一个损坏的数据包,这很可能已经触发了操作系统的即时冻结。

但是通过要求接收器加1和乘以8,不再需要两个validation,因为无论在0到255范围内的哪个字节值应用这个计算,它都会产生一个至less为8的结果,是8的倍数。作为额外的好处,它将可能的扩展头大小从255字节增加到2048字节。

接收器仍然必须validation最大长度,这是没有办法的。 任何具有有效扩展头的数据包都可能因为主扩展头中的有效负载长度字段对于扩展头太短而被破坏。

为什么IPSec是不同的

IPSec用于IPv4和IPv6。 但是IPv4通常只需要4字节alignment(针对32位CPU进行优化),其中IPv6需要8字节alignment(针对64位CPU进行了优化)。 出于这个原因,乘数在这种情况下只有4。 头的最小长度仍然是8个字节。

这意味着,当通过IPv6使用IPSec时,接收方必须validation长度字段是偶数字节值。 然而,假设CPU架构能够访问未alignment的值(以降低的性能),那么开发人员忘记这个特定validation的风险是微不足道的。 在最坏的情况下,损坏的数据包将需要几个CPU周期来处理。

使用这个来find有效载荷头

以下伪代码显示了如何处理标题。

Initialize a pointer to the first byte of the IPv6 header. Initialize the header type to 41. While the header type is a known IP or extension header: Compute current header length Process current header if applicable Copy next header field from current header Move pointer forward by current header length 

在这种algorithm中,报头types4和41是特别的,它们表示IPv4报头和IPv6报头。