以太网的协议有层,而每层都包含有更多的协议。所谓协议,通俗的讲就是通信双方约定的规则。

今天我们介绍一些一个听起来陌生却有很常用的协议,ICMP协议。

—ICMP是(Internet Control Message Protocol)Internet控制报文协议。ICMP协议是一种面向无连接的协议,它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递和网络安全具有极其重要的意义。

ICMP设计的最初目的主要是用于IP层(以太网第三层网络层)的差错报告,一路由器或信宿以一对一的模式向信源报告传输错误的原因。

随着网络的发展,检测和控制能力逐渐被引入到ICMP协议中,使得ICMP协议不仅用于传输差错报告,而且大量用于传输控制报文。

ICMP两级封装,如下图:

ICMP协议与IP协议位于同一层次(IP层),但ICMP报文是封装在IP数据报的数据部分进行传输的。由上图我们可以看出。

TCP/IP协议栈中,ICMP协议位于比IP协议略高的位置。但ICMP不作为单独的独立层次,而只是IP层的一部分。

ICMP协议是IP协议的补充,用于IP层的差错报告,拥塞控制,路径控制以及路由器或主机信息的获取。

ICMP报文由首部和数据段组成。(注:不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报(datagram),在链路层叫做帧(frame)。数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。)


ICMP首部定长为8个字节。前4个字节是通用部分,后4个字节随报文类型的不同有所差异。一般格式如下:

类型(type):8bit,ICMP报文类型。

ICMP报文虽然细分为很多类,但总的来看可分为如图所示的三大类:差错报告,控制报文,和请求应答报文。

代码(code):8bit,报文类型的进一步信息。

由于类型众多,我们以实现PING功能的回应请求与应答报文做出说明。

回应请求与应答报文的目的是对网络进行诊断和测试。请求方(路由器,主机)向某信宿机(主机或路由器)发送一个回应请求,请求的数据区带有发送发给定的数据。

信宿机收到请求以后,根据请求形成回应应答,数据中包含请求所带的数据。

信源机根据应答报文中所带的数据就可以确定两个设备间是否可以正常通信。回应请求与应答不仅可以被用来测试主机或路由器的可达性 ,还可以测试IP协议的工作情况。

如果请求方能够成功收到对请求方的应答,那么不但说明信宿可达,而且说明信源机和信宿机的ICMP协议和IP协议工作正常,同时也说明请求和应答经过的中间路由器能够正常进行路由。

ICMP回应请求与应答报文的格式:

类型“8”,表明回应请求报文,要发送请求报文或者收到了请求报文

类型“0”,表明回应应答报文,收到应答报文或者要发送应答报文

代码:在这种类型中为0;

协议为对标识符和序列号字段进行正式定义,通常标识符和序列号用于匹配请求和应答。标识符一般为发起请求进程的进程ID,回应请求与应答报文的标识符和序列号一致。

标识符和序列号作为首部的其他部分,共占32bit。大部分报文不使用该字段,置0,参数错报告会用到其中的一个字节做指针,请求应答报文对利用该4个字节匹配请求与应答报文。

在使用请求与应答报文时(PING功能)时,可将标识符和序列号随机定义,比如在请求报文中将标识符两个字节定义为0x1234,将序列号两个字节定义为0x4321,那么在接收到应答报文时,相应的两个字节数据是一致的,如果不一致说明应答出错。

校验和(checksum):16bit,ICMP整个报文的校验和。

数据部分:差错报告时,携带原始出错数据的首部和数据的前8个字节,包括了该数据包的关键信息(详见ICMP协议)。

请求与应答报文中,携带请求与应答相关的额外信息。通常由发送方指定数据,接收方原样返回。


计算校验和:

当发送请求时,应将校验和16bit先置0,计算所有数据的校验和之后将16位校验和放到报文的校验和字段。

当发送应答时,应将校验和16bit先置0,将类型改为应答,计算所有数据的校验和之后将16位校验和放到报文的校验和字段。

校验校验和:

当收到请求或应答时,与计算校验和一样重新算一遍,如果全为1,说明正确。

ICMP具体算法:(与IP校验和稍有不同)

为了计算一份数据报的ICMP检验和,首先把检验和字段置为0。然后,对整个ICMP报文中每个16 bit进行二进制反码求和(整个报文看成是由一串16 bit的字组成),结果存在检验和字段中。当收到一份ICMP数据报后,同样对数据报文中每个16 bit进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果数据报在传输过程中没有发生任何差错,那么接收方计算的结果应该为全0。另外ICMP数据报的长度可以为奇数字节,所以在计算校验和时需要在最后增加填充字节0(填充字节只是为了计算校验和,可以不被传送)。

1、把ICMP报文二进制数据以2字节为单位累加起来(以16位计算)。存入32位的变量reg中。

2、若ICMP报文为奇数个字节,会剩下最后一字节。把最后一个字节视为一个2字节数据的高字节这个2字节数据的低字节为0,继续累加。

3、校验和是以16位为单位进行求和计算的,放到32位的变量reg中存储,取reg高16位于低16位继续累加,此时是将之前的进位进行累加。

4、继续去reg高16位和低16位进行累加,这步主要是考虑到上一步加法有进位。

5、对上述结果进行取反,去低16位输出即可作为检验和。

由于上述计算校验和时将进位也计算在内,所以校验校验和时得到的结果应该是0。

举个简单例子,发送端发送A和B数据以及校验和E。

A=1010_1010_1010_1010

B=1001_1001_1001_1001

计算A和B的和:(相加)

C=1_0100_0100_0100_0011

计算进位(累加进位,高16位)

D=0100_0100_0100_0100

计算校验和(按位取反)

E=1011_1011_1011_1011

接收端接收到A和B以及校验和之后,验证校验和:

A=1010_1010_1010_1010

B=1001_1001_1001_1001

E=1011_1011_1011_1011

计算A、B、E的和:

F=1_1111_1111_1111_1110

继续累加进位,高16位为进位

G=1111_1111_1111_1111

计算校验和(按位取反)

H=0000_0000_0000_0000

可以看到,ICMP在计算校验和的过程中将进位加入,所以最终收到数据报文校验校验和的时候,得到的校验和(16位)为0,要想得到16位全为1的结果,对校验校验和按位取反就可以了。

注:在上述算法中,先相加后取反与先取反后相加得到的结果是一样的。


版权所有权归卿萃科技,转载请注明出处

作者:卿萃科技ALIFPGA

原文地址:卿萃科技FPGA极客空间 微信公众号


扫描二维码关注卿萃科技FPGA极客空间


你知道PING功能是怎么实现的吗的更多相关文章

  1. Linux下实现ping功能

    实现ping功能,就肯定要用到ping命令,那么在Linux下ping命令为: ping [-dfnqrRv][-c<完成次数>][-i<间隔秒数>][-I<网络界面&g ...

  2. Java实现ping功能的三种方法及Linux的区分

    前大半部份转自:https://blog.csdn.net/futudeniaodan/article/details/52317650 检测设备的运行状态,有的是使用ping的方式来检测的.所以需要 ...

  3. 如何开放 Azure 虚拟机 Ping 功能

    前言 文章<使用 PsPing & PaPing 进行 TCP 端口连通性测试>中提到,ICMP 协议的数据包无法通过 Azure 的防火墙和负载均衡器,所以不能直接使用 Ping ...

  4. 【虚拟机-网络IP】如何开放 Azure 虚拟机 Ping 功能

    前言 文章<使用 PsPing & PaPing 进行 TCP 端口连通性测试>中提到,ICMP 协议的数据包无法通过 Azure 的防火墙和负载均衡器,所以不能直接使用 Ping ...

  5. C++实现ping功能

    今天接到需求要实现ping的功能,然后网上查了一些资料,对网络编程的一些函数熟悉了一下,虽然还有一些细节不清楚,但是慢慢积累. 要实现这样的功能: 基础知识 ping的过程是向目的IP发送一个type ...

  6. C++实现ping功能<转>

    今天接到需求要实现ping的功能,然后网上查了一些资料,对网络编程的一些函数熟悉了一下,虽然还有一些细节不清楚,但是慢慢积累. 要实现这样的功能: 基础知识 ping的过程是向目的IP发送一个type ...

  7. 如何开启和禁止Linux系统的ping功能

    在日常的网络维护和使用过程中,ping命令是最为常用的一个检测命令,它所使用的是ICMP协议,但是为了保护主机,很多时候我们需要禁止ICMP协议,在这种情况下,终端再使用ping命令检测,服务器是不会 ...

  8. 用socket实现ping功能(记录)

    /* 参考 http://bbs.csdn.net/topics/230001156 原文为win32版本 稍有改动,以适应mac与linux系统 */ #include <stdio.h> ...

  9. Linux C 实现Ping功能的程序.

    ping命令是用来查看网络上另一个主机系统的网络连接是否正常的一个工具.ping命令的工作原理是:向网络上的另一个主机系统发送ICMP报文,如果指定系统得到了报文,它将把报文一模一样地传回给发送者,这 ...

随机推荐

  1. Oracle常见的几种登录方式

    1.运行SQLPLUS工具 C:\Users\csb>sqlplus(回车) (输入账户)system(回车) (输入密码) (回车) 2.直接进入SQLPLUS命令提示符,无用户的登陆 C:\ ...

  2. java父类调用被子类重写的方法

    [转][原文]  1.如果父类构造器调用了被子类重写的方法,且通过子类构造函数创建子类对象,调用了这个父类构造器(无论显示还是隐式),就会导致父类在构造时实际上调用的是子类覆盖的方法(你需要了解jav ...

  3. github上十二款最著名的Android播放器开源项目

    1.ijkplayer 项目地址: https://github.com/Bilibili/ijkplayer 介绍:Ijkplayer 是Bilibili发布的基于 FFplay 的轻量级 Andr ...

  4. python学习笔记(excel+unittest)

    准备先利用之前整理的python自带的unittest框架 整合excel 实现接口自动化测试功能 先看看excel表格设置: 下来是对excel获取的代码: #!/usr/bin/env pytho ...

  5. Java class、Object、Class 的区别

    Java的对象模型中: 所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例. 所有的类都最终继承自Object类,Class是类,那么Class也继承自Obj ...

  6. centos下使用fdisk扩展分区容量大小

    硬盘空间为20G,VMware增加磁盘大小,需要再增加10G空间 扩展完后,重启系统,再次使用fdisk -l查看,会发现硬盘空间变大了: 重新创建分区,调整分区信息 本次实验主要对/dev/sda4 ...

  7. mysql:字符分割,将字符分割成数组

    1.分割函数:SUBSTRING_INDEX('浙江温州-中国电信','-','1') 2.用例(筛选'-'前至少4个汉字的数据) a.数据分布 b.筛选sql   select t.mobile_n ...

  8. softmax实现(程序逐句讲解)

    上一个博客已经讲了softmax理论部分,接下来我们就来做个实验,我们有一些手写字体图片(28*28),训练样本(train-images.idx3-ubyte里面的图像对应train-labels. ...

  9. 解决通用串行总线(USB)控制器有感叹号

    (转自:http://blog.sina.com.cn/s/blog_44190ce10101ejth.html)   通用串行总线控制器:由于其配置信息(注册表中的)不完整或已损坏,Windows ...

  10. tomcat映射物理路径

    <Context path="/woyoubaoweb/upload" docBase="/opt/file/image/woyoubaoweb/upload&qu ...