summaryrefslogtreecommitdiffstats
path: root/contrib/wakeonlan/mp-form1.pl
blob: d42624a57be7fe68fec9f59c280f65bf7361bffd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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";
  }
}