2013-01-22 22 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; 
}