Michael
Michael

Reputation: 479

Wake on lan script that works

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

Upvotes: 14

Views: 40118

Answers (5)

aaa
aaa

Reputation: 715

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).

Upvotes: -1

Allanrbo
Allanrbo

Reputation: 2358

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);
        }
    }
}

Upvotes: 0

Mez
Mez

Reputation: 24933

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

Upvotes: 14

Ken H
Ken H

Reputation: 331

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.

Upvotes: 2

Ryan Steffer
Ryan Steffer

Reputation: 434

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.

Upvotes: 9

Related Questions