谈ICMP
- 作者: 雪山肥鱼
- 时间:20211026 22:30
- 目的: ICMP 回顾
# 为什么需要ICMP
# ICMP报文种类
## 报文格式
### 错误类型
## 查询
# 检验和
# ping & traceroute
# ICMP软件包
## 输入模块
## 输出模块
为什么需要ICMP
IP协议是不可靠和无连接的数据交付,只是说尽最大努力交付。
IP并不考虑差错检验和差错控制
所以IP协议有两个缺点
- 缺少差错控制
- 缺少辅助机制
暴露的问题:
如果路由器找不到可到达最后终点的路由器,该怎么办?
或者因生存时间字段值为0 而必须丢弃数据报时,该怎么办
如果最终目的主机在预先设定的时间内没收全数据报分片,因而必须把已接收到的分片全部丢掉,该怎么办?
以上所出的问题,IP协议都没有内建机制通知发出该数据的主机。主机应该根据这些错误,做出反应,判断对端是否还活跃。
ICMP 就是为了补偿者两个缺点设计的。是IP协议的伴侣
ICMP的位置于arp位置相反,成对角线,出于传输层和网络层之间。但其本身定是出于网络层的位置
因为是IP伴侣的关系,其实他是塞到IP数据报中的。
ICMP报文结构.png
由上图可知,dpdk中 icmp解包 是要先解IP层的。具体见<<谈ARP>>这篇文章
ICMP 报文种类
- 差错报文
报告了路由器or 主机 在处理IP报时可能遇到的问题 -
查询报文
成双成对的出现,帮助主机或者网络管理员从某个路由器或对方主机那里获取特定的信息。
ICMP报文.png
报文格式
ICMP报文格式.png与上一节的表格进行匹配。
ICMP不能纠错,只能见到那的报告差错。
差错纠正留给更高层的协议去做
ICMP总是把差错报文报告给最初的数据源 错误种类.png 差错报文的数据字段内容.png
由此看出 ICMP分组包含了数据报的前8个字节,即端口信息。
错误类型
以下错误都是ICMP
- 终点不可达<desitnation-unreachable message>
根据错误代码查看原因 - 源点抑制
IP协议是无连接协议,在产生数据报源主机和转发数据报的路由器以及处理数据报的目的主机之间没有任何通信。这种缺乏通信则会引起缺乏流量控制和拥塞控制。
IP协议中没有流量控制或者拥塞控制
当路由器或主机因拥塞而丢弃数据报时,它就像该数据报的源头发送源点抑制的报文,这是一种icmp报文!
作用:
- 通知源点,数据包已被丢弃
- 警告源点,出现了拥塞,需要放慢发送
- 目的主机拥塞时,每丢掉一个包,就会发送一个源点抑制报文。
- 没有机制告诉源点,拥塞得到缓解,只有源点自己判断,收到的抑制报文少了。才会提高发送速率。
- 1v1 Nv1 都可能产生拥塞。
1v1 源高速发包。路由器无法处理,则抑制报文很有用
Nv1 有的快有的慢,则抑制 报文并不一定有用,因为路由器,不知道谁发的快,谁发的慢。
- 超时
- TTL 为0.
- 其中一个分片没到达目的,目的主机回启动一个计时器,到点还没来,则丢掉所有收到的分片,向源头发送一个超时报文。
- 参数问题
某个字段有二义性 -
改变路由
找到更合适的路由器IP地址。
主机不参与路由更新,只有路由器之间时动态更新的。主机只跟新路由表。
找到更合适的路由.png
改变路由虽然时一种差错报文,但与其他的差错报文不同。这种情况下路由器不会丢弃报文。而是将数据包转发给何时的路由器
查询
-
回送请求与回答
诊断用的,确定两个主机之间能否被彼此通信
这对echo,源头向目标节点发送会送请求报文。并且在icmp的可选数据字段包含一个报文,这个报文必须与由目的节点返回的回答报文中的内容一模一样。
标识符通常与发起请求的进程ID是一致的。
图片.png -
时间戳请求与回答
时间戳请求回答.png
确定IP数据报在两个及其之间来回所需的往返时间。
也可用于同步两个及其的时钟 -
源点生成时间戳请求报文。
- 原始时间: 源点发包时的时间戳 -- A
- 接受时间: 0
- 发送时间: 0
- 目的回答报文
- 原始时间:A
- 接受时间: 收包时候的 时间戳 B
- 发送时间: 发包时候的 时间戳 C
发送时间 = B - A
接收时间 = 分组返回时间 - 源头送时间
往返时间 = 发送时间 + 接收时间
只有当源点和目的地的时钟是同步的,发送时间和接收时间才是准确的,但往返时间一直都是准确的,因为往返时间计算出现了两次,做差抵消掉了
举例:
注意时间差的公式。用来同步。可以发现例子中
时间差 = 59 -(46+10) = 3
所以两台机器相差3ms
检验和
发送方 算出 检验和 A
接收方 反算 检验和 A, 如果检验和 A 为 0 ,则通过。
ping & traceroute
工具
traceroute 路由线路
ICMP 软件包
image.png输入模块
ICMP_Input_Module(ICMP_Packet)
{
if(类型为请求)
{
产生回答报文
发送这个回答报文
}
if(类型指定的是一个噶便路由报文)
{
修改路由表
}
if(类型指定的是其他差错报文)
{
把情况上报给适当的源协议
}
返回
}
输出模块
输出模块负责高层协议或IP协议的要求,创建请求报文、查询报文、差错报文。
输出模块接收 来自 IP UDP TCP 的请求发送一个ICMP差错报文。若是来自IP,则输出模块必须首先检查这个
输出模块还可以从应用程序处收到发送ICMP某个请求报文的要求。
请求是否被允许。四种情况是不会创建ICMP报文的。
- 携带ICMP差错报文的IP分组
- 被分片的IP分组
- 多播IP分组
- 以及IP为 0.0.0.0 或 127.x.y.z的IP分组。
ICMP_Output_Module(要求)
{
if(要求定义的是一个差错报文)
{
if(从IP来的,并且是进制的)
{
返回
}//end
if(要求是一个有效的改变路由报文)
{
返回
}//end
产生一个差错报文
}//end
if(要求定义的是一个请求)
{
产生一个请求报文
}
发送这个报文
}//end mod
dpdk中现在只接触到 ICMP echo 类型的报文。