type
status
date
slug
summary
tags
category
icon
password

1、网络层概述

网络层的主要作用是:实现主机与主机或路由器之间的通信,也叫点对点(end to end)通信
网络层位于传输层之下,向传输层只提供简单灵活的、无连接的、尽最大努力交付的数据报服务。其中包括:
  • 网络在发送分组时不需要先建立连接。每一个分组(也就是IP数据报)独立发送,与其前后的分组无关(不进行编号)。
  • 网络层不提供服务质量的承诺。也就是说,所传送的分组可能出错、丢失、重复和失序(即不按序到达终点),当然也不保证分组交付的时限。
  • 如果主机(即端系统)中的进程之间的通信需要是可靠的,那么就由网络的主机中的运输层负责(包括差错处理、流量控制等)。
💡
那么网络层与数据链路层有什么关系呢
MAC 的作用则是实现「直连」的两个设备之间通信,而 IP 则负责在「没有直连」的两个网络之间进行通信传输。
notion image
  1. IP 地址写在 IP 数据报的首部,一旦把 IP 数据报交给了数据链路层,就被封装成 MAC 帧了。MAC 帧在传送时使用的源地址和目的地址都是硬件地址,这两个硬件地址都写在 MAC 帧的首部中。换而言之,在数据链路层是看不到数据报的 IP 地址的,只能看到 MAC 帧和 MAC 地址
  1. MAC 帧只负责两个直连设备间的数据传输,当数据包在两台直连的设备上从一端传输到另外一端时,这时候源 MAC 地址就会被赋值当前的目标 MAC 地址(因为数据包已经传输到当前目标 MAC 地址了),而目标MAC地址就会被就会被赋值下一台直连设备的 MAC 地址。所以数据包在两个远程主机间传输的过程中,源 IP 地址和目标 IP 地址在传输过程中是不会变化的,但源 MAC 地址和目标 MAC 地址一直在变化。当然,MAC 帧的首部的这种变化,在上面的 IP 层上也是看不见的。
由此看出,IP 层的这种抽象屏蔽了下层复杂的细节。只要我们在网络层上讨论问题,就能够使用统一的、抽象的 IP 地址研究主机和主机或路由器之间的通信

2、IP地址

IP 地址就是给因特网上的每一个主机(或路由器)的每一个接口分配一个在全世界范围是唯一的32位的标识符
IP 地址(IPv4 地址)由 32 位正整数来表示,IP 地址在计算机是以二进制的方式处理的。为了提高可读性,我们常常把 32 位的 IP 地址中的每 8 位插入一个空格(但在机器中并没有这样的空格)。要更加便于使用,可用其等效的十进制数字表示,并且在这些数字之间加上一个点。这就叫做点分十进制记法(dotted decimal notation)
notion image
IP地址的编址方法共经过了三个历史阶段。
  1. 分类的IP地址。这是最基本的编址方法,在1981年就通过了相应的标准协议。
  1. 子网的划分。这是对最基本的编址方法的改进,其标准RFC 950在1985年通过。
  1. 无分类编址CIDR。这是比较新的无分类编址方法。1993年提出后很快就得到推广应用。

2.1 分类的IP地址

最初设计互联网络时,为了便于寻址以及层次化构造网络,IP地址由 网络号主机号 两部分组成。同一个物理网络上的所有主机都使用同一个网络ID。
notion image
之所以要分为网络号和主机号,是因为两台计算机要通讯,首先要判断是否处于同一个广播域内,即网络地址是否相同。如果网络地址相同,表明接受方在本网络上,那么可以把数据包直接发送到目标主机。路由器寻址工作中,也就是通过这样的方式来找到对应的网络号的,进而把数据包转发给对应的网络内。
IP地址根据 网络号的不同 分为 5 种类型:A类地址B类地址C类地址D类地址E类地址。A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同。
notion image
  • A 类 IP 地址:由 1 字节的网络地址和3 字节主机地址组成,网络地址的最高位必须是 0。前八位取值范围是 [1,126],注意没有包括 0 和 127。减2的原因是:第一,IP地址中的全 0 表示“这个(this)”。网络号字段为全 0 的 IP 地址是个保留地址,意思是“本网络”。第二,网络号为 127(即01111111)保留作为本地软件环回测试(loopback test)本主机的进程之间的通信之用。若主机发送一个目的地址为环回地址(例如127.0.0.1)的 IP 数据报,则本主机中的协议软件就处理数据报中的数据,而不会把数据报发送到任何网络。目的地址为环回地址的 IP 数据报永远不会出现在任何网络上,因为网络号为 127 的地址根本不是一个网络地址。
  • B 类 IP 地址:由 2 字节的网络地址和 2 字节主机地址组成,网络地址的最高位必须是 10。前八位取值范围是 [128,191]
  • C 类 IP 地址:由 3 字节的网络地址和 1 字节主机地址组成,网络地址的最高位必须是 110。前八位取值范围是 [192,223]
  • D 类 IP 地址:不分网络地址和主机地址,网络地址的最高位必须是 1110,用于多播。由于广播无法穿透路由,若想给其他网段发送同样的包,就可以使用可以穿透路由的多播。多播用于将包发送给特定组内的所有主机。
  • E 类 IP 地址:不分网络地址和主机地址,网络地址的最高位必须是 11110,用于保留实验。
各类IP地址对应的相关内容如下:
分类
前缀码
最高位范围
网络地址位数
主机地址位数
主机开始地址
主机结束地址
对应CIDR修饰
网络数
每个网络的主机数
默认子网掩码
A类地址
0
[1,126]
8
24
1.0.0.1
126.255.255.254
/8
126
16,777,214
255.0.0.0
B类地址
10
[128,191]
16
16
128.0.0.1
191.255.255.254
/16
16,384
65,534
255.255.0.0
C类地址
110
[192,223]
24
8
192.0.0.1
223.255.255.254
/24
2,097,152
254
255.255.255.0
D类地址(群播)
1110
[224,239]
未定义
未定义
224.0.0.1
239.255.255.254
/4
未定义
未定义
未定义
E类地址 (保留)
11110
[240,255]
未定义
未定义
240.0.0.1
255.255.255.254
/4
未定义
未定义
未定义
这里要指出,由于近年来已经广泛使用无分类IP地址进行路由选择,A类、B类和C类地址的区分已成为历史[RFC 1812],但由于很多文献和资料都还使用传统的分类 IP 地址,而且从概念的演进上更清晰,因此我们在这里还要从分类 IP 地址讲起。
有一些特殊IP地址,这些地址只能在特定的情况下使用
notion image
  • 专用地址:这些地址只能用于一个机构的内部通信,而不能用于和因特网上的主机通信。换言之,专用地址只能用作本地地址而不能用作全球地址。在因特网中的所有路由器,对目的地址是专用地址的数据报一律不进行转发。
    • A类专用地址:10.0.0.010.255.255.255 (或记为 10.0.0.0/8,它又称为 24 位块)
    • B类专用地址:172.16.0.0172.31.255.255 (或记为 172.16.0.0/12,它又称为 20 位块)
    • C类专用地址:192.168.0.0192.168.255.255 (或记为 192.168.0.0/16,它又称为 16 位块)
  • 本机地址:IP 地址中的全 0 表示“这个(this)”。网络号字段为全 0 的 IP 地址表示本网络。主机号字段全 0 的 IP 地址表示“本主机”的网络地址(例如,一主机的 IP 地址为 5.6.7.8,则该主机所在的网络地址就是 5.0.0.0)。综合上述,0.0.0.0 一般用来表示本机宿主机地址。
  • 回环地址:127 开头的地址,127.0.0.1127.255.255.255 作为网络测试地址,也称为 loop-back 回环地址。环回地址是在同一台计算机上的程序之间进行网络通信时所使用的默认地址。计算机使用一个特殊的 IP 地址 127.0.0.1 作为环回地址,与该地址具有相同意义的是一个叫做 localhost 的主机名。使用这个 IP 或主机名时,数据包不会流向网络。
  • 广播地址:主机号全为 1 的表示该网络上的所有主机,又称为广播地址。用于同一个链路中相互连接的主机之间发送数据包。发向该地址的数据包会广播到网段内的所有设备。
💡
如果计算分类地址最大主机个数?
因为每个网段下的第一个地址(网络地址)和最后一个地址(广播地址)不能用于主机地址分配,所以我们得到关系:
  • 最大可容纳主机地址数 = 2 ^ 主机位数
  • 可用的主机地址数 = 最大可容纳主机地址数 - 2

2.2 划分子网

2.2.1 子网的划分

从实际使用来看,ABC 类 IP 地址的设计确实不够合理。
  • IP 地址空间使用率低:每一个A 类地址网络可连接的主机数超过 1000 万台,而每一个 B 类地址网络可连接的主机数也超过 6 万台。然而有些网络对连接在网络上的计算机数目有限制,根本达不到这样大的数值。例如 10BASE-T 以太网规定其最大结点数只有 1024 个。这样的以太网若使用一个 B 类地址就浪费 6 万多个IP地址,地址空间的利用率还不到 2%。
  • 不能划分出更小的网络:公司还希望在网段内不划分出多个不同的小网络,不同的小网络分给不同的部门使用。但是 ABC 类网络还不具备这样的划分功能。
这位了解决以上问题,IP 地址中又增加了一个子网号字,使两级 IP 地址变成为三级 IP 地址,它能够较好地解决上述问题,并且使用起来也很灵活。这种做法叫作划分子网(subnetting) [RFC 950],或子网寻址或子网路由选择。
划分子网的方法是从网络的主机号借用若干位作为子网号 subnet-id,当然主机号也就相应减少了同样的位数。于是两级IP地址在本单位内部就变为三级IP地址:网络号、子网号和主机号
 
notion image
子网划分实际上是将主机地址分为两个部分:子网网络地址和子网主机地址。
  • 未做子网划分的 ip 地址:网络地址 + 主机地址
  • 做子网划分后的 ip 地址:网络地址 + 子网地址 + 主机地址
图 4-18 表示某单位拥有一个 B 类 IP 地址,网络地址是 145.13.0.0(网络号是 145.13)。凡目的地址为 145.13.x.x 的数据报都被送到这个网络上的路由器 R1。
现把图 4-18 的网络划分为三个子网(图4-19)。这里假定子网号占用 8 位,因此在增加了子网号后,主机号就只有 8 位。所划分的三个子网分别是: 145.13.3.0145.13.7.0145.13.21.0 。在划分子网后,整个网络对外部仍表现为一个网络,其网络地址仍为 145.13.0.0。但网络 145.13.0.0 上的路由器 R1 在收到外来的数据报后,再根据数据报的目的地址把它转发到相应的子网。
 
notion image
总之,当没有划分子网时,IP 地址是两级结构。划分子网后 IP 地址变成了三级结构。划分子网只是把 IP 地址的主机号这部分进行再划分,而不改变 IP 地址原来的网络号。

2.2.2 子网掩码

现在剩下的问题就是:假定有一个数据报(其目的地址是 145.13.3.10 )已经到达了路由器 R1。那么这个路由器如何把它转发到子网 145.13.3.0 呢?我们知道,从 IP 数据报的首部无法看出源主机或目的主机所连接的网络是否进行了子网的划分。这是因为 32 位的IP地址本身以及数据报的首部都没有包含任何有关子网划分的信息。为了确定 IP 地址对应的子网地址,就需要用到子网掩码
子网掩码是连续的 1 和连续的 0 组成的 32 位地址。子网掩码不能单独存在,它必须结合 IP 地址一起使用。例如
notion image
  • 图4-20(a)是IP地址为 145.13.3.10 的主机本来的两级IP地址结构。
  • 图4-20(b)是两级 IP 地址的子网掩码。子网掩码中的 1 对应于 IP 地址的 16 位网络号。
  • 图4-20(c)是同一地址的三级IP地址结构,也就是说,现在从原来 16 位的主机号中拿出 8 位作为子网号,而主机号由 16 位减少到 8 位。
  • 图4-20(d)是三级 IP 地址的子网掩码。子网掩码中的 1 对应于 IP 地址中原来二级地址中的 16 位网络号加上新增加的 8 位子网号,而子网掩码中的 0 对应于现在的8位主机号。
有了子网掩码,我们可以轻松实现下面两个功能:
  • 利用子网掩码计算网络地址。掩码的意思就是掩盖掉主机号,剩余的就是网络号。所以子网掩码的第一个作用是计算出网络地址,将某个 IP 地址划分成网络地址和主机地址两部分。
  • 利用子网掩码划分子网。如果给定网络地址,子网掩码划分出来的网络地址位数比给定的网络地址要多,多出来的几个位就属于子网网络地址,所以子网掩码的另外一个作用是将某个 IP 地址划分成网络地址、子网网络地址和主机地址三部分。
💡
利用子网掩码计算网络地址
将子网掩码和 IP 地址按位与计算 AND,就可得到网络地址。这样就可以知道把 IP 数据发到哪个子网上了。
notion image
💡
已知 IP 地址是141.14.72.24,子网掩码是255.255.192.0。试求网络地址。
子网掩码是 11111111 11111111 1100000000000000。请注意,掩码的前两个字节都是全1 ,因此网络地址的前两个字节可写为 141.14。子网掩码的第四字节是全0 ,因此网络地址的第四字节是 0。可见本题仅需对地址中的第三字节进行计算。我们只要把 IP 地址和子网掩码的第三字节用二进制表示,就可以很容易地得出网络地址(图4-22)。
notion image
💡
利用子网掩码划分子网
假设对 C 类地址进行子网划分,网络地址 192.168.1.0,使用子网掩码 255.255.255.192 对其进行子网划分。C 类地址中前 24 位是网络号,最后 8 位是主机号,子网掩码 255.255.255.192 的前 26 位是 1,后 6 位是 0,表示从 8 位主机号中借用 2 位作为子网号
notion image
由于子网网络地址被划分成 2 位,那么子网地址就有 4 个,分别是 00、01、10、11。所以被划分为四个子网:
  • 192.168.1.00000000 ~ 192.168.1.00111111
  • 192.168.1.01000000 ~ 192.168.1.01111111
  • 192.168.1.10000000 ~ 192.168.1.10111111
  • 192.168.1.11000000 ~ 192.168.1.11111111
notion image
子网数是根据子网号 subnet-id 计算出来的。若 subnet-id 有 n 位,则共有 2 ^ n 种可能的排列。除去全 0 和全 1 这两种情况,以一个 B 类地址为例,下面是所有子网划分的方法。
notion image

2.3 无分类地址 CIDR

A、B、C类有个尴尬处境,就是不能很好的与现实网络匹配。C 类地址能包含的最大主机数量实在太少了,只有 254 个,而 B 类地址能包含的最大主机数量又太多了,一般中小企业用不到 6 万多台主机。所以后面提出了无分类地址的方案,即 CIDR
CIDR 不再有 ABC 类地址的概念,32 位的 IP 地址被划分为两部分,前面是网络号,后面是主机号。因此 CIDR 使IP地址从三级编址(使用子网掩码)又回到了两级编址,但这已是无分类的两级编址
CIDR 地址采用了斜线记法,即在IP地址后面加上斜线 /,然后写上网络前缀所占的位数。 例如 a.b.c.d/x 这种写法。比如 10.100.122.2/24,这种地址表示形式就是 CIDR,/24 表示前 24 位是网络号,剩余的 8 位是主机号。
CIDR 把网络前缀都相同的连续的IP地址组成一个“CIDR地址块”。我们只要知道 CIDR 地址块中的任何一个地址,就可以知道这个地址块的起始地址(即最小地址)和最大地址,以及地址块中的地址数
notion image
虽然CIDR不使用子网了,但由于目前仍有一些网络还使用子网划分和子网掩码,因此 CIDR 使用的地址掩码也可继续称为子网掩码。子网掩码使用 CIDR 表示法表示如下:
  • A类的默认子网掩码:255.0.0.0 或者 /8
  • B类的默认子网掩码:255.255.0.0 或者 /16
  • C类的默认子网掩码:255.255.255.0 或者 /24
💡
最长前缀匹配
在使用CIDR时,由于采用了网络前缀这种记法,IP地址由网络前缀和主机号这两个部分组成,因此在路由表中的项目也要有相应的改变。这时,每个项目由“网络前缀”和“下一跳地址”组成。但是在查找路由表时可能会得到不止一个匹配结果。这样就带来一个问题:我们应当从这些匹配结果中选择哪一条路由呢?
解决方案是:应当从匹配结果中选择具有最长网络前缀的路由。这叫作最长前缀匹配(longest-prefix matching),这是因为网络前缀越长,其地址块就越小,因而路由就越具体(more specific)。
假如我们有两个子网 206.0.68.0/22206.0.71.128/25 ,现在收到一个数据报,其目的 IP 地址为 206.0.71.130 。把这个目标 IP 地址和路由表中这两个子网的子网掩码逐位相“与”(AND操作)。
  • 11111111 11111111 1111110000000000 逐位相“与”= 206.0.68.0/22
  • 11111111 11111111 11111111 10000000 逐位相“与”= 206.0.71.128/25
现在看到两个子网的地址都能匹配到,根据最长前缀匹配的原理,应该选择最长子网掩码匹配的结果,所以应该把数据报发送到 206.0.71.128/25

3、IP数据报格式

一个IP数据报由首部和数据两部分组成。首部的前一部分是固定长度,共20字节,是所有IP数据报必须具有的。在首部的固定部分的后面是一些可选字段,其长度是可变的。
notion image
这里只介绍比较重要的几个字段:
  • 版本:占4位,指 IP 协议的版本。通信双方使用的 IP 协议的版本必须一致。目前广泛使用的 IP 协议版本号为 4 (即IPv4)。关于以后要使用的 IPv6(即版本6的 IP 协议)。
  • 生存时间:占 8 位,生存时间字段常用的英文缩写是 TTL (Time To Live),表明是数据报在网络中的寿命。但这个 TTL 的单位不再是秒,而是跳数。路由器在转发数据报之前就把 TTL 值减1,若 TTL 值减小到零,就丢弃这个数据报,不再转发。因此,TTL 的意义是指明数据报在因特网中至多可经过多少个路由器
  • 协议:占8位,协议字段指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个处理过程。常用的一些协议和相应的协议字段值如下
notion image
  • 源地址:32位。
  • 目的地址:32位。

4、IP协议相关协议和技术

与 IP 协议配套使用的还有三个协议:
  • 地址解析协议 ARP (Address Resolution Protocol)
  • 网际控制报文协议 ICMP (Internet Control Message Protocol)
  • 网际组管理协议 IGMP (Internet Group Management Protocol)
本来还有一个协议叫做逆地址解析协议 RARP (Reverse Address Resolution Protocol),是和 ARP 协议配合使用的。但现在已被淘汰不使用了。
这三个协议和网际协议 IP 的关系。在这一层中,ARP 画在最下面,因为 IP 经常要使用这个协议。ICMP 和 IGMP 画在这一层的上部,因为它们要使用 IP 协议。
notion image

4.1 ARP

在传输一个 IP 数据报的时候,确定了源 IP 地址和目标 IP 地址后,就需要确定 IP 数据包的下一跳 MAC 地址。但是我们主机的「路由表」中只能找到下一跳的 IP 地址,所以我们需要把下一跳的 IP 地址转换成下一跳的 MAC 地址。这就需要用到 ARP 协议ARP 协议的全称是 Address Resolution Protocol(地址解析协议),作用是实现从 IP 地址到 MAC 地址的映射
我们知道,网络层使用的是 IP 地址,但在实际网络的链路上传送数据帧时,最终还是必须使用该网络的硬件地址。但 IP 地址和下面的网络的硬件地址之间由于格式不同而不存在简单的映射关系(例如,IP 地址有 32 位,而局域网的硬件地址是 48 位)。此外,在一个网络上可能经常会有新的主机加入进来,或撤走一些主机。更换网络适配器也会使主机的硬件地址改变。ARP 解决这个问题的方法是在主机 ARP 高速缓存中应存放一个从 IP 地址到硬件地址的映射表,并且这个映射表还经常动态更新(新增或超时删除)。
每个主机和路由器上都有一个 ARP 缓存(或表)。这个缓存维护着每个 IP 到 MAC 地址的映射关系。通过把第一次 ARP 获取到的 MAC 地址作为 IP 对 MAC 的映射关系到一个 ARP 缓存表中,下一次再向这个地址发送数据报时就不再需要重新发送 ARP 请求了,而是直接使用这个缓存表中的 MAC 地址进行数据报的发送。每发送一次 ARP 请求,缓存表中对应的映射关系都会被清除。
notion image
通过 ARP 缓存,降低了网络流量的使用,在一定程度上防止了 ARP 的大量广播。不过 MAC 地址的缓存有一定生存期限,ARP 把保存在高速缓存中的每一个映射地址项目都设置生存时间(例如,10~20分钟)。凡超过生存时间的项目就从高速缓存中删除掉。
ARP 是借助 ARP 请求与 ARP 响应两种类型的包确定 MAC 地址的
  • 主机会通过广播向同一链路的所有主机发送 ARP 请求,这个包中包含了想要知道的 MAC 地址的主机 IP 地址。
notion image
  • 当同一链路中的所有设备收到 ARP 请求时,会去拆开 ARP 请求包里的内容,如果 ARP 请求包中的目标 IP 地址与自己的 IP 地址一致,那么这个设备就将自己的 MAC 地址塞入 ARP 响应包返回给主机。
notion image
如果目标主机不在同一个链路上,那么会查找下一跳路由器的 MAC 地址。
💡
RARP(了解即可)
与 ARP 相对的,RARP(Reverse Address Resolution Protocol) 是将 ARP 反过来,从 MAC 地址定位 IP 地址的一种协议,将打印机服务器等小型嵌入式设备接入网络时会使用到。
通常这需要架设一台 RARP 服务器,在这个服务器上注册设备的 MAC 地址及其 IP 地址。然后再将这个设备接 入到网络,接着:
  • 该设备会发送一条「我的 MAC 地址是XXXX,请告诉我,我的IP地址应该是什么」的请求信息。
  • RARP 服务器接到这个消息后返回「MAC地址为 XXXX 的设备,IP地址为 XXXX」的信息给这个设备。
现在的 DHCP 协议已经包含了 RARP 协议的功能,因此基本已经废弃。

4.2 ICMP

网络包在复杂的网络传输环境里,常常会遇到各种问题。当遇到问题的时候,我们需要获得反馈报告遇到了什么问题,这样才可以调整传输策略,以此来控制整个局面。这就需要 ICMP 协议。
ICMP 全称是 Internet Control Message Protocol,也就是互联网控制报文协议。ICMP 主要的功能包括:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置等。例如在 IP 通信中如果某个 IP 包因为某种原因未能达到目标地址,那么这个具体的原因将由 ICMP 负责通知。
从 ICMP 的报文格式来说,ICMP 是 IP 的上层协议。但是 ICMP 分担了 IP 的一部分功能,一般我们把 ICMP 当作和 IP 协议同层的网络层协议。ICMP 报文被封装成 IP 数据包。在 IP 数据包中如果协议类型字段的值是 1 的话,就表示 IP 数据是 ICMP 报文。IP 数据包就是靠这个协议类型字段来区分不同的数据包的。ICMP 报文和 IP 报文的关系如图所示:
notion image
下面是 ICMP 报文的一种使用场景。主机 A 向主机 B 发送了数据包,由于某种原因,途中的路由器 2 未能发现主机 B 的存在, 这时,路由器 2 就会向主机 A 发送一个 ICMP 目标不可达数据包,说明发往主机 B 的包未能成功。
notion image
 

4.2.1 ICMP的报文种类

ICMP报文的种类有两种:
  • 一类是用于诊断的查询消息,也就是 ICMP 询问报文
  • 另一类是通知出错原因的错误消息,也就是 ICMP 差错报告报文
💡
ICMP 询问报文
回送消息用于进行通信的主机或路由器之间,判断所发送的数据包是否已经成功到达对端的一种消息, ping 命令 就是利用这个消息实现的。
  • 回应请求消息,类型为 0
  • 回应应答消息,类型为 8
notion image
notion image
相比原生的 ICMP,这里多了两个字段:
  • 标识符:用以区分是哪个应用程序发 ICMP 包,比如用进程 PID 作为标识符;
  • 序号:序列号从 0 开始,每发送一次新的回送请求就会加 1,可以用来确认网络包是否有丢失。
在选项数据中, ping 还会存放发送请求的时间值,来计算往返时间,说明路程的⻓短。
💡
ICMP 差错报告报文
常见的差错报文类型有:
  • 目标不可达消息,类型为 3 。IP 路由器无法将 IP 数据包发送给目标地址时,会给发送端主机返回一个目标不可达的 ICMP 消息,并在这个消息中显示不可达的具体原因,原因记录在 ICMP 包头的代码字段。代码类型:
    • 网络不可达代码为 0
    • 主机不可达代码为 1
    • 协议不可达代码为 2
    • 端口不可达代码为 3
    • 需要进行分片但设置了不分片位代码为 4
  • 原点抑制消息,类型为 4 。在使用低速广域线路的情况下,连接 WAN 的路由器可能会遇到网络拥堵的问题。当路由器向低速线路发送数据时,其发送队列的缓存变为零而无法发送出去时,可以向 IP 包的源地址发送一个 ICMP 原点抑制消息。收到这个消息的主机借此了解在整个线路的某一处发生了拥堵的情况,从而增大 IP 包的传输间隔,减少网络拥堵 的情况。然而,由于这种 ICMP 可能会引起不公平的网络通信,一般不被使用。
  • 重定向消息,类型为 5 。如果路由器发现发送端主机使用了「不是最优」的路径发送数据,那么它会返回一个 ICMP 重定向消息给这个主机。在这个消息中包含了最合适的路由信息和源数据。这主要发生在路由器持有更好的路由信息的情况下。路由器会通过这样的 ICMP 消息告知发送端,让它下次发给另外一个路由器。
  • 超时消息,类型为 11 。IP 包中有一个字段叫做 TTL ( Time To Live ,生存周期),它的值随着每经过一次路由器就会减 1,直到减到 0 时该 IP 包会被丢弃。此时,路由器将会发送一个 ICMP 超时消息给发送端主机,并通知该包已被丢弃。设置 IP 包生存周期的主要目的,是为了在路由控制遇到问题发生循环状况时,避免 IP 包无休止地在网络上被转发。

4.2.2 ICMP 询问报文的应用——ping

ICMP 回送请求报文是由主机或路由器向一个特定的目的主机发出的询问。收到此报文的主机必须给源主机或路由器发送 ICMP 回送回答报文。这种询问报文用来测试目的站是否可达以及了解其有关状态。
常用的 ping 命令就是基于 ICMP 协议的查询报文:类型为 8 的回送请求消息和类型为 0 的回送应答消息。
notion image

4.2.3 ICMP 差错报告报文的应用—traceroute

有一款充分利用 ICMP 差错报文类型的应用叫做 traceroute
traceroute 的第一个作用是故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器。它的原理就是利用 IP 包的生存期限 从 1 开始按照顺序递增的同时发送 UDP 包,强制接收 ICMP 超时消息。工作流程:
  1. Traceroute 从源主机向目的主机发送一连串的 IP 数据报,数据报中封装的是无法交付的 UDP 用户数据报。
  1. 第一个数据报 P1 的生存时间 TTL 设置为1。当 P1 到达路径上的第一个路由器 R1 时,路由器 R1 先收下它,接着把 TTL 的值减 1。由于 TTL 等于零了,R1 就把 P1 丢弃了,并向源主机发送一个 ICMP 时间超过差错报告报文。
  1. 源主机接着发送第二个数据报 P2,并把 TTL 设置为 2。P2 先到达路由器 R1,R1 收下后把 TTL 减 1 再转发给路由器 R2。R2 收到 P2 时 TTL 为 1,但减 1 后 TTL 变为零了。R2 就丢弃 P2,并向源主机发送一个 ICMP 时间超过差错报告报文。这样一直继续下去。
  1. 当最后一个数据报刚刚到达目的主机时,数据报的 TTL 是 1 。主机不转发数据报,也不把 TTL 值减 1。但因 IP 数据报中封装的是无法交付的运输层的 UDP 用户数据报,因此目的主机要向源主机发送 ICMP 终点不可达差错报告报文。
  1. 这样主机就收集到了到达目的主机所经过的路由器的 IP 地址,以及到达其中的每一个路由器的往返时间。
traceroute 的第二个作用是故意设置不分片,从而确定路径的 MTU。因为有的时候我们并不知道路由器的 MTU 大小,以太网的数据链路上的 MTU 通常是 1500 字节,但是非以 外网的 MTU 值就不一样了,所以我们要知道 MTU 的大小,从而控制发送的包大小。工作流程:
  1. 首先在发送端主机发送 IP 数据报时,将 IP 包首部的分片禁止标志位设置为 1。根据这个标志位,途中的路由 器不会对大数据包进行分片,而是将包丢弃。
  1. 随后,通过一个 ICMP 的不可达消息将数据链路上 MTU 的值一起给发送主机,不可达消息的类型为「需要进行分 片但设置了不分片位」。
  1. 发送主机端每次收到 ICMP 差错报文时就减少包的大小,以此来定位一个合适的 MTU 值,以便来达到目标主机。
例如在 Linux 和 MacOS 上可以使用 traceroute 命令,在 Windows 上可以使用 tracert 命令,使用如下所示。图中每一行有三个时间出现,是因为对应于每一个 TTL 值,源主机要发送三次同样的 IP 数据报。

4.3 VPN

有时一个很大的机构有许多部门分布在相距很远的一些地点,而在每一个地点都有自己的专用网。假定这些分布在不同地点的专用网需要经常进行通信。这时,可以有两种方法。第一种方法是租用电信公司的通信线路为本机构专用。这种方法的好处是简单方便,但线路的租金太高。第二种方法是利用公用的因特网作为本机构各专用网之间的通信载体,然后对传送的数据进行加密,这样的专用网称为虚拟专用网VPN (Virtual Private Network)
一个机构要构建自己的 VPN 就必须为它的每一个场所购买专门的硬件和软件,并进行配置,使每一个场所的 VPN 系统都知道其他场所的地址。假定某个机构在两个相隔较远的场所建立了专用网 A 和 B,其网络地址分别为专用地址 10.1.0.010.2.0.0。现在这两个场所需要通过公用的因特网构成一个 VPN。VPN 的组成如下图所示:
notion image
  1. 首先,每一个场所至少要有一个路由器具有合法的全球 IP 地址,如图4-52(a)中的路由器 R1 和 R2 和因特网的接口地址必须是合法的全球 IP 地址。R1 的全球 IP 地址为 125.1.2.3 ,R2 的全球 IP 地址为 194.4.5.6。路由器 R1 和 R2 在专用网内部网络的接口地址则是专用网的本地地址。场所 A 的专用网地址为 10.1.0.0 ,场所 B 的专用网地址为 10.2.0.0
  1. 主机 X 向主机 Y 发送的IP数据报的源地址是 10.1.0.1,而目的地址是 10.2.0.3。这个数据报先作为本机构的内部数据报从 X 发送到与因特网连接的路由器 R1。路由器 R1 收到内部数据报后,发现其目的网络必须通过因特网才能到达,就把整个的内部数据报进行加密(这样就保证了内部数据报的安全),然后重新加上数据报的首部,封装成为在因特网上发送的外部数据报,其源地址是路由器 R1 的全球地址 125.1.2.3 ,而目的地址是路由器 R2 的全球地址 194.4.5.6
  1. 路由器 R2 收到数据报后将其数据部分取出进行解密,恢复出原来的内部数据报(目的地址是 10.2.0.3),交付主机 Y。

4.4 DNS

因特网采用了层次树状结构的命名方法,就像全球邮政系统和电话系统那样。采用这种命名方法,任何一个连接在因特网上的主机或路由器,都有一个唯一的层次结构的名字,即域名(domain name)。这里,“域”(domain)是名字空间中一个可被管理的划分。域还可以划分为子域,而子域还可继续划分为子域的子域,这样就形成了顶级域、二级域、三级域。
从语法上讲,每一个域名都是由标号(label)序列组成,而各标号之间用点隔开(请注意,是小数点“.”,不是中文的句号“。”)。例如下面的域名
我们在上网的时候,通常使用的方式是域名,而不是 IP 地址,因为域名方便人类记忆。但我们的 IP 协议里面只能用 IP,所以需要将域名转成具体的 IP 地址,实现这种过程的技术就是 DNS (Domain Name System)
因特网的域名系统 DNS 被设计成为一个联机分布式数据库系统,并采用客户-服务器方式。DNS 使大多数名字都在本地进行解析(resolve)[插图],仅少量解析需要在因特网上通信,因此 DNS 系统的效率很高。由于 DNS 是分布式系统,即使单个计算机出了故障,也不会妨碍整个 DNS 系统的正常运行。
域名到IP地址的解析是由分布在因特网上的许多域名服务器程序(可简称为域名服务器)共同完成的。域名服务器程序在专设的结点上运行,而人们也常把运行域名服务器程序的机器也称为域名服务器。域名服务器也是按照层次安排的。每一个域名服务器都只对域名体系中的一部分进行管辖。根据域名服务器所起的作用,可以把域名服务器划分为以下四种不同的类型:
  • 根域名服务器(root name server):根域名服务器是最高层次的域名服务器,也是最重要的域名服务器。所有的根域名服务器都知道所有的顶级域名服务器的域名和 IP 地址。若要对因特网上任何一个域名进行解析(即转换为IP地址),只要自己无法解析,就首先要求助于根域名服务器。假定所有的根域名服务器都瘫痪了,那么整个的 DNS 系统就无法工作。共有 13 个不同IP地址的根域名服务器,它们的名字是用一个英文字母命名,从 a 一直到 m (前13个字母)。这些根域名服务器相应的域名分别是: a.rootservers.netm.rootservers.net
  • 顶级域名服务器(即TLD 服务器):这些域名服务器负责管理在该顶级域名服务器注册的所有二级域名。当收到DNS查询请求时,就给出相应的回答。常用的 com 就属于顶级域名。
  • 权限域名服务器:这是负责一个区的域名服务器。当一个权限域名服务器还不能给出最后的查询回答时,就会告诉发出查询请求的 DNS 客户,下一步应当找哪一个权限域名服务器。
  • 本地域名服务器(local name server):当一个主机发出DNS查询请求时,这个查询请求报文就发送给本地域名服务器。每一个因特网服务提供者 ISP,或一个大学,甚至一个大学里的系,都可以拥有一个本地域名服务器,这种域名服务器有时也称为默认域名服务器。
notion image
域名到 IP 地址的解析过程如下:
  1. 当某一个应用进程需要把主机名解析为 IP 地址时,该应用进程就调用解析程序(resolver),并成为 DNS 的一个客户,把待解析的域名放在 DNS 请求报文中,以 UDP 用户数据报方式发给本地域名服务器(使用UDP是为了减少开销)。本地域名服务器在查找域名后,把对应的 IP 地址放在回答报文中返回。应用进程获得目的主机的 IP 地址后即可进行通信。
  1. 若本地域名服务器不能回答该请求,则此域名服务器就暂时成为 DNS 中的另一个客户,并向其他域名服务器发出查询请求。这种过程直至找到能够回答该请求的域名服务器为止。
这里要注意两点:
  • 主机向本地域名服务器的查询一般都是采用递归查询(recursive query)。所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器就以 DNS 客户的身份,向其他根域名服务器继续发出查询请求报文(即替该主机继续查询),而不是让该主机自己进行下一步的查询。因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询到所需的 IP 地址。
  • 本地域名服务器向根域名服务器的查询通常是采用迭代查询(iterative query)。迭代查询的特点是这样的:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地域名服务器:“你下一步应当向哪一个域名服务器进行查询”。然后让本地域名服务器进行后续的查询(而不是替本地域名服务器进行后续的查询)。
notion image
假定域名为 m.xyz.com 的主机想知道另一个主机(域名为 y.abc.com)的IP地址。例如,主机 m.xyz.com 打算发送邮件给主机 y.abc.com。这时就必须知道主机 y.abc.com 的IP地址。下面是图6-5(a)的几个查询步骤:
  1. 主机 m.xyz.com 先向其本地域名服务器 dns.xyz.com 进行递归查询。
  1. 本地域名服务器采用迭代查询。它先向一个根域名服务器查询。
  1. 根域名服务器告诉本地域名服务器,下一次应查询的顶级域名服务器 dns.com 的 IP 地址。
  1. 本地域名服务器向顶级域名服务器 dns.com 进行查询。
  1. 顶级域名服务器 dns.com 告诉本地域名服务器,下一次应查询的权限域名服务器 dns.abc.com 的 IP 地址。
  1. 本地域名服务器向权限域名服务器 dns.abc.com 进行查询。
  1. 权限域名服务器 dns.abc.com 告诉本地域名服务器,所查询的主机的 IP 地址。
  1. 本地域名服务器最后把查询结果告诉主机 m.xyz.com

4.5 DHCP

当我们的设备连到局域网上的时候,需要被分配一个 ip 地址,如果每次都手动分配静态地址,难以保证这个 ip 地址不会和局域网内的其他设备冲突,所以我们需要一种动态管理 ip 地址的技术,而且必须要有一个服务器来集中管理,这就是 DHCPDHCP 的作用是在子网内对地址进行统一规划,分配和管理,以及租约,续租的动态管理
上面我们提到 RARP 技术也可以将 MAC 地址转换成 IP 地址,那么 RARP 和 DHCP 的区别是什么?
RARP只能实现简单的从MAC地址到IP地址的查询工作,RARP server上的MAC地址和IP地址是必须事先静态配置好的。但DHCP却可以实现除静态分配外的动态IP地址分配以及IP地址租期管理等等相对复杂的功能。
RARP是在数据链路层实现的,无法穿透子网,DHCP基于UDP协议,在应用层实现的,可以穿透子网。
使用 DHCP 协议需要先搭建一个 DHCP 服务器。我们的服务器通常内置 DHCP 服务器。
notion image
  • 客户端首先发起 DHCP 发现报文(DHCP DISCOVER) 的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的地址,所以使用的是 UDP 广播通信,其使用的广播目的地址是 255.255.255.255(端口 67) 并且使用 0.0.0.0(端口 68) 作为源 IP 地址。DHCP 客户端将该 IP 数据报传递给链路层,链路层然后 将帧广播到所有的网络中设备。
  • DHCP 服务器收到 DHCP 发现报文时,用 DHCP 提供报文(DHCP OFFER) 向客户端做出响应。该报文仍 然使用 IP 广播地址 255.255.255.255,该报文信息携带服务器提供可租约的 IP 地址、子网掩码、默认网关、 DNS 服务器以及 IP 地址租用期。
  • 客户端收到一个或多个服务器的 DHCP 提供报文后,从中选择一个服务器,并向选中的服务器发送 DHCP 请求报文(DHCP REQUEST进行响应,回显配置的参数。
  • 最后,服务端用 DHCP ACK 报文对 DHCP 请求报文进行响应,应答所要求的参数。
一旦客户端收到 DHCP ACK 后,交互便完成了,并且客户端能够在租用期内使用 DHCP 服务器分配的 IP 地址。 如果租约的 DHCP IP 地址快期后,客户端会向服务器发送 DHCP 请求报文:
  • 服务器如果同意继续租用,则用 DHCP ACK 报文进行应答,客户端就会延⻓租期。
  • 服务器如果不同意继续租用,则用 DHCP NACK 报文,客户端就要停止使用租约的 IP 地址。
可以发现,DHCP 交互中,全程都是使用 UDP 广播通信。
💡
DHCP 中继代理
那如果 DHCP 服务器和客户端不是在同一个局域网内,路由器又不会转发广播包,那不是每个网络 都要配一个 DHCP 服务器?
这种情况就需要 DHCP 中继代理。有了 DHCP 中继代理以后,对不同网段的 IP 地址分配也 可以由一个 DHCP 服务器统一进行管理。
notion image
  • DHCP 客户端会向 DHCP 中继代理发送 DHCP 请求包,而 DHCP 中继代理在收到这个广播包以后,再以单播的形式发给 DHCP 服务器。
  • 服务器端收到该包以后再向 DHCP 中继代理返回应答,并由 DHCP 中继代理将此包广播给 DHCP 客户端 。

4.6 NAT

我们的设备在局域网内使用的时候,被分配的地址都是私有 IP 地址。当我们的设备需要和局域网外的其他主机进行通信的时候,需要把私有 IP 地址转换成公有 IP 地址,这就是网络地址转换NAT (Network Address Translation)
notion image
  1. NAT 路由器收到从专用网内部的主机 A 发往因特网上主机 B 的 IP 数据报:源IP地址是 192.168.0.3,而目的IP地址是 213.18.2.4。NAT路由器把 IP 数据报的源 IP 地址 192.168.0.3,转换为新的源 IP 地址(即NAT路由器的全球IP地址) 172.38.1.5,然后转发出去。因此,主机 B 收到这个 IP 数据报时,以为 A 的 IP 地址是 172.38.1.5
  1. 当 B 给 A 发送应答时,IP 数据报的目的 IP 地址是 NAT 路由器的 IP 地址 172.38.1.5。B 并不知道 A 的专用地址 192.168.0.3。实际上,即使知道了,也不能使用,因为因特网上的路由器都不转发目的地址是专用网本地 IP 地址的 IP 数据报。当 NAT 路由器收到因特网上的主机 B 发来的 IP 数据报时,还要进行一次 IP 地址的转换。通过 NAT地址转换表,就可把 IP 数据报上的旧的目的 IP 地址 172.38.1.5,转换为新的目的 IP 地址 192.168.0.3(主机A真正的本地 IP 地址)
如果私有 IP 地址和公有 IP 地址的转换是一对一对应关系,我们现有的 ipv4 地址数量远远不能满足世界上的所有设备。由于绝大多数的网络应用都是使用传输层协议 TCP 或 UDP 来传输数据的,我们可以把私有 IP 地址 + 端口号一起进行转换公有 IP 地址 + 端口号,使用端口号的 NAT 也叫做网络地址与端口号转换 NAPT (Network Address and Port Translation)
notion image
  • 两个客户端 192.168.1.10192.168.1.11 同时与服务器 183.232.231.172 进行通信,并且这两个客户端的本地端口都是 1025。转换之后两个私有 IP 地址都转换 IP 地址为公有地址 120.229.175.121,但是以不同的端口号作为区分。
最后会生成一个 NAPT 路由器的转换表,就可以正确地转换地址跟端口的组合,令客户端 A、B 能同时与服务器之间进行通信。这种转换表在 NAT 路由器上自动生成。例如,在 TCP 的情况下,建立 TCP 连接首次握手时的 SYN 包一经发出,就会生成这个表。而后又随着收到关闭连接时发出 FIN 包的确认应答从表中被删除。
💡
NAT穿透技术
由于 NAT/NAPT 都依赖于自己的转换表,因此会有以下的问题:
  • 外部无法主动与 NAT 内部服务器建立连接,因为 NAPT 转换表没有转换记录。
  • 转换表的生成与转换操作都会产生性能开销。
  • 通信过程中,如果 NAT 路由器重启了,所有的 TCP 连接都将被重置。
这些问题的根源是转换表。如果我们有一种技术让局域网内的设备不依赖转换表就可以把私有地址转换成公有地址,就可以解决这些问题,这就是NAT穿透技术。
在NAT穿透技术下,客户端可以主动发现自己位于 NAT 设备之后,并且会主动获得 NAT 设 备的公有 IP,并为自己建立端口映射条目,然后用这个条目对外通信, 就不需要 NAT 设备来进行转换了。
Elasticsearch系列:入门基础计算机网路系列(三):传输层(TCP和UDP)