commit 9cfb79545d1a5e8e2f15f127c1c2d6f0c48cc13d Author: Björn Benouarets Date: Tue Nov 11 20:39:44 2025 +0100 feat(cli): Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..0abf8d6 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# Wake on LAN (WOL) CLI tool with authentication support + +## Description + +This is a CLI tool that sends a Wake on LAN (WOL) packet to a target device. It supports authentication using a username and password. + +## Usage + +```bash +python wol.py -m AA:BB:CC:DD:EE:FF -u admin -p secret +``` + +## Arguments + +- `-m, --mac`: MAC address of the target device (format: XX:XX:XX:XX:XX:XX or XX-XX-XX-XX-XX-XX) +- `-u, --username`: Username for authentication +- `-p, --password`: Password for authentication +- `-H, --host`: Target host address (default: 255.255.255.255 for broadcast) +- `-P, --port`: Target UDP port (default: 9999) + +## Example + +```bash +python wol.py -m AA:BB:CC:DD:EE:FF -u admin -p secret -H 192.168.1.100 -P 9999 +``` + +## Notes + +- The tool sends a Wake on LAN packet to the target device using the UDP protocol. +- The tool supports authentication using a username and password. +- The tool supports broadcasting to the target host address. +- The tool supports specifying the target UDP port. + +## License + +This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details. \ No newline at end of file diff --git a/index.py b/index.py new file mode 100644 index 0000000..125b1dd --- /dev/null +++ b/index.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +""" +Wake-on-LAN CLI tool with authentication support. +Sends a magic packet over UDP port 9999 with AUTH format. +""" + +import socket +import argparse +import sys +from typing import Optional + + +def create_magic_packet(mac_address: str) -> bytes: + """ + Creates a Wake-on-LAN magic packet. + + Args: + mac_address: MAC address in format XX:XX:XX:XX:XX:XX or XX-XX-XX-XX-XX-XX + + Returns: + Magic packet as bytes (6 bytes 0xFF + 16 repetitions of MAC address) + """ + # Remove separators and convert to uppercase + mac = mac_address.replace(':', '').replace('-', '').upper() + + # Validate MAC address format (should be 12 hex characters) + if len(mac) != 12: + raise ValueError(f"Invalid MAC address format: {mac_address}") + + try: + # Convert MAC address to bytes + mac_bytes = bytes.fromhex(mac) + except ValueError as e: + raise ValueError(f"Invalid MAC address format: {mac_address}") from e + + # Magic packet: 6 bytes of 0xFF followed by 16 repetitions of MAC address + magic_packet = b'\xff' * 6 + mac_bytes * 16 + + return magic_packet + + +def send_wol_packet( + mac_address: str, + username: str, + password: str, + host: str = "255.255.255.255", + port: int = 9999 +) -> bool: + """ + Sends a Wake-on-LAN packet with authentication over UDP. + + Args: + mac_address: MAC address of the target device + username: Username for authentication + password: Password for authentication + host: Target host (default: broadcast address) + port: Target port (default: 9999) + + Returns: + True if packet was sent successfully, False otherwise + """ + try: + # Create magic packet + magic_packet = create_magic_packet(mac_address) + + # Create authentication header + auth_header = f"AUTH:{username}:{password}:".encode('utf-8') + + # Combine authentication header with magic packet + packet = auth_header + magic_packet + + # Create UDP socket + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + # Enable broadcast + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + + # Send packet + sock.sendto(packet, (host, port)) + sock.close() + + return True + + except Exception as e: + print(f"Error sending packet: {e}", file=sys.stderr) + return False + + +def main(): + """Main entry point for the CLI application.""" + parser = argparse.ArgumentParser( + description="Wake-on-LAN tool with authentication support", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + %(prog)s -m AA:BB:CC:DD:EE:FF -u admin -p secret + %(prog)s -m AA-BB-CC-DD-EE-FF -u user -p pass -H 192.168.1.100 -p 9999 + """ + ) + + parser.add_argument( + '-m', '--mac', + required=True, + help='MAC address of the target device (format: XX:XX:XX:XX:XX:XX or XX-XX-XX-XX-XX-XX)' + ) + + parser.add_argument( + '-u', '--username', + required=True, + help='Username for authentication' + ) + + parser.add_argument( + '-p', '--password', + required=True, + help='Password for authentication' + ) + + parser.add_argument( + '-H', '--host', + default='255.255.255.255', + help='Target host address (default: 255.255.255.255 for broadcast)' + ) + + parser.add_argument( + '-P', '--port', + type=int, + default=9999, + help='Target UDP port (default: 9999)' + ) + + args = parser.parse_args() + + # Send the Wake-on-LAN packet + print(f"Sending Wake-on-LAN packet to {args.mac}...") + print(f"Host: {args.host}:{args.port}") + print(f"Username: {args.username}") + + success = send_wol_packet( + mac_address=args.mac, + username=args.username, + password=args.password, + host=args.host, + port=args.port + ) + + if success: + print("Packet sent successfully!") + return 0 + else: + print("Failed to send packet.", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + sys.exit(main()) +