#!/usr/bin/env python
#
# Wake On Lan - Magic Packet 0.1
# Copyright (C) 2009 Damian Pasternok <my_forename at pasternok.org>
# This code is free software under the GPLv3+.
# For more information see <http://gnu.org/licenses/gpl.html>.
#
# Used some parts of code of:
# Brian McErlean <b_mcerlean@yahoo.com>
# http://mail.python.org/pipermail/python-list/2002-August/159592.html
# Marc Balmer <marc@msys.ch>
# http://gsd.di.uminho.pt/jpo/software/wakeonlan/mini-howto/wolpython.txt
### config
use_remote_tld_list = "no" # if set to "no" tld_local will be used
tld_remote = "http://data.iana.org/TLD/tlds-alpha-by-domain.txt"
### do not change tld_local unless you know what you are doing
# tld_local (Version 2017011600, Last Updated Mon Jan 16 07:07:01 2017 UTC)
tld_local = r"""aaa|aarp|abarth|abb|abbott|abbvie|abc|able|abogado|abudhabi|
ac|academy|accenture|accountant|accountants|aco|active|actor|ad|adac|ads|
adult|ae|aeg|aero|aetna|af|afamilycompany|afl|ag|agakhan|agency|ai|aig|
aigo|airbus|airforce|airtel|akdn|al|alfaromeo|alibaba|alipay|allfinanz|
allstate|ally|alsace|alstom|am|americanexpress|americanfamily|amex|amfam|
amica|amsterdam|analytics|android|anquan|anz|ao|aol|apartments|app|apple|
aq|aquarelle|ar|aramco|archi|army|arpa|art|arte|as|asda|asia|associates|
at|athleta|attorney|au|auction|audi|audible|audio|auspost|author|auto|autos|
avianca|aw|aws|ax|axa|az|azure|ba|baby|baidu|banamex|bananarepublic|band|
bank|bar|barcelona|barclaycard|barclays|barefoot|bargains|baseball|basketball|
bauhaus|bayern|bb|bbc|bbt|bbva|bcg|bcn|bd|be|beats|beauty|beer|bentley|
berlin|best|bestbuy|bet|bf|bg|bh|bharti|bi|bible|bid|bike|bing|bingo|bio|
biz|bj|black|blackfriday|blanco|blockbuster|blog|bloomberg|blue|bm|bms|
bmw|bn|bnl|bnpparibas|bo|boats|boehringer|bofa|bom|bond|boo|book|booking|
boots|bosch|bostik|boston|bot|boutique|box|br|bradesco|bridgestone|broadway|
broker|brother|brussels|bs|bt|budapest|bugatti|build|builders|business|
buy|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|call|calvinklein|cam|camera|camp|
cancerresearch|canon|capetown|capital|capitalone|car|caravan|cards|care|
career|careers|cars|cartier|casa|case|caseih|cash|casino|cat|catering|catholic|
cba|cbn|cbre|cbs|cc|cd|ceb|center|ceo|cern|cf|cfa|cfd|cg|ch|chanel|channel|
chase|chat|cheap|chintai|chloe|christmas|chrome|chrysler|church|ci|cipriani|
circle|cisco|citadel|citi|citic|city|cityeats|ck|cl|claims|cleaning|click|
clinic|clinique|clothing|cloud|club|clubmed|cm|cn|co|coach|codes|coffee|
college|cologne|com|comcast|commbank|community|company|compare|computer|
comsec|condos|construction|consulting|contact|contractors|cooking|cookingchannel|
cool|coop|corsica|country|coupon|coupons|courses|cr|credit|creditcard|creditunion|
cricket|crown|crs|cruise|cruises|csc|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|
cz|dabur|dad|dance|data|date|dating|datsun|day|dclk|dds|de|deal|dealer|
deals|degree|delivery|dell|deloitte|delta|democrat|dental|dentist|desi|
design|dev|dhl|diamonds|diet|digital|direct|directory|discount|discover|
dish|diy|dj|dk|dm|dnp|do|docs|doctor|dodge|dog|doha|domains|dot|download|
drive|dtv|dubai|duck|dunlop|duns|dupont|durban|dvag|dvr|dz|earth|eat|ec|
eco|edeka|edu|education|ee|eg|email|emerck|energy|engineer|engineering|
enterprises|epost|epson|equipment|er|ericsson|erni|es|esq|estate|esurance|
et|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|extraspace|
fage|fail|fairwinds|faith|family|fan|fans|farm|farmers|fashion|fast|fedex|
feedback|ferrari|ferrero|fi|fiat|fidelity|fido|film|final|finance|financial|
fire|firestone|firmdale|fish|fishing|fit|fitness|fj|fk|flickr|flights|flir|
florist|flowers|fly|fm|fo|foo|food|foodnetwork|football|ford|forex|forsale|
forum|foundation|fox|fr|free|fresenius|frl|frogans|frontdoor|frontier|ftr|
fujitsu|fujixerox|fun|fund|furniture|futbol|fyi|ga|gal|gallery|gallo|gallup|
game|games|gap|garden|gb|gbiz|gd|gdn|ge|gea|gent|genting|george|gf|gg|ggee|
gh|gi|gift|gifts|gives|giving|gl|glade|glass|gle|global|globo|gm|gmail|
gmbh|gmo|gmx|gn|godaddy|gold|goldpoint|golf|goo|goodhands|goodyear|goog|
google|gop|got|gov|gp|gq|gr|grainger|graphics|gratis|green|gripe|group|
gs|gt|gu|guardian|gucci|guge|guide|guitars|guru|gw|gy|hair|hamburg|hangout|
haus|hbo|hdfc|hdfcbank|health|healthcare|help|helsinki|here|hermes|hgtv|
hiphop|hisamitsu|hitachi|hiv|hk|hkt|hm|hn|hockey|holdings|holiday|homedepot|
homegoods|homes|homesense|honda|honeywell|horse|hospital|host|hosting|hot|
hoteles|hotmail|house|how|hr|hsbc|ht|htc|hu|hughes|hyatt|hyundai|ibm|icbc|
ice|icu|id|ie|ieee|ifm|ikano|il|im|imamat|imdb|immo|immobilien|in|industries|
infiniti|info|ing|ink|institute|insurance|insure|int|intel|international|
intuit|investments|io|ipiranga|iq|ir|irish|is|iselect|ismaili|ist|istanbul|
it|itau|itv|iveco|iwc|jaguar|java|jcb|jcp|je|jeep|jetzt|jewelry|jio|jlc|
jll|jm|jmp|jnj|jo|jobs|joburg|jot|joy|jp|jpmorgan|jprs|juegos|juniper|kaufen|
kddi|ke|kerryhotels|kerrylogistics|kerryproperties|kfh|kg|kh|ki|kia|kim|
kinder|kindle|kitchen|kiwi|km|kn|koeln|komatsu|kosher|kp|kpmg|kpn|kr|krd|
kred|kuokgroup|kw|ky|kyoto|kz|la|lacaixa|ladbrokes|lamborghini|lamer|lancaster|
lancia|lancome|land|landrover|lanxess|lasalle|lat|latino|latrobe|law|lawyer|
lb|lc|lds|lease|leclerc|lefrak|legal|lego|lexus|lgbt|li|liaison|lidl|life|
lifeinsurance|lifestyle|lighting|like|lilly|limited|limo|lincoln|linde|
link|lipsy|live|living|lixil|lk|loan|loans|locker|locus|loft|lol|london|
lotte|lotto|love|lpl|lplfinancial|lr|ls|lt|ltd|ltda|lu|lundbeck|lupin|luxe|
luxury|lv|ly|ma|macys|madrid|maif|maison|makeup|man|management|mango|market|
marketing|markets|marriott|marshalls|maserati|mattel|mba|mc|mcd|mcdonalds|
mckinsey|md|me|med|media|meet|melbourne|meme|memorial|men|menu|meo|metlife|
mg|mh|miami|microsoft|mil|mini|mint|mit|mitsubishi|mk|ml|mlb|mls|mm|mma|
mn|mo|mobi|mobile|mobily|moda|moe|moi|mom|monash|money|monster|montblanc|
mopar|mormon|mortgage|moscow|moto|motorcycles|mov|movie|movistar|mp|mq|
mr|ms|msd|mt|mtn|mtpc|mtr|mu|museum|mutual|mv|mw|mx|my|mz|na|nab|nadex|
nagoya|name|nationwide|natura|navy|nba|nc|ne|nec|net|netbank|netflix|network|
neustar|new|newholland|news|next|nextdirect|nexus|nf|nfl|ng|ngo|nhk|ni|
nico|nike|nikon|ninja|nissan|nissay|nl|no|nokia|northwesternmutual|norton|
now|nowruz|nowtv|np|nr|nra|nrw|ntt|nu|nyc|nz|obi|observer|off|office|okinawa|
olayan|olayangroup|oldnavy|ollo|om|omega|one|ong|onl|online|onyourside|
ooo|open|oracle|orange|org|organic|orientexpress|origins|osaka|otsuka|ott|
ovh|pa|page|pamperedchef|panasonic|panerai|paris|pars|partners|parts|party|
passagens|pay|pccw|pe|pet|pf|pfizer|pg|ph|pharmacy|philips|phone|photo|
photography|photos|physio|piaget|pics|pictet|pictures|pid|pin|ping|pink|
pioneer|pizza|pk|pl|place|play|playstation|plumbing|plus|pm|pn|pnc|pohl|
poker|politie|porn|post|pr|pramerica|praxi|press|prime|pro|prod|productions|
prof|progressive|promo|properties|property|protection|pru|prudential|ps|
pt|pub|pw|pwc|py|qa|qpon|quebec|quest|qvc|racing|radio|raid|re|read|realestate|
realtor|realty|recipes|red|redstone|redumbrella|rehab|reise|reisen|reit|
reliance|ren|rent|rentals|repair|report|republican|rest|restaurant|review|
reviews|rexroth|rich|richardli|ricoh|rightathome|ril|rio|rip|rmit|ro|rocher|
rocks|rodeo|rogers|room|rs|rsvp|ru|ruhr|run|rw|rwe|ryukyu|sa|saarland|safe|
safety|sakura|sale|salon|samsclub|samsung|sandvik|sandvikcoromant|sanofi|
sap|sapo|sarl|sas|save|saxo|sb|sbi|sbs|sc|sca|scb|schaeffler|schmidt|scholarships|
school|schule|schwarz|science|scjohnson|scor|scot|sd|se|seat|secure|security|
seek|select|sener|services|ses|seven|sew|sex|sexy|sfr|sg|sh|shangrila|sharp|
shaw|shell|shia|shiksha|shoes|shop|shopping|shouji|show|showtime|shriram|
si|silk|sina|singles|site|sj|sk|ski|skin|sky|skype|sl|sling|sm|smart|smile|
sn|sncf|so|soccer|social|softbank|software|sohu|solar|solutions|song|sony|
soy|space|spiegel|spot|spreadbetting|sr|srl|srt|st|stada|staples|star|starhub|
statebank|statefarm|statoil|stc|stcgroup|stockholm|storage|store|stream|
studio|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|
sv|swatch|swiftcover|swiss|sx|sy|sydney|symantec|systems|sz|tab|taipei|
talk|taobao|target|tatamotors|tatar|tattoo|tax|taxi|tc|tci|td|tdk|team|
tech|technology|tel|telecity|telefonica|temasek|tennis|teva|tf|tg|th|thd|
theater|theatre|tiaa|tickets|tienda|tiffany|tips|tires|tirol|tj|tjmaxx|
tjx|tk|tkmaxx|tl|tm|tmall|tn|to|today|tokyo|tools|top|toray|toshiba|total|
tours|town|toyota|toys|tr|trade|trading|training|travel|travelchannel|travelers|
travelersinsurance|trust|trv|tt|tube|tui|tunes|tushu|tv|tvs|tw|tz|ua|ubank|
ubs|uconnect|ug|uk|unicom|university|uno|uol|ups|us|uy|uz|va|vacations|
vana|vanguard|vc|ve|vegas|ventures|verisign|versicherung|vet|vg|vi|viajes|
video|vig|viking|villas|vin|vip|virgin|visa|vision|vista|vistaprint|viva|
vivo|vlaanderen|vn|vodka|volkswagen|volvo|vote|voting|voto|voyage|vu|vuelos|
wales|walmart|walter|wang|wanggou|warman|watch|watches|weather|weatherchannel|
webcam|weber|website|wed|wedding|weibo|weir|wf|whoswho|wien|wiki|williamhill|
win|windows|wine|winners|wme|wolterskluwer|woodside|work|works|world|wow|
ws|wtc|wtf|xbox|xerox|xfinity|xihuan|xin|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|
xn--30rr7y|xn--3bst00m|xn--3ds443g|xn--3e0b707e|xn--3oq18vl8pn36a|xn--3pxu8k|
xn--42c2d9a|xn--45brj9c|xn--45q11c|xn--4gbrim|xn--54b7fta0cc|xn--55qw42g|
xn--55qx5d|xn--5su34j936bgsg|xn--5tzm5g|xn--6frz82g|xn--6qq986b3xl|xn--80adxhks|
xn--80ao21a|xn--80aqecdr1a|xn--80asehdb|xn--80aswg|xn--8y0a063a|xn--90a3ac|
xn--90ae|xn--90ais|xn--9dbq2a|xn--9et52u|xn--9krt00a|xn--b4w605ferd|xn--bck1b9a5dre4c|
xn--c1avg|xn--c2br7g|xn--cck2b3b|xn--cg4bki|xn--clchc0ea0b2g2a9gcd|xn--czr694b|
xn--czrs0t|xn--czru2d|xn--d1acj3b|xn--d1alf|xn--e1a4c|xn--eckvdtc9d|xn--efvy88h|
xn--estv75g|xn--fct429k|xn--fhbei|xn--fiq228c5hs|xn--fiq64b|xn--fiqs8s|
xn--fiqz9s|xn--fjq720a|xn--flw351e|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--fzys8d69uvgm|
xn--g2xx48c|xn--gckr3f0f|xn--gecrj9c|xn--gk3at1e|xn--h2brj9c|xn--hxt814e|
xn--i1b6b1a6a2e|xn--imr513n|xn--io0a7i|xn--j1aef|xn--j1amh|xn--j6w193g|
xn--jlq61u9w7b|xn--jvr189m|xn--kcrx77d1x4a|xn--kprw13d|xn--kpry57d|xn--kpu716f|
xn--kput3i|xn--l1acc|xn--lgbbat1ad8j|xn--mgb9awbf|xn--mgba3a3ejt|xn--mgba3a4f16a|
xn--mgba7c0bbn0a|xn--mgbaam7a8h|xn--mgbab2bd|xn--mgbayh7gpa|xn--mgbb9fbpob|
xn--mgbbh1a71e|xn--mgbc0a9azcg|xn--mgbca7dzdo|xn--mgberp4a5d4ar|xn--mgbi4ecexp|
xn--mgbpl2fh|xn--mgbt3dhd|xn--mgbtx2b|xn--mgbx4cd0ab|xn--mix891f|xn--mk1bu44c|
xn--mxtq1m|xn--ngbc5azd|xn--ngbe9e0a|xn--node|xn--nqv7f|xn--nqv7fs00ema|
xn--nyqy26a|xn--o3cw4h|xn--ogbpf8fl|xn--p1acf|xn--p1ai|xn--pbt977c|xn--pgbs0dh|
xn--pssy2u|xn--q9jyb4c|xn--qcka1pmc|xn--qxam|xn--rhqv96g|xn--rovu88b|xn--s9brj9c|
xn--ses554g|xn--t60b56a|xn--tckwe|xn--tiq49xqyj|xn--unup4y|xn--vermgensberater-ctb|
xn--vermgensberatung-pwb|xn--vhquv|xn--vuq861b|xn--w4r85el8fhu5dnra|xn--w4rs40l|
xn--wgbh1c|xn--wgbl6a|xn--xhq521b|xn--xkc2al3hye2a|xn--xkc2dl3a5ee0h|xn--y9a3aq|
xn--yfro4i67o|xn--ygbi2ammx|xn--zfr164b|xperia|xxx|xyz|yachts|yahoo|yamaxun|
yandex|ye|yodobashi|yoga|yokohama|you|youtube|yt|yun|za|zappos|zara|zero|
zip|zippo|zm|zone|zuerich|zw"""
### code
__author__="Damian Pasternok <my_forename at pasternok.org>"
__program__="Wake On Lan - Magic Packet"
__version__="0.1"
__date__ ="$2009-07-01 16:57:06$"
import pygtk
pygtk.require('2.0')
import gtk
import re
import struct
import socket
import sys
import os
import urllib
tld_local = tld_local.replace("\n", "")
class TLDParser:
def __init__(self, tld):
self.url = urllib.urlopen(tld)
self.html = self.url.readlines()
# no version header (probably 404 or something)
if not re.match("^#.*$", self.html[0]):
self.err = 1
else:
self.err = 0
def get_header(self):
self.header = self.html[0]
return self.header
def parse_tlds(self):
self.tlds = ""
self.tlds = self.html
self.tlds.pop(0) # remove header
i = 0
for domain in self.tlds:
self.tlds[i] = domain.lower()
self.tlds[i] = self.tlds[i].replace("\n", "|")
i += 1
# remove "|" from last item
self.tlds[len(self.tlds)-1] = self.tlds[len(self.tlds)-1].replace("|",
"")
return self.tlds
# args: type
# regexp - used by 'use_remote_tld_list = "yes"'
# variable - used by '--update-tlds' (create new tld_local variable)
def get_tld(self, type):
self.tld_local = ""
self.tld_local_list = [] # or list()
if type == "regexp":
for domain in self.parse_tlds():
self.tld_local += domain
self.tlds = self.tlds[:-1] # remove last "|"
return self.tld_local
elif type == "variable":
self.tld_local_list.append(self.get_header())
self.tld_local_list[0] = self.tld_local_list[0].replace("# ",
"# tld_local (")
self.tld_local_list[0] = self.tld_local_list[0].replace("\n", ")\n")
self.tld_local_list.append("tld_local = r\"\"\"")
# create fancy variable string fitted to vt100 based terminals
i = 1
for domain in self.parse_tlds():
if len(self.tld_local_list[i]) > 70:
self.tld_local_list[i] += "\n"
self.tld_local_list.append("")
i += 1
self.tld_local_list[i] += domain
continue
else:
self.tld_local_list[i] += domain
self.tld_local_list[i] += "\"\"\""
for lines in self.tld_local_list:
self.tld_local += lines
return self.tld_local
class Group:
def __init__(self, l, size):
self.size = size
self.l = l
def __getitem__(self, group):
idx = group * self.size
if idx > len(self.l):
raise IndexError("Out of range")
return self.l[idx:idx+self.size]
class MagicPacket:
# calculate broadcast
def get_broadcast(self, inetaddr, submask):
try:
self.inetaddr = socket.gethostbyname(inetaddr)
except:
self.err = 1
return -1
self.inetaddr = self.inetaddr.split('.')
self.submask = submask.split('.')
self.broadcast = ""
self.broadcast_list = []
i = 0
for sbyte in self.submask:
self.submask[i] = int(sbyte) ^ 0xff # xor the binary subnet mask
self.broadcast_list.append(int(self.inetaddr[i]) | self.submask[i])
self.broadcast += str(self.broadcast_list[i])
self.broadcast += "."
i += 1
self.broadcast = self.broadcast[:-1]
return self.broadcast
def mac_into_list(self, macaddr):
# check MAC format
self.macaddr = macaddr.split(':')
if len(self.macaddr) != 6:
self.macaddr = macaddr.split('-')
if len(self.macaddr) != 6:
self.macaddr = []
# group MAC bytes into list
for pair in Group(macaddr, 2):
self.macaddr.append(pair)
self.macaddr.pop() # remove last empty item from list
i = 0
for pair in self.macaddr: # all letters in uppercase
self.macaddr[i] = pair.upper()
i += 1
return self.macaddr
def send_magic_packet(self, macaddr, inetaddr, submask, remport):
self.macaddr = self.mac_into_list(macaddr)
# prepare magic packet
self.hw_addr = struct.pack('BBBBBB', int(self.macaddr[0], 16),
int(self.macaddr[1], 16),
int(self.macaddr[2], 16),
int(self.macaddr[3], 16),
int(self.macaddr[4], 16),
int(self.macaddr[5], 16))
self.msg = '\xff' * 6 + self.hw_addr * 16
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.err = 0 # set to 1 if failed to resolve hostname
if inetaddr:
self.broadcast = self.get_broadcast(inetaddr, submask)
if not self.err:
self.s.sendto(self.msg, (self.broadcast, int(remport)))
else:
self.broadcast = "255.255.255.255"
self.s.sendto(self.msg, (self.broadcast, int(remport)))
self.s.close()
return self.broadcast # returns broadcast address
class Errors:
errors = ""
def show_errors(self):
dialog = gtk.MessageDialog(self.parent_window,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
"Unable to send Magic Packet due to following errors: %s"
% self.errors)
dialog.set_title(__program__)
dialog.run()
dialog.destroy()
def combine_errors(self, error_message):
self.errors += error_message
def check_mac(self, macaddr):
self.res = re.match(r"^[\dA-Fa-f]{2}(-[\dA-Fa-f]{2}){5}$|"
"^[\dA-Fa-f]{2}(:[\dA-Fa-f]{2}){5}$|"
"^[\dA-Fa-f]{2}([\dA-Fa-f]{2}){5}$", macaddr)
if self.res:
return 0
else:
self.combine_errors("\n- wrong MAC - correct MAC formats are "
"(case-insensitive):\n 00-74-F1-37-4B-59, "
"00:74:F1:37:4B:59 or 0074F1374B59")
def check_inetaddr(self, inetaddr):
if use_remote_tld_list == "yes":
try:
parser = TLDParser(tld_remote)
tld = parser.get_tld("regexp")
if parser.err: # wrong tld url
tld = tld_local
IndexErrors()
except:
dialog = gtk.MessageDialog(self.parent_window,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_WARNING, gtk.BUTTONS_OK,
"Unable to get the list of Top-level Domains.\n"
"Using Top-level Domains from tld_local.")
dialog.set_title(__program__)
dialog.run()
dialog.destroy()
tld = tld_local
elif use_remote_tld_list == "no":
tld = tld_local
self.prog = re.compile(r"^((\d{1,2}|1\d{2}|2[0-4]\d{1}|25[0-5])" # ip
"(\.(\d{1,2}|1\d{2}|2[0-4]\d{1}|25[0-5])){3})|"
"([A-Za-z\d]+((\-|_){0,1}[A-Za-z\d])*" # fqdn
"(\.[A-Za-z\d]+((\-|_){0,1}[A-Za-z\d])*)*"
"\.(%s))$" % tld)
self.res = self.prog.match(inetaddr)
if self.res:
return 0
else:
self.combine_errors("\n- wrong internet address - correct formats "
"are:\n IP address (e.g. 192.168.0.1) or "
"fully qualified domain\n name (e.g. "
"bgp-0-2.br0.nyc1.isp.net)")
def check_submask(self, submask):
self.res = re.match(r"^(\d{1,2}|1\d{2}|2[0-4]\d{1}|25[0-5])"
"(\.(\d{1,2}|1\d{2}|2[0-4]\d{1}|25[0-5])){3}$", submask)
if self.res:
return 0
else:
self.combine_errors("\n- wrong subnet mask - correct format is e.g."
" 255.255.255.0")
def check_remport(self, remport):
self.res = re.match(r"^(\d{1,4}|[1-5]\d{4}|6([0-4]\d{3}|"
"5[0-4]\d{2}|55[0-2]\d{1}|553[0-5]))$", remport)
if self.res:
return 0
else:
self.combine_errors("\n- wrong remote port - use one from range "
"0-65535\n (typically 0, 7 or 9)")
def __init__(self, window):
self.parent_window = window
class CommandLine:
def version(self):
version_message = r"""%s %s
Copyright (C) 2009 %s
%s comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of %s
under the terms of the GNU General Public License version 3 or later.
For more information see <http://gnu.org/licenses/gpl.html>.""" % (
__program__, __version__, __author__, __program__, __program__)
return version_message
def help(self):
help_message = r"""Usage: %s [OPTION]...
Available options:
--update-tlds try to download list of Top-level Domains from
URL defined in tld_remote variable and update
tld_local variable in script
--help display this help and exit
--version output version information and exit
""" % sys.argv[0]
return help_message
class MainWindow:
def destroy(self, widget, data=None):
gtk.main_quit()
def wake_me(self, button, data=None):
self.check = Errors(self.window)
self.check.check_mac(self.edit_macaddr.get_text())
if self.select_target.get_active_text() == "Internet":
self.check.check_inetaddr(self.edit_inetaddr.get_text())
self.check.check_submask(self.edit_submask.get_text())
self.check.check_remport(self.edit_remport.get_text())
if len(self.check.errors):
self.check.show_errors()
else:
self.send = MagicPacket()
broadcast = self.send.send_magic_packet(
self.edit_macaddr.get_text(),
self.edit_inetaddr.get_text(),
self.edit_submask.get_text(),
self.edit_remport.get_text())
if self.send.err:
self.statusbar.push(0,
"Unable to send Magic Packet. Can't resolve hostname...")
return -1
fancy_mac = ""
for mbyte in self.send.mac_into_list(self.edit_macaddr.get_text()):
fancy_mac += mbyte
fancy_mac += ":"
fancy_mac = fancy_mac[:-1] # remove last ":"
self.statusbar.push(0,
"Magic Packet sent to %s (%s)..." % (broadcast, fancy_mac))
def show_about(self, widget, string):
dialog = gtk.MessageDialog(self.window,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_INFO, gtk.BUTTONS_OK, string)
dialog.set_title(__program__)
dialog.run()
dialog.destroy()
def select_send_option(self, button, data=None):
if self.select_target.get_active_text() == "Internet":
self.edit_inetaddr.set_sensitive(True)
self.edit_submask.set_sensitive(True)
elif self.select_target.get_active_text() == "Local Subnet":
self.edit_inetaddr.set_text("")
self.edit_submask.set_text("")
self.edit_inetaddr.set_sensitive(False)
self.edit_submask.set_sensitive(False)
def __init__(self):
# main window
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("destroy", self.destroy)
self.window.set_title(__program__)
self.window.set_position(gtk.WIN_POS_CENTER)
# root vbox
self.root_vbox = gtk.VBox(False, 0)
# menu
self.menu = gtk.Menu()
self.about_item = gtk.MenuItem("_About...")
self.menu.append(self.about_item)
self.cmd = CommandLine()
self.about_item.connect("activate", self.show_about, self.cmd.version())
self.root_menu = gtk.MenuItem("_Help")
self.root_menu.set_right_justified(True)
self.root_menu.set_submenu(self.menu)
self.menu_bar = gtk.MenuBar()
self.menu_bar.append(self.root_menu)
self.root_vbox.pack_start(self.menu_bar, False, False, 0)
# frame
self.frame = gtk.Frame(" %s" % __program__)
self.window.add(self.root_vbox)
self.root_vbox.pack_start(self.frame, False, False, 0)
# statusbar
self.statusbar = gtk.Statusbar()
self.root_vbox.pack_end(self.statusbar, False, False, 0)
# labels
self.label1 = gtk.Label("Mac Address")
self.label1.set_alignment(1, 0.5)
self.label2 = gtk.Label("Internet Address")
self.label2.set_alignment(1, 0.5)
self.label3 = gtk.Label("Subnet Mask")
self.label3.set_alignment(1, 0.5)
self.label4 = gtk.Label("Send options")
self.label4.set_alignment(1, 0.5)
self.label5 = gtk.Label("Remote Port Number")
self.label5.set_alignment(1, 0.5)
# edit boxes & selection
self.edit_macaddr = gtk.Entry()
self.edit_inetaddr = gtk.Entry()
self.edit_submask = gtk.Entry()
self.select_target = gtk.combo_box_new_text()
self.select_target.append_text("Local Subnet")
self.select_target.append_text("Internet")
self.select_target.set_active(0)
self.edit_remport = gtk.Entry()
# combobox action
self.select_target.connect("changed", self.select_send_option)
# hide by default "internet address" and "subnet mask"
# (they are not required when send local magic packet)
self.edit_inetaddr.set_sensitive(False)
self.edit_submask.set_sensitive(False)
# default values
self.edit_macaddr.set_text("00-74-F1-37-4B-59")
self.edit_remport.set_text("9")
# table
self.table = gtk.Table(5, 2)
self.table.set_row_spacings(4)
self.table.set_col_spacings(10)
self.table.attach(self.label1, 0, 1, 0, 1)
self.table.attach(self.label2, 0, 1, 1, 2)
self.table.attach(self.label3, 0, 1, 2, 3)
self.table.attach(self.label4, 0, 1, 3, 4)
self.table.attach(self.label5, 0, 1, 4, 5)
self.table.attach(self.edit_macaddr, 1, 2, 0, 1)
self.table.attach(self.edit_inetaddr, 1, 2, 1, 2)
self.table.attach(self.edit_submask, 1, 2, 2, 3)
self.table.attach(self.select_target, 1, 2, 3, 4)
self.table.attach(self.edit_remport, 1, 2, 4, 5)
# vertical box
self.vbox = gtk.VBox(False, 8)
self.vbox.set_border_width(16)
self.frame.add(self.vbox)
# add table to vbox
self.vbox.pack_start(self.table, False, False, 0)
# add separator to vbox
self.vbox.pack_start(gtk.HSeparator(), False, False, 0)
# wake button
self.button = gtk.Button("Wake Me Up")
self.button.connect("clicked", self.wake_me)
self.vbox.pack_end(self.button, False, False, 0)
self.window.show_all()
def main():
cmd = CommandLine()
if len(sys.argv) == 1:
MainWindow()
gtk.main()
elif len(sys.argv) == 2:
if sys.argv[1] == "--update-tlds":
try:
parser = TLDParser(tld_remote)
if parser.err: # wrong tld url
IndexErrors()
new_tld_local = parser.get_tld("variable")
except:
print "Unable to get the list of Top-level Domains.\nExiting."
return -1
f = open(sys.argv[0], "r")
script = f.read()
f.close()
script = re.sub("# tld_local(.|\n)*[\w]{2}\"\"\"",
new_tld_local, script, re.M)
os.remove(sys.argv[0])
f = open(sys.argv[0], "w")
os.chmod(sys.argv[0], 0755)
f.write(script)
f.close()
print "Top-level Domains updated successfully."
while 1:
print "Do you want to run the main program? [n]",
key = raw_input()
if key == "y" or key == "Y":
MainWindow()
gtk.main()
break
elif key == "n" or key == "N" or key == "":
break
elif sys.argv[1] == "--version":
print cmd.version()
else:
print cmd.help()
else:
print cmd.help()
return 0
if __name__ == "__main__":
main()