第11章 ICMP:Internet控制报文协议

所属:TCP/IP详解 卷2:实现 来源:TCP/IP详解 卷2:实现

本章描述ICMP协议的内核实现,包括ICMP报文类型、ICMP输入处理、ICMP输出处理和ICMP差错报文等。


11.1 引言

ICMP的作用

ICMP(Internet Control Message Protocol):

  • Internet控制报文协议
  • 传递网络层的控制信息
  • 报告错误和状态
  • 诊断工具(ping、traceroute等)
  • IP协议的一部分,协议号1

ICMP用于网络控制和诊断。


ICMP的特点

ICMP的特点:

  • 封装在IP数据报中
  • 协议号1
  • 不保证可靠交付
  • 不产生ICMP的ICMP(防止雪崩)
  • 差错报文包含原IP首部和前8字节数据

ICMP是IP的辅助协议。


本章讨论的内容

本章讨论的内容:

  • ICMP报文类型
  • ICMP输入处理(icmp_input)
  • ICMP输出处理(icmp_output)
  • ICMP差错报文
  • ICMP查询报文
  • ICMP与上层协议的交互

本章讨论ICMP的内核实现。


11.2 ICMP报文类型

ICMP报文分类

ICMP报文分为两大类:

  1. 差错报文(Error Messages)

    • 报告错误
    • 如目的不可达、超时、重定向等
  2. 查询报文(Query Messages)

    • 请求-应答模式
    • 如回显请求/应答、时间戳请求/应答等

差错报文报告错误,查询报文用于诊断。


常见的ICMP报文

常见的ICMP报文类型:

类型代码名称类别
00回显应答(Echo Reply)查询
30-15目的不可达(Destination Unreachable)差错
40源抑制(Source Quench)差错
50-3重定向(Redirect)差错
80回显请求(Echo Request)查询
90路由器通告(Router Advertisement)查询
100路由器请求(Router Solicitation)查询
110-1超时(Time Exceeded)差错
120-1参数问题(Parameter Problem)差错
130时间戳请求(Timestamp Request)查询
140时间戳应答(Timestamp Reply)查询
150信息请求(Information Request)查询
160信息应答(Information Reply)查询
170地址掩码请求(Address Mask Request)查询
180地址掩码应答(Address Mask Reply)查询

有很多种ICMP报文类型。


ICMP报文格式

ICMP报文的通用格式:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      类型     |      代码     |           检验和             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                         内容(可变)                          |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

字段说明:

  • 类型:8位,报文类型
  • 代码:8位,进一步细分
  • 检验和:16位,ICMP报文的检验和
  • 内容:可变,取决于类型和代码

ICMP封装在IP数据报中。


差错报文的内容

差错报文包含:

  • 原IP首部
  • 原数据报的前8字节数据
  • 这样上层协议可以匹配是哪个数据报出错了

为什么是前8字节:

  • TCP/UDP的端口号在前8字节
  • 可以找到对应的套接字
  • 上层可以处理错误

差错报文包含原数据的一部分。


11.3 ICMP输入处理

icmp_input函数

ICMP输入处理(icmp_input):

  • IP层分用后调用
  • 处理收到的ICMP报文
  • 验证检验和
  • 根据类型分别处理
  • 有些交给应用(原始套接字)
  • 有些内核自己处理

icmp_input是ICMP输入的入口。


输入处理流程

ICMP输入的处理流程:

收到ICMP报文
   |
   v
验证检验和
   |
   v
根据类型和代码处理
   |
   +---> 查询报文(回显请求等)
   |        |
   |        +---> 内核处理,生成应答
   |
   +---> 差错报文(不可达、超时等)
   |        |
   |        +---> 通知上层协议
   |        +---> 通知原始套接字
   |
   +---> 其他
            |
            +---> 交给原始套接字

查询报文的处理

回显请求(ping)的处理:

  1. 收到回显请求
  2. 验证
  3. 生成回显应答
    • 类型从8改成0
    • 交换源目地址
    • 数据部分不变
    • 重新计算检验和
  4. 发送回去

ping的应答由内核处理。


差错报文的处理

差错报文的处理:

  1. 解析差错报文
  2. 提取原IP首部和前8字节数据
  3. 找到对应的上层协议
  4. 通知上层协议
    • TCP:tcp_ctlinput
    • UDP:udp_ctlinput
  5. 通知原始套接字

差错报文中包含原数据的一部分。


11.4 ICMP输出处理

icmp_error函数

ICMP差错报文发送(icmp_error):

  • 内核需要发送ICMP差错时调用
  • 构造ICMP报文
  • 包含原IP首部和前8字节数据
  • 发送出去

icmp_error发送差错报文。


什么时候发送ICMP差错

发送ICMP差错的情况:

  1. 目的不可达

    • 主机不可达
    • 端口不可达
    • 协议不可达
    • 需要分片但DF置位
    • 等等
  2. 超时

    • TTL=0
    • 分片重装超时
  3. 参数问题

    • IP首部有问题
  4. 源抑制

    • 拥塞时发送(现在很少用)
  5. 重定向

    • 路由优化时发送

各种错误情况都可能发送ICMP。


不发送ICMP的情况

不发送ICMP差错的情况:

  1. ICMP差错报文

    • ICMP差错不产生ICMP差错
    • 防止雪崩效应
  2. 广播或多播

    • 目的是广播或多播地址
    • 不发送ICMP差错
  3. 链路层广播

    • 不是单播的帧
    • 不发送
  4. 源地址不是单播

    • 源地址是广播、多播、0等
    • 不发送
  5. 第一个分片之后的分片

    • 不是第一个分片
    • 不发送

有些情况不发送ICMP,防止问题扩大。


11.5 ICMP与上层协议

ICMP与TCP

ICMP差错对TCP的影响:

  • 目的不可达 → 连接可能失败
  • 超时 → 可能是路由问题
  • 源抑制 → 降低发送速率
  • TCP会根据ICMP错误调整

处理方式:

  • tcp_ctlinput函数
  • 根据ICMP类型和代码处理
  • 可能导致连接复位
  • 可能记录错误

TCP会处理ICMP差错。


ICMP与UDP

ICMP差错对UDP的影响:

  • 端口不可达 → 应用可能收到错误
  • 其他错误 → 应用可能收到

处理方式:

  • udp_ctlinput函数
  • 通知对应的套接字
  • 应用可以用recvfrom等收到错误

UDP也会处理ICMP差错。


原始套接字

原始套接字与ICMP:

  • 进程可以用原始套接字接收ICMP
  • ping、traceroute等工具用
  • 需要特殊权限

原始套接字可以直接处理ICMP。


11.6 小结

ICMP概述

  1. 作用

    • 控制报文协议
    • 报告错误和状态
    • 诊断工具
  2. 特点

    • 封装在IP中
    • 协议号1
    • 不保证可靠
    • 差错不产生差错

ICMP报文类型

  1. 分类

    • 差错报文
    • 查询报文
  2. 常见类型

    • 回显请求/应答
    • 目的不可达
    • 超时
    • 重定向
    • 时间戳
    • 等等
  3. 格式

    • 类型、代码、检验和
    • 内容可变

ICMP输入处理

  1. icmp_input

    • ICMP输入入口
    • 验证检验和
    • 按类型处理
  2. 查询报文

    • 内核处理
    • 生成应答
  3. 差错报文

    • 通知上层协议
    • 通知原始套接字

ICMP输出处理

  1. icmp_error

    • 发送差错报文
    • 包含原数据的一部分
  2. 发送时机

    • 目的不可达
    • 超时
    • 参数问题
    • 重定向
    • 等等
  3. 不发送的情况

    • ICMP差错不产生差错
    • 广播多播不发送
    • 源地址不对不发送

ICMP与上层

  1. 与TCP

    • tcp_ctlinput
    • 影响连接
  2. 与UDP

    • udp_ctlinput
    • 通知套接字
  3. 与原始套接字

    • 可以直接收发ICMP
    • ping等工具用

关键概念

  1. ICMP

    • 控制报文协议
    • 报告错误
    • 诊断工具
  2. 报文类型

    • 差错和查询
    • 各种类型
  3. icmp_input

    • 输入处理
    • 按类型处理
  4. icmp_error

    • 输出差错
    • 有很多限制
  5. 与上层交互

    • 通知TCP/UDP
    • 原始套接字

控制报文协议