return 0;
}
+/* XXX (mef) need to generalize the IPOD stuff. Right now I am borrowing
+ from the ICMP infrastructure. */
+#ifdef CONFIG_ICMP_IPOD
+#include <linux/reboot.h>
+
+extern int sysctl_icmp_ipod_version;
+extern int sysctl_icmp_ipod_enabled;
+extern u32 sysctl_icmp_ipod_host;
+extern u32 sysctl_icmp_ipod_mask;
+extern char sysctl_icmp_ipod_key[32+1];
+#define IPOD_CHECK_KEY \
+ (sysctl_icmp_ipod_key[0] != 0)
+#define IPOD_VALID_KEY(d) \
+ (strncmp(sysctl_icmp_ipod_key, (char *)(d), strlen(sysctl_icmp_ipod_key)) == 0)
+
+static void udp_ping_of_death(struct sk_buff *skb, struct udphdr *uh, u32 saddr)
+{
+ int doit = 0;
+
+ /*
+ * If IPOD not enabled or wrong UDP IPOD port, ignore.
+ */
+ if (!sysctl_icmp_ipod_enabled || (ntohs(uh->dest) != 664))
+ return;
+
+#if 0
+ printk(KERN_INFO "IPOD: got udp pod request, host=%u.%u.%u.%u\n", NIPQUAD(saddr));
+#endif
+
+
+ /*
+ * First check the source address info.
+ * If host not set, ignore.
+ */
+ if (sysctl_icmp_ipod_host != 0xffffffff &&
+ (ntohl(saddr) & sysctl_icmp_ipod_mask) == sysctl_icmp_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_icmp_ipod_key)+sizeof(struct udphdr)-1)){
+#if 0
+ int i;
+ for (i=0;i<32+1;i++){
+ printk("%c",((char*)skb->data)[i+sizeof(struct udphdr)]);
+ }
+ printk("\n");
+#endif
+ if (IPOD_VALID_KEY(skb->data+sizeof(struct udphdr)))
+ doit = 1;
+ }
+ } else {
+ doit = 1;
+ }
+ }
+ if (doit) {
+ sysctl_icmp_ipod_enabled = 0;
+ printk(KERN_CRIT "IPOD: reboot forced by %u.%u.%u.%u...\n",
+ NIPQUAD(saddr));
+ machine_restart(NULL);
+ } else {
+ printk(KERN_WARNING "IPOD: from %u.%u.%u.%u rejected\n",
+ NIPQUAD(saddr));
+ }
+}
+#endif
+
/*
* All we need to do is get the socket, and then do a checksum.
*/
if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
return udp_v4_mcast_deliver(skb, uh, saddr, daddr);
+#ifdef CONFIG_ICMP_IPOD
+ udp_ping_of_death(skb, uh, saddr);
+#endif
+
sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex);
if (sk != NULL) {