Wake on lan script that works
Asked Answered
I

5

13

is there a wake on lan script using a web language preferably php that works? Also one that has some documentation on how to get it to work like what needs to be enabled on your server etc

Ivett answered 19/5, 2011 at 7:34 Comment(2)
What's a "wake on lan script" exactly?Cooperative
About server configuration: beware of OS-level WoL blocking (Linux turning off Wake-on-LAN) - basically ethtool -s eth0 wol g will be your friend: ubuntuforums.org/showthread.php?t=234588 - so much about "server configuration"Metalwork
G
14
function wol($broadcast, $mac)
{
    $hwaddr = pack('H*', preg_replace('/[^0-9a-fA-F]/', '', $mac));

    // Create Magic Packet
    $packet = sprintf(
        '%s%s',
        str_repeat(chr(255), 6),
        str_repeat($hwaddr, 16)
    );

    $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

    if ($sock !== false) {
        $options = socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, true);

        if ($options !== false) {
            socket_sendto($sock, $packet, strlen($packet), 0, $broadcast, 7);
            socket_close($sock);
        }
    }
}

Should work - call it with a broadcast IP address, and a MAC address

Guthry answered 19/5, 2011 at 8:20 Comment(3)
When you say call it with those two things do you mean set those as variables?Ivett
I mean - pass them as arguments into the functionGuthry
Sorry doesn't work anymore. Warning: socket_send() expects exactly 4 parameters, 6 givenAshore
P
9

I know this is an old questions, but it's still the first Google result, so here's what I ended up doing after a bit of research:

Prerequisites:

  • Linux box on the same network
  • Install the wakeonlan package from your system's package manager
        (i.e. sudo apt-get install wakeonlan)

Now the script is as easy as this:

<?php
    # replace with your target MAC address
    $mac = 'aa:bb:cc:11:22:33';

    exec("wakeonlan $mac");
?>

 

Hope that helps someone.

Pilkington answered 19/11, 2013 at 7:6 Comment(4)
This works as long as $mac never contains user input. Thanks!Lineation
yup. be VERY careful with exec, and if possible, just dont use itChanachance
Given that this question assumed a simple, off-the-shelf solution, I believe that "linux box on the same network" prerequesit (especially one where you have to trigger exec command) doesn't seem to fit here.Une
@Une exec() is totally fine if you control the entire command. And of course this solution only works for people with an existing server, but it's better to share info rather than hide it because it might not work for one specific person.Pilkington
S
2

HTML (test.htm)

<body>
<a href="test.php?mymac=XX:XX:XX:XX:XX:XX">Click to WOL XX:XX:XX:XX:XX:XX</a>
</body>

PHP (test.php)

<?php
$mymac = $_REQUEST['mymac'];
wol("255.255.255.255", $mymac);
echo 'WOL sent to '.$mymac;

function wol($broadcast, $mac){
$mac_array = preg_split('#:#', $mac); //print_r($mac_array);
$hwaddr = '';
    foreach($mac_array AS $octet){
    $hwaddr .= chr(hexdec($octet));
    }
    //Magic Packet
    $packet = '';
    for ($i = 1; $i <= 6; $i++){
    $packet .= chr(255);
    }
    for ($i = 1; $i <= 16; $i++){
    $packet .= $hwaddr;
    }
    //set up socket
    $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
    if ($sock){
    $options = socket_set_option($sock, 1, 6, true);
        if ($options >=0){    
        $e = socket_sendto($sock, $packet, strlen($packet), 0, $broadcast, 7);
        socket_close($sock);
        }    
    }
}  //end function wol
?>

Since the split() function was removed from PHP 7.0.0, this script uses preg_split() to be compatible with current and previous PHP versions.

Replace XX:XX:XX:XX:XX:XX in the HTML with your target MAC to test the script.

Stereotomy answered 20/5, 2018 at 15:31 Comment(2)
I don't think that is a very good idea at all. I can imagine a company retiring some old application servers and leaving them racked, then forgetting about them. Along comes a spider and bam! I start brodcasting WOL for every popular server NIC overnight and you come in the next morning to find tons of IP conflicts and garbage database connections... Not to mention the security vulnerabilities introduced by a bunch of old, unpatched servers suddenly appearing back on the network.Lineation
Yes, thats a good security tip. You would not want this on a public web page. This is the kind of tool you use on your home, private network, to power on your pc's from a simple, private web page.Stereotomy
R
0

Building upon the previous answers. Had to set udp port to 9 and repeat the MAC a couple more times before it worked for me:

function wol($mac)
{
    $hwaddr = pack('H*', preg_replace('/[^0-9a-fA-F]/', '', $mac));

    // Create Magic Packet
    $packet = sprintf(
        '%s%s',
        str_repeat(chr(255), 6),
        str_repeat($hwaddr, 20)
    );

    $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

    if ($sock !== false) {
        $options = socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, true);

        if ($options !== false) {
            socket_sendto($sock, $packet, strlen($packet), 0, "255.255.255.255", 9);
            socket_close($sock);
        }
    }
}
Rossman answered 26/6, 2020 at 9:26 Comment(1)
May as well then make the port/repeats optional. However; I've had no luck getting any of these examples to work. For some reason when using "homebrew's" 'wakeonlan', I would see the packet appear in packetsender (set to receive UDP on port 9), but not when using the above script. I'm guessing it may be due to PHP running in docker though.Awestricken
A
-1

Please read if you're running PHP in Docker, otherwise disregard this.

It seems that UDP broadcast from docker isn't being routed properly (possibly only broadcasted in the container itself, not on the host).

You may try setting (CLI) --network host or (compose) network_mode: host, but for PHP this was causing issues.

You can't send UDP WoL messages directly, as the device you're trying to control is 'offline' it doesn't show up in your router's ARP table and thus the direct message can't be delivered.

I ended up running @reboot root /usr/bin/php -S 0.0.0.0:8877 -t /home/user/php and putting the wol.php file there.

As a 'more proper' solution you may run an 'wol proxy' docker container that does exactly that (but then in a network host privileged docker container).

Awestricken answered 9/4, 2021 at 9:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.