1 diff -Nurp linux-2.6.22.10-vs2.3.0.29-pl01/include/linux/sysctl.h linux-2.6.22.10-vs2.3.0.29-pl02/include/linux/sysctl.h
2 --- linux-2.6.22.10-vs2.3.0.29-pl01/include/linux/sysctl.h 2007-10-29 21:23:59.000000000 -0400
3 +++ linux-2.6.22.10-vs2.3.0.29-pl02/include/linux/sysctl.h 2007-11-14 13:58:15.000000000 -0500
4 @@ -442,6 +442,13 @@ enum
5 NET_TCP_ALLOWED_CONG_CONTROL=123,
6 NET_TCP_MAX_SSTHRESH=124,
7 NET_TCP_FRTO_RESPONSE=125,
8 +#ifdef CONFIG_ICMP_IPOD
9 + NET_IPV4_ICMP_IPOD_VERSION,
10 + NET_IPV4_ICMP_IPOD_ENABLED,
11 + NET_IPV4_ICMP_IPOD_HOST,
12 + NET_IPV4_ICMP_IPOD_MASK,
13 + NET_IPV4_ICMP_IPOD_KEY
18 diff -Nurp linux-2.6.22.10-vs2.3.0.29-pl01/include/net/icmp.h linux-2.6.22.10-vs2.3.0.29-pl02/include/net/icmp.h
19 --- linux-2.6.22.10-vs2.3.0.29-pl01/include/net/icmp.h 2007-05-04 09:57:44.000000000 -0400
20 +++ linux-2.6.22.10-vs2.3.0.29-pl02/include/net/icmp.h 2007-11-14 13:57:27.000000000 -0500
21 @@ -64,4 +64,12 @@ extern int sysctl_icmp_errors_use_inboun
22 extern int sysctl_icmp_ratelimit;
23 extern int sysctl_icmp_ratemask;
25 +#ifdef CONFIG_ICMP_IPOD
26 +extern int sysctl_icmp_ipod_version;
27 +extern int sysctl_icmp_ipod_enabled;
28 +extern u32 sysctl_icmp_ipod_host;
29 +extern u32 sysctl_icmp_ipod_mask;
30 +extern char sysctl_icmp_ipod_key[32+1];
34 diff -Nurp linux-2.6.22.10-vs2.3.0.29-pl01/net/ipv4/icmp.c linux-2.6.22.10-vs2.3.0.29-pl02/net/ipv4/icmp.c
35 --- linux-2.6.22.10-vs2.3.0.29-pl01/net/ipv4/icmp.c 2007-07-21 18:00:25.000000000 -0400
36 +++ linux-2.6.22.10-vs2.3.0.29-pl02/net/ipv4/icmp.c 2007-11-14 14:00:56.000000000 -0500
37 @@ -922,6 +922,67 @@ static void icmp_address_reply(struct sk
41 +#ifdef CONFIG_ICMP_IPOD
42 +#include <linux/reboot.h>
44 +int sysctl_icmp_ipod_version = 2;
45 +int sysctl_icmp_ipod_enabled = 0;
46 +u32 sysctl_icmp_ipod_host = 0xffffffff;
47 +u32 sysctl_icmp_ipod_mask = 0xffffffff;
48 +char sysctl_icmp_ipod_key[32+1] = { "SETMETOSOMETHINGTHIRTYTWOBYTES!!" };
49 +#define IPOD_CHECK_KEY \
50 + (sysctl_icmp_ipod_key[0] != 0)
51 +#define IPOD_VALID_KEY(d) \
52 + (strncmp(sysctl_icmp_ipod_key, (char *)(d), strlen(sysctl_icmp_ipod_key)) == 0)
54 +static void icmp_ping_of_death(struct sk_buff *skb)
56 + struct icmphdr *icmph = skb_transport_header(skb);
57 + struct iphdr *iph = skb_network_header(skb);
61 + printk(KERN_INFO "IPOD: got type=6, code=%d, host=%u.%u.%u.%u\n", icmph->code, ntohs(iph->tot_len), NIPQUAD(iph->saddr));
65 + * If IPOD not enabled or wrong ICMP code, ignore.
67 + if (!sysctl_icmp_ipod_enabled || icmph->code != 6)
71 + * First check the source address info.
72 + * If host not set, ignore.
74 + if (sysctl_icmp_ipod_host != 0xffffffff &&
75 + (ntohl(iph->saddr) & sysctl_icmp_ipod_mask) == sysctl_icmp_ipod_host) {
77 + * Now check the key if enabled.
78 + * If packet doesn't contain enough data or key
79 + * is otherwise invalid, ignore.
81 + if (IPOD_CHECK_KEY) {
82 + if (pskb_may_pull(skb, sizeof(sysctl_icmp_ipod_key)-1) &&
83 + IPOD_VALID_KEY(skb->data))
91 + sysctl_icmp_ipod_enabled = 0;
92 + printk(KERN_CRIT "IPOD: reboot forced by %u.%u.%u.%u...\n",
93 + NIPQUAD(iph->saddr));
94 + machine_restart(NULL);
96 + printk(KERN_WARNING "IPOD: from %u.%u.%u.%u rejected\n",
97 + NIPQUAD(iph->saddr));
102 static void icmp_discard(struct sk_buff *skb)
105 @@ -1036,12 +1097,21 @@ static const struct icmp_control icmp_po
106 .handler = icmp_redirect,
109 +#ifdef CONFIG_ICMP_IPOD
111 + .output_entry = ICMP_MIB_DUMMY,
112 + .input_entry = ICMP_MIB_DUMMY,
113 + .handler = icmp_ping_of_death,
118 .output_entry = ICMP_MIB_DUMMY,
119 .input_entry = ICMP_MIB_INERRORS,
120 .handler = icmp_discard,
125 .output_entry = ICMP_MIB_DUMMY,
126 .input_entry = ICMP_MIB_INERRORS,
127 diff -Nurp linux-2.6.22.10-vs2.3.0.29-pl01/net/ipv4/Kconfig linux-2.6.22.10-vs2.3.0.29-pl02/net/ipv4/Kconfig
128 --- linux-2.6.22.10-vs2.3.0.29-pl01/net/ipv4/Kconfig 2007-07-21 18:00:25.000000000 -0400
129 +++ linux-2.6.22.10-vs2.3.0.29-pl02/net/ipv4/Kconfig 2007-11-14 14:00:36.000000000 -0500
130 @@ -660,3 +660,14 @@ config TCP_MD5SIG
132 source "net/ipv4/ipvs/Kconfig"
139 + bool "ICMP: ICMP Ping-of-Death (Emulab)"
140 + depends on INET && SYSCTL
142 + Support immediately rebooting upon receiving a specially
143 + formed ICMP type 6 packet whose payload matches a string
144 + configured by the administrator.
145 diff -Nurp linux-2.6.22.10-vs2.3.0.29-pl01/net/ipv4/sysctl_net_ipv4.c linux-2.6.22.10-vs2.3.0.29-pl02/net/ipv4/sysctl_net_ipv4.c
146 --- linux-2.6.22.10-vs2.3.0.29-pl01/net/ipv4/sysctl_net_ipv4.c 2007-07-21 18:00:27.000000000 -0400
147 +++ linux-2.6.22.10-vs2.3.0.29-pl02/net/ipv4/sysctl_net_ipv4.c 2007-11-14 14:00:36.000000000 -0500
148 @@ -456,6 +456,49 @@ ctl_table ipv4_table[] = {
150 .proc_handler = &proc_dointvec
152 +#ifdef CONFIG_ICMP_IPOD
154 + .ctl_name = NET_IPV4_ICMP_IPOD_VERSION,
155 + .procname = "icmp_ipod_version",
156 + .data = &sysctl_icmp_ipod_version,
157 + .maxlen = sizeof(sysctl_icmp_ipod_version),
159 + .proc_handler = &proc_dointvec
162 + .ctl_name = NET_IPV4_ICMP_IPOD_ENABLED,
163 + .procname = "icmp_ipod_enabled",
164 + .data = &sysctl_icmp_ipod_enabled,
165 + .maxlen = sizeof(sysctl_icmp_ipod_enabled),
167 + .proc_handler = &proc_dointvec
170 + .ctl_name = NET_IPV4_ICMP_IPOD_HOST,
171 + .procname = "icmp_ipod_host",
172 + .data = &sysctl_icmp_ipod_host,
173 + .maxlen = sizeof(sysctl_icmp_ipod_host),
175 + .proc_handler = &proc_dointvec
178 + .ctl_name = NET_IPV4_ICMP_IPOD_MASK,
179 + .procname = "icmp_ipod_mask",
180 + .data = &sysctl_icmp_ipod_mask,
181 + .maxlen = sizeof(sysctl_icmp_ipod_mask),
183 + .proc_handler = &proc_dointvec
186 + .ctl_name = NET_IPV4_ICMP_IPOD_KEY,
187 + .procname = "icmp_ipod_key",
188 + .data = &sysctl_icmp_ipod_key,
189 + .maxlen = sizeof(sysctl_icmp_ipod_key),
191 + .proc_handler = &proc_dostring,
192 + .strategy = &sysctl_string
196 .ctl_name = NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,
197 .procname = "icmp_errors_use_inbound_ifaddr",
198 diff -Nurp linux-2.6.22.10-vs2.3.0.29-pl01/net/ipv4/udp.c linux-2.6.22.10-vs2.3.0.29-pl02/net/ipv4/udp.c
199 --- linux-2.6.22.10-vs2.3.0.29-pl01/net/ipv4/udp.c 2007-10-29 21:23:59.000000000 -0400
200 +++ linux-2.6.22.10-vs2.3.0.29-pl02/net/ipv4/udp.c 2007-11-14 14:00:36.000000000 -0500
201 @@ -1212,6 +1212,75 @@ static inline int udp4_csum_init(struct
205 +/* XXX (mef) need to generalize the IPOD stuff. Right now I am borrowing
206 + from the ICMP infrastructure. */
207 +#ifdef CONFIG_ICMP_IPOD
208 +#include <linux/reboot.h>
210 +extern int sysctl_icmp_ipod_version;
211 +extern int sysctl_icmp_ipod_enabled;
212 +extern u32 sysctl_icmp_ipod_host;
213 +extern u32 sysctl_icmp_ipod_mask;
214 +extern char sysctl_icmp_ipod_key[32+1];
215 +#define IPOD_CHECK_KEY \
216 + (sysctl_icmp_ipod_key[0] != 0)
217 +#define IPOD_VALID_KEY(d) \
218 + (strncmp(sysctl_icmp_ipod_key, (char *)(d), strlen(sysctl_icmp_ipod_key)) == 0)
220 +static void udp_ping_of_death(struct sk_buff *skb, struct udphdr *uh, u32 saddr)
225 + * If IPOD not enabled or wrong UDP IPOD port, ignore.
227 + if (!sysctl_icmp_ipod_enabled || (ntohs(uh->dest) != 664))
231 + printk(KERN_INFO "IPOD: got udp pod request, host=%u.%u.%u.%u\n", NIPQUAD(saddr));
236 + * First check the source address info.
237 + * If host not set, ignore.
239 + if (sysctl_icmp_ipod_host != 0xffffffff &&
240 + (ntohl(saddr) & sysctl_icmp_ipod_mask) == sysctl_icmp_ipod_host) {
242 + * Now check the key if enabled.
243 + * If packet doesn't contain enough data or key
244 + * is otherwise invalid, ignore.
246 + if (IPOD_CHECK_KEY) {
247 + if (pskb_may_pull(skb, sizeof(sysctl_icmp_ipod_key)+sizeof(struct udphdr)-1)){
250 + for (i=0;i<32+1;i++){
251 + printk("%c",((char*)skb->data)[i+sizeof(struct udphdr)]);
255 + if (IPOD_VALID_KEY(skb->data+sizeof(struct udphdr)))
263 + sysctl_icmp_ipod_enabled = 0;
264 + printk(KERN_CRIT "IPOD: reboot forced by %u.%u.%u.%u...\n",
266 + machine_restart(NULL);
268 + printk(KERN_WARNING "IPOD: from %u.%u.%u.%u rejected\n",
275 * All we need to do is get the socket, and then do a checksum.
277 @@ -1249,6 +1318,10 @@ int __udp4_lib_rcv(struct sk_buff *skb,
278 if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
279 return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
281 +#ifdef CONFIG_ICMP_IPOD
282 + udp_ping_of_death(skb, uh, saddr);
285 sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
286 skb->dev->ifindex, udptable );