yichao firstname, zeaster nickname, zhang lastname

wake-on-lan by python script

How to wake up your computer on the LAN?
the answer is just to send a Magic Packet to your computer on port 7 or 9.
However when your computer is down, it has no ip, so send it to the broadcast ip
the following python script implements the above idea.


import struct, socket

def wake_on_lan(ether_addr, inet_addr):
addr_byte=ether_addr.split(':')
hw_addr=struct.pack('BBBBBB',
int(addr_byte[0],16),
int(addr_byte[1],16),
int(addr_byte[2],16),
int(addr_byte[3],16),
int(addr_byte[4],16),
int(addr_byte[5],16))
msg='\xff'*6+hw_addr*16

s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.sendto(msg, (inet_addr,7))
s.close()

wake_on_lan('00:E0:4C:E1:D9:CC', '192.168.1.255')


The code above is based on socket.SOCK_DGRAM to send UDP packet.
How to create a UDP packet based on raw socket in python?
the project dpkt does an excellent job.
the following example shows that:

import socket
from dpkt import ethernet,udp,ip
import dpkt
import struct
import string

iface = "eth1"
mac = "00:0E:35:AB:9B:40"
inet = "192.168.1.6"
debug = 0

def eth_aton(buffer):
addr =''
temp = string.split(buffer,':')
buffer = string.join(temp,'')
for i in range(0, len(buffer), 2):
addr = ''.join([addr,struct.pack('B', int(buffer[i: i + 2], 16))],)
return addr

def buildUdp():
ether_addr='00:E0:4C:E1:D9:CD'
addr_byte=ether_addr.split(':')
hw_addr=struct.pack('BBBBBB',
int(addr_byte[0],16),
int(addr_byte[1],16),
int(addr_byte[2],16),
int(addr_byte[3],16),
int(addr_byte[4],16),
int(addr_byte[5],16))
msg='xff'*6+hw_addr*16

udp_p = udp.UDP()
udp_p.sport = 0x8130
udp_p.dport = 7
udp_p.data = msg
udp_p.ulen += len(udp_p.data)

ip_p = ip.IP()
ip_p.src = socket.inet_aton('192.168.1.6');
ip_p.dst = socket.inet_aton('192.168.1.255');
ip_p.off = 0x4000
ip_p.data = udp_p
ip_p.p = ip.IP_PROTO_UDP
ip_p.len += len(udp_p)

packet = ethernet.Ethernet()
packet.src = eth_aton(mac)
packet.dst = eth_aton('ff:ff:ff:ff:ff:ff')
packet.data = ip_p
packet.type = ethernet.ETH_TYPE_IP

if debug: print dpkt.hexdump(str(packet))
return packet

s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW)
s.bind((iface,ethernet.ETH_TYPE_IP))
packet = buildUdp()
s.send(str(packet))

No comments: