📚 第四章 IP协议
📄 一句话概括

掩码是「网络位全 1、主机位全 0」的一个 32 位数,它不是地址,是一把尺子。 有了掩码,分界线就不用再由「类别」决定——这是子网划分的全部内容。

📝 本节和前面几节的关系

4.3.2 说「分界线靠类别」,这一节说「分界线可以自己划」。 它是 CIDR 和 VLSM 的基础,也是所有内网规划的起点。

一、掩码是一把尺子

几个常用前缀的掩码:

前缀 掩码 块大小 可用主机
/24 255.255.255.0 256 254
/26 255.255.255.192 64 62
/28 255.255.255.240 16 14
/30 255.255.255.252 4 2

掩码的「1」的个数就是前缀长度: /26 意味着前 26 位是 1,写成十进制就是 255.255.255.192(因为 192 是 11000000)。 所以「掩码」和「前缀长度」是同一个东西的两种写法。 第三列的「块大小」是心算的关键:/26 是 64 一格,/28 是 16 一格, 所以「152 落在哪一格」只要除一下就知道。这比按位与快,而且不容易错。

二、用块大小心算

算 192.168.3.152/26 的网络地址,只要三步:

块大小 = 256 / 2^(26-24) = 64
152 / 64 = 2 余 24   -> 落在第 2 块(从 0 数)
网络地址 = 192.168.3.(2*64) = 192.168.3.128
广播地址 = 192.168.3.(128+64-1) = 192.168.3.191

这四行把「子网划分」的心算讲完了:块大小、取整、加偏移、减一。 其中「取整」这一步用的是整除,不是四舍五入—— 所以 152 除 64 得 2(不是 2.4 舍成 2),而 191 除 64 得 2,也在同一块里。 这套算法对任何前缀都成立:块大小等于 2 的主机位数次方, 所以 /24 是 256、/25 是 128、/27 是 32、/30 是 4。 记住这几个数,内网规划时基本不用计算器。 有一个坑要说清:「块大小」是从「最后一个掩码非 255 的那一段」算起的。 比如 /20 的掩码是 255.255.240.0,它的块大小是 16,但作用在第三段,不是第四段—— 所以「192.168.5.0/20」这种写法本身就是错的(它不对齐)。

三、/31 和 /32 两个例外

这两个前缀不符合「减 2」的习惯:

前缀 地址数 传统算法 实际用法
/31 2 0 RFC 3021 点对点
/32 1 0 单主机路由

第一行是「两个地址、两端各一个」:点对点链路没有「本网段广播」这个概念(只有两家), 所以不需要预留网络地址和广播地址。 这样「一段 /30 只用掉 2 个可用」就变成「/31 用掉 2 个」,对运营商来说省了一半地址。 第二行是「一个地址、就是它自己」:它最常见的用途是「路由表里给某个 IP 单独指一条路」, 也就是 4.2.2 讲的「最具体的那条前缀」。 所以「/32 主机路由」这个词在运维里天天出现——它不表示「一个网段」,表示「一台机器」。 最后说清「掩码必须连续」这件事: 合法的掩码只有「前面全是 1、后面全是 0」这 33 种(0 到 32 位)。 「255.0.255.0」这种是非法掩码, 因为它中间有 0 又有 1,设备一般会拒绝配置,或者报「掩码不连续」。

四、动手 Demo:子网掩码就是把「分界线」写出来

把九个前缀的掩码、地址数、可用主机列出来,再用块大小心算一次。 注意最后两行:/31 和 /32 不按「减 2」算。

import ipaddress
for p in (24, 26, 28, 30, 31, 32):
    n = 2 ** (32 - p)
    mask = ipaddress.ip_network('0.0.0.0/%d' % p).netmask
    print('/%-2d %-16s 地址 %3d  可用 %s'
          % (p, mask, n, n - 2 if p < 31 else '见 RFC 3021'))

实跑输出:

--------------------------------------------------------------------
子网掩码就是把「分界线」写出来
--------------------------------------------------------------------
**掩码是「网络位全 1、主机位全 0」的一个 32 位数。**
**所以掩码不是「另一个地址」,它是「一把尺子」。**

  前缀     掩码                地址数     可用主机
  ------------------------------------------------------
  /24      255.255.255.0       256        254
  /25      255.255.255.128     128        126
  /26      255.255.255.192     64         62
  /27      255.255.255.224     32         30
  /28      255.255.255.240     16         14
  /29      255.255.255.248     8          6
  /30      255.255.255.252     4          2
  /31      255.255.255.254     2          2(RFC 3021)
  /32      255.255.255.255     1          1(单主机)

**最后两行要特别注意**:
**/31 只有 2 个地址,传统算法「减 2」之后是 0**——**因为它没有可分的网络地址和广播地址。**
**但 RFC 3021 把它救活了**:点对点链路两端各用一个,不要广播,正好两个。
**/32 只有 1 个地址,平时不给主机用**,
**它的典型用途是「给某一个 IP 单独指一条路由」**——**也就是路由表里那条最具体的 /32。**

**算一下掩码是怎么「切」地址的**:
**192.168.3.152/26** 的网络地址是 **192.168.3.128**,主机部分是 **24**
**验算:152 除以 64 得 2 余 24**,**所以它落在「64 的倍数」里第 2 段(128 到 191)**,
**网络地址 192.168.3.128、广播地址 192.168.3.191。**
**这套「除以块大小再取整」的心算法,比按位与快得多。**

ipaddress 的 netmask 属性给的是「点分十进制掩码」, 而 prefixlen 给的是「/26」这种长度。 两者互换很方便: ip_network('0.0.0.0/26').netmask 和ip_network('255.255.255.192/26').prefixlen 说的是同一件事。 「/26 是 64 一格」这个换算值得背下来: /25 是 128、/26 是 64、/27 是 32、/28 是 16、/29 是 8、/30 是 4。 这六个数覆盖了绝大多数内网规划场景。 最后一个实用提醒:配 IP 时「地址」和「掩码」必须一起给, 因为「192.168.3.152」这个数本身不包含「网络有几位」的信息。 所以「只给 IP 不给掩码」在技术上是不完整的—— 很多系统会默认填一个「类别掩码」,那就容易出错了。

30 秒实验

  1. 算一下:192.168.3.200/27 的网络地址和广播地址分别是什么?
  2. 想一下:为什么「255.0.255.0」这种掩码不合法?
  3. 想一下:/31 为什么能省地址?

常见误区

  1. 以为「掩码是另一个 IP 地址」。 它是「尺子」,标记网络位到哪一位为止。
  2. 以为「配 IP 不用给掩码」。 必须一起给,否则不知道网络有几位。
  3. 以为「所有掩码都能用」。 只有「连续的前缀」合法,中间夹 0 的不行。
自测三问(点开对答案) 1. /26 的掩码和块大小是多少? —— **255.255.255.192,块大小 64**,可用主机 62 台。 2. 192.168.3.152/26 的网络地址怎么算? —— **152 除 64 取整得 2,所以网络地址是 192.168.3.128**,广播是 .191。 3. /32 有什么用? —— **给单个 IP 指一条路由**,也就是「最具体的那条前缀」。

下一节看 CIDR 和 VLSM:一个往外并、一个往里切。

相关笔记