ipv4校验和计算

发布时间:2020-07-31 18:03:21 作者:1406404036
来源:网络 阅读:2259

ipv4校验和的计算

原理:

计算方法一:除去校验和的两位,将其他的位相加:45+00+00+3c+55+81+00+00+40+01+ac+1c

0f+0d+ac+1c+0f+0e=

计算方法二:


校验和(checksum)算法,简单的说就是16位累加的反码运算:

计算函数如下:

我们在计算时是主机字节序,计算的结果封装成IP包时是网络字节序,注意这两者之间的区别,我们在从IP包里读取要转化为主机字节序,往IP包里存入时要转化为网络字节序在存入。

UINT32 Checksum(UINT32 cksum, VOID*pBuffer, UINT32 size)

{

   INT8 num = 0;

   UINT8 *p = (UINT8 *)pBuffer;

 

   if ((NULL == pBuffer) || (0 == size))

    {

       return cksum;

    }

  

   while (size > 1)

    {

       cksum += ((UINT16)p[num] << 8 & 0xff00) | (UINT16)p[num + 1]& 0x00FF;

/*2个字节累加,先取网络字节序低位左移8位(变成主机字节序高位),与(加)上 网络字节序中的高位(主机字节序地位),即网络字节序要先变成主机字节序在进行累加,*/

       size  -= 2;

       num   += 2;

    }

  

if (size > 0)

//如果长度为奇数

    {

       cksum += ((UINT16)p[num] << 8) & 0xFFFF;

//如果总的字节数为奇数,则最后一个字节单独相加

       num += 1;

    }

 

   while (cksum >> 16)

    {

       cksum = (cksum & 0xFFFF) + (cksum >> 16);

//累加完毕将结果中高16位再加到低16位上,重复这一过程直到高16位为全0

    }

  

   return cksum;

}

 

注意:UINT32 cksum的类型,这里是4个字节的,防止在累加的过程中,数据溢出,(例如 0xFF 累加时就会内存溢出)

 

详细的计算过程和原理如下

一:ip 头 的计算:

直接对头部数据进行累加(不包括原来的checksum值):

1、ipv4包头

 

       ipHeadLen  =(pIpHeader->ver_ihl & 0x0F) << 2;

在ipv4 头中,版本类型和头长度加在一起是1 个字节(8位),各占4位,版本类型在前,长度在后,所以要取长度只能取低4 位,

       pIpHeader->chksum = 0;

因为不包括原来的checksum值,所以在每次计算前先把checksum的值置0,然后计算

       sum = Checksum(0, (VOID *)pIpHeader, ipHeadLen);

对整个ip包头的累加

       pIpHeader->chksum = HTONS((UINT16)(~sum));

结果为计算值的反码,(别忘转化为网络字节序)


推荐阅读:
  1. IP地址之IPv4
  2. IP的校验和算法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

网络 return 计算方法

上一篇:利用Azure Backup备份虚拟机之十:监视Azure 备份工作负载

下一篇:Oracle 11g正确删除归档日志方法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》