我查看RFC 1071以获取有关计算IP校验和的一些信息。对于我正在进行的应用程序,我需要计算20字节IP头的IP校验和(无选项)。我的代码如下:
uint16_t calculate_ip_chksum(IP *ip)
{
uint16_t *buf = (uint16_t *) ip;
uint32_t sum = 0;
uint16_t checksum = 0;
int counter = (ip->version & 0xF) * 4;
while (counter > 1)
{
sum += *buf++;
counter -= 2;
}
if (counter == 1)
sum += * (uint8_t *) buf;
while (sum >> 16)
sum = (sum & 0xFFFF) + (sum >> 16);
checksum = ~sum;
return checksum;
}
我定义了一个IP头,如下所示:
typedef struct ip_h
{
uint8_t version;
uint8_t tos;
uint16_t tot_len;
uint16_t id;
uint16_t frag_off;
uint8_t ttl;
uint8_t proto;
uint16_t chksum;
uint32_t src;
uint32_t dst;
} IP;
我理解如何计算校验和的数学,但我不明白为什么我的代码(几乎与RFC完全相同)不起作用。
答案 0 :(得分:0)
您从ip->版本而不是tot_len派生计数器。
int counter = (ip->version & 0xF) * 4;
我假设您希望缓冲区中的总字节数用于校验和。