Mon, 8th Sep 2008 04:47:09
Never fear, this site is here

#wirewake.py

Language: Python
Written by doug on 2008-01-29 23:15:00

#!/usr/bin/python
#####
# author: doug@neverfear.org
# ----------------
# wirewake - a "magic packet" implementation for Wake-On-Lan 
# enabled network interfaces. Please report any errors to the
# above E-Mail.
#####
import socket, re, sys, os

hwaddr = ""
port = socket.getservbyname('discard', 'udp')
proto = socket.getprotobyname('udp');
ip = "255.255.255.255"
verbose = 0
force = False
password = ""

def printpkt(pkt):
	print "Packet dump (" + str(len(pkt)), "bytes):"
	i = 0
	for b in pkt:
		print hex(ord(b))[2:].zfill(2).upper(),
		i = i + 1
		if i % 6 == 0: print 
	print

def checkpkt(pkt):
	if len(pkt) <= 102 or len(pkt) >= 108:
		return False
	return True

def printsettings():
	global hwaddr, port, ip, verbose, force, password
	if verbose >= 2:
		print "target hwaddr:", hwaddr
		print "port:", port
		print "ip:", ip
		print "force:", force
		print "verbosity level:", verbose
		print

def valid_hwaddr(hwaddr):
	# Accepts MAC strings in:
	# 00:11:22:33:44:55
	# and
	# 00-11-22-33-44-55
	# formats only.
	result = re.split("[0-9A-Fa-f]{2}", hwaddr)
	if not len(result) == 7: return False
	elif not result.count("") == 2: return False
	elif result.count(":") == 5: return True
	elif result.count("-") == 5: return True
	else: return False # "what the.. is going on?"

def usage():
	print "wirewake [-vVfh] [-i ipaddr] [-p port] [-P pass] [hardware_address]"
	print "\t-v  increase verbosity level"
	print "\t-V  print version information"
	print "\t-f  force continuation against any checks"
	print "\t-h  display this help screen"
	print "\t-p  set port"
	print "\t-i  set IP address"
	print "\t-P  set password"
	print

if len(sys.argv) <= 1:
	usage()
	sys.exit(1)
i = 1
while i < len(sys.argv):
	arg = sys.argv[i]
	if arg[0] == '-':
		# switch
		for c in arg[1:]:
			if c == 'v': verbose = verbose + 1
			elif c == 'V': print "wirewake version 1.0"
			elif c == 'f': force = True
			elif c == 'h':
				usage()
				sys.exit(1)
			elif c == 'i':
				i = i + 1
				ip = sys.argv[i]
				break
			elif c == 'p':
				i = i + 1
				port = int(sys.argv[i])
				break
			elif c == 'P':
				i = i + 1
				password = sys.argv[i]
				break
	else: hwaddr = sys.argv[i]
	i = i + 1

printsettings()

if not valid_hwaddr(hwaddr):
	print "Invalid Hardware Address parameter:", hwaddr
	sys.exit(2)

sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, proto)
sck.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

pkt = ""
for i in range(6):
	pkt += chr(0xFF)

splitchr = ":"
if hwaddr.find("-") >= 0: splitchr = "-"

for i in range(16):
	for a in hwaddr.split(splitchr):
		pkt += chr(int(a, 16))

if not(len(password) == 4 or len(password) == 6) and len(password) > 0:
	print "Invalid password. Password must be a byte string, 4 or 6 bytes long"
	if not force: sys.exit(3)

pkt += password
badpkt = checkpkt(pkt)
if badpkt or verbose:
	printpkt(pkt)
	if badpkt:
		print "Error generating packet. Size should be between 102 and 108 bytes, size is:", len(pkt)
		if not force:
			print "Use -f to force this anyway"
			sys.exit(4)

print "Sending packet to", ip, "on port", port
try:
	sck.sendto(pkt, (ip, port))
except socket.error, (code, msg):
	if code:
		print "Please check the IP and Port, they are not valid arguments"
		sys.exit(5)
	else: print msg
sck.close()
Powered by Debian, Jack Daniels, Guinness, and excessive quantities of caffeine and sugar.