diff -Nru linux-2.4.20/include/net/tcp.h linux-2.4.20-pom2patch/include/net/tcp.h
--- linux-2.4.20/include/net/tcp.h	2002-11-28 17:53:15.000000000 -0600
+++ linux-2.4.20-pom2patch/include/net/tcp.h	2003-05-02 12:57:54.000000000 -0500
@@ -140,6 +140,7 @@
 extern void tcp_bucket_unlock(struct sock *sk);
 extern int tcp_port_rover;
 extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif);
+extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif);
 
 /* These are AF independent. */
 static __inline__ int tcp_bhashfn(__u16 lport)
diff -Nru linux-2.4.20/include/net/udp.h linux-2.4.20-pom2patch/include/net/udp.h
--- linux-2.4.20/include/net/udp.h	2001-11-22 13:47:15.000000000 -0600
+++ linux-2.4.20-pom2patch/include/net/udp.h	2003-05-02 12:57:54.000000000 -0500
@@ -69,6 +69,8 @@
 extern int	udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 extern int	udp_disconnect(struct sock *sk, int flags);
 
+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
+
 extern struct udp_mib udp_statistics[NR_CPUS*2];
 #define UDP_INC_STATS(field)		SNMP_INC_STATS(udp_statistics, field)
 #define UDP_INC_STATS_BH(field)		SNMP_INC_STATS_BH(udp_statistics, field)
diff -Nru linux-2.4.20/net/ipv4/netfilter/ipt_owner.c linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_owner.c
--- linux-2.4.20/net/ipv4/netfilter/ipt_owner.c	2002-11-28 17:53:15.000000000 -0600
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_owner.c	2003-05-02 12:57:54.000000000 -0500
@@ -2,17 +2,25 @@
    locally generated outgoing packets.
 
    Copyright (C) 2000 Marc Boucher
+
+   03/26/2003 Patrick McHardy <kaber@trash.net>: LOCAL_IN support
  */
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/file.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
 #include <net/sock.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+#include <net/route.h>
 
 #include <linux/netfilter_ipv4/ipt_owner.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 
 static int
-match_comm(const struct sk_buff *skb, const char *comm)
+match_comm(const struct sock *sk, const char *comm)
 {
 	struct task_struct *p;
 	struct files_struct *files;
@@ -28,7 +36,7 @@
 		if(files) {
 			read_lock(&files->file_lock);
 			for (i=0; i < files->max_fds; i++) {
-				if (fcheck_files(files, i) == skb->sk->socket->file) {
+				if (fcheck_files(files, i) == sk->socket->file) {
 					read_unlock(&files->file_lock);
 					task_unlock(p);
 					read_unlock(&tasklist_lock);
@@ -44,7 +52,7 @@
 }
 
 static int
-match_pid(const struct sk_buff *skb, pid_t pid)
+match_pid(const struct sock *sk, pid_t pid)
 {
 	struct task_struct *p;
 	struct files_struct *files;
@@ -59,7 +67,7 @@
 	if(files) {
 		read_lock(&files->file_lock);
 		for (i=0; i < files->max_fds; i++) {
-			if (fcheck_files(files, i) == skb->sk->socket->file) {
+			if (fcheck_files(files, i) == sk->socket->file) {
 				read_unlock(&files->file_lock);
 				task_unlock(p);
 				read_unlock(&tasklist_lock);
@@ -75,10 +83,10 @@
 }
 
 static int
-match_sid(const struct sk_buff *skb, pid_t sid)
+match_sid(const struct sock *sk, pid_t sid)
 {
 	struct task_struct *p;
-	struct file *file = skb->sk->socket->file;
+	struct file *file = sk->socket->file;
 	int i, found=0;
 
 	read_lock(&tasklist_lock);
@@ -119,41 +127,71 @@
       int *hotdrop)
 {
 	const struct ipt_owner_info *info = matchinfo;
-
-	if (!skb->sk || !skb->sk->socket || !skb->sk->socket->file)
-		return 0;
+	struct iphdr *iph = skb->nh.iph;
+	struct sock *sk = NULL;
+	int ret = 0;
+
+	if (out) {
+		sk = skb->sk;
+	} else {
+		if (iph->protocol == IPPROTO_TCP) {
+			struct tcphdr *tcph =
+			        (struct tcphdr*)((u_int32_t*)iph + iph->ihl);
+			sk = tcp_v4_lookup(iph->saddr, tcph->source,
+			                   iph->daddr, tcph->dest,
+			                   ((struct rtable*)skb->dst)->rt_iif);
+			if (sk && sk->state == TCP_TIME_WAIT) {
+				tcp_tw_put((struct tcp_tw_bucket *)sk);
+				return ret;
+			}
+		} else if (iph->protocol == IPPROTO_UDP) {
+			struct udphdr *udph =
+			        (struct udphdr*)((u_int32_t*)iph + iph->ihl);
+			sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr,
+			                   udph->dest, skb->dev->ifindex);
+		}
+	} 
+					
+	if (!sk || !sk->socket || !sk->socket->file)
+		goto out;
 
 	if(info->match & IPT_OWNER_UID) {
-		if((skb->sk->socket->file->f_uid != info->uid) ^
+		if((sk->socket->file->f_uid != info->uid) ^
 		    !!(info->invert & IPT_OWNER_UID))
-			return 0;
+			goto out;
 	}
 
 	if(info->match & IPT_OWNER_GID) {
-		if((skb->sk->socket->file->f_gid != info->gid) ^
+		if((sk->socket->file->f_gid != info->gid) ^
 		    !!(info->invert & IPT_OWNER_GID))
-			return 0;
+			goto out;
 	}
 
 	if(info->match & IPT_OWNER_PID) {
-		if (!match_pid(skb, info->pid) ^
+		if (!match_pid(sk, info->pid) ^
 		    !!(info->invert & IPT_OWNER_PID))
-			return 0;
+			goto out;
 	}
 
 	if(info->match & IPT_OWNER_SID) {
-		if (!match_sid(skb, info->sid) ^
+		if (!match_sid(sk, info->sid) ^
 		    !!(info->invert & IPT_OWNER_SID))
-			return 0;
+			goto out;
 	}
 
 	if(info->match & IPT_OWNER_COMM) {
-		if (!match_comm(skb, info->comm) ^
+		if (!match_comm(sk, info->comm) ^
 		    !!(info->invert & IPT_OWNER_COMM))
-			return 0;
+			goto out;
 	}
 
-	return 1;
+	ret = 1;
+
+out:
+	if (in && sk)
+		sock_put(sk);
+
+	return ret;
 }
 
 static int
@@ -164,11 +202,19 @@
            unsigned int hook_mask)
 {
         if (hook_mask
-            & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
-                printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
+            & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) |
+		(1 << NF_IP_LOCAL_IN))) {
+        	printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT "
+		       "or POST_ROUTING.\n");
                 return 0;
         }
 
+	if ((hook_mask & (1 << NF_IP_LOCAL_IN))
+	    && ip->proto != IPPROTO_TCP && ip->proto != IPPROTO_UDP) {
+		printk("ipt_owner: only TCP or UDP can be used in LOCAL_IN\n");
+		return 0;
+	}
+
 	if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info)))
 		return 0;
 
diff -Nru linux-2.4.20/net/netsyms.c linux-2.4.20-pom2patch/net/netsyms.c
--- linux-2.4.20/net/netsyms.c	2002-11-28 17:53:16.000000000 -0600
+++ linux-2.4.20-pom2patch/net/netsyms.c	2003-05-02 12:57:54.000000000 -0500
@@ -596,4 +596,14 @@
 EXPORT_SYMBOL(wireless_send_event);
 #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
 
+#if defined(CONFIG_IP_NF_MATCH_OWNER)||defined(CONFIG_IP_NF_MATCH_OWNER_MODULE)
+EXPORT_SYMBOL(tcp_v4_lookup);
+#if !defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
+EXPORT_SYMBOL(udp_v4_lookup);
+#endif
+#if !(defined (CONFIG_IPV6_MODULE) || defined (CONFIG_KHTTPD) || defined (CONFIG_KHTTPD_MODULE))
+EXPORT_SYMBOL(tcp_timewait_cachep);
+#endif
+#endif /* CONFIG_IP_NF_MATCH_OWNER */
+
 #endif  /* CONFIG_NET */
