-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpywake.py
79 lines (70 loc) · 2.51 KB
/
pywake.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# PyWake - Python Wake-On-LAN client
#
# Copyright 2013 Michal Belica <[email protected]>
#
# This file is part of PyWake.
#
# PyWake is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyWake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PyWake. If not, see <http://www.gnu.org/licenses/>.
import socket
import sys
import binascii
__version__ = '0.1.3'
IPV6_DEST = 'ff02::1'
IPV4_DEST = '255.255.255.255'
MP_START = binascii.a2b_hex('ffffffffffff')
address_family = {
6: socket.AF_INET6,
4: socket.AF_INET,
0: socket.AF_UNSPEC,
}
af2text = {
socket.AF_INET6: 'IPv6',
socket.AF_INET: 'IPv4',
}
class MagicPacket(bytes):
def __new__(self, mac):
self.mac = ''.join( (x for x in mac if x not in '.:-') )
self.bytemac = binascii.a2b_hex(self.mac)
return super(MagicPacket, self).__new__(self,
MP_START + self.bytemac * 16)
class PyWake(object):
def __init__(self, mac, src_ip=None, dst_ip=None, port=9, ipv=0):
self.mac = mac
self.src_ip = src_ip
self.dst_ip = dst_ip
self.ipv = ipv
self.port = port
def send_packet(self):
if self.dst_ip:
dest = self.dst_ip
elif self.ipv == 4:
dest = IPV4_DEST
else:
dest = IPV6_DEST
for res in socket.getaddrinfo(dest, self.port,
address_family[self.ipv], socket.SOCK_DGRAM):
af, socktype, proto, canonname, sa = res
print('sending %s packet%s to IP %s for MAC %s' % (
af2text[af],
(' from IP ' + self.src_ip) if self.src_ip else '',
sa[0],
self.mac
))
s = socket.socket(af, socktype, proto)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
if self.src_ip:
s_addr = socket.getaddrinfo(self.src_ip, None, af, socket.SOCK_DGRAM, 0, socket.AI_PASSIVE)[0][4]
s.bind(s_addr)
packet = MagicPacket(self.mac)
s.sendto(packet, sa)