Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

We need to wake-up some computers on our internal LAN, from the Internet.
We have a somewhat closed router. Very few ways to configure it.
I'd like to use netfilter (iptables) to do this because it doesn't involve a daemon or so, 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 datas to a Linux box
  • the Linux box transform the UDP unicast packet into a broadcast packet (exact same content, only destination address is modified to 255.255.255.255 or 192.168.0.255)
  • the multicast packet comes to every NICs, 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 192.168.0.255

Alas netfilter seems to ignore transformation to broadcast. 192.168.0.255 and 255.255.255.255 gives nothing. Also tested with 192.168.0.0 and 0.0.0.0
I used tcpdump to see what happens:
tcpdump -n dst port 1234
13:54:28.583556 IP www.xxx.yyy.zzz.43852 > 192.168.0.100.1234: UDP, length 102
and nothing else. I should have a second line like:
13:54:28.xxxxxx IP www.xxx.yyy.zzz.43852 > 192.168.0.255.1234: 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 their 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 iptable to redirect the desired packets to a local daemon, which fire the broadcast packet (simplier)
  • use socat (how ?)
share|improve this question
    
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. –  Bertrand SCHITS 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
1  
Have you tried iptables --table nat --append PREROUTING --in-interface eth+ --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.0 ? –  lgeorget Jun 1 '13 at 13:25
    
@lgeorget: thanks for the idea. But same result. I update the question –  Gregory MOUSSAT Jun 1 '13 at 14:00

3 Answers 3

up vote 7 down vote accepted

socat is a killer utility. Put somewhere in your init scripts:
socat -u -T1 UDP-LISTEN:1234,fork UDP-DATAGRAM:255.255.255.255:5678,broadcast
Some users have problems with UDP-LISTEN, so using UDP-RECV seem better (warning: could send the broadcast packets in an endless loop)
socat -u UDP-RECV:1234,fork UDP-DATAGRAM:255.255.255.255:5678,broadcast

fork allow to keep socat listening for next packets.
T1 limit life of forked subprocesses to 1 second.
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 send the broadcasted packets to every interfaces.

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-pivilegied port, so you can run socat with user nobody.

Thanks to lgeorget Hauke Laging and Gregory MOUSSAT to have participated to this answer.
Fell free to add details.

share|improve 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. –  Bertrand SCHITS 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? –  Hauke Laging Jun 1 '13 at 13:50
1  
@lgeorget: "echo 'dummy' | nc -u -q 0 127.0.0.1 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 ? –  Bertrand SCHITS Jun 1 '13 at 13:53

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.

share|improve this answer

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

There is a great workaround with the mentioned ARP trick. You will "loose" one IP address. I'll use dummy 192.168.0.254 in this example:

TIP: Remember to never assign 192.168.0.254 to any devices in your network.

Step 1. Create static ARP entry on LAN interface for IP address you will never use for any machine, ex: 192.168.0.254:

arp -i ethLAN --set 192.168.0.254 FF:FF:FF:FF:FF:FF

Step 2. DNAT your Wake-On-Lan UDP taffic on 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 a WOL packets. This workaround also works on products which are based on linux kernel, ex: Mikrotik devices, openwrt devices. I use this trick on Mikrotik devices to wake my machine remotely with my cell phone.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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