diff -ur --unidirectional-new-file skipsrc-1.0.orig/skip/freebsd/skip_es.c work.new/skip/freebsd/skip_es.c
--- skipsrc-1.0.orig/skip/freebsd/skip_es.c	Fri Oct 25 13:12:42 1996
+++ work.new/skip/freebsd/skip_es.c	Tue Feb  1 10:07:11 2000
@@ -63,6 +63,10 @@
 #include <skip_if.h>
 #include <skip_crypt.h>
 
+#if __FreeBSD_version >= 400013
+#include <netinet/ipprotosw.h>
+#endif
+
 /*
  * global SKIP interface information
  */
@@ -73,14 +77,24 @@
 int			skip_alignment		= 4; /* 32 bit */
 static unsigned int	inetsw_size		= 0;
 
+#if __FreeBSD_version < 400013
 static struct protosw	*inetsw_default;
 extern struct protosw	inetsw[];
+#else
+static struct ipprotosw	*inetsw_default;
+extern struct ipprotosw	inetsw[];
+#endif
 
 skip_es_t		*skip_es_ifs		= NULL;
 static int		skip_inited 		= 0;
 static unsigned short	skip_pktid;
 static skip_softc_t	skip_softc[SKIP_MAX_OPENS];
 
+static struct callout_handle
+	skip_timeout_handle = CALLOUT_HANDLE_INITIALIZER(&skip_timeout_handle);
+
+MALLOC_DEFINE(M_SKIP, "skip", "SKIP control structures and buffers");
+
 /*
  * statistics
  */
@@ -116,11 +130,13 @@
 static int		skip_ifoutput(struct ifnet *, struct mbuf *,
 				struct sockaddr *, struct rtentry *rtp);
 static int		skip_ifinput(struct mbuf *, int);
-static void		skip_inittimers();
-static void		skip_uninittimers();
-static void		skip_timer();
+static void		skip_inittimers(void);
+static void		skip_uninittimers(void);
+static void		skip_timer(void *);
 static int		skip_add_interface(char *);
 static int		skip_del_interface(char *);
+static void		skip_ifwakeup(skip_softc_t *);
+static int		skip_bufextend(struct mbuf *, int);
 
 static void	     skip_encrypt_done(void *, struct mbuf *, struct mbuf *,
 				void *, skip_arg_t *);
@@ -136,14 +152,14 @@
 /*
  * From Crypt/MAC system...
  */
-extern int		skip_es_bypass_init();
-extern void		skip_es_bypass_uninit();
-extern void		skip_key_initstore();
-extern void		skip_key_uninitstore();
-extern void		skip_key_initcryptors();
-extern void		skip_key_uninitcryptors();
-extern void		skip_mac_init();
-extern void		skip_mac_uninit();
+extern int		skip_es_bypass_init(void);
+extern void		skip_es_bypass_uninit(void);
+extern void		skip_key_initstore(void);
+extern void		skip_key_uninitstore(void);
+extern void		skip_key_initcryptors(void);
+extern void		skip_key_uninitcryptors(void);
+extern void		skip_mac_init(void);
+extern void		skip_mac_uninit(void);
 extern int		skip_fmt_kmgr(union skip_messages *, skip_keycb_t *);
 
 extern struct cdevsw skipdevsw;
@@ -157,7 +173,7 @@
  * Returns: 0 on success, errno otherwise.
  */
 int
-skip_init()
+skip_init(void)
 {
 	register int		s, rc;
 	register struct protosw	*pr;
@@ -252,7 +268,10 @@
 		for (pr = inetdomain.dom_protosw;
 			pr < inetdomain.dom_protoswNPROTOSW; pr++) {
 
-			pr->pr_input = skip_ifinput;
+			if (pr->pr_protocol == IPPROTO_DIVERT)
+				continue;
+			pr->pr_input =
+				(void (*)(struct mbuf *, int)) skip_ifinput;
 		}
 		splx(s);
 	}
@@ -266,7 +285,7 @@
  * Returns: 0 on success, errno otherwise.
  */
 int
-skip_uninit()
+skip_uninit(void)
 {
 	register int		s;
 	if (skip_busy || skip_keys_stats.skip_encrypt_keys_active 
@@ -319,7 +338,11 @@
 						major(dev), flags);
 #endif
 
+#if __FreeBSD_version < 400005
 	if (suser(p->p_ucred, &p->p_acflag )) {
+#else
+	if (suser(p)) {
+#endif
 		return (EPERM);
 	}
 	if (minor(dev) >= SKIP_MAX_OPENS) {
@@ -422,27 +445,30 @@
  * Returns: 0 if no data available, 1 otherwise
  */
 int
-skip_ifselect(dev, rw, p)
+skip_ifpoll(dev, events, p)
 	dev_t		dev;
-	int		rw;
+	int		events;
 	struct proc 	*p;
 {
 	register skip_softc_t	*sp = &skip_softc[minor(dev)];
 	register int		s;
+	int revents = 0;
 
-	if (rw == FWRITE) {
-		return (1);
-	}
+	/* Check readable */
 	s = splimp();
-	if (sp->q.ifq_len > 0) {
-		splx(s);
-		return (1);
+	if (events & (POLLIN | POLLRDNORM)) {
+		if (sp->q.ifq_len > 0)
+			revents |= (events & (POLLIN | POLLRDNORM));
+		else
+			selrecord(p, &sp->sp_si);
 	}
 
-	selrecord(p, &sp->sp_si);
+	/* Always writable */
+	if (events & (POLLOUT | POLLWRNORM))
+		revents |= (events & (POLLOUT | POLLWRNORM));
 
 	splx(s);
-	return(0);
+	return(revents);
 }
 
 /* skip_ifread()
@@ -786,9 +812,9 @@
  * Returns: None
  */
 static void
-skip_inittimers()
+skip_inittimers(void)
 {
-	timeout(skip_timer, NULL, skip_key_tick * hz);
+	skip_timeout_handle = timeout(skip_timer, NULL, skip_key_tick * hz);
 }
  
 /* skip_uninittimers()
@@ -798,9 +824,10 @@
  * Returns: None
  */
 static void
-skip_uninittimers()
+skip_uninittimers(void)
 {
-	untimeout(skip_timer, NULL);
+	untimeout(skip_timer, NULL, skip_timeout_handle);
+	callout_handle_init(&skip_timeout_handle);
 }
  
 /* skip_timer()
@@ -812,14 +839,13 @@
  */
 /*ARGSUSED*/
 static void
-skip_timer(arg)
-	caddr_t		arg;
+skip_timer(void *arg)
 {
 	/*
 	 * run through the key store
 	 */
 	skip_key_iterate(skip_key_check, NULL);
-	timeout(skip_timer, NULL, skip_key_tick * hz);
+	skip_timeout_handle = timeout(skip_timer, NULL, skip_key_tick * hz);
 }
 
 #ifdef notdef
@@ -846,6 +872,7 @@
 }
 #endif
 
+#ifdef notdef
 void
 skip_dump_buf(char *what, unsigned char *p, int len) 
 {
@@ -857,7 +884,9 @@
 	}
 	printf("].\n");
 }
+#endif
 
+#ifdef notdef
 void
 skip_dump_ip(struct ip *ip)
 {
@@ -878,6 +907,7 @@
 			ip->ip_ttl, ip->ip_p, ntohs(ip->ip_sum));
 
 }
+#endif
 
 /*
  * SKIP Ioctl and Interface management routines
@@ -1107,7 +1137,7 @@
 int
 skip_ifioctl(dev, cmd, data, fflag, p)
 	dev_t		dev;
-	int		cmd;
+	u_long		cmd;
 	caddr_t		data;
 	int		fflag;
 	struct		proc *p;
@@ -1390,7 +1420,6 @@
 	skip_es_t		*skip_if;
 	int			iphlen, hdrlen = 0;
 	struct mbuf		*decryptbuf = NULL;
-	extern u_char		ip_protox[];
 	skip_param_t		params;
 	skip_hdr_t		skip_hdr;
 	skip_es_hash_t          *entry, **acl;
@@ -1718,7 +1747,7 @@
 		 */
 		decryptbuf->m_data += iphlen;
 	
-                SKIP_DEBUG2("skip_ifinput: decryptbuf m_len=%d m_data=%d\n",
+                SKIP_DEBUG2("skip_ifinput: decryptbuf m_len=%d m_data=%p\n",
                                         decryptbuf->m_len, decryptbuf->m_data);
 
 	} 
@@ -1745,8 +1774,12 @@
 	ip->ip_id = ntohs(ip->ip_id);
 	ip->ip_off = ntohs(ip->ip_off);
 pass:
-	m->m_flags &= ~ M_EOR;
+	m->m_flags &= ~ M_PROTO1;
+#if __FreeBSD_version < 400013
 	(*inetsw_default[ip_protox[ip->ip_p]].pr_input)(m, hlen);
+#else
+	(*inetsw_default[ip_protox[ip->ip_p]].pr_input)(m, hlen, ip->ip_p);
+#endif
 	return (0);
 }
 
@@ -1910,6 +1943,13 @@
 		 */
                 IPADDRCOPY(&params.tunnel_addr, &newip->ip_dst);
 
+		/* 
+		 * insert different source address if specified 
+		 */
+
+		if(params.source != 0)
+			(&newip->ip_src)->s_addr = params.source;
+
 		encryptbuf->m_len += sizeof (struct ip);
 
 		/*
@@ -2005,7 +2045,7 @@
 			if (params.kp_alg) {
 				newip->ip_p = SKIP_NEXT_ESP;
 			} else {
-				newip->ip_p = IPPROTO_ENCAP;
+				newip->ip_p = IPPROTO_IPIP;
 			}
 		}
 		skip_if->stats.skip_if_raw_out++;
@@ -2028,6 +2068,13 @@
 		 * insert tunnel address as destination
 		 */
 		IPADDRCOPY(&params.tunnel_addr, &newip->ip_dst);
+
+		/* 
+		 * insert different source address if specified 
+		 */
+
+		if(params.source != 0) 
+			(&newip->ip_src)->s_addr = params.source;
 	}
 
 	if (params.s_nsid == 0) {
@@ -2097,7 +2144,7 @@
 	register skip_param_t   *params = &res->params;
 	register struct ip      *ip = mtod(original, struct ip *);
 	int                     rc, s, iphlen;
-	struct mbuf             *outbuf, *new_hdr;
+	struct mbuf             *outbuf;
 
 	SKIP_PRINT("skip_decrypt_done", params);
 
@@ -2125,7 +2172,7 @@
 	 */
 	outbuf = (res->modes & SKIP_CRYPT_ON) ? m : original;
 
-	if (res->proto != IPPROTO_ENCAP) {
+	if (res->proto != IPPROTO_IPIP) {
 		/*
 		 * transport mode, need to copy original IP header
 		 */
@@ -2195,7 +2242,7 @@
 	/*
 	 * tag the start of the header buffer so SKIP can recognise it
 	 */
-	outbuf->m_flags |= M_EOR | M_PKTHDR;
+	outbuf->m_flags |= M_PROTO1 | M_PKTHDR;
     
 	s = splimp();
 	if (IF_QFULL(&ipintrq)) {
@@ -2240,7 +2287,8 @@
 	unsigned short		len;
 	struct ip		*hptr;
 	struct rtentry		*rtp;
+	struct mbuf		*n;
 	
 	/*
 	 * recover the route pointer
 	 */
@@ -2263,6 +2311,9 @@
 	hptr->ip_len = htons(len); /* total length */
 
 	skip_ipsum(hptr);
+
+	for (m->m_pkthdr.len = 0, n = m; n != NULL; n = n->m_next)
+		m->m_pkthdr.len += n->m_len;
 
 	(*skip_if->if_output)(skip_if->ifp, m, dst, rtp);
 	RTFREE(rtp);