热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LWIP协议栈:ICMP协议

ICMP(InternetControlMessageProtocol),因特网控制报文协议。ICMP协议属于网络层协议,用于在源主机与路由器之间传递控制消息。控制消息对数据报文的

  • ICMP(Internet Control Message Protocol),因特网控制报文协议。ICMP协议属于网络层协议,用于在源主机与路由器之间传递控制消息。控制消息对数据报文的传递有着重要作用,如:网络不通、通信超时等消息。

  • ICMP协议也是一种无连接的不可靠数据报交付协议,协议本身不提供任何的错误检查与恢复机制。

  • ICMP协议的主要功能:

    1)差错通知:反馈数据传递过程出现的错误的信息至源主机;

    2)信息查询:源主机向目标主机查询相关信息。

P.S.:ICMP只能搭配IPv4使用,ICMPv6搭配IPv6使用。


2. ICMP报文


2.1 报文格式

(1)ICMP报文格式

类型:报文的类型,表示产生报文的原因,占8bit;

代码(code):报文的代码,表示产生报文的具体原因,占8bit;

校验和:整个ICMP报文的校验和

(2)ICMP报文封装

ICMP数据报封装在IP数据报中,IP数据报封装在以太网帧中。



2.2 报文类型

ICMP报文分为两大类:差错报告报文、查询报文。



  • 差错报告报文:当目标主机或路由器不能正常处理当前的数据报时,目标主机或路由器会反馈一个差错报告报文到源主机,向源主机表明出差错的具体原因。

  • 查询报文:源主机向目标主机发送信息查询请求,目标主机向源主机作出应答。


2.3 差错报告报文

差错报告报文有6中类型:目的不可达、源站抑制、重定向、超时、参数错误。

(1)目的不可达

网络数据报在传递过程中出错,不能到达目标主机,或到达目标主机后无法传递至上层协议;此时,路由器或目标主机会反馈一个ICMP目的不可达差错报文,通知源主机数据发送失败。

目的不可达报文如下图所示。



  • ICMP首部剩余的4Byte未使用,为全0。

  • IP数据报首部包含了源IP地址和目标IP地址,源主机可通过该信息判断是哪个数据报出现差错。

  • IP数据报数据区域前8Byte包含了传输层协议的“port”字段的值,源主机可以将ICMP报文传递给对应的上层协议处理。

导致目的不可达的原因有多个,其“code”字段值如下图所示。LWIP协议栈只实现了前6种。


(2)源站抑制

当出现网络拥堵,路由器或目标主机会向源主机发送源站抑制报文,同时源主机降低数据报的发送频率。

源站抑制报文的格式和目的不可达报文相同,但其“code”字段为0。

(3)重定向

源主机刚启动时,其路由表中只有一个默认路由,所有数据都会发送至默认路由。当默认路由器发现数据是发送给其他路由器时,默认路由器会反馈一个ICMP重定向报文给 源主机,通知源主机更改路由表。下次发送数据时,通过新路由进行发送,从而提高数据发送效率。

P.S.:LWIP协议栈中未对ICMP重定向报文进行处理。

(4)超时

IP数据报首部的“TTL”字段记录着该数据报的生命值,该数据报每被转发一次,TTL值减1。当路由器转发一个TTL为0的数据报时,会丢弃数据报并向源主机反馈一个ICMP超时报文。另外,IP分片重装未在规定时间完成也会认为它超时。

超时报文的格式和目的不可达报文相同,但其“code”字段有两个,“code = 0”表示生存时间超时,“code = 1”表示IP数据报分片重装超时。

(5)参数错误

网络数据报传输过程中,会对IP数据报首部进行校验。若IP首部校验出错,则该IP数据报会被丢弃,并向源主机发送ICMP参数错误报文。

P.S.:对于携带 ICMP 差错报文的数据报、非第一个分片的分片数据报、具有特殊目的地址的数据报(如环回、多播、广播),即使是出现了差错也不会返回对应的差错报文。


2.4 查询报文

LWIP协议栈中只实现了ICMP回显请求报文、回显应答报文。ping命令使用的是ICMP回显请求报文、回显应答报文。ping是一个应用程序,该程序发送一份 ICMP 回显请求报文给目标主机,并等待目标主机返回 ICMP 回显应答报文。ping命令执行成功,说明链路层、网络层、传输层都能通信正常。

ICMP回显请求报文、回显应答报文格式,如下图所示。



  • “标识符”表示ping程序的编号,同一台主机可同时运行多个ping程序。

  • “序号”表示回显请求的编号,每发送一个回显请求,其值加1。

ping程序执行后,会打印出每个回显请求的序列号及其回显应答,从而可以判断数据报是否丢失、失序、重复。


2.5 报文数据结构

LWIP协议栈中定义了“icmp_echo_hdr”结构体来描述ICMP报文首部的数据结构。同时定义了ICMP报文的“type”、“code”字段的宏,以及对其进行读取和操作的宏。

P.S.:“icmp_echo_hdr”结构体实际上描述的回显报文的首部,但由于ICMP各个类型的报文类似,因此可以用其描述其余报文的数据结构。

PACK_STRUCT_BEGIN
struct icmp_echo_hdr
{
PACK_STRUCT_FLD_8(u8_t type);
//类型
PACK_STRUCT_FLD_8(u8_t code); //代码
PACK_STRUCT_FIELD(u16_t chksum); //校验和
PACK_STRUCT_FIELD(u16_t id); //标志符
PACK_STRUCT_FIELD(u16_t seqno); //序号
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END

3. ICMP报文的发送与接收


3.1 ICMP报文的发送

LWIP协议栈中,只实现了“目的不可达报文、超时报文”的发送。实现代码位置:lwip_2_1_2/src/core/ipv4/icmp.c

(1)发送“目的不可达报文”

调用“icmp_dest_unreach()”函数发送目的不可达报文。当IP层无法向传输层传递数据报,ip_input()函数将会调用此函数发送“目的不可达报文”;当UDP协议无法向应用层传递数据报,udp_input()也将会调用此函数发送“目的不可达报文”。

/**
*   功能:发送目的不可达报文。
* 参数:
* struct pbuf *p:指向引起ICMP报文的IP数据报;
* enum icmp_dur_type t:报文“code”字段的值。
*
*/
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);

(2)发送“超时报文”

调用“icmp_time_exceeded()”函数发送超时报文。当IP数据报TTL值为0时,ip_forward()函数在转发数据报时会调用此函数;或者IP数据报分片重装超时,也将调用此函数发送超时报文。

/**
* 功能:发送超时报文。
* 参数:
* struct pbuf *p:指向引起ICMP报文的IP数据报;
* enum icmp_dur_type t:报文“code”字段的值。
*
*/
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);

icmp_dest_unreach()、icmp_time_exceeded()函数实际调用此函数完成ICMP报文的发送。

/**
* 功能:发送ICMP报文。
*
* 参数:
* struct pbuf *p:指向引起ICMP报文的IP数据报;
* u8_t type:报文“type”字段的值
* u8_t code:报文“code”字段的值。
*
*/
void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);

3.2 ICMP报文的接收

LWIP协议栈中,只对回显报文进行处理。当IP层收到一个ICMP报文,“ip_input()”函数将调用“icmp_input()”函数对其进行处理(只处理回显报文)。

实现代码位置:lwip_2_1_2/src/core/ipv4/icmp.c

/**
* 功能:处理接收到的回显报文,并向源主机发送回显报文应答。
*
* 参数:
* struct pbuf *p:指向引起ICMP报文的IP数据报;
* struct netif *inp:接收ICMP报文的netif。
*
*/
void icmp_input(struct pbuf *p, struct netif *inp);

4. 参考资料

 [1] 野火《LwIP应用开发实战指南》。



推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
author-avatar
松恋崖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有