• ICMP经常被认为是IP层的一个组成部分。它传递差错报文以及其他需要注意的信息。
  • ICMP报文通常被IP层或更高层协议TCP或UDP使用。
  • 一些ICMP报文把差错报文返回给用户进程
 
ICMP报文是在IP数据报内部被传输的,如:

ICMP报文的类型

 

  • 所有报文的前4个字节都是一样

    • 8位类型+8位代码+16位校验和
    • 校验和
      • 和IP首部校验算法相同
      • 反向二进制求和
  • 剩余
    • 类型

      • 15个不同类型字段
      • 描述特定类型的ICMP报文
    • 代码
      • 使用代码字段的值来进一步描述不同的条件
 
ping--类型8,代码0-->请求回显
 
回显应答<--类型0,代码0--ping
 
不同类型由类型字段和代码字段共同决定;

分类
  • 查询报文
    • 查询报文如果出错会产生一个差错报文
  • 差错报文
    • 有时需要做特殊处理
    • 永远不会产生一个差错报文
      • 差错报文会继续产生差错报文,形成死循环
 
不会产生ICMP差错报文:
  • ICMP差错报文(但是, ICMP查询报文可能会产生 ICMP差错报文)。
  • 目的地址是广播地址(见图3 - 9)或多播地址(D类地址,见图1 - 5)的IP数据报。
  • 作为链路层广播的数据报
  • 不是IP分片的第一片(将在11 . 5节介绍分片)。
  • 源地址不是单个主机的数据报。这就是说,源地址不能为零地址、环回地址、广播地
    址或多播地址。
 
ICMP地址掩码请求与应答

 
ICMP地址掩码请求用于无盘系统在引导过程中获取自己的子网掩码
 
ICMP地址掩码请求和应答报文的格式如图:

ICMP报文中的标识符和序列号字段由发送端任意选择设定,这些值在应答中将被返回。
这样,发送端就可以把应答与请求进行匹配。
 
ICMP时间戳请求与应答

  • ICMP时间戳请求允许系统向另一个系统查询当前的时间
    • 返回的建议值是自午夜开始计算的毫秒数
    • 协调的统一时间(Coordinated Universal Time, UTC)
  • ICMP报文的好处是它提供了毫秒级的分辨率
    • 如某些Unix系统提供的rdate命令只能提供秒级的分辨率。
  • 缺陷
    • 返回的时间是从午夜开始计算的,因此调用者必须通过其他方法获知当时的日期

 
请求端填写发起时间戳,然后发送报文。应答系统收到请求报文时填写接收时间戳,在
发送应答时填写传送时间戳。但是,实际上,大多数的实现把后面两个字段都设成相同的值
(提供三个字段的原因是可以让发送方分别计算发送请求的时间和发送应答的时间)。
 
 
请求与应答报文:
  • ICMP报文中都有标识符和序列号。
  • 发送端应用程序在标识字段内存入一个唯一的数值,以区别于其他进程的应答。
  • 序列号字段使得客户程序可以在区分哪个请求对应哪个应答。
 
ICMP端口不可达差错

ICMP差错报文, 端口不可达报文,它是 ICMP目的不可到达报文中的一种,以此来看一看ICMP差错报文中所附加的信息。
 
用例:
  • UDP

    • UDP的规则之一是,如果收到一份UDP数据报而目的端口与某个正在使用的进程不相符,
      那么UDP返回一个ICMP不可达报文。
  • TFTP
    • 可以用 TFTP来强制生成一个端口不可达报文
 
对于 TFTP服务器来说, UDP的公共端口号是 69。但是大多数的 TFTP客户程序允许用
connect命令来指定一个不同的端口号。这里,我们就用它来指定 8888端口:

connect命令首先指定要连接的主机名及其端口号,接着用 get命令来取文件。敲入 get
命令后,一份 UDP数据报就发送到主机 svr4上的8 8 8 8端口。 tcpdump命令引起的报文交换结果:

过程分析:
  • 在UDP数据报送到 svr4之前,要先发送一份ARP请求来确定它的硬件地址(第1行)。
  • 接着返回ARP应答(第2行)
  • 然后才发送UDP数据报(第3行)
  • 一个ICMP端口不可达差错是立刻返回的(第 4行)
  • 但是, TFTP客户程序看上去似乎忽略了这个ICMP报文,而在5秒钟之后又发送了另一份 UDP数据报(第 5行)。
  • 在客户程序放弃之前重发了三次
  • 跟在每个 UDP后面的数字 20指的是UDP数据报中的数据长度。
 
注意:
  • 在tcpdump的输出中保留ARP请求和应答是为了提醒我们,这些报文交换可能在第一个IP数据报从一个主机发送到另一个主机之前是必需的
  • ICMP报文是在主机之间交换的,而不用目的端口号,而每个20字节的UDP数据报
    则是从一个特定端口2924发送到另一个特定端口8888。
 
 
UDP端口不可达中ICMP报文:
 

ICMP规则:
  • ICMP差错报文必须包含生成该差错报文的数据报IP首部(包含任何选项)以及后续8个字节(如UDP首部)
    • 这个信息对于 ICMP差错的接收方来说是必要的,可以更多地了解导致差错的原因。
    • 这是因为TCP和UDP都在它们的首部前8个字节中存入源端口号和目的端口号
  • 尽管ICMP规则允许系统返回多于8个字节的产生差错的IP数据报中的数据,但一般只返回8个字节。
 
ICMP不可达报文的一般格式:

IP首部:得到源地址和目的地址
前8个字节:源端口号和目的端口号
 
tcpdump输出时间序列图:

当ICMP差错报文返回时,为啥应用程序(tftp)一直重发?
  • 网络编程中,BSD系统不把socket接收到的ICMP报文中的UDP数据通知TFTP
  • 即应用程序根本就不知道ICMP差错报文存在?
 
 
ICMP报文的处理

icmp覆盖范围很广,从致命差错到信息差错。
因此应用程序对每个ICMP报文的处理都是不一样的。

ping程序

该程序发送一份 ICMP回显请求报文给主机,并等待返回 ICMP回显应答.
回显
  • 类型:8
  • 代码:0
 
ping作用:
  • 可以作为诊断工具查看网络问题
  • 还能测出往返时间,
  • 检测IP记录路由和时间戳选项
 
ICMP回显请求和回显应答报文

Unix系统在实现ping程序时是把 ICMP报文中的标识符字段置成发送进程的id号。
序列号从0开始,每发送一次新的回显请求就加 1。
 
ping输出
  1. zane@zane-V:~$ ping zane-V
  2. PING zane-V (127.0.1.1) () bytes of data.
  3. bytes from zane-V (127.0.1.1): icmp_seq= ttl= time=0.022 ms
  4. bytes from zane-V (127.0.1.1): icmp_seq= ttl= time=0.023 ms
  5. bytes from zane-V (127.0.1.1): icmp_seq= ttl= time=0.023 ms
  6. bytes from zane-V (127.0.1.1): icmp_seq= ttl= time=0.023 ms
  7. bytes from zane-V (127.0.1.1): icmp_seq= ttl= time=0.025 ms
  8. bytes from zane-V (127.0.1.1): icmp_seq= ttl= time=0.025 m
当返回ICMP回显应答时,打印出 序列号 和 TTL(位于IP首部中的生存时间字段),并计算往返时间;
 
IP记录路由选项
  • 提供-R选项,以提供记录路由的功能。
    • 会频繁使用默认路由
过程:
  • 使得ping程序在发送出去的IP数据报中设置IP的RR选项(该IP数据报包含ICMP回显请求报文)。
  • 每个处理该数据报的路由器都把它的IP地址放入选项字段中
  • 当数据报到达目的端时,IP地址清单应该复制到ICMP回显应答中,
  • 这样返回途中所经过的路由器地址也被加入清单中。
  • 当 ping程序收到回显应答时,它就打印出这份IP地址清单
 
问题:ip首部中只有有限的空间来存放IP地址。
答:路由的IP地址不是放在IP报文首部中,而是放在IP报文中的选项字段中
 
我们从图 3 - 1可以看到,IP首部中的首部长度字段只有 4 bit,因此整个IP首部最长只能包括 15个32 bit长的字(即60个字
节)。由于 IP首部固定长度为 20字节, RR选项用去 3个字节(下面我们再讨论),这样只剩下37个字节(60-20-3)来存放
IP地址清单,也就是说只能存放9个IP地址。
 
  1. [root@zane1 ~]# ping -R 192.168.56.12
  2. PING 192.168.56.12 (192.168.56.12) () bytes of data.
  3. bytes from 192.168.56.12: icmp_seq= ttl= time=1.19 ms
  4. RR: 192.168.56.10
  5. 192.168.56.12
  6. 192.168.56.12
  7. 192.168.56.10
  8.  
  9. bytes from 192.168.56.12: icmp_seq= ttl= time=0.250 ms (same route)
  10. bytes from 192.168.56.12: icmp_seq= ttl= time=0.190 ms (same route)
  11. bytes from 192.168.56.12: icmp_seq= ttl= time=0.248 ms (same route)
  12. bytes from 192.168.56.12: icmp_seq= ttl= time=0.208 ms (same route)
  13. bytes from 192.168.56.12: icmp_seq= ttl= time=0.331 ms (same route)
  14. bytes from 192.168.56.12: icmp_seq= ttl= time=0.274 ms (same route)
  15. bytes from 192.168.56.12: icmp_seq= ttl= time=0.250 ms (same route)
 
  • ping程序是对两个 TCP/IP系统连通性进行测试的基本工具。
  • 它只利用ICMP回显请求和回显应答报文,而不用经过传输层(TCP/UDP)
  • Ping服务器一般在内核中实现 ICMP的功能。
 
 
Traceroute程序

 
  • Traceroute程序可以让我们看到 IP数据报从一台主机传到另一台主机所经过的路由。
  • Traceroute程序还可以让我们使用 IP源路由选项
 
Traceroute程序使用
  • ICMP报文
  • IP首部中的TTL字段(生存周期)。
 
原理:
当路由器收到一份IP数据报,如果其TTL字段是0或1,则路由器不转发该数据报
相反,路由器将该数据报丢弃,并给信源机发一份ICMP“超时”信息。
Traceroute程序的关键在于包含这份 ICM 信息的IP报文的信源地址是该路由器的IP地址
 
Traceroute 操作过程
  • 它发送一份 TTL字段为1的IP数据报给目的主机
    • 处理这份数据报的第一个路由器将 TTL值减1,丢弃该数据报并发回一份超时ICMP报文
    • 这样就得到了该路径中的第一个路由器的地址
  • 然后 Traceroute程序发送一份TTL值为2的数据报,这样我们就可以得到第二个路由器的地址。
  • 继续这个过程直至该数据报到达目的主机。
    • 但是目的主机哪怕接收到TTL值为1的IP数据报,也不会丢弃该数据报并产生一份超时ICMP报文,这是因为数据报已经到达其最终目的地。
    • 那么我们该如何判断是否已经到达目的主机了呢?
      • Traceroute程序发送一份UDP数据报给目的主机,但它选择一个不可能的值作为UDP端口号(大于 30 000),使目的主机的任何一个应用程序都不可能使用该端口。
      • 因为,当该数据报到达时,将使目的主机的 UDP模块产生一份“端口不可达”错误的 ICMP报文。
  • Traceroute程序所要做的就是区分接收到的ICMP报文是超时还是端口不可达,以判断什么时候结束。
 
Traceroute输出
  1. [root@zane1 ~]# traceroute www.baidu.com
  2. traceroute to www.baidu.com (180.97.33.108), hops max, byte packets
  3. 10.0.2.2 (10.0.2.2) 0.135 ms 0.054 ms 0.050 ms
  4. 10.0.2.2 (10.0.2.2) 1.918 ms 1.833 ms 1.766 ms
  • 输出第1个无标号的行给出了

    • 主机名及其IP地址
    • TTL字段最大值
    • 发送的数据报大小
  • 输出的后面两行:
    • TTL值+主机名或路由器名称+主机/路由器IP
    • 对于每个TTL值发送3分数据报,打印往返时间
 
ICMP超时报文
类型:11

注意事项
  • 并不能保证现在的路由也是将来所要采用的路由,甚至两份连续的 IP数据报都可能采用不同的路由。
  • 第二,不能保证 ICMP报文的路由与traceroute程序发送的UDP数据报采用同一路由。
  • 第三,返回的 ICMP报文中的信源 IP地址是UDP数据报到达的路由器接口的 IP地址。
 
 

ICMP--ping--Traceroute的更多相关文章

  1. icmp,tcp,traceroute,ping,iptables

    有东莞的监控主机到北京BGP出问题了: 报警短信疯狂发送: 找东莞IDC和北京BGP服务商协查: 有个奇怪的问题:北京到东莞trcaceroute都有路由信息 东莞143段到北京全无路由信息:但,东莞 ...

  2. Zabbix中使用ICMP ping来判断主机是否存活的问题

    上一节配置了Simple check,现在来通过Simple check 用ICMP ping来监控充节点运行情况.Zabbix使用fping处理ICMP ping的请求,需要安装fping程序,安装 ...

  3. 使用zabbix3.0.4的ICMP Ping模版实现对客户端网络状态的监控

    一.登陆Zabbix服务器做以下操作: 1.fping安装 wget http://www.fping.org/dist/fping-3.16.tar.gz tar zxvf fping-3.16.t ...

  4. zabbix使用ICMP Ping模版实现对客户端网络状态的监控,监控丢包率、响应时间

    参考网站: https://www.cnblogs.com/saneri/p/6706578.html 使用fping报错注意事项: https://blog.csdn.net/oqqssh/arti ...

  5. ICMP Ping模版实现对客户端网络状态的监控

    Zabbix使用外部命令fping处理ICMP ping的请求,fping不包含在zabbix的发行版本中,需要额外去下载安装fping程序,安装完毕之后需要zabinx_server.conf中的参 ...

  6. Zabbix使用外部命令fping处理ICMP ping的请求

    Zabbix使用外部命令fping处理ICMP ping的请求,fping不包含在zabbix的发行版本中,需要额外去下载安装fping程序, 安装完毕之后需要在zabinx_server.conf中 ...

  7. 《TCP/IP 详解 卷一》读书笔记-----Ping&Traceroute

    1.ping是用于测试对方主机是否可达的命令,其实本质上就是echo类型的ICMP报文.同时,ping还能用于计算RTT(round-trip time),即两台主机间的往返时延. 2.随着网络安全意 ...

  8. Linux下网络排查之ping|traceroute|mtr工具(zz)

      1.ping ping使用了ICMP回送请求和回送应答报文.ping工具发出去的数据包没有通过tcp/udp协议,但是要经过ip协议.ping命令计算的时间是数据包的往返总时间. ping命令常用 ...

  9. ping traceroute原理

    ping命令工作原理 ping命令主要是用于检测网络的连通性. Ping命令发送一个ICMP请求报文给目的IP,然后目的IP回复一个ICMP报文. 原理:网络上的机器都有唯一确定的IP地址,我们给目标 ...

  10. ping & traceroute 原理

    说明: 忘记从哪里看到的原文了. 不过我应该进行了大刀阔斧的删选. ping 用类型码为0的ICMP发请 求,受到请求的主机则用类型码为8的ICMP回应. ping程序来计算间隔时间,并计算有多少个包 ...

随机推荐

  1. [0] Devexpress 控件参数集合

    gridview控件/统计功能 比如对“数量”列进行统计,只要在GridControl的设计器中设置SummaryItem:   SummaryItem.DisplayFormat = "{ ...

  2. OS X 和iOS 中的多线程技术(上)

    OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供 ...

  3. kubeadm 安装1.6.0版本出错 未解决

    工具包已经安装好了. [root@master data]# rpm -qa |grep kubekubeadm-1.6.0-0.x86_64kubectl-1.6.0-0.x86_64kubelet ...

  4. 在C#中初遇Socket - 2

    后期项目实战:多人在线聊天室 源码位置:https://git.oschina.net/z13qu/BlogProjects 前言 第一篇主要对Socket有个基本认识,实现初始化,发送.接受消息:本 ...

  5. linux开机启动smb服务

    修改/etc/rc.local文件(增加红色部分) [root@localhost ~]# cat /etc/rc.local #!/bin/sh## This script will be exec ...

  6. 开源搜索引擎abelkhan

    发起一个开源项目http://www.abelkhan.com/ 目前而言,已经用python编写了一个网络爬虫抓取页面,和一个简单的前端 网络爬虫,已经有很多高手写过,我基本上奉行了拿来主义, 得益 ...

  7. C语言之复杂链表的复制(图示详解)

    什么是复杂链表? 复杂链表指的是一个链表有若干个结点,每个结点有一个数据域用于存放数据,还有两个指针域,其中一个指向下一个节点,还有一个随机指向当前复杂链表中的任意一个节点或者是一个空结点.今天我们要 ...

  8. 浅析ConcurrentHashMap

    一.导论 这些天一直在看关于多线程和高并发的书籍,也对jdk中的并发措施了解了些许,看到concurrentHashMap的时候感觉知识点很乱,有必要写篇博客整理记录一下. 当资源在多线程下共享时会产 ...

  9. Perl根据日期分割数据文件

    Perl的优势:比C好写,比Shell高效,Linux普遍支持. #!/usr/bin/perl -w # auth: lichmama@cnblogs.com # what: split data_ ...

  10. java中变量赋值的理解

    1.当赋值的值超出声明变量的范围时候,会报错! byte a =200 //会报错,因超出范围. byte a =(byte)200;//进行一个强制转换,就不会报错,不过会超出范围,超出部分会从头开 ...