2 # Marc E. Fiuczynski <mef@cs.princeton.edu>
3 # Copyright (C) 2004 The Trustees of Princeton University
5 # Client ping of death program for both udp & icmp
7 # modified for inclusion by api by Aaron K
17 def _in_cksum(packet):
18 """THE RFC792 states: 'The 16 bit one's complement of
19 the one's complement sum of all 16 bit words in the header.'
20 Generates a checksum of a (ICMP) packet. Based on in_chksum found
24 # add byte if not dividable by 2
26 packet = packet + '\0'
28 # split into 16-bit word and insert into a binary array
29 words = array.array('h', packet)
32 # perform ones complement arithmetic on 16-bit words
34 sum += (word & 0xffff)
39 sum = sum + (sum >> 16)
41 return (~sum) & 0xffff # return ones complement
43 def _construct(id, data):
44 """Constructs a ICMP IPOD packet
46 ICMP_TYPE = 6 # ping of death code used by PLK
52 header = struct.pack('bbHHh', ICMP_TYPE, ICMP_CODE, ICMP_CHECKSUM, \
53 ICMP_ID, ICMP_SEQ_NR+id)
55 packet = header + data # ping packet without checksum
56 checksum = _in_cksum(packet) # make checksum
58 # construct header with correct checksum
59 header = struct.pack('bbHHh', ICMP_TYPE, ICMP_CODE, checksum, ICMP_ID, \
62 # ping packet *with* checksum
63 packet = header + data
65 # a perfectly formatted ICMP echo packet
68 def icmp_pod(host,key):
71 print "must be root to send icmp pod"
74 s = socket(AF_INET, SOCK_RAW, getprotobyname("icmp"))
75 packet = _construct(0, key) # make a ping packet
77 print 'pod sending icmp-based reboot request to %s' % host
79 s.sendto(packet, addr)
81 def udp_pod(host,key,fromaddr=('', 0)):
82 addr = host, UPOD_PORT
83 s = socket(AF_INET, SOCK_DGRAM)
86 print 'pod sending udp-based reboot request to %s' % host
88 s.sendto(packet, addr)
90 def noop_pod(host,key):