Как рассчитывается контрольная сумма 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
, Я подтвердил, что мой алгоритм выбирает байты попарно и в правильном порядке, а затем складывает их вместе:
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 ответ
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$