summaryrefslogtreecommitdiffstats
path: root/contrib/wakeonlan
diff options
context:
space:
mode:
authorMichael Brown2005-05-17 18:44:57 +0200
committerMichael Brown2005-05-17 18:44:57 +0200
commit1097cf8685cd81f0003bd6f17d050e5174a85b90 (patch)
tree47a39f2a1e980cca43c28c4d1a6dfdf431b910b2 /contrib/wakeonlan
parentQuickly hacked to use a buffer rather than a processor. (diff)
downloadipxe-1097cf8685cd81f0003bd6f17d050e5174a85b90.tar.gz
ipxe-1097cf8685cd81f0003bd6f17d050e5174a85b90.tar.xz
ipxe-1097cf8685cd81f0003bd6f17d050e5174a85b90.zip
Initial revision
Diffstat (limited to 'contrib/wakeonlan')
-rw-r--r--contrib/wakeonlan/Makefile37
-rw-r--r--contrib/wakeonlan/README3
-rw-r--r--contrib/wakeonlan/maclist.txt9
-rw-r--r--contrib/wakeonlan/mp-form.pl172
-rw-r--r--contrib/wakeonlan/mp-form.txt26
-rw-r--r--contrib/wakeonlan/mp-form1.pl171
-rw-r--r--contrib/wakeonlan/readme.txt35
-rw-r--r--contrib/wakeonlan/wake.pl116
-rw-r--r--contrib/wakeonlan/wakeserver.patch179
-rw-r--r--contrib/wakeonlan/wakeup.pl86
-rw-r--r--contrib/wakeonlan/wakeup.txt9
-rw-r--r--contrib/wakeonlan/wol.c374
12 files changed, 1217 insertions, 0 deletions
diff --git a/contrib/wakeonlan/Makefile b/contrib/wakeonlan/Makefile
new file mode 100644
index 00000000..563faa93
--- /dev/null
+++ b/contrib/wakeonlan/Makefile
@@ -0,0 +1,37 @@
+## 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)
+
diff --git a/contrib/wakeonlan/README b/contrib/wakeonlan/README
new file mode 100644
index 00000000..03b7e61c
--- /dev/null
+++ b/contrib/wakeonlan/README
@@ -0,0 +1,3 @@
+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.
diff --git a/contrib/wakeonlan/maclist.txt b/contrib/wakeonlan/maclist.txt
new file mode 100644
index 00000000..b96b3e44
--- /dev/null
+++ b/contrib/wakeonlan/maclist.txt
@@ -0,0 +1,9 @@
+# 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
diff --git a/contrib/wakeonlan/mp-form.pl b/contrib/wakeonlan/mp-form.pl
new file mode 100644
index 00000000..144b507f
--- /dev/null
+++ b/contrib/wakeonlan/mp-form.pl
@@ -0,0 +1,172 @@
+#!/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";
+ }
+}
+
diff --git a/contrib/wakeonlan/mp-form.txt b/contrib/wakeonlan/mp-form.txt
new file mode 100644
index 00000000..2c2ca5b8
--- /dev/null
+++ b/contrib/wakeonlan/mp-form.txt
@@ -0,0 +1,26 @@
+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
diff --git a/contrib/wakeonlan/mp-form1.pl b/contrib/wakeonlan/mp-form1.pl
new file mode 100644
index 00000000..d42624a5
--- /dev/null
+++ b/contrib/wakeonlan/mp-form1.pl
@@ -0,0 +1,171 @@
+#!/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";
+ }
+}
+
diff --git a/contrib/wakeonlan/readme.txt b/contrib/wakeonlan/readme.txt
new file mode 100644
index 00000000..94f2ef34
--- /dev/null
+++ b/contrib/wakeonlan/readme.txt
@@ -0,0 +1,35 @@
+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
diff --git a/contrib/wakeonlan/wake.pl b/contrib/wakeonlan/wake.pl
new file mode 100644
index 00000000..d9be35b7
--- /dev/null
+++ b/contrib/wakeonlan/wake.pl
@@ -0,0 +1,116 @@
+#!/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);
+}
diff --git a/contrib/wakeonlan/wakeserver.patch b/contrib/wakeonlan/wakeserver.patch
new file mode 100644
index 00000000..43e78b1d
--- /dev/null
+++ b/contrib/wakeonlan/wakeserver.patch
@@ -0,0 +1,179 @@
+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
diff --git a/contrib/wakeonlan/wakeup.pl b/contrib/wakeonlan/wakeup.pl
new file mode 100644
index 00000000..83cf363a
--- /dev/null
+++ b/contrib/wakeonlan/wakeup.pl
@@ -0,0 +1,86 @@
+#!/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);
+}
diff --git a/contrib/wakeonlan/wakeup.txt b/contrib/wakeonlan/wakeup.txt
new file mode 100644
index 00000000..b96b3e44
--- /dev/null
+++ b/contrib/wakeonlan/wakeup.txt
@@ -0,0 +1,9 @@
+# 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
diff --git a/contrib/wakeonlan/wol.c b/contrib/wakeonlan/wol.c
new file mode 100644
index 00000000..07b7e4fc
--- /dev/null
+++ b/contrib/wakeonlan/wol.c
@@ -0,0 +1,374 @@
+/*****************************************************************************
+ *
+ * wol.c - Wake-On-LAN utility to wake a networked PC
+ *
+ * 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 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.
+ */
+
+#define VERSION "1.12.2 (c) G.Knauf http://www.gknw.de/"
+
+#include <errno.h>
+#include <stdio.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
+
+#endif
+
+static int read_file (char *destfile);
+static int in_ether (char *bufp, unsigned char *addr);
+static int send_wol (char *dest, char *host);
+
+
+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++;
+ }
+ 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);
+ }
+}
+
+
+
+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++)
+ for (i = 0; i < 6; i++)
+ *ptr++ = ethaddr [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);
+}
+