TCP over IPv6的校验和 [英] Checksum of TCP over IPv6
问题描述
Hello Guys,
我试图找出TCP over IPV6的校验和。请看下面的鳕鱼
我的尝试:
Hello Guys,
I am trying to find out checksum of TCP over IPV6. Please see the below cod
What I have tried:
char src_addr[] = {
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa1, 0xe4, 0x22, 0x2c, 0x0c, 0x9b, 0x57, 0x22
};
char dest_addr[] = {
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0xd7, 0xc9, 0x57, 0x52, 0xd7, 0x0f, 0xcd
};
_inline unsigned short TOWORD(unsigned int a)
{
return (unsigned short)( ((a>>8)&0x00FFL) + ((a<<8)&0xFF00L) );
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int sum=0;
for(int i = 0; i < 8; i++)
{
sum += *((unsigned short*)(src_addr+i));
}
for(int i = 0; i < 8; i++)
{
sum += *(((unsigned short*)dest_addr+i));
}
unsigned short type = 0x06; // TCP protocol
sum += TOWORD(type);
unsigned int tcplen = 0x1c; // 28 bytes length
sum += ((tcplen <<8) & 0xFFFF) + (tcplen >> 8);
sum = (sum>>16)+(sum&0xffff);
sum += (sum>>16);
sum = (~sum & 0xFFFF);
unsigned short sum1 = sum;
printf("Checksum = %x\n", sum1);
return 0;
}
给出3a96的输出。
但是WireShak显示0x3c3b的校验和。
能帮忙吗?
gives output of 3a96.
However WireShak shows checksum of 0x3c3b.
Can you please help?
推荐答案
这显然是错误的很好的例子为什么施法可能不安全:
This is obviously wrong and a fine example why casting can be unsafe:
for(int i = 0; i < 8; i++)
{
sum += *((unsigned short*)(src_addr+i));
}
您正在投射 char
指针 unsigned short *
。虽然这可能会被使用,但至少你忘了你必须将指针增加2。
我不知道这种情况下的字节顺序,所以一个可能的解决方案可能是其中之一:
You are casting a char
pointer to unsigned short*
. While this might be used, you forgot at least that you have to increment the pointer by two then.
I don't know about the byte order in this case, so a possible solution might be one of these:
for(int i = 0; i < 16; i += 2)
{
sum += src_addr[i] + (src_addr[i+1] << 8U);
// Or this (EDIT: I guess this is it)
sum += (src_addr[i] << 8U) + src_addr[i+1];
}
可能还有其他错误和/或错误的实施。在TCP标头,伪标头和数据上生成IPv6 TCP校验和。
您的代码计算伪标头的校验和。我不知道WireShark报告了哪个校验和但是期望它是完整的校验和。
[/ EDIT]
There may be also other errors and/or a wrong implementation. The IPv6 TCP checksum is generated on the TCP header, the pseudo header, and the data.
Your code calculates the checksum for the pseudo header. I don't know which checksum is reported by WireShark but would expect that it is the complete one.
[/EDIT]
按照以上代码尝试下面的代码建议。
Tried below code as per above suggestion.
char src_addr[] = {
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa1, 0xe4, 0x22, 0x2c, 0x0c, 0x9b, 0x57, 0x22
};
char dest_addr[] = {
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0xd7, 0xc9, 0x57, 0x52, 0xd7, 0x0f, 0xcd
};
_inline unsigned short TOWORD(unsigned int a)
{
return (unsigned short)( ((a>>8)&0x00FFL) + ((a<<8)&0xFF00L) );
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int sum=0;
for(int i = 0; i < 16; i += 2)
{
sum += src_addr[i] + (src_addr[i+1] << 8U);
}
for(int i = 0; i < 16; i += 2)
{
sum += dest_addr[i] + (dest_addr[i+1] << 8U);
}
unsigned short type = 0x06; // TCP protocol
sum += TOWORD(type);
unsigned int tcplen = 0x1c; // 28 bytes length
sum += ((tcplen <<8) & 0xFFFF) + (tcplen >> 8);
sum = (sum>>16)+(sum&0xffff);
sum += (sum>>16);
sum = (~sum & 0xFFFF);
unsigned short sum1 = sum;
printf("Checksum = %x\n", sum1);
return 0;
}
结果为3e9c的校验和
results into checksum of 3e9c
TCP头+数据是失踪。谢谢Jochen。
The TCP header + data was missing. Thanks Jochen.
这篇关于TCP over IPv6的校验和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!