Skip to content

网络层

网络层提供的两种服务

在计算机网络领域,网络层应该向运输层提供怎样的服务(“面向连接”还是“无连接”)曾引起了长期的争论。
争论的焦点的实质就是:在计算机通信中,可靠交付应当由谁来负责?是网络还是端系统?

有些人认为应当借助于电信网的成功经验,让网络负责可靠交付。大家知道,传统电信网的主要业务是提供电话服务。
电信网使用昂贵的程控交换机(其软件也非常复杂),用面向连接的通信方式,使电信网络能够向用户(实际上就是电话机)提供可靠传输的服务。
因此他们认为,计算机网络也应模仿打电话所使用的面向连接的通信方式。
当两台计算机进行通信时,也应当先建立连接(但在分组交换中是建立一条虚电路 VC(Virtual Circuit)),以预留双方通信所需的一切网络资源。然后双方就沿着已建立的虚电路发送分组。
这样的分组的首部不需要填写完整的目的主机地址,而只需要填写这条虚电路的编号(一个不大的整数),因而减少了分组的开销。
这种通信方式如果再使用可靠传输的网络协议,就可使所发送的分组无差错按序到达终点,当然也不丢失、不重复。在通信结束后要释放建立的虚电路。

图(a) 是网络提供虚电路服务的示意图。主机 H1 和 H2 之间交换的分组都必须在事先建立的虚电路上传送

但互联网的先驱者却提出一种崭新的网络设计思路。
他们认为,电信网提供的端到端可靠传输的服务对电话业务无疑是很合适的,因为电信网的终端(电话机)非常简单,没有智能,也没有差错处理能力。
因此电信网必须负责把用户电话机产生的话音信号可靠地传送到对方的电话机,使还原后的话音质量符合技术规范的要求。
但计算机网络的端系统是有智能的计算机。
计算机有很强的差错处理能力(这点和传统的电话机有本质上的差别)。因此,互联网在设计上就采用了和电信网完全不同的思路。

互联网采用的设计思路是这样的:网络层向上只提供简单灵活的、无连接的、尽最大努力交付的数据报服务。
这里的“数据报”是互联网的设计者最初使用的名词,其实数据报(或 IP 数据报)就是我们经常使用的“分组”

网络在发送分组时不需要先建立连接。
每一个分组(也就是 IP 数据报)独立发送,与其前后的分组无关(不进行编号)。网络层不提供服务质量的承诺。
也就是说,所传送的分组可能出错、丢失、重复和失序(即不按序到达终点),当然也不保证分组交付的时限。
由于传输网络不提供端到端的可靠传输服务,这就使网络中的路由器比较简单,且价格低廉(与电信网的交换机相比较)。
如果主机(即端系统)中的进程之间的通信需要是可靠的,那么就由网络的主机中的运输层负责(包括差错处理、流量控制等)。
采用这种设计思路的好处是:网络造价大大降低,运行方式灵活,能够适应多种应用。
互联网能够发展到今日的规模,充分证明了当初采用这种设计思路的正确性。

图(b)给出了网络提供数据报服务的示意图。
主机 H1 向 H2 发送的分组各自独立地选择路由,并且在传送的过程中还可能丢失

下表归纳了虚电路服务与数据报服务的主要区别

对比的方面 虚电路服务 数据报服务
思路 可靠通信应当由网络来保证 可靠通信应当由用户来保证
连接的建立 必须有 不需要
终点地址 仅在连接建立阶段使用,每个分组使用短的虚电路号 每个分组都有终点的完整地址
分组的转发 属于同一条虚电路的分组均按照同一路由器进行转发 每个分组独立选择路由进行转发
当结点出故障时 所有通过出故障的结点的虚电路均不能工作 出故障的结点可能会丢失分组,一些路由可能会发生变化
分组的顺序 总是按发送顺序到达终点 到达终点的时间不一定按发送顺序
端到端的差错处理和流量控制 可以由网络负责,也可以由用户主机负责 由用户主机负责

鉴于 TCP/IP 体系的网络层提供的是数据报服务,因此下面我们的讨论都是围绕网络层如何传送 IP 数据报这个主题。

网络协议 IP

网络协议 IP 是 TCP/IP 体系中两个最主要的协议之一,也是最重要的互联网标准协议之一。
网络协议 IP 又称为 Kahn-Cerf 协议,因为这个重要协议正是 Robert Kahn 和 Vint Cerf 二人共同研发的。
这两位学者在 2005 年获得图灵奖(其地位相当于计算机科学领域的诺贝尔奖)。
严格来说,这里所讲的 IP 其实是 IP 的第 4 个版本,应记为 IPv4。但在讲述 IP 协议的各种原理时,往往不在 IP 后面加上版本号。

与 IP 协议配套使用的还有三个协议:

  • 地址解析协议 ARP(Address Resolution Protocol)
  • 网际控制报文协议 ICMP(Internet Control Message Protocol)
  • 网际组管理协议 IGMP(Internet Group Management Protocol)

如图画出了这三个协议和网络协议 IP 的关系。
在这一层中,ARP 画在最下面,因为 IP 经常要使用这个协议。
ICMP 和 IGMP 画在这一层的上部,因为它们要使用 IP 协议。
由于网络协议 IP 是用来使互连起来的许多计算机网络能够进行通信的,因此 TCP/IP 体系中的网络层常常被称为网际层,或 IP 层。
使用“网际层”这个名词的好处是强调这是由很多网络构成的互连网络

在讨论网络协议 IP 之前,必须了解什么是互连网络

虚拟互连网络

我们知道,如果要在全世界范围内把数以百万计的网络都互连起来,并且能够互相通信,那么这样的任务一定非常复杂。
其中会遇到许多需要解决的问题,如:

  • 不同的寻址方案
  • 不同的最大分组长度
  • 不同的网络接入机制
  • 不同的超时控制
  • 不同的差错恢复方法
  • 不同的状态报告方法
  • 不同的路由选择技术
  • 不同的用户接入控制
  • 不同的服务(面向连接服务和无连接服务)
  • 不同的管理与控制方式;等等

能不能让大家都使用相同的网络,这样可使网络互连变得比较简单。答案是不行的。
因为用户的需求是多种多样的,没有一种单一的网络能够适应所有用户的需求。
另外,网络技术是不断发展的,网络的制造厂家也要经常推出新的网络,在竞争中求生存。
因此在市场上总是有很多种不同性能、不同网络协议的网络,供不同的用户选用

从一般的概念来讲,将网络互相连接起来要使用一些中间设备。
根据中间设备所在的层次,可以有以下四种不同的中间设备

(1) 物理层使用的中间设备叫做转发器
(2) 数据链路层使用的中间设备叫做网桥或桥接器
(3) 网络层使用的中间设备叫做路由器
(4) 在网络层以上使用的中间设备叫做网关。用网关连接两个不兼容的系统需要在高层进行协议的转换

当中间设备是转发器或网桥时,这仅仅是把一个网络扩大了,而从网络层的角度看,这仍然是一个网络,一般并不称之为网络互连。
网关由于比较复杂,目前使用得较少。因此现在我们讨论网络互连时,都是指用路由器进行网络互连和路由选择。
路由器其实就是一台专用计算机,用来在互联网中进行路由选择
由于历史的原因,许多有关 TCP/IP 的文献曾经把网络层使用的路由器称为网关。

下图(a)表示有许多计算机网络通过一些路由器互连。
由于参加互连的计算机网络都使用相同的网际协议 IP(Internet Protocol),因此可以把互连以后的计算机网络看成如图(b)所示的一个虚拟互连网络。
它的意思就是互连起来的各种物理网络的异构性本来是客观存在的,但是我们利用 IP 协议就可以使这些性能各异的网络在网络层上看起来好像是一个统一的网络。
这种使用 IP 协议的虚拟互连网可简称为 IP 网(IP 网是虚拟的,但平常不必每次都强调“虚拟”二字)。
使用 IP 网的好处是:当 IP 网上的主机进行通信时,就好像在一个单个网络上通信一样,它们看不见互连的各网络的具体异构细节(如具体的编址方案、路由选择协议,等等)。
如果在这种覆盖全球的 IP 网的上层使用 TCP 协议,那么就是现在互联网

IP网的概念

当很多异构网络通过路由器互连起来时,如果所有的网络都使用相同的 IP 协议,那么在网络层讨论问题就显得很方便。
现在用一个例子来说明

下图所示的互联网中的源主机 H1 要把一个 IP 数据报发送给目的主机 H2。
根据分组交换的存储转发概念,主机 H1 先要查找自己的路由表,看目的主机是否就在本网络上。
如是,则不需要经过任何路由器而是直接交付,任务就完成了。
如不是,则必须把 IP 数据报发送给某个路由器(图中的 R1)。
R1 在查找了自己的路由表(更准确些说应是转发表)后,知道应当把数据报转发给 R2 进行间接交付。
这样一直转发下去,最后由路由器 R5 知道自己是和 H2 连接在同一网络上,不需要再使用别的路由器转发了,于是就把数据报直接交付目的主机 H2。
图中画出了源主机、目的主机以及各路由器的协议栈。
我们注意到,主机的协议栈共有五层,但路由器的协议栈只有下三层。
图中还画出了数据在各协议栈中流动的方向(用黑色粗线表示)。
我们还可注意到,在 R4 和 R5 之间使用了卫星链路,而 R5 所连接的是个无线局域网。
在 R1 到 R4 之间的三个网络则可以是任意类型的网络。
总之,这里强调的是:互联网可以由多种异构网络互连组成。

如果我们只从网络层考虑问题,那么 IP 数据报就可以想象是在网络层中传送,其传送路径是:

H1->R1->R2->R3->R4->R5-H2

这样就不必画出许多完整的协议栈,使问题的描述更加简单。

分组在互联网中的传送

有了虚拟互连网络的概念后,我们再讨论在这样的虚拟网络上如何寻址。

分类的 IP 地址

在 TCP/IP 体系中,IP 地址是一个最基本的概念,一定要把它弄清楚。
有关 IP 最重要的文档就是互联网的正式标准 RFC 791

IP 地址及其表示方法
整个的互联网就是一个单一的、抽象的网络。
IP 地址就是给互联网上的每一台主机(或路由器)的每一个接口分配一个在全世界范围内是唯一的 32 位的标识符。
IP 地址的结构使我们可以在互联网上很方便地进行寻址。
IP 地址现在由互联网名字和数字分配机构 ICANN(Internet Corporation for Assigned Names and Numbers)进行分配(我国用户可向亚太网络信息中心 APNIC(Asic Pacific NetWork Information Center)申请 IP 地址(要缴费))

IP 地址的编址方法共经过了三个历史阶段
(1) 分类的 IP 地址。这是最基本的编址方法,在 1981 年就通过了相应的标准协议
(2) 子网的划分。这是对最基本的编址方法的改进,其标准 RFC 950 在 1985 年通过
(3) 构成超网。这是比较新的无分类编址方法。1993 年提出后很快就得到推广应用

现在我们只讨论最基本的分类的 IP 地址。

所谓“分类的 IP 地址”就是将 IP 地址划分为若干个固定类,每一个类地址都由两个固定长度的字段组成,其中第一个字段是网络号,它标志主机(或路由器)所连接到的网络。一个网络号在整个互联网范围内必须是唯一的。
第二个字段是主机号,它标志该主机(或路由器)。
一台主机号在它面前的网络号所指明的网络范围内必须是唯一的。
由此可见,一个 IP 地址在整个互联网范围内是唯一的。

这种两级的 IP 地址可以记为:IP 地址 ::= {<网络号>,<主机号>}

式中的符号::=表示“定义为”。下图给出了各种 IP 地址的网络号字段和主机号字段,这里 A 类、B 类和 C 类地址都是单播地址(一对一通信),是最常用的

IP地址中的网络号字段和主机号字段

从上图可以看出:

  • A 类、B 类和 C 类地址的网络号字段(在图中这个字段是灰色的)分别为 1 个、2 个和 3 个字节长,而在网络号字段的最前面有 1-3 位的类别位,其数值分别规定为 0,10 和 110
  • A 类、B 类和 C 类地址的主机号字段分别位 3 个、2 个和 1 个字节长
  • D 类地址(前 4 位是 1110)用于多播(一对多通信)
  • E 类地址(前 4 位是 1111)保留位以后用

从 IP 地址的结构来看,IP 地址并不仅仅指明一台主机,而是还指明了主机所连接到的网络

把 IP 地址划分为 A 类、B 类、C 类三个类别,当初是这样考虑的。
各种网络的差异很大,有的网络拥有很多主机,而有的网络上的主机则很少。
把 IP 地址划分为 A 类、B 类和 C 类是为了更好地满足不同用户的要求。
当某个单位申请到一个 IP 地址时,实际上是获得了具有同样网络号的一块地址。
其中具体的各台主机号则由该单位自行分配,只要做到在该单位管辖的范围内无重复的主机号即可。

对主机或路由器来说,IP 地址都是 32 位的二进制代码。
为了提高可读性,我们常常把 32 位的 IP 地址中的每 8 位插入一个空格(但在机器中并没有这样的空格)。
为了便于书写,可用其等效的十进制数字表示,并且在这些数字之间加一个点。
这就叫做点分十进制记法。 下图是一个 B 类 IP 地址的表示方法。显然,128.11.3.31 书写起来要方便得多

点分十进制记法

常用的三种类别的 IP 地址
A 类地址的网络号字段占一个字节,只有 7 位可供使用(该字段的第一位已固定为 0),但可指派的网络号是 126 个(即 2^7 - 2)。
减 2 的原因是:第一,IP 地址中的全 0 表示“这个”(this)。网络号字段为全 0 的 IP 地址是保留地址,意思是“本网络”;
第二,网络号为 127(即 01111111)保留作为本地软件环回测试本主机的进程之间的通信之用。
若主机发送一个目的地址为环回地址(例如 127.0.0.1)的 IP 数据报,则本主机中的协议软件就处理数据报中的数据,而不会把数据报发送到任何网络。
目的地址为环回地址的 IP 数据报永远不会出现在任何网络上,因为网络号为 127 的地址根本不是一个网络地址。

每一个 A 类网络中的最大主机数是 2^{24} - 2,即 16777214。
这里减 2 的原因是:全 0 的主机号字段表示该 IP 地址是“本主机”所连接到的单个网络地址(例如,一主机的 IP 地址为 5.6.7.8,则该主机所在的网络地址就是 5.0.0.0),而全 1 表示“所有的”,因此全 1 的主机号字段表示该网络上的所有主机

IP 地址空间共有 2^{32}(即 4294967296)个地址。整个 A 类地址空间共有 2^{31}个地址。

B 类地址的网络号字段有 2 个字节,但前面两位(10)已经固定了,只剩下 14 为可以进行分配。
因为网络号字段后面的 14 位无论怎样取值也不可能出现使整个 2 个字节的网络号字段成为全 0 或全 1,因此这里不存在网络总数减 2 的问题。
但实际上 B 类网络地址 128.0.0.0 是不指派的,而可以指派的 B 类最小网络地址是 128.1.0.0。
因此 B 类地址可指派的网络数为 2^{14} - 1,即 16383。
B 类地址的每一个网络上的最大主机数是 2^{16} - 2,即 65534。
这里需要减 2 是因为要扣除全 0 和全 1 的主机号。整个 B 类地址空间共约有 2^{30} 个地址

C 类地址有 3 个字节的网络号字段,最前面的 3 位是(110),还有 21 位可以进行分配。
C 类网络地址 192.0.0.0 也是不指派的,可以指派的 C 类最小网络地址是 192.0.1.0,因此 C 类地址可指派的网络总数是 2^{21} - 1,即 2097151。
每一个 C 类地址的最大主机数是 2^8 - 2,即 254。整个 C 类地址空间共约有 2^29 个地址

这样,我们就可得出如下表所示的 IP 地址的指派范围。

网络类别 最大可指派的网络数 第一个可指派的网络号 最后一个可指派的网络号 每个网络中的最大主机数
A 126(2^7 - 1) 1 126 16777214
B 16383(2^{14} - 1) 128.1 191.255 65534
C 2097151(2^{21} - 1) 192.0.1 223.255.255 254

IP 地址具有以下一些重要特点
(1) 每一个 IP 地址都由网络号和主机号连部分组成。
从这个意义上说,IP 地址是一种分等级的地址结构。
分两个等级的好处是:第一,IP 地址管理机构在分配 IP 地址时只分配网络号(第一级),而剩下的主机号(第二级)则由得到该网络的单位自行分配。这样就方便了 IP 地址的管理;
第二,路由器仅根据目的主机所连接的网络号来转发分组(而不考虑目的主机号),这样就可以使路由表中的项目数大幅度减少,从而减小了路由表所占的存储空间以及查找路由表的时间

(2) 实际上 IP 地址是标志一台主机(或路由器)和一条链路的接口。
当一台主机同时连接到两个网络上时,其网络号必须是不同的。这种主机称为多归属主机。
由于一个路由器至少应当连接到两个网络,因此一个路由器至少应当有两个不同的 IP 地址。
这好比一个建筑正好处在北京路和上海路的交叉口上,那么这个建筑就可以拥有两个门牌号码。例如,北京路 4 号和上海路 37 号

(3) 按照互联网的观点,一个网络是指具有相同网络号的主机的集合,因此,用转发器或网桥连接起来的若干个局域网仍为一个网络,因为这些局域网都具有同样的网络号。具有不同网络号的局域网必须使用路由器进行互连

(4) 在 IP 地址中,所有分配到网络号的网络(不管是范围很小的局域网,还是可能覆盖很大地理范围的广域网)都是平等的。所谓平等,是指互联网同等对待每一个 IP 地址

下图画出了三个局域网(LAN1,LAN2 和 LAN3)通过三个路由器(R1,R2 和 R3)互连起来所构成的一个互联网(此互联网用虚线圆角方框表示)。
其中局域网 LAN2 是由两个网段通过网桥 B 互连的。图中的小圆圈表示需要有一个 IP 地址

互联网中的IP地址

我们应当注意到:

在同一个局域网上的主机或路由器的 IP 地址中的网络号必须是一样的。
图中所示的网络号就是 IP 地址中的网络号字段的值,这也是文献中常见的一种表示方法。另一种表示方法是用主机号全 0 的网络 IP 地址

用网桥(它只在链路层工作)互连的网段仍然是一个局域网,只能有一个网络号

路由器总是具有两个或两个以上的 IP 地址。即路由器的每一个接口都有一个不同网络号的 IP 地址

当两个路由器直接相连时(例如通过一条租用线路),子啊连线两端的接口处,可以分配也可以不分配 IP 地址。
如分配了 IP 地址,则这一段连线就构成了一种只包含一段线路的特殊“网络”(如图中的 N1,N2 和 N3).
之所以叫做“网络”是因为它有 IP 地址。
但为了节省 IP 地址资源,对于这种仅由一段连线构成的特殊“网络”,现在也常常不分配 IP 地址。
通常把这样的特殊网络叫做无编号网络或无名网络。

IP 地址与硬件地址

在学习 IP 地址时,很重要的一点就是要弄懂主机的 IP 地址与硬件地址的区别

在局域网中,由于硬件地址已固化在往卡上的 ROM 中,因此常常将硬件地址称为物理地址。
因为在局域网的 MAC 帧中的源地址和目的地址都是硬件地址,因此硬件地址又称为 MAC 地址。

下图说明了这两种地址的区别。
从层次的角度看,物理地址是数据链路层和物理层使用的地址,而 IP 地址是网络层和以上各层使用的地址,是一种逻辑地址(称 IP 地址为逻辑地址是因为 IP 地址是用软件实现的)

IP地址与硬件地址的区别

在发送数据时,数据从高层下到低层,然后才到通信链路上传输。
使用 IP 地址的 IP 数据报一旦交给了数据链路层,就被封装成 MAC 帧了。
MAC 帧在传送时使用的源地址和目的地址都是硬件地址,这两个硬件地址都写在 MAC 帧的首部中。

连接在通信链路上的设备(主机或路由器)在收到 MAC 帧时,根据 MAC 帧首部中的硬件地址决定收下或丢弃。
只有在剥去 MAC 帧的首部和尾部后把 MAC 层的数据上交给网络层后,网络层才能在 IP 数据报的首部中找到源 IP 地址和目的 IP 地址。

总之,IP 地址放在 IP 数据报的首部,而硬件地址则放在 MAC 帧的首部。
在网络层和网络层以上使用的是 IP 地址,而数据链路层及以下使用的是硬件地址。
在上图中,当 IP 数据报放入数据链路层的 MAC 帧中以后,整个的 IP 数据报就成为 MAC 帧的数据,因而在数据链路层看不见数据报的 IP 地址。

下图(a)画的是三个局域网用两个路由器 R1 和 R2 互连起来。
现在主机 H1 要和主机 H2 通信。这两台主机的 IP 地址分别是 IP1 和 IP2,而它们的硬件地址分别为 HA1 和 HA2(HA 表示 Hardware Address)。
通信的路径是:H1->经过 R1 转发->再经过 R2 转发->H2。
路由器 R1 因同时连接到两个局域网上,因此它有两个硬件地址,即 HA3 和 HA4。同理,路由器 R2 也有两个硬件地址 HA5 和 HA6。

从不同层次上看IP地址和硬件地址

图(b)特别强调了 IP 地址与硬件地址的区别

这里要强调指出以下几点:
(1) 在 IP 层抽象的互联网只能看到 IP 数据报。
虽然 IP 数据报要经过路由器 R1 和 R2 的两次转发,但在它的首部中的源地址和目的地址始终分别是 IP1 和 IP2。
图中的数据报上写的“从 IP1 到 IP2”就表示前者是源地址而后者是目的地址。
数据报中间经过的两个路由器的 IP 地址并不出现在 IP 数据报的首部中

(2) 虽然在 IP 数据报首部有源站地址,但路由器只根据目的站的 IP 地址的网络号进行路由选择

(3) 在局域网的链路层,只能看见 MAC 帧,IP 数据被封装在 MAC 帧中。
MAC 帧在不同网络上传送时,其 MAC 帧首部中的源地址和目的地址要发生变化,见上图(b)。
开始在 H1 到 R1 间传送时,MAC 帧首部中写的是从硬件地址 HA1 发送到硬件地址 HA3,路由器 R1 收到此 MAC 帧后,在数据链路层,要丢弃原来的 MAC 帧的首部和尾部。
在转发时,在数据链路层,要重新添加上 MAC 帧的首部和尾部。
这时首部中的源地址和目的地址分别变成为 HA4 和 HA5。路由器 R2 收到此帧后,再次更换 MAC 帧的首部和尾部,首部中的源地址和目的地址分别变成为 HA6 和 HA2。
MAC 帧的首部的这种变化,在上面的 IP 层上是看不见的。

(4) 尽管互连在一起的网络的硬件地址体系各不相同,但 IP 层抽象的互联网却屏蔽了下层这些很复杂的细节。
只要我们在网络层上讨论问题,就能够使用统一的、抽象的 IP 地址研究主机和主机或路由器之间的通信。
上述的这种“屏蔽”是一个很有用、很普遍的基本概念。例如,计算机中广泛使用的图形用户界面使得用户只需简单地点击几下鼠标就能让计算机完成很多任务。实际上计算机要完成这些任务必须执行很多条指令。
但这些复杂的过程全都被设计良好的图形用户界面屏蔽掉了,使用户看不见这些复杂过程

现在还有两个重要问题没有解决:
(1) 主机或路由器怎样知道应当在 MAC 帧的首部填入什么样的硬件地址?
(2) 路由器中的路由表是怎样得出的?

地址解析协议 ARP

在实际应用中,我们经常会遇到这样的问题:已经知道了一个机器(主机或路由器)的 IP 地址,需要找出其相应的硬件地址。
地址解析协议 ARP 就是用来解决这样的问题的。下图说明了 ARP 协议的作用

ARP协议的作用

由于是 IP 协议使用了 ARP 协议,因此通常就把 ARP 协议划归网络层。
但 ARP 协议的用途是为了从网络层使用的 IP 地址,解析出在数据链路层使用的硬件地址。
因此,有的教科书就按照协议的所用,把 ARP 协议划归在数据链路层。这样做当然也是可以的

还有一个旧的协议叫做逆地址解析协议 RARP,它的作用是使只知道自己硬件地址的主机能够通过 RARP 协议找出其 IP 地址。现在的 DHCP 协议已经包含了 RARP 协议的功能。

下面介绍 ARP 协议的要点

我们知道,网络层使用的是 IP 地址,但在实际网络的链路上传送数据帧时,最终还是必须使用该网络的硬件地址。
但 IP 地址和下面的网络的硬件地址之间由于格式不同而不存在简单的映射关系(例如,IP 地址有 32 位,而局域网的硬件地址是 48 位)。
此外,在一个网络上可能经常会有新的主机加入进来,或撤走一些主机。
更换网络适配器也会使主机的硬件地址改变。
地址解析协议 ARP 解决这个问题的方法是在主机 ARP 高速缓存中存放一个从 IP 地址到硬件地址的映射表,并且这个映射表还经常动态更新(新增或超时删除)

每一台主机都设有一个 ARP 高速缓存(ARP cache),里面有本局域网上的各主机和路由器的 IP 地址到硬件地址的映射表,这些都是该主机目前知道的一些地址。
那么主机怎样知道这些地址呢?我们可以通过下面的例子来说明。

当主机 A 要向本局域网上的某台主机 B 发送 IP 数据报时,就先在其 ARP 高速缓存中查看有无主机 B 的 IP 地址。
如有,就在 ARP 高速缓存中查出其对应的硬件地址,再把这个硬件地址写入 MAC 帧,然后通过局域网把该 MAC 帧发往此硬件地址。

也有可能查不到主机 B 的 IP 地址的项目。这可能是主机 B 才入网,也可能是主机 A 刚刚加电,其高速缓存还是空的。
在这种情况下,主机 A 就自动运行 ARP,然后按以下步骤找出主机 B 的硬件地址。

(1) ARP 进程在本局域网上广播发送一个 ARP 请求分组。
下图(a)是主机 A 广播发送 ARP 请求分组的示意图。ARP 请求分组的主要内容是:“我的 IP 地址是 209.0.0.5,硬件地址是 00-00-C0-15-AD-18。我想知道 IP 地址为 209.0.0.6 的主机的硬件地址“

(2) 在本局域网上的所有主机上运行的 ARP 进程都收到此 ARP 请求分组

(3) 主机 B 的 IP 地址与 ARP 请求分组中要查询的 IP 地址一致,就收下这个 ARP 请求分组,并向主机 A 发送 ARP 响应分组,同时在这个 ARP 响应分组中写入自己的硬件地址。
由于其余的所有主机的 IP 地址都与 ARP 请求分组中要查询的 IP 地址不一致,因此都不理睬这个 ARP 请求分组,见图(b)。
ARP 响应分组的主要内容是:“我的 IP 地址是 209.0.0.6,我的硬件地址是 08-00-2B-00-EE-0A”。
请注意:虽然 ARP 请求分组是广播发送的,但 ARP 响应分组是普通的单播,即从一个源地址发送到另一个目的地址

地址解析协议ARP的工作原理

(4) 主机 A 收到主机 B 的 ARP 响应分组后,就在其 ARP 高速缓存中写入主机 B 的 IP 地址到硬件地址的映射

当主机 A 向 B 发送数据报时,很可能以后不久主机 B 还要向 A 发送数据报,因而主机 B 也可能要向 A 发送 ARP 请求分组。为了减少网络上的通信量,主机 A 在发送其 ARP 请求分组时,就把自己的 IP 地址到硬件地址的映射写入 ARP 请求分组。
当主机 B 收到 A 的 ARP 请求分组时,就把主机 A 的这一地址映射写入主机 B 自己的 ARP 高速缓存中。
以后主机 B 向 A 发送数据报时就很方便了。

可见 ARP 高速缓存非常有用。
如果不使用 ARP 高速缓存,那么任何一台主机只要进行一次通信,就必须在网络上用广播方式发送 ARP 请求分组,这就使网络上的通信量大大增加。
ARP 把已经得到的地址映射保存在高速缓存中,这样就使得该主机下次再和具有同样目的地址的主机通信时,可以直接从高速缓存中找到所需的硬件地址而不必再用广播方式发送 ARP 请求分组

ARP 对保存在高速缓存中的每一个映射地址项目都设置生存时间(例如,10-20 分钟)。
凡超过生存时间的项目就从高速缓存中删除掉。设置这种地址映射项目的生存时间是很重要的。
设想有一种情况。主机 A 和 B 通信。A 的 ARP 高速缓存里保存有 B 的硬件地址。
但 B 的网络适配器突然坏了,B 立即更换了一块,因此 B 的硬件地址就改变了。
假定 A 还要和 B 继续通信。 A 在其 ARP 高速缓存中查找到 B 原先的硬件地址,并使用该硬件地址向 B 发送数据帧。
但 B 原先的硬件地址已经失效了,因此 A 无法找到主机 B。
但是过了一段不长的生存时间,A 的 ARP 高速缓存中已经删除了 B 原先的硬件地址,于是 A 重新广播发送 ARP 请求分组,又找到了 B

请注意,ARP 是解决同一个局域网上的主机或路由器的 IP 地址和硬件地址的映射问题。
如果所要找的主机 H2 和源主机 H1 不在同一个局域网上,主机 H1 就无法解析出另一个局域网上主机 H2 的硬件地址(实际上主机 H1 也不需要知道远程主机 H2 的硬件地址)。
主机 H1 发送给 H2 的 IP 数据报首先需要通过与主机 H1 连接在同一个局域网上路由器 R1 来转发。
因此主机 H1 这时需要把路由器 R1 的 IP 地址 IP3 解析为硬件地址 HA3。以便能够把 IP 数据报传送到路由器 R1。
以后,R1 从转发表找出下一跳路由器 R2,同时使用 ARP 解析出 R2 的硬件地址 HA5。
于是 IP 数据报按照硬件地址 HA5 转发到路由器 R2。路由器 R2 在转发这个 IP 数据报时用类似方法解析出目的主机 H2 的硬件地址 HA2,使 IP 数据报最终交付主机 H2。

从 IP 地址到硬件地址的解析是自动进行的,主机的用户对这种地址解析过程是不知道的。
只要主机或路由器要和本网络上的另一个已知 IP 地址的主机或路由器进行通信,ARP 协议就会自动地把这个 IP 协议解析为链路层所需要的硬件地址

下面我们归纳出使用 ARP 的四种典型情况

使用ARP的四种典型情况

(1) 发送方是主机(如 H1),要把 IP 数据报发送到同一个网络上的另一台主机(如 H2)。
这时 H1 发送 ARP 请求分组(在网 1 上广播),找到目的主机 H2 的硬件地址

(2) 发送方是主机(如 H1),要把 IP 数据报发送到另一个网络上的一台主机(如 H3 或 H4)。
这时 H1 发送 ARP 请求分组(在网 1 上广播),找到网 1 上的一个路由器 R1 的硬件地址。
剩下的工作由路由器 R1 来完成。R1 要做的事情是下面的 (3) 或 (4)

(3) 发送方是路由器(如 R1),要把 IP 数据报转发送与 R1 连接在同一个网络(网2)上的主机(如 H3)。这时 R1 发送 ARP 请求分组(在网 2 上广播),找到目的主机 H3 的硬件地址

(4) 发送方是路由器(如 R1),要把 IP 数据报转发送网 3 上的一台主机(如 H4)。
H4 与 R1 不是连接在同一个网络上。这时 R1 发送 ARP 请求分组(在网 2 上广播),找到连接在网 2 上的一个路由器 R2 的硬件地址。剩下的工作由路由器 R2 来完成

在许多情况下需要多次使用 ARP。但这只是以上几种情况的反复使用而已。

既然在网络链路上传送的帧最终是按照硬件地址找到目的主机的,那么为什么我们还要使用抽象的 IP 地址,而不直接使用硬件地址进行通信?这样似乎可以免除使用 ARP。

这个问题必须弄清楚

由于全世界存在着各式各样的网络,它们使用不同的硬件地址。
要使这些异构网络能够互相通信就必须进行非常复杂的硬件地址转换工作,因此由用户或用户主机来完成这项工作几乎是不可能的事。
但 IP 编址把这个复杂问题解决了。连接到互联网的主机只需各自拥有一个唯一的 IP 地址,它们之间的通信就像连接在同一个网络上那样简单方便,因为上述的调用 ARP 的复杂过程都是由计算机软件自动进行的,对用户来说是看不见这种调用过程的。

因此,在虚拟的 IP 网路上用 IP 地址进行通信给广大的计算机用户带来很大的方便

IP 数据报的格式

IP 数据报的格式能够说明 IP 协议都具有什么功能。
在 TCP/IP 的标准中,各种数据格式常以 32 位(即 4 字节)为单位来描述。下图是 IP 数据报的完整格式

IP数据报的格式

从上图可以看出,一个 IP 数据报由首部和数据两部分组成。
首部的前一部分是固定长度,共 20 个字节,是所有 IP 数据报必须具有的。
在首部的固定部分的后面是一些可选字段,其长度是可变的。下面介绍首部各字段的意义。

IP 数据报首部的固定部分中的各字段

(1) 版本占 4 位,指 IP 协议的版本。通信双方使用的 IP 协议的版本必须一致。目前广泛使用的 IP 协议版本号为 4(即 IPv4)。关于以后要使用的 IPv6(即版本 6 的 IP 协议)我们后面讨论

(2) 首部长度占 4 位,可表示的最大十进制数值是 15.
请注意,首部长度字段所表示数的单位是 32 位字(1 个 32 位字长是 4 字节)。
因为 IP 首部的固定长度是 20 字节,因此首部长度字段的最小值是 5(即二进制表示的首部长度是 0101)。
而当首部长度为最大值 1111 时(即十进制数的 15),就表明首部长度达到最大值 15 个 32 位字长,即 60 字节。
当 IP 分组的首部长度不是 4 字节的整数倍时,必须利用最后的填充字段加以填充。
因此 IP 数据报的数据部分永远在 4 字节的整数倍时开始,这样在实现 IP 协议时较为方便。
首部长度限制为 60 字节的缺点是有时可能不够用。
但这样做是希望用户尽量减少开销。最常用的首部长度是 20 字节(即首部长度为 0101),这时不使用任何选项

(3) 区分服务占 8 为,用来获得更好的服务,这个字段在旧标准中叫做服务类型,但实际上一直没有被使用过。1998 年 IETF 把这个字段改名为区分服务 DS(Differentiated Services)。只有在使用区分服务时,这个字段才起作用。在一般的情况下都不使用这个字段

(4) 总长度指首部和数据之和的长度,单位为字节。总长度字段为 16 位,因此数据报的最大长度为 2^{16} - 1 = 65535字节。然后实际上传送这样的长的数据报在现实中是极少遇到的

我们知道,在 IP 层下面的每一种数据链路协议都规定了一个数据帧中的数据字段的最大长度,这称为最大传送单元 MTU(Maximum Transfer Unit)。
当一个 IP 数据报封装成链路层的帧时,此数据报的总长度一定不能超过下面的数据链路层所规定的 MTU 值。
例如,最常用的以太网就规定其 MTU 值是 1500 字节。若所传送的数据报长度超过数据链路层的 MTU 值,就必须把过长的数据报进行分片处理。

虽然使用尽可能长的 IP 数据报会使传输效率得到提高(因为每一个 IP 数据报中的首部长度占数据报总长度的比例就会小些),但数据报短也有好处。每一个 IP 数据报越短,路由器转发的速度就越快。
为此,IP 协议规定,在互联网中所有的主机和路由器,必须能够接受长度不超过 576 字节的数据报。
这是假定上层交下来的数据长度有 512 字节(合理的长度),加上最长的 IP 首部 60 字节,再加上 4 字节的富余量,就得到 576 字节。
当主机需要发送长度超过 576 字节的数据报时,应当先了解一下,目的主机能否接受所要发送的数据报长度。否则就要进行分片。

在进行分片时,数据报首部中的“总长度”字段是指分片后每一个分片的首部长度与该分片的数据长度的总和

(5) 标识占 16 位。IP 软件在存储器中维持一个计数器,每产生一个数据报,计数器就加一,并将此值赋给标识字段。
但这个“标识”并不是序号,因为 IP 是无连接服务,数据报不存在按序接收的问题。当数据报由于长度超过网络的 MTU 而必须分片时,这个标识字段的值就被复制到所有的数据报片的标识字段中。
相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报

(6) 标志 占 3 位,但目前只有两位的意义。
标志字段中的最低位记为 MF(More Fragment)。MF = 1即表示后面“还有分片”的数据。MF = 0表示这已是若干数据报片中的最后一个
标志字段中间的一位记为 DF(Don't Fragment),意思是“不能分片”。只有当DF = 0时才允许分片

(7) 片偏移占 13 位。片偏移指出:较长的分组的分片后,某片在原分组中的相对位置。也就是说,相对于用户数据字段的起点,该片从何处开始。片偏移以 8 各字节为偏移单位。这就是说,每个分片的长度一定是 8 字节(64 位)的整数倍。

下面举一个例子:

一数据报的总长度为 3820 字节,其数据部分为 3800 字节长(使用固定首部),需要分片的长度不超过 1420 字节的数据报片。因固定首部长度为 20 字节,因此每个数据报片的数据部分长度不能超过 1400 字节。
于是分成 3 各数据报片,其数据部分的长度分别为 1400,1400 和 1000 字节。
原始数据报首部被复制为各数据报片的首部,但必须修改有关字段的值。

下图给出分片后得出的结果(请注意片偏移的数值)

数据报的分片举例

下表是本例中数据报首部与分片有关的字段中的值,其中标识字段的值是任意给定的(12345)。
具有相同标识的数据报片在目的站就可无误地重装成原来的数据报

数据报分片表

现在假定数据报片 2 经过某个网络时还需要再进行分片,即划分成数据报片 2-1(携带数据 800 字节)和数据报片 2-2(携带数据 600 字节)。
那么这两个数据报片的总长度、标识、MF、DF 和片偏移分别为:820, 12345, 1, 0, 175; 620, 12345, 1, 0, 275

(8) 生存时间占 8 位,生存时间字段常用的英文缩写是 TTL(Time To Live),表明这是数据报在网络中的寿命。
由发出数据报的源点设置这个字段。其目的是防止无法交付的数据报无限制地在互联网中兜圈子(例如从路由器 R1 转发到 R2,再转发到 R3,然后又转发到 R1),因而白白消耗网络资源。
最初的设计是以秒作为 TTL 的单位。每经过一个路由器时,就把 TTL 减去数据报在路由器所消耗掉的一段时间。
如数据报在路由器消耗的时间小于 1 秒,就把 TTL 值减一。当 TTL 值减为 0 时,就丢弃这个数据报

然而随着技术的进步,路由器处理数据报所需的时间不断在缩短,一般都远远小于 1 秒,后来就把 TTL 字段的功能改为“跳数限制”(但名称不变)。
路由器在每次转发数据报之前就把 TTL 值减 1。若 TTL 值减小到 0,就丢弃这个数据报,不再转发。
因此,现在 TTL 的单位不再是秒,而是跳数。TTL 的意义是指明数据报在互联网中至多经过多少个路由器。
显然,数据报能在互联网中经过的路由器的最大数值是 255.
若把 TTL 的初始值设置为 1,就表示这个数据报只能在本局域网中传送。
因为这个数据报一传送到局域网的某个路由器,在被转发之前 TTL 值就减小到零,因而就会被这个路由器丢弃

(9) 协议占 8 位,协议字段指出此数据报携带的数据使用何种协议,以便使目的主机的 IP 层知道应将数据部分上交给哪个协议进行处理

常用的一些协议和相应的协议字段值如下

协议名 ICMP IGMP IP TCP EGP IGP UDP IPv6 ESP OSPF
协议字段值 1 2 4 6 8 9 17 41 50 89

注:这里的 IP 表示特殊的 IP 数据报--IP 数据报再封装到 IP 数据报中

(10) 首部检验和占 16 位。这个字段只检验数据报的首部,但不包括数据部分。
这是因为数据报每经过一个路由器,路由器都要重新计算一下首部检验和(一些字段,如生存时间、标志、片偏移等都可能发生变化)。
不检验数据部分可减少计算的工作量。
为了进一步减小计算检验和的工作量,IP 首部的检验和不采用复杂的 CRC 检验码而采用下面的简单计算方法:在发送方,先把 IP 数据报首部划分为许多 16 位字的序列,并把检验和字段置 0.
用反码算法运算把所有 16 位字相加后,将得到的反码写入检验和字段。
接收方收到数据报后,将首部的所有 16 位字再使用反码算术运算相加一次。
将得到的和取反码,即得出接收方检验和的计算结果。若首部未发生任何变化,则此结果必为 0,于是就保留这个数据报。
否则即认为出差错,并将此数据报丢弃。

下面说明了 IP 数据报首部检验和的计算过程

IP数据报首部检验和的计算过程

(11) 源地址占 32 位
(12) 目的地址占 32 位

IP 数据报首部的可变部分

IP 数据报首部的可变部分就是一个选项字段。选项字段用来支持排错、测量以及安全等措施,内容很丰富。
此字段的长度可变,从 1 个字节到 40 个字节不等,取决于所选择的项目。
某些选项项目只需要 1 个字节,它只包括 1 个字节的选项代码。
而有些选项需要多个字节,这些选项一个个拼接起来,中间不需要有分隔符,最后用全 0 的填充字段补齐成为 4 字节的整数倍

增加首部的可变部分是为了增加 IP 数据报的功能,但这同时也使得 IP 数据报的首部长度成为可变的。
这就增加了每一个路由器处理数据报的开销。实际上这些选项很少被使用。
很多路由器都不考虑 IP 首部的选项字段,因此新的 IPv6 就把 IP 数据报的首部长度做成固定的

IP 层转发分组的流程

下面我们先用一个简单例子来说明路由器是怎样转发分组的。下图(a)是一个路由表的简单例子。

路由表举例

有四个 A 类网络通过三个路由器连接在一起。每一个网络上都可能有成千上万台主机(图中没有画出这些主机)。
可以想象,若路由器指出到每一台主机应怎样转发,则所得出的路由表就会过于庞大(如果每一个网络有 1 万台主机,四个网络就有 4 万台主机,因而每个路由表就有 4 万个项目,即 4 万行。每一行对应于一台主机)。
但若路由表指出到某个网络应如何转发,则每个路由器中的路由表就只包含 4 个项目(即只有 4 行,每一行对应于一个网络)。
以路由器 R2 的路由表为例。由于 R2 同时连接在网络 2 和网络 3 上,因此只要目的主机在网络 2 或网络 3 上,都可通过接口 0 或 1 由路由器 R2 直接交付(当然还要利用地址解析协议 ARP 才能到这些主机相应的硬件地址)。
若目的主机在网络 1 中,则下一跳路由器应为 R1,其 IP 地址为 20.0.0.7。
路由器 R2 和 R1 由于同时连接在网络 2 上,因此从路由器 R2 把分组转发到路由器 R1 是很容易的。
同理,若目的主机在网络 4 中,则路由器 R2 应把分组转发给 IP 地址为 30.0.0.1 的路由器 R3。
我们应当注意到,图中的每一个路由器都有两个不同的 IP 地址

可以把整个的网络拓扑简化成上图(b)所示的那样。
在简化图中,网络变成了一条链路,但每一个路由器旁边都注明其 IP 地址。
使用这样的简化图,可以使我们不必关心某个网络内部的具体拓扑以及连接在该网络上有多少台主机,因为这些对于研究分组转发问题并没有什么关系。
这样的简化图强调了在互联网上转发分组时,是从一个路由器转发到下一个路由器

总之,在路由表中,对每一条路由最主要的是以下两个信息:
(目的网络地址,下一跳地址)

于是,我们就根据目的网络地址来确定下一跳路由器,这样做可得出以下的结果

(1) IP 数据报最终一定可以找到目的主机所在目的网络上的路由器(可能要通过多次的间接交付)
(2) 只有到达最后一个路由次时,才试图向目的主机进行直接交付

虽然互联网所有的分组转发都是基于目的主机所在的网络,但在大多数情况下都允许有这样的特例,即对特定的目的主机指明一个路由。
这种路由叫做特定主机路由。
采用特定主机路由可使网络管理人员更方便地控制网络和测试网络,同时也可在需要考虑某种安全问题时采用这种特定主机路由。
在对网络的连接或路由表进行排错时,指明到某一台主机的特殊路由就十分有用。

路由器还可以采用默认路由以减小路由表所占用的空间和搜索路由表所用的时间。
这种转发方式在一个网络只有很少的对外连接时是很有用的。
实际上,默认路由在主机发送 IP 数据报时往往更能显示出它的好处。

前面讲过,主机在发送每一个 IP 数据报时都要查找自己的路由表。
如果一台主机连接在一个小网络上,而这个网络只用一个路由器和互联网连接,那么在这种情况下使用默认路由是非常合适的。
例如,在下图的互联网中,连接在网络 N1 上的任何一台主机中的路由表只需要三个项目即可。

路由器R1充当网络N1的默认路由器

第一个项目就是到本网络主机的路由,其目的网络就是本网络 N1,因而不需要路由器转发,而是直接交付。
第二个项目是到网络 N2 的路由,对应的下一跳路由器是 R2。
第三个项目就是默认路由器。只要目的网络是其他网络(不是 N1 或 N2),就一律选择默认路由,把数据报先间接交付路由器 R1,让 R1 再转发给互联网中的下一个路由器,一直转发到目的网络上的路由器,最后进行交付。
在实际上的路由器中,像上图路由表中所示的“直接”和“其他”的几个字符并没有出现在路由表中,而是被记为 0.0.0.0。

这里我们应当强调指出,在 IP 数据报的首部中没有地方可以用来指明“下一跳路由器的 IP 地址”。
在 IP 数据报的首部写上的 IP 地址是源 IP 地址和目的 IP 地址,而没有中间经过的路由器的 IP 地址。
既然 IP 数据报中没有下一跳路由器的 IP 地址,那么待转发的数据报又怎样能够找到下一跳路由器呢?

当路由器收到一个待转发的数据报,在从路由表得出下一跳路由器的 IP 地址后,不是把这个地址填入 IP 数据报,而是送交数据链路层的网络接口软件。
网络接口软件负责把下一跳路由器的 IP 地址转换成硬件地址(必须使用 ARP),并将此硬件地址放在链路层的 MAC 帧的首部,然后根据这个硬件地址找到下一跳路由器。
由此可见,当发送一连串的数据报时,上述的这种查找路由器、用 ARP 得到硬件地址、把硬件地址写入 MAC 帧的首部等过程,将不断地重复进行,造成了一定的开销。

那么,能不能在路由表中不使用 IP 地址而直接使用硬件地址呢?不行。我们一定要弄清楚,使用抽象的 IP 地址,本来就是为了隐藏各种底层网络的复杂性而便于分析和研究问题,这样就不可避免地要付出些代价,例如在选择路由时多了一些开销。
但反过来,如果在路由器中直接使用硬件地址,那就会带来更多的麻烦。

根据以上所述,可归纳出分组转发算法如下:

(1) 从数据报的首部提取目的主机的 IP 地址 D,得出目的网络地址为 N
(2) 若 N 就是与此路由器直接相连的某个网络地址,则进行直接交付,不需要再经过其他的路由器,直接把数据报交付目的主机(这里包括把目的主机地址 D 转换为具体的硬件地址,把数据报封装为 MAC 帧,再发送此帧);否则就是间接交付,执行(3)
(3) 若路由表中有目的地址为 D 的特定主机路由,则把数据报传送路由表中所指明的下一跳路由器;否则,执行(4)
(4) 若路由表中有到达网络 N 的路由,则把数据报传送给路由表中所指明的下一跳路由器;否则,执行(5)
(5) 若路由表中有一个默认路由,则把数据报传送给路由表中所指明的默认路由器;否则,执行(6)
(6) 报告转发分组出错

这里我们再要强调一下,路由表并没有给分组指明到某个网络的完整路径(即先经过哪一个路由器,然后再经过哪一个路由器,等等)。
路由表指出,到某个网络应当先到某个路由器(即下一跳路由器),在到达下一跳路由器后,再继续查找路由表,知道再下一步应当到哪一个路由器。
这样一步一步地查找下去,直到最后到达目的网络。

可以用一个简单的比喻来说明查找路由表的作用。
例如,从家门口开车到机场,但没有地图,不知道应当走哪条路线。
好在每一个道路岔口都有一个警察可以询问。因此,每到一个岔口(相当于到了一个路由器),就问:“到机场应当走哪个方向?”(相当于查找路由表)。
该警察既不指明到下一个岔口以后再应当如何走,也不指明还要经过几个岔口才到达机场。
他仅仅指出下一个岔口的方向。其回答可能是:“向左转”。
到了下一个岔口,再询问到机场该走哪个方向?回答可能是:“直行”。
这样,每到一个岔口,就询问下一步该如何走。这样,即使我们没有地图,但最终一定可以到达目的地--机场。

上面所讨论的是 IP 层怎样根据路由表的内容进行分组转发,而没有涉及到路由表一开始是如何建立的以及路由表中的内容应如何进行更新。

划分子网和构造超网

划分子网

从两级 IP 地址到三级 IP 地址

在今天看来,在 ARPANET 的早起,IP 地址的涉及确实不够合理

第一,IP 地址空间的利用率有时很低

每一个 A 类地址网络可连接的主机数超过 1000 万,而每一个 B 类地址网络可连接的主机数也超过 6 万。
有的单位申请到了一个 B 类地址网络,但所连接的主机数并不多,可是又不愿意申请一个足够使用的 C 类地址,理由是考虑到今后可能的发展。IP 地址的浪费,还会使 IP 地址空间的资源过早地被用完

第二,给每一个物理网络分配一个网络号会使路由表变得太大因而使网络性能变坏

每一个路由器都应当能够从路由表查出应该怎样到达其他网络的下一跳路由器。
因此,互联网中的网路数越多,路由器的路由表的项目数也就越多。
这样,即使我们拥有足够多的 IP 地址资源可以给每一个物理网络分配一个网络号,也会导致路由器的路由表中的项目数过多。
这不仅增加了路由器的成本(需要更多的存储空间),而且使查找路由时耗费更多的时间,同时也使路由器之间定期交换的路由信息急剧增加,因而使路由器和整个互联网的性能都下降了

第三,两级 IP 地址不够灵活

有时情况紧急,一个单位需要在新的地点马上开通一个新的网络。
但是在申请到一个新的 IP 地址之前,新增加的网络是不可能连接到互联网上工作的。
我们希望有一种方法,使一个单位能随时灵活地增加本单位的网络,而不必事先到互联网管理机构去申请新的网络号。
原来的两级 IP 地址无法做到这一点

为解决上述问题,从 1985 年起在 IP 地址中又增加了一个“子网号字段”,使两级 IP 地址变成为三级 IP 地址,它能够较好地解决上述问题,并且使用起来也很灵活。
这种做法叫做划分子网,或子网寻址或子网路由选择。
划分子网已成为互联网的正式标准协议。

划分子网的基本思路如下:
(1) 一个拥有许多物理网络的单位,可将所属的物理网络划分为若干个子网。划分子网纯属一个单位内部的事情。
本单位以外的网络看不见这个网络是由多少个子网组成,因为这个单位对外仍然表现为一个网络

(2) 划分子网的方法是从网络的主机号借用若干位作为子网号,当然主机号也就相当减少了同样的位数。
于是两级 IP 地址在本单位内部就变成三级 IP 地址:网络号、子网号和主机号。也可以用以下记法来表示

IP 地址 ::= {<网络号>,<子网号>,<主机号>}

(3) 凡事从其他网络发送给本单位某台主机的 IP 数据报,仍然是根据 IP 数据报的目的网络号找到连接在本单位网络上的路由器。
但此路由器在收到 IP 数据报后,再按目的的网络号和子网号找到目的子网,把 IP 数据报交付目的主机

下面用例子说明划分子网的概念。

一个B类网络

上图表示某单位拥有一个 B 类 IP 地址,网络地址是 145.13.0.0(网络号是 145.13)。
凡目的地址为 145.13.x.x 的数据报都被送到这个网络上的路由器 R1

现把上图的网络划分为三个子网。

划分为三个子网

这里假定子网号占用 8 位,因此在增加了子网号后,主机就只有 8 位。
所划分的三个子网分别是:145.13.3.0, 145.13.7.0 和 145.13.21.0。
在划分子网后,整个网络对外部仍表现为一个网络,其网络地址仍为 145.13.0.0。
但网络 145.13.0.0 上的路由器 R1 在收到外来的数据报后,再根据数据报的目的地址把它转发到相应的子网。

总之,当没有划分子网时,IP 地址是两级结构。划分子网后 IP 地址变成了三级结构。
划分子网只是把 IP 地址的主机号这部分进行再划分,而不改变 IP 地址原来的网络号

子网掩码

现在剩下的问题就是:假定有一个数据报(其目的地址是 145.13.3.10)已经到达了路由器 R1。
那么这个路由器如何把它转发到子网 145.13.3.0 呢?

我们知道,从 IP 数据报的首部无法看出源主机或目的主机所连接的网络是否进行了子网的划分。
这是因为 32 位的 IP 地址本身以及数据报的首部都没有包含任何有关子网划分的信息。
因此必须另外想办法,这就是使用子网掩码。

IP地址的各字段和子网掩码

上图(a)是 IP 地址为 145.13.3.10 的主机本来的两级 IP 地址结构。
图(b)是这个两级 IP 地址的子网掩码。
图(c)是同一个地址的三级 IP 地址结构,也就是说,现在从原来的 16 位的主机号中拿出 8 位作为子网号,而主机号由 16 位减少到 8 位。
请注意,现在子网号位 3 的网络的网络地址是 145.13.3.0(既不是原来两级 IP 地址的网络地址 145.13.0.0,也不是简单的子网号 3)。
为了使路由器 R1 能够很方便地从数据报中的目的 IP 地址中提取出所要找的子网的网络地址,路由器 R1 就要使用三级 IP 地址的子网掩码。
图(d)是三级 IP 地址的子网掩码,它也是 32 位,由一串 24 个 1 和跟随的一串 8 个 0 组成。
子网掩码中的 1 对应于 IP 地址中原来二级地址中的 16 位网络号加上新增加的 8 位子网号,而子网掩码中的 0 对应于现在的 8 位主机号。
虽然 RFC 文档中没有规定子网掩码中的一串 1 必须是连续的,但却极力推荐在子网掩码中选用连续的 1,以免出现可能发生的差错。

图(e)表示 R1 把三级 IP 地址的子网掩码和收到的数据报的目的 IP 地址 145.13.3.10 逐位相“与”(AND),得出了所要找的子网的网络地址 145.13.3.0

使用子网掩码的好处就是:不管网络有没有划分子网,只要把子网掩码和 IP 地址进行逐位的“与”运算(AND),就立即得出网络地址来。
这样在路由器处理到来的分组时就可采用同样的算法。

归纳一下上述的要点。从网络 145.13.0.0 外面看,这就是一个普通的 B 类网络,其子网掩码为 16 个连 1 后面跟上 16 个连 0.
但进入到这个网络后(即到了路由器 R1),就看到了还有许多网络(即划分了子网后的许多网络),其网络地址是 145.13.x.0(这里 x 可以表示不同的数字),而这些网络的子网掩码都是 24 个连 1 后面跟上 8 个连 0.
总之,在这个 B 类网络的外面和里面,看到的网络是不一样的

这里还要弄清一个问题,这就是:在不划分子网时,既然没有子网,为什么还要使用子网掩码?
这就是为了便于查找路由表。
现在互联网的标准规定:所有的网络都必须使用子网掩码,同时在路由器的路由表中也必须有子网掩码这一栏。
如果一个网络不划分子网,那么该网络的子网掩码就使用默认子网掩码。
默认子网掩码中 1 的位置和 IP 地址中的网络号字段正好相对应。
因此,若用默认子网掩码和某个不划分子网的 IP 地址逐位相“与”(AND),就应当能够得出该 IP 地址的网络地址来。
这样做可以不用查找该地址的类别位就能知道这是哪一类的 IP 地址。显然,

A 类地址的默认子网掩码是 255.0.0.,或 0xFF000000
B 类地址的默认子网掩码是 255.255.0.0,或 0xFFFF0000
C 类地址的默认子网掩码是 255.255.255.0,或 0xFFFFFF00

下图是这三类 IP 地址的网络地址和相应的默认子网掩码

默认子网掩码

子网掩码是一个网络或一个子网的重要属性。
在 RFC 950 成为互联网的正式标准后,路由器在和相邻路由器交换路由信息时,必须把自己所在的网络(或子网)的子网掩码高速相邻路由器。
在路由器的路由表中的每一个项目,除了要给出目的网络地址外,还必须同时给出该网络的子网掩码。
若一个路由器连接在两个子网上就拥有两个网络地址和两个子网掩码

我们以一个 B 类地址为例,说明可以有多少种子网划分的方法。
在采用固定长度子网时,所划分的所有子网的子网掩码都是相同的

表:B 类地址的子网划分选择(使用固定长度子网)

子网号的位数 子网掩码 子网数 每个子网的主机数
2 255.255.192.0 2 16382
3 255.255.224.0 6 8190
4 255.255.240.0 14 4094
5 255.255.248.0 30 2046
6 255.255.252.0 62 1022
7 255.255.254.0 126 510
8 255.255.255.0 254 254
9 255.255.255.128 510 126
10 255.255.255.192 1022 30
11 255.255.255.224 2046 14
12 255.255.255.240 4094 6
13 255.255.255.248 8190 4
14 255.255.255.252 16382 2

在上表中,子网数是根据子网号(subnet-id)计算出来的。
若 subnet-id 有 n 位,则共有 2^n 种可能的排列。除去全 0 和全 1 这两种情况,就得出表中的子网数。

表中的“子网号的位数”中没有 0,1,15 和 16 这四种情况,因为这没有意义。

虽然根据已成为互联网标准协议的 RFC 950 文档,子网号不能位全 1 或全 0,但随着无分类域间路由选择 CIDR 的广泛使用,现在全 1 和全 0 的子网号也可以使用了,但一定要谨慎使用,要弄清你的路由器所用的路由选择软件是否支持全 0 或全 1 的子网号这种较新的用法。

我们可以看出,若使用较少位数的子网号,则每一个子网上可连接的主机数就较多。
反之,若使用较多位数的子网号,则子网的数据较多但每个子网上可连接的主机数就较少。
因此我们可根据网络的具体情况(一共需要划分多少个子网,每个子网中最多有多少台主机)来选择合适的子网掩码

通过简单的计算,不难得到这样的结论:划分子网增加了灵活性,但却减少了能够连接在网络上的主机总数。
例如,本来一个 B 类地址最多可连接 65534 台主机,但表中任意一行的最后两项的乘积一定小于 65534

例题:已知 IP 地址是 141.14.72.24,子网掩码是 255.255.192.0,试求网络地址
解:掩码的前两个字节都是全 1,因此网络地址的前两个字节写为 141.14。子网掩码的第四字节是全 0,因此网络地址的第四字节是 0.我们计算第三字节即可72 & 192 = 64

例题:若子网掩码改为 255.255.224.0。试求网络地址
解:用同样的方法可得出网络地址是141.14.64.0,和上例的结果相同

这个例子说明,同样的 IP 地址和不同的子网掩码可以得出相同的网络地址。但是,不同掩码的效果是不同的。
第一个例子中,子网号是 2 位,主机号是 14 位。第二个例子中,子网号是 3 位,主机号是 13 位。
因此这两个例子中可划分的子网数和每一个子网中的最大主机数都是不一样的

下面进一步讨论使用了子网掩码后怎样查找路由表

使用子网时分组的转发

在划分子网的情况下,分组转发的算法必须做相应的改动

我们应当注意到,使用子网划分后,路由表必须包含以下三项内容:目的网络地址、子网掩码和下一跳地址

在划分子网的情况下,路由器转发分组的算法如下:
(1) 从收到的数据报的首部提取目的 IP 地址 D
(2) 先判断是否为直接交付。对路由器直接相连的网络逐个进行检查:用各网络的子网掩码和 D 逐位相“与”(AND 操作),看结果是否和相应的网络地址匹配。
若匹配,则把分组进行直接交付(当然还需要把 D 转化成物理地址,把数据报封装成帧发送出去),转发任务技术。
否则就是间接交付,执行(3)
(3) 若路由表中目的地址为 D 的特定主机路由,则把数据报传送给路由表中所指明的下一跳路由器;否则,执行(4)
(4) 对路由器表中的每一行(目的网络地址,子网掩码,下一跳地址),用其中的子网掩码和 D 逐位相“与”,其结果为 N。若 N 与该行的目的网络地址匹配,则把数据报传送给该行指明的下一跳路由器;否则,执行(5)
(5) 若路由表中有一个默认路由,则把数据报传送给路由表中所指明的默认路由器;否则,执行(6)
(6) 报告转发分组出错

例题:图中有三个子网,两个路由器,以及路由器 R1 中的部分路由表。
现在源主机 H1 向目的主机发送分组。试讨论 R1 收到 H1 向 H2 发送的分组后查找路由表的过程

主机H1向H2发送分组

解:源主机 H1 向目的主机 H2 发送的分组的目的地址是 H2 的 IP 地址 128.30.33.138

源主机 H1 首先要进行的操作是要判断:发送的这个分组,是在本子网上直接交付还是要通过本子网上的路由器进行间接交付?

源主机 H1 把本子网的“子网掩码 255.255.255.128”与目的主机 H2 的“IP 地址 128.30.33.138”逐位相与,得出 128.30.33.128,它不等于 H1 的网络地址(128.30.33.0)。这说明 H2 与 H1 不在同一个子网上。
因此 H1 不能把分组直接交付 H2,而必须交给子网上的默认路由器 R1,由 R1 来转发

路由器 R1 在收到一个分组后,就在其路由表中逐行寻找有无匹配的网络地址。

先看 R1 路由表中的第一行。
用这一行的“子网掩码 255.255.255.128”逐位相与,得出 128.30.33.128。
然后和这一行给出的目的网络地址 128.30.33.0 进行比较。但比较的结果不一致(即不匹配)

用同样方法继续往下找第二行。
用第二行的“子网掩码 255.255.255.128”和该分组的“目的地址 128.30.33.138”逐位相与,结果也是 128.30.33.128。
这个结果和第二行的目的网络地址 128.30.33.128 相匹配,说明这个网络(子网 2)就是收到的分组所要寻找的目的网络。
于是不需要再继续查找下去。R1 把分组从接口 1 直接交付主机 H2(它们都在一个子网上)。

无分类编址 CIDR(构造超网)

网络前缀

划分子网在一定程度上缓解了互联网在发展中遇到的困难。
然而在 1992 年互联网仍然面临三个必须尽早解决的问题,这就是:

(1) B 类地址在 1992 年已分配了近一半,眼看很快就将全部分配完毕
(2) 互联网主干网上的路由表中的项目数急剧增长(从几千个增长到几万个)
(3) 整个 IPv4 的地址空间最终将全部耗尽,在 2011 年 2 月 3 日,IANA 宣布 IPv4 地址已经耗尽了

当时预计前两个问题将在 1994 年变得非常严重。因此 IETF 很快就研究出采用无分类编址的方法来解决前两个问题。
IETF 认为上面的第三个问题属于更加长远的问题,因此专门成立 IPv6 工作组负责研究解决新版本 IP 协议的问题。

其实早在 1987 年,RFC 1009 就指明了在一个划分子网的网络可同时使用几个不同的子网掩码。
使用变长子网掩码 VLSM(Variable Length Subnet Mask)可进一步提高 IP 地址资源的利用率。
在 VLSM 的基础上又进一步研究出无分类编址方法,它的正式名字是无分类域间路由选择(Classless Inter-Domain Routing, CIDR 的读音是"sider")。

CIDR 最主要的特点有两个:

(1) CIDR 消除了传统的 A 类、B 类和 C 类地址以及划分子网的概念,因而能更加有效地分配 IPv4 的地址空间,并且在新的 IPv6 使用之前容许互联网的规模继续增长。
CIDR 把 32 位 IP 地址划分为前后两个部分。前面部分是“网络前缀”(network-prefix)(或简称为“前缀”),用来指明网络,后面部分则用来指明主机。
因此 CIDR 使 IP 地址从三级编址(使用子网掩码)又回到了两级编址,但这已是无分类的两级编址。其记法是:

CIDR 还使用“斜线记法”,或称为 CIDR 记法,即在 IP 地址后面加上斜线“/”,然后写上网络前缀所占的位数。

(2) CIDR 把网络前缀都相同的连续的 IP 地址组成一个“CIDR 地址块”。
我们只要知道 CIDR 地址块中的任何一个地址,就可以知道这个地址块的起始地址(即最小地址)和最大地址,以及地址块中的地址数。
例如,已知 IP 地址 128.14.35.7/20 是某 CIDR 地址块中的一个地址,现在把它写成二进制表示,其中的前 20 位是网络前缀(用粗体和下划线表示出),而前缀后面的 12 位是主机号。
这个地址所在的地址块中的最小地址和最大地址可以很方便地得出:
最小地址:128.14.32.0(后面 12 位都是 0),最大地址:128.14.47.255(后面 12 位都是 1)

当然,以上这两个特殊地址的主机号是全 0 和 全 1 的地址。一般并不使用。通常只使用在这两个特殊地址之间的地址。
不难看出,这个地址块共有 2^{12} 个地址。
我们可以用地址块中的最小地址和网络前缀的位数指明这个地址块。
例如,上面的地址块可记为 128.14.32.0/20。在不需要指出地址块的起始地址时,也可把这样的地址块简称位“/20 地址块”

为了更方便地进行路由选择,CIDR 使用 32 位的地址掩码。地址掩码由一串 1 和一串 0 组成,而 1 的个数就是网络前缀的长度。
虽然 CIDR 不使用子网了,但由于目前仍有一些网络还使用子网划分和子网掩码,因此 CIDR 使用的地址掩码也可继续称为子网掩码。
例如,/20地址块的地址掩码是:20 个连续的 1,12 个连续的 0。斜线记法中,斜线后面的数字就是地址掩码中 1 的个数

注意,“CIDR不使用子网”是指 CIDR 并没有在 32 位地址中指明若干位作为子网字段。
但分配到一个 CIDR 地址块的单位,仍然可以在本单位内根据需要划分出一些子网。
这些子网也都只有一个网络前缀和一台主机号字段,但子网的网络前缀比整个单位的网络前缀要长些。
例如,某单位分配到地址块 /20,就可以再继续划分为 8 个子网(即需要从主机号中借用 3 位来划分子网)。
这时每一个子网的网络前缀就变成 23 位(原来的 20 位加上主机号借来的 3 位),比该单位的网络前缀多了 3 位。

斜线记法还有一个好处就是它除了表示一个 IP 地址外,还提供了其他一些重要信息。我们举例说明如下。

例如,地址 192.199.170.82/27 不仅表示 IP 地址是 192.199.170.82,而且还表示这个地址块的网络的前缀有 27 位(剩下的 5 位是主机号),因此这个地址块包含 32 个 IP 地址块(2^5 = 32)。
通过简单的计算还可得出,这个地址块的最小地址是 192.199.170.64,最大地址是 192.199.170.95。

由于一个 CIDR 地址块中有很多地址,所以在路由表中就利用 CIDR 地址块来查找目的网络。
这种地址的聚合常称为路由聚合,它使得路由表中的一个项目可以表示原来传统分类地址的很多个(例如上千个)路由。路由聚合也称为构成超网
如果没有采用 CIDR,则在 1994 年和 1995 年互联网的一个路由表就会超过 7 万个项目,而使用了 CIDR 后,在 1996 年一个路由表的项目数才只有 3 万多个。
路由聚合有利于减少路由器之间的路由选择信息的交换,从而提高了整个互联网的性能。

CIDR 记法有多种形式,例如,地址块 10.0.0.0/10 可简写为 10/10,也就是把点分十进制中低位连续的 0 省略。
另一种简化表示方法是在网络前缀的后面加一个星号,如0000101000*,意思是:在星号之前是网络前缀,而星号表示 IP 地址中的主机号,可以是任意值。

前缀位数不是 8 的整数倍时,需要进行简单的计算才能得到一些地址信息。

下表给出了最常用的 CIDR 地址块。表中的 K 表示 2^{10} 即 1024.
网络前缀小于 13 或大于 27 都较少使用。在“包含的地址数”中没有把全 1 和全 0 的主机号除外。

CIDR前缀长度 点分十进制 包含的地址数 相当于包含分类的网络数
/13 255.248.0.0 512 K 8 个 B 类或 2048 个 C 类
/14 255.252.0.0 256 K 4 个 B 类或 1024 个 C 类
/15 255.254.0.0 128 K 2 个 B 类或 512 个 C 类
/16 255.255.0.0 64 K 1 个 B 类或 256 个 C 类
/17 255.255.128.0 32 K 128 个 C 类
/18 255.255.192.0 16 K 64 个 C 类
/19 255.255.224.0 8 K 32 个 C 类
/20 255.255.240.0 4 K 16 个 C 类
/21 255.255.248.0 2 K 8 个 C 类
/22 255.255.252.0 1 K 4 个 C 类
/23 255.255.254.0 512 2 个 C 类
/24 255.255.255.0 256 1 个 C 类
/25 255.255.255.128 128 1/2 个 C 类
/26 255.255.255.192 64 1/4 个 C 类
/27 255.255.255.224 32 1/8 个 C 类

从表可看出,每一个 CIDR 地址块中的地址数一定是 2 的整数次幂。
除最后几行外,CIDR 地址块都包含了多个 C 类地址(是一个 C 类地址的 2^n 倍,n 是整数),这就是“构成超网”这一名词的来源。

使用 CIDR 的一个好处就是可以更加有效地分配 IPv4 的地址空间,可根据客户的需要分配适当大小的 CIDR 地址块。
然后在分类地址的环境中,向一个部门分配 IP 地址,就只能以 /8,16 或 /24 为单位来分配。这就很不灵活。

下图给出的是 CIDR 地址块分配的例子。
假定某 ISP 已拥有地址块 206.0.64.0/18 (相当于有 64 个 C 类网络)。
现在某大学需要 800 个 IP 地址。
ISP 可以给该大学分配一个地址块 206.0.68.0/22,它包括 1024 个 IP 地址,相当于 4 个连续的 C类/24 地址块,占该 ISP 拥有的地址空间的 1/16。
这个大学人后可自由地对本校的各系分配地址块,而各系还可再划分本系的地址块。
CIDR 的地址块分配有时不易看清,这是因为网络前缀和主机号的界限不是恰好出现在整数字节处。
只要写出地址的二进制表示(从图中的地址块的二进制表示中可看出,实际上只需要将其中的一个关键字转换为二进制的表示即可),弄清网络前缀的位数,就不会把地址块的范围弄错。

CIDR地址块划分举例

从图中可以清楚地看出地址聚合的概念。这个 ISP 共拥有 64 个 C 类网络。
如果不采用 CIDR 技术,则在该 ISP 的路由器交换路由信息的每一个路由器的路由表中,就需要有 64 个项目。
但采用地址聚合后,就只需用路由聚合后的一个项目 206.0.64.0/18 就能找到该 ISP。同理,这个大学共有 4 个系。
在 ISP 内的路由器的路由表中,也需使用 206.0.68.0/22 这个项目。这个项目好比是大学的收发室。
凡寄给这个大学任何一个系的邮件,邮递员都不考虑大学各个系的地址,而是把这些邮件集中投递到大学的收发室,然后由大学的收发室再进行下一步的投递。
这样就减轻了邮递员的工作量(相当于简化了路由器的查找)

从图下面表格中的二进制地址可看出,把四个系的路由聚合为大学的一个路由(即构成超网),是将网络前缀缩短。
网络前缀越短,其地址块所包含的地址数就越多。
而在三级结构的 IP 地址中,划分子网是使网络前缀变长。

虚拟专用网 VPN 和 网络地址转换 NAT

虚拟专用网 VPN

由于 IP 地址的紧缺,一个机构能够申请到的 IP 地址数往往远小于本机构所拥有的主机数。
考虑到因特网并不很安全,一个机构内也并不需要把所有的主机接入到外部的因特网。
实际上,在许多情况下,很多主机主要还是和本机构内的其他主机进行通信(例如,在大型商场或宾馆中,有很多用于营业和管理的计算机。显然这些计算机并不都需要和因特网相连)。

假定在一个机构内部的计算机通信也是采用 TCP/IP 协议,那么从原则上讲,对于这些仅在机构内部使用的计算机就可以由本机构自行分配其 IP 地址。
这就是说,让这些计算机使用仅在本机构有效的 IP 地址(这种地址称为本地地址),而不需要向因特网的管理机构申请全球唯一的 IP 地址(这种地址称为全球地址)。这样就可以大大节约宝贵的全球 IP 地址资源

但是,如果任意选择一些 IP 地址作为本机构内部使用的本地地址,那么在某种情况下可能会引起一些麻烦。
例如,有时机构内部的某个主机需要和因特网连接,那么这种仅在内部使用的本地地址就有可能和因特网中某个 IP 地址重合,这样就会出现地址二义性问题。

为了解决这一问题,RFC 1918 指明了一些专用地址(private address)。
这些地址只能用于一个机构的内部通信,而不能用于和因特网上的主机通信。换言之,专用地址只能用作本地地址而不能用作全球地址。
在因特网中的所有路由器,对目的地址是专用地址的数据报一律不进行转发。RFC 1918 指明的专用地址是:

(1) 10.0.0.0 到 10.255.255.255(或记为 10/8, 它又被称为 24 位块)
(2) 172.16.0.0 到 172.31.255.255(或记为 172.16/12,它又被称为 20 位块)
(3) 192.168.0.0 到 192.168.255.255(或记为 192.168/16,它又称为 16 位块)

采用这样的专用 IP 地址的互联网络称为专用互联网或本地互联网,或更简单些,就叫做专用网。
显然,全世界可能有很多专用互联网络具有相同的专用 IP,但这并不会引起麻烦,因为这些专用地址仅在本机构内部使用。
专用 IP 地址也叫做可重用地址(reusable address)