如何计算ospf校验和?

时间:2014-11-28 05:10:23

标签: c checksum ospf

我无法计算出准确的校验和。我的路由器正在拒绝我的Hello消息。这是十六进制的包(从ospf头开始)

                                           vv vv <-- my program's checksum
0000   02 01 00 30 c0 a8 03 0a 00 00 00 00 f3 84 00 00  ...0............
0010   00 00 00 00 00 00 00 00 ff ff ff 00 00 0a 00 01  ................
0020   00 00 00 28 c0 a8 03 0a c0 a8 03 0a              ...(........

Wireshark调用0xf384伪造,并说预期值为0xb382。我已经确认我的algorythm成对并按正确的顺序选择字节然后将它们加在一起:

0201 + 0030 + c0a8 + ... + 030a

无需担心身份验证。我们甚至没有教过如何设置它。最后,这是我计算校验和的注意事项:

OspfHeader result;

result.Type = type;
result.VersionNumber = 0x02;
result.PacketLength = htons(24 + content_len);
result.AuthType = htons(auth_type);
result.AuthValue = auth_val;
result.AreaId = area_id;
result.RouterId = router_id;

uint16_t header_buffer[12];
memcpy(header_buffer, &result, 24);

uint32_t checksum;
for(int i = 0; i < 8; i++)
{
    checksum += ntohs(header_buffer[i]);
    checksum = (checksum & 0xFFFF) + (checksum >> 16);
}

for(int i = 0; i + 1 < content_len; i += 2)
{
    checksum += (content_buffer[i] << 8) + content_buffer[i+1];
    checksum = (checksum & 0xFFF) + (checksum >> 16);
}

result.Checksum = htons(checksum xor 0xFFFF);

return result;

我不确定我到底在哪里搞砸了。有线索吗?

1 个答案:

答案 0 :(得分:0)

Mac_3.2.57$cat ospfCheckSum2.c
#include <stdio.h>

int main(void){

    // array was wrong len
    unsigned short header_buffer[22] = {
        0x0201, 0x0030, 0xc0a8, 0x030a,
        0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000,
        0xffff, 0xff00, 0x000a, 0x0001,
        0x0000, 0x0028, 0xc0a8, 0x030a,
        0xc0a8, 0x030a
    };
    // note ospf len is also wrong, BTW
    
    // was not init'd
    unsigned int checksum = 0;

    // was only scanning 8 vs 22
    for(int i = 0; i < 22; i++)
    {
        checksum += header_buffer[i];
        checksum = (checksum & 0xFFFF) + (checksum >> 16);
    }
    
    // len not odd, so this is not needed
    //for(int i = 0; i + 1 < content_len; i += 2)
    //{
    //    checksum += (content_buffer[i] << 8) + content_buffer[i+1];
    //    checksum = (checksum & 0xFFF) + (checksum >> 16);
    //}
    
    printf("result is %04x\n", checksum ^ 0xFFFF); // no "xor" for me (why not do ~ instead?)

    // also: where/what is: content_len, content_buffer, result, OspfHeader 

    return(0);
}
Mac_3.2.57$cc ospfCheckSum2.c
Mac_3.2.57$./a.out 
result is b382
Mac_3.2.57$