We need to wake-up some computers on our internal LAN, from the Internet.
We have a somewhat closed router, with very few ways to configure it.
I'd like to use netfilter (iptables) to do this because it doesn't involve a daemon or similar, but other solutions are okay.

What I have in mind:

  • the external computer issues a WOL (Wake-On-LAN) packet to the public IP address (with the correct MAC inside)
  • the correct port is open on the router (say 1234), redirecting the data to a Linux box
  • the Linux box transforms the UDP unicast packet into a broadcast packet (exact same content, only destination address is modified to or
  • the multicast packet comes to every NIC, and the desired computer is now awake

For that, a very simple netfilter rule is:
iptables --table nat --append PREROUTING --in-interface eth+ --protocol udp --destination-port 1234 --jump DNAT --to-destination

Alas netfilter seems to ignore transformation to broadcast. and gives nothing. Also tested with and
I used tcpdump to see what happens:
tcpdump -n dst port 1234
13:54:28.583556 IP www.xxx.yyy.zzz.43852 > UDP, length 102
and nothing else. I should have a second line like:
13:54:28.xxxxxx IP www.xxx.yyy.zzz.43852 > UDP, length 102

If I redirect to a non-multicast address, everything is okay. I have the 2 expected lines. But obviously this don't work for WOL.

Is there a way to tell netfilter to issue broadcast packets?

Other methods I think about:

  • use iptables to match the desired packets, log them, and use a daemon to monitor the log file and fire the broadcast packet
  • use iptables to redirect the desired packets to a local daemon, which fires the broadcast packet (simpler)
  • use socat (how?)
  • A broadcast packet is not just a packet sent to a broadcast address. There is a flag for sockets called SO_BROADCAST. I'm trying to figure out how iptables can modify it.
    – lgeorget
    Jun 1 '13 at 13:01
  • @lgeorget: iptables is not related to so sockets. Jun 1 '13 at 13:08
  • Indeed. I'm not looking at the right place. There must be an option somewhere for iptables to allow it to send broadcast packets.
    – lgeorget
    Jun 1 '13 at 13:17
  • 2
    Have you tried iptables --table nat --append PREROUTING --in-interface eth+ --protocol udp --destination-port 1234 --jump DNAT --to-destination ?
    – lgeorget
    Jun 1 '13 at 13:25
  • @lgeorget: thanks for the idea. But same result. I update the question Jun 1 '13 at 14:00

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:,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:,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.
  • is more general than 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.

  • I tried that but the problem is that UDP-LISTEN will close the socket after the first packet has arrived, no matter the fork. Use UDP-RECV instead.
    – lgeorget
    Jun 1 '13 at 13:07
  • No problem here. You used the "fork" option ? I see in the man UDP-RECV merge packets. I have no idea about what it means. UDP-RECVFROM doesn't exhibit this behviour, but it may be an error in the man. Jun 1 '13 at 13:22
  • Yes, I used the 'fork'. I tried with a socat and two netcat processes (one to send packets to socat, the other to receive the broadcast packets). With UPD-LISTEN, socat simulates a connection, and closes the socket at the end. With UDP-RECV, it uses the default connection-less behaviour of UDP. From socat man: "Normally, socket connections will be ended with shutdown(2) which terminates the socket even if it is shared by multiple processes."
    – lgeorget
    Jun 1 '13 at 13:28
  • 2
    Is socat going to broadcast on all interfaces then? Jun 1 '13 at 13:50
  • 1
    @lgeorget: "echo 'dummy' | nc -u -q 0 1234" works perfectly with -UDP-LISTEN. I can run it several times. But I have problems with -UDP-RECV and -UDP-RECVFROM: the packets are broadcasted at maximum link rate until socat is killed. Do you see the same problem with tcpdump ? Jun 1 '13 at 13:53

Broadcast traffic by definition is destined to local machine. This means the packet gets DNAT'ed to 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 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 in this example -- remember to never assign 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 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

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.

  • The packets received from the internet are not broadcast. This is why the question is "Transform UNICAST to BROADCAST" Mar 17 '15 at 13:15
  • @GregoryMOUSSAT yes, but I believe they are saying that once the packet is transformed, making its destination a broadcast address, the kernel considers it destined to the local machine. Aug 3 at 15:40

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.


Socat OpenWRT

Socat has already been stated as an answer, however the stated answer did not work for me on my platform, OpenWRT, with a dynamic WAN address.

My goal is to forward unicast UDP wake-on-lan packets from UDP port 9 of the WAN interface to a subnet broadcast on

The broken (iptables)

I too tried with iptables, but everytime I add a rule that ends in 255, the rule is turned into mush with destination address when I print with:

iptables -t nat -L

I believe iptables isn't capable of multiplexing traffic, as required in a unicast to broadcast conversion.

The bad (faking arp entries)

Faking arp entries is not so bad, because the packets get to everyone on the ethernet segment, but it has the following disadvantages

  • You "consume" an IP address
  • The destination IP in the WoL packet is wrong, even though you get it 'cause the MAC address is all FFFF...
  • An IP malfunction may occur if someone on the network uses that IP address.
  • It is an Ethernet broadcast, and not an IP broadcast.

Note: This may be done with the arp command or ip neigh command.

The good

socat, as indicated by the previous answer, is badass. The previous socat answer, however, I ran into a few issues with it.

  1. My socat didn't forward traffic when the UDP broadcast destination was I avoided this by restricting the broadcast subnet to the one I use is probably safer.
  2. When I set the bind address to, I ran into a broadcast storm due to traffic bouncing back into socat from my LAN. I first solved this by binding to my public ddns, however this is not ideal because ddns may not be available and my dynamically assigned IP address my change.

I was able to bind to (all addresses) and avoid the broadcast storm by adding an iptables rule to block incoming broadcast from bouncing back into socat from the LAN side. This rule, in addition to an iptables rule to accept traffic on UDP port 9, and an iptables rule to log it we get the following three rules in addition to the socat command.

iptables -I input_wan_rule -p udp --dport 9 -j ACCEPT -m comment --comment "firewall entry to allow udp port 9 to socat"
iptables -I input_wan_rule -p udp --dport 9 -j LOG --log-prefix 'Received MAGIC PACKET on udp/9'
iptables -I input_lan_rule -p udp --dport 9 -d -j DROP -m comment --comment "block broadcast from bouncing back to socat to avoid storm"

killall socat 2>/dev/null
socat -u -T1 UDP-LISTEN:9,bind=,fork UDP-DATAGRAM:,broadcast &

For the OpenWRTers, pasting this into /etc/firewall.user and issuing /etc/init.d/firewall restart is sufficient.

Congratulations, you should now have WoL working for your network from anywhere on the web.


Actually netfilter cannot do any broadcast, the routing mechanism does this.

But it drops any forwarded broadcast by default.

It's became possible to forward directed UDP broadcast in recent Linux kernel (circa version 5.0)

You need to modify bc_forwarding parameter for broadcasting network interface:

sudo sysctl -w net.ipv4.conf.eth1.bc_forwarding=1

(Note: it seems the option net.ipv4.conf.all.bc_forwarding doesn't work)

So now, kernel about 5.0 + iptables should be enough for you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.