我知道如果我有一个网络,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 数据包的目标地址设置为子网地址,那么如果子网永远不会成为 AN IP 流的端点,为什么子网本身需要一个地址?对我来说,不允许将此地址用作主机地址似乎是一种浪费。
总而言之,我的问题是:
- IP 数据包的目的地是否设置为子网 IP 地址?
- 如果是,在什么情况下以及为什么?
- 如果不是,那么为什么不释放该地址供任何主机使用?
主机部分全为零的地址指的是网络本身,而不是任何特定的主机。
从历史上看,这个零主机地址用作替代广播地址,并且设备仍然以这种方式响应。
所以,我不同意其他一些答案:不,零不是一个完全可用的主机地址。如果您需要超过 254 个地址,则必须创建更大的子网。
看,我的 Linksys 路由器,其地址是
.1
响应.0
. (网络掩码是255.255.255.0
,因此最后一个八位字节对应于主机号。)如果我将
.0
地址分配给某个主机,如果路由器不响应它,我将无法对它执行 ping 操作。如您所见,某些工具(例如路由器版本)ping
将0
其视为广播。如果您愿意修补所有受这种弯曲影响的协议栈和其他软件,您可以弯曲规则。否则,请遵守规则。
举个例子。
我在一家公司工作,该公司设计了一个内置于 14 插槽机箱中的网络节点,在多种类型的卡上运行大量独立的操作系统映像,所有这些都通过背板进行通信。背板上有一个网络设置,约定
127.X.0.Y
是插槽 X 中节点 Y 的内部 IP 地址,全部从 1 开始编号。我们基本上出于我们自己的目的对环回地址进行了子网划分。为了让它工作,我们不得不到处修补 Linux 内核和 IIRC,一点点用户空间。
由于该网络仅在盒子内使用,并且大多数需要环回的程序使用继续正常工作的
127.0.*
网络(实际上是特定地址),所以一切都很酷。127.0.0.1
是的。这是一个有效的 IP,因此可以使用。
它只是 /24 中 255 个可用 IP 之一
如果你有旧硬件,那么你需要检查它是否使用第一个或最后一个地址作为网络地址。(掩码为 FF.FF.FF.00 的网络为 .0 或 .255)
这使跳过该 IP 成为一个好习惯。很久以前养成的习惯很难忽视。
而不知道背景的人不使用它“因为其他人也不使用它,所以使用它一定是错误的”或者因为他们没有意识到“0”可以是第一个数字。
[编辑] Grezzo 刚刚在 Windows XP 上对其进行了测试,其中 Windows 网络 GUI“有效地”阻止了此设置。Windows 7 具有相同的行为。然后我在它可以正常工作的非 Windows 主机上尝试了它。如果您使用 Windows,那么您可能必须通过 IPconfig 手动配置您的网络以将其设置为全零。
[编辑2]
我使用它的时间越长,我就越困惑。
Rfc4632 - Classless Inter-domain Routing 似乎没有禁止它,但也没有明确允许它。
这篇 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]
同一个问题的另一个链接。它在堆栈交换上似乎有点流行:
https://superuser.com/questions/379451/why-can-a-network-address-not-be-a-valid-host-address
一个想法:
在与路由表中的条目进行比较之前, Destination_IP 可能与网络桅杆进行AND运算(硬件中的快速操作)。但:
(半随机 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 页指出:
在我们的网络工程网站上引用@ylearn
我相信第一个文档来自RFC950,它引用了 RFC943(它废弃了上面的RFC923,但对特殊地址使用相同的语言):
实际上它取决于网络掩码,例如,对于网络 83.23.159.0/23,83.23.159.0 是一个完全可用的 ip 地址
听起来这里与基本网络有点混淆。
其中一个响应中提到的“古老硬件”不会使用 IP 子网零 - 使用 IP 地址 xxx0 和为 /24 CIDR 或 255.255.255.0 子网掩码设置的网络是完全不同的问题。
IP 子网零
子网上可用的主机 IP 地址
网络地址和广播地址都是保留的,不能(根据当前和以前的网络标准)分配给设备。在 /24 系统上使用 xxx0 作为主机地址是错误的。即使 Linux 让你用,也不代表它就是对的,只是说明 Linux 认为你知道自己在做什么。
如果您的系统允许您将 xxx0 作为 IP4 地址分配给主机并且它似乎可以正常工作 - 可能是特定主机正在接收针对该网络上任何设备的所有流量,因此其网络可能无法以最佳方式工作。
RFC 1122(“互联网主机的要求——通信层”)禁止它:
实际上答案是子网划分的基础。您的子网的“全零”IP 与网络 ID 相结合用于计算数据包必须发送到的位置。
在您的示例中,您的子网为 255.255.255.0。任何了解 TCP/IP 协议的设备都会使用网络掩码和 IP 地址来计算数据包是发往本地网络(通过执行逻辑与运算)还是必须通过网关/路由器发送。
所以我想 IP 不能使用的原因是因为它已经被设计用来与网络掩码一起“定义”网络边界。
有人要求我从NetworkEngineering重新发布我的答案,所以我将对这个站点进行一些修改。
在RFC919中,引用了通用的网络地址:
如果有人提到“10.1.2.0”是网络而不是网络上的主机,这提供了一个约定,应该澄清我们的理解。
从那里开始,在RFC923中定义了在 IP 地址中使用“0”,并在后续的 RFC 中继续使用:
此示例通过在地址的网络部分中使用 0 来提供当前网络 (0.0.0.37) 上的特定主机,但实际上并没有阐明相反的情况(地址的主机部分中为 0)。然而,因为它确实将“0”定义为“this”。
在RFC1060中,地址“0.0.0.0”被明确记录为“此网络上的此主机”:
由于地址的主机部分全为零表示“此主机”,因此从逻辑上讲它不能用作主机地址。
回到直接回答你的问题:
根据我在 RFC 中的发现,不应使用它。我承认它没有像我希望的那样明确指定,但这在许多标准中都很常见。当标准在某一点上不太坚定时,该行业似乎就会“安定下来”,形成一个普遍接受的解释。
此外,根据 RFC 的内容,可以编写软件以假设该地址用于寻址网络而不是特定主机。或者更确切地说是某种“环回”(即指定网络上的主机)。
那么为什么有些操作系统明确允许使用它呢?我想很多事情都归结为开发人员的时间/资源,或者没有人真正想过添加有效性检查。逻辑必须比“如果它以 0 结尾”更复杂一些,因为更大的子网(/23 或更大)将包含 .255 和 .0 的有效 IP 地址(即 10.1.2.0/23 包含两个有效 IP地址 10.1.2.255 和 10.1.3.0)。尽管一些组织也确实避免在较大的子网中使用这些有效地址,以避免不正确支持现代子网划分的软件出现任何奇怪的问题。
至于为什么不释放那个 IP 地址,它只是归结为成本/收益。进行此更改以恢复每个子网的一个 IP 地址需要花费大量时间和精力,并且在需要额外 IP 地址的情况下,只有一个地址就足够了吗?添加第二个子网或扩大当前子网要容易得多,可能会为您提供多个地址而不是一个地址,同时无需对任何现有软件/硬件进行重大更改。
首先,值得注意的是,RFC4291 将 IPv6 中的全零地址定义为“必需的任播地址”,这些地址是一个网段上至少有一个路由器(但不一定是所有路由器)将回答的地址。(IPv6 和 IPv4 中的任播地址都可以具有非零主机部分。)因此,除非您使用 IPv6 提供任播服务,否则答案肯定是“否”。
正如其他答案中提到的那样,将这些 IPv4 地址用作广播媒体上的主机地址是不安全的:由于历史原因,许多主机将响应具有这些地址的数据包,就好像它们是广播数据包一样。但是,禁止在上游使用这些地址也是不安全的,即使您有明确的指示(来自路由条目)该地址位于子网的底部......该地址可能用于非广播子网,如 NAT 池,或用作路由器线路地址的 /31。这意味着如果可能的话,反“smurf”类 DoS 保护属于直接连接的路由器,路由器应该知道媒体是否是广播域。这些保护在通常情况下是存在的,所以这是为什么将这些地址用作广播媒体上的单播地址不起作用的第二个原因:
如果要从 RFC923 推断,零主机将是“特定网络上的此主机”。进行这种推断是不安全的,因为 RFC 仅针对网络地址,而不是主机地址。然而,可以想象一些 IP 地址协商协议可能已经部署在主机知道它想要属于的子网但不知道其主机地址并且通过指定零主机地址要求在该特定网络上进行自动配置的地方。这是需要注意的另一种可能的解释。