我正在研究Linux內核的驅動程序。爲了使我的項目成功,我需要確定添加到以太網幀的填充量小於60字節的最小大小(不包括FCS)。我沒有生成這些框架;我正在通過網卡接收它們進行處理。確定添加到以太網幀的填充量
有一個struct sk_buff
,是有可能確定後直接加入到該分組的零的量?
我當然可以通過整個數據包去,找出確定值,其中最高的層端部的內容,然後簡單地減去幀大小位置(在這種情況下,60個字節)。但有沒有一種更有效的方式直接從struct sk_buff
上存儲的信息來完成?
我正在研究Linux內核的驅動程序。爲了使我的項目成功,我需要確定添加到以太網幀的填充量小於60字節的最小大小(不包括FCS)。我沒有生成這些框架;我正在通過網卡接收它們進行處理。確定添加到以太網幀的填充量
有一個struct sk_buff
,是有可能確定後直接加入到該分組的零的量?
我當然可以通過整個數據包去,找出確定值,其中最高的層端部的內容,然後簡單地減去幀大小位置(在這種情況下,60個字節)。但有沒有一種更有效的方式直接從struct sk_buff
上存儲的信息來完成?
編輯:據我所知,目前還沒有辦法檢查用於填零直接使用的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仍然沒有,那麼你可以直接使用指定長度的字段來完成你的工作。
的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;
}
謝謝你的答案,但我不太清楚,我明白了。我對'sk_buff'結構非常熟悉,可以按照你的想法,但是以太網頭不包含幀長度(它只包含發送者/接收者MAC地址和EtherType字段)。你能再詳細一點嗎? – pap42
對不起,我想我錯過了。標題中有時會有'長度'字段,但這不是你應該指望的 - 也不是我想要提及的。我所指的'長度'字段不是標題的一部分。看看這個: http://nerdcrunch.com/wp-content/uploads/2011/05/Ethernet-Frame-Explained。png 您希望長度字段列在底部。使用該字段和其他字段的大小,可以計算出填充量。那有意義嗎? – HodorTheCoder
以太網II幀確實有一個類型字段,但802.3以太網幀使用該字段的長度。 (以太網II類型都有很高的數值,不能與長度混淆,所以你可以知道你在處理什麼。)但是如果你在處理以太網II並且你有填充幀,那麼你必須依靠封裝協議實際長度;你不能從以太網頭獲得它。這裏有一個參考文獻:http://www.dcs.gla.ac.uk/~lewis/networkpages/m04s03EthernetFrame.htm –