TCP/IP详解卷一:ICMP:Internet控制报文协议

490 阅读6分钟

引言

  • ICMP 报文通常被IP层或更高层协议(TCP或UDP)使用
  • 一些ICMP报文把差错报文返回给用户进程
  • ICMP报文是在IP数据报内部被传输的

图片.png

  • 类型字段可以有15个不同的值,以描述特定类型的ICMP报文

图片.png

6.2 ICMP报文的类型

表6.3表明下面的信息:

  • ICMP 消息信息类型由 type 和 code 两个字段决定
  • 最后两列标明 ICMP 是否为错误消息或者查询消息。(对错误消息从来不会再次生成错误消息)
  • 当 ICMP 错误消息被发送时,错误消息中包含引起错误消息的报文的 IP 头以及 IP 报文的前8位。这使得将接收到的 ICMP 模块与一个特定的协议(根据 ip 头来判断 TCP 或者 UDP)联系起来 以及 特定的 用户进程(根据 TCP 或者 UDP 头中 IP报文中前8位包含的 端口号 )。一个 ICMP 错误消息不会产生用来响应:
    1. 一个ICMP 错误消息

    2. 目的地为IP广播地址或者一个IP多播地址的数据报文

    3. 作为链路层广播的数据报文

    4. 数据报文的源地址没有定义为单独的主机。这意味着源地址不能为 0地址,环回地址,广播地址或者多播地址

    5. 不是 IP 分片的第一片(将在11 . 5节介绍分片)

图片.png

ICMP地址掩码请求与应答

  • ICMP地址掩码请求用于无盘系统在引导过程中获取自己的子网掩码(3.5节)
  • 无盘系统获取子网掩码的另一个方法是BOOTP协议(16章)

图片.png

sun % icmpaddnnask 140.252.13.63
received mask = ffffffeO, from 140.252.13.33                                 #from ourself
received mask = ffffffeO, from 140.252.13.35                                 #from bsdi
received mask = ffff0000, from 140.252.13.34                                 #from svr4

svr4 返回的掩码是错误的,尽管 svr4 设置了正确的掩码

svr4 % ifconfig emd0
emd0: flags=23<UP, BROADCAST ,NOTRAILERS>
inet 140.252.13.34 netmask ffffffe0 broadcast 140.252.13.63

此处为 SVR4 处理 ICMP 地址掩码请求 有bug

在 bsdi 机器上使用 tcpdump 命令查看:

1     0.0 8:0:20:3:f6:42 ff;ff:ff:ff:ff:ff ip 60:
      sun > 140.252.13.63: icmp: address mask request
2     0.00 (0.00) 0:0:c0:6f:2d:40 ff;ff:ff:ff:ff:ff ip 46:
      bsdi > sun: icmp: address mask is 0xffffffe0
3     0.01 (0.01) 0:0:c0:c2:9b:26 8:0:20:3:f6:42 ip 60:
      svr4 > sun: icmp: address mask is 0xffff0000
  • sun 接收到了 ICMP 响应(from ourself注释的行),为广播的特性:发送主机会通过内部的环回机制收到广播包的复制
  • bsdi 广播了响应,尽管 。正常情况下响应应该是独播的除非请求IP地址为0.0.0.0(此例子中不是)。因此这种情况为 BSD/386 bug

最后,尝试将 地址掩码请求 到 自己的 IP 地址 和 环回地址:

sun % icmpaddrmask sun
received mask = ff000000, from 140.252.13.33
sun % icmpaddrmask localhost
received mask = ff000000, from 127.0.0.1

两种方法都返回 环回地址 对应的 地址掩码 ,A类地址 127.0.0.1。根据图 2.4,发送到 主机的IP地址(140.252.13.33)IP 数据报文,实际上是发送到环回接口中。主机对于每个网络接口都有对应的子网掩码。

图片.png

ICMP时间戳请求与应答

  • ICMP时间戳请求允许系统向另一个系统查询当前的时间(返回的建议值是自午夜开始计算的毫秒数,因此不能得知日期)
  • ICMP时间戳请求和应答报文格式

图片.png

  • 还可以用另一种方法来获得时间和日期
sun % telnet bsdi daytime
Trying 140.252.13.35 ...     #first three lines output are from the Telnet client
Connected to bsdi.           
Escape character is "^]"
Wed Feb 3 16:38:33 1993      # here's the daytime service output
Connection closed by foreign host.      #   this is also from the Telnet client 

ICMP端口不可达差错

UDP的规则之一是,如果收到一份UDP数据报而目的端口与某个正在使用的进程不相符,那么UDP返回一个ICMP不可达报文。

对于TFTP服务器来说,UDP的公共端口号是69。但是大多数的TFTP客户程序允许用connect命令来指定一个不同的端口号。这里,我们就用它来指定8888端口:

bsdi % tftp
tftp> connect svr4 8888   # specify the hostname and port number
tftp> get temp.foo        # try to fetch a file
Transfer timed out.       # about 15 seconds later
tftp> quit

使用 tcpdump命令:

1  0.0                 arp who-has svr4 tell bsdi
2  0.002050 (0.0020)   arp reply svr4 is-at 0:0:c0:c2:9b:26
3  0.002723 (0.0007)   bsdi.2924 > svr4.8888: udp 20
4  0.006399 (0.0037)   svr4 > bsdi: icmp: svr4 udp port 8888 unreachable

5  5.000776 (4.9944)   bsdi. 2924 > svr4.8888: udp 20
6  5.004304 (0.0035)   svr4 > bsdi: icmp: svr4 udp port 8888 unreachable

7  10.000887(4.9966)   bsdi. 2924 > svr4.8888: udp 20
8  10.004416(0.0035)   svr4 > bsdi: icmp: svr4 udp port 8888 unreachable

9  15.001014(4.9966)   bsdi.2924 > svr4.8888: udp 20
10 15.004574(0.0036)   svr4 > bsdi: icmp: svr4 udp port 8888 unreachable

11 20.001177(4.9966)   bsdi.2924 > svr4.8888: udp 20
12 20.004759(0.0036)   svr4 > bsdi: icmp: svr4 udp port 8888 

port 不可到达 立刻返回(第四行)。但是 TFTP 客户端忽视了 ICMP 消息,在 5 秒之后再次发送了 udp 数据报文,然后又再次尝试了3次,客户端才放弃发送报文。

在UDP 行后面的数字 20 为 UDP 数据报文的长度(此例中长度20包含了TFTP的2字节 opcode,9字节 以空字符结束的文件名 temp.foo,以及9字节以空字符结束的字符串netascii)

图片.png

图片.png

图片.png

ICMP报文的4.4BSD处理

从致命错误到信息消息,ICMP 覆盖广泛的错误范围,因此对于每种报文处理方法可能不同

图片.png

小结

  • ICMP地址掩码请求和应答以及时间戳请求和应答
  • ICMP端口不可达差错
  • ICMP报文的4.4BSD处理

习题

在6.2节的末尾,我们列出了5种不发送ICMP差错报文的特殊条件。如果这些条件不满足而我们又在局域网上向一个似乎不存在的端口号发送一份广播UDP数据报,这时会发生什么样的情况?

每台主机都可能在同一个时刻发送一个ICMP端口不可达的报文。很多报文的传输都可能发生冲突(如果使用的是以太网),这将导致1秒或2秒的时间里网络不可用。

阅读RFC[Braden1989a],注意生成一个“ ICMP 端口不可达差错”为“必须”,“应该”或者“可能”哪一个词语。这些信息所在的页码和章节是多少?

            A host SHOULD generate Destination Unreachable messages with
            code:

SHOULD tools.ietf.org/html/rfc112… ,section-3.2.2.1[Page 39]

阅读RFC1349[Almquist1992],看看IP的服务类型字段(见图3-2)是如何被ICMP设置的?

   o   ICMP error messages include ICMP message types 3 (Destination
       Unreachable), 4 (Source Quench), 5 (Redirect), 11 (Time
       Exceeded), and 12 (Parameter Problem).

   o   ICMP request messages include ICMP message types 8 (Echo), 10
       (Router Solicitation), 13 (Timestamp), 15 (Information
       Request -- now obsolete), and 17 (Address Mask Request).

   o   ICMP reply messages include ICMP message types 0 (Echo
       Reply), 9 (Router Advertisement), 14 (Timestamp Reply), 16
       (Information Reply -- also obsolete), and 18 (Address Mask
       Reply).

tools.ietf.org/html/rfc134…

图片.png

如果你的系统提供netstat命令,请用它来查看接收和发送的ICMP报文类型。

xxx@xxx-xxx:~$ netstat -s
......
Icmp:
    610322 ICMP messages received
    252 input ICMP message failed.
    InCsumErrors: 2
    ICMP input histogram:
        destination unreachable: 36922
        timeout in transit: 746
        echo requests: 144203
        echo replies: 428421
        timestamp request: 28
    574090 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 1425
        echo request: 428434
        echo replies: 144203
        timestamp replies: 28
IcmpMsg:
        InType0: 428421
        InType3: 36922
        InType8: 144203
        InType11: 746
        InType13: 28
        OutType0: 144203
        OutType3: 1425
        OutType8: 428434
        OutType14: 28

......