我看到了问题,路由表有:
192.168.1.1/32 link#4 UCS 2 0 en0
openwrt.lan 46:94:fc:63:fc:7 UHLWIir 11 3610 en0 1200
192.168.1.125/32 link#4 UCS 2 0 en0
子网掩码为 是什么意思/32
?在这种情况下,它的网络 ID 是什么?如果我们将上述内容视为单个主机,主机是否可以在没有网络 ID 的情况下存在?
据我所知,分配给该网络中主机的网络 ID 和 IP 地址是两个不同的东西。192.168.0.0 是网络 ID,如果其子网为 255.255.255.0,则此网络中的主机可以是 192.168.0.1 - 192.168.0.254。在这种情况下,主机如何在没有网络 ID 的情况下存在?
答案1
这里有点令人困惑;/32 不是指任何(子)网络的大小,而是指特定路由表条目适用的地址范围。通常两者是相同的(因为您将网络或子网作为一个单元进行路由,对吧?),但 macOS 对同一本地网络上的其他主机的做法略有不同。让我在您引用的行之前添加几行:
Destination Gateway Flags Refs Use Netif Expire
default openwrt.lan UGSc 10 0 en0
...
192.168.1 link#4 UCS 2 0 en0
192.168.1.1/32 link#4 UCS 2 0 en0
openwrt.lan 46:94:fc:63:fc:7 UHLWIir 11 3610 en0 1200
192.168.1.125/32 link#4 UCS 2 0 en0
请注意,192.168.1(192.168.1.0/24 的缩写)通过 en0(又名 link#4)路由;不通过任何网关,只通过接口本身。这是 Mac 本身所在的网络。192.168.1.1 和 192.168.1.125 都是特定地址在该网络范围内如果将这些 /32 条目与 192.168.1 条目进行比较,它们基本上是冗余的重复项;它们说的是同一件事,只是关于特定的地址而不是整个网络范围。
我不知道 macOS 为什么要创建这些冗余的地址特定条目,但这可能与您在上面的列表中看到的另一件事有关:macOS 在路由表中列出了其 ARP 表条目。上面的“openwrt.lan”条目(我很确定它实际上是 192.168.1.1,只是按名称而不是数字列出)表示它通过 en0 路由到 MAC 地址 46:94:fc:63:fc:7。
因此,您在路由列表中看到的是实际网络路由(如“默认”和 192.168.1 条目)和每个主机条目(/32 和 MAC 目标条目)的混合。
答案2
/32
寻址
一般来说,/32
这意味着网络只有一个 IPv4 地址,所有流量将直接在具有该 IPv4 地址的设备和默认网关之间传输。该设备将无法与本地子网上的其他设备通信。
我发现有几个可能的原因。可能是:
- 为多个站点提供服务的 Web 服务器,每个站点绑定到特定的 IPv4 地址
- A环回地址用于测试。
- 网络安全花招:将具有 /32 网络掩码的计算机与子网上的其他系统隔离。这仅允许流量流向系统上由静态路由明确定义的目的地。例如,这可用于停用系统。
网络 ID
这网络标识IP 地址的一部分由子网掩码决定。例如:
- IPv4
/24
网络的子网掩码为1111.1111.1111.0000
,这意味着前 3 个八位字节是网络 ID,最后一个八位字节用于分配主机 ID(256 个可用 ID,但通常会保留一些)。 - IPv4
/16
网络的子网掩码为1111.1111.0000.0000
,这意味着前 2 个八位字节是网络 ID,最后一个八位字节用于分配主机 ID(65536 个可用 ID,但通常会保留一些)。
在 的情况下/32
,这不适用,因为地址既是网络 ID 又是主机 ID。/31
地址也都是没有保留的第 0 个地址的主机 ID。
答案3
答案4
你看到的不是子网掩码。它们指示路由表¹前缀的长度。
路由表的一个简单实现将列出所有可能的 IP 地址,以便给定任何 IP 地址,您都可以查找该精确的 IP 地址并返回与其关联的路由信息²。
显然需要某种压缩。路由信息的本质是相邻地址可能使用相同的信息,因此我们可以使用一种形式基数树将它们压缩在一起。下面简要介绍一下它的工作原理。
给定数字 0-7,我们可以用二进制表示它们,如下所示:
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111
现在,如果我们有两个路由表条目,一个用于地址 0 和 1,另一个用于地址 2 和 3,我们可以将它们存储在它们共享的二进制前缀下。如果我们使用 a.
来指示前缀末尾的“未使用”位,则我们有00.
范围 0-1 和
01.
范围 2-3。
表示这一点的标准方式是使用范围中的最小数字后跟前缀的长度;在这种情况下,这些将是0/2
范围 0-1 和2/2
范围 2-3。
但是如果我们想查找地址 6 的路由信息会发生什么?通常,我们会添加一组带有前缀的“默认”路由信息0/0
,即匹配任何位,然后在搜索时寻找最具体的信息,即我们能找到的最长匹配前缀。因此,我们刚刚描述的完整路由表是:
0/2 00. Matches addresses 1 and 2.
2/2 01. Matches addresses 3 and 4.
0/0 ... Matches any address.
子网掩码可以用相同的方式用前缀来描述,因此这种方案通常用于此目的。但请记住,仅仅因为这种方案能用于描述子网并不意味着它被使用仅有的用于描述子网。
举个路由表前缀不是子网的例子,你可以有两个网络接口连接到同一个网络,比如 192.168.2.0/24。(这可以通过将两个单独的网卡连接到同一个交换机来实现,每个网卡都有自己的电缆。)然后,你可以使用两个路由表条目设置路由表以“平衡”两个接口之间的传出流量:
192.168.2.0/25 eth0 # range ...2.0 to ...2.127
192.168.2.128/25 eth1 # range ...2.128 to ...2.255
这会将发往该网络上地址 0-127 的数据包发送出去eth0
,但将发往该网络上地址 128-255 的数据包发送出去eth1
。这是一种糟糕的做法(原因我在这里就不说了),但它演示了路由前缀和网络地址可能不匹配的情况。
¹维基百科文章路由表不幸的是,前缀字段包含“网络 ID”。虽然这在某些特定的路由表实现中可能是正确的,但在一般情况下它并不总是网络 ID,正如您提供的示例和我在本答案后面的示例中所见。
²此路由信息通常包括要使用的接口、在该接口上要联系的路由器(如果有)、可通过该接口直接访问的主机的 MAC 地址、如果主机有多个源地址,我们应该在数据包上放置哪个源地址、安全信息等。可能存在各种各样的数据,但这些对于本讨论的目的而言都不重要,因为我们只讨论如何查找给定地址的正确数据集,而不是数据集本身的内容。