今まで、遠隔からPCの電源を入れる場合、Wake on LAN 用のツールを使っていました。
Wake-on-LAN - Wikipedia
そこで今回、ScapyでWake on LANのマジックパケットを作ってみて、ツールの代替となるかを試してみました。
目次
環境
ネットワーク構成
----------------------------------------- Raspberry Pi 2 Model B (`eth0` : オンボードLANアダプタ) ----------------------------------------- | | ----------------------------------------- スイッチングハブ ----------------------------------------- | | ----------------------------------------- (外付けUSB有線LANアダプタ) Windows10 (オンボードLANアダプタ) -----------------------------------------
ネットワークアダプタ設定
明示的に設定したネットワークアダプタ設定です。
なお、以降の表記は
- Raspberry Pi 2 Model B = ラズパイ
- Windows10のThinkPad X201s = X201s
- DGW = デフォルトゲートウェイ
とします。
機器 | アダプタ | IPアドレス | DGW | DNS |
---|---|---|---|---|
ラズパイ | eth0 | 192.168.10.50/24 | 192.168.10.1 | 192.168.10.1 |
X201s | USB有線 | 192.168.10.201/24 | 192.168.10.1 | 192.168.10.1 |
X201s | オンボード | DHCP | DHCP | DHCP |
各機器の構成
以前、ブリッジやルータを自作した時と同じ構成です。
- マジックパケットを送信する端末
- Raspberry Pi 2 Model B
- マジックパケットを受信し、起動する端末
- ThinkPad X201s
- Windows10
- 外付けUSB有線LANアダプタ(LUA4-U3-AGT)
- ThinkPad X201s
Wake on LANができる環境を調査
Wake on LANができる環境を調査するため、いろいろと試してみましたので、それらのメモを残します。
試してみたこと
[NG] Macからマジックパケットを送信できるか
当初MacからWiFi経由でマジックパケットを送信しようとしましたが、手元の環境が良くないのか、MacからX201sへのWake on LANは成功しませんでした。
そのため、今回はMacからマジックパケットを送信するのはあきらめました。
[NG] Wake on LANでラズパイを起動できるか
Wake on LANでラズパイを起動してみようと思いました。
しかし、以下にある通り、Wake on LANではラズパイは起動しないことが分かりました。
- networking - How do I enable Wake On LAN? - Raspberry Pi Stack Exchange
- Any success using WOL on a RPi - Raspberry Pi Forums
そのため、Wake on LANでラズパイを起動することもあきらめました。
[NG] Wake on LAN + オンボードLANアダプタで、Windows10のX201sを起動できるか
元々、X201sではWake on LANができそうでした。ただ、Windows10のX201sで試してみたところ、起動しませんでした。
そのため、Windows10版向けのLANアダプタドライバを探してみました。
すると、LenovoではX201sがEOL扱いとなっており、Windows10版のドライバ提供はありませんでした。
Device Drivers File Matrices - ThinkPad X201s
そのため、Windows10のX201sのオンボードLANアダプタを使ってWake on LANすることもあきらめました。
[OK] X201s + 外付けUSB有線LANアダプタで起動するか
X201sに外付けUSB有線LANアダプタのLUA4-U3-AGTをつないでみたところ、アダプタのプロパティに Wake on LAN関係の設定がありました。
そこで、それらの設定を有効化後、X201sのLUA4-U3-AGT宛にマジックパケットを送信したところ、Wake on LANができました。
そのため、
- ラズパイからマジックパケットを送信
- X201sをWake on LANで起動
の構成で試すことにしました。
Wake on LANするための設定
今回、LUA4-U3-AGTでWake on LANするため、LUA4-U3-AGTの アダプターのプロパテイ > ネットワークタブの構成ボタン > 電源の管理タブ
より
- このデバイスで、コンピューターのスタンバイ状態を解除できるようにする
- Magic Packet でのみ、コンピューターのスタンバイ状態を解除できるようにする
の2つにチェックを入れました。
一方、オンボードのLANアダプタではなかったせいか、
- BIOSのWake on LAN設定を無効
Config > Network > Wake On LAN
を[Disabled]
にする
- 高速スタートアップを有効化
コントロールパネル > 電源オプション > システム設定(電源ボタンの動作を選択する) > 現在利用可能ではない設定を変更します > 高速スタートアップを有効にする
のチェックを入れたまま
としても、Wake on LANができました。
ただ、スリープ状態の時はWake on LANできましたが、電源OFFの時はできませんでした。
とはいえ、今回はWake on LANができればよかったので、電源OFFの時の対応は気にしないことにしました。
Scapyでマジックパケットを送信する
マジックパケットのフォーマットについて
以下を参考にしました。
ScapyでUDPデータを設定する方法について
マジックパケットを送信するにはUDPでデータを送信する必要があります。
そのため、方法を調べてみたところ、Rawクラスを使い、データ部分は decode('hex')
すれば良さそうでした。
scapy command for defining the data part of udp packet - Stack Overflow
なお、 decode('hex')
はPython2系のみ利用可能ですが、今回使うScapyはPython2なため、気にしないことにしました。
How to create python bytes object from long hex string? - Stack Overflow
ソースコード全体
wake_on_lan.py
# -*- coding: utf-8 -*- # from scapy.allでも良い from scapy.sendrecv import sendp from scapy.layers.l2 import Ether from scapy.layers.inet import IP, UDP, Raw # 必要に応じて、宛先のMACアドレスに変更する TARGET_MAC_ADDRESS = '88:xx:xx:xx:xx:xx' PREFIX_PAYLOAD = 'ff' * 6 BROADCAST_MAC_ADDRESS = 'FF:FF:FF:FF:FF:FF' LIMITED_BROADCAST_IP_ADDRESS = '255.255.255.255' def send_magic_packet(): # マジックパケットの仕様に従い、文字列でペイロードを準備 str_payload = PREFIX_PAYLOAD + (TARGET_MAC_ADDRESS.replace(':', '') * 16) hex_payload = str_payload.decode('hex') ether_layer = Ether(dst=BROADCAST_MAC_ADDRESS) ip_layer = IP(dst=LIMITED_BROADCAST_IP_ADDRESS) udp_layer = UDP() raw_layer = Raw(load=hex_payload) magic_packet = ether_layer / ip_layer / udp_layer / raw_layer # ブリッジやルータと異なり、戻りパケットの受け取りは不要 # そのため、sendp()関数でL2パケットを送信するだけで良い sendp(magic_packet) if __name__ == '__main__': send_magic_packet()
実行結果
X201sをスリープにした後、上記スクリプトを実行してみたところ、
pi@raspberrypi:~/scapy_sample/wol $ sudo python wake_on_lan.py . Sent 1 packets.
X201sが起動しました。
これにより、Scapyでマジックパケットが正しく作成・送信できたと分かりました。
ソースコード
GitHubに上げました。wol/wake_on_lan.py
が今回のファイルです。
https://github.com/thinkAmi-sandbox/scapy-sample