Linux kernel Linux内核如何找到正确的偏移量来解析IP数据包?

Linux kernel Linux内核如何找到正确的偏移量来解析IP数据包?,linux-kernel,ip,Linux Kernel,Ip,我在中找到了解析IP(v4)数据包的代码。此功能,ip_rcv,可以高度确定地检测数据包是否正确,如其中一条注释所述: 长度至少为ip标头的大小 第4版 校验和正确。[后期速度优化,跳过环回校验和] 没有伪造的长度 格式错误的数据包只会被丢弃。这个函数似乎得到了一堆类似于IP数据包的字节,但是如果某个恶意参与者会在线路上偷偷增加一个字节呢?如果处理不正确,从现在起,ip_rcv接收的所有字节块将从1字节开始,并且不再能够重建正确的ip数据包。我假设内核做的事情比尝试所有不同的字节偏移量来开始解析

我在中找到了解析IP(v4)数据包的代码。此功能,
ip_rcv
,可以高度确定地检测数据包是否正确,如其中一条注释所述:

  • 长度至少为ip标头的大小
  • 第4版
  • 校验和正确。[后期速度优化,跳过环回校验和]
  • 没有伪造的长度

  • 格式错误的数据包只会被丢弃。这个函数似乎得到了一堆类似于IP数据包的字节,但是如果某个恶意参与者会在线路上偷偷增加一个字节呢?如果处理不正确,从现在起,
    ip_rcv
    接收的所有字节块将从1字节开始,并且不再能够重建正确的ip数据包。我假设内核做的事情比尝试所有不同的字节偏移量来开始解析IP数据包更聪明。确切地说,我找不到。有人能解释一下吗?

    我没有花时间看内核代码,但大多数协议栈都是通过在上一个堆栈位置之后立即解析数据而不是搜索数据来工作的

    在以太网的情况下,以太网帧头的大小通常为14字节。它可以不同,但标头本身在必要时指示etherType字段中的不同长度。在此示例中,NIC(网络接口卡)将接收以太网帧。如果帧的目的地是此NIC,则从NIC驱动程序传递到IP堆栈的数据将是一个包含此14字节报头的以太网帧,后面紧跟着IP报头(例如,如果是版本4的IP报头,则第一个半字节将为4)

    同样,我没有查看网络堆栈代码,但这里有两种常见情况:

    1) IP堆栈被告知这是一个以太网帧,只需要解析以太网帧头的长度,下一个字节必须是IP头,否则数据被视为不是IP帧


    2) IP堆栈被赋予一个指针,指向紧跟在以太网帧头之后的数据的开头,然后IP堆栈在该位置开始解析。

    我没有花时间看内核代码,但大多数协议堆栈将通过解析紧跟在前一个堆栈位置之后的数据而不是通过搜索数据

    在以太网的情况下,以太网帧头的大小通常为14字节。它可以不同,但标头本身在必要时指示etherType字段中的不同长度。在此示例中,NIC(网络接口卡)将接收以太网帧。如果帧的目的地是此NIC,则从NIC驱动程序传递到IP堆栈的数据将是一个包含此14字节报头的以太网帧,后面紧跟着IP报头(例如,如果是版本4的IP报头,则第一个半字节将为4)

    同样,我没有查看网络堆栈代码,但这里有两种常见情况:

    1) IP堆栈被告知这是一个以太网帧,只需要解析以太网帧头的长度,下一个字节必须是IP头,否则数据被视为不是IP帧


    2) IP堆栈被赋予一个指向以太网帧头之后数据开头的指针,然后IP堆栈在该位置开始解析。

    谢谢您的回答。在这种情况下,IP堆栈依赖于底层协议。如果使用
    tun
    设备,该怎么办?Tun设备是IP in和IP out,除了两个Tunnelling应用程序之间的协议外,没有其他任何东西可以保护IP数据包的完整性。如果这个隧道是建立在一个不可靠的协议之上的,那么一切希望都破灭了吗?以太网在每个以太网帧上都有一个CRC检查。如果接收到的帧未通过CRC检查,则该帧将被丢弃,并且不会发送到任何底层协议。我认为你可能使用的任何协议都应该做同样的事情。如果没有,那么IP校验和将有望找到坏数据并丢弃它。因此,所有的希望都没有失去,IP将在没有收到预期的数据报时重试。谢谢你的回答。在这种情况下,IP堆栈依赖于底层协议。如果使用
    tun
    设备,该怎么办?Tun设备是IP in和IP out,除了两个Tunnelling应用程序之间的协议外,没有其他任何东西可以保护IP数据包的完整性。如果这个隧道是建立在一个不可靠的协议之上的,那么一切希望都破灭了吗?以太网在每个以太网帧上都有一个CRC检查。如果接收到的帧未通过CRC检查,则该帧将被丢弃,并且不会发送到任何底层协议。我认为你可能使用的任何协议都应该做同样的事情。如果没有,那么IP校验和将有望找到坏数据并丢弃它。因此,所有的希望都没有失去,IP将在没有收到预期的数据报时重试。