#!/usr/bin/perl -w #Script to wake-up machines with EUI64 IPv6 addresses my $toaddr="255.255.255.255"; die "usage: $0 hostname\n" if (!defined($ARGV[0])); use Net::DNS; use Socket; my $addr; if ($ARGV[0] =~ /:/) { $addr = $ARGV[0]; } else { my $resolver=Net::DNS::Resolver->new; my $query=$resolver->query($ARGV[0],"AAAA") or die "Can't lookup host\n"; foreach $record ($query->answer) { next unless $record->type eq "AAAA"; $addr = $record->address; last; } } #IPv6 address expansion if ( $addr=~ /::/ ) { my $pos = -1; for ( my $ccount=7; $ccount > 0; $ccount--) { next if (($pos=index($addr,":",$pos+1)) != -1); $addr=~s /::/:0000::/; $pos=length($addr)+1; } $addr=~s /::/:0000:/g; } $addr=~s /^(.*)$/:$1:/; $addr=~s /:(.):/:000$1:/g; $addr=~s /:(.):/:000$1:/g; $addr=~s /:(..):/:00$1:/g; $addr=~s /:(..):/:00$1:/g; $addr=~s /:(...):/:0$1:/g; $addr=~s /:(...):/:0$1:/g; $addr=~s /:(.*):/$1/; die "Invalid address $addr\n" if ( ! ($addr=~ /^[[:xdigit:]]{4}:[[:xdigit:]]{4}:[[:xdigit:]]{4}:[[:xdigit:]]{4}:([[:xdigit:]]{4}:[[:xdigit:]]{4}:[[:xdigit:]]{4}:[[:xdigit:]]{4})$/) ); #Enet my $enet = $1; $enet=~s /://g; die "${addr} is not EUI64!\n" if (!($enet=~ /^(......)fffe(......)$/i)); $enet=$1.$2; $enet=~ /^(..)(.*)$/; #2nd bit needs to be 0 $enet=sprintf("%2.2x",(hex($1) & (0xff-2))).$2; my $mac = pack "H12", $enet; $enet=~s /([^:]{2})/$1:/g; $enet=~s /:$//; print "Waking up ${enet}\n"; #WOL-Init my $wolpkg = pack "H12", "ffffffffffff"; for (my $i=0; $i < 16; $i++) { $wolpkg .= $mac; } socket($mysock, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or die "Can't create socket\n";; setsockopt($mysock, SOL_SOCKET, SO_REUSEADDR, 1); setsockopt($mysock, SOL_SOCKET, SO_BROADCAST, 1); bind($mysock, sockaddr_in(0, INADDR_ANY)) or die "can't bind\n"; $saddr = sockaddr_in(4211, inet_aton($toaddr)) or die "sockaddr failed\n"; send($mysock, $wolpkg, 0, $saddr); send($mysock, $wolpkg, 0, $saddr); send($mysock, $wolpkg, 0, $saddr); send($mysock, $wolpkg, 0, $saddr); send($mysock, $wolpkg, 0, $saddr);