diff -Naur linux-2.6.18.1/include/linux/netfilter_ipv4/ip_tproxy.h linux-2.6.18.1_new/include/linux/netfilter_ipv4/ip_tproxy.h
--- linux-2.6.18.1/include/linux/netfilter_ipv4/ip_tproxy.h	2007-09-25 20:18:22.000000000 +0530
+++ linux-2.6.18.1_new/include/linux/netfilter_ipv4/ip_tproxy.h	2007-09-25 20:15:04.000000000 +0530
@@ -74,5 +74,60 @@
 	} v;
 };
 
+#ifdef __KERNEL__
+struct ip_tproxy_sockref;
+
+struct ip_tproxy_hash
+{
+	struct list_head list;
+	struct ip_tproxy_sockref *sockref;
+};
+
+struct ip_tproxy_sockref
+{
+	int flags;
+	atomic_t references;
+
+	u8 proto;
+
+	/* foreign address associated with a local socket */
+	u32 faddr;
+	u16 fport;
+
+	/* local socket address */
+	u32 laddr;
+	u16 lport;
+
+	/* remote addresses, needed for datagram protocols when the peer
+	 * sends the packet triggering the NAT translation. (as there might
+	 * be multiple sockrefs on the same foreign address).
+	 */
+	u32 raddr;
+	u16 rport;
+
+	/* hash chains indexed by local and foreign addresses */
+	struct ip_tproxy_hash bylocal, byforeign;
+
+	/* lock protecting access to related list */
+	spinlock_t relatedlock;
+	/* number of related connections */
+	atomic_t related;
+	/* list of related connections */
+	struct list_head relatedct;
+
+	/* socket which we were assigned to */
+	struct sock *assigned_to;
+
+	/* How many sockets use this sockref? Used for mark-only sockrefs,
+	 * which can be shared between multiple sockets bound to the same local
+	 * address */
+	atomic_t socket_count;
+
+	/* when was this entry inserted in hash */
+	struct timespec tv_hashed;
+};
+#endif //__KERNEL__
+
+
 #endif
 
diff -Naur linux-2.6.18.1/net/ipv4/netfilter/ip_tables.c linux-2.6.18.1_new/net/ipv4/netfilter/ip_tables.c
--- linux-2.6.18.1/net/ipv4/netfilter/ip_tables.c	2006-10-14 09:04:03.000000000 +0530
+++ linux-2.6.18.1_new/net/ipv4/netfilter/ip_tables.c	2007-09-25 20:16:17.000000000 +0530
@@ -33,6 +33,9 @@
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_tproxy.h>
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("IPv4 packet filter");
@@ -47,12 +50,16 @@
 #define dprintf(format, args...)
 #endif
 
+
+DEFINE_RWLOCK(ip_conntrack_lock);
+
 #ifdef DEBUG_IP_FIREWALL_USER
 #define duprintf(format, args...) printk(format , ## args)
 #else
 #define duprintf(format, args...)
 #endif
 
+#if 0
 #ifdef CONFIG_NETFILTER_DEBUG
 #define IP_NF_ASSERT(x)						\
 do {								\
@@ -63,6 +70,7 @@
 #else
 #define IP_NF_ASSERT(x)
 #endif
+#endif // #if 0
 
 #if 0
 /* All the better to debug you with... */
@@ -70,6 +78,7 @@
 #define inline
 #endif
 
+
 /*
    We keep a set of rules for each CPU, so we can avoid write-locking
    them in the softirq when updating the counters and therefore
@@ -85,7 +94,7 @@
 		const char *indev,
 		const char *outdev,
 		const struct ipt_ip *ipinfo,
-		int isfrag)
+		int isfrag, char TproxyBitSet, u32 tproxyFaddr)
 {
 	size_t i;
 	unsigned long ret;
@@ -108,7 +117,13 @@
 			NIPQUAD(ipinfo->dmsk.s_addr),
 			NIPQUAD(ipinfo->dst.s_addr),
 			ipinfo->invflags & IPT_INV_DSTIP ? " (INV)" : "");
-		return 0;
+                if (TproxyBitSet && ((tproxyFaddr == ipinfo->src.s_addr) ||
+                                     ((tproxyFaddr & ipinfo->smsk.s_addr) == ipinfo->src.s_addr)))
+                {
+                     // Do nothing
+		}
+		else
+                     return 0;
 	}
 
 	/* Look for ifname matches; this should unroll nicely. */
@@ -232,11 +247,53 @@
 	struct ipt_entry *e, *back;
 	struct xt_table_info *private;
 
+	struct ip_conntrack *ct;
+	enum ip_conntrack_info ctinfo;
+
+        char TproxyBitSet;
+        u32 tproxyFaddr;
+
 	/* Initialization */
 	ip = (*pskb)->nh.iph;
 	datalen = (*pskb)->len - ip->ihl * 4;
 	indev = in ? in->name : nulldevname;
 	outdev = out ? out->name : nulldevname;
+
+	read_lock_bh(&ip_conntrack_lock);
+	TproxyBitSet = 0;
+	tproxyFaddr = 0;
+        if (NF_IP_POST_ROUTING == hook)
+        {
+             ct = ip_conntrack_get (*pskb, &ctinfo);
+
+             if (ct)
+             {
+                  if (test_bit (IPS_TPROXY_BIT, &ct->status))
+                  {
+                       TproxyBitSet = 1;
+
+                       if (ct->tproxy.sockref)
+                       {
+                            struct ip_tproxy_sockref* sr = (struct ip_tproxy_sockref *)ct->tproxy.sockref;
+                            tproxyFaddr = sr->faddr;
+
+                       }
+                       else
+                       {
+                            TproxyBitSet = 0;
+                            tproxyFaddr = 0;
+                       }
+                  }
+                  else
+                  {
+                       TproxyBitSet = 0;
+                       tproxyFaddr = 0;
+                  }
+             }
+	}
+	read_unlock_bh(&ip_conntrack_lock);
+	
+
 	/* We handle fragments by dealing with the first fragment as
 	 * if it was a normal packet.  All other fragments are treated
 	 * normally, except that they will NEVER match rules that ask
@@ -257,7 +314,8 @@
 	do {
 		IP_NF_ASSERT(e);
 		IP_NF_ASSERT(back);
-		if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) {
+		if (ip_packet_match(ip, indev, outdev, &e->ip, offset,
+                                    TproxyBitSet, tproxyFaddr)) {
 			struct ipt_entry_target *t;
 
 			if (IPT_MATCH_ITERATE(e, do_match,
diff -Naur linux-2.6.18.1/net/ipv4/netfilter/iptable_tproxy.c linux-2.6.18.1_new/net/ipv4/netfilter/iptable_tproxy.c
--- linux-2.6.18.1/net/ipv4/netfilter/iptable_tproxy.c	2007-09-25 20:18:27.000000000 +0530
+++ linux-2.6.18.1_new/net/ipv4/netfilter/iptable_tproxy.c	2007-09-25 20:15:04.000000000 +0530
@@ -45,7 +45,7 @@
 
 #include <linux/netfilter_ipv4/listhelp.h>
 
-#define TPROXY_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
+#define TPROXY_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) 
 
 #if 0
 #define DEBUGP printk
@@ -147,6 +147,7 @@
 
 #define TF_STATE_MASK	  0xffff0000
 
+#if 0
 struct ip_tproxy_sockref;
 
 struct ip_tproxy_hash
@@ -198,6 +199,7 @@
 	/* when was this entry inserted in hash */
 	struct timespec tv_hashed;
 };
+#endif
 
 static int hashsize = 0;
 module_param(hashsize, uint, 0600);
@@ -724,6 +726,11 @@
 		       hooknum, sr->laddr, sr->lport, newip, newport);
 	}
 	else {
+		if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status))
+		{
+			test_and_clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status);
+		}
+
 		/* we store a reference to the sockref in the conntrack */
 		if (!test_and_set_bit(IPS_TPROXY_BIT, &ct->status)) {
 			if (flags & TN_STOREREF) {
@@ -828,6 +835,7 @@
 	enum ip_conntrack_info ctinfo;
 	unsigned int verdict = NF_ACCEPT;
 
+
 	ct = ip_conntrack_get(*pskb, &ctinfo);
 
 	if (ct && ctinfo == IP_CT_NEW) {
@@ -869,6 +877,7 @@
 			sr = ip_tproxy_sockref_find_foreign(iph->daddr, tports[1],
 						iph->protocol, iph->saddr, tports[0]);
 
+
 			if (sr && sr->flags & TF_ORPHAN) {
 				/* This sockref is orphaned, the listening socket is already unassigned,
 				 * so it should not be used for setting up NAT for a new connection. */
@@ -891,6 +900,7 @@
 				if ((sr->flags & TF_MARK_ONLY) == 0)
 					sr = NULL;
 			}
+
 		}
 		else if (hooknum == NF_IP_POST_ROUTING) {
 
@@ -906,6 +916,7 @@
 
 			/* source address is interesting */
 
+			
 			sr = ip_tproxy_sockref_find_local(iph->saddr, tports[0], iph->protocol,
 					1, iph->daddr, tports[1]);
 			if (sr && (sr->flags & (TF_CONNECT|TF_MARK_ONLY)) == 0) {
@@ -984,9 +995,9 @@
 			/* there was no matching sockref, so we consult the
 			 * TPROXY table
 			 */
-
 			ui.changed = 0;
 			verdict = ipt_do_table(pskb, hooknum, in, out, &tproxy_table, &ui);
+
 			if (ui.changed && verdict == NF_ACCEPT) {
 				struct ip_tproxy_sockref sr;
 				u32 laddr;
@@ -1016,7 +1027,6 @@
 			}
 		}
 	}
-
 	return verdict;
 }
 
