dechamps / WinIPBroadcast

Automagically sends IP broadcast packets to all interfaces on Windows
GNU General Public License v3.0
252 stars 21 forks source link

Puzzels:what are the key lines of the code that send to each interface with raw socket? #6

Closed chao-sun01io closed 4 years ago

chao-sun01io commented 4 years ago

Dear sir, I have a requirement that sending a broadcast to all interfaces to scan a Networking camera (according to the protocal, the device will response), I use raw socket to send the broadcast message, it works when there is only one network interface on my computer, but may fail on the one with multiple interfaces. It's also because the windows route the broadcast to 'preffered' interface. I have read your code, but quite not understand how to replay the messge to multiple interfaces. I am not familiar with socket programming in fact, so could you please explain what is the key point to reach the goal sending to each interface in the function void sendBroadcast? Thank you in advance!

dechamps commented 4 years ago

Here's how WinIPBroadcast sends a broadcast packet to all network interfaces:

  1. Use GetIpForwardTable() to get the IPv4 routing table.
  2. For each broadcast address in the routing table (i.e. each broadcast subnet configured on each interface, e.g. 192.168.1.255, as opposed to the global broadcast address 255.255.255.255):
    1. Create a socket using WSASocket();
    2. bind() it to the source address from the routing table entry (i.e. the local address of the interface);
    3. Set SO_BROADCAST to enable broadcast on the socket;
    4. Send the original broadcast packet to the destination broadcast address from the routing table entry.

In the current WinIPBroadcast code, the socket is created in SOCK_RAW mode. I don't quite remember why I did that; SOCK_RAW is required for WinIPBroadcast's receive socket (otherwise it won't see local broadcasts), but I don't think it's necessary for sending. You might be able to use SOCK_DGRAM which probably makes more sense here.

chao-sun01io commented 4 years ago

@dechamps I have tried and found that the key point is bind()it to the local address of the interface, then set SO_BROADCAST; while my former implementation didn't bind the source address. Thank you for your help!