2011-06-12 52 views
3

前一段時間,我寫了一封小小的WOL腳本[來自Google的幫助]打開我網絡中的計算機。這裏是腳本:來自外部WAN的WOL

exec /usr/bin/python -x "$0" "[email protected]" 
# 
node_lst = [ 
     'srv1 0a:1b:8c:0d:2e:7f', 
     'srv2 0A-0B-4C-8D-CE:3F', 
] 
# 
import os,sys,string,commands 
import struct, socket 
import re,random 

retval = 0 

mac_addr = "mac_addr.txt" 
X = '([a-zA-Z0-9]{2}[:|\-|.]?){5}[a-zA-Z0-9]{2}' 
S = re.compile(r'\s+') 

mmap = {} 

## First argument 'None' in str.translate is new in 2.6. 
## Previously, it was a string of 256 characters 
if sys.version_info < (2, 6): 
    f1_arg = ''.join(chr(i) for i in xrange(256)) 
else: 
    f1_arg = None 

## broadcast address 
sysOS = "uname -s" 
BSD = "ifconfig | grep -w broadcast | cut -d\ -f 6" 
LNX = "ip -o addr show | grep -w inet | grep -e eth | cut -d\ -f 9" 
# 
if commands.getoutput(sysOS) == "Linux": 
    bCast = commands.getoutput(LNX) 
elif commands.getoutput(sysOS) == "Darwin": 
    bCast = commands.getoutput(BSD) 
else: 
    print "System not supported!!" 
    sys_exit() 

def WakeOnLan(mac_address): 

    ## Building the Wake-On-LAN "Magic Packet"... 
    ## Pad the synchronization stream. 
    data = ''.join(['FFFFFFFFFFFF', mac_address * 20]) 
    msg = '' 

    ## Split up the hex values and pack. 
    for i in range(0, len(data), 2): 
     msg = ''.join([msg, struct.pack('B', int(data[i: i + 2], 16))]) 

    ## ...and send it to the broadcast address using UDP 
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 
    s.sendto(msg, (bCast, 9)) 
    s.close() 

def sys_exit(): 
    sys.stdout.flush() 
    sys.exit(1) 

## check if hostname is provided 
if len(sys.argv) != 2: 
    print "Usage: %s <hostname>" % sys.argv[0] 
    sys_exit() 

for i in node_lst: 
    # strip off everything from first "#" [if] found 
    i = i.split('#',1)[0] 
    if not re.search(X, i): 
     continue 

    h = S.split(i,1)[0]     ## host name 
    m = S.split(i,1)[-1]    ## MAC address 
    mmap[h] = m.strip('\t|" "') 

for j, k in mmap.iteritems(): 
    if sys.argv[1] == j: 
     if not re.search(X.replace('zA-Z','fA-F'), k): 
      print "Invalid MAC address [",k,"]; nothing to do!!" 
      sys_exit() 
     else: 
      WakeOnLan(k.translate(f1_arg,':.-')) 
      print "WOL request has been sent to %s [%s]" % (j,k) 
      break 
else: 
    print "Host [%s] doesn't exist!!" % sys.argv[1] 
    sys_exit() 

這在我的家庭網絡(或局域網)內工作得很好。如何更改腳本以使其在局域網之外工作?任何想法或建議?乾杯!!

回答

1

這是不可能的,因爲WOL數據包是廣播數據包(因爲你不知道是誰發送它)。家庭路由器,尤其是ISP /網絡路由器會丟棄所有的廣播數據包,因爲每次運行這個腳本時,整個互聯網上的所有計算機都會收到你的數據包,這會造成一些混亂。

你當然可以做的是編寫一個小型應用程序,該應用程序位於廣域網內運行的計算機上,您希望打開所有計算機,然後讓該應用程序發送WOL數據包。但是,這需要一臺可以隨時上網的電腦。

+0

我在互聯網上發現了幾篇文章,說可能使用路由器的IP地址,並使用NAT /端口轉發到一個不存在的局域網IP地址。乾杯!! – MacUsers 2011-06-12 20:08:43

+0

如果你確實知道如何,請讓每個人都知道:)。 – 2011-06-12 20:09:22

+0

這裏有一個,剛剛發現(我應該在發佈之前進行搜索和嘗試):'http:// www.schuetzler.net/blog/4/first-python-program-wake-on-wan'還沒有測試過。 – MacUsers 2011-06-12 20:50:45

1

配置您的路由器將10個非順序端口選擇的數據包轉發到LAN上的一臺計算機。

根據格林尼治標準時間+時間+哈希來設計一些方案來生成端口觸發序列。

在您的網絡內的命令框中有一個python程序(使用scappy)監聽一系列syn數據包。

監聽器代碼將類似於tcpdump的以下語法:

sudo tcpdump -ni eth0 'tcp[tcpflags] & (tcp-syn) !=0' 

凡剛捕獲的SYN數據包。

你的程序就在那裏,等待正確的順序。當它收到序列時,它會運行你的WOL腳本。

完成。

如果您不想打開端口,您的腳本可以改爲輪詢遠程網站,等待更改。或者收聽通過電子郵件獲取的電子郵件。

將你的想法進一步發揮,你可以做一些花哨的東西,比如開燈或啓動電視。

+0

聽起來很有希望。我會試試這個報告。乾杯!! – MacUsers 2013-04-15 11:09:09