icmp报文校验算法

icmp报文校验算法备忘用检验和算法在TCP/IP协议族中是比较常见的算法。IP、ICMP、UDP和TCP报文头部都有校验和字段,不过IP、TCP、UDP只针对首部计算校验和  而ICMP对首部和报文数据一起计算校验和。检验和算法可以分成两步来实现。首先在发送端,有以下三步:1.把校验和字段置为0。2.对需要校验的数据看成以16bit为单位的数字组成,依次进行二进制求和。3.将上一步的求和结果取反,存入校验和字

大家好,又见面了,我是你们的朋友全栈君。

备忘用

检验和算法在 TCP/IP 协议族中是比较常见的算法。IP、ICMP、UDP和TCP报文头部都有校验和字段,不过IP、TCP、UDP只针对首部计算校验和

  而 ICMP 对首部和报文数据一起计算校验和。

检验和算法可以分成两步来实现。

首先在发送端,有以下三步:

1.把校验和字段置为0。

2.对需要校验的数据看成以16bit为单位的数字组成,依次进行二进制求和。

3.将上一步的求和结果取反,存入校验和字段。

其次在接收端,也有相应的三步:

1.对需要校验的数据看成以16bit为单位的数字组成,依次进行二进制求和,包括校验和字段。

2.将上一步的求和结果取反。

3.判断最终结果是否为0。如果为0,说明校验和正确。如果不为0,则协议栈会丢掉接收到的数据。

从上可以看出,归根到底,校验和算法就是二进制反码求和。由于先取反后相加与先相加后取反,得到的结果是一样的,所以上面的步骤都是先求和后取反。

下面用C语言来实现校验和算法,代码如下:

/** * addr 指向需校验数据缓冲区的指针 * len 需校验数据的总长度(字节单位) ***下面的addr是icmp报文结构(strcut)的地址,被强制转换成了unsigned short, 32*位机子上是16位,两字节,所以每次加下地址都加了16位的数据*** */



unsigned short checkSum(unsigned short *addr, int len){
    unsigned int sum = 0;  
    while(len > 1){
        sum += *addr++;
        len -= 2;
    }

    // 处理剩下的一个字节
    if(len == 1){
        sum += *(unsigned char *)addr;
    }

    // 将32位的高16位与低16位相加
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);

    return (unsigned short) ~sum;
}

上面的代码首先定义了一个32位无符号整型的变量sum,用来保存16bit二进制数字相加的结果,由于16bit相加可能会产生进位,所以这里使用32位变量来保存结果,其中高16bit保存的是相加产生的进位。

然后下面的 while 循环,对数据按16bit累加求和。

接下来的if语句判断是否还剩下8bit(一字节)。如果校验的数据为奇数个字节,会剩下最后一字节。把最后一个字节视为一个2字节数据的高字节,这个2字节数据的低字节为0,继续累加。

之后的两行代码作用是将 sum 高16bit的值加到低16bit上,即把累加中最高位的进位加到最低位上。(sum >> 16)将高16bit右移到低16bit,(sum & 0xffff)将高16bit全部置为0。注意,这两步都不会改变sum原来的值。

进行了两次相加可以保证 sum 高16bit都为0,没有进位了。

最后取反,并返回。

扩展:

为什么使用二进制反码求和,而不是原码或补码呢?

这是因为,使用反码计算校验和比较简单和快速。对于网络通信来说,最重要的就是效率和速度。

以上转载自实验楼:
c语言实现ping程序—感谢课程教师tianji

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138820.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SpringBoot——关于Cache缓存获取值后修改的问题「建议收藏」

    SpringBoot——关于Cache缓存获取值后修改的问题「建议收藏」SpringBoot——关于Cache缓存获取值后修改的问题

    2022年4月23日
    38
  • QT设置活动窗口「建议收藏」

    QT设置活动窗口「建议收藏」QT设置活动窗口遇到一个QT窗口问题记录下,已经显示的窗口被其他窗口遮挡。再调用show无法将窗口激活显示到最前面。解决方式如下:if(!isActiveWindow())//判断是否是活动窗口{activateWindow();//设置成活动窗口}这样窗口就会被激活。…

    2025年8月11日
    5
  • 使用fiddler对手机APP进行抓包

    使用fiddler对手机APP进行抓包在做手机或移动端APP的接口测试时,需要从开发人员那里获取接口文档,接口文档应该包括完整的功能接口、接口请求方式、接口请求URL、接口请求参数、接口返回参数。如果当前项目没有接口文档,则可以使用fiddler对APP进行抓包确认。在手机上对APP进行操作,然后在Fiddler中可以抓取对应的网络交互信息(一个功能中可能设计多个接口的交互)。在抓取的信息中可以看到接口请求方式、接口请求URL、接口请

    2022年5月16日
    86
  • Hadoop安装与配置详细教程「建议收藏」

    Hadoop安装与配置详细教程「建议收藏」【确保服务器集群安装和配置已经完成!】前言请根据读者的自身情况,进行相应随机应变。我的三台CentOS7服务器:主机:master(192.168.56.110)从机:slave0(192.168.56.111)从机:slave1(192.168.56.112)每一个节点的安装与配置是相同的,在实际工作中,通常在master节点上完成安装和配置后,然后将安装目录复制到其他节点就可以,…

    2022年5月31日
    50
  • 搭建邮件服务器,过程非常简单「建议收藏」

    搭建邮件服务器,过程非常简单,只需几个步骤即可。通常在Linux搭建邮件服务器是需要安装很多软件和配置文件的,所以我们可以使用一个开源邮件服务器软件来搭建的。

    2022年4月10日
    118
  • GoLand 2021.5 x64 激活码【在线注册码/序列号/破解码】

    GoLand 2021.5 x64 激活码【在线注册码/序列号/破解码】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月18日
    67

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号