1、演算法思路:
ip/icmp/igmp/tcp/udp等協議的校驗和演算法都是相同的,演算法如下:
在傳送資料時,為了計算ip資料報的校驗和。應該按如下步驟:
(1)把ip資料報的校驗和字段置為0;
(2)把首部看成以16位為單位的數字組成,依次進行二進位制反碼求和;
(3)把得到的結果存入校驗和字段中。
在接收資料時,計算資料報的校驗和相對簡單,按如下步驟:
(1)把首部看成以16位為單位的數字組成,依次進行二進位制反碼求和,包括校驗和字段;
(2)檢查計算出的校驗和的結果是否等於零(反碼應為16個0);
(3)如果等於零,說明被整除,校驗是和正確。否則,校驗和就是錯誤的,協議棧要拋棄這個資料報。
所謂的二進位制反碼求和,即為先進行二進位制求和,然後對和取反。
計算對ip首部檢驗和的演算法如下:
(1)把ip資料報的校驗和字段置為0;
(2)把首部看成以16位為單位的數字組成,依次進行二進位制求和(注意:求和時應將最高位的進製儲存,所以 加法應採用32位加法);
(3)將上述加法過程中產生的進製(最高位的進製)加到低16位(採用32位加法時,即為將高16位與低16位 相加,之後還要把該次加法最高位產生的進製加到低16位)
(4)將上述的和取反,即得到校驗和。
2、實現範例:
彙編:這個可以在linux核心**裡找到,下面就是 arch/x86/include/asm/checksum_32.h裡面的內容:
/*
* this is a version of ip_compute_csum() optimized for ip headers,
* which always checksum on 4 octet boundaries.
* * by jorge cwik , adapted for linux by
* arnt gulbrandsen.
*/static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
c語言:很多網路協議都用如下**實現校驗和演算法:
/*求校驗和函式*/
ushort checksum(ushort *buffer, int size)
if (size)
/*對每個16bit進行二進位制反碼求和*/
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (ushort)(~cksum);
}
IP資料報的校驗和演算法C 版 原
為做偽ip,特地做了乙個ip包,用c 改寫ip頭的校驗和演算法。資料一 ip頭格式 版本號 4位 ip頭長度 4位 服務型別 8位 資料報長度 16位 標識段 16位 標誌段 16位 生存時間 8位 傳輸協議 8位 頭校驗和 16位 傳送位址 16位 目標位址 16位 選項 填充 資料二 ip 協議...
IP資料報的校驗和演算法C 版 原
為做偽ip,特地做了乙個ip包,用c 改寫ip頭的校驗和演算法。資料一 ip頭格式 版本號 4位 ip頭長度 4位 服務型別 8位 資料報長度 16位 標識段 16位 標誌段 16位 生存時間 8位 傳輸協議 8位 頭校驗和 16位 傳送位址 16位 目標位址 16位 選項 填充 資料二 ip 協議...
關於IP資料報首部校驗欄位的理解
關於ip資料報首部校驗欄位的理解 ip資料報格式及首部個字段 www.2cto.com 對上表的各個資料項就不一一解釋了,這裡具體關注以下幾個資料項 1 4位首部長度 這裡的長度指的是4bytes單元的個數,例如上圖在 選項 欄位不存在的情況下,ip包的首部是20bytes,那麼首部長度字段應該為5...