Desired behavior
When an application sends a packet to the global broadcast IP address 255.255.255.255
, I would like that the packet be sent to the Ethernet global broadcast address (ff:ff:ff:ff:ff:ff
), on all interfaces.
On Linux and probably other OSes as well this seems to work. Windows XP and Windows 7 exhibit different behaviors about this, and neither behaviour is desirable for my situation.
Windows XP behavior
The packet will be sent correctly to the first network interface (interface order is specified in "Network Connections/Advanced/Advanced Settings"). It will also be sent to the other interfaces.
Everything is right so far. Problem is, when sending to the other interfaces, the source address of the broadcast packet is the IP address of the first interface. For example, imagine this network configuration (order is important):
- Adapter 1: IP address
192.168.0.1
- Adapter 2: IP address
10.0.0.1
- Adapter 3: IP address
172.17.0.1
Now if I send a broadcast packet, the following packets will be sent (with source and destination IP addresses):
On adapter 1:
192.168.0.1
=>255.255.255.255
On adapter 2:
192.168.0.1
=>255.255.255.255
On adapter 3:
192.168.0.1
=>255.255.255.255
In practice, applications using broadcast packets won't work on any interfaces other than adapter 1. In my opinion, this is a blatant bug in the TCP/IP stack of Windows XP.
Windows 7 behavior
Modifying the network interface order doesn't seem to have any effect on Windows 7. Instead, broadcast seems to be controlled by the IP route table.
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
===========================================================================
See the 255.255.255.255
routes? Yep, they control broadcast packets. In this situation, broadcast packets will be send via the 192.168.0.3
because it has the lower metric... but not to the other interfaces.
You can change the interface through which global broadcast packets will be sent very easily (just add a persistent 255.255.255.255
route with a low metric). But no matter how hard you try, broadcast packets will only be sent on only one interface, not all of them like I'd like it to do.
Conclusion
- Windows 7 only sends broadcast packets to one interface. You can choose which one, but that's not the point here.
- Windows XP sends broadcast packets to all interfaces, but it only sends them as expected to one interface, which in practice is equivalent to the Windows 7 behavior.
The goal
I want to change this global IP broadcast support in Windows (preferably Windows 7) once and for all. Of course the better way would be to have some kind of supported configuration change (registry hack or similar), but I'm open to all suggestions.
Any ideas?
Not that I am in the business of defending Microsoft, but after reading through the following RFCs which attempt to define how broadcasts work, I don't think that Microsoft is necessarily violating any RFCs. IMO the problem should be fixed at the application level (i.e. directed broadcasts, not global) which will hit the appropriate routes in the routing table and only be sent from the correct interface for that IP network.
They both state that there is no standard defined for broadcasts. It also mentions in 919 that a specific physical interface should be selected for the broadcast. In the case of a multi-homed, multi-NIC machine generating the broadcast, I don't think that it's clearly stated what should happen. Broadcasts are never supposed to be passed by routers from one interface to the other, so is the Windows machine a router or not in this case?
If it is acting as a router, then any host responding to the broadcast with the incorrect IP address for that network (Adapters 2 and 3 in your example) should send the packet back to the ethernet address of Adapters 2 and 3 in response to Adapter 1's IP address and the Windows host should route it to the proper interface.
That sounds confusing... but can't think of a better way to phrase this
And finally, RFC 919 specifically says From RFC 919
Reading that would suggest that the source IP address is irrelevant for a broadcast.
Since each application seems to handle broadcasts differently, I think that's where the responsibility resides. For example.
nbtstat
sends out directed broadcasts on multi-NICed machines, whereas games might use global broadcasts.In short, the application should be fixed, not the OS in this case...
EDIT: Here is a link for the same circumstances, but on Linux. The linux kernel handles it by only sending one packet out the default interface (NIC A in this example). They recommend that the application enumerate the NICs and send a directed broadcast out each NIC. Link
Finally, I solved it programmatically. I wrote a tiny software called WinIPBroadcast which takes care of relaying the broadcast frames to all interfaces.
It works using an interesting fact: it is possible to receive locally generated global broadcast packets when listening on the loop back address (127.0.0.1). WinIPBroadcast listens on the local address for all broadcast using RAW sockets, then for each broadcast packet, it relays it to all interfaces except the preferred one.
Update 06.12.2021: Updated Link for the community