Sockets 为什么在输入数据包时,skb_缓冲区需要跳过20个字节才能读取传输缓冲区?

Sockets 为什么在输入数据包时,skb_缓冲区需要跳过20个字节才能读取传输缓冲区?,sockets,networking,tcp,linux-kernel,linux-device-driver,Sockets,Networking,Tcp,Linux Kernel,Linux Device Driver,我正在Linux中编写一个网络模块,我发现只有在从skb缓冲区跳过20个字节后才能提取tcp头,即使API是“skb_transport_header”。 背后的原因是什么?有人能详细解释一下吗?对于传出数据包,不需要相同的设置。我知道在接收数据包时,当数据包从L1流到L5时,会删除报头。但是,当数据包传出时,会添加报头。这有什么不同 /**用于输入数据包**/ struct tcphdr*tcp; tcp=(结构tcphdr*)(skb_传输_头(skb)+20); /**用于发送数据包**

我正在Linux中编写一个网络模块,我发现只有在从skb缓冲区跳过20个字节后才能提取tcp头,即使API是“skb_transport_header”。 背后的原因是什么?有人能详细解释一下吗?对于传出数据包,不需要相同的设置。我知道在接收数据包时,当数据包从L1流到L5时,会删除报头。但是,当数据包传出时,会添加报头。这有什么不同

/**用于输入数据包**/

struct tcphdr*tcp;
tcp=(结构tcphdr*)(skb_传输_头(skb)+20);
/**用于发送数据包**/

struct tcphdr*tcp;
tcp=(结构tcphdr*)(skb_传输_头(skb));

这取决于您在堆栈中处理数据包的位置。在收到数据包之后,传输头偏移量还没有设置。一旦确定此数据包实际上是发送到本地盒子的,就不再需要这样做了。这在ip_local_deliver_finish()中的IPv4中发生。(请注意,例如,tcp_hdr()假定已设置传输_头位置。)

这是完全有意义的(即使很难确定在正常流程中这样的事情发生在哪里):当识别和处理每一层时,下一层的起始偏移量记录在sk_buff中。标题并没有被实际删除,skb“数据”位置只是调整到超出它们的位置。并且,层特定位置也进行了类似的调整


在输出上,它更简单一些,并且按照相反的顺序完成:首先创建传输头。然后,将网络头添加到该函数前面,以此类推。

我在netfilter钩子函数中看到了这一点。这意味着,netfilter钩子函数在网络层工作。但是,我不明白为什么问题出在输入端而不是输出端。您能重复您的回答吗?在传输数据包时,数据链路层头没有设置,是真的吗?由于netfilter在L2层-网络层上工作。因此,在发送时不设置数据链路层报头。我说的对吗?可能是