易栈 · 一盏

塞外秋来,衡阳雁去

网络层:ICMP、IGMP

一、ICMP:Internet控制报文协议

ICMP是IP层的组成部分,但是它是封装在IP数据报中进行传输的,它的一个重要作用是传递差错报文。ICMP报文通常被IP层或者更高层协议(TCP、UDP)使用。例如前面说过的IP层转发数据时,如果在路由表中找不到相应的路由,将会给源主机返回ICMP主机不可达差错;另外UDP如果收到一个UDP数据报而目的端口当前没有被任何进程使用,将返回ICMP端口不可达差错

ICMP报文格式如下:

类型|代码|校验和|报文内容(不同类型和代码有不同的内容)

报文类型由类型字段代码字段共同决定。类型字段是大分类,代码字段在类型字段下进行细分,例如“目的不可达”类型可细分为“主机不可达”或者“端口不可达”等等。

查询  回显请求/应答 (ping命令用来测试另一台主机是否可达)
     路由器请求/通告 (用来发现网络中的路由器)
     时间戳请求/应答
     地址掩码请求/应答 (无盘系统用来在引导时获取自己的子网掩码)

差错  目的不可达 (用来探测MTU/traceroute用来判断是否到达目的主机)
     源站抑制 (接收方处理不过来时,用来告知发送方停止发送)
     重定向 (IP静态选路)
     超时 (traceroute用来获取每一跳路由的IP地址)

根据作用的不同,ICMP报文可以分成两大类:查询报文和差错报文

  • 查询报文:包括请求报文和应答报文。查询报文一般会有一个标识符和序列号,发送端可以用这个把应答和请求进行匹配。
  • 差错报文:的报文内容中包含产生该差错报文的IP数据报的“首部(包括选项部分)+数据部分的前8个字节”。这样做的目的是什么呢?TCP和UDP用端口号来标识数据来自哪个应用程序。因为ICMP是IP层的协议,它没有指明端口号,所以当给源主机发ICMP差错报文时,为了让源主机知道该把这个差错返回给哪个进程,附上原IP数据报的IP首部(为了识别数据部分是TCP还是UDP)和数据部分的前8个字节(TCP报文段和UDP数据报的端口号字段都在前8个字节)。

下列情况都不会产生差错报文:

    • 收到ICMP差错报文时(对ICMP差错报文响应另一份ICMP差错报文,可能会导致无休止的循环)。
    • 收到的IP数据报不是IP分片的第一片时(只有第一个分片中有运输层首部,前面说过差错报文要包含“数据部分的前8个字节”,也就是源IP数据报中的运输层首部)。
    • 收到作为链路层广播的数据报时(例如ARP请求、RARP请求)。
    • IP数据报的目的地址是广播地址或多播地址时(否则可能导致广播风暴)。
    • IP数据报的源地址不是单个主机时(也就是说源地址不能为零地址、环回地址、广播地址或多播地址)。

二、IGMP:Internet组管理协议

多播数据可以被路由器转发( 多播的含义,详见《运输层:UDP、广播、多播》)。主机通过IGMP向路由器通告自己所在的多播组。路由器通过IGMP获取多播组信息,建立多播路由表,以便知道多播数据报应该向哪些接口转发。

IGMP有查询报文和报告报文

  • 查询报文:多播路由器定时发送IGMP查询来了解网络中是否有任何主机属于多播组。IGMP查询发往多播地址224.0.0.1,这个地址被称为“所有主机组地址”,网络上所有具有多播能力的接口,在初始化后都会自动加入这个多播组。也就是发往这个多播地址的数据,会被网络内所有的主机、路由器接收。
  • 报告报文:当主机有进程加入一个新的多播组时,主机就往该多播组的多播地址发送一个IGMP报告。收到来自路由器的IGMP查询时,主机会往自己所在的每个多播组都发一个IGMP报告。为了能够收到IGMP报告,路由器必须要接收发往所有多播组的多播数据包(路由器无法确定主机可能加入哪个多播组)。另外同一个多播组的所有主机都会相互收到对方的IGMP报告。一台主机在准备发送IGMP报告时,如果收到来自同组主机的报告,就可以不用发自己的了(路由器只关心该多播组是否至少还拥有一台主机,而不关心拥有多少台主机)。

本文链接:易栈 - 网络层:ICMP、IGMP