Index: src/client_side.c
===================================================================
RCS file: /cvsroot/squid/squid/src/client_side.c,v
retrieving revision 1.561.2.80
diff -u -p -r1.561.2.80 client_side.c
--- src/client_side.c	30 Jun 2005 08:38:00 -0000	1.561.2.80
+++ src/client_side.c	30 Jun 2005 09:18:49 -0000
@@ -2587,19 +2587,6 @@ parseHttpRequest(ConnStateData * conn, m
     size_t req_sz;
     method_t method;
     clientHttpRequest *http = NULL;
-#if IPF_TRANSPARENT
-    struct natlookup natLookup;
-    static int natfd = -1;
-    static int siocgnatl_cmd = SIOCGNATL & 0xff;
-    int x;
-#endif
-#if PF_TRANSPARENT
-    struct pfioc_natlook nl;
-    static int pffd = -1;
-#endif
-#if LINUX_NETFILTER
-    socklen_t sock_sz = sizeof(conn->me);
-#endif
 
     /* pre-set these values to make aborting simpler */
     *prefix_p = NULL;
@@ -2733,12 +2720,52 @@ parseHttpRequest(ConnStateData * conn, m
 	int vport;
 	if (vhost_mode) {
 #if IPF_TRANSPARENT
+#if defined(IPFILTER_VERSION) && (IPFILTER_VERSION >= 4000027)
+	    static int natfd = -1;
+	    static time_t last_reported = 0;
+	    if (natfd < 0) {
+		int save_errno;
+		enter_suid();
+		natfd = open(IPNAT_NAME, O_RDONLY, 0);
+		save_errno = errno;
+		leave_suid();
+		errno = save_errno;
+	    }
+	    if (natfd < 0) {
+		if (squid_curtime - last_reported > 60) {
+		    debug(50, 1) ("parseHttpRequest: NAT open failed: %s\n", xstrerror());
+		    last_reported = squid_curtime;
+		}
+	    } else {
+		struct natlookup natLookup;
+		struct ipfobj obj;
+		natLookup.nl_inport = http->conn->me.sin_port;
+		natLookup.nl_outport = http->conn->peer.sin_port;
+		natLookup.nl_inip = http->conn->me.sin_addr;
+		natLookup.nl_outip = http->conn->peer.sin_addr;
+		natLookup.nl_flags = IPN_TCP;
+		obj.ipfo_rev = IPFILTER_VERSION;
+		obj.ipfo_size = sizeof(natLookup);
+		obj.ipfo_ptr = &natLookup;
+		obj.ipfo_type = IPFOBJ_NATLOOKUP;
+		obj.ipfo_offset = 0;
+		if (ioctl(natfd, SIOCGNATL, &obj) < 0) {
+		    if (errno != ESRCH) {
+			if (squid_curtime - last_reported > 60) {
+			    debug(50, 1) ("parseHttpRequest: NAT lookup failed: ioctl(SIOCGNATL): %s\n", xstrerror());
+			    last_reported = squid_curtime;
+			}
+			close(natfd);
+			natfd = -1;
+		    }
+		} else {
+		    conn->me.sin_port = natLookup.nl_realport;
+		    conn->me.sin_addr = natLookup.nl_realip;
+		}
+	    }
+#else
+	    static int natfd = -1;
 	    static time_t last_reported = 0;
-	    natLookup.nl_inport = http->conn->me.sin_port;
-	    natLookup.nl_outport = http->conn->peer.sin_port;
-	    natLookup.nl_inip = http->conn->me.sin_addr;
-	    natLookup.nl_outip = http->conn->peer.sin_addr;
-	    natLookup.nl_flags = IPN_TCP;
 	    if (natfd < 0) {
 		int save_errno;
 		enter_suid();
@@ -2757,6 +2784,14 @@ parseHttpRequest(ConnStateData * conn, m
 		    last_reported = squid_curtime;
 		}
 	    } else {
+		struct natlookup natLookup;
+		static int siocgnatl_cmd = SIOCGNATL & 0xff;
+		int x;
+		natLookup.nl_inport = http->conn->me.sin_port;
+		natLookup.nl_outport = http->conn->peer.sin_port;
+		natLookup.nl_inip = http->conn->me.sin_addr;
+		natLookup.nl_outip = http->conn->peer.sin_addr;
+		natLookup.nl_flags = IPN_TCP;
 		/*
 		 * IP-Filter changed the type for SIOCGNATL between
 		 * 3.3 and 3.4.  It also changed the cmd value for
@@ -2784,7 +2819,9 @@ parseHttpRequest(ConnStateData * conn, m
 		    conn->me.sin_addr = natLookup.nl_realip;
 		}
 	    }
+#endif /* IPFILTER_VERSION */
 #elif PF_TRANSPARENT
+	    static int pffd = -1;
 	    static time_t last_reported = 0;
 	    if (pffd < 0)
 		pffd = open("/dev/pf", O_RDWR);
@@ -2794,6 +2831,7 @@ parseHttpRequest(ConnStateData * conn, m
 		    last_reported = squid_curtime;
 		}
 	    } else {
+		struct pfioc_natlook nl;
 		memset(&nl, 0, sizeof(struct pfioc_natlook));
 		nl.saddr.v4.s_addr = http->conn->peer.sin_addr.s_addr;
 		nl.sport = http->conn->peer.sin_port;
@@ -2817,6 +2855,7 @@ parseHttpRequest(ConnStateData * conn, m
 		}
 	    }
 #elif LINUX_NETFILTER
+	    socklen_t sock_sz = sizeof(conn->me);
 	    static time_t last_reported = 0;
 	    /* If the call fails the address structure will be unchanged */
 	    if (getsockopt(conn->fd, SOL_IP, SO_ORIGINAL_DST, &conn->me, &sock_sz) != 0) {
