1

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())