wakeonlan: Added Wake-on-LAN magic packet sender script
parent
7bfdae8ec5
commit
062569a111
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/python
|
||||
'''Send a Wake-on-LAN magic packet
|
||||
|
||||
This program can be used to send a Wake-on-LAN magic packet to a host
|
||||
on the local network. A WOL magic packet consists of 6 bytes of all
|
||||
ones, followed by sixteen repetitions of the target system's hardware
|
||||
(MAC) address. A WOL magic packet can be sent to any network (IP)
|
||||
address, as the contents of the packet are only inspected for the
|
||||
exact contents above, regardless of other header information.
|
||||
Typically, magic packets are broadcast, either to the limited
|
||||
broadcast address (255.255.255.255) or the network broadcast
|
||||
address to ensure that routers and switches will forward them to
|
||||
the desired destination host.
|
||||
|
||||
:Author: Dustin C. Hatch <dustin@hatch.name>
|
||||
:Copyright: 2014 Dustin C. Hatch
|
||||
:License: Apache 2.0
|
||||
'''
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
|
||||
|
||||
def wake(mac_addr, ip_addr='255.255.255.255', port=9):
|
||||
'''Send a Wake-on-LAN magic packet
|
||||
|
||||
:param mac: Destination hardware (MAC) address
|
||||
'''
|
||||
|
||||
# strip all formatting characters from the given
|
||||
# address and convert it to an integer.
|
||||
# this allows any formatting variant to be accepted,
|
||||
# including:
|
||||
# * standard: 00:11:22:aa:bb:cc
|
||||
# * Windows: 00-11-22-AA-BB-CC
|
||||
# * Cisco: 0011.22AA.BBCC
|
||||
mac_int = int(re.sub('[^0-9a-f]', '', mac_addr.lower()), 16)
|
||||
# separate the address into eight-bit pieces (as integers)
|
||||
mac_intlist = []
|
||||
while mac_int > 0:
|
||||
mac_intlist.insert(0, mac_int & 0xff)
|
||||
mac_int >>= 8
|
||||
|
||||
# convert the 6 integers to a byte string
|
||||
# and generate the preamble
|
||||
if str is bytes: # Python 2
|
||||
payload = '\xff' * 6
|
||||
mac = ''.join(chr(b) for b in mac_intlist)
|
||||
else:
|
||||
payload = bytes((0xff,) * 6)
|
||||
mac = bytes(mac_intlist)
|
||||
|
||||
# populate the remainder of the packet payload by repeating
|
||||
# the destination hardware address
|
||||
for _ in range(16):
|
||||
payload += mac
|
||||
|
||||
# open a UDP-IP broadcast socket and send the packet
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||
s.connect((ip_addr, port))
|
||||
s.send(payload)
|
||||
s.close()
|
||||
|
||||
|
||||
def _parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-i', dest='ip_address', metavar='ADDRESS',
|
||||
default='255.255.255.255',
|
||||
help='destination IP address')
|
||||
parser.add_argument('-p', dest='port', metavar='PORT', type=int,
|
||||
default=9, help='destination UDP port')
|
||||
parser.add_argument('-f', dest='macfile', metavar='FILE',
|
||||
help='read destination hardware addresses from FILE')
|
||||
parser.add_argument('address', help='destination hardware (MAC) address',
|
||||
nargs='*')
|
||||
args = parser.parse_args()
|
||||
if not args.address and not args.macfile:
|
||||
parser.error('No hardware address given')
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
args = _parse_args()
|
||||
|
||||
if args.macfile:
|
||||
with open(args.macfile) as f:
|
||||
for line in f.readlines():
|
||||
# each address in the file can be followed by a comment
|
||||
mac, _ = line.split(None, 1)
|
||||
wake(mac, args.ip_address, args.port)
|
||||
else:
|
||||
for mac in args.address:
|
||||
wake(mac, args.ip_address, args.port)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue