[zorp-hu] tproxy nyug

Balazs Scheidler zorp-hu@lists.balabit.hu
Sun, 05 Dec 2004 14:43:21 +0100


--=-wz+Dm4yNxpJqhUwc1bMm
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Sat, 2004-12-04 at 18:54, Ifj. Darvas Istvan wrote:
> sziasztok,
> 
> szituacio:
> telepitettem egy uj gepet, fel szerettem volna telepiteni arra ugyan azt a
> zorp konfigot, ami a masikon van. csak ujabb kernellel. Akkor bele is vagnek
> a lenyegbe.
> 
> kornyezet:
> 2.6.8.1-es kernel, megbuheralva a cttproxy-2.6.8.1-2.0.0 csomagotokkal

> -------->instances.conf
> TESZT --verbose=8 --policy /etc/zorp/policy.py --autobind-ip 1.2.3.4
> 
> -------->policy.py
> def TESZT():
>         Service(
>                 "inter_TESZT_H12",
>                 PlugProxy,
>                 router=DirectedRouter(SockAddrInet(IP_H12,443)),
>                 snat=ForgeClientSourceNAT()
>         )
>         Listener(SockAddrInet(IP0,52000), "inter_TESZT_H12")
> 
> --------->iptables
>     -t tproxy -A PREROUTING -i eth0 -p tcp -d 195.70.41.161 --dport 10000 -j
> TPROXY --on-port 52000
> 
> err.log csatolva
> Dec  4 18:40:20 hyperion TESZT[1279]: (https-Zorp/inter_TESZT_H12:0/plug):
> bind() failed; error='Cannot assign requested address'
> 
> en ezt a sort nem ertem, hogy miert nem tud a zorp cimet igenyeleni

az 1.2-es es a 2.0-as tproxy nem kompatibilis egymassal, es a 2.0-as
zorp meg nem ismeri az uj tproxy feluletet. most keszitunk elo egy
2.1-es release-t (2.1.9) illetve nemsokara (most mar tenyleg) megjelenik
a 3.0-asbol is az elso GPL-es.

Ezek tudjak kezelni az uj tproxyt.

Addig is kibanyasztam a CVS-unkbol azt a patchet, ami tproxy2 tamogatast
ad a 2.1-es Zorphoz. Ez elvileg felmegy a 2.1.8-ra, esetleg kisebb
conflict-okkal. Utana mar menni fog.



-- 
Bazsi


--=-wz+Dm4yNxpJqhUwc1bMm
Content-Disposition: attachment; filename=zorp-2.1-tproxy-2.0.diff
Content-Type: text/x-patch; name=zorp-2.1-tproxy-2.0.diff; charset=iso-8859-2
Content-Transfer-Encoding: 7bit

---------------------
PatchSet 2764 
Date: 2004/11/08 16:56:34
Author: sasa
Branch: zorp_2_0_fp1
Tag: (none) 
Log:
a

Members: 
	debian/maintainchangelog.sh:1.11.2.14->1.11.2.15 
	lib/packsock.c:1.57.2.8->1.57.2.9 
	lib/sysdep.c:1.15.2.3->1.15.2.4 
	lib/tpsocket.c:1.24.2.11->1.24.2.12 
	lib/zorp/sysdep.h:1.7.2.3->1.7.2.4 
	lib/zorp/tpsocket.h:1.5.4.2->1.5.4.3 

Index: zorp-core/debian/maintainchangelog.sh
diff -u zorp-core/debian/maintainchangelog.sh:1.11.2.14 zorp-core/debian/maintainchangelog.sh:1.11.2.15
--- zorp-core/debian/maintainchangelog.sh:1.11.2.14	Tue Aug 24 09:14:13 2004
+++ zorp-core/debian/maintainchangelog.sh	Mon Nov  8 17:56:34 2004
@@ -4,7 +4,7 @@
 date=`date -R`
 if ! head -5 changelog | grep "^zorp-pro ($ver-1)" >/dev/null; then
 	cat > changelog <<EOF
-zorp-pro ($ver-1) zorp21; urgency=low
+zorp-pro ($ver-1) zorp21dbg; urgency=low
 
   * new upstream release
 
Index: zorp-core/lib/packsock.c
diff -u zorp-core/lib/packsock.c:1.57.2.8 zorp-core/lib/packsock.c:1.57.2.9
--- zorp-core/lib/packsock.c:1.57.2.8	Thu Apr  8 12:01:42 2004
+++ zorp-core/lib/packsock.c	Mon Nov  8 17:56:34 2004
@@ -2,7 +2,7 @@
  *
  * COPYRIGHTHERE
  *
- * $Id: packsock.c,v 1.57.2.8 2004/04/08 10:01:42 sasa Exp $
+ * $Id: packsock.c,v 1.57.2.9 2004/11/08 16:56:34 sasa Exp $
  *
  * Author  : yeti
  * Auditor : bazsi
@@ -22,6 +22,7 @@
 #include <zorp/stream.h>
 #include <zorp/cap.h>
 #include <zorp/sysdep.h>
+#include <zorp/tpsocket.h>
 
 #include <time.h>
 #include <netinet/ip.h>
@@ -50,6 +51,10 @@
   
   if (fd < 0)
     {
+      /*LOG
+        This message indicate that Zorp failed opening a new socket.
+        It is likely that Zorp reached some resource limit.
+       */
       z_log(NULL, CORE_ERROR, 3, "Error opening socket; error='%s'", g_strerror(errno));
       close(fd);
       z_leave();
@@ -222,36 +227,43 @@
 
 #if ENABLE_NETFILTER_TPROXY
 
-#include <zorp/nfiptproxy-kernel.h>
+#include <zorp/nfiptproxy-kernelv2.h>
 
-#ifndef IP_RECVORIGADDRS
-
-#define IP_RECVORIGADDRS 16
-#define IP_ORIGADDRS     17
+#ifndef IP_RECVORIGADDRS_V12
+#define IP_RECVORIGADDRS_V12 16
+#define IP_ORIGADDRS_V12     17
+#endif
 
-struct in_origaddrs {
-        struct in_addr ioa_srcaddr;
-        struct in_addr ioa_dstaddr;
-        unsigned short int ioa_srcport;
-        unsigned short int ioa_dstport;
-};
+#endif
 
+#if ENABLE_IPFILTER_TPROXY
+#include <zorp/ipfiptproxy-kernel.h>
 #endif
 
+#if ENABLE_NETFILTER_TPROXY || ENABLE_IPFILTER_TPROXY
+static gint z_nf_recvorigaddrs_opt;
+
+#if ENABLE_NETFILTER_TPROXY
+static gint z_nf_origaddrs_opt;
+#endif /* ENABLE_NETFILTER_TPROXY */
+
+
 gint
 z_nf_packsock_open(guint flags, ZSockAddr *remote, ZSockAddr *local, guint32 sock_flags, GError **error G_GNUC_UNUSED)
 {
   gint fd;
   gint tmp = 1;
-  gint tmpflags;
-  gint flagslen = sizeof(tmpflags);
   
   z_enter();
   fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
   
   if (fd < 0)
     {
-      z_log(NULL, CORE_ERROR, 3, "Error creating socket; error='%s'", g_strerror(errno));
+      /*LOG
+        This message indicate that Zorp failed opening a new socket.
+        It is likely that Zorp reached some resource limit.
+       */
+      z_log(NULL, CORE_ERROR, 3, "Error opening socket; error='%s'", g_strerror(errno));
       close(fd);
       z_leave();
       return -1;
@@ -259,29 +271,43 @@
   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
   tmp = 1;
   setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &tmp, sizeof(tmp));
-  
+
   if (flags & ZPS_LISTEN)
     {
-      if (setsockopt(fd, SOL_IP, IP_RECVORIGADDRS, &tmp, sizeof(tmp)) < 0)
+      tmp = 1;
+      if (setsockopt(fd, SOL_IP, z_nf_recvorigaddrs_opt, &tmp, sizeof(tmp)) < 0)
         {
-          /* FIXME: log error */
+          /*LOG
+            This message indicates that the setsockopt failed.
+           */
           z_log(NULL, CORE_ERROR, 3, "Error during setsockopt(SOL_IP, IP_RECVORIGADDRS); error='%s'", g_strerror(errno));
           close(fd);
           z_leave();
           return -1;
         }
+#if ZORPLIB_ENABLE_TOS
+      tmp = 1;
+      if (setsockopt(fd, SOL_IP, IP_RECVTOS, &tmp, sizeof(tmp)) < 0)
+        {
+          z_log(NULL, CORE_ERROR, 3, "Error during setsockopt(SOL_IP, IP_RECVTOS); error='%s'", g_strerror(errno));
+          close(fd);
+          z_leave();
+          return -1;
+        }
+#endif
       if (z_bind(fd, local, sock_flags) != G_IO_STATUS_NORMAL)
         {
           /* z_bind already issued a log message */
           z_leave();
           return -1;
         }
-      if (getsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &tmpflags, &flagslen) >= 0)
+      if (z_tp_query(fd, NULL, NULL) != -1)
         {
-          tmp = ITP_LISTEN | ITP_UNIDIR;
-          if (setsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &tmp, sizeof(tmp)) < 0)
+          if (z_tp_set_flags(fd, ITP_LISTEN | ITP_UNIDIR) < 0)
             {
-              /* FIXME: error message */
+              /*LOG
+                This message indicates that the setsockopt failed, and Zorp can not listen on a foreign address.
+               */
               z_log(NULL, CORE_ERROR, 3, "Error during setsockopt(SOL_IP, IP_TPROXY_FLAGS, ITP_LISTEN | ITP_UNIDIR); error='%s'", g_strerror(errno));
               close(fd);
               z_leave();
@@ -310,24 +336,37 @@
       
       if (!local)
         {
-          struct sockaddr disconnect;
           
           if (z_getsockname(fd, &local, ZSF_MARK_TPROXY) != G_IO_STATUS_NORMAL)
             {
+              /*LOG
+                This message indicates that Zorp was unable to get a local address.
+               */
               z_log(NULL, CORE_ERROR, 3, "Error getting dynamic local address (nf); error='%s'", g_strerror(errno));
               close(fd);
               z_leave();
               return -1;
             }
-          disconnect.sa_family = AF_UNSPEC;
-          if (connect(fd, &disconnect, sizeof(disconnect)) < 0)
+          /* reopen fd so that we are able to call z_bind() */
+          close(fd);
+          fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+          
+          if (fd < 0)
             {
-              z_log(NULL, CORE_ERROR, 3, "Error unconnecting for dynamic binding (nf); error='%s'", g_strerror(errno));
-              z_sockaddr_unref(local);
+              /*LOG
+                This message indicate that Zorp failed opening a new socket.
+                It is likely that Zorp reached some resource limit.
+               */
+              z_log(NULL, CORE_ERROR, 3, "Error opening socket; error='%s'", g_strerror(errno));
               close(fd);
               z_leave();
               return -1;
             }
+          
+          setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
+          tmp = 1;
+          setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &tmp, sizeof(tmp));
+
           if (z_bind(fd, local, sock_flags) != G_IO_STATUS_NORMAL)
             {
               z_sockaddr_unref(local);
@@ -339,6 +378,8 @@
           local = NULL;
           if (connect(fd, &remote->sa, remote->salen) < 0)
             {
+              /*LOG
+               */
               z_log(NULL, CORE_ERROR, 3, "Error reconnecting UDP socket (nf); error='%s'", g_strerror(errno));
               close(fd);
               z_leave();
@@ -346,11 +387,13 @@
             }
         }
       
-      if (getsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &flags, &flagslen) >= 0)
+      if (z_tp_query(fd, NULL, NULL) != -1)
         {
-          tmp = ITP_ESTABLISHED;
-          if (setsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &tmp, sizeof(tmp)) < 0)
+          z_tp_connect(fd, ((struct sockaddr_in *) &remote->sa)->sin_addr.s_addr, ((struct sockaddr_in *) &remote->sa)->sin_port); 
+          if (z_tp_set_flags(fd, ITP_ESTABLISHED) < 0) 
             {
+              /*LOG
+               */
               z_log(NULL, CORE_ERROR, 3, "Error during setsockopt(SOL_IP, IP_TPROXY_FLAGS, ITP_ESTABLISHED); error='%s'", g_strerror(errno));
               close(fd);
               z_leave();
@@ -361,6 +404,10 @@
   return fd;
 }
 
+#endif /* ENABLE_NETFILTER_TPROXY || ENABLE_IPFILTER_TPROXY */
+
+#if ENABLE_NETFILTER_TPROXY
+
 GIOStatus
 z_nf_packsock_recv(gint fd, ZPacket **packet, ZSockAddr **from_addr, ZSockAddr **to_addr, GError **error G_GNUC_UNUSED)
 {
@@ -402,20 +449,20 @@
   
   if (to_addr)
     {
-      *to_addr = NULL;
+      if (to_addr)
+        *to_addr = NULL;
       for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg,cmsg))
         {
-          if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_ORIGADDRS)
+          if (to_addr && cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == z_nf_origaddrs_opt)
             {
               struct in_origaddrs *ioa = (struct in_origaddrs *) CMSG_DATA(cmsg);
 
-	      to.sin_family = AF_INET;
-	      to.sin_addr = ioa->ioa_dstaddr;
-	      to.sin_port = ioa->ioa_dstport;
-	      *to_addr = z_sockaddr_inet_new2(&to);
-	      break;
-	    }
-	}
+              to.sin_family = AF_INET;
+              to.sin_addr = ioa->ioa_dstaddr;
+              to.sin_port = ioa->ioa_dstport;
+              *to_addr = z_sockaddr_inet_new2(&to);
+            }
+        }
       if (*to_addr == NULL)
         {
           struct sockaddr_in to;
@@ -431,6 +478,10 @@
   
 }
 
+#endif /* ENABLE_NETFILTER_TPROXY */
+
+#if ENABLE_NETFILTER_TPROXY || ENABLE_IPFILTER_TPROXY
+
 /* destination address is implicit, specified by socket creation */
 GIOStatus
 z_nf_packsock_write(gint fd, ZPacket *packet, GError **error G_GNUC_UNUSED)
@@ -478,6 +529,9 @@
   return G_IO_STATUS_NORMAL;
 }
 
+#endif
+
+#if ENABLE_NETFILTER_TPROXY
 ZPacksockFuncs z_nf_packsock_funcs = 
 {
   z_nf_packsock_open,
@@ -488,6 +542,124 @@
 
 #endif
 
+#if ENABLE_IPFILTER_TPROXY
+
+GIOStatus
+z_ipf_packsock_recv(gint fd, ZPacket **packet, ZSockAddr **from_addr, ZSockAddr **to_addr, GError **error G_GNUC_UNUSED)
+{
+  struct sockaddr_in from, to;
+  gchar buf[65536], ctl_buf[64];
+  struct msghdr msg;
+  struct cmsghdr *cmsg;
+  struct iovec iov;
+            
+  gint rc;
+  
+  z_enter();
+
+  memset(&msg, 0, sizeof(msg));
+  memset(&ctl_buf, 0, sizeof(ctl_buf));
+  msg.msg_name = &from;
+  msg.msg_namelen = sizeof(from);
+  msg.msg_controllen = sizeof(ctl_buf);
+  msg.msg_control = ctl_buf;
+  msg.msg_iovlen = 1;
+  msg.msg_iov = &iov;
+  iov.iov_base = buf;
+  iov.iov_len = sizeof(buf);
+                
+  do
+    {
+      rc = recvmsg(fd, &msg, 0);
+    }
+  while (rc < 0 && errno == EINTR);
+  
+  if (rc < 0)
+    {
+      z_leave();
+      return errno == EAGAIN ? G_IO_STATUS_AGAIN : G_IO_STATUS_ERROR;
+    }
+  *packet = z_packet_new();
+  
+  z_packet_set_data(*packet, buf, rc);
+  *from_addr = z_sockaddr_inet_new2(&from);
+  
+  if (to_addr)
+    {
+      if (to_addr)
+        *to_addr = NULL;
+      for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg,cmsg))
+        {
+          if (to_addr && cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVOPTS)
+            {
+              /* parse IP options, search for original destination address */
+              guint left = cmsg->cmsg_len, length;
+              guchar *src = CMSG_DATA(cmsg);
+
+              while (left)
+                {
+                  if (*src == '\0')
+                    {
+                      /* EOOL */
+                      left--;
+                      break;
+                    }
+                  else if (*src == '\1')
+                    {
+                      /* NOP */
+                      left--;
+                    }
+                  else if (*src == IPOPT_ORIGDST)
+                    {
+                      /* original destination address */
+                      if (left <= 1)
+                        {
+                          /* no space for length field */
+                          break;
+                        }
+                      length = *(src + 1);
+                      if ((length > left) || (length != 8))
+                        {
+                          /* option too long or invalid */
+                          break;
+                        }
+
+                      /* copy address */
+                      to.sin_family = AF_INET;
+                      to.sin_port = *((guint16 *)(src + 2));
+                      to.sin_addr.s_addr = *((guint32 *)(src + 4));
+                      *to_addr = z_sockaddr_inet_new2(&to);
+                      break;
+                    }
+                } /* while (left) */
+            } /* if (IP_RECVOPTS) */
+        } /* for (cmsg) */
+
+      if (*to_addr == NULL)
+        {
+          struct sockaddr_in to;
+          socklen_t tolen = sizeof(to);
+                             
+          getsockname(fd, (struct sockaddr *) &to, &tolen);
+          *to_addr = z_sockaddr_inet_new2(&to);
+        }
+    }
+
+  z_leave();
+  return G_IO_STATUS_NORMAL;
+  
+}
+
+ZPacksockFuncs z_ipf_packsock_funcs =
+{
+  z_nf_packsock_open,
+  z_ipf_packsock_recv,
+  z_nf_packsock_read,
+  z_nf_packsock_write
+};
+
+#endif
+
 ZPacksockFuncs *packsock_funcs;
 
 gint 
@@ -526,11 +698,29 @@
       break;
 #endif
 #if ENABLE_NETFILTER_TPROXY
-    case Z_SD_TPROXY_NETFILTER:
+    case Z_SD_TPROXY_NETFILTER_V12:
+      z_nf_recvorigaddrs_opt = IP_RECVORIGADDRS_V12;
+      z_nf_origaddrs_opt = IP_ORIGADDRS_V12;
+      packsock_funcs = &z_nf_packsock_funcs;
+      break;
+    case Z_SD_TPROXY_NETFILTER_V20:
+      z_nf_recvorigaddrs_opt = IP_RECVORIGADDRS;
+      z_nf_origaddrs_opt = IP_ORIGADDRS;
       packsock_funcs = &z_nf_packsock_funcs;
       break;
 #endif
+#if ENABLE_IPFILTER_TPROXY
+    case Z_SD_TPROXY_IPF:
+      z_nf_recvorigaddrs_opt = IP_RECVOPTS;
+      packsock_funcs = &z_ipf_packsock_funcs;
+      break;
+#endif
     default:
+      /*LOG
+        This message indicates that Zorp was compiled without the required transparency support for UDP, or bad 
+        transparency support was specified on command line.
+        Check your "instances.conf" or your kernel tproxy capabilities.
+       */
       z_log(NULL, CORE_ERROR, 0, "Required transparency support not compiled in (UDP); sysdep_tproxy='%d'", sysdep_tproxy);
       return FALSE;
     }
Index: zorp-core/lib/sysdep.c
diff -u zorp-core/lib/sysdep.c:1.15.2.3 zorp-core/lib/sysdep.c:1.15.2.4
--- zorp-core/lib/sysdep.c:1.15.2.3	Fri Sep 12 10:33:07 2003
+++ zorp-core/lib/sysdep.c	Mon Nov  8 17:56:34 2004
@@ -3,7 +3,7 @@
  * Copyright (c) 2000, 2001 BalaBit IT Ltd, Budapest, Hungary
  * All rights reserved.
  *
- * $Id: sysdep.c,v 1.15.2.3 2003/09/12 08:33:07 bazsi Exp $
+ * $Id: sysdep.c,v 1.15.2.4 2004/11/08 16:56:34 sasa Exp $
  *
  * Author  : Bazsi
  * Auditor :
@@ -19,22 +19,44 @@
 #include <zorp/tpsocket.h>
 
 #if ENABLE_NETFILTER_TPROXY
+
+#if ENABLE_NETFILTER_TPROXY_V12_FALLBACK
+#define in_tproxy in_tproxy_v12
 #include <zorp/nfiptproxy-kernel.h>
+#undef in_tproxy
+#endif
+
+#include <zorp/nfiptproxy-kernelv2.h>
 #endif
 
 #include <stdlib.h>
 
+/**
+ * z_sysdep_parse_tproxy_arg:
+ * @sysdep_tproxy_arg: --tproxy argument passed to Zorp
+ *
+ * This function converts the --tproxy argument to an internal Z_SD_TPROXY_*
+ * representation.
+ *
+ * Returns: one of the Z_SD_TPROXY_* values
+ **/
 static gint
 z_sysdep_parse_tproxy_arg(const gchar *sysdep_tproxy_arg)
 {
   if (sysdep_tproxy_arg)
     {
 #if ENABLE_NETFILTER_TPROXY
-      if (strcasecmp(sysdep_tproxy_arg, "netfilter") == 0)
+      if (strcasecmp(sysdep_tproxy_arg, "netfilterv2") == 0 || strcasecmp(sysdep_tproxy_arg, "tproxy20") == 0)
+        {
+          return Z_SD_TPROXY_NETFILTER_V20;
+        }
+#if ENABLE_NETFILTER_TPROXY_V12_FALLBACK
+      if (strcasecmp(sysdep_tproxy_arg, "netfilter") == 0 || strcasecmp(sysdep_tproxy_arg, "tproxy12") == 0)
         {
-          return Z_SD_TPROXY_NETFILTER;
+          return Z_SD_TPROXY_NETFILTER_V12;
         }
 #endif
+#endif
 #if ENABLE_LINUX22_TPROXY
       if (strcasecmp(sysdep_tproxy_arg, "linux22") == 0)
         {
@@ -51,31 +73,64 @@
   return 0;
 }
 
+/**
+ * z_sysdep_init:
+ * @sysdep_tproxy_arg: --tproxy argument passed to Zorp
+ *
+ * Initialize runtime system detection, currently it boils down to detecting
+ * kernel support for transparent proxying.
+ *
+ * Returns: TRUE to indicate success
+ **/
 gboolean
 z_sysdep_init(const gchar *sysdep_tproxy_arg)
 {
+  const gchar *sysdep_tproxy_str[] =
+  {   
+    [0]                            NULL,
+    [Z_SD_TPROXY_LINUX22]          "linux22",
+    [Z_SD_TPROXY_NETFILTER_V12]    "tproxy12",
+    [Z_SD_TPROXY_IPF]              "ipf",
+    [Z_SD_TPROXY_NETFILTER_V20]    "tproxy20"
+  };
   gint sysdep_tproxy = z_sysdep_parse_tproxy_arg(sysdep_tproxy_arg);
+  
 
   if (sysdep_tproxy == 0)
     {
 #if ENABLE_NETFILTER_TPROXY
+      struct in_tproxy itp;
+      socklen_t size = sizeof(itp);
       gint sock;
-
+ 
       sysdep_tproxy = Z_SD_TPROXY_LINUX22;
-      
+   
       system("/sbin/modprobe iptable_tproxy >/dev/null 2>&1");
       sock = socket(AF_INET, SOCK_STREAM, 0);
       if (sock != -1)
         {
-          guint flags;
-          socklen_t flagslen = sizeof(flags);
-          if (getsockopt(sock, SOL_IP, IP_TPROXY_FLAGS, &flags, &flagslen) == -1)
+          itp.op = TPROXY_VERSION;
+          itp.v.version = 0x02000000;
+          if (getsockopt(sock, SOL_IP, IP_TPROXY, &itp, &size) == -1)
             {
-              if (errno != ENOPROTOOPT)
-                sysdep_tproxy = Z_SD_TPROXY_NETFILTER;
+#if ENABLE_NETFILTER_TPROXY_V12_FALLBACK
+               guint flags;
+               socklen_t flagslen = sizeof(flags);
+               if (getsockopt(sock, SOL_IP, IP_TPROXY_FLAGS, &flags, &flagslen) == -1)
+                 {
+                   if (errno != ENOPROTOOPT)
+                     sysdep_tproxy = Z_SD_TPROXY_NETFILTER_V12;
+                 }
+               else
+                 sysdep_tproxy = Z_SD_TPROXY_NETFILTER_V12;
+#else
+               ;
+#endif
             }
           else
-            sysdep_tproxy = Z_SD_TPROXY_NETFILTER;
+            { 
+              sysdep_tproxy = Z_SD_TPROXY_NETFILTER_V20;
+            }
           close(sock);
         }
 #elif ENABLE_LINUX22_TPROXY
@@ -85,8 +140,11 @@
 #else
       #error "No known tproxy support"
 #endif
-    }
-  z_log(NULL, CORE_DEBUG, 6, "System dependant init; sysdep_tproxy='%d'", sysdep_tproxy);
+    } 
+  /*LOG
+    This message reports that system dependant was successful, tproxy support was set.
+   */
+  z_log(NULL, CORE_DEBUG, 6, "System dependant init; sysdep_tproxy='%s'", sysdep_tproxy_str[sysdep_tproxy]);
   if (!z_packsock_init(sysdep_tproxy))
     return FALSE;
   if (!z_tp_socket_init(sysdep_tproxy))
Index: zorp-core/lib/tpsocket.c
diff -u zorp-core/lib/tpsocket.c:1.24.2.11 zorp-core/lib/tpsocket.c:1.24.2.12
--- zorp-core/lib/tpsocket.c:1.24.2.11	Fri Feb  6 13:35:22 2004
+++ zorp-core/lib/tpsocket.c	Mon Nov  8 17:56:34 2004
@@ -2,7 +2,7 @@
  *
  * COPYRIGHTHERE
  *
- * $Id: tpsocket.c,v 1.24.2.11 2004/02/06 12:35:22 bazsi Exp $
+ * $Id: tpsocket.c,v 1.24.2.12 2004/11/08 16:56:34 sasa Exp $
  *
  * Author  : Bazsi
  * Auditor :
@@ -21,7 +21,13 @@
 
 #if ENABLE_NETFILTER_TPROXY
 
+#if ENABLE_NETFILTER_TPROXY_V12_FALLBACK
+#define in_tproxy in_tproxy_v12
 #include <zorp/nfiptproxy-kernel.h>
+#undef in_tproxy
+#endif
+
+#include <zorp/nfiptproxy-kernelv2.h>
 
 #elif ENABLE_IPFILTER_TPROXY
 
@@ -37,9 +43,9 @@
 #include <netinet/ip6.h>
 #include <netinet/tcp.h>
 #include <net/if.h>
-#include <netinet/ip_compat.h>
-#include <netinet/ip_fil.h>
-#include <netinet/ip_nat.h>
+#include <ipfilter/ip_compat.h>
+#include <ipfilter/ip_fil.h>
+#include <ipfilter/ip_nat.h>
 #include <zorp/ipfiptproxy-kernel.h>
 
 #endif
@@ -47,13 +53,16 @@
 
 const gchar *auto_bind_ip = "1.2.3.4";
 
-gint
+static gint sysdep_tproxy;
+
+static gint
 z_tp_autobind(gint fd, unsigned short port)
 {
   struct sockaddr_in sa;
   socklen_t salen = sizeof(sa);
   struct in_addr ab_addr;
   
+  z_enter();
   memset(&sa, 0, sizeof(sa));
   
   z_inet_aton(auto_bind_ip, &ab_addr);
@@ -62,6 +71,7 @@
       /* already bound */
       if (sa.sin_family == AF_INET && sa.sin_addr.s_addr == ab_addr.s_addr)
         {
+          z_leave();
           return 0;
         }
     }
@@ -76,6 +86,7 @@
       sa.sin_port = htons(port);
       if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) >= 0)
         {
+          z_leave();
           return 0;
         }
       else if (errno != EADDRINUSE)
@@ -98,23 +109,237 @@
         }
     }
   while (1);
-                                                                                
+  
   /*LOG
     This message indicates that the bind syscall failed for the given reason.
    */
   z_log(NULL, CORE_ERROR, 3, "Error autobinding transparent socket; fd='%d', ip='%s', error='%s'", fd, auto_bind_ip, g_strerror(errno));
+  z_leave();
   errno = EADDRNOTAVAIL;
   return -1;
 }
 
 #if ENABLE_NETFILTER_TPROXY || ENABLE_IPFILTER_TPROXY
+
+#if ENABLE_NETFILTER_TPROXY_V12_FALLBACK
+
+static gint map_sockopts[] = 
+{
+  [TPROXY_VERSION] = -1,
+  [TPROXY_ASSIGN] = IP_TPROXY_ASSIGN,
+  [TPROXY_UNASSIGN] = IP_TPROXY_UNASSIGN,
+  [TPROXY_QUERY] = IP_TPROXY_QUERY,
+  [TPROXY_FLAGS] = IP_TPROXY_FLAGS,
+  [TPROXY_ALLOC] = -2,
+  [TPROXY_CONNECT] = -2
+};
+
+#elif ENABLE_IPFILTER_TPROXY
+
+static gint map_sockopts[] =
+{  [TPROXY_VERSION] = IP_TPROXY_VERSION,
+   [TPROXY_ASSIGN] = IP_TPROXY_ASSIGN,
+   [TPROXY_UNASSIGN] = IP_TPROXY_UNASSIGN,
+   [TPROXY_QUERY] = IP_TPROXY_QUERY,
+   [TPROXY_FLAGS] = IP_TPROXY_FLAGS,
+   [TPROXY_ALLOC] = IP_TPROXY_ALLOC,
+   [TPROXY_CONNECT] = IP_TPROXY_CONNECT
+};
+
+#endif
+
+gint
+z_tp_set_tproxy_opt(int fd, gint op, void *param, gint paramlen)
+{
+  
+  z_enter();
+
+#if ENABLE_NETFILTER_TPROXY
+  if (sysdep_tproxy == Z_SD_TPROXY_NETFILTER_V20)
+    {
+      struct in_tproxy tp20;
+
+      g_assert(sizeof(tp20.v) >= (guint) paramlen);
+      
+      tp20.op = op;
+      if (param)
+        memcpy(&tp20.v, param, paramlen);
+      z_leave();
+      return setsockopt(fd, SOL_IP, IP_TPROXY, &tp20, sizeof(tp20));
+    }
+#endif
+#if ENABLE_NETFILTER_TPROXY_V12_FALLBACK || ENABLE_IPFILTER_TPROXY
+#  if ENABLE_NETFILTER_TPROXY_V12_FALLBACK
+  else
+#  elif ENABLE_IPFILTER_TPROXY
+  if (sysdep_tproxy == Z_SD_TPROXY_IPF)
+#  endif /* ENABLE_NETFILTER_TPROXY_V12_FALLBACK */
+    {
+      gint ip_op = map_sockopts[op];
+      if (ip_op >= 0)
+        {
+          z_leave();
+          return setsockopt(fd, SOL_IP, ip_op, param, paramlen);
+        }
+      else if (ip_op == -1)
+        {
+          z_leave();
+          errno = ENOPROTOOPT;
+          return -1;
+        }
+      z_leave();
+      return 0;
+    }
+#endif /* ENABLE_NETFILTER_TPROXY_V12_FALLBACK || ENABLE_IPFILTER_TPROXY */
+  z_leave();
+  return -1;
+}
+
+gint
+z_tp_get_tproxy_opt(int fd, gint op, void *param, gint *paramlen)
+{
+  z_enter();
+
+#if ENABLE_NETFILTER_TPROXY
+  if (sysdep_tproxy == Z_SD_TPROXY_NETFILTER_V20) 
+    {
+      struct in_tproxy tp20;
+      socklen_t tp20size = sizeof(tp20);
+      gint res;
+      
+      g_assert(sizeof(tp20.v) >= (guint) *paramlen);
+      
+      tp20.op = op;
+      res = getsockopt(fd, SOL_IP, IP_TPROXY, &tp20, &tp20size);
+      g_assert(tp20size == sizeof(tp20));
+      if (res >= 0)
+        memcpy(param, &tp20.v, *paramlen);
+      z_leave();
+      return res;
+    }
+#endif
+#if ENABLE_NETFILTER_TPROXY_V12_FALLBACK || ENABLE_IPFILTER_TPROXY
+#  if ENABLE_NETFILTER_TPROXY_V12_FALLBACK
+  else
+#  elif ENABLE_IPFILTER_TPROXY
+  if (sysdep_tproxy == Z_SD_TPROXY_IPF)
+#  endif /* ENABLE_NETFILTER_TPROXY_V12_FALLBACK */
+    {
+      gint ip_op = map_sockopts[op];
+      if (ip_op >= 0)
+        {
+          z_leave();
+          return getsockopt(fd, SOL_IP, ip_op, param, paramlen);
+        }
+      else if (ip_op == -1)
+        {
+          z_leave();
+          errno = ENOPROTOOPT;
+          return -1;
+        }
+      z_leave();
+      return 0;
+    }
+#endif /* ENABLE_NETFILTER_TPROXY_V12_FALLBACK || ENABLE_IPFILTER_TPROXY */
+  z_leave();
+  return -1;
+}
+
+/*
+ * Assign to foreign address
+ */
+int
+z_tp_assign(int fd, in_addr_t faddr, guint16 fport)
+{
+  struct in_tproxy_addr itpa;
+  int ret;
+
+  z_enter();  
+  itpa.faddr.s_addr = faddr;
+  itpa.fport = fport;
+  
+  ret = z_tp_set_tproxy_opt(fd, TPROXY_ASSIGN, &itpa, sizeof(itpa));
+  
+  z_leave();
+  return ret;
+}
+
+int
+z_tp_set_flags(int fd, int flags)
+{
+  int ret;
+  
+  z_enter();
+  ret = z_tp_set_tproxy_opt(fd, TPROXY_FLAGS, &flags, sizeof(flags));
+  z_leave();
+  return ret;
+}
+
+int
+z_tp_get_flags(int fd, int *flags)
+{
+  socklen_t flagslen = sizeof(*flags);
+  int ret;
+  
+  z_enter();
+  ret = z_tp_get_tproxy_opt(fd, TPROXY_FLAGS, flags, &flagslen);
+  z_leave();
+  return ret;
+}
+
+int
+z_tp_query(int fd, in_addr_t *faddr, guint16 *fport)
+{
+  struct in_tproxy_addr itpa;
+  socklen_t itplen;
+  int ret = -1;
+
+  z_enter();
+  itplen = sizeof(itpa);
+  ret = z_tp_get_tproxy_opt(fd, TPROXY_QUERY, &itpa, &itplen);
+  if (ret != -1)
+    {
+      if (faddr)
+        *faddr = itpa.faddr.s_addr;
+  
+      if (fport)
+        *fport = itpa.fport;
+    }
+  z_leave();
+  return ret;
+}
+
+int
+z_tp_connect(int fd, in_addr_t faddr, guint16 fport)
+{
+  struct in_tproxy_addr itpa;
+  int ret;
+  
+  z_enter();
+  itpa.fport = fport;
+  itpa.faddr.s_addr = faddr;
+  ret = z_tp_set_tproxy_opt(fd, TPROXY_CONNECT, &itpa, sizeof(itpa));
+  z_leave();
+  return ret;
+}
+
+int
+z_tp_alloc(int fd)
+{
+  int ret;
+  
+  z_enter();
+  ret = z_tp_set_tproxy_opt(fd, TPROXY_ALLOC, NULL, 0);
+  z_leave();
+  return ret;
+}
+
 static gint
 z_do_tp_bind(gint fd, struct sockaddr *sa, socklen_t salen, guint32 sock_flags)
 {
-  struct in_tproxy itp;
-  socklen_t itplen = sizeof(itp);
   struct sockaddr_in *sinp = (struct sockaddr_in *) sa;
-    
+  
+  z_enter();
   if (sa->sa_family != AF_INET)
     return z_do_ll_bind(fd, sa, salen, sock_flags);
   
@@ -126,40 +351,61 @@
           ((struct sockaddr_in *) sa)->sin_addr.s_addr != 0)
         {
           /* we don't want NAT, only that -m tproxy matches our session */
-          itp.itp_fport = 0;
-          itp.itp_faddr.s_addr = 0;
-          if (setsockopt(fd, SOL_IP, IP_TPROXY_ASSIGN, &itp, itplen) == -1)
+          if (z_tp_assign(fd, 0, 0) == -1)
     	    {
     	      /*LOG
-    	        This message attempt when setsockopt() syscall failed
-    	        for the given reason.
+    	        This message indicates that setsockopt() syscall failed for
+		the given reason.  It is likely that your kernel does not
+		have tproxy support.
     	       */
-              z_log(NULL, CORE_ERROR, 3, "Error in setsockopt(SOL_IP, IP_TPROXY_ASSIGN), netfilter-tproxy support required; fd='%d', error='%m'", fd);
+              z_log(NULL, CORE_ERROR, 3, "Error in set_tproxy_opt(TPROXY_ASSIGN), netfilter-tproxy support required; fd='%d', error='%m'", fd);
+              z_leave();
               return 0;
             }
         }
+      z_leave();
       return 0;
     }
   else if (errno != EADDRNOTAVAIL)
-    return -1;
+    {
+      z_leave();
+      return -1;
+    }
     
   /* we couldn't bind because the address was not available, try transparent proxy tricks */
+  
+  /*
+   * NOTE: this code depends on Netfilter/TProxy behaviour, that is it
+   * assumes that the NAT code will try to match the NATed port with the
+   * original source port.
+   *
+   * 'loose' binding means that we don't really care about the specific port
+   * chosen, we only want to make sure that privileged port remains
+   * privileged on the server side. In this case the autobind port is bound
+   * appropriately and the NAT code will choose a matching port when
+   * calculating the SNAT mapping.
+   * 
+   * Otherwise we are absolutely sure that we want a specific port, even if
+   * it clashes. In this case it does not matter what our autobind port is,
+   * we specify a single foreign port as solution.
+   */
+  
   if (z_tp_autobind(fd, !(sock_flags & ZSF_LOOSE_BIND) ? 0 : ntohs(sinp->sin_port)) == -1)
     {
       /* autobind was not successful either */
+      z_leave();
       return -1;
     }
-  itp.itp_fport = (sock_flags & ZSF_LOOSE_BIND) ? 0 : sinp->sin_port;
-  itp.itp_faddr = ((struct sockaddr_in *) sa)->sin_addr;
-  if (setsockopt(fd, SOL_IP, IP_TPROXY_ASSIGN, &itp, itplen) == -1)
+  if (z_tp_assign(fd, sinp->sin_addr.s_addr, (sock_flags & ZSF_LOOSE_BIND) ? 0 : sinp->sin_port) == -1) 
     {
       /*LOG
-        This message attempt when setsockopt() syscall failed
-        for the given reason.
+        This message indicates that setsockopt() syscall failed for the given reason.
        */
       z_log(NULL, CORE_ERROR, 3, "Error in setsockopt(SOL_IP, IP_TPROXY_ASSIGN), netfilter-tproxy support required; fd='%d', error='%m'", fd);
+      z_leave();
       return -1;
     }
+  z_leave();
   return 0;
 }
 
@@ -167,7 +413,6 @@
 z_do_tp_listen(gint fd, gint backlog, guint32 sock_flags)
 {
   unsigned int flags;
-  socklen_t flagslen = sizeof(flags);
   
   z_enter();
   if (z_do_ll_listen(fd, backlog, !!(sock_flags & ZSF_ACCEPT_ONE)) == -1)
@@ -175,25 +420,18 @@
       z_leave();
       return -1;
     }
-  if (getsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &flags, &flagslen) == -1)
+  if (z_tp_get_flags(fd, &flags) == -1)
     {
       /* this is not a real problem, as it might mean that this socket is
          a unix domain socket */
       z_leave();
       return 0;
     }
-  if (flags & ITP_MARK)
-    {
-      z_leave();
-      return 0;
-    }
-    
   flags = ITP_LISTEN | ((sock_flags & ZSF_ACCEPT_ONE) ? ITP_ONCE : 0);
-  if (setsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &flags, sizeof(flags)) == -1)
+  if (z_tp_set_flags(fd, flags) == -1)
     {
       /*LOG
-        This message attempt when setsockopt() syscall failed
-        for the given reason.
+        This message indicates that setsockopt() syscall failed for the given reason.
        */
       z_log(NULL, CORE_ERROR, 3, "Error in setsockopt(SOL_IP, IP_TPROXY_FLAGS), netfilter-tproxy support required; fd='%d', error='%m'", fd);
       z_leave();
@@ -207,19 +445,25 @@
 z_do_tp_connect(gint fd, struct sockaddr *sa, socklen_t salen, guint32 sock_flags G_GNUC_UNUSED)
 {
   unsigned int flags;
-  struct in_tproxy itp;
-  socklen_t itplen = sizeof(itp);
   
-  if (getsockopt(fd, SOL_IP, IP_TPROXY_QUERY, &itp, &itplen) == -1)
+  if (sa->sa_family != AF_INET || z_tp_query(fd, NULL, NULL) == -1)
     {
       return z_do_ll_connect(fd, sa, salen, sock_flags);
     }
+  if (z_tp_connect(fd, ((struct sockaddr_in *) sa)->sin_addr.s_addr, ((struct sockaddr_in *) sa)->sin_port) == -1)
+    {
+      /*LOG
+        This message indicates that setsockopt() syscall failed for the given reason.
+       */
+      z_log(NULL, CORE_ERROR, 3, "Error in setsockopt(SOL_IP, IP_TPROXY_CONNECT), netfilter-tproxy support required; fd='%d', error='%m'", fd);
+      return -1;
+    }
+  
   flags = ITP_CONNECT | ITP_ONCE;
-  if (setsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &flags, sizeof(flags)) == -1)
+  if (z_tp_set_flags(fd, flags) == -1) 
     {
       /*LOG
-        This message attempt when setsockopt() syscall failed
-        for the given reason.
+        This message indicates that setsockopt() syscall failed for the given reason.
        */
       z_log(NULL, CORE_ERROR, 3, "Error in setsockopt(SOL_IP, IP_TPROXY_FLAGS), netfilter-tproxy support required; fd='%d', error='%m'", fd);
       return -1;
@@ -266,11 +510,15 @@
 void
 z_ipf_tproxy_init(void)
 {
-  ipnat_fd = open(IPL_NAT, O_RDONLY);
+  ipnat_fd = open(IPNAT_NAME, O_RDONLY);
 
   if (ipnat_fd < 0)
     {
-      z_log(NULL, CORE_ERROR, 3, "Error opening ipnat device, transparency will not be supported; dev='%s', error='%m'", IPL_NAT);
+      /*LOG
+	This message indicates that Zorp was unable to open the ipnat device.
+	It is likely that ipfilter is not installed correctly, please contact your Zorp support for assistance.
+       */
+      z_log(NULL, CORE_ERROR, 3, "Error opening ipnat device, transparency will not be supported; dev='%s', error='%m'", IPNAT_NAME);
     }
 }
 
@@ -281,8 +529,22 @@
 }
 
 #if 1
+
+struct ipfobj64 {
+  u_32_t  ipfo_rev;               /* IPFilter version number */
+  u_32_t  ipfo_size;              /* size of object at ipfo_ptr */
+  struct {
+    void *p_high;
+    void *p_low;
+  } ipfo_ptr;
+  int     ipfo_type;              /* type of object being pointed to */
+  int     ipfo_offset;            /* bytes from ipfo_ptr where to start */
+  u_char  ipfo_xxxpad[32];        /* reserved for future use */
+};
 /* try to fallback to the 64 bit version */
-#define SIOCGNATL64 _IOWRN('r', 63, 8)
+#define SIOCGNATL64 _IOWR('r', 63, struct ipfobj64)
+#define IPFILTER_VERSION        4010100
+
 #endif
 
 
@@ -291,7 +553,8 @@
 {
   struct sockaddr_in local, peer;
   int len = sizeof(struct sockaddr_in);
-  natlookup_t nl, *nlp = &nl;
+  natlookup_t nl;
+  ipfobj_t obj;
   int rc;
 
   if (*salen < sizeof(struct sockaddr_in))
@@ -326,26 +589,34 @@
   nl.nl_outip = peer.sin_addr;
   nl.nl_outport = peer.sin_port;
   nl.nl_flags = IPN_TCP;
+  
+  memset(&obj, 0, sizeof(obj));
+  obj.ipfo_rev = IPFILTER_VERSION;
+  obj.ipfo_size = sizeof(nl);
+  obj.ipfo_type = IPFOBJ_NATLOOKUP;
+  obj.ipfo_ptr = (void *) &nl;
+          
   /* first try the native SIOCGNATL value */
-  rc = ioctl(ipnat_fd, SIOCGNATL, &nlp);
+  rc = ioctl(ipnat_fd, SIOCGNATL, &obj);
 
 #if 1
   if (rc < 0)
     {
-      struct
-      {
-        void *p_high;
-        void *p_low;
-      } nlp64;  
-
+      struct ipfobj64 obj64;
+      
       /* NOTE: this is a gross hack, it works on big-endian machines only, 
        * and as IPFilter is only supported for Solaris now, and it is also
        * the only platform using 64/32 bit kernel/userlands this is currently
        * not a problem */
 
-      nlp64.p_low = &nl;
-      nlp64.p_high = NULL;
-      rc = ioctl(ipnat_fd, SIOCGNATL64, &nlp64);
+      memset(&obj64, 0, sizeof(obj64));
+      obj64.ipfo_rev = IPFILTER_VERSION;
+      obj64.ipfo_size = sizeof(nl);
+      obj64.ipfo_type = IPFOBJ_NATLOOKUP;
+      obj64.ipfo_ptr.p_low = (void *) &nl;
+      obj64.ipfo_ptr.p_high = NULL;
+      rc = ioctl(ipnat_fd, SIOCGNATL64, &obj64);
+
     }
 #endif
 
@@ -372,23 +643,39 @@
 static gint
 z_do_tp_getsockname(gint fd, struct sockaddr *sa, socklen_t *salen, guint32 sock_flags)
 {
-  struct in_tproxy itp;
-  socklen_t itplen = sizeof(itp);
+  in_addr_t faddr;
+  guint16 fport;
   struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+  gboolean allocated = FALSE;
   
-  if (getsockopt(fd, SOL_IP, IP_TPROXY_QUERY, &itp, &itplen) == -1)
-    {
-      return z_do_ll_getsockname(fd, sa, salen, sock_flags);
-    }
-  if (*salen < sizeof(*sin))
+  do
     {
-      errno = EFAULT;
-      return -1;
+      if (z_tp_query(fd, &faddr, &fport) == -1) //getsockopt(fd, SOL_IP, IP_TPROXY_QUERY, &itp, &itplen) == -1)
+        {
+          return z_do_ll_getsockname(fd, sa, salen, sock_flags);
+        }
+      if (*salen < sizeof(*sin))
+        {
+          errno = EFAULT;
+          return -1;
+        }
+      sin->sin_family = AF_INET;
+      sin->sin_addr.s_addr = faddr;
+      sin->sin_port = fport;
+      *salen = sizeof(*sin);
+      if (sin->sin_port == 0 && !allocated)
+        {
+          allocated = TRUE;
+          if (z_tp_alloc(fd) == -1) //setsockopt(fd, SOL_IP, IP_TPROXY_ALLOC, NULL, 0) == -1)
+            {
+              z_log(NULL, CORE_ERROR, 3, "Error in setsockopt(SOL_IP, IP_TPROXY_ALLOC), netfilter-tproxy support required; fd='%d', error='%m'", fd);
+              return -1;
+            }
+        }
+      else
+        break;
     }
-  sin->sin_family = AF_INET;
-  sin->sin_addr = itp.itp_faddr;
-  sin->sin_port = itp.itp_fport;
-  *salen = sizeof(*sin);  
+  while (1);
   return 0;
 }
 
@@ -407,19 +694,24 @@
 #endif
 
 gboolean
-z_tp_socket_init(gint sysdep_tproxy)
+z_tp_socket_init(gint sysdep_tproxyp)
 {
   /* Linux22 doesn't need any magic */
   gboolean res = TRUE;
+  
+  sysdep_tproxy = sysdep_tproxyp;
 
 #if ENABLE_NETFILTER_TPROXY || ENABLE_IPFILTER_TPROXY
-  if (sysdep_tproxy == Z_SD_TPROXY_NETFILTER || sysdep_tproxy == Z_SD_TPROXY_IPF)
+  if (sysdep_tproxy == Z_SD_TPROXY_NETFILTER_V12 || sysdep_tproxy == Z_SD_TPROXY_NETFILTER_V20 || sysdep_tproxy == Z_SD_TPROXY_IPF)
     {
       gint fd;
       
       fd = socket(AF_INET, SOCK_STREAM, 0);
       if (!auto_bind_ip || z_tp_autobind(fd, 0) == -1)
         {
+	  /*LOG
+	    This message indicates that Zorp was unable to bind to the dummy interface.
+	   */
           z_log(NULL, CORE_ERROR, 3, "Binding to dummy interface failed, please create one and pass --autobind-ip parameter; autobind='%s'", auto_bind_ip);
           res = FALSE;
         }
@@ -436,6 +728,10 @@
 #endif
   if (sysdep_tproxy != Z_SD_TPROXY_LINUX22)
     {
+      /*LOG
+	This message indicates that the required transparency support was not found.
+	Check your kernel configuration, or please contact your Zorp support for assistance.
+       */
       z_log(NULL, CORE_ERROR, 0, "Required transparency support not compiled in (TCP); sysdep_tproxy='%d'", sysdep_tproxy);
       res = FALSE;
     }
Index: zorp-core/lib/zorp/sysdep.h
diff -u zorp-core/lib/zorp/sysdep.h:1.7.2.3 zorp-core/lib/zorp/sysdep.h:1.7.2.4
--- zorp-core/lib/zorp/sysdep.h:1.7.2.3	Wed Sep 10 19:41:35 2003
+++ zorp-core/lib/zorp/sysdep.h	Mon Nov  8 17:56:34 2004
@@ -3,7 +3,7 @@
  * Copyright (c) 2000, 2001 BalaBit IT Ltd, Budapest, Hungary
  * All rights reserved.
  *
- * $Id: sysdep.h,v 1.7.2.3 2003/09/10 17:41:35 bazsi Exp $
+ * $Id: sysdep.h,v 1.7.2.4 2004/11/08 16:56:34 sasa Exp $
  *
  ***************************************************************************/
 
@@ -12,9 +12,10 @@
 
 #include <zorp/zorp.h>
 
-#define Z_SD_TPROXY_LINUX22   1
-#define Z_SD_TPROXY_NETFILTER 2
-#define Z_SD_TPROXY_IPF       3
+#define Z_SD_TPROXY_LINUX22       1
+#define Z_SD_TPROXY_NETFILTER_V12 2
+#define Z_SD_TPROXY_IPF           3
+#define Z_SD_TPROXY_NETFILTER_V20 4
 
 gboolean z_sysdep_init(const gchar *sysdep_tproxy_arg);
 void z_sysdep_destroy(void);
Index: zorp-core/lib/zorp/tpsocket.h
diff -u zorp-core/lib/zorp/tpsocket.h:1.5.4.2 zorp-core/lib/zorp/tpsocket.h:1.5.4.3
--- zorp-core/lib/zorp/tpsocket.h:1.5.4.2	Fri Feb  6 13:35:22 2004
+++ zorp-core/lib/zorp/tpsocket.h	Mon Nov  8 17:56:34 2004
@@ -3,7 +3,7 @@
  * Copyright (c) 2000, 2001, 2002 BalaBit IT Ltd, Budapest, Hungary
  * All rights reserved.
  *
- * $Id: tpsocket.h,v 1.5.4.2 2004/02/06 12:35:22 bazsi Exp $
+ * $Id: tpsocket.h,v 1.5.4.3 2004/11/08 16:56:34 sasa Exp $
  *
  * Author  : Bazsi
  * Auditor :
@@ -21,4 +21,12 @@
 
 gboolean z_tp_socket_init(gint sysdep_tproxy);
 
+int z_tp_assign(int fd, in_addr_t faddr, guint16 fport);
+int z_tp_set_flags(int fd, int flags);
+int z_tp_get_flags(int fd, int *flags);
+int z_tp_connect(int fd, in_addr_t faddr, guint16 fport);
+int z_tp_query(int fd, in_addr_t *faddr, guint16 *fport);
+int z_tp_alloc(int fd);
+
+
 #endif

--=-wz+Dm4yNxpJqhUwc1bMm--