server.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #!/usr/bin/env python3
  2. import socket
  3. import platform
  4. from subprocess import check_output, Popen
  5. INVALID = "INVALID"
  6. WAKE = "WAKE"
  7. SLEEP = "SLEEP"
  8. OTHERS = "OTHERS"
  9. def parse_magic_packet(packet):
  10. frame = packet[0:6].hex()
  11. macs = set()
  12. for _ in range(0, 16):
  13. packet = packet[6:]
  14. mac = packet[:6].hex()
  15. macs.add(mac)
  16. if frame != "ff"*6 or len(macs) != 1:
  17. return INVALID
  18. mac = list(macs)[0].lower()
  19. if mac in MACS:
  20. return WAKE
  21. if mac[::-1] in MACS:
  22. return SLEEP
  23. return OTHERS
  24. def get_windows_macs():
  25. import re
  26. out = check_output(["ipconfig", "/all"]).decode("ascii").split("\n")
  27. match_mac = r"\s(?P<mac>[0-9a-f-]{17})\s"
  28. ret = []
  29. for line in out:
  30. matches = re.search(match_mac, line, flags=re.IGNORECASE)
  31. if matches:
  32. ret.append(matches.group("mac").replace("-", "").lower())
  33. return ret
  34. def get_linux_macs():
  35. import netifaces
  36. ret = []
  37. ifaces = netifaces.interfaces()
  38. ifaces.remove('lo')
  39. for i in ifaces:
  40. addresses = netifaces.ifaddresses(i)[netifaces.AF_LINK]
  41. ret.append(addresses[0]['addr'].replace(":", "")).lower()
  42. return ret
  43. def get_macs():
  44. if platform.system() == 'Windows':
  45. return get_windows_macs()
  46. else:
  47. return get_linux_macs()
  48. def suspend():
  49. if platform.system() == 'Windows':
  50. Popen(["rundll32.exe", "powrprof.dll,SetSuspendState", "0,1,0"])
  51. else:
  52. Popen(["systemctl", "suspend"])
  53. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  54. sock.bind(('', 9))
  55. MACS = get_macs()
  56. while True:
  57. msg, addr = sock.recvfrom(1024)
  58. res = parse_magic_packet(msg)
  59. print(res)
  60. if res == "SLEEP":
  61. suspend()