lunes, 6 de octubre de 2008

Redes - Crear un WakeOnLan en Java

Algunas computadoras tiene en el BIOS una opcion de configuracion llamada WakeOnLan. lo que hacen es hacer que la tarjeta de red espere un mensaje especifico para provocar que la computadora se encienda.

Como lo hace?

Cuando un paquete (UDP) es transmitido a todas las computadoras y este contiene una cadena que empieza con seis veces el byte cero (0xff) y luego 16 veces la cadena de bytes que representan el MAC Address de una maquina y esta maquina tiene habilitado el WakeOnLan, al recibir los primeros 6 ceros esperara a recibir el resto de la cadena y finalmente si recibe 16 veces su propio MAC Address entonces enviara una señal a la computadora para encenderse.


Aqui esta un ejemplo de como se implementaria un objeto capaz de hacerlo



import java.net.*;

public class WakeOnLan {

public static final int PUERTO = 9;

private String ipAddress;
private String macAddress;

public WakeOnLan(String ipAddress, String macAddress) {
this.ipAddress = ipAddress;
this.macAddress = macAddress;
}

private byte[] obtenerMacAddressBytes(String macStr) throws IllegalArgumentException {
byte[] bytes = new byte[6];
String[] hex = macStr.split("(\\:|\\-)");
if (hex.length != 6) {
throw new IllegalArgumentException("El MAC Address es invalido");
}
try {
for (int i = 0; i < 6; i++) {
bytes[i] = (byte) Integer.parseInt(hex[i], 16);
}
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("El MAC Address es invalido");
}
return bytes;
}


public void wakeUp() {
try {
byte[] macBytes = obtenerMacAddressBytes(macAddress);
byte[] bytes = new byte[6 + 16 * macBytes.length];
for (int i = 0; i < 6; i++) {
bytes[i] = (byte) 0xff;
}
for (int i = 6; i < bytes.length; i += macBytes.length) {
System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
}

InetAddress address = InetAddress.getByName(ipAddress);
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, PUERTO);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();

System.out.println("Se ha enviado el paquete");
}
catch (Exception e) {
System.out.println("No se pudo enviar el paquete: " + e.getMessage());
System.exit(1);
}

}

public static void main(String[] args) {

if (args.length != 2) {
System.out.println("Uso: java WakeOnLan ");
System.out.println("Ejempolo: java WakeOnLan 192.168.0.255 00:0D:61:08:22:4A");
System.out.println("Ejemplo: java WakeOnLan 192.168.0.255 00-0D-61-08-22-4A");
System.exit(1);
}

new WakeOnLan(args[0], args[1]).wakeUp();

}

}

No hay comentarios: