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