WAKE ON LAN
Aus VDR Wiki
Inhaltsverzeichnis |
Beschreibung
Mittels Wake on LAN (Abgekürzt: WOL oder WoL) kann der Rechner per Netzwerk eingeschaltet werden. Dies ist z.B. sehr schön, wenn man einen Linux-Router hat, sich per Internet zu diesem verbindet, und dann seinen VDR einschalten kann (um etwa neue Timer zu speichern). Das funktioniert z.B. bei der FritzBox mit Hilfe des Fritz!Box WoL Hack.
Das Einschalten erfolgt meistens durch das sogenante "MagicPacket".
Die Programme müssen das "MagicPacket" erzeugen und an die MAC-Adresse der Netzwerkkarte des aufzuweckenden Rechners schicken.
Möglichkeiten
Browser
Bequem per Browser läßt sich über diesen Wake-On-Lan über Router-Dienst das MagicPacket aus einem Web-Formular senden. Das funktioniert teilweise sogar durch (DSL-) Router hindurch.
Programme
Linux
Ein passendes Linux-Programm ist ether-wake.
Kompiliert wird der Quelltext mit
wget ftp://ftp.scyld.com/pub/diag/ether-wake.c gcc -O -Wall -o ether-wake ether-wake.c cp ./ether-wake /usr/local/bin
Der Aufruf erfolgt so:
ether-wake 00:11:22:33:44:55
Bzw.
ether-wake -p <HOST> 00:11:22:33:44:55
Wobei man für die Zahlenfolge einfach die MAC-Adresse des aufzuweckenden Rechners eingeben muss. Wenn man die nicht hat, kann man sich diese mit
ifconfig eth0
Oder
arp
Anzeigen lassen (natürlich auf dem Rechner den man später wecken will!).
- als Alternative dazu gibt es z.B. noch wol
Win
Für Windows gibt es die Freeware LANStart.
Einige Leute haben berichtet dass LanStart bei Ihnen nicht funktioniert. Alternativen sind wol.exe von http://www.gammadyne.com/cmdline.htm
oder mc-wol.exe von http://www.matcode.com/wol.htm (funktioniert auch nicht immer. Für die Scovery250 ist es ok, für den via-rhine II nicht).
Manche Firewalls lassen keine globalen Broadcasts (255.255.255.255) durch. Damit scheitern viele WOL Programme. Daher habe ich df-wol.exe geschrieben. Damit kann man LAN locale Broadcasts erzeugen (z.B. 192.168.1.255). Habe leider keinen Webspace, würde es unter GPL veröffentlichen.
Wakeup per CGI
Ein eigener Wakeupdienst mit MagicPacket(TM) und Web-Formular ist aber an sich auch keine größere Schwierigkeit. Also wenn man sich z.B. die eigene MAC Adresse nicht permanent merken möchte, und wenn ein eigener Webserver, der CGI+Perl unterstützt, zur Verfügung steht, kann mit folgendem HTML-Wrapper und CGI-Script ein eigener Wakeupdienst aufgesetzt werden.
Diesen HTML-Teil in die Webseite einbetten.
<form action="/cgi/wakeup.pl" method="post"> <table> <tr><td>HWaddress:</td><td><input size="40" maxlength="40" name="HWaddress" value="00:11:22:33:44:55"></td></tr> <tr><td>IPaddress:</td><td><input size="40" maxlength="40" name="IPaddress" value="1.2.3.4"></td></tr> <tr><td>Port:</td><td><input size="40" maxlength="40" name="Port" value="9"></td></tr> <tr><td> </td><td><input type="submit" value="Absenden"></td></tr> </table> </form>
Und diesen CGI-Teil auf dem Webserver speichern.
#!/usr/bin/perl -w use strict; use Socket; use CGI; my $cgi = new CGI; use CGI::Carp qw(fatalsToBrowser); $cgi->default_dtd('-//W3C//DTD HTML 4.01 Transitional//EN'); print $cgi->header(-type =>'text/html'), $cgi->start_html('Wakeup'), $cgi->h1('Wakeup'), wake($cgi->param('HWaddress'),$cgi->param('IPaddress'),$cgi->param('Port')), $cgi->end_html(); sub wake { my $hwaddr = shift; my $ipaddr = shift || '255.255.255.255'; my $port = shift || getservbyname('discard', 'udp'); my ($raddr, $them, $proto); my ($hwaddr_re, $pkt); # Validate hardware address (ethernet address) $hwaddr_re = join(':', ('[0-9A-Fa-f]{1,2}') x 6); if ($hwaddr !~ m/^$hwaddr_re$/) { return $cgi->p({-style => 'color:red'}, "Invalid hardware address: $hwaddr" ); } # Generate magic sequence foreach (split /:/, $hwaddr) { $pkt .= chr(hex($_)); } $pkt = chr(0xFF) x 6 . $pkt x 16; # Allocate socket and send packet $raddr = gethostbyname($ipaddr); $them = pack_sockaddr_in($port, $raddr); $proto = getprotobyname('udp'); if(!socket(S, AF_INET, SOCK_DGRAM, $proto)) { return $cgi->p({-style => 'color:red'}, "socket : $!"); } if(!setsockopt(S, SOL_SOCKET, SO_BROADCAST, 1)) { return $cgi->p({-style => 'color:red'}, "setsockopt : $!" ); } if(!send(S, $pkt, 0, $them)) { return $cgi->p({-style => 'color:red'}, "send : $!"); } close S; return $cgi->p("Sending magic packet to $ipaddr:$port with $hwaddr"); }
Probleme
2.6er Kernel
- Seit dem 2.6er Kernel gibt es Probleme, dass WOL nicht funktioniert. Das Problem liegt darin, dass die meisten Netzwerkkarten-Treiber das WOL deaktivieren.
- Update 03.11.2006: Ab linux-2.6.18 (frühere Kernel ungetestet) funktioniert WoL jetzt mit einer INTEL PRO/1000GT (82541).
- Bei Verwendung von ACPI
Sollte der PC trotz "ethtool -s eth0 wol g" nicht aufwachen ist ein Blick in /proc/acpi/wakeup hilfreich. Ein cat /proc/acpi/wakeup zeigte folgendes:
Device Sleep state Status PCI0 4 disabled COM1 4 disabled ...
Wake on PCI0 ist hier abgeschalten (die Netzwerkkarte die normalerweise am PCI Bus hängt kann den PC also trotz des MagicPaket nicht einschalten)
ein einfaches
echo -n PCI0 > /proc/acpi/wakeup
ist nötig um WoL zu ermöglichen.
Daher: die paar Zeilen
/usr/sbin/ethtool -s eth0 wol g if (grep PCI0 /proc/acpi/wakeup | grep disabled 2>&1 >> /dev/null) ; then echo -n PCI0 > /proc/acpi/wakeup fi
in einem suspend2ram, shutdown etc. script stellen sicher, dass der PC mittels WoL auch wieder aufwacht.
Getestet mit Debian Kernel 2.6.18. Nach Suspend2RAM und Shutdown konnte der PC mittels WoL wieder aufgeweckt werden.
ifdown
- Bei SUSE 10.1 wird im init script network die Netzwerkkarte mit ifdown abgeschaltet was anscheinend dazu führt, dass das System trotz des Befehls "ethtool -s eth0 wol g" nicht aufwacht.
3Com Karten
- 3Com Karten die den Treiber 3c59x verwenden, müssen den Parameter enable_wol=1 angeben, um WOL zu aktivieren. Dies geht allerdings nur wenn der Treiber als Modul eingebunden wird.
Lösung des Problems:
Es gibt ein Programm namens "ethtool". Hiermit kann man - nachdem der Netzwerktreiber geladen ist - die Netzwerkkartenparameter auslesen und ändern. So bekommt man angezeigt, wie die Parameter derzeit sind:
Debian-spezifisch
- Wer einem VDR auf Debian mit nvram-wakeup und (forced_)reboot WOL beibringen will, wird mit dem Problem konfrontiert, dass beim Reboot z.B. in einen PowerOff-Kernel die Netzwerkschnittstelle komplett deaktiviert wird. Damit geht die mit ethtool gesetzte WOL-Bereitschaft verloren.
Lösung: In /etc/init.d/reboot für reboot den Parameter -i entfernen. Dieser sorgt sonst für die Abschaltung aller Netzwerkschnittstellen.
ethtool eth0
Beispiel:
ethtool eth0 Settings for eth0: Supported ports: [ TP MII ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full Supports auto-negotiation: Yes Advertised link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full Advertised auto-negotiation: Yes Speed: 100Mb/s Duplex: Full Port: MII PHYAD: 1 Transceiver: internal Auto-negotiation: on Supports Wake-on: pumbg Wake-on: g Current message level: 0x00000001 (1) Link detected: yes
Besonders die Zeilen "Supports Wake-on:" und "Wake-on:" sollte man hier im Auge behalten. Die Buchstaben bedeuten:
wol p|u|m|b|a|g|s|d... Set Wake-on-LAN options. Not all devices support this. The argument to this option is a string of characters specifying which options to enable. p Wake on phy activity u Wake on unicast messages m Wake on multicast messages b Wake on broadcast messages a Wake on ARP g Wake on MagicPacket(tm) s Enable SecureOn(tm) password for MagicPacket(tm) d Disable (wake on nothing). This option clears all previous options.
So aktiviert man das Wake-On-Lan beim Eintreffen eines "MagicPacket(TM)":
ethtool -s eth0 wol g
Script für den Einsatz in init.d
#! /bin/sh # # Ensures that the Wake On Lan works # #PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin set -e case "$1" in stop|start|restart|force-reload|reload) echo -n "Turn on: Wake on Magic Packet" /usr/sbin/ethtool -s eth0 wol g echo ;; *) # N=/etc/init.d/hwtools # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 exit 1 ;; esac exit 0
Diesen kopiert man nach /etc/init.d. Zugriffsrechte sind bei mir:
-rwxr-xr-x 1 root root 386 2006-01-31 09:50 wake_on_lan
Dann muss noch ein Link darauf erzeugt werden damit der Script automatisch aufgerufen wird:
/etc/rc0.d/S80wake_on_lan -> ../init.d/wake_on_lan
Er macht die Arbeit beim Starten, es kann sein das es auf manchen Systemen besser ist dies bei Shutdown zu machen. Dann muss der Link mit 'K' anfangen.
Den Link kann man damit setzen:
cd /etc/rc0.d ln -s ../init.d/wake_on_lan S80wake_on_lan
Sonstiges
BIOS einstellungen
Das ganze ist im BIOS zu aktivieren: Power On by Ring bzw. Wake on LAN
Verbindung
Vor allem bei älteren Netzwerkkarten, bzw. Mainboards muss außerdem ein Kabel zwischen Mainboard und Netzwerkkarte gesteckt werden: (Ausnahme sind Mainboards mit Onboard-Netzwerkkarte). Abhängig ist dies von der verwendeten PCI-Spezifikation.
Eine genauere Erläuterung dazu ist auf den c't Hotline Seiten zur Ausgabe 24/2004 unter Komplizierter Netzverkehr zu finden
Anmerkung zu Kernel 2.6 und 3Com Karten
Problematisch ist dabei augenscheinlich, dass die Hardware-Erkennung und das Laden der Module offenbar mehr als einmal laufen - zumindest lassen die Statusausgaben das vermuten. Scrollt man den Boot-Screen nach oben, stößt man zunächst auf eine Zeile "3c59x already loaded" und weiter oben auf den Vermerk, dass das Modul 3c59x geladen wurde.
Dabei scheint zumindest der erste Ladevorgang die Optionen in "modules.conf", in dem "enable_wol=1" normalerweise steht, nicht zu beachten. Der zweite Versuch das Modul zu laden, der die Option evtl. berücksichtigen würde, ist aber nicht erfolgreich. Möglicherweise könnte man den ersten Ladeversuch (z. B. durch Änderungen an "discover"?, "discover.conf"?, etc.) unterbinden und damit den Zweiten wirksam werden lassen.
Da die Einstellung aber quasi erst beim Abschalten des Systems benötigt wird, scheint der Workaround nach dem Muster von "Debian - WAKE ON LAN" einfacher zu sein (hier: scriptmäßiges Entladen des Moduls durch "rmmod 3c59x" und danach "modprobe 3c59x enable_wol=1")
Jedoch dürfte dabei unter Umständen das Problem auftreten, daß das WOL nicht funktioniert, wenn der Rechner nach einem Crash "abgewürgt" wird, bevor das Script ausgeführt wurde.
[marvel] Soweit ich das erforscht habe (und mich richtig erinnere) wird der erste Ladevorgang des Treibers aus der Initramdisk heraus durchgeführt. Diese hat eine eigene modules.conf, die vom System aus nicht zu editieren ist. Auch blacklisting hilft hier nicht. Als Lösung empfiehlt sich alle Treiber zu entladen, die nicht zum Booten benötigt werden und in diesem "nackten" Zustand eine neue Initramdisk zu erstellen. In dieser neuen Ramdisk fehlen dann alle Treiber, die nicht geladen waren. Anschließend greifen die üblichen Mechanismen mit modules.conf usw.
Links
- Thread zu "Wake-On-Lan aus Internet durch DSL-Router (hier FritzBox)"
- Wake-On-Lan per MagicPacket(TM) direkt über Internetseite (inkl. Routerliste & Anleitungen)
- Wake on Lan for Windows (kleines Programm für WoL über Internet)
- Fritz!Box WoL Hack
- Wake On LAN client - FAQ
- Gute Verteilerseite
- C++ Beispiel auf codeproject.com
- Debian-spezifischer Artikel zu WOL
- Wake-On-Lan einrichten