traceroute程序可以使我们看到IP数据报从一台主机传到另一台主机的所经过的路由,并且可以使用IP源站路由选项。
traceroute
取代
IP RR
的原因
1
不是所有的路由器都支持
IP RR
选项,而
traceroute
程序不需要中间路由器具备任何特殊的或可选的功能。
2
记录路由一般是单向选项。发送端设置该选项,接收端不得不从收到的
IP
首部中提取出所有的信息,然后全部返回给发送端。这样使记录下来的
IP
地址多了一倍(一来一回)。
traceroute
程序只需要目的端运行一个
UDP
模块,其他不需要任何特殊的服务器应用程序。
3 IP
首部中留给
RR
选项的空间有限,不够存放当前大多数的路径。
traceroute
原理
traceroute
通过
ICMP“
超时
”
和
“
端口不可达
”
两种消息记录所经过路径的路由。
使用
“
超时
”
消息记录经过的路由:
traceroute
程序发送的数据报首部
TTL
字段由发送端设置成一个
8bit
字段。每个处理数据报的路由器都需要把
TTL
的值减
1
或减去数据报在路由器中停留的秒数。由于大多数的路由器转发数据报的时延都小于
1
秒,因此
TTL
最终成为一个跳数计数器,每经过一台路由器就将其值减
1
。
当路由器收到一份
IP
数据报,如果其
TTL
字段是
0
或
1
,则路由器不转发该数据报。通常情况下,系统不会接收
TTL
值为
0
的数据报。
1
接收到这种数据报的主机是目的主机,直接将其交给应用程序。
2
接收主机不是目的主机,直接将其丢弃,并给发送端发一份
ICMP
超时消息。
traceroute
程序记录所经过路由的关键在于包含这份
ICMP
信息的
IP
报文的信源地址是该路由器的入站接口
IP
地址。
使用
“
端口不可达
”
消息判断是否到达目的主机:
traceroute
程序发送一份
UDP
数据报给目的主机。但它选择一个不可能的值作为
UDP
端口号(大于
30000
),目的主机的任何一个应用程序都不可能使用该端口。因此,当该数据报到达时,将使目的主机的
UDP
模块产生一份
“
端口不可达
”
错误的
ICMP
报文。
traceroute
程序要做的就是区分接收到的
ICMP
错误报文是
“
超时
”
还是
“
端口不可达
”
来判断什么时间结束。
traceroute
示例

R1#traceroute 10.0.0.2
Type escape sequence to abort.
Tracing the route to 10.0.0.2
1 172.16.0.2 28 msec 24 msec 144 msec
2 192.168.1.2 144 msec 288 msec 160 msec
3 10.0.0.2 240 msec * 288 msec
1
R1
发送一份
TTL
字段为
1
的
IP
数据报给目的主机
R4
。处理这份数据报的第一个路由器
R2
将
TTL
值减
1
,然后丢弃该数据报,并发回一份超时
ICMP
报文。这样发送端就得到了该路径中的第一个路由器
R2
的地址
172.16.0.2
(入站接口地址),并把
R2
标记为该路径的第一跳。
2
R1
发送一份
TTL
字段为
2
的
IP
数据报给目的主机
R4
,经过
R2
时将
TTL
字段减
1
后转发至
R3
。
R3
接收到
IP
数据报将
TTL
字段减
1
后丢弃,并发回一份超时
ICMP
报文。这样就得到了该路径中的第二台路由器
R3
的地址
192.168.1.2
,并把
R3
标记为该路径的第二跳。
3
继续这个过程,
R1
发送一份
TTL
字段为
3
的
IP
数据报给目的主机
R4
,当到达
R4
后,该
IP
数据报使
R4
模块产生一份
ICMP“
端口不可达
”
错误报文并发送给源。
traceroute
过程此时结束。
svr4 % traceroute slip
traceroute to slip (140.252.13.65)
,
30 hops max
,
40byte packets
1 bsdi
(
140.252.13.35
)
20ms 10ms 10ms
2 slip
(
140.252.13.65
)
120ms 120ms 120ms
//
主机名,
IP
地址,
3
份数据报的往返时间
输出的第
1
个无标号行给出了目的主机名和其
IP
地址,指出
TTL
最大值是
30
。
40
字节的数据报包含
20
字节
IP
首部,
8
字节的
UDP
首部和
12
字节的用户数据(序列号,
TTL
副本,发送数据报的时间)输出的后面两行以
TTL
开始,接下来是主机或路由器名及其
IP
地址。对于每个
TTL
值,发送
3
份数据报。每接收到一份
ICMP
报文,就计算并打印出往返时间。如果在
5
秒内仍未收到
3
份数据报的任意一份响应,则打印一个
*
号,并发送下一份数据报。
目的主机的端口号最初设置为
33435
,每发送一个数据报加
1
。可以通过命令行选项来改变开始的端口号。
当路由器将
TTL
值减到
0
时将发回
“
传送超时
”
的
ICMP
报文。即使这份被丢弃的
IP
报文发送往目的地,路由器也会发回
ICMP
报文。
ICMP
超时报文格式
有两种不同的
ICMP
超时报文,它们的
ICMP
报文中的
code
字段不同。
ICMP
差错报文的格式如下:

我们所讨论的
ICMP
报文是在
TTL
值为
0
时产生的,其代码字段为
0
。
主机在组装分片时可能发生超时。这时它将发送一份
“
组装报文超时
”
的
ICMP
报文。这种差错报文将
code
字段置
1
。
traceroute
注意事项
对于在同一台主机上多次运行
traceroute
程序的情况,每个进程都查看
ICMP
返回的
UDP
首部的源端口号,并且只处理那些对自己发送应答的报文。
1
不能保证现在的路由也是将来要采用的路由。甚至两份连续的
IP
数据报都可能采用不同的路由。
2
不能保证
ICMP
报文的路由与
traceroute
程序发送的
UDP
数据报采用同一路由。这表明所打印出来的往返时间可能并不能真正体现数据报发出和返回的时间差。(如果
UDP
数据报从信源到路由器的时间是
1
秒,而
ICMP
报文用另一条路由返回信源用了
3
秒时间,则打印出来的往返时间是
4
秒。
3
返回的
ICMP
报文中的信源
IP
地址是
UDP
数据报到达的路由器接口的
IP
地址。这与
IP RR
选项不同,记录的
IP
地址指的是入站接口地址。由于每个定义的路由器都有多个接口,因此从
A
到
B
和从
B
到
A
运行
traceroute
程序所得到的结果可能是不同的。
IP
源站选路选项
通常
IP
路由是动态的,即每个路由器都要判断数据报下面该转发到哪个路由器。应用程序对此不进行控制,而且通常也并不关心路由。
源站选路的思想是由发送者指定路由。它可以采用以下两种方式:
1
严格的源路由选择(
LSRR
)
发送端指明
IP
数据报所必须采用的确切路由。如果一个路由器发现源路由所指定的下一个路由器不在其直接连接的网络上,那么它就返回一个
“
源站选路失败
”
的
ICMP
报文。
2
宽松的源站选路(
SSRR
)
发送端指明了一个数据报经过的
IP
地址清单,但是数据报在清单上指明的任意两个地址之间可以通过其他路由器。
源站路由选项格式:

此格式与
IP RR
选项格式基本一致。不同之处是,对于源站选路,我们必须在发送
IP
数据报前填充
IP
地址清单。而对于记录路由选项,需要为
IP
地址清单分配并清空一些空间,并让路由器填充该清单中的各项。
宽松的源站选路的
code
字段的值是
0x83
;严格的源站选路的值是
0x89
。
扩展
traceroute
选项
R1#traceroute
Protocol [ip]:
//
指定协议类型
Target IP address:
//
与指定协议相关的目标地址
Source address:
//
指定源地址
Numeric display [n]:
//
数字显示
Timeout in seconds [3]:
//
设置超时时间。默认为
3
秒
Probe count [3]:
//
发送
UDP
包的数量。默认为
3
个
Minimum Time to Live [1]:
//
设定最小
TTL
值。默认为
1
Maximum Time to Live [30]:
//
设定最大
TTL
值。默认为
30
Port Number [33434]:
//UDP
报文使用的目的端口号。默认为
33434
Loose, Strict, Record, Timestamp, Verbose[none]:
//option
功能。可以指定任意组合。