Wake-on-LAN
Wake-on-LAN (WOL; в переводе с англ. — «пробуждение по [сигналу из] локальной сети») — технология, позволяющая удалённо включить компьютер посредством отправки через локальную сеть специальной последовательности байтов — пакета данных (так называемого magic packet — «волшебного пакета», см. ниже). Этот пакет может быть вставлен в пакеты любых стандартных протоколов более высоких уровней, например, UDP или IPX.
Требования к компьютеру для работы с Wake-on-LAN
- Компьютер с источником питания, соответствующим стандарту ATX 2.01, и материнской платой, поддерживающей Wake-on-LAN;
- Сетевая плата (в виде платы расширения либо встроенная в материнскую плату) с поддержкой Wake-on-LAN;
- Если используется внешняя (не встроенная в материнскую плату) сетевая плата, и хотя бы одна из этих плат не соответствуют стандарту PCI 2.2 или более позднему, то необходим также специальный трёхпроводной кабель для соединения разъёмов Wake-on-LAN на материнской и сетевой платах.
- Как для интегрированного, так и для внешнего сетевого адаптера, как правило, требуется включение Wake-on-LAN в настройках BIOS материнской платы.
Кроме того, необходима возможность послать magic packet управляемому компьютеру. Это можно сделать, например, с помощью другого компьютера с соответствующей программой (см. примеры ниже).
Принцип работы
Управляемый компьютер находится в дежурном режиме (англ. stand-by — режим, предусмотренный спецификацией ATX, при котором из всех выходных цепей блока питания активна только дежурная +5VSB) и выдаёт питание на микросхему BIOS и сетевой адаптер[1]. Сетевой адаптер находится в режиме пониженного энергопотребления, при этом его микроконтроллер анализирует все пакеты, приходящие на соответствующий MAC-адрес, ничего не отвечая на них. Если одним из пакетов окажется magic packet, сетевой адаптер выдаст сигнал на включение питания компьютера.
Magic packet
англ. Magic packet — это специальная последовательность байтов, которую для нормального прохождения по локальным сетям можно вставить в пакеты транспортного уровня, не требующие установки соединения (например, протокол UDP или устаревший IPX). Обычно для Wake-on-LAN пакеты протоколов верхнего уровня рассылают широковещательно, так как в случае динамического присвоения адресов неизвестно, какой IP-адрес соответствует какому MAC-адресу. Однако, для корректного прохождения через маршрутизатор, запрещающий широковещательные пакеты, можно послать пакет по какому-то определённому адресу.
В начале пакета идет так называемая цепочка синхронизации: 6 байт, равных 0xFF. Затем — MAC-адрес сетевой платы, повторённый 16 раз. То есть, если бы адрес платы выглядел как 01:02:03:04:05:06, то магический пакет оказался бы таким:
FFFFFFFFFFFF010203040506 010203040506010203040506 010203040506010203040506 010203040506010203040506 010203040506010203040506 010203040506010203040506 010203040506010203040506 010203040506010203040506 010203040506
Примеры
Программы
- Wake On Lan через Интернет — http://wakeonlan.ru/
- Для Linux — https://web.archive.org/web/20070121141809/http://gsd.di.uminho.pt/jpo/software/wakeonlan/mini-howto/wol-mini-howto-3.html#ss3.1
- FreeBSD - начиная с 8.0-RELEASE содержит утилиту wake — http://www.freebsd.org/cgi/man.cgi?query=wake&sektion=8&manpath=FreeBSD+8.0-RELEASE
- Для Maemo 4 (Nokia Internet Tablet N800/N810) — http://fernando.mercado.googlepages.com/maemowol
- woncli — консольная утилита для Windows — http://www.relvarsoft.com/woncli.html
- MultiWOL — CGI скрипт на Perl для многопользовательского окружения — http://multiwol.sourceforge.net/
- WakeMeOnLan — http://www.nirsoft.net/utils/wake_on_lan.html
- Инструмент RouterOS Wake-on-LAN
Исходники
Задача написания программы, посылающей магический пакет, достаточно проста и часто дается как учебная при изучении основ работы с сетью. Ниже представлено два примера таких программ в исходных кодах:
using System;
using System.Net.Sockets;
using System.Net;
using System.Collections.Generic;
namespace Wol
{
class Program
{
static void Main(string[] args)
{
using (UdpClient udpClient = new UdpClient())
{
Console.WriteLine("Enter mac address");
byte[] mac = StrToMac(Console.ReadLine());
udpClient.Send(mac, mac.Length, new IPEndPoint(IPAddress.Broadcast, 9));
}
}
static byte[] StrToMac(string s)
{
List<byte> arr = new List<byte>(102);
string[] macs = s.Split(' ', ':', '-');
for (int i = 0; i < 6; i++)
arr.Add(0xff);
for (int j = 0; j < 16; j++)
for (int i = 0; i < 6; i++)
arr.Add(Convert.ToByte(macs[i], 16));
return arr.ToArray();
}
}
}
Адаптирован для версии Delphi7.
unit WOL;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent,IdComponent,IdUDPBase,IdUDPClient,IdGlobal,
StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TMACAddress = packed record
case integer of
0: (s1,s2,s3,s4,s5,s6 : byte; );
1: (cmp1:word; cmp2:integer;);
end;
TWakeupMagicPacket = packed record
FillFF : array [0..5] of byte;
Mac : array [0..15] of TMACAddress;
end;
function TryStrToMac(str:string; var mac:TMACAddress):boolean;
var a,b:integer;
const ToHex = '0123456789ABCDEF';
begin
Result:=false;
str:=AnsiUpperCase(trim(str));
if length(str)<17 then begin
mac.cmp1:=0;
mac.cmp2:=0;
exit;
end;
a:=pos(str[1],ToHex)-1; b:=pos(str[2],ToHex)-1;
if((a>=0)and(b>=0)and(str[3]='-')) then mac.s1:=a*16+b else exit;
a:=pos(str[4],ToHex)-1; b:=pos(str[5],ToHex)-1;
if((a>=0)and(b>=0)and(str[6]='-')) then mac.s2:=a*16+b else exit;
a:=pos(str[7],ToHex)-1; b:=pos(str[8],ToHex)-1;
if((a>=0)and(b>=0)and(str[9]='-')) then mac.s3:=a*16+b else exit;
a:=pos(str[10],ToHex)-1; b:=pos(str[11],ToHex)-1;
if((a>=0)and(b>=0)and(str[12]='-')) then mac.s4:=a*16+b else exit;
a:=pos(str[13],ToHex)-1; b:=pos(str[14],ToHex)-1;
if((a>=0)and(b>=0)and(str[15]='-')) then mac.s5:=a*16+b else exit;
a:=pos(str[16],ToHex)-1; b:=pos(str[17],ToHex)-1;
if((a>=0)and(b>=0)) then mac.s6:=a*16+b else exit;
Result:=true;
end;
function TryWakeUpComputer(const MacAddress: string):boolean;
var i : integer;
mac : TMACAddress;
pkt : TWakeupMagicPacket;
begin
Result := false;
if not TryStrToMac(MacAddress,mac) then exit;
FillChar(pkt.FillFF[0],SizeOf(pkt.FillFF),$FF);
for i:=0 to High(pkt.Mac) do pkt.Mac[i]:=mac;
with TIdUDPClient.Create(nil) do try
BroadcastEnabled := True;
Host := '255.255.255.255';
Port := 9;
SendBuffer(pkt,sizeof(pkt));
Result := true;
finally
Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not TryWakeUpComputer(Edit1.Text) then \\Мак вида BC-AE-C5-8E-0A-2C
begin
// Do something...
showmessage('ERROR');
end;
end;
Примечания
- Некоторые компьютеры необходимо включить вручную хотя бы один раз после установки сетевой платы. При этом включении компьютер обнаружит сетевую плату и в дальнейшем запомнит, на какое именно устройство следует подавать питание. Другим возможным решением может быть установка в BIOS параметра Wake After Power Fail («пробуждаться после пропадания питания») в значение On («Вкл.»)