Created
May 26, 2024 11:42
-
-
Save santaklouse/f7e024922cd53c2bb04fd92531d92b89 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
import os | |
import logging | |
import psutil | |
WOL_PORT = 9 | |
INTERFACE_NAME = 'Ethernet 4' | |
logging.basicConfig(format='%(levelname)s: %(asctime)s %(message)s', level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
def get_ip_mac_address(interface_name: str) -> tuple: | |
ip_addr = mac_addr = None | |
for item in psutil.net_if_addrs()[interface_name]: | |
addr = item.address | |
# В IPv4-адресах разделители - точки | |
if '.' in addr: | |
ip_addr = addr | |
# В MAC-адресах разделители либо тире, либо одинарное двоеточие. | |
# Двойное двоеточие - это разделители для адресов IPv6 | |
elif ('-' in addr or ':' in addr) and '::' not in addr: | |
# Приводим MAC-адрес к одному формату. Формат может меняться в зависимости от ОС | |
mac_addr = addr.replace(':', '-').upper() | |
if not ip_addr or not mac_addr or ip_addr == '127.0.0.1': | |
raise 'Не удалось получить IP или MAC-адрес сетевого интерфейса' | |
return ip_addr, mac_addr | |
def assemble_wol_packet(mac_address: str) -> str: | |
return f'{"FF-" * 6}{(mac_address + "-") * 16}' | |
def check_is_wol_packet(raw_bytes: bytes, assembled_wol_packet: str) -> int: | |
decoded_packet_data = '-'.join(f'{byte:02x}' for byte in raw_bytes).upper() + '-' | |
if decoded_packet_data == assembled_wol_packet: | |
return 1 | |
return 0 | |
def run_udp_port_listener(port: int, interface_name: str): | |
ip_addr, mac_addr = get_ip_mac_address(interface_name) | |
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
server_socket.bind((ip_addr, port)) | |
logger.info(f'Listening on {ip_addr}:{port}') | |
assembled_wol_packet = assemble_wol_packet(mac_addr) | |
while True: | |
data, _ = server_socket.recvfrom(1024) | |
is_wol_packet = check_is_wol_packet(data, assembled_wol_packet) | |
if is_wol_packet == 1: | |
if os.name == 'posix': | |
os.system('sudo shutdown -h now') | |
elif os.name == 'nt': | |
os.system('shutdown -s -t 0 -f') | |
run_udp_port_listener(WOL_PORT, INTERFACE_NAME) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment