Skip to content

Instantly share code, notes, and snippets.

@santaklouse
Created May 26, 2024 11:42
Show Gist options
  • Save santaklouse/f7e024922cd53c2bb04fd92531d92b89 to your computer and use it in GitHub Desktop.
Save santaklouse/f7e024922cd53c2bb04fd92531d92b89 to your computer and use it in GitHub Desktop.
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