diff -urN vpnclient.orig/GenDefs.h vpnclient/GenDefs.h
--- vpnclient.orig/GenDefs.h	2007-08-22 20:30:31.000000000 +0100
+++ vpnclient/GenDefs.h	2008-06-19 22:25:00.000000000 +0100
@@ -105,6 +105,15 @@
 #define _INTPTR_T_DEFINED
 #endif
 
+/* uintptr_t has been defined in include/linux/types.h in 2.6.24.
+ * No need to define it here again (will only lead to compile errors)
+ *
+ * by Alexander Griesser <work@tuxx-home.at>, 2008-01-11
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#define _UINTPTR_T_DEFINED
+#endif
+
 #ifndef _UINTPTR_T_DEFINED
 #if defined(_LP64)
 #warning 64 bit
diff -urN vpnclient.orig/Makefile vpnclient/Makefile
--- vpnclient.orig/Makefile	2007-08-22 20:30:31.000000000 +0100
+++ vpnclient/Makefile	2008-06-19 23:26:26.000000000 +0100
@@ -12,7 +12,9 @@
 SOURCE_OBJS := linuxcniapi.o frag.o IPSecDrvOS_linux.o interceptor.o linuxkernelapi.o
 
 ifeq ($(SUBARCH),x86_64)
-CFLAGS += -mcmodel=kernel -mno-red-zone
+# Must NOT fiddle with CFLAGS
+# CFLAGS += -mcmodel=kernel -mno-red-zone
+EXTRA_CFLAGS += -mcmodel=kernel -mno-red-zone
 NO_SOURCE_OBJS := libdriver64.so
 else
 NO_SOURCE_OBJS := libdriver.so
diff -urN vpnclient.orig/frag.c vpnclient/frag.c
--- vpnclient.orig/frag.c	2007-08-22 20:30:31.000000000 +0100
+++ vpnclient/frag.c	2008-07-06 23:48:52.000000000 +0100
@@ -22,7 +22,9 @@
 #include "frag.h"
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-#define SKB_IPHDR(skb) ((struct iphdr*)skb->network_header)
+/* 2.6.22 added an inline function for 32-/64-bit usage here, so use it.
+ */
+#define SKB_IPHDR(skb) ((struct iphdr*)skb_network_header)
 #else
 #define SKB_IPHDR(skb) skb->nh.iph
 #endif
diff -urN vpnclient.orig/interceptor.c vpnclient/interceptor.c
--- vpnclient.orig/interceptor.c	2007-08-22 20:30:31.000000000 +0100
+++ vpnclient/interceptor.c	2008-07-06 23:45:13.000000000 +0100
@@ -28,6 +28,10 @@
 #include <linux/udp.h>
 #include <net/protocol.h>
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#include <net/net_namespace.h>
+#endif
+
 #include "linux_os.h"
 
 #include "vpn_ioctl_linux.h"
@@ -48,7 +52,7 @@
 unsigned long rx_bytes;
 
 /*methods of the cipsec network device*/
-static int interceptor_init(struct net_device *);
+static void interceptor_init(struct net_device *);
 static struct net_device_stats *interceptor_stats(struct net_device *dev);
 static int interceptor_ioctl(struct net_device *dev, struct ifreq *ifr,
                              int cmd);
@@ -107,18 +111,27 @@
 
 BINDING Bindings[MAX_INTERFACES];
 
+/* 2.6.24 handles net_devices a little bit different
+ *
+ * by Alexander Griesser <work@tuxx-home.at>, 2008-01-11
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+static struct net_device* interceptor_dev;
+#else
 static struct net_device interceptor_dev = {
     .name = interceptor_name,
     .init = interceptor_init
 };
+#endif
+
 static struct notifier_block interceptor_notifier = {
     .notifier_call = handle_netdev_event,
 };
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-static int
+static void
 #else
-static int __init
+static void __init
 #endif
 interceptor_init(struct net_device *dev)
 {
@@ -133,8 +146,6 @@
     dev->flags |= IFF_NOARP;
     dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
     kernel_memset(dev->broadcast, 0xFF, ETH_ALEN);
-
-    return 0;
 }
 
 static struct net_device_stats *
@@ -362,8 +373,13 @@
 
     dp = NULL;
     num_target_devices = 0;
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-    for_each_netdev(dp)
+    for_each_netdev(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+                    &init_net,
+#endif
+                    dp)
 #else
     for (dp = dev_base; dp != NULL; dp = dp->next)
 #endif
@@ -630,19 +646,30 @@
 
     reset_inject_status(&pBinding->recv_stat);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-    if (skb->mac_header)
+/* 2.6.22 added an inline function for 32-/64-bit usage here, so use it.
+ */
+    if (skb_mac_header_was_set(skb))
 #else
     if (skb->mac.raw)
 #endif
     {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-        hard_header_len = skb->data - skb->mac_header;
+/* 2.6.22 added an inline function for 32-/64-bit usage here, so use it.
+ */
+        hard_header_len = skb->data - skb_mac_header(skb);
 #else
         hard_header_len = skb->data - skb->mac.raw;
 #endif
         if ((hard_header_len < 0) || (hard_header_len > skb_headroom(skb)))
         {
             printk(KERN_DEBUG "bad hh len %d\n", hard_header_len);
+
+            printk(KERN_DEBUG "bad hh len %d, mac: %d, data: %p, head: %p\n",
+                hard_header_len,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+                skb->mac_header,    /* actualy ptr in 32-bit */
+#else
+                skb->mac.raw,
+#endif
+                skb->data,
+                skb->head);
+
             hard_header_len = 0;
         }
     }
@@ -657,7 +684,9 @@
     {
     case ETH_HLEN:
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-        CniNewFragment(ETH_HLEN, skb->mac_header, &MacHdr, CNI_USE_BUFFER);
+/* 2.6.22 added an inline function for 32-/64-bit usage here, so use it.
+ */
+        CniNewFragment(ETH_HLEN, skb_mac_header(skb), &MacHdr, CNI_USE_BUFFER);
 #else
         CniNewFragment(ETH_HLEN, skb->mac.raw, &MacHdr, CNI_USE_BUFFER);
 #endif
@@ -775,7 +804,9 @@
 #endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     reset_inject_status(&pBinding->send_stat);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-    hard_header_len = skb->network_header - skb->data;
+/* 2.6.22 added an inline function for 32-/64-bit usage here, so use it.
+ */
+    hard_header_len = skb_network_header(skb) - skb->data;
 #else
     hard_header_len = skb->nh.raw - skb->data;
 #endif
@@ -919,15 +950,29 @@
 
     rc = CniPluginLoad(&pcDeviceName, &PCNICallbackTable);
 
+/* 2.6.24 needs to allocate each netdevice before registering it, otherwise
+ * the kernel BUG()s.
+ *
+ * by Alexander Griesser <work@tuxx-home.at>, 2008-01-11
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+    if(! (interceptor_dev = alloc_netdev(sizeof(struct net_device), interceptor_name, interceptor_init)))
+      return 0;
+#endif
+
     if (CNI_IS_SUCCESS(rc))
     {
 
         CNICallbackTable = *PCNICallbackTable;
         CniPluginDeviceCreated();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+	if ((status = register_netdev(interceptor_dev)) != 0)
+#else
         if ((status = register_netdev(&interceptor_dev)) != 0)
+#endif
         {
             printk(KERN_INFO "%s: error %d registering device \"%s\".\n",
-                   LINUX_VPN_IFNAME, status, interceptor_dev.name);
+                   LINUX_VPN_IFNAME, status, interceptor_name);
             CniPluginUnload();
 
         }
@@ -947,7 +992,11 @@
     cleanup_frag_queue();
     CniPluginUnload();
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+    unregister_netdev(interceptor_dev);
+#else
     unregister_netdev(&interceptor_dev);
+#endif
     unregister_netdevice_notifier(&interceptor_notifier);
 
     return;
diff -urN vpnclient.orig/linuxcniapi.c vpnclient/linuxcniapi.c
--- vpnclient.orig/linuxcniapi.c	2007-08-22 20:30:31.000000000 +0100
+++ vpnclient/linuxcniapi.c	2008-07-06 23:46:06.000000000 +0100
@@ -338,8 +338,12 @@
     skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-    skb->network_header = (sk_buff_data_t) skb->data;
-    skb->mac_header = (sk_buff_data_t)pMac;
+/* 2.6.22 added an inline function for 32-/64-bit usage here, so use it.
+ * We have to use (pMac - skb->data) to get an offset.
+ * We need to cast ptrs to byte ptrs and take the difference.
+ */
+    skb_reset_network_header(skb);
+    skb_set_mac_header(skb, (int)((void *)pMac - (void *)skb->data));
 #else
     skb->nh.iph = (struct iphdr *) skb->data;
     skb->mac.raw = pMac;
@@ -478,8 +482,12 @@
     skb->dev = pBinding->pDevice;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-    skb->mac_header = (sk_buff_data_t)pMac;
-    skb->network_header = (sk_buff_data_t)pIP;
+/* 2.6.22 added an inline function for 32-/64-bit usage here, so use it.
+ * We have to use (pIP/pMac - skb->data) to get an offset.
+ * We need to cast ptrs to byte ptrs and take the difference.
+ */
+    skb_set_mac_header(skb, (int)((void *)pMac - (void *)skb->data));
+    skb_set_network_header(skb, (int)((void *)pIP - (void *)skb->data));
 #else
     skb->mac.raw = pMac;
     skb->nh.raw = pIP;
@@ -487,8 +495,13 @@
 
     /*ip header length is in 32bit words */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-    skb->transport_header = (sk_buff_data_t)
-      (pIP + (((struct iphdr*)(skb->network_header))->ihl * 4));
+/* 2.6.22 added an inline function for 32-/64-bit usage here, so use it.
+ * We have to use (pIP - skb->data) to get an offset.
+ * We need to cast ptrs to byte ptrs and take the difference.
+ */
+    skb_set_transport_header(skb,
+        ((int)((void *)pIP - (void *)skb->data) +
+           (((struct iphdr*)(skb_network_header(skb)))->ihl * 4)));
 #else
     skb->h.raw = pIP + (skb->nh.iph->ihl * 4);
 #endif
diff -urN vpnclient.orig/linuxkernelapi.c vpnclient/linuxkernelapi.c
--- vpnclient.orig/linuxkernelapi.c	2007-08-22 20:30:31.000000000 +0100
+++ vpnclient/linuxkernelapi.c	2008-06-19 23:24:46.000000000 +0100
@@ -9,7 +9,10 @@
     void*rc = kmalloc(size, GFP_ATOMIC);
     if(NULL == rc)
     {
-        printk("<1> os_malloc size %d failed\n",size);
+/* Allow for 32- or 64-bit size        
+ *        printk("<1> os_malloc size %d failed\n",size);
+ */
+        printk("<1> os_malloc size %ld failed\n", (long)size);
     }
 
     return rc;

