/22、/26、255.255.252.0、通配符 0.0.3.255……子网划分的各种写法到底怎么互相换算?怎么给几个部门分配地址才不重叠?什么时候能聚合路由?这篇用代码把规则算一遍,再对照本机真实的路由表。
10.1.2.200/8 掩码 255.0.0.0 通配符 0.255.255.255 网络号 10.0.0.0 广播 10.255.255.255 可用主机 16777214 范围 10.0.0.1 ~ 10.255.255.254 10.1.2.200/16 掩码 255.255.0.0 通配符 0.0.255.255 网络号 10.1.0.0 广播 10.1.255.255 可用主机 65534 范围 10.1.0.1 ~ 10.1.255.254 10.1.2.200/22 掩码 255.255.252.0 通配符 0.0.3.255 网络号 10.1.0.0 广播 10.1.3.255 可用主机 1022 范围 10.1.0.1 ~ 10.1.3.254 10.1.2.200/24 掩码 255.255.255.0 通配符 0.0.0.255 网络号 10.1.2.0 广播 10.1.2.255 可用主机 254 范围 10.1.2.1 ~ 10.1.2.254 172.16.5.9/20 掩码 255.255.240.0 通配符 0.0.15.255 网络号 172.16.0.0 广播 172.16.15.255 可用主机 4094 范围 172.16.0.1 ~ 172.16.15.254 192.0.2.77/26 掩码 255.255.255.192 通配符 0.0.0.63 网络号 192.0.2.64 广播 192.0.2.127 可用主机 62 范围 192.0.2.65 ~ 192.0.2.126 192.0.2.77/28 掩码 255.255.255.240 通配符 0.0.0.15 网络号 192.0.2.64 广播 192.0.2.79 可用主机 14 范围 192.0.2.65 ~ 192.0.2.78 192.0.2.77/30 掩码 255.255.255.252 通配符 0.0.0.3 网络号 192.0.2.76 广播 192.0.2.79 可用主机 2 范围 192.0.2.77 ~ 192.0.2.78 规律:前缀每加 1 位,地址数减半;可用主机数 = 2^(32−前缀) − 2
前缀长度 n、点分掩码和通配符(掩码取反)是同一件事的三种写法;网络号 = 地址 AND 掩码,广播 = 网络号 OR 通配符。
192.0.2.4/30: 共 4 个地址,地址列表 ['192.0.2.4', '192.0.2.5', '192.0.2.6', '192.0.2.7'] 192.0.2.4/31: 共 2 个地址,地址列表 ['192.0.2.4', '192.0.2.5'] 192.0.2.4/32: 共 1 个地址,地址列表 ['192.0.2.4'] ipaddress 的 hosts() 在 /31 上返回两个地址,在 /32 上返回一个,与 RFC 3021 / 主机路由的约定一致:[2, 2, 1]
/31 没有网络号和广播,用于点对点链路;/32 是单个主机。
部门 A:需要 60 台 → 10.0.0.0/26 (可用 62 台,浪费 2 个) 部门 B:需要 28 台 → 10.0.0.64/27 (可用 30 台,浪费 2 个) 部门 C:需要 12 台 → 10.0.0.96/28 (可用 14 台,浪费 2 个) 部门 D:需要 2 台 → 10.0.0.112/30 (可用 2 台,浪费 0 个) 四个子网互不重叠: True;用掉 116 个地址,/24 里还剩 140 个
VLSM 要按大小从大到小分配,起点必须对齐到自己的大小,这样才不会重叠和碎片化。
10.8.0.0/24 ~ 10.8.7.0/24 合并 → [IPv4Network('10.8.0.0/21')]
10.8.1.0/24 ~ 10.8.4.0/24(从 1 开始,没有对齐到 4 的倍数)→ [IPv4Network('10.8.1.0/24'), IPv4Network('10.8.2.0/23'), IPv4Network('10.8.4.0/24')]
10.8.0.0/24, .1, .2, .4(缺 .3)→ [IPv4Network('10.8.0.0/23'), IPv4Network('10.8.2.0/24'), IPv4Network('10.8.4.0/24')]
聚合要求:个数是 2 的幂、起点按这个大小对齐(/21 的起点必须是 8 的倍数),否则只能合并一部分相邻子网要个数是 2 的幂、起点对齐才能合并成一条。
100 万个 172.16.0.0/16 里的随机地址,落在 172.16.0.0/20 内的有 62318 个(位运算算出 62318 个,一致) ipaddress.ip_address() in network: 254 ms;整数 (ip & mask) == network: 36 ms,快 7 倍——路由器做最长前缀匹配就是在做这个运算
(ip AND mask) == network 是一切路由与访问控制的基础,用整数比用对象快一个数量级。
路由表共 198 条目的地;前缀长度分布: /0×1, /4×1, /22×1, /32×195 default <本机局域网IP> UGScg en0 127 127.0.0.1 UCS lo0 169.254 link#14 UCS en0 ! <本机局域网IP>/22 link#14 UCS en0 ! 224.0.0/4 link#14 UmCS en0 ! 255.255.255.255/32 link#14 UCS en0 ! 另有 33 条 169.254.x.x 的主机路由(同网段邻居的 ARP 条目,标志 UHLSW,不逐条列出) netstat 把目的地的尾部 0 省略写(127 = 127.0.0.0/8,169.254 = 169.254.0.0/16),/N 给出前缀长度;default 就是 0.0.0.0/0
netstat 里目的地末尾的 0 被省略:127 就是 127.0.0.0/8,default 就是 0.0.0.0/0。