路由与路由表
路由(route)就是分组在因特网上从一台计算机传输到另一台计算机的实际路径。
因特网上的每个路由器都存储有一张表,称为路由表(routing table),路由器正是依据路由表的内容将各个 IP 分组转发到正确的去处。
注意:
- 路由器上的路由表反映的是该路由器与相邻路由器之间的连接关系,以及任何一个可达网络与某个邻接路由器之间的“目标-经过”关系
- 一个路由器上的路由表从来不会反映该路由器与任何非相邻路由器之间的连接关系
- 路由表每个表项中的IP默认为目标网段的IP地址,而不是目标计算机的IP地址,这样能够最大限度地提高路由的效率
这里有三个概念:路由,路由器,路由表。对于小白可能容易混淆,注意路由既可以指计算机之间的传输路径,又可以指传输这一动态过程,而路由器是设备,即完成路由这一动态过程的设备,路由表是信息。是储存在路由器中的用来路由的信息
实际中由于路由器开发厂商的不同,路由表中的信息也不尽相同,但是几乎都包含五项基本信息:
- 目标网络的IP地址:32位,这里在上文提到,是目标网络的IP地址而非目标计算机的IP地址
- 目标网络的子网掩码:32位,即子网掩码,没什么好解释
- 下一跳IP地址:32位,如果目标网络需经过多个路由器,下一跳即使下一个路由器的IP地址
- 离出接口名字:路由器会提供多个接口,每个接口通向不同的网段,所以表项中需要提供该项,即使确定IP分组从哪一个接口发出去,离出接口只是标识本路由器的信息,没有过多的全局含义
- 度量:从该路由器到达目标网络的代价,这个属性反映这一路径的优劣,由于路由协议的不同,该项具体数据形式也不同,常见的有跳数(途径路由器的数量),当前往返时间,最窄链路带宽等等
下面举一个例子
上图中白框即代表路由器,电脑标识即是主机,下面以路由器R2为例,列举出其路由表
首先对于最上方的主机或者网段而言,主机地址是202.39.2.65,根据IP首八位可以判断出这是C类IP地址,即网络号有三个八位,所以该网段为202.39.2.0,子网掩码为255.255.255.0,因为R2首先要经过R3才能到达该网段,下一站IP地址,即是所以R3近端的IP地址为172.200.1.1(此处既然为下一“站”,不难理解是一个具体的IP地址,而非一个网段,所以直接用给定的IP即可,不要化成172.200.0.0),离出接口,可以看出R2经上方I21口发出,离出接口可以填接口名,也可以填接口的IP地址,比如此处可以填I21,也可以填172.200.0.1,但是为了简洁通常填名称即可,没有给出名称才考虑填写出口的IP地址。因为到达最上方网段需要经过一个路由器,这里度量就认定为1。而对于主机B或主机C所在的网段,其间不需经过其他的路由器,像这种直连的网段,下一站IP地址项默认填C表示直连,度量默认填0(上文也提到过实际中度量的标准会有不同,就算都用跳数这一标准,有一些将直连的度量认为是1,而有些认为是0,所以在具体环境中具体区分即可,对于直连跳数认为是1的,那么其他的跳数也相应都+1)
以此类推,可求出R2的所有表项
表中的最后一项目标地址设为0.0.0.0,称为默认路由项,也叫做缺省路由项,即是路由器一旦不知道应该向哪里转发IP分组(比如上面四项的目标地址都不匹配),就按照这一项发出,这一项的参数也是根据实际灵活改变
路由器与IP分组转发算法
上文中提到了路由器就是完成路由过程的设备,从构成上看,它是一个完整的计算机系统,包括硬件,操作系统和应用软件算法,与通用计算机系统的不同之处就在于,路由器硬件以通讯处理为主要设计目标,特别是 I/O部分;路由器操作系统也主要针对协议处理及通讯功能进行了优化,这一点与支持通用计算的分时系统如 Windows NT、UNIX 不同,而是更偏向于实时处理能力。
IP分组即是IP包,或者说IP报文,因为引入的名字叫做IP Packet,有些翻译为分组,其实是IP信息的涵义,下面给出IP分组转发算法的逻辑结构:
IP_Packet_Routing(IP 分组 P) { int found = FALSE; A=P 的目标IP 地址; for( 每个非默认路由项(D, M, N, I, d) ) { /*D 是目标网络的IP 地址, M 是子网掩码, N 是下一站路由器的IP 地址, I 是离出接口, d 是路由的性能度量 */ if(A&M==D 2 ) { /* & 是逐位逻辑与 */ if( d 表示P 的目标网络并非邻接) { /* 例如, d 表示网络距离且d>0. */ 将队列项[N, P]放入接口I 的离出队列; /*[N, P]的涵义是: 将分组P 载入数据链路帧, 帧的目标MAC 地址 与IP 地址 N 对应. */ } else { /* d 表示目标网络就是接口I 连接的邻接网段, 例如, d 表示网络距离且d=0.*/ 将队列项[A, P]放入接口I 的离出队列; /* 涵义同上 */ } found = TRUE; break; } /* if…*/ } /* for…*/ if( ! found ) { /* 假设默认路由项是(0.0.0.0, 0.0.0.0, N*, I*, -) */ 将队列项[N*, P]放入接口I*的离出队列; /*涵义同上*/ } } IP_Packet_Routing 算法被分组转发进程调用: while(1) { /*无限循环*/ P=get_IP_Packet(); /*取一个到达的IP 分组*/ IP_Packet_Routing(P); /*路由检索*/ output_IP_Packet(P); /*发送分组*/ }
注意: IP 分组在接受路由器处理、经过一个一个路由器传输的过程中,其源IP 地址和目标 IP 地址始终不变,发生变化的是其承载帧的源 MAC 地址等中间信息