![为什么 IP 地址的主机部分不能全为零来表示主机?](https://linux22.com/image/601179/%E4%B8%BA%E4%BB%80%E4%B9%88%20IP%20%E5%9C%B0%E5%9D%80%E7%9A%84%E4%B8%BB%E6%9C%BA%E9%83%A8%E5%88%86%E4%B8%8D%E8%83%BD%E5%85%A8%E4%B8%BA%E9%9B%B6%E6%9D%A5%E8%A1%A8%E7%A4%BA%E4%B8%BB%E6%9C%BA%EF%BC%9F.png)
我知道如果我有一个网络83.23.159.0/24
那么我就有 254 个可用的主机 IP 地址,因为:
83.23.159.0 (in binary: host portion all zeros) is the subnet address
83.23.159.1-254 are host addresses
83.23.159.255 (in binary: host portion all ones) is the broadcast address
我理解广播地址的用途,但我不明白子网地址的用途。我看不出将 IP 数据包的目标地址设置为子网地址的任何理由,那么如果子网本身永远不会成为 IP 流的端点,它为什么需要地址呢?在我看来,不允许将此地址用作主机地址似乎是一种浪费。
总而言之,我的问题是:
- IP 数据包的目的地是否曾设置为子网 IP 地址?
- 如果是,在什么情况下以及为什么?
- 如果没有,那么为什么不释放该地址供任何主机使用?
答案1
IP 数据包的目的地是否曾设置为子网 IP 地址?
是的。这是一个有效的 IP,因此可以使用。
如果是,在什么情况下以及为什么?
它只是 /24 中 255 个可用 IP 之一
如果没有,那么为什么不释放该地址供任何主机使用?
如果你有古老的硬件,那么您需要检查它是否使用第一个或最后一个地址作为网络地址。(对于掩码为 FF.FF.FF.00 的网络,则为 .0 或 .255)
这使得跳过该 IP 成为一种好习惯。而且很久以前养成的习惯很难被忽视。
而那些不了解背景的人不会使用它,‘因为其他人也不使用它,所以使用它一定是错误的’,或者是因为他们没有意识到‘0’可以是第一的数字。
[编辑] Grezzo 刚刚在 Windows XP 上进行了测试,其中 Windows 网络 GUI '有帮助' 阻止了此设置。Windows 7 有同样的行为。然后我在非 Windows 主机上尝试了它,它正常工作。如果您使用 Windows,那么您可能必须通过 IPconfig 手动配置您的网络以将其设置为全零。
[编辑2]
我从事这项工作的时间越长,我就越困惑。
Rfc4632 - 无类域间路由 似乎没有禁止它,但也没有明确允许它。
这篇 ServerFault 帖子提及:“由于历史原因,许多操作系统将第一个地址视为广播。例如,在我的本地 (/24) 网络上从 OS X、Linux 和 Solaris ping xxx0 会得到响应。默认情况下,Windows 不允许您 ping 第一个地址,但您可以使用 SetIPUseZeroBroadcast WMI 方法启用它。我想知道您是否可以在全 Windows 网络上使用 .0 作为主机地址。”。
这是同样的问题,但没有答案。
网络地址也用于路由表。但我不明白为什么它因此而不起作用。路由表中的相同符号将路由到正确的网络。一旦进入正确的网络,它将到达 IP 为 0 的 PC。
(所有这些都适用于 192.168.1/24。
如果您使用 192.168.0/23,那么 192.168.1.0 将是范围中间的有效且安全的值)
[编辑3]
另一个指向同一问题的链接。它在 Stack Exchange 上似乎颇受欢迎:
https://superuser.com/questions/379451/why-can-a-network-address-not-be-a-valid-host-address
还有一个想法:
Destination_IP 可能是和先与网络桅杆进行通信(硬件中的快速操作),然后再与路由表中的条目进行比较。但是:
(半随机 IP)192.168.0.42 与 255.255.255.0 将得出 192.168.0.0
但 192.168.0.0 与 255.255.255.0 也会产生 192.168.0.0
[编辑 4 - 在写完这个答案很久之后 - 我可能需要重写整个帖子,因为这一新信息]
RFC923第 3 页指出:
In certain contexts, it is useful to have fixed addresses with
functional significance rather than as identifiers of specific
hosts. When such usage is called for, the address zero is to be
interpreted as meaning "this", as in "this network". The address
of all ones are to be interpreted as meaning "all", as in "all
hosts". For example, the address 128.9.255.255 could be
interpreted as meaning all hosts on the network 128.9. Or, the
address 0.0.0.37 could be interpreted as meaning host 37 on this
network.
我相信第一个关于这方面的文献来自射频识别 (RFC950)参考文献RFC943(这取代了RFC923但对特殊地址使用相同的语言):
It is useful to preserve and extend the interpretation of these
special addresses in subnetted networks. This means the values
of all zeros and all ones in the subnet field should not be
assigned to actual (physical) subnets.
答案2
主机部分全为零的地址指的是网络本身,而不是任何特定主机。
从历史上看,这个零主机地址一直作为备用广播地址,并且设备仍然以这种方式响应。
因此,我不得不反对其他一些答案:不,零不是一个完全可用的主机地址。如果您需要超过 254 个地址,则必须创建更大的子网。
瞧,我的 Linksys 路由器,其地址为 ,.1
可响应 的 ping .0
。(网络掩码为255.255.255.0
,因此最后一个八位字节对应于主机号。)
webserver:~# ping 192.168.1.0
Do you want to ping broadcast? Then -b
webserver:~# ping -b 192.168.1.0
WARNING: pinging broadcast address
PING 192.168.1.0 (192.168.1.0) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.46 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.812 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.819 ms
如果我将.0
地址分配给某个主机,我将无法 ping 该主机,除非路由器也做出响应。正如您所见,某些工具(例如该路由器版本)将其视为ping
广播0
。
如果您愿意修补所有协议栈和其他受此影响的软件,则可以变通规则。否则,请遵守规则。
举个例子。
我曾在一家公司工作,该公司设计了一个内置在 14 插槽机箱中的网络节点,在几种类型的卡上运行大量独立的操作系统映像,所有映像都通过背板进行通信。背板上有一个网络设置,其约定是127.X.0.Y
X 插槽中节点 Y 的内部 IP 地址,所有 IP 地址都从 1 开始编号。
我们基本上将环回地址划分为子网以达到我们自己的目的。为了使其正常工作,我们必须对 Linux 内核进行一些修补,如果我没记错的话,还需要修补一些用户空间。
由于该网络仅在框内使用,并且大多数需要环回的程序都使用该127.0.*
网络(实际上是特定地址127.0.0.1
)继续正常工作,所以一切都很顺利。
答案3
实际上,这取决于网络掩码,例如,对于网络 83.23.159.0/23,83.23.159.0 是一个完全可用的 IP 地址
答案4
RFC 1122(“互联网主机要求--通信层”)禁止这样做:
IP 地址的 < Host-number>、< Network-number> 或 < Subnet-number> 字段的值不得为 0 或 -1