« Perl の Net::Ping モジュール | メイン | Perl でデータベースを操作する実験 »
2004年02月22日
Wake up on LAN の実験
管理しているPCが離れたところにあったり、数が多かったりすると、電源を入れるだけでも結構大変である。多くの作業を自動化するように工夫していて、電源を入れるところだけは手動というのも悔しい。そういうときに使えるのが Wake up on LAN。文字通り LAN 経由で、PCを起こしてくれる。
方法としては、マジックパケットと呼ばれるパケットをターゲットのPCに届けてやれば良いらしい。
http://www3.jpn.hp.com/CPO_TC/pc/doc/34602.pdf によるとマジックパケットというのは、6個の FF(16進)のあと、MACアドレスを16回以上繰り返したものだそうである。
Perl によるスクリプトがhttp://adlib.rsch.tuis.ac.jp/~akira/unix/にあった。
自分用に書き直したのが、以下のスクリプト。複数のPCをターゲットにするよう書きかえるのも簡単である。(MAC address と Broadcast IP address を書き換えてから試してみてほしい。)
use Socket; # # wake up on LAN # # ターゲットの MAC address と Broadcast IP address $ret=wakeup_on_lan("00-11-22-33-44-55", "10.255.255.255"); print $ret if $ret; # # wakeup_on_lan(MACアドレス, ブロードキャストアドレス) # エラーのときはエラーの内容を示す文字列を返す。 # エラーでないときは空文字列を返す。 sub wakeup_on_lan{ my($mac_address, $broadcast_address)=@_; my($macstr, $remote_port,$proto,$iaddr,$paddr,$pac); # MAC address decode $mac_address=~s/-//g; $macstr=pack("H12", $mac_address); # Magic Packet create $pac = "\xff\xff\xff\xff\xff\xff"; for($i=0; $i<20;$i++) { $pac .=$macstr; } # open socket $remote_port="7"; $proto=getprotobyname('udp'); socket(S, PF_INET, SOCK_DGRAM, $proto) or return "ERROR at open socket: $!"; setsockopt(S, SOL_SOCKET, SO_BROADCAST,1) or return "ERROR at sockopt: $!"; # send Magic Packet $iaddr=inet_aton($broadcast_address) or return "ERROR at get broadcast address: $!"; $paddr=sockaddr_in($remote_port,$iaddr) or return "ERROR at make broadcast: $!"; send(S,$pac,0,$paddr) or return "ERROR at send broadcast:$!"; return(""); }
マジックパケットの送り先が1台なのにブロードキャストを使うには理由がある。 届きさえすれば、ブロードキャストでなくてもよいのだが、arp テーブルがクリアされたりしていると届かない。ブロードキャストを使えば、そういうことは気にしなくて良くなる。
UDP の port 7 を使っているが、実験してみると port 番号は適当で良いようだ。
ターゲットの MAC アドレスが必要になるが、電源が入っているときに ping を飛ばしてから arp コマンドを使って、arp -a とやれば簡単に調べられる。
がんばれば、LAN だけでなくインターネット経由で Wake up on LAN を行うこともできるらしい。
http://bb.watch.impress.co.jp/column/shimizu/2003/09/16/
投稿者 augustus : 2004年02月22日 05:54