
import java.net.*;

public class Jwol {

   
    public static void main(String[] args) {
        
        //kdyz se pocet argumentu nerovna 2
        if(args.length != 2) {
            WOL.help();
            System.exit(1);
        }
        /*  -----------------------------
         * | vytvoreni objektu tridy WOL |
         *  -----------------------------
         * -> prvni vstupni retezec udava IP broadcastu
         * -> a druhy MAC adresu probouzeneho pocitace
         */
        WOL wol = new WOL(args[0], args[1]);
        //zavolani metody, ktera odelse magicky packet
        wol.send();
    }
}


/*****************************
 * Wake On Lan Java class    *
 *****************************
 * 
 * Autor: Pavel Novák
 * -> http://pavel-novak.net
 */

class WOL {
    
    //promenne
    private InetAddress ip;
    private final int port = 9;
    private byte[] mac = new byte[6];
    private byte[] byty = new byte[6 + 16 * mac.length];
    private DatagramPacket packet;
    private DatagramSocket soket;
    
    //konstruktor
    public WOL(String broadcast, String mac) {
        
        isIP(broadcast);
        MacByty(mac);
        createPacket();
    }
    
    //metoda zarizujici prirazeni vstupni IP broadcastu na InetAddress
    private void isIP(String s) {
        
        try {
            ip = InetAddress.getByName(s);
        } catch (UnknownHostException ex) {
            System.err.println("Zadana IP broadcastu je ve spatnem formatu!");
            help();
            System.exit(1);
        }
    }
    
    //metoda, ktera prevede MAC adresu na pole bytu
    private byte[] MacByty(String s) {
    
        String reg = "^[:0-9A-F]{17}$";
        if(!s.toUpperCase().matches(reg)) {
            System.err.println("Zadana MAC adresa je ve spatem formatu!");
            help();
            System.exit(1);  
        } else {
            String[] pole = s.toUpperCase().split(":");
            for(int i = 0;i < 6;i++) {
                mac[i] = (byte) Integer.parseInt(pole[i], 16);
            }
        }
        return mac;
    }
    
    //metoda, ktera vytvori datagram - magicky packet
    private void createPacket() {
        
        try {
            for(int i = 0; i < 6;i++) {
                byty[i] = (byte) 0xff;
            }
            for (int i = 6; i < byty.length; i += mac.length) {
                System.arraycopy(mac, 0, byty, i, mac.length);
            }
            packet = new DatagramPacket(byty, byty.length, ip, port);
        } catch(Exception ex) {
            help();
            System.exit(1);
        }
    }
    
    //metoda, ktera odesle datovy ramec
    public void send() {
    
        try{
            soket = new DatagramSocket();
            soket.send(packet);
            soket.close();
        } catch(Exception ex) {
            System.err.println(ex);
            System.exit(1);
        }
        System.out.println("Magicky packet uspesne odeslan.");
    }
    
    //metoda vypisujici pouziti programu
    public static void help() {
    
        System.out.println("\n********************\n" +
                           "* Java Wake on LAN *\n" +
                           "********************\n");
        System.out.println("Pouziti:");
        System.out.println("java -jar wol.jar [broadcast IP] [MAC]");
        System.out.println("Priklad:");
        System.out.println("java -jar wol.jar 192.168.1.255 00:F3:D4:B2:02:F1");
    }
}