热门标签 | 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应用开发实战指南》。



推荐阅读
  • HSRP热备份路由器协议的应用及配置
    本文介绍了HSRP热备份路由器协议的应用及配置方法,包括设计目标、工作原理、配置命令等。通过HSRP协议,可以实现在主动路由器故障时自动切换到备份路由器,保证网络连通性。此外,还介绍了R1和R2路由器的配置方法以及Sw1和Sw2交换机的配置方法,最后还介绍了测试连通性和路由追踪的方法。 ... [详细]
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了如何使用iptables添加非对称的NAT规则段,以实现内网穿透和端口转发的功能。通过查阅相关文章,得出了解决方案,即当匹配的端口在映射端口的区间内时,可以成功进行端口转发。详细的操作步骤和命令示例也在文章中给出。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了网络编程的要点,包括InetAddress类获取IP地址的方法,IP地址的定义和表示方法,IPv4和IPv6的区别,以及网络通信协议中的端口和协议类型。 ... [详细]
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社区 版权所有