2015-06-15 55 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头中的多字节字段,它将使用网络字节顺序发送,请理解。 –