期望的行为
当应用程序向全局广播 IP 地址发送数据包时255.255.255.255
,我希望该数据包ff:ff:ff:ff:ff:ff
在所有接口上都被发送到以太网全局广播地址()。
在 Linux 和其他操作系统上,这似乎也有效。Windows XP 和 Windows 7 对此表现出不同的行为,这两种行为都不适合我的情况。
Windows XP 行为
数据包将正确发送到第一个网络接口(接口顺序在“网络连接/高级/高级设置”中指定)。它还将发送到其他接口。
到目前为止一切都正确。问题是,当发送到其他接口时,广播数据包的源地址是第一个接口的 IP 地址。例如,想象一下这个网络配置(顺序很重要):
- 适配器 1:IP 地址
192.168.0.1
- 适配器 2:IP 地址
10.0.0.1
- 适配器 3:IP 地址
172.17.0.1
现在,如果我发送一个广播数据包,则会发送以下数据包(带有源和目标 IP 地址):
在适配器 1 上:
192.168.0.1
=>255.255.255.255
在适配器 2 上:
192.168.0.1
=>255.255.255.255
在适配器 3 上:
192.168.0.1
=>255.255.255.255
实际上,使用广播数据包的应用程序无法在适配器 1 以外的任何接口上运行。在我看来,这是 Windows XP 的 TCP/IP 堆栈中的一个明显的错误。
Windows 7 行为
修改网络接口顺序似乎对 Windows 7 没有任何影响。相反,广播似乎由 IP 路由表控制。
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 10.202.254.254 10.202.1.2 286
0.0.0.0 0.0.0.0 192.168.0.1 192.168.0.3 10
10.202.0.0 255.255.0.0 On-link 10.202.1.2 286
10.202.1.2 255.255.255.255 On-link 10.202.1.2 286
10.202.255.255 255.255.255.255 On-link 10.202.1.2 286
127.0.0.0 255.0.0.0 On-link 127.0.0.1 306
127.0.0.1 255.255.255.255 On-link 127.0.0.1 306
127.255.255.255 255.255.255.255 On-link 127.0.0.1 306
192.168.0.0 255.255.255.0 On-link 192.168.0.3 266
192.168.0.3 255.255.255.255 On-link 192.168.0.3 266
192.168.0.255 255.255.255.255 On-link 192.168.0.3 266
224.0.0.0 240.0.0.0 On-link 127.0.0.1 306
224.0.0.0 240.0.0.0 On-link 192.168.0.3 266
224.0.0.0 240.0.0.0 On-link 10.202.1.2 286
255.255.255.255 255.255.255.255 On-link 127.0.0.1 306
255.255.255.255 255.255.255.255 On-link 192.168.0.3 266
255.255.255.255 255.255.255.255 On-link 10.202.1.2 286
===========================================================================
看到255.255.255.255
路由了吗?没错,它们控制广播数据包。在这种情况下,广播数据包将通过 发送,192.168.0.3
因为它的度量值较低……但不会发送到其他接口。
你可以很轻松地更改发送全局广播数据包的接口(只需添加一个255.255.255.255
具有低度量的持久路由)。但无论你如何努力,广播数据包只会在一界面,但并不是所有界面都像我希望的那样。
结论
- Windows 7 仅向一个接口发送广播数据包。你可以选择哪一个,但这不是重点。
- Windows XP 向所有接口发送广播数据包,但它只会按预期将它们发送到一个接口,这实际上相当于 Windows 7 的行为。
目标
我想一劳永逸地改变 Windows(最好是 Windows 7)中的全局 IP 广播支持。当然,更好的方法是进行某种支持的配置更改(注册表破解或类似操作),但我愿意接受所有建议。
有任何想法吗?
答案1
我并不是在为微软辩护,但在阅读了以下试图定义广播工作原理的 RFC 后,我认为微软不一定违反了任何 RFC。在我看来,问题应该在应用程序级别(即定向广播,而不是全局广播)解决,这将命中路由表中的适当路由,并且仅从该 IP 网络的正确接口发送。
他们都说没有为广播定义标准。它还在 919 中提到应该为广播选择特定的物理接口。对于多宿主、多 NIC 计算机生成广播的情况,我认为没有明确说明应该发生什么。广播永远不应该由路由器从一个接口传递到另一个接口,那么在这种情况下,Windows 计算机是否是路由器?
如果是演技作为路由器,则任何响应该网络的错误 IP 地址广播的主机(示例中的适配器 2 和 3)都应将数据包发送回适配器 2 和 3 的以太网地址以响应适配器 1 的 IP 地址,并且 Windows 主机应将其路由到正确的接口。
这听起来很令人困惑……但我想不出更好的表达方式
最后,RFC 919 明确指出 来自 RFC 919
由于我们假设该问题已在数据链路层得到解决,因此希望
发送本地广播或定向广播的 IP 主机只需
指定适当的目标地址并照常发送数据报即可
。任何复杂的算法只需驻留在网关中即可。
读到这些内容会让人觉得源 IP 地址与广播无关。
由于每个应用程序似乎以不同的方式处理广播,因此我认为这就是责任所在。例如, nbtstat
在多网卡的机器上发送定向广播,而游戏可能使用全局广播。
简而言之,在这种情况下,应该修复应用程序,而不是操作系统……
编辑:这是一个关联适用于相同情况,但在 Linux 上。Linux 内核通过仅从默认接口(本例中为 NIC A)发送一个数据包来处理它。他们建议应用程序枚举 NIC 并发送导演广播出每个 NIC。 关联
答案2
最后,我用编程解决了这个问题。我写了一个小软件,叫温控广播它负责将广播帧中继到所有接口。
它的工作原理是利用一个有趣的事实:在监听环回地址 (127.0.0.1) 时,可以接收本地生成的全局广播数据包。WinIPBroadcast 使用 RAW 套接字监听本地地址上的所有广播,然后对于每个广播数据包,将其中继到除首选接口之外的所有接口。
2021 年 12 月 6 日更新:更新了社区链接