« 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

コメント

コメントしてください




保存しますか?