如果您netstat -rn
在 Mac 上运行(我使用的是 Mojave 10.14.6,但我怀疑这适用于所有 MacOS),您会得到 IP 路由表,但其中一些 IP 地址不完整,并且网络掩码列不存在:
$ netstat -rn
Routing tables
Internet:
Destination Gateway Flags Refs Use Netif Expire
default 192.168.1.1 UGSc 192 0 en0
127 127.0.0.1 UCS 0 0 lo0
127.0.0.1 127.0.0.1 UH 1 248 lo0
169.254 link#5 UCS 1 0 en0 !
192.168.1 link#5 UCS 1 0 en0 !
192.168.1.1/32 link#5 UCS 1 0 en0 !
192.168.1.1 xx:xx:xx:xx:xx:xx UHLWIir 68 1450 en0 1144
192.168.1.101 yy:yy:yy:yy:yy:yy UHLWI 0 0 en0 1073
192.168.1.103/32 link#5 UCS 0 0 en0 !
224.0.0/4 link#5 UmCS 2 0 en0 !
224.0.0.251 z:z:zz:zz:z:zz UHmLWI 0 0 en0
239.255.255.250 1:1:11:11:11:11 UHmLWI 0 540 en0
255.255.255.255/32 link#5 UCS 0 0 en0 !
我应该如何解释不完整的 IP 地址?例如,是什么127
?我应该将其解释为吗127.0.0.0
?这始终是规则吗 - 假设缺失的八位字节为 0,并且 Mac 路由表中显示的八位字节是最重要的八位字节(即是127
而127.0.0.0
不是0.0.0.127
)?
此外,在 Windows ( route print
) 和 Linux ( route -n
) 上有一个 netmask/genmask 列。但由于 Mac 上没有这样的列,我猜它被替换为 Destination 列中的 CIDR 表示法(例如,192.168.1.1/32
而不是192.168.1.1
掩码255.255.255.255
)。但并非所有路由都在 Destination 列中具有 CIDR 表示法 - 例如239.255.255.250
在上表中。当目标列中的 IP 地址省略斜线和后面的掩码时,我们是否可以假设掩码始终为0.0.0.0
?
答案1
该 macOS版本netstat
(可能还有其他 BSD 衍生的 unix?)使用了一种有点特殊的地址和网络掩码简写。正如您所推断的那样,它在列中使用 CIDR 表示法,destination
而不是单独的网络掩码列。但它使用了几个基于 CIDR 之前的缩写“分类”寻址系统(感谢@grawity 指出这一点并让我看看源代码以确认这一点)。
简要总结:在旧的分类系统中,第一个八位字节为0
- 127
(0 和 127 为保留位)的地址为“A 类”网络,网络掩码为255.0.0.0
(我们现在称之为/8
)。128.x
-191.x
为“B 类”网络,网络掩码为255.255.0.0
(/16
)。192.x.x
-223.x.x
为“C 类”网络,网络掩码为255.255.255.0
(/24
)。其余地址空间为“D 类”(用于多播)和“E 类”(保留),网络掩码未定义。该系统不灵活且效率低下,因此在 1993 年被无类域间路由 (CIDR) 取代(!),但它的痕迹仍然存在于各个地方,包括这里。
基本上,它netstat
所做的就是忽略与分类系统下预期相匹配的内容(因此可以从该系统推断出来)。好吧,除了它将 D 类和 E 类视为具有与 C 类相同的隐式网络掩码(即/24
)。
- 如果地址以
0
八位字节结尾,而旧系统下的主机部分位于其中,则它会省略这些字节。例如,10/24
是 的缩写10.0.0.0/24
。但177.0.0.0/24
只能缩写为177.0/24
,因为那将是 B 类网络,因此第二个八位字节被认为是重要的。 - 如果网络掩码与旧系统下的网络掩码匹配,或者如果它是“主机”路由条目,则省略 CIDR 后缀。例如,
169.254
是缩写,169.254.0.0/16
因为169
属于 B 类范围。
这有点复杂,但将其转换回完整列表很容易:如果它没有列出 CIDR 后缀,则它只是明确列出的八位字节数的 8 倍(或主机条目的 /32);如果没有列出 4 个八位字节,则根据需要在地址部分添加“.0”。例如,169.254
-> 169.254/16
-> 169.254.0.0/16
。