确定添加到以太网帧的填充量

时间:2013-01-22 15:22:38

标签: c linux-kernel padding linux-device-driver

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

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

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

2 个答案:

答案 0 :(得分:2)

编辑:据我所知,没有办法直接使用sk_buff结构检查零填充,而没有实际查看以太网头,这很简单。

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

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

这里有一个很好的数据包结构参考,在'data'的底部图片中显示'length'字段。

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

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

希望有所帮助。

此外,为了获得最佳实践,您可能应该使用两个版本的802.3的驱动程序帐户。您可以通过检查Ethertype / length字段来完成此操作。如果该值大于1536(0x0600),则表示它是以太网II类型数据包,并且该字段包含ethertype,它告诉您以太网数据包封装的内容。如果你是维基百科的“Ethertype”,那么有一些流行的。

例如,IP = 0x0800。如果字段指定Ethertype,则必须求助于在里面找到数据长度字段以找到填充。如果没有,那么很多基于以太网的局域网仍然没有,那么你可以直接使用指定为长度的字段来完成你的工作。

答案 1 :(得分: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;
}