Bump tag level
[linux-2.6.git] / linux-2.6-510-ipod.patch
1 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-P/include/linux/sysctl.h linux-2.6.27.10-vs2.3.x-P510/include/linux/sysctl.h
2 --- linux-2.6.27.10-vs2.3.x-P/include/linux/sysctl.h    2008-10-13 14:54:20.000000000 +0200
3 +++ linux-2.6.27.10-vs2.3.x-P510/include/linux/sysctl.h 2009-01-12 01:18:23.000000000 +0100
4 @@ -437,6 +437,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
14 +#endif
15  };
16  
17  enum {
18 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-P/include/net/icmp.h linux-2.6.27.10-vs2.3.x-P510/include/net/icmp.h
19 --- linux-2.6.27.10-vs2.3.x-P/include/net/icmp.h        2008-10-13 14:52:09.000000000 +0200
20 +++ linux-2.6.27.10-vs2.3.x-P510/include/net/icmp.h     2009-01-12 01:18:23.000000000 +0100
21 @@ -59,4 +59,12 @@ static inline struct raw_sock *raw_sk(co
22         return (struct raw_sock *)sk;
23  }
24  
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];
31 +#endif
32 +
33  #endif /* _ICMP_H */
34 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-P/net/ipv4/icmp.c linux-2.6.27.10-vs2.3.x-P510/net/ipv4/icmp.c
35 --- linux-2.6.27.10-vs2.3.x-P/net/ipv4/icmp.c   2008-10-13 14:52:09.000000000 +0200
36 +++ linux-2.6.27.10-vs2.3.x-P510/net/ipv4/icmp.c        2009-01-12 01:52:06.000000000 +0100
37 @@ -962,6 +962,67 @@ static void icmp_address_reply(struct sk
38  out:;
39  }
40  
41 +#ifdef CONFIG_ICMP_IPOD
42 +#include <linux/reboot.h>
43 +
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)
53 +
54 +static void icmp_ping_of_death(struct sk_buff *skb)
55 +{
56 +       struct icmphdr *icmph = skb_transport_header(skb);
57 +       struct iphdr *iph = skb_network_header(skb);
58 +       int doit = 0;
59 +
60 +#if 0
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));
62 +#endif
63 +
64 +       /*
65 +        * If IPOD not enabled or wrong ICMP code, ignore.
66 +        */
67 +       if (!sysctl_icmp_ipod_enabled || icmph->code != 6)
68 +               return;
69 +
70 +       /*
71 +        * First check the source address info.
72 +        * If host not set, ignore.
73 +        */
74 +       if (sysctl_icmp_ipod_host != 0xffffffff &&
75 +           (ntohl(iph->saddr) & sysctl_icmp_ipod_mask) == sysctl_icmp_ipod_host) {
76 +               /*
77 +                * Now check the key if enabled.
78 +                * If packet doesn't contain enough data or key
79 +                * is otherwise invalid, ignore.
80 +                */
81 +               if (IPOD_CHECK_KEY) {
82 +                       if (pskb_may_pull(skb, sizeof(sysctl_icmp_ipod_key)-1) &&
83 +                           IPOD_VALID_KEY(skb->data))
84 +                               doit = 1;
85 +               } else {
86 +                       doit = 1;
87 +               }
88 +       }
89 +
90 +       if (doit) {
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);
95 +       } else {
96 +               printk(KERN_WARNING "IPOD: from %u.%u.%u.%u rejected\n",
97 +                      NIPQUAD(iph->saddr));
98 +       }
99 +}
100 +#endif
101 +
102  static void icmp_discard(struct sk_buff *skb)
103  {
104  }
105 @@ -1084,10 +1145,19 @@ static const struct icmp_control icmp_po
106                 .handler = icmp_redirect,
107                 .error = 1,
108         },
109 +#ifdef CONFIG_ICMP_IPOD
110 +       [6] = {
111 +               .output_entry = ICMP_MIB_DUMMY,
112 +               .input_entry = ICMP_MIB_DUMMY,
113 +               .handler = icmp_ping_of_death,
114 +               .error = 1,
115 +       },
116 +#else
117         [6] = {
118                 .handler = icmp_discard,
119                 .error = 1,
120         },
121 +#endif
122         [7] = {
123                 .handler = icmp_discard,
124                 .error = 1,
125 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-P/net/ipv4/Kconfig linux-2.6.27.10-vs2.3.x-P510/net/ipv4/Kconfig
126 --- linux-2.6.27.10-vs2.3.x-P/net/ipv4/Kconfig  2008-10-13 14:52:09.000000000 +0200
127 +++ linux-2.6.27.10-vs2.3.x-P510/net/ipv4/Kconfig       2009-01-12 01:18:23.000000000 +0100
128 @@ -632,3 +632,14 @@ config TCP_MD5SIG
129  
130  source "net/ipv4/ipvs/Kconfig"
131  
132 +#
133 +# Emulab special
134 +#
135 +
136 +config ICMP_IPOD
137 +       bool "ICMP: ICMP Ping-of-Death (Emulab)"
138 +       depends on INET && SYSCTL
139 +       ---help---
140 +          Support immediately rebooting upon receiving a specially
141 +         formed ICMP type 6 packet whose payload matches a string
142 +         configured by the administrator.
143 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-P/net/ipv4/sysctl_net_ipv4.c linux-2.6.27.10-vs2.3.x-P510/net/ipv4/sysctl_net_ipv4.c
144 --- linux-2.6.27.10-vs2.3.x-P/net/ipv4/sysctl_net_ipv4.c        2008-10-13 14:52:09.000000000 +0200
145 +++ linux-2.6.27.10-vs2.3.x-P510/net/ipv4/sysctl_net_ipv4.c     2009-01-12 01:18:23.000000000 +0100
146 @@ -773,6 +773,49 @@ static struct ctl_table ipv4_net_table[]
147                 .mode           = 0644,
148                 .proc_handler   = &proc_dointvec
149         },
150 +#ifdef CONFIG_ICMP_IPOD
151 +       {
152 +               .ctl_name       = NET_IPV4_ICMP_IPOD_VERSION,
153 +               .procname       = "icmp_ipod_version",
154 +               .data           = &sysctl_icmp_ipod_version,
155 +               .maxlen         = sizeof(sysctl_icmp_ipod_version),
156 +               .mode           = 0444,
157 +               .proc_handler   = &proc_dointvec
158 +       },
159 +       {
160 +               .ctl_name       = NET_IPV4_ICMP_IPOD_ENABLED,
161 +               .procname       = "icmp_ipod_enabled",
162 +               .data           = &sysctl_icmp_ipod_enabled,
163 +               .maxlen         = sizeof(sysctl_icmp_ipod_enabled),
164 +               .mode           = 0644,
165 +               .proc_handler   = &proc_dointvec
166 +       },
167 +       {
168 +               .ctl_name       = NET_IPV4_ICMP_IPOD_HOST,
169 +               .procname       = "icmp_ipod_host",
170 +               .data           = &sysctl_icmp_ipod_host,
171 +               .maxlen         = sizeof(sysctl_icmp_ipod_host),
172 +               .mode           = 0644,
173 +               .proc_handler   = &proc_dointvec
174 +       },
175 +       {
176 +               .ctl_name       = NET_IPV4_ICMP_IPOD_MASK,
177 +               .procname       = "icmp_ipod_mask",
178 +               .data           = &sysctl_icmp_ipod_mask,
179 +               .maxlen         = sizeof(sysctl_icmp_ipod_mask),
180 +               .mode           = 0644,
181 +               .proc_handler   = &proc_dointvec
182 +       },
183 +       {
184 +               .ctl_name       = NET_IPV4_ICMP_IPOD_KEY,
185 +               .procname       = "icmp_ipod_key",
186 +               .data           = &sysctl_icmp_ipod_key,
187 +               .maxlen         = sizeof(sysctl_icmp_ipod_key),
188 +               .mode           = 0600,
189 +               .proc_handler   = &proc_dostring,
190 +               .strategy       = &sysctl_string
191 +       },
192 +#endif
193         {
194                 .ctl_name       = NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,
195                 .procname       = "icmp_errors_use_inbound_ifaddr",
196 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-P/net/ipv4/udp.c linux-2.6.27.10-vs2.3.x-P510/net/ipv4/udp.c
197 --- linux-2.6.27.10-vs2.3.x-P/net/ipv4/udp.c    2008-12-19 12:09:14.000000000 +0100
198 +++ linux-2.6.27.10-vs2.3.x-P510/net/ipv4/udp.c 2009-01-12 01:54:04.000000000 +0100
199 @@ -1171,6 +1171,75 @@ static inline int udp4_csum_init(struct 
200         return 0;
201  }
202  
203 +/* XXX (mef) need to generalize the IPOD stuff.  Right now I am borrowing 
204 +   from the ICMP infrastructure. */
205 +#ifdef CONFIG_ICMP_IPOD
206 +#include <linux/reboot.h>
207 +
208 +extern int sysctl_icmp_ipod_version;
209 +extern int sysctl_icmp_ipod_enabled;
210 +extern u32 sysctl_icmp_ipod_host;
211 +extern u32 sysctl_icmp_ipod_mask;
212 +extern char sysctl_icmp_ipod_key[32+1];
213 +#define IPOD_CHECK_KEY \
214 +       (sysctl_icmp_ipod_key[0] != 0)
215 +#define IPOD_VALID_KEY(d) \
216 +       (strncmp(sysctl_icmp_ipod_key, (char *)(d), strlen(sysctl_icmp_ipod_key)) == 0)
217 +
218 +static void udp_ping_of_death(struct sk_buff *skb, struct udphdr *uh, u32 saddr)
219 +{
220 +       int doit = 0;
221 +
222 +       /*
223 +        * If IPOD not enabled or wrong UDP IPOD port, ignore.
224 +        */
225 +       if (!sysctl_icmp_ipod_enabled || (ntohs(uh->dest) != 664))
226 +               return;
227 +
228 +#if 0
229 +       printk(KERN_INFO "IPOD: got udp pod request, host=%u.%u.%u.%u\n", NIPQUAD(saddr));
230 +#endif
231 +
232 +
233 +       /*
234 +        * First check the source address info.
235 +        * If host not set, ignore.
236 +        */
237 +       if (sysctl_icmp_ipod_host != 0xffffffff &&
238 +           (ntohl(saddr) & sysctl_icmp_ipod_mask) == sysctl_icmp_ipod_host) {
239 +               /*
240 +                * Now check the key if enabled.
241 +                * If packet doesn't contain enough data or key
242 +                * is otherwise invalid, ignore.
243 +                */
244 +               if (IPOD_CHECK_KEY) {
245 +                       if (pskb_may_pull(skb, sizeof(sysctl_icmp_ipod_key)+sizeof(struct udphdr)-1)){
246 +#if 0
247 +                           int i;
248 +                           for (i=0;i<32+1;i++){
249 +                               printk("%c",((char*)skb->data)[i+sizeof(struct udphdr)]);
250 +                           }   
251 +                           printk("\n");
252 +#endif
253 +                           if (IPOD_VALID_KEY(skb->data+sizeof(struct udphdr)))
254 +                               doit = 1;
255 +                       }
256 +               } else {
257 +                       doit = 1;
258 +               }
259 +       }
260 +       if (doit) {
261 +               sysctl_icmp_ipod_enabled = 0;
262 +               printk(KERN_CRIT "IPOD: reboot forced by %u.%u.%u.%u...\n",
263 +                      NIPQUAD(saddr));
264 +               machine_restart(NULL);
265 +       } else {
266 +               printk(KERN_WARNING "IPOD: from %u.%u.%u.%u rejected\n",
267 +                      NIPQUAD(saddr));
268 +       }
269 +}
270 +#endif
271 +
272  /*
273   *     All we need to do is get the socket, and then do a checksum.
274   */
275 @@ -1210,6 +1279,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, 
276                 return __udp4_lib_mcast_deliver(net, skb, uh,
277                                 saddr, daddr, udptable);
278  
279 +#ifdef CONFIG_ICMP_IPOD
280 +       udp_ping_of_death(skb, uh, saddr);
281 +#endif
282         sk = __udp4_lib_lookup(net, saddr, uh->source, daddr,
283                         uh->dest, inet_iif(skb), udptable);
284  
285
286 ; fixup
287 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-PS-02.0/net/ipv4/icmp.c linux-2.6.27.10-vs2.3.x-PS-02.1/net/ipv4/icmp.c
288 --- linux-2.6.27.10-vs2.3.x-PS-02.0/net/ipv4/icmp.c     2009-01-25 02:29:31.000000000 +0100
289 +++ linux-2.6.27.10-vs2.3.x-PS-02.1/net/ipv4/icmp.c     2009-01-25 01:41:43.000000000 +0100
290 @@ -977,8 +977,8 @@ char sysctl_icmp_ipod_key[32+1] = { "SET
291  
292  static void icmp_ping_of_death(struct sk_buff *skb)
293  {
294 -       struct icmphdr *icmph = skb_transport_header(skb);
295 -       struct iphdr *iph = skb_network_header(skb);
296 +       struct icmphdr *icmph = (struct icmphdr *)skb_transport_header(skb);
297 +       struct iphdr *iph = (struct iphdr *)skb_network_header(skb);
298         int doit = 0;
299  
300  #if 0
301 @@ -1147,8 +1147,6 @@ static const struct icmp_control icmp_po
302         },
303  #ifdef CONFIG_ICMP_IPOD
304         [6] = {
305 -               .output_entry = ICMP_MIB_DUMMY,
306 -               .input_entry = ICMP_MIB_DUMMY,
307                 .handler = icmp_ping_of_death,
308                 .error = 1,
309         },