我做了一个函数来计算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校验和的唯一错误,还有什么失败?
问候,谢谢。