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

ICMP报文是在太多了,没有意义关注这么多,现在只要关注一下ping和traceroute两个指令就好了
ping,类型:0,代码:0,描述:回显应答,查询报文
Traceroute,类型:0,代码:0,描述:回显应答,差错报文
因为对ICMP差错报文有时候需要做特殊处理,因此我们需要对他们做区分。例如,在对ICMP差错报文进行响应时候,永远不会生成另外一份ICMP差错报文(如果没有这个限制,可能回遇到一个差错产生另外一个差错对情况,而差错再产生差错,这样无休止地循环下去)
Ping
ping这个词源于声纳定位这个操作,目的就是测试另一台主机是否可以到达,该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答。Ping程序还能测出到这台主机到往返时间,以表明该主机离我们有“多远”。
我们称发送回显请求的ping程序为客户,而称被ping的主机为服务器。大多数的TCP/IP实现都在内核中直接支持ping服务器,这种服务器不是一种用户进程(在内核中处理)。下面是ICMP的回显请求(客户端)和回显应答报文(服务端)的格式:
<br />我们来ping一下一个经典地址,www.baidu,com, 结果如下图所示:
- Unix系统在实现ping程序时是把ICMP报文中的标识符字段设置为发送进程ID号,这样即使在同一个主机上运行了多个ping程序实例,ping程序也可以识别出返回信息。 序列号从0开始,每发送一次新的回显请求就加1。ping程序打印出返回的每个分组的序号,允许我们查看是否有分组丢失,失序或重复
- 当返回ICMP回显应答时,要打印出ICMP序列号和TTL的时间,TTL每经过一个路由就会减1
- 通过ICMP报文数据中存放发送请求的时间值来计算往返时间。当应答返回时候,用当前时间减去存放在ICMP报文中的时间值,就是往返时间
- 我们还可以发现,如果输入命令之后,锅几秒钟之后才会打印IP地址,BNS就是利用这段时间来确定主机域名所对应的IP地址。
- 这个ping的程序是由Mike Muuss实现的
Traceroute
尽管不能保证此从源发往目的端的两份连续的IP数据包具有相同的路由,但是大多数情况下是这样的。traceroute程序可以让我们看到IP数据报从一台主机传到另一台主机所经过的路由。
Traceroute程序使用ICMP报文和IP首部中的TTL字段(生存周期)。TTL字段是由发送端初始设置一个8 bit字段,推荐的初始值为64。其操作过程如下:
- 发送一份TTL字段为1的IP数据报给目的主机,处理这份数据报的第一个路由器将TTL减1,丢弃该数据报,并发回一份超时ICMP报文,得到第一个路由器的地址
- 然后tracetoute程序发送TTL值为2的数据报,这样我们就可以得到第二个路由器地址
- 继续这个过程直到该数据报到达目的主机,但是目的主机哪怕接收到TTL值为1的IP数据报,也不会丢弃数据报产生一份超时报文,因为数据报已经到达最终目的地。我们是这么做的,traceroute发送一份UDP数据报给目的主机,但是它选择的是一个不可能的值作为UDP端口号(大于30000)。因此,当该数据报到达的时候,将使目的主机的UDP模块产生一份“端口不可达”错误的ICMP报文。Traceroute程序所要做的就是区分接收到的ICMP报文是超时还是端口不可达,以判定什么结束。
后面有机会还需要看一下ICMP重定向差错报文,ICMP发现报文,ICMP源站抑制差错报文,RIP协议之间的关系等
