【问题标题】:RFC 1071 - Calculating IP header checksum confusion in CRFC 1071 - 在 C 中计算 IP 标头校验和混淆
【发布时间】:2015-06-16 06:05:48
【问题描述】:

我正在尝试使用 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

感谢您的澄清

【问题讨论】:

  • 字节序不匹配?
  • hton 可以解决问题,但 rfc 并没有在这上面浪费任何文字
  • 校验和函数的部分代码。 iphead的声明在哪里?
  • 我添加了上面结构的声明和初始化。前四个字节应该足以证明字节顺序的问题。除了输出之外,校验和函数与 rfc 1071 中的示例相同

标签: c header ip rfc


【解决方案1】:

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

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

打印时,除非另有强制要求,否则前导 0 会被抑制。

所以结果是 0x45 = 69

【讨论】:

  • 所以解决方案是交换字节顺序? sum += htons(* (unsigned short *) (iphead)); ...这样做后它就起作用了。我只是对 rfc 没有在这方面浪费任何文字感到困惑。
  • 出于某种原因...作为 IP 标头中的多字节字段,它将使用网络字节顺序发送,可以理解。
猜你喜欢
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 2015-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多