--- linux-2.4.0-test6clean/net/ipv6/sit.c	Sat Aug  5 11:18:49 2000
+++ linux-2.4.0-test6hacked/net/ipv6/sit.c	Mon Aug 28 08:43:49 2000
@@ -27,6 +27,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/icmp.h>
+#include <linux/inet.h>
 #include <asm/uaccess.h>
 #include <linux/init.h>
 #include <linux/netfilter_ipv4.h>
@@ -55,6 +56,7 @@
 
 #define HASH_SIZE  16
 #define HASH(addr) ((addr^(addr>>4))&0xF)
+#define SIXTO4PREF htons(0x2002)
 
 static int ipip6_fb_tunnel_init(struct net_device *dev);
 static int ipip6_tunnel_init(struct net_device *dev);
@@ -420,6 +422,28 @@
 	return ip_send(skb);
 }
 
+
+/* returns the embedded IPv4 address if the IPv6 address
+   comes from 6to4 (draft-ietf-ngtrans-6to4-06) addr space */
+static inline u32 try_6to4(struct in6_addr *v6dst) {
+	u32 dst = 0;
+	
+	if (*v6dst->s6_addr16 == SIXTO4PREF) {
+	        /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */
+		memcpy(&dst, &v6dst->s6_addr16[1], sizeof(u32));
+		if (IN_MULTICAST(ntohl(dst)) || 
+		   (dst == htonl(INADDR_BROADCAST)) ||
+		   IN_LOOPBACK(ntohl(dst))) {
+			if (net_ratelimit())
+				printk("sit.c: 6to4 IPv6 dest. encoded naughty IPv4 dest. %s\n",
+				       in_ntoa(dst));
+			return 0;
+		}
+	}
+	return dst;
+}
+
+
 /*
  *	This function assumes it is being called from dev_queue_xmit()
  *	and that skb is filled properly by that function.
@@ -448,6 +472,12 @@
 
 	if (skb->protocol != __constant_htons(ETH_P_IPV6))
 		goto tx_error;
+
+	if (!dst) {
+		/* well we first check if they are using the SIT device
+		   in wildcard 6to4 send mode */
+		dst = try_6to4(&iph6->daddr);
+	}
 
 	if (!dst) {
 		struct neighbour *neigh = NULL;
