IP校驗和


首部檢驗和字段是根據 I P首部計算的檢驗和碼,它不對首部后面的數據進行計算。

I C M P、I G M P、U D P和T C P在它們各自的首部中均含有同時覆蓋首部和數據檢驗和碼。

為了計算一份數據報的 I P檢驗和,首先把檢驗和字段置為 0。然后,對首部中每個 16 bit進行二進制反碼求和(整個首部看成是由一串 16 bit的字組成),結果存在檢驗和字段中。

當收到一份 I P數據報后,同樣對首部中每個 16 bit進行二進制反碼的求和。由於接收方在計算過程中包含了發送方存在首部中的檢驗和,因此,如果首部在傳輸過程中沒有發生任何差錯,那么接收方計算的結果應該為全 1。如果結果不是全 1(即檢驗和錯誤),那么I P就丟棄收到的數據報。但是不生成差錯報文,由上層去發現丟失的數據報並進行重傳。
I C M P、I G M P、U D P和T C P都采用相同的檢驗和算法,盡管 T C P和U D P除了本身的首部和數據外,在 I P首部中還包含不同的字段。在 RFC 1071[Braden, Borman and Patridge 1988]中有關於如何計算 I n t e r n e t檢驗和的實現技術。由於路由器經常只修改 T T L字段(減 1),因此當路由器轉發一份報文時可以增加它的檢驗和,而不需要對I P 整個首部進行重新計算。 R F C1141[Mallory and Kullberg 1990]為此給出了一個很有效的方法。但是,標准的BSD實現在轉發數據報時並不是采用這種增加的辦法。

二進制反碼求和

先進行二進制求和,然后對和取反。對一個無符號的數,先求其反碼,然后從低位到高位,按位相加,有益處則向高位進1(和一般的二進制法則一樣),若最高位有進位,則向最低位進1。

關於二進制反碼求和運算需要說明的一點是,先取反后相加與先相加后取反,得到的結果是一樣的。

It may look awkword to use a 1's complement addition on 2's complement machines. This method however has its own benefits.
Probably the most important is that it is endian independent. Little Endian computers store hex numbers with the LSB last (Intel processors for example). Big Endian computers put the LSB first (IBM mainframes for example). When carry is added to the LSB to form the 1's complement sum (see the example) it doesn't matter if we add 03 + 01 or 01 + 03. The result is the same.
Other benefits include the easiness of checking the transmission and the checksum calculation plus a variety of ways to speed up the calculation by updating only IP fields that have changed.

a、 不依賴系統是大端小端。即無論你是發送方計算機或者接收方檢查校驗和時,都不要調用htons或者ntohs,直接通過上面的算法就可以得到正確的結果。這個問題你可以自己舉個例子,用反碼求和時,交換16位數的字節順序,得到的結果相同,只是字節順序相應地也交換了;而如果使用原碼或者補碼求和,得到的結果可能就不同。

b、 計算和驗證校驗和比較簡單、快遞。

具體方法

在發送數據時,為了計算數IP據報的校驗和。應該按如下步驟:
    (1)把IP數據報的首部都置為0,包括校驗和字段。
    (2)把首部看成以16位為單位的數字組成,依次進行二進制反碼求和。
    (3)把得到的結果存入校驗和字段中。
    在接收數據時,計算數據報的校驗和相對簡單,按如下步驟:
    (1)把首部看成以16位為單位的數字組成,依次進行二進制反碼求和,包括校驗和字段。
    (2)檢查計算出的校驗和的結果是否全為1。
    (3)如果全為1,說明被整除,校驗和正確。否則,校驗和就是錯誤的,協議棧要拋棄這個數據包

接收方計算校驗和時的首部與發送方計算校驗和時的首部相比,多了一個發送方計算出來的校驗和。因此,如果首部在傳輸過程中沒有發生差錯,那么接收方計算的結果應該為全一,因為接收方計算除校驗和以外的部分得到值是校驗和的反碼,再加多出來的校驗和當然是全一了。

計算對IP首部檢驗和的算法如下:   
(1)把IP數據包的校驗和字段置為0;   
(2)把首部看成以16位為單位的數字組成,依次進行二進制求和(注意:求和時應將最高位的進位保存,所以加法應采用32位加法);   
(3)將上述加法過程中產生的進位(最高位的進位)加到低16位(采用32位加法時,即為將高16位與低16位相加,之后還要把該次加法最高位產生的進位加到低16位)   
(4)將上述的和取反,即得到校驗和。

程序

unsigned short cal_chksum(unsigned short *addr, int len)
{
    int nleft = len;
    int sum = 0;
    unsigned short *w=addr;
    unsigned short answer = 0;
    while(nleft > 1){    // 16bit為單位累加運算
        sum += *w++;
        nleft -= 2;
    }   
    if(nleft == 1){  //若addr奇數個字節,會剩下最后一字節. sum + =*(unsigned char *)w;  
    }   
    sum = (sum>>16) + (sum&0xffff);
    sum += (sum>>16);
    answer = ~sum;
    return answer;
}

示例

  IP頭:
  45 00    00 31
  89 F5    00 00
  6E 06    00 00(校驗字段)
  DE B7   45 5D       ->    222.183.69.93
  C0 A8   00 DC     ->    192.168.0.220
  計算:  
  4500 + 0031 +89F5 + 0000 + 6e06+ 0000 + DEB7 + 455D + C0A8 + 00DC =3 22C4
  0003 + 22C4 = 22C7
  ~22C7 = DD38      ->即為應填充的校驗和
  當接受到IP數據包時,要檢查IP頭是否正確,則對IP頭進行檢驗,方法同上:
  計算:
  4500 + 0031 +89F5 + 0000 + 6E06+ DD38 + DEB7 + 455D + C0A8 + 00DC =3 FFFC
  0003 + FFFC = FFFF
  得到的結果是全一,正確。
 

 IP/UDP/TCP/ICMP校驗和異同

四種報文的校驗和算法一樣,但在作用范圍存在不同:IP校驗和只校驗20字節的IP報頭;而ICMP校驗和覆蓋整個報文(ICMP報頭+ICMP數據);UDP和TCP校驗和不僅覆蓋整個報文,而且還有12字節的IP偽首部,包括源IP地址(4字節)、目的IP地址(4字節)、協議(2字節,第一字節補0)和TCP/UDP包長(2字節,包含協議頭和數據)。另外UDP、TCP數據報的長度可以為奇數字節,所以在計算校驗和時需要在最后增加填充字節0(注意,填充字節只是為了計算校驗和,可以不被傳送)。
這里還要提一點,UDP的校驗和是可選的,當校驗和字段為0時,表明該UDP報文未使用校驗和,接收方就不需要校驗和檢查了!那如果UDP校驗和的計算結果是0時怎么辦呢?書上有這么一句話:“如果校驗和的計算結果為0,則存入的值為全1(65535),這在二進制反碼計算中是等效的。”
TCP校驗和示例
由於TCP首部中不包含源地址與目標地址等信息,為了保證TCP校驗的有效性,在進行TCP校驗和的計算時,需要增加一個TCP偽首部的校驗和,定義如下:
struct 
{
    unsigned long saddr;  //源地址

    unsigned long daddr; //目的地址

    char mbz; //強制置空

    char ptcl; //協議類型

    unsigned short tcpl; //TCP長度

}psd_header;

然后我們將這兩個字段復制到同一個緩沖區SendBuf中並計算TCP校驗和:
memcpy(SendBuf, &psd_header, sizeof(psd_header)); 
memcpy(SendBuf+sizeof(psd_header), &tcp_header, sizeof(tcp_header));
tcp_header.th_sum=checksum((unsigned short *)SendBuf, sizeof(psd_header)+sizeof(tcp_header));

 

參考:

圖解TCP/IP

TCP/IP詳解卷一

IP頭校驗和

https://zhidao.baidu.com/question/331155022269467205.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM