From: Planet-Lab Support Date: Fri, 5 Aug 2005 23:05:13 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create tag X-Git-Tag: planetlab-3_1_1-rc3^0 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=c01b121e7cd32624a9d0d18290ced9b7102b8a4e;hp=b78b4a0b9256d477c3bdb70693a66de3da3865d2;p=pingofdeath.git This commit was manufactured by cvs2svn to create tag 'planetlab-3_1_1-rc3'. --- diff --git a/Makefile b/Makefile index 338dc58..fc4cf8d 100644 --- a/Makefile +++ b/Makefile @@ -7,31 +7,12 @@ # test: runs the tests on the current machine # -ALLBUILD=pl-poddoit pod ipod-2.0.tar.gz -PLBIN=/usr/local/planetlab/bin/ -INIT=/etc/init.d/ +ALLBUILD=pl-poddoit all: $(ALLBUILD) -pod: pod.src disable_pod.sh enable_pod.sh status_pod.sh - ./shell_include --source pod.src --destination pod - -ipod-2.0.tar.gz: pod ipod.spec - mkdir ipod-2.0 - cp ipod.spec disable_pod.sh enable_pod.sh INTEL_LICENSE.txt ipod.patch \ - Makefile pl-podcntl pl-poddoit.c pl-podset pl-podzap pod.src \ - README shell_include status_pod.sh test-pod ipod-2.0 - tar cvfz ipod-2.0.tar.gz ipod-2.0 - rm -rf ipod-2.0 - pl-poddoit: pl-poddoit.c gcc pl-poddoit.c -o pl-poddoit -install: all - cp pl-poddoit $(PLBIN) - chmod 555 $(PLBIN)/pl-poddoit - cp pod $(INIT) - chmod 555 $(INIT)/pod - clean: - rm -f pod pl-poddoit ipod-2.0.tar.gz + rm -f pl-poddoit diff --git a/ipod.spec b/ipod.spec index 3161ead..9609456 100644 --- a/ipod.spec +++ b/ipod.spec @@ -1,10 +1,20 @@ +%define name ipod +%define version 2.1 +%define release 1.planetlab%{?date:.%{date}} + +Vendor: PlanetLab +Packager: PlanetLab Central +Distribution: PlanetLab 3.0 +URL: http://cvs.planet-lab.org/cvs/ipod + Summary: PlanetLab ICMP Ping of Death -Name: ipod -Version: 2.0 -Release: 2 +Name: %{name} +Version: %{version} +Release: %{release} Copyright: GPL Group: System Environment/Kernel -Source: ipod-2.0.tar.gz +Source: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}root %description Startup service to enable Ping Of Death @@ -16,26 +26,32 @@ Startup service to enable Ping Of Death %build make + %install -make install +mkdir -p $RPM_BUILD_ROOT/usr/local/planetlab/bin +mkdir -p $RPM_BUILD_ROOT/etc/init.d + +cp pl-poddoit $RPM_BUILD_ROOT/usr/local/planetlab/bin/ +cp pod $RPM_BUILD_ROOT/etc/init.d/ + %clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + %files -%defattr(-, root, root) +%defattr(0755, root, root) /etc/init.d/pod /usr/local/planetlab/bin/pl-poddoit %pre %post -RUNLEVEL=`/sbin/runlevel` - if [ "$1" = 1 ]; then chkconfig --add pod chkconfig pod on - if [[ "$RUNLEVEL" != "unknown" ]]; then + if [[ "$PL_BOOTCD" != "1" ]] ; then /etc/init.d/pod start fi fi @@ -48,3 +64,13 @@ fi %postun + +%changelog +* Fri Aug 5 2005 Aaron Klingaman +- updated to use new source of POD Hash (/etc/planetlab/session) +- minor build changes to simply build process +- remove unnecessary call to runlevel in post section + +* Mon Apr 12 2004 Aaron Klingaman +- moved to new build process +- added change log diff --git a/pod b/pod new file mode 100755 index 0000000..a2ee0ee --- /dev/null +++ b/pod @@ -0,0 +1,216 @@ +#! /bin/bash +#include INTEL_LICENSE.txt +# +######################################################################## +# +# PlanetLab Ping Of Death +# +######################################################################## +# +# DESCRIPTION +# +# This shell script takes care of starting and stopping Planetlab +# Ping-Of-Death. +# +# The Planetlab POD is a Linux kernel patch that creates the feature +# of resetting and rebooting a computer when a particularily +# formatted ICMP "ping" commmand is received. +# +# A PlanetLab node's kernel gets a host, mask and hash value through +# sysctl's that are performed on the node. The node then looks +# for an ICMP packet from a host matching the host/mask and, if the +# packet payload is the hash value, the node forces an immediate +# reboot. +# +# HISTORY +# +# May 17, 2003 - Paul Brett +# Initial version based on the work of +# Robert Adams and EMULAB +# +# chkconfig: - 11 99 +# description: enable Ping of Death + +# Source function library. +. /etc/init.d/functions + +# Source networking configuration. +. /etc/sysconfig/network + +function enable_pod() +{ + local SYSCTL=/sbin/sysctl + + local IP_SUBNET=$1 + local IP_MASK=$2 + local HASH=$3 + + # Grotesque sed/awk converts IP addrs into an integer for sysctl + local IPODHOST=`echo $IP_SUBNET | \ + sed -e 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \2 \3 \4/' | \ + awk '{ printf "%d\n", $1*16777216+$2*65536+$3*256+$4 }'` + local IPODMASK=`echo $IP_MASK | \ + sed -e 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \2 \3 \4/' | \ + awk '{ printf "%d\n", $1*16777216+$2*65536+$3*256+$4 }'` + + # figure out the version + local version=`$SYSCTL net.ipv4.icmp_ipod_version 2>/dev/null` + if [[ "$version" == "" ]] + then + $SYSCTL net.ipv4.icmp_ipod_enabled >/dev/null 2>&1 + case $? in + 0) + version=1 + ;; + *) + version=0 + ;; + esac + fi + + # enable if possible + case $version in + 0) + return 1 + ;; + 1) + $SYSCTL -w net.ipv4.icmp_ipod_host=$IPODHOST >/dev/null + $SYSCTL -w net.ipv4.icmp_ipod_enabled=1 >/dev/null + Success=0 + ;; + *) + $SYSCTL -w net.ipv4.icmp_ipod_host=$IPODHOST >/dev/null + Success=$? + $SYSCTL -w net.ipv4.icmp_ipod_mask=$IPODMASK >/dev/null + $SYSCTL -w net.ipv4.icmp_ipod_key=$HASH >/dev/null + $SYSCTL -w net.ipv4.icmp_ipod_enabled=1 >/dev/null + ;; + esac + return $Success +} + +function disable_pod() +{ + local SYSCTL=/sbin/sysctl + $SYSCTL -w net.ipv4.icmp_ipod_enabled=0 >/dev/null + return 0 +} + +function status_pod() +{ + + local SYSCTL="/sbin/sysctl" + + # Check that IPOD is built into this kernel + local version + version=`$SYSCTL -n net.ipv4.icmp_ipod_version 2> /dev/null` + if [[ $? -ne 0 ]] + then + echo "Not installed" + return 255 + fi + + # Check if it has been enabled + local enabled=`$SYSCTL -n net.ipv4.icmp_ipod_enabled` + echo -n "version $version " + if [[ $enabled -eq 1 ]] + then + echo "Enabled" + else + echo "Disabled" + fi + return $enabled +} + +echo -n "PlanetLab Ping Of Death " + +CONF=/etc/ipod.conf + +if [[ -r $CONF ]] +then + # load the POD configuration file + . $CONF +else + # no POD configuration file - failed + echo + action $"Missing configuration file $CONF" /bin/false + exit 1 +fi + +SESSION=/etc/planetlab/session + +if [[ -r $SESSION ]] +then + # load the session value file + HASH=`cat $SESSION` +else + # no session value (ie, no hash) + echo + action $"Missing node session file $SESSION" /bin/false + exit 1 +fi + +# Check that networking is up. +if [[ ${NETWORKING} = "no" ]] +then + action $"" /bin/false + exit 1 +fi + +# Check the POD parameters +if [[ "$HASH" == "" ]] +then + echo + action $"Missing HASH (from $SESSION)" /bin/false + exit 1 +fi + +if [[ "$IP_SUBNET" == "" ]] +then + echo + action $"Missing IP_SUBNET in $CONF" /bin/false + exit 1 +fi + +if [[ "$IP_MASK" == "" ]] +then + echo + action $"Missing IP_MASK in $CONF" /bin/false + exit 1 +fi + +# See how we were called. +case "$1" in + start) + enable_pod $IP_SUBNET $IP_MASK $HASH + RETVAL=$? + if [[ $RETVAL -eq 0 ]] + then + action $"" /bin/true + else + action $"" /bin/false + fi + ;; + stop) + disable_pod + RETVAL=$? + if [[ $RETVAL -eq 0 ]] + then + action $"" /bin/true + else + action $"" /bin/false + fi + ;; + status) + status_pod + RETVAL=$? + ;; + restart|reload) + disable_pod + enable_pod + RETVAL=$? + ;; + *) + echo $"Usage: $0 {start|stop|restart|status}" + exit 1 +esac diff --git a/pod.py b/pod.py new file mode 100755 index 0000000..7e406df --- /dev/null +++ b/pod.py @@ -0,0 +1,141 @@ +#! /usr/bin/env python +# +# Marc E. Fiuczynski +# Copyright (C) 2004 The Trustees of Princeton University +# +# Client ping of death program for both udp & icmp + +import sys +import struct +import os +import array +import getopt +from socket import * + +def usage(): + sys.stdout = sys.stderr + print 'Usage: pod -i identityfile [--icmp,--udp] hostnamelist' + print ' -i identity key where key may be - for stdin' + print ' --icmp icmp protocol only' + print ' --udp udp protocol only' + print ' by default both icmp and udp are used' + + +UPOD_PORT = 664 + +def _in_cksum(packet): + """THE RFC792 states: 'The 16 bit one's complement of + the one's complement sum of all 16 bit words in the header.' + Generates a checksum of a (ICMP) packet. Based on in_chksum found + in ping.c on FreeBSD. + """ + + # add byte if not dividable by 2 + if len(packet) & 1: + packet = packet + '\0' + + # split into 16-bit word and insert into a binary array + words = array.array('h', packet) + sum = 0 + + # perform ones complement arithmetic on 16-bit words + for word in words: + sum += (word & 0xffff) + + hi = sum >> 16 + lo = sum & 0xffff + sum = hi + lo + sum = sum + (sum >> 16) + + return (~sum) & 0xffff # return ones complement + +def _construct(id, data): + """Constructs a ICMP IPOD packet + """ + ICMP_TYPE = 6 # ping of death code used by PLK + ICMP_CODE = 0 + ICMP_CHECKSUM = 0 + ICMP_ID = 0 + ICMP_SEQ_NR = 0 + + header = struct.pack('bbHHh', ICMP_TYPE, ICMP_CODE, ICMP_CHECKSUM, \ + ICMP_ID, ICMP_SEQ_NR+id) + + packet = header + data # ping packet without checksum + checksum = _in_cksum(packet) # make checksum + + # construct header with correct checksum + header = struct.pack('bbHHh', ICMP_TYPE, ICMP_CODE, checksum, ICMP_ID, \ + ICMP_SEQ_NR+id) + + # ping packet *with* checksum + packet = header + data + + # a perfectly formatted ICMP echo packet + return packet + +def icmp_pod(host,key): + uid = os.getuid() + if uid <> 0: + print "must be root to send icmp pod" + return + + s = socket(AF_INET, SOCK_RAW, getprotobyname("icmp")) + packet = _construct(0, key) # make a ping packet + addr = (host,1) + print 'pod sending icmp-based reboot request to %s' % host + for i in range(1,10): + s.sendto(packet, addr) + +def udp_pod(host,key): + addr = host, UPOD_PORT + s = socket(AF_INET, SOCK_DGRAM) + s.bind(('', 0)) + packet = key + print 'pod sending udp-based reboot request to %s' % host + for i in range(1,10): + s.sendto(packet, addr) + +def noop_pod(host,key): + pass + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "i:", ["icmp","udp"]) + except getops.GetoptError: + usage() + sys.exit(2) + + hosts = args + protos = {'udp' : udp_pod, 'icmp' : icmp_pod} + key = None + for o, a in opts: + if o == "--icmp": + del protos['udp'] + if o == "--udp": + del protos['icmp'] + if o == "-i": + if len(a)==1 and a[0]=='-': + key = sys.stdin.readline() + else: + try: + f = open(a) + key = f.readline() + key = k[:32] + f.close() + except: + print '%s not found' % a + usage() + sys.exit(2) + + if key is None: + usage() + sys.exit(2) + + protocols = ['udp','icmp'] + for host in hosts: + for protocol in protocols: + pod = protos.get(protocol,noop_pod) + pod(host,key) + +main()