TCP 校验和失败 C++

问题描述 投票:0回答:1

我做了一个计算 TCP 校验和的函数,但它失败了,我不知道为什么。我向该函数提供了我刚刚在网络中捕获的数据包的字节及其大小。

首先我计算伪标头tcp(tcp长度错误,但这不是唯一的问题,因为有时它有cero并且问题仍然存在。

我在这里给你代码:

//http://www.arcesio.net/checksum/checksumTCP.html
u_char* tcp_checksum(const u_char* datos, int tamaño)
{
    u_char *checksum = new u_char[2]();
    uint16_t sumando = 0;
    bitset<17> total;
    bool ack = false;
    if (datos[47] == 0x10) ack = true;

    //sumo ip origen e ip destino
    for (int i = 26; i < 33; i++){
        total = sumando + (uint16_t)((datos[i] << 8) + datos[i + 1]);
        sumando += (uint16_t)((datos[i] << 8) + datos[i + 1]);
        if (total[16] == 1)
            sumando++;
        i++;
    }

    //sumo el byte de ceros y el numero de protocolo TCP
    total = sumando + (uint16_t)(0x06);
    sumando += (uint16_t)(0x06);
    if (total[16] == 1)
        sumando++;

    //aqui sumaría el tcp len no se calcular aún.
    //[IP Total Length] - (([IP IHL] + [TCP Data offset]) * 4)
    //Aquí sumaríamos el TCP len ¿cuanto es?.
    /*total = sumando + (uint16_t)((datos[38] << 8) + datos[39]);
    sumando += (uint16_t)((datos[38] << 8) + datos[39]);
    if (total[16] == 1)
        sumando++;*/

    //sumo todo el campo de cabecera con el checksum a cero
    for (int i = 34; i < 54; i++){
        if (i != 50){
            total = sumando + (uint16_t)((datos[i] << 8) + datos[i + 1]);
            sumando += (uint16_t)((datos[i] << 8) + datos[i + 1]);
            if (total[16] == 1)
                sumando++;
        }
        i++;
    }

    //sumo todo el campo de datos a lo que teníamos.
    for (int i = 55; i < tamaño - 1; i++){
        total = sumando + (uint16_t)((datos[i] << 8) + datos[i + 1]);
        sumando += (uint16_t)((datos[i] << 8) + datos[i + 1]);
        if (total[16] == 1)
            sumando++;
        i++;
    }

    //invertimos y pasamos a dos bytes el resultado.
    sumando = sumando & 0xFFFF;
    sumando = ~sumando;
    checksum[0] = (sumando >> 8) & 0x00FF;
    checksum[1] = sumando & 0x00FF;
    return checksum;
}

我知道 TCP 长度是错误的,但这不是 TCP 校验和实现中唯一的错误,还有什么失败?

问候,谢谢。

c++ tcp checksum
1个回答
0
投票

我建议您自己计算发送和接收缓冲区的校验和。不要依赖于将您自己的校验和函数与“TCP 校验和的比较”、winpcap 或wireshark 等进行比较,因为它们的计算方式可能不同。假设 TCP/IP 正在工作并且低级校验和正常。您可能只是想检查您发送/接收的数据是否损坏。

char64_t ComputeChecksum ( char* buf, int len ) {
char64_t 总和 = 0;
 对于 (int n=0; n < len; n++) {
   sum = sum + char64_t(* (无符号字符*) buf);
   缓冲区++;
  }
返回总和;
}

printf("%d 字节, chksum %lld “,len,chksum);

在发送缓冲区上的“send”之前以及在重组完成的缓冲区上的“recv”之后使用它。

© www.soinside.com 2019 - 2024. All rights reserved.