如何从 IP 校验和字段计算 Hexa 值?

How to calculate the Hexa value from the IP checksum field?

我有一个无符号的短缓冲区,它包含 IP header 的六进制值。

unsigned short buffer = {45,00,00,4E,4E,05,00,10,80,11,0X00,0X00,0A,00,00,1C,1A,00,00,2F};

我在校验和的位置添加了 0X00 , 0X00,并使用 RFC 1071 - 计算 IP header 校验和 计算校验和。所以它返回一个 unsigned short checksum 值。现在我需要插入到 Ip 缓冲区。

例如 :如果我的 unsigned short checksum value = 55168 并且它的十六进制值 = D780 。现在我需要添加 D780buffer[11]buffer[12] 。我如何转换无符号短校验和值并拆分十六进制值以插入缓冲区?如果它 Hex = D78 ,那么我还需要将 0D78 添加到缓冲区字段。

您可以使用位运算符分隔值

buffer[11] = (checksum >> 8) & 0xff;
buffer[12] = checksum & 0xff;

第一行将校验和右移 8 位,相当于除以 256,然后确保您仅使用 and(&) 获取剩余 8 位 (0xD7) 的信息具有 0xff 的运算符,在二进制表示中等于 1111 1111。 第二行还使用 and 运算符仅保存校验和的最后 8 位,即 0x80。

您可以使用 buffer[11] = (checkSum & 0xFF00) >> 8; buffer[12] = (checkSum & 0xFF) 形式的表达式,但您应该仔细检查您的处理器体系结构是否使用大端或小端形式来表示整数。因此,可能在某些系统上您必须将表达式交换为 buffer[12] = (checkSum & 0xFF00) >> 8; buffer[11] = (checkSum & 0xFF).

见以下代码:

#include <stdio.h>

unsigned short getCheckSum(unsigned short buffer[]) {
    return 0xD780;
}

int main(int argc, const char *argv[])
{
    unsigned short buffer[20] = {0x45,0x00,0x00,0x4E,0x4E,0x05,0x00,0x10,0x80,0x11,0X00,0X00,0x0A,0x00,0x00,0x1C,0x1A,0x00,0x00,0x2F};

    unsigned short checkSum = getCheckSum(buffer);

    buffer[11] = (checkSum & 0xFF00) >> 8;
    buffer[12] = (checkSum & 0xFF);

    for (int i=0; i<20; i++) {
        printf("%02X ", buffer[i]);
    }

    return 0;
}