poniedziałek, 14 lipca 2014

Wake On Lan (WOL) - Lokalne włączanie komputerów

Wake On Lan to metoda włączania komputerów poprzez sieć lokalną (LAN).
Polega ona na wysłaniu Magic Packet do karty sieciowej, która przesyła informację do płyty głównej o potrzebie załączenia się. Jeżeli chodzi o laptopy to ta funkcja również jest dostępna tylko musi mieć zewnętrzne źródło zasilania, na baterii funkcja WOL nie działa.

Chcąc załączyć komputer, musimy znać jego MAC adres karty sieciowej.

Z programistycznego punktu widzenia, potrzebujemy napisać program, który będzie wyśle najpierw 0xFFFFFFFFFFFF, a następnie 16x Mac adres - na podany mac adres.

Dla design'u aplikacji wystarczy TextBox i Button.

Tworzymy event dla przycisku:
private void button1_Click_1(object sender, EventArgs e)
{
    try
    {
        SendMagicPacket(textBox1.Text);
        MessageBox.Show("Packet Sent to " + textBox1.Text);
    }
    catch (Exception ex) { MessageBox.Show("Error:\n\n" + ex.Message, "Error"); }
}

Przycisk jest już gotowy, pozostała tylko funkcjonalność:
public static void SendMagicPacket(string macAddress)
{
    if (!Test(macAddress))
        throw new ArgumentException("Niepoprawny MAC adres", "macAddress", null);

    byte[] mac = ConvToByte(macAddress);
    WakePC(mac);
}

Musimy też sprawdzić czy wprowadzony mac adres jest poprawny, jak widać powyżej jest funkcja Test().
public static bool Test(string macAddress)
{
    var valid_chars = "0123456789ABCDEFabcdef";
    if (string.IsNullOrEmpty(macAddress)) return false;
    if (macAddress.Length != 12) return false;
    foreach (var c in macAddress)
    {
        if (valid_chars.IndexOf(c) < 0) { return false; }
    }
    return true;
}
Gdy nasz Mac adres jest poprawny, to rozkładamy go na bajty funkcja ConvToByte():
public static byte[] ConvToByte(string macAddress)
{
    byte[] mac = new byte[6];
    if (!Test(macAddress))
        throw new ArgumentException("Niepoprawny MAC adres", "macAddress", null);

    for (var i = 0; i < 6; i++)
    {
        var t = macAddress.Substring((i * 2), 2);
        mac[i] = Convert.ToByte(t, 16);
    }
    return mac;
}
Ostatnim krokiem będzie wysłanie, przed chwilą otrzymanych bajtów, do karty sieciowej, ale przed tym jeszcze sprawdzenie czy nasze bajty zostały poprawnie przekonwertowane.
public static bool TestByteArray(byte[] macAddress)
{
    if (macAddress == null) return false;
    if (macAddress.Length != 6) return false;
    return true;
}
public static void WakePC(byte[] macAddress)
{
    if (!TestByteArray(macAddress))
        throw new ArgumentException("Niepoprawny MAC adres", "macAddress", null);

    using (UdpClient client = new UdpClient())
    {
        client.Connect(IPAddress.Broadcast, 40000);
        byte[] packet = new byte[17 * 6];
        for (int i = 0; i < 6; i++) { packet[i] = 0xFF; }
        for (int i = 1; i <= 16; i++)
        {
            for (int j = 0; j < 6; j++)
            {
                packet[i * 6 + j] = macAddress[j];
            }
        }
        client.Send(packet, packet.Length);
    }
}
Poniżej obrazek jak aplikacja wygląda i jak powinno się wpisywać Mac adres :)



Enjoy !