yd1227

下面摘自《TCP/IP协议簇》的IP头校验和算法:

发送时:

1. 将校验和字段置为0;

2. 将整个首部分为16bit的部分,求和;

3. 取反码,填入到校验和字段中;

接收时:

1. 直接将整个首部分为16bit的部分,求和;

2. 取反码,若结果为0,取合法;否则丢弃;

这上面有两个细节没有描述清楚:

1. 计算时的字节顺序(litter endian和big endian)问题;

2. 取和溢出时的改进计算方法;

根据实验结果,及参考网络上的资料,实际上几乎现有所有的系统对校验和算法已经有点小小的补充,也许《TCP/IP协议簇》这里没有更新罢了,自我安慰吧,如下:

◆当发送IP包时,需要计算IP报头的校验和:

1、  把校验和字段置为0;

2、  对IP头部中的每16bit进行二进制求和;

3、  如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit为0,从而获得一个16bit的值;

4、  将该16bit的值取反,存入校验和字段。

◆当接收IP包时,需要对报头进行确认,检查IP头是否有误,算法同上2、3步,然后判断取反的结果是否为0,是则正确,否则有错。

算法:

        unsigned short CheckSum(unsigned short *_pBuff, int _Size)
        {
            unsigned int ckSum = 0;

            unsigned short *tmpBuff = _pBuff;
            int tmpSize = _Size;

            while (tmpSize > 1)
            {
                ckSum += *tmpBuff ++;
                tmpSize -= sizeof(unsigned short);
            }

            if (tmpSize > 0)
            {
                ckSum += *(unsigned char*)tmpBuff;
            }

            ckSum = (ckSum >> 16) + (ckSum & 0xFFFF); //将高16bit与低16bit相加
            ckSum += (ckSum >> 16); //将进位到高位的16bit与低16bit 再相加

            return (unsigned short)(~ckSum);
        }

关于计算时的字节顺序,一般以网络字节顺序(big endian)为准,但仍然有个十分模糊的地方,就是为什么校验和这个字段不用进行网络转换了,如X86系统,直接以本地字节顺序(litter endian)发送就可以了,这也让我十分纠结。

下面是举例:

    char szBuf[] = {\'\x45\', \'\x00\', \'\x00\', \'\xf4\', \'\x00\', \'\x2e\', \'\x00\', \'\x00\' ,\'\x80\' ,\'\x11\',
                    \'\x00\', \'\x00\', \'\xc0\', \'\xa8\', \'\x09\', \'\x0a\', \'\xc0\', \'\xa8\', \'\x09\', \'\xff\'};
    
    unsigned short SendCkSum = 0x71a5; //这个值不用转换为网络字节顺序,直接以 A5 71填入 

    char szBuf[] = {\'\x45\', \'\x00\', \'\x00\', \'\xf4\', \'\x00\', \'\x2e\', \'\x00\', \'\x00\' ,\'\x80\' ,\'\x11\',
                    \'\xa5\', \'\x71\', \'\xc0\', \'\xa8\', \'\x09\', \'\x0a\', \'\xc0\', \'\xa8\', \'\x09\', \'\xff\'};

    unsigned short RecvCkSum = CheckSum((unsigned short*)szBuf, 20); //这里RecvCkSum为0

分类:

技术点:

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-11-28
  • 2021-08-05
  • 2022-12-23
  • 2021-12-30
  • 2022-12-23
猜你喜欢
  • 2021-12-30
  • 2021-12-30
  • 2021-12-30
  • 2021-12-30
  • 2021-11-11
  • 2021-09-24
相关资源
相似解决方案