Transform a UDP unicast packet into a broadcast?

socat is a killer utility. Put this somewhere in your init scripts:

socat -u -T1 UDP-LISTEN:1234,fork,range=<ip address of source>/32 UDP-DATAGRAM:255.255.255.255:5678,broadcast

Some users have problems with UDP-LISTEN, so using UDP-RECV seems better (warning: could send the broadcast packets in an endless loop):

socat -u UDP-RECV:1234 UDP-DATAGRAM:255.255.255.255:5678,broadcast
  • fork allows socat to keep listening for next packets.
  • T1 limits the life of forked subprocesses to 1 second.
  • range makes socat listen only to packets coming from this source. Assuming this is another computer than the one where socat is running, this helps that socat does not listen to its own broadcast packets which would result in an endless loop.
  • 255.255.255.255 is more general than 192.168.0.255. Allowing you to just copy-paste without thinking about your current network structure. Caveat: this probably sends the broadcasted packets to every interface.

As you, I noticed WOL works with whatever port. I wonder if this is reliable. Lots of documents only talk about ports 0, 7 and 9.
This allow to use a non-pivileged port, so you can run socat with user nobody.

Thanks to @lgeorget @Hauke Laging and @Gregory MOUSSAT to have participated to this answer.


Broadcast traffic by definition is destined to local machine. This means the packet gets DNAT'ed to 192.168.0.255 and then the kernel sees the packet and decides that it's destined to the router itself, so you will see this packet in the INPUT chain. The router (and any other device) will think that 192.168.0.255 packets are destined for itself and will not forward them further. Broadcast packets are not routed/forwarded by design.

There is a great workaround with the mentioned ARP trick. You will "lose" one IP address. I'll use dummy 192.168.0.254 in this example -- remember to never assign 192.168.0.254 to any devices in your network:

  1. Create a static ARP entry on LAN interface for the IP address you will never use for any machine:

    arp -i ethLAN --set 192.168.0.254 FF:FF:FF:FF:FF:FF
    
  2. DNAT your Wake-On-Lan UDP taffic on the WAN interface to this dummy IP address:

    iptables --table nat --append PREROUTING  --in-interface ethWAN --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.254
    

This works perfect for WOL packets. This workaround also works on products which are based on the Linux kernel, like Mikrotik devices and openwrt devices. I use this trick on Mikrotik devices to wake my machine remotely with my cell phone.


I found this question on Serverfault.

I didn't manage to get such broadcast traffic through my router though. The DNATted packets didn't even arrive at my FORWARD chain. Maybe there is some strange kernel option which disallows that.

But the ARP idea is interesting. I guess that should be accompanied by a rule in OUTPUT which forbids packets to this address so that it can be reached with forwarded traffic only.