TCP校验和计算出错
TCP checksum calculation goes wrong
我正在尝试获取正确的TCP校验和,但失败了。我使用C++,我用winpcap获取本地网络的数据包,并尝试计算它们的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;
}
好吧,当我尝试在实际的tcp校验和字节和我的tcp校验之间进行比较时,它不一样:
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%xn", c[0], c[1]); cout << endl; delete c;
我得到不同的字节,通常数据包tcp的字节51和52属于tcp校验和。当我输出它们时,它们是不一样的。
不要将您的结果与wireshark进行比较,至少不要在不关闭校验和卸载的情况下进行比较。
由于网络接口卡执行校验和卸载,通过libpcap/winpcap捕获的数据包的校验和通常是错误的。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 读取文件的最后一行并输入到链接列表时出错
- 计算字符串中字符的出现次数时出错
- 计算选择排序中的比较次数时出错
- 在另一台计算机上打开 Visual Studio 项目的.exe时出错
- 在部署计算机上运行 QDB2 驱动程序时出错
- 用C++计算小双精度数时出错
- TCP校验和计算出错
- 计算数组平均值时出错
- 计算 e^x 的近似值时出错
- 计算继承方法时出错
- 本征逆矩阵计算出错
- 使用EXPECT_EQ计算双精度或浮点数的和时出错
- 我在计算带有静态变量的对象总数的程序中出错