My favorites
▼
|
Sign in
sevenever
sevenever's s open source code repository
Project Home
Downloads
Wiki
Issues
Source
Checkout
Browse
Changes
Source path:
svn
/
trunk
/
misc
/
wol.py
‹r138
r234
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/python
import sys
import struct
import string
import random
from socket import *
def usage():
print """send UDP packet to broadcasting address to remote wakeup
UDP package format is FFFFFFFFFFFF0017314BACCB....................
(fixed 6 FF)( mac )(repeat mac 15 times)
usage: wol.py broadcasting_address udp_port target_host_mac
example: wol.py sevenever.vicp.net 4672 0017314BACCB
If udp_port is 53, will try to wrap wol message into a dns query,
that will cheat most firewall which prevent you sending udp package except for DNS query.
Notice(!): if the firewall is so strict that it check DNS query for legality of querying domain name,
this wrap will not help because domain name never contains 0xFF.
"""
def main():
if len(sys.argv) != 4:
usage()
return 1
bc_addr = sys.argv[1]
udp_port = int(sys.argv[2])
if udp_port < 1 or udp_port > 65535:
sys.stderr.write('udp_port error')
return 2
mac = sys.argv[3]
if len(mac) != 12 or len(set(mac) - set(string.hexdigits)) > 0:
sys.stderr.write('invalid mac address')
return 2
hw_addr = struct.pack('!BBBBBB', int(mac[0:2], 16),
int(mac[2:4], 16),
int(mac[4:6], 16),
int(mac[6:8], 16),
int(mac[8:10], 16),
int(mac[10:12], 16))
if int(udp_port) == 53:
# wrap into a dns query
# dns head
dnspkg = struct.pack('!HHHHHH',
random.randint(0,65536), # Transaction ID
256, # Flags
1,0,0,0) # Questions, Answer PRs, Authority PRs, Additional PRs
# try to construct a fake dns query to wrap wol message
hn = '\xff' * 6 + hw_addr * 8 # 6 0xff and former 8 mac can be wrap into a lable with length 54
# 8 mac left to try
macs = map(''.join, map(None, mac[::2], mac[1::2]))
for i in range(7): # this 7 is 6(bytes of mac)+1, no relation with the number of remaining mac addresses
index = i
while index<48:
val = int(macs[index%6], 16)
if val == 0 or val > 63:
# invalid label length
break
index += val+1
if index >= 48:
# can be wrapped into domain name part
hn = chr(6+8*6+i) + hn + hw_addr * 8
lblchrfunc = lambda x:random.choice(string.letters+string.digits)
# padding label
lbllen = index - 48
hn += random.choice(string.letters) + ''.join(map(lblchrfunc, range(lbllen-1)))
# sldn (second level domain name)
lbllen = random.randint(1, 63)
hn += chr(lbllen) + random.choice(string.letters) + ''.join(map(lblchrfunc, range(lbllen-1)))
# tld (top level domain name)
tld = random.choice(['com','net','org','edu'])
hn += chr(len(tld)) + tld
break
else:
# cannot wrap wol message into domain name part of a dns query
# send it as dns query anyway
sys.stderr.write('WARNING: can not wrap wol magic package into a integrated dns query package, but still try to send it as a dns query.')
hn = chr(6+16*6) + hn
hn += hw_addr * 7
msg = dnspkg + hn + '\x00' + '\x00\x01' * 2
else:
# send a nake wol message
msg = '\xff' * 6 + hw_addr * 16
sk = socket(AF_INET, SOCK_DGRAM)
sk.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
sk.sendto(msg, (bc_addr, udp_port))
sk.close()
if __name__ == '__main__':
sys.exit(main())
Show details
Hide details
Change log
r140
by sevenever on Dec 12, 2009
Diff
[No log message]
Go to:
/trunk/misc/wol.py
Sign in
to write a code review
Older revisions
r138
by sevenever on Dec 6, 2009
Diff
wol update, fake dns query
r119
by sevenever on May 21, 2009
Diff
wake on lan
All revisions of this file
File info
Size: 3944 bytes, 98 lines
View raw file
Powered by
Google Project Hosting