計算數IP據報的校驗和

IP/ICMP/IGMP/TCP/UDP等協議的校驗和算法都是相同的,算法以下:算法


在發送數據時,爲了計算數IP據報的校驗和。應該按以下步驟:ide

(1)把IP數據報的首部都置爲0,包括校驗和字段。函數

(2)把首部當作以16位爲單位的數字組成,依次進行二進制反碼求和。spa

(3)把獲得的結果存入校驗和字段中。orm

在接收數據時,計算數據報的校驗和相對簡單,按以下步驟:it

 

(1)當接收IP包時,須要對報頭進行確認,檢查IP頭是否有誤,算法同上二、3步,而後判斷取反的結果是否爲0,是則正確,不然有錯。class


一、發送方二進制

  i)將校驗和字段置爲0,而後將IP包頭按16比特分紅多個單元,如包頭長度不是16比特的倍數,則用0比特填充到16比特的倍數;方法

 

  ii)對各個單元採用反碼加法運算(即高位溢出位會加到低位,一般的補碼運算是直接丟掉溢出的高位),將獲得的和的反碼填入校驗和字段;數據

 

  iii)發送數據包。

 

二、接收方

  i)將IP包頭按16比特分紅多個單元,如包頭長度不是16比特的倍數,則用0比特填充到16比特的倍數;

 

  ii)對各個單元採用反碼加法運算,檢查獲得的和是否符合是全1(有的實現可能對獲得的和會取反碼,而後判斷最終值是否是全0);

 

iii)若是是全1則進行下步處理,不然意味着包已變化從而丟棄之。須要強調的是反碼和是採用高位溢出加到低位的,如3比特的反碼和運算:100b+101b=010b(由於100b+101b=1001b,高位溢出1,其應該加到低位,即001b+1b(高位溢出位)=010b)。



現假如一數據報爲45 00 05 D4 CA E0 40 00 75 06 70 D2 CA 62 39 64 C0 A8 00 02

根據IP數據報的格式能夠看出它的首部校驗字段爲70 D2 它是怎麼算出來的呢?

方法:咱們把首部校驗字段即70 D2 用0000代替

4500+05D4+CAE0+4000+7506+0000+CA62+3964+C0A8+0002=38F2A

而後把進出來的一位與後4位再進行十六進制加法,8F2A+0003=8F2D

最後用FFFF減去算出來的結果就能夠了即FFFF-8F2D=70D2

    



函數代碼以下。

USHORT CheckSum(USHORT *buffer, int size)  

{  

    unsigned long cksum=0;  

    while (size > 1)   

    {  

        cksum += *buffer++;  

        size -= sizeof(USHORT);  

    }  

    if (size)   

    {  

        cksum += *(UCHAR*)buffer;  

    }    

    cksum = (cksum >> 16) + (cksum & 0xffff);  

    cksum += (cksum >>16);  

    return (USHORT)(~cksum);  

}  

相關文章
相關標籤/搜索