diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/include/net/sock.h linux-patched/include/net/sock.h
--- linux/include/net/sock.h	Wed Aug 27 15:52:54 2003
+++ linux-patched/include/net/sock.h	Wed Aug 27 15:58:59 2003
@@ -245,6 +245,12 @@
 	__u32	end_seq;
 };
 
+#if 1
+struct udp_opt {
+	__u32 esp_in_udp;
+};
+#endif
+
 struct tcp_opt {
 	int	tcp_header_len;	/* Bytes of tcp header to send		*/
 
@@ -584,6 +590,9 @@
 #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
 		struct spx_opt		af_spx;
 #endif /* CONFIG_SPX */
+#if 1
+		struct udp_opt 		af_udp;
+#endif
 
 	} tp_pinfo;
 
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/Config.in linux-patched/net/Config.in
--- linux/net/Config.in	Wed Aug 27 15:52:58 2003
+++ linux-patched/net/Config.in	Wed Aug 27 15:58:59 2003
@@ -88,4 +88,9 @@
 #bool 'Network code profiler' CONFIG_NET_PROFILE
 endmenu
 
+tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC
+if [ "$CONFIG_IPSEC" != "n" ]; then
+  source net/ipsec/Config.in
+fi
+
 endmenu
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/Makefile linux-patched/net/Makefile
--- linux/net/Makefile	Wed Aug 27 15:52:57 2003
+++ linux-patched/net/Makefile	Wed Aug 27 15:58:59 2003
@@ -17,6 +17,7 @@
 subdir-$(CONFIG_NET)		+= 802 sched
 subdir-$(CONFIG_INET)		+= ipv4
 subdir-$(CONFIG_NETFILTER)	+= ipv4/netfilter
+subdir-$(CONFIG_IPSEC)		+= ipsec
 subdir-$(CONFIG_UNIX)		+= unix
 subdir-$(CONFIG_IPV6)		+= ipv6
 
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/Config.in linux-patched/net/ipsec/Config.in
--- linux/net/ipsec/Config.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/Config.in	Thu Sep  5 04:53:52 2002
@@ -0,0 +1,63 @@
+#
+# IPSEC configuration
+# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
+# 
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+# 
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+
+comment 'IPSec options (FreeS/WAN)'
+
+bool '   IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP
+
+bool '   IPSEC: Authentication Header' CONFIG_IPSEC_AH
+if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then
+  bool '      HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5
+  bool '      HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1
+fi
+
+bool '   IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP
+if [ "$CONFIG_IPSEC_ESP" = "y" ]; then
+  bool '      3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES
+fi
+
+bool '   IPSEC Modular Extensions' CONFIG_IPSEC_ALG
+if [ "$CONFIG_IPSEC_ALG" != "n" ]; then
+	source net/ipsec/alg/Config.in
+fi
+
+bool '   IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP
+
+bool '   IPSEC Debugging Option' CONFIG_IPSEC_DEBUG
+
+bool '   IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL
+
+#
+#
+# $Log: super-freeswan-1.99.8-delsol1.diff,v $
+# Revision 1.1  2003/09/09 09:20:34  john
+# Initial import
+#
+# Revision 1.3  2002/09/05 03:53:52  ken
+# Added NAT-T Patch
+#
+# Revision 1.2  2002/09/05 03:27:08  ken
+# Applied freeswan-alg-0.8.0-BASE-klips.diff
+#
+# Revision 1.1.1.1  2002/09/05 03:13:17  ken
+# 1.98b
+#
+# Revision 1.25  2002/02/21 19:55:12  mcr
+# 	removed all traces of IPSEC_CONFIG_REGRESS because it
+# 	screwed up 2.2's "make menuconfig" scripts.
+#
+# Revision 1.24  2002/01/28 20:24:31  mcr
+# 	commented out IPSEC_REGRESS option from user visible config.
+#
+#
+
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/Makefile linux-patched/net/ipsec/Makefile
--- linux/net/ipsec/Makefile	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/Makefile	Fri Feb  7 13:14:24 2003
@@ -0,0 +1,333 @@
+# Makefile for KLIPS kernel code
+# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
+# 
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+# 
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+ifndef TOPDIR
+TOPDIR  := /usr/src/linux
+endif
+
+subdir-  := 
+subdir-n := 
+subdir-y :=
+subdir-m :=
+
+O_TARGET := ipsec.o
+obj-y := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
+obj-y += ipsec_life.o ipsec_proc.o
+obj-y += ipsec_tunnel.o ipsec_rcv.o sysctl_net_ipsec.o 
+obj-y +=  pfkey_v2.o pfkey_v2_parser.o 
+
+export-objs := radij.o
+
+obj-$(CONFIG_IPSEC_ALG) +=ipsec_alg.o alg/ipsec_alg_static.o
+export-objs += ipsec_alg.o
+subdir-m += alg
+
+# 'override CFLAGS' should really be 'EXTRA_CFLAGS'
+EXTRA_CFLAGS += -Ilibfreeswan -Ilibdes
+ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.2-2)
+EXTRA_CFLAGS += -DREDHAT_BOGOSITY
+endif
+ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.3-12)
+EXTRA_CFLAGS += -DREDHAT_BOGOSITY
+endif
+
+#ifeq ($(CONFIG_IPSEC_DEBUG),y)
+#EXTRA_CFLAGS += -g
+#endif
+
+EXTRA_CFLAGS += $(KLIPSCOMPILE)
+EXTRA_CFLAGS += -Wall
+#EXTRA_CFLAGS += -Werror
+#EXTRA_CFLAGS += -Wconversion 
+#EXTRA_CFLAGS += -Wmissing-prototypes 
+EXTRA_CFLAGS += -Wpointer-arith 
+#EXTRA_CFLAGS += -Wcast-qual 
+#EXTRA_CFLAGS += -Wmissing-declarations 
+EXTRA_CFLAGS += -Wstrict-prototypes
+#EXTRA_CFLAGS += -pedantic
+#EXTRA_CFLAGS += -O3
+#EXTRA_CFLAGS += -W
+#EXTRA_CFLAGS += -Wwrite-strings 
+#EXTRA_CFLAGS += -Wbad-function-cast 
+
+obj-$(CONFIG_IPSEC_ENC_3DES) += libdes/libdes.a
+obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o
+obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o
+obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o zlib/zlib.a
+subdir-$(CONFIG_IPSEC_IPCOMP) += zlib
+subdir-$(CONFIG_IPSEC) += libfreeswan
+obj-y += libfreeswan/libkernel.a
+
+###
+### Pre Rules.make
+###
+# undo O_TARGET, obj-y if no static
+ifneq ($(CONFIG_IPSEC),y)
+O_TARGET := 
+ipsec_obj-y := $(obj-y)
+obj-y :=
+subdir-y :=
+endif
+
+# Define obj-m if modular ipsec 
+ifeq ($(CONFIG_IPSEC),m)
+obj-m += ipsec.o
+endif
+
+
+# These rules translate from new to old makefile rules
+# Translate to Rules.make lists.
+multi-used      := $(filter $(list-multi), $(obj-y) $(obj-m))
+multi-objs      := $(foreach m, $(multi-used), $($(basename $(m))-objs))
+active-objs     := $(sort $(multi-objs) $(obj-y) $(obj-m))
+O_OBJS          := $(obj-y)
+M_OBJS          := $(obj-m)
+MIX_OBJS        := $(filter $(export-objs), $(active-objs))
+OX_OBJS := $(export-objs)
+SUB_DIRS := $(subdir-y)
+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
+MOD_SUB_DIRS := $(subdir-m)
+
+#   dunno why, but some 2.2 setups may need explicit -DEXPORT_SYMTAB
+#   uncomment next line if ipsec_alg.c compilation fails with
+#   "parse error before `EXPORT_SYMTAB_not_defined'"  --Juanjo
+# CFLAGS_ipsec_alg.o += -DEXPORT_SYMTAB
+#
+
+include $(TOPDIR)/Rules.make
+
+###
+### Post Rules.make
+###
+# for modular ipsec, no O_TARGET defined => define ipsec.o creation rules
+ifeq ($(CONFIG_IPSEC),m)
+ipsec.o : $(ipsec_obj-y)
+	rm -f $@
+	$(LD) $(LD_EXTRAFLAGS) -r $(ipsec_obj-y) -o $@
+endif
+
+$(ipsec_obj-y) $(obj-y) $(obj-m):  $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
+
+libdes/libdes.a:
+	( cd libdes && \
+	if test " `arch | sed 's/^i[3456]/x/'`" = " x86" ; \
+	then $(MAKE) CC='$(CC)' CFLAG='$(CFLAGS)' TESTING='' x86-elf ; \
+	else $(MAKE) CC='$(CC)' CFLAG='$(CFLAGS)' libdes.a ; \
+	fi )
+
+libfreeswan/libkernel.a:
+	$(MAKE) -C libfreeswan
+
+zlib/zlib.a:
+	$(MAKE) -C zlib
+
+alg/ipsec_alg_static.o: dummy
+	$(MAKE) -C alg CC='$(CC)' CFLAGS='$(CFLAGS)' ipsec_alg_static.o
+
+clean:
+	$(MAKE) -C alg clean
+	-rm -f *.o
+
+tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
+	find . -name '*.[ch]' |xargs etags
+	find . -name '*.[ch]' |xargs ctags
+
+tar:
+		tar -cvf /dev/f1 .
+
+#
+# $Log: super-freeswan-1.99.8-delsol1.diff,v $
+# Revision 1.1  2003/09/09 09:20:34  john
+# Initial import
+#
+# Revision 1.3  2003/02/07 13:14:24  ken
+# Pullin jjo's ALG 0.8.1rc branch
+#
+# Revision 1.2.2.1  2003/02/06 22:09:49  jjo
+# sync to alg-0.8.1-rc4
+#
+# Revision 1.2  2002/09/05 03:27:08  ken
+# Applied freeswan-alg-0.8.0-BASE-klips.diff
+#
+# Revision 1.1.1.1  2002/09/05 03:13:17  ken
+# 1.98b
+#
+# Revision 1.39  2002/01/17 04:39:40  rgb
+# Take compile options from top level Makefile.inc
+#
+# Revision 1.38  2001/11/27 05:28:07  rgb
+# Shut off -Werror until we figure out a graceful way of quieting down the
+# pfkey_ops defined but not used complaint in the case of SMP in
+# pfkey_v2.c.
+#
+# Revision 1.37  2001/11/27 05:10:15  rgb
+# Added -Ilibdes and removed lib/des* symlinks.
+#
+# Revision 1.36  2001/11/26 09:23:47  rgb
+# Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+#
+# Revision 1.35.2.1  2001/09/25 02:17:50  mcr
+# 	added ipsec_sa, ipsec_life, ipsec_proc.
+# 	added -Werror to compile flags (see fix for zlib/zutil.h)
+#
+# Revision 1.3  2001/09/21 04:41:26  mcr
+# 	actually, ipsec_proc.c and ipsec_life.c were never actually compiled.
+#
+# Revision 1.2  2001/09/21 04:11:33  mcr
+# 	first compilable version.
+#
+# Revision 1.1.1.2  2001/09/17 01:17:52  mcr
+#   snapshot 2001-09-16
+#
+# Revision 1.35  2001/09/07 22:09:12  rgb
+# Quiet down compilation.
+#
+# Revision 1.34  2001/08/11 17:10:23  henry
+# update bogosity stuff to cover RH7.1 update
+#
+# Revision 1.33  2001/06/14 19:35:07  rgb
+# Update copyright date.
+#
+# Revision 1.32  2001/06/13 21:00:50  rgb
+# Added a kludge to get around RedHat kernel version bogosity...
+#
+# Revision 1.31  2001/01/29 22:19:06  rgb
+# Convert to 2.4 new style with back compat.
+#
+# Revision 1.30  2000/09/29 19:51:57  rgb
+# Moved klips/net/ipsec/ipcomp_* to zlib/* (Svenning).
+#
+# Revision 1.29  2000/09/15 11:37:01  rgb
+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
+# IPCOMP zlib deflate code.
+#
+# Revision 1.28  2000/09/15 04:55:25  rgb
+# Clean up pfkey object inclusion into the default object.
+#
+# Revision 1.27  2000/09/12 03:20:47  rgb
+# Cleared out now unused pfkeyv2 switch.
+# Enabled sysctl.
+#
+# Revision 1.26  2000/09/08 19:12:55  rgb
+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+#
+# Revision 1.25  2000/06/16 03:09:16  rgb
+# Shut up cast lost warning due to changes in 2.4.0-test1.
+#
+# Revision 1.24  2000/03/16 06:40:48  rgb
+# Hardcode PF_KEYv2 support.
+#
+# Revision 1.23  2000/02/14 21:10:38  rgb
+# Added gcc debug flag when KLIPS_DEBUG is swtiched on.
+#
+# Revision 1.22  2000/01/21 09:44:29  rgb
+# Added compiler switches to be a lot more fussy.
+#
+# Revision 1.21  1999/11/25 23:35:20  rgb
+# Removed quotes to fix Alpha compile issues.
+#
+# Revision 1.20  1999/11/17 15:49:34  rgb
+# Changed all occurrences of ../../../lib in pathnames to libfreeswan,
+# which refers to the /usr/src/linux/net/ipsec/lib directory setup by the
+# klink target in the top-level Makefile; and libdeslite.o to
+# libdes/libdes.a.
+# Added SUB_DIRS := lib definition for the kernel libraries.
+#
+# Revision 1.19  1999/04/27 19:06:47  rgb
+# dd libs and dependancies to tags generation.
+#
+# Revision 1.18  1999/04/16 16:28:12  rgb
+# Minor bugfix to avoid including DES if only AH is used.
+#
+# Revision 1.17  1999/04/15 15:37:23  rgb
+# Forward check changes from POST1_00 branch.
+#
+# Revision 1.14.2.1  1999/03/30 17:29:17  rgb
+# Add support for pfkey.
+#
+# Revision 1.16  1999/04/11 00:28:56  henry
+# GPL boilerplate
+#
+# Revision 1.15  1999/04/06 04:54:25  rgb
+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+# patch shell fixes.
+#
+# Revision 1.14  1999/02/18 16:50:45  henry
+# update for new DES library
+#
+# Revision 1.13  1999/02/12 21:11:45  rgb
+# Prepare for newer LIBDES (patch from P.Onion).
+#
+# Revision 1.12  1999/01/26 02:05:08  rgb
+# Remove references to INET_GET_PROTOCOL.
+# Removed CONFIG_IPSEC_ALGO_SWITCH macro.
+# Change from transform switch to algorithm switch.
+#
+# Revision 1.11  1999/01/22 06:16:09  rgb
+# Added algorithm switch code config option.
+#
+# Revision 1.10  1998/11/08 05:31:21  henry
+# be a little fussier
+#
+# Revision 1.9  1998/11/08 05:29:41  henry
+# revisions for new libdes handling
+#
+# Revision 1.8  1998/08/12 00:05:48  rgb
+# Added new xforms to Makefile (moved des-cbc to des-old).
+#
+# Revision 1.7  1998/07/27 21:48:47  rgb
+# Add libkernel.
+#
+# Revision 1.6  1998/07/14 15:50:47  rgb
+# Add dependancies on linux config files.
+#
+# Revision 1.5  1998/07/09 17:44:06  rgb
+# Added 'clean' and 'tags' targets.
+# Added TOPDIR macro.
+# Change module back from symbol exporting to not.
+#
+# Revision 1.3  1998/06/25 19:25:04  rgb
+# Rearrange to support static linking and objects with exported symbol
+# tables.
+#
+# Revision 1.1  1998/06/18 21:27:42  henry
+# move sources from klips/src to klips/net/ipsec, to keep stupid
+# kernel-build scripts happier in the presence of symlinks
+#
+# Revision 1.3  1998/04/15 23:18:43  rgb
+# Unfixed the ../../libdes fix to avoid messing up Henry's script.
+#
+# Revision 1.2  1998/04/14 17:50:47  rgb
+# Fixed to find the new location of libdes.
+#
+# Revision 1.1  1998/04/09 03:05:22  henry
+# sources moved up from linux/net/ipsec
+# modifications to centralize libdes code
+#
+# Revision 1.1.1.1  1998/04/08 05:35:02  henry
+# RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+#
+# Revision 0.5  1997/06/03 04:24:48  ji
+# Added ESP-3DES-MD5-96
+#
+# Revision 0.4  1997/01/15 01:32:59  ji
+# Added new transforms.
+#
+# Revision 0.3  1996/11/20 14:22:53  ji
+# *** empty log message ***
+#
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/Makefile.inc linux-patched/net/ipsec/Makefile.inc
--- linux/net/ipsec/Makefile.inc	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/Makefile.inc	Wed Aug 27 15:58:54 2003
@@ -0,0 +1,182 @@
+# FreeS/WAN pathnames and other master configuration
+# Copyright (C) 2001, 2002  Henry Spencer.
+# 
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+# 
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+
+
+
+# Variables in this file with names starting with INC_ are not for use
+# by Makefiles which include it; they are subject to change without warning.
+#
+# "Final" and "finally" refer to where the files will end up on the
+# running IPsec system, as opposed to where they get installed by our
+# Makefiles.  (The two are different for cross-compiles and the like,
+# where our Makefiles are not the end of the installation process.)
+# Paths with FINAL in their names are the only ones that the installed
+# software itself depends on.  (Very few things should know about the
+# FINAL paths; think twice and consult Henry before making something new
+# depend on them.)  All other paths are install targets.
+# See also DESTDIR, below.
+
+
+
+### boilerplate, do not change
+SHELL=/bin/sh
+
+
+
+### install pathnames
+
+# DESTDIR can be used to supply a prefix to all install targets.
+# (Note that "final" pathnames, signifying where files will eventually
+# reside rather than where install puts them, are exempt from this.)
+# The prefixing is done in this file, so as to have central control over
+# it; DESTDIR itself should never appear in any other Makefile.
+DESTDIR?=
+
+# "local" part of tree, used in building other pathnames
+INC_USRLOCAL=/usr/local
+
+# PUBDIR is where the "ipsec" command goes; beware, many things define PATH
+# settings which are assumed to include it (or at least, to include *some*
+# copy of the "ipsec" command).
+PUBDIR=$(DESTDIR)$(INC_USRLOCAL)/sbin
+
+# BINDIR is where commands get put, FINALBINDIR is where the "ipsec"
+# command will look for them when it is run.
+FINALBINDIR=$(INC_USRLOCAL)/lib/ipsec
+BINDIR=$(DESTDIR)$(FINALBINDIR)
+
+# where the appropriate manpage tree is located
+# location within INC_USRLOCAL
+INC_MANDIR=man
+# the full pathname
+MANTREE=$(DESTDIR)$(INC_USRLOCAL)/$(INC_MANDIR)
+# all relevant subdirectories of MANTREE
+MANPLACES=man3 man5 man8
+
+# where configuration files go
+FINALCONFDIR=/etc
+CONFDIR=$(DESTDIR)$(FINALCONFDIR)
+
+# An attempt is made to automatically figure out where boot/shutdown scripts 
+# will finally go:  the first directory in INC_RCDIRS which exists gets them.
+# If none of those exists (or INC_RCDIRS is empty), INC_RCDEFAULT gets them.
+# With a non-null DESTDIR, INC_RCDEFAULT will be used unless one of the
+# INC_RCDIRS directories has been pre-created under DESTDIR.
+INC_RCDIRS=/etc/rc.d/init.d /etc/rc.d /etc/init.d /sbin/init.d
+INC_RCDEFAULT=/etc/rc.d/init.d
+
+# RCDIR is where boot/shutdown scripts go; FINALRCDIR is where they think
+# will finally be (so utils/Makefile can create a symlink in BINDIR to the
+# place where the boot/shutdown script will finally be, rather than the
+# place where it is installed).
+FINALRCDIR=$(shell for d in $(INC_RCDIRS) ; \
+		do if test -d $(DESTDIR)/$$d ; \
+		then echo $$d ; exit 0 ; \
+		fi ; done ; echo $(INC_RCDEFAULT) )
+RCDIR=$(DESTDIR)$(FINALRCDIR)
+
+
+
+### kernel pathnames
+
+# Kernel location:  where patches are inserted, where kernel builds are done.
+KERNELSRC?=/usr/src/redhat/BUILD/kernel-2.4.9/linux-patched
+
+# things whose existence indicates what kernel version we have
+DIRIN22=$(KERNELSRC)/net/netlink
+FILIN24=$(KERNELSRC)/net/khttpd/main.c
+
+# where kernel configuration outputs are located
+KCFILE=$(KERNELSRC)/.config
+ACFILE=$(KERNELSRC)/include/linux/autoconf.h
+VERFILE=$(KERNELSRC)/include/linux/version.h
+
+
+
+### misc installation stuff
+
+# what program to use when installing things
+INSTALL=install
+
+# flags to the install program, for programs, manpages, and config files
+# -b has install make backups (n.b., unlinks original), --suffix controls
+# how backup names are composed.
+# Note that the install procedures will never overwrite an existing config
+# file, which is why -b is not specified for them.
+INSTBINFLAGS=-b --suffix=.old
+INSTMANFLAGS=
+INSTCONFFLAGS=
+
+
+
+### misc configuration, included here in hopes that other files will not
+### have to be changed for common customizations.
+
+# extra compile flags, for userland and kernel stuff, e.g. -g for debug info
+# (caution, this stuff is still being sorted out, will change in future)
+USERCOMPILE=-g -O3
+KLIPSCOMPILE=-O3
+
+# command used to link/copy KLIPS into kernel source tree
+# There are good reasons why this is "ln -s"; only people like distribution
+# builders should ever change it.
+KLIPSLINK=ln -s
+
+# extra options for use in kernel build
+KERNMAKEOPTS=
+
+# kernel Makefile targets to be done before build
+# Can be overridden if you are *sure* your kernel doesn't need them.  (2.2.xx
+# and later reportedly do not.)
+KERNDEP=dep
+KERNCLEAN=clean
+
+# kernel make name:  zImage for 2.0.xx, bzImage for 2.2.xx and later, and
+# boot on non-x86s (what ever happened to standards?)
+INC_B=$(shell test -d $(DIRIN22) && echo b)
+KERNEL=$(shell if expr " `uname -m`" : ' i.86' >/dev/null ; \
+	then echo $(INC_B)zImage ; \
+	else echo boot ; \
+	fi)
+
+# temporary directory to be used when building RPMs, and where to put the
+# resulting RPM tree
+RPMKERNDIR := $(shell echo `pwd`/tmp.rpmkernel)
+RPMTMPDIR := $(shell echo `pwd`/tmp.rpmbuild)
+RPMDEST := $(shell echo `pwd`/rpms)
+# Newer versions of RPM do not permit building of packages with the "rpm" 
+# command. For RedHat systems with older version of RPM, use:
+# RPMBUILD=rpm
+# instead.
+RPMBUILD=rpmbuild
+
+#
+# Set this to a RedHat kernel-sources RPM. This normally extracts into
+# /usr/src/linux-2.4, but you might have extracted it elsewhere with
+# rpm2cpio.
+#
+RH_KERNELSRC=/usr/src/linux-2.4
+
+#RH_KERNELSRC=/a3/kernel_sources/linux-2.4.2
+#RH_KERNELSRC=/a3/kernel_sources/linux-2.4.9-13
+#RH_KERNELSRC=/c2/kernel/rh/linux-2.4.9-13
+
+# the following is a list of symbols which will be used to construct
+# the module goo to identify which module goes with each kernel.
+MODULE_GOO_LIST=irq_stat netif_rx register_sysctl_table send_sig
+MODULE_GOO_LIST+=kmalloc __kfree_skb __ip_select_ident alloc_skb
+MODULE_GOO_LIST+=icmp_send ip_fragment sock_register 
+
+
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/Makefile.ver linux-patched/net/ipsec/Makefile.ver
--- linux/net/ipsec/Makefile.ver	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/Makefile.ver	Tue Jul  8 20:02:03 2003
@@ -0,0 +1 @@
+IPSECVERSION=super-freeswan-1.99.8
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_1des.in linux-patched/net/ipsec/alg/Config.alg_1des.in
--- linux/net/ipsec/alg/Config.alg_1des.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_1des.in	Fri Feb  7 14:39:36 2003
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        1DES **INSECURE** encryption algorithm (modular alg)' CONFIG_IPSEC_ALG_1DES
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_3des.in linux-patched/net/ipsec/alg/Config.alg_3des.in
--- linux/net/ipsec/alg/Config.alg_3des.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_3des.in	Thu Sep  5 04:36:54 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        3DES encryption algorithm (modular alg)' CONFIG_IPSEC_ALG_3DES
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_aes.in linux-patched/net/ipsec/alg/Config.alg_aes.in
--- linux/net/ipsec/alg/Config.alg_aes.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_aes.in	Thu Sep  5 04:38:06 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        AES encryption algorithm' CONFIG_IPSEC_ALG_AES
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_blowfish.in linux-patched/net/ipsec/alg/Config.alg_blowfish.in
--- linux/net/ipsec/alg/Config.alg_blowfish.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_blowfish.in	Thu Sep  5 04:39:46 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        BLOWFISH encryption algorithm' CONFIG_IPSEC_ALG_BLOWFISH
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_cast.in linux-patched/net/ipsec/alg/Config.alg_cast.in
--- linux/net/ipsec/alg/Config.alg_cast.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_cast.in	Thu Sep  5 04:48:04 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        CAST encryption algorithm' CONFIG_IPSEC_ALG_CAST
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_cryptoapi.in linux-patched/net/ipsec/alg/Config.alg_cryptoapi.in
--- linux/net/ipsec/alg/Config.alg_cryptoapi.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_cryptoapi.in	Fri Feb 21 23:23:03 2003
@@ -0,0 +1,6 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  dep_tristate '        CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
+  if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
+    bool '          CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
+  fi
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_md5.in linux-patched/net/ipsec/alg/Config.alg_md5.in
--- linux/net/ipsec/alg/Config.alg_md5.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_md5.in	Thu Sep  5 04:31:27 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        HMAC_MD5 auth algorithm (modular alg)' CONFIG_IPSEC_ALG_MD5
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_null.in linux-patched/net/ipsec/alg/Config.alg_null.in
--- linux/net/ipsec/alg/Config.alg_null.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_null.in	Thu Sep  5 04:49:06 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        NULL encryption algorithm' CONFIG_IPSEC_ALG_NULL
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_serpent.in linux-patched/net/ipsec/alg/Config.alg_serpent.in
--- linux/net/ipsec/alg/Config.alg_serpent.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_serpent.in	Thu Sep  5 04:43:55 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        SERPENT encryption algorithm' CONFIG_IPSEC_ALG_SERPENT
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_sha1.in linux-patched/net/ipsec/alg/Config.alg_sha1.in
--- linux/net/ipsec/alg/Config.alg_sha1.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_sha1.in	Thu Sep  5 04:34:24 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        HMAC_SHA1 auth algorithm (modular alg)' CONFIG_IPSEC_ALG_SHA1
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_sha2.in linux-patched/net/ipsec/alg/Config.alg_sha2.in
--- linux/net/ipsec/alg/Config.alg_sha2.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_sha2.in	Thu Sep  5 04:34:24 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        HMAC_SHA2 auth algorithm' CONFIG_IPSEC_ALG_SHA2
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.alg_twofish.in linux-patched/net/ipsec/alg/Config.alg_twofish.in
--- linux/net/ipsec/alg/Config.alg_twofish.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.alg_twofish.in	Thu Sep  5 04:41:17 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        TWOFISH encryption algorithm' CONFIG_IPSEC_ALG_TWOFISH
+fi
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Config.in linux-patched/net/ipsec/alg/Config.in
--- linux/net/ipsec/alg/Config.in	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Config.in	Tue May 20 02:12:35 2003
@@ -0,0 +1,13 @@
+#Placeholder
+source net/ipsec/alg/Config.alg_md5.in
+source net/ipsec/alg/Config.alg_sha1.in
+source net/ipsec/alg/Config.alg_sha2.in
+source net/ipsec/alg/Config.alg_3des.in
+source net/ipsec/alg/Config.alg_aes.in
+source net/ipsec/alg/Config.alg_blowfish.in
+source net/ipsec/alg/Config.alg_twofish.in
+source net/ipsec/alg/Config.alg_serpent.in
+source net/ipsec/alg/Config.alg_cast.in
+source net/ipsec/alg/Config.alg_null.in
+source net/ipsec/alg/Config.alg_cryptoapi.in
+source net/ipsec/alg/Config.alg_1des.in
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile linux-patched/net/ipsec/alg/Makefile
--- linux/net/ipsec/alg/Makefile	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,104 @@
+# $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+KLIPSDIR:= $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)/..
+
+#LIBCRYPTO:=$(KLIPSDIR)/../../../libcrypto
+LIBCRYPTO:=$(KLIPSDIR)/libcrypto
+EXTRA_CFLAGS:=-I$(KLIPSDIR) -I$(KLIPSDIR)/libfreeswan -I$(LIBCRYPTO)/include -I$(LIBCRYPTO)
+ifeq ($(CONFIG_IPSEC_DEBUG),y)
+EXTRA_CFLAGS += -g
+endif
+EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
+
+MOD_LIST_NAME := NET_MISC_MODULES
+
+#O_TARGET := ipsec_alg_static.o
+
+subdir-  := 
+subdir-n := 
+subdir-y :=
+subdir-m :=
+
+obj-y := ipsec_alg_static_init.o
+
+ARCH_ASM-y :=
+ARCH_ASM-$(CONFIG_M586)		:= i586
+ARCH_ASM-$(CONFIG_M586TSC)	:= i586
+ARCH_ASM-$(CONFIG_M586MMX)	:= i586
+ARCH_ASM-$(CONFIG_MK6)		:= i586
+ARCH_ASM-$(CONFIG_M686)		:= i686
+ARCH_ASM-$(CONFIG_MPENTIUMIII)	:= i686
+ARCH_ASM-$(CONFIG_MPENTIUM4)	:= i686
+ARCH_ASM-$(CONFIG_MK7)		:= i686
+ARCH_ASM-$(CONFIG_MCRUSOE)	:= i586
+ARCH_ASM-$(CONFIG_MWINCHIPC6)	:= i586
+ARCH_ASM-$(CONFIG_MWINCHIP2)	:= i586
+ARCH_ASM-$(CONFIG_MWINCHIP3D)	:= i586
+ARCH_ASM-$(CONFIG_USERMODE)	:= i586
+
+ARCH_ASM :=$(ARCH_ASM-y)
+ifdef NO_ASM
+ARCH_ASM :=
+endif
+
+## debug:
+#$(warning CONFIG_M586=$(CONFIG_M586))
+#$(warning CONFIG_M686=$(CONFIG_M686))
+#$(warning ARCH_ASM=$(ARCH_ASM))
+# The algorithm makefiles may put dependences, short-circuit them
+null:
+
+makefiles=$(wildcard Makefile.alg_*)
+ifneq ($(makefiles),)
+#include Makefile.alg_aes
+#include Makefile.alg_aes-opt
+include $(makefiles)
+endif
+
+# These rules translate from new to old makefile rules
+# Translate to Rules.make lists.
+multi-used      := $(filter $(list-multi), $(obj-y) $(obj-m))
+multi-objs      := $(foreach m, $(multi-used), $($(basename $(m))-objs))
+active-objs     := $(sort $(multi-objs) $(obj-y) $(obj-m))
+O_OBJS          := $(obj-y)
+M_OBJS          := $(obj-m)
+MIX_OBJS        := $(filter $(export-objs), $(active-objs))
+#OX_OBJS := $(export-objs)
+SUB_DIRS := $(subdir-y)
+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
+MOD_SUB_DIRS := $(subdir-m)
+
+
+ifdef TOPDIR
+include $(TOPDIR)/Rules.make
+endif
+
+ipsec_alg_static.o: $(obj-y) 
+	rm -f $@
+	$(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@
+
+perlasm: $(LIBCRYPTO)/perlasm
+	ln -sf $? $@
+
+$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h ../ipsec_alg.h
+$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h ../ipsec_alg.h
+
+
+alg_modules: perlasm $(ALG_MODULES)
+	@echo "ALG_MODULES=$(ALG_MODULES)"
+
+
+#
+# Construct alg. init. function: call ipsec_ALGO_init() for every static algo
+# Needed when there are static algos (with static or modular ipsec.o)
+#
+ipsec_alg_static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh
+	@echo "Re-creating $@"
+	$(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@
+
+clean:
+	@for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0
+	@find . -type l  -exec rm -f {} \;
+	-rm -f perlasm
+	-rm -rf $(ALG_SUBDIRS)
+	-rm -f *.o ipsec_alg_static_init.c
+
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_1des linux-patched/net/ipsec/alg/Makefile.alg_1des
--- linux/net/ipsec/alg/Makefile.alg_1des	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_1des	Fri Mar 28 13:56:19 2003
@@ -0,0 +1,20 @@
+MOD_1DES += ipsec_1des.o
+
+ALG_MODULES += $(MOD_1DES)
+ALG_SUBDIRS += libdes
+
+obj-$(CONFIG_IPSEC_ALG_1DES) += $(MOD_1DES)
+static_init-func-$(CONFIG_IPSEC_ALG_1DES)+= ipsec_1des_init
+alg_obj-$(CONFIG_IPSEC_ALG_1DES) += ipsec_alg_1des.o
+
+DES_1DES_OBJS=ipsec_alg_1des.o ../libdes/libdes.a
+
+$(MOD_1DES): $(DES_1DES_OBJS)
+	$(LD) -r $(DES_1DES_OBJS) -o $@
+
+# avoid multiple rules for libdes.a
+ifeq ($(LIBDES),)
+LIBDES:=../libdes/libdes.a
+$(LIBDES):
+	$(MAKE) -C .. libdes/libdes.a
+endif
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_3des linux-patched/net/ipsec/alg/Makefile.alg_3des
--- linux/net/ipsec/alg/Makefile.alg_3des	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_3des	Fri Mar 28 13:56:19 2003
@@ -0,0 +1,20 @@
+MOD_3DES += ipsec_3des.o
+
+ALG_MODULES += $(MOD_3DES)
+ALG_SUBDIRS += libdes
+
+obj-$(CONFIG_IPSEC_ALG_3DES) += $(MOD_3DES)
+static_init-func-$(CONFIG_IPSEC_ALG_3DES)+= ipsec_3des_init
+alg_obj-$(CONFIG_IPSEC_ALG_3DES) += ipsec_alg_3des.o
+
+DES_3DES_OBJS=ipsec_alg_3des.o ../libdes/libdes.a
+
+$(MOD_3DES): $(DES_3DES_OBJS)
+	$(LD) -r $(DES_3DES_OBJS) -o $@
+
+# avoid multiple rules for libdes.a
+ifeq ($(LIBDES),)
+LIBDES:=../libdes/libdes.a
+$(LIBDES):
+	$(MAKE) -C .. libdes/libdes.a
+endif
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_aes linux-patched/net/ipsec/alg/Makefile.alg_aes
--- linux/net/ipsec/alg/Makefile.alg_aes	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_aes	Thu Sep  5 04:38:06 2002
@@ -0,0 +1,23 @@
+MOD_AES := ipsec_aes.o
+
+ALG_MODULES += $(MOD_AES)
+ALG_SUBDIRS += libaes
+
+obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
+static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
+alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
+
+AES_OBJS := ipsec_alg_aes.o libaes/libaes.a 
+
+$(MOD_AES): libaes $(AES_OBJS) 
+	$(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
+
+libaes: $(LIBCRYPTO)/libaes
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+	cd $@/asm && ln -sf $?/asm/*.S .
+
+libaes/libaes.a: libaes
+	( cd libaes && \
+		$(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libaes.a ;)
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_blowfish linux-patched/net/ipsec/alg/Makefile.alg_blowfish
--- linux/net/ipsec/alg/Makefile.alg_blowfish	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_blowfish	Thu Sep  5 04:39:46 2002
@@ -0,0 +1,23 @@
+MOD_BLOWFISH := ipsec_blowfish.o
+
+ALG_MODULES += $(MOD_BLOWFISH)
+ALG_SUBDIRS += libblowfish
+
+obj-$(CONFIG_IPSEC_ALG_BLOWFISH) += $(MOD_BLOWFISH)
+static_init-func-$(CONFIG_IPSEC_ALG_BLOWFISH)+= ipsec_blowfish_init
+alg_obj-$(CONFIG_IPSEC_ALG_BLOWFISH) += ipsec_alg_blowfish.o
+
+BLOWFISH_OBJS:= ipsec_alg_blowfish.o libblowfish/libblowfish.a
+
+$(MOD_BLOWFISH): libblowfish $(BLOWFISH_OBJS)
+	$(LD) -r $(BLOWFISH_OBJS) -o $@
+
+libblowfish : $(LIBCRYPTO)/libblowfish 
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+	cd $@/asm && ln -sf $?/asm/*.pl .
+
+libblowfish/libblowfish.a:
+	( cd libblowfish && \
+		$(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libblowfish.a ;)
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_cast linux-patched/net/ipsec/alg/Makefile.alg_cast
--- linux/net/ipsec/alg/Makefile.alg_cast	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_cast	Thu Sep  5 04:48:04 2002
@@ -0,0 +1,23 @@
+MOD_CAST := ipsec_cast.o
+
+ALG_MODULES += $(MOD_CAST)
+ALG_SUBDIRS += libcast
+
+obj-$(CONFIG_IPSEC_ALG_CAST) += $(MOD_CAST)
+static_init-func-$(CONFIG_IPSEC_ALG_CAST)+= ipsec_cast_init
+alg_obj-$(CONFIG_IPSEC_ALG_CAST) += ipsec_alg_cast.o
+
+CAST_OBJS := ipsec_alg_cast.o libcast/libcast.a
+
+$(MOD_CAST): libcast $(CAST_OBJS)
+	$(LD) -r $(CAST_OBJS) -o $@
+
+libcast : $(LIBCRYPTO)/libcast 
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+	cd $@/asm && ln -sf $?/asm/*.pl .
+
+libcast/libcast.a:
+	( cd libcast && \
+		$(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libcast.a ;)
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_cryptoapi linux-patched/net/ipsec/alg/Makefile.alg_cryptoapi
--- linux/net/ipsec/alg/Makefile.alg_cryptoapi	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_cryptoapi	Fri Feb  7 14:39:36 2003
@@ -0,0 +1,11 @@
+MOD_CRYPTOAPI := ipsec_cryptoapi.o
+
+ALG_MODULES += $(MOD_CRYPTOAPI)
+
+obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
+static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
+alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
+
+CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o 
+$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
+	$(LD) -r $(CRYPTOAPI_OBJS) -o $@
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_md5 linux-patched/net/ipsec/alg/Makefile.alg_md5
--- linux/net/ipsec/alg/Makefile.alg_md5	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_md5	Thu Sep  5 04:31:27 2002
@@ -0,0 +1,23 @@
+MOD_MD5 := ipsec_md5.o
+
+ALG_MODULES += $(MOD_MD5)
+ALG_SUBDIRS += libmd5
+
+obj-$(CONFIG_IPSEC_ALG_MD5) += $(MOD_MD5)
+static_init-func-$(CONFIG_IPSEC_ALG_MD5)+= ipsec_md5_init
+alg_obj-$(CONFIG_IPSEC_ALG_MD5) += ipsec_alg_md5.o
+
+MD5_OBJS :=ipsec_alg_md5.o libmd5/libmd5.a
+
+$(MOD_MD5): libmd5 $(MD5_OBJS)
+	$(LD) $(EXTRA_LDFLAGS) -r $(MD5_OBJS) -o $@
+
+libmd5 : $(LIBCRYPTO)/libmd5 
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+	cd $@/asm && ln -sf $?/asm/*.pl .
+
+libmd5/libmd5.a:
+	( cd libmd5 && \
+		$(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libmd5.a ;)
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_null linux-patched/net/ipsec/alg/Makefile.alg_null
--- linux/net/ipsec/alg/Makefile.alg_null	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_null	Thu Sep  5 04:49:06 2002
@@ -0,0 +1,13 @@
+MOD_NULL := ipsec_null.o
+
+ALG_MODULES += $(MOD_NULL)
+ALG_SUBDIRS += 
+
+obj-$(CONFIG_IPSEC_ALG_NULL) += ipsec_null.o
+static_init-func-$(CONFIG_IPSEC_ALG_NULL)+= ipsec_null_init
+alg_obj-$(CONFIG_IPSEC_ALG_NULL) += ipsec_alg_null.o
+
+NULL_OBJS=ipsec_alg_null.o
+ipsec_null.o: $(NULL_OBJS)
+	$(LD) -r $(NULL_OBJS) -o $@
+
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_serpent linux-patched/net/ipsec/alg/Makefile.alg_serpent
--- linux/net/ipsec/alg/Makefile.alg_serpent	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_serpent	Thu Sep  5 04:43:55 2002
@@ -0,0 +1,21 @@
+MOD_SERPENT := ipsec_serpent.o
+
+ALG_MODULES += $(MOD_SERPENT)
+ALG_SUBDIRS += libserpent
+
+obj-$(CONFIG_IPSEC_ALG_SERPENT) += $(MOD_SERPENT)
+static_init-func-$(CONFIG_IPSEC_ALG_SERPENT)+= ipsec_serpent_init
+alg_obj-$(CONFIG_IPSEC_ALG_SERPENT) += ipsec_alg_serpent.o
+
+SERPENT_OBJS=ipsec_alg_serpent.o libserpent/libserpent.a
+$(MOD_SERPENT) : libserpent $(SERPENT_OBJS)
+	$(LD) -r $(SERPENT_OBJS) -o $@
+
+libserpent : $(LIBCRYPTO)/libserpent 
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+
+libserpent/libserpent.a:
+	( cd libserpent && \
+		$(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libserpent.a ;)
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_sha1 linux-patched/net/ipsec/alg/Makefile.alg_sha1
--- linux/net/ipsec/alg/Makefile.alg_sha1	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_sha1	Thu Sep  5 04:34:24 2002
@@ -0,0 +1,23 @@
+MOD_SHA1 := ipsec_sha1.o
+
+ALG_MODULES += $(MOD_SHA1)
+ALG_SUBDIRS += libsha1
+
+obj-$(CONFIG_IPSEC_ALG_SHA1) += $(MOD_SHA1)
+static_init-func-$(CONFIG_IPSEC_ALG_SHA1)+= ipsec_sha1_init
+alg_obj-$(CONFIG_IPSEC_ALG_SHA1) += ipsec_alg_sha1.o
+
+SHA1_OBJS :=ipsec_alg_sha1.o libsha1/libsha1.a
+
+$(MOD_SHA1): libsha1 $(SHA1_OBJS)
+	$(LD) $(EXTRA_LDFLAGS) -r $(SHA1_OBJS) -o $@
+
+libsha1 : $(LIBCRYPTO)/libsha1 
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+	cd $@/asm && ln -sf $?/asm/*.pl .
+
+libsha1/libsha1.a:
+	( cd libsha1 && \
+		$(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libsha1.a ;)
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_sha2 linux-patched/net/ipsec/alg/Makefile.alg_sha2
--- linux/net/ipsec/alg/Makefile.alg_sha2	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_sha2	Thu Sep  5 04:34:24 2002
@@ -0,0 +1,22 @@
+MOD_SHA2 := ipsec_sha2.o
+
+ALG_MODULES += $(MOD_SHA2)
+ALG_SUBDIRS += libsha2
+
+obj-$(CONFIG_IPSEC_ALG_SHA2) += $(MOD_SHA2)
+static_init-func-$(CONFIG_IPSEC_ALG_SHA2)+= ipsec_sha2_init
+alg_obj-$(CONFIG_IPSEC_ALG_SHA2) += ipsec_alg_sha2.o
+
+SHA2_OBJS := ipsec_alg_sha2.o libsha2/libsha2.a
+
+$(MOD_SHA2): libsha2 $(SHA2_OBJS)
+	$(LD) $(EXTRA_LDFLAGS) -r $(SHA2_OBJS) -o $@
+
+libsha2 : $(LIBCRYPTO)/libsha2 
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+	
+libsha2/libsha2.a:
+	( cd libsha2 && \
+		$(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libsha2.a ;)
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/Makefile.alg_twofish linux-patched/net/ipsec/alg/Makefile.alg_twofish
--- linux/net/ipsec/alg/Makefile.alg_twofish	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/Makefile.alg_twofish	Thu Sep  5 04:41:17 2002
@@ -0,0 +1,21 @@
+MOD_TWOFISH := ipsec_twofish.o
+
+ALG_MODULES += $(MOD_TWOFISH)
+ALG_SUBDIRS += libtwofish
+
+obj-$(CONFIG_IPSEC_ALG_TWOFISH) += $(MOD_TWOFISH)
+static_init-func-$(CONFIG_IPSEC_ALG_TWOFISH)+= ipsec_twofish_init
+alg_obj-$(CONFIG_IPSEC_ALG_TWOFISH) += ipsec_alg_twofish.o
+
+TWOFISH_OBJS := ipsec_alg_twofish.o libtwofish/libtwofish.a
+$(MOD_TWOFISH): libtwofish $(TWOFISH_OBJS)
+	$(LD) -r $(TWOFISH_OBJS) -o $@
+
+libtwofish : $(LIBCRYPTO)/libtwofish 
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+
+libtwofish/libtwofish.a:
+	( cd libtwofish && \
+		$(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libtwofish.a ;)
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_1des.c linux-patched/net/ipsec/alg/ipsec_alg_1des.c
--- linux/net/ipsec/alg/ipsec_alg_1des.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_1des.c	Mon Mar 17 11:50:43 2003
@@ -0,0 +1,161 @@
+/*
+ * ipsec_alg 1DES cipher 
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ *
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_1DES
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+#include <linux/socket.h>
+#include <linux/in.h>
+#include "ipsec_param.h"
+#include "ipsec_sa.h"
+#include "ipsec_alg.h"
+#include "../libdes/des.h"
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int I_know_des_is_insecure=0;
+MODULE_PARM(I_know_des_is_insecure, "i");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+static int esp_id=0;
+MODULE_PARM(esp_id, "i");
+
+#define ESP_DES			2
+
+#define ESP_DES_CBC_BLKLEN	8	/* 64 bit blocks */
+#define ESP_DES_KEY_SZ		8	/* 56 bits keylen :P */
+
+struct des1_eks{
+	des_key_schedule ctx[1];
+};
+static int _1des_set_key(struct ipsec_alg_enc *alg,__u8 *key_e, const __u8 * key, size_t keysize) {
+	des_key_schedule *ctx=((struct des1_eks*)key_e)->ctx;
+	int error;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _1des_set_key: "
+				"key_e=%p key=%p keysize=%d\n",
+				key_e, key, keysize);
+	if (!I_know_des_is_insecure)
+		printk(KERN_WARNING "You should NOT use 1DES except for testing purposes !\n");
+	des_set_odd_parity((des_cblock *)key);
+	error = des_set_key((des_cblock *)key, ctx[0]);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:des_set_key:"
+			"ctx[%d]=%p, error=%d \n",
+			0, ctx[0], error);
+	if (error == -1)
+		printk("klips_debug: _1des_set_key: "
+				"parity error in 1des key\n");
+	else if (error == -2)
+		printk("klips_debug: _1des_set_key: "
+				"illegal weak 1des key \n");
+	if (error)
+		return error;
+	return 0;
+}
+void des_cbc_encrypt(des_cblock *input, des_cblock *output,
+		long length, des_key_schedule ks, 
+		des_cblock *ivec, int enc);
+
+static int _1des_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
+	char iv_buf[ESP_DES_CBC_BLKLEN];
+	des_key_schedule *ctx=((struct des1_eks*)key_e)->ctx;
+	*((__u32*)&(iv_buf)) = ((__u32*)(iv))[0];
+	*((__u32*)&(iv_buf)+1) = ((__u32*)(iv))[1];
+	if (debug > 1) {
+		printk(KERN_DEBUG "klips_debug:_1des_cbc_encrypt:"
+				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
+				ctx, in, ilen, iv, encrypt);
+	}
+	des_cbc_encrypt((des_cblock*) in, (des_cblock*) in, ilen, ctx[0], (des_cblock *)iv_buf, encrypt);
+	return ilen;
+}
+static struct ipsec_alg_enc ipsec_alg_1DES = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_name: 	"1des",
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_DES,
+	ixt_blocksize:	ESP_DES_CBC_BLKLEN,
+	ixt_keyminbits:	ESP_DES_KEY_SZ*7, /*  7bits key+1bit parity  */
+	ixt_keymaxbits:	ESP_DES_KEY_SZ*7, /*  7bits key+1bit parity  */
+	ixt_e_keylen:	ESP_DES_KEY_SZ,
+	ixt_e_ctx_size:	sizeof(struct des1_eks),
+	ixt_e_set_key:	_1des_set_key,
+	ixt_e_cbc_encrypt:_1des_cbc_encrypt,
+};
+	
+IPSEC_ALG_MODULE_INIT(ipsec_1des_init)
+{
+	int ret, test_ret;
+	if (esp_id)
+		ipsec_alg_1DES.ixt_alg_id=esp_id;
+	if (excl) ipsec_alg_1DES.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_enc(&ipsec_alg_1DES);
+	printk("ipsec_1des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_1DES.ixt_alg_type, 
+			ipsec_alg_1DES.ixt_alg_id, 
+			ipsec_alg_1DES.ixt_name, 
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_1DES.ixt_alg_type,
+				ipsec_alg_1DES.ixt_alg_id, 
+				test);
+		printk("ipsec_1des_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_1DES.ixt_alg_type, 
+				ipsec_alg_1DES.ixt_alg_id, 
+				test_ret);
+	}
+	if (!I_know_des_is_insecure)
+		printk(KERN_WARNING "You should NOT load 1DES support except for testing purposes !\n");
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT(ipsec_1des_fini)
+{
+	unregister_ipsec_alg_enc(&ipsec_alg_1DES);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_3des.c linux-patched/net/ipsec/alg/ipsec_alg_3des.c
--- linux/net/ipsec/alg/ipsec_alg_3des.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_3des.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,160 @@
+/*
+ * ipsec_alg 3DES cipher
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ *
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_3DES
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+#include <linux/socket.h>
+#include <linux/in.h>
+#include "ipsec_param.h"
+#include "ipsec_sa.h"
+#include "ipsec_alg.h"
+#include "../libdes/des.h"
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+static int esp_id=0;
+MODULE_PARM(esp_id, "i");
+
+#define ESP_3DES		3
+
+#define ESP_3DES_CBC_BLKLEN	8	/* 64 bit blocks */
+#define ESP_DES_KEY_SZ		8
+#define ESP_3DES_KEY_SZ		8*3 	/* 3DES */
+
+struct des3_eks{
+	des_key_schedule ctx[3];
+};
+static int _3des_set_key(struct ipsec_alg_enc *alg,__u8 *key_e, const __u8 * key, size_t keysize) {
+	des_key_schedule *ctx=((struct des3_eks*)key_e)->ctx;
+	int i, error;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _3des_set_key: "
+				"key_e=%p key=%p keysize=%d\n",
+				key_e, key, keysize);
+	for(i = 0; i < 3; i++) {
+		des_set_odd_parity((des_cblock *)(key+ESP_DES_KEY_SZ * i));
+		error = des_set_key((des_cblock *)(key+ESP_DES_KEY_SZ * i),
+				    ctx[i]);
+		if (debug > 0)
+			printk(KERN_DEBUG "klips_debug:des_set_key:"
+				"ctx[%d]=%p, error=%d \n",
+				i, ctx[i], error);
+		if (error == -1)
+			printk("klips_debug: _3des_set_key: "
+					"parity error in des key %d/3\n",
+					i + 1);
+		else if (error == -2)
+			printk("klips_debug: _3des_set_key: "
+					"illegal weak des key %d/3\n", i + 1);
+		if (error)
+			return error;
+	}
+	return 0;
+}
+void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
+		long length, des_key_schedule ks1, des_key_schedule ks2,
+		des_key_schedule ks3, des_cblock *ivec, int enc);
+
+static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
+	char iv_buf[ESP_3DES_CBC_BLKLEN];
+	des_key_schedule *ctx=((struct des3_eks*)key_e)->ctx;
+	*((__u32*)&(iv_buf)) = ((__u32*)(iv))[0];
+	*((__u32*)&(iv_buf)+1) = ((__u32*)(iv))[1];
+	if (debug > 1) {
+		printk(KERN_DEBUG "klips_debug:_3des_cbc_encrypt:"
+				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
+				ctx, in, ilen, iv, encrypt);
+	}
+	des_ede3_cbc_encrypt((des_cblock*) in, (des_cblock*) in, ilen, ctx[0], ctx[1], ctx[2], (des_cblock *)iv_buf, encrypt);
+	return ilen;
+}
+static struct ipsec_alg_enc ipsec_alg_3DES = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_name: 	"3des",
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_3DES,
+	ixt_blocksize:	ESP_3DES_CBC_BLKLEN,
+	ixt_keyminbits:	ESP_3DES_KEY_SZ*7, /*  7bits key+1bit parity  */
+	ixt_keymaxbits:	ESP_3DES_KEY_SZ*7, /*  7bits key+1bit parity  */
+	ixt_e_keylen:	ESP_3DES_KEY_SZ,
+	ixt_e_ctx_size:	sizeof(struct des3_eks),
+	ixt_e_set_key:	_3des_set_key,
+	ixt_e_cbc_encrypt:_3des_cbc_encrypt,
+};
+	
+IPSEC_ALG_MODULE_INIT(ipsec_3des_init)
+{
+	int ret, test_ret;
+	if (esp_id)
+		ipsec_alg_3DES.ixt_alg_id=esp_id;
+	if (excl) ipsec_alg_3DES.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_enc(&ipsec_alg_3DES);
+	printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_3DES.ixt_alg_type, 
+			ipsec_alg_3DES.ixt_alg_id, 
+			ipsec_alg_3DES.ixt_name, 
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_3DES.ixt_alg_type,
+				ipsec_alg_3DES.ixt_alg_id, 
+				test);
+		printk("ipsec_3des_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_3DES.ixt_alg_type, 
+				ipsec_alg_3DES.ixt_alg_id, 
+				test_ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT(ipsec_3des_fini)
+{
+	unregister_ipsec_alg_enc(&ipsec_alg_3DES);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_aes.c linux-patched/net/ipsec/alg/ipsec_alg_aes.c
--- linux/net/ipsec/alg/ipsec_alg_aes.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_aes.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,253 @@
+/*
+ * ipsec_alg AES cipher stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * Fixes by:
+ * 	PK:	Pawel Krawczyk <kravietz@aba.krakow.pl>
+ * Fixes list:
+ * 	PK:	make XCBC comply with latest draft (keylength)
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+#include "libaes/aes_cbc.h"
+
+#define CONFIG_IPSEC_ALG_AES_MAC 1
+
+#define AES_CONTEXT_T aes_context
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+static int keyminbits=0;
+MODULE_PARM(keyminbits, "i");
+static int keymaxbits=0;
+MODULE_PARM(keymaxbits, "i");
+
+#if CONFIG_IPSEC_ALG_AES_MAC
+#include "libaes/aes_xcbc_mac.h"
+
+/*	
+ *	Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
+ *	We use 9 for non-modular algorithm and none for modular, thus
+ *	forcing user to specify one on module load. -kravietz
+ */
+#ifdef MODULE
+static int auth_id=0;
+#else
+static int auth_id=9;
+#endif
+MODULE_PARM(auth_id, "i");
+#endif
+
+#define ESP_AES			12	/* truely _constant_  :)  */
+
+/* 128, 192 or 256 */
+#define ESP_AES_KEY_SZ_MIN	16 	/* 128 bit secret key */
+#define ESP_AES_KEY_SZ_MAX	32 	/* 256 bit secret key */
+#define ESP_AES_CBC_BLK_LEN	16	/* AES-CBC block size */
+
+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
+ * -kravietz
+ */
+#define ESP_AES_MAC_KEY_SZ	16	/* 128 bit MAC key */
+#define ESP_AES_MAC_BLK_LEN	16	/* 128 bit block */
+
+static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
+	int ret;
+	AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
+	ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_aes_set_key:"
+				"ret=%d key_e=%p key=%p keysize=%d\n",
+				ret, key_e, key, keysize);
+	return ret;
+}
+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
+	AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
+				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
+				key_e, in, ilen, iv, encrypt);
+	return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
+}
+#if CONFIG_IPSEC_ALG_AES_MAC
+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
+	aes_context_mac *ctxm=(aes_context_mac *)key_a;
+	return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
+}
+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
+	int ret;
+	char hash_buf[16];
+	aes_context_mac *ctxm=(aes_context_mac *)key_a;
+	ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
+	memcpy(hash, hash_buf, hashlen);
+	return ret;
+}
+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_AUTH,
+	ixt_alg_id: 	0,
+	ixt_name: 	"aes_mac",
+	ixt_blocksize:	ESP_AES_MAC_BLK_LEN,
+	ixt_keyminbits:	ESP_AES_MAC_KEY_SZ*8,
+	ixt_keymaxbits:	ESP_AES_MAC_KEY_SZ*8,
+	ixt_a_keylen:	ESP_AES_MAC_KEY_SZ,
+	ixt_a_ctx_size:	sizeof(aes_context_mac),
+	ixt_a_hmac_set_key:	_aes_mac_set_key,
+	ixt_a_hmac_hash:_aes_mac_hash,
+};
+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
+static struct ipsec_alg_enc ipsec_alg_AES = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_AES,
+	ixt_name: 	"aes",
+	ixt_blocksize:	ESP_AES_CBC_BLK_LEN, 
+	ixt_keyminbits:	ESP_AES_KEY_SZ_MIN*8,
+	ixt_keymaxbits:	ESP_AES_KEY_SZ_MAX*8,
+	ixt_e_keylen:	ESP_AES_KEY_SZ_MAX,
+	ixt_e_ctx_size:	sizeof(AES_CONTEXT_T),
+	ixt_e_set_key:	_aes_set_key,
+	ixt_e_cbc_encrypt:_aes_cbc_encrypt,
+};
+	
+IPSEC_ALG_MODULE_INIT( ipsec_aes_init )
+{
+	int ret, test_ret;
+	if (keyminbits)
+		ipsec_alg_AES.ixt_keyminbits=keyminbits;
+	if (keymaxbits) {
+		ipsec_alg_AES.ixt_keymaxbits=keymaxbits;
+		if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits)
+			ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
+	}
+	if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_enc(&ipsec_alg_AES);
+	printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_AES.ixt_alg_type, 
+			ipsec_alg_AES.ixt_alg_id, 
+			ipsec_alg_AES.ixt_name, 
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_AES.ixt_alg_type,
+				ipsec_alg_AES.ixt_alg_id, 
+				test);
+		printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_AES.ixt_alg_type, 
+				ipsec_alg_AES.ixt_alg_id, 
+				test_ret);
+	}
+#if CONFIG_IPSEC_ALG_AES_MAC
+	if (auth_id!=0){
+		int ret;
+		ipsec_alg_AES_MAC.ixt_alg_id=auth_id;
+		ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
+		printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+				ipsec_alg_AES_MAC.ixt_alg_type, 
+				ipsec_alg_AES_MAC.ixt_alg_id, 
+				ipsec_alg_AES_MAC.ixt_name, 
+				ret);
+		if (ret==0 && test) {
+			test_ret=ipsec_alg_test(
+					ipsec_alg_AES_MAC.ixt_alg_type,
+					ipsec_alg_AES_MAC.ixt_alg_id, 
+					test);
+			printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+					ipsec_alg_AES_MAC.ixt_alg_type, 
+					ipsec_alg_AES_MAC.ixt_alg_id, 
+					test_ret);
+		}
+	} else {
+		printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
+	}
+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT( ipsec_aes_fini )
+{
+#if CONFIG_IPSEC_ALG_AES_MAC
+	if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
+	unregister_ipsec_alg_enc(&ipsec_alg_AES);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+#if 0+NOT_YET
+#ifndef MODULE
+/*
+ * 	This is intended for static module setups, currently
+ * 	doesn't work for modular ipsec.o with static algos inside
+ */
+static int setup_keybits(const char *str)
+{
+	unsigned aux;
+	char *end;
+
+	aux = simple_strtoul(str,&end,0);
+	if (aux != 128 && aux != 192 && aux != 256)
+		return 0;
+	keyminbits = aux;
+
+	if (*end == 0 || *end != ',')
+		return 1;
+	str=end+1;
+	aux = simple_strtoul(str, NULL, 0);
+	if (aux != 128 && aux != 192 && aux != 256)
+		return 0;
+	if (aux >= keyminbits)
+		keymaxbits = aux;
+	return 1;
+}
+__setup("ipsec_aes_keybits=", setup_keybits);
+#endif
+#endif
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_blowfish.c linux-patched/net/ipsec/alg/ipsec_alg_blowfish.c
--- linux/net/ipsec/alg/ipsec_alg_blowfish.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_blowfish.c	Thu May  8 14:48:39 2003
@@ -0,0 +1,143 @@
+/*
+ * ipsec_alg BLOWFISH cipher stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_BLOWFISH
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+#include "libblowfish/blowfish.h"
+#define blowfish_context BF_KEY
+
+#define ESP_BLOWFISH			7	/* truely _constant_  :)  */
+
+#define ESP_BLOWFISH_KEY_SZ_MIN	12 	/* 96 bit secret key min */
+#define ESP_BLOWFISH_KEY_SZ		16 	/* 128 bit secret key */
+#define ESP_BLOWFISH_KEY_SZ_MAX		56 	/* 448 bit secret key */
+#define ESP_BLOWFISH_CBC_BLK_LEN	8  	/* block size */
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+static int keyminbits=0;
+MODULE_PARM(keyminbits, "i");
+static int keymaxbits=0;
+MODULE_PARM(keymaxbits, "i");
+
+static int _blowfish_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
+	blowfish_context *ctx=(blowfish_context*)key_e;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_blowfish_set_key:"
+				"key_e=%p key=%p keysize=%d\n",
+				key_e, key, keysize);
+	BF_set_key(ctx, keysize, (unsigned char *)key);
+	return 0;
+}
+static int _blowfish_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 *iv, int encrypt) {
+	/* blowfish toasts passed IV */
+	__u8    iv_buf[ESP_BLOWFISH_CBC_BLK_LEN];
+	blowfish_context *ctx=(blowfish_context*)key_e;
+	*((__u32*)&(iv_buf)) = ((__u32*)(iv))[0];
+	*((__u32*)&(iv_buf)+1) = ((__u32*)(iv))[1];
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_blowfish_cbc_encrypt:"
+				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
+				key_e, in, ilen, iv_buf, encrypt);
+	BF_cbc_encrypt(in, in, ilen, ctx, iv_buf, encrypt);
+	return ilen;
+}
+static struct ipsec_alg_enc ipsec_alg_BLOWFISH = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_BLOWFISH,
+	ixt_name: 	"blowfish",
+	ixt_blocksize:	ESP_BLOWFISH_CBC_BLK_LEN,
+	ixt_keyminbits:	ESP_BLOWFISH_KEY_SZ_MIN*8,
+	ixt_keymaxbits:	ESP_BLOWFISH_KEY_SZ_MAX*8,
+	ixt_e_keylen:	ESP_BLOWFISH_KEY_SZ,	
+	ixt_e_ctx_size:	sizeof(blowfish_context),
+	ixt_e_set_key:	_blowfish_set_key,
+	ixt_e_cbc_encrypt:_blowfish_cbc_encrypt,
+};
+
+IPSEC_ALG_MODULE_INIT(ipsec_blowfish_init)
+{
+	int ret, test_ret;
+	if (keyminbits)
+		ipsec_alg_BLOWFISH.ixt_keyminbits=keyminbits;
+	if (keymaxbits) {
+		ipsec_alg_BLOWFISH.ixt_keymaxbits=keymaxbits;
+		if (keymaxbits*8>ipsec_alg_BLOWFISH.ixt_keymaxbits)
+			ipsec_alg_BLOWFISH.ixt_e_keylen=keymaxbits*8;
+	}
+	if (excl) ipsec_alg_BLOWFISH.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_enc(&ipsec_alg_BLOWFISH);
+	printk("ipsec_blowfish_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_BLOWFISH.ixt_alg_type, 
+			ipsec_alg_BLOWFISH.ixt_alg_id, 
+			ipsec_alg_BLOWFISH.ixt_name, 
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_BLOWFISH.ixt_alg_type,
+				ipsec_alg_BLOWFISH.ixt_alg_id, 
+				test);
+		printk("ipsec_blowfish_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_BLOWFISH.ixt_alg_type, 
+				ipsec_alg_BLOWFISH.ixt_alg_id, 
+				test_ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT(ipsec_blowfish_fini)
+{
+	unregister_ipsec_alg_enc(&ipsec_alg_BLOWFISH);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_cast.c linux-patched/net/ipsec/alg/ipsec_alg_cast.c
--- linux/net/ipsec/alg/ipsec_alg_cast.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_cast.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,144 @@
+/*
+ * ipsec_alg CAST cipher stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CAST
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+#define cast_context cast_key
+#include "libcast/cast.h"
+
+#define ESP_CAST		6	/* quite constant :) */
+
+#define ESP_CAST_KEY_SZ_MIN	5
+#define ESP_CAST_KEY_SZ		16 	/* 128 bit secret key */
+#define ESP_CAST_CBC_BLK_LEN	8	/* CAST-CBC block size */
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+static int keyminbits=0;
+MODULE_PARM(keyminbits, "i");
+static int keymaxbits=0;
+MODULE_PARM(keymaxbits, "i");
+
+#undef cast_context
+#define cast_context CAST_KEY
+static int _cast_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
+	cast_context *ctx=(cast_context *)key_e;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_cast_set_key:"
+				"key_e=%p key=%p keysize=%d\n",
+				key_e, key, keysize);
+	CAST_set_key(ctx, keysize, (u_int8_t *)key);
+	return 0;
+}
+static int _cast_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
+	/* cast toasts passed IV */
+	__u8    iv_buf[ESP_CAST_CBC_BLK_LEN];
+	cast_context *ctx=(cast_context *)key_e;
+	*((__u32*)&(iv_buf)) = ((__u32*)(iv))[0];
+	*((__u32*)&(iv_buf)+1) = ((__u32*)(iv))[1];
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_cast_cbc_encrypt:"
+				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
+				key_e, in, ilen, iv, encrypt);
+	CAST_cbc_encrypt(in, in, ilen, ctx, iv_buf, encrypt);
+	return ilen;
+}
+static struct ipsec_alg_enc ipsec_alg_CAST = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_CAST,
+	ixt_name: 	"cast",
+	ixt_blocksize:	ESP_CAST_CBC_BLK_LEN, 
+	ixt_keyminbits:	ESP_CAST_KEY_SZ_MIN*8,
+	ixt_keymaxbits:	ESP_CAST_KEY_SZ*8,
+	ixt_e_keylen:	ESP_CAST_KEY_SZ,
+	ixt_e_ctx_size:	sizeof(cast_context),
+	ixt_e_set_key:	_cast_set_key,
+	ixt_e_cbc_encrypt:_cast_cbc_encrypt,
+};
+	
+IPSEC_ALG_MODULE_INIT(ipsec_cast_init)
+{
+	int ret, test_ret;
+	if (keyminbits)
+		ipsec_alg_CAST.ixt_keyminbits=keyminbits;
+	if (keymaxbits) {
+		ipsec_alg_CAST.ixt_keymaxbits=keymaxbits;
+		if (keymaxbits*8>ipsec_alg_CAST.ixt_keymaxbits)
+			ipsec_alg_CAST.ixt_e_keylen=keymaxbits*8;
+	}
+	if (excl) ipsec_alg_CAST.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_enc(&ipsec_alg_CAST);
+	printk("ipsec_cast_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_CAST.ixt_alg_type, 
+			ipsec_alg_CAST.ixt_alg_id, 
+			ipsec_alg_CAST.ixt_name, 
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_CAST.ixt_alg_type,
+				ipsec_alg_CAST.ixt_alg_id, 
+				test);
+		printk("ipsec_cast_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_CAST.ixt_alg_type, 
+				ipsec_alg_CAST.ixt_alg_id, 
+				test_ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT(ipsec_cast_fini)
+{
+	unregister_ipsec_alg_enc(&ipsec_alg_CAST);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_cryptoapi.c linux-patched/net/ipsec/alg/ipsec_alg_cryptoapi.c
--- linux/net/ipsec/alg/ipsec_alg_cryptoapi.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_cryptoapi.c	Fri Feb  7 14:39:36 2003
@@ -0,0 +1,556 @@
+/*
+ * ipsec_alg to linux cryptoapi GLUE
+ *
+ * Authors: CODE.ar TEAM
+ * 	Harpo MAxx <harpo@linuxmendoza.org.ar>
+ * 	JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 	Luciano Ruete <docemeses@softhome.net>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * Example usage:
+ *   modinfo -p ipsec_cryptoapi   (quite useful info, including supported algos)
+ *   modprobe ipsec_cryptoapi
+ *   modprobe ipsec_cryptoapi test=1
+ *   modprobe ipsec_cryptoapi excl=1                     (exclusive cipher/algo)
+ *   modprobe ipsec_cryptoapi latebind=1                 (defer cipher binding)
+ *   modprobe ipsec_cryptoapi noauto=1  aes=1 twofish=1  (only these ciphers)
+ *   modprobe ipsec_cryptoapi aes=128,128                (force these keylens)
+ *   modprobe ipsec_cryptoapi des_ede3=0                 (everything but 3DES)
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/* warn the innocent */
+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
+#warning "No linux cryptoapi setup found... you *MUST*  install it ! (www.kerneli.org)"
+#endif
+/*	Low freeswan header coupling	*/
+#include <ipsec_alg.h>
+#include <linux/crypto.h>
+
+#ifndef  CRYPTO_API_VERSION_CODE
+#error "you *MUST*  install linux cryptoapi ! (www.kerneli.org)"
+#endif
+#define ESP_3DES		3
+#define CIPHERNAME_3DES		"des_ede3-cbc"
+
+#define ESP_AES			12
+#define CIPHERNAME_AES		"aes-cbc"
+
+#define ESP_BLOWFISH		7	/* truely _constant_  :)  */
+#define CIPHERNAME_BLOWFISH	"blowfish-cbc"
+
+#define ESP_CAST		6	/* quite constant :) */
+#define CIPHERNAME_CAST		"cast5-cbc"
+
+#define ESP_SERPENT		252	/* from ipsec drafts */
+#define CIPHERNAME_SERPENT	"serpent-cbc"
+
+#define ESP_TWOFISH		253	/* from ipsec drafts */
+#define CIPHERNAME_TWOFISH	"twofish-cbc"
+
+#define AH_MD5			2
+#define DIGESTNAME_MD5		"md5"
+
+#define AH_SHA			3
+#define DIGESTNAME_SHA1		"sha1"
+
+
+#ifdef CONFIG_IPSEC_ALG_NON_LIBRE
+#define ESP_MARS		249	/* from ipsec drafts */
+#define CIPHERNAME_MARS		"mars-cbc"
+
+#define ESP_RC6			250	/* from ipsec drafts */
+#define CIPHERNAME_RC6		"rc6-cbc"
+#endif /* CONFIG_IPSEC_ALG_NON_LIBRE */
+
+MODULE_AUTHOR("CODE.ar team: Harpo MAxx, Juanjo Ciarlante, Luciano Ruete");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+
+static int noauto = 0;
+MODULE_PARM(noauto,"i");
+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
+
+static int latebind = 0;
+MODULE_PARM(latebind,"i");
+MODULE_PARM_DESC(latebind, "Bind cryptoapi ciphers at SA creation time");
+
+static int des_ede3[] = {-1, -1};
+static int aes[] = {-1, -1};
+static int blowfish[] = {-1, -1};
+static int cast[] = {-1, -1};
+static int serpent[] = {-1, -1};
+static int twofish[] = {-1, -1};
+#ifdef CONFIG_IPSEC_ALG_NON_LIBRE
+static int mars[] = {-1, -1};
+static int rc6[] = {-1, -1};
+#endif /* CONFIG_IPSEC_ALG_NON_LIBRE */
+
+MODULE_PARM(des_ede3,"1-2i");
+MODULE_PARM(aes,"1-2i");
+MODULE_PARM(blowfish,"1-2i");
+MODULE_PARM(cast,"1-2i");
+MODULE_PARM(serpent,"1-2i");
+MODULE_PARM(twofish,"1-2i");
+#ifdef CONFIG_IPSEC_ALG_NON_LIBRE
+MODULE_PARM(mars,"1-2i");
+MODULE_PARM(rc6,"1-2i");
+#endif /* CONFIG_IPSEC_ALG_NON_LIBRE */
+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
+#ifdef CONFIG_IPSEC_ALG_NON_LIBRE
+MODULE_PARM_DESC(mars, "0: disable | 1: force_enable | min,max: keybitlens");
+MODULE_PARM_DESC(rc6, "0: disable | 1: force_enable | min,max: keybitlens");
+#endif /* CONFIG_IPSEC_ALG_NON_LIBRE */
+
+struct ipsec_alg_capi_cipher {
+	const char *ciphername;	/* cryptoapi's ciphername */
+	int *parm;		/* lkm param for this cipher */
+	struct cipher_implementation *ci;	/* actual ci */
+	struct ipsec_alg_enc alg;	/* note it's not a pointer */
+	atomic_t ci_usecnt;		/* ci use count */
+};
+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
+	{ CIPHERNAME_AES,     aes    , NULL, { ixt_alg_id: ESP_AES, }},
+	{ CIPHERNAME_TWOFISH, twofish, NULL, { ixt_alg_id: ESP_TWOFISH, }},
+	{ CIPHERNAME_SERPENT, serpent, NULL, { ixt_alg_id: ESP_SERPENT, }},
+	{ CIPHERNAME_CAST,    cast   , NULL, { ixt_alg_id: ESP_CAST, }},
+	{ CIPHERNAME_BLOWFISH,blowfish,NULL, { ixt_alg_id: ESP_BLOWFISH, }},
+	{ CIPHERNAME_3DES,    des_ede3,NULL, { ixt_alg_id: ESP_3DES, }},
+#ifdef CONFIG_IPSEC_ALG_NON_LIBRE
+	{ CIPHERNAME_MARS,    mars   , NULL, { ixt_alg_id: ESP_MARS, }},
+	{ CIPHERNAME_RC6,     rc6    , NULL, { ixt_alg_id: ESP_RC6, }},
+#endif /* CONFIG_IPSEC_ALG_NON_LIBRE */
+	{ NULL, NULL, NULL, {} }
+};
+#ifdef NOT_YET
+struct ipsec_alg_capi_digest {
+	const char *digestname;	/* cryptoapi's digestname */
+	struct digest_implementation *di;
+	struct ipsec_alg_auth alg;	/* note it's not a pointer */
+};
+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
+	{ DIGESTNAME_MD5,     NULL, { ixt_alg_id: AH_MD5, }},
+	{ DIGESTNAME_SHA1,    NULL, { ixt_alg_id: AH_SHA, }},
+	{ NULL, NULL, {} }
+};
+#endif
+/*
+ * 	"generic" linux cryptoapi setup_cipher() function
+ */
+static struct cipher_implementation *
+setup_cipher (const char *ciphername)
+{
+	struct cipher_implementation *ci;
+	/* 	1: atomic */
+	ci = find_cipher_by_name (ciphername, 1); 
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:setup_cipher():"
+				"ciphername=%s ci=%p\n"
+				, ciphername, ci);
+	if (!ci) {
+		printk (KERN_INFO "cipher \"%s\" not found\n", ciphername);
+		return NULL;
+	}
+	return ci;
+}
+
+/*
+ * 	map cryptoapi's bitmaps to KLIPS min,max bitlens,
+ * 	considering user passed parms for forced bitlens.
+ * 	smells quite heuristic ...
+ */
+static void
+setup_keylens(struct ipsec_alg_capi_cipher *cptr, struct cipher_implementation *ci,  int *keyminbitsp, int *keymaxbitsp)
+{
+	struct capi_keysz {
+		int mask;
+		int len;
+	};
+	struct capi_keysz *kz;
+	struct capi_keysz capi_keysz_array[] = {
+		{ CIPHER_KEYSIZE_40   , 40 },
+		{ CIPHER_KEYSIZE_56   , 56 },
+		{ CIPHER_KEYSIZE_64   , 64 },
+		{ CIPHER_KEYSIZE_80   , 80 },
+		{ CIPHER_KEYSIZE_96   , 96 },
+		{ CIPHER_KEYSIZE_112  , 112 },
+		{ CIPHER_KEYSIZE_128  , 128 },
+		{ CIPHER_KEYSIZE_160  , 160 },
+		{ CIPHER_KEYSIZE_168  , 168 },
+		{ CIPHER_KEYSIZE_192  , 192 },
+		{ CIPHER_KEYSIZE_256  , 256 },
+		{ 0 , 0 }
+	};
+	if (cptr->parm[0] > 1 && cptr->parm[1] > 1) {
+		*keyminbitsp=cptr->parm[0];
+		*keymaxbitsp=cptr->parm[1];
+	} else {
+		*keyminbitsp=*keymaxbitsp=0;
+		for (kz=capi_keysz_array; kz->mask; kz++) {
+			if (kz->mask & ci->key_size_mask) {
+				if (!*keyminbitsp) *keyminbitsp=kz->len;
+				*keymaxbitsp=kz->len;
+			}
+		}
+	}
+}
+/*
+ * 	setups ipsec_alg_capi_cipher "hyper" struct components, calling
+ * 	register_ipsec_alg for cointaned ipsec_alg object
+ */
+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
+
+static int
+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr, struct cipher_implementation *ci)
+{
+	int ret;
+	int keyminbits, keymaxbits;
+	cptr->ci = NULL;
+	atomic_set (& cptr->ci_usecnt, 0);
+	cptr->alg.ixt_version = IPSEC_ALG_VERSION;
+	cptr->alg.ixt_module = THIS_MODULE;
+	atomic_set (& cptr->alg.ixt_refcnt, 0);
+	strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
+
+	cptr->alg.ixt_blocksize=ci->blocksize;
+	setup_keylens(cptr, ci, &keyminbits, &keymaxbits);
+	cptr->alg.ixt_state = 0;
+	if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
+	cptr->alg.ixt_keyminbits=keyminbits;
+	cptr->alg.ixt_keymaxbits=keymaxbits;
+	cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
+	cptr->alg.ixt_e_ctx_size = 0;
+	cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
+	cptr->alg.ixt_e_new_key = _capi_new_key;
+	cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
+	cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
+	cptr->alg.ixt_data = cptr;
+
+	ret=register_ipsec_alg_enc(&cptr->alg);
+	printk("setup_ipsec_alg_capi_cipher(): " 
+			"alg_type=%d alg_id=%d name=%s "
+			"keyminbits=%d keymaxbits=%d, ret=%d\n", 
+				cptr->alg.ixt_alg_type, 
+				cptr->alg.ixt_alg_id, 
+				cptr->alg.ixt_name, 
+				cptr->alg.ixt_keyminbits,
+				cptr->alg.ixt_keymaxbits,
+				ret);
+	return ret;
+}
+/*
+ * 	bind cryptoapi cipher to ipsec_alg_capi_cipher "hyper" struct 
+ * 	it will also create 1 lock() inside cipher
+ */
+static struct cipher_implementation *
+_capi_ci_bind(struct ipsec_alg_capi_cipher *cptr, struct cipher_implementation *ci)
+{
+	if (atomic_read(&cptr->ci_usecnt) == 0) {
+		cptr->ci=ci? ci : setup_cipher(cptr->ciphername);
+	}
+	if (cptr->ci) {
+		atomic_inc(&cptr->ci_usecnt);
+		cptr->ci->lock();
+	}
+	return cptr->ci;
+}
+/*
+ * 	unbind cryptoapi cipher from ipsec_alg_capi_cipher "hyper" struct,
+ * 	will do 1 unlock()
+ */
+static void
+_capi_ci_unbind(struct ipsec_alg_capi_cipher *cptr)
+{
+	struct cipher_implementation *ci = cptr->ci;
+	if (ci) {
+		if (atomic_dec_and_test(&cptr->ci_usecnt) ) {
+			cptr->ci = NULL;
+		}
+		ci->unlock();
+	}
+}
+/*
+ * 	called in ipsec_sa_wipe() time, will destroy key contexts
+ * 	and do 1 unbind()
+ */
+static void 
+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
+{
+	struct cipher_context *cx = (struct cipher_context *)key_e;
+	struct cipher_implementation* ci=cx->ci;
+	struct ipsec_alg_capi_cipher *cptr = alg->ixt_data;
+
+
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
+				"name=%s key_e=%p ci=%p\n",
+				alg->ixt_name, key_e, ci);
+	if (!cx) {
+		printk(KERN_ERR "klips_debug: _capi_destroy_key:"
+				"name=%s NULL key_e!\n",
+				alg->ixt_name);
+		return;
+	}
+
+	ci->wipe_context(cx);
+	ci->free_context(cx);
+	/* ci->unlock(); */
+	_capi_ci_unbind(cptr);
+}
+	
+/*
+ * 	create new key context, need alg->ixt_data to know which
+ * 	(of many) cipher inside this module is the target
+ */
+static __u8 *
+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
+{
+	struct cipher_context *cx = NULL;
+	struct ipsec_alg_capi_cipher *cptr;
+	struct cipher_implementation *ci;
+
+	cptr = alg->ixt_data;
+	if (!cptr) {
+		printk(KERN_ERR "_capi_new_key(): "
+				"NULL ixt_data (?!) for \"%s\" algo\n" 
+				, alg->ixt_name);
+		goto err;
+	}
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_capi_new_key:"
+				"name=%s cptr=%p key=%p keysize=%d\n",
+				alg->ixt_name, cptr, key, keylen);
+	
+	/* 
+	 * 	sortof "cache": try to bind the cipher (will be noop if
+	 *	already in use); if 1st SA using this cipher will
+	 *	end doing find_cipher_by_name()
+	 *	
+	 *	this logic is needed to support "latebind"
+	 */
+	if (!(ci=_capi_ci_bind(cptr, NULL)))
+		goto err;
+	/* ci->lock (); */
+
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_capi_new_key (after setup):"
+				"name=%s ci=%p\n",
+				alg->ixt_name, ci);
+	/*	
+	 *	alloc cipher context for this key
+	 */
+	cx = ci->realloc_context (NULL, ci, keylen);
+	if (!cx) {
+		printk(KERN_ERR "_capi_new_key(): "
+				"NULL cx for \"%s\" cryptoapi algo\n" 
+			, alg->ixt_name);
+		/* ci->unlock (); */
+		goto err;
+	}
+	if (ci->set_key (cx, key, keylen) < 0) {
+		printk(KERN_ERR "_capi_new_key(): "
+				"failed new_key() for \"%s\" cryptoapi algo\n" 
+			, alg->ixt_name);
+		ci->wipe_context (cx);
+		ci->free_context (cx);
+		/* ci->unlock (); */
+		cx=NULL;
+	}
+err:
+	/*
+	 * 	unbind 1 lease if failed (bad key, ENOMEM, etc ...) 
+	 */
+	if (!cx)
+		_capi_ci_unbind(cptr);
+
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_capi_new_key:"
+				"name=%s key=%p keylen=%d cx=%p\n",
+				alg->ixt_name, key, keylen, cx);
+	return (__u8 *) cx;
+}
+/*
+ * 	core encryption function: will use cx->ci to call actual cipher's
+ * 	cbc function
+ */
+static int 
+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
+	int error;
+	struct cipher_context *cx=(struct cipher_context *)key_e;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
+				"cx=%p key_e=%p "
+				"in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
+				, cx , key_e
+				, in, in, ilen, iv, encrypt);
+	/* this _iv() functions seems to appear AFTER 2.4.18.1 */
+	if (encrypt)
+		error = cx->ci->encrypt_atomic_iv (cx, in, in, ilen, iv);
+	else
+		error = cx->ci->decrypt_atomic_iv (cx, in, in, ilen, iv);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
+				"error=%d\n"
+				, error);
+	return (error<0)? error : ilen;
+}
+/*
+ * 	main initialization loop: for each cipher in list, do
+ * 	1) setup cryptoapi cipher else continue
+ * 	2) register ipsec_alg object
+ * 	   dont bind (lock) cipher if latebind specified, it will
+ * 	   get re-searched and locked at SA creation time (_new_key())
+ */
+static int
+setup_cipher_list (struct ipsec_alg_capi_cipher* clist) 
+{
+	struct ipsec_alg_capi_cipher *cptr;
+	struct cipher_implementation *ci;
+	/* foreach cipher in list ... */
+	for (cptr=clist;cptr->ciphername;cptr++) {
+		/* 
+		 * see if cipher has been disabled (0) or
+		 * if noauto set and not enabled (1)
+		 */
+		if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
+			if (debug>0)
+				printk(KERN_INFO "setup_cipher_list(): "
+					"ciphername=%s skipped at user request: "
+					"noauto=%d parm[0]=%d parm[1]=%d\n"
+					, cptr->ciphername
+					, noauto
+					, cptr->parm[0]
+					, cptr->parm[1]);
+			continue;
+		}
+		/* 
+		 * 	use a temp ci to avoid touching cptr->ci,
+		 * 	if register ipsec_alg success then bind cipher
+		 */
+		ci = setup_cipher(cptr->ciphername);
+		if (ci) {
+			ci->lock();
+			if (debug > 0)
+				printk(KERN_DEBUG "klips_debug:"
+						"setup_cipher_list():"
+						"ciphername=%s found\n"
+				, cptr->ciphername);
+			if (setup_ipsec_alg_capi_cipher(cptr, ci) == 0) {
+				if (latebind==0)
+					_capi_ci_bind(cptr, ci);
+			} else {
+				printk(KERN_ERR "klips_debug:"
+						"setup_cipher_list():"
+						"ciphername=%s failed ipsec_alg_register\n"
+				, cptr->ciphername);
+			}
+			ci->unlock();
+		}
+	}
+	return 0;
+}
+/*
+ * 	deregister ipsec_alg objects and unbind ciphers
+ */
+static int
+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) 
+{
+	struct ipsec_alg_capi_cipher *cptr;
+	/* foreach cipher in list ... */
+	for (cptr=clist;cptr->ciphername;cptr++) {
+		if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
+			unregister_ipsec_alg_enc(&cptr->alg);
+			if (latebind==0)
+				_capi_ci_unbind(cptr);
+		}
+	}
+	return 0;
+}
+/*
+ * 	test loop for registered algos
+ */
+static int
+test_cipher_list (struct ipsec_alg_capi_cipher* clist) 
+{
+	int test_ret;
+	struct ipsec_alg_capi_cipher *cptr;
+	/* foreach cipher in list ... */
+	for (cptr=clist;cptr->ciphername;cptr++) {
+		if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
+			test_ret=ipsec_alg_test(
+					cptr->alg.ixt_alg_type,
+					cptr->alg.ixt_alg_id, 
+					test);
+			printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n", 
+					cptr->alg.ixt_alg_type, 
+					cptr->alg.ixt_alg_id, 
+					test_ret);
+		}
+	}
+	return 0;
+}
+
+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
+{
+	int ret, test_ret;
+	if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
+		return  -EPROTONOSUPPORT;
+	if (ret==0 && test) {
+		test_ret=test_cipher_list(alg_capi_carray);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
+{
+	unsetup_cipher_list(alg_capi_carray);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_md5.c linux-patched/net/ipsec/alg/ipsec_alg_md5.c
--- linux/net/ipsec/alg/ipsec_alg_md5.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_md5.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,122 @@
+/*
+ * ipsec_alg MD5 hash stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_MD5
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+#include "libmd5/md5.h"
+#include "libmd5/hmac_md5.h"
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+
+#define AH_MD5		2
+
+static int _md5_hmac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
+	md5_hmac_context *hctx=(md5_hmac_context*)(key_a);
+	md5_hmac_set_key(hctx, key, keylen);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _md5_hmac_set_key(): "
+				"key_a=%p key=%p keysize=%d\n",
+				key_a, key, keylen);
+	return 0;
+}
+static int _md5_hmac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
+	md5_hmac_context *hctx=(md5_hmac_context*)(key_a);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _md5_hmac_hash(): "
+				"key_a=%p dat=%p len=%d hash=%p hashlen=%d\n",
+				key_a, dat, len, hash, hashlen);
+	md5_hmac_hash(hctx, dat, len, hash, hashlen);
+	return 0;
+}
+static struct ipsec_alg_auth ipsec_alg_MD5 = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_AUTH,
+	ixt_alg_id: 	AH_MD5,
+	ixt_name: 	"md5",
+	ixt_blocksize:	MD5_BLOCKSIZE,
+	ixt_keyminbits:	128,
+	ixt_keymaxbits:	128,
+	ixt_a_keylen:	128/8,
+	ixt_a_ctx_size:	sizeof(md5_hmac_context),
+	ixt_a_hmac_set_key:	_md5_hmac_set_key,
+	ixt_a_hmac_hash:	_md5_hmac_hash,
+};
+IPSEC_ALG_MODULE_INIT( ipsec_md5_init )
+{
+	int ret, test_ret;
+	if (excl) ipsec_alg_MD5.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_auth(&ipsec_alg_MD5);
+	printk("ipsec_md5_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_MD5.ixt_alg_type, 
+			ipsec_alg_MD5.ixt_alg_id, 
+			ipsec_alg_MD5.ixt_name, 
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_MD5.ixt_alg_type,
+				ipsec_alg_MD5.ixt_alg_id, 
+				test);
+		printk("ipsec_md5_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_MD5.ixt_alg_type, 
+				ipsec_alg_MD5.ixt_alg_id, 
+				test_ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT( ipsec_md5_fini )
+{
+	unregister_ipsec_alg_auth(&ipsec_alg_MD5);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_null.c linux-patched/net/ipsec/alg/ipsec_alg_null.c
--- linux/net/ipsec/alg/ipsec_alg_null.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_null.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,133 @@
+/*
+ * ipsec_alg NULL cipher stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * Fixes by:
+ * 	DDR:	David De Reu <DeReu@tComLabs.com> 
+ * Fixes:
+ * 	DDR:	comply to RFC2410 and make it interop with other impl.
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_NULL
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+
+#define ESP_NULL		11	/* from ipsec drafts */
+#define ESP_NULL_BLK_LEN	1	/* from RFC 2410 */
+#define ESP_NULL_IV_LEN		0	/* from RFC 2410 */
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+
+typedef int null_context;
+
+struct null_eks{
+	null_context null_ctx;
+};
+static int _null_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
+	null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_null_set_key:"
+				"key_e=%p key=%p keysize=%d\n",
+				key_e, key, keysize);
+	*ctx = 1;
+	return 0;
+}
+static int _null_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
+	null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_null_cbc_encrypt:"
+				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
+				key_e, in, ilen, iv, encrypt);
+	(*ctx)++;
+	return ilen;
+}
+static struct ipsec_alg_enc ipsec_alg_NULL = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_NULL,
+	ixt_name: 	"null",
+	ixt_blocksize:	ESP_NULL_BLK_LEN, 
+	ixt_ivlen:	ESP_NULL_IV_LEN,
+	ixt_keyminbits:	0,
+	ixt_keymaxbits:	0,
+	ixt_e_keylen:	0,
+	ixt_e_ctx_size:	sizeof(null_context),
+	ixt_e_set_key:	_null_set_key,
+	ixt_e_cbc_encrypt:_null_cbc_encrypt,
+};
+	
+IPSEC_ALG_MODULE_INIT(ipsec_null_init)
+{
+	int ret, test_ret;
+	if (excl) ipsec_alg_NULL.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_enc(&ipsec_alg_NULL);
+	printk("ipsec_null_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_NULL.ixt_alg_type, 
+			ipsec_alg_NULL.ixt_alg_id, 
+			ipsec_alg_NULL.ixt_name, 
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_NULL.ixt_alg_type,
+				ipsec_alg_NULL.ixt_alg_id, 
+				test);
+		printk("ipsec_null_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_NULL.ixt_alg_type, 
+				ipsec_alg_NULL.ixt_alg_id, 
+				test_ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT(ipsec_null_fini)
+{
+	unregister_ipsec_alg_enc(&ipsec_alg_NULL);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_serpent.c linux-patched/net/ipsec/alg/ipsec_alg_serpent.c
--- linux/net/ipsec/alg/ipsec_alg_serpent.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_serpent.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,139 @@
+/*
+ * ipsec_alg SERPENT cipher stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_SERPENT
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+#include "libserpent/serpent.h"
+#include "libserpent/serpent_cbc.h"
+
+#define ESP_SERPENT		252	/* from ipsec drafts */
+
+/* 128, 192 or 256 */
+#define ESP_SERPENT_KEY_SZ_MIN	16 	/* 128 bit secret key */
+#define ESP_SERPENT_KEY_SZ_MAX	32 	/* 256 bit secret key */
+#define ESP_SERPENT_CBC_BLK_LEN	16	/* SERPENT-CBC block size */
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+static int keyminbits=0;
+MODULE_PARM(keyminbits, "i");
+static int keymaxbits=0;
+MODULE_PARM(keymaxbits, "i");
+
+static int _serpent_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
+	serpent_context *ctx=(serpent_context *)key_e;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_serpent_set_key:"
+				"key_e=%p key=%p keysize=%d\n",
+				key_e, key, keysize);
+	serpent_set_key(ctx, key,  keysize);
+	return 0;
+}
+static int _serpent_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
+	serpent_context *ctx=(serpent_context *)key_e;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_serpent_cbc_encrypt:"
+				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
+				key_e, in, ilen, iv, encrypt);
+	serpent_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
+	return ilen;
+}
+static struct ipsec_alg_enc ipsec_alg_SERPENT = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_SERPENT,
+	ixt_name: 	"serpent",
+	ixt_blocksize:	ESP_SERPENT_CBC_BLK_LEN,
+	ixt_keyminbits:	ESP_SERPENT_KEY_SZ_MIN * 8,
+	ixt_keymaxbits:	ESP_SERPENT_KEY_SZ_MAX * 8,
+	ixt_e_keylen:	ESP_SERPENT_KEY_SZ_MAX,
+	ixt_e_ctx_size:	sizeof(serpent_context),
+	ixt_e_set_key:	_serpent_set_key,
+	ixt_e_cbc_encrypt:_serpent_cbc_encrypt,
+};
+	
+IPSEC_ALG_MODULE_INIT(ipsec_serpent_init)
+{
+	int ret, test_ret;
+	if (keyminbits)
+		ipsec_alg_SERPENT.ixt_keyminbits=keyminbits;
+	if (keymaxbits) {
+		ipsec_alg_SERPENT.ixt_keymaxbits=keymaxbits;
+		if (keymaxbits*8>ipsec_alg_SERPENT.ixt_keymaxbits)
+			ipsec_alg_SERPENT.ixt_e_keylen=keymaxbits*8;
+	}
+	if (excl) ipsec_alg_SERPENT.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_enc(&ipsec_alg_SERPENT);
+	printk("ipsec_serpent_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
+			ipsec_alg_SERPENT.ixt_alg_type,
+			ipsec_alg_SERPENT.ixt_alg_id,
+			ipsec_alg_SERPENT.ixt_name,
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_SERPENT.ixt_alg_type,
+				ipsec_alg_SERPENT.ixt_alg_id,
+				test);
+		printk("ipsec_serpent_init(alg_type=%d alg_id=%d): test_ret=%d\n",
+				ipsec_alg_SERPENT.ixt_alg_type,
+				ipsec_alg_SERPENT.ixt_alg_id,
+				test_ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT(ipsec_serpent_fini)
+{
+	unregister_ipsec_alg_enc(&ipsec_alg_SERPENT);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_sha1.c linux-patched/net/ipsec/alg/ipsec_alg_sha1.c
--- linux/net/ipsec/alg/ipsec_alg_sha1.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_sha1.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,122 @@
+/*
+ * ipsec_alg SHA1 hash stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_SHA1
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+#include "libsha1/sha.h"
+#include "libsha1/hmac_sha1.h"
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+
+#define AH_SHA		3
+
+static int _sha1_hmac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
+	sha1_hmac_context *hctx=(sha1_hmac_context*)(key_a);
+	sha1_hmac_set_key(hctx, key, keylen);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _sha1_hmac_set_key(): "
+				"key_a=%p key=%p keysize=%d\n",
+				key_a, key, keylen);
+	return 0;
+}
+static int _sha1_hmac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
+	sha1_hmac_context *hctx=(sha1_hmac_context*)(key_a);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _sha1_hmac_hash(): "
+				"key_a=%p dat=%p len=%d hash=%p hashlen=%d\n",
+				key_a, dat, len, hash, hashlen);
+	sha1_hmac_hash(hctx, dat, len, hash, hashlen);
+	return 0;
+}
+static struct ipsec_alg_auth ipsec_alg_SHA1 = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_AUTH,
+	ixt_alg_id: 	AH_SHA,
+	ixt_name: 	"sha1",
+	ixt_blocksize:	SHA1_BLOCKSIZE,
+	ixt_keyminbits:	160,
+	ixt_keymaxbits:	160,
+	ixt_a_keylen:	160/8,
+	ixt_a_ctx_size:	sizeof(sha1_hmac_context),
+	ixt_a_hmac_set_key:	_sha1_hmac_set_key,
+	ixt_a_hmac_hash:	_sha1_hmac_hash,
+};
+IPSEC_ALG_MODULE_INIT( ipsec_sha1_init )
+{
+	int ret, test_ret;
+	if (excl) ipsec_alg_SHA1.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_auth(&ipsec_alg_SHA1);
+	printk("ipsec_sha1_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_SHA1.ixt_alg_type, 
+			ipsec_alg_SHA1.ixt_alg_id, 
+			ipsec_alg_SHA1.ixt_name, 
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_SHA1.ixt_alg_type,
+				ipsec_alg_SHA1.ixt_alg_id, 
+				test);
+		printk("ipsec_sha1_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_SHA1.ixt_alg_type, 
+				ipsec_alg_SHA1.ixt_alg_id, 
+				test_ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT( ipsec_sha1_fini )
+{
+	unregister_ipsec_alg_auth(&ipsec_alg_SHA1);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_sha2.c linux-patched/net/ipsec/alg/ipsec_alg_sha2.c
--- linux/net/ipsec/alg/ipsec_alg_sha2.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_sha2.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,185 @@
+/*
+ * ipsec_alg SHA2 hash stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_SHA2
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+#include "libsha2/sha2.h"
+#include "libsha2/hmac_sha2.h"
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+
+/* almost constants ...: draft-ietf-ipsec-ciph-aes-cbc-03.txt */
+#define AH_SHA2_256               5
+#define AH_SHA2_384               6
+#define AH_SHA2_512               7
+
+static int _sha256_hmac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
+	sha256_hmac_context *hctx=(sha256_hmac_context*)(key_a);
+	sha256_hmac_set_key(hctx, key, keylen);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _sha256_hmac_set_key(): "
+				"key_a=%p key=%p keysize=%d\n",
+				key_a, key, keylen);
+	return 0;
+}
+static int _sha256_hmac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
+	sha256_hmac_context *hctx=(sha256_hmac_context*)(key_a);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _sha256_hmac_hash(): "
+				"key_a=%p dat=%p len=%d hash=%p hashlen=%d\n",
+				key_a, dat, len, hash, hashlen);
+	sha256_hmac_hash(hctx, dat, len, hash, hashlen);
+	return 0;
+}
+static int _sha512_hmac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
+	sha512_hmac_context *hctx=(sha512_hmac_context*)(key_a);
+	sha512_hmac_set_key(hctx, key, keylen);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _sha512_hmac_set_key(): "
+				"key_a=%p key=%p keysize=%d\n",
+				key_a, key, keylen);
+	return 0;
+}
+static int _sha512_hmac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
+	sha512_hmac_context *hctx=(sha512_hmac_context*)(key_a);
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug: _sha512_hmac_hash(): "
+				"key_a=%p dat=%p len=%d hash=%p hashlen=%d\n",
+				key_a, dat, len, hash, hashlen);
+	sha512_hmac_hash(hctx, dat, len, hash, hashlen);
+	return 0;
+}
+static struct ipsec_alg_auth ipsec_alg_SHA2_256 = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_AUTH,
+	ixt_alg_id: 	AH_SHA2_256,
+	ixt_name: 	"sha2_256",
+	ixt_blocksize:	SHA256_BLOCKSIZE,
+	ixt_keyminbits:	256,
+	ixt_keymaxbits:	256,
+	ixt_a_keylen:	256/8,
+	ixt_a_ctx_size:	sizeof(sha256_hmac_context),
+	ixt_a_hmac_set_key:	_sha256_hmac_set_key,
+	ixt_a_hmac_hash:	_sha256_hmac_hash,
+};
+static struct ipsec_alg_auth ipsec_alg_SHA2_512 = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_AUTH,
+	ixt_alg_id: 	AH_SHA2_512,
+	ixt_name: 	"sha2_512",
+	ixt_blocksize:	SHA512_BLOCKSIZE,
+	ixt_keyminbits:	512,
+	ixt_keymaxbits:	512,
+	ixt_a_keylen:	512/8,
+	ixt_a_ctx_size:	sizeof(sha512_hmac_context),
+	ixt_a_hmac_set_key:	_sha512_hmac_set_key,
+	ixt_a_hmac_hash:	_sha512_hmac_hash,
+};
+	
+IPSEC_ALG_MODULE_INIT( ipsec_sha2_init )
+{
+	int ret, test_ret;
+	if (excl) ipsec_alg_SHA2_256.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_auth(&ipsec_alg_SHA2_256);
+	printk("ipsec_sha2_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_SHA2_256.ixt_alg_type, 
+			ipsec_alg_SHA2_256.ixt_alg_id, 
+			ipsec_alg_SHA2_256.ixt_name, 
+			ret);
+	if (ret != 0) 
+		goto out;
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_SHA2_256.ixt_alg_type,
+				ipsec_alg_SHA2_256.ixt_alg_id, 
+				test);
+		printk("ipsec_sha2_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_SHA2_256.ixt_alg_type, 
+				ipsec_alg_SHA2_256.ixt_alg_id, 
+				test_ret);
+	}
+	if (excl) ipsec_alg_SHA2_512.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_auth(&ipsec_alg_SHA2_512);
+	printk("ipsec_sha2_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+			ipsec_alg_SHA2_512.ixt_alg_type, 
+			ipsec_alg_SHA2_512.ixt_alg_id, 
+			ipsec_alg_SHA2_512.ixt_name, 
+			ret);
+	if (ret != 0) 
+		goto out_256;
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_SHA2_512.ixt_alg_type,
+				ipsec_alg_SHA2_512.ixt_alg_id, 
+				test);
+		printk("ipsec_sha2_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+				ipsec_alg_SHA2_512.ixt_alg_type, 
+				ipsec_alg_SHA2_512.ixt_alg_id, 
+				test_ret);
+	}
+	goto out;
+out_256:
+	unregister_ipsec_alg_auth(&ipsec_alg_SHA2_256);
+out:
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT( ipsec_sha2_fini )
+{
+	unregister_ipsec_alg_auth(&ipsec_alg_SHA2_512);
+	unregister_ipsec_alg_auth(&ipsec_alg_SHA2_256);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+EXPORT_NO_SYMBOLS;
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/ipsec_alg_twofish.c linux-patched/net/ipsec/alg/ipsec_alg_twofish.c
--- linux/net/ipsec/alg/ipsec_alg_twofish.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/ipsec_alg_twofish.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,138 @@
+/*
+ * ipsec_alg TWOFISH cipher stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_TWOFISH
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_alg.h"
+#include "libtwofish/twofish.h"
+#include "libtwofish/twofish_cbc.h"
+
+#define ESP_TWOFISH		253	/* from ipsec drafts */
+
+/* 128, 192 or 256 */
+#define ESP_TWOFISH_KEY_SZ_MIN	16 	/* 128 bit secret key */
+#define ESP_TWOFISH_KEY_SZ_MAX	32 	/* 256 bit secret key */
+#define ESP_TWOFISH_CBC_BLK_LEN	16	/* TWOFISH-CBC block size */
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int excl=0;
+MODULE_PARM(excl, "i");
+static int keyminbits=0;
+MODULE_PARM(keyminbits, "i");
+static int keymaxbits=0;
+MODULE_PARM(keymaxbits, "i");
+
+static int _twofish_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
+	twofish_context *ctx=(twofish_context *)key_e;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_twofish_set_key:"
+				"key_e=%p key=%p keysize=%d\n",
+				key_e, key, keysize);
+	twofish_set_key(ctx, key,  keysize);
+	return 0;
+}
+static int _twofish_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
+	twofish_context *ctx=(twofish_context *)key_e;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_twofish_cbc_encrypt:"
+				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
+				key_e, in, ilen, iv, encrypt);
+	twofish_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
+	return ilen;
+}
+static struct ipsec_alg_enc ipsec_alg_TWOFISH = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_TWOFISH,
+	ixt_name: 	"twofish",
+	ixt_blocksize:	ESP_TWOFISH_CBC_BLK_LEN, 
+	ixt_keyminbits:	ESP_TWOFISH_KEY_SZ_MIN * 8,
+	ixt_keymaxbits:	ESP_TWOFISH_KEY_SZ_MAX * 8,
+	ixt_e_keylen:	ESP_TWOFISH_KEY_SZ_MAX,
+	ixt_e_ctx_size:	sizeof(twofish_context),
+	ixt_e_set_key:	_twofish_set_key,
+	ixt_e_cbc_encrypt:_twofish_cbc_encrypt,
+};
+	
+IPSEC_ALG_MODULE_INIT( ipsec_twofish_init )
+{
+	int ret, test_ret;
+	if (keyminbits)
+		ipsec_alg_TWOFISH.ixt_keyminbits=keyminbits;
+	if (keymaxbits) {
+		ipsec_alg_TWOFISH.ixt_keymaxbits=keymaxbits;
+		if (keymaxbits*8>ipsec_alg_TWOFISH.ixt_keymaxbits)
+			ipsec_alg_TWOFISH.ixt_e_keylen=keymaxbits*8;
+	}
+	if (excl) ipsec_alg_TWOFISH.ixt_state |= IPSEC_ALG_ST_EXCL;
+	ret=register_ipsec_alg_enc(&ipsec_alg_TWOFISH);
+	printk("ipsec_twofish_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
+				ipsec_alg_TWOFISH.ixt_alg_type, 
+				ipsec_alg_TWOFISH.ixt_alg_id, 
+				ipsec_alg_TWOFISH.ixt_name, ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_TWOFISH.ixt_alg_type,
+				ipsec_alg_TWOFISH.ixt_alg_id, 
+				test);
+		printk("ipsec_twofish_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
+			ipsec_alg_TWOFISH.ixt_alg_type, 
+			ipsec_alg_TWOFISH.ixt_alg_id, 
+			ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT( ipsec_twofish_fini )
+{
+	unregister_ipsec_alg_enc(&ipsec_alg_TWOFISH);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
+#endif
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/alg/scripts/mk-static_init.c.sh linux-patched/net/ipsec/alg/scripts/mk-static_init.c.sh
--- linux/net/ipsec/alg/scripts/mk-static_init.c.sh	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/alg/scripts/mk-static_init.c.sh	Thu Sep  5 04:36:54 2002
@@ -0,0 +1,17 @@
+#!/bin/sh
+cat << EOF
+#include <linux/kernel.h>
+#include "../ipsec_alg.h"
+$(for i in $*; do
+	test -z "$i" && continue
+	echo "extern int $i(void);"
+done)
+void ipsec_alg_static_init(void){ 
+	int __attribute__ ((unused)) err=0;
+$(for i in $*; do
+	test -z "$i" && continue
+	echo "	if ((err=$i()) < 0)"
+	echo "		printk(KERN_WARNING \"$i() returned %d\", err);"
+done)
+}
+EOF
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/defconfig linux-patched/net/ipsec/defconfig
--- linux/net/ipsec/defconfig	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/defconfig	Fri Jul  4 20:07:34 2003
@@ -0,0 +1,132 @@
+
+#
+# RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+#
+
+#
+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
+#
+
+#
+# First, lets override stuff already set or not in the kernel config.
+#
+# We can't even think about leaving this off...
+CONFIG_INET=y
+
+#
+# This must be on for subnet protection.
+CONFIG_IP_FORWARD=y
+
+# Shut off IPSEC masquerading if it has been enabled, since it will 
+# break the compile.  IPPROTO_ESP and IPPROTO_AH were included in 
+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
+CONFIG_IP_MASQUERADE_IPSEC=n
+
+#
+# Next, lets set the recommended FreeS/WAN configuration.
+#
+
+# To config as static (preferred), 'y'.  To config as module, 'm'.
+CONFIG_IPSEC=m
+
+# To do tunnel mode IPSec, this must be enabled.
+CONFIG_IPSEC_IPIP=y
+
+# To enable authentication, say 'y'.   (Highly recommended)
+CONFIG_IPSEC_AH=y
+
+# Authentication algorithm(s):
+CONFIG_IPSEC_AUTH_HMAC_MD5=y
+CONFIG_IPSEC_AUTH_HMAC_SHA1=y
+
+# To enable encryption, say 'y'.   (Highly recommended)
+CONFIG_IPSEC_ESP=y
+
+# Encryption algorithm(s):
+CONFIG_IPSEC_ENC_3DES=y
+
+# IP Compression: new, probably still has minor bugs.
+CONFIG_IPSEC_IPCOMP=y
+
+# To enable userspace-switchable KLIPS debugging, say 'y'.
+CONFIG_IPSEC_DEBUG=y
+
+# modular algo extensions (and new ALGOs)
+CONFIG_IPSEC_ALG=y
+CONFIG_IPSEC_ALG_AES=m
+CONFIG_IPSEC_ALG_TWOFISH=m
+CONFIG_IPSEC_ALG_SERPENT=m
+
+# NAT Traversal
+CONFIG_IPSEC_NAT_TRAVERSAL=y
+
+# Use CryptoAPI for ALG?
+CONFIG_IPSEC_ALG_CRYPTOAPI=n
+
+# NAT Traversal
+CONFIG_IPSEC_NAT_TRAVERSAL=y
+
+#
+#
+# $Log: super-freeswan-1.99.8-delsol1.diff,v $
+# Revision 1.1  2003/09/09 09:20:34  john
+# Initial import
+#
+# Revision 1.5  2003/07/04 19:07:34  ken
+# Added NAT-T 0.6 diff/patch from Tuomo
+#
+# Revision 1.4  2003/02/21 22:59:21  ken
+# Set default for CONFIG_IPSEC_ALG_CRYPTOAPI=n
+#
+# Revision 1.3  2002/09/05 16:50:58  ken
+# Enabled NAT-T by default
+#
+# Revision 1.2  2002/09/05 03:27:08  ken
+# Applied freeswan-alg-0.8.0-BASE-klips.diff
+#
+# Revision 1.1.1.1  2002/09/05 03:13:17  ken
+# 1.98b
+#
+# Revision 1.20  2002/04/02 04:07:40  mcr
+# 	default build is now 'm'odule for KLIPS
+#
+# Revision 1.19  2002/03/08 18:57:17  rgb
+# Added a blank line at the beginning of the file to make it easier for
+# other projects to patch ./arch/i386/defconfig, for example
+# LIDS+grSecurity requested by Jason Pattie.
+#
+# Revision 1.18  2000/11/30 17:26:56  rgb
+# Cleaned out unused options and enabled ipcomp by default.
+#
+# Revision 1.17  2000/09/15 11:37:01  rgb
+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
+# IPCOMP zlib deflate code.
+#
+# Revision 1.16  2000/09/08 19:12:55  rgb
+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+#
+# Revision 1.15  2000/05/24 19:37:13  rgb
+# *** empty log message ***
+#
+# Revision 1.14  2000/05/11 21:14:57  henry
+# just commenting the FOOBAR=y lines out is not enough
+#
+# Revision 1.13  2000/05/10 20:17:58  rgb
+# Comment out netlink defaults, which are no longer needed.
+#
+# Revision 1.12  2000/05/10 19:13:38  rgb
+# Added configure option to shut off no eroute passthrough.
+#
+# Revision 1.11  2000/03/16 07:09:46  rgb
+# Hardcode PF_KEYv2 support.
+# Disable IPSEC_ICMP by default.
+# Remove DES config option from defaults file.
+#
+# Revision 1.10  2000/01/11 03:09:42  rgb
+# Added a default of 'y' to PF_KEYv2 keying I/F.
+#
+# Revision 1.9  1999/05/08 21:23:12  rgb
+# Added support for 2.2.x kernels.
+#
+# Revision 1.8  1999/04/06 04:54:25  rgb
+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+# patch shell fixes.
+#
+#
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipcomp.c linux-patched/net/ipsec/ipcomp.c
--- linux/net/ipsec/ipcomp.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipcomp.c	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,742 @@
+/*
+ * IPCOMP zlib interface code.
+ * Copyright (C) 2000  Svenning Soerensen <svenning@post5.tele.dk>
+ * Copyright (C) 2000, 2001  Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+char ipcomp_c_version[] = "RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $";
+
+/* SSS */
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/kernel.h> /* printk() */
+
+#define IPSEC_KLIPS1_COMPAT
+#include "ipsec_param.h"
+
+#ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+#else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+#endif /* MALLOC_SLAB */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/ip.h>
+#include <linux/skbuff.h>
+
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/skbuff.h>
+
+#include <freeswan.h>
+#ifdef NET_21
+# include <net/dst.h>
+# include <asm/uaccess.h>
+# include <linux/in6.h>
+# define proto_priv cb
+#endif /* NET21 */
+#include <asm/checksum.h>
+#include <net/ip.h>
+
+#include "radij.h"
+#include "ipsec_encap.h"
+#include "ipsec_sa.h"
+
+#include "ipsec_netlink.h"
+#include "ipsec_xform.h"
+#include "ipsec_tunnel.h"
+#include "ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
+#include "ipcomp.h"
+#include "zlib/zlib.h"
+#include "zlib/zutil.h"
+
+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
+
+#ifdef CONFIG_IPSEC_DEBUG
+int sysctl_ipsec_debug_ipcomp = 0;
+#endif /* CONFIG_IPSEC_DEBUG */
+
+static
+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
+
+static
+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
+{
+	return (voidpf) kmalloc(items*size, GFP_ATOMIC);
+}
+
+static
+void my_zfree(voidpf opaque, voidpf address)
+{
+	kfree(address);
+}
+
+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *tdb, unsigned int *flags)
+{
+	struct iphdr *iph;
+	unsigned int iphlen, pyldsz, cpyldsz;
+	unsigned char *buffer;
+	z_stream zs;
+	int zresult;
+	
+	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+		    "klips_debug:skb_compress: .\n");
+
+	if(!skb) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_compress: "
+			    "passed in NULL skb, returning ERROR.\n");
+		if (flags) *flags |= IPCOMP_PARMERROR;
+		return skb;
+	}
+
+	if(!tdb) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_compress: "
+			    "passed in NULL tdb needed for cpi, returning ERROR.\n");
+		if (flags) *flags |= IPCOMP_PARMERROR;
+		return skb;
+	}
+
+	if (!flags) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_compress: "
+			    "passed in NULL flags, returning ERROR.\n");
+#ifdef NET_21
+		kfree_skb(skb);
+#else /* NET_21 */
+		dev_kfree_skb(skb, FREE_WRITE);
+#endif /* NET_21 */
+		return NULL;
+	}
+	
+#ifdef NET_21
+	iph = skb->nh.iph;
+#else /* NET_21 */
+	iph = skb->ip_hdr;
+#endif /* NET_21 */
+
+	switch (iph->protocol) {
+	case IPPROTO_COMP:
+	case IPPROTO_AH:
+	case IPPROTO_ESP:
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_compress: "
+			    "skipping compression of packet with ip protocol %d.\n",
+			    iph->protocol);
+		*flags |= IPCOMP_UNCOMPRESSABLE;
+		return skb;
+	}
+	
+	/* Don't compress packets already fragmented */
+	if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_compress: "
+			    "skipping compression of fragmented packet.\n");
+		*flags |= IPCOMP_UNCOMPRESSABLE;
+		return skb;
+	}
+	
+	iphlen = iph->ihl << 2;
+	pyldsz = ntohs(iph->tot_len) - iphlen;
+
+	/* Don't compress less than 90 bytes (rfc 2394) */
+	if (pyldsz < 90) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_compress: "
+			    "skipping compression of tiny packet, len=%d.\n",
+			    pyldsz);
+		*flags |= IPCOMP_UNCOMPRESSABLE;
+		return skb;
+	}
+	
+	/* Adaptive decision */
+	if (tdb->tdb_comp_adapt_skip) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_compress: "
+			    "skipping compression: tdb_comp_adapt_skip=%d.\n",
+			    tdb->tdb_comp_adapt_skip);
+		tdb->tdb_comp_adapt_skip--;
+		*flags |= IPCOMP_UNCOMPRESSABLE;
+		return skb;
+	}
+
+	zs.zalloc = my_zcalloc;
+	zs.zfree = my_zfree;
+	zs.opaque = 0;
+	
+	/* We want to use deflateInit2 because we don't want the adler
+	   header. */
+	zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
+			       DEF_MEM_LEVEL,  Z_DEFAULT_STRATEGY);
+	if (zresult != Z_OK) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_compress: "
+			    "deflateInit2() returned error %d (%s), "
+			    "skipping compression.\n",
+			    zresult,
+			    zs.msg ? zs.msg : zError(zresult));
+		*flags |= IPCOMP_COMPRESSIONERROR;
+		return skb;
+	}
+	
+
+	/* Max output size. Result should be max this size.
+	 * Implementation specific tweak:
+	 * If it's not at least 32 bytes and 6.25% smaller than
+	 * the original packet, it's probably not worth wasting
+	 * the receiver's CPU cycles decompressing it.
+	 * Your mileage may vary.
+	 */
+	cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
+
+	buffer = kmalloc(cpyldsz, GFP_ATOMIC);
+	if (!buffer) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_compress: "
+			    "unable to kmalloc(%d, GFP_ATOMIC), "
+			    "skipping compression.\n",
+			    cpyldsz);
+		*flags |= IPCOMP_COMPRESSIONERROR;
+		deflateEnd(&zs);
+		return skb;
+	}
+	
+#ifdef CONFIG_IPSEC_DEBUG
+	if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
+		__u8 *c;
+		int i;
+
+		c = (__u8*)iph + iphlen;
+		for(i = 0; i < pyldsz; i++, c++) {
+			if(!(i % 16)) {
+				printk(KERN_INFO "skb_compress:   before:");
+			}
+			printk("%02x ", *c);
+			if(!((i + 1) % 16)) {
+				printk("\n");
+			}
+		}
+		if(i % 16) {
+			printk("\n");
+		}
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	zs.next_in = (char *) iph + iphlen; /* start of payload */
+	zs.avail_in = pyldsz;
+	zs.next_out = buffer;     /* start of compressed payload */
+	zs.avail_out = cpyldsz;
+	
+	/* Finish compression in one step */
+	zresult = deflate(&zs, Z_FINISH);
+
+	/* Free all dynamically allocated buffers */
+	deflateEnd(&zs);
+	if (zresult != Z_STREAM_END) {
+		*flags |= IPCOMP_UNCOMPRESSABLE;
+		kfree(buffer);
+
+		/* Adjust adaptive counters */
+		if (++(tdb->tdb_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
+			KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+				    "klips_debug:skb_compress: "
+				    "first %d packets didn't compress, "
+				    "skipping next %d\n",
+				    IPCOMP_ADAPT_INITIAL_TRIES,
+				    IPCOMP_ADAPT_INITIAL_SKIP);
+			tdb->tdb_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
+		}
+		else if (tdb->tdb_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
+			KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+				    "klips_debug:skb_compress: "
+				    "next %d packets didn't compress, "
+				    "skipping next %d\n",
+				    IPCOMP_ADAPT_SUBSEQ_TRIES,
+				    IPCOMP_ADAPT_SUBSEQ_SKIP);
+			tdb->tdb_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
+			tdb->tdb_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
+		}
+
+		return skb;
+	}
+	
+	/* resulting compressed size */
+	cpyldsz -= zs.avail_out;
+	
+	/* Insert IPCOMP header */
+	((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
+	((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
+	/* use the bottom 16 bits of the spi for the cpi.  The top 16 bits are
+	   for internal reference only. */
+	((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(tdb->tdb_said.spi) & 0x0000ffff));
+	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+		    "klips_debug:skb_compress: "
+		    "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
+		    ntohl(tdb->tdb_said.spi),
+		    ntohl(tdb->tdb_said.spi) & 0x0000ffff,
+		    ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
+		    pyldsz,
+		    cpyldsz);
+	
+	/* Update IP header */
+	iph->protocol = IPPROTO_COMP;
+	iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
+#if 1 /* XXX checksum is done by ipsec_tunnel ? */
+	iph->check = 0;
+	iph->check = ip_fast_csum((char *) iph, iph->ihl);
+#endif
+	
+	/* Copy compressed payload */
+	memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
+	       buffer,
+	       cpyldsz);
+	kfree(buffer);
+	
+	/* Update skb length/tail by "unputting" the shrinkage */
+	skb_put(skb,
+		cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
+	
+#ifdef CONFIG_IPSEC_DEBUG
+	if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
+		__u8 *c;
+		int i;
+		
+		c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
+		for(i = 0; i < cpyldsz; i++, c++) {
+			if(!(i % 16)) {
+				printk(KERN_INFO "skb_compress:   result:");
+			}
+			printk("%02x ", *c);
+			if(!((i + 1) % 16)) {
+				printk("\n");
+			}
+		}
+		if(i % 16) {
+			printk("\n");
+		}
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+	
+	tdb->tdb_comp_adapt_skip = 0;
+	tdb->tdb_comp_adapt_tries = 0;
+	
+	return skb;
+}
+
+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *tdb, unsigned int *flags)
+{
+	struct sk_buff *nskb = NULL;
+
+	/* original ip header */
+	struct iphdr *oiph, *iph;
+	unsigned int iphlen, pyldsz, cpyldsz;
+	z_stream zs;
+	int zresult;
+
+	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+		    "klips_debug:skb_decompress: .\n");
+
+	if(!skb) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "passed in NULL skb, returning ERROR.\n");
+		if (flags) *flags |= IPCOMP_PARMERROR;
+		return skb;
+	}
+
+	if(!tdb && sysctl_ipsec_inbound_policy_check) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "passed in NULL tdb needed for comp alg, returning ERROR.\n");
+		if (flags) *flags |= IPCOMP_PARMERROR;
+		return skb;
+	}
+
+	if (!flags) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "passed in NULL flags, returning ERROR.\n");
+#ifdef NET_21
+		kfree_skb(skb);
+#else /* NET_21 */
+		dev_kfree_skb(skb, FREE_WRITE);
+#endif /* NET_21 */
+		return NULL;
+	}
+	
+#ifdef NET_21
+	oiph = skb->nh.iph;
+#else /* NET_21 */
+	oiph = skb->ip_hdr;
+#endif /* NET_21 */
+	
+	iphlen = oiph->ihl << 2;
+	
+	if (oiph->protocol != IPPROTO_COMP) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "called with non-IPCOMP packet (protocol=%d),"
+			    "skipping decompression.\n",
+			    oiph->protocol);
+		*flags |= IPCOMP_PARMERROR;
+		return skb;
+	}
+	
+	if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
+	     || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
+		!= htons(SADB_X_CALG_DEFLATE))
+		 && sysctl_ipsec_inbound_policy_check
+		 && (!tdb || (tdb && (tdb->tdb_encalg != SADB_X_CALG_DEFLATE)))) ) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "called with incompatible IPCOMP packet (flags=%d, "
+			    "cpi=%d), tdb-compalg=%d, skipping decompression.\n",
+			    ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
+			    ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
+			    tdb ? tdb->tdb_encalg : 0);
+		*flags |= IPCOMP_PARMERROR;
+		
+		return skb;
+	}
+	
+	if (ntohs(oiph->frag_off) & ~0x4000) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "called with fragmented IPCOMP packet, "
+			    "skipping decompression.\n");
+		*flags |= IPCOMP_PARMERROR;
+		return skb;
+	}
+	
+	/* original compressed payload size */
+	cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
+
+	zs.zalloc = my_zcalloc;
+	zs.zfree = my_zfree;
+	zs.opaque = 0;
+	
+	zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
+	zs.avail_in = cpyldsz;
+	
+	/* Maybe we should be a bit conservative about memory
+	   requirements and use inflateInit2 */
+	/* Beware, that this might make us unable to decompress packets
+	   from other implementations - HINT: check PGPnet source code */
+	/* We want to use inflateInit2 because we don't want the adler
+	   header. */
+	zresult = inflateInit2(&zs, -15); 
+	if (zresult != Z_OK) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "inflateInit2() returned error %d (%s), "
+			    "skipping decompression.\n",
+			    zresult,
+			    zs.msg ? zs.msg : zError(zresult));
+		*flags |= IPCOMP_DECOMPRESSIONERROR;
+
+		return skb;
+	}
+	
+	/* We have no way of knowing the exact length of the resulting
+	   decompressed output before we have actually done the decompression.
+	   For now, we guess that the packet will not be bigger than the
+	   attached ipsec device's mtu or 16260, whichever is biggest.
+	   This may be wrong, since the sender's mtu may be bigger yet.
+	   XXX This must be dealt with later XXX
+	*/
+	
+	/* max payload size */
+	pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
+			  : (65520 - iphlen);
+	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+		    "klips_debug:skb_decompress: "
+		    "max payload size: %d\n", pyldsz);
+	
+	while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) && 
+	       (nskb = skb_copy_ipcomp(skb,
+				       pyldsz - cpyldsz - sizeof(struct ipcomphdr),
+				       GFP_ATOMIC)) == NULL) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
+			    "trying with less payload size.\n",
+			    pyldsz - cpyldsz - sizeof(struct ipcomphdr));
+		pyldsz >>=1;
+	}
+	
+	if (!nskb) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "unable to allocate memory, dropping packet.\n");
+		*flags |= IPCOMP_DECOMPRESSIONERROR;
+		inflateEnd(&zs);
+
+		return skb;
+	}
+	
+#ifdef CONFIG_IPSEC_DEBUG
+	if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
+		__u8 *c;
+		int i;
+		
+		c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
+		for(i = 0; i < cpyldsz; i++, c++) {
+			if(!(i % 16)) {
+				printk(KERN_INFO "skb_decompress:   before:");
+			}
+			printk("%02x ", *c);
+			if(!((i + 1) % 16)) {
+				printk("\n");
+			}
+		}
+		if(i % 16) {
+			printk("\n");
+		}
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#ifdef NET_21
+	iph = nskb->nh.iph;
+#else /* NET_21 */
+	iph = nskb->ip_hdr;
+#endif /* NET_21 */
+	zs.next_out = (char *)iph + iphlen;
+	zs.avail_out = pyldsz;
+
+	zresult = inflate(&zs, Z_SYNC_FLUSH);
+
+	/* work around a bug in zlib, which sometimes wants to taste an extra
+	 * byte when being used in the (undocumented) raw deflate mode.
+	 */
+	if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
+		__u8 zerostuff = 0;
+		
+		zs.next_in = &zerostuff;
+		zs.avail_in = 1;
+		zresult = inflate(&zs, Z_FINISH);
+	}
+
+	inflateEnd(&zs);
+	if (zresult != Z_STREAM_END) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_error:skb_decompress: "
+			    "inflate() returned error %d (%s), "
+			    "skipping decompression.\n",
+			    zresult,
+			    zs.msg ? zs.msg : zError(zresult));
+		*flags |= IPCOMP_DECOMPRESSIONERROR;
+#ifdef NET_21
+		kfree_skb(nskb);
+#else /* NET_21 */
+		dev_kfree_skb(nskb, FREE_WRITE);
+#endif /* NET_21 */
+
+		return skb;
+	}
+	
+	/* Update IP header */
+	/* resulting decompressed size */
+	pyldsz -= zs.avail_out;
+	iph->tot_len = htons(iphlen + pyldsz);
+	iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
+	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+		    "klips_debug:skb_decompress: "
+		    "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
+		    tdb ? ntohl(tdb->tdb_said.spi) : 0,
+		    tdb ? ntohl(tdb->tdb_said.spi) & 0x0000ffff : 0,
+		    ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
+		    cpyldsz,
+		    pyldsz,
+		    iph->protocol);
+	
+#if 1 /* XXX checksum is done by ipsec_rcv ? */
+	iph->check = 0;
+	iph->check = ip_fast_csum((char*) iph, iph->ihl);
+#endif
+	
+	/* Update skb length/tail by "unputting" the unused data area */
+	skb_put(nskb, -zs.avail_out);
+	
+#ifdef NET_21
+	kfree_skb(skb);
+#else /* NET_21 */
+	dev_kfree_skb(skb, FREE_WRITE);
+#endif /* NET_21 */
+	
+	if (iph->protocol == IPPROTO_COMP)
+	{
+#ifdef CONFIG_IPSEC_DEBUG
+		if(sysctl_ipsec_debug_ipcomp)
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_decompress: "
+			    "Eh? inner packet is also compressed, dropping.\n");
+#endif /* CONFIG_IPSEC_DEBUG */
+		
+#ifdef NET_21
+		kfree_skb(nskb);
+#else /* NET_21 */
+		dev_kfree_skb(nskb, FREE_WRITE);
+#endif /* NET_21 */
+		return NULL;
+	}
+	
+#ifdef CONFIG_IPSEC_DEBUG
+	if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
+		__u8 *c;
+		int i;
+		
+		c = (__u8*)iph + iphlen;
+		for(i = 0; i < pyldsz; i++, c++) {
+			if(!(i % 16)) {
+				printk(KERN_INFO "skb_decompress:   result:");
+			}
+			printk("%02x ", *c);
+			if(!((i + 1) % 16)) {
+				printk("\n");
+			}
+		}
+		if(i % 16) {
+			printk("\n");
+		}
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+	
+	return nskb;
+}
+
+
+/* this is derived from skb_copy() in linux 2.2.14 */
+/* May be incompatible with other kernel versions!! */
+static
+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
+{
+        struct sk_buff *n;
+	struct iphdr *iph;
+        unsigned long offset;
+        unsigned int iphlen;
+	
+	if(!skb) {
+		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
+			    "klips_debug:skb_copy_ipcomp: "
+			    "passed in NULL skb, returning NULL.\n");
+		return NULL;
+	}
+
+        /*
+         *      Allocate the copy buffer
+         */
+	
+#ifdef NET_21
+	iph = skb->nh.iph;
+#else /* NET_21 */
+	iph = skb->ip_hdr;
+#endif /* NET_21 */
+        if (!iph) return NULL;
+        iphlen = iph->ihl << 2;
+	
+        n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
+        if(n==NULL)
+                return NULL;
+	
+        /*
+         *      Shift between the two data areas in bytes
+         */
+	
+        offset=n->head-skb->head;
+
+        /* Set the data pointer */
+        skb_reserve(n,skb->data-skb->head);
+        /* Set the tail pointer and length */
+        skb_put(n,skb->len+data_growth);
+        /* Copy the bytes up to and including the ip header */
+        memcpy(n->head,
+	       skb->head,
+	       ((char *)iph - (char *)skb->head) + iphlen);
+        n->list=NULL;
+	n->next=NULL;
+	n->prev=NULL;
+        n->sk=NULL;
+        n->dev=skb->dev;
+	if (skb->h.raw)
+		n->h.raw=skb->h.raw+offset;
+	else
+		n->h.raw=NULL;
+        n->protocol=skb->protocol;
+#ifdef NET_21
+        n->csum = 0;
+        n->priority=skb->priority;
+        n->dst=dst_clone(skb->dst);
+        n->nh.raw=skb->nh.raw+offset;
+#ifndef NETDEV_23
+        n->is_clone=0;
+#endif /* NETDEV_23 */
+        atomic_set(&n->users, 1);
+        n->destructor = NULL;
+        n->security=skb->security;
+        memcpy(n->cb, skb->cb, sizeof(skb->cb));
+#ifdef CONFIG_IP_FIREWALL
+        n->fwmark = skb->fwmark;
+#endif
+#else /* NET_21 */
+	n->link3=NULL;
+	n->when=skb->when;
+	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;
+	n->free=1;
+	n->arp=skb->arp;
+	n->tries=0;
+	n->lock=0;
+	n->users=0;
+	memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
+#endif /* NET_21 */
+	if (skb->mac.raw)
+		n->mac.raw=skb->mac.raw+offset;
+	else
+		n->mac.raw=NULL;
+#ifndef NETDEV_23
+	n->used=skb->used;
+#endif /* !NETDEV_23 */
+        n->pkt_type=skb->pkt_type;
+#ifndef NETDEV_23
+	n->pkt_bridged=skb->pkt_bridged;
+#endif /* NETDEV_23 */
+	n->ip_summed=0;
+        n->stamp=skb->stamp;
+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
+        n->shapelatency=skb->shapelatency;       /* Latency on frame */
+        n->shapeclock=skb->shapeclock;           /* Time it should go out */
+        n->shapelen=skb->shapelen;               /* Frame length in clocks */
+        n->shapestamp=skb->shapestamp;           /* Stamp for shaper    */
+        n->shapepend=skb->shapepend;             /* Pending */
+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
+#endif /* NETDEV_23 */
+#ifdef CONFIG_HIPPI
+        n->private.ifield=skb->private.ifield;
+#endif /* CONFIG_HIPPI */
+
+        return n;
+}
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipcomp.h linux-patched/net/ipsec/ipcomp.h
--- linux/net/ipsec/ipcomp.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipcomp.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,59 @@
+/*
+ * IPCOMP zlib interface code.
+ * Copyright (C) 2000  Svenning Soerensen <svenning@post5.tele.dk>
+ * Copyright (C) 2000, 2001  Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+
+ RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+
+ */
+
+/* SSS */
+
+#ifndef _IPCOMP_H
+#define _IPCOMP_H
+
+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
+#define IPCOMP_PREFIX
+
+#ifndef IPPROTO_COMP
+#define IPPROTO_COMP 108
+#endif /* IPPROTO_COMP */
+
+#ifdef CONFIG_IPSEC_DEBUG
+extern int sysctl_ipsec_debug_ipcomp;
+#endif /* CONFIG_IPSEC_DEBUG */
+
+struct ipcomphdr {			/* IPCOMP header */
+    __u8    ipcomp_nh;		/* Next header (protocol) */
+    __u8    ipcomp_flags;	/* Reserved, must be 0 */
+    __u16   ipcomp_cpi;		/* Compression Parameter Index */
+};
+
+extern struct inet_protocol comp_protocol;
+extern int sysctl_ipsec_debug_ipcomp;
+
+#define IPCOMP_UNCOMPRESSABLE     0x000000001
+#define IPCOMP_COMPRESSIONERROR   0x000000002
+#define IPCOMP_PARMERROR          0x000000004
+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
+
+#define IPCOMP_ADAPT_INITIAL_TRIES	8
+#define IPCOMP_ADAPT_INITIAL_SKIP	4
+#define IPCOMP_ADAPT_SUBSEQ_TRIES	2
+#define IPCOMP_ADAPT_SUBSEQ_SKIP	8
+
+/* Function prototypes */
+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *tdb, unsigned int *flags);
+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *tdb, unsigned int *flags);
+
+#endif /* _IPCOMP_H */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_ah.h linux-patched/net/ipsec/ipsec_ah.h
--- linux/net/ipsec/ipsec_ah.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_ah.h	Thu Sep  5 04:27:08 2002
@@ -0,0 +1,205 @@
+/*
+ * Authentication Header declarations
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+#include "ipsec_md5h.h"
+#include "ipsec_sha1.h"
+
+#ifndef IPPROTO_AH
+#define IPPROTO_AH 51
+#endif /* IPPROTO_AH */
+
+#define AH_FLENGTH		12		/* size of fixed part */
+#define AHMD5_KMAX		64		/* MD5 max 512 bits key */
+#define AHMD5_AMAX		12		/* MD5 96 bits of authenticator */
+
+#define AHMD596_KLEN		16		/* MD5 128 bits key */
+#define AHSHA196_KLEN		20		/* SHA1 160 bits key */
+
+#define AHMD596_ALEN    	16		/* MD5 128 bits authentication length */
+#define AHSHA196_ALEN		20		/* SHA1 160 bits authentication length */
+
+#define AHMD596_BLKLEN  	64		/* MD5 block length */
+#define AHSHA196_BLKLEN 	64		/* SHA1 block length */
+#define AHSHA2_256_BLKLEN 	64		/* SHA2-256 block length */
+#define AHSHA2_384_BLKLEN 	128 		/* SHA2-384 block length (?) */
+#define AHSHA2_512_BLKLEN 	128		/* SHA2-512 block length */
+
+#define AH_BLKLEN_MAX 		128		/* keep up to date! */
+
+#define AH_AMAX         	AHSHA196_ALEN   /* keep up to date! */
+#define AHHMAC_HASHLEN  	12              /* authenticator length of 96bits */
+#define AHHMAC_RPLLEN   	4               /* 32 bit replay counter */
+
+#define DB_AH_PKTRX		0x0001
+#define DB_AH_PKTRX2		0x0002
+#define DB_AH_DMP		0x0004
+#define DB_AH_TDB		0x0010
+#define DB_AH_XF		0x0020
+#define DB_AH_INAU		0x0040
+#define DB_AH_REPLAY		0x0100
+
+#ifdef __KERNEL__
+
+/* General HMAC algorithm is described in RFC 2104 */
+
+#define		HMAC_IPAD	0x36
+#define		HMAC_OPAD	0x5C
+
+struct md5_ctx {
+	MD5_CTX ictx;		/* context after H(K XOR ipad) */
+	MD5_CTX	octx;		/* context after H(K XOR opad) */
+};
+
+struct sha1_ctx {
+	SHA1_CTX ictx;		/* context after H(K XOR ipad) */
+	SHA1_CTX octx;		/* context after H(K XOR opad) */
+};
+
+extern struct inet_protocol ah_protocol;
+
+struct options;
+
+extern int 
+ah_rcv(struct sk_buff *skb,
+       struct device *dev,
+       struct options *opt, 
+       __u32 daddr,
+       unsigned short len,
+       __u32 saddr,
+       int redo,
+       struct inet_protocol *protocol);
+
+struct ah				/* Generic AH header */
+{
+	__u8	ah_nh;			/* Next header (protocol) */
+	__u8	ah_hl;			/* AH length, in 32-bit words */
+	__u16	ah_rv;			/* reserved, must be 0 */
+	__u32	ah_spi;			/* Security Parameters Index */
+        __u32   ah_rpl;                 /* Replay prevention */
+	__u8	ah_data[AHHMAC_HASHLEN];/* Authentication hash */
+};
+
+#ifdef CONFIG_IPSEC_DEBUG
+extern int debug_ah;
+#endif /* CONFIG_IPSEC_DEBUG */
+#endif /* __KERNEL__ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.2  2002/09/05 03:27:08  ken
+ * Applied freeswan-alg-0.8.0-BASE-klips.diff
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.16  2002/02/20 01:27:06  rgb
+ * Ditched a pile of structs only used by the old Netlink interface.
+ *
+ * Revision 1.15  2001/12/11 02:35:57  rgb
+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
+ *
+ * Revision 1.14  2001/11/26 09:23:47  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.13.2.1  2001/09/25 02:18:24  mcr
+ * 	replace "struct device" with "struct netdevice"
+ *
+ * Revision 1.13  2001/06/14 19:35:08  rgb
+ * Update copyright date.
+ *
+ * Revision 1.12  2000/09/12 03:21:20  rgb
+ * Cleared out unused htonq.
+ *
+ * Revision 1.11  2000/09/08 19:12:55  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ *
+ * Revision 1.10  2000/01/21 06:13:10  rgb
+ * Tidied up spacing.
+ * Added macros for HMAC padding magic numbers.(kravietz)
+ *
+ * Revision 1.9  1999/12/07 18:16:23  rgb
+ * Fixed comments at end of #endif lines.
+ *
+ * Revision 1.8  1999/04/11 00:28:56  henry
+ * GPL boilerplate
+ *
+ * Revision 1.7  1999/04/06 04:54:25  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.6  1999/01/26 02:06:01  rgb
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
+ *
+ * Revision 1.5  1999/01/22 06:17:49  rgb
+ * Updated macro comments.
+ * Added context types to support algorithm switch code.
+ * 64-bit clean-up -- converting 'u long long' to __u64.
+ *
+ * Revision 1.4  1998/07/14 15:54:56  rgb
+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
+ *
+ * Revision 1.3  1998/06/30 18:05:16  rgb
+ * Comment out references to htonq.
+ *
+ * Revision 1.2  1998/06/25 19:33:46  rgb
+ * Add prototype for protocol receive function.
+ * Rearrange for more logical layout.
+ *
+ * Revision 1.1  1998/06/18 21:27:43  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.4  1998/05/18 22:28:43  rgb
+ * Disable key printing facilities from /proc/net/ipsec_*.
+ *
+ * Revision 1.3  1998/04/21 21:29:07  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.2  1998/04/12 22:03:17  rgb
+ * Updated ESP-3DES-HMAC-MD5-96,
+ * 	ESP-DES-HMAC-MD5-96,
+ * 	AH-HMAC-MD5-96,
+ * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
+ *
+ * Fixed eroute references in /proc/net/ipsec*.
+ *
+ * Started to patch module unloading memory leaks in ipsec_netlink and
+ * radij tree unloading.
+ *
+ * Revision 1.1  1998/04/09 03:05:55  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:02  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * Added definitions for new AH transforms.
+ *
+ * Revision 0.3  1996/11/20 14:35:48  ji
+ * Minor Cleanup.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_alg.c linux-patched/net/ipsec/ipsec_alg.c
--- linux/net/ipsec/ipsec_alg.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_alg.c	Fri Feb  7 13:14:24 2003
@@ -0,0 +1,847 @@
+/*
+ * Modular extensions service and registration functions
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * Version: 0.7.3
+ *
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/kernel.h> /* printk() */
+
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/types.h>
+#include <linux/string.h>	/* memcmp() */
+#include <linux/random.h>	/* get_random_bytes() */
+#include <linux/errno.h>  /* error codes */
+#ifdef SPINLOCK
+# ifdef SPINLOCK_23
+#  include <linux/spinlock.h> /* *lock* */
+# else /* SPINLOCK_23 */
+#  include <asm/spinlock.h> /* *lock* */
+# endif /* SPINLOCK_23 */
+#endif /* SPINLOCK */
+#ifdef NET_21
+# include <asm/uaccess.h>
+# include <linux/in6.h>
+# define proto_priv cb
+#endif /* NET21 */
+#include "ipsec_param.h"
+#include <freeswan.h>
+#include "radij.h"
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+#include "ipsec_netlink.h"
+#include "ipsec_xform.h"
+#include "ipsec_tunnel.h"
+#include "ipsec_rcv.h"
+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
+# include "ipsec_ah.h"
+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
+#ifdef CONFIG_IPSEC_ESP
+# include "ipsec_esp.h"
+#endif /* !CONFIG_IPSEC_ESP */
+#ifdef CONFIG_IPSEC_IPCOMP
+# include "ipcomp.h"
+#endif /* CONFIG_IPSEC_COMP */
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#include "ipsec_sa.h"
+#include "ipsec_alg.h"
+
+#if SADB_EALG_MAX < 255
+#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
+#endif
+
+static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
+#define IPSEC_ALG_HASHSZ	16	/* must be power of 2, even 2^0=1 */
+static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
+
+/*	Old gcc's will fail here 	*/
+#define barf_out(fmt, args...)  do { printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixt->ixt_name , ## args)\
+	; goto out; } while(0)
+
+/* 
+ * 	Must be already protected by lock 
+ */
+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
+	if (ixt->ixt_module)
+		__MOD_INC_USE_COUNT(ixt->ixt_module);
+	atomic_inc(&ixt->ixt_refcnt);
+}
+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
+	atomic_dec(&ixt->ixt_refcnt);
+	if (ixt->ixt_module)
+		__MOD_DEC_USE_COUNT(ixt->ixt_module);
+}
+/*
+ * 	simple hash function, optimized for 0-hash (1 list) special
+ * 	case
+ */
+#if IPSEC_ALG_HASHSZ > 1
+static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
+	return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
+}
+#else
+#define ipsec_alg_hashfn(x,y) (0)
+#endif
+
+/*****************************************************************
+ *
+ * 	INTERNAL table handling: insert, delete, find
+ *
+ *****************************************************************/
+
+/*	
+ *	hash table initialization, called from ipsec_alg_init()
+ */
+static void ipsec_alg_hash_init(void) {
+	struct list_head *head = ipsec_alg_hash_table;
+	int i = IPSEC_ALG_HASHSZ;
+	do {
+		INIT_LIST_HEAD(head);
+		head++;
+		i--;
+	} while (i);
+}
+/*
+ * 	hash list lookup by {alg_type, alg_id} and table head,
+ * 	must be already protected by lock
+ */
+static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
+	struct list_head *p;
+	struct ipsec_alg *ixt=NULL;
+	for (p=head->next; p!=head; p=p->next) {
+		ixt = list_entry(p, struct ipsec_alg, ixt_list);
+		if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
+			goto out;
+		}
+	}
+	ixt=NULL;
+out:
+	return ixt;
+}
+/*
+ * 	inserts (in front) a new entry in hash table, 
+ * 	called from ipsec_alg_register() when new algorithm is registered.
+ */
+static int ipsec_alg_insert(struct ipsec_alg *ixt) {
+	int ret=-EINVAL;
+	unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
+	struct list_head *head= ipsec_alg_hash_table + hashval;
+	struct ipsec_alg *ixt_cur;
+	/* 	new element must be virgin ... */
+	if (ixt->ixt_list.next != &ixt->ixt_list || 
+		ixt->ixt_list.prev != &ixt->ixt_list) {
+		printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
+				"list head not initialized\n",
+				ixt->ixt_name);
+		return ret;
+	}
+	write_lock_bh(&ipsec_alg_lock);
+	ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
+	/* if previous (current) ipsec_alg found check excl flag of _anyone_ */
+	if (ixt_cur && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL))
+		barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
+				"Not loaded (ret=%d).\n",
+				ixt->ixt_alg_type,
+				ixt->ixt_alg_id, ret=-EEXIST);
+	list_add(&ixt->ixt_list, head);
+	ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
+	ret=0;
+out:
+	write_unlock_bh(&ipsec_alg_lock);
+	return ret;
+}
+/*
+ * 	deletes an existing entry in hash table, 
+ * 	called from ipsec_alg_unregister() when algorithm is unregistered.
+ */
+static int ipsec_alg_delete(struct ipsec_alg *ixt) {
+	write_lock_bh(&ipsec_alg_lock);
+	list_del(&ixt->ixt_list);
+	write_unlock_bh(&ipsec_alg_lock);
+	return 0;
+}
+/*
+ * 	here @user context (read-only when @kernel bh context) 
+ * 	-> no bh disabling
+ *
+ * 	called from ipsec_sa_init() -> ipsec_alg_sa_init()
+ */
+static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id) {
+	unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
+	struct list_head *head= ipsec_alg_hash_table + hashval;
+	struct ipsec_alg *ixt;
+	read_lock(&ipsec_alg_lock);
+	ixt=__ipsec_alg_find(alg_type, alg_id, head);
+	if (ixt) __ipsec_alg_usage_inc(ixt);
+	read_unlock(&ipsec_alg_lock);
+	return ixt;
+}
+
+static void ipsec_alg_put(struct ipsec_alg *ixt) {
+	__ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
+}
+
+/*****************************************************************
+ *
+ * 	INTERFACE for ENC services: key creation, encrypt function
+ *
+ *****************************************************************/
+
+/*
+ * 	main encrypt service entry point
+ * 	called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
+ * 	ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
+ */
+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat, int ilen, const __u8 * iv, int encrypt) {
+	int ret;
+	struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
+	KLIPS_PRINT(debug_rcv||debug_tunnel,
+		    "klips_debug:ipsec_alg_esp_encrypt: "
+		    "entering with encalg=%d, ixt_e=%p\n",
+		    sa_p->ips_encalg, ixt_e);
+	if (!ixt_e) {
+		KLIPS_PRINT(debug_rcv||debug_tunnel,
+			    "klips_debug:ipsec_alg_esp_encrypt: "
+			    "NULL ipsec_alg_enc object\n");
+		return -1;
+	}
+	KLIPS_PRINT(debug_rcv||debug_tunnel,
+		    "klips_debug:ipsec_alg_esp_encrypt: "
+		    "calling cbc_encrypt encalg=%d "
+		    "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
+			sa_p->ips_encalg, 
+			sa_p->ips_key_e, idat, ilen, iv, encrypt);
+	ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat, ilen, iv, encrypt);
+	KLIPS_PRINT(debug_rcv||debug_tunnel,
+		    "klips_debug:ipsec_alg_esp_encrypt: "
+		    "returned ret=%d\n",
+		    ret);
+	return ret;
+}
+/*
+ * 	encryption key context creation function
+ * 	called from pfkey_v2_parser.c:pfkey_ips_init() 
+ */
+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
+	int ret=-EINVAL;
+	int keyminbits, keymaxbits;
+	caddr_t ekp;
+	struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
+
+	KLIPS_PRINT(debug_pfkey,
+		    "klips_debug:ipsec_alg_enc_key_create: "
+		    "entering with encalg=%d ixt_e=%p\n",
+		    sa_p->ips_encalg, ixt_e);
+	if (!ixt_e) {
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_alg_enc_key_create: "
+			    "NULL ipsec_alg_enc object\n");
+		return -EPROTO;
+	}
+
+	/* 
+	 * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo 
+	 */
+	switch(ixt_e->ixt_alg_id) {
+		case ESP_3DES:
+			keyminbits=keymaxbits=192;break;
+		case ESP_DES:
+			keyminbits=keymaxbits=64;break;
+		default:
+			keyminbits=ixt_e->ixt_keyminbits;
+			keymaxbits=ixt_e->ixt_keymaxbits;
+	}
+	if(sa_p->ips_key_bits_e<keyminbits || 
+			sa_p->ips_key_bits_e>keymaxbits) {
+		KLIPS_PRINT(debug_pfkey,
+				"klips_debug:ipsec_alg_enc_key_create: "
+				"incorrect encryption key size for id=%d: %d bits -- "
+				"must be between %d,%d bits\n" /*octets (bytes)\n"*/,
+				ixt_e->ixt_alg_id,
+				sa_p->ips_key_bits_e, keyminbits, keymaxbits);
+		ret=-EINVAL;
+		goto ixt_out;
+	}
+	/* save encryption key pointer */
+	ekp = sa_p->ips_key_e;
+
+
+	if (ixt_e->ixt_e_new_key) {
+		sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
+				ekp, sa_p->ips_key_bits_e/8);
+		ret =  (sa_p->ips_key_e)? 0 : -EINVAL;
+	} else {
+		if((sa_p->ips_key_e = (caddr_t)
+		    kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
+			    GFP_ATOMIC)) == NULL) {
+			ret=-ENOMEM;
+			goto ixt_out;
+		}
+		/* zero-out key_e */
+		memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
+
+		/* I cast here to allow more decoupling in alg module */
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_alg_enc_key_create: about to call:"
+				    "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
+				    (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
+		ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
+	}
+	/* paranoid */
+	memset(ekp, 0, sa_p->ips_key_bits_e/8);
+	kfree(ekp);
+ixt_out:
+	return ret;
+}
+
+/***************************************************************
+ *
+ * 	INTERFACE for AUTH services: key creation, hash functions
+ *
+ ***************************************************************/
+
+/*
+ * 	auth key context creation function
+ * 	called from pfkey_v2_parser.c:pfkey_ips_init() 
+ */
+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
+	int ret=-EINVAL;
+	struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
+	int keyminbits, keymaxbits;
+	unsigned char *akp;
+	unsigned int aks;
+	KLIPS_PRINT(debug_pfkey,
+		    "klips_debug:ipsec_alg_auth_key_create: "
+		    "entering with authalg=%d ixt_a=%p\n",
+		    sa_p->ips_authalg, ixt_a);
+	if (!ixt_a) {
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_alg_auth_key_create: "
+			    "NULL ipsec_alg_auth object\n");
+		return -EPROTO;
+	}
+	keyminbits=ixt_a->ixt_keyminbits;
+	keymaxbits=ixt_a->ixt_keymaxbits;
+	if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
+			    "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
+			    sa_p->ips_key_bits_a, keyminbits, keymaxbits);
+		ret=-EINVAL;
+		goto ixt_out;
+	}
+	/* save auth key pointer */
+	sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
+	akp = sa_p->ips_key_a;
+	aks = sa_p->ips_key_a_size;
+
+	/* will hold: 2 ctx and a blocksize buffer: kb */
+	sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
+	if((sa_p->ips_key_a = 
+		(caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
+		ret=-ENOMEM;
+		goto ixt_out;
+	}
+	ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
+	ret=0;
+	memset(akp, 0, aks);
+	kfree(akp);
+			
+ixt_out:
+	return ret;
+}
+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) {
+	struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
+	if (!ixt_a) {
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_sa_esp_hash: "
+			    "NULL ipsec_alg_auth object\n");
+		return -EPROTO;
+	}
+	KLIPS_PRINT(debug_tunnel|debug_rcv,
+			"klips_debug:ipsec_sa_esp_hash: "
+			"hashing %p (%d bytes) to %p (%d bytes)\n",
+			espp, len,
+			hash, hashlen);
+	ixt_a->ixt_a_hmac_hash(ixt_a,
+			sa_p->ips_key_a, 
+			espp, len,
+			hash, hashlen);
+	return 0;
+}
+
+/***************************************************************
+ *
+ * 	INTERFACE for module loading,testing, and unloading
+ *
+ ***************************************************************/
+
+/* validation for registering (enc) module */
+static int check_enc(struct ipsec_alg_enc *ixt) {
+	int ret=-EINVAL;
+	if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_EALG_MAX)
+		barf_out("invalid alg_id=%d >= %d\n", ixt->ixt_alg_id, SADB_EALG_MAX);
+	if (ixt->ixt_blocksize==0) /*  || ixt->ixt_blocksize%2) need for ESP_NULL */
+		barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
+	if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_e_keylen==0)
+		goto zero_key_ok;
+	if (ixt->ixt_keyminbits==0)
+		barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
+	if (ixt->ixt_keymaxbits==0)
+		barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
+	if (ixt->ixt_e_keylen==0)
+		barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
+zero_key_ok:
+	if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
+		barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
+	if (ixt->ixt_e_cbc_encrypt==NULL)
+		barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
+	ret=0;
+out:
+	return ret;
+}
+
+/* validation for registering (auth) module */
+static int check_auth(struct ipsec_alg_auth *ixt) {
+	int ret=-EINVAL;
+	if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_AALG_MAX)
+		barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n", ixt->ixt_alg_id, SADB_AALG_MAX);
+	if (ixt->ixt_blocksize==0 || ixt->ixt_blocksize%2)
+		barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
+	if (ixt->ixt_blocksize>AH_BLKLEN_MAX)
+		barf_out(KERN_ERR "sorry blocksize=%d > %d. "
+			"Please increase AH_BLKLEN_MAX and recompile\n", 
+			ixt->ixt_blocksize,
+			AH_BLKLEN_MAX);
+	if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_a_keylen==0)
+		goto zero_key_ok;
+	if (ixt->ixt_keyminbits==0)
+		barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
+	if (ixt->ixt_keymaxbits==0)
+		barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
+	if (ixt->ixt_keymaxbits!=ixt->ixt_keyminbits)
+		barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
+	if (ixt->ixt_a_keylen==0)
+		barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
+zero_key_ok:
+	if (ixt->ixt_a_ctx_size==0)
+		barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
+	if (ixt->ixt_a_hmac_set_key==NULL)
+		barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
+	if (ixt->ixt_a_hmac_hash==NULL)
+		barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
+	ret=0;
+out:
+	return ret;
+}
+
+/* 
+ * Generic (enc, auth) registration entry point 
+ */
+int register_ipsec_alg(struct ipsec_alg *ixt) {
+	int ret=-EINVAL;
+	/*	Validation 	*/
+	if (ixt==NULL)
+		barf_out("NULL ipsec_alg object passed\n");
+	if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
+		barf_out("incorrect version: %d.%d.%d-%d, "
+			"must be %d.%d.%d[-%d]\n",
+				IPSEC_ALG_VERSION_QUAD(ixt->ixt_version), 
+				IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
+	switch(ixt->ixt_alg_type) {
+		case IPSEC_ALG_TYPE_AUTH:
+			if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
+				goto out;
+			break;
+		case IPSEC_ALG_TYPE_ENCRYPT: 
+			if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
+				goto out;
+ 			/* 
+			 * Adapted two lines below: 
+			 * 	ivlen == 0 is possible (NULL enc has blocksize==1)
+			 *
+			 * fixed NULL support by David De Reu <DeReu@tComLabs.com>
+ 			 */
+			if (ixt->ixt_ivlen == 0 && ixt->ixt_blocksize > 1)
+				ixt->ixt_ivlen = ixt->ixt_blocksize*8;
+			break;
+		default:
+			barf_out("alg_type=%d not supported", ixt->ixt_alg_type);
+	}
+	INIT_LIST_HEAD(&ixt->ixt_list);
+	ret = ipsec_alg_insert(ixt);
+	if (ret<0) 
+		barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
+				"Not loaded (ret=%d).\n",
+				ixt->ixt_alg_id, ret);
+
+	ret = pfkey_list_insert_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));
+	if (ret==0) {
+		ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
+		/*	send register event to userspace	*/
+		pfkey_register_reply(SADB_SATYPE_ESP, NULL);
+	} else
+		printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
+				"Loading anyway.\n", ret);
+	ret=0;
+out:
+	return ret;
+}
+
+/* 
+ * 	unregister ipsec_alg object from own tables, if 
+ * 	success => calls pfkey_list_remove_supported()
+ */
+int unregister_ipsec_alg(struct ipsec_alg *ixt) {
+	int ret= -EINVAL;
+	switch(ixt->ixt_alg_type) {
+		case IPSEC_ALG_TYPE_AUTH:
+		case IPSEC_ALG_TYPE_ENCRYPT: 
+			break;
+		default:
+			/*	this is not a typo :) */
+			barf_out("frog found in list (\"%s\"): ixt_p=NULL\n", 
+				ixt->ixt_name);
+	}
+
+	ret=ipsec_alg_delete(ixt);
+	if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
+		ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
+		pfkey_list_remove_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));
+		/*	send register event to userspace	*/
+		pfkey_register_reply(SADB_SATYPE_ESP, NULL);
+	}
+
+out:
+	return ret;
+}
+/*
+ * 	Must be called from user context
+ * 	used at module load type for testing algo implementation
+ */
+static int ipsec_alg_test_encrypt(int enc_alg, int test) {
+	int ret;
+	caddr_t buf = NULL;
+	int iv_size, keysize, key_e_size;
+	struct ipsec_alg_enc *ixt_e;
+	void *tmp_key_e = NULL;
+	#define BUFSZ	1024
+	#define MARGIN	0
+	#define test_enc   (buf+MARGIN)
+	#define test_dec   (test_enc+BUFSZ+MARGIN)
+	#define test_tmp   (test_dec+BUFSZ+MARGIN)
+	#define test_key_e (test_tmp+BUFSZ+MARGIN)
+	#define test_iv    (test_key_e+key_e_size+MARGIN)
+	#define test_key   (test_iv+iv_size+MARGIN)
+	#define test_size  (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
+	ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
+	if (ixt_e==NULL) {
+		KLIPS_PRINT(1, 
+			    "klips_debug: ipsec_alg_test_encrypt: "
+			    "encalg=%d object not found\n",
+			    enc_alg);
+		ret=-EINVAL;
+		goto out;
+	}
+	iv_size=ixt_e->ixt_ivlen / 8;
+	key_e_size=ixt_e->ixt_e_ctx_size;
+	keysize=ixt_e->ixt_e_keylen;
+	KLIPS_PRINT(1, 
+		    "klips_debug: ipsec_alg_test_encrypt: "
+		    "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
+		    enc_alg, iv_size, key_e_size, keysize);
+	if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
+		ret= -ENOMEM;
+		goto out;
+	}
+	get_random_bytes(test_key, keysize);
+	get_random_bytes(test_iv, iv_size);
+	if (ixt_e->ixt_e_new_key) {
+		tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
+		ret = tmp_key_e ? 0 : -EINVAL;
+	} else {
+		tmp_key_e = test_key_e;
+		ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
+	}
+	if (ret < 0)
+		goto out;
+	get_random_bytes(test_enc, BUFSZ);
+	memcpy(test_tmp, test_enc, BUFSZ);
+	ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
+	printk(KERN_INFO
+		    "klips_info: ipsec_alg_test_encrypt: "
+		    "cbc_encrypt=1 ret=%d\n", 
+		    	ret);
+	ret=memcmp(test_enc, test_tmp, BUFSZ);
+	printk(KERN_INFO
+		    "klips_info: ipsec_alg_test_encrypt: "
+		    "memcmp(enc, tmp) ret=%d: %s\n", ret,
+			ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
+	memcpy(test_dec, test_enc, BUFSZ);
+	ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
+	printk(KERN_INFO
+		    "klips_info: ipsec_alg_test_encrypt: "
+		    "cbc_encrypt=0 ret=%d\n", ret);
+	ret=memcmp(test_dec, test_tmp, BUFSZ);
+	printk(KERN_INFO
+		    "klips_info: ipsec_alg_test_encrypt: "
+		    "memcmp(dec,tmp) ret=%d: %s\n", ret,
+			ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
+	{
+		/*	Shamelessly taken from drivers/md sources  O:)  */
+		unsigned long now;
+		int i, count, max=0;
+		int encrypt, speed;
+		for (encrypt=0; encrypt <2;encrypt ++) {
+			for (i = 0; i < 5; i++) {
+				now = jiffies;
+				count = 0;
+				while (jiffies == now) {
+					mb();
+					ixt_e->ixt_e_cbc_encrypt(ixt_e, 
+							tmp_key_e, test_tmp, 
+							BUFSZ, test_iv, encrypt);
+					mb();
+					count++;
+					mb();
+				}
+				if (count > max)
+					max = count;
+			}
+			speed = max * (HZ * BUFSZ / 1024);
+			printk(KERN_INFO
+				    "klips_info: ipsec_alg_test_encrypt: "
+				    "%s %s speed=%d KB/s\n", 
+				    ixt_e->ixt_name,
+				    encrypt? "encrypt": "decrypt", speed);
+		}
+	}
+out:
+	if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
+	if (buf) kfree(buf);
+	if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
+	return ret;
+	#undef test_enc  
+	#undef test_dec  
+	#undef test_tmp  
+	#undef test_key_e
+	#undef test_iv   
+	#undef test_key  
+	#undef test_size 
+}
+/*
+ * 	Must be called from user context
+ * 	used at module load type for testing algo implementation
+ */
+static int ipsec_alg_test_auth(int auth_alg, int test) {
+	int ret;
+	caddr_t buf = NULL;
+	int blocksize, keysize, key_a_size;
+	struct ipsec_alg_auth *ixt_a;
+	#define BUFSZ	1024
+	#define MARGIN	0
+	#define test_auth  (buf+MARGIN)
+	#define test_key_a (test_auth+BUFSZ+MARGIN)
+	#define test_key   (test_key_a+key_a_size+MARGIN)
+	#define test_hash  (test_key+keysize+MARGIN)
+	#define test_size  (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
+	ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
+	if (ixt_a==NULL) {
+		KLIPS_PRINT(1, 
+			    "klips_debug: ipsec_alg_test_auth: "
+			    "encalg=%d object not found\n",
+			    auth_alg);
+		ret=-EINVAL;
+		goto out;
+	}
+	blocksize=ixt_a->ixt_blocksize;
+	key_a_size=ixt_a->ixt_a_ctx_size;
+	keysize=ixt_a->ixt_a_keylen;
+	KLIPS_PRINT(1, 
+		    "klips_debug: ipsec_alg_test_auth: "
+		    "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
+		    auth_alg, blocksize, key_a_size, keysize);
+	if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
+		ret= -ENOMEM;
+		goto out;
+	}
+	get_random_bytes(test_key, keysize);
+	ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
+	if (ret < 0 )
+		goto out;
+	get_random_bytes(test_auth, BUFSZ);
+	ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
+	printk(KERN_INFO
+		    "klips_info: ipsec_alg_test_auth: "
+		    "ret=%d\n", ret);
+	{
+		/*	Shamelessly taken from drivers/md sources  O:)  */
+		unsigned long now;
+		int i, count, max=0;
+		int speed;
+		for (i = 0; i < 5; i++) {
+			now = jiffies;
+			count = 0;
+			while (jiffies == now) {
+				mb();
+				ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
+				mb();
+				count++;
+				mb();
+			}
+			if (count > max)
+				max = count;
+		}
+		speed = max * (HZ * BUFSZ / 1024);
+		printk(KERN_INFO
+				"klips_info: ipsec_alg_test_auth: "
+				"%s hash speed=%d KB/s\n", 
+				ixt_a->ixt_name,
+				speed);
+	}
+out:
+	if (buf) kfree(buf);
+	if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
+	return ret;
+	#undef test_auth 
+	#undef test_key_a
+	#undef test_key  
+	#undef test_hash 
+	#undef test_size 
+}
+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
+	switch(alg_type) {
+		case IPSEC_ALG_TYPE_ENCRYPT:
+			return ipsec_alg_test_encrypt(alg_id, test);
+			break;
+		case IPSEC_ALG_TYPE_AUTH:
+			return ipsec_alg_test_auth(alg_id, test);
+			break;
+	}
+	printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
+			"alg_type=%d alg_id=%d\n",
+			alg_type, alg_id);
+	return -EINVAL;
+}
+int ipsec_alg_init(void) {
+	KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
+			"KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
+			IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
+			SADB_EALG_MAX, SADB_AALG_MAX);
+	/*	Initialize tables */
+	write_lock_bh(&ipsec_alg_lock);
+	ipsec_alg_hash_init();
+	write_unlock_bh(&ipsec_alg_lock);
+	/*	Initialize static algos 	*/
+	KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
+		"calling ipsec_alg_static_init()\n");
+	ipsec_alg_static_init();
+	return 0;
+}
+
+/**********************************************
+ *
+ * 	INTERFACE for ipsec_sa init and wipe
+ *
+ **********************************************/
+
+/*	
+ *	Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()	
+ */
+int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
+	struct ipsec_alg_enc *ixt_e;
+	struct ipsec_alg_auth *ixt_a;
+
+	/*	Only ESP for now ... */
+	if (sa_p->ips_said.proto != IPPROTO_ESP)
+		return -EPROTONOSUPPORT;
+	KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
+			"entering for encalg=%d, authalg=%d\n",
+			    sa_p->ips_encalg, sa_p->ips_authalg);
+	if ((ixt_e=(struct ipsec_alg_enc *)
+		ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
+		KLIPS_PRINT(debug_pfkey,
+		    "klips_debug: ipsec_alg_sa_init() :"
+		    "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
+		    ixt_e, sa_p->ips_encalg);
+		sa_p->ips_alg_enc=ixt_e;
+	}
+	if ((ixt_a=(struct ipsec_alg_auth *)
+		ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
+		KLIPS_PRINT(debug_pfkey,
+		    "klips_debug: ipsec_alg_sa_init() :"
+		    "found ipsec_alg (ixt_a=%p) for auth=%d\n",
+		    ixt_a, sa_p->ips_authalg);
+		sa_p->ips_alg_auth=ixt_a;
+	}
+	return 0;
+}
+
+/*	
+ *	Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
+ */
+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
+	struct ipsec_alg *ixt;
+	if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
+		KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
+				"unlinking for encalg=%d\n",
+				ixt->ixt_alg_id);
+		ipsec_alg_put(ixt);
+	}
+	if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
+		KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
+				"unlinking for authalg=%d\n",
+				ixt->ixt_alg_id);
+		ipsec_alg_put(ixt);
+	}
+	return 0;
+}
+/*
+ * 	As the author of this module, I ONLY ALLOW using it from
+ * 	GPL (or same LICENSE TERMS as kernel source) modules.
+ *
+ * 	In respect to hardware crypto engines this means:
+ * 	* Closed-source device drivers ARE NOT ALLOWED to use 
+ * 	  this interface.
+ * 	* Closed-source VHDL/Verilog firmware running on 
+ * 	  the crypto hardware device IS ALLOWED to use this interface
+ * 	  via a GPL (or same LICENSE TERMS as kernel source) device driver.
+ * 	--Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
+ */
+
+/*	
+ *	These symbols can only be used from GPL modules	
+ *	for now, I'm disabling this because it creates false
+ *	symbol problems for old modutils.
+ */
+
+/* #ifndef EXPORT_SYMBOL_GPL */
+#undef EXPORT_SYMBOL_GPL
+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
+/* #endif */
+EXPORT_SYMBOL_GPL(register_ipsec_alg);
+EXPORT_SYMBOL_GPL(unregister_ipsec_alg);
+EXPORT_SYMBOL_GPL(ipsec_alg_test);
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_alg.h linux-patched/net/ipsec/ipsec_alg.h
--- linux/net/ipsec/ipsec_alg.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_alg.h	Fri Feb  7 13:14:24 2003
@@ -0,0 +1,256 @@
+/*
+ * Modular extensions service and registration functions interface
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ *
+ * $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ */
+#ifndef IPSEC_ALG_H
+#define IPSEC_ALG_H
+
+/* 
+ *   gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
+ *   *BUT* its a compiler variable.
+ */
+#if (__GNUC__ >= 3)
+#ifndef __FUNCTION__
+#define __FUNCTION__ __func__
+#endif
+#endif
+
+/*	Version 0.8.1-0 */
+#define IPSEC_ALG_VERSION	0x00080100
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <asm/atomic.h>
+/*	
+ *	The following structs are used via pointers in ipsec_alg object to
+ *	avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
+ *	module development
+ */
+struct ipsec_sa;
+struct esp;
+
+/**************************************
+ *
+ *	Main registration object 
+ *
+ *************************************/
+#define IPSEC_ALG_VERSION_QUAD(v)	\
+	(v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
+/*	
+ *	Main ipsec_alg objects: "OOPrograming wannabe"
+ *	Hierachy (carefully handled with _minimal_ cast'ing):
+ *
+ *      ipsec_alg+
+ *		 +->ipsec_alg_enc  (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
+ *		 +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
+ */
+
+/***************************************************************
+ *
+ * 	INTERFACE object: struct ipsec_alg
+ *
+ ***************************************************************/
+
+/* 
+ * 	common part for every struct ipsec_alg_*	
+ * 	(sortof poor's man OOP)
+ */
+#define IPSEC_ALG_STRUCT_COMMON \
+	unsigned ixt_version;	/* only allow this version (or 'near')*/ \
+	struct list_head ixt_list;	/* dlinked list */ \
+	struct module *ixt_module;	/* THIS_MODULE */ \
+	unsigned ixt_state;		/* state flags */ \
+	atomic_t ixt_refcnt; 	/* ref. count when pointed from ipsec_sa */ \
+	char ixt_name[16];	/* descriptive short name, eg. "3des" */ \
+	void *ixt_data;		/* private for algo implementation */ \
+	uint8_t  ixt_blocksize;	/* blocksize in bytes */ \
+	\
+	/* THIS IS A COPY of struct supported (lib/pfkey.h)        \
+	 * please keep in sync until we migrate 'supported' stuff  \
+	 * to ipsec_alg \
+	 */ \
+	uint16_t ixt_alg_type;	/* correspond to IPSEC_ALG_{ENCRYPT,AUTH} */ \
+	uint8_t  ixt_alg_id;	/* enc. alg. number, eg. ESP_3DES */ \
+	uint8_t  ixt_ivlen;	/* ivlen in bits, expected to be multiple of 8! */ \
+	uint16_t ixt_keyminbits;/* min. keybits (of entropy) */ \
+	uint16_t ixt_keymaxbits;/* max. keybits (of entropy) */
+
+#define ixt_support ixt_alg_type
+	
+#define IPSEC_ALG_ST_SUPP	0x01
+#define IPSEC_ALG_ST_REGISTERED 0x02
+#define IPSEC_ALG_ST_EXCL	0x04
+struct ipsec_alg {
+	IPSEC_ALG_STRUCT_COMMON
+};
+/* 
+ * 	Note the const in cbc_encrypt IV arg:
+ * 	some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
+ */
+struct ipsec_alg_enc {
+	IPSEC_ALG_STRUCT_COMMON
+	unsigned ixt_e_keylen;		/* raw key length in bytes          */
+	unsigned ixt_e_ctx_size;	/* sa_p->key_e_size */
+	int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
+	__u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
+	void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
+	int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt);
+};
+struct ipsec_alg_auth {
+	IPSEC_ALG_STRUCT_COMMON
+	unsigned ixt_a_keylen;		/* raw key length in bytes          */
+	unsigned ixt_a_ctx_size;	/* sa_p->key_a_size */
+	unsigned ixt_a_authlen;		/* 'natural' auth. hash len (bytes) */
+	int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
+	int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
+};
+/*	
+ *	These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT}, 
+ *	to avoid header coupling for true constants
+ *	about headers ... "cp is your friend" --Linus
+ */
+#define IPSEC_ALG_TYPE_AUTH	14
+#define IPSEC_ALG_TYPE_ENCRYPT	15
+
+/***************************************************************
+ *
+ * 	INTERFACE for module loading,testing, and unloading
+ *
+ ***************************************************************/
+/*	-  registration calls 	*/
+int register_ipsec_alg(struct ipsec_alg *);
+int unregister_ipsec_alg(struct ipsec_alg *);
+/*	-  optional (simple test) for algos 	*/
+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
+/*	inline wrappers (usefull for type validation */
+static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
+	return register_ipsec_alg((struct ipsec_alg*)ixt);
+}
+static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
+	return unregister_ipsec_alg((struct ipsec_alg*)ixt);
+}
+static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
+	return register_ipsec_alg((struct ipsec_alg*)ixt);
+}
+static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
+	return unregister_ipsec_alg((struct ipsec_alg*)ixt);
+}
+
+/*****************************************************************
+ *
+ * 	INTERFACE for ENC services: key creation, encrypt function
+ *
+ *****************************************************************/
+
+#define IPSEC_ALG_ENCRYPT 1
+#define IPSEC_ALG_DECRYPT 0
+
+/* 	encryption key context creation function */
+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
+/* 
+ * 	ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
+ * 	0 or ERR<0
+ */
+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action);
+
+/***************************************************************
+ *
+ * 	INTERFACE for AUTH services: key creation, hash functions
+ *
+ ***************************************************************/
+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
+#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
+
+/* only called from ipsec_init.c */
+int ipsec_alg_init(void);
+
+/* algo module glue for static algos */
+void ipsec_alg_static_init(void);
+typedef int (*ipsec_alg_init_func_t) (void);
+
+/**********************************************
+ *
+ * 	INTERFACE for ipsec_sa init and wipe
+ *
+ **********************************************/
+
+/* returns true if ipsec_sa has ipsec_alg obj attached */
+#define IPSEC_ALG_SA_ESP_ENC(sa_p) ((sa_p)->ips_alg_enc)
+#define IPSEC_ALG_SA_ESP_AUTH(sa_p) ((sa_p)->ips_alg_auth)
+/* 
+ * Initializes ipsec_sa's ipsec_alg object, using already loaded
+ * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
+ */
+int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
+/* 
+ * Destroys ipsec_sa's ipsec_alg object
+ * unlinking ipsec_alg objects
+ */
+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
+
+/**********************************************
+ *
+ * 	2.2 backport for some 2.4 useful module stuff
+ *
+ **********************************************/
+#ifdef MODULE
+#ifndef THIS_MODULE
+#define THIS_MODULE          (&__this_module)
+#endif
+#ifndef module_init
+typedef int (*__init_module_func_t)(void);
+typedef void (*__cleanup_module_func_t)(void);
+
+#define module_init(x) \
+        int init_module(void) __attribute__((alias(#x))); \
+        static inline __init_module_func_t __init_module_inline(void) \
+        { return x; }
+#define module_exit(x) \
+        void cleanup_module(void) __attribute__((alias(#x))); \
+        static inline __cleanup_module_func_t __cleanup_module_inline(void) \
+        { return x; }
+#endif
+
+#define IPSEC_ALG_MODULE_INIT( func_name )	\
+	static int func_name(void);		\
+	module_init(func_name);			\
+	static int __init func_name(void)
+#define IPSEC_ALG_MODULE_EXIT( func_name )	\
+	static void func_name(void);		\
+	module_exit(func_name);			\
+	static void __exit func_name(void)
+#else	/* not MODULE */
+#ifndef THIS_MODULE
+#define THIS_MODULE          NULL
+#endif
+/*	
+ *	I only want module_init() magic 
+ *	when algo.c file *is THE MODULE*, in all other
+ *	cases, initialization is called explicitely from ipsec_alg_init()
+ */
+#define IPSEC_ALG_MODULE_INIT( func_name )	\
+	extern int func_name(void);		\
+	int func_name(void)
+#define IPSEC_ALG_MODULE_EXIT( func_name )	\
+	extern void func_name(void);		\
+	void func_name(void)
+#endif
+
+#endif /* IPSEC_ALG_H */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_encap.h linux-patched/net/ipsec/ipsec_encap.h
--- linux/net/ipsec/ipsec_encap.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_encap.h	Thu Dec 12 03:32:07 2002
@@ -0,0 +1,143 @@
+/*
+ * declarations relevant to encapsulation-like operations
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+#ifndef _IPSEC_ENCAP_H_
+
+#define SENT_IP4	16	/* data is two struct in_addr + proto + ports*/
+			/* (2 * sizeof(struct in_addr)) */
+			/* sizeof(struct sockaddr_encap)
+			   - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
+
+struct sockaddr_encap
+{
+	__u8	sen_len;		/* length */
+	__u8	sen_family;		/* AF_ENCAP */
+	__u16	sen_type;		/* see SENT_* */
+	union
+	{
+		struct			/* SENT_IP4 */
+		{
+			struct in_addr Src;
+			struct in_addr Dst;
+			__u8 Proto;
+			__u16 Sport;
+			__u16 Dport;
+		} Sip4;
+	} Sen;
+};
+
+#define sen_ip_src	Sen.Sip4.Src
+#define sen_ip_dst	Sen.Sip4.Dst
+#define sen_proto       Sen.Sip4.Proto
+#define sen_sport       Sen.Sip4.Sport
+#define sen_dport       Sen.Sip4.Dport
+
+#ifndef AF_ENCAP
+#define AF_ENCAP 26
+#endif /* AF_ENCAP */
+
+#define _IPSEC_ENCAP_H_
+#endif /* _IPSEC_ENCAP_H_ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.2  2002/12/12 03:32:07  ken
+ * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.16  2001/11/26 09:23:47  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.15.2.1  2001/09/25 02:18:54  mcr
+ * 	struct eroute moved to ipsec_eroute.h
+ *
+ * Revision 1.15  2001/09/14 16:58:36  rgb
+ * Added support for storing the first and last packets through a HOLD.
+ *
+ * Revision 1.14  2001/09/08 21:13:31  rgb
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
+ *
+ * Revision 1.13  2001/06/14 19:35:08  rgb
+ * Update copyright date.
+ *
+ * Revision 1.12  2001/05/27 06:12:10  rgb
+ * Added structures for pid, packet count and last access time to eroute.
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
+ *
+ * Revision 1.11  2000/09/08 19:12:56  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ *
+ * Revision 1.10  2000/03/22 16:15:36  rgb
+ * Fixed renaming of dev_get (MB).
+ *
+ * Revision 1.9  2000/01/21 06:13:26  rgb
+ * Added a macro for AF_ENCAP
+ *
+ * Revision 1.8  1999/12/31 14:56:55  rgb
+ * MB fix for 2.3 dev-use-count.
+ *
+ * Revision 1.7  1999/11/18 04:09:18  rgb
+ * Replaced all kernel version macros to shorter, readable form.
+ *
+ * Revision 1.6  1999/09/24 00:34:13  rgb
+ * Add Marc Boucher's support for 2.3.xx+.
+ *
+ * Revision 1.5  1999/04/11 00:28:57  henry
+ * GPL boilerplate
+ *
+ * Revision 1.4  1999/04/06 04:54:25  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.3  1998/10/19 14:44:28  rgb
+ * Added inclusion of freeswan.h.
+ * sa_id structure implemented and used: now includes protocol.
+ *
+ * Revision 1.2  1998/07/14 18:19:33  rgb
+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
+ *
+ * Revision 1.1  1998/06/18 21:27:44  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.2  1998/04/21 21:29:10  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.1  1998/04/09 03:05:58  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:02  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * Minor cosmetic changes.
+ *
+ * Revision 0.3  1996/11/20 14:35:48  ji
+ * Minor Cleanup.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_eroute.h linux-patched/net/ipsec/ipsec_eroute.h
--- linux/net/ipsec/ipsec_eroute.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_eroute.h	Thu Dec 12 03:32:07 2002
@@ -0,0 +1,103 @@
+/*
+ * @(#) declarations of eroute structures
+ *
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
+ * Copyright (C) 2001                    Michael Richardson <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
+ *
+ */
+
+#ifndef _IPSEC_EROUTE_H_
+
+#include "radij.h"
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+
+/*
+ * The "type" is really part of the address as far as the routing
+ * system is concerned. By using only one bit in the type field
+ * for each type, we sort-of make sure that different types of
+ * encapsulation addresses won't be matched against the wrong type.
+ */
+
+/*
+ * An entry in the radix tree 
+ */
+
+struct rjtentry
+{
+	struct	radij_node rd_nodes[2];	/* tree glue, and other values */
+#define	rd_key(r)	((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
+#define	rd_mask(r)	((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
+	short	rd_flags;
+	short	rd_count;
+};
+
+struct ident
+{
+	__u16	type;	/* identity type */
+	__u64	id;	/* identity id */
+	__u8	len;	/* identity len */
+	caddr_t	data;	/* identity data */
+};
+
+/*
+ * An encapsulation route consists of a pointer to a 
+ * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
+ */
+
+struct eroute
+{
+	struct rjtentry er_rjt;
+	struct sa_id er_said;
+	uint32_t er_pid;
+	uint32_t er_count;
+	uint64_t er_lasttime;
+	struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
+	struct sockaddr_encap er_emask;
+        struct ident er_ident_s;
+        struct ident er_ident_d;
+	struct sk_buff* er_first;
+	struct sk_buff* er_last;
+};
+
+#define er_dst er_said.dst
+#define er_spi er_said.spi
+
+#define _IPSEC_EROUTE_H_
+#endif /* _IPSEC_EROUTE_H_ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.2  2002/12/12 03:32:07  ken
+ * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.2  2001/11/26 09:16:13  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:18:54  mcr
+ * 	struct eroute moved to ipsec_eroute.h
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_errs.h linux-patched/net/ipsec/ipsec_errs.h
--- linux/net/ipsec/ipsec_errs.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_errs.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,50 @@
+/*
+ * @(#) definition of ipsec_errs structure
+ *
+ * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
+ *                 and Michael Richardson  <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ */
+
+/* 
+ * This file describes the errors/statistics that FreeSWAN collects.
+ *
+ */
+
+struct ipsec_errs {
+	__u32		ips_alg_errs;	       /* number of algorithm errors */
+	__u32		ips_auth_errs;	       /* # of authentication errors */
+	__u32		ips_encsize_errs;      /* # of encryption size errors*/
+	__u32		ips_encpad_errs;       /* # of encryption pad  errors*/
+	__u32		ips_replaywin_errs;    /* # of pkt sequence errors */
+};
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.2  2001/11/26 09:16:13  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:25:57  mcr
+ * 	lifetime structure created and common functions created.
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_esp.h linux-patched/net/ipsec/ipsec_esp.h
--- linux/net/ipsec/ipsec_esp.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_esp.h	Thu Sep  5 04:27:08 2002
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+#include "ipsec_md5h.h"
+#include "ipsec_sha1.h"
+
+#include "des.h"
+
+#ifndef IPPROTO_ESP
+#define IPPROTO_ESP 50
+#endif /* IPPROTO_ESP */
+
+#define ESP_HEADER_LEN		8	/* 64 bits header (spi+rpl)*/
+
+#define EMT_ESPDESCBC_ULEN	20	/* coming from user mode */
+#define EMT_ESPDES_KMAX		64	/* 512 bit secret key enough? */
+#define EMT_ESPDES_KEY_SZ	8	/* 56 bit secret key with parity = 64 bits */
+#define EMT_ESP3DES_KEY_SZ	24	/* 168 bit secret key with parity = 192 bits */
+#define EMT_ESPDES_IV_SZ	8	/* IV size */
+#define ESP_DESCBC_BLKLEN       8       /* DES-CBC block size */
+
+#define ESP_IV_MAXSZ		16	/* This is _critical_ */
+#define ESP_IV_MAXSZ_INT	(ESP_IV_MAXSZ/sizeof(int))
+
+#define DB_ES_PKTRX	0x0001
+#define DB_ES_PKTRX2	0x0002
+#define DB_ES_TDB	0x0010
+#define DB_ES_XF	0x0020
+#define DB_ES_IPAD	0x0040
+#define DB_ES_INAU	0x0080
+#define DB_ES_OINFO	0x0100
+#define DB_ES_OINFO2	0x0200
+#define DB_ES_OH	0x0400
+#define DB_ES_REPLAY	0x0800
+
+#ifdef __KERNEL__
+struct des_eks {
+	des_key_schedule ks;
+};
+
+extern struct inet_protocol esp_protocol;
+
+struct options;
+
+extern int
+esp_rcv(struct sk_buff *skb,
+	struct device *dev,
+	struct options *opt, 
+	__u32 daddr,
+	unsigned short len,
+	__u32 saddr,
+	int redo,
+	struct inet_protocol *protocol);
+
+/* XXX: only for 64 bits IVs, eg. ESP_3DES */
+struct esp
+{
+	__u32	esp_spi;		/* Security Parameters Index */
+        __u32   esp_rpl;                /* Replay counter */
+	__u8	esp_iv[8];		/* iv */
+};
+
+#ifdef CONFIG_IPSEC_DEBUG
+extern int debug_esp;
+#endif /* CONFIG_IPSEC_DEBUG */
+#endif /* __KERNEL__ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.2  2002/09/05 03:27:08  ken
+ * Applied freeswan-alg-0.8.0-BASE-klips.diff
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.17  2002/02/20 01:27:07  rgb
+ * Ditched a pile of structs only used by the old Netlink interface.
+ *
+ * Revision 1.16  2001/12/11 02:35:57  rgb
+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
+ *
+ * Revision 1.15  2001/11/26 09:23:48  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.14.2.3  2001/10/23 04:16:42  mcr
+ * 	get definition of des_key_schedule from des.h
+ *
+ * Revision 1.14.2.2  2001/10/22 20:33:13  mcr
+ * 	use "des_key_schedule" structure instead of cooking our own.
+ *
+ * Revision 1.14.2.1  2001/09/25 02:18:25  mcr
+ * 	replace "struct device" with "struct netdevice"
+ *
+ * Revision 1.14  2001/06/14 19:35:08  rgb
+ * Update copyright date.
+ *
+ * Revision 1.13  2000/09/08 19:12:56  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ *
+ * Revision 1.12  2000/08/01 14:51:50  rgb
+ * Removed _all_ remaining traces of DES.
+ *
+ * Revision 1.11  2000/01/10 16:36:20  rgb
+ * Ditch last of EME option flags, including initiator.
+ *
+ * Revision 1.10  1999/12/07 18:16:22  rgb
+ * Fixed comments at end of #endif lines.
+ *
+ * Revision 1.9  1999/04/11 00:28:57  henry
+ * GPL boilerplate
+ *
+ * Revision 1.8  1999/04/06 04:54:25  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.7  1999/01/26 02:06:00  rgb
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
+ *
+ * Revision 1.6  1999/01/22 15:22:05  rgb
+ * Re-enable IV in the espblkrply_edata structure to avoid breaking pluto
+ * until pluto can be fixed properly.
+ *
+ * Revision 1.5  1999/01/22 06:18:16  rgb
+ * Updated macro comments.
+ * Added key schedule types to support algorithm switch code.
+ *
+ * Revision 1.4  1998/08/12 00:07:32  rgb
+ * Added data structures for new xforms: null, {,3}dessha1.
+ *
+ * Revision 1.3  1998/07/14 15:57:01  rgb
+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
+ *
+ * Revision 1.2  1998/06/25 19:33:46  rgb
+ * Add prototype for protocol receive function.
+ * Rearrange for more logical layout.
+ *
+ * Revision 1.1  1998/06/18 21:27:45  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.6  1998/06/05 02:28:08  rgb
+ * Minor comment fix.
+ *
+ * Revision 1.5  1998/05/27 22:34:00  rgb
+ * Changed structures to accomodate key separation.
+ *
+ * Revision 1.4  1998/05/18 22:28:43  rgb
+ * Disable key printing facilities from /proc/net/ipsec_*.
+ *
+ * Revision 1.3  1998/04/21 21:29:07  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.2  1998/04/12 22:03:20  rgb
+ * Updated ESP-3DES-HMAC-MD5-96,
+ * 	ESP-DES-HMAC-MD5-96,
+ * 	AH-HMAC-MD5-96,
+ * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
+ *
+ * Fixed eroute references in /proc/net/ipsec*.
+ *
+ * Started to patch module unloading memory leaks in ipsec_netlink and
+ * radij tree unloading.
+ *
+ * Revision 1.1  1998/04/09 03:06:00  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:02  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.5  1997/06/03 04:24:48  ji
+ * Added ESP-3DES-MD5-96 transform.
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * Added definitions for new ESP transforms.
+ *
+ * Revision 0.3  1996/11/20 14:35:48  ji
+ * Minor Cleanup.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_init.c linux-patched/net/ipsec/ipsec_init.c
--- linux/net/ipsec/ipsec_init.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_init.c	Thu Sep  5 04:27:08 2002
@@ -0,0 +1,663 @@
+/*
+ * @(#) Initialization code.
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
+ *                                 2001  Michael Richardson <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * /proc system code was split out into ipsec_proc.c after rev. 1.70.
+ *
+ */
+
+char ipsec_init_c_version[] = "RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $";
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h> /* printk() */
+
+#include "ipsec_param.h"
+
+#ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+#else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+#endif /* MALLOC_SLAB */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/in.h>          /* struct sockaddr_in */
+#include <linux/skbuff.h>
+#include <freeswan.h>
+
+#ifdef NET_21
+# include <asm/uaccess.h>
+# include <linux/in6.h>
+#endif /* NET_21 */
+
+#include <asm/checksum.h>
+#include <net/ip.h>
+
+#ifdef CONFIG_PROC_FS
+# include <linux/proc_fs.h>
+#endif /* CONFIG_PROC_FS */
+
+#ifdef NETLINK_SOCK
+# include <linux/netlink.h>
+#else
+# include <net/netlink.h>
+#endif
+
+#include "radij.h"
+
+#include "ipsec_life.h"
+#include "ipsec_stats.h"
+#include "ipsec_sa.h"
+
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+#include "ipsec_netlink.h"
+#include "ipsec_xform.h"
+#include "ipsec_tunnel.h"
+
+#include "ipsec_rcv.h"
+#include "ipsec_ah.h"
+#include "ipsec_esp.h"
+
+#ifdef CONFIG_IPSEC_IPCOMP
+# include "ipcomp.h"
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+#include "ipsec_proto.h"
+#include "ipsec_alg.h"
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#if !defined(CONFIG_IPSEC_ESP) && !defined(CONFIG_IPSEC_AH)
+#error "kernel configuration must include ESP or AH"
+#endif
+
+/*
+ * seems to be present in 2.4.10 (Linus), but also in some RH and other
+ * distro kernels of a lower number.
+ */
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("Dual BSD/GPL");
+#endif
+
+#ifdef CONFIG_IPSEC_DEBUG
+int debug_eroute = 0;
+int debug_spi = 0;
+int debug_netlink = 0;
+#endif /* CONFIG_IPSEC_DEBUG */
+
+int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
+/*
+ * the following structure is required so that we receive
+ * event notifications when network devices are enabled and
+ * disabled (ifconfig up and down).
+ */
+static struct notifier_block ipsec_dev_notifier={
+	ipsec_device_event,
+	NULL,
+	0
+};
+
+#ifdef CONFIG_SYSCTL
+extern int ipsec_sysctl_register(void);
+extern void ipsec_sysctl_unregister(void);
+#endif
+
+/* void */
+int
+ipsec_init(void)
+{
+	int error = 0;
+#ifdef CONFIG_IPSEC_ENC_3DES
+	extern int des_check_key;
+
+	/* turn off checking of keys */
+	des_check_key=0;
+#endif /* CONFIG_IPSEC_ENC_3DES */
+
+	KLIPS_PRINT(1, "klips_info:ipsec_init: "
+		    "KLIPS startup, FreeS/WAN IPSec version: %s\n",
+		    ipsec_version_code());
+
+	error |= ipsec_proc_init();
+
+#ifndef SPINLOCK
+	tdb_lock.lock = 0;
+	eroute_lock.lock = 0;
+#endif /* !SPINLOCK */
+
+	error |= ipsec_sadb_init();
+	error |= ipsec_radijinit();
+
+	error |= pfkey_init();
+
+	error |= register_netdevice_notifier(&ipsec_dev_notifier);
+
+#ifdef CONFIG_IPSEC_ESP
+	inet_add_protocol(&esp_protocol);
+#endif /* CONFIG_IPSEC_ESP */
+
+#ifdef CONFIG_IPSEC_AH
+	inet_add_protocol(&ah_protocol);
+#endif /* CONFIG_IPSEC_AH */
+
+#if 0
+#ifdef CONFIG_IPSEC_IPCOMP
+	inet_add_protocol(&comp_protocol);
+#endif /* CONFIG_IPSEC_IPCOMP */
+#endif
+
+	error |= ipsec_tunnel_init_devices();
+
+#ifdef CONFIG_SYSCTL
+        error |= ipsec_sysctl_register();
+#endif                                                                          
+#ifdef CONFIG_IPSEC_ALG
+	ipsec_alg_init();
+#endif
+	return error;
+}	
+
+
+/* void */
+int
+ipsec_cleanup(void)
+{
+	int error = 0;
+
+#ifdef CONFIG_SYSCTL
+        ipsec_sysctl_unregister();
+#endif                                                                          
+	KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
+		    "klips_debug:ipsec_cleanup: "
+		    "calling ipsec_tunnel_cleanup_devices.\n");
+	error |= ipsec_tunnel_cleanup_devices();
+
+#if 0
+#ifdef CONFIG_IPSEC_IPCOMP
+	if (inet_del_protocol(&comp_protocol) < 0)
+		printk(KERN_INFO "klips_debug:ipsec_cleanup: "
+		       "comp close: can't remove protocol\n");
+#endif /* CONFIG_IPSEC_IPCOMP */
+#endif /* 0 */
+#ifdef CONFIG_IPSEC_AH
+	if (inet_del_protocol(&ah_protocol) < 0)
+		printk(KERN_INFO "klips_debug:ipsec_cleanup: "
+		       "ah close: can't remove protocol\n");
+#endif /* CONFIG_IPSEC_AH */
+#ifdef CONFIG_IPSEC_ESP
+	if (inet_del_protocol(&esp_protocol) < 0)
+		printk(KERN_INFO "klips_debug:ipsec_cleanup: "
+		       "esp close: can't remove protocol\n");
+#endif /* CONFIG_IPSEC_ESP */
+
+	error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
+
+	KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
+		    "klips_debug:ipsec_cleanup: "
+		    "calling ipsec_tdbcleanup.\n");
+	error |= ipsec_sadb_cleanup(0);
+	KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
+		    "klips_debug:ipsec_cleanup: "
+		    "calling ipsec_radijcleanup.\n");
+	error |= ipsec_radijcleanup();
+	
+	KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
+		    "klips_debug:ipsec_cleanup: "
+		    "calling pfkey_cleanup.\n");
+	error |= pfkey_cleanup();
+
+	ipsec_proc_cleanup();
+
+	return error;
+}
+
+#ifdef MODULE
+int
+init_module(void)
+{
+	int error = 0;
+
+	error |= ipsec_init();
+
+	return error;
+}
+
+int
+cleanup_module(void)
+{
+	int error = 0;
+
+	KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
+		    "klips_debug:cleanup_module: "
+		    "calling ipsec_cleanup.\n");
+
+	error |= ipsec_cleanup();
+
+	KLIPS_PRINT(1, "klips_info:cleanup_module: "
+		    "ipsec module unloaded.\n");
+
+	return error;
+}
+#endif /* MODULE */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.2  2002/09/05 03:27:08  ken
+ * Applied freeswan-alg-0.8.0-BASE-klips.diff
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.80  2002/03/24 07:34:08  rgb
+ * Sanity check for at least one of AH or ESP configured.
+ *
+ * Revision 1.79  2002/02/05 22:55:15  mcr
+ * 	added MODULE_LICENSE declaration.
+ * 	This macro does not appear in all kernel versions (see comment).
+ *
+ * Revision 1.78  2002/01/29 17:17:55  mcr
+ * 	moved include of ipsec_param.h to after include of linux/kernel.h
+ * 	otherwise, it seems that some option that is set in ipsec_param.h
+ * 	screws up something subtle in the include path to kernel.h, and
+ * 	it complains on the snprintf() prototype.
+ *
+ * Revision 1.77  2002/01/29 04:00:51  mcr
+ * 	more excise of kversions.h header.
+ *
+ * Revision 1.76  2002/01/29 02:13:17  mcr
+ * 	introduction of ipsec_kversion.h means that include of
+ * 	ipsec_param.h must preceed any decisions about what files to
+ * 	include to deal with differences in kernel source.
+ *
+ * Revision 1.75  2001/11/26 09:23:48  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.74  2001/11/22 05:44:11  henry
+ * new version stuff
+ *
+ * Revision 1.71.2.2  2001/10/22 20:51:00  mcr
+ * 	explicitely set des_check_key.
+ *
+ * Revision 1.71.2.1  2001/09/25 02:19:39  mcr
+ * 	/proc manipulation code moved to new ipsec_proc.c
+ *
+ * Revision 1.73  2001/11/06 19:47:17  rgb
+ * Changed lifetime_packets to uint32 from uint64.
+ *
+ * Revision 1.72  2001/10/18 04:45:19  rgb
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
+ * lib/freeswan.h version macros moved to lib/kversions.h.
+ * Other compiler directive cleanups.
+ *
+ * Revision 1.71  2001/09/20 15:32:45  rgb
+ * Minor pfkey lifetime fixes.
+ *
+ * Revision 1.70  2001/07/06 19:51:21  rgb
+ * Added inbound policy checking code for IPIP SAs.
+ *
+ * Revision 1.69  2001/06/14 19:33:26  rgb
+ * Silence startup message for console, but allow it to be logged.
+ * Update copyright date.
+ *
+ * Revision 1.68  2001/05/29 05:14:36  rgb
+ * Added PMTU to /proc/net/ipsec_tncfg output.  See 'man 5 ipsec_tncfg'.
+ *
+ * Revision 1.67  2001/05/04 16:34:52  rgb
+ * Rremove erroneous checking of return codes for proc_net_* in 2.4.
+ *
+ * Revision 1.66  2001/05/03 19:40:34  rgb
+ * Check error return codes in startup and shutdown.
+ *
+ * Revision 1.65  2001/02/28 05:03:27  rgb
+ * Clean up and rationalise startup messages.
+ *
+ * Revision 1.64  2001/02/27 22:24:53  rgb
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
+ * Check for satoa() return codes.
+ *
+ * Revision 1.63  2000/11/29 20:14:06  rgb
+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
+ *
+ * Revision 1.62  2000/11/06 04:31:24  rgb
+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
+ * Fixed longlong for pre-2.4 kernels (Svenning).
+ * Add Svenning's adaptive content compression.
+ * Disabled registration of ipcomp handler.
+ *
+ * Revision 1.61  2000/10/11 13:37:54  rgb
+ * #ifdef out debug print that causes proc/net/ipsec_version to oops.
+ *
+ * Revision 1.60  2000/09/20 03:59:01  rgb
+ * Change static info functions to DEBUG_NO_STATIC to reveal function names
+ * in oopsen.
+ *
+ * Revision 1.59  2000/09/16 01:06:26  rgb
+ * Added cast of var to silence compiler warning about long fed to int
+ * format.
+ *
+ * Revision 1.58  2000/09/15 11:37:01  rgb
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
+ * IPCOMP zlib deflate code.
+ *
+ * Revision 1.57  2000/09/12 03:21:50  rgb
+ * Moved radij_c_version printing to ipsec_version_get_info().
+ * Reformatted ipsec_version_get_info().
+ * Added sysctl_{,un}register() calls.
+ *
+ * Revision 1.56  2000/09/08 19:16:50  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
+ *
+ * Revision 1.55  2000/08/30 05:19:03  rgb
+ * Cleaned up no longer used spi_next, netlink register/unregister, other
+ * minor cleanup.
+ * Removed cruft replaced by TDB_XFORM_NAME.
+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
+ * Moved debug version strings to printk when /proc/net/ipsec_version is
+ * called.
+ *
+ * Revision 1.54  2000/08/20 18:31:05  rgb
+ * Changed cosmetic alignment in spi_info.
+ * Changed addtime and usetime to use actual value which is relative
+ * anyways, as intended. (Momchil)
+ *
+ * Revision 1.53  2000/08/18 17:37:03  rgb
+ * Added an (int) cast to shut up the compiler...
+ *
+ * Revision 1.52  2000/08/01 14:51:50  rgb
+ * Removed _all_ remaining traces of DES.
+ *
+ * Revision 1.51  2000/07/25 20:41:22  rgb
+ * Removed duplicate parameter in spi_getinfo.
+ *
+ * Revision 1.50  2000/07/17 03:21:45  rgb
+ * Removed /proc/net/ipsec_spinew.
+ *
+ * Revision 1.49  2000/06/28 05:46:51  rgb
+ * Renamed ivlen to iv_bits for consistency.
+ * Changed output of add and use times to be relative to now.
+ *
+ * Revision 1.48  2000/05/11 18:26:10  rgb
+ * Commented out calls to netlink_attach/detach to avoid activating netlink
+ * in the kenrel config.
+ *
+ * Revision 1.47  2000/05/10 22:35:26  rgb
+ * Comment out most of the startup version information.
+ *
+ * Revision 1.46  2000/03/22 16:15:36  rgb
+ * Fixed renaming of dev_get (MB).
+ *
+ * Revision 1.45  2000/03/16 06:40:48  rgb
+ * Hardcode PF_KEYv2 support.
+ *
+ * Revision 1.44  2000/01/22 23:19:20  rgb
+ * Simplified code to use existing macro TDB_XFORM_NAME().
+ *
+ * Revision 1.43  2000/01/21 06:14:04  rgb
+ * Print individual stats only if non-zero.
+ * Removed 'bits' from each keylength for brevity.
+ * Shortened lifetimes legend for brevity.
+ * Changed wording from 'last_used' to the clearer 'idle'.
+ *
+ * Revision 1.42  1999/12/31 14:57:19  rgb
+ * MB fix for new dummy-less proc_get_info in 2.3.35.
+ *
+ * Revision 1.41  1999/11/23 23:04:03  rgb
+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
+ * Sort out pfkey and freeswan headers, putting them in a library path.
+ *
+ * Revision 1.40  1999/11/18 18:47:01  rgb
+ * Added dynamic proc registration for 2.3.25+.
+ * Changed all device registrations for static linking to
+ * dynamic to reduce the number and size of patches.
+ * Changed all protocol registrations for static linking to
+ * dynamic to reduce the number and size of patches.
+ *
+ * Revision 1.39  1999/11/18 04:12:07  rgb
+ * Replaced all kernel version macros to shorter, readable form.
+ * Added Marc Boucher's 2.3.25 proc patches.
+ * Converted all PROC_FS entries to dynamic to reduce kernel patching.
+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
+ *
+ * Revision 1.38  1999/11/17 15:53:38  rgb
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
+ * klips/net/ipsec/Makefile.
+ *
+ * Revision 1.37  1999/10/16 04:23:06  rgb
+ * Add stats for replaywin_errs, replaywin_max_sequence_difference,
+ * authentication errors, encryption size errors, encryption padding
+ * errors, and time since last packet.
+ *
+ * Revision 1.36  1999/10/16 00:30:47  rgb
+ * Added SA lifetime counting.
+ *
+ * Revision 1.35  1999/10/15 22:14:00  rgb
+ * Clean out cruft.
+ *
+ * Revision 1.34  1999/10/03 18:46:28  rgb
+ * Spinlock fixes for 2.0.xx and 2.3.xx.
+ *
+ * Revision 1.33  1999/10/01 17:08:10  rgb
+ * Disable spinlock init.
+ *
+ * Revision 1.32  1999/10/01 16:22:24  rgb
+ * Switch from assignment init. to functional init. of spinlocks.
+ *
+ * Revision 1.31  1999/10/01 15:44:52  rgb
+ * Move spinlock header include to 2.1> scope.
+ *
+ * Revision 1.30  1999/10/01 00:00:16  rgb
+ * Added eroute structure locking.
+ * Added tdb structure locking.
+ * Minor formatting changes.
+ * Add call to initialize tdb hash table.
+ *
+ * Revision 1.29  1999/09/23 20:22:40  rgb
+ * Enable, tidy and fix network notifier code.
+ *
+ * Revision 1.28  1999/09/18 11:39:56  rgb
+ * Start to add (disabled) netdevice notifier code.
+ *
+ * Revision 1.27  1999/08/28 08:24:47  rgb
+ * Add compiler directives to compile cleanly without debugging.
+ *
+ * Revision 1.26  1999/08/06 16:03:22  rgb
+ * Correct error messages on failure to unload /proc entries.
+ *
+ * Revision 1.25  1999/08/03 17:07:25  rgb
+ * Report device MTU, not private MTU.
+ *
+ * Revision 1.24  1999/05/25 22:24:37  rgb
+ * /PROC/NET/ipsec* init problem fix.
+ *
+ * Revision 1.23  1999/05/25 02:16:38  rgb
+ * Make modular proc_fs entries dynamic and fix for 2.2.x.
+ *
+ * Revision 1.22  1999/05/09 03:25:35  rgb
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
+ *
+ * Revision 1.21  1999/05/05 22:02:30  rgb
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
+ *
+ * Revision 1.20  1999/04/29 15:15:50  rgb
+ * Fix undetected iv_len reporting bug.
+ * Add sanity checking for null pointer to private data space.
+ * Add return values to init and cleanup functions.
+ *
+ * Revision 1.19  1999/04/27 19:24:44  rgb
+ * Added /proc/net/ipsec_klipsdebug support for reading the current debug
+ * settings.
+ * Instrument module load/init/unload.
+ *
+ * Revision 1.18  1999/04/15 15:37:24  rgb
+ * Forward check changes from POST1_00 branch.
+ *
+ * Revision 1.15.2.3  1999/04/13 20:29:19  rgb
+ * /proc/net/ipsec_* cleanup.
+ *
+ * Revision 1.15.2.2  1999/04/02 04:28:23  rgb
+ * /proc/net/ipsec_* formatting enhancements.
+ *
+ * Revision 1.15.2.1  1999/03/30 17:08:33  rgb
+ * Add pfkey initialisation.
+ *
+ * Revision 1.17  1999/04/11 00:28:57  henry
+ * GPL boilerplate
+ *
+ * Revision 1.16  1999/04/06 04:54:25  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.15  1999/02/24 20:15:07  rgb
+ * Update output format.
+ *
+ * Revision 1.14  1999/02/17 16:49:39  rgb
+ * Convert DEBUG_IPSEC to KLIPS_PRINT
+ * Ditch NET_IPIP dependancy.
+ *
+ * Revision 1.13  1999/01/26 02:06:37  rgb
+ * Remove ah/esp switching on include files.
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
+ * Removed dead code.
+ * Remove references to INET_GET_PROTOCOL.
+ *
+ * Revision 1.12  1999/01/22 06:19:18  rgb
+ * Cruft clean-out.
+ * 64-bit clean-up.
+ * Added algorithm switch code.
+ *
+ * Revision 1.11  1998/12/01 05:54:53  rgb
+ * Cleanup and order debug version output.
+ *
+ * Revision 1.10  1998/11/30 13:22:54  rgb
+ * Rationalised all the klips kernel file headers.  They are much shorter
+ * now and won't conflict under RH5.2.
+ *
+ * Revision 1.9  1998/11/10 05:35:13  rgb
+ * Print direction in/out flag from /proc/net/ipsec_spi.
+ *
+ * Revision 1.8  1998/10/27 13:48:10  rgb
+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
+ * Fixed less(1) truncated output bug.
+ * Code clean-up.
+ *
+ * Revision 1.7  1998/10/22 06:43:16  rgb
+ * Convert to use satoa for printk.
+ *
+ * Revision 1.6  1998/10/19 14:24:35  rgb
+ * Added inclusion of freeswan.h.
+ *
+ * Revision 1.5  1998/10/09 04:43:35  rgb
+ * Added 'klips_debug' prefix to all klips printk debug statements.
+ *
+ * Revision 1.4  1998/07/27 21:50:22  rgb
+ * Not necessary to traverse mask tree for /proc/net/ipsec_eroute.
+ *
+ * Revision 1.3  1998/06/25 19:51:20  rgb
+ * Clean up #endif comments.
+ * Shift debugging comment control for procfs to debug_tunnel.
+ * Make proc_dir_entries visible to rest of kernel for static link.
+ * Replace hardwired fileperms with macros.
+ * Use macros for procfs inode numbers.
+ * Rearrange initialisations between ipsec_init and module_init as appropriate
+ * for static loading.
+ *
+ * Revision 1.2  1998/06/23 02:55:43  rgb
+ * Slightly quieted init-time messages.
+ * Re-introduced inet_add_protocol after it mysteriously disappeared...
+ * Check for and warn of absence of IPIP protocol on install of module.
+ * Move tdbcleanup to ipsec_xform.c.
+ *
+ * Revision 1.10  1998/06/18 21:29:04  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
+ * build scripts happier in presence of symbolic links
+ *
+ * Revision 1.9  1998/06/14 23:49:40  rgb
+ * Clarify version reporting on module loading.
+ *
+ * Revision 1.8  1998/06/11 05:54:23  rgb
+ * Added /proc/net/ipsec_version to report freeswan and transform versions.
+ * Added /proc/net/ipsec_spinew to generate new and unique spi's..
+ * Fixed /proc/net/ipsec_tncfg bug.
+ *
+ * Revision 1.7  1998/05/25 20:23:13  rgb
+ * proc_register changed to dynamic registration to avoid arbitrary inode
+ * numbers.
+ *
+ * Implement memory recovery from tdb and eroute tables.
+ *
+ * Revision 1.6  1998/05/21 13:08:58  rgb
+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
+ * information is available for printout.
+ *
+ * Revision 1.5  1998/05/18 21:29:48  rgb
+ * Cleaned up /proc/net/ipsec_* output, including a title line, algorithm
+ * names instead of numbers, standard format for numerical output base,
+ * whitespace for legibility, and the names themselves for consistency.
+ *
+ * Added /proc/net/ipsec_spigrp and /proc/net/ipsec_tncfg.
+ *
+ * Revision 1.4  1998/04/30 15:42:24  rgb
+ * Silencing attach for normal operations with #ifdef IPSEC_DEBUG.
+ *
+ * Revision 1.3  1998/04/21 21:28:58  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.2  1998/04/12 22:03:22  rgb
+ * Updated ESP-3DES-HMAC-MD5-96,
+ * 	ESP-DES-HMAC-MD5-96,
+ * 	AH-HMAC-MD5-96,
+ * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
+ *
+ * Fixed eroute references in /proc/net/ipsec*.
+ *
+ * Started to patch module unloading memory leaks in ipsec_netlink and
+ * radij tree unloading.
+ *
+ * Revision 1.1  1998/04/09 03:06:05  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:02  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * No changes.
+ *
+ * Revision 0.3  1996/11/20 14:39:04  ji
+ * Fixed problem with node names of /proc/net entries.
+ * Other minor cleanups.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_ipe4.h linux-patched/net/ipsec/ipsec_ipe4.h
--- linux/net/ipsec/ipsec_ipe4.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_ipe4.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,65 @@
+/*
+ * IP-in-IP Header declarations
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+/* The packet header is an IP header! */
+
+struct ipe4_xdata			/* transform table data */
+{
+	struct in_addr	i4_src;
+	struct in_addr	i4_dst;
+};
+
+#define EMT_IPE4_ULEN	8	/* coming from user mode */
+ 
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.4  2001/06/14 19:35:08  rgb
+ * Update copyright date.
+ *
+ * Revision 1.3  1999/04/11 00:28:57  henry
+ * GPL boilerplate
+ *
+ * Revision 1.2  1999/04/06 04:54:25  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.1  1998/06/18 21:27:47  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.1  1998/04/09 03:06:07  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:03  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * No changes.
+ *
+ * Revision 0.3  1996/11/20 14:48:53  ji
+ * Release update only.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_kversion.h linux-patched/net/ipsec/ipsec_kversion.h
--- linux/net/ipsec/ipsec_kversion.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_kversion.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,190 @@
+#ifndef _FREESWAN_KVERSIONS_H
+/*
+ * header file for FreeS/WAN library functions
+ * Copyright (C) 1998, 1999, 2000  Henry Spencer.
+ * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs
+ * 
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
+ * 
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+#define	_FREESWAN_KVERSIONS_H	/* seen it, no need to see it again */
+
+/*
+ * this file contains a series of atomic defines that depend upon
+ * kernel version numbers. The kernel versions are arranged
+ * in version-order number (which is often not chronological)
+ * and each clause enables or disables a feature.
+ */
+
+/*
+ * First, assorted kernel-version-dependent trickery.
+ */
+#include <linux/version.h>
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+#define HEADER_CACHE_BIND_21
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
+#define SPINLOCK
+#define PROC_FS_21
+#define NETLINK_SOCK
+#define NET_21
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
+#define net_device_stats enet_statistics
+#endif                                                                         
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+#define SPINLOCK_23
+#define NETDEV_23
+#  ifndef CONFIG_IP_ALIAS
+#  define CONFIG_IP_ALIAS
+#  endif
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
+#define PROC_FS_2325
+#undef  PROC_FS_21
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
+#define PROC_NO_DUMMY
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
+#define SKB_COPY_EXPAND
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
+#define IP_SELECT_IDENT
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
+#define SKB_RESET_NFCT
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
+#define IP_SELECT_IDENT_NEW
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
+#define IPH_is_SKB_PULLED
+#define SKB_COW_NEW
+#define PROTO_HANDLER_SINGLE_PARM
+#define IP_FRAGMENT_LINEARIZE 1
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
+#  ifdef REDHAT_BOGOSITY
+#  define IP_SELECT_IDENT_NEW
+#  define IPH_is_SKB_PULLED
+#  define SKB_COW_NEW
+#  define PROTO_HANDLER_SINGLE_PARM
+#  endif /* REDHAT_BOGOSITY */
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
+#define MALLOC_SLAB
+#define LINUX_KERNEL_HAS_SNPRINTF
+#endif                                                                         
+
+#ifdef NET_21
+#  include <linux/in6.h>
+#else
+     /* old kernel in.h has some IPv6 stuff, but not quite enough */
+#  define	s6_addr16	s6_addr
+#  define	AF_INET6	10
+#  define uint8_t __u8
+#  define uint16_t __u16 
+#  define uint32_t __u32 
+#  define uint64_t __u64 
+#endif
+
+#ifndef SPINLOCK
+#  include <linux/bios32.h>
+     /* simulate spin locks and read/write locks */
+     typedef struct {
+       volatile char lock;
+     } spinlock_t;
+
+     typedef struct {
+       volatile unsigned int lock;
+     } rwlock_t;                                                                     
+
+#  define spin_lock_init(x) { (x)->lock = 0;}
+#  define rw_lock_init(x) { (x)->lock = 0; }
+
+#  define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
+#  define spin_lock_irq(x) { cli(); spin_lock(x);}
+#  define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
+
+#  define spin_unlock(x) { (x)->lock=0;}
+#  define spin_unlock_irq(x) { spin_unlock(x); sti();}
+#  define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
+
+#  define read_lock(x) spin_lock(x)
+#  define read_lock_irq(x) spin_lock_irq(x)
+#  define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
+
+#  define read_unlock(x) spin_unlock(x)
+#  define read_unlock_irq(x) spin_unlock_irq(x)
+#  define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
+
+#  define write_lock(x) spin_lock(x)
+#  define write_lock_irq(x) spin_lock_irq(x)
+#  define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
+
+#  define write_unlock(x) spin_unlock(x)
+#  define write_unlock_irq(x) spin_unlock_irq(x)
+#  define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
+#endif /* !SPINLOCK */
+
+#ifndef SPINLOCK_23
+#  define spin_lock_bh(x)  spin_lock_irq(x)
+#  define spin_unlock_bh(x)  spin_unlock_irq(x)
+
+#  define read_lock_bh(x)  read_lock_irq(x)
+#  define read_unlock_bh(x)  read_unlock_irq(x)
+
+#  define write_lock_bh(x)  write_lock_irq(x)
+#  define write_unlock_bh(x)  write_unlock_irq(x)
+#endif /* !SPINLOCK_23 */
+
+#endif /* _FREESWAN_KVERSIONS_H */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.2.2.1  2002/04/12 03:21:43  mcr
+ *    fixes for compilation on RH 7.1
+ *
+ * Revision 1.3  2002/04/12 03:21:17  mcr
+ * 	three parameter version of ip_select_ident appears first
+ * 	in 2.4.2 (RH7.1) not 2.4.4.
+ *
+ * Revision 1.2  2002/03/08 21:35:22  rgb
+ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
+ * 2.4.9.  (Andreas Piesk).
+ *
+ * Revision 1.1  2002/01/29 02:11:42  mcr
+ * 	removal of kversions.h - sources that needed it now use ipsec_param.h.
+ * 	updating of IPv6 structures to match latest in6.h version.
+ * 	removed dead code from freeswan.h that also duplicated kversions.h
+ * 	code.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_life.c linux-patched/net/ipsec/ipsec_life.c
--- linux/net/ipsec/ipsec_life.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_life.c	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,242 @@
+/*
+ * @(#) lifetime structure utilities
+ *
+ * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
+ *                 and Michael Richardson  <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ */
+
+/* 
+ * This provides series of utility functions for dealing with lifetime
+ * structures.
+ *
+ * ipsec_check_lifetime - returns -1    hard lifetime exceeded
+ *                                 0    soft lifetime exceeded
+ *                                 1    everything is okay
+ *                        based upon whether or not the count exceeds hard/soft
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/config.h>	/* for CONFIG_IP_FORWARD */
+#include <linux/version.h>
+#include <linux/kernel.h> /* printk() */
+
+#include "ipsec_param.h"
+
+#include <linux/netdevice.h>   /* struct device, struct net_device_stats and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/skbuff.h>
+#include <freeswan.h>
+
+#include "radij.h"
+#include "ipsec_life.h"
+#include "ipsec_xform.h"
+#include "ipsec_eroute.h"
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+
+#include "ipsec_netlink.h"
+#include "ipsec_sa.h"
+#include "ipsec_tunnel.h"
+#include "ipsec_ipe4.h"
+#include "ipsec_ah.h"
+#include "ipsec_esp.h"
+
+#ifdef CONFIG_IPSEC_IPCOMP
+#include "ipcomp.h"
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#include "ipsec_proto.h"
+
+
+enum ipsec_life_alive
+ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
+		     const char *lifename,
+		     const char *saname,
+		     enum ipsec_life_type ilt,
+		     enum ipsec_direction idir,
+		     struct ipsec_sa *ips)
+{
+	__u64 count;
+	const char *dir;
+
+	if(saname == NULL) {
+		saname = "unknown-SA";
+	}
+
+	if(idir == ipsec_incoming) {
+		dir = "incoming";
+	} else {
+		dir = "outgoing";
+	}
+		
+
+	if(ilt == ipsec_life_timebased) {
+		count = jiffies/HZ - il64->ipl_count;
+	} else {
+		count = il64->ipl_count;
+	}
+
+	if(il64->ipl_hard &&
+	   (count > il64->ipl_hard)) {
+		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
+			    "%s packet dropped.\n",
+			    lifename,
+			    IPS_XFORM_NAME(ips),
+			    saname,
+			    dir);
+
+		pfkey_expire(ips, 1);
+		return ipsec_life_harddied;
+	}
+
+	if(il64->ipl_soft &&
+	   (count > il64->ipl_soft)) {
+		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
+			    "soft expire message sent up, %s packet still processed.\n",
+			    lifename,
+			    IPS_XFORM_NAME(ips),
+			    saname,
+			    dir);
+
+		if(ips->ips_state != SADB_SASTATE_DYING) {
+			pfkey_expire(ips, 0);
+		}
+		ips->ips_state = SADB_SASTATE_DYING;
+
+		return ipsec_life_softdied;
+	}
+	return ipsec_life_okay;
+}
+
+
+/*
+ * This function takes a buffer (with length), a lifetime name and type,
+ * and formats a string to represent the current values of the lifetime.
+ * 
+ * It returns the number of bytes that the format took.
+ * This is used in /proc routines and in debug output.
+ */
+int
+ipsec_lifetime_format(char *buffer,
+		      int   buflen,
+		      char *lifename,
+		      enum ipsec_life_type timebaselife,
+		      struct ipsec_lifetime64 *lifetime)
+{
+	int len = 0;
+	__u64 count;
+
+	if(timebaselife == ipsec_life_timebased) {
+		count = jiffies/HZ - lifetime->ipl_count;
+	} else {
+		count = lifetime->ipl_count;
+	}
+
+	if(lifetime->ipl_count > 1 || 
+	   lifetime->ipl_soft      ||
+	   lifetime->ipl_hard) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) 
+		len = snprintf(buffer, buflen,
+			       "%s(%Lu,%Lu,%Lu)",
+			       lifename,
+			       count,
+			       lifetime->ipl_soft,
+			       lifetime->ipl_hard);
+#else /* XXX high 32 bits are not displayed */
+		len = snprintf(buffer, buflen,
+				"%s(%lu,%lu,%lu)",
+				lifename,
+				(unsigned long)count,
+				(unsigned long)lifetime->ipl_soft,
+				(unsigned long)lifetime->ipl_hard);
+#endif
+	}
+
+	return len;
+}
+
+void
+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
+			  __u64 newvalue)
+{
+	if(newvalue &&
+	   (!lifetime->ipl_hard ||
+	    (newvalue < lifetime->ipl_hard))) {
+		lifetime->ipl_hard = newvalue;
+
+		if(!lifetime->ipl_soft &&
+		   (lifetime->ipl_hard < lifetime->ipl_soft)) {
+			lifetime->ipl_soft = lifetime->ipl_hard;
+		}
+	}
+}	
+
+void
+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
+			  __u64 newvalue)
+{
+	if(newvalue &&
+	   (!lifetime->ipl_soft ||
+	    (newvalue < lifetime->ipl_soft))) {
+		lifetime->ipl_soft = newvalue;
+
+		if(lifetime->ipl_hard &&
+		   (lifetime->ipl_hard < lifetime->ipl_soft)) {
+			lifetime->ipl_soft = lifetime->ipl_hard;
+		}
+	}
+}
+
+	
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.4.6.1  2002/05/31 00:19:05  mcr
+ * 	pullup of PR#72 fix from mainbranch-lifetime is relative.
+ *
+ * Revision 1.4  2002/01/29 17:17:55  mcr
+ * 	moved include of ipsec_param.h to after include of linux/kernel.h
+ * 	otherwise, it seems that some option that is set in ipsec_param.h
+ * 	screws up something subtle in the include path to kernel.h, and
+ * 	it complains on the snprintf() prototype.
+ *
+ * Revision 1.3  2002/01/29 02:13:17  mcr
+ * 	introduction of ipsec_kversion.h means that include of
+ * 	ipsec_param.h must preceed any decisions about what files to
+ * 	include to deal with differences in kernel source.
+ *
+ * Revision 1.2  2001/11/26 09:16:14  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:25:57  mcr
+ * 	lifetime structure created and common functions created.
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_life.h linux-patched/net/ipsec/ipsec_life.h
--- linux/net/ipsec/ipsec_life.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_life.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,109 @@
+/*
+ * Definitions relevant to IPSEC lifetimes
+ * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
+ *                 and Michael Richardson  <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
+ *
+ */
+
+/* 
+ * This file describes the book keeping fields for the 
+ *   IPsec Security Association Structure. ("ipsec_sa")
+ *
+ * This structure is never allocated directly by kernel code,
+ * (it is always a static/auto or is part of a structure)
+ * so it does not have a reference count.
+ *
+ */
+
+#ifndef _IPSEC_LIFE_H_
+
+/*
+ *  _count is total count.
+ *  _hard is hard limit (kill SA after this number)
+ *  _soft is soft limit (try to renew SA after this number)
+ *  _last is used in some special cases.
+ *
+ */
+
+struct ipsec_lifetime64
+{
+	__u64           ipl_count;
+	__u64           ipl_soft;
+	__u64           ipl_hard;
+	__u64           ipl_last;  
+};
+
+struct ipsec_lifetimes
+{
+	/* number of bytes processed */
+	struct ipsec_lifetime64 ipl_bytes;
+
+	/* number of packets processed */
+	struct ipsec_lifetime64 ipl_packets;
+
+	/* time since SA was added */
+	struct ipsec_lifetime64 ipl_addtime;
+
+	/* time since SA was first used */
+	struct ipsec_lifetime64 ipl_usetime;
+
+	/* from rfc2367:  
+         *         For CURRENT, the number of different connections,
+         *         endpoints, or flows that the association has been
+         *          allocated towards. For HARD and SOFT, the number of
+         *          these the association may be allocated towards
+         *          before it expires. The concept of a connection,
+         *          flow, or endpoint is system specific.
+	 *
+	 * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
+	 *          They are maintained for PF_KEY compatibility. 
+	 */
+	struct ipsec_lifetime64 ipl_allocations;
+};
+
+enum ipsec_life_alive {
+	ipsec_life_harddied = -1,
+	ipsec_life_softdied = 0,
+	ipsec_life_okay     = 1
+};
+
+enum ipsec_life_type {
+	ipsec_life_timebased = 1,
+	ipsec_life_countbased= 0
+};
+
+#define _IPSEC_LIFE_H_
+#endif /* _IPSEC_LIFE_H_ */
+
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.2  2001/11/26 09:16:14  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:25:58  mcr
+ * 	lifetime structure created and common functions created.
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_md5c.c linux-patched/net/ipsec/ipsec_md5c.c
--- linux/net/ipsec/ipsec_md5c.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_md5c.c	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,433 @@
+/*
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+/*
+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
+ * changes to accomodate it in the kernel by ji.
+ */
+
+#include <asm/byteorder.h>
+#include <linux/string.h>
+
+#include "ipsec_md5h.h"
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/*
+ * Additions by JI
+ * 
+ * HAVEMEMCOPY is defined if mem* routines are available
+ *
+ * HAVEHTON is defined if htons() and htonl() can be used
+ * for big/little endian conversions
+ *
+ */
+
+#define HAVEMEMCOPY
+#ifdef __LITTLE_ENDIAN
+#define LITTLENDIAN
+#endif
+#ifdef __BIG_ENDIAN
+#define BIGENDIAN
+#endif
+
+/* Constants for MD5Transform routine.
+ */
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+
+#ifdef LITTLEENDIAN
+#define Encode MD5_memcpy
+#define Decode MD5_memcpy
+#else
+static void Encode PROTO_LIST
+  ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+  ((UINT4 *, unsigned char *, unsigned int));
+#endif
+
+#ifdef HAVEMEMCOPY
+/* no need to include <memory.h> here; <linux/string.h> defines these */
+#define MD5_memcpy	memcpy
+#define MD5_memset	memset
+#else
+#ifdef HAVEBCOPY
+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
+#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
+#else
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+#endif
+#endif
+static unsigned char PADDING[64] = {
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (context)
+MD5_CTX *context;                                        /* context */
+{
+  context->count[0] = context->count[1] = 0;
+  /* Load magic initialization constants.
+*/
+  context->state[0] = 0x67452301;
+  context->state[1] = 0xefcdab89;
+  context->state[2] = 0x98badcfe;
+  context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+  operation, processing another message block, and updating the
+  context.
+ */
+void MD5Update (context, input, inputLen)
+MD5_CTX *context;                                        /* context */
+unsigned char *input;                                /* input block */
+__u32 inputLen;                     /* length of input block */
+{
+  __u32 i;
+  unsigned int index, partLen;
+
+  /* Compute number of bytes mod 64 */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+  /* Update number of bits */
+  if ((context->count[0] += ((UINT4)inputLen << 3))
+   < ((UINT4)inputLen << 3))
+ context->count[1]++;
+  context->count[1] += ((UINT4)inputLen >> 29);
+
+  partLen = 64 - index;
+
+  /* Transform as many times as possible.
+*/
+  if (inputLen >= partLen) {
+ MD5_memcpy
+   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+   MD5Transform (context->state, &input[i]);
+
+ index = 0;
+  }
+  else
+ i = 0;
+
+  /* Buffer remaining input */
+  MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+  inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+  the message digest and zeroizing the context.
+ */
+void MD5Final (digest, context)
+unsigned char digest[16];                         /* message digest */
+MD5_CTX *context;                                       /* context */
+{
+  unsigned char bits[8];
+  unsigned int index, padLen;
+
+  /* Save number of bits */
+  Encode (bits, context->count, 8);
+
+  /* Pad out to 56 mod 64.
+*/
+  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+  padLen = (index < 56) ? (56 - index) : (120 - index);
+  MD5Update (context, PADDING, padLen);
+
+  /* Append length (before padding) */
+  MD5Update (context, bits, 8);
+
+  if (digest != NULL)			/* Bill Simpson's padding */
+  {
+	  /* store state in digest */
+	  Encode (digest, context->state, 16);
+
+	  /* Zeroize sensitive information.
+	   */
+	  MD5_memset ((POINTER)context, 0, sizeof (*context));
+  }
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+  Decode (x, block, 64);
+
+  /* Round 1 */
+  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+  /* Round 3 */
+  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+  /* Round 4 */
+  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+
+  /* Zeroize sensitive information.
+*/
+  MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+#ifndef LITTLEENDIAN
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+  a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+  }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+  a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+#endif
+
+#ifndef HAVEMEMCOPY
+#ifndef HAVEBCOPY
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+
+ output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
+#endif
+#endif
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.4  1999/12/13 13:59:12  rgb
+ * Quick fix to argument size to Update bugs.
+ *
+ * Revision 1.3  1999/05/21 18:09:28  henry
+ * unnecessary <memory.h> include causes trouble in 2.2
+ *
+ * Revision 1.2  1999/04/06 04:54:26  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.1  1998/06/18 21:27:48  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.2  1998/04/23 20:54:02  rgb
+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
+ * verified.
+ *
+ * Revision 1.1  1998/04/09 03:06:08  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:04  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.3  1996/11/20 14:48:53  ji
+ * Release update only.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_md5h.h linux-patched/net/ipsec/ipsec_md5h.h
--- linux/net/ipsec/ipsec_md5h.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_md5h.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,132 @@
+/*
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+/*
+ * The rest of this file is Copyright RSA DSI. See the following comments
+ * for the full Copyright notice.
+ */
+
+#ifndef _IPSEC_MD5H_H_
+#define _IPSEC_MD5H_H_
+
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+     function argument prototyping.
+   The following makes PROTOTYPES default to 0 if it has not already
+     been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 1
+#endif /* !PROTOTYPES */
+
+/* POINTER defines a generic pointer type */
+typedef __u8 *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef __u16 UINT2;
+
+/* UINT4 defines a four byte word */
+typedef __u32 UINT4;
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+   If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+     returns an empty list.
+ */
+
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else /* PROTOTYPES */
+#define PROTO_LIST(list) ()
+#endif /* PROTOTYPES */
+
+
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* MD5 context. */
+typedef struct {
+  UINT4 state[4];                                   /* state (ABCD) */
+  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];                         /* input buffer */
+} MD5_CTX;
+
+void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST
+  ((MD5_CTX *, unsigned char *, __u32));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+ 
+#endif /* _IPSEC_MD5H_H_ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.6  1999/12/13 13:59:13  rgb
+ * Quick fix to argument size to Update bugs.
+ *
+ * Revision 1.5  1999/12/07 18:16:23  rgb
+ * Fixed comments at end of #endif lines.
+ *
+ * Revision 1.4  1999/04/06 04:54:26  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.3  1999/01/22 06:19:58  rgb
+ * 64-bit clean-up.
+ *
+ * Revision 1.2  1998/11/30 13:22:54  rgb
+ * Rationalised all the klips kernel file headers.  They are much shorter
+ * now and won't conflict under RH5.2.
+ *
+ * Revision 1.1  1998/06/18 21:27:48  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.2  1998/04/23 20:54:03  rgb
+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
+ * verified.
+ *
+ * Revision 1.1  1998/04/09 03:04:21  henry
+ * sources moved up from linux/net/ipsec
+ * these two include files modified not to include others except in kernel
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:03  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * No changes.
+ *
+ * Revision 0.3  1996/11/20 14:48:53  ji
+ * Release update only.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_netlink.c linux-patched/net/ipsec/ipsec_netlink.c
--- linux/net/ipsec/ipsec_netlink.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_netlink.c	Sun Jan 19 22:32:30 2003
@@ -0,0 +1,710 @@
+/*
+ * IPSEC <> netlink interface
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+char ipsec_netlink_c_version[] = "RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $";
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h> /* printk() */
+
+#include "ipsec_param.h"
+
+#ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+#else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+#endif /* MALLOC_SLAB */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/skbuff.h>
+#include <freeswan.h>
+#ifdef SPINLOCK
+# ifdef SPINLOCK_23
+#  include <linux/spinlock.h> /* *lock* */
+# else /* 23_SPINLOCK */
+#  include <asm/spinlock.h> /* *lock* */
+# endif /* 23_SPINLOCK */
+#endif /* SPINLOCK */
+#ifdef NET_21
+# include <asm/uaccess.h>
+# include <linux/in6.h>
+# define ip_chk_addr inet_addr_type
+# define IS_MYADDR RTN_LOCAL
+#endif
+#include <asm/checksum.h>
+#include <net/ip.h>
+#ifdef NETLINK_SOCK
+# include <linux/netlink.h>
+#else
+# include <net/netlink.h>
+#endif
+
+#include "radij.h"
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+#include "ipsec_netlink.h"
+#include "ipsec_xform.h"
+
+#include "ipsec_rcv.h"
+#include "ipsec_ah.h"
+#include "ipsec_esp.h"
+
+#ifdef CONFIG_IPSEC_DEBUG
+# include "ipsec_tunnel.h"
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#ifdef CONFIG_IPSEC_DEBUG
+ int debug_netlink = 0;
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#define SENDERR(_x) do { len = -(_x); goto errlab; } while (0)
+
+#if 0
+int 
+#ifdef NETLINK_SOCK
+ipsec_callback(int proto, struct sk_buff *skb)
+#else /* NETLINK_SOCK */
+ipsec_callback(struct sk_buff *skb)
+#endif /* NETLINK_SOCK */
+{
+	/*
+	 * this happens when we write to /dev/ipsec (c 36 10)
+	 */
+	int len = skb->len;
+	u_char *dat = (u_char *)skb->data;
+	struct encap_msghdr *em	= (struct encap_msghdr *)dat;
+	struct tdb *tdbp, *tprev;
+	int i, nspis, error = 0;
+#ifdef CONFIG_IPSEC_DEBUG
+	struct eroute *eret;
+	char sa[SATOA_BUF];
+	size_t sa_len;
+	struct sk_buff *first, *last;
+
+
+	sa_len = satoa(em->em_said, 0, sa, SATOA_BUF);
+
+	if(debug_netlink) {
+		printk("klips_debug:ipsec_callback: "
+		       "skb=0x%p skblen=%ld em_magic=%d em_type=%d\n",
+		       skb,
+		       (unsigned long int)skb->len,
+		       em->em_magic,
+		       em->em_type);
+		switch(em->em_type) {
+		case EMT_SETDEBUG:
+			printk("klips_debug:ipsec_callback: "
+			       "set ipsec_debug level\n");
+			break;
+		case EMT_DELEROUTE:
+		case EMT_CLREROUTE:
+		case EMT_CLRSPIS:
+			break;
+		default:
+			printk("klips_debug:ipsec_callback: "
+			       "called for SA:%s\n",
+			       sa_len ? sa : " (error)");
+		}
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	/* XXXX Temporarily disable netlink I/F code until it gets permanantly
+	   ripped out in favour of PF_KEYv2 I/F. */
+	SENDERR(EPROTONOSUPPORT);
+
+	/*	em = (struct encap_msghdr *)dat; */
+	if (em->em_magic != EM_MAGIC) {
+		printk("klips_debug:ipsec_callback: "
+		       "bad magic=%d failed, should be %d\n",
+		       em->em_magic,
+		       EM_MAGIC);
+		SENDERR(EINVAL);
+	}
+	switch (em->em_type) {
+	case EMT_SETDEBUG:
+#ifdef CONFIG_IPSEC_DEBUG
+		if(em->em_db_nl >> (sizeof(em->em_db_nl) * 8 - 1)) {
+			em->em_db_nl &= ~(1 << (sizeof(em->em_db_nl) * 8 -1));
+			debug_tunnel  |= em->em_db_tn;
+			debug_netlink |= em->em_db_nl;
+			debug_xform   |= em->em_db_xf;
+			debug_eroute  |= em->em_db_er;
+			debug_spi     |= em->em_db_sp;
+			debug_radij   |= em->em_db_rj;
+			debug_esp     |= em->em_db_es;
+			debug_ah      |= em->em_db_ah;
+			debug_rcv     |= em->em_db_rx;
+			debug_pfkey   |= em->em_db_ky;
+			if(debug_netlink)
+				printk("klips_debug:ipsec_callback: set\n");
+		} else {
+			if(debug_netlink)
+				printk("klips_debug:ipsec_callback: unset\n");
+			debug_tunnel  &= em->em_db_tn;
+			debug_netlink &= em->em_db_nl;
+			debug_xform   &= em->em_db_xf;
+			debug_eroute  &= em->em_db_er;
+			debug_spi     &= em->em_db_sp;
+			debug_radij   &= em->em_db_rj;
+			debug_esp     &= em->em_db_es;
+			debug_ah      &= em->em_db_ah;
+			debug_rcv     &= em->em_db_rx;
+			debug_pfkey   &= em->em_db_ky;
+		}
+#else /* CONFIG_IPSEC_DEBUG */
+		printk("klips_debug:ipsec_callback: "
+		       "debugging not enabled\n");
+		SENDERR(EINVAL);
+#endif /* CONFIG_IPSEC_DEBUG */
+		break;
+
+	case EMT_SETEROUTE:
+		if ((error = ipsec_makeroute(&(em->em_eaddr), &(em->em_emask), em->em_ersaid, 0, NULL, NULL, NULL)))
+			SENDERR(-error);
+		break;
+
+	case EMT_REPLACEROUTE:
+		if ((error = ipsec_breakroute(&(em->em_eaddr), &(em->em_emask), &first, &last)) == EINVAL) {
+			kfree_skb(first);
+			kfree_skb(last);
+			SENDERR(-error);
+		}
+		if ((error = ipsec_makeroute(&(em->em_eaddr), &(em->em_emask), em->em_ersaid, NULL, NULL)))
+			SENDERR(-error);
+		break;
+
+	case EMT_DELEROUTE:
+		if ((error = ipsec_breakroute(&(em->em_eaddr), &(em->em_emask), &first, &last)))
+			kfree_skb(first);
+			kfree_skb(last);
+			SENDERR(-error);
+		break;
+
+	case EMT_CLREROUTE:
+		if ((error = ipsec_cleareroutes()))
+			SENDERR(-error);
+		break;
+
+	case EMT_SETSPI:
+		if (em->em_if >= 5)	/* XXX -- why 5? */
+			SENDERR(ENODEV);
+		
+		tdbp = gettdb(&(em->em_said));
+		if (tdbp == NULL) {
+			tdbp = (struct tdb *)kmalloc(sizeof (*tdbp), GFP_ATOMIC);
+
+			if (tdbp == NULL)
+				SENDERR(ENOBUFS);
+			
+			memset((caddr_t)tdbp, 0, sizeof(*tdbp));
+			
+			tdbp->tdb_said = em->em_said;
+			tdbp->tdb_flags = em->em_flags;
+			
+			if(ip_chk_addr((unsigned long)em->em_said.dst.s_addr) == IS_MYADDR) {
+				tdbp->tdb_flags |= EMT_INBOUND;
+			}
+			KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
+				    "klips_debug:ipsec_callback: "
+				    "existing Tunnel Descriptor Block not found (this is good) for SA: %s, %s-bound, allocating.\n",
+				    sa_len ? sa : " (error)",
+				    (tdbp->tdb_flags & EMT_INBOUND) ? "in" : "out");
+
+/* XXX  		tdbp->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/
+			tdbp->tdb_rcvif = NULL;
+		} else {
+			KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
+				    "klips_debug:ipsec_callback: "
+				    "EMT_SETSPI found an old Tunnel Descriptor Block for SA: %s, delete it first.\n",
+				    sa_len ? sa : " (error)");
+			SENDERR(EEXIST);
+		}
+		
+		if ((error = tdb_init(tdbp, em))) {
+			KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
+				    "klips_debug:ipsec_callback: "
+				    "EMT_SETSPI not successful for SA: %s, deleting.\n",
+				    sa_len ? sa : " (error)");
+			ipsec_tdbwipe(tdbp);
+			
+			SENDERR(-error);
+		}
+
+		tdbp->tdb_lifetime_addtime_c = jiffies/HZ;
+		tdbp->tdb_state = 1;
+		if(!tdbp->tdb_lifetime_allocations_c) {
+			tdbp->tdb_lifetime_allocations_c += 1;
+		}
+
+		puttdb(tdbp);
+		KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
+			    "klips_debug:ipsec_callback: "
+			    "EMT_SETSPI successful for SA: %s\n",
+			    sa_len ? sa : " (error)");
+		break;
+		
+	case EMT_DELSPI:
+		if (em->em_if >= 5)	/* XXX -- why 5? */
+			SENDERR(ENODEV);
+		
+		spin_lock_bh(&tdb_lock);
+		
+		tdbp = gettdb(&(em->em_said));
+		if (tdbp == NULL) {
+			KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
+				    "klips_debug:ipsec_callback: "
+				    "EMT_DELSPI Tunnel Descriptor Block not found for SA%s, could not delete.\n",
+				    sa_len ? sa : " (error)");
+			spin_unlock_bh(&tdb_lock);
+			SENDERR(ENXIO);  /* XXX -- wrong error message... */
+		} else {
+			if((error = deltdbchain(tdbp))) {
+				spin_unlock_bh(&tdb_lock);
+				SENDERR(-error);
+			}
+		}
+		spin_unlock_bh(&tdb_lock);
+
+		break;
+		
+	case EMT_GRPSPIS:
+		nspis = (len - EMT_GRPSPIS_FLEN) / sizeof(em->em_rel[0]);
+		if ((nspis * (sizeof(em->em_rel[0]))) != (len - EMT_GRPSPIS_FLEN)) {
+			printk("klips_debug:ipsec_callback: "
+			       "EMT_GRPSPI message size incorrect, expected nspis(%d)*%d, got %d.\n",
+			       nspis,
+			       sizeof(em->em_rel[0]),
+			       (len - EMT_GRPSPIS_FLEN));
+			SENDERR(EINVAL);
+			break;
+		}
+		
+		spin_lock_bh(&tdb_lock);
+
+		for (i = 0; i < nspis; i++) {
+			KLIPS_PRINT(debug_netlink,
+				    "klips_debug:ipsec_callback: "
+				    "EMT_GRPSPI for SA(%d) %s,\n",
+				    i,
+				    sa_len ? sa : " (error)");
+			if ((tdbp = gettdb(&(em->em_rel[i].emr_said))) == NULL) {
+				KLIPS_PRINT(debug_netlink,
+					    "klips_debug:ipsec_callback: "
+					    "EMT_GRPSPI Tunnel Descriptor Block not found for SA%s, could not group.\n",
+					    sa_len ? sa : " (error)");
+				spin_unlock_bh(&tdb_lock);
+				SENDERR(ENXIO);
+			} else {
+				if(tdbp->tdb_inext || tdbp->tdb_onext) {
+					KLIPS_PRINT(debug_netlink,
+						    "klips_debug:ipsec_callback: "
+						    "EMT_GRPSPI Tunnel Descriptor Block already grouped for SA: %s, can't regroup.\n",
+						    sa_len ? sa : " (error)");
+					spin_unlock_bh(&tdb_lock);
+					SENDERR(EBUSY);
+				}
+				em->em_rel[i].emr_tdb = tdbp;
+			}
+		}
+		tprev = em->em_rel[0].emr_tdb;
+		tprev->tdb_inext = NULL;
+		for (i = 1; i < nspis; i++) {
+			tdbp = em->em_rel[i].emr_tdb;
+			tprev->tdb_onext = tdbp;
+			tdbp->tdb_inext = tprev;
+			tprev = tdbp;
+		}
+		tprev->tdb_onext = NULL;
+
+		spin_unlock_bh(&tdb_lock);
+
+		error = 0;
+		break;
+		
+	case EMT_UNGRPSPIS:
+		if (len != (8 + (sizeof(struct sa_id) + sizeof(struct tdb *)) /* 12 */) ) {
+			printk("klips_debug:ipsec_callback: "
+			       "EMT_UNGRPSPIS message size incorrect, expected %d, got %d.\n",
+			       8 + (sizeof(struct sa_id) + sizeof(struct tdb *)),
+				    len);
+			SENDERR(EINVAL);
+			break;
+		}
+		
+		spin_lock_bh(&tdb_lock);
+
+		if ((tdbp = gettdb(&(em->em_rel[0].emr_said))) == NULL) {
+			KLIPS_PRINT(debug_netlink,
+				    "klips_debug:ipsec_callback: "
+				    "EMT_UGRPSPI Tunnel Descriptor Block not found for SA%s, could not ungroup.\n",
+				    sa_len ? sa : " (error)");
+			spin_unlock_bh(&tdb_lock);
+			SENDERR(ENXIO);
+		}
+		while(tdbp->tdb_onext) {
+			tdbp = tdbp->tdb_onext;
+		}
+		while(tdbp->tdb_inext) {
+			tprev = tdbp;
+			tdbp = tdbp->tdb_inext;
+			tprev->tdb_inext = NULL;
+			tdbp->tdb_onext = NULL;
+		}
+
+		spin_unlock_bh(&tdb_lock);
+
+		break;
+		
+	case EMT_CLRSPIS:
+		KLIPS_PRINT(debug_netlink,
+			    "klips_debug:ipsec_callback: "
+			    "spi clear called.\n");
+		if (em->em_if >= 5)	/* XXX -- why 5? */
+			SENDERR(ENODEV);
+		ipsec_tdbcleanup(0);
+		break;
+	default:
+		KLIPS_PRINT(debug_netlink,
+			    "klips_debug:ipsec_callback: "
+			    "unknown message type\n");
+		SENDERR(EINVAL);
+	}
+ errlab:
+#ifdef NET_21
+	kfree_skb(skb);
+#else /* NET_21 */
+	kfree_skb(skb, FREE_WRITE);
+#endif /* NET_21 */
+	return len;
+}
+#endif
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.3  2003/01/19 22:32:30  ken
+ * X.509 0.9.19 -> 0.9.20
+ *
+ * Revision 1.2  2002/12/12 03:32:07  ken
+ * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.56  2002/01/29 17:17:55  mcr
+ * 	moved include of ipsec_param.h to after include of linux/kernel.h
+ * 	otherwise, it seems that some option that is set in ipsec_param.h
+ * 	screws up something subtle in the include path to kernel.h, and
+ * 	it complains on the snprintf() prototype.
+ *
+ * Revision 1.55  2002/01/29 04:00:51  mcr
+ * 	more excise of kversions.h header.
+ *
+ * Revision 1.54  2001/10/18 04:45:19  rgb
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
+ * lib/freeswan.h version macros moved to lib/kversions.h.
+ * Other compiler directive cleanups.
+ *
+ * Revision 1.53  2001/09/15 16:24:04  rgb
+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
+ *
+ * Revision 1.52  2001/09/14 16:58:36  rgb
+ * Added support for storing the first and last packets through a HOLD.
+ *
+ * Revision 1.51  2001/09/08 21:13:32  rgb
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
+ *
+ * Revision 1.50  2001/07/06 19:49:00  rgb
+ * Renamed EMT_RPLACEROUTE to EMT_REPLACEROUTE for clarity and logical text
+ * searching.
+ *
+ * Revision 1.49  2001/06/14 19:35:08  rgb
+ * Update copyright date.
+ *
+ * Revision 1.48  2001/02/27 22:24:54  rgb
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
+ * Check for satoa() return codes.
+ *
+ * Revision 1.47  2000/11/06 04:32:08  rgb
+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
+ *
+ * Revision 1.46  2000/09/08 19:16:50  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
+ *
+ * Revision 1.45  2000/08/30 05:23:55  rgb
+ * Compiler-define out ipsec_callback() function of ipsec_netlink.c.
+ * Nothing should be using it anyways.
+ *
+ * Revision 1.44  2000/03/16 14:01:26  rgb
+ * Indented headers for readability.
+ *
+ * Revision 1.43  2000/03/16 07:13:04  rgb
+ * Hardcode PF_KEYv2 support.
+ * Disable NET_LINK support.
+ *
+ * Revision 1.42  2000/01/21 06:14:27  rgb
+ * Moved debug message for expected output on set or clear.
+ *
+ * Revision 1.41  1999/12/01 22:14:37  rgb
+ * Added debugging message for bad netlink magic.
+ * Initialise tdb_sastate to MATURE (1).
+ * Added UNGRPSPIS bad length debugging message.
+ *
+ * Revision 1.40  1999/11/23 23:06:25  rgb
+ * Sort out pfkey and freeswan headers, putting them in a library path.
+ *
+ * Revision 1.39  1999/11/18 04:09:18  rgb
+ * Replaced all kernel version macros to shorter, readable form.
+ *
+ * Revision 1.38  1999/11/17 15:53:39  rgb
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
+ * klips/net/ipsec/Makefile.
+ *
+ * Revision 1.37  1999/10/26 13:58:32  rgb
+ * Put spinlock flags variable declaration outside the debug compiler
+ * directive to enable compilation with debug shut off.
+ *
+ * Revision 1.36  1999/10/16 18:24:22  rgb
+ * Initialize lifetime_addtime_c and lifetime_allocations_c.
+ * Clean-up unused cruft.
+ *
+ * Revision 1.35  1999/10/08 18:37:34  rgb
+ * Fix end-of-line spacing to sate whining PHMs.
+ *
+ * Revision 1.34  1999/10/03 18:49:11  rgb
+ * Spinlock fixes for 2.0.xx and 2.3.xx.
+ *
+ * Revision 1.33  1999/10/01 15:44:53  rgb
+ * Move spinlock header include to 2.1> scope.
+ *
+ * Revision 1.32  1999/10/01 00:00:53  rgb
+ * Fix for proper netlink debugging operation.
+ * Added tdb structure locking.
+ * Minor formatting changes.
+ *
+ * Revision 1.31  1999/05/25 21:21:43  rgb
+ * Fix deltdbchain() error return code checking.
+ *
+ * Revision 1.30  1999/05/09 03:25:36  rgb
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
+ *
+ * Revision 1.29  1999/05/08 21:23:27  rgb
+ * Simplify satoa() calling.
+ * Fix error return reporting.
+ * Add casting to silence the 2.2.x compile.
+ *
+ * Revision 1.28  1999/05/05 22:02:31  rgb
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
+ *
+ * Revision 1.27  1999/04/29 15:16:24  rgb
+ * Add pfkey support to debugging.
+ * Change gettdb parameter to a pointer to reduce stack loading and
+ * facilitate
+ * parameter sanity checking.
+ * Add IS_MYADDR support obviating the necessity of doing this in user
+ * space.
+ * Fix undetected bug by moving puttdb in SETSPI until after initialisation
+ * to
+ * prevent tdb usage before it is ready and to save work if it does not
+ * initialise.
+ * Clean up deltdb/wipe code.
+ * Fix undetected bug of returning error as positive value.
+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
+ *
+ * Revision 1.26  1999/04/16 15:39:35  rgb
+ * Fix already fixed unbalanced #endif.
+ *
+ * Revision 1.25  1999/04/15 15:37:24  rgb
+ * Forward check changes from POST1_00 branch.
+ *
+ * Revision 1.21.2.1  1999/04/13 20:30:26  rgb
+ * Add experimental 'getdebug'.
+ *
+ * Revision 1.24  1999/04/11 00:28:58  henry
+ * GPL boilerplate
+ *
+ * Revision 1.23  1999/04/07 17:44:21  rgb
+ * Fix ipsec_callback memory leak, skb not freed after use.
+ *
+ * Revision 1.22  1999/04/06 04:54:26  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.21  1999/02/17 16:50:11  rgb
+ * Consolidate satoa()s for space and speed efficiency.
+ * Convert DEBUG_IPSEC to KLIPS_PRINT
+ * Clean out unused cruft.
+ *
+ * Revision 1.20  1999/01/28 23:20:49  rgb
+ * Replace hard-coded numbers in macros and code with meaningful values
+ * automatically generated from sizeof() and offsetof() to further the
+ * goal of platform independance.
+ *
+ * Revision 1.19  1999/01/26 02:07:07  rgb
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
+ * Remove ah/esp switching on include files.
+ * Removed dead code.
+ *
+ * Revision 1.18  1999/01/22 06:20:36  rgb
+ * Cruft clean-out.
+ * 64-bit clean-up.
+ * Added algorithm switch code.
+ *
+ * Revision 1.17  1998/12/02 03:09:39  rgb
+ * Clean up debug printing conditionals to compile with debugging off.
+ *
+ * Revision 1.16  1998/12/01 05:56:57  rgb
+ * Add support for debug printing of version info.
+ * Fail on unknown error for breakroute in replace command.
+ *
+ * Revision 1.15  1998/11/30 13:22:54  rgb
+ * Rationalised all the klips kernel file headers.  They are much shorter
+ * now and won't conflict under RH5.2.
+ *
+ * Revision 1.14  1998/11/10 05:36:14  rgb
+ * Clean up debug output.
+ * Add direction to spi setup debug code.
+ * Add support for SA direction flag.
+ *
+ * Revision 1.13  1998/10/31 06:51:56  rgb
+ * Get zeroize to return something useful.
+ * Clean up code to isolate 'spi --add/del' memory leak.
+ * Fixed up comments in #endif directives.
+ *
+ * Revision 1.12  1998/10/27 00:35:02  rgb
+ * Supressed debug output during normal operation.
+ *
+ * Revision 1.11  1998/10/25 02:40:21  rgb
+ * Selective debug printing, depending upon called service.
+ * Institute more precise error return codes from eroute commands.
+ * Fix bug in size of stucture passed in from user space for grpspi command.
+ *
+ * Revision 1.10  1998/10/22 06:44:58  rgb
+ * Convert to use satoa for printk.
+ * Moved break; in 'set debug level code to avoid undetected bug.
+ * Fixed run-on error message to fit 80 columns.
+ *
+ * Revision 1.9  1998/10/19 14:44:28  rgb
+ * Added inclusion of freeswan.h.
+ * sa_id structure implemented and used: now includes protocol.
+ *
+ * Revision 1.8  1998/10/09 04:29:51  rgb
+ * Added support for '-replace' option to eroute.
+ * Fixed spiungroup bug.
+ * Added 'klips_debug' prefix to all klips printk debug statements.
+ *
+ * Revision 1.7  1998/08/12 00:10:06  rgb
+ * Fixed minor error return code syntax.
+ *
+ * Revision 1.6  1998/07/29 20:22:57  rgb
+ * Cosmetic cleanup.
+ *
+ * Revision 1.5  1998/07/27 21:53:11  rgb
+ * Check for proper return code from eroute clear command.
+ * Use appropriate error return codes from kernel.
+ * Add an option to clear the SA table.
+ *
+ * Revision 1.4  1998/07/14 18:02:40  rgb
+ * Add a command to clear the eroute table.
+ * Clean up some error codes.
+ *
+ * Revision 1.3  1998/06/25 19:52:33  rgb
+ * Code cosmetic changes only.
+ *
+ * Revision 1.2  1998/06/23 02:57:58  rgb
+ * Clean up after an error condition in setspi.
+ *
+ * Revision 1.9  1998/06/18 21:29:06  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
+ * build scripts happier in presence of symbolic links
+ *
+ * Revision 1.8  1998/06/08 17:57:15  rgb
+ * Very minor spacing change.
+ *
+ * Revision 1.7  1998/05/18 21:46:45  rgb
+ * Clean up for numerical consistency of output.
+ *
+ * Added debugging switch output.
+ *
+ * SETSPI will refuse to overwrite a previous SA.  This is to make it
+ * consistent with the eroute command.
+ *
+ * spidel now deletes entire chain of spi's.
+ *
+ * spigrp can now ungroup a set of spi's.
+ *
+ * spigrp will not regroup a previously grouped spi.
+ *
+ * Key data is properly cleaned up, ie. zeroed.
+ *
+ * Revision 1.6  1998/05/07 20:36:27  rgb
+ * Fixed case where debugging not enabled that caused ipsec_netlink.c to
+ * not compile.
+ *
+ * Revision 1.5  1998/05/06 03:34:21  rgb
+ * Updated debugging output statements.
+ *
+ * Revision 1.4  1998/04/23 21:03:59  rgb
+ * Completed kernel development for userspace access to klips kernel debugging
+ * switches.
+ * Added detail to the kernel error message when trying to group non-existant
+ * spi's.
+ *
+ * Revision 1.3  1998/04/21 21:29:06  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.2  1998/04/12 22:03:23  rgb
+ * Updated ESP-3DES-HMAC-MD5-96,
+ * 	ESP-DES-HMAC-MD5-96,
+ * 	AH-HMAC-MD5-96,
+ * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
+ *
+ * Fixed eroute references in /proc/net/ipsec*.
+ *
+ * Started to patch module unloading memory leaks in ipsec_netlink and
+ * radij tree unloading.
+ *
+ * Revision 1.1  1998/04/09 03:06:08  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:02  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * No changes.
+ *
+ * Revision 0.3  1996/11/20 14:39:04  ji
+ * Minor cleanups.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_netlink.h linux-patched/net/ipsec/ipsec_netlink.h
--- linux/net/ipsec/ipsec_netlink.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_netlink.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,345 @@
+/*
+ * IPSEC <> netlink interface
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+#include <linux/stddef.h>
+
+#ifndef NETLINK_IPSEC
+#define NETLINK_IPSEC          10      /* IPSEC */ 
+#endif /* !NETLINK_IPSEC */
+
+#define EM_MAXRELSPIS	4		/* at most five chained xforms */
+#define EM_MAGIC	0x5377616e	/* "Swan" */
+
+#define EMT_IFADDR	1	/* set enc if addr */
+#define EMT_SETSPI	2	/* Set SPI properties */
+#define EMT_DELSPI	3	/* Delete an SPI */
+#define EMT_GRPSPIS	4	/* Group SPIs (output order)  */
+#define EMT_SETEROUTE	5	/* set an extended route */
+#define EMT_DELEROUTE	6	/* del an extended route */
+#define EMT_TESTROUTE	7	/* try to find route, print to console */
+#define EMT_SETDEBUG	8	/* set debug level if active */
+#define EMT_UNGRPSPIS	9	/* UnGroup SPIs (output order)  */
+#define EMT_CLREROUTE	10	/* clear the extended route table */
+#define EMT_CLRSPIS	11	/* clear the spi table */
+#define EMT_REPLACEROUTE	12	/* set an extended route */
+#define EMT_GETDEBUG	13	/* get debug level if active */
+#define EMT_INEROUTE	14	/* set incoming policy for IPIP on a chain */
+
+#ifdef CONFIG_IPSEC_DEBUG
+#define DB_NL_TDBCB	0x0001
+#endif /* CONFIG_IPSEC_DEBUG */
+
+/* em_flags constants */
+/* be mindful that this flag conflicts with SADB_SAFLAGS_PFS in pfkeyv2 */
+/* perhaps it should be moved... */
+#define EMT_INBOUND	0x01	/* SA direction, 1=inbound */
+
+struct encap_msghdr
+{
+	__u32	em_magic;		/* EM_MAGIC */
+#if 0
+	__u16	em_msglen;		/* message length */
+#endif
+	__u8	em_msglen;		/* message length */
+	__u8	em_flags;		/* message flags */
+	__u8	em_version;		/* for future expansion */
+	__u8	em_type;		/* message type */
+	union
+	{
+		__u8	C;		/* Free-text */
+		
+		struct 
+		{
+			struct sa_id Said; /* SA ID */
+			struct sockaddr_encap Eaddr;
+			struct sockaddr_encap Emask;
+		} Ert;
+
+		struct
+		{
+			struct in_addr Ia;
+			__u8	Ifn;
+			__u8  xxx[3];	/* makes life a lot easier */
+		} Ifa;
+
+		struct
+		{
+			struct sa_id Said; /* SA ID */
+			int If;		/* enc i/f for input */
+			int Alg;	/* Algorithm to use */
+
+                        /* The following union is a surrogate for
+                         * algorithm-specific data.  To insure
+                         * proper alignment, worst-case fields
+                         * should be included.  It would be even
+                         * better to include the types that will
+                         * actually be used, but they may not be
+                         * defined for each use of this header.
+                         * The actual length is expected to be longer
+                         * than is declared here.  References are normally
+                         * made using the em_dat macro, as if it were a
+                         * field name.
+                         */
+                        union { /* Data */
+                                __u8 Dat[1];
+                                __u64 Datq[1];  /* maximal alignment (?) */
+                        } u;
+		} Xfm;
+		
+		struct
+		{
+			struct sa_id emr_said; /* SA ID */
+			struct ipsec_sa * emr_tdb; /* used internally! */
+			
+		} Rel[EM_MAXRELSPIS];
+		
+#ifdef CONFIG_IPSEC_DEBUG
+		struct
+		{
+			int debug_tunnel;
+			int debug_netlink;
+			int debug_xform;
+			int debug_eroute;
+			int debug_spi;
+			int debug_radij;
+			int debug_esp;
+			int debug_ah;
+			int debug_rcv;
+			int debug_pfkey;
+			int debug_ipcomp;
+			int debug_verbose;
+		} Dbg;
+#endif /* CONFIG_IPSEC_DEBUG */
+	} Eu;
+};
+
+#define EM_MINLEN	offsetof(struct encap_msghdr, Eu)
+#define EMT_SETSPI_FLEN	offsetof(struct encap_msghdr, em_dat)
+#define EMT_GRPSPIS_FLEN offsetof(struct encap_msghdr, Eu.Rel)
+#define EMT_SETDEBUG_FLEN (offsetof(struct encap_msghdr, Eu.Dbg + \
+			sizeof(((struct encap_msghdr*)0)->Eu.Dbg)))
+
+#define em_c	Eu.C
+#define em_eaddr Eu.Ert.Eaddr
+#define em_emask Eu.Ert.Emask
+#define em_ersaid Eu.Ert.Said
+#define em_erdst Eu.Ert.Said.dst
+#define em_erspi Eu.Ert.Said.spi
+#define em_erproto Eu.Ert.Said.proto
+
+#define em_ifa	Eu.Ifa.Ia
+#define em_ifn	Eu.Ifa.Ifn
+
+#define em_said	Eu.Xfm.Said
+#define em_spi	Eu.Xfm.Said.spi
+#define em_dst	Eu.Xfm.Said.dst
+#define em_proto	Eu.Xfm.Said.proto
+#define em_if	Eu.Xfm.If
+#define em_alg	Eu.Xfm.Alg
+#define em_dat	Eu.Xfm.u.Dat
+
+#define em_rel	Eu.Rel
+#define emr_dst emr_said.dst
+#define emr_spi emr_said.spi
+#define emr_proto emr_said.proto
+
+#ifdef CONFIG_IPSEC_DEBUG
+#define em_db_tn Eu.Dbg.debug_tunnel
+#define em_db_nl Eu.Dbg.debug_netlink
+#define em_db_xf Eu.Dbg.debug_xform
+#define em_db_er Eu.Dbg.debug_eroute
+#define em_db_sp Eu.Dbg.debug_spi
+#define em_db_rj Eu.Dbg.debug_radij
+#define em_db_es Eu.Dbg.debug_esp
+#define em_db_ah Eu.Dbg.debug_ah
+#define em_db_rx Eu.Dbg.debug_rcv
+#define em_db_ky Eu.Dbg.debug_pfkey
+#define em_db_gz Eu.Dbg.debug_ipcomp
+#define em_db_vb Eu.Dbg.debug_verbose
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#ifdef __KERNEL__
+extern char ipsec_netlink_c_version[];
+#ifndef KERNEL_VERSION
+#  include <linux/version.h>
+#endif
+#ifdef NETLINK_SOCK
+extern int ipsec_callback(int proto, struct sk_buff *skb);
+#else /* NETLINK_SOCK */
+extern int ipsec_callback(struct sk_buff *skb);
+#endif /* NETLINK_SOCK */
+extern void ipsec_print_ip(struct iphdr *ip);
+
+#ifdef CONFIG_IPSEC_DEBUG
+	#define KLIPS_PRINT(flag, format, args...) \
+		((flag) ? printk(KERN_INFO format , ## args) : 0)
+	#define KLIPS_PRINTMORE(flag, format, args...) \
+		((flag) ? printk(format , ## args) : 0)
+	#define KLIPS_IP_PRINT(flag, ip) \
+		((flag) ? ipsec_print_ip(ip) : 0)
+#else /* CONFIG_IPSEC_DEBUG */
+	#define KLIPS_PRINT(flag, format, args...) do ; while(0)
+	#define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
+	#define KLIPS_IP_PRINT(flag, ip) do ; while(0)
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#ifdef CONFIG_IPSEC_DEBUG
+extern int debug_netlink;
+#endif /* CONFIG_IPSEC_DEBUG */
+#endif /* __KERNEL__ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.31  2001/11/26 09:23:48  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.30  2001/07/06 19:49:16  rgb
+ * Renamed EMT_RPLACEROUTE to EMT_REPLACEROUTE for clarity and logical text
+ * searching.
+ * Added EMT_INEROUTE for supporting incoming policy checks.
+ *
+ * Revision 1.29  2001/06/14 19:35:09  rgb
+ * Update copyright date.
+ *
+ * Revision 1.28  2000/10/10 20:10:18  rgb
+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
+ *
+ * Revision 1.27  2000/09/12 03:20:28  rgb
+ * Cleared out now unused pfkeyv2 switch.
+ *
+ * Revision 1.26  2000/09/08 19:16:50  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
+ *
+ * Revision 1.25  2000/08/24 16:51:59  rgb
+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
+ * info.
+ *
+ * Revision 1.24  2000/08/09 20:43:34  rgb
+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
+ *
+ * Revision 1.23  2000/03/16 14:01:48  rgb
+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
+ *
+ * Revision 1.22  1999/12/08 20:31:32  rgb
+ * Moved IPPROTO_COMP to lib/freeswan.h to simplify userspace includes.
+ *
+ * Revision 1.21  1999/11/18 18:47:41  rgb
+ * Added "#define NETLINK_IPSEC" in case kernel was not compiled with it.
+ *
+ * Revision 1.20  1999/11/18 04:09:18  rgb
+ * Replaced all kernel version macros to shorter, readable form.
+ *
+ * Revision 1.19  1999/08/28 08:27:05  rgb
+ * Add a temporary kludge for 2.0.37-38 to compile even if one patch failed.
+ *
+ * Revision 1.18  1999/08/03 17:09:33  rgb
+ * Tidy up debug output, use KERN_INFO macro in printk's.
+ *
+ * Revision 1.17  1999/05/25 01:45:37  rgb
+ * Fix version macros for 2.0.x as a module.
+ *
+ * Revision 1.16  1999/05/05 22:02:31  rgb
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
+ *
+ * Revision 1.15  1999/04/29 15:16:55  rgb
+ * Add pfkey support to debugging.
+ *
+ * Revision 1.14  1999/04/15 15:37:24  rgb
+ * Forward check changes from POST1_00 branch.
+ *
+ * Revision 1.13  1999/04/11 00:28:58  henry
+ * GPL boilerplate
+ *
+ * Revision 1.12  1999/04/06 04:54:26  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.11  1999/02/12 21:13:17  rgb
+ * Moved KLIPS_PRINT into a more accessible place.
+ *
+ * Revision 1.10  1999/01/28 23:20:49  rgb
+ * Replace hard-coded numbers in macros and code with meaningful values
+ * automatically generated from sizeof() and offsetof() to further the
+ * goal of platform independance.
+ *
+ * Revision 1.9  1999/01/22 06:21:23  rgb
+ * Added algorithm switch code.
+ * Cruft clean-out.
+ * 64-bit clean-up.
+ *
+ * Revision 1.8  1998/12/01 05:57:42  rgb
+ * Add support for printing debug version info.
+ *
+ * Revision 1.7  1998/11/10 05:37:35  rgb
+ * Add support for SA direction flag.
+ *
+ * Revision 1.6  1998/10/25 02:40:45  rgb
+ * Fix bug in size of stucture passed in from user space for grpspi command.
+ *
+ * Revision 1.5  1998/10/19 14:44:29  rgb
+ * Added inclusion of freeswan.h.
+ * sa_id structure implemented and used: now includes protocol.
+ *
+ * Revision 1.4  1998/10/09 04:30:11  rgb
+ * Added support for '-replace' option to eroute.
+ *
+ * Revision 1.3  1998/07/27 21:54:22  rgb
+ * Rearrange structures for consistent alignment within a union.
+ * Add an option for clearing SA table.
+ *
+ * Revision 1.2  1998/07/14 18:05:51  rgb
+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
+ *
+ * Revision 1.1  1998/06/18 21:27:49  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.4  1998/05/18 21:48:24  rgb
+ * Added switch for ungrouping spi's.
+ *
+ * Revision 1.3  1998/04/23 21:01:50  rgb
+ * Added a macro for userspace access to klips kernel debugging switches.
+ *
+ * Revision 1.2  1998/04/21 21:29:09  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.1  1998/04/09 03:06:09  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:03  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * No changes.
+ *
+ * Revision 0.3  1996/11/20 14:39:04  ji
+ * Minor cleanups.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_param.h linux-patched/net/ipsec/ipsec_param.h
--- linux/net/ipsec/ipsec_param.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_param.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,150 @@
+/*
+ * @(#) FreeSWAN tunable paramaters
+ *
+ * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
+ *                 and Michael Richardson  <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ */
+
+/* 
+ * This file provides a set of #define's which may be tuned by various
+ * people/configurations. It keeps all compile-time tunables in one place.
+ *
+ * This file should be included before all other IPsec kernel-only files.
+ *
+ */
+
+#ifndef _IPSEC_PARAM_H_
+
+#include "ipsec_kversion.h"
+
+#ifdef CONFIG_IPSEC_BIGGATE
+#define SADB_HASHMOD   8069
+#else
+#define SADB_HASHMOD	257
+#endif
+
+#ifndef PROC_NO_DUMMY
+#define IPSEC_PROC_LAST_ARG , int dummy
+#else
+#define IPSEC_PROC_LAST_ARG
+#endif /* !PROC_NO_DUMMY */
+
+#ifdef NETDEV_23
+
+#define device net_device
+#define ipsec_dev_get __dev_get_by_name
+
+#else
+
+#define ipsec_dev_get dev_get
+
+#endif /* NETDEV_23 */
+
+#ifndef PROC_FS_2325
+#define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
+#else
+#define IPSEC_PROCFS_DEBUG_NO_STATIC
+#endif /* PROC_FS_2325 */
+
+#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
+/* GNU CPP specific! */
+#define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
+#endif
+
+#ifdef SPINLOCK
+ #ifdef SPINLOCK_23
+  #include <linux/spinlock.h> /* *lock* */
+ #else /* SPINLOCK_23 */
+  #include <asm/spinlock.h> /* *lock* */
+ #endif /* SPINLOCK_23 */
+#endif /* SPINLOCK */
+
+#ifndef KLIPS_FIXES_DES_PARITY
+#define KLIPS_FIXES_DES_PARITY 1
+#endif
+
+#ifndef KLIPS_DIVULGE_CYPHER_KEY
+#define KLIPS_DIVULGE_CYPHER_KEY 0
+#endif
+
+/* extra toggles for regression testing */
+#ifdef CONFIG_IPSEC_REGRESS
+
+/* 
+ * should pfkey_acquire() become 100% lossy?
+ *
+ */
+extern int sysctl_ipsec_regress_pfkey_lossage;
+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
+#ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE
+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
+#else
+/* not by default! */
+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
+#endif
+#endif
+
+#endif
+
+/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
+#ifndef IP_FRAGMENT_LINEARIZE
+#define IP_FRAGMENT_LINEARIZE 0
+#endif
+
+#define _IPSEC_PARAM_H_
+#endif
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.6  2002/01/29 02:11:42  mcr
+ * 	removal of kversions.h - sources that needed it now use ipsec_param.h.
+ * 	updating of IPv6 structures to match latest in6.h version.
+ * 	removed dead code from freeswan.h that also duplicated kversions.h
+ * 	code.
+ *
+ * Revision 1.5  2002/01/28 19:22:01  mcr
+ * 	by default, turn off LINEARIZE option
+ * 	(let kversions.h turn it on)
+ *
+ * Revision 1.4  2002/01/20 20:19:36  mcr
+ * 	renamed option to IP_FRAGMENT_LINEARIZE.
+ *
+ * Revision 1.3  2002/01/12 02:57:25  mcr
+ * 	first regression test causes acquire messages to be lost
+ * 	100% of the time. This is to help testing of pluto.
+ *
+ * Revision 1.2  2001/11/26 09:16:14  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.3  2001/10/23 04:40:16  mcr
+ * 	added #define for DIVULGING session keys in debug output.
+ *
+ * Revision 1.1.2.2  2001/10/22 20:53:25  mcr
+ * 	added a define to control forcing of DES parity.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:20:19  mcr
+ * 	many common kernel configuration questions centralized.
+ * 	more things remain that should be moved from freeswan.h.
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_proc.c linux-patched/net/ipsec/ipsec_proc.c
--- linux/net/ipsec/ipsec_proc.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_proc.c	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,765 @@
+/*
+ * @(#) /proc file system interface code.
+ *
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
+ *                                 2001  Michael Richardson <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * Split out from ipsec_init.c version 1.70.
+ */
+
+char ipsec_proc_c_version[] = "RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $";
+
+#include <linux/config.h>
+#include <linux/version.h>
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/kernel.h> /* printk() */
+
+#include "ipsec_param.h"
+
+#ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+#else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+#endif /* MALLOC_SLAB */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/in.h>          /* struct sockaddr_in */
+#include <linux/skbuff.h>
+#include <freeswan.h>
+#ifdef SPINLOCK
+#ifdef SPINLOCK_23
+#include <linux/spinlock.h> /* *lock* */
+#else /* SPINLOCK_23 */
+#include <asm/spinlock.h> /* *lock* */
+#endif /* SPINLOCK_23 */
+#endif /* SPINLOCK */
+#ifdef NET_21
+#include <asm/uaccess.h>
+#include <linux/in6.h>
+#endif /* NET_21 */
+#include <asm/checksum.h>
+#include <net/ip.h>
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif /* CONFIG_PROC_FS */
+#ifdef NETLINK_SOCK
+#include <linux/netlink.h>
+#else
+#include <net/netlink.h>
+#endif
+
+#include "radij.h"
+
+#include "ipsec_life.h"
+#include "ipsec_stats.h"
+#include "ipsec_sa.h"
+
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+#include "ipsec_netlink.h"
+#include "ipsec_xform.h"
+#include "ipsec_tunnel.h"
+
+#include "ipsec_rcv.h"
+#include "ipsec_ah.h"
+#include "ipsec_esp.h"
+
+#ifdef CONFIG_IPSEC_IPCOMP
+#include "ipcomp.h"
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+#include "ipsec_proto.h"
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#ifdef CONFIG_PROC_FS
+
+#if 0
+static struct proc_dir_entry *proc_net_ipsec_dir;
+#endif
+
+IPSEC_PROCFS_DEBUG_NO_STATIC
+int
+ipsec_eroute_get_info(char *buffer, 
+		      char **start, 
+		      off_t offset, 
+		      int length        IPSEC_PROC_LAST_ARG)
+{
+	struct wsbuf w = {buffer, length, offset, 0, 0, 0, 0};
+
+#ifdef CONFIG_IPSEC_DEBUG
+	if (debug_radij & DB_RJ_DUMPTREES)
+	  rj_dumptrees();			/* XXXXXXXXX */
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_eroute_get_info: "
+		    "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
+		    buffer,
+		    (u_int)*start,
+		    (int)offset,
+		    length);
+
+	spin_lock_bh(&eroute_lock);
+
+	rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
+/*	rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
+
+	spin_unlock_bh(&eroute_lock);
+
+	*start = buffer + (offset - w.begin);	/* Start of wanted data */
+	w.len -= (offset - w.begin);			/* Start slop */
+	if (w.len > length)
+		w.len = length;
+	return w.len;
+}
+
+IPSEC_PROCFS_DEBUG_NO_STATIC
+int
+ipsec_spi_get_info(char *buffer,
+		   char **start,
+		   off_t offset,
+		   int length    IPSEC_PROC_LAST_ARG)
+{
+	int len = 0;
+	off_t pos = 0, begin = 0;
+	int i;
+	struct ipsec_sa *sa_p;
+	char sa[SATOA_BUF];
+	char buf_s[SUBNETTOA_BUF];
+	char buf_d[SUBNETTOA_BUF];
+	size_t sa_len;
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_spi_get_info: "
+		    "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
+		    buffer,
+		    (u_int)*start,
+		    (int)offset,
+		    length);
+	
+	spin_lock_bh(&tdb_lock);
+
+
+	
+	for (i = 0; i < SADB_HASHMOD; i++) {
+		for (sa_p = ipsec_sadb_hash[i];
+		     sa_p;
+		     sa_p = sa_p->ips_hnext) {
+			sa_len = satoa(sa_p->ips_said, 0, sa, SATOA_BUF);
+			len += sprintf(buffer + len, "%s ",
+				       sa_len ? sa : " (error)");
+
+			len += sprintf(buffer + len, "%s%s%s",
+				       IPS_XFORM_NAME(sa_p));
+
+			len += sprintf(buffer + len, ": dir=%s",
+				       (sa_p->ips_flags & EMT_INBOUND) ?
+				       "in " : "out");
+
+			if(sa_p->ips_addr_s) {
+				addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
+					0, buf_s, sizeof(buf_s));
+				len += sprintf(buffer + len, " src=%s",
+					       buf_s);
+			}
+
+			if((sa_p->ips_said.proto == IPPROTO_IPIP)
+			   && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
+				subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
+					  sa_p->ips_mask_s.u.v4.sin_addr,
+					  0,
+					  buf_s,
+					  sizeof(buf_s));
+
+				subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
+					  sa_p->ips_mask_d.u.v4.sin_addr,
+					  0,
+					  buf_d,
+					  sizeof(buf_d));
+
+				len += sprintf(buffer + len, " policy=%s->%s",
+					       buf_s, buf_d);
+			}
+			
+			if(sa_p->ips_iv_bits) {
+				int j;
+				len += sprintf(buffer + len, " iv_bits=%dbits iv=0x",
+					       sa_p->ips_iv_bits);
+
+				for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
+					len += sprintf(buffer + len, "%02x",
+						       (__u32)((__u8*)(sa_p->ips_iv))[j]);
+				}
+			}
+
+			if(sa_p->ips_encalg || sa_p->ips_authalg) {
+				if(sa_p->ips_replaywin) {
+					len += sprintf(buffer + len, " ooowin=%d",
+						       sa_p->ips_replaywin);
+				}
+				if(sa_p->ips_errs.ips_replaywin_errs) {
+					len += sprintf(buffer + len, " ooo_errs=%d",
+						       sa_p->ips_errs.ips_replaywin_errs);
+				}
+				if(sa_p->ips_replaywin_lastseq) {
+                                       len += sprintf(buffer + len, " seq=%d",
+						      sa_p->ips_replaywin_lastseq);
+				}
+				if(sa_p->ips_replaywin_bitmap) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+					len += sprintf(buffer + len, " bit=0x%Lx",
+						       sa_p->ips_replaywin_bitmap);
+#else
+					len += sprintf(buffer + len, " bit=0x%x%08x",
+						       (__u32)(sa_p->ips_replaywin_bitmap >> 32),
+						       (__u32)sa_p->ips_replaywin_bitmap);
+#endif
+				}
+				if(sa_p->ips_replaywin_maxdiff) {
+					len += sprintf(buffer + len, " max_seq_diff=%d",
+						       sa_p->ips_replaywin_maxdiff);
+				}
+			}
+			if(sa_p->ips_flags & ~EMT_INBOUND) {
+				len += sprintf(buffer + len, " flags=0x%x",
+					       sa_p->ips_flags & ~EMT_INBOUND);
+				len += sprintf(buffer + len, "<");
+				/* flag printing goes here */
+				len += sprintf(buffer + len, ">");
+			}
+			if(sa_p->ips_auth_bits) {
+				len += sprintf(buffer + len, " alen=%d",
+					       sa_p->ips_auth_bits);
+			}
+			if(sa_p->ips_key_bits_a) {
+				len += sprintf(buffer + len, " aklen=%d",
+					       sa_p->ips_key_bits_a);
+			}
+			if(sa_p->ips_errs.ips_auth_errs) {
+				len += sprintf(buffer + len, " auth_errs=%d",
+					       sa_p->ips_errs.ips_auth_errs);
+			}
+			if(sa_p->ips_key_bits_e) {
+				len += sprintf(buffer + len, " eklen=%d",
+					       sa_p->ips_key_bits_e);
+			}
+			if(sa_p->ips_errs.ips_encsize_errs) {
+				len += sprintf(buffer + len, " encr_size_errs=%d",
+					       sa_p->ips_errs.ips_encsize_errs);
+			}
+			if(sa_p->ips_errs.ips_encpad_errs) {
+				len += sprintf(buffer + len, " encr_pad_errs=%d",
+					       sa_p->ips_errs.ips_encpad_errs);
+			}
+			
+			len += sprintf(buffer + len, " life(c,s,h)=");
+
+			len += ipsec_lifetime_format(buffer + len,
+						     length - len,
+						     "alloc", 
+						     ipsec_life_countbased,
+						     &sa_p->ips_life.ipl_allocations);
+
+			len += ipsec_lifetime_format(buffer + len,
+						     length - len,
+						     "bytes",
+						     ipsec_life_countbased,
+						     &sa_p->ips_life.ipl_bytes);
+
+			len += ipsec_lifetime_format(buffer + len,
+						     length - len,
+						     "addtime",
+						     ipsec_life_timebased,
+						     &sa_p->ips_life.ipl_addtime);
+
+			len += ipsec_lifetime_format(buffer + len,
+						     length - len,
+						     "usetime",
+						     ipsec_life_timebased,
+						     &sa_p->ips_life.ipl_usetime);
+			
+			len += ipsec_lifetime_format(buffer + len,
+						     length - len,
+						     "packets",
+						     ipsec_life_countbased,
+						     &sa_p->ips_life.ipl_packets);
+			
+			if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+				len += sprintf(buffer + len, " idle=%Ld",
+					       jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
+#else
+				len += sprintf(buffer + len, " idle=%lu",
+					       jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
+#endif
+			}
+
+#ifdef CONFIG_IPSEC_IPCOMP
+			if(sa_p->ips_said.proto == IPPROTO_COMP &&
+			   (sa_p->ips_comp_ratio_dbytes ||
+			    sa_p->ips_comp_ratio_cbytes)) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+				len += sprintf(buffer + len, " ratio=%Ld:%Ld",
+					       sa_p->ips_comp_ratio_dbytes,
+					       sa_p->ips_comp_ratio_cbytes);
+#else
+				len += sprintf(buffer + len, " ratio=%lu:%lu",
+					       (unsigned long)sa_p->ips_comp_ratio_dbytes,
+					       (unsigned long)sa_p->ips_comp_ratio_cbytes);
+#endif
+			}
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+			len += sprintf(buffer + len, "\n");
+
+			pos = begin + len;
+			if(pos < offset) {
+				len = 0;
+				begin = pos;
+			}
+			if (pos > offset + length) {
+				goto done_spi_i;
+			}
+		}
+	}
+
+ done_spi_i:	
+	spin_unlock_bh(&tdb_lock);
+
+	*start = buffer + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin);			/* Start slop */
+	if (len > length)
+		len = length;
+	return len;
+}
+
+IPSEC_PROCFS_DEBUG_NO_STATIC
+int
+ipsec_spigrp_get_info(char *buffer,
+		      char **start,
+		      off_t offset,
+		      int length     IPSEC_PROC_LAST_ARG)
+{
+	int len = 0;
+	off_t pos = 0, begin = 0;
+	int i;
+	struct ipsec_sa *sa_p, *sa_p2;
+	char sa[SATOA_BUF];
+	size_t sa_len;
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_spigrp_get_info: "
+		    "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
+		    buffer,
+		    (u_int)*start,
+		    (int)offset,
+		    length);
+
+	spin_lock_bh(&tdb_lock);
+	
+	for (i = 0; i < SADB_HASHMOD; i++) {
+		for (sa_p = ipsec_sadb_hash[i];
+		     sa_p;
+		     sa_p = sa_p->ips_hnext)
+		{
+			if(!sa_p->ips_inext)
+			{
+				sa_p2 = sa_p;
+				while(sa_p2) {
+					sa_len = satoa(sa_p2->ips_said,
+						       0, sa, SATOA_BUF);
+					
+					len += sprintf(buffer + len, "%s ",
+						       sa_len ? sa : " (error)");
+					sa_p2 = sa_p2->ips_onext;
+				}
+				len += sprintf(buffer + len, "\n");
+				pos = begin + len;
+				if(pos < offset) {
+					len = 0;
+					begin = pos;
+				}
+				if (pos > offset + length) {
+					goto done_spigrp_i;
+				}
+			}
+		}
+	}
+
+ done_spigrp_i:	
+	spin_unlock_bh(&tdb_lock);
+
+	*start = buffer + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin);			/* Start slop */
+	if (len > length)
+		len = length;
+	return len;
+}
+
+IPSEC_PROCFS_DEBUG_NO_STATIC
+int
+ipsec_tncfg_get_info(char *buffer,
+		     char **start,
+		     off_t offset,
+		     int length     IPSEC_PROC_LAST_ARG)
+{
+	int len = 0;
+	off_t pos = 0, begin = 0;
+	int i;
+	char name[9];
+	struct device *dev, *privdev;
+	struct ipsecpriv *priv;
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_tncfg_get_info: "
+		    "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
+		    buffer,
+		    (u_int)*start,
+		    (int)offset,
+		    length);
+
+	for(i = 0; i < IPSEC_NUM_IF; i++) {
+		sprintf(name, "ipsec%d", i);
+		dev = ipsec_dev_get(name);
+		if(dev) {
+			priv = (struct ipsecpriv *)(dev->priv);
+			len += sprintf(buffer + len, "%s",
+				       dev->name);
+			if(priv) {
+				privdev = (struct device *)(priv->dev);
+				len += sprintf(buffer + len, " -> %s",
+					       privdev ? privdev->name : "NULL");
+				len += sprintf(buffer + len, " mtu=%d(%d) -> %d",
+					       dev->mtu,
+					       priv->mtu,
+					       privdev ? privdev->mtu : 0);
+			} else {
+				KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+					    "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
+					    dev->name);
+			}
+			len += sprintf(buffer + len, "\n");
+
+			pos = begin + len;
+			if(pos < offset) {
+				len = 0;
+				begin = pos;
+			}
+			else if (pos > offset + length)	{
+				break;
+			}
+		}
+	}
+	*start = buffer + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin);			/* Start slop */
+	if (len > length)
+		len = length;
+	return len;
+}
+
+IPSEC_PROCFS_DEBUG_NO_STATIC
+int
+ipsec_version_get_info(char *buffer,
+		       char **start,
+		       off_t offset,
+		       int length  IPSEC_PROC_LAST_ARG)
+{
+	int len = 0;
+	off_t begin = 0;
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_version_get_info: "
+		    "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
+		    buffer,
+		    (u_int)*start,
+		    (int)offset,
+		    length);
+
+	len += sprintf(buffer + len, "FreeS/WAN version: %s\n",
+		       ipsec_version_code());
+#if 0
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_version_get_info: "
+		    "ipsec_init version: %s\n",
+		    ipsec_init_c_version);
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_version_get_info: "
+		    "ipsec_tunnel version: %s\n",
+		    ipsec_tunnel_c_version);
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_version_get_info: "
+		    "ipsec_netlink version: %s\n",
+		    ipsec_netlink_c_version);
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_version_get_info: "
+		    "radij_c_version: %s\n",
+		    radij_c_version);
+#endif
+
+	*start = buffer + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin);			/* Start slop */
+	if (len > length)
+		len = length;
+	return len;
+}
+
+#ifdef CONFIG_IPSEC_DEBUG
+IPSEC_PROCFS_DEBUG_NO_STATIC
+int
+ipsec_klipsdebug_get_info(char *buffer,
+			  char **start,
+			  off_t offset,
+			  int length      IPSEC_PROC_LAST_ARG)
+{
+	int len = 0;
+	off_t begin = 0;
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
+		    "klips_debug:ipsec_klipsdebug_get_info: "
+		    "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
+		    buffer,
+		    (u_int)*start,
+		    (int)offset,
+		    length);
+
+	len += sprintf(buffer + len, "debug_tunnel=%08x.\n", debug_tunnel);
+	len += sprintf(buffer + len, "debug_netlink=%08x.\n", debug_netlink);
+	len += sprintf(buffer + len, "debug_xform=%08x.\n", debug_xform);
+	len += sprintf(buffer + len, "debug_eroute=%08x.\n", debug_eroute);
+	len += sprintf(buffer + len, "debug_spi=%08x.\n", debug_spi);
+	len += sprintf(buffer + len, "debug_radij=%08x.\n", debug_radij);
+	len += sprintf(buffer + len, "debug_esp=%08x.\n", debug_esp);
+	len += sprintf(buffer + len, "debug_ah=%08x.\n", debug_ah);
+	len += sprintf(buffer + len, "debug_rcv=%08x.\n", debug_rcv);
+	len += sprintf(buffer + len, "debug_pfkey=%08x.\n", debug_pfkey);
+
+	*start = buffer + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin);			/* Start slop */
+	if (len > length)
+		len = length;
+	return len;
+}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#ifndef PROC_FS_2325
+struct proc_dir_entry ipsec_eroute =
+{
+	0,
+	12, "ipsec_eroute",
+	S_IFREG | S_IRUGO, 1, 0, 0, 0,
+	&proc_net_inode_operations,
+	ipsec_eroute_get_info,
+	NULL, NULL, NULL, NULL, NULL
+};
+
+struct proc_dir_entry ipsec_spi =
+{
+	0,
+	9, "ipsec_spi",
+	S_IFREG | S_IRUGO, 1, 0, 0, 0,
+	&proc_net_inode_operations,
+	ipsec_spi_get_info,
+	NULL, NULL, NULL, NULL, NULL
+};
+
+struct proc_dir_entry ipsec_spigrp =
+{
+	0,
+	12, "ipsec_spigrp",
+	S_IFREG | S_IRUGO, 1, 0, 0, 0,
+	&proc_net_inode_operations,
+	ipsec_spigrp_get_info,
+	NULL, NULL, NULL, NULL, NULL
+};
+
+struct proc_dir_entry ipsec_tncfg =
+{
+	0,
+	11, "ipsec_tncfg",
+	S_IFREG | S_IRUGO, 1, 0, 0, 0,
+	&proc_net_inode_operations,
+	ipsec_tncfg_get_info,
+	NULL, NULL, NULL, NULL, NULL
+};
+
+struct proc_dir_entry ipsec_version =
+{
+	0,
+	13, "ipsec_version",
+	S_IFREG | S_IRUGO, 1, 0, 0, 0,
+	&proc_net_inode_operations,
+	ipsec_version_get_info,
+	NULL, NULL, NULL, NULL, NULL
+};
+
+#ifdef CONFIG_IPSEC_DEBUG
+struct proc_dir_entry ipsec_klipsdebug =
+{
+	0,
+	16, "ipsec_klipsdebug",
+	S_IFREG | S_IRUGO, 1, 0, 0, 0,
+	&proc_net_inode_operations,
+	ipsec_klipsdebug_get_info,
+	NULL, NULL, NULL, NULL, NULL
+};
+#endif /* CONFIG_IPSEC_DEBUG */
+#endif /* !PROC_FS_2325 */
+#endif /* CONFIG_PROC_FS */
+
+int
+ipsec_proc_init()
+{
+	int error = 0;
+
+	/* compile a dummy function if no /proc/-fs */
+
+	/* XXX-mcr probably should just complain because pluto won't
+	 * run without /proc!
+	 */
+
+#ifdef CONFIG_PROC_FS 
+#  ifndef PROC_FS_2325
+#    ifdef PROC_FS_21
+	error |= proc_register(proc_net, &ipsec_eroute);
+	error |= proc_register(proc_net, &ipsec_spi);
+	error |= proc_register(proc_net, &ipsec_spigrp);
+	error |= proc_register(proc_net, &ipsec_tncfg);
+	error |= proc_register(proc_net, &ipsec_version);
+#      ifdef CONFIG_IPSEC_DEBUG
+	error |= proc_register(proc_net, &ipsec_klipsdebug);
+#      endif /* CONFIG_IPSEC_DEBUG */
+#    else /* PROC_FS_21 */
+	error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
+	error |= proc_register_dynamic(&proc_net, &ipsec_spi);
+	error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
+	error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
+	error |= proc_register_dynamic(&proc_net, &ipsec_version);
+#      ifdef CONFIG_IPSEC_DEBUG
+	error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
+#      endif /* CONFIG_IPSEC_DEBUG */
+#    endif /* PROC_FS_21 */
+#  else /* !PROC_FS_2325 */
+	/* create /proc/net/ipsec */
+#if 0
+	proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
+	if(proc_net_ipsec_dir == NULL) {
+		error |= 1;
+	} else{
+		error |= proc_register();
+	}		
+#endif
+
+	proc_net_create ("ipsec_eroute", 0, ipsec_eroute_get_info);
+	proc_net_create ("ipsec_spi", 0, ipsec_spi_get_info);
+	proc_net_create ("ipsec_spigrp", 0, ipsec_spigrp_get_info);
+	proc_net_create ("ipsec_tncfg", 0, ipsec_tncfg_get_info);
+	proc_net_create ("ipsec_version", 0, ipsec_version_get_info);
+#    ifdef CONFIG_IPSEC_DEBUG
+	proc_net_create ("ipsec_klipsdebug", 0, ipsec_klipsdebug_get_info);
+#    endif /* CONFIG_IPSEC_DEBUG */
+#  endif /* !PROC_FS_2325 */
+#endif /* CONFIG_PROC_FS */
+
+	return error;
+}
+
+void
+ipsec_proc_cleanup()
+{
+#ifdef CONFIG_PROC_FS
+#  ifndef PROC_FS_2325
+#    ifdef CONFIG_IPSEC_DEBUG
+	if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
+		printk("klips_debug:ipsec_cleanup: "
+		       "cannot unregister /proc/net/ipsec_klipsdebug\n");
+#    endif /* CONFIG_IPSEC_DEBUG */
+	if (proc_net_unregister(ipsec_version.low_ino) != 0)
+		printk("klips_debug:ipsec_cleanup: "
+		       "cannot unregister /proc/net/ipsec_version\n");
+	if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
+		printk("klips_debug:ipsec_cleanup: "
+		       "cannot unregister /proc/net/ipsec_eroute\n");
+	if (proc_net_unregister(ipsec_spi.low_ino) != 0)
+		printk("klips_debug:ipsec_cleanup: "
+		       "cannot unregister /proc/net/ipsec_spi\n");
+	if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
+		printk("klips_debug:ipsec_cleanup: "
+		       "cannot unregister /proc/net/ipsec_spigrp\n");
+	if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
+		printk("klips_debug:ipsec_cleanup: "
+		       "cannot unregister /proc/net/ipsec_tncfg\n");
+#  else /* !PROC_FS_2325 */
+#    ifdef CONFIG_IPSEC_DEBUG
+	proc_net_remove ("ipsec_klipsdebug");
+#    endif /* CONFIG_IPSEC_DEBUG */
+	proc_net_remove ("ipsec_eroute");
+	proc_net_remove ("ipsec_spi");
+	proc_net_remove ("ipsec_spigrp");
+	proc_net_remove ("ipsec_tncfg");
+	proc_net_remove ("ipsec_version");
+#  endif /* !PROC_FS_2325 */
+#endif          /* CONFIG_PROC_FS */
+}
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.8  2002/01/29 17:17:55  mcr
+ * 	moved include of ipsec_param.h to after include of linux/kernel.h
+ * 	otherwise, it seems that some option that is set in ipsec_param.h
+ * 	screws up something subtle in the include path to kernel.h, and
+ * 	it complains on the snprintf() prototype.
+ *
+ * Revision 1.7  2002/01/29 04:00:52  mcr
+ * 	more excise of kversions.h header.
+ *
+ * Revision 1.6  2002/01/29 02:13:17  mcr
+ * 	introduction of ipsec_kversion.h means that include of
+ * 	ipsec_param.h must preceed any decisions about what files to
+ * 	include to deal with differences in kernel source.
+ *
+ * Revision 1.5  2002/01/12 02:54:30  mcr
+ * 	beginnings of /proc/net/ipsec dir.
+ *
+ * Revision 1.4  2001/12/11 02:21:05  rgb
+ * Don't include module version here, fixing 2.2 compile bug.
+ *
+ * Revision 1.3  2001/12/05 07:19:44  rgb
+ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
+ *
+ * Revision 1.2  2001/11/26 09:16:14  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.74  2001/11/22 05:44:11  henry
+ * new version stuff
+ *
+ * Revision 1.1.2.1  2001/09/25 02:19:40  mcr
+ * 	/proc manipulation code moved to new ipsec_proc.c
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_proto.h linux-patched/net/ipsec/ipsec_proto.h
--- linux/net/ipsec/ipsec_proto.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_proto.h	Sun Jan 19 22:32:30 2003
@@ -0,0 +1,134 @@
+/*
+ * @(#) prototypes for FreeSWAN functions 
+ *
+ * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
+ *                 and Michael Richardson  <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ */
+
+#ifndef _IPSEC_PROTO_H_
+
+#include "ipsec_param.h"
+
+/* 
+ * This file is a kernel only file that declares prototypes for
+ * all intra-module function calls and global data structures.
+ *
+ * Include this file last.
+ *
+ */
+
+/* ipsec_sa.c */
+extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
+extern spinlock_t       tdb_lock;
+extern int ipsec_sadb_init(void);
+
+extern struct ipsec_sa *ipsec_sa_getbyid(struct sa_id*);
+extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
+extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
+extern /* void */ int ipsec_sa_put(struct ipsec_sa *);
+
+extern int ipsec_sa_init(struct ipsec_sa *, struct encap_msghdr *);
+extern int ipsec_sadb_cleanup(__u8);
+extern int ipsec_sa_wipe(struct ipsec_sa *);
+
+/* debug declarations */
+
+/* ipsec_proc.c */
+extern int  ipsec_proc_init(void);
+extern void ipsec_proc_cleanup(void);
+
+/* ipsec_radij.c */
+extern int ipsec_makeroute(struct sockaddr_encap *ea,
+			   struct sockaddr_encap *em,
+			   struct sa_id said,
+			   uint32_t pid,
+			   struct sk_buff *skb,
+			   struct ident *ident_s,
+			   struct ident *ident_d);
+
+extern int ipsec_breakroute(struct sockaddr_encap *ea,
+			    struct sockaddr_encap *em,
+			    struct sk_buff **first,
+			    struct sk_buff **last);
+
+int ipsec_radijinit(void);
+int ipsec_cleareroutes(void);
+int ipsec_radijcleanup(void);
+
+/* ipsec_life.c */
+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
+						  const char *lifename,
+						  const char *saname,
+						  enum ipsec_life_type ilt,
+						  enum ipsec_direction idir,
+						  struct ipsec_sa *ips);
+
+
+extern int ipsec_lifetime_format(char *buffer,
+				 int   buflen,
+				 char *lifename,
+				 enum ipsec_life_type timebaselife,
+				 struct ipsec_lifetime64 *lifetime);
+
+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
+				       __u64 newvalue);
+
+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
+				       __u64 newvalue);
+
+
+
+
+#ifdef CONFIG_IPSEC_DEBUG
+
+extern int debug_xform;
+extern int debug_eroute;
+extern int debug_spi;
+
+#endif /* CONFIG_IPSEC_DEBUG */
+
+
+
+
+#define _IPSEC_PROTO_H
+#endif /* _IPSEC_PROTO_H_ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.3  2003/01/19 22:32:30  ken
+ * X.509 0.9.19 -> 0.9.20
+ *
+ * Revision 1.2  2002/12/12 03:32:07  ken
+ * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.2  2001/11/26 09:16:15  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:21:01  mcr
+ * 	ipsec_proto.h created to keep prototypes rather than deal with
+ * 	cyclic dependancies of structures and prototypes in .h files.
+ *
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
+
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_radij.c linux-patched/net/ipsec/ipsec_radij.c
--- linux/net/ipsec/ipsec_radij.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_radij.c	Sun Jan 19 22:32:30 2003
@@ -0,0 +1,810 @@
+/*
+ * Interface between the IPSEC code and the radix (radij) tree code
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h> /* printk() */
+
+#include "ipsec_param.h"
+
+#ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+#else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+#endif /* MALLOC_SLAB */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+
+#include <linux/netdevice.h>   /* struct device, struct net_device_stats and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/skbuff.h>
+#include <freeswan.h>
+#ifdef SPINLOCK
+# ifdef SPINLOCK_23
+#  include <linux/spinlock.h> /* *lock* */
+# else /* 23_SPINLOCK */
+#  include <asm/spinlock.h> /* *lock* */
+# endif /* 23_SPINLOCK */
+#endif /* SPINLOCK */
+#ifdef NET_21
+# include <asm/uaccess.h>
+# include <linux/in6.h>
+#endif
+#include <asm/checksum.h>
+#include <net/ip.h>
+
+#include "ipsec_eroute.h"
+#include "ipsec_sa.h"
+ 
+#include "radij.h"
+#include "ipsec_encap.h"
+#include "radij.h"
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+#include "ipsec_netlink.h"
+#include "ipsec_tunnel.h"	/* struct ipsecpriv */
+#include "ipsec_xform.h"
+ 
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#include "ipsec_proto.h"
+
+#ifdef CONFIG_IPSEC_DEBUG
+int debug_radij = 0;
+#endif /* CONFIG_IPSEC_DEBUG */
+
+struct radij_node_head *rnh = NULL;
+#ifdef SPINLOCK
+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
+#else /* SPINLOCK */
+spinlock_t eroute_lock;
+#endif /* SPINLOCK */
+
+int
+ipsec_radijinit(void)
+{
+	maj_keylen = sizeof (struct sockaddr_encap);
+
+	rj_init();
+	
+	if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
+		return -1;
+	return 0;
+}
+
+int
+ipsec_radijcleanup(void)
+{
+	int error;
+
+	spin_lock_bh(&eroute_lock);
+
+	error = radijcleanup();
+
+	spin_unlock_bh(&eroute_lock);
+
+	return error;
+}
+
+int
+ipsec_cleareroutes(void)
+{
+	int error = 0;
+
+	spin_lock_bh(&eroute_lock);
+
+	error = radijcleartree();
+
+	spin_unlock_bh(&eroute_lock);
+
+	return error;
+}
+
+int
+ipsec_breakroute(struct sockaddr_encap *eaddr,
+		 struct sockaddr_encap *emask,
+		 struct sk_buff **first,
+		 struct sk_buff **last)
+{
+	struct eroute *ro;
+	struct radij_node *rn;
+	int error = 0;
+#ifdef CONFIG_IPSEC_DEBUG
+	char buf1[64], buf2[64];
+	
+	if (debug_eroute) {
+		subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
+		subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
+		KLIPS_PRINT(debug_eroute, 
+			    "klips_debug:ipsec_breakroute: "
+			    "attempting to delete eroute for %s:%d->%s:%d %d\n",
+			    buf1, ntohs(eaddr->sen_sport),
+			    buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	spin_lock_bh(&eroute_lock);
+
+	if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
+		spin_unlock_bh(&eroute_lock);
+		KLIPS_PRINT(debug_eroute,
+			    "klips_debug:ipsec_breakroute: "
+			    "node not found, eroute delete failed.\n");
+		return error;
+	}
+
+	spin_unlock_bh(&eroute_lock);
+	
+	ro = (struct eroute *)rn;
+	
+	KLIPS_PRINT(debug_eroute, 
+		    "klips_debug:ipsec_breakroute: "
+		    "deleted eroute=%p, ident=%p->%p, first=%p, last=%p\n",
+		    ro,
+		    ro->er_ident_s.data,
+		    ro->er_ident_d.data,
+		    ro->er_first,
+		    ro->er_last);
+	
+	if (ro->er_ident_s.data != NULL) {
+		kfree(ro->er_ident_s.data);
+	}
+	if (ro->er_ident_d.data != NULL) {
+		kfree(ro->er_ident_d.data);
+	}
+	if (ro->er_first != NULL) {
+#if 0
+		struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
+		stats->tx_dropped--;
+#endif
+		*first = ro->er_first;
+	}
+	if (ro->er_last != NULL) {
+#if 0
+		struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
+		stats->tx_dropped--;
+#endif
+		*last = ro->er_last;
+	}
+	
+	if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
+		panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
+	memset((caddr_t)rn, 0, sizeof (struct eroute));
+	kfree(rn);
+	
+	return 0;
+}
+
+int
+ipsec_makeroute(struct sockaddr_encap *eaddr,
+		struct sockaddr_encap *emask,
+		struct sa_id said,
+		uint32_t pid,
+		struct sk_buff *skb,
+		struct ident *ident_s,
+		struct ident *ident_d)
+{
+	struct eroute *retrt;
+	int error = 0;
+	char sa[SATOA_BUF];
+	size_t sa_len;
+#ifdef CONFIG_IPSEC_DEBUG
+	char buf1[64], buf2[64];
+	
+	if (debug_eroute) {
+		subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
+		subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
+		sa_len = satoa(said, 0, sa, SATOA_BUF);
+		KLIPS_PRINT(debug_eroute, 
+			    "klips_debug:ipsec_makeroute: "
+			    "attempting to insert eroute for %s:%d->%s:%d %d, SA: %s, PID:%d, skb=%p, ident:%s->%s\n",
+			    buf1, ntohs(eaddr->sen_sport),
+			    buf2, ntohs(eaddr->sen_dport),
+			    eaddr->sen_proto,
+			    sa_len ? sa : " (error)",
+			    pid,
+			    skb,
+			    (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
+			    (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
+	if (retrt == NULL) {
+		printk("klips_error:ipsec_makeroute: "
+		       "not able to allocate kernel memory");
+		return -ENOMEM;
+	}
+	memset((caddr_t)retrt, 0, sizeof (struct eroute));
+
+	retrt->er_eaddr = *eaddr;
+	retrt->er_emask = *emask;
+	retrt->er_said = said;
+	retrt->er_pid = pid;
+	retrt->er_count = 0;
+	retrt->er_lasttime = jiffies/HZ;
+	rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr);
+	
+	if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
+		int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
+		
+		retrt->er_ident_s.type = ident_s->type;
+		retrt->er_ident_s.id = ident_s->id;
+		retrt->er_ident_s.len = ident_s->len;
+		if(data_len) {
+			if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
+				kfree(retrt);
+				printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
+				return ENOMEM;
+			}
+			memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
+		} else {
+			retrt->er_ident_s.data = NULL;
+		}
+	}
+	
+	if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
+		int data_len = ident_d->len  * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
+		
+		retrt->er_ident_d.type = ident_d->type;
+		retrt->er_ident_d.id = ident_d->id;
+		retrt->er_ident_d.len = ident_d->len;
+		if(data_len) {
+			if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
+				if (retrt->er_ident_s.data)
+					kfree(retrt->er_ident_s.data);
+				kfree(retrt);
+				printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
+				return ENOMEM;
+			}
+			memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
+		} else {
+			retrt->er_ident_d.data = NULL;
+		}
+	}
+	retrt->er_first = skb;
+	retrt->er_last = NULL;
+	
+	spin_lock_bh(&eroute_lock);
+	
+	error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask), 
+			 rnh, retrt->er_rjt.rd_nodes);
+
+	spin_unlock_bh(&eroute_lock);
+	
+	if(error) {
+		sa_len = satoa(said, 0, sa, SATOA_BUF);
+		KLIPS_PRINT(debug_eroute, 
+			    "klips_debug:ipsec_makeroute: "
+			    "rj_addroute not able to insert eroute for SA:%s\n",
+			    sa_len ? sa : " (error)");
+		if (retrt->er_ident_s.data)
+			kfree(retrt->er_ident_s.data);
+		if (retrt->er_ident_d.data)
+			kfree(retrt->er_ident_d.data);
+		
+		kfree(retrt);
+		
+		return error;
+	}
+
+#ifdef CONFIG_IPSEC_DEBUG
+	if (debug_eroute && 0) {
+/*
+		subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
+		subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
+*/
+		subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
+		subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
+		sa_len = satoa(retrt->er_said, 0, sa, SATOA_BUF);
+		
+		KLIPS_PRINT(debug_eroute,
+			    "klips_debug:ipsec_makeroute: "
+			    "pid=%05d "
+			    "count=%10d "
+			    "lasttime=%6d "
+			    "%-18s -> %-18s => %s\n",
+			    retrt->er_pid,
+			    retrt->er_count,
+			    (int)(jiffies/HZ - retrt->er_lasttime),
+			    buf1,
+			    buf2,
+			    sa_len ? sa : " (error)");
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+	KLIPS_PRINT(debug_eroute,
+		    "klips_debug:ipsec_makeroute: "
+		    "succeeded, I think...\n");
+	return 0;
+}
+
+struct eroute *
+ipsec_findroute(struct sockaddr_encap *eaddr)
+{
+	struct radij_node *rn;
+#ifdef CONFIG_IPSEC_DEBUG
+	char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
+	
+	if (debug_radij & DB_RJ_FINDROUTE) {
+		addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
+		addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
+		KLIPS_PRINT(debug_eroute,
+			    "klips_debug:ipsec_findroute: "
+			    "%s:%d->%s:%d %d\n",
+			    buf1, ntohs(eaddr->sen_sport),
+			    buf2, ntohs(eaddr->sen_dport),
+			    eaddr->sen_proto);
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+	rn = rj_match((caddr_t)eaddr, rnh);
+	if(rn) {
+		KLIPS_PRINT(debug_eroute,
+			    "klips_debug:ipsec_findroute: "
+			    "found, points to proto=%d, spi=%x, dst=%x.\n",
+			    ((struct eroute*)rn)->er_said.proto,
+			    ntohl(((struct eroute*)rn)->er_said.spi),
+			    ntohl(((struct eroute*)rn)->er_said.dst.s_addr));
+	}
+	return (struct eroute *)rn;
+}
+		
+#ifdef CONFIG_PROC_FS
+int
+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
+{
+	struct eroute *ro = (struct eroute *)rn;
+	struct rjtentry *rd = (struct rjtentry *)rn;
+	struct wsbuf *w = (struct wsbuf *)w0;
+	char buf1[64], buf2[64];
+	char sa[SATOA_BUF];
+	size_t sa_len, buf_len;
+	struct sockaddr_encap *key, *mask;
+	
+	KLIPS_PRINT(debug_radij,
+		    "klips_debug:ipsec_rj_walker_procprint: "
+		    "rn=%p, w0=%p\n",
+		    rn,
+		    w0);
+	if (rn == NULL)	{
+		return 120;
+	}
+	
+	if (rn->rj_b >= 0) {
+		return 0;
+	}
+	
+	key = rd_key(rd);
+	mask = rd_mask(rd);
+	
+	if ((key == 0) || (mask == 0)) {
+		return 0;
+	}
+
+	buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
+	sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
+	buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
+	sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
+	sa_len = satoa(ro->er_said, 0, sa, SATOA_BUF);
+#define IPSEC_EROUTE_IDENT_
+#ifndef IPSEC_EROUTE_IDENT
+	w->len += sprintf(w->buffer + w->len,
+/*
+			  "%05d "
+*/
+			  "%-10d "
+/*
+			  "%6d "
+*/
+			  "%-18s -> %-18s => %s:%d\n",
+/*
+			  ro->er_pid,
+*/
+			  ro->er_count,
+/*
+			  jiffies / HZ - ro->er_lasttime,
+*/
+			  buf1,
+			  buf2,
+			  sa_len ? sa : " (error)",
+			  key->sen_proto);
+#else /* IPSEC_EROUTE_IDENT */
+	w->len += sprintf(w->buffer + w->len,
+/*
+			  "%05d "
+*/
+			  "%-10d "
+/*
+			  "%6d "
+*/
+			  "%-18s -> %-18s => %s:%d (%s) (%s)\n",
+/*
+			  ro->er_pid,
+*/
+			  ro->er_count,
+/*
+			  jiffies / HZ - ro->er_lasttime,
+*/
+			  buf1,
+			  buf2,
+			  sa_len ? sa : " (error)",
+			  key->sen_proto,
+			  (ro->er_ident_s.data ? ro->er_ident_s.data : ""),
+			  (ro->er_ident_d.data ? ro->er_ident_d.data : ""));
+#endif /* IPSEC_EROUTE_IDENT */
+	
+	w->pos = w->begin + w->len;
+	if(w->pos < w->offset) {
+		w->len = 0;
+		w->begin = w->pos;
+	}
+	if (w->pos > w->offset + w->length) {
+		return -ENOBUFS;
+	}
+	return 0;
+}
+#endif          /* CONFIG_PROC_FS */
+
+int
+ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
+{
+	struct eroute *ro;
+	struct rjtentry *rd = (struct rjtentry *)rn;
+	struct radij_node *rn2;
+	int error = 0;
+	struct sockaddr_encap *key, *mask;
+#ifdef CONFIG_IPSEC_DEBUG
+	char buf1[64] = { 0 }, buf2[64] = { 0 };
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	if (rn == NULL)	{
+		return 120;
+	}
+	
+	key = rd_key(rd);
+	mask = rd_mask(rd);
+	
+	if(!key || !mask) {
+		return -ENODATA;
+	}
+#ifdef CONFIG_IPSEC_DEBUG
+	if(debug_radij)	{
+		subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
+		subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
+		KLIPS_PRINT(debug_radij, 
+			    "klips_debug:ipsec_rj_walker_delete: "
+			    "deleting: %s -> %s\n",
+			    buf1,
+			    buf2);
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	if((error = rj_delete(key, mask, rnh, &rn2))) {
+		KLIPS_PRINT(debug_radij,
+			    "klips_debug:ipsec_rj_walker_delete: "
+			    "rj_delete failed with error=%d.\n", error);
+		return error;
+	}
+
+	if(rn2 != rn) {
+		printk("klips_debug:ipsec_rj_walker_delete: "
+		       "tried to delete a different node?!?  This should never happen!\n");
+	}
+ 
+	ro = (struct eroute *)rn;
+	
+	if (ro->er_ident_s.data)
+		kfree(ro->er_ident_s.data);
+	if (ro->er_ident_d.data)
+		kfree(ro->er_ident_d.data);
+	
+	memset((caddr_t)rn, 0, sizeof (struct eroute));
+	kfree(rn);
+	
+	return 0;
+}
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.3  2003/01/19 22:32:30  ken
+ * X.509 0.9.19 -> 0.9.20
+ *
+ * Revision 1.2  2002/12/12 03:32:07  ken
+ * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.60  2002/02/19 23:59:45  rgb
+ * Removed redundant compiler directives.
+ *
+ * Revision 1.59  2002/02/06 04:13:47  mcr
+ * 	missing #ifdef CONFIG_IPSEC_DEBUG.
+ *
+ * Revision 1.58  2002/01/29 17:17:56  mcr
+ * 	moved include of ipsec_param.h to after include of linux/kernel.h
+ * 	otherwise, it seems that some option that is set in ipsec_param.h
+ * 	screws up something subtle in the include path to kernel.h, and
+ * 	it complains on the snprintf() prototype.
+ *
+ * Revision 1.57  2002/01/29 04:00:52  mcr
+ * 	more excise of kversions.h header.
+ *
+ * Revision 1.56  2002/01/29 02:13:17  mcr
+ * 	introduction of ipsec_kversion.h means that include of
+ * 	ipsec_param.h must preceed any decisions about what files to
+ * 	include to deal with differences in kernel source.
+ *
+ * Revision 1.55  2001/11/26 09:23:48  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.53.2.1  2001/09/25 02:26:32  mcr
+ * 	headers adjusted for new usage.
+ *
+ * Revision 1.54  2001/10/18 04:45:20  rgb
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
+ * lib/freeswan.h version macros moved to lib/kversions.h.
+ * Other compiler directive cleanups.
+ *
+ * Revision 1.53  2001/09/19 17:19:40  rgb
+ * Debug output bugfix for NetCelo's PF_KEY ident patch.
+ *
+ * Revision 1.52  2001/09/19 16:33:37  rgb
+ * Temporarily disable ident fields to /proc/net/ipsec_eroute.
+ *
+ * Revision 1.51  2001/09/15 16:24:04  rgb
+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
+ *
+ * Revision 1.50  2001/09/14 16:58:36  rgb
+ * Added support for storing the first and last packets through a HOLD.
+ *
+ * Revision 1.49  2001/09/08 21:13:32  rgb
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
+ *
+ * Revision 1.48  2001/06/15 04:12:56  rgb
+ * Fixed kernel memory allocation error return code polarity bug.
+ *
+ * Revision 1.47  2001/06/14 19:35:09  rgb
+ * Update copyright date.
+ *
+ * Revision 1.46  2001/06/08 08:47:18  rgb
+ * Fixed for debug disabled.
+ *
+ * Revision 1.45  2001/05/27 06:12:11  rgb
+ * Added structures for pid, packet count and last access time to eroute.
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
+ *
+ * Revision 1.44  2001/05/03 19:41:01  rgb
+ * Initialise error return variable.
+ * Use more appropriate return value for ipsec_rj_walker_delete().
+ *
+ * Revision 1.43  2001/02/27 22:24:54  rgb
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
+ * Check for satoa() return codes.
+ *
+ * Revision 1.42  2001/02/27 06:21:57  rgb
+ * Added findroute success instrumentation.
+ *
+ * Revision 1.41  2000/11/06 04:32:08  rgb
+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
+ *
+ * Revision 1.40  2000/09/08 19:12:56  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ *
+ * Revision 1.39  2000/08/30 05:25:20  rgb
+ * Correct debug text in ipsec_breakroute() from incorrect
+ * "ipsec_callback".
+ *
+ * Revision 1.38  2000/07/28 14:58:31  rgb
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
+ *
+ * Revision 1.37  2000/03/16 14:02:50  rgb
+ * Fixed debug scope to enable compilation with debug off.
+ *
+ * Revision 1.36  2000/01/21 06:14:46  rgb
+ * Added debugging text to ipsec_rj_walker_delete().
+ * Set return code to negative for consistency.
+ *
+ * Revision 1.35  1999/11/23 23:05:24  rgb
+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
+ *
+ * Revision 1.34  1999/11/18 04:13:56  rgb
+ * Replaced all kernel version macros to shorter, readable form.
+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
+ *
+ * Revision 1.33  1999/11/17 15:53:39  rgb
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
+ * klips/net/ipsec/Makefile.
+ *
+ * Revision 1.32  1999/10/26 13:58:33  rgb
+ * Put spinlock flags variable declaration outside the debug compiler
+ * directive to enable compilation with debug shut off.
+ *
+ * Revision 1.31  1999/10/15 22:13:29  rgb
+ * Clean out cruft.
+ * Align /proc/net/ipsec_eroute output for easier readability.
+ * Fix double linefeed in radij debug output.
+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
+ *
+ * Revision 1.30  1999/10/08 18:37:33  rgb
+ * Fix end-of-line spacing to sate whining PHMs.
+ *
+ * Revision 1.29  1999/10/03 18:52:45  rgb
+ * Spinlock support for 2.0.xx.
+ * Dumb return code spin_unlock fix.
+ *
+ * Revision 1.28  1999/10/01 16:22:24  rgb
+ * Switch from assignment init. to functional init. of spinlocks.
+ *
+ * Revision 1.27  1999/10/01 15:44:53  rgb
+ * Move spinlock header include to 2.1> scope.
+ *
+ * Revision 1.26  1999/10/01 00:01:23  rgb
+ * Added eroute structure locking.
+ *
+ * Revision 1.25  1999/06/10 16:07:30  rgb
+ * Silence delete eroute on no debug.
+ *
+ * Revision 1.24  1999/05/09 03:25:36  rgb
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
+ *
+ * Revision 1.23  1999/05/05 22:02:31  rgb
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
+ *
+ * Revision 1.22  1999/04/29 15:17:23  rgb
+ * Add return values to init and cleanup functions.
+ * Add sanity checking for null pointer arguments.
+ *
+ * Revision 1.21  1999/04/11 00:28:58  henry
+ * GPL boilerplate
+ *
+ * Revision 1.20  1999/04/06 04:54:26  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.19  1999/02/17 16:50:35  rgb
+ * Clean out unused cruft.
+ * Consolidate for space and speed efficiency.
+ * Convert DEBUG_IPSEC to KLIPS_PRINT
+ *
+ * Revision 1.18  1999/01/22 06:22:06  rgb
+ * Cruft clean-out.
+ * 64-bit clean-up.
+ *
+ * Revision 1.17  1998/12/02 03:09:39  rgb
+ * Clean up debug printing conditionals to compile with debugging off.
+ *
+ * Revision 1.16  1998/12/01 13:49:39  rgb
+ * Wrap version info printing in debug switches.
+ *
+ * Revision 1.15  1998/11/30 13:22:54  rgb
+ * Rationalised all the klips kernel file headers.  They are much shorter
+ * now and won't conflict under RH5.2.
+ *
+ * Revision 1.14  1998/10/31 06:48:17  rgb
+ * Fixed up comments in #endif directives.
+ *
+ * Revision 1.13  1998/10/27 13:48:09  rgb
+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
+ * Fixed less(1) truncated output bug.
+ * Code clean-up.
+ *
+ * Revision 1.12  1998/10/25 02:41:36  rgb
+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
+ * argument to be able to transmit more infomation about errors.
+ * Fix cut-and-paste debug statement identifier.
+ *
+ * Revision 1.11  1998/10/22 06:45:39  rgb
+ * Cleaned up cruft.
+ * Convert to use satoa for printk.
+ *
+ * Revision 1.10  1998/10/19 14:44:28  rgb
+ * Added inclusion of freeswan.h.
+ * sa_id structure implemented and used: now includes protocol.
+ *
+ * Revision 1.9  1998/10/09 04:30:52  rgb
+ * Added 'klips_debug' prefix to all klips printk debug statements.
+ * Deleted old commented out cruft.
+ *
+ * Revision 1.8  1998/08/06 17:24:23  rgb
+ * Fix addrtoa return code bug from stale manpage advice preventing packets
+ * from being erouted.
+ *
+ * Revision 1.7  1998/08/06 07:44:59  rgb
+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
+ * ended up in nothing being printed.
+ *
+ * Revision 1.6  1998/08/05 22:16:41  rgb
+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
+ *
+ * Revision 1.5  1998/07/29 20:38:44  rgb
+ * Debug and fix subnettoa and addrtoa output.
+ *
+ * Revision 1.4  1998/07/28 00:02:39  rgb
+ * Converting to exclusive use of addrtoa.
+ * Fix eroute delete.
+ *
+ * Revision 1.3  1998/07/14 18:21:26  rgb
+ * Add function to clear the eroute table.
+ *
+ * Revision 1.2  1998/06/23 02:59:14  rgb
+ * Added debugging output to eroute add/delete routines.
+ *
+ * Revision 1.9  1998/06/18 21:29:06  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
+ * build scripts happier in presence of symbolic links
+ *
+ * Revision 1.8  1998/06/05 02:32:26  rgb
+ * Fix spi ntoh kernel debug output.
+ *
+ * Revision 1.7  1998/05/25 20:30:37  rgb
+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
+ *
+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
+ * add ipsec_rj_walker_delete.
+ *
+ * Revision 1.6  1998/05/21 13:08:57  rgb
+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
+ * information is available for printout.
+ *
+ * Revision 1.5  1998/05/18 21:35:55  rgb
+ * Clean up output for numerical consistency and readability.  Zero freed
+ * eroute memory.
+ *
+ * Revision 1.4  1998/04/21 21:28:58  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.3  1998/04/14 17:30:39  rgb
+ * Fix up compiling errors for radij tree memory reclamation.
+ *
+ * Revision 1.2  1998/04/12 22:03:23  rgb
+ * Updated ESP-3DES-HMAC-MD5-96,
+ * 	ESP-DES-HMAC-MD5-96,
+ * 	AH-HMAC-MD5-96,
+ * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
+ *
+ * Fixed eroute references in /proc/net/ipsec*.
+ *
+ * Started to patch module unloading memory leaks in ipsec_netlink and
+ * radij tree unloading.
+ *
+ * Revision 1.1  1998/04/09 03:06:10  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:03  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * No changes.
+ *
+ * Revision 0.3  1996/11/20 14:39:04  ji
+ * Minor cleanups.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_radij.h linux-patched/net/ipsec/ipsec_radij.h
--- linux/net/ipsec/ipsec_radij.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_radij.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,163 @@
+/*
+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+#ifndef _IPSEC_RADIJ_H
+
+#include <freeswan.h>
+
+int ipsec_walk(char *);
+
+int ipsec_rj_walker_procprint(struct radij_node *, void *);
+int ipsec_rj_walker_delete(struct radij_node *, void *);
+
+struct wsbuf
+{
+	char *buffer;
+	int length;
+	off_t offset;
+	int len;
+	int prev_len;
+	off_t begin;
+	off_t pos;
+};
+
+extern struct radij_node_head *rnh;
+extern spinlock_t eroute_lock;
+
+struct eroute * ipsec_findroute(struct sockaddr_encap *);
+
+#define O1(x) (int)(((x)>>24)&0xff)
+#define O2(x) (int)(((x)>>16)&0xff)
+#define O3(x) (int)(((x)>>8)&0xff)
+#define O4(x) (int)(((x))&0xff)
+
+#ifdef CONFIG_IPSEC_DEBUG
+extern int debug_radij;
+void rj_dumptrees(void);
+
+#define DB_RJ_DUMPTREES	0x0001
+#define DB_RJ_FINDROUTE 0x0002
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#define _IPSEC_RADIJ_H
+#endif
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.17  2001/11/26 09:23:49  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.16.2.1  2001/09/25 02:21:17  mcr
+ * 	ipsec_proto.h created to keep prototypes rather than deal with
+ * 	cyclic dependancies of structures and prototypes in .h files.
+ *
+ * Revision 1.16  2001/09/15 16:24:04  rgb
+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
+ *
+ * Revision 1.15  2001/09/14 16:58:37  rgb
+ * Added support for storing the first and last packets through a HOLD.
+ *
+ * Revision 1.14  2001/09/08 21:13:32  rgb
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
+ *
+ * Revision 1.13  2001/06/14 19:35:09  rgb
+ * Update copyright date.
+ *
+ * Revision 1.12  2001/05/27 06:12:11  rgb
+ * Added structures for pid, packet count and last access time to eroute.
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
+ *
+ * Revision 1.11  2000/09/08 19:12:56  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ *
+ * Revision 1.10  1999/11/17 15:53:39  rgb
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
+ * klips/net/ipsec/Makefile.
+ *
+ * Revision 1.9  1999/10/01 00:01:23  rgb
+ * Added eroute structure locking.
+ *
+ * Revision 1.8  1999/04/11 00:28:59  henry
+ * GPL boilerplate
+ *
+ * Revision 1.7  1999/04/06 04:54:26  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.6  1999/01/22 06:23:26  rgb
+ * Cruft clean-out.
+ *
+ * Revision 1.5  1998/10/25 02:42:08  rgb
+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
+ * argument to be able to transmit more infomation about errors.
+ *
+ * Revision 1.4  1998/10/19 14:44:29  rgb
+ * Added inclusion of freeswan.h.
+ * sa_id structure implemented and used: now includes protocol.
+ *
+ * Revision 1.3  1998/07/28 00:03:31  rgb
+ * Comment out temporary inet_nto4u() kluge.
+ *
+ * Revision 1.2  1998/07/14 18:22:00  rgb
+ * Add function to clear the eroute table.
+ *
+ * Revision 1.1  1998/06/18 21:27:49  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.5  1998/05/25 20:30:38  rgb
+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
+ *
+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
+ * add ipsec_rj_walker_delete.
+ *
+ * Revision 1.4  1998/05/21 13:02:56  rgb
+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
+ * limit fix.
+ *
+ * Revision 1.3  1998/04/21 21:29:09  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.2  1998/04/14 17:30:39  rgb
+ * Fix up compiling errors for radij tree memory reclamation.
+ *
+ * Revision 1.1  1998/04/09 03:06:10  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:04  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * No changes.
+ *
+ * Revision 0.3  1996/11/20 14:39:04  ji
+ * Minor cleanups.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_rcv.c linux-patched/net/ipsec/ipsec_rcv.c
--- linux/net/ipsec/ipsec_rcv.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_rcv.c	Fri Jul  4 20:07:34 2003
@@ -0,0 +1,2595 @@
+/*
+ * receive code
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+char ipsec_rcv_c_version[] = "RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $";
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/kernel.h> /* printk() */
+
+#define IPSEC_KLIPS1_COMPAT 1
+#include "ipsec_param.h"
+
+#ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+#else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+#endif /* MALLOC_SLAB */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/skbuff.h>
+#include <freeswan.h>
+#ifdef SPINLOCK
+# ifdef SPINLOCK_23
+#  include <linux/spinlock.h> /* *lock* */
+# else /* SPINLOCK_23 */
+#  include <asm/spinlock.h> /* *lock* */
+# endif /* SPINLOCK_23 */
+#endif /* SPINLOCK */
+#ifdef NET_21
+# include <asm/uaccess.h>
+# include <linux/in6.h>
+# define proto_priv cb
+#endif /* NET21 */
+#include <asm/checksum.h>
+#include <net/ip.h>
+
+#include "radij.h"
+#include "ipsec_encap.h"
+#include "ipsec_sa.h"
+
+#include "ipsec_radij.h"
+#include "ipsec_netlink.h"
+#include "ipsec_xform.h"
+#include "ipsec_tunnel.h"
+#include "ipsec_rcv.h"
+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
+# include "ipsec_ah.h"
+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
+#ifdef CONFIG_IPSEC_ESP
+# include "ipsec_esp.h"
+#endif /* !CONFIG_IPSEC_ESP */
+#ifdef CONFIG_IPSEC_IPCOMP
+# include "ipcomp.h"
+#endif /* CONFIG_IPSEC_COMP */
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#include "ipsec_proto.h"
+
+#include "ipsec_alg.h"
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+#include <linux/udp.h>
+#endif
+
+#ifdef CONFIG_IPSEC_DEBUG
+int debug_ah = 0;
+int debug_esp = 0;
+int debug_rcv = 0;
+#endif /* CONFIG_IPSEC_DEBUG */
+
+int sysctl_ipsec_inbound_policy_check = 1;
+
+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
+__u32 zeroes[AH_AMAX];
+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
+
+/*
+ * Check-replay-window routine, adapted from the original 
+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
+ *
+ *  This is a routine that implements a 64 packet window. This is intend-
+ *  ed on being an implementation sample.
+ */
+
+DEBUG_NO_STATIC int
+ipsec_checkreplaywindow(struct ipsec_sa*tdbp, __u32 seq)
+{
+	__u32 diff;
+	
+	if (tdbp->tdb_replaywin == 0)	/* replay shut off */
+		return 1;
+	if (seq == 0) 
+		return 0;		/* first == 0 or wrapped */
+
+	/* new larger sequence number */
+	if (seq > tdbp->tdb_replaywin_lastseq) {
+		return 1;		/* larger is good */
+	}
+	diff = tdbp->tdb_replaywin_lastseq - seq;
+
+	/* too old or wrapped */ /* if wrapped, kill off SA? */
+	if (diff >= tdbp->tdb_replaywin) {
+		return 0;
+	}
+	/* this packet already seen */
+	if (tdbp->tdb_replaywin_bitmap & (1 << diff))
+		return 0;
+	return 1;			/* out of order but good */
+}
+
+DEBUG_NO_STATIC int
+ipsec_updatereplaywindow(struct ipsec_sa*tdbp, __u32 seq)
+{
+	__u32 diff;
+	
+	if (tdbp->tdb_replaywin == 0)	/* replay shut off */
+		return 1;
+	if (seq == 0) 
+		return 0;		/* first == 0 or wrapped */
+
+	/* new larger sequence number */
+	if (seq > tdbp->tdb_replaywin_lastseq) {
+		diff = seq - tdbp->tdb_replaywin_lastseq;
+
+		/* In win, set bit for this pkt */
+		if (diff < tdbp->tdb_replaywin)
+			tdbp->tdb_replaywin_bitmap =
+				(tdbp->tdb_replaywin_bitmap << diff) | 1;
+		else
+			/* This packet has way larger seq num */
+			tdbp->tdb_replaywin_bitmap = 1;
+
+		if(seq - tdbp->tdb_replaywin_lastseq - 1 > tdbp->tdb_replaywin_maxdiff) {
+			tdbp->tdb_replaywin_maxdiff = seq - tdbp->tdb_replaywin_lastseq - 1;
+		}
+		tdbp->tdb_replaywin_lastseq = seq;
+		return 1;		/* larger is good */
+	}
+	diff = tdbp->tdb_replaywin_lastseq - seq;
+
+	/* too old or wrapped */ /* if wrapped, kill off SA? */
+	if (diff >= tdbp->tdb_replaywin) {
+/*
+		if(seq < 0.25*max && tdbp->tdb_replaywin_lastseq > 0.75*max) {
+			deltdbchain(tdbp);
+		}
+*/	
+		return 0;
+	}
+	/* this packet already seen */
+	if (tdbp->tdb_replaywin_bitmap & (1 << diff))
+		return 0;
+	tdbp->tdb_replaywin_bitmap |= (1 << diff);	/* mark as seen */
+	return 1;			/* out of order but good */
+}
+
+int
+#ifdef PROTO_HANDLER_SINGLE_PARM
+ipsec_rcv(struct sk_buff *skb)
+#else /* PROTO_HANDLER_SINGLE_PARM */
+#ifdef NET_21
+ipsec_rcv(struct sk_buff *skb, unsigned short xlen)
+#else /* NET_21 */
+ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, 
+		__u32 daddr_unused, unsigned short xlen, __u32 saddr,
+                                   int redo, struct inet_protocol *protocol)
+#endif /* NET_21 */
+#endif /* PROTO_HANDLER_SINGLE_PARM */
+{
+#ifdef NET_21
+#ifdef CONFIG_IPSEC_DEBUG
+	struct device *dev = skb->dev;
+#endif /* CONFIG_IPSEC_DEBUG */
+#endif /* NET_21 */
+	unsigned char protoc;
+	struct iphdr *ipp;
+	int authlen = 0;
+#ifdef CONFIG_IPSEC_ESP
+	struct esp *espp = NULL;
+	int esphlen = 0;
+#ifdef CONFIG_IPSEC_ENC_3DES
+	__u32 iv[ESP_IV_MAXSZ_INT];
+#endif /* !CONFIG_IPSEC_ENC_3DES */
+#endif /* !CONFIG_IPSEC_ESP */
+#ifdef CONFIG_IPSEC_AH
+	struct ah *ahp = NULL;
+	int ahhlen = 0;
+#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1)
+	struct iphdr ipo;
+#endif
+#endif /* CONFIG_IPSEC_AH */
+	unsigned char *authenticator = NULL;
+	union {
+		MD5_CTX		md5;
+		SHA1_CTX	sha1;
+	} tctx;
+	__u8 hash[AH_AMAX];
+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
+#ifdef CONFIG_IPSEC_IPCOMP
+	struct ipcomphdr*compp = NULL;
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+	int hard_header_len;
+	int iphlen;
+	unsigned char *dat;
+	struct ipsec_sa *tdbp = NULL;
+	struct sa_id said;
+	struct net_device_stats *stats = NULL;		/* This device's statistics */
+	struct device *ipsecdev = NULL, *prvdev;
+	struct ipsecpriv *prv;
+	char name[9];
+	char sa[SATOA_BUF];
+	size_t sa_len;
+	char ipaddr_txt[ADDRTOA_BUF];
+	int i;
+	struct in_addr ipaddr;
+	__u8 next_header = 0;
+	__u8 proto;
+	
+#ifdef CONFIG_IPSEC_ESP
+	int pad = 0, padlen;
+#endif /* CONFIG_IPSEC_ESP */
+	int ilen;	/* content to be decrypted/authenticated */
+	int len;	/* packet length */
+	int replay = 0;	/* replay value in AH or ESP packet */
+	__u8 *idat;	/* pointer to content to be decrypted/authenticated */
+	struct ipsec_sa* tdbprev = NULL;	/* previous SA from outside of packet */
+	struct ipsec_sa* tdbnext = NULL;	/* next SA towards inside of packet */
+#ifdef INBOUND_POLICY_CHECK_eroute
+	struct sockaddr_encap matcher;	/* eroute search key */
+	struct eroute *er;
+	struct ipsec_sa* policy_tdb = NULL;
+	struct sa_id policy_said;
+	struct sockaddr_encap policy_eaddr;
+	struct sockaddr_encap policy_emask;
+#endif /* INBOUND_POLICY_CHECK_eroute */
+#ifdef CONFIG_IPSEC_ALG
+	struct ipsec_alg_enc *ixt_e=NULL;
+	struct ipsec_alg_auth *ixt_a=NULL;
+#endif /* CONFIG_IPSEC_ALG */
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	__u16 natt_len = 0, natt_sport = 0, natt_dport = 0;
+	__u8 natt_type = 0;
+#endif
+
+	/* Don't unlink in the middle of a turnaround */
+	MOD_INC_USE_COUNT;
+	
+	if (skb == NULL) {
+		KLIPS_PRINT(debug_rcv, 
+			    "klips_debug:ipsec_rcv: "
+			    "NULL skb passed in.\n");
+		goto rcvleave;
+	}
+		
+	if (skb->data == NULL) {
+		KLIPS_PRINT(debug_rcv,
+			    "klips_debug:ipsec_rcv: "
+			    "NULL skb->data passed in, packet is bogus, dropping.\n");
+		goto rcvleave;
+	}
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
+		/**
+		 * Packet comes from udp_queue_rcv_skb so it is already defrag,
+		 * checksum verified, ... (ie safe to use)
+		 *
+		 * If the packet is not for us, return -1 and udp_queue_rcv_skb
+		 * will continue to handle it (do not kfree skb !!).
+		 */
+		struct udp_opt *tp =  &(skb->sk->tp_pinfo.af_udp);
+		struct iphdr *ip = (struct iphdr *)skb->nh.iph;
+		struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
+		__u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
+		__u32 *udpdata32 = (__u32 *)udpdata;
+
+		natt_sport = ntohs(udp->source);
+		natt_dport = ntohs(udp->dest);
+
+		KLIPS_PRINT(debug_rcv,
+		    "klips_debug:ipsec_rcv: "
+		    "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
+			tp->esp_in_udp);
+		KLIPS_IP_PRINT(debug_rcv, ip);
+
+		if (udpdata < skb->tail) {
+			unsigned int len = skb->tail - udpdata;
+			if ((len==1) && (udpdata[0]==0xff)) {
+				KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+					/* not IPv6 compliant message */
+				    "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
+				goto rcvleave;
+			}
+			else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
+				(len > (2*sizeof(__u32) + sizeof(struct esp))) &&
+				(udpdata32[0]==0) && (udpdata32[1]==0) ) {
+				/* ESP Packet with Non-IKE header */
+				KLIPS_PRINT(debug_rcv, 
+					"klips_debug:ipsec_rcv: "
+					"ESPinUDP pkt with Non-IKE - spi=0x%x\n",
+					udpdata32[2]);
+				natt_type = ESPINUDP_WITH_NON_IKE;
+				natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
+			}
+			else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
+				(len > sizeof(struct esp)) &&
+				(udpdata32[0]!=0) ) {
+				/* ESP Packet without Non-ESP header */
+				natt_type = ESPINUDP_WITH_NON_ESP;
+				natt_len = sizeof(struct udphdr);
+				KLIPS_PRINT(debug_rcv, 
+					"klips_debug:ipsec_rcv: "
+                                        "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
+					udpdata32[0]);
+			}
+			else {
+				KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+					"IKE packet - not handled here\n");
+				MOD_DEC_USE_COUNT;
+				return -1;
+			}
+		}
+		else {
+			MOD_DEC_USE_COUNT;
+			return -1;
+		}
+	}
+#endif
+		
+#ifdef IPH_is_SKB_PULLED
+	/* In Linux 2.4.4, the IP header has been skb_pull()ed before the
+	   packet is passed to us. So we'll skb_push() to get back to it. */
+	if (skb->data == skb->h.raw) {
+		skb_push(skb, skb->h.raw - skb->nh.raw);
+	}
+#endif /* IPH_is_SKB_PULLED */
+
+	ipp = (struct iphdr *)skb->data;
+	iphlen = ipp->ihl << 2;
+	/* dev->hard_header_len is unreliable and should not be used */
+	hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0;
+	if((hard_header_len < 0) || (hard_header_len > skb_headroom(skb)))
+		hard_header_len = 0;
+
+#ifdef NET_21
+	/* if skb was cloned (most likely due to a packet sniffer such as
+	   tcpdump being momentarily attached to the interface), make
+	   a copy of our own to modify */
+	if(skb_cloned(skb)) {
+		/* include any mac header while copying.. */
+		if(skb_headroom(skb) < hard_header_len) {
+			printk(KERN_WARNING "klips_error:ipsec_rcv: "
+			       "tried to skb_push hhlen=%d, %d available.  This should never happen, please report.\n",
+			       hard_header_len,
+			       skb_headroom(skb));
+			goto rcvleave;
+		}
+		skb_push(skb, hard_header_len);
+		if
+#ifdef SKB_COW_NEW
+               (skb_cow(skb, skb_headroom(skb)) != 0)
+#else /* SKB_COW_NEW */
+               ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
+#endif /* SKB_COW_NEW */
+		{
+			goto rcvleave;
+		}
+		if(skb->len < hard_header_len) {
+			printk(KERN_WARNING "klips_error:ipsec_rcv: "
+			       "tried to skb_pull hhlen=%d, %d available.  This should never happen, please report.\n",
+			       hard_header_len,
+			       skb->len);
+			goto rcvleave;
+		}
+		skb_pull(skb, hard_header_len);
+	}
+	
+#endif /* NET_21 */
+		
+#if IP_FRAGMENT_LINEARIZE
+	/* In Linux 2.4.4, we may have to reassemble fragments. They are
+	   not assembled automatically to save TCP from having to copy
+	   twice.
+	*/
+      if (skb_is_nonlinear(skb)) {
+	if (skb_linearize(skb, GFP_ATOMIC) != 0) {
+	  goto rcvleave;
+	}
+      }
+      ipp = (struct iphdr *)skb->nh.iph;
+      iphlen = ipp->ihl << 2;
+#endif
+	
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	if (natt_len) {
+		/**
+		 * Now, we are sure packet is ESPinUDP. Remove natt_len bytes from
+		 * packet and modify protocol to ESP.
+		 */
+		if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph) &&
+			((unsigned char *)skb->nh.iph > (unsigned char *)skb->head)) {
+			unsigned int _len = (unsigned char *)skb->data -
+				(unsigned char *)skb->nh.iph;
+			KLIPS_PRINT(debug_rcv,
+				"klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
+				_len);
+			skb_push(skb, _len);
+		}
+		KLIPS_PRINT(debug_rcv,
+		    "klips_debug:ipsec_rcv: "
+			"removing %d bytes from ESPinUDP packet\n", natt_len);
+		ipp = (struct iphdr *)skb->data;
+		iphlen = ipp->ihl << 2;
+		ipp->tot_len = htons(ntohs(ipp->tot_len) - natt_len);
+		if (skb->len < iphlen + natt_len) {
+			printk(KERN_WARNING
+		       "klips_error:ipsec_rcv: "
+		       "ESPinUDP packet is too small (%d < %d+%d). "
+			   "This should never happen, please report.\n",
+		       (int)(skb->len), iphlen, natt_len);
+			goto rcvleave;
+		}
+		memmove(skb->data + natt_len, skb->data, iphlen);
+		skb_pull(skb, natt_len);
+
+		/* update nh.iph */
+		ipp = skb->nh.iph = (struct iphdr *)skb->data;
+
+		/* modify protocol */
+		ipp->protocol = IPPROTO_ESP;
+
+		skb->sk = NULL;
+
+		KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
+	}
+#endif
+
+	KLIPS_PRINT(debug_rcv, 
+		    "klips_debug:ipsec_rcv: "
+		    "<<< Info -- ");
+	KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
+		    skb->dev->name ? skb->dev->name : "NULL");
+	KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
+		    dev->name ? dev->name : "NULL");
+	KLIPS_PRINTMORE(debug_rcv, "\n");
+
+	KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
+		    "klips_debug:ipsec_rcv: "
+		    "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
+		    skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
+		    dev ? (dev->name ? dev->name : "NULL") : "NULL");
+
+	protoc = ipp->protocol;
+#ifndef NET_21
+	if((!protocol) || (protocol->protocol != protoc)) {
+		KLIPS_PRINT(debug_rcv & DB_RX_TDB,
+			    "klips_debug:ipsec_rcv: "
+			    "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
+	}
+#endif /* !NET_21 */
+
+	if( (protoc != IPPROTO_AH) &&
+#ifdef CONFIG_IPSEC_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
+	    (protoc != IPPROTO_COMP) &&
+#endif /* CONFIG_IPSEC_IPCOMP */
+	    (protoc != IPPROTO_ESP) ) {
+		KLIPS_PRINT(debug_rcv & DB_RX_TDB,
+			    "klips_debug:ipsec_rcv: Why the hell is someone "
+			    "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
+			    protoc);
+		goto rcvleave;
+	}
+
+	if(skb->dev) {
+		for(i = 0; i < IPSEC_NUM_IF; i++) {
+			sprintf(name, "ipsec%d", i);
+			if(!strcmp(name, skb->dev->name)) {
+				prv = (struct ipsecpriv *)(skb->dev->priv);
+				if(prv) {
+					stats = (struct net_device_stats *) &(prv->mystats);
+				}
+				ipsecdev = skb->dev;
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
+				break;
+			}
+			if((ipsecdev = ipsec_dev_get(name)) == NULL) {
+				KLIPS_PRINT(debug_rcv,
+					    "klips_error:ipsec_rcv: "
+					    "device %s does not exist\n",
+					    name);
+			}
+			prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
+			prvdev = prv ? (struct device *)(prv->dev) : NULL;
+			
+#if 0
+			KLIPS_PRINT(debug_rcv && prvdev, 
+				    "klips_debug:ipsec_rcv: "
+				    "physical device for device %s is %s\n",
+				    name,
+				    prvdev->name);
+#endif
+			if(prvdev && skb->dev &&
+			   !strcmp(prvdev->name, skb->dev->name)) {
+				stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
+				skb->dev = ipsecdev;
+				KLIPS_PRINT(debug_rcv && prvdev, 
+					    "klips_debug:ipsec_rcv: "
+					    "assigning packet ownership to virtual device %s from physical device %s.\n",
+					    name, prvdev->name);
+				if(stats) {
+					stats->rx_packets++;
+				}
+				break;
+			}
+		}
+	} else {
+		KLIPS_PRINT(debug_rcv, 
+			    "klips_debug:ipsec_rcv: "
+			    "device supplied with skb is NULL\n");
+	}
+			
+	if(!stats) {
+		ipsecdev = NULL;
+	}
+	KLIPS_PRINT((debug_rcv && !stats),
+		    "klips_error:ipsec_rcv: "
+		    "packet received from physical I/F (%s) not connected to ipsec I/F.  Cannot record stats.  May not have SA for decoding.  Is IPSEC traffic expected on this I/F?  Check routing.\n",
+		    skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
+
+	KLIPS_IP_PRINT(debug_rcv, ipp);
+
+	/* begin decapsulating loop here */
+	do {
+		authlen = 0;
+#ifdef CONFIG_IPSEC_ESP
+		espp = NULL;
+		esphlen = 0;
+#endif /* !CONFIG_IPSEC_ESP */
+#ifdef CONFIG_IPSEC_AH
+		ahp = NULL;
+		ahhlen = 0;
+#endif /* CONFIG_IPSEC_AH */
+#ifdef CONFIG_IPSEC_IPCOMP
+		compp = NULL;
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+		len = skb->len;
+		dat = skb->data;
+		ipp = (struct iphdr *)skb->data;
+		proto = ipp->protocol;
+		ipaddr.s_addr = ipp->saddr;
+		addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt));
+		
+		iphlen = ipp->ihl << 2;
+		ipp->check = 0;			/* we know the sum is good */
+		
+#ifdef CONFIG_IPSEC_ESP
+		/* XXX this will need to be 8 for IPv6 */
+		if ((proto == IPPROTO_ESP) && ((len - iphlen) % 4)) {
+			printk("klips_error:ipsec_rcv: "
+			       "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
+			       len - iphlen,
+			       ipaddr_txt);
+			if(stats) {
+				stats->rx_errors++;
+			}
+			goto rcvleave;
+		}
+#endif /* !CONFIG_IPSEC_ESP */
+		
+		/*
+		 * Find tunnel control block and (indirectly) call the
+		 * appropriate tranform routine. The resulting sk_buf
+		 * is a valid IP packet ready to go through input processing.
+		 */
+		
+		said.dst.s_addr = ipp->daddr;
+		switch(proto) {
+#ifdef CONFIG_IPSEC_ESP
+		case IPPROTO_ESP:
+			if(skb->len < (hard_header_len + sizeof(struct iphdr) + sizeof(struct esp))) {
+				KLIPS_PRINT(debug_rcv & DB_RX_INAU,
+					    "klips_debug:ipsec_rcv: "
+					    "runt esp packet of skb->len=%d received from %s, dropped.\n",
+					    skb->len,
+					    ipaddr_txt);
+				if(stats) {
+					stats->rx_errors++;
+				}
+				goto rcvleave;
+			}
+		       
+			espp = (struct esp *)(skb->data + iphlen);
+			said.spi = espp->esp_spi;
+			break;
+#endif /* !CONFIG_IPSEC_ESP */
+#ifdef CONFIG_IPSEC_AH
+		case IPPROTO_AH:
+			if((skb->len 
+			    < (hard_header_len + sizeof(struct iphdr) + sizeof(struct ah)))
+			   || (skb->len 
+			       < (hard_header_len + sizeof(struct iphdr) 
+				  + ((ahp = (struct ah *) (skb->data + iphlen))->ah_hl << 2)))) {
+				KLIPS_PRINT(debug_rcv & DB_RX_INAU,
+					    "klips_debug:ipsec_rcv: "
+					    "runt ah packet of skb->len=%d received from %s, dropped.\n",
+					    skb->len,
+					    ipaddr_txt);
+				if(stats) {
+					stats->rx_errors++;
+				}
+				goto rcvleave;
+			}
+		       
+			said.spi = ahp->ah_spi;
+			break;
+#endif /* CONFIG_IPSEC_AH */
+#ifdef CONFIG_IPSEC_IPCOMP
+		case IPPROTO_COMP:
+			if(skb->len < (hard_header_len + sizeof(struct iphdr) + sizeof(struct ipcomphdr))) {
+				KLIPS_PRINT(debug_rcv & DB_RX_INAU,
+					    "klips_debug:ipsec_rcv: "
+					    "runt comp packet of skb->len=%d received from %s, dropped.\n",
+					    skb->len,
+					    ipaddr_txt);
+				if(stats) {
+					stats->rx_errors++;
+				}
+				goto rcvleave;
+			}
+		       
+			compp = (struct ipcomphdr *)(skb->data + iphlen);
+			said.spi = htonl((__u32)ntohs(compp->ipcomp_cpi));
+			break;
+#endif /* CONFIG_IPSEC_IPCOMP */
+		default:
+			if(stats) {
+				stats->rx_errors++;
+			}
+			goto rcvleave;
+		}
+		said.proto = proto;
+		sa_len = satoa(said, 0, sa, SATOA_BUF);
+		if(sa_len == 0) {
+		  strcpy(sa, "(error)");
+		}
+		
+#ifdef CONFIG_IPSEC_AH
+		if(proto == IPPROTO_AH) {
+			ahhlen = (ahp->ah_hl << 2) +
+				((caddr_t)&(ahp->ah_rpl) - (caddr_t)ahp);
+			next_header = ahp->ah_nh;
+			if (ahhlen != sizeof(struct ah)) {
+				KLIPS_PRINT(debug_rcv & DB_RX_INAU,
+					    "klips_debug:ipsec_rcv: "
+					    "bad authenticator length %d, expected %d from %s.\n",
+					    ahhlen - ((caddr_t)(ahp->ah_data) - (caddr_t)ahp),
+					    AHHMAC_HASHLEN,
+					    ipaddr_txt);
+				if(stats) {
+					stats->rx_errors++;
+				}
+				goto rcvleave;
+			}
+			
+		}
+#endif /* CONFIG_IPSEC_AH */
+		
+		/*
+		  The spinlock is to prevent any other process from
+		  accessing or deleting the TDB hash table or any of the
+		  TDBs while we are using and updating them.
+		  
+		  This is not optimal, but was relatively straightforward
+		  at the time.  A better way to do it has been planned for
+		  more than a year, to lock the hash table and put reference
+		  counts on each TDB instead.  This is not likely to happen
+		  in KLIPS1 unless a volunteer contributes it, but will be
+		  designed into KLIPS2.
+		*/
+		if(tdbprev == NULL) {
+			spin_lock(&tdb_lock);
+		}
+		
+#ifdef CONFIG_IPSEC_IPCOMP
+		if (proto == IPPROTO_COMP) {
+			unsigned int flags = 0;
+			if (tdbp == NULL) {
+				spin_unlock(&tdb_lock);
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n",
+					    sa_len ? sa : " (error)");
+				if(stats) {
+					stats->rx_dropped++;
+				}
+
+				goto rcvleave;
+			}
+
+			tdbprev = tdbp;
+			tdbp = tdbnext;
+
+			if(sysctl_ipsec_inbound_policy_check
+			   && ((tdbp == NULL)
+			       || (((ntohl(tdbp->tdb_said.spi) & 0x0000ffff)
+				    != ntohl(said.spi))
+				/* next line is a workaround for peer
+				   non-compliance with rfc2393 */
+				   && (tdbp->tdb_encalg != ntohl(said.spi)) 
+				       ))) {
+				char sa2[SATOA_BUF];
+				size_t sa_len2 = 0;
+
+				if(tdbp) {
+					sa_len2 = satoa(tdbp->tdb_said, 0, sa2, SATOA_BUF);
+				}
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n",
+					    sa_len ? sa : " (error)",
+					    tdbp ? (sa_len2 ? sa2 : " (error)") : "NULL",
+					    ntohs(compp->ipcomp_cpi),
+					    (__u32)ntohl(said.spi),
+					    tdbp ? (__u32)ntohl((tdbp->tdb_said.spi)) : 0,
+					    tdbp ? (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff) : 0);
+				spin_unlock(&tdb_lock);
+				if(stats) {
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			}
+
+			if (tdbp) {
+				tdbp->tdb_comp_ratio_cbytes += ntohs(ipp->tot_len);
+				tdbnext = tdbp->tdb_inext;
+			}
+			next_header = compp->ipcomp_nh;
+
+			skb = skb_decompress(skb, tdbp, &flags);
+			if (!skb || flags) {
+				spin_unlock(&tdb_lock);
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "skb_decompress() returned error flags=%x, dropped.\n",
+					    flags);
+				if (stats) {
+				    if (flags)
+					stats->rx_errors++;
+				    else
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			}
+#ifdef NET_21
+			ipp = skb->nh.iph;
+#else /* NET_21 */
+			ipp = skb->ip_hdr;
+#endif /* NET_21 */
+
+			if (tdbp) {
+				tdbp->tdb_comp_ratio_dbytes += ntohs(ipp->tot_len);
+			}
+
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
+				    sa_len ? sa : " (error)",
+				    (__u32)ntohl(said.spi),
+				    tdbp ? (__u32)ntohl((tdbp->tdb_said.spi)) : 0,
+				    tdbp ? (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff) : 0,
+				    next_header);
+			KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
+
+			continue;
+			/* Skip rest of stuff and decapsulate next inner
+			   packet, if any */
+		}
+#endif /* CONFIG_IPSEC_IPCOMP */
+		
+		tdbp = ipsec_sa_getbyid(&said);
+		if (tdbp == NULL) {
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "no Tunnel Descriptor Block for SA:%s: incoming packet with no SA dropped\n",
+				    sa_len ? sa : " (error)");
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+		if ((natt_type) &&
+			( (ipp->saddr != (((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr)) ||
+			  (natt_sport != tdbp->ips_natt_sport)
+			)) {
+			struct sockaddr sipaddr;
+			/** Advertise NAT-T addr change to pluto **/
+			sipaddr.sa_family = AF_INET;
+			((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = ipp->saddr;
+			((struct sockaddr_in*)&sipaddr)->sin_port = htons(natt_sport);
+			pfkey_nat_t_new_mapping(tdbp, &sipaddr, natt_sport);
+			/**
+			 * Then allow or block packet depending on
+			 * sysctl_ipsec_inbound_policy_check.
+			 *
+			 * In all cases, pluto will update SA if new mapping is
+			 * accepted.
+			 */
+			if (sysctl_ipsec_inbound_policy_check) {
+				spin_unlock(&tdb_lock);
+				ipaddr.s_addr = ipp->saddr;
+				addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt));
+				KLIPS_PRINT(debug_rcv,
+					"klips_debug:ipsec_rcv: "
+					"SA:%s, src=%s:%u of pkt does not agree with expected "
+					"SA source address policy (pluto has been informed).\n",
+					sa_len ? sa : " (error)",
+					ipaddr_txt, natt_sport);
+				if(stats) {
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			}
+		}
+#endif
+
+		if(sysctl_ipsec_inbound_policy_check) {
+			if(ipp->saddr != ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr) {
+				spin_unlock(&tdb_lock);
+				ipaddr.s_addr = ipp->saddr;
+				addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt));
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
+					    sa_len ? sa : " (error)",
+					    ipaddr_txt);
+				if(stats) {
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			}
+			ipaddr.s_addr = ipp->saddr;
+			addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt));
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
+				    sa_len ? sa : " (error)",
+				    ipaddr_txt);
+			if(tdbnext) {
+				if(tdbnext != tdbp) {
+					spin_unlock(&tdb_lock);
+					KLIPS_PRINT(debug_rcv,
+						    "klips_debug:ipsec_rcv: "
+						    "unexpected SA:%s: does not agree with tdb->inext policy, dropped\n",
+						    sa_len ? sa : " (error)");
+					if(stats) {
+						stats->rx_dropped++;
+					}
+					goto rcvleave;
+				}
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "SA:%s grouping from previous SA is OK.\n",
+					    sa_len ? sa : " (error)");
+			} else {
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "SA:%s First SA in group.\n",
+					    sa_len ? sa : " (error)");
+			}
+			
+			if(tdbp->tdb_onext) {
+				if(tdbprev != tdbp->tdb_onext) {
+					spin_unlock(&tdb_lock);
+					KLIPS_PRINT(debug_rcv,
+						    "klips_debug:ipsec_rcv: "
+						    "unexpected SA:%s: does not agree with tdb->onext policy, dropped.\n",
+						    sa_len ? sa : " (error)");
+					if(stats) {
+						stats->rx_dropped++;
+					}
+					goto rcvleave;
+				} else {
+					KLIPS_PRINT(debug_rcv,
+						    "klips_debug:ipsec_rcv: "
+						    "SA:%s grouping to previous SA is OK.\n",
+						    sa_len ? sa : " (error)");
+				}
+			} else {
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "SA:%s No previous backlink in group.\n",
+					    sa_len ? sa : " (error)");
+			}
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+			KLIPS_PRINT(debug_rcv,
+				"klips_debug:ipsec_rcv: "
+				"natt_type=%u tdbp->ips_natt_type=%u : %s\n",
+				natt_type, tdbp->ips_natt_type,
+				(natt_type==tdbp->ips_natt_type)?"ok":"bad");
+			if (natt_type != tdbp->ips_natt_type) {
+				spin_unlock(&tdb_lock);
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "SA:%s does not agree with expected NAT-T policy.\n",
+					    sa_len ? sa : " (error)");
+				if(stats) {
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			}
+#endif
+		}
+		
+		/* If it is in larval state, drop the packet, we cannot process yet. */
+		if(tdbp->tdb_state == SADB_SASTATE_LARVAL) {
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "TDB in larval state, cannot be used yet, dropping packet.\n");
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+		
+		if(tdbp->tdb_state == SADB_SASTATE_DEAD) {
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "TDB in dead state, cannot be used any more, dropping packet.\n");
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+		
+		if(ipsec_lifetime_check(&tdbp->ips_life.ipl_bytes,   "bytes", sa,
+					ipsec_life_countbased, ipsec_incoming, tdbp) == ipsec_life_harddied ||
+		   ipsec_lifetime_check(&tdbp->ips_life.ipl_addtime, "addtime",sa,
+					ipsec_life_timebased,  ipsec_incoming, tdbp) == ipsec_life_harddied ||
+		   ipsec_lifetime_check(&tdbp->ips_life.ipl_addtime, "usetime",sa,
+					ipsec_life_timebased,  ipsec_incoming, tdbp) == ipsec_life_harddied ||
+		   ipsec_lifetime_check(&tdbp->ips_life.ipl_packets, "packets",sa, 
+					ipsec_life_countbased, ipsec_incoming, tdbp) == ipsec_life_harddied) {
+			ipsec_sa_delchain(tdbp);
+			spin_unlock(&tdb_lock);
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+
+		/* authenticate, if required */
+		idat = dat + iphlen;
+#ifdef CONFIG_IPSEC_ALG
+		if ((ixt_a=IPSEC_ALG_SA_ESP_AUTH(tdbp))) {
+			authlen = AHHMAC_HASHLEN;
+			KLIPS_PRINT(debug_rcv,
+					"klips_debug:ipsec_rcv: "
+					"authalg=%d authlen=%d\n",
+					tdbp->tdb_authalg, authlen);
+		} else
+#endif /* CONFIG_IPSEC_ALG */
+		switch(tdbp->tdb_authalg) {
+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
+		case AH_MD5:
+			authlen = AHHMAC_HASHLEN;
+			break;
+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
+		case AH_SHA:
+			authlen = AHHMAC_HASHLEN;
+			break;
+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
+		case AH_NONE:
+			authlen = 0;
+			break;
+		default:
+			tdbp->tdb_alg_errs += 1;
+			spin_unlock(&tdb_lock);
+			if(stats) {
+				stats->rx_errors++;
+			}
+			goto rcvleave;
+		}
+		ilen = len - iphlen - authlen;
+		if(ilen <= 0) {
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "runt AH packet with no data, dropping.\n");
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+		
+#ifdef CONFIG_IPSEC_ESP
+		KLIPS_PRINT(proto == IPPROTO_ESP && debug_rcv, 
+			    "klips_debug:ipsec_rcv: "
+			    "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
+			    ipaddr_txt,
+			    (__u32)ntohl(espp->esp_rpl),
+			    (__u32)ntohl(*((__u32 *)(espp->esp_iv)    )),
+			    (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
+			    len,
+			    ilen,
+			    sa_len ? sa : " (error)");
+#endif /* !CONFIG_IPSEC_ESP */
+		
+		switch(proto) {
+#ifdef CONFIG_IPSEC_ESP
+		case IPPROTO_ESP:
+			replay = ntohl(espp->esp_rpl);
+			authenticator = &(dat[len - authlen]);
+			break;
+#endif /* !CONFIG_IPSEC_ESP */
+#ifdef CONFIG_IPSEC_AH
+		case IPPROTO_AH:
+			replay = ntohl(ahp->ah_rpl);
+			authenticator = ahp->ah_data;
+			break;
+#endif /* CONFIG_IPSEC_AH */
+		}
+
+		if (!ipsec_checkreplaywindow(tdbp, replay)) {
+			tdbp->tdb_replaywin_errs += 1;
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
+				    "klips_debug:ipsec_rcv: "
+				    "duplicate frame from %s, packet dropped\n",
+				    ipaddr_txt);
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+		
+		/*
+		 * verify authenticator
+		 */
+		
+		KLIPS_PRINT(debug_rcv,
+			    "klips_debug:ipsec_rcv: "
+			    "encalg = %d, authalg = %d.\n",
+			    tdbp->tdb_encalg,
+			    tdbp->tdb_authalg);
+		
+#ifdef CONFIG_IPSEC_ALG
+		if (ixt_a) {
+			KLIPS_PRINT(debug_rcv,
+					"klips_debug:ipsec_rcv: "
+					"ipsec_alg hashing ... ");
+			if(proto == IPPROTO_ESP) {
+				ipsec_alg_sa_esp_hash(tdbp,
+						(caddr_t)espp, ilen,
+						hash, AHHMAC_HASHLEN);
+#ifdef CONFIG_IPSEC_AH
+#ifdef IPSEC_ALG_WHEN_AH_IS_READY
+			} else {
+				ipo = *ipp;
+				ipo.tos = 0;
+				ipo.frag_off = 0;
+				ipo.ttl = 0;
+				ipo.check = 0;
+
+				ipsec_alg_hmac_update(tdbp->tdb_key_a,
+						(caddr_t)&ipo, 
+						sizeof(struct iphdr));
+				ipsec_alg_hmac_update(tdbp->tdb_key_a,
+						(caddr_t)ahp,
+						ahhlen - AHHMAC_HASHLEN);
+				ipsec_alg_hmac_update(tdbp->tdb_key_a,
+						(caddr_t)zeroes,
+						AHHMAC_HASHLEN);
+				ipsec_alg_hmac_hash(tdbp->tdb_key_a,
+						(caddr_t)dat + iphlen + ahhlen,
+						len - iphlen - ahhlen,
+						hash, AHHMAC_HASHLEN);
+#endif
+#endif /* CONFIG_IPSEC_AH */
+			}
+		} else
+#endif /* CONFIG_IPSEC_ALG */
+		if(tdbp->tdb_authalg) {
+			switch(tdbp->tdb_authalg) {
+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
+			case AH_MD5:
+				tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;
+				if(proto == IPPROTO_ESP) {
+					MD5Update(&tctx.md5, (caddr_t)espp, ilen);
+#ifdef CONFIG_IPSEC_AH
+				} else {
+					ipo = *ipp;
+					ipo.tos = 0;	/* mutable RFC 2402 3.3.3.1.1.1 */
+					ipo.frag_off = 0;
+					ipo.ttl = 0;
+					ipo.check = 0;
+					
+					MD5Update(&tctx.md5, (caddr_t)&ipo,
+						  sizeof(struct iphdr));
+					MD5Update(&tctx.md5, (caddr_t)ahp,
+						  ahhlen - AHHMAC_HASHLEN);
+					MD5Update(&tctx.md5, (caddr_t)zeroes,
+						  AHHMAC_HASHLEN);
+					MD5Update(&tctx.md5,
+						  (caddr_t)dat + iphlen + ahhlen,
+						  len - iphlen - ahhlen);
+#endif /* CONFIG_IPSEC_AH */
+				}
+				MD5Final(hash, &tctx.md5);
+				tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;
+				MD5Update(&tctx.md5, hash, AHMD596_ALEN);
+				MD5Final(hash, &tctx.md5);
+				break;
+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
+			case AH_SHA:
+				tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;
+				if(proto == IPPROTO_ESP) {
+					SHA1Update(&tctx.sha1, (caddr_t)espp, ilen);
+#ifdef CONFIG_IPSEC_AH
+				} else {
+					ipo = *ipp;
+					ipo.tos = 0;
+					ipo.frag_off = 0;
+					ipo.ttl = 0;
+					ipo.check = 0;
+					
+					SHA1Update(&tctx.sha1, (caddr_t)&ipo,
+						   sizeof(struct iphdr));
+					SHA1Update(&tctx.sha1, (caddr_t)ahp,
+						   ahhlen - AHHMAC_HASHLEN);
+					SHA1Update(&tctx.sha1, (caddr_t)zeroes,
+						   AHHMAC_HASHLEN);
+					SHA1Update(&tctx.sha1,
+						   (caddr_t)dat + iphlen + ahhlen,
+						   len - iphlen - ahhlen);
+#endif /* CONFIG_IPSEC_AH */
+				}
+				SHA1Final(hash, &tctx.sha1);
+				tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
+				SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
+				SHA1Final(hash, &tctx.sha1);
+				break;
+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
+			case AH_NONE:
+				break;
+			}
+		
+			if(!authenticator) {
+				tdbp->tdb_auth_errs += 1;
+				spin_unlock(&tdb_lock);
+				if(stats) {
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			}
+
+			if (memcmp(hash, authenticator, authlen)) {
+				tdbp->tdb_auth_errs += 1;
+				spin_unlock(&tdb_lock);
+				KLIPS_PRINT(debug_rcv & DB_RX_INAU,
+					    "klips_debug:ipsec_rcv: "
+					    "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
+					    ipaddr_txt,
+					    *(__u32*)&hash[0],
+					    *(__u32*)&hash[4],
+					    *(__u32*)&hash[8],
+					    *(__u32*)authenticator,
+					    *((__u32*)authenticator + 1),
+					    *((__u32*)authenticator + 2));
+				if(stats) {
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			} else {
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "authentication successful.\n");
+			}
+			
+			memset((caddr_t)&tctx, 0, sizeof(tctx));
+			memset(hash, 0, sizeof(hash));
+		}
+
+		/* If the sequence number == 0, expire SA, it had rolled */
+		if(tdbp->tdb_replaywin && !replay /* !tdbp->tdb_replaywin_lastseq */) {
+			ipsec_sa_delchain(tdbp);
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "replay window counter rolled, expiring SA.\n");
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+
+		if (!ipsec_updatereplaywindow(tdbp, replay)) {
+			tdbp->tdb_replaywin_errs += 1;
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
+				    "klips_debug:ipsec_rcv: "
+				    "duplicate frame from %s, packet dropped\n",
+				    ipaddr_txt);
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+		
+		switch(proto) {
+#ifdef CONFIG_IPSEC_ESP
+		case IPPROTO_ESP:
+#ifdef CONFIG_IPSEC_ALG
+			if ((ixt_e=IPSEC_ALG_SA_ESP_ENC(tdbp))) {
+				esphlen = ESP_HEADER_LEN + ixt_e->ixt_ivlen/8;
+				KLIPS_PRINT(debug_rcv,
+						"klips_debug:ipsec_rcv: "
+						"encalg=%d esphlen=%d\n",
+						tdbp->tdb_encalg, esphlen);
+			} else
+#endif /* CONFIG_IPSEC_ALG */
+			switch(tdbp->tdb_encalg) {
+#ifdef CONFIG_IPSEC_ENC_3DES
+			case ESP_3DES:
+				iv[0] = *((__u32 *)(espp->esp_iv)    );
+				iv[1] = *((__u32 *)(espp->esp_iv) + 1);
+				esphlen = sizeof(struct esp);
+				break;
+#endif /* CONFIG_IPSEC_ENC_3DES */
+			default:
+				tdbp->tdb_alg_errs += 1;
+				spin_unlock(&tdb_lock);
+				if(stats) {
+					stats->rx_errors++;
+				}
+				goto rcvleave;
+			}
+			idat += esphlen;
+			ilen -= esphlen;
+			
+#ifdef CONFIG_IPSEC_ALG
+			if (ixt_e)
+			{
+				if (ipsec_alg_esp_encrypt(tdbp, 
+					idat, ilen, espp->esp_iv, 
+					IPSEC_ALG_DECRYPT) <= 0)
+				{
+					spin_unlock(&tdb_lock);
+					printk("klips_error:ipsec_rcv: "
+						"got packet with esplen = %d "
+						"from %s -- should be on "
+						"ENC(%d) octet boundary, "
+						"packet dropped\n",
+							ilen,
+							ipaddr_txt,
+							tdbp->tdb_encalg);
+					stats->rx_errors++;
+					goto rcvleave;
+				}
+			} else
+#endif /* CONFIG_IPSEC_ALG */
+			switch(tdbp->tdb_encalg) {
+#ifdef CONFIG_IPSEC_ENC_3DES
+			case ESP_3DES:
+				if ((ilen) % 8) {
+					tdbp->tdb_encsize_errs += 1;
+					spin_unlock(&tdb_lock);
+					printk("klips_error:ipsec_rcv: "
+					       "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n",
+					       ilen,
+					       ipaddr_txt);
+					if(stats) {
+						stats->rx_errors++;
+					}
+					goto rcvleave;
+				}
+				des_ede3_cbc_encrypt((des_cblock *)idat,
+						     (des_cblock *)idat,
+						     ilen,
+						     ((struct des_eks *)(tdbp->tdb_key_e))[0].ks,
+						     ((struct des_eks *)(tdbp->tdb_key_e))[1].ks,
+						     ((struct des_eks *)(tdbp->tdb_key_e))[2].ks,
+						     (des_cblock *)iv, 0);
+				break;
+#endif /* CONFIG_IPSEC_ENC_3DES */
+			default:
+			}
+			next_header = idat[ilen - 1];
+			padlen = idat[ilen - 2];
+			pad = padlen + 2 + authlen;
+			{
+			        int badpad = 0;
+				
+				KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
+					    "klips_debug:ipsec_rcv: "
+					    "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
+					    padlen);
+				
+				for (i = 1; i <= padlen; i++) {
+					if((i % 16) == 1) {
+						KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
+							    "klips_debug:           %02x:",
+							    i - 1);
+					}
+					KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
+						    " %02x",
+						    idat[ilen - 2 - padlen + i - 1]);
+					if(i != idat[ilen - 2 - padlen + i - 1]) {
+					        badpad = 1;
+					} 
+					if((i % 16) == 0) {
+						KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
+							    "\n");
+					}
+				}
+				if((i % 16) != 1) {
+					KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
+							"\n");
+				}
+				if(badpad) {
+					KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
+						    "klips_debug:ipsec_rcv: "
+						    "warning, decrypted packet from %s has bad padding\n",
+						    ipaddr_txt);
+					KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
+						    "klips_debug:ipsec_rcv: "
+						    "...may be bad decryption -- not dropped\n");
+					tdbp->tdb_encpad_errs += 1;
+				}
+				
+				KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
+					    "klips_debug:ipsec_rcv: "
+					    "packet decrypted from %s: next_header = %d, padding = %d\n",
+					    ipaddr_txt,
+					    next_header,
+					    pad - 2 - authlen);
+			}
+#endif /* !CONFIG_IPSEC_ESP */
+#ifdef CONFIG_IPSEC_AH
+		case IPPROTO_AH:
+			break;
+#endif /* CONFIG_IPSEC_AH */
+		}
+	       
+		/*
+		 *	Discard the original ESP/AH header
+		 */
+		
+		ipp->protocol = next_header;
+		
+		switch(proto) {
+#ifdef CONFIG_IPSEC_ESP
+		case IPPROTO_ESP:
+			ipp->tot_len = htons(ntohs(ipp->tot_len) - (esphlen + pad));
+			memmove((void *)(skb->data + esphlen),
+				(void *)(skb->data), iphlen);
+			if(skb->len < esphlen) {
+				spin_unlock(&tdb_lock);
+				printk(KERN_WARNING
+				       "klips_error:ipsec_rcv: "
+				       "tried to skb_pull esphlen=%d, %d available.  This should never happen, please report.\n",
+				       esphlen, (int)(skb->len));
+				goto rcvleave;
+			}
+			skb_pull(skb, esphlen);
+
+			KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
+				    "klips_debug:ipsec_rcv: "
+				    "trimming to %d.\n",
+				    len - esphlen - pad);
+			if(pad + esphlen <= len) {
+			        skb_trim(skb, len - esphlen - pad);
+			} else {
+				spin_unlock(&tdb_lock);
+			        KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
+				            "klips_debug:ipsec_rcv: "
+					    "bogus packet, size is zero or negative, dropping.\n");
+				goto rcvleave;
+			}
+		break;
+#endif /* !CONFIG_IPSEC_ESP */
+#ifdef CONFIG_IPSEC_AH
+		case IPPROTO_AH:
+			ipp->tot_len = htons(ntohs(ipp->tot_len) - ahhlen);
+			memmove((void *)(skb->data + ahhlen),
+				(void *)(skb->data), iphlen);
+			if(skb->len < ahhlen) {
+				spin_unlock(&tdb_lock);
+				printk(KERN_WARNING
+				       "klips_error:ipsec_rcv: "
+				       "tried to skb_pull ahhlen=%d, %d available.  This should never happen, please report.\n",
+				       ahhlen,
+				       (int)(skb->len));
+				goto rcvleave;
+			}
+			skb_pull(skb, ahhlen);
+			break;
+#endif /* CONFIG_IPSEC_AH */
+		}
+
+
+		/*
+		 *	Adjust pointers
+		 */
+		
+		len = skb->len;
+		dat = skb->data;
+		
+#ifdef NET_21
+/*		skb->h.ipiph=(struct iphdr *)skb->data; */
+		skb->nh.raw = skb->data;
+		skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
+		
+		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+#else /* NET_21 */
+		skb->h.iph=(struct iphdr *)skb->data;
+		skb->ip_hdr=(struct iphdr *)skb->data;
+		memset(skb->proto_priv, 0, sizeof(struct options));
+#endif /* NET_21 */
+		
+		ipp = (struct iphdr *)dat;
+		ipp->check = 0;
+		ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2);
+		
+		KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
+			    "klips_debug:ipsec_rcv: "
+			    "after <%s%s%s>, SA:%s:\n",
+			    IPS_XFORM_NAME(tdbp),
+			    sa_len ? sa : " (error)");
+		KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
+		
+		skb->protocol = htons(ETH_P_IP);
+		skb->ip_summed = 0;
+
+		tdbprev = tdbp;
+		tdbnext = tdbp->tdb_inext;
+		if(sysctl_ipsec_inbound_policy_check) {
+			if(tdbnext) {
+				if(tdbnext->tdb_onext != tdbp) {
+					spin_unlock(&tdb_lock);
+					KLIPS_PRINT(debug_rcv,
+						    "klips_debug:ipsec_rcv: "
+						    "SA:%s, backpolicy does not agree with fwdpolicy.\n",
+						    sa_len ? sa : " (error)");
+					if(stats) {
+						stats->rx_dropped++;
+					}
+					goto rcvleave;
+				}
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "SA:%s, backpolicy agrees with fwdpolicy.\n",
+					    sa_len ? sa : " (error)");
+				if(
+					ipp->protocol != IPPROTO_AH  
+					&& ipp->protocol != IPPROTO_ESP 
+#ifdef CONFIG_IPSEC_IPCOMP
+					&& ipp->protocol != IPPROTO_COMP
+					&& (tdbnext->tdb_said.proto != IPPROTO_COMP
+					    || (tdbnext->tdb_said.proto == IPPROTO_COMP
+						&& tdbnext->tdb_inext))
+#endif /* CONFIG_IPSEC_IPCOMP */
+					&& ipp->protocol != IPPROTO_IPIP
+					&& ipp->protocol != 0xFE  // added to support heartbeats to AT&T SIG/GIG
+					) {
+					spin_unlock(&tdb_lock);
+					KLIPS_PRINT(debug_rcv,
+						    "klips_debug:ipsec_rcv: "
+						    "packet with incomplete policy dropped, last successful SA:%s.\n",
+						    sa_len ? sa : " (error)");
+					if(stats) {
+						stats->rx_dropped++;
+					}
+					goto rcvleave;
+				}
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "SA:%s, Another IPSEC header to process.\n",
+					    sa_len ? sa : " (error)");
+			} else {
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "No tdb_inext from this SA:%s.\n",
+					    sa_len ? sa : " (error)");
+			}
+		}
+
+#ifdef CONFIG_IPSEC_IPCOMP
+		/* update ipcomp ratio counters, even if no ipcomp packet is present */
+		if (tdbnext
+		  && tdbnext->tdb_said.proto == IPPROTO_COMP
+		  && ipp->protocol != IPPROTO_COMP) {
+			tdbnext->tdb_comp_ratio_cbytes += ntohs(ipp->tot_len);
+			tdbnext->tdb_comp_ratio_dbytes += ntohs(ipp->tot_len);
+		}
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+		tdbp->ips_life.ipl_bytes.ipl_count += len;
+		tdbp->ips_life.ipl_bytes.ipl_last   = len;
+
+		if(!tdbp->ips_life.ipl_usetime.ipl_count) {
+			tdbp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
+		}
+		tdbp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
+		tdbp->ips_life.ipl_packets.ipl_count += 1;
+		
+	/* end decapsulation loop here */
+	} while(   (ipp->protocol == IPPROTO_ESP )
+		|| (ipp->protocol == IPPROTO_AH  )
+#ifdef CONFIG_IPSEC_IPCOMP
+		|| (ipp->protocol == IPPROTO_COMP)
+#endif /* CONFIG_IPSEC_IPCOMP */
+		);
+	
+#ifdef CONFIG_IPSEC_IPCOMP
+	if(tdbnext && tdbnext->tdb_said.proto == IPPROTO_COMP) {
+		tdbprev = tdbp;
+		tdbp = tdbnext;
+		tdbnext = tdbp->tdb_inext;
+	}
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	if ((natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
+		/**
+		 * NAT-Traversal and Transport Mode:
+		 *   we need to correct TCP/UDP checksum
+		 *
+		 * If we've got NAT-OA, we can fix checksum without recalculation.
+		 */
+		__u32 natt_oa = tdbp->ips_natt_oa ?
+			((struct sockaddr_in*)(tdbp->ips_natt_oa))->sin_addr.s_addr : 0;
+		__u16 pkt_len = skb->tail - (unsigned char *)ipp;
+		__u16 data_len = pkt_len - (ipp->ihl << 2);
+
+		switch (ipp->protocol) {
+			case IPPROTO_TCP:
+				if (data_len >= sizeof(struct tcphdr)) {
+					struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ipp+ipp->ihl);
+					if (natt_oa) {
+						__u32 buff[2] = { ~natt_oa, ipp->saddr };
+						KLIPS_PRINT(debug_rcv,
+				    		"klips_debug:ipsec_rcv: "
+							"NAT-T & TRANSPORT: "
+							"fix TCP checksum using NAT-OA\n");
+						tcp->check = csum_fold(
+							csum_partial((unsigned char *)buff, sizeof(buff),
+							tcp->check^0xffff));
+					}
+					else {
+						KLIPS_PRINT(debug_rcv,
+			    			"klips_debug:ipsec_rcv: "
+							"NAT-T & TRANSPORT: recalc TCP checksum\n");
+						if (pkt_len > (ntohs(ipp->tot_len)))
+							data_len -= (pkt_len - ntohs(ipp->tot_len));
+						tcp->check = 0;
+						tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
+							data_len, IPPROTO_TCP,
+							csum_partial((unsigned char *)tcp, data_len, 0));
+					}
+				}
+				else {
+					KLIPS_PRINT(debug_rcv,
+			    		"klips_debug:ipsec_rcv: "
+						"NAT-T & TRANSPORT: can't fix TCP checksum\n");
+				}
+				break;
+			case IPPROTO_UDP:
+				if (data_len >= sizeof(struct udphdr)) {
+					struct udphdr *udp = (struct udphdr *)((__u32 *)ipp+ipp->ihl);
+					if (udp->check == 0) {
+						KLIPS_PRINT(debug_rcv,
+				    		"klips_debug:ipsec_rcv: "
+							"NAT-T & TRANSPORT: UDP checksum already 0\n");
+					}
+					else if (natt_oa) {
+						__u32 buff[2] = { ~natt_oa, ipp->saddr };
+						KLIPS_PRINT(debug_rcv,
+				    		"klips_debug:ipsec_rcv: "
+							"NAT-T & TRANSPORT: "
+							"fix UDP checksum using NAT-OA\n");
+						udp->check = csum_fold(
+							csum_partial((unsigned char *)buff, sizeof(buff),
+							udp->check^0xffff));
+					}
+					else {
+						KLIPS_PRINT(debug_rcv,
+				    		"klips_debug:ipsec_rcv: "
+							"NAT-T & TRANSPORT: zero UDP checksum\n");
+						udp->check = 0;
+					}
+				}
+				else {
+					KLIPS_PRINT(debug_rcv,
+			    		"klips_debug:ipsec_rcv: "
+						"NAT-T & TRANSPORT: can't fix UDP checksum\n");
+				}
+				break;
+			default:
+				KLIPS_PRINT(debug_rcv,
+			    	"klips_debug:ipsec_rcv: "
+					"NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
+				break;
+		}
+	}
+#endif
+
+	/*
+	 * XXX this needs to be locked from when it was first looked
+	 * up in the decapsulation loop.  Perhaps it is better to put
+	 * the IPIP decap inside the loop.
+	 */
+	if(tdbnext) {
+		tdbp = tdbnext;
+		sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
+		if((ipp->protocol != IPPROTO_IPIP) && 
+                   ( 0xFE != ipp->protocol))          // added to support AT&T heartbeats to SIG/GIG
+                { 
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "SA:%s, Hey!  How did this get through?  Dropped.\n",
+				    sa_len ? sa : " (error)");
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+		if(sysctl_ipsec_inbound_policy_check) {
+			if((tdbnext = tdbp->tdb_inext)) {
+				char sa2[SATOA_BUF];
+				size_t sa_len2;
+				sa_len2 = satoa(tdbnext->tdb_said, 0, sa2, SATOA_BUF);
+				spin_unlock(&tdb_lock);
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "unexpected SA:%s after IPIP SA:%s\n",
+					    sa_len2 ? sa2 : " (error)",
+					    sa_len ? sa : " (error)");
+				if(stats) {
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			}
+			if(ipp->saddr != ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr) {
+				spin_unlock(&tdb_lock);
+				ipaddr.s_addr = ipp->saddr;
+				addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt));
+				KLIPS_PRINT(debug_rcv,
+					    "klips_debug:ipsec_rcv: "
+					    "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
+					    sa_len ? sa : " (error)",
+					    ipaddr_txt);
+				if(stats) {
+					stats->rx_dropped++;
+				}
+				goto rcvleave;
+			}
+		}
+
+  if(ipp->protocol == IPPROTO_IPIP)  // added to support AT&T heartbeats to SIG/GIG
+  {  
+		/*
+		 * XXX this needs to be locked from when it was first looked
+		 * up in the decapsulation loop.  Perhaps it is better to put
+		 * the IPIP decap inside the loop.
+		 */
+		tdbp->ips_life.ipl_bytes.ipl_count += len;
+		tdbp->ips_life.ipl_bytes.ipl_last   = len;
+
+		if(!tdbp->ips_life.ipl_usetime.ipl_count) {
+			tdbp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
+		}
+		tdbp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
+		tdbp->ips_life.ipl_packets.ipl_count += 1;
+		
+		if(skb->len < iphlen) {
+			spin_unlock(&tdb_lock);
+			printk(KERN_WARNING "klips_debug:ipsec_rcv: "
+			       "tried to skb_pull iphlen=%d, %d available.  This should never happen, please report.\n",
+			       iphlen,
+			       (int)(skb->len));
+
+			goto rcvleave;
+		}
+		skb_pull(skb, iphlen);
+
+#ifdef NET_21
+		ipp = (struct iphdr *)skb->nh.raw = skb->data;
+		skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
+		
+		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+#else /* NET_21 */
+		ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data;
+
+		memset(skb->proto_priv, 0, sizeof(struct options));
+#endif /* NET_21 */
+
+		skb->protocol = htons(ETH_P_IP);
+		skb->ip_summed = 0;
+		KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
+			    "klips_debug:ipsec_rcv: "
+			    "IPIP tunnel stripped.\n");
+		KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
+  }
+
+		if(sysctl_ipsec_inbound_policy_check
+		   /* 
+		      Note: "xor" (^) logically replaces "not equal"
+		      (!=) and "bitwise or" (|) logically replaces
+		      "boolean or" (||).  This is done to speed up
+		      execution by doing only bitwise operations and
+		      no branch operations
+		   */
+		   && (((ipp->saddr & tdbp->tdb_mask_s.u.v4.sin_addr.s_addr)
+			            ^ tdbp->tdb_flow_s.u.v4.sin_addr.s_addr)
+		       | ((ipp->daddr & tdbp->tdb_mask_d.u.v4.sin_addr.s_addr)
+			              ^ tdbp->tdb_flow_d.u.v4.sin_addr.s_addr)) )
+		{
+			struct in_addr daddr, saddr;
+			char saddr_txt[ADDRTOA_BUF], daddr_txt[ADDRTOA_BUF];
+			char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
+			
+			subnettoa(tdbp->tdb_flow_s.u.v4.sin_addr,
+				tdbp->tdb_mask_s.u.v4.sin_addr,
+				0, sflow_txt, sizeof(sflow_txt));
+			subnettoa(tdbp->tdb_flow_d.u.v4.sin_addr,
+				tdbp->tdb_mask_d.u.v4.sin_addr,
+				0, dflow_txt, sizeof(dflow_txt));
+			spin_unlock(&tdb_lock);
+			saddr.s_addr = ipp->saddr;
+			daddr.s_addr = ipp->daddr;
+			addrtoa(saddr, 0, saddr_txt, sizeof(saddr_txt));
+			addrtoa(daddr, 0, daddr_txt, sizeof(daddr_txt));
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
+				    sa_len ? sa : " (error)",
+				    sflow_txt,
+				    dflow_txt,
+				    saddr_txt,
+				    daddr_txt);
+			if(stats) {
+				stats->rx_dropped++;
+			}
+			goto rcvleave;
+		}
+	}
+
+#ifdef INBOUND_POLICY_CHECK_eroute
+	/*
+	  Do *not* enable this without thoroughly checking spinlock issues
+	  first.  In particular, nesting an eroute spinlock within a tdb
+	  spinlock could result in a deadlock.  (Well, only on a SMP machine
+	  under 2.4?)
+	*/
+
+	/*
+	 * First things first -- look us up in the erouting tables.
+	 */
+	matcher.sen_len = sizeof (struct sockaddr_encap);
+	matcher.sen_family = AF_ENCAP;
+	matcher.sen_type = SENT_IP4;
+	if(ipp->protocol == IPPROTO_IPIP) {
+		struct iphdr *ipp2;
+
+		ipp2 = (struct iphdr*) (((char*)ipp) + (ipp->ihl << 2));
+		matcher.sen_ip_src.s_addr = ipp2->saddr;
+		matcher.sen_ip_dst.s_addr = ipp2->daddr;
+	} else {
+		matcher.sen_ip_src.s_addr = ipp->saddr;
+		matcher.sen_ip_dst.s_addr = ipp->daddr;
+	}
+	
+	/*
+	 * The spinlock is to prevent any other process from accessing or
+	 * deleting the eroute while we are using and updating it.
+	 */
+	spin_lock(&eroute_lock);
+	
+	er = ipsec_findroute(&matcher);
+	if(er) {
+		policy_said = er->er_said;
+		policy_eaddr = er->er_eaddr;
+		policy_emask = er->er_emask;
+		er->er_count++;
+		er->er_lasttime = jiffies/HZ;
+	}
+	
+	spin_unlock(&eroute_lock);
+
+	if(er) {
+		/*
+		 * The spinlock is to prevent any other process from
+		 * accessing or deleting the tdb while we are using and
+		 * updating it.
+		 */
+		spin_lock(&tdb_lock);
+
+		policy_tdb = gettdb(&policy_said);
+		if (policy_tdb == NULL) {
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "no Tunnel Descriptor Block for SA%s: incoming packet with no policy SA, dropped.\n",
+				    sa_len ? sa : " (error)");
+			goto rcvleave;
+		}
+		
+		sa_len = satoa(policy_said, 0, sa, SATOA_BUF);
+
+		KLIPS_PRINT(debug_rcv,
+			    "klips_debug:ipsec_rcv: "
+			    "found policy Tunnel Descriptor Block -- SA:%s\n",
+			    sa_len ? sa : " (error)");
+		while(1) {
+			if(policy_tdb->tdb_inext) {
+				policy_tdb = policy_tdb->tdb_inext;
+			} else {
+				break;
+			}
+		}
+		if(policy_tdb != tdbp) {
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_rcv,
+				    "klips_debug:ipsec_rcv: "
+				    "Tunnel Descriptor Block for SA%s: incoming packet with different policy SA, dropped.\n",
+				    sa_len ? sa : " (error)");
+			goto rcvleave;
+		}
+
+		/* spin_unlock(&tdb_lock); */
+	}
+#endif /* INBOUND_POLICY_CHECK_eroute */
+
+	spin_unlock(&tdb_lock);
+
+#ifdef NET_21
+	if(stats) {
+		stats->rx_bytes += skb->len;
+	}
+	if(skb->dst) {
+		dst_release(skb->dst);
+		skb->dst = NULL;
+	}
+	skb->pkt_type = PACKET_HOST;
+	if(hard_header_len &&
+	   (skb->mac.raw != (skb->data - hard_header_len)) &&
+	   (hard_header_len <= skb_headroom(skb))) {
+		/* copy back original MAC header */
+		memmove(skb->data - hard_header_len, skb->mac.raw, hard_header_len);
+		skb->mac.raw = skb->data - hard_header_len;
+	}
+#endif /* NET_21 */
+
+#ifdef CONFIG_IPSEC_IPCOMP
+	if(ipp->protocol == IPPROTO_COMP) {
+		unsigned int flags = 0;
+
+		if(sysctl_ipsec_inbound_policy_check) {
+			KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
+				"klips_debug:ipsec_rcv: "
+				"inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
+			if (stats) {
+				stats->rx_errors++;
+			}
+			goto rcvleave;
+		}
+		/*
+		  XXX need a TDB for updating ratio counters but it is not
+		  following policy anyways so it is not a priority
+		*/
+		skb = skb_decompress(skb, NULL, &flags);
+		if (!skb || flags) {
+			KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
+				"klips_debug:ipsec_rcv: "
+				"skb_decompress() returned error flags: %d, dropped.\n",
+			       flags);
+			if (stats) {
+				stats->rx_errors++;
+			}
+			goto rcvleave;
+		}
+	}
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+#ifdef SKB_RESET_NFCT
+        nf_conntrack_put(skb->nfct);
+        skb->nfct = NULL;
+#ifdef CONFIG_NETFILTER_DEBUG
+	skb->nf_debug = 0;
+#endif /* CONFIG_NETFILTER_DEBUG */
+#endif /* SKB_RESET_NFCT */
+	KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
+		    "klips_debug:ipsec_rcv: "
+		    "netif_rx() called.\n");
+	netif_rx(skb);
+
+	MOD_DEC_USE_COUNT;
+	return(0);
+	
+ rcvleave:
+ 	if(skb) {
+#ifdef NET_21
+                kfree_skb(skb);
+#else /* NET_21 */
+                kfree_skb(skb, FREE_WRITE);
+#endif /* NET_21 */
+	}
+
+	MOD_DEC_USE_COUNT;
+	return(0);
+}
+
+struct inet_protocol ah_protocol =
+{
+	ipsec_rcv,				/* AH handler */
+	NULL,				/* TUNNEL error control */
+	0,				/* next */
+	IPPROTO_AH,			/* protocol ID */
+	0,				/* copy */
+	NULL,				/* data */
+	"AH"				/* name */
+};
+
+struct inet_protocol esp_protocol = 
+{
+	ipsec_rcv,			/* ESP handler          */
+	NULL,				/* TUNNEL error control */
+	0,				/* next */
+	IPPROTO_ESP,			/* protocol ID */
+	0,				/* copy */
+	NULL,				/* data */
+	"ESP"				/* name */
+};
+
+#if 0
+/* We probably don't want to install a pure IPCOMP protocol handler, but
+   only want to handle IPCOMP if it is encapsulated inside an ESP payload
+   (which is already handled) */
+#ifdef CONFIG_IPSEC_IPCOMP
+struct inet_protocol comp_protocol =
+{
+	ipsec_rcv,			/* COMP handler		*/
+	NULL,				/* COMP error control	*/
+	0,				/* next */
+	IPPROTO_COMP,			/* protocol ID */
+	0,				/* copy */
+	NULL,				/* data */
+	"COMP"				/* name */
+};
+#endif /* CONFIG_IPSEC_IPCOMP */
+#endif
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.15  2003/07/04 19:07:34  ken
+ * Added NAT-T 0.6 diff/patch from Tuomo
+ *
+ * Revision 1.14  2003/02/07 13:14:24  ken
+ * Pullin jjo's ALG 0.8.1rc branch
+ *
+ * Revision 1.13.2.1  2003/02/06 22:09:49  jjo
+ * sync to alg-0.8.1-rc4
+ *
+ * Revision 1.13  2003/01/19 23:06:27  ken
+ * Added MTS Patch (fix broken AT&T VPN System for IBM Users) - amcedwards
+ *
+ * Revision 1.12  2003/01/02 21:47:45  ken
+ * NAT-T 0.5
+ *
+ * Revision 1.11  2002/11/05 01:41:46  ken
+ * Pulled  from 1.99
+ *
+ * Revision 1.102.6.6  2002/10/30 17:39:07  rgb
+ * Fixed cut-and-paste error mis-identifying comp runt as ah.
+ *
+ * Revision 1.102.6.5  2002/10/30 05:45:19  rgb
+ * Make sure partial esp/ah/comp headers don't cause oops.
+ *
+ * Revision 1.102.6.4  2002/10/28 19:54:56  sam
+ * Fix scope of shift in AH header length check.
+ *
+ * Revision 1.10  2002/11/05 01:35:58  ken
+ * 1.99cand -> 1.99 Final Code changes
+ *
+ * Revision 1.9  2002/10/26 19:18:48  ken
+ * fixed bad patch of ipsec_rcv.c
+ *
+ * Revision 1.102.6.3  2002/10/25 17:26:40  sam
+ * runt patch applied for DOS
+ *
+ * Revision 1.102.6.2  2002/10/18 05:20:36  sam
+ * Patched with RGB's fix from ipsec_rcv.c v1.109:
+ *
+ * Fixed ESP short packet DOS (and AH and IPCOMP)
+ *
+ * Revision 1.8  2002/10/26 14:32:44  ken
+ * Patch in code from 1.99 for ESP DOS Fix, and RPM build fixes.
+ * patch -p1 -F 3 < ../_kb9-DOSFIX.diff
+ *
+ * Revision 1.7  2002/10/16 00:21:46  ken
+ * Applied JuanJo's NULL Patch
+ *
+ * Revision 1.6  2002/10/16 00:16:50  ken
+ * Backed out David patch in prep for JuanJo's
+ *
+ * Revision 1.5  2002/10/15 18:35:24  ken
+ * Updated README/CHANGES for _kb8
+ *
+ * Revision 1.4  2002/10/15 17:52:47  ken
+ * Added David De Reu's NULL ALG Bugfix
+ *
+ * Revision 1.3  2002/09/05 03:53:52  ken
+ * Added NAT-T Patch
+ *
+ * Revision 1.2  2002/09/05 03:27:08  ken
+ * Applied freeswan-alg-0.8.0-BASE-klips.diff
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.102  2002/01/29 17:17:56  mcr
+ * 	moved include of ipsec_param.h to after include of linux/kernel.h
+ * 	otherwise, it seems that some option that is set in ipsec_param.h
+ * 	screws up something subtle in the include path to kernel.h, and
+ * 	it complains on the snprintf() prototype.
+ *
+ * Revision 1.101  2002/01/29 04:00:52  mcr
+ * 	more excise of kversions.h header.
+ *
+ * Revision 1.100  2002/01/29 02:13:17  mcr
+ * 	introduction of ipsec_kversion.h means that include of
+ * 	ipsec_param.h must preceed any decisions about what files to
+ * 	include to deal with differences in kernel source.
+ *
+ * Revision 1.99  2002/01/28 21:40:59  mcr
+ * 	should use #if to test boolean option rather than #ifdef.
+ *
+ * Revision 1.98  2002/01/20 20:19:36  mcr
+ * 	renamed option to IP_FRAGMENT_LINEARIZE.
+ *
+ * Revision 1.97  2002/01/12 02:55:36  mcr
+ * 	fix for post-2.4.4 to linearize skb's when ESP packet
+ * 	was assembled from fragments.
+ *
+ * Revision 1.96  2001/11/26 09:23:49  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.93.2.2  2001/10/22 20:54:07  mcr
+ * 	include des.h, removed phony prototypes and fixed calling
+ * 	conventions to match real prototypes.
+ *
+ * Revision 1.93.2.1  2001/09/25 02:22:22  mcr
+ * 	struct tdb -> struct ipsec_sa.
+ * 	lifetime checks moved to ipsec_life.c
+ * 	some sa(tdb) manipulation functions renamed.
+ *
+ * Revision 1.95  2001/11/06 19:49:07  rgb
+ * Added variable descriptions.
+ * Removed unauthenticated sequence==0 check to prevent DoS.
+ *
+ * Revision 1.94  2001/10/18 04:45:20  rgb
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
+ * lib/freeswan.h version macros moved to lib/kversions.h.
+ * Other compiler directive cleanups.
+ *
+ * Revision 1.93  2001/09/07 22:17:24  rgb
+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
+ *
+ * Revision 1.92  2001/08/27 19:44:41  rgb
+ * Fix error in comment.
+ *
+ * Revision 1.91  2001/07/20 19:31:48  dhr
+ * [DHR] fix source and destination subnets of policy in diagnostic
+ *
+ * Revision 1.90  2001/07/06 19:51:09  rgb
+ * Added inbound policy checking code for IPIP SAs.
+ * Renamed unused function argument for ease and intuitive naming.
+ *
+ * Revision 1.89  2001/06/22 19:35:23  rgb
+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp
+ * or ah header.
+ * Print protocol if we are handed a non-ipsec packet.
+ *
+ * Revision 1.88  2001/06/20 06:30:47  rgb
+ * Fixed transport mode IPCOMP policy check bug.
+ *
+ * Revision 1.87  2001/06/13 20:58:40  rgb
+ * Added parentheses around assignment used as truth value to silence
+ * compiler.
+ *
+ * Revision 1.86  2001/06/07 22:25:23  rgb
+ * Added a source address policy check for tunnel mode.  It still does
+ * not check client addresses and masks.
+ * Only decapsulate IPIP if it is expected.
+ *
+ * Revision 1.85  2001/05/30 08:14:02  rgb
+ * Removed vestiges of esp-null transforms.
+ *
+ * Revision 1.84  2001/05/27 06:12:11  rgb
+ * Added structures for pid, packet count and last access time to eroute.
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
+ *
+ * Revision 1.83  2001/05/04 16:45:47  rgb
+ * Remove unneeded code.  ipp is not used after this point.
+ *
+ * Revision 1.82  2001/05/04 16:36:00  rgb
+ * Fix skb_cow() call for 2.4.4. (SS)
+ *
+ * Revision 1.81  2001/05/02 14:46:53  rgb
+ * Fix typo for compiler directive to pull IPH back.
+ *
+ * Revision 1.80  2001/04/30 19:46:34  rgb
+ * Update for 2.4.4.  We now receive the skb with skb->data pointing to
+ * h.raw.
+ *
+ * Revision 1.79  2001/04/23 15:01:15  rgb
+ * Added spin_lock() check to prevent double-locking for multiple
+ * transforms and hence kernel lock-ups with SMP kernels.
+ * Minor spin_unlock() adjustments to unlock before non-dependant prints
+ * and IPSEC device stats updates.
+ *
+ * Revision 1.78  2001/04/21 23:04:24  rgb
+ * Check if soft expire has already been sent before sending another to
+ * prevent ACQUIRE flooding.
+ *
+ * Revision 1.77  2001/03/16 07:35:20  rgb
+ * Ditch extra #if 1 around now permanent policy checking code.
+ *
+ * Revision 1.76  2001/02/27 22:24:54  rgb
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
+ * Check for satoa() return codes.
+ *
+ * Revision 1.75  2001/02/19 22:28:30  rgb
+ * Minor change to virtual device discovery code to assert which I/F has
+ * been found.
+ *
+ * Revision 1.74  2000/11/25 03:50:36  rgb
+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
+ *
+ * Revision 1.73  2000/11/09 20:52:15  rgb
+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
+ * include ipcomp and prevent races, renaming some tdb variables that got
+ * forgotten, moving some unlocks to include tdbs and adding a missing
+ * unlock.  Thanks to Svenning for some of these.
+ *
+ * Revision 1.72  2000/11/09 20:11:22  rgb
+ * Minor shuffles to fix non-standard kernel config option selection.
+ *
+ * Revision 1.71  2000/11/06 04:36:18  rgb
+ * Ditched spin_lock_irqsave in favour of spin_lock.
+ * Minor initial protocol check rewrite.
+ * Clean up debug printing.
+ * Clean up tdb handling on ipcomp.
+ * Fixed transport mode null pointer de-reference without ipcomp.
+ * Add Svenning's adaptive content compression.
+ * Disabled registration of ipcomp handler.
+ *
+ * Revision 1.70  2000/10/30 23:41:43  henry
+ * Hans-Joerg Hoexer's null-pointer fix
+ *
+ * Revision 1.69  2000/10/10 18:54:16  rgb
+ * Added a fix for incoming policy check with ipcomp enabled but
+ * uncompressible.
+ *
+ * Revision 1.68  2000/09/22 17:53:12  rgb
+ * Fixed ipcomp tdb pointers update for policy checking.
+ *
+ * Revision 1.67  2000/09/21 03:40:58  rgb
+ * Added more debugging to try and track down the cpi outward copy problem.
+ *
+ * Revision 1.66  2000/09/20 04:00:10  rgb
+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for
+ * debugging oopsen.
+ *
+ * Revision 1.65  2000/09/19 07:07:16  rgb
+ * Added debugging to inbound policy check for ipcomp.
+ * Added missing spin_unlocks (thanks Svenning!).
+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
+ * Protect ipcomp policy check following ipip decap with sysctl switch.
+ *
+ * Revision 1.64  2000/09/18 21:27:29  rgb
+ * 2.0 fixes.
+ *
+ * Revision 1.63  2000/09/18 02:35:50  rgb
+ * Added policy checking to ipcomp and re-enabled policy checking by
+ * default.
+ * Optimised satoa calls.
+ *
+ * Revision 1.62  2000/09/17 21:02:32  rgb
+ * Clean up debugging, removing slow timestamp debug code.
+ *
+ * Revision 1.61  2000/09/16 01:07:55  rgb
+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
+ *
+ * Revision 1.60  2000/09/15 11:37:01  rgb
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
+ * IPCOMP zlib deflate code.
+ *
+ * Revision 1.59  2000/09/15 04:56:20  rgb
+ * Remove redundant satoa() call, reformat comment.
+ *
+ * Revision 1.58  2000/09/13 08:00:52  rgb
+ * Flick on inbound policy checking.
+ *
+ * Revision 1.57  2000/09/12 03:22:19  rgb
+ * Converted inbound_policy_check to sysctl.
+ * Re-enabled policy backcheck.
+ * Moved policy checks to top and within tdb lock.
+ *
+ * Revision 1.56  2000/09/08 19:12:56  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ *
+ * Revision 1.55  2000/08/28 18:15:46  rgb
+ * Added MB's nf-debug reset patch.
+ *
+ * Revision 1.54  2000/08/27 01:41:26  rgb
+ * More minor tweaks to the bad padding debug code.
+ *
+ * Revision 1.53  2000/08/24 16:54:16  rgb
+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
+ * info.
+ * Tidied up device reporting at the start of ipsec_rcv.
+ * Tidied up bad padding debugging and processing.
+ *
+ * Revision 1.52  2000/08/20 21:36:03  rgb
+ * Activated pfkey_expire() calls.
+ * Added a hard/soft expiry parameter to pfkey_expire().
+ * Added sanity checking to avoid propagating zero or smaller-length skbs
+ * from a bogus decryption.
+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
+ *
+ * Revision 1.51  2000/08/18 21:23:30  rgb
+ * Improve bad padding warning so that the printk buffer doesn't get
+ * trampled.
+ *
+ * Revision 1.50  2000/08/01 14:51:51  rgb
+ * Removed _all_ remaining traces of DES.
+ *
+ * Revision 1.49  2000/07/28 13:50:53  rgb
+ * Changed enet_statistics to net_device_stats and added back compatibility
+ * for pre-2.1.19.
+ *
+ * Revision 1.48  2000/05/10 19:14:40  rgb
+ * Only check usetime against soft and hard limits if the tdb has been
+ * used.
+ * Cast output of ntohl so that the broken prototype doesn't make our
+ * compile noisy.
+ *
+ * Revision 1.47  2000/05/09 17:45:43  rgb
+ * Fix replay bitmap corruption bug upon receipt of bogus packet
+ * with correct SPI.  This was a DoS.
+ *
+ * Revision 1.46  2000/03/27 02:31:58  rgb
+ * Fixed authentication failure printout bug.
+ *
+ * Revision 1.45  2000/03/22 16:15:37  rgb
+ * Fixed renaming of dev_get (MB).
+ *
+ * Revision 1.44  2000/03/16 08:17:24  rgb
+ * Hardcode PF_KEYv2 support.
+ * Fixed minor bug checking AH header length.
+ *
+ * Revision 1.43  2000/03/14 12:26:59  rgb
+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
+ *
+ * Revision 1.42  2000/01/26 10:04:04  rgb
+ * Fixed inbound policy checking on transport mode bug.
+ * Fixed noisy 2.0 printk arguments.
+ *
+ * Revision 1.41  2000/01/24 20:58:02  rgb
+ * Improve debugging/reporting support for (disabled) inbound
+ * policy checking.
+ *
+ * Revision 1.40  2000/01/22 23:20:10  rgb
+ * Fixed up inboud policy checking code.
+ * Cleaned out unused crud.
+ *
+ * Revision 1.39  2000/01/21 06:15:29  rgb
+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
+ * Fixed cut-and-paste debug_tunnel to debug_rcv.
+ * Added inbound policy checking code, disabled.
+ * Simplified output code by updating ipp to post-IPIP decapsulation.
+ *
+ * Revision 1.38  1999/12/22 05:08:36  rgb
+ * Checked for null skb, skb->dev, skb->data, skb->dev->name, dev->name,
+ * protocol and take appropriate action for sanity.
+ * Set ipsecdev to NULL if device could not be determined.
+ * Fixed NULL stats access bug if device could not be determined.
+ *
+ * Revision 1.37  1999/12/14 20:07:59  rgb
+ * Added a default switch case to catch bogus encalg values.
+ *
+ * Revision 1.36  1999/12/07 18:57:57  rgb
+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
+ *
+ * Revision 1.35  1999/12/01 22:15:35  rgb
+ * Add checks for LARVAL and DEAD SAs.
+ * Change state of SA from MATURE to DYING when a soft lifetime is
+ * reached and print debug warning.
+ *
+ * Revision 1.34  1999/11/23 23:04:03  rgb
+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
+ * Sort out pfkey and freeswan headers, putting them in a library path.
+ *
+ * Revision 1.33  1999/11/19 01:10:06  rgb
+ * Enable protocol handler structures for static linking.
+ *
+ * Revision 1.32  1999/11/18 04:09:19  rgb
+ * Replaced all kernel version macros to shorter, readable form.
+ *
+ * Revision 1.31  1999/11/17 15:53:39  rgb
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
+ * klips/net/ipsec/Makefile.
+ *
+ * Revision 1.30  1999/10/26 15:09:07  rgb
+ * Used debug compiler directives to shut up compiler for decl/assign
+ * statement.
+ *
+ * Revision 1.29  1999/10/16 18:25:37  rgb
+ * Moved SA lifetime expiry checks before packet processing.
+ * Expire SA on replay counter rollover.
+ *
+ * Revision 1.28  1999/10/16 04:23:07  rgb
+ * Add stats for replaywin_errs, replaywin_max_sequence_difference,
+ * authentication errors, encryption size errors, encryption padding
+ * errors, and time since last packet.
+ *
+ * Revision 1.27  1999/10/16 00:30:47  rgb
+ * Added SA lifetime counting.
+ *
+ * Revision 1.26  1999/10/15 22:14:37  rgb
+ * Add debugging.
+ *
+ * Revision 1.25  1999/10/08 18:37:34  rgb
+ * Fix end-of-line spacing to sate whining PHMs.
+ *
+ * Revision 1.24  1999/10/03 18:54:51  rgb
+ * Spinlock support for 2.3.xx.
+ * Don't forget to undo spinlocks on error!
+ *
+ * Revision 1.23  1999/10/01 15:44:53  rgb
+ * Move spinlock header include to 2.1> scope.
+ *
+ * Revision 1.22  1999/10/01 00:01:54  rgb
+ * Added tdb structure locking.
+ *
+ * Revision 1.21  1999/09/18 11:42:12  rgb
+ * Add Marc Boucher's tcpdump cloned packet fix.
+ *
+ * Revision 1.20  1999/09/17 23:50:25  rgb
+ * Add Marc Boucher's hard_header_len patches.
+ *
+ * Revision 1.19  1999/09/10 05:31:36  henry
+ * tentative fix for 2.0.38-crash bug (move chunk of new code into 2.2 #ifdef)
+ *
+ * Revision 1.18  1999/08/28 08:28:06  rgb
+ * Delete redundant sanity check.
+ *
+ * Revision 1.17  1999/08/28 02:00:58  rgb
+ * Add an extra sanity check for null skbs.
+ *
+ * Revision 1.16  1999/08/27 05:21:38  rgb
+ * Clean up skb->data/raw/nh/h manipulation.
+ * Add Marc Boucher's mods to aid tcpdump.
+ *
+ * Revision 1.15  1999/08/25 14:22:40  rgb
+ * Require 4-octet boundary check only for ESP.
+ *
+ * Revision 1.14  1999/08/11 08:36:44  rgb
+ * Add compiler directives to allow configuring out AH, ESP or transforms.
+ *
+ * Revision 1.13  1999/08/03 17:10:49  rgb
+ * Cosmetic fixes and clarification to debug output.
+ *
+ * Revision 1.12  1999/05/09 03:25:36  rgb
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
+ *
+ * Revision 1.11  1999/05/08 21:23:57  rgb
+ * Add casting to silence the 2.2.x compile.
+ *
+ * Revision 1.10  1999/05/05 22:02:31  rgb
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
+ *
+ * Revision 1.9  1999/04/29 15:18:01  rgb
+ * hange debugging to respond only to debug_rcv.
+ * Change gettdb parameter to a pointer to reduce stack loading and
+ * facilitate parameter sanity checking.
+ *
+ * Revision 1.8  1999/04/15 15:37:24  rgb
+ * Forward check changes from POST1_00 branch.
+ *
+ * Revision 1.4.2.2  1999/04/13 20:32:45  rgb
+ * Move null skb sanity check.
+ * Silence debug a bit more when off.
+ * Use stats more effectively.
+ *
+ * Revision 1.4.2.1  1999/03/30 17:10:32  rgb
+ * Update AH+ESP bugfix.
+ *
+ * Revision 1.7  1999/04/11 00:28:59  henry
+ * GPL boilerplate
+ *
+ * Revision 1.6  1999/04/06 04:54:27  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.5  1999/03/17 15:39:23  rgb
+ * Code clean-up.
+ * Bundling bug fix.
+ * ESP_NULL esphlen and IV bug fix.
+ *
+ * Revision 1.4  1999/02/17 16:51:02  rgb
+ * Ditch NET_IPIP dependancy.
+ * Decapsulate recursively for an entire bundle.
+ *
+ * Revision 1.3  1999/02/12 21:22:47  rgb
+ * Convert debugging printks to KLIPS_PRINT macro.
+ * Clean-up cruft.
+ * Process IPIP tunnels internally.
+ *
+ * Revision 1.2  1999/01/26 02:07:36  rgb
+ * Clean up debug code when switched off.
+ * Remove references to INET_GET_PROTOCOL.
+ *
+ * Revision 1.1  1999/01/21 20:29:11  rgb
+ * Converted from transform switching to algorithm switching.
+ *
+ *
+ * Id: ipsec_esp.c,v 1.16 1998/12/02 03:08:11 rgb Exp $
+ *
+ * Log: ipsec_esp.c,v $
+ * Revision 1.16  1998/12/02 03:08:11  rgb
+ * Fix incoming I/F bug in AH and clean up inconsistencies in the I/F
+ * discovery routine in both AH and ESP.
+ *
+ * Revision 1.15  1998/11/30 13:22:51  rgb
+ * Rationalised all the klips kernel file headers.  They are much shorter
+ * now and won't conflict under RH5.2.
+ *
+ * Revision 1.14  1998/11/10 05:55:37  rgb
+ * Add even more detail to 'wrong I/F' debug statement.
+ *
+ * Revision 1.13  1998/11/10 05:01:30  rgb
+ * Clean up debug output to be quiet when disabled.
+ * Add more detail to 'wrong I/F' debug statement.
+ *
+ * Revision 1.12  1998/10/31 06:39:32  rgb
+ * Fixed up comments in #endif directives.
+ * Tidied up debug printk output.
+ * Convert to addrtoa and satoa where possible.
+ *
+ * Revision 1.11  1998/10/27 00:49:30  rgb
+ * AH+ESP bundling bug has been squished.
+ * Cosmetic brace fixing in code.
+ * Newlines added before calls to ipsec_print_ip.
+ * Fix debug output function ID's.
+ *
+ * Revision 1.10  1998/10/22 06:37:22  rgb
+ * Fixed run-on error message to fit 80 columns.
+ *
+ * Revision 1.9  1998/10/20 02:41:04  rgb
+ * Fixed a replay window size sanity test bug.
+ *
+ * Revision 1.8  1998/10/19 18:55:27  rgb
+ * Added inclusion of freeswan.h.
+ * sa_id structure implemented and used: now includes protocol.
+ * \n bugfix to printk debug message.
+ *
+ * Revision 1.7  1998/10/09 04:23:03  rgb
+ * Fixed possible DoS caused by invalid transform called from an ESP
+ * packet.  This should not be a problem when protocol is added to the SA.
+ * Sanity check added for null xf_input routine.  Sanity check added for null
+ * socket buffer returned from xf_input routine.
+ * Added 'klips_debug' prefix to all klips printk debug statements.
+ *
+ * Revision 1.6  1998/07/14 15:56:04  rgb
+ * Set sdb->dev to virtual ipsec I/F.
+ *
+ * Revision 1.5  1998/06/30 18:07:46  rgb
+ * Change for ah/esp_protocol stuct visible only if module.
+ *
+ * Revision 1.4  1998/06/30 00:12:46  rgb
+ * Clean up a module compile error.
+ *
+ * Revision 1.3  1998/06/25 19:28:06  rgb
+ * Readjust premature unloading of module on packet receipt.
+ * Make protocol structure abailable to rest of kernel.
+ * Use macro for protocol number.
+ *
+ * Revision 1.2  1998/06/23 02:49:34  rgb
+ * Fix minor #include bug that prevented compiling without debugging.
+ * Added code to check for presence of IPIP protocol if an incoming packet
+ * is IPIP encapped.
+ *
+ * Revision 1.1  1998/06/18 21:27:44  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.9  1998/06/14 23:48:42  rgb
+ * Fix I/F name comparison oops bug.
+ *
+ * Revision 1.8  1998/06/11 07:20:04  rgb
+ * Stats fixed for rx_packets.
+ *
+ * Revision 1.7  1998/06/11 05:53:34  rgb
+ * Added stats for rx error and good packet reporting.
+ *
+ * Revision 1.6  1998/06/05 02:27:28  rgb
+ * Add rx_errors stats.
+ * Fix DoS bug:  skb's not being freed on dropped packets.
+ *
+ * Revision 1.5  1998/05/27 21:21:29  rgb
+ * Fix DoS potential bug.  skb was not being freed if the packet was bad.
+ *
+ * Revision 1.4  1998/05/18 22:31:37  rgb
+ * Minor change in debug output and comments.
+ *
+ * Revision 1.3  1998/04/21 21:29:02  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.2  1998/04/12 22:03:19  rgb
+ * Updated ESP-3DES-HMAC-MD5-96,
+ * 	ESP-DES-HMAC-MD5-96,
+ * 	AH-HMAC-MD5-96,
+ * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
+ *
+ * Fixed eroute references in /proc/net/ipsec*.
+ *
+ * Started to patch module unloading memory leaks in ipsec_netlink and
+ * radij tree unloading.
+ *
+ * Revision 1.1  1998/04/09 03:05:59  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:04  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * Minor cosmetic changes.
+ *
+ * Revision 0.3  1996/11/20 14:35:48  ji
+ * Minor Cleanup.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_rcv.h linux-patched/net/ipsec/ipsec_rcv.h
--- linux/net/ipsec/ipsec_rcv.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_rcv.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,177 @@
+/*
+ * 
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+#define DB_RX_PKTRX	0x0001
+#define DB_RX_PKTRX2	0x0002
+#define DB_RX_DMP	0x0004
+#define DB_RX_TDB	0x0010
+#define DB_RX_XF	0x0020
+#define DB_RX_IPAD	0x0040
+#define DB_RX_INAU	0x0080
+#define DB_RX_OINFO	0x0100
+#define DB_RX_OINFO2	0x0200
+#define DB_RX_OH	0x0400
+#define DB_RX_REPLAY	0x0800
+
+#ifdef __KERNEL__
+/* struct options; */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/config.h>	/* for CONFIG_IP_FORWARD */
+#include <linux/version.h>
+#include <freeswan.h>
+
+extern int
+#ifdef PROTO_HANDLER_SINGLE_PARM
+ipsec_rcv(struct sk_buff *skb);
+#else /* PROTO_HANDLER_SINGLE_PARM */
+ipsec_rcv(struct sk_buff *skb,
+#ifdef NET_21
+	  unsigned short xlen);
+#else /* NET_21 */
+	  struct device *dev,
+	  struct options *opt, 
+	  __u32 daddr,
+	  unsigned short len,
+	  __u32 saddr,
+	  int redo,
+	  struct inet_protocol *protocol);
+#endif /* NET_21 */
+#endif /* PROTO_HANDLER_SINGLE_PARM */
+
+#ifdef CONFIG_IPSEC_DEBUG
+extern int debug_rcv;
+#endif /* CONFIG_IPSEC_DEBUG */
+extern int sysctl_ipsec_inbound_policy_check;
+#endif /* __KERNEL__ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.14  2001/09/07 22:15:48  rgb
+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
+ *
+ * Revision 1.13  2001/06/14 19:35:09  rgb
+ * Update copyright date.
+ *
+ * Revision 1.12  2001/03/16 07:36:44  rgb
+ * Fixed #endif comment to sate compiler.
+ *
+ * Revision 1.11  2000/09/21 04:34:21  rgb
+ * Moved declaration of sysctl_ipsec_inbound_policy_check outside
+ * CONFIG_IPSEC_DEBUG. (MB)
+ *
+ * Revision 1.10  2000/09/18 02:36:10  rgb
+ * Exported sysctl_ipsec_inbound_policy_check for skb_decompress().
+ *
+ * Revision 1.9  2000/09/08 19:12:56  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ *
+ * Revision 1.8  1999/11/18 04:09:19  rgb
+ * Replaced all kernel version macros to shorter, readable form.
+ *
+ * Revision 1.7  1999/05/25 01:45:37  rgb
+ * Fix version macros for 2.0.x as a module.
+ *
+ * Revision 1.6  1999/05/08 21:24:27  rgb
+ * Add includes for 2.2.x include into net/ipv4/protocol.c
+ *
+ * Revision 1.5  1999/05/05 22:02:32  rgb
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
+ *
+ * Revision 1.4  1999/04/11 00:28:59  henry
+ * GPL boilerplate
+ *
+ * Revision 1.3  1999/04/06 04:54:27  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.2  1999/01/22 20:06:59  rgb
+ * Fixed cut-and-paste error from ipsec_esp.h.
+ *
+ * Revision 1.1  1999/01/21 20:29:12  rgb
+ * Converted from transform switching to algorithm switching.
+ *
+ * Log: ipsec_esp.h,v 
+ * Revision 1.4  1998/08/12 00:07:32  rgb
+ * Added data structures for new xforms: null, {,3}dessha1.
+ *
+ * Revision 1.3  1998/07/14 15:57:01  rgb
+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
+ *
+ * Revision 1.2  1998/06/25 19:33:46  rgb
+ * Add prototype for protocol receive function.
+ * Rearrange for more logical layout.
+ *
+ * Revision 1.1  1998/06/18 21:27:45  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.6  1998/06/05 02:28:08  rgb
+ * Minor comment fix.
+ *
+ * Revision 1.5  1998/05/27 22:34:00  rgb
+ * Changed structures to accomodate key separation.
+ *
+ * Revision 1.4  1998/05/18 22:28:43  rgb
+ * Disable key printing facilities from /proc/net/ipsec_*.
+ *
+ * Revision 1.3  1998/04/21 21:29:07  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.2  1998/04/12 22:03:20  rgb
+ * Updated ESP-3DES-HMAC-MD5-96,
+ * 	ESP-DES-HMAC-MD5-96,
+ * 	AH-HMAC-MD5-96,
+ * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
+ *
+ * Fixed eroute references in /proc/net/ipsec*.
+ *
+ * Started to patch module unloading memory leaks in ipsec_netlink and
+ * radij tree unloading.
+ *
+ * Revision 1.1  1998/04/09 03:06:00  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:02  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.5  1997/06/03 04:24:48  ji
+ * Added ESP-3DES-MD5-96 transform.
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * Added definitions for new ESP transforms.
+ *
+ * Revision 0.3  1996/11/20 14:35:48  ji
+ * Minor Cleanup.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
+
+
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_sa.c linux-patched/net/ipsec/ipsec_sa.c
--- linux/net/ipsec/ipsec_sa.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_sa.c	Fri Feb  7 13:14:25 2003
@@ -0,0 +1,786 @@
+/*
+ * Common routines for IPsec SA maintenance routines.
+ *
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ * This is the file formerly known as "ipsec_xform.h"
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h> /* printk() */
+
+#include "ipsec_param.h"
+
+#ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+#else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+#endif /* MALLOC_SLAB */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/skbuff.h>
+#include <linux/random.h>	/* get_random_bytes() */
+#include <freeswan.h>
+#ifdef SPINLOCK
+#ifdef SPINLOCK_23
+#include <linux/spinlock.h> /* *lock* */
+#else /* SPINLOCK_23 */
+#include <asm/spinlock.h> /* *lock* */
+#endif /* SPINLOCK_23 */
+#endif /* SPINLOCK */
+#ifdef NET_21
+#include <asm/uaccess.h>
+#include <linux/in6.h>
+#endif
+#include <asm/checksum.h>
+#include <net/ip.h>
+
+#include "radij.h"
+
+#include "ipsec_stats.h"
+#include "ipsec_life.h"
+#include "ipsec_sa.h"
+#include "ipsec_xform.h"
+
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+#include "ipsec_netlink.h"
+#include "ipsec_xform.h"
+#include "ipsec_ipe4.h"
+#include "ipsec_ah.h"
+#include "ipsec_esp.h"
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#include "ipsec_proto.h"
+#include "ipsec_alg.h"
+
+
+#ifdef CONFIG_IPSEC_DEBUG
+int debug_xform = 0;
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
+
+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
+#ifdef SPINLOCK
+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
+#else /* SPINLOCK */
+spinlock_t tdb_lock;
+#endif /* SPINLOCK */
+
+int
+ipsec_sadb_init(void)
+{
+	int i;
+
+	for(i = 1; i < SADB_HASHMOD; i++) {
+		ipsec_sadb_hash[i] = NULL;
+	}
+	return 0;
+}
+
+struct ipsec_sa *
+ipsec_sa_getbyid(struct sa_id *said)
+{
+	int hashval;
+	struct ipsec_sa *ips;
+        char sa[SATOA_BUF];
+	size_t sa_len;
+
+	if(!said) {
+		KLIPS_PRINT(debug_xform,
+			    "klips_error:gettdb: "
+			    "null pointer passed in!\n");
+		return NULL;
+	}
+
+	sa_len = satoa(*said, 0, sa, SATOA_BUF);
+
+	hashval = (said->spi+said->dst.s_addr+said->proto) % SADB_HASHMOD;
+	
+	KLIPS_PRINT(debug_xform,
+		    "klips_debug:gettdb: "
+		    "linked entry in tdb table for hash=%d of SA:%s requested.\n",
+		    hashval,
+		    sa_len ? sa : " (error)");
+
+	if(!(ips = ipsec_sadb_hash[hashval])) {
+		KLIPS_PRINT(debug_xform,
+			    "klips_debug:gettdb: "
+			    "no entries in tdb table for hash=%d of SA:%s.\n",
+			    hashval,
+			    sa_len ? sa : " (error)");
+		return NULL;
+	}
+
+	for (; ips; ips = ips->ips_hnext) {
+		if ((ips->ips_said.spi == said->spi) &&
+		    (ips->ips_said.dst.s_addr == said->dst.s_addr) &&
+		    (ips->ips_said.proto == said->proto)) {
+			return ips;
+		}
+	}
+	
+	KLIPS_PRINT(debug_xform,
+		    "klips_debug:gettdb: "
+		    "no entry in linked list for hash=%d of SA:%s.\n",
+		    hashval,
+		    sa_len ? sa : " (error)");
+	return NULL;
+}
+
+/*
+  The tdb table better *NOT* be locked before it is handed in, or SMP locks will happen
+*/
+int
+ipsec_sa_put(struct ipsec_sa *ips)
+{
+	int error = 0;
+	unsigned int hashval;
+
+	if(!ips) {
+		KLIPS_PRINT(debug_xform,
+			    "klips_error:puttdb: "
+			    "null pointer passed in!\n");
+		return -ENODATA;
+	}
+	hashval = ((ips->ips_said.spi + ips->ips_said.dst.s_addr + ips->ips_said.proto) % SADB_HASHMOD);
+
+	spin_lock_bh(&tdb_lock);
+	
+	ips->ips_hnext = ipsec_sadb_hash[hashval];
+	ipsec_sadb_hash[hashval] = ips;
+	
+	spin_unlock_bh(&tdb_lock);
+
+	return error;
+}
+
+/*
+  The tdb table better be locked before it is handed in, or races might happen
+*/
+int
+ipsec_sa_del(struct ipsec_sa *ips)
+{
+	unsigned int hashval;
+	struct ipsec_sa *tdbtp;
+        char sa[SATOA_BUF];
+	size_t sa_len;
+
+	if(!ips) {
+		KLIPS_PRINT(debug_xform,
+			    "klips_error:deltdb: "
+			    "null pointer passed in!\n");
+		return -ENODATA;
+	}
+	
+	sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
+	if(ips->ips_inext || ips->ips_onext) {
+		KLIPS_PRINT(debug_xform,
+			    "klips_error:deltdb: "
+			    "SA:%s still linked!\n",
+			    sa_len ? sa : " (error)");
+		return -EMLINK;
+	}
+	
+	hashval = ((ips->ips_said.spi + ips->ips_said.dst.s_addr + ips->ips_said.proto) % SADB_HASHMOD);
+	
+	KLIPS_PRINT(debug_xform,
+		    "klips_debug:deltdb: "
+		    "deleting SA:%s, hashval=%d.\n",
+		    sa_len ? sa : " (error)",
+		    hashval);
+	if(!ipsec_sadb_hash[hashval]) {
+		KLIPS_PRINT(debug_xform,
+			    "klips_debug:deltdb: "
+			    "no entries in tdb table for hash=%d of SA:%s.\n",
+			    hashval,
+			    sa_len ? sa : " (error)");
+		return -ENOENT;
+	}
+	
+	if (ips == ipsec_sadb_hash[hashval]) {
+		ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
+		ips->ips_hnext = NULL;
+		KLIPS_PRINT(debug_xform,
+			    "klips_debug:deltdb: "
+			    "successfully deleted first tdb in chain.\n");
+		return 0;
+	} else {
+		for (tdbtp = ipsec_sadb_hash[hashval];
+		     tdbtp;
+		     tdbtp = tdbtp->ips_hnext) {
+			if (tdbtp->ips_hnext == ips) {
+				tdbtp->ips_hnext = ips->ips_hnext;
+				ips->ips_hnext = NULL;
+				KLIPS_PRINT(debug_xform,
+					    "klips_debug:deltdb: "
+					    "successfully deleted link in tdb chain.\n");
+				return 0;
+			}
+		}
+	}
+	
+	KLIPS_PRINT(debug_xform,
+		    "klips_debug:deltdb: "
+		    "no entries in linked list for hash=%d of SA:%s.\n",
+		    hashval,
+		    sa_len ? sa : " (error)");
+	return -ENOENT;
+}
+
+/*
+  The tdb table better be locked before it is handed in, or races might happen
+*/
+int
+ipsec_sa_delchain(struct ipsec_sa *ips)
+{
+	struct ipsec_sa *tdbdel;
+	int error = 0;
+        char sa[SATOA_BUF];
+	size_t sa_len;
+
+	if(!ips) {
+		KLIPS_PRINT(debug_xform,
+			    "klips_error:deltdbchain: "
+			    "null pointer passed in!\n");
+		return -ENODATA;
+	}
+
+	sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
+	KLIPS_PRINT(debug_xform,
+		    "klips_debug:deltdbchain: "
+		    "passed SA:%s\n",
+		    sa_len ? sa : " (error)");
+	while(ips->ips_onext) {
+		ips = ips->ips_onext;
+	}
+
+	while(ips) {
+		/* XXX send a pfkey message up to advise of deleted TDB */
+		sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
+		KLIPS_PRINT(debug_xform,
+			    "klips_debug:deltdbchain: "
+			    "unlinking and delting SA:%s",
+			    sa_len ? sa : " (error)");
+		tdbdel = ips;
+		ips = ips->ips_inext;
+		if(ips) {
+			sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
+			KLIPS_PRINT(debug_xform,
+				    ", inext=%s",
+				    sa_len ? sa : " (error)");
+			tdbdel->ips_inext = NULL;
+			ips->ips_onext = NULL;
+		}
+		KLIPS_PRINT(debug_xform,
+			    ".\n");
+		if((error = ipsec_sa_del(tdbdel))) {
+			KLIPS_PRINT(debug_xform,
+				    "klips_debug:deltdbchain: "
+				    "deltdb returned error %d.\n", -error);
+			return error;
+		}
+		if((error = ipsec_sa_wipe(tdbdel))) {
+			KLIPS_PRINT(debug_xform,
+				    "klips_debug:deltdbchain: "
+				    "ipsec_tdbwipe returned error %d.\n", -error);
+			return error;
+		}
+	}
+	return error;
+}
+
+int 
+ipsec_sadb_cleanup(__u8 proto)
+{
+	int i;
+	int error = 0;
+	struct ipsec_sa *ips, **ipsprev, *tdbdel;
+        char sa[SATOA_BUF];
+	size_t sa_len;
+
+	KLIPS_PRINT(debug_xform,
+		    "klips_debug:ipsec_tdbcleanup: "
+		    "cleaning up proto=%d.\n",
+		    proto);
+
+	spin_lock_bh(&tdb_lock);
+
+	for (i = 0; i < SADB_HASHMOD; i++) {
+		ipsprev = &(ipsec_sadb_hash[i]);
+		ips = ipsec_sadb_hash[i];
+		for(; ips;) {
+			sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
+			KLIPS_PRINT(debug_xform,
+				    "klips_debug:ipsec_tdbcleanup: "
+				    "checking SA:%s, hash=%d",
+				    sa_len ? sa : " (error)",
+				    i);
+			tdbdel = ips;
+			ips = tdbdel->ips_hnext;
+			if(ips) {
+				sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
+				KLIPS_PRINT(debug_xform,
+					    ", hnext=%s",
+					    sa_len ? sa : " (error)");
+			}
+			if(*ipsprev) {
+				sa_len = satoa((*ipsprev)->ips_said, 0, sa, SATOA_BUF);
+				KLIPS_PRINT(debug_xform,
+					    ", *ipsprev=%s",
+					    sa_len ? sa : " (error)");
+				if((*ipsprev)->ips_hnext) {
+					sa_len = satoa((*ipsprev)->ips_hnext->ips_said, 0, sa, SATOA_BUF);
+					KLIPS_PRINT(debug_xform,
+						    ", *ipsprev->ips_hnext=%s",
+						    sa_len ? sa : " (error)");
+				}
+			}
+			KLIPS_PRINT(debug_xform,
+				    ".\n");
+			if(!proto || (proto == tdbdel->ips_said.proto)) {
+				sa_len = satoa(tdbdel->ips_said, 0, sa, SATOA_BUF);
+				KLIPS_PRINT(debug_xform,
+					    "klips_debug:ipsec_tdbcleanup: "
+					    "deleting SA chain:%s.\n",
+					    sa_len ? sa : " (error)");
+				if((error = ipsec_sa_delchain(tdbdel))) {
+					SENDERR(-error);
+				}
+				ipsprev = &(ipsec_sadb_hash[i]);
+				ips = ipsec_sadb_hash[i];
+
+				KLIPS_PRINT(debug_xform,
+					    "klips_debug:ipsec_tdbcleanup: "
+					    "deleted SA chain:%s",
+					    sa_len ? sa : " (error)");
+				if(ips) {
+					sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
+					KLIPS_PRINT(debug_xform,
+						    ", tdbh[%d]=%s",
+						    i,
+						    sa_len ? sa : " (error)");
+				}
+				if(*ipsprev) {
+					sa_len = satoa((*ipsprev)->ips_said, 0, sa, SATOA_BUF);
+					KLIPS_PRINT(debug_xform,
+						    ", *ipsprev=%s",
+						    sa_len ? sa : " (error)");
+					if((*ipsprev)->ips_hnext) {
+						sa_len = satoa((*ipsprev)->ips_hnext->ips_said, 0, sa, SATOA_BUF);
+						KLIPS_PRINT(debug_xform,
+							    ", *ipsprev->ips_hnext=%s",
+							    sa_len ? sa : " (error)");
+					}
+				}
+				KLIPS_PRINT(debug_xform,
+					    ".\n");
+			} else {
+				ipsprev = &tdbdel;
+			}
+		}
+	}
+ errlab:
+
+	spin_unlock_bh(&tdb_lock);
+
+	return(error);
+}
+
+int
+ipsec_sa_wipe(struct ipsec_sa *ips)
+{
+	if(!ips) {
+		return -ENODATA;
+	}
+
+	if(ips->ips_addr_s) {
+		memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
+		kfree(ips->ips_addr_s);
+	}
+	ips->ips_addr_s = NULL;
+
+	if(ips->ips_addr_d) {
+		memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
+		kfree(ips->ips_addr_d);
+	}
+	ips->ips_addr_d = NULL;
+
+	if(ips->ips_addr_p) {
+		memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
+		kfree(ips->ips_addr_p);
+	}
+	ips->ips_addr_p = NULL;
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	if(ips->ips_natt_oa) {
+		memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
+		kfree(ips->ips_natt_oa);
+	}
+	ips->ips_natt_oa = NULL;
+#endif
+
+	if(ips->ips_key_a) {
+		memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
+		kfree(ips->ips_key_a);
+	}
+	ips->ips_key_a = NULL;
+
+	if(ips->ips_key_e) {
+#ifdef CONFIG_IPSEC_ALG
+		if (ips->ips_alg_enc&&ips->ips_alg_enc->ixt_e_destroy_key) {
+			ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc, 
+					ips->ips_key_e);
+		} else {
+#endif /* CONFIG_IPSEC_ALG */
+		memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
+		kfree(ips->ips_key_e);
+#ifdef CONFIG_IPSEC_ALG
+		}
+#endif /* CONFIG_IPSEC_ALG */
+	}
+	ips->ips_key_e = NULL;
+
+	if(ips->ips_iv) {
+		memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
+		kfree(ips->ips_iv);
+	}
+	ips->ips_iv = NULL;
+
+	if(ips->ips_ident_s.data) {
+		memset((caddr_t)(ips->ips_ident_s.data),
+                       0,
+		       ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
+		kfree(ips->ips_ident_s.data);
+        }
+	ips->ips_ident_s.data = NULL;
+	
+	if(ips->ips_ident_d.data) {
+		memset((caddr_t)(ips->ips_ident_d.data),
+                       0,
+		       ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
+		kfree(ips->ips_ident_d.data);
+        }
+	ips->ips_ident_d.data = NULL;
+
+#ifdef CONFIG_IPSEC_ALG
+	if (ips->ips_alg_enc||ips->ips_alg_auth) {
+		ipsec_alg_sa_wipe(ips);
+	}
+#endif /* CONFIG_IPSEC_ALG */
+	
+	memset((caddr_t)ips, 0, sizeof(*ips));
+	kfree(ips);
+	ips = NULL;
+
+	return 0;
+}
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.5  2003/02/07 13:14:25  ken
+ * Pullin jjo's ALG 0.8.1rc branch
+ *
+ * Revision 1.4.2.1  2003/02/06 22:09:50  jjo
+ * sync to alg-0.8.1-rc4
+ *
+ * Revision 1.4  2002/10/30 12:41:26  ken
+ * #ifdef around ipsec_alg_sa_wipe when not using ALGs
+ *
+ * Revision 1.3  2002/09/05 03:53:52  ken
+ * Added NAT-T Patch
+ *
+ * Revision 1.2  2002/09/05 03:27:08  ken
+ * Applied freeswan-alg-0.8.0-BASE-klips.diff
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.5  2002/01/29 17:17:56  mcr
+ * 	moved include of ipsec_param.h to after include of linux/kernel.h
+ * 	otherwise, it seems that some option that is set in ipsec_param.h
+ * 	screws up something subtle in the include path to kernel.h, and
+ * 	it complains on the snprintf() prototype.
+ *
+ * Revision 1.4  2002/01/29 04:00:52  mcr
+ * 	more excise of kversions.h header.
+ *
+ * Revision 1.3  2002/01/29 02:13:18  mcr
+ * 	introduction of ipsec_kversion.h means that include of
+ * 	ipsec_param.h must preceed any decisions about what files to
+ * 	include to deal with differences in kernel source.
+ *
+ * Revision 1.2  2001/11/26 09:16:15  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.2  2001/10/22 21:05:41  mcr
+ * 	removed phony prototype for des_set_key.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:24:57  mcr
+ * 	struct tdb -> struct ipsec_sa.
+ * 	sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
+ * 	ipsec_xform.c removed. header file still contains useful things.
+ *
+ *
+ *
+ * CLONED from ipsec_xform.c:
+ * Revision 1.53  2001/09/08 21:13:34  rgb
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
+ *
+ * Revision 1.52  2001/06/14 19:35:11  rgb
+ * Update copyright date.
+ *
+ * Revision 1.51  2001/05/30 08:14:03  rgb
+ * Removed vestiges of esp-null transforms.
+ *
+ * Revision 1.50  2001/05/03 19:43:18  rgb
+ * Initialise error return variable.
+ * Update SENDERR macro.
+ * Fix sign of error return code for ipsec_tdbcleanup().
+ * Use more appropriate return code for ipsec_tdbwipe().
+ *
+ * Revision 1.49  2001/04/19 18:56:17  rgb
+ * Fixed tdb table locking comments.
+ *
+ * Revision 1.48  2001/02/27 22:24:55  rgb
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
+ * Check for satoa() return codes.
+ *
+ * Revision 1.47  2000/11/06 04:32:08  rgb
+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
+ *
+ * Revision 1.46  2000/09/20 16:21:57  rgb
+ * Cleaned up ident string alloc/free.
+ *
+ * Revision 1.45  2000/09/08 19:16:51  rgb
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
+ *
+ * Revision 1.44  2000/08/30 05:29:04  rgb
+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
+ *
+ * Revision 1.43  2000/08/18 21:30:41  rgb
+ * Purged all tdb_spi, tdb_proto and tdb_dst macros.  They are unclear.
+ *
+ * Revision 1.42  2000/08/01 14:51:51  rgb
+ * Removed _all_ remaining traces of DES.
+ *
+ * Revision 1.41  2000/07/28 14:58:31  rgb
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
+ *
+ * Revision 1.40  2000/06/28 05:50:11  rgb
+ * Actually set iv_bits.
+ *
+ * Revision 1.39  2000/05/10 23:11:09  rgb
+ * Added netlink debugging output.
+ * Added a cast to quiet down the ntohl bug.
+ *
+ * Revision 1.38  2000/05/10 19:18:42  rgb
+ * Cast output of ntohl so that the broken prototype doesn't make our
+ * compile noisy.
+ *
+ * Revision 1.37  2000/03/16 14:04:59  rgb
+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
+ *
+ * Revision 1.36  2000/01/26 10:11:28  rgb
+ * Fixed spacing in error text causing run-in words.
+ *
+ * Revision 1.35  2000/01/21 06:17:16  rgb
+ * Tidied up compiler directive indentation for readability.
+ * Added ictx,octx vars for simplification.(kravietz)
+ * Added macros for HMAC padding magic numbers.(kravietz)
+ * Fixed missing key length reporting bug.
+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
+ *
+ * Revision 1.34  1999/12/08 00:04:19  rgb
+ * Fixed SA direction overwriting bug for netlink users.
+ *
+ * Revision 1.33  1999/12/01 22:16:44  rgb
+ * Minor formatting changes in ESP MD5 initialisation.
+ *
+ * Revision 1.32  1999/11/25 09:06:36  rgb
+ * Fixed error return messages, should be returning negative numbers.
+ * Implemented SENDERR macro for propagating error codes.
+ * Added debug message and separate error code for algorithms not compiled
+ * in.
+ *
+ * Revision 1.31  1999/11/23 23:06:26  rgb
+ * Sort out pfkey and freeswan headers, putting them in a library path.
+ *
+ * Revision 1.30  1999/11/18 04:09:20  rgb
+ * Replaced all kernel version macros to shorter, readable form.
+ *
+ * Revision 1.29  1999/11/17 15:53:40  rgb
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
+ * klips/net/ipsec/Makefile.
+ *
+ * Revision 1.28  1999/10/18 20:04:01  rgb
+ * Clean-out unused cruft.
+ *
+ * Revision 1.27  1999/10/03 19:01:03  rgb
+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
+ *
+ * Revision 1.26  1999/10/01 16:22:24  rgb
+ * Switch from assignment init. to functional init. of spinlocks.
+ *
+ * Revision 1.25  1999/10/01 15:44:54  rgb
+ * Move spinlock header include to 2.1> scope.
+ *
+ * Revision 1.24  1999/10/01 00:03:46  rgb
+ * Added tdb structure locking.
+ * Minor formatting changes.
+ * Add function to initialize tdb hash table.
+ *
+ * Revision 1.23  1999/05/25 22:42:12  rgb
+ * Add deltdbchain() debugging.
+ *
+ * Revision 1.22  1999/05/25 21:24:31  rgb
+ * Add debugging statements to deltdbchain().
+ *
+ * Revision 1.21  1999/05/25 03:51:48  rgb
+ * Refix error return code.
+ *
+ * Revision 1.20  1999/05/25 03:34:07  rgb
+ * Fix error return for flush.
+ *
+ * Revision 1.19  1999/05/09 03:25:37  rgb
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
+ *
+ * Revision 1.18  1999/05/05 22:02:32  rgb
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
+ *
+ * Revision 1.17  1999/04/29 15:20:16  rgb
+ * Change gettdb parameter to a pointer to reduce stack loading and
+ * facilitate parameter sanity checking.
+ * Add sanity checking for null pointer arguments.
+ * Add debugging instrumentation.
+ * Add function deltdbchain() which will take care of unlinking,
+ * zeroing and deleting a chain of tdbs.
+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
+ * structures.
+ *
+ * Revision 1.16  1999/04/16 15:36:29  rgb
+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
+ *
+ * Revision 1.15  1999/04/11 00:29:01  henry
+ * GPL boilerplate
+ *
+ * Revision 1.14  1999/04/06 04:54:28  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.13  1999/02/19 18:23:01  rgb
+ * Nix debug off compile warning.
+ *
+ * Revision 1.12  1999/02/17 16:52:16  rgb
+ * Consolidate satoa()s for space and speed efficiency.
+ * Convert DEBUG_IPSEC to KLIPS_PRINT
+ * Clean out unused cruft.
+ * Ditch NET_IPIP dependancy.
+ * Loop for 3des key setting.
+ *
+ * Revision 1.11  1999/01/26 02:09:05  rgb
+ * Remove ah/esp/IPIP switching on include files.
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
+ * Removed dead code.
+ * Clean up debug code when switched off.
+ * Remove references to INET_GET_PROTOCOL.
+ * Added code exclusion macros to reduce code from unused algorithms.
+ *
+ * Revision 1.10  1999/01/22 06:28:55  rgb
+ * Cruft clean-out.
+ * Put random IV generation in kernel.
+ * Added algorithm switch code.
+ * Enhanced debugging.
+ * 64-bit clean-up.
+ *
+ * Revision 1.9  1998/11/30 13:22:55  rgb
+ * Rationalised all the klips kernel file headers.  They are much shorter
+ * now and won't conflict under RH5.2.
+ *
+ * Revision 1.8  1998/11/25 04:59:06  rgb
+ * Add conditionals for no IPIP tunnel code.
+ * Delete commented out code.
+ *
+ * Revision 1.7  1998/10/31 06:50:41  rgb
+ * Convert xform ASCII names to no spaces.
+ * Fixed up comments in #endif directives.
+ *
+ * Revision 1.6  1998/10/19 14:44:28  rgb
+ * Added inclusion of freeswan.h.
+ * sa_id structure implemented and used: now includes protocol.
+ *
+ * Revision 1.5  1998/10/09 04:32:19  rgb
+ * Added 'klips_debug' prefix to all klips printk debug statements.
+ *
+ * Revision 1.4  1998/08/12 00:11:31  rgb
+ * Added new xform functions to the xform table.
+ * Fixed minor debug output spelling error.
+ *
+ * Revision 1.3  1998/07/09 17:45:31  rgb
+ * Clarify algorithm not available message.
+ *
+ * Revision 1.2  1998/06/23 03:00:51  rgb
+ * Check for presence of IPIP protocol if it is setup one way (we don't
+ * know what has been set up the other way and can only assume it will be
+ * symmetrical with the exception of keys).
+ *
+ * Revision 1.1  1998/06/18 21:27:51  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.3  1998/06/11 05:54:59  rgb
+ * Added transform version string pointer to xformsw initialisations.
+ *
+ * Revision 1.2  1998/04/21 21:28:57  rgb
+ * Rearrange debug switches to change on the fly debug output from user
+ * space.  Only kernel changes checked in at this time.  radij.c was also
+ * changed to temporarily remove buggy debugging code in rj_delete causing
+ * an OOPS and hence, netlink device open errors.
+ *
+ * Revision 1.1  1998/04/09 03:06:13  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:02  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.5  1997/06/03 04:24:48  ji
+ * Added ESP-3DES-MD5-96
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * Added new transforms.
+ *
+ * Revision 0.3  1996/11/20 14:39:04  ji
+ * Minor cleanups.
+ * Rationalized debugging code.
+ *
+ * Revision 0.2  1996/11/02 00:18:33  ji
+ * First limited release.
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_sa.h linux-patched/net/ipsec/ipsec_sa.h
--- linux/net/ipsec/ipsec_sa.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_sa.h	Thu Sep  5 04:53:52 2002
@@ -0,0 +1,215 @@
+/*
+ * @(#) Definitions of IPsec Security Association (ipsec_sa)
+ *
+ * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
+ *                 and Michael Richardson  <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
+ *
+ */
+
+/* 
+ * This file describes the IPsec Security Association Structure.
+ *
+ * This structure keeps track of a single transform that may be done
+ * to a set of packets. It can describe applying the transform or
+ * apply the reverse. (e.g. compression vs expansion). However, it
+ * only describes one at a time. To describe both, two structures would
+ * be used, but since the sides of the transform are performed 
+ * on different machines typically it is usual to have only one side
+ * of each association.
+ * 
+ */
+
+#ifndef _IPSEC_SA_H_
+
+#include "ipsec_stats.h"
+#include "ipsec_life.h"
+#include "ipsec_eroute.h"
+
+/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
+struct ipsec_sa 	                        
+{
+	atomic_t         ips_usecount;       /* use count for this struct */
+	struct ipsec_sa	*ips_hnext;	     /* next in hash chain */
+	struct ipsec_sa	*ips_inext;	     /* pointer to next xform */
+	struct ipsec_sa	*ips_onext;	     /* pointer to prev xform */
+
+	struct ifnet	*ips_rcvif;	     /* related rcv encap interface */
+
+	struct sa_id	ips_said;	     /* SA ID */
+
+	__u32		ips_seq;    /* seq num of msg that initiated this SA */
+	__u32		ips_pid;    /* PID of process that initiated this SA */
+	__u8		ips_authalg;	     /* auth algorithm for this SA */
+	__u8		ips_encalg;	     /* enc algorithm for this SA */
+
+	struct ipsec_stats ips_errs;
+
+	__u8		ips_replaywin;		/* replay window size */
+	__u8		ips_state;		/* state of SA */
+	__u32		ips_replaywin_lastseq;	/* last pkt sequence num */
+	__u64		ips_replaywin_bitmap;	/* bitmap of received pkts */
+	__u32		ips_replaywin_maxdiff;	/* max pkt sequence difference */
+
+	__u32		ips_flags;		/* generic xform flags */
+
+
+	struct ipsec_lifetimes ips_life;             /* lifetime records */
+
+	/* selector information */
+	struct sockaddr*ips_addr_s;		/* src sockaddr */
+	struct sockaddr*ips_addr_d;		/* dst sockaddr */
+	struct sockaddr*ips_addr_p;		/* proxy sockaddr */
+	__u16		ips_addr_s_size;
+	__u16		ips_addr_d_size;
+	__u16		ips_addr_p_size;
+	ip_address	ips_flow_s;
+	ip_address	ips_flow_d;
+	ip_address	ips_mask_s;
+	ip_address	ips_mask_d;
+
+	__u16		ips_key_bits_a;	    /* size of authkey in bits */
+	__u16		ips_auth_bits;	    /* size of authenticator in bits */
+	__u16		ips_key_bits_e;	    /* size of enckey in bits */
+	__u16		ips_iv_bits;	    /* size of IV in bits */
+	__u8		ips_iv_size;
+	__u16		ips_key_a_size;
+	__u16		ips_key_e_size;
+
+	caddr_t		ips_key_a;		/* authentication key */
+	caddr_t		ips_key_e;		/* encryption key */
+	caddr_t	        ips_iv;			/* Initialisation Vector */
+
+	struct ident	ips_ident_s;		/* identity src */
+	struct ident	ips_ident_d;		/* identity dst */
+
+#ifdef CONFIG_IPSEC_IPCOMP
+	__u16		ips_comp_adapt_tries;	/* ipcomp self-adaption tries */
+	__u16		ips_comp_adapt_skip;	/* ipcomp self-adaption to-skip */
+	__u64		ips_comp_ratio_cbytes;	/* compressed bytes */
+	__u64		ips_comp_ratio_dbytes;	/* decompressed (or uncompressed) bytes */
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	__u8        ips_natt_type;
+	__u8        ips_natt_reserved[3];
+	__u16       ips_natt_sport;
+	__u16       ips_natt_dport;
+ 
+	struct sockaddr *ips_natt_oa;
+	__u16		ips_natt_oa_size;
+	__u16		ips_natt_reserved2;
+#endif
+
+#if 0
+	__u32		ips_sens_dpd;
+	__u8		ips_sens_sens_level;
+	__u8		ips_sens_sens_len;
+	__u64*		ips_sens_sens_bitmap;
+	__u8		ips_sens_integ_level;
+	__u8		ips_sens_integ_len;
+	__u64*		ips_sens_integ_bitmap;
+#endif
+	struct ipsec_alg_enc *ips_alg_enc;
+	struct ipsec_alg_auth *ips_alg_auth;
+};
+
+enum ipsec_direction {
+	ipsec_incoming = 1,
+	ipsec_outgoing = 2
+};
+
+#ifdef IPSEC_KLIPS1_COMPAT
+#define tdb_hnext ips_hnext
+#define tdb_inext ips_inext
+#define tdb_onext ips_onext
+#define tdb_said  ips_said
+#define tdb_addr_s ips_addr_s
+#define tdb_addr_s_size ips_addr_s_size
+#define tdb_addr_d ips_addr_d
+#define tdb_addr_d_size ips_addr_d_size
+#define tdb_addr_p ips_addr_p
+#define tdb_addr_p_size ips_addr_p_size
+#define tdb_ident_s ips_ident_s
+#define tdb_ident_d ips_ident_d
+#define tdb_state   ips_state
+
+#define tdb_replaywin ips_replaywin
+#define tdb_replaywin_lastseq ips_replaywin_lastseq
+#define tdb_replaywin_bitmap  ips_replaywin_bitmap
+#define tdb_replaywin_maxdiff ips_replaywin_maxdiff
+#define tdb_replaywin_errs    ips_errs.ips_replaywin_errs
+
+#define tdb_encalg    ips_encalg
+#define tdb_encsize_errs ips_errs.ips_encsize_errs
+#define tdb_encpad_errs  ips_errs.ips_encpad_errs
+#define tdb_alg_errs  ips_errs.ips_alg_errs
+#define tdb_authalg   ips_authalg
+#define tdb_auth_errs ips_errs.ips_auth_errs
+#define tdb_iv        ips_iv
+#define tdb_iv_size   ips_iv_size
+#define tdb_iv_bits   ips_iv_bits
+#define tdb_key_e     ips_key_e
+#define tdb_key_e_size ips_key_e_size
+#define tdb_key_bits_e ips_key_bits_e
+#define tdb_key_bits_a ips_key_bits_a
+#define tdb_key_a     ips_key_a
+#define tdb_auth_bits ips_auth_bits
+#define tdb_key_a_size ips_key_a_size
+
+#define tdb_comp_ratio_cbytes ips_comp_ratio_cbytes 
+#define tdb_comp_ratio_dbytes ips_comp_ratio_dbytes 
+#define tdb_comp_adapt_tries  ips_comp_adapt_tries
+#define tdb_comp_adapt_skip   ips_comp_adapt_skip
+
+#define tdb_mask_s    ips_mask_s
+#define tdb_flow_s    ips_flow_s
+#define tdb_mask_d    ips_mask_d
+#define tdb_flow_d    ips_flow_d
+
+#define tdb_flags     ips_flags
+#define tdb_rcvif     ips_rcvif
+
+#endif /* IPSEC_KLIPS1_COMPAT */
+
+#define _IPSEC_SA_H
+#endif /* _IPSEC_SA_H_ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.3  2002/09/05 03:53:52  ken
+ * Added NAT-T Patch
+ *
+ * Revision 1.2  2002/09/05 03:27:08  ken
+ * Applied freeswan-alg-0.8.0-BASE-klips.diff
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.2  2001/11/26 09:16:15  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:24:58  mcr
+ * 	struct tdb -> struct ipsec_sa.
+ * 	sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
+ * 	ipsec_xform.c removed. header file still contains useful things.
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_sha1.c linux-patched/net/ipsec/ipsec_sha1.c
--- linux/net/ipsec/ipsec_sha1.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_sha1.c	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,204 @@
+/*
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+/*
+ * The rest of the code is derived from sha1.c by Steve Reid, which is
+ * public domain.
+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
+ */
+
+#include <asm/byteorder.h>
+#include <linux/string.h>
+
+#include "ipsec_sha1.h"
+
+#if defined(rol)
+#undef rol
+#endif
+
+#define SHA1HANDSOFF
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef __LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(__u32 state[5], __u8 buffer[64])
+{
+__u32 a, b, c, d, e;
+typedef union {
+    unsigned char c[64];
+    __u32 l[16];
+} CHAR64LONG16;
+CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+static unsigned char workspace[64];
+    block = (CHAR64LONG16*)workspace;
+    memcpy(block, buffer, 64);
+#else
+    block = (CHAR64LONG16*)buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, unsigned char* data, __u32 len)
+{
+__u32 i, j;
+
+    j = context->count[0];
+    if ((context->count[0] += len << 3) < j)
+	context->count[1]++;
+    context->count[1] += (len>>29);
+    j = (j >> 3) & 63;
+    if ((j + len) > 63) {
+        memcpy(&context->buffer[j], data, (i = 64-j));
+        SHA1Transform(context->state, context->buffer);
+        for ( ; i + 63 < len; i += 64) {
+            SHA1Transform(context->state, &data[i]);
+        }
+        j = 0;
+    }
+    else i = 0;
+    memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+__u32 i, j;
+unsigned char finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
+    }
+    SHA1Update(context, (unsigned char *)"\200", 1);
+    while ((context->count[0] & 504) != 448) {
+        SHA1Update(context, (unsigned char *)"\0", 1);
+    }
+    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+    for (i = 0; i < 20; i++) {
+        digest[i] = (unsigned char)
+         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+    }
+    /* Wipe variables */
+    i = j = 0;
+    memset(context->buffer, 0, 64);
+    memset(context->state, 0, 20);
+    memset(context->count, 0, 8);
+    memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite its own static vars */
+    SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.5  1999/12/13 13:59:13  rgb
+ * Quick fix to argument size to Update bugs.
+ *
+ * Revision 1.4  1999/04/11 00:29:00  henry
+ * GPL boilerplate
+ *
+ * Revision 1.3  1999/04/06 04:54:27  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.2  1999/01/22 06:55:50  rgb
+ * 64-bit clean-up.
+ *
+ * Revision 1.1  1998/06/18 21:27:50  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.2  1998/04/23 20:54:04  rgb
+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
+ * verified.
+ *
+ * Revision 1.1  1998/04/09 03:06:11  henry
+ * sources moved up from linux/net/ipsec
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:05  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * New transform
+ *
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_sha1.h linux-patched/net/ipsec/ipsec_sha1.h
--- linux/net/ipsec/ipsec_sha1.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_sha1.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,71 @@
+/*
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ */
+
+/*
+ * Here is the original comment from the distribution:
+
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+ * Adapted for use by the IPSEC code by John Ioannidis
+ */
+
+
+#ifndef _IPSEC_SHA1_H_
+#define _IPSEC_SHA1_H_
+
+typedef struct
+{
+	__u32	state[5];
+	__u32	count[2];
+	__u8	buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(__u32 state[5], __u8 buffer[64]);
+void SHA1Init(SHA1_CTX *context);
+void SHA1Update(SHA1_CTX *context, unsigned char *data, __u32 len);
+void SHA1Final(unsigned char digest[20], SHA1_CTX *context);
+
+ 
+#endif /* _IPSEC_SHA1_H_ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.5  1999/12/13 13:59:13  rgb
+ * Quick fix to argument size to Update bugs.
+ *
+ * Revision 1.4  1999/12/07 18:16:23  rgb
+ * Fixed comments at end of #endif lines.
+ *
+ * Revision 1.3  1999/04/06 04:54:27  rgb
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+ * patch shell fixes.
+ *
+ * Revision 1.2  1998/11/30 13:22:54  rgb
+ * Rationalised all the klips kernel file headers.  They are much shorter
+ * now and won't conflict under RH5.2.
+ *
+ * Revision 1.1  1998/06/18 21:27:50  henry
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
+ * kernel-build scripts happier in the presence of symlinks
+ *
+ * Revision 1.2  1998/04/23 20:54:05  rgb
+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
+ * verified.
+ *
+ * Revision 1.1  1998/04/09 03:04:21  henry
+ * sources moved up from linux/net/ipsec
+ * these two include files modified not to include others except in kernel
+ *
+ * Revision 1.1.1.1  1998/04/08 05:35:04  henry
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
+ *
+ * Revision 0.4  1997/01/15 01:28:15  ji
+ * New transform
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_stats.h linux-patched/net/ipsec/ipsec_stats.h
--- linux/net/ipsec/ipsec_stats.h	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_stats.h	Thu Sep  5 04:13:17 2002
@@ -0,0 +1,55 @@
+/*
+ * @(#) definition of ipsec_stats structure
+ *
+ * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
+ *                 and Michael Richardson  <mcr@freeswan.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $
+ *
+ */
+
+/* 
+ * This file describes the errors/statistics that FreeSWAN collects.
+ */
+
+#ifndef _IPSEC_STATS_H_
+
+struct ipsec_stats {
+	__u32		ips_alg_errs;	       /* number of algorithm errors */
+	__u32		ips_auth_errs;	       /* # of authentication errors */
+	__u32		ips_encsize_errs;      /* # of encryption size errors*/
+	__u32		ips_encpad_errs;       /* # of encryption pad  errors*/
+	__u32		ips_replaywin_errs;    /* # of pkt sequence errors */
+};
+
+#define _IPSEC_STATS_H_
+#endif /* _IPSEC_STATS_H_ */
+
+/*
+ * $Log: super-freeswan-1.99.8-delsol1.diff,v $
+ * Revision 1.1  2003/09/09 09:20:34  john
+ * Initial import
+ *
+ * Revision 1.1.1.1  2002/09/05 03:13:17  ken
+ * 1.98b
+ *
+ * Revision 1.2  2001/11/26 09:16:16  rgb
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
+ *
+ * Revision 1.1.2.1  2001/09/25 02:27:00  mcr
+ * 	statistics moved to seperate structure.
+ *
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff -Nru -x '*.ipsecmd5' -x '*.preipsec' -x '*.ipsecmd5' -x '*.wipsec' linux/net/ipsec/ipsec_tunnel.c linux-patched/net/ipsec/ipsec_tunnel.c
--- linux/net/ipsec/ipsec_tunnel.c	Thu Jan  1 01:00:00 1970
+++ linux-patched/net/ipsec/ipsec_tunnel.c	Fri Jul  4 20:07:34 2003
@@ -0,0 +1,4164 @@
+/*
+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
+ * Copyright (C) 1996, 1997  John Ioannidis.
+ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+char ipsec_tunnel_c_version[] = "RCSID $Id: super-freeswan-1.99.8-delsol1.diff,v 1.1 2003/09/09 09:20:34 john Exp $";
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/config.h>	/* for CONFIG_IP_FORWARD */
+#include <linux/version.h>
+#include <linux/kernel.h> /* printk() */
+
+/* XXX-mcr remove this definition when the code has been properly rototiled */
+#define IPSEC_KLIPS1_COMPAT 1
+#include "ipsec_param.h"
+
+#ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+#else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+#endif /* MALLOC_SLAB */
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+
+#include <linux/netdevice.h>   /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/tcp.h>         /* struct tcphdr */
+#include <linux/udp.h>         /* struct udphdr */
+#include <linux/skbuff.h>
+#include <freeswan.h>
+#ifdef NET_21
+# define MSS_HACK_		/* experimental */
+# include <asm/uaccess.h>
+# include <linux/in6.h>
+# define ip_chk_addr inet_addr_type
+# define IS_MYADDR RTN_LOCAL
+# include <net/dst.h>
+# undef dev_kfree_skb
+# define dev_kfree_skb(a,b) kfree_skb(a)
+# define proto_priv cb
+# define PHYSDEV_TYPE
+#endif /* NET_21 */
+#include <asm/checksum.h>
+#include <net/icmp.h>		/* icmp_send() */
+#include <net/ip.h>
+#ifdef NETDEV_23
+# include <linux/netfilter_ipv4.h>
+#endif /* NETDEV_23 */
+
+#include "ipsec_alg.h"
+
+#include <linux/if_arp.h>
+#ifdef MSS_HACK
+# include <net/tcp.h>		/* TCP options */
+#endif	/* MSS_HACK */
+
+#include "radij.h"
+#include "ipsec_life.h"
+#include "ipsec_xform.h"
+#include "ipsec_eroute.h"
+#include "ipsec_encap.h"
+#include "ipsec_radij.h"
+#include "ipsec_netlink.h"
+#include "ipsec_sa.h"
+#include "ipsec_tunnel.h"
+#include "ipsec_ipe4.h"
+#include "ipsec_ah.h"
+#include "ipsec_esp.h"
+
+#ifdef CONFIG_IPSEC_IPCOMP
+# include "ipcomp.h"
+#endif /* CONFIG_IPSEC_IPCOMP */
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#include "ipsec_proto.h"
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+#include <linux/udp.h>
+#endif
+
+static __u32 zeroes[64];
+
+#ifdef CONFIG_IPSEC_DEBUG
+int debug_tunnel = 0;
+int sysctl_ipsec_debug_verbose = 0;
+#endif /* CONFIG_IPSEC_DEBUG */
+
+int sysctl_ipsec_icmp = 0;
+int sysctl_ipsec_tos = 0;
+
+/*
+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
+ * source and destination ports to those from the TCP/UDP header.
+ */
+static void extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
+{
+	struct udphdr *udp;
+
+	switch (iph->protocol) {
+	case IPPROTO_UDP:
+	case IPPROTO_TCP:
+		/*
+		 * The ports are at the same offsets in a TCP and UDP
+		 * header so hack it ...
+		 */
+		udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
+		er->sen_sport = udp->source;
+		er->sen_dport = udp->dest;
+		break;
+	default:
+		er->sen_sport = 0;
+		er->sen_dport = 0;
+		break;
+	}
+}
+
+/*
+ * A TRAP eroute is installed and we want to replace it with a HOLD
+ * eroute.
+ */
+static int create_hold_eroute(struct sk_buff * skb, struct iphdr * iph,
+			      uint32_t eroute_pid)
+{
+	struct eroute hold_eroute;
+	struct sa_id hold_said;
+	struct sk_buff *first, *last;
+	int error;
+
+	first = last = NULL;
+	memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
+	memset((caddr_t)&hold_said, 0, sizeof(hold_said));
+	
+	hold_said.proto = IPPROTO_INT;
+	hold_said.spi = htonl(SPI_HOLD);
+	hold_said.dst.s_addr = INADDR_ANY;
+	
+	hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
+	hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
+	hold_eroute.er_eaddr.sen_family = AF_ENCAP;
+	hold_eroute.er_emask.sen_family = AF_ENCAP;
+	hold_eroute.er_eaddr.sen_type = SENT_IP4;
+	hold_eroute.er_emask.sen_type = 255;
+	
+	hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
+	hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
+	hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
+	hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
+	hold_eroute.er_emask.sen_sport = ~0;
+	hold_eroute.er_emask.sen_dport = ~0;
+	hold_eroute.er_pid = eroute_pid;
+	hold_eroute.er_count = 0;
+	hold_eroute.er_lasttime = jiffies/HZ;
+						
+	hold_eroute.er_eaddr.sen_proto = iph->protocol;
+	extract_ports(iph, &hold_eroute.er_eaddr);
+
+#ifdef CONFIG_IPSEC_DEBUG
+	if (debug_pfkey) {
+		char buf1[64], buf2[64];
+		subnettoa(hold_eroute.er_eaddr.sen_ip_src,
+			  hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
+		subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
+			  hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
+			    buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
+			    buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
+			    hold_eroute.er_eaddr.sen_proto);
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
+			     &first, &last)) {
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "HOLD breakeroute found nothing.\n");
+	} else {
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
+			    NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
+			    ntohs(hold_eroute.er_eaddr.sen_sport),
+			    NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
+			    ntohs(hold_eroute.er_eaddr.sen_dport),
+			    hold_eroute.er_eaddr.sen_proto);
+	}
+	if (first != NULL)
+		kfree_skb(first);
+	if (last != NULL)
+		kfree_skb(last);
+
+	error = ipsec_makeroute(&(hold_eroute.er_eaddr),
+				&(hold_eroute.er_emask),
+				hold_said, eroute_pid, skb, NULL, NULL);
+	if (error) {
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "HOLD makeroute returned %d, failed.\n", error);
+	} else {
+		KLIPS_PRINT(debug_pfkey,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "HOLD makeroute call successful.\n");
+	}
+	return (error == 0);
+}
+
+
+
+#ifdef CONFIG_IPSEC_DEBUG_
+DEBUG_NO_STATIC void
+dmp(char *s, caddr_t bb, int len)
+{
+	int i;
+	unsigned char *b = bb;
+  
+	if (debug_tunnel) {
+		printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: "
+		       "at %s, len=%d:",
+		       s,
+		       len);
+		for (i=0; i < len; i++) {
+			if(!(i%16)){
+				printk("\nklips_debug:  ");
+			}
+			printk(" %02x", *b++);
+		}
+		printk("\n");
+	}
+}
+#else /* CONFIG_IPSEC_DEBUG */
+#define dmp(_x, _y, _z) 
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#ifndef SKB_COPY_EXPAND
+/*
+ *	This is mostly skbuff.c:skb_copy().
+ */
+struct sk_buff *
+skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority)
+{
+	struct sk_buff *n;
+	unsigned long offset;
+
+	/*
+	 *	Do sanity checking
+	 */
+	if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
+		printk(KERN_WARNING
+		       "klips_error:skb_copy_expand: "
+		       "Illegal negative head,tailroom %d,%d\n",
+		       headroom,
+		       tailroom);
+		return NULL;
+	}
+	/*
+	 *	Allocate the copy buffer
+	 */
+	 
+#ifndef NET_21
+	IS_SKB(skb);
+#endif /* !NET_21 */
+
+
+	n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
+		    "klips_debug:skb_copy_expand: "
+		    "head=%p data=%p tail=%p end=%p end-head=%d tail-data=%d\n",
+		    skb->head,
+		    skb->data,
+		    skb->tail,
+		    skb->end,
+		    skb->end - skb->head,
+		    skb->tail - skb->data);
+
+	if(n==NULL)
+		return NULL;
+
+	/*
+	 *	Shift between the two data areas in bytes
+	 */
+	 
+	/* offset=n->head-skb->head; */ /* moved down a few lines */
+
+	/* Set the data pointer */
+	skb_reserve(n,skb->data-skb->head+headroom);
+	/* Set the tail pointer and length */
+	if(skb_tailroom(n) < skb->len) {
+		printk(KERN_WARNING "klips_error:skb_copy_expand: "
+		       "tried to skb_put %ld, %d available.  This should never happen, please report.\n",
+		       (unsigned long int)skb->len,
+		       skb_tailroom(n));
+		dev_kfree_skb(n, FREE_WRITE);
+		return NULL;
+	}
+	skb_put(n,skb->len);
+
+	offset=n->head + headroom - skb->head;
+
+	/* Copy the bytes */
+	memcpy(n->head + headroom, skb->head,skb->end-skb->head);
+#ifdef NET_21
+	n->csum=skb->csum;
+	n->priority=skb->priority;
+	n->dst=dst_clone(skb->dst);
+	if(skb->nh.raw)
+		n->nh.raw=skb->nh.raw+offset;
+#ifndef NETDEV_23
+	n->is_clone=0;
+#endif /* NETDEV_23 */
+	atomic_set(&n->users, 1);
+	n->destructor = NULL;
+	n->security=skb->security;
+#else /* NET_21 */
+	n->link3=NULL;
+	n->when=skb->when;
+	if(skb->ip_hdr)
+	        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;
+	n->free=1;
+	n->arp=skb->arp;
+	n->tries=0;
+	n->lock=0;
+	n->users=0;
+#endif /* NET_21 */
+	n->protocol=skb->protocol;
+	n->list=NULL;
+	n->sk=NULL;
+	n->dev=skb->dev;
+	if(skb->h.raw)
+		n->h.raw=skb->h.raw+offset;
+	if(skb->mac.raw) 
+		n->mac.raw=skb->mac.raw+offset;
+	memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
+#ifndef NETDEV_23
+	n->used=skb->used;
+#endif /* !NETDEV_23 */
+	n->pkt_type=skb->pkt_type;
+	n->stamp=skb->stamp;
+	
+#ifndef NET_21
+	IS_SKB(n);
+#endif /* !NET_21 */
+	return n;
+}
+#endif /* !SKB_COPY_EXPAND */
+
+#ifdef CONFIG_IPSEC_DEBUG
+void
+ipsec_print_ip(struct iphdr *ip)
+{
+	char buf[ADDRTOA_BUF];
+
+	printk(KERN_INFO "klips_debug:   IP:");
+	printk(" ihl:%d", ip->ihl*4);
+	printk(" ver:%d", ip->version);
+	printk(" tos:%d", ip->tos);
+	printk(" tlen:%d", ntohs(ip->tot_len));
+	printk(" id:%d", ntohs(ip->id));
+	printk(" %s%s%sfrag_off:%d",
+               ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
+               ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
+               ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
+               (ntohs(ip->frag_off) & IP_OFFSET) << 3);
+	printk(" ttl:%d", ip->ttl);
+	printk(" proto:%d", ip->protocol);
+	if(ip->protocol == IPPROTO_UDP)
+		printk(" (UDP)");
+	if(ip->protocol == IPPROTO_TCP)
+		printk(" (TCP)");
+	if(ip->protocol == IPPROTO_ICMP)
+		printk(" (ICMP)");
+	printk(" chk:%d", ntohs(ip->check));
+	addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
+	printk(" saddr:%s", buf);
+	if(ip->protocol == IPPROTO_UDP)
+		printk(":%d",
+		       ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
+	if(ip->protocol == IPPROTO_TCP)
+		printk(":%d",
+		       ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
+	addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
+	printk(" daddr:%s", buf);
+	if(ip->protocol == IPPROTO_UDP)
+		printk(":%d",
+		       ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
+	if(ip->protocol == IPPROTO_TCP)
+		printk(":%d",
+		       ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
+	if(ip->protocol == IPPROTO_ICMP)
+		printk(" type:code=%d:%d",
+		       ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
+		       ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
+	printk("\n");
+
+	if(sysctl_ipsec_debug_verbose) {
+		__u8 *c;
+		int i;
+		
+		c = ((__u8*)ip) + ip->ihl*4;
+		for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) {
+			if(!(i % 16)) {
+				printk(KERN_INFO
+				       "klips_debug:   @%03x:",
+				       i);
+			}
+			printk(" %02x", /***/c[i]);
+			if(!((i + 1) % 16)) {
+				printk("\n");
+			}
+		}
+		if(i % 16) {
+			printk("\n");
+		}
+	}
+}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+#ifdef REAL_LOCKING_P
+/*
+ *	Locking
+ */
+ 
+#if 0
+DEBUG_NO_STATIC int
+ipsec_tunnel_lock(struct ipsecpriv *prv)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	/*
+	 *	Lock in an interrupt may fail
+	 */
+	if(prv->locked && in_interrupt()) {
+		restore_flags(flags);
+		return 0;
+	}
+	while(prv->locked)
+		sleep_on(&prv->wait_queue);
+	prv->locked=1;
+	restore_flags(flags);
+	return 1;
+}
+#endif
+
+#if 0
+DEBUG_NO_STATIC void
+ipsec_tunnel_unlock(struct ipsecpriv *prv)
+{
+	prv->locked=0;
+	wake_up(&prv->wait_queue);
+}
+#endif
+#endif /* REAL_LOCKING_P */
+
+DEBUG_NO_STATIC int
+ipsec_tunnel_open(struct device *dev)
+{
+	struct ipsecpriv *prv = dev->priv;
+	
+	/*
+	 * Can't open until attached.
+	 */
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
+		    "klips_debug:ipsec_tunnel_open: "
+		    "dev = %s, prv->dev = %s\n",
+		    dev->name, prv->dev?prv->dev->name:"NONE");
+
+	if (prv->dev == NULL)
+		return -ENODEV;
+	
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+DEBUG_NO_STATIC int
+ipsec_tunnel_close(struct device *dev)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+#ifdef MSS_HACK
+/*
+ * Issues:
+ *  1) Fragments arriving in the tunnel should probably be rejected.
+ *  2) How does this affect syncookies, mss_cache, dst cache ?
+ *  3) Path MTU discovery handling needs to be reviewed.  For example,
+ *     if we receive an ICMP 'packet too big' message from an intermediate 
+ *     router specifying it's next hop MTU, our stack may process this and
+ *     adjust the MSS without taking our AH/ESP overheads into account.
+ */
+
+ 
+/*
+ * Recaclulate checksum using differences between changed datum, 
+ * borrowed from netfilter.
+ */
+DEBUG_NO_STATIC u_int16_t 
+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
+{
+	u_int32_t diffs[] = { oldvalinv, newval };
+	return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
+	oldcheck^0xFFFF));
+}
+
+/*
+ * Determine effective MSS.
+ *
+ * Note that we assume that there is always an MSS option for our own
+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
+ * This could change, and we should probably parse TCP options instead.
+ *
+ */
+DEBUG_NO_STATIC u_int8_t
+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
+{
+	u_int16_t oldmss, newmss;
+	u_int32_t *mssp;
+	struct sock *sk = skb->sk;
+	
+	newmss = tcp_sync_mss(sk, mtu);
+	printk(KERN_INFO "klips: setting mss to %u\n", newmss);
+	mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
+	oldmss = ntohl(*mssp) & 0x0000FFFF;
+	*mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
+	tcph->check = ipsec_fast_csum(htons(~oldmss), 
+	                              htons(newmss), tcph->check);
+	return 1;
+}
+#endif	/* MSS_HACK */
+                                                        
+#ifdef NETDEV_23
+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
+{
+	return ip_send(skb);
+}
+#endif /* NETDEV_23 */
+
+/*
+ *	This function assumes it is being called from dev_queue_xmit()
+ *	and that skb is filled properly by that function.
+ */
+
+int
+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev)
+{
+	struct ipsecpriv *prv;		/* Our device' private space */
+	struct sk_buff *oskb = NULL;	/* Original skb pointer */
+	struct net_device_stats *stats;	/* This device's statistics */
+	struct iphdr  *iph;		/* Our new IP header */
+	__u32   newdst;			/* The other SG's IP address */
+	__u32	orgdst;			/* Original IP destination address */
+	__u32	orgedst;		/* 1st SG's IP address */
+	__u32   newsrc;			/* The new source SG's IP address */
+	__u32	orgsrc;			/* Original IP source address */
+	__u32	innersrc;		/* Innermost IP source address */
+	int	iphlen;			/* IP header length */
+	int	pyldsz;			/* upper protocol payload size */
+	int	headroom;
+	int	tailroom;
+	int     max_headroom = 0;	/* The extra header space needed */
+	int	max_tailroom = 0;	/* The extra stuffing needed */
+	int     ll_headroom;		/* The extra link layer hard_header space needed */
+	int     tot_headroom = 0;	/* The total header space needed */
+	int	tot_tailroom = 0;	/* The totalstuffing needed */
+	__u8	*saved_header = NULL;	/* saved copy of the hard header */
+	int i;
+	unsigned short   sport,dport;
+
+	struct sockaddr_encap matcher;	/* eroute search key */
+	struct eroute *er;
+	struct ipsec_sa *tdbp, *tdbq;	/* Tunnel Descriptor Block pointers */
+	char sa[SATOA_BUF];
+	size_t sa_len;
+	int hard_header_stripped = 0;	/* has the hard header been removed yet? */
+	int hard_header_len = 0;
+	struct device *physdev;
+/*	struct device *virtdev; */
+	short physmtu;
+	short mtudiff;
+	int blocksize = 8;
+#ifdef NET_21
+	struct rtable *rt = NULL;
+#endif /* NET_21 */
+	struct sa_id outgoing_said;
+#ifdef NET_21
+	int pass = 0;
+#endif /* NET_21 */
+	int error = 0;
+	uint32_t eroute_pid = 0;
+	struct ipsec_sa tdb;
+#ifdef CONFIG_IPSEC_ALG
+	struct ipsec_alg_enc *ixt_e = NULL;
+	struct ipsec_alg_auth *ixt_a = NULL;
+#endif /* CONFIG_IPSEC_ALG */
+
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	uint8_t natt_type = 0, natt_head = 0;
+	uint16_t natt_sport = 0, natt_dport = 0;
+#endif
+
+	dport=sport=0;
+
+	memset((char*)&tdb, 0, sizeof(struct ipsec_sa));
+
+	/*
+	 *	Return if there is nothing to do.  (Does this ever happen?) XXX
+	 */
+	if (skb == NULL) {
+		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+			    "klips_error:ipsec_tunnel_start_xmit: "
+			    "Nothing to do!\n" );
+		goto cleanup;
+	}
+	if (dev == NULL) {
+		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+			    "klips_error:ipsec_tunnel_start_xmit: "
+			    "No device associated with skb!\n" );
+		goto cleanup;
+	}
+
+	prv = dev->priv;
+	if (prv == NULL) {
+		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+			    "klips_error:ipsec_tunnel_start_xmit: "
+			    "Device has no private structure!\n" );
+		goto cleanup;
+	}
+
+	physdev = prv->dev;
+	if (physdev == NULL) {
+		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+			    "klips_error:ipsec_tunnel_start_xmit: "
+			    "Device is not attached to physical device!\n" );
+		goto cleanup;
+	}
+
+	physmtu = physdev->mtu;
+
+	stats = (struct net_device_stats *) &(prv->mystats);
+
+#ifdef NET_21
+	/* if skb was cloned (most likely due to a packet sniffer such as
+	   tcpdump being momentarily attached to the interface), make
+	   a copy of our own to modify */
+	if(skb_cloned(skb)) {
+		if
+#ifdef SKB_COW_NEW
+	       (skb_cow(skb, skb_headroom(skb)) != 0)
+#else /* SKB_COW_NEW */
+	       ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
+#endif /* SKB_COW_NEW */
+		{
+			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+				    "klips_error:ipsec_tunnel_start_xmit: "
+				    "skb_cow failed to allocate buffer, dropping.\n" );
+			stats->tx_dropped++;
+			goto cleanup;
+		}
+	}
+#endif /* NET_21 */
+
+#ifdef NET_21
+	iph = skb->nh.iph;
+#else /* NET_21 */
+	iph = skb->ip_hdr;
+#endif /* NET_21 */
+
+	/* sanity check for IP version as we can't handle IPv6 right now */
+	if (iph->version != 4) {
+		KLIPS_PRINT(debug_tunnel,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "found IP Version %d but cannot process other IP versions than v4.\n",
+			    iph->version); /* XXX */
+		stats->tx_dropped++;
+		goto cleanup;
+	}
+	
+	/* physdev->hard_header_len is unreliable and should not be used */
+	hard_header_len = (unsigned char *)iph - skb->data;
+
+	if(hard_header_len < 0) {
+		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+			    "klips_error:ipsec_tunnel_start_xmit: "
+			    "Negative hard_header_len (%d)?!\n", hard_header_len);
+		stats->tx_dropped++;
+		goto cleanup;
+	}
+
+	if(hard_header_len == 0) { /* no hard header present */
+		hard_header_stripped = 1;
+	}
+
+#ifdef CONFIG_IPSEC_DEBUG
+	if (debug_tunnel & DB_TN_XMIT) {
+		int i;
+		char c;
+		
+		printk(KERN_INFO "klips_debug:ipsec_tunnel_start_xmit: "
+		       ">>> skb->len=%ld hard_header_len:%d",
+		       (unsigned long int)skb->len, hard_header_len);
+		c = ' ';
+		for (i=0; i < hard_header_len; i++) {
+			printk("%c%02x", c, skb->data[i]);
+			c = ':';
+		}
+		printk(" \n");
+	}
+#endif /* CONFIG_IPSEC_DEBUG */
+
+	KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph);
+
+	/*
+	 * Sanity checks
+	 */
+
+	if ((iph->ihl << 2) != sizeof (struct iphdr)) {
+		KLIPS_PRINT(debug_tunnel,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "cannot process IP header options yet.  May be mal-formed packet.\n"); /* XXX */
+		stats->tx_dropped++;
+		goto cleanup;
+	}
+	
+#ifndef NET_21
+	/* TTL decrement code (on the way out!) borrowed from ip_forward.c */
+	if(0) {
+		unsigned long checksum = iph->check;
+		iph->ttl--;
+	/*
+	 *	Re-compute the IP header checksum.
+	 *	This is efficient. We know what has happened to the header
+	 *	and can thus adjust the checksum as Phil Karn does in KA9Q
+	 *	except we do this in "network byte order".
+	 */
+		checksum += htons(0x0100);
+		/* carry overflow? */
+		checksum += checksum >> 16;
+		iph->check = checksum;
+	}
+	if (iph->ttl <= 0) {
+		/* Tell the sender its packet died... */
+		ICMP_SEND(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, physdev);
+
+		KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_tunnel_start_xmit: "
+			    "TTL=0, too many hops!\n");
+		stats->tx_dropped++;
+		goto cleanup;
+	}
+#endif /* !NET_21 */
+
+	/*
+	 * First things first -- look us up in the erouting tables.
+	 */
+	matcher.sen_len = sizeof (struct sockaddr_encap);
+	matcher.sen_family = AF_ENCAP;
+	matcher.sen_type = SENT_IP4;
+	matcher.sen_ip_src.s_addr = iph->saddr;
+	matcher.sen_ip_dst.s_addr = iph->daddr;
+	matcher.sen_proto = iph->protocol;
+	extract_ports(iph, &matcher);
+
+	/*
+	 * The spinlock is to prevent any other process from accessing or deleting
+	 * the eroute while we are using and updating it.
+	 */
+	spin_lock(&eroute_lock);
+	
+	er = ipsec_findroute(&matcher);
+
+	if(iph->protocol == IPPROTO_UDP) {
+		if(skb->sk) {
+			sport=ntohs(skb->sk->sport);
+			dport=ntohs(skb->sk->dport);
+		} else if((ntohs(iph->frag_off) & IP_OFFSET) == 0 &&
+			  iph->ihl << 2 > sizeof(struct iphdr) + sizeof(struct udphdr)) {
+			sport=ntohs(((struct udphdr*)((caddr_t)iph+(iph->ihl<<2)))->source);
+			dport=ntohs(((struct udphdr*)((caddr_t)iph + (iph->ihl<<2)))->dest);
+		} else {
+			sport=0; dport=0;
+		}
+	}
+
+	/* default to a %drop eroute */
+	outgoing_said.proto = IPPROTO_INT;
+	outgoing_said.spi = htonl(SPI_DROP);
+	outgoing_said.dst.s_addr = INADDR_ANY;
+	KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+		    "klips_debug:ipsec_tunnel_start_xmit: "
+		    "checking for local udp/500 IKE packet "
+		    "saddr=%x, er=%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
+		    ntohl((unsigned int)iph->saddr),
+		    er,
+		    ntohl((unsigned int)iph->daddr),
+		    er ? ntohl((unsigned int)er->er_said.dst.s_addr) : 0,
+		    iph->protocol,
+		    sport,
+		    dport); 
+
+	/*
+	 * Quick cheat for now...are we udp/500? If so, let it through
+	 * without interference since it is most likely an IKE packet.
+	 */
+
+	if (ip_chk_addr((unsigned long)iph->saddr) == IS_MYADDR
+	    && (!er
+		|| iph->daddr == er->er_said.dst.s_addr
+		|| INADDR_ANY == er->er_said.dst.s_addr)
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+ 	    && ((sport == 500) || (sport == 4500))
+#else
+ 	    && (sport == 500)
+#endif
+	    ) {                                                                  
+		/* Whatever the eroute, this is an IKE message
+		 * from us (i.e. not being forwarded).
+		 * Furthermore, if there is a tunnel eroute,
+		 * the destination is the peer for this eroute.
+		 * So %pass the packet: modify the default %drop.
+		 */
+		outgoing_said.spi = htonl(SPI_PASS);
+		if(!(skb->sk) && ((ntohs(iph->frag_off) & IP_MF) != 0)) {
+			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+				    "klips_debug:ipsec_tunnel_start_xmit: "
+				    "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
+		}
+	} else if (er) {
+		er->er_count++;
+		er->er_lasttime = jiffies/HZ;
+		if(er->er_said.proto==IPPROTO_INT
+		   && er->er_said.spi==htonl(SPI_HOLD)) {
+			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+				    "klips_debug:ipsec_tunnel_start_xmit: "
+				    "shunt SA of HOLD: skb stored in HOLD.\n");
+			if(er->er_last != NULL) {
+				kfree_skb(er->er_last);
+			}
+			er->er_last = skb;
+			skb = NULL;
+			stats->tx_dropped++;
+			spin_unlock(&eroute_lock);
+			goto cleanup;
+		}
+		outgoing_said = er->er_said;
+		eroute_pid = er->er_pid;
+		/* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
+		if(outgoing_said.proto==IPPROTO_INT
+		   && (outgoing_said.spi==htonl(SPI_TRAP)
+		       || (outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
+			int len;
+			
+			tdb.tdb_ident_s.type = er->er_ident_s.type;
+			tdb.tdb_ident_s.id = er->er_ident_s.id;
+			tdb.tdb_ident_s.len = er->er_ident_s.len;
+			if (tdb.tdb_ident_s.len) {
+				len = tdb.tdb_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
+				if ((tdb.tdb_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
+					printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "
+					       "Failed, tried to allocate %d bytes for source ident.\n", 
+					       len);
+					stats->tx_dropped++;
+					spin_unlock(&eroute_lock);
+					goto cleanup;
+				}
+				memcpy(tdb.tdb_ident_s.data, er->er_ident_s.data, len);
+			}
+			tdb.tdb_ident_d.type = er->er_ident_d.type;
+			tdb.tdb_ident_d.id = er->er_ident_d.id;
+			tdb.tdb_ident_d.len = er->er_ident_d.len;
+			if (tdb.tdb_ident_d.len) {
+				len = tdb.tdb_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
+				if ((tdb.tdb_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
+					printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "
+					       "Failed, tried to allocate %d bytes for dest ident.\n", 
+					       len);
+					stats->tx_dropped++;
+					spin_unlock(&eroute_lock);
+					goto cleanup;
+				}
+				memcpy(tdb.tdb_ident_d.data, er->er_ident_d.data, len);
+			}
+		}
+	}
+
+	spin_unlock(&eroute_lock);
+
+	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
+		    "klips_debug:ipsec_tunnel_start_xmit: "
+		    "Original head,tailroom: %d,%d\n",
+		    skb_headroom(skb), skb_tailroom(skb));
+
+	innersrc = iph->saddr;
+	/* start encapsulation loop here XXX */
+	do {
+		struct ipsec_sa *tdbprev = NULL;
+
+		newdst = orgdst = iph->daddr;
+		newsrc = orgsrc = iph->saddr;
+		orgedst = outgoing_said.dst.s_addr;
+		iphlen = iph->ihl << 2;
+		pyldsz = ntohs(iph->tot_len) - iphlen;
+		max_headroom = max_tailroom = 0;
+		
+		if (outgoing_said.proto == IPPROTO_INT) {
+			switch (ntohl(outgoing_said.spi)) {
+			case SPI_DROP:
+				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+					    "klips_debug:ipsec_tunnel_start_xmit: "
+					    "shunt SA of DROP or no eroute: dropping.\n");
+				stats->tx_dropped++;
+				break;
+				
+			case SPI_REJECT:
+				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+					    "klips_debug:ipsec_tunnel_start_xmit: "
+					    "shunt SA of REJECT: notifying and dropping.\n");
+				ICMP_SEND(skb,
+					  ICMP_DEST_UNREACH,
+					  ICMP_PKT_FILTERED,
+					  0,
+					  physdev);
+				stats->tx_dropped++;
+				break;
+				
+			case SPI_PASS:
+#ifdef NET_21
+				pass = 1;
+#endif /* NET_21 */
+				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+					    "klips_debug:ipsec_tunnel_start_xmit: "
+					    "PASS: calling dev_queue_xmit\n");
+				goto bypass;
+				
+#if 1 /* now moved up to finderoute so we don't need to lock it longer */
+			case SPI_HOLD:
+				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+					    "klips_debug:ipsec_tunnel_start_xmit: "
+					    "shunt SA of HOLD: this does not make sense here, dropping.\n");
+			stats->tx_dropped++;
+			break;
+#endif		
+			case SPI_TRAP:
+			case SPI_TRAPSUBNET:
+			{
+				struct sockaddr_in src, dst;
+#ifdef CONFIG_IPSEC_DEBUG
+				char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
+#endif /* CONFIG_IPSEC_DEBUG */
+				
+				/* Signal all listening KMds with a PF_KEY ACQUIRE */
+				tdb.tdb_said.proto = iph->protocol;
+				src.sin_family = AF_INET;
+				dst.sin_family = AF_INET;
+				src.sin_addr.s_addr = iph->saddr;
+				dst.sin_addr.s_addr = iph->daddr;
+				src.sin_port = 
+					(iph->protocol == IPPROTO_UDP
+					 ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->source
+					 : (iph->protocol == IPPROTO_TCP
+					    ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->source
+					    : 0));
+				dst.sin_port = 
+					(iph->protocol == IPPROTO_UDP
+					 ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->dest
+					 : (iph->protocol == IPPROTO_TCP
+					    ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->dest
+					    : 0));
+				for(i = 0;
+				    i < sizeof(struct sockaddr_in)
+					    - offsetof(struct sockaddr_in, sin_zero);
+				    i++) {
+					src.sin_zero[i] = 0;
+					dst.sin_zero[i] = 0;
+				}
+				
+				tdb.tdb_addr_s = (struct sockaddr*)(&src);
+				tdb.tdb_addr_d = (struct sockaddr*)(&dst);
+				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+					    "klips_debug:ipsec_tunnel_start_xmit: "
+					    "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
+					    addrtoa(((struct sockaddr_in*)(tdb.tdb_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
+					    ntohs(((struct sockaddr_in*)(tdb.tdb_addr_s))->sin_port),
+					    addrtoa(((struct sockaddr_in*)(tdb.tdb_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
+					    ntohs(((struct sockaddr_in*)(tdb.tdb_addr_d))->sin_port),
+					    tdb.tdb_said.proto);
+				
+				if (pfkey_acquire(&tdb) == 0) {
+					
+					if (outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
+						/*
+						 * The spinlock is to prevent any other
+						 * process from accessing or deleting
+						 * the eroute while we are using and
+						 * updating it.
+						 */
+						spin_lock(&eroute_lock);
+						er = ipsec_findroute(&matcher);
+						if(er) {
+							er->er_said.spi = htonl(SPI_HOLD);
+							er->er_first = skb;
+							skb = NULL;
+						}
+						spin_unlock(&eroute_lock);
+					} else if (create_hold_eroute(skb, iph, eroute_pid)) {
+						skb = NULL;
+					}
+				}
+				stats->tx_dropped++;
+			}
+			default:
+				/* XXX what do we do with an unknown shunt spi? */
+			} /* switch (ntohl(outgoing_said.spi)) */
+			goto cleanup;
+		} /* if (outgoing_said.proto == IPPROTO_INT) */
+		
+		/*
+		  The spinlock is to prevent any other process from
+		  accessing or deleting the TDB hash table or any of the
+		  TDBs while we are using and updating them.
+		  
+		  This is not optimal, but was relatively straightforward
+		  at the time.  A better way to do it has been planned for
+		  more than a year, to lock the hash table and put reference
+		  counts on each TDB instead.  This is not likely to happen
+		  in KLIPS1 unless a volunteer contributes it, but will be
+		  designed into KLIPS2.
+		*/
+		spin_lock(&tdb_lock);
+
+		tdbp = ipsec_sa_getbyid(&outgoing_said);
+		sa_len = satoa(outgoing_said, 0, sa, SATOA_BUF);
+
+		if (tdbp == NULL) {
+			spin_unlock(&tdb_lock);
+			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+				    "klips_debug:ipsec_tunnel_start_xmit: "
+				    "no Tunnel Descriptor Block for SA%s: outgoing packet with no SA, dropped.\n",
+				    sa_len ? sa : " (error)");
+			stats->tx_dropped++;
+			goto cleanup;
+		}
+		
+		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+			    "klips_debug:ipsec_tunnel_start_xmit: "
+			    "found Tunnel Descriptor Block -- SA:<%s%s%s> %s\n",
+			    IPS_XFORM_NAME(tdbp),
+			    sa_len ? sa : " (error)");
+		
+		/*
+		 * How much headroom do we need to be able to apply
+		 * all the grouped transforms?
+		 */
+		tdbq = tdbp;	/* save the head of the tdb chain */
+		while (tdbp)	{
+			sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
+			if(sa_len == 0) {
+				strcpy(sa, "(error)");
+			}
+
+			/* If it is in larval state, drop the packet, we cannot process yet. */
+			if(tdbp->tdb_state == SADB_SASTATE_LARVAL) {
+				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+					    "klips_debug:ipsec_tunnel_start_xmit: "
+					    "TDB in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
+					    IPS_XFORM_NAME(tdbp),
+					    sa_len ? sa : " (error)");
+				spin_unlock(&tdb_lock);
+				stats->tx_errors++;
+				goto cleanup;
+			}
+
+			if(tdbp->tdb_state == SADB_SASTATE_DEAD) {
+				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+					    "klips_debug:ipsec_tunnel_start_xmit: "
+					    "TDB in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
+					    IPS_XFORM_NAME(tdbp),
+					    sa_len ? sa : " (error)");
+				spin_unlock(&tdb_lock);
+				stats->tx_errors++;
+				goto cleanup;
+			}
+
+			/* If the replay window counter == -1, expire SA, it will roll */
+			if(tdbp->tdb_replaywin && tdbp->tdb_replaywin_lastseq == -1) {
+				pfkey_expire(tdbp, 1);
+				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
+					    "klips_debug:ipsec_tunnel_start_xmit: "
+					    "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
+					    IPS_XFORM_NAME(tdbp),
+					    sa_len ? sa : " (error)");
+				ipsec_sa_delchain(tdbp);
+				spin_unlock(&tdb_lock);
+				stats->tx_errors++;
+				goto cleanup;
+			}
+
+			/*
+			 * if this is the first time we are using this SA, mark start time,
+			 * and offset hard/soft counters by "now" for later checking.
+			 */
+#if 0
+			if(tdbp->ips_life.ipl_usetime.count == 0) {
+				tdbp->ips_life.ipl_usetime.count = jiffies;
+				tdbp->ips_life.ipl_usetime.hard += jiffies;
+				tdbp->ips_life.ipl_usetime.soft += jiffies;
+			}
+#endif
+			  
+
+			if(ipsec_lifetime_check(&tdbp->ips_life.ipl_bytes, "bytes", sa, 
+						ipsec_life_countbased, ipsec_outgoing, tdbp) == ipsec_life_harddied ||
+			   ipsec_lifetime_check(&tdbp->ips_life.ipl_addtime, "addtime",sa,
+						ipsec_life_timebased,  ipsec_outgoing, tdbp) == ipsec_life_harddied ||
+			   ipsec_lifetime_check(&tdbp->ips_life.ipl_usetime, "usetime",sa,
+						ipsec_life_timebased,  ipsec_outgoing, tdbp) == ipsec_life_harddied ||
+			   ipsec_lifetime_check(&tdbp->ips_life.ipl_packets, "packets",sa,
+						ipsec_life_countbased, ipsec_outgoing, tdbp) == ipsec_life_harddied) {
+				
+				ipsec_sa_delchain(tdbp);
+				spin_unlock(&tdb_lock);
+				stats->tx_errors++;
+				goto cleanup;
+			}
+			
+
+			headroom = tailroom = 0;
+			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
+				    "klips_debug:ipsec_tunnel_start_xmit: "
+				    "calling room for <%s%s%s>, SA:%s\n", 
+				    IPS_XFORM_NAME(tdbp),
+				    sa_len ? sa : " (error)");
+			switch(tdbp->tdb_said.proto) {
+#ifdef CONFIG_IPSEC_AH
+			case IPPROTO_AH:
+				headroom += sizeof(struct ah);
+				break;
+#endif /* CONFIG_IPSEC_AH */
+#ifdef CONFIG_IPSEC_ESP
+			case IPPROTO_ESP:
+#ifdef CONFIG_IPSEC_ALG
+				if ((ixt_e=IPSEC_ALG_SA_ESP_ENC(tdbp))) {
+					blocksize = ixt_e-
