该系列相关文章:
                               TCP/IP网络故障诊断的结构化方法(一)
                               TCP/IP网络故障诊断的结构化方法(三)
  本文解释路由表如何工作,并阐述如何在Windows网络中诊断路由故障。在上篇文章中,笔者概括性地指出了TCP/IP网络故障诊断的结构化方法。这种方法有三个关键方面:
  •   理解作为基础的网络技术和协议
  •   决定问题的不同元素及其属性
  •   决定应该采取哪些故障诊断措施和工具来解决问题
  笔者以为故障诊断问题不是简单的一、两步措施就能够解决的,换句话说,故障的解决更确切地讲是一种艺术(基于直觉)而非科学(基于某种方法)。
  TCP/IP网络的基础是路由表,这是一种TCP/IP网络上每台主机的数据结构。路由表有以下三个作用:
  •   用于存储网络上其它子网的信息,以及如何到达这些网络上的主机。
  •   为了达到此数据包的最终目的地,路由表可以决定每个数据包如何被转发到某台主机。
  •   用于决定哪个网络接口(称为下一跳接口)应该用于转发这个数据包,从而使其到达目的地。
  可以说,如果你想高效地诊断TCP/IP网络上的路由问题,理解路由表是很关键的。现在让我们看看路由表是如何工作的,在不同的情况下路由表的表现是怎样的,并且看看在不同的情况下需要使用哪些故障诊断的措施和工具。我们将从检查一个简单的服务器(只有一个网络接口的服务器)的路由表开始,此服务器只分配了一个IP地址。笔者选择这个例子是因为它最易理解,在笔者的下一篇文章中,我们将看一些更为复杂的例子,包括拥有多个IP地址的服务器(如web 服务器)和拥有多个网络接口的服务器(如既能连接到LAN又能连接到一个用于备份的单独的网络)。
  只拥有一个IP地址的简单服务器的路由表
  下面的路由表是在172.16.11.0/24网络上IP地址为172.16.11.30的服务器的路由表:
以下是引用片段:
  C:\>route print
  IPv4 Route Table
  ===========================================================================
  Interface List
  0x1 ........................... MS TCP Loopback interface
  0x10003 ...00 03 ff 25 88 8c ...... Intel 21140-Based PCI Fast Ethernet Adapter
  (Generic)
  ===========================================================================
  ===========================================================================
  Active Routes:
  Network Destination Netmask Gateway Interface Metric
  0.0.0.0 0.0.0.0 172.16.11.1 172.16.11.30 20
  127.0.0.0 255.0.0.0 127.0.0.1 127.0.0.1 1
  172.16.11.0 255.255.255.0 172.16.11.30 172.16.11.30 20
  172.16.11.30 255.255.255.255 127.0.0.1 127.0.0.1 20
  172.16.255.255 255.255.255.255 172.16.11.30 172.16.11.30 20
  224.0.0.0 240.0.0.0 172.16.11.30 172.16.11.30 20
  255.255.255.255 255.255.255.255 172.16.11.30 172.16.11.30 1
  Default Gateway: 172.16.11.1
  ===========================================================================
  Persistent Routes:
  None
  为了显示这个路由表,你需要打开一个命令提示窗口,在其中输入route print。下面我们对其各个部分逐个分析便于我们理解它是如何工作的:
  路由表中每一个路由表项(或路由)都由五个字段组成:
  •   网络目标地址(Network Destination):代表某个可能的目的地址,它是一个IP地址或子网,即表示IP数据包被转发到何处的地址。
  •   掩码(Netmask):一个用于将某数据包中的IP地址中的目标地址字段与上面可能的网络地址匹配起来的位模式。
  •   网关(Gateway):下一跳的IP地址,数据包必须被转发到此,才能到达特定的目的网络。
  •   接口(Interface):下一跳的接口,这个接口必须用于将数据包进行转发,以达到特定的目的网络。
  •   跳数(metric):表示到达目的的过程中经过了多少跳数(路由器数),即路由的成本。
示例一:目标主机在本地子网上
  对于我们例子而言,假设这个特定的服务器(172.16.11.30)要将数据包发往同一子网内的另一台主机(IP地址为172.16.11.80)。那么这个数据包的源地址为172.16.11.30,目标地址为172.16.11.80。下面我们将展示Windows是如何用其路由表来决定选择使用哪条路由的:
  1. Windows首先依次从路由表中取出每一个路由,并将数据包的目标地址(172.16.11.80)与选中路由的掩码执行逻辑“与”运算。下面展示结果,这里,路由表中的每一个路由是通过其网络目的地址确定的:
 
Route <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Netmask

172.16.11.80 AND Netmask

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /> 0.0.0 .0

0.0.0 .0

0.0.0 .0

127.0.0.0

255.0.0.0

172.0.0.0

172.16.11.0

255.255.255.0

172.16.11.0

172.16.11.30

255.255.255.255

172.16.11.80

172.16.255.255

255.255.255.255

172.16.11.80

224.0.0.0

224.0.0.0

160.0.0.0

255.255.255.255

255.255.255.255

172.16.11.80

  2. 对每一个路由来说,这个“与”运算的结果要与路由的网络目标地址比比较,而二者的一次匹配意思着这条路由可被用于将数据包转发到其目标地址。如果发现不只有一个匹配,Windows就会选用拥有最长匹配的路由(即1的位数最高的路由)。如果这并不有产生唯一的路由,Windows就任意地选用一个作为路由。从上面的列表中,这个“与”运算的结果导致了两个匹配(路由1和3),因此Windows选择了拥有最长匹配的路由,即第三行的那个。其结果是Windows知道了使用哪个路由将数据包传送到目的地。下面是这条路由在服务器的路由表中看起来的样子:
  Network Destination     Netmask         Gateway           Interface Metric
  172.16.11.0                 255.255.255.0   172.16.11.30    172.16.11.30 20
  3. Windows现在要使用下面的算法来决定下一步做什么:
  a) 如果路由的网关字段与服务器上的一个网络接口的地址相匹配(或者如果网关是空的话),那么Windows就会用在路由中指定的接口将数据包直接发送到目标地址。
  b) 如果路由的网关字段并不与服务器上网络接口的任意地址相匹配,Windows将会把数据包转发给路由中的网关字段的地址。
  很明显,这里符合条件a,路由的网关字段(172.16.11.30)即为分配给服务器单个网卡的地址。Windows因此会作出决定认为目标地址位于本地子网上,这也就是说Windows不需要将数据包发送到任何路由器,而是直接发送给其目的地址。在此例中,Windows使用服务器的172.16.11.30的网络接口,简单地将数据包发送给172.16.11.80,接收主机得到了数据包。
示例二:目标主机在远程子网上
  现在,让我们继续同样的过程,不过这次我们假定服务器想把数据包发往一个不同子网上的一台主机(IP地址为172.16.10.200)。换句话说,数据包的源地址为172.16.11.30,目标地址为172.16.10.200。下面我们看一下Windows是如何利用路由表决定选择哪条路由的:
  1. Windows从路由表中取出每一条路由,将数据包的目标地址(172.16.10.200)与路由中的掩码进行“与” 运算。运算结果如下:
 
Route

Netmask

172.16.10.200 AND Netmask

0.0.0 .0

0.0.0 .0

0.0.0 .0

127.0.0.0

255.0.0.0

172.0.0.0

172.16.11.0

255.255.255.0

172.16.10.0

172.16.11.30

255.255.255.255

172.16.10.200

172.16.255.255

255.255.255.255

172.16.10.200

224.0.0.0

224.0.0.0

160.0.0.0

255.255.255.255

255.255.255.255

172.16.10.200

  2. 对于每一条路由来说,“与”运算的结果要与路由中网络目标地址相比较,二者匹配意味着这条路由可被用于将数据包转发到其目标地址。从我们上面的第二张路由表,你可以看出这次只有一个匹配,也就是说是第一行,这个路由的网络目地字段(0.0.0.0)与“与”运算的结果匹配。因此Windows用来将数据包转发到其目标地址的路由即为下面的路由:
  Network Destination    Netmask     Gateway     Interface Metric
  0.0.0.0           0.0.0.0      172.16.11.1   172.16.11.30 20
  3. 然后Windows就会使用前述的算法来决定下一步做什么,这次符合条件b,因为路由的网关字段(172.16.11.1)与分配给服务器的单独网卡的地址(172.16.11.30)并不匹配。Windows因此会决定目标地址位于一个远程子网上,将数据包转发给路由器,路由器通过继续转发数据包将其传送到目的地。在此例中,Windows使用服务器的172.16.11.30网络接口,将数据包发送到在网关字段中所显示的地址。一旦位于172.16.11.1的路由器收到了数据包,它会决定下一步需要采取什么步骤,才能将数据包转发到其最后的目标地址172.16.10.200,而这又依赖于172.16.11.10/24网络是172.16.11.11/24(由单个路由器连接)或一个远程网络的邻近子网(由几个中间网络之间的路由器连接)。
 
故障诊断小技巧
  在上述的过程中哪里会出问题呢?首先,Windows有可能无法选择一条网络目的地址字段与“与”运算的结果(即路由的掩码字段与数据包的目标字段“与”运算的结果)相匹配的路由。如果发生这种情况,你就会收到一个路由选择错误,这一般会通过一些运行在服务器上的网络应用程序指示给你。通常情况下,Windows会使用TCP来通知网络堆栈的上层,说明数据包不能送达,就会导致某种错误消息。
  在这种情况下,你的路由表可能已经损坏,或者说,你的路由表中有一个非法的持久性路由。持久性路由指的是你通过使用route -p add手动命令添加到路由表中的路由,这种路由需要重启才可以使用,因为其值是存储在注册表中的。如果你添加了非法的路由,就会产生奇怪的结果。(虽然这种非法路由多数情况下会导致数据通信被莫名其妙地丢弃。)
  另外一方面,如果目标主机位于一个远程子网上,Windows会将数据包转发给一个路由器(默认的网关地址),而这个路由器又不能选择一个路由,那么这种情况就会发生:路由会将把一个ICMP(网际控制报文协议)消息:“目标不可达到(Destination Unreachable)-主机不可到达(Host Unreachable)”返回给发送此数据包的主机。此例中,TCP会通知上层协议,然后就会显示某种错误消息。
  无论何种情况,一个处理问题的实用方法是在发送方主机上检查路由表,还要检查数据包在到达目的地的过程中沿途经过的路径所连接的路由器,查看这些路由表是否一致或已经损坏。一个损坏的路由表可以通过重置TCP/IP堆栈进行恢复(至少在Windows计算机上是这样),具体方法是使用netsh int ip reset命令,大家可以参考微软的KB299357查找祥细资料。不过,需要注意,这种重置操作并不会清除你手动添加到路由表中的路由。
   结论
  我们讨论了路由表是如何工作的,并且阐述了如何诊断路由表的故障,下一篇文章我们将讨论几个更为复杂的例子,例如看看拥有多个地址和多个网卡的服务器的情况。