--- /root/netfilter/tproxy_orginal_code/patch/nf_tproxy_core.h	2011-06-16 05:32:49.232300795 +0200
+++ /root/netfilter/xtables-addons-1.31/extensions/patch/nf_tproxy_core.h	2011-06-16 05:32:22.070409400 +0200
@@ -8,6 +8,7 @@
 #include <net/inet_hashtables.h>
 #include <net/inet6_hashtables.h>
 #include <net/tcp.h>
+#include <net/sctp/structs.h>
 
 #define NFT_LOOKUP_ANY         0
 #define NFT_LOOKUP_LISTENER    1
@@ -63,27 +64,39 @@
  * "socket" match will be the first one, effectively all packets
  * belonging to established connections going through that one.
  */
+
+struct sctp_endpoint *__sctp_rcv_lookup_endpoint (const union sctp_addr *laddr);
+extern struct sock *sctp_get_ctl_sock(void);
+void sctp_hash_endpoint(struct sctp_endpoint *ep);
+
 static inline struct sock *
 nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
 		      const __be32 saddr, const __be32 daddr,
 		      const __be16 sport, const __be16 dport,
 		      const struct net_device *in, int lookup_type)
 {
-	struct sock *sk;
+	struct sock *sk, *tempsk=NULL;
+	union sctp_addr dest;
+	struct sctp_endpoint *ep = NULL;
 
 	case IPPROTO_TCP:
 		switch (lookup_type) {
 		case NFT_LOOKUP_ANY:
 			sk = __inet_lookup(net, &tcp_hashinfo,
-					   saddr, sport, daddr, dport,
-					   in->ifindex);
+					saddr, sport, daddr, dport,
+					in->ifindex);
 			break;
 		case NFT_LOOKUP_LISTENER:
 			sk = inet_lookup_listener(net, &tcp_hashinfo,
-						    daddr, dport,
-						    in->ifindex);
+					daddr, dport,
+					in->ifindex);
 
 			/* NOTE: we return listeners even if bound to
 			 * 0.0.0.0, those are filtered out in
@@ -93,8 +106,8 @@
 			break;
 		case NFT_LOOKUP_ESTABLISHED:
 			sk = inet_lookup_established(net, &tcp_hashinfo,
-						    saddr, sport, daddr, dport,
-						    in->ifindex);
+					saddr, sport, daddr, dport,
+					in->ifindex);
 			break;
 		default:
 			WARN_ON(1);
@@ -102,35 +115,106 @@
 			break;
 		}
 		break;
-	case IPPROTO_UDP:
-		sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
-				     in->ifindex);
-		if (sk && lookup_type != NFT_LOOKUP_ANY) {
-			int connected = (sk->sk_state == TCP_ESTABLISHED);
-			int wildcard = (inet_sk(sk)->rcv_saddr == 0);
+		case IPPROTO_UDP:
+			sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
+					in->ifindex);
+			if (sk && lookup_type != NFT_LOOKUP_ANY) {
+				int connected = (sk->sk_state == TCP_ESTABLISHED);
+				int wildcard = (inet_sk(sk)->rcv_saddr == 0);
+
+				/* NOTE: we return listeners even if bound to
+				 * 0.0.0.0, those are filtered out in
+				 * xt_socket, since xt_TPROXY needs 0 bound
+				 * listeners too */
+				if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) ||
+						(lookup_type == NFT_LOOKUP_LISTENER && connected)) {
+					sock_put(sk);
+					sk = NULL;
+				}
+			}
+			break;
 
-			/* NOTE: we return listeners even if bound to
-			 * 0.0.0.0, those are filtered out in
-			 * xt_socket, since xt_TPROXY needs 0 bound
-			 * listeners too */
-			if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) ||
-			    (lookup_type == NFT_LOOKUP_LISTENER && connected)) {
-				sock_put(sk);
+		case IPPROTO_SCTP:
+		{
+			switch(lookup_type)
+			{
+			case NFT_LOOKUP_ANY:
+
 				sk = NULL;
-			}
-		}
+				break;
+
+			case NFT_LOOKUP_ESTABLISHED:
+
+				sk = NULL;
+				break;
+
+			case NFT_LOOKUP_LISTENER:
+			{
+				dest.v4.sin_addr.s_addr = daddr;  
+               /*look up using destination port*/
+				dest.v4.sin_port = sport;    // for sctp only this is made as 1200 
+                		dest.v4.sin_family = PF_INET;
+		        ep = __sctp_rcv_lookup_endpoint(&dest);
+				if(!ep)
+					return NULL;
+					
+				tempsk = sctp_get_ctl_sock();
+				if(ep->base.sk != tempsk){
+					sk = ep->base.sk;
+					return sk;
+				}
+			
+				/*Now lookup using tproxy port */
+				dest.v4.sin_port = dport;
+				ep = __sctp_rcv_lookup_endpoint(&dest);
+				if(!ep)
+					return NULL;
+				sk = ep->base.sk;
+				ep->base.bind_addr.port=htons(sport);				
+				sctp_hash_endpoint(ep);	
+				 			
+				break;
+			}	
+			default:
+				WARN_ON(1);
+				sk = NULL;
+				break;
+			} 
+			
+		}/*case sctp*/
 		break;
-	default:
-		WARN_ON(1);
-		sk = NULL;
-	}
+		default:
+			WARN_ON(1);
+			sk = NULL;
+			break;
+		}/*outer switch*/
 
-	pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n",
-		 protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk);
 
-	return sk;
+	if(sk){
+		pr_info("TPROXY:%s:%d:%s() - return with (sk:%p) \n","nf_tproxy_core.h",__LINE__,__func__,sk);
+	}else{
+		pr_info("TPROXY:%s:%d:%s() - return with (sk:NULL) \n","nf_tproxy_core.h",__LINE__,__func__);
+	}
+return sk;
+
 }
 
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static inline struct sock *
 nf_tproxy_get_sock_v6(struct net *net, const u8 protocol,
@@ -139,7 +223,7 @@
 		      const struct net_device *in, int lookup_type)
 {
 	struct sock *sk;
-
+	pr_info("TPROXY:%s:%d:%s() - Entry for IPv6 \n","nf_tproxy_core.h",__LINE__,__func__);
 	/* look up socket */
 	switch (protocol) {
 	case IPPROTO_TCP:
@@ -204,11 +288,16 @@
 static inline void
 nf_tproxy_put_sock(struct sock *sk)
 {
+	pr_info("TPROXY:%s:%d:%s() - entry(sk:%p) \n","nf_tproxy_core.h",__LINE__,__func__,sk);
 	/* TIME_WAIT inet sockets have to be handled differently */
-	if ((sk->sk_protocol == IPPROTO_TCP) && (sk->sk_state == TCP_TIME_WAIT))
+	if ((sk->sk_protocol == IPPROTO_TCP) && (sk->sk_state == TCP_TIME_WAIT)){
+		pr_info("TPROXY:%s:%d:%s() - calling inet_twsk_put. return void \n","nf_tproxy_core.h",__LINE__,__func__);
 		inet_twsk_put(inet_twsk(sk));
-	else
+	}
+	else{
+		pr_info("TPROXY:%s:%d:%s() - calling sock_put. return void \n","nf_tproxy_core.h",__LINE__,__func__);
 		sock_put(sk);
+	}
 }
 
 /* assign a socket to the skb -- consumes sk */
