你知道PING功能是怎么实现的吗
以太网的协议有层,而每层都包含有更多的协议。所谓协议,通俗的讲就是通信双方约定的规则。
今天我们介绍一些一个听起来陌生却有很常用的协议,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功能是怎么实现的吗的更多相关文章
- Linux下实现ping功能
实现ping功能,就肯定要用到ping命令,那么在Linux下ping命令为: ping [-dfnqrRv][-c<完成次数>][-i<间隔秒数>][-I<网络界面&g ...
- Java实现ping功能的三种方法及Linux的区分
前大半部份转自:https://blog.csdn.net/futudeniaodan/article/details/52317650 检测设备的运行状态,有的是使用ping的方式来检测的.所以需要 ...
- 如何开放 Azure 虚拟机 Ping 功能
前言 文章<使用 PsPing & PaPing 进行 TCP 端口连通性测试>中提到,ICMP 协议的数据包无法通过 Azure 的防火墙和负载均衡器,所以不能直接使用 Ping ...
- 【虚拟机-网络IP】如何开放 Azure 虚拟机 Ping 功能
前言 文章<使用 PsPing & PaPing 进行 TCP 端口连通性测试>中提到,ICMP 协议的数据包无法通过 Azure 的防火墙和负载均衡器,所以不能直接使用 Ping ...
- C++实现ping功能
今天接到需求要实现ping的功能,然后网上查了一些资料,对网络编程的一些函数熟悉了一下,虽然还有一些细节不清楚,但是慢慢积累. 要实现这样的功能: 基础知识 ping的过程是向目的IP发送一个type ...
- C++实现ping功能<转>
今天接到需求要实现ping的功能,然后网上查了一些资料,对网络编程的一些函数熟悉了一下,虽然还有一些细节不清楚,但是慢慢积累. 要实现这样的功能: 基础知识 ping的过程是向目的IP发送一个type ...
- 如何开启和禁止Linux系统的ping功能
在日常的网络维护和使用过程中,ping命令是最为常用的一个检测命令,它所使用的是ICMP协议,但是为了保护主机,很多时候我们需要禁止ICMP协议,在这种情况下,终端再使用ping命令检测,服务器是不会 ...
- 用socket实现ping功能(记录)
/* 参考 http://bbs.csdn.net/topics/230001156 原文为win32版本 稍有改动,以适应mac与linux系统 */ #include <stdio.h> ...
- Linux C 实现Ping功能的程序.
ping命令是用来查看网络上另一个主机系统的网络连接是否正常的一个工具.ping命令的工作原理是:向网络上的另一个主机系统发送ICMP报文,如果指定系统得到了报文,它将把报文一模一样地传回给发送者,这 ...
随机推荐
- 使用Ant和YUICompressor链接合并压缩你的JS和CSS代码
JS代码和CSS代码在上线前要压缩大家应该都是知道的了.记得之前做项目的时候,最后要交差的时候是找了个网站,将JS代码的文件一个一个地复制,粘贴,复制,粘贴. 当时就在想:TMD有没有好一点的方法,劳 ...
- spring boot项目获取application配置文件参数的两种方式
前言:了解过spring boot这个技术的,应该知道spring boot的核心配置文件application.properties,当然也可以通过注解自定义配置文件**.properties的信息 ...
- JavaWeb -- Struts2 模型驱动
1. 模型驱动 示例: 注册表单reg.jsp <%@ page language="java" contentType="text/html; charset=u ...
- Author Agreement
Dear Editor,We the undersigned declare that this manuscript entitled “文章标题” is original, has not bee ...
- D3.js学习笔记(四)—— 使用SVG坐标空间
目标 在这一章,你将要使用D3.js基于一些数据把SVG元素添加到你想要的坐标位置上. 我们的目标就是使用下面的数据集: var spaceCircles = [30,70,110]; 并使用D3.j ...
- EditText实现输入表情
EditText实现输入表情 一.简介 editText是TextView的子类,TextView能用的工具EditText都能用,这里就是editText利用SpannableString的Imag ...
- Python 导出数据from Mysql
环境 Anaconda3 Python 3.6, Window 64bit 目的 从MySQL数据库读取目标表数据,并处理 代码 # -*- coding: utf-8 -*- import pand ...
- 复制文件夹的方法 .net
void CopyDirectory(string SourcePath,string DestinationPath) { //创建所有目录 foreach(string dirPath inDir ...
- MySQL index merge
深入理解 index merge 是使用索引进行优化的重要基础之一. [ index merge] 当where谓词中存在多个条件(或者join)涉及到多个字段,它们之间进行 AND 或者 ...
- sql语句遇到错误: The used SELECT statements have a different number of columns :
这是因为使用union的两个SQL语句产生的记录的表结构不一致. 必须是结构完全一致的记录集合才可以使用UNION. 以上就是两个表的字段不一样,导致,所以大家可以检查下.