4

我正在开发 Linux 内核的驱动程序。为了我的项目的成功,我需要确定添加到小于最小 60 字节大小的以太网帧的填充量(不包括 FCS)。我没有生成这些帧;我在 NIC 上接收它们以进行处理。

struct sk_buff, 是否可以直接确定添加到数据包中的尾随零的数量?

我当然可以通过遍历整个数据包来确定该值,找出最高层的内容在哪里结束,然后简单地从帧大小中减去该位置(在本例中为 60 字节)。但是有没有更有效的方法可以直接从存储在 a 上的信息中进行操作struct sk_buff

4

2 回答 2

2

编辑:据我所知,如果不实际查看以太网标头,就无法直接使用 sk_buff 结构检查零填充,这很简单。

也就是说,通过一些简单的指针运算和字节减法,您可以使用 IP 数据中的长度字段来计算填充。

这是 sk_buff 的一个很好的参考:http: //vger.kernel.org/~davem/skb_data.html

这是数据包结构的一个很好的参考,显示了“数据”内底部图片中的“长度”字段。

http://nerdcrunch.com/wp-content/uploads/2011/05/Ethernet-Frame-Explained.png

我认为这是必须完成的方式,但它不需要像您之前维护的那样进行解析。标头/数据结构字段的设置使得它们可以通过指针/数组直接引用/剥离而无需解析,然后通过从原始数据包长度中减去标头+数据长度,您可以获得填充,所有这些都无需检查数据。

希望有帮助。

此外,为了获得最佳实践,您可能应该同时使用两个 802.3 版本的驱动程序帐户。您可以通过检查 Ethertype/length 字段来做到这一点。如果该值大于 1536 (0x0600),那么您就知道它是以太网 II 类型的数据包,并且该字段包含一个以太网类型,它告诉您以太网数据包封装的内容。如果您在 Wikipedia 中查找“Ethertype”,则有一些流行的。

例如,IP = 0x0800。如果该字段指定了 Ethertype,则必须求助于查找内部的数据长度字段才能找到填充。如果没有,很多基于以太网的 LAN 仍然没有,那么您可以直接使用指定为长度的字段来完成您的工作。

于 2013-01-22T16:15:17.927 回答
0

IPv4 的作用几乎相同,可能没有更好的方法。检查 ip_rcv():

len = ntohs(iph->tot_len);
if (skb->len < len) {
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INTRUNCATEDPKTS);
        goto drop;
} else if (len < (iph->ihl*4))
        goto inhdr_error;

/* Our transport medium may have padded the buffer out. Now we know it
 * is IP we can trim to the true length of the frame.
 * Note this now means skb->len holds ntohs(iph->tot_len).
 */
if (pskb_trim_rcsum(skb, len)) {
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
        goto drop;
}
于 2013-01-26T07:04:29.653 回答