我正在 Linux 中编写一个网络模块,我发现只有在从 skb 缓冲区跳过 20 个字节后才能提取 tcp 标头,即使 API 是“skb_transport_header”。
其背后的原因是什么?有人可以详细解释一下吗?传出数据包不需要同样的操作。据我了解,在接收数据包时,当数据包从 L1 流向 L5 时,标头会被删除。但是,当数据包发出时,会添加标头。这有何不同?
/**对于输入数据包**/
struct tcphdr *tcp;
tcp = (struct tcphdr *)(skb_transport_header(skb)+20);
/** 对于传出数据包 **/
struct tcphdr *tcp;
tcp = (struct tcphdr *)(skb_transport_header(skb));
这取决于您在堆栈中处理数据包的位置。刚收到数据包后,传输标头偏移量尚未设置。一旦您确定该数据包实际上是发往本地盒子的,那么就不再需要这样做了。对于 ip_local_deliver_finish() 中的 IPv4,会发生这种情况。 (请注意,例如,tcp_hdr() 假设已经设置了transport_header 位置。)
这是完全有道理的(尽管很难确定这样的事情在正常流程中发生在哪里):当每一层被识别和处理时,下一层的起始偏移量被记录在 sk_buff 中。标头实际上并未被删除,skb“数据”位置只是调整为指向标头之外。并且特定于层的位置也进行类似的调整。
在输出时,它更简单一些,并且以相反的顺序完成:首先创建传输标头。然后,将网络标头添加到其前面,等等。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)