【lwip】10-ICMP协议&源码分析( 三 )


【lwip】10-ICMP协议&源码分析

文章插图
在以下情况下,网关会向主机发送重定向消息 。
网关Gl从网关所连接的网络上的主机接收互联网数据报,然后检查自己的路由表,得到数据报internet目的网络X的路由上的下一个网关G2的地址 。
如果G2与数据报internet源地址标识的主机在同一网络上,则向该主机发送重定向消息 。
重定向消息建议主机将其网络X的流量直接发送到网关G2,因为这是到达目的地的较短路径 。
网关将原始数据报的数据转发到其internet目的地 。
对于带有IP源路由选项和目的地址字段中网关地址的数据报,即使到达最终目的地的路由比源路由中的下一个地址有更好的路由,也不发送重定向消息 。
可以从网关接收编码0、1、2和3 。
10.3.4 超时类型代码描述查询差错11超时:0传输期间TTL为0√1分片数据报重装超时√10.3.5 参数错误类型代码描述查询差错12参数问题:0IP首部异常√1缺少必须的选项√IP 数据报在网络中传输的时候,都是根据其首部进行识别的,如果首部出现错误,那么就会产生严重的问题,因此如果 IP 数据报首部出现错误就会丢弃数据报,并且向源主机返回一个 ICMP参数错误报文 。
10.4 ICMP查询报文常见的ICMP查询报文:
  1. 回显请求或回答 。
  2. 路由器查询和通告 。
  3. 时间戳请求或回答 。
  4. 信息请求或回答 。
  5. 地址掩码请求或回答 。
10.4.1 回显这是当前lwip唯一实现的ICMP查询报文 。
类型代码描述查询差错00回显应答(如ping应答)√80请求回显(如ping请求)√报文格式:
【lwip】10-ICMP协议&源码分析

文章插图
标识符和序列号没有具体范围要求,符合字节限制即可 。发送方可以自由使用这两个字段 。
如该标识符可能被用作TCP或UDP中的端口来标识会话,而序列号可能会在每次发送回显请求时递增 。
数据字段可选,但是在请求回显消息中接收到的数据必须在回显应答消息中返回 。(即是同一对回显的数据必须一致)
10.5 ICMP数据结构lwip支持的icmp数据结构在icmp.h文件中 。
10.5.1 ICMP数据报数据结构数据结构:
/** This is the standard ICMP header only that the u32_t data *is split to two u16_t like ICMP echo needs it. *This header is also used for other ICMP types that do not *use the data part. */PACK_STRUCT_BEGINstruct 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操作:
#define ICMPH_TYPE(hdr) ((hdr)->type) // 读取类型字段#define ICMPH_CODE(hdr) ((hdr)->code) // 读取代码字段#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) // 设置类型字段#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) // 设置代码字段10.5.2 ICMP类型字段#define ICMP_ER0/* 回显回答 */#define ICMP_DUR3/* 目的不可达 */#define ICMP_SQ4/* 源站抑制 */#define ICMP_RD5/* 重定向 */#define ICMP_ECHO 8/* 回显请求 */#define ICMP_TE11/* 数据报超时 */#define ICMP_PP12/* 数据报参数错误 */#define ICMP_TS13/* 时间戳请求 */#define ICMP_TSR 14/* 时间戳回答 */#define ICMP_IRQ 15/* 信息请求 */#define ICMP_IR16/* 信息回答 */#define ICMP_AM17/* 地址掩码请求 */#define ICMP_AMR 18/* 地址掩码回答 */10.5.3 目的不可达代码字段/** ICMP目的不可达代码字段 */enum icmp_dur_type {/** 网络不可达 */ICMP_DUR_NET= 0,/** 主机不可达 */ICMP_DUR_HOST= 1,/** 协议不可达 */ICMP_DUR_PROTO = 2,/** 端口不可达 */ICMP_DUR_PORT= 3,/** 需要分片但不分片置位 */ICMP_DUR_FRAG= 4,/** 源路由失败 */ICMP_DUR_SR= 5};

经验总结扩展阅读