LwIP协议栈之ICMP(Internet Message Protocal)协议

在之前主要讲到LWIP了IP层的相关概念(详见本人另外一篇文章:LwIP协议栈之IP协议),其中主要讲解了网络接口(链路层)与IP层(网络层)的数据交互,而数据包是如何从IP层向上级(传输层)传输的并没有介绍,本次就会详细讲解这个过程。这一过程的关键就是今天要介绍的ICMP(网络控制报文协议)协议

1 什么是ICMP协议

  • ICMP( Internet Control Message Protocal)是 Internet控制报文协议,用于在 IP 主机、路由器之间传递控制消息。
  • 控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。
  • 这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。

2 ICMP协议介绍

2.1 报文格式

所有的ICMP报文的前四个字节都是一样的,分别为1字节的类型字段,1字节的代码字段和2字节的校验和字段。如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RIlqKIsM-1597030026382)(images/15.jpg)]

  • 校验和字段的计算覆盖了整个ICMP报文;
  • 类型字段和代码字段唯一确定了该 ICMP 报文属于那种类型:如回显、超时、时间戮请求等等;
2.2 ICMP报文分类
  • ICMP 报文从大的方面来说可以分为 ICMP 查询报文和 ICMP 差错报文。
  • ICMP 查询报文包括 ICMP 回显应答、回显请求、时间戮请求、地址掩码请求等等类型, LWIP 只实现了ICMP 回显应答
  • ICMP 差错报文有目的不可达、超时、重定向等等类型, LWIP 只实现了目的不可达、超时两项 ICMP 处理功能

3 差错报文源码描述

3.1 目的不可达差错报文
  • 目的不可达差错报文在LWIP中用icmp_dest_unreach 函数来描述,该报文的类型字段值应为3,代码字段值应为(0~15);
  • 目前 LWIP 只支持( 0~5), 分别表示网络不可达、主机不可达、协议不可达、端口不可达、需进行分片但设置了不分片位、源站选择失败。
  • 很明显,在 ip_input 函数找不到将该数据包交到哪个上层协议时,应该产生一个协议不可达的差错报文,即代码字段值为 2。

函数原型如下,输入参数为接收到的目标不可达的IP数据包和应该用于填充ICMP头部代码字段的值。

void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)

函数工作过程:

  1. 为要发送数去的 ICMP 数据包申请一个 pbuf 缓冲区,这个缓冲区的长度为上图所述结构的长度与一个 IP 数据报头大小之和(便于直接在已经申请号的包头中填入IP头部数据);
  2. 函数填写ICMP数据包的相关字段,将类型段填充为3,代码段为输入参数t,同时将不可达的IP数据包的IP报头和数据前8个字节拷贝到ICMP数据包相应字段;
  3. 最后计算校验和字段的值,然后调用ip_output函数将组装好的ICMP包发送出去。

ip_output函数通过调用ip_output_if函数完成数据包的发送,它在调用ip_output_if函数前,要先根据发送数据包的目的IP地址找到相应的发送网络接口结构,并将该结构作为调用ip_output_if函数的参数。ip_output_if函数主要是填充IP报头各个字段的值,然后调用netif->output函数将封装好的IP数据包发送出去。

3.2 超时报文

icmp_time_exceeded 函数用于产生一个超时类型的 ICMP 报文。该类型的报文与上面所述的报文有完全相同的报文结构,但类型字段值应为11,代码字段应为0或1,分别代表传输期间生存时间超时和数据组装期间生存时间超时。
icmp_time_exceeded函数的代码流程和内容与 icmp_dest_unreach函数完全一样,只是在填充ICMP报文的类型和代码字段使用了不同的值。

4 查询报文

查询报文在整个产品的设计调试过程中显示出非常重要的作用。即Ping命令,它与ICMP回显应答、请求报文密切相关。
Ping命令:目的是为了测试另一台主机是否可达。该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答。如果不能Ping到某台主机,就不能Telnet或者FTP到那台主机。反过来如果不能Telnet到某台主机,那么通常可以用Ping程序来确定问题出在哪里。
Ping程序还能测出到这台主机的往返时间,以表明该主机距离多远。同时Ping程序也能在数据包的路由过程中记录下路由路径。

报文格式
ICMP 回显请求和回显应答报文格式如下图,回显应答的类型值为 0,回显请求类型值为 8,二者代码字段值均为 0。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VSxLkSGa-1597030026385)(images/16.jpg)]

** 工作流程**:

  1. 若当前的数据包为ICMP回显请求,则函数继续判断该数据包是否为广播或者多播包,对这两种数据包不做处理;
  2. 接下来判断该数据包大小是否小于ICMP回显请求头部长度,若是则丢弃数据包;
  3. 为这个数据包申请IP报头和以太网帧头内存空间,成功后将该 ICMP 包类型字段变为 0,从新计算校验和,并将 IP 报头的源 IP 地址和目的 IP地址交换位置;
  4. 最后将整个数据包利用 ip_output_if 函数将数据包发送出去。

ICMP 回显应答将回显请求中的数据原样返回给源主机,源主机在收到回显应答后,通过处理回显应答中的数据可以得到相关信息,如计算往返时间等。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值