3.2 ICMPv4 报文和报文类型

3.2 ICMPv4 报文和报文类型

1. ICMPv4 报头

ICMPv4 是基于IP协议的。所以在 ICMPv4 的报文外面,还有一层 IP 报文格式。

image-20240319205705802

ICMPv4 报头struct icmphdr类型(8位)代码(8位)校验和(16位)可变部分(32位)组成。

image-20240319210559594

struct icmphdr {
  __u8		type;
  __u8		code;
  __sum16	checksum;
  union {
	struct {
		__be16	id;
		__be16	sequence;
	} echo;
	__be32	gateway;
	struct {
		__be16	__unused;
		__be16	mtu;
	} frag;
	__u8	reserved[4];
  } un;
};

在 ICMPv4 的报头中,typecode的组合构成了 ICMPv4 的各种报文类型。其它的字段则是不同的报文类型所携带的私有属性。下面将通过type和code的不同组合,先来整体的了解以下,icmp所能传达的信息。

2. ICMPv4报文类型

image-20240325163422715

在这张图中,报文类型分为2类:查询差错

查询报文,顾名思义,它并不是发生了错误而产生,它是为了在网路中获取数据。最常用的就是 Type 0Type 8 ping服务。

差错报文,当网路中发生错误信息时,将被发送出去。最常用的就是Type 3不可达差错和Type 11 超时差错。

ICMPv4 有一个结构体struct icmp_control 来描述ICMPv4处理函数。

struct icmp_control {
	bool (*handler)(struct sk_buff *skb); //处理函数
	short error; // 用来标记是否是错误信息
};

在文章开头提到,ICMPv4信息,有2个作用,一个是信息消息,一个是错误消息,在ICMPv4中,error注册为1的为错误消息。(ICMPv6则用bit位来表示)

在ICMPv4中记录消息类型处理的数组是icmp_pointers[NR_ICMP_TYPES + 1] 详见附录1.

以下是每个服务所对应的处理函数:

typeID 消息类型 处理函数 错误消息 信息消息
0 ICMP_ECHOREPLY ping_rcv x
3 ICMP_DEST_UNREACH icmp_unreach x
4 ICMP_SOURCE_QUENCH icmp_unreach x
5 ICMP_REDIRECT icmp_redirect x
8 ICMP_ECHO icmp_echo x
11 ICMP_TIME_EXCEEDED icmp_unreach x
12 ICMP_PARAMETERPROB icmp_unreach x
13 ICMP_TIMESTAMP icmp_timestamp x
14 ICMP_TIMESTAMPREPLY icmp_discard x
15 ICMP_INFO_REQUEST(作废) icmp_discard x
16 ICMP_INFO_REPLY(作废) icmp_discard x
17 ICMP_ADDRESS icmp_discard x
18 ICMP_ADDRESSREPLY icmp_discard x

处理函数进行归纳有:

  • 查询处理:ping_rcv() \ icmp_echo() \ icmp_timestamp()
  • 差错处理:icmp_unreach() \ icmp_redirect()
  • 不做处理:icmp_discard()

他们的功能如下:

  • ping_rcv 负责处理接收ping应答(ICMP_ECHOREPLY)。
  • icmp_echo 处理回应ping请求。(ICMP_ECHO)
  • icmp_timestamp 用来处理ICMP时间戳请求(ICMP_TIMESTAMP)。
  • icmp_unreach 消息不可达的消息类型。在很多情况下都会发送(ICMP_DEST_UNREACH).
  • icmp_redirect 处理重定向消息(ICMP_REDIRECT)。
  • icmp_discard 这是一个空处理函数。用于不存在的消息类型不需要做任何处理的消息。

下文我们将对如何接收一个ICMPv4报文做出描述。

3. 附录

附录1. ICMP消息处理数组:

static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = {
	[ICMP_ECHOREPLY] = {
		.handler = ping_rcv,
	},
	[1] = {
		.handler = icmp_discard,
		.error = 1,
	},
	[2] = {
		.handler = icmp_discard,
		.error = 1,
	},
	[ICMP_DEST_UNREACH] = {
		.handler = icmp_unreach,
		.error = 1,
	},
	[ICMP_SOURCE_QUENCH] = {
		.handler = icmp_unreach,
		.error = 1,
	},
	[ICMP_REDIRECT] = {
		.handler = icmp_redirect,
		.error = 1,
	},
	[6] = {
		.handler = icmp_discard,
		.error = 1,
	},
	[7] = {
		.handler = icmp_discard,
		.error = 1,
	},
	[ICMP_ECHO] = {
		.handler = icmp_echo,
	},
	[9] = {
		.handler = icmp_discard,
		.error = 1,
	},
	[10] = {
		.handler = icmp_discard,
		.error = 1,
	},
	[ICMP_TIME_EXCEEDED] = {
		.handler = icmp_unreach,
		.error = 1,
	},
	[ICMP_PARAMETERPROB] = {
		.handler = icmp_unreach,
		.error = 1,
	},
	[ICMP_TIMESTAMP] = {
		.handler = icmp_timestamp,
	},
	[ICMP_TIMESTAMPREPLY] = {
		.handler = icmp_discard,
	},
	[ICMP_INFO_REQUEST] = {
		.handler = icmp_discard,
	},
	[ICMP_INFO_REPLY] = {
		.handler = icmp_discard,
	},
	[ICMP_ADDRESS] = {
		.handler = icmp_discard,
	},
	[ICMP_ADDRESSREPLY] = {
		.handler = icmp_discard,
	},
};
posted @ 2024-04-05 17:56  kmist  阅读(215)  评论(0编辑  收藏  举报