From: rct@merkin.csap.af.mil (Bob Tracy - TDS)
Subject: ENskip patches for Linux-2.1.10[2-5]
To: skip-info@skip.org
Date: Mon, 8 Jun 1998 15:16:17 -0500 (CDT)
X-Mailer: ELM [version 2.4ME+ PL40 (25)]
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=ELM897336977-404-0_
Content-Transfer-Encoding: 7bit
Sender: owner-skip-info@rt.com
Precedence: bulk
Content-Length: 34674
Status: O


--ELM897336977-404-0_
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

Here are the latest patch sets for ENskip-0.67 and the Linux kernel
source tree.  The ENskip-0.67 patch set now includes a missing patch
for cert/suncert/lib/Bigint.C that should have been there from day
one for glibc-2 people: sorry!  There is also an improved patch for
linux/interface.c that should compile much more cleanly than the
previous version.  Note that the ENskip-0.67 patch set works for Linux
2.1.92 and later with glibc-2 (at least).  The kernel patch set is a
bit more restricted in its applicability: 2.1.10[2-5].

We're coming into the home stretch as far as the last release of
Linux-2.1.  Now would be a real good time for interested parties to
test this code, i.e., *before* 2.2 is released.  I do *not* expect
the kernel patch set to change significantly between now and the
release of 2.2 unless someone uncovers a problem that has gone
unnoticed for a long time.  (Hey, it happens!)

-- 
Bob Tracy               | "Microsoft's biggest and most dangerous
Trident Data Systems    |  contribution to the software industry may
AFIWC/TIPER             |  be the degree to which it has lowered user
rct@merkin.csap.af.mil  |  expectations."	- Esther Schindler
                                                  OS/2 Magazine

--ELM897336977-404-0_
Content-Type: text/plain; charset=US-ASCII
Content-Disposition: attachment; filename=patch105_ENskip
Content-Description: /usr/src/linux/.patch/patch105_ENskip
Content-Transfer-Encoding: 7bit

--- linux/include/net/sock.h.orig	Fri May 15 15:28:35 1998
+++ linux/include/net/sock.h	Fri May 15 15:32:09 1998
@@ -505,6 +505,14 @@
   	int			(*backlog_rcv) (struct sock *sk,
 						struct sk_buff *skb);  
 	void                    (*destruct)(struct sock *sk);
+
+#ifdef CONFIG_NET_SECURITY
+  /*
+   *	Security
+   */
+	short			authentication;
+	short			encryption;
+#endif
 };
 
 /* IP protocol blocks we attach to sockets.
--- linux/net/core/sock.c.orig	Fri May 15 15:28:00 1998
+++ linux/net/core/sock.c	Fri May 15 15:32:09 1998
@@ -285,6 +285,16 @@
 			sk->bsdism = valbool;
 			break;
 
+#ifdef CONFIG_NET_SECURITY
+		case SO_SECURITY_AUTHENTICATION:
+			sk->authentication = val;
+			break;
+
+		case SO_SECURITY_ENCRYPTION_TRANSPORT:
+			sk->encryption = val;
+			break;
+#endif
+
 		case SO_PASSCRED:
 			sock->passcred = valbool;
 			break;
@@ -435,6 +445,16 @@
 			v.val = sk->bsdism;
 			break;
 			
+#ifdef CONFIG_NET_SECURITY
+		case SO_SECURITY_AUTHENTICATION:
+			v.val = sk->authentication;
+			break;
+
+		case SO_SECURITY_ENCRYPTION_TRANSPORT:
+			v.val = sk->encryption;
+			break;
+#endif
+
 		case SO_RCVTIMEO:
 		case SO_SNDTIMEO:
 			lv=sizeof(struct timeval);
--- linux/net/ipv4/ip_forward.c.orig	Fri May 15 15:28:00 1998
+++ linux/net/ipv4/ip_forward.c	Fri May 15 15:32:09 1998
@@ -126,9 +126,10 @@
 	mtu = dev2->mtu;
 
 #ifdef CONFIG_NET_SECURITY
-	call_fw_firewall(PF_SECURITY, dev2, NULL, &mtu, NULL);
+	if (call_fw_firewall(PF_SECURITY, dev2, NULL, &mtu, NULL) < FW_ACCEPT)
+		return -1;
 #endif	
-	
+
 	/*
 	 *	In IP you never have to forward a frame on the interface that it 
 	 *	arrived upon. We now generate an ICMP HOST REDIRECT giving the route
@@ -137,6 +138,11 @@
 	if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr)
 		ip_rt_send_redirect(skb);
 	
+#ifdef CONFIG_NET_SECURITY
+	if (call_out_firewall(PF_SECURITY, dev2, NULL, (void *)2, &skb) < FW_ACCEPT)
+		return -1;
+#endif	
+
 	/*
 	 * We now may allocate a new buffer, and copy the datagram into it.
 	 * If the indicated interface is up and running, kick it.
--- linux/net/ipv4/ip_output.c.orig	Fri May 15 15:28:36 1998
+++ linux/net/ipv4/ip_output.c	Fri May 15 15:32:09 1998
@@ -74,6 +74,7 @@
 #include <linux/firewall.h>
 #include <linux/mroute.h>
 #include <linux/netlink.h>
+#include <linux/ipsec.h>
 
 /*
  *      Shall we try to damage output packets if routing dev changes?
@@ -99,7 +100,8 @@
 {
 	struct rtable *rt = (struct rtable *)skb->dst;
 	struct iphdr *iph;
-	
+	struct device *dev;
+
 	/* Build the IP header. */
 	if (opt)
 		iph=(struct iphdr *)skb_push(skb,sizeof(struct iphdr) + opt->optlen);
@@ -126,10 +128,24 @@
 		ip_options_build(skb, opt, daddr, rt, 0);
 	}
 
+	dev = rt->u.dst.dev;
+
+	if (call_out_firewall(PF_INET, dev, iph, NULL, &skb) < FW_ACCEPT)
+		goto drop;
+
 	ip_send_check(iph);
 
+#ifdef CONFIG_NET_SECURITY
+	if (call_out_firewall(PF_SECURITY, dev, NULL, (void *) 7, &skb) < FW_ACCEPT)
+		goto drop;
+#endif
+
 	/* Send it out. */
 	skb->dst->output(skb);
+	return;
+
+drop:
+	kfree_skb(skb);
 }
 
 int __ip_finish_output(struct sk_buff *skb)
@@ -294,6 +310,16 @@
 	if (call_out_firewall(PF_INET, dev, iph, NULL, &skb) < FW_ACCEPT) 
 		goto drop;
 
+#ifdef CONFIG_NET_SECURITY	
+	/* Add an IP checksum (must do this before SECurity because
+	 * of possible tunneling).
+	 */
+	ip_send_check(iph);
+	if (call_out_firewall(PF_SECURITY, dev, NULL, (void *) 4, &skb) < FW_ACCEPT)
+		goto drop;
+	iph = skb->nh.iph;
+	/* Don't update tot_len, as the dev->mtu is already decreased. */
+#endif
 	/* This can happen when the transport layer has segments queued
 	 * with a cached route, and by the time we get here things are
 	 * re-routed to a device with a different MTU than the original
@@ -316,9 +342,10 @@
 	if (tot_len > rt->u.dst.pmtu)
 		goto fragment;
 
+#ifndef CONFIG_NET_SECURITY
 	/* Add an IP checksum. */
 	ip_send_check(iph);
-
+#endif
 	skb->priority = sk->priority;
 	skb->dst->output(skb);
 	return;
@@ -382,6 +409,9 @@
 	int nfrags=0;
 	struct ip_options *opt = ipc->opt;
 	int df = htons(IP_DF);
+#ifdef CONFIG_NET_SECURITY
+	int fw_res;
+#endif
 
 	if (sk->ip_pmtudisc == IP_PMTUDISC_DONT ||
 		(rt->u.dst.mxlock&(1<<RTAX_MTU)))
@@ -540,6 +570,13 @@
 		if(!err && offset == 0 && 
 		   call_out_firewall(PF_INET, rt->u.dst.dev, skb->nh.iph, NULL, &skb) < FW_ACCEPT)
 			err = -EPERM;
+#ifdef CONFIG_NET_SECURITY
+		if ((fw_res=call_out_firewall(PF_SECURITY, rt->u.dst.dev, NULL, (void *) 6, &skb))<FW_ACCEPT)
+		{
+			if (fw_res != FW_QUEUE)
+				err= -EPERM;
+		}
+#endif		
 
 		if (err) { 
 			ip_statistics.IpOutDiscards++;
@@ -587,6 +624,9 @@
 	struct sk_buff *skb;
 	int df;
 	struct iphdr *iph;
+#ifdef CONFIG_NET_SECURITY
+	int fw_res;
+#endif
 
 	/*
 	 *	Try the simple case first. This leaves fragmented frames, and by
@@ -657,6 +697,16 @@
 
 	if(!err && call_out_firewall(PF_INET, rt->u.dst.dev, iph, NULL, &skb) < FW_ACCEPT) 
 		err = -EPERM;
+#ifdef CONFIG_NET_SECURITY
+	if ((fw_res=call_out_firewall(PF_SECURITY, rt->u.dst.dev, NULL, (void *) 5, &skb))<FW_ACCEPT)
+	{
+		kfree_skb(skb);
+		if (fw_res != FW_QUEUE)
+			return -EPERM;
+		else
+			return 0;
+	}
+#endif
 
 	if (err) { 
 		kfree_skb(skb);
--- linux/net/Config.in.orig	Fri May 15 15:28:01 1998
+++ linux/net/Config.in	Fri May 15 15:32:09 1998
@@ -10,6 +10,9 @@
   tristate 'Netlink device emulation' CONFIG_NETLINK_DEV
 fi
 bool 'Network firewalls' CONFIG_FIREWALL
+if [ "$CONFIG_FIREWALL" = "y" ]; then
+  bool 'Network security (ENskip support)' CONFIG_NET_SECURITY
+fi
 bool 'Network aliasing'  CONFIG_NET_ALIAS
 bool 'Socket Filtering'  CONFIG_FILTER
 tristate 'Unix domain sockets' CONFIG_UNIX
--- linux/net/netsyms.c.orig	Fri May 15 15:28:37 1998
+++ linux/net/netsyms.c	Fri May 15 15:32:09 1998
@@ -215,6 +215,7 @@
 #endif
 EXPORT_SYMBOL(ip_id_count);
 EXPORT_SYMBOL(ip_send_check);
+EXPORT_SYMBOL(ip_forward);
 EXPORT_SYMBOL(ip_fragment);
 EXPORT_SYMBOL(inet_family_ops);
 EXPORT_SYMBOL(in_aton);

--ELM897336977-404-0_
Content-Type: text/plain; charset=US-ASCII
Content-Disposition: attachment; filename=linux-2.1.92+glibc
Content-Description: /usr/src/cmd/ENskip-0.67b/.patch/linux-2.1.92+glibc
Content-Transfer-Encoding: 7bit

--- ENskip-0.67/Makefile.orig	Sun May 25 11:04:47 1997
+++ ENskip-0.67/Makefile	Thu Apr  9 16:34:17 1998
@@ -48,7 +48,8 @@
 FLAGS_linux_KERNEL = -fomit-frame-pointer -fno-strength-reduce -O2 -DKERNEL -D__KERNEL__ -DMODULE -Wall -pipe -I`pwd`/../linux -I/usr/src/linux/include
 FLAGS_linux_USER = -g -O2 -Wall -pipe -I/usr/include -I`pwd`/../skipd -I`pwd`/../linux -I/usr/src/linux/include
 FLAGS_linux_CERT = $(FLAGS_linux_USER)
-LIBS_linux_USER =
+# Add -lg++ for g++-2.8.1: use of libg++ is deprecated.
+LIBS_linux_USER = -lg++
 
 #if you are forced to use the SUN compiler
 #DIR_solaris = solaris
--- ENskip-0.67/linux/interface.c.orig	Wed Feb  5 15:37:14 1997
+++ ENskip-0.67/linux/interface.c	Fri Jun  5 15:02:53 1998
@@ -22,13 +22,14 @@
 #include "config.h"
 #define __NO_VERSION__
 #include <linux/module.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include <linux/ip.h>
-#include <linux/in.h>
+#include <linux/udp.h>
+#include <linux/icmp.h>
+#include <net/ip.h>
+#include <endian.h>
+#include "ip.h"			/* <netinet/ip.h> __USE_BSD section only */
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/inetdevice.h>
 #include <linux/firewall.h>
 #include <linux/string.h>
 #include <linux/ipsec.h>
@@ -54,7 +55,7 @@
 
 
 /* This function copies an skb, growing it to "size" bytes. 
-   Mostly derived from the Linux 2.0.25 skb_copy function. */
+   Mostly derived from the Linux 2.1.92 skb_copy function. */
 
 static struct sk_buff *skb_expand_copy(struct sk_buff *skb, int size)
 {
@@ -63,8 +64,6 @@
 
   /* Allocate the copy buffer */
 
-  IS_SKB(skb);
-
   n = alloc_skb(size, GFP_ATOMIC);
   if (n == NULL)
     return NULL;
@@ -80,33 +79,25 @@
 
   /* Copy the bytes */
   memcpy(n->head, skb->head, skb->end - skb->head);
-  n->link3   = NULL;
-  n->list    = NULL;
-  n->sk      = NULL;
-  n->when    = skb->when;
-  n->dev     = skb->dev;
-  n->h.raw   = skb->h.raw + offset;
-  n->mac.raw = skb->mac.raw + offset;
-  n->ip_hdr  = (struct iphdr *)(((char *)skb->ip_hdr) + offset);
-  n->saddr   = skb->saddr;
-  n->daddr   = skb->daddr;
-  n->raddr   = skb->raddr;
-  n->seq     = skb->seq;
-  n->end_seq = skb->end_seq;
-  n->ack_seq = skb->ack_seq;
-  n->acked   = skb->acked;
-  memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
-  n->used    = skb->used;
-  n->free    = 1;
-  n->arp     = skb->arp;
-  n->tries   = 0;
-  n->lock    = 0;
-  n->users   = 0;
-  n->pkt_type= skb->pkt_type;
-  n->stamp   = skb->stamp;
+  n->csum     = skb->csum;
+  n->list     = NULL;
+  n->sk       = NULL;
+  n->dev      = skb->dev;
+  n->priority = skb->priority;
+  n->protocol = skb->protocol;
+  n->dst      = dst_clone(skb->dst);
+  n->h.raw    = skb->h.raw + offset;
+  n->nh.raw   = skb->nh.raw + offset;
+  n->mac.raw  = skb->mac.raw + offset;
+  memcpy(n->cb, skb->cb, sizeof(skb->cb));
+  n->used     = skb->used;
+  n->is_clone = 0;
+  atomic_set(&n->users, 1);
+  n->pkt_type = skb->pkt_type;
+  n->stamp    = skb->stamp;
+  n->destructor = NULL;
+  n->security = skb->security;
 
-  IS_SKB(n);
-        
   return n;
 }
 
@@ -128,9 +119,9 @@
   /* first "segment descriptor" (the one and only we actually use) */
   mb->ms     = ms;
   /* offset == offset of IP header in data area */
-  mb->offset = (u_char *) skb->ip_hdr - skb->head;
+  mb->offset = (u_char *) skb->nh.iph - skb->head;
   /* len == length of IP packet */
-  mb->len    = ntohs(skb->ip_hdr->tot_len);
+  mb->len    = ntohs(skb->nh.iph->tot_len);
 
   /* ptr == pointer to the data area in first segment descriptor */
   ms->ptr = skb->head;
@@ -180,7 +171,7 @@
 int input_packet(struct firewall_ops *this, int pf, struct device *dev,
 		 void *phdr, void *arg, struct sk_buff **pskb)
 {
-  struct iphdr *ipp = (*pskb)->ip_hdr;
+  struct iphdr *ipp = (*pskb)->nh.iph;
   int tot_len = ntohs(ipp->tot_len);
   struct sk_buff *newm, *qskb;
   int result;
@@ -222,7 +213,7 @@
 
   }
 
-  if ((*pskb)->proto_priv[15] & RCV_SEC)
+  if ((*pskb)->security & RCV_SEC)
     return FW_SKIP;
 
   /* never change transparent UDP ports needed for discovery */
@@ -247,7 +238,7 @@
 
   save_flags(flags);
   cli();	
-	
+
   /* Clone the input skb. This operation locks the data of the input skb,
      so we can queue it. Be careful not to free the skb while it is queued! */
   qskb = newm = skb_clone(*pskb, GFP_ATOMIC);
@@ -265,11 +256,11 @@
   if (result == SKIP_PROCESSED) {
     /* nothing happened */
 
-    kfree_skb(newm, FREE_WRITE);
+    kfree_skb(newm);
     if (newm != qskb)
-      kfree_skb(qskb, FREE_WRITE);
+      kfree_skb(qskb);
 
-    newm->proto_priv[15] = RCV_SEC;
+    newm->security = RCV_SEC;
     retval = FW_SKIP;
   }
   else if (result > SKIP_PROCESSED) {
@@ -277,15 +268,15 @@
 
     /* fix up the skb pointers */
     newm->data      = BLKSTART(&newmb);
-    newm->ip_hdr    = (struct iphdr *) newm->data;
-    newm->len       = ntohs(newm->ip_hdr->tot_len);
+    newm->nh.iph    = (struct iphdr *) newm->data;
+    newm->len       = ntohs(newm->nh.iph->tot_len);
     newm->tail      = newm->data + newm->len;
     newm->protocol  = htons(ETH_P_IP);
     newm->ip_summed = 0;
-    newm->h.iph     = newm->ip_hdr;
+    newm->h.ipiph   = newm->nh.iph;
 
     /* and mark the skb as "authenticated"/"decrypted" */
-    newm->proto_priv[15] = ((result & SKIP_P_AUTH)    ? RCV_AUTH   : 0)
+    newm->security = ((result & SKIP_P_AUTH)    ? RCV_AUTH   : 0)
                          | ((result & SKIP_P_DECRYPT) ? RCV_CRYPT  : 0)
                          | ((result & SKIP_P_TUNNEL)  ? RCV_TUNNEL : 0)
                          | RCV_SEC;
@@ -293,7 +284,7 @@
     /* and feed the packet back into the input queue (must not switch
        skbs here, because we need the defragmentor) */
     if (newm != qskb)
-      kfree_skb(qskb, FREE_WRITE);
+      kfree_skb(qskb);
 
     netif_rx(newm); /* frees skb for us */
   } 
@@ -301,13 +292,13 @@
     /* the skb was queued */
 
     if (newm != qskb)
-      kfree_skb(newm, FREE_WRITE);
+      kfree_skb(newm);
   } else {
     /* bad packet, policy violation, unsupported protocol, etc. */
 
-    kfree_skb(newm, FREE_WRITE);
+    kfree_skb(newm);
     if (newm != qskb)
-      kfree_skb(qskb, FREE_WRITE);
+      kfree_skb(qskb);
   }
 
   restore_flags(flags);
@@ -327,7 +318,7 @@
 int output_packet(struct firewall_ops *dummy1, int pf, struct device *dev,
 		  void *dummy3, void *arg, struct sk_buff **pskb)
 {
-  struct iphdr *ipp = (*pskb)->ip_hdr;
+  struct iphdr *ipp = (*pskb)->nh.iph;
   int tot_len = ntohs(ipp->tot_len);
   struct sk_buff *newm, *qskb;
   int result;
@@ -344,7 +335,7 @@
   /* Recursion happens if the datagram has been fragmented:
      ip_queue_xmit -> skip -> ip_fragment -> ip_queue_xmit -> SKIP */
   
-  if ((*pskb)->proto_priv[15] & SND_SEC)
+  if ((*pskb)->security & SND_SEC)
     return FW_ACCEPT;
 
   /* this happens, too */
@@ -394,9 +385,9 @@
   if (result == SKIP_PROCESSED) {
     /* nothing happened - if not enskipped, we just say "OK" */ 
 
-    kfree_skb(newm, FREE_WRITE);
+    kfree_skb(newm);
     if (newm != qskb)
-      kfree_skb(qskb, FREE_WRITE);
+      kfree_skb(qskb);
 
     /* check user level policy */
     if (!((*pskb)->sk &&
@@ -404,7 +395,7 @@
           (*pskb)->sk->encryption     >= IPSEC_LEVEL_USE))) {
 
       /* Set marker in skb + accept packet */
-      (*pskb)->proto_priv[15] |= SND_SEC;
+      (*pskb)->security |= SND_SEC;
       retval = FW_SKIP;
     }
   } 
@@ -418,27 +409,27 @@
          (!(result & SKIP_P_ENCRYPT) &&
           (*pskb)->sk->encryption >= IPSEC_LEVEL_USE))) {
 
-      kfree_skb(newm, FREE_WRITE);
+      kfree_skb(newm);
       if (newm != qskb)
-        kfree_skb(qskb, FREE_WRITE);
+        kfree_skb(qskb);
     }
     else {
       /* fix up skb */
       newm->data      = BLKSTART(&newmb);
-      newm->ip_hdr    = (struct iphdr *) newm->data;
-      newm->len       = ntohs(newm->ip_hdr->tot_len);
+      newm->nh.iph    = (struct iphdr *) newm->data;
+      newm->len       = ntohs(newm->nh.iph->tot_len);
       newm->tail      = newm->data + newm->len;
       newm->protocol  = htons(ETH_P_IP);
       newm->ip_summed = 0;
-      newm->h.iph     = newm->ip_hdr;
+      newm->h.ipiph   = newm->nh.iph;
 
       newm->dev	    = dev;
 
       if (newm != qskb)
-        kfree_skb(qskb, FREE_WRITE);
+        kfree_skb(qskb);
 
       /* Set marker in skb */
-      newm->proto_priv[15] |= SND_SEC;
+      newm->security |= SND_SEC;
 
       interface_ship_out(newm);
 
@@ -449,7 +440,7 @@
     /* queued, will be fed back to us */
 
     if (newm != qskb)
-      kfree_skb(newm, FREE_WRITE);
+      kfree_skb(newm);
     
     qskb->dev = dev;
 
@@ -458,9 +449,9 @@
   else {
     /* bad packet/policy/etc. */
 
-    kfree_skb(newm, FREE_WRITE);
+    kfree_skb(newm);
     if (newm != qskb)
-      kfree_skb(qskb, FREE_WRITE);
+      kfree_skb(qskb);
   }
 
   restore_flags(flags);
@@ -500,7 +491,7 @@
 int packet_accept(struct firewall_ops *this, int pf, struct device *dev,
 	       void *phdr, void *arg, struct sk_buff **pskb)
 {
-  if ((*pskb)->proto_priv[15] & SND_SEC)
+  if ((*pskb)->security & SND_SEC)
     return FW_ACCEPT;
   else
     return FW_SKIP;
@@ -514,10 +505,32 @@
 
 static inline void interface_ship_out(struct sk_buff *skb)
 {
-  IS_SKB(skb);
+  /*
+  *  Not sure how to do this for 2.1.X.  ip_forward() will free skb
+  *  before returning non-zero, so for the first attempt we'll simply
+  *  call ip_forward() and be done with it.  N.B.: for 2.0.X, nothing
+  *  was done for the case where ip_forward() returned 0.
+  *
+  *  New for 2.1.X: ip_forward() cannot be told to leave the TTL alone,
+  *  so we'll increment it and recalculate the checksum before calling
+  *  ip_forward().  Alan says I can pass stuff out through the routing
+  *  code directly, but I'm not savvy enough to see how that might be
+  *  done.	--rct
+  */
+  struct iphdr *iph;
+  unsigned short check;
+
+  /*
+  *  Hopefully, this is the inverse of ip_decrease_ttl().
+  */
+  iph = skb->nh.iph;
+  check = ntohs(iph->check) - 0x0100;
+  if ((check & 0xff00) == 0xff00)
+    check--;
+  iph->check = htons(check);
+  ++iph->ttl;
 
-  if (ip_forward(skb, skb->dev, IPFWD_NOTTLDEC, skb->h.iph->daddr))
-    kfree_skb(skb, FREE_WRITE);
+  (void)ip_forward(skb);
 }
 
 
@@ -528,15 +541,12 @@
   unsigned long flags;
 */
 
-  IS_SKB(skb);
-
-
   /* fix the packet for ip_forward (because ip_build_xmit might not have) */
-  skb->h.iph = skb->ip_hdr;
+  skb->h.ipiph = skb->nh.iph;
 
   /* check it */
-  if (output_packet(NULL, PF_IPSEC, skb->dev, NULL, NULL, &skb) < FW_ACCEPT)
-    kfree_skb(skb, FREE_WRITE);
+  if (output_packet(NULL, PF_SECURITY, skb->dev, NULL, NULL, &skb) < FW_ACCEPT)
+    kfree_skb(skb);
   else {
     /* ...and ship it */
 /*
@@ -670,18 +680,26 @@
 int interface_attach(void *dummy, u_char *ipaddr)
 {
   struct device *dev;
+  struct in_device *in_dev;
+  struct in_ifaddr *ifa;
   int result = -1;
 
-  for (dev = dev_base; dev != NULL; dev = dev->next) { 
-    if ((dev->family == AF_INET) && (dev->pa_addr == *((__u32 *) ipaddr))
-      && !dev_skip(dev, "attach")) {
-      if (dev->mtu < 68 + maxheadergrowth)
-        printk("enskip: %s: interface mtu of %d is too small\n",
-                dev->name, dev->mtu);
-      else {
-        dev->mtu -= maxheadergrowth;
-	dev_addlist(dev);
-        result = 0;
+  for (dev = dev_base; dev; dev = dev->next) { 
+    if ((in_dev = dev->ip_ptr) != NULL) {
+      for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
+	if (ifa->ifa_local == *((__u32 *) ipaddr) && !dev_skip(dev, "attach")) {
+	  if (dev->mtu < 68 + maxheadergrowth)
+	    printk("enskip: %s: interface mtu of %d is too small\n",
+             dev->name, dev->mtu);
+	  else {
+	    if (dev->change_mtu)
+	      (void)dev->change_mtu(dev, dev->mtu - maxheadergrowth);
+	    else
+	      dev->mtu -= maxheadergrowth;
+	    dev_addlist(dev);
+	    result = 0;
+	  }
+	}
       }
     }
   }
@@ -692,14 +710,22 @@
 int interface_detach(void *dummy, u_char *ipaddr)
 {
   struct device *dev;
+  struct in_device *in_dev;
+  struct in_ifaddr *ifa;
   int result = -1;
 
-  for (dev = dev_base; dev != NULL; dev = dev->next) { 
-    if ((dev->family == AF_INET) && (dev->pa_addr == *((__u32 *) ipaddr)) 
-       && dev_skip(dev, "detach")) {
-      dev_rmlist(dev);
-      dev->mtu += maxheadergrowth;
-      result = 0;
+  for (dev = dev_base; dev; dev = dev->next) { 
+    if ((in_dev = dev->ip_ptr) != NULL) {
+      for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
+	if (ifa->ifa_local == *((__u32 *) ipaddr) && dev_skip(dev, "detach")) {
+	  dev_rmlist(dev);
+	  if (dev->change_mtu)
+	    (void)dev->change_mtu(dev, dev->mtu + maxheadergrowth);
+	  else
+	    dev->mtu += maxheadergrowth;
+	  result = 0;
+	}
+      }
     }
   }
 
@@ -715,14 +741,17 @@
 
   maxheadergrowth = ipsp_maxheadergrowth();
 
-  for (dev = dev_base; dev != NULL; dev = dev->next) { 
-    if (dev->family == AF_INET) {
+  for (dev = dev_base; dev; dev = dev->next) { 
+    if (dev->ip_ptr) {
       if (dev->mtu < 68 + maxheadergrowth)
         printk("enskip: %s: interface mtu of %d is too small\n",
                 dev->name, dev->mtu);
       else {
         if ((dev->flags & IFF_LOOPBACK) == 0) {
-          dev->mtu -= maxheadergrowth;
+	  if (dev->change_mtu)
+	    (void)dev->change_mtu(dev, dev->mtu - maxheadergrowth);
+	  else
+            dev->mtu -= maxheadergrowth;
           dev_addlist(dev);
         }
       }
@@ -739,10 +768,13 @@
 {
   struct device *dev;
 
-  for (dev = dev_base; dev != NULL; dev = dev->next) { 
-    if ((dev->family == AF_INET) && dev_skip(dev, "exit")) {
+  for (dev = dev_base; dev; dev = dev->next) { 
+    if (dev->ip_ptr && dev_skip(dev, "exit")) {
       dev_rmlist(dev);
-      dev->mtu += maxheadergrowth;
+      if (dev->change_mtu)
+	(void)dev->change_mtu(dev, dev->mtu + maxheadergrowth);
+      else
+	dev->mtu += maxheadergrowth;
     }
   }
 
--- ENskip-0.67/linux/queue.c.orig	Thu Feb  6 03:38:36 1997
+++ ENskip-0.67/linux/queue.c	Thu Apr  2 13:34:48 1998
@@ -21,9 +21,18 @@
 
 #include "config.h"
 #include <asm/system.h>
+#ifdef KERNEL	/* glibc */
+#include <linux/in_systm.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <endian.h>
+#include "ip.h"			/* <netinet/ip.h> __USE_BSD section only */
+#define IP_CE	IP_RF
+#else
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
+#endif
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/firewall.h>
@@ -50,9 +59,9 @@
   int retval = 0;
 
 #ifdef DEBUG_LINUX_QUEUE
-  struct iphdr *ip = ((struct sk_buff *) pkt)->ip_hdr;
+  struct iphdr *ip = ((struct sk_buff *) pkt)->nh.iph;
 
-  printf("queue %p: enqueue_in skb=%p ip_hdr=%p srcip=%08x dstip=%08x\n",
+  printf("queue %p: enqueue_in skb=%p nh.iph=%p srcip=%08x dstip=%08x\n",
          q, pkt, ip, ip->saddr, ip->daddr);
 #endif
   tmp = kmalloc(sizeof (*tmp), GFP_ATOMIC);
@@ -78,7 +87,7 @@
     printf("queue overflow: free skb=%p queue=%p\n", pkt, tmp);
 #endif
     kfree(tmp);
-    kfree_skb((struct sk_buff *) pkt, FREE_WRITE);
+    kfree_skb((struct sk_buff *) pkt);
 
     retval = -1;
   }
@@ -98,9 +107,9 @@
   int retval = 0;
 
 #ifdef DEBUG_LINUX_QUEUE
-  struct iphdr *ip = ((struct sk_buff *) pkt)->ip_hdr;
+  struct iphdr *ip = ((struct sk_buff *) pkt)->nh.iph;
 
-  printf("queue %p: enqueue_out skb=%p ip_hdr %p srcip=%08x dstip=%08x\n", 
+  printf("queue %p: enqueue_out skb=%p nh.iph %p srcip=%08x dstip=%08x\n", 
          q, pkt, ip, ip->saddr, ip->daddr);
 #endif
 
@@ -127,7 +136,7 @@
     printf("queue overflow: free skb=%p queue=%p\n", pkt, tmp);
 #endif
     kfree(tmp);
-    kfree_skb((struct sk_buff *) pkt, FREE_WRITE);
+    kfree_skb((struct sk_buff *) pkt);
 
     retval = -1;
   }
@@ -157,7 +166,7 @@
 #ifdef DEBUG_LINUX_QUEUE
     printf("queue_free: free skb=%p queue=%p\n", tmp->pskb, tmp);
 #endif
-    kfree_skb(tmp->pskb, FREE_WRITE);
+    kfree_skb(tmp->pskb);
     kfree(tmp);
   }
 
@@ -171,7 +180,7 @@
 #ifdef DEBUG_LINUX_QUEUE
     printf("queue_free: free skb=%p queue=%p\n", tmp->pskb, tmp);
 #endif
-    kfree_skb(tmp->pskb, FREE_WRITE);
+    kfree_skb(tmp->pskb);
     kfree(tmp);
   }
 
@@ -250,9 +259,9 @@
     else
       m = NULL;
 
-  if (m && m->ip_hdr) {
-    *((__u32 *) srcip) = m->ip_hdr->saddr;
-    *((__u32 *) dstip) = m->ip_hdr->daddr;
+  if (m && m->nh.iph) {
+    *((__u32 *) srcip) = m->nh.iph->saddr;
+    *((__u32 *) dstip) = m->nh.iph->daddr;
     result = 0;
   }
   else {
--- ENskip-0.67/linux/device.c.orig	Wed Jan 29 03:20:23 1997
+++ ENskip-0.67/linux/device.c	Sat Feb 14 22:41:10 1998
@@ -38,6 +38,7 @@
 #include <linux/major.h>
 #include <linux/netdevice.h>
 #include <linux/firewall.h>
+#include <asm/uaccess.h>
 #include "skip_defs.h"
 #include "dynamic.h"
 #include "memblk.h"
@@ -82,21 +83,21 @@
   if (io == NULL)
     return -ENOMEM;
 
-  memcpy_fromfs(io, (void *) arg, sizeof(struct devioctl));
-
+  copy_from_user(io, (void *)arg, sizeof(struct devioctl));
+  
   retval = verify_area(VERIFY_WRITE, (void *) io->ic_dp, io->ic_len);
   if (retval) {
     kfree(io);
     return retval;
   }
-  
+
   req = (u_char *) kmalloc(io->ic_len, GFP_ATOMIC);
   if (req == NULL) {
     kfree(io);
     return -ENOMEM;
   }
 
-  memcpy_fromfs(req, io->ic_dp, io->ic_len);
+  copy_from_user(req, io->ic_dp, io->ic_len);
 
 #ifdef DEBUG_LINUX_IOCTL
   printk("Calling ioctl request handler, request len=%i\n", io->ic_len);
@@ -111,10 +112,10 @@
       kfree(io);
       return retval;
     }
-    memcpy_tofs((void *) io->ic_dp, req, newlen);
+    copy_to_user((void *)io->ic_dp, req, newlen);
   }
   io->ic_len = newlen;
-  memcpy_tofs((void *) arg, io, sizeof(struct devioctl));
+  copy_to_user((void *)arg, io, sizeof(struct devioctl));
 
   kfree(req);
   kfree(io);
@@ -133,8 +134,9 @@
 }
 
 /* close function -- called from device switching table */
-void close_skip(struct inode *inode, struct file *file)
+int close_skip(struct inode *inode, struct file *file)
 {
   MOD_DEC_USE_COUNT;
+  return 0;
 }
 
--- ENskip-0.67/linux/device.h.orig	Sun Dec  1 18:56:43 1996
+++ ENskip-0.67/linux/device.h	Wed Jan 28 11:21:10 1998
@@ -24,7 +24,7 @@
 
 extern int ioctl_skip(struct inode *, struct file *, unsigned int, unsigned long);
 extern int open_skip(struct inode *, struct file *);
-extern void close_skip(struct inode *, struct file *);
+extern int close_skip(struct inode *, struct file *);
 
 #endif /* _ENSKIP_LINUX_DEVICE_H */
 
--- ENskip-0.67/linux/skipmod.c.orig	Sun Jan 26 08:40:32 1997
+++ ENskip-0.67/linux/skipmod.c	Fri Feb 13 13:06:28 1998
@@ -103,7 +103,7 @@
   forward_packet,
   packet_nop,
   output_packet,
-  PF_IPSEC,
+  PF_SECURITY,
   2  /* allow other filters to hook before us */
 };
 
@@ -114,7 +114,7 @@
   NULL,                     	/* read */
   NULL,                     	/* write */
   NULL,                         /* readdir */
-  NULL,                     	/* select */
+  NULL,                     	/* poll */
   ioctl_skip,                   /* ioctl */
   NULL,                         /* mmap */
   open_skip,                	/* open code */
@@ -132,7 +132,7 @@
   }
 
   if (register_firewall(PF_INET, &skip_in) ||
-      register_firewall(PF_IPSEC, &skip_out)) {
+      register_firewall(PF_SECURITY, &skip_out)) {
     printk("Unable to register ENskip as packet filter!\n");
 
     unregister_chrdev(SKIP_DEV_MAJOR, SKIP_DEV_NAME);
@@ -156,7 +156,7 @@
 
     unregister_chrdev(SKIP_DEV_MAJOR, SKIP_DEV_NAME);
 
-    unregister_firewall(PF_IPSEC, &skip_out);
+    unregister_firewall(PF_SECURITY, &skip_out);
     unregister_firewall(PF_INET, &skip_in);
 
     printk(KERN_INFO "enskip: module unloaded.\n");
--- ENskip-0.67/linux/ip.h.orig	Wed Mar 11 10:21:33 1998
+++ ENskip-0.67/linux/ip.h	Mon Mar  9 13:59:35 1998
@@ -0,0 +1,87 @@
+#ifdef __USE_BSD
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ip.h	8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Definitions for internet protocol version 4.
+ * Per RFC 791, September 1981.
+ */
+
+/*
+ * Structure of an internet header, naked of options.
+ */
+struct ip
+  {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+    u_int8_t ip_hl:4;			/* header length */
+    u_int8_t ip_v:4;			/* version */
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+    u_int8_t ip_v:4;			/* version */
+    u_int8_t ip_hl:4;			/* header length */
+#endif
+    u_int8_t ip_tos;			/* type of service */
+    u_short ip_len;			/* total length */
+    u_short ip_id;			/* identification */
+    u_short ip_off;			/* fragment offset field */
+#define	IP_RF 0x8000			/* reserved fragment flag */
+#define	IP_DF 0x4000			/* dont fragment flag */
+#define	IP_MF 0x2000			/* more fragments flag */
+#define	IP_OFFMASK 0x1fff		/* mask for fragmenting bits */
+    u_int8_t ip_ttl;			/* time to live */
+    u_int8_t ip_p;			/* protocol */
+    u_short ip_sum;			/* checksum */
+    struct in_addr ip_src, ip_dst;	/* source and dest address */
+  };
+
+/*
+ * Time stamp option structure.
+ */
+struct ip_timestamp
+  {
+    u_int8_t ipt_code;			/* IPOPT_TS */
+    u_int8_t ipt_len;			/* size of structure (variable) */
+    u_int8_t ipt_ptr;			/* index of current entry */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+    u_int8_t ipt_flg:4;			/* flags, see below */
+    u_int8_t ipt_oflw:4;		/* overflow counter */
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+    u_int8_t ipt_oflw:4;		/* overflow counter */
+    u_int8_t ipt_flg:4;			/* flags, see below */
+#endif
+    u_int32_t data[9];
+  };
+#endif /* __USE_BSD */
--- ENskip-0.67/linux/config.h.orig	Thu Mar 13 09:35:54 1997
+++ ENskip-0.67/linux/config.h	Mon Mar  9 14:53:03 1998
@@ -33,9 +33,11 @@
 #define __BSD_SOURCE
 
 #include <asm/types.h>
+#ifndef KERNEL	/* glibc */
 #include <sys/types.h>
 #include <unistd.h>
 #include <netinet/in.h>
+#endif
 
 typedef __s32 int32;
 typedef __u32 u_int32;
@@ -65,9 +67,11 @@
 #include <asm/system.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#ifndef KERNEL	/* glibc */
 #include <sys/socket.h>
 #include <net/if.h>
 #include <net/ip.h>
+#endif
 #include <linux/skbuff.h>
 
 #define SMALL_KERNEL_STACK
@@ -121,7 +125,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <malloc.h>
-#include <bsd/signal.h>
+#include <signal.h>	/* glibc */
 #include <sys/time.h>
 
 #define KALLOC(size)		malloc((size))
--- ENskip-0.67/lib/ah.c.orig	Wed Feb  5 16:37:59 1997
+++ ENskip-0.67/lib/ah.c	Thu Apr  2 13:31:19 1998
@@ -4,9 +4,18 @@
  */
 #include "config.h"
 
+#if defined(KERNEL) && defined(linux)
+#include <linux/in.h>
+#include <linux/in_systm.h>
+#include <linux/ip.h>
+#include <endian.h>
+#include "ip.h"			/* <netinet/ip.h> __USE_BSD section only */
+#define IP_CE	IP_RF
+#else
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#endif
 
 #include "skip_defs.h"
 #include "memblk.h"
--- ENskip-0.67/lib/ipsp.c.orig	Wed Feb  5 16:45:52 1997
+++ ENskip-0.67/lib/ipsp.c	Thu Apr  2 13:28:41 1998
@@ -11,9 +11,18 @@
 #include "config.h"
 
 #include <errno.h>
+#if defined(KERNEL) && defined(linux)	/* glibc */
+#include <linux/in.h>
+#include <linux/in_systm.h>
+#include <linux/ip.h>
+#include <endian.h>
+#include "ip.h"			/* <netinet/ip.h> __USE_BSD section only */
+#define IP_CE	IP_RF
+#else
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#endif
 
 #include "skip_defs.h"
 #include "id.h"
--- ENskip-0.67/lib/ipsum.c.orig	Thu Nov 14 15:46:44 1996
+++ ENskip-0.67/lib/ipsum.c	Thu Apr  2 13:29:43 1998
@@ -4,10 +4,20 @@
  */
 #include "config.h"
 
+#if defined(KERNEL) && defined(linux)	/* glibc */
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/in_systm.h>
+#include <linux/ip.h>
+#include <endian.h>
+#include "ip.h"			/* <netinet/ip.h> __USE_BSD section only */
+#define IP_CE	IP_RF
+#else
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#endif
 #include "ipsum.h"
 
 #ifdef __GNUC__
--- ENskip-0.67/lib/skip.c.orig	Wed Feb 19 02:46:33 1997
+++ ENskip-0.67/lib/skip.c	Thu Apr  2 13:30:45 1998
@@ -7,10 +7,20 @@
 
 #include "config.h"
 #include <errno.h>
+#if defined(KERNEL) && defined(linux)	/* glibc */
+#include <linux/in.h>
+#include <linux/in_systm.h>
+#include <linux/ip.h>
+#include <endian.h>
+#include "ip.h"			/* <netinet/ip.h> __USE_BSD section only */
+#define IP_CE	IP_RF
+#include <linux/udp.h>
+#else
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/udp.h>
+#endif
 
 #include "skip_defs.h"
 #include "memblk.h"
--- ENskip-0.67/lib/id.c.orig	Fri May  9 06:20:05 1997
+++ ENskip-0.67/lib/id.c	Mon Mar  9 14:50:25 1998
@@ -5,7 +5,9 @@
 
 #include "config.h"
 
+#ifndef KERNEL
 #include <sys/types.h>
+#endif
 #include "skip_defs.h"
 
 #ifndef KERNEL
--- ENskip-0.67/cert/suncert/lib/Bigint.C.orig	Thu Mar 13 08:13:23 1997
+++ ENskip-0.67/cert/suncert/lib/Bigint.C	Fri Jun  5 12:31:04 1998
@@ -46,7 +46,7 @@
 #include "Time.h"
 #include "asn1_der.h"
 
-#ifndef SOLARIS2
+#if !defined(SOLARIS2) && !defined(linux)	/* glibc */
 extern "C" {
 	void bzero(void *, int);
 };

--ELM897336977-404-0_--

