2015-06-15 62 views
1
計算IP報頭校驗混亂

我試圖通過使用RFC 1071的C語言代碼來計算合適的IP報頭校驗和,但有最好用代碼來描述一個問題:RFC 1071 - 用C

設置了IP報頭:

#include <linux/ip.h> 

typedef struct iphdr tipheader; 

int main(int argc, char **argv) 
{ 
    tipheader * iphead = (tipheader *) malloc(sizeof(tipheader)); 
    iphead->ihl = 5; 
    iphead->version = 4; 
    iphead->tos = 0; 
    iphead->tot_len = 60; 
    .... 
    unsigned short checksum = getChecksum((unsigned short *) iphead, 20); 
} 

校驗功能:

unsigned short getChecksum(unsigned short * iphead, int count) 
{ 
    unsigned long int sum = 0; 
    unsigned short checksum = 0; 

    printf("\nStarting adress: %p\n", iphead); 

    while(count > 1) { 
     sum += * (unsigned short *) (iphead); 
     count -=2; 
     printf("a: %p, content is: %d, new sum: %ld\n", iphead, (unsigned short) *(iphead), sum); 
     iphead++; 
    } 

    if(count > 0) { 
     sum += * (unsigned short *) (iphead); 
    } 

    while(sum >> 16) { 
     sum = (sum & 0xffff) + (sum >> 16); 
    } 

    checksum = ~sum; 

    return checksum; 
} 

遍歷存儲器指向iphead一個無符號短指針顯示以下輸出的第一兩次迭代之後:

Starting address: 0x603090 
a: 0x603090, content is: 69, new sum: 69 
a: 0x603092, content is: 60, new sum: 129 

所以指針起作用「預期」和由2每次迭代增加。 但爲什麼前兩個字節的內容解釋爲69(0×45),其中它應該是0x4500

Thx的澄清

+1

排序不匹配? – fferri

+0

hton可以解決這個問題,但rfc不會浪費任何文字給 –

+0

爲校驗和函數提供的部分代碼。 「iphead」的聲明在哪裏? – Pynchia

回答

0

前兩個字段僅4位長,所以, 在存儲器是0x4500 。

但是,由於Endian'ness,它被讀爲0x0045。

打印時,除非強制否則前導0被抑制。因此結果是0x45 = 69

+0

中的示例相同所以解決方案將交換字節順序? sum + = htons(*(unsigned short *)(iphead)); ...它在這樣做之後起作用。我只是困惑,rfc不會浪費任何文字。 –

+0

出於某種原因......作爲IP頭中的多字節字段,它將使用網絡字節順序發送,請理解。 –