前言
与前面学习的
ping
命令类似,还存在一个traceroute
命令,其基于UDP
协议。
Traceroute
Traceroute
不能保证从源端发往目的端的两份连续的ip
数据报具有相同的路由(链路环境变化导致选择路由不同),但多数时候相同。同时由于其基于UDP
协议,所以不能保证ip
数据报一定到达目的端。
通过ping
命令的-RR
参数可支持记录路由选项,但相比与traceroute
,其有如下三点需要考虑。
- 并非所有路由器都支持记录路由选项功能。
- 记录路由一般为单项选项,发送端设置该选项,则接收端从
ip
首部提取所有信息,然后全部返回给发送端,这样使得记录的ip
地址长度翻倍。 ip
首部中留给选项的空间有限,不能存放当前的大多数路径,如ip
首部选项字段最多只能存放9
个ip
地址,这是远远不够的。
traceroute
使用ICMP
报文和ip
报文首部中的TTL
字段,TTL
字段一般设置为64
,而在ping
中一般设置为255
。所经过每隔路由器都将TTL
减少1
。TTL
字段是为防止数据报在选路时无休止地在网络中流动,当路由器收到一份IP
数据报,如果其TTL
字段是0或1
,则路由器不转发该数据报(接收该数据报的目的主机可将它交给应用程序);否则,路由器将该数据报丢弃,并给源端发一份ICMP
超时信息,而traceroute
的关键在于包含这份ICMP信息的IP报文的源端地址(目的端为发送源)是该路由器的IP地址。
traceroute
执行过程如下。
- 发送一份
TTL
字段为1
的IP
数据报给目的主机,处理该数据报的第一个路由器将TTL
减少1
,丢弃该数据报,并发回一份超时ICMP
报文,这样便得到该路径第一个路由器地址。 - 发送一份
TTL
字段为2
的IP
数据报给目的主机,这样便可得到第二个路由器地址。 - 继续上面过程(每次
TTL
值加1
),直至该数据报到达目的主机。
值得注意的是,当目的主机收到TTL
为1
的IP
数据报时,不会丢弃该数据报并产生ICMP
超时报文,那么如何判断是否已经到达了目的主机呢?traceroute
发送udp
数据报给目的主机,并选择不可能的端口值(>30000,使得目的主机应用程序都不能使用),这样目的主机就会产生udp
端口不可达错误,这样源主机只需要确认接收到的ICMP
报文时超时还是端口不可达即可。
traceroute输出
当使用traceroute www.qq.com
时有如下输出。
可以看到最大TTL
为30
,数据报长度为60
。然后路由器名和IP
地址为(10.0.2.2),对于每个TTL
会发出3
份数据报,没收到一份数据报,则显示往返时间,若在5s
内未收到3
份数据报中的任意一份,则显示*
。
IP源站选路选项
IP
路由是动态的,每个路由都要判断数据报下面该转发到哪个路由器。源站选路的思想是由发送者指定路由,通常有如下两种方式。
- 严格源站选路。发送端指明
IP
数据报必须采用的确切路由,若路由器发现源路由所指定的下一个路由器不在直接连接的网络上,那么就返回一个源站路由失败的ICMP
差错报文。 - 宽松源站选路。发送端指明
IP
数据报经过的IP
地址清单,但数据报在清单上指明的任意两个地址之间可以通过其他路由器。
源站路由选项的格式如下所示。
必须要在发送IP
数据报之前填充IP
地址清单;严格源站选路的code
字段值为0x83
,而宽松源站选路的code
字段值为0x85
;在数据报沿路由器发送过程中,对IP
地址会进行更新,过程如下。
- 发送主机从应用程序接收源站路由清单,将第一个表项(最终目的地址)去掉,再将其他剩余表项左移一个位置,最后将原来的第一个表项作为清单的最后一项。
- 每个处理数据报的路由器检查其是否为数据报的最终地址,若不是,则正常转发数据报(宽松源站选路)。
- 若该路由器为最终目的,且指针不大于路径长度,那么进行如下操作。
- 由
ptr
指定的下一个地址就是数据报的最终目的地址; - 由外出接口相对应的
IP
地址取代刚才使用的源地址; - 指针加
4
。
- 由
下面为示例,假定主机S
的应用程序发送一份数据报给D
,指定源路由为R1、R2、R3
。
其中,#
表示指针字段,值分别为4、8、12、16
,每一跳IP
数据报中的目的地址都发生了改变。
总结
traceroute
程序开始时发送一个TTL
为1的UDP
数据报,然后将TTL
字段每次加1
,以确定路径中的每个路由器,每个路由器在丢弃UDP
数据报时都会返回一个ICMP
超时报文,而最终的目的主机则产生一个ICMP
端口不可达的报文,源端根据返回的不同报文确定最终的目的地址。