TCP over IPv6的校验和 [英] Checksum of TCP over IPv6

查看:164
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆