58 lines
1.7 KiB
Python
Executable File
58 lines
1.7 KiB
Python
Executable File
#! /usr/bin/env python3
|
|
import argparse
|
|
import sys
|
|
import logging
|
|
import socket
|
|
import struct
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def main() -> int:
|
|
# Handle program arguments
|
|
ap = argparse.ArgumentParser(prog="wol", description="Wake On LAN")
|
|
ap.add_argument("mac", help="MAC address of the target machine")
|
|
ap.add_argument(
|
|
"-p", "--port", help="UDP port to send the magic packet to", type=int, default=9
|
|
)
|
|
ap.add_argument(
|
|
"-v", "--verbose", help="Enable verbose logging", action="store_true"
|
|
)
|
|
args = ap.parse_args()
|
|
|
|
# Configure logging
|
|
logging.basicConfig(
|
|
level=logging.DEBUG if args.verbose else logging.INFO,
|
|
format="%(levelname)s: %(message)s",
|
|
)
|
|
|
|
# Parse MAC address
|
|
mac = args.mac.replace(":", "").replace("-", "").replace(".", "")
|
|
if len(mac) != 12:
|
|
logger.error("Invalid MAC address")
|
|
return 1
|
|
mac = bytes.fromhex(mac)
|
|
|
|
# Create magic packet
|
|
magic_packet = b"\xff" * 6 + mac * 16
|
|
|
|
# Try to broadcast magic packet over both IPv4 and IPv6
|
|
try:
|
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
|
s.sendto(magic_packet, ("<broadcast>", args.port))
|
|
except OSError as e:
|
|
logger.error("Failed to broadcast magic packet over IPv4: %s", e)
|
|
try:
|
|
with socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) as s:
|
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
|
s.sendto(magic_packet, ("ff02::1", args.port))
|
|
except OSError as e:
|
|
logger.error("Failed to broadcast magic packet over IPv6: %s", e)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|