Contents

【计算机网络】网络层

网络层基于数据链路层实现,实现了主机到主机的通信,这一章对其中常见的知识进行讲解

概览&目标

网络层在五层模型中的位置

数据链路层的通信协议,能够让多台设备共享同一条物理信道交换机在数据链路层中提供了转发的功能,与只使用一根网线串联起所有设备的网络相比,含有交换机的网络更具有可拓展性。交换机的转发功能,是通过维护当前网络中Mac地址端口号的映射关系实现的,网络中的设备数受到交换机的存储能力的限制。因此**:数据链路层的传输范围有限**。

网络层的引入,将大的网络划分为了不同的子网,数据链路层只需要关心在某一子网内的数据传输问题即可,这和分治的思想非常相似。

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/split_network.svg

1. 路由器划分子网

如上图所示,两个路由器将网络划分为三个部分,紫色的交换机只需要关心如何在紫色的网络中进行数据传输即可,具体的原因我们后面再讲。网络层设备也无需关心数据链路层的具体情况,只需要在网络层构建的虚拟信道中进行通信即可。

需要学习的内容

  • 如何标识网络层中的设备?

    Mac地址是数据链路层设备的唯一标识,网络层设备也需要一个地址进行区分。

  • 知道目标设备的标识,如何在众多网络中找到对方?

  • 如何通过网络层信息知道对方的MAC地址?

IP数据报(v4)

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/ip_struct.svg

2. IP数据报格式

基础信息

  • 源IP地址 & 目标IP地址:网络层将数据从一台主机传送到另一台主机,数据报中存储双方地址进行标记,每个地址长32位;
  • 总长度:记录IP数据报头部+数据部分的长度,单位是byte
  • 首部长度:记录IP数据报头部长度,单位是4 bytes。这样设计是因为ip数据包的头部长度必须是4 bytes的整数倍,就算是对头部进行拓展时也需要通过补0的方法来维护这一性质;
  • 生存时间(TTL):从源主机传送到目标主机的过程中能够经过的最大路由数量。路由器每次转发之前都会将TTL减1,如果发现TTL为0就会直接丢弃;
  • 头部检验和:使用checksum作为检验和,只检验头部数据的正确性;

IP数据报分片

每个网络能够支持的最大数据报长度不同,我们将网络中的IP数据报中能够承载的数据部分长度叫做MTU。当路由设备识别到转发的数据报大小大于MTU时,有两种策略:

  • 扔掉这个数据报(直接不处理了,摆烂);
  • 将数据报分片,再由接收方进行拼接;

接下来从数据报格式的角度来理解一下这个过程。

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/ip_split_tags.svg

3. IP数据报中的分片标识

我们依次讲解:

  • DF(Don't Fragment):为0时表示允许分片,其他分片相关标识位有效。为1时表示禁止分片,其他分片相关标识全都无效;

    后面的字段,我们只讨论DF为0,即允许分片时的意义;另外,DF为0时数据不一定被分片。

  • MF(More Fragmentation):为1时表示后面还有更多分片,即当前分片不是最后一片;为0时表示没有更多分片了,当前分片可能是最后一片,也可能数据报根本没有被分片;

  • 分片标识:相当于分片的ID,和目的IP、源IP配合唯一标识一组分片;

  • 片偏移:标识当前片的数据的起始地址在总体中的偏移量。

    片偏移的单位是8byte,这是因为总长度用了16bit,而片偏移只用了13bit,因此将片偏移后补3个0,让他能够表达16bit的内容。不过也正因如此,除最后一个分片外,其他分片的长度必须为8byte的整数倍;

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/relations_offsetAndTotal.svg

4. 片偏移通过补0表达大范围数字

ip数据报分片实例

在这里,我们只关注分片相关的标识位以及数据部分的长度。假设网络的MTU = 1500Byte,这时传入了一个数据部分长度为4000Byte的ip数据报。

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/split_demo_origin.svg

5. 分片前数据

传入的数据IDXDF为0,表示允许分片。他的长度大于MTU,需要被分片。 $$ 4000 / 1500 = 2.6666… $$ 因此,会被分为三片,前两片中的数据部分长度与MTU相同,最后一片有剩余的数据。

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/split_demo_to.svg

6. 分片结果

IP地址

网络号与主机号

通过ip数据报的格式可以看出ip地址是一个32位数字。为了更好的供人类观看,我们将他的每一个字节用整数表示出来,中间用点分割。如:192.168.0.1。那么在实际的网络中ip地址对设备进行分层描述:第一部分是网络号,表示所在网络的编号;第二部分是设备号,表示设备在该网络中的编号

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/ip_address_split.svg

7. ip地址划分

子网掩码

不同子网中的主机数量未必相同,因此有了子网掩码。子网掩码用于记录网络号在ip地址中占高几位,如:

  • IP地址为192.168.43.56
  • 子网掩码为255.255.0.0

子网掩码与IP地址的长度相同,子网掩码中为1的位,在IP地址中表示网络号;为0的位则表示主机号。在上面的例子中,该ip地址对应的网络号为192.168.43.56

正是子网掩码实现了网络层次的划分,如:

ip地址子网掩码网络号
192.168.0.1255.255.0.0192.168.0.0
192.168.3.127255.255.255.0192.168.3.0
192.168.3.188255.255.255.0192.168.3.0
192.168.4.134255.255.255.0192.168.4.0

在上述网络中,网络被分为两层,这些机器同属于192.168.0.0这个子网,在子网中,又进行了进一步的细分,分为192.168.3.0192.168.4.0两个子网。子网下有不同的设备,整体结构如下图所示。

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/sub_net.svg

8. 子网分层

新的问题又产生了:想要将数据报从当前子网发出,应该怎么发?

网关

实际上,子网192.168.3.0中的设备在向外部进行通信时,不会直接发出。在该网络中,会存在一个"代表",他负责收集子网中的数据报向外发送;也负责接收外部请求,向内分发;这个网关就是一个入口。

假如192.168.3.127想要发送数据到192.168.4.134;子网192.168.3.0的网关为192.168.3.1;子网192.168.4.0的网关为192.168.4.1

那么:

  • 192.168.3.127监测到目标地址不在当前子网中,会将数据发送给他的网关192.168.3.1
  • 192.168.3.1同时处于192.168.3.0192.168.0.0两个网络中,他监测到目标在192.168.0.0子网中,所以不把数据发送给自己的网关, 而是直接在子网内发送给192.168.4.1192.168.4.0网络的网关;
  • 192.168.4.1收到数据报,监测到目标在192.168.4.0网络中,直接发送给192.168.4.134

子网内传输ARP

我想要发一个包到子网内的设备,我们的数据在网络层封装成数据报后需要交给链路层进行发送。数据链路层需要我们指定目标的MAC地址,这要怎么解决呢?

实际上每个参与到网络层的设备中都会维护一个ARP表,其中记录了子网中IP地址与MAC地址的映射关系。可以通过arp -a对arp表进行查看,具体如下:

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/image-20210907000435671.png

9. ARP表

DHCP——IP地址分配技术

经过上面的学习,我们发现,如果一台机器想要正常上网,需要配置:

  • IP地址:网络号要与所在网络相同,设备号不能与当前子网中其他设备重复;
  • 子网掩码:子网掩码必须和网络号相互配合;
  • 网关:必须显式的制定当前子网的代理人;

这些参数显然不能让每一个用户去手工配置,因此就有了DHCP,他的目的就是让用户不去手工配置这些参数,而是在连入网络时自动配置。现代的路由器上一般都会维护一个小型的DHCP服务器,整体过程如下。

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/foobar.svg

10. DHCP通信过程

但是值得注意的是,DHCP算得上是一个应用层协议,他是借助UDP协议实现的。

除此之外,分配地址后,客户端需要定期向DHCPServer进行续租操作,否则IP地址会被收回,并且分配给其他设备使用。

数据跨子网传输

NAT网络地址转换

上一小节中讲到每个子网中会有一个“代理人”网关,他同时存在于两个网络中,负责收集子网的数据向外发送,假设有下图中的网络。

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/NAT_Router.svg

11. 单设备代理子网

现在路由器代理的内网中有多台设备,他们都需要向外网发送数据、接收数据。如果路由不对数据报进行任何处理,在发送时候不会有任何影响。但是在接受数据报时,接收的对象是子网内ip地址,无法在公网找到当前路由。NAT技术通过映射端口号的方法来满足跨网通信。

简谈传输层

在了解NAT前需要先了解一点传输层知识,网络层实现了复杂网络中从一台主机到另一台主机的通信。但实际应用过程中,需要进行进程与进程之间通信,所以传输层在网络层基础上进一步封装,实现进程间通信。具体讲:

  • 网络层中定义了端口号;
  • 应用进程会监听当前主机的某个端口;
  • 不同进程监听不同端口,同一个端口在一般情况下不可以被多个进程监听;

在传输层指定端口就可以达到进程间通信的目的。

回到NAT协议

NAT协议较为特殊,他通过映射端口号来实现代理。路由接收到子网中设备的数据报,其中:

  • 网络层协议中会带有发送方的IP地址;
  • 传输层协议中会带有发送方的端口号;

路由开辟一个新的端口用于代理收到的IP, port,路由中维护一个NAT表,记录自身端口号与子网中IP, port的映射关系。当路由收到数据后会检查数据的端口号,在NAT表中查找端口号对应的IP, port,随后替换数据报中的IPNAT表中的IP,随后将数据部分承载的上层协议的Port也进行替换。

CIDR——路由聚合

上面我们讲解了IP地址,想要解读一个IP地址需要知道他的IP地址,以及他的子网掩码。

有类IP地址

有组织制定了标准,在该标准中,将IP地址划分为5类:

  • A类0.0.0.0 ~ 126.255.255.255这个范围被称为A类,它的子网掩码为255.0.0.0
  • B类127.0.0.0 ~ 191.255.255.255这个范围被称为B类,它的子网掩码为255.255.0.0
  • 以此类推

我们不详细介绍有类IP了,有类IP的划分过于固定,难以适应现实世界的情况;

CIDR

CIDR解决了有类IP划分过于固定的问题,具体来说CIDR使用下面的方法表示一个IP地址

192.168.3.4/24

这里就表示:

  • IP地址为:192.168.3.4
  • 子网掩码为:255.255.255.0

后缀可以任意活动,这样就可以针对不同的情况进行更好的划分。

路由聚合

实际上,在每个路由中都会维护一个转发表。假设有这样一个网络:

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/normal_router.svg

12. 简单路由
目标地址转发到哪个子网
192.168.3.1A
192.168.4.XB

但是,实际情况可能有所不同,如:

https://goleveldb-1301596189.cos.ap-guangzhou.myqcloud.com/nnr.svg

13. 较为复杂的网络的路由

这个时候就会触发路由聚合。

目标地址转发到哪个子网
192.168.4.3A
192.168.4.0B
192.168.5.2B

在实际转发过程中,将在路由表中对目标地址进行最长前缀匹配,将数据报转发到最长匹配的目标中。