Portfolio
Tutorials

PHP Tutorial

Info Wake on LAN with Magic Packets
Dec 29th, 14 • Views: 6191
How to wake a computer from sleep mode on your local network using a Magic Packet.

This is less of a tutorial and more of a "hey this is cool" so I figured I'd share and at least try to be a little descriptive (so I can pretend it's a tutorial)

Before we begin though, I want to give credit to the posts that enabled me to put this together (as I literally copied one of them and tweaked another):
socket_sendto(): A specific comment from "ole" on the reference at php.net.
wake on lan (php) cannot get it to work: StackOverflow for the win.
Wake-on-LAN: Wikipedia. Because where would we be without it?

Also, to actually use this, make sure your computer's NIC is setup to allow the device to wake the computer and only when a magic packet is sent. If you don't restrict it to only wake on magic packets, it could wake on any request to the computer (which is nice in its own right, but sometimes you would rather not wake it up accidentally).
<?php
/** Generates the magic packet that will be broadcast over UDP */
function generate_packet($mac){
	$addr_byte = explode(':', $mac);
	for($x = 0; $x < count($addr_byte); $x++)
		$addr_byte[$x] = chr(hexdec($addr_byte[$x]));
 
	return str_repeat(chr(0xFF), 6) . str_repeat(implode($addr_byte), 16);
}
 
/** Create the socket and broadcast the message for the given MAC address */
function wake_on_lan($mac){
	// Create a socket for the UDP broadcast
	$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
 
	if($socket == false){
		echo "Error creating socket!\n";
		echo "Error code is '" . socket_last_error($socket) . "' - " . socket_strerror(socket_last_error($socket));
		return false;
	}else{
		// Setting the broadcast option to socket
		$opt_ret = socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1);
 
		if($opt_ret < 0){
			echo "setsockopt() failed, error: " . strerror($opt_ret) . "\n";
			return false;
		}
 
		$msg = generate_packet($mac);
		// Don't know why I'm using port 4000 but it seems to work.
		$sent = socket_sendto($socket, $msg, strlen($msg), 0, '255.255.255.255', 4000);
		socket_close($socket);
		return $sent;
	}
}
 
// Replace with your NICs MAC address
if(wake_on_lan('XX:XX:XX:XX:XX:XX')){
	echo 'Magic Packet sent successfully! Pinging...';
 
	// We tried to wake it up, ping it until we are positive it is awake
	$ping = '';
	do{
		// Replace the capital letters here
		$ping = shell_exec('ping HOSTNAME_OR_IP_ADDRESS_YOU_ARE_WAKING');
		echo "\n" . $ping;
	} while(strpos($ping, '(0% loss)') === false);
}else{
	echo "Magic packet failed!\nPress any key to continue...";
 
	// Windows, pause so we can see errors
	shell_exec('pause');
 
	/*
	Linux?
	http://stackoverflow.com/questions/92802/what-is-the-linux-equivalent-to-dos-pause
	shell_exec('read -n1 -r key');
	*/
}
?>

With that you should be able to wake up any machine on your local network. That means you won't be able to put it on a shared host somewhere and wake anything up. Google can help if you really want to do something like that. But it'll involve port forwarding on your home router.

If you have PHP installed on your computers PATH at home then you can also create a shortcut with the following to wake your computer up in just a few clicks of a button:
php C:\path\to\wol.php