Freigeben über


Wake on Lan depuis votre téléphone

Soyez green, faites des économies d’énergie! Quoi, vous avez un serveur à la maison? assassin! Il ne sert pas forcément toute la journée en continu!

Oui, mais le problème c’est qu’on a pas forcément idée de quand on pourrait en avoir besoin… il faudrait pouvoir l’allumer et l’éteindre à distance juste quand on en a besoin. La fonction Wake-On-Lan de la majorité des cartes mères récentes (traduisez, ATX, ca fait quand même un bail) est là pour ça: elle permet en envoyant un “magic packet” sur le port ethernet de réveiller la machine: c’est comme appuyer sur le bouton “ON” à distance.

Ce qu’on va faire en quelques lignes, c’est écrire un petit programme qui nous permet de réveiller le PC ou son serveur à distance avec son téléphone mobile.

Le “magic packet” est composé de 6 fois 0xFF suivi de 16 fois l’adresse MAC de la machine à réveiller: facile à générer!

 Byte[] OutputBuffer = new Byte[102];

/* The first 6 bytes */
for (int i = 0; i < 6; i++)
    OutputBuffer[i] = 0xFF;

/* Then we parse the mac address, and put it into an intermediate buffer */
String StrippedMacAddress = Regex.Replace(tbMac.Text, "[^a-f0-9]", "");

if (StrippedMacAddress.Length != 12)
{
    MessageBox.Show("Please enter the mac address formatted as xx:xx:xx:xx:xx:xx");
    return;
}

Byte[] MacAddressBuffer = new Byte[6];
for (int i = 0; i < 6; i++)
{
    String s = StrippedMacAddress.Substring(i * 2, 2);
    MacAddressBuffer[i] = Byte.Parse(s, System.Globalization.NumberStyles.HexNumber);
}

/* Then we copy this Mac address 16 times */
for (int i = 6; i <= 96; i+=6)
    MacAddressBuffer.CopyTo(OutputBuffer, i);

Plusieurs choses à souligner dans ce petit bout de code:

  • D’abord l’utilisation de l’expression régulière permet de ne pas avoir à s’occuper de savoir comment l’utilisateur formatte son adresse mac (avec des :, ou des – ou des .). Ensuite on teste le nombre de caractères, c’est basique, et pas forcément élégant mais bon ca évite que l’utilisateur ne rentre n’importe quoi. Certes certain format “corrects” ne passeraient pas le test, mais on veut aussi garder le code simple :)
  • Pour la copie x16 de l’adresse MAC, il vaut mieux la convertir en tableau de byte avant… Dans le code dont je me suis inspiré, celui qui avait écrit le code refaisait un parsing de la chaine de caractère à chaque itération! Sur ce genre de petits bouts de code, le gain en optimisation n’est pas forcément critique, mais ca ne doit pas empêcher de faire les choses intelligement, car sur un téléphone mobile, il y a d’autres applications qui tournent en même temps! :)
  • Pour l’incrément de boucle, il peut paraitre étrange, à la base j’avais écrit ça:
 for (int i = 1; i <= 16; i++)
    MacAddressBuffer.CopyTo(OutputBuffer, i*6);

L’incrément est plus classique (i++) mais du coup on fait une multiplication à chaque fois. j’ai les multiplications en horreur (ça coute cher dans un micro embarqué) donc je préfère les éviter en utilisant i+=6. c’est surement du snobisme, mais bon… en attendant je gagne un tout petit peu de batterie :)

Bref, il reste à envoyer ce “magic packet”, et c’est l’affaire de quelques lignes:

 /* We're finally ready to send the packet, so let's do it! */
try
{
    IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(tbIpAddress.Text), int.Parse(tbPort.Text));
    UdpClient myUdpClient = new UdpClient();
    myUdpClient.Send(OutputBuffer, OutputBuffer.Length, remoteEndPoint);
    myUdpClient.Close();
}
catch (Exception ex)
{
    MessageBox.Show("Problem sending the WOL Datagram:\r\n" + ex.Message, "Datagram not sent", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
}

 

Je n’inclue pas le code du formulaire, archi-simple, qui contient 3 text box et deux soft keys (à préférer aux boutons, non disponible dans le SDK standard pour les terminaux sans touchscreen!): un pour quitter, un pour lancer envoyer le magic packet: Vous aurez compris que tbMac est la TextBox pour l’adresse MAC, tbIpAddress pour l’adresse IP, et tbPort le numéro de port.

Quoi, un numéro de port???

Ben oui, parce que le serveur il est derrière une box, et donc il faut paramétrer la box pour laisser passer le magic packet par un certain port: choisissez celui qui vous plait! en fait la machine à réveiller n’en a rien à faire, du port sur lequel elle reçoit le magic packet: c’est juste histoire de passer le firewall!

Merci Blaise pour l’idée, le bout de code de référence (même si c’était du VB!)!

Comments

  • Anonymous
    March 19, 2009
    Domage qu'il soit si rare de pouvoir envoyer des trames UDP depuis un portable.

  • Anonymous
    March 21, 2009
    rare? y'aurait-il des opérateurs qui bloqueraient le traffic UDP sur les connections data?

  • Anonymous
    March 27, 2009
    Je prends l'exemple du pass surf 2.0 de SFR, il ne laisse passer que du tcp sur le 80 ou 443, en clair le http et le https. Mon wakeonlan étant sur le port 9 (via le routeur de ma freebox) je ne peux donc pas le faire depuis mon téléphone. Sauf si je passe par un serveur web qui propose ce service.

  • Anonymous
    March 27, 2009
    Damned, les arcanes des forfaits data des opérateurs... ils ne pourraient pas libérer les forfaits une bonne fois pour toute!

  • Anonymous
    May 10, 2009
    Moi j'veux bien le code en version VB ;) Où est-ce qu'on peut le trouver (Blaise ?) ?

  • Anonymous
    May 18, 2009
    Blaise n'aura qu'une vieille version :p mais honnêtement, il n'y a pas grand chose à traduire...

  • Anonymous
    March 21, 2010
    Salut, Merci Blaise et Pierreca ! Je me suis servi de votre code pour développer une appli sur mon i900 (WM 6.1) pour le WOL. Elle fonctionne super bien et je suis en train de la parfaire pour l'enregistrement de config dans un xml ainsi que d'autre fonction ("plugin") comme rendormir l'ordinateur. Si vous avez des idées de supplément faire moi suivre. Merci ! BN

  • Anonymous
    May 04, 2010
    The comment has been removed