0%

学习TCP/IP(4):网际协议 IPv4-转发IP数据报

学习TCP/IP(4):网际协议 IPv4-转发IP数据报

引言

在网络的世界里,数据报转发可以分为两种类型:直接交付间接交付

直接交付

直接交付是指把数据报从一台机器通过物理网络直接传输到另外一台机器,这是所有互联网通信的基础。 只有当两台主机位于同一个物理网络时,才会发生直接交付。

当然,还有几个小问题没有解决。

Q1: 直接交付具体怎么交付? A1:先用ARP协议解析得到目标站点的MAC地址,然后,知道了MAC地址就直接将数据报封装成帧发送过去。

Q2:如果每次都用ARP协议解析得到对方MAC地址,会不会效率太低了? A2:当然,不一定要解析,每一次进行ARP解析之前,都会去检查ARP缓存有没有以往解析的记录。若有,直接取出记录即可发送。

Q3:如何判断对方网络是不是跟我处于在一个网段? A3:直接取出对方IP地址的网络号部分和我方IP地址的网络号进行比对。若网络号相同,则说明处在同一物理网络。

间接交付

简介交付是指,当两个主机不处于同一个物理网络,也即两个主机之间间隔了至少一个路由器时,一台主机要给另外一个主机发送数据报,则这台主机会将这个数据报发送给最近的路由器,通过路由器之间的互相传递,最终将数据报交给目标主机。

这个概念在《用TCP/IP进行网际互连》有一段精辟的总结:

TCP/IP互联网中的路由器形成一个互相协作的互联结构。数据报从一个路由器传递到下一个路由器,直到抵达一个可直接交付的路由器。

表驱动的IP转发

虽然已经知道了数据报会经过路由器序列一级一级转发从而到达路由器,但是,还有一个关键问题没有解决:当一个数据报抵达一个路由器时,它是怎么知道应该转发到哪一个路由器上的?

为了解决这个问题,需要引入一个数据结构---路由表。路由表又称网际协议路由表(Internet Protocol Routing table)IP路由表(IP Routing Table)。这个表看成是一个Key-Value的数组,数组的每一个元素都是一个键值对(Key-Value),其中存储着可能的IP到路由器出口(路由器至少有两个IP地址,一个IP地址视为一个出口)的配对信息。

也许你会想,路由器如果需要存储所有可能的IP到路由器出口配对信息,那路由器内存岂不是会爆炸(笑)!

这时候IP协议的优越性就体现出来了:路由器连接了多个物理网络,它需要将某一个目的地IP是a.b.c.d(这里假设a.b.c是网络号部分,d是主机号部分)的数据报转发出去,那既然每个物理网络的网络号都不同,那么可以将目的IP地址中的网络号提取出来,与对应的出口配对(a.b.c,出口1)存入路由表就行了!

下次我需要转发目的地址是a.b.c.e的数据报,那么我提取网络号出来(a.b.c),在路由表里查询到出口是出口1,那么我就可以直接将这个数据报从出口1转发出去!

上述转发过程同样在《用TCP/IP进行网际互连》也有一段精辟的总结:

为了隐藏信息,应该保持路由表较小并使转发决策效率更高,IP转发软件保存的只是有关目的网络地址的信息,而不是有关个体主机地址的信息

上述Key-value 的专业术语应该为(N,R),N代表目的网络,R是通往网络N的路径的“下一个”路由器地址以及对应的网络接口!

通常,可直接交付的路由器之间两两相连,若A路由器需要发送数据报给路由器B,那么路由器A不仅需要知道路由器B的的IP地址(直接交付的两个路由器处于同一个物理网络,其IP地址(专指用于路由器之间互相通信的网络的IP地址)的网络号相同)),还要知道对应的网络接口(路由器可能不止安装了一个物理接口)。

路由器R称为下一跳(Next Hop),这种转发方法称之为下一跳路由选择(Next-Hop Routing)下一跳转发(Next-Hop Forwarding)

此外,尽管我们知道所有的转发都是基于网络而不是基于特定主机的,但是大多数IP转发软件都允许指明某个特定的主机的路由作为特例,这么做的理由可能有为了安全、为了更好的通信质量、为了调试通信,等等等。

默认路由

如果有一个数据报到来但是上述的转发表里面没有包含这个数据报的IP地址的转发信息,且存在一个默认路由,那么主机就会将这个数据报转发到默认路由去。默认路由在转发表里的目的网络N(网络部分)一般是0.0.0.0/0(假定是Ipv4转发表),前面的0.0.0.0代表目的网络IP地址,后面的0代表网络号部分长度为0,说明当若前面记录没有满足的跳转条件而导致扫描到这条记录时,无论什么目的IP地址的网络号时什么都会通过这条记录转发出去。

IP转发算法

基于上面的讨论,我们可以得出IP软件的转发算法的原型算法的伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
从数据报中抽取目的IP地址D;
IF 表中含有D的特定主机路由:
把数据报发送到表中指明的下一跳,然后退出;
计算地址D的网络前缀N;
IF N与任何一个直接相连的网络地址匹配:
通过该网络把数据报直接交付给目的站D;
ELSE IF 表中包含一个针对网络N的路由:
把数据报发送到表中指明的下一跳;
ELSE IF 表中包含一个默认路由:
把数据报发送到表中指明的默认路由器;
ELSE 声明一个转发出错;(见ICMP相关内容)

(摘自《用TCP/IP进行网际互连》)

还有说明没提到?

上述虽然讨论了怎么使用路由表,但是没有说明系统如何初始化路由表,以及如何根据网络的更新动态更新路由表。这些主题更为复杂,将在之后的文章里讨论。