3 # Marc E. Fiuczynski <mef@cs.princeton.edu>
4 # Copyright (C) 2004 The Trustees of Princeton University
6 # Client ping of death program for both udp & icmp
8 # modified for inclusion by api by Aaron K
18 def _in_cksum(packet):
19 """THE RFC792 states: 'The 16 bit one's complement of
20 the one's complement sum of all 16 bit words in the header.'
21 Generates a checksum of a (ICMP) packet. Based on in_chksum found
25 # add byte if not dividable by 2
27 packet = packet + '\0'
29 # split into 16-bit word and insert into a binary array
30 words = array.array('h', packet)
33 # perform ones complement arithmetic on 16-bit words
35 sum += (word & 0xffff)
40 sum = sum + (sum >> 16)
42 return (~sum) & 0xffff # return ones complement
44 def _construct(id, data):
45 """Constructs a ICMP IPOD packet
47 ICMP_TYPE = 6 # ping of death code used by PLK
53 header = struct.pack('bbHHh', ICMP_TYPE, ICMP_CODE, ICMP_CHECKSUM, \
54 ICMP_ID, ICMP_SEQ_NR+id)
56 packet = header + data # ping packet without checksum
57 checksum = _in_cksum(packet) # make checksum
59 # construct header with correct checksum
60 header = struct.pack('bbHHh', ICMP_TYPE, ICMP_CODE, checksum, ICMP_ID, \
63 # ping packet *with* checksum
64 packet = header + data
66 # a perfectly formatted ICMP echo packet
69 def icmp_pod(host,key):
72 print "must be root to send icmp pod"
75 s = socket(AF_INET, SOCK_RAW, getprotobyname("icmp"))
76 packet = _construct(0, key) # make a ping packet
78 print 'pod sending icmp-based reboot request to %s' % host
80 s.sendto(packet, addr)
82 def udp_pod(host,key,fromaddr=('', 0)):
83 addr = host, UPOD_PORT
84 s = socket(AF_INET, SOCK_DGRAM)
87 print 'pod sending udp-based reboot request to %s' % host
89 s.sendto(packet, addr)
91 def noop_pod(host,key):