2010-04-05 82 views
3
unsigned short /* this function generates header checksums */ 
csum (unsigned short *buf, int nwords) 
{ 
    unsigned long sum; 
    for (sum = 0; nwords > 0; nwords--) // add words(16bits) together 
    { 
     sum += *buf++; 
    } 
    sum = (sum >> 16) + (sum & 0xffff); //add carry over 
    sum += (sum >> 16);     //MY question: what exactly does this step do??? add possible left-over 
             //byte? But hasn't it already been added in the loop (if 
             //any)? 
    return ((unsigned short) ~sum); 
} 
  1. 我nwords承擔16位的字的數量問題,而不是8位字節(如果有奇數個字節,nword四捨五入到下一個大),是正確的嗎?說ip_hdr總共有27個字節,那麼nword將是14而不是13,對不對?
  2. 總和=(總和>> 16)+(總和& 0xffff)是加進位16位補全
  3. sum + =(sum >> 16);這一步的目的是什麼?添加剩餘字節?但是,循環中已經添加了剩餘的字節?

謝謝!關於IP校驗碼

+0

可以格式化你的代碼一點,好嗎? – WhirlWind 2010-04-05 19:19:24

+0

有人需要清理它。 :( – Rev316 2010-04-05 19:19:37

+0

'ip_hdr'不能是27個字節,它們必須是4個字節長的倍數,並且長度必須在20到60個字節之間 - '(4 * ip_hdr-> ip_ihl)',因爲'ip_ihl'是一個四位的字段 – Alnitak 2014-11-06 08:46:22

回答

0

你是對的。步驟3將總和(32位長)壓縮成16位無符號短路,這是校驗和的長度。這是出於性能目的,允許一個計算校驗和而不跟蹤溢出直到結束。它在步驟2和步驟3都執行此操作,因爲它可能已經從步驟2溢出。然後它僅返回反轉的低16位和。

這是一個有點清晰: http://www.sysnet.ucsd.edu/~cfleizac/iptcphdr.html

+0

這裏的假設是一個long的長度是32位,而一個short的長度是16位,但是有一些平臺的兩個都不是真的 – 2010-04-05 22:29:38

+0

是的,但這不是平臺無關的代碼;它在內核中,你知道尺寸是什麼,所以這是一個合理的假設。 – WhirlWind 2010-04-06 00:07:44

+0

你可以看到BSD源使用類似的「不可移植」聲明:http://fxr.watson.org/fxr/source /netinet/in_cksum.c – WhirlWind 2010-04-06 00:16:39