Trying to make php wake on lan work (via internet).
Through wolcmd program I can successfully turn on server from internet with command:
/Users/usr/Downloads/wolcmd [mac] [public IP] 255.255.255.255 1009
So there is no router/server issue.
I've found several php scripts on internet, but non of them work! :S
tried:
<?php
flush();
function WakeOnLan($addr, $mac,$socket_number) {
$addr_byte = explode(':', $mac);
$hw_addr = '';
for ($a=0; $a <6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a]));
$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
for ($a = 1; $a <= 16; $a++) $msg .= $hw_addr;
// send it to the broadcast address using UDP
// SQL_BROADCAST option isn't help!!
$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if ($s == false) {
echo "Error creating socket!\n";
echo "Error code is '".socket_last_error($s)."' - " . socket_strerror(socket_last_error($s));
return FALSE;
} else {
// setting a broadcast option to socket:
$opt_ret = socket_set_option($s, 1, 6, TRUE);
if ($opt_ret < 0) {
echo "setsockopt() failed, error: " . strerror($opt_ret) . "\n";
return FALSE;
}
if (socket_sendto($s, $msg, strlen($msg), 0, $addr, $socket_number)) {
echo "Magic Packet sent successfully!";
socket_close($s);
return TRUE;
} else {
echo "Magic packet failed!";
return FALSE;
}
}
}
// Port number where the computer is listening. Usually, any number between 1-50000 will do. Normally people choose 7 or 9.
$socket_number = "1009";
// MAC Address of the listening computer's network device
$mac_addy = "XX:XX:XX:XX:XX:XX";
// IP address of the listening computer. Input the domain name if you are using a hostname (like when under Dynamic DNS/IP)
$ip_addy = gethostbyname("name.dyndns.org");
WakeOnLan($ip_addy, $mac_addy,$socket_number)
?>
This script gives me success, but server doesn't wake up. Plus there is no way to specify: 255.255.255.255
I also tried to use packet sniffer on my laptop (not server) and I didn't see any UDP packages arrive.
Another script I tried is this:
<?php
//
// ################## user variables... ##################
// Friendly name for device, example "My Computer".
$device = "Server";
// IP address of device, example "x.x.x.x".
$deviceip = gethostbyname("name.dyndns.org");
// TCP Port on device to check, example "3389" = RDP, "80" = WebServer.
$deviceport = "1009";
// MAC address of NIC1 on device, example "00:00:00:00:00:00" or "00-00-00-00-00-00".
$devicemac1 = "XX:XX:XX:XX:XX:XX";
// MAC address of NIC2 on device, example "00:00:00:00:00:00" or "00-00-00-00-00-00". - Optional set to "" if NIC2 not required.
$devicemac2 = "";
// Number of times to attempt to connect to port on device after magic packet sent, example "10"
$maxtries = "5";
// Broadcast address of network, example ""x.x.x.x". ("255.255.255.255" works in most cases.)
$broadcast = "255.255.255.255";
// ICMP port number, default "7".
$udport = "1009";
// Timeout value for re-tries (in seconds), default "10".
$timeout = "5";
// #######################################################
//
// ##### Read in variables from url #####
//
// $frame - used to determine which content to display when executed.
$frame = $_GET[ "frame" ];
// $tries - used to determine number of attempts at checking port beetween reloads, compared with maxtries.
$tries = $_GET[ "tries" ];
// $pageurl - obtain URL used to access file, used when creating frameset & setting reloads.
$pageurl = pageurl();
// Process variables used in frame2, increments tries & sets status to Success(1) or Failed(2)
if ( $frame == 2 ) {
processurl();
}
// ###### Functions ######
//
// function pageurl( ) - Returns URL of page via PHP variables.
function pageurl() {
$pageurl = "HTTP";
if ( $_SERVER[ "HTTPS" ] == "on" ) {
$pageurl .= "S";
}
$pageurl .= "://";
if ( $_SERVER[ "SERVER_PORT" ] != "80" ) {
$pageurl .= $_SERVER[ "SERVER_NAME" ] . ":" . $_SERVER[ "SERVER_PORT" ] . $_SERVER[ "REQUEST_URI" ];
} else {
$pageurl .= $_SERVER[ "SERVER_NAME" ] . $_SERVER[ "REQUEST_URI" ];
}
$urlarts = explode( "?", $pageurl );
$pageurl = $urlarts[ "0" ];
return $pageurl;
}
// function processurl( ) - Processes variables used in frame2, increments tries & sets status to Success(1) or Failed(2)
function processurl() {
global $status, $tries, $maxtries;
if ( $status == 0 && $tries < $maxtries - 1 ) {
$tries = $tries + 1;
} else {
$status = 2;
}
if ( portcheck() == 0 ) {
$status = 1;
}
}
// function wakeonlan() - Attempts to send WoL packet and returns outcome.
function wakeonlan( $device, $mac ) {
global $broadcast, $udport;
$mac = ereg_replace( "[^A-Za-z0-9]", ":", $mac );
$broadcast_byte = explode( ':', $mac );
$hw_addr = '';
for ( $a = 0; $a < 6; $a++ )
$hw_addr .= chr( hexdec( $broadcast_byte[ $a ] ) );
$msg = chr( 255 ) . chr( 255 ) . chr( 255 ) . chr( 255 ) . chr( 255 ) . chr( 255 );
for ( $a = 1; $a <= 16; $a++ )
$msg .= $hw_addr;
$s = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
if ( $s == false ) {
$content = "Error creating socket!\n";
} else {
// setting a broadcast option to socket:
$opt_ret = socket_set_option( $s, 1, 6, true );
if ( $opt_ret < 0 ) {
$content = "setsockopt() failed, error: " . strerror( $opt_ret ) . "\n";
}
if ( socket_sendto( $s, $msg, strlen( $msg ), 0, $broadcast, $udport ) ) {
$content = "WoL packet sent to mac address " . $mac . "...\n";
socket_close( $s );
} else {
$content = "Failed to send WoL packet!";
}
}
return $content;
}
// function portcheck( ) - Attempts to connect to TCP port on the device via a Socket, returns $errno.
function portcheck() {
global $deviceip, $deviceport;
$file = fsockopen( $deviceip, $deviceport, $errno, $errstr, 50 );
if ( $errno == 0 ) {
fclose( $file );
}
return $errno;
}
// function htmlheader( ) - Returns HTML Header for TITLE and if Frame2 REFRESH set.
function htmlheader() {
global $device, $frame, $tries, $maxtries, $status, $pageurl, $timeout;
// global "custom" header settings
$content = "<TITLE>PHP WoL ($device) - by PRThomasUK </TITLE>\n";
//generate refresh header for frame2.
if ( $frame == 2 && $status == 0 ) {
$content .= "<META HTTP-EQUIV=\"refresh\" CONTENT=\"$timeout;url=$pageurl?frame=$frame&tries=$tries\">\n";
}
return $content;
}
// function htmlheader( ) - Returns HTML content for mainpage, frame1 & frame2 based on value of $frame.
function htmlcontent() {
global $pageurl, $device, $deviceip, $deviceport, $devicemac1, $devicemac2, $frame, $tries, $maxtries, $status;
if ( $frame == 2 ) {
if ( $status == 0 ) {
$content = "<H3>$tries/$maxtries attempts to connect to $deviceip:$deviceport completed.</H3>\n";
} elseif ( $status == 1 ) {
$content = "<FONT COLOR=\"green\">\n";
$content .= "<H1>SUCCESS!!!</H1>\n";
$content .= "</FONT>\n";
$content .= "<H3>Connection made to $device ($deviceip:$deviceport).</H3>\n";
} else {
$content = "<FONT COLOR=\"red\">\n";
$content .= "<H1>FAILED...</H1>\n";
$content .= "</FONT>\n";
$content .= "<H3>Unable to connect to $device ($deviceip:$deviceport).</H3>\n";
}
} elseif ( $frame == 1 ) {
$content = "<FONT COLOR=\"navy\">\n";
$content .= "<H1>PHP WoL ($device)</H1>\n";
$content .= "</FONT>\n";
$content .= wakeonlan( $device, $devicemac1 );
if ( $devicemac2 ) {
$content .= "<BR>\n";
$content .= wakeonlan( $device, $devicemac2 );
}
} else {
$content = "<FRAMESET rows=\"130,*\" frameborder=0 border=0 framespacing=5>\n";
$content .= "<FRAME SRC=\"$pageurl?frame=1\">\n";
$content .= "<FRAME SRC=\"$pageurl?frame=2\">\n";
$content .= "<NOFRAMES>\n";
$content .= "<FONT COLOR=\"navy\">\n";
$content .= "<H1>PHP WoL ($device)</H1>\n";
$content .= "</FONT>\n";
$content .= wakeonlan( $device, $devicemac1 );
if ( $devicemac2 ) {
$content .= "<BR>\n";
$content .= wakeonlan( $device, $devicemac2 );
}
$content .= "<BR>\n";
$content .= "<BR>\n";
$content .= "<FONT COLOR=\"red\">\n";
$content .= "<H2>Your browser does not support frames...</H2>\n";
$content .= "</FONT>\n";
$content .= "<H3>Status of $device will not be monitored!</H3>\n";
$content .= "</NOFRAMES>\n";
$content .= "</FRAMESET>\n";
}
return $content;
}
?>
<!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd">
<HTML>
<HEAD>
<?php
echo htmlheader();
?>
<META NAME="author" CONTENT="PRThomasUK">
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=utf-8">
<META HTTP-EQUIV="cache-control" CONTENT="no-cache">
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META NAME="robots" CONTENT="none">
<META NAME="rating" CONTENT="safe for kids">
</HEAD>
<?php
echo htmlcontent();
?>
</HTML>
here problematic is $deviceport = "1009"; if I specify 80 it tells me host is down... but that I know already :) that's why I'm sending magic packet right?...
Please can someone with experience in this help? I'm out of ideas to try.
EDIT 2015
Well, I've cleaned up my process, this works perfectly: https://github.com/wearede/wake-on-wan
old
It works now! I can wake up my server by simply visiting a subdomain wol.domain.com :) cool.
Lesson learned: above script wasn't functioning because I had mis-configured router. As you can see from the script, correct port is 1009. On router I had it set-up incoming port 1009 redirecting wihin lan to port 9. For some reason (maybe because it's UDP?) 1009->9 isn't working. I did 1009->1009 and server did wake up!
Final code I used: