IP協議的CheckSum函式之理解

2021-04-20 11:44:15 字數 4599 閱讀 1365

ip協議中的checksum

author:zfive5(zhaozidong)

email :[email protected]

最近一段時間,對網路又開始追根溯源,最好的辦法就是開啟開源協議棧看乙個究竟,不求寫乙個完整的ip協議棧,但求通達解惑!

眾所周知,ip頭定義如下:

struct

ipheader ;

ip頭中的大多欄位都好理解,只要一本tcp/ip入門的書就可以明明白白了,對cksum欄位理解,如果只是看書,到頭來很可能還不清楚怎麼算它!

關於cksum_header的描述在《tcp/ip卷一》中是這樣描述的:

首部檢驗和字段是根據i p首部計算的檢驗和碼。它不對首部後面的資料進行計算。i c m pi g m pu d pt c p在它們各自的首部中均含有同時覆蓋首部和資料檢驗和碼。

為了計算乙份資料報的i p檢驗和,首先把檢驗和字段置為0。然後,對首部中每個16 bit進行二進位制反碼求和(整個首部看成是由一串16 bit的字組成),結果存在檢驗和字段中。當收到乙份i p資料報後,同樣對首部中每個16 bit進行二進位制反碼的求和。由於接收方在計算過,程中包含了傳送方存在首部中的檢驗和,因此,如果首部在傳輸過程中沒有發生任何差錯,那麼接收方計算的結果應該為全1。如果結果不是全1(即檢驗和錯誤),那麼i p就丟棄收到的資料報。但是不生成差錯報文,由上層去發現丟失的資料報並進行重傳。

」不知道有多少能人看完此描述後,寫出演算法或函式來!

正確的函式如下:

unsigned short checksum(unsigned short *szbuf,int

isize)

讓我們假設乙個ip頭資料,來解cksum的惑!

ip頭資料:

01000101   / *ver_hlen; */

00000000   /*tos*/

00000000 00000010/*len*/

00000000 00000000/*id*/

00000000 00000000/*offset*/

00000001/*ttl*/

00010001/*type*/

00000000 00000000/*cksum(0)*/

01111111 00000000 00000000 0000001/*sip*/

01111111 00000000 00000000 0000001/*dip*/

運算過程(注意是大端格式加):

01000101 00000000

01000101 00000000

00000000 00000010

01000101 00000010

00000000 00000000

01000101 00000010

00000000 00000000

01000101 00000010

00000100 00010001

01001001 00010011

00000000 00000000

01001001 00010011

01111111 00000000

11001000 00010011

00000000 00000001

11001000 00010100

01111111 00000000

101000111 00010100

00000000 00000001

和: 101000111 00010101

cksum=(cksum>>16)+(cksum&0xffff)後:

00000000 000000011

01000111 00010101

和: 01000111 00010110

cksum+=(cksum>>16)後:

01000111 00010110

00000000 00000000

和: 01000111 00010110

~: 10111000 11101000(效檢和)

運算過程(注意用小端格式加):

00000000 01000101

00000000 01000101

00000010 00000000

00000010 01000101

00000000 00000000

00000010 01000101

00000000 00000000

00000010 01000101

00010001 00000100

00010011 01001001

00000000 00000000  

00010011 01001001

00000000 01111111  

00010011

11001000

00000001 00000000  

00010100 11001000

00000000 01111111  

00010101 01000111

00000001 00000000  

和: 00010110 01000111

cksum=(cksum>>16)+(cksum&0xffff)後:

00000000 000000001

00010110 01000111

和: 00010110 01000111

cksum+=(cksum>>16)後:

00010110 01000111

00000000 00000000

和: 00010110 01000111

~: 11101001 10111000(效檢和)

checksum211101000 10111000(小端)

checksum110111000 11101000(大端)

演算法一樣,說白了就是迴圈加,加到沒有進製為止,然後在取反!

在現在《tcp/ip卷二》中的cksum實現有以下語句:

while(sum>>16)

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

通過它更能說明就是在作迴圈加操作,現在又有乙個疑問:

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

cksum+=(cksum>>16);

while(sum>>16)

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

等價嗎?

等價,在一定條件下等價,大家都知道ip理論上最長是0xffff

那麼checksum最大不會超過:0xffff0000

這樣》16後為0xffff

0xffff+checksum最大0x1fffe,

0x1fffe >>16+0x1fffe=0xffff

注意了沒有了進製

所以得到等價的結論!

IP協議的CheckSum函式之理解

解 ip協議中的 checksum author zfive5 zhaozidong email zfive5 yahoo.com.cn 最近一段時間,對網路又開始追根溯源,最好的辦法就是開啟開源協議棧看乙個究竟,不求寫乙個完整的 ip協議棧,但求通達解惑!眾所周知,ip頭定義如下 struct i...

詳解IP首部效檢和 checksum

最近一段時間,對網路又開始追根溯源,最好的辦法就是開啟開源協議棧看乙個究竟,不求寫乙個完整的ip協議棧,但求通達解惑!眾所周知,ip頭定義如下 struct ipheader unsigned char ver hlen unsigned char tos unsigned short len un...

TCP IP協議 IP協議

ip協議層 在傳輸層的下邊,鏈路層的上邊。ip層封裝後稱為資料報 傳輸層叫資料段,鏈路層叫資料幀。值得注意的是,不是所有的乙太網資料幀都是ip資料報,至少乙太網還要使用arp協議。不是所有的ip資料報都是udp或tcp資料,因為比如icmp igmp也用ip傳送資料 ip協議在網路中當然非常重要了,...