子网掩码是如何生效的&子网掩码的作用
整个转发过程只有一条规则:查自己的路由表。主机和路由器做的是同一件事,只是表的行数不同。由此推出掩码是什么、网关是什么、以及「掩码不同能不能通」的全部答案。
写这篇之前,我一直以为子网掩码就是用来划分网段的。但公司内网里见到的情况对不上:两台机器明明属于不同的网络——子网掩码和网关都不一样——却能互相连通。我猜它们接的那台路由器上面还有一层设备,把两个网段接在了一起。这个猜测对不对、掩码在这中间到底起了什么作用,值得弄清楚。
所以这篇文章只做两件事:先构建出一套通用的模型,然后拿它去跑每一种情况。
模型
整个过程只有一条规则
不管是你的电脑、公司的路由器,还是运营商机房里的路由器,拿到一个包之后做的事都一样:
就是这么简单的规则,包每经过一台设备就跑一遍。
主机的路由表
对于一台主机来说,这条规则在一张只有两行的表上跑:
| 目的 | 类型 | 怎么走 | 这一行由谁定 |
|---|---|---|---|
| 192.168.1.0/24 | 直连 | 直接送给对方 | 掩码算出来的 |
| 0.0.0.0/0 | 下一跳 | 交给 192.168.1.1 | 「网关」那一栏配的 |
掩码和网关对于主机的意义,就是维护这样的两行路由表。
路由器的路由表
| 目的 | 类型 | 怎么走 | 这一行由谁定 |
|---|---|---|---|
| 192.168.1.0/24 | 直连 | 从接口①直接送 | 接口①那个地址算出来的 |
| 192.168.2.0/24 | 直连 | 从接口②直接送 | 接口②那个地址算出来的 |
| 0.0.0.0/0 | 下一跳 | 交给运营商 | 上联配的 |
提示
这里的接口是什么?
接口是一个配了 IP 和掩码的三层入口。它背后可能是一个网口,也可能是一堆桥在一起的网口。
| 接口 | 哪些网口 | 网段 |
|---|---|---|
| 家用路由器的 LAN 接口 | LAN1–4 加 WiFi | 192.168.1.0/24 |
| 交换机上 VLAN 10 | 端口 1–8 | 192.168.1.0/24 |
| 交换机上 VLAN 20 | 端口 9–16 | 192.168.2.0/24 |
最长前缀匹配
一个目的 IP 可能同时落进好几行。规矩是前缀越长越优先:/32 胜过 /24,/24 胜过 /0。
| 目的 | 类型 | 怎么走 | 这一行由谁定 |
|---|---|---|---|
| 192.168.2.0/24← 落在这一行 | 直连 | 从接口②直接送 | 前缀 24 位,更具体 |
| 0.0.0.0/0← 不中 | 下一跳 | 交给运营商 | 前缀 0 位,最不具体 |
掩码生效在哪一步
掩码的作用只有一个:生成「直连」那一行。主机和路由器都一样——主机拿自己的 IP 和掩码算出第一行,路由器每个接口各算出一行。
所以主机发包时那次「和掩码做与运算再比较」并不是另一套机制,它就是在判断第一行中不中。下面这对机器为例(也正是后面的第 2 种情况,先把算法本身看清楚):
| 主机 | IP | 掩码 |
|---|---|---|
| A | 192.168.1.10 | /24 |
| B | 192.168.1.200 | /25 |
| 192.168.1.200 | & | /24 | = | 192.168.1.0 |
| A 认为的「B 的网段」 | ||||
| 192.168.1.10 | & | /24 | = | 192.168.1.0 |
| A 自己的网段 | ||||
| 192.168.1.200 | & | /25 | = | 192.168.1.128 |
| B 自己的网段 | ||||
| 192.168.1.10 | & | /25 | = | 192.168.1.0 |
| B 认为的「A 的网段」 | ||||
掩码是每台主机自己私有的一个参数,只在自己计算的时候使用。IP 包头里根本没有掩码这个字段,所以对方的掩码是多少,你无从知晓。
拿模型跑各种情况
1、掩码不同,但两边都认对方在本段
各自算各自的第一行,看对方在不在里面:
两者可以互相直连。
2、只有一方认
把 B 的地址换到轴的右半边,掩码不动:
于是两趟落在了不同的行上:
提示
为什么这里的网关是 .129 而不是 .1?
因为网关自己也得先送得到。B 的第一行是 192.168.1.128/25,192.168.1.1 不在里面——它既不命中第一行,又正是第二行要交出去的那个对象,等于自己指着自己。所以下一跳必须落在自己的直连段里,配成 .1 的话系统会直接拒绝这条路由。
3、网段不一样
这次两趟的第一行都不中:
要让两趟都走通,需要有一台设备在这两段里各有一个接口——它表里因此有两行直连,两个方向都直接命中:
所以让两个网段互通,解法只有两个:把地址改到同一个网段,或者放一台在两段里各有一个接口的设备(家用路由器、三层交换机都算)。
广播问题
掩码把 32 位切成两截:为 1 的那些位是网络位,剩下的是主机位。主机位全 0 的那个地址是这一段的网络地址,全 1 的那个是这一段的广播地址。
| IP | 192.168.1.10 | 11000000101010000000000100001010 |
| 掩码 | 255.255.255.0 | 11111111111111111111111100000000 |
| 网络地址主机位全 0 | 192.168.1.0 | 11000000101010000000000100000000 |
| 广播地址主机位全 1 | 192.168.1.255 | 11000000101010000000000111111111 |
这两个地址把可以分配给主机的范围夹在中间,而它们自己都不能分配给任何主机。
广播包一样要查表、一样命中第一行,区别只在命中之后:它不是送给某一台机器,而是在二层上喊给一整段,意思是「本段里所有人都收下」。可「本段」有多大,恰恰是第一行圈出来的,于是掩码不一致时两边圈出的人群就不是同一批:
这会导致一类特别难查的故障:两台机器互相点对点访问明明是通的(那是第一行命中的功劳),但凡是依赖广播做发现的东西全部失灵——局域网里的设备发现、某些打印机和 NAS 的自动搜索、老式的网上邻居、部分游戏的联机列表,都会莫名其妙看不到对方。
提示
DHCP 不受这个影响。它用的是 255.255.255.255 这个受限广播地址,不经过掩码计算,所以掩码配错的机器照样能拿到地址——而且拿到的往往就是正确的掩码,故障因此自愈了。这也是为什么这类问题几乎只出现在手工配置静态 IP 的机器上。
评论
评论加载中……