TCP/IP协议-Ping 与 Traceroute 程序

风尘

文章目录

  1. 1. Ping 程序
    1. 1.1. LAN 输出
    2. 1.2. WAN 输出
    3. 1.3. IP 记录路由选项
  2. 2. Traceroute 程序
    1. 2.1. LAN 输出
    2. 2.2. WAN 输出
    3. 2.3. IP 源站选路选项
    4. 2.4. traceroute 命令示例

[TOC]

Ping 程序

名字源于声纳定位,用于测试目的主机是否可达。该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答。

一般来说,如果不能Ping到某台主机,也就不能TelnetFTP到那台主机。

随着Internet安全意识的增强,出现了提供访问控制清单的路由器和防火墙,像这样的无限定的断言就不再成立了。

一台主机的可达性可能不只取决于IP层是否可达,还取决于使用何种协议以及端口号。

Ping程序还能测出到这台主机的往返时间,表明该主机离我们有“多远”。

发送回显请求的 Ping 程序为客户,被 Ping 主机称为服务器。

大多数TCP/IP实现都在内核中直接支持Ping服务器,这种服务器不是一个用户进程。

ICMP 回显请求和应答报文ICMP 回显请求和应答报文

对于其他类型的ICMP查询报文,服务器必须响应标识符和序列号字段。另外,客户发送的选项数据必须回显。

Unix系统在实现Ping程序时是把ICMP报文中的标识符字段置成发送进程的ID号。这样即使在同一台主机上同时运行了多个Ping程序实例,Ping程序也可以识别出返回的信息。

序列号0开始,每发送一次新的回显请求就加1Ping程序打印出返回的每个分组的序列号,允许我们查看是否有分组丢失、失序或重复。

LAN 输出

在局域网上Ping程序输出结果如下:

$ ping test
PING test (192.168.2.80): 56 data bytes
64 bytes from 192.168.2.80: icmp_seq=0 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=1 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=2 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=3 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=4 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=5 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=6 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=7 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=8 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=9 ttl=54 time=0 ms
64 bytes from 192.168.2.80: icmp_seq=10 ttl=54 time=0 ms
...
--- www.a.shifen.com ping statistics ---
10 packets transmitted, 10 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 5.709/12.672/25.952/8.467 ms

ICMP回显应答时,打印结果:

  • 目的主机IP 域名被解析器转换成了IP地址。

  • icmp_seq(序列号)每次都从0开始逐条加1

  • ttlIP首部中生存时间)

  • time(往返时间)往返时间是当应答返回时,用当前时间减去在ICMP存放的请求时间计算得出。

  • packets transmitted 发包数量

  • packets received 接包数量

  • packet loss 丢包率

  • round-trip time(RTT) 往返时间的min/avg/max计算结果。

上面结果中time均为0ms,这是因为程序使用的计时器分辨率低的原因。

BSD/386版本0.9.4系统只能提供10ms级的计时器。

通常,第1个往返时间值要比其他的大。这是由于目的端的硬件地址不在ARP高速缓存中的缘故。

WAN 输出

广域网上Ping程序输出结果会有一些不同,如下:

$ ping www.baidu.com
PING www.wshifen.com (103.235.46.39): 56 data bytes
64 bytes from 103.235.46.39: icmp_seq=0 ttl=48 time=467.455 ms
64 bytes from 103.235.46.39: icmp_seq=1 ttl=48 time=473.325 ms
64 bytes from 103.235.46.39: icmp_seq=2 ttl=48 time=494.168 ms
Request timeout for icmp_seq 3
64 bytes from 103.235.46.39: icmp_seq=4 ttl=48 time=473.140 ms
64 bytes from 103.235.46.39: icmp_seq=5 ttl=48 time=469.418 ms
64 bytes from 103.235.46.39: icmp_seq=6 ttl=48 time=481.582 ms
64 bytes from 103.235.46.39: icmp_seq=7 ttl=48 time=486.009 ms
64 bytes from 103.235.46.39: icmp_seq=8 ttl=48 time=478.788 ms
64 bytes from 103.235.46.39: icmp_seq=9 ttl=48 time=484.603 ms
64 bytes from 103.235.46.39: icmp_seq=10 ttl=48 time=470.790 ms
...
--- www.wshifen.com ping statistics ---
15 packets transmitted, 13 packets received, 13.3% packet loss
round-trip min/avg/max/stddev = 467.455/481.129/494.168/9.280 ms

如上,序号3回显请求或应答丢失。广域网中还可能出现,重复的分组(相同序号的分组被打印多次)、失序的分组(序号N+1在序号N前面打印)

IP 记录路由选项

学习IP首部的时候,提到过可变部分有32bit的选项,Ping程序就提供了查看IP记录路由的选项RR。大多数ping命令通过-R选项指定该功能,它使得Ping程序发出的IP数据报中设置IPRR选项。这样,每个处理该数据报的路由器都把它的IP放入选项字段中。

当数据报到达目的端时, IP地址清单应该复制到ICMP回显应答中,这样返回途中所经过的路由器地址也被加入清单中。当Ping程序收到回显应答时,它就打印出这份IP地址清单。

这个过程看似简单,但是存在一些缺陷。因为RR是选项功能,中间路由器对RR的处理未必支持。

幸运的是,现在的大多数系统都支持这些选项功能,只是有一些系统不把ICMP请求中的IP清单复制到ICMP应答中。

IP首部长度字段只有4bit,因此IP首部只能包含1532bit(即60字节)。其中固定部分长度为20字节,RR选项占3个字节(格式见下图),所以最多只剩下37个字节用来存在IP地址清单,也就是最多只能放9IP地址。

除了上面提到的两个缺点外,记录路由选项工作得很好,为详细查看如何处理IP选项提供了一个机会。

IP 首部中 RR 选项一般格式IP 首部中 RR 选项一般格式

code 字段,值为7指明IP选项类型。

len 字段,RR选项总字节长度,一般为39(尽管可以为RR选项设置比最大长度小的长度,但是Ping程序总是提供39字节的选项字段,最多可以记录9IP地址。由于IP首部中留给选项的空间有限,所以一般情况都设置成最大长度)。

ptr 字段,称作指针字段。它是一个基于1的指针,指向存放下一个IP地址的位置。它的最小值为4,指向存放第一个IP地址的位置。随着每个IP地址存入清单, ptr的值分别为81216,最大到36。当记录下9IP地址后,ptr的值为40,表示清单已满。

当路由器在清单中记录IP地址时,它应该记录入口地址还是出口地址?

RFC 791 [Postel 1981a]指定路由器记录出口IP地址。

当原始主机(运行ping程序的主机)收到带有RR选项的ICMP回显应答时,它也要把它的入口IP地址放入清单中。

RR选项示例:


在主机svr4上运行Ping程序到主机slip,其中有个中间路由bdsi将处理这个数据报。

$ ping -R slip
PING slip (140.252.13.65): 56 data bytes
64 bytes from 140.252.13.65: icmp_seq=0 ttl=254 times=280ms
RR:    bsdi (140.252.13.65)
       slip (140.252.13.65)
       bsdi (140.252.13.35)
       svr4 (140.252.13.34)
64 bytes from 140.252.13.65: icmp_seq=1 ttl=254 times=280ms 
64 bytes from 140.252.13.65: icmp_seq=2 ttl=254 times=270ms 
... 省略
--- 140.252.13.65 ping statistics ---
3 packets transmitted, 3 packets recieved, 0% packets loss
round-trip min/avg/max = 270/276/280 ms

分组经过4跳,每一跳把自己的出口ip加入RR清单,最后一跳svr4收到ICMP回显应答,所以把自己的入口IP也加入清单中。如下图:

Ping 程序记录路由选项Ping 程序记录路由选项

Traceroute 程序

Ping程序可以通过RR选项记录IP路由有三个问题:

  • 并不是所有的路由器都支持RR选项。
  • 记录路由是单项的选项。发送端设置了该选项,那么接收端不得不从收到的IP首部中提取出所有的信息,然后全部返回给发送端。
  • IP首部中留给选项的空间有限,不能存放当前大多数的路径。在IP首部选项字段中最多只能存放9IP地址。

Traceroute程序可以解决上面的问题。它不需要中间路由器具备任何特殊的或可选的功能;它只需要目的端运行一个UDP模块,其他不需要任何特殊的服务器应用程序;

Traceroute程序使用ICMP报文和IP首部中的TTL字段。TTL字段由发送端初始设置的一个8bit字段,推荐初始值为64。较老系统一经常初始化为1532。一些Ping程序发送ICMP回显应答时经常把TTL设为最大值255

每个处理数据报的路由器都需要把TTL的值减1或减去数据报在路由器中停留的秒数。

由于大多数的路由器转发数据报的时延都小于1秒钟,因此TTL最终成为一个跳站的计数器,所

经过的每个路由器都将其值减1

RFC 1009 [Braden and Postel 1987]指出,如果路由器转发数据报的时延超过1秒,那么它将把TTL值减去所消耗的时间(秒数)。但很少有路由器这么实现。新的路由器需求文档RFC [Almquist 1993]为此指定它为可选择功能,允许把TTL看成一个跳站计数器。

TTL字段的目的是防止数据报在选中时无休止的在网络中流动。当路由器收到一份IP数据报时,如果其TTL值是0,路由器会将该数据报丢弃并给源主机发送一个ICMP超时信息。Traceroute程序的关键在于包含这份 ICMP 信息的 IP 报文信源地址是该路由器的 IP 地址


综上所述,Traceroute程序的操作过程是,它发送一个TTL1IP数据报给目的主机,第一个路由器将TTL值减1后丢弃该数据报并发回一份ICMP超时报文,这样就得到了第一个路由器地址;然后,Traceroute再发送一份TTL2IP数据报,获取第二个路由器地址,依此类推,直到最终目的主机为止。


上面操作过程问题是,当目的主机接收到TTL1IP数据报时,因为已经到达目的地,所以它不会丢弃该数据报而产生一个超时ICMP报文。所以该方法无法判断是否已经到达目的地。

为了解决这个问题,Traceroute程序发送一个UDP数据报给目的主机,但使用一个不可能值作为端口(大于30 000),使目的主机任何一个程序都不可能使用该端口。所以,当数据报到达时,目的主机UDP模块将产生一个“端口不可达”错误的ICMP报文,通过判断这个状态就可以知道是否已经到达目的地。

Traceroute程序可以为发送数据报设置TTL字段,并非所有TCP/IP接口程序都支持这项功能(目前大多数系统都支持这项功能)。

LAN 输出

$ traceroute lanip
traceroute to lanip (192.168.1.59), 64 hops max, 52 byte packets
 1  lanip (192.168.1.59)  6.332 ms  5.757 ms  5.427 ms

第一行,打印出域名和IP地址、最大TTL值为6452字节数据包包括IP首部20字节、UDP首部8字节和24字节的用户数据(包含每发一个数据报就加 1的序列号、TTL和发送数据报的时间)。

从第二行起,以TTL开始,接下来是主机或路由器名及IP地址。

对于每个TTL值,发送3份数据报,每收到一份ICMP数据报就打印其往返时间。如果在5秒内仍未收到任意一个数据报的响应,则打印一个*号,并发送下一个数据报。

往返时间是由发送主机的Traceroute程序计算的,它是指从Traceroute程序到该路由器的总往返时间。如果对每段路径的时间感兴趣,可以用TTL字段为N + 1所打印出来的时间减去TTL字段为N的时间。

上面数据TTL1的前3ICMP数据报分别在6.332ms5.757ms5.427ms收到。并且由于TTL为字段为1就到达最终目的主机,因此程序就此停止。

WAN 输出

$ traceroute www.baidu.com
traceroute: Warning: www.baidu.com has multiple addresses; using 182.61.200.7
traceroute to www.a.shifen.com (182.61.200.7), 64 hops max, 52 byte packets
 1  192.168.1.1 (192.168.1.1)  19.327 ms  19.036 ms  19.118 ms
 2  43.228.38.145 (43.228.38.145)  6.653 ms  6.279 ms  6.568 ms
 3  10.1.14.33 (10.1.14.33)  4.085 ms  3.979 ms *
 4  10.1.16.165 (10.1.16.165)  25.585 ms  25.723 ms  25.560 ms
 5  103.216.40.30 (103.216.40.30)  5.586 ms  27.102 ms  25.276 ms
 6  182.61.255.32 (182.61.255.32)  24.570 ms
    182.61.255.40 (182.61.255.40)  6.256 ms
    182.61.255.34 (182.61.255.34)  24.247 ms
 7  182.61.255.47 (182.61.255.47)  6.141 ms
    182.61.254.183 (182.61.254.183)  6.415 ms
    182.61.254.171 (182.61.254.171)  5.069 ms
 8  * * *
 9  * * *
10  * * *
... 省略
64  * * *

IP 源站选路选项

通常IP路由是动态的,即每个路由器都要判断数据报下面该转发到哪个路由器。应用程序对此不进行控制,通常也不关心路由。

源站选路(source route) 的思想是由发送者指定路由,可以采用以下两种形式:

  • 严格源站选路,发送端指明IP数据报所必须采用的确切路由。如果一个路由器发现源站路由所指定的下一个路由器不在其直接连接的网络上,那么它就返回一个“源站路由失败”的ICMP差错报文(即type字段值为3code字段值为5,同时RTT后面会跟随!S符号)。
  • 宽松源站选路,发送端指明一个数据报经过的IP地址清单,但是数据报在清单上指明任意两个地址之间可以通过其他路由器。

Traceroute程序提供了一个查看源站选路的方法,可以在选项中指明源站路由,然后检查其运行情况。

一些公开的Traceroute程序源代码包中包含指明宽松的源站选路的补丁。但是在标准版中通常并不包含此项。这些补丁的解释是 “Van Jacobson的原始Traceroute程序(1 9 8 8年春)支持该特性,但后来因为有人提出会使网关崩溃而将此功能去除。”

源站路由选项的格式与记录路由选项格式基本一致。不同之处是,对于源站选路,我们必须在发送IP数据报前填充IP地址清单,即对于源站选路,要为所需要的IP地址数分配空间并进行初始化,通常其数量小于9

code 字段,值分别为0x83(表示宽松源站选路)和0x89(表示严格的源站选路)。

lenptr 字段与记录路由选项一样。

源站路由选项的实际称呼为“源站及记录路由”(对于宽松的源站选路和严格的源站选路,分别用LSRRSSRR表示),这是因为在数据报沿路由发送过程中,对IP地址清单进行了更新。其运行过程如下:

  • 发送主机从应用程序接收源站路由清单,将第1个表项去掉(它是数据报的最终目的地址),将剩余的项移到1个项中,并将原来的目的地址作为清单的最后一项。指针仍然指向清单的第1项(即,指针的值为4)。

  • 每个处理数据报的路由器检查其是否为数据报的最终地址。如果不是,则正常转发数据报(在这种情况下,必须指明宽松源站选路,否则就不能接收到该数据报)。

  • 如果该路由器是最终目的,且指针不大于路径的长度:

    • ptr所指定的清单中的下一个地址就是数据报的最终目的地址;
    • 由外出接口(outgoing interface)相对应的IP地址取代刚才使用的源地址;
    • 指针加4。

    如下图示例,主机S发送数据报到D,指定源路由为R1R2R3#表示指针,其值分别为481216。长度字段为15(三个IP地址12字节加上首部3字节)。

IP 源站路由选项示例IP 源站路由选项示例

traceroute 命令示例

使用traceroute命令-g选项,可以为宽松的源站选路指明一些中间路由器。最多可指定8个中间路由器(不是9个的原因是所有编程接口要求最后的表目是目的主机)。

在命令行指定的路由器必须是十进制IP地址而不是域名,因为反向域名解析(通过IP地址返回域名)将域名与IP地址相关联,但是前向解析(即给出域名返回IP地址)则无法做到。在DNS中,前向映射和反向映射是两个独立的文件,而并非所有的管理者都同时拥有这两个文件。因此,在一个方向是工作正常而另一个方向却失败的情况并不少见。

使用traceroute命令-G选项,可以执行严格源站选路。

宽松选路的往返路由可能不完全相同,即从AB的路径并不一定与从BA的路径完全一样。

指定一个宽松的源站路由,该路由的目的端和宽松路径一样,但发送端为目的主机。如果发出路径的结果与返回路径不同,这很好地说明了在Internet上,选路可能是不对称的。