路由(route)就是分组在因特网上从一台计算机传输到另一台计算机的实际路径。
因特网上的每个路由器都存储有一张表,称为路由表(routing table),路由器正是依据路由表的内容将各个 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分组(比如上面四项的目标地址都不匹配),就按照这一项发出,这一项的参数也是根据实际灵活改变
上文中提到了路由器就是完成路由过程的设备,从构成上看,它是一个完整的计算机系统,包括硬件,操作系统和应用软件算法,与通用计算机系统的不同之处就在于,路由器硬件以通讯处理为主要设计目标,特别是 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 地址等中间信息
有关动态路由以及动态路由协议+算法的内容,感兴趣的请移步我的另一篇笔记