ip首部檢驗和算法


最近在書中看到多次ip檢驗和算法,就找度娘問了一下,結果給出的答案也都大差不離,
但是自己也不是很明白,就決定自己親自實踐計算一下,徹底的搞明白。
工具:wireshark
下面是ip首部的結構

經過抓包后得到下圖

從圖中可以看出,ip首部的各種數據格式
解釋如下:
版本號4,占了4位,表示ipv4.
接下來是包頭長度,又占了4位,指明ipv4協議包頭長度的字節數包含多少個32位。由於IPv4
的包頭可能包含可變數量的可選 項,所以這個字段可以用來確定IPv4數據報中數據部分的偏
移位置。IPv4包頭的最小長度是20個字節,因此IHL這個字段的最小值用十進制表示就是5
(5x4(4個字節32位) = 20字節)。就是說,它表示的是包頭的總字節數是4字節的倍數。
圖中即為header length為20表示是20個字節,所以經過計算此處用十進制表示為5,二進制
表示為1001。
再往下是服務類型為0x00。
服務類型此處一共占了8位,涵義如下:
過程字段: 3位,設置了數據包的重要性,取值越大數據越重要,取值范圍為:0(正常)~ 7(網絡控制)
延遲字段: 1位,取值:0(正常)、1(期特低的延遲)
流量字段: 1位,取值:0(正常)、1(期特高的流量)
可靠性字段: 1位,取值:0(正常)、1(期特高的可靠性)
成本字段: 1位,取值:0(正常)、1(期特最小成本)
未使用: 1位
接着是總長度total length:71(十進制表示),換位十六進制是0x0047
標識字段:占16位。IP軟件在存儲器中維持一個計數器,每產生一個數據報,計數器就加1,並將此值賦給標識字段。
但這個“標識”不是序號,因為IP是無連接服務,數據報不存在按序接收的問題。當數據報由於長度超過網絡的MTU而必須分片時,
這個標識字段的值就被復制到所有的數據報片的標識字段中。相同的標識字段的值使分片后的各數據報片最后能正確地重裝成為原來的數據報
此處值為0x1fd6
標志(flag):占3位,但目前只有兩位有意義。
標志字段中的最低位為MF(More Fragment)。MF=1即表示后面“還有分片”的數據報。MF=0表示這已是若干數據報片中的最后一個。
標志字段中間的一位記為DF(Don't Fragment),意思是“不能分片”。只有當DF=0時才允許分片。
此處值為0x02即010表示不能分片,即don't Fragment
段偏移量:當數據分組時,它和更多段位(MF, More fragments)進行連接,幫助目的主機將分段的包組合
此處值為0x00
在往后為ttl,生存時間8位,表示數據包在網絡上生存多久,每通過一個路由器該值減一,為0時將被路由器丟棄。
協議:8位,這個字段定義了IP數據報的數據部分使用的協議類型。常用的協議及其十進制數值包括ICMP(1)、TCP(6)、UDP(17)。
此處生存時間為1,協議是17,換算為16進制是0x0111
源端ip:192.168.0.109 0xc0a8 0x006d
目標ip:224.0.0.252 0xe000 0x00fc
到此,首部的數據基本確定清楚,往下我們來計算檢驗和checksum
首先明確檢驗和的計算方法
0和0相加是0,0和1相加是1,1和1相加是0但要產生一個進位1,加到下一列.若最高位相加后產生進位,則最后得到的結果要加1.
在發送數據時,為了計算IP數據包的校驗和。應該按如下步驟:
(1)把IP數據包的校驗和字段置為0;
(2)把首部看成以16位為單位的數字組成,依次進行二進制反碼求和;
(3)把得到的結果存入校驗和字段中。
在接收數據時,計算數據包的校驗和相對簡單,按如下步驟:
(1)把首部看成以16位為單位的數字組成,依次進行二進制反碼求和,包括校驗和字段;
(2)檢查計算出的校驗和的結果是否等於零(反碼應為16個0);
(3)如果等於零,說明被整除,校驗和正確。否則,校驗和就是錯誤的,協議棧要拋棄這個數據包。
網上找了一個簡單點的例子先來看一下
原始數據為 1100 , 1010 , 0000(校驗位)
那么把他們按照4bit一組進行按位取反相加。 1100取反0011 , 1010取反是0101,0011加上0101 是1000,填入到校驗位后
1100 , 1010 , 1000
那么這個就是要發送的數據。收到數據后同樣進行按位取反相加。0011+0101+0111 =1111;全為1表示正確
先來計算發送端:
我們這的原始數據為
十六進制:
0x4500 0x0047
0x1fd6 0x0000
0x0111 0xf7be
0xc0a8 0x006d
0xe000 0x00fc
分別對應的二進制如下:
0100 0101 0000 0000
0000 0000 0100 0111
0001 1111 1101 0110
0000 0000 0000 0000
0000 0001 0001 0001
1111 0111 1011 1110
1100 0000 1010 1000
0000 0000 0110 1101
1110 0000 0000 0000
0000 0000 1111 1100
將檢驗和置0為0x0000
其余分別取反:
1011 1010 1111 1111
1111 1111 1011 1000
1110 0000 0010 1001
1111 1111 1111 1111
1111 1110 1110 1110
0000 0000 0000 0000 ---〉檢驗和
0011 1111 0101 0111
1111 1111 1001 0010
0001 1111 1111 1111
1111 1111 0000 0011
求和后化為十六進制剛好為0xf7be
另一種方法
先直接相加在取反:
4500+0047+1fd6+0000+0111+c0a8+006d+e000+00fc=2083f
083f+2=841
化為二進制:0000 1000 0100 0001
將其取反后:1111 0111 1011 1110
也是0xf7be
由此可見兩種方法均可以計算出正確的檢驗和。
下面再來看一下接收數據的情況。此次我們用第二種方法計算,即先求和再取反。


4500+0257+8bbb+0000+4006+6b27+c0a8+0001+c0a8+006d=2fffd
fffd+2=ffff
取反后為0000因此結果正確。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM