ICMP(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议簇的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
ICMP数据报总览
ICMP 数据报包含 首部和数据两部分,作为IP数据报的数据段。
首部分为类型,代码,校验和与首部剩余部分
ICMP的报文类型(type),分为查询和差错
所有报文的前4个字节都是一样的,但是剩下的其他字节则互不相同。
类型字段可以有 1 5个不同的值,以描述特定类型的 I C M P报文。某些 I C M P报文还使用代码字段的值来进一步描述不同的条件。
code 是对type的细分
参考 TCP-IP协议卷1 第6章 ICMP:Internet控制报文协议
代码
/**
* Processes ICMP input packets, called from ip_input().
*
* Currently only processes icmp echo requests and sends
* out the echo response.
*
* @param p the icmp echo request packet, p->payload pointing to the ip header
* @param inp the netif on which this packet was received
*/
void
icmp_input(struct pbuf *p, struct netif *inp)
ip_input 提交数据包到icmp_input
LWIP ICMP只对ICMP_ECHO 进行相应,也就是ping 命令的回应。
switch (type) {
case ICMP_ECHO:
当数据无法向上层提交的时候回,表示数据不可达。ICMP_DUR 会装入ICMP 首部
/**
* Send an icmp 'destination unreachable' packet, called from ip_input() if
* the transport layer protocol is unknown and from udp_input() if the local
* port is not bound.
*
* @param p the input packet for which the 'unreachable' should be sent,
* p->payload pointing to the IP header
* @param t type of the 'unreachable' packet
*/
void
icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
{
icmp_send_response(p, ICMP_DUR, t);
}
在组分片和转发过程中会出现ICMP超时ICMP_TE作为参数传入 ICMP首部
/**
* Send a 'time exceeded' packet, called from ip_forward() if TTL is 0.
*
* @param p the input packet for which the 'time exceeded' should be sent,
* p->payload pointing to the IP header
* @param t type of the 'time exceeded' packet
*/
void
icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
{
icmp_send_response(p, ICMP_TE, t);
}
icmp_send_response 安装传入的type组合ICMP数据报
/**
* Send an icmp packet in response to an incoming packet.
*
* @param p the input packet for which the 'unreachable' should be sent,
* p->payload pointing to the IP header
* @param type Type of the ICMP header
* @param code Code of the ICMP header
*/
static void
icmp_send_response(struct pbuf *p, u8_t type, u8_t code)