2014-05-05 150 views
1

我有兩個問題:關於TCP校驗和計算問題

  1. RFC 793指出,校驗應計算在一個96位的僞頭,TCP報頭和數據。僞首部包含源和目標IP地址。這不會破壞保持層單獨的整體思路,因爲現在當網絡層開始使用不同大小的地址時,傳輸層也需要改變。

  2. 在另一個SO帖子中,我找到了下面的java代碼來計算校驗和。

    private long computeChecksum(byte[] buf){ 
        int length = buf.length; 
        int i = 0; 
        long sum = 0; 
        long data; 
    
        // loop through all 16-bit words unless there's 0 or 1 byte left. 
        while(length > 1){ 
         data = (((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF)); 
         sum += data; 
         if((sum & 0xFFFF0000) > 0){ 
          sum = sum & 0xFFFF; 
          sum += 1; 
         } 
         i += 2; 
         length -= 2; 
        } 
    
        if (length > 0){ // ie. there are 8 bits of data remaining. 
         sum += (buf[i] << 8 & 0xFF00); // create a 16 bit word where the 8 lsb are 0's and add it to the sum. 
         if((sum & 0xFFFF0000) > 0) { 
          sum = sum & 0xFFFF; 
          sum += 1; 
         } 
        } 
    
        sum = ~sum; 
        sum = sum & 0xFFFF; 
        return sum; 
    } 
    

有一些事情我不明白爲什麼他們需要的代碼。第一個在:

data = (((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF)); 

什麼是二進制AND的需要?我不明白,因爲buf [i]是一個字節,但被視爲一個int,並向左移8位。不是說已經保證結果如下所示:00000000 00000000 ???????? 00000000.

此外,爲什麼sum和data聲明爲long?就我所見,兩個變量都不會超過17位,所以爲什麼不能使用int?最後他們甚至可以這樣做:sum = sum & 0xFFFF它丟棄除16個最低有效位以外的任何數據。

謝謝!

回答

2

這樣做是否會破壞保持圖層分離的整體思路,因爲現在當網絡層開始使用不同大小的地址時,傳輸層也需要更改。

是的。確實,這就是爲什麼RFC 2460重新定義了IPv6的僞首部:

,其包括來自在其校驗和計算的IP報頭中的 地址的任何傳輸或其它上層協議必須 修改以用於在IPv6 ,以包含128位IPv6地址 而不是32位IPv4地址。 [...]