2013-01-22 24 views
3

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

有一个struct sk_buff,是有可能确定后直接加入到该分组的零的量?

我当然可以通过整个数据包去,找出确定值,其中最高的层端部的内容,然后简单地减去帧大小位置(在这种情况下,60个字节)。但有没有一种更有效的方式直接从struct sk_buff上存储的信息来完成?

回答

0

编辑:据我所知,目前还没有办法检查用于填零直接使用的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),那么它就是Ethernet II类型的数据包,并且该字段包含一个ethertype,它告诉您以太网数据包封装的内容。如果你有维基百科的“Ethertype”,有一些流行的。

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

+0

谢谢你的答案,但我不太清楚,我明白了。我对'sk_buff'结构非常熟悉,可以按照你的想法,但是以太网头不包含帧长度(它只包含发送者/接收者MAC地址和EtherType字段)。你能再详细一点吗? – pap42

+0

对不起,我想我错过了。标题中有时会有'长度'字段,但这不是你应该指望的 - 也不是我想要提及的。我所指的'长度'字段不是标题的一部分。看看这个: http://nerdcrunch.com/wp-content/uploads/2011/05/Ethernet-Frame-Explained。png 您希望长度字段列在底部。使用该字段和其他字段的大小,可以计算出填充量。那有意义吗? – HodorTheCoder

+0

以太网II帧确实有一个类型字段,但802.3以太网帧使用该字段的长度。 (以太网II类型都有很高的数值,不能与长度混淆,所以你可以知道你在处理什么。)但是如果你在处理以太网II并且你有填充帧,那么你必须依靠封装协议实际长度;你不能从以太网头获得它。这里有一个参考文献:http://www.dcs.gla.ac.uk/~lewis/networkpages/m04s03EthernetFrame.htm –

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; 
}