据我所知,以 结尾的 IP 地址x.x.x.0
并不指向特定主机,而是指向整个子网。
但是我不清楚如果我发送一个数据包到例如会发生什么192.168.1.0
:您能给我举个例子吗?
答案1
xxx0 传统上是广播地址。(后来改为 xxx255)
它会将您的请求转发到 1/254 范围内的所有 IP 地址,但前提是操作系统支持此功能。默认情况下,OSX 和 Linux 上启用此功能。对于 Windows,您需要启用 SetIPUseZeroBroadcast WMI 才能启用此功能。
xxx0 地址一般用于路由目的,有些路由器会响应并将流量引导至自身。
我在学校里学到,要把 xxx0 地址当成网线。虽然这只是一个比喻,但确实如此。
答案2
IP 地址中“0”和“1”的使用定义于RFC923 并在后续的 RFC 中延续:
Special Addresses:
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.
“以 0 结尾”符号有时也用于路由目的,以指示整个源子网和目标子网。
关于这个主题的完整论述可以在维基百科中找到 Internet 协议版本 4 “第一个和最后一个子网地址”部分:
子网中的第一个地址用于标识子网本身。在此地址中,所有主机位均为 0。为避免表示歧义,此地址被保留。最后一个地址的所有主机位均设置为 1。它用作本地广播地址,用于同时向子网上的所有设备发送消息。对于大小为 /24 或更大的网络,广播地址始终以 255 结尾。
过去,由于某些软件使用非标准广播地址(以零代替一),因此出现了网络地址和广播地址冲突。
此维基百科文章部分还包含示例来说明规则。
答案3
一些历史
第3.2.1.3节定义了四种标准IP广播地址形式:
有限广播:{-1,-1}
定向广播:{<Network-number>,-1}
子网定向广播:{<网络号>,<子网号>,-1}
所有子网定向广播:{<网络号>,-1,-1}
主机必须识别传入数据报的目标地址中的任何这些形式。
请注意,虽然可能存在过时的(早于无类路由)广播版本(剩下 2 个:有限广播:255.255.255.255 和子网定向广播(今天称为定向广播,例如:网络 192.168.1.0/24 中的 192.168.1.255),但(目前)没有 .0 定义。但如下:
有一类主办方*使用非标准广播地址表格,用 0 代替 -1. 所有主机应该 [...]
*4.2BSD Unix及其衍生产品,但不包括4.3BSD。
[...] 承认并接受其中任何一项非标准广播地址作为传入数据报的目标地址。
主机可以选择配置选项,为每个物理接口选择 0 或 -1 形式的广播地址,但此选项应默认为标准 (-1) 形式。
所以因为4.2BSD历史上的非标准行为以及为了与之兼容,.0也被认为是30多年的广播。
如果我将数据包发送到例如 192.168.1.0(在 LAN 192.168.1.0/24 中)会发生什么?
因此,在 LAN 192.168.1.0/24 中,直到今天,大多数系统都会将 192.168.1.0 视为广播,此外还将 192.168.1.255 和/或可能配置为广播地址的任何其他地址视为广播:额外的广播地址没有实际用途,因此这是一个被浪费的地址,主机无法使用。在 /24 中,浪费了 1/256:可以忽略不计。在主机提供商可以租用的 /29(有 8 个地址)中,浪费了 1/8 或 ~12.5% 的地址空间:不再微不足道。
这里有两个 Linux 示例。
在 Linux 内核 5.10 上:
# ip addr add 192.168.1.1/24 broadcast 192.168.1.255 dev eth0
# ping 192.168.1.0
Do you want to ping broadcast? Then -b. If not, check your local firewall rules.
# nc -n -v 192.168.1.255 9
nc: connect to 192.168.1.255 port 9 (tcp) failed: Network is unreachable
# nc -n -v 192.168.1.0 9
nc: connect to 192.168.1.0 port 9 (tcp) failed: Network is unreachable
# ip route get 192.168.1.0
broadcast 192.168.1.0 dev eth0 src 192.168.1.1 uid 0
cache <local,brd>
ICMP(或 UDP)要求指定它是允许发出的广播,而常见的 Linux 变体ping
不会自动执行此操作(它需要-b
)。TCP 失败,因为它不能与广播一起使用:.0 被视为 .-1:广播。
可能任何 Windows、Unix(包括 MacOS、BSD)或路由器品牌(Cisco 等)都会有同样的表现。
但在 Linux >= 5.14 上:
# ip addr add 192.168.1.2/24 broadcast 192.168.1.255 dev eth0
# ping -t 4 -c 1 192.168.1.0
PING 192.168.1.0 (192.168.1.0) 56(84) bytes of data.
From 192.168.1.2 icmp_seq=1 Destination Host Unreachable
--- 192.168.1.0 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
# time nc -n -v 192.168.1.0 9
nc: connect to 192.168.1.0 port 9 (tcp) failed: No route to host
real 0m3,086s
user 0m0,000s
sys 0m0,003s
# ip route get 192.168.1.0
192.168.1.0 dev eth0 src 192.168.1.2 uid 0
cache
# ip neigh show 192.168.1.0
192.168.1.0 dev enp2s0 FAILED
这里 192.168.1.0 现在被视为正常(单播)地址。它会触发 ARP 请求(如果 3 秒后没有得到答复,则通常会失败)。
Linux 在此提交中进行了更改(在内核 5.14+ 中可用):
对待只取最高,不取最低、本地子网内的 IPv4 地址作为广播地址。
因此,根据操作系统及其版本的不同,行为可能会有所不同:要么遵循应该RFC 的兼容 4.2BSD 从 1980 年代开始,并认为它是一个广播,或者它对此表示反对应该(这不是必须但只有应该毕竟,它会认为这是一个正常的单播地址。
即使有这样的变化,由于没有任何东西可以使用 .0 地址,所以不会造成任何损害。
但是,如果 LAN 中的所有系统(包括路由器)都将 .0 视为单播地址(例如,如果所有系统都运行 Linux >= 5.14),则 .0 地址可用,例如用于其他节点。否则,任何将其视为广播并看到来自此 .0 地址的 ARP 请求的节点都会忽略它,因为它认为它是无效的(广播地址不能是源地址,只能是目标地址):它们之间没有连接。
对于非常小的网络(例如 /29),这意味着浪费更少:现在可以将此 8 个地址中的 7 个用于此 LAN 中的节点,或者在考虑路由器时使用 6 + 1,而不是 6 或 5 + 1,只要所有节点(包括路由器)不再将 .0 视为广播。
这种好处或许可以抵消一些人对这种改变不愿血腥屠杀的呼声。