当前位置: 首页 > news >正文

LwIP下ICMP协议浅析

目录

  • 1 ICMP协议
    • 1.1 工作机制
    • 1.2 ICMP 的实际应用场景
  • 2 ICMP协议在嵌入式系统中的应用
    • 2.1 差错报告报文 (Error Reporting)
    • 2.2 询问/查询报文 (Query Messages)
    • 2.3 LwIP上ICMP功能具体实现

1 ICMP协议

ICMP(Internet Control Message Protocol,互联网控制消息协议)是TCP/IP协议族中一个非常重要的网络层子协议。如果把 IP 协议比作负责寄送包裹的“快递员”,那么 ICMP就是快递公司的“异常反馈与客服系统”。IP协议只负责尽最大努力去传递数据包,但它本身并不保证送达,也不会在出错时主动告诉你。而ICMP的核心作用,就是在数据包传输过程中出现差错或需要传递网络状态时,在主机和路由器之间传递控制消息。

1.1 工作机制

ICMP报文并不是直接交给下层数据链路层的,而是会被封装在IP数据报内部,作为IP数据包的数据部分进行传递。每一个ICMP报文都包含三个关键字段,用来标识具体的情况:
a. 类型 (Type):表示大类的差错或查询类型。
b. 代码 (Code):对类型进行更细致的划分(例如“不可达”是因为网络不通、主机关闭还是端口未监听)。
c. 校验和 (Checksum):用于检验报文在传输过程中是否损坏。
在实际应用中,ICMP的功能主要分为两大类:差错报告报文和查询报文。

1.2 ICMP 的实际应用场景

除了底层的自动报错机制,ICMP在日常网络管理中有着非常直观的应用:
1)Ping命令(网络连通性测试):通过发送ICMP回送请求来测试本地主机是否能与另一台主机交换数据,是排查网络故障的第一步。
2)Traceroute/Tracert命令(路由追踪):利用ICMP的“超时”机制。该命令故意发送一系列TTL值逐渐递增(1, 2, 3…)的数据包,迫使路径上的每一个路由器在TTL耗尽时返回超时报文。通过收集这些报文,就能完整描绘出数据包从源到目的地所经过的每一跳路径。

2 ICMP协议在嵌入式系统中的应用

LwIP作为一个面向嵌入式系统的轻量级协议栈,并没有实现ICMP的所有标准类型,而是聚焦于最核心的差错报告和网络诊断功能,标准的 ICMP 包含重定向、源站抑制、时间戳等报文,但在 LwIP 中通常为了节省资源而不做处理或直接忽略。

2.1 差错报告报文 (Error Reporting)

当IP数据报在网络传输中出现问题(如无法到达目的地)时,路由器或目标主机会通过ICMP 向源主机发送差错报文。LwIP主要实现了以下两种最常用的差错报文:
1)目的不可达 (Destination Unreachable, Type 3):
a触发场景:当数据包找不到对应的路由、目标主机关闭、或者目标端口没有程序监听时触发。
LwIP 的实现细节:LwIP会根据具体错误返回不同的代码(Code),例如 端口不可达(UDP 包发到了一个未绑定的端口)、协议不可达(IP头部指定的上层协议不存在)或 需要分片但设置了不分片 等。
2)超时 (Time Exceeded, Type 11):
触发场景:最常见的是 IP 头部的TTL(生存时间)字段减为 0。每经过一个路由器TTL会减 1,当它为 0 时,路由器会丢弃该包并回传超时报文。这常用于traceroute路由追踪工具。
底层原理:当LwIP触发这些差错时,会调用内部的icmp_dest_unreach() 或icmp_time_exceeded() 函数。这些函数会将引起差错的原始 IP 首部 + 原始数据包的前8字节数据封装在新的ICMP报文中发回给源主机,以便源主机判断是哪个应用或连接出了问题。

2.2 询问/查询报文 (Query Messages)

1)回送请求与应答 (Echo Request/Reply, Type 8 / Type 0):
这是大家最熟悉的Ping命令的核心。源主机发送Type 8的请求,目标主机收到后回复Type 0的应答。如果能收到应答,说明网络链路是通的。
LwIP的处理逻辑:LwIP 内部会自动处理接收到的Echo请求,并构造一个Echo应答包原路返回,无需用户编写额外的业务代码。

2.3 LwIP上ICMP功能具体实现

在STM32等嵌入式设备上,利用LwIP实现Ping功能(即主动向外发送ICMP请求)是非常常见的需求,常用于设备上线后的网络自检或与上位机的心跳保活。LwIP默认提供了底层的ICMP处理能力,但没有直接提供一个现成的“Ping应用程序”。我们需要利用LwIP的Raw API(原始 API) 来自己实现一个简单的Ping客户端。步骤如下:
1)创建 Raw PCB:使用raw_new(IP_PROTO_ICMP) 创建一个专门用于ICMP协议的协议控制块。
2)绑定接收回调:注册一个回调函数,当接收到ICMP应答包(Type 0)时,由该函数进行处理(比如点亮 LED或打印RTT往返时间)。
3)构造并发送请求:手动填充ICMP首部(设置 Type=8, Code=0, 标识符和序列号),计算校验和,然后通过raw_sendto()发送出去。
简版代码如下:

#include"lwip/raw.h"#include"lwip/icmp.h"#include"lwip/inet_chksum.h"staticstructraw_pcb*ping_pcb=NULL;staticu16_tping_seq_num=0;// 接收 ICMP 应答的回调函数staticu8_tping_recv(void*arg,structraw_pcb*pcb,structpbuf*p,constip_addr_t*addr){structicmp_echo_hdr*iecho=(structicmp_echo_hdr*)p->payload;// 检查是否是回显应答(Type 0)且标识符匹配if(iecho->type==ICMP_ER&&ntohs(iecho->id)==PING_ID){printf("收到来自 %s 的应答! 序列号: %d\n",ipaddr_ntoa(addr),ntohs(iecho->seqno));}return1;// 表示已处理该包}// 初始化并发送一次 Pingvoiddevice_ping(ip_addr_t*target_ip){structpbuf*p;structicmp_echo_hdr*iecho;if(!ping_pcb){ping_pcb=raw_new(IP_PROTO_ICMP);raw_recv(ping_pcb,ping_recv,NULL);// 绑定接收回调}// 分配内存:ICMP 首部 + 少量测试数据p=pbuf_alloc(PBUF_IP,sizeof(structicmp_echo_hdr)+4,PBUF_RAM);if(p!=NULL){iecho=(structicmp_echo_hdr*)p->payload;// 填充 ICMP 首部ICMPH_TYPE_SET(iecho,ICMP_ECHO);// Type = 8ICMPH_CODE_SET(iecho,0);// Code = 0iecho->chksum=0;iecho->id=htons(PING_ID);// 自定义 IDiecho->seqno=htons(++ping_seq_num);// 计算校验和iecho->chksum=inet_chksum(iecho,p->tot_len);// 发送数据包raw_sendto(ping_pcb,p,target_ip);pbuf_free(p);}}
http://www.zskr.cn/news/1429105.html

相关文章:

  • Pearcleaner:macOS彻底清理工具的终极指南
  • 第24篇|相机权限和设备枚举:先判断能力再打开预览
  • 打破Java字节码黑箱:JD-GUI的实战逆向工程指南
  • HS2-HF补丁:让Honey Select 2游戏体验焕然一新的终极解决方案
  • PyTorch实现的MANO手部模型:3D手势生成与计算机视觉应用终极指南
  • IGMP协议浅析
  • 2026 杭州直播代运营行业大洗牌,乱象频发,高 ROI 靠谱全链路服务商精选推荐 - 品牌榜中榜
  • 别再死磕梯度下降了!用Python手搓一个遗传算法,轻松搞定那些‘不听话’的优化问题
  • 别再让回车变空格了!手把手教你用JavaScript处理textarea换行符(含 转br实战)
  • 用Scratch打造钩针图案生成器:连接编程与手工的创意实践
  • 2026年 西安消防器材/消防设备/消防设施/灭火器材/应急消防器材最新推荐:精选品牌与实战性能深度解析! - 品牌企业推荐师(官方)
  • 从假设检验到机器学习:正态分布与卡方分布在数据分析中的实战联动指南
  • WarcraftHelper终极指南:让经典魔兽争霸3焕发新生,解决所有版本兼容问题
  • 乔布斯教会耄耋的事:在《一念成仙》,耄耋如何定义“最好的产品”
  • 告别深夜夺命Call:如何利用 AI Agent Skills 自动自愈生产环境故障
  • 免费数据恢复神器:TestDisk与PhotoRec的终极使用指南
  • 预训练模型破解AI搜索冷启动:从BERT到向量检索的实战指南
  • 告别杜邦线乱飞!用Arduino Uno和TM1650驱动数码管模块,一个IIC接口搞定四位显示
  • 嵌入式开发避坑指南:用HexView移动固件数据时,如何避免覆盖已有数据?
  • 别只刷题了!用‘整理高手’算法题,手把手教你理解双向冒泡排序的C++实现
  • 【几分钟搞定】OpenClaw 聊天渠道配置 飞书对接方法(包含安装包)
  • 2026年阿拉善左旗TOP4高性价比电器门店,哪家才是真正最低价?
  • 从BEV检测实战出发:深入理解Nuscenes与Argoverse数据集的坐标系‘基因’差异
  • 苏州做 GEO 效果怎么样?2026年行业实践解析 - 品牌排行榜
  • go swagger慢
  • 如何在Windows上高效安装安卓应用:APK安装器完整指南
  • 如何通过APKMirror安全获取安卓应用?这款开源客户端为你提供官方商店外的可靠选择
  • 2026年石家庄GEO优化权威排名:调研AI核心数据于深度解析指南优化避坑指南 - 资讯纵览
  • OBS-Multi-RTMP:一键开启多平台直播推流的终极解决方案
  • Inkscape光线追踪扩展终极指南:5分钟创建专业光学图表