下面摘自《tcp/ip協議簇》的ip頭校驗和演算法:
傳送時:
1. 將校驗和字段置為0;
2. 將整個首部分為16bit的部分,求和;
3. 取反碼,填入到校驗和字段中;
接收時:
1. 直接將整個首部分為16bit的部分,求和;
2. 取反碼,若結果為0,取合法;否則丟棄;
這上面有兩個細節沒有描述清楚:
1. 計算時的位元組順序(litter endian和big endian)問題;
2. 取和溢位時的改進計算方法;
◆當傳送ip包時,需要計算ip報頭的校驗和:
1、 把校驗和字段置為0;
2、 對ip頭部中的每16bit進行二進位制求和;
3、 如果和的高16bit不為0,則將和的高16bit和低16bit反覆相加,直到和的高16bit為0,從而獲得乙個16bit的值;
4、 將該16bit的值取反,存入校驗和字段。
◆當接收ip包時,需要對報頭進行確認,檢查ip頭是否有誤,演算法同上2、3步,然後判斷取反的結果是否為0,是則正確,否則有錯。
演算法:unsigned short checksum(unsigned short *_pbuff, int _size)
if (tmpsize > 0)
cksum = (cksum >> 16) + (cksum & 0xffff); //將高16bit與低16bit相加
cksum += (cksum >> 16); //將進製到高位的16bit與低16bit 再相加
return (unsigned short)(~cksum);
}關於計算時的位元組順序,一般以網路位元組順序(big endian)為準,但仍然有個十分模糊的地方,就是為什麼校驗和這個字段不用進行網路轉換了,如x86系統,直接以本地位元組順序(litter endian)傳送就可以了,這也讓我十分糾結。
下面是舉例:
char szbuf = ;
unsigned short sendcksum = 0x71a5; //這個值不用轉換為網路位元組順序,直接以 a5 71填入
char szbuf = ;
unsigned short recvcksum = checksum((unsigned short*)szbuf, 20); //這裡recvcksum為0
ip首部校驗和計算
ip首部校驗和的計算方法 1.把校驗和字段清零。2.然後對每16位 2位元組 進行二進位制反碼求和,反碼求和的意思是先對每16位求和,再將得到的和轉為反碼。接下來詳細描述反碼求和的步驟 看下面的 演算法 short checksum ushort buffer,int size if size ck...
ip首部校驗和計算
ip首部校驗和的計算方法 1.把校驗和字段清零。2.然後對每16位 2位元組 進行二進位制反碼求和,反碼求和的意思是先對每16位求和,再將得到的和轉為反碼。接下來詳細描述反碼求和的步驟 看下面的 演算法 short checksum ushort buffer,int size if size ck...
IP校驗和計算相關
校驗和只是為防止報文在通道傳輸出現誤碼導致報文錯誤,並不保證報文被他人惡意篡改。unsigned short ip fast csum unsigned char iph,unsigned int ihl iph ip頭指標 ihl ip頭長度,4位元組長度的數目。利用這個函式在傳送報文時計算校驗和...