在發送數據時,為了計算數IP據報的校驗和。應該按如下步驟: (1)把IP數據報的首部都置為0,包括校驗和字段。 (2)把首部看成以16位為單位的數字組成,依次進行二進制反碼求和。 (3)把得到的結果存入校驗和字段中。 在接收數據時,計算數據報的校驗和相對簡單,按如下步驟: (1)當接收IP包時,需要對報頭進行確認,檢查IP頭是否有誤,算法同上2、3步,然后判斷取反的結果是否為0,是則正確,否則有錯。
1、發送方 i)將校驗和字段置為0,然后將IP包頭按16比特分成多個單元,如包頭長度不是16比特的倍數,則用0比特填充到16比特的倍數; ii)對各個單元采用反碼加法運算(即高位溢出位會加到低位,通常的補碼運算是直接丟掉溢出的高位),將得到的和的反碼填入校驗和字段; iii)發送數據包。 2、接收方 i)將IP包頭按16比特分成多個單元,如包頭長度不是16比特的倍數,則用0比特填充到16比特的倍數; ii)對各個單元采用反碼加法運算,檢查得到的和是否符合是全1(有的實現可能對得到的和會取反碼,然后判斷最終值是不是全0); iii)如果是全1則進行下步處理,否則意味着包已變化從而丟棄之。需要強調的是反碼和是采用高位溢出加到低位的,如3比特的反碼和運算:100b+101b=010b(因為100b+101b=1001b,高位溢出1,其應該加到低位,即001b+1b(高位溢出位)=010b)。
1.實例
請看我用ominipeek的抓包
I.將校驗和字段置為0,然后將IP包頭按16比特分成多個
校驗和Header Checksum:0x618D將其重置為0X0000
將IP包頭分段:
1. 0x4500
2. 0x0029
3. 0x44F1
4. 0x4000
5. 0x8006
6. 0x0000 ------->這個為Header Checksum的值,我們前面將其重置為0了
7. 0xC0A8
8. 0x01AE
9. 0x4A7D
+ 10. 0x477D
-------------------------------------------------------
將1至10相加求出來的和為:0x29E70
II.對各個單元采用反碼加法運算(即高位溢出位會加到低位,通常的補碼運算是直接丟掉溢出的高位),將得到的和的反碼填入校驗和字段
0x0002+0x9E70=0x9E72
0x9E72二進制為:1001 1110 0111 0010
反碼為:0110 0001 1000 1101
0110 0001 1000 1101的16進制為:0x618D
看看這個 是否與IP包頭中的Checksum相同
==========================================================
當接收到IP對其進行檢測
III.對各個單元采用反碼加法運算,檢查得到的和是否符合是全1(有的實現可能對得到的和會取反碼,然后判斷最終值是不是全0)
當收到IP數據局包的時候,要驗證IP頭是否正確,則可以這樣進行
1. 0x4500
2. 0x0029
3. 0x44F1
4. 0x4000
5. 0x8006
6. 0x618D ------->這個為Header Checksum的值
7. 0xC0A8
8. 0x01AE
9. 0x4A7D
+ 10. 0x477D
-------------------------------------------------------
將1至10相加求出來的和為:0x2FFD
對各個單元采用反碼加法運算(即高位溢出位會加到低位,通常的補碼運算是直接丟掉溢出的高位),將得到的和的反碼填入校驗和字段:
0x0002+0x0FFD=0xFFFF
0xFFFF二進制為:1111 1111 1111 1111
1111 1111 1111 1111反碼為:0
====================================================
關於這一部的補充說明,
將IP包頭分段: 1. 0x4500 2. 0x0029 3. 0x44F1 4. 0x4000 5. 0x8006 6. 0x0000 ------->這個為Header Checksum的值,我們前面將其重置為0了 7. 0xC0A8 8. 0x01AE 9. 0x4A7D + 10. 0x477D
----------------------------------------------------------------------------------------------------------