RFC 1071 - 计算C

时间:2015-06-15 21:12:59

标签: c header ip rfc

我正在尝试使用RFC 1071的示例C代码来计算正确的IP头校验和,但是有一个问题最好用代码描述:

设置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(0x45),它应该是0x4500

澄清的问题

1 个答案:

答案 0 :(得分:0)

前两个字段只有4位长,所以, 在内存中是0x4500。

但是,由于Endian'ness,它被读为0x0045。

打印时,除非另外强制,否则会抑制前导0。

所以结果是0x45 = 69