ICMP协议 ######## :: ICMP: Internet Control Message Protocol 网络控制报文协议 用于告知网络包传送过程中产生的错误以及各种控制消息 当传送IP数据包发生错误--比如主机不可达,路由不可达等等 ICMP协议将会把错误信息封包,然后传送回给主机 .. figure:: https://img.zhaoweiguo.com/knowledge/images/protocols/icmp1.png ICMP协议——查询报文&差错报文 主要的 ICMP 消息:: 1. Echo reply 0 响应 Echo 消息 屏蔽类型 0和下面的8 消息后,ping 命令就没有响应了 如果屏蔽 0 和 8,就不会响应 ping 命令 2. Destination unreachable 3 终点不可达: 出于某些原因包没有到达目的地而是被丢弃,则通过此消息通知发送方。 可能的原因包括: 目标 IP 地址在路由表中不存在; 目标端口号不存在对应的套接字; 需要分片,但分片被禁用 3. Source quench 4 源抑制: 当发送的包数量超过路由器的转发能力时,超过的部分会被丢弃,这时会通过这一消息通知发送方 但是,并不是说遇到这种情况一定会发送这一消息。 当路由器的性能不足时,可能连这条消息都不发送,就直接把多余的包丢弃 当发送方收到这条消息时,必须降低发送速率 4. Redirect 5 重定向: 当查询路由表后判断该包的入口和出口为同一个网络接口时, 则表示这个包不需要该路由器转发,可以由发送方直接发送给下一个路由器。 遇到这种情况时,路由器会发送这条消息,给出下一个路由器的 IP 地址,指示发送方直接发送过去 5. Echo 8 ping 命令发送的消息。 收到这条消息的设备需返回一个 Echo reply 消息,以便确认通信对象是否存在 6. Time exceeded 11 超时: 由于超过了 IP 头部中的 TTL 字段表示的存活时间而被路由器丢弃,此时路由器会向发送方发送这条消息 7. Parameter problem 12 由于 IP 头部字段存在错误而被丢弃,此时会向发送方发送这条消息 如下是不产生ICMP错误报文的:: 1. ICMP差错报文不会产生ICMP差错报文(出IMCP查询报文)(防止IMCP的无限产生和传送) 2. 目的地址是广播地址或多播地址的IP数据报 3. 作为链路层广播的数据报 4. 不是IP分片的第一片 5. 源地址不是单个主机的数据报。这就是说,源地址不能为零地址、环回地址、广播地 址或多播地址 ICMP协议大致分为两类:: 一种是查询报文 一种是差错报文 差错报文则产生在数据传送发生错误的时候 查询报文有以下几种用途:: 1. ping查询 2. 子网掩码查询(用于无盘工作站在初始化自身的时候初始化子网掩码) 3. 时间戳查询(可以用来同步时间) ICMP的应用 ========== ping ---- .. note:: 使用查询报文 :: 它利用ICMP协议包来侦测另一个主机是否可达 原理是用类型码为0的ICMP发请求,受到请求的主机则用类型码为8的ICMP回应 ping程序来计算间隔时间,并计算有多少个包被送达。用户就可以判断网络大致的情况 ping给出来了传送的时间和TTL的数据 ICMP的ping请求数据报在每经过一个路由器的时候,路由器都会把自己的ip放到该数据报中 而目的主机则会把这个ip列表复制到回应icmp数据包中发回给主机 但是,无论如何,ip头所能纪录的路由列表是非常的有限 ping 发的包也是符合 ICMP 协议格式的,只不过它在后面增加了自己的格式。 ping 还会存放发送请求的时间值,来计算往返时间,说明路程的长短。 Traceroute ---------- .. note:: 使用差错报文 :: % windows下面的名字叫做tracert Traceroute是用来侦测主机到目的主机之间所经路由情况的重要工具,也是最便利的工具 Traceroute的原理: 1. 它受到目的主机的IP后,首先给目的主机发送一个TTL=1的UDP数据包 2. 而经过的第一个路由器收到这个数据包以后,就自动把TTL减1,而TTL变为0以后 路由器就把这个包给抛弃了,并同时产生 一个「主机不可达」的ICMP数据报给主机 3. 主机收到这个数据报以后再发一个TTL=2的UDP数据报给目的主机 然后刺激第二个路由器给主机发ICMP数据报 4. 如此往复直到到达目的主机。这样,traceroute就拿到了所有的路由器ip 从而避开了ip头只能记录有限路由IP的问题 怎么知道UDP到没到达目的主机呢? 而traceroute发送的是端口号>30000的UDP报文 TTL减为0时最后一个经手的路由器会返回TTL-Exceeded报文 到目的主机后由于端口大于30000,会返回Port-Unreachable,这样就可以知道到达了主机 有的路由器压根不会回这个 ICMP。这也是 Traceroute 一个公网的地址,看不到中间路由的原因。 Traceroute另一用法——故意设置不分片,从而确定路径的 MTU:: 1. 发送分组,并设置 “不分片” 标志。 2. 当发送的分组的长度大于出口 MTU 时。会发送 ICMP 网络差错包 类型为 “需要进行分片但设置了不分片位”。 3. 每次收到 ICMP “不能分片” 差错时就减小分组的长度,直到到达目标主机。 tcpdump抓包 ----------- :: $ tcpdump -i eth0 icmp