WakeUp on LAN

[Encender una PC remotamente]
(Hecho 100% en C#)

Fecha: 10/Abr/2005 (05/04/2005)
Autor: Diego Jancic - jancic@gmail.com

 


¿¿¿Como funciona???

El WakeUp On Lan, permite encender una pc de forma remota, siempre y cuando la computadora remota lo permita y este habilitado desde el BIOS de la pc. Para permitir el encendido remoto, la pc que se va a encender requiere estar conectada via ethernet (configuracion utilizada en casi todas las redes) y poseer la tecnología ACPI, que aunque es una tecnología bastante antigua, solo es permitido en las computadoras con fuentes ATX, las cuales vienen en todos los modelos desde hace unos cuantos años.

Para permitir el encendido, la computadora debe estar "escuchando" (o listening) en el puerto 9 de la interfaz de red, esto se hace solamente habilitando una opción en el BIOS (siempre y cuando este permitido!). Los mensajes que espera recibir son de cualquier protocolo, aunque se usa UDP por el modelo de coneccion que utiliza.

El protocolo

A la hora de enviar un mensaje, hay que utilizar un protocolo muy sencillo para identificar la pc. La identificación utilizada se basa en la dirección ethernet (Ethernet Address), para ver la dirección ethernet de una pc se puede proceder de muchas formas, aunque las 3 mas comunes que funcionan en Windows/DOS son:

El protocolo esta compuesto por un encabezado igual a 6 caracteres 0xFF (255 en decimal considerando el 0), por lo que quedaria algo como: FFFFFFFFFFFF; despues este encabezado es seguido por la direccion de ethernet 16 veces. es decir si la direccion ethernet es 00-50-BA-87-2C-11, el mensaje completo quedaria asi (sin los espacios y sin los guiones):

FF FF FF FF FF FF - 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11

 

Haciendo la aplicacion en .NET

Para crear el mensaje, lo unico que hay que hacer es crearlo en un array de bytes, es decir un byte[], el largo del mensaje es siempre 102, ya que son 6 bytes del encabezado más 6 bytes de la direccion ethernet multiplicado por 16 veces, es decir 6+6*16=102.

Despues hay que abrir el socket para enviar los datos, lo cual se hace utilizando la clase System.Net.Sockets.Socket, despues se crea un objeto IPEndPoint, el cual especifica a donde va a ser enviado el mensaje, por default yo utilizo la opcion IPAddress.Broadcast para que el mensaje sea enviado a toda la red, pero esto se puede reemplazar por IPAddress.Parse("192.168.0.31"), para que el mensaje sea enviado a un solo ip, en donde 192.168.0.31 es el ip de la maquina a encender, en el constructor del objeto IPEndPoint, tambien hay que especificar un puerto, hay que utilizar el 9 ya que el WakeUp On Lan utiliza este puerto y no es configurable (al menos en la mayoria de los casos).

Por ultimo se utiliza el metodo SendTo para enviar el mensaje, este metodo requiere como argumentos un IPEndPoint y el mensaje a enviar.

Este es el codigo funcionando, o al menos para mi :), si se lo copia en el Main de una aplicacion o en cualquier otro lugar deberia funcionar.

			
byte[] UdpMessage = new byte[102];
			
// Escribo el Header (encabezado) del mensaje
UdpMessage[0] = 0xFF;
UdpMessage[1] = 0xFF;
UdpMessage[2] = 0xFF;
UdpMessage[3] = 0xFF;
UdpMessage[4] = 0xFF;
UdpMessage[5] = 0xFF;
 
for (int Count = 0 ; Count < 16 ; Count++)
{
			
				// Escribo la direccion ethernet 16 veces... 
        int Start = Count*6+6;
        UdpMessage[Start+0] = 0x00;
        UdpMessage[Start+1] = 0x0A;
        UdpMessage[Start+2] = 0xE6;
        UdpMessage[Start+3] = 0x71;
        UdpMessage[Start+4] = 0xCF;
        UdpMessage[Start+5] = 0x05;
}
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 9);
sock.SendTo(UdpMessage, iep);
sock.Close();
			

Espacios de nombres usados en el código de este artículo:

System.Net
System.Net.Sockets


Aplicacion de ejemplo: Diegos_WakeUpOnLan.zip - 16 KB


ir al índice