您还未登录! 登录 | 注册 | 帮助  

您的位置: 首页 > 软件开发专栏 > 网络/安全 > 正文

只有 32 位的 IPv4,为何依然够用?

发表于:2019-02-13 作者:张旸 来源:51cto

一、前言

我一直在强调,打好基础怎么变都不慌,但是一直也没有重点分享过这些基础技术。正好 2019 年了,决定再挖个大的新坑,准备开始写一些那些多年不变的基础技术,算法、数据结构、网络协议、设计模式、操作系统有时间都会写。先挖坑,挖完慢慢填,我尽量写的有趣一些,希望大家能够看下去。

今天就来讲讲网络协议中的 CIDR(无类型域间选路),先来说说 CIDR 的背景。

二、CIDR 的背景

2.1 IPv4 和 IPv6

现存所有的网络设备硬件中,网卡是设备上网必备的硬件条件,网卡虽然有唯一(相对唯一)的 Mac 地址去标识,但是依然需要分配一个 IP 地址。有了 IP 地址,才能让世界知道你的位置。

简单来说,IP 地址是一个网卡在网络世界的通讯地址,这就相当于现实世界中,我们在网购时填的收货地址。可以帮助别人,从世界的任何位置,找到我们。

现存的 IP 协议有两套,就是我们常说的 IPv4 和 IPv6。IPv4 由于最初设计的"缺陷",长度只有 32 位,大约只能提供 40 亿个地址。早期设计时,可能也想不到互联网会发展到现在这个地步,随便一个设备都需要联网。

这就造成了 IPv4 地址很快就不够用了,尤其是这样 32 位地址中,还被分为了 A、B、C、D、E 这五类地址,抛开一些特殊的 IP 地址,可供使用的就更少了。由此可见 IPv4 在当初设计时,是有多么奢侈。

随后 IPv6 就被设计出来。我们知道当容量不够的时候,扩容是一条短期正确,但是长期来看依然是存在隐患的事情,无论扩大到多少,如果没有合理的规划,用完其实也是迟早的事情。

IPv6 的长度增加到 128 位,可以提供更多的地址,但是 IPv4 和 IPv6 相互之间并不兼容,导致迁移困难。如今 IPv6 已经慢慢在被一些大厂所使用,例如在淘宝 App 的启动页底部,就可以看到 IPv6 的标识。即便如此,在未来很长的一段时间内,依然会保持两个协议并行支持。

IPv6 并不是本文的重点,再说回到 IPv4 的地址过少这个硬伤上。虽然地址确实不够用,但是设备需要联网确实是强需求,这也是必须要解决的问题,联网就需要 IP 地址,是不是感觉进入死循环了。

IPv4 这种 A、B、C 类为主要的分类的 IP 数量,到底少到什么地步呢?这里看一张表就知道了。

能够感受到 IPv4 的尴尬了吗?C 类地址能够包含的最大主机数量,是在太少了,现在随便一个网吧可能就不够用了,而 B 类地址包含的最大主机数量又太多了,大量用不到的地址,很容易造成地址的浪费。有句老话怎么说的,旱的旱死,涝的涝死。

于是就出现了一个折中的方案,那就是我们本文要聊的 CIDR,中文名为无类型域间选路。

2.2 子网的划分

现在还不到说 CIDR 的时候(就是不爱写这种基础技术,想写清楚会发现有太多需要前置交代)。在说 CIDR 之前,还有个背景需要交代,那就是子网。

互联网这个大网,中间被分割成一个个子网,而子网下又被进一步分割。

从我们上面的 IP 分类图中,可以看出,一个 IP 地址的 32 位中,还被分为两类,分别是网络号和主机号,将主机号都置为 0,得到的就是网络地址。

可以看出,这样很明显的两级划分,也被称为两级 IP 地址。而 IP 地址的利用率有时很低,这种两级划分的方式就显得不那么灵活,于是就出现了子网。

子网其实就在之前的两级 IP 地址中,又加了一层子网号,将其变成三级结构。虽然增加了子网号,但是 IP 地址的长度依然是 32 位,网络号肯定是无法变更的,所以这里的子网就只能从主机号想办法。此时的子网号,其实就是从主机号中借位,这样就等于是减少了主机数,将其分割到不同的子网中。

涉及到子网,还有一个重要的概念,就是子网掩码。子网掩码,就是为了区分识别对 IP 地址划分的子网的。子网掩码很简单,它就是将网络号和子网号,对应的位全部置为 1,将主机号对应的位都置为 0,这就是子网掩码了。

这三个信息中,只要知道 IP 地址和子网掩码,自然就可以推算出对应的网络地址。这也正是我们前面说的子网的概念,其实是将一个大的网络,在其内部分割成一个个小的子网,但是在网 络的外层来看,还是一个大的网络,他们都是通过网络地址来通信的。

例子一:

例子二:

从上面的两个例子中,可以看出,相同的 IP 地址,不同的子网掩码,可以得出相同的网络地址,但是他们却是被划分在不同的子网当中的。

三、无类型域间选路(CIDR)

3.1 什么是 CIDR

通过子网掩码去划分的子网,是借走的主机号,这是有损耗的。例如借走两位主机号,原则上可以划分四个子网(11、10、01、00),但是其中全 0 和全 1 是不使用的,所以就只剩下两个了。使用 CIDR 是没有这个问题的,它可以使用全 0 和全 1,不会造成浪费。

终于可以说到 CIDR 了。

CIDR 中文全称是无分类域间路由,是英文 Classless Inter-Domain Routing 的缩写。CIDR 打破了原先设计的 A、B、C 类地址的概念,将 32 位 IP 地址保持两分的结构,就是依然保持前面是网络号,后面是主机号。

这样如何区分呢?CIDR 会在 IP 地址的后面,用斜线分割一个网络前缀占位数的标识。

例如:10.100.120.2/24,斜线后面有一个数字 24,这种地址的表示形式,就是 CIDR。这里的 24 表示,32 位的 IP 地址中,前 24 位是网络号,后 8 位是主机号。

这一组 CIDR,包含的信息可就多了,还是拿 10.100.120.2/24 来举例。

将主机号,所有的位都置为 1,就是广播地址,例如:10.100.120.255,如果发送这个地址,10.100.120 网络里面的机器都可以收到。

将 24 位网络号都置为 1,8 位主机号置为 0,得到的就是子网掩码,255.255.255.0。

CIDR 除了表示一个 IP 地址,还相当于给出了一个 CIDR 子网的地址范围。将主机号,从全 0 到全 1 的范围,就是当前子网的所能包含的最大地址数。

3.2 容易算错的 CIDR

再来回忆一下 IP 地址的格式,32 位中以 8 位为一个单位,用 . 进行分割。所以比较常见的 /24、/16 这种就比较容易区分,不需要将十进制转换成二进制,就可以明显看出来,那些是网路号,那些是主机号,

家庭 WiFi 中,一般不会超过 256 个设备,所以 /24 也就够用了,例如 192.168.1.117/24。

如果遇上不是 8 的整数倍 CIDR,有时候我们就容易算错。

我们来看一下 16.158.165.20/22 这个 CIDR,求一下这个网络的起始 IP 地址、子网掩码和广播地址。

你要是上来就写 16.158.165.1、255.255.255.0、16.158.165.255,那你就错了。

首先看到 /22 不是 8 的整数倍,肉眼不好区分,我们转成二进制就清晰了。

遇到不好算的 CIDR,换成二进制再看看,一切都清晰了。

3.3 CIDR 应用

前面说到,互联网就是被切分成一个个子网下存在的,一个个子网往下还可以继续切分,但是对外就是一个整体。所以 CIDR 这种方式,/x 这个数值越小,说明当前子网下的主机数量越多。反之可以通过增加 /x 来继续进行子网的划分。

例如从 /16 变为 /20,右移了四位,等于又切分出来 16 个子网。

举个例子,有一个 CIDR 地址块,201.0.68.0/22,然后我们可以怎么切分?拆分成二进制就清晰了。

要是有心,我们还可以继续往下切分,但是正常我们为了保证子网可用,一般也会保持一个子网下的主机数不会太少。

四、小结时刻

CIDR 这种分割子网的规则,其实设计的很巧妙,只要向右移位网络前缀所占的位数,就可以继续分割子网。就算以后全面升级了 IPv6 后,我个人认为应该也不会抛弃 CIDR 这种方式。

CIDR 这种分割子网的计算方法,你明白了吗?留一道思考题吧,已知 16.158.165.20/20 这个 CIDR,计算子网掩码、网络地址、广播地址吗?