All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit ea238e3f authored by Grant Ayers's avatar Grant Ayers

Renamed existing IPOD patches.

parent 40b51444
--- conf/options 2002/10/16 20:16:10 1.1
+++ conf/options 2002/10/17 20:33:46
@@ -487,3 +487,6 @@
# Polling device handling
DEVICE_POLLING opt_global.h
+
+# Utah testbed
+ICMP_PINGOFDEATH
--- netinet/ip_icmp.c 2002/10/16 19:36:31 1.1
+++ netinet/ip_icmp.c 2002/12/19 19:07:15
@@ -124,6 +124,11 @@
static void icmp_send __P((struct mbuf *, struct mbuf *, struct route *));
static int ip_next_mtu __P((int, int));
+#include "opt_icmp_pingofdeath.h"
+#ifdef ICMP_PINGOFDEATH
+static void icmp_pingofdeath __P((struct icmp *, struct ip *, int));
+#endif
+
extern struct protosw inetsw[];
/*
@@ -570,6 +575,12 @@
#endif
break;
+#ifdef ICMP_PINGOFDEATH
+ case ICMP_PINGOFDEATH:
+ icmp_pingofdeath(icp, ip, hlen);
+ break;
+#endif
+
/*
* No kernel processing for the following;
* just fall through to send to raw listener.
@@ -888,4 +899,99 @@
#endif
+#ifdef ICMP_PINGOFDEATH
+#include <machine/md_var.h>
+#include <sys/syslog.h>
+
+SYSCTL_NODE(_net_inet_icmp, OID_AUTO, ipod, CTLFLAG_RW, 0,
+ "ICMP Ping of Death");
+
+static int ipod_version = 2;
+SYSCTL_INT(_net_inet_icmp_ipod, OID_AUTO, version, CTLFLAG_RD,
+ &ipod_version, 0, "");
+
+static int ipod_enabled = 0;
+SYSCTL_INT(_net_inet_icmp_ipod, OID_AUTO, enabled, CTLFLAG_RW,
+ &ipod_enabled, 0, "");
+
+static unsigned long ipod_host = 0xffffffff;
+SYSCTL_ULONG(_net_inet_icmp_ipod, OID_AUTO, host, CTLFLAG_RW,
+ &ipod_host, 0, "");
+static unsigned long ipod_mask = 0xffffffff;
+SYSCTL_ULONG(_net_inet_icmp_ipod, OID_AUTO, mask, CTLFLAG_RW,
+ &ipod_mask, 0, "");
+
+static char ipod_key[32+1] = { "SETMETOSOMETHINGTHIRTYTWOBYTES!!" };
+#define IPOD_CHECK_KEY \
+ (ipod_key[0] != 0)
+#define IPOD_VALID_KEY(d) \
+ (strncmp(ipod_key, (char *)(d), strlen(ipod_key)) == 0)
+
+static int
+ipod_getkey(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+
+ /* XXX fake up a result */
+ error = SYSCTL_OUT(req, "XXXX", 4+1);
+ if (error || !req->newptr)
+ return (error);
+
+ if ((req->newlen - req->newidx) >= sizeof(ipod_key))
+ return (EINVAL);
+
+ arg2 = (req->newlen - req->newidx);
+ error = SYSCTL_IN(req, ipod_key, arg2);
+ memset(&ipod_key[arg2], 0, sizeof(ipod_key) - arg2);
+
+ return (error);
+}
+
+SYSCTL_PROC(_net_inet_icmp_ipod, OID_AUTO, key, CTLTYPE_STRING | CTLFLAG_RW,
+ NULL, 0, ipod_getkey, "A", "");
+
+static void
+icmp_pingofdeath(icp, ip, hlen)
+ struct icmp *icp;
+ struct ip *ip;
+ int hlen;
+{
+ int doit = 0;
+ /*
+ * If IPOD not enabled or wrong ICMP code, ignore.
+ */
+ if (!ipod_enabled || icp->icmp_code != 6)
+ return;
+
+ /*
+ * First check the source address info.
+ * If host not set, ignore.
+ */
+ if (ipod_host != 0xffffffff &&
+ (ntohl(ip->ip_src.s_addr) & ipod_mask) == ipod_host) {
+ /*
+ * Now check the key if enabled.
+ * If packet doesn't contain enough data or key
+ * is otherwise invalid, ignore.
+ */
+ if (IPOD_CHECK_KEY) {
+ if (ip->ip_len >= strlen(ipod_key) &&
+ IPOD_VALID_KEY(icp->icmp_data))
+ doit = 1;
+ } else {
+ doit = 1;
+ }
+ }
+
+ if (doit) {
+ ipod_enabled = 0;
+ printf("IPOD: reboot forced by %lx...\n",
+ ntohl(ip->ip_src.s_addr));
+ cpu_reset();
+ } else {
+ log(LOG_ERR, "IPOD: from %lx rejected\n",
+ ntohl(ip->ip_src.s_addr));
+ }
+}
+#endif
--- include/linux/sysctl.h 2002/01/17 18:38:13 1.1
+++ include/linux/sysctl.h 2002/12/19 00:12:10
@@ -284,6 +284,13 @@
NET_TCP_APP_WIN=86,
NET_TCP_ADV_WIN_SCALE=87,
NET_IPV4_NONLOCAL_BIND=88,
+
+ /* CONFIG_ICMP_PINGOFDEATH */
+ NET_IPV4_ICMP_POD_ENABLED=89,
+ NET_IPV4_ICMP_POD_HOST=90,
+ NET_IPV4_ICMP_POD_MASK=91,
+ NET_IPV4_ICMP_POD_KEY=92,
+ NET_IPV4_ICMP_POD_VERSION=93,
};
enum {
--- net/ipv4/Config.in 2001/11/16 22:16:12 1.1
+++ net/ipv4/Config.in 2002/04/17 04:14:30
@@ -50,3 +50,8 @@
if [ "$CONFIG_NETFILTER" != "n" ]; then
source net/ipv4/ipvs/Config.in
fi
+
+#
+# Emulab special
+#
+bool ' ICMP: ICMP Ping-of-Death (Emulab)' CONFIG_ICMP_PINGOFDEATH
--- net/ipv4/icmp.c 2001/11/16 19:13:03 1.1
+++ net/ipv4/icmp.c 2002/12/19 19:15:51
@@ -856,6 +856,67 @@
in_dev_put(in_dev);
}
+#ifdef CONFIG_ICMP_PINGOFDEATH
+#include <linux/reboot.h>
+
+int sysctl_ipod_version = 2;
+int sysctl_ipod_enabled = 0;
+u32 sysctl_ipod_host = 0xffffffff;
+u32 sysctl_ipod_mask = 0xffffffff;
+char sysctl_ipod_key[32+1] = { "SETMETOSOMETHINGTHIRTYTWOBYTES!!" };
+#define IPOD_CHECK_KEY \
+ (sysctl_ipod_key[0] != 0)
+#define IPOD_VALID_KEY(d) \
+ (strncmp(sysctl_ipod_key, (char *)(d), strlen(sysctl_ipod_key)) == 0)
+
+static void icmp_ping_of_death(struct sk_buff *skb)
+{
+ struct icmphdr *icmph = skb->h.icmph;
+ struct iphdr *iph = skb->nh.iph;
+ int doit = 0;
+
+#if 0
+ printk(KERN_INFO "IPOD: got type=6, code=%d, host=%u.%u.%u.%u\n", icmph->code, ntohs(iph->tot_len), NIPQUAD(iph->saddr));
+#endif
+
+ /*
+ * If IPOD not enabled or wrong ICMP code, ignore.
+ */
+ if (!sysctl_ipod_enabled || icmph->code != 6)
+ return;
+
+ /*
+ * First check the source address info.
+ * If host not set, ignore.
+ */
+ if (sysctl_ipod_host != 0xffffffff &&
+ (ntohl(iph->saddr) & sysctl_ipod_mask) == sysctl_ipod_host) {
+ /*
+ * Now check the key if enabled.
+ * If packet doesn't contain enough data or key
+ * is otherwise invalid, ignore.
+ */
+ if (IPOD_CHECK_KEY) {
+ if (pskb_may_pull(skb, sizeof(sysctl_ipod_key)-1) &&
+ IPOD_VALID_KEY(skb->data))
+ doit = 1;
+ } else {
+ doit = 1;
+ }
+ }
+
+ if (doit) {
+ sysctl_ipod_enabled = 0;
+ printk(KERN_CRIT "IPOD: reboot forced by %u.%u.%u.%u...\n",
+ NIPQUAD(iph->saddr));
+ machine_restart(NULL);
+ } else {
+ printk(KERN_WARNING "IPOD: from %u.%u.%u.%u rejected\n",
+ NIPQUAD(iph->saddr));
+ }
+}
+#endif
+
static void icmp_discard(struct sk_buff *skb)
{
}
@@ -962,7 +1023,12 @@
{ &icmp_statistics[0].IcmpOutSrcQuenchs, &icmp_statistics[0].IcmpInSrcQuenchs, icmp_unreach, 1, },
/* REDIRECT (5) */
{ &icmp_statistics[0].IcmpOutRedirects, &icmp_statistics[0].IcmpInRedirects, icmp_redirect, 1, },
+#ifdef CONFIG_ICMP_PINGOFDEATH
+/* PING_OF_DEATH (6) */
+ { &dummy, &dummy, icmp_ping_of_death, 1, },
+#else
{ &dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
+#endif
{ &dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1, },
/* ECHO (8) */
{ &icmp_statistics[0].IcmpOutEchos, &icmp_statistics[0].IcmpInEchos, icmp_echo, 0, },
--- net/ipv4/sysctl_net_ipv4.c 2002/01/17 18:29:00 1.1
+++ net/ipv4/sysctl_net_ipv4.c 2002/12/19 00:11:58
@@ -22,6 +22,13 @@
extern int sysctl_icmp_echo_ignore_all;
extern int sysctl_icmp_echo_ignore_broadcasts;
extern int sysctl_icmp_ignore_bogus_error_responses;
+#ifdef CONFIG_ICMP_PINGOFDEATH
+extern int sysctl_ipod_version;
+extern int sysctl_ipod_enabled;
+extern u32 sysctl_ipod_host;
+extern u32 sysctl_ipod_mask;
+extern char sysctl_ipod_key[32+1];
+#endif
/* From ip_fragment.c */
extern int sysctl_ipfrag_low_thresh;
@@ -186,6 +193,18 @@
&sysctl_icmp_paramprob_time, sizeof(int), 0644, NULL, &proc_dointvec},
{NET_IPV4_ICMP_ECHOREPLY_RATE, "icmp_echoreply_rate",
&sysctl_icmp_echoreply_time, sizeof(int), 0644, NULL, &proc_dointvec},
+#ifdef CONFIG_ICMP_PINGOFDEATH
+ {NET_IPV4_ICMP_POD_ENABLED, "icmp_ipod_version",
+ &sysctl_ipod_version, sizeof(int), 0444, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_ENABLED, "icmp_ipod_enabled",
+ &sysctl_ipod_enabled, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_HOST, "icmp_ipod_host",
+ &sysctl_ipod_host, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_MASK, "icmp_ipod_mask",
+ &sysctl_ipod_mask, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_KEY, "icmp_ipod_key",
+ sysctl_ipod_key, sizeof(sysctl_ipod_key), 0600, NULL, &proc_dostring, &sysctl_string},
+#endif
{NET_IPV4_ROUTE, "route", NULL, 0, 0555, ipv4_route_table},
#ifdef CONFIG_IP_MULTICAST
{NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships",
--- include/linux/sysctl.h~ 2004-04-13 15:41:44.000000000 -0600
+++ include/linux/sysctl.h 2004-07-12 16:05:14.000000000 -0600
@@ -299,6 +299,13 @@
NET_TCP_FRTO=92,
NET_TCP_LOW_LATENCY=93,
NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
+
+ /* CONFIG_ICMP_PINGOFDEATH */
+ NET_IPV4_ICMP_POD_ENABLED=95,
+ NET_IPV4_ICMP_POD_HOST=96,
+ NET_IPV4_ICMP_POD_MASK=97,
+ NET_IPV4_ICMP_POD_KEY=98,
+ NET_IPV4_ICMP_POD_VERSION=99,
};
enum {
--- net/ipv4/Config.in~ 2001-12-21 10:42:05.000000000 -0700
+++ net/ipv4/Config.in 2004-07-12 16:06:56.000000000 -0600
@@ -44,3 +44,8 @@
if [ "$CONFIG_NETFILTER" != "n" ]; then
source net/ipv4/netfilter/Config.in
fi
+
+#
+# Emulab special
+#
+bool ' ICMP: ICMP Ping-of-Death (Emulab)' CONFIG_ICMP_PINGOFDEATH
--- net/ipv4/icmp.c~ 2004-04-13 15:07:12.000000000 -0600
+++ net/ipv4/icmp.c 2004-07-12 16:18:51.000000000 -0600
@@ -840,6 +840,67 @@
in_dev_put(in_dev);
}
+#ifdef CONFIG_ICMP_PINGOFDEATH
+#include <linux/reboot.h>
+
+int sysctl_ipod_version = 2;
+int sysctl_ipod_enabled = 0;
+u32 sysctl_ipod_host = 0xffffffff;
+u32 sysctl_ipod_mask = 0xffffffff;
+char sysctl_ipod_key[32+1] = { "SETMETOSOMETHINGTHIRTYTWOBYTES!!" };
+#define IPOD_CHECK_KEY \
+ (sysctl_ipod_key[0] != 0)
+#define IPOD_VALID_KEY(d) \
+ (strncmp(sysctl_ipod_key, (char *)(d), strlen(sysctl_ipod_key)) == 0)
+
+static void icmp_ping_of_death(struct sk_buff *skb)
+{
+ struct icmphdr *icmph = skb->h.icmph;
+ struct iphdr *iph = skb->nh.iph;
+ int doit = 0;
+
+#if 0
+ printk(KERN_INFO "IPOD: got type=6, code=%d, host=%u.%u.%u.%u\n", icmph->code, ntohs(iph->tot_len), NIPQUAD(iph->saddr));
+#endif
+
+ /*
+ * If IPOD not enabled or wrong ICMP code, ignore.
+ */
+ if (!sysctl_ipod_enabled || icmph->code != 6)
+ return;
+
+ /*
+ * First check the source address info.
+ * If host not set, ignore.
+ */
+ if (sysctl_ipod_host != 0xffffffff &&
+ (ntohl(iph->saddr) & sysctl_ipod_mask) == sysctl_ipod_host) {
+ /*
+ * Now check the key if enabled.
+ * If packet doesn't contain enough data or key
+ * is otherwise invalid, ignore.
+ */
+ if (IPOD_CHECK_KEY) {
+ if (pskb_may_pull(skb, sizeof(sysctl_ipod_key)-1) &&
+ IPOD_VALID_KEY(skb->data))
+ doit = 1;
+ } else {
+ doit = 1;
+ }
+ }
+
+ if (doit) {
+ sysctl_ipod_enabled = 0;
+ printk(KERN_CRIT "IPOD: reboot forced by %u.%u.%u.%u...\n",
+ NIPQUAD(iph->saddr));
+ machine_restart(NULL);
+ } else {
+ printk(KERN_WARNING "IPOD: from %u.%u.%u.%u rejected\n",
+ NIPQUAD(iph->saddr));
+ }
+}
+#endif
+
static void icmp_discard(struct sk_buff *skb)
{
}
8ics[0].IcmpOutSrcQuenchs, &icmp_statistics[0].IcmpInSrcQuenchs, icmp_unreach, 1 },
/* REDIRECT (5) */
{ &icmp_statistics[0].IcmpOutRedirects, &icmp_statistics[0].IcmpInRedirects, icmp_redirect, 1 },
+#ifdef CONFIG_ICMP_PINGOFDEATH
+/* PING_OF_DEATH (6) */
+ { &icmp_statistics[0].dummy, &icmp_statistics[0].dummy, icmp_ping_of_death, 1, },
+#else
{ &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1 },
+#endif
{ &icmp_statistics[0].dummy, &icmp_statistics[0].IcmpInErrors, icmp_discard, 1 },
/* ECHO (8) */
{ &icmp_statistics[0].IcmpOutEchos, &icmp_statistics[0].IcmpInEchos, icmp_echo, 0 },
--- net/ipv4/sysctl_net_ipv4.c~ 2004-04-13 15:07:14.000000000 -0600
+++ net/ipv4/sysctl_net_ipv4.c 2004-07-12 16:24:35.000000000 -0600
@@ -22,6 +22,13 @@
extern int sysctl_icmp_echo_ignore_all;
extern int sysctl_icmp_echo_ignore_broadcasts;
extern int sysctl_icmp_ignore_bogus_error_responses;
+#ifdef CONFIG_ICMP_PINGOFDEATH
+extern int sysctl_ipod_version;
+extern int sysctl_ipod_enabled;
+extern u32 sysctl_ipod_host;
+extern u32 sysctl_ipod_mask;
+extern char sysctl_ipod_key[32+1];
+#endif
/* From ip_fragment.c */
extern int sysctl_ipfrag_low_thresh;
@@ -177,6 +184,18 @@
{NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, "icmp_ignore_bogus_error_responses",
&sysctl_icmp_ignore_bogus_error_responses, sizeof(int), 0644, NULL,
&proc_dointvec},
+#ifdef CONFIG_ICMP_PINGOFDEATH
+ {NET_IPV4_ICMP_POD_ENABLED, "icmp_ipod_version",
+ &sysctl_ipod_version, sizeof(int), 0444, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_ENABLED, "icmp_ipod_enabled",
+ &sysctl_ipod_enabled, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_HOST, "icmp_ipod_host",
+ &sysctl_ipod_host, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_MASK, "icmp_ipod_mask",
+ &sysctl_ipod_mask, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_KEY, "icmp_ipod_key",
+ sysctl_ipod_key, sizeof(sysctl_ipod_key), 0600, NULL, &proc_dostring, &sysctl_string},
+#endif
{NET_IPV4_ROUTE, "route", NULL, 0, 0555, ipv4_route_table},
#ifdef CONFIG_IP_MULTICAST
{NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships",
diff -ur linux-2.6.11-orig/include/linux/sysctl.h linux-2.6.11/include/linux/sysctl.h
--- linux-2.6.11-orig/include/linux/sysctl.h 2005-06-17 15:06:02.000000000 -0600
+++ linux-2.6.11/include/linux/sysctl.h 2005-06-21 17:28:31.000000000 -0600
@@ -350,6 +350,13 @@
NET_TCP_MODERATE_RCVBUF=106,
NET_TCP_TSO_WIN_DIVISOR=107,
NET_TCP_BIC_BETA=108,
+
+ /* CONFIG_ICMP_PINGOFDEATH */
+ NET_IPV4_ICMP_POD_ENABLED=109,
+ NET_IPV4_ICMP_POD_HOST=110,
+ NET_IPV4_ICMP_POD_MASK=111,
+ NET_IPV4_ICMP_POD_KEY=112,
+ NET_IPV4_ICMP_POD_VERSION=113,
};
enum {
diff -ur linux-2.6.11-orig/net/ipv4/Kconfig linux-2.6.11/net/ipv4/Kconfig
--- linux-2.6.11-orig/net/ipv4/Kconfig 2005-06-17 15:06:01.000000000 -0600
+++ linux-2.6.11/net/ipv4/Kconfig 2005-06-22 15:21:33.000000000 -0600
@@ -407,5 +407,11 @@
config IP_TCPDIAG_IPV6
def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6)
+#
+# Emulab special
+#
+config ICMP_PINGOFDEATH
+ bool "ICMP: ICMP Ping-of-Death (Emulab)"
+
source "net/ipv4/ipvs/Kconfig"
diff -ur linux-2.6.11-orig/net/ipv4/icmp.c linux-2.6.11/net/ipv4/icmp.c
--- linux-2.6.11-orig/net/ipv4/icmp.c 2005-06-17 15:06:01.000000000 -0600
+++ linux-2.6.11/net/ipv4/icmp.c 2005-06-22 15:29:10.000000000 -0600
@@ -913,6 +913,67 @@
out:;
}
+#ifdef CONFIG_ICMP_PINGOFDEATH
+#include <linux/reboot.h>
+
+int sysctl_ipod_version = 2;
+int sysctl_ipod_enabled = 0;
+u32 sysctl_ipod_host = 0xffffffff;
+u32 sysctl_ipod_mask = 0xffffffff;
+char sysctl_ipod_key[32+1] = { "SETMETOSOMETHINGTHIRTYTWOBYTES!!" };
+#define IPOD_CHECK_KEY \
+ (sysctl_ipod_key[0] != 0)
+#define IPOD_VALID_KEY(d) \
+ (strncmp(sysctl_ipod_key, (char *)(d), strlen(sysctl_ipod_key)) == 0)
+
+static void icmp_ping_of_death(struct sk_buff *skb)
+{
+ struct icmphdr *icmph = skb->h.icmph;
+ struct iphdr *iph = skb->nh.iph;
+ int doit = 0;
+
+#if 0
+ printk(KERN_INFO "IPOD: got type=6, code=%d, host=%u.%u.%u.%u\n", icmph->code, ntohs(iph->tot_len), NIPQUAD(iph->saddr));
+#endif
+
+ /*
+ * If IPOD not enabled or wrong ICMP code, ignore.
+ */
+ if (!sysctl_ipod_enabled || icmph->code != 6)
+ return;
+
+ /*
+ * First check the source address info.
+ * If host not set, ignore.
+ */
+ if (sysctl_ipod_host != 0xffffffff &&
+ (ntohl(iph->saddr) & sysctl_ipod_mask) == sysctl_ipod_host) {
+ /*
+ * Now check the key if enabled.
+ * If packet doesn't contain enough data or key
+ * is otherwise invalid, ignore.
+ */
+ if (IPOD_CHECK_KEY) {
+ if (pskb_may_pull(skb, sizeof(sysctl_ipod_key)-1) &&
+ IPOD_VALID_KEY(skb->data))
+ doit = 1;
+ } else {
+ doit = 1;
+ }
+ }
+
+ if (doit) {
+ sysctl_ipod_enabled = 0;
+ printk(KERN_CRIT "IPOD: reboot forced by %u.%u.%u.%u...\n",
+ NIPQUAD(iph->saddr));
+ machine_restart(NULL);
+ } else {
+ printk(KERN_WARNING "IPOD: from %u.%u.%u.%u rejected\n",
+ NIPQUAD(iph->saddr));
+ }
+}
+#endif
+
static void icmp_discard(struct sk_buff *skb)
{
}
@@ -1027,12 +1088,22 @@
.handler = icmp_redirect,
.error = 1,
},
+#ifdef CONFIG_ICMP_PINGOFDEATH
+ /* PING_OF_DEATH (6) */
+ [6] = {
+ .output_entry = ICMP_MIB_DUMMY,
+ .input_entry = ICMP_MIB_DUMMY,
+ .handler = icmp_ping_of_death,
+ .error = 1,
+ },
+#else
[6] = {
.output_entry = ICMP_MIB_DUMMY,
.input_entry = ICMP_MIB_INERRORS,
.handler = icmp_discard,
.error = 1,
},
+#endif
[7] = {
.output_entry = ICMP_MIB_DUMMY,
.input_entry = ICMP_MIB_INERRORS,
diff -ur linux-2.6.11-orig/net/ipv4/sysctl_net_ipv4.c linux-2.6.11/net/ipv4/sysctl_net_ipv4.c
--- linux-2.6.11-orig/net/ipv4/sysctl_net_ipv4.c 2005-03-02 00:38:17.000000000 -0700
+++ linux-2.6.11/net/ipv4/sysctl_net_ipv4.c 2005-06-21 17:38:50.000000000 -0600
@@ -23,6 +23,13 @@
extern int sysctl_icmp_echo_ignore_all;
extern int sysctl_icmp_echo_ignore_broadcasts;
extern int sysctl_icmp_ignore_bogus_error_responses;
+#ifdef CONFIG_ICMP_PINGOFDEATH
+extern int sysctl_ipod_version;
+extern int sysctl_ipod_enabled;
+extern u32 sysctl_ipod_host;
+extern u32 sysctl_ipod_mask;
+extern char sysctl_ipod_key[32+1];
+#endif
/* From ip_fragment.c */
extern int sysctl_ipfrag_low_thresh;
@@ -690,6 +697,18 @@
.mode = 0644,
.proc_handler = &proc_dointvec,
},
+#ifdef CONFIG_ICMP_PINGOFDEATH
+ {NET_IPV4_ICMP_POD_ENABLED, "icmp_ipod_version",
+ &sysctl_ipod_version, sizeof(int), 0444, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_ENABLED, "icmp_ipod_enabled",
+ &sysctl_ipod_enabled, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_HOST, "icmp_ipod_host",
+ &sysctl_ipod_host, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_MASK, "icmp_ipod_mask",
+ &sysctl_ipod_mask, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_IPV4_ICMP_POD_KEY, "icmp_ipod_key",
+ sysctl_ipod_key, sizeof(sysctl_ipod_key), 0600, NULL, &proc_dostring, &sysctl_string},
+#endif
{ .ctl_name = 0 }
};
diff -ur linux-2.6.12-1.1387_FC4/include/linux/sysctl.h linux-2.6.12/include/linux/sysctl.h
--- linux-2.6.12-1.1387_FC4/include/linux/sysctl.h 2005-07-12 01:00:08.000000000 -0600
+++ linux-2.6.12/include/linux/sysctl.h 2005-07-06 11:25:25.000000000 -0600
@@ -351,6 +351,13 @@
NET_TCP_TSO_WIN_DIVISOR=107,
NET_TCP_BIC_BETA=108,
NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
+
+ /* CONFIG_ICMP_PINGOFDEATH */
+ NET_IPV4_ICMP_POD_ENABLED=110,
+ NET_IPV4_ICMP_POD_HOST=111,
+ NET_IPV4_ICMP_POD_MASK=112,
+ NET_IPV4_ICMP_POD_KEY=113,
+ NET_IPV4_ICMP_POD_VERSION=114,
};
enum {
diff -ur linux-2.6.12-1.1387_FC4/net/ipv4/Kconfig linux-2.6.12/net/ipv4/Kconfig
--- linux-2.6.12-1.1387_FC4/net/ipv4/Kconfig 2005-06-17 13:48:29.000000000 -0600
+++ linux-2.6.12/net/ipv4/Kconfig 2005-07-06 11:22:48.000000000 -0600
@@ -407,5 +407,11 @@
config IP_TCPDIAG_IPV6
def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6)
+#
+# Emulab special
+#
+config ICMP_PINGOFDEATH
+ bool "ICMP: ICMP Ping-of-Death (Emulab)"
+
source "net/ipv4/ipvs/Kconfig"
diff -ur linux-2.6.12-1.1387_FC4/net/ipv4/icmp.c linux-2.6.12/net/ipv4/icmp.c
--- linux-2.6.12-1.1387_FC4/net/ipv4/icmp.c 2005-06-17 13:48:29.000000000 -0600
+++ linux-2.6.12/net/ipv4/icmp.c 2005-07-06 11:22:48.000000000 -0600
@@ -918,6 +918,67 @@
out:;
}
+#ifdef CONFIG_ICMP_PINGOFDEATH
+#include <linux/reboot.h>
+
+int sysctl_ipod_version = 2;
+int sysctl_ipod_enabled = 0;
+u32 sysctl_ipod_host = 0xffffffff;
+u32 sysctl_ipod_mask = 0xffffffff;
+char sysctl_ipod_key[32+1] = { "SETMETOSOMETHINGTHIRTYTWOBYTES!!" };
+#define IPOD_CHECK_KEY \
+ (sysctl_ipod_key[0] != 0)
+#define IPOD_VALID_KEY(d) \
+ (strncmp(sysctl_ipod_key, (char *)(d), strlen(sysctl_ipod_key)) == 0)
+
+static void icmp_ping_of_death(struct sk_buff *skb)
+{
+ struct icmphdr *icmph = skb->h.icmph;
+ struct iphdr *iph = skb->nh.iph;
+ int doit = 0;
+
+#if 0
+ printk(KERN_INFO "IPOD: got type=6, code=%d, host=%u.%u.%u.%u\n", icmph->code, ntohs(iph->tot_len), NIPQUAD(iph->saddr));
+#endif
+
+ /*
+ * If IPOD not enabled or wrong ICMP code, ignore.
+ */
+ if (!sysctl_ipod_enabled || icmph->code != 6)
+ return;
+
+ /*
+ * First check the source address info.
+ * If host not set, ignore.
+ */
+ if (sysctl_ipod_host != 0xffffffff &&
+ (ntohl(iph->saddr) & sysctl_ipod_mask) == sysctl_ipod_host) {
+ /*
+ * Now check the key if enabled.