david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[Contribs] Add updated wake-on-LAN patch from Bill <level42@sympatico.ca>

This commit is contained in:
Michael Brown 2008-03-19 01:08:38 +00:00
parent af1c6b869c
commit 7067142fb4
13 changed files with 142 additions and 1199 deletions

View File

@ -1,37 +0,0 @@
## Makefile for use with gnu make and MinGW32 gnu gcc
TARGET=wol
CC=gcc
LD=gcc
CPPFLAGS= -Wall -O2
LFLAGS= -s
#LIBFILES= -lwsock
#LIBPATH= -L/usr/lib
ICON=$(TARGET).ico
OBJS=$(TARGET).o
RESF=$(TARGET).rc
#RESNAME=$(TARGET).res
#BINNAME=$(TARGET).exe
BINNAME=$(TARGET)
$(BINNAME): $(OBJS) $(RESNAME)
$(LD) $(LFLAGS) -o $@ $^ $(LIBPATH) $(LIBFILES)
%.res:%.rc
windres -I rc -O coff -i $< -o $@
%.rc:Makefile
@echo 100 ICON "$(ICON)" > $@
dist:$(BINNAME)
rm -f $(OBJS) $(RESNAME) $(RESF)
clean:
rm -f $(OBJS) $(RESNAME) $(RESF)
rm -f $(BINNAME)

View File

@ -1,3 +1,40 @@
Here are two programs to send Wake-On-LAN packets to a dormant workstation
using the WOL feature. Please contact the respective authors for any
queries.
From level42@sympatico.ca Tue Mar 18 04:35:31 2008
Date: Mon, 17 Mar 2008 23:47:39 -0400
From: Bill <level42@sympatico.ca>
To: etherboot-developers@lists.sourceforge.net
Subject: [Etherboot-developers] WOL Routine
Attached is a WOL routine that can be used to wake a remote server from
gpxe. I put wol.c in src/usr and wol.h in src/include/usr. This is really
in improved replacement of that in contrib\wakeonlan\wakeserver.patch. This
version will no longer work since the eth_transmit routine no longer works
with the newer driver arhitecture such as the e1000 driver.
Please consider adding it to gpxe preferrably in the main src directory or
in the contrib directory.
Thank you
[ Part 2, Text/PLAIN (Name: "wol.c") 109 lines. ]
[ Unable to print this part. ]
[ Part 3, Text/PLAIN (Name: "wol.h") 12 lines. ]
[ Unable to print this part. ]
[ Part 4: "Attached Text" ]
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
[ Part 5: "Attached Text" ]
_______________________________________________
Etherboot-developers mailing list
Etherboot-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/etherboot-developers

View File

@ -1,9 +0,0 @@
# maclist - mac addresses for wakeonlan
00:BA:BE:FA:CE:00 mainframe
00:11:22:33:44:5A maschine1
00:11:22:33:44:B5 maschine2
00:11:22:33:44:5C maschine3
0A:BB:CC:DD:EE:F9 macintosh
1A:BB:CC:DD:E6:FF
3A:BB:CC:DD:EE:F5 testpc
3A:BB:CC:DD:EE:F6 123.45.6.7

View File

@ -1,172 +0,0 @@
#!/perl/bin/perl -w
# Magic Packet for the Web
# Perl version by ken.yap@acm.org after DOS/Windows C version posted by
# Steve_Marfisi@3com.com on the Netboot mailing list
# modified to work with web by G. Knauf <info@gknw.de>
# Released under GNU Public License
#
use CGI qw(:standard); # import shortcuts
use Socket;
$ver = 'v0.52 &copy; gk 2003-Apr-24 11:00:00';
# Defaults - Modify to point to the location of your mac file
$www = "$ENV{'DOCUMENT_ROOT'}/perldemo";
$maclist = "$www/maclist.txt";
# Defaults - Modify to fit to your network
$defbc = '255.255.255.255';
$port = 60000;
MAIN:
{
# Read in all the variables set by the form
if (param()) {
&process_form();
} else {
&print_form();
}
}
sub process_form {
# Print the header
print header();
print start_html("Mp-Form - send Magic Packets");
# If defined new mac save it
if (defined(param("mac"))) {
print h1("Result of adding an entry to the maclist");
print '<HR><H3><TT>';
&add_entry();
print '</TT></H3><HR>';
print '<FORM method="POST"><input type="submit" value="ok"></FORM>';
} else {
# send magic packets to selected macs
print h1("Result of sending magic packets to multiple PCs");
print '<HR><H3><TT>';
if (param("all")) {
&process_file(S);
} else {
for (param()) {
my ($brc,$mac) = split(/-/,param($_));
&send_broadcast_packet(inet_aton($brc),$mac);
}
}
print '</TT></H3><HR>';
print '<FORM><input type="button" value="back" onClick="history.back()"></FORM>';
}
# Close the document cleanly.
print end_html;
}
sub print_form {
# Print the header
print header();
print start_html("Mp-Form - send Magic Packets");
print h1("Form for sending magic packets to multiple PCs");
print <<ENDOFTEXT;
<HR>
<FORM method="POST">
<H2>Select the destination mac addresses:</H2>
<TABLE BORDER COLS=3 WIDTH="80%">
<TR>
<TD><CENTER><B><FONT SIZE="+1">Broadcast address</FONT></B></CENTER></TD>
<TD><CENTER><B><FONT SIZE="+1">MAC address</FONT></B></CENTER></TD>
<TD><CENTER><B><FONT SIZE="+1">Name</FONT></B></CENTER></TD>
<TD><CENTER><B><FONT SIZE="+1"><input type=checkbox name="all" value="all">Select all</FONT></B></CENTER></TD>
</TR>
ENDOFTEXT
# build up table with mac addresses
&process_file(R);
# print rest of the form
print <<ENDOFTEXT;
</TABLE>
<P><B><FONT SIZE="+1">
Press <input type="submit" value="wakeup"> to send the magic packets to your selections.
Press <input type="reset" value="clear"> to reset the form.
</FONT></B>
</FORM>
<HR>
<FORM method="POST">
<H2>Enter new destination mac address:</H2>
<B><FONT SIZE="+1">Broadcast: </FONT></B><input name="brc" size="15" maxlength="15" value="$defbc">
<B><FONT SIZE="+1">MAC: </FONT></B><input name="mac" size="17" maxlength="17">
<B><FONT SIZE="+1">Name: </FONT></B><input name="ip" size="40" maxlength="40">
<P><B><FONT SIZE="+1">
Press <input type="submit" value="save"> to add the entry to your maclist.
Press <input type="reset" value="clear"> to reset the form.
</FONT></B>
</FORM>
<HR>
$ver
ENDOFTEXT
# Close the document cleanly.
print end_html;
}
sub send_broadcast_packet {
my ($nbc,$mac) = @_;
if ($mac !~ /^[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}$/i) {
print "Malformed MAC address $mac<BR>\n";
return;
}
printf("Sending wakeup packet to %04X:%08X-%s<BR>\n", $port, unpack('N',$nbc), $mac);
# Remove colons
$mac =~ tr/://d;
# Magic packet is 6 bytes of FF followed by the MAC address 16 times
$magic = ("\xff" x 6) . (pack('H12', $mac) x 16);
# Create socket
socket(S, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or die "socket: $!\n";
# Enable broadcast
setsockopt(S, SOL_SOCKET, SO_BROADCAST, 1) or die "setsockopt: $!\n";
# Send the wakeup packet
defined(send(S, $magic, 0, sockaddr_in($port, $nbc))) or print "send: $!\n";
close(S);
}
sub process_file {
unless (open(F, $maclist)) {
print "Error reading $maclist: $!\n";
} else {
while (<F>) {
next if (/^\s*#|^\s*;/); # skip comments
my ($mac, $ip) = split;
next if (!defined($mac) or $mac eq '');
$mac = uc($mac);
my $bc = $defbc;
($bc,$mac) = split(/-/,$mac) if ($mac =~ /-/);
my $nbc = inet_aton($bc);
if ($_[0] eq 'S') {
&send_broadcast_packet($nbc, $mac);
} else {
my $hbc = sprintf("0x%08X", unpack('N',$nbc));
print "<TD WIDTH=20%><CENTER><TT>$hbc</TT></CENTER></TD>";
print "<TD WIDTH=30%><CENTER><TT>$mac</TT></CENTER></TD>";
$ip = '&nbsp;' if (!defined($ip) or $ip eq '');
print "<TD WIDTH=30%><CENTER><TT>$ip</TT></CENTER></TD>";
print "<TD WIDTH=20%><CENTER><input type=checkbox name=mac$. value=$hbc-$mac><TT>WakeUp</TT></CENTER></TD></TR>\n";
}
}
close(F);
}
}
sub add_entry {
if (param("brc") !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/i) {
print "Malformed broadcast address ",param("brc"),"\n";
return;
}
if (param("mac") !~ /^[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}$/i) {
print "Malformed MAC address ",param("mac"),"\n";
return;
}
unless (open(F, ">> $maclist")) {
print "Error writing $maclist: $!\n";
} else {
#my $nbc = inet_aton(param("brc"));
#my $hbc = sprintf("0x%8X", unpack('N',$nbc));
#print F $hbc."-".uc(param("mac"))." ".param("ip")."\n";
print F param("brc")."-".uc(param("mac"))." ".param("ip")."\n";
close(F);
print "Saved entry to maclist: ".param("brc")."-".uc(param("mac"))." ".param("ip")."\n";
}
}

View File

@ -1,26 +0,0 @@
mp-form.pl - Send magic packets with your web server
This is my trial of waking up PCs with a form via web server.
The perl script reads in a text file which contains lines of the form
aa:bb:cc:dd:ee:ff 12.34.56.78 or
aa:bb:cc:dd:ee:ff foo.bar.com
aa:bb:cc:dd:ee:ff
The script is based on wake.pl by Ken Yap who is also the author of the Etherboot package.
The script uses CGI.pm to parse form input and Socket.pm to send the magic packets, both
modules should belong to your perl distribution. The script runs with linux as well as
with NT, with NetWare you have to use the Socket.NLP from recent Perl build #334, with
Perl build #333 and earlier I got an error from the Socket.pm.
This script uses only broadcast so you don't need root rights to use it.
To install the script copy it to your ../cgi-bin directory. Then for Linux do a chmod 755
to the script. Modify the lines which point to the location of the maclist. If you do not
have a maclist, the form could save new entries to a list (with unix perhaps you have to
create an empty file). Check also the first line of mp-form.pl and modify it to point to
your perl5 location. For NetWare copy the script to /novonyx/suitespot/docs/perlroot.
Older version: If you have problems running the script with CGI.pm you could try the older
version mp-form1.pl which uses cgi-lib.pl to parse form input. You can get cgi-lib.pl
from http://cgi-lib.berkeley.edu/. With NetWare you should also use mp-form1.pl as using
CGI.pm consumes much memory. The older version is also included in the zip archive.
Homepage of the script: http://www.gknw.de/mpform.html

View File

@ -1,171 +0,0 @@
#!/usr/bin/perl -w
# Magic Packet for the Web
# Perl version by ken.yap@acm.org after DOS/Windows C version posted by
# Steve_Marfisi@3com.com on the Netboot mailing list
# modified to work with web by G. Knauf <info@gknw.de>
# Released under GNU Public License
#
require "cgi-lib.pl";
use Socket;
$ver = 'v0.52 &copy; gk 2003-Apr-24 11:00:00';
# Defaults - Modify to point to the location of your mac file
$www = "$ENV{'DOCUMENT_ROOT'}/perldemo";
$maclist = "$www/maclist.txt";
# Defaults - Modify to fit to your network
$defbc = '255.255.255.255';
$port = 60000;
MAIN:
{
# Read in all the variables set by the form
if (&ReadParse(*input)) {
&process_form();
} else {
&print_form();
}
}
sub process_form {
# Print the header
print &PrintHeader();
# If defined new mac save it
if (defined($input{'mac'})) {
print &HtmlTop("Result of adding an entry to the maclist");
print '<HR><H3><TT>';
&add_entry;
print '</TT></H3><HR>';
print '<FORM method="POST"><input type=submit value="ok"></FORM>';
} else {
# send magic packets to selected macs
print &HtmlTop("Result of sending magic packets to multiple PCs");
print '<HR><H3><TT>';
if (defined($input{'all'})) {
&process_file(S);
} else {
foreach $x (keys %input) {
my ($brc,$mac) = split(/-/,$input{$x});
&send_broadcast_packet(inet_aton($brc),$mac);
}
}
print '</TT></H3><HR>';
print '<form><input type=button value="back" onClick="history.back()"></FORM>';
}
# Close the document cleanly.
print &HtmlBot;
exit;
}
sub print_form {
print &PrintHeader();
print &HtmlTop("Form for sending magic packets to multiple PCs");
# Print out the body of the form
print <<ENDOFTEXT;
<HR>
<FORM method="POST">
<H2> Select the destination mac addresses: </H2>
<TABLE BORDER COLS=3 WIDTH="80%">
<TR>
<TD><CENTER><B><FONT SIZE="+1">Broadcast address</FONT></B></CENTER></TD>
<TD><CENTER><B><FONT SIZE="+1">MAC address</FONT></B></CENTER></TD>
<TD><CENTER><B><FONT SIZE="+1">Name</FONT></B></CENTER></TD>
<TD><CENTER><B><FONT SIZE="+1"><input type=checkbox name="all" value="all">Select all</FONT></B></CENTER></TD>
</TR>
ENDOFTEXT
# build up table with mac addresses
&process_file;
# print rest of the form
print <<ENDOFTEXT;
</TABLE>
<P><B><FONT SIZE="+1">
Press <input type="submit" value="wakeup"> to send the magic packets to your selections.
Press <input type="reset" value="clear"> to reset the form.
</FONT></B>
</FORM>
<HR>
<FORM method="POST">
<H2>Enter new destination mac address:</H2>
<B><FONT SIZE="+1">Broadcast: </FONT></B><input name="brc" size="15" maxlength="15" value="$defbc">
<B><FONT SIZE="+1">MAC: </FONT></B><input name="mac" size=17 maxlength=17>
<B><FONT SIZE="+1">Name: </FONT></B><input name="ip" size=40 maxlength=40>
<P><B><FONT SIZE="+1">
Press <input type="submit" value="save"> to add the entry to your maclist.
Press <input type="reset" value="clear"> to reset the form.
</FONT></B>
</FORM>
<HR>
$ver
ENDOFTEXT
# Close the document cleanly.
print &HtmlBot;
}
sub send_broadcast_packet {
my ($nbc,$mac) = @_;
if ($mac !~ /^[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}$/i) {
print "Malformed MAC address $mac<BR>\n";
return;
}
printf("Sending wakeup packet to %04X:%08X-%s<BR>\n", $port, unpack('N',$nbc), $mac);
# Remove colons
$mac =~ tr/://d;
# Magic packet is 6 bytes of FF followed by the MAC address 16 times
$magic = ("\xff" x 6) . (pack('H12', $mac) x 16);
# Create socket
socket(S, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or die "socket: $!\n";
# Enable broadcast
setsockopt(S, SOL_SOCKET, SO_BROADCAST, 1) or die "setsockopt: $!\n";
# Send the wakeup packet
defined(send(S, $magic, 0, sockaddr_in($port, $nbc))) or print "send: $!\n";
close(S);
}
sub process_file {
unless (open(F, $maclist)) {
print "Error reading $maclist: $!\n";
} else {
while (<F>) {
next if (/^\s*#|^\s*;/); # skip comments
my ($mac, $ip) = split;
next if (!defined($mac) or $mac eq '');
$mac = uc($mac);
my $bc = $defbc;
($bc,$mac) = split(/-/,$mac) if ($mac =~ /-/);
my $nbc = inet_aton($bc);
if ($_[0] eq 'S') {
&send_broadcast_packet($nbc, $mac);
} else {
my $hbc = sprintf("0x%08X", unpack('N',$nbc));
print "<TD WIDTH=20%><CENTER><TT>$hbc</TT></CENTER></TD>";
print "<TD WIDTH=30%><CENTER><TT>$mac</TT></CENTER></TD>";
$ip = '&nbsp;' if (!defined($ip) or $ip eq '');
print "<TD WIDTH=30%><CENTER><TT>$ip</TT></CENTER></TD>";
print "<TD WIDTH=20%><CENTER><input type=checkbox name=mac$. value=$hbc-$mac><TT>WakeUp</TT></CENTER></TD></TR>\n";
}
}
close(F);
}
}
sub add_entry {
if (param("brc") !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/i) {
print "Malformed broadcast address ",param("brc"),"\n";
return;
}
if (param("mac") !~ /^[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}$/i) {
print "Malformed MAC address ",param("mac"),"\n";
return;
}
unless (open(F, ">> $maclist")) {
print "Error writing $maclist: $!\n";
} else {
#my $nbc = inet_aton(param("brc"));
#my $hbc = sprintf("0x%8X", unpack('N',$nbc));
#print F $hbc."-".uc(param("mac"))." ".param("ip")."\n";
print F param("brc")."-".uc(param("mac"))." ".param("ip")."\n";
close(F);
print "Saved entry to maclist: ".param("brc")."-".uc(param("mac"))." ".param("ip")."\n";
}
}

View File

@ -1,35 +0,0 @@
mp-form.pl - Send magic packets with your web server
This is my trial of waking up PCs with a form via web server.
The perl script reads in a text file which contains lines of the form
aa:bb:cc:dd:ee:ff 12.34.56.78 or
aa:bb:cc:dd:ee:ff foo.bar.com
aa:bb:cc:dd:ee:ff
optional a broadcast address mask can be prefixed:
192.168.1.255-aa:bb:cc:dd:ee:ff
The script is based on wake.pl by Ken Yap who is also the author of the Etherboot package.
The script uses CGI.pm to parse form input and Socket.pm to send the magic packets, both
modules should belong to your perl distribution. The script runs with linux as well as
with NT, with NetWare you have to use the Socket.NLP from recent Perl build #334, with
Perl build #333 and earlier I got an error from the Socket.pm. You should also update
your Perl to minimum #331 from CPAN: http://www.cpan.org/ports/index.html#netware.
This script uses only broadcast so you don't need root rights to use it.
To install the script copy it to your ../cgi-bin directory. Then for Linux do a chmod 755
to the script. Modify the lines which point to the location of the maclist. If you do not
have a maclist, the form could save new entries to a list (with unix perhaps you have to
create an empty file). Check also the first line of mp-form.pl and modify it to point to
your perl5 location. For NetWare copy the script to /novonyx/suitespot/docs/perlroot.
Older version: If you have problems running the script with CGI.pm you could try the older
version mp-form1.pl which uses cgi-lib.pl to parse form input. You can get cgi-lib.pl
from http://cgi-lib.berkeley.edu/. With NetWare you should also use mp-form1.pl as using
CGI.pm consumes much memory. The older version is also included in the zip archive.
A modified version of the original script is now also included which runs with older
Getopt::Std.pm as shipped with NetWare. This script you could use from command line
or from cron. With NetWare copy the script to /perl/scripts; then call from console with:
perl wakeup.pl <parameters>.
Homepage of the script: http://www.gknw.de/mpform.html

View File

@ -1,116 +0,0 @@
#!/usr/bin/perl -w
#
# If called as wake.pl -f file it reads lines of the form
#
# aa:bb:cc:dd:ee;ff 12.34.56.78 or
# aa:bb:cc:dd:ee:ff foo.bar.com
# aa:bb:cc:dd:ee:ff
#
# which are MAC addresses and hostnames of NICs to send a wakeup packet.
# In the first two cases, unicast is used (and root permission may be
# required if the ARP cache needs to be injected with a mapping).
# In the third case, broadcast is used, and anybody can run the command.
# Comments in the file start with #.
#
# Or MAC addresses can be specified on the command line
#
# wake.pl aa.bb.cc.dd.ee.ff
#
# Or both can be used:
#
# wake.pl -f addresses.cfg 11:22:33:44:55:66
#
# This program may have to be run with superuser privilege because it
# may need to inject an ARP entry into the cache.
# Be careful, you could corrupt valid entries if those NICs are
# already active.
#
# Perl version by ken_yap@users.sourceforge.net after DOS/Windows C version posted by
# Steve_Marfisi@3com.com on the Netboot mailing list
# Released under GNU Public License, 2000-01-08
# Added switch -q for quiet mode, changed Getopt usage to work with older versions,
# added switch -u for unicast mode, now default is always broadcast mode,
# added switch -s for seach pattern so you could filter entries from file.
# Guenter.Knauf@dialup.soco.de, 2000-10-14
#
use Getopt::Std;
use Socket;
getopts('quf:s:');
if (defined($opt_f)) {
unless (open(F, $opt_f)) {
print STDERR "open: $opt_f: $!\n";
} else {
while (<F>) {
next if /^\s*#/; # skip comments
($mac, $ip) = split;
next if !defined($mac) or $mac eq '';
next if defined($opt_s) and (!/$opt_s/);
if (!defined($ip) or $ip eq '' or !$opt_u) {
&send_broadcast_packet($mac);
} else {
&send_unicast_packet($mac, $ip);
}
}
close(F);
}
}
while (@ARGV) {
send_broadcast_packet(shift(@ARGV));
}
sub send_broadcast_packet {
($mac) = @_;
if ($mac !~ /^[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}$/i) {
print STDERR "Malformed MAC address $mac\n";
return;
}
# Remove colons
$mac =~ tr/://d;
# Magic packet is 6 bytes of FF followed by the MAC address 16 times
$magic = ("\xff" x 6) . (pack('H12', $mac) x 16);
# Create socket
socket(S, PF_INET, SOCK_DGRAM, getprotobyname('udp'))
or die "socket: $!\n";
# Enable broadcast
setsockopt(S, SOL_SOCKET, SO_BROADCAST, 1)
or die "setsockopt: $!\n";
# Send the wakeup packet
if (!$opt_q) {
print "Sending wakeup packet to MAC address $mac";
print " ($ip)" if (defined($ip));
print "\n";
}
defined(send(S, $magic, 0, sockaddr_in(0x2fff, INADDR_BROADCAST)))
or print STDERR "send: $!\n";
close(S);
}
sub send_unicast_packet {
($mac, $ip) = @_;
if (!defined($iaddr = inet_aton($ip))) {
print STDERR "Cannot resolve $ip\n";
return;
}
if ($mac !~ /^[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}$/i) {
print STDERR "Malformed MAC address $mac\n";
return;
}
# Inject entry into ARP table, in case it's not there already
system("arp -s $ip $mac") == 0
or print STDERR "Warning: arp command failed, you need to be root\n";
# Remove colons
$mac =~ tr/://d;
# Magic packet is 6 bytes of FF followed by the MAC address 16 times
$magic = ("\xff" x 6) . (pack('H12', $mac) x 16);
# Create socket
socket(S, PF_INET, SOCK_DGRAM, getprotobyname('udp'))
or die "socket: $!\n";
# Send the wakeup packet
print "Sending wakeup packet to $ip at MAC address $mac\n" if (!$opt_q);
defined(send(S, $magic, 0, sockaddr_in(0x2fff, $iaddr)))
or print STDERR "send: $!\n";
close(S);
}

View File

@ -1,179 +0,0 @@
To: etherboot-developers@lists.sourceforge.net
X-face: #Qvg5o3u!)WoVDDi4-bFy`fl@""4^pm68%_,`puon{0Q6lQ-O,)3D.J.":A&^,#4O2vc8`?
3^1lhBh=EQH,"Qq*e1vY":she&t^8:!&Fb32Ed:nM2Y<E9|i[+z20G?CO=E=-IWv;bL"=Y`+`q,ML6
,!Me?==j&In1
Mime-Version: 1.0
Content-Type: multipart/mixed ;
boundary="==_Exmh_-19971541890"
From: Tilmann Bubeck <bubeck@think-at-work.de>
Message-Id: <20010219195622.C97A84ABD8@chaos.think-at-work.de>
Subject: [Etherboot-developers] Wake-on-LAN patch
Sender: etherboot-developers-admin@lists.sourceforge.net
Errors-To: etherboot-developers-admin@lists.sourceforge.net
X-BeenThere: etherboot-developers@lists.sourceforge.net
X-Mailman-Version: 2.0
Precedence: bulk
List-Help: <mailto:etherboot-developers-request@lists.sourceforge.net?subject=help>
List-Post: <mailto:etherboot-developers@lists.sourceforge.net>
List-Subscribe: <http://lists.sourceforge.net/lists/listinfo/etherboot-developers>,
<mailto:etherboot-developers-request@lists.sourceforge.net?subject=subscribe>
List-Id: Discussion list for Etherboot developers <etherboot-developers.lists.sourceforge.net>
List-Unsubscribe: <http://lists.sourceforge.net/lists/listinfo/etherboot-developers>,
<mailto:etherboot-developers-request@lists.sourceforge.net?subject=unsubscribe>
List-Archive: <http://lists.sourceforge.net/archives//etherboot-developers/>
Date: Mon, 19 Feb 2001 20:56:22 +0100
Status: RO
Content-Length: 5351
Lines: 152
This is a multipart MIME message.
--==_Exmh_-19971541890
Content-Type: text/plain; charset=us-ascii
Hello!
please find enclosed a patch to optionally enable etherboot to start the
server it is booting from by sending a magic wake-on-lan packet to the
sleeping server first.
This is very important for an etherboot-server, which is not running all the
time and is not easily accessible from the etherboot machine (e.g. because it
is installed in the basement of the house and one must climb several stairs to
switch the server on...)
Are the authors of etherboot willing to accept this patch for inclusion?
Please note, that the wake-on-lan code is only compiled in, when setting
appropriate flags in src/Config.
If you don't want to include the patch, should I change anything of the
implementation or do you dislike the idea at all?
Thanks!
Till
+-------+--------------------------------------------------------------+
| | dr. tilmann bubeck think@work it consulting |
| | professional services |
| think | cell.: +49 172 8842972 widmaierstrasse 58 |
| @work | fax : +49 711 7227734 70567 stuttgart |
| | email: bubeck@think-at-work.de http://www.think-at-work.de |
+-------+ -------------------------------------------------------------+
--==_Exmh_-19971541890
Content-Type: application/x-patch ; name="etherboot-4.7.17-wol.patch"
Content-Description: etherboot-4.7.17-wol.patch
Content-Disposition: attachment; filename="etherboot-4.7.17-wol.patch"
diff -r -u etherboot-4.7.17/src/Config etherboot-4.7.17-wol/src/Config
--- etherboot-4.7.17/src/Config Sat Jan 6 16:25:23 2001
+++ etherboot-4.7.17-wol/src/Config Mon Feb 19 20:28:00 2001
@@ -113,6 +113,16 @@
# -DINTERNAL_BOOTP_DATA
# - define if the area 0x93C00-0x93FFF is not available
# for use for bootpd_data by the loader for some reason
+# -DWAKEUP_SERVER
+# - define this for sending a Wake-On-LAN (WOL)
+# "Magic Packet" to a sleeping server, before trying
+# a etherboot. Useful if your server is soft-off all
+# the time and must be switched on when booting a
+# client. Define SERVER_MAC with the MAC address of the
+# server to wakeup. CAUTION! This MAC address is
+# stored in the rom image. The rom is therefore not
+# generic anymore but tailored for a specific
+# server!
# These default settings compile Etherboot with a small number of options.
# You may wish to enable more of the features if the size of your ROM allows.
@@ -142,6 +152,10 @@
# These flags affect the loader that is prepended to the Etherboot image
LCONFIG+= -DMOVEROM
+
+# Include code for sending a Wake-On-LAN (WOL) "Magic Packet" to a sleeping
+# server, before trying a etherboot.
+CFLAGS32+= -DWAKEUP_SERVER -DSERVER_MAC=0x00,0x01,0x02,0xDA,0xDF,0x77
# you should normally not need to change these
RM= rm -f
diff -r -u etherboot-4.7.17/src/main.c etherboot-4.7.17-wol/src/main.c
--- etherboot-4.7.17/src/main.c Fri Jan 5 12:45:29 2001
+++ etherboot-4.7.17-wol/src/main.c Thu Feb 8 20:46:59 2001
@@ -137,6 +137,7 @@
* declarations, but in this case I like to see main() as the first
* routine.
*/
+static void wakeup_server(void) ;
static int bootp(void);
static int rarp(void);
static void load(void);
@@ -217,6 +218,11 @@
rfc951_sleep(++card_retries);
}
#endif
+
+#ifdef WAKEUP_SERVER
+ wakeup_server();
+#endif
+
while (1) {
/* -1: timeout or ESC
-2: error return from loader
@@ -650,6 +656,46 @@
return (0);
}
#endif /* DOWNLOAD_PROTO_TFTP */
+
+#ifdef WAKEUP_SERVER
+#ifndef SERVER_MAC
+#error "Please define SERVER_MAC to the MAC address of the sleeping server"
+#endif
+
+/**************************************************************************
+WOL - Wake up a sleeping server by transmitting a Wake-On-LAN (WOL) "Magic
+ Packet", used for restarting machines that have been soft-powered-down
+ (ACPI D3-warm state). It currently generates the standard AMD Magic
+ Packet format.
+**************************************************************************/
+static void wakeup_server(void)
+{
+ unsigned char data[100];
+ int i, len, retry;
+ char server_adr[] = { SERVER_MAC };
+ unsigned long time;
+
+ /* build "Magic Packet" */
+ len = 0;
+ data[len++] = 0xff;
+ data[len++] = 0xff;
+ data[len++] = 0xff;
+ data[len++] = 0xff;
+ data[len++] = 0xff;
+ data[len++] = 0xff;
+ for ( i = 0; i < 16; i++ ) {
+ memcpy(&data[len], server_adr, 6);
+ len += 6;
+ }
+
+ printf("Sending Wake-On-LAN (WOL) \"Magic Packet\" to server %b:%b:%b:%b:%b:%b...",
+ server_adr[0], server_adr[1], server_adr[2],
+ server_adr[3], server_adr[4], server_adr[5]);
+
+ eth_transmit(broadcast, 0x0842, len, data);
+ printf("done\n");
+}
+#endif
#ifdef RARP_NOT_BOOTP
/**************************************************************************
--==_Exmh_-19971541890--
_______________________________________________
Etherboot-developers mailing list
Etherboot-developers@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/etherboot-developers

View File

@ -1,86 +0,0 @@
#!/usr/bin/perl
#!/usr/bin/perl -w
#
# If called as wakeup.pl -f file it reads lines of the form
#
# aa:bb:cc:dd:ee;ff 12.34.56.78 or
# aa:bb:cc:dd:ee:ff foo.bar.com
# aa:bb:cc:dd:ee:ff
#
# which are MAC addresses and hostnames of NICs to send a wakeup packet.
# Broadcast is used to send the magic packets, so anybody can run the command.
# Notice that many routers do NOT forward broadcasts automatically!!
# Comments in the file start with #.
#
# Or MAC addresses can be specified on the command line
#
# wakeup.pl aa.bb.cc.dd.ee.ff
#
# Or both can be used:
#
# wakeup.pl -f addresses.cfg 11:22:33:44:55:66
#
# Use option -b to specify broadcast mask.
# Use option -d for screen output.
#
# Perl version by ken.yap@acm.org after DOS/Windows C version posted by
# Steve_Marfisi@3com.com on the Netboot mailing list
# Released under GNU Public License, 2000-01-08
# Modified for use with NetWare by gk@gknw.de, 2000-09-18
# With NetWare you have to use Socket.NLP from NetWare Perl #334 or higher!
# You could download Socket.NLP #334 from: http://www.gknw.de/mpform.html
#
use Getopt::Std;
use Socket;
getopts('b:df:p:q');
$brc = $opt_b || '255.255.255.255';
$port = $opt_p || 60000;
die "Malformed broadcast address: $brc!\n" if ($brc !~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$)/);
if (defined($opt_f)) {
unless (open(F, $opt_f)) {
print "open: $opt_f: $!\n";
} else {
print "Using file $opt_f...\n" if ($opt_d);
while (<F>) {
next if /^\s*#/; # skip comments
my ($mac, $ip) = split;
next if !defined($mac) or $mac eq '';
&send_broadcast_packet($mac,$ip);
}
close(F);
}
}
while (@ARGV) {
send_broadcast_packet(shift(@ARGV));
}
sub send_broadcast_packet {
my ($mac,$ip) = @_;
if ($mac =~ /-/) {
($bc,$mac) = split(/-/,$mac);
} else {
$bc = $brc;
}
if ($mac !~ /^[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}:[\da-f]{2}$/i) {
print "Malformed MAC address $mac\n";
return;
}
my $nbc = inet_aton($bc);
# Remove colons
$mac =~ tr/://d;
# Magic packet is 6 bytes of FF followed by the MAC address 16 times
$magic = ("\xff" x 6) . (pack('H12', $mac) x 16);
# Create socket
socket(S, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or die "socket: $!\n";
# Enable broadcast
setsockopt(S, SOL_SOCKET, SO_BROADCAST, 1) or die "setsockopt: $!\n";
# Send the wakeup packet
printf("$0: Sending wakeup packet to %04X:%08X-%s %s\n",$port,unpack('N',$nbc),uc($mac),$ip) if ($opt_d);
defined(send(S, $magic, 0, sockaddr_in($port, $nbc)))
or print "send: $!\n";
close(S);
}

View File

@ -1,9 +0,0 @@
# maclist - mac addresses for wakeonlan
00:BA:BE:FA:CE:00 mainframe
00:11:22:33:44:5A maschine1
00:11:22:33:44:B5 maschine2
00:11:22:33:44:5C maschine3
0A:BB:CC:DD:EE:F9 macintosh
1A:BB:CC:DD:E6:FF
3A:BB:CC:DD:EE:F5 testpc
3A:BB:CC:DD:EE:F6 123.45.6.7

View File

@ -1,374 +1,108 @@
/*****************************************************************************
/*
* Copyright (C) 2008 William Stewart.
*
* wol.c - Wake-On-LAN utility to wake a networked PC
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* by R. Edwards (bob@cs.anu.edu.au), January 2000
* (in_ether routine adapted from net-tools-1.51/lib/ether.c by
* Fred N. van Kempen)
* added file input, some minor changes for compiling for NetWare
* added switches -q and -d=<ms>, added Win32 target support
* by G. Knauf (gk@gknw.de), 30-Jan-2001
* added switches -b=<bcast> and -p=<port>
* by G. Knauf (gk@gknw.de), 10-Okt-2001
* added OS/2 target support
* by G. Knauf (gk@gknw.de), 24-May-2002
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* This utility allows a PC with WOL configured to be powered on by
* sending a "Magic Packet" to it's network adaptor (see:
* http://www.amd.com/products/npd/overview/20212.html).
* Only the ethernet dest address needs to be given to make this work.
* Current version uses a UDP broadcast to send out the Magic Packet.
*
* compile with: gcc -Wall -o wol wol.c
* with Solaris: (g)cc -o wol wol.c -lsocket -lnsl
* with MingW32: gcc -Wall -o wol wol.c -lwsock32
*
* usage: wol <dest address>
* where <dest address> is in [ddd.ddd.ddd.ddd-]xx:xx:xx:xx:xx:xx format.
* or: wol [-q] [-b=<bcast>] [-p=<port>] [-d=<ms>] -f=<File name>
* where <File name> is a file containing one dest address per line,
* optional followed by a hostname or ip separated by a blank.
* -b sets optional broadcast address, -p sets optional port,
* -q supresses output, -d=<ms> delays ms milliseconds between sending.
*
* Released under GNU Public License January, 2000.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define VERSION "1.12.2 (c) G.Knauf http://www.gknw.de/"
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifdef WATTCP
#define strncasecmp strnicmp
#include <ctype.h>
#include <dos.h>
#include <tcp.h>
#else
#ifdef WIN32 /* Win32 platform */
#define USE_WINSOCKAPI
#define delay Sleep
#if (defined(__LCC__) || defined(__BORLANDC__))
#define strncasecmp strnicmp
#else
#define strncasecmp _strnicmp
#endif
#elif defined(N_PLAT_NLM) /* NetWare platform */
#ifdef __NOVELL_LIBC__
#include <ctype.h>
#else
extern int isdigit(int c); /* no ctype.h for NW3.x */
#include <nwthread.h>
#define strncasecmp strnicmp
#endif
#elif defined(__OS2__) /* OS/2 platform */
#ifdef __EMX__
#define strncasecmp strnicmp
#endif
extern int DosSleep(long t);
#define delay DosSleep
#else /* all other platforms */
#define delay(t) usleep(t*1000)
#endif
#ifndef N_PLAT_NLM /* ! NetWare platform */
#include <ctype.h>
#endif
#ifndef WIN32 /* ! Win32 platform */
#include <unistd.h>
#endif
#ifdef USE_WINSOCKAPI /* Winsock2 platforms */
#ifdef N_PLAT_NLM /* NetWare platform */
#include <ws2nlm.h>
#else
#include <winsock.h>
#endif
#define close(s) { \
closesocket(s); \
WSACleanup(); \
}
#else /* Socket platforms */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if defined(__OS2__) && !defined(__EMX__)
#include <utils.h>
#else
#include <arpa/inet.h>
#endif
#endif
#include <errno.h>
#include <byteswap.h>
#include <gpxe/features.h>
#include <gpxe/netdevice.h>
#include <gpxe/if_ether.h>
#include <gpxe/iobuf.h>
#include <usr/ifmgmt.h>
#include <usr/wol.h>
#include <timer.h>
#endif
/** @file
*
* Wake on lan
*
*/
static int read_file (char *destfile);
static int in_ether (char *bufp, unsigned char *addr);
static int send_wol (char *dest, char *host);
/**
* Boot from a network device
*
* @v netdev Network device
* @ret rc Return status code
*/
#define WOL_MSG_LEN (6 + 16*6)
void wakeup_server(char *server_adr)
{
int rc, i,j;
unsigned char *buf;
uint8_t eth_broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
unsigned int len;
struct io_buffer *iobuf;
struct ethhdr *ethhdr;
struct net_device *netdev;
for_each_netdev ( netdev ) {
break;
}
char *progname;
int quiet = 0;
int twait = 0;
unsigned int port = 60000;
unsigned long bcast = 0xffffffff;
int main (int argc, char *argv[]) {
int cmdindx = 0;
progname = argv[0];
if (argc > 1) {
/* parse input parameters */
for (argc--, argv++; *argv; argc--, argv++) {
char *bp;
char *ep;
if (strncasecmp (*argv, "-", 1) == 0) {
if (strncasecmp (*argv, "-F=", 3) == 0) {
bp = *argv + 3;
read_file (bp);
} else if (strncasecmp (*argv, "-B=", 3) == 0) {
bp = *argv + 3;
bcast = inet_addr(bp);
if (bcast == -1) {
fprintf (stderr, "%s: expected address argument at %s\n", progname, *argv);
exit (1);
}
} else if (strncasecmp (*argv, "-D=", 3) == 0) {
bp = *argv + 3;
twait = strtol (bp, &ep, 0);
if (ep == bp || *ep != '\0') {
fprintf (stderr, "%s: expected integer argument at %s\n", progname, *argv);
exit (1);
}
} else if (strncasecmp (*argv, "-P=", 3) == 0) {
bp = *argv + 3;
port = strtol (bp, &ep, 0);
if (ep == bp || *ep != '\0') {
fprintf (stderr, "%s: expected integer argument at %s\n", progname, *argv);
exit (1);
}
} else if (strncasecmp (*argv, "-Q", 2) == 0) {
quiet = 1;
} else if (strncasecmp (*argv, "-V", 2) == 0) {
fprintf (stderr, "\r%s Version %s\n", progname, VERSION);
exit (0);
} else {
fprintf (stderr, "\r%s: invalid or unknown option %s\n", progname, *argv);
exit (1);
}
} else {
send_wol (*argv, "");
}
cmdindx++;
if (netdev == NULL)
{
printf("Could not find netdev\n");
return;
}
return (0);
} else {
/* No arguments given -> usage message */
fprintf (stderr, "\rUsage: %s [-q] [-b=<bcast>] [-p=<port>] [-d=<ms>] -f=<file> | <dest>\n", progname);
fprintf (stderr, " need at least hardware address or file option\n");
return (-1);
}
}
/* Open device and display device status */
if ( (ifopen ( netdev ) ) != 0 )
{
printf("Could not open netdev\n");
return;
}
/* Create outgoing I/O buffer */
iobuf = alloc_iob ((ETH_HLEN + WOL_MSG_LEN)*2);
if (!iobuf)
{
printf("Could not allocate iob\n");
return;
}
ethhdr = iob_put(iobuf, sizeof(*ethhdr));
/* Build Ethernet header */
memcpy (ethhdr->h_dest, eth_broadcast, ETH_ALEN );
memcpy (ethhdr->h_source, netdev->ll_addr, ETH_ALEN );
ethhdr->h_protocol = htons (0x0842);
buf = iob_put (iobuf, WOL_MSG_LEN);
static int in_ether (char *bufp, unsigned char *addr) {
char c, *orig;
int i;
unsigned char *ptr = addr;
unsigned val;
i = 0;
orig = bufp;
while ((*bufp != '\0') && (i < 6)) {
val = 0;
c = *bufp++;
if (isdigit(c))
val = c - '0';
else if (c >= 'a' && c <= 'f')
val = c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
val = c - 'A' + 10;
else {
#ifdef DEBUG
fprintf (stderr, "\rin_ether(%s): invalid ether address!\n", orig);
#endif
errno = EINVAL;
return (-1);
}
val <<= 4;
c = *bufp;
if (isdigit(c))
val |= c - '0';
else if (c >= 'a' && c <= 'f')
val |= c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
val |= c - 'A' + 10;
else if (c == ':' || c == 0)
val >>= 4;
else {
#ifdef DEBUG
fprintf (stderr, "\rin_ether(%s): invalid ether address!\n", orig);
#endif
errno = EINVAL;
return (-1);
}
if (c != 0)
bufp++;
*ptr++ = (unsigned char) (val & 0377);
i++;
/* We might get a semicolon here - not required. */
if (*bufp == ':') {
if (i == 6) {
; /* nothing */
}
bufp++;
}
}
if (bufp - orig != 17) {
return (-1);
} else {
return (0);
}
} /* in_ether */
static int read_file (char *destfile) {
FILE *pfile = NULL;
char dest[64];
char host[32];
char buffer[512];
pfile = fopen (destfile, "r+");
if (pfile) {
while (fgets (buffer, 511, pfile) != NULL) {
if (buffer[0] != '#' && buffer[0] != ';') {
dest[0] = host[0] = '\0';
sscanf (buffer, "%s %s", dest, host);
send_wol (dest, host);
}
}
fclose (pfile);
return (0);
} else {
fprintf (stderr, "\r%s: destfile '%s' not found\n", progname, destfile);
return (-1);
}
}
static int send_wol (char *dest, char *host) {
int i, j;
int packet;
struct sockaddr_in sap;
unsigned char ethaddr[8];
unsigned char *ptr;
unsigned char buf [128];
unsigned long bc;
char mask[32];
char *tmp;
#ifdef USE_WINSOCKAPI
WORD wVersionRequested;
WSADATA wsaData;
int err;
#endif
#ifdef WATTCP
static udp_Socket sock;
udp_Socket *s;
#else
int optval = 1;
#endif
/* Fetch the broascast address if present. */
if ((tmp = strstr(dest,"-"))) {
printf("found: %s\n", tmp);
tmp[0] = 32;
sscanf (dest, "%s %s", mask, dest);
bc = inet_addr(mask);
printf("bc: string %s address %08lX\n", mask, bc);
if (bc == -1) {
fprintf (stderr, "\r%s: expected address argument at %s\n", progname, mask);
return (-1);
}
} else
bc = bcast;
/* Fetch the hardware address. */
if (in_ether (dest, ethaddr) < 0) {
fprintf (stderr, "\r%s: invalid hardware address\n", progname);
return (-1);
}
#ifdef USE_WINSOCKAPI
/* I would like to have Socket Vers. 1.1 */
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup (wVersionRequested, &wsaData);
if (err != 0) {
fprintf (stderr, "\r%s: couldn't init Winsock Version 1.1\n", progname);
WSACleanup ();
return (-1);
}
#endif
/* setup the packet socket */
#ifdef WATTCP
sock_init();
s = &sock;
if (!udp_open( s, 0, bc, port, NULL )) {
#else
if ((packet = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
#endif
fprintf (stderr, "\r%s: socket failed\n", progname);
#ifdef USE_WINSOCKAPI
WSACleanup ();
#endif
return (-1);
}
#ifndef WATTCP
/* Set socket options */
if (setsockopt (packet, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof (optval)) < 0) {
fprintf (stderr, "\r%s: setsocket failed %s\n", progname, strerror (errno));
close (packet);
return (-1);
}
/* Set up broadcast address */
sap.sin_family = AF_INET;
sap.sin_addr.s_addr = bc; /* broadcast address */
sap.sin_port = htons(port);
#endif
/* Build the message to send - 6 x 0xff then 16 x dest address */
ptr = buf;
for (i = 0; i < 6; i++)
*ptr++ = 0xff;
for (j = 0; j < 16; j++)
/* Build the message to send - 6 x 0xff then 16 x dest address */
len =0;
for (i = 0; i < 6; i++)
*ptr++ = ethaddr [i];
buf[len++] = 0xff;
for (j = 0; j < 16; j++)
for (i = 0; i < 6; i++)
buf[len++] = server_adr[i];
/* Send the packet out */
#ifdef WATTCP
sock_write( s, buf, 102 );
sock_close( s );
#else
if (sendto (packet, (char *)buf, 102, 0, (struct sockaddr *)&sap, sizeof (sap)) < 0) {
fprintf (stderr, "\r%s: sendto failed, %s\n", progname, strerror(errno));
close (packet);
return (-1);
}
close (packet);
#endif
if (!quiet) fprintf (stderr, "\r%s: packet sent to %04X:%08lX-%s %s\n",
progname, port, (unsigned long)htonl(bc), dest, host);
if (twait > 0 ) {
delay (twait);
}
return (0);
rc = netdev_tx (netdev, iobuf);
if (rc !=0)
printf("Failed to transmit WOL packet\n");
/* Give the controller a chance to send it before checking */
mdelay(100);
netdev_poll(netdev);
}

12
contrib/wakeonlan/wol.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _USR_WOL_H
#define _USR_WOL_H
/** @file
*
* Wakeon lan
*
*/
extern void wakeup_server(char *);
#endif /* _USR_WOL_H */