C++ TCP校验和计算出错

C++ TCP校验和计算出错,c++,networking,tcp,network-programming,C++,Networking,Tcp,Network Programming,我正在尝试获取正确的TCP校验和,但失败了。我使用C++,我用WiPCAP获取本地网络的数据包,我尝试计算它们的TCP校验和(我已经把正确的过滤器只得到TCP包)。但是,当我将计算出的校验和与wireshark tcp校验和进行比较时,它们并不相同 这是我用C++做的代码,它使用位图来检测位携带。 u_char* tcp_checksum(const u_char* data, int size) { u_char *checksum = new u_char[2](); uin

我正在尝试获取正确的TCP校验和,但失败了。我使用C++,我用WiPCAP获取本地网络的数据包,我尝试计算它们的TCP校验和(我已经把正确的过滤器只得到TCP包)。但是,当我将计算出的校验和与wireshark tcp校验和进行比较时,它们并不相同

这是我用C++做的代码,它使用位图来检测位携带。

u_char* tcp_checksum(const u_char* data, int size)
{
    u_char *checksum = new u_char[2]();
    uint16_t sumando = 0;
    bitset<17> total;

    //add ip src and ip dst
    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++;
    }

    //add el zero byte and number of protocol
    total = sumando + (uint16_t)(0x06);
    sumando += (uint16_t)(0x06);
    if (total[16] == 1)
        sumando++;

    /*here I should add the tcp length to complete the tcp pseudo header but i    didnt add anything because I dont know to calculate the tcp len correctly but its not a problem because a lot of times is cero and the tcp still failing.*/

    //okay we have just calculated the pseudoheader.

    //add all tcp header except the 2 bytes of the checksum (20 bytes normally)
    for (int i = 34; i < 54; i++){
        if (i != 50 && i != 52){//no sumo ni padding ni checksum.
            total = sumando + (uint16_t)((datos[i] << 8) + datos[i + 1]);
            sumando += (uint16_t)((datos[i] << 8) + datos[i + 1]);
            if (total[16] == 1)
                sumando++;
        }
        //
        if (i == 52) break;
        i++;
    }


    //add the tcp payload in 16 bits each adding.
    for (int i = 55; i < tamaño - 1; i++){//tamaño - 1
        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++;
    }
    if (tamaño % 2 == 0){
        total = sumando + (uint16_t)((0x00 << 8) + datos[tamaño]);
        sumando += (uint16_t)((0x00 << 8) + datos[tamaño]);
        if (total[16] == 1)
            sumando++;
    }

    //i get the complementary and i divided the u_short (16 bits) (uint16_t) in 2 bytes which i return
    sumando = sumando & 0xFFFF;
    sumando = ~sumando;
    checksum[0] = (sumando >> 8) & 0x00FF;
    checksum[1] = sumando & 0x00FF;
    return checksum;
    }
u_char*tcp_校验和(const u_char*data,int size)
{
u_字符*校验和=新u_字符[2]();
uint16_t sumando=0;
位集总数;
//添加ip src和ip dst
对于(int i=26;i<33;i++){

total=sumando+(uint16_t)((datos[i]不要将您的结果与wireshark进行比较,至少在不关闭的情况下是如此


通过libpcap/winpcap捕获的数据包的校验和是由网络接口卡执行的校验和卸载造成的。

您不能将您的校验和代码与wireshark在用户空间中的工作进行比较,或者检查linux内核,看看它是如何完成的吗?这不是问题,因为我已经读到了“校验和卸载”的内容也会影响IP校验和,在本例中,我使用相同的方法计算了IP校验和,结果成功。问题出在代码中,因此请关注代码,不要关注不存在的问题。我的代码是错误的,我在这里发布是为了更正它,而不是谈论“校验和卸载”当我的代码有100个错误没有被纠正时。你遵循RFC了吗?请参阅(发布)这不是问题,因为我已经读到“校验和卸载”也会影响IP校验和,在本例中,我使用相同的方法计算了IP校验和,结果成功。问题出在代码中,因此请关注代码,不要关注不存在的问题。我的代码是错误的,我在这里发布是为了更正它,而不是谈论“校验和卸载”当我的代码有100个未更正的错误时。
printf("%x%x==", pkt_data[50], pkt_data[51]);
u_char *c = new u_char[2]();
c= tcp_checksum(pkt_data, header->caplen);
printf("%x%x\n", c[0], c[1]);
cout << endl;
delete c;