前面讲到了,IP 协议并不是一个可靠的协议,它不保证数据被送达,那么,自然的,保证数据送达的工作应该由其他的模块来完 成。其中一个重要的模块就是 ICMP(网络控制报文)协议。
当传送 IP 数据包发生错误--比如主机不可达,路由不可达等等,ICMP 协议将会把错误信息封包,然后传送回给主机。给主机 一个处理错误的机会,这 也就是为什么说建立在 IP 层以上的协议是可能做到安全的原因。ICMP 数据包由8bit 的错误类型和8bit 的代 码和16bit 的校验和组成。而前 16bit 就组成了 ICMP 所要传递的信息。书上的图6-3清楚的给出了错误类型和代码的组合代表的意思。
尽管在大多数情况下,错误的包传送应该给出 ICMP 报文,但是在特殊情况下,是不产生 ICMP 错误报文的。如下:
ICMP 差错报文不会产生 ICMP 差错报文(出 IMCP 查询报文)(防止 IMCP 的无限产生和传送)
目的地址是广播地址或多播地址的IP数据报。
作为链路层广播的数据报。
不是IP分片的第一片。
源地址不是单个主机的数据报。这就是说,源地址不能为零地址、环回地址、广播地址或多播地址。 虽然里面的一些规定现在还不是很明白,但是所有的这一切规定,都是为了防止产生 ICMP 报文的无限传播而定义的。即时通讯聊天软件app开发可以加蔚可云的v:weikeyun24咨询
ICMP 协议大致分为两类,一种是查询报文,一种是差错报文。其中查询报文有以下几种用途:
ping 查询(不要告诉我你不知道 ping 程序)
子网掩码查询(用于无盘工作站在初始化自身的时候初始化子网掩码)
时间戳查询(可以用来同步时间)
而差错报文则产生在数据传送发生错误的时候。就不赘述了。
ICMP 的应用--ping
ping 可以说是 ICMP 的最著名的应用,当我们某一个网站上不去的时候。通常会 ping 一下这个网站。ping 会回显出一些有用的信息。
ping 这个单词源自声纳定位,而这个程序的作用也确实如此,它利用 ICMP 协议包来侦测另一个主机是否可达。原理是用类型码 为0的 ICMP 发请 求,受到请求的主机则用类型码为8的 ICMP 回应。ping 程序来计算间隔时间,并计算有多少个包被送达。用户就可 以判断网络大致的情况。我们可以看到, ping 给出来了传送的时间和 TTL 的数据。我给的例子不太好,因为走的路由少,有兴趣地 可以 ping 一下国外的网站比如 sf.net,就可以观察到一些 丢包的现象,而程序运行的时间也会更加的长。
ping 还给我们一个看主机到目的主机的路由的机会。这是因为,ICMP 的 ping 请求数据报在每经过一个路由器的时候,路由器都会把 自己的 ip 放到该数 据报中。而目的主机则会把这个 ip 列表复制到回应 icmp 数据包中发回给主机。但是,无论如何,ip 头所能纪录的 路由列表是非常的有限。如果要观察路由, 我们还是需要使用更好的工具,就是要讲到的 Traceroute(windows 下面的名字叫做 tracert)。
ICMP 的应用--Traceroute
Traceroute 是用来侦测主机到目的主机之间所经路由情况的重要工具,也是最便利的工具。前面说到,尽管 ping 工具也可以进行 侦测,但是,因为 ip 头的限制,ping 不能完全的记录下所经过的路由器。所以 Traceroute 正好就填补了这个缺憾。
Traceroute 的原理是非常非常的有意思,它受到目的主机的 IP 后,首先给目的主机发送一个 TTL=1(还记得 TTL 是什么吗?)的 UDP(后面就 知道 UDP 是什么了)数据包,而经过的第一个路由器收到这个数据包以后,就自动把 TTL 减1,而 TTL 变为0以后,路由 器就把这个包给抛弃了,并同时产生 一个主机不可达的 ICMP 数据报给主机。主机收到这个数据报以后再发一个 TTL=2的 UDP 数据报给目的主机,然后刺激第二个路由器给主机发 ICMP 数据 报。如此往复直到到达目的主机。这样,traceroute 就拿到了所有的路由器 ip。从而避开了 ip 头只能记录有限路由 IP 的问题。
有人要问,我怎么知道 UDP 到没到达目的主机呢?这就涉及一个技巧的问题,TCP 和 UDP 协议有一个端口号定义,而普通的网 络程序只监控少数的几个号码较 小的端口,比如说80,比如说23,等等。而 traceroute 发送的是端口号>30000(真变态)的 UDP 报,所以到 达目的主机的时候,目的 主机只能发送一个端口不可达的 ICMP 数据报给主机。主机接到这个报告以后就知道,主机到了,所以,说 Traceroute 是一个骗子一点也不为过
Traceroute 程序里面提供了一些很有用的选项,甚至包含了 IP 选路的选项,请察看 man 文档来了解这些,这里就不赘述了。