--- /dev/null
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+
+# * Neither the name of the Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
+# YOUR JURISDICTION. It is licensee's responsibility to comply with any
+# export regulations applicable in licensee's jurisdiction. Under
+# CURRENT (May 2000) U.S. export regulations this software is eligible
+# for export from the U.S. and can be downloaded by or otherwise
+# exported or reexported worldwide EXCEPT to U.S. embargoed destinations
+# which include Cuba, Iraq, Libya, North Korea, Iran, Syria, Sudan,
+# Afghanistan and any other country to which the U.S. has embargoed
+# goods and services.
--- /dev/null
+# Makefile for building and installing the application
+# level tools for the Planetlab "ping of death" feature.
+#
+# Targets are:
+# all: builds all of the components
+# install: installes the tools into the planetlab bin directory
+# 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/
+
+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
--- /dev/null
+Planetlab Ping-of-Death (POD)
+-----------------------------
+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.
+
+From a controlling host's side, one invokes commands on the
+remote node to set the host, mask and hash values and remembering
+the hash value. When the rebooting of a remote node is required,
+the remembered hash value is looked up and sent to the node
+in a specially constructed ICMP packet.
+
+This POD system uses the same packet definition as EMULAB and uses
+the some code from EMULAB to generate and transmit the packet.
+No reason to invent something new.
+
+The remote execution (ssh commands) are all done as "idsl1".
+
+Contolling host tools:
+pl-podset: set the host and hash on a remote node
+ Call: pl-podset hostIP maskIP targetName
+ Uses ssh to call 'pl-podcntl' on the remote node to
+ set the host and hash in that node. Also saves the
+ information into the file './HashFile'.
+pl-podzap: send ICMP packet to node to resetit
+ Call: pl-podzap targetName
+ Fetches parameters from the file './HashFile' and
+ calls 'pl-poddoit' on the 'hostIP' machine to send the
+ reset ICMP packet to the specified target node.
+ Note that this relies on the planetlab node that
+ was specified in the 'pl-podset' command to actually
+ do the packet transmission.
+pl-poddoit: send the ICMP packet (called by 'pl-podzap')
+ Routine that constructs an ICMP packet of the proper
+ format and send it to the node.
+
+Planetlab node scripts:
+pl-podcntl: set the host and hash into the kernel
+ Call: pl-podcntl hostIP maskIP hashValue
+ Sets the specified values into the kernel and enables
+ the POD filtering operation.
+
+EXAMPLE
+-------
+Setting a node to be able to reset (assuming running on 123.123.12.23):
+ pl-podset 123.123.12.23 255.255.255.255 planetlab-1.stanford.edu
+
+To later reset the node (command performed on 123.123.12.23):
+ pl-podzap planetlab-1.stanford.edu
--- /dev/null
+#! /bin/bash
+#include INTEL_LICENSE.txt
+#
+########################################################################
+#
+# Disable Ping Of Death
+#
+########################################################################
+#
+# DESCRIPTION
+#
+# The disable_pod function turns off the pod syscntl
+#
+# HISTORY
+#
+# May 17, 2003 - Paul Brett <paul.brett@intel.com>
+# Initial version based on the work of
+# Robert Adams <robert.adams@intel.com> and EMULAB
+#
+
+function disable_pod()
+{
+ local SYSCTL=/sbin/sysctl
+ $SYSCTL -w net.ipv4.icmp_ipod_enabled=0 >/dev/null
+ return 0
+}
+
+
--- /dev/null
+#! /bin/bash
+#include INTEL_LICENSE.txt
+#
+########################################################################
+#
+# Enable Ping Of Death
+#
+########################################################################
+#
+# DESCRIPTION
+#
+# The Enable_POD function is passed the IP_SUBNET, IP_MASK and HASH and
+# does all the dirty muching about with syscontrols
+#
+# HISTORY
+#
+# May 17, 2003 - Paul Brett <paul.brett@intel.com>
+# Initial version based on the work of
+# Robert Adams <robert.adams@intel.com> and EMULAB
+#
+
+function enable_pod()
+{
+ local SYSCTL=/sbin/sysctl
+
+ local IP_SUBNET=$1
+ local IP_MASK=$2
+ local IP_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 }'`
+ local IPODKEY=`echo $HASH | \
+ sed -e 's/\(.*\)/\1/'`
+
+ # 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=$IPODKEY >/dev/null
+ $SYSCTL -w net.ipv4.icmp_ipod_enabled=1 >/dev/null
+ ;;
+ esac
+ return $Success
+}
+
+
--- /dev/null
+Summary: PlanetLab ICMP Ping of Death
+Name: ipod
+Version: 2.0
+Release: 2
+Copyright: GPL
+Group: System Environment/Kernel
+Source: ipod-2.0.tar.gz
+
+%description
+Startup service to enable Ping Of Death
+
+%prep
+
+%setup
+
+%build
+make
+
+%install
+make install
+
+%clean
+
+%files
+%defattr(-, 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
+ /etc/init.d/pod start
+ fi
+fi
+
+%preun
+if [ "$1" = 0 ]; then
+ chkconfig pod off
+ chkconfig --del pod
+fi
+
+%postun
+
--- /dev/null
+#/bin/sh -
+#
+# Enable ICMP ping-of-death. Runs on the target node and sets the
+# passed parameters into the kernel.
+# Invocation: pl-podcntl HOSTIP HOSTMASK HASH
+
+# -----------------------------------------------------------------
+# $Header: /shareddata/CVS/planetlab/admin/ipod/pl-podcntl,v 1.2 2003/01/18 01:43:48 radams Exp $
+#
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+# This file is distributed under the terms in the attached INTEL_LICENSE
+# file. If you do not find this file, a copy can be obtained by
+# writing to Intel Research Berkeley; Attention: Intel License Inquiry;
+# 2150 Shattuck Avenue; Berkeley, CA 94704
+# -----------------------------------------------------------------
+
+# Modified from origional EMULAB script. Origional copyright:
+# EMULAB-COPYRIGHT
+# Copyright (c) 2000-2002 University of Utah and the Flux Group.
+# All rights reserved.
+#
+# Enable ICMP ping-of-death
+# Support both the old style (host only) and the new style (host+mask+key)
+#
+
+IPODHOSTP=$1
+IPODMASKP=$2
+IPODHASHP=$3
+
+SYSCTL="/sbin/sysctl"
+
+# Grotesque sed/awk converts IP addrs into an integer for sysctl
+if [ x"$IPODHOSTP" != x ]; then
+ IPODHOST=`echo $IPODHOSTP | \
+ 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 }'`
+ IPODMASK=`echo $IPODMASKP | \
+ 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 }'`
+ IPODKEY=`echo $IPODHASHP | \
+ sed -e 's/\(.*\)/\1/'`
+
+ echo "IPODHOST = $IPODHOST"
+ echo "IPODMASK = $IPODMASK"
+ echo "IPODKEY = $IPODKEY"
+
+ # figure out the version
+ version=`$SYSCTL net.ipv4.icmp_ipod_version 2>/dev/null`
+ if [ "$version"x = x ]; then
+ $SYSCTL net.ipv4.icmp_ipod_enabled >/dev/null 2>&1
+ case $? in
+ 0)
+ version=1
+ ;;
+ *)
+ version=0
+ ;;
+ esac
+ fi
+
+ echo "Version = $version"
+ # enable if possible
+ case $version in
+ 0)
+ echo "*** WARNING: no IPOD sysctls, not enabled"
+ exit 1
+ ;;
+ 1)
+ $SYSCTL -w net.ipv4.icmp_ipod_host=$IPODHOST >/dev/null
+ $SYSCTL -w net.ipv4.icmp_ipod_enabled=1 >/dev/null
+ str="Old-style"
+ ;;
+ *)
+ $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=$IPODKEY >/dev/null
+ $SYSCTL -w net.ipv4.icmp_ipod_enabled=1 >/dev/null
+ str="Authenticated"
+ ;;
+ esac
+ echo Success = $Success
+ if [[ $Success -eq 0 ]] ; then
+ IPODHOST=`echo $IPODINFO | \
+ sed -e 's/.*HOST=\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/'`
+ IPODMASK=`echo $IPODINFO | \
+ sed -e 's/.*MASK=\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/'`
+ echo "$str IPOD enabled from $IPODHOST/$IPODMASK"
+ else
+ echo "*** WARNING: could not set IPOD info, not enabled"
+ fi
+else
+ echo "*** WARNING: no IPOD info, not enabled"
+fi
+
--- /dev/null
+/*
+ * EMULAB-COPYRIGHT
+ * Copyright (c) 2000-2002 University of Utah and the Flux Group.
+ * All rights reserved.
+ */
+
+/*
+ * Send the magical ping of death ICMP type
+ */
+
+
+#include <time.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <arpa/inet.h>
+
+#define IPOD_ICMPTYPE 6
+#define IPOD_ICMPCODE 6
+#define IPOD_IPLEN 666
+#define IPOD_IDLEN 32
+
+int icmpid = 0;
+static char myid[IPOD_IDLEN];
+static int myidlen = 0;
+
+u_short in_cksum(u_short *addr, int len);
+void icmpmap_init(); /* For getting information */
+void icmp_info(struct icmp *icmp, char *outbuf, int maxlen);
+
+/*
+ * We perform lookups on the hosts, and then store them in a chain
+ * here.
+ */
+
+struct hostdesc {
+ char *hostname;
+ struct in_addr hostaddr;
+ struct hostdesc *next;
+};
+
+struct hostdesc *hostnames;
+struct hostdesc *hosttail;
+
+/*
+ * Set up the list of hosts. Return the count.
+ */
+
+int makehosts(char **hostlist)
+{
+ int i;
+ struct hostent *hp;
+ struct in_addr tmpaddr;
+ int hostcount = 0;
+
+ for (i = 0; hostlist[i]; i++) {
+#ifdef DEBUG
+ printf("Resolving %s\n", hostlist[i]);
+#endif
+ if (!hostlist[i] ||
+ !hostlist[i][0] ||
+ strlen(hostlist[i]) > MAXHOSTNAMELEN) {
+ fprintf(stderr, "bad host entry, exiting\n");
+ exit(-1);
+ }
+ if (!inet_aton(hostlist[i], &tmpaddr)) {
+ if ((hp = gethostbyname(hostlist[i])) == NULL) {
+ /* Could not resolve it. Skip it. */
+ fprintf(stderr, "%s: unknown host\n",
+ hostlist[i]);
+ continue;
+ }
+ else {
+ memcpy(&tmpaddr.s_addr,
+ hp->h_addr_list[0],
+ hp->h_length);
+ }
+ }
+
+ /* The host has been resolved. Put it in the chain */
+ /* We want to stick it on the end. */
+ if (hostnames == NULL) {
+ hostnames = (struct hostdesc *)
+ malloc(sizeof(*hostnames));
+ if (hostnames == NULL) {
+ perror("hostnames malloc failed");
+ exit(-1);
+ }
+ hosttail = hostnames;
+ } else {
+ hosttail->next = (struct hostdesc *)
+ malloc(sizeof(*hostnames));
+ if (hosttail->next == NULL) {
+ perror("hosttail->next malloc failed");
+ exit(-1);
+ }
+ hosttail = hosttail->next;
+ }
+ hosttail->hostname = strdup(hostlist[i]);
+ if (hosttail->hostname == NULL) {
+ perror("strdup failed");
+ exit(-1);
+ }
+ hosttail->hostaddr = tmpaddr;
+ hosttail->next = NULL;
+ hostcount++;
+ }
+ return hostcount;
+}
+
+void usage(char *prog)
+{
+ fprintf(stderr, "%s [ -i identityfile ] target [ target ... ]\n", prog);
+}
+
+/*
+ * Set up a packet. Returns the length of the ICMP portion.
+ */
+
+void initpacket(char *buf, int querytype, struct in_addr fromaddr)
+{
+ struct ip *ip = (struct ip *)buf;
+ struct icmp *icmp = (struct icmp *)(ip + 1);
+
+ /* things we customize */
+ int icmplen = 0;
+
+ ip->ip_src = fromaddr; /* if 0, have kernel fill in */
+ ip->ip_v = 4; /* Always use ipv4 for now */
+ ip->ip_hl = sizeof *ip >> 2;
+ ip->ip_tos = 0;
+ ip->ip_id = htons(4321);
+ ip->ip_ttl = 255;
+ ip->ip_p = 1;
+ ip->ip_sum = 0; /* kernel fills in */
+
+ icmp->icmp_seq = 1;
+ icmp->icmp_cksum = 0; /* We'll compute it later. */
+ icmp->icmp_type = querytype;
+ icmp->icmp_code = IPOD_ICMPCODE;
+ if (myidlen)
+ memcpy(icmp->icmp_data, myid, myidlen);
+
+ ip->ip_len = IPOD_IPLEN;
+ icmplen = IPOD_IPLEN - sizeof(struct ip);
+ icmp->icmp_cksum = in_cksum((u_short *)icmp, icmplen);
+}
+
+/*
+ * Send all of the ICMP queries.
+ */
+
+void sendpings(int s, int querytype, struct hostdesc *head, int delay,
+ struct in_addr fromaddr)
+
+{
+ char buf[1500];
+ struct ip *ip = (struct ip *)buf;
+ struct sockaddr_in dst;
+
+ bzero(buf, 1500);
+ initpacket(buf, querytype, fromaddr);
+ dst.sin_family = AF_INET;
+#ifdef DA_HAS_SIN_LEN
+ dst.sin_len = sizeof(dst);
+#endif
+
+ while (head != NULL) {
+ int rc;
+#ifdef DEBUG
+ printf("pinging %s\n", head->hostname);
+#endif
+ ip->ip_dst.s_addr = head->hostaddr.s_addr;
+ dst.sin_addr = head->hostaddr;
+ rc = sendto(s, buf, ip->ip_len, 0,
+ (struct sockaddr *)&dst,
+ sizeof(dst));
+ if (rc != ip->ip_len) {
+ perror("sendto");
+ }
+ /* Don't flood small pipes. */
+ if (delay)
+ usleep(delay);
+ head = head->next;
+ }
+}
+
+/*
+ * Handles our timeout for us. Called by the signal handler
+ * when we get a SIGARLM.
+ */
+
+void myexit(int whatsig)
+{
+ exit(0);
+}
+
+/*
+ * Open a raw socket for receiving ICMP. Tell the kernel we want
+ * to supply the IP headers.
+ */
+
+int get_icmp_socket()
+{
+ int s;
+ int on = 1;
+ if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
+ perror("socket");
+ exit(1);
+ }
+ if (setsockopt(s, IPPROTO_IP, IP_HDRINCL,
+ (const char *)&on, sizeof(on)) < 0) {
+ perror("IP_HDRINCL");
+ exit(1);
+ }
+ return s;
+}
+
+int
+main(int argc, char **argv)
+{
+ int s;
+
+ char *progname;
+ extern char *optarg; /* getopt variable declarations */
+ extern int optind;
+ char ch; /* Holds the getopt result */
+ int hostcount;
+ int delay = 0;
+ int querytype = ICMP_TSTAMP;
+ struct in_addr fromaddr;
+ int timeout = 5; /* Default to 5 seconds */
+ int identityfile;
+
+ fromaddr.s_addr = 0;
+
+ progname = argv[0];
+
+ querytype = IPOD_ICMPTYPE; /* the magical death packet number */
+
+ while ((ch = getopt(argc, argv, "i:")) != -1)
+ switch(ch)
+ {
+ case 'i':
+ if (optarg[0] == '-')
+ identityfile = 0;
+ else if ((identityfile = open(optarg, 0)) < 0)
+ {
+ perror(optarg);
+ exit(1);
+ }
+ myidlen = read(identityfile, myid, IPOD_IDLEN);
+ if (optarg[0] != '-')
+ close(identityfile);
+ if (myidlen != IPOD_IDLEN)
+ {
+ fprintf(stderr, "%s: cannot read %d-byte identity\n",
+ optarg[0] != '-' ? optarg : "<stdin>", IPOD_IDLEN);
+ exit(2);
+ }
+ break;
+ default:
+ usage(progname);
+ exit(-1);
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (!argv[0] || !strlen(argv[0]))
+ {
+ usage(progname);
+ exit(-1);
+ }
+
+ hostcount = makehosts(argv);
+
+ s = get_icmp_socket();
+
+ signal(SIGALRM, myexit);
+ alarm(timeout);
+ sendpings(s, querytype, hostnames, delay, fromaddr);
+ exit(0);
+}
+
+/*
+ * in_cksum --
+ * Checksum routine for Internet Protocol family headers (C Version)
+ * From FreeBSD's ping.c
+ */
+
+u_short
+in_cksum(addr, len)
+ u_short *addr;
+ int len;
+{
+ register int nleft = len;
+ register u_short *w = addr;
+ register int sum = 0;
+ u_short answer = 0;
+
+ /*
+ * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+ * sequential 16 bit words to it, and at the end, fold back all the
+ * carry bits from the top 16 bits into the lower 16 bits.
+ */
+ while (nleft > 1) {
+ sum += *w++;
+ nleft -= 2;
+ }
+
+ /* mop up an odd byte, if necessary */
+ if (nleft == 1) {
+ *(u_char *)(&answer) = *(u_char *)w ;
+ sum += answer;
+ }
+
+ /* add back carry outs from top 16 bits to low 16 bits */
+ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
+ sum += (sum >> 16); /* add carry */
+ answer = ~sum; /* truncate to 16 bits */
+ return(answer);
+}
+
--- /dev/null
+#! /bin/bash
+Invocation="pl-podset HOSTIPAddr TARGETIPAddr"
+# Run on a controlling computer to set the pod parameters on a
+# remote node. A hash code is generated and set into the remote
+# node and stored in a local file for later invocation.
+# -----------------------------------------------------------------
+# $Header: /shareddata/CVS/planetlab/admin/ipod/pl-podset,v 1.3 2003/01/18 01:43:48 radams Exp $
+#
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+# This file is distributed under the terms in the attached INTEL_LICENSE
+# file. If you do not find this file, a copy can be obtained by
+# writing to Intel Research Berkeley; Attention: Intel License Inquiry;
+# 2150 Shattuck Avenue; Berkeley, CA 94704
+# -----------------------------------------------------------------
+
+HOSTIP=$1
+TARGETIP=$2
+
+if [[ x$HOSTIP == x || x$TARGETIP == x ]] ; then
+ echo "Invocation: $Invocation"
+ exit 1
+fi
+
+DATEE=`date +%Y%m%d%H%M`
+TEMPFILE="/tmp/HashFile_$RANDOM"
+HASHFILE="./HashFile"
+PLBIN="/usr/local/planetlab/bin"
+
+HASHCODE=`printf "%04x%04x%04x%04x%04x%04x%04x%04x\n" $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM`
+
+#echo "HOSTIP = $HOSTIP"
+#echo "TARGETIP = $TARGETIP"
+#echo "HASHCODE = '$HASHCODE'"
+
+ssh idsl1@$TARGETIP "sudo $PLBIN/pl-podcntl $HOSTIP 255.255.255.255 $HASHCODE"
+
+if [[ -f $HASHFILE ]] ; then
+ grep -v "$TARGETIP" $HASHFILE > $TEMPFILE
+else
+ touch $HASHFILE
+ touch $TEMPFILE
+fi
+echo "$DATEE $HOSTIP $TARGETIP $HASHCODE" >> $TEMPFILE
+mv $HASHFILE $HASHFILE.last
+mv $TEMPFILE $HASHFILE
--- /dev/null
+#! /bin/bash
+Invocation="pl-podzap TargetHostName"
+# Fetches the hash code from the saved hash code file and commands
+# the specified PlanetLab node to send
+# the properly constructed ICMP message to the remote node to
+# reset it.
+# -----------------------------------------------------------------
+# $Header: /shareddata/CVS/planetlab/admin/ipod/pl-podzap,v 1.4 2003/01/18 01:43:48 radams Exp $
+#
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+# This file is distributed under the terms in the attached INTEL_LICENSE
+# file. If you do not find this file, a copy can be obtained by
+# writing to Intel Research Berkeley; Attention: Intel License Inquiry;
+# 2150 Shattuck Avenue, suite 1300; Berkeley, CA 94704
+# -----------------------------------------------------------------
+
+TARGETIP=$1
+
+if [[ x$TARGETIP == x ]] ; then
+ echo "Invocation: $Invocation"
+ exit 1
+fi
+
+PLBIN="/usr/local/planetlab/bin"
+HASHFILE="./HashFile"
+
+set `grep "$TARGETIP" $HASHFILE`
+DATEE=$1
+HOSTIP=$2
+TARGETIPP=$3
+HASHCODE=$4
+
+if [[ x$HASHCODE != x ]] ; then
+ echo "DATEE=$DATEE, HOSTIP=$HOSTIP, TARGETIPP=$TARGETIPP, HASHCODE = '$HASHCODE'"
+
+ ssh idsl1@$HOSTIP "echo $HASHCODE | sudo $PLBIN/pl-poddoit -i - $TARGETIP"
+else
+ echo "No hash code found for specified target node"
+fi
+
--- /dev/null
+#! /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 <paul.brett@intel.com>
+# Initial version based on the work of
+# Robert Adams <robert.adams@intel.com> and EMULAB
+#
+# chkconfig: - 11 99
+# description: enable Ping of Death
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+#include enable_pod.sh
+#include disable_pod.sh
+#include status_pod.sh
+
+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
+
+# 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 in $CONF" /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 $IP_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
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use Getopt::Long;
+
+my $source = "";
+my $destination = "";
+my $make;
+my $help;
+
+my @lines;
+my %included;
+
+########################################################################
+#
+# usage
+#
+
+sub usage()
+{
+ print "Usage: shell_include --source <file> --destination <file> [--make] [--help]\n";
+ print "\n";
+ print "--make will output makefile dependencies to stdout and exit\n";
+ print "--help will output this text and exit\n";
+ print "\n";
+}
+########################################################################
+#
+# check_options
+#
+
+sub check_options()
+{
+ if ( !GetOptions(
+ 's|source=s' => \$source,
+ 'd|destination=s' => \$destination,
+ 'm|make' => \$make,
+ 'h|help' => \$help ) )
+ {
+ &usage;
+ exit 1;
+ }
+
+ if ( $help ) {
+ &usage;
+ exit 0;
+ };
+
+ die( "Missing input file - use --source <file>" ) if ( $source eq "" );
+ die( "Missing output file - use --destination <file>") if ( $destination eq "" );
+}
+
+########################################################################
+#
+# read_input : Read in the initial input file into @lines
+#
+
+sub read_input()
+{
+ open( SOURCE, $source ) || die ( "Cannot open input file : $source" );
+ while ( <SOURCE> ) {
+ @lines = ( @lines, $_ );
+ };
+ close( SOURCE );
+}
+
+########################################################################
+#
+# Process #include directives
+#
+sub process_includes()
+{
+ my $changed = 0;
+ my @newlines;
+
+ foreach my $line ( @lines ) {
+
+ if ( $line =~ /^(\s*)\#include(\s+)(\S+)/ ) {
+ $changed = 1;
+ my $filename = $3;
+ if ( ! defined $included{ $filename } ) {
+ open( INC, $filename ) || die ( "Cannot open include file : $filename" );
+ @newlines = ( @newlines, "########################################################################\n" );
+ @newlines = ( @newlines, "#\n" );
+ @newlines = ( @newlines, "# Included file : $filename\n" );
+ @newlines = ( @newlines, "#\n" );
+ while( <INC> ) {
+ @newlines = ( @newlines, $_ );
+ }
+ close( INC );
+ @newlines = ( @newlines, "#\n" );
+ @newlines = ( @newlines, "# End of included file : $filename\n" );
+ @newlines = ( @newlines, "#\n" );
+ @newlines = ( @newlines, "########################################################################\n" );
+ $included{ $filename } = "";
+ }
+ } else {
+ @newlines = ( @newlines, $line );
+ }
+ }
+ @lines = @newlines;
+ return $changed;
+}
+
+########################################################################
+#
+# write_output : write the final set of lines to the output file
+#
+sub write_output()
+{
+ open( DEST, ">$destination" ) || die( "Cannot open output file : $destination" );
+ foreach my $line ( @lines ) {
+ print DEST $line;
+ }
+ close( DEST );
+}
+
+&check_options;
+&read_input;
+while ( &process_includes ) { };
+if ( $make ) {
+ print "$destination: $source ";
+ foreach my $inc ( sort( keys( %included ) ) ) {
+ print "$inc ";
+ };
+ print "\n";
+} else {
+ &write_output;
+}
--- /dev/null
+#!/bin/bash
+
+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
+}
--- /dev/null
+#! /bin/sh
+# Script to test the "ping-of-death" ("POD") functionality.
+# This script is run on a machine that has the POD feature patched
+# into the kernel and has the tools installed in the machine.
+#
+# The process is:
+# * build the kernel with the pod patch
+# * install the kernel on a machine
+# * reboot to run that kernel
+# * on the machine with that kernel, run this script
+# * if you answer "y" to the question, you will reboot that machine
+#
+# This script was built from the pl-pod* script files. It has no
+# dependency on them other than it expects /usr/local/planetlab/bin/pl-poddoit
+# to exist to send the POD packet.
+# -----------------------------------------------------------------
+# $Header: /shareddata/CVS/planetlab/admin/ipod/test-pod,v 1.2 2003/01/18 01:52:10 radams Exp $
+#
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+# This file is distributed under the terms in the attached INTEL_LICENSE
+# file. If you do not find this file, a copy can be obtained by
+# writing to Intel Research Berkeley; Attention: Intel License Inquiry;
+# 2150 Shattuck Avenue, suite 1300; Berkeley, CA 94704
+# -----------------------------------------------------------------
+
+PLBIN="/usr/local/planetlab/bin"
+PLDOIT="$PLBIN/pl-poddoit"
+
+SYSCTL="/sbin/sysctl"
+
+if ! [[ -x $PLDOIT ]] ; then
+ echo "CONFIG ERROR: the send POD executable not available at $PLDOIT"
+ exit 1
+fi
+
+IPODHOSTP=`hostname -i`
+IPODMASKP="255.255.255.255"
+IPODHASHP=`printf "%04x%04x%04x%04x%04x%04x%04x%04x\n" $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM`
+
+echo "IPODHOST = $IPODHOSTP"
+echo "IPODMASK = $IPODMASKP"
+echo "IPODKEY = $IPODHASHP"
+
+echo "=== Set the set parameters into the kernel ==="
+IPODHOST=`echo $IPODHOSTP | \
+ 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 }'`
+IPODMASK=`echo $IPODMASKP | \
+ 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 }'`
+IPODKEY=`echo $IPODHASHP | \
+ sed -e 's/\(.*\)/\1/'`
+$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=$IPODKEY >/dev/null
+$SYSCTL -w net.ipv4.icmp_ipod_enabled=1 >/dev/null
+if [[ $Success -eq 0 ]] ; then
+ echo "SUCCESS setting parameters"
+else
+ echo "FAILURE to set POD parameters"
+ exit 1
+fi
+
+echo "=== Try to reset with wrong payload -- this should fail ==="
+echo echo "01234567890123456789012345678901" \| $PLDOIT -i - $IPODHOSTP
+echo "01234567890123456789012345678901" | $PLDOIT -i - $IPODHOSTP
+
+echo "=== Reset host ==="
+echo "THIS NEXT STEP WILL RESET THIS COMPUTER!!!!"
+read -p "Enter 'y' if you wish to reset this computer: " REPLY
+if [[ x"$REPLY" == "xy" ]] ; then
+ echo $IPODHASHP | $PLDOIT -i - $IPODHOSTP
+ echo echo $IPODHASHP \| $PLDOIT -i - $IPODHOSTP
+else
+ echo "Final reset test not performed."
+fi
+
+