Ethernet ii的以太網幀結構總結(關於墊片)

Ethernet II 的以太網幀結構分析總結

最近在做一個發包程序,程序的功能就是向指定的mac地址發送數據包。其中,這些數據包都是自己從wireshark抓來的,在程序裏對這些包的mac地址和ip、端口都進行了修改,當然其他的像tcp序列號、cookies、host都是自己修改成需要的樣子。不多說這些無用的。
在發包的過程中發現一個包有點問題,因爲在程序中需要修改包的一些字段,包的長度自然就變化了,這時就需要修改ip報文的total_length字段的值。修改完後我加了一個判斷看看是否修改正確,這時發現有一個包的長度是對不上的。如下:


一般來說,pcap數據包頭指示的數據包實際長度 = ip->total_length + 以太包頭的長度(14字節)。但是這個數據包卻不是,最上面pcap數據包頭指示抓到了60字節的數據包,ip報文的total_length字段指示帶了40字節的數據(ip頭加tcp頭),這時會發現前者(60bytes)並不等於後者(40bytes)加上以太包頭的長度(14bytes),確切的說是少了6個bytes。
這時細心的同學可能就發現了,在ethernet ii幀結構中多出了一個字段trailer:000000000000;這個字段剛好是6bytes。尼瑪,這是什麼玩意!!!
後來上網查了查,原來是一個叫 墊片 的東西。什麼是墊片?

好!我們先來看一下ethernet ii的幀結構。


Ethernet II 的幀結構:

大家知道,以太網幀的最小長度和最大長度是有限制的,最小64bytes,最大1518字節。這可不是MTU,別混淆了。MTU是IP層面的東西,咱們現在討論的是二層數據鏈路層!

新手朋友可能不理解這兩個是怎麼算出來的:
最小64bytes =  src(6bytes) + dst(6bytes)+ type(2bytes)+ 最小數據長度(46bytes) +  FCS(4bytes)
最大1518bytes =  src(6bytes) + dst(6bytes)+ type(2bytes) + 最大數據長度(1500字節) + FCS(4bytes)
爲什麼要最小?
以太網採用的是CSMA/CD方法在介質上傳輸數據,而CSMA/CD的特性要求有最小字節限制。這個自己去網上搜去,到處都是。
爲什麼最大?
其實沒有最大,一般默認是那麼大!!可以設置的。

所以,即使你要傳輸1byte的數據你也要使用46bytes的數據字段,來保證最小幀64字節的限制。那麼,結果就出來了,怎麼保證呢,就是在空餘的數據字段位置上加上墊片,來填充數據長度。
就像開始的那個幀一樣:
64bytes =  src(6bytes) + dst(6bytes)+ type(2bytes)+ ip_head(20bytes) + tcp_head(20bytes)+ 墊片(6bytes)+ FCS(4bytes)

即:14字節的固定以太頭 + 46字節的數據(最小數據長度,這裏是20字節的IP頭加上20字節tcp頭再加上6字節的墊片) +  4字節的固定幀結尾(FCS幀校驗)。

不要問我爲什麼前導符的8bytes爲什麼沒加上,前導符你是看不到的,wireshark也抓不到。pcap數據包頭指示的抓取數據長度是不包括前導符的。前導符這玩意是前期開始傳輸幀做準備工作用的,貌似是在物理層才用得着,以前學的都忘了,反正別把它拉到我們討論的以太幀長度中來!

如果大家也做過拆包的話,有個細節問題,不知道大家注意到沒?
問題:
墊片的位置加在什麼地方?
當我們拿到pcap包頭指示的數據報指針後,一般情況下,我們會直接讓指針偏移以太包頭的長度(14字節)去獲取ip包的位置。問題就出在這裏,如果墊片加在以太包頭後或者IP包頭前,其實只要是插在數據包的任何位置都是有問題的,根據偏移量來取ip包或者tcp包都是有問題的,拿到的數據報都是錯誤的!
別慌!我後來做了測試,數據包取的都是正確的。其實是大驚小怪,看了一下linux內核的網卡驅動,人家也是這麼寫的,直接偏移14字節去取的ip包。後來又看了網上的一些文章,說這墊片是加在邏輯層面的,mac層沒有影響,,,,,,,
然後我到現在也是凌亂了!!!!!
還是多看書吧。。。。。大學時間都玩魔獸世界了,那還記得什麼邏輯,什麼mac。。。。。。。。。。












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章