ICMP
ICMP 协议之内容
ICMP 的全称是 Internet Control Message Protocol 。从技术教度来说,ICMP 就是一个 "错误侦测与回报机制",其目的就是让我们能够检测网络的联机状况﹐也能确保联机的准确性﹐其功能主要有﹕
· 侦测远程主机是否存在。
· 建立及维护路由数据。
· 重导数据传送路径。
· 数据流量控制。
ICMP 在沟通之中,主要是透过不同的类别( Type )与代码( Code ) 让机器来识别不同的联机状况。常用的类别如下表所列﹕
类别 | 名称 | 代表意思 |
0 | Echo Reply | 是一个回应信息。 |
3 | Distination Unreachable | 表示目的地不可到达。 |
4 | Source Quench | 当 router 负载过时﹐用来竭止来源继续发送讯息。 |
5 | Redirect | 用来重新导向路由路径。 |
8 | Echo Request | 请求响应讯息。 |
11 | Time Exeeded for a Datagram | 当资料封包在某些路由现象中逾时﹐告知来源该封包已被忽略忽略。 |
12 | Parameter Problem on a Datagram | 当一个 ICMP 封包重复着之前的错误时﹐会回复来源主机关于参数错误的讯息。 |
13 | Timestamp Request | 要求对方送出时间讯息﹐用以计算路由时间的差异﹐以满足同步性协议的要求。 |
14 | Timestamp Replay | 此讯息纯粹是响应 Timestamp Request 用的。 |
15 | Information Request | 在 RARP 协议应用之前﹐此讯息是用来在开机时取得网络信息。 |
16 | Information Reply | 用以回应 Infromation Request 讯息。 |
17 | Address Mask Request | 这讯息是用来查询子网络 mask 设定信息。 |
18 | Address Mask Reply | 响应子网络 mask 查询讯息的。 |
在 ICMP 使用中﹐不同的类别会以不同的代码来描述具体的状况。以 Type 3 ( Distination Unreachable ) 为例,其下的代码如下所列﹕
代码 | 代表意思 |
0 | Network Unreachable |
1 | Host Unreachable |
2 | Protocol Unreachable |
3 | Port Unreachable |
4 | Fragmentation Needed and DF set |
5 | Source Route Failed |
6 | Destination network unknown |
7 | Destination host unknown |
8 | Source host isolated |
9 | Communication with destination network administraively prohibited |
10 | Communication with destination host administraively prohibited |
11 | Network unreachable for type of service |
12 | host unreachable for type of service |
ICMP 是个非常有用的协议﹐尤其是当我们要对网络连接状况进行判断的时候。下面让我们看看常用的 ICMP 实例,以更好了解 ICMP 的功能与作用。
关于 PING
l 原理:
ping这个单词源自声纳定位,而这个程序的作用也确实如此,它利用ICMP协议包来侦测另一个主机是否可达。原理是用类型码为0的ICMP发请求,受到请求的主机则用类型码为8的ICMP回应。ping程序来计算间隔时间,并计算有多少个包被送达。用户就可以判断网络大致的情况。我们可以看到, ping给出来了传送的时间和TTL的数据。
l PING命令详解
对于Windows下ping命令相信大家已经再熟悉不过了,但是能把ping的功能发挥到最大的人却并不是很多,当然我也并不是说我可以让ping发挥最大的功能,我也只不过经常用ping这个工具,也总结了一些小经验,现在和大家分享一下。
现在我就参照ping命令的帮助说明来给大家说说我使用ping时会用到的技巧,ping只有在安装了TCP/IP协议以后才可以使用:
ping [-t] [-a] [-n count] [-l length] [-f] [-i ttl] [-v tos] [-r count] [-s count] [-j computer-list] │ [-k computer-list] [-w timeout] destination-list
Options:
-t Ping the specified host until stopped.To see statistics and continue - type Control-Break;To stop - type Control-C.
不停的ping地方主机,直到你按下Control-C。
此功能没有什么特别的技巧,不过可以配合其他参数使用,将在下面提到。
-a Resolve addresses to hostnames.
解析计算机NetBios名。
示例:
C:\>ping -a 192.168.1.21
Pinging iceblood.yofor.com [192.168.1.21] with 32 bytes of data:
Reply from 192.168.1.21: bytes=32 time<10ms TTL=254
Reply from 192.168.1.21: bytes=32 time<10ms TTL=254
Reply from 192.168.1.21: bytes=32 time<10ms TTL=254
Reply from 192.168.1.21: bytes=32 time<10ms TTL=254
Ping statistics for 192.168.1.21:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
从上面就可以知道IP为192.168.1.21的计算机NetBios名为iceblood.yofor.com。
-n count Number of echo requests to send.
发送count指定的Echo数据包数。
在默认情况下,一般都只发送四个数据包,通过这个命令可以自己定义发送的个数,对衡量网络速度很有帮助,比如我想测试发送50个数据包的返回的平均时间为多少,最快时间为多少,最慢时间为多少就可以通过以下获知:
C:\>ping -n 50 202.103.96.68
Pinging 202.103.96.68 with 32 bytes of data:
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Request timed out.
………………
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Ping statistics for 202.103.96.68:
Packets: Sent = 50, Received = 48, Lost = 2 (4% loss),Approximate round trip times in milli-seconds:
Minimum = 40ms, Maximum = 51ms, Average = 46ms
从以上我就可以知道在给202.103.96.68发送50个数据包的过程当中,返回了48个,其中有两个由于未知原因丢失,这48个数据包当中返回速度最快为40ms,最慢为51ms,平均速度为46ms。
-l size Send buffer size.
定义echo数据包大小。
在默认的情况下windows的ping发送的数据包大小为32byt,我们也可以自己定义它的大小,但有一个大小的限制,就是最大只能发送65500byt,也许有人会问为什么要限制到65500byt,因为Windows系列的系统都有一个安全漏洞(也许还包括其他系统)就是当向对方一次发送的数据包大于或等于65532时,对方就很有可能当机,所以微软公司为了解决这一安全漏洞于是限制了ping的数据包大小。虽然微软公司已经做了此限制,但这个参数配合其他参数以后危害依然非常强大,比如我们就可以通过配合-t参数来实现一个带有攻击性的命令:(以下介绍带有危险性,仅用于试验,请勿轻易施于别人机器上,否则后果自负)
C:\>ping -l 65500 -t 192.168.1.21
Pinging 192.168.1.21 with 65500 bytes of data:
Reply from 192.168.1.21: bytes=65500 time<10ms TTL=254
Reply from 192.168.1.21: bytes=65500 time<10ms TTL=254
………………
这样它就会不停的向192.168.1.21计算机发送大小为65500byt的数据包,如果你只有一台计算机也许没有什么效果,但如果有很多计算机那么就可以使对方完全瘫痪,我曾经就做过这样的试验,当我同时使用10台以上计算机ping一台Win2000Pro系统的计算机时,不到5分钟对方的网络就已经完全瘫痪,网络严重堵塞,HTTP和FTP服务完全停止,由此可见威力非同小可。
-f Set Don't Fragment flag in packet.
在数据包中发送“不要分段”标志。
在一般你所发送的数据包都会通过路由分段再发送给对方,加上此参数以后路由就不会再分段处理。
-i TTL Time To Live.
指定TTL值在对方的系统里停留的时间。
此参数同样是帮助你检查网络运转情况的。
-v TOS Type Of Service.
将“服务类型”字段设置为 tos 指定的值。
-r count Record route for count hops.
在“记录路由”字段中记录传出和返回数据包的路由。
在一般情况下你发送的数据包是通过一个个路由才到达对方的,但到底是经过了哪些路由呢?通过此参数就可以设定你想探测经过的路由的个数,不过限制在了9个,也就是说你只能跟踪到9个路由,如果想探测更多,可以通过其他命令实现,我将在以后的文章中给大家讲解。以下为示例:
C:\>ping -n 1 -r 9 202.96.105.101 (发送一个数据包,最多记录9个路由)
Pinging 202.96.105.101 with 32 bytes of data:
Reply from 202.96.105.101: bytes=32 time=10ms TTL=249
Route: 202.107.208.187 ->
202.107.210.214 ->
61.153.112.70 ->
61.153.112.89 ->
202.96.105.149 ->
202.96.105.97 ->
202.96.105.101 ->
202.96.105.150 ->
61.153.112.90
Ping statistics for 202.96.105.101:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 10ms, Maximum = 10ms, Average = 10ms
从上面我就可以知道从我的计算机到202.96.105.101一共通过了202.107.208.187 ,202.107.210.214 , 61.153.112.70 , 61.153.112.89 , 202.96.105.149 , 202.96.105.97这几个路由。
-s count Timestamp for count hops.
指定 count 指定的跃点数的时间戳。
此参数和-r差不多,只是这个参数不记录数据包返回所经过的路由,最多也只记录4个。
-j host-list Loose source route along host-list.
利用 computer-list 指定的计算机列表路由数据包。连续计算机可以被中间网关分隔(路由稀疏源)IP 允许的最大数量为 9。
-k host-list Strict source route along host-list.
利用 computer-list 指定的计算机列表路由数据包。连续计算机不能被中间网关分隔(路由严格源)IP 允许的最大数量为 9。
-w timeout Timeout in milliseconds to wait for each reply.
指定超时间隔,单位为毫秒。
此参数没有什么其他技巧。
ping命令的其他技巧:在一般情况下还可以通过ping对方让对方返回给你的TTL值大小,粗略的判断目标主机的系统类型是Windows系列还是UNIX/Linux系列,一般情况下Windows系列的系统返回的TTL值在100-130之间,而UNIX/Linux系列的系统返回的TTL值在240-255之间,当然TTL的值在对方的主机里是可以修改的,Windows系列的系统可以通过修改注册表以下键值实现:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"DefaultTTL"=dword:000000ff
255---FF
128---80
64----40
32----20
Ping命令序列生成又一妙法
打开DOS窗口,键入:
for /L %i in (1,1,224) do ping -n 2 192.168.2.%i>>test.txt命令,将从IP地址192.168.2.1开始,192.168.2.224结束,对每一台电脑执行Ping命令,并将结果保存到test.txt中。
这方法很不错,经常用到很方便
PING工具里的Byte= ` Time=` TTL=`究竟是什么意思啊?
TTL是IP协议包中的一个值,它告诉网络路由器包在网络中的时间是否太长而应被丢弃。有很多原因使包在一定时间内不能被传递到目的地。例如,不正确的路由表可能导致包的无限循环。所以需要在包中设置这样一个值,包在每经过一个节点,将这个值减1,反复这样操作,最终可能造成两个结果:包在这个值还为正数的时候到达了目的地,或者是在经过一定数量的节点后,这个值减为了0。前者代表完成了一次正常的传输,后者代表包可能选择了一条非常长的路径甚至是进入了环路,这显然不是我们期望的,所以在这个值为0的时候,网络设备将不会再传递这个包而是直接将他抛弃,并发送一个通知给包的源地址,说这个包已死。 第二个问题,通过TTL值我们能得到什么 其实TTL值这个东西本身并代表不了什么,对于使用者来说,关心的问题应该是包是否到达了目的地而不是经过了几个节点后到达。但是TTL值还是可以得到有意思的信息的。 每个操作系统对TTL值得定义都不同,这个值甚至可以通过修改某些系统的网络参数来修改,例如Win2000默认为128,通过注册表也可以修改。而Linux大多定义为64。不过一般来说,很少有人会去修改自己机器的这个值的,这就给了我们机会可以通过ping的回显TTL来大体判断一台机器是什么操作系统。如你看到112,可能是初始128,跳了16个节点,或者是初始160,跳了48次。
不同的操作系统,它的TTL值默认值是不相同的。默认情况下,Linux系统的TTL值为64或255,Windows NT/2000/XP系统的TTL值为128,Windows 98系统的TTL值为32,UNIX主机的TTL值为255。
以我公司2台机器为例 看如下命令 ping 61.152.93.131
Pinging 61.152.93.131 with 32 bytes of data:
Reply from 61.152.93.131: bytes=32 time=21ms TTL=118
Reply from 61.152.93.131: bytes=32 time=19ms TTL=118
Reply from 61.152.93.131: bytes=32 time=18ms TTL=118
Reply from 61.152.93.131: bytes=32 time=22ms TTL=118
Ping statistics for 61.152.93.131: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss
Approximate round trip times in milli-seconds:
Minimum = 18ms, Maximum = 22ms, Average = 20ms
ping 61.152.104.40 Pinging 61.152.104.40 with 32 bytes of data:
Reply from 61.152.104.40: bytes=32 time=28ms TTL=54
Reply from 61.152.104.40: bytes=32 time=18ms TTL=54
Reply from 61.152.104.40: bytes=32 time=18ms TTL=54
Reply from 61.152.104.40: bytes=32 time=13ms TTL=54
Ping statistics for 61.152.104.40: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss
Approximate round trip times in milli-seconds:
Minimum = 13ms, Maximum = 28ms, Average = 19ms
第一台TTL为118,则基本可以判断这是一台Windows机器,从我的机器到这台机器经过了10个节点,因为128-118=10。而第二台应该是台Linux,理由一样64-54=10。 了解了上面的东西,可能有人会有一些疑问,例如以下: 1,不是说包可能走很多路径吗,为什么我看到的4个包TTL都是一样的,没有出现不同? 这是由于包经过的路径是经过了一些最优选择算法来定下来的,在网络拓扑稳定一段时间后,包的路由路径也会相对稳定在一个最短路径上。具体怎么算出来的要去研究路由算法了,不在讨论之列。 2,对于上面例子第二台机器,为什么不认为它是经过了74个节点的Windows机器?因为128-74=54。 对于这个问题,我们要引入另外一个很好的ICMP协议工具。不过首先要声明的是,一个包经过74个节点这个有些恐怖,这样的路径还是不用为好。 要介绍的这个工具是tracert(*nix下为traceroute),让我们来看对上面的第二台机器用这个命令的结果 tracert 61.152.104.40
Tracing route to 61.152.104.40 over a maximum of 30 hops
1 13 ms 16 ms 9 ms 10.120.32.1
2 9 ms 9 ms 11 ms 219.233.244.105
3 12 ms 10 ms 10 ms 219.233.238.173
4 15 ms 15 ms 17 ms 219.233.238.13
5 14 ms 19 ms 19 ms 202.96.222.73
6 14 ms 17 ms 13 ms 202.96.222.121
7 14 ms 15 ms 14 ms 61.152.81.86
8 15 ms 14 ms 13 ms 61.152.87.162
9 16 ms 16 ms 28 ms 61.152.99.26
10 12 ms 13 ms 18 ms 61.152.99.94
11 14 ms 18 ms 16 ms 61.152.104.40
Trace complete.
从这个命令的结果能够看到从我的机器到服务器所走的路由,确实是11个节点(上面说10个好像是我犯了忘了算0的错误了,应该是64-54+1,嘿嘿),而不是128的TTL经过了70多个节点。 既然已经说到这里了,不妨顺便说说关于这两个ICMP命令的高级一点的东西。 首先是ping命令,其实ping有这样一个参数,可以无视操作系统默认TTL值而使用自己定义的值来发送ICMP Request包。 例如还是用那台Linux机器,用以下命令: ping 61.152.104.40 -i 11
Pinging 61.152.104.40 with 32 bytes of data:
Reply from 61.152.104.40: bytes=32 time=10ms TTL=54
Reply from 61.152.104.40: bytes=32 time=13ms TTL=54
Reply from 61.152.104.40: bytes=32 time=10ms TTL=54
Reply from 61.152.104.40: bytes=32 time=13ms TTL=54
Ping statistics for 61.152.104.40: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 10ms, Maximum = 13ms, Average = 11ms
这个命令我们定义了发包的TTL为11,而前面我们知道,我到这台服务器是要经过11个节点的,所以这个输出和以前没什么不同。现在再用这个试试看: ping 61.152.104.40 -i 10
Pinging 61.152.104.40 with 32 bytes of data:
Reply from 61.152.99.94: TTL expired in transit.
Reply from 61.152.99.94: TTL expired in transit.
Reply from 61.152.99.94: TTL expired in transit.
Reply from 61.152.99.94: TTL expired in transit.
Ping statistics for 61.152.104.40: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
可以看到,结果不一样了,我定义了TTL为10来发包,结果是TTL expired in transit.就是说在到达服务器之前这个包的生命周期就结束了。注意看这句话前面的ip,这个ip恰好是我们前面tracert结果到服务器之前的最后1个ip,包的TTL就是在这里减少到0了,根据我们前面的讨论,当TTL减为0时设备会丢弃包并发送一个TTL过期的ICMP反馈给源地址,这里的结果就是最好的证明。 通过这里再次又证明了从我机器到服务器是经过了11个节点而不是70多个,呵呵。 最后再巩固一下知识,有人可能觉得tracer这个命令很神奇,可以发现一个包所经过的路由路径。其实这个命令的原理就在我们上面的讨论中。 想象一下,如果我给目的服务器发送一个TTL为1的包,结果会怎样? 根据前面的讨论,在包港出发的第一个节点,TTL就会减少为0,这时这个节点就会回应TTL失效的反馈,这个回应包含了设备本身的ip地址,这样我们就得到了路由路径的第一个节点的地址。 因此,我们继续发送TTL=2的包,也就受到第二个节点的TTL失效回应 依次类推,我们一个一个的发现,当最终返回的结果不是TTL失效而是ICMP Response的时候,我们的tracert也就结束了,就是这么简单。 顺便补一句ping命令还有个-n的参数指定要发包的数量,指定了这个数字就会按照你的要求来发包了而不是默认的4个包。如果使用-t参数的话,命令会一直发包直到你强行中止它。
byte:通过对目标计算机发送数据包,以检查其返回时间并判断网络速度,bytes=32就是说对目标计算机发送32位数据包!
time:指响应时间
TTL:全称Time to Live,意思就是生存周期。
ping -c 4 10.0.1.131 |
PING 10.0.1.130 (10.0.1.130) from 10.0.1.130 : 56(84) bytes of data. |
在 Linux 使用 ping 命令﹐如果您不使用 -c N 参数来指定送出多少个 ICMP 封包的话﹐ping 命令会一直持续下去﹐直到您按 Ctrl + C 为止。从上面的命令结果我们可以确定联机是否成功之外﹐还可以根据它的 time 来判断当前的联机速度﹐数值越低速度越快﹔在命令结束的两行﹐还有一个总结﹐如果发现您的 packet loss 很严重的话﹐那就要检察您的线路质量﹐或是上游的服务质量了﹔最后一行是 round-trip (来回)时间的最小值﹑平均值﹑最大值﹐它们的时间单位都是微秒 (ms)。不过﹐那个 mdev 是什么意思我也不知道~~
如果运用得当﹐ping 可以帮我们判断出许多状况。例如﹐我们要看一下跟远方的机器是否连接得上﹐先可以 ping 一下对方的机器名称﹔如果连接不上的话﹐我们可以 ping 对方的 ip ﹐如果 ip 可以 ping 得到﹐那么﹐很可能是 dns 不工作了﹔那么我们可以检查本身主机的 dns 服务器是否指定正确、以及 dns 服务器是否设定正确。如果连 IP 都 ping 不了﹐那么﹐很可能是 IP 设定的问题了﹐也可能是网络的联机问题。检查的步骤也有很多种﹐下面是方法之一﹕
1. ping 对方的 router (如过您知道其地址的话)﹐假如 ping 得上﹐那可能是对方机器和其相连网络的问题﹔
2. 如果 ping 不到对方的 router ﹐那么可以 ping 自己的 router。如果 ping 得上﹐那么好可能是 router 和 router 之间的问题﹔
3. 如果自己的 router 也 ping 不到﹐那么可能是自己的机器和 router 之间的问题﹐我们可以 ping 一下自己的 IP 。如果自己的 IP 可以 ping 得到﹐那么﹐可能是联机的问题﹐我们可以检查一下网线、hub、等设备﹐看看有没有损毁的状况。
4. 同时﹐我们也可以 pin g一下网络上面其它的机器﹐也可以用其它机器 ping 一下 router ﹐来判别一下问题来自自己机器、还是网络、还是 router、等等。
5. 如果自己的 IP 都 ping 不到﹐那么可能是网络卡坏掉了或没有正确设定﹐可以看看设备资源有没有冲突﹐也可以看看设备有没有被系统启动。
6. 如果看来都没问题﹐那么可以 ping 一下循环地址 127.0.0.1 ﹐如果连这个都 ping 不了的话﹐这台机器的 IP 功能根本就没被启动﹗那么﹐您就要先检查一下网络功能有没有选择、IP 协议有没有被绑定( bind )、等基本网络设定了。
从上面的过程中﹐我们不难看出 ping 这个命令真是非常有用的。然而,我们能 ping 一台机器的时候﹐我们就可以确定联机是成功的﹐但如果不能 ping 的话﹐未必是连不上哦。嗯﹖怎么说呢﹖且听我道来﹕使用 ping 命令的时候﹐事实上是送出一个 echo-request( type 8 ) 的 ICMP 封包﹐如果对方的机器能接收到这个请求﹐而且愿意作出响应﹐则送回一个 echo-reply( type 0 ) 的 ICMP 封包﹐当这个响应能顺利抵达的时候﹐那就完成一个 ping 的动作。
很显然﹐如果这个 echo-request 不能到达对方的机器﹐或是对方响应的 echo-reply 不能顺利送回来﹐那 ping 就失败。这情形在许多有防火墙的环境中都会碰到﹐如果防火墙随便将 request 和 reply 拦下来就会导致 ping 失败﹐但并不代表其它联机不能建立。另外﹐就算没有防火墙作怪﹐对方也可以将机器设定为不响应任何 echo-request 封包﹐若在 Linux 上,只要用下面命令就可以了﹕
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all |
如果您不想别人 ping 您的机器﹐也可以如法泡制。但真的当您需要用 ping 命令来测试网络联机的时候﹐就做不到了﹐有利有弊啦。
关于 TRACEROUTE
除了用 ping 命令来检查联机之外﹐还有另外一个非常厉害的工具我们可以使用的﹐就是 traceroute 命令了(在 windows 上面则称为 tracert 命令)﹕
traceroute www.yahoo.com |
traceroute: Warning: www.yahoo.com has multiple addresses; using 216.115.102.78 |
透过 traceroute 命令﹐我们可以找出通往目的地的所有经过的路由节点﹐并以数字将路由顺序标识出来。若是您觉得响应很慢,那可加上 -n 参数﹐节点名称将会以 IP 地址显示﹐因为不需要进行名称解析﹐响应速度当然会快一些。
从上面的 traceroute 结果﹐我们可以看到每一个节点都返回 3 个 round-trip 时间作参考。这样﹐您就能够判断整个联机路由中﹐交通瓶颈所在的位置在哪里。您或许奇怪 traceroute 是如何揪出所有路由节点的呢﹖且听我细说﹕
您是否有留意到 ping 命令的结果有一个 TTL 值﹖通常来说﹐Time To Live 都是以时间为单位的﹐但是在路由上面却是以跳站数目为单位的。为了防止一个封包无限期呆在网络上路由﹐每一个封包都会被赋予一个 TTL 值﹐告诉它最多能经过多少个跳站。当封包被一个路由节点处理之后﹐它原来的 TTL 值就会被扣掉 1 ﹐这样﹐如果封包的 TTL 降到 0 的时候﹐路由器就会丢弃这个封包﹐并且同时向来源地送出一个 time_exceeded( type 11 ) 的 ICMP 封包﹐以告知其封包的命运。
找到灵感了吗﹖聪明的 traceroute 程序设计者正是利用了 ICMP 这个特殊功能﹐来找出每一个路由节点的﹕
1. 首先﹐traceroute 命令会向目标地址送出 UDP 侦测封包(在 Linux 中,可用 -I 改为 ICMP 封包)﹐但将第一个送出的封包之 TTL 设为 1 。这样﹐第一个路由节点在处理这个封包的时候﹐减掉 1 ,并发现 TTL 为 0 ﹐于是就不处理这个封包﹐并同时送回一个 ICMP 封包。这样﹐发送端就知道第一个路由节点在哪里了。
2. 当接得到第一个 ICMP 返回的时候﹐程序会检查返回主机是否就是目标主机﹐如果不是﹐则再送出第二个封包﹐但 TTL 比上次增加 1 。
3. 这样﹐第一路由节点接到的封包之 TTL 就不是 0 ﹐那么处理完毕后送给下一个节点﹐同时将 TTL 扣除 1 。这样,当下一个站收到这个封包,再扣掉 TTL 为 0 ﹐也会送回 ICMP 封包﹐这样﹐程序就知道第二个路由节点在哪里了。
4. 然后重复上一个动作﹐直到找到目标主机为止﹐或是封包的最大 TTL (通常为 30) 都用光为止﹐但您可以用 -m 参数来指定最大的 TTL 值。
怎样﹖聪明吧﹗^_^
但是﹐在实作中﹐未必是所有路由设备都会﹑或愿意送回 ICMP 封包的。碰到这样的情况﹐您就会看到第 8 个跳站的情形了(以星号显示)。假如 traceroute 最后的结果一直维持着 * 符号﹐那可能是因为 ICMP 被对方的防火墙拦下来的结果。这样的话﹐您可能无法完成防火墙后的路由追踪了。
从上面的例子来观察﹐由第 6 个跳站开始明显降慢下来﹐而根据名称看来﹐应该就是 ISP 连出 backbond 的节点。假如您发现从内部网络到自己的 router 之间的联机都很快﹐过了 router 之后就很慢﹐如果不是专线的线路出现了问题﹐那很可能到了要升级专线的时候了﹐或是这时候刚好碰到有人大量使用频宽﹔假如速度过了 router 连到对方的机房还很快﹐然后就开始降下来﹐那您要好好审查一下当初和 ISP 签订的合约上﹐关于频宽的保证问题是如何说的﹔但如果您发现联机到国外的网站﹐而速度是从进入对方国家之后才降下来的﹐那就没什么办法好想了。
其实 ICMP 协议还有许多实在上面的例子﹐这里不一一介绍了。能灵活运用 ICMP 协议﹐对我们了解和测试网络情况非常有帮助。
ICMP 封包格式
由于 ICMP 的类别翻多,且各自又有各自的代码,因此,ICMP 并没有一个统一的封包格式以供全部 ICMP 讯息使用,不同的 ICMP 类别分别有不同的封包字段。以 echo-request 与 echo-reply 为例,它们的 ICMP 封包内容如下:
0 | 8 | 16 | 31 |
Type | Code | Checksum |
Identifier | Sequence Number | |
OPTIONAL DATA |
ICMP 与 IP 的关系
在 OSI 模型中,ICMP 协议虽然与 IP 协定同为第三层协议,但 ICMP 本身是不具备传送能力的。实实上,它跟 TCP/UDP 一样,也是考 IP 帮忙进行传送。其封包结构如下:
因此,只要网络之间能支持 IP ,那就可透过 ICMP 进行错误侦测与回报。