[OpenWrt-Devel] [PATCH 13/21] kernel stuff

Sergey Lapin slapin at hackndev.com
Sat Apr 26 00:09:49 CEST 2008


FreeS/WAN patch, some hacks, hw acceleration

Signed-off-by: Sergey Lapin <slapin at hackndev.com>
---
 .../patches-2.4.28/700-include-freeswan.patch      |25085 ++++++++++++++++++++
 1 files changed, 25085 insertions(+), 0 deletions(-)
 create mode 100644 target/linux/rtl865x-2.4/patches-2.4.28/700-include-freeswan.patch

diff --git a/target/linux/rtl865x-2.4/patches-2.4.28/700-include-freeswan.patch b/target/linux/rtl865x-2.4/patches-2.4.28/700-include-freeswan.patch
new file mode 100644
index 0000000..b66bab2
--- /dev/null
+++ b/target/linux/rtl865x-2.4/patches-2.4.28/700-include-freeswan.patch
@@ -0,0 +1,25085 @@
+diff --git a/include/zconf.h b/include/zconf.h
+new file mode 100644
+index 0000000..783e0f0
+--- /dev/null
++++ b/include/zconf.h
+@@ -0,0 +1,309 @@
++/* zconf.h -- configuration of the zlib compression library
++ * Copyright (C) 1995-2002 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#ifndef _ZCONF_H
++#define _ZCONF_H
++
++/*
++ * If you *really* need a unique prefix for all types and library functions,
++ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
++ */
++#ifdef IPCOMP_PREFIX
++#  define deflateInit_	ipcomp_deflateInit_
++#  define deflate	ipcomp_deflate
++#  define deflateEnd	ipcomp_deflateEnd
++#  define inflateInit_ 	ipcomp_inflateInit_
++#  define inflate	ipcomp_inflate
++#  define inflateEnd	ipcomp_inflateEnd
++#  define deflateInit2_	ipcomp_deflateInit2_
++#  define deflateSetDictionary ipcomp_deflateSetDictionary
++#  define deflateCopy	ipcomp_deflateCopy
++#  define deflateReset	ipcomp_deflateReset
++#  define deflateParams	ipcomp_deflateParams
++#  define inflateInit2_	ipcomp_inflateInit2_
++#  define inflateSetDictionary ipcomp_inflateSetDictionary
++#  define inflateSync	ipcomp_inflateSync
++#  define inflateSyncPoint ipcomp_inflateSyncPoint
++#  define inflateReset	ipcomp_inflateReset
++#  define compress	ipcomp_compress
++#  define compress2	ipcomp_compress2
++#  define uncompress	ipcomp_uncompress
++#  define adler32	ipcomp_adler32
++#  define crc32		ipcomp_crc32
++#  define get_crc_table ipcomp_get_crc_table
++/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
++#  define inflate_blocks ipcomp_deflate_blocks
++#  define inflate_blocks_free ipcomp_deflate_blocks_free
++#  define inflate_blocks_new ipcomp_inflate_blocks_new
++#  define inflate_blocks_reset ipcomp_inflate_blocks_reset
++#  define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
++#  define inflate_set_dictionary ipcomp_inflate_set_dictionary
++#  define inflate_codes ipcomp_inflate_codes
++#  define inflate_codes_free ipcomp_inflate_codes_free
++#  define inflate_codes_new ipcomp_inflate_codes_new
++#  define inflate_fast ipcomp_inflate_fast
++#  define inflate_trees_bits ipcomp_inflate_trees_bits
++#  define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
++#  define inflate_trees_fixed ipcomp_inflate_trees_fixed
++#  define inflate_flush ipcomp_inflate_flush
++#  define inflate_mask ipcomp_inflate_mask
++#  define _dist_code _ipcomp_dist_code
++#  define _length_code _ipcomp_length_code
++#  define _tr_align _ipcomp_tr_align
++#  define _tr_flush_block _ipcomp_tr_flush_block
++#  define _tr_init _ipcomp_tr_init
++#  define _tr_stored_block _ipcomp_tr_stored_block
++#  define _tr_tally _ipcomp_tr_tally
++#  define zError ipcomp_zError
++#  define z_errmsg ipcomp_z_errmsg
++#  define zlibVersion ipcomp_zlibVersion
++#  define match_init ipcomp_match_init
++#  define longest_match ipcomp_longest_match
++#endif
++
++#ifdef Z_PREFIX
++#  define Byte		z_Byte
++#  define uInt		z_uInt
++#  define uLong		z_uLong
++#  define Bytef	        z_Bytef
++#  define charf		z_charf
++#  define intf		z_intf
++#  define uIntf		z_uIntf
++#  define uLongf	z_uLongf
++#  define voidpf	z_voidpf
++#  define voidp		z_voidp
++#endif
++
++#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
++#  define WIN32
++#endif
++#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
++#  ifndef __32BIT__
++#    define __32BIT__
++#  endif
++#endif
++#if defined(__MSDOS__) && !defined(MSDOS)
++#  define MSDOS
++#endif
++
++/*
++ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
++ * than 64k bytes at a time (needed on systems with 16-bit int).
++ */
++#if defined(MSDOS) && !defined(__32BIT__)
++#  define MAXSEG_64K
++#endif
++#ifdef MSDOS
++#  define UNALIGNED_OK
++#endif
++
++#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
++#  define STDC
++#endif
++#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
++#  ifndef STDC
++#    define STDC
++#  endif
++#endif
++
++#ifndef STDC
++#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
++#    define const
++#  endif
++#endif
++
++/* Some Mac compilers merge all .h files incorrectly: */
++#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
++#  define NO_DUMMY_DECL
++#endif
++
++/* Old Borland C incorrectly complains about missing returns: */
++#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
++#  define NEED_DUMMY_RETURN
++#endif
++
++
++/* Maximum value for memLevel in deflateInit2 */
++#ifndef MAX_MEM_LEVEL
++#  ifdef MAXSEG_64K
++#    define MAX_MEM_LEVEL 8
++#  else
++#    define MAX_MEM_LEVEL 9
++#  endif
++#endif
++
++/* Maximum value for windowBits in deflateInit2 and inflateInit2.
++ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
++ * created by gzip. (Files created by minigzip can still be extracted by
++ * gzip.)
++ */
++#ifndef MAX_WBITS
++#  define MAX_WBITS   15 /* 32K LZ77 window */
++#endif
++
++/* The memory requirements for deflate are (in bytes):
++            (1 << (windowBits+2)) +  (1 << (memLevel+9))
++ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
++ plus a few kilobytes for small objects. For example, if you want to reduce
++ the default memory requirements from 256K to 128K, compile with
++     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
++ Of course this will generally degrade compression (there's no free lunch).
++
++   The memory requirements for inflate are (in bytes) 1 << windowBits
++ that is, 32K for windowBits=15 (default value) plus a few kilobytes
++ for small objects.
++*/
++
++                        /* Type declarations */
++
++#ifndef OF /* function prototypes */
++#  ifdef STDC
++#    define OF(args)  args
++#  else
++#    define OF(args)  ()
++#  endif
++#endif
++
++/* The following definitions for FAR are needed only for MSDOS mixed
++ * model programming (small or medium model with some far allocations).
++ * This was tested only with MSC; for other MSDOS compilers you may have
++ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
++ * just define FAR to be empty.
++ */
++#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
++   /* MSC small or medium model */
++#  define SMALL_MEDIUM
++#  ifdef _MSC_VER
++#    define FAR _far
++#  else
++#    define FAR far
++#  endif
++#endif
++#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
++#  ifndef __32BIT__
++#    define SMALL_MEDIUM
++#    define FAR _far
++#  endif
++#endif
++
++/* Compile with -DZLIB_DLL for Windows DLL support */
++#if defined(ZLIB_DLL)
++#  if defined(_WINDOWS) || defined(WINDOWS)
++#    ifdef FAR
++#      undef FAR
++#    endif
++#    include <windows.h>
++#    define ZEXPORT  WINAPI
++#    ifdef WIN32
++#      define ZEXPORTVA  WINAPIV
++#    else
++#      define ZEXPORTVA  FAR _cdecl _export
++#    endif
++#  endif
++#  if defined (__BORLANDC__)
++#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)
++#      include <windows.h>
++#      define ZEXPORT __declspec(dllexport) WINAPI
++#      define ZEXPORTRVA __declspec(dllexport) WINAPIV
++#    else
++#      if defined (_Windows) && defined (__DLL__)
++#        define ZEXPORT _export
++#        define ZEXPORTVA _export
++#      endif
++#    endif
++#  endif
++#endif
++
++#if defined (__BEOS__)
++#  if defined (ZLIB_DLL)
++#    define ZEXTERN extern __declspec(dllexport)
++#  else
++#    define ZEXTERN extern __declspec(dllimport)
++#  endif
++#endif
++
++#ifndef ZEXPORT
++#  define ZEXPORT
++#endif
++#ifndef ZEXPORTVA
++#  define ZEXPORTVA
++#endif
++#ifndef ZEXTERN
++#  define ZEXTERN extern
++#endif
++
++#ifndef FAR
++#   define FAR
++#endif
++
++#if !defined(MACOS) && !defined(TARGET_OS_MAC)
++typedef unsigned char  Byte;  /* 8 bits */
++#endif
++typedef unsigned int   uInt;  /* 16 bits or more */
++typedef unsigned long  uLong; /* 32 bits or more */
++
++#ifdef SMALL_MEDIUM
++   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
++#  define Bytef Byte FAR
++#else
++   typedef Byte  FAR Bytef;
++#endif
++typedef char  FAR charf;
++typedef int   FAR intf;
++typedef uInt  FAR uIntf;
++typedef uLong FAR uLongf;
++
++#ifdef STDC
++   typedef void FAR *voidpf;
++   typedef void     *voidp;
++#else
++   typedef Byte FAR *voidpf;
++   typedef Byte     *voidp;
++#endif
++
++#ifdef HAVE_UNISTD_H
++#  include <sys/types.h> /* for off_t */
++#  include <unistd.h>    /* for SEEK_* and off_t */
++#  define z_off_t  off_t
++#endif
++#ifndef SEEK_SET
++#  define SEEK_SET        0       /* Seek from beginning of file.  */
++#  define SEEK_CUR        1       /* Seek from current position.  */
++#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
++#endif
++#ifndef z_off_t
++#  define  z_off_t long
++#endif
++
++/* MVS linker does not support external names larger than 8 bytes */
++#if defined(__MVS__)
++#   pragma map(deflateInit_,"DEIN")
++#   pragma map(deflateInit2_,"DEIN2")
++#   pragma map(deflateEnd,"DEEND")
++#   pragma map(inflateInit_,"ININ")
++#   pragma map(inflateInit2_,"ININ2")
++#   pragma map(inflateEnd,"INEND")
++#   pragma map(inflateSync,"INSY")
++#   pragma map(inflateSetDictionary,"INSEDI")
++#   pragma map(inflate_blocks,"INBL")
++#   pragma map(inflate_blocks_new,"INBLNE")
++#   pragma map(inflate_blocks_free,"INBLFR")
++#   pragma map(inflate_blocks_reset,"INBLRE")
++#   pragma map(inflate_codes_free,"INCOFR")
++#   pragma map(inflate_codes,"INCO")
++#   pragma map(inflate_fast,"INFA")
++#   pragma map(inflate_flush,"INFLU")
++#   pragma map(inflate_mask,"INMA")
++#   pragma map(inflate_set_dictionary,"INSEDI2")
++#   pragma map(ipcomp_inflate_copyright,"INCOPY")
++#   pragma map(inflate_trees_bits,"INTRBI")
++#   pragma map(inflate_trees_dynamic,"INTRDY")
++#   pragma map(inflate_trees_fixed,"INTRFI")
++#   pragma map(inflate_trees_free,"INTRFR")
++#endif
++
++#endif /* _ZCONF_H */
+diff --git a/include/zlib/zlib.h b/include/zlib/zlib.h
+new file mode 100644
+index 0000000..744e382
+--- /dev/null
++++ b/include/zlib/zlib.h
+@@ -0,0 +1,893 @@
++/* zlib.h -- interface of the 'zlib' general purpose compression library
++  version 1.1.4, March 11th, 2002
++
++  Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
++
++  This software is provided 'as-is', without any express or implied
++  warranty.  In no event will the authors be held liable for any damages
++  arising from the use of this software.
++
++  Permission is granted to anyone to use this software for any purpose,
++  including commercial applications, and to alter it and redistribute it
++  freely, subject to the following restrictions:
++
++  1. The origin of this software must not be misrepresented; you must not
++     claim that you wrote the original software. If you use this software
++     in a product, an acknowledgment in the product documentation would be
++     appreciated but is not required.
++  2. Altered source versions must be plainly marked as such, and must not be
++     misrepresented as being the original software.
++  3. This notice may not be removed or altered from any source distribution.
++
++  Jean-loup Gailly        Mark Adler
++  jloup at gzip.org          madler at alumni.caltech.edu
++
++
++  The data format used by the zlib library is described by RFCs (Request for
++  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
++  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
++*/
++
++#ifndef _ZLIB_H
++#define _ZLIB_H
++
++#include "zconf.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#define ZLIB_VERSION "1.1.4"
++
++/* 
++     The 'zlib' compression library provides in-memory compression and
++  decompression functions, including integrity checks of the uncompressed
++  data.  This version of the library supports only one compression method
++  (deflation) but other algorithms will be added later and will have the same
++  stream interface.
++
++     Compression can be done in a single step if the buffers are large
++  enough (for example if an input file is mmap'ed), or can be done by
++  repeated calls of the compression function.  In the latter case, the
++  application must provide more input and/or consume the output
++  (providing more output space) before each call.
++
++     The library also supports reading and writing files in gzip (.gz) format
++  with an interface similar to that of stdio.
++
++     The library does not install any signal handler. The decoder checks
++  the consistency of the compressed data, so the library should never
++  crash even in case of corrupted input.
++*/
++
++typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
++typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
++
++struct internal_state;
++
++typedef struct z_stream_s {
++    Bytef    *next_in;  /* next input byte */
++    uInt     avail_in;  /* number of bytes available at next_in */
++    uLong    total_in;  /* total nb of input bytes read so far */
++
++    Bytef    *next_out; /* next output byte should be put there */
++    uInt     avail_out; /* remaining free space at next_out */
++    uLong    total_out; /* total nb of bytes output so far */
++
++    const char     *msg;      /* last error message, NULL if no error */
++    struct internal_state FAR *state; /* not visible by applications */
++
++    alloc_func zalloc;  /* used to allocate the internal state */
++    free_func  zfree;   /* used to free the internal state */
++    voidpf     opaque;  /* private data object passed to zalloc and zfree */
++
++    int     data_type;  /* best guess about the data type: ascii or binary */
++    uLong   adler;      /* adler32 value of the uncompressed data */
++    uLong   reserved;   /* reserved for future use */
++} z_stream;
++
++typedef z_stream FAR *z_streamp;
++
++/*
++   The application must update next_in and avail_in when avail_in has
++   dropped to zero. It must update next_out and avail_out when avail_out
++   has dropped to zero. The application must initialize zalloc, zfree and
++   opaque before calling the init function. All other fields are set by the
++   compression library and must not be updated by the application.
++
++   The opaque value provided by the application will be passed as the first
++   parameter for calls of zalloc and zfree. This can be useful for custom
++   memory management. The compression library attaches no meaning to the
++   opaque value.
++
++   zalloc must return Z_NULL if there is not enough memory for the object.
++   If zlib is used in a multi-threaded application, zalloc and zfree must be
++   thread safe.
++
++   On 16-bit systems, the functions zalloc and zfree must be able to allocate
++   exactly 65536 bytes, but will not be required to allocate more than this
++   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
++   pointers returned by zalloc for objects of exactly 65536 bytes *must*
++   have their offset normalized to zero. The default allocation function
++   provided by this library ensures this (see zutil.c). To reduce memory
++   requirements and avoid any allocation of 64K objects, at the expense of
++   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
++
++   The fields total_in and total_out can be used for statistics or
++   progress reports. After compression, total_in holds the total size of
++   the uncompressed data and may be saved for use in the decompressor
++   (particularly if the decompressor wants to decompress everything in
++   a single step).
++*/
++
++                        /* constants */
++
++#define Z_NO_FLUSH      0
++#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
++#define Z_SYNC_FLUSH    2
++#define Z_FULL_FLUSH    3
++#define Z_FINISH        4
++/* Allowed flush values; see deflate() below for details */
++
++#define Z_OK            0
++#define Z_STREAM_END    1
++#define Z_NEED_DICT     2
++#define Z_ERRNO        (-1)
++#define Z_STREAM_ERROR (-2)
++#define Z_DATA_ERROR   (-3)
++#define Z_MEM_ERROR    (-4)
++#define Z_BUF_ERROR    (-5)
++#define Z_VERSION_ERROR (-6)
++/* Return codes for the compression/decompression functions. Negative
++ * values are errors, positive values are used for special but normal events.
++ */
++
++#define Z_NO_COMPRESSION         0
++#define Z_BEST_SPEED             1
++#define Z_BEST_COMPRESSION       9
++#define Z_DEFAULT_COMPRESSION  (-1)
++/* compression levels */
++
++#define Z_FILTERED            1
++#define Z_HUFFMAN_ONLY        2
++#define Z_DEFAULT_STRATEGY    0
++/* compression strategy; see deflateInit2() below for details */
++
++#define Z_BINARY   0
++#define Z_ASCII    1
++#define Z_UNKNOWN  2
++/* Possible values of the data_type field */
++
++#define Z_DEFLATED   8
++/* The deflate compression method (the only one supported in this version) */
++
++#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
++
++#define zlib_version zlibVersion()
++/* for compatibility with versions < 1.0.2 */
++
++                        /* basic functions */
++
++ZEXTERN const char * ZEXPORT zlibVersion OF((void));
++/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
++   If the first character differs, the library code actually used is
++   not compatible with the zlib.h header file used by the application.
++   This check is automatically made by deflateInit and inflateInit.
++ */
++
++/* 
++ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
++
++     Initializes the internal stream state for compression. The fields
++   zalloc, zfree and opaque must be initialized before by the caller.
++   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
++   use default allocation functions.
++
++     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
++   1 gives best speed, 9 gives best compression, 0 gives no compression at
++   all (the input data is simply copied a block at a time).
++   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
++   compression (currently equivalent to level 6).
++
++     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
++   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
++   with the version assumed by the caller (ZLIB_VERSION).
++   msg is set to null if there is no error message.  deflateInit does not
++   perform any compression: this will be done by deflate().
++*/
++
++
++ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
++/*
++    deflate compresses as much data as possible, and stops when the input
++  buffer becomes empty or the output buffer becomes full. It may introduce some
++  output latency (reading input without producing any output) except when
++  forced to flush.
++
++    The detailed semantics are as follows. deflate performs one or both of the
++  following actions:
++
++  - Compress more input starting at next_in and update next_in and avail_in
++    accordingly. If not all input can be processed (because there is not
++    enough room in the output buffer), next_in and avail_in are updated and
++    processing will resume at this point for the next call of deflate().
++
++  - Provide more output starting at next_out and update next_out and avail_out
++    accordingly. This action is forced if the parameter flush is non zero.
++    Forcing flush frequently degrades the compression ratio, so this parameter
++    should be set only when necessary (in interactive applications).
++    Some output may be provided even if flush is not set.
++
++  Before the call of deflate(), the application should ensure that at least
++  one of the actions is possible, by providing more input and/or consuming
++  more output, and updating avail_in or avail_out accordingly; avail_out
++  should never be zero before the call. The application can consume the
++  compressed output when it wants, for example when the output buffer is full
++  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
++  and with zero avail_out, it must be called again after making room in the
++  output buffer because there might be more output pending.
++
++    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
++  flushed to the output buffer and the output is aligned on a byte boundary, so
++  that the decompressor can get all input data available so far. (In particular
++  avail_in is zero after the call if enough output space has been provided
++  before the call.)  Flushing may degrade compression for some compression
++  algorithms and so it should be used only when necessary.
++
++    If flush is set to Z_FULL_FLUSH, all output is flushed as with
++  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
++  restart from this point if previous compressed data has been damaged or if
++  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
++  the compression.
++
++    If deflate returns with avail_out == 0, this function must be called again
++  with the same value of the flush parameter and more output space (updated
++  avail_out), until the flush is complete (deflate returns with non-zero
++  avail_out).
++
++    If the parameter flush is set to Z_FINISH, pending input is processed,
++  pending output is flushed and deflate returns with Z_STREAM_END if there
++  was enough output space; if deflate returns with Z_OK, this function must be
++  called again with Z_FINISH and more output space (updated avail_out) but no
++  more input data, until it returns with Z_STREAM_END or an error. After
++  deflate has returned Z_STREAM_END, the only possible operations on the
++  stream are deflateReset or deflateEnd.
++  
++    Z_FINISH can be used immediately after deflateInit if all the compression
++  is to be done in a single step. In this case, avail_out must be at least
++  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
++  Z_STREAM_END, then it must be called again as described above.
++
++    deflate() sets strm->adler to the adler32 checksum of all input read
++  so far (that is, total_in bytes).
++
++    deflate() may update data_type if it can make a good guess about
++  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
++  binary. This field is only for information purposes and does not affect
++  the compression algorithm in any manner.
++
++    deflate() returns Z_OK if some progress has been made (more input
++  processed or more output produced), Z_STREAM_END if all input has been
++  consumed and all output has been produced (only when flush is set to
++  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
++  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
++  (for example avail_in or avail_out was zero).
++*/
++
++
++ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
++/*
++     All dynamically allocated data structures for this stream are freed.
++   This function discards any unprocessed input and does not flush any
++   pending output.
++
++     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
++   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
++   prematurely (some input or output was discarded). In the error case,
++   msg may be set but then points to a static string (which must not be
++   deallocated).
++*/
++
++
++/* 
++ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
++
++     Initializes the internal stream state for decompression. The fields
++   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
++   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
++   value depends on the compression method), inflateInit determines the
++   compression method from the zlib header and allocates all data structures
++   accordingly; otherwise the allocation will be deferred to the first call of
++   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
++   use default allocation functions.
++
++     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
++   version assumed by the caller.  msg is set to null if there is no error
++   message. inflateInit does not perform any decompression apart from reading
++   the zlib header if present: this will be done by inflate().  (So next_in and
++   avail_in may be modified, but next_out and avail_out are unchanged.)
++*/
++
++
++ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
++/*
++    inflate decompresses as much data as possible, and stops when the input
++  buffer becomes empty or the output buffer becomes full. It may some
++  introduce some output latency (reading input without producing any output)
++  except when forced to flush.
++
++  The detailed semantics are as follows. inflate performs one or both of the
++  following actions:
++
++  - Decompress more input starting at next_in and update next_in and avail_in
++    accordingly. If not all input can be processed (because there is not
++    enough room in the output buffer), next_in is updated and processing
++    will resume at this point for the next call of inflate().
++
++  - Provide more output starting at next_out and update next_out and avail_out
++    accordingly.  inflate() provides as much output as possible, until there
++    is no more input data or no more space in the output buffer (see below
++    about the flush parameter).
++
++  Before the call of inflate(), the application should ensure that at least
++  one of the actions is possible, by providing more input and/or consuming
++  more output, and updating the next_* and avail_* values accordingly.
++  The application can consume the uncompressed output when it wants, for
++  example when the output buffer is full (avail_out == 0), or after each
++  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
++  must be called again after making room in the output buffer because there
++  might be more output pending.
++
++    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
++  output as possible to the output buffer. The flushing behavior of inflate is
++  not specified for values of the flush parameter other than Z_SYNC_FLUSH
++  and Z_FINISH, but the current implementation actually flushes as much output
++  as possible anyway.
++
++    inflate() should normally be called until it returns Z_STREAM_END or an
++  error. However if all decompression is to be performed in a single step
++  (a single call of inflate), the parameter flush should be set to
++  Z_FINISH. In this case all pending input is processed and all pending
++  output is flushed; avail_out must be large enough to hold all the
++  uncompressed data. (The size of the uncompressed data may have been saved
++  by the compressor for this purpose.) The next operation on this stream must
++  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
++  is never required, but can be used to inform inflate that a faster routine
++  may be used for the single inflate() call.
++
++     If a preset dictionary is needed at this point (see inflateSetDictionary
++  below), inflate sets strm-adler to the adler32 checksum of the
++  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
++  it sets strm->adler to the adler32 checksum of all output produced
++  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
++  an error code as described below. At the end of the stream, inflate()
++  checks that its computed adler32 checksum is equal to that saved by the
++  compressor and returns Z_STREAM_END only if the checksum is correct.
++
++    inflate() returns Z_OK if some progress has been made (more input processed
++  or more output produced), Z_STREAM_END if the end of the compressed data has
++  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
++  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
++  corrupted (input stream not conforming to the zlib format or incorrect
++  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
++  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
++  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
++  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
++  case, the application may then call inflateSync to look for a good
++  compression block.
++*/
++
++
++ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
++/*
++     All dynamically allocated data structures for this stream are freed.
++   This function discards any unprocessed input and does not flush any
++   pending output.
++
++     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
++   was inconsistent. In the error case, msg may be set but then points to a
++   static string (which must not be deallocated).
++*/
++
++                        /* Advanced functions */
++
++/*
++    The following functions are needed only in some special applications.
++*/
++
++/*   
++ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
++                                     int  level,
++                                     int  method,
++                                     int  windowBits,
++                                     int  memLevel,
++                                     int  strategy));
++
++     This is another version of deflateInit with more compression options. The
++   fields next_in, zalloc, zfree and opaque must be initialized before by
++   the caller.
++
++     The method parameter is the compression method. It must be Z_DEFLATED in
++   this version of the library.
++
++     The windowBits parameter is the base two logarithm of the window size
++   (the size of the history buffer).  It should be in the range 8..15 for this
++   version of the library. Larger values of this parameter result in better
++   compression at the expense of memory usage. The default value is 15 if
++   deflateInit is used instead.
++
++     The memLevel parameter specifies how much memory should be allocated
++   for the internal compression state. memLevel=1 uses minimum memory but
++   is slow and reduces compression ratio; memLevel=9 uses maximum memory
++   for optimal speed. The default value is 8. See zconf.h for total memory
++   usage as a function of windowBits and memLevel.
++
++     The strategy parameter is used to tune the compression algorithm. Use the
++   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
++   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
++   string match).  Filtered data consists mostly of small values with a
++   somewhat random distribution. In this case, the compression algorithm is
++   tuned to compress them better. The effect of Z_FILTERED is to force more
++   Huffman coding and less string matching; it is somewhat intermediate
++   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
++   the compression ratio but not the correctness of the compressed output even
++   if it is not set appropriately.
++
++      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
++   method). msg is set to null if there is no error message.  deflateInit2 does
++   not perform any compression: this will be done by deflate().
++*/
++                            
++ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
++                                             const Bytef *dictionary,
++                                             uInt  dictLength));
++/*
++     Initializes the compression dictionary from the given byte sequence
++   without producing any compressed output. This function must be called
++   immediately after deflateInit, deflateInit2 or deflateReset, before any
++   call of deflate. The compressor and decompressor must use exactly the same
++   dictionary (see inflateSetDictionary).
++
++     The dictionary should consist of strings (byte sequences) that are likely
++   to be encountered later in the data to be compressed, with the most commonly
++   used strings preferably put towards the end of the dictionary. Using a
++   dictionary is most useful when the data to be compressed is short and can be
++   predicted with good accuracy; the data can then be compressed better than
++   with the default empty dictionary.
++
++     Depending on the size of the compression data structures selected by
++   deflateInit or deflateInit2, a part of the dictionary may in effect be
++   discarded, for example if the dictionary is larger than the window size in
++   deflate or deflate2. Thus the strings most likely to be useful should be
++   put at the end of the dictionary, not at the front.
++
++     Upon return of this function, strm->adler is set to the Adler32 value
++   of the dictionary; the decompressor may later use this value to determine
++   which dictionary has been used by the compressor. (The Adler32 value
++   applies to the whole dictionary even if only a subset of the dictionary is
++   actually used by the compressor.)
++
++     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
++   parameter is invalid (such as NULL dictionary) or the stream state is
++   inconsistent (for example if deflate has already been called for this stream
++   or if the compression method is bsort). deflateSetDictionary does not
++   perform any compression: this will be done by deflate().
++*/
++
++ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
++                                    z_streamp source));
++/*
++     Sets the destination stream as a complete copy of the source stream.
++
++     This function can be useful when several compression strategies will be
++   tried, for example when there are several ways of pre-processing the input
++   data with a filter. The streams that will be discarded should then be freed
++   by calling deflateEnd.  Note that deflateCopy duplicates the internal
++   compression state which can be quite large, so this strategy is slow and
++   can consume lots of memory.
++
++     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
++   (such as zalloc being NULL). msg is left unchanged in both source and
++   destination.
++*/
++
++ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
++/*
++     This function is equivalent to deflateEnd followed by deflateInit,
++   but does not free and reallocate all the internal compression state.
++   The stream will keep the same compression level and any other attributes
++   that may have been set by deflateInit2.
++
++      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
++   stream state was inconsistent (such as zalloc or state being NULL).
++*/
++
++ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
++				      int level,
++				      int strategy));
++/*
++     Dynamically update the compression level and compression strategy.  The
++   interpretation of level and strategy is as in deflateInit2.  This can be
++   used to switch between compression and straight copy of the input data, or
++   to switch to a different kind of input data requiring a different
++   strategy. If the compression level is changed, the input available so far
++   is compressed with the old level (and may be flushed); the new level will
++   take effect only at the next call of deflate().
++
++     Before the call of deflateParams, the stream state must be set as for
++   a call of deflate(), since the currently available input may have to
++   be compressed and flushed. In particular, strm->avail_out must be non-zero.
++
++     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
++   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
++   if strm->avail_out was zero.
++*/
++
++/*   
++ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
++                                     int  windowBits));
++
++     This is another version of inflateInit with an extra parameter. The
++   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
++   before by the caller.
++
++     The windowBits parameter is the base two logarithm of the maximum window
++   size (the size of the history buffer).  It should be in the range 8..15 for
++   this version of the library. The default value is 15 if inflateInit is used
++   instead. If a compressed stream with a larger window size is given as
++   input, inflate() will return with the error code Z_DATA_ERROR instead of
++   trying to allocate a larger window.
++
++      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
++   memLevel). msg is set to null if there is no error message.  inflateInit2
++   does not perform any decompression apart from reading the zlib header if
++   present: this will be done by inflate(). (So next_in and avail_in may be
++   modified, but next_out and avail_out are unchanged.)
++*/
++
++ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
++                                             const Bytef *dictionary,
++                                             uInt  dictLength));
++/*
++     Initializes the decompression dictionary from the given uncompressed byte
++   sequence. This function must be called immediately after a call of inflate
++   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
++   can be determined from the Adler32 value returned by this call of
++   inflate. The compressor and decompressor must use exactly the same
++   dictionary (see deflateSetDictionary).
++
++     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
++   parameter is invalid (such as NULL dictionary) or the stream state is
++   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
++   expected one (incorrect Adler32 value). inflateSetDictionary does not
++   perform any decompression: this will be done by subsequent calls of
++   inflate().
++*/
++
++ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
++/* 
++    Skips invalid compressed data until a full flush point (see above the
++  description of deflate with Z_FULL_FLUSH) can be found, or until all
++  available input is skipped. No output is provided.
++
++    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
++  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
++  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
++  case, the application may save the current current value of total_in which
++  indicates where valid compressed data was found. In the error case, the
++  application may repeatedly call inflateSync, providing more input each time,
++  until success or end of the input data.
++*/
++
++ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
++/*
++     This function is equivalent to inflateEnd followed by inflateInit,
++   but does not free and reallocate all the internal decompression state.
++   The stream will keep attributes that may have been set by inflateInit2.
++
++      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
++   stream state was inconsistent (such as zalloc or state being NULL).
++*/
++
++
++                        /* utility functions */
++
++/*
++     The following utility functions are implemented on top of the
++   basic stream-oriented functions. To simplify the interface, some
++   default options are assumed (compression level and memory usage,
++   standard memory allocation functions). The source code of these
++   utility functions can easily be modified if you need special options.
++*/
++
++ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
++                                 const Bytef *source, uLong sourceLen));
++/*
++     Compresses the source buffer into the destination buffer.  sourceLen is
++   the byte length of the source buffer. Upon entry, destLen is the total
++   size of the destination buffer, which must be at least 0.1% larger than
++   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
++   compressed buffer.
++     This function can be used to compress a whole file at once if the
++   input file is mmap'ed.
++     compress returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_BUF_ERROR if there was not enough room in the output
++   buffer.
++*/
++
++ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
++                                  const Bytef *source, uLong sourceLen,
++                                  int level));
++/*
++     Compresses the source buffer into the destination buffer. The level
++   parameter has the same meaning as in deflateInit.  sourceLen is the byte
++   length of the source buffer. Upon entry, destLen is the total size of the
++   destination buffer, which must be at least 0.1% larger than sourceLen plus
++   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
++
++     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
++   Z_STREAM_ERROR if the level parameter is invalid.
++*/
++
++ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
++                                   const Bytef *source, uLong sourceLen));
++/*
++     Decompresses the source buffer into the destination buffer.  sourceLen is
++   the byte length of the source buffer. Upon entry, destLen is the total
++   size of the destination buffer, which must be large enough to hold the
++   entire uncompressed data. (The size of the uncompressed data must have
++   been saved previously by the compressor and transmitted to the decompressor
++   by some mechanism outside the scope of this compression library.)
++   Upon exit, destLen is the actual size of the compressed buffer.
++     This function can be used to decompress a whole file at once if the
++   input file is mmap'ed.
++
++     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_BUF_ERROR if there was not enough room in the output
++   buffer, or Z_DATA_ERROR if the input data was corrupted.
++*/
++
++
++typedef voidp gzFile;
++
++ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
++/*
++     Opens a gzip (.gz) file for reading or writing. The mode parameter
++   is as in fopen ("rb" or "wb") but can also include a compression level
++   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
++   Huffman only compression as in "wb1h". (See the description
++   of deflateInit2 for more information about the strategy parameter.)
++
++     gzopen can be used to read a file which is not in gzip format; in this
++   case gzread will directly read from the file without decompression.
++
++     gzopen returns NULL if the file could not be opened or if there was
++   insufficient memory to allocate the (de)compression state; errno
++   can be checked to distinguish the two cases (if errno is zero, the
++   zlib error is Z_MEM_ERROR).  */
++
++ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
++/*
++     gzdopen() associates a gzFile with the file descriptor fd.  File
++   descriptors are obtained from calls like open, dup, creat, pipe or
++   fileno (in the file has been previously opened with fopen).
++   The mode parameter is as in gzopen.
++     The next call of gzclose on the returned gzFile will also close the
++   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
++   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
++     gzdopen returns NULL if there was insufficient memory to allocate
++   the (de)compression state.
++*/
++
++ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
++/*
++     Dynamically update the compression level or strategy. See the description
++   of deflateInit2 for the meaning of these parameters.
++     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
++   opened for writing.
++*/
++
++ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
++/*
++     Reads the given number of uncompressed bytes from the compressed file.
++   If the input file was not in gzip format, gzread copies the given number
++   of bytes into the buffer.
++     gzread returns the number of uncompressed bytes actually read (0 for
++   end of file, -1 for error). */
++
++ZEXTERN int ZEXPORT    gzwrite OF((gzFile file, 
++				   const voidp buf, unsigned len));
++/*
++     Writes the given number of uncompressed bytes into the compressed file.
++   gzwrite returns the number of uncompressed bytes actually written
++   (0 in case of error).
++*/
++
++ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
++/*
++     Converts, formats, and writes the args to the compressed file under
++   control of the format string, as in fprintf. gzprintf returns the number of
++   uncompressed bytes actually written (0 in case of error).
++*/
++
++ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
++/*
++      Writes the given null-terminated string to the compressed file, excluding
++   the terminating null character.
++      gzputs returns the number of characters written, or -1 in case of error.
++*/
++
++ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
++/*
++      Reads bytes from the compressed file until len-1 characters are read, or
++   a newline character is read and transferred to buf, or an end-of-file
++   condition is encountered.  The string is then terminated with a null
++   character.
++      gzgets returns buf, or Z_NULL in case of error.
++*/
++
++ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
++/*
++      Writes c, converted to an unsigned char, into the compressed file.
++   gzputc returns the value that was written, or -1 in case of error.
++*/
++
++ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
++/*
++      Reads one byte from the compressed file. gzgetc returns this byte
++   or -1 in case of end of file or error.
++*/
++
++ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
++/*
++     Flushes all pending output into the compressed file. The parameter
++   flush is as in the deflate() function. The return value is the zlib
++   error number (see function gzerror below). gzflush returns Z_OK if
++   the flush parameter is Z_FINISH and all output could be flushed.
++     gzflush should be called only when strictly necessary because it can
++   degrade compression.
++*/
++
++ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
++				      z_off_t offset, int whence));
++/* 
++      Sets the starting position for the next gzread or gzwrite on the
++   given compressed file. The offset represents a number of bytes in the
++   uncompressed data stream. The whence parameter is defined as in lseek(2);
++   the value SEEK_END is not supported.
++     If the file is opened for reading, this function is emulated but can be
++   extremely slow. If the file is opened for writing, only forward seeks are
++   supported; gzseek then compresses a sequence of zeroes up to the new
++   starting position.
++
++      gzseek returns the resulting offset location as measured in bytes from
++   the beginning of the uncompressed stream, or -1 in case of error, in
++   particular if the file is opened for writing and the new starting position
++   would be before the current position.
++*/
++
++ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
++/*
++     Rewinds the given file. This function is supported only for reading.
++
++   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
++*/
++
++ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
++/*
++     Returns the starting position for the next gzread or gzwrite on the
++   given compressed file. This position represents a number of bytes in the
++   uncompressed data stream.
++
++   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
++*/
++
++ZEXTERN int ZEXPORT gzeof OF((gzFile file));
++/*
++     Returns 1 when EOF has previously been detected reading the given
++   input stream, otherwise zero.
++*/
++
++ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
++/*
++     Flushes all pending output if necessary, closes the compressed file
++   and deallocates all the (de)compression state. The return value is the zlib
++   error number (see function gzerror below).
++*/
++
++ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
++/*
++     Returns the error message for the last error which occurred on the
++   given compressed file. errnum is set to zlib error number. If an
++   error occurred in the file system and not in the compression library,
++   errnum is set to Z_ERRNO and the application may consult errno
++   to get the exact error code.
++*/
++
++                        /* checksum functions */
++
++/*
++     These functions are not related to compression but are exported
++   anyway because they might be useful in applications using the
++   compression library.
++*/
++
++ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
++
++/*
++     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
++   return the updated checksum. If buf is NULL, this function returns
++   the required initial value for the checksum.
++   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
++   much faster. Usage example:
++
++     uLong adler = adler32(0L, Z_NULL, 0);
++
++     while (read_buffer(buffer, length) != EOF) {
++       adler = adler32(adler, buffer, length);
++     }
++     if (adler != original_adler) error();
++*/
++
++ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
++/*
++     Update a running crc with the bytes buf[0..len-1] and return the updated
++   crc. If buf is NULL, this function returns the required initial value
++   for the crc. Pre- and post-conditioning (one's complement) is performed
++   within this function so it shouldn't be done by the application.
++   Usage example:
++
++     uLong crc = crc32(0L, Z_NULL, 0);
++
++     while (read_buffer(buffer, length) != EOF) {
++       crc = crc32(crc, buffer, length);
++     }
++     if (crc != original_crc) error();
++*/
++
++
++                        /* various hacks, don't look :) */
++
++/* deflateInit and inflateInit are macros to allow checking the zlib version
++ * and the compiler's view of z_stream:
++ */
++ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
++                                     const char *version, int stream_size));
++ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
++                                     const char *version, int stream_size));
++ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
++                                      int windowBits, int memLevel,
++                                      int strategy, const char *version,
++                                      int stream_size));
++ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
++                                      const char *version, int stream_size));
++#define deflateInit(strm, level) \
++        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
++#define inflateInit(strm) \
++        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
++#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
++        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
++                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
++#define inflateInit2(strm, windowBits) \
++        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
++
++
++#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
++    struct internal_state {int dummy;}; /* hack for buggy compilers */
++#endif
++
++ZEXTERN const char   * ZEXPORT zError           OF((int err));
++ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
++ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _ZLIB_H */
+diff --git a/include/zlib/zutil.h b/include/zlib/zutil.h
+new file mode 100644
+index 0000000..00059d7
+--- /dev/null
++++ b/include/zlib/zutil.h
+@@ -0,0 +1,225 @@
++/* zutil.h -- internal interface and configuration of the compression library
++ * Copyright (C) 1995-2002 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++/* @(#) $Id$ */
++
++#ifndef _Z_UTIL_H
++#define _Z_UTIL_H
++
++#include "zlib.h"
++
++#include <linux/string.h>
++#define HAVE_MEMCPY
++
++#if 0 // #ifdef STDC
++#  include <stddef.h>
++#  include <string.h>
++#  include <stdlib.h>
++#endif
++#ifndef __KERNEL__
++#ifdef NO_ERRNO_H
++    extern int errno;
++#else
++#   include <errno.h>
++#endif
++#endif
++
++#ifndef local
++#  define local static
++#endif
++/* compile with -Dlocal if your debugger can't find static symbols */
++
++typedef unsigned char  uch;
++typedef uch FAR uchf;
++typedef unsigned short ush;
++typedef ush FAR ushf;
++typedef unsigned long  ulg;
++
++extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
++/* (size given to avoid silly warnings with Visual C++) */
++
++#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
++
++#define ERR_RETURN(strm,err) \
++  return (strm->msg = ERR_MSG(err), (err))
++/* To be used only when the state is known to be valid */
++
++        /* common constants */
++
++#ifndef DEF_WBITS
++#  define DEF_WBITS MAX_WBITS
++#endif
++/* default windowBits for decompression. MAX_WBITS is for compression only */
++
++#if MAX_MEM_LEVEL >= 8
++#  define DEF_MEM_LEVEL 8
++#else
++#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
++#endif
++/* default memLevel */
++
++#define STORED_BLOCK 0
++#define STATIC_TREES 1
++#define DYN_TREES    2
++/* The three kinds of block type */
++
++#define MIN_MATCH  3
++#define MAX_MATCH  258
++/* The minimum and maximum match lengths */
++
++#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
++
++        /* target dependencies */
++
++#ifdef MSDOS
++#  define OS_CODE  0x00
++#  if defined(__TURBOC__) || defined(__BORLANDC__)
++#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
++       /* Allow compilation with ANSI keywords only enabled */
++       void _Cdecl farfree( void *block );
++       void *_Cdecl farmalloc( unsigned long nbytes );
++#    else
++#     include <alloc.h>
++#    endif
++#  else /* MSC or DJGPP */
++#    include <malloc.h>
++#  endif
++#endif
++
++#ifdef OS2
++#  define OS_CODE  0x06
++#endif
++
++#ifdef WIN32 /* Window 95 & Windows NT */
++#  define OS_CODE  0x0b
++#endif
++
++#if defined(VAXC) || defined(VMS)
++#  define OS_CODE  0x02
++#  define F_OPEN(name, mode) \
++     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
++#endif
++
++#ifdef AMIGA
++#  define OS_CODE  0x01
++#endif
++
++#if defined(ATARI) || defined(atarist)
++#  define OS_CODE  0x05
++#endif
++
++#if defined(MACOS) || defined(TARGET_OS_MAC)
++#  define OS_CODE  0x07
++#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
++#    include <unix.h> /* for fdopen */
++#  else
++#    ifndef fdopen
++#      define fdopen(fd,mode) NULL /* No fdopen() */
++#    endif
++#  endif
++#endif
++
++#ifdef __50SERIES /* Prime/PRIMOS */
++#  define OS_CODE  0x0F
++#endif
++
++#ifdef TOPS20
++#  define OS_CODE  0x0a
++#endif
++
++#if defined(_BEOS_) || defined(RISCOS)
++#  define fdopen(fd,mode) NULL /* No fdopen() */
++#endif
++
++#if (defined(_MSC_VER) && (_MSC_VER > 600))
++#  define fdopen(fd,type)  _fdopen(fd,type)
++#endif
++
++
++        /* Common defaults */
++
++#ifndef OS_CODE
++#  define OS_CODE  0x03  /* assume Unix */
++#endif
++
++#ifndef F_OPEN
++#  define F_OPEN(name, mode) fopen((name), (mode))
++#endif
++
++         /* functions */
++
++#ifdef HAVE_STRERROR
++   extern char *strerror OF((int));
++#  define zstrerror(errnum) strerror(errnum)
++#else
++#  define zstrerror(errnum) ""
++#endif
++
++#if defined(pyr)
++#  define NO_MEMCPY
++#endif
++#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
++ /* Use our own functions for small and medium model with MSC <= 5.0.
++  * You may have to use the same strategy for Borland C (untested).
++  * The __SC__ check is for Symantec.
++  */
++#  define NO_MEMCPY
++#endif
++#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
++#  define HAVE_MEMCPY
++#endif
++#ifdef HAVE_MEMCPY
++#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
++#    define zmemcpy _fmemcpy
++#    define zmemcmp _fmemcmp
++#    define zmemzero(dest, len) _fmemset(dest, 0, len)
++#  else
++#    define zmemcpy memcpy
++#    define zmemcmp memcmp
++#    define zmemzero(dest, len) memset(dest, 0, len)
++#  endif
++#else
++   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
++   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
++   extern void zmemzero OF((Bytef* dest, uInt len));
++#endif
++
++/* Diagnostic functions */
++#ifdef DEBUG
++#  include <stdio.h>
++   extern int z_verbose;
++   extern void z_error    OF((char *m));
++#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
++#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
++#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
++#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
++#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
++#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
++#else
++#  define Assert(cond,msg)
++#  define Trace(x)
++#  define Tracev(x)
++#  define Tracevv(x)
++#  define Tracec(c,x)
++#  define Tracecv(c,x)
++#endif
++
++
++typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
++				       uInt len));
++voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
++void   zcfree  OF((voidpf opaque, voidpf ptr));
++
++#define ZALLOC(strm, items, size) \
++           (*((strm)->zalloc))((strm)->opaque, (items), (size))
++#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
++#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
++
++#endif /* _Z_UTIL_H */
+diff --git a/include/spr.h b/include/spr.h
+new file mode 100644
+index 0000000..a84d6a7
+--- /dev/null
++++ b/include/spr.h
+@@ -0,0 +1,204 @@
++/* crypto/des/spr.h */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++const DES_LONG des_SPtrans[8][64]={
++{
++/* nibble 0 */
++0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
++0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
++0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
++0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
++0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
++0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
++0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
++0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
++0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
++0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
++0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
++0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
++0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
++0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
++0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
++0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
++},{
++/* nibble 1 */
++0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
++0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
++0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
++0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
++0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
++0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
++0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
++0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
++0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
++0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
++0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
++0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
++0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
++0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
++0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
++0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
++},{
++/* nibble 2 */
++0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
++0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
++0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
++0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
++0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
++0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
++0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
++0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
++0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
++0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
++0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
++0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
++0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
++0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
++0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
++0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
++},{
++/* nibble 3 */
++0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
++0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
++0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
++0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
++0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
++0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
++0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
++0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
++0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
++0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
++0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
++0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
++0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
++0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
++0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
++0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
++},{
++/* nibble 4 */
++0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
++0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
++0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
++0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
++0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
++0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
++0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
++0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
++0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
++0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
++0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
++0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
++0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
++0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
++0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
++0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
++},{
++/* nibble 5 */
++0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
++0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
++0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
++0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
++0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
++0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
++0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
++0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
++0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
++0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
++0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
++0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
++0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
++0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
++0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
++0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
++},{
++/* nibble 6 */
++0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
++0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
++0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
++0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
++0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
++0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
++0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
++0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
++0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
++0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
++0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
++0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
++0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
++0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
++0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
++0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
++},{
++/* nibble 7 */
++0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
++0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
++0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
++0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
++0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
++0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
++0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
++0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
++0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
++0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
++0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
++0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
++0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
++0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
++0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
++0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
++}};
+diff --git a/include/trees.h b/include/trees.h
+new file mode 100644
+index 0000000..72facf9
+--- /dev/null
++++ b/include/trees.h
+@@ -0,0 +1,128 @@
++/* header created automatically with -DGEN_TREES_H */
++
++local const ct_data static_ltree[L_CODES+2] = {
++{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
++{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
++{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
++{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
++{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
++{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
++{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
++{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
++{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
++{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
++{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
++{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
++{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
++{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
++{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
++{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
++{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
++{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
++{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
++{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
++{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
++{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
++{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
++{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
++{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
++{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
++{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
++{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
++{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
++{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
++{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
++{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
++{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
++{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
++{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
++{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
++{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
++{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
++{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
++{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
++{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
++{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
++{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
++{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
++{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
++{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
++{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
++{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
++{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
++{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
++{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
++{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
++{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
++{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
++{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
++{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
++{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
++{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
++};
++
++local const ct_data static_dtree[D_CODES] = {
++{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
++{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
++{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
++{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
++{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
++{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
++};
++
++const uch _dist_code[DIST_CODE_LEN] = {
++ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
++ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
++10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
++11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
++12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
++13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
++13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
++14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
++14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
++14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
++18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
++23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
++24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
++27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
++27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
++28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
++28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
++28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
++};
++
++const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
++ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
++13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
++17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
++19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
++21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
++22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
++23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
++24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
++25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
++25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
++26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
++27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
++};
++
++local const int base_length[LENGTH_CODES] = {
++0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
++64, 80, 96, 112, 128, 160, 192, 224, 0
++};
++
++local const int base_dist[D_CODES] = {
++    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
++   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
++ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
++};
++
+diff --git a/include/sk.h b/include/sk.h
+new file mode 100644
+index 0000000..2407030
+--- /dev/null
++++ b/include/sk.h
+@@ -0,0 +1,204 @@
++/* crypto/des/sk.h */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++static const DES_LONG des_skb[8][64]={
++{
++/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
++0x00000000L,0x00000010L,0x20000000L,0x20000010L,
++0x00010000L,0x00010010L,0x20010000L,0x20010010L,
++0x00000800L,0x00000810L,0x20000800L,0x20000810L,
++0x00010800L,0x00010810L,0x20010800L,0x20010810L,
++0x00000020L,0x00000030L,0x20000020L,0x20000030L,
++0x00010020L,0x00010030L,0x20010020L,0x20010030L,
++0x00000820L,0x00000830L,0x20000820L,0x20000830L,
++0x00010820L,0x00010830L,0x20010820L,0x20010830L,
++0x00080000L,0x00080010L,0x20080000L,0x20080010L,
++0x00090000L,0x00090010L,0x20090000L,0x20090010L,
++0x00080800L,0x00080810L,0x20080800L,0x20080810L,
++0x00090800L,0x00090810L,0x20090800L,0x20090810L,
++0x00080020L,0x00080030L,0x20080020L,0x20080030L,
++0x00090020L,0x00090030L,0x20090020L,0x20090030L,
++0x00080820L,0x00080830L,0x20080820L,0x20080830L,
++0x00090820L,0x00090830L,0x20090820L,0x20090830L,
++},{
++/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
++0x00000000L,0x02000000L,0x00002000L,0x02002000L,
++0x00200000L,0x02200000L,0x00202000L,0x02202000L,
++0x00000004L,0x02000004L,0x00002004L,0x02002004L,
++0x00200004L,0x02200004L,0x00202004L,0x02202004L,
++0x00000400L,0x02000400L,0x00002400L,0x02002400L,
++0x00200400L,0x02200400L,0x00202400L,0x02202400L,
++0x00000404L,0x02000404L,0x00002404L,0x02002404L,
++0x00200404L,0x02200404L,0x00202404L,0x02202404L,
++0x10000000L,0x12000000L,0x10002000L,0x12002000L,
++0x10200000L,0x12200000L,0x10202000L,0x12202000L,
++0x10000004L,0x12000004L,0x10002004L,0x12002004L,
++0x10200004L,0x12200004L,0x10202004L,0x12202004L,
++0x10000400L,0x12000400L,0x10002400L,0x12002400L,
++0x10200400L,0x12200400L,0x10202400L,0x12202400L,
++0x10000404L,0x12000404L,0x10002404L,0x12002404L,
++0x10200404L,0x12200404L,0x10202404L,0x12202404L,
++},{
++/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
++0x00000000L,0x00000001L,0x00040000L,0x00040001L,
++0x01000000L,0x01000001L,0x01040000L,0x01040001L,
++0x00000002L,0x00000003L,0x00040002L,0x00040003L,
++0x01000002L,0x01000003L,0x01040002L,0x01040003L,
++0x00000200L,0x00000201L,0x00040200L,0x00040201L,
++0x01000200L,0x01000201L,0x01040200L,0x01040201L,
++0x00000202L,0x00000203L,0x00040202L,0x00040203L,
++0x01000202L,0x01000203L,0x01040202L,0x01040203L,
++0x08000000L,0x08000001L,0x08040000L,0x08040001L,
++0x09000000L,0x09000001L,0x09040000L,0x09040001L,
++0x08000002L,0x08000003L,0x08040002L,0x08040003L,
++0x09000002L,0x09000003L,0x09040002L,0x09040003L,
++0x08000200L,0x08000201L,0x08040200L,0x08040201L,
++0x09000200L,0x09000201L,0x09040200L,0x09040201L,
++0x08000202L,0x08000203L,0x08040202L,0x08040203L,
++0x09000202L,0x09000203L,0x09040202L,0x09040203L,
++},{
++/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
++0x00000000L,0x00100000L,0x00000100L,0x00100100L,
++0x00000008L,0x00100008L,0x00000108L,0x00100108L,
++0x00001000L,0x00101000L,0x00001100L,0x00101100L,
++0x00001008L,0x00101008L,0x00001108L,0x00101108L,
++0x04000000L,0x04100000L,0x04000100L,0x04100100L,
++0x04000008L,0x04100008L,0x04000108L,0x04100108L,
++0x04001000L,0x04101000L,0x04001100L,0x04101100L,
++0x04001008L,0x04101008L,0x04001108L,0x04101108L,
++0x00020000L,0x00120000L,0x00020100L,0x00120100L,
++0x00020008L,0x00120008L,0x00020108L,0x00120108L,
++0x00021000L,0x00121000L,0x00021100L,0x00121100L,
++0x00021008L,0x00121008L,0x00021108L,0x00121108L,
++0x04020000L,0x04120000L,0x04020100L,0x04120100L,
++0x04020008L,0x04120008L,0x04020108L,0x04120108L,
++0x04021000L,0x04121000L,0x04021100L,0x04121100L,
++0x04021008L,0x04121008L,0x04021108L,0x04121108L,
++},{
++/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
++0x00000000L,0x10000000L,0x00010000L,0x10010000L,
++0x00000004L,0x10000004L,0x00010004L,0x10010004L,
++0x20000000L,0x30000000L,0x20010000L,0x30010000L,
++0x20000004L,0x30000004L,0x20010004L,0x30010004L,
++0x00100000L,0x10100000L,0x00110000L,0x10110000L,
++0x00100004L,0x10100004L,0x00110004L,0x10110004L,
++0x20100000L,0x30100000L,0x20110000L,0x30110000L,
++0x20100004L,0x30100004L,0x20110004L,0x30110004L,
++0x00001000L,0x10001000L,0x00011000L,0x10011000L,
++0x00001004L,0x10001004L,0x00011004L,0x10011004L,
++0x20001000L,0x30001000L,0x20011000L,0x30011000L,
++0x20001004L,0x30001004L,0x20011004L,0x30011004L,
++0x00101000L,0x10101000L,0x00111000L,0x10111000L,
++0x00101004L,0x10101004L,0x00111004L,0x10111004L,
++0x20101000L,0x30101000L,0x20111000L,0x30111000L,
++0x20101004L,0x30101004L,0x20111004L,0x30111004L,
++},{
++/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
++0x00000000L,0x08000000L,0x00000008L,0x08000008L,
++0x00000400L,0x08000400L,0x00000408L,0x08000408L,
++0x00020000L,0x08020000L,0x00020008L,0x08020008L,
++0x00020400L,0x08020400L,0x00020408L,0x08020408L,
++0x00000001L,0x08000001L,0x00000009L,0x08000009L,
++0x00000401L,0x08000401L,0x00000409L,0x08000409L,
++0x00020001L,0x08020001L,0x00020009L,0x08020009L,
++0x00020401L,0x08020401L,0x00020409L,0x08020409L,
++0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
++0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
++0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
++0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
++0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
++0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
++0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
++0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
++},{
++/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
++0x00000000L,0x00000100L,0x00080000L,0x00080100L,
++0x01000000L,0x01000100L,0x01080000L,0x01080100L,
++0x00000010L,0x00000110L,0x00080010L,0x00080110L,
++0x01000010L,0x01000110L,0x01080010L,0x01080110L,
++0x00200000L,0x00200100L,0x00280000L,0x00280100L,
++0x01200000L,0x01200100L,0x01280000L,0x01280100L,
++0x00200010L,0x00200110L,0x00280010L,0x00280110L,
++0x01200010L,0x01200110L,0x01280010L,0x01280110L,
++0x00000200L,0x00000300L,0x00080200L,0x00080300L,
++0x01000200L,0x01000300L,0x01080200L,0x01080300L,
++0x00000210L,0x00000310L,0x00080210L,0x00080310L,
++0x01000210L,0x01000310L,0x01080210L,0x01080310L,
++0x00200200L,0x00200300L,0x00280200L,0x00280300L,
++0x01200200L,0x01200300L,0x01280200L,0x01280300L,
++0x00200210L,0x00200310L,0x00280210L,0x00280310L,
++0x01200210L,0x01200310L,0x01280210L,0x01280310L,
++},{
++/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
++0x00000000L,0x04000000L,0x00040000L,0x04040000L,
++0x00000002L,0x04000002L,0x00040002L,0x04040002L,
++0x00002000L,0x04002000L,0x00042000L,0x04042000L,
++0x00002002L,0x04002002L,0x00042002L,0x04042002L,
++0x00000020L,0x04000020L,0x00040020L,0x04040020L,
++0x00000022L,0x04000022L,0x00040022L,0x04040022L,
++0x00002020L,0x04002020L,0x00042020L,0x04042020L,
++0x00002022L,0x04002022L,0x00042022L,0x04042022L,
++0x00000800L,0x04000800L,0x00040800L,0x04040800L,
++0x00000802L,0x04000802L,0x00040802L,0x04040802L,
++0x00002800L,0x04002800L,0x00042800L,0x04042800L,
++0x00002802L,0x04002802L,0x00042802L,0x04042802L,
++0x00000820L,0x04000820L,0x00040820L,0x04040820L,
++0x00000822L,0x04000822L,0x00040822L,0x04040822L,
++0x00002820L,0x04002820L,0x00042820L,0x04042820L,
++0x00002822L,0x04002822L,0x00042822L,0x04042822L,
++}};
+diff --git a/include/podd.h b/include/podd.h
+new file mode 100644
+index 0000000..c00cd6b
+--- /dev/null
++++ b/include/podd.h
+@@ -0,0 +1,75 @@
++/* crypto/des/podd.h */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++static const unsigned char odd_parity[256]={
++  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
++ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
++ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
++ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
++ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
++ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
++ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
++112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
++128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
++145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
++161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
++176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
++193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
++208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
++224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
++241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
+diff --git a/include/pfkeyv2.h b/include/pfkeyv2.h
+new file mode 100644
+index 0000000..4367254
+--- /dev/null
++++ b/include/pfkeyv2.h
+@@ -0,0 +1,443 @@
++/*
++ * RCSID $Id$
++ */
++
++/*
++RFC 2367               PF_KEY Key Management API               July 1998
++
++
++Appendix D: Sample Header File
++
++This file defines structures and symbols for the PF_KEY Version 2
++key management interface. It was written at the U.S. Naval Research
++Laboratory. This file is in the public domain. The authors ask that
++you leave this credit intact on any copies of this file.
++*/
++#ifndef __PFKEY_V2_H
++#define __PFKEY_V2_H 1
++
++#define PF_KEY_V2 2
++#define PFKEYV2_REVISION        199806L
++
++#define SADB_RESERVED    0
++#define SADB_GETSPI      1
++#define SADB_UPDATE      2
++#define SADB_ADD         3
++#define SADB_DELETE      4
++#define SADB_GET         5
++#define SADB_ACQUIRE     6
++#define SADB_REGISTER    7
++#define SADB_EXPIRE      8
++#define SADB_FLUSH       9
++#define SADB_DUMP       10
++#define SADB_X_PROMISC  11
++#define SADB_X_PCHANGE  12
++#define SADB_X_GRPSA    13
++#define SADB_X_ADDFLOW	14
++#define SADB_X_DELFLOW	15
++#define SADB_X_DEBUG	16
++#define SADB_MAX        16
++
++struct sadb_msg {
++  uint8_t sadb_msg_version;
++  uint8_t sadb_msg_type;
++  uint8_t sadb_msg_errno;
++  uint8_t sadb_msg_satype;
++  uint16_t sadb_msg_len;
++  uint16_t sadb_msg_reserved;
++  uint32_t sadb_msg_seq;
++  uint32_t sadb_msg_pid;
++};
++
++struct sadb_ext {
++  uint16_t sadb_ext_len;
++  uint16_t sadb_ext_type;
++};
++
++struct sadb_sa {
++  uint16_t sadb_sa_len;
++  uint16_t sadb_sa_exttype;
++  uint32_t sadb_sa_spi;
++  uint8_t sadb_sa_replay;
++  uint8_t sadb_sa_state;
++  uint8_t sadb_sa_auth;
++  uint8_t sadb_sa_encrypt;
++  uint32_t sadb_sa_flags;
++  uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
++  uint8_t sadb_x_reserved[4];
++};
++
++struct sadb_sa_v1 {
++  uint16_t sadb_sa_len;
++  uint16_t sadb_sa_exttype;
++  uint32_t sadb_sa_spi;
++  uint8_t sadb_sa_replay;
++  uint8_t sadb_sa_state;
++  uint8_t sadb_sa_auth;
++  uint8_t sadb_sa_encrypt;
++  uint32_t sadb_sa_flags;
++};
++
++struct sadb_lifetime {
++  uint16_t sadb_lifetime_len;
++  uint16_t sadb_lifetime_exttype;
++  uint32_t sadb_lifetime_allocations;
++  uint64_t sadb_lifetime_bytes;
++  uint64_t sadb_lifetime_addtime;
++  uint64_t sadb_lifetime_usetime;
++  uint32_t sadb_x_lifetime_packets;
++  uint32_t sadb_x_lifetime_reserved;
++};
++
++struct sadb_address {
++  uint16_t sadb_address_len;
++  uint16_t sadb_address_exttype;
++  uint8_t sadb_address_proto;
++  uint8_t sadb_address_prefixlen;
++  uint16_t sadb_address_reserved;
++};
++
++struct sadb_key {
++  uint16_t sadb_key_len;
++  uint16_t sadb_key_exttype;
++  uint16_t sadb_key_bits;
++  uint16_t sadb_key_reserved;
++};
++
++struct sadb_ident {
++  uint16_t sadb_ident_len;
++  uint16_t sadb_ident_exttype;
++  uint16_t sadb_ident_type;
++  uint16_t sadb_ident_reserved;
++  uint64_t sadb_ident_id;
++};
++
++struct sadb_sens {
++  uint16_t sadb_sens_len;
++  uint16_t sadb_sens_exttype;
++  uint32_t sadb_sens_dpd;
++  uint8_t sadb_sens_sens_level;
++  uint8_t sadb_sens_sens_len;
++  uint8_t sadb_sens_integ_level;
++  uint8_t sadb_sens_integ_len;
++  uint32_t sadb_sens_reserved;
++};
++
++struct sadb_prop {
++  uint16_t sadb_prop_len;
++  uint16_t sadb_prop_exttype;
++  uint8_t sadb_prop_replay;
++  uint8_t sadb_prop_reserved[3];
++};
++
++struct sadb_comb {
++  uint8_t sadb_comb_auth;
++  uint8_t sadb_comb_encrypt;
++  uint16_t sadb_comb_flags;
++  uint16_t sadb_comb_auth_minbits;
++  uint16_t sadb_comb_auth_maxbits;
++  uint16_t sadb_comb_encrypt_minbits;
++  uint16_t sadb_comb_encrypt_maxbits;
++  uint32_t sadb_comb_reserved;
++  uint32_t sadb_comb_soft_allocations;
++  uint32_t sadb_comb_hard_allocations;
++  uint64_t sadb_comb_soft_bytes;
++  uint64_t sadb_comb_hard_bytes;
++  uint64_t sadb_comb_soft_addtime;
++  uint64_t sadb_comb_hard_addtime;
++  uint64_t sadb_comb_soft_usetime;
++  uint64_t sadb_comb_hard_usetime;
++  uint32_t sadb_x_comb_soft_packets;
++  uint32_t sadb_x_comb_hard_packets;
++};
++
++struct sadb_supported {
++  uint16_t sadb_supported_len;
++  uint16_t sadb_supported_exttype;
++  uint32_t sadb_supported_reserved;
++};
++
++struct sadb_alg {
++  uint8_t sadb_alg_id;
++  uint8_t sadb_alg_ivlen;
++  uint16_t sadb_alg_minbits;
++  uint16_t sadb_alg_maxbits;
++  uint16_t sadb_alg_reserved;
++};
++
++struct sadb_spirange {
++  uint16_t sadb_spirange_len;
++  uint16_t sadb_spirange_exttype;
++  uint32_t sadb_spirange_min;
++  uint32_t sadb_spirange_max;
++  uint32_t sadb_spirange_reserved;
++};
++
++struct sadb_x_kmprivate {
++  uint16_t sadb_x_kmprivate_len;
++  uint16_t sadb_x_kmprivate_exttype;
++  uint32_t sadb_x_kmprivate_reserved;
++};
++
++struct sadb_x_satype {
++  uint16_t sadb_x_satype_len;
++  uint16_t sadb_x_satype_exttype;
++  uint8_t sadb_x_satype_satype;
++  uint8_t sadb_x_satype_reserved[3];
++};
++  
++struct sadb_x_policy {
++  uint16_t sadb_x_policy_len;
++  uint16_t sadb_x_policy_exttype;
++  uint16_t sadb_x_policy_type;
++  uint8_t sadb_x_policy_dir;
++  uint8_t sadb_x_policy_reserved;
++  uint32_t sadb_x_policy_id;
++  uint32_t sadb_x_policy_reserved2;
++};
++ 
++struct sadb_x_debug {
++  uint16_t sadb_x_debug_len;
++  uint16_t sadb_x_debug_exttype;
++  uint32_t sadb_x_debug_tunnel;
++  uint32_t sadb_x_debug_netlink;
++  uint32_t sadb_x_debug_xform;
++  uint32_t sadb_x_debug_eroute;
++  uint32_t sadb_x_debug_spi;
++  uint32_t sadb_x_debug_radij;
++  uint32_t sadb_x_debug_esp;
++  uint32_t sadb_x_debug_ah;
++  uint32_t sadb_x_debug_rcv;
++  uint32_t sadb_x_debug_pfkey;
++  uint32_t sadb_x_debug_ipcomp;
++  uint32_t sadb_x_debug_verbose;
++  uint8_t sadb_x_debug_reserved[4];
++};
++  
++/*
++ * A protocol structure for passing through the transport level
++ * protocol.  It contains more fields than are actually used/needed
++ * but it is this way to be compatible with the structure used in
++ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
++ */
++struct sadb_protocol {
++  uint16_t sadb_protocol_len;
++  uint16_t sadb_protocol_exttype;
++  uint8_t  sadb_protocol_proto;
++  uint8_t  sadb_protocol_direction;
++  uint8_t  sadb_protocol_flags;
++  uint8_t  sadb_protocol_reserved2;
++};
++
++#define SADB_EXT_RESERVED             0
++#define SADB_EXT_SA                   1
++#define SADB_EXT_LIFETIME_CURRENT     2
++#define SADB_EXT_LIFETIME_HARD        3
++#define SADB_EXT_LIFETIME_SOFT        4
++#define SADB_EXT_ADDRESS_SRC          5
++#define SADB_EXT_ADDRESS_DST          6
++#define SADB_EXT_ADDRESS_PROXY        7
++#define SADB_EXT_KEY_AUTH             8
++#define SADB_EXT_KEY_ENCRYPT          9
++#define SADB_EXT_IDENTITY_SRC         10
++#define SADB_EXT_IDENTITY_DST         11
++#define SADB_EXT_SENSITIVITY          12
++#define SADB_EXT_PROPOSAL             13
++#define SADB_EXT_SUPPORTED_AUTH       14
++#define SADB_EXT_SUPPORTED_ENCRYPT    15
++#define SADB_EXT_SPIRANGE             16
++#define SADB_X_EXT_KMPRIVATE          17
++#define SADB_X_EXT_SATYPE2            18
++#ifdef KERNEL26_HAS_KAME_DUPLICATES
++#define SADB_X_EXT_POLICY             18
++#endif
++#define SADB_X_EXT_SA2                19
++#define SADB_X_EXT_ADDRESS_DST2       20
++#define SADB_X_EXT_ADDRESS_SRC_FLOW   21
++#define SADB_X_EXT_ADDRESS_DST_FLOW   22
++#define SADB_X_EXT_ADDRESS_SRC_MASK   23
++#define SADB_X_EXT_ADDRESS_DST_MASK   24
++#define SADB_X_EXT_DEBUG              25
++#define SADB_X_EXT_PROTOCOL           26
++#define SADB_EXT_MAX                  26
++
++/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
++#define SADB_X_EXT_ADDRESS_DELFLOW \
++	( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
++	| (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
++	| (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
++	| (1<<SADB_X_EXT_ADDRESS_DST_MASK))
++
++#define SADB_SATYPE_UNSPEC    0
++#define SADB_SATYPE_AH        2
++#define SADB_SATYPE_ESP       3
++#define SADB_SATYPE_RSVP      5
++#define SADB_SATYPE_OSPFV2    6
++#define SADB_SATYPE_RIPV2     7
++#define SADB_SATYPE_MIP       8
++#define SADB_X_SATYPE_IPIP    9
++#ifdef KERNEL26_HAS_KAME_DUPLICATES
++#define SADB_X_SATYPE_IPCOMP  9   /* ICK! */
++#endif
++#define SADB_X_SATYPE_COMP    10
++#define SADB_X_SATYPE_INT     11
++#define SADB_SATYPE_MAX       11
++
++#define SADB_SASTATE_LARVAL   0
++#define SADB_SASTATE_MATURE   1
++#define SADB_SASTATE_DYING    2
++#define SADB_SASTATE_DEAD     3
++#define SADB_SASTATE_MAX      3
++
++#define SADB_SAFLAGS_PFS		1
++#define SADB_X_SAFLAGS_REPLACEFLOW	2
++#define SADB_X_SAFLAGS_CLEARFLOW	4
++#define SADB_X_SAFLAGS_INFLOW		8
++
++/* not obvious, but these are the same values as used in isakmp,
++ * and in freeswan/ipsec_policy.h. If you need to add any, they
++ * should be added as according to 
++ *   http://www.iana.org/assignments/isakmp-registry
++ * 
++ * and if not, then please try to use a private-use value, and
++ * consider asking IANA to assign a value.
++ */
++#define SADB_AALG_NONE                  0
++#define SADB_AALG_MD5HMAC               2
++#define SADB_AALG_SHA1HMAC              3
++#define SADB_X_AALG_SHA2_256HMAC	5
++#define SADB_X_AALG_SHA2_384HMAC	6
++#define SADB_X_AALG_SHA2_512HMAC	7
++#define SADB_X_AALG_RIPEMD160HMAC	8
++#define SADB_X_AALG_NULL		251	/* kame */
++#define SADB_AALG_MAX			251
++
++#define SADB_EALG_NONE                  0
++#define SADB_EALG_DESCBC                2
++#define SADB_EALG_3DESCBC               3
++#define SADB_X_EALG_CASTCBC		6
++#define SADB_X_EALG_BLOWFISHCBC		7
++#define SADB_EALG_NULL			11
++#define SADB_X_EALG_AESCBC		12
++#define SADB_EALG_MAX			12
++
++#define SADB_X_CALG_NONE          0
++#define SADB_X_CALG_OUI           1
++#define SADB_X_CALG_DEFLATE       2
++#define SADB_X_CALG_LZS           3
++#define SADB_X_CALG_V42BIS        4
++#ifdef KERNEL26_HAS_KAME_DUPLICATES
++#define SADB_X_CALG_LZJH          4
++#endif
++#define SADB_X_CALG_MAX           4
++
++#define SADB_X_TALG_NONE          0
++#define SADB_X_TALG_IPv4_in_IPv4  1
++#define SADB_X_TALG_IPv6_in_IPv4  2
++#define SADB_X_TALG_IPv4_in_IPv6  3
++#define SADB_X_TALG_IPv6_in_IPv6  4
++#define SADB_X_TALG_MAX           4
++
++
++#define SADB_IDENTTYPE_RESERVED   0
++#define SADB_IDENTTYPE_PREFIX     1
++#define SADB_IDENTTYPE_FQDN       2
++#define SADB_IDENTTYPE_USERFQDN   3
++#define SADB_X_IDENTTYPE_CONNECTION 4
++#define SADB_IDENTTYPE_MAX        4
++
++#define SADB_KEY_FLAGS_MAX     0
++#endif /* __PFKEY_V2_H */
++
++/*
++ * $Log: pfkeyv2.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:40  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:28:12  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.28  2003/12/04 19:05:22  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.27  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.25  2003/07/31 23:59:17  mcr
++ * 	re-introduce kernel 2.6 duplicate values for now.
++ * 	hope to get them changed!
++ *
++ * Revision 1.24  2003/07/31 22:55:27  mcr
++ * 	added some definitions to keep pfkeyv2.h files in sync.
++ *
++ * Revision 1.23  2003/05/11 00:43:48  mcr
++ * 	added comment about origin of values used
++ *
++ * Revision 1.22  2003/01/30 02:31:34  rgb
++ *
++ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
++ *
++ * Revision 1.21  2002/12/16 19:26:49  mcr
++ * 	added definition of FS 1.xx sadb structure
++ *
++ * Revision 1.20  2002/09/20 15:40:25  rgb
++ * Added sadb_x_sa_ref to struct sadb_sa.
++ *
++ * Revision 1.19  2002/04/24 07:36:49  mcr
++ * Moved from ./lib/pfkeyv2.h,v
++ *
++ * Revision 1.18  2001/11/06 19:47:47  rgb
++ * Added packet parameter to lifetime and comb structures.
++ *
++ * Revision 1.17  2001/09/08 21:13:35  rgb
++ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
++ *
++ * Revision 1.16  2001/07/06 19:49:46  rgb
++ * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
++ *
++ * Revision 1.15  2001/02/26 20:00:43  rgb
++ * Added internal IP protocol 61 for magic SAs.
++ *
++ * Revision 1.14  2001/02/08 18:51:05  rgb
++ * Include RFC document title and appendix subsection title.
++ *
++ * Revision 1.13  2000/10/10 20:10:20  rgb
++ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
++ *
++ * Revision 1.12  2000/09/15 06:41:50  rgb
++ * Added V42BIS constant.
++ *
++ * Revision 1.11  2000/09/12 22:35:37  rgb
++ * Restructured to remove unused extensions from CLEARFLOW messages.
++ *
++ * Revision 1.10  2000/09/12 18:50:09  rgb
++ * Added IPIP tunnel types as algo support.
++ *
++ * Revision 1.9  2000/08/21 16:47:19  rgb
++ * Added SADB_X_CALG_* macros for IPCOMP.
++ *
++ * Revision 1.8  2000/08/09 20:43:34  rgb
++ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
++ *
++ * Revision 1.7  2000/01/21 06:28:37  rgb
++ * Added flow add/delete message type macros.
++ * Added flow address extension type macros.
++ * Tidied up spacing.
++ * Added klipsdebug switching capability.
++ *
++ * Revision 1.6  1999/11/27 11:56:08  rgb
++ * Add SADB_X_SATYPE_COMP for compression, eventually.
++ *
++ * Revision 1.5  1999/11/23 22:23:16  rgb
++ * This file has been moved in the distribution from klips/net/ipsec to
++ * lib.
++ *
++ * Revision 1.4  1999/04/29 15:23:29  rgb
++ * Add GRPSA support.
++ * Add support for a second SATYPE, SA and DST_ADDRESS.
++ * Add IPPROTO_IPIP support.
++ *
++ * Revision 1.3  1999/04/15 17:58:08  rgb
++ * Add RCSID labels.
++ *
++ */
+diff --git a/include/openssl/opensslconf.h b/include/openssl/opensslconf.h
+new file mode 100644
+index 0000000..896d9a4
+--- /dev/null
++++ b/include/openssl/opensslconf.h
+@@ -0,0 +1,180 @@
++/* opensslconf.h */
++/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
++
++#ifdef __KERNEL__
++/* OpenSSL was configured with the following options: */
++#ifdef OPENSSL_ALGORITHM_DEFINES
++   /* no ciphers excluded */
++#endif
++#ifdef OPENSSL_THREAD_DEFINES
++# ifndef THREADS
++#  define THREADS
++# endif
++#endif
++#ifdef OPENSSL_OTHER_DEFINES
++# ifndef DSO_DLFCN
++#  define DSO_DLFCN
++# endif
++# ifndef HAVE_DLFCN_H
++#  define HAVE_DLFCN_H
++# endif
++#endif
++
++/* crypto/opensslconf.h.in */
++
++/* Generate 80386 code? */
++#undef I386_ONLY
++
++#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
++#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
++#define OPENSSLDIR "/usr/local/ssl"
++#endif
++#endif
++
++#define OPENSSL_UNISTD <unistd.h>
++
++#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
++#define IDEA_INT unsigned int
++#endif
++
++#if defined(HEADER_MD2_H) && !defined(MD2_INT)
++#define MD2_INT unsigned int
++#endif
++
++#if defined(HEADER_RC2_H) && !defined(RC2_INT)
++/* I need to put in a mod for the alpha - eay */
++#define RC2_INT unsigned int
++#endif
++
++#if defined(HEADER_RC4_H)
++#if !defined(RC4_INT)
++/* using int types make the structure larger but make the code faster
++ * on most boxes I have tested - up to %20 faster. */
++/*
++ * I don't know what does "most" mean, but declaring "int" is a must on:
++ * - Intel P6 because partial register stalls are very expensive;
++ * - elder Alpha because it lacks byte load/store instructions;
++ */
++#define RC4_INT unsigned int
++#endif
++#if !defined(RC4_CHUNK)
++/*
++ * This enables code handling data aligned at natural CPU word
++ * boundary. See crypto/rc4/rc4_enc.c for further details.
++ */
++#undef RC4_CHUNK
++#endif
++#endif
++
++#if defined(HEADER_DES_H) && !defined(DES_LONG)
++/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
++ * %20 speed up (longs are 8 bytes, int's are 4). */
++#ifndef DES_LONG
++#define DES_LONG unsigned long
++#endif
++#endif
++
++#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
++#define CONFIG_HEADER_BN_H
++#define BN_LLONG
++
++/* Should we define BN_DIV2W here? */
++
++/* Only one for the following should be defined */
++/* The prime number generation stuff may not work when
++ * EIGHT_BIT but I don't care since I've only used this mode
++ * for debuging the bignum libraries */
++#undef SIXTY_FOUR_BIT_LONG
++#undef SIXTY_FOUR_BIT
++#define THIRTY_TWO_BIT
++#undef SIXTEEN_BIT
++#undef EIGHT_BIT
++#endif
++
++#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
++#define CONFIG_HEADER_RC4_LOCL_H
++/* if this is defined data[i] is used instead of *data, this is a %20
++ * speedup on x86 */
++#define RC4_INDEX
++#endif
++
++#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
++#define CONFIG_HEADER_BF_LOCL_H
++#undef BF_PTR
++#endif /* HEADER_BF_LOCL_H */
++
++#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
++#define CONFIG_HEADER_DES_LOCL_H
++#ifndef DES_DEFAULT_OPTIONS
++/* the following is tweaked from a config script, that is why it is a
++ * protected undef/define */
++#ifndef DES_PTR
++#define DES_PTR
++#endif
++
++/* This helps C compiler generate the correct code for multiple functional
++ * units.  It reduces register dependancies at the expense of 2 more
++ * registers */
++#ifndef DES_RISC1
++#define DES_RISC1
++#endif
++
++#ifndef DES_RISC2
++#undef DES_RISC2
++#endif
++
++#if defined(DES_RISC1) && defined(DES_RISC2)
++YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
++#endif
++
++/* Unroll the inner loop, this sometimes helps, sometimes hinders.
++ * Very mucy CPU dependant */
++#ifndef DES_UNROLL
++#define DES_UNROLL
++#endif
++
++/* These default values were supplied by
++ * Peter Gutman <pgut001 at cs.auckland.ac.nz>
++ * They are only used if nothing else has been defined */
++#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
++/* Special defines which change the way the code is built depending on the
++   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
++   even newer MIPS CPU's, but at the moment one size fits all for
++   optimization options.  Older Sparc's work better with only UNROLL, but
++   there's no way to tell at compile time what it is you're running on */
++ 
++#if defined( sun )		/* Newer Sparc's */
++#  define DES_PTR
++#  define DES_RISC1
++#  define DES_UNROLL
++#elif defined( __ultrix )	/* Older MIPS */
++#  define DES_PTR
++#  define DES_RISC2
++#  define DES_UNROLL
++#elif defined( __osf1__ )	/* Alpha */
++#  define DES_PTR
++#  define DES_RISC2
++#elif defined ( _AIX )		/* RS6000 */
++  /* Unknown */
++#elif defined( __hpux )		/* HP-PA */
++  /* Unknown */
++#elif defined( __aux )		/* 68K */
++  /* Unknown */
++#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
++#  define DES_UNROLL
++#elif defined( __sgi )		/* Newer MIPS */
++#  define DES_PTR
++#  define DES_RISC2
++#  define DES_UNROLL
++#elif defined( i386 )		/* x86 boxes, should be gcc */
++#  define DES_PTR
++#  define DES_RISC1
++#  define DES_UNROLL
++#endif /* Systems-specific speed defines */
++#endif
++
++#endif /* DES_DEFAULT_OPTIONS */
++#endif /* HEADER_DES_LOCL_H */
++#else /* KERNEL */
++#include_next <openssl/opensslconf.h>
++#endif
+diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
+new file mode 100644
+index 0000000..3905778
+--- /dev/null
++++ b/include/openssl/opensslv.h
+@@ -0,0 +1,89 @@
++#ifdef __KERNEL__
++#ifndef HEADER_OPENSSLV_H
++#define HEADER_OPENSSLV_H
++
++/* Numeric release version identifier:
++ * MMNNFFPPS: major minor fix patch status
++ * The status nibble has one of the values 0 for development, 1 to e for betas
++ * 1 to 14, and f for release.  The patch level is exactly that.
++ * For example:
++ * 0.9.3-dev	  0x00903000
++ * 0.9.3-beta1	  0x00903001
++ * 0.9.3-beta2-dev 0x00903002
++ * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
++ * 0.9.3	  0x0090300f
++ * 0.9.3a	  0x0090301f
++ * 0.9.4 	  0x0090400f
++ * 1.2.3z	  0x102031af
++ *
++ * For continuity reasons (because 0.9.5 is already out, and is coded
++ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
++ * part is slightly different, by setting the highest bit.  This means
++ * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
++ * with 0x0090600S...
++ *
++ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
++ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
++ *  major minor fix final patch/beta)
++ */
++#define OPENSSL_VERSION_NUMBER	0x0090601fL
++#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.6a 5 Apr 2001"
++#define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
++
++
++/* The macros below are to be used for shared library (.so, .dll, ...)
++ * versioning.  That kind of versioning works a bit differently between
++ * operating systems.  The most usual scheme is to set a major and a minor
++ * number, and have the runtime loader check that the major number is equal
++ * to what it was at application link time, while the minor number has to
++ * be greater or equal to what it was at application link time.  With this
++ * scheme, the version number is usually part of the file name, like this:
++ *
++ *	libcrypto.so.0.9
++ *
++ * Some unixen also make a softlink with the major verson number only:
++ *
++ *	libcrypto.so.0
++ *
++ * On True64 it works a little bit differently.  There, the shared library
++ * version is stored in the file, and is actually a series of versions,
++ * separated by colons.  The rightmost version present in the library when
++ * linking an application is stored in the application to be matched at
++ * run time.  When the application is run, a check is done to see if the
++ * library version stored in the application matches any of the versions
++ * in the version string of the library itself.
++ * This version string can be constructed in any way, depending on what
++ * kind of matching is desired.  However, to implement the same scheme as
++ * the one used in the other unixen, all compatible versions, from lowest
++ * to highest, should be part of the string.  Consecutive builds would
++ * give the following versions strings:
++ *
++ *	3.0
++ *	3.0:3.1
++ *	3.0:3.1:3.2
++ *	4.0
++ *	4.0:4.1
++ *
++ * Notice how version 4 is completely incompatible with version, and
++ * therefore give the breach you can see.
++ *
++ * There may be other schemes as well that I haven't yet discovered.
++ *
++ * So, here's the way it works here: first of all, the library version
++ * number doesn't need at all to match the overall OpenSSL version.
++ * However, it's nice and more understandable if it actually does.
++ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
++ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
++ * For the sake of True64 and any other OS that behaves in similar ways,
++ * we need to keep a history of version numbers, which is done in the
++ * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
++ * should only keep the versions that are binary compatible with the current.
++ */
++#define SHLIB_VERSION_HISTORY ""
++#define SHLIB_VERSION_NUMBER "0.9.6"
++
++
++#endif /* HEADER_OPENSSLV_H */
++#else /* __KERNEL__ */
++#include_next <openssl/opensslv.h>
++#endif
+diff --git a/include/openssl/rc4.h b/include/openssl/rc4.h
+new file mode 100644
+index 0000000..51bba5b
+--- /dev/null
++++ b/include/openssl/rc4.h
+@@ -0,0 +1,92 @@
++/* crypto/rc4/rc4.h */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++#ifdef __KERNEL__
++#ifndef HEADER_RC4_H
++#define HEADER_RC4_H
++
++#ifdef NO_RC4
++#error RC4 is disabled.
++#endif
++
++#include <openssl/opensslconf.h> /* RC4_INT */
++
++#ifdef  __cplusplus
++extern "C" {
++#endif
++
++typedef struct rc4_key_st
++	{
++	RC4_INT x,y;
++	RC4_INT data[256];
++	} RC4_KEY;
++
++ 
++const char *RC4_options(void);
++void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
++void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
++		unsigned char *outdata);
++
++#ifdef  __cplusplus
++}
++#endif
++
++#endif
++#else /* __KERNEL__ */
++#include_next <openssl/rc4.h>
++#endif
+diff --git a/include/openssl/sha.h b/include/openssl/sha.h
+new file mode 100644
+index 0000000..f9a786c
+--- /dev/null
++++ b/include/openssl/sha.h
+@@ -0,0 +1,122 @@
++/* crypto/sha/sha.h */
++/* Copyright (C) 1995-1998 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++#ifdef __KERNEL__
++#ifndef HEADER_SHA_H
++#define HEADER_SHA_H
++
++#ifdef  __cplusplus
++extern "C" {
++#endif
++
++#if defined(NO_SHA) || (defined(NO_SHA0) && defined(NO_SHA1))
++#error SHA is disabled.
++#endif
++
++/*
++ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
++ * ! SHA_LONG_LOG2 has to be defined along.                        !
++ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++ */
++
++#if defined(WIN16) || defined(__LP32__)
++#define SHA_LONG unsigned long
++#elif defined(_CRAY) || defined(__ILP64__)
++#define SHA_LONG unsigned long
++#define SHA_LONG_LOG2 3
++#else
++#define SHA_LONG unsigned int
++#endif
++
++#define SHA_LBLOCK	16
++#define SHA_CBLOCK	(SHA_LBLOCK*4)	/* SHA treats input data as a
++					 * contiguous array of 32 bit
++					 * wide big-endian values. */
++#define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
++#define SHA_DIGEST_LENGTH 20
++
++typedef struct SHAstate_st
++	{
++	SHA_LONG h0,h1,h2,h3,h4;
++	SHA_LONG Nl,Nh;
++	SHA_LONG data[SHA_LBLOCK];
++	int num;
++	} SHA_CTX;
++
++#ifndef NO_SHA0
++void SHA_Init(SHA_CTX *c);
++void SHA_Update(SHA_CTX *c, const void *data, unsigned long len);
++void SHA_Final(unsigned char *md, SHA_CTX *c);
++unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md);
++void SHA_Transform(SHA_CTX *c, const unsigned char *data);
++#endif
++#ifndef NO_SHA1
++void SHA1_Init(SHA_CTX *c);
++void SHA1_Update(SHA_CTX *c, const void *data, unsigned long len);
++void SHA1_Final(unsigned char *md, SHA_CTX *c);
++unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md);
++void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
++#endif
++#ifdef  __cplusplus
++}
++#endif
++
++#endif
++#else /* __KERNEL__ */
++#include_next <openssl/sha.h>
++#endif
+diff --git a/include/pfkey.h b/include/pfkey.h
+new file mode 100644
+index 0000000..25d43ee
+--- /dev/null
++++ b/include/pfkey.h
+@@ -0,0 +1,493 @@
++/*
++ * FreeS/WAN specific PF_KEY headers
++ * Copyright (C) 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$
++ */
++
++#ifndef __NET_IPSEC_PF_KEY_H
++#define __NET_IPSEC_PF_KEY_H
++#ifdef __KERNEL__
++extern struct proto_ops pfkey_proto_ops;
++typedef struct sock pfkey_sock;
++extern int debug_pfkey;
++
++extern /* void */ int pfkey_init(void);
++extern /* void */ int pfkey_cleanup(void);
++
++struct socket_list
++{
++	struct socket *socketp;
++	struct socket_list *next;
++};
++extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
++extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
++extern struct socket_list *pfkey_open_sockets;
++extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
++
++struct supported
++{
++	uint16_t supported_alg_exttype;
++	uint8_t supported_alg_id;
++	uint8_t supported_alg_ivlen;
++	uint16_t supported_alg_minbits;
++	uint16_t supported_alg_maxbits;
++};
++
++extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
++struct supported_list
++{
++	struct supported *supportedp;
++	struct supported_list *next;
++};
++extern int pfkey_list_insert_supported(struct supported*, struct supported_list**);
++extern int pfkey_list_remove_supported(struct supported*, struct supported_list**);
++
++struct sockaddr_key
++{
++	uint16_t	key_family;	/* PF_KEY */
++	uint16_t	key_pad;	/* not used */
++	uint32_t	key_pid;	/* process ID */
++};
++
++struct pfkey_extracted_data
++{
++	struct ipsec_sa* ips;
++	struct ipsec_sa* ips2;
++	struct eroute *eroute;
++};
++
++extern int
++pfkey_alloc_eroute(struct eroute** eroute);
++
++extern int
++pfkey_sa_process(struct sadb_ext *pfkey_ext,
++		 struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
++		       struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_address_process(struct sadb_ext *pfkey_ext,
++		      struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_key_process(struct sadb_ext *pfkey_ext,
++		  struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_ident_process(struct sadb_ext *pfkey_ext,
++		    struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_sens_process(struct sadb_ext *pfkey_ext,
++		   struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_prop_process(struct sadb_ext *pfkey_ext,
++		   struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_supported_process(struct sadb_ext *pfkey_ext,
++			struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_spirange_process(struct sadb_ext *pfkey_ext,
++		       struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
++			  struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
++		       struct pfkey_extracted_data* extr);
++
++extern int
++pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
++		      struct pfkey_extracted_data* extr);
++
++extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
++extern int pfkey_expire(struct ipsec_sa *, int);
++extern int pfkey_acquire(struct ipsec_sa *);
++#else /* ! __KERNEL__ */
++
++extern void (*pfkey_debug_func)(const char *message, ...);
++extern void (*pfkey_error_func)(const char *message, ...);
++extern void pfkey_print(struct sadb_msg *msg, FILE *out);
++
++
++#endif /* __KERNEL__ */
++
++extern uint8_t satype2proto(uint8_t satype);
++extern uint8_t proto2satype(uint8_t proto);
++extern char* satype2name(uint8_t satype);
++extern char* proto2name(uint8_t proto);
++
++struct key_opt
++{
++	uint32_t	key_pid;	/* process ID */
++	struct sock	*sk;
++};
++
++#define key_pid(sk) ((struct key_opt*)&((sk)->sk_protinfo))->key_pid
++
++/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
++ * words.
++ */
++#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
++#define BITS_PER_OCTET 8
++#define OCTETBITS 8
++#define PFKEYBITS 64
++#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
++#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
++
++#define IPSEC_PFKEYv2_LEN(x)   ((x) * IPSEC_PFKEYv2_ALIGN)
++#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
++
++
++#define PFKEYv2_MAX_MSGSIZE 4096
++
++/*
++ * PF_KEYv2 permitted and required extensions in and out bitmaps
++ */
++struct pf_key_ext_parsers_def {
++	int  (*parser)(struct sadb_ext*);
++	char  *parser_name;
++};
++
++
++extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/];
++#define EXT_BITS_IN 0
++#define EXT_BITS_OUT 1
++#define EXT_BITS_PERM 0
++#define EXT_BITS_REQ 1
++
++extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
++extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
++extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
++
++extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
++			   struct pf_key_ext_parsers_def *ext_parsers[],
++			   struct sadb_ext **extensions,
++			   int dir);
++
++/*
++ * PF_KEYv2 build function prototypes
++ */
++
++int
++pfkey_msg_hdr_build(struct sadb_ext**	pfkey_ext,
++		    uint8_t		msg_type,
++		    uint8_t		satype,
++		    uint8_t		msg_errno,
++		    uint32_t		seq,
++		    uint32_t		pid);
++
++int
++pfkey_sa_ref_build(struct sadb_ext **	pfkey_ext,
++	       uint16_t			exttype,
++	       uint32_t			spi, /* in network order */
++	       uint8_t			replay_window,
++	       uint8_t			sa_state,
++	       uint8_t			auth,
++	       uint8_t			encrypt,
++	       uint32_t			flags,
++	       uint32_t/*IPsecSAref_t*/	ref);
++
++int
++pfkey_sa_build(struct sadb_ext **	pfkey_ext,
++	       uint16_t			exttype,
++	       uint32_t			spi, /* in network order */
++	       uint8_t			replay_window,
++	       uint8_t			sa_state,
++	       uint8_t			auth,
++	       uint8_t			encrypt,
++	       uint32_t			flags);
++
++int
++pfkey_lifetime_build(struct sadb_ext **	pfkey_ext,
++		     uint16_t		exttype,
++		     uint32_t		allocations,
++		     uint64_t		bytes,
++		     uint64_t		addtime,
++		     uint64_t		usetime,
++		     uint32_t		packets);
++
++int
++pfkey_address_build(struct sadb_ext**	pfkey_ext,
++		    uint16_t		exttype,
++		    uint8_t		proto,
++		    uint8_t		prefixlen,
++		    struct sockaddr*	address);
++
++int
++pfkey_key_build(struct sadb_ext**	pfkey_ext,
++		uint16_t		exttype,
++		uint16_t		key_bits,
++		char*			key);
++
++int
++pfkey_ident_build(struct sadb_ext**	pfkey_ext,
++		  uint16_t		exttype,
++		  uint16_t		ident_type,
++		  uint64_t		ident_id,
++		  uint8_t               ident_len,
++		  char*			ident_string);
++
++int
++pfkey_sens_build(struct sadb_ext**	pfkey_ext,
++		 uint32_t		dpd,
++		 uint8_t		sens_level,
++		 uint8_t		sens_len,
++		 uint64_t*		sens_bitmap,
++		 uint8_t		integ_level,
++		 uint8_t		integ_len,
++		 uint64_t*		integ_bitmap);
++
++int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
++
++
++int
++pfkey_prop_build(struct sadb_ext**	pfkey_ext,
++		 uint8_t		replay,
++		 unsigned int		comb_num,
++		 struct sadb_comb*	comb);
++
++int
++pfkey_supported_build(struct sadb_ext**	pfkey_ext,
++		      uint16_t		exttype,
++		      unsigned int	alg_num,
++		      struct sadb_alg*	alg);
++
++int
++pfkey_spirange_build(struct sadb_ext**	pfkey_ext,
++		     uint16_t		exttype,
++		     uint32_t		min,
++		     uint32_t		max);
++
++int
++pfkey_x_kmprivate_build(struct sadb_ext**	pfkey_ext);
++
++int
++pfkey_x_satype_build(struct sadb_ext**	pfkey_ext,
++		     uint8_t		satype);
++
++int
++pfkey_x_debug_build(struct sadb_ext**	pfkey_ext,
++		    uint32_t            tunnel,
++		    uint32_t		netlink,
++		    uint32_t		xform,
++		    uint32_t		eroute,
++		    uint32_t		spi,
++		    uint32_t		radij,
++		    uint32_t		esp,
++		    uint32_t		ah,
++		    uint32_t		rcv,
++		    uint32_t            pfkey,
++		    uint32_t            ipcomp,
++		    uint32_t            verbose);
++
++int
++pfkey_msg_build(struct sadb_msg**	pfkey_msg,
++		struct sadb_ext*	extensions[],
++		int			dir);
++
++/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
++const char *
++pfkey_v2_sadb_ext_string(int extnum);
++
++const char *
++pfkey_v2_sadb_type_string(int sadb_type);
++
++
++#endif /* __NET_IPSEC_PF_KEY_H */
++
++/*
++ * $Log: pfkey.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:40  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:28:12  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.46  2004/02/22 06:48:23  mcr
++ * 	moved include files for libraries to main include directory.
++ *
++ * Revision 1.45.6.1  2004/02/20 14:09:50  mcr
++ * 	moved code to net/ipsec/ to make 2.6 happy.
++ *
++ * Revision 1.45  2003/12/04 19:05:22  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.44  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.42  2003/08/25 22:08:19  mcr
++ * 	removed pfkey_proto_init() from pfkey.h for 2.6 support.
++ *
++ * Revision 1.41  2003/05/07 17:28:57  mcr
++ * 	new function pfkey_debug_func added for us in debugging from
++ * 	pfkey library.
++ *
++ * Revision 1.40  2003/01/30 02:31:34  rgb
++ *
++ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
++ *
++ * Revision 1.39  2002/09/20 15:40:21  rgb
++ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
++ * Added ref parameter to pfkey_sa_build().
++ * Cleaned out unused cruft.
++ *
++ * Revision 1.38  2002/05/14 02:37:24  rgb
++ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
++ * ipsec_sa or ipsec_sa.
++ * Added function prototypes for the functions moved to
++ * pfkey_v2_ext_process.c.
++ *
++ * Revision 1.37  2002/04/24 07:36:49  mcr
++ * Moved from ./lib/pfkey.h,v
++ *
++ * Revision 1.36  2002/01/20 20:34:49  mcr
++ * 	added pfkey_v2_sadb_type_string to decode sadb_type to string.
++ *
++ * Revision 1.35  2001/11/27 05:27:47  mcr
++ * 	pfkey parses are now maintained by a structure
++ * 	that includes their name for debug purposes.
++ *
++ * Revision 1.34  2001/11/26 09:23:53  rgb
++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
++ *
++ * Revision 1.33  2001/11/06 19:47:47  rgb
++ * Added packet parameter to lifetime and comb structures.
++ *
++ * Revision 1.32  2001/09/08 21:13:34  rgb
++ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
++ *
++ * Revision 1.31  2001/06/14 19:35:16  rgb
++ * Update copyright date.
++ *
++ * Revision 1.30  2001/02/27 07:04:52  rgb
++ * Added satype2name prototype.
++ *
++ * Revision 1.29  2001/02/26 19:59:33  rgb
++ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
++ *
++ * Revision 1.28  2000/10/10 20:10:19  rgb
++ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
++ *
++ * Revision 1.27  2000/09/21 04:20:45  rgb
++ * Fixed array size off-by-one error.  (Thanks Svenning!)
++ *
++ * Revision 1.26  2000/09/12 03:26:05  rgb
++ * Added pfkey_acquire prototype.
++ *
++ * Revision 1.25  2000/09/08 19:21:28  rgb
++ * Fix pfkey_prop_build() parameter to be only single indirection.
++ *
++ * Revision 1.24  2000/09/01 18:46:42  rgb
++ * Added a supported algorithms array lists, one per satype and registered
++ * existing algorithms.
++ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
++ * list.
++ *
++ * Revision 1.23  2000/08/27 01:55:26  rgb
++ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
++ *
++ * Revision 1.22  2000/08/20 21:39:23  rgb
++ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
++ * pfkey_expire().
++ *
++ * Revision 1.21  2000/08/15 17:29:23  rgb
++ * Fixes from SZI to untested pfkey_prop_build().
++ *
++ * Revision 1.20  2000/05/10 20:14:19  rgb
++ * Fleshed out sensitivity, proposal and supported extensions.
++ *
++ * Revision 1.19  2000/03/16 14:07:23  rgb
++ * Renamed ALIGN macro to avoid fighting with others in kernel.
++ *
++ * Revision 1.18  2000/01/22 23:24:06  rgb
++ * Added prototypes for proto2satype(), satype2proto() and proto2name().
++ *
++ * Revision 1.17  2000/01/21 06:26:59  rgb
++ * Converted from double tdb arguments to one structure (extr)
++ * containing pointers to all temporary information structures.
++ * Added klipsdebug switching capability.
++ * Dropped unused argument to pfkey_x_satype_build().
++ *
++ * Revision 1.16  1999/12/29 21:17:41  rgb
++ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
++ * parameter for cleaner manipulation of extensions[] and to guard
++ * against potential memory leaks.
++ * Changed the I/F to pfkey_msg_free() for the same reason.
++ *
++ * Revision 1.15  1999/12/09 23:12:54  rgb
++ * Added macro for BITS_PER_OCTET.
++ * Added argument to pfkey_sa_build() to do eroutes.
++ *
++ * Revision 1.14  1999/12/08 20:33:25  rgb
++ * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
++ *
++ * Revision 1.13  1999/12/07 19:53:40  rgb
++ * Removed unused first argument from extension parsers.
++ * Changed __u* types to uint* to avoid use of asm/types.h and
++ * sys/types.h in userspace code.
++ * Added function prototypes for pfkey message and extensions
++ * initialisation and cleanup.
++ *
++ * Revision 1.12  1999/12/01 22:19:38  rgb
++ * Change pfkey_sa_build to accept an SPI in network byte order.
++ *
++ * Revision 1.11  1999/11/27 11:55:26  rgb
++ * Added extern sadb_satype2proto to enable moving protocol lookup table
++ * to lib/pfkey_v2_parse.c.
++ * Delete unused, moved typedefs.
++ * Add argument to pfkey_msg_parse() for direction.
++ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
++ *
++ * Revision 1.10  1999/11/23 22:29:21  rgb
++ * This file has been moved in the distribution from klips/net/ipsec to
++ * lib.
++ * Add macros for dealing with alignment and rounding up more opaquely.
++ * The uint<n>_t type defines have been moved to freeswan.h to avoid
++ * chicken-and-egg problems.
++ * Add macros for dealing with alignment and rounding up more opaque.
++ * Added prototypes for using extention header bitmaps.
++ * Added prototypes of all the build functions.
++ *
++ * Revision 1.9  1999/11/20 21:59:48  rgb
++ * Moved socketlist type declarations and prototypes for shared use.
++ * Slightly modified scope of sockaddr_key declaration.
++ *
++ * Revision 1.8  1999/11/17 14:34:25  rgb
++ * Protect sa_family_t from being used in userspace with GLIBC<2.
++ *
++ * Revision 1.7  1999/10/27 19:40:35  rgb
++ * Add a maximum PFKEY packet size macro.
++ *
++ * Revision 1.6  1999/10/26 16:58:58  rgb
++ * Created a sockaddr_key and key_opt socket extension structures.
++ *
++ * Revision 1.5  1999/06/10 05:24:41  rgb
++ * Renamed variables to reduce confusion.
++ *
++ * Revision 1.4  1999/04/29 15:21:11  rgb
++ * Add pfkey support to debugging.
++ * Add return values to init and cleanup functions.
++ *
++ * Revision 1.3  1999/04/15 17:58:07  rgb
++ * Add RCSID labels.
++ *
++ */
+diff --git a/include/crypto/des.h b/include/crypto/des.h
+new file mode 100644
+index 0000000..baddf86
+--- /dev/null
++++ b/include/crypto/des.h
+@@ -0,0 +1,308 @@
++/* crypto/des/des.org */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 
++ *
++ * Always modify des.org since des.h is automatically generated from
++ * it during SSLeay configuration.
++ *
++ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
++ */
++
++#ifndef HEADER_DES_H
++#define HEADER_DES_H
++
++#ifdef  __cplusplus
++extern "C" {
++#endif
++
++
++/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
++ * %20 speed up (longs are 8 bytes, int's are 4). */
++/* Must be unsigned int on ia64/Itanium or DES breaks badly */
++
++#ifdef __KERNEL__
++#include <linux/types.h>
++#else
++#include <sys/types.h>
++#endif
++
++#ifndef DES_LONG
++#define DES_LONG u_int32_t
++#endif
++
++typedef unsigned char des_cblock[8];
++typedef struct des_ks_struct
++	{
++	union	{
++		des_cblock _;
++		/* make sure things are correct size on machines with
++		 * 8 byte longs */
++		DES_LONG pad[2];
++		} ks;
++#undef _
++#define _	ks._
++	} des_key_schedule[16];
++
++#define DES_KEY_SZ 	(sizeof(des_cblock))
++#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
++
++#define DES_ENCRYPT	1
++#define DES_DECRYPT	0
++
++#define DES_CBC_MODE	0
++#define DES_PCBC_MODE	1
++
++#define des_ecb2_encrypt(i,o,k1,k2,e) \
++	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
++
++#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
++	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
++
++#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
++	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
++
++#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
++	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
++
++#define C_Block des_cblock
++#define Key_schedule des_key_schedule
++#ifdef KERBEROS
++#define ENCRYPT DES_ENCRYPT
++#define DECRYPT DES_DECRYPT
++#endif
++#define KEY_SZ DES_KEY_SZ
++#define string_to_key des_string_to_key
++#define read_pw_string des_read_pw_string
++#define random_key des_random_key
++#define pcbc_encrypt des_pcbc_encrypt
++#define set_key des_set_key
++#define key_sched des_key_sched
++#define ecb_encrypt des_ecb_encrypt
++#define cbc_encrypt des_cbc_encrypt
++#define ncbc_encrypt des_ncbc_encrypt
++#define xcbc_encrypt des_xcbc_encrypt
++#define cbc_cksum des_cbc_cksum
++#define quad_cksum des_quad_cksum
++
++/* For compatibility with the MIT lib - eay 20/05/92 */
++typedef des_key_schedule bit_64;
++#define des_fixup_key_parity des_set_odd_parity
++#define des_check_key_parity check_parity
++
++extern int des_check_key;	/* defaults to false */
++extern int des_rw_mode;		/* defaults to DES_PCBC_MODE */
++
++/* The next line is used to disable full ANSI prototypes, if your
++ * compiler has problems with the prototypes, make sure this line always
++ * evaluates to true :-) */
++#if defined(MSDOS) || defined(__STDC__)
++#undef NOPROTO
++#endif
++#ifndef NOPROTO
++char *des_options(void);
++void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
++	des_key_schedule ks1,des_key_schedule ks2,
++	des_key_schedule ks3, int enc);
++DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
++	long length,des_key_schedule schedule,des_cblock *ivec);
++void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
++	des_key_schedule schedule,des_cblock *ivec,int enc);
++void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
++	des_key_schedule schedule,des_cblock *ivec,int enc);
++void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
++	des_key_schedule schedule,des_cblock *ivec,
++	des_cblock *inw,des_cblock *outw,int enc);
++void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
++	long length,des_key_schedule schedule,des_cblock *ivec,int enc);
++void des_ecb_encrypt(des_cblock *input,des_cblock *output,
++	des_key_schedule ks,int enc);
++void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
++void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
++void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
++	des_key_schedule ks2, des_key_schedule ks3);
++void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
++	des_key_schedule ks2, des_key_schedule ks3);
++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);
++void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
++	long length, des_key_schedule ks1, des_key_schedule ks2,
++	des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
++void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
++	long length, des_key_schedule ks1, des_key_schedule ks2,
++	des_key_schedule ks3, des_cblock *ivec, int *num);
++
++void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
++	des_cblock (*out_white));
++
++int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
++	des_cblock *iv);
++int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
++	des_cblock *iv);
++char *des_fcrypt(const char *buf,const char *salt, char *ret);
++#ifdef PERL5
++char *des_crypt(const char *buf,const char *salt);
++#else
++/* some stupid compilers complain because I have declared char instead
++ * of const char */
++#ifndef __KERNEL__
++#ifdef HEADER_DES_LOCL_H
++char *crypt(const char *buf,const char *salt);
++#else /* HEADER_DES_LOCL_H */
++char *crypt(void);
++#endif /* HEADER_DES_LOCL_H */
++#endif /* __KERNEL__ */
++#endif /* PERL5 */
++void des_ofb_encrypt(unsigned char *in,unsigned char *out,
++	int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
++void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
++	des_key_schedule schedule,des_cblock *ivec,int enc);
++DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
++	long length,int out_count,des_cblock *seed);
++void des_random_seed(des_cblock key);
++void des_random_key(des_cblock ret);
++int des_read_password(des_cblock *key,char *prompt,int verify);
++int des_read_2passwords(des_cblock *key1,des_cblock *key2,
++	char *prompt,int verify);
++int des_read_pw_string(char *buf,int length,char *prompt,int verify);
++void des_set_odd_parity(des_cblock *key);
++int des_is_weak_key(des_cblock *key);
++int des_set_key(des_cblock *key,des_key_schedule schedule);
++int des_key_sched(des_cblock *key,des_key_schedule schedule);
++void des_string_to_key(char *str,des_cblock *key);
++void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
++void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
++	des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
++void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
++	des_key_schedule schedule, des_cblock *ivec, int *num);
++int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
++
++/* Extra functions from Mark Murray <mark at grondar.za> */
++/* The following functions are not in the normal unix build or the
++ * SSLeay build.  When using the SSLeay build, use RAND_seed()
++ * and RAND_bytes() instead. */
++int des_new_random_key(des_cblock *key);
++void des_init_random_number_generator(des_cblock *key);
++void des_set_random_generator_seed(des_cblock *key);
++void des_set_sequence_number(des_cblock new_sequence_number);
++void des_generate_random_block(des_cblock *block);
++
++#else
++
++char *des_options();
++void des_ecb3_encrypt();
++DES_LONG des_cbc_cksum();
++void des_cbc_encrypt();
++void des_ncbc_encrypt();
++void des_xcbc_encrypt();
++void des_cfb_encrypt();
++void des_ede3_cfb64_encrypt();
++void des_ede3_ofb64_encrypt();
++void des_ecb_encrypt();
++void des_encrypt();
++void des_encrypt2();
++void des_encrypt3();
++void des_decrypt3();
++void des_ede3_cbc_encrypt();
++int des_enc_read();
++int des_enc_write();
++char *des_fcrypt();
++#ifdef PERL5
++char *des_crypt();
++#else
++char *crypt();
++#endif
++void des_ofb_encrypt();
++void des_pcbc_encrypt();
++DES_LONG des_quad_cksum();
++void des_random_seed();
++void des_random_key();
++int des_read_password();
++int des_read_2passwords();
++int des_read_pw_string();
++void des_set_odd_parity();
++int des_is_weak_key();
++int des_set_key();
++int des_key_sched();
++void des_string_to_key();
++void des_string_to_2keys();
++void des_cfb64_encrypt();
++void des_ofb64_encrypt();
++int des_read_pw();
++void des_xwhite_in2out();
++
++/* Extra functions from Mark Murray <mark at grondar.za> */
++/* The following functions are not in the normal unix build or the
++ * SSLeay build.  When using the SSLeay build, use RAND_seed()
++ * and RAND_bytes() instead. */
++#ifdef FreeBSD
++int des_new_random_key();
++void des_init_random_number_generator();
++void des_set_random_generator_seed();
++void des_set_sequence_number();
++void des_generate_random_block();
++#endif
++
++#endif
++
++#ifdef  __cplusplus
++}
++#endif
++
++#endif
+diff --git a/include/deflate.h b/include/deflate.h
+new file mode 100644
+index 0000000..511d0cb
+--- /dev/null
++++ b/include/deflate.h
+@@ -0,0 +1,318 @@
++/* deflate.h -- internal compression state
++ * Copyright (C) 1995-2002 Jean-loup Gailly
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++/* @(#) $Id$ */
++
++#ifndef _DEFLATE_H
++#define _DEFLATE_H
++
++#include "zlib/zutil.h"
++
++/* ===========================================================================
++ * Internal compression state.
++ */
++
++#define LENGTH_CODES 29
++/* number of length codes, not counting the special END_BLOCK code */
++
++#define LITERALS  256
++/* number of literal bytes 0..255 */
++
++#define L_CODES (LITERALS+1+LENGTH_CODES)
++/* number of Literal or Length codes, including the END_BLOCK code */
++
++#define D_CODES   30
++/* number of distance codes */
++
++#define BL_CODES  19
++/* number of codes used to transfer the bit lengths */
++
++#define HEAP_SIZE (2*L_CODES+1)
++/* maximum heap size */
++
++#define MAX_BITS 15
++/* All codes must not exceed MAX_BITS bits */
++
++#define INIT_STATE    42
++#define BUSY_STATE   113
++#define FINISH_STATE 666
++/* Stream status */
++
++
++/* Data structure describing a single value and its code string. */
++typedef struct ct_data_s {
++    union {
++        ush  freq;       /* frequency count */
++        ush  code;       /* bit string */
++    } fc;
++    union {
++        ush  dad;        /* father node in Huffman tree */
++        ush  len;        /* length of bit string */
++    } dl;
++} FAR ct_data;
++
++#define Freq fc.freq
++#define Code fc.code
++#define Dad  dl.dad
++#define Len  dl.len
++
++typedef struct static_tree_desc_s  static_tree_desc;
++
++typedef struct tree_desc_s {
++    ct_data *dyn_tree;           /* the dynamic tree */
++    int     max_code;            /* largest code with non zero frequency */
++    static_tree_desc *stat_desc; /* the corresponding static tree */
++} FAR tree_desc;
++
++typedef ush Pos;
++typedef Pos FAR Posf;
++typedef unsigned IPos;
++
++/* A Pos is an index in the character window. We use short instead of int to
++ * save space in the various tables. IPos is used only for parameter passing.
++ */
++
++typedef struct internal_state {
++    z_streamp strm;      /* pointer back to this zlib stream */
++    int   status;        /* as the name implies */
++    Bytef *pending_buf;  /* output still pending */
++    ulg   pending_buf_size; /* size of pending_buf */
++    Bytef *pending_out;  /* next pending byte to output to the stream */
++    int   pending;       /* nb of bytes in the pending buffer */
++    int   noheader;      /* suppress zlib header and adler32 */
++    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
++    Byte  method;        /* STORED (for zip only) or DEFLATED */
++    int   last_flush;    /* value of flush param for previous deflate call */
++
++                /* used by deflate.c: */
++
++    uInt  w_size;        /* LZ77 window size (32K by default) */
++    uInt  w_bits;        /* log2(w_size)  (8..16) */
++    uInt  w_mask;        /* w_size - 1 */
++
++    Bytef *window;
++    /* Sliding window. Input bytes are read into the second half of the window,
++     * and move to the first half later to keep a dictionary of at least wSize
++     * bytes. With this organization, matches are limited to a distance of
++     * wSize-MAX_MATCH bytes, but this ensures that IO is always
++     * performed with a length multiple of the block size. Also, it limits
++     * the window size to 64K, which is quite useful on MSDOS.
++     * To do: use the user input buffer as sliding window.
++     */
++
++    ulg window_size;
++    /* Actual size of window: 2*wSize, except when the user input buffer
++     * is directly used as sliding window.
++     */
++
++    Posf *prev;
++    /* Link to older string with same hash index. To limit the size of this
++     * array to 64K, this link is maintained only for the last 32K strings.
++     * An index in this array is thus a window index modulo 32K.
++     */
++
++    Posf *head; /* Heads of the hash chains or NIL. */
++
++    uInt  ins_h;          /* hash index of string to be inserted */
++    uInt  hash_size;      /* number of elements in hash table */
++    uInt  hash_bits;      /* log2(hash_size) */
++    uInt  hash_mask;      /* hash_size-1 */
++
++    uInt  hash_shift;
++    /* Number of bits by which ins_h must be shifted at each input
++     * step. It must be such that after MIN_MATCH steps, the oldest
++     * byte no longer takes part in the hash key, that is:
++     *   hash_shift * MIN_MATCH >= hash_bits
++     */
++
++    long block_start;
++    /* Window position at the beginning of the current output block. Gets
++     * negative when the window is moved backwards.
++     */
++
++    uInt match_length;           /* length of best match */
++    IPos prev_match;             /* previous match */
++    int match_available;         /* set if previous match exists */
++    uInt strstart;               /* start of string to insert */
++    uInt match_start;            /* start of matching string */
++    uInt lookahead;              /* number of valid bytes ahead in window */
++
++    uInt prev_length;
++    /* Length of the best match at previous step. Matches not greater than this
++     * are discarded. This is used in the lazy match evaluation.
++     */
++
++    uInt max_chain_length;
++    /* To speed up deflation, hash chains are never searched beyond this
++     * length.  A higher limit improves compression ratio but degrades the
++     * speed.
++     */
++
++    uInt max_lazy_match;
++    /* Attempt to find a better match only when the current match is strictly
++     * smaller than this value. This mechanism is used only for compression
++     * levels >= 4.
++     */
++#   define max_insert_length  max_lazy_match
++    /* Insert new strings in the hash table only if the match length is not
++     * greater than this length. This saves time but degrades compression.
++     * max_insert_length is used only for compression levels <= 3.
++     */
++
++    int level;    /* compression level (1..9) */
++    int strategy; /* favor or force Huffman coding*/
++
++    uInt good_match;
++    /* Use a faster search when the previous match is longer than this */
++
++    int nice_match; /* Stop searching when current match exceeds this */
++
++                /* used by trees.c: */
++    /* Didn't use ct_data typedef below to supress compiler warning */
++    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
++    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
++    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
++
++    struct tree_desc_s l_desc;               /* desc. for literal tree */
++    struct tree_desc_s d_desc;               /* desc. for distance tree */
++    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
++
++    ush bl_count[MAX_BITS+1];
++    /* number of codes at each bit length for an optimal tree */
++
++    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
++    int heap_len;               /* number of elements in the heap */
++    int heap_max;               /* element of largest frequency */
++    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
++     * The same heap array is used to build all trees.
++     */
++
++    uch depth[2*L_CODES+1];
++    /* Depth of each subtree used as tie breaker for trees of equal frequency
++     */
++
++    uchf *l_buf;          /* buffer for literals or lengths */
++
++    uInt  lit_bufsize;
++    /* Size of match buffer for literals/lengths.  There are 4 reasons for
++     * limiting lit_bufsize to 64K:
++     *   - frequencies can be kept in 16 bit counters
++     *   - if compression is not successful for the first block, all input
++     *     data is still in the window so we can still emit a stored block even
++     *     when input comes from standard input.  (This can also be done for
++     *     all blocks if lit_bufsize is not greater than 32K.)
++     *   - if compression is not successful for a file smaller than 64K, we can
++     *     even emit a stored file instead of a stored block (saving 5 bytes).
++     *     This is applicable only for zip (not gzip or zlib).
++     *   - creating new Huffman trees less frequently may not provide fast
++     *     adaptation to changes in the input data statistics. (Take for
++     *     example a binary file with poorly compressible code followed by
++     *     a highly compressible string table.) Smaller buffer sizes give
++     *     fast adaptation but have of course the overhead of transmitting
++     *     trees more frequently.
++     *   - I can't count above 4
++     */
++
++    uInt last_lit;      /* running index in l_buf */
++
++    ushf *d_buf;
++    /* Buffer for distances. To simplify the code, d_buf and l_buf have
++     * the same number of elements. To use different lengths, an extra flag
++     * array would be necessary.
++     */
++
++    ulg opt_len;        /* bit length of current block with optimal trees */
++    ulg static_len;     /* bit length of current block with static trees */
++    uInt matches;       /* number of string matches in current block */
++    int last_eob_len;   /* bit length of EOB code for last block */
++
++#ifdef DEBUG
++    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
++    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
++#endif
++
++    ush bi_buf;
++    /* Output buffer. bits are inserted starting at the bottom (least
++     * significant bits).
++     */
++    int bi_valid;
++    /* Number of valid bits in bi_buf.  All bits above the last valid bit
++     * are always zero.
++     */
++
++} FAR deflate_state;
++
++/* Output a byte on the stream.
++ * IN assertion: there is enough room in pending_buf.
++ */
++#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
++
++
++#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
++/* Minimum amount of lookahead, except at the end of the input file.
++ * See deflate.c for comments about the MIN_MATCH+1.
++ */
++
++#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
++/* In order to simplify the code, particularly on 16 bit machines, match
++ * distances are limited to MAX_DIST instead of WSIZE.
++ */
++
++        /* in trees.c */
++void _tr_init         OF((deflate_state *s));
++int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
++void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
++			  int eof));
++void _tr_align        OF((deflate_state *s));
++void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
++                          int eof));
++
++#define d_code(dist) \
++   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
++/* Mapping from a distance to a distance code. dist is the distance - 1 and
++ * must not have side effects. _dist_code[256] and _dist_code[257] are never
++ * used.
++ */
++
++#ifndef DEBUG
++/* Inline versions of _tr_tally for speed: */
++
++#if defined(GEN_TREES_H) || !defined(STDC)
++  extern uch _length_code[];
++  extern uch _dist_code[];
++#else
++  extern const uch _length_code[];
++  extern const uch _dist_code[];
++#endif
++
++# define _tr_tally_lit(s, c, flush) \
++  { uch cc = (c); \
++    s->d_buf[s->last_lit] = 0; \
++    s->l_buf[s->last_lit++] = cc; \
++    s->dyn_ltree[cc].Freq++; \
++    flush = (s->last_lit == s->lit_bufsize-1); \
++   }
++# define _tr_tally_dist(s, distance, length, flush) \
++  { uch len = (length); \
++    ush dist = (distance); \
++    s->d_buf[s->last_lit] = dist; \
++    s->l_buf[s->last_lit++] = len; \
++    dist--; \
++    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
++    s->dyn_dtree[d_code(dist)].Freq++; \
++    flush = (s->last_lit == s->lit_bufsize-1); \
++  }
++#else
++# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
++# define _tr_tally_dist(s, distance, length, flush) \
++              flush = _tr_tally(s, distance, length) 
++#endif
++
++#endif /* _DEFLATE_H */
+diff --git a/include/des_locl.h b/include/des_locl.h
+new file mode 100644
+index 0000000..020d6b7
+--- /dev/null
++++ b/include/des_locl.h
+@@ -0,0 +1,515 @@
++/* crypto/des/des_locl.org */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
++ *
++ * Always modify des_locl.org since des_locl.h is automatically generated from
++ * it during SSLeay configuration.
++ *
++ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
++ */
++
++#ifndef HEADER_DES_LOCL_H
++#define HEADER_DES_LOCL_H
++
++#if defined(WIN32) || defined(WIN16)
++#ifndef MSDOS
++#define MSDOS
++#endif
++#endif
++
++#include "crypto/des.h"
++
++#ifndef DES_DEFAULT_OPTIONS
++/* the following is tweaked from a config script, that is why it is a
++ * protected undef/define */
++#ifndef DES_PTR
++#define DES_PTR
++#endif
++
++/* This helps C compiler generate the correct code for multiple functional
++ * units.  It reduces register dependancies at the expense of 2 more
++ * registers */
++#ifndef DES_RISC1
++#define DES_RISC1
++#endif
++
++#ifndef DES_RISC2
++#undef DES_RISC2
++#endif
++
++#if defined(DES_RISC1) && defined(DES_RISC2)
++YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
++#endif
++
++/* Unroll the inner loop, this sometimes helps, sometimes hinders.
++ * Very mucy CPU dependant */
++#ifndef DES_UNROLL
++#define DES_UNROLL
++#endif
++
++/* These default values were supplied by
++ * Peter Gutman <pgut001 at cs.auckland.ac.nz>
++ * They are only used if nothing else has been defined */
++#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
++/* Special defines which change the way the code is built depending on the
++   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
++   even newer MIPS CPU's, but at the moment one size fits all for
++   optimization options.  Older Sparc's work better with only UNROLL, but
++   there's no way to tell at compile time what it is you're running on */
++ 
++#if defined( sun )		/* Newer Sparc's */
++  #define DES_PTR
++  #define DES_RISC1
++  #define DES_UNROLL
++#elif defined( __ultrix )	/* Older MIPS */
++  #define DES_PTR
++  #define DES_RISC2
++  #define DES_UNROLL
++#elif defined( __osf1__ )	/* Alpha */
++  #define DES_PTR
++  #define DES_RISC2
++#elif defined ( _AIX )		/* RS6000 */
++  /* Unknown */
++#elif defined( __hpux )		/* HP-PA */
++  /* Unknown */
++#elif defined( __aux )		/* 68K */
++  /* Unknown */
++#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
++  #define DES_UNROLL
++#elif defined( __sgi )		/* Newer MIPS */
++  #define DES_PTR
++  #define DES_RISC2
++  #define DES_UNROLL
++#elif defined( i386 )		/* x86 boxes, should be gcc */
++  #define DES_PTR
++  #define DES_RISC1
++  #define DES_UNROLL
++#endif /* Systems-specific speed defines */
++#endif
++
++#endif /* DES_DEFAULT_OPTIONS */
++
++#ifdef MSDOS		/* Visual C++ 2.1 (Windows NT/95) */
++#include <stdlib.h>
++#include <errno.h>
++#include <time.h>
++#include <io.h>
++#ifndef RAND
++#define RAND
++#endif
++#undef NOPROTO
++#endif
++
++#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
++#ifndef __KERNEL__
++#include <string.h>
++#else
++#include <linux/string.h>
++#endif
++#endif
++
++#ifndef RAND
++#define RAND
++#endif
++
++#ifdef linux
++#undef RAND
++#endif
++
++#ifdef MSDOS
++#define getpid() 2
++#define RAND
++#undef NOPROTO
++#endif
++
++#if defined(NOCONST)
++#define const
++#endif
++
++#ifdef __STDC__
++#undef NOPROTO
++#endif
++
++#ifdef RAND
++#define srandom(s) srand(s)
++#define random rand
++#endif
++
++#define ITERATIONS 16
++#define HALF_ITERATIONS 8
++
++/* used in des_read and des_write */
++#define MAXWRITE	(1024*16)
++#define BSIZE		(MAXWRITE+4)
++
++#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
++			 l|=((DES_LONG)(*((c)++)))<< 8L, \
++			 l|=((DES_LONG)(*((c)++)))<<16L, \
++			 l|=((DES_LONG)(*((c)++)))<<24L)
++
++/* NOTE - c is not incremented as per c2l */
++#define c2ln(c,l1,l2,n)	{ \
++			c+=n; \
++			l1=l2=0; \
++			switch (n) { \
++			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
++			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
++			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
++			case 5: l2|=((DES_LONG)(*(--(c))));     \
++			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
++			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
++			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
++			case 1: l1|=((DES_LONG)(*(--(c))));     \
++				} \
++			}
++
++#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
++			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
++			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
++			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
++
++/* replacements for htonl and ntohl since I have no idea what to do
++ * when faced with machines with 8 byte longs. */
++#define HDRSIZE 4
++
++#define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
++			 l|=((DES_LONG)(*((c)++)))<<16L, \
++			 l|=((DES_LONG)(*((c)++)))<< 8L, \
++			 l|=((DES_LONG)(*((c)++))))
++
++#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
++			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
++			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
++			 *((c)++)=(unsigned char)(((l)     )&0xff))
++
++/* NOTE - c is not incremented as per l2c */
++#define l2cn(l1,l2,c,n)	{ \
++			c+=n; \
++			switch (n) { \
++			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
++			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
++			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
++			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
++			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
++			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
++			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
++			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
++				} \
++			}
++
++#if defined(WIN32)
++#define	ROTATE(a,n)	(_lrotr(a,n))
++#else
++#define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
++#endif
++
++/* Don't worry about the LOAD_DATA() stuff, that is used by
++ * fcrypt() to add it's little bit to the front */
++
++#ifdef DES_FCRYPT
++
++#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
++	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
++
++#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
++	t=R^(R>>16L); \
++	u=t&E0; t&=E1; \
++	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
++	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
++#else
++#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
++#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
++	u=R^s[S  ]; \
++	t=R^s[S+1]
++#endif
++
++/* The changes to this macro may help or hinder, depending on the
++ * compiler and the achitecture.  gcc2 always seems to do well :-).
++ * Inspired by Dana How <how at isl.stanford.edu>
++ * DO NOT use the alternative version on machines with 8 byte longs.
++ * It does not seem to work on the Alpha, even when DES_LONG is 4
++ * bytes, probably an issue of accessing non-word aligned objects :-( */
++#ifdef DES_PTR
++
++/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
++ * is no reason to not xor all the sub items together.  This potentially
++ * saves a register since things can be xored directly into L */
++
++#if defined(DES_RISC1) || defined(DES_RISC2)
++#ifdef DES_RISC1
++#define D_ENCRYPT(LL,R,S) { \
++	unsigned int u1,u2,u3; \
++	LOAD_DATA(R,S,u,t,E0,E1,u1); \
++	u2=(int)u>>8L; \
++	u1=(int)u&0xfc; \
++	u2&=0xfc; \
++	t=ROTATE(t,4); \
++	u>>=16L; \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
++	u3=(int)(u>>8L); \
++	u1=(int)u&0xfc; \
++	u3&=0xfc; \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
++	u2=(int)t>>8L; \
++	u1=(int)t&0xfc; \
++	u2&=0xfc; \
++	t>>=16L; \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
++	u3=(int)t>>8L; \
++	u1=(int)t&0xfc; \
++	u3&=0xfc; \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
++#endif
++#ifdef DES_RISC2
++#define D_ENCRYPT(LL,R,S) { \
++	unsigned int u1,u2,s1,s2; \
++	LOAD_DATA(R,S,u,t,E0,E1,u1); \
++	u2=(int)u>>8L; \
++	u1=(int)u&0xfc; \
++	u2&=0xfc; \
++	t=ROTATE(t,4); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
++	s1=(int)(u>>16L); \
++	s2=(int)(u>>24L); \
++	s1&=0xfc; \
++	s2&=0xfc; \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
++	u2=(int)t>>8L; \
++	u1=(int)t&0xfc; \
++	u2&=0xfc; \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
++	s1=(int)(t>>16L); \
++	s2=(int)(t>>24L); \
++	s1&=0xfc; \
++	s2&=0xfc; \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
++	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
++#endif
++#else
++#define D_ENCRYPT(LL,R,S) { \
++	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
++	t=ROTATE(t,4); \
++	LL^= \
++	*(DES_LONG *)((unsigned char *)des_SP      +((u     )&0xfc))^ \
++	*(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
++	*(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
++	*(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
++	*(DES_LONG *)((unsigned char *)des_SP+0x100+((t     )&0xfc))^ \
++	*(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
++	*(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
++	*(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
++#endif
++
++#else /* original version */
++
++#if defined(DES_RISC1) || defined(DES_RISC2)
++#ifdef DES_RISC1
++#define D_ENCRYPT(LL,R,S) {\
++	unsigned int u1,u2,u3; \
++	LOAD_DATA(R,S,u,t,E0,E1,u1); \
++	u>>=2L; \
++	t=ROTATE(t,6); \
++	u2=(int)u>>8L; \
++	u1=(int)u&0x3f; \
++	u2&=0x3f; \
++	u>>=16L; \
++	LL^=des_SPtrans[0][u1]; \
++	LL^=des_SPtrans[2][u2]; \
++	u3=(int)u>>8L; \
++	u1=(int)u&0x3f; \
++	u3&=0x3f; \
++	LL^=des_SPtrans[4][u1]; \
++	LL^=des_SPtrans[6][u3]; \
++	u2=(int)t>>8L; \
++	u1=(int)t&0x3f; \
++	u2&=0x3f; \
++	t>>=16L; \
++	LL^=des_SPtrans[1][u1]; \
++	LL^=des_SPtrans[3][u2]; \
++	u3=(int)t>>8L; \
++	u1=(int)t&0x3f; \
++	u3&=0x3f; \
++	LL^=des_SPtrans[5][u1]; \
++	LL^=des_SPtrans[7][u3]; }
++#endif
++#ifdef DES_RISC2
++#define D_ENCRYPT(LL,R,S) {\
++	unsigned int u1,u2,s1,s2; \
++	LOAD_DATA(R,S,u,t,E0,E1,u1); \
++	u>>=2L; \
++	t=ROTATE(t,6); \
++	u2=(int)u>>8L; \
++	u1=(int)u&0x3f; \
++	u2&=0x3f; \
++	LL^=des_SPtrans[0][u1]; \
++	LL^=des_SPtrans[2][u2]; \
++	s1=(int)u>>16L; \
++	s2=(int)u>>24L; \
++	s1&=0x3f; \
++	s2&=0x3f; \
++	LL^=des_SPtrans[4][s1]; \
++	LL^=des_SPtrans[6][s2]; \
++	u2=(int)t>>8L; \
++	u1=(int)t&0x3f; \
++	u2&=0x3f; \
++	LL^=des_SPtrans[1][u1]; \
++	LL^=des_SPtrans[3][u2]; \
++	s1=(int)t>>16; \
++	s2=(int)t>>24L; \
++	s1&=0x3f; \
++	s2&=0x3f; \
++	LL^=des_SPtrans[5][s1]; \
++	LL^=des_SPtrans[7][s2]; }
++#endif
++
++#else
++
++#define D_ENCRYPT(LL,R,S) {\
++	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
++	t=ROTATE(t,4); \
++	LL^=\
++		des_SPtrans[0][(u>> 2L)&0x3f]^ \
++		des_SPtrans[2][(u>>10L)&0x3f]^ \
++		des_SPtrans[4][(u>>18L)&0x3f]^ \
++		des_SPtrans[6][(u>>26L)&0x3f]^ \
++		des_SPtrans[1][(t>> 2L)&0x3f]^ \
++		des_SPtrans[3][(t>>10L)&0x3f]^ \
++		des_SPtrans[5][(t>>18L)&0x3f]^ \
++		des_SPtrans[7][(t>>26L)&0x3f]; }
++#endif
++#endif
++
++	/* IP and FP
++	 * The problem is more of a geometric problem that random bit fiddling.
++	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
++	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
++	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
++	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
++
++	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
++	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
++	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
++	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
++
++	The output has been subject to swaps of the form
++	0 1 -> 3 1 but the odd and even bits have been put into
++	2 3    2 0
++	different words.  The main trick is to remember that
++	t=((l>>size)^r)&(mask);
++	r^=t;
++	l^=(t<<size);
++	can be used to swap and move bits between words.
++
++	So l =  0  1  2  3  r = 16 17 18 19
++	        4  5  6  7      20 21 22 23
++	        8  9 10 11      24 25 26 27
++	       12 13 14 15      28 29 30 31
++	becomes (for size == 2 and mask == 0x3333)
++	   t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
++		 6^20  7^21 -- --        4  5 20 21       6  7 22 23
++		10^24 11^25 -- --        8  9 24 25      10 11 24 25
++		14^28 15^29 -- --       12 13 28 29      14 15 28 29
++
++	Thanks for hints from Richard Outerbridge - he told me IP&FP
++	could be done in 15 xor, 10 shifts and 5 ands.
++	When I finally started to think of the problem in 2D
++	I first got ~42 operations without xors.  When I remembered
++	how to use xors :-) I got it to its final state.
++	*/
++#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
++	(b)^=(t),\
++	(a)^=((t)<<(n)))
++
++#define IP(l,r) \
++	{ \
++	register DES_LONG tt; \
++	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
++	PERM_OP(l,r,tt,16,0x0000ffffL); \
++	PERM_OP(r,l,tt, 2,0x33333333L); \
++	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
++	PERM_OP(r,l,tt, 1,0x55555555L); \
++	}
++
++#define FP(l,r) \
++	{ \
++	register DES_LONG tt; \
++	PERM_OP(l,r,tt, 1,0x55555555L); \
++	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
++	PERM_OP(l,r,tt, 2,0x33333333L); \
++	PERM_OP(r,l,tt,16,0x0000ffffL); \
++	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
++	}
++
++extern const DES_LONG des_SPtrans[8][64];
++
++#ifndef NOPROTO
++void fcrypt_body(DES_LONG *out,des_key_schedule ks,
++	DES_LONG Eswap0, DES_LONG Eswap1);
++#else
++void fcrypt_body();
++#endif
++
++#endif
+diff --git a/include/freeswan.h b/include/freeswan.h
+new file mode 100644
+index 0000000..68b9ddc
+--- /dev/null
++++ b/include/freeswan.h
+@@ -0,0 +1,477 @@
++#ifndef _FREESWAN_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$
++ */
++#define	_FREESWAN_H	/* seen it, no need to see it again */
++
++
++
++/*
++ * We've just got to have some datatypes defined...  And annoyingly, just
++ * where we get them depends on whether we're in userland or not.
++ */
++#ifdef __KERNEL__
++
++#  include <linux/types.h>
++#  include <linux/in.h>
++
++#else /* __KERNEL__ */
++
++#  include <stdio.h>
++#  include <netinet/in.h>
++
++#  define uint8_t u_int8_t
++#  define uint16_t u_int16_t 
++#  define uint32_t u_int32_t 
++#  define uint64_t u_int64_t 
++
++#  define DEBUG_NO_STATIC static
++
++#endif /* __KERNEL__ */
++
++#include <freeswan/ipsec_param.h>
++
++
++/*
++ * Grab the kernel version to see if we have NET_21, and therefore 
++ * IPv6. Some of this is repeated from ipsec_kversions.h. Of course, 
++ * we aren't really testing if the kernel has IPv6, but rather if the
++ * the include files do.
++ */
++#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 NET_21
++#endif
++
++#ifndef IPPROTO_COMP
++#  define IPPROTO_COMP 108
++#endif /* !IPPROTO_COMP */
++
++#ifndef IPPROTO_INT
++#  define IPPROTO_INT 61
++#endif /* !IPPROTO_INT */
++
++#ifdef CONFIG_KLIPS_DEBUG
++#  define DEBUG_NO_STATIC
++#else /* CONFIG_KLIPS_DEBUG */
++#  define DEBUG_NO_STATIC static
++#endif /* CONFIG_KLIPS_DEBUG */
++
++#define IPCOMP_PREFIX 1
++
++/*
++ * Basic data types for the address-handling functions.
++ * ip_address and ip_subnet are supposed to be opaque types; do not
++ * use their definitions directly, they are subject to change!
++ */
++
++/* first, some quick fakes in case we're on an old system with no IPv6 */
++#ifndef s6_addr16
++struct in6_addr {
++	union 
++	{
++		__u8		u6_addr8[16];
++		__u16		u6_addr16[8];
++		__u32		u6_addr32[4];
++	} in6_u;
++#define s6_addr			in6_u.u6_addr8
++#define s6_addr16		in6_u.u6_addr16
++#define s6_addr32		in6_u.u6_addr32
++};
++struct sockaddr_in6 {
++	unsigned short int	sin6_family;    /* AF_INET6 */
++	__u16			sin6_port;      /* Transport layer port # */
++	__u32			sin6_flowinfo;  /* IPv6 flow information */
++	struct in6_addr		sin6_addr;      /* IPv6 address */
++	__u32			sin6_scope_id;  /* scope id (new in RFC2553) */
++};
++#endif	/* !s6_addr16 */
++
++/* then the main types */
++typedef struct {
++	union {
++		struct sockaddr_in v4;
++		struct sockaddr_in6 v6;
++	} u;
++} ip_address;
++typedef struct {
++	ip_address addr;
++	int maskbits;
++} ip_subnet;
++
++/* and the SA ID stuff */
++#ifdef __KERNEL__
++typedef __u32 ipsec_spi_t;
++#else
++typedef u_int32_t ipsec_spi_t;
++#endif
++typedef struct {		/* to identify an SA, we need: */
++        ip_address dst;		/* A. destination host */
++        ipsec_spi_t spi;	/* B. 32-bit SPI, assigned by dest. host */
++#		define	SPI_PASS	256	/* magic values... */
++#		define	SPI_DROP	257	/* ...for use... */
++#		define	SPI_REJECT	258	/* ...with SA_INT */
++#		define	SPI_HOLD	259
++#		define	SPI_TRAP	260
++#		define  SPI_TRAPSUBNET  261
++#               define  SPI_PASSTRAP    262
++	int proto;		/* C. protocol */
++#		define	SA_ESP	50	/* IPPROTO_ESP */
++#		define	SA_AH	51	/* IPPROTO_AH */
++#		define	SA_IPIP	4	/* IPPROTO_IPIP */
++#		define	SA_COMP	108	/* IPPROTO_COMP */
++#		define	SA_INT	61	/* IANA reserved for internal use */
++} ip_said;
++
++/* misc */
++typedef const char *err_t;	/* error message, or NULL for success */
++struct prng {			/* pseudo-random-number-generator guts */
++	unsigned char sbox[256];
++	int i, j;
++	unsigned long count;
++};
++
++
++/*
++ * definitions for user space, taken from freeswan/ipsec_sa.h
++ */
++typedef uint32_t IPsecSAref_t;
++
++#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
++
++#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
++#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
++
++#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0))
++
++/* GCC magic for use in function definitions! */
++#ifdef GCC_LINT
++# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
++# define NEVER_RETURNS __attribute__ ((noreturn))
++# define UNUSED __attribute__ ((unused))
++# define BLANK_FORMAT " "	/* GCC_LINT whines about empty formats */
++#else
++# define PRINTF_LIKE(n)	/* ignore */
++# define NEVER_RETURNS /* ignore */
++# define UNUSED /* ignore */
++# define BLANK_FORMAT ""
++#endif
++
++
++
++
++
++/*
++ * new IPv6-compatible functions
++ */
++
++/* text conversions */
++err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
++size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
++#define	ULTOT_BUF	(22+1)	/* holds 64 bits in octal */
++err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
++err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
++size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
++/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
++#define	ADDRTOT_BUF	(32*2 + 3 + 1 + 3 + 1 + 1)
++err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
++size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
++#define	SUBNETTOT_BUF	(ADDRTOT_BUF + 1 + 3)
++err_t ttosa(const char *src, size_t srclen, ip_said *dst);
++size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
++#define	SATOT_BUF	(5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
++err_t ttodata(const char *src, size_t srclen, int base, char *buf,
++						size_t buflen, size_t *needed);
++err_t ttodatav(const char *src, size_t srclen, int base,
++	       char *buf,  size_t buflen, size_t *needed,
++	       char *errp, size_t errlen, unsigned int flags);
++#define	TTODATAV_BUF	40	/* ttodatav's largest non-literal message */
++#define TTODATAV_IGNORESPACE  (1<<1)  /* ignore spaces in base64 encodings*/
++#define TTODATAV_SPACECOUNTS  0       /* do not ignore spaces in base64   */
++
++size_t datatot(const char *src, size_t srclen, int format, char *buf,
++								size_t buflen);
++size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
++								size_t dstlen);
++size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
++					size_t mlen, char *dst, size_t dstlen);
++#define	KEYID_BUF	10	/* up to 9 text digits plus NUL */
++err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port);
++
++/* initializations */
++void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
++err_t loopbackaddr(int af, ip_address *dst);
++err_t unspecaddr(int af, ip_address *dst);
++err_t anyaddr(int af, ip_address *dst);
++err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
++err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
++err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
++
++/* misc. conversions and related */
++err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
++int addrtypeof(const ip_address *src);
++int subnettypeof(const ip_subnet *src);
++size_t addrlenof(const ip_address *src);
++size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
++size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
++int masktocount(const ip_address *src);
++void networkof(const ip_subnet *src, ip_address *dst);
++void maskof(const ip_subnet *src, ip_address *dst);
++
++/* tests */
++int sameaddr(const ip_address *a, const ip_address *b);
++int addrcmp(const ip_address *a, const ip_address *b);
++int samesubnet(const ip_subnet *a, const ip_subnet *b);
++int addrinsubnet(const ip_address *a, const ip_subnet *s);
++int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
++int subnetishost(const ip_subnet *s);
++int samesaid(const ip_said *a, const ip_said *b);
++int sameaddrtype(const ip_address *a, const ip_address *b);
++int samesubnettype(const ip_subnet *a, const ip_subnet *b);
++int isanyaddr(const ip_address *src);
++int isunspecaddr(const ip_address *src);
++int isloopbackaddr(const ip_address *src);
++
++/* low-level grot */
++int portof(const ip_address *src);
++void setportof(int port, ip_address *dst);
++struct sockaddr *sockaddrof(ip_address *src);
++size_t sockaddrlenof(const ip_address *src);
++
++/* PRNG */
++void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
++void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
++unsigned long prng_count(struct prng *prng);
++void prng_final(struct prng *prng);
++
++/* odds and ends */
++const char *ipsec_version_code(void);
++const char *ipsec_version_string(void);
++const char **ipsec_copyright_notice(void);
++
++const char *dns_string_rr(int rr, char *buf, int bufsize);
++const char *dns_string_datetime(time_t seconds,
++				char *buf,
++				int bufsize);
++
++
++/*
++ * old functions, to be deleted eventually
++ */
++
++/* unsigned long */
++const char *			/* NULL for success, else string literal */
++atoul(
++	const char *src,
++	size_t srclen,		/* 0 means strlen(src) */
++	int base,		/* 0 means figure it out */
++	unsigned long *resultp
++);
++size_t				/* space needed for full conversion */
++ultoa(
++	unsigned long n,
++	int base,
++	char *dst,
++	size_t dstlen
++);
++#define	ULTOA_BUF	21	/* just large enough for largest result, */
++				/* assuming 64-bit unsigned long! */
++
++/* Internet addresses */
++const char *			/* NULL for success, else string literal */
++atoaddr(
++	const char *src,
++	size_t srclen,		/* 0 means strlen(src) */
++	struct in_addr *addr
++);
++size_t				/* space needed for full conversion */
++addrtoa(
++	struct in_addr addr,
++	int format,		/* character; 0 means default */
++	char *dst,
++	size_t dstlen
++);
++#define	ADDRTOA_BUF	16	/* just large enough for largest result */
++
++/* subnets */
++const char *			/* NULL for success, else string literal */
++atosubnet(
++	const char *src,
++	size_t srclen,		/* 0 means strlen(src) */
++	struct in_addr *addr,
++	struct in_addr *mask
++);
++size_t				/* space needed for full conversion */
++subnettoa(
++	struct in_addr addr,
++	struct in_addr mask,
++	int format,		/* character; 0 means default */
++	char *dst,
++	size_t dstlen
++);
++#define	SUBNETTOA_BUF	32	/* large enough for worst case result */
++
++/* ranges */
++const char *			/* NULL for success, else string literal */
++atoasr(
++	const char *src,
++	size_t srclen,		/* 0 means strlen(src) */
++	char *type,		/* 'a', 's', 'r' */
++	struct in_addr *addrs	/* two-element array */
++);
++size_t				/* space needed for full conversion */
++rangetoa(
++	struct in_addr *addrs,	/* two-element array */
++	int format,		/* character; 0 means default */
++	char *dst,
++	size_t dstlen
++);
++#define	RANGETOA_BUF	34	/* large enough for worst case result */
++
++/* data types for SA conversion functions */
++
++/* generic data, e.g. keys */
++const char *			/* NULL for success, else string literal */
++atobytes(
++	const char *src,
++	size_t srclen,		/* 0 means strlen(src) */
++	char *dst,
++	size_t dstlen,
++	size_t *lenp		/* NULL means don't bother telling me */
++);
++size_t				/* 0 failure, else true size */
++bytestoa(
++	const char *src,
++	size_t srclen,
++	int format,		/* character; 0 means default */
++	char *dst,
++	size_t dstlen
++);
++
++/* old versions of generic-data functions; deprecated */
++size_t				/* 0 failure, else true size */
++atodata(
++	const char *src,
++	size_t srclen,		/* 0 means strlen(src) */
++	char *dst,
++	size_t dstlen
++);
++size_t				/* 0 failure, else true size */
++datatoa(
++	const char *src,
++	size_t srclen,
++	int format,		/* character; 0 means default */
++	char *dst,
++	size_t dstlen
++);
++
++/* part extraction and special addresses */
++struct in_addr
++subnetof(
++	struct in_addr addr,
++	struct in_addr mask
++);
++struct in_addr
++hostof(
++	struct in_addr addr,
++	struct in_addr mask
++);
++struct in_addr
++broadcastof(
++	struct in_addr addr,
++	struct in_addr mask
++);
++
++/* mask handling */
++int
++goodmask(
++	struct in_addr mask
++);
++int
++masktobits(
++	struct in_addr mask
++);
++struct in_addr
++bitstomask(
++	int n
++);
++
++
++
++/*
++ * general utilities
++ */
++
++#ifndef __KERNEL__
++/* option pickup from files (userland only because of use of FILE) */
++const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
++						int optind, FILE *errorreport);
++
++/* sanitize a string */
++extern size_t sanitize_string(char *buf, size_t size);
++
++/* count 0s and 1s in a buffer */
++extern int parityofbuffer(const unsigned char *buf, size_t size);
++
++#endif
++
++/*
++ * ENUM of klips debugging values. Not currently used in klips.
++ * debug flag is actually 32 -bits, but only one bit is ever used,
++ * so we can actually pack it all into a single 32-bit word.
++ */
++enum klips_debug_flags {
++    KDF_VERBOSE     = 0,
++    KDF_XMIT        = 1,
++    KDF_NETLINK     = 2, /* obsolete */
++    KDF_XFORM       = 3,
++    KDF_EROUTE      = 4,
++    KDF_SPI         = 5,
++    KDF_RADIJ       = 6,
++    KDF_ESP         = 7,
++    KDF_AH          = 8, /* obsolete */
++    KDF_RCV         = 9,
++    KDF_TUNNEL      = 10,
++    KDF_PFKEY       = 11,
++    KDF_COMP        = 12
++};
++    
++/*
++ * Debugging levels for pfkey_lib_debug
++ */
++#define PF_KEY_DEBUG_PARSE_NONE    0
++#define PF_KEY_DEBUG_PARSE_PROBLEM 1
++#define PF_KEY_DEBUG_PARSE_STRUCT  2
++#define PF_KEY_DEBUG_PARSE_FLOW    4
++#define PF_KEY_DEBUG_BUILD         8
++#define PF_KEY_DEBUG_PARSE_MAX    15
++
++extern unsigned int pfkey_lib_debug;  /* bits selecting what to report */
++
++/*
++ * pluto and lwdnsq need to know the maximum size of the commands to,
++ * and replies from lwdnsq. 
++ */
++
++#define LWDNSQ_CMDBUF_LEN      1024
++#define LWDNSQ_RESULT_LEN_MAX  4096
++
++#endif /* _FREESWAN_H */
+diff --git a/include/freeswan/ipsec_auth.h b/include/freeswan/ipsec_auth.h
+new file mode 100644
+index 0000000..b2c4ff9
+--- /dev/null
++++ b/include/freeswan/ipsec_auth.h
+@@ -0,0 +1,91 @@
++/*
++ * Authentication Header declarations
++ * Copyright (C) 2003 Michael Richardson <mcr at sandelman.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$
++ */
++
++#include "ipsec_md5h.h"
++#include "ipsec_sha1.h"
++
++#ifndef IPSEC_AUTH_H
++#define IPSEC_AUTH_H
++
++#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 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_IPSA		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) */
++};
++
++struct auth_alg {
++	void (*init)(void *ctx);
++	void (*update)(void *ctx, unsigned char *bytes, __u32 len);
++	void (*final)(unsigned char *hash, void *ctx);
++	int hashlen;
++};
++
++struct options;
++
++#endif /* __KERNEL__ */
++#endif /* IPSEC_AUTH_H */
++
++/*
++ * $Log: ipsec_auth.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.1  2003/12/06 21:21:19  mcr
++ * 	split up receive path into per-transform files, for
++ * 	easier later removal.
++ *
++ *
++ */
+diff --git a/include/freeswan/ipsec_encap.h b/include/freeswan/ipsec_encap.h
+new file mode 100644
+index 0000000..56338e9
+--- /dev/null
++++ b/include/freeswan/ipsec_encap.h
+@@ -0,0 +1,166 @@
++/*
++ * 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$
++ */
++
++#ifndef _IPSEC_ENCAP_H_
++
++#define SENT_IP4	0x0008	/* data is two struct in_addr */
++			/* (2 * sizeof(struct in_addr)) */
++			/* sizeof(struct sockaddr_encap)
++			   - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
++
++#define SEN_HDRLEN	(2*sizeof(__u8)+sizeof(__u16))
++			/* offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
++
++#define SEN_IP4_SRCOFF	(0)
++#define SEN_IP4_DSTOFF (sizeof (struct in_addr))
++			/* offsetof(struct sockaddr_encap, Sen.Sip4.Dst)
++			   - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
++#define SEN_IP4_OPTOFF	(2 * sizeof (struct in_addr))
++			/* sizeof(struct sockaddr_encap)
++			   - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
++
++#define SEN_IP4_LEN	(SENT_HDRLEN + SENT_IP4_OPTOFF)
++			/* sizeof(struct sockaddr_encap) */
++
++#ifdef CONFIG_KLIPS_DEBUG
++#define DB_ER_PROCFS	0x0001
++#define DB_SP_PROCFS	0x0001
++#endif /* CONFIG_KLIPS_DEBUG */
++
++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;
++		} Sip4;
++	} Sen;
++};
++
++#define sen_ip_src	Sen.Sip4.Src
++#define sen_ip_dst	Sen.Sip4.Dst
++
++#ifndef AF_ENCAP
++#define AF_ENCAP 26
++#endif /* AF_ENCAP */
++
++#define _IPSEC_ENCAP_H_
++#endif /* _IPSEC_ENCAP_H_ */
++
++/*
++ * $Log: ipsec_encap.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.20  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.19  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.17  2002/04/24 07:36:46  mcr
++ * Moved from ./klips/net/ipsec/ipsec_encap.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_eroute.h b/include/freeswan/ipsec_eroute.h
+new file mode 100644
+index 0000000..8096198
+--- /dev/null
++++ b/include/freeswan/ipsec_eroute.h
+@@ -0,0 +1,113 @@
++/*
++ * @(#) declarations of eroute structures
++ *
++ * Copyright (C) 1996, 1997  John Ioannidis.
++ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs <rgb at freeswan.org>
++ * Copyright (C) 2001                    Michael Richardson <mcr at 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$
++ *
++ * 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;
++	ip_said 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 er_proto er_said.proto
++
++#define _IPSEC_EROUTE_H_
++#endif /* _IPSEC_EROUTE_H_ */
++
++/*
++ * $Log: ipsec_eroute.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.6  2003/12/04 19:05:26  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.5  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.3  2002/04/24 07:36:46  mcr
++ * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_errs.h b/include/freeswan/ipsec_errs.h
+new file mode 100644
+index 0000000..0b013f1
+--- /dev/null
++++ b/include/freeswan/ipsec_errs.h
+@@ -0,0 +1,56 @@
++/*
++ * @(#) definition of ipsec_errs structure
++ *
++ * Copyright (C) 2001  Richard Guy Briggs  <rgb at freeswan.org>
++ *                 and Michael Richardson  <mcr at 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$
++ *
++ */
++
++/* 
++ * 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: ipsec_errs.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.3  2002/04/24 07:36:46  mcr
++ * Moved from ./klips/net/ipsec/ipsec_errs.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_esp.h b/include/freeswan/ipsec_esp.h
+new file mode 100644
+index 0000000..ddd653a
+--- /dev/null
++++ b/include/freeswan/ipsec_esp.h
+@@ -0,0 +1,218 @@
++/*
++ * 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$
++ */
++
++#include "freeswan/ipsec_md5h.h"
++#include "freeswan/ipsec_sha1.h"
++
++#include "crypto/des.h"
++
++#ifndef IPPROTO_ESP
++#define IPPROTO_ESP 50
++#endif /* IPPROTO_ESP */
++
++#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 DB_ES_PKTRX	0x0001
++#define DB_ES_PKTRX2	0x0002
++#define DB_ES_IPSA	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;
++
++struct esphdr
++{
++	__u32	esp_spi;		/* Security Parameters Index */
++        __u32   esp_rpl;                /* Replay counter */
++	__u8	esp_iv[8];		/* iv */
++};
++
++extern struct xform_functions esp_xform_funcs[];
++
++#ifdef CONFIG_KLIPS_DEBUG
++extern int debug_esp;
++#endif /* CONFIG_KLIPS_DEBUG */
++#endif /* __KERNEL__ */
++
++/*
++ * $Log: ipsec_esp.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.24  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.23  2003/12/11 20:14:58  mcr
++ * 	refactored the xmit code, to move all encapsulation
++ * 	code into protocol functions. Note that all functions
++ * 	are essentially done by a single function, which is probably
++ * 	wrong.
++ * 	the rcv_functions structures are renamed xform_functions.
++ *
++ * Revision 1.22  2003/12/06 21:21:19  mcr
++ * 	split up receive path into per-transform files, for
++ * 	easier later removal.
++ *
++ * Revision 1.21  2003/02/06 02:21:34  rgb
++ *
++ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
++ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
++ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
++ *
++ * Revision 1.20  2002/05/14 02:37:02  rgb
++ * Change reference from _TDB to _IPSA.
++ *
++ * Revision 1.19  2002/04/24 07:55:32  mcr
++ * 	#include patches and Makefiles for post-reorg compilation.
++ *
++ * Revision 1.18  2002/04/24 07:36:46  mcr
++ * Moved from ./klips/net/ipsec/ipsec_esp.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_ipcomp.h b/include/freeswan/ipsec_ipcomp.h
+new file mode 100644
+index 0000000..93c8908
+--- /dev/null
++++ b/include/freeswan/ipsec_ipcomp.h
+@@ -0,0 +1,92 @@
++/*
++ * IP compression header declations
++ *
++ * Copyright (C) 2003 Michael Richardson <mcr at sandelman.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$
++ */
++
++#ifndef IPSEC_IPCOMP_H
++#define IPSEC_IPCOMP_H
++
++#include "freeswan/ipsec_auth.h"
++
++/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
++#ifndef IPCOMP_PREFIX
++#define IPCOMP_PREFIX
++#endif /* IPCOMP_PREFIX */
++
++#ifndef IPPROTO_COMP
++#define IPPROTO_COMP 108
++#endif /* IPPROTO_COMP */
++
++#ifdef CONFIG_KLIPS_DEBUG
++extern int sysctl_ipsec_debug_ipcomp;
++#endif /* CONFIG_KLIPS_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 *ips, unsigned int *flags);
++struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
++
++extern struct xform_functions ipcomp_xform_funcs[];
++
++#endif /* IPSEC_IPCOMP_H */
++
++/*
++ * $Log: ipsec_ipcomp.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.3  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.2  2003/12/11 20:14:58  mcr
++ * 	refactored the xmit code, to move all encapsulation
++ * 	code into protocol functions. Note that all functions
++ * 	are essentially done by a single function, which is probably
++ * 	wrong.
++ * 	the rcv_functions structures are renamed xform_functions.
++ *
++ * Revision 1.1  2003/12/06 21:21:19  mcr
++ * 	split up receive path into per-transform files, for
++ * 	easier later removal.
++ *
++ *
++ *
++ */
++
++
++
+diff --git a/include/freeswan/ipsec_ipe4.h b/include/freeswan/ipsec_ipe4.h
+new file mode 100644
+index 0000000..94bac31
+--- /dev/null
++++ b/include/freeswan/ipsec_ipe4.h
+@@ -0,0 +1,71 @@
++/*
++ * 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$
++ */
++
++/* 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: ipsec_ipe4.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.5  2002/04/24 07:36:46  mcr
++ * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_ipip.h b/include/freeswan/ipsec_ipip.h
+new file mode 100644
+index 0000000..f9a754e
+--- /dev/null
++++ b/include/freeswan/ipsec_ipip.h
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (C) 2003 Michael Richardson <mcr at sandelman.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$
++ */
++
++#ifndef _IPSEC_IPIP_H_
++
++#ifndef IPPROTO_IPIP
++#define IPPROTO_IPIP 4
++#endif /* IPPROTO_ESP */
++
++extern struct xform_functions ipip_xform_funcs[];
++
++#define _IPSEC_IPIP_H_
++
++#endif /* _IPSEC_IPIP_H_ */
++
++/*
++ * $Log: ipsec_ipip.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.1  2003/12/11 20:14:58  mcr
++ * 	refactored the xmit code, to move all encapsulation
++ * 	code into protocol functions. Note that all functions
++ * 	are essentially done by a single function, which is probably
++ * 	wrong.
++ * 	the rcv_functions structures are renamed xform_functions.
++ *
++ *
++ */
+diff --git a/include/freeswan/ipsec_kern24.h b/include/freeswan/ipsec_kern24.h
+new file mode 100644
+index 0000000..7b50bfc
+--- /dev/null
++++ b/include/freeswan/ipsec_kern24.h
+@@ -0,0 +1,43 @@
++/*
++ * @(#) routines to makes kernel 2.4 compatible with 2.6 usage.
++
++ * Copyright (C) 2004 Michael Richardson <mcr at sandelman.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$
++ */
++
++#ifndef _IPSEC_KERN24_H
++
++#ifndef NET_26
++#define sk_receive_queue  receive_queue
++#define sk_destruct       destruct
++#define sk_reuse          reuse
++#define sk_zapped         zapped
++#define sk_family         family
++#define sk_protocol       protocol
++#define sk_protinfo       protinfo
++#define sk_sleep          sleep
++#define sk_state_change   state_change
++#define sk_shutdown       shutdown
++#define sk_err            err
++#define sk_stamp          stamp
++#define sk_socket         socket
++#define sk_sndbuf         sndbuf
++#define sock_flag(sk, flag)  sk->dead
++#define sk_for_each(sk, node, plist) for(sk=*plist; sk!=NULL; sk = sk->next)
++#endif
++
++#define _IPSEC_KERN24_H 1
++
++#endif /* _IPSEC_KERN24_H */
++
+diff --git a/include/freeswan/ipsec_kversion.h b/include/freeswan/ipsec_kversion.h
+new file mode 100644
+index 0000000..118d8b7
+--- /dev/null
++++ b/include/freeswan/ipsec_kversion.h
+@@ -0,0 +1,262 @@
++#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$
++ */
++#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
++#include <linux/socket.h>
++#include <linux/skbuff.h>
++#include <linux/netlink.h>
++#  ifdef NETLINK_XFRM
++#  define NETDEV_25
++#  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                                                                         
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#define HAVE_NETDEV_PRINTK 1
++#define NET_26
++#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
++
++#ifdef NET_21
++# define ipsec_kfree_skb(a) kfree_skb(a)
++#else /* NET_21 */
++# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
++#endif /* NET_21 */
++
++
++#ifdef NETDEV_23
++#if 0
++#ifndef NETDEV_25
++#define device net_device
++#endif
++#endif
++# define ipsec_dev_get dev_get_by_name
++# define __ipsec_dev_get __dev_get_by_name
++# define ipsec_dev_put(x) dev_put(x)
++# define __ipsec_dev_put(x) __dev_put(x)
++# define ipsec_dev_hold(x) dev_hold(x)
++#else /* NETDEV_23 */
++# define ipsec_dev_get dev_get
++# define __ipsec_dev_put(x) 
++# define ipsec_dev_put(x)
++# define ipsec_dev_hold(x) 
++#endif /* NETDEV_23 */
++
++#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 */
++
++#ifndef HAVE_NETDEV_PRINTK
++#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
++	printk(sevlevel "%s: " format , netdev->name , ## arg)
++#endif
++
++#endif /* _FREESWAN_KVERSIONS_H */
++
++/*
++ * $Log: ipsec_kversion.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.10  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.9  2004/02/22 06:49:15  mcr
++ * 	kernel 2.6 port - merged with 2.4 code.
++ *
++ * Revision 1.8.6.1  2004/02/20 14:09:55  mcr
++ * 	moved code to net/ipsec/ to make 2.6 happy.
++ *
++ * Revision 1.8  2003/12/11 20:14:58  mcr
++ * 	refactored the xmit code, to move all encapsulation
++ * 	code into protocol functions. Note that all functions
++ * 	are essentially done by a single function, which is probably
++ * 	wrong.
++ * 	the rcv_functions structures are renamed xform_functions.
++ *
++ * Revision 1.7  2003/07/31 22:48:08  mcr
++ * 	derive NET25-ness from presence of NETLINK_XFRM macro.
++ *
++ * Revision 1.6  2003/06/24 20:22:32  mcr
++ * 	added new global: ipsecdevices[] so that we can keep track of
++ * 	the ipsecX devices. They will be referenced with dev_hold(),
++ * 	so 2.2 may need this as well.
++ *
++ * Revision 1.5  2003/04/03 17:38:09  rgb
++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
++ *
++ * Revision 1.4  2002/04/24 07:36:46  mcr
++ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_life.h b/include/freeswan/ipsec_life.h
+new file mode 100644
+index 0000000..c2e50d3
+--- /dev/null
++++ b/include/freeswan/ipsec_life.h
+@@ -0,0 +1,115 @@
++/*
++ * Definitions relevant to IPSEC lifetimes
++ * Copyright (C) 2001  Richard Guy Briggs  <rgb at freeswan.org>
++ *                 and Michael Richardson  <mcr at 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$
++ *
++ * 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: ipsec_life.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.3  2002/04/24 07:36:46  mcr
++ * Moved from ./klips/net/ipsec/ipsec_life.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_md5h.h b/include/freeswan/ipsec_md5h.h
+new file mode 100644
+index 0000000..a481f70
+--- /dev/null
++++ b/include/freeswan/ipsec_md5h.h
+@@ -0,0 +1,143 @@
++/*
++ * RCSID $Id$
++ */
++
++/*
++ * 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 ((void *));
++void MD5Update PROTO_LIST
++  ((void *, unsigned char *, __u32));
++void MD5Final PROTO_LIST ((unsigned char [16], void *));
++ 
++#endif /* _IPSEC_MD5H_H_ */
++
++/*
++ * $Log: ipsec_md5h.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.8  2002/09/10 01:45:09  mcr
++ * 	changed type of MD5_CTX and SHA1_CTX to void * so that
++ * 	the function prototypes would match, and could be placed
++ * 	into a pointer to a function.
++ *
++ * Revision 1.7  2002/04/24 07:36:46  mcr
++ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_param.h b/include/freeswan/ipsec_param.h
+new file mode 100644
+index 0000000..3823ffc
+--- /dev/null
++++ b/include/freeswan/ipsec_param.h
+@@ -0,0 +1,365 @@
++/*
++ * @(#) FreeSWAN tunable paramaters
++ *
++ * Copyright (C) 2001  Richard Guy Briggs  <rgb at freeswan.org>
++ *                 and Michael Richardson  <mcr at 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$
++ *
++ */
++
++/* 
++ * 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_
++
++#ifdef __KERNEL__
++#include "ipsec_kversion.h"
++
++/* these are always now on */
++#undef CONFIG_KLIPS_ESP
++#define CONFIG_KLIPS_ESP 1
++#undef CONFIG_KLIPS_IPIP
++#define CONFIG_KLIPS_IPIP 1
++
++/* Set number of ipsecX virtual devices here. */
++/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
++/* It must also be reasonable so as not to overload the memory and CPU */
++/* constraints of the host. */
++#define IPSEC_NUM_IF	4
++/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
++/* With "ipsec" being 5 characters, that means 10 is the max field width */
++/* but machine memory and CPU constraints are not likely to tollerate */
++/* more than 3 digits.  The default is one digit. */
++/* Update: userland scripts get upset if they can't find "ipsec0", so */
++/* for now, no "0"-padding should be used (which would have been helpful */
++/* to make text-searches work */
++#define IPSEC_DEV_FORMAT "ipsec%d"
++/* For, say, 500 virtual ipsec devices, I would recommend: */
++/* #define IPSEC_NUM_IF	500 */
++/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
++/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
++
++/* use dynamic ipsecX device allocation */
++#ifndef CONFIG_KLIPS_DYNDEV
++#define CONFIG_KLIPS_DYNDEV 1
++#endif /* CONFIG_KLIPS_DYNDEV */
++
++
++#ifdef CONFIG_KLIPS_BIGGATE
++# define SADB_HASHMOD   8069
++#else /* CONFIG_KLIPS_BIGGATE */
++# define SADB_HASHMOD	257
++#endif /* CONFIG_KLIPS_BIGGATE */
++#endif /* __KERNEL__ */
++
++/*
++ * This is for the SA reference table. This number is related to the
++ * maximum number of SAs that KLIPS can concurrently deal with, plus enough
++ * space for keeping expired SAs around.
++ *
++ * TABLE_MAX_WIDTH is the number of bits that we will use.
++ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
++ *
++ */
++#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
++# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
++#endif
++
++#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 
++# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4 
++#endif
++
++#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES 
++# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
++#endif
++
++#ifndef IPSEC_SA_REF_CODE 
++# define IPSEC_SA_REF_CODE 1 
++#endif
++
++#ifdef __KERNEL__
++/* This is defined for 2.4, but not 2.2.... */
++#ifndef ARPHRD_VOID
++# define ARPHRD_VOID 0xFFFF
++#endif
++
++/*
++ * Worry about PROC_FS stuff
++ */
++#if defined(PROC_FS_2325)
++/* kernel 2.4 */
++# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
++# define IPSEC_PROCFS_DEBUG_NO_STATIC
++# define IPSEC_PROC_SUBDIRS
++#else
++/* kernel <2.4 */
++# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
++
++# ifndef PROC_NO_DUMMY
++#  define IPSEC_PROC_LAST_ARG , int dummy
++# else
++#  define IPSEC_PROC_LAST_ARG
++# endif /* !PROC_NO_DUMMY */
++#endif /* PROC_FS_2325 */
++
++#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
++/* GNU CPP specific! */
++# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
++#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
++
++#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 /* !KLIPS_FIXES_DES_PARITY */
++
++/* we don't really want to print these unless there are really big problems */
++#ifndef KLIPS_DIVULGE_CYPHER_KEY
++# define KLIPS_DIVULGE_CYPHER_KEY 0
++#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
++
++#ifndef KLIPS_DIVULGE_HMAC_KEY
++# define KLIPS_DIVULGE_HMAC_KEY 0
++#endif /* !KLIPS_DIVULGE_HMAC_KEY */
++
++#ifndef IPSEC_DISALLOW_IPOPTIONS
++# define IPSEC_DISALLOW_IPOPTIONS 1
++#endif /* !KLIPS_DIVULGE_HMAC_KEY */
++
++/* extra toggles for regression testing */
++#ifdef CONFIG_KLIPS_REGRESS
++
++/* 
++ * should pfkey_acquire() become 100% lossy?
++ *
++ */
++extern int sysctl_ipsec_regress_pfkey_lossage;
++#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
++# ifdef CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE
++#  define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
++# else /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
++/* not by default! */
++#  define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
++# endif /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
++#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
++
++#endif /* CONFIG_KLIPS_REGRESS */
++
++
++/*
++ * debugging routines.
++ */
++#ifdef CONFIG_KLIPS_DEBUG
++extern void ipsec_print_ip(struct iphdr *ip);
++
++#define KLIPS_PRINTIF(flag) flag
++#define KLIPS_WRITE(format, args...) printk(KERN_INFO format , ## args)
++#define KLIPS_PRINT(flag, format, args...) \
++		((flag) ? KLIPS_WRITE(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_KLIPS_DEBUG */
++
++#define KLIPS_PRINTIF(flag) 0
++#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_KLIPS_DEBUG */
++
++
++/* 
++ * Stupid kernel API differences in APIs. Not only do some
++ * kernels not have ip_select_ident, but some have differing APIs,
++ * and SuSE has one with one parameter, but no way of checking to
++ * see what is really what.
++ */
++
++#ifdef SUSE_LINUX_2_4_19_IS_STUPID
++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
++#else
++
++/* simplest case, nothing */
++#if !defined(IP_SELECT_IDENT)
++#define KLIPS_IP_SELECT_IDENT(iph, skb)  do { iph->id = htons(ip_id_count++); } while(0)
++#endif
++
++/* kernels > 2.3.37-ish */
++#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
++#endif
++
++/* kernels > 2.4.2 */
++#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
++#endif
++
++#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
++
++/*
++ * make klips fail test:east-espiv-01.
++ * exploit is at testing/attacks/espiv
++ *
++ */
++#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
++
++
++/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
++#ifndef IP_FRAGMENT_LINEARIZE
++# define IP_FRAGMENT_LINEARIZE 0
++#endif /* IP_FRAGMENT_LINEARIZE */
++#endif /* __KERNEL__ */
++
++#define _IPSEC_PARAM_H_
++#endif /* _IPSEC_PARAM_H_ */
++
++/*
++ * $Log: ipsec_param.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.29  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.28  2004/02/16 04:38:32  mcr
++ * 	introduced new KLIPS_WRITE() function which is unconditional,
++ * 	and KLIPS_PRINTIF() which just does the condition.
++ *
++ * Revision 1.27  2003/12/15 20:38:07  mcr
++ * 	make sure that IPIP is always on.
++ *
++ * Revision 1.26  2003/12/15 15:42:24  mcr
++ * 	make sure that ESP is always on, and AH is no more.
++ *
++ * Revision 1.25  2003/12/11 20:14:58  mcr
++ * 	refactored the xmit code, to move all encapsulation
++ * 	code into protocol functions. Note that all functions
++ * 	are essentially done by a single function, which is probably
++ * 	wrong.
++ * 	the rcv_functions structures are renamed xform_functions.
++ *
++ * Revision 1.24  2003/12/04 19:05:26  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.23  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.21  2003/04/03 17:38:18  rgb
++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
++ * Change indentation for readability.
++ *
++ * Revision 1.20  2003/03/14 08:09:26  rgb
++ * Fixed up CONFIG_IPSEC_DYNDEV definitions.
++ *
++ * Revision 1.19  2003/01/30 02:31:43  rgb
++ *
++ * Rename SAref table macro names for clarity.
++ *
++ * Revision 1.18  2002/09/30 19:06:26  rgb
++ * 	Reduce default table to 16 bits width.
++ *
++ * Revision 1.17  2002/09/20 15:40:29  rgb
++ * Define switch to activate new SAref code.
++ * Prefix macros with "IPSEC_".
++ * Rework saref freelist.
++ * Restrict some bits to kernel context for use to klips utils.
++ *
++ * Revision 1.16  2002/09/20 05:00:31  rgb
++ * Define switch to divulge hmac keys for debugging.
++ * Added IPOPTIONS switch.
++ *
++ * Revision 1.15  2002/09/19 02:34:24  mcr
++ * 	define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
++ * 	to decide if we are to create /proc/net/ipsec/.
++ *
++ * Revision 1.14  2002/08/30 01:20:54  mcr
++ * 	reorganized 2.0/2.2/2.4 procfs support macro so match
++ * 	2.4 values/typedefs.
++ *
++ * Revision 1.13  2002/07/28 22:03:28  mcr
++ * 	added some documentation to SA_REF_*
++ * 	turned on fix for ESPIV attack, now that we have the attack code.
++ *
++ * Revision 1.12  2002/07/26 08:48:31  rgb
++ * Added SA ref table code.
++ *
++ * Revision 1.11  2002/07/23 02:57:45  rgb
++ * Define ARPHRD_VOID for < 2.4 kernels.
++ *
++ * Revision 1.10  2002/05/27 21:37:28  rgb
++ * Set the defaults sanely for those adventurous enough to try more than 1
++ * digit of ipsec devices.
++ *
++ * Revision 1.9  2002/05/27 18:56:07  rgb
++ * Convert to dynamic ipsec device allocation.
++ *
++ * Revision 1.8  2002/04/24 07:36:47  mcr
++ * Moved from ./klips/net/ipsec/ipsec_param.h,v
++ *
++ * Revision 1.7  2002/04/20 00:12:25  rgb
++ * Added esp IV CBC attack fix, disabled.
++ *
++ * 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 --git a/include/freeswan/ipsec_policy.h b/include/freeswan/ipsec_policy.h
+new file mode 100644
+index 0000000..65edf4c
+--- /dev/null
++++ b/include/freeswan/ipsec_policy.h
+@@ -0,0 +1,216 @@
++#ifndef _IPSEC_POLICY_H
++/*
++ * policy interface file between pluto and applications
++ * Copyright (C) 2003              Michael Richardson <mcr at freeswan.org>
++ * 
++ * 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$
++ */
++#define	_IPSEC_POLICY_H 	/* seen it, no need to see it again */
++
++
++/*
++ * this file defines an interface between an application (or rather an
++ * application library) and a key/policy daemon. It provides for inquiries
++ * as to the current state of a connected socket, as well as for general
++ * questions.
++ *
++ * In general, the interface is defined as a series of functional interfaces,
++ * and the policy messages should be internal. However, because this is in
++ * fact an ABI between pieces of the system that may get compiled and revised
++ * seperately, this ABI must be public and revision controlled.
++ *
++ * It is expected that the daemon will always support previous versions.
++ */
++
++#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
++
++enum ipsec_policy_command {
++  IPSEC_CMD_QUERY_FD       = 1,
++  IPSEC_CMD_QUERY_HOSTPAIR = 2,
++  IPSEC_CMD_QUERY_DSTONLY  = 3,
++};
++
++struct ipsec_policy_msg_head {
++  u_int32_t ipm_version;
++  u_int32_t ipm_msg_len;  
++  u_int32_t ipm_msg_type;
++  u_int32_t ipm_msg_seq;
++};
++
++enum ipsec_privacy_quality {
++  IPSEC_PRIVACY_NONE     = 0,
++  IPSEC_PRIVACY_INTEGRAL = 4,   /* not private at all. AH-like */
++  IPSEC_PRIVACY_UNKNOWN  = 8,   /* something is claimed, but details unavail */
++  IPSEC_PRIVACY_ROT13    = 12,  /* trivially breakable, i.e. 1DES */
++  IPSEC_PRIVACY_GAK      = 16,  /* known eavesdroppers */
++  IPSEC_PRIVACY_PRIVATE  = 32,  /* secure for at least a decade */
++  IPSEC_PRIVACY_STRONG   = 64,  /* ridiculously secure */
++  IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
++  IPSEC_PRIVACY_OTP      = 224, /* some kind of *true* one time pad */
++};
++
++enum ipsec_bandwidth_quality {
++  IPSEC_QOS_UNKNOWN = 0,       /* unknown bandwidth */
++  IPSEC_QOS_INTERACTIVE = 16,  /* reasonably moderate jitter, moderate fast.
++				  Good enough for telnet/ssh. */
++  IPSEC_QOS_VOIP        = 32,  /* faster crypto, predicable jitter */
++  IPSEC_QOS_FTP         = 64,  /* higher throughput crypto, perhaps hardware
++				  offloaded, but latency/jitter may be bad */
++  IPSEC_QOS_WIRESPEED   = 128, /* expect to be able to fill your pipe */
++};
++
++/* moved from programs/pluto/constants.h */
++/* IPsec AH transform values
++ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
++ * and in http://www.iana.org/assignments/isakmp-registry
++ */
++enum ipsec_authentication_algo {
++  AH_MD5=2,
++  AH_SHA=3,
++  AH_DES=4,
++  AH_SHA2_256=5,
++  AH_SHA2_384=6,
++  AH_SHA2_512=7
++};
++
++/* IPsec ESP transform values
++ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
++ * and from http://www.iana.org/assignments/isakmp-registry
++ */
++
++enum ipsec_cipher_algo {
++  ESP_reserved=0,
++  ESP_DES_IV64=1,
++  ESP_DES=2,
++  ESP_3DES=3,
++  ESP_RC5=4,
++  ESP_IDEA=5,
++  ESP_CAST=6,
++  ESP_BLOWFISH=7,
++  ESP_3IDEA=8,
++  ESP_DES_IV32=9,
++  ESP_RC4=10,
++  ESP_NULL=11,
++  ESP_AES=12,
++};
++
++/* IPCOMP transform values
++ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
++ */
++
++enum ipsec_comp_algo {
++  IPCOMP_OUI=               1,
++  IPCOMP_DEFLATE=           2,
++  IPCOMP_LZS=               3,
++  IPCOMP_V42BIS=            4
++};
++
++/* Identification type values
++ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1 
++ */
++
++enum ipsec_id_type {
++  ID_IMPOSSIBLE=             (-2),	/* private to Pluto */
++  ID_MYID=                   (-1),	/* private to Pluto */
++  ID_NONE=                     0,	/* private to Pluto */
++  ID_IPV4_ADDR=                1,
++  ID_FQDN=                     2,
++  ID_USER_FQDN=                3,
++  ID_IPV4_ADDR_SUBNET=         4,
++  ID_IPV6_ADDR=                5,
++  ID_IPV6_ADDR_SUBNET=         6,
++  ID_IPV4_ADDR_RANGE=          7,
++  ID_IPV6_ADDR_RANGE=          8,
++  ID_DER_ASN1_DN=              9,
++  ID_DER_ASN1_GN=              10,
++  ID_KEY_ID=                   11
++};
++
++/* Certificate type values
++ * RFC 2408 ISAKMP, chapter 3.9
++ */
++enum ipsec_cert_type {
++  CERT_NONE=			0,  
++  CERT_PKCS7_WRAPPED_X509=	1,  /* self-signed certificate from disk */
++  CERT_PGP=			2,
++  CERT_DNS_SIGNED_KEY=		3,  /* KEY RR from DNS */
++  CERT_X509_SIGNATURE=		4,
++  CERT_X509_KEY_EXCHANGE=	5,
++  CERT_KERBEROS_TOKENS=		6,
++  CERT_CRL=			7,
++  CERT_ARL=			8,
++  CERT_SPKI=			9,
++  CERT_X509_ATTRIBUTE=		10,
++  CERT_RAW_RSA=                 11, /* raw RSA from config file */ 
++};
++
++/* a SIG record in ASCII */
++struct ipsec_dns_sig {
++  char fqdn[256];
++  char dns_sig[768];     /* empty string if not signed */
++};
++
++struct ipsec_raw_key {
++  char id_name[256];
++  char fs_keyid[8];
++};
++
++struct ipsec_identity {
++  enum ipsec_id_type     ii_type;
++  enum ipsec_cert_type   ii_format;
++  union {
++    struct ipsec_dns_sig ipsec_dns_signed;
++    /* some thing for PGP */
++    /* some thing for PKIX */
++    struct ipsec_raw_key ipsec_raw_key;
++  } ii_credential;
++};
++
++#define IPSEC_MAX_CREDENTIALS 32
++
++struct ipsec_policy_cmd_query {
++  struct ipsec_policy_msg_head head;
++
++  /* Query section */
++  ip_address query_local;     /* us   */
++  ip_address query_remote;    /* them */
++  u_short src_port, dst_port;
++
++  /* Answer section */
++  enum ipsec_privacy_quality     strength;
++  enum ipsec_bandwidth_quality   bandwidth;
++  enum ipsec_authentication_algo auth_detail;  
++  enum ipsec_cipher_algo         esp_detail;
++  enum ipsec_comp_algo           comp_detail;
++
++  int                            credential_count;
++
++  struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
++};
++
++#define IPSEC_POLICY_SOCKET "/var/run/pluto.info"
++
++/* prototypes */
++extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
++extern err_t ipsec_policy_init(void);
++extern err_t ipsec_policy_final(void);
++extern err_t ipsec_policy_readmsg(int policysock,
++				  unsigned char *buf, size_t buflen);
++extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
++extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
++
++
++extern const char *ipsec_policy_version_code(void);
++extern const char *ipsec_policy_version_string(void);
++
++#endif /* _IPSEC_POLICY_H */
+diff --git a/include/freeswan/ipsec_proto.h b/include/freeswan/ipsec_proto.h
+new file mode 100644
+index 0000000..1a755b0
+--- /dev/null
++++ b/include/freeswan/ipsec_proto.h
+@@ -0,0 +1,157 @@
++/*
++ * @(#) prototypes for FreeSWAN functions 
++ *
++ * Copyright (C) 2001  Richard Guy Briggs  <rgb at freeswan.org>
++ *                 and Michael Richardson  <mcr at 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$
++ *
++ */
++
++#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_init.c */
++extern struct prng ipsec_prng;
++
++/* 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(ip_said *);
++extern int ipsec_sa_put(struct ipsec_sa *);
++extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
++extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
++extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
++
++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,
++			   ip_said 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_KLIPS_DEBUG
++
++extern int debug_xform;
++extern int debug_eroute;
++extern int debug_spi;
++
++#endif /* CONFIG_KLIPS_DEBUG */
++
++
++
++
++#define _IPSEC_PROTO_H
++#endif /* _IPSEC_PROTO_H_ */
++
++/*
++ * $Log: ipsec_proto.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.10  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.9  2003/12/04 19:05:26  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.8  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.6  2002/05/23 07:13:48  rgb
++ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
++ *
++ * Revision 1.5  2002/05/14 02:36:40  rgb
++ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
++ * with "put" usage in the kernel.
++ *
++ * Revision 1.4  2002/04/24 07:36:47  mcr
++ * Moved from ./klips/net/ipsec/ipsec_proto.h,v
++ *
++ * Revision 1.3  2002/04/20 00:12:25  rgb
++ * Added esp IV CBC attack fix, disabled.
++ *
++ * 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 --git a/include/freeswan/ipsec_radij.h b/include/freeswan/ipsec_radij.h
+new file mode 100644
+index 0000000..81fc8ce
+--- /dev/null
++++ b/include/freeswan/ipsec_radij.h
+@@ -0,0 +1,181 @@
++/*
++ * @(#) 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$
++ */
++
++#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 *);
++
++/* This structure is used to pass information between
++ * ipsec_eroute_get_info and ipsec_rj_walker_procprint
++ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
++ */
++struct wsbuf
++{
++	/* from caller of ipsec_eroute_get_info: */
++	char *const buffer;	/* start of buffer provided */
++	const int length;	/* length of buffer provided */
++	const off_t offset;	/* file position of first character of interest */
++	/* accumulated by ipsec_rj_walker_procprint: */
++	int len;	/* number of character filled into buffer */
++	off_t begin;	/* file position contained in buffer[0] (<=offset) */
++};
++
++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_KLIPS_DEBUG
++extern int debug_radij;
++void rj_dumptrees(void);
++
++#define DB_RJ_DUMPTREES	0x0001
++#define DB_RJ_FINDROUTE 0x0002
++#endif /* CONFIG_KLIPS_DEBUG */
++
++#define _IPSEC_RADIJ_H
++#endif
++
++/*
++ * $Log: ipsec_radij.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.20  2004/04/12 17:39:05  dhr
++ *
++ * simplify and clarify struct wsbuf (used in generating /proc/net/ipsec_eroute)
++ *
++ * Revision 1.19  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.18  2002/04/24 07:36:47  mcr
++ * Moved from ./klips/net/ipsec/ipsec_radij.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_rcv.h b/include/freeswan/ipsec_rcv.h
+new file mode 100644
+index 0000000..adef14e
+--- /dev/null
++++ b/include/freeswan/ipsec_rcv.h
+@@ -0,0 +1,285 @@
++/*
++ * 
++ * 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$
++ */
++
++#ifndef IPSEC_RCV_H
++#define IPSEC_RCV_H
++
++#include "freeswan/ipsec_auth.h"
++
++#define DB_RX_PKTRX	0x0001
++#define DB_RX_PKTRX2	0x0002
++#define DB_RX_DMP	0x0004
++#define DB_RX_IPSA	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>
++
++#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
++
++struct ipsec_birth_reply {
++  int            packet_template_len;
++  unsigned char  packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
++};
++
++extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
++extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
++
++enum ipsec_rcv_value {
++	IPSEC_RCV_LASTPROTO=1,
++	IPSEC_RCV_OK=0,
++	IPSEC_RCV_BADPROTO=-1,
++	IPSEC_RCV_BADLEN=-2,
++	IPSEC_RCV_ESP_BADALG=-3,
++	IPSEC_RCV_3DES_BADBLOCKING=-4,
++	IPSEC_RCV_ESP_DECAPFAIL=-5,
++	IPSEC_RCV_DECAPFAIL=-6,
++	IPSEC_RCV_SAIDNOTFOUND=-7,
++	IPSEC_RCV_IPCOMPALONE=-8,
++	IPSEC_RCV_IPCOMPFAILED=-10,
++	IPSEC_RCV_SAIDNOTLIVE=-11,
++	IPSEC_RCV_FAILEDINBOUND=-12,
++	IPSEC_RCV_LIFETIMEFAILED=-13,
++	IPSEC_RCV_BADAUTH=-14,
++	IPSEC_RCV_REPLAYFAILED=-15,
++	IPSEC_RCV_AUTHFAILED=-16,
++	IPSEC_RCV_REPLAYROLLED=-17
++};
++
++struct ipsec_rcv_state {
++	struct sk_buff *skb;
++	struct net_device_stats *stats;
++	struct iphdr *ipp;
++	struct ipsec_sa *ipsp;
++	int len;
++	int ilen;
++	int authlen;
++	int hard_header_len;
++	int iphlen;
++	struct auth_alg *authfuncs;
++	ip_said said;
++	char   sa[SATOT_BUF];
++	size_t sa_len;
++	__u8 next_header;
++	__u8 hash[AH_AMAX];
++	char ipsaddr_txt[ADDRTOA_BUF];
++	char ipdaddr_txt[ADDRTOA_BUF];
++	__u8 *octx;
++	__u8 *ictx;
++	int ictx_len;
++	int octx_len;
++	union {
++		struct {
++			struct esphdr *espp;
++		} espstuff;
++		struct {
++			struct ahhdr *ahp;
++		} ahstuff;
++		struct {
++			struct ipcomphdr *compp;
++		} ipcompstuff;
++	} protostuff;
++};
++
++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 net_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_KLIPS_DEBUG
++extern int debug_rcv;
++#endif /* CONFIG_KLIPS_DEBUG */
++#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z)
++
++extern int sysctl_ipsec_inbound_policy_check;
++#endif /* __KERNEL__ */
++
++#endif /* IPSEC_RCV_H */
++
++/*
++ * $Log: ipsec_rcv.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:50  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.21  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.20  2004/02/22 06:49:15  mcr
++ * 	kernel 2.6 port - merged with 2.4 code.
++ *
++ * Revision 1.19.6.1  2004/02/20 14:09:55  mcr
++ * 	moved code to net/ipsec/ to make 2.6 happy.
++ *
++ * Revision 1.19  2003/12/11 20:14:58  mcr
++ * 	refactored the xmit code, to move all encapsulation
++ * 	code into protocol functions. Note that all functions
++ * 	are essentially done by a single function, which is probably
++ * 	wrong.
++ * 	the rcv_functions structures are renamed xform_functions.
++ *
++ * Revision 1.18  2003/12/06 21:21:19  mcr
++ * 	split up receive path into per-transform files, for
++ * 	easier later removal.
++ *
++ * Revision 1.17  2002/09/03 16:32:32  mcr
++ * 	definitions of ipsec_birth_reply.
++ *
++ * Revision 1.16  2002/05/14 02:36:00  rgb
++ * Change references to _TDB to _IPSA.
++ *
++ * Revision 1.15  2002/04/24 07:36:47  mcr
++ * Moved from ./klips/net/ipsec/ipsec_rcv.h,v
++ *
++ * 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 at 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 --git a/include/freeswan/ipsec_sa.h b/include/freeswan/ipsec_sa.h
+new file mode 100644
+index 0000000..eeddca2
+--- /dev/null
++++ b/include/freeswan/ipsec_sa.h
+@@ -0,0 +1,334 @@
++/*
++ * @(#) Definitions of IPsec Security Association (ipsec_sa)
++ *
++ * Copyright (C) 2001, 2002, 2003
++ *                      Richard Guy Briggs  <rgb at freeswan.org>
++ *                  and Michael Richardson  <mcr at 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$
++ *
++ * 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_
++
++#ifdef __KERNEL__
++#include "ipsec_stats.h"
++#include "ipsec_life.h"
++#include "ipsec_eroute.h"
++#endif /* __KERNEL__ */
++#include "ipsec_param.h"
++
++
++/* SAs are held in a table.
++ * Entries in this table are referenced by IPsecSAref_t values.
++ * IPsecSAref_t values are conceptually subscripts.  Because
++ * we want to allocate the table piece-meal, the subscripting
++ * is implemented with two levels, a bit like paged virtual memory.
++ * This representation mechanism is known as an Iliffe Vector.
++ *
++ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
++ * pointers to subtables.
++ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
++ * is a pointer to an SA.
++ *
++ * An IPsecSAref_t contains either an exceptional value (signified by the
++ * high-order bit being on) or a reference to a table entry.  A table entry
++ * reference has the subtable subscript in the low-order
++ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
++ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
++ *
++ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
++ * IPsecSAref2table(x).  It is of type struct IPsecSArefSubTable *.
++ *
++ * The pointer to the SA for x is IPsecSAref2SA(x).  It is of type
++ * struct ipsec_sa*.  The macro definition clearly shows the two-level
++ * access needed to find the SA pointer.
++ *
++ * The Maintable is allocated when IPsec is initialized.
++ * Each subtable is allocated when needed, but the first is allocated
++ * when IPsec is initialized.
++ *
++ * IPsecSAref_t is designed to be smaller than an NFmark so that
++ * they can be stored in NFmarks and still leave a few bits for other
++ * purposes.  The spare bits are in the low order of the NFmark
++ * but in the high order of the IPsecSAref_t, so conversion is required.
++ * We pick the upper bits of NFmark on the theory that they are less likely to
++ * interfere with more pedestrian uses of nfmark.
++ */
++
++
++typedef unsigned short int IPsecRefTableUnusedCount;
++
++#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
++
++#ifdef __KERNEL__
++#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
++#error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")"
++#endif
++
++#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
++
++#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
++#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
++
++#ifdef CONFIG_NETFILTER
++#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
++#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
++#else /* CONFIG_NETFILTER */
++/* just make it work for now, it doesn't matter, since there is no nfmark */
++#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
++#endif /* CONFIG_NETFILTER */
++#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
++#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
++
++#define IPSEC_SA_REF_MASK        (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
++#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
++#define IPSEC_SA_REF_ENTRY_MASK  (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
++
++#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
++#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
++#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
++
++#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
++#define IPsecSA2SAref(x) ((x)->ips_ref)
++
++#define EMT_INBOUND	0x01	/* SA direction, 1=inbound */
++
++/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
++struct ipsec_sa 	                        
++{
++	IPsecSAref_t	ips_ref;		/* reference table entry number */
++	atomic_t	ips_refcount;		/* reference 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 */
++
++	ip_said	        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 */
++        __u8            ips_transport_protocol; /* protocol for this SA, if ports are involved */
++	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 */
++
++//++++ Stanley add for cyrpto and auth engin 2004.11.24
++	__u8		alpha_ips_key_a[20];		/* authentication key */
++	__u8		alpha_ips_key_e[24];		/* encryption key */
++//---- Stanley
++
++	struct ident	ips_ident_s;		/* identity src */
++	struct ident	ips_ident_d;		/* identity dst */
++
++#ifdef CONFIG_KLIPS_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_KLIPS_IPCOMP */
++
++#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
++	IPsecSAref_t	ips_ref_rel;
++};
++
++struct IPsecSArefSubTable
++{
++	struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
++};
++
++struct ipsec_sadb {
++	struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
++	IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
++	int refFreeListHead;
++	int refFreeListTail;
++	IPsecSAref_t refFreeListCont;
++	IPsecSAref_t said_hash[SADB_HASHMOD];
++	spinlock_t sadb_lock;
++};
++
++extern struct ipsec_sadb ipsec_sadb;
++
++extern int ipsec_SAref_recycle(void);
++extern int ipsec_SArefSubTable_alloc(unsigned table);
++extern int ipsec_saref_freelist_init(void);
++extern int ipsec_sadb_init(void);
++extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
++extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
++extern int ipsec_sa_free(struct ipsec_sa* ips);
++extern int ipsec_sa_put(struct ipsec_sa *ips);
++extern int ipsec_sa_add(struct ipsec_sa *ips);
++extern int ipsec_sa_del(struct ipsec_sa *ips);
++extern int ipsec_sa_delchain(struct ipsec_sa *ips);
++extern int ipsec_sadb_cleanup(__u8 proto);
++extern int ipsec_sadb_free(void);
++extern int ipsec_sa_wipe(struct ipsec_sa *ips);
++#endif /* __KERNEL__ */
++
++enum ipsec_direction {
++	ipsec_incoming = 1,
++	ipsec_outgoing = 2
++};
++
++#define _IPSEC_SA_H_
++#endif /* _IPSEC_SA_H_ */
++
++/*
++ * $Log: ipsec_sa.h,v $
++ * Revision 1.2  2004/11/25 13:32:30  r05549
++ * *** empty log message ***
++ *
++ * Revision 1.1.1.1  2004/08/20 11:33:51  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.19  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.18  2003/12/04 19:05:26  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.17  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.15  2003/05/11 00:53:09  mcr
++ * 	IPsecSAref_t and macros were moved to freeswan.h.
++ *
++ * Revision 1.14  2003/02/12 19:31:55  rgb
++ * Fixed bug in "file seen" machinery.
++ * Updated copyright year.
++ *
++ * Revision 1.13  2003/01/30 02:31:52  rgb
++ *
++ * Re-wrote comments describing SAref system for accuracy.
++ * Rename SAref table macro names for clarity.
++ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
++ * Transmit error code through to caller from callee for better diagnosis of problems.
++ * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
++ *
++ * Revision 1.12  2002/10/07 18:31:19  rgb
++ * Change comment to reflect the flexible nature of the main and sub-table widths.
++ * Added a counter for the number of unused entries in each subtable.
++ * Further break up host field type macro to host field.
++ * Move field width sanity checks to ipsec_sa.c
++ * Define a mask for an entire saref.
++ *
++ * Revision 1.11  2002/09/20 15:40:33  rgb
++ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
++ * Fixed SAref/nfmark macros.
++ * Rework saref freeslist.
++ * Place all ipsec sadb globals into one struct.
++ * Restrict some bits to kernel context for use to klips utils.
++ *
++ * Revision 1.10  2002/09/20 05:00:34  rgb
++ * Update copyright date.
++ *
++ * Revision 1.9  2002/09/17 17:19:29  mcr
++ * 	make it compile even if there is no netfilter - we lost
++ * 	functionality, but it works, especially on 2.2.
++ *
++ * Revision 1.8  2002/07/28 22:59:53  mcr
++ * 	clarified/expanded one comment.
++ *
++ * Revision 1.7  2002/07/26 08:48:31  rgb
++ * Added SA ref table code.
++ *
++ * Revision 1.6  2002/05/31 17:27:48  rgb
++ * Comment fix.
++ *
++ * Revision 1.5  2002/05/27 18:55:03  rgb
++ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
++ *
++ * Revision 1.4  2002/05/23 07:13:36  rgb
++ * Convert "usecount" to "refcount" to remove ambiguity.
++ *
++ * Revision 1.3  2002/04/24 07:36:47  mcr
++ * Moved from ./klips/net/ipsec/ipsec_sa.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_sha1.h b/include/freeswan/ipsec_sha1.h
+new file mode 100644
+index 0000000..0ec0695
+--- /dev/null
++++ b/include/freeswan/ipsec_sha1.h
+@@ -0,0 +1,82 @@
++/*
++ * RCSID $Id$
++ */
++
++/*
++ * Here is the original comment from the distribution:
++
++SHA-1 in C
++By Steve Reid <steve at 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(void *context);
++void SHA1Update(void *context, unsigned char *data, __u32 len);
++void SHA1Final(unsigned char digest[20], void *context);
++
++ 
++#endif /* _IPSEC_SHA1_H_ */
++
++/*
++ * $Log: ipsec_sha1.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:51  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.7  2002/09/10 01:45:09  mcr
++ * 	changed type of MD5_CTX and SHA1_CTX to void * so that
++ * 	the function prototypes would match, and could be placed
++ * 	into a pointer to a function.
++ *
++ * Revision 1.6  2002/04/24 07:36:47  mcr
++ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_stats.h b/include/freeswan/ipsec_stats.h
+new file mode 100644
+index 0000000..327c895
+--- /dev/null
++++ b/include/freeswan/ipsec_stats.h
+@@ -0,0 +1,66 @@
++/*
++ * @(#) definition of ipsec_stats structure
++ *
++ * Copyright (C) 2001  Richard Guy Briggs  <rgb at freeswan.org>
++ *                 and Michael Richardson  <mcr at 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$
++ *
++ */
++
++/* 
++ * 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 */
++};
++
++extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
++
++#define _IPSEC_STATS_H_
++#endif /* _IPSEC_STATS_H_ */
++
++/*
++ * $Log: ipsec_stats.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:51  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.4  2004/03/24 01:58:31  mcr
++ * 	sprintf->snprintf for formatting into proc buffer.
++ *
++ * Revision 1.3  2002/04/24 07:36:47  mcr
++ * Moved from ./klips/net/ipsec/ipsec_stats.h,v
++ *
++ * 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 --git a/include/freeswan/ipsec_tunnel.h b/include/freeswan/ipsec_tunnel.h
+new file mode 100644
+index 0000000..257178e
+--- /dev/null
++++ b/include/freeswan/ipsec_tunnel.h
+@@ -0,0 +1,283 @@
++/*
++ * IPSEC tunneling code
++ * Copyright (C) 1996, 1997  John Ioannidis.
++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  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$
++ */
++
++
++#ifdef NET_21
++# define DEV_QUEUE_XMIT(skb, device, pri) {\
++	skb->dev = device; \
++	neigh_compat_output(skb); \
++	/* skb->dst->output(skb); */ \
++ }
++# define ICMP_SEND(skb_in, type, code, info, dev) \
++	icmp_send(skb_in, type, code, htonl(info))
++# define IP_SEND(skb, dev) \
++	ip_send(skb);
++#else /* NET_21 */
++# define DEV_QUEUE_XMIT(skb, device, pri) {\
++	dev_queue_xmit(skb, device, pri); \
++ }
++# define ICMP_SEND(skb_in, type, code, info, dev) \
++	icmp_send(skb_in, type, code, info, dev)
++# define IP_SEND(skb, dev) \
++	if(ntohs(iph->tot_len) > physmtu) { \
++		ip_fragment(NULL, skb, dev, 0); \
++		ipsec_kfree_skb(skb); \
++	} else { \
++		dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
++	}
++#endif /* NET_21 */
++
++
++/*
++ * Heavily based on drivers/net/new_tunnel.c.  Lots
++ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
++ */
++
++struct ipsectunnelconf
++{
++	__u32	cf_cmd;
++	union
++	{
++		char 	cfu_name[12];
++	} cf_u;
++#define cf_name cf_u.cfu_name
++};
++
++#define IPSEC_SET_DEV	(SIOCDEVPRIVATE)
++#define IPSEC_DEL_DEV	(SIOCDEVPRIVATE + 1)
++#define IPSEC_CLR_DEV	(SIOCDEVPRIVATE + 2)
++
++#ifdef __KERNEL__
++#include <linux/version.h>
++#ifndef KERNEL_VERSION
++#  define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
++#endif
++struct ipsecpriv
++{
++	struct sk_buff_head sendq;
++	struct net_device *dev;
++	struct wait_queue *wait_queue;
++	char locked;
++	int  (*hard_start_xmit) (struct sk_buff *skb,
++		struct net_device *dev);
++	int  (*hard_header) (struct sk_buff *skb,
++		struct net_device *dev,
++		unsigned short type,
++		void *daddr,
++		void *saddr,
++		unsigned len);
++#ifdef NET_21
++	int  (*rebuild_header)(struct sk_buff *skb);
++#else /* NET_21 */
++	int  (*rebuild_header)(void *buff, struct net_device *dev,
++			unsigned long raddr, struct sk_buff *skb);
++#endif /* NET_21 */
++	int  (*set_mac_address)(struct net_device *dev, void *addr);
++#ifndef NET_21
++	void (*header_cache_bind)(struct hh_cache **hhp
++				  , struct net_device *dev
++				  , unsigned short htype
++				  , __u32 daddr);
++#endif /* !NET_21 */
++	void (*header_cache_update)(struct hh_cache *hh
++				    , struct net_device *dev
++				    , unsigned char *  haddr);
++	struct net_device_stats *(*get_stats)(struct net_device *dev);
++	struct net_device_stats mystats;
++	int mtu;	/* What is the desired MTU? */
++};
++
++extern char ipsec_tunnel_c_version[];
++
++extern struct net_device *ipsecdevices[IPSEC_NUM_IF];
++
++int ipsec_tunnel_init_devices(void);
++
++/* void */ int ipsec_tunnel_cleanup_devices(void);
++
++extern /* void */ int ipsec_init(void);
++
++extern int ipsec_tunnel_start_xmit(struct sk_buff *skb
++				   , struct net_device *dev);
++
++#ifdef CONFIG_KLIPS_DEBUG
++extern int debug_tunnel;
++extern int sysctl_ipsec_debug_verbose;
++#endif /* CONFIG_KLIPS_DEBUG */
++#endif /* __KERNEL__ */
++
++#ifdef CONFIG_KLIPS_DEBUG
++#define DB_TN_INIT	0x0001
++#define DB_TN_PROCFS	0x0002
++#define DB_TN_XMIT	0x0010
++#define DB_TN_OHDR	0x0020
++#define DB_TN_CROUT	0x0040
++#define DB_TN_OXFS	0x0080
++#define DB_TN_REVEC	0x0100
++#endif /* CONFIG_KLIPS_DEBUG */
++
++/*
++ * $Log: ipsec_tunnel.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:51  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.30  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.29  2004/02/22 06:49:15  mcr
++ * 	kernel 2.6 port - merged with 2.4 code.
++ *
++ * Revision 1.28.10.1  2004/02/20 14:09:55  mcr
++ * 	moved code to net/ipsec/ to make 2.6 happy.
++ *
++ * Revision 1.28  2003/06/24 20:22:32  mcr
++ * 	added new global: ipsecdevices[] so that we can keep track of
++ * 	the ipsecX devices. They will be referenced with dev_hold(),
++ * 	so 2.2 may need this as well.
++ *
++ * Revision 1.27  2003/04/03 17:38:09  rgb
++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
++ *
++ * Revision 1.26  2003/02/12 19:32:20  rgb
++ * Updated copyright year.
++ *
++ * Revision 1.25  2002/05/27 18:56:07  rgb
++ * Convert to dynamic ipsec device allocation.
++ *
++ * Revision 1.24  2002/04/24 07:36:48  mcr
++ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
++ *
++ * Revision 1.23  2001/11/06 19:50:44  rgb
++ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
++ * use also by pfkey_v2_parser.c
++ *
++ * Revision 1.22  2001/09/15 16:24:05  rgb
++ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
++ *
++ * Revision 1.21  2001/06/14 19:35:10  rgb
++ * Update copyright date.
++ *
++ * Revision 1.20  2000/09/15 11:37:02  rgb
++ * Merge in heavily modified Svenning Soerensen's <svenning at post5.tele.dk>
++ * IPCOMP zlib deflate code.
++ *
++ * Revision 1.19  2000/09/08 19:12:56  rgb
++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
++ *
++ * Revision 1.18  2000/07/28 13:50:54  rgb
++ * Changed enet_statistics to net_device_stats and added back compatibility
++ * for pre-2.1.19.
++ *
++ * Revision 1.17  1999/11/19 01:12:15  rgb
++ * Purge unneeded proc_info prototypes, now that static linking uses
++ * dynamic proc_info registration.
++ *
++ * Revision 1.16  1999/11/18 18:51:00  rgb
++ * Changed all device registrations for static linking to
++ * dynamic to reduce the number and size of patches.
++ *
++ * Revision 1.15  1999/11/18 04:14:21  rgb
++ * Replaced all kernel version macros to shorter, readable form.
++ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
++ * Added Marc Boucher's 2.3.25 proc patches.
++ *
++ * Revision 1.14  1999/05/25 02:50:10  rgb
++ * Fix kernel version macros for 2.0.x static linking.
++ *
++ * Revision 1.13  1999/05/25 02:41:06  rgb
++ * Add ipsec_klipsdebug support for static linking.
++ *
++ * Revision 1.12  1999/05/05 22:02:32  rgb
++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc at mbsi.ca>.
++ *
++ * Revision 1.11  1999/04/29 15:19:50  rgb
++ * Add return values to init and cleanup functions.
++ *
++ * Revision 1.10  1999/04/16 16:02:39  rgb
++ * Bump up macro to 4 ipsec I/Fs.
++ *
++ * Revision 1.9  1999/04/15 15:37:25  rgb
++ * Forward check changes from POST1_00 branch.
++ *
++ * Revision 1.5.2.1  1999/04/02 04:26:14  rgb
++ * Backcheck from HEAD, pre1.0.
++ *
++ * Revision 1.8  1999/04/11 00:29:01  henry
++ * GPL boilerplate
++ *
++ * Revision 1.7  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.6  1999/03/31 05:44:48  rgb
++ * Keep PMTU reduction private.
++ *
++ * Revision 1.5  1999/02/10 22:31:20  rgb
++ * Change rebuild_header member to reflect generality of link layer.
++ *
++ * Revision 1.4  1998/12/01 13:22:04  rgb
++ * Added support for debug printing of version info.
++ *
++ * Revision 1.3  1998/07/29 20:42:46  rgb
++ * Add a macro for clearing all tunnel devices.
++ * Rearrange structures and declarations for sharing with userspace.
++ *
++ * Revision 1.2  1998/06/25 20:01:45  rgb
++ * Make prototypes available for ipsec_init and ipsec proc_dir_entries
++ * for static linking.
++ *
++ * 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.3  1998/05/18 21:51:50  rgb
++ * Added macros for num of I/F's and a procfs debug switch.
++ *
++ * 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:13  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.5  1997/06/03 04:24:48  ji
++ * Added transport mode.
++ * Changed the way routing is done.
++ * Lots of bug fixes.
++ *
++ * 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 --git a/include/freeswan/ipsec_xform.h b/include/freeswan/ipsec_xform.h
+new file mode 100644
+index 0000000..85a82fd
+--- /dev/null
++++ b/include/freeswan/ipsec_xform.h
+@@ -0,0 +1,330 @@
++/*
++ * Definitions relevant to IPSEC transformations
++ * 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$
++ */
++
++#ifndef _IPSEC_XFORM_H_
++
++#include <freeswan.h>
++
++#define XF_NONE			0	/* No transform set */
++#define XF_IP4			1	/* IPv4 inside IPv4 */
++#define XF_AHMD5		2	/* AH MD5 */
++#define XF_AHSHA		3	/* AH SHA */
++#define XF_ESP3DES		5	/* ESP DES3-CBC */
++#define XF_AHHMACMD5		6	/* AH-HMAC-MD5 with opt replay prot */
++#define XF_AHHMACSHA1		7	/* AH-HMAC-SHA1 with opt replay prot */
++#define XF_ESP3DESMD5		9	/* triple DES, HMAC-MD-5, 128-bits of authentication */
++#define	XF_ESP3DESMD596		10	/* triple DES, HMAC-MD-5, 96-bits of authentication */
++#define	XF_ESPNULLMD596		12	/* NULL, HMAC-MD-5 with 96-bits of authentication */
++#define	XF_ESPNULLSHA196	13	/* NULL, HMAC-SHA-1 with 96-bits of authentication */
++#define	XF_ESP3DESSHA196	14	/* triple DES, HMAC-SHA-1, 96-bits of authentication */
++#define XF_IP6			15	/* IPv6 inside IPv6 */
++#define XF_COMPDEFLATE		16	/* IPCOMP deflate */
++
++#define XF_CLR			126	/* Clear SA table */
++#define XF_DEL			127	/* Delete SA */
++
++/* IPsec AH transform values
++ * RFC 2407
++ * draft-ietf-ipsec-doi-tc-mib-02.txt
++ */
++
++#define AH_NONE			0
++#define AH_MD5			2
++#define AH_SHA			3
++
++/* IPsec ESP transform values */
++
++#define ESP_NONE		0
++#define ESP_3DES		3
++#define ESP_RC5			4
++#define ESP_IDEA		5
++#define ESP_CAST		6
++#define ESP_BLOWFISH		7
++#define ESP_3IDEA		8
++#define ESP_RC4			10
++#define ESP_NULL		11
++
++/* IPCOMP transform values */
++
++#define IPCOMP_NONE		0
++#define IPCOMP_OUI		1
++#define IPCOMP_DEFLAT		2
++#define IPCOMP_LZS		3
++#define IPCOMP_V42BIS		4
++
++#define XFT_AUTH		0x0001
++#define XFT_CONF		0x0100
++
++/* available if CONFIG_KLIPS_DEBUG is defined */
++#define DB_XF_INIT		0x0001
++
++#define PROTO2TXT(x) \
++	(x) == IPPROTO_AH ? "AH" : \
++	(x) == IPPROTO_ESP ? "ESP" : \
++	(x) == IPPROTO_IPIP ? "IPIP" : \
++	(x) == IPPROTO_COMP ? "COMP" : \
++	"UNKNOWN_proto"
++
++#define IPS_XFORM_NAME(x) \
++	PROTO2TXT((x)->ips_said.proto), \
++	(x)->ips_said.proto == IPPROTO_COMP ? \
++		((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
++		 "_DEFLATE" : "_UNKNOWN_comp") : \
++	(x)->ips_encalg == ESP_NONE ? "" : \
++	(x)->ips_encalg == ESP_3DES ? "_3DES" : \
++	"_UNKNOWN_encr", \
++	(x)->ips_authalg == AH_NONE ? "" : \
++	(x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
++	(x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
++	"_UNKNOWN_auth" \
++
++#ifdef __KERNEL__
++struct ipsec_rcv_state;
++struct ipsec_xmit_state;
++
++struct xform_functions {
++	enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
++				       struct sk_buff *skb);
++        enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
++
++	enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
++					   struct sk_buff *skb,
++					   __u32          *replay,
++					   unsigned char **authenticator);
++	enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
++					struct sk_buff *skb);
++
++  	enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
++        enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
++
++	enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
++					   struct sk_buff *skb,
++					   __u32          *replay,
++					   unsigned char **authenticator);
++	enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
++					struct sk_buff *skb);
++        int  xmit_headroom;
++	int  xmit_needtailroom;
++};
++
++#endif /* __KERNEL__ */
++
++#ifdef CONFIG_KLIPS_DEBUG
++extern void ipsec_dmp(char *s, caddr_t bb, int len);
++#else /* CONFIG_KLIPS_DEBUG */
++#define ipsec_dmp(_x, _y, _z) 
++#endif /* CONFIG_KLIPS_DEBUG */
++
++
++#define _IPSEC_XFORM_H_
++#endif /* _IPSEC_XFORM_H_ */
++
++/*
++ * $Log: ipsec_xform.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:51  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.38  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.37  2003/12/11 20:14:58  mcr
++ * 	refactored the xmit code, to move all encapsulation
++ * 	code into protocol functions. Note that all functions
++ * 	are essentially done by a single function, which is probably
++ * 	wrong.
++ * 	the rcv_functions structures are renamed xform_functions.
++ *
++ * Revision 1.36  2002/04/24 07:36:48  mcr
++ * Moved from ./klips/net/ipsec/ipsec_xform.h,v
++ *
++ * Revision 1.35  2001/11/26 09:23:51  rgb
++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
++ *
++ * Revision 1.33.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.
++ *
++ * Revision 1.34  2001/11/06 19:47:17  rgb
++ * Changed lifetime_packets to uint32 from uint64.
++ *
++ * Revision 1.33  2001/09/08 21:13:34  rgb
++ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
++ *
++ * Revision 1.32  2001/07/06 07:40:01  rgb
++ * Reformatted for readability.
++ * Added inbound policy checking fields for use with IPIP SAs.
++ *
++ * Revision 1.31  2001/06/14 19:35:11  rgb
++ * Update copyright date.
++ *
++ * Revision 1.30  2001/05/30 08:14:03  rgb
++ * Removed vestiges of esp-null transforms.
++ *
++ * Revision 1.29  2001/01/30 23:42:47  rgb
++ * Allow pfkey msgs from pid other than user context required for ACQUIRE
++ * and subsequent ADD or UDATE.
++ *
++ * Revision 1.28  2000/11/06 04:30:40  rgb
++ * Add Svenning's adaptive content compression.
++ *
++ * Revision 1.27  2000/09/19 00:38:25  rgb
++ * Fixed algorithm name bugs introduced for ipcomp.
++ *
++ * Revision 1.26  2000/09/17 21:36:48  rgb
++ * Added proto2txt macro.
++ *
++ * Revision 1.25  2000/09/17 18:56:47  rgb
++ * Added IPCOMP support.
++ *
++ * Revision 1.24  2000/09/12 19:34:12  rgb
++ * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
++ *
++ * Revision 1.23  2000/09/12 03:23:14  rgb
++ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
++ *
++ * Revision 1.22  2000/09/08 19:12:56  rgb
++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
++ *
++ * Revision 1.21  2000/09/01 18:32:43  rgb
++ * Added (disabled) sensitivity members to tdb struct.
++ *
++ * Revision 1.20  2000/08/30 05:31:01  rgb
++ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
++ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
++ *
++ * Revision 1.19  2000/08/01 14:51:52  rgb
++ * Removed _all_ remaining traces of DES.
++ *
++ * Revision 1.18  2000/01/21 06:17:45  rgb
++ * Tidied up spacing.
++ *
++ * Revision 1.17  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.16  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.15  1999/10/16 00:29:11  rgb
++ * Added SA lifetime packet counting variables.
++ *
++ * Revision 1.14  1999/10/01 00:04:14  rgb
++ * Added tdb structure locking.
++ * Add function to initialize tdb hash table.
++ *
++ * Revision 1.13  1999/04/29 15:20:57  rgb
++ * dd return values to init and cleanup functions.
++ * Eliminate unnessessary usage of tdb_xform member to further switch
++ * away from the transform switch to the algorithm switch.
++ * Change gettdb parameter to a pointer to reduce stack loading and
++ * facilitate parameter sanity checking.
++ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
++ *
++ * Revision 1.12  1999/04/15 15:37:25  rgb
++ * Forward check changes from POST1_00 branch.
++ *
++ * Revision 1.9.2.2  1999/04/13 20:35:57  rgb
++ * Fix spelling mistake in comment.
++ *
++ * Revision 1.9.2.1  1999/03/30 17:13:52  rgb
++ * Extend struct tdb to support pfkey.
++ *
++ * Revision 1.11  1999/04/11 00:29:01  henry
++ * GPL boilerplate
++ *
++ * Revision 1.10  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.9  1999/01/26 02:09:31  rgb
++ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
++ * Removed dead code.
++ *
++ * Revision 1.8  1999/01/22 06:29:35  rgb
++ * Added algorithm switch code.
++ * Cruft clean-out.
++ *
++ * Revision 1.7  1998/11/10 05:37:35  rgb
++ * Add support for SA direction flag.
++ *
++ * Revision 1.6  1998/10/19 14:44:29  rgb
++ * Added inclusion of freeswan.h.
++ * sa_id structure implemented and used: now includes protocol.
++ *
++ * Revision 1.5  1998/08/12 00:12:30  rgb
++ * Added macros for new xforms.  Added prototypes for new xforms.
++ *
++ * Revision 1.4  1998/07/28 00:04:20  rgb
++ * Add macro for clearing the SA table.
++ *
++ * Revision 1.3  1998/07/14 18:06:46  rgb
++ * Added #ifdef __KERNEL__ directives to restrict scope of header.
++ *
++ * Revision 1.2  1998/06/23 03:02:19  rgb
++ * Created a prototype for ipsec_tdbcleanup when it was moved from
++ * ipsec_init.c.
++ *
++ * 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.4  1998/06/11 05:55:31  rgb
++ * Added transform version string pointer to xformsw structure definition.
++ * Added extern declarations for transform version strings.
++ *
++ * Revision 1.3  1998/05/18 22:02:54  rgb
++ * Modify the *_zeroize function prototypes to include one parameter.
++ *
++ * Revision 1.2  1998/04/21 21:29:08  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:14  henry
++ * sources moved up from linux/net/ipsec
++ *
++ * Revision 1.1.1.1  1998/04/08 05:35:06  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.
++ *
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ *
++ */
+diff --git a/include/freeswan/ipsec_xmit.h b/include/freeswan/ipsec_xmit.h
+new file mode 100644
+index 0000000..17678f8
+--- /dev/null
++++ b/include/freeswan/ipsec_xmit.h
+@@ -0,0 +1,167 @@
++/*
++ * IPSEC tunneling code
++ * Copyright (C) 1996, 1997  John Ioannidis.
++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  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$
++ */
++
++#include "freeswan/ipsec_sa.h"
++
++enum ipsec_xmit_value
++{
++	IPSEC_XMIT_STOLEN=2,
++	IPSEC_XMIT_PASS=1,
++	IPSEC_XMIT_OK=0,
++	IPSEC_XMIT_ERRMEMALLOC=-1,
++	IPSEC_XMIT_ESP_BADALG=-2,
++	IPSEC_XMIT_BADPROTO=-3,
++	IPSEC_XMIT_ESP_PUSHPULLERR=-4,
++	IPSEC_XMIT_BADLEN=-5,
++	IPSEC_XMIT_AH_BADALG=-6,
++	IPSEC_XMIT_SAIDNOTFOUND=-7,
++	IPSEC_XMIT_SAIDNOTLIVE=-8,
++	IPSEC_XMIT_REPLAYROLLED=-9,
++	IPSEC_XMIT_LIFETIMEFAILED=-10,
++	IPSEC_XMIT_CANNOTFRAG=-11,
++	IPSEC_XMIT_MSSERR=-12,
++	IPSEC_XMIT_ERRSKBALLOC=-13,
++	IPSEC_XMIT_ENCAPFAIL=-14,
++	IPSEC_XMIT_NODEV=-15,
++	IPSEC_XMIT_NOPRIVDEV=-16,
++	IPSEC_XMIT_NOPHYSDEV=-17,
++	IPSEC_XMIT_NOSKB=-18,
++	IPSEC_XMIT_NOIPV6=-19,
++	IPSEC_XMIT_NOIPOPTIONS=-20,
++	IPSEC_XMIT_TTLEXPIRED=-21,
++	IPSEC_XMIT_BADHHLEN=-22,
++	IPSEC_XMIT_PUSHPULLERR=-23,
++	IPSEC_XMIT_ROUTEERR=-24,
++	IPSEC_XMIT_RECURSDETECT=-25,
++	IPSEC_XMIT_IPSENDFAILURE=-26,
++};
++
++struct ipsec_xmit_state
++{
++	struct sk_buff *skb;		/* working skb pointer */
++	struct net_device *dev;		/* working dev pointer */
++	struct ipsecpriv *prv;		/* Our device' private space */
++	struct sk_buff *oskb;		/* 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     authlen;
++	int     max_headroom;		/* The extra header space needed */
++	int	max_tailroom;		/* The extra stuffing needed */
++	int     ll_headroom;		/* The extra link layer hard_header space needed */
++	int     tot_headroom;		/* The total header space needed */
++	int	tot_tailroom;		/* The totalstuffing needed */
++	__u8	*saved_header;		/* saved copy of the hard header */
++	unsigned short   sport, dport;
++
++	struct sockaddr_encap matcher;	/* eroute search key */
++	struct eroute *eroute;
++	struct ipsec_sa *ipsp, *ipsq;	/* ipsec_sa pointers */
++	char sa_txt[SATOT_BUF];
++	size_t sa_len;
++	int hard_header_stripped;	/* has the hard header been removed yet? */
++	int hard_header_len;
++	struct net_device *physdev;
++/*	struct net_device *virtdev; */
++	short physmtu;
++	short mtudiff;
++#ifdef NET_21
++	struct rtable *route;
++#endif /* NET_21 */
++	ip_said outgoing_said;
++#ifdef NET_21
++	int pass;
++#endif /* NET_21 */
++	int error;
++	uint32_t eroute_pid;
++	struct ipsec_sa ips;
++};
++
++enum ipsec_xmit_value
++ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
++
++enum ipsec_xmit_value
++ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
++
++enum ipsec_xmit_value
++ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
++
++extern int ipsec_xmit_trap_count;
++extern int ipsec_xmit_trap_sendcount;
++
++#ifdef CONFIG_KLIPS_DEBUG
++extern int debug_tunnel;
++extern int sysctl_ipsec_debug_verbose;
++#endif /* CONFIG_KLIPS_DEBUG */
++
++#define debug_xmit debug_tunnel
++
++#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z)
++
++extern int sysctl_ipsec_icmp;
++extern int sysctl_ipsec_tos;
++
++
++/*
++ * $Log: ipsec_xmit.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:51  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.8  2004/02/24 17:16:40  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.7  2004/02/22 06:49:15  mcr
++ * 	kernel 2.6 port - merged with 2.4 code.
++ *
++ * Revision 1.6.6.1  2004/02/20 14:09:55  mcr
++ * 	moved code to net/ipsec/ to make 2.6 happy.
++ *
++ * Revision 1.6  2003/12/11 20:14:58  mcr
++ * 	refactored the xmit code, to move all encapsulation
++ * 	code into protocol functions. Note that all functions
++ * 	are essentially done by a single function, which is probably
++ * 	wrong.
++ * 	the rcv_functions structures are renamed xform_functions.
++ *
++ * Revision 1.5  2003/12/04 19:05:26  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.4  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.2  2003/06/20 01:42:13  mcr
++ * 	added counters to measure how many ACQUIREs we send to pluto,
++ * 	and how many are successfully sent.
++ *
++ * Revision 1.1  2003/02/12 19:31:03  rgb
++ * Refactored from ipsec_tunnel.c
++ *
++ */
+diff --git a/include/freeswan/passert.h b/include/freeswan/passert.h
+new file mode 100644
+index 0000000..30b9eea
+--- /dev/null
++++ b/include/freeswan/passert.h
+@@ -0,0 +1,64 @@
++/*
++ * sanitize a string into a printable format.
++ *
++ * Copyright (C) 1998-2002  D. Hugh Redelmeier.
++ * Copyright (C) 2003  Michael Richardson <mcr at freeswan.org>
++ * 
++ * 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$
++ */
++
++#include "freeswan.h"
++
++/* our versions of assert: log result */
++
++#ifdef DEBUG
++
++extern void passert_fail(const char *pred_str
++    , const char *file_str, unsigned long line_no) NEVER_RETURNS;
++
++extern void pexpect_log(const char *pred_str
++			, const char *file_str, unsigned long line_no);
++
++# define impossible() passert_fail("impossible", __FILE__, __LINE__)
++
++extern void switch_fail(int n
++    , const char *file_str, unsigned long line_no) NEVER_RETURNS;
++
++# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
++
++# define passert(pred) { \
++	if (!(pred)) \
++	    passert_fail(#pred, __FILE__, __LINE__); \
++    }
++
++# define pexpect(pred) { \
++	if (!(pred)) \
++	    pexpect_log(#pred, __FILE__, __LINE__); \
++    }
++
++/* assert that an err_t is NULL; evaluate exactly once */
++# define happy(x) { \
++	err_t ugh = x; \
++	if (ugh != NULL) \
++	    passert_fail(ugh, __FILE__, __LINE__); \
++    }
++
++#else /*!DEBUG*/
++
++# define impossible() abort()
++# define bad_case(n) abort()
++# define passert(pred)  { }	/* do nothing */
++# define happy(x)  { (void) x; }	/* evaluate non-judgementally */
++
++#endif /*!DEBUG*/
++
+diff --git a/include/freeswan/pfkey_debug.h b/include/freeswan/pfkey_debug.h
+new file mode 100644
+index 0000000..7188db1
+--- /dev/null
++++ b/include/freeswan/pfkey_debug.h
+@@ -0,0 +1,54 @@
++/*
++ * sanitize a string into a printable format.
++ *
++ * Copyright (C) 1998-2002  D. Hugh Redelmeier.
++ * Copyright (C) 2003  Michael Richardson <mcr at freeswan.org>
++ * 
++ * 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$
++ */
++
++#ifndef _FREESWAN_PFKEY_DEBUG_H
++#define _FREESWAN_PFKEY_DEBUG_H
++
++#ifdef __KERNEL__
++
++/* note, kernel version ignores pfkey levels */
++# define DEBUGGING(level,args...) \
++         KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
++
++# define ERROR(args...) printk(KERN_ERR "klips:" args)
++
++#else
++
++extern unsigned int pfkey_lib_debug;
++
++extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
++extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
++
++#define DEBUGGING(level,args...)  if(pfkey_lib_debug & level) { \
++                              if(pfkey_debug_func != NULL) { \
++                                (*pfkey_debug_func)("pfkey_lib_debug:" args); \
++                              } else { \
++                                printf("pfkey_lib_debug:" args); \
++                              } }
++
++#define ERROR(args...)      if(pfkey_error_func != NULL) { \
++                                (*pfkey_error_func)("pfkey_lib_debug:" args); \
++                              } 
++
++# define MALLOC(size) malloc(size)
++# define FREE(obj) free(obj)
++
++#endif
++
++#endif
+diff --git a/include/freeswan/radij.h b/include/freeswan/radij.h
+new file mode 100644
+index 0000000..3d76b06
+--- /dev/null
++++ b/include/freeswan/radij.h
+@@ -0,0 +1,283 @@
++/*
++ * RCSID $Id$
++ */
++
++/*
++ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
++ *
++ * Variable and procedure names have been modified so that they don't
++ * conflict with the original BSD code, as a small number of modifications
++ * have been introduced and we may want to reuse this code in BSD.
++ * 
++ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
++ * chi or a German ch sound (as `doch', not as in `milch'), or even a 
++ * spanish j as in Juan.  It is not as far back in the throat like
++ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
++ * It has nothing to do with the Dutch ij sound.
++ * 
++ * Here is the appropriate copyright notice:
++ */
++
++/*
++ * Copyright (c) 1988, 1989, 1993
++ *	The Regents of the University of California.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *	This product includes software developed by the University of
++ *	California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ *    may be used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ *
++ *	@(#)radix.h	8.1 (Berkeley) 6/10/93
++ */
++
++#ifndef _RADIJ_H_
++#define	_RADIJ_H_
++
++/* 
++#define RJ_DEBUG
++*/
++
++#ifdef __KERNEL__
++
++#ifndef __P
++#ifdef __STDC__
++#define __P(x)  x
++#else
++#define __P(x)  ()
++#endif
++#endif
++
++/*
++ * Radix search tree node layout.
++ */
++
++struct radij_node
++{
++	struct	radij_mask *rj_mklist;	/* list of masks contained in subtree */
++	struct	radij_node *rj_p;	/* parent */
++	short	rj_b;			/* bit offset; -1-index(netmask) */
++	char	rj_bmask;		/* node: mask for bit test*/
++	u_char	rj_flags;		/* enumerated next */
++#define RJF_NORMAL	1		/* leaf contains normal route */
++#define RJF_ROOT	2		/* leaf is root leaf for tree */
++#define RJF_ACTIVE	4		/* This node is alive (for rtfree) */
++	union {
++		struct {			/* leaf only data: */
++			caddr_t	rj_Key;	/* object of search */
++			caddr_t	rj_Mask;	/* netmask, if present */
++			struct	radij_node *rj_Dupedkey;
++		} rj_leaf;
++		struct {			/* node only data: */
++			int	rj_Off;		/* where to start compare */
++			struct	radij_node *rj_L;/* progeny */
++			struct	radij_node *rj_R;/* progeny */
++		}rj_node;
++	}		rj_u;
++#ifdef RJ_DEBUG
++	int rj_info;
++	struct radij_node *rj_twin;
++	struct radij_node *rj_ybro;
++#endif
++};
++
++#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
++#define rj_key rj_u.rj_leaf.rj_Key
++#define rj_mask rj_u.rj_leaf.rj_Mask
++#define rj_off rj_u.rj_node.rj_Off
++#define rj_l rj_u.rj_node.rj_L
++#define rj_r rj_u.rj_node.rj_R
++
++/*
++ * Annotations to tree concerning potential routes applying to subtrees.
++ */
++
++extern struct radij_mask {
++	short	rm_b;			/* bit offset; -1-index(netmask) */
++	char	rm_unused;		/* cf. rj_bmask */
++	u_char	rm_flags;		/* cf. rj_flags */
++	struct	radij_mask *rm_mklist;	/* more masks to try */
++	caddr_t	rm_mask;		/* the mask */
++	int	rm_refs;		/* # of references to this struct */
++} *rj_mkfreelist;
++
++#define MKGet(m) {\
++	if (rj_mkfreelist) {\
++		m = rj_mkfreelist; \
++		rj_mkfreelist = (m)->rm_mklist; \
++	} else \
++		R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
++
++#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
++
++struct radij_node_head {
++	struct	radij_node *rnh_treetop;
++	int	rnh_addrsize;		/* permit, but not require fixed keys */
++	int	rnh_pktsize;		/* permit, but not require fixed keys */
++#if 0
++	struct	radij_node *(*rnh_addaddr)	/* add based on sockaddr */
++		__P((void *v, void *mask,
++		     struct radij_node_head *head, struct radij_node nodes[]));
++#endif
++	int (*rnh_addaddr)	/* add based on sockaddr */
++		__P((void *v, void *mask,
++		     struct radij_node_head *head, struct radij_node nodes[]));
++	struct	radij_node *(*rnh_addpkt)	/* add based on packet hdr */
++		__P((void *v, void *mask,
++		     struct radij_node_head *head, struct radij_node nodes[]));
++#if 0
++	struct	radij_node *(*rnh_deladdr)	/* remove based on sockaddr */
++		__P((void *v, void *mask, struct radij_node_head *head));
++#endif
++	int (*rnh_deladdr)	/* remove based on sockaddr */
++		__P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
++	struct	radij_node *(*rnh_delpkt)	/* remove based on packet hdr */
++		__P((void *v, void *mask, struct radij_node_head *head));
++	struct	radij_node *(*rnh_matchaddr)	/* locate based on sockaddr */
++		__P((void *v, struct radij_node_head *head));
++	struct	radij_node *(*rnh_matchpkt)	/* locate based on packet hdr */
++		__P((void *v, struct radij_node_head *head));
++	int	(*rnh_walktree)			/* traverse tree */
++		__P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
++	struct	radij_node rnh_nodes[3];	/* empty tree for common case */
++};
++
++
++#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
++#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
++#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
++#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
++#define Free(p) kfree((caddr_t)p);
++
++void	 rj_init __P((void));
++int	 rj_inithead __P((void **, int));
++int	 rj_refines __P((void *, void *));
++int	 rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
++struct radij_node
++	 *rj_addmask __P((void *, int, int)) /* , rgb */ ;
++int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
++			struct radij_node [2])) /* , rgb */ ;
++int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
++struct radij_node /* rgb */
++	 *rj_insert __P((void *, struct radij_node_head *, int *,
++			struct radij_node [2])),
++	 *rj_match __P((void *, struct radij_node_head *)),
++	 *rj_newpair __P((void *, int, struct radij_node[2])),
++	 *rj_search __P((void *, struct radij_node *)),
++	 *rj_search_m __P((void *, struct radij_node *, void *));
++
++void rj_deltree(struct radij_node_head *);
++void rj_delnodes(struct radij_node *);
++void rj_free_mkfreelist(void);
++int radijcleartree(void);
++int radijcleanup(void);
++
++extern struct radij_node_head *mask_rjhead;
++extern int maj_keylen;
++#endif /* __KERNEL__ */
++
++#endif /* _RADIJ_H_ */
++
++
++/*
++ * $Log: radij.h,v $
++ * Revision 1.1.1.1  2004/08/20 11:33:51  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:12:20  rupert
++ * +: Add Freeswan IPSEC 2.06
++ *
++ * Revision 1.12  2002/04/24 07:36:48  mcr
++ * Moved from ./klips/net/ipsec/radij.h,v
++ *
++ * Revision 1.11  2001/09/20 15:33:00  rgb
++ * Min/max cleanup.
++ *
++ * Revision 1.10  1999/11/18 04:09:20  rgb
++ * Replaced all kernel version macros to shorter, readable form.
++ *
++ * Revision 1.9  1999/05/05 22:02:33  rgb
++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc at mbsi.ca>.
++ *
++ * Revision 1.8  1999/04/29 15:24:58  rgb
++ * Add check for existence of macros min/max.
++ *
++ * Revision 1.7  1999/04/11 00:29:02  henry
++ * GPL boilerplate
++ *
++ * Revision 1.6  1999/04/06 04:54:29  rgb
++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
++ * patch shell fixes.
++ *
++ * Revision 1.5  1999/01/22 06:30:32  rgb
++ * 64-bit clean-up.
++ *
++ * Revision 1.4  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.3  1998/10/25 02:43:27  rgb
++ * Change return type on rj_addroute and rj_delete and add and argument
++ * to the latter to be able to transmit more infomation about errors.
++ *
++ * Revision 1.2  1998/07/14 18:09:51  rgb
++ * Add a routine to clear eroute table.
++ * Added #ifdef __KERNEL__ directives to restrict scope of header.
++ *
++ * Revision 1.1  1998/06/18 21:30:22  henry
++ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
++ * build scripts happier about symlinks
++ *
++ * Revision 1.4  1998/05/25 20:34:16  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.
++ *
++ * Recover memory for eroute table on unload of module.
++ *
++ * Revision 1.3  1998/04/22 16:51:37  rgb
++ * Tidy up radij debug code from recent rash of modifications to debug code.
++ *
++ * Revision 1.2  1998/04/14 17:30:38  rgb
++ * Fix up compiling errors for radij tree memory reclamation.
++ *
++ * Revision 1.1  1998/04/09 03:06:16  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:44:45  ji
++ * Release update only.
++ *
++ * Revision 0.2  1996/11/02 00:18:33  ji
++ * First limited release.
++ *
++ *
++ */
+diff --git a/include/infblock.h b/include/infblock.h
+new file mode 100644
+index 0000000..173b226
+--- /dev/null
++++ b/include/infblock.h
+@@ -0,0 +1,39 @@
++/* infblock.h -- header to use infblock.c
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++struct inflate_blocks_state;
++typedef struct inflate_blocks_state FAR inflate_blocks_statef;
++
++extern inflate_blocks_statef * inflate_blocks_new OF((
++    z_streamp z,
++    check_func c,               /* check function */
++    uInt w));                   /* window size */
++
++extern int inflate_blocks OF((
++    inflate_blocks_statef *,
++    z_streamp ,
++    int));                      /* initial return code */
++
++extern void inflate_blocks_reset OF((
++    inflate_blocks_statef *,
++    z_streamp ,
++    uLongf *));                  /* check value on output */
++
++extern int inflate_blocks_free OF((
++    inflate_blocks_statef *,
++    z_streamp));
++
++extern void inflate_set_dictionary OF((
++    inflate_blocks_statef *s,
++    const Bytef *d,  /* dictionary */
++    uInt  n));       /* dictionary length */
++
++extern int inflate_blocks_sync_point OF((
++    inflate_blocks_statef *s));
+diff --git a/include/infcodes.h b/include/infcodes.h
+new file mode 100644
+index 0000000..27e4a40
+--- /dev/null
++++ b/include/infcodes.h
+@@ -0,0 +1,31 @@
++/* infcodes.h -- header to use infcodes.c
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++#ifndef _INFCODES_H
++#define _INFCODES_H
++
++struct inflate_codes_state;
++typedef struct inflate_codes_state FAR inflate_codes_statef;
++
++extern inflate_codes_statef *inflate_codes_new OF((
++    uInt, uInt,
++    inflate_huft *, inflate_huft *,
++    z_streamp ));
++
++extern int inflate_codes OF((
++    inflate_blocks_statef *,
++    z_streamp ,
++    int));
++
++extern void inflate_codes_free OF((
++    inflate_codes_statef *,
++    z_streamp ));
++
++#endif /* _INFCODES_H */
+diff --git a/include/inffast.h b/include/inffast.h
+new file mode 100644
+index 0000000..652a0e8
+--- /dev/null
++++ b/include/inffast.h
+@@ -0,0 +1,22 @@
++/* inffast.h -- header to use inffast.c
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++#ifndef _INFFAST_H
++#define _INFFAST_H
++
++extern int inflate_fast OF((
++    uInt,
++    uInt,
++    inflate_huft *,
++    inflate_huft *,
++    inflate_blocks_statef *,
++    z_streamp ));
++
++#endif /* _INFFAST_H */
+diff --git a/include/inffixed.h b/include/inffixed.h
+new file mode 100644
+index 0000000..77f7e76
+--- /dev/null
++++ b/include/inffixed.h
+@@ -0,0 +1,151 @@
++/* inffixed.h -- table for decoding fixed codes
++ * Generated automatically by the maketree.c program
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++local uInt fixed_bl = 9;
++local uInt fixed_bd = 5;
++local inflate_huft fixed_tl[] = {
++    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
++    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
++    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
++    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
++    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
++    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
++    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
++    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
++    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
++    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
++    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
++    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
++    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
++    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
++    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
++    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
++    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
++    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
++    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
++    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
++    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
++    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
++    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
++    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
++    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
++    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
++    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
++    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
++    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
++    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
++    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
++    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
++    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
++    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
++    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
++    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
++    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
++    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
++    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
++    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
++    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
++    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
++    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
++    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
++    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
++    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
++    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
++    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
++    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
++    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
++    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
++    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
++    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
++    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
++    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
++    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
++    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
++    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
++    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
++    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
++    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
++    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
++    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
++    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
++    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
++    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
++    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
++    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
++    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
++    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
++    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
++    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
++    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
++    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
++    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
++    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
++    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
++    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
++    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
++    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
++    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
++    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
++    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
++    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
++    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
++    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
++    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
++    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
++    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
++    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
++    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
++    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
++    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
++    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
++    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
++    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
++    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
++    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
++    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
++    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
++    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
++    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
++    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
++    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
++    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
++    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
++    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
++    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
++    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
++    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
++    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
++    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
++    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
++    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
++    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
++    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
++    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
++    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
++    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
++    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
++    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
++    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
++    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
++    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
++    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
++    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
++    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
++    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
++  };
++local inflate_huft fixed_td[] = {
++    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
++    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
++    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
++    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
++    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
++    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
++    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
++    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
++  };
+diff --git a/include/inftrees.h b/include/inftrees.h
+new file mode 100644
+index 0000000..ef15b1b
+--- /dev/null
++++ b/include/inftrees.h
+@@ -0,0 +1,63 @@
++/* inftrees.h -- header to use inftrees.c
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++/* Huffman code lookup table entry--this entry is four bytes for machines
++   that have 16-bit pointers (e.g. PC's in the small or medium model). */
++
++#ifndef _INFTREES_H
++#define _INFTREES_H
++
++typedef struct inflate_huft_s FAR inflate_huft;
++
++struct inflate_huft_s {
++  union {
++    struct {
++      Byte Exop;        /* number of extra bits or operation */
++      Byte Bits;        /* number of bits in this code or subcode */
++    } what;
++    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
++  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
++  uInt base;            /* literal, length base, distance base,
++                           or table offset */
++};
++
++/* Maximum size of dynamic tree.  The maximum found in a long but non-
++   exhaustive search was 1004 huft structures (850 for length/literals
++   and 154 for distances, the latter actually the result of an
++   exhaustive search).  The actual maximum is not known, but the
++   value below is more than safe. */
++#define MANY 1440
++
++extern int inflate_trees_bits OF((
++    uIntf *,                    /* 19 code lengths */
++    uIntf *,                    /* bits tree desired/actual depth */
++    inflate_huft * FAR *,       /* bits tree result */
++    inflate_huft *,             /* space for trees */
++    z_streamp));                /* for messages */
++
++extern int inflate_trees_dynamic OF((
++    uInt,                       /* number of literal/length codes */
++    uInt,                       /* number of distance codes */
++    uIntf *,                    /* that many (total) code lengths */
++    uIntf *,                    /* literal desired/actual bit depth */
++    uIntf *,                    /* distance desired/actual bit depth */
++    inflate_huft * FAR *,       /* literal/length tree result */
++    inflate_huft * FAR *,       /* distance tree result */
++    inflate_huft *,             /* space for trees */
++    z_streamp));                /* for messages */
++
++extern int inflate_trees_fixed OF((
++    uIntf *,                    /* literal desired/actual bit depth */
++    uIntf *,                    /* distance desired/actual bit depth */
++    inflate_huft * FAR *,       /* literal/length tree result */
++    inflate_huft * FAR *,       /* distance tree result */
++    z_streamp));                /* for memory allocation */
++
++#endif /* _INFTREES_H */
+diff --git a/include/infutil.h b/include/infutil.h
+new file mode 100644
+index 0000000..959e12e
+--- /dev/null
++++ b/include/infutil.h
+@@ -0,0 +1,98 @@
++/* infutil.h -- types and macros common to blocks and codes
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++#ifndef _INFUTIL_H
++#define _INFUTIL_H
++
++typedef enum {
++      TYPE,     /* get type bits (3, including end bit) */
++      LENS,     /* get lengths for stored */
++      STORED,   /* processing stored block */
++      TABLE,    /* get table lengths */
++      BTREE,    /* get bit lengths tree for a dynamic block */
++      DTREE,    /* get length, distance trees for a dynamic block */
++      CODES,    /* processing fixed or dynamic block */
++      DRY,      /* output remaining window bytes */
++      DONE,     /* finished last block, done */
++      BAD}      /* got a data error--stuck here */
++inflate_block_mode;
++
++/* inflate blocks semi-private state */
++struct inflate_blocks_state {
++
++  /* mode */
++  inflate_block_mode  mode;     /* current inflate_block mode */
++
++  /* mode dependent information */
++  union {
++    uInt left;          /* if STORED, bytes left to copy */
++    struct {
++      uInt table;               /* table lengths (14 bits) */
++      uInt index;               /* index into blens (or border) */
++      uIntf *blens;             /* bit lengths of codes */
++      uInt bb;                  /* bit length tree depth */
++      inflate_huft *tb;         /* bit length decoding tree */
++    } trees;            /* if DTREE, decoding info for trees */
++    struct {
++      inflate_codes_statef 
++         *codes;
++    } decode;           /* if CODES, current state */
++  } sub;                /* submode */
++  uInt last;            /* true if this block is the last block */
++
++  /* mode independent information */
++  uInt bitk;            /* bits in bit buffer */
++  uLong bitb;           /* bit buffer */
++  inflate_huft *hufts;  /* single malloc for tree space */
++  Bytef *window;        /* sliding window */
++  Bytef *end;           /* one byte after sliding window */
++  Bytef *read;          /* window read pointer */
++  Bytef *write;         /* window write pointer */
++  check_func checkfn;   /* check function */
++  uLong check;          /* check on output */
++
++};
++
++
++/* defines for inflate input/output */
++/*   update pointers and return */
++#define UPDBITS {s->bitb=b;s->bitk=k;}
++#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
++#define UPDOUT {s->write=q;}
++#define UPDATE {UPDBITS UPDIN UPDOUT}
++#define LEAVE {UPDATE return inflate_flush(s,z,r);}
++/*   get bytes and bits */
++#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
++#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
++#define NEXTBYTE (n--,*p++)
++#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
++#define DUMPBITS(j) {b>>=(j);k-=(j);}
++/*   output bytes */
++#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
++#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
++#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
++#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
++#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
++#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
++/*   load local pointers */
++#define LOAD {LOADIN LOADOUT}
++
++/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
++extern uInt inflate_mask[17];
++
++/* copy as much as possible from the sliding window to the output area */
++extern int inflate_flush OF((
++    inflate_blocks_statef *,
++    z_streamp ,
++    int));
++
++struct internal_state      {int dummy;}; /* for buggy compilers */
++
++#endif /* _INFUTIL_H */
+diff --git a/include/internal.h b/include/internal.h
+new file mode 100644
+index 0000000..c18db31
+--- /dev/null
++++ b/include/internal.h
+@@ -0,0 +1,81 @@
++/*
++ * internal definitions for use within the library; do not export!
++ * Copyright (C) 1998, 1999  Henry Spencer.
++ * 
++ * 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$
++ */
++
++#ifndef ABITS
++#define	ABITS	32	/* bits in an IPv4 address */
++#endif
++
++/* case-independent ASCII character equality comparison */
++#define	CIEQ(c1, c2)	( ((c1)&~040) == ((c2)&~040) )
++
++/* syntax for passthrough SA */
++#ifndef PASSTHROUGHNAME
++#define	PASSTHROUGHNAME	"%passthrough"
++#define	PASSTHROUGH4NAME	"%passthrough4"
++#define	PASSTHROUGH6NAME	"%passthrough6"
++#define	PASSTHROUGHIS	"tun0 at 0.0.0.0"
++#define	PASSTHROUGH4IS	"tun0 at 0.0.0.0"
++#define	PASSTHROUGH6IS	"tun0@::"
++#define	PASSTHROUGHTYPE	"tun"
++#define	PASSTHROUGHSPI	0
++#define	PASSTHROUGHDST	0
++#endif
++
++/*
++ * Headers, greatly complicated by stupid and unnecessary inconsistencies
++ * between the user environment and the kernel environment.  These are done
++ * here so that this mess need exist in only one place.
++ *
++ * It may seem like a -I or two could avoid most of this, but on closer
++ * inspection it is not quite that easy.
++ */
++
++/* things that need to come from one place or the other, depending */
++#ifdef __KERNEL__
++#include <linux/types.h>
++#include <linux/socket.h>
++#include <linux/in.h>
++#include <linux/string.h>
++#include <linux/ctype.h>
++#define	assert(foo)	/* nothing */
++#else
++#include <sys/types.h>
++#include <netinet/in.h>
++#include <string.h>
++#include <ctype.h>
++#include <assert.h>
++#endif
++
++/* things that exist only in userland */
++#ifndef __KERNEL__
++
++/* You'd think this would be okay in the kernel too -- it's just a */
++/* bunch of constants -- but no, in RH5.1 it screws up other things. */
++/* (Credit:  Mike Warfield tracked this problem down.  Thanks Mike!) */
++/* Fortunately, we don't need it in the kernel subset of the library. */
++#include <limits.h>
++
++/* header files for things that should never be called in kernel */
++#include <netdb.h>
++
++/* memory allocation, currently user-only, macro-ized just in case */
++#include <stdlib.h>
++#define	MALLOC(n)	malloc(n)
++#define	FREE(p)		free(p)
++
++#endif /* __KERNEL__ */
++
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index c3cd5ff..bb5c5a5 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -807,6 +807,9 @@ static void udp_close(struct sock *sk, long timeout)
+ 
+ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
+ {
++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
++	struct udp_opt *tp =  &(sk->tp_pinfo.af_udp);
++#endif
+ 	/*
+ 	 *	Charge it to the socket, dropping if the queue is full.
+ 	 */
+@@ -823,7 +826,38 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
+ 		skb->ip_summed = CHECKSUM_UNNECESSARY;
+ 	}
+ #endif
++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
++	if (tp->esp_in_udp) {
++		/*
++		 * Set skb->sk and xmit packet to ipsec_rcv.
++		 *
++		 * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
++		 * restore skb->sk and fall back to sock_queue_rcv_skb
++		 */
++		struct inet_protocol *esp = NULL;
+ 
++#ifdef CONFIG_IPSEC_MODULE
++		for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
++			(esp) && (esp->protocol != IPPROTO_ESP);
++			esp = esp->next);
++#else
++		extern struct inet_protocol esp_protocol;
++		esp = &esp_protocol;
++#endif
++
++		if (esp && esp->handler) {
++			struct sock *sav_sk = skb->sk;
++			skb->sk = sk;
++		if (esp->handler(skb) == 0) {
++				skb->sk = sav_sk;
++				/* not sure we might count ESPinUDP as UDP... */
++				UDP_INC_STATS_BH(UdpInDatagrams);
++				return 0;
++			}
++			skb->sk = sav_sk;
++		}
++	}
++#endif
+ 	if (sock_queue_rcv_skb(sk,skb)<0) {
+ 		UDP_INC_STATS_BH(UdpInErrors);
+ 		IP_INC_STATS_BH(IpInDiscards);
+@@ -1047,13 +1081,55 @@ out:
+ 	return len;
+ }
+ 
++#if 1
++static int udp_setsockopt(struct sock *sk, int level, int optname,
++	char *optval, int optlen)
++{
++	struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
++	int val;
++	int err = 0;
++
++	if (level != SOL_UDP)
++		return ip_setsockopt(sk, level, optname, optval, optlen);
++
++	if(optlen<sizeof(int))
++		return -EINVAL;
++
++	if (get_user(val, (int *)optval))
++		return -EFAULT;
++	
++	lock_sock(sk);
++
++	switch(optname) {
++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
++#ifndef UDP_ESPINUDP
++#define UDP_ESPINUDP 100
++#endif
++		case UDP_ESPINUDP:
++			tp->esp_in_udp = val;
++			break;
++#endif
++		default:
++			err = -ENOPROTOOPT;
++			break;
++	}
++
++	release_sock(sk);
++	return err;
++}
++#endif
++
+ struct proto udp_prot = {
+  	name:		"UDP",
+ 	close:		udp_close,
+ 	connect:	udp_connect,
+ 	disconnect:	udp_disconnect,
+ 	ioctl:		udp_ioctl,
+-	setsockopt:	ip_setsockopt,
++#if 1
++	setsockopt:	udp_setsockopt,
++#else
++ 	setsockopt:	ip_setsockopt,
++#endif
+ 	getsockopt:	ip_getsockopt,
+ 	sendmsg:	udp_sendmsg,
+ 	recvmsg:	udp_recvmsg,
+diff --git a/net/Config.in b/net/Config.in
+index f14b12c..754bf21 100644
+--- a/net/Config.in
++++ b/net/Config.in
+@@ -102,4 +102,9 @@ comment 'Network testing'
+ tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN
+ endmenu
+ 
++tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_KLIPS
++if [ "$CONFIG_KLIPS" != "n" ]; then
++  source net/ipsec/Config.in
++fi
++
+ endmenu
+diff --git a/net/ipsec/Config.in b/net/ipsec/Config.in
+new file mode 100644
+index 0000000..33d88b6
+--- /dev/null
++++ b/net/ipsec/Config.in
+@@ -0,0 +1,58 @@
++#
++# 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: Config.in,v 1.1.1.1 2004/08/20 11:34:10 r04482 Exp $
++
++comment 'IPSec options (FreeS/WAN)'
++
++bool '    HMAC-MD5 authentication algorithm' CONFIG_KLIPS_AUTH_HMAC_MD5
++bool '    HMAC-SHA1 authentication algorithm' CONFIG_KLIPS_AUTH_HMAC_SHA1
++bool '    3DES encryption algorithm' CONFIG_KLIPS_ENC_3DES
++
++comment ' ESP always enabled with tunnel mode'
++
++bool '   IPSEC: IP Compression' CONFIG_KLIPS_IPCOMP
++bool '   IPSEC Debugging Option' CONFIG_KLIPS_DEBUG
++
++#
++#
++# $Log: Config.in,v $
++# Revision 1.1.1.1  2004/08/20 11:34:10  r04482
++# no message
++#
++# Revision 1.1  2004/08/02 02:09:58  rupert
++# +: Add Freeswan IPSec 2.06
++#
++# Revision 1.29  2004/02/24 17:17:04  mcr
++# 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++# 	turn it on/off as well.
++#
++# Revision 1.28  2003/12/15 15:42:27  mcr
++# 	make sure that ESP is always on, and AH is no more.
++#
++# Revision 1.27  2003/12/13 04:09:21  mcr
++# 	AH transform removed.
++#
++# Revision 1.26  2002/04/24 07:36:26  mcr
++# Moved from ./klips/net/ipsec/Config.in,v
++#
++# 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 --git a/net/ipsec/Kconfig b/net/ipsec/Kconfig
+new file mode 100644
+index 0000000..33292c9
+--- /dev/null
++++ b/net/ipsec/Kconfig
+@@ -0,0 +1,95 @@
++#
++# IPSEC configuration
++# Copyright (C) 2004 Michael Richardson <mcr at 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: Kconfig,v 1.1.1.1 2004/08/20 11:34:10 r04482 Exp $
++
++config KLIPS
++	tristate "FreeS/WAN IPsec (KLIPS)"
++	default n
++	help
++  	  KLIPS is the FreeS/WAN (www.freeswan.org) Kernel Level IP Security
++	  system. It is extensively tested, and has interoperated with
++	  many other systems. 
++          It provides "ipsecX" devices on which one can do firewalling.
++ 	  It is maintained outside of the United States, so no export
++	  controls apply (nor any fear of retroactive controls being imposed
++	  by USA's BXA).  
++          The userland, is compatible with both KLIPS and 26sec.
++
++menu "KLIPS options"
++	depends on KLIPS
++
++config KLIPS_AUTH_HMAC_MD5
++	bool 'HMAC-MD5 authentication algorithm' 
++	default y
++	help
++           The HMAC-MD5 algorithm is used by ESP (and AH) to guarantee packet
++	   integrity. There is little reason not to include it.
++
++config KLIPS_AUTH_HMAC_SHA1
++	bool 'HMAC-SHA1 authentication algorithm' 
++	default y
++	help
++           The HMAC-SHA1 algorithm is used by ESP (and AH) to guarantee packet
++	   integrity. SHA1 is a little slower than MD5, but is said to be 
++	   a bit more secure. There is little reason not to include it.
++
++config KLIPS_ENC_3DES
++	bool '3DES encryption algorithm'
++	default y
++	help
++           The 3DES algorithm is used by ESP to provide for packet privacy.
++	   3DES is 3-repeats of the DES algorithm. 3DES is widely supported,
++	   and analyzed and is considered very secure. 1DES is not supported.
++
++config KLIPS_IPCOMP
++	bool 'IP compression'
++	default y
++	help
++           The IPcomp protocol is used prior to ESP to make the packet
++	   smaller. Once encrypted, compression will fail, so any link
++	   layer efforts (e.g. PPP) will not work. 
++
++config KLIPS_DEBUG
++	bool 'IPsec debugging'
++	default y 
++	help
++           KLIPS includes a lot of debugging code. Unless there is a real
++	   tangible benefit to removing this code, it should be left in place.
++	   Debugging connections without access to kernel level debugging is
++	   essentially impossible. Leave this on.
++
++endmenu
++
++#
++#
++# $Log: Kconfig,v $
++# Revision 1.1.1.1  2004/08/20 11:34:10  r04482
++# no message
++#
++# Revision 1.1  2004/08/02 02:09:58  rupert
++# +: Add Freeswan IPSec 2.06
++#
++# Revision 1.3  2004/02/24 17:17:04  mcr
++# 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++# 	turn it on/off as well.
++#
++# Revision 1.2  2004/02/22 06:50:42  mcr
++# 	kernel 2.6 port - merged with 2.4 code.
++#
++# Revision 1.1.2.1  2004/02/20 02:07:53  mcr
++# 	module configuration for KLIPS 2.6
++#
++#
++
+diff --git a/net/ipsec/Makefile b/net/ipsec/Makefile
+new file mode 100644
+index 0000000..3856de1
+--- /dev/null
++++ b/net/ipsec/Makefile
+@@ -0,0 +1,531 @@
++# Makefile for KLIPS kernel code as a module    for 2.4 kernels
++#
++# Makefile for KLIPS kernel code as a module
++# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
++# Copyright (C) 2002	Michael Richardson <mcr at 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: Makefile,v 1.4 2005/02/03 12:45:49 r05549 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).
++#
++
++ifeq ($(strip $(KLIPSMODULE)),)
++FREESWANSRCDIR=.
++else
++FREESWANSRCDIR=../../..
++endif
++-include ${FREESWANSRCDIR}/Makefile.ver
++
++ifeq ($(strip $(KLIPS_TOP)),)
++KLIPS_TOP=../..
++endif
++
++ifneq ($(strip $(KLIPSMODULE)),)
++
++ifndef TOPDIR
++TOPDIR:=/usr/src/linux
++endif
++export TOPDIR
++
++endif
++
++subdir-  := 
++subdir-n := 
++subdir-y :=
++subdir-m :=
++
++
++MOD_DESTDIR:=net/ipsec
++
++export TOPDIR
++
++all: ipsec.o
++
++foo:
++	echo KERNEL: ${KERNEL_CFLAGS}
++	echo MODULE: ${MODULE_CFLAGS}
++
++ipsec.o: foo
++
++# always force it on
++CONFIG_KLIPS_ESP:=y
++CONFIG_KLIPS_IPIP:=y
++
++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_xmit.o ipsec_rcv.o ipsec_ipip.o
++obj-y += sysctl_net_ipsec.o 
++obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o 
++obj-y += version.o
++obj-$(CONFIG_KLIPS_ESP)+= ipsec_esp.o
++obj-$(CONFIG_KLIPS_IPCOMP)+= ipsec_ipcomp.o
++
++# not included in normal distribution
++#obj-$(CONFIG_KLIPS_AH) += ipsec_ah.o
++
++LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des
++
++ifndef CONFIG_RTL865XB_EXP_CRYPTOENGINE
++	obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
++	obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
++	obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
++endif
++#obj-$(CONFIG_KLIPS_ENC_3DES) += des_opts.o
++#obj-$(CONFIG_KLIPS_ENC_3DES) += fcrypt.o
++
++ifeq ($(strip ${SUBARCH}),)
++SUBARCH:=${ARCH}
++endif
++
++ifeq (${SUBARCH},i386)
++obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
++else
++ifndef CONFIG_RTL865XB_EXP_CRYPTOENGINE
++	obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
++endif
++endif
++
++LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan
++
++obj-y += satot.o
++obj-y += addrtot.o
++obj-y += ultot.o 
++obj-y += addrtypeof.o
++obj-y += anyaddr.o
++obj-y += initaddr.o
++obj-y += ultoa.o 
++obj-y += addrtoa.o 
++obj-y += subnettoa.o 
++obj-y += subnetof.o 
++obj-y += goodmask.o 
++obj-y += datatot.o 
++obj-y += rangetoa.o 
++obj-y += prng.o 
++obj-y += pfkey_v2_parse.o 
++obj-y += pfkey_v2_build.o 
++obj-y += pfkey_v2_debug.o 
++obj-y += pfkey_v2_ext_bits.o 
++obj-y += version.o
++
++# IPcomp stuff
++obj-$(CONFIG_KLIPS_IPCOMP) += ipcomp.o 
++
++obj-$(CONFIG_KLIPS_IPCOMP) += adler32.o
++obj-$(CONFIG_KLIPS_IPCOMP) += deflate.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infblock.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infcodes.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inffast.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inflate.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inftrees.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infutil.o
++obj-$(CONFIG_KLIPS_IPCOMP) += trees.o
++obj-$(CONFIG_KLIPS_IPCOMP) += zutil.o
++
++asm-obj-$(CONFIG_M586)          += match586.o
++asm-obj-$(CONFIG_M586TSC)       += match586.o
++asm-obj-$(CONFIG_M586MMX)       += match586.o
++asm-obj-$(CONFIG_M686)          += match686.o
++asm-obj-$(CONFIG_MPENTIUMIII)   += match686.o
++asm-obj-$(CONFIG_MPENTIUM4)     += match686.o
++asm-obj-$(CONFIG_MK6)           += match586.o
++asm-obj-$(CONFIG_MK7)           += match686.o
++asm-obj-$(CONFIG_MCRUSOE)       += match586.o
++asm-obj-$(CONFIG_MWINCHIPC6)    += match586.o
++asm-obj-$(CONFIG_MWINCHIP2)     += match686.o
++asm-obj-$(CONFIG_MWINCHIP3D)    += match686.o
++
++export-objs := radij.o
++obj-m += $(O_TARGET)
++
++
++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_KLIPS_DEBUG),y)
++#EXTRA_CFLAGS += -g
++#endif
++
++# MOST of these flags are in KERNEL_CFLAGS already!
++
++# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM
++# include/linux/highmem.h has an inline function definition that uses void* arithmentic.
++ifeq ($(CONFIG_NOHIGHMEM),y)
++#EXTRA_CFLAGS += -Wpointer-arith 
++endif
++#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 
++EXTRA_CFLAGS += -DIPCOMP_PREFIX
++
++ifneq ($(strip $(KLIPSMODULE)),)
++# for when we aren't building in the kernel tree
++EXTRA_CFLAGS += -DARCH=${ARCH} 
++EXTRA_CFLAGS += -DMODVERSIONS
++EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h
++EXTRA_CFLAGS += ${MODULE_CFLAGS} 
++endif
++
++# GCC 3.2 (and we presume any other 3.x) wants -falign-functions
++# in place of the traditional -malign-functions.  Getting this
++# wrong leads to a warning, which is fatal due to our use of -Werror.
++ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3)
++override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS))
++endif
++
++
++obj-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
++obj-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
++
++# 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)
++
++include $(TOPDIR)/Rules.make
++
++$(obj-y) $(obj-m):  $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
++
++USE_STANDARD_AS_RULE=true
++
++clean:
++	-rm -f *.o
++	-rm -f .*.o.flags
++
++tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
++	etags *.c ../../include/*.h ../../include/freeswan/*.h
++	ctags *.c ../../include/*.h ../../include/freeswan/*.h
++
++tar:
++		tar -cvf /dev/f1 .
++
++#
++# $Log: Makefile,v $
++# Revision 1.4  2005/02/03 12:45:49  r05549
++# *** empty log message ***
++#
++# Revision 1.3  2004/12/16 06:28:08  rupert
++# *: fix condition for crypto Engine
++#
++# Revision 1.2  2004/12/10 08:45:20  yjlou
++# +: support ACLDB and IPSEC (20Mbps)
++#
++# Revision 1.1  2004/08/02 02:09:58  rupert
++# +: Add Freeswan IPSec 2.06
++#
++# Revision 1.3  2004/02/24 17:17:04  mcr
++# 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++# 	turn it on/off as well.
++#
++# Revision 1.2  2004/02/22 06:50:42  mcr
++# 	kernel 2.6 port - merged with 2.4 code.
++#
++# Revision 1.1  2004/02/14 21:59:19  mcr
++# 	split up Makefile into kernel specific versions.
++#
++# Revision 1.68  2003/12/15 20:38:11  mcr
++# 	make sure that IPIP is always on.
++#
++# Revision 1.67  2003/12/15 15:42:27  mcr
++# 	make sure that ESP is always on, and AH is no more.
++#
++# Revision 1.66  2003/12/13 04:09:21  mcr
++# 	AH transform removed.
++#
++# Revision 1.65  2003/12/11 20:15:04  mcr
++# 	refactored the xmit code, to move all encapsulation
++# 	code into protocol functions. Note that all functions
++# 	are essentially done by a single function, which is probably
++# 	wrong.
++# 	the rcv_functions structures are renamed xform_functions.
++#
++# Revision 1.64  2003/12/06 21:21:38  mcr
++# 	split up receive path into per-transform files, for
++# 	easier later removal.
++#
++# Revision 1.63  2003/11/07 02:58:06  mcr
++# 	backout of port-selector and X.509 patches
++#
++# Revision 1.61  2003/06/22 21:07:46  mcr
++# 	adjusted TAGS target in makefile to be useful in 2.00 source layout.
++#
++# Revision 1.60  2003/05/03 23:45:23  mcr
++# 	rm .o.flags and generated version.c file.
++#
++# Revision 1.59  2003/02/12 19:32:47  rgb
++# Added ipsec_xmit to the list of object files.
++#
++# Revision 1.58  2003/01/03 00:36:44  rgb
++#
++# Added emacs compile-command.
++#
++# Revision 1.57  2002/11/08 23:49:53  mcr
++# 	use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list
++# 	of include directories.
++# 	This also eliminates some of the guesswork in the kernel
++# 	configuration file.
++#
++# Revision 1.56  2002/11/08 23:23:18  mcr
++# 	attempt to guess kernel compilation flags (i.e. list of -I)
++# 	by using some magic targets in the kernel makefile.
++#
++# Revision 1.55  2002/11/08 10:13:33  mcr
++# 	added additional include directories for module builds for 2.4.19.
++#
++# Revision 1.54  2002/10/20 06:10:30  build
++# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues.
++#
++# Revision 1.53  2002/10/17 16:32:01  mcr
++# 	enable standard AS rules.
++#
++# Revision 1.52  2002/10/06 06:13:44  sam
++# Altering order of includes, so that architecture-specific header files,
++# used for building RPM modules specifically, are processed first.
++#
++# Revision 1.51  2002/10/05 15:06:38  dhr
++#
++# - To allow for gcc3.2 (used in Red Hat Linux 8.0):  adjust CFLAGS (set
++#   by kernel machinery) to use -falign-functions= in place of
++#   -malign-functions=.  Eliminates a warning (fatal with -Werror).
++#
++# - When CONFIG_HIGHMEM is on, -Wpointer-arith will warn about
++#   include/linux/highmem.h.  Since this is fatal with -Werror, we
++#   suppress -Wpointer-arith if CONFIG_HIGHMEM is set.
++#
++# Revision 1.50  2002/09/16 21:19:45  mcr
++# 	enable -Werror for production - this helps a lot (found a bug in ipsec_rcv.c)
++#
++# Revision 1.49  2002/07/29 05:12:39  mcr
++# 	get rid of some extraneous stuff, now handled by a prefix
++# 	Makefile when building as a module.
++#
++# Revision 1.48  2002/07/28 23:13:49  mcr
++# 	set KLIPS_TOP and use it instead of ../..
++# 	if KLIPSMODULE, then include a bunch of stuff defined in Makefile.inc
++# 	that gets us the "typical" configuration that we want.
++#
++# Revision 1.47  2002/06/02 21:51:41  mcr
++# 	changed TOPDIR->FREESWANSRCDIR in all Makefiles.
++# 	(note that linux/net/ipsec/Makefile uses TOPDIR because this is the
++# 	kernel sense.)
++#
++# Revision 1.46  2002/05/14 02:35:51  rgb
++# Added file pfkey_v2_ext_process.c.
++#
++# Revision 1.45  2002/05/13 17:21:40  mcr
++# 	mkdep dies when given a -I to a directory that does not exist.
++# 	arch/${ARCH}/include is for UM arch only, so include it for that
++# 	ARCH only.
++#
++# Revision 1.44  2002/04/24 20:38:12  mcr
++# 	moved more stuff behind $KLIPSMODULE=y to get static linking to work.
++#
++# Revision 1.43  2002/04/24 09:16:18  mcr
++# 	include local Makefile.ver as well as FS_rootdir version.
++#
++# Revision 1.42  2002/04/24 08:50:08  mcr
++# 	critical patch is to set TOPDIR with :=.
++#
++# Revision 1.40  2002/04/24 00:41:07  mcr
++# Moved from ./klips/net/ipsec/Makefile,v
++#
++# 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 at 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 ***
++#
++#
++# Local Variables:
++# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
++# End Variables:
++#
++
+diff --git a/net/ipsec/Makefile.fs2_0 b/net/ipsec/Makefile.fs2_0
+new file mode 100644
+index 0000000..64734a4
+--- /dev/null
++++ b/net/ipsec/Makefile.fs2_0
+@@ -0,0 +1,493 @@
++# Makefile for KLIPS kernel code as a module	for 2.0 kernels
++#
++# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
++# Copyright (C) 2002	Michael Richardson <mcr at 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: Makefile.fs2_0,v 1.1.1.1 2004/08/20 11:34:10 r04482 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).
++#
++
++ifeq ($(strip $(KLIPSMODULE)),)
++FREESWANSRCDIR=.
++else
++FREESWANSRCDIR=../../..
++endif
++-include ${FREESWANSRCDIR}/Makefile.ver
++
++ifeq ($(strip $(KLIPS_TOP)),)
++KLIPS_TOP=../..
++endif
++
++ifneq ($(strip $(KLIPSMODULE)),)
++
++ifndef TOPDIR
++TOPDIR:=/usr/src/linux
++endif
++export TOPDIR
++
++endif
++
++#
++# This magic from User-Mode-Linux list. It gets list of -I options, as
++# UML needs some extra, that varry by revision.
++#
++KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)'   )
++
++MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)'  )
++
++subdir-  := 
++subdir-n := 
++subdir-y :=
++subdir-m :=
++
++
++MOD_DESTDIR:=net/ipsec
++
++export TOPDIR
++
++all: ipsec.o
++
++foo:
++	echo KERNEL: ${KERNEL_CFLAGS}
++	echo MODULE: ${MODULE_CFLAGS}
++
++ipsec.o: foo
++
++# always force it on
++CONFIG_IPSEC_ESP:=y
++CONFIG_IPSEC_IPIP:=y
++
++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_xmit.o ipsec_rcv.o ipsec_ipip.o
++obj-y += sysctl_net_ipsec.o 
++obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o 
++obj-y += version.o
++obj-$(CONFIG_IPSEC_ESP)+= ipsec_esp.o
++obj-$(CONFIG_IPSEC_IPCOMP)+= ipsec_ipcomp.o
++
++# not included in normal distribution
++#obj-$(CONFIG_IPSEC_AH) += ipsec_ah.o
++
++LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des
++VPATH+= ${LIBDESDIR}
++
++include ${LIBDESDIR}/Makefile.objs
++
++LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan
++VPATH+=${LIBFREESWANDIR}
++
++include ${LIBFREESWANDIR}/Makefile.objs
++
++# IPcomp stuff
++obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o 
++
++LIBZLIBSRCDIR=${KLIPS_TOP}/lib/zlib
++VPATH+=${LIBZLIBSRCDIR}
++
++include ${LIBZLIBSRCDIR}/Makefile.objs
++
++export-objs := radij.o
++obj-m += $(O_TARGET)
++
++
++# include file with .h-style macros that would otherwise be created by
++# config. Must occur before other includes.
++ifneq ($(strip $(MODULE_DEF_INCLUDE)),)
++EXTRA_CFLAGS += -include ${MODULE_DEF_INCLUDE}
++endif
++
++# 'override CFLAGS' should really be 'EXTRA_CFLAGS'
++#EXTRA_CFLAGS += -nostdinc
++EXTRA_CFLAGS += -I${KLIPS_TOP}/include
++
++EXTRA_CFLAGS += -I${TOPDIR}/include 
++EXTRA_CFLAGS += -I${LIBZLIBSRCDIR}
++
++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
++
++# MOST of these flags are in KERNEL_CFLAGS already!
++
++EXTRA_CFLAGS += $(KLIPSCOMPILE)
++EXTRA_CFLAGS += -Wall
++#EXTRA_CFLAGS += -Werror
++#EXTRA_CFLAGS += -Wconversion 
++#EXTRA_CFLAGS += -Wmissing-prototypes 
++# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM
++# include/linux/highmem.h has an inline function definition that uses void* arithmentic.
++ifeq ($(CONFIG_NOHIGHMEM),y)
++EXTRA_CFLAGS += -Wpointer-arith 
++endif
++#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 
++
++ifneq ($(strip $(KLIPSMODULE)),)
++# for when we aren't building in the kernel tree
++EXTRA_CFLAGS += -DARCH=${ARCH} 
++EXTRA_CFLAGS += -DMODVERSIONS
++EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h
++EXTRA_CFLAGS += ${MODULE_CFLAGS} 
++endif
++
++EXTRA_CFLAGS += ${KERNEL_CFLAGS}
++
++
++# GCC 3.2 (and we presume any other 3.x) wants -falign-functions
++# in place of the traditional -malign-functions.  Getting this
++# wrong leads to a warning, which is fatal due to our use of -Werror.
++ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3)
++override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS))
++endif
++
++
++obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o
++obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o
++
++# 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)
++
++include $(TOPDIR)/Rules.make
++
++$(obj-y) $(obj-m):  $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
++
++USE_STANDARD_AS_RULE=true
++
++clean:
++	-rm -f *.o
++	-rm -f .*.o.flags
++	-rm version.c
++
++tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
++	etags *.c ../../include/*.h ../../include/freeswan/*.h
++	ctags *.c ../../include/*.h ../../include/freeswan/*.h
++
++tar:
++		tar -cvf /dev/f1 .
++
++#
++# $Log: Makefile.fs2_0,v $
++# Revision 1.1.1.1  2004/08/20 11:34:10  r04482
++# no message
++#
++# Revision 1.1  2004/08/02 02:09:58  rupert
++# +: Add Freeswan IPSec 2.06
++#
++# Revision 1.1  2004/02/14 21:59:19  mcr
++# 	split up Makefile into kernel specific versions.
++#
++# Revision 1.68  2003/12/15 20:38:11  mcr
++# 	make sure that IPIP is always on.
++#
++# Revision 1.67  2003/12/15 15:42:27  mcr
++# 	make sure that ESP is always on, and AH is no more.
++#
++# Revision 1.66  2003/12/13 04:09:21  mcr
++# 	AH transform removed.
++#
++# Revision 1.65  2003/12/11 20:15:04  mcr
++# 	refactored the xmit code, to move all encapsulation
++# 	code into protocol functions. Note that all functions
++# 	are essentially done by a single function, which is probably
++# 	wrong.
++# 	the rcv_functions structures are renamed xform_functions.
++#
++# Revision 1.64  2003/12/06 21:21:38  mcr
++# 	split up receive path into per-transform files, for
++# 	easier later removal.
++#
++# Revision 1.63  2003/11/07 02:58:06  mcr
++# 	backout of port-selector and X.509 patches
++#
++# Revision 1.61  2003/06/22 21:07:46  mcr
++# 	adjusted TAGS target in makefile to be useful in 2.00 source layout.
++#
++# Revision 1.60  2003/05/03 23:45:23  mcr
++# 	rm .o.flags and generated version.c file.
++#
++# Revision 1.59  2003/02/12 19:32:47  rgb
++# Added ipsec_xmit to the list of object files.
++#
++# Revision 1.58  2003/01/03 00:36:44  rgb
++#
++# Added emacs compile-command.
++#
++# Revision 1.57  2002/11/08 23:49:53  mcr
++# 	use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list
++# 	of include directories.
++# 	This also eliminates some of the guesswork in the kernel
++# 	configuration file.
++#
++# Revision 1.56  2002/11/08 23:23:18  mcr
++# 	attempt to guess kernel compilation flags (i.e. list of -I)
++# 	by using some magic targets in the kernel makefile.
++#
++# Revision 1.55  2002/11/08 10:13:33  mcr
++# 	added additional include directories for module builds for 2.4.19.
++#
++# Revision 1.54  2002/10/20 06:10:30  build
++# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues.
++#
++# Revision 1.53  2002/10/17 16:32:01  mcr
++# 	enable standard AS rules.
++#
++# Revision 1.52  2002/10/06 06:13:44  sam
++# Altering order of includes, so that architecture-specific header files,
++# used for building RPM modules specifically, are processed first.
++#
++# Revision 1.51  2002/10/05 15:06:38  dhr
++#
++# - To allow for gcc3.2 (used in Red Hat Linux 8.0):  adjust CFLAGS (set
++#   by kernel machinery) to use -falign-functions= in place of
++#   -malign-functions=.  Eliminates a warning (fatal with -Werror).
++#
++# - When CONFIG_HIGHMEM is on, -Wpointer-arith will warn about
++#   include/linux/highmem.h.  Since this is fatal with -Werror, we
++#   suppress -Wpointer-arith if CONFIG_HIGHMEM is set.
++#
++# Revision 1.50  2002/09/16 21:19:45  mcr
++# 	enable -Werror for production - this helps a lot (found a bug in ipsec_rcv.c)
++#
++# Revision 1.49  2002/07/29 05:12:39  mcr
++# 	get rid of some extraneous stuff, now handled by a prefix
++# 	Makefile when building as a module.
++#
++# Revision 1.48  2002/07/28 23:13:49  mcr
++# 	set KLIPS_TOP and use it instead of ../..
++# 	if KLIPSMODULE, then include a bunch of stuff defined in Makefile.inc
++# 	that gets us the "typical" configuration that we want.
++#
++# Revision 1.47  2002/06/02 21:51:41  mcr
++# 	changed TOPDIR->FREESWANSRCDIR in all Makefiles.
++# 	(note that linux/net/ipsec/Makefile uses TOPDIR because this is the
++# 	kernel sense.)
++#
++# Revision 1.46  2002/05/14 02:35:51  rgb
++# Added file pfkey_v2_ext_process.c.
++#
++# Revision 1.45  2002/05/13 17:21:40  mcr
++# 	mkdep dies when given a -I to a directory that does not exist.
++# 	arch/${ARCH}/include is for UM arch only, so include it for that
++# 	ARCH only.
++#
++# Revision 1.44  2002/04/24 20:38:12  mcr
++# 	moved more stuff behind $KLIPSMODULE=y to get static linking to work.
++#
++# Revision 1.43  2002/04/24 09:16:18  mcr
++# 	include local Makefile.ver as well as FS_rootdir version.
++#
++# Revision 1.42  2002/04/24 08:50:08  mcr
++# 	critical patch is to set TOPDIR with :=.
++#
++# Revision 1.40  2002/04/24 00:41:07  mcr
++# Moved from ./klips/net/ipsec/Makefile,v
++#
++# 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 at 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 ***
++#
++#
++# Local Variables:
++# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
++# End Variables:
++#
++
+diff --git a/net/ipsec/Makefile.fs2_2 b/net/ipsec/Makefile.fs2_2
+new file mode 100644
+index 0000000..7b4e053
+--- /dev/null
++++ b/net/ipsec/Makefile.fs2_2
+@@ -0,0 +1,494 @@
++# Makefile for KLIPS kernel code as a module    for 2.2 kernels
++#
++# Makefile for KLIPS kernel code as a module
++# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
++# Copyright (C) 2002	Michael Richardson <mcr at 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: Makefile.fs2_2,v 1.1.1.1 2004/08/20 11:34:10 r04482 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).
++#
++
++ifeq ($(strip $(KLIPSMODULE)),)
++FREESWANSRCDIR=.
++else
++FREESWANSRCDIR=../../..
++endif
++-include ${FREESWANSRCDIR}/Makefile.ver
++
++ifeq ($(strip $(KLIPS_TOP)),)
++KLIPS_TOP=../..
++endif
++
++ifneq ($(strip $(KLIPSMODULE)),)
++
++ifndef TOPDIR
++TOPDIR:=/usr/src/linux
++endif
++export TOPDIR
++
++endif
++
++#
++# This magic from User-Mode-Linux list. It gets list of -I options, as
++# UML needs some extra, that varry by revision.
++#
++KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)'   )
++
++MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)'  )
++
++subdir-  := 
++subdir-n := 
++subdir-y :=
++subdir-m :=
++
++
++MOD_DESTDIR:=net/ipsec
++
++export TOPDIR
++
++all: ipsec.o
++
++foo:
++	echo KERNEL: ${KERNEL_CFLAGS}
++	echo MODULE: ${MODULE_CFLAGS}
++
++ipsec.o: foo
++
++# always force it on
++CONFIG_IPSEC_ESP:=y
++CONFIG_IPSEC_IPIP:=y
++
++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_xmit.o ipsec_rcv.o ipsec_ipip.o
++obj-y += sysctl_net_ipsec.o 
++obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o 
++obj-y += version.o
++obj-$(CONFIG_IPSEC_ESP)+= ipsec_esp.o
++obj-$(CONFIG_IPSEC_IPCOMP)+= ipsec_ipcomp.o
++
++# not included in normal distribution
++#obj-$(CONFIG_IPSEC_AH) += ipsec_ah.o
++
++LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des
++VPATH+= ${LIBDESDIR}
++
++include ${LIBDESDIR}/Makefile.objs
++
++LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan
++VPATH+=${LIBFREESWANDIR}
++
++include ${LIBFREESWANDIR}/Makefile.objs
++
++# IPcomp stuff
++obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o 
++
++LIBZLIBSRCDIR=${KLIPS_TOP}/lib/zlib
++VPATH+=${LIBZLIBSRCDIR}
++
++include ${LIBZLIBSRCDIR}/Makefile.objs
++
++export-objs := radij.o
++obj-m += $(O_TARGET)
++
++
++# include file with .h-style macros that would otherwise be created by
++# config. Must occur before other includes.
++ifneq ($(strip $(MODULE_DEF_INCLUDE)),)
++EXTRA_CFLAGS += -include ${MODULE_DEF_INCLUDE}
++endif
++
++# 'override CFLAGS' should really be 'EXTRA_CFLAGS'
++#EXTRA_CFLAGS += -nostdinc
++EXTRA_CFLAGS += -I${KLIPS_TOP}/include
++
++EXTRA_CFLAGS += -I${TOPDIR}/include 
++EXTRA_CFLAGS += -I${LIBZLIBSRCDIR}
++
++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
++
++# MOST of these flags are in KERNEL_CFLAGS already!
++
++EXTRA_CFLAGS += $(KLIPSCOMPILE)
++EXTRA_CFLAGS += -Wall
++#EXTRA_CFLAGS += -Werror
++#EXTRA_CFLAGS += -Wconversion 
++#EXTRA_CFLAGS += -Wmissing-prototypes 
++# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM
++# include/linux/highmem.h has an inline function definition that uses void* arithmentic.
++ifeq ($(CONFIG_NOHIGHMEM),y)
++EXTRA_CFLAGS += -Wpointer-arith 
++endif
++#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 
++
++ifneq ($(strip $(KLIPSMODULE)),)
++# for when we aren't building in the kernel tree
++EXTRA_CFLAGS += -DARCH=${ARCH} 
++EXTRA_CFLAGS += -DMODVERSIONS
++EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h
++EXTRA_CFLAGS += ${MODULE_CFLAGS} 
++endif
++
++EXTRA_CFLAGS += ${KERNEL_CFLAGS}
++
++
++# GCC 3.2 (and we presume any other 3.x) wants -falign-functions
++# in place of the traditional -malign-functions.  Getting this
++# wrong leads to a warning, which is fatal due to our use of -Werror.
++ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3)
++override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS))
++endif
++
++
++obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o
++obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o
++
++# 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)
++
++include $(TOPDIR)/Rules.make
++
++$(obj-y) $(obj-m):  $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
++
++USE_STANDARD_AS_RULE=true
++
++clean:
++	-rm -f *.o
++	-rm -f .*.o.flags
++	-rm version.c
++
++tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
++	etags *.c ../../include/*.h ../../include/freeswan/*.h
++	ctags *.c ../../include/*.h ../../include/freeswan/*.h
++
++tar:
++		tar -cvf /dev/f1 .
++
++#
++# $Log: Makefile.fs2_2,v $
++# Revision 1.1.1.1  2004/08/20 11:34:10  r04482
++# no message
++#
++# Revision 1.1  2004/08/02 02:09:58  rupert
++# +: Add Freeswan IPSec 2.06
++#
++# Revision 1.1  2004/02/14 21:59:19  mcr
++# 	split up Makefile into kernel specific versions.
++#
++# Revision 1.68  2003/12/15 20:38:11  mcr
++# 	make sure that IPIP is always on.
++#
++# Revision 1.67  2003/12/15 15:42:27  mcr
++# 	make sure that ESP is always on, and AH is no more.
++#
++# Revision 1.66  2003/12/13 04:09:21  mcr
++# 	AH transform removed.
++#
++# Revision 1.65  2003/12/11 20:15:04  mcr
++# 	refactored the xmit code, to move all encapsulation
++# 	code into protocol functions. Note that all functions
++# 	are essentially done by a single function, which is probably
++# 	wrong.
++# 	the rcv_functions structures are renamed xform_functions.
++#
++# Revision 1.64  2003/12/06 21:21:38  mcr
++# 	split up receive path into per-transform files, for
++# 	easier later removal.
++#
++# Revision 1.63  2003/11/07 02:58:06  mcr
++# 	backout of port-selector and X.509 patches
++#
++# Revision 1.61  2003/06/22 21:07:46  mcr
++# 	adjusted TAGS target in makefile to be useful in 2.00 source layout.
++#
++# Revision 1.60  2003/05/03 23:45:23  mcr
++# 	rm .o.flags and generated version.c file.
++#
++# Revision 1.59  2003/02/12 19:32:47  rgb
++# Added ipsec_xmit to the list of object files.
++#
++# Revision 1.58  2003/01/03 00:36:44  rgb
++#
++# Added emacs compile-command.
++#
++# Revision 1.57  2002/11/08 23:49:53  mcr
++# 	use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list
++# 	of include directories.
++# 	This also eliminates some of the guesswork in the kernel
++# 	configuration file.
++#
++# Revision 1.56  2002/11/08 23:23:18  mcr
++# 	attempt to guess kernel compilation flags (i.e. list of -I)
++# 	by using some magic targets in the kernel makefile.
++#
++# Revision 1.55  2002/11/08 10:13:33  mcr
++# 	added additional include directories for module builds for 2.4.19.
++#
++# Revision 1.54  2002/10/20 06:10:30  build
++# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues.
++#
++# Revision 1.53  2002/10/17 16:32:01  mcr
++# 	enable standard AS rules.
++#
++# Revision 1.52  2002/10/06 06:13:44  sam
++# Altering order of includes, so that architecture-specific header files,
++# used for building RPM modules specifically, are processed first.
++#
++# Revision 1.51  2002/10/05 15:06:38  dhr
++#
++# - To allow for gcc3.2 (used in Red Hat Linux 8.0):  adjust CFLAGS (set
++#   by kernel machinery) to use -falign-functions= in place of
++#   -malign-functions=.  Eliminates a warning (fatal with -Werror).
++#
++# - When CONFIG_HIGHMEM is on, -Wpointer-arith will warn about
++#   include/linux/highmem.h.  Since this is fatal with -Werror, we
++#   suppress -Wpointer-arith if CONFIG_HIGHMEM is set.
++#
++# Revision 1.50  2002/09/16 21:19:45  mcr
++# 	enable -Werror for production - this helps a lot (found a bug in ipsec_rcv.c)
++#
++# Revision 1.49  2002/07/29 05:12:39  mcr
++# 	get rid of some extraneous stuff, now handled by a prefix
++# 	Makefile when building as a module.
++#
++# Revision 1.48  2002/07/28 23:13:49  mcr
++# 	set KLIPS_TOP and use it instead of ../..
++# 	if KLIPSMODULE, then include a bunch of stuff defined in Makefile.inc
++# 	that gets us the "typical" configuration that we want.
++#
++# Revision 1.47  2002/06/02 21:51:41  mcr
++# 	changed TOPDIR->FREESWANSRCDIR in all Makefiles.
++# 	(note that linux/net/ipsec/Makefile uses TOPDIR because this is the
++# 	kernel sense.)
++#
++# Revision 1.46  2002/05/14 02:35:51  rgb
++# Added file pfkey_v2_ext_process.c.
++#
++# Revision 1.45  2002/05/13 17:21:40  mcr
++# 	mkdep dies when given a -I to a directory that does not exist.
++# 	arch/${ARCH}/include is for UM arch only, so include it for that
++# 	ARCH only.
++#
++# Revision 1.44  2002/04/24 20:38:12  mcr
++# 	moved more stuff behind $KLIPSMODULE=y to get static linking to work.
++#
++# Revision 1.43  2002/04/24 09:16:18  mcr
++# 	include local Makefile.ver as well as FS_rootdir version.
++#
++# Revision 1.42  2002/04/24 08:50:08  mcr
++# 	critical patch is to set TOPDIR with :=.
++#
++# Revision 1.40  2002/04/24 00:41:07  mcr
++# Moved from ./klips/net/ipsec/Makefile,v
++#
++# 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 at 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 ***
++#
++#
++# Local Variables:
++# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
++# End Variables:
++#
++
+diff --git a/net/ipsec/Makefile.fs2_4 b/net/ipsec/Makefile.fs2_4
+new file mode 100644
+index 0000000..301e126
+--- /dev/null
++++ b/net/ipsec/Makefile.fs2_4
+@@ -0,0 +1,521 @@
++# Makefile for KLIPS kernel code as a module    for 2.4 kernels
++#
++# Makefile for KLIPS kernel code as a module
++# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
++# Copyright (C) 2002	Michael Richardson <mcr at 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: Makefile.fs2_4,v 1.1.1.1 2004/08/20 11:34:10 r04482 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).
++#
++
++ifeq ($(strip $(KLIPSMODULE)),)
++FREESWANSRCDIR=.
++else
++FREESWANSRCDIR=../../..
++endif
++-include ${FREESWANSRCDIR}/Makefile.ver
++
++ifeq ($(strip $(KLIPS_TOP)),)
++KLIPS_TOP=../..
++endif
++
++ifneq ($(strip $(KLIPSMODULE)),)
++
++ifndef TOPDIR
++TOPDIR:=/usr/src/linux
++endif
++export TOPDIR
++
++endif
++
++subdir-  := 
++subdir-n := 
++subdir-y :=
++subdir-m :=
++
++
++MOD_DESTDIR:=net/ipsec
++
++export TOPDIR
++
++all: ipsec.o
++
++foo:
++	echo KERNEL: ${KERNEL_CFLAGS}
++	echo MODULE: ${MODULE_CFLAGS}
++
++ipsec.o: foo
++
++# always force it on
++CONFIG_KLIPS_ESP:=y
++CONFIG_KLIPS_IPIP:=y
++
++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_xmit.o ipsec_rcv.o ipsec_ipip.o
++obj-y += sysctl_net_ipsec.o 
++obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o 
++obj-y += version.o
++obj-$(CONFIG_KLIPS_ESP)+= ipsec_esp.o
++obj-$(CONFIG_KLIPS_IPCOMP)+= ipsec_ipcomp.o
++
++# not included in normal distribution
++#obj-$(CONFIG_KLIPS_AH) += ipsec_ah.o
++
++LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des
++
++obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
++obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
++obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
++#obj-$(CONFIG_KLIPS_ENC_3DES) += des_opts.o
++#obj-$(CONFIG_KLIPS_ENC_3DES) += fcrypt.o
++
++ifeq ($(strip ${SUBARCH}),)
++SUBARCH:=${ARCH}
++endif
++
++ifeq (${SUBARCH},i386)
++obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
++else
++obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
++endif
++
++LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan
++
++obj-y += satot.o
++obj-y += addrtot.o
++obj-y += ultot.o 
++obj-y += addrtypeof.o
++obj-y += anyaddr.o
++obj-y += initaddr.o
++obj-y += ultoa.o 
++obj-y += addrtoa.o 
++obj-y += subnettoa.o 
++obj-y += subnetof.o 
++obj-y += goodmask.o 
++obj-y += datatot.o 
++obj-y += rangetoa.o 
++obj-y += prng.o 
++obj-y += pfkey_v2_parse.o 
++obj-y += pfkey_v2_build.o 
++obj-y += pfkey_v2_debug.o 
++obj-y += pfkey_v2_ext_bits.o 
++obj-y += version.o
++
++# IPcomp stuff
++obj-$(CONFIG_KLIPS_IPCOMP) += ipcomp.o 
++
++obj-$(CONFIG_KLIPS_IPCOMP) += adler32.o
++obj-$(CONFIG_KLIPS_IPCOMP) += deflate.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infblock.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infcodes.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inffast.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inflate.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inftrees.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infutil.o
++obj-$(CONFIG_KLIPS_IPCOMP) += trees.o
++obj-$(CONFIG_KLIPS_IPCOMP) += zutil.o
++
++asm-obj-$(CONFIG_M586)          += match586.o
++asm-obj-$(CONFIG_M586TSC)       += match586.o
++asm-obj-$(CONFIG_M586MMX)       += match586.o
++asm-obj-$(CONFIG_M686)          += match686.o
++asm-obj-$(CONFIG_MPENTIUMIII)   += match686.o
++asm-obj-$(CONFIG_MPENTIUM4)     += match686.o
++asm-obj-$(CONFIG_MK6)           += match586.o
++asm-obj-$(CONFIG_MK7)           += match686.o
++asm-obj-$(CONFIG_MCRUSOE)       += match586.o
++asm-obj-$(CONFIG_MWINCHIPC6)    += match586.o
++asm-obj-$(CONFIG_MWINCHIP2)     += match686.o
++asm-obj-$(CONFIG_MWINCHIP3D)    += match686.o
++
++export-objs := radij.o
++obj-m += $(O_TARGET)
++
++
++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_KLIPS_DEBUG),y)
++#EXTRA_CFLAGS += -g
++#endif
++
++# MOST of these flags are in KERNEL_CFLAGS already!
++
++# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM
++# include/linux/highmem.h has an inline function definition that uses void* arithmentic.
++ifeq ($(CONFIG_NOHIGHMEM),y)
++#EXTRA_CFLAGS += -Wpointer-arith 
++endif
++#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 
++EXTRA_CFLAGS += -DIPCOMP_PREFIX
++
++ifneq ($(strip $(KLIPSMODULE)),)
++# for when we aren't building in the kernel tree
++EXTRA_CFLAGS += -DARCH=${ARCH} 
++EXTRA_CFLAGS += -DMODVERSIONS
++EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h
++EXTRA_CFLAGS += ${MODULE_CFLAGS} 
++endif
++
++# GCC 3.2 (and we presume any other 3.x) wants -falign-functions
++# in place of the traditional -malign-functions.  Getting this
++# wrong leads to a warning, which is fatal due to our use of -Werror.
++ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3)
++override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS))
++endif
++
++
++obj-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
++obj-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
++
++# 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)
++
++include $(TOPDIR)/Rules.make
++
++$(obj-y) $(obj-m):  $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
++
++USE_STANDARD_AS_RULE=true
++
++clean:
++	-rm -f *.o
++	-rm -f .*.o.flags
++
++tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
++	etags *.c ../../include/*.h ../../include/freeswan/*.h
++	ctags *.c ../../include/*.h ../../include/freeswan/*.h
++
++tar:
++		tar -cvf /dev/f1 .
++
++#
++# $Log: Makefile.fs2_4,v $
++# Revision 1.1.1.1  2004/08/20 11:34:10  r04482
++# no message
++#
++# Revision 1.1  2004/08/02 02:09:58  rupert
++# +: Add Freeswan IPSec 2.06
++#
++# Revision 1.3  2004/02/24 17:17:04  mcr
++# 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++# 	turn it on/off as well.
++#
++# Revision 1.2  2004/02/22 06:50:42  mcr
++# 	kernel 2.6 port - merged with 2.4 code.
++#
++# Revision 1.1  2004/02/14 21:59:19  mcr
++# 	split up Makefile into kernel specific versions.
++#
++# Revision 1.68  2003/12/15 20:38:11  mcr
++# 	make sure that IPIP is always on.
++#
++# Revision 1.67  2003/12/15 15:42:27  mcr
++# 	make sure that ESP is always on, and AH is no more.
++#
++# Revision 1.66  2003/12/13 04:09:21  mcr
++# 	AH transform removed.
++#
++# Revision 1.65  2003/12/11 20:15:04  mcr
++# 	refactored the xmit code, to move all encapsulation
++# 	code into protocol functions. Note that all functions
++# 	are essentially done by a single function, which is probably
++# 	wrong.
++# 	the rcv_functions structures are renamed xform_functions.
++#
++# Revision 1.64  2003/12/06 21:21:38  mcr
++# 	split up receive path into per-transform files, for
++# 	easier later removal.
++#
++# Revision 1.63  2003/11/07 02:58:06  mcr
++# 	backout of port-selector and X.509 patches
++#
++# Revision 1.61  2003/06/22 21:07:46  mcr
++# 	adjusted TAGS target in makefile to be useful in 2.00 source layout.
++#
++# Revision 1.60  2003/05/03 23:45:23  mcr
++# 	rm .o.flags and generated version.c file.
++#
++# Revision 1.59  2003/02/12 19:32:47  rgb
++# Added ipsec_xmit to the list of object files.
++#
++# Revision 1.58  2003/01/03 00:36:44  rgb
++#
++# Added emacs compile-command.
++#
++# Revision 1.57  2002/11/08 23:49:53  mcr
++# 	use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list
++# 	of include directories.
++# 	This also eliminates some of the guesswork in the kernel
++# 	configuration file.
++#
++# Revision 1.56  2002/11/08 23:23:18  mcr
++# 	attempt to guess kernel compilation flags (i.e. list of -I)
++# 	by using some magic targets in the kernel makefile.
++#
++# Revision 1.55  2002/11/08 10:13:33  mcr
++# 	added additional include directories for module builds for 2.4.19.
++#
++# Revision 1.54  2002/10/20 06:10:30  build
++# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues.
++#
++# Revision 1.53  2002/10/17 16:32:01  mcr
++# 	enable standard AS rules.
++#
++# Revision 1.52  2002/10/06 06:13:44  sam
++# Altering order of includes, so that architecture-specific header files,
++# used for building RPM modules specifically, are processed first.
++#
++# Revision 1.51  2002/10/05 15:06:38  dhr
++#
++# - To allow for gcc3.2 (used in Red Hat Linux 8.0):  adjust CFLAGS (set
++#   by kernel machinery) to use -falign-functions= in place of
++#   -malign-functions=.  Eliminates a warning (fatal with -Werror).
++#
++# - When CONFIG_HIGHMEM is on, -Wpointer-arith will warn about
++#   include/linux/highmem.h.  Since this is fatal with -Werror, we
++#   suppress -Wpointer-arith if CONFIG_HIGHMEM is set.
++#
++# Revision 1.50  2002/09/16 21:19:45  mcr
++# 	enable -Werror for production - this helps a lot (found a bug in ipsec_rcv.c)
++#
++# Revision 1.49  2002/07/29 05:12:39  mcr
++# 	get rid of some extraneous stuff, now handled by a prefix
++# 	Makefile when building as a module.
++#
++# Revision 1.48  2002/07/28 23:13:49  mcr
++# 	set KLIPS_TOP and use it instead of ../..
++# 	if KLIPSMODULE, then include a bunch of stuff defined in Makefile.inc
++# 	that gets us the "typical" configuration that we want.
++#
++# Revision 1.47  2002/06/02 21:51:41  mcr
++# 	changed TOPDIR->FREESWANSRCDIR in all Makefiles.
++# 	(note that linux/net/ipsec/Makefile uses TOPDIR because this is the
++# 	kernel sense.)
++#
++# Revision 1.46  2002/05/14 02:35:51  rgb
++# Added file pfkey_v2_ext_process.c.
++#
++# Revision 1.45  2002/05/13 17:21:40  mcr
++# 	mkdep dies when given a -I to a directory that does not exist.
++# 	arch/${ARCH}/include is for UM arch only, so include it for that
++# 	ARCH only.
++#
++# Revision 1.44  2002/04/24 20:38:12  mcr
++# 	moved more stuff behind $KLIPSMODULE=y to get static linking to work.
++#
++# Revision 1.43  2002/04/24 09:16:18  mcr
++# 	include local Makefile.ver as well as FS_rootdir version.
++#
++# Revision 1.42  2002/04/24 08:50:08  mcr
++# 	critical patch is to set TOPDIR with :=.
++#
++# Revision 1.40  2002/04/24 00:41:07  mcr
++# Moved from ./klips/net/ipsec/Makefile,v
++#
++# 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 at 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 ***
++#
++#
++# Local Variables:
++# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
++# End Variables:
++#
++
+diff --git a/net/ipsec/Makefile.fs2_6 b/net/ipsec/Makefile.fs2_6
+new file mode 100644
+index 0000000..943f3f5
+--- /dev/null
++++ b/net/ipsec/Makefile.fs2_6
+@@ -0,0 +1,146 @@
++# Makefile for KLIPS kernel code as a module    for 2.6 kernels
++#
++# Makefile for KLIPS kernel code as a module
++# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
++# Copyright (C) 2002-2004	Michael Richardson <mcr at 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: Makefile.fs2_6,v 1.1.1.1 2004/08/20 11:34:10 r04482 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).
++#
++
++FREESWANSRCDIR=.
++KLIPS_TOP=.
++-include ${FREESWANSRCDIR}/Makefile.ver
++
++# always force it on
++CONFIG_KLIPS_ESP:=y
++CONFIG_KLIPS_IPIP:=y
++
++obj-$(CONFIG_KLIPS) := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
++obj-$(CONFIG_KLIPS) += ipsec_life.o ipsec_proc.o
++obj-$(CONFIG_KLIPS) += ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
++obj-$(CONFIG_KLIPS) += sysctl_net_ipsec.o 
++obj-$(CONFIG_KLIPS) += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o 
++obj-$(CONFIG_KLIPS) += version.o
++obj-$(CONFIG_KLIPS_ESP)+= ipsec_esp.o
++obj-$(CONFIG_KLIPS_IPCOMP)+= ipsec_ipcomp.o
++obj-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
++obj-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
++
++obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
++obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
++obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
++
++ifeq ($(strip ${SUBARCH}),)
++SUBARCH:=${ARCH}
++endif
++
++ifeq (${SUBARCH},i386)
++obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
++else
++obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
++endif
++
++
++obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
++#obj-$(CONFIG_KLIPS_ENC_3DES) += des_opts.o
++obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
++#obj-$(CONFIG_KLIPS_ENC_3DES) += fcrypt.o
++obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
++
++ifeq ($(strip ${SUBARCH}),)
++SUBARCH:=${ARCH}
++endif
++
++ifeq (${SUBARCH},i386)
++obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
++else
++obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
++endif
++
++obj-$(CONFIG_KLIPS) += satot.o
++obj-$(CONFIG_KLIPS) += addrtot.o
++obj-$(CONFIG_KLIPS) += ultot.o 
++obj-$(CONFIG_KLIPS) += addrtypeof.o
++obj-$(CONFIG_KLIPS) += anyaddr.o
++obj-$(CONFIG_KLIPS) += initaddr.o
++obj-$(CONFIG_KLIPS) += ultoa.o 
++obj-$(CONFIG_KLIPS) += addrtoa.o 
++obj-$(CONFIG_KLIPS) += subnettoa.o 
++obj-$(CONFIG_KLIPS) += subnetof.o 
++obj-$(CONFIG_KLIPS) += goodmask.o 
++obj-$(CONFIG_KLIPS) += datatot.o 
++obj-$(CONFIG_KLIPS) += rangetoa.o 
++obj-$(CONFIG_KLIPS) += prng.o 
++obj-$(CONFIG_KLIPS) += pfkey_v2_parse.o 
++obj-$(CONFIG_KLIPS) += pfkey_v2_build.o 
++obj-$(CONFIG_KLIPS) += pfkey_v2_debug.o 
++obj-$(CONFIG_KLIPS) += pfkey_v2_ext_bits.o 
++obj-$(CONFIG_KLIPS) += version.o
++
++# IPcomp stuff
++obj-$(CONFIG_KLIPS_IPCOMP) += ipcomp.o 
++
++obj-$(CONFIG_KLIPS_IPCOMP) += adler32.o
++obj-$(CONFIG_KLIPS_IPCOMP) += deflate.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infblock.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infcodes.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inffast.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inflate.o
++obj-$(CONFIG_KLIPS_IPCOMP) += inftrees.o
++obj-$(CONFIG_KLIPS_IPCOMP) += infutil.o
++obj-$(CONFIG_KLIPS_IPCOMP) += trees.o
++obj-$(CONFIG_KLIPS_IPCOMP) += zutil.o
++
++asm-obj-$(CONFIG_M586)          += match586.o
++asm-obj-$(CONFIG_M586TSC)       += match586.o
++asm-obj-$(CONFIG_M586MMX)       += match586.o
++asm-obj-$(CONFIG_M686)          += match686.o
++asm-obj-$(CONFIG_MPENTIUMIII)   += match686.o
++asm-obj-$(CONFIG_MPENTIUM4)     += match686.o
++asm-obj-$(CONFIG_MK6)           += match586.o
++asm-obj-$(CONFIG_MK7)           += match686.o
++asm-obj-$(CONFIG_MCRUSOE)       += match586.o
++asm-obj-$(CONFIG_MWINCHIPC6)    += match586.o
++asm-obj-$(CONFIG_MWINCHIP2)     += match686.o
++asm-obj-$(CONFIG_MWINCHIP3D)    += match686.o
++
++EXTRA_CFLAGS += -DIPCOMP_PREFIX
++
++#
++# $Log: Makefile.fs2_6,v $
++# Revision 1.1.1.1  2004/08/20 11:34:10  r04482
++# no message
++#
++# Revision 1.1  2004/08/02 02:09:58  rupert
++# +: Add Freeswan IPSec 2.06
++#
++# Revision 1.3  2004/02/24 17:17:04  mcr
++# 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++# 	turn it on/off as well.
++#
++# Revision 1.2  2004/02/22 06:50:42  mcr
++# 	kernel 2.6 port - merged with 2.4 code.
++#
++# Revision 1.1.2.1  2004/02/20 02:07:53  mcr
++# 	module configuration for KLIPS 2.6
++#
++#
++# Local Variables:
++# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
++# End Variables:
++#
++
+diff --git a/net/ipsec/addrtoa.c b/net/ipsec/addrtoa.c
+new file mode 100644
+index 0000000..02ddf19
+--- /dev/null
++++ b/net/ipsec/addrtoa.c
+@@ -0,0 +1,68 @@
++/*
++ * addresses to ASCII
++ * Copyright (C) 1998, 1999  Henry Spencer.
++ * 
++ * 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$
++ */
++#include "internal.h"
++#include "freeswan.h"
++
++#define	NBYTES	4		/* bytes in an address */
++#define	PERBYTE	4		/* three digits plus a dot or NUL */
++#define	BUFLEN	(NBYTES*PERBYTE)
++
++#if BUFLEN != ADDRTOA_BUF
++#error	"ADDRTOA_BUF in freeswan.h inconsistent with addrtoa() code"
++#endif
++
++/*
++ - addrtoa - convert binary address to ASCII dotted decimal
++ */
++size_t				/* space needed for full conversion */
++addrtoa(addr, format, dst, dstlen)
++struct in_addr addr;
++int format;			/* character */
++char *dst;			/* need not be valid if dstlen is 0 */
++size_t dstlen;
++{
++	unsigned long a = ntohl(addr.s_addr);
++	int i;
++	size_t n;
++	unsigned long byte;
++	char buf[BUFLEN];
++	char *p;
++
++	switch (format) {
++	case 0:
++		break;
++	default:
++		return 0;
++		break;
++	}
++
++	p = buf;
++	for (i = NBYTES-1; i >= 0; i--) {
++		byte = (a >> (i*8)) & 0xff;
++		p += ultoa(byte, 10, p, PERBYTE);
++		if (i != 0)
++			*(p-1) = '.';
++	}
++	n = p - buf;
++
++	if (dstlen > 0) {
++		if (n > dstlen)
++			buf[dstlen - 1] = '\0';
++		strcpy(dst, buf);
++	}
++	return n;
++}
+diff --git a/net/ipsec/addrtot.c b/net/ipsec/addrtot.c
+new file mode 100644
+index 0000000..50dd35d
+--- /dev/null
++++ b/net/ipsec/addrtot.c
+@@ -0,0 +1,328 @@
++/*
++ * addresses to text
++ * Copyright (C) 2000  Henry Spencer.
++ * 
++ * 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$
++ */
++#include "internal.h"
++#include "freeswan.h"
++
++#define	IP4BYTES	4	/* bytes in an IPv4 address */
++#define	PERBYTE		4	/* three digits plus a dot or NUL */
++#define	IP6BYTES	16	/* bytes in an IPv6 address */
++
++/* forwards */
++static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
++static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
++static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
++static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
++
++/*
++ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
++ */
++size_t				/* space needed for full conversion */
++addrtot(src, format, dst, dstlen)
++const ip_address *src;
++int format;			/* character */
++char *dst;			/* need not be valid if dstlen is 0 */
++size_t dstlen;
++{
++	const unsigned char *b;
++	size_t n;
++	char buf[1+ADDRTOT_BUF+1];	/* :address: */
++	char *p;
++	int t = addrtypeof(src);
++#	define	TF(t, f)	(((t)<<8) | (f))
++
++	n = addrbytesptr(src, &b);
++	if (n == 0) {
++	bad:
++	  dst[0]='\0';
++	  strncat(dst, "<invalid>", dstlen);
++	  return 0;
++	}
++
++	switch (TF(t, format)) {
++	case TF(AF_INET, 0):
++		n = normal4(b, n, buf, &p);
++		break;
++	case TF(AF_INET6, 0):
++		n = normal6(b, n, buf, &p, 1);
++		break;
++	case TF(AF_INET, 'Q'):
++		n = normal4(b, n, buf, &p);
++		break;
++	case TF(AF_INET6, 'Q'):
++		n = normal6(b, n, buf, &p, 0);
++		break;
++	case TF(AF_INET, 'r'):
++		n = reverse4(b, n, buf, &p);
++		break;
++	case TF(AF_INET6, 'r'):
++		n = reverse6(b, n, buf, &p);
++		break;
++	default:		/* including (AF_INET, 'R') */
++	        goto bad;
++		break;
++	}
++
++	if (dstlen > 0) {
++		if (dstlen < n)
++			p[dstlen - 1] = '\0';
++		strcpy(dst, p);
++	}
++	return n;
++}
++
++/*
++ - normal4 - normal IPv4 address-text conversion
++ */
++static size_t			/* size of text, including NUL */
++normal4(srcp, srclen, buf, dstp)
++const unsigned char *srcp;
++size_t srclen;
++char *buf;			/* guaranteed large enough */
++char **dstp;			/* where to put result pointer */
++{
++	int i;
++	char *p;
++
++	if (srclen != IP4BYTES)	/* "can't happen" */
++		return 0;
++	p = buf;
++	for (i = 0; i < IP4BYTES; i++) {
++		p += ultot(srcp[i], 10, p, PERBYTE);
++		if (i != IP4BYTES - 1)
++			*(p-1) = '.';	/* overwrites the NUL */
++	}
++	*dstp = buf;
++	return p - buf;
++}
++
++/*
++ - normal6 - normal IPv6 address-text conversion
++ */
++static size_t			/* size of text, including NUL */
++normal6(srcp, srclen, buf, dstp, squish)
++const unsigned char *srcp;
++size_t srclen;
++char *buf;			/* guaranteed large enough, plus 2 */
++char **dstp;			/* where to put result pointer */
++int    squish;                  /* whether to squish out 0:0 */
++{
++	int i;
++	unsigned long piece;
++	char *p;
++	char *q;
++
++	if (srclen != IP6BYTES)	/* "can't happen" */
++		return 0;
++	p = buf;
++	*p++ = ':';
++	for (i = 0; i < IP6BYTES/2; i++) {
++		piece = (srcp[2*i] << 8) + srcp[2*i + 1];
++		p += ultot(piece, 16, p, 5);	/* 5 = abcd + NUL */
++		*(p-1) = ':';	/* overwrites the NUL */
++	}
++	*p = '\0';
++	q = strstr(buf, ":0:0:");
++	if (squish && q != NULL) {	/* zero squishing is possible */
++		p = q + 1;
++		while (*p == '0' && *(p+1) == ':')
++			p += 2;
++		q++;
++		*q++ = ':';	/* overwrite first 0 */
++		while (*p != '\0')
++			*q++ = *p++;
++		*q = '\0';
++		if (!(*(q-1) == ':' && *(q-2) == ':'))
++			*--q = '\0';	/* strip final : unless :: */
++		p = buf;
++		if (!(*p == ':' && *(p+1) == ':'))
++			p++;	/* skip initial : unless :: */
++	} else {
++		q = p;
++		*--q = '\0';	/* strip final : */
++		p = buf + 1;	/* skip initial : */
++	}
++	*dstp = p;
++	return q - p + 1;
++}
++
++/*
++ - reverse4 - IPv4 reverse-lookup conversion
++ */
++static size_t			/* size of text, including NUL */
++reverse4(srcp, srclen, buf, dstp)
++const unsigned char *srcp;
++size_t srclen;
++char *buf;			/* guaranteed large enough */
++char **dstp;			/* where to put result pointer */
++{
++	int i;
++	char *p;
++
++	if (srclen != IP4BYTES)	/* "can't happen" */
++		return 0;
++	p = buf;
++	for (i = IP4BYTES-1; i >= 0; i--) {
++		p += ultot(srcp[i], 10, p, PERBYTE);
++		*(p-1) = '.';	/* overwrites the NUL */
++	}
++	strcpy(p, "IN-ADDR.ARPA.");
++	*dstp = buf;
++	return strlen(buf) + 1;
++}
++
++/*
++ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
++ * A trifle inefficient, really shouldn't use ultot...
++ */
++static size_t			/* size of text, including NUL */
++reverse6(srcp, srclen, buf, dstp)
++const unsigned char *srcp;
++size_t srclen;
++char *buf;			/* guaranteed large enough */
++char **dstp;			/* where to put result pointer */
++{
++	int i;
++	unsigned long piece;
++	char *p;
++
++	if (srclen != IP6BYTES)	/* "can't happen" */
++		return 0;
++	p = buf;
++	for (i = IP6BYTES-1; i >= 0; i--) {
++		piece = srcp[i];
++		p += ultot(piece&0xf, 16, p, 2);
++		*(p-1) = '.';
++		p += ultot(piece>>4, 16, p, 2);
++		*(p-1) = '.';
++	}
++	strcpy(p, "IP6.ARPA.");
++	*dstp = buf;
++	return strlen(buf) + 1;
++}
++
++/*
++ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
++ * this version removed as it was obsoleted in the end.
++ */
++
++#ifdef ADDRTOT_MAIN
++
++#include <stdio.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++
++void regress(void);
++
++int
++main(int argc, char *argv[])
++{
++	if (argc < 2) {
++		fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
++								argv[0]);
++		exit(2);
++	}
++
++	if (strcmp(argv[1], "-r") == 0) {
++		regress();
++		fprintf(stderr, "regress() returned?!?\n");
++		exit(1);
++	}
++	exit(0);
++}
++
++struct rtab {
++	char *input;
++        char  format;
++	char *output;			/* NULL means error expected */
++} rtab[] = {
++	{"1.2.3.0",			0, "1.2.3.0"},
++	{"1:2::3:4",                    0, "1:2::3:4"},
++	{"1:2::3:4",                   'Q', "1:2:0:0:0:0:3:4"},
++	{"1:2:0:0:3:4:0:0",             0, "1:2::3:4:0:0"},
++	{"1.2.3.4",                    'r' , "4.3.2.1.IN-ADDR.ARPA."},
++ 	/*                                    0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */
++	{"1:2::3:4",                   'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."},
++	 {NULL,				0, NULL}
++};
++
++void
++regress()
++{
++	struct rtab *r;
++	int status = 0;
++	ip_address a;
++	char in[100];
++	char buf[100];
++	const char *oops;
++	size_t n;
++
++	for (r = rtab; r->input != NULL; r++) {
++		strcpy(in, r->input);
++
++		/* convert it *to* internal format */
++		oops = ttoaddr(in, strlen(in), 0, &a);
++
++		/* now convert it back */
++
++		n = addrtot(&a, r->format, buf, sizeof(buf));
++
++		if (n == 0 && r->output == NULL)
++			{}		/* okay, error expected */
++		
++		else if (n == 0) {
++			printf("`%s' atoasr failed\n", r->input);
++			status = 1;
++			
++		} else if (r->output == NULL) {
++			printf("`%s' atoasr succeeded unexpectedly '%c'\n",
++							r->input, r->format);
++			status = 1;
++		} else {
++		  if (strcasecmp(r->output, buf) != 0) {
++		    printf("`%s' '%c' gave `%s', expected `%s'\n",
++			   r->input, r->format, buf, r->output);
++		    status = 1;
++		  }
++		}
++	}
++	exit(status);
++}
++
++#endif /* ADDRTOT_MAIN */
++
++/*
++ * $Log: addrtot.c,v $
++ * Revision 1.1.1.1  2004/08/20 11:34:10  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:09:58  rupert
++ * +: Add Freeswan IPSec 2.06
++ *
++ * Revision 1.2  2004/02/22 06:50:42  mcr
++ * 	kernel 2.6 port - merged with 2.4 code.
++ *
++ * Revision 1.1.2.1  2004/02/20 14:10:18  mcr
++ * 	moved code to net/ipsec/ to make 2.6 happy.
++ *
++ * Revision 1.13  2003/12/29 21:19:16  mcr
++ * 	fixes to satot() and addrtot() to properly terminate the
++ * 	string and to adjust the definition of special SAs.
++ *
++ *
++ */
++
+diff --git a/net/ipsec/addrtypeof.c b/net/ipsec/addrtypeof.c
+new file mode 100644
+index 0000000..ab303cc
+--- /dev/null
++++ b/net/ipsec/addrtypeof.c
+@@ -0,0 +1,94 @@
++/*
++ * extract parts of an ip_address
++ * Copyright (C) 2000  Henry Spencer.
++ * 
++ * 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$
++ */
++#include "internal.h"
++#include "freeswan.h"
++
++/*
++ - addrtypeof - get the type of an ip_address
++ */
++int
++addrtypeof(src)
++const ip_address *src;
++{
++	return src->u.v4.sin_family;
++}
++
++/*
++ - addrbytesptr - get pointer to the address bytes of an ip_address
++ */
++size_t				/* 0 for error */
++addrbytesptr(src, dstp)
++const ip_address *src;
++const unsigned char **dstp;	/* NULL means just a size query */
++{
++	const unsigned char *p;
++	size_t n;
++
++	switch (src->u.v4.sin_family) {
++	case AF_INET:
++		p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
++		n = 4;
++		break;
++	case AF_INET6:
++		p = (const unsigned char *)&src->u.v6.sin6_addr;
++		n = 16;
++		break;
++	default:
++		return 0;
++		break;
++	}
++
++	if (dstp != NULL)
++		*dstp = p;
++	return n;
++}
++
++/*
++ - addrlenof - get length of the address bytes of an ip_address
++ */
++size_t				/* 0 for error */
++addrlenof(src)
++const ip_address *src;
++{
++	return addrbytesptr(src, NULL);
++}
++
++/*
++ - addrbytesof - get the address bytes of an ip_address
++ */
++size_t				/* 0 for error */
++addrbytesof(src, dst, dstlen)
++const ip_address *src;
++unsigned char *dst;
++size_t dstlen;
++{
++	const unsigned char *p;
++	size_t n;
++	size_t ncopy;
++
++	n = addrbytesptr(src, &p);
++	if (n == 0)
++		return 0;
++
++	if (dstlen > 0) {
++		ncopy = n;
++		if (ncopy > dstlen)
++			ncopy = dstlen;
++		memcpy(dst, p, ncopy);
++	}
++	return n;
++}
+diff --git a/net/ipsec/adler32.c b/net/ipsec/adler32.c
+new file mode 100644
+index 0000000..d791786
+--- /dev/null
++++ b/net/ipsec/adler32.c
+@@ -0,0 +1,50 @@
++/* adler32.c -- compute the Adler-32 checksum of a data stream
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#define IPCOMP_PREFIX 1
++#include <zlib/zlib.h>
++#include "zconf.h"
++
++#define BASE 65521L /* largest prime smaller than 65536 */
++#define NMAX 5552
++/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
++
++#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
++#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
++#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
++#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
++#define DO16(buf)   DO8(buf,0); DO8(buf,8);
++
++/* ========================================================================= */
++uLong ZEXPORT adler32(adler, buf, len)
++    uLong adler;
++    const Bytef *buf;
++    uInt len;
++{
++    unsigned long s1 = adler & 0xffff;
++    unsigned long s2 = (adler >> 16) & 0xffff;
++    int k;
++
++    if (buf == Z_NULL) return 1L;
++
++    while (len > 0) {
++        k = len < NMAX ? len : NMAX;
++        len -= k;
++        while (k >= 16) {
++            DO16(buf);
++	    buf += 16;
++            k -= 16;
++        }
++        if (k != 0) do {
++            s1 += *buf++;
++	    s2 += s1;
++        } while (--k);
++        s1 %= BASE;
++        s2 %= BASE;
++    }
++    return (s2 << 16) | s1;
++}
+diff --git a/net/ipsec/anyaddr.c b/net/ipsec/anyaddr.c
+new file mode 100644
+index 0000000..9169a9c
+--- /dev/null
++++ b/net/ipsec/anyaddr.c
+@@ -0,0 +1,147 @@
++/*
++ * special addresses
++ * Copyright (C) 2000  Henry Spencer.
++ * 
++ * 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$
++ */
++#include "internal.h"
++#include "freeswan.h"
++
++/* these are mostly fallbacks for the no-IPv6-support-in-library case */
++#ifndef IN6ADDR_ANY_INIT
++#define	IN6ADDR_ANY_INIT	{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}
++#endif
++#ifndef IN6ADDR_LOOPBACK_INIT
++#define	IN6ADDR_LOOPBACK_INIT	{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
++#endif
++
++/* expect errors here when the above #define is not used */
++static struct in6_addr v6any = IN6ADDR_ANY_INIT;
++static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
++
++/*
++ - anyaddr - initialize to the any-address value
++ */
++err_t				/* NULL for success, else string literal */
++anyaddr(af, dst)
++int af;				/* address family */
++ip_address *dst;
++{
++	uint32_t v4any = htonl(INADDR_ANY);
++
++	switch (af) {
++	case AF_INET:
++		return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
++		break;
++	case AF_INET6:
++		return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
++		break;
++	default:
++		return "unknown address family in anyaddr/unspecaddr";
++		break;
++	}
++}
++
++/*
++ - unspecaddr - initialize to the unspecified-address value
++ */
++err_t				/* NULL for success, else string literal */
++unspecaddr(af, dst)
++int af;				/* address family */
++ip_address *dst;
++{
++	return anyaddr(af, dst);
++}
++
++/*
++ - loopbackaddr - initialize to the loopback-address value
++ */
++err_t				/* NULL for success, else string literal */
++loopbackaddr(af, dst)
++int af;				/* address family */
++ip_address *dst;
++{
++	uint32_t v4loop = htonl(INADDR_LOOPBACK);
++
++	switch (af) {
++	case AF_INET:
++		return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
++		break;
++	case AF_INET6:
++		return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
++		break;
++	default:
++		return "unknown address family in loopbackaddr";
++		break;
++	}
++}
++
++/*
++ - isanyaddr - test for the any-address value
++ */
++int
++isanyaddr(src)
++const ip_address *src;
++{
++	uint32_t v4any = htonl(INADDR_ANY);
++	int cmp;
++
++	switch (src->u.v4.sin_family) {
++	case AF_INET:
++		cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
++		break;
++	case AF_INET6:
++		cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
++		break;
++	default:
++		return 0;
++		break;
++	}
++
++	return (cmp == 0) ? 1 : 0;
++}
++
++/*
++ - isunspecaddr - test for the unspecified-address value
++ */
++int
++isunspecaddr(src)
++const ip_address *src;
++{
++	return isanyaddr(src);
++}
++
++/*
++ - isloopbackaddr - test for the loopback-address value
++ */
++int
++isloopbackaddr(src)
++const ip_address *src;
++{
++	uint32_t v4loop = htonl(INADDR_LOOPBACK);
++	int cmp;
++
++	switch (src->u.v4.sin_family) {
++	case AF_INET:
++		cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
++		break;
++	case AF_INET6:
++		cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
++		break;
++	default:
++		return 0;
++		break;
++	}
++
++	return (cmp == 0) ? 1 : 0;
++}
+diff --git a/net/ipsec/cbc_enc.c b/net/ipsec/cbc_enc.c
+new file mode 100644
+index 0000000..a06f9f9
+--- /dev/null
++++ b/net/ipsec/cbc_enc.c
+@@ -0,0 +1,135 @@
++/* crypto/des/cbc_enc.c */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++#include "des_locl.h"
++
++void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
++des_cblock (*input);
++des_cblock (*output);
++long length;
++des_key_schedule schedule;
++des_cblock (*ivec);
++int enc;
++	{
++	register DES_LONG tin0,tin1;
++	register DES_LONG tout0,tout1,xor0,xor1;
++	register unsigned char *in,*out;
++	register long l=length;
++	DES_LONG tin[2];
++	unsigned char *iv;
++
++	in=(unsigned char *)input;
++	out=(unsigned char *)output;
++	iv=(unsigned char *)ivec;
++
++	if (enc)
++		{
++		c2l(iv,tout0);
++		c2l(iv,tout1);
++		for (l-=8; l>=0; l-=8)
++			{
++			c2l(in,tin0);
++			c2l(in,tin1);
++			tin0^=tout0; tin[0]=tin0;
++			tin1^=tout1; tin[1]=tin1;
++			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
++			tout0=tin[0]; l2c(tout0,out);
++			tout1=tin[1]; l2c(tout1,out);
++			}
++		if (l != -8)
++			{
++			c2ln(in,tin0,tin1,l+8);
++			tin0^=tout0; tin[0]=tin0;
++			tin1^=tout1; tin[1]=tin1;
++			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
++			tout0=tin[0]; l2c(tout0,out);
++			tout1=tin[1]; l2c(tout1,out);
++			}
++		}
++	else
++		{
++		c2l(iv,xor0);
++		c2l(iv,xor1);
++		for (l-=8; l>=0; l-=8)
++			{
++			c2l(in,tin0); tin[0]=tin0;
++			c2l(in,tin1); tin[1]=tin1;
++			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
++			tout0=tin[0]^xor0;
++			tout1=tin[1]^xor1;
++			l2c(tout0,out);
++			l2c(tout1,out);
++			xor0=tin0;
++			xor1=tin1;
++			}
++		if (l != -8)
++			{
++			c2l(in,tin0); tin[0]=tin0;
++			c2l(in,tin1); tin[1]=tin1;
++			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
++			tout0=tin[0]^xor0;
++			tout1=tin[1]^xor1;
++			l2cn(tout0,tout1,out,l+8);
++		/*	xor0=tin0;
++			xor1=tin1; */
++			}
++		}
++	tin0=tin1=tout0=tout1=xor0=xor1=0;
++	tin[0]=tin[1]=0;
++	}
++
+diff --git a/net/ipsec/datatot.c b/net/ipsec/datatot.c
+new file mode 100644
+index 0000000..d7a43c4
+--- /dev/null
++++ b/net/ipsec/datatot.c
+@@ -0,0 +1,233 @@
++/*
++ * convert from binary data (e.g. key) to text form
++ * Copyright (C) 2000  Henry Spencer.
++ * 
++ * 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$
++ */
++#include "internal.h"
++#include "freeswan.h"
++
++static void convert(const char *src, size_t nreal, int format, char *out);
++
++/*
++ - datatot - convert data bytes to text
++ */
++size_t				/* true length (with NUL) for success */
++datatot(src, srclen, format, dst, dstlen)
++const char *src;
++size_t srclen;
++int format;			/* character indicating what format */
++char *dst;			/* need not be valid if dstlen is 0 */
++size_t dstlen;
++{
++	size_t inblocksize;	/* process this many bytes at a time */
++	size_t outblocksize;	/* producing this many */
++	size_t breakevery;	/* add a _ every this many (0 means don't) */
++	size_t sincebreak;	/* output bytes since last _ */
++	char breakchar;		/* character used to break between groups */
++	char inblock[10];	/* enough for any format */
++	char outblock[10];	/* enough for any format */
++	char fake[1];		/* fake output area for dstlen == 0 */
++	size_t needed;		/* return value */
++	char *stop;		/* where the terminating NUL will go */
++	size_t ntodo;		/* remaining input */
++	size_t nreal;
++	char *out;
++	char *prefix;
++
++	breakevery = 0;
++	breakchar = '_';
++
++	switch (format) {
++	case 0:
++	case 'h':
++		format = 'x';
++		breakevery = 8;
++		/* FALLTHROUGH */
++	case 'x':
++		inblocksize = 1;
++		outblocksize = 2;
++		prefix = "0x";
++		break;
++	case ':':
++		format = 'x';
++		breakevery = 2;
++		breakchar = ':';
++		/* FALLTHROUGH */
++	case 16:
++		inblocksize = 1;
++		outblocksize = 2;
++		prefix = "";
++		format = 'x';
++		break;
++	case 's':
++		inblocksize = 3;
++		outblocksize = 4;
++		prefix = "0s";
++		break;
++	case 64:		/* beware, equals ' ' */
++		inblocksize = 3;
++		outblocksize = 4;
++		prefix = "";
++		format = 's';
++		break;
++	default:
++		return 0;
++		break;
++	}
++	assert(inblocksize < sizeof(inblock));
++	assert(outblocksize < sizeof(outblock));
++	assert(breakevery % outblocksize == 0);
++
++	if (srclen == 0)
++		return 0;
++	ntodo = srclen;
++
++	if (dstlen == 0) {	/* dispose of awkward special case */
++		dst = fake;
++		dstlen = 1;
++	}
++	stop = dst + dstlen - 1;
++
++	nreal = strlen(prefix);
++	needed = nreal;			/* for starters */
++	if (dstlen <= nreal) {		/* prefix won't fit */
++		strncpy(dst, prefix, dstlen - 1);
++		dst += dstlen - 1;
++	} else {
++		strcpy(dst, prefix);
++		dst += nreal;
++	}
++	assert(dst <= stop);
++	sincebreak = 0;
++
++	while (ntodo > 0) {
++		if (ntodo < inblocksize) {	/* incomplete input */
++			memset(inblock, 0, sizeof(inblock));
++			memcpy(inblock, src, ntodo);
++			src = inblock;
++			nreal = ntodo;
++			ntodo = inblocksize;
++		} else
++			nreal = inblocksize;
++		out = (outblocksize > stop - dst) ? outblock : dst;
++
++		convert(src, nreal, format, out);
++		needed += outblocksize;
++		sincebreak += outblocksize;
++		if (dst < stop) {
++			if (out != dst) {
++				assert(outblocksize > stop - dst);
++				memcpy(dst, out, stop - dst);
++				dst = stop;
++			} else
++				dst += outblocksize;
++		}
++
++		src += inblocksize;
++		ntodo -= inblocksize;
++		if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
++			if (dst < stop)
++				*dst++ = breakchar;
++			needed++;
++			sincebreak = 0;
++		}
++	}
++
++	assert(dst <= stop);
++	*dst++ = '\0';
++	needed++;
++
++	return needed;
++}
++
++/*
++ - convert - convert one input block to one output block
++ */
++static void
++convert(src, nreal, format, out)
++const char *src;
++size_t nreal;			/* how much of the input block is real */
++int format;
++char *out;
++{
++	static char hex[] = "0123456789abcdef";
++	static char base64[] =	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
++				"abcdefghijklmnopqrstuvwxyz"
++				"0123456789+/";
++	unsigned char c;
++	unsigned char c1, c2, c3;
++
++	assert(nreal > 0);
++	switch (format) {
++	case 'x':
++		assert(nreal == 1);
++		c = (unsigned char)*src;
++		*out++ = hex[c >> 4];
++		*out++ = hex[c & 0xf];
++		break;
++	case 's':
++		c1 = (unsigned char)*src++;
++		c2 = (unsigned char)*src++;
++		c3 = (unsigned char)*src++;
++		*out++ = base64[c1 >> 2];	/* top 6 bits of c1 */
++		c = (c1 & 0x3) << 4;		/* bottom 2 of c1... */
++		c |= c2 >> 4;			/* ...top 4 of c2 */
++		*out++ = base64[c];
++		if (nreal == 1)
++			*out++ = '=';
++		else {
++			c = (c2 & 0xf) << 2;	/* bottom 4 of c2... */
++			c |= c3 >> 6;		/* ...top 2 of c3 */
++			*out++ = base64[c];
++		}
++		if (nreal <= 2)
++			*out++ = '=';
++		else
++			*out++ = base64[c3 & 0x3f];	/* bottom 6 of c3 */
++		break;
++	default:
++		assert(nreal == 0);	/* unknown format */
++		break;
++	}
++}
++
++/*
++ - datatoa - convert data to ASCII
++ * backward-compatibility synonym for datatot
++ */
++size_t				/* true length (with NUL) for success */
++datatoa(src, srclen, format, dst, dstlen)
++const char *src;
++size_t srclen;
++int format;			/* character indicating what format */
++char *dst;			/* need not be valid if dstlen is 0 */
++size_t dstlen;
++{
++	return datatot(src, srclen, format, dst, dstlen);
++}
++
++/*
++ - bytestoa - convert data bytes to ASCII
++ * backward-compatibility synonym for datatot
++ */
++size_t				/* true length (with NUL) for success */
++bytestoa(src, srclen, format, dst, dstlen)
++const char *src;
++size_t srclen;
++int format;			/* character indicating what format */
++char *dst;			/* need not be valid if dstlen is 0 */
++size_t dstlen;
++{
++	return datatot(src, srclen, format, dst, dstlen);
++}
+diff --git a/net/ipsec/defconfig b/net/ipsec/defconfig
+new file mode 100644
+index 0000000..0928f51
+--- /dev/null
++++ b/net/ipsec/defconfig
+@@ -0,0 +1,120 @@
++
++#
++# RCSID $Id: defconfig,v 1.1.1.1 2004/08/20 11:34:10 r04482 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_KLIPS=y
++
++# To do tunnel mode IPSec, this must be enabled.
++CONFIG_KLIPS_IPIP=y
++
++# To enable authentication, say 'y'.   (Highly recommended)
++CONFIG_KLIPS_AH=n
++
++# Authentication algorithm(s):
++CONFIG_KLIPS_AUTH_HMAC_MD5=y
++CONFIG_KLIPS_AUTH_HMAC_SHA1=y
++
++# To enable encryption, say 'y'.   (Highly recommended)
++CONFIG_KLIPS_ESP=y
++
++# Encryption algorithm(s):
++CONFIG_KLIPS_ENC_3DES=y
++
++# IP Compression: new, probably still has minor bugs.
++CONFIG_KLIPS_IPCOMP=y
++
++# To enable userspace-switchable KLIPS debugging, say 'y'.
++CONFIG_KLIPS_DEBUG=y
++
++#
++#
++# $Log: defconfig,v $
++# Revision 1.1.1.1  2004/08/20 11:34:10  r04482
++# no message
++#
++# Revision 1.1  2004/08/02 02:09:58  rupert
++# +: Add Freeswan IPSec 2.06
++#
++# Revision 1.24  2004/02/24 23:27:54  mcr
++# 	make sure to set IPCOMP_PREFIX.
++#
++# Revision 1.23  2003/12/13 04:09:21  mcr
++# 	AH transform removed.
++#
++# Revision 1.22  2003/02/24 19:37:27  mcr
++# 	changed default compilation mode to static.
++#
++# Revision 1.21  2002/04/24 07:36:27  mcr
++# Moved from ./klips/net/ipsec/defconfig,v
++#
++# 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 at 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 --git a/net/ipsec/deflate.c b/net/ipsec/deflate.c
+new file mode 100644
+index 0000000..ca7a2cc
+--- /dev/null
++++ b/net/ipsec/deflate.c
+@@ -0,0 +1,1352 @@
++/* deflate.c -- compress data using the deflation algorithm
++ * Copyright (C) 1995-2002 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/*
++ *  ALGORITHM
++ *
++ *      The "deflation" process depends on being able to identify portions
++ *      of the input text which are identical to earlier input (within a
++ *      sliding window trailing behind the input currently being processed).
++ *
++ *      The most straightforward technique turns out to be the fastest for
++ *      most input files: try all possible matches and select the longest.
++ *      The key feature of this algorithm is that insertions into the string
++ *      dictionary are very simple and thus fast, and deletions are avoided
++ *      completely. Insertions are performed at each input character, whereas
++ *      string matches are performed only when the previous match ends. So it
++ *      is preferable to spend more time in matches to allow very fast string
++ *      insertions and avoid deletions. The matching algorithm for small
++ *      strings is inspired from that of Rabin & Karp. A brute force approach
++ *      is used to find longer strings when a small match has been found.
++ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
++ *      (by Leonid Broukhis).
++ *         A previous version of this file used a more sophisticated algorithm
++ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
++ *      time, but has a larger average cost, uses more memory and is patented.
++ *      However the F&G algorithm may be faster for some highly redundant
++ *      files if the parameter max_chain_length (described below) is too large.
++ *
++ *  ACKNOWLEDGEMENTS
++ *
++ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
++ *      I found it in 'freeze' written by Leonid Broukhis.
++ *      Thanks to many people for bug reports and testing.
++ *
++ *  REFERENCES
++ *
++ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
++ *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
++ *
++ *      A description of the Rabin and Karp algorithm is given in the book
++ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
++ *
++ *      Fiala,E.R., and Greene,D.H.
++ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
++ *
++ */
++
++/* @(#) $Id$ */
++
++#define IPCOMP_PREFIX 1
++#include "deflate.h"
++
++local const char deflate_copyright[] =
++   " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
++/*
++  If you use the zlib library in a product, an acknowledgment is welcome
++  in the documentation of your product. If for some reason you cannot
++  include such an acknowledgment, I would appreciate that you keep this
++  copyright string in the executable of your product.
++ */
++
++/* ===========================================================================
++ *  Function prototypes.
++ */
++typedef enum {
++    need_more,      /* block not completed, need more input or more output */
++    block_done,     /* block flush performed */
++    finish_started, /* finish started, need only more output at next deflate */
++    finish_done     /* finish done, accept no more input or output */
++} block_state;
++
++typedef block_state (*compress_func) OF((deflate_state *s, int flush));
++/* Compression function. Returns the block state after the call. */
++
++local void fill_window    OF((deflate_state *s));
++local block_state deflate_stored OF((deflate_state *s, int flush));
++local block_state deflate_fast   OF((deflate_state *s, int flush));
++local block_state deflate_slow   OF((deflate_state *s, int flush));
++local void lm_init        OF((deflate_state *s));
++local void putShortMSB    OF((deflate_state *s, uInt b));
++local void flush_pending  OF((z_streamp strm));
++local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
++#ifdef ASMV
++      void match_init OF((void)); /* asm code initialization */
++      uInt longest_match  OF((deflate_state *s, IPos cur_match));
++#else
++local uInt longest_match  OF((deflate_state *s, IPos cur_match));
++#endif
++
++#ifdef DEBUG
++local  void check_match OF((deflate_state *s, IPos start, IPos match,
++                            int length));
++#endif
++
++/* ===========================================================================
++ * Local data
++ */
++
++#define NIL 0
++/* Tail of hash chains */
++
++#ifndef TOO_FAR
++#  define TOO_FAR 4096
++#endif
++/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
++
++#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
++/* Minimum amount of lookahead, except at the end of the input file.
++ * See deflate.c for comments about the MIN_MATCH+1.
++ */
++
++/* Values for max_lazy_match, good_match and max_chain_length, depending on
++ * the desired pack level (0..9). The values given below have been tuned to
++ * exclude worst case performance for pathological files. Better values may be
++ * found for specific files.
++ */
++typedef struct config_s {
++   ush good_length; /* reduce lazy search above this match length */
++   ush max_lazy;    /* do not perform lazy search above this match length */
++   ush nice_length; /* quit search above this match length */
++   ush max_chain;
++   compress_func func;
++} config;
++
++local const config configuration_table[10] = {
++/*      good lazy nice chain */
++/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
++/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
++/* 2 */ {4,    5, 16,    8, deflate_fast},
++/* 3 */ {4,    6, 32,   32, deflate_fast},
++
++/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
++/* 5 */ {8,   16, 32,   32, deflate_slow},
++/* 6 */ {8,   16, 128, 128, deflate_slow},
++/* 7 */ {8,   32, 128, 256, deflate_slow},
++/* 8 */ {32, 128, 258, 1024, deflate_slow},
++/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
++
++/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
++ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
++ * meaning.
++ */
++
++#define EQUAL 0
++/* result of memcmp for equal strings */
++
++struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
++
++/* ===========================================================================
++ * Update a hash value with the given input byte
++ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
++ *    input characters, so that a running hash key can be computed from the
++ *    previous key instead of complete recalculation each time.
++ */
++#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
++
++
++/* ===========================================================================
++ * Insert string str in the dictionary and set match_head to the previous head
++ * of the hash chain (the most recent string with same hash key). Return
++ * the previous length of the hash chain.
++ * If this file is compiled with -DFASTEST, the compression level is forced
++ * to 1, and no hash chains are maintained.
++ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
++ *    input characters and the first MIN_MATCH bytes of str are valid
++ *    (except for the last MIN_MATCH-1 bytes of the input file).
++ */
++#ifdef FASTEST
++#define INSERT_STRING(s, str, match_head) \
++   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
++    match_head = s->head[s->ins_h], \
++    s->head[s->ins_h] = (Pos)(str))
++#else
++#define INSERT_STRING(s, str, match_head) \
++   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
++    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
++    s->head[s->ins_h] = (Pos)(str))
++#endif
++
++/* ===========================================================================
++ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
++ * prev[] will be initialized on the fly.
++ */
++#define CLEAR_HASH(s) \
++    s->head[s->hash_size-1] = NIL; \
++    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
++
++/* ========================================================================= */
++int ZEXPORT deflateInit_(strm, level, version, stream_size)
++    z_streamp strm;
++    int level;
++    const char *version;
++    int stream_size;
++{
++    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
++			 Z_DEFAULT_STRATEGY, version, stream_size);
++    /* To do: ignore strm->next_in if we use it as window */
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
++		  version, stream_size)
++    z_streamp strm;
++    int  level;
++    int  method;
++    int  windowBits;
++    int  memLevel;
++    int  strategy;
++    const char *version;
++    int stream_size;
++{
++    deflate_state *s;
++    int noheader = 0;
++    static const char* my_version = ZLIB_VERSION;
++
++    ushf *overlay;
++    /* We overlay pending_buf and d_buf+l_buf. This works since the average
++     * output size for (length,distance) codes is <= 24 bits.
++     */
++
++    if (version == Z_NULL || version[0] != my_version[0] ||
++        stream_size != sizeof(z_stream)) {
++	return Z_VERSION_ERROR;
++    }
++    if (strm == Z_NULL) return Z_STREAM_ERROR;
++
++    strm->msg = Z_NULL;
++    if (strm->zalloc == Z_NULL) {
++      return Z_STREAM_ERROR;
++/*	strm->zalloc = zcalloc;
++	strm->opaque = (voidpf)0;*/
++    }
++    if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
++
++    if (level == Z_DEFAULT_COMPRESSION) level = 6;
++#ifdef FASTEST
++    level = 1;
++#endif
++
++    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
++        noheader = 1;
++        windowBits = -windowBits;
++    }
++    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
++        windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
++	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
++        return Z_STREAM_ERROR;
++    }
++    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
++    if (s == Z_NULL) return Z_MEM_ERROR;
++    strm->state = (struct internal_state FAR *)s;
++    s->strm = strm;
++
++    s->noheader = noheader;
++    s->w_bits = windowBits;
++    s->w_size = 1 << s->w_bits;
++    s->w_mask = s->w_size - 1;
++
++    s->hash_bits = memLevel + 7;
++    s->hash_size = 1 << s->hash_bits;
++    s->hash_mask = s->hash_size - 1;
++    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
++
++    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
++    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
++    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
++
++    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
++
++    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
++    s->pending_buf = (uchf *) overlay;
++    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
++
++    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
++        s->pending_buf == Z_NULL) {
++        strm->msg = ERR_MSG(Z_MEM_ERROR);
++        deflateEnd (strm);
++        return Z_MEM_ERROR;
++    }
++    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
++    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
++
++    s->level = level;
++    s->strategy = strategy;
++    s->method = (Byte)method;
++
++    return deflateReset(strm);
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
++    z_streamp strm;
++    const Bytef *dictionary;
++    uInt  dictLength;
++{
++    deflate_state *s;
++    uInt length = dictLength;
++    uInt n;
++    IPos hash_head = 0;
++
++    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
++        strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
++
++    s = strm->state;
++    strm->adler = adler32(strm->adler, dictionary, dictLength);
++
++    if (length < MIN_MATCH) return Z_OK;
++    if (length > MAX_DIST(s)) {
++	length = MAX_DIST(s);
++#ifndef USE_DICT_HEAD
++	dictionary += dictLength - length; /* use the tail of the dictionary */
++#endif
++    }
++    zmemcpy(s->window, dictionary, length);
++    s->strstart = length;
++    s->block_start = (long)length;
++
++    /* Insert all strings in the hash table (except for the last two bytes).
++     * s->lookahead stays null, so s->ins_h will be recomputed at the next
++     * call of fill_window.
++     */
++    s->ins_h = s->window[0];
++    UPDATE_HASH(s, s->ins_h, s->window[1]);
++    for (n = 0; n <= length - MIN_MATCH; n++) {
++	INSERT_STRING(s, n, hash_head);
++    }
++    if (hash_head) hash_head = 0;  /* to make compiler happy */
++    return Z_OK;
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateReset (strm)
++    z_streamp strm;
++{
++    deflate_state *s;
++    
++    if (strm == Z_NULL || strm->state == Z_NULL ||
++        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
++
++    strm->total_in = strm->total_out = 0;
++    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
++    strm->data_type = Z_UNKNOWN;
++
++    s = (deflate_state *)strm->state;
++    s->pending = 0;
++    s->pending_out = s->pending_buf;
++
++    if (s->noheader < 0) {
++        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
++    }
++    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
++    strm->adler = 1;
++    s->last_flush = Z_NO_FLUSH;
++
++    _tr_init(s);
++    lm_init(s);
++
++    return Z_OK;
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateParams(strm, level, strategy)
++    z_streamp strm;
++    int level;
++    int strategy;
++{
++    deflate_state *s;
++    compress_func func;
++    int err = Z_OK;
++
++    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
++    s = strm->state;
++
++    if (level == Z_DEFAULT_COMPRESSION) {
++	level = 6;
++    }
++    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
++	return Z_STREAM_ERROR;
++    }
++    func = configuration_table[s->level].func;
++
++    if (func != configuration_table[level].func && strm->total_in != 0) {
++	/* Flush the last buffer: */
++	err = deflate(strm, Z_PARTIAL_FLUSH);
++    }
++    if (s->level != level) {
++	s->level = level;
++	s->max_lazy_match   = configuration_table[level].max_lazy;
++	s->good_match       = configuration_table[level].good_length;
++	s->nice_match       = configuration_table[level].nice_length;
++	s->max_chain_length = configuration_table[level].max_chain;
++    }
++    s->strategy = strategy;
++    return err;
++}
++
++/* =========================================================================
++ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
++ * IN assertion: the stream state is correct and there is enough room in
++ * pending_buf.
++ */
++local void putShortMSB (s, b)
++    deflate_state *s;
++    uInt b;
++{
++    put_byte(s, (Byte)(b >> 8));
++    put_byte(s, (Byte)(b & 0xff));
++}   
++
++/* =========================================================================
++ * Flush as much pending output as possible. All deflate() output goes
++ * through this function so some applications may wish to modify it
++ * to avoid allocating a large strm->next_out buffer and copying into it.
++ * (See also read_buf()).
++ */
++local void flush_pending(strm)
++    z_streamp strm;
++{
++    unsigned len = strm->state->pending;
++
++    if (len > strm->avail_out) len = strm->avail_out;
++    if (len == 0) return;
++
++    zmemcpy(strm->next_out, strm->state->pending_out, len);
++    strm->next_out  += len;
++    strm->state->pending_out  += len;
++    strm->total_out += len;
++    strm->avail_out  -= len;
++    strm->state->pending -= len;
++    if (strm->state->pending == 0) {
++        strm->state->pending_out = strm->state->pending_buf;
++    }
++}
++
++/* ========================================================================= */
++int ZEXPORT deflate (strm, flush)
++    z_streamp strm;
++    int flush;
++{
++    int old_flush; /* value of flush param for previous deflate call */
++    deflate_state *s;
++
++    if (strm == Z_NULL || strm->state == Z_NULL ||
++	flush > Z_FINISH || flush < 0) {
++        return Z_STREAM_ERROR;
++    }
++    s = strm->state;
++
++    if (strm->next_out == Z_NULL ||
++        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
++	(s->status == FINISH_STATE && flush != Z_FINISH)) {
++        ERR_RETURN(strm, Z_STREAM_ERROR);
++    }
++    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
++
++    s->strm = strm; /* just in case */
++    old_flush = s->last_flush;
++    s->last_flush = flush;
++
++    /* Write the zlib header */
++    if (s->status == INIT_STATE) {
++
++        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
++        uInt level_flags = (s->level-1) >> 1;
++
++        if (level_flags > 3) level_flags = 3;
++        header |= (level_flags << 6);
++	if (s->strstart != 0) header |= PRESET_DICT;
++        header += 31 - (header % 31);
++
++        s->status = BUSY_STATE;
++        putShortMSB(s, header);
++
++	/* Save the adler32 of the preset dictionary: */
++	if (s->strstart != 0) {
++	    putShortMSB(s, (uInt)(strm->adler >> 16));
++	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
++	}
++	strm->adler = 1L;
++    }
++
++    /* Flush as much pending output as possible */
++    if (s->pending != 0) {
++        flush_pending(strm);
++        if (strm->avail_out == 0) {
++	    /* Since avail_out is 0, deflate will be called again with
++	     * more output space, but possibly with both pending and
++	     * avail_in equal to zero. There won't be anything to do,
++	     * but this is not an error situation so make sure we
++	     * return OK instead of BUF_ERROR at next call of deflate:
++             */
++	    s->last_flush = -1;
++	    return Z_OK;
++	}
++
++    /* Make sure there is something to do and avoid duplicate consecutive
++     * flushes. For repeated and useless calls with Z_FINISH, we keep
++     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
++     */
++    } else if (strm->avail_in == 0 && flush <= old_flush &&
++	       flush != Z_FINISH) {
++        ERR_RETURN(strm, Z_BUF_ERROR);
++    }
++
++    /* User must not provide more input after the first FINISH: */
++    if (s->status == FINISH_STATE && strm->avail_in != 0) {
++        ERR_RETURN(strm, Z_BUF_ERROR);
++    }
++
++    /* Start a new block or continue the current one.
++     */
++    if (strm->avail_in != 0 || s->lookahead != 0 ||
++        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
++        block_state bstate;
++
++	bstate = (*(configuration_table[s->level].func))(s, flush);
++
++        if (bstate == finish_started || bstate == finish_done) {
++            s->status = FINISH_STATE;
++        }
++        if (bstate == need_more || bstate == finish_started) {
++	    if (strm->avail_out == 0) {
++	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
++	    }
++	    return Z_OK;
++	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
++	     * of deflate should use the same flush parameter to make sure
++	     * that the flush is complete. So we don't have to output an
++	     * empty block here, this will be done at next call. This also
++	     * ensures that for a very small output buffer, we emit at most
++	     * one empty block.
++	     */
++	}
++        if (bstate == block_done) {
++            if (flush == Z_PARTIAL_FLUSH) {
++                _tr_align(s);
++            } else { /* FULL_FLUSH or SYNC_FLUSH */
++                _tr_stored_block(s, (char*)0, 0L, 0);
++                /* For a full flush, this empty block will be recognized
++                 * as a special marker by inflate_sync().
++                 */
++                if (flush == Z_FULL_FLUSH) {
++                    CLEAR_HASH(s);             /* forget history */
++                }
++            }
++            flush_pending(strm);
++	    if (strm->avail_out == 0) {
++	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
++	      return Z_OK;
++	    }
++        }
++    }
++    Assert(strm->avail_out > 0, "bug2");
++
++    if (flush != Z_FINISH) return Z_OK;
++    if (s->noheader) return Z_STREAM_END;
++
++    /* Write the zlib trailer (adler32) */
++    putShortMSB(s, (uInt)(strm->adler >> 16));
++    putShortMSB(s, (uInt)(strm->adler & 0xffff));
++    flush_pending(strm);
++    /* If avail_out is zero, the application will call deflate again
++     * to flush the rest.
++     */
++    s->noheader = -1; /* write the trailer only once! */
++    return s->pending != 0 ? Z_OK : Z_STREAM_END;
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateEnd (strm)
++    z_streamp strm;
++{
++    int status;
++
++    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
++
++    status = strm->state->status;
++    if (status != INIT_STATE && status != BUSY_STATE &&
++	status != FINISH_STATE) {
++      return Z_STREAM_ERROR;
++    }
++
++    /* Deallocate in reverse order of allocations: */
++    TRY_FREE(strm, strm->state->pending_buf);
++    TRY_FREE(strm, strm->state->head);
++    TRY_FREE(strm, strm->state->prev);
++    TRY_FREE(strm, strm->state->window);
++
++    ZFREE(strm, strm->state);
++    strm->state = Z_NULL;
++
++    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
++}
++
++/* =========================================================================
++ * Copy the source state to the destination state.
++ * To simplify the source, this is not supported for 16-bit MSDOS (which
++ * doesn't have enough memory anyway to duplicate compression states).
++ */
++int ZEXPORT deflateCopy (dest, source)
++    z_streamp dest;
++    z_streamp source;
++{
++#ifdef MAXSEG_64K
++    return Z_STREAM_ERROR;
++#else
++    deflate_state *ds;
++    deflate_state *ss;
++    ushf *overlay;
++
++
++    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
++        return Z_STREAM_ERROR;
++    }
++
++    ss = source->state;
++
++    *dest = *source;
++
++    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
++    if (ds == Z_NULL) return Z_MEM_ERROR;
++    dest->state = (struct internal_state FAR *) ds;
++    *ds = *ss;
++    ds->strm = dest;
++
++    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
++    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
++    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
++    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
++    ds->pending_buf = (uchf *) overlay;
++
++    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
++        ds->pending_buf == Z_NULL) {
++        deflateEnd (dest);
++        return Z_MEM_ERROR;
++    }
++    /* following zmemcpy do not work for 16-bit MSDOS */
++    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
++    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
++    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
++    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
++
++    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
++    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
++    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
++
++    ds->l_desc.dyn_tree = ds->dyn_ltree;
++    ds->d_desc.dyn_tree = ds->dyn_dtree;
++    ds->bl_desc.dyn_tree = ds->bl_tree;
++
++    return Z_OK;
++#endif
++}
++
++/* ===========================================================================
++ * Read a new buffer from the current input stream, update the adler32
++ * and total number of bytes read.  All deflate() input goes through
++ * this function so some applications may wish to modify it to avoid
++ * allocating a large strm->next_in buffer and copying from it.
++ * (See also flush_pending()).
++ */
++local int read_buf(strm, buf, size)
++    z_streamp strm;
++    Bytef *buf;
++    unsigned size;
++{
++    unsigned len = strm->avail_in;
++
++    if (len > size) len = size;
++    if (len == 0) return 0;
++
++    strm->avail_in  -= len;
++
++    if (!strm->state->noheader) {
++        strm->adler = adler32(strm->adler, strm->next_in, len);
++    }
++    zmemcpy(buf, strm->next_in, len);
++    strm->next_in  += len;
++    strm->total_in += len;
++
++    return (int)len;
++}
++
++/* ===========================================================================
++ * Initialize the "longest match" routines for a new zlib stream
++ */
++local void lm_init (s)
++    deflate_state *s;
++{
++    s->window_size = (ulg)2L*s->w_size;
++
++    CLEAR_HASH(s);
++
++    /* Set the default configuration parameters:
++     */
++    s->max_lazy_match   = configuration_table[s->level].max_lazy;
++    s->good_match       = configuration_table[s->level].good_length;
++    s->nice_match       = configuration_table[s->level].nice_length;
++    s->max_chain_length = configuration_table[s->level].max_chain;
++
++    s->strstart = 0;
++    s->block_start = 0L;
++    s->lookahead = 0;
++    s->match_length = s->prev_length = MIN_MATCH-1;
++    s->match_available = 0;
++    s->ins_h = 0;
++#ifdef ASMV
++    match_init(); /* initialize the asm code */
++#endif
++}
++
++/* ===========================================================================
++ * Set match_start to the longest match starting at the given string and
++ * return its length. Matches shorter or equal to prev_length are discarded,
++ * in which case the result is equal to prev_length and match_start is
++ * garbage.
++ * IN assertions: cur_match is the head of the hash chain for the current
++ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
++ * OUT assertion: the match length is not greater than s->lookahead.
++ */
++#ifndef ASMV
++/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
++ * match.S. The code will be functionally equivalent.
++ */
++#ifndef FASTEST
++local uInt longest_match(s, cur_match)
++    deflate_state *s;
++    IPos cur_match;                             /* current match */
++{
++    unsigned chain_length = s->max_chain_length;/* max hash chain length */
++    register Bytef *scan = s->window + s->strstart; /* current string */
++    register Bytef *match;                       /* matched string */
++    register int len;                           /* length of current match */
++    int best_len = s->prev_length;              /* best match length so far */
++    int nice_match = s->nice_match;             /* stop if match long enough */
++    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
++        s->strstart - (IPos)MAX_DIST(s) : NIL;
++    /* Stop when cur_match becomes <= limit. To simplify the code,
++     * we prevent matches with the string of window index 0.
++     */
++    Posf *prev = s->prev;
++    uInt wmask = s->w_mask;
++
++#ifdef UNALIGNED_OK
++    /* Compare two bytes at a time. Note: this is not always beneficial.
++     * Try with and without -DUNALIGNED_OK to check.
++     */
++    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
++    register ush scan_start = *(ushf*)scan;
++    register ush scan_end   = *(ushf*)(scan+best_len-1);
++#else
++    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
++    register Byte scan_end1  = scan[best_len-1];
++    register Byte scan_end   = scan[best_len];
++#endif
++
++    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
++     * It is easy to get rid of this optimization if necessary.
++     */
++    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
++
++    /* Do not waste too much time if we already have a good match: */
++    if (s->prev_length >= s->good_match) {
++        chain_length >>= 2;
++    }
++    /* Do not look for matches beyond the end of the input. This is necessary
++     * to make deflate deterministic.
++     */
++    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
++
++    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
++
++    do {
++        Assert(cur_match < s->strstart, "no future");
++        match = s->window + cur_match;
++
++        /* Skip to next match if the match length cannot increase
++         * or if the match length is less than 2:
++         */
++#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
++        /* This code assumes sizeof(unsigned short) == 2. Do not use
++         * UNALIGNED_OK if your compiler uses a different size.
++         */
++        if (*(ushf*)(match+best_len-1) != scan_end ||
++            *(ushf*)match != scan_start) continue;
++
++        /* It is not necessary to compare scan[2] and match[2] since they are
++         * always equal when the other bytes match, given that the hash keys
++         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
++         * strstart+3, +5, ... up to strstart+257. We check for insufficient
++         * lookahead only every 4th comparison; the 128th check will be made
++         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
++         * necessary to put more guard bytes at the end of the window, or
++         * to check more often for insufficient lookahead.
++         */
++        Assert(scan[2] == match[2], "scan[2]?");
++        scan++, match++;
++        do {
++        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
++                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
++                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
++                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
++                 scan < strend);
++        /* The funny "do {}" generates better code on most compilers */
++
++        /* Here, scan <= window+strstart+257 */
++        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
++        if (*scan == *match) scan++;
++
++        len = (MAX_MATCH - 1) - (int)(strend-scan);
++        scan = strend - (MAX_MATCH-1);
++
++#else /* UNALIGNED_OK */
++
++        if (match[best_len]   != scan_end  ||
++            match[best_len-1] != scan_end1 ||
++            *match            != *scan     ||
++            *++match          != scan[1])      continue;
++
++        /* The check at best_len-1 can be removed because it will be made
++         * again later. (This heuristic is not always a win.)
++         * It is not necessary to compare scan[2] and match[2] since they
++         * are always equal when the other bytes match, given that
++         * the hash keys are equal and that HASH_BITS >= 8.
++         */
++        scan += 2, match++;
++        Assert(*scan == *match, "match[2]?");
++
++        /* We check for insufficient lookahead only every 8th comparison;
++         * the 256th check will be made at strstart+258.
++         */
++        do {
++        } while (*++scan == *++match && *++scan == *++match &&
++                 *++scan == *++match && *++scan == *++match &&
++                 *++scan == *++match && *++scan == *++match &&
++                 *++scan == *++match && *++scan == *++match &&
++                 scan < strend);
++
++        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
++
++        len = MAX_MATCH - (int)(strend - scan);
++        scan = strend - MAX_MATCH;
++
++#endif /* UNALIGNED_OK */
++
++        if (len > best_len) {
++            s->match_start = cur_match;
++            best_len = len;
++            if (len >= nice_match) break;
++#ifdef UNALIGNED_OK
++            scan_end = *(ushf*)(scan+best_len-1);
++#else
++            scan_end1  = scan[best_len-1];
++            scan_end   = scan[best_len];
++#endif
++        }
++    } while ((cur_match = prev[cur_match & wmask]) > limit
++             && --chain_length != 0);
++
++    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
++    return s->lookahead;
++}
++
++#else /* FASTEST */
++/* ---------------------------------------------------------------------------
++ * Optimized version for level == 1 only
++ */
++local uInt longest_match(s, cur_match)
++    deflate_state *s;
++    IPos cur_match;                             /* current match */
++{
++    register Bytef *scan = s->window + s->strstart; /* current string */
++    register Bytef *match;                       /* matched string */
++    register int len;                           /* length of current match */
++    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
++
++    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
++     * It is easy to get rid of this optimization if necessary.
++     */
++    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
++
++    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
++
++    Assert(cur_match < s->strstart, "no future");
++
++    match = s->window + cur_match;
++
++    /* Return failure if the match length is less than 2:
++     */
++    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
++
++    /* The check at best_len-1 can be removed because it will be made
++     * again later. (This heuristic is not always a win.)
++     * It is not necessary to compare scan[2] and match[2] since they
++     * are always equal when the other bytes match, given that
++     * the hash keys are equal and that HASH_BITS >= 8.
++     */
++    scan += 2, match += 2;
++    Assert(*scan == *match, "match[2]?");
++
++    /* We check for insufficient lookahead only every 8th comparison;
++     * the 256th check will be made at strstart+258.
++     */
++    do {
++    } while (*++scan == *++match && *++scan == *++match &&
++	     *++scan == *++match && *++scan == *++match &&
++	     *++scan == *++match && *++scan == *++match &&
++	     *++scan == *++match && *++scan == *++match &&
++	     scan < strend);
++
++    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
++
++    len = MAX_MATCH - (int)(strend - scan);
++
++    if (len < MIN_MATCH) return MIN_MATCH - 1;
++
++    s->match_start = cur_match;
++    return len <= s->lookahead ? len : s->lookahead;
++}
++#endif /* FASTEST */
++#endif /* ASMV */
++
++#ifdef DEBUG
++/* ===========================================================================
++ * Check that the match at match_start is indeed a match.
++ */
++local void check_match(s, start, match, length)
++    deflate_state *s;
++    IPos start, match;
++    int length;
++{
++    /* check that the match is indeed a match */
++    if (zmemcmp(s->window + match,
++                s->window + start, length) != EQUAL) {
++        fprintf(stderr, " start %u, match %u, length %d\n",
++		start, match, length);
++        do {
++	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
++	} while (--length != 0);
++        z_error("invalid match");
++    }
++    if (z_verbose > 1) {
++        fprintf(stderr,"\\[%d,%d]", start-match, length);
++        do { putc(s->window[start++], stderr); } while (--length != 0);
++    }
++}
++#else
++#  define check_match(s, start, match, length)
++#endif
++
++/* ===========================================================================
++ * Fill the window when the lookahead becomes insufficient.
++ * Updates strstart and lookahead.
++ *
++ * IN assertion: lookahead < MIN_LOOKAHEAD
++ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
++ *    At least one byte has been read, or avail_in == 0; reads are
++ *    performed for at least two bytes (required for the zip translate_eol
++ *    option -- not supported here).
++ */
++local void fill_window(s)
++    deflate_state *s;
++{
++    register unsigned n, m;
++    register Posf *p;
++    unsigned more;    /* Amount of free space at the end of the window. */
++    uInt wsize = s->w_size;
++
++    do {
++        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
++
++        /* Deal with !@#$% 64K limit: */
++        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
++            more = wsize;
++
++        } else if (more == (unsigned)(-1)) {
++            /* Very unlikely, but possible on 16 bit machine if strstart == 0
++             * and lookahead == 1 (input done one byte at time)
++             */
++            more--;
++
++        /* If the window is almost full and there is insufficient lookahead,
++         * move the upper half to the lower one to make room in the upper half.
++         */
++        } else if (s->strstart >= wsize+MAX_DIST(s)) {
++
++            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
++            s->match_start -= wsize;
++            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
++            s->block_start -= (long) wsize;
++
++            /* Slide the hash table (could be avoided with 32 bit values
++               at the expense of memory usage). We slide even when level == 0
++               to keep the hash table consistent if we switch back to level > 0
++               later. (Using level 0 permanently is not an optimal usage of
++               zlib, so we don't care about this pathological case.)
++             */
++	    n = s->hash_size;
++	    p = &s->head[n];
++	    do {
++		m = *--p;
++		*p = (Pos)(m >= wsize ? m-wsize : NIL);
++	    } while (--n);
++
++	    n = wsize;
++#ifndef FASTEST
++	    p = &s->prev[n];
++	    do {
++		m = *--p;
++		*p = (Pos)(m >= wsize ? m-wsize : NIL);
++		/* If n is not on any hash chain, prev[n] is garbage but
++		 * its value will never be used.
++		 */
++	    } while (--n);
++#endif
++            more += wsize;
++        }
++        if (s->strm->avail_in == 0) return;
++
++        /* If there was no sliding:
++         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
++         *    more == window_size - lookahead - strstart
++         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
++         * => more >= window_size - 2*WSIZE + 2
++         * In the BIG_MEM or MMAP case (not yet supported),
++         *   window_size == input_size + MIN_LOOKAHEAD  &&
++         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
++         * Otherwise, window_size == 2*WSIZE so more >= 2.
++         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
++         */
++        Assert(more >= 2, "more < 2");
++
++        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
++        s->lookahead += n;
++
++        /* Initialize the hash value now that we have some input: */
++        if (s->lookahead >= MIN_MATCH) {
++            s->ins_h = s->window[s->strstart];
++            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
++#if MIN_MATCH != 3
++            Call UPDATE_HASH() MIN_MATCH-3 more times
++#endif
++        }
++        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
++         * but this is not important since only literal bytes will be emitted.
++         */
++
++    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
++}
++
++/* ===========================================================================
++ * Flush the current block, with given end-of-file flag.
++ * IN assertion: strstart is set to the end of the current match.
++ */
++#define FLUSH_BLOCK_ONLY(s, eof) { \
++   _tr_flush_block(s, (s->block_start >= 0L ? \
++                   (charf *)&s->window[(unsigned)s->block_start] : \
++                   (charf *)Z_NULL), \
++		(ulg)((long)s->strstart - s->block_start), \
++		(eof)); \
++   s->block_start = s->strstart; \
++   flush_pending(s->strm); \
++   Tracev((stderr,"[FLUSH]")); \
++}
++
++/* Same but force premature exit if necessary. */
++#define FLUSH_BLOCK(s, eof) { \
++   FLUSH_BLOCK_ONLY(s, eof); \
++   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
++}
++
++/* ===========================================================================
++ * Copy without compression as much as possible from the input stream, return
++ * the current block state.
++ * This function does not insert new strings in the dictionary since
++ * uncompressible data is probably not useful. This function is used
++ * only for the level=0 compression option.
++ * NOTE: this function should be optimized to avoid extra copying from
++ * window to pending_buf.
++ */
++local block_state deflate_stored(s, flush)
++    deflate_state *s;
++    int flush;
++{
++    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
++     * to pending_buf_size, and each stored block has a 5 byte header:
++     */
++    ulg max_block_size = 0xffff;
++    ulg max_start;
++
++    if (max_block_size > s->pending_buf_size - 5) {
++        max_block_size = s->pending_buf_size - 5;
++    }
++
++    /* Copy as much as possible from input to output: */
++    for (;;) {
++        /* Fill the window as much as possible: */
++        if (s->lookahead <= 1) {
++
++            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
++		   s->block_start >= (long)s->w_size, "slide too late");
++
++            fill_window(s);
++            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
++
++            if (s->lookahead == 0) break; /* flush the current block */
++        }
++	Assert(s->block_start >= 0L, "block gone");
++
++	s->strstart += s->lookahead;
++	s->lookahead = 0;
++
++	/* Emit a stored block if pending_buf will be full: */
++ 	max_start = s->block_start + max_block_size;
++        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
++	    /* strstart == 0 is possible when wraparound on 16-bit machine */
++	    s->lookahead = (uInt)(s->strstart - max_start);
++	    s->strstart = (uInt)max_start;
++            FLUSH_BLOCK(s, 0);
++	}
++	/* Flush if we may have to slide, otherwise block_start may become
++         * negative and the data will be gone:
++         */
++        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
++            FLUSH_BLOCK(s, 0);
++	}
++    }
++    FLUSH_BLOCK(s, flush == Z_FINISH);
++    return flush == Z_FINISH ? finish_done : block_done;
++}
++
++/* ===========================================================================
++ * Compress as much as possible from the input stream, return the current
++ * block state.
++ * This function does not perform lazy evaluation of matches and inserts
++ * new strings in the dictionary only for unmatched strings or for short
++ * matches. It is used only for the fast compression options.
++ */
++local block_state deflate_fast(s, flush)
++    deflate_state *s;
++    int flush;
++{
++    IPos hash_head = NIL; /* head of the hash chain */
++    int bflush;           /* set if current block must be flushed */
++
++    for (;;) {
++        /* Make sure that we always have enough lookahead, except
++         * at the end of the input file. We need MAX_MATCH bytes
++         * for the next match, plus MIN_MATCH bytes to insert the
++         * string following the next match.
++         */
++        if (s->lookahead < MIN_LOOKAHEAD) {
++            fill_window(s);
++            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
++	        return need_more;
++	    }
++            if (s->lookahead == 0) break; /* flush the current block */
++        }
++
++        /* Insert the string window[strstart .. strstart+2] in the
++         * dictionary, and set hash_head to the head of the hash chain:
++         */
++        if (s->lookahead >= MIN_MATCH) {
++            INSERT_STRING(s, s->strstart, hash_head);
++        }
++
++        /* Find the longest match, discarding those <= prev_length.
++         * At this point we have always match_length < MIN_MATCH
++         */
++        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
++            /* To simplify the code, we prevent matches with the string
++             * of window index 0 (in particular we have to avoid a match
++             * of the string with itself at the start of the input file).
++             */
++            if (s->strategy != Z_HUFFMAN_ONLY) {
++                s->match_length = longest_match (s, hash_head);
++            }
++            /* longest_match() sets match_start */
++        }
++        if (s->match_length >= MIN_MATCH) {
++            check_match(s, s->strstart, s->match_start, s->match_length);
++
++            _tr_tally_dist(s, s->strstart - s->match_start,
++                           s->match_length - MIN_MATCH, bflush);
++
++            s->lookahead -= s->match_length;
++
++            /* Insert new strings in the hash table only if the match length
++             * is not too large. This saves time but degrades compression.
++             */
++#ifndef FASTEST
++            if (s->match_length <= s->max_insert_length &&
++                s->lookahead >= MIN_MATCH) {
++                s->match_length--; /* string at strstart already in hash table */
++                do {
++                    s->strstart++;
++                    INSERT_STRING(s, s->strstart, hash_head);
++                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
++                     * always MIN_MATCH bytes ahead.
++                     */
++                } while (--s->match_length != 0);
++                s->strstart++; 
++            } else
++#endif
++	    {
++                s->strstart += s->match_length;
++                s->match_length = 0;
++                s->ins_h = s->window[s->strstart];
++                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
++#if MIN_MATCH != 3
++                Call UPDATE_HASH() MIN_MATCH-3 more times
++#endif
++                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
++                 * matter since it will be recomputed at next deflate call.
++                 */
++            }
++        } else {
++            /* No match, output a literal byte */
++            Tracevv((stderr,"%c", s->window[s->strstart]));
++            _tr_tally_lit (s, s->window[s->strstart], bflush);
++            s->lookahead--;
++            s->strstart++; 
++        }
++        if (bflush) FLUSH_BLOCK(s, 0);
++    }
++    FLUSH_BLOCK(s, flush == Z_FINISH);
++    return flush == Z_FINISH ? finish_done : block_done;
++}
++
++/* ===========================================================================
++ * Same as above, but achieves better compression. We use a lazy
++ * evaluation for matches: a match is finally adopted only if there is
++ * no better match at the next window position.
++ */
++local block_state deflate_slow(s, flush)
++    deflate_state *s;
++    int flush;
++{
++    IPos hash_head = NIL;    /* head of hash chain */
++    int bflush;              /* set if current block must be flushed */
++
++    /* Process the input block. */
++    for (;;) {
++        /* Make sure that we always have enough lookahead, except
++         * at the end of the input file. We need MAX_MATCH bytes
++         * for the next match, plus MIN_MATCH bytes to insert the
++         * string following the next match.
++         */
++        if (s->lookahead < MIN_LOOKAHEAD) {
++            fill_window(s);
++            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
++	        return need_more;
++	    }
++            if (s->lookahead == 0) break; /* flush the current block */
++        }
++
++        /* Insert the string window[strstart .. strstart+2] in the
++         * dictionary, and set hash_head to the head of the hash chain:
++         */
++        if (s->lookahead >= MIN_MATCH) {
++            INSERT_STRING(s, s->strstart, hash_head);
++        }
++
++        /* Find the longest match, discarding those <= prev_length.
++         */
++        s->prev_length = s->match_length, s->prev_match = s->match_start;
++        s->match_length = MIN_MATCH-1;
++
++        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
++            s->strstart - hash_head <= MAX_DIST(s)) {
++            /* To simplify the code, we prevent matches with the string
++             * of window index 0 (in particular we have to avoid a match
++             * of the string with itself at the start of the input file).
++             */
++            if (s->strategy != Z_HUFFMAN_ONLY) {
++                s->match_length = longest_match (s, hash_head);
++            }
++            /* longest_match() sets match_start */
++
++            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
++                 (s->match_length == MIN_MATCH &&
++                  s->strstart - s->match_start > TOO_FAR))) {
++
++                /* If prev_match is also MIN_MATCH, match_start is garbage
++                 * but we will ignore the current match anyway.
++                 */
++                s->match_length = MIN_MATCH-1;
++            }
++        }
++        /* If there was a match at the previous step and the current
++         * match is not better, output the previous match:
++         */
++        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
++            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
++            /* Do not insert strings in hash table beyond this. */
++
++            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
++
++            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
++			   s->prev_length - MIN_MATCH, bflush);
++
++            /* Insert in hash table all strings up to the end of the match.
++             * strstart-1 and strstart are already inserted. If there is not
++             * enough lookahead, the last two strings are not inserted in
++             * the hash table.
++             */
++            s->lookahead -= s->prev_length-1;
++            s->prev_length -= 2;
++            do {
++                if (++s->strstart <= max_insert) {
++                    INSERT_STRING(s, s->strstart, hash_head);
++                }
++            } while (--s->prev_length != 0);
++            s->match_available = 0;
++            s->match_length = MIN_MATCH-1;
++            s->strstart++;
++
++            if (bflush) FLUSH_BLOCK(s, 0);
++
++        } else if (s->match_available) {
++            /* If there was no match at the previous position, output a
++             * single literal. If there was a match but the current match
++             * is longer, truncate the previous match to a single literal.
++             */
++            Tracevv((stderr,"%c", s->window[s->strstart-1]));
++	    _tr_tally_lit(s, s->window[s->strstart-1], bflush);
++	    if (bflush) {
++                FLUSH_BLOCK_ONLY(s, 0);
++            }
++            s->strstart++;
++            s->lookahead--;
++            if (s->strm->avail_out == 0) return need_more;
++        } else {
++            /* There is no previous match to compare with, wait for
++             * the next step to decide.
++             */
++            s->match_available = 1;
++            s->strstart++;
++            s->lookahead--;
++        }
++    }
++    Assert (flush != Z_NO_FLUSH, "no flush?");
++    if (s->match_available) {
++        Tracevv((stderr,"%c", s->window[s->strstart-1]));
++        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
++        s->match_available = 0;
++    }
++    FLUSH_BLOCK(s, flush == Z_FINISH);
++    return flush == Z_FINISH ? finish_done : block_done;
++}
+diff --git a/net/ipsec/des_enc.c b/net/ipsec/des_enc.c
+new file mode 100644
+index 0000000..1e1906d
+--- /dev/null
++++ b/net/ipsec/des_enc.c
+@@ -0,0 +1,502 @@
++/* crypto/des/des_enc.c */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++#include "des_locl.h"
++
++void des_encrypt(data, ks, enc)
++DES_LONG *data;
++des_key_schedule ks;
++int enc;
++	{
++	register DES_LONG l,r,t,u;
++#ifdef DES_PTR
++	register unsigned char *des_SP=(unsigned char *)des_SPtrans;
++#endif
++#ifndef DES_UNROLL
++	register int i;
++#endif
++	register DES_LONG *s;
++
++	r=data[0];
++	l=data[1];
++
++	IP(r,l);
++	/* Things have been modified so that the initial rotate is
++	 * done outside the loop.  This required the
++	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
++	 * One perl script later and things have a 5% speed up on a sparc2.
++	 * Thanks to Richard Outerbridge <71755.204 at CompuServe.COM>
++	 * for pointing this out. */
++	/* clear the top bits on machines with 8byte longs */
++	/* shift left by 2 */
++	r=ROTATE(r,29)&0xffffffffL;
++	l=ROTATE(l,29)&0xffffffffL;
++
++	s=(DES_LONG *)ks;
++	/* I don't know if it is worth the effort of loop unrolling the
++	 * inner loop */
++	if (enc)
++		{
++#ifdef DES_UNROLL
++		D_ENCRYPT(l,r, 0); /*  1 */
++		D_ENCRYPT(r,l, 2); /*  2 */
++		D_ENCRYPT(l,r, 4); /*  3 */
++		D_ENCRYPT(r,l, 6); /*  4 */
++		D_ENCRYPT(l,r, 8); /*  5 */
++		D_ENCRYPT(r,l,10); /*  6 */
++		D_ENCRYPT(l,r,12); /*  7 */
++		D_ENCRYPT(r,l,14); /*  8 */
++		D_ENCRYPT(l,r,16); /*  9 */
++		D_ENCRYPT(r,l,18); /*  10 */
++		D_ENCRYPT(l,r,20); /*  11 */
++		D_ENCRYPT(r,l,22); /*  12 */
++		D_ENCRYPT(l,r,24); /*  13 */
++		D_ENCRYPT(r,l,26); /*  14 */
++		D_ENCRYPT(l,r,28); /*  15 */
++		D_ENCRYPT(r,l,30); /*  16 */
++#else
++		for (i=0; i<32; i+=8)
++			{
++			D_ENCRYPT(l,r,i+0); /*  1 */
++			D_ENCRYPT(r,l,i+2); /*  2 */
++			D_ENCRYPT(l,r,i+4); /*  3 */
++			D_ENCRYPT(r,l,i+6); /*  4 */
++			}
++#endif
++		}
++	else
++		{
++#ifdef DES_UNROLL
++		D_ENCRYPT(l,r,30); /* 16 */
++		D_ENCRYPT(r,l,28); /* 15 */
++		D_ENCRYPT(l,r,26); /* 14 */
++		D_ENCRYPT(r,l,24); /* 13 */
++		D_ENCRYPT(l,r,22); /* 12 */
++		D_ENCRYPT(r,l,20); /* 11 */
++		D_ENCRYPT(l,r,18); /* 10 */
++		D_ENCRYPT(r,l,16); /*  9 */
++		D_ENCRYPT(l,r,14); /*  8 */
++		D_ENCRYPT(r,l,12); /*  7 */
++		D_ENCRYPT(l,r,10); /*  6 */
++		D_ENCRYPT(r,l, 8); /*  5 */
++		D_ENCRYPT(l,r, 6); /*  4 */
++		D_ENCRYPT(r,l, 4); /*  3 */
++		D_ENCRYPT(l,r, 2); /*  2 */
++		D_ENCRYPT(r,l, 0); /*  1 */
++#else
++		for (i=30; i>0; i-=8)
++			{
++			D_ENCRYPT(l,r,i-0); /* 16 */
++			D_ENCRYPT(r,l,i-2); /* 15 */
++			D_ENCRYPT(l,r,i-4); /* 14 */
++			D_ENCRYPT(r,l,i-6); /* 13 */
++			}
++#endif
++		}
++
++	/* rotate and clear the top bits on machines with 8byte longs */
++	l=ROTATE(l,3)&0xffffffffL;
++	r=ROTATE(r,3)&0xffffffffL;
++
++	FP(r,l);
++	data[0]=l;
++	data[1]=r;
++	l=r=t=u=0;
++	}
++
++void des_encrypt2(data, ks, enc)
++DES_LONG *data;
++des_key_schedule ks;
++int enc;
++	{
++	register DES_LONG l,r,t,u;
++#ifdef DES_PTR
++	register unsigned char *des_SP=(unsigned char *)des_SPtrans;
++#endif
++#ifndef DES_UNROLL
++	register int i;
++#endif
++	register DES_LONG *s;
++
++	r=data[0];
++	l=data[1];
++
++	/* Things have been modified so that the initial rotate is
++	 * done outside the loop.  This required the
++	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
++	 * One perl script later and things have a 5% speed up on a sparc2.
++	 * Thanks to Richard Outerbridge <71755.204 at CompuServe.COM>
++	 * for pointing this out. */
++	/* clear the top bits on machines with 8byte longs */
++	r=ROTATE(r,29)&0xffffffffL;
++	l=ROTATE(l,29)&0xffffffffL;
++
++	s=(DES_LONG *)ks;
++	/* I don't know if it is worth the effort of loop unrolling the
++	 * inner loop */
++	if (enc)
++		{
++#ifdef DES_UNROLL
++		D_ENCRYPT(l,r, 0); /*  1 */
++		D_ENCRYPT(r,l, 2); /*  2 */
++		D_ENCRYPT(l,r, 4); /*  3 */
++		D_ENCRYPT(r,l, 6); /*  4 */
++		D_ENCRYPT(l,r, 8); /*  5 */
++		D_ENCRYPT(r,l,10); /*  6 */
++		D_ENCRYPT(l,r,12); /*  7 */
++		D_ENCRYPT(r,l,14); /*  8 */
++		D_ENCRYPT(l,r,16); /*  9 */
++		D_ENCRYPT(r,l,18); /*  10 */
++		D_ENCRYPT(l,r,20); /*  11 */
++		D_ENCRYPT(r,l,22); /*  12 */
++		D_ENCRYPT(l,r,24); /*  13 */
++		D_ENCRYPT(r,l,26); /*  14 */
++		D_ENCRYPT(l,r,28); /*  15 */
++		D_ENCRYPT(r,l,30); /*  16 */
++#else
++		for (i=0; i<32; i+=8)
++			{
++			D_ENCRYPT(l,r,i+0); /*  1 */
++			D_ENCRYPT(r,l,i+2); /*  2 */
++			D_ENCRYPT(l,r,i+4); /*  3 */
++			D_ENCRYPT(r,l,i+6); /*  4 */
++			}
++#endif
++		}
++	else
++		{
++#ifdef DES_UNROLL
++		D_ENCRYPT(l,r,30); /* 16 */
++		D_ENCRYPT(r,l,28); /* 15 */
++		D_ENCRYPT(l,r,26); /* 14 */
++		D_ENCRYPT(r,l,24); /* 13 */
++		D_ENCRYPT(l,r,22); /* 12 */
++		D_ENCRYPT(r,l,20); /* 11 */
++		D_ENCRYPT(l,r,18); /* 10 */
++		D_ENCRYPT(r,l,16); /*  9 */
++		D_ENCRYPT(l,r,14); /*  8 */
++		D_ENCRYPT(r,l,12); /*  7 */
++		D_ENCRYPT(l,r,10); /*  6 */
++		D_ENCRYPT(r,l, 8); /*  5 */
++		D_ENCRYPT(l,r, 6); /*  4 */
++		D_ENCRYPT(r,l, 4); /*  3 */
++		D_ENCRYPT(l,r, 2); /*  2 */
++		D_ENCRYPT(r,l, 0); /*  1 */
++#else
++		for (i=30; i>0; i-=8)
++			{
++			D_ENCRYPT(l,r,i-0); /* 16 */
++			D_ENCRYPT(r,l,i-2); /* 15 */
++			D_ENCRYPT(l,r,i-4); /* 14 */
++			D_ENCRYPT(r,l,i-6); /* 13 */
++			}
++#endif
++		}
++	/* rotate and clear the top bits on machines with 8byte longs */
++	data[0]=ROTATE(l,3)&0xffffffffL;
++	data[1]=ROTATE(r,3)&0xffffffffL;
++	l=r=t=u=0;
++	}
++
++void des_encrypt3(data,ks1,ks2,ks3)
++DES_LONG *data;
++des_key_schedule ks1;
++des_key_schedule ks2;
++des_key_schedule ks3;
++	{
++	register DES_LONG l,r;
++
++	l=data[0];
++	r=data[1];
++	IP(l,r);
++	data[0]=l;
++	data[1]=r;
++	des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
++	des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
++	des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
++	l=data[0];
++	r=data[1];
++	FP(r,l);
++	data[0]=l;
++	data[1]=r;
++	}
++
++void des_decrypt3(data,ks1,ks2,ks3)
++DES_LONG *data;
++des_key_schedule ks1;
++des_key_schedule ks2;
++des_key_schedule ks3;
++	{
++	register DES_LONG l,r;
++
++	l=data[0];
++	r=data[1];
++	IP(l,r);
++	data[0]=l;
++	data[1]=r;
++	des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
++	des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
++	des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
++	l=data[0];
++	r=data[1];
++	FP(r,l);
++	data[0]=l;
++	data[1]=r;
++	}
++
++#ifndef DES_DEFAULT_OPTIONS
++
++void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
++des_cblock (*input);
++des_cblock (*output);
++long length;
++des_key_schedule schedule;
++des_cblock (*ivec);
++int enc;
++	{
++	register DES_LONG tin0,tin1;
++	register DES_LONG tout0,tout1,xor0,xor1;
++	register unsigned char *in,*out;
++	register long l=length;
++	DES_LONG tin[2];
++	unsigned char *iv;
++
++	in=(unsigned char *)input;
++	out=(unsigned char *)output;
++	iv=(unsigned char *)ivec;
++
++	if (enc)
++		{
++		c2l(iv,tout0);
++		c2l(iv,tout1);
++		for (l-=8; l>=0; l-=8)
++			{
++			c2l(in,tin0);
++			c2l(in,tin1);
++			tin0^=tout0; tin[0]=tin0;
++			tin1^=tout1; tin[1]=tin1;
++			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
++			tout0=tin[0]; l2c(tout0,out);
++			tout1=tin[1]; l2c(tout1,out);
++			}
++		if (l != -8)
++			{
++			c2ln(in,tin0,tin1,l+8);
++			tin0^=tout0; tin[0]=tin0;
++			tin1^=tout1; tin[1]=tin1;
++			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
++			tout0=tin[0]; l2c(tout0,out);
++			tout1=tin[1]; l2c(tout1,out);
++			}
++		iv=(unsigned char *)ivec;
++		l2c(tout0,iv);
++		l2c(tout1,iv);
++		}
++	else
++		{
++		c2l(iv,xor0);
++		c2l(iv,xor1);
++		for (l-=8; l>=0; l-=8)
++			{
++			c2l(in,tin0); tin[0]=tin0;
++			c2l(in,tin1); tin[1]=tin1;
++			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
++			tout0=tin[0]^xor0;
++			tout1=tin[1]^xor1;
++			l2c(tout0,out);
++			l2c(tout1,out);
++			xor0=tin0;
++			xor1=tin1;
++			}
++		if (l != -8)
++			{
++			c2l(in,tin0); tin[0]=tin0;
++			c2l(in,tin1); tin[1]=tin1;
++			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
++			tout0=tin[0]^xor0;
++			tout1=tin[1]^xor1;
++			l2cn(tout0,tout1,out,l+8);
++			xor0=tin0;
++			xor1=tin1;
++			}
++
++		iv=(unsigned char *)ivec;
++		l2c(xor0,iv);
++		l2c(xor1,iv);
++		}
++	tin0=tin1=tout0=tout1=xor0=xor1=0;
++	tin[0]=tin[1]=0;
++	}
++
++void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
++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;
++	{
++	register DES_LONG tin0,tin1;
++	register DES_LONG tout0,tout1,xor0,xor1;
++	register unsigned char *in,*out;
++	register long l=length;
++	DES_LONG tin[2];
++	unsigned char *iv;
++
++	in=(unsigned char *)input;
++	out=(unsigned char *)output;
++	iv=(unsigned char *)ivec;
++
++	if (enc)
++		{
++		c2l(iv,tout0);
++		c2l(iv,tout1);
++		for (l-=8; l>=0; l-=8)
++			{
++			c2l(in,tin0);
++			c2l(in,tin1);
++			tin0^=tout0;
++			tin1^=tout1;
++
++			tin[0]=tin0;
++			tin[1]=tin1;
++			des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
++			tout0=tin[0];
++			tout1=tin[1];
++
++			l2c(tout0,out);
++			l2c(tout1,out);
++			}
++		if (l != -8)
++			{
++			c2ln(in,tin0,tin1,l+8);
++			tin0^=tout0;
++			tin1^=tout1;
++
++			tin[0]=tin0;
++			tin[1]=tin1;
++			des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
++			tout0=tin[0];
++			tout1=tin[1];
++
++			l2c(tout0,out);
++			l2c(tout1,out);
++			}
++		iv=(unsigned char *)ivec;
++		l2c(tout0,iv);
++		l2c(tout1,iv);
++		}
++	else
++		{
++		register DES_LONG t0,t1;
++
++		c2l(iv,xor0);
++		c2l(iv,xor1);
++		for (l-=8; l>=0; l-=8)
++			{
++			c2l(in,tin0);
++			c2l(in,tin1);
++
++			t0=tin0;
++			t1=tin1;
++
++			tin[0]=tin0;
++			tin[1]=tin1;
++			des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
++			tout0=tin[0];
++			tout1=tin[1];
++
++			tout0^=xor0;
++			tout1^=xor1;
++			l2c(tout0,out);
++			l2c(tout1,out);
++			xor0=t0;
++			xor1=t1;
++			}
++		if (l != -8)
++			{
++			c2l(in,tin0);
++			c2l(in,tin1);
++			
++			t0=tin0;
++			t1=tin1;
++
++			tin[0]=tin0;
++			tin[1]=tin1;
++			des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
++			tout0=tin[0];
++			tout1=tin[1];
++		
++			tout0^=xor0;
++			tout1^=xor1;
++			l2cn(tout0,tout1,out,l+8);
++			xor0=t0;
++			xor1=t1;
++			}
++
++		iv=(unsigned char *)ivec;
++		l2c(xor0,iv);
++		l2c(xor1,iv);
++		}
++	tin0=tin1=tout0=tout1=xor0=xor1=0;
++	tin[0]=tin[1]=0;
++	}
++
++#endif /* DES_DEFAULT_OPTIONS */
+diff --git a/net/ipsec/dx86unix.S b/net/ipsec/dx86unix.S
+new file mode 100644
+index 0000000..31dc0d0
+--- /dev/null
++++ b/net/ipsec/dx86unix.S
+@@ -0,0 +1,3160 @@
++/* 
++ * This file was originally generated by Michael Richardson <mcr at freeswan.org>
++ * via the perl scripts found in the ASM subdir. It remains copyright of
++ * Eric Young, see the file COPYRIGHT.
++ *
++ * This was last done on October 9, 2002.
++ *
++ * While this file does not need to go through cpp, we pass it through
++ * CPP by naming it dx86unix.S instead of dx86unix.s because there is
++ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
++ * which may contain stuff that AS doesn't understand instead of
++ * referencing EXTRA_AFLAGS.
++ */	 
++
++	.file	"dx86unix.S"
++	.version	"01.01"
++.text
++	.align 16 
++.globl des_encrypt
++	.type    des_encrypt , @function  
++des_encrypt:
++	pushl	%esi
++	pushl	%edi
++
++	 
++	movl	12(%esp),	%esi
++	xorl	%ecx,		%ecx
++	pushl	%ebx
++	pushl	%ebp
++	movl	(%esi),		%eax
++	movl	28(%esp),	%ebx
++	movl	4(%esi),	%edi
++
++	 
++	roll	$4,		%eax
++	movl	%eax,		%esi
++	xorl	%edi,		%eax
++	andl	$0xf0f0f0f0,	%eax
++	xorl	%eax,		%esi
++	xorl	%eax,		%edi
++
++	roll	$20,		%edi
++	movl	%edi,		%eax
++	xorl	%esi,		%edi
++	andl	$0xfff0000f,	%edi
++	xorl	%edi,		%eax
++	xorl	%edi,		%esi
++
++	roll	$14,		%eax
++	movl	%eax,		%edi
++	xorl	%esi,		%eax
++	andl	$0x33333333,	%eax
++	xorl	%eax,		%edi
++	xorl	%eax,		%esi
++
++	roll	$22,		%esi
++	movl	%esi,		%eax
++	xorl	%edi,		%esi
++	andl	$0x03fc03fc,	%esi
++	xorl	%esi,		%eax
++	xorl	%esi,		%edi
++
++	roll	$9,		%eax
++	movl	%eax,		%esi
++	xorl	%edi,		%eax
++	andl	$0xaaaaaaaa,	%eax
++	xorl	%eax,		%esi
++	xorl	%eax,		%edi
++
++.byte 209
++.byte 199		 
++	movl	24(%esp),	%ebp
++	cmpl	$0,		%ebx
++	je	.L000start_decrypt
++
++	 
++	movl	(%ebp),		%eax
++	xorl	%ebx,		%ebx
++	movl	4(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	8(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	12(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	16(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	20(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	24(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	28(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	32(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	36(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	40(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	44(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	48(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	52(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	56(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	60(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	64(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	68(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	72(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	76(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	80(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	84(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	88(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	92(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	96(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	100(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	104(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	108(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	112(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	116(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	120(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	124(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++	jmp	.L001end
++.L000start_decrypt:
++
++	 
++	movl	120(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	124(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	112(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	116(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	104(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	108(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	96(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	100(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	88(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	92(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	80(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	84(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	72(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	76(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	64(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	68(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	56(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	60(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	48(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	52(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	40(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	44(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	32(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	36(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	24(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	28(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	16(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	20(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	8(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	12(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	(%ebp),		%eax
++	xorl	%ebx,		%ebx
++	movl	4(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++.L001end:
++
++	 
++	movl	20(%esp),	%edx
++.byte 209
++.byte 206		 
++	movl	%edi,		%eax
++	xorl	%esi,		%edi
++	andl	$0xaaaaaaaa,	%edi
++	xorl	%edi,		%eax
++	xorl	%edi,		%esi
++
++	roll	$23,		%eax
++	movl	%eax,		%edi
++	xorl	%esi,		%eax
++	andl	$0x03fc03fc,	%eax
++	xorl	%eax,		%edi
++	xorl	%eax,		%esi
++
++	roll	$10,		%edi
++	movl	%edi,		%eax
++	xorl	%esi,		%edi
++	andl	$0x33333333,	%edi
++	xorl	%edi,		%eax
++	xorl	%edi,		%esi
++
++	roll	$18,		%esi
++	movl	%esi,		%edi
++	xorl	%eax,		%esi
++	andl	$0xfff0000f,	%esi
++	xorl	%esi,		%edi
++	xorl	%esi,		%eax
++
++	roll	$12,		%edi
++	movl	%edi,		%esi
++	xorl	%eax,		%edi
++	andl	$0xf0f0f0f0,	%edi
++	xorl	%edi,		%esi
++	xorl	%edi,		%eax
++
++	rorl	$4,		%eax
++	movl	%eax,		(%edx)
++	movl	%esi,		4(%edx)
++	popl	%ebp
++	popl	%ebx
++	popl	%edi
++	popl	%esi
++	ret
++.des_encrypt_end:
++	.size    des_encrypt , .des_encrypt_end-des_encrypt  
++.ident	"desasm.pl"
++.text
++	.align 16 
++.globl des_encrypt2
++	.type    des_encrypt2 , @function  
++des_encrypt2:
++	pushl	%esi
++	pushl	%edi
++
++	 
++	movl	12(%esp),	%eax
++	xorl	%ecx,		%ecx
++	pushl	%ebx
++	pushl	%ebp
++	movl	(%eax),		%esi
++	movl	28(%esp),	%ebx
++	roll	$3,		%esi
++	movl	4(%eax),	%edi
++	roll	$3,		%edi
++	movl	24(%esp),	%ebp
++	cmpl	$0,		%ebx
++	je	.L002start_decrypt
++
++	 
++	movl	(%ebp),		%eax
++	xorl	%ebx,		%ebx
++	movl	4(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	8(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	12(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	16(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	20(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	24(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	28(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	32(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	36(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	40(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	44(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	48(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	52(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	56(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	60(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	64(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	68(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	72(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	76(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	80(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	84(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	88(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	92(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	96(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	100(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	104(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	108(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	112(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	116(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	120(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	124(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++	jmp	.L003end
++.L002start_decrypt:
++
++	 
++	movl	120(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	124(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	112(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	116(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	104(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	108(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	96(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	100(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	88(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	92(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	80(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	84(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	72(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	76(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	64(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	68(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	56(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	60(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	48(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	52(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	40(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	44(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	32(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	36(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	24(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	28(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	16(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	20(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++
++	 
++	movl	8(%ebp),	%eax
++	xorl	%ebx,		%ebx
++	movl	12(%ebp),	%edx
++	xorl	%esi,		%eax
++	xorl	%esi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%edi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%edi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%edi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%edi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%edi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%edi
++
++	 
++	movl	(%ebp),		%eax
++	xorl	%ebx,		%ebx
++	movl	4(%ebp),	%edx
++	xorl	%edi,		%eax
++	xorl	%edi,		%edx
++	andl	$0xfcfcfcfc,	%eax
++	andl	$0xcfcfcfcf,	%edx
++	movb	%al,		%bl
++	movb	%ah,		%cl
++	rorl	$4,		%edx
++	movl	      des_SPtrans(%ebx),%ebp
++	movb	%dl,		%bl
++	xorl	%ebp,		%esi
++	movl	0x200+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movb	%dh,		%cl
++	shrl	$16,		%eax
++	movl	0x100+des_SPtrans(%ebx),%ebp
++	xorl	%ebp,		%esi
++	movb	%ah,		%bl
++	shrl	$16,		%edx
++	movl	0x300+des_SPtrans(%ecx),%ebp
++	xorl	%ebp,		%esi
++	movl	24(%esp),	%ebp
++	movb	%dh,		%cl
++	andl	$0xff,		%eax
++	andl	$0xff,		%edx
++	movl	0x600+des_SPtrans(%ebx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x700+des_SPtrans(%ecx),%ebx
++	xorl	%ebx,		%esi
++	movl	0x400+des_SPtrans(%eax),%ebx
++	xorl	%ebx,		%esi
++	movl	0x500+des_SPtrans(%edx),%ebx
++	xorl	%ebx,		%esi
++.L003end:
++
++	 
++	rorl	$3,		%edi
++	movl	20(%esp),	%eax
++	rorl	$3,		%esi
++	movl	%edi,		(%eax)
++	movl	%esi,		4(%eax)
++	popl	%ebp
++	popl	%ebx
++	popl	%edi
++	popl	%esi
++	ret
++.des_encrypt2_end:
++	.size    des_encrypt2 , .des_encrypt2_end-des_encrypt2  
++.ident	"desasm.pl"
++.text
++	.align 16 
++.globl des_encrypt3
++	.type    des_encrypt3 , @function  
++des_encrypt3:
++	pushl	%ebx
++	movl	8(%esp),	%ebx
++	pushl	%ebp
++	pushl	%esi
++	pushl	%edi
++
++	 
++	movl	(%ebx),		%edi
++	movl	4(%ebx),	%esi
++	subl	$12,		%esp
++
++	 
++	roll	$4,		%edi
++	movl	%edi,		%edx
++	xorl	%esi,		%edi
++	andl	$0xf0f0f0f0,	%edi
++	xorl	%edi,		%edx
++	xorl	%edi,		%esi
++
++	roll	$20,		%esi
++	movl	%esi,		%edi
++	xorl	%edx,		%esi
++	andl	$0xfff0000f,	%esi
++	xorl	%esi,		%edi
++	xorl	%esi,		%edx
++
++	roll	$14,		%edi
++	movl	%edi,		%esi
++	xorl	%edx,		%edi
++	andl	$0x33333333,	%edi
++	xorl	%edi,		%esi
++	xorl	%edi,		%edx
++
++	roll	$22,		%edx
++	movl	%edx,		%edi
++	xorl	%esi,		%edx
++	andl	$0x03fc03fc,	%edx
++	xorl	%edx,		%edi
++	xorl	%edx,		%esi
++
++	roll	$9,		%edi
++	movl	%edi,		%edx
++	xorl	%esi,		%edi
++	andl	$0xaaaaaaaa,	%edi
++	xorl	%edi,		%edx
++	xorl	%edi,		%esi
++
++	rorl	$3,		%edx
++	rorl	$2,		%esi
++	movl	%esi,		4(%ebx)
++	movl	36(%esp),	%eax
++	movl	%edx,		(%ebx)
++	movl	40(%esp),	%edi
++	movl	44(%esp),	%esi
++	movl	$1,		8(%esp)
++	movl	%eax,		4(%esp)
++	movl	%ebx,		(%esp)
++	call	des_encrypt2
++	movl	$0,		8(%esp)
++	movl	%edi,		4(%esp)
++	movl	%ebx,		(%esp)
++	call	des_encrypt2
++	movl	$1,		8(%esp)
++	movl	%esi,		4(%esp)
++	movl	%ebx,		(%esp)
++	call	des_encrypt2
++	addl	$12,		%esp
++	movl	(%ebx),		%edi
++	movl	4(%ebx),	%esi
++
++	 
++	roll	$2,		%esi
++	roll	$3,		%edi
++	movl	%edi,		%eax
++	xorl	%esi,		%edi
++	andl	$0xaaaaaaaa,	%edi
++	xorl	%edi,		%eax
++	xorl	%edi,		%esi
++
++	roll	$23,		%eax
++	movl	%eax,		%edi
++	xorl	%esi,		%eax
++	andl	$0x03fc03fc,	%eax
++	xorl	%eax,		%edi
++	xorl	%eax,		%esi
++
++	roll	$10,		%edi
++	movl	%edi,		%eax
++	xorl	%esi,		%edi
++	andl	$0x33333333,	%edi
++	xorl	%edi,		%eax
++	xorl	%edi,		%esi
++
++	roll	$18,		%esi
++	movl	%esi,		%edi
++	xorl	%eax,		%esi
++	andl	$0xfff0000f,	%esi
++	xorl	%esi,		%edi
++	xorl	%esi,		%eax
++
++	roll	$12,		%edi
++	movl	%edi,		%esi
++	xorl	%eax,		%edi
++	andl	$0xf0f0f0f0,	%edi
++	xorl	%edi,		%esi
++	xorl	%edi,		%eax
++
++	rorl	$4,		%eax
++	movl	%eax,		(%ebx)
++	movl	%esi,		4(%ebx)
++	popl	%edi
++	popl	%esi
++	popl	%ebp
++	popl	%ebx
++	ret
++.des_encrypt3_end:
++	.size    des_encrypt3 , .des_encrypt3_end-des_encrypt3  
++.ident	"desasm.pl"
++.text
++	.align 16 
++.globl des_decrypt3
++	.type    des_decrypt3 , @function  
++des_decrypt3:
++	pushl	%ebx
++	movl	8(%esp),	%ebx
++	pushl	%ebp
++	pushl	%esi
++	pushl	%edi
++
++	 
++	movl	(%ebx),		%edi
++	movl	4(%ebx),	%esi
++	subl	$12,		%esp
++
++	 
++	roll	$4,		%edi
++	movl	%edi,		%edx
++	xorl	%esi,		%edi
++	andl	$0xf0f0f0f0,	%edi
++	xorl	%edi,		%edx
++	xorl	%edi,		%esi
++
++	roll	$20,		%esi
++	movl	%esi,		%edi
++	xorl	%edx,		%esi
++	andl	$0xfff0000f,	%esi
++	xorl	%esi,		%edi
++	xorl	%esi,		%edx
++
++	roll	$14,		%edi
++	movl	%edi,		%esi
++	xorl	%edx,		%edi
++	andl	$0x33333333,	%edi
++	xorl	%edi,		%esi
++	xorl	%edi,		%edx
++
++	roll	$22,		%edx
++	movl	%edx,		%edi
++	xorl	%esi,		%edx
++	andl	$0x03fc03fc,	%edx
++	xorl	%edx,		%edi
++	xorl	%edx,		%esi
++
++	roll	$9,		%edi
++	movl	%edi,		%edx
++	xorl	%esi,		%edi
++	andl	$0xaaaaaaaa,	%edi
++	xorl	%edi,		%edx
++	xorl	%edi,		%esi
++
++	rorl	$3,		%edx
++	rorl	$2,		%esi
++	movl	%esi,		4(%ebx)
++	movl	36(%esp),	%esi
++	movl	%edx,		(%ebx)
++	movl	40(%esp),	%edi
++	movl	44(%esp),	%eax
++	movl	$0,		8(%esp)
++	movl	%eax,		4(%esp)
++	movl	%ebx,		(%esp)
++	call	des_encrypt2
++	movl	$1,		8(%esp)
++	movl	%edi,		4(%esp)
++	movl	%ebx,		(%esp)
++	call	des_encrypt2
++	movl	$0,		8(%esp)
++	movl	%esi,		4(%esp)
++	movl	%ebx,		(%esp)
++	call	des_encrypt2
++	addl	$12,		%esp
++	movl	(%ebx),		%edi
++	movl	4(%ebx),	%esi
++
++	 
++	roll	$2,		%esi
++	roll	$3,		%edi
++	movl	%edi,		%eax
++	xorl	%esi,		%edi
++	andl	$0xaaaaaaaa,	%edi
++	xorl	%edi,		%eax
++	xorl	%edi,		%esi
++
++	roll	$23,		%eax
++	movl	%eax,		%edi
++	xorl	%esi,		%eax
++	andl	$0x03fc03fc,	%eax
++	xorl	%eax,		%edi
++	xorl	%eax,		%esi
++
++	roll	$10,		%edi
++	movl	%edi,		%eax
++	xorl	%esi,		%edi
++	andl	$0x33333333,	%edi
++	xorl	%edi,		%eax
++	xorl	%edi,		%esi
++
++	roll	$18,		%esi
++	movl	%esi,		%edi
++	xorl	%eax,		%esi
++	andl	$0xfff0000f,	%esi
++	xorl	%esi,		%edi
++	xorl	%esi,		%eax
++
++	roll	$12,		%edi
++	movl	%edi,		%esi
++	xorl	%eax,		%edi
++	andl	$0xf0f0f0f0,	%edi
++	xorl	%edi,		%esi
++	xorl	%edi,		%eax
++
++	rorl	$4,		%eax
++	movl	%eax,		(%ebx)
++	movl	%esi,		4(%ebx)
++	popl	%edi
++	popl	%esi
++	popl	%ebp
++	popl	%ebx
++	ret
++.des_decrypt3_end:
++	.size    des_decrypt3 , .des_decrypt3_end-des_decrypt3  
++.ident	"desasm.pl"
++.text
++	.align 16 
++.globl des_ncbc_encrypt
++	.type    des_ncbc_encrypt , @function  
++des_ncbc_encrypt:
++
++	pushl	%ebp
++	pushl	%ebx
++	pushl	%esi
++	pushl	%edi
++	movl	28(%esp),	%ebp
++	 
++	movl	36(%esp),	%ebx
++	movl	(%ebx),		%esi
++	movl	4(%ebx),	%edi
++	pushl	%edi
++	pushl	%esi
++	pushl	%edi
++	pushl	%esi
++	movl	%esp,		%ebx
++	movl	36(%esp),	%esi
++	movl	40(%esp),	%edi
++	 
++	movl	56(%esp),	%ecx
++	 
++	pushl	%ecx
++	 
++	movl	52(%esp),	%eax
++	pushl	%eax
++	pushl	%ebx
++	cmpl	$0,		%ecx
++	jz	.L004decrypt
++	andl	$4294967288,	%ebp
++	movl	12(%esp),	%eax
++	movl	16(%esp),	%ebx
++	jz	.L005encrypt_finish
++.L006encrypt_loop:
++	movl	(%esi),		%ecx
++	movl	4(%esi),	%edx
++	xorl	%ecx,		%eax
++	xorl	%edx,		%ebx
++	movl	%eax,		12(%esp)
++	movl	%ebx,		16(%esp)
++	call	des_encrypt
++	movl	12(%esp),	%eax
++	movl	16(%esp),	%ebx
++	movl	%eax,		(%edi)
++	movl	%ebx,		4(%edi)
++	addl	$8,		%esi
++	addl	$8,		%edi
++	subl	$8,		%ebp
++	jnz	.L006encrypt_loop
++.L005encrypt_finish:
++	movl	56(%esp),	%ebp
++	andl	$7,		%ebp
++	jz	.L007finish
++	xorl	%ecx,		%ecx
++	xorl	%edx,		%edx
++	movl	.L008cbc_enc_jmp_table(,%ebp,4),%ebp
++	jmp	*%ebp
++.L009ej7:
++	movb	6(%esi),	%dh
++	sall	$8,		%edx
++.L010ej6:
++	movb	5(%esi),	%dh
++.L011ej5:
++	movb	4(%esi),	%dl
++.L012ej4:
++	movl	(%esi),		%ecx
++	jmp	.L013ejend
++.L014ej3:
++	movb	2(%esi),	%ch
++	sall	$8,		%ecx
++.L015ej2:
++	movb	1(%esi),	%ch
++.L016ej1:
++	movb	(%esi),		%cl
++.L013ejend:
++	xorl	%ecx,		%eax
++	xorl	%edx,		%ebx
++	movl	%eax,		12(%esp)
++	movl	%ebx,		16(%esp)
++	call	des_encrypt
++	movl	12(%esp),	%eax
++	movl	16(%esp),	%ebx
++	movl	%eax,		(%edi)
++	movl	%ebx,		4(%edi)
++	jmp	.L007finish
++.align 16 
++.L004decrypt:
++	andl	$4294967288,	%ebp
++	movl	20(%esp),	%eax
++	movl	24(%esp),	%ebx
++	jz	.L017decrypt_finish
++.L018decrypt_loop:
++	movl	(%esi),		%eax
++	movl	4(%esi),	%ebx
++	movl	%eax,		12(%esp)
++	movl	%ebx,		16(%esp)
++	call	des_encrypt
++	movl	12(%esp),	%eax
++	movl	16(%esp),	%ebx
++	movl	20(%esp),	%ecx
++	movl	24(%esp),	%edx
++	xorl	%eax,		%ecx
++	xorl	%ebx,		%edx
++	movl	(%esi),		%eax
++	movl	4(%esi),	%ebx
++	movl	%ecx,		(%edi)
++	movl	%edx,		4(%edi)
++	movl	%eax,		20(%esp)
++	movl	%ebx,		24(%esp)
++	addl	$8,		%esi
++	addl	$8,		%edi
++	subl	$8,		%ebp
++	jnz	.L018decrypt_loop
++.L017decrypt_finish:
++	movl	56(%esp),	%ebp
++	andl	$7,		%ebp
++	jz	.L007finish
++	movl	(%esi),		%eax
++	movl	4(%esi),	%ebx
++	movl	%eax,		12(%esp)
++	movl	%ebx,		16(%esp)
++	call	des_encrypt
++	movl	12(%esp),	%eax
++	movl	16(%esp),	%ebx
++	movl	20(%esp),	%ecx
++	movl	24(%esp),	%edx
++	xorl	%eax,		%ecx
++	xorl	%ebx,		%edx
++	movl	(%esi),		%eax
++	movl	4(%esi),	%ebx
++.L019dj7:
++	rorl	$16,		%edx
++	movb	%dl,		6(%edi)
++	shrl	$16,		%edx
++.L020dj6:
++	movb	%dh,		5(%edi)
++.L021dj5:
++	movb	%dl,		4(%edi)
++.L022dj4:
++	movl	%ecx,		(%edi)
++	jmp	.L023djend
++.L024dj3:
++	rorl	$16,		%ecx
++	movb	%cl,		2(%edi)
++	sall	$16,		%ecx
++.L025dj2:
++	movb	%ch,		1(%esi)
++.L026dj1:
++	movb	%cl,		(%esi)
++.L023djend:
++	jmp	.L007finish
++.align 16 
++.L007finish:
++	movl	64(%esp),	%ecx
++	addl	$28,		%esp
++	movl	%eax,		(%ecx)
++	movl	%ebx,		4(%ecx)
++	popl	%edi
++	popl	%esi
++	popl	%ebx
++	popl	%ebp
++	ret
++.align 16 
++.L008cbc_enc_jmp_table:
++	.long 0
++	.long .L016ej1
++	.long .L015ej2
++	.long .L014ej3
++	.long .L012ej4
++	.long .L011ej5
++	.long .L010ej6
++	.long .L009ej7
++.align 16 
++.L027cbc_dec_jmp_table:
++	.long 0
++	.long .L026dj1
++	.long .L025dj2
++	.long .L024dj3
++	.long .L022dj4
++	.long .L021dj5
++	.long .L020dj6
++	.long .L019dj7
++.des_ncbc_encrypt_end:
++	.size    des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt  
++.ident	"desasm.pl"
++.text
++	.align 16 
++.globl des_ede3_cbc_encrypt
++	.type    des_ede3_cbc_encrypt , @function  
++des_ede3_cbc_encrypt:
++
++	pushl	%ebp
++	pushl	%ebx
++	pushl	%esi
++	pushl	%edi
++	movl	28(%esp),	%ebp
++	 
++	movl	44(%esp),	%ebx
++	movl	(%ebx),		%esi
++	movl	4(%ebx),	%edi
++	pushl	%edi
++	pushl	%esi
++	pushl	%edi
++	pushl	%esi
++	movl	%esp,		%ebx
++	movl	36(%esp),	%esi
++	movl	40(%esp),	%edi
++	 
++	movl	64(%esp),	%ecx
++	 
++	movl	56(%esp),	%eax
++	pushl	%eax
++	 
++	movl	56(%esp),	%eax
++	pushl	%eax
++	 
++	movl	56(%esp),	%eax
++	pushl	%eax
++	pushl	%ebx
++	cmpl	$0,		%ecx
++	jz	.L028decrypt
++	andl	$4294967288,	%ebp
++	movl	16(%esp),	%eax
++	movl	20(%esp),	%ebx
++	jz	.L029encrypt_finish
++.L030encrypt_loop:
++	movl	(%esi),		%ecx
++	movl	4(%esi),	%edx
++	xorl	%ecx,		%eax
++	xorl	%edx,		%ebx
++	movl	%eax,		16(%esp)
++	movl	%ebx,		20(%esp)
++	call	des_encrypt3
++	movl	16(%esp),	%eax
++	movl	20(%esp),	%ebx
++	movl	%eax,		(%edi)
++	movl	%ebx,		4(%edi)
++	addl	$8,		%esi
++	addl	$8,		%edi
++	subl	$8,		%ebp
++	jnz	.L030encrypt_loop
++.L029encrypt_finish:
++	movl	60(%esp),	%ebp
++	andl	$7,		%ebp
++	jz	.L031finish
++	xorl	%ecx,		%ecx
++	xorl	%edx,		%edx
++	movl	.L032cbc_enc_jmp_table(,%ebp,4),%ebp
++	jmp	*%ebp
++.L033ej7:
++	movb	6(%esi),	%dh
++	sall	$8,		%edx
++.L034ej6:
++	movb	5(%esi),	%dh
++.L035ej5:
++	movb	4(%esi),	%dl
++.L036ej4:
++	movl	(%esi),		%ecx
++	jmp	.L037ejend
++.L038ej3:
++	movb	2(%esi),	%ch
++	sall	$8,		%ecx
++.L039ej2:
++	movb	1(%esi),	%ch
++.L040ej1:
++	movb	(%esi),		%cl
++.L037ejend:
++	xorl	%ecx,		%eax
++	xorl	%edx,		%ebx
++	movl	%eax,		16(%esp)
++	movl	%ebx,		20(%esp)
++	call	des_encrypt3
++	movl	16(%esp),	%eax
++	movl	20(%esp),	%ebx
++	movl	%eax,		(%edi)
++	movl	%ebx,		4(%edi)
++	jmp	.L031finish
++.align 16 
++.L028decrypt:
++	andl	$4294967288,	%ebp
++	movl	24(%esp),	%eax
++	movl	28(%esp),	%ebx
++	jz	.L041decrypt_finish
++.L042decrypt_loop:
++	movl	(%esi),		%eax
++	movl	4(%esi),	%ebx
++	movl	%eax,		16(%esp)
++	movl	%ebx,		20(%esp)
++	call	des_decrypt3
++	movl	16(%esp),	%eax
++	movl	20(%esp),	%ebx
++	movl	24(%esp),	%ecx
++	movl	28(%esp),	%edx
++	xorl	%eax,		%ecx
++	xorl	%ebx,		%edx
++	movl	(%esi),		%eax
++	movl	4(%esi),	%ebx
++	movl	%ecx,		(%edi)
++	movl	%edx,		4(%edi)
++	movl	%eax,		24(%esp)
++	movl	%ebx,		28(%esp)
++	addl	$8,		%esi
++	addl	$8,		%edi
++	subl	$8,		%ebp
++	jnz	.L042decrypt_loop
++.L041decrypt_finish:
++	movl	60(%esp),	%ebp
++	andl	$7,		%ebp
++	jz	.L031finish
++	movl	(%esi),		%eax
++	movl	4(%esi),	%ebx
++	movl	%eax,		16(%esp)
++	movl	%ebx,		20(%esp)
++	call	des_decrypt3
++	movl	16(%esp),	%eax
++	movl	20(%esp),	%ebx
++	movl	24(%esp),	%ecx
++	movl	28(%esp),	%edx
++	xorl	%eax,		%ecx
++	xorl	%ebx,		%edx
++	movl	(%esi),		%eax
++	movl	4(%esi),	%ebx
++.L043dj7:
++	rorl	$16,		%edx
++	movb	%dl,		6(%edi)
++	shrl	$16,		%edx
++.L044dj6:
++	movb	%dh,		5(%edi)
++.L045dj5:
++	movb	%dl,		4(%edi)
++.L046dj4:
++	movl	%ecx,		(%edi)
++	jmp	.L047djend
++.L048dj3:
++	rorl	$16,		%ecx
++	movb	%cl,		2(%edi)
++	sall	$16,		%ecx
++.L049dj2:
++	movb	%ch,		1(%esi)
++.L050dj1:
++	movb	%cl,		(%esi)
++.L047djend:
++	jmp	.L031finish
++.align 16 
++.L031finish:
++	movl	76(%esp),	%ecx
++	addl	$32,		%esp
++	movl	%eax,		(%ecx)
++	movl	%ebx,		4(%ecx)
++	popl	%edi
++	popl	%esi
++	popl	%ebx
++	popl	%ebp
++	ret
++.align 16 
++.L032cbc_enc_jmp_table:
++	.long 0
++	.long .L040ej1
++	.long .L039ej2
++	.long .L038ej3
++	.long .L036ej4
++	.long .L035ej5
++	.long .L034ej6
++	.long .L033ej7
++.align 16 
++.L051cbc_dec_jmp_table:
++	.long 0
++	.long .L050dj1
++	.long .L049dj2
++	.long .L048dj3
++	.long .L046dj4
++	.long .L045dj5
++	.long .L044dj6
++	.long .L043dj7
++.des_ede3_cbc_encrypt_end:
++	.size    des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt  
++.ident	"desasm.pl"
+diff --git a/net/ipsec/ecb_enc.c b/net/ipsec/ecb_enc.c
+new file mode 100644
+index 0000000..081a411
+--- /dev/null
++++ b/net/ipsec/ecb_enc.c
+@@ -0,0 +1,128 @@
++/* crypto/des/ecb_enc.c */
++/* Copyright (C) 1995-1997 Eric Young (eay at cryptsoft.com)
++ * All rights reserved.
++ *
++ * This package is an SSL implementation written
++ * by Eric Young (eay at cryptsoft.com).
++ * The implementation was written so as to conform with Netscapes SSL.
++ * 
++ * This library is free for commercial and non-commercial use as long as
++ * the following conditions are aheared to.  The following conditions
++ * apply to all code found in this distribution, be it the RC4, RSA,
++ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
++ * included with this distribution is covered by the same copyright terms
++ * except that the holder is Tim Hudson (tjh at cryptsoft.com).
++ * 
++ * Copyright remains Eric Young's, and as such any Copyright notices in
++ * the code are not to be removed.
++ * If this package is used in a product, Eric Young should be given attribution
++ * as the author of the parts of the library used.
++ * This can be in the form of a textual message at program startup or
++ * in documentation (online or textual) provided with the package.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *    "This product includes cryptographic software written by
++ *     Eric Young (eay at cryptsoft.com)"
++ *    The word 'cryptographic' can be left out if the rouines from the library
++ *    being used are not cryptographic related :-).
++ * 4. If you include any Windows specific code (or a derivative thereof) from 
++ *    the apps directory (application code) you must include an acknowledgement:
++ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
++ * 
++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * 
++ * The licence and distribution terms for any publically available version or
++ * derivative of this code cannot be changed.  i.e. this code cannot simply be
++ * copied and put under another distribution licence
++ * [including the GNU Public Licence.]
++ */
++
++#include "des_locl.h"
++#include "spr.h"
++
++char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
++char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
++
++/* RCSID $Id$ */
++/* This function ifdef'ed out for FreeS/WAN project. */
++#ifdef notdef
++char *des_options()
++	{
++	static int init=1;
++	static char buf[32];
++
++	if (init)
++		{
++		char *ptr,*unroll,*risc,*size;
++
++		init=0;
++#ifdef DES_PTR
++		ptr="ptr";
++#else
++		ptr="idx";
++#endif
++#if defined(DES_RISC1) || defined(DES_RISC2)
++#ifdef DES_RISC1
++		risc="risc1";
++#endif
++#ifdef DES_RISC2
++		risc="risc2";
++#endif
++#else
++		risc="cisc";
++#endif
++#ifdef DES_UNROLL
++		unroll="16";
++#else
++		unroll="4";
++#endif
++		if (sizeof(DES_LONG) != sizeof(long))
++			size="int";
++		else
++			size="long";
++		sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
++		}
++	return(buf);
++	}
++#endif
++		
++
++void des_ecb_encrypt(input, output, ks, enc)
++des_cblock (*input);
++des_cblock (*output);
++des_key_schedule ks;
++int enc;
++	{
++	register DES_LONG l;
++	register unsigned char *in,*out;
++	DES_LONG ll[2];
++
++	in=(unsigned char *)input;
++	out=(unsigned char *)output;
++	c2l(in,l); ll[0]=l;
++	c2l(in,l); ll[1]=l;
++	des_encrypt(ll,ks,enc);
++	l=ll[0]; l2c(l,out);
++	l=ll[1]; l2c(l,out);
++	l=ll[0]=ll[1]=0;
++	}
++
+diff --git a/net/ipsec/goodmask.c b/net/ipsec/goodmask.c
+new file mode 100644
+index 0000000..59eaaa0
+--- /dev/null
++++ b/net/ipsec/goodmask.c
+@@ -0,0 +1,97 @@
++/*
++ * minor utilities for subnet-mask manipulation
++ * Copyright (C) 1998, 1999  Henry Spencer.
++ * 
++ * 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$
++ */
++#include "internal.h"
++#include "freeswan.h"
++
++/*
++ - goodmask - is this a good (^1*0*$) subnet mask?
++ * You are not expected to understand this.  See Henry S. Warren Jr, 
++ * "Functions realizable with word-parallel logical and two's-complement
++ * addition instructions", CACM 20.6 (June 1977), p.439.
++ */
++int				/* predicate */
++goodmask(mask)
++struct in_addr mask;
++{
++	unsigned long x = ntohl(mask.s_addr);
++	/* clear rightmost contiguous string of 1-bits */
++#	define	CRCS1B(x)	(((x|(x-1))+1)&x)
++#	define	TOPBIT		(1UL << 31)
++
++	/* either zero, or has one string of 1-bits which is left-justified */
++	if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
++		return 1;
++	return 0;
++}
++
++/*
++ - masktobits - how many bits in this mask?
++ * The algorithm is essentially a binary search, but highly optimized
++ * for this particular task.
++ */
++int				/* -1 means !goodmask() */
++masktobits(mask)
++struct in_addr mask;
++{
++	unsigned long m = ntohl(mask.s_addr);
++	int masklen;
++
++	if (!goodmask(mask))
++		return -1;
++
++	if (m&0x00000001UL)
++		return 32;
++	masklen = 0;
++	if (m&(0x0000ffffUL<<1)) {	/* <<1 for 1-origin numbering */
++		masklen |= 0x10;
++		m <<= 16;
++	}
++	if (m&(0x00ff0000UL<<1)) {
++		masklen |= 0x08;
++		m <<= 8;
++	}
++	if (m&(0x0f000000UL<<1)) {
++		masklen |= 0x04;
++		m <<= 4;
++	}
++	if (m&(0x30000000UL<<1)) {
++		masklen |= 0x02;
++		m <<= 2;
++	}
++	if (m&(0x40000000UL<<1))
++		masklen |= 0x01;
++
++	return masklen;
++}
++
++/*
++ - bitstomask - return a mask with this many high bits on
++ */
++struct in_addr
++bitstomask(n)
++int n;
++{
++	struct in_addr result;
++
++	if (n > 0 && n <= ABITS)
++		result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
++	else if (n == 0)
++		result.s_addr = 0;
++	else
++		result.s_addr = 0;	/* best error report we can do */
++	return result;
++}
+diff --git a/net/ipsec/infblock.c b/net/ipsec/infblock.c
+new file mode 100644
+index 0000000..c316ce0
+--- /dev/null
++++ b/net/ipsec/infblock.c
+@@ -0,0 +1,403 @@
++/* infblock.c -- interpret and process block types to last block
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include <zlib/zutil.h>
++#include "infblock.h"
++#include "inftrees.h"
++#include "infcodes.h"
++#include "infutil.h"
++
++struct inflate_codes_state {int dummy;}; /* for buggy compilers */
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++/* Table for deflate from PKZIP's appnote.txt. */
++local const uInt border[] = { /* Order of the bit length code lengths */
++        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
++
++/*
++   Notes beyond the 1.93a appnote.txt:
++
++   1. Distance pointers never point before the beginning of the output
++      stream.
++   2. Distance pointers can point back across blocks, up to 32k away.
++   3. There is an implied maximum of 7 bits for the bit length table and
++      15 bits for the actual data.
++   4. If only one code exists, then it is encoded using one bit.  (Zero
++      would be more efficient, but perhaps a little confusing.)  If two
++      codes exist, they are coded using one bit each (0 and 1).
++   5. There is no way of sending zero distance codes--a dummy must be
++      sent if there are none.  (History: a pre 2.0 version of PKZIP would
++      store blocks with no distance codes, but this was discovered to be
++      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
++      zero distance codes, which is sent as one code of zero bits in
++      length.
++   6. There are up to 286 literal/length codes.  Code 256 represents the
++      end-of-block.  Note however that the static length tree defines
++      288 codes just to fill out the Huffman codes.  Codes 286 and 287
++      cannot be used though, since there is no length base or extra bits
++      defined for them.  Similarily, there are up to 30 distance codes.
++      However, static trees define 32 codes (all 5 bits) to fill out the
++      Huffman codes, but the last two had better not show up in the data.
++   7. Unzip can check dynamic Huffman blocks for complete code sets.
++      The exception is that a single code would not be complete (see #4).
++   8. The five bits following the block type is really the number of
++      literal codes sent minus 257.
++   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
++      (1+6+6).  Therefore, to output three times the length, you output
++      three codes (1+1+1), whereas to output four times the same length,
++      you only need two codes (1+3).  Hmm.
++  10. In the tree reconstruction algorithm, Code = Code + Increment
++      only if BitLength(i) is not zero.  (Pretty obvious.)
++  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
++  12. Note: length code 284 can represent 227-258, but length code 285
++      really is 258.  The last length deserves its own, short code
++      since it gets used a lot in very redundant files.  The length
++      258 is special since 258 - 3 (the min match length) is 255.
++  13. The literal/length and distance code bit lengths are read as a
++      single stream of lengths.  It is possible (and advantageous) for
++      a repeat code (16, 17, or 18) to go across the boundary between
++      the two sets of lengths.
++ */
++
++
++void inflate_blocks_reset(s, z, c)
++inflate_blocks_statef *s;
++z_streamp z;
++uLongf *c;
++{
++  if (c != Z_NULL)
++    *c = s->check;
++  if (s->mode == BTREE || s->mode == DTREE)
++    ZFREE(z, s->sub.trees.blens);
++  if (s->mode == CODES)
++    inflate_codes_free(s->sub.decode.codes, z);
++  s->mode = TYPE;
++  s->bitk = 0;
++  s->bitb = 0;
++  s->read = s->write = s->window;
++  if (s->checkfn != Z_NULL)
++    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
++  Tracev((stderr, "inflate:   blocks reset\n"));
++}
++
++
++inflate_blocks_statef *inflate_blocks_new(z, c, w)
++z_streamp z;
++check_func c;
++uInt w;
++{
++  inflate_blocks_statef *s;
++
++  if ((s = (inflate_blocks_statef *)ZALLOC
++       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
++    return s;
++  if ((s->hufts =
++       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
++  {
++    ZFREE(z, s);
++    return Z_NULL;
++  }
++  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
++  {
++    ZFREE(z, s->hufts);
++    ZFREE(z, s);
++    return Z_NULL;
++  }
++  s->end = s->window + w;
++  s->checkfn = c;
++  s->mode = TYPE;
++  Tracev((stderr, "inflate:   blocks allocated\n"));
++  inflate_blocks_reset(s, z, Z_NULL);
++  return s;
++}
++
++
++int inflate_blocks(s, z, r)
++inflate_blocks_statef *s;
++z_streamp z;
++int r;
++{
++  uInt t;               /* temporary storage */
++  uLong b;              /* bit buffer */
++  uInt k;               /* bits in bit buffer */
++  Bytef *p;             /* input data pointer */
++  uInt n;               /* bytes available there */
++  Bytef *q;             /* output window write pointer */
++  uInt m;               /* bytes to end of window or read pointer */
++
++  /* copy input/output information to locals (UPDATE macro restores) */
++  LOAD
++
++  /* process input based on current state */
++  while (1) switch (s->mode)
++  {
++    case TYPE:
++      NEEDBITS(3)
++      t = (uInt)b & 7;
++      s->last = t & 1;
++      switch (t >> 1)
++      {
++        case 0:                         /* stored */
++          Tracev((stderr, "inflate:     stored block%s\n",
++                 s->last ? " (last)" : ""));
++          DUMPBITS(3)
++          t = k & 7;                    /* go to byte boundary */
++          DUMPBITS(t)
++          s->mode = LENS;               /* get length of stored block */
++          break;
++        case 1:                         /* fixed */
++          Tracev((stderr, "inflate:     fixed codes block%s\n",
++                 s->last ? " (last)" : ""));
++          {
++            uInt bl, bd;
++            inflate_huft *tl, *td;
++
++            inflate_trees_fixed(&bl, &bd, &tl, &td, z);
++            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
++            if (s->sub.decode.codes == Z_NULL)
++            {
++              r = Z_MEM_ERROR;
++              LEAVE
++            }
++          }
++          DUMPBITS(3)
++          s->mode = CODES;
++          break;
++        case 2:                         /* dynamic */
++          Tracev((stderr, "inflate:     dynamic codes block%s\n",
++                 s->last ? " (last)" : ""));
++          DUMPBITS(3)
++          s->mode = TABLE;
++          break;
++        case 3:                         /* illegal */
++          DUMPBITS(3)
++          s->mode = BAD;
++          z->msg = (char*)"invalid block type";
++          r = Z_DATA_ERROR;
++          LEAVE
++      }
++      break;
++    case LENS:
++      NEEDBITS(32)
++      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
++      {
++        s->mode = BAD;
++        z->msg = (char*)"invalid stored block lengths";
++        r = Z_DATA_ERROR;
++        LEAVE
++      }
++      s->sub.left = (uInt)b & 0xffff;
++      b = k = 0;                      /* dump bits */
++      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
++      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
++      break;
++    case STORED:
++      if (n == 0)
++        LEAVE
++      NEEDOUT
++      t = s->sub.left;
++      if (t > n) t = n;
++      if (t > m) t = m;
++      zmemcpy(q, p, t);
++      p += t;  n -= t;
++      q += t;  m -= t;
++      if ((s->sub.left -= t) != 0)
++        break;
++      Tracev((stderr, "inflate:       stored end, %lu total out\n",
++              z->total_out + (q >= s->read ? q - s->read :
++              (s->end - s->read) + (q - s->window))));
++      s->mode = s->last ? DRY : TYPE;
++      break;
++    case TABLE:
++      NEEDBITS(14)
++      s->sub.trees.table = t = (uInt)b & 0x3fff;
++#ifndef PKZIP_BUG_WORKAROUND
++      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
++      {
++        s->mode = BAD;
++        z->msg = (char*)"too many length or distance symbols";
++        r = Z_DATA_ERROR;
++        LEAVE
++      }
++#endif
++      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
++      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
++      {
++        r = Z_MEM_ERROR;
++        LEAVE
++      }
++      DUMPBITS(14)
++      s->sub.trees.index = 0;
++      Tracev((stderr, "inflate:       table sizes ok\n"));
++      s->mode = BTREE;
++    case BTREE:
++      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
++      {
++        NEEDBITS(3)
++        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
++        DUMPBITS(3)
++      }
++      while (s->sub.trees.index < 19)
++        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
++      s->sub.trees.bb = 7;
++      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
++                             &s->sub.trees.tb, s->hufts, z);
++      if (t != Z_OK)
++      {
++        r = t;
++        if (r == Z_DATA_ERROR)
++        {
++          ZFREE(z, s->sub.trees.blens);
++          s->mode = BAD;
++        }
++        LEAVE
++      }
++      s->sub.trees.index = 0;
++      Tracev((stderr, "inflate:       bits tree ok\n"));
++      s->mode = DTREE;
++    case DTREE:
++      while (t = s->sub.trees.table,
++             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
++      {
++        inflate_huft *h;
++        uInt i, j, c;
++
++        t = s->sub.trees.bb;
++        NEEDBITS(t)
++        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
++        t = h->bits;
++        c = h->base;
++        if (c < 16)
++        {
++          DUMPBITS(t)
++          s->sub.trees.blens[s->sub.trees.index++] = c;
++        }
++        else /* c == 16..18 */
++        {
++          i = c == 18 ? 7 : c - 14;
++          j = c == 18 ? 11 : 3;
++          NEEDBITS(t + i)
++          DUMPBITS(t)
++          j += (uInt)b & inflate_mask[i];
++          DUMPBITS(i)
++          i = s->sub.trees.index;
++          t = s->sub.trees.table;
++          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
++              (c == 16 && i < 1))
++          {
++            ZFREE(z, s->sub.trees.blens);
++            s->mode = BAD;
++            z->msg = (char*)"invalid bit length repeat";
++            r = Z_DATA_ERROR;
++            LEAVE
++          }
++          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
++          do {
++            s->sub.trees.blens[i++] = c;
++          } while (--j);
++          s->sub.trees.index = i;
++        }
++      }
++      s->sub.trees.tb = Z_NULL;
++      {
++        uInt bl, bd;
++        inflate_huft *tl, *td;
++        inflate_codes_statef *c;
++
++        bl = 9;         /* must be <= 9 for lookahead assumptions */
++        bd = 6;         /* must be <= 9 for lookahead assumptions */
++        t = s->sub.trees.table;
++        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
++                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
++                                  s->hufts, z);
++        if (t != Z_OK)
++        {
++          if (t == (uInt)Z_DATA_ERROR)
++          {
++            ZFREE(z, s->sub.trees.blens);
++            s->mode = BAD;
++          }
++          r = t;
++          LEAVE
++        }
++        Tracev((stderr, "inflate:       trees ok\n"));
++        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
++        {
++          r = Z_MEM_ERROR;
++          LEAVE
++        }
++        s->sub.decode.codes = c;
++      }
++      ZFREE(z, s->sub.trees.blens);
++      s->mode = CODES;
++    case CODES:
++      UPDATE
++      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
++        return inflate_flush(s, z, r);
++      r = Z_OK;
++      inflate_codes_free(s->sub.decode.codes, z);
++      LOAD
++      Tracev((stderr, "inflate:       codes end, %lu total out\n",
++              z->total_out + (q >= s->read ? q - s->read :
++              (s->end - s->read) + (q - s->window))));
++      if (!s->last)
++      {
++        s->mode = TYPE;
++        break;
++      }
++      s->mode = DRY;
++    case DRY:
++      FLUSH
++      if (s->read != s->write)
++        LEAVE
++      s->mode = DONE;
++    case DONE:
++      r = Z_STREAM_END;
++      LEAVE
++    case BAD:
++      r = Z_DATA_ERROR;
++      LEAVE
++    default:
++      r = Z_STREAM_ERROR;
++      LEAVE
++  }
++}
++
++
++int inflate_blocks_free(s, z)
++inflate_blocks_statef *s;
++z_streamp z;
++{
++  inflate_blocks_reset(s, z, Z_NULL);
++  ZFREE(z, s->window);
++  ZFREE(z, s->hufts);
++  ZFREE(z, s);
++  Tracev((stderr, "inflate:   blocks freed\n"));
++  return Z_OK;
++}
++
++
++void inflate_set_dictionary(s, d, n)
++inflate_blocks_statef *s;
++const Bytef *d;
++uInt  n;
++{
++  zmemcpy(s->window, d, n);
++  s->read = s->write = s->window + n;
++}
++
++
++/* Returns true if inflate is currently at the end of a block generated
++ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
++ * IN assertion: s != Z_NULL
++ */
++int inflate_blocks_sync_point(s)
++inflate_blocks_statef *s;
++{
++  return s->mode == LENS;
++}
+diff --git a/net/ipsec/infcodes.c b/net/ipsec/infcodes.c
+new file mode 100644
+index 0000000..f56eae4
+--- /dev/null
++++ b/net/ipsec/infcodes.c
+@@ -0,0 +1,251 @@
++/* infcodes.c -- process literals and length/distance pairs
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include <zlib/zutil.h>
++#include "inftrees.h"
++#include "infblock.h"
++#include "infcodes.h"
++#include "infutil.h"
++#include "inffast.h"
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
++      START,    /* x: set up for LEN */
++      LEN,      /* i: get length/literal/eob next */
++      LENEXT,   /* i: getting length extra (have base) */
++      DIST,     /* i: get distance next */
++      DISTEXT,  /* i: getting distance extra */
++      COPY,     /* o: copying bytes in window, waiting for space */
++      LIT,      /* o: got literal, waiting for output space */
++      WASH,     /* o: got eob, possibly still output waiting */
++      END,      /* x: got eob and all data flushed */
++      BADCODE}  /* x: got error */
++inflate_codes_mode;
++
++/* inflate codes private state */
++struct inflate_codes_state {
++
++  /* mode */
++  inflate_codes_mode mode;      /* current inflate_codes mode */
++
++  /* mode dependent information */
++  uInt len;
++  union {
++    struct {
++      inflate_huft *tree;       /* pointer into tree */
++      uInt need;                /* bits needed */
++    } code;             /* if LEN or DIST, where in tree */
++    uInt lit;           /* if LIT, literal */
++    struct {
++      uInt get;                 /* bits to get for extra */
++      uInt dist;                /* distance back to copy from */
++    } copy;             /* if EXT or COPY, where and how much */
++  } sub;                /* submode */
++
++  /* mode independent information */
++  Byte lbits;           /* ltree bits decoded per branch */
++  Byte dbits;           /* dtree bits decoder per branch */
++  inflate_huft *ltree;          /* literal/length/eob tree */
++  inflate_huft *dtree;          /* distance tree */
++
++};
++
++
++inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
++uInt bl, bd;
++inflate_huft *tl;
++inflate_huft *td; /* need separate declaration for Borland C++ */
++z_streamp z;
++{
++  inflate_codes_statef *c;
++
++  if ((c = (inflate_codes_statef *)
++       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
++  {
++    c->mode = START;
++    c->lbits = (Byte)bl;
++    c->dbits = (Byte)bd;
++    c->ltree = tl;
++    c->dtree = td;
++    Tracev((stderr, "inflate:       codes new\n"));
++  }
++  return c;
++}
++
++
++int inflate_codes(s, z, r)
++inflate_blocks_statef *s;
++z_streamp z;
++int r;
++{
++  uInt j;               /* temporary storage */
++  inflate_huft *t;      /* temporary pointer */
++  uInt e;               /* extra bits or operation */
++  uLong b;              /* bit buffer */
++  uInt k;               /* bits in bit buffer */
++  Bytef *p;             /* input data pointer */
++  uInt n;               /* bytes available there */
++  Bytef *q;             /* output window write pointer */
++  uInt m;               /* bytes to end of window or read pointer */
++  Bytef *f;             /* pointer to copy strings from */
++  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
++
++  /* copy input/output information to locals (UPDATE macro restores) */
++  LOAD
++
++  /* process input and output based on current state */
++  while (1) switch (c->mode)
++  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
++    case START:         /* x: set up for LEN */
++#ifndef SLOW
++      if (m >= 258 && n >= 10)
++      {
++        UPDATE
++        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
++        LOAD
++        if (r != Z_OK)
++        {
++          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
++          break;
++        }
++      }
++#endif /* !SLOW */
++      c->sub.code.need = c->lbits;
++      c->sub.code.tree = c->ltree;
++      c->mode = LEN;
++    case LEN:           /* i: get length/literal/eob next */
++      j = c->sub.code.need;
++      NEEDBITS(j)
++      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
++      DUMPBITS(t->bits)
++      e = (uInt)(t->exop);
++      if (e == 0)               /* literal */
++      {
++        c->sub.lit = t->base;
++        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
++                 "inflate:         literal '%c'\n" :
++                 "inflate:         literal 0x%02x\n", t->base));
++        c->mode = LIT;
++        break;
++      }
++      if (e & 16)               /* length */
++      {
++        c->sub.copy.get = e & 15;
++        c->len = t->base;
++        c->mode = LENEXT;
++        break;
++      }
++      if ((e & 64) == 0)        /* next table */
++      {
++        c->sub.code.need = e;
++        c->sub.code.tree = t + t->base;
++        break;
++      }
++      if (e & 32)               /* end of block */
++      {
++        Tracevv((stderr, "inflate:         end of block\n"));
++        c->mode = WASH;
++        break;
++      }
++      c->mode = BADCODE;        /* invalid code */
++      z->msg = (char*)"invalid literal/length code";
++      r = Z_DATA_ERROR;
++      LEAVE
++    case LENEXT:        /* i: getting length extra (have base) */
++      j = c->sub.copy.get;
++      NEEDBITS(j)
++      c->len += (uInt)b & inflate_mask[j];
++      DUMPBITS(j)
++      c->sub.code.need = c->dbits;
++      c->sub.code.tree = c->dtree;
++      Tracevv((stderr, "inflate:         length %u\n", c->len));
++      c->mode = DIST;
++    case DIST:          /* i: get distance next */
++      j = c->sub.code.need;
++      NEEDBITS(j)
++      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
++      DUMPBITS(t->bits)
++      e = (uInt)(t->exop);
++      if (e & 16)               /* distance */
++      {
++        c->sub.copy.get = e & 15;
++        c->sub.copy.dist = t->base;
++        c->mode = DISTEXT;
++        break;
++      }
++      if ((e & 64) == 0)        /* next table */
++      {
++        c->sub.code.need = e;
++        c->sub.code.tree = t + t->base;
++        break;
++      }
++      c->mode = BADCODE;        /* invalid code */
++      z->msg = (char*)"invalid distance code";
++      r = Z_DATA_ERROR;
++      LEAVE
++    case DISTEXT:       /* i: getting distance extra */
++      j = c->sub.copy.get;
++      NEEDBITS(j)
++      c->sub.copy.dist += (uInt)b & inflate_mask[j];
++      DUMPBITS(j)
++      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
++      c->mode = COPY;
++    case COPY:          /* o: copying bytes in window, waiting for space */
++      f = q - c->sub.copy.dist;
++      while (f < s->window)             /* modulo window size-"while" instead */
++        f += s->end - s->window;        /* of "if" handles invalid distances */
++      while (c->len)
++      {
++        NEEDOUT
++        OUTBYTE(*f++)
++        if (f == s->end)
++          f = s->window;
++        c->len--;
++      }
++      c->mode = START;
++      break;
++    case LIT:           /* o: got literal, waiting for output space */
++      NEEDOUT
++      OUTBYTE(c->sub.lit)
++      c->mode = START;
++      break;
++    case WASH:          /* o: got eob, possibly more output */
++      if (k > 7)        /* return unused byte, if any */
++      {
++        Assert(k < 16, "inflate_codes grabbed too many bytes")
++        k -= 8;
++        n++;
++        p--;            /* can always return one */
++      }
++      FLUSH
++      if (s->read != s->write)
++        LEAVE
++      c->mode = END;
++    case END:
++      r = Z_STREAM_END;
++      LEAVE
++    case BADCODE:       /* x: got error */
++      r = Z_DATA_ERROR;
++      LEAVE
++    default:
++      r = Z_STREAM_ERROR;
++      LEAVE
++  }
++#ifdef NEED_DUMMY_RETURN
++  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
++#endif
++}
++
++
++void inflate_codes_free(c, z)
++inflate_codes_statef *c;
++z_streamp z;
++{
++  ZFREE(z, c);
++  Tracev((stderr, "inflate:       codes free\n"));
++}
+diff --git a/net/ipsec/inffast.c b/net/ipsec/inffast.c
+new file mode 100644
+index 0000000..2a363c5
+--- /dev/null
++++ b/net/ipsec/inffast.c
+@@ -0,0 +1,183 @@
++/* inffast.c -- process literals and length/distance pairs fast
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include <zlib/zutil.h>
++#include "inftrees.h"
++#include "infblock.h"
++#include "infcodes.h"
++#include "infutil.h"
++#include "inffast.h"
++
++struct inflate_codes_state {int dummy;}; /* for buggy compilers */
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++/* macros for bit input with no checking and for returning unused bytes */
++#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
++#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
++
++/* Called with number of bytes left to write in window at least 258
++   (the maximum string length) and number of input bytes available
++   at least ten.  The ten bytes are six bytes for the longest length/
++   distance pair plus four bytes for overloading the bit buffer. */
++
++int inflate_fast(bl, bd, tl, td, s, z)
++uInt bl, bd;
++inflate_huft *tl;
++inflate_huft *td; /* need separate declaration for Borland C++ */
++inflate_blocks_statef *s;
++z_streamp z;
++{
++  inflate_huft *t;      /* temporary pointer */
++  uInt e;               /* extra bits or operation */
++  uLong b;              /* bit buffer */
++  uInt k;               /* bits in bit buffer */
++  Bytef *p;             /* input data pointer */
++  uInt n;               /* bytes available there */
++  Bytef *q;             /* output window write pointer */
++  uInt m;               /* bytes to end of window or read pointer */
++  uInt ml;              /* mask for literal/length tree */
++  uInt md;              /* mask for distance tree */
++  uInt c;               /* bytes to copy */
++  uInt d;               /* distance back to copy from */
++  Bytef *r;             /* copy source pointer */
++
++  /* load input, output, bit values */
++  LOAD
++
++  /* initialize masks */
++  ml = inflate_mask[bl];
++  md = inflate_mask[bd];
++
++  /* do until not enough input or output space for fast loop */
++  do {                          /* assume called with m >= 258 && n >= 10 */
++    /* get literal/length code */
++    GRABBITS(20)                /* max bits for literal/length code */
++    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
++    {
++      DUMPBITS(t->bits)
++      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
++                "inflate:         * literal '%c'\n" :
++                "inflate:         * literal 0x%02x\n", t->base));
++      *q++ = (Byte)t->base;
++      m--;
++      continue;
++    }
++    do {
++      DUMPBITS(t->bits)
++      if (e & 16)
++      {
++        /* get extra bits for length */
++        e &= 15;
++        c = t->base + ((uInt)b & inflate_mask[e]);
++        DUMPBITS(e)
++        Tracevv((stderr, "inflate:         * length %u\n", c));
++
++        /* decode distance base of block to copy */
++        GRABBITS(15);           /* max bits for distance code */
++        e = (t = td + ((uInt)b & md))->exop;
++        do {
++          DUMPBITS(t->bits)
++          if (e & 16)
++          {
++            /* get extra bits to add to distance base */
++            e &= 15;
++            GRABBITS(e)         /* get extra bits (up to 13) */
++            d = t->base + ((uInt)b & inflate_mask[e]);
++            DUMPBITS(e)
++            Tracevv((stderr, "inflate:         * distance %u\n", d));
++
++            /* do the copy */
++            m -= c;
++            r = q - d;
++            if (r < s->window)                  /* wrap if needed */
++            {
++              do {
++                r += s->end - s->window;        /* force pointer in window */
++              } while (r < s->window);          /* covers invalid distances */
++              e = s->end - r;
++              if (c > e)
++              {
++                c -= e;                         /* wrapped copy */
++                do {
++                    *q++ = *r++;
++                } while (--e);
++                r = s->window;
++                do {
++                    *q++ = *r++;
++                } while (--c);
++              }
++              else                              /* normal copy */
++              {
++                *q++ = *r++;  c--;
++                *q++ = *r++;  c--;
++                do {
++                    *q++ = *r++;
++                } while (--c);
++              }
++            }
++            else                                /* normal copy */
++            {
++              *q++ = *r++;  c--;
++              *q++ = *r++;  c--;
++              do {
++                *q++ = *r++;
++              } while (--c);
++            }
++            break;
++          }
++          else if ((e & 64) == 0)
++          {
++            t += t->base;
++            e = (t += ((uInt)b & inflate_mask[e]))->exop;
++          }
++          else
++          {
++            z->msg = (char*)"invalid distance code";
++            UNGRAB
++            UPDATE
++            return Z_DATA_ERROR;
++          }
++        } while (1);
++        break;
++      }
++      if ((e & 64) == 0)
++      {
++        t += t->base;
++        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
++        {
++          DUMPBITS(t->bits)
++          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
++                    "inflate:         * literal '%c'\n" :
++                    "inflate:         * literal 0x%02x\n", t->base));
++          *q++ = (Byte)t->base;
++          m--;
++          break;
++        }
++      }
++      else if (e & 32)
++      {
++        Tracevv((stderr, "inflate:         * end of block\n"));
++        UNGRAB
++        UPDATE
++        return Z_STREAM_END;
++      }
++      else
++      {
++        z->msg = (char*)"invalid literal/length code";
++        UNGRAB
++        UPDATE
++        return Z_DATA_ERROR;
++      }
++    } while (1);
++  } while (m >= 258 && n >= 10);
++
++  /* not enough input or output--restore pointers and return */
++  UNGRAB
++  UPDATE
++  return Z_OK;
++}
+diff --git a/net/ipsec/inflate.c b/net/ipsec/inflate.c
+new file mode 100644
+index 0000000..b0d5d0d
+--- /dev/null
++++ b/net/ipsec/inflate.c
+@@ -0,0 +1,369 @@
++/* inflate.c -- zlib interface to inflate modules
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#define IPCOMP_PREFIX 1
++#include <zlib/zutil.h>
++#include "infblock.h"
++
++struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
++
++typedef enum {
++      METHOD,   /* waiting for method byte */
++      FLAG,     /* waiting for flag byte */
++      DICT4,    /* four dictionary check bytes to go */
++      DICT3,    /* three dictionary check bytes to go */
++      DICT2,    /* two dictionary check bytes to go */
++      DICT1,    /* one dictionary check byte to go */
++      DICT0,    /* waiting for inflateSetDictionary */
++      BLOCKS,   /* decompressing blocks */
++      CHECK4,   /* four check bytes to go */
++      CHECK3,   /* three check bytes to go */
++      CHECK2,   /* two check bytes to go */
++      CHECK1,   /* one check byte to go */
++      DONE,     /* finished check, done */
++      BAD}      /* got an error--stay here */
++inflate_mode;
++
++/* inflate private state */
++struct internal_state {
++
++  /* mode */
++  inflate_mode  mode;   /* current inflate mode */
++
++  /* mode dependent information */
++  union {
++    uInt method;        /* if FLAGS, method byte */
++    struct {
++      uLong was;                /* computed check value */
++      uLong need;               /* stream check value */
++    } check;            /* if CHECK, check values to compare */
++    uInt marker;        /* if BAD, inflateSync's marker bytes count */
++  } sub;        /* submode */
++
++  /* mode independent information */
++  int  nowrap;          /* flag for no wrapper */
++  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
++  inflate_blocks_statef 
++    *blocks;            /* current inflate_blocks state */
++
++};
++
++
++int ZEXPORT inflateReset(z)
++z_streamp z;
++{
++  if (z == Z_NULL || z->state == Z_NULL)
++    return Z_STREAM_ERROR;
++  z->total_in = z->total_out = 0;
++  z->msg = Z_NULL;
++  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
++  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
++  Tracev((stderr, "inflate: reset\n"));
++  return Z_OK;
++}
++
++
++int ZEXPORT inflateEnd(z)
++z_streamp z;
++{
++  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
++    return Z_STREAM_ERROR;
++  if (z->state->blocks != Z_NULL)
++    inflate_blocks_free(z->state->blocks, z);
++  ZFREE(z, z->state);
++  z->state = Z_NULL;
++  Tracev((stderr, "inflate: end\n"));
++  return Z_OK;
++}
++
++
++int ZEXPORT inflateInit2_(z, w, version, stream_size)
++z_streamp z;
++int w;
++const char *version;
++int stream_size;
++{
++  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
++      stream_size != sizeof(z_stream))
++      return Z_VERSION_ERROR;
++
++  /* initialize state */
++  if (z == Z_NULL)
++    return Z_STREAM_ERROR;
++  z->msg = Z_NULL;
++  if (z->zalloc == Z_NULL)
++  {
++    return Z_STREAM_ERROR;
++/*    z->zalloc = zcalloc;
++    z->opaque = (voidpf)0;
++*/
++  }
++  if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
++  if ((z->state = (struct internal_state FAR *)
++       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
++    return Z_MEM_ERROR;
++  z->state->blocks = Z_NULL;
++
++  /* handle undocumented nowrap option (no zlib header or check) */
++  z->state->nowrap = 0;
++  if (w < 0)
++  {
++    w = - w;
++    z->state->nowrap = 1;
++  }
++
++  /* set window size */
++  if (w < 8 || w > 15)
++  {
++    inflateEnd(z);
++    return Z_STREAM_ERROR;
++  }
++  z->state->wbits = (uInt)w;
++
++  /* create inflate_blocks state */
++  if ((z->state->blocks =
++      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
++      == Z_NULL)
++  {
++    inflateEnd(z);
++    return Z_MEM_ERROR;
++  }
++  Tracev((stderr, "inflate: allocated\n"));
++
++  /* reset state */
++  inflateReset(z);
++  return Z_OK;
++}
++
++
++int ZEXPORT inflateInit_(z, version, stream_size)
++z_streamp z;
++const char *version;
++int stream_size;
++{
++  return inflateInit2_(z, DEF_WBITS, version, stream_size);
++}
++
++
++#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
++#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
++
++int ZEXPORT inflate(z, f)
++z_streamp z;
++int f;
++{
++  int r;
++  uInt b;
++
++  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
++    return Z_STREAM_ERROR;
++  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
++  r = Z_BUF_ERROR;
++  while (1) switch (z->state->mode)
++  {
++    case METHOD:
++      NEEDBYTE
++      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
++      {
++        z->state->mode = BAD;
++        z->msg = (char*)"unknown compression method";
++        z->state->sub.marker = 5;       /* can't try inflateSync */
++        break;
++      }
++      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
++      {
++        z->state->mode = BAD;
++        z->msg = (char*)"invalid window size";
++        z->state->sub.marker = 5;       /* can't try inflateSync */
++        break;
++      }
++      z->state->mode = FLAG;
++    case FLAG:
++      NEEDBYTE
++      b = NEXTBYTE;
++      if (((z->state->sub.method << 8) + b) % 31)
++      {
++        z->state->mode = BAD;
++        z->msg = (char*)"incorrect header check";
++        z->state->sub.marker = 5;       /* can't try inflateSync */
++        break;
++      }
++      Tracev((stderr, "inflate: zlib header ok\n"));
++      if (!(b & PRESET_DICT))
++      {
++        z->state->mode = BLOCKS;
++        break;
++      }
++      z->state->mode = DICT4;
++    case DICT4:
++      NEEDBYTE
++      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
++      z->state->mode = DICT3;
++    case DICT3:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
++      z->state->mode = DICT2;
++    case DICT2:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
++      z->state->mode = DICT1;
++    case DICT1:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE;
++      z->adler = z->state->sub.check.need;
++      z->state->mode = DICT0;
++      return Z_NEED_DICT;
++    case DICT0:
++      z->state->mode = BAD;
++      z->msg = (char*)"need dictionary";
++      z->state->sub.marker = 0;       /* can try inflateSync */
++      return Z_STREAM_ERROR;
++    case BLOCKS:
++      r = inflate_blocks(z->state->blocks, z, r);
++      if (r == Z_DATA_ERROR)
++      {
++        z->state->mode = BAD;
++        z->state->sub.marker = 0;       /* can try inflateSync */
++        break;
++      }
++      if (r == Z_OK)
++        r = f;
++      if (r != Z_STREAM_END)
++        return r;
++      r = f;
++      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
++      if (z->state->nowrap)
++      {
++        z->state->mode = DONE;
++        break;
++      }
++      z->state->mode = CHECK4;
++    case CHECK4:
++      NEEDBYTE
++      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
++      z->state->mode = CHECK3;
++    case CHECK3:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
++      z->state->mode = CHECK2;
++    case CHECK2:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
++      z->state->mode = CHECK1;
++    case CHECK1:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE;
++
++      if (z->state->sub.check.was != z->state->sub.check.need)
++      {
++        z->state->mode = BAD;
++        z->msg = (char*)"incorrect data check";
++        z->state->sub.marker = 5;       /* can't try inflateSync */
++        break;
++      }
++      Tracev((stderr, "inflate: zlib check ok\n"));
++      z->state->mode = DONE;
++    case DONE:
++      return Z_STREAM_END;
++    case BAD:
++      return Z_DATA_ERROR;
++    default:
++      return Z_STREAM_ERROR;
++  }
++#ifdef NEED_DUMMY_RETURN
++  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
++#endif
++}
++
++
++int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
++z_streamp z;
++const Bytef *dictionary;
++uInt  dictLength;
++{
++  uInt length = dictLength;
++
++  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
++    return Z_STREAM_ERROR;
++
++  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
++  z->adler = 1L;
++
++  if (length >= ((uInt)1<<z->state->wbits))
++  {
++    length = (1<<z->state->wbits)-1;
++    dictionary += dictLength - length;
++  }
++  inflate_set_dictionary(z->state->blocks, dictionary, length);
++  z->state->mode = BLOCKS;
++  return Z_OK;
++}
++
++
++int ZEXPORT inflateSync(z)
++z_streamp z;
++{
++  uInt n;       /* number of bytes to look at */
++  Bytef *p;     /* pointer to bytes */
++  uInt m;       /* number of marker bytes found in a row */
++  uLong r, w;   /* temporaries to save total_in and total_out */
++
++  /* set up */
++  if (z == Z_NULL || z->state == Z_NULL)
++    return Z_STREAM_ERROR;
++  if (z->state->mode != BAD)
++  {
++    z->state->mode = BAD;
++    z->state->sub.marker = 0;
++  }
++  if ((n = z->avail_in) == 0)
++    return Z_BUF_ERROR;
++  p = z->next_in;
++  m = z->state->sub.marker;
++
++  /* search */
++  while (n && m < 4)
++  {
++    static const Byte mark[4] = {0, 0, 0xff, 0xff};
++    if (*p == mark[m])
++      m++;
++    else if (*p)
++      m = 0;
++    else
++      m = 4 - m;
++    p++, n--;
++  }
++
++  /* restore */
++  z->total_in += p - z->next_in;
++  z->next_in = p;
++  z->avail_in = n;
++  z->state->sub.marker = m;
++
++  /* return no joy or set up to restart on a new block */
++  if (m != 4)
++    return Z_DATA_ERROR;
++  r = z->total_in;  w = z->total_out;
++  inflateReset(z);
++  z->total_in = r;  z->total_out = w;
++  z->state->mode = BLOCKS;
++  return Z_OK;
++}
++
++
++/* Returns true if inflate is currently at the end of a block generated
++ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
++ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
++ * but removes the length bytes of the resulting empty stored block. When
++ * decompressing, PPP checks that at the end of input packet, inflate is
++ * waiting for these length bytes.
++ */
++int ZEXPORT inflateSyncPoint(z)
++z_streamp z;
++{
++  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
++    return Z_STREAM_ERROR;
++  return inflate_blocks_sync_point(z->state->blocks);
++}
+diff --git a/net/ipsec/inftrees.c b/net/ipsec/inftrees.c
+new file mode 100644
+index 0000000..59ffb02
+--- /dev/null
++++ b/net/ipsec/inftrees.c
+@@ -0,0 +1,454 @@
++/* inftrees.c -- generate Huffman trees for efficient decoding
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include <zlib/zutil.h>
++#include "inftrees.h"
++
++#if !defined(BUILDFIXED) && !defined(STDC)
++#  define BUILDFIXED   /* non ANSI compilers may not accept inffixed.h */
++#endif
++
++local const char inflate_copyright[] =
++   " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
++/*
++  If you use the zlib library in a product, an acknowledgment is welcome
++  in the documentation of your product. If for some reason you cannot
++  include such an acknowledgment, I would appreciate that you keep this
++  copyright string in the executable of your product.
++ */
++struct internal_state  {int dummy;}; /* for buggy compilers */
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++
++local int huft_build OF((
++    uIntf *,            /* code lengths in bits */
++    uInt,               /* number of codes */
++    uInt,               /* number of "simple" codes */
++    const uIntf *,      /* list of base values for non-simple codes */
++    const uIntf *,      /* list of extra bits for non-simple codes */
++    inflate_huft * FAR*,/* result: starting table */
++    uIntf *,            /* maximum lookup bits (returns actual) */
++    inflate_huft *,     /* space for trees */
++    uInt *,             /* hufts used in space */
++    uIntf * ));         /* space for values */
++
++/* Tables for deflate from PKZIP's appnote.txt. */
++local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
++        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
++        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
++        /* see note #13 above about 258 */
++local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
++        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
++        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
++local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
++        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
++        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
++        8193, 12289, 16385, 24577};
++local const uInt cpdext[30] = { /* Extra bits for distance codes */
++        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
++        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
++        12, 12, 13, 13};
++
++/*
++   Huffman code decoding is performed using a multi-level table lookup.
++   The fastest way to decode is to simply build a lookup table whose
++   size is determined by the longest code.  However, the time it takes
++   to build this table can also be a factor if the data being decoded
++   is not very long.  The most common codes are necessarily the
++   shortest codes, so those codes dominate the decoding time, and hence
++   the speed.  The idea is you can have a shorter table that decodes the
++   shorter, more probable codes, and then point to subsidiary tables for
++   the longer codes.  The time it costs to decode the longer codes is
++   then traded against the time it takes to make longer tables.
++
++   This results of this trade are in the variables lbits and dbits
++   below.  lbits is the number of bits the first level table for literal/
++   length codes can decode in one step, and dbits is the same thing for
++   the distance codes.  Subsequent tables are also less than or equal to
++   those sizes.  These values may be adjusted either when all of the
++   codes are shorter than that, in which case the longest code length in
++   bits is used, or when the shortest code is *longer* than the requested
++   table size, in which case the length of the shortest code in bits is
++   used.
++
++   There are two different values for the two tables, since they code a
++   different number of possibilities each.  The literal/length table
++   codes 286 possible values, or in a flat code, a little over eight
++   bits.  The distance table codes 30 possible values, or a little less
++   than five bits, flat.  The optimum values for speed end up being
++   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
++   The optimum values may differ though from machine to machine, and
++   possibly even between compilers.  Your mileage may vary.
++ */
++
++
++/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
++#define BMAX 15         /* maximum bit length of any code */
++
++local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
++uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
++uInt n;                 /* number of codes (assumed <= 288) */
++uInt s;                 /* number of simple-valued codes (0..s-1) */
++const uIntf *d;         /* list of base values for non-simple codes */
++const uIntf *e;         /* list of extra bits for non-simple codes */
++inflate_huft * FAR *t;  /* result: starting table */
++uIntf *m;               /* maximum lookup bits, returns actual */
++inflate_huft *hp;       /* space for trees */
++uInt *hn;               /* hufts used in space */
++uIntf *v;               /* working area: values in order of bit length */
++/* Given a list of code lengths and a maximum table size, make a set of
++   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
++   if the given code set is incomplete (the tables are still built in this
++   case), or Z_DATA_ERROR if the input is invalid. */
++{
++
++  uInt a;                       /* counter for codes of length k */
++  uInt c[BMAX+1];               /* bit length count table */
++  uInt f;                       /* i repeats in table every f entries */
++  int g;                        /* maximum code length */
++  int h;                        /* table level */
++  register uInt i;              /* counter, current code */
++  register uInt j;              /* counter */
++  register int k;               /* number of bits in current code */
++  int l;                        /* bits per table (returned in m) */
++  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
++  register uIntf *p;            /* pointer into c[], b[], or v[] */
++  inflate_huft *q;              /* points to current table */
++  struct inflate_huft_s r;      /* table entry for structure assignment */
++  inflate_huft *u[BMAX];        /* table stack */
++  register int w;               /* bits before this table == (l * h) */
++  uInt x[BMAX+1];               /* bit offsets, then code stack */
++  uIntf *xp;                    /* pointer into x */
++  int y;                        /* number of dummy codes added */
++  uInt z;                       /* number of entries in current table */
++
++
++  /* Generate counts for each bit length */
++  p = c;
++#define C0 *p++ = 0;
++#define C2 C0 C0 C0 C0
++#define C4 C2 C2 C2 C2
++  C4                            /* clear c[]--assume BMAX+1 is 16 */
++  p = b;  i = n;
++  do {
++    c[*p++]++;                  /* assume all entries <= BMAX */
++  } while (--i);
++  if (c[0] == n)                /* null input--all zero length codes */
++  {
++    *t = (inflate_huft *)Z_NULL;
++    *m = 0;
++    return Z_OK;
++  }
++
++
++  /* Find minimum and maximum length, bound *m by those */
++  l = *m;
++  for (j = 1; j <= BMAX; j++)
++    if (c[j])
++      break;
++  k = j;                        /* minimum code length */
++  if ((uInt)l < j)
++    l = j;
++  for (i = BMAX; i; i--)
++    if (c[i])
++      break;
++  g = i;                        /* maximum code length */
++  if ((uInt)l > i)
++    l = i;
++  *m = l;
++
++
++  /* Adjust last length count to fill out codes, if needed */
++  for (y = 1 << j; j < i; j++, y <<= 1)
++    if ((y -= c[j]) < 0)
++      return Z_DATA_ERROR;
++  if ((y -= c[i]) < 0)
++    return Z_DATA_ERROR;
++  c[i] += y;
++
++
++  /* Generate starting offsets into the value table for each length */
++  x[1] = j = 0;
++  p = c + 1;  xp = x + 2;
++  while (--i) {                 /* note that i == g from above */
++    *xp++ = (j += *p++);
++  }
++
++
++  /* Make a table of values in order of bit lengths */
++  p = b;  i = 0;
++  do {
++    if ((j = *p++) != 0)
++      v[x[j]++] = i;
++  } while (++i < n);
++  n = x[g];                     /* set n to length of v */
++
++
++  /* Generate the Huffman codes and for each, make the table entries */
++  x[0] = i = 0;                 /* first Huffman code is zero */
++  p = v;                        /* grab values in bit order */
++  h = -1;                       /* no tables yet--level -1 */
++  w = -l;                       /* bits decoded == (l * h) */
++  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
++  q = (inflate_huft *)Z_NULL;   /* ditto */
++  z = 0;                        /* ditto */
++
++  /* go through the bit lengths (k already is bits in shortest code) */
++  for (; k <= g; k++)
++  {
++    a = c[k];
++    while (a--)
++    {
++      /* here i is the Huffman code of length k bits for value *p */
++      /* make tables up to required level */
++      while (k > w + l)
++      {
++        h++;
++        w += l;                 /* previous table always l bits */
++
++        /* compute minimum size table less than or equal to l bits */
++        z = g - w;
++        z = z > (uInt)l ? l : z;        /* table size upper limit */
++        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
++        {                       /* too few codes for k-w bit table */
++          f -= a + 1;           /* deduct codes from patterns left */
++          xp = c + k;
++          if (j < z)
++            while (++j < z)     /* try smaller tables up to z bits */
++            {
++              if ((f <<= 1) <= *++xp)
++                break;          /* enough codes to use up j bits */
++              f -= *xp;         /* else deduct codes from patterns */
++            }
++        }
++        z = 1 << j;             /* table entries for j-bit table */
++
++        /* allocate new table */
++        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
++          return Z_DATA_ERROR;  /* overflow of MANY */
++        u[h] = q = hp + *hn;
++        *hn += z;
++
++        /* connect to last table, if there is one */
++        if (h)
++        {
++          x[h] = i;             /* save pattern for backing up */
++          r.bits = (Byte)l;     /* bits to dump before this table */
++          r.exop = (Byte)j;     /* bits in this table */
++          j = i >> (w - l);
++          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
++          u[h-1][j] = r;        /* connect to last table */
++        }
++        else
++          *t = q;               /* first table is returned result */
++      }
++
++      /* set up table entry in r */
++      r.bits = (Byte)(k - w);
++      if (p >= v + n)
++        r.exop = 128 + 64;      /* out of values--invalid code */
++      else if (*p < s)
++      {
++        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
++        r.base = *p++;          /* simple code is just the value */
++      }
++      else
++      {
++        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
++        r.base = d[*p++ - s];
++      }
++
++      /* fill code-like entries with r */
++      f = 1 << (k - w);
++      for (j = i >> w; j < z; j += f)
++        q[j] = r;
++
++      /* backwards increment the k-bit code i */
++      for (j = 1 << (k - 1); i & j; j >>= 1)
++        i ^= j;
++      i ^= j;
++
++      /* backup over finished tables */
++      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
++      while ((i & mask) != x[h])
++      {
++        h--;                    /* don't need to update q */
++        w -= l;
++        mask = (1 << w) - 1;
++      }
++    }
++  }
++
++
++  /* Return Z_BUF_ERROR if we were given an incomplete table */
++  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
++}
++
++
++int inflate_trees_bits(c, bb, tb, hp, z)
++uIntf *c;               /* 19 code lengths */
++uIntf *bb;              /* bits tree desired/actual depth */
++inflate_huft * FAR *tb; /* bits tree result */
++inflate_huft *hp;       /* space for trees */
++z_streamp z;            /* for messages */
++{
++  int r;
++  uInt hn = 0;          /* hufts used in space */
++  uIntf *v;             /* work area for huft_build */
++
++  if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
++    return Z_MEM_ERROR;
++  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
++                 tb, bb, hp, &hn, v);
++  if (r == Z_DATA_ERROR)
++    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
++  else if (r == Z_BUF_ERROR || *bb == 0)
++  {
++    z->msg = (char*)"incomplete dynamic bit lengths tree";
++    r = Z_DATA_ERROR;
++  }
++  ZFREE(z, v);
++  return r;
++}
++
++
++int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
++uInt nl;                /* number of literal/length codes */
++uInt nd;                /* number of distance codes */
++uIntf *c;               /* that many (total) code lengths */
++uIntf *bl;              /* literal desired/actual bit depth */
++uIntf *bd;              /* distance desired/actual bit depth */
++inflate_huft * FAR *tl; /* literal/length tree result */
++inflate_huft * FAR *td; /* distance tree result */
++inflate_huft *hp;       /* space for trees */
++z_streamp z;            /* for messages */
++{
++  int r;
++  uInt hn = 0;          /* hufts used in space */
++  uIntf *v;             /* work area for huft_build */
++
++  /* allocate work area */
++  if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
++    return Z_MEM_ERROR;
++
++  /* build literal/length tree */
++  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
++  if (r != Z_OK || *bl == 0)
++  {
++    if (r == Z_DATA_ERROR)
++      z->msg = (char*)"oversubscribed literal/length tree";
++    else if (r != Z_MEM_ERROR)
++    {
++      z->msg = (char*)"incomplete literal/length tree";
++      r = Z_DATA_ERROR;
++    }
++    ZFREE(z, v);
++    return r;
++  }
++
++  /* build distance tree */
++  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
++  if (r != Z_OK || (*bd == 0 && nl > 257))
++  {
++    if (r == Z_DATA_ERROR)
++      z->msg = (char*)"oversubscribed distance tree";
++    else if (r == Z_BUF_ERROR) {
++#ifdef PKZIP_BUG_WORKAROUND
++      r = Z_OK;
++    }
++#else
++      z->msg = (char*)"incomplete distance tree";
++      r = Z_DATA_ERROR;
++    }
++    else if (r != Z_MEM_ERROR)
++    {
++      z->msg = (char*)"empty distance tree with lengths";
++      r = Z_DATA_ERROR;
++    }
++    ZFREE(z, v);
++    return r;
++#endif
++  }
++
++  /* done */
++  ZFREE(z, v);
++  return Z_OK;
++}
++
++
++/* build fixed tables only once--keep them here */
++#ifdef BUILDFIXED
++local int fixed_built = 0;
++#define FIXEDH 544      /* number of hufts used by fixed tables */
++local inflate_huft fixed_mem[FIXEDH];
++local uInt fixed_bl;
++local uInt fixed_bd;
++local inflate_huft *fixed_tl;
++local inflate_huft *fixed_td;
++#else
++#include "inffixed.h"
++#endif
++
++
++int inflate_trees_fixed(bl, bd, tl, td, z)
++uIntf *bl;               /* literal desired/actual bit depth */
++uIntf *bd;               /* distance desired/actual bit depth */
++inflate_huft * FAR *tl;  /* literal/length tree result */
++inflate_huft * FAR *td;  /* distance tree result */
++z_streamp z;             /* for memory allocation */
++{
++#ifdef BUILDFIXED
++  /* build fixed tables if not already */
++  if (!fixed_built)
++  {
++    int k;              /* temporary variable */
++    uInt f = 0;         /* number of hufts used in fixed_mem */
++    uIntf *c;           /* length list for huft_build */
++    uIntf *v;           /* work area for huft_build */
++
++    /* allocate memory */
++    if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
++      return Z_MEM_ERROR;
++    if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
++    {
++      ZFREE(z, c);
++      return Z_MEM_ERROR;
++    }
++
++    /* literal table */
++    for (k = 0; k < 144; k++)
++      c[k] = 8;
++    for (; k < 256; k++)
++      c[k] = 9;
++    for (; k < 280; k++)
++      c[k] = 7;
++    for (; k < 288; k++)
++      c[k] = 8;
++    fixed_bl = 9;
++    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
++               fixed_mem, &f, v);
++
++    /* distance table */
++    for (k = 0; k < 30; k++)
++      c[k] = 5;
++    fixed_bd = 5;
++    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
++               fixed_mem, &f, v);
++
++    /* done */
++    ZFREE(z, v);
++    ZFREE(z, c);
++    fixed_built = 1;
++  }
++#endif
++  *bl = fixed_bl;
++  *bd = fixed_bd;
++  *tl = fixed_tl;
++  *td = fixed_td;
++  return Z_OK;
++}
+diff --git a/net/ipsec/infutil.c b/net/ipsec/infutil.c
+new file mode 100644
+index 0000000..b50358f
+--- /dev/null
++++ b/net/ipsec/infutil.c
+@@ -0,0 +1,87 @@
++/* inflate_util.c -- data and routines common to blocks and codes
++ * Copyright (C) 1995-2002 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include <zlib/zutil.h>
++#include "infblock.h"
++#include "inftrees.h"
++#include "infcodes.h"
++#include "infutil.h"
++
++struct inflate_codes_state {int dummy;}; /* for buggy compilers */
++
++/* And'ing with mask[n] masks the lower n bits */
++uInt inflate_mask[17] = {
++    0x0000,
++    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
++    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
++};
++
++
++/* copy as much as possible from the sliding window to the output area */
++int inflate_flush(s, z, r)
++inflate_blocks_statef *s;
++z_streamp z;
++int r;
++{
++  uInt n;
++  Bytef *p;
++  Bytef *q;
++
++  /* local copies of source and destination pointers */
++  p = z->next_out;
++  q = s->read;
++
++  /* compute number of bytes to copy as far as end of window */
++  n = (uInt)((q <= s->write ? s->write : s->end) - q);
++  if (n > z->avail_out) n = z->avail_out;
++  if (n && r == Z_BUF_ERROR) r = Z_OK;
++
++  /* update counters */
++  z->avail_out -= n;
++  z->total_out += n;
++
++  /* update check information */
++  if (s->checkfn != Z_NULL)
++    z->adler = s->check = (*s->checkfn)(s->check, q, n);
++
++  /* copy as far as end of window */
++  zmemcpy(p, q, n);
++  p += n;
++  q += n;
++
++  /* see if more to copy at beginning of window */
++  if (q == s->end)
++  {
++    /* wrap pointers */
++    q = s->window;
++    if (s->write == s->end)
++      s->write = s->window;
++
++    /* compute bytes to copy */
++    n = (uInt)(s->write - q);
++    if (n > z->avail_out) n = z->avail_out;
++    if (n && r == Z_BUF_ERROR) r = Z_OK;
++
++    /* update counters */
++    z->avail_out -= n;
++    z->total_out += n;
++
++    /* update check information */
++    if (s->checkfn != Z_NULL)
++      z->adler = s->check = (*s->checkfn)(s->check, q, n);
++
++    /* copy */
++    zmemcpy(p, q, n);
++    p += n;
++    q += n;
++  }
++
++  /* update pointers */
++  z->next_out = p;
++  s->read = q;
++
++  /* done */
++  return r;
++}
+diff --git a/net/ipsec/initaddr.c b/net/ipsec/initaddr.c
+new file mode 100644
+index 0000000..b8427c6
+--- /dev/null
++++ b/net/ipsec/initaddr.c
+@@ -0,0 +1,51 @@
++/*
++ * initialize address structure
++ * Copyright (C) 2000  Henry Spencer.
++ * 
++ * 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$
++ */
++#include "internal.h"
++#include "freeswan.h"
++
++/*
++ - initaddr - initialize ip_address from bytes
++ */
++err_t				/* NULL for success, else string literal */
++initaddr(src, srclen, af, dst)
++const unsigned char *src;
++size_t srclen;
++int af;				/* address family */
++ip_address *dst;
++{
++	switch (af) {
++	case AF_INET:
++		if (srclen != 4)
++			return "IPv4 address must be exactly 4 bytes";
++		dst->u.v4.sin_family = af;
++		dst->u.v4.sin_port = 0;		/* unused */
++		memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
++		break;
++	case AF_INET6:
++		if (srclen != 16)
++			return "IPv6 address must be exactly 16 bytes";
++		dst->u.v6.sin6_family = af;
++		dst->u.v6.sin6_flowinfo = 0;		/* unused */
++		dst->u.v6.sin6_port = 0;		/* unused */
++		memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
++		break;
++	default:
++		return "unknown address family in initaddr";
++		break;
++	}
++	return NULL;
++}
+diff --git a/net/ipsec/ipcomp.c b/net/ipsec/ipcomp.c
+new file mode 100644
+index 0000000..f62361b
+--- /dev/null
++++ b/net/ipsec/ipcomp.c
+@@ -0,0 +1,721 @@
++/*
++ * IPCOMP zlib interface code.
++ * Copyright (C) 2000  Svenning Soerensen <svenning at post5.tele.dk>
++ * Copyright (C) 2000, 2001  Richard Guy Briggs <rgb at 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$";
++
++/* SSS */
++
++#include <linux/config.h>
++#include <linux/version.h>
++
++#define __NO_VERSION__
++#include <linux/module.h>
++#include <linux/kernel.h> /* printk() */
++
++#include "freeswan/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/etherdevice.h> /* eth_type_trans */
++
++#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 "freeswan/radij.h"
++#include "freeswan/ipsec_encap.h"
++#include "freeswan/ipsec_sa.h"
++
++#include "freeswan/ipsec_xform.h"
++#include "freeswan/ipsec_tunnel.h"
++#include "freeswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
++#include "freeswan/ipsec_ipcomp.h"
++#include "zlib/zlib.h"
++#include "zlib/zutil.h"
++
++#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
++
++#ifdef CONFIG_KLIPS_DEBUG
++int sysctl_ipsec_debug_ipcomp = 0;
++#endif /* CONFIG_KLIPS_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 *ips, 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 == NULL) {
++		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
++			    "klips_debug:skb_compress: "
++			    "passed in NULL skb, returning ERROR.\n");
++		if(flags != NULL) {
++			*flags |= IPCOMP_PARMERROR;
++		}
++		return skb;
++	}
++
++	if(ips == NULL) {
++		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
++			    "klips_debug:skb_compress: "
++			    "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
++		if(flags) {
++			*flags |= IPCOMP_PARMERROR;
++		}
++		return skb;
++	}
++
++	if (flags == NULL) {
++		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
++			    "klips_debug:skb_compress: "
++			    "passed in NULL flags, returning ERROR.\n");
++		ipsec_kfree_skb(skb);
++		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_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 (ips->ips_comp_adapt_skip) {
++		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
++			    "klips_debug:skb_compress: "
++			    "skipping compression: ips_comp_adapt_skip=%d.\n",
++			    ips->ips_comp_adapt_skip);
++		ips->ips_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_KLIPS_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_KLIPS_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 (++(ips->ips_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);
++			ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
++		}
++		else if (ips->ips_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);
++			ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
++			ips->ips_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(ips->ips_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(ips->ips_said.spi),
++		    ntohl(ips->ips_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_KLIPS_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_KLIPS_DEBUG */
++	
++	ips->ips_comp_adapt_skip = 0;
++	ips->ips_comp_adapt_tries = 0;
++	
++	return skb;
++}
++
++struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, 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(!ips && sysctl_ipsec_inbound_policy_check) {
++		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
++			    "klips_error:skb_decompress: "
++			    "passed in NULL ipsec_sa 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");
++		ipsec_kfree_skb(skb);
++		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
++		 && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
++		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
++			    "klips_error:skb_decompress: "
++			    "called with incompatible IPCOMP packet (flags=%d, "
++			    "cpi=%d), ips-compalg=%d, skipping decompression.\n",
++			    ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
++			    ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
++			    ips ? ips->ips_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",
++			    (int)(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_KLIPS_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_KLIPS_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;
++		ipsec_kfree_skb(nskb);
++
++		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",
++		    ips ? ntohl(ips->ips_said.spi) : 0,
++		    ips ? ntohl(ips->ips_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);
++	
++	ipsec_kfree_skb(skb);
++	
++	if (iph->protocol == IPPROTO_COMP)
++	{
++#ifdef CONFIG_KLIPS_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_KLIPS_DEBUG */
++		
++		ipsec_kfree_skb(nskb);
++		return NULL;
++	}
++	
++#ifdef CONFIG_KLIPS_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_KLIPS_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 --git a/net/ipsec/ipsec_ipcomp.c b/net/ipsec/ipsec_ipcomp.c
+new file mode 100644
+index 0000000..301cf5f
+--- /dev/null
++++ b/net/ipsec/ipsec_ipcomp.c
+@@ -0,0 +1,276 @@
++/*
++ * processing code for IPCOMP
++ * Copyright (C) 2003 Michael Richardson <mcr at sandelman.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 ipsec_ipcomp_c_version[] = "RCSID $Id$";
++#include <linux/config.h>
++#include <linux/version.h>
++
++#define __NO_VERSION__
++#include <linux/module.h>
++#include <linux/kernel.h> /* printk() */
++
++#include "freeswan/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 "freeswan/radij.h"
++#include "freeswan/ipsec_encap.h"
++#include "freeswan/ipsec_sa.h"
++
++#include "freeswan/ipsec_radij.h"
++#include "freeswan/ipsec_xform.h"
++#include "freeswan/ipsec_tunnel.h"
++#include "freeswan/ipsec_rcv.h"
++#include "freeswan/ipsec_xmit.h"
++
++#include "freeswan/ipsec_auth.h"
++
++#ifdef CONFIG_KLIPS_IPCOMP
++#include "freeswan/ipsec_ipcomp.h"
++#endif /* CONFIG_KLIPS_IPCOMP */
++
++#include "freeswan/ipsec_proto.h"
++
++#ifdef CONFIG_KLIPS_DEBUG
++int debug_ipcomp = 0;
++#endif /* CONFIG_KLIPS_DEBUG */
++
++
++#ifdef CONFIG_KLIPS_IPCOMP
++enum ipsec_rcv_value
++ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
++			struct sk_buff *skb)
++{
++	int ipcompminlen;
++
++	ipcompminlen = irs->hard_header_len + sizeof(struct iphdr);
++
++	if(skb->len < (ipcompminlen + 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,
++			    irs->ipsaddr_txt);
++		if(irs->stats) {
++			irs->stats->rx_errors++;
++		}
++		return IPSEC_RCV_BADLEN;
++	}
++
++	irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)(skb->data + irs->iphlen);
++	irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
++	return IPSEC_RCV_OK;
++}
++
++enum ipsec_rcv_value
++ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
++{
++	unsigned int flags = 0;
++	struct ipsec_sa *ipsp = irs->ipsp;
++	struct sk_buff *skb;
++
++	skb=irs->skb;
++
++	ipsec_xmit_dmp("ipcomp", skb->data, skb->len);
++
++	if(ipsp == NULL) {
++		return IPSEC_RCV_SAIDNOTFOUND;
++	}
++
++#if 0
++	/* we want to check that this wasn't the first SA on the list, because
++	 * we don't support bare IPCOMP, for unexplained reasons. MCR
++	 */
++	if (ipsp->ips_onext != NULL) {
++		KLIPS_PRINT(debug_rcv,
++			    "klips_debug:ipsec_rcv: "
++			    "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n",
++			    irs->sa_len ? irs->sa : " (error)");
++		if(irs->stats) {
++			irs->stats->rx_dropped++;
++		}
++
++		return IPSEC_RCV_IPCOMPALONE;
++	}
++#endif
++
++	if(sysctl_ipsec_inbound_policy_check &&
++	   ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
++	     (ipsp->ips_encalg != ntohl(irs->said.spi))   /* this is a workaround for peer non-compliance with rfc2393 */
++		    ))) {
++		char sa2[SATOT_BUF];
++		size_t sa_len2 = 0;
++
++		sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2));
++
++		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",
++			    irs->sa_len ? irs->sa : " (error)",
++			    ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
++			    ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
++			    (__u32)ntohl(irs->said.spi),
++			    ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
++			    ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
++		if(irs->stats) {
++			irs->stats->rx_dropped++;
++		}
++		return IPSEC_RCV_SAIDNOTFOUND;
++	}
++
++	ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
++	irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
++
++	skb = skb_decompress(skb, ipsp, &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 (irs->stats) {
++			if (flags)
++				irs->stats->rx_errors++;
++			else
++				irs->stats->rx_dropped++;
++		}
++		return IPSEC_RCV_IPCOMPFAILED;
++	}
++
++	/* make sure we update the pointer */
++	irs->skb = skb;
++	
++#ifdef NET_21
++	irs->ipp = skb->nh.iph;
++#else /* NET_21 */
++	irs->ipp = skb->ip_hdr;
++#endif /* NET_21 */
++
++	ipsp->ips_comp_ratio_dbytes += ntohs(irs->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",
++		    irs->sa_len ? irs->sa : " (error)",
++		    (__u32)ntohl(irs->said.spi),
++		    ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
++		    ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
++		    irs->next_header);
++	KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
++
++	return IPSEC_RCV_OK;
++}
++
++enum ipsec_xmit_value
++ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
++{
++  unsigned int flags = 0;
++#ifdef CONFIG_KLIPS_DEBUG
++  unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
++#endif /* CONFIG_KLIPS_DEBUG */
++
++  ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
++
++  ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
++
++#ifdef NET_21
++  ixs->iph = ixs->skb->nh.iph;
++#else /* NET_21 */
++  ixs->iph = ixs->skb->ip_hdr;
++#endif /* NET_21 */
++  
++  ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
++  
++#ifdef CONFIG_KLIPS_DEBUG
++  if (debug_tunnel & DB_TN_CROUT)
++    {
++      if (old_tot_len > ntohs(ixs->iph->tot_len))
++	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
++		    "klips_debug:ipsec_xmit_encap_once: "
++		    "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
++		    old_tot_len, ntohs(ixs->iph->tot_len),
++		    ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
++		    ntohl(ixs->ipsp->ips_said.spi),
++		    (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
++      else
++	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
++		    "klips_debug:ipsec_xmit_encap_once: "
++		    "packet did not compress (flags = %d).\n",
++		    flags);
++    }
++#endif /* CONFIG_KLIPS_DEBUG */
++
++  return IPSEC_XMIT_OK;
++}
++
++struct xform_functions ipcomp_xform_funcs[]={
++	{rcv_checks:  ipsec_rcv_ipcomp_checks,
++	 rcv_decrypt: ipsec_rcv_ipcomp_decomp,
++	 xmit_setup:  ipsec_xmit_ipcomp_setup,
++	 xmit_headroom: 0,
++	 xmit_needtailroom: 0,
++	},
++};
++
++#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_KLIPS_IPCOMP
++struct inet_protocol comp_protocol =
++{
++	ipsec_rcv,			/* COMP handler		*/
++	NULL,				/* COMP error control	*/
++#ifdef NETDEV_25
++	1,				/* no policy */
++#else
++	0,				/* next */
++	IPPROTO_COMP,			/* protocol ID */
++	0,				/* copy */
++	NULL,				/* data */
++	"COMP"				/* name */
++#endif
++};
++#endif /* CONFIG_KLIPS_IPCOMP */
++#endif
++
++#endif /* CONFIG_KLIPS_IPCOMP */
+diff --git a/net/ipsec/ipsec_ipip.c b/net/ipsec/ipsec_ipip.c
+new file mode 100644
+index 0000000..e00cf53
+--- /dev/null
++++ b/net/ipsec/ipsec_ipip.c
+@@ -0,0 +1,131 @@
++/*
++ * processing code for IPIP
++ * Copyright (C) 2003 Michael Richardson <mcr at sandelman.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 ipsec_ipip_c_version[] = "RCSID $Id$";
++#include <linux/config.h>
++#include <linux/version.h>
++
++#define __NO_VERSION__
++#include <linux/module.h>
++#include <linux/kernel.h> /* printk() */
++
++#include "freeswan/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 "freeswan/radij.h"
++#include "freeswan/ipsec_encap.h"
++#include "freeswan/ipsec_sa.h"
++
++#include "freeswan/ipsec_radij.h"
++#include "freeswan/ipsec_xform.h"
++#include "freeswan/ipsec_tunnel.h"
++#include "freeswan/ipsec_rcv.h"
++#include "freeswan/ipsec_xmit.h"
++
++#include "freeswan/ipsec_ipip.h"
++
++#include "freeswan/ipsec_proto.h"
++
++enum ipsec_xmit_value
++ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
++{
++  ixs->iph->version  = 4;
++
++  switch(sysctl_ipsec_tos) {
++  case 0:
++#ifdef NET_21
++    ixs->iph->tos = ixs->skb->nh.iph->tos;
++#else /* NET_21 */
++    ixs->iph->tos = ixs->skb->ip_hdr->tos;
++#endif /* NET_21 */
++    break;
++  case 1:
++    ixs->iph->tos = 0;
++    break;
++  default:
++    break;
++  }
++#ifdef NET_21
++#ifdef NETDEV_23
++  ixs->iph->ttl      = sysctl_ip_default_ttl;
++#else /* NETDEV_23 */
++  ixs->iph->ttl      = ip_statistics.IpDefaultTTL;
++#endif /* NETDEV_23 */
++#else /* NET_21 */
++  ixs->iph->ttl      = 64; /* ip_statistics.IpDefaultTTL; */
++#endif /* NET_21 */
++  ixs->iph->frag_off = 0;
++  ixs->iph->saddr    = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
++  ixs->iph->daddr    = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
++  ixs->iph->protocol = IPPROTO_IPIP;
++  ixs->iph->ihl      = sizeof(struct iphdr) >> 2;
++  
++  KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
++  
++  ixs->newdst = (__u32)ixs->iph->daddr;
++  ixs->newsrc = (__u32)ixs->iph->saddr;
++  
++#ifdef NET_21
++  ixs->skb->h.ipiph = ixs->skb->nh.iph;
++#endif /* NET_21 */
++  return IPSEC_XMIT_OK;
++}
++
++struct xform_functions ipip_xform_funcs[]={
++  {	rcv_checks:         NULL,
++	rcv_setup_auth:     NULL,
++	rcv_calc_auth:      NULL,
++	rcv_decrypt:        NULL,
++
++	xmit_setup:         ipsec_xmit_ipip_setup,
++	xmit_headroom:      sizeof(struct iphdr),
++	xmit_needtailroom:  0,
++  },
++};
++
++
++
++
++
++
++
+diff --git a/net/ipsec/ipsec_life.c b/net/ipsec/ipsec_life.c
+new file mode 100644
+index 0000000..7d6d0e3
+--- /dev/null
++++ b/net/ipsec/ipsec_life.c
+@@ -0,0 +1,277 @@
++/*
++ * @(#) lifetime structure utilities
++ *
++ * Copyright (C) 2001  Richard Guy Briggs  <rgb at freeswan.org>
++ *                 and Michael Richardson  <mcr at 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$
++ *
++ */
++
++/* 
++ * 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 "freeswan/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 "freeswan/radij.h"
++#include "freeswan/ipsec_life.h"
++#include "freeswan/ipsec_xform.h"
++#include "freeswan/ipsec_eroute.h"
++#include "freeswan/ipsec_encap.h"
++#include "freeswan/ipsec_radij.h"
++
++#include "freeswan/ipsec_sa.h"
++#include "freeswan/ipsec_tunnel.h"
++#include "freeswan/ipsec_ipe4.h"
++#include "freeswan/ipsec_esp.h"
++
++#ifdef CONFIG_KLIPS_IPCOMP
++#include "freeswan/ipsec_ipcomp.h"
++#endif /* CONFIG_KLIPS_IPCOMP */
++
++#include <pfkeyv2.h>
++#include <pfkey.h>
++
++#include "freeswan/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_lifetime_check: "
++			    "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_lifetime_check: "
++			    "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 (or would take,
++ * if the buffer were large enough: snprintf semantics).
++ * 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 = ipsec_snprintf(buffer, buflen,
++			       "%s(%Lu,%Lu,%Lu)",
++			       lifename,
++			       count,
++			       lifetime->ipl_soft,
++			       lifetime->ipl_hard);
++#else /* XXX high 32 bits are not displayed */
++		len = ipsec_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: ipsec_life.c,v $
++ * Revision 1.1.1.1  2004/08/20 11:34:11  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:09:58  rupert
++ * +: Add Freeswan IPSec 2.06
++ *
++ * Revision 1.16  2004/04/12 19:48:31  dhr
++ *
++ * convert more sprintf calls to ipsec_snprintf and then fix surrounding code
++ *
++ * Revision 1.15  2004/03/29 02:21:43  sam
++ * Replacing calls to snprintf().
++ *
++ * Revision 1.14  2004/02/24 17:17:04  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.13  2003/12/13 04:09:21  mcr
++ * 	AH transform removed.
++ *
++ * Revision 1.12  2003/12/06 21:21:38  mcr
++ * 	split up receive path into per-transform files, for
++ * 	easier later removal.
++ *
++ * Revision 1.11  2003/12/04 19:05:54  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.10  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.8  2003/02/06 02:00:10  rgb
++ * Fixed incorrect debugging text label
++ *
++ * Revision 1.7  2002/05/23 07:16:26  rgb
++ * Fixed absolute/relative reference to lifetime count printout.
++ *
++ * Revision 1.6  2002/04/24 07:55:32  mcr
++ * 	#include patches and Makefiles for post-reorg compilation.
++ *
++ * Revision 1.5  2002/04/24 07:36:28  mcr
++ * Moved from ./klips/net/ipsec/ipsec_life.c,v
++ *
++ * 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 --git a/net/ipsec/ipsec_mast.c b/net/ipsec/ipsec_mast.c
+new file mode 100644
+index 0000000..3176faa
+--- /dev/null
++++ b/net/ipsec/ipsec_mast.c
+@@ -0,0 +1,1109 @@
++/*
++ * IPSEC MAST code.
++ * Copyright (C) 1996, 1997  John Ioannidis.
++ * Copyright (C) 1998, 1999, 2000, 2001, 2002  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_mast_c_version[] = "RCSID $Id$";
++
++#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 "freeswan/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>
++#include <asm/uaccess.h>
++#include <linux/in6.h>
++#include <net/dst.h>
++#undef dev_kfree_skb
++#define dev_kfree_skb(a,b) kfree_skb(a)
++#define PHYSDEV_TYPE
++#include <asm/checksum.h>
++#include <net/icmp.h>		/* icmp_send() */
++#include <net/ip.h>
++#include <linux/netfilter_ipv4.h>
++
++#include <linux/if_arp.h>
++
++#include "freeswan/radij.h"
++#include "freeswan/ipsec_life.h"
++#include "freeswan/ipsec_xform.h"
++#include "freeswan/ipsec_eroute.h"
++#include "freeswan/ipsec_encap.h"
++#include "freeswan/ipsec_radij.h"
++#include "freeswan/ipsec_sa.h"
++#include "freeswan/ipsec_tunnel.h"
++#include "freeswan/ipsec_mast.h"
++#include "freeswan/ipsec_ipe4.h"
++#include "freeswan/ipsec_esp.h"
++
++#include <pfkeyv2.h>
++#include <pfkey.h>
++
++#include "freeswan/ipsec_proto.h"
++
++int ipsec_maxdevice_count = -1;
++
++DEBUG_NO_STATIC int
++ipsec_mast_open(struct net_device *dev)
++{
++	struct ipsecpriv *prv = dev->priv;
++	
++	/*
++	 * Can't open until attached.
++	 */
++
++	KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++		    "klips_debug:ipsec_mast_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_mast_close(struct net_device *dev)
++{
++	MOD_DEC_USE_COUNT;
++	return 0;
++}
++
++static inline int ipsec_mast_xmit2(struct sk_buff *skb)
++{
++	return ip_send(skb);
++}
++
++enum ipsec_xmit_value
++ipsec_mast_send(struct ipsec_xmit_state*ixs)
++{
++	/* new route/dst cache code from James Morris */
++	ixs->skb->dev = ixs->physdev;
++	/*skb_orphan(ixs->skb);*/
++	if((ixs->error = ip_route_output(&ixs->route,
++				    ixs->skb->nh.iph->daddr,
++				    ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
++				    RT_TOS(ixs->skb->nh.iph->tos),
++				    ixs->physdev->iflink /* rgb: should this be 0? */))) {
++		ixs->stats->tx_errors++;
++		KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
++			    "klips_debug:ipsec_xmit_send: "
++			    "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
++			    ixs->error,
++			    ixs->route->u.dst.dev->name);
++		return IPSEC_XMIT_ROUTEERR;
++	}
++	if(ixs->dev == ixs->route->u.dst.dev) {
++		ip_rt_put(ixs->route);
++		/* This is recursion, drop it. */
++		ixs->stats->tx_errors++;
++		KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
++			    "klips_debug:ipsec_xmit_send: "
++			    "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
++			    ixs->dev->name);
++		return IPSEC_XMIT_RECURSDETECT;
++	}
++	dst_release(ixs->skb->dst);
++	ixs->skb->dst = &ixs->route->u.dst;
++	ixs->stats->tx_bytes += ixs->skb->len;
++	if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
++		ixs->stats->tx_errors++;
++		printk(KERN_WARNING
++		       "klips_error:ipsec_xmit_send: "
++		       "tried to __skb_pull nh-data=%ld, %d available.  This should never happen, please report.\n",
++		       (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
++		       ixs->skb->len);
++		return IPSEC_XMIT_PUSHPULLERR;
++	}
++	__skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
++#ifdef SKB_RESET_NFCT
++	nf_conntrack_put(ixs->skb->nfct);
++	ixs->skb->nfct = NULL;
++#ifdef CONFIG_NETFILTER_DEBUG
++	ixs->skb->nf_debug = 0;
++#endif /* CONFIG_NETFILTER_DEBUG */
++#endif /* SKB_RESET_NFCT */
++	KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
++		    "klips_debug:ipsec_xmit_send: "
++		    "...done, calling ip_send() on device:%s\n",
++		    ixs->skb->dev ? ixs->skb->dev->name : "NULL");
++	KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
++	{
++		int err;
++
++		err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
++			      ipsec_mast_xmit2);
++		if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
++			if(net_ratelimit())
++				printk(KERN_ERR
++				       "klips_error:ipsec_xmit_send: "
++				       "ip_send() failed, err=%d\n", 
++				       -err);
++			ixs->stats->tx_errors++;
++			ixs->stats->tx_aborted_errors++;
++			ixs->skb = NULL;
++			return IPSEC_XMIT_IPSENDFAILURE;
++		}
++	}
++	ixs->stats->tx_packets++;
++
++	ixs->skb = NULL;
++	
++	return IPSEC_XMIT_OK;
++}
++
++void
++ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
++{
++#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
++	netif_wake_queue(ixs->dev);
++#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
++	ixs->dev->tbusy = 0;
++#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
++	if(ixs->saved_header) {
++		kfree(ixs->saved_header);
++	}
++	if(ixs->skb) {
++		dev_kfree_skb(ixs->skb, FREE_WRITE);
++	}
++	if(ixs->oskb) {
++		dev_kfree_skb(ixs->oskb, FREE_WRITE);
++	}
++	if (ixs->ips.ips_ident_s.data) {
++		kfree(ixs->ips.ips_ident_s.data);
++	}
++	if (ixs->ips.ips_ident_d.data) {
++		kfree(ixs->ips.ips_ident_d.data);
++	}
++}
++
++#if 0
++/*
++ *	This function assumes it is being called from dev_queue_xmit()
++ *	and that skb is filled properly by that function.
++ */
++int
++ipsec_mast_start_xmit(struct sk_buff *skb
++		      , struct net_device *dev
++		      , IPsecSAref_t SAref)
++{
++	struct ipsec_xmit_state ixs_mem;
++	struct ipsec_xmit_state *ixs = &ixs_mem;
++	enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
++
++	/* dev could be a mast device, but should be optional, I think... */
++	/* SAref is also optional, but one of the two must be present. */
++	/* I wonder if it could accept no device or saref and guess? */
++
++/*	ipsec_xmit_sanity_check_dev(ixs); */
++
++	ipsec_xmit_sanity_check_skb(ixs);
++
++	ipsec_xmit_adjust_hard_header(ixs);
++
++	stat = ipsec_xmit_encap_bundle(ixs);
++	if(stat != IPSEC_XMIT_OK) {
++		/* SA processing failed */
++	}
++
++	ipsec_xmit_hard_header_restore();
++}
++#endif
++
++DEBUG_NO_STATIC struct net_device_stats *
++ipsec_mast_get_stats(struct net_device *dev)
++{
++	return &(((struct ipsecpriv *)(dev->priv))->mystats);
++}
++
++/*
++ * Revectored calls.
++ * For each of these calls, a field exists in our private structure.
++ */
++
++DEBUG_NO_STATIC int
++ipsec_mast_hard_header(struct sk_buff *skb
++		       , struct net_device *dev
++		       , unsigned short type
++		       , void *daddr
++		       , void *saddr
++		       , unsigned len)
++{
++	struct ipsecpriv *prv = dev->priv;
++	struct net_device *tmp;
++	int ret;
++	struct net_device_stats *stats;	/* This device's statistics */
++	
++	if(skb == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_hard_header: "
++			    "no skb...\n");
++		return -ENODATA;
++	}
++
++	if(dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_hard_header: "
++			    "no device...\n");
++		return -ENODEV;
++	}
++
++	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++		    "klips_debug:ipsec_mast_hard_header: "
++		    "skb->dev=%s dev=%s.\n",
++		    skb->dev ? skb->dev->name : "NULL",
++		    dev->name);
++	
++	if(prv == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_hard_header: "
++			    "no private space associated with dev=%s\n",
++			    dev->name ? dev->name : "NULL");
++		return -ENODEV;
++	}
++
++	stats = (struct net_device_stats *) &(prv->mystats);
++
++	if(prv->dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_hard_header: "
++			    "no physical device associated with dev=%s\n",
++			    dev->name ? dev->name : "NULL");
++		stats->tx_dropped++;
++		return -ENODEV;
++	}
++
++	/* check if we have to send a IPv6 packet. It might be a Router
++	   Solicitation, where the building of the packet happens in
++	   reverse order:
++	   1. ll hdr,
++	   2. IPv6 hdr,
++	   3. ICMPv6 hdr
++	   -> skb->nh.raw is still uninitialized when this function is
++	   called!!  If this is no IPv6 packet, we can print debugging
++	   messages, otherwise we skip all debugging messages and just
++	   build the ll header */
++	if(type != ETH_P_IPV6) {
++		/* execute this only, if we don't have to build the
++		   header for a IPv6 packet */
++		if(!prv->hard_header) {
++			KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++				    "klips_debug:ipsec_mast_hard_header: "
++				    "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
++				    saddr,
++				    daddr,
++				    len,
++				    type,
++				    dev->name);
++			KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
++					"ip=%08x->%08x\n",
++					(__u32)ntohl(skb->nh.iph->saddr),
++					(__u32)ntohl(skb->nh.iph->daddr) );
++			stats->tx_dropped++;
++			return -ENODEV;
++		}
++		
++#define da ((struct net_device *)(prv->dev))->dev_addr
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_hard_header: "
++			    "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
++			    saddr,
++			    daddr,
++			    len,
++			    type,
++			    dev->name,
++			    prv->dev->name,
++			    da[0], da[1], da[2], da[3], da[4], da[5]);
++		KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
++			    "ip=%08x->%08x\n",
++			    (__u32)ntohl(skb->nh.iph->saddr),
++			    (__u32)ntohl(skb->nh.iph->daddr) );
++	} else {
++		KLIPS_PRINT(debug_mast,
++			    "klips_debug:ipsec_mast_hard_header: "
++			    "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
++	}                                                                       
++	tmp = skb->dev;
++	skb->dev = prv->dev;
++	ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
++	skb->dev = tmp;
++	return ret;
++}
++
++DEBUG_NO_STATIC int
++ipsec_mast_rebuild_header(struct sk_buff *skb)
++{
++	struct ipsecpriv *prv = skb->dev->priv;
++	struct net_device *tmp;
++	int ret;
++	struct net_device_stats *stats;	/* This device's statistics */
++	
++	if(skb->dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_rebuild_header: "
++			    "no device...");
++		return -ENODEV;
++	}
++
++	if(prv == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_rebuild_header: "
++			    "no private space associated with dev=%s",
++			    skb->dev->name ? skb->dev->name : "NULL");
++		return -ENODEV;
++	}
++
++	stats = (struct net_device_stats *) &(prv->mystats);
++
++	if(prv->dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_rebuild_header: "
++			    "no physical device associated with dev=%s",
++			    skb->dev->name ? skb->dev->name : "NULL");
++		stats->tx_dropped++;
++		return -ENODEV;
++	}
++
++	if(!prv->rebuild_header) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_rebuild_header: "
++			    "physical device has been detached, packet dropped skb->dev=%s->NULL ",
++			    skb->dev->name);
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "ip=%08x->%08x\n",
++			    (__u32)ntohl(skb->nh.iph->saddr),
++			    (__u32)ntohl(skb->nh.iph->daddr) );
++		stats->tx_dropped++;
++		return -ENODEV;
++	}
++
++	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++		    "klips_debug:ipsec_mast: "
++		    "Revectored rebuild_header dev=%s->%s ",
++		    skb->dev->name, prv->dev->name);
++	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++		    "ip=%08x->%08x\n",
++		    (__u32)ntohl(skb->nh.iph->saddr),
++		    (__u32)ntohl(skb->nh.iph->daddr) );
++	tmp = skb->dev;
++	skb->dev = prv->dev;
++	
++	ret = prv->rebuild_header(skb);
++	skb->dev = tmp;
++	return ret;
++}
++
++DEBUG_NO_STATIC int
++ipsec_mast_set_mac_address(struct net_device *dev, void *addr)
++{
++	struct ipsecpriv *prv = dev->priv;
++	
++	struct net_device_stats *stats;	/* This device's statistics */
++	
++	if(dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_set_mac_address: "
++			    "no device...");
++		return -ENODEV;
++	}
++
++	if(prv == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_set_mac_address: "
++			    "no private space associated with dev=%s",
++			    dev->name ? dev->name : "NULL");
++		return -ENODEV;
++	}
++
++	stats = (struct net_device_stats *) &(prv->mystats);
++
++	if(prv->dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_set_mac_address: "
++			    "no physical device associated with dev=%s",
++			    dev->name ? dev->name : "NULL");
++		stats->tx_dropped++;
++		return -ENODEV;
++	}
++
++	if(!prv->set_mac_address) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_set_mac_address: "
++			    "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
++			    dev->name);
++		return -ENODEV;
++	}
++
++	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++		    "klips_debug:ipsec_mast_set_mac_address: "
++		    "Revectored dev=%s->%s addr=0p%p\n",
++		    dev->name, prv->dev->name, addr);
++	return prv->set_mac_address(prv->dev, addr);
++
++}
++
++DEBUG_NO_STATIC void
++ipsec_mast_cache_update(struct hh_cache *hh
++			, struct net_device *dev
++			, unsigned char *  haddr)
++{
++	struct ipsecpriv *prv = dev->priv;
++	
++	struct net_device_stats *stats;	/* This device's statistics */
++	
++	if(dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_cache_update: "
++			    "no device...");
++		return;
++	}
++
++	if(prv == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_cache_update: "
++			    "no private space associated with dev=%s",
++			    dev->name ? dev->name : "NULL");
++		return;
++	}
++
++	stats = (struct net_device_stats *) &(prv->mystats);
++
++	if(prv->dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_cache_update: "
++			    "no physical device associated with dev=%s",
++			    dev->name ? dev->name : "NULL");
++		stats->tx_dropped++;
++		return;
++	}
++
++	if(!prv->header_cache_update) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_cache_update: "
++			    "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
++			    dev->name);
++		return;
++	}
++
++	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++		    "klips_debug:ipsec_mast: "
++		    "Revectored cache_update\n");
++	prv->header_cache_update(hh, prv->dev, haddr);
++	return;
++}
++
++DEBUG_NO_STATIC int
++ipsec_mast_neigh_setup(struct neighbour *n)
++{
++	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++		    "klips_debug:ipsec_mast_neigh_setup:\n");
++
++        if (n->nud_state == NUD_NONE) {
++                n->ops = &arp_broken_ops;
++                n->output = n->ops->output;
++        }
++        return 0;
++}
++
++DEBUG_NO_STATIC int
++ipsec_mast_neigh_setup_dev(struct net_device *dev
++			   , struct neigh_parms *p)
++{
++	KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++		    "klips_debug:ipsec_mast_neigh_setup_dev: "
++		    "setting up %s\n",
++		    dev ? dev->name : "NULL");
++
++        if (p->tbl->family == AF_INET) {
++                p->neigh_setup = ipsec_mast_neigh_setup;
++                p->ucast_probes = 0;
++                p->mcast_probes = 0;
++        }
++        return 0;
++}
++
++/*
++ * We call the attach routine to attach another device.
++ */
++
++DEBUG_NO_STATIC int
++ipsec_mast_attach(struct net_device *dev
++		  , struct device *physdev)
++{
++        int i;
++	struct ipsecpriv *prv = dev->priv;
++
++	if(dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_attach: "
++			    "no device...");
++		return -ENODEV;
++	}
++
++	if(prv == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_attach: "
++			    "no private space associated with dev=%s",
++			    dev->name ? dev->name : "NULL");
++		return -ENODATA;
++	}
++
++	prv->dev = physdev;
++	prv->hard_start_xmit = physdev->hard_start_xmit;
++	prv->get_stats = physdev->get_stats;
++
++	if (physdev->hard_header) {
++		prv->hard_header = physdev->hard_header;
++		dev->hard_header = ipsec_mast_hard_header;
++	} else
++		dev->hard_header = NULL;
++	
++	if (physdev->rebuild_header) {
++		prv->rebuild_header = physdev->rebuild_header;
++		dev->rebuild_header = ipsec_mast_rebuild_header;
++	} else
++		dev->rebuild_header = NULL;
++	
++	if (physdev->set_mac_address) {
++		prv->set_mac_address = physdev->set_mac_address;
++		dev->set_mac_address = ipsec_mast_set_mac_address;
++	} else
++		dev->set_mac_address = NULL;
++	
++	if (physdev->header_cache_update) {
++		prv->header_cache_update = physdev->header_cache_update;
++		dev->header_cache_update = ipsec_mast_cache_update;
++	} else
++		dev->header_cache_update = NULL;
++
++	dev->hard_header_len = physdev->hard_header_len;
++
++/*	prv->neigh_setup        = physdev->neigh_setup; */
++	dev->neigh_setup        = ipsec_mast_neigh_setup_dev;
++	dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
++	prv->mtu = physdev->mtu;
++
++#ifdef PHYSDEV_TYPE
++	dev->type = physdev->type; /* ARPHRD_MAST; */
++#endif /*  PHYSDEV_TYPE */
++
++	dev->addr_len = physdev->addr_len;
++	for (i=0; i<dev->addr_len; i++) {
++		dev->dev_addr[i] = physdev->dev_addr[i];
++	}
++#ifdef CONFIG_KLIPS_DEBUG
++	if(debug_mast & DB_MAST_INIT) {
++		printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
++		       "physical device %s being attached has HW address: %2x",
++		       physdev->name, physdev->dev_addr[0]);
++		for (i=1; i < physdev->addr_len; i++) {
++			printk(":%02x", physdev->dev_addr[i]);
++		}
++		printk("\n");
++	}
++#endif /* CONFIG_KLIPS_DEBUG */
++
++	return 0;
++}
++
++/*
++ * We call the detach routine to detach the ipsec mast from another device.
++ */
++
++DEBUG_NO_STATIC int
++ipsec_mast_detach(struct net_device *dev)
++{
++        int i;
++	struct ipsecpriv *prv = dev->priv;
++
++	if(dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_detach: "
++			    "no device...");
++		return -ENODEV;
++	}
++
++	if(prv == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
++			    "klips_debug:ipsec_mast_detach: "
++			    "no private space associated with dev=%s",
++			    dev->name ? dev->name : "NULL");
++		return -ENODATA;
++	}
++
++	KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++		    "klips_debug:ipsec_mast_detach: "
++		    "physical device %s being detached from virtual device %s\n",
++		    prv->dev ? prv->dev->name : "NULL",
++		    dev->name);
++
++	prv->dev = NULL;
++	prv->hard_start_xmit = NULL;
++	prv->get_stats = NULL;
++
++	prv->hard_header = NULL;
++#ifdef DETACH_AND_DOWN
++	dev->hard_header = NULL;
++#endif /* DETACH_AND_DOWN */
++	
++	prv->rebuild_header = NULL;
++#ifdef DETACH_AND_DOWN
++	dev->rebuild_header = NULL;
++#endif /* DETACH_AND_DOWN */
++	
++	prv->set_mac_address = NULL;
++#ifdef DETACH_AND_DOWN
++	dev->set_mac_address = NULL;
++#endif /* DETACH_AND_DOWN */
++	
++	prv->header_cache_update = NULL;
++#ifdef DETACH_AND_DOWN
++	dev->header_cache_update = NULL;
++#endif /* DETACH_AND_DOWN */
++
++#ifdef DETACH_AND_DOWN
++	dev->neigh_setup        = NULL;
++#endif /* DETACH_AND_DOWN */
++
++	dev->hard_header_len = 0;
++#ifdef DETACH_AND_DOWN
++	dev->mtu = 0;
++#endif /* DETACH_AND_DOWN */
++	prv->mtu = 0;
++	for (i=0; i<MAX_ADDR_LEN; i++) {
++		dev->dev_addr[i] = 0;
++	}
++	dev->addr_len = 0;
++#ifdef PHYSDEV_TYPE
++	dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
++#endif /*  PHYSDEV_TYPE */
++	
++	return 0;
++}
++
++/*
++ * We call the clear routine to detach all ipsec masts from other devices.
++ */
++DEBUG_NO_STATIC int
++ipsec_mast_clear(void)
++{
++	int i;
++	struct net_device *ipsecdev = NULL, *prvdev;
++	struct ipsecpriv *prv;
++	char name[9];
++	int ret;
++
++	KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++		    "klips_debug:ipsec_mast_clear: .\n");
++
++	for(i = 0; i < IPSEC_NUM_IF; i++) {
++		sprintf(name, IPSEC_DEV_FORMAT, i);
++		if((ipsecdev = ipsec_dev_get(name)) != NULL) {
++			if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
++				prvdev = (struct net_device *)(prv->dev);
++				if(prvdev) {
++					KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++						    "klips_debug:ipsec_mast_clear: "
++						    "physical device for device %s is %s\n",
++						    name, prvdev->name);
++					if((ret = ipsec_mast_detach(ipsecdev))) {
++						KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++							    "klips_debug:ipsec_mast_clear: "
++							    "error %d detatching device %s from device %s.\n",
++							    ret, name, prvdev->name);
++						return ret;
++					}
++				}
++			}
++		}
++	}
++	return 0;
++}
++
++DEBUG_NO_STATIC int
++ipsec_mast_ioctl(struct net_device *dev
++		 , struct ifreq *ifr, int cmd)
++{
++	struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
++	struct ipsecpriv *prv = dev->priv;
++	struct net_device *them; /* physical device */
++#ifdef CONFIG_IP_ALIAS
++	char *colon;
++	char realphysname[IFNAMSIZ];
++#endif /* CONFIG_IP_ALIAS */
++	
++	if(dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_ioctl: "
++			    "device not supplied.\n");
++		return -ENODEV;
++	}
++
++	KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++		    "klips_debug:ipsec_mast_ioctl: "
++		    "tncfg service call #%d for dev=%s\n",
++		    cmd,
++		    dev->name ? dev->name : "NULL");
++	switch (cmd) {
++	/* attach a virtual ipsec? device to a physical device */
++	case IPSEC_SET_DEV:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_ioctl: "
++			    "calling ipsec_mast_attatch...\n");
++#ifdef CONFIG_IP_ALIAS
++		/* If this is an IP alias interface, get its real physical name */
++		strncpy(realphysname, cf->cf_name, IFNAMSIZ);
++		realphysname[IFNAMSIZ-1] = 0;
++		colon = strchr(realphysname, ':');
++		if (colon) *colon = 0;
++		them = ipsec_dev_get(realphysname);
++#else /* CONFIG_IP_ALIAS */
++		them = ipsec_dev_get(cf->cf_name);
++#endif /* CONFIG_IP_ALIAS */
++
++		if (them == NULL) {
++			KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++				    "klips_debug:ipsec_mast_ioctl: "
++				    "physical device %s requested is null\n",
++				    cf->cf_name);
++			return -ENXIO;
++		}
++		
++#if 0
++		if (them->flags & IFF_UP) {
++			KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++				    "klips_debug:ipsec_mast_ioctl: "
++				    "physical device %s requested is not up.\n",
++				    cf->cf_name);
++			return -ENXIO;
++		}
++#endif
++		
++		if (prv && prv->dev) {
++			KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++				    "klips_debug:ipsec_mast_ioctl: "
++				    "virtual device is already connected to %s.\n",
++				    prv->dev->name ? prv->dev->name : "NULL");
++			return -EBUSY;
++		}
++		return ipsec_mast_attach(dev, them);
++
++	case IPSEC_DEL_DEV:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_ioctl: "
++			    "calling ipsec_mast_detatch.\n");
++		if (! prv->dev) {
++			KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++				    "klips_debug:ipsec_mast_ioctl: "
++				    "physical device not connected.\n");
++			return -ENODEV;
++		}
++		return ipsec_mast_detach(dev);
++	       
++	case IPSEC_CLR_DEV:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_ioctl: "
++			    "calling ipsec_mast_clear.\n");
++		return ipsec_mast_clear();
++
++	default:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_ioctl: "
++			    "unknown command %d.\n",
++			    cmd);
++		return -EOPNOTSUPP;
++	}
++}
++
++int
++ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
++{
++	struct net_device *dev = ptr;
++	struct net_device *ipsec_dev;
++	struct ipsecpriv *priv;
++	char name[9];
++	int i;
++
++	if (dev == NULL) {
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "dev=NULL for event type %ld.\n",
++			    event);
++		return(NOTIFY_DONE);
++	}
++
++	/* check for loopback devices */
++	if (dev && (dev->flags & IFF_LOOPBACK)) {
++		return(NOTIFY_DONE);
++	}
++
++	switch (event) {
++	case NETDEV_DOWN:
++		/* look very carefully at the scope of these compiler
++		   directives before changing anything... -- RGB */
++
++	case NETDEV_UNREGISTER:
++		switch (event) {
++		case NETDEV_DOWN:
++			KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++				    "klips_debug:ipsec_mast_device_event: "
++				    "NETDEV_DOWN dev=%s flags=%x\n",
++				    dev->name,
++				    dev->flags);
++			if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
++				printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
++				       dev->name);
++			}
++			break;
++		case NETDEV_UNREGISTER:
++			KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++				    "klips_debug:ipsec_mast_device_event: "
++				    "NETDEV_UNREGISTER dev=%s flags=%x\n",
++				    dev->name,
++				    dev->flags);
++			break;
++		}
++		
++		/* find the attached physical device and detach it. */
++		for(i = 0; i < IPSEC_NUM_IF; i++) {
++			sprintf(name, IPSEC_DEV_FORMAT, i);
++			ipsec_dev = ipsec_dev_get(name);
++			if(ipsec_dev) {
++				priv = (struct ipsecpriv *)(ipsec_dev->priv);
++				if(priv) {
++					;
++					if(((struct net_device *)(priv->dev)) == dev) {
++						/* dev_close(ipsec_dev); */
++						/* return */ ipsec_mast_detach(ipsec_dev);
++						KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++							    "klips_debug:ipsec_mast_device_event: "
++							    "device '%s' has been detached.\n",
++							    ipsec_dev->name);
++						break;
++					}
++				} else {
++					KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++						    "klips_debug:ipsec_mast_device_event: "
++						    "device '%s' has no private data space!\n",
++						    ipsec_dev->name);
++				}
++			}
++		}
++		break;
++	case NETDEV_UP:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "NETDEV_UP dev=%s\n",
++			    dev->name);
++		break;
++	case NETDEV_REBOOT:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "NETDEV_REBOOT dev=%s\n",
++			    dev->name);
++		break;
++	case NETDEV_CHANGE:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "NETDEV_CHANGE dev=%s flags=%x\n",
++			    dev->name,
++			    dev->flags);
++		break;
++	case NETDEV_REGISTER:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "NETDEV_REGISTER dev=%s\n",
++			    dev->name);
++		break;
++	case NETDEV_CHANGEMTU:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
++			    dev->name,
++			    dev->mtu);
++		break;
++	case NETDEV_CHANGEADDR:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "NETDEV_CHANGEADDR dev=%s\n",
++			    dev->name);
++		break;
++	case NETDEV_GOING_DOWN:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "NETDEV_GOING_DOWN dev=%s\n",
++			    dev->name);
++		break;
++	case NETDEV_CHANGENAME:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "NETDEV_CHANGENAME dev=%s\n",
++			    dev->name);
++		break;
++	default:
++		KLIPS_PRINT(debug_mast & DB_MAST_INIT,
++			    "klips_debug:ipsec_mast_device_event: "
++			    "event type %ld unrecognised for dev=%s\n",
++			    event,
++			    dev->name);
++		break;
++	}
++	return NOTIFY_DONE;
++}
++
++/*
++ *	Called when an ipsec mast device is initialized.
++ *	The ipsec mast device structure is passed to us.
++ */
++ 
++int
++ipsec_mast_init(struct net_device *dev)
++{
++	int i;
++
++	KLIPS_PRINT(debug_mast,
++		    "klips_debug:ipsec_mast_init: "
++		    "allocating %lu bytes initialising device: %s\n",
++		    (unsigned long) sizeof(struct ipsecpriv),
++		    dev->name ? dev->name : "NULL");
++
++	/* Add our mast functions to the device */
++	dev->open		= ipsec_mast_open;
++	dev->stop		= ipsec_mast_close;
++	dev->hard_start_xmit	= ipsec_mast_start_xmit;
++	dev->get_stats		= ipsec_mast_get_stats;
++
++	dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
++	if (dev->priv == NULL)
++		return -ENOMEM;
++	memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
++
++	for(i = 0; i < sizeof(zeroes); i++) {
++		((__u8*)(zeroes))[i] = 0;
++	}
++	
++	dev->set_multicast_list = NULL;
++	dev->do_ioctl		= ipsec_mast_ioctl;
++	dev->hard_header	= NULL;
++	dev->rebuild_header 	= NULL;
++	dev->set_mac_address 	= NULL;
++	dev->header_cache_update= NULL;
++	dev->neigh_setup        = ipsec_mast_neigh_setup_dev;
++	dev->hard_header_len 	= 0;
++	dev->mtu		= 0;
++	dev->addr_len		= 0;
++	dev->type		= ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
++	dev->tx_queue_len	= 10;		/* Small queue */
++	memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN);	/* what if this is not attached to ethernet? */
++
++	/* New-style flags. */
++	dev->flags		= IFF_NOARP /* 0 */ /* Petr Novak */;
++	dev_init_buffers(dev);
++
++	/* We're done.  Have I forgotten anything? */
++	return 0;
++}
++
++/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
++/*  Module specific interface (but it links with the rest of IPSEC)  */
++/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
++
++int
++ipsec_mast_probe(struct net_device *dev)
++{
++	ipsec_mast_init(dev); 
++	return 0;
++}
++
++int 
++ipsec_mast_init_devices(void)
++{
++	return 0;
++}
++
++/* void */
++int
++ipsec_mast_cleanup_devices(void)
++{
++	int error = 0;
++	int i;
++	char name[10];
++	struct net_device *dev_mast;
++	
++	for(i = 0; i < ipsec_mastdevice_count; i++) {
++		sprintf(name, MAST_DEV_FORMAT, i);
++		if((dev_mast = ipsec_dev_get(name)) == NULL) {
++			break;
++		}
++		unregister_netdev(dev_mast);
++		kfree(dev_mast->priv);
++		dev_mast->priv=NULL;
++	}
++	return error;
++}
++
++/*
++ * $Log: ipsec_mast.c,v $
++ * Revision 1.1.1.1  2004/08/20 11:34:11  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:09:58  rupert
++ * +: Add Freeswan IPSec 2.06
++ *
++ * Revision 1.8  2004/02/24 17:17:04  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.7  2004/02/22 06:50:42  mcr
++ * 	kernel 2.6 port - merged with 2.4 code.
++ *
++ * Revision 1.6.6.1  2004/02/20 14:10:18  mcr
++ * 	moved code to net/ipsec/ to make 2.6 happy.
++ *
++ * Revision 1.6  2003/12/13 04:09:21  mcr
++ * 	AH transform removed.
++ *
++ * Revision 1.5  2003/12/04 19:05:54  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.4  2003/11/07 02:58:06  mcr
++ * 	backout of port-selector and X.509 patches
++ *
++ * Revision 1.2  2003/06/22 20:06:17  mcr
++ * 	refactored mast code still had lots of ipsecX junk in it.
++ *
++ * Revision 1.1  2003/02/12 19:31:12  rgb
++ * Refactored from ipsec_tunnel.c
++ *
++ */
+diff --git a/net/ipsec/ipsec_md5c.c b/net/ipsec/ipsec_md5c.c
+new file mode 100644
+index 0000000..26749ce
+--- /dev/null
++++ b/net/ipsec/ipsec_md5c.c
+@@ -0,0 +1,451 @@
++/*
++ * RCSID $Id$
++ */
++
++/*
++ * 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 "freeswan/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(void *vcontext)
++{
++  MD5_CTX *context = vcontext;                                     
++
++  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 (vcontext, input, inputLen)
++     void *vcontext;
++     unsigned char *input;                                /* input block */
++     __u32 inputLen;                     /* length of input block */
++{
++  MD5_CTX *context = vcontext;                                     
++  __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, vcontext)
++unsigned char digest[16];                         /* message digest */
++void *vcontext;                                       /* context */
++{
++  MD5_CTX *context = vcontext;                                     
++  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: ipsec_md5c.c,v $
++ * Revision 1.1.1.1  2004/08/20 11:34:11  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:09:58  rupert
++ * +: Add Freeswan IPSec 2.06
++ *
++ * Revision 1.7  2002/09/10 01:45:14  mcr
++ * 	changed type of MD5_CTX and SHA1_CTX to void * so that
++ * 	the function prototypes would match, and could be placed
++ * 	into a pointer to a function.
++ *
++ * Revision 1.6  2002/04/24 07:55:32  mcr
++ * 	#include patches and Makefiles for post-reorg compilation.
++ *
++ * Revision 1.5  2002/04/24 07:36:28  mcr
++ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
++ *
++ * 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 --git a/net/ipsec/ipsec_proc.c b/net/ipsec/ipsec_proc.c
+new file mode 100644
+index 0000000..3a48319
+--- /dev/null
++++ b/net/ipsec/ipsec_proc.c
+@@ -0,0 +1,1100 @@
++/*
++ * @(#) /proc file system interface code.
++ *
++ * Copyright (C) 1996, 1997  John Ioannidis.
++ * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs <rgb at freeswan.org>
++ *                                 2001  Michael Richardson <mcr at 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$";
++
++#include <linux/config.h>
++#include <linux/version.h>
++#define __NO_VERSION__
++#include <linux/module.h>
++#include <linux/kernel.h> /* printk() */
++
++#include "freeswan/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 "freeswan/radij.h"
++
++#include "freeswan/ipsec_life.h"
++#include "freeswan/ipsec_stats.h"
++#include "freeswan/ipsec_sa.h"
++
++#include "freeswan/ipsec_encap.h"
++#include "freeswan/ipsec_radij.h"
++#include "freeswan/ipsec_xform.h"
++#include "freeswan/ipsec_tunnel.h"
++#include "freeswan/ipsec_xmit.h"
++
++#include "freeswan/ipsec_rcv.h"
++
++#include "freeswan/ipsec_esp.h"
++#include "freeswan/ipsec_ipcomp.h"
++
++#include "freeswan/ipsec_proto.h"
++
++#include <pfkeyv2.h>
++#include <pfkey.h>
++
++#ifdef CONFIG_PROC_FS
++
++#ifdef IPSEC_PROC_SUBDIRS
++static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
++static struct proc_dir_entry *proc_eroute_dir    = NULL;
++static struct proc_dir_entry *proc_spi_dir       = NULL;
++static struct proc_dir_entry *proc_spigrp_dir    = NULL;
++static struct proc_dir_entry *proc_birth_dir     = NULL;
++static struct proc_dir_entry *proc_stats_dir     = NULL;
++#endif
++
++struct ipsec_birth_reply ipsec_ipv4_birth_packet;
++struct ipsec_birth_reply ipsec_ipv6_birth_packet;
++
++/* ipsec_snprintf: like snprintf except
++ * - size is signed and a negative value is treated as if it were 0
++ * - the returned result is never negative --
++ *   an error generates a "?" or null output (depending on space).
++ *   (Our callers are too lazy to check for an error return.)
++ */
++int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
++{
++	va_list args;
++	int i;
++	size_t possize = size < 0? 0 : size;
++
++	va_start(args, fmt);
++	i = vsnprintf(buf,possize,fmt,args);
++	va_end(args);
++	if (i < 0) {
++	    /* create empty output in place of error */
++	    i = 0;
++	    if (size > 0) {
++		*buf = '\0';
++	    }
++	}
++	return i;
++}
++
++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};
++
++#ifdef CONFIG_KLIPS_DEBUG
++	if (debug_radij & DB_RJ_DUMPTREES)
++	  rj_dumptrees();			/* XXXXXXXXX */
++#endif /* CONFIG_KLIPS_DEBUG */
++
++	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
++		    "klips_debug:ipsec_eroute_get_info: "
++		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
++		    buffer,
++		    *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 */
++	return w.len - (offset - w.begin);
++}
++
++IPSEC_PROCFS_DEBUG_NO_STATIC
++int
++ipsec_spi_get_info(char *buffer,
++		   char **start,
++		   off_t offset,
++		   int length    IPSEC_PROC_LAST_ARG)
++{
++	const int max_content = length > 0? length-1 : 0;	/* limit of useful snprintf output */
++	int len = 0;
++	off_t begin = 0;
++	int i;
++	struct ipsec_sa *sa_p;
++	char sa[SATOT_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=0p%p, *start=0p%p, offset=%d, length=%d\n",
++		    buffer,
++		    *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) {
++			atomic_inc(&sa_p->ips_refcount);
++			sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
++			len += ipsec_snprintf(buffer+len, length-len, "%s ",
++				       sa_len ? sa : " (error)");
++
++			len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
++				       IPS_XFORM_NAME(sa_p));
++
++			len += ipsec_snprintf(buffer+len, length-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 += ipsec_snprintf(buffer+len, length-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 += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
++					       buf_s, buf_d);
++			}
++			
++			if(sa_p->ips_iv_bits) {
++				int j;
++				len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
++					       sa_p->ips_iv_bits);
++
++				for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
++					len += ipsec_snprintf(buffer+len, length-len, "%02x",
++						       (__u32)((__u8*)(sa_p->ips_iv))[j]);
++				}
++			}
++
++			if(sa_p->ips_encalg || sa_p->ips_authalg) {
++				if(sa_p->ips_replaywin) {
++					len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
++						       sa_p->ips_replaywin);
++				}
++				if(sa_p->ips_errs.ips_replaywin_errs) {
++					len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
++						       sa_p->ips_errs.ips_replaywin_errs);
++				}
++				if(sa_p->ips_replaywin_lastseq) {
++                                       len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
++						      sa_p->ips_replaywin_lastseq);
++				}
++				if(sa_p->ips_replaywin_bitmap) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
++					len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
++						       sa_p->ips_replaywin_bitmap);
++#else
++					len += ipsec_snprintf(buffer+len, length-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 += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
++						       sa_p->ips_replaywin_maxdiff);
++				}
++			}
++			if(sa_p->ips_flags & ~EMT_INBOUND) {
++				len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
++					       sa_p->ips_flags & ~EMT_INBOUND);
++				len += ipsec_snprintf(buffer+len, length-len, "<");
++				/* flag printing goes here */
++				len += ipsec_snprintf(buffer+len, length-len, ">");
++			}
++			if(sa_p->ips_auth_bits) {
++				len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
++					       sa_p->ips_auth_bits);
++			}
++			if(sa_p->ips_key_bits_a) {
++				len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
++					       sa_p->ips_key_bits_a);
++			}
++			if(sa_p->ips_errs.ips_auth_errs) {
++				len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
++					       sa_p->ips_errs.ips_auth_errs);
++			}
++			if(sa_p->ips_key_bits_e) {
++				len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
++					       sa_p->ips_key_bits_e);
++			}
++			if(sa_p->ips_errs.ips_encsize_errs) {
++				len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
++					       sa_p->ips_errs.ips_encsize_errs);
++			}
++			if(sa_p->ips_errs.ips_encpad_errs) {
++				len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
++					       sa_p->ips_errs.ips_encpad_errs);
++			}
++			
++			len += ipsec_snprintf(buffer+len, length-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 += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
++					       jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
++#else
++				len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
++					       jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
++#endif
++			}
++
++#ifdef CONFIG_KLIPS_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 += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
++					       sa_p->ips_comp_ratio_dbytes,
++					       sa_p->ips_comp_ratio_cbytes);
++#else
++ 				len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
++					       (unsigned long)sa_p->ips_comp_ratio_dbytes,
++					       (unsigned long)sa_p->ips_comp_ratio_cbytes);
++#endif
++			}
++#endif /* CONFIG_KLIPS_IPCOMP */
++
++ 			len += ipsec_snprintf(buffer+len, length-len, " refcount=%d",
++				       atomic_read(&sa_p->ips_refcount));
++
++ 			len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
++				       sa_p->ips_ref);
++#ifdef CONFIG_KLIPS_DEBUG
++			if(debug_xform) {
++ 			len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
++				       (unsigned long)IPsecSAref2table(sa_p->ips_ref),
++				       (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
++			}
++#endif /* CONFIG_KLIPS_DEBUG */
++
++ 			len += ipsec_snprintf(buffer+len, length-len, "\n");
++
++			atomic_dec(&sa_p->ips_refcount);
++
++			if (len >= max_content) {
++				/* we've done all that can fit -- stop loops */
++				len = max_content;	/* truncate crap */
++				goto done_spi_i;
++			} else {
++				const off_t pos = begin + len;	/* file position of end of what we've generated */
++
++				if (pos <= offset) {
++					/* all is before first interesting character:
++					 * discard, but note where we are.
++					 */
++					len = 0;
++					begin = pos;
++				}
++			}
++		}
++	}
++
++ done_spi_i:	
++	spin_unlock_bh(&tdb_lock);
++
++	*start = buffer + (offset - begin);	/* Start of wanted data */
++	return len - (offset - begin);
++}
++
++IPSEC_PROCFS_DEBUG_NO_STATIC
++int
++ipsec_spigrp_get_info(char *buffer,
++		      char **start,
++		      off_t offset,
++		      int length     IPSEC_PROC_LAST_ARG)
++{
++	const int max_content = length > 0? length-1 : 0;	/* limit of useful snprintf output */
++	int len = 0;
++	off_t begin = 0;
++	int i;
++	struct ipsec_sa *sa_p, *sa_p2;
++	char sa[SATOT_BUF];
++	size_t sa_len;
++
++	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
++		    "klips_debug:ipsec_spigrp_get_info: "
++		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
++		    buffer,
++		    *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 != NULL;
++		     sa_p = sa_p->ips_hnext)
++		{
++			atomic_inc(&sa_p->ips_refcount);
++			if(sa_p->ips_inext == NULL) {
++				sa_p2 = sa_p;
++				while(sa_p2 != NULL) {
++					atomic_inc(&sa_p2->ips_refcount);
++					sa_len = satot(&sa_p2->ips_said,
++						       'x', sa, sizeof(sa));
++					
++					len += ipsec_snprintf(buffer+len, length-len, "%s ",
++						       sa_len ? sa : " (error)");
++					atomic_dec(&sa_p2->ips_refcount);
++					sa_p2 = sa_p2->ips_onext;
++				}
++				len += ipsec_snprintf(buffer+len, length-len, "\n");
++			}
++			atomic_dec(&sa_p->ips_refcount);
++
++			if (len >= max_content) {
++				/* we've done all that can fit -- stop loops */
++				len = max_content;	/* truncate crap */
++				goto done_spigrp_i;
++			} else {
++				const off_t pos = begin + len;	/* file position of end of what we've generated */
++
++				if (pos <= offset) {
++					/* all is before first interesting character:
++					 * discard, but note where we are.
++					 */
++					len = 0;
++					begin = pos;
++				}
++			}
++		}
++	}
++
++ done_spigrp_i:	
++	spin_unlock_bh(&tdb_lock);
++
++	*start = buffer + (offset - begin);	/* Start of wanted data */
++	return len - (offset - begin);
++}
++
++
++IPSEC_PROCFS_DEBUG_NO_STATIC
++int
++ipsec_tncfg_get_info(char *buffer,
++		     char **start,
++		     off_t offset,
++		     int length     IPSEC_PROC_LAST_ARG)
++{
++	const int max_content = length > 0? length-1 : 0;	/* limit of useful snprintf output */
++	int len = 0;
++	off_t begin = 0;
++	int i;
++	char name[9];
++	struct net_device *dev, *privdev;
++	struct ipsecpriv *priv;
++
++	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
++		    "klips_debug:ipsec_tncfg_get_info: "
++		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
++		    buffer,
++		    *start,
++		    (int)offset,
++		    length);
++
++	for(i = 0; i < IPSEC_NUM_IF; i++) {
++		sprintf(name, IPSEC_DEV_FORMAT, i);
++		dev = __ipsec_dev_get(name);
++		if(dev) {
++			priv = (struct ipsecpriv *)(dev->priv);
++ 			len += ipsec_snprintf(buffer+len, length-len, "%s",
++				       dev->name);
++			if(priv) {
++				privdev = (struct net_device *)(priv->dev);
++ 				len += ipsec_snprintf(buffer+len, length-len, " -> %s",
++					       privdev ? privdev->name : "NULL");
++ 				len += ipsec_snprintf(buffer+len, length-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 += ipsec_snprintf(buffer+len, length-len, "\n");
++
++			if (len >= max_content) {
++				/* we've done all that can fit -- stop loop */
++				len = max_content;	/* truncate crap */
++				break;
++			} else {
++				const off_t pos = begin + len;	/* file position of end of what we've generated */
++
++				if (pos <= offset) {
++					/* all is before first interesting character:
++					 * discard, but note where we are.
++					 */
++					len = 0;
++					begin = pos;
++				}
++			}
++		}
++	}
++	*start = buffer + (offset - begin);	/* Start of wanted data */
++	return len - (offset - begin);
++}
++
++IPSEC_PROCFS_DEBUG_NO_STATIC
++int
++ipsec_version_get_info(char *buffer,
++		       char **start,
++		       off_t offset,
++		       int length  IPSEC_PROC_LAST_ARG)
++{
++	const int max_content = length > 0? length-1 : 0;	/* limit of useful snprintf output */
++	int len;
++
++	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
++		    "klips_debug:ipsec_version_get_info: "
++		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
++		    buffer,
++		    *start,
++		    (int)offset,
++		    length);
++
++	len = ipsec_snprintf(buffer, length, "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
++
++	if (len >= max_content)
++		len = max_content;	/* truncate crap */
++
++	*start = buffer + offset;	/* Start of wanted data */
++	return len > offset? len - offset : 0;
++}
++
++IPSEC_PROCFS_DEBUG_NO_STATIC
++int
++ipsec_birth_info(char *page,
++		 char **start,
++		 off_t offset,
++		 int count,
++		 int *eof,
++		 void *data)
++{
++	struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
++	int len;
++
++	if(offset >= ibr->packet_template_len) {
++		if(eof) {
++			*eof=1;
++		}
++		return 0;
++	}
++
++	len = ibr->packet_template_len;
++	len -= offset;
++	if (len > count)
++		len = count;
++
++	memcpy(page + offset, ibr->packet_template+offset, len);
++
++	return len;
++}
++
++IPSEC_PROCFS_DEBUG_NO_STATIC
++int
++ipsec_birth_set(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
++	int len;
++
++	MOD_INC_USE_COUNT;
++        if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
++                len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
++	} else {
++                len = count;
++	}
++
++        if(copy_from_user(ibr->packet_template, buffer, len)) {
++                MOD_DEC_USE_COUNT;
++                return -EFAULT;
++        }
++	ibr->packet_template_len = len;
++
++        MOD_DEC_USE_COUNT;
++
++        return len;
++}
++
++
++#ifdef CONFIG_KLIPS_DEBUG
++IPSEC_PROCFS_DEBUG_NO_STATIC
++int
++ipsec_klipsdebug_get_info(char *buffer,
++			  char **start,
++			  off_t offset,
++			  int length      IPSEC_PROC_LAST_ARG)
++{
++	const int max_content = length > 0? length-1 : 0;	/* limit of useful snprintf output */
++	int len = 0;
++
++	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
++		    "klips_debug:ipsec_klipsdebug_get_info: "
++		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
++		    buffer,
++		    *start,
++		    (int)offset,
++		    length);
++
++ 	len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
++ 	len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
++ 	len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
++ 	len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
++ 	len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
++ 	len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
++ 	len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
++ 	len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
++
++	if (len >= max_content)
++		len = max_content;	/* truncate crap */
++
++	*start = buffer + offset;	/* Start of wanted data */
++	return len > offset? len - offset : 0;
++}
++#endif /* CONFIG_KLIPS_DEBUG */
++
++IPSEC_PROCFS_DEBUG_NO_STATIC
++int
++ipsec_stats_get_int_info(char *buffer,
++			 char **start,
++			 off_t offset,
++			 int   length,
++			 int   *eof,
++			 void  *data)
++{
++	const int max_content = length > 0? length-1 : 0;	/* limit of useful snprintf output */
++	int len;
++	int *thing;
++
++	thing = (int *)data;
++	
++	len = ipsec_snprintf(buffer, length, "%08x\n", *thing);
++
++	if (len >= max_content)
++		len = max_content;	/* truncate crap */
++
++	*start = buffer + offset;	/* Start of wanted data */
++	return len > offset? len - offset : 0;
++}
++
++#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_KLIPS_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_KLIPS_DEBUG */
++#endif /* !PROC_FS_2325 */
++#endif /* CONFIG_PROC_FS */
++
++#if defined(PROC_FS_2325) 
++struct ipsec_proc_list {
++	char                   *name;
++	struct proc_dir_entry **parent;
++	struct proc_dir_entry **dir;
++	read_proc_t            *readthing;
++	write_proc_t           *writething;
++	void                   *data;
++};
++static struct ipsec_proc_list proc_items[]={
++#ifdef CONFIG_KLIPS_DEBUG
++	{"klipsdebug", &proc_net_ipsec_dir, NULL,             ipsec_klipsdebug_get_info, NULL, NULL},
++#endif
++	{"eroute",     &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
++	{"all",        &proc_eroute_dir,    NULL,             ipsec_eroute_get_info,     NULL, NULL},
++	{"spi",        &proc_net_ipsec_dir, &proc_spi_dir,    NULL, NULL, NULL},
++	{"all",        &proc_spi_dir,       NULL,             ipsec_spi_get_info,        NULL, NULL},
++	{"spigrp",     &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
++	{"all",        &proc_spigrp_dir,    NULL,             ipsec_spigrp_get_info,     NULL, NULL},
++	{"birth",      &proc_net_ipsec_dir, &proc_birth_dir,  NULL,      NULL, NULL},
++	{"ipv4",       &proc_birth_dir,     NULL,             ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
++	{"ipv6",       &proc_birth_dir,     NULL,             ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
++	{"tncfg",      &proc_net_ipsec_dir, NULL,             ipsec_tncfg_get_info,      NULL, NULL},
++	{"stats",      &proc_net_ipsec_dir, &proc_stats_dir,  NULL,      NULL, NULL},
++	{"trap_count", &proc_stats_dir,     NULL,             ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
++	{"trap_sendcount", &proc_stats_dir, NULL,             ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
++	{"version",    &proc_net_ipsec_dir, NULL,             ipsec_version_get_info,    NULL, NULL},
++	{NULL,         NULL,                NULL,             NULL,      NULL, NULL}
++};
++#endif
++		
++int
++ipsec_proc_init()
++{
++	int error = 0;
++#ifdef IPSEC_PROC_SUBDIRS
++	struct proc_dir_entry *item;
++#endif
++
++	/*
++	 * just complain because pluto won't run without /proc!
++	 */
++#ifndef CONFIG_PROC_FS 
++#error You must have PROC_FS built in to use KLIPS
++#endif
++
++        /* for 2.0 kernels */
++#if !defined(PROC_FS_2325) && !defined(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_KLIPS_DEBUG
++	error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
++#endif /* CONFIG_KLIPS_DEBUG */
++#endif
++
++	/* for 2.2 kernels */
++#if !defined(PROC_FS_2325) && defined(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_KLIPS_DEBUG
++	error |= proc_register(proc_net, &ipsec_klipsdebug);
++#endif /* CONFIG_KLIPS_DEBUG */
++#endif
++
++	/* for 2.4 kernels */
++#if defined(PROC_FS_2325)
++	/* create /proc/net/ipsec */
++
++	/* zero these out before we initialize /proc/net/ipsec/birth/stuff */
++	memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
++	memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
++
++	proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
++	if(proc_net_ipsec_dir == NULL) {
++		/* no point in continuing */
++		return 1;
++	} 	
++
++	{
++		struct ipsec_proc_list *it;
++
++		it=proc_items;
++		while(it->name!=NULL) {
++			if(it->dir) {
++				/* make a dir instead */
++				item = proc_mkdir(it->name, *it->parent);
++				*it->dir = item;
++			} else {
++				item = create_proc_entry(it->name, 0400, *it->parent);
++			}
++			if(item) {
++				item->read_proc  = it->readthing;
++				item->write_proc = it->writething;
++				item->data       = it->data;
++#ifdef MODULE
++				item->owner = THIS_MODULE;
++#endif
++			} else {
++				error |= 1;
++			}
++			it++;
++		}
++	}
++	
++	/* now create some symlinks to provide compatibility */
++	proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
++	proc_symlink("ipsec_spi",    proc_net, "ipsec/spi/all");
++	proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
++	proc_symlink("ipsec_tncfg",  proc_net, "ipsec/tncfg");
++	proc_symlink("ipsec_version",proc_net, "ipsec/version");
++	proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
++
++#endif /* !PROC_FS_2325 */
++
++	return error;
++}
++
++void
++ipsec_proc_cleanup()
++{
++
++	/* for 2.0 and 2.2 kernels */
++#if !defined(PROC_FS_2325) 
++
++#ifdef CONFIG_KLIPS_DEBUG
++	if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
++		printk("klips_debug:ipsec_cleanup: "
++		       "cannot unregister /proc/net/ipsec_klipsdebug\n");
++#endif /* CONFIG_KLIPS_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");
++#endif
++
++	/* for 2.4 kernels */
++#if defined(PROC_FS_2325)
++	{
++		struct ipsec_proc_list *it;
++
++		/* find end of list */
++		it=proc_items;
++		while(it->name!=NULL) {
++			it++;
++		}
++		it--;
++
++		do {
++			remove_proc_entry(it->name, *it->parent);
++			it--;
++		} while(it > proc_items);
++	}
++
++
++#ifdef CONFIG_KLIPS_DEBUG
++	remove_proc_entry("ipsec_klipsdebug", proc_net);
++#endif /* CONFIG_KLIPS_DEBUG */
++	remove_proc_entry("ipsec_eroute",     proc_net);
++	remove_proc_entry("ipsec_spi",        proc_net);
++	remove_proc_entry("ipsec_spigrp",     proc_net);
++	remove_proc_entry("ipsec_tncfg",      proc_net);
++	remove_proc_entry("ipsec_version",    proc_net);
++	remove_proc_entry("ipsec",            proc_net);
++#endif /* 2.4 kernel */
++}
++
++/*
++ * $Log: ipsec_proc.c,v $
++ * Revision 1.1.1.1  2004/08/20 11:34:11  r04482
++ * no message
++ *
++ * Revision 1.1  2004/08/02 02:09:58  rupert
++ * +: Add Freeswan IPSec 2.06
++ *
++ * Revision 1.36  2004/04/12 19:48:31  dhr
++ *
++ * convert more sprintf calls to ipsec_snprintf and then fix surrounding code
++ *
++ * Revision 1.35  2004/04/12 17:39:05  dhr
++ *
++ * simplify and clarify struct wsbuf (used in generating /proc/net/ipsec_eroute)
++ *
++ * Revision 1.34  2004/04/12 17:36:19  dhr
++ *
++ * refine handling buffer end in generating /proc/net/ipsec_eroute
++ *
++ * Revision 1.33  2004/04/12 04:46:35  sam
++ * - ipsec_snprintf returns 0 length string when vsnprintf returns error (because
++ *   callers of ipsec_snprintf don't handle an error return)
++ * - in ipsec_eroute_get_info, fix case offset != w.begin
++ * - in ipsec_rj_walker_procprint, remove scar tissue.
++ * - in ipsec_rj_walker_procprint, be handle the fact that an overflowing snprintf
++ *   jams a NUL at the end of the buffer.
++ *
++ * Revision 1.32  2004/03/24 01:17:51  mcr
++ * 	fixes for sprintf() problem.
++ *
++ * Revision 1.31  2004/02/24 17:17:04  mcr
++ * 	s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
++ * 	turn it on/off as well.
++ *
++ * Revision 1.30  2004/02/22 06:50:42  mcr
++ * 	kernel 2.6 port - merged with 2.4 code.
++ *
++ * Revision 1.29.6.1  2004/02/20 14:10:18  mcr
++ * 	moved code to net/ipsec/ to make 2.6 happy.
++ *
++ * Revision 1.29  2003/12/13 04:09:21  mcr
++ * 	AH transform removed.
++ *
++ * Revision 1.28  2003/12/06 21:21:38  mcr
++ * 	split up receive path into per-transform files, for
++ * 	easier later removal.
++ *
++ * Revision 1.27  2003/12/04 19:05:54  mcr
++ * 	cleaned up "sa_id" structure to use "ip_said" only.
++ *
++ * Revision 1.26  2003/11/07 17:37:12  mcr
++ * 	backout X.509 and port-selector code
++ *
++ * Revision 1.24  2003/06/20 01:42:21  mcr
++ * 	added counters to measure how many ACQUIREs we send to pluto,
++ * 	and how many are successfully sent.
++ *
++ * Revision 1.23  2003/04/03 17:38:09  rgb
++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
++ *
++ * Revision 1.22  2002/09/20 15:40:57  rgb
++ * Renamed saref macros for consistency and brevity.
++ *
++ * Revision 1.21  2002/09/20 05:01:35  rgb
++ * Print ref and  reftable, refentry seperately.
++ *
++ * Revision 1.20  2002/09/19 02:35:39  mcr
++ * 	do not define structures needed by /proc/net/ipsec/ if we
++ * 	aren't going create that directory.
++ *
++ * Revision 1.19  2002/09/10 01:43:25  mcr
++ * 	fixed problem in /-* comment.
++ *
++ * Revision 1.18  2002/09/03 16:22:11  mcr
++ * 	fixed initialization of birth/stuff values - some simple
++ * 	screw ups in the code.
++ * 	removed debugging that was left in by mistake.
++ *
++ * Revision 1.17  2002/09/02 17:54:53  mcr
++ * 	changed how the table driven /proc entries are created so that
++ * 	making subdirs is now explicit rather than implicit.
++ *
++ * Revision 1.16  2002/08/30 01:23:37  mcr
++ * 	reorganized /proc creating code to clear up ifdefs,
++ * 	make the 2.4 code table driven, and put things into
++ * 	/proc/net/ipsec subdir. Symlinks are left for compatibility.
++ *
++ * Revision 1.15  2002/08/13 19:01:25  mcr
++ * 	patches from kenb to permit compilation of FreeSWAN on ia64.
++ * 	des library patched to use proper DES_LONG type for ia64.
++ *
++ * Revision 1.14  2002/07/26 08:48:31  rgb
++ * Added SA ref table code.
++ *
++ * Revision 1.13  2002/07/24 18:44:54  rgb
++ * Type fiddling to tame ia64 compiler.
++ *
++ * Revision 1.12  2002/05/27 18:56:07  rgb
++ * Convert to dynamic ipsec device allocation.
++ *
++ * Revision 1.11  2002/05/23 07:14:50  rgb
++ * Added refcount code.
++ * Cleaned up %p variants to 0p%p for test suite cleanup.
++ * Convert "usecount" to "refcount" to remove ambiguity.
++ *
++ * Revision 1.10  2002/04/24 07:55:32  mcr
++ * 	#include patches and Makefiles for post-reorg compilation.
++ *
++ * Revision 1.9  2002/04/24 07:36:28  mcr
++ * Moved from ./klips/net/ipsec/ipsec_proc.c,v
++ *
++ * 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:
++ *
++ */
-- 
1.5.4.1



More information about the openwrt-devel mailing list