TCP校验和3.0版本

时间:2016-01-03 21:50:11

标签: c++ tcp network-protocols checksum winpcap

我再次在这里计算TCP校验和。

我需要添加pseudoheader tcp + tcp header + tcp payload。 所有必须以16位的形式添加,如您所知。

在我的代码中,我做的第一件事就是添加到" sumando" (加载校验和的变量)伪头。 之后,我将标头tcp从unsigned short添加到unsigned short。 之后,我将有效负载tcp从unsigned short添加到unsigned short。

最后,我做了tcp校验和的补充,并将其转换为2个字节。它应该是有效的,但它起作用了。

我正在使用winpcap从我的计算机中捕获数据包并重新计算tcp校验和。打开wireshark,你可以看到哪个字节开始字段。

//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];
u_short sumando = 0, sumanda = 0;
bitset<17> controlador;

if (_tamaño < 54)
    return nullptr;

//sumo ip origen e ip destino
for (int i = 26; i < 33; i++){
    sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
    controlador = sumando + sumanda;
    sumando += sumanda;
    if (controlador[16] == 1)
        sumando++;
    i++;
}

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

//sumamos el tcp segment len
sumanda = (u_short)((_datos[16] << 8) + _datos[17]) - ((u_short)((_datos[46] & 0xF0) >> 4) + 
(u_short)(_datos[14] & 0x0F)) * 4;
//cout << "tcpseglen: " << sumanda;
cout << " tamaño: " << _tamaño << " ";
controlador = sumando + sumanda;
sumando += sumanda;
if (controlador[16] == 1)
    sumando++;

//YA TENEMOS SUMADO EL PSEUDO HEADER BIEEEEEN

//sumo todo el campo de cabecera con el checksum a cero
for (int i = 34; i < 53; i++){
    if (i != 50){
        sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
        controlador = sumando + sumanda;
        sumando += sumanda;
        if (controlador[16] == 1)
            sumando++;
    }
    i++;
}
//suponiendo un tamaño de 20 bytes de cabecera siempre..

//sumo todo el payload tcp
for (int i = 54; i < _tamaño; i++){
    if (i + 1 == _tamaño && _tamaño % 2 == 0){//se desborda entonces copiamos solo el ultimo, pero estará ya copiado??
        sumanda = (u_short)_datos[_tamaño - 1];
        controlador = sumando + sumanda;
        sumando += sumanda;
        if (controlador[16] == 1)
            sumando++;
        break;
    }
    sumanda = (u_short)((_datos[i] << 8) + _datos[i + 1]);
    controlador = sumando + sumanda;
    sumando += sumanda;
    if (controlador[16] == 1)
        sumando++;
    i++;
}

u_short original;
original = (_datos[50] << 8) + _datos[51];
sumando += 20;
sumando = sumando & 0xFFFF;
sumando = ~sumando;
//cout << "checksum original: " << original << endl;
//cout << "checksum calculado: " << sumando << endl;
checksum[0] = (sumando >> 8) & 0x00FF;
checksum[1] = sumando & 0x00FF;
return checksum;
}

我将tcp数据包传递给此函数(使用winpcap捕获数据包)。 我将我的tcp校验和与数据包的实际tcp校验和进行比较,这分别是输出,原始tcp cheksum和mine tcp校验和的示例:

6e9==6e9
75a==75a
fe1e==fe1e
8c3e==8c3e
73ed==73ed
8a52==8a52
844d==841d
dad2==dac4
5cde==5cde
e2d1==e2d1

当数据包不是奇数我只需要添加20到我的cheksum得到原始我不知道为什么但它的工作..但我不想明显做,如果数据包是奇数校验和之间的区别是不是常数。

我的代码出了什么问题?请帮忙。

Regardes Kaxper!

0 个答案:

没有答案